diff options
| -rwxr-xr-x | src/server/game/Entities/Unit/Unit.cpp | 2 | ||||
| -rwxr-xr-x | src/server/game/Spells/Auras/SpellAuras.cpp | 91 | ||||
| -rwxr-xr-x | src/server/game/Spells/SpellMgr.h | 11 | 
3 files changed, 64 insertions, 40 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index c3c2ceaa11d..dedfb4b28d1 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -3117,7 +3117,7 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellEntry const* newAura, uint          casterGUID = caster->GetGUID();      // passive and Incanter's Absorption and auras with different type can stack with themselves any number of times -    if (!IsPassiveSpell(newAura) && newAura->Id != 44413) +    if (!IsMultiSlotAura(newAura))      {          // check if cast item changed          uint64 castItemGUID = 0; diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 6a0c969822b..3f49fc2cf18 100755 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -960,7 +960,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b  {      Unit* target = aurApp->GetTarget();      AuraRemoveMode removeMode = aurApp->GetRemoveMode(); -    // spell_area table +    // handle spell_area table      SpellAreaForAreaMapBounds saBounds = sSpellMgr->GetSpellAreaForAuraMapBounds(GetId());      if (saBounds.first != saBounds.second)      { @@ -980,21 +980,69 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b              }          }      } -    // mods at aura apply -    if (apply) + +    // handle spell_linked_spell table +    uint32 customAttr = sSpellMgr->GetSpellCustomAttr(GetId()); +    if (!onReapply)      { -        // Apply linked auras (On first aura apply) -        if (sSpellMgr->GetSpellCustomAttr(GetId()) & SPELL_ATTR0_CU_LINK_AURA) +        // apply linked auras +        if (apply)          { -            if (const std::vector<int32> *spell_triggered = sSpellMgr->GetSpellLinked(GetId() + SPELL_LINK_AURA)) -                for (std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr) +            if (customAttr & SPELL_ATTR0_CU_LINK_AURA) +            { +                std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(GetId() + SPELL_LINK_AURA); +                for (std::vector<int32>::const_iterator itr = spellTriggered->begin(); itr != spellTriggered->end(); ++itr)                  {                      if (*itr < 0)                          target->ApplySpellImmune(GetId(), IMMUNITY_ID, -(*itr), true);                      else if (caster)                          caster->AddAura(*itr, target);                  } +            }          } +        else +        { +            // remove linked auras +            if (customAttr & SPELL_ATTR0_CU_LINK_REMOVE) +            { +                std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(-(int32)GetId()); +                for (std::vector<int32>::const_iterator itr = spellTriggered->begin(); itr != spellTriggered->end(); ++itr) +                { +                    if (*itr < 0) +                        target->RemoveAurasDueToSpell(-(*itr)); +                    else if (removeMode != AURA_REMOVE_BY_DEATH) +                        target->CastSpell(target, *itr, true, NULL, NULL, GetCasterGUID()); +                } +            } +            if (customAttr & SPELL_ATTR0_CU_LINK_AURA) +            { +                std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(GetId() + SPELL_LINK_AURA); +                for (std::vector<int32>::const_iterator itr = spellTriggered->begin(); itr != spellTriggered->end(); ++itr) +                { +                    if (*itr < 0) +                        target->ApplySpellImmune(GetId(), IMMUNITY_ID, -(*itr), false); +                    else +                        target->RemoveAura(*itr, GetCasterGUID(), 0, removeMode); +                } +            } +        } +    } +    else if (apply) +    { +        // modify stack amount of linked auras +        if (customAttr & SPELL_ATTR0_CU_LINK_AURA) +        { +            std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(GetId() + SPELL_LINK_AURA); +            for (std::vector<int32>::const_iterator itr = spellTriggered->begin(); itr != spellTriggered->end(); ++itr) +                if (*itr > 0) +                    if (Aura* triggeredAura = target->GetAura(*itr, GetCasterGUID())) +                        triggeredAura->ModStackAmount(GetStackAmount() - triggeredAura->GetStackAmount()); +        } +    } + +    // mods at aura apply +    if (apply) +    {          switch (GetSpellProto()->SpellFamilyName)          {              case SPELLFAMILY_GENERIC: @@ -1201,35 +1249,6 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b      // mods at aura remove      else      { -        // Remove Linked Auras -        if (!onReapply && removeMode != AURA_REMOVE_BY_DEATH) -        { -            if (uint32 customAttr = sSpellMgr->GetSpellCustomAttr(GetId())) -            { -                if (customAttr & SPELL_ATTR0_CU_LINK_REMOVE) -                { -                    if (const std::vector<int32> *spell_triggered = sSpellMgr->GetSpellLinked(-(int32)GetId())) -                        for (std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr) -                        { -                            if (*itr < 0) -                                target->RemoveAurasDueToSpell(-(*itr)); -                            else if (removeMode != AURA_REMOVE_BY_DEFAULT) -                                target->CastSpell(target, *itr, true, NULL, NULL, GetCasterGUID()); -                        } -                } -                if (customAttr & SPELL_ATTR0_CU_LINK_AURA) -                { -                    if (const std::vector<int32> *spell_triggered = sSpellMgr->GetSpellLinked(GetId() + SPELL_LINK_AURA)) -                        for (std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr) -                        { -                            if (*itr < 0) -                                target->ApplySpellImmune(GetId(), IMMUNITY_ID, -(*itr), false); -                            else -                                target->RemoveAurasDueToSpell(*itr); -                        } -                } -            } -        }          switch(GetSpellProto()->SpellFamilyName)          {              case SPELLFAMILY_GENERIC: diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 4c2ce3741c0..c6d875bf0cf 100755 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -311,6 +311,11 @@ inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto)      return !IsSpellHaveEffect(spellProto, SPELL_EFFECT_APPLY_AURA);  } +inline bool IsMultiSlotAura(SpellEntry const* spellProto) +{ +    return IsPassiveSpell(spellProto) || spellProto->Id == 44413; +} +  inline bool IsDeathPersistentSpell(SpellEntry const *spellInfo)  {      return spellInfo->AttributesEx3 & SPELL_ATTR3_DEATH_PERSISTENT; @@ -723,7 +728,7 @@ enum ProcFlagsSpellPhase  enum ProcFlagsHit  { -    PROC_HIT_NONE                = 0x0000000, // no value - PROC_HIT_NORMAL | PROC_HIT_CRITICAL for TAKEN proc type, PROC_HIT_NORMAL | PROC_HIT_CRITICAL | PROC_HIT_ABSORB +    PROC_HIT_NONE                = 0x0000000, // no value - PROC_HIT_NORMAL | PROC_HIT_CRITICAL for TAKEN proc type, PROC_HIT_NORMAL | PROC_HIT_CRITICAL | PROC_HIT_ABSORB for DONE      PROC_HIT_NORMAL              = 0x0000001, // non-critical hits      PROC_HIT_CRITICAL            = 0x0000002,      PROC_HIT_MISS                = 0x0000004, @@ -769,8 +774,8 @@ struct SpellProcEntry      uint32      spellTypeMask;                              // if nonzero - bitmask for matching proc condition based on candidate spell's damage/heal effects, see enum ProcFlagsSpellType      uint32      spellPhaseMask;                             // if nonzero - bitmask for matching phase of a spellcast on which proc occurs, see enum ProcFlagsSpellPhase      uint32      hitMask;                                    // if nonzero - bitmask for matching proc condition based on hit result, see enum ProcFlagsHit -    uint32      attributesMask; -    float       ratePerMinute;                              // if nonzero - chance to proc is equal to value * weapon speed / 60 +    uint32      attributesMask;                             // bitmask, see ProcAttributes +    float       ratePerMinute;                              // if nonzero - chance to proc is equal to value * aura caster's weapon speed / 60      float       chance;                                     // if nonzero - owerwrite procChance field for given Spell.dbc entry, defines chance of proc to occur, not used if perMinuteRate set      float       cooldown;                                   // if nonzero - cooldown in secs for aura proc, applied to aura      uint32      charges;                                    // if nonzero - owerwrite procCharges field for given Spell.dbc entry, defines how many times proc can occur before aura remove, 0 - infinite  | 
