diff options
-rw-r--r-- | src/game/SpellMgr.cpp | 79 | ||||
-rw-r--r-- | src/game/SpellMgr.h | 7 | ||||
-rw-r--r-- | src/game/Unit.cpp | 54 |
3 files changed, 81 insertions, 59 deletions
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 07a0df04450..688514dcb54 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -99,7 +99,7 @@ bool IsPassiveSpell(uint32 spellId) return (spellInfo->Attributes & SPELL_ATTR_PASSIVE) != 0; } -bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2) +/*bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2) { SpellEntry const *spellInfo_1 = sSpellStore.LookupEntry(spellId_1); SpellEntry const *spellInfo_2 = sSpellStore.LookupEntry(spellId_2); @@ -113,7 +113,7 @@ bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_ return false; return true; -} +}*/ int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2) { @@ -244,14 +244,24 @@ bool IsSingleFromSpellSpecificPerCaster(uint32 spellSpec1,uint32 spellSpec2) case SPELL_STING: case SPELL_CURSE: case SPELL_ASPECT: + case SPELL_POSITIVE_SHOUT: + case SPELL_JUDGEMENT: + case SPELL_WARLOCK_CORRUPTION: + return spellSpec1==spellSpec2; + default: + return false; + } +} + +bool IsSingleFromSpellSpecificPerTarget(uint32 spellSpec1,uint32 spellSpec2) +{ + switch(spellSpec1) + { case SPELL_TRACKER: case SPELL_WARLOCK_ARMOR: case SPELL_MAGE_ARMOR: case SPELL_ELEMENTAL_SHIELD: case SPELL_MAGE_POLYMORPH: - case SPELL_POSITIVE_SHOUT: - case SPELL_JUDGEMENT: - case SPELL_WARLOCK_CORRUPTION: return spellSpec1==spellSpec2; case SPELL_BATTLE_ELIXIR: return spellSpec2==SPELL_BATTLE_ELIXIR @@ -1030,10 +1040,10 @@ bool SpellMgr::canStackSpellRanks(SpellEntry const *spellInfo) return true; } -bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) const +bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool sameCaster) const { - if(spellId_1 == spellId_2) // auras due to the same spell - return false; + //if(spellId_1 == spellId_2) // auras due to the same spell + // return false; SpellEntry const *spellInfo_1 = sSpellStore.LookupEntry(spellId_1); SpellEntry const *spellInfo_2 = sSpellStore.LookupEntry(spellId_2); @@ -1041,22 +1051,65 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons 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) + ||(IsSingleFromSpellSpecificPerCaster(spellId_spec_1, spellId_spec_2) && sameCaster)) + return true; + if(spellInfo_1->SpellFamilyName != spellInfo_2->SpellFamilyName) return false; - if(!spellInfo_1->SpellFamilyName) // generic spells + // generic spells + if(!spellInfo_1->SpellFamilyName) { if(!spellInfo_1->SpellIconID || spellInfo_1->SpellIconID != spellInfo_2->SpellIconID) return false; } - else if (spellInfo_1->SpellFamilyFlags != spellInfo_2->SpellFamilyFlags) - return false; + + // if both elixirs are not battle/guardian/potions/flasks then always stack + else if(spellInfo_1->SpellFamilyName == SPELLFAMILY_POTION) + { + if(spellId_spec_1 || spellId_spec_2)) + return false; + } + + // check for class spells + else + { + if (spellInfo_1->SpellFamilyFlags != spellInfo_2->SpellFamilyFlags) + return false; + } for(uint32 i = 0; i < 3; ++i) + { if(spellInfo_1->Effect[i] != spellInfo_2->Effect[i] - || spellInfo_1->EffectApplyAuraName[i] != spellInfo_2->EffectApplyAuraName[i]) - return false; + || 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 + + if(spellInfo_1->EffectApplyAuraName[i] // both spell has the same auras + && !sameCaster + && spellInfo_1->Effect[i] != SPELL_EFFECT_APPLY_AREA_AURA_PARTY) // not area auras (shaman totem) + // a better check may be effect == SPELL_EFFECT_APPLY_AURA + { + 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: + return false; + default: + break; + } + } + } return true; } diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 7de9c54c6cb..6e3c5c3ddff 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -284,7 +284,7 @@ inline bool IsSpellHaveEffect(SpellEntry const *spellInfo, SpellEffects effect) return false; } -bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2); +//bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2); inline bool IsSealSpell(SpellEntry const *spellInfo) { @@ -300,7 +300,8 @@ inline bool IsElementalShield(SpellEntry const *spellInfo) } int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2); -bool IsSingleFromSpellSpecificPerCaster(uint32 spellSpec1,uint32 spellSpec2); +bool IsSingleFromSpellSpecificPerCaster(uint32 spellSpec1, uint32 spellSpec2); +bool IsSingleFromSpellSpecificPerTarget(uint32 spellSpec1, uint32 spellSpec2); bool IsPassiveSpell(uint32 spellId); inline bool IsDeathPersistentSpell(SpellEntry const *spellInfo) @@ -768,7 +769,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) const; + bool IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_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 a78f1ca2c29..027c9becb6b 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -3895,16 +3895,17 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) if(!is_triggered_by_spell) { - SpellSpecific i_spellId_spec = GetSpellSpecific(i_spellId); - - bool is_sspc = IsSingleFromSpellSpecificPerCaster(spellId_spec,i_spellId_spec); - - if( is_sspc && Aur->GetCasterGUID() == (*i).second->GetCasterGUID() ) - { - // cannot remove higher rank - if (spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId)) - if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0) - return false; + bool sameCaster = Aur->GetCasterGUID() == (*i).second->GetCasterGUID(); + if( spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId, sameCaster) ) + { + //some spells should be not removed by lower rank of them + // what is this spell? + if (!sameCaster + &&(spellProto->Effect[effIndex]==SPELL_EFFECT_APPLY_AREA_AURA_PARTY) + &&(spellProto->DurationIndex==21) + &&(spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId)) + &&(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0)) + return false; // Its a parent aura (create this aura in ApplyModifier) if ((*i).second->IsInUse()) @@ -3919,39 +3920,6 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) else next = m_Auras.begin(); } - else if( !is_sspc && spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId) ) - { - // Its a parent aura (create this aura in ApplyModifier) - if ((*i).second->IsInUse()) - { - sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(), i->second->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex()); - continue; - } - RemoveAurasDueToSpell(i_spellId); - - if( m_Auras.empty() ) - break; - else - next = m_Auras.begin(); - } - // Potions stack aura by aura (elixirs/flask already checked) - else if( spellProto->SpellFamilyName == SPELLFAMILY_POTION && i_spellProto->SpellFamilyName == SPELLFAMILY_POTION ) - { - if (IsNoStackAuraDueToAura(spellId, effIndex, i_spellId, i_effIndex)) - { - if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0) - return false; // cannot remove higher rank - - // Its a parent aura (create this aura in ApplyModifier) - if ((*i).second->IsInUse()) - { - sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(), i->second->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex()); - continue; - } - RemoveAura(i); - next = i; - } - } } } return true; |