diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index fc6d8bbf5..85e5389c0 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -277,36 +277,53 @@ SpellSpecific GetSpellSpecific(uint32 spellId) // target not allow have more one spell specific from same caster -bool IsSingleFromSpellSpecificPerCaster(SpellSpecific spellSpec1,SpellSpecific spellSpec2) +bool IsSingleFromSpellSpecificPerTargetPerCaster(SpellSpecific spellSpec1,SpellSpecific spellSpec2) { switch(spellSpec1) { - case SPELL_SEAL: case SPELL_BLESSING: case SPELL_AURA: case SPELL_STING: case SPELL_CURSE: + case SPELL_POSITIVE_SHOUT: + case SPELL_JUDGEMENT: + case SPELL_HAND: + return spellSpec1==spellSpec2; + default: + return false; + } +} + +// target not allow have more one ranks from spell from spell specific per target +bool IsSingleFromSpellSpecificSpellRanksPerTarget(SpellSpecific spellSpec1,SpellSpecific spellSpec2) +{ + switch(spellSpec1) + { + case SPELL_BLESSING: + case SPELL_AURA: + case SPELL_CURSE: + case SPELL_HAND: + return spellSpec1==spellSpec2; + default: + return false; + } +} + +// target not allow have more one spell specific per target from any caster +bool IsSingleFromSpellSpecificPerTarget(SpellSpecific spellSpec1,SpellSpecific spellSpec2) +{ + switch(spellSpec1) + { + case SPELL_SEAL: case SPELL_ASPECT: 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_PRESENCE: - case SPELL_HAND: case SPELL_WELL_FED: return spellSpec1==spellSpec2; - case SPELL_FOOD: - return spellSpec2==SPELL_FOOD - || spellSpec2==SPELL_FOOD_AND_DRINK; - case SPELL_DRINK: - return spellSpec2==SPELL_DRINK - || spellSpec2==SPELL_FOOD_AND_DRINK; - case SPELL_FOOD_AND_DRINK: - return spellSpec2==SPELL_FOOD - || spellSpec2==SPELL_DRINK - || spellSpec2==SPELL_FOOD_AND_DRINK; case SPELL_BATTLE_ELIXIR: return spellSpec2==SPELL_BATTLE_ELIXIR || spellSpec2==SPELL_FLASK_ELIXIR; @@ -317,22 +334,16 @@ bool IsSingleFromSpellSpecificPerCaster(SpellSpecific spellSpec1,SpellSpecific s return spellSpec2==SPELL_BATTLE_ELIXIR || spellSpec2==SPELL_GUARDIAN_ELIXIR || spellSpec2==SPELL_FLASK_ELIXIR; - default: - return false; - } -} - -// target not allow have more one ranks from spell from spell specific per target -bool IsSingleFromSpellSpecificRanksPerTarget(SpellSpecific spellId_spec, SpellSpecific i_spellId_spec) -{ - switch(spellId_spec) - { - case SPELL_BLESSING: - case SPELL_AURA: - case SPELL_CURSE: - case SPELL_HAND: - case SPELL_ELEMENTAL_SHIELD: - return spellId_spec==i_spellId_spec; + case SPELL_FOOD: + return spellSpec2==SPELL_FOOD + || spellSpec2==SPELL_FOOD_AND_DRINK; + case SPELL_DRINK: + return spellSpec2==SPELL_DRINK + || spellSpec2==SPELL_FOOD_AND_DRINK; + case SPELL_FOOD_AND_DRINK: + return spellSpec2==SPELL_FOOD + || spellSpec2==SPELL_DRINK + || spellSpec2==SPELL_FOOD_AND_DRINK; default: return false; } diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index a5760ea8a..a43e51437 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -180,8 +180,12 @@ inline bool IsLootCraftingSpell(SpellEntry const *spellInfo) } int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2); -bool IsSingleFromSpellSpecificPerCaster(SpellSpecific spellSpec1,SpellSpecific spellSpec2); -bool IsSingleFromSpellSpecificRanksPerTarget(SpellSpecific spellId_spec, SpellSpecific i_spellId_spec); + +// order from less to more strict +bool IsSingleFromSpellSpecificPerTargetPerCaster(SpellSpecific spellSpec1,SpellSpecific spellSpec2); +bool IsSingleFromSpellSpecificSpellRanksPerTarget(SpellSpecific spellSpec1,SpellSpecific spellSpec2); +bool IsSingleFromSpellSpecificPerTarget(SpellSpecific spellSpec1,SpellSpecific spellSpec2); + bool IsPassiveSpell(uint32 spellId); inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index aa2ee8a85..c66325b6b 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -3631,9 +3631,10 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) SpellSpecific i_spellId_spec = GetSpellSpecific(i_spellId); - // single allowed spell specific from same caster - bool is_sspc = IsSingleFromSpellSpecificPerCaster(spellId_spec,i_spellId_spec); - if( is_sspc && Aur->GetCasterGUID() == (*i).second->GetCasterGUID() ) + // single allowed spell specific from same caster or from any caster at target + bool is_spellSpecPerTargetPerCaster = IsSingleFromSpellSpecificPerTargetPerCaster(spellId_spec,i_spellId_spec); + bool is_spellSpecPerTarget = IsSingleFromSpellSpecificPerTarget(spellId_spec,i_spellId_spec); + if( is_spellSpecPerTarget || is_spellSpecPerTargetPerCaster && Aur->GetCasterGUID() == (*i).second->GetCasterGUID() ) { // cannot remove higher rank if (spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId)) @@ -3658,9 +3659,8 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) // spell with spell specific that allow single ranks for spell from diff caster // same caster case processed or early or later - bool is_sspt = IsSingleFromSpellSpecificRanksPerTarget(spellId_spec,i_spellId_spec); - if ( is_sspt && Aur->GetCasterGUID() != (*i).second->GetCasterGUID() && - (spellProto->Id == i_spellId || spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId))) + bool is_spellPerTarget = IsSingleFromSpellSpecificSpellRanksPerTarget(spellId_spec,i_spellId_spec); + if ( is_spellPerTarget && Aur->GetCasterGUID() != (*i).second->GetCasterGUID() && spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId)) { // cannot remove higher rank if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0) @@ -3682,8 +3682,8 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) continue; } - // non single per caster spell specific (possible single per target spells at caster) - if( !is_sspc && spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId) ) + // non single (per caster) per target spell specific (possible single spell per target at caster) + if( !is_spellSpecPerTargetPerCaster && !is_spellSpecPerTarget && spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId) ) { // Its a parent aura (create this aura in ApplyModifier) if ((*i).second->IsInUse()) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 6520bedb0..89bfe25c2 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8413" + #define REVISION_NR "8414" #endif // __REVISION_NR_H__