*Update rules of aura stack.

--HG--
branch : trunk
This commit is contained in:
megamage
2009-08-23 10:22:58 -05:00
parent d132f7e401
commit 0b06baee4d
5 changed files with 68 additions and 65 deletions

View File

@@ -266,7 +266,7 @@ enum SpellCategory
#define SPELL_ATTR_EX_UNK11 0x00000800 // 11 aura
#define SPELL_ATTR_EX_UNK12 0x00001000 // 12
#define SPELL_ATTR_EX_UNK13 0x00002000 // 13
#define SPELL_ATTR_EX_UNK14 0x00004000 // 14
#define SPELL_ATTR_EX_STACK_FOR_DIFF_CASTERS 0x00004000 // 14
#define SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY 0x00008000 // 15 remove auras on immunity
#define SPELL_ATTR_EX_UNK16 0x00010000 // 16 on immuniy
#define SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET 0x00020000 // 17
@@ -325,7 +325,7 @@ enum SpellCategory
#define SPELL_ATTR_EX3_UNK4 0x00000010 // 4 Druid Rebirth only this spell have this flag
#define SPELL_ATTR_EX3_UNK5 0x00000020 // 5
#define SPELL_ATTR_EX3_UNK6 0x00000040 // 6
#define SPELL_ATTR_EX3_STACKS_FOR_DIFFERENT_CASTERS 0x00000080 // 7 separate stack for every caster
#define SPELL_ATTR_EX3_STACK_FOR_DIFF_CASTERS 0x00000080 // 7 separate stack for every caster
#define SPELL_ATTR_EX3_PLAYERS_ONLY 0x00000100 // 8 Player only?
#define SPELL_ATTR_EX3_TRIGGERED_CAN_TRIGGER_2 0x00000200 // 9 triggered from effect?
#define SPELL_ATTR_EX3_MAIN_HAND 0x00000400 // 10 Main hand weapon required

View File

