mirror of
https://github.com/liyunfan1223/azerothcore-wotlk.git
synced 2026-08-08 15:58:04 +00:00
fix(Core/Spells): apply SPELLFAMILY_GENERIC mods to spells by default (#24996)
Co-authored-by: ariel- <ariel-@users.noreply.github.com>
This commit is contained in:
@@ -1105,14 +1105,12 @@ bool AuraEffect::IsAffectedOnSpell(SpellInfo const* spell) const
|
|||||||
{
|
{
|
||||||
if (!spell)
|
if (!spell)
|
||||||
return false;
|
return false;
|
||||||
// Check family name
|
|
||||||
if (spell->SpellFamilyName != m_spellInfo->SpellFamilyName)
|
// Check family name and EffectClassMask
|
||||||
|
if (!spell->IsAffected(m_spellInfo->SpellFamilyName, m_spellInfo->Effects[m_effIndex].SpellClassMask))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check EffectClassMask
|
return true;
|
||||||
if (m_spellInfo->Effects[m_effIndex].SpellClassMask & spell->SpellFamilyFlags)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuraEffect::HasSpellClassMask() const
|
bool AuraEffect::HasSpellClassMask() const
|
||||||
|
|||||||
@@ -1285,6 +1285,20 @@ bool SpellInfo::IsAutoRepeatRangedSpell() const
|
|||||||
return AttributesEx2 & SPELL_ATTR2_AUTO_REPEAT;
|
return AttributesEx2 & SPELL_ATTR2_AUTO_REPEAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SpellInfo::IsAffected(uint32 familyName, flag96 const& familyFlags) const
|
||||||
|
{
|
||||||
|
if (!familyName)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (familyName != SpellFamilyName)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (familyFlags && !(familyFlags & SpellFamilyFlags))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool SpellInfo::IsAffectedBySpellMods() const
|
bool SpellInfo::IsAffectedBySpellMods() const
|
||||||
{
|
{
|
||||||
return !(AttributesEx3 & SPELL_ATTR3_IGNORE_CASTER_MODIFIERS);
|
return !(AttributesEx3 & SPELL_ATTR3_IGNORE_CASTER_MODIFIERS);
|
||||||
@@ -1300,23 +1314,12 @@ bool SpellInfo::IsAffectedBySpellMod(SpellModifier const* mod) const
|
|||||||
SpellInfo const* affectSpell = sSpellMgr->GetSpellInfo(mod->spellId);
|
SpellInfo const* affectSpell = sSpellMgr->GetSpellInfo(mod->spellId);
|
||||||
|
|
||||||
if (!affectSpell)
|
if (!affectSpell)
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (!sScriptMgr->OnIsAffectedBySpellModCheck(affectSpell, this, mod))
|
if (!sScriptMgr->OnIsAffectedBySpellModCheck(affectSpell, this, mod))
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
// False if affect_spell == nullptr or spellFamily not equal
|
return IsAffected(affectSpell->SpellFamilyName, mod->mask);
|
||||||
if (affectSpell->SpellFamilyName != SpellFamilyName)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (mod->mask && !(mod->mask & SpellFamilyFlags))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpellInfo::CanPierceImmuneAura(SpellInfo const* aura) const
|
bool SpellInfo::CanPierceImmuneAura(SpellInfo const* aura) const
|
||||||
|
|||||||
@@ -466,6 +466,8 @@ public:
|
|||||||
bool IsRangedWeaponSpell() const;
|
bool IsRangedWeaponSpell() const;
|
||||||
bool IsAutoRepeatRangedSpell() const;
|
bool IsAutoRepeatRangedSpell() const;
|
||||||
|
|
||||||
|
[[nodiscard]] bool IsAffected(uint32 familyName, flag96 const& familyFlags) const;
|
||||||
|
|
||||||
bool IsAffectedBySpellMods() const;
|
bool IsAffectedBySpellMods() const;
|
||||||
bool IsAffectedBySpellMod(SpellModifier const* mod) const;
|
bool IsAffectedBySpellMod(SpellModifier const* mod) const;
|
||||||
|
|
||||||
|
|||||||
@@ -823,17 +823,10 @@ bool SpellMgr::CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcE
|
|||||||
|
|
||||||
// check spell family name/flags (if set) for spells
|
// check spell family name/flags (if set) for spells
|
||||||
if (eventInfo.GetTypeMask() & SPELL_PROC_FLAG_MASK)
|
if (eventInfo.GetTypeMask() & SPELL_PROC_FLAG_MASK)
|
||||||
{
|
|
||||||
if (SpellInfo const* eventSpellInfo = eventInfo.GetSpellInfo())
|
if (SpellInfo const* eventSpellInfo = eventInfo.GetSpellInfo())
|
||||||
{
|
if (!eventSpellInfo->IsAffected(procEntry.SpellFamilyName, procEntry.SpellFamilyMask))
|
||||||
if (procEntry.SpellFamilyName && procEntry.SpellFamilyName != eventSpellInfo->SpellFamilyName)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (procEntry.SpellFamilyMask && !(procEntry.SpellFamilyMask & eventSpellInfo->SpellFamilyFlags))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check spell type mask (if set)
|
// check spell type mask (if set)
|
||||||
if (eventInfo.GetTypeMask() & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK))
|
if (eventInfo.GetTypeMask() & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -790,6 +790,52 @@ TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_SpellFamilyFlagsZeroAcceptsAll)
|
|||||||
EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo));
|
EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_GenericFamilyIgnoresMask)
|
||||||
|
{
|
||||||
|
// Generic family (0) should bypass family mask checks entirely
|
||||||
|
auto* spellInfo = SpellInfoBuilder()
|
||||||
|
.WithId(101)
|
||||||
|
.WithSpellFamilyName(SPELLFAMILY_MAGE)
|
||||||
|
.WithSpellFamilyFlags(0x1, 0, 0) // some mage flag
|
||||||
|
.Build();
|
||||||
|
_spellInfos.push_back(spellInfo);
|
||||||
|
|
||||||
|
DamageInfo damageInfo(nullptr, nullptr, 100, spellInfo, SPELL_SCHOOL_MASK_FIRE, SPELL_DIRECT_DAMAGE);
|
||||||
|
|
||||||
|
auto procEntry = SpellProcEntryBuilder()
|
||||||
|
.WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG)
|
||||||
|
.WithSpellFamilyName(0) // generic family
|
||||||
|
.WithSpellFamilyMask(flag96(0x2, 0, 0)) // does NOT match the spell's flags
|
||||||
|
.WithSpellPhaseMask(PROC_SPELL_PHASE_HIT)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
auto eventInfo = ProcEventInfoBuilder()
|
||||||
|
.WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG)
|
||||||
|
.WithSpellPhaseMask(PROC_SPELL_PHASE_HIT)
|
||||||
|
.WithHitMask(PROC_HIT_NORMAL)
|
||||||
|
.WithDamageInfo(&damageInfo)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo))
|
||||||
|
<< "Generic family entries should ignore mask restrictions";
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpellProcTest, SpellInfo_IsAffected_GenericBehavior)
|
||||||
|
{
|
||||||
|
auto* spellInfo = SpellInfoBuilder()
|
||||||
|
.WithId(102)
|
||||||
|
.WithSpellFamilyName(SPELLFAMILY_WARLOCK)
|
||||||
|
.WithSpellFamilyFlags(0x4, 0, 0)
|
||||||
|
.Build();
|
||||||
|
_spellInfos.push_back(spellInfo);
|
||||||
|
|
||||||
|
// generic family should return true regardless of mask
|
||||||
|
EXPECT_TRUE(spellInfo->IsAffected(0, flag96(0x4, 0, 0)));
|
||||||
|
EXPECT_TRUE(spellInfo->IsAffected(0, flag96(0x8, 0, 0)));
|
||||||
|
// a non-generic family still respects mask
|
||||||
|
EXPECT_FALSE(spellInfo->IsAffected(SPELLFAMILY_PALADIN, flag96(0x4, 0, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Real-world Spell Proc Examples
|
// Real-world Spell Proc Examples
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user