diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/SpellAuras.cpp | 20 | ||||
-rw-r--r-- | src/game/SpellAuras.h | 6 | ||||
-rw-r--r-- | src/game/Unit.cpp | 23 |
3 files changed, 32 insertions, 17 deletions
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 63952c723b0..c2be850370c 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -352,6 +352,8 @@ m_periodicTimer(0), m_PeriodicEventId(0), m_AuraDRGroup(DIMINISHING_NONE) m_applyTime = time(NULL); + m_isSingleTargetAura = IsSingleTargetSpell(m_spellProto); + if(!caster) { m_caster_guid = target->GetGUID(); @@ -6176,3 +6178,21 @@ void Aura::HandleArenaPreparation(bool apply, bool Real) m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION); } +void Aura::UnregisterSingleCastAura() +{ + if (IsSingleTarget()) + { + Unit* caster = NULL; + caster = GetCaster(); + if(caster) + { + caster->GetSingleCastAuras().remove(this); + } + else + { + sLog.outError("Couldn't find the caster of the single target aura, may crash later!"); + assert(false); + } + m_isSingleTargetAura = false; + } +} diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index 40552a3cb40..245669456e9 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -310,6 +310,11 @@ class TRINITY_DLL_SPEC Aura int32 GetStackAmount() {return m_stackAmount;} void SetStackAmount(int32 amount) {m_stackAmount=amount;} + + // Single cast aura helpers + void UnregisterSingleCastAura(); + bool IsSingleTarget() const {return m_isSingleTargetAura;} + void SetIsSingleTarget(bool val) { m_isSingleTargetAura = val;} protected: Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL); @@ -342,6 +347,7 @@ class TRINITY_DLL_SPEC Aura bool m_isRemovedOnShapeLost:1; bool m_updated:1; bool m_in_use:1; // true while in Aura::ApplyModifier call + bool m_isSingleTargetAura:1; // true if it's a single target spell and registered at caster - can change at spell steal for example int32 m_periodicTimer; uint32 m_PeriodicEventId; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 6c4e171e4f1..cac26755d3f 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -3822,7 +3822,7 @@ bool Unit::AddAura(Aura *Aur) } // update single target auras list (before aura add to aura list, to prevent unexpected remove recently added aura) - if (IsSingleTargetSpell(aurSpellInfo) && Aur->GetTarget()) + if (Aur->IsSingleTarget() && Aur->GetTarget()) { // caster pointer can be deleted in time aura remove, find it by guid at each iteration for(;;) @@ -4160,9 +4160,12 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit new_aur->SetAuraMaxDuration( max_dur > dur ? dur : max_dur ); new_aur->SetAuraDuration( max_dur > dur ? dur : max_dur ); + // 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); // add the new aura to stealer stealer->AddAura(new_aur); - // Remove aura as dispel RemoveAura(iter, AURA_REMOVE_BY_DISPEL); } @@ -4309,20 +4312,7 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) ++m_removedAuras; // internal count used by unit update Unit* caster = NULL; - if (IsSingleTargetSpell(AurSpellInfo)) - { - caster = Aur->GetCaster(); - if(caster) - { - AuraList& scAuras = caster->GetSingleCastAuras(); - scAuras.remove(Aur); - } - else - { - sLog.outError("Couldn't find the caster of the single target aura, may crash later!"); - assert(false); - } - } + Aur->UnregisterSingleCastAura(); // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order) if (Aur->GetModifier()->m_auraname < TOTAL_AURAS) @@ -13087,4 +13077,3 @@ void Unit::AddAura(uint32 spellId, Unit* target) } } } - |