mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +00:00
[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 <vladimir@getmangos.com>
This commit is contained in:
parent
178c308c5b
commit
f3930cb06f
4 changed files with 75 additions and 17 deletions
|
|
@ -136,13 +136,46 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
|
||||||
switch(spellInfo->SpellFamilyName)
|
switch(spellInfo->SpellFamilyName)
|
||||||
{
|
{
|
||||||
case SPELLFAMILY_GENERIC:
|
case SPELLFAMILY_GENERIC:
|
||||||
|
{
|
||||||
|
// 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)
|
// 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
|
// SpellIcon 2560 is Spell 46687, does not have this flag
|
||||||
if ((spellInfo->AttributesEx2 & SPELL_ATTR_EX2_FOOD_BUFF || spellInfo->SpellIconID == 2560) &&
|
if ((spellInfo->AttributesEx2 & SPELL_ATTR_EX2_FOOD_BUFF) || spellInfo->SpellIconID == 2560)
|
||||||
!(spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED))
|
|
||||||
return SPELL_WELL_FED;
|
return SPELL_WELL_FED;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case SPELLFAMILY_MAGE:
|
case SPELLFAMILY_MAGE:
|
||||||
{
|
{
|
||||||
// family flags 18(Molten), 25(Frost/Ice), 28(Mage)
|
// family flags 18(Molten), 25(Frost/Ice), 28(Mage)
|
||||||
|
|
@ -241,6 +274,8 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
|
||||||
return SPELL_NORMAL;
|
return SPELL_NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// target not allow have more one spell specific from same caster
|
||||||
bool IsSingleFromSpellSpecificPerCaster(SpellSpecific spellSpec1,SpellSpecific spellSpec2)
|
bool IsSingleFromSpellSpecificPerCaster(SpellSpecific spellSpec1,SpellSpecific spellSpec2)
|
||||||
{
|
{
|
||||||
switch(spellSpec1)
|
switch(spellSpec1)
|
||||||
|
|
@ -260,7 +295,16 @@ bool IsSingleFromSpellSpecificPerCaster(SpellSpecific spellSpec1,SpellSpecific s
|
||||||
case SPELL_PRESENCE:
|
case SPELL_PRESENCE:
|
||||||
case SPELL_HAND:
|
case SPELL_HAND:
|
||||||
case SPELL_WELL_FED:
|
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:
|
case SPELL_BATTLE_ELIXIR:
|
||||||
return spellSpec2==SPELL_BATTLE_ELIXIR
|
return spellSpec2==SPELL_BATTLE_ELIXIR
|
||||||
|| spellSpec2==SPELL_FLASK_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)
|
bool IsSingleFromSpellSpecificRanksPerTarget(SpellSpecific spellId_spec, SpellSpecific i_spellId_spec)
|
||||||
{
|
{
|
||||||
switch(spellId_spec)
|
switch(spellId_spec)
|
||||||
|
|
@ -284,6 +329,7 @@ bool IsSingleFromSpellSpecificRanksPerTarget(SpellSpecific spellId_spec, SpellSp
|
||||||
case SPELL_AURA:
|
case SPELL_AURA:
|
||||||
case SPELL_CURSE:
|
case SPELL_CURSE:
|
||||||
case SPELL_HAND:
|
case SPELL_HAND:
|
||||||
|
case SPELL_ELEMENTAL_SHIELD:
|
||||||
return spellId_spec==i_spellId_spec;
|
return spellId_spec==i_spellId_spec;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1523,10 +1569,6 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons
|
||||||
case SPELLFAMILY_SHAMAN:
|
case SPELLFAMILY_SHAMAN:
|
||||||
if( spellInfo_2->SpellFamilyName == SPELLFAMILY_SHAMAN )
|
if( spellInfo_2->SpellFamilyName == SPELLFAMILY_SHAMAN )
|
||||||
{
|
{
|
||||||
// shaman shields
|
|
||||||
if( IsElementalShield(spellInfo_1) && IsElementalShield(spellInfo_2) )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Windfury weapon
|
// Windfury weapon
|
||||||
if( spellInfo_1->SpellIconID==220 && spellInfo_2->SpellIconID==220 &&
|
if( spellInfo_1->SpellIconID==220 && spellInfo_2->SpellIconID==220 &&
|
||||||
spellInfo_1->SpellFamilyFlags != spellInfo_2->SpellFamilyFlags )
|
spellInfo_1->SpellFamilyFlags != spellInfo_2->SpellFamilyFlags )
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,10 @@ enum SpellSpecific
|
||||||
SPELL_FLASK_ELIXIR = 16,
|
SPELL_FLASK_ELIXIR = 16,
|
||||||
SPELL_PRESENCE = 17,
|
SPELL_PRESENCE = 17,
|
||||||
SPELL_HAND = 18,
|
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);
|
SpellSpecific GetSpellSpecific(uint32 spellId);
|
||||||
|
|
|
||||||
|
|
@ -3631,9 +3631,8 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
|
||||||
|
|
||||||
SpellSpecific i_spellId_spec = GetSpellSpecific(i_spellId);
|
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_sspc = IsSingleFromSpellSpecificPerCaster(spellId_spec,i_spellId_spec);
|
||||||
bool is_sspt = IsSingleFromSpellSpecificRanksPerTarget(spellId_spec,i_spellId_spec);
|
|
||||||
|
|
||||||
if( is_sspc && Aur->GetCasterGUID() == (*i).second->GetCasterGUID() )
|
if( is_sspc && Aur->GetCasterGUID() == (*i).second->GetCasterGUID() )
|
||||||
{
|
{
|
||||||
// cannot remove higher rank
|
// cannot remove higher rank
|
||||||
|
|
@ -3653,8 +3652,15 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
next = m_Auras.begin();
|
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
|
// cannot remove higher rank
|
||||||
if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0)
|
if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0)
|
||||||
|
|
@ -3672,8 +3678,12 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
next = m_Auras.begin();
|
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)
|
// Its a parent aura (create this aura in ApplyModifier)
|
||||||
if ((*i).second->IsInUse())
|
if ((*i).second->IsInUse())
|
||||||
|
|
@ -3687,9 +3697,12 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
next = m_Auras.begin();
|
next = m_Auras.begin();
|
||||||
|
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Potions stack aura by aura (elixirs/flask already checked)
|
// 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))
|
if (IsNoStackAuraDueToAura(spellId, effIndex, i_spellId, i_effIndex))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "8405"
|
#define REVISION_NR "8406"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue