*Re-commit some reverted patch: aura stacking check. By QAston.
--HG-- branch : trunk
This commit is contained in:
+66
-13
@@ -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;
|
||||
}
|
||||
|
||||
+4
-3
@@ -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;
|
||||
|
||||
|
||||
+10
-42
@@ -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() )
|
||||
bool sameCaster = Aur->GetCasterGUID() == (*i).second->GetCasterGUID();
|
||||
if( spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId, sameCaster) )
|
||||
{
|
||||
// cannot remove higher rank
|
||||
if (spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId))
|
||||
if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0)
|
||||
return false;
|
||||
//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;
|
||||
|
||||
Reference in New Issue
Block a user