mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-25 06:36:24 +00:00
fix(Core/Spells): Implemented PROC_EX_ONLY_FIRST_TICK (#7933)
This commit is contained in:
@@ -142,7 +142,7 @@ void DamageInfo::BlockDamage(uint32 amount)
|
||||
m_damage -= amount;
|
||||
}
|
||||
|
||||
ProcEventInfo::ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget, uint32 typeMask, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo, SpellInfo const* triggeredByAuraSpell, int8 procAuraEffectIndex)
|
||||
ProcEventInfo::ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget, uint32 typeMask, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell const* spell, DamageInfo* damageInfo, HealInfo* healInfo, SpellInfo const* triggeredByAuraSpell, int8 procAuraEffectIndex)
|
||||
: _actor(actor), _actionTarget(actionTarget), _procTarget(procTarget), _typeMask(typeMask), _spellTypeMask(spellTypeMask), _spellPhaseMask(spellPhaseMask),
|
||||
_hitMask(hitMask), _spell(spell), _damageInfo(damageInfo), _healInfo(healInfo), _triggeredByAuraSpell(triggeredByAuraSpell), _procAuraEffectIndex(procAuraEffectIndex)
|
||||
{
|
||||
@@ -15407,7 +15407,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
|
||||
|
||||
DamageInfo damageInfo = DamageInfo(actor, actionTarget, damage, procSpellInfo, procSpellInfo ? SpellSchoolMask(procSpellInfo->SchoolMask) : SPELL_SCHOOL_MASK_NORMAL, SPELL_DIRECT_DAMAGE);
|
||||
HealInfo healInfo = HealInfo(actor, actionTarget, damage, procSpellInfo, procSpellInfo ? SpellSchoolMask(procSpellInfo->SchoolMask) : SPELL_SCHOOL_MASK_NORMAL);
|
||||
ProcEventInfo eventInfo = ProcEventInfo(actor, actionTarget, target, procFlag, 0, 0, procExtra, nullptr, &damageInfo, &healInfo, procAura, procAuraEffectIndex);
|
||||
ProcEventInfo eventInfo = ProcEventInfo(actor, actionTarget, target, procFlag, 0, 0, procExtra, procSpell, &damageInfo, &healInfo, procAura, procAuraEffectIndex);
|
||||
|
||||
ProcTriggeredList procTriggered;
|
||||
// Fill procTriggered list
|
||||
@@ -15439,7 +15439,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
|
||||
if (!active && !isVictim && !(procFlag & PROC_FLAG_DONE_PERIODIC) && procSpellInfo && procSpellInfo->SpellFamilyName && (procSpellInfo->HasAura(SPELL_AURA_PERIODIC_DAMAGE) || procSpellInfo->HasAura(SPELL_AURA_PERIODIC_HEAL)))
|
||||
active = true;
|
||||
|
||||
if (!IsTriggeredAtSpellProcEvent(target, triggerData.aura, procSpellInfo, procFlag, procExtra, attType, isVictim, active, triggerData.spellProcEvent, eventInfo))
|
||||
if (!IsTriggeredAtSpellProcEvent(target, triggerData.aura, attType, isVictim, active, triggerData.spellProcEvent, eventInfo))
|
||||
continue;
|
||||
|
||||
// do checks using conditions table
|
||||
@@ -16483,9 +16483,10 @@ bool Unit::InitTamedPet(Pet* pet, uint8 level, uint32 spell_id)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Unit::IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, SpellInfo const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent, ProcEventInfo const& eventInfo)
|
||||
bool Unit::IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent, ProcEventInfo const& eventInfo)
|
||||
{
|
||||
SpellInfo const* spellProto = aura->GetSpellInfo();
|
||||
SpellInfo const* procSpell = eventInfo.GetSpellInfo();
|
||||
|
||||
// let the aura be handled by new proc system if it has new entry
|
||||
if (sSpellMgr->GetSpellProcEntry(spellProto->Id))
|
||||
@@ -16520,7 +16521,7 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, SpellInfo const
|
||||
return false;
|
||||
|
||||
// Check spellProcEvent data requirements
|
||||
if (!sSpellMgr->IsSpellProcEventCanTriggeredBy(spellProto, spellProcEvent, EventProcFlag, procSpell, procFlag, procExtra, active))
|
||||
if (!sSpellMgr->IsSpellProcEventCanTriggeredBy(spellProto, spellProcEvent, EventProcFlag, eventInfo, active))
|
||||
return false;
|
||||
// In most cases req get honor or XP from kill
|
||||
if (EventProcFlag & PROC_FLAG_KILL && GetTypeId() == TYPEID_PLAYER)
|
||||
|
||||
@@ -958,14 +958,14 @@ private:
|
||||
uint32 _spellPhaseMask;
|
||||
uint32 _hitMask;
|
||||
uint32 _cooldown;
|
||||
Spell* _spell;
|
||||
Spell const* _spell;
|
||||
DamageInfo* _damageInfo;
|
||||
HealInfo* _healInfo;
|
||||
SpellInfo const* const _triggeredByAuraSpell;
|
||||
int8 _procAuraEffectIndex;
|
||||
|
||||
public:
|
||||
explicit ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget, uint32 typeMask, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo, SpellInfo const* triggeredByAuraSpell = nullptr, int8 procAuraEffectIndex = -1);
|
||||
explicit ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget, uint32 typeMask, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell const* spell, DamageInfo* damageInfo, HealInfo* healInfo, SpellInfo const* triggeredByAuraSpell = nullptr, int8 procAuraEffectIndex = -1);
|
||||
Unit* GetActor() { return _actor; };
|
||||
[[nodiscard]] Unit* GetActionTarget() const { return _actionTarget; }
|
||||
[[nodiscard]] Unit* GetProcTarget() const { return _procTarget; }
|
||||
@@ -975,7 +975,7 @@ public:
|
||||
[[nodiscard]] uint32 GetHitMask() const { return _hitMask; }
|
||||
[[nodiscard]] SpellInfo const* GetSpellInfo() const;
|
||||
[[nodiscard]] SpellSchoolMask GetSchoolMask() const { return SPELL_SCHOOL_MASK_NONE; }
|
||||
[[nodiscard]] Spell* GetProcSpell() const { return _spell; }
|
||||
[[nodiscard]] Spell const* GetProcSpell() const { return _spell; }
|
||||
[[nodiscard]] DamageInfo* GetDamageInfo() const { return _damageInfo; }
|
||||
[[nodiscard]] HealInfo* GetHealInfo() const { return _healInfo; }
|
||||
[[nodiscard]] SpellInfo const* GetTriggerAuraSpell() const { return _triggeredByAuraSpell; }
|
||||
@@ -2571,7 +2571,7 @@ protected:
|
||||
bool _instantCast;
|
||||
|
||||
private:
|
||||
bool IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, SpellInfo const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent, ProcEventInfo const& eventInfo);
|
||||
bool IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent, ProcEventInfo const& eventInfo);
|
||||
bool HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
|
||||
bool HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, bool* handled);
|
||||
bool HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user