From 2e551a052ecef2f7bb9c0206ecae3960e3653fa3 Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Thu, 14 Feb 2019 09:07:29 +0100 Subject: [PATCH] Core/Spells: implement OnSpellStart spellscript hook that is getting called when the cast check has been successfully passed and the spell starts casting with a cast time --- src/server/game/Spells/Spell.cpp | 16 ++++++++++++++++ src/server/game/Spells/Spell.h | 1 + src/server/game/Spells/SpellScript.h | 5 ++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index d42231263ab..d2aef5a6eda 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -3148,6 +3148,8 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered if (!(_triggeredCastFlags & TRIGGERED_IGNORE_GCD)) TriggerGlobalCooldown(); + CallScriptOnSpellStartHandlers(); + // commented out !m_spellInfo->StartRecoveryTime, it forces instant spells with global cooldown to be processed in spell::update // as a result a spell that passed CheckCast and should be processed instantly may suffer from this delayed process // the easiest bug to observe is LoS check in AddUnitTarget, even if spell passed the CheckCast LoS check the situation can change in spell::update @@ -7699,6 +7701,20 @@ SpellCastResult Spell::CallScriptCheckCastHandlers() return retVal; } +void Spell::CallScriptOnSpellStartHandlers() +{ + for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr) + { + (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_SPELL_START); + auto hookItrEnd = (*scritr)->OnSpellStart.end(), hookItr = (*scritr)->OnSpellStart.begin(); + for (; hookItr != hookItrEnd; ++hookItr) + (*hookItr).Call(*scritr); + + (*scritr)->_FinishScriptCall(); + } +} + + void Spell::PrepareScriptHitHandlers() { for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr) diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index d368f1a1cc3..e204e0b5e6a 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -689,6 +689,7 @@ class TC_GAME_API Spell void CallScriptBeforeCastHandlers(); void CallScriptOnCastHandlers(); void CallScriptAfterCastHandlers(); + void CallScriptOnSpellStartHandlers(); SpellCastResult CallScriptCheckCastHandlers(); void PrepareScriptHitHandlers(); bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode); diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index ada9008551c..97a0a0984f2 100644 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -172,7 +172,8 @@ enum SpellScriptHookType SPELL_SCRIPT_HOOK_CHECK_CAST, SPELL_SCRIPT_HOOK_BEFORE_CAST, SPELL_SCRIPT_HOOK_ON_CAST, - SPELL_SCRIPT_HOOK_AFTER_CAST + SPELL_SCRIPT_HOOK_AFTER_CAST, + SPELL_SCRIPT_HOOK_ON_SPELL_START }; #define HOOK_SPELL_HIT_START SPELL_SCRIPT_HOOK_EFFECT_HIT @@ -307,6 +308,8 @@ class TC_GAME_API SpellScript : public _SpellScript // SpellScript interface // hooks to which you can attach your functions // + // example: OnSpellStart += SpellCastFn(class::function); + HookList OnSpellStart; // example: BeforeCast += SpellCastFn(class::function); HookList BeforeCast; // example: OnCast += SpellCastFn(class::function);