From 9d4218f6d4f43939fc3412d7e14c7f80ffe1f3fc Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Sun, 26 Dec 2021 22:08:57 +0100 Subject: [PATCH] Core/Units: corrected armor damage reduction calculation --- src/server/game/Entities/Unit/Unit.cpp | 54 +++++++++++++++----------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index d08b8fafcc..bc5fac38e1 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -1609,16 +1609,37 @@ bool Unit::IsDamageReducedByArmor(SpellSchoolMask schoolMask, SpellInfo const* s return true; } +// Calculation taken from Paperdollframe.lua (15595) +static float GetArmorReduction(float armor, uint8 attackerLevel) +{ + float levelModifier = attackerLevel; + if (levelModifier > 80) + levelModifier = levelModifier + (4.5f * (levelModifier - 59)) + (20 * (levelModifier - 80)); + else if (levelModifier > 59) + levelModifier = levelModifier + (4.5f * (levelModifier - 59)); + + float temp = 0.1f * armor / (8.5f * levelModifier + 40); + temp = temp / (1 + temp); + + if (temp > 0.75f) + return 75.f; + + if (temp < 0) + return 0.f; + + return temp * 100; +} + uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo const* spellInfo, WeaponAttackType /*attackType*/) const { float armor = float(victim->GetArmor()); // bypass enemy armor by SPELL_AURA_BYPASS_ARMOR_FOR_CASTER - int32 armorBypassPct = 0; - AuraEffectList const & reductionAuras = victim->GetAuraEffectsByType(SPELL_AURA_BYPASS_ARMOR_FOR_CASTER); - for (AuraEffectList::const_iterator i = reductionAuras.begin(); i != reductionAuras.end(); ++i) - if ((*i)->GetCasterGUID() == GetGUID()) - armorBypassPct += (*i)->GetAmount(); + int32 armorBypassPct = victim->GetTotalAuraModifier(SPELL_AURA_BYPASS_ARMOR_FOR_CASTER, [&](AuraEffect const* aurEff) + { + return aurEff->GetCasterGUID() == GetGUID(); + }); + armor = CalculatePct(armor, 100 - std::min(armorBypassPct, 100)); // Ignore enemy armor by SPELL_AURA_MOD_TARGET_RESISTANCE aura @@ -1628,31 +1649,18 @@ uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo if (Player* modOwner = GetSpellModOwner()) modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_IGNORE_ARMOR, armor); - AuraEffectList const& resIgnoreAuras = GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST); - for (AuraEffectList::const_iterator j = resIgnoreAuras.begin(); j != resIgnoreAuras.end(); ++j) + for (AuraEffect const* aurEff : GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST)) { - if ((*j)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) - armor = std::floor(AddPct(armor, -(*j)->GetAmount())); + if (aurEff->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) + armor = std::floor(AddPct(armor, -aurEff->GetAmount())); } if (armor < 0.0f) armor = 0.0f; - float levelModifier = getLevel(); - if (levelModifier > 80) - levelModifier = levelModifier + (4.5f * (levelModifier - 59)) + (20 * (levelModifier - 80)); - else if (levelModifier > 59) - levelModifier = levelModifier + (4.5f * (levelModifier - 59)); + float armorReduction = 100.f - GetArmorReduction(armor, getLevel()); - float tmpvalue = 0.1f * armor / (8.5f * levelModifier + 40); - tmpvalue = tmpvalue / (1.0f + tmpvalue); - - if (tmpvalue < 0.0f) - tmpvalue = 0.0f; - if (tmpvalue > 0.75f) - tmpvalue = 0.75f; - - return std::max(damage * (1.0f - tmpvalue), 1); + return std::max(CalculatePct(damage, armorReduction), 1); } uint32 Unit::CalcSpellResistedDamage(Unit* victim, uint32 damage, SpellSchoolMask schoolMask, SpellInfo const* spellInfo) const