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