diff options
-rw-r--r-- | src/game/Player.cpp | 30 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 54 | ||||
-rw-r--r-- | src/game/SpellAuras.h | 9 | ||||
-rw-r--r-- | src/game/Unit.cpp | 99 |
4 files changed, 62 insertions, 130 deletions
diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 9227cb7414c..8dcb28224f7 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -6309,26 +6309,27 @@ void Player::DuelComplete(DuelCompleteType type) duel->initiator->RemoveGameObject(obj,true); /* remove auras */ - std::vector<uint32> auras2remove; - AuraMap const& vAuras = duel->opponent->GetAuras(); - for (AuraMap::const_iterator i = vAuras.begin(); i != vAuras.end(); ++i) + AuraMap & vAuras = duel->opponent->GetAuras(); + for(AuraMap::iterator i = vAuras.begin(); i != vAuras.end();) { if (!i->second->IsPositive() && i->second->GetCasterGUID() == GetGUID() && i->second->GetAuraApplyTime() >= duel->startTime) - auras2remove.push_back(i->second->GetId()); + { + RemoveAura(i); + } + else + ++i; } - for(size_t i=0; i<auras2remove.size(); i++) - duel->opponent->RemoveAurasDueToSpell(auras2remove[i], GetGUID()); - - auras2remove.clear(); - AuraMap const& auras = GetAuras(); - for (AuraMap::const_iterator i = auras.begin(); i != auras.end(); ++i) + vAuras = GetAuras(); + for(AuraMap::iterator i = vAuras.begin(); i != vAuras.end();) { if (!i->second->IsPositive() && i->second->GetCasterGUID() == duel->opponent->GetGUID() && i->second->GetAuraApplyTime() >= duel->startTime) - auras2remove.push_back(i->second->GetId()); + { + RemoveAura(i); + } + else + ++i; } - for(size_t i=0; i<auras2remove.size(); i++) - RemoveAurasDueToSpell(auras2remove[i], duel->opponent->GetGUID()); // cleanup combo points if(GetComboTarget()==duel->opponent->GetGUID()) @@ -19052,8 +19053,7 @@ void Player::RemoveItemDependentAurasAndCasts( Item * pItem ) } // no alt item, remove aura, restart check - RemoveAurasDueToSpell(aura->GetId()); - itr = auras.begin(); + RemoveAura(itr); } // currently casted spells can be dependent from item diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 036209c86f7..0484a9265ad 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -345,7 +345,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= Aura::Aura(SpellEntry const* spellproto, uint32 effMask, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) : m_caster_guid(0), m_castItemGuid(castItem?castItem->GetGUID():0), m_target(target), m_timeCla(1000), m_removeMode(AURA_NO_REMOVE_MODE), m_AuraDRGroup(DIMINISHING_NONE), -m_auraSlot(MAX_AURAS), m_auraLevel(1), m_procCharges(0), m_stackAmount(1),m_auraStateMask(0), m_updated(false), m_duringUpdate(false) +m_auraSlot(MAX_AURAS), m_auraLevel(1), m_procCharges(0), m_stackAmount(1),m_auraStateMask(0), m_updated(false), m_in_use(false) { assert(target); @@ -456,7 +456,7 @@ Aura::~Aura() AuraEffect::AuraEffect(Aura * parentAura, uint8 effIndex, int32 * currentBasePoints , Unit * caster, Item* castItem) : m_parentAura(parentAura), m_spellmod(NULL), m_periodicTimer(0), m_isPeriodic(false), m_isAreaAura(false), m_isPersistent(false), -m_in_use(false), m_target(parentAura->GetTarget()) +m_target(parentAura->GetTarget()) { m_spellProto = parentAura->GetSpellProto(); m_effIndex = effIndex; @@ -676,7 +676,6 @@ void Aura::Update(uint32 diff) } } - m_duringUpdate=true; for (uint8 i = 0; i<MAX_SPELL_EFFECTS;++i) if (m_partAuras[i]) { @@ -687,7 +686,6 @@ void Aura::Update(uint32 diff) else m_partAuras[i]->Update(diff); } - m_duringUpdate=false; } void AuraEffect::Update(uint32 diff) @@ -856,10 +854,13 @@ void AuraEffect::ApplyModifier(bool apply, bool Real) { AuraType aura = m_auraName; - m_in_use = true; + bool inuse = GetParentAura()->IsInUse(); + if (!inuse) + GetParentAura()->SetInUse(true); if(aura<TOTAL_AURAS) (*this.*AuraHandler [aura])(apply,Real); - m_in_use = false; + if (!inuse) + GetParentAura()->SetInUse(false); } void AuraEffect::CleanupTriggeredSpells() @@ -1261,19 +1262,6 @@ bool Aura::DropAuraCharge() return m_procCharges == 0; } -bool Aura::IsInUse() const -{ - for (uint8 i=0; i<MAX_SPELL_EFFECTS;++i) - { - if (m_partAuras[i]) - { - if (m_partAuras[i]->IsInUse()) - return true; - } - } - return false; -} - bool Aura::IsPersistent() const { for (uint8 i=0; i<MAX_SPELL_EFFECTS;++i) @@ -1453,8 +1441,7 @@ void AuraEffect::HandleShapeshiftBoosts(bool apply) { if (itr->second->IsRemovedOnShapeLost()) { - m_target->RemoveAurasDueToSpell(itr->second->GetId()); - itr = tAuras.begin(); + m_target->RemoveAura(itr); } else { @@ -4076,10 +4063,8 @@ void AuraEffect::HandleModMechanicImmunity(bool apply, bool Real) if(apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY) { Unit::AuraMap& Auras = m_target->GetAuras(); - for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) + for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end();) { - next = iter; - ++next; SpellEntry const *spell = iter->second->GetSpellProto(); if (!( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) && // spells unaffected by invulnerability spell->Id != GetId()) @@ -4087,13 +4072,12 @@ void AuraEffect::HandleModMechanicImmunity(bool apply, bool Real) //check for mechanic mask if(GetAllSpellMechanicMask(spell) & mechanic) { - m_target->RemoveAurasDueToSpell(spell->Id); - if(Auras.empty()) - break; - else - next = Auras.begin(); + m_target->RemoveAura(iter); } + else + ++iter; } + ++iter; } } @@ -4213,10 +4197,8 @@ void AuraEffect::HandleAuraModSchoolImmunity(bool apply, bool Real) { uint32 school_mask = GetMiscValue(); Unit::AuraMap& Auras = m_target->GetAuras(); - for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) + for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end();) { - next = iter; - ++next; SpellEntry const *spell = iter->second->GetSpellProto(); if((GetSpellSchoolMask(spell) & school_mask)//Check for school mask && !( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) //Spells unaffected by invulnerability @@ -4224,11 +4206,9 @@ void AuraEffect::HandleAuraModSchoolImmunity(bool apply, bool Real) && spell->Id != GetId() ) //Don't remove self { m_target->RemoveAurasDueToSpell(spell->Id); - if(Auras.empty()) - break; - else - next = Auras.begin(); } + else + ++iter; } } if( Real && GetSpellProto()->Mechanic == MECHANIC_BANISH ) @@ -5670,7 +5650,7 @@ void AuraEffect::PeriodicTick() 100; if(m_target->GetHealth()*100 >= m_target->GetMaxHealth()*percent ) { - m_target->RemoveAurasDueToSpell(GetId()); + GetParentAura()->RemoveAura(); return; } break; diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index ef2a92c6a9b..5bc03e7beb4 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -98,10 +98,11 @@ class TRINITY_DLL_SPEC Aura bool IsDeathPersistent() const { return m_isDeathPersist; } bool IsRemovedOnShapeLost() const { return m_isRemovedOnShapeLost; } bool IsUpdated() const { return m_updated; } - bool IsDuringUpdate() const { return m_duringUpdate; } void SetUpdated(bool val) { m_updated = val; } - bool IsInUse() const; + bool IsInUse() const { return m_in_use; } + void SetInUse(bool val) { m_in_use = val; } + bool IsPersistent() const; bool IsAreaAura() const; bool IsAuraType(AuraType type) const; @@ -158,7 +159,7 @@ class TRINITY_DLL_SPEC Aura bool m_positive:1; bool m_permanent:1; bool m_updated:1; // Prevent remove aura by stack if set - bool m_duringUpdate:1; // Prevent remove aura by stack if set + bool m_in_use:1; bool m_isSingleTargetAura:1; // true if it's a single target spell and registered at caster - can change at spell steal for example }; class TRINITY_DLL_SPEC AuraEffect @@ -337,7 +338,6 @@ class TRINITY_DLL_SPEC AuraEffect bool IsAreaAura() const { return m_isAreaAura; } bool IsPeriodic() const { return m_isPeriodic; } - bool IsInUse() const { return m_in_use;} bool IsPersistent() const { return m_isPersistent; } bool isAffectedOnSpell(SpellEntry const *spell) const; @@ -377,7 +377,6 @@ class TRINITY_DLL_SPEC AuraEffect bool m_isPeriodic:1; bool m_isAreaAura:1; - bool m_in_use:1; // true while in Aura::ApplyModifier call bool m_isPersistent:1; }; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index c9f7adc6a81..def8f0c1f3a 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -3231,7 +3231,9 @@ void Unit::_UpdateSpells( uint32 time ) if ((*i).second->IsUpdated()) continue; (*i).second->SetUpdated(true); + (*i).second->SetInUse(true); (*i).second->Update( time ); + (*i).second->SetInUse(false); // several auras can be deleted due to update if (m_removedAuras) { @@ -3752,11 +3754,6 @@ bool Unit::AddAura(Aura *Aur) if( (*itr)->GetTarget() != Aur->GetTarget() && IsSingleTargetSpells((*itr)->GetSpellProto(),aurSpellInfo) ) { - if ((*itr)->IsInUse()) - { - sLog.outError("Aura (Spell %u) is in process but attempt removed at aura (Spell %u) adding, need add stack rule for IsSingleTargetSpell", (*itr)->GetId(),Aur->GetId()); - continue; - } (*itr)->GetTarget()->RemoveAurasDueToSpell((*itr)->GetId(), caster->GetGUID(), AURA_REMOVE_BY_STACK); restart = true; break; @@ -3800,8 +3797,6 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) return false; SpellEntry const* spellProto = Aur->GetSpellProto(); - if (!spellProto) - return false; uint32 spellId = Aur->GetId(); @@ -3821,13 +3816,10 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) { next = i; ++next; - if (!(*i).second) continue; + if ((*i).second->IsInUse()) continue; SpellEntry const* i_spellProto = (*i).second->GetSpellProto(); - if (!i_spellProto) - continue; - uint32 i_spellId = i_spellProto->Id; if(IsPassiveSpell(i_spellId)) @@ -3877,20 +3869,8 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) &&(IsHigherHankOfSpell(spellId,i_spellId))) return false; - // Its a parent aura (create this aura in ApplyModifier) - if ((*i).second->IsInUse()) - { - sLog.outError("Aura (Spell %u) is in process but attempt removed at aura (Spell %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(),Aur->GetId()); - continue; - } - // Remove all auras by aura caster - RemoveAurasDueToSpell(i_spellId , (*i).second->GetCasterGUID(), AURA_REMOVE_BY_STACK); - - if( m_Auras.empty()) - break; - else - next = m_Auras.begin(); + RemoveAura(i, AURA_REMOVE_BY_STACK); } return true; } @@ -3899,7 +3879,7 @@ void Unit::RemoveAura(uint32 spellId, uint64 caster ,AuraRemoveMode removeMode) { for(AuraMap::iterator iter = m_Auras.lower_bound(spellId); iter != m_Auras.upper_bound(spellId);) { - if ((!caster || iter->second->GetCasterGUID()==caster) && !iter->second->IsDuringUpdate()) + if (!caster || iter->second->GetCasterGUID()==caster) { RemoveAura(iter, removeMode); return; @@ -3913,7 +3893,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->IsDuringUpdate()) + if ((!caster || iter->second->GetCasterGUID()==caster) && (!iter->second->IsInUse() || !iter->second->GetRemoveMode())) { RemoveAura(iter, removeMode); iter = m_Auras.lower_bound(spellId); @@ -4007,7 +3987,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->IsDuringUpdate()) + if ((!castItem || iter->second->GetCastItemGUID()==castItem->GetGUID()) && (!iter->second->IsInUse() || !iter->second->GetRemoveMode())) { RemoveAura(iter); iter = m_Auras.upper_bound(spellId); // overwrite by more appropriate @@ -4075,7 +4055,7 @@ 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->IsDuringUpdate()) + if (Aur->IsInUse()) { Aur->RemoveAura(); i++; @@ -4158,7 +4138,6 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) } sLog.outDebug("Aura %u now is remove mode %d", Aur->GetId(), mode); - assert(!Aur->IsInUse()); Aur->HandleEffects(false); Aur->_RemoveAura(); @@ -11499,35 +11478,26 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag // Nothing found if (procTriggered.empty()) return; + Aura * parentAura = NULL; // Handle effects proceed this time for(ProcTriggeredList::iterator i = procTriggered.begin(); i != procTriggered.end(); ++i) { - bool found=true; - bool useCharges=false; - Aura * parentAura = NULL; + // look for parent aura in auras list, it may be removed while proc even processing + parentAura = GetAura(i->spellId, i->casterGUID); + if (!parentAura) + continue; + + bool inuse = parentAura->IsInUse(); + if (!inuse) + parentAura->SetInUse(true); + + bool useCharges= parentAura->GetAuraCharges()>0; bool takeCharges = false; - for (uint8 j = 0; j<MAX_SPELL_EFFECTS && found;++j) + + for (uint8 j = 0; j<MAX_SPELL_EFFECTS;++j) { if (!i->triggeringAura[j]) continue; - // Some auras can be deleted in function called in this loop (except first, ofc) - // Until storing auars in std::multimap to hard check deleting by another way - if(i != procTriggered.begin()) - { - if(!GetAura(i->spellId, i->casterGUID)) - { -// sLog.outDebug("Spell aura %u (id:%u effect:%u) has been deleted before call spell proc event handler", i->triggeredByAura->GetModifier()->m_auraname, i->triggeredByAura_SpellPair.first, i->triggeredByAura_SpellPair.second); -// sLog.outDebug("It can be deleted one from early proccesed auras:"); -// for(ProcTriggeredList::iterator i2 = procTriggered.begin(); i != i2; ++i2) -// sLog.outDebug(" Spell aura %u (id:%u effect:%u)", i->triggeredByAura->GetModifier()->m_auraname,i2->triggeredByAura_SpellPair.first,i2->triggeredByAura_SpellPair.second); -// sLog.outDebug(" <end of list>"); - found=false; - break; - } - } - - if (!found) - continue; SpellProcEventEntry const *spellProcEvent = i->triggeringAura[j]->spellProcEvent; AuraEffect *triggeredByAura =triggeredByAura = i->triggeringAura[j]->triggeredByAura; @@ -11538,17 +11508,6 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag uint32 cooldown = 0; if (GetTypeId() == TYPEID_PLAYER && spellProcEvent && spellProcEvent->cooldown) cooldown = spellProcEvent->cooldown; - if (!parentAura) - { - parentAura=triggeredByAura->GetParentAura(); - if (!parentAura) - { - sLog.outError("Still null pointer here, something went wrong"); - found=false; - continue; - } - useCharges = parentAura->GetAuraCharges()>0; - } switch(triggeredByAura->GetAuraName()) { @@ -11660,19 +11619,13 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag } takeCharges=true; } + if (!inuse) + parentAura->SetInUse(false); // Remove charge (aura can be removed by triggers) - if(useCharges && found && takeCharges) + if(useCharges && takeCharges) { - // need found aura on drop (can be dropped by triggers) - for(AuraMap::iterator iter = m_Auras.lower_bound(i->spellId); iter != m_Auras.upper_bound(i->spellId);) - { - if (iter->second->GetCasterGUID()==i->casterGUID) - { - if (iter->second->DropAuraCharge()) - RemoveAura(iter); - break; - } - } + if (parentAura->DropAuraCharge()) + RemoveAura(parentAura->GetId(),parentAura->GetCasterGUID()); } } } |