TrinityCore
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 : uint8;
56enum class ItemContext : uint8;
57
58#define SPELL_EFFECT_ANY ((uint16)-1)
59#define SPELL_AURA_ANY ((uint16)-1)
60
62{
67};
68#define SPELL_SCRIPT_STATE_END (SPELL_SCRIPT_STATE_UNLOADING + 1)
69
70// helper class from which SpellScript and AuraScript derive, use these classes instead
72{
73// internal use classes & functions
74// DO NOT OVERRIDE THESE IN SCRIPTS
75public:
78
79 SpellScriptBase(SpellScriptBase const& right) = delete;
81 SpellScriptBase& operator=(SpellScriptBase const& right) = delete;
83
84 void _Register();
85 void _Unload();
86 void _Init(std::string const& scriptname, uint32 spellId);
87 std::string_view GetScriptName() const;
88
89protected:
90 virtual bool _Validate(SpellInfo const* entry);
91
93 {
94 public:
95 explicit EffectHook(uint8 effIndex);
96 EffectHook(EffectHook const& right) = delete;
97 EffectHook(EffectHook&& right) noexcept;
98 EffectHook& operator=(EffectHook const& right) = delete;
99 EffectHook& operator=(EffectHook&& right) noexcept;
100 virtual ~EffectHook();
101
102 uint32 GetAffectedEffectsMask(SpellInfo const* spellInfo) const;
103 bool IsEffectAffected(SpellInfo const* spellInfo, uint8 effIndex) const;
104 virtual bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex) const = 0;
105 std::string EffIndexToString() const;
106
107 protected:
109 };
110
111 template<typename>
113 {
114 using type = void;
115 };
116
117 template<typename Return, typename Class, typename... Args>
118 struct GetScriptClass<Return(Class::*)(Args...)>
119 {
120 using type = Class;
121 };
122
123 template<typename Return, typename Class, typename... Args>
124 struct GetScriptClass<Return(Class::*)(Args...) const>
125 {
126 using type = Class;
127 };
128
129 template<typename ScriptFunc>
131
133 std::string_view m_scriptName;
135
136private:
137
138#ifdef TRINITY_API_USE_DYNAMIC_LINKING
139
140 // Strong reference to keep the binary code loaded
141 std::shared_ptr<ModuleReference> m_moduleReference;
142
143#endif // #ifndef TRINITY_API_USE_DYNAMIC_LINKING
144
145public:
146 //
147 // SpellScript/AuraScript interface base
148 // these functions are safe to override, see notes below for usage instructions
149 //
150 // Function in which handler functions are registered, must be implemented in script
151 virtual void Register() = 0;
152 // Function called on server startup, if returns false script won't be used in core
153 // use for: dbc/template data presence/correctness checks
154 virtual bool Validate([[maybe_unused]] SpellInfo const* spellInfo) { return true; }
155 // Function called when script is created, if returns false script will be unloaded afterwards
156 // use for: initializing local script variables (DO NOT USE CONSTRUCTOR FOR THIS PURPOSE!)
157 virtual bool Load() { return true; }
158 // Function called when script is destroyed
159 // use for: deallocating memory allocated by script
160 virtual void Unload() { }
161 // Helpers
162 static bool ValidateSpellInfo(std::initializer_list<uint32> spellIds)
163 {
164 return ValidateSpellInfoImpl(spellIds.begin(), spellIds.end());
165 }
166
167 template <class T>
168 static bool ValidateSpellInfo(T const& spellIds)
169 {
170 return ValidateSpellInfoImpl(std::cbegin(spellIds), std::cend(spellIds));
171 }
172
173 static bool ValidateSpellEffect(std::initializer_list<std::pair<uint32, SpellEffIndex>> effects)
174 {
175 return ValidateSpellEffectsImpl(effects.begin(), effects.end());
176 }
177
178 template <class T>
179 static bool ValidateSpellEffect(T const& spellEffects)
180 {
181 return ValidateSpellEffectsImpl(std::cbegin(spellEffects), std::cend(spellEffects));
182 }
183
184private:
185 template<typename Iterator>
186 static bool ValidateSpellInfoImpl(Iterator begin, Iterator end)
187 {
188 bool allValid = true;
189 while (begin != end)
190 {
191 if (!ValidateSpellInfoImpl(*begin))
192 allValid = false;
193
194 ++begin;
195 }
196 return allValid;
197 }
198
199 template<typename Iterator>
200 static bool ValidateSpellEffectsImpl(Iterator begin, Iterator end)
201 {
202 bool allValid = true;
203 while (begin != end)
204 {
205 if (!ValidateSpellEffectImpl(begin->first, begin->second))
206 allValid = false;
207
208 ++begin;
209 }
210 return allValid;
211 }
212
213 static bool ValidateSpellInfoImpl(uint32 spellId);
214 static bool ValidateSpellEffectImpl(uint32 spellId, SpellEffIndex effectIndex);
215};
216
217// SpellScript interface - enum used for runtime checks of script function calls
219{
243};
244
245#define HOOK_SPELL_HIT_START SPELL_SCRIPT_HOOK_EFFECT_HIT
246#define HOOK_SPELL_HIT_END SPELL_SCRIPT_HOOK_AFTER_HIT + 1
247
249{
250 // internal use classes & functions
251 // DO NOT OVERRIDE THESE IN SCRIPTS
252public:
253 class CastHandler final
254 {
255 public:
256 using SpellCastFnType = void(SpellScript::*)();
257
258 using SafeWrapperType = void(*)(SpellScript* spellScript, SpellCastFnType callImpl);
259
260 template<typename ScriptFunc>
261 explicit CastHandler(ScriptFunc handler)
262 {
263 using ScriptClass = GetScriptClass_t<ScriptFunc>;
264
265 static_assert(sizeof(SpellCastFnType) >= sizeof(ScriptFunc));
266 static_assert(alignof(SpellCastFnType) >= alignof(ScriptFunc));
267
268 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass>,
269 "CastHandler signature must be \"void HandleCast()\"");
270
271 _callImpl = reinterpret_cast<SpellCastFnType>(handler);
272 _safeWrapper = [](SpellScript* spellScript, SpellCastFnType callImpl) -> void
273 {
274 return (static_cast<ScriptClass*>(spellScript)->*reinterpret_cast<ScriptFunc>(callImpl))();
275 };
276 }
277
278 void Call(SpellScript* spellScript) const
279 {
280 return _safeWrapper(spellScript, _callImpl);
281 }
282 private:
285 };
286
288 {
289 public:
291 {
293 SpellCastResult(*Static)();
294 };
295
297
298 template<typename ScriptFunc>
299 explicit CheckCastHandler(ScriptFunc handler)
300 {
301 using ScriptClass = GetScriptClass_t<ScriptFunc>;
302
303 static_assert(sizeof(SpellCheckCastFnType) >= sizeof(ScriptFunc));
304 static_assert(alignof(SpellCheckCastFnType) >= alignof(ScriptFunc));
305
306 if constexpr (!std::is_void_v<ScriptClass>)
307 {
308 static_assert(std::is_invocable_r_v<SpellCastResult, ScriptFunc, ScriptClass>,
309 "CheckCastHandler signature must be \"SpellCastResult CheckCast()\"");
310
311 _callImpl = { .Member = reinterpret_cast<decltype(SpellCheckCastFnType::Member)>(handler) };
312 _safeWrapper = [](SpellScript* spellScript, SpellCheckCastFnType callImpl) -> SpellCastResult
313 {
314 return (static_cast<ScriptClass*>(spellScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))();
315 };
316 }
317 else
318 {
319 static_assert(std::is_invocable_r_v<SpellCastResult, ScriptFunc>,
320 "CheckCastHandler signature must be \"static SpellCastResult CheckCast()\"");
321
322 _callImpl = { .Static = reinterpret_cast<decltype(SpellCheckCastFnType::Static)>(handler) };
323 _safeWrapper = [](SpellScript* /*spellScript*/, SpellCheckCastFnType callImpl) -> SpellCastResult
324 {
325 return reinterpret_cast<ScriptFunc>(callImpl.Static)();
326 };
327 }
328 }
329
330 SpellCastResult Call(SpellScript* spellScript) const
331 {
332 return _safeWrapper(spellScript, _callImpl);
333 }
334 private:
337 };
338
340 {
341 public:
342 EffectBase(uint8 effIndex, uint16 effName);
343 EffectBase(EffectBase const& right) = delete;
344 EffectBase(EffectBase&& right) noexcept;
345 EffectBase& operator=(EffectBase const& right) = delete;
346 EffectBase& operator=(EffectBase&& right) noexcept;
348 std::string ToString() const;
349 bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex) const override;
350 private:
352 };
353
354 class EffectHandler final : public EffectBase
355 {
356 public:
357 using SpellEffectFnType = void(SpellScript::*)(SpellEffIndex effIndex);
358
359 using SafeWrapperType = void(*)(SpellScript* spellScript, SpellEffIndex effIndex, SpellEffectFnType callImpl);
360
361 template<typename ScriptFunc>
362 explicit EffectHandler(ScriptFunc handler, uint8 effIndex, uint16 effName)
363 : EffectBase(effIndex, effName)
364 {
365 using ScriptClass = GetScriptClass_t<ScriptFunc>;
366
367 static_assert(sizeof(SpellEffectFnType) >= sizeof(ScriptFunc));
368 static_assert(alignof(SpellEffectFnType) >= alignof(ScriptFunc));
369
370 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, SpellEffIndex>,
371 "EffectHandler signature must be \"void HandleEffect(SpellEffIndex effIndex)\"");
372
373 _callImpl = reinterpret_cast<SpellEffectFnType>(handler);
374 _safeWrapper = [](SpellScript* spellScript, SpellEffIndex effIndex, SpellEffectFnType callImpl) -> void
375 {
376 return (static_cast<ScriptClass*>(spellScript)->*reinterpret_cast<ScriptFunc>(callImpl))(effIndex);
377 };
378 }
379
380 void Call(SpellScript* spellScript, SpellEffIndex effIndex) const
381 {
382 return _safeWrapper(spellScript, effIndex, _callImpl);
383 }
384 private:
387 };
388
390 {
391 public:
393
394 using SafeWrapperType = void(*)(SpellScript* spellScript, SpellMissInfo missInfo, SpellBeforeHitFnType callImpl);
395
396 template<typename ScriptFunc>
397 explicit BeforeHitHandler(ScriptFunc handler)
398 {
399 using ScriptClass = GetScriptClass_t<ScriptFunc>;
400
401 static_assert(sizeof(SpellBeforeHitFnType) >= sizeof(ScriptFunc));
402 static_assert(alignof(SpellBeforeHitFnType) >= alignof(ScriptFunc));
403
404 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, SpellMissInfo>,
405 "BeforeHitHandler signature must be \"void HandleBeforeHit(SpellMissInfo missInfo)\"");
406
407 _callImpl = reinterpret_cast<SpellBeforeHitFnType>(handler);
408 _safeWrapper = [](SpellScript* spellScript, SpellMissInfo missInfo, SpellBeforeHitFnType callImpl) -> void
409 {
410 return (static_cast<ScriptClass*>(spellScript)->*reinterpret_cast<ScriptFunc>(callImpl))(missInfo);
411 };
412 }
413
414 void Call(SpellScript* spellScript, SpellMissInfo missInfo) const
415 {
416 return _safeWrapper(spellScript, missInfo, _callImpl);
417 }
418 private:
421 };
422
423 class HitHandler final
424 {
425 public:
426 using SpellHitFnType = void(SpellScript::*)();
427
428 using SafeWrapperType = void(*)(SpellScript* spellScript, SpellHitFnType callImpl);
429
430 template<typename ScriptFunc>
431 explicit HitHandler(ScriptFunc handler)
432 {
433 using ScriptClass = GetScriptClass_t<ScriptFunc>;
434
435 static_assert(sizeof(SpellHitFnType) >= sizeof(ScriptFunc));
436 static_assert(alignof(SpellHitFnType) >= alignof(ScriptFunc));
437
438 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass>,
439 "HitHandler signature must be \"void HandleHit()\"");
440
441 _callImpl = reinterpret_cast<SpellHitFnType>(handler);
442 _safeWrapper = [](SpellScript* spellScript, SpellHitFnType callImpl) -> void
443 {
444 return (static_cast<ScriptClass*>(spellScript)->*reinterpret_cast<ScriptFunc>(callImpl))();
445 };
446 }
447
448 void Call(SpellScript* spellScript) const
449 {
450 return _safeWrapper(spellScript, _callImpl);
451 }
452 private:
455 };
456
458 {
459 public:
461 {
462 void(SpellScript::* Member)(Unit const* victim, float& critChance);
463 void(*Static)(Unit const* victim, float& critChance);
464 };
465
466 using SafeWrapperType = void(*)(SpellScript* spellScript, Unit const* victim, float& critChance, SpellOnCalcCritChanceFnType callImpl);
467
468 template<typename ScriptFunc>
469 explicit OnCalcCritChanceHandler(ScriptFunc handler)
470 {
471 using ScriptClass = GetScriptClass_t<ScriptFunc>;
472
473 static_assert(sizeof(SpellOnCalcCritChanceFnType) >= sizeof(ScriptFunc));
474 static_assert(alignof(SpellOnCalcCritChanceFnType) >= alignof(ScriptFunc));
475
476 if constexpr (!std::is_void_v<ScriptClass>)
477 {
478 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, Unit const*, float&>,
479 "OnCalcCritChanceHandler signature must be \"void CalcCritChance(Unit const* victim, float& critChance)\"");
480
481 _callImpl = { .Member = reinterpret_cast<decltype(SpellOnCalcCritChanceFnType::Member)>(handler) };
482 _safeWrapper = [](SpellScript* spellScript, Unit const* victim, float& critChance, SpellOnCalcCritChanceFnType callImpl) -> void
483 {
484 return (static_cast<ScriptClass*>(spellScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(victim, critChance);
485 };
486 }
487 else
488 {
489 static_assert(std::is_invocable_r_v<void, ScriptFunc, Unit const*, float&>,
490 "OnCalcCritChanceHandler signature must be \"static void CalcCritChance(Unit const* victim, float& critChance)\"");
491
492 _callImpl = { .Static = reinterpret_cast<decltype(SpellOnCalcCritChanceFnType::Static)>(handler) };
493 _safeWrapper = [](SpellScript* /*spellScript*/, Unit const* victim, float& critChance, SpellOnCalcCritChanceFnType callImpl) -> void
494 {
495 return reinterpret_cast<ScriptFunc>(callImpl.Static)(victim, critChance);
496 };
497 }
498 }
499
500 void Call(SpellScript* spellScript, Unit const* victim, float& critChance) const
501 {
502 return _safeWrapper(spellScript, victim, critChance, _callImpl);
503 }
504 private:
507 };
508
510 {
511 public:
512 TargetHook(uint8 effectIndex, uint16 targetType, bool area, bool dest);
513 TargetHook(TargetHook const& right) = delete;
514 TargetHook(TargetHook&& right) noexcept;
515 TargetHook& operator=(TargetHook const& right) = delete;
516 TargetHook& operator=(TargetHook&& right) noexcept;
517 virtual ~TargetHook();
518 bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex) const override;
519 std::string ToString() const;
520 uint16 GetTarget() const { return _targetType; }
521 protected:
523 bool _area;
524 bool _dest;
525 };
526
528 {
529 public:
531 {
532 void(SpellScript::* Member)(std::list<WorldObject*>& targets);
533 void(*Static)(std::list<WorldObject*>& targets);
534 };
535
536 using SafeWrapperType = void(*)(SpellScript* spellScript, std::list<WorldObject*>& targets, SpellObjectAreaTargetSelectFnType callImpl);
537
538 template<typename ScriptFunc>
539 explicit ObjectAreaTargetSelectHandler(ScriptFunc handler, uint8 effIndex, uint16 targetType)
540 : TargetHook(effIndex, targetType, true, false)
541 {
542 using ScriptClass = GetScriptClass_t<ScriptFunc>;
543
544 static_assert(sizeof(SpellObjectAreaTargetSelectFnType) >= sizeof(ScriptFunc));
545 static_assert(alignof(SpellObjectAreaTargetSelectFnType) >= alignof(ScriptFunc));
546
547 if constexpr (!std::is_void_v<ScriptClass>)
548 {
549 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, std::list<WorldObject*>&>,
550 "ObjectAreaTargetSelectHandler signature must be \"void SetTargets(std::list<WorldObject*>& targets)\"");
551
552 _callImpl = { .Member = reinterpret_cast<decltype(SpellObjectAreaTargetSelectFnType::Member)>(handler) };
553 _safeWrapper = [](SpellScript* spellScript, std::list<WorldObject*>& targets, SpellObjectAreaTargetSelectFnType callImpl) -> void
554 {
555 return (static_cast<ScriptClass*>(spellScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(targets);
556 };
557 }
558 else
559 {
560 static_assert(std::is_invocable_r_v<void, ScriptFunc, std::list<WorldObject*>&>,
561 "ObjectAreaTargetSelectHandler signature must be \"static void SetTargets(std::list<WorldObject*>& targets)\"");
562
563 _callImpl = { .Static = reinterpret_cast<decltype(SpellObjectAreaTargetSelectFnType::Static)>(handler) };
564 _safeWrapper = [](SpellScript* /*spellScript*/, std::list<WorldObject*>& targets, SpellObjectAreaTargetSelectFnType callImpl) -> void
565 {
566 return reinterpret_cast<ScriptFunc>(callImpl.Static)(targets);
567 };
568 }
569 }
570
571 void Call(SpellScript* spellScript, std::list<WorldObject*>& targets) const
572 {
573 return _safeWrapper(spellScript, targets, _callImpl);
574 }
575
577 {
578 return _callImpl.Member == other._callImpl.Member || _callImpl.Static == other._callImpl.Static;
579 }
580 private:
583 };
584
586 {
587 public:
589 {
590 void(SpellScript::* Member)(WorldObject*& target);
591 void(*Static)(WorldObject*& target);
592 };
593
594 using SafeWrapperType = void(*)(SpellScript* spellScript, WorldObject*& target, SpellObjectTargetSelectFnType callImpl);
595
596 template<typename ScriptFunc>
597 explicit ObjectTargetSelectHandler(ScriptFunc handler, uint8 effIndex, uint16 targetType)
598 : TargetHook(effIndex, targetType, false, false)
599 {
600 using ScriptClass = GetScriptClass_t<ScriptFunc>;
601
602 static_assert(sizeof(SpellObjectTargetSelectFnType) >= sizeof(ScriptFunc));
603 static_assert(alignof(SpellObjectTargetSelectFnType) >= alignof(ScriptFunc));
604
605 if constexpr (!std::is_void_v<ScriptClass>)
606 {
607 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, WorldObject*&>,
608 "ObjectTargetSelectHandler signature must be \"void SetTarget(WorldObject*& target)\"");
609
610 _callImpl = { .Member = reinterpret_cast<decltype(SpellObjectTargetSelectFnType::Member)>(handler) };
611 _safeWrapper = [](SpellScript* spellScript, WorldObject*& target, SpellObjectTargetSelectFnType callImpl) -> void
612 {
613 return (static_cast<ScriptClass*>(spellScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(target);
614 };
615 }
616 else
617 {
618 static_assert(std::is_invocable_r_v<void, ScriptFunc, WorldObject*&>,
619 "ObjectTargetSelectHandler signature must be \"static void SetTarget(WorldObject*& target)\"");
620
621 _callImpl = { .Static = reinterpret_cast<decltype(SpellObjectTargetSelectFnType::Static)>(handler) };
622 _safeWrapper = [](SpellScript* /*spellScript*/, WorldObject*& target, SpellObjectTargetSelectFnType callImpl) -> void
623 {
624 return reinterpret_cast<ScriptFunc>(callImpl.Static)(target);
625 };
626 }
627 }
628
629 void Call(SpellScript* spellScript, WorldObject*& target) const
630 {
631 return _safeWrapper(spellScript, target, _callImpl);
632 }
633
635 {
636 return _callImpl.Member == other._callImpl.Member || _callImpl.Static == other._callImpl.Static;
637 }
638 private:
641 };
642
644 {
645 public:
647 {
649 void(*Static)(SpellDestination& target);
650 };
651
652 using SafeWrapperType = void(*)(SpellScript* spellScript, SpellDestination& target, SpellDestinationTargetSelectFnType callImpl);
653
654 template<typename ScriptFunc>
655 explicit DestinationTargetSelectHandler(ScriptFunc handler, uint8 effIndex, uint16 targetType)
656 : TargetHook(effIndex, targetType, false, true)
657 {
658 using ScriptClass = GetScriptClass_t<ScriptFunc>;
659
660 static_assert(sizeof(SpellDestinationTargetSelectFnType) >= sizeof(ScriptFunc));
661 static_assert(alignof(SpellDestinationTargetSelectFnType) >= alignof(ScriptFunc));
662
663 if constexpr (!std::is_void_v<ScriptClass>)
664 {
665 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, SpellDestination&>,
666 "DestinationTargetSelectHandler signature must be \"void SetTarget(SpellDestination& target)\"");
667
668 _callImpl = { .Member = reinterpret_cast<decltype(SpellDestinationTargetSelectFnType::Member)>(handler) };
669 _safeWrapper = [](SpellScript* spellScript, SpellDestination& target, SpellDestinationTargetSelectFnType callImpl) -> void
670 {
671 return (static_cast<ScriptClass*>(spellScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(target);
672 };
673 }
674 else
675 {
676 static_assert(std::is_invocable_r_v<void, ScriptFunc, SpellDestination&>,
677 "DestinationTargetSelectHandler signature must be \"static void SetTarget(SpellDestination& target)\"");
678
679 _callImpl = { .Static = reinterpret_cast<decltype(SpellDestinationTargetSelectFnType::Static)>(handler) };
680 _safeWrapper = [](SpellScript* /*spellScript*/, SpellDestination& target, SpellDestinationTargetSelectFnType callImpl) -> void
681 {
682 return reinterpret_cast<ScriptFunc>(callImpl.Static)(target);
683 };
684 }
685 }
686
687 void Call(SpellScript* spellScript, SpellDestination& target) const
688 {
689 return _safeWrapper(spellScript, target, _callImpl);
690 }
691 private:
694 };
695
697 {
698 public:
700 {
701 void(SpellScript::* Member)(SpellEffectInfo const& spellEffectInfo, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod);
702 void(*Static)(SpellEffectInfo const& spellEffectInfo, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod);
703 };
704
705 using SafeWrapperType = void(*)(SpellScript* spellScript, SpellEffectInfo const& spellEffectInfo, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod, DamageAndHealingCalcFnType callImpl);
706
707 template<typename ScriptFunc>
708 explicit DamageAndHealingCalcHandler(ScriptFunc handler)
709 {
710 using ScriptClass = GetScriptClass_t<ScriptFunc>;
711
712 static_assert(sizeof(DamageAndHealingCalcFnType) >= sizeof(ScriptFunc));
713 static_assert(alignof(DamageAndHealingCalcFnType) >= alignof(ScriptFunc));
714
715 if constexpr (!std::is_void_v<ScriptClass>)
716 {
717 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, SpellEffectInfo const&, Unit*, int32&, int32&, float&>,
718 "DamageAndHealingCalcHandler signature must be \"void CalcDamage(SpellEffectInfo const& spellEffectInfo, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod)\"");
719
720 _callImpl = { .Member = reinterpret_cast<decltype(DamageAndHealingCalcFnType::Member)>(handler) };
721 _safeWrapper = [](SpellScript* spellScript, SpellEffectInfo const& spellEffectInfo, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod, DamageAndHealingCalcFnType callImpl) -> void
722 {
723 return (static_cast<ScriptClass*>(spellScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(spellEffectInfo, victim, damageOrHealing, flatMod, pctMod);
724 };
725 }
726 else
727 {
728 static_assert(std::is_invocable_r_v<void, ScriptFunc, SpellEffectInfo const&, Unit*, int32&, int32&, float&>,
729 "DamageAndHealingCalcHandler signature must be \"static void CalcDamage(SpellEffectInfo const& spellEffectInfo, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod)\"");
730
731 _callImpl = { .Static = reinterpret_cast<decltype(DamageAndHealingCalcFnType::Static)>(handler) };
732 _safeWrapper = [](SpellScript* /*spellScript*/, SpellEffectInfo const& spellEffectInfo, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod, DamageAndHealingCalcFnType callImpl) -> void
733 {
734 return reinterpret_cast<ScriptFunc>(callImpl.Static)(spellEffectInfo, victim, damageOrHealing, flatMod, pctMod);
735 };
736 }
737 }
738
739 void Call(SpellScript* spellScript, SpellEffectInfo const& spellEffectInfo, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod) const
740 {
741 return _safeWrapper(spellScript, spellEffectInfo, victim, damageOrHealing, flatMod, pctMod, _callImpl);
742 }
743 private:
746 };
747
749 {
750 public:
752 {
753 void(SpellScript::* Member)(DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount);
754 void(*Static)(DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount);
755 };
756
757 using SafeWrapperType = void(*)(SpellScript* spellScript, DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount, SpellOnResistAbsorbCalculateFnType callImpl);
758
759 template<typename ScriptFunc>
760 explicit OnCalculateResistAbsorbHandler(ScriptFunc handler)
761 {
762 using ScriptClass = GetScriptClass_t<ScriptFunc>;
763
764 static_assert(sizeof(SpellOnResistAbsorbCalculateFnType) >= sizeof(ScriptFunc));
765 static_assert(alignof(SpellOnResistAbsorbCalculateFnType) >= alignof(ScriptFunc));
766
767 if constexpr (!std::is_void_v<ScriptClass>)
768 {
769 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, DamageInfo const&, uint32&, int32&>,
770 "OnCalculateResistAbsorbHandler signature must be \"void CalcAbsorbResist(DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount)\"");
771
772 _callImpl = { .Member = reinterpret_cast<decltype(SpellOnResistAbsorbCalculateFnType::Member)>(handler) };
773 _safeWrapper = [](SpellScript* spellScript, DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount, SpellOnResistAbsorbCalculateFnType callImpl) -> void
774 {
775 return (static_cast<ScriptClass*>(spellScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(damageInfo, resistAmount, absorbAmount);
776 };
777 }
778 else
779 {
780 static_assert(std::is_invocable_r_v<void, ScriptFunc, DamageInfo const&, uint32&, int32&>,
781 "OnCalculateResistAbsorbHandler signature must be \"static void CalcAbsorbResist(DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount)\"");
782
783 _callImpl = { .Static = reinterpret_cast<decltype(SpellOnResistAbsorbCalculateFnType::Static)>(handler) };
784 _safeWrapper = [](SpellScript* /*spellScript*/, DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount, SpellOnResistAbsorbCalculateFnType callImpl) -> void
785 {
786 return reinterpret_cast<ScriptFunc>(callImpl.Static)(damageInfo, resistAmount, absorbAmount);
787 };
788 }
789 }
790
791 void Call(SpellScript* spellScript, DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount) const
792 {
793 return _safeWrapper(spellScript, damageInfo, resistAmount, absorbAmount, _callImpl);
794 }
795 private:
798 };
799
801 {
802 public:
804
805 using SafeWrapperType = void(*)(SpellScript* spellScript, EmpowerStageFnType callImpl, int32 completedStagesCount);
806
807 template<typename ScriptFunc>
808 explicit EmpowerStageCompletedHandler(ScriptFunc handler)
809 {
810 using ScriptClass = GetScriptClass_t<ScriptFunc>;
811
812 static_assert(sizeof(EmpowerStageFnType) >= sizeof(ScriptFunc));
813 static_assert(alignof(EmpowerStageFnType) >= alignof(ScriptFunc));
814
815 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, int32>,
816 "EmpowerStageCompleted/EmpowerCompleted signature must be \"void HandleEmpowerStageCompleted(int32 completedStagesCount)\"");
817
818 _callImpl = reinterpret_cast<EmpowerStageFnType>(handler);
819 _safeWrapper = [](SpellScript* spellScript, EmpowerStageFnType callImpl, int32 completedStagesCount) -> void
820 {
821 return (static_cast<ScriptClass*>(spellScript)->*reinterpret_cast<ScriptFunc>(callImpl))(completedStagesCount);
822 };
823 }
824
825 void Call(SpellScript* spellScript, int32 completedStagesCount) const
826 {
827 return _safeWrapper(spellScript, _callImpl, completedStagesCount);
828 }
829 private:
832 };
833
834 // left for custom compatibility only, DO NOT USE
835 #define PrepareSpellScript(CLASSNAME)
836
837 SpellScript();
839 bool _Validate(SpellInfo const* entry) override;
840 bool _Load(Spell* spell);
841 void _InitHit();
842 bool _IsEffectPrevented(SpellEffIndex effIndex) const { return (m_hitPreventEffectMask & (1 << effIndex)) != 0; }
843 bool _IsDefaultEffectPrevented(SpellEffIndex effIndex) const { return (m_hitPreventDefaultEffectMask & (1 << effIndex)) != 0; }
844 void _PrepareScriptCall(SpellScriptHookType hookType);
845 void _FinishScriptCall();
846 bool IsInCheckCastHook() const;
847 bool IsAfterTargetSelectionPhase() const;
848 bool IsInTargetHook() const;
849 bool IsInModifiableHook() const;
850 bool IsInHitPhase() const;
851 bool IsInEffectHook() const;
852private:
856public:
857 //
858 // SpellScript interface
859 //
860 // example: void OnPrecast() override { }
861 virtual void OnPrecast() { }
862 //
863 // hooks to which you can attach your functions
864 //
865 // example: BeforeCast += SpellCastFn(class::function);
867 // example: OnCast += SpellCastFn(class::function);
869 // example: AfterCast += SpellCastFn(class::function);
871 #define SpellCastFn(F) CastHandler(&F)
872
873 // example: OnCheckCast += SpellCheckCastFn();
874 // where function is SpellCastResult function()
876 #define SpellCheckCastFn(F) CheckCastHandler(&F)
877
878 // example: int32 CalcCastTime(int32 castTime) override { return 1500; }
879 virtual int32 CalcCastTime(int32 castTime) { return castTime; }
880
881 // example: OnEffect**** += SpellEffectFn(class::function, EffectIndexSpecifier, EffectNameSpecifier);
882 // where function is void function(SpellEffIndex effIndex)
888 #define SpellEffectFn(F, I, N) EffectHandler(&F, I, N)
889
890 // example: BeforeHit += BeforeSpellHitFn(class::function);
891 // where function is void function(SpellMissInfo missInfo)
893 #define BeforeSpellHitFn(F) BeforeHitHandler(&F)
894
895 // example: OnHit += SpellHitFn(class::function);
897 // example: AfterHit += SpellHitFn(class::function);
899 // where function is: void function()
900 #define SpellHitFn(F) HitHandler(&F)
901
902 // example: OnCalcCritChance += SpellOnCalcCritChanceFn(class::function);
903 // where function is: void function(Unit* victim, float& critChance)
905 #define SpellOnCalcCritChanceFn(F) OnCalcCritChanceHandler(&F)
906
907 // example: OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier);
908 // where function is void function(std::list<WorldObject*>& targets)
910 #define SpellObjectAreaTargetSelectFn(F, I, N) ObjectAreaTargetSelectHandler(&F, I, N)
911
912 // example: OnObjectTargetSelect += SpellObjectTargetSelectFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier);
913 // where function is void function(WorldObject*& target)
915 #define SpellObjectTargetSelectFn(F, I, N) ObjectTargetSelectHandler(&F, I, N)
916
917 // example: OnDestinationTargetSelect += SpellDestinationTargetSelectFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier);
918 // where function is void function(SpellDestination& target)
920 #define SpellDestinationTargetSelectFn(F, I, N) DestinationTargetSelectHandler(&F, I, N)
921
922 // example: CalcDamage += SpellCalcDamageFn(class::function);
923 // where function is void function(Unit* victim, int32& damage, int32& flatMod, float& pctMod)
925 #define SpellCalcDamageFn(F) DamageAndHealingCalcHandler(&F)
926
927 // example: CalcHealing += SpellCalcHealingFn(class::function);
928 // where function is void function(Unit* victim, int32& healing, int32& flatMod, float& pctMod)
930 #define SpellCalcHealingFn(F) DamageAndHealingCalcHandler(&F)
931
932 // example: OnCalculateResistAbsorb += SpellOnResistAbsorbCalculateFn(class::function);
933 // where function is void function(DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount)
935 #define SpellOnResistAbsorbCalculateFn(F) OnCalculateResistAbsorbHandler(&F)
936
937 // example: OnEmpowerStageCompleted += SpellOnEmpowerStageCompletedFn(class::function);
938 // where function is void function(int32 completedStages)
940 #define SpellOnEmpowerStageCompletedFn(F) EmpowerStageCompletedHandler(&F)
941
942 // example: OnEmpowerCompleted += SpellOnEmpowerCompletedFn(class::function);
943 // where function is void function(int32 completedStages)
945 #define SpellOnEmpowerCompletedFn(F) EmpowerStageCompletedHandler(&F)
946
947 // hooks are executed in following order, at specified event of spell:
948 // 1. OnPrecast - executed during spell preparation (before cast bar starts)
949 // 2. BeforeCast - executed when spell preparation is finished (when cast bar becomes full) before cast is handled
950 // 3. OnCheckCast - allows to override result of CheckCast function
951 // 4a. OnObjectAreaTargetSelect - executed just before adding selected targets to final target list (for area targets)
952 // 4b. OnObjectTargetSelect - executed just before adding selected target to final target list (for single unit targets)
953 // 4c. OnDestinationTargetSelect - executed just before adding selected target to final target list (for destination targets)
954 // 5. OnCast - executed just before spell is launched (creates missile) or executed
955 // 6. AfterCast - executed after spell missile is launched and immediate spell actions are done
956 // 7. OnEffectLaunch - executed just before specified effect handler call - when spell missile is launched
957 // 8. OnCalcCritChance - executed just after specified effect handler call - when spell missile is launched - called for each target from spell target map
958 // 9. OnEffectLaunchTarget - executed just before specified effect handler call - when spell missile is launched - called for each target from spell target map
959 // 10a. CalcDamage - executed during specified effect handler call - when spell missile is launched - called for each target from spell target map
960 // 10b. CalcHealing - executed during specified effect handler call - when spell missile is launched - called for each target from spell target map
961 // 11. OnCalculateResistAbsorb - executed when damage resist/absorbs is calculated - before spell hit target
962 // 12. OnEffectHit - executed just before specified effect handler call - when spell missile hits dest
963 // 13. BeforeHit - executed just before spell hits a target - called for each target from spell target map
964 // 14. OnEffectHitTarget - executed just before specified effect handler call - called for each target from spell target map
965 // 15. OnHit - executed just before spell deals damage and procs auras - when spell hits target - called for each target from spell target map
966 // 16. AfterHit - executed just after spell finishes all it's jobs for target - called for each target from spell target map
967 // 17. OnEmpowerStageCompleted - executed when empowered spell completes each stage
968 // 18. OnEmpowerCompleted - executed when empowered spell is released
969
970 // this hook is only executed after a successful dispel of any aura
971 // OnEffectSuccessfulDispel - executed just after effect successfully dispelled aura(s)
972
973 //
974 // methods allowing interaction with Spell object
975 //
976 // methods useable during all spell handling phases
977 Unit* GetCaster() const;
978 GameObject* GetGObjCaster() const;
979 Unit* GetOriginalCaster() const;
980 SpellInfo const* GetSpellInfo() const;
981 SpellEffectInfo const& GetEffectInfo(SpellEffIndex effIndex) const;
982 SpellValue const* GetSpellValue() const;
983
984 // methods useable after spell is prepared
985 // accessors to the explicit targets of the spell
986 // explicit target - target selected by caster (player, game client, or script - DoCast(explicitTarget, ...), required for spell to be cast
987 // examples:
988 // -shadowstep - explicit target is the unit you want to go behind of
989 // -chain heal - explicit target is the unit to be healed first
990 // -holy nova/arcane explosion - explicit target = NULL because target you are selecting doesn't affect how spell targets are selected
991 // you can determine if spell requires explicit targets by dbc columns:
992 // - Targets - mask of explicit target types
993 // - ImplicitTargetXX set to TARGET_XXX_TARGET_YYY, _TARGET_ here means that explicit target is used by the effect, so spell needs one too
994
995 // returns: WorldLocation which was selected as a spell destination or NULL
996 WorldLocation const* GetExplTargetDest() const;
997
998 void SetExplTargetDest(WorldLocation const& loc);
999
1000 // returns: WorldObject which was selected as an explicit spell target or NULL if there's no target
1001 WorldObject* GetExplTargetWorldObject() const;
1002
1003 // returns: Unit which was selected as an explicit spell target or NULL if there's no target
1004 Unit* GetExplTargetUnit() const;
1005
1006 // returns: GameObject which was selected as an explicit spell target or NULL if there's no target
1007 GameObject* GetExplTargetGObj() const;
1008
1009 // returns: Item which was selected as an explicit spell target or NULL if there's no target
1010 Item* GetExplTargetItem() const;
1011
1012 // methods usable only after spell targets have been fully selected
1013 int64 GetUnitTargetCountForEffect(SpellEffIndex effect) const;
1014 int64 GetGameObjectTargetCountForEffect(SpellEffIndex effect) const;
1015 int64 GetItemTargetCountForEffect(SpellEffIndex effect) const;
1016 int64 GetCorpseTargetCountForEffect(SpellEffIndex effect) const;
1017
1018 // methods useable only during spell hit on target, or during spell launch on target:
1019 // returns: target of current effect if it was Unit otherwise NULL
1020 Unit* GetHitUnit() const;
1021 // returns: target of current effect if it was Creature otherwise NULL
1022 Creature* GetHitCreature() const;
1023 // returns: target of current effect if it was Player otherwise NULL
1024 Player* GetHitPlayer() const;
1025 // returns: target of current effect if it was Item otherwise NULL
1026 Item* GetHitItem() const;
1027 // returns: target of current effect if it was GameObject otherwise NULL
1028 GameObject* GetHitGObj() const;
1029 // returns: target of current effect if it was Corpse otherwise nullptr
1030 Corpse* GetHitCorpse() const;
1031 // returns: destination of current effect
1032 WorldLocation* GetHitDest() const;
1033 // setter/getter for for damage done by spell to target of spell hit
1034 // returns damage calculated before hit, and real dmg done after hit
1035 int32 GetHitDamage() const;
1036 void SetHitDamage(int32 damage);
1037 void PreventHitDamage() { SetHitDamage(0); }
1038 // setter/getter for for heal done by spell to target of spell hit
1039 // returns healing calculated before hit, and real dmg done after hit
1040 int32 GetHitHeal() const;
1041 void SetHitHeal(int32 heal);
1042 void PreventHitHeal() { SetHitHeal(0); }
1043 // returns: true if spell critically hits current HitUnit
1044 bool IsHitCrit() const;
1045 Spell* GetSpell() const { return m_spell; }
1046 // returns current spell hit target aura
1047 Aura* GetHitAura(bool dynObjAura = false) const;
1048 // prevents applying aura on current spell hit target
1049 void PreventHitAura();
1050
1051 // prevents effect execution on current spell hit target
1052 // including other effect/hit scripts
1053 // will not work on aura/damage/heal
1054 // will not work if effects were already handled
1055 void PreventHitEffect(SpellEffIndex effIndex);
1056
1057 // prevents default effect execution on current spell hit target
1058 // will not work on aura/damage/heal effects
1059 // will not work if effects were already handled
1060 void PreventHitDefaultEffect(SpellEffIndex effIndex);
1061
1062 // method available only in EffectHandler method
1063 SpellEffectInfo const& GetEffectInfo() const;
1064 int32 GetEffectValue() const;
1065 void SetEffectValue(int32 value);
1066 float GetEffectVariance() const;
1067 void SetEffectVariance(float variance);
1068
1069 // returns: cast item if present.
1070 Item* GetCastItem() const;
1071
1072 // Creates item. Calls Spell::DoCreateItem method.
1073 void CreateItem(uint32 itemId, ItemContext context);
1074
1075 // Returns SpellInfo from the spell that triggered the current one
1076 SpellInfo const* GetTriggeringSpell() const;
1077
1078 // finishes spellcast prematurely with selected error message
1079 void FinishCast(SpellCastResult result, int32* param1 = nullptr, int32* param2 = nullptr);
1080
1081 void SetCustomCastResultMessage(SpellCustomErrors result);
1082
1083 // returns desired cast difficulty for triggered spells
1084 Difficulty GetCastDifficulty() const;
1085};
1086
1087// AuraScript interface - enum used for runtime checks of script function calls
1089{
1111 // Spell Proc Hooks
1119 /*AURA_SCRIPT_HOOK_APPLY,
1120 AURA_SCRIPT_HOOK_REMOVE, */
1121};
1122/*
1123#define HOOK_AURA_EFFECT_START HOOK_AURA_EFFECT_APPLY
1124#define HOOK_AURA_EFFECT_END HOOK_AURA_EFFECT_CALC_SPELLMOD + 1
1125#define HOOK_AURA_EFFECT_COUNT HOOK_AURA_EFFECT_END - HOOK_AURA_EFFECT_START
1126*/
1128{
1129 // internal use classes & functions
1130 // DO NOT OVERRIDE THESE IN SCRIPTS
1131public:
1133 {
1134 public:
1136 {
1137 bool(AuraScript::* Member)(Unit* target);
1138 bool(*Static)(Unit* target);
1139 };
1140
1141 using SafeWrapperType = bool(*)(AuraScript* auraScript, Unit* target, AuraCheckAreaTargetFnType callImpl);
1142
1143 template<typename ScriptFunc>
1144 explicit CheckAreaTargetHandler(ScriptFunc handler)
1145 {
1146 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1147
1148 static_assert(sizeof(AuraCheckAreaTargetFnType) >= sizeof(ScriptFunc));
1149 static_assert(alignof(AuraCheckAreaTargetFnType) >= alignof(ScriptFunc));
1150
1151 if constexpr (!std::is_void_v<ScriptClass>)
1152 {
1153 static_assert(std::is_invocable_r_v<bool, ScriptFunc, ScriptClass, Unit*>,
1154 "CheckAreaTargetHandler signature must be \"bool CheckTarget(Unit* target)\"");
1155
1156 _callImpl = { .Member = reinterpret_cast<decltype(AuraCheckAreaTargetFnType::Member)>(handler) };
1157 _safeWrapper = [](AuraScript* auraScript, Unit* target, AuraCheckAreaTargetFnType callImpl) -> bool
1158 {
1159 return (static_cast<ScriptClass*>(auraScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(target);
1160 };
1161 }
1162 else
1163 {
1164 static_assert(std::is_invocable_r_v<bool, ScriptFunc, Unit*>,
1165 "CheckAreaTargetHandler signature must be \"static bool CheckTarget(Unit* target)\"");
1166
1167 _callImpl = { .Static = reinterpret_cast<decltype(AuraCheckAreaTargetFnType::Static)>(handler) };
1168 _safeWrapper = [](AuraScript* /*auraScript*/, Unit* target, AuraCheckAreaTargetFnType callImpl) -> bool
1169 {
1170 return reinterpret_cast<ScriptFunc>(callImpl.Static)(target);
1171 };
1172 }
1173 }
1174
1175 bool Call(AuraScript* auraScript, Unit* target) const
1176 {
1177 return _safeWrapper(auraScript, target, _callImpl);
1178 }
1179 private:
1182 };
1183
1185 {
1186 public:
1188 {
1189 void(AuraScript::* Member)(DispelInfo* dispelInfo);
1190 void(*Static)(DispelInfo* dispelInfo);
1191 };
1192
1193 using SafeWrapperType = void(*)(AuraScript* auraScript, DispelInfo* dispelInfo, AuraDispelFnType callImpl);
1194
1195 template<typename ScriptFunc>
1196 explicit AuraDispelHandler(ScriptFunc handler)
1197 {
1198 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1199
1200 static_assert(sizeof(AuraDispelFnType) >= sizeof(ScriptFunc));
1201 static_assert(alignof(AuraDispelFnType) >= alignof(ScriptFunc));
1202
1203 if constexpr (!std::is_void_v<ScriptClass>)
1204 {
1205 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, DispelInfo*>,
1206 "AuraDispelHandler signature must be \"void HandleDispel(DispelInfo* dispelInfo)\"");
1207
1208 _callImpl = { .Member = reinterpret_cast<decltype(AuraDispelFnType::Member)>(handler) };
1209 _safeWrapper = [](AuraScript* auraScript, DispelInfo* dispelInfo, AuraDispelFnType callImpl) -> void
1210 {
1211 return (static_cast<ScriptClass*>(auraScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(dispelInfo);
1212 };
1213 }
1214 else
1215 {
1216 static_assert(std::is_invocable_r_v<void, ScriptFunc, DispelInfo*>,
1217 "AuraDispelHandler signature must be \"static void HandleDispel(DispelInfo* dispelInfo)\"");
1218
1219 _callImpl = { .Static = reinterpret_cast<decltype(AuraDispelFnType::Static)>(handler) };
1220 _safeWrapper = [](AuraScript* /*auraScript*/, DispelInfo* dispelInfo, AuraDispelFnType callImpl) -> void
1221 {
1222 return reinterpret_cast<ScriptFunc>(callImpl.Static)(dispelInfo);
1223 };
1224 }
1225 }
1226
1227 void Call(AuraScript* auraScript, DispelInfo* dispelInfo) const
1228 {
1229 return _safeWrapper(auraScript, dispelInfo, _callImpl);
1230 }
1231 private:
1234 };
1235
1237 {
1238 public:
1240 {
1241 void(AuraScript::* Member)();
1242 void(*Static)();
1243 };
1244
1245 using SafeWrapperType = void(*)(AuraScript* auraScript, AuraHeartbeatFnType callImpl);
1246
1247 template<typename ScriptFunc>
1248 explicit AuraHeartbeatHandler(ScriptFunc handler)
1249 {
1250 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1251
1252 static_assert(sizeof(AuraHeartbeatFnType) >= sizeof(ScriptFunc));
1253 static_assert(alignof(AuraHeartbeatFnType) >= alignof(ScriptFunc));
1254
1255 if constexpr (!std::is_void_v<ScriptClass>)
1256 {
1257 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass>,
1258 "AuraHeartbeat signature must be \"void HandleHeartbeat()\"");
1259
1260 _callImpl = { .Member = reinterpret_cast<decltype(AuraHeartbeatFnType::Member)>(handler) };
1261 _safeWrapper = [](AuraScript* auraScript, AuraHeartbeatFnType callImpl) -> void
1262 {
1263 return (static_cast<ScriptClass*>(auraScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))();
1264 };
1265 }
1266 else
1267 {
1268 static_assert(std::is_invocable_r_v<void, ScriptFunc>,
1269 "AuraHeartbeatHandler signature must be \"static void HandleHeartbeat()\"");
1270
1271 _callImpl = { .Static = reinterpret_cast<decltype(AuraHeartbeatFnType::Static)>(handler) };
1272 _safeWrapper = [](AuraScript* /*auraScript*/, AuraHeartbeatFnType callImpl) -> void
1273 {
1274 return reinterpret_cast<ScriptFunc>(callImpl.Static)();
1275 };
1276 }
1277 }
1278
1279 void Call(AuraScript* auraScript) const
1280 {
1281 return _safeWrapper(auraScript, _callImpl);
1282 }
1283 private:
1286 };
1287
1289 {
1290 public:
1291 EffectBase(uint8 effIndex, uint16 auraType);
1292 EffectBase(EffectBase const& right) = delete;
1293 EffectBase(EffectBase&& right) noexcept;
1294 EffectBase& operator=(EffectBase const& right) = delete;
1295 EffectBase& operator=(EffectBase&& right) noexcept;
1296 virtual ~EffectBase();
1297 std::string ToString() const;
1298 bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex) const override;
1299 private:
1301 };
1302
1304 {
1305 public:
1307 {
1308 void(AuraScript::* Member)(AuraEffect const* aurEff);
1309 void(*Static)(AuraEffect const* aurEff);
1310 };
1311
1312 using SafeWrapperType = void(*)(AuraScript* auraScript, AuraEffect const* aurEff, AuraEffectPeriodicFnType callImpl);
1313
1314 template<typename ScriptFunc>
1315 explicit EffectPeriodicHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1316 : EffectBase(effIndex, auraType)
1317 {
1318 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1319
1320 static_assert(sizeof(AuraEffectPeriodicFnType) >= sizeof(ScriptFunc));
1321 static_assert(alignof(AuraEffectPeriodicFnType) >= alignof(ScriptFunc));
1322
1323 if constexpr (!std::is_void_v<ScriptClass>)
1324 {
1325 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, AuraEffect const*>,
1326 "EffectPeriodicHandler signature must be \"void HandlePeriodic(AuraEffect const* aurEff)\"");
1327
1328 _callImpl = { .Member = reinterpret_cast<decltype(AuraEffectPeriodicFnType::Member)>(handler) };
1329 _safeWrapper = [](AuraScript* auraScript, AuraEffect const* aurEff, AuraEffectPeriodicFnType callImpl) -> void
1330 {
1331 return (static_cast<ScriptClass*>(auraScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(aurEff);
1332 };
1333 }
1334 else
1335 {
1336 static_assert(std::is_invocable_r_v<void, ScriptFunc, AuraEffect const*>,
1337 "EffectPeriodicHandler signature must be \"static void HandlePeriodic(AuraEffect const* aurEff)\"");
1338
1339 _callImpl = { .Static = reinterpret_cast<decltype(AuraEffectPeriodicFnType::Static)>(handler) };
1340 _safeWrapper = [](AuraScript* /*auraScript*/, AuraEffect const* aurEff, AuraEffectPeriodicFnType callImpl) -> void
1341 {
1342 return reinterpret_cast<ScriptFunc>(callImpl.Static)(aurEff);
1343 };
1344 }
1345 }
1346
1347 void Call(AuraScript* auraScript, AuraEffect const* aurEff) const
1348 {
1349 return _safeWrapper(auraScript, aurEff, _callImpl);
1350 }
1351 private:
1354 };
1355
1357 {
1358 public:
1360 {
1361 void(AuraScript::* Member)(AuraEffect* aurEff);
1362 void(*Static)(AuraEffect* aurEff);
1363 };
1364
1365 using SafeWrapperType = void(*)(AuraScript* auraScript, AuraEffect* aurEff, AuraEffectUpdatePeriodicFnType callImpl);
1366
1367 template<typename ScriptFunc>
1368 explicit EffectUpdatePeriodicHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1369 : EffectBase(effIndex, auraType)
1370 {
1371 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1372
1373 static_assert(sizeof(AuraEffectUpdatePeriodicFnType) >= sizeof(ScriptFunc));
1374 static_assert(alignof(AuraEffectUpdatePeriodicFnType) >= alignof(ScriptFunc));
1375
1376 if constexpr (!std::is_void_v<ScriptClass>)
1377 {
1378 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, AuraEffect*>,
1379 "EffectUpdatePeriodicHandler signature must be \"void HandleUpdatePeriodic(AuraEffect* aurEff)\"");
1380
1381 _callImpl = { .Member = reinterpret_cast<decltype(AuraEffectUpdatePeriodicFnType::Member)>(handler) };
1382 _safeWrapper = [](AuraScript* auraScript, AuraEffect* aurEff, AuraEffectUpdatePeriodicFnType callImpl) -> void
1383 {
1384 return (static_cast<ScriptClass*>(auraScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(aurEff);
1385 };
1386 }
1387 else
1388 {
1389 static_assert(std::is_invocable_r_v<void, ScriptFunc, AuraEffect*>,
1390 "EffectUpdatePeriodicHandler signature must be \"static void HandleUpdatePeriodic(AuraEffect* aurEff)\"");
1391
1392 _callImpl = { .Static = reinterpret_cast<decltype(AuraEffectUpdatePeriodicFnType::Static)>(handler) };
1393 _safeWrapper = [](AuraScript* /*auraScript*/, AuraEffect* aurEff, AuraEffectUpdatePeriodicFnType callImpl) -> void
1394 {
1395 return reinterpret_cast<ScriptFunc>(callImpl.Static)(aurEff);
1396 };
1397 }
1398 }
1399
1400 void Call(AuraScript* auraScript, AuraEffect* aurEff) const
1401 {
1402 return _safeWrapper(auraScript, aurEff, _callImpl);
1403 }
1404 private:
1407 };
1408
1410 {
1411 public:
1413 {
1414 void(AuraScript::* Member)(AuraEffect const* aurEff, int32& amount, bool& canBeRecalculated);
1415 void(*Static)(AuraEffect const* aurEff, int32& amount, bool& canBeRecalculated);
1416 };
1417
1418 using SafeWrapperType = void(*)(AuraScript* auraScript, AuraEffect const* aurEff, int32& amount, bool& canBeRecalculated, AuraEffectCalcAmountFnType callImpl);
1419
1420 template<typename ScriptFunc>
1421 explicit EffectCalcAmountHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1422 : EffectBase(effIndex, auraType)
1423 {
1424 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1425
1426 static_assert(sizeof(AuraEffectCalcAmountFnType) >= sizeof(ScriptFunc));
1427 static_assert(alignof(AuraEffectCalcAmountFnType) >= alignof(ScriptFunc));
1428
1429 if constexpr (!std::is_void_v<ScriptClass>)
1430 {
1431 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, AuraEffect const*, int32&, bool&>,
1432 "EffectCalcAmountHandler signature must be \"void CalcAmount(AuraEffect const* aurEff, int32& amount, bool& canBeRecalculated)\"");
1433
1434 _callImpl = { .Member = reinterpret_cast<decltype(AuraEffectCalcAmountFnType::Member)>(handler) };
1435 _safeWrapper = [](AuraScript* auraScript, AuraEffect const* aurEff, int32& amount, bool& canBeRecalculated, AuraEffectCalcAmountFnType callImpl) -> void
1436 {
1437 return (static_cast<ScriptClass*>(auraScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(aurEff, amount, canBeRecalculated);
1438 };
1439 }
1440 else
1441 {
1442 static_assert(std::is_invocable_r_v<void, ScriptFunc, AuraEffect const*, int32&, bool&>,
1443 "EffectCalcAmountHandler signature must be \"static void CalcAmount(AuraEffect const* aurEff, int32& amount, bool& canBeRecalculated)\"");
1444
1445 _callImpl = { .Static = reinterpret_cast<decltype(AuraEffectCalcAmountFnType::Static)>(handler) };
1446 _safeWrapper = [](AuraScript* /*auraScript*/, AuraEffect const* aurEff, int32& amount, bool& canBeRecalculated, AuraEffectCalcAmountFnType callImpl) -> void
1447 {
1448 return reinterpret_cast<ScriptFunc>(callImpl.Static)(aurEff, amount, canBeRecalculated);
1449 };
1450 }
1451 }
1452
1453 void Call(AuraScript* auraScript, AuraEffect const* aurEff, int32& amount, bool& canBeRecalculated) const
1454 {
1455 return _safeWrapper(auraScript, aurEff, amount, canBeRecalculated, _callImpl);
1456 }
1457 private:
1460 };
1461
1463 {
1464 public:
1466 {
1467 void(AuraScript::* Member)(AuraEffect const* aurEff, bool& isPeriodic, int32& periodicTimer);
1468 void(*Static)(AuraEffect const* aurEff, bool& isPeriodic, int32& periodicTimer);
1469 };
1470
1471 using SafeWrapperType = void(*)(AuraScript* auraScript, AuraEffect const* aurEff, bool& isPeriodic, int32& periodicTimer, AuraEffectCalcPeriodicFnType callImpl);
1472
1473 template<typename ScriptFunc>
1474 explicit EffectCalcPeriodicHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1475 : EffectBase(effIndex, auraType)
1476 {
1477 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1478
1479 static_assert(sizeof(AuraEffectCalcPeriodicFnType) >= sizeof(ScriptFunc));
1480 static_assert(alignof(AuraEffectCalcPeriodicFnType) >= alignof(ScriptFunc));
1481
1482 if constexpr (!std::is_void_v<ScriptClass>)
1483 {
1484 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, AuraEffect const*, bool&, int32&>,
1485 "EffectCalcPeriodicHandler signature must be \"void CalcPeriodic(AuraEffect const* aurEff, bool& isPeriodic, int32& periodicTimer)\"");
1486
1487 _callImpl = { .Member = reinterpret_cast<decltype(AuraEffectCalcPeriodicFnType::Member)>(handler) };
1488 _safeWrapper = [](AuraScript* auraScript, AuraEffect const* aurEff, bool& isPeriodic, int32& periodicTimer, AuraEffectCalcPeriodicFnType callImpl) -> void
1489 {
1490 return (static_cast<ScriptClass*>(auraScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(aurEff, isPeriodic, periodicTimer);
1491 };
1492 }
1493 else
1494 {
1495 static_assert(std::is_invocable_r_v<void, ScriptFunc, AuraEffect const*, bool&, int32&>,
1496 "EffectCalcPeriodicHandler signature must be \"static void CalcPeriodic(AuraEffect const* aurEff, bool& isPeriodic, int32& periodicTimer)\"");
1497
1498 _callImpl = { .Static = reinterpret_cast<decltype(AuraEffectCalcPeriodicFnType::Static)>(handler) };
1499 _safeWrapper = [](AuraScript* /*auraScript*/, AuraEffect const* aurEff, bool& isPeriodic, int32& periodicTimer, AuraEffectCalcPeriodicFnType callImpl) -> void
1500 {
1501 return reinterpret_cast<ScriptFunc>(callImpl.Static)(aurEff, isPeriodic, periodicTimer);
1502 };
1503 }
1504 }
1505
1506 void Call(AuraScript* auraScript, AuraEffect const* aurEff, bool& isPeriodic, int32& periodicTimer) const
1507 {
1508 return _safeWrapper(auraScript, aurEff, isPeriodic, periodicTimer, _callImpl);
1509 }
1510 private:
1513 };
1514
1516 {
1517 public:
1519 {
1520 void(AuraScript::* Member)(AuraEffect const* aurEff, SpellModifier*& spellMod);
1521 void(*Static)(AuraEffect const* aurEff, SpellModifier*& spellMod);
1522 };
1523
1524 using SafeWrapperType = void(*)(AuraScript* auraScript, AuraEffect const* aurEff, SpellModifier*& spellMod, AuraEffectCalcSpellModFnType callImpl);
1525
1526 template<typename ScriptFunc>
1527 explicit EffectCalcSpellModHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1528 : EffectBase(effIndex, auraType)
1529 {
1530 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1531
1532 static_assert(sizeof(AuraEffectCalcSpellModFnType) >= sizeof(ScriptFunc));
1533 static_assert(alignof(AuraEffectCalcSpellModFnType) >= alignof(ScriptFunc));
1534
1535 if constexpr (!std::is_void_v<ScriptClass>)
1536 {
1537 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, AuraEffect const*, SpellModifier*&>,
1538 "EffectCalcSpellModHandler signature must be \"void CalcSpellMod(AuraEffect const* aurEff, SpellModifier*& spellMod)\"");
1539
1540 _callImpl = { .Member = reinterpret_cast<decltype(AuraEffectCalcSpellModFnType::Member)>(handler) };
1541 _safeWrapper = [](AuraScript* auraScript, AuraEffect const* aurEff, SpellModifier*& spellMod, AuraEffectCalcSpellModFnType callImpl) -> void
1542 {
1543 return (static_cast<ScriptClass*>(auraScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(aurEff, spellMod);
1544 };
1545 }
1546 else
1547 {
1548 static_assert(std::is_invocable_r_v<void, ScriptFunc, AuraEffect const*, SpellModifier*&>,
1549 "EffectCalcSpellModHandler signature must be \"static void CalcSpellMod(AuraEffect const* aurEff, SpellModifier*& spellMod)\"");
1550
1551 _callImpl = { .Static = reinterpret_cast<decltype(AuraEffectCalcSpellModFnType::Static)>(handler) };
1552 _safeWrapper = [](AuraScript* /*auraScript*/, AuraEffect const* aurEff, SpellModifier*& spellMod, AuraEffectCalcSpellModFnType callImpl) -> void
1553 {
1554 return reinterpret_cast<ScriptFunc>(callImpl.Static)(aurEff, spellMod);
1555 };
1556 }
1557 }
1558
1559 void Call(AuraScript* auraScript, AuraEffect const* aurEff, SpellModifier*& spellMod) const
1560 {
1561 return _safeWrapper(auraScript, aurEff, spellMod, _callImpl);
1562 }
1563 private:
1566 };
1567
1569 {
1570 public:
1572 {
1573 void(AuraScript::* Member)(AuraEffect const* aurEff, Unit const* victim, float& critChance);
1574 void(*Static)(AuraEffect const* aurEff, Unit const* victim, float& critChance);
1575 };
1576
1577 using SafeWrapperType = void(*)(AuraScript* auraScript, AuraEffect const* aurEff, Unit const* victim, float& critChance, AuraEffectCalcCritChanceFnType callImpl);
1578
1579 template<typename ScriptFunc>
1580 explicit EffectCalcCritChanceHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1581 : EffectBase(effIndex, auraType)
1582 {
1583 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1584
1585 static_assert(sizeof(AuraEffectCalcCritChanceFnType) >= sizeof(ScriptFunc));
1586 static_assert(alignof(AuraEffectCalcCritChanceFnType) >= alignof(ScriptFunc));
1587
1588 if constexpr (!std::is_void_v<ScriptClass>)
1589 {
1590 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, AuraEffect const*, Unit const*, float&>,
1591 "EffectCalcCritChanceHandler signature must be \"void CalcCritChance(AuraEffect const* aurEff, Unit const* victim, float& critChance)\"");
1592
1593 _callImpl = { .Member = reinterpret_cast<decltype(AuraEffectCalcCritChanceFnType::Member)>(handler) };
1594 _safeWrapper = [](AuraScript* auraScript, AuraEffect const* aurEff, Unit const* victim, float& critChance, AuraEffectCalcCritChanceFnType callImpl) -> void
1595 {
1596 return (static_cast<ScriptClass*>(auraScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(aurEff, victim, critChance);
1597 };
1598 }
1599 else
1600 {
1601 static_assert(std::is_invocable_r_v<void, ScriptFunc, AuraEffect const*, Unit const*, float&>,
1602 "EffectCalcCritChanceHandler signature must be \"static void CalcCritChance(AuraEffect const* aurEff, Unit const* victim, float& critChance)\"");
1603
1604 _callImpl = { .Static = reinterpret_cast<decltype(AuraEffectCalcCritChanceFnType::Static)>(handler) };
1605 _safeWrapper = [](AuraScript* /*auraScript*/, AuraEffect const* aurEff, Unit const* victim, float& critChance, AuraEffectCalcCritChanceFnType callImpl) -> void
1606 {
1607 return reinterpret_cast<ScriptFunc>(callImpl.Static)(aurEff, victim, critChance);
1608 };
1609 }
1610 }
1611
1612 void Call(AuraScript* auraScript, AuraEffect const* aurEff, Unit const* victim, float& critChance) const
1613 {
1614 return _safeWrapper(auraScript, aurEff, victim, critChance, _callImpl);
1615 }
1616 private:
1619 };
1620
1622 {
1623 public:
1625 {
1626 void(AuraScript::* Member)(AuraEffect const* aurEff, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod);
1627 void(*Static)(AuraEffect const* aurEff, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod);
1628 };
1629
1630 using SafeWrapperType = void(*)(AuraScript* auraScript, AuraEffect const* aurEff, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod, AuraEffectDamageAndHealingCalcFnType callImpl);
1631
1632 template<typename ScriptFunc>
1633 explicit EffectCalcDamageAndHealingHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1634 : EffectBase(effIndex, auraType)
1635 {
1636 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1637
1638 static_assert(sizeof(AuraEffectDamageAndHealingCalcFnType) >= sizeof(ScriptFunc));
1639 static_assert(alignof(AuraEffectDamageAndHealingCalcFnType) >= alignof(ScriptFunc));
1640
1641 if constexpr (!std::is_void_v<ScriptClass>)
1642 {
1643 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, AuraEffect const*, Unit*, int32&, int32&, float&>,
1644 "EffectCalcDamageAndHealingHandler signature must be \"void CalcDamageAndHealing(AuraEffect const* aurEff, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod)\"");
1645
1646 _callImpl = { .Member = reinterpret_cast<decltype(AuraEffectDamageAndHealingCalcFnType::Member)>(handler) };
1647 _safeWrapper = [](AuraScript* auraScript, AuraEffect const* aurEff, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod, AuraEffectDamageAndHealingCalcFnType callImpl) -> void
1648 {
1649 return (static_cast<ScriptClass*>(auraScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(aurEff, victim, damageOrHealing, flatMod, pctMod);
1650 };
1651 }
1652 else
1653 {
1654 static_assert(std::is_invocable_r_v<void, ScriptFunc, AuraEffect const*, Unit*, int32&, int32&, float&>,
1655 "EffectCalcDamageAndHealingHandler signature must be \"static void CalcDamageAndHealing(AuraEffect const* aurEff, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod)\"");
1656
1657 _callImpl = { .Static = reinterpret_cast<decltype(AuraEffectDamageAndHealingCalcFnType::Static)>(handler) };
1658 _safeWrapper = [](AuraScript* /*auraScript*/, AuraEffect const* aurEff, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod, AuraEffectDamageAndHealingCalcFnType callImpl) -> void
1659 {
1660 return reinterpret_cast<ScriptFunc>(callImpl.Static)(aurEff, victim, damageOrHealing, flatMod, pctMod);
1661 };
1662 }
1663 }
1664
1665 void Call(AuraScript* auraScript, AuraEffect const* aurEff, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod) const
1666 {
1667 return _safeWrapper(auraScript, aurEff, victim, damageOrHealing, flatMod, pctMod, _callImpl);
1668 }
1669 private:
1672 };
1673
1674 class EffectApplyHandler final : public EffectBase
1675 {
1676 public:
1678 {
1679 void(AuraScript::* Member)(AuraEffect const* aurEff, AuraEffectHandleModes mode);
1680 void(*Static)(AuraEffect const* aurEff, AuraEffectHandleModes mode);
1681 };
1682
1683 using SafeWrapperType = void(*)(AuraScript* auraScript, AuraEffect const* aurEff, AuraEffectHandleModes mode, AuraEffectApplicationModeFnType callImpl);
1684
1685 template<typename ScriptFunc>
1686 explicit EffectApplyHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType, AuraEffectHandleModes mode)
1687 : EffectBase(effIndex, auraType), _mode(mode)
1688 {
1689 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1690
1691 static_assert(sizeof(AuraEffectApplicationModeFnType) >= sizeof(ScriptFunc));
1692 static_assert(alignof(AuraEffectApplicationModeFnType) >= alignof(ScriptFunc));
1693
1694 if constexpr (!std::is_void_v<ScriptClass>)
1695 {
1696 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, AuraEffect const*, AuraEffectHandleModes>,
1697 "EffectApplyHandler signature must be \"void HandleApplyOrRemove(AuraEffect const* aurEff, AuraEffectHandleModes mode)\"");
1698
1699 _callImpl = { .Member = reinterpret_cast<decltype(AuraEffectApplicationModeFnType::Member)>(handler) };
1700 _safeWrapper = [](AuraScript* auraScript, AuraEffect const* aurEff, AuraEffectHandleModes mode, AuraEffectApplicationModeFnType callImpl) -> void
1701 {
1702 return (static_cast<ScriptClass*>(auraScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(aurEff, mode);
1703 };
1704 }
1705 else
1706 {
1707 static_assert(std::is_invocable_r_v<void, ScriptFunc, AuraEffect const*, AuraEffectHandleModes>,
1708 "EffectApplyHandler signature must be \"static void HandleApplyOrRemove(AuraEffect const* aurEff, AuraEffectHandleModes mode)\"");
1709
1710 _callImpl = { .Static = reinterpret_cast<decltype(AuraEffectApplicationModeFnType::Static)>(handler) };
1711 _safeWrapper = [](AuraScript* /*auraScript*/, AuraEffect const* aurEff, AuraEffectHandleModes mode, AuraEffectApplicationModeFnType callImpl) -> void
1712 {
1713 return reinterpret_cast<ScriptFunc>(callImpl.Static)(aurEff, mode);
1714 };
1715 }
1716 }
1717
1718 void Call(AuraScript* auraScript, AuraEffect const* aurEff, AuraEffectHandleModes mode) const
1719 {
1720 if (!(_mode & mode))
1721 return;
1722
1723 return _safeWrapper(auraScript, aurEff, mode, _callImpl);
1724 }
1725 private:
1729 };
1730
1731 class EffectAbsorbHandler final : public EffectBase
1732 {
1733 public:
1735 {
1736 void(AuraScript::* Member)(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount);
1737 void(*Static)(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount);
1738 };
1739
1740 using SafeWrapperType = void(*)(AuraScript* auraScript, AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount, AuraEffectAbsorbFnType callImpl);
1741
1742 template<typename ScriptFunc>
1743 explicit EffectAbsorbHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1744 : EffectBase(effIndex, auraType)
1745 {
1746 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1747
1748 static_assert(sizeof(AuraEffectAbsorbFnType) >= sizeof(ScriptFunc));
1749 static_assert(alignof(AuraEffectAbsorbFnType) >= alignof(ScriptFunc));
1750
1751 if constexpr (!std::is_void_v<ScriptClass>)
1752 {
1753 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, AuraEffect*, DamageInfo&, uint32&>,
1754 "EffectAbsorbHandler signature must be \"void HandleAbsorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount)\"");
1755
1756 _callImpl = { .Member = reinterpret_cast<decltype(AuraEffectAbsorbFnType::Member)>(handler) };
1757 _safeWrapper = [](AuraScript* auraScript, AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount, AuraEffectAbsorbFnType callImpl) -> void
1758 {
1759 return (static_cast<ScriptClass*>(auraScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(aurEff, dmgInfo, absorbAmount);
1760 };
1761 }
1762 else
1763 {
1764 static_assert(std::is_invocable_r_v<void, ScriptFunc, AuraEffect*, DamageInfo&, uint32&>,
1765 "EffectAbsorbHandler signature must be \"static void HandleAbsorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount)\"");
1766
1767 _callImpl = { .Static = reinterpret_cast<decltype(AuraEffectAbsorbFnType::Static)>(handler) };
1768 _safeWrapper = [](AuraScript* /*auraScript*/, AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount, AuraEffectAbsorbFnType callImpl) -> void
1769 {
1770 return reinterpret_cast<ScriptFunc>(callImpl.Static)(aurEff, dmgInfo, absorbAmount);
1771 };
1772 }
1773 }
1774
1775 void Call(AuraScript* auraScript, AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount) const
1776 {
1777 return _safeWrapper(auraScript, aurEff, dmgInfo, absorbAmount, _callImpl);
1778 }
1779 private:
1782 };
1783
1785 {
1786 public:
1788 {
1789 void(AuraScript::* Member)(AuraEffect* aurEff, HealInfo& healInfo, uint32& absorbAmount);
1790 void(*Static)(AuraEffect* aurEff, HealInfo& healInfo, uint32& absorbAmount);
1791 };
1792
1793 using SafeWrapperType = void(*)(AuraScript* auraScript, AuraEffect* aurEff, HealInfo& healInfo, uint32& absorbAmount, AuraEffectAbsorbHealFnType callImpl);
1794
1795 template<typename ScriptFunc>
1796 explicit EffectAbsorbHealHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1797 : EffectBase(effIndex, auraType)
1798 {
1799 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1800
1801 static_assert(sizeof(AuraEffectAbsorbHealFnType) >= sizeof(ScriptFunc));
1802 static_assert(alignof(AuraEffectAbsorbHealFnType) >= alignof(ScriptFunc));
1803
1804 if constexpr (!std::is_void_v<ScriptClass>)
1805 {
1806 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, AuraEffect*, HealInfo&, uint32&>,
1807 "EffectAbsorbHealHandler signature must be \"void HandleAbsorb(AuraEffect* aurEff, HealInfo& healInfo, uint32& absorbAmount)\"");
1808
1809 _callImpl = { .Member = reinterpret_cast<decltype(AuraEffectAbsorbHealFnType::Member)>(handler) };
1810 _safeWrapper = [](AuraScript* auraScript, AuraEffect* aurEff, HealInfo& healInfo, uint32& absorbAmount, AuraEffectAbsorbHealFnType callImpl) -> void
1811 {
1812 return (static_cast<ScriptClass*>(auraScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(aurEff, healInfo, absorbAmount);
1813 };
1814 }
1815 else
1816 {
1817 static_assert(std::is_invocable_r_v<void, ScriptFunc, AuraEffect*, HealInfo&, uint32&>,
1818 "EffectAbsorbHealHandler signature must be \"static void HandleAbsorb(AuraEffect* aurEff, HealInfo& healInfo, uint32& absorbAmount)\"");
1819
1820 _callImpl = { .Static = reinterpret_cast<decltype(AuraEffectAbsorbHealFnType::Static)>(handler) };
1821 _safeWrapper = [](AuraScript* /*auraScript*/, AuraEffect* aurEff, HealInfo& healInfo, uint32& absorbAmount, AuraEffectAbsorbHealFnType callImpl) -> void
1822 {
1823 return reinterpret_cast<ScriptFunc>(callImpl.Static)(aurEff, healInfo, absorbAmount);
1824 };
1825 }
1826 }
1827
1828 void Call(AuraScript* auraScript, AuraEffect* aurEff, HealInfo& healInfo, uint32& absorbAmount) const
1829 {
1830 return _safeWrapper(auraScript, aurEff, healInfo, absorbAmount, _callImpl);
1831 }
1832 private:
1835 };
1836
1838 {
1839 public:
1841 {
1842 bool(AuraScript::* Member)(ProcEventInfo& eventInfo);
1843 bool(*Static)(ProcEventInfo& eventInfo);
1844 };
1845
1846 using SafeWrapperType = bool(*)(AuraScript* auraScript, ProcEventInfo& eventInfo, AuraCheckProcFnType callImpl);
1847
1848 template<typename ScriptFunc>
1849 explicit CheckProcHandler(ScriptFunc handler)
1850 {
1851 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1852
1853 static_assert(sizeof(AuraCheckProcFnType) >= sizeof(ScriptFunc));
1854 static_assert(alignof(AuraCheckProcFnType) >= alignof(ScriptFunc));
1855
1856 if constexpr (!std::is_void_v<ScriptClass>)
1857 {
1858 static_assert(std::is_invocable_r_v<bool, ScriptFunc, ScriptClass, ProcEventInfo&>,
1859 "CheckProcHandler signature must be \"bool CheckProc(ProcEventInfo& eventInfo)\"");
1860
1861 _callImpl = { .Member = reinterpret_cast<decltype(AuraCheckProcFnType::Member)>(handler) };
1862 _safeWrapper = [](AuraScript* auraScript, ProcEventInfo& eventInfo, AuraCheckProcFnType callImpl) -> bool
1863 {
1864 return (static_cast<ScriptClass*>(auraScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(eventInfo);
1865 };
1866 }
1867 else
1868 {
1869 static_assert(std::is_invocable_r_v<bool, ScriptFunc, ProcEventInfo&>,
1870 "CheckProcHandler signature must be \"static bool CheckProc(ProcEventInfo& eventInfo)\"");
1871
1872 _callImpl = { .Static = reinterpret_cast<decltype(AuraCheckProcFnType::Static)>(handler) };
1873 _safeWrapper = [](AuraScript* /*auraScript*/, ProcEventInfo& eventInfo, AuraCheckProcFnType callImpl) -> bool
1874 {
1875 return reinterpret_cast<ScriptFunc>(callImpl.Static)(eventInfo);
1876 };
1877 }
1878 }
1879
1880 bool Call(AuraScript* auraScript, ProcEventInfo& eventInfo) const
1881 {
1882 return _safeWrapper(auraScript, eventInfo, _callImpl);
1883 }
1884 private:
1887 };
1888
1890 {
1891 public:
1893 {
1894 bool(AuraScript::* Member)(AuraEffect const* aurEff, ProcEventInfo& eventInfo);
1895 bool(*Static)(AuraEffect const* aurEff, ProcEventInfo& eventInfo);
1896 };
1897
1898 using SafeWrapperType = bool(*)(AuraScript* auraScript, AuraEffect const* aurEff, ProcEventInfo& eventInfo, AuraCheckEffectProcFnType callImpl);
1899
1900 template<typename ScriptFunc>
1901 explicit CheckEffectProcHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
1902 : EffectBase(effIndex, auraType)
1903 {
1904 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1905
1906 static_assert(sizeof(AuraCheckEffectProcFnType) >= sizeof(ScriptFunc));
1907 static_assert(alignof(AuraCheckEffectProcFnType) >= alignof(ScriptFunc));
1908
1909 if constexpr (!std::is_void_v<ScriptClass>)
1910 {
1911 static_assert(std::is_invocable_r_v<bool, ScriptFunc, ScriptClass, AuraEffect const*, ProcEventInfo&>,
1912 "CheckEffectProcHandler signature must be \"bool CheckProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)\"");
1913
1914 _callImpl = { .Member = reinterpret_cast<decltype(AuraCheckEffectProcFnType::Member)>(handler) };
1915 _safeWrapper = [](AuraScript* auraScript, AuraEffect const* aurEff, ProcEventInfo& eventInfo, AuraCheckEffectProcFnType callImpl) -> bool
1916 {
1917 return (static_cast<ScriptClass*>(auraScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(aurEff, eventInfo);
1918 };
1919 }
1920 else
1921 {
1922 static_assert(std::is_invocable_r_v<bool, ScriptFunc, AuraEffect const*, ProcEventInfo&>,
1923 "CheckEffectProcHandler signature must be \"static bool CheckProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)\"");
1924
1925 _callImpl = { .Static = reinterpret_cast<decltype(AuraCheckEffectProcFnType::Static)>(handler) };
1926 _safeWrapper = [](AuraScript* /*auraScript*/, AuraEffect const* aurEff, ProcEventInfo& eventInfo, AuraCheckEffectProcFnType callImpl) -> bool
1927 {
1928 return reinterpret_cast<ScriptFunc>(callImpl.Static)(aurEff, eventInfo);
1929 };
1930 }
1931 }
1932
1933 bool Call(AuraScript* auraScript, AuraEffect const* aurEff, ProcEventInfo& eventInfo) const
1934 {
1935 return _safeWrapper(auraScript, aurEff, eventInfo, _callImpl);
1936 }
1937 private:
1940 };
1941
1943 {
1944 public:
1946 {
1947 void(AuraScript::* Member)(ProcEventInfo& eventInfo);
1948 void(*Static)(ProcEventInfo& eventInfo);
1949 };
1950
1951 using SafeWrapperType = void(*)(AuraScript* auraScript, ProcEventInfo& eventInfo, AuraProcFnType callImpl);
1952
1953 template<typename ScriptFunc>
1954 explicit AuraProcHandler(ScriptFunc handler)
1955 {
1956 using ScriptClass = GetScriptClass_t<ScriptFunc>;
1957
1958 static_assert(sizeof(AuraProcFnType) >= sizeof(ScriptFunc));
1959 static_assert(alignof(AuraProcFnType) >= alignof(ScriptFunc));
1960
1961 if constexpr (!std::is_void_v<ScriptClass>)
1962 {
1963 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, ProcEventInfo&>,
1964 "AuraProcHandler signature must be \"void HandleProc(ProcEventInfo& eventInfo)\"");
1965
1966 _callImpl = { .Member = reinterpret_cast<decltype(AuraProcFnType::Member)>(handler) };
1967 _safeWrapper = [](AuraScript* auraScript, ProcEventInfo& eventInfo, AuraProcFnType callImpl) -> void
1968 {
1969 return (static_cast<ScriptClass*>(auraScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(eventInfo);
1970 };
1971 }
1972 else
1973 {
1974 static_assert(std::is_invocable_r_v<void, ScriptFunc, ProcEventInfo&>,
1975 "AuraProcHandler signature must be \"static void HandleProc(ProcEventInfo& eventInfo)\"");
1976
1977 _callImpl = { .Member = reinterpret_cast<decltype(AuraProcFnType::Member)>(handler) };
1978 _safeWrapper = [](AuraScript* /*auraScript*/, ProcEventInfo& eventInfo, AuraProcFnType callImpl) -> void
1979 {
1980 return reinterpret_cast<ScriptFunc>(callImpl.Member)(eventInfo);
1981 };
1982 }
1983 }
1984
1985 void Call(AuraScript* auraScript, ProcEventInfo& eventInfo) const
1986 {
1987 return _safeWrapper(auraScript, eventInfo, _callImpl);
1988 }
1989 private:
1992 };
1993
1994 class EffectProcHandler final : public EffectBase
1995 {
1996 public:
1998 {
1999 void(AuraScript::* Member)(AuraEffect* aurEff, ProcEventInfo& eventInfo);
2000 void(*Static)(AuraEffect* aurEff, ProcEventInfo& eventInfo);
2001 };
2002
2003 using SafeWrapperType = void (*)(AuraScript* auraScript, AuraEffect* aurEff, ProcEventInfo& eventInfo, AuraEffectProcFnType callImpl);
2004
2005 template<typename ScriptFunc>
2006 explicit EffectProcHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
2007 : EffectBase(effIndex, auraType)
2008 {
2009 using ScriptClass = GetScriptClass_t<ScriptFunc>;
2010
2011 static_assert(sizeof(AuraEffectProcFnType) >= sizeof(ScriptFunc));
2012 static_assert(alignof(AuraEffectProcFnType) >= alignof(ScriptFunc));
2013
2014 if constexpr (!std::is_void_v<ScriptClass>)
2015 {
2016 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, AuraEffect*, ProcEventInfo&>,
2017 "EffectProcHandler signature must be \"void HandleProc(AuraEffect* aurEff, ProcEventInfo& eventInfo)\"");
2018
2019 _callImpl = { .Member = reinterpret_cast<decltype(AuraEffectProcFnType::Member)>(handler) };
2020 _safeWrapper = [](AuraScript* auraScript, AuraEffect* aurEff, ProcEventInfo& eventInfo, AuraEffectProcFnType callImpl) -> void
2021 {
2022 return (static_cast<ScriptClass*>(auraScript)->*reinterpret_cast<ScriptFunc>(callImpl.Member))(aurEff, eventInfo);
2023 };
2024 }
2025 else
2026 {
2027 static_assert(std::is_invocable_r_v<void, ScriptFunc, AuraEffect*, ProcEventInfo&>,
2028 "EffectProcHandler signature must be \"static void HandleProc(AuraEffect* aurEff, ProcEventInfo& eventInfo)\"");
2029
2030 _callImpl = { .Static = reinterpret_cast<decltype(AuraEffectProcFnType::Static)>(handler) };
2031 _safeWrapper = [](AuraScript* /*auraScript*/, AuraEffect* aurEff, ProcEventInfo& eventInfo, AuraEffectProcFnType callImpl) -> void
2032 {
2033 return reinterpret_cast<ScriptFunc>(callImpl.Static)(aurEff, eventInfo);
2034 };
2035 }
2036 }
2037
2038 void Call(AuraScript* auraScript, AuraEffect* aurEff, ProcEventInfo& eventInfo) const
2039 {
2040 return _safeWrapper(auraScript, aurEff, eventInfo, _callImpl);
2041 }
2042 private:
2045 };
2046
2048 {
2049 public:
2050 using AuraEnterLeaveCombatFnType = void(AuraScript::*)(bool isNowInCombat);
2051
2052 using SafeWrapperType = void(*)(AuraScript* auraScript, bool isNowInCombat, AuraEnterLeaveCombatFnType callImpl);
2053
2054 template<typename ScriptFunc>
2055 explicit EnterLeaveCombatHandler(ScriptFunc handler)
2056 {
2057 using ScriptClass = GetScriptClass_t<ScriptFunc>;
2058
2059 static_assert(sizeof(AuraEnterLeaveCombatFnType) >= sizeof(ScriptFunc));
2060 static_assert(alignof(AuraEnterLeaveCombatFnType) >= alignof(ScriptFunc));
2061
2062 static_assert(std::is_invocable_r_v<void, ScriptFunc, ScriptClass, bool>,
2063 "EnterLeaveCombatHandler signature must be \"void HandleEnterLeaveCombat(bool isNowInCombat)\"");
2064
2065 _callImpl = reinterpret_cast<AuraEnterLeaveCombatFnType>(handler);
2066 _safeWrapper = [](AuraScript* auraScript, bool isNowInCombat, AuraEnterLeaveCombatFnType callImpl) -> void
2067 {
2068 return (static_cast<ScriptClass*>(auraScript)->*reinterpret_cast<ScriptFunc>(callImpl))(isNowInCombat);
2069 };
2070 }
2071
2072 void Call(AuraScript* auraScript, bool isNowInCombat) const
2073 {
2074 return _safeWrapper(auraScript, isNowInCombat, _callImpl);
2075 }
2076 private:
2079 };
2080
2081 // left for custom compatibility only, DO NOT USE
2082 #define PrepareAuraScript(CLASSNAME)
2083
2084public:
2085 AuraScript();
2087 bool _Validate(SpellInfo const* entry) override;
2088 bool _Load(Aura* aura);
2089 void _PrepareScriptCall(AuraScriptHookType hookType, AuraApplication const* aurApp = nullptr);
2090 void _FinishScriptCall();
2091 bool _IsDefaultActionPrevented() const;
2092private:
2096
2098 {
2099 public:
2103 ScriptStateStore(uint8 currentScriptState, AuraApplication const* auraApplication, bool defaultActionPrevented)
2104 : _auraApplication(auraApplication), _currentScriptState(currentScriptState), _defaultActionPrevented(defaultActionPrevented)
2105 { }
2106 };
2107 typedef std::stack<ScriptStateStore> ScriptStateStack;
2109
2110public:
2111 //
2112 // AuraScript interface
2113 // hooks to which you can attach your functions
2114 //
2115 // executed when area aura checks if it can be applied on target
2116 // example: OnEffectApply += AuraEffectApplyFn(class::function);
2117 // where function is: bool function (Unit* target);
2119 #define AuraCheckAreaTargetFn(F) CheckAreaTargetHandler(&F)
2120
2121 // executed when aura is dispelled by a unit
2122 // example: OnDispel += AuraDispelFn(class::function);
2123 // where function is: void function (DispelInfo* dispelInfo);
2125 // executed after aura is dispelled by a unit
2126 // example: AfterDispel += AuraDispelFn(class::function);
2127 // where function is: void function (DispelInfo* dispelInfo);
2129 #define AuraDispelFn(F) AuraDispelHandler(&F)
2130
2131 // executed on every heartbeat of a unit
2132 // example: OnHeartbeat += AuraHeartbeatFn(class::function);
2133 // where function is: void function ();
2135 #define AuraHeartbeatFn(F) AuraHeartbeatHandler(&F)
2136
2137 // executed when aura effect is applied with specified mode to target
2138 // 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
2139 // example: OnEffectApply += AuraEffectApplyFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
2140 // where function is: void function (AuraEffect const* aurEff, AuraEffectHandleModes mode);
2142 // executed after aura effect is applied with specified mode to target
2143 // example: AfterEffectApply += AuraEffectApplyFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
2144 // where function is: void function (AuraEffect const* aurEff, AuraEffectHandleModes mode);
2146 #define AuraEffectApplyFn(F, I, N, M) EffectApplyHandler(&F, I, N, M)
2147
2148 // executed after aura effect is removed with specified mode from target
2149 // should be used when effect handler preventing/replacing is needed, do not use this hook for triggering spellcasts/removing auras etc - may be unsafe
2150 // example: OnEffectRemove += AuraEffectRemoveFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
2151 // where function is: void function (AuraEffect const* aurEff, AuraEffectHandleModes mode);
2153 // executed when aura effect is removed with specified mode from target
2154 // example: AfterEffectRemove += AuraEffectRemoveFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
2155 // where function is: void function (AuraEffect const* aurEff, AuraEffectHandleModes mode);
2157 #define AuraEffectRemoveFn(F, I, N, M) EffectApplyHandler(&F, I, N, M)
2158
2159 // executed when periodic aura effect ticks on target
2160 // example: OnEffectPeriodic += AuraEffectPeriodicFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
2161 // where function is: void function (AuraEffect const* aurEff);
2163 #define AuraEffectPeriodicFn(F, I, N) EffectPeriodicHandler(&F, I, N)
2164
2165 // executed when periodic aura effect is updated
2166 // example: OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
2167 // where function is: void function (AuraEffect* aurEff);
2169 #define AuraEffectUpdatePeriodicFn(F, I, N) EffectUpdatePeriodicHandler(&F, I, N)
2170
2171 // executed when aura effect calculates amount
2172 // example: DoEffectCalcAmount += AuraEffectCalcAmounFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
2173 // where function is: void function (AuraEffect* aurEff, int32& amount, bool& canBeRecalculated);
2175 #define AuraEffectCalcAmountFn(F, I, N) EffectCalcAmountHandler(&F, I, N)
2176
2177 // executed when aura effect calculates periodic data
2178 // example: DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
2179 // where function is: void function (AuraEffect const* aurEff, bool& isPeriodic, int32& amplitude);
2181 #define AuraEffectCalcPeriodicFn(F, I, N) EffectCalcPeriodicHandler(&F, I, N)
2182
2183 // executed when aura effect calculates spellmod
2184 // example: DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
2185 // where function is: void function (AuraEffect const* aurEff, SpellModifier*& spellMod);
2187 #define AuraEffectCalcSpellModFn(F, I, N) EffectCalcSpellModHandler(&F, I, N)
2188
2189 // executed when aura effect calculates crit chance for dots and hots
2190 // example: DoEffectCalcCritChance += AuraEffectCalcCritChanceFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
2191 // where function is: void function (AuraEffect const* aurEff, Unit* victim, float& critChance);
2193 #define AuraEffectCalcCritChanceFn(F, I, N) EffectCalcCritChanceHandler(&F, I, N)
2194
2195 // executed when aura effect calculates damage or healing for dots and hots
2196 // example: DoEffectCalcDamageAndHealing += AuraEffectCalcDamageFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
2197 // example: DoEffectCalcDamageAndHealing += AuraEffectCalcHealingFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
2198 // where function is: void function (AuraEffect const* aurEff, Unit* victim, int32& damageOrHealing, int32& flatMod, float& pctMod);
2200 #define AuraEffectCalcDamageFn(F, I, N) EffectCalcDamageAndHealingHandler(&F, I, N)
2201 #define AuraEffectCalcHealingFn(F, I, N) EffectCalcDamageAndHealingHandler(&F, I, N)
2202
2203 // executed when absorb aura effect is going to reduce damage
2204 // example: OnEffectAbsorb += AuraEffectAbsorbFn(class::function, EffectIndexSpecifier);
2205 // where function is: void function (AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount);
2207 #define AuraEffectAbsorbFn(F, I) EffectAbsorbHandler(&F, I, SPELL_AURA_SCHOOL_ABSORB)
2208 #define AuraEffectAbsorbOverkillFn(F, I) EffectAbsorbHandler(&F, I, SPELL_AURA_SCHOOL_ABSORB_OVERKILL)
2209
2210 // executed after absorb aura effect reduced damage to target - absorbAmount is real amount absorbed by aura
2211 // example: AfterEffectAbsorb += AuraEffectAbsorbFn(class::function, EffectIndexSpecifier);
2212 // where function is: void function (AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount);
2214
2215 // executed when absorb aura effect is going to reduce damage
2216 // example: OnEffectAbsorbHeal += AuraEffectAbsorbHealFn(class::function, EffectIndexSpecifier);
2217 // where function is: void function (AuraEffect const* aurEff, HealInfo& healInfo, uint32& absorbAmount);
2219 #define AuraEffectAbsorbHealFn(F, I) EffectAbsorbHealHandler(&F, I, SPELL_AURA_SCHOOL_HEAL_ABSORB)
2220
2221 // executed after absorb aura effect reduced heal to target - absorbAmount is real amount absorbed by aura
2222 // example: AfterEffectAbsorbHeal += AuraEffectAbsorbHealFn(class::function, EffectIndexSpecifier);
2223 // where function is: void function (AuraEffect* aurEff, HealInfo& healInfo, uint32& absorbAmount);
2225
2226 // executed when mana shield aura effect is going to reduce damage
2227 // example: OnEffectManaShield += AuraEffectManaShieldFn(class::function, EffectIndexSpecifier);
2228 // where function is: void function (AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount);
2230 #define AuraEffectManaShieldFn(F, I) EffectAbsorbHandler(&F, I, SPELL_AURA_MANA_SHIELD)
2231
2232 // executed after mana shield aura effect reduced damage to target - absorbAmount is real amount absorbed by aura
2233 // example: AfterEffectManaShield += AuraEffectManaShieldFn(class::function, EffectIndexSpecifier);
2234 // where function is: void function (AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount);
2236
2237 // executed when the caster of some spell with split dmg aura gets damaged through it
2238 // example: OnEffectSplit += AuraEffectSplitFn(class::function, EffectIndexSpecifier);
2239 // where function is: void function (AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& splitAmount);
2241 #define AuraEffectSplitFn(F, I) EffectAbsorbHandler(&F, I, SPELL_AURA_SPLIT_DAMAGE_PCT)
2242
2243 // executed when aura checks if it can proc
2244 // example: DoCheckProc += AuraCheckProcFn(class::function);
2245 // where function is: bool function (ProcEventInfo& eventInfo);
2247 #define AuraCheckProcFn(F) CheckProcHandler(&F)
2248
2249 // executed when aura effect checks if it can proc the aura
2250 // example: DoCheckEffectProc += AuraCheckEffectProcFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
2251 // where function is bool function (AuraEffect const* aurEff, ProcEventInfo& eventInfo);
2253 #define AuraCheckEffectProcFn(F, I, N) CheckEffectProcHandler(&F, I, N)
2254
2255 // executed before aura procs (possibility to prevent charge drop/cooldown)
2256 // example: DoPrepareProc += AuraProcFn(class::function);
2257 // where function is: void function (ProcEventInfo& eventInfo);
2259 // executed when aura procs
2260 // example: OnProc += AuraProcFn(class::function);
2261 // where function is: void function (ProcEventInfo& eventInfo);
2263 // executed after aura proced
2264 // example: AfterProc += AuraProcFn(class::function);
2265 // where function is: void function (ProcEventInfo& eventInfo);
2267 #define AuraProcFn(F) AuraProcHandler(&F)
2268
2269 // executed when aura effect procs
2270 // example: OnEffectProc += AuraEffectProcFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
2271 // where function is: void function (AuraEffect* aurEff, ProcEventInfo& procInfo);
2273 // executed after aura effect proced
2274 // example: AfterEffectProc += AuraEffectProcFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
2275 // where function is: void function (AuraEffect* aurEff, ProcEventInfo& procInfo);
2277 #define AuraEffectProcFn(F, I, N) EffectProcHandler(&F, I, N)
2278
2279 // executed when target enters or leaves combat
2280 // example: OnEnterLeaveCombat += AuraEnterLeaveCombatFn(class::function)
2281 // where function is: void function (bool isNowInCombat);
2283 #define AuraEnterLeaveCombatFn(F) EnterLeaveCombatHandler(&F)
2284
2285 // AuraScript interface - hook/effect execution manipulators
2286
2287 // prevents default action of a hook from being executed (works only while called in a hook which default action can be prevented)
2288 void PreventDefaultAction();
2289
2290 // AuraScript interface - functions which are redirecting to Aura class
2291
2292 // returns proto of the spell
2293 SpellInfo const* GetSpellInfo() const;
2294 SpellEffectInfo const& GetEffectInfo(SpellEffIndex effIndex) const;
2295 // returns spellid of the spell
2296 uint32 GetId() const;
2297
2298 // returns guid of object which cast the aura (m_originalCaster of the Spell class)
2299 ObjectGuid GetCasterGUID() const;
2300 // returns unit which cast the aura or NULL if not avalible (caster logged out for example)
2301 Unit* GetCaster() const;
2302 // returns gameobject which cast the aura or NULL if not available
2303 GameObject* GetGObjCaster() const;
2304 // returns object on which aura was cast, target for non-area auras, area aura source for area auras
2305 WorldObject* GetOwner() const;
2306 // returns owner if it's unit or unit derived object, NULL otherwise (only for persistent area auras NULL is returned)
2307 Unit* GetUnitOwner() const;
2308 // returns owner if it's dynobj, NULL otherwise
2309 DynamicObject* GetDynobjOwner() const;
2310
2311 // removes aura with remove mode (see AuraRemoveMode enum)
2312 void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
2313 // returns aura object of script
2314 Aura* GetAura() const;
2315
2316 // returns type of the aura, may be dynobj owned aura or unit owned aura
2317 AuraObjectType GetType() const;
2318
2319 // aura duration manipulation - when duration goes to 0 aura is removed
2320 int32 GetDuration() const;
2321 void SetDuration(int32 duration, bool withMods = false);
2322 // sets duration to maxduration
2323 void RefreshDuration();
2324 time_t GetApplyTime() const;
2325 int32 GetMaxDuration() const;
2326 void SetMaxDuration(int32 duration);
2327 int32 CalcMaxDuration() const;
2328 // expired - duration just went to 0
2329 bool IsExpired() const;
2330 // permament - has infinite duration
2331 bool IsPermanent() const;
2332
2333 // charges manipulation - 0 - not charged aura
2334 uint8 GetCharges() const;
2335 void SetCharges(uint8 charges);
2336 uint8 CalcMaxCharges() const;
2337 bool ModCharges(int8 num, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
2338 // returns true if last charge dropped
2339 bool DropCharge(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
2340
2341 // stack amount manipulation
2342 uint8 GetStackAmount() const;
2343 void SetStackAmount(uint8 num);
2344 bool ModStackAmount(int32 num, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
2345
2346 // passive - "working in background", not saved, not removed by immunities, not seen by player
2347 bool IsPassive() const;
2348 // death persistent - not removed on death
2349 bool IsDeathPersistent() const;
2350
2351 // check if aura has effect of given effindex
2352 bool HasEffect(uint8 effIndex) const;
2353 // returns aura effect of given effect index or NULL
2354 AuraEffect* GetEffect(uint8 effIndex) const;
2355
2356 // check if aura has effect of given aura type
2357 bool HasEffectType(AuraType type) const;
2358
2359 // AuraScript interface - functions which are redirecting to AuraApplication class
2360 // Do not call these in hooks in which AuraApplication is not avalible, otherwise result will differ from expected (the functions will return NULL)
2361
2362 // returns currently processed target of an aura
2363 // Return value does not need to be NULL-checked, the only situation this will (always)
2364 // return NULL is when the call happens in an unsupported hook, in other cases, it is always valid
2365 Unit* GetTarget() const;
2366 // returns AuraApplication object of currently processed target
2367 AuraApplication const* GetTargetApplication() const;
2368
2369 // returns desired cast difficulty for triggered spells
2370 Difficulty GetCastDifficulty() const;
2371};
2372
2373//
2374// definitions:
2375//
2376// EffectIndexSpecifier - specifies conditions for effects
2377// EFFECT_0 - first effect matches
2378// EFFECT_1 - second effect matches
2379// EFFECT_2 - third effect matches
2380// EFFECT_FIRST_FOUND - first effect matching other conditions matches
2381// EFFECT_ALL - all effects of spell match
2382//
2383// EffectNameSpecifier - specifies conditions for spell effect names
2384// SPELL_EFFECT_ANY - any effect but not 0 matches condition
2385// SPELL_EFFECT_XXX - one of values of enum SpellEffects - effect with equal name matches
2386//
2387
2388#endif // TRINITY_SPELL_SCRIPT_H
Difficulty
Definition: DBCEnums.h:918
ItemContext
Definition: DBCEnums.h:1108
#define TC_GAME_API
Definition: Define.h:123
uint8_t uint8
Definition: Define.h:144
int64_t int64
Definition: Define.h:137
int8_t int8
Definition: Define.h:140
int32_t int32
Definition: Define.h:138
uint16_t uint16
Definition: Define.h:143
uint32_t uint32
Definition: Define.h:142
SpellEffIndex
Definition: SharedDefines.h:29
SpellMissInfo
SpellCustomErrors
SpellCastResult
AuraEffectHandleModes
AuraRemoveMode
@ AURA_REMOVE_BY_DEFAULT
AuraType
AuraObjectType
AuraScriptHookType
Definition: SpellScript.h:1089
@ AURA_SCRIPT_HOOK_EFFECT_CALC_PERIODIC
Definition: SpellScript.h:1097
@ AURA_SCRIPT_HOOK_CHECK_EFFECT_PROC
Definition: SpellScript.h:1113
@ AURA_SCRIPT_HOOK_EFFECT_CALC_DAMAGE_AND_HEALING
Definition: SpellScript.h:1100
@ AURA_SCRIPT_HOOK_EFFECT_CALC_AMOUNT
Definition: SpellScript.h:1096
@ AURA_SCRIPT_HOOK_EFFECT_REMOVE
Definition: SpellScript.h:1092
@ AURA_SCRIPT_HOOK_EFFECT_CALC_CRIT_CHANCE
Definition: SpellScript.h:1099
@ AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD
Definition: SpellScript.h:1104
@ AURA_SCRIPT_HOOK_PREPARE_PROC
Definition: SpellScript.h:1114
@ AURA_SCRIPT_HOOK_ON_HEARTBEAT
Definition: SpellScript.h:1109
@ AURA_SCRIPT_HOOK_EFFECT_AFTER_APPLY
Definition: SpellScript.h:1091
@ AURA_SCRIPT_HOOK_EFFECT_AFTER_REMOVE
Definition: SpellScript.h:1093
@ AURA_SCRIPT_HOOK_AFTER_PROC
Definition: SpellScript.h:1118
@ AURA_SCRIPT_HOOK_CHECK_AREA_TARGET
Definition: SpellScript.h:1106
@ AURA_SCRIPT_HOOK_EFFECT_MANASHIELD
Definition: SpellScript.h:1103
@ AURA_SCRIPT_HOOK_PROC
Definition: SpellScript.h:1115
@ AURA_SCRIPT_HOOK_EFFECT_AFTER_ABSORB
Definition: SpellScript.h:1102
@ AURA_SCRIPT_HOOK_DISPEL
Definition: SpellScript.h:1107
@ AURA_SCRIPT_HOOK_EFFECT_APPLY
Definition: SpellScript.h:1090
@ AURA_SCRIPT_HOOK_EFFECT_PERIODIC
Definition: SpellScript.h:1094
@ AURA_SCRIPT_HOOK_EFFECT_AFTER_PROC
Definition: SpellScript.h:1117
@ AURA_SCRIPT_HOOK_EFFECT_ABSORB
Definition: SpellScript.h:1101
@ AURA_SCRIPT_HOOK_EFFECT_PROC
Definition: SpellScript.h:1116
@ AURA_SCRIPT_HOOK_EFFECT_SPLIT
Definition: SpellScript.h:1105
@ AURA_SCRIPT_HOOK_EFFECT_CALC_SPELLMOD
Definition: SpellScript.h:1098
@ AURA_SCRIPT_HOOK_AFTER_DISPEL
Definition: SpellScript.h:1108
@ AURA_SCRIPT_HOOK_CHECK_PROC
Definition: SpellScript.h:1112
@ AURA_SCRIPT_HOOK_ENTER_LEAVE_COMBAT
Definition: SpellScript.h:1110
@ AURA_SCRIPT_HOOK_EFFECT_UPDATE_PERIODIC
Definition: SpellScript.h:1095
SpellScriptState
Definition: SpellScript.h:62
@ SPELL_SCRIPT_STATE_NONE
Definition: SpellScript.h:63
@ SPELL_SCRIPT_STATE_LOADING
Definition: SpellScript.h:65
@ SPELL_SCRIPT_STATE_UNLOADING
Definition: SpellScript.h:66
@ SPELL_SCRIPT_STATE_REGISTRATION
Definition: SpellScript.h:64
#define SPELL_SCRIPT_STATE_END
Definition: SpellScript.h:68
SpellScriptHookType
Definition: SpellScript.h:219
@ SPELL_SCRIPT_HOOK_AFTER_CAST
Definition: SpellScript.h:235
@ SPELL_SCRIPT_HOOK_EFFECT_HIT
Definition: SpellScript.h:222
@ SPELL_SCRIPT_HOOK_AFTER_HIT
Definition: SpellScript.h:227
@ SPELL_SCRIPT_HOOK_EFFECT_SUCCESSFUL_DISPEL
Definition: SpellScript.h:224
@ SPELL_SCRIPT_HOOK_CALC_HEALING
Definition: SpellScript.h:238
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH
Definition: SpellScript.h:220
@ SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT
Definition: SpellScript.h:228
@ SPELL_SCRIPT_HOOK_BEFORE_HIT
Definition: SpellScript.h:225
@ SPELL_SCRIPT_HOOK_CALC_DAMAGE
Definition: SpellScript.h:237
@ SPELL_SCRIPT_HOOK_CHECK_CAST
Definition: SpellScript.h:231
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET
Definition: SpellScript.h:221
@ SPELL_SCRIPT_HOOK_CALC_CAST_TIME
Definition: SpellScript.h:240
@ SPELL_SCRIPT_HOOK_EMPOWER_STAGE_COMPLETED
Definition: SpellScript.h:241
@ SPELL_SCRIPT_HOOK_EMPOWER_COMPLETED
Definition: SpellScript.h:242
@ SPELL_SCRIPT_HOOK_HIT
Definition: SpellScript.h:226
@ SPELL_SCRIPT_HOOK_BEFORE_CAST
Definition: SpellScript.h:232
@ SPELL_SCRIPT_HOOK_ON_RESIST_ABSORB_CALCULATION
Definition: SpellScript.h:234
@ SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT
Definition: SpellScript.h:230
@ SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT
Definition: SpellScript.h:229
@ SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET
Definition: SpellScript.h:223
@ SPELL_SCRIPT_HOOK_CALC_CRIT_CHANCE
Definition: SpellScript.h:236
@ SPELL_SCRIPT_HOOK_ON_CAST
Definition: SpellScript.h:233
@ SPELL_SCRIPT_HOOK_ON_PRECAST
Definition: SpellScript.h:239
void(*)(AuraScript *auraScript, DispelInfo *dispelInfo, AuraDispelFnType callImpl) SafeWrapperType
Definition: SpellScript.h:1193
AuraDispelHandler(ScriptFunc handler)
Definition: SpellScript.h:1196
void Call(AuraScript *auraScript, DispelInfo *dispelInfo) const
Definition: SpellScript.h:1227
AuraHeartbeatFnType _callImpl
Definition: SpellScript.h:1284
void Call(AuraScript *auraScript) const
Definition: SpellScript.h:1279
AuraHeartbeatHandler(ScriptFunc handler)
Definition: SpellScript.h:1248
void(*)(AuraScript *auraScript, AuraHeartbeatFnType callImpl) SafeWrapperType
Definition: SpellScript.h:1245
SafeWrapperType _safeWrapper
Definition: SpellScript.h:1991
AuraProcHandler(ScriptFunc handler)
Definition: SpellScript.h:1954
void(*)(AuraScript *auraScript, ProcEventInfo &eventInfo, AuraProcFnType callImpl) SafeWrapperType
Definition: SpellScript.h:1951
void Call(AuraScript *auraScript, ProcEventInfo &eventInfo) const
Definition: SpellScript.h:1985
bool(*)(AuraScript *auraScript, Unit *target, AuraCheckAreaTargetFnType callImpl) SafeWrapperType
Definition: SpellScript.h:1141
bool Call(AuraScript *auraScript, Unit *target) const
Definition: SpellScript.h:1175
AuraCheckAreaTargetFnType _callImpl
Definition: SpellScript.h:1180
CheckAreaTargetHandler(ScriptFunc handler)
Definition: SpellScript.h:1144
AuraCheckEffectProcFnType _callImpl
Definition: SpellScript.h:1938
CheckEffectProcHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
Definition: SpellScript.h:1901
bool Call(AuraScript *auraScript, AuraEffect const *aurEff, ProcEventInfo &eventInfo) const
Definition: SpellScript.h:1933
bool(*)(AuraScript *auraScript, AuraEffect const *aurEff, ProcEventInfo &eventInfo, AuraCheckEffectProcFnType callImpl) SafeWrapperType
Definition: SpellScript.h:1898
AuraCheckProcFnType _callImpl
Definition: SpellScript.h:1885
bool Call(AuraScript *auraScript, ProcEventInfo &eventInfo) const
Definition: SpellScript.h:1880
bool(*)(AuraScript *auraScript, ProcEventInfo &eventInfo, AuraCheckProcFnType callImpl) SafeWrapperType
Definition: SpellScript.h:1846
SafeWrapperType _safeWrapper
Definition: SpellScript.h:1886
CheckProcHandler(ScriptFunc handler)
Definition: SpellScript.h:1849
void(*)(AuraScript *auraScript, AuraEffect *aurEff, DamageInfo &dmgInfo, uint32 &absorbAmount, AuraEffectAbsorbFnType callImpl) SafeWrapperType
Definition: SpellScript.h:1740
void Call(AuraScript *auraScript, AuraEffect *aurEff, DamageInfo &dmgInfo, uint32 &absorbAmount) const
Definition: SpellScript.h:1775
EffectAbsorbHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
Definition: SpellScript.h:1743
AuraEffectAbsorbFnType _callImpl
Definition: SpellScript.h:1780
EffectAbsorbHealHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
Definition: SpellScript.h:1796
AuraEffectAbsorbHealFnType _callImpl
Definition: SpellScript.h:1833
void(*)(AuraScript *auraScript, AuraEffect *aurEff, HealInfo &healInfo, uint32 &absorbAmount, AuraEffectAbsorbHealFnType callImpl) SafeWrapperType
Definition: SpellScript.h:1793
void Call(AuraScript *auraScript, AuraEffect *aurEff, HealInfo &healInfo, uint32 &absorbAmount) const
Definition: SpellScript.h:1828
void(*)(AuraScript *auraScript, AuraEffect const *aurEff, AuraEffectHandleModes mode, AuraEffectApplicationModeFnType callImpl) SafeWrapperType
Definition: SpellScript.h:1683
void Call(AuraScript *auraScript, AuraEffect const *aurEff, AuraEffectHandleModes mode) const
Definition: SpellScript.h:1718
AuraEffectApplicationModeFnType _callImpl
Definition: SpellScript.h:1726
EffectApplyHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType, AuraEffectHandleModes mode)
Definition: SpellScript.h:1686
AuraEffectHandleModes _mode
Definition: SpellScript.h:1728
EffectBase & operator=(EffectBase const &right)=delete
EffectBase & operator=(EffectBase &&right) noexcept
EffectBase(EffectBase &&right) noexcept
EffectBase(EffectBase const &right)=delete
AuraEffectCalcAmountFnType _callImpl
Definition: SpellScript.h:1458
EffectCalcAmountHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
Definition: SpellScript.h:1421
void(*)(AuraScript *auraScript, AuraEffect const *aurEff, int32 &amount, bool &canBeRecalculated, AuraEffectCalcAmountFnType callImpl) SafeWrapperType
Definition: SpellScript.h:1418
void Call(AuraScript *auraScript, AuraEffect const *aurEff, int32 &amount, bool &canBeRecalculated) const
Definition: SpellScript.h:1453
void Call(AuraScript *auraScript, AuraEffect const *aurEff, Unit const *victim, float &critChance) const
Definition: SpellScript.h:1612
EffectCalcCritChanceHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
Definition: SpellScript.h:1580
AuraEffectCalcCritChanceFnType _callImpl
Definition: SpellScript.h:1617
void(*)(AuraScript *auraScript, AuraEffect const *aurEff, Unit const *victim, float &critChance, AuraEffectCalcCritChanceFnType callImpl) SafeWrapperType
Definition: SpellScript.h:1577
void(*)(AuraScript *auraScript, AuraEffect const *aurEff, Unit *victim, int32 &damageOrHealing, int32 &flatMod, float &pctMod, AuraEffectDamageAndHealingCalcFnType callImpl) SafeWrapperType
Definition: SpellScript.h:1630
AuraEffectDamageAndHealingCalcFnType _callImpl
Definition: SpellScript.h:1670
EffectCalcDamageAndHealingHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
Definition: SpellScript.h:1633
void Call(AuraScript *auraScript, AuraEffect const *aurEff, Unit *victim, int32 &damageOrHealing, int32 &flatMod, float &pctMod) const
Definition: SpellScript.h:1665
void(*)(AuraScript *auraScript, AuraEffect const *aurEff, bool &isPeriodic, int32 &periodicTimer, AuraEffectCalcPeriodicFnType callImpl) SafeWrapperType
Definition: SpellScript.h:1471
EffectCalcPeriodicHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
Definition: SpellScript.h:1474
AuraEffectCalcPeriodicFnType _callImpl
Definition: SpellScript.h:1511
void Call(AuraScript *auraScript, AuraEffect const *aurEff, bool &isPeriodic, int32 &periodicTimer) const
Definition: SpellScript.h:1506
EffectCalcSpellModHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
Definition: SpellScript.h:1527
void(*)(AuraScript *auraScript, AuraEffect const *aurEff, SpellModifier *&spellMod, AuraEffectCalcSpellModFnType callImpl) SafeWrapperType
Definition: SpellScript.h:1524
AuraEffectCalcSpellModFnType _callImpl
Definition: SpellScript.h:1564
void Call(AuraScript *auraScript, AuraEffect const *aurEff, SpellModifier *&spellMod) const
Definition: SpellScript.h:1559
void Call(AuraScript *auraScript, AuraEffect const *aurEff) const
Definition: SpellScript.h:1347
AuraEffectPeriodicFnType _callImpl
Definition: SpellScript.h:1352
EffectPeriodicHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
Definition: SpellScript.h:1315
void(*)(AuraScript *auraScript, AuraEffect const *aurEff, AuraEffectPeriodicFnType callImpl) SafeWrapperType
Definition: SpellScript.h:1312
EffectProcHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
Definition: SpellScript.h:2006
void Call(AuraScript *auraScript, AuraEffect *aurEff, ProcEventInfo &eventInfo) const
Definition: SpellScript.h:2038
void(*)(AuraScript *auraScript, AuraEffect *aurEff, ProcEventInfo &eventInfo, AuraEffectProcFnType callImpl) SafeWrapperType
Definition: SpellScript.h:2003
AuraEffectProcFnType _callImpl
Definition: SpellScript.h:2043
void Call(AuraScript *auraScript, AuraEffect *aurEff) const
Definition: SpellScript.h:1400
void(*)(AuraScript *auraScript, AuraEffect *aurEff, AuraEffectUpdatePeriodicFnType callImpl) SafeWrapperType
Definition: SpellScript.h:1365
AuraEffectUpdatePeriodicFnType _callImpl
Definition: SpellScript.h:1405
EffectUpdatePeriodicHandler(ScriptFunc handler, uint8 effIndex, uint16 auraType)
Definition: SpellScript.h:1368
void(AuraScript::*)(bool isNowInCombat) AuraEnterLeaveCombatFnType
Definition: SpellScript.h:2050
void Call(AuraScript *auraScript, bool isNowInCombat) const
Definition: SpellScript.h:2072
EnterLeaveCombatHandler(ScriptFunc handler)
Definition: SpellScript.h:2055
AuraEnterLeaveCombatFnType _callImpl
Definition: SpellScript.h:2077
void(*)(AuraScript *auraScript, bool isNowInCombat, AuraEnterLeaveCombatFnType callImpl) SafeWrapperType
Definition: SpellScript.h:2052
ScriptStateStore(uint8 currentScriptState, AuraApplication const *auraApplication, bool defaultActionPrevented)
Definition: SpellScript.h:2103
AuraApplication const * _auraApplication
Definition: SpellScript.h:2100
HookList< EffectAbsorbHandler > OnEffectManaShield
Definition: SpellScript.h:2229
HookList< EffectCalcDamageAndHealingHandler > DoEffectCalcDamageAndHealing
Definition: SpellScript.h:2199
HookList< EffectAbsorbHealHandler > OnEffectAbsorbHeal
Definition: SpellScript.h:2218
HookList< EffectCalcPeriodicHandler > DoEffectCalcPeriodic
Definition: SpellScript.h:2180
HookList< AuraHeartbeatHandler > OnHeartbeat
Definition: SpellScript.h:2134
HookList< EffectApplyHandler > AfterEffectRemove
Definition: SpellScript.h:2156
AuraApplication const * m_auraApplication
Definition: SpellScript.h:2094
HookList< CheckEffectProcHandler > DoCheckEffectProc
Definition: SpellScript.h:2252
HookList< EffectPeriodicHandler > OnEffectPeriodic
Definition: SpellScript.h:2162
bool m_defaultActionPrevented
Definition: SpellScript.h:2095
HookList< EffectApplyHandler > AfterEffectApply
Definition: SpellScript.h:2145
HookList< EffectProcHandler > AfterEffectProc
Definition: SpellScript.h:2276
HookList< EffectAbsorbHandler > AfterEffectAbsorb
Definition: SpellScript.h:2213
HookList< EffectCalcAmountHandler > DoEffectCalcAmount
Definition: SpellScript.h:2174
HookList< EffectUpdatePeriodicHandler > OnEffectUpdatePeriodic
Definition: SpellScript.h:2168
HookList< EffectCalcSpellModHandler > DoEffectCalcSpellMod
Definition: SpellScript.h:2186
HookList< EnterLeaveCombatHandler > OnEnterLeaveCombat
Definition: SpellScript.h:2282
HookList< EffectAbsorbHandler > OnEffectAbsorb
Definition: SpellScript.h:2206
std::stack< ScriptStateStore > ScriptStateStack
Definition: SpellScript.h:2107
HookList< EffectCalcCritChanceHandler > DoEffectCalcCritChance
Definition: SpellScript.h:2192
HookList< EffectAbsorbHandler > AfterEffectManaShield
Definition: SpellScript.h:2235
HookList< CheckAreaTargetHandler > DoCheckAreaTarget
Definition: SpellScript.h:2118
Aura * m_aura
Definition: SpellScript.h:2093
HookList< EffectAbsorbHealHandler > AfterEffectAbsorbHeal
Definition: SpellScript.h:2224
HookList< AuraProcHandler > AfterProc
Definition: SpellScript.h:2266
HookList< AuraDispelHandler > OnDispel
Definition: SpellScript.h:2124
HookList< CheckProcHandler > DoCheckProc
Definition: SpellScript.h:2246
HookList< EffectApplyHandler > OnEffectRemove
Definition: SpellScript.h:2152
HookList< AuraDispelHandler > AfterDispel
Definition: SpellScript.h:2128
ScriptStateStack m_scriptStates
Definition: SpellScript.h:2108
HookList< EffectProcHandler > OnEffectProc
Definition: SpellScript.h:2272
HookList< AuraProcHandler > DoPrepareProc
Definition: SpellScript.h:2258
HookList< AuraProcHandler > OnProc
Definition: SpellScript.h:2262
HookList< EffectApplyHandler > OnEffectApply
Definition: SpellScript.h:2141
HookList< EffectAbsorbHandler > OnEffectSplit
Definition: SpellScript.h:2240
Definition: Corpse.h:53
Definition: Unit.h:458
Definition: Util.h:453
Definition: Item.h:171
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
Definition: SpellScript.h:134
uint8 m_currentScriptState
Definition: SpellScript.h:132
virtual void Register()=0
virtual bool Validate(SpellInfo const *spellInfo)
Definition: SpellScript.h:154
std::string_view m_scriptName
Definition: SpellScript.h:133
static bool ValidateSpellEffect(T const &spellEffects)
Definition: SpellScript.h:179
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
static bool ValidateSpellEffect(std::initializer_list< std::pair< uint32, SpellEffIndex > > effects)
Definition: SpellScript.h:173
static bool ValidateSpellInfo(T const &spellIds)
Definition: SpellScript.h:168
static bool ValidateSpellEffectsImpl(Iterator begin, Iterator end)
Definition: SpellScript.h:200
static bool ValidateSpellInfoImpl(Iterator begin, Iterator end)
Definition: SpellScript.h:186
typename GetScriptClass< ScriptFunc >::type GetScriptClass_t
Definition: SpellScript.h:130
virtual bool Load()
Definition: SpellScript.h:157
SpellScriptBase & operator=(SpellScriptBase &&right)=delete
SpellScriptBase(SpellScriptBase &&right)=delete
virtual ~SpellScriptBase()
virtual void Unload()
Definition: SpellScript.h:160
SpellScriptBase & operator=(SpellScriptBase const &right)=delete
void Call(SpellScript *spellScript, SpellMissInfo missInfo) const
Definition: SpellScript.h:414
void(SpellScript::*)(SpellMissInfo missInfo) SpellBeforeHitFnType
Definition: SpellScript.h:392
BeforeHitHandler(ScriptFunc handler)
Definition: SpellScript.h:397
SafeWrapperType _safeWrapper
Definition: SpellScript.h:420
SpellBeforeHitFnType _callImpl
Definition: SpellScript.h:419
void(*)(SpellScript *spellScript, SpellMissInfo missInfo, SpellBeforeHitFnType callImpl) SafeWrapperType
Definition: SpellScript.h:394
CastHandler(ScriptFunc handler)
Definition: SpellScript.h:261
void Call(SpellScript *spellScript) const
Definition: SpellScript.h:278
SafeWrapperType _safeWrapper
Definition: SpellScript.h:284
void(SpellScript::*)() SpellCastFnType
Definition: SpellScript.h:256
void(*)(SpellScript *spellScript, SpellCastFnType callImpl) SafeWrapperType
Definition: SpellScript.h:258
SpellCastFnType _callImpl
Definition: SpellScript.h:283
SpellCheckCastFnType _callImpl
Definition: SpellScript.h:335
SafeWrapperType _safeWrapper
Definition: SpellScript.h:336
SpellCastResult(*)(SpellScript *spellScript, SpellCheckCastFnType callImpl) SafeWrapperType
Definition: SpellScript.h:296
SpellCastResult Call(SpellScript *spellScript) const
Definition: SpellScript.h:330
CheckCastHandler(ScriptFunc handler)
Definition: SpellScript.h:299
void Call(SpellScript *spellScript, SpellEffectInfo const &spellEffectInfo, Unit *victim, int32 &damageOrHealing, int32 &flatMod, float &pctMod) const
Definition: SpellScript.h:739
DamageAndHealingCalcHandler(ScriptFunc handler)
Definition: SpellScript.h:708
DamageAndHealingCalcFnType _callImpl
Definition: SpellScript.h:744
void(*)(SpellScript *spellScript, SpellEffectInfo const &spellEffectInfo, Unit *victim, int32 &damageOrHealing, int32 &flatMod, float &pctMod, DamageAndHealingCalcFnType callImpl) SafeWrapperType
Definition: SpellScript.h:705
void(*)(SpellScript *spellScript, SpellDestination &target, SpellDestinationTargetSelectFnType callImpl) SafeWrapperType
Definition: SpellScript.h:652
DestinationTargetSelectHandler(ScriptFunc handler, uint8 effIndex, uint16 targetType)
Definition: SpellScript.h:655
SpellDestinationTargetSelectFnType _callImpl
Definition: SpellScript.h:692
void Call(SpellScript *spellScript, SpellDestination &target) const
Definition: SpellScript.h:687
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)
Definition: SpellScript.h:362
SpellEffectFnType _callImpl
Definition: SpellScript.h:385
void(*)(SpellScript *spellScript, SpellEffIndex effIndex, SpellEffectFnType callImpl) SafeWrapperType
Definition: SpellScript.h:359
void(SpellScript::*)(SpellEffIndex effIndex) SpellEffectFnType
Definition: SpellScript.h:357
void Call(SpellScript *spellScript, SpellEffIndex effIndex) const
Definition: SpellScript.h:380
SafeWrapperType _safeWrapper
Definition: SpellScript.h:386
EmpowerStageCompletedHandler(ScriptFunc handler)
Definition: SpellScript.h:808
void(SpellScript::*)(int32) EmpowerStageFnType
Definition: SpellScript.h:803
void Call(SpellScript *spellScript, int32 completedStagesCount) const
Definition: SpellScript.h:825
void(*)(SpellScript *spellScript, EmpowerStageFnType callImpl, int32 completedStagesCount) SafeWrapperType
Definition: SpellScript.h:805
void(SpellScript::*)() SpellHitFnType
Definition: SpellScript.h:426
SafeWrapperType _safeWrapper
Definition: SpellScript.h:454
void Call(SpellScript *spellScript) const
Definition: SpellScript.h:448
SpellHitFnType _callImpl
Definition: SpellScript.h:453
void(*)(SpellScript *spellScript, SpellHitFnType callImpl) SafeWrapperType
Definition: SpellScript.h:428
HitHandler(ScriptFunc handler)
Definition: SpellScript.h:431
void Call(SpellScript *spellScript, std::list< WorldObject * > &targets) const
Definition: SpellScript.h:571
bool HasSameTargetFunctionAs(ObjectAreaTargetSelectHandler const &other) const
Definition: SpellScript.h:576
ObjectAreaTargetSelectHandler(ScriptFunc handler, uint8 effIndex, uint16 targetType)
Definition: SpellScript.h:539
SpellObjectAreaTargetSelectFnType _callImpl
Definition: SpellScript.h:581
void(*)(SpellScript *spellScript, std::list< WorldObject * > &targets, SpellObjectAreaTargetSelectFnType callImpl) SafeWrapperType
Definition: SpellScript.h:536
void(*)(SpellScript *spellScript, WorldObject *&target, SpellObjectTargetSelectFnType callImpl) SafeWrapperType
Definition: SpellScript.h:594
bool HasSameTargetFunctionAs(ObjectTargetSelectHandler const &other) const
Definition: SpellScript.h:634
ObjectTargetSelectHandler(ScriptFunc handler, uint8 effIndex, uint16 targetType)
Definition: SpellScript.h:597
SpellObjectTargetSelectFnType _callImpl
Definition: SpellScript.h:639
void Call(SpellScript *spellScript, WorldObject *&target) const
Definition: SpellScript.h:629
void(*)(SpellScript *spellScript, Unit const *victim, float &critChance, SpellOnCalcCritChanceFnType callImpl) SafeWrapperType
Definition: SpellScript.h:466
SpellOnCalcCritChanceFnType _callImpl
Definition: SpellScript.h:505
void Call(SpellScript *spellScript, Unit const *victim, float &critChance) const
Definition: SpellScript.h:500
OnCalcCritChanceHandler(ScriptFunc handler)
Definition: SpellScript.h:469
OnCalculateResistAbsorbHandler(ScriptFunc handler)
Definition: SpellScript.h:760
SpellOnResistAbsorbCalculateFnType _callImpl
Definition: SpellScript.h:796
void Call(SpellScript *spellScript, DamageInfo const &damageInfo, uint32 &resistAmount, int32 &absorbAmount) const
Definition: SpellScript.h:791
void(*)(SpellScript *spellScript, DamageInfo const &damageInfo, uint32 &resistAmount, int32 &absorbAmount, SpellOnResistAbsorbCalculateFnType callImpl) SafeWrapperType
Definition: SpellScript.h:757
TargetHook(TargetHook &&right) noexcept
uint16 GetTarget() const
Definition: SpellScript.h:520
TargetHook & operator=(TargetHook &&right) noexcept
TargetHook(TargetHook const &right)=delete
TargetHook & operator=(TargetHook const &right)=delete
bool _IsDefaultEffectPrevented(SpellEffIndex effIndex) const
Definition: SpellScript.h:843
HookList< DamageAndHealingCalcHandler > CalcDamage
Definition: SpellScript.h:924
HookList< CastHandler > AfterCast
Definition: SpellScript.h:870
HookList< CheckCastHandler > OnCheckCast
Definition: SpellScript.h:875
HookList< EmpowerStageCompletedHandler > OnEmpowerStageCompleted
Definition: SpellScript.h:939
HookList< HitHandler > AfterHit
Definition: SpellScript.h:898
HookList< DestinationTargetSelectHandler > OnDestinationTargetSelect
Definition: SpellScript.h:919
bool _IsEffectPrevented(SpellEffIndex effIndex) const
Definition: SpellScript.h:842
uint32 m_hitPreventDefaultEffectMask
Definition: SpellScript.h:855
HookList< HitHandler > OnHit
Definition: SpellScript.h:896
void PreventHitDamage()
Definition: SpellScript.h:1037
uint32 m_hitPreventEffectMask
Definition: SpellScript.h:854
HookList< EffectHandler > OnEffectHit
Definition: SpellScript.h:885
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:886
void PreventHitHeal()
Definition: SpellScript.h:1042
HookList< ObjectTargetSelectHandler > OnObjectTargetSelect
Definition: SpellScript.h:914
HookList< CastHandler > OnCast
Definition: SpellScript.h:868
HookList< OnCalculateResistAbsorbHandler > OnCalculateResistAbsorb
Definition: SpellScript.h:934
HookList< CastHandler > BeforeCast
Definition: SpellScript.h:866
virtual int32 CalcCastTime(int32 castTime)
Definition: SpellScript.h:879
Spell * m_spell
Definition: SpellScript.h:853
Spell * GetSpell() const
Definition: SpellScript.h:1045
HookList< EffectHandler > OnEffectLaunchTarget
Definition: SpellScript.h:884
HookList< BeforeHitHandler > BeforeHit
Definition: SpellScript.h:892
virtual void OnPrecast()
Definition: SpellScript.h:861
HookList< EffectHandler > OnEffectSuccessfulDispel
Definition: SpellScript.h:887
HookList< OnCalcCritChanceHandler > OnCalcCritChance
Definition: SpellScript.h:904
HookList< EmpowerStageCompletedHandler > OnEmpowerCompleted
Definition: SpellScript.h:944
HookList< EffectHandler > OnEffectLaunch
Definition: SpellScript.h:883
HookList< DamageAndHealingCalcHandler > CalcHealing
Definition: SpellScript.h:929
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
Definition: SpellScript.h:909
Definition: Spell.h:262
Definition: Unit.h:630
TC_GAME_API uint32 GetId(std::string_view username)
std::string ToString(Type &&val, Params &&... params)
void Remove(VignetteData &vignette, WorldObject const *owner)
Definition: Vignette.cpp:113
void(SpellScript::* Member)(std::list< WorldObject * > &targets)
Definition: SpellScript.h:532