TrinityCore
Loading...
Searching...
No Matches
SpellScript.h
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef TRINITY_SPELL_SCRIPT_H
19#define TRINITY_SPELL_SCRIPT_H
20
21#include "ObjectGuid.h"
22#include "SharedDefines.h"
23#include "SpellAuraDefines.h"
24#include "Util.h"
25#include <stack>
26
27#ifdef TRINITY_API_USE_DYNAMIC_LINKING
28#include <memory>
29#endif
30
31class Aura;
32class AuraApplication;
33class AuraEffect;
34class Creature;
35class Corpse;
36class DamageInfo;
37class DispelInfo;
38class DynamicObject;
39class GameObject;
40class HealInfo;
41class Item;
42class ModuleReference;
43class Player;
44class ProcEventInfo;
45class Spell;
46class SpellEffectInfo;
47class SpellInfo;
48class SpellScript;
49class Unit;
50class WorldLocation;
51class WorldObject;
52struct SpellDestination;
53struct SpellModifier;
54struct SpellValue;
55enum Difficulty : int16;
56enum class ItemContext : uint8;
57
58using SpellEffectValue = double;
59
60#define SPELL_EFFECT_ANY ((uint16)-1)
61#define SPELL_AURA_ANY ((uint16)-1)
62
70#define SPELL_SCRIPT_STATE_END (SPELL_SCRIPT_STATE_UNLOADING + 1)
71
72// helper class from which SpellScript and AuraScript derive, use these classes instead
74{
75// internal use classes & functions
76// DO NOT OVERRIDE THESE IN SCRIPTS
77public:
78 SpellScriptBase() noexcept;
80
81 SpellScriptBase(SpellScriptBase const& right) = delete;
83 SpellScriptBase& operator=(SpellScriptBase const& right) = delete;
85
86 void _Register();
87 void _Unload();
88 void _Init(std::string const& scriptname, uint32 spellId);
89 std::string_view GetScriptName() const;
90
91protected:
92 virtual bool _Validate(SpellInfo const* entry);
93
94 // compile barrier to avoid instantiating operator+= in every script file
95 template <typename T>
96 class HookList : public ::HookList<T>
97 {
98 public:
99 HookList& operator+=(T&& t) noexcept;
100 };
101
103 {
104 public:
105 explicit EffectHook(uint8 effIndex);
106 EffectHook(EffectHook const& right) = delete;
107 EffectHook(EffectHook&& right) noexcept;
108 EffectHook& operator=(EffectHook const& right) = delete;
109 EffectHook& operator=(EffectHook&& right) noexcept;
110 virtual ~EffectHook();
111
112 uint32 GetAffectedEffectsMask(SpellInfo const* spellInfo) const;
113 bool IsEffectAffected(SpellInfo const* spellInfo, uint8 effIndex) const;
114 virtual bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex) const = 0;
115 std::string EffIndexToString() const;
116
117 protected:
119 };
120
121 template<typename>
123 {
124 using type = void;
125 };
126
127 template<typename Return, typename Class, typename... Args>
128 struct GetScriptClass<Return(Class::*)(Args...)>
129 {
130 using type = Class;
131 };
132
133 template<typename Return, typename Class, typename... Args>
134 struct GetScriptClass<Return(Class::*)(Args...) const>
135 {
136 using type = Class;
137 };
138
139 template<typename Return, typename Class, typename... Args>
140 struct GetScriptClass<Return(*)(Class&, Args...)>
141 {
142 using type = std::remove_const_t<Class>;
143 };
144
145 template<typename ScriptFunc>
147
148 template <typename Ret, typename BaseClass, typename... Args>
150 {
152 {
153 Ret(BaseClass::* Member)(Args...);
154 Ret(* Static)(BaseClass&, Args...);
155 };
156
157 static constexpr std::size_t Size = sizeof(SizeAndAlignment);
158 static constexpr std::size_t Alignment = alignof(SizeAndAlignment);
159
160 struct alignas(Alignment) StorageType : std::array<std::byte, Size> { };
161
162 template <typename ScriptFunc>
163 struct Impl
164 {
166
167 static Ret Invoke(BaseClass& script, Args... args, StorageType callImpl)
168 {
169 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
170 return (static_cast<ScriptClass&>(script).*reinterpret_cast<Impl const*>(callImpl.data())->Func)(args...);
171 else
172 return reinterpret_cast<Impl const*>(callImpl.data())->Func(static_cast<ScriptClass&>(script), args...);
173 }
174
175 ScriptFunc Func;
176 };
177
179 Ret(* Thunk)(BaseClass&, Args..., StorageType);
180 };
181
182 std::string_view m_scriptName;
185
186private:
187
188#ifdef TRINITY_API_USE_DYNAMIC_LINKING
189
190 // Strong reference to keep the binary code loaded
191 std::shared_ptr<ModuleReference> m_moduleReference;
192
193#endif // #ifndef TRINITY_API_USE_DYNAMIC_LINKING
194
195public:
196 //
197 // SpellScript/AuraScript interface base
198 // these functions are safe to override, see notes below for usage instructions
199 //
200 // Function in which handler functions are registered, must be implemented in script
201 virtual void Register() = 0;
202 // Function called on server startup, if returns false script won't be used in core
203 // use for: dbc/template data presence/correctness checks
204 virtual bool Validate([[maybe_unused]] SpellInfo const* spellInfo) { return true; }
205 // Function called when script is created, if returns false script will be unloaded afterwards
206 // use for: initializing local script variables (DO NOT USE CONSTRUCTOR FOR THIS PURPOSE!)
207 virtual bool Load() { return true; }
208 // Function called when script is destroyed
209 // use for: deallocating memory allocated by script
210 virtual void Unload() { }
211 // Helpers
212 static bool ValidateSpellInfo(std::initializer_list<uint32> spellIds)
213 {
214 return ValidateSpellInfoImpl(spellIds.begin(), spellIds.end());
215 }
216
217 template <class T>
218 static bool ValidateSpellInfo(T const& spellIds)
219 {
220 return ValidateSpellInfoImpl(std::cbegin(spellIds), std::cend(spellIds));
221 }
222
223 static bool ValidateSpellEffect(std::initializer_list<std::pair<uint32, SpellEffIndex>> effects)
224 {
225 return ValidateSpellEffectsImpl(effects.begin(), effects.end());
226 }
227
228 template <class T>
229 static bool ValidateSpellEffect(T const& spellEffects)
230 {
231 return ValidateSpellEffectsImpl(std::cbegin(spellEffects), std::cend(spellEffects));
232 }
233
234private:
235 template<typename Iterator>
236 static bool ValidateSpellInfoImpl(Iterator begin, Iterator end)
237 {
238 bool allValid = true;
239 while (begin != end)
240 {
241 if (!ValidateSpellInfoImpl(*begin))
242 allValid = false;
243
244 ++begin;
245 }
246 return allValid;
247 }
248
249 template<typename Iterator>
250 static bool ValidateSpellEffectsImpl(Iterator begin, Iterator end)
251 {
252 bool allValid = true;
253 while (begin != end)
254 {
255 if (!ValidateSpellEffectImpl(begin->first, begin->second))
256 allValid = false;
257
258 ++begin;
259 }
260 return allValid;
261 }
262
263 static bool ValidateSpellInfoImpl(uint32 spellId);
264 static bool ValidateSpellEffectImpl(uint32 spellId, SpellEffIndex effectIndex);
265};
266
267// SpellScript interface - enum used for runtime checks of script function calls
294
295#define HOOK_SPELL_HIT_START SPELL_SCRIPT_HOOK_EFFECT_HIT
296#define HOOK_SPELL_HIT_END SPELL_SCRIPT_HOOK_AFTER_HIT + 1
297
299{
300 // internal use classes & functions
301 // DO NOT OVERRIDE THESE IN SCRIPTS
302 template <typename Ret, typename... Args>
304
305public:
306 class CastHandler final
307 {
308 public:
310
311 template<typename ScriptFunc>
312 explicit CastHandler(ScriptFunc handler)
313 {
314 using ScriptClass = GetScriptClass_t<ScriptFunc>;
315
316 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
317 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
318
319 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&>,
320 R""(CastHandler signature must be "void HandleCast()")"");
321
322 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
324 }
325
326 void Call(SpellScript* spellScript) const
327 {
328 return _invoker.Thunk(*spellScript, _invoker.ImplStorage);
329 }
330 private:
332 };
333
335 {
336 public:
338
339 template<typename ScriptFunc>
340 explicit CheckCastHandler(ScriptFunc handler)
341 {
342 using ScriptClass = GetScriptClass_t<ScriptFunc>;
343
344 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
345 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
346
347 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
348 static_assert(std::is_invocable_r_v<SpellCastResult, ScriptFunc, ScriptClass&>,
349 R""(CheckCastHandler signature must be "SpellCastResult CheckCast()")"");
350 else
351 static_assert(std::is_invocable_r_v<SpellCastResult, ScriptFunc, SpellScript&>,
352 R""(CheckCastHandler signature must be "static SpellCastResult CheckCast(your_script_class& script, SpellScript&)")"");
353
354 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
356 }
357
358 SpellCastResult Call(SpellScript* spellScript) const
359 {
360 return _invoker.Thunk(*spellScript, _invoker.ImplStorage);
361 }
362 private:
364 };
365
367 {
368 public:
369 EffectBase(uint8 effIndex, uint16 effName);
370 EffectBase(EffectBase const& right) = delete;
371 EffectBase(EffectBase&& right) noexcept;
372 EffectBase& operator=(EffectBase const& right) = delete;
373 EffectBase& operator=(EffectBase&& right) noexcept;
375 std::string ToString() const;
376 bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex) const override;
377 private:
379 };
380
381 class EffectHandler final : public EffectBase
382 {
383 public:
385
386 template<typename ScriptFunc>
387 explicit EffectHandler(ScriptFunc handler, uint8 effIndex, uint16 effName)
388 : EffectBase(effIndex, effName)
389 {
390 using ScriptClass = GetScriptClass_t<ScriptFunc>;
391
392 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
393 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
394
395 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, SpellEffIndex>,
396 R""(EffectHandler signature must be "void HandleEffect(SpellEffIndex effIndex)")"");
397
398 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
400 }
401
402 void Call(SpellScript* spellScript, SpellEffIndex effIndex) const
403 {
404 return _invoker.Thunk(*spellScript, effIndex, _invoker.ImplStorage);
405 }
406 private:
408 };
409
411 {
412 public:
414
415 template<typename ScriptFunc>
416 explicit BeforeHitHandler(ScriptFunc handler)
417 {
418 using ScriptClass = GetScriptClass_t<ScriptFunc>;
419
420 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
421 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
422
423 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, SpellMissInfo>,
424 R""(BeforeHitHandler signature must be "void HandleBeforeHit(SpellMissInfo missInfo)")"");
425
426 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
428 }
429
430 void Call(SpellScript* spellScript, SpellMissInfo missInfo) const
431 {
432 return _invoker.Thunk(*spellScript, missInfo, _invoker.ImplStorage);
433 }
434 private:
436 };
437
438 class HitHandler final
439 {
440 public:
442
443 template<typename ScriptFunc>
444 explicit HitHandler(ScriptFunc handler)
445 {
446 using ScriptClass = GetScriptClass_t<ScriptFunc>;
447
448 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
449 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
450
451 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&>,
452 R""(HitHandler signature must be "void HandleHit()")"");
453
454 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
456 }
457
458 void Call(SpellScript* spellScript) const
459 {
460 return _invoker.Thunk(*spellScript, _invoker.ImplStorage);
461 }
462 private:
464 };
465
467 {
468 public:
470
471 template<typename ScriptFunc>
472 explicit OnCalcCritChanceHandler(ScriptFunc handler)
473 {
474 using ScriptClass = GetScriptClass_t<ScriptFunc>;
475
476 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
477 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
478
479 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
480 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, Unit const*, float&>,
481 R""(OnCalcCritChanceHandler signature must be "void CalcCritChance(Unit const* victim, float& critChance)")"");
482 else
483 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, Unit const*, float&>,
484 R""(OnCalcCritChanceHandler signature must be "static void CalcCritChance(your_script_class& script, Unit const* victim, float& critChance)")"");
485
486 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
488 }
489
490 void Call(SpellScript* spellScript, Unit const* victim, float& critChance) const
491 {
492 return _invoker.Thunk(*spellScript, victim, critChance, _invoker.ImplStorage);
493 }
494 private:
496 };
497
499 {
500 public:
501 TargetHook(uint8 effectIndex, uint16 targetType, bool area, bool dest);
502 TargetHook(TargetHook const& right) = delete;
503 TargetHook(TargetHook&& right) noexcept;
504 TargetHook& operator=(TargetHook const& right) = delete;
505 TargetHook& operator=(TargetHook&& right) noexcept;
506 virtual ~TargetHook();
507 bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex) const override;
508 std::string ToString() const;
509 uint16 GetTarget() const { return _targetType; }
510 protected:
512 bool _area;
513 bool _dest;
514 };
515
517 {
518 public:
520
521 template<typename ScriptFunc>
522 explicit ObjectAreaTargetSelectHandler(ScriptFunc handler, uint8 effIndex, uint16 targetType)
523 : TargetHook(effIndex, targetType, true, false)
524 {
525 using ScriptClass = GetScriptClass_t<ScriptFunc>;
526
527 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
528 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
529
530 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
531 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, std::list<WorldObject*>&>,
532 R""(ObjectAreaTargetSelectHandler signature must be "void SetTargets(std::list<WorldObject*>& targets)")"");
533 else
534 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, std::list<WorldObject*>&>,
535 R""(ObjectAreaTargetSelectHandler signature must be "static void SetTargets(your_script_class& script, std::list<WorldObject*>& targets)")"");
536
537 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
539 }
540
541 void Call(SpellScript* spellScript, std::list<WorldObject*>& targets) const
542 {
543 return _invoker.Thunk(*spellScript, targets, _invoker.ImplStorage);
544 }
545
547 {
548 return _invoker.ImplStorage == other._invoker.ImplStorage;
549 }
550 private:
552 };
553
555 {
556 public:
558
559 template<typename ScriptFunc>
560 explicit ObjectTargetSelectHandler(ScriptFunc handler, uint8 effIndex, uint16 targetType)
561 : TargetHook(effIndex, targetType, false, false)
562 {
563 using ScriptClass = GetScriptClass_t<ScriptFunc>;
564
565 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
566 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
567
568 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
569 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, WorldObject*&>,
570 R""(ObjectTargetSelectHandler signature must be "void SetTarget(WorldObject*& target)")"");
571 else
572 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, WorldObject*&>,
573 R""(ObjectTargetSelectHandler signature must be "static void SetTarget(your_script_class& script, WorldObject*& target)")"");
574
575 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
577 }
578
579 void Call(SpellScript* spellScript, WorldObject*& target) const
580 {
581 return _invoker.Thunk(*spellScript, target, _invoker.ImplStorage);
582 }
583
585 {
586 return _invoker.ImplStorage == other._invoker.ImplStorage;
587 }
588 private:
590 };
591
593 {
594 public:
596
597 template<typename ScriptFunc>
598 explicit DestinationTargetSelectHandler(ScriptFunc handler, uint8 effIndex, uint16 targetType)
599 : TargetHook(effIndex, targetType, false, true)
600 {
601 using ScriptClass = GetScriptClass_t<ScriptFunc>;
602
603 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
604 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
605
606 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
607 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, SpellDestination&>,
608 R""(DestinationTargetSelectHandler signature must be "void SetTarget(SpellDestination& target)")"");
609 else
610 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, SpellDestination&>,
611 R""(DestinationTargetSelectHandler signature must be "static void SetTarget(your_script_class& script, SpellDestination& target)")"");
612
613 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
615 }
616
617 void Call(SpellScript* spellScript, SpellDestination& target) const
618 {
619 return _invoker.Thunk(*spellScript, target, _invoker.ImplStorage);
620 }
621 private:
623 };
624
626 {
627 public:
629
630 template<typename ScriptFunc>
631 explicit DamageAndHealingCalcHandler(ScriptFunc handler)
632 {
633 using ScriptClass = GetScriptClass_t<ScriptFunc>;
634
635 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
636 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
637
638 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
639 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, SpellEffectInfo const&, Unit*, int32&, int32&, float&>,
640 R""(DamageAndHealingCalcHandler signature must be "void CalcDamage(SpellEffectInfo const& spellEffectInfo, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod)")"");
641 else
642 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, SpellEffectInfo const&, Unit*, int32&, int32&, float&>,
643 R""(DamageAndHealingCalcHandler signature must be "static void CalcDamage(your_script_class& script, SpellEffectInfo const& spellEffectInfo, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod)")"");
644
645 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
647 }
648
649 void Call(SpellScript* spellScript, SpellEffectInfo const& spellEffectInfo, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod) const
650 {
651 return _invoker.Thunk(*spellScript, spellEffectInfo, victim, damageOrHealing, flatMod, pctMod, _invoker.ImplStorage);
652 }
653 private:
655 };
656
658 {
659 public:
661
662 template<typename ScriptFunc>
663 explicit OnCalculateResistAbsorbHandler(ScriptFunc handler)
664 {
665 using ScriptClass = GetScriptClass_t<ScriptFunc>;
666
667 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
668 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
669
670 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
671 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, DamageInfo const&, uint32&, int32&>,
672 R""(OnCalculateResistAbsorbHandler signature must be "void CalcAbsorbResist(DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount)")"");
673 else
674 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, DamageInfo const&, uint32&, int32&>,
675 R""(OnCalculateResistAbsorbHandler signature must be "static void CalcAbsorbResist(your_script_class& script, DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount)")"");
676
677 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
679 }
680
681 void Call(SpellScript* spellScript, DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount) const
682 {
683 return _invoker.Thunk(*spellScript, damageInfo, resistAmount, absorbAmount, _invoker.ImplStorage);
684 }
685 private:
687 };
688
690 {
691 public:
693
694 template<typename ScriptFunc>
695 explicit EmpowerStageCompletedHandler(ScriptFunc handler)
696 {
697 using ScriptClass = GetScriptClass_t<ScriptFunc>;
698
699 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
700 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
701
702 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, int32>,
703 R""(EmpowerStageCompleted/EmpowerCompleted signature must be "void HandleEmpowerStageCompleted(int32 completedStagesCount)")"");
704
705 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
707 }
708
709 void Call(SpellScript* spellScript, int32 completedStagesCount) const
710 {
711 return _invoker.Thunk(*spellScript, completedStagesCount, _invoker.ImplStorage);
712 }
713 private:
715 };
716
717 // left for custom compatibility only, DO NOT USE
718 #define PrepareSpellScript(CLASSNAME)
719
720 SpellScript() noexcept;
722 bool _Validate(SpellInfo const* entry) override;
723 bool _Load(Spell* spell);
724 void _InitHit();
725 bool _IsEffectPrevented(SpellEffIndex effIndex) const { return (m_hitPreventEffectMask & (1 << effIndex)) != 0; }
726 bool _IsDefaultEffectPrevented(SpellEffIndex effIndex) const { return (m_hitPreventDefaultEffectMask & (1 << effIndex)) != 0; }
727 void _PrepareScriptCall(SpellScriptHookType hookType);
728 void _FinishScriptCall();
729 bool IsInCheckCastHook() const;
730 bool IsAfterTargetSelectionPhase() const;
731 bool IsInTargetHook() const;
732 bool IsInModifiableHook() const;
733 bool IsInHitPhase() const;
734 bool IsInEffectHook() const;
735private:
739public:
740 //
741 // SpellScript interface
742 //
743 // example: void OnPrecast() override { }
744 virtual void OnPrecast() { }
745 //
746 // hooks to which you can attach your functions
747 //
748 // example: BeforeCast += SpellCastFn(class::function);
750 // example: OnCast += SpellCastFn(class::function);
752 // example: AfterCast += SpellCastFn(class::function);
754 #define SpellCastFn(F) CastHandler(&F)
755
756 // example: OnCheckCast += SpellCheckCastFn();
757 // where function is SpellCastResult function()
759 #define SpellCheckCastFn(F) CheckCastHandler(&F)
760
761 // example: int32 CalcCastTime(int32 castTime) override { return 1500; }
762 virtual int32 CalcCastTime(int32 castTime) { return castTime; }
763
764 // example: OnEffect**** += SpellEffectFn(class::function, EffectIndexSpecifier, EffectNameSpecifier);
765 // where function is void function(SpellEffIndex effIndex)
771 #define SpellEffectFn(F, I, N) EffectHandler(&F, I, N)
772
773 // example: BeforeHit += BeforeSpellHitFn(class::function);
774 // where function is void function(SpellMissInfo missInfo)
776 #define BeforeSpellHitFn(F) BeforeHitHandler(&F)
777
778 // example: OnHit += SpellHitFn(class::function);
780 // example: AfterHit += SpellHitFn(class::function);
782 // where function is: void function()
783 #define SpellHitFn(F) HitHandler(&F)
784
785 // example: OnCalcCritChance += SpellOnCalcCritChanceFn(class::function);
786 // where function is: void function(Unit* victim, float& critChance)
788 #define SpellOnCalcCritChanceFn(F) OnCalcCritChanceHandler(&F)
789
790 // example: OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier);
791 // where function is void function(std::list<WorldObject*>& targets)
793 #define SpellObjectAreaTargetSelectFn(F, I, N) ObjectAreaTargetSelectHandler(&F, I, N)
794
795 // example: OnObjectTargetSelect += SpellObjectTargetSelectFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier);
796 // where function is void function(WorldObject*& target)
798 #define SpellObjectTargetSelectFn(F, I, N) ObjectTargetSelectHandler(&F, I, N)
799
800 // example: OnDestinationTargetSelect += SpellDestinationTargetSelectFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier);
801 // where function is void function(SpellDestination& target)
803 #define SpellDestinationTargetSelectFn(F, I, N) DestinationTargetSelectHandler(&F, I, N)
804
805 // example: CalcDamage += SpellCalcDamageFn(class::function);
806 // where function is void function(SpellEffectInfo const& effectInfo, Unit* victim, int32& damage, int32& flatMod, float& pctMod)
808 #define SpellCalcDamageFn(F) DamageAndHealingCalcHandler(&F)
809
810 // example: CalcHealing += SpellCalcHealingFn(class::function);
811 // where function is void function(SpellEffectInfo const& effectInfo, Unit* victim, int32& healing, int32& flatMod, float& pctMod)
813 #define SpellCalcHealingFn(F) DamageAndHealingCalcHandler(&F)
814
815 // example: OnCalculateResistAbsorb += SpellOnResistAbsorbCalculateFn(class::function);
816 // where function is void function(DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount)
818 #define SpellOnResistAbsorbCalculateFn(F) OnCalculateResistAbsorbHandler(&F)
819
820 // example: OnEmpowerStageCompleted += SpellOnEmpowerStageCompletedFn(class::function);
821 // where function is void function(int32 completedStages)
823 #define SpellOnEmpowerStageCompletedFn(F) EmpowerStageCompletedHandler(&F)
824
825 // example: OnEmpowerCompleted += SpellOnEmpowerCompletedFn(class::function);
826 // where function is void function(int32 completedStages)
828 #define SpellOnEmpowerCompletedFn(F) EmpowerStageCompletedHandler(&F)
829
830 // hooks are executed in following order, at specified event of spell:
831 // 1. OnPrecast - executed during spell preparation (before cast bar starts)
832 // 2. BeforeCast - executed when spell preparation is finished (when cast bar becomes full) before cast is handled
833 // 3. OnCheckCast - allows to override result of CheckCast function
834 // 4a. OnObjectAreaTargetSelect - executed just before adding selected targets to final target list (for area targets)
835 // 4b. OnObjectTargetSelect - executed just before adding selected target to final target list (for single unit targets)
836 // 4c. OnDestinationTargetSelect - executed just before adding selected target to final target list (for destination targets)
837 // 5. OnCast - executed just before spell is launched (creates missile) or executed
838 // 6. AfterCast - executed after spell missile is launched and immediate spell actions are done
839 // 7. OnEffectLaunch - executed just before specified effect handler call - when spell missile is launched
840 // 8. OnCalcCritChance - executed just after specified effect handler call - when spell missile is launched - called for each target from spell target map
841 // 9. OnEffectLaunchTarget - executed just before specified effect handler call - when spell missile is launched - called for each target from spell target map
842 // 10a. CalcDamage - executed during specified effect handler call - when spell missile is launched - called for each target from spell target map
843 // 10b. CalcHealing - executed during specified effect handler call - when spell missile is launched - called for each target from spell target map
844 // 11. OnCalculateResistAbsorb - executed when damage resist/absorbs is calculated - before spell hit target
845 // 12. OnEffectHit - executed just before specified effect handler call - when spell missile hits dest
846 // 13. BeforeHit - executed just before spell hits a target - called for each target from spell target map
847 // 14. OnEffectHitTarget - executed just before specified effect handler call - called for each target from spell target map
848 // 15. OnHit - executed just before spell deals damage and procs auras - when spell hits target - called for each target from spell target map
849 // 16. AfterHit - executed just after spell finishes all it's jobs for target - called for each target from spell target map
850 // 17. OnEmpowerStageCompleted - executed when empowered spell completes each stage
851 // 18. OnEmpowerCompleted - executed when empowered spell is released
852
853 // this hook is only executed after a successful dispel of any aura
854 // OnEffectSuccessfulDispel - executed just after effect successfully dispelled aura(s)
855
856 //
857 // methods allowing interaction with Spell object
858 //
859 // methods useable during all spell handling phases
860 Unit* GetCaster() const;
861 GameObject* GetGObjCaster() const;
862 Unit* GetOriginalCaster() const;
863 SpellInfo const* GetSpellInfo() const;
864 SpellEffectInfo const& GetEffectInfo(SpellEffIndex effIndex) const;
865 SpellValue const* GetSpellValue() const;
866
867 // methods useable after spell is prepared
868 // accessors to the explicit targets of the spell
869 // explicit target - target selected by caster (player, game client, or script - DoCast(explicitTarget, ...), required for spell to be cast
870 // examples:
871 // -shadowstep - explicit target is the unit you want to go behind of
872 // -chain heal - explicit target is the unit to be healed first
873 // -holy nova/arcane explosion - explicit target = NULL because target you are selecting doesn't affect how spell targets are selected
874 // you can determine if spell requires explicit targets by dbc columns:
875 // - Targets - mask of explicit target types
876 // - ImplicitTargetXX set to TARGET_XXX_TARGET_YYY, _TARGET_ here means that explicit target is used by the effect, so spell needs one too
877
878 // returns: WorldLocation which was selected as a spell destination or NULL
879 WorldLocation const* GetExplTargetDest() const;
880
881 void SetExplTargetDest(WorldLocation const& loc);
882
883 // returns: WorldObject which was selected as an explicit spell target or NULL if there's no target
884 WorldObject* GetExplTargetWorldObject() const;
885
886 // returns: Unit which was selected as an explicit spell target or NULL if there's no target
887 Unit* GetExplTargetUnit() const;
888
889 // returns: GameObject which was selected as an explicit spell target or NULL if there's no target
890 GameObject* GetExplTargetGObj() const;
891
892 // returns: Item which was selected as an explicit spell target or NULL if there's no target
893 Item* GetExplTargetItem() const;
894
895 // methods usable only after spell targets have been fully selected
896 int64 GetUnitTargetCountForEffect(SpellEffIndex effect) const;
897 int32 GetUnitTargetIndexForEffect(ObjectGuid const& target, SpellEffIndex effect) const;
898 int64 GetGameObjectTargetCountForEffect(SpellEffIndex effect) const;
899 int64 GetItemTargetCountForEffect(SpellEffIndex effect) const;
900 int64 GetCorpseTargetCountForEffect(SpellEffIndex effect) const;
901
902 // methods useable only during spell hit on target, or during spell launch on target:
903 // returns: target of current effect if it was Unit otherwise NULL
904 Unit* GetHitUnit() const;
905 // returns: target of current effect if it was Creature otherwise NULL
906 Creature* GetHitCreature() const;
907 // returns: target of current effect if it was Player otherwise NULL
908 Player* GetHitPlayer() const;
909 // returns: target of current effect if it was Item otherwise NULL
910 Item* GetHitItem() const;
911 // returns: target of current effect if it was GameObject otherwise NULL
912 GameObject* GetHitGObj() const;
913 // returns: target of current effect if it was Corpse otherwise nullptr
914 Corpse* GetHitCorpse() const;
915 // returns: destination of current effect
916 WorldLocation* GetHitDest() const;
917 // setter/getter for for damage done by spell to target of spell hit
918 // returns damage calculated before hit, and real dmg done after hit
919 int32 GetHitDamage() const;
920 void SetHitDamage(int32 damage);
921 void PreventHitDamage() { SetHitDamage(0); }
922 // setter/getter for for heal done by spell to target of spell hit
923 // returns healing calculated before hit, and real dmg done after hit
924 int32 GetHitHeal() const;
925 void SetHitHeal(int32 heal);
926 void PreventHitHeal() { SetHitHeal(0); }
927 // returns: true if spell critically hits current HitUnit
928 bool IsHitCrit() const;
929 Spell* GetSpell() const { return m_spell; }
930 // returns current spell hit target aura
931 Aura* GetHitAura(bool dynObjAura = false, bool withRemoved = false) const;
932 // prevents applying aura on current spell hit target
933 void PreventHitAura();
934
935 // prevents effect execution on current spell hit target
936 // including other effect/hit scripts
937 // will not work on aura/damage/heal
938 // will not work if effects were already handled
939 void PreventHitEffect(SpellEffIndex effIndex);
940
941 // prevents default effect execution on current spell hit target
942 // will not work on aura/damage/heal effects
943 // will not work if effects were already handled
944 void PreventHitDefaultEffect(SpellEffIndex effIndex);
945
946 // method available only in EffectHandler method
947 SpellEffectInfo const& GetEffectInfo() const;
948 int32 GetEffectValueAsInt() const;
949 SpellEffectValue GetEffectValue() const;
950 void SetEffectValue(SpellEffectValue value);
951 float GetEffectVariance() const;
952 void SetEffectVariance(float variance);
953
954 // returns: cast item if present.
955 Item* GetCastItem() const;
956
957 // Creates item. Calls Spell::DoCreateItem method.
958 void CreateItem(uint32 itemId, ItemContext context);
959
960 // Returns SpellInfo from the spell that triggered the current one
961 SpellInfo const* GetTriggeringSpell() const;
962
963 // finishes spellcast prematurely with selected error message
964 void FinishCast(SpellCastResult result, int32* param1 = nullptr, int32* param2 = nullptr);
965
966 void SetCustomCastResultMessage(SpellCustomErrors result);
967
968 // returns desired cast difficulty for triggered spells
969 Difficulty GetCastDifficulty() const;
970};
971
972// AuraScript interface - enum used for runtime checks of script function calls
1007/*
1008#define HOOK_AURA_EFFECT_START HOOK_AURA_EFFECT_APPLY
1009#define HOOK_AURA_EFFECT_END HOOK_AURA_EFFECT_CALC_SPELLMOD + 1
1010#define HOOK_AURA_EFFECT_COUNT HOOK_AURA_EFFECT_END - HOOK_AURA_EFFECT_START
1011*/
1013{
1014 // internal use classes & functions
1015 // DO NOT OVERRIDE THESE IN SCRIPTS
1016 template <typename Ret, typename... Args>
1018
1019public:
1021 {
1022 public:
1024
1025 template<typename ScriptFunc>
1026 explicit CheckAreaTargetHandler(ScriptFunc handler)
1027 {
1028 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1029
1030 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
1031 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
1032
1033 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
1034 static_assert(std::is_invocable_r_v<bool, ScriptFunc, ScriptClass&, Unit*>,
1035 R""(CheckAreaTargetHandler signature must be "bool CheckTarget(Unit* target)")"");
1036 else
1037 static_assert(std::is_invocable_r_v<bool, ScriptFunc, ScriptClass&, Unit*>,
1038 R""(CheckAreaTargetHandler signature must be "static bool CheckTarget(your_script_class& script, Unit* target)")"");
1039
1040 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
1042 }
1043
1044 bool Call(AuraScript* auraScript, Unit* target) const
1045 {
1046 return _invoker.Thunk(*auraScript, target, _invoker.ImplStorage);
1047 }
1048 private:
1050 };
1051
1053 {
1054 public:
1056
1057 template<typename ScriptFunc>
1058 explicit AuraDispelHandler(ScriptFunc handler)
1059 {
1060 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1061
1062 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
1063 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
1064
1065 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
1066 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, DispelInfo*>,
1067 R""(AuraDispelHandler signature must be "void HandleDispel(DispelInfo* dispelInfo)")"");
1068 else
1069 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, DispelInfo*>,
1070 R""(AuraDispelHandler signature must be "static void HandleDispel(your_script_class& script, DispelInfo* dispelInfo)")"");
1071
1072 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
1074 }
1075
1076 void Call(AuraScript* auraScript, DispelInfo* dispelInfo) const
1077 {
1078 return _invoker.Thunk(*auraScript, dispelInfo, _invoker.ImplStorage);
1079 }
1080 private:
1082 };
1083
1085 {
1086 public:
1088
1089 template<typename ScriptFunc>
1090 explicit AuraHeartbeatHandler(ScriptFunc handler)
1091 {
1092 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1093
1094 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
1095 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
1096
1097 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
1098 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass>,
1099 R""(AuraHeartbeatHandler signature must be "void HandleHeartbeat()")"");
1100 else
1101 static_assert(std::is_invocable_r_v<void, ScriptFunc>,
1102 R""(AuraHeartbeatHandler signature must be "static void HandleHeartbeat(your_script_class& script)")"");
1103
1104 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
1106 }
1107
1108 void Call(AuraScript* auraScript) const
1109 {
1110 return _invoker.Thunk(*auraScript, _invoker.ImplStorage);
1111 }
1112 private:
1114 };
1115
1117 {
1118 public:
1119 EffectBase(uint8 effIndex, uint16 auraType);
1120 EffectBase(EffectBase const& right) = delete;
1121 EffectBase(EffectBase&& right) noexcept;
1122 EffectBase& operator=(EffectBase const& right) = delete;
1123 EffectBase& operator=(EffectBase&& right) noexcept;
1124 virtual ~EffectBase();
1125 std::string ToString() const;
1126 bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex) const override;
1127 private:
1129 };
1130
1132 {
1133 public:
1135
1136 template<typename ScriptFunc>
1137 explicit EffectPeriodicHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1138 : EffectBase(effIndex, auraType)
1139 {
1140 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1141
1142 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
1143 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
1144
1145 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
1146 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect const*>,
1147 R""(EffectPeriodicHandler signature must be "void HandlePeriodic(AuraEffect const* aurEff)")"");
1148 else
1149 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect const*>,
1150 R""(EffectPeriodicHandler signature must be "static void HandlePeriodic(your_script_class& script, AuraEffect const* aurEff)")"");
1151
1152 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
1154 }
1155
1156 void Call(AuraScript* auraScript, AuraEffect const* aurEff) const
1157 {
1158 return _invoker.Thunk(*auraScript, aurEff, _invoker.ImplStorage);
1159 }
1160 private:
1162 };
1163
1165 {
1166 public:
1168
1169 template<typename ScriptFunc>
1170 explicit EffectUpdatePeriodicHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1171 : EffectBase(effIndex, auraType)
1172 {
1173 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1174
1175 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
1176 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
1177
1178 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
1179 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect*>,
1180 R""(EffectUpdatePeriodicHandler signature must be "void HandleUpdatePeriodic(AuraEffect* aurEff)")"");
1181 else
1182 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect*>,
1183 R""(EffectUpdatePeriodicHandler signature must be "static void HandleUpdatePeriodic(your_script_class& script, AuraEffect* aurEff)")"");
1184
1185 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
1187 }
1188
1189 void Call(AuraScript* auraScript, AuraEffect* aurEff) const
1190 {
1191 return _invoker.Thunk(*auraScript, aurEff, _invoker.ImplStorage);
1192 }
1193 private:
1195 };
1196
1198 {
1199 public:
1201
1202 template<typename ScriptFunc>
1203 explicit EffectCalcAmountHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1204 : EffectBase(effIndex, auraType)
1205 {
1206 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1207
1208 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
1209 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
1210
1211 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
1212 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect const*, SpellEffectValue&, bool&>,
1213 R""(EffectCalcAmountHandler signature must be "void CalcAmount(AuraEffect const* aurEff, SpellEffectValue& amount, bool& canBeRecalculated)")"");
1214 else
1215 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect const*, SpellEffectValue&, bool&>,
1216 R""(EffectCalcAmountHandler signature must be "static void CalcAmount(your_script_class& script, AuraEffect const* aurEff, SpellEffectValue& amount, bool& canBeRecalculated)")"");
1217
1218 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
1220 }
1221
1222 void Call(AuraScript* auraScript, AuraEffect const* aurEff, SpellEffectValue& amount, bool& canBeRecalculated) const
1223 {
1224 return _invoker.Thunk(*auraScript, aurEff, amount, canBeRecalculated, _invoker.ImplStorage);
1225 }
1226 private:
1228 };
1229
1231 {
1232 public:
1234
1235 template<typename ScriptFunc>
1236 explicit EffectCalcPeriodicHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1237 : EffectBase(effIndex, auraType)
1238 {
1239 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1240
1241 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
1242 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
1243
1244 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
1245 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect const*, bool&, int32&>,
1246 R""(EffectCalcPeriodicHandler signature must be "void CalcPeriodic(AuraEffect const* aurEff, bool& isPeriodic, int32& periodicTimer)")"");
1247 else
1248 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect const*, bool&, int32&>,
1249 R""(EffectCalcPeriodicHandler signature must be "static void CalcPeriodic(your_script_class& script, AuraEffect const* aurEff, bool& isPeriodic, int32& periodicTimer)")"");
1250
1251 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
1253 }
1254
1255 void Call(AuraScript* auraScript, AuraEffect const* aurEff, bool& isPeriodic, int32& periodicTimer) const
1256 {
1257 return _invoker.Thunk(*auraScript, aurEff, isPeriodic, periodicTimer, _invoker.ImplStorage);
1258 }
1259 private:
1261 };
1262
1264 {
1265 public:
1267
1268 template<typename ScriptFunc>
1269 explicit EffectCalcSpellModHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1270 : EffectBase(effIndex, auraType)
1271 {
1272 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1273
1274 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
1275 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
1276
1277 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
1278 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect const*, SpellModifier*&>,
1279 R""(EffectCalcSpellModHandler signature must be "void CalcSpellMod(AuraEffect const* aurEff, SpellModifier*& spellMod)")"");
1280 else
1281 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect const*, SpellModifier*&>,
1282 R""(EffectCalcSpellModHandler signature must be "static void CalcSpellMod(your_script_class& script, AuraEffect const* aurEff, SpellModifier*& spellMod)")"");
1283
1284 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
1286 }
1287
1288 void Call(AuraScript* auraScript, AuraEffect const* aurEff, SpellModifier*& spellMod) const
1289 {
1290 return _invoker.Thunk(*auraScript, aurEff, spellMod, _invoker.ImplStorage);
1291 }
1292 private:
1294 };
1295
1297 {
1298 public:
1300
1301 template<typename ScriptFunc>
1302 explicit EffectCalcCritChanceHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1303 : EffectBase(effIndex, auraType)
1304 {
1305 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1306
1307 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
1308 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
1309
1310 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
1311 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect const*, Unit const*, float&>,
1312 R""(EffectCalcCritChanceHandler signature must be "void CalcCritChance(AuraEffect const* aurEff, Unit const* victim, float& critChance)")"");
1313 else
1314 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect const*, Unit const*, float&>,
1315 R""(EffectCalcCritChanceHandler signature must be "static void CalcCritChance(your_script_class& script, AuraEffect const* aurEff, Unit const* victim, float& critChance)")"");
1316
1317 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
1319 }
1320
1321 void Call(AuraScript* auraScript, AuraEffect const* aurEff, Unit const* victim, float& critChance) const
1322 {
1323 return _invoker.Thunk(*auraScript, aurEff, victim, critChance, _invoker.ImplStorage);
1324 }
1325 private:
1327 };
1328
1330 {
1331 public:
1333
1334 template<typename ScriptFunc>
1335 explicit EffectCalcDamageAndHealingHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1336 : EffectBase(effIndex, auraType)
1337 {
1338 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1339
1340 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
1341 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
1342
1343 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
1344 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect const*, Unit*, int32&, int32&, float&>,
1345 R""(EffectCalcDamageAndHealingHandler signature must be "void CalcDamageAndHealing(AuraEffect const* aurEff, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod)")"");
1346 else
1347 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect const*, Unit*, int32&, int32&, float&>,
1348 R""(EffectCalcDamageAndHealingHandler signature must be "static void CalcDamageAndHealing(your_script_class& script, AuraEffect const* aurEff, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod)")"");
1349
1350 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
1352 }
1353
1354 void Call(AuraScript* auraScript, AuraEffect const* aurEff, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod) const
1355 {
1356 return _invoker.Thunk(*auraScript, aurEff, victim, damageOrHealing, flatMod, pctMod, _invoker.ImplStorage);
1357 }
1358 private:
1360 };
1361
1362 class EffectApplyHandler final : public EffectBase
1363 {
1364 public:
1366
1367 template<typename ScriptFunc>
1368 explicit EffectApplyHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType, AuraEffectHandleModes mode)
1369 : EffectBase(effIndex, auraType), _mode(mode)
1370 {
1371 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1372
1373 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
1374 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
1375
1376 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
1377 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect const*, AuraEffectHandleModes>,
1378 R""(EffectApplyHandler signature must be "void HandleApplyOrRemove(AuraEffect const* aurEff, AuraEffectHandleModes mode)")"");
1379 else
1380 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect const*, AuraEffectHandleModes>,
1381 R""(EffectApplyHandler signature must be "static void HandleApplyOrRemove(your_script_class& script, AuraEffect const* aurEff, AuraEffectHandleModes mode)")"");
1382
1383 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
1385 }
1386
1387 void Call(AuraScript* auraScript, AuraEffect const* aurEff, AuraEffectHandleModes mode) const
1388 {
1389 if (!(_mode & mode))
1390 return;
1391
1392 return _invoker.Thunk(*auraScript, aurEff, mode, _invoker.ImplStorage);
1393 }
1394 private:
1397 };
1398
1399 class EffectAbsorbHandler final : public EffectBase
1400 {
1401 public:
1403
1404 template<typename ScriptFunc>
1405 explicit EffectAbsorbHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1406 : EffectBase(effIndex, auraType)
1407 {
1408 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1409
1410 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
1411 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
1412
1413 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
1414 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect*, DamageInfo&, uint32&>,
1415 R""(EffectAbsorbHandler signature must be "void HandleAbsorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount)")"");
1416 else
1417 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect*, DamageInfo&, uint32&>,
1418 R""(EffectAbsorbHandler signature must be "static void HandleAbsorb(your_script_class& script, AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount)")"");
1419
1420 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
1422 }
1423
1424 void Call(AuraScript* auraScript, AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount) const
1425 {
1426 return _invoker.Thunk(*auraScript, aurEff, dmgInfo, absorbAmount, _invoker.ImplStorage);
1427 }
1428 private:
1430 };
1431
1433 {
1434 public:
1436
1437 template<typename ScriptFunc>
1438 explicit EffectAbsorbHealHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1439 : EffectBase(effIndex, auraType)
1440 {
1441 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1442
1443 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
1444 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
1445
1446 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
1447 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect*, HealInfo&, uint32&>,
1448 R""(EffectAbsorbHealHandler signature must be "void HandleAbsorb(AuraEffect* aurEff, HealInfo& healInfo, uint32& absorbAmount)")"");
1449 else
1450 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect*, HealInfo&, uint32&>,
1451 R""(EffectAbsorbHealHandler signature must be "static void HandleAbsorb(your_script_class& script, AuraEffect* aurEff, HealInfo& healInfo, uint32& absorbAmount)")"");
1452
1453 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
1455 }
1456
1457 void Call(AuraScript* auraScript, AuraEffect* aurEff, HealInfo& healInfo, uint32& absorbAmount) const
1458 {
1459 return _invoker.Thunk(*auraScript, aurEff, healInfo, absorbAmount, _invoker.ImplStorage);
1460 }
1461 private:
1463 };
1464
1466 {
1467 public:
1469
1470 template<typename ScriptFunc>
1471 explicit CheckProcHandler(ScriptFunc handler)
1472 {
1473 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1474
1475 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
1476 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
1477
1478 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
1479 static_assert(std::is_invocable_r_v<bool, ScriptFunc, ScriptClass&, ProcEventInfo&>,
1480 R""(CheckProcHandler signature must be "bool CheckProc(ProcEventInfo& eventInfo)")"");
1481 else
1482 static_assert(std::is_invocable_r_v<bool, ScriptFunc, ScriptClass&, ProcEventInfo&>,
1483 R""(CheckProcHandler signature must be "static bool CheckProc(your_script_class& script, ProcEventInfo& eventInfo)")"");
1484
1485 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
1487 }
1488
1489 bool Call(AuraScript* auraScript, ProcEventInfo& eventInfo) const
1490 {
1491 return _invoker.Thunk(*auraScript, eventInfo, _invoker.ImplStorage);
1492 }
1493 private:
1495 };
1496
1498 {
1499 public:
1501
1502 template<typename ScriptFunc>
1503 explicit CheckEffectProcHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1504 : EffectBase(effIndex, auraType)
1505 {
1506 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1507
1508 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
1509 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
1510
1511 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
1512 static_assert(std::is_invocable_r_v<bool, ScriptFunc, ScriptClass&, AuraEffect const*, ProcEventInfo&>,
1513 R""(CheckEffectProcHandler signature must be "bool CheckProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)")"");
1514 else
1515 static_assert(std::is_invocable_r_v<bool, ScriptFunc, ScriptClass&, AuraEffect const*, ProcEventInfo&>,
1516 R""(CheckEffectProcHandler signature must be "static bool CheckProc(your_script_class& script, AuraEffect const* aurEff, ProcEventInfo& eventInfo)")"");
1517
1518 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
1520 }
1521
1522 bool Call(AuraScript* auraScript, AuraEffect const* aurEff, ProcEventInfo& eventInfo) const
1523 {
1524 return _invoker.Thunk(*auraScript, aurEff, eventInfo, _invoker.ImplStorage);
1525 }
1526 private:
1528 };
1529
1531 {
1532 public:
1534
1535 template<typename ScriptFunc>
1536 explicit AuraProcHandler(ScriptFunc handler)
1537 {
1538 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1539
1540 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
1541 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
1542
1543 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
1544 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, ProcEventInfo&>,
1545 R""(AuraProcHandler signature must be "void HandleProc(ProcEventInfo& eventInfo)")"");
1546 else
1547 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, ProcEventInfo&>,
1548 R""(AuraProcHandler signature must be "static void HandleProc(your_script_class& script, ProcEventInfo& eventInfo)")"");
1549
1550 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
1552 }
1553
1554 void Call(AuraScript* auraScript, ProcEventInfo& eventInfo) const
1555 {
1556 return _invoker.Thunk(*auraScript, eventInfo, _invoker.ImplStorage);
1557 }
1558 private:
1560 };
1561
1562 class EffectProcHandler final : public EffectBase
1563 {
1564 public:
1566
1567 template<typename ScriptFunc>
1568 explicit EffectProcHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1569 : EffectBase(effIndex, auraType)
1570 {
1571 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1572
1573 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
1574 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
1575
1576 if constexpr (std::is_member_function_pointer_v<ScriptFunc>)
1577 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect*, ProcEventInfo&>,
1578 R""(EffectProcHandler signature must be "void HandleProc(AuraEffect* aurEff, ProcEventInfo& eventInfo)")"");
1579 else
1580 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass&, AuraEffect*, ProcEventInfo&>,
1581 R""(EffectProcHandler signature must be "static void HandleProc(your_script_class& script, AuraEffect* aurEff, ProcEventInfo& eventInfo)")"");
1582
1583 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
1585 }
1586
1587 void Call(AuraScript* auraScript, AuraEffect* aurEff, ProcEventInfo& eventInfo) const
1588 {
1589 return _invoker.Thunk(*auraScript, aurEff, eventInfo, _invoker.ImplStorage);
1590 }
1591 private:
1593 };
1594
1596 {
1597 public:
1599
1600 template<typename ScriptFunc>
1601 explicit EnterLeaveCombatHandler(ScriptFunc handler)
1602 {
1603 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1604
1605 static_assert(ScriptFuncInvoker::Size >= sizeof(ScriptFunc));
1606 static_assert(ScriptFuncInvoker::Alignment >= alignof(ScriptFunc));
1607
1608 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, bool>,
1609 R""(EnterLeaveCombatHandler signature must be "void HandleEnterLeaveCombat(bool isNowInCombat)")"");
1610
1611 new (_invoker.ImplStorage.data()) ScriptFuncInvoker::Impl<ScriptFunc>{ .Func = handler };
1613 }
1614
1615 void Call(AuraScript* auraScript, bool isNowInCombat) const
1616 {
1617 return _invoker.Thunk(*auraScript, isNowInCombat, _invoker.ImplStorage);
1618 }
1619 private:
1621 };
1622
1623 // left for custom compatibility only, DO NOT USE
1624 #define PrepareAuraScript(CLASSNAME)
1625
1626public:
1627 AuraScript() noexcept;
1629 bool _Validate(SpellInfo const* entry) override;
1630 bool _Load(Aura* aura);
1631 void _PrepareScriptCall(AuraScriptHookType hookType, AuraApplication const* aurApp = nullptr);
1632 void _FinishScriptCall();
1633 bool _IsDefaultActionPrevented() const;
1634private:
1635 Aura* m_aura;
1636 AuraApplication const* m_auraApplication;
1637 bool m_defaultActionPrevented;
1638
1640 {
1641 public:
1645 ScriptStateStore(uint8 currentScriptState, AuraApplication const* auraApplication, bool defaultActionPrevented)
1646 : _auraApplication(auraApplication), _currentScriptState(currentScriptState), _defaultActionPrevented(defaultActionPrevented)
1647 { }
1648 };
1649 typedef std::stack<ScriptStateStore> ScriptStateStack;
1651
1652public:
1653 //
1654 // AuraScript interface
1655 // hooks to which you can attach your functions
1656 //
1657 // executed when area aura checks if it can be applied on target
1658 // example: OnEffectApply += AuraEffectApplyFn(class::function);
1659 // where function is: bool function(Unit* target);
1661 #define AuraCheckAreaTargetFn(F) CheckAreaTargetHandler(&F)
1662
1663 // executed when aura is dispelled by a unit
1664 // example: OnDispel += AuraDispelFn(class::function);
1665 // where function is: void function(DispelInfo* dispelInfo);
1667 // executed after aura is dispelled by a unit
1668 // example: AfterDispel += AuraDispelFn(class::function);
1669 // where function is: void function(DispelInfo* dispelInfo);
1671 #define AuraDispelFn(F) AuraDispelHandler(&F)
1672
1673 // executed on every heartbeat of a unit
1674 // example: OnHeartbeat += AuraHeartbeatFn(class::function);
1675 // where function is: void function();
1677 #define AuraHeartbeatFn(F) AuraHeartbeatHandler(&F)
1678
1679 // executed when aura effect is applied with specified mode to target
1680 // should be used when when effect handler preventing/replacing is needed, do not use this hook for triggering spellcasts/removing auras etc - may be unsafe
1681 // example: OnEffectApply += AuraEffectApplyFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
1682 // where function is: void function(AuraEffect const* aurEff, AuraEffectHandleModes mode);
1684 // executed after aura effect is applied with specified mode to target
1685 // example: AfterEffectApply += AuraEffectApplyFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
1686 // where function is: void function(AuraEffect const* aurEff, AuraEffectHandleModes mode);
1688 #define AuraEffectApplyFn(F, I, N, M) EffectApplyHandler(&F, I, N, M)
1689
1690 // executed after aura effect is removed with specified mode from target
1691 // should be used when effect handler preventing/replacing is needed, do not use this hook for triggering spellcasts/removing auras etc - may be unsafe
1692 // example: OnEffectRemove += AuraEffectRemoveFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
1693 // where function is: void function(AuraEffect const* aurEff, AuraEffectHandleModes mode);
1695 // executed when aura effect is removed with specified mode from target
1696 // example: AfterEffectRemove += AuraEffectRemoveFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
1697 // where function is: void function(AuraEffect const* aurEff, AuraEffectHandleModes mode);
1699 #define AuraEffectRemoveFn(F, I, N, M) EffectApplyHandler(&F, I, N, M)
1700
1701 // executed when periodic aura effect ticks on target
1702 // example: OnEffectPeriodic += AuraEffectPeriodicFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
1703 // where function is: void function(AuraEffect const* aurEff);
1705 #define AuraEffectPeriodicFn(F, I, N) EffectPeriodicHandler(&F, I, N)
1706
1707 // executed when periodic aura effect is updated
1708 // example: OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
1709 // where function is: void function(AuraEffect* aurEff);
1711 #define AuraEffectUpdatePeriodicFn(F, I, N) EffectUpdatePeriodicHandler(&F, I, N)
1712
1713 // executed when aura effect calculates amount
1714 // example: DoEffectCalcAmount += AuraEffectCalcAmounFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
1715 // where function is: void function(AuraEffect* aurEff, int32& amount, bool& canBeRecalculated);
1717 #define AuraEffectCalcAmountFn(F, I, N) EffectCalcAmountHandler(&F, I, N)
1718
1719 // executed when aura effect calculates periodic data
1720 // example: DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
1721 // where function is: void function(AuraEffect const* aurEff, bool& isPeriodic, int32& amplitude);
1723 #define AuraEffectCalcPeriodicFn(F, I, N) EffectCalcPeriodicHandler(&F, I, N)
1724
1725 // executed when aura effect calculates spellmod
1726 // example: DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
1727 // where function is: void function(AuraEffect const* aurEff, SpellModifier*& spellMod);
1729 #define AuraEffectCalcSpellModFn(F, I, N) EffectCalcSpellModHandler(&F, I, N)
1730
1731 // executed when aura effect calculates crit chance for dots and hots
1732 // example: DoEffectCalcCritChance += AuraEffectCalcCritChanceFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
1733 // where function is: void function(AuraEffect const* aurEff, Unit* victim, float& critChance);
1735 #define AuraEffectCalcCritChanceFn(F, I, N) EffectCalcCritChanceHandler(&F, I, N)
1736
1737 // executed when aura effect calculates damage or healing for dots and hots or initial absorb aura amount calculation
1738 // example: DoEffectCalcDamageAndHealing += AuraEffectCalcDamageFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
1739 // example: DoEffectCalcDamageAndHealing += AuraEffectCalcHealingFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
1740 // where function is: void function(AuraEffect const* aurEff, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod);
1742 #define AuraEffectCalcDamageFn(F, I, N) EffectCalcDamageAndHealingHandler(&F, I, N)
1743 #define AuraEffectCalcHealingFn(F, I, N) EffectCalcDamageAndHealingHandler(&F, I, N)
1744 #define AuraEffectCalcAbsorbFn(F, I) EffectCalcDamageAndHealingHandler(&F, I, SPELL_AURA_SCHOOL_ABSORB)
1745
1746 // executed when absorb aura effect is going to reduce damage
1747 // example: OnEffectAbsorb += AuraEffectAbsorbFn(class::function, EffectIndexSpecifier);
1748 // where function is: void function(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount);
1750 #define AuraEffectAbsorbFn(F, I) EffectAbsorbHandler(&F, I, SPELL_AURA_SCHOOL_ABSORB)
1751 #define AuraEffectAbsorbOverkillFn(F, I) EffectAbsorbHandler(&F, I, SPELL_AURA_SCHOOL_ABSORB_OVERKILL)
1752
1753 // executed after absorb aura effect reduced damage to target - absorbAmount is real amount absorbed by aura
1754 // example: AfterEffectAbsorb += AuraEffectAbsorbFn(class::function, EffectIndexSpecifier);
1755 // where function is: void function(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount);
1757
1758 // executed when absorb aura effect is going to reduce damage
1759 // example: OnEffectAbsorbHeal += AuraEffectAbsorbHealFn(class::function, EffectIndexSpecifier);
1760 // where function is: void function(AuraEffect const* aurEff, HealInfo& healInfo, uint32& absorbAmount);
1762 #define AuraEffectAbsorbHealFn(F, I) EffectAbsorbHealHandler(&F, I, SPELL_AURA_SCHOOL_HEAL_ABSORB)
1763
1764 // executed after absorb aura effect reduced heal to target - absorbAmount is real amount absorbed by aura
1765 // example: AfterEffectAbsorbHeal += AuraEffectAbsorbHealFn(class::function, EffectIndexSpecifier);
1766 // where function is: void function(AuraEffect* aurEff, HealInfo& healInfo, uint32& absorbAmount);
1768
1769 // executed when mana shield aura effect is going to reduce damage
1770 // example: OnEffectManaShield += AuraEffectManaShieldFn(class::function, EffectIndexSpecifier);
1771 // where function is: void function (AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount);
1773 #define AuraEffectManaShieldFn(F, I) EffectAbsorbHandler(&F, I, SPELL_AURA_MANA_SHIELD)
1774
1775 // executed after mana shield aura effect reduced damage to target - absorbAmount is real amount absorbed by aura
1776 // example: AfterEffectManaShield += AuraEffectManaShieldFn(class::function, EffectIndexSpecifier);
1777 // where function is: void function(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount);
1779
1780 // executed when the caster of some spell with split dmg aura gets damaged through it
1781 // example: OnEffectSplit += AuraEffectSplitFn(class::function, EffectIndexSpecifier);
1782 // where function is: void function(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& splitAmount);
1784 #define AuraEffectSplitFn(F, I) EffectAbsorbHandler(&F, I, SPELL_AURA_SPLIT_DAMAGE_PCT)
1785
1786 // executed when aura checks if it can proc
1787 // example: DoCheckProc += AuraCheckProcFn(class::function);
1788 // where function is: bool function(ProcEventInfo& eventInfo);
1790 #define AuraCheckProcFn(F) CheckProcHandler(&F)
1791
1792 // executed when aura effect checks if it can proc the aura
1793 // example: DoCheckEffectProc += AuraCheckEffectProcFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
1794 // where function is bool function(AuraEffect const* aurEff, ProcEventInfo& eventInfo);
1796 #define AuraCheckEffectProcFn(F, I, N) CheckEffectProcHandler(&F, I, N)
1797
1798 // executed before aura procs (possibility to prevent charge drop/cooldown)
1799 // example: DoPrepareProc += AuraProcFn(class::function);
1800 // where function is: void function(ProcEventInfo& eventInfo);
1802 // executed when aura procs
1803 // example: OnProc += AuraProcFn(class::function);
1804 // where function is: void function(ProcEventInfo& eventInfo);
1806 // executed after aura proced
1807 // example: AfterProc += AuraProcFn(class::function);
1808 // where function is: void function(ProcEventInfo& eventInfo);
1810 #define AuraProcFn(F) AuraProcHandler(&F)
1811
1812 // executed when aura effect procs
1813 // example: OnEffectProc += AuraEffectProcFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
1814 // where function is: void function(AuraEffect* aurEff, ProcEventInfo& procInfo);
1816 // executed after aura effect proced
1817 // example: AfterEffectProc += AuraEffectProcFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
1818 // where function is: void function(AuraEffect* aurEff, ProcEventInfo& procInfo);
1820 #define AuraEffectProcFn(F, I, N) EffectProcHandler(&F, I, N)
1821
1822 // executed when target enters or leaves combat
1823 // example: OnEnterLeaveCombat += AuraEnterLeaveCombatFn(class::function)
1824 // where function is: void function (bool isNowInCombat);
1826 #define AuraEnterLeaveCombatFn(F) EnterLeaveCombatHandler(&F)
1827
1828 // AuraScript interface - hook/effect execution manipulators
1829
1830 // prevents default action of a hook from being executed (works only while called in a hook which default action can be prevented)
1831 void PreventDefaultAction();
1832
1833 // AuraScript interface - functions which are redirecting to Aura class
1834
1835 // returns proto of the spell
1836 SpellInfo const* GetSpellInfo() const;
1837 SpellEffectInfo const& GetEffectInfo(SpellEffIndex effIndex) const;
1838 // returns spellid of the spell
1839 uint32 GetId() const;
1840
1841 // returns guid of object which cast the aura (m_originalCaster of the Spell class)
1842 ObjectGuid GetCasterGUID() const;
1843 // returns unit which cast the aura or NULL if not avalible (caster logged out for example)
1844 Unit* GetCaster() const;
1845 // returns gameobject which cast the aura or NULL if not available
1846 GameObject* GetGObjCaster() const;
1847 // returns object on which aura was cast, target for non-area auras, area aura source for area auras
1848 WorldObject* GetOwner() const;
1849 // returns owner if it's unit or unit derived object, NULL otherwise (only for persistent area auras NULL is returned)
1850 Unit* GetUnitOwner() const;
1851 // returns owner if it's dynobj, NULL otherwise
1852 DynamicObject* GetDynobjOwner() const;
1853
1854 // removes aura with remove mode (see AuraRemoveMode enum)
1855 void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
1856 // returns aura object of script
1857 Aura* GetAura() const;
1858
1859 // returns type of the aura, may be dynobj owned aura or unit owned aura
1860 AuraObjectType GetType() const;
1861
1862 // aura duration manipulation - when duration goes to 0 aura is removed
1863 int32 GetDuration() const;
1864 void SetDuration(int32 duration, bool withMods = false);
1865 // sets duration to maxduration
1866 void RefreshDuration();
1867 time_t GetApplyTime() const;
1868 int32 GetMaxDuration() const;
1869 void SetMaxDuration(int32 duration);
1870 int32 CalcMaxDuration() const;
1871 // expired - duration just went to 0
1872 bool IsExpired() const;
1873 // permament - has infinite duration
1874 bool IsPermanent() const;
1875
1876 // charges manipulation - 0 - not charged aura
1877 uint8 GetCharges() const;
1878 void SetCharges(uint8 charges);
1879 uint8 CalcMaxCharges() const;
1880 bool ModCharges(int8 num, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
1881 // returns true if last charge dropped
1882 bool DropCharge(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
1883
1884 // stack amount manipulation
1885 uint8 GetStackAmount() const;
1886 void SetStackAmount(uint8 num);
1887 bool ModStackAmount(int32 num, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
1888
1889 // passive - "working in background", not saved, not removed by immunities, not seen by player
1890 bool IsPassive() const;
1891 // death persistent - not removed on death
1892 bool IsDeathPersistent() const;
1893
1894 // check if aura has effect of given effindex
1895 bool HasEffect(uint8 effIndex) const;
1896 // returns aura effect of given effect index or NULL
1897 AuraEffect* GetEffect(uint8 effIndex) const;
1898
1899 // check if aura has effect of given aura type
1900 bool HasEffectType(AuraType type) const;
1901
1902 // AuraScript interface - functions which are redirecting to AuraApplication class
1903 // Do not call these in hooks in which AuraApplication is not avalible, otherwise result will differ from expected (the functions will return NULL)
1904
1905 // returns currently processed target of an aura
1906 // Return value does not need to be NULL-checked, the only situation this will (always)
1907 // return NULL is when the call happens in an unsupported hook, in other cases, it is always valid
1908 Unit* GetTarget() const;
1909 // returns AuraApplication object of currently processed target
1910 AuraApplication const* GetTargetApplication() const;
1911
1912 // returns desired cast difficulty for triggered spells
1913 Difficulty GetCastDifficulty() const;
1914};
1915
1916//
1917// definitions:
1918//
1919// EffectIndexSpecifier - specifies conditions for effects
1920// EFFECT_0 - first effect matches
1921// EFFECT_1 - second effect matches
1922// EFFECT_2 - third effect matches
1923// EFFECT_FIRST_FOUND - first effect matching other conditions matches
1924// EFFECT_ALL - all effects of spell match
1925//
1926// EffectNameSpecifier - specifies conditions for spell effect names
1927// SPELL_EFFECT_ANY - any effect but not 0 matches condition
1928// SPELL_EFFECT_XXX - one of values of enum SpellEffects - effect with equal name matches
1929//
1930
1931#endif // TRINITY_SPELL_SCRIPT_H
ItemContext
Definition DBCEnums.h:1324
Difficulty
Definition DBCEnums.h:935
#define TC_GAME_API
Definition Define.h:129
uint8_t uint8
Definition Define.h:156
int64_t int64
Definition Define.h:149
int16_t int16
Definition Define.h:151
int8_t int8
Definition Define.h:152
int32_t int32
Definition Define.h:150
uint16_t uint16
Definition Define.h:155
uint32_t uint32
Definition Define.h:154
SpellEffIndex
SpellMissInfo
SpellCustomErrors
SpellCastResult
AuraEffectHandleModes
AuraRemoveMode
@ AURA_REMOVE_BY_DEFAULT
AuraObjectType
double SpellEffectValue
This is a double instead of float to be able to store full range of int32.
AuraScriptHookType
@ AURA_SCRIPT_HOOK_EFFECT_CALC_PERIODIC
@ AURA_SCRIPT_HOOK_CHECK_EFFECT_PROC
@ AURA_SCRIPT_HOOK_EFFECT_CALC_DAMAGE_AND_HEALING
@ AURA_SCRIPT_HOOK_EFFECT_CALC_AMOUNT
@ AURA_SCRIPT_HOOK_EFFECT_REMOVE
@ AURA_SCRIPT_HOOK_EFFECT_CALC_CRIT_CHANCE
@ AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD
@ AURA_SCRIPT_HOOK_PREPARE_PROC
@ AURA_SCRIPT_HOOK_ON_HEARTBEAT
@ AURA_SCRIPT_HOOK_EFFECT_AFTER_APPLY
@ AURA_SCRIPT_HOOK_EFFECT_AFTER_REMOVE
@ AURA_SCRIPT_HOOK_AFTER_PROC
@ AURA_SCRIPT_HOOK_CHECK_AREA_TARGET
@ AURA_SCRIPT_HOOK_EFFECT_MANASHIELD
@ AURA_SCRIPT_HOOK_PROC
@ AURA_SCRIPT_HOOK_EFFECT_AFTER_ABSORB
@ AURA_SCRIPT_HOOK_DISPEL
@ AURA_SCRIPT_HOOK_EFFECT_APPLY
@ AURA_SCRIPT_HOOK_EFFECT_PERIODIC
@ AURA_SCRIPT_HOOK_EFFECT_AFTER_PROC
@ AURA_SCRIPT_HOOK_EFFECT_ABSORB
@ AURA_SCRIPT_HOOK_EFFECT_PROC
@ AURA_SCRIPT_HOOK_EFFECT_SPLIT
@ AURA_SCRIPT_HOOK_EFFECT_CALC_SPELLMOD
@ AURA_SCRIPT_HOOK_AFTER_DISPEL
@ AURA_SCRIPT_HOOK_CHECK_PROC
@ AURA_SCRIPT_HOOK_ENTER_LEAVE_COMBAT
@ AURA_SCRIPT_HOOK_EFFECT_UPDATE_PERIODIC
SpellScriptState
Definition SpellScript.h:64
@ SPELL_SCRIPT_STATE_NONE
Definition SpellScript.h:65
@ SPELL_SCRIPT_STATE_LOADING
Definition SpellScript.h:67
@ SPELL_SCRIPT_STATE_UNLOADING
Definition SpellScript.h:68
@ SPELL_SCRIPT_STATE_REGISTRATION
Definition SpellScript.h:66
double SpellEffectValue
Definition SpellScript.h:58
#define SPELL_SCRIPT_STATE_END
Definition SpellScript.h:70
SpellScriptHookType
@ SPELL_SCRIPT_HOOK_AFTER_CAST
@ SPELL_SCRIPT_HOOK_EFFECT_HIT
@ SPELL_SCRIPT_HOOK_AFTER_HIT
@ SPELL_SCRIPT_HOOK_EFFECT_SUCCESSFUL_DISPEL
@ SPELL_SCRIPT_HOOK_CALC_HEALING
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH
@ SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT
@ SPELL_SCRIPT_HOOK_BEFORE_HIT
@ SPELL_SCRIPT_HOOK_CALC_DAMAGE
@ SPELL_SCRIPT_HOOK_CHECK_CAST
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET
@ SPELL_SCRIPT_HOOK_CALC_CAST_TIME
@ SPELL_SCRIPT_HOOK_EMPOWER_STAGE_COMPLETED
@ SPELL_SCRIPT_HOOK_EMPOWER_COMPLETED
@ SPELL_SCRIPT_HOOK_HIT
@ SPELL_SCRIPT_HOOK_BEFORE_CAST
@ SPELL_SCRIPT_HOOK_ON_RESIST_ABSORB_CALCULATION
@ SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT
@ SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT
@ SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET
@ SPELL_SCRIPT_HOOK_CALC_CRIT_CHANCE
@ SPELL_SCRIPT_HOOK_ON_CAST
@ SPELL_SCRIPT_HOOK_ON_PRECAST
AuraDispelHandler(ScriptFunc handler)
void Call(AuraScript *auraScript, DispelInfo *dispelInfo) const
void Call(AuraScript *auraScript) const
AuraHeartbeatHandler(ScriptFunc handler)
AuraProcHandler(ScriptFunc handler)
void Call(AuraScript *auraScript, ProcEventInfo &eventInfo) const
ScriptFuncInvoker _invoker
bool Call(AuraScript *auraScript, Unit *target) const
CheckAreaTargetHandler(ScriptFunc handler)
CheckEffectProcHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
bool Call(AuraScript *auraScript, AuraEffect const *aurEff, ProcEventInfo &eventInfo) const
bool Call(AuraScript *auraScript, ProcEventInfo &eventInfo) const
CheckProcHandler(ScriptFunc handler)
void Call(AuraScript *auraScript, AuraEffect *aurEff, DamageInfo &dmgInfo, uint32 &absorbAmount) const
EffectAbsorbHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
EffectAbsorbHealHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
void Call(AuraScript *auraScript, AuraEffect *aurEff, HealInfo &healInfo, uint32 &absorbAmount) const
void Call(AuraScript *auraScript, AuraEffect const *aurEff, AuraEffectHandleModes mode) const
EffectApplyHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType, AuraEffectHandleModes mode)
AuraEffectHandleModes _mode
EffectBase & operator=(EffectBase const &right)=delete
EffectBase & operator=(EffectBase &&right) noexcept
EffectBase(EffectBase &&right) noexcept
EffectBase(EffectBase const &right)=delete
void Call(AuraScript *auraScript, AuraEffect const *aurEff, SpellEffectValue &amount, bool &canBeRecalculated) const
EffectCalcAmountHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
void Call(AuraScript *auraScript, AuraEffect const *aurEff, Unit const *victim, float &critChance) const
EffectCalcCritChanceHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
EffectCalcDamageAndHealingHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
void Call(AuraScript *auraScript, AuraEffect const *aurEff, Unit *victim, int32 &damageOrHealing, int32 &flatMod, float &pctMod) const
EffectCalcPeriodicHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
void Call(AuraScript *auraScript, AuraEffect const *aurEff, bool &isPeriodic, int32 &periodicTimer) const
EffectCalcSpellModHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
void Call(AuraScript *auraScript, AuraEffect const *aurEff, SpellModifier *&spellMod) const
void Call(AuraScript *auraScript, AuraEffect const *aurEff) const
EffectPeriodicHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
EffectProcHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
void Call(AuraScript *auraScript, AuraEffect *aurEff, ProcEventInfo &eventInfo) const
void Call(AuraScript *auraScript, AuraEffect *aurEff) const
EffectUpdatePeriodicHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
void Call(AuraScript *auraScript, bool isNowInCombat) const
EnterLeaveCombatHandler(ScriptFunc handler)
ScriptStateStore(uint8 currentScriptState, AuraApplication const *auraApplication, bool defaultActionPrevented)
AuraApplication const * _auraApplication
HookList< EffectAbsorbHandler > OnEffectManaShield
HookList< EffectCalcDamageAndHealingHandler > DoEffectCalcDamageAndHealing
HookList< EffectAbsorbHealHandler > OnEffectAbsorbHeal
HookList< EffectCalcPeriodicHandler > DoEffectCalcPeriodic
HookList< AuraHeartbeatHandler > OnHeartbeat
HookList< EffectApplyHandler > AfterEffectRemove
HookList< CheckEffectProcHandler > DoCheckEffectProc
HookList< EffectPeriodicHandler > OnEffectPeriodic
HookList< EffectApplyHandler > AfterEffectApply
HookList< EffectProcHandler > AfterEffectProc
HookList< EffectAbsorbHandler > AfterEffectAbsorb
HookList< EffectCalcAmountHandler > DoEffectCalcAmount
HookList< EffectUpdatePeriodicHandler > OnEffectUpdatePeriodic
HookList< EffectCalcSpellModHandler > DoEffectCalcSpellMod
HookList< EnterLeaveCombatHandler > OnEnterLeaveCombat
HookList< EffectAbsorbHandler > OnEffectAbsorb
std::stack< ScriptStateStore > ScriptStateStack
HookList< EffectCalcCritChanceHandler > DoEffectCalcCritChance
HookList< EffectAbsorbHandler > AfterEffectManaShield
HookList< CheckAreaTargetHandler > DoCheckAreaTarget
HookList< EffectAbsorbHealHandler > AfterEffectAbsorbHeal
HookList< AuraProcHandler > AfterProc
HookList< AuraDispelHandler > OnDispel
HookList< CheckProcHandler > DoCheckProc
HookList< EffectApplyHandler > OnEffectRemove
HookList< AuraDispelHandler > AfterDispel
ScriptStateStack m_scriptStates
HookList< EffectProcHandler > OnEffectProc
HookList< AuraProcHandler > DoPrepareProc
HookList< AuraProcHandler > OnProc
HookList< EffectApplyHandler > OnEffectApply
HookList< EffectAbsorbHandler > OnEffectSplit
Definition Item.h:185
EffectHook & operator=(EffectHook &&right) noexcept
EffectHook(EffectHook const &right)=delete
EffectHook(EffectHook &&right) noexcept
virtual bool CheckEffect(SpellInfo const *spellInfo, uint8 effIndex) const =0
EffectHook & operator=(EffectHook const &right)=delete
SpellScriptBase(SpellScriptBase const &right)=delete
uint32 m_scriptSpellId
uint8 m_currentScriptState
virtual void Register()=0
virtual bool Validate(SpellInfo const *spellInfo)
std::string_view m_scriptName
static bool ValidateSpellEffect(T const &spellEffects)
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
static bool ValidateSpellEffect(std::initializer_list< std::pair< uint32, SpellEffIndex > > effects)
static bool ValidateSpellInfo(T const &spellIds)
static bool ValidateSpellEffectsImpl(Iterator begin, Iterator end)
static bool ValidateSpellInfoImpl(Iterator begin, Iterator end)
typename GetScriptClass< ScriptFunc >::type GetScriptClass_t
virtual bool Load()
SpellScriptBase & operator=(SpellScriptBase &&right)=delete
SpellScriptBase(SpellScriptBase &&right)=delete
virtual ~SpellScriptBase()
virtual void Unload()
SpellScriptBase & operator=(SpellScriptBase const &right)=delete
void Call(SpellScript *spellScript, SpellMissInfo missInfo) const
BeforeHitHandler(ScriptFunc handler)
CastHandler(ScriptFunc handler)
ScriptFuncInvoker _invoker
void Call(SpellScript *spellScript) const
SpellCastResult Call(SpellScript *spellScript) const
CheckCastHandler(ScriptFunc handler)
void Call(SpellScript *spellScript, SpellEffectInfo const &spellEffectInfo, Unit *victim, int32 &damageOrHealing, int32 &flatMod, float &pctMod) const
DamageAndHealingCalcHandler(ScriptFunc handler)
DestinationTargetSelectHandler(ScriptFunc handler, uint8 effIndex, uint16 targetType)
void Call(SpellScript *spellScript, SpellDestination &target) const
EffectBase(EffectBase const &right)=delete
EffectBase(EffectBase &&right) noexcept
EffectBase & operator=(EffectBase const &right)=delete
EffectBase & operator=(EffectBase &&right) noexcept
EffectHandler(ScriptFunc handler, uint8 effIndex, uint16 effName)
void Call(SpellScript *spellScript, SpellEffIndex effIndex) const
ScriptFuncInvoker _invoker
EmpowerStageCompletedHandler(ScriptFunc handler)
void Call(SpellScript *spellScript, int32 completedStagesCount) const
void Call(SpellScript *spellScript) const
ScriptFuncInvoker _invoker
HitHandler(ScriptFunc handler)
void Call(SpellScript *spellScript, std::list< WorldObject * > &targets) const
bool HasSameTargetFunctionAs(ObjectAreaTargetSelectHandler const &other) const
ObjectAreaTargetSelectHandler(ScriptFunc handler, uint8 effIndex, uint16 targetType)
bool HasSameTargetFunctionAs(ObjectTargetSelectHandler const &other) const
ObjectTargetSelectHandler(ScriptFunc handler, uint8 effIndex, uint16 targetType)
void Call(SpellScript *spellScript, WorldObject *&target) const
void Call(SpellScript *spellScript, Unit const *victim, float &critChance) const
OnCalcCritChanceHandler(ScriptFunc handler)
void Call(SpellScript *spellScript, DamageInfo const &damageInfo, uint32 &resistAmount, int32 &absorbAmount) const
TargetHook(TargetHook &&right) noexcept
uint16 GetTarget() const
TargetHook & operator=(TargetHook &&right) noexcept
TargetHook(TargetHook const &right)=delete
TargetHook & operator=(TargetHook const &right)=delete
bool _IsDefaultEffectPrevented(SpellEffIndex effIndex) const
HookList< DamageAndHealingCalcHandler > CalcDamage
HookList< CastHandler > AfterCast
HookList< CheckCastHandler > OnCheckCast
HookList< EmpowerStageCompletedHandler > OnEmpowerStageCompleted
HookList< HitHandler > AfterHit
HookList< DestinationTargetSelectHandler > OnDestinationTargetSelect
uint32 m_hitPreventDefaultEffectMask
HookList< HitHandler > OnHit
void PreventHitDamage()
uint32 m_hitPreventEffectMask
HookList< EffectHandler > OnEffectHit
HookList< EffectHandler > OnEffectHitTarget
void PreventHitHeal()
HookList< ObjectTargetSelectHandler > OnObjectTargetSelect
HookList< CastHandler > OnCast
HookList< OnCalculateResistAbsorbHandler > OnCalculateResistAbsorb
HookList< CastHandler > BeforeCast
virtual int32 CalcCastTime(int32 castTime)
Spell * m_spell
Spell * GetSpell() const
HookList< EffectHandler > OnEffectLaunchTarget
HookList< BeforeHitHandler > BeforeHit
virtual void OnPrecast()
HookList< EffectHandler > OnEffectSuccessfulDispel
HookList< OnCalcCritChanceHandler > OnCalcCritChance
HookList< EmpowerStageCompletedHandler > OnEmpowerCompleted
HookList< EffectHandler > OnEffectLaunch
HookList< DamageAndHealingCalcHandler > CalcHealing
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
Definition Spell.h:277
Definition Unit.h:647
static Ret Invoke(BaseClass &script, Args... args, StorageType callImpl)
GetScriptClass_t< ScriptFunc > ScriptClass