@@ -780,8 +780,7 @@ void AreaAuraEffect::Update(uint32 diff)
bool skip = false;
for(Unit::AuraMap::iterator iter = (*tIter)->GetAuras().begin(); iter != (*tIter)->GetAuras().end();++iter)
{
bool samecaster = iter->second->GetCasterGUID() == GetCasterGUID();
if(spellmgr.IsNoStackSpellDueToSpell(GetId(), iter->first, samecaster))
if(!spellmgr.CanAurasStack(GetSpellProto(), iter->second->GetSpellProto(), iter->second->GetCasterGUID() == GetCasterGUID()))
{
skip = true;
break;

View File

@@ -3002,94 +3002,98 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32
//-----------TRINITY-------------
bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool sameCaster) const
bool SpellMgr::CanAurasStack(SpellEntry const *spellInfo_1, SpellEntry const *spellInfo_2, bool sameCaster) const
{
SpellEntry const *spellInfo_1 = sSpellStore.LookupEntry(spellId_1);
SpellEntry const *spellInfo_2 = sSpellStore.LookupEntry(spellId_2);
if(!spellInfo_1 || !spellInfo_2)
return false;
SpellSpecific spellId_spec_1 = GetSpellSpecific(spellId_1);
SpellSpecific spellId_spec_2 = GetSpellSpecific(spellId_2);
if (spellId_spec_1 && spellId_spec_2)
if (IsSingleFromSpellSpecificPerTarget(spellId_spec_1, spellId_spec_2)
||(sameCaster && IsSingleFromSpellSpecificPerCaster(spellId_spec_1, spellId_spec_2)))
return true;
SpellSpecific spellSpec_1 = GetSpellSpecific(spellInfo_1->Id);
SpellSpecific spellSpec_2 = GetSpellSpecific(spellInfo_2->Id);
if (spellSpec_1 && spellSpec_2)
if (IsSingleFromSpellSpecificPerTarget(spellSpec_1, spellSpec_2)
|| sameCaster && IsSingleFromSpellSpecificPerCaster(spellSpec_1, spellSpec_2))
return false;
if(spellInfo_1->SpellFamilyName != spellInfo_2->SpellFamilyName)
return false;
return true;
if(!sameCaster)
{
if(spellInfo_1->AttributesEx & SPELL_ATTR_EX3_STACK_FOR_DIFF_CASTERS
|| spellInfo_1->AttributesEx3 & SPELL_ATTR_EX3_STACK_FOR_DIFF_CASTERS)
return true;
// check same periodic auras
for(uint32 i = 0; i < 3; ++i)
if (spellInfo_1->Effect[i] == SPELL_EFFECT_APPLY_AURA
|| spellInfo_1->Effect[i] == SPELL_EFFECT_PERSISTENT_AREA_AURA)
{
// area auras should not stack (shaman totem)
if(spellInfo_1->Effect[i] != SPELL_EFFECT_APPLY_AURA
&& spellInfo_1->Effect[i] != SPELL_EFFECT_PERSISTENT_AREA_AURA)
continue;
// not channeled AOE effects should not stack (blizzard should, but Consecration should not)
if((IsAreaEffectTarget[spellInfo_1->EffectImplicitTargetA[i]] || IsAreaEffectTarget[spellInfo_1->EffectImplicitTargetB[i]])
&& !IsChanneledSpell(spellInfo_1))
continue;
switch(spellInfo_1->EffectApplyAuraName[i])
{
// not channeled AOE effects can stack
if(IsAreaEffectTarget[spellInfo_1->EffectImplicitTargetA[i]] || IsAreaEffectTarget[spellInfo_1->EffectImplicitTargetB[i]]
&& !IsChanneledSpell(spellInfo_1))
continue;
// not area auras (shaman totem)
switch(spellInfo_1->EffectApplyAuraName[i])
{
// DOT or HOT from different casters will stack
case SPELL_AURA_PERIODIC_DAMAGE:
case SPELL_AURA_PERIODIC_HEAL:
case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
case SPELL_AURA_PERIODIC_ENERGIZE:
case SPELL_AURA_PERIODIC_MANA_LEECH:
case SPELL_AURA_PERIODIC_LEECH:
case SPELL_AURA_POWER_BURN_MANA:
case SPELL_AURA_OBS_MOD_ENERGY:
case SPELL_AURA_OBS_MOD_HEALTH:
case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
return false;
default:
break;
}
// DOT or HOT from different casters will stack
case SPELL_AURA_PERIODIC_DAMAGE:
case SPELL_AURA_PERIODIC_HEAL:
case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
case SPELL_AURA_PERIODIC_ENERGIZE:
case SPELL_AURA_PERIODIC_MANA_LEECH:
case SPELL_AURA_PERIODIC_LEECH:
case SPELL_AURA_POWER_BURN_MANA:
case SPELL_AURA_OBS_MOD_ENERGY:
case SPELL_AURA_OBS_MOD_HEALTH:
case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
return true;
default:
break;
}
}
}
spellId_2 = GetLastSpellInChain(spellId_2);
spellId_1 = GetLastSpellInChain(spellId_1);
// Hack for Incanter's Absorption
if (spellId_1 == spellId_2 && (spellId_1 == 44413 || (!sameCaster && spellInfo_1->AttributesEx3 & SPELL_ATTR_EX3_STACKS_FOR_DIFFERENT_CASTERS)))
return false;
uint32 spellId_1 = GetLastSpellInChain(spellInfo_1->Id);
uint32 spellId_2 = GetLastSpellInChain(spellInfo_2->Id);
// same spell
if (spellId_1 == spellId_2)
return true;
{
// Hack for Incanter's Absorption
if(spellId_1 == 44413)
return true;
// same spell with same caster should not stack
return false;
}
// generic spells
// use icon to check generic spells
if(!spellInfo_1->SpellFamilyName)
{
if(!spellInfo_1->SpellIconID
|| spellInfo_1->SpellIconID == 1
if(!spellInfo_1->SpellIconID || spellInfo_1->SpellIconID == 1
|| spellInfo_1->SpellIconID != spellInfo_2->SpellIconID)
return false;
return true;
}
// check for class spells
// use familyflag to check class spells
else
{
if (spellInfo_1->SpellFamilyFlags != spellInfo_2->SpellFamilyFlags)
return false;
if (!spellInfo_1->SpellFamilyFlags)
return false;
if(!spellInfo_1->SpellFamilyFlags
|| spellInfo_1->SpellFamilyFlags != spellInfo_2->SpellFamilyFlags)
return true;
}
//use data of highest rank spell(needed for spells which ranks have different effects)
spellInfo_1=sSpellStore.LookupEntry(spellId_1);
spellInfo_2=sSpellStore.LookupEntry(spellId_2);
spellInfo_1 = sSpellStore.LookupEntry(spellId_1);
spellInfo_2 = sSpellStore.LookupEntry(spellId_2);
//if spells have exactly the same effect they cannot stack
//if spells do not have the same effect or aura or miscvalue, they will stack
for(uint32 i = 0; i < 3; ++i)
if(spellInfo_1->Effect[i] != spellInfo_2->Effect[i]
|| spellInfo_1->EffectApplyAuraName[i] != spellInfo_2->EffectApplyAuraName[i]
|| spellInfo_1->EffectMiscValue[i] != spellInfo_2->EffectMiscValue[i]) // paladin resist aura
return false; // need itemtype check? need an example to add that check
return true; // need itemtype check? need an example to add that check
return (!(!sameCaster && spellInfo_1->AttributesEx3 & SPELL_ATTR_EX3_STACKS_FOR_DIFFERENT_CASTERS));
// different spells with same effect
return false;
}
bool IsDispelableBySpell(SpellEntry const * dispelSpell, uint32 spellId, bool def)

View File

@@ -967,7 +967,7 @@ class SpellMgr
bool IsRankSpellDueToSpell(SpellEntry const *spellInfo_1,uint32 spellId_2) const;
static bool canStackSpellRanks(SpellEntry const *spellInfo);
bool IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool sameCaster) const;
bool CanAurasStack(SpellEntry const *spellInfo_1, SpellEntry const *spellInfo_2, bool sameCaster) const;
SpellEntry const* SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const;

View File

@@ -3865,7 +3865,7 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
if (is_triggered_by_spell)
continue;
if(!spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId, sameCaster))
if(spellmgr.CanAurasStack(spellProto, i_spellProto, sameCaster))
continue;
//some spells should be not removed by lower rank of them (totem, paladin aura)