private static function _ApplyItemBonuses($proto, $slot, $apply, $only_level_scale = false) { if (!$proto) { return false; } $ssd = $proto->ScalingStatDistribution ? DB::WoW()->selectRow("SELECT * FROM `DBPREFIX_ssd` WHERE `entry` = %d", $proto->ScalingStatDistribution) : null; if ($only_level_scale && !$ssd) { return false; } $ssd_level = WoW_Characters::GetLevel(); if ($ssd && $ssd_level > $ssd['MaxLevel']) { $ssd_level = $ssd['MaxLevel']; } $ssv = $proto->ScalingStatValue ? DB::WoW()->selectRow("SELECT * FROM `DBPREFIX_ssv` WHERE `id` = %d", $proto->ScalingStatValue) : null; if ($only_level_scale && !$ssv) { return false; } for ($i = 0; $i < MAX_ITEM_PROTO_STATS; ++$i) { $statType = 0; $val = 0; // If set ScalingStatDistribution need get stats and values from it if ($ssd && $ssv) { if ($ssd['StatMod_' . $i] < 0) { continue; } $statType = $ssd['StatMod_' . $i]; $val = WoW_Items::GetSSDMultiplier($ssv, $proto->ScalingStatValue) * $ssd['Modifier_' . $i] / 1000; } else { if ($i >= $proto->StatsCount) { continue; } $statType = $proto->ItemStat[$i]['type']; $val = $proto->ItemStat[$i]['value']; } if ($val == 0) { continue; } switch ($statType) { case ITEM_MOD_MANA: self::HandleStatModifier(UNIT_MOD_MANA, BASE_VALUE, $val, $apply); break; case ITEM_MOD_HEALTH: // modify HP self::HandleStatModifier(UNIT_MOD_HEALTH, BASE_VALUE, $val, $apply); break; case ITEM_MOD_AGILITY: // modify agility self::HandleStatModifier(UNIT_MOD_STAT_AGILITY, BASE_VALUE, $val, $apply); self::ApplyStatBuffMod(STAT_AGILITY, $val, $apply); break; case ITEM_MOD_STRENGTH: //modify strength self::HandleStatModifier(UNIT_MOD_STAT_STRENGTH, BASE_VALUE, $val, $apply); self::ApplyStatBuffMod(STAT_STRENGTH, $val, $apply); break; case ITEM_MOD_INTELLECT: //modify intellect self::HandleStatModifier(UNIT_MOD_STAT_INTELLECT, BASE_VALUE, $val, $apply); self::ApplyStatBuffMod(STAT_INTELLECT, $val, $apply); break; case ITEM_MOD_SPIRIT: //modify spirit self::HandleStatModifier(UNIT_MOD_STAT_SPIRIT, BASE_VALUE, $val, $apply); self::ApplyStatBuffMod(STAT_SPIRIT, $val, $apply); break; case ITEM_MOD_STAMINA: //modify stamina self::HandleStatModifier(UNIT_MOD_STAT_STAMINA, BASE_VALUE, $val, $apply); self::ApplyStatBuffMod(STAT_STAMINA, $val, $apply); break; case ITEM_MOD_DEFENSE_SKILL_RATING: self::ApplyRatingMod(CR_DEFENSE_SKILL, $val, $apply); break; case ITEM_MOD_DODGE_RATING: self::ApplyRatingMod(CR_DODGE, $val, $apply); break; case ITEM_MOD_PARRY_RATING: self::ApplyRatingMod(CR_PARRY, $val, $apply); break; case ITEM_MOD_BLOCK_RATING: self::ApplyRatingMod(CR_BLOCK, $val, $apply); break; case ITEM_MOD_HIT_MELEE_RATING: self::ApplyRatingMod(CR_HIT_MELEE, $val, $apply); break; case ITEM_MOD_HIT_RANGED_RATING: self::ApplyRatingMod(CR_HIT_RANGED, $val, $apply); break; case ITEM_MOD_HIT_SPELL_RATING: self::ApplyRatingMod(CR_HIT_SPELL, $val, $apply); break; case ITEM_MOD_CRIT_MELEE_RATING: self::ApplyRatingMod(CR_CRIT_MELEE, $val, $apply); break; case ITEM_MOD_CRIT_RANGED_RATING: self::ApplyRatingMod(CR_CRIT_RANGED, $val, $apply); break; case ITEM_MOD_CRIT_SPELL_RATING: self::ApplyRatingMod(CR_CRIT_SPELL, $val, $apply); break; case ITEM_MOD_HIT_TAKEN_MELEE_RATING: self::ApplyRatingMod(CR_HIT_TAKEN_MELEE, $val, $apply); break; case ITEM_MOD_HIT_TAKEN_RANGED_RATING: self::ApplyRatingMod(CR_HIT_TAKEN_RANGED, $val, $apply); break; case ITEM_MOD_HIT_TAKEN_SPELL_RATING: self::ApplyRatingMod(CR_HIT_TAKEN_SPELL, $val, $apply); break; case ITEM_MOD_CRIT_TAKEN_MELEE_RATING: self::ApplyRatingMod(CR_CRIT_TAKEN_MELEE, $val, $apply); break; case ITEM_MOD_CRIT_TAKEN_RANGED_RATING: self::ApplyRatingMod(CR_CRIT_TAKEN_RANGED, $val, $apply); break; case ITEM_MOD_CRIT_TAKEN_SPELL_RATING: self::ApplyRatingMod(CR_CRIT_TAKEN_SPELL, $val, $apply); break; case ITEM_MOD_HASTE_MELEE_RATING: self::ApplyRatingMod(CR_HASTE_MELEE, $val, $apply); break; case ITEM_MOD_HASTE_RANGED_RATING: self::ApplyRatingMod(CR_HASTE_RANGED, $val, $apply); break; case ITEM_MOD_HASTE_SPELL_RATING: self::ApplyRatingMod(CR_HASTE_SPELL, $val, $apply); break; case ITEM_MOD_HIT_RATING: self::ApplyRatingMod(CR_HIT_MELEE, $val, $apply); self::ApplyRatingMod(CR_HIT_RANGED, $val, $apply); self::ApplyRatingMod(CR_HIT_SPELL, $val, $apply); break; case ITEM_MOD_CRIT_RATING: self::ApplyRatingMod(CR_CRIT_MELEE, $val, $apply); self::ApplyRatingMod(CR_CRIT_RANGED, $val, $apply); self::ApplyRatingMod(CR_CRIT_SPELL, $val, $apply); break; case ITEM_MOD_HIT_TAKEN_RATING: self::ApplyRatingMod(CR_HIT_TAKEN_MELEE, $val, $apply); self::ApplyRatingMod(CR_HIT_TAKEN_RANGED, $val, $apply); self::ApplyRatingMod(CR_HIT_TAKEN_SPELL, $val, $apply); break; case ITEM_MOD_CRIT_TAKEN_RATING: self::ApplyRatingMod(CR_CRIT_TAKEN_MELEE, $val, $apply); self::ApplyRatingMod(CR_CRIT_TAKEN_RANGED, $val, $apply); self::ApplyRatingMod(CR_CRIT_TAKEN_SPELL, $val, $apply); break; case ITEM_MOD_RESILIENCE_RATING: self::ApplyRatingMod(CR_CRIT_TAKEN_MELEE, $val, $apply); self::ApplyRatingMod(CR_CRIT_TAKEN_RANGED, $val, $apply); self::ApplyRatingMod(CR_CRIT_TAKEN_SPELL, $val, $apply); break; case ITEM_MOD_HASTE_RATING: self::ApplyRatingMod(CR_HASTE_MELEE, $val, $apply); self::ApplyRatingMod(CR_HASTE_RANGED, $val, $apply); self::ApplyRatingMod(CR_HASTE_SPELL, $val, $apply); break; case ITEM_MOD_EXPERTISE_RATING: self::ApplyRatingMod(CR_EXPERTISE, $val, $apply); break; case ITEM_MOD_ATTACK_POWER: self::HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, $val, $apply); self::HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, $val, $apply); break; case ITEM_MOD_RANGED_ATTACK_POWER: self::HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, $val, $apply); break; case ITEM_MOD_MANA_REGENERATION: self::ApplyManaRegenBonus($val, $apply); break; case ITEM_MOD_ARMOR_PENETRATION_RATING: self::ApplyRatingMod(CR_ARMOR_PENETRATION, $val, $apply); break; case ITEM_MOD_SPELL_POWER: self::ApplySpellPowerBonus($val, $apply); break; case ITEM_MOD_SPELL_PENETRATION: self::ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE, -$val, $apply); self::$m_spellPenetrationItemMod += $apply ? $val : -$val; break; case ITEM_MOD_BLOCK_VALUE: self::HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, $val, $apply); break; // deprecated item mods // deprecated item mods case ITEM_MOD_FERAL_ATTACK_POWER: case ITEM_MOD_SPELL_HEALING_DONE: case ITEM_MOD_SPELL_DAMAGE_DONE: break; } } if ($ssv) { if ($spellbonus = WoW_Items::GetSpellBonus($ssv, $proto->ScalingStatValue)) { self::ApplySpellPowerBonus($spellbonus, $apply); } } $armor = $proto->armor; if ($ssv) { if ($ssvarmor = WoW_Items::GetArmorMod($ssv, $proto->ScalingStatValue)) { $armor = $ssvarmor; } } // Add armor bonus from ArmorDamageModifier if > 0 if ($proto->ArmorDamageModifier > 0) { $armor += $proto->ArmorDamageModifier; } if ($armor) { self::HandleStatModifier(UNIT_MOD_ARMOR, BASE_VALUE, $armor, $apply); } if ($proto->block) { self::HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, $proto->block, $apply); } if ($proto->holy_res) { self::HandleStatModifier(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, $proto->holy_res, $apply); } if ($proto->fire_res) { self::HandleStatModifier(UNIT_MOD_RESISTANCE_FIRE, BASE_VALUE, $proto->fire_res, $apply); } if ($proto->nature_res) { self::HandleStatModifier(UNIT_MOD_RESISTANCE_NATURE, BASE_VALUE, $proto->nature_res, $apply); } if ($proto->frost_res) { self::HandleStatModifier(UNIT_MOD_RESISTANCE_FROST, BASE_VALUE, $proto->frost_res, $apply); } if ($proto->shadow_res) { self::HandleStatModifier(UNIT_MOD_RESISTANCE_SHADOW, BASE_VALUE, $proto->shadow_res, $apply); } if ($proto->arcane_res) { self::HandleStatModifier(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, $proto->arcane_res, $apply); } $attType = BASE_ATTACK; $damage = 0.0; if ($slot == EQUIPMENT_SLOT_RANGED && in_array($proto->InventoryType, array(INV_TYPE_RANGED, INV_TYPE_THROWN, INV_TYPE_RANGED_RIGHT))) { $attType = RANGED_ATTACK; } elseif ($slot == EQUIPMENT_SLOT_OFFHAND) { $attType = OFF_ATTACK; } $minDamage = $proto->Damage[0]['min']; $maxDamage = $proto->Damage[0]['max']; $extraDPS = 0; if ($ssv) { if ($extraDPS = WoW_Items::GetDPSMod($ssv, $proto->ScalingStatValue)) { $average = $extraDPS * $proto->delay / 1000; $minDamage = 0.7 * $average; $maxDamage = 1.3 * $average; } } if ($minDamage > 0) { $damage = $apply ? $minDamage : BASE_MINDAMAGE; self::SetBaseWeaponDamage($attType, MINDAMAGE, $damage); } if ($maxDamage > 0) { $damage = $apply ? $maxDamage : BASE_MAXDAMAGE; self::SetBaseWeaponDamage($attType, MAXDAMAGE, $damage); } if ($proto->delay) { if ($slot == EQUIPMENT_SLOT_RANGED) { self::SetAttackTime(RANGED_ATTACK, $apply ? $proto->delay : BASE_ATTACK_TIME); } elseif ($slot == EQUIPMENT_SLOT_MAINHAND) { self::SetAttackTime(BASE_ATTACK, $apply ? $proto->delay : BASE_ATTACK_TIME); } elseif ($slot == EQUIPMENT_SLOT_OFFHAND) { self::SetAttackTime(OFF_ATTACK, $apply ? $proto->delay : BASE_ATTACK_TIME); } } if (self::CanModifyStats() && ($damage || $proto->delay)) { self::UpdateDamagePhysical($attType); } }
// Subclass / inventory type if (in_array($proto->class, array(ITEM_CLASS_ARMOR, ITEM_CLASS_WEAPON))) { echo sprintf('<li><span class="float-right">%s</span>%s</li>', $proto->subclass_name, WoW_Locale::GetString('template_item_invtype_' . $proto->InventoryType)); } // Is container? if ($proto->class == ITEM_CLASS_CONTAINER) { echo sprintf('<li>%s</li>', sprintf(WoW_Locale::GetString('template_item_container'), $proto->ContainerSlots)); } if ($proto->class == ITEM_CLASS_WEAPON) { // Weapon. Calculate damage and DPS. $minDmg = $proto->Damage[0]['min']; $maxDmg = $proto->Damage[0]['max']; $dps = 0; // SSV Check. if ($ssv) { if ($extraDPS = WoW_Items::GetDPSMod($ssv, $proto->ScalingStatValue)) { $average = $extraDPS * $proto->delay / 1000; $minDmg = 0.7 * $average; $maxDmg = 1.3 * $average; $dps = round(($maxDmg + $minDmg) / (2 * ($proto->delay / 1000))); } } for ($i = 0; $i <= 1; $i++) { $d_type = $proto->Damage[$i]['type']; $d_min = $proto->Damage[$i]['min']; $d_max = $proto->Damage[$i]['max']; if ($d_max > 0 && $proto->class != ITEM_CLASS_PROJECTILE) { $delay = $proto->delay / 1000; if ($delay > 0) { $dps += round(($d_max + $d_min) / (2 * $delay), 1); }