Core/Auras: Fixed auras limited to a single target not being removed in all cases as expected

* Fixes possible assertion failure in Aura::UnregisterSingleTarget
Closes #15696
Ref #15668
This commit is contained in:
Shauren
2015-10-14 08:29:19 +02:00
parent e06bc72da7
commit b808910a89
+13 -6
View File
@@ -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;
}