[8742] Avoid aura remove triggered casts and packets send at logout/delete

This is must speedup logout and solve some crash cases or unexpected effects.

Also fix some nonsense code with memory lost possibility.
This commit is contained in:
VladimirMangos 2009-10-27 04:03:24 +03:00
parent 7b6f4accd1
commit 15ab6794d3
6 changed files with 117 additions and 121 deletions

View file

@ -1141,85 +1141,89 @@ bool Aura::_RemoveAura()
SetAura(true);
SetAuraFlags(AFLAG_NONE);
SetAuraLevel(0);
SendAuraUpdate(true);
// update for out of range group members
m_target->UpdateAuraForGroup(slot);
//*****************************************************
// Update target aura state flag (at last aura remove)
//*****************************************************
// Enrage aura state
if(m_spellProto->Dispel == DISPEL_ENRAGE)
m_target->ModifyAuraState(AURA_STATE_ENRAGE, false);
uint32 removeState = 0;
uint64 removeFamilyFlag = m_spellProto->SpellFamilyFlags;
uint32 removeFamilyFlag2 = m_spellProto->SpellFamilyFlags2;
switch(m_spellProto->SpellFamilyName)
if (m_removeMode != AURA_REMOVE_BY_DELETE)
{
case SPELLFAMILY_PALADIN:
if (IsSealSpell(m_spellProto))
removeState = AURA_STATE_JUDGEMENT; // Update Seals information
break;
case SPELLFAMILY_WARLOCK:
// Conflagrate aura state on Immolate and Shadowflame,
if ((m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000004)) ||
(m_spellProto->SpellFamilyFlags2 & 0x00000002))
{
removeFamilyFlag = UI64LIT(0x0000000000000004);
removeFamilyFlag2 = 0x00000002;
removeState = AURA_STATE_CONFLAGRATE;
}
break;
case SPELLFAMILY_DRUID:
if(m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000400))
removeState = AURA_STATE_FAERIE_FIRE; // Faerie Fire (druid versions)
else if(m_spellProto->SpellFamilyFlags & UI64LIT(0x50))
{
removeFamilyFlag = 0x50;
removeState = AURA_STATE_SWIFTMEND; // Swiftmend aura state
}
break;
case SPELLFAMILY_WARRIOR:
if(m_spellProto->SpellFamilyFlags & UI64LIT(0x0004000000000000))
removeState = AURA_STATE_WARRIOR_VICTORY_RUSH; // Victorious
break;
case SPELLFAMILY_ROGUE:
if(m_spellProto->SpellFamilyFlags & UI64LIT(0x10000))
removeState = AURA_STATE_DEADLY_POISON; // Deadly poison aura state
break;
case SPELLFAMILY_HUNTER:
if(m_spellProto->SpellFamilyFlags & UI64LIT(0x1000000000000000))
removeState = AURA_STATE_FAERIE_FIRE; // Sting (hunter versions)
SendAuraUpdate(true);
}
// Remove state (but need check other auras for it)
if (removeState)
{
bool found = false;
Unit::AuraMap& Auras = m_target->GetAuras();
for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i)
// update for out of range group members
m_target->UpdateAuraForGroup(slot);
//*****************************************************
// Update target aura state flag (at last aura remove)
//*****************************************************
// Enrage aura state
if(m_spellProto->Dispel == DISPEL_ENRAGE)
m_target->ModifyAuraState(AURA_STATE_ENRAGE, false);
uint32 removeState = 0;
uint64 removeFamilyFlag = m_spellProto->SpellFamilyFlags;
uint32 removeFamilyFlag2 = m_spellProto->SpellFamilyFlags2;
switch(m_spellProto->SpellFamilyName)
{
SpellEntry const *auraSpellInfo = (*i).second->GetSpellProto();
if(auraSpellInfo->SpellFamilyName == m_spellProto->SpellFamilyName &&
(auraSpellInfo->SpellFamilyFlags & removeFamilyFlag || auraSpellInfo->SpellFamilyFlags2 & removeFamilyFlag2))
{
found = true;
case SPELLFAMILY_PALADIN:
if (IsSealSpell(m_spellProto))
removeState = AURA_STATE_JUDGEMENT; // Update Seals information
break;
}
case SPELLFAMILY_WARLOCK:
// Conflagrate aura state on Immolate and Shadowflame,
if ((m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000004)) ||
(m_spellProto->SpellFamilyFlags2 & 0x00000002))
{
removeFamilyFlag = UI64LIT(0x0000000000000004);
removeFamilyFlag2 = 0x00000002;
removeState = AURA_STATE_CONFLAGRATE;
}
break;
case SPELLFAMILY_DRUID:
if(m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000400))
removeState = AURA_STATE_FAERIE_FIRE; // Faerie Fire (druid versions)
else if(m_spellProto->SpellFamilyFlags & UI64LIT(0x50))
{
removeFamilyFlag = 0x50;
removeState = AURA_STATE_SWIFTMEND; // Swiftmend aura state
}
break;
case SPELLFAMILY_WARRIOR:
if(m_spellProto->SpellFamilyFlags & UI64LIT(0x0004000000000000))
removeState = AURA_STATE_WARRIOR_VICTORY_RUSH; // Victorious
break;
case SPELLFAMILY_ROGUE:
if(m_spellProto->SpellFamilyFlags & UI64LIT(0x10000))
removeState = AURA_STATE_DEADLY_POISON; // Deadly poison aura state
break;
case SPELLFAMILY_HUNTER:
if(m_spellProto->SpellFamilyFlags & UI64LIT(0x1000000000000000))
removeState = AURA_STATE_FAERIE_FIRE; // Sting (hunter versions)
}
// this has been last aura
if(!found)
m_target->ModifyAuraState(AuraState(removeState), false);
}
// reset cooldown state for spells
if(caster && caster->GetTypeId() == TYPEID_PLAYER)
{
if ( GetSpellProto()->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE )
// note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases)
((Player*)caster)->SendCooldownEvent(GetSpellProto());
// Remove state (but need check other auras for it)
if (removeState)
{
bool found = false;
Unit::AuraMap& Auras = m_target->GetAuras();
for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i)
{
SpellEntry const *auraSpellInfo = (*i).second->GetSpellProto();
if(auraSpellInfo->SpellFamilyName == m_spellProto->SpellFamilyName &&
(auraSpellInfo->SpellFamilyFlags & removeFamilyFlag || auraSpellInfo->SpellFamilyFlags2 & removeFamilyFlag2))
{
found = true;
break;
}
}
// this has been last aura
if(!found)
m_target->ModifyAuraState(AuraState(removeState), false);
}
// reset cooldown state for spells
if(caster && caster->GetTypeId() == TYPEID_PLAYER)
{
if ( GetSpellProto()->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE )
// note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases)
((Player*)caster)->SendCooldownEvent(GetSpellProto());
}
}
return true;