diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 8bbe43bcfd..f17386bad1 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -1709,7 +1709,6 @@ static float GetArmorReduction(float armor, uint8 attackerLevel) RoundToInterval(auraAbsorbMod, 0.0f, 100.0f); int32 absorbIgnoringDamage = CalculatePct(damageInfo.GetDamage(), auraAbsorbMod); - damageInfo.ModifyDamage(-absorbIgnoringDamage); // We're going to call functions which can modify content of the list during iteration over it's elements // Let's copy the list so we can prevent iterator invalidation @@ -1733,6 +1732,9 @@ static float GetArmorReduction(float armor, uint8 attackerLevel) if (currentAbsorb < 0) currentAbsorb = 0; + if (!absorbAurEff->GetSpellInfo()->HasAttribute(SPELL_ATTR6_ABSORB_CANNOT_BE_IGNORE)) + damageInfo.ModifyDamage(-absorbIgnoringDamage); + uint32 tempAbsorb = uint32(currentAbsorb); bool defaultPrevented = false; @@ -1740,26 +1742,30 @@ static float GetArmorReduction(float armor, uint8 attackerLevel) absorbAurEff->GetBase()->CallScriptEffectAbsorbHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb, defaultPrevented); currentAbsorb = tempAbsorb; - if (defaultPrevented) - continue; - - // absorb must be smaller than the damage itself - currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(damageInfo.GetDamage())); - - damageInfo.AbsorbDamage(currentAbsorb); - - tempAbsorb = currentAbsorb; - absorbAurEff->GetBase()->CallScriptEffectAfterAbsorbHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb); - - // Check if our aura is using amount to count damage - if (absorbAurEff->GetAmount() >= 0) + if (!defaultPrevented) { - // Reduce shield amount - absorbAurEff->SetAmount(absorbAurEff->GetAmount() - currentAbsorb); - // Aura cannot absorb anything more - remove it - if (absorbAurEff->GetAmount() <= 0) - absorbAurEff->GetBase()->Remove(AuraRemoveFlags::ByEnemySpell); + + // absorb must be smaller than the damage itself + currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(damageInfo.GetDamage())); + + damageInfo.AbsorbDamage(currentAbsorb); + + tempAbsorb = currentAbsorb; + absorbAurEff->GetBase()->CallScriptEffectAfterAbsorbHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb); + + // Check if our aura is using amount to count damage + if (absorbAurEff->GetAmount() >= 0) + { + // Reduce shield amount + absorbAurEff->SetAmount(absorbAurEff->GetAmount() - currentAbsorb); + // Aura cannot absorb anything more - remove it + if (absorbAurEff->GetAmount() <= 0) + absorbAurEff->GetBase()->Remove(AuraRemoveFlags::ByEnemySpell); + } } + + if (!absorbAurEff->GetSpellInfo()->HasAttribute(SPELL_ATTR6_ABSORB_CANNOT_BE_IGNORE)) + damageInfo.ModifyDamage(absorbIgnoringDamage); } // absorb by mana cost @@ -1781,6 +1787,9 @@ static float GetArmorReduction(float armor, uint8 attackerLevel) if (currentAbsorb < 0) currentAbsorb = 0; + if (!absorbAurEff->GetSpellInfo()->HasAttribute(SPELL_ATTR6_ABSORB_CANNOT_BE_IGNORE)) + damageInfo.ModifyDamage(-absorbIgnoringDamage); + uint32 tempAbsorb = currentAbsorb; bool defaultPrevented = false; @@ -1788,38 +1797,40 @@ static float GetArmorReduction(float armor, uint8 attackerLevel) absorbAurEff->GetBase()->CallScriptEffectManaShieldHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb, defaultPrevented); currentAbsorb = tempAbsorb; - if (defaultPrevented) - continue; - - // absorb must be smaller than the damage itself - currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(damageInfo.GetDamage())); - - int32 manaReduction = currentAbsorb; - - // lower absorb amount by talents - if (float manaMultiplier = absorbAurEff->GetSpellInfo()->Effects[absorbAurEff->GetEffIndex()].CalcValueMultiplier(absorbAurEff->GetCaster())) - manaReduction = int32(float(manaReduction) * manaMultiplier); - - int32 manaTaken = -damageInfo.GetVictim()->ModifyPower(POWER_MANA, -manaReduction); - - // take case when mana has ended up into account - currentAbsorb = currentAbsorb ? int32(float(currentAbsorb) * (float(manaTaken) / float(manaReduction))) : 0; - - damageInfo.AbsorbDamage(currentAbsorb); - - tempAbsorb = currentAbsorb; - absorbAurEff->GetBase()->CallScriptEffectAfterManaShieldHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb); - - // Check if our aura is using amount to count damage - if (absorbAurEff->GetAmount() >= 0) + if (!defaultPrevented) { - absorbAurEff->SetAmount(absorbAurEff->GetAmount() - currentAbsorb); - if ((absorbAurEff->GetAmount() <= 0)) - absorbAurEff->GetBase()->Remove(AuraRemoveFlags::ByEnemySpell); - } - } - damageInfo.ModifyDamage(absorbIgnoringDamage); + // absorb must be smaller than the damage itself + currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(damageInfo.GetDamage())); + + int32 manaReduction = currentAbsorb; + + // lower absorb amount by talents + if (float manaMultiplier = absorbAurEff->GetSpellInfo()->Effects[absorbAurEff->GetEffIndex()].CalcValueMultiplier(absorbAurEff->GetCaster())) + manaReduction = int32(float(manaReduction) * manaMultiplier); + + int32 manaTaken = -damageInfo.GetVictim()->ModifyPower(POWER_MANA, -manaReduction); + + // take case when mana has ended up into account + currentAbsorb = currentAbsorb ? int32(float(currentAbsorb) * (float(manaTaken) / float(manaReduction))) : 0; + + damageInfo.AbsorbDamage(currentAbsorb); + + tempAbsorb = currentAbsorb; + absorbAurEff->GetBase()->CallScriptEffectAfterManaShieldHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb); + + // Check if our aura is using amount to count damage + if (absorbAurEff->GetAmount() >= 0) + { + absorbAurEff->SetAmount(absorbAurEff->GetAmount() - currentAbsorb); + if ((absorbAurEff->GetAmount() <= 0)) + absorbAurEff->GetBase()->Remove(AuraRemoveFlags::ByEnemySpell); + } + } + + if (!absorbAurEff->GetSpellInfo()->HasAttribute(SPELL_ATTR6_ABSORB_CANNOT_BE_IGNORE)) + damageInfo.ModifyDamage(absorbIgnoringDamage); + } // split damage auras - only when not damaging self if (damageInfo.GetVictim() != damageInfo.GetAttacker()) diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 5fd86ed08d..6259206335 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -592,7 +592,7 @@ enum SpellAttr6 : uint32 SPELL_ATTR6_DELAY_COMBAT_TIMER_DURING_CAST = 0x00080000, // TITLE Delay Combat Timer During Cast SPELL_ATTR6_AURA_ICON_ONLY_FOR_CASTER_LIMIT_10 = 0x00100000, // TITLE Aura Icon Only For Caster (Limit 10) (client only) SPELL_ATTR6_SHOW_MECHANIC_AS_COMBAT_TEXT = 0x00200000, // TITLE Show Mechanic as Combat Text (client only) - SPELL_ATTR6_ABSORB_CANNOT_BE_IGNORE = 0x00400000, /*NYI*/ // TITLE Absorb Cannot Be Ignore + SPELL_ATTR6_ABSORB_CANNOT_BE_IGNORE = 0x00400000, // TITLE Absorb Cannot Be Ignore SPELL_ATTR6_TAPS_IMMEDIATELY = 0x00800000, /*NYI*/ // TITLE Taps immediately SPELL_ATTR6_CAN_TARGET_UNTARGETABLE = 0x01000000, // TITLE Can Target Untargetable SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT = 0x02000000, // TITLE Doesn't Reset Swing Timer if Instant