TrinityCore
Loading...
Searching...
No Matches
SpellScript.cpp
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#include "SpellScript.h"
19#include "Log.h"
20#include "ScriptMgr.h"
21#include "Spell.h"
22#include "SpellAuras.h"
23#include "SpellMgr.h"
24#include "Unit.h"
25#include <string>
26
28{
29 if (!Validate(entry))
30 {
31 TC_LOG_ERROR("scripts", "Spell `{}` did not pass Validate() function of script `{}` - script will be not added to the spell", entry->Id, m_scriptName);
32 return false;
33 }
34 return true;
35}
36
37SpellScriptBase::SpellScriptBase() noexcept : m_scriptSpellId(0), m_currentScriptState(SPELL_SCRIPT_STATE_NONE)
38{
39}
40
42
44{
45 if (!sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE))
46 {
47 TC_LOG_ERROR("scripts.spells", "SpellScriptBase::ValidateSpellInfo: Spell {} does not exist.", spellId);
48 return false;
49 }
50
51 return true;
52}
53
55{
56 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE);
57 if (!spellInfo)
58 {
59 TC_LOG_ERROR("scripts.spells", "SpellScriptBase::ValidateSpellEffect: Spell {} does not exist.", spellId);
60 return false;
61 }
62
63 if (spellInfo->GetEffects().size() <= effectIndex)
64 {
65 TC_LOG_ERROR("scripts.spells", "SpellScriptBase::ValidateSpellEffect: Spell {} does not have EFFECT_{}.", spellId, uint32(effectIndex));
66 return false;
67 }
68
69 return true;
70}
71
78
85
86void SpellScriptBase::_Init(std::string const& scriptname, uint32 spellId)
87{
89 m_scriptName = scriptname;
90 m_scriptSpellId = spellId;
91
92#ifdef TRINITY_API_USE_DYNAMIC_LINKING
93 // Acquire a strong reference to the binary code
94 // to keep it loaded until all spells are destroyed.
95 m_moduleReference = sScriptMgr->AcquireModuleReferenceOfScriptName(scriptname);
96#endif // #ifndef TRINITY_API_USE_DYNAMIC_LINKING
97}
98
99std::string_view SpellScriptBase::GetScriptName() const
100{
101 return m_scriptName;
102}
103
104template <typename T>
106{
107 ::HookList<T>::operator+=(std::move(t));
108 return *this;
109}
110
112{
113 // effect index must be in range <0;2>, allow use of special effindexes
114 ASSERT(effIndex == EFFECT_ALL || effIndex == EFFECT_FIRST_FOUND || effIndex < MAX_SPELL_EFFECTS);
115 _effIndex = effIndex;
116}
117
118SpellScriptBase::EffectHook::EffectHook(EffectHook&& right) noexcept = default;
121
123{
124 uint32 mask = 0;
125 if (_effIndex == EFFECT_ALL || _effIndex == EFFECT_FIRST_FOUND)
126 {
127 for (uint8 i = 0; i < spellInfo->GetEffects().size(); ++i)
128 {
129 if (_effIndex == EFFECT_FIRST_FOUND && mask)
130 return mask;
131 if (CheckEffect(spellInfo, i))
132 mask |= 1 << i;
133 }
134 }
135 else
136 {
137 if (CheckEffect(spellInfo, _effIndex))
138 mask |= 1 << _effIndex;
139 }
140 return mask;
141}
142
144{
145 return (GetAffectedEffectsMask(spellInfo) & 1 << effIndex) != 0;
146}
147
149{
150 if (_effIndex == EFFECT_ALL)
151 return "EFFECT_ALL";
152 if (_effIndex == EFFECT_FIRST_FOUND)
153 return "EFFECT_FIRST_FOUND";
154 if (_effIndex < MAX_SPELL_EFFECTS)
155 return Trinity::StringFormat("EFFECT_{}", uint32(_effIndex));
156 return "Invalid Value";
157}
158
160 : EffectHook(effIndex), _effName(effName)
161{
162}
163
164SpellScript::EffectBase::EffectBase(EffectBase&& right) noexcept = default;
167
169{
170 switch (_effName)
171 {
172 case SPELL_EFFECT_ANY:
173 return Trinity::StringFormat("Index: {}, Effect: SPELL_EFFECT_ANY", EffIndexToString());
174 default:
175 return Trinity::StringFormat("Index: {}, Effect: SPELL_EFFECT_{}", EffIndexToString(), _effName);
176 }
177}
178
179bool SpellScript::EffectBase::CheckEffect(SpellInfo const* spellInfo, uint8 effIndex) const
180{
181 if (spellInfo->GetEffects().size() <= effIndex)
182 return false;
183 SpellEffectInfo const& spellEffectInfo = spellInfo->GetEffect(SpellEffIndex(effIndex));
184 if (!spellEffectInfo.Effect && !_effName)
185 return true;
186 if (!spellEffectInfo.Effect)
187 return false;
188 return (_effName == SPELL_EFFECT_ANY) || (spellEffectInfo.Effect == _effName);
189}
190
191SpellScript::TargetHook::TargetHook(uint8 effectIndex, uint16 targetType, bool area, bool dest)
192 : EffectHook(effectIndex), _targetType(targetType), _area(area), _dest(dest) { }
193
194SpellScript::TargetHook::TargetHook(TargetHook&& right) noexcept = default;
197
199{
200 return Trinity::StringFormat("Index: {} Target: {}", EffIndexToString(), _targetType);
201}
202
203bool SpellScript::TargetHook::CheckEffect(SpellInfo const* spellInfo, uint8 effIndex) const
204{
205 if (!_targetType)
206 return false;
207
208 if (spellInfo->GetEffects().size() <= effIndex)
209 return false;
210
211 SpellEffectInfo const& spellEffectInfo = spellInfo->GetEffect(SpellEffIndex(effIndex));
212 if (spellEffectInfo.TargetA.GetTarget() != _targetType &&
213 spellEffectInfo.TargetB.GetTarget() != _targetType)
214 return false;
215
216 SpellImplicitTargetInfo targetInfo(_targetType);
217 switch (targetInfo.GetSelectionCategory())
218 {
219 case TARGET_SELECT_CATEGORY_CHANNEL: // SINGLE
220 return !_area;
222 return true;
223 case TARGET_SELECT_CATEGORY_CONE: // AREA
224 case TARGET_SELECT_CATEGORY_LINE: // AREA
225 return _area;
226 case TARGET_SELECT_CATEGORY_AREA: // AREA
228 return _area || _dest;
229 return _area;
231 switch (targetInfo.GetObjectType())
232 {
233 case TARGET_OBJECT_TYPE_SRC: // EMPTY
234 return false;
235 case TARGET_OBJECT_TYPE_DEST: // DEST
236 return _dest;
237 default:
238 switch (targetInfo.GetReferenceType())
239 {
240 case TARGET_REFERENCE_TYPE_CASTER: // SINGLE
241 return !_area;
242 case TARGET_REFERENCE_TYPE_TARGET: // BOTH
243 return true;
244 default:
245 break;
246 }
247 break;
248 }
249 break;
250 default:
251 break;
252 }
253
254 return false;
255}
256
269
273
274SpellScript::~SpellScript() = default;
275
277{
278 for (EffectHandler& hook : OnEffectLaunch)
279 if (!hook.GetAffectedEffectsMask(entry))
280 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `OnEffectLaunch` of SpellScript won't be executed", entry->Id, hook.ToString(), m_scriptName);
281
283 if (!hook.GetAffectedEffectsMask(entry))
284 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `OnEffectLaunchTarget` of SpellScript won't be executed", entry->Id, hook.ToString(), m_scriptName);
285
286 for (EffectHandler& hook : OnEffectHit)
287 if (!hook.GetAffectedEffectsMask(entry))
288 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `OnEffectHit` of SpellScript won't be executed", entry->Id, hook.ToString(), m_scriptName);
289
290 for (EffectHandler& hook : OnEffectHitTarget)
291 if (!hook.GetAffectedEffectsMask(entry))
292 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `OnEffectHitTarget` of SpellScript won't be executed", entry->Id, hook.ToString(), m_scriptName);
293
295 if (!hook.GetAffectedEffectsMask(entry))
296 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `OnEffectSuccessfulDispel` of SpellScript won't be executed", entry->Id, hook.ToString(), m_scriptName);
297
299 if (!hook.GetAffectedEffectsMask(entry))
300 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `OnObjectAreaTargetSelect` of SpellScript won't be executed", entry->Id, hook.ToString(), m_scriptName);
301
303 if (!hook.GetAffectedEffectsMask(entry))
304 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `OnObjectTargetSelect` of SpellScript won't be executed", entry->Id, hook.ToString(), m_scriptName);
305
307 if (!hook.GetAffectedEffectsMask(entry))
308 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `OnDestinationTargetSelect` of SpellScript won't be executed", entry->Id, hook.ToString(), m_scriptName);
309
310 if (CalcDamage.size())
311 {
319 TC_LOG_ERROR("scripts", "Spell `{}` script `{}` does not have a damage effect - handler bound to hook `CalcDamage` of SpellScript won't be executed", entry->Id, m_scriptName);
320 }
321
322 if (CalcHealing.size())
323 {
324 if (!entry->HasEffect(SPELL_EFFECT_HEAL)
328 TC_LOG_ERROR("scripts", "Spell `{}` script `{}` does not have a damage effect - handler bound to hook `CalcHealing` of SpellScript won't be executed", entry->Id, m_scriptName);
329 }
330
331 return SpellScriptBase::_Validate(entry);
332}
333
335{
336 m_spell = spell;
338 bool load = Load();
340 return load;
341}
342
348
353
358
363
374
389
391{
392 // after hit hook executed after damage/healing is already done
393 // modifying it at this point has no effect
394 switch (m_currentScriptState)
395 {
400 return true;
401 }
402 return false;
403}
404
409
415
417{
418 return m_spell->GetCaster()->ToUnit();
419}
420
425
430
432{
433 return m_spell->GetSpellInfo();
434}
435
437{
438 return GetSpellInfo()->GetEffect(effIndex);
439}
440
442{
443 return m_spell->m_spellValue;
444}
445
447{
448 if (m_spell->m_targets.HasDst())
449 return m_spell->m_targets.GetDstPos();
450 return nullptr;
451}
452
457
462
467
472
477
479{
481 {
482 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::GetUnitTargetCountForEffect was called, but function has no effect in current hook! (spell has not selected targets yet)",
484 return 0;
485 }
486 return m_spell->GetUnitTargetCountForEffect(effect);
487}
488
490{
492 {
493 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::GetUnitTargetIndexForEffect was called, but function has no effect in current hook! (spell has not selected targets yet)",
495 return 0;
496 }
497 return m_spell->GetUnitTargetIndexForEffect(target, effect);
498}
499
501{
503 {
504 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::GetGameObjectTargetCountForEffect was called, but function has no effect in current hook! (spell has not selected targets yet)",
506 return 0;
507 }
509}
510
512{
514 {
515 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::GetItemTargetCountForEffect was called, but function has no effect in current hook! (spell has not selected targets yet)",
517 return 0;
518 }
519 return m_spell->GetItemTargetCountForEffect(effect);
520}
521
523{
525 {
526 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::GetCorpseTargetCountForEffect was called, but function has no effect in current hook! (spell has not selected targets yet)",
528 return 0;
529 }
531}
532
534{
535 if (!IsInTargetHook())
536 {
537 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::GetHitUnit was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
538 return nullptr;
539 }
540 return m_spell->unitTarget;
541}
542
544{
545 if (!IsInTargetHook())
546 {
547 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::GetHitCreature was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
548 return nullptr;
549 }
550 if (m_spell->unitTarget)
551 return m_spell->unitTarget->ToCreature();
552 return nullptr;
553}
554
556{
557 if (!IsInTargetHook())
558 {
559 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::GetHitPlayer was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
560 return nullptr;
561 }
562 if (m_spell->unitTarget)
563 return m_spell->unitTarget->ToPlayer();
564 return nullptr;
565}
566
568{
569 if (!IsInTargetHook())
570 {
571 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::GetHitItem was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
572 return nullptr;
573 }
574 return m_spell->itemTarget;
575}
576
578{
579 if (!IsInTargetHook())
580 {
581 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::GetHitGObj was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
582 return nullptr;
583 }
584 return m_spell->gameObjTarget;
585}
586
588{
589 if (!IsInTargetHook())
590 {
591 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::GetHitCorpse was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
592 return nullptr;
593 }
594 return m_spell->m_corpseTarget;
595}
596
598{
599 if (!IsInEffectHook())
600 {
601 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::GetHitDest was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
602 return nullptr;
603 }
604 return m_spell->destTarget;
605}
606
608{
609 if (!IsInTargetHook())
610 {
611 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::GetHitDamage was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
612 return 0;
613 }
614 return m_spell->m_damage;
615}
616
618{
619 if (!IsInModifiableHook())
620 {
621 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::SetHitDamage was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
622 return;
623 }
624 m_spell->m_damage = damage;
625}
626
628{
629 if (!IsInTargetHook())
630 {
631 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::GetHitHeal was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
632 return 0;
633 }
634 return m_spell->m_healing;
635}
636
638{
639 if (!IsInModifiableHook())
640 {
641 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::SetHitHeal was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
642 return;
643 }
644 m_spell->m_healing = heal;
645}
646
648{
649 if (!IsInTargetHook())
650 {
651 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::IsHitCrit was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
652 return false;
653 }
654 if (Unit* hitUnit = GetHitUnit())
655 {
656 auto itr = std::ranges::find(m_spell->m_UniqueTargetInfo, hitUnit->GetGUID(), &Spell::TargetInfo::TargetGUID);
657 ASSERT(itr != m_spell->m_UniqueTargetInfo.end());
658 return itr->IsCrit;
659 }
660 return false;
661}
662
663Aura* SpellScript::GetHitAura(bool dynObjAura /*= false*/, bool withRemoved /*= false*/) const
664{
665 if (!IsInTargetHook())
666 {
667 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::GetHitAura was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
668 return nullptr;
669 }
670
671 Aura* aura = m_spell->_spellAura;
672 if (dynObjAura)
673 aura = m_spell->_dynObjAura;
674
675 if (!aura || (aura->IsRemoved() && !withRemoved))
676 return nullptr;
677
678 return aura;
679}
680
682{
683 if (!IsInTargetHook())
684 {
685 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::PreventHitAura was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
686 return;
687 }
688 if (UnitAura* aura = m_spell->_spellAura)
689 aura->Remove();
690 if (DynObjAura* aura = m_spell->_dynObjAura)
691 aura->Remove();
692}
693
695{
696 if (!IsInHitPhase() && !IsInEffectHook())
697 {
698 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::PreventHitEffect was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
699 return;
700 }
701 m_hitPreventEffectMask |= 1 << effIndex;
702 PreventHitDefaultEffect(effIndex);
703}
704
706{
707 if (!IsInHitPhase() && !IsInEffectHook())
708 {
709 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::PreventHitDefaultEffect was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
710 return;
711 }
712 m_hitPreventDefaultEffectMask |= 1 << effIndex;
713}
714
716{
717 ASSERT(IsInEffectHook(), "Script: `" STRING_VIEW_FMT "` Spell: `%u`: function SpellScript::GetEffectInfo was called, but function has no effect in current hook!", STRING_VIEW_FMT_ARG(m_scriptName), m_scriptSpellId);
718
719 return *m_spell->effectInfo;
720}
721
723{
724 return static_cast<int32>(GetEffectValue());
725}
726
728{
729 if (!IsInEffectHook())
730 {
731 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::GetEffectValue was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
732 return 0;
733 }
734
735 return m_spell->effectValue;
736}
737
739{
740 if (!IsInEffectHook())
741 {
742 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::SetEffectValue was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
743 return;
744 }
745
747}
748
750{
751 if (!IsInEffectHook())
752 {
753 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::GetEffectVariance was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
754 return 0.0f;
755 }
756
757 return m_spell->variance;
758}
759
761{
762 if (!IsInEffectHook())
763 {
764 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::SetEffectVariance was called, but function has no effect in current hook!", m_scriptName, m_scriptSpellId);
765 return;
766 }
767
768 m_spell->variance = variance;
769}
770
772{
773 return m_spell->m_CastItem;
774}
775
777{
778 m_spell->DoCreateItem(itemId, context);
779}
780
785
786void SpellScript::FinishCast(SpellCastResult result, int32* param1 /*= nullptr*/, int32* param2 /*= nullptr*/)
787{
788 m_spell->SendCastResult(result, param1, param2);
789 m_spell->finish(result);
790}
791
793{
794 if (!IsInCheckCastHook())
795 {
796 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}`: function SpellScript::SetCustomCastResultMessage was called while spell not in check cast phase!", m_scriptName, m_scriptSpellId);
797 return;
798 }
799
800 m_spell->m_customError = result;
801}
802
807
826
828{
829 for (auto itr = DoCheckAreaTarget.begin(); itr != DoCheckAreaTarget.end(); ++itr)
831 TC_LOG_ERROR("scripts", "Spell `{}` of script `{}` does not have apply aura effect - handler bound to hook `DoCheckAreaTarget` of AuraScript won't be executed", entry->Id, m_scriptName);
832
833 for (auto itr = OnDispel.begin(); itr != OnDispel.end(); ++itr)
834 if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
835 TC_LOG_ERROR("scripts", "Spell `{}` of script `{}` does not have apply aura effect - handler bound to hook `OnDispel` of AuraScript won't be executed", entry->Id, m_scriptName);
836
837 for (auto itr = AfterDispel.begin(); itr != AfterDispel.end(); ++itr)
838 if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
839 TC_LOG_ERROR("scripts", "Spell `{}` of script `{}` does not have apply aura effect - handler bound to hook `AfterDispel` of AuraScript won't be executed", entry->Id, m_scriptName);
840
841 for (auto itr = OnEffectApply.begin(); itr != OnEffectApply.end(); ++itr)
842 if (!itr->GetAffectedEffectsMask(entry))
843 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `OnEffectApply` of AuraScript won't be executed", entry->Id, itr->ToString(), m_scriptName);
844
845 for (auto itr = OnEffectRemove.begin(); itr != OnEffectRemove.end(); ++itr)
846 if (!itr->GetAffectedEffectsMask(entry))
847 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `OnEffectRemove` of AuraScript won't be executed", entry->Id, itr->ToString(), m_scriptName);
848
849 for (auto itr = AfterEffectApply.begin(); itr != AfterEffectApply.end(); ++itr)
850 if (!itr->GetAffectedEffectsMask(entry))
851 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `AfterEffectApply` of AuraScript won't be executed", entry->Id, itr->ToString(), m_scriptName);
852
853 for (auto itr = AfterEffectRemove.begin(); itr != AfterEffectRemove.end(); ++itr)
854 if (!itr->GetAffectedEffectsMask(entry))
855 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `AfterEffectRemove` of AuraScript won't be executed", entry->Id, itr->ToString(), m_scriptName);
856
857 for (auto itr = OnEffectPeriodic.begin(); itr != OnEffectPeriodic.end(); ++itr)
858 if (!itr->GetAffectedEffectsMask(entry))
859 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `OnEffectPeriodic` of AuraScript won't be executed", entry->Id, itr->ToString(), m_scriptName);
860
861 for (auto itr = OnEffectUpdatePeriodic.begin(); itr != OnEffectUpdatePeriodic.end(); ++itr)
862 if (!itr->GetAffectedEffectsMask(entry))
863 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `OnEffectUpdatePeriodic` of AuraScript won't be executed", entry->Id, itr->ToString(), m_scriptName);
864
865 for (auto itr = DoEffectCalcAmount.begin(); itr != DoEffectCalcAmount.end(); ++itr)
866 if (!itr->GetAffectedEffectsMask(entry))
867 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `DoEffectCalcAmount` of AuraScript won't be executed", entry->Id, itr->ToString(), m_scriptName);
868
869 for (auto itr = DoEffectCalcPeriodic.begin(); itr != DoEffectCalcPeriodic.end(); ++itr)
870 if (!itr->GetAffectedEffectsMask(entry))
871 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `DoEffectCalcPeriodic` of AuraScript won't be executed", entry->Id, itr->ToString(), m_scriptName);
872
873 for (auto itr = DoEffectCalcSpellMod.begin(); itr != DoEffectCalcSpellMod.end(); ++itr)
874 if (!itr->GetAffectedEffectsMask(entry))
875 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `DoEffectCalcSpellMod` of AuraScript won't be executed", entry->Id, itr->ToString(), m_scriptName);
876
877 for (auto itr = DoEffectCalcCritChance.begin(); itr != DoEffectCalcCritChance.end(); ++itr)
878 if (!itr->GetAffectedEffectsMask(entry))
879 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `DoEffectCalcCritChance` of AuraScript won't be executed", entry->Id, itr->ToString(), m_scriptName);
880
881 for (EffectCalcDamageAndHealingHandler const& hook : DoEffectCalcDamageAndHealing)
882 if (!hook.GetAffectedEffectsMask(entry))
883 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `DoEffectCalcDamageAndHealing` of AuraScript won't be executed", entry->Id, hook.ToString(), m_scriptName);
884
885 for (auto itr = OnEffectAbsorb.begin(); itr != OnEffectAbsorb.end(); ++itr)
886 if (!itr->GetAffectedEffectsMask(entry))
887 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `OnEffectAbsorb` of AuraScript won't be executed", entry->Id, itr->ToString(), m_scriptName);
888
889 for (auto itr = AfterEffectAbsorb.begin(); itr != AfterEffectAbsorb.end(); ++itr)
890 if (!itr->GetAffectedEffectsMask(entry))
891 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `AfterEffectAbsorb` of AuraScript won't be executed", entry->Id, itr->ToString(), m_scriptName);
892
893 for (auto itr = OnEffectManaShield.begin(); itr != OnEffectManaShield.end(); ++itr)
894 if (!itr->GetAffectedEffectsMask(entry))
895 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `OnEffectManaShield` of AuraScript won't be executed", entry->Id, itr->ToString(), m_scriptName);
896
897 for (auto itr = AfterEffectManaShield.begin(); itr != AfterEffectManaShield.end(); ++itr)
898 if (!itr->GetAffectedEffectsMask(entry))
899 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `AfterEffectManaShield` of AuraScript won't be executed", entry->Id, itr->ToString(), m_scriptName);
900
901 for (auto itr = OnEffectSplit.begin(); itr != OnEffectSplit.end(); ++itr)
902 if (!itr->GetAffectedEffectsMask(entry))
903 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `OnEffectSplit` of AuraScript won't be executed", entry->Id, itr->ToString(), m_scriptName);
904
905 for (auto itr = DoCheckProc.begin(); itr != DoCheckProc.end(); ++itr)
906 if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
907 TC_LOG_ERROR("scripts", "Spell `{}` of script `{}` does not have apply aura effect - handler bound to hook `DoCheckProc` of AuraScript won't be executed", entry->Id, m_scriptName);
908
909 for (auto itr = DoCheckEffectProc.begin(); itr != DoCheckEffectProc.end(); ++itr)
910 if (!itr->GetAffectedEffectsMask(entry))
911 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `DoCheckEffectProc` of AuraScript won't be executed", entry->Id, itr->ToString(), m_scriptName);
912
913 for (auto itr = DoPrepareProc.begin(); itr != DoPrepareProc.end(); ++itr)
914 if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
915 TC_LOG_ERROR("scripts", "Spell `{}` of script `{}` does not have apply aura effect - handler bound to hook `DoPrepareProc` of AuraScript won't be executed", entry->Id, m_scriptName);
916
917 for (auto itr = OnProc.begin(); itr != OnProc.end(); ++itr)
918 if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
919 TC_LOG_ERROR("scripts", "Spell `{}` of script `{}` does not have apply aura effect - handler bound to hook `OnProc` of AuraScript won't be executed", entry->Id, m_scriptName);
920
921 for (auto itr = AfterProc.begin(); itr != AfterProc.end(); ++itr)
922 if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
923 TC_LOG_ERROR("scripts", "Spell `{}` of script `{}` does not have apply aura effect - handler bound to hook `AfterProc` of AuraScript won't be executed", entry->Id, m_scriptName);
924
925 for (auto itr = OnEffectProc.begin(); itr != OnEffectProc.end(); ++itr)
926 if (!itr->GetAffectedEffectsMask(entry))
927 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `OnEffectProc` of AuraScript won't be executed", entry->Id, itr->ToString(), m_scriptName);
928
929 for (auto itr = AfterEffectProc.begin(); itr != AfterEffectProc.end(); ++itr)
930 if (!itr->GetAffectedEffectsMask(entry))
931 TC_LOG_ERROR("scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `AfterEffectProc` of AuraScript won't be executed", entry->Id, itr->ToString(), m_scriptName);
932
933 return SpellScriptBase::_Validate(entry);
934}
935
937 : EffectHook(effIndex), _auraType(auraType) { }
938
939AuraScript::EffectBase::EffectBase(EffectBase&& right) noexcept = default;
942
943bool AuraScript::EffectBase::CheckEffect(SpellInfo const* spellInfo, uint8 effIndex) const
944{
945 if (spellInfo->GetEffects().size() <= effIndex)
946 return false;
947 SpellEffectInfo const& spellEffectInfo = spellInfo->GetEffect(SpellEffIndex(effIndex));
948 if (!spellEffectInfo.ApplyAuraName && !_auraType)
949 return true;
950 if (!spellEffectInfo.ApplyAuraName)
951 return false;
952 return (_auraType == SPELL_AURA_ANY) || (spellEffectInfo.ApplyAuraName == _auraType);
953}
954
956{
957 switch (_auraType)
958 {
959 case SPELL_AURA_ANY:
960 return Trinity::StringFormat("Index: {}, AuraName: SPELL_AURA_ANY", EffIndexToString());
961 default:
962 return Trinity::StringFormat("Index: {}, AuraName: SPELL_AURA_{}", EffIndexToString(), _auraType);
963 }
964}
965
967{
968}
969
970AuraScript::~AuraScript() = default;
971
973{
974 m_aura = aura;
976 bool load = Load();
978 return load;
979}
980
988
997
999{
1000 switch (m_currentScriptState)
1001 {
1011 default:
1012 ABORT_MSG("AuraScript::_IsDefaultActionPrevented is called in a wrong place");
1013 return false;
1014 }
1015}
1016
1018{
1019 switch (m_currentScriptState)
1020 {
1030 break;
1031 default:
1032 TC_LOG_ERROR("scripts", "Script: `{}` Spell: `{}` AuraScript::PreventDefaultAction called in a hook in which the call won't have effect!", m_scriptName, m_scriptSpellId);
1033 break;
1034 }
1035}
1036
1038{
1039 return m_aura->GetSpellInfo();
1040}
1041
1043{
1044 return m_aura->GetSpellInfo()->GetEffect(effIndex);
1045}
1046
1048{
1049 return m_aura->GetId();
1050}
1051
1053{
1054 return m_aura->GetCasterGUID();
1055}
1056
1058{
1059 if (WorldObject* caster = m_aura->GetCaster())
1060 return caster->ToUnit();
1061 return nullptr;
1062}
1063
1065{
1066 if (WorldObject* caster = m_aura->GetCaster())
1067 return caster->ToGameObject();
1068 return nullptr;
1069}
1070
1072{
1073 return m_aura->GetOwner();
1074}
1075
1077{
1078 return m_aura->GetUnitOwner();
1079}
1080
1085
1087{
1088 m_aura->Remove(removeMode);
1089}
1090
1092{
1093 return m_aura;
1094}
1095
1097{
1098 return m_aura->GetType();
1099}
1100
1102{
1103 return m_aura->GetDuration();
1104}
1105
1106void AuraScript::SetDuration(int32 duration, bool withMods)
1107{
1108 m_aura->SetDuration(duration, withMods);
1109}
1110
1115
1117{
1118 return m_aura->GetApplyTime();
1119}
1120
1122{
1123 return m_aura->GetMaxDuration();
1124}
1125
1127{
1128 m_aura->SetMaxDuration(duration);
1129}
1130
1132{
1133 return m_aura->CalcMaxDuration();
1134}
1135
1137{
1138 return m_aura->IsExpired();
1139}
1140
1142{
1143 return m_aura->IsPermanent();
1144}
1145
1147{
1148 return m_aura->GetCharges();
1149}
1150
1152{
1153 m_aura->SetCharges(charges);
1154}
1155
1157{
1158 return m_aura->CalcMaxCharges();
1159}
1160
1161bool AuraScript::ModCharges(int8 num, AuraRemoveMode removeMode /*= AURA_REMOVE_BY_DEFAULT*/)
1162{
1163 return m_aura->ModCharges(num, removeMode);
1164}
1165
1167{
1168 return m_aura->DropCharge(removeMode);
1169}
1170
1172{
1173 return m_aura->GetStackAmount();
1174}
1175
1177{
1178 m_aura->SetStackAmount(num);
1179}
1180
1182{
1183 return m_aura->ModStackAmount(num, removeMode);
1184}
1185
1187{
1188 return m_aura->IsPassive();
1189}
1190
1192{
1193 return m_aura->IsDeathPersistent();
1194}
1195
1196bool AuraScript::HasEffect(uint8 effIndex) const
1197{
1198 return m_aura->HasEffect(effIndex);
1199}
1200
1202{
1203 return m_aura->GetEffect(effIndex);
1204}
1205
1207{
1208 return m_aura->HasEffectType(type);
1209}
1210
1242
1247
ItemContext
Definition DBCEnums.h:1315
Difficulty
Definition DBCEnums.h:932
@ DIFFICULTY_NONE
Definition DBCEnums.h:933
#define MAX_SPELL_EFFECTS
Definition DBCEnums.h:2430
#define TC_GAME_API
Definition Define.h:129
uint8_t uint8
Definition Define.h:156
#define STRING_VIEW_FMT_ARG(str)
Definition Define.h:147
int64_t int64
Definition Define.h:149
int8_t int8
Definition Define.h:152
#define STRING_VIEW_FMT
Definition Define.h:146
int32_t int32
Definition Define.h:150
uint16_t uint16
Definition Define.h:155
uint32_t uint32
Definition Define.h:154
#define ABORT_MSG
Definition Errors.h:88
#define ASSERT
Definition Errors.h:80
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:190
#define sScriptMgr
Definition ScriptMgr.h:1449
SpellEffIndex
#define EFFECT_FIRST_FOUND
@ SPELL_EFFECT_HEALTH_LEECH
@ SPELL_EFFECT_WEAPON_DAMAGE
@ SPELL_EFFECT_HEAL
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
@ SPELL_EFFECT_HEAL_MECHANICAL
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
@ SPELL_EFFECT_PERSISTENT_AREA_AURA
@ SPELL_EFFECT_POWER_DRAIN
@ SPELL_EFFECT_SCHOOL_DAMAGE
@ SPELL_EFFECT_HEAL_PCT
@ SPELL_EFFECT_APPLY_AURA
SpellCustomErrors
SpellCastResult
#define EFFECT_ALL
AuraRemoveMode
AuraObjectType
@ TARGET_SELECT_CATEGORY_CONE
Definition SpellInfo.h:47
@ TARGET_SELECT_CATEGORY_AREA
Definition SpellInfo.h:48
@ TARGET_SELECT_CATEGORY_DEFAULT
Definition SpellInfo.h:44
@ TARGET_SELECT_CATEGORY_NEARBY
Definition SpellInfo.h:46
@ TARGET_SELECT_CATEGORY_LINE
Definition SpellInfo.h:50
@ TARGET_SELECT_CATEGORY_CHANNEL
Definition SpellInfo.h:45
@ TARGET_OBJECT_TYPE_UNIT_AND_DEST
Definition SpellInfo.h:69
@ TARGET_OBJECT_TYPE_DEST
Definition SpellInfo.h:67
@ TARGET_OBJECT_TYPE_SRC
Definition SpellInfo.h:66
@ TARGET_REFERENCE_TYPE_TARGET
Definition SpellInfo.h:57
@ TARGET_REFERENCE_TYPE_CASTER
Definition SpellInfo.h:56
#define sSpellMgr
Definition SpellMgr.h:812
AuraScriptHookType
@ AURA_SCRIPT_HOOK_CHECK_EFFECT_PROC
@ AURA_SCRIPT_HOOK_EFFECT_CALC_DAMAGE_AND_HEALING
@ AURA_SCRIPT_HOOK_EFFECT_REMOVE
@ AURA_SCRIPT_HOOK_EFFECT_CALC_CRIT_CHANCE
@ AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD
@ AURA_SCRIPT_HOOK_PREPARE_PROC
@ AURA_SCRIPT_HOOK_EFFECT_AFTER_APPLY
@ AURA_SCRIPT_HOOK_EFFECT_AFTER_REMOVE
@ AURA_SCRIPT_HOOK_AFTER_PROC
@ AURA_SCRIPT_HOOK_EFFECT_MANASHIELD
@ AURA_SCRIPT_HOOK_PROC
@ AURA_SCRIPT_HOOK_EFFECT_AFTER_ABSORB
@ AURA_SCRIPT_HOOK_EFFECT_APPLY
@ AURA_SCRIPT_HOOK_EFFECT_PERIODIC
@ AURA_SCRIPT_HOOK_EFFECT_AFTER_PROC
@ AURA_SCRIPT_HOOK_EFFECT_ABSORB
@ AURA_SCRIPT_HOOK_EFFECT_PROC
@ AURA_SCRIPT_HOOK_EFFECT_SPLIT
@ AURA_SCRIPT_HOOK_CHECK_PROC
@ AURA_SCRIPT_HOOK_ENTER_LEAVE_COMBAT
@ SPELL_SCRIPT_STATE_NONE
Definition SpellScript.h:65
@ SPELL_SCRIPT_STATE_LOADING
Definition SpellScript.h:67
@ SPELL_SCRIPT_STATE_UNLOADING
Definition SpellScript.h:68
@ SPELL_SCRIPT_STATE_REGISTRATION
Definition SpellScript.h:66
double SpellEffectValue
Definition SpellScript.h:58
#define HOOK_SPELL_HIT_START
#define HOOK_SPELL_HIT_END
SpellScriptHookType
@ SPELL_SCRIPT_HOOK_AFTER_CAST
@ SPELL_SCRIPT_HOOK_AFTER_HIT
@ SPELL_SCRIPT_HOOK_EFFECT_SUCCESSFUL_DISPEL
@ SPELL_SCRIPT_HOOK_CALC_HEALING
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH
@ SPELL_SCRIPT_HOOK_BEFORE_HIT
@ SPELL_SCRIPT_HOOK_CALC_DAMAGE
@ SPELL_SCRIPT_HOOK_CHECK_CAST
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET
@ SPELL_SCRIPT_HOOK_HIT
@ SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET
@ SPELL_SCRIPT_HOOK_CALC_CRIT_CHANCE
@ SPELL_SCRIPT_HOOK_ON_CAST
#define SPELL_EFFECT_ANY
Definition SpellScript.h:60
#define SPELL_AURA_ANY
Definition SpellScript.h:61
Unit * GetTarget() const
Definition SpellAuras.h:81
std::string ToString() const
EffectBase & operator=(EffectBase const &right)=delete
EffectBase(uint8 effIndex, uint16 auraType)
bool CheckEffect(SpellInfo const *spellInfo, uint8 effIndex) const override
AuraApplication const * _auraApplication
bool IsPermanent() const
void PreventDefaultAction()
AuraObjectType GetType() const
bool IsExpired() const
void _PrepareScriptCall(AuraScriptHookType hookType, AuraApplication const *aurApp=nullptr)
void SetMaxDuration(int32 duration)
AuraApplication const * GetTargetApplication() const
int32 GetDuration() const
AuraApplication const * m_auraApplication
bool ModCharges(int8 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
bool m_defaultActionPrevented
SpellInfo const * GetSpellInfo() const
WorldObject * GetOwner() const
uint8 CalcMaxCharges() const
int32 GetMaxDuration() const
time_t GetApplyTime() const
void SetCharges(uint8 charges)
Unit * GetCaster() const
void SetDuration(int32 duration, bool withMods=false)
bool DropCharge(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
SpellEffectInfo const & GetEffectInfo(SpellEffIndex effIndex) const
AuraEffect * GetEffect(uint8 effIndex) const
bool HasEffectType(AuraType type) const
bool _Validate(SpellInfo const *entry) override
Aura * GetAura() const
Unit * GetTarget() const
ObjectGuid GetCasterGUID() const
void RefreshDuration()
bool IsDeathPersistent() const
AuraScript() noexcept
Aura * m_aura
GameObject * GetGObjCaster() const
Difficulty GetCastDifficulty() const
bool _Load(Aura *aura)
void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
ScriptStateStack m_scriptStates
int32 CalcMaxDuration() const
uint8 GetCharges() const
void SetStackAmount(uint8 num)
Unit * GetUnitOwner() const
bool _IsDefaultActionPrevented() const
void _FinishScriptCall()
bool HasEffect(uint8 effIndex) const
uint8 GetStackAmount() const
DynamicObject * GetDynobjOwner() const
bool IsPassive() const
uint32 GetId() const
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
int32 GetMaxDuration() const
Definition SpellAuras.h:217
void SetStackAmount(uint8 num)
Unit * GetUnitOwner() const
Definition SpellAuras.h:196
void RefreshDuration(bool withMods=false)
DynamicObject * GetDynobjOwner() const
Definition SpellAuras.h:197
ObjectGuid GetCasterGUID() const
Definition SpellAuras.h:187
bool HasEffect(uint8 effIndex) const
Definition SpellAuras.h:277
bool IsRemoved() const
Definition SpellAuras.h:254
WorldObject * GetOwner() const
Definition SpellAuras.h:195
bool ModCharges(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
uint32 GetId() const
Definition SpellAuras.h:183
int32 GetDuration() const
Definition SpellAuras.h:222
bool IsDeathPersistent() const
bool HasEffectType(AuraType type) const
AuraEffect * GetEffect(uint32 index) const
Unit * GetCaster() const
uint8 CalcMaxCharges(Unit *caster) const
void SetCharges(uint8 charges)
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool resetPeriodicTimer=true)
int32 CalcMaxDuration() const
Definition SpellAuras.h:219
void SetDuration(int32 duration, bool withMods=false)
AuraObjectType GetType() const
uint8 GetStackAmount() const
Definition SpellAuras.h:238
uint8 GetCharges() const
Definition SpellAuras.h:229
SpellInfo const * GetSpellInfo() const
Definition SpellAuras.h:182
void SetMaxDuration(int32 duration)
Definition SpellAuras.h:218
Difficulty GetCastDifficulty() const
Definition SpellAuras.h:184
bool IsExpired() const
Definition SpellAuras.h:226
bool IsPassive() const
time_t GetApplyTime() const
Definition SpellAuras.h:216
bool IsPermanent() const
Definition SpellAuras.h:227
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
bool DropCharge(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition SpellAuras.h:234
Definition Item.h:179
Player * ToPlayer()
Definition Object.h:126
GameObject * ToGameObject()
Definition Object.h:131
Creature * ToCreature()
Definition Object.h:121
Unit * ToUnit()
Definition Object.h:116
WorldObject * GetObjectTarget() const
Definition Spell.cpp:246
GameObject * GetGOTarget() const
Definition Spell.cpp:212
void SetDst(float x, float y, float z, float orientation, uint32 mapId=MAPID_INVALID)
Definition Spell.cpp:341
bool HasDst() const
Definition Spell.cpp:393
Item * GetItemTarget() const
Unit * GetUnitTarget() const
Definition Spell.cpp:186
WorldLocation const * GetDstPos() const
Definition Spell.cpp:336
AuraType ApplyAuraName
Definition SpellInfo.h:216
SpellEffectName Effect
Definition SpellInfo.h:215
static constexpr SpellEffectValue MaxValue
Definition SpellInfo.h:267
static constexpr SpellEffectValue MinValue
Definition SpellInfo.h:266
SpellImplicitTargetInfo TargetA
Definition SpellInfo.h:228
SpellImplicitTargetInfo TargetB
Definition SpellInfo.h:229
SpellTargetReferenceTypes GetReferenceType() const
Definition SpellInfo.cpp:88
SpellTargetSelectionCategories GetSelectionCategory() const
Definition SpellInfo.cpp:83
SpellTargetObjectTypes GetObjectType() const
Definition SpellInfo.cpp:93
Targets GetTarget() const
bool HasEffect(SpellEffectName effect) const
uint32 const Id
Definition SpellInfo.h:328
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition SpellInfo.h:588
std::vector< SpellEffectInfo > const & GetEffects() const
Definition SpellInfo.h:587
bool HasAreaAuraEffect() const
bool IsEffectAffected(SpellInfo const *spellInfo, uint8 effIndex) const
uint32 GetAffectedEffectsMask(SpellInfo const *spellInfo) const
EffectHook & operator=(EffectHook const &right)=delete
std::string EffIndexToString() const
HookList & operator+=(T &&t) noexcept
uint32 m_scriptSpellId
uint8 m_currentScriptState
void _Init(std::string const &scriptname, uint32 spellId)
virtual void Register()=0
virtual bool Validate(SpellInfo const *spellInfo)
std::string_view m_scriptName
static bool ValidateSpellInfoImpl(Iterator begin, Iterator end)
static bool ValidateSpellEffectImpl(uint32 spellId, SpellEffIndex effectIndex)
virtual bool Load()
virtual ~SpellScriptBase()
SpellScriptBase() noexcept
std::string_view GetScriptName() const
virtual void Unload()
virtual bool _Validate(SpellInfo const *entry)
bool CheckEffect(SpellInfo const *spellInfo, uint8 effIndex) const override
EffectBase & operator=(EffectBase const &right)=delete
EffectBase(uint8 effIndex, uint16 effName)
std::string ToString() const
std::string ToString() const
bool CheckEffect(SpellInfo const *spellInfo, uint8 effIndex) const override
TargetHook(uint8 effectIndex, uint16 targetType, bool area, bool dest)
TargetHook & operator=(TargetHook const &right)=delete
bool IsHitCrit() const
HookList< DamageAndHealingCalcHandler > CalcDamage
WorldLocation * GetHitDest() const
Creature * GetHitCreature() const
Player * GetHitPlayer() const
Aura * GetHitAura(bool dynObjAura=false, bool withRemoved=false) const
int32 GetHitDamage() const
int64 GetCorpseTargetCountForEffect(SpellEffIndex effect) const
Unit * GetCaster() const
bool IsInEffectHook() const
void SetEffectVariance(float variance)
void SetEffectValue(SpellEffectValue value)
bool _Load(Spell *spell)
SpellEffectValue GetEffectValue() const
HookList< DestinationTargetSelectHandler > OnDestinationTargetSelect
int32 GetEffectValueAsInt() const
SpellScript() noexcept
void CreateItem(uint32 itemId, ItemContext context)
uint32 m_hitPreventDefaultEffectMask
bool IsInTargetHook() const
uint32 m_hitPreventEffectMask
bool IsAfterTargetSelectionPhase() const
HookList< EffectHandler > OnEffectHit
void PreventHitDefaultEffect(SpellEffIndex effIndex)
int64 GetUnitTargetCountForEffect(SpellEffIndex effect) const
SpellInfo const * GetTriggeringSpell() const
Unit * GetHitUnit() const
SpellValue const * GetSpellValue() const
bool IsInHitPhase() const
SpellEffectInfo const & GetEffectInfo() const
HookList< EffectHandler > OnEffectHitTarget
Corpse * GetHitCorpse() const
void PreventHitEffect(SpellEffIndex effIndex)
Item * GetCastItem() const
HookList< ObjectTargetSelectHandler > OnObjectTargetSelect
bool _Validate(SpellInfo const *entry) override
void SetExplTargetDest(WorldLocation const &loc)
Spell * m_spell
void SetCustomCastResultMessage(SpellCustomErrors result)
void FinishCast(SpellCastResult result, int32 *param1=nullptr, int32 *param2=nullptr)
WorldObject * GetExplTargetWorldObject() const
HookList< EffectHandler > OnEffectLaunchTarget
Item * GetHitItem() const
int64 GetItemTargetCountForEffect(SpellEffIndex effect) const
Difficulty GetCastDifficulty() const
int32 GetHitHeal() const
int32 GetUnitTargetIndexForEffect(ObjectGuid const &target, SpellEffIndex effect) const
void SetHitDamage(int32 damage)
HookList< EffectHandler > OnEffectSuccessfulDispel
WorldLocation const * GetExplTargetDest() const
bool IsInCheckCastHook() const
HookList< EffectHandler > OnEffectLaunch
void SetHitHeal(int32 heal)
HookList< DamageAndHealingCalcHandler > CalcHealing
GameObject * GetExplTargetGObj() const
GameObject * GetGObjCaster() const
void PreventHitAura()
Item * GetExplTargetItem() const
bool IsInModifiableHook() const
Unit * GetExplTargetUnit() const
int64 GetGameObjectTargetCountForEffect(SpellEffIndex effect) const
void _PrepareScriptCall(SpellScriptHookType hookType)
SpellInfo const * GetSpellInfo() const
float GetEffectVariance() const
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
Unit * GetOriginalCaster() const
GameObject * GetHitGObj() const
void _FinishScriptCall()
Definition Spell.h:277
SpellInfo const * GetSpellInfo() const
Definition Spell.h:702
GameObject * gameObjTarget
Definition Spell.h:799
DynObjAura * _dynObjAura
Definition Spell.h:811
int64 GetCorpseTargetCountForEffect(SpellEffIndex effect) const
Definition Spell.cpp:2724
SpellCastTargets m_targets
Definition Spell.h:651
Difficulty GetCastDifficulty() const
Definition Spell.cpp:8233
std::vector< TargetInfo > m_UniqueTargetInfo
Definition Spell.h:877
int64 GetItemTargetCountForEffect(SpellEffIndex effect) const
Definition Spell.cpp:2716
Item * itemTarget
Definition Spell.h:798
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, SpellCastVisual spellVisual, ObjectGuid cast_count, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE, int32 *param1=nullptr, int32 *param2=nullptr)
Definition Spell.cpp:4699
float variance
Definition Spell.h:805
int32 m_damage
Definition Spell.h:817
void DoCreateItem(uint32 itemId, ItemContext context=ItemContext::NONE, std::vector< int32 > const *bonusListIDs=nullptr)
SpellEffectValue effectValue
Definition Spell.h:802
int64 GetGameObjectTargetCountForEffect(SpellEffIndex effect) const
Definition Spell.cpp:2708
SpellCustomErrors m_customError
Definition Spell.h:652
int32 m_healing
Definition Spell.h:818
SpellEffectInfo const * effectInfo
Definition Spell.h:807
SpellInfo const * m_triggeredByAuraSpell
Definition Spell.h:997
UnitAura * _spellAura
Definition Spell.h:810
Unit * unitTarget
Definition Spell.h:797
WorldObject * GetCaster() const
Definition Spell.h:699
Unit * GetOriginalCaster() const
Definition Spell.h:701
Corpse * m_corpseTarget
Definition Spell.h:800
WorldLocation * destTarget
Definition Spell.h:801
Item * m_CastItem
Definition Spell.h:600
int32 GetUnitTargetIndexForEffect(ObjectGuid const &target, SpellEffIndex effect) const
Definition Spell.cpp:2683
SpellValue *const m_spellValue
Definition Spell.h:747
void finish(SpellCastResult result=SPELL_CAST_OK)
Definition Spell.cpp:4342
int64 GetUnitTargetCountForEffect(SpellEffIndex effect) const
Definition Spell.cpp:2700
Definition Unit.h:635
std::string StringFormat(FormatString< Args... > fmt, Args &&... args) noexcept
Default TC string format function.
ObjectGuid TargetGUID
Definition Spell.h:853