mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-16 04:59:41 -04:00
Core/Auras: Improvements in spell_linked_spell table handling, now auras with using this table have linked stack amount, also linked aura removal is called now when aura is removed on target death.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user