diff options
Diffstat (limited to 'src')
-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 |