mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/SpellScripts: implement Spell Proc Hooks and use it in old and new proc system
Hooks: - DoCheckProc: executed when aura checks if it can proc - DoPrepareProc: executed before aura procs (possibility to prevent charge drop/cooldown) - OnProc: executed when aura procs - OnEffectProc: executed when aura effect procs - AfterEffectProc: executed after aura effect proced - AfterProc: executed after aura proced and charges removed using PreventDefaultAction() in DoPrepareProc will prevent charge drop and cooldown default execution of a proc can prevented in OnEffectProc with PreventDefaultAction() Now we should be able to convert almost all procs from Unit::ProcDamageAndSpellFor to SpellScripts Notes to old proc system: - if a proc has a cooldown we must check it in spellscript and add it when we handle the proc - behavior with charge drops is possible undefined (use PreventDefaultAction() in OnEffectProc to notify that the script is executed)
This commit is contained in:
@@ -470,7 +470,7 @@ WorldLocation* SpellScript::GetHitDest()
|
||||
{
|
||||
if (!IsInEffectHook())
|
||||
{
|
||||
sLog->outError(LOG_FILTER_TSCR, "Script: `%s` Spell: `%u`: function SpellScript::GetHitGObj was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId);
|
||||
sLog->outError(LOG_FILTER_TSCR, "Script: `%s` Spell: `%u`: function SpellScript::GetHitDest was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId);
|
||||
return NULL;
|
||||
}
|
||||
return m_spell->destTarget;
|
||||
@@ -679,6 +679,30 @@ bool AuraScript::_Validate(SpellInfo const* entry)
|
||||
if (!(*itr).GetAffectedEffectsMask(entry))
|
||||
sLog->outError(LOG_FILTER_TSCR, "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectSplit` of AuraScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
|
||||
|
||||
for (std::list<CheckProcHandler>::iterator itr = DoCheckProc.begin(); itr != DoCheckProc.end(); ++itr)
|
||||
if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
|
||||
sLog->outError(LOG_FILTER_TSCR, "Spell `%u` of script `%s` 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<AuraProcHandler>::iterator itr = DoPrepareProc.begin(); itr != DoPrepareProc.end(); ++itr)
|
||||
if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
|
||||
sLog->outError(LOG_FILTER_TSCR, "Spell `%u` of script `%s` does not have apply aura effect - handler bound to hook `DoPrepareProc` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
|
||||
|
||||
for (std::list<AuraProcHandler>::iterator itr = OnProc.begin(); itr != OnProc.end(); ++itr)
|
||||
if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
|
||||
sLog->outError(LOG_FILTER_TSCR, "Spell `%u` of script `%s` does not have apply aura effect - handler bound to hook `OnProc` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
|
||||
|
||||
for (std::list<AuraProcHandler>::iterator itr = AfterProc.begin(); itr != AfterProc.end(); ++itr)
|
||||
if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
|
||||
sLog->outError(LOG_FILTER_TSCR, "Spell `%u` of script `%s` does not have apply aura effect - handler bound to hook `AfterProc` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
|
||||
|
||||
for (std::list<EffectProcHandler>::iterator itr = OnEffectProc.begin(); itr != OnEffectProc.end(); ++itr)
|
||||
if (!(*itr).GetAffectedEffectsMask(entry))
|
||||
sLog->outError(LOG_FILTER_TSCR, "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectProc` of AuraScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
|
||||
|
||||
for (std::list<EffectProcHandler>::iterator itr = AfterEffectProc.begin(); itr != AfterEffectProc.end(); ++itr)
|
||||
if (!(*itr).GetAffectedEffectsMask(entry))
|
||||
sLog->outError(LOG_FILTER_TSCR, "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `AfterEffectProc` of AuraScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
|
||||
|
||||
return _SpellScript::_Validate(entry);
|
||||
}
|
||||
|
||||
@@ -818,6 +842,37 @@ void AuraScript::EffectSplitHandler::Call(AuraScript* auraScript, AuraEffect* au
|
||||
(auraScript->*pEffectHandlerScript)(aurEff, dmgInfo, splitAmount);
|
||||
}
|
||||
|
||||
AuraScript::CheckProcHandler::CheckProcHandler(AuraCheckProcFnType handlerScript)
|
||||
{
|
||||
_HandlerScript = handlerScript;
|
||||
}
|
||||
|
||||
bool AuraScript::CheckProcHandler::Call(AuraScript* auraScript, ProcEventInfo& eventInfo)
|
||||
{
|
||||
return (auraScript->*_HandlerScript)(eventInfo);
|
||||
}
|
||||
|
||||
AuraScript::AuraProcHandler::AuraProcHandler(AuraProcFnType handlerScript)
|
||||
{
|
||||
_HandlerScript = handlerScript;
|
||||
}
|
||||
|
||||
void AuraScript::AuraProcHandler::Call(AuraScript* auraScript, ProcEventInfo& eventInfo)
|
||||
{
|
||||
(auraScript->*_HandlerScript)(eventInfo);
|
||||
}
|
||||
|
||||
AuraScript::EffectProcHandler::EffectProcHandler(AuraEffectProcFnType effectHandlerScript, uint8 effIndex, uint16 effName)
|
||||
: AuraScript::EffectBase(effIndex, effName)
|
||||
{
|
||||
_EffectHandlerScript = effectHandlerScript;
|
||||
}
|
||||
|
||||
void AuraScript::EffectProcHandler::Call(AuraScript* auraScript, AuraEffect const* aurEff, ProcEventInfo& eventInfo)
|
||||
{
|
||||
(auraScript->*_EffectHandlerScript)(aurEff, eventInfo);
|
||||
}
|
||||
|
||||
bool AuraScript::_Load(Aura* aura)
|
||||
{
|
||||
m_aura = aura;
|
||||
@@ -853,6 +908,8 @@ bool AuraScript::_IsDefaultActionPrevented()
|
||||
case AURA_SCRIPT_HOOK_EFFECT_PERIODIC:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_ABSORB:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_SPLIT:
|
||||
case AURA_SCRIPT_HOOK_PREPARE_PROC:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_PROC:
|
||||
return m_defaultActionPrevented;
|
||||
default:
|
||||
ASSERT(false && "AuraScript::_IsDefaultActionPrevented is called in a wrong place");
|
||||
@@ -869,6 +926,8 @@ void AuraScript::PreventDefaultAction()
|
||||
case AURA_SCRIPT_HOOK_EFFECT_PERIODIC:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_ABSORB:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_SPLIT:
|
||||
case AURA_SCRIPT_HOOK_PREPARE_PROC:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_PROC:
|
||||
m_defaultActionPrevented = true;
|
||||
break;
|
||||
default:
|
||||
@@ -1051,6 +1110,12 @@ Unit* AuraScript::GetTarget() const
|
||||
case AURA_SCRIPT_HOOK_EFFECT_MANASHIELD:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_SPLIT:
|
||||
case AURA_SCRIPT_HOOK_CHECK_PROC:
|
||||
case AURA_SCRIPT_HOOK_PREPARE_PROC:
|
||||
case AURA_SCRIPT_HOOK_PROC:
|
||||
case AURA_SCRIPT_HOOK_AFTER_PROC:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_PROC:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_AFTER_PROC:
|
||||
return m_auraApplication->GetTarget();
|
||||
default:
|
||||
sLog->outError(LOG_FILTER_TSCR, "Script: `%s` Spell: `%u` AuraScript::GetTarget called in a hook in which the call won't have effect!", m_scriptName->c_str(), m_scriptSpellId);
|
||||
|
||||
Reference in New Issue
Block a user