*Implement m_AurasUpdateIterator. [8329] Author: VladimirMangos
--HG-- branch : trunk
This commit is contained in:
@@ -354,7 +354,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
|
|||||||
Aura::Aura(SpellEntry const* spellproto, uint32 effMask, int32 *currentBasePoints, Unit *target, WorldObject *source, Unit *caster, Item* castItem) :
|
Aura::Aura(SpellEntry const* spellproto, uint32 effMask, int32 *currentBasePoints, Unit *target, WorldObject *source, Unit *caster, Item* castItem) :
|
||||||
m_caster_guid(0), m_castItemGuid(castItem?castItem->GetGUID():0), m_target(target),
|
m_caster_guid(0), m_castItemGuid(castItem?castItem->GetGUID():0), m_target(target),
|
||||||
m_timeCla(0), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_AuraDRGroup(DIMINISHING_NONE),
|
m_timeCla(0), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_AuraDRGroup(DIMINISHING_NONE),
|
||||||
m_auraSlot(MAX_AURAS), m_auraLevel(1), m_procCharges(0), m_stackAmount(1), m_updated(false), m_isRemoved(false)
|
m_auraSlot(MAX_AURAS), m_auraLevel(1), m_procCharges(0), m_stackAmount(1), m_isRemoved(false)
|
||||||
{
|
{
|
||||||
assert(target);
|
assert(target);
|
||||||
|
|
||||||
|
|||||||
@@ -102,9 +102,7 @@ class TRINITY_DLL_SPEC Aura
|
|||||||
bool IsDeathPersistent() const { return m_isDeathPersist; }
|
bool IsDeathPersistent() const { return m_isDeathPersist; }
|
||||||
bool IsRemovedOnShapeLost() const { return m_isRemovedOnShapeLost; }
|
bool IsRemovedOnShapeLost() const { return m_isRemovedOnShapeLost; }
|
||||||
bool CanBeSaved() const;
|
bool CanBeSaved() const;
|
||||||
bool IsUpdated() const { return m_updated; }
|
|
||||||
bool IsRemoved() const { return m_isRemoved; }
|
bool IsRemoved() const { return m_isRemoved; }
|
||||||
void SetUpdated(bool val) { m_updated = val; }
|
|
||||||
|
|
||||||
bool IsPersistent() const;
|
bool IsPersistent() const;
|
||||||
bool IsAreaAura() const;
|
bool IsAreaAura() const;
|
||||||
@@ -163,7 +161,6 @@ class TRINITY_DLL_SPEC Aura
|
|||||||
bool m_positive:1;
|
bool m_positive:1;
|
||||||
bool m_permanent:1;
|
bool m_permanent:1;
|
||||||
bool m_isRemoved:1;
|
bool m_isRemoved:1;
|
||||||
bool m_updated:1; // Prevent remove aura by stack if set
|
|
||||||
bool m_isSingleTargetAura:1; // true if it's a single target spell and registered at caster - can change at spell steal for example
|
bool m_isSingleTargetAura:1; // true if it's a single target spell and registered at caster - can change at spell steal for example
|
||||||
|
|
||||||
bool IsVisible() const;
|
bool IsVisible() const;
|
||||||
|
|||||||
+14
-28
@@ -117,6 +117,7 @@ Unit::Unit()
|
|||||||
//m_removeAuraTimer = 4;
|
//m_removeAuraTimer = 4;
|
||||||
//tmpAura = NULL;
|
//tmpAura = NULL;
|
||||||
|
|
||||||
|
m_AurasUpdateIterator = m_Auras.end();
|
||||||
m_Visibility = VISIBILITY_ON;
|
m_Visibility = VISIBILITY_ON;
|
||||||
|
|
||||||
m_interruptMask = 0;
|
m_interruptMask = 0;
|
||||||
@@ -3358,36 +3359,16 @@ void Unit::_UpdateSpells( uint32 time )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Find a better way to prevent crash when multiple auras are removed.
|
// update auras
|
||||||
for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end(); ++i)
|
// m_AurasUpdateIterator can be updated in inderect called code at aura remove to skip next planned to update but removed auras
|
||||||
i->second->SetUpdated(false);
|
for (m_AurasUpdateIterator = m_Auras.begin(); m_AurasUpdateIterator != m_Auras.end();)
|
||||||
|
|
||||||
for(AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end();)
|
|
||||||
{
|
{
|
||||||
Aura *aur = i->second;
|
Aura* i_aura = m_AurasUpdateIterator->second;
|
||||||
|
++m_AurasUpdateIterator; // need shift to next for allow update if need into aura update
|
||||||
// prevent double update
|
i_aura->Update(time);
|
||||||
if(aur->IsUpdated())
|
|
||||||
{
|
|
||||||
++i;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
aur->SetUpdated(true);
|
|
||||||
|
|
||||||
m_removedAurasCount = 0;
|
|
||||||
aur->Update( time );
|
|
||||||
|
|
||||||
// several auras can be deleted due to update
|
|
||||||
if(m_removedAurasCount)
|
|
||||||
{
|
|
||||||
m_removedAurasCount = 0;
|
|
||||||
i = m_Auras.begin();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove expired auras
|
||||||
for(AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end();)
|
for(AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end();)
|
||||||
{
|
{
|
||||||
if(i->second->IsExpired())
|
if(i->second->IsExpired())
|
||||||
@@ -4262,10 +4243,15 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
|
|||||||
{
|
{
|
||||||
Aura* Aur = i->second;
|
Aura* Aur = i->second;
|
||||||
|
|
||||||
|
// if unit currently update aura list then make safe update iterator shift to next
|
||||||
|
if (m_AurasUpdateIterator == i)
|
||||||
|
++m_AurasUpdateIterator;
|
||||||
|
|
||||||
// some ShapeshiftBoosts at remove trigger removing other auras including parent Shapeshift aura
|
// some ShapeshiftBoosts at remove trigger removing other auras including parent Shapeshift aura
|
||||||
// remove aura from list before to prevent deleting it before
|
// remove aura from list before to prevent deleting it before
|
||||||
m_Auras.erase(i);
|
m_Auras.erase(i);
|
||||||
m_removedAurasCount += 1;
|
|
||||||
|
++m_removedAurasCount;
|
||||||
|
|
||||||
Aur->UnregisterSingleCastAura();
|
Aur->UnregisterSingleCastAura();
|
||||||
|
|
||||||
|
|||||||
@@ -1846,6 +1846,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
|||||||
DeathState m_deathState;
|
DeathState m_deathState;
|
||||||
|
|
||||||
AuraMap m_Auras;
|
AuraMap m_Auras;
|
||||||
|
AuraMap::iterator m_AurasUpdateIterator;
|
||||||
uint32 m_removedAurasCount;
|
uint32 m_removedAurasCount;
|
||||||
int32 m_procDeep;
|
int32 m_procDeep;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user