aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp2
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuras.cpp91
-rwxr-xr-xsrc/server/game/Spells/SpellMgr.h11
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