fix(Scripts/Spells): Finger of Frost Shatter Combo. (#13006)

This commit is contained in:
UltraNix
2022-09-19 05:46:17 +02:00
committed by GitHub
parent c8da2b64fe
commit a5ab96c79d
8 changed files with 173 additions and 5 deletions

View File

@@ -169,6 +169,7 @@ ProcEventInfo::ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget,
: _actor(actor), _actionTarget(actionTarget), _procTarget(procTarget), _typeMask(typeMask), _spellTypeMask(spellTypeMask), _spellPhaseMask(spellPhaseMask),
_hitMask(hitMask), _spell(spell), _damageInfo(damageInfo), _healInfo(healInfo), _triggeredByAuraSpell(triggeredByAuraSpell), _procAuraEffectIndex(procAuraEffectIndex)
{
_chance.reset();
}
SpellInfo const* ProcEventInfo::GetSpellInfo() const
@@ -15852,18 +15853,29 @@ 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, attType, isVictim, active, triggerData.spellProcEvent, eventInfo))
// AuraScript Hook
if (!triggerData.aura->CallScriptCheckProcHandlers(itr->second, eventInfo))
{
continue;
}
bool isTriggeredAtSpellProcEvent = IsTriggeredAtSpellProcEvent(target, triggerData.aura, attType, isVictim, active, triggerData.spellProcEvent, eventInfo);
// AuraScript Hook
triggerData.aura->CallScriptCheckAfterProcHandlers(itr->second, eventInfo);
if (!isTriggeredAtSpellProcEvent)
{
continue;
}
// do checks using conditions table
ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_PROC, spellProto->Id);
ConditionSourceInfo condInfo = ConditionSourceInfo(eventInfo.GetActor(), eventInfo.GetActionTarget());
if (!sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
{
continue;
// AuraScript Hook
if (!triggerData.aura->CallScriptCheckProcHandlers(itr->second, eventInfo))
continue;
}
// Triggered spells not triggering additional spells
//bool triggered = !spellProto->HasAttribute(SPELL_ATTR3_CAN_PROC_FROM_PROCS) ?
@@ -17164,11 +17176,17 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, WeaponAttackTyp
}
}
if (eventInfo.GetProcChance())
{
chance = *eventInfo.GetProcChance();
}
// Apply chance modifer aura
if (Player* modOwner = GetSpellModOwner())
{
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CHANCE_OF_SUCCESS, chance);
}
return roll_chance_f(chance);
}

View File

@@ -25,6 +25,7 @@
#include "HostileRefMgr.h"
#include "MotionMaster.h"
#include "Object.h"
#include "Optional.h"
#include "SpellAuraDefines.h"
#include "SpellDefines.h"
#include "ThreatMgr.h"
@@ -836,6 +837,7 @@ private:
HealInfo* _healInfo;
SpellInfo const* const _triggeredByAuraSpell;
int8 _procAuraEffectIndex;
std::optional<float> _chance;
public:
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);
@@ -855,6 +857,9 @@ public:
[[nodiscard]] int8 GetTriggerAuraEffectIndex() const { return _procAuraEffectIndex; }
[[nodiscard]] uint32 GetProcCooldown() const { return _cooldown; }
void SetProcCooldown(uint32 cooldown) { _cooldown = cooldown; }
[[nodiscard]] std::optional<float> GetProcChance() const { return _chance; }
void SetProcChance(float chance) { _chance = chance; }
void ResetProcChance() { _chance.reset(); }
};
// Struct for use in Unit::CalculateMeleeDamage

View File

@@ -2620,6 +2620,22 @@ bool Aura::CallScriptCheckProcHandlers(AuraApplication const* aurApp, ProcEventI
return result;
}
bool Aura::CallScriptCheckAfterProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo)
{
bool result = true;
for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
{
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_CHECK_AFTER_PROC, aurApp);
std::list<AuraScript::CheckProcHandler>::iterator hookItrEnd = (*scritr)->DoCheckAfterProc.end(), hookItr = (*scritr)->DoCheckAfterProc.begin();
for (; hookItr != hookItrEnd; ++hookItr)
result &= hookItr->Call(*scritr, eventInfo);
(*scritr)->_FinishScriptCall();
}
return result;
}
bool Aura::CallScriptPrepareProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo)
{
bool prepare = true;

View File

@@ -226,6 +226,7 @@ public:
// Spell Proc Hooks
bool CallScriptCheckProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo);
bool CallScriptCheckAfterProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo);
bool CallScriptPrepareProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo);
bool CallScriptProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo);
void CallScriptAfterProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo);

View File

@@ -733,6 +733,10 @@ bool AuraScript::_Validate(SpellInfo const* entry)
if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
LOG_ERROR("spells.scripts", "Spell `{}` of script `{}` does not have apply aura effect - handler bound to hook `DoCheckProc` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
for (std::list<CheckProcHandler>::iterator itr = DoCheckAfterProc.begin(); itr != DoCheckAfterProc.end(); ++itr)
if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
LOG_ERROR("spells.scripts", "Spell `{}` of script `{}` does not have apply aura effect - handler bound to hook `DoCheckAfterProc` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
for (std::list<AuraProcHandler>::iterator itr = DoPrepareProc.begin(); itr != DoPrepareProc.end(); ++itr)
if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
LOG_ERROR("spells.scripts", "Spell `{}` of script `{}` does not have apply aura effect - handler bound to hook `DoPrepareProc` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
@@ -1163,6 +1167,7 @@ Unit* AuraScript::GetTarget() const
case AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD:
case AURA_SCRIPT_HOOK_EFFECT_SPLIT:
case AURA_SCRIPT_HOOK_CHECK_PROC:
case AURA_SCRIPT_HOOK_CHECK_AFTER_PROC:
case AURA_SCRIPT_HOOK_PREPARE_PROC:
case AURA_SCRIPT_HOOK_PROC:
case AURA_SCRIPT_HOOK_AFTER_PROC:

View File

@@ -499,6 +499,7 @@ enum AuraScriptHookType
AURA_SCRIPT_HOOK_AFTER_DISPEL,
// Spell Proc Hooks
AURA_SCRIPT_HOOK_CHECK_PROC,
AURA_SCRIPT_HOOK_CHECK_AFTER_PROC,
AURA_SCRIPT_HOOK_PREPARE_PROC,
AURA_SCRIPT_HOOK_PROC,
AURA_SCRIPT_HOOK_EFFECT_PROC,
@@ -804,6 +805,10 @@ public:
// example: DoCheckProc += AuraCheckProcFn(class::function);
// where function is: bool function (ProcEventInfo& eventInfo);
HookList<CheckProcHandler> DoCheckProc;
// executed when aura checks if it can proc
// example: DoCheckAfterProc += AuraCheckProcFn(class::function);
// where function is: bool function (ProcEventInfo& eventInfo);
HookList<CheckProcHandler> DoCheckAfterProc;
#define AuraCheckProcFn(F) CheckProcHandlerFunction(&F)
// executed before aura procs (possibility to prevent charge drop/cooldown)