aboutsummaryrefslogtreecommitdiff
path: root/src/game/Unit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/Unit.cpp')
-rw-r--r--src/game/Unit.cpp116
1 files changed, 60 insertions, 56 deletions
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index e08d4c2d43e..21a6ec75e7e 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -159,7 +159,6 @@ Unit::Unit()
for (int i = 0; i < MAX_MOVE_TYPE; ++i)
m_speed_rate[i] = 1.0f;
- m_removedAuras = 0;
m_charmInfo = NULL;
m_unit_movement_flags = 0;
m_reducedThreatPercent = 0;
@@ -182,6 +181,14 @@ Unit::~Unit()
}
}
+ for (AuraList::iterator i = m_removedAuras.begin(); i != m_removedAuras.end();i = m_removedAuras.begin())
+ {
+ Aura * aur = *i;
+ sLog.outDebug("Aura %d is deleted from unit %d", aur->GetId(), GetGUIDLow());
+ m_removedAuras.pop_front();
+ delete (aur);
+ }
+
RemoveAllGameObjects();
RemoveAllDynObjects();
@@ -472,7 +479,10 @@ void Unit::RemoveAurasWithInterruptFlags(uint32 flag, uint32 except)
++iter;
if ((aur->GetSpellProto()->AuraInterruptFlags & flag) && (!except || aur->GetId() != except))
{
+ uint32 removedAuras = m_removedAuras.size();
RemoveAura(aur);
+ if (removedAuras+1<m_removedAuras.size())
+ iter=m_interruptableAuras.begin();
}
}
@@ -513,7 +523,10 @@ void Unit::RemoveSpellbyDamageTaken(uint32 damage, uint32 spell)
++iter;
if ((!spell || aur->GetId() != spell) && roll_chance_f(chance))
{
+ uint32 removedAuras = m_removedAuras.size();
RemoveAura(aur);
+ if (removedAuras+1<m_ccAuras.size())
+ iter=m_interruptableAuras.begin();
}
}
}
@@ -1659,7 +1672,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
// victim's damage shield
std::set<AuraEffect*> alreadyDone;
- uint32 removedAuras = pVictim->m_removedAuras;
+ uint32 removedAuras = pVictim->m_removedAuras.size();
AuraEffectList const& vDamageShields = pVictim->GetAurasByType(SPELL_AURA_DAMAGE_SHIELD);
for(AuraEffectList::const_iterator i = vDamageShields.begin(), next = vDamageShields.begin(); i != vDamageShields.end(); i = next)
{
@@ -1688,9 +1701,9 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
pVictim->DealDamage(this, damage, 0, SPELL_DIRECT_DAMAGE, GetSpellSchoolMask(spellProto), spellProto, true);
- if (pVictim->m_removedAuras > removedAuras)
+ if (pVictim->m_removedAuras.size() > removedAuras)
{
- removedAuras = pVictim->m_removedAuras;
+ removedAuras = pVictim->m_removedAuras.size();
next = vDamageShields.begin();
}
}
@@ -2083,7 +2096,10 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
++i;
if (auraeff->GetAmount()<=0)
{
+ uint32 removedAuras = pVictim->m_removedAuras.size();
pVictim->RemoveAura(aura);
+ if (removedAuras+1<pVictim->m_removedAuras.size())
+ i=vSchoolAbsorb.begin();
}
}
}
@@ -3199,7 +3215,6 @@ void Unit::_UpdateSpells( uint32 time )
}
// TODO: Find a better way to prevent crash when multiple auras are removed.
- m_removedAuras = 0;
for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end(); ++i)
i->second->SetUpdated(false);
@@ -3212,18 +3227,16 @@ void Unit::_UpdateSpells( uint32 time )
continue;
aur->SetUpdated(true);
- aur->SetInUse(true);
+ uint32 removedAuras = m_removedAuras.size();
aur->Update( time );
- aur->SetInUse(false);
// several auras can be deleted due to update
- if(m_removedAuras)
+ if(removedAuras < m_removedAuras.size())
{
- m_removedAuras = 0;
i = m_Auras.begin();
}
else
- ++i;
+ ++i;
}
for(AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end();)
@@ -3234,6 +3247,14 @@ void Unit::_UpdateSpells( uint32 time )
++i;
}
+ for (AuraList::iterator i = m_removedAuras.begin(); i != m_removedAuras.end();i = m_removedAuras.begin())
+ {
+ Aura * aur = *i;
+ sLog.outDebug("Aura %d is deleted from unit %d", aur->GetId(), GetGUIDLow());
+ m_removedAuras.pop_front();
+ delete (aur);
+ }
+
if(!m_gameObj.empty())
{
std::list<GameObject*>::iterator ite1, dnext1;
@@ -3787,7 +3808,6 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
{
next = i;
++next;
- if ((*i).second->IsInUse()) continue;
SpellEntry const* i_spellProto = (*i).second->GetSpellProto();
@@ -3863,12 +3883,9 @@ void Unit::RemoveAura(uint32 spellId, uint64 caster ,AuraRemoveMode removeMode)
void Unit::RemoveAura(Aura * aur ,AuraRemoveMode mode)
{
- if (aur->IsInUse())
- {
- if (!aur->GetRemoveMode())
- aur->RemoveAura(mode);
+ // no need to remove
+ if (aur->IsRemoved())
return;
- }
for(AuraMap::iterator iter = m_Auras.lower_bound(aur->GetId()); iter != m_Auras.upper_bound(aur->GetId());)
{
if (aur == iter->second)
@@ -3885,7 +3902,7 @@ void Unit::RemoveAurasDueToSpell(uint32 spellId, uint64 caster ,AuraRemoveMode r
{
for(AuraMap::iterator iter = m_Auras.lower_bound(spellId); iter != m_Auras.upper_bound(spellId);)
{
- if ((!caster || iter->second->GetCasterGUID()==caster) && (!iter->second->IsInUse() || !iter->second->GetRemoveMode()))
+ if (!caster || iter->second->GetCasterGUID()==caster)
{
RemoveAura(iter, removeMode);
iter = m_Auras.lower_bound(spellId);
@@ -3964,9 +3981,9 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit
// Unregister _before_ adding to stealer
aur->UnregisterSingleCastAura();
-
// strange but intended behaviour: Stolen single target auras won't be treated as single targeted
new_aur->SetIsSingleTarget(false);
+ stealer->AddAura(new_aur);
RemoveAuraFromStack(iter, AURA_REMOVE_BY_ENEMY_SPELL);
return;
}
@@ -3979,7 +3996,7 @@ void Unit::RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId)
{
for (AuraMap::iterator iter = m_Auras.lower_bound(spellId); iter != m_Auras.upper_bound(spellId);)
{
- if ((!castItem || iter->second->GetCastItemGUID()==castItem->GetGUID()) && (!iter->second->IsInUse() || !iter->second->GetRemoveMode()))
+ if (!castItem || iter->second->GetCastItemGUID()==castItem->GetGUID())
{
RemoveAura(iter);
iter = m_Auras.upper_bound(spellId); // overwrite by more appropriate
@@ -3998,7 +4015,10 @@ void Unit::RemoveAurasByType(AuraType auraType, uint64 casterGUID, Aura * except
++iter;
if (aur != except && (!casterGUID || aur->GetCasterGUID()==casterGUID))
{
+ uint32 removedAuras = m_removedAuras.size();
RemoveAura(aur);
+ if (removedAuras+1<m_removedAuras.size())
+ iter=m_modAuras[auraType].begin();
}
}
}
@@ -4012,7 +4032,10 @@ void Unit::RemoveAurasByTypeWithDispel(AuraType auraType, Spell * spell)
++iter;
if (GetDispelChance(spell, aur->GetCaster(), aur->GetId()))
{
+ uint32 removedAuras = m_removedAuras.size();
RemoveAura(aur, AURA_REMOVE_BY_ENEMY_SPELL);
+ if (removedAuras+1<m_removedAuras.size())
+ iter=m_modAuras[auraType].begin();
}
}
}
@@ -4032,35 +4055,26 @@ void Unit::RemoveNotOwnSingleTargetAuras()
AuraList& scAuras = GetSingleCastAuras();
for (AuraList::iterator iter = scAuras.begin(); iter != scAuras.end();)
{
- if ((*iter)->GetTarget()!=this)
+ Aura * aur=*iter;
+ ++iter;
+ if (aur->GetTarget()!=this)
{
- Aura * aur=*iter;
- ++iter;
+ uint32 removedAuras = m_removedAuras.size();
aur->GetTarget()->RemoveAura(aur->GetId(),aur->GetCasterGUID());
+ if (removedAuras+1<m_removedAuras.size())
+ iter=scAuras.begin();
}
- else
- ++iter;
}
}
void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
{
Aura* Aur = i->second;
- //aura can be during update when removing, set it to remove at next update
- if (Aur->IsInUse())
- {
- if (!Aur->GetRemoveMode())
- Aur->RemoveAura(mode);
- i++;
- return;
- }
-
SpellEntry const* AurSpellInfo = Aur->GetSpellProto();
// 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_removedAuras; // internal count used by unit update
Aur->UnregisterSingleCastAura();
@@ -4077,10 +4091,6 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
m_ccAuras.remove(Aur);
}
- // Set remove mode if mode already not set
- if (!Aur->GetRemoveMode())
- Aur->SetRemoveMode(mode);
-
// Statue unsummoned at aura remove
Totem* statue = NULL;
bool channeled = false;
@@ -4129,11 +4139,15 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
}
}
+ Aur->SetRemoveMode(mode);
+
sLog.outDebug("Aura %u now is remove mode %d", Aur->GetId(), mode);
Aur->HandleEffects(false);
- Aur->_RemoveAura();
- delete Aur;
+ // set aura to be removed during unit::_updatespells
+ m_removedAuras.push_back(Aur);
+
+ Aur->_RemoveAura();
if(statue)
statue->UnSummon();
@@ -11475,10 +11489,6 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
if (!parentAura)
continue;
- bool inuse = parentAura->IsInUse();
- if (!inuse)
- parentAura->SetInUse(true);
-
bool useCharges= parentAura->GetAuraCharges()>0;
bool takeCharges = false;
@@ -11611,19 +11621,11 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
}
takeCharges=true;
}
- if (!inuse)
- parentAura->SetInUse(false);
-
- if ( !parentAura->GetAuraDuration() && !(parentAura->IsPermanent() || (parentAura->IsPassive())) )
- RemoveAura(parentAura);
- else
+ // Remove charge (aura can be removed by triggers)
+ if(useCharges && takeCharges)
{
- // Remove charge (aura can be removed by triggers)
- if(useCharges && takeCharges)
- {
- if (parentAura->DropAuraCharge())
- RemoveAura(parentAura->GetId(),parentAura->GetCasterGUID());
- }
+ if (parentAura->DropAuraCharge())
+ RemoveAura(parentAura->GetId(),parentAura->GetCasterGUID());
}
}
}
@@ -13107,6 +13109,8 @@ void Unit::GetPartyMember(std::list<Unit*> &TagUnitMap, float radius)
void Unit::HandleAuraEffect(AuraEffect * aureff, bool apply)
{
+ if (aureff->GetParentAura()->IsRemoved())
+ return;
if (apply)
{
m_modAuras[aureff->GetAuraName()].push_back(aureff);