diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 44b078028bb..9d18fddb2b6 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -3762,20 +3762,27 @@ void Unit::RemoveAurasWithAttribute(uint32 flags) void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase, bool phaseid) { // single target auras from other casters - for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();) + // Iterate m_ownedAuras - aura is marked as single target in Unit::AddAura (and pushed to m_ownedAuras). + // m_appliedAuras will NOT contain the aura before first Unit::Update after adding it to m_ownedAuras. + // Quickly removing such an aura will lead to it not being unregistered from caster's single cast auras container + // leading to assertion failures if the aura was cast on a player that can + // (and is changing map at the point where this function is called). + // Such situation occurs when player is logging in inside an instance and fails the entry check for any reason. + // The aura that was loaded from db (indirectly, via linked casts) gets removed before it has a chance + // to register in m_appliedAuras + for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();) { - AuraApplication const* aurApp = iter->second; - Aura const* aura = aurApp->GetBase(); + Aura const* aura = iter->second; - if (aura->GetCasterGUID() != GetGUID() && aura->GetSpellInfo()->IsSingleTarget()) + if (aura->GetCasterGUID() != GetGUID() && aura->IsSingleTarget()) { if (!newPhase && !phaseid) - RemoveAura(iter); + RemoveOwnedAura(iter); else { Unit* caster = aura->GetCaster(); if (!caster || (newPhase && !caster->IsInPhase(newPhase)) || (!newPhase && !caster->IsInPhase(this))) - RemoveAura(iter); + RemoveOwnedAura(iter); else ++iter; } |