diff options
author | megamage <none@none> | 2009-08-23 10:22:58 -0500 |
---|---|---|
committer | megamage <none@none> | 2009-08-23 10:22:58 -0500 |
commit | 0b06baee4dcbc18534bbfb3becb679ae42103439 (patch) | |
tree | 7740eb58fae708062901ae493c48472615f6bd9c | |
parent | d132f7e401ecfc032b33405f6b247807a0754133 (diff) |
*Update rules of aura stack.
--HG--
branch : trunk
-rw-r--r-- | src/game/SharedDefines.h | 4 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 3 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 122 | ||||
-rw-r--r-- | src/game/SpellMgr.h | 2 | ||||
-rw-r--r-- | src/game/Unit.cpp | 2 |
5 files changed, 68 insertions, 65 deletions
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index fdd4f6401fe..6a2a9ff334e 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -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 diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 27e2c2a9e3a..837b8323a60 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -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; diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 9f21fd442d4..91e11ca90a4 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -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) diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 42705f1e7ca..b8dca34edf0 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -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; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index aca48c53e01..be24edb329f 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -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) |