Core/Auras: Update absorb aura priority ordering

This commit is contained in:
Shauren
2026-04-15 00:02:59 +02:00
parent daae0381f0
commit 5bd241a826
2 changed files with 11 additions and 38 deletions

View File

@@ -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;

View File

@@ -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();
}
};
}