diff options
| -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)          }      }  } - | 
