From 9f015512100612b60ca3bdff4beabc4fdf7b43e8 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 24 Aug 2009 06:39:19 +0400 Subject: [PATCH] [8414] Re-implement [8406] in more clear and working way. * Rename IsSingleFromSpellSpecificPerCaster to IsSingleFromSpellSpecificPerTargetPerCaster for clear meaning. * Rename IsSingleFromSpellSpecificRanksPerTarget to IsSingleFromSpellSpecificSpellRanksPerTarget for clear meaning. * Add new IsSingleFromSpellSpecificPerTarget for case single spell specific aura allowed to be at target from any caster and use it. Move some spell psecific checks (mostly sellf casted) from IsSingleFromSpellSpecificPerCaster to new function. --- src/game/SpellMgr.cpp | 73 +++++++++++++++++++++++----------------- src/game/SpellMgr.h | 8 +++-- src/game/Unit.cpp | 16 ++++----- src/shared/revision_nr.h | 2 +- 4 files changed, 57 insertions(+), 42 deletions(-) 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__