From eea37f121301cf1c1b69b431c03d0e32590baaa3 Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Tue, 6 Apr 2021 14:16:08 +0200 Subject: [PATCH] fix(Core/Spell): Make use of SPELL_ATTR4_DONT_REMOVE_IN_ARENA (#4990) --- src/server/game/Entities/Unit/Unit.cpp | 47 ++++++++++++++++++-------- src/server/game/Entities/Unit/Unit.h | 6 ++++ 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index d6ec7db93..fc562b6db 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -4427,6 +4427,32 @@ void Unit::RemoveAura(Aura* aura, AuraRemoveMode mode) RemoveAura(aurApp, mode); } +void Unit::RemoveAppliedAuras(std::function const& check) +{ + for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();) + { + if (check(iter->second)) + { + RemoveAura(iter); + continue; + } + ++iter; + } +} + +void Unit::RemoveAppliedAuras(uint32 spellId, std::function const& check) +{ + for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);) + { + if (check(iter->second)) + { + RemoveAura(iter); + continue; + } + ++iter; + } +} + void Unit::RemoveAurasDueToSpell(uint32 spellId, uint64 casterGUID, uint8 reqEffMask, AuraRemoveMode removeMode) { for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);) @@ -4845,23 +4871,14 @@ void Unit::RemoveArenaAuras() { // in join, remove positive buffs, on end, remove negative // used to remove positive visible auras in arenas - for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();) + RemoveAppliedAuras([](AuraApplication const* aurApp) { - AuraApplication const* aurApp = iter->second; Aura const* aura = aurApp->GetBase(); - if (!aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_DONT_REMOVE_IN_ARENA) // don't remove stances, shadowform, pally/hunter auras - && !aura->IsPassive() // don't remove passive auras - && !aura->IsArea() // don't remove area auras, eg pet talents affecting owner - && (aurApp->IsPositive() || IsPet() || !aura->GetSpellInfo()->HasAttribute(SPELL_ATTR3_DEATH_PERSISTENT))) // not negative death persistent auras - { - RemoveAura(iter); - } - // xinef: special marker, 95% sure - else if (aura->GetSpellInfo()->HasAttribute(SPELL_ATTR5_REMOVE_ON_ARENA_ENTER)) - RemoveAura(iter); - else - ++iter; - } + return (!aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_DONT_REMOVE_IN_ARENA) // don't remove stances, shadowform, pally/hunter auras + && !aura->IsPassive() // don't remove passive auras + && (aurApp->IsPositive() || !aura->GetSpellInfo()->HasAttribute(SPELL_ATTR3_DEATH_PERSISTENT))) || // not negative death persistent auras + aura->GetSpellInfo()->HasAttribute(SPELL_ATTR5_REMOVE_ON_ARENA_ENTER); // special marker, always remove + }); } void Unit::RemoveAllAurasOnDeath() diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 7a224f37a..e51727a4b 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1985,6 +1985,12 @@ public: void RemoveMovementImpairingAuras(bool withRoot); void RemoveAurasByShapeShift(); + // Convenience methods removing auras by predicate + void RemoveAppliedAuras(std::function const& check); + + // Optimized overloads taking advantage of map key + void RemoveAppliedAuras(uint32 spellId, std::function const& check); + void RemoveAreaAurasDueToLeaveWorld(); void RemoveAllAuras(); void RemoveArenaAuras();