/** * Returns array with character stats. Most functions taked from CSWOWD. Requires $this->guid! * @category Character class * @example Characters::ConstructCharacterData() * @todo Update method to 3.3.0a `data` field * @return array **/ public function ConstructCharacterData() { $guid = $this->guid; $StatArray = array(); $rating = Utils::GetRating($this->level); /* Basic data */ $StatArray['effective_strenght'] = $this->GetDataField(UNIT_FIELD_STAT0); $StatArray['bonus_strenght'] = Utils::getFloatValue($this->GetDataField(UNIT_FIELD_POSSTAT0), 0); $StatArray['negative_strenght'] = Utils::getFloatValue($this->GetDataField(UNIT_FIELD_NEGSTAT0), 0); $StatArray['stat_strenght'] = $StatArray['effective_strenght'] - $StatArray['bonus_strenght'] - $StatArray['negative_strenght']; $StatArray['bonus_strenght_attackpower'] = Utils::GetAttackPowerForStat(STAT_STRENGTH, $StatArray['effective_strenght'], $this->class); if ($this->class == CLASS_WARRIOR || $this->class == CLASS_PALADIN || $this->class == CLASS_SHAMAN) { $StatArray['bonus_strenght_block'] = max(0, $StatArray['effective_strenght'] * BLOCK_PER_STRENGTH - 10); } else { $StatArray['bonus_strenght_block'] = '-1'; } $StatArray['effective_agility'] = $this->GetDataField(UNIT_FIELD_STAT1); $StatArray['bonus_agility'] = Utils::getFloatValue($this->GetDataField(UNIT_FIELD_POSSTAT1), 0); $StatArray['negative_agility'] = Utils::getFloatValue($this->GetDataField(UNIT_FIELD_NEGSTAT1), 0); $StatArray['stat_agility'] = $StatArray['effective_agility'] - $StatArray['bonus_agility'] - $StatArray['negative_agility']; $StatArray['crit_agility'] = floor(Utils::GetCritChanceFromAgility($rating, $this->class, $StatArray['effective_agility'])); $StatArray['bonus_agility_attackpower'] = Utils::GetAttackPowerForStat(STAT_AGILITY, $StatArray['effective_agility'], $this->class); $StatArray['bonus_agility_armor'] = $StatArray['effective_agility'] * ARMOR_PER_AGILITY; if ($StatArray['bonus_agility_attackpower'] == 0) { $StatArray['bonus_agility_attackpower'] = '-1'; } $StatArray['effective_stamina'] = $this->GetDataField(UNIT_FIELD_STAT2); $StatArray['bonus_stamina'] = Utils::getFloatValue($this->GetDataField(UNIT_FIELD_POSSTAT2), 0); $StatArray['negative_stamina'] = Utils::getFloatValue($this->GetDataField(UNIT_FIELD_NEGSTAT2), 0); $StatArray['stat_stamina'] = $StatArray['effective_stamina'] - $StatArray['bonus_stamina'] - $StatArray['negative_stamina']; $StatArray['base_stamina'] = min(20, $StatArray['effective_stamina']); $StatArray['more_stamina'] = $StatArray['effective_stamina'] - $StatArray['base_stamina']; $StatArray['bonus_stamina_health'] = $StatArray['base_stamina'] + $StatArray['more_stamina'] * HEALTH_PER_STAMINA; $StatArray['bonus_stamina_petstamina'] = Utils::ComputePetBonus(2, $StatArray['effective_stamina'], $this->class); if ($StatArray['bonus_stamina_petstamina'] == 0) { $StatArray['bonus_stamina_petstamina'] = '-1'; } $StatArray['effective_intellect'] = $this->GetDataField(UNIT_FIELD_STAT3); $StatArray['bonus_intellect'] = Utils::getFloatValue($this->GetDataField(UNIT_FIELD_POSSTAT3), 0); $StatArray['negative_intellect'] = Utils::getFloatValue($this->GetDataField(UNIT_FIELD_NEGSTAT3), 0); $StatArray['stat_intellect'] = $StatArray['effective_intellect'] - $StatArray['bonus_intellect'] - $StatArray['negative_intellect']; if ($this->class != CLASS_WARRIOR && $this->class != CLASS_ROGUE && $this->class != CLASS_DK) { $StatArray['base_intellect'] = min(20, $StatArray['effective_intellect']); $StatArray['more_intellect'] = $StatArray['effective_intellect'] - $StatArray['base_intellect']; $StatArray['mana_intellect'] = $StatArray['base_intellect'] + $StatArray['more_intellect'] * MANA_PER_INTELLECT; $StatArray['bonus_intellect_spellcrit'] = round(Utils::GetSpellCritChanceFromIntellect($rating, $this->class, $StatArray['effective_intellect']), 2); } else { $StatArray['base_intellect'] = '-1'; $StatArray['more_intellect'] = '-1'; $StatArray['mana_intellect'] = '-1'; $StatArray['bonus_intellect_spellcrit'] = '-1'; } $StatArray['bonus_intellect_petintellect'] = Utils::ComputePetBonus(7, $StatArray['effective_intellect'], $this->class); if ($StatArray['bonus_intellect_petintellect'] == 0) { $StatArray['bonus_intellect_petintellect'] = '-1'; } $StatArray['effective_spirit'] = $this->GetDataField(UNIT_FIELD_STAT4); $StatArray['bonus_spirit'] = Utils::getFloatValue($this->GetDataField(UNIT_FIELD_POSSTAT4), 0); $StatArray['negative_spirit'] = Utils::getFloatValue($this->GetDataField(UNIT_FIELD_NEGSTAT4), 0); $StatArray['stat_spirit'] = $StatArray['effective_spirit'] - $StatArray['bonus_spirit'] - $StatArray['negative_spirit']; $baseRatio = array(0, 0.625, 0.2631, 0.2, 0.3571, 0.1923, 0.625, 0.1724, 0.1212, 0.1282, 1, 0.1389); $StatArray['bonus_spirit_hpregeneration'] = $StatArray['effective_spirit'] * Utils::GetHRCoefficient($rating, $this->class); $StatArray['base_spirit'] = $StatArray['effective_spirit']; if ($StatArray['base_spirit'] > 50) { $StatArray['base_spirit'] = 50; } $StatArray['more_spirit'] = $StatArray['effective_spirit'] - $StatArray['base_spirit']; $StatArray['bonus_spirit_hpregeneration'] = floor($StatArray['base_spirit'] * $baseRatio[$this->class] + $StatArray['more_spirit'] * Utils::GetHRCoefficient($rating, $this->class)); if ($this->class != CLASS_WARRIOR && $this->class != CLASS_ROGUE && $this->class != CLASS_DK) { $StatArray['bonus_spitit_manaregeneration'] = sqrt($StatArray['effective_intellect']) * $StatArray['effective_spirit'] * Utils::GetMRCoefficient($rating, $this->class); $StatArray['bonus_spitit_manaregeneration'] = floor($StatArray['bonus_spitit_manaregeneration'] * 5); } else { $StatArray['bonus_spitit_manaregeneration'] = '-1'; } $StatArray['effective_armor'] = $this->GetDataField(UNIT_FIELD_RESISTANCES); $StatArray['bonus_armor'] = Utils::getFloatValue($this->GetDataField(UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE), 0); $StatArray['negative_armor'] = Utils::getFloatValue($this->GetDataField(UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE), 0); $StatArray['stat_armor'] = $StatArray['effective_armor'] - $StatArray['bonus_armor'] - $StatArray['negative_armor']; if ($this->level > 59) { $levelModifier = $this->level + 4.5 * ($this->level - 59); } $StatArray['bonus_armor_reduction'] = 0.1 * $StatArray['effective_armor'] / (8.5 * $levelModifier + 40); $StatArray['bonus_armor_reduction'] = round($StatArray['bonus_armor_reduction'] / (1 + $StatArray['bonus_armor_reduction']) * 100, 2); if ($StatArray['bonus_armor_reduction'] > 75) { $StatArray['bonus_armor_reduction'] = 75; } if ($StatArray['bonus_armor_reduction'] < 0) { $StatArray['bonus_armor_reduction'] = 0; } $StatArray['bonus_armor_petbonus'] = Utils::ComputePetBonus(4, $StatArray['effective_armor'], $this->class); if ($StatArray['bonus_armor_petbonus'] == 0) { $StatArray['bonus_armor_petbonus'] = '-1'; } /* Melee stats */ $StatArray['min_melee_dmg'] = Utils::getFloatValue($this->GetDataField(UNIT_FIELD_MINDAMAGE), 0); $StatArray['max_melee_dmg'] = Utils::getFloatValue($this->GetDataField(UNIT_FIELD_MAXDAMAGE), 0); $StatArray['speed_melee_dmg'] = round(Utils::getFloatValue($this->GetDataField(UNIT_FIELD_BASEATTACKTIME), 2) / 1000, 2); $StatArray['melee_dmg'] = ($StatArray['min_melee_dmg'] + $StatArray['max_melee_dmg']) * 0.5; $StatArray['dps_melee_dmg'] = round(max($StatArray['melee_dmg'], 1) / $StatArray['speed_melee_dmg'], 1); if ($StatArray['speed_melee_dmg'] < 0.1) { $StatArray['speed_melee_dmg'] = '0.1'; } $StatArray['hasterating_melee_dmg'] = $this->GetDataField(PLAYER_FIELD_COMBAT_RATING_1 + 17); $StatArray['hastepct_melee_dmg'] = round($StatArray['hasterating_melee_dmg'] / Utils::GetRatingCoefficient($rating, 19), 2); $StatArray['multipler_melee_ap'] = Utils::getFloatValue($this->GetDataField(UNIT_FIELD_ATTACK_POWER_MULTIPLIER), 8); if ($StatArray['multipler_melee_ap'] < 0) { $StatArray['multipler_melee_ap'] = 0; } else { $StatArray['multipler_melee_ap'] += 1; } $StatArray['effective_melee_ap'] = $this->GetDataField(UNIT_FIELD_ATTACK_POWER) * $StatArray['multipler_melee_ap']; $StatArray['bonus_melee_ap'] = $this->GetDataField(UNIT_FIELD_ATTACK_POWER_MODS) * $StatArray['multipler_melee_ap']; $StatArray['stat_melee_ap'] = $StatArray['effective_melee_ap'] + $StatArray['bonus_melee_ap']; $StatArray['bonus_ap_dps'] = floor(max($StatArray['stat_melee_ap'], 0) / 14); $StatArray['melee_hit_rating'] = $this->GetDataField(PLAYER_FIELD_COMBAT_RATING_1 + 5); $StatArray['melee_hit_ratingpct'] = floor($StatArray['melee_hit_rating'] / Utils::GetRatingCoefficient($rating, 6)); $StatArray['melee_hit_penetration'] = $this->GetDataField(PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE); $StatArray['melee_crit'] = Utils::getFloatValue($this->GetDataField(PLAYER_CRIT_PERCENTAGE), 2); $StatArray['melee_crit_rating'] = $this->GetDataField(PLAYER_FIELD_COMBAT_RATING_1 + 8); $StatArray['melee_crit_ratingpct'] = floor($StatArray['melee_crit_rating'] / Utils::GetRatingCoefficient($rating, 9)); $StatArray['melee_skill_id'] = Utils::getSkillFromItemID($this->getCharacterEquip('mainhand')); $character_data = $this->cDB->selectCell("SELECT `data` FROM `characters` WHERE `guid`=?", $this->guid); $StatArray['melee_skill'] = Utils::getSkill($StatArray['melee_skill_id'], $character_data); $StatArray['melee_skill_defrating'] = $this->GetDataField(PLAYER_FIELD_COMBAT_RATING_1 + 20); $StatArray['melee_skill_ratingadd'] = $StatArray['melee_skill_defrating'] / Utils::GetRatingCoefficient($rating, 2); $buff = $StatArray['melee_skill'][4] + $StatArray['melee_skill'][5] + intval($StatArray['melee_skill_ratingadd']); $StatArray['stat_melee_skill'] = $StatArray['melee_skill'][2] + $buff; $gskill = $this->getCharacterSkill(SKILL_DEFENCE); $StatArray['defense_rating_skill'] = $gskill['value']; $StatArray['rating_defense'] = $this->GetDataField(PLAYER_FIELD_COMBAT_RATING_1 + 1); $StatArray['rating_defense_add'] = $StatArray['rating_defense'] / Utils::GetRatingCoefficient($rating, 2); $buff = intval($StatArray['rating_defense_add']); $StatArray['stat_defense_rating'] = $StatArray['rating_defense_add'] + $buff; $StatArray['defense_percent'] = DODGE_PARRY_BLOCK_PERCENT_PER_DEFENSE * ($StatArray['stat_defense_rating'] - $this->level * 5); $StatArray['defense_percent'] = max($StatArray['defense_percent'], 0); unset($character_data); $rating = Utils::GetRating($this->level); $StatArray['dodge_chance'] = Utils::getFloatValue($this->GetDataField(PLAYER_DODGE_PERCENTAGE), 2); $StatArray['stat_dodge'] = $this->GetDataField(PLAYER_FIELD_COMBAT_RATING_1 + 2); $StatArray['stat_dodge_pct'] = floor($StatArray['stat_dodge'] / Utils::GetRatingCoefficient($rating, 3)); $StatArray['parry_chance'] = Utils::getFloatValue($this->GetDataField(PLAYER_PARRY_PERCENTAGE), 2); $StatArray['stat_parry'] = $this->GetDataField(PLAYER_FIELD_COMBAT_RATING_1 + 3); $StatArray['stat_parry_pct'] = floor($StatArray['stat_parry'] / Utils::GetRatingCoefficient($rating, 4)); $StatArray['melee_resilence'] = $this->GetDataField(PLAYER_FIELD_CRIT_TAKEN_MELEE_RATING); $StatArray['ranged_resilence'] = $this->GetDataField(PLAYER_FIELD_CRIT_TAKEN_RANGED_RATING); $StatArray['spell_resilence'] = $this->GetDataField(PLAYER_FIELD_CRIT_TAKEN_SPELL_RATING); $StatArray['min_resilence'] = min($StatArray['melee_resilence'], $StatArray['ranged_resilence'], $StatArray['spell_resilence']); $StatArray['melee_resilence_pct'] = $StatArray['melee_resilence'] / Utils::GetRatingCoefficient($rating, 15); $StatArray['ranged_resilence_pct'] = $StatArray['ranged_resilence'] / Utils::GetRatingCoefficient($rating, 16); $StatArray['spell_resilence_pct'] = $StatArray['spell_resilence'] / Utils::GetRatingCoefficient($rating, 17); $StatArray['mana_regen_out_of_cast'] = $this->GetDataField(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER); $StatArray['mana_regen_cast'] = $this->GetDataField(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER); $StatArray['mana_regen_out_of_cast'] = floor(Utils::getFloatValue($StatArray['mana_regen_out_of_cast'], 2) * 5); $StatArray['mana_regen_cast'] = round(Utils::getFloatValue($StatArray['mana_regen_cast'], 2) * 5, 2); $holySchool = 1; $minModifier = Utils::GetSpellBonusDamage($holySchool, $guid); for ($i = 1; $i < 7; $i++) { $bonusDamage[$i] = Utils::GetSpellBonusDamage($i, $guid); $minModifier = min($minModifier, $bonusDamage); } $StatArray['spd_holy'] = $bonusDamage[2]; $StatArray['spd_fire'] = $bonusDamage[2]; $StatArray['spd_nature'] = $bonusDamage[3]; $StatArray['spd_frost'] = $bonusDamage[4]; $StatArray['spd_shadow'] = $bonusDamage[5]; $StatArray['spd_arcane'] = $bonusDamage[6]; $StatArray['pet_bonus_ap'] = '-1'; $StatArray['pet_bonus_dmg'] = '-1'; if ($this->class == 3 || $this->class == 9) { $shadow = Utils::GetSpellBonusDamage(5, $guid); $fire = Utils::GetSpellBonusDamage(2, $guid); $StatArray['pet_bonus_ap'] = Utils::ComputePetBonus(6, max($shadow, $fire), $this->class); $StatArray['pet_bonus_dmg'] = Utils::ComputePetBonus(5, max($shadow, $fire), $this->class); } // spell heal bonus $StatArray['heal_bonus'] = $this->GetDataField(PLAYER_FIELD_MOD_HEALING_DONE_POS); // spell haste $StatArray['spell_haste_rating'] = $this->GetDataField(PLAYER_FIELD_COMBAT_RATING_1 + 19); $StatArray['spell_haste_pct'] = round($StatArray['spell_haste_rating'] / Utils::GetRatingCoefficient($rating, 20), 2); // spell hit $StatArray['spell_hit_rating'] = $this->GetDataField(PLAYER_FIELD_COMBAT_RATING_1 + 7); $StatArray['spell_hit_pct'] = floor($StatArray['spell_hit_rating'] / Utils::GetRatingCoefficient($rating, 8)); $StatArray['spell_hit_penetration'] = $this->GetDataField(PLAYER_FIELD_MOD_TARGET_RESISTANCE); // Spell crit $StatArray['spell_crit_rating'] = $this->GetDataField(PLAYER_FIELD_COMBAT_RATING_1 + 10); $StatArray['spell_crit_pct'] = $StatArray['spell_crit_rating'] / Utils::GetRatingCoefficient($rating, 11); $minCrit = $this->GetDataField(PLAYER_SPELL_CRIT_PERCENTAGE1 + 1); for ($i = 1; $i < 7; $i++) { $scfield = PLAYER_SPELL_CRIT_PERCENTAGE1 + $i; $s_crit_value = $this->GetDataField($scfield); $spellCrit[$i] = Utils::getFloatValue($s_crit_value, 2); $minCrit = min($minCrit, $spellCrit[$i]); } $StatArray['spell_crit_holy'] = $spellCrit[1]; $StatArray['spell_crit_fire'] = $spellCrit[2]; $StatArray['spell_crit_nature'] = $spellCrit[3]; $StatArray['spell_crit_frost'] = $spellCrit[4]; $StatArray['spell_crit_arcane'] = $spellCrit[5]; $StatArray['spell_crit_shadow'] = $spellCrit[6]; // block $blockvalue = $this->GetDataField(PLAYER_BLOCK_PERCENTAGE); $StatArray['block_pct'] = Utils::getFloatValue($blockvalue, 2); $StatArray['block_rating'] = $this->GetDataField(PLAYER_FIELD_COMBAT_RATING_1 + 4); //TODO: block % $StatArray['block_chance'] = $this->GetDataField(PLAYER_SHIELD_BLOCK); // ranged attack power $multipler = Utils::getFloatValue($this->GetDataField(UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER), 8); if ($multipler < 0) { $multipler = 0; } else { $multipler += 1; } $effectiveStat = $this->GetDataField(UNIT_FIELD_RANGED_ATTACK_POWER) * $multipler; $buff = $this->GetDataField(UNIT_FIELD_RANGED_ATTACK_POWER_MODS) * $multipler; $multiple = Utils::getFloatValue($this->GetDataField(UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER), 2); $posBuff = 0; $negBuff = 0; if ($buff > 0) { $posBuff = $buff; } elseif ($buff < 0) { $negBuff = $buff; } $stat = $effectiveStat + $buff; $StatArray['ranged_base'] = floor($effectiveStat); $StatArray['ranged_effective'] = floor($stat); $StatArray['ranged_dps_ap'] = floor(max($stat, 0) / 14); $StatArray['ranged_pet_ap'] = floor(Utils::ComputePetBonus(0, $stat, $this->class)); $StatArray['ranged_pet_spd'] = floor(Utils::ComputePetBonus(1, $stat, $this->class)); // ranged speed $rangedSkillID = Mangos::getSkillFromItemID($this->GetDataField(PLAYER_VISIBLE_ITEM_18_ENTRYID)); if ($rangedSkillID == SKILL_UNARMED) { $StatArray['ranged_speed'] = '0'; $StatArray['ranged_speed_rating'] = '0'; $StatArray['ranged_speed_pct'] = '0'; } else { $StatArray['ranged_speed'] = round(Utils::getFloatValue($this->GetDataField(UNIT_FIELD_RANGEDATTACKTIME), 2) / 1000, 2); $StatArray['ranged_speed_rating'] = round($this->GetDataField(PLAYER_FIELD_COMBAT_RATING_1 + 18)); $StatArray['ranged_speed_pct'] = round($StatArray['ranged_speed_rating'] / Utils::GetRatingCoefficient($rating, 19), 2); } // ranged hit rating $StatArray['ranged_hit'] = $this->GetDataField(PLAYER_FIELD_COMBAT_RATING_1 + 6); $StatArray['ranged_hit_pct'] = floor($StatArray['ranged_hit'] / Utils::GetRatingCoefficient($rating, 7)); $StatArray['ranged_hit_penetration'] = $this->GetDataField(PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE); // ranged crit $StatArray['ranged_crit'] = Utils::getFloatValue($this->GetDataField(PLAYER_RANGED_CRIT_PERCENTAGE), 2); $StatArray['ranged_crit_rating'] = $this->GetDataField(PLAYER_FIELD_COMBAT_RATING_1 + 9); $StatArray['ranged_crit_pct'] = floor($StatArray['ranged_crit_rating'] / Utils::GetRatingCoefficient($rating, 10)); if ($rangedSkillID == SKILL_UNARMED) { $StatArray['ranged_dps'] = 0; $StatArray['ranged_dps_min'] = 0; $StatArray['ranged_dps_max'] = 0; $StatArray['ranged_dps_speed'] = 0; $StatArray['ranged_dps_pct'] = 0; } else { $StatArray['ranged_dps_min'] = Utils::getFloatValue($this->GetDataField(UNIT_FIELD_MINRANGEDDAMAGE), 0); $StatArray['ranged_dps_max'] = Utils::getFloatValue($this->GetDataField(UNIT_FIELD_MAXRANGEDDAMAGE), 0); $StatArray['ranged_dps_speed'] = round(Utils::getFloatValue($this->GetDataField(UNIT_FIELD_RANGEDATTACKTIME), 2) / 1000, 2); $StatArray['ranged_dps'] = ($StatArray['ranged_dps_min'] + $StatArray['ranged_dps_max']) * 0.5; if ($StatArray['ranged_dps_speed'] < 0.1) { $StatArray['ranged_dps_speed'] = 0.1; } $StatArray['ranged_dps_pct'] = round(max($StatArray['ranged_dps'], 1) / $StatArray['ranged_dps_speed']); } return $StatArray; }
public function GetCharacterRangedHaste() { $player_stats = array(); $rating = $this->SetRating(); $rangedSkillID = Mangos::getSkillFromItemID($this->GetDataField(PLAYER_VISIBLE_ITEM_18_ENTRYID)); if ($rangedSkillID == SKILL_UNARMED) { $player_stats['value'] = '0'; $player_stats['hasteRating'] = '0'; $player_stats['hastePercent'] = '0'; } else { $player_stats['value'] = round(Utils::getFloatValue($this->GetDataField(UNIT_FIELD_RANGEDATTACKTIME), 2) / 1000, 2); $player_stats['hasteRating'] = round($this->GetDataField(PLAYER_FIELD_COMBAT_RATING_1 + 18)); $player_stats['hastePercent'] = round($player_stats['hasteRating'] / Utils::GetRatingCoefficient($rating, 19), 2); } unset($rating); unset($rangedSkillID); return $player_stats; }