From b703ad70cdc377304c8b6167419ba5af853bc114 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 23 Aug 2009 03:28:03 +0400 Subject: [PATCH] [8406] Detect/check stacking of food/drink/elental shileds as spell specifics. Food/Drink checks base at nos4r2zod's patch code. Signed-off-by: VladimirMangos --- src/game/SpellMgr.cpp | 62 ++++++++++++++++++++++++++++++++++++++++-------- src/game/SpellMgr.h | 5 +++- src/game/Unit.cpp | 23 ++++++++++++++---- src/shared/revision_nr.h | 2 +- 4 files changed, 75 insertions(+), 17 deletions(-) diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index e9de58492..9b27ec841 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -137,11 +137,44 @@ SpellSpecific GetSpellSpecific(uint32 spellId) { case SPELLFAMILY_GENERIC: { - // Well Fed buffs (must be exclusive with Food / Drink replenishment effects, or else Well Fed will cause them to be removed) - // SpellIcon 2560 is Spell 46687, does not have this flag - if ((spellInfo->AttributesEx2 & SPELL_ATTR_EX2_FOOD_BUFF || spellInfo->SpellIconID == 2560) && - !(spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED)) - return SPELL_WELL_FED; + // Food / Drinks (mostly) + if(spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) + { + bool food = false; + bool drink = false; + for(int i = 0; i < 3; ++i) + { + switch(spellInfo->EffectApplyAuraName[i]) + { + // Food + case SPELL_AURA_MOD_REGEN: + case SPELL_AURA_OBS_MOD_HEALTH: + food = true; + break; + // Drink + case SPELL_AURA_MOD_POWER_REGEN: + case SPELL_AURA_OBS_MOD_MANA: + drink = true; + break; + default: + break; + } + } + + if(food && drink) + return SPELL_FOOD_AND_DRINK; + else if(food) + return SPELL_FOOD; + else if(drink) + return SPELL_DRINK; + } + else + { + // Well Fed buffs (must be exclusive with Food / Drink replenishment effects, or else Well Fed will cause them to be removed) + // SpellIcon 2560 is Spell 46687, does not have this flag + if ((spellInfo->AttributesEx2 & SPELL_ATTR_EX2_FOOD_BUFF) || spellInfo->SpellIconID == 2560) + return SPELL_WELL_FED; + } } case SPELLFAMILY_MAGE: { @@ -241,6 +274,8 @@ SpellSpecific GetSpellSpecific(uint32 spellId) return SPELL_NORMAL; } + +// target not allow have more one spell specific from same caster bool IsSingleFromSpellSpecificPerCaster(SpellSpecific spellSpec1,SpellSpecific spellSpec2) { switch(spellSpec1) @@ -260,7 +295,16 @@ bool IsSingleFromSpellSpecificPerCaster(SpellSpecific spellSpec1,SpellSpecific s 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; @@ -276,6 +320,7 @@ bool IsSingleFromSpellSpecificPerCaster(SpellSpecific spellSpec1,SpellSpecific s } } +// 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) @@ -284,6 +329,7 @@ bool IsSingleFromSpellSpecificRanksPerTarget(SpellSpecific spellId_spec, SpellSp case SPELL_AURA: case SPELL_CURSE: case SPELL_HAND: + case SPELL_ELEMENTAL_SHIELD: return spellId_spec==i_spellId_spec; default: return false; @@ -1523,10 +1569,6 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons case SPELLFAMILY_SHAMAN: if( spellInfo_2->SpellFamilyName == SPELLFAMILY_SHAMAN ) { - // shaman shields - if( IsElementalShield(spellInfo_1) && IsElementalShield(spellInfo_2) ) - return true; - // Windfury weapon if( spellInfo_1->SpellIconID==220 && spellInfo_2->SpellIconID==220 && spellInfo_1->SpellFamilyFlags != spellInfo_2->SpellFamilyFlags ) diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index f1c0a54c0..a5760ea8a 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -99,7 +99,10 @@ enum SpellSpecific SPELL_FLASK_ELIXIR = 16, SPELL_PRESENCE = 17, SPELL_HAND = 18, - SPELL_WELL_FED = 19 + SPELL_WELL_FED = 19, + SPELL_FOOD = 20, + SPELL_DRINK = 21, + SPELL_FOOD_AND_DRINK = 22, }; SpellSpecific GetSpellSpecific(uint32 spellId); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 31071b6ed..aa2ee8a85 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -3631,9 +3631,8 @@ 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); - bool is_sspt = IsSingleFromSpellSpecificRanksPerTarget(spellId_spec,i_spellId_spec); - if( is_sspc && Aur->GetCasterGUID() == (*i).second->GetCasterGUID() ) { // cannot remove higher rank @@ -3653,8 +3652,15 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) break; else next = m_Auras.begin(); + + continue; } - else if( is_sspt && Aur->GetCasterGUID() != (*i).second->GetCasterGUID() && spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId) ) + + // 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))) { // cannot remove higher rank if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0) @@ -3672,8 +3678,12 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) break; else next = m_Auras.begin(); + + continue; } - else if( !is_sspc && spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId) ) + + // non single per caster spell specific (possible single per target spells at caster) + if( !is_sspc && spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId) ) { // Its a parent aura (create this aura in ApplyModifier) if ((*i).second->IsInUse()) @@ -3687,9 +3697,12 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) break; else next = m_Auras.begin(); + + continue; } + // Potions stack aura by aura (elixirs/flask already checked) - else if( spellProto->SpellFamilyName == SPELLFAMILY_POTION && i_spellProto->SpellFamilyName == SPELLFAMILY_POTION ) + if( spellProto->SpellFamilyName == SPELLFAMILY_POTION && i_spellProto->SpellFamilyName == SPELLFAMILY_POTION ) { if (IsNoStackAuraDueToAura(spellId, effIndex, i_spellId, i_effIndex)) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index ff1c205ca..087700435 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 "8405" + #define REVISION_NR "8406" #endif // __REVISION_NR_H__ -- 2.11.4.GIT