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:
QAston
2011-06-26 19:31:11 +02:00
parent d2e1f5a259
commit faaba1aa65
3 changed files with 64 additions and 40 deletions

View File

@@ -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;

View File

@@ -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:

View File

@@ -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