fix(Core/Spells): Implemented PROC_EX_ONLY_FIRST_TICK (#7933)

This commit is contained in:
UltraNix
2021-09-21 14:02:06 +02:00
committed by GitHub
parent 3570c0b16c
commit c3259dabcf
7 changed files with 45 additions and 16 deletions

View File

@@ -641,6 +641,7 @@ Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags,
m_preCastSpell = 0;
m_triggeredByAuraSpell = nullptr;
m_triggeredByAuraEffectIndex = -1;
m_triggeredByAuraTickNumber = 0;
m_spellAura = nullptr;
m_pathFinder = nullptr; // pussywizard
_scriptsLoaded = false;
@@ -3238,6 +3239,7 @@ SpellCastResult Spell::prepare(SpellCastTargets const* targets, AuraEffect const
{
m_triggeredByAuraSpell = triggeredByAura->GetSpellInfo();
m_triggeredByAuraEffectIndex = triggeredByAura->GetEffIndex();
m_triggeredByAuraTickNumber = triggeredByAura->GetTickNumber();
}
// create and add update event for this spell

View File

@@ -545,7 +545,10 @@ public:
// xinef: moved to public
void LoadScripts();
std::list<TargetInfo>* GetUniqueTargetInfo() { return &m_UniqueTargetInfo; }
protected:
[[nodiscard]] uint32 GetTriggeredByAuraTickNumber() const { return m_triggeredByAuraTickNumber; }
protected:
bool HasGlobalCooldown() const;
void TriggerGlobalCooldown();
void CancelGlobalCooldown();
@@ -722,6 +725,7 @@ protected:
// and in same time need aura data and after aura deleting.
SpellInfo const* m_triggeredByAuraSpell;
int8 m_triggeredByAuraEffectIndex;
uint32 m_triggeredByAuraTickNumber;
bool m_skipCheck;
uint8 m_auraScaleMask;

View File

@@ -724,11 +724,15 @@ SpellProcEventEntry const* SpellMgr::GetSpellProcEvent(uint32 spellId) const
return nullptr;
}
bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellInfo const* spellProto, SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, SpellInfo const* procSpell, uint32 procFlags, uint32 procExtra, bool active) const
bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellInfo const* spellProto, SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, ProcEventInfo const& eventInfo, bool active) const
{
// No extra req need
uint32 procEvent_procEx = PROC_EX_NONE;
uint32 procFlags = eventInfo.GetTypeMask();
uint32 procExtra = eventInfo.GetHitMask();
SpellInfo const* procSpellInfo = eventInfo.GetSpellInfo();
// check prockFlags for condition
if ((procFlags & EventProcFlag) == 0)
return false;
@@ -786,7 +790,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellInfo const* spellProto, Spell
procEvent_procEx = spellProcEvent->procEx;
// For melee triggers
if (procSpell == nullptr)
if (!procSpellInfo)
{
// Check (if set) for school (melee attack have Normal school)
if (spellProcEvent->schoolMask && (spellProcEvent->schoolMask & SPELL_SCHOOL_MASK_NORMAL) == 0)
@@ -795,23 +799,35 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellInfo const* spellProto, Spell
else // For spells need check school/spell family/family mask
{
// Check (if set) for school
if (spellProcEvent->schoolMask && (spellProcEvent->schoolMask & procSpell->SchoolMask) == 0)
if (spellProcEvent->schoolMask && (spellProcEvent->schoolMask & procSpellInfo->SchoolMask) == 0)
return false;
// Check (if set) for spellFamilyName
if (spellProcEvent->spellFamilyName && (spellProcEvent->spellFamilyName != procSpell->SpellFamilyName))
if (spellProcEvent->spellFamilyName && (spellProcEvent->spellFamilyName != procSpellInfo->SpellFamilyName))
return false;
// spellFamilyName is Ok need check for spellFamilyMask if present
if (spellProcEvent->spellFamilyMask)
{
if (!(spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags))
if (!(spellProcEvent->spellFamilyMask & procSpellInfo->SpellFamilyFlags))
return false;
hasFamilyMask = true;
// Some spells are not considered as active even with have spellfamilyflags
if (!(procEvent_procEx & PROC_EX_ONLY_ACTIVE_SPELL))
active = true;
}
// Check tick numbers
if (procEvent_procEx & PROC_EX_ONLY_FIRST_TICK)
{
if (Spell const* procSpell = eventInfo.GetProcSpell())
{
if (procSpell->GetTriggeredByAuraTickNumber() > 1)
{
return false;
}
}
}
}
}

View File

@@ -201,6 +201,7 @@ enum ProcFlagsExLegacy
PROC_EX_ONLY_ACTIVE_SPELL = 0x0040000, // Spell has to do damage/heal to proc
PROC_EX_NO_OVERHEAL = 0x0080000, // Proc if heal did some work
PROC_EX_NO_AURA_REFRESH = 0x0100000, // Proc if aura was not refreshed
PROC_EX_ONLY_FIRST_TICK = 0x0200000, // Proc only on first tick (in case of periodic spells)
// Flags for internal use - do not use these in db!
PROC_EX_INTERNAL_CANT_PROC = 0x0800000,
@@ -650,7 +651,7 @@ public:
// Spell proc event table
[[nodiscard]] SpellProcEventEntry const* GetSpellProcEvent(uint32 spellId) const;
bool IsSpellProcEventCanTriggeredBy(SpellInfo const* spellProto, SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, SpellInfo const* procSpell, uint32 procFlags, uint32 procExtra, bool active) const;
bool IsSpellProcEventCanTriggeredBy(SpellInfo const* spellProto, SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, ProcEventInfo const& eventInfo, bool active) const;
// Spell proc table
[[nodiscard]] SpellProcEntry const* GetSpellProcEntry(uint32 spellId) const;