aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormegamage <none@none>2009-08-12 21:24:15 -0500
committermegamage <none@none>2009-08-12 21:24:15 -0500
commit5cd6c7c4f71711ecf5b9eb4b7cff9b7c6156fee8 (patch)
tree0c5f8a2e0934d2c7248977348c56995848bc68ad /src
parent32e960d5bc75fe8dfac2bb902c470d8904210924 (diff)
*Implement m_AurasUpdateIterator. [8329] Author: VladimirMangos
--HG-- branch : trunk
Diffstat (limited to 'src')
-rw-r--r--src/game/SpellAuras.cpp2
-rw-r--r--src/game/SpellAuras.h3
-rw-r--r--src/game/Unit.cpp42
-rw-r--r--src/game/Unit.h1
4 files changed, 16 insertions, 32 deletions
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index fc66b5af7b8..ed5edbaad3e 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -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) :
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_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);
diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h
index 3c0f902792d..9c3b170a04c 100644
--- a/src/game/SpellAuras.h
+++ b/src/game/SpellAuras.h
@@ -102,9 +102,7 @@ class TRINITY_DLL_SPEC Aura
bool IsDeathPersistent() const { return m_isDeathPersist; }
bool IsRemovedOnShapeLost() const { return m_isRemovedOnShapeLost; }
bool CanBeSaved() const;
- bool IsUpdated() const { return m_updated; }
bool IsRemoved() const { return m_isRemoved; }
- void SetUpdated(bool val) { m_updated = val; }
bool IsPersistent() const;
bool IsAreaAura() const;
@@ -163,7 +161,6 @@ class TRINITY_DLL_SPEC Aura
bool m_positive:1;
bool m_permanent: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 IsVisible() const;
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 2fb789fca16..1b2b80c38bd 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -117,6 +117,7 @@ Unit::Unit()
//m_removeAuraTimer = 4;
//tmpAura = NULL;
+ m_AurasUpdateIterator = m_Auras.end();
m_Visibility = VISIBILITY_ON;
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.
- for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end(); ++i)
- i->second->SetUpdated(false);
-
- for(AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end();)
+ // update auras
+ // m_AurasUpdateIterator can be updated in inderect called code at aura remove to skip next planned to update but removed auras
+ for (m_AurasUpdateIterator = m_Auras.begin(); m_AurasUpdateIterator != m_Auras.end();)
{
- Aura *aur = i->second;
-
- // prevent double update
- 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;
+ Aura* i_aura = m_AurasUpdateIterator->second;
+ ++m_AurasUpdateIterator; // need shift to next for allow update if need into aura update
+ i_aura->Update(time);
}
+ // remove expired auras
for(AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end();)
{
if(i->second->IsExpired())
@@ -4262,10 +4243,15 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
{
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
// remove aura from list before to prevent deleting it before
m_Auras.erase(i);
- m_removedAurasCount += 1;
+
+ ++m_removedAurasCount;
Aur->UnregisterSingleCastAura();
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 6a8515480c7..21b92bfb7ad 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1846,6 +1846,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
DeathState m_deathState;
AuraMap m_Auras;
+ AuraMap::iterator m_AurasUpdateIterator;
uint32 m_removedAurasCount;
int32 m_procDeep;