[8994] Re-implement remove auras from channeled target

* Old way have problem with auras that have last tick avent at one from caster/target:
  depndent from auras update order in caster/target pair ti can wrongly not triggered.
* Fxied possible problem with remove same spell non-caster auras at target/caster at spell cast cancel
* Also fix memory lost in old deleted auras cleanup.
This commit is contained in:
VladimirMangos 2009-12-15 18:45:27 +03:00
parent 8211bcd218
commit be79375b56
4 changed files with 25 additions and 42 deletions

View file

@ -2417,11 +2417,10 @@ void Spell::cancel()
{
Unit* unit = m_caster->GetGUID()==(*ihit).targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
if( unit && unit->isAlive() )
unit->RemoveAurasDueToSpell(m_spellInfo->Id);
unit->RemoveAurasByCasterSpell(m_spellInfo->Id,m_caster->GetGUID());
}
}
m_caster->RemoveAurasDueToSpell(m_spellInfo->Id);
SendChannelUpdate(0);
SendInterrupted(0);
SendCastResult(SPELL_FAILED_INTERRUPTED);
@ -3441,6 +3440,13 @@ void Spell::SendChannelUpdate(uint32 time)
{
if(time == 0)
{
m_caster->RemoveAurasByCasterSpell(m_spellInfo->Id,m_caster->GetGUID());
if(uint64 target_guid = m_caster->GetChannelObjectGUID())
if(target_guid != m_caster->GetGUID() && IS_UNIT_GUID(target_guid))
if(Unit* target = ObjectAccessor::GetUnit(*m_caster, target_guid))
target->RemoveAurasByCasterSpell(m_spellInfo->Id,m_caster->GetGUID());
m_caster->SetChannelObjectGUID(0);
m_caster->SetUInt32Value(UNIT_CHANNEL_SPELL, 0);
}

View file

@ -176,6 +176,7 @@ Unit::~Unit()
// those should be already removed at "RemoveFromWorld()" call
assert(m_gameObj.size() == 0);
assert(m_dynObjGUIDs.size() == 0);
assert(m_deletedAuras.size() == 0);
}
void Unit::Update( uint32 p_time )
@ -196,6 +197,8 @@ void Unit::Update( uint32 p_time )
m_Events.Update( p_time );
_UpdateSpells( p_time );
CleanupDeletedAuars();
if (m_lastManaUseTimer)
{
if (p_time >= m_lastManaUseTimer)
@ -204,11 +207,6 @@ void Unit::Update( uint32 p_time )
m_lastManaUseTimer -= p_time;
}
// really delete auras "deleted" while processing its ApplyModify code
for(AuraList::const_iterator itr = m_deletedAuras.begin(); itr != m_deletedAuras.begin(); ++itr)
delete *itr;
m_deletedAuras.clear();
if (CanHaveThreatList())
getThreatManager().UpdateForClient(p_time);
@ -4254,19 +4252,10 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
// Statue unsummoned at aura remove
Totem* statue = NULL;
bool caster_channeled = false;
if(IsChanneledSpell(AurSpellInfo))
{
Unit* caster = Aur->GetCaster();
if(caster)
{
if(Unit* caster = Aur->GetCaster())
if(caster->GetTypeId()==TYPEID_UNIT && ((Creature*)caster)->isTotem() && ((Totem*)caster)->GetTotemType()==TOTEM_STATUE)
statue = ((Totem*)caster);
else
caster_channeled = caster==this;
}
}
sLog.outDebug("Aura %u now is remove mode %d",Aur->GetModifier()->m_auraname, mode);
if (mode != AURA_REMOVE_BY_DELETE) // not unapply if target will deleted
@ -4286,9 +4275,6 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
else
delete Aur;
if(caster_channeled)
RemoveAurasAtChanneledTarget (AurSpellInfo);
if(statue)
statue->UnSummon();
@ -4297,6 +4283,7 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
i = m_Auras.end();
else
i = m_Auras.begin();
}
void Unit::RemoveAllAuras(AuraRemoveMode mode /*= AURA_REMOVE_BY_DEFAULT*/)
@ -11417,6 +11404,7 @@ void Unit::RemoveFromWorld()
RemoveGuardians();
RemoveAllGameObjects();
RemoveAllDynObjects();
CleanupDeletedAuars();
}
Object::RemoveFromWorld();
@ -12828,26 +12816,6 @@ bool Unit::HandleMendingAuraProc( Aura* triggeredByAura )
return true;
}
void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo)
{
uint64 target_guid = GetChannelObjectGUID();
if(!IS_UNIT_GUID(target_guid))
return;
Unit* target = ObjectAccessor::GetUnit(*this, target_guid);
if(!target)
return;
for (AuraMap::iterator iter = target->GetAuras().begin(); iter != target->GetAuras().end(); )
{
if (iter->second->GetId() == spellInfo->Id && iter->second->GetCasterGUID()==GetGUID())
target->RemoveAura(iter);
else
++iter;
}
}
void Unit::RemoveAurasAtMechanicImmunity(uint32 mechMask, uint32 exceptSpellId, bool non_positive /*= false*/)
{
Unit::AuraMap& auras = GetAuras();
@ -13080,3 +13048,11 @@ void Unit::StopAttackFaction(uint32 faction_id)
if(Unit* guardian = Unit::GetUnit(*this,*itr))
guardian->StopAttackFaction(faction_id);
}
void Unit::CleanupDeletedAuars()
{
// really delete auras "deleted" while processing its ApplyModify code
for(AuraList::const_iterator itr = m_deletedAuras.begin(); itr != m_deletedAuras.end(); ++itr)
delete *itr;
m_deletedAuras.clear();
}

View file

@ -1247,7 +1247,6 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void RemoveAurasByCasterSpell(uint32 spellId, uint32 effindex, uint64 casterGUID);
void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer);
void RemoveAurasDueToSpellByCancel(uint32 spellId);
void RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo);
// removing unknown aura stacks by diff reasons and selections
void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0);
@ -1618,6 +1617,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
uint32 m_lastManaUseTimer;
private:
void CleanupDeletedAuars();
bool IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent );
bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "8993"
#define REVISION_NR "8994"
#endif // __REVISION_NR_H__