diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 038af6515e..82bd3399bb 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -998,6 +998,7 @@ bool Unit::HasBreakableByDamageCrowdControlAura(Unit const* excludeCasterChannel if (damagetype != NODAMAGE && damagetype != SELF_DAMAGE && victim->HasAuraType(SPELL_AURA_SCHOOL_ABSORB_OVERKILL)) { AuraEffectVector vAbsorbOverkill = CopyAuraEffectList(victim->GetAuraEffectsByType(SPELL_AURA_SCHOOL_ABSORB_OVERKILL)); + std::ranges::stable_sort(vAbsorbOverkill, Trinity::AbsorbAuraOrderPred()); DamageInfo damageInfo = DamageInfo(attacker, victim, damageTaken, spellProto, damageSchoolMask, damagetype, cleanDamage ? cleanDamage->attackType : BASE_ATTACK); for (AuraEffect* absorbAurEff : vAbsorbOverkill) @@ -1011,7 +1012,12 @@ bool Unit::HasBreakableByDamageCrowdControlAura(Unit const* excludeCasterChannel continue; // cannot absorb over limit - if (damageTaken >= victim->CountPctFromMaxHealth(100 + absorbAurEff->GetMiscValueB())) + if (absorbAurEff->GetAmount() > 0) + { + if (damageTaken > absorbAurEff->GetAmount()) + continue; + } + else if (damageTaken >= victim->GetMaxHealth() * 2) continue; // absorb all damage by default @@ -1891,7 +1897,7 @@ void Unit::HandleEmoteCommand(Emote emoteId, Player* target /*=nullptr*/, Trinit // 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 AuraEffectVector vSchoolAbsorbCopy = CopyAuraEffectList(damageInfo.GetVictim()->GetAuraEffectsByType(SPELL_AURA_SCHOOL_ABSORB)); - std::sort(vSchoolAbsorbCopy.begin(), vSchoolAbsorbCopy.end(), Trinity::AbsorbAuraOrderPred()); + std::ranges::stable_sort(vSchoolAbsorbCopy, Trinity::AbsorbAuraOrderPred()); // absorb without mana cost for (auto itr = vSchoolAbsorbCopy.begin(); (itr != vSchoolAbsorbCopy.end()) && (damageInfo.GetDamage() > 0); ++itr) @@ -2104,6 +2110,7 @@ void Unit::HandleEmoteCommand(Emote emoteId, Player* target /*=nullptr*/, Trinit return; AuraEffectVector vHealAbsorb = CopyAuraEffectList(healInfo.GetTarget()->GetAuraEffectsByType(SPELL_AURA_SCHOOL_HEAL_ABSORB)); + std::ranges::stable_sort(vHealAbsorb, Trinity::AbsorbAuraOrderPred()); for (auto i = vHealAbsorb.begin(); i != vHealAbsorb.end() && healInfo.GetHeal() > 0; ++i) { AuraEffect* absorbAurEff = *i; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h index 4f02394b71..8bdccfb27c 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.h +++ b/src/server/game/Spells/Auras/SpellAuraEffects.h @@ -380,43 +380,9 @@ namespace Trinity class AbsorbAuraOrderPred { public: - AbsorbAuraOrderPred() { } - bool operator() (AuraEffect* aurEffA, AuraEffect* aurEffB) const + bool operator()(AuraEffect const* aurEffA, AuraEffect const* aurEffB) const { - SpellInfo const* spellProtoA = aurEffA->GetSpellInfo(); - SpellInfo const* spellProtoB = aurEffB->GetSpellInfo(); - - // Fel Blossom - if (spellProtoA->Id == 28527) - return true; - if (spellProtoB->Id == 28527) - return false; - - // Ice Barrier - if (spellProtoA->GetCategory() == 471) - return true; - if (spellProtoB->GetCategory() == 471) - return false; - - // Sacrifice - if (spellProtoA->Id == 7812) - return true; - if (spellProtoB->Id == 7812) - return false; - - // Cauterize (must be last) - if (spellProtoA->Id == 86949) - return false; - if (spellProtoB->Id == 86949) - return true; - - // Spirit of Redemption (must be last) - if (spellProtoA->Id == 20711) - return false; - if (spellProtoB->Id == 20711) - return true; - - return false; + return aurEffA->GetMiscValueB() < aurEffB->GetMiscValueB(); } }; }