TrinityCore
SpellInfo.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 "SpellInfo.h"
19#include "Battleground.h"
20#include "Containers.h"
21#include "Corpse.h"
22#include "DB2Stores.h"
23#include "FlatSet.h"
24#include "GameTables.h"
25#include "InstanceScript.h"
26#include "Item.h"
27#include "ItemTemplate.h"
28#include "Log.h"
29#include "LootMgr.h"
30#include "Map.h"
31#include "ObjectAccessor.h"
32#include "Pet.h"
33#include "Player.h"
34#include "Random.h"
35#include "Spell.h"
36#include "SpellAuraEffects.h"
37#include "SpellMgr.h"
38#include "Vehicle.h"
39#include <G3D/g3dmath.h>
40
42{
43 switch (objType)
44 {
56 return TARGET_FLAG_UNIT;
62 return TARGET_FLAG_ITEM;
65 default:
66 return TARGET_FLAG_NONE;
67 }
68}
69
71{
72 _target = Targets(target);
73}
74
76{
78}
79
81{
82 return _data[_target].SelectionCategory;
83}
84
86{
87 return _data[_target].ReferenceType;
88}
89
91{
92 return _data[_target].ObjectType;
93}
94
96{
97 return _data[_target].SelectionCheckType;
98}
99
101{
102 return _data[_target].DirectionType;
103}
104
106{
107 switch (GetDirectionType())
108 {
109 case TARGET_DIR_FRONT:
110 return 0.0f;
111 case TARGET_DIR_BACK:
112 return static_cast<float>(M_PI);
113 case TARGET_DIR_RIGHT:
114 return static_cast<float>(-M_PI/2);
115 case TARGET_DIR_LEFT:
116 return static_cast<float>(M_PI/2);
118 return static_cast<float>(-M_PI/4);
120 return static_cast<float>(-3*M_PI/4);
122 return static_cast<float>(3*M_PI/4);
124 return static_cast<float>(M_PI/4);
126 return rand_norm() * static_cast<float>(2 * M_PI);
127 default:
128 return 0.0f;
129 }
130}
131
133{
134 return _target;
135}
136
138{
139 uint32 targetMask = 0;
141 {
142 if (!srcSet)
143 targetMask = TARGET_FLAG_SOURCE_LOCATION;
144 if (!dstSet)
145 targetMask |= TARGET_FLAG_DEST_LOCATION;
146 }
147 else
148 {
149 switch (GetReferenceType())
150 {
152 if (srcSet)
153 break;
154 targetMask = TARGET_FLAG_SOURCE_LOCATION;
155 break;
157 if (dstSet)
158 break;
159 targetMask = TARGET_FLAG_DEST_LOCATION;
160 break;
162 switch (GetObjectType())
163 {
165 targetMask = TARGET_FLAG_GAMEOBJECT;
166 break;
168 targetMask = TARGET_FLAG_GAMEOBJECT_ITEM;
169 break;
173 switch (GetCheckType())
174 {
176 targetMask = TARGET_FLAG_UNIT_ENEMY;
177 break;
179 targetMask = TARGET_FLAG_UNIT_ALLY;
180 break;
182 targetMask = TARGET_FLAG_UNIT_PARTY;
183 break;
185 targetMask = TARGET_FLAG_UNIT_RAID;
186 break;
188 targetMask = TARGET_FLAG_UNIT_PASSENGER;
189 break;
191 [[fallthrough]];
192 default:
193 targetMask = TARGET_FLAG_UNIT;
194 break;
195 }
196 break;
197 default:
198 break;
199 }
200 break;
201 default:
202 break;
203 }
204 }
205
206 switch (GetObjectType())
207 {
209 srcSet = true;
210 break;
213 dstSet = true;
214 break;
215 default:
216 break;
217 }
218 return targetMask;
219}
220
222{
223 ImmunityInfo() = default;
224 ~ImmunityInfo() = default;
225
226 ImmunityInfo(ImmunityInfo const&) = delete;
227 ImmunityInfo(ImmunityInfo&&) noexcept = delete;
228 ImmunityInfo& operator=(ImmunityInfo const&) = delete;
229 ImmunityInfo& operator=(ImmunityInfo&&) noexcept = delete;
230
237
238 Trinity::Containers::FlatSet<AuraType> AuraTypeImmune;
240};
241
243{ {
397} };
398
405{
406}
407
409 : EffectAttributes(SpellEffectAttributes::None)
410{
411 ASSERT(spellInfo);
412
413 _spellInfo = spellInfo;
415 Effect = SpellEffectName(_effect.Effect);
421 Amplitude = _effect.EffectAmplitude;
424 MiscValue = _effect.EffectMiscValue[0];
425 MiscValueB = _effect.EffectMiscValue[1];
433 ItemType = _effect.EffectItemType;
437 Scaling.Class = _effect.ScalingClass;
439 Scaling.Variance = _effect.Variance;
441 ImplicitTargetConditions = nullptr;
443 _immunityInfo = nullptr;
444}
445
447SpellEffectInfo& SpellEffectInfo::operator=(SpellEffectInfo&&) noexcept = default;
448
449SpellEffectInfo::~SpellEffectInfo() = default;
450
451bool SpellEffectInfo::IsEffect() const
452{
453 return Effect != 0;
454}
455
457{
458 return Effect == effectName;
459}
460
462{
464}
465
467{
468 return IsAura() && ApplyAuraName == uint32(aura);
469}
470
472{
473 return TargetA.IsArea() || TargetB.IsArea();
474}
475
477{
486 return true;
487 return false;
488}
489
491{
493}
494
495int32 SpellEffectInfo::CalcValue(WorldObject const* caster /*= nullptr*/, int32 const* bp /*= nullptr*/, Unit const* target /*= nullptr*/, float* variance /*= nullptr*/, uint32 castItemId /*= 0*/, int32 itemLevel /*= -1*/) const
496{
497 double basePointsPerLevel = RealPointsPerLevel;
498 // TODO: this needs to be a float, not rounded
499 int32 basePoints = CalcBaseValue(caster, target, castItemId, itemLevel);
500 double value = bp ? *bp : basePoints;
501 double comboDamage = PointsPerResource;
502
503 Unit const* casterUnit = nullptr;
504 if (caster)
505 casterUnit = caster->ToUnit();
506
507 if (Scaling.Variance)
508 {
509 float delta = fabs(Scaling.Variance * 0.5f);
510 double valueVariance = frand(-delta, delta);
511 value += double(basePoints) * valueVariance;
512
513 if (variance)
514 *variance = valueVariance;
515 }
516
517 // base amount modification based on spell lvl vs caster lvl
518 if (Scaling.Coefficient != 0.0f)
519 {
521 comboDamage = Scaling.ResourceCoefficient * value;
522 }
524 {
525 if (casterUnit && basePointsPerLevel != 0.0)
526 {
527 int32 level = int32(casterUnit->GetLevel());
528 if (level > int32(_spellInfo->MaxLevel) && _spellInfo->MaxLevel > 0)
529 level = int32(_spellInfo->MaxLevel);
530
531 // if base level is greater than spell level, reduce by base level (eg. pilgrims foods)
532 level -= int32(std::max(_spellInfo->BaseLevel, _spellInfo->SpellLevel));
533 if (level < 0)
534 level = 0;
535 value += level * basePointsPerLevel;
536 }
537 }
538
539 // random damage
540 if (casterUnit)
541 {
542 // bonus amount from combo points
543 if (comboDamage)
544 if (int32 comboPoints = casterUnit->GetPower(POWER_COMBO_POINTS))
545 value += comboDamage * comboPoints;
546 }
547
548 if (caster)
549 value = caster->ApplyEffectModifiers(_spellInfo, EffectIndex, value);
550
551 return int32(round(value));
552}
553
554int32 SpellEffectInfo::CalcBaseValue(WorldObject const* caster, Unit const* target, uint32 itemId, int32 itemLevel) const
555{
556 if (Scaling.Coefficient != 0.0f)
557 {
560 level = target->GetLevel();
561 else if (caster && caster->IsUnit())
562 level = caster->ToUnit()->GetLevel();
563
565 level = _spellInfo->BaseLevel;
566
569
572
573 float value = 0.0f;
574 if (level > 0)
575 {
576 if (!Scaling.Class)
577 return 0;
578
579 uint32 effectiveItemLevel = itemLevel != -1 ? uint32(itemLevel) : 1u;
581 {
583 effectiveItemLevel = _spellInfo->Scaling.ScalesFromItemLevel;
584
585 if (Scaling.Class == -8 || Scaling.Class == -9)
586 {
587 RandPropPointsEntry const* randPropPoints = sRandPropPointsStore.LookupEntry(effectiveItemLevel);
588 if (!randPropPoints)
589 randPropPoints = sRandPropPointsStore.AssertEntry(sRandPropPointsStore.GetNumRows() - 1);
590
591 value = Scaling.Class == -8 ? randPropPoints->DamageReplaceStatF : randPropPoints->DamageSecondaryF;
592 }
593 else
594 value = GetRandomPropertyPoints(effectiveItemLevel, ITEM_QUALITY_RARE, INVTYPE_CHEST, 0);
595 }
596 else
598
599 if (Scaling.Class == -7)
600 if (GtCombatRatingsMultByILvl const* ratingMult = sCombatRatingsMultByILvlGameTable.GetRow(effectiveItemLevel))
601 if (ItemSparseEntry const* itemSparse = sItemSparseStore.LookupEntry(itemId))
602 value *= GetIlvlStatMultiplier(ratingMult, InventoryType(itemSparse->InventoryType));
603
604 if (Scaling.Class == -6)
605 if (GtStaminaMultByILvl const* staminaMult = sStaminaMultByILvlGameTable.GetRow(effectiveItemLevel))
606 if (ItemSparseEntry const* itemSparse = sItemSparseStore.LookupEntry(itemId))
607 value *= GetIlvlStatMultiplier(staminaMult, InventoryType(itemSparse->InventoryType));
608 }
609
610 value *= Scaling.Coefficient;
611 if (value > 0.0f && value < 1.0f)
612 value = 1.0f;
613
614 return int32(round(value));
615 }
616 else
617 {
618 float value = BasePoints;
620 if (stat != ExpectedStatType::None)
621 {
624
625 // TODO - add expansion and content tuning id args?
626 uint32 contentTuningId = _spellInfo->ContentTuningId; // content tuning should be passed as arg, the one stored in SpellInfo is fallback
627 int32 expansion = -2;
628 if (ContentTuningEntry const* contentTuning = sContentTuningStore.LookupEntry(contentTuningId))
629 expansion = contentTuning->ExpansionID;
630
631 int32 level = 1;
633 level = target->GetLevel();
634 else if (caster && caster->IsUnit())
635 level = caster->ToUnit()->GetLevel();
636
637 value = sDB2Manager.EvaluateExpectedStat(stat, level, expansion, 0, CLASS_NONE, 0) * BasePoints / 100.0f;
638 }
639
640 return int32(round(value));
641 }
642}
643
644float SpellEffectInfo::CalcValueMultiplier(WorldObject* caster, Spell* spell /*= nullptr*/) const
645{
646 float multiplier = Amplitude;
647 if (Player* modOwner = (caster ? caster->GetSpellModOwner() : nullptr))
648 modOwner->ApplySpellMod(_spellInfo, SpellModOp::Amplitude, multiplier, spell);
649 return multiplier;
650}
651
652float SpellEffectInfo::CalcDamageMultiplier(WorldObject* caster, Spell* spell /*= nullptr*/) const
653{
654 float multiplierPercent = ChainAmplitude * 100.0f;
655 if (Player* modOwner = (caster ? caster->GetSpellModOwner() : nullptr))
656 modOwner->ApplySpellMod(_spellInfo, SpellModOp::ChainAmplitude, multiplierPercent, spell);
657 return multiplierPercent / 100.0f;
658}
659
661{
662 switch (targetIndex)
663 {
665 return TargetARadiusEntry != nullptr;
667 return TargetBRadiusEntry != nullptr;
668 default:
669 return false;
670 }
671}
672
673float SpellEffectInfo::CalcRadius(WorldObject* caster /*= nullptr*/, SpellTargetIndex targetIndex /*=SpellTargetIndex::TargetA*/, Spell* spell /*= nullptr*/) const
674{
675 // TargetA -> TargetARadiusEntry
676 // TargetB -> TargetBRadiusEntry
677 // Aura effects have TargetARadiusEntry == TargetBRadiusEntry (mostly)
680 if (targetIndex == SpellTargetIndex::TargetB && HasRadius(targetIndex))
681 {
682 target = TargetB;
683 entry = TargetBRadiusEntry;
684 }
685
686 if (!entry)
687 return 0.0f;
688
689 float radius = entry->RadiusMin;
690
691 // Random targets use random value between RadiusMin and RadiusMax
692 // For other cases, client uses RadiusMax if RadiusMin is 0
693 if (target.GetTarget() == TARGET_DEST_CASTER_RANDOM ||
696 radius += (entry->RadiusMax - radius) * rand_norm();
697 else if (radius == 0.0f)
698 radius = entry->RadiusMax;
699
700 if (caster)
701 {
702 if (Unit* casterUnit = caster->ToUnit())
703 radius += entry->RadiusPerLevel * casterUnit->GetLevel();
704
705 radius = std::min(radius, entry->RadiusMax);
706
707 if (Player* modOwner = caster->GetSpellModOwner())
708 modOwner->ApplySpellMod(_spellInfo, SpellModOp::Radius, radius, spell);
709 }
710
711 return radius;
712}
713
715{
717}
718
719uint32 SpellEffectInfo::GetMissingTargetMask(bool srcSet /*= false*/, bool dstSet /*= false*/, uint32 mask /*=0*/) const
720{
721 uint32 effImplicitTargetMask = GetTargetFlagMask(GetUsedTargetObjectType());
722 uint32 providedTargetMask = GetProvidedTargetMask() | mask;
723
724 // remove all flags covered by effect target mask
725 if (providedTargetMask & TARGET_FLAG_UNIT_MASK)
726 effImplicitTargetMask &= ~(TARGET_FLAG_UNIT_MASK);
727 if (providedTargetMask & TARGET_FLAG_CORPSE_MASK)
728 effImplicitTargetMask &= ~(TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK);
729 if (providedTargetMask & TARGET_FLAG_GAMEOBJECT_ITEM)
731 if (providedTargetMask & TARGET_FLAG_GAMEOBJECT)
732 effImplicitTargetMask &= ~(TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM);
733 if (providedTargetMask & TARGET_FLAG_ITEM)
734 effImplicitTargetMask &= ~(TARGET_FLAG_ITEM | TARGET_FLAG_GAMEOBJECT_ITEM);
735 if (dstSet || providedTargetMask & TARGET_FLAG_DEST_LOCATION)
736 effImplicitTargetMask &= ~(TARGET_FLAG_DEST_LOCATION);
737 if (srcSet || providedTargetMask & TARGET_FLAG_SOURCE_LOCATION)
738 effImplicitTargetMask &= ~(TARGET_FLAG_SOURCE_LOCATION);
739
740 return effImplicitTargetMask;
741}
742
744{
745 return _data[Effect].ImplicitTargetType;
746}
747
749{
750 return _data[Effect].UsedTargetObjectType;
751}
752
754{
755 switch (Effect)
756 {
768 if (MiscValue == POWER_MANA)
784 switch (ApplyAuraName)
785 {
829 if (MiscValue == POWER_MANA)
832 default:
833 break;
834 }
835 break;
836 default:
837 break;
838 }
839
841}
842
843std::array<SpellEffectInfo::StaticData, TOTAL_SPELL_EFFECTS> SpellEffectInfo::_data =
844{ {
845 // implicit target type used target object type
847 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 1 SPELL_EFFECT_INSTAKILL
848 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 2 SPELL_EFFECT_SCHOOL_DAMAGE
849 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 3 SPELL_EFFECT_DUMMY
850 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 4 SPELL_EFFECT_PORTAL_TELEPORT
852 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 6 SPELL_EFFECT_APPLY_AURA
853 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 7 SPELL_EFFECT_ENVIRONMENTAL_DAMAGE
854 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 8 SPELL_EFFECT_POWER_DRAIN
855 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 9 SPELL_EFFECT_HEALTH_LEECH
858 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 12 SPELL_EFFECT_PORTAL
859 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 13 SPELL_EFFECT_TELEPORT_TO_RETURN_POINT
860 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 14 SPELL_EFFECT_INCREASE_CURRENCY_CAP
861 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 15 SPELL_EFFECT_TELEPORT_WITH_SPELL_VISUAL_KIT_LOADING_SCREEN
862 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 16 SPELL_EFFECT_QUEST_COMPLETE
863 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 17 SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
865 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 19 SPELL_EFFECT_ADD_EXTRA_ATTACKS
866 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 20 SPELL_EFFECT_DODGE
867 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 21 SPELL_EFFECT_EVADE
868 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 22 SPELL_EFFECT_PARRY
869 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 23 SPELL_EFFECT_BLOCK
870 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 24 SPELL_EFFECT_CREATE_ITEM
871 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 25 SPELL_EFFECT_WEAPON
872 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 26 SPELL_EFFECT_DEFENSE
873 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 27 SPELL_EFFECT_PERSISTENT_AREA_AURA
874 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 28 SPELL_EFFECT_SUMMON
876 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 30 SPELL_EFFECT_ENERGIZE
877 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 31 SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
878 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 32 SPELL_EFFECT_TRIGGER_MISSILE
880 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 34 SPELL_EFFECT_SUMMON_CHANGE_ITEM
881 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 35 SPELL_EFFECT_APPLY_AREA_AURA_PARTY
882 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 36 SPELL_EFFECT_LEARN_SPELL
883 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 37 SPELL_EFFECT_SPELL_DEFENSE
884 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 38 SPELL_EFFECT_DISPEL
885 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 39 SPELL_EFFECT_LANGUAGE
886 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 40 SPELL_EFFECT_DUAL_WIELD
888 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 42 SPELL_EFFECT_JUMP_DEST
889 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 43 SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
890 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 44 SPELL_EFFECT_SKILL_STEP
891 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 45 SPELL_EFFECT_ADD_HONOR
892 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 46 SPELL_EFFECT_SPAWN
893 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 47 SPELL_EFFECT_TRADE_SKILL
894 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 48 SPELL_EFFECT_STEALTH
895 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 49 SPELL_EFFECT_DETECT
896 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 50 SPELL_EFFECT_TRANS_DOOR
897 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 51 SPELL_EFFECT_FORCE_CRITICAL_HIT
898 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 52 SPELL_EFFECT_SET_MAX_BATTLE_PET_COUNT
899 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 53 SPELL_EFFECT_ENCHANT_ITEM
900 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 54 SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
901 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 55 SPELL_EFFECT_TAMECREATURE
902 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 56 SPELL_EFFECT_SUMMON_PET
903 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 57 SPELL_EFFECT_LEARN_PET_SPELL
904 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 58 SPELL_EFFECT_WEAPON_DAMAGE
905 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 59 SPELL_EFFECT_CREATE_RANDOM_ITEM
906 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 60 SPELL_EFFECT_PROFICIENCY
907 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 61 SPELL_EFFECT_SEND_EVENT
908 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 62 SPELL_EFFECT_POWER_BURN
909 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 63 SPELL_EFFECT_THREAT
910 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 64 SPELL_EFFECT_TRIGGER_SPELL
911 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 65 SPELL_EFFECT_APPLY_AREA_AURA_RAID
912 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 66 SPELL_EFFECT_RECHARGE_ITEM
913 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 67 SPELL_EFFECT_HEAL_MAX_HEALTH
914 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 68 SPELL_EFFECT_INTERRUPT_CAST
916 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 70 SPELL_EFFECT_COMPLETE_AND_REWARD_WORLD_QUEST
917 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 71 SPELL_EFFECT_PICKPOCKET
918 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 72 SPELL_EFFECT_ADD_FARSIGHT
919 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 73 SPELL_EFFECT_UNTRAIN_TALENTS
920 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 74 SPELL_EFFECT_APPLY_GLYPH
921 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 75 SPELL_EFFECT_HEAL_MECHANICAL
922 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 76 SPELL_EFFECT_SUMMON_OBJECT_WILD
923 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 77 SPELL_EFFECT_SCRIPT_EFFECT
924 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 78 SPELL_EFFECT_ATTACK
925 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 79 SPELL_EFFECT_SANCTUARY
926 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 80 SPELL_EFFECT_MODIFY_FOLLOWER_ITEM_LEVEL
927 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 81 SPELL_EFFECT_PUSH_ABILITY_TO_ACTION_BAR
928 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 82 SPELL_EFFECT_BIND_SIGHT
930 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 84 SPELL_EFFECT_STUCK
931 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 85 SPELL_EFFECT_SUMMON_PLAYER
932 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 86 SPELL_EFFECT_ACTIVATE_OBJECT
933 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 87 SPELL_EFFECT_GAMEOBJECT_DAMAGE
934 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 88 SPELL_EFFECT_GAMEOBJECT_REPAIR
935 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 89 SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
936 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 90 SPELL_EFFECT_KILL_CREDIT
937 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 91 SPELL_EFFECT_THREAT_ALL
938 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM
939 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 93 SPELL_EFFECT_FORCE_DESELECT
940 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 94 SPELL_EFFECT_SELF_RESURRECT
941 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 95 SPELL_EFFECT_SKINNING
942 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 96 SPELL_EFFECT_CHARGE
943 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 97 SPELL_EFFECT_CAST_BUTTON
944 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 98 SPELL_EFFECT_KNOCK_BACK
945 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 99 SPELL_EFFECT_DISENCHANT
946 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 100 SPELL_EFFECT_INEBRIATE
947 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 101 SPELL_EFFECT_FEED_PET
948 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 102 SPELL_EFFECT_DISMISS_PET
949 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 103 SPELL_EFFECT_REPUTATION
950 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 104 SPELL_EFFECT_SUMMON_OBJECT_SLOT1
951 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 105 SPELL_EFFECT_SURVEY
952 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 106 SPELL_EFFECT_CHANGE_RAID_MARKER
953 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 107 SPELL_EFFECT_SHOW_CORPSE_LOOT
954 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 108 SPELL_EFFECT_DISPEL_MECHANIC
955 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 109 SPELL_EFFECT_RESURRECT_PET
956 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 110 SPELL_EFFECT_DESTROY_ALL_TOTEMS
957 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 111 SPELL_EFFECT_DURABILITY_DAMAGE
959 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 113 SPELL_EFFECT_CANCEL_CONVERSATION
960 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 114 SPELL_EFFECT_ATTACK_ME
961 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 115 SPELL_EFFECT_DURABILITY_DAMAGE_PCT
962 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_CORPSE_ENEMY}, // 116 SPELL_EFFECT_SKIN_PLAYER_CORPSE
963 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 117 SPELL_EFFECT_SPIRIT_HEAL
964 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 118 SPELL_EFFECT_SKILL
965 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 119 SPELL_EFFECT_APPLY_AREA_AURA_PET
966 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 120 SPELL_EFFECT_TELEPORT_GRAVEYARD
967 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 121 SPELL_EFFECT_NORMALIZED_WEAPON_DMG
968 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 122 SPELL_EFFECT_122
969 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 123 SPELL_EFFECT_SEND_TAXI
970 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 124 SPELL_EFFECT_PULL_TOWARDS
971 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 125 SPELL_EFFECT_MODIFY_THREAT_PERCENT
972 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 126 SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
973 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 127 SPELL_EFFECT_PROSPECTING
974 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 128 SPELL_EFFECT_APPLY_AREA_AURA_FRIEND
975 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
976 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 130 SPELL_EFFECT_REDIRECT_THREAT
977 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 131 SPELL_EFFECT_PLAY_SOUND
978 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 132 SPELL_EFFECT_PLAY_MUSIC
979 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 133 SPELL_EFFECT_UNLEARN_SPECIALIZATION
980 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 134 SPELL_EFFECT_KILL_CREDIT2
981 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 135 SPELL_EFFECT_CALL_PET
982 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 136 SPELL_EFFECT_HEAL_PCT
983 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 137 SPELL_EFFECT_ENERGIZE_PCT
984 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 138 SPELL_EFFECT_LEAP_BACK
985 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 139 SPELL_EFFECT_CLEAR_QUEST
986 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 140 SPELL_EFFECT_FORCE_CAST
987 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 141 SPELL_EFFECT_FORCE_CAST_WITH_VALUE
988 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
989 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER
990 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 144 SPELL_EFFECT_KNOCK_BACK_DEST
991 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 145 SPELL_EFFECT_PULL_TOWARDS_DEST
992 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 146 SPELL_EFFECT_RESTORE_GARRISON_TROOP_VITALITY
993 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 147 SPELL_EFFECT_QUEST_FAIL
994 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 148 SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
995 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 149 SPELL_EFFECT_CHARGE_DEST
996 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 150 SPELL_EFFECT_QUEST_START
997 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 151 SPELL_EFFECT_TRIGGER_SPELL_2
998 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 152 SPELL_EFFECT_SUMMON_RAF_FRIEND
999 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 153 SPELL_EFFECT_CREATE_TAMED_PET
1000 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 154 SPELL_EFFECT_DISCOVER_TAXI
1001 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 155 SPELL_EFFECT_TITAN_GRIP
1002 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 156 SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
1003 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 157 SPELL_EFFECT_CREATE_LOOT
1004 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 158 SPELL_EFFECT_MILLING
1005 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 159 SPELL_EFFECT_ALLOW_RENAME_PET
1006 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 160 SPELL_EFFECT_FORCE_CAST_2
1007 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 161 SPELL_EFFECT_TALENT_SPEC_COUNT
1008 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 162 SPELL_EFFECT_TALENT_SPEC_SELECT
1009 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 163 SPELL_EFFECT_OBLITERATE_ITEM
1010 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 164 SPELL_EFFECT_REMOVE_AURA
1011 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 165 SPELL_EFFECT_DAMAGE_FROM_MAX_HEALTH_PCT
1012 {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 166 SPELL_EFFECT_GIVE_CURRENCY
1013 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 167 SPELL_EFFECT_UPDATE_PLAYER_PHASE
1014 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 168 SPELL_EFFECT_ALLOW_CONTROL_PET
1015 {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 169 SPELL_EFFECT_DESTROY_ITEM
1016 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 170 SPELL_EFFECT_UPDATE_ZONE_AURAS_AND_PHASES
1017 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 171 SPELL_EFFECT_SUMMON_PERSONAL_GAMEOBJECT
1018 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_CORPSE_ALLY}, // 172 SPELL_EFFECT_RESURRECT_WITH_AURA
1019 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 173 SPELL_EFFECT_UNLOCK_GUILD_VAULT_TAB
1020 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 174 SPELL_EFFECT_APPLY_AURA_ON_PET
1021 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 175 SPELL_EFFECT_175
1022 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 176 SPELL_EFFECT_SANCTUARY_2
1023 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 177 SPELL_EFFECT_DESPAWN_PERSISTENT_AREA_AURA
1024 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 178 SPELL_EFFECT_178
1025 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 179 SPELL_EFFECT_CREATE_AREATRIGGER
1026 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 180 SPELL_EFFECT_UPDATE_AREATRIGGER
1027 {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 181 SPELL_EFFECT_REMOVE_TALENT
1028 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 182 SPELL_EFFECT_DESPAWN_AREATRIGGER
1029 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 183 SPELL_EFFECT_183
1030 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 184 SPELL_EFFECT_REPUTATION_2
1031 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 185 SPELL_EFFECT_185
1032 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 186 SPELL_EFFECT_186
1033 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 187 SPELL_EFFECT_RANDOMIZE_ARCHAEOLOGY_DIGSITES
1034 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 188 SPELL_EFFECT_SUMMON_STABLED_PET_AS_GUARDIAN
1035 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 189 SPELL_EFFECT_LOOT
1036 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 190 SPELL_EFFECT_CHANGE_PARTY_MEMBERS
1037 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 191 SPELL_EFFECT_TELEPORT_TO_DIGSITE
1038 {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 192 SPELL_EFFECT_UNCAGE_BATTLEPET
1039 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 193 SPELL_EFFECT_START_PET_BATTLE
1040 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 194 SPELL_EFFECT_194
1041 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 195 SPELL_EFFECT_PLAY_SCENE_SCRIPT_PACKAGE
1042 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 196 SPELL_EFFECT_CREATE_SCENE_OBJECT
1043 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 197 SPELL_EFFECT_CREATE_PERSONAL_SCENE_OBJECT
1044 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 198 SPELL_EFFECT_PLAY_SCENE
1045 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 199 SPELL_EFFECT_DESPAWN_SUMMON
1046 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 200 SPELL_EFFECT_HEAL_BATTLEPET_PCT
1047 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 201 SPELL_EFFECT_ENABLE_BATTLE_PETS
1048 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 202 SPELL_EFFECT_APPLY_AREA_AURA_SUMMONS
1049 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 203 SPELL_EFFECT_REMOVE_AURA_2
1050 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 204 SPELL_EFFECT_CHANGE_BATTLEPET_QUALITY
1051 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 205 SPELL_EFFECT_LAUNCH_QUEST_CHOICE
1052 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 206 SPELL_EFFECT_ALTER_IETM
1053 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 207 SPELL_EFFECT_LAUNCH_QUEST_TASK
1054 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 208 SPELL_EFFECT_SET_REPUTATION
1055 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 209 SPELL_EFFECT_209
1056 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 210 SPELL_EFFECT_LEARN_GARRISON_BUILDING
1057 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 211 SPELL_EFFECT_LEARN_GARRISON_SPECIALIZATION
1058 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 212 SPELL_EFFECT_REMOVE_AURA_BY_SPELL_LABEL
1059 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 213 SPELL_EFFECT_JUMP_DEST_2
1060 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 214 SPELL_EFFECT_CREATE_GARRISON
1061 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 215 SPELL_EFFECT_UPGRADE_CHARACTER_SPELLS
1062 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 216 SPELL_EFFECT_CREATE_SHIPMENT
1063 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 217 SPELL_EFFECT_UPGRADE_GARRISON
1064 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 218 SPELL_EFFECT_218
1065 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 219 SPELL_EFFECT_CREATE_CONVERSATION
1066 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 220 SPELL_EFFECT_ADD_GARRISON_FOLLOWER
1067 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 221 SPELL_EFFECT_ADD_GARRISON_MISSION
1068 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 222 SPELL_EFFECT_CREATE_HEIRLOOM_ITEM
1069 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 223 SPELL_EFFECT_CHANGE_ITEM_BONUSES
1070 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 224 SPELL_EFFECT_ACTIVATE_GARRISON_BUILDING
1071 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 225 SPELL_EFFECT_GRANT_BATTLEPET_LEVEL
1072 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 226 SPELL_EFFECT_TRIGGER_ACTION_SET
1073 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 227 SPELL_EFFECT_TELEPORT_TO_LFG_DUNGEON
1074 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 228 SPELL_EFFECT_228
1075 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 229 SPELL_EFFECT_SET_FOLLOWER_QUALITY
1077 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 231 SPELL_EFFECT_INCREASE_FOLLOWER_EXPERIENCE
1078 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 232 SPELL_EFFECT_REMOVE_PHASE
1079 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 233 SPELL_EFFECT_RANDOMIZE_FOLLOWER_ABILITIES
1080 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 234 SPELL_EFFECT_234
1081 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 235 SPELL_EFFECT_235
1082 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 236 SPELL_EFFECT_GIVE_EXPERIENCE
1083 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 237 SPELL_EFFECT_GIVE_RESTED_EXPERIENCE_BONUS
1084 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 238 SPELL_EFFECT_INCREASE_SKILL
1085 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 239 SPELL_EFFECT_END_GARRISON_BUILDING_CONSTRUCTION
1086 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 240 SPELL_EFFECT_GIVE_ARTIFACT_POWER
1087 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 241 SPELL_EFFECT_241
1088 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 242 SPELL_EFFECT_GIVE_ARTIFACT_POWER_NO_BONUS
1089 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 243 SPELL_EFFECT_APPLY_ENCHANT_ILLUSION
1090 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 244 SPELL_EFFECT_LEARN_FOLLOWER_ABILITY
1091 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 245 SPELL_EFFECT_UPGRADE_HEIRLOOM
1092 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 246 SPELL_EFFECT_FINISH_GARRISON_MISSION
1093 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 247 SPELL_EFFECT_ADD_GARRISON_MISSION_SET
1094 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 248 SPELL_EFFECT_FINISH_SHIPMENT
1095 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 249 SPELL_EFFECT_FORCE_EQUIP_ITEM
1096 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 250 SPELL_EFFECT_TAKE_SCREENSHOT
1097 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 251 SPELL_EFFECT_SET_GARRISON_CACHE_SIZE
1098 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 252 SPELL_EFFECT_TELEPORT_UNITS
1099 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 253 SPELL_EFFECT_GIVE_HONOR
1100 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 254 SPELL_EFFECT_JUMP_CHARGE
1101 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 255 SPELL_EFFECT_LEARN_TRANSMOG_SET
1102 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 256 SPELL_EFFECT_256
1103 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 257 SPELL_EFFECT_257
1104 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 258 SPELL_EFFECT_MODIFY_KEYSTONE
1105 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 259 SPELL_EFFECT_RESPEC_AZERITE_EMPOWERED_ITEM
1106 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 260 SPELL_EFFECT_SUMMON_STABLED_PET
1107 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 261 SPELL_EFFECT_SCRAP_ITEM
1108 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 262 SPELL_EFFECT_262
1109 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 263 SPELL_EFFECT_REPAIR_ITEM
1110 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 264 SPELL_EFFECT_REMOVE_GEM
1111 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 265 SPELL_EFFECT_LEARN_AZERITE_ESSENCE_POWER
1112 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 266 SPELL_EFFECT_SET_ITEM_BONUS_LIST_GROUP_ENTRY
1113 {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 267 SPELL_EFFECT_CREATE_PRIVATE_CONVERSATION
1114 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 268 SPELL_EFFECT_APPLY_MOUNT_EQUIPMENT
1115 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 269 SPELL_EFFECT_INCREASE_ITEM_BONUS_LIST_GROUP_STEP
1117 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 271 SPELL_EFFECT_APPLY_AREA_AURA_PARTY_NONRANDOM
1118 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 272 SPELL_EFFECT_SET_COVENANT
1119 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 273 SPELL_EFFECT_CRAFT_RUNEFORGE_LEGENDARY
1120 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 274 SPELL_EFFECT_274
1121 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 275 SPELL_EFFECT_275
1122 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 276 SPELL_EFFECT_LEARN_TRANSMOG_ILLUSION
1123 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 277 SPELL_EFFECT_SET_CHROMIE_TIME
1124 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 278 SPELL_EFFECT_278
1125 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 279 SPELL_EFFECT_LEARN_GARR_TALENT
1126 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 280 SPELL_EFFECT_280
1127 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 281 SPELL_EFFECT_LEARN_SOULBIND_CONDUIT
1128 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 282 SPELL_EFFECT_CONVERT_ITEMS_TO_CURRENCY
1129 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 283 SPELL_EFFECT_COMPLETE_CAMPAIGN
1130 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 284 SPELL_EFFECT_SEND_CHAT_MESSAGE
1131 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 285 SPELL_EFFECT_MODIFY_KEYSTONE_2
1132 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 286 SPELL_EFFECT_GRANT_BATTLEPET_EXPERIENCE
1133 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 287 SPELL_EFFECT_SET_GARRISON_FOLLOWER_LEVEL
1134 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 288 SPELL_EFFECT_CRAFT_ITEM
1135 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 289 SPELL_EFFECT_MODIFY_AURA_STACKS
1136 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 290 SPELL_EFFECT_MODIFY_COOLDOWN
1137 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 291 SPELL_EFFECT_MODIFY_COOLDOWNS
1138 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 292 SPELL_EFFECT_MODIFY_COOLDOWNS_BY_CATEGORY
1139 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 293 SPELL_EFFECT_MODIFY_CHARGES
1140 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 294 SPELL_EFFECT_CRAFT_LOOT
1141 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 295 SPELL_EFFECT_SALVAGE_ITEM
1142 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 296 SPELL_EFFECT_CRAFT_SALVAGE_ITEM
1143 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 297 SPELL_EFFECT_RECRAFT_ITEM
1144 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 298 SPELL_EFFECT_CANCEL_ALL_PRIVATE_CONVERSATIONS
1145 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 299 SPELL_EFFECT_299
1146 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 300 SPELL_EFFECT_300
1147 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 301 SPELL_EFFECT_CRAFT_ENCHANT
1148 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_NONE}, // 302 SPELL_EFFECT_GATHERING
1149 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 303 SPELL_EFFECT_CREATE_TRAIT_TREE_CONFIG
1150 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 304 SPELL_EFFECT_CHANGE_ACTIVE_COMBAT_TRAIT_CONFIG
1151 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 305 SPELL_EFFECT_305
1152 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 306 SPELL_EFFECT_UPDATE_INTERACTIONS
1153 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 307 SPELL_EFFECT_307
1154 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 308 SPELL_EFFECT_CANCEL_PRELOAD_WORLD
1155 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 309 SPELL_EFFECT_PRELOAD_WORLD
1156 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 310 SPELL_EFFECT_310
1157 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 311 SPELL_EFFECT_ENSURE_WORLD_LOADED
1158 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 312 SPELL_EFFECT_312
1159 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 313 SPELL_EFFECT_CHANGE_ITEM_BONUSES_2
1160 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 314 SPELL_EFFECT_ADD_SOCKET_BONUS
1161 {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 315 SPELL_EFFECT_LEARN_TRANSMOG_APPEARANCE_FROM_ITEM_MOD_APPEARANCE_GROUP
1162} };
1163
1165 : Id(spellName->ID), Difficulty(difficulty)
1166{
1167 _effects.reserve(32);
1168 for (SpellEffectEntry const* spellEffect : data.Effects)
1169 {
1170 if (!spellEffect)
1171 continue;
1172
1174 }
1175
1176 // Correct EffectIndex for blank effects
1177 for (size_t i = 0; i < _effects.size(); ++i)
1178 {
1179 _effects[i]._spellInfo = this;
1180 _effects[i].EffectIndex = SpellEffIndex(i);
1181 }
1182
1183 _effects.shrink_to_fit();
1184
1185 SpellName = &spellName->Name;
1186
1187 // SpellMiscEntry
1188 if (SpellMiscEntry const* _misc = data.Misc)
1189 {
1190 Attributes = _misc->Attributes[0];
1191 AttributesEx = _misc->Attributes[1];
1192 AttributesEx2 = _misc->Attributes[2];
1193 AttributesEx3 = _misc->Attributes[3];
1194 AttributesEx4 = _misc->Attributes[4];
1195 AttributesEx5 = _misc->Attributes[5];
1196 AttributesEx6 = _misc->Attributes[6];
1197 AttributesEx7 = _misc->Attributes[7];
1198 AttributesEx8 = _misc->Attributes[8];
1199 AttributesEx9 = _misc->Attributes[9];
1200 AttributesEx10 = _misc->Attributes[10];
1201 AttributesEx11 = _misc->Attributes[11];
1202 AttributesEx12 = _misc->Attributes[12];
1203 AttributesEx13 = _misc->Attributes[13];
1204 AttributesEx14 = _misc->Attributes[14];
1205 CastTimeEntry = sSpellCastTimesStore.LookupEntry(_misc->CastingTimeIndex);
1206 DurationEntry = sSpellDurationStore.LookupEntry(_misc->DurationIndex);
1207 RangeEntry = sSpellRangeStore.LookupEntry(_misc->RangeIndex);
1208 Speed = _misc->Speed;
1209 LaunchDelay = _misc->LaunchDelay;
1210 SchoolMask = _misc->SchoolMask;
1211 IconFileDataId = _misc->SpellIconFileDataID;
1212 ActiveIconFileDataId = _misc->ActiveIconFileDataID;
1213 ContentTuningId = _misc->ContentTuningID;
1214 ShowFutureSpellPlayerConditionID = _misc->ShowFutureSpellPlayerConditionID;
1215 }
1216
1217 // SpellScalingEntry
1218 if (SpellScalingEntry const* _scaling = data.Scaling)
1219 {
1220 Scaling.MinScalingLevel = _scaling->MinScalingLevel;
1221 Scaling.MaxScalingLevel = _scaling->MaxScalingLevel;
1222 Scaling.ScalesFromItemLevel = _scaling->ScalesFromItemLevel;
1223 }
1224
1225 // SpellAuraOptionsEntry
1226 if (SpellAuraOptionsEntry const* _options = data.AuraOptions)
1227 {
1228 ProcFlags = _options->ProcTypeMask;
1229 ProcChance = _options->ProcChance;
1230 ProcCharges = _options->ProcCharges;
1231 ProcCooldown = _options->ProcCategoryRecovery;
1232 StackAmount = _options->CumulativeAura;
1233 if (SpellProcsPerMinuteEntry const* _ppm = sSpellProcsPerMinuteStore.LookupEntry(_options->SpellProcsPerMinuteID))
1234 {
1235 ProcBasePPM = _ppm->BaseProcRate;
1236 ProcPPMMods = sDB2Manager.GetSpellProcsPerMinuteMods(_ppm->ID);
1237 }
1238 }
1239
1240 // SpellAuraRestrictionsEntry
1241 if (SpellAuraRestrictionsEntry const* _aura = data.AuraRestrictions)
1242 {
1243 CasterAuraState = _aura->CasterAuraState;
1244 TargetAuraState = _aura->TargetAuraState;
1245 ExcludeCasterAuraState = _aura->ExcludeCasterAuraState;
1246 ExcludeTargetAuraState = _aura->ExcludeTargetAuraState;
1247 CasterAuraSpell = _aura->CasterAuraSpell;
1248 TargetAuraSpell = _aura->TargetAuraSpell;
1249 ExcludeCasterAuraSpell = _aura->ExcludeCasterAuraSpell;
1250 ExcludeTargetAuraSpell = _aura->ExcludeTargetAuraSpell;
1251 CasterAuraType = AuraType(_aura->CasterAuraType);
1252 TargetAuraType = AuraType(_aura->TargetAuraType);
1253 ExcludeCasterAuraType = AuraType(_aura->ExcludeCasterAuraType);
1254 ExcludeTargetAuraType = AuraType(_aura->ExcludeTargetAuraType);
1255 }
1256
1257 // SpellCastingRequirementsEntry
1258 if (SpellCastingRequirementsEntry const* _castreq = data.CastingRequirements)
1259 {
1260 RequiresSpellFocus = _castreq->RequiresSpellFocus;
1261 FacingCasterFlags = _castreq->FacingCasterFlags;
1262 RequiredAreasID = _castreq->RequiredAreasID;
1263 }
1264
1265 // SpellCategoriesEntry
1266 if (SpellCategoriesEntry const* _categories = data.Categories)
1267 {
1268 CategoryId = _categories->Category;
1269 Dispel = _categories->DispelType;
1270 Mechanic = _categories->Mechanic;
1271 StartRecoveryCategory = _categories->StartRecoveryCategory;
1272 DmgClass = _categories->DefenseType;
1273 PreventionType = _categories->PreventionType;
1274 ChargeCategoryId = _categories->ChargeCategory;
1275 }
1276
1277 // SpellClassOptionsEntry
1278 if (SpellClassOptionsEntry const* _class = data.ClassOptions)
1279 {
1280 SpellFamilyName = _class->SpellClassSet;
1281 SpellFamilyFlags = _class->SpellClassMask;
1282 }
1283
1284 // SpellCooldownsEntry
1285 if (SpellCooldownsEntry const* _cooldowns = data.Cooldowns)
1286 {
1287 RecoveryTime = _cooldowns->RecoveryTime;
1288 CategoryRecoveryTime = _cooldowns->CategoryRecoveryTime;
1289 StartRecoveryTime = _cooldowns->StartRecoveryTime;
1290 CooldownAuraSpellId = _cooldowns->AuraSpellID;
1291 }
1292
1293 // SpellEquippedItemsEntry
1294 if (SpellEquippedItemsEntry const* _equipped = data.EquippedItems)
1295 {
1296 EquippedItemClass = _equipped->EquippedItemClass;
1297 EquippedItemSubClassMask = _equipped->EquippedItemSubclass;
1298 EquippedItemInventoryTypeMask = _equipped->EquippedItemInvTypes;
1299 }
1300
1301 // SpellInterruptsEntry
1302 if (SpellInterruptsEntry const* _interrupt = data.Interrupts)
1303 {
1304 InterruptFlags = SpellInterruptFlags(_interrupt->InterruptFlags);
1305 AuraInterruptFlags = SpellAuraInterruptFlags(_interrupt->AuraInterruptFlags[0]);
1306 AuraInterruptFlags2 = SpellAuraInterruptFlags2(_interrupt->AuraInterruptFlags[1]);
1307 ChannelInterruptFlags = SpellAuraInterruptFlags(_interrupt->ChannelInterruptFlags[0]);
1308 ChannelInterruptFlags2 = SpellAuraInterruptFlags2(_interrupt->ChannelInterruptFlags[1]);
1309 }
1310
1311 for (SpellLabelEntry const* label : data.Labels)
1312 Labels.insert(label->LabelID);
1313
1314 // SpellLevelsEntry
1315 if (SpellLevelsEntry const* _levels = data.Levels)
1316 {
1317 MaxLevel = _levels->MaxLevel;
1318 BaseLevel = _levels->BaseLevel;
1319 SpellLevel = _levels->SpellLevel;
1320 }
1321
1322 // SpellPowerEntry
1323 PowerCosts = data.Powers;
1324
1325 // SpellReagentsEntry
1326 if (SpellReagentsEntry const* _reagents = data.Reagents)
1327 {
1328 Reagent = _reagents->Reagent;
1329 ReagentCount = _reagents->ReagentCount;
1330 }
1331
1333
1334 // SpellShapeshiftEntry
1335 if (SpellShapeshiftEntry const* _shapeshift = data.Shapeshift)
1336 {
1337 Stances = MAKE_PAIR64(_shapeshift->ShapeshiftMask[0], _shapeshift->ShapeshiftMask[1]);
1338 StancesNot = MAKE_PAIR64(_shapeshift->ShapeshiftExclude[0], _shapeshift->ShapeshiftExclude[1]);
1339 }
1340
1341 // SpellTargetRestrictionsEntry
1342 if (SpellTargetRestrictionsEntry const* _target = data.TargetRestrictions)
1343 {
1344 ConeAngle = _target->ConeDegrees;
1345 Width = _target->Width;
1346 Targets = _target->Targets;
1347 TargetCreatureType = _target->TargetCreatureType;
1348 MaxAffectedTargets = _target->MaxTargets;
1349 MaxTargetLevel = _target->MaxTargetLevel;
1350 }
1351
1352 // SpellTotemsEntry
1353 if (SpellTotemsEntry const* _totem = data.Totems)
1354 {
1355 TotemCategory = _totem->RequiredTotemCategoryID;
1356 Totem = _totem->Totem;
1357 }
1358
1359 _visuals = data.Visuals;
1360}
1361
1362SpellInfo::SpellInfo(SpellNameEntry const* spellName, ::Difficulty difficulty, std::vector<SpellEffectEntry> const& effects)
1363 : Id(spellName->ID), Difficulty(difficulty)
1364{
1365 SpellName = &spellName->Name;
1366
1367 _effects.reserve(32);
1368 for (SpellEffectEntry const& spellEffect : effects)
1369 Trinity::Containers::EnsureWritableVectorIndex(_effects, spellEffect.EffectIndex) = SpellEffectInfo(this, spellEffect);
1370
1371 // Correct EffectIndex for blank effects
1372 for (size_t i = 0; i < _effects.size(); ++i)
1373 {
1374 _effects[i]._spellInfo = this;
1375 _effects[i].EffectIndex = SpellEffIndex(i);
1376 }
1377
1378 _effects.shrink_to_fit();
1379}
1380
1382{
1384}
1385
1387{
1388 return CategoryId;
1389}
1390
1392{
1393 for (SpellEffectInfo const& eff : GetEffects())
1394 if (eff.IsEffect(effect))
1395 return true;
1396
1397 return false;
1398}
1399
1401{
1402 for (SpellEffectInfo const& effect : GetEffects())
1403 if (effect.IsAura(aura))
1404 return true;
1405
1406 return false;
1407}
1408
1410{
1411 for (SpellEffectInfo const& effect : GetEffects())
1412 if (effect.IsAreaAuraEffect())
1413 return true;
1414
1415 return false;
1416}
1417
1419{
1420 for (SpellEffectInfo const& effect : GetEffects())
1421 {
1422 if (effect.IsEffect())
1423 {
1424 switch (effect.Effect)
1425 {
1434 continue;
1435 default:
1436 return false;
1437 }
1438 }
1439 }
1440
1441 return true;
1442}
1443
1445{
1446 for (SpellEffectInfo const& effect : GetEffects())
1447 if (effect.TargetA.GetTarget() == target || effect.TargetB.GetTarget() == target)
1448 return true;
1449
1450 return false;
1451}
1452
1453bool SpellInfo::CanBeInterrupted(WorldObject const* interruptCaster, Unit const* interruptTarget, bool ignoreImmunity /*= false*/) const
1454{
1459 || (interruptCaster && interruptCaster->IsUnit() && interruptCaster->ToUnit()->HasAuraTypeWithMiscvalue(SPELL_AURA_ALLOW_INTERRUPT_SPELL, Id))
1460 || ((!(interruptTarget->GetMechanicImmunityMask() & (1 << MECHANIC_INTERRUPT)) || ignoreImmunity)
1463}
1464
1466{
1468}
1469
1471{
1472 if (GetEffects().size() < 2)
1473 return false;
1474
1478 || Id == 64323;
1479}
1480
1482{
1484}
1485
1487{
1488 for (SpellEffectInfo const& effect : GetEffects())
1489 {
1490 if (effect.Effect == SPELL_EFFECT_SKILL)
1491 {
1492 uint32 skill = effect.MiscValue;
1493
1494 if (IsProfessionSkill(skill))
1495 return true;
1496 }
1497 }
1498 return false;
1499}
1500
1502{
1503 for (SpellEffectInfo const& effect : GetEffects())
1504 {
1505 if (effect.Effect == SPELL_EFFECT_SKILL)
1506 {
1507 uint32 skill = effect.MiscValue;
1508
1509 if (IsPrimaryProfessionSkill(skill))
1510 return true;
1511 }
1512 }
1513 return false;
1514}
1515
1517{
1518 return IsPrimaryProfession() && GetRank() == 1;
1519}
1520
1522{
1523 SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(Id);
1524
1525 for (SkillLineAbilityMap::const_iterator _spell_idx = bounds.first; _spell_idx != bounds.second; ++_spell_idx)
1526 if (_spell_idx->second->SkillLine == int32(skillType))
1527 return true;
1528
1529 return false;
1530}
1531
1533{
1534 for (SpellEffectInfo const& effect : GetEffects())
1535 if (effect.IsEffect() && (effect.IsTargetingArea() || effect.IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) || effect.IsAreaAuraEffect()))
1536 return true;
1537
1538 return false;
1539}
1540
1541// checks if spell targets are selected from area, doesn't include spell effects in check (like area wide auras for example)
1543{
1544 for (SpellEffectInfo const& effect : GetEffects())
1545 if (effect.IsEffect() && effect.IsTargetingArea())
1546 return true;
1547
1548 return false;
1549}
1550
1552{
1554}
1555
1556bool SpellInfo::NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell) const
1557{
1559 return true;
1560
1561 /*
1562 for (SpellEffectInfo const& effect : GetEffects())
1563 {
1564 if (effect.IsEffect())
1565 {
1566 if (effect.TargetA.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CHANNEL
1567 || effect.TargetB.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CHANNEL)
1568 return true;
1569 }
1570 }
1571 */
1572
1573 if (triggeringSpell->IsChanneled())
1574 {
1575 uint32 mask = 0;
1576 for (SpellEffectInfo const& effect : GetEffects())
1577 {
1578 if (effect.TargetA.GetTarget() != TARGET_UNIT_CASTER && effect.TargetA.GetTarget() != TARGET_DEST_CASTER
1579 && effect.TargetB.GetTarget() != TARGET_UNIT_CASTER && effect.TargetB.GetTarget() != TARGET_DEST_CASTER)
1580 {
1581 mask |= effect.GetProvidedTargetMask();
1582 }
1583 }
1584
1585 if (mask & TARGET_FLAG_UNIT_MASK)
1586 return true;
1587 }
1588
1589 return false;
1590}
1591
1593{
1595}
1596
1598{
1599 if (IsPassive())
1600 return false;
1602 return false;
1603 return true;
1604}
1605
1607{
1608 if (IsPassive())
1609 return false;
1610
1611 // All stance spells. if any better way, change it.
1612 for (SpellEffectInfo const& effect : GetEffects())
1613 {
1614 switch (SpellFamilyName)
1615 {
1617 // Paladin aura Spell
1618 if (effect.Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID)
1619 return false;
1620 break;
1621 case SPELLFAMILY_DRUID:
1622 // Druid form Spell
1623 if (effect.Effect == SPELL_EFFECT_APPLY_AURA &&
1624 effect.ApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT)
1625 return false;
1626 break;
1627 }
1628 }
1629
1630 return true;
1631}
1632
1634{
1636}
1637
1639{
1640 return IsPassive() || Id == 55849 || Id == 40075 || Id == 44413; // Power Spark, Fel Flak Fire, Incanter's Absorption
1641}
1642
1644{
1647}
1648
1650{
1652 return true;
1653
1654 SpellCategoryEntry const* category = sSpellCategoryStore.LookupEntry(CategoryId);
1655 return category && category->Flags & SPELL_CATEGORY_FLAG_COOLDOWN_STARTS_ON_EVENT;
1656}
1657
1659{
1661}
1662
1664{
1666}
1667
1669{
1671 return true;
1672
1673 for (SpellEffectInfo const& effect : GetEffects())
1674 {
1675 if (!effect.IsEffect())
1676 continue;
1677
1678 if (effect.TargetA.GetObjectType() == TARGET_OBJECT_TYPE_CORPSE || effect.TargetB.GetObjectType() == TARGET_OBJECT_TYPE_CORPSE)
1679 return true;
1680 }
1681
1682 return false;
1683}
1684
1686{
1687 for (SpellEffectInfo const& effect : GetEffects())
1688 {
1689 switch (effect.TargetA.GetCheckType())
1690 {
1691 case TARGET_CHECK_PARTY:
1692 case TARGET_CHECK_RAID:
1694 return true;
1695 default:
1696 break;
1697 }
1698 }
1699
1700 return false;
1701}
1702
1703bool SpellInfo::CanBeUsedInCombat(Unit const* caster) const
1704{
1707}
1708
1710{
1711 return NegativeEffects.none();
1712}
1713
1715{
1716 return !NegativeEffects.test(effIndex);
1717}
1718
1720{
1722}
1723
1725{
1727}
1728
1730{
1732}
1733
1735{
1736 return (SpellFamilyName == SPELLFAMILY_HUNTER && !(SpellFamilyFlags[1] & 0x10000000)) // for 53352, cannot find better way
1739}
1740
1742{
1744}
1745
1747{
1749}
1750
1752{
1753 return Speed > 0.0f || LaunchDelay > 0.0f;
1754}
1755
1757{
1758 WeaponAttackType result;
1759 switch (DmgClass)
1760 {
1763 result = OFF_ATTACK;
1764 else
1765 result = BASE_ATTACK;
1766 break;
1769 break;
1770 default:
1771 // Wands
1773 result = RANGED_ATTACK;
1774 else
1775 result = BASE_ATTACK;
1776 break;
1777 }
1778
1779 return result;
1780}
1781
1783{
1784 // item neutral spell
1785 if (EquippedItemClass == -1)
1786 return true;
1787
1788 // item dependent spell
1789 if (item && item->IsFitToSpellRequirements(this))
1790 return true;
1791
1792 return false;
1793}
1794
1795bool SpellInfo::IsAffected(uint32 familyName, flag128 const& familyFlags) const
1796{
1797 if (!familyName)
1798 return true;
1799
1800 if (familyName != SpellFamilyName)
1801 return false;
1802
1803 if (familyFlags && !(familyFlags & SpellFamilyFlags))
1804 return false;
1805
1806 return true;
1807}
1808
1810{
1812}
1813
1815{
1816 if (!IsAffectedBySpellMods())
1817 return false;
1818
1819 SpellInfo const* affectSpell = sSpellMgr->GetSpellInfo(mod->spellId, Difficulty);
1820 if (!affectSpell)
1821 return false;
1822
1823 switch (mod->type)
1824 {
1825 case SPELLMOD_FLAT:
1826 case SPELLMOD_PCT:
1827 // TEMP: dont use IsAffected - !familyName and !familyFlags are not valid options for spell mods
1828 // TODO: investigate if the !familyName and !familyFlags conditions are even valid for all other (nonmod) uses of SpellInfo::IsAffected
1829 return affectSpell->SpellFamilyName == SpellFamilyName && static_cast<SpellModifierByClassMask const*>(mod)->mask & SpellFamilyFlags;
1831 return HasLabel(static_cast<SpellFlatModifierByLabel const*>(mod)->value.LabelID);
1832 case SPELLMOD_LABEL_PCT:
1833 return HasLabel(static_cast<SpellPctModifierByLabel const*>(mod)->value.LabelID);
1834 default:
1835 break;
1836 }
1837
1838 return false;
1839}
1840
1841bool SpellInfo::CanPierceImmuneAura(SpellInfo const* auraSpellInfo) const
1842{
1843 // aura can't be pierced
1844 if (!auraSpellInfo || auraSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES))
1845 return false;
1846
1847 // these spells pierce all available spells (Resurrection Sickness for example)
1849 return true;
1850
1851 // these spells (Cyclone for example) can pierce all...
1853 {
1854 // ...but not these (Divine shield, Ice block, Cyclone and Banish for example)
1855 if (auraSpellInfo->Mechanic != MECHANIC_IMMUNE_SHIELD &&
1856 auraSpellInfo->Mechanic != MECHANIC_INVULNERABILITY &&
1857 (auraSpellInfo->Mechanic != MECHANIC_BANISH || (IsRankOf(auraSpellInfo) && auraSpellInfo->Dispel != DISPEL_NONE))) // Banish shouldn't be immune to itself, but Cyclone should
1858 return true;
1859 }
1860
1861 // Dispels other auras on immunity, check if this spell makes the unit immune to aura
1863 return true;
1864
1865 return false;
1866}
1867
1868bool SpellInfo::CanDispelAura(SpellInfo const* auraSpellInfo) const
1869{
1870 // These auras (like Divine Shield) can't be dispelled
1871 if (auraSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES))
1872 return false;
1873
1874 // These spells (like Mass Dispel) can dispel all auras
1876 return true;
1877
1878 // These auras (Cyclone for example) are not dispelable
1881 return false;
1882
1883 return true;
1884}
1885
1887{
1888 // all other single target spells have if it has AttributesEx5
1890 return true;
1891
1892 return false;
1893}
1894
1896{
1897 SpellSpecificType spellSpec1 = GetSpellSpecific();
1898 SpellSpecificType spellSpec2 = spellInfo->GetSpellSpecific();
1899 switch (spellSpec1)
1900 {
1911 return spellSpec1 == spellSpec2;
1913 return spellSpec2 == SPELL_SPECIFIC_FOOD
1914 || spellSpec2 == SPELL_SPECIFIC_FOOD_AND_DRINK;
1916 return spellSpec2 == SPELL_SPECIFIC_DRINK
1917 || spellSpec2 == SPELL_SPECIFIC_FOOD_AND_DRINK;
1919 return spellSpec2 == SPELL_SPECIFIC_FOOD
1920 || spellSpec2 == SPELL_SPECIFIC_DRINK
1921 || spellSpec2 == SPELL_SPECIFIC_FOOD_AND_DRINK;
1922 default:
1923 return false;
1924 }
1925}
1926
1928{
1929 SpellSpecificType spellSpec = GetSpellSpecific();
1930 switch (spellSpec)
1931 {
1940 return spellSpec == spellInfo->GetSpellSpecific();
1941 default:
1942 return false;
1943 }
1944}
1945
1947{
1948 // talents that learn spells can have stance requirements that need ignore
1949 // (this requirement only for client-side stance show in talent description)
1950 /* TODO: 6.x fix this in proper way (probably spell flags/attributes?)
1951 if (GetTalentSpellCost(Id) > 0 && HasEffect(SPELL_EFFECT_LEARN_SPELL))
1952 return SPELL_CAST_OK;*/
1953
1954 //if (HasAttribute(SPELL_ATTR13_ACTIVATES_REQUIRED_SHAPESHIFT))
1955 // return SPELL_CAST_OK;
1956
1957 uint64 stanceMask = (form ? UI64LIT(1) << (form - 1) : 0);
1958
1959 if (stanceMask & StancesNot) // can explicitly not be cast in this stance
1961
1962 if (stanceMask & Stances) // can explicitly be cast in this stance
1963 return SPELL_CAST_OK;
1964
1965 bool actAsShifted = false;
1966 SpellShapeshiftFormEntry const* shapeInfo = nullptr;
1967 if (form > 0)
1968 {
1969 shapeInfo = sSpellShapeshiftFormStore.LookupEntry(form);
1970 if (!shapeInfo)
1971 {
1972 TC_LOG_ERROR("spells", "GetErrorAtShapeshiftedCast: unknown shapeshift {}", form);
1973 return SPELL_CAST_OK;
1974 }
1975 actAsShifted = !shapeInfo->GetFlags().HasFlag(SpellShapeshiftFormFlags::Stance);
1976 }
1977
1978 if (actAsShifted)
1979 {
1980 if (HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFTED) || (shapeInfo && shapeInfo->GetFlags().HasFlag(SpellShapeshiftFormFlags::CanOnlyCastShapeshiftSpells))) // not while shapeshifted
1982 else if (Stances != 0) // needs other shapeshift
1984 }
1985 else
1986 {
1987 // needs shapeshift
1990 }
1991
1992 return SPELL_CAST_OK;
1993}
1994
1995SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player) const
1996{
1997 // normal case
1998 if (RequiredAreasID > 0)
1999 {
2000 bool found = false;
2001 std::vector<uint32> areaGroupMembers = sDB2Manager.GetAreasForGroup(RequiredAreasID);
2002 for (uint32 areaId : areaGroupMembers)
2003 {
2004 if (DB2Manager::IsInArea(area_id, areaId))
2005 {
2006 found = true;
2007 break;
2008 }
2009 }
2010
2011 if (!found)
2013 }
2014
2015 // continent limitation (virtual continent)
2017 {
2019 if (player && player->HasAuraType(SPELL_AURA_MOUNT_RESTRICTIONS))
2020 {
2021 for (AuraEffect const* auraEffect : player->GetAuraEffectsByType(SPELL_AURA_MOUNT_RESTRICTIONS))
2022 mountFlags |= AreaMountFlags(auraEffect->GetMiscValue());
2023 }
2024 else if (AreaTableEntry const* areaTable = sAreaTableStore.LookupEntry(area_id))
2025 mountFlags = areaTable->GetMountFlags();
2026
2027 if (!(mountFlags.HasFlag(AreaMountFlags::AllowFlyingMounts)))
2029
2030 if (player)
2031 {
2032 uint32 mapToCheck = map_id;
2033 if (MapEntry const* mapEntry = sMapStore.LookupEntry(map_id))
2034 mapToCheck = mapEntry->CosmeticParentMapID;
2035
2036 if ((mapToCheck == 1116 || mapToCheck == 1464) && !player->HasSpell(191645)) // Draenor Pathfinder
2038 else if (mapToCheck == 1220 && !player->HasSpell(233368)) // Broken Isles Pathfinder
2040 else if ((mapToCheck == 1642 || mapToCheck == 1643) && !player->HasSpell(278833)) // Battle for Azeroth Pathfinder
2042 }
2043 }
2044
2045 // raid instance limitation
2047 {
2048 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2049 if (!mapEntry || mapEntry->IsRaid())
2051 }
2052
2054 {
2055 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2056 if (!mapEntry || !mapEntry->IsDungeon())
2058 }
2059
2061 {
2062 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2063 if (!mapEntry || mapEntry->IsBattleground())
2065 }
2066
2067 // DB base check (if non empty then must fit at least single for allow)
2068 SpellAreaMapBounds saBounds = sSpellMgr->GetSpellAreaMapBounds(Id);
2069 if (saBounds.first != saBounds.second)
2070 {
2071 for (SpellAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
2072 {
2073 if (itr->second.IsFitToRequirements(player, zone_id, area_id))
2074 return SPELL_CAST_OK;
2075 }
2077 }
2078
2079 // bg spell checks
2080 switch (Id)
2081 {
2082 case 23333: // Warsong Flag
2083 case 23335: // Silverwing Flag
2084 return map_id == 489 && player && player->InBattleground() ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
2085 case 2584: // Waiting to Resurrect
2086 case 42792: // Recently Dropped Flag
2087 case 43681: // Inactive
2088 case 44535: // Spirit Heal (mana)
2089 {
2090 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2091 if (!mapEntry)
2093
2094 return zone_id == AREA_WINTERGRASP || (mapEntry->IsBattleground() && player && player->InBattleground()) ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
2095 }
2096 case 44521: // Preparation
2097 {
2098 if (!player)
2100
2101 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2102 if (!mapEntry)
2104
2105 if (!mapEntry->IsBattleground())
2107
2108 Battleground* bg = player->GetBattleground();
2110 }
2111 case 32724: // Gold Team (Alliance)
2112 case 32725: // Green Team (Alliance)
2113 case 35774: // Gold Team (Horde)
2114 case 35775: // Green Team (Horde)
2115 {
2116 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2117 if (!mapEntry)
2119
2120 return mapEntry->IsBattleArena() && player && player->InBattleground() ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
2121 }
2122 case 32727: // Arena Preparation
2123 {
2124 if (!player)
2126
2127 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2128 if (!mapEntry)
2130
2131 if (!mapEntry->IsBattleArena())
2133
2134 Battleground* bg = player->GetBattleground();
2136 }
2137 }
2138
2139 // aura limitations
2140 if (player)
2141 {
2142 for (SpellEffectInfo const& effect : GetEffects())
2143 {
2144 if (!effect.IsAura())
2145 continue;
2146
2147 switch (effect.ApplyAuraName)
2148 {
2150 {
2151 if (SpellShapeshiftFormEntry const* spellShapeshiftForm = sSpellShapeshiftFormStore.LookupEntry(effect.MiscValue))
2152 if (uint32 mountType = spellShapeshiftForm->MountTypeID)
2153 if (!player->GetMountCapability(mountType))
2154 return SPELL_FAILED_NOT_HERE;
2155 break;
2156 }
2157 case SPELL_AURA_MOUNTED:
2158 {
2159 uint32 mountType = effect.MiscValueB;
2160 if (MountEntry const* mountEntry = sDB2Manager.GetMount(Id))
2161 mountType = mountEntry->MountTypeID;
2162 if (mountType && !player->GetMountCapability(mountType))
2163 return SPELL_FAILED_NOT_HERE;
2164 break;
2165 }
2166 default:
2167 break;
2168 }
2169 }
2170 }
2171
2172 return SPELL_CAST_OK;
2173}
2174
2175SpellCastResult SpellInfo::CheckTarget(WorldObject const* caster, WorldObject const* target, bool implicit /*= true*/) const
2176{
2177 if (HasAttribute(SPELL_ATTR1_EXCLUDE_CASTER) && caster == target)
2179
2180 // check visibility - ignore invisibility/stealth for implicit (area) targets
2181 if (!HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && !caster->CanSeeOrDetect(target, implicit))
2183
2184 Unit const* unitTarget = target->ToUnit();
2185
2187 {
2188 auto getCreatorOrSelf = [](WorldObject const* obj)
2189 {
2190 ObjectGuid creator = obj->GetCreatorGUID();
2191 if (creator.IsEmpty())
2192 creator = obj->GetGUID();
2193
2194 return creator;
2195 };
2196 if (getCreatorOrSelf(caster) != getCreatorOrSelf(target))
2198 }
2199
2200 // creature/player specific target checks
2201 if (unitTarget)
2202 {
2203 // spells cannot be cast if target has a pet in combat either
2206
2207 // only spells with SPELL_ATTR3_ONLY_TARGET_GHOSTS can target ghosts
2209 {
2212 else
2214 }
2215
2216 if (caster != unitTarget)
2217 {
2218 if (caster->GetTypeId() == TYPEID_PLAYER)
2219 {
2220 // Do not allow these spells to target creatures not tapped by us (Banish, Polymorph, many quest spells)
2222 if (Creature const* targetCreature = unitTarget->ToCreature())
2223 if (targetCreature->hasLootRecipient() && !targetCreature->isTappedBy(caster->ToPlayer()))
2225
2227 {
2228 Creature const* targetCreature = unitTarget->ToCreature();
2229 if (!targetCreature)
2231
2232 if (!targetCreature->CanHaveLoot() || !LootTemplates_Pickpocketing.HaveLootFor(targetCreature->GetCreatureDifficulty()->PickPocketLootID))
2234 }
2235
2236 // Not allow disarm unarmed player
2238 {
2239 if (unitTarget->GetTypeId() == TYPEID_PLAYER)
2240 {
2241 Player const* player = unitTarget->ToPlayer();
2242 if (!player->GetWeaponForAttack(BASE_ATTACK) || !player->IsUseEquipedWeapon(true))
2244 }
2245 else if (!unitTarget->GetVirtualItemId(0))
2247 }
2248 }
2249 }
2250
2252 if (!unitTarget->IsSummon() || unitTarget->ToTempSummon()->GetSummonerGUID() != caster->GetGUID())
2254
2258 }
2259 // corpse specific target checks
2260 else if (Corpse const* corpseTarget = target->ToCorpse())
2261 {
2262 // cannot target bare bones
2263 if (corpseTarget->GetType() == CORPSE_BONES)
2265 // we have to use owner for some checks (aura preventing resurrection for example)
2266 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2267 unitTarget = owner;
2268 // we're not interested in corpses without owner
2269 else
2271 }
2272 // other types of objects - always valid
2273 else return SPELL_CAST_OK;
2274
2275 // corpseOwner and unit specific target checks
2276 if (!unitTarget->IsPlayer())
2277 {
2280
2283 }
2286
2287 if (!IsAllowingDeadTarget() && !unitTarget->IsAlive())
2289
2290 // check this flag only for implicit targets (chain and area), allow to explicitly target units for spells like Shield of Righteousness
2293
2294 // checked in Unit::IsValidAttack/AssistTarget, shouldn't be checked for ENTRY targets
2295 //if (!HasAttribute(SPELL_ATTR6_CAN_TARGET_UNTARGETABLE) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE))
2296 // return SPELL_FAILED_BAD_TARGETS;
2297
2298 if (!CheckTargetCreatureType(unitTarget))
2299 {
2300 if (target->GetTypeId() == TYPEID_PLAYER)
2302 else
2304 }
2305
2306 // check GM mode and GM invisibility - only for player casts (npc casts are controlled by AI) and negative spells
2307 if (unitTarget != caster && (caster->GetAffectingPlayer() || !IsPositive()) && unitTarget->GetTypeId() == TYPEID_PLAYER)
2308 {
2309 if (!unitTarget->ToPlayer()->IsVisible())
2311
2312 if (unitTarget->ToPlayer()->IsGameMaster())
2314 }
2315
2316 // not allow casting on flying player
2319
2320 /* TARGET_UNIT_MASTER gets blocked here for passengers, because the whole idea of this check is to
2321 not allow passengers to be implicitly hit by spells, however this target type should be an exception,
2322 if this is left it kills spells that award kill credit from vehicle to master (few spells),
2323 the use of these 2 covers passenger target check, logically, if vehicle cast this to master it should always hit
2324 him, because it would be it's passenger, there's no such case where this gets to fail legitimacy, this problem
2325 cannot be solved from within the check in other way since target type cannot be called for the spell currently
2326 Spell examples: [ID - 52864 Devour Water, ID - 52862 Devour Wind, ID - 49370 Wyrmrest Defender: Destabilize Azure Dragonshrine Effect] */
2327 if (Unit const* unitCaster = caster->ToUnit())
2328 {
2329 if (!unitCaster->IsVehicle() && !(unitCaster->GetCharmerOrOwner() == target))
2330 {
2331 if (TargetAuraState && !unitTarget->HasAuraState(AuraStateType(TargetAuraState), this, unitCaster))
2333
2334 if (ExcludeTargetAuraState && unitTarget->HasAuraState(AuraStateType(ExcludeTargetAuraState), this, unitCaster))
2336 }
2337 }
2338
2339 if (TargetAuraSpell && !unitTarget->HasAura(TargetAuraSpell))
2341
2344
2348
2350 if (Map* map = caster->GetMap())
2351 if (InstanceMap* iMap = map->ToInstanceMap())
2352 if (InstanceScript* instance = iMap->GetInstanceScript())
2353 if (instance->GetCombatResurrectionCharges() == 0 && instance->IsEncounterInProgress())
2355
2356 return SPELL_CAST_OK;
2357}
2358
2359SpellCastResult SpellInfo::CheckExplicitTarget(WorldObject const* caster, WorldObject const* target, Item const* itemTarget /*= nullptr*/) const
2360{
2361 uint32 neededTargets = GetExplicitTargetMask();
2362 if (!target)
2363 {
2365 if (!(neededTargets & TARGET_FLAG_GAMEOBJECT_ITEM) || !itemTarget)
2367 return SPELL_CAST_OK;
2368 }
2369
2370 if (Unit const* unitTarget = target->ToUnit())
2371 {
2373 {
2374 Unit const* unitCaster = caster->ToUnit();
2375 if (neededTargets & TARGET_FLAG_UNIT_ENEMY)
2376 if (caster->IsValidAttackTarget(unitTarget, this))
2377 return SPELL_CAST_OK;
2378 if ((neededTargets & TARGET_FLAG_UNIT_ALLY)
2379 || ((neededTargets & TARGET_FLAG_UNIT_PARTY) && unitCaster && unitCaster->IsInPartyWith(unitTarget))
2380 || ((neededTargets & TARGET_FLAG_UNIT_RAID) && unitCaster && unitCaster->IsInRaidWith(unitTarget)))
2381 if (caster->IsValidAssistTarget(unitTarget, this))
2382 return SPELL_CAST_OK;
2383 if ((neededTargets & TARGET_FLAG_UNIT_MINIPET) && unitCaster)
2384 if (unitTarget->GetGUID() == unitCaster->GetCritterGUID())
2385 return SPELL_CAST_OK;
2386 if ((neededTargets & TARGET_FLAG_UNIT_PASSENGER) && unitCaster)
2387 if (unitTarget->IsOnVehicle(unitCaster))
2388 return SPELL_CAST_OK;
2390 }
2391 }
2392 return SPELL_CAST_OK;
2393}
2394
2396{
2397 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
2398 if (caster->GetTypeId() != TYPEID_PLAYER)
2399 return SPELL_CAST_OK;
2400
2401 Vehicle* vehicle = caster->GetVehicle();
2402 if (vehicle)
2403 {
2404 uint16 checkMask = 0;
2405 for (SpellEffectInfo const& effect : GetEffects())
2406 {
2407 if (effect.IsAura(SPELL_AURA_MOD_SHAPESHIFT))
2408 {
2409 SpellShapeshiftFormEntry const* shapeShiftFromEntry = sSpellShapeshiftFormStore.LookupEntry(effect.MiscValue);
2410 if (shapeShiftFromEntry && (shapeShiftFromEntry->Flags & 1) == 0) // unk flag
2411 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
2412 break;
2413 }
2414 }
2415
2418
2419 if (!checkMask)
2420 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
2421
2422 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(caster);
2424 && (vehicleSeat->Flags & checkMask) != checkMask)
2426
2427 // Can only summon uncontrolled minions/guardians when on controlled vehicle
2429 {
2430 for (SpellEffectInfo const& effect : GetEffects())
2431 {
2432 if (!effect.IsEffect(SPELL_EFFECT_SUMMON))
2433 continue;
2434
2435 SummonPropertiesEntry const* props = sSummonPropertiesStore.LookupEntry(effect.MiscValueB);
2436 if (props && props->Control != SUMMON_CATEGORY_WILD)
2438 }
2439 }
2440 }
2441
2442 return SPELL_CAST_OK;
2443}
2444
2446{
2447 // Curse of Doom & Exorcism: not find another way to fix spell target check :/
2449 {
2450 // not allow cast at player
2451 if (target->GetTypeId() == TYPEID_PLAYER)
2452 return false;
2453 else
2454 return true;
2455 }
2456
2457 // if target is magnet (i.e Grounding Totem) the check is skipped
2458 if (target->IsMagnet())
2459 return true;
2460
2461 uint32 creatureType = target->GetCreatureTypeMask();
2462 return !TargetCreatureType || !creatureType || (creatureType & TargetCreatureType) || target->HasAuraType(SPELL_AURA_IGNORE_SPELL_CREATURE_TYPE_REQUIREMENTS);
2463}
2464
2466{
2468}
2469
2471{
2472 uint64 mask = 0;
2473 if (Mechanic)
2474 mask |= UI64LIT(1) << Mechanic;
2475
2476 for (SpellEffectInfo const& effect : GetEffects())
2477 if (effect.IsEffect() && effect.Mechanic)
2478 mask |= UI64LIT(1) << effect.Mechanic;
2479
2480 return mask;
2481}
2482
2484{
2485 uint64 mask = 0;
2486 if (Mechanic)
2487 mask |= UI64LIT(1) << Mechanic;
2488
2489 if (GetEffect(effIndex).IsEffect() && GetEffect(effIndex).Mechanic)
2490 mask |= UI64LIT(1) << GetEffect(effIndex).Mechanic;
2491
2492 return mask;
2493}
2494
2496{
2497 uint64 mask = 0;
2498 if (Mechanic)
2499 mask |= UI64LIT(1) << Mechanic;
2500
2501 for (SpellEffectInfo const& effect : GetEffects())
2502 if ((effectMask & (1 << effect.EffectIndex)) && effect.Mechanic)
2503 mask |= UI64LIT(1) << effect.Mechanic;
2504
2505 return mask;
2506}
2507
2509{
2510 if (GetEffect(effIndex).IsEffect() && GetEffect(effIndex).Mechanic)
2511 return GetEffect(effIndex).Mechanic;
2512
2513 if (Mechanic)
2514 return Mechanics(Mechanic);
2515
2516 return MECHANIC_NONE;
2517}
2518
2520{
2522}
2523
2525{
2526 // If dispel all
2527 if (type == DISPEL_ALL)
2528 return DISPEL_ALL_MASK;
2529 else
2530 return uint32(1 << type);
2531}
2532
2534{
2535 return ExplicitTargetMask;
2536}
2537
2539{
2540 return _auraState;
2541}
2542
2544{
2545 _auraState = [this]()->AuraStateType
2546 {
2547 // Faerie Fire (Feral)
2548 if (GetCategory() == 1133)
2550
2551 // Swiftmend state on Regrowth, Rejuvenation, Wild Growth
2552 if (SpellFamilyName == SPELLFAMILY_DRUID && (SpellFamilyFlags[0] & 0x50 || SpellFamilyFlags[1] & 0x4000000))
2554
2555 // Deadly poison aura state
2556 if (SpellFamilyName == SPELLFAMILY_ROGUE && SpellFamilyFlags[0] & 0x10000)
2558
2559 // Enrage aura state
2560 if (Dispel == DISPEL_ENRAGE)
2561 return AURA_STATE_ENRAGED;
2562
2563 // Bleeding aura state
2565 return AURA_STATE_BLEED;
2566
2568 for (SpellEffectInfo const& effect : GetEffects())
2569 if (effect.IsAura(SPELL_AURA_MOD_STUN) || effect.IsAura(SPELL_AURA_MOD_ROOT) || effect.IsAura(SPELL_AURA_MOD_ROOT_2))
2570 return AURA_STATE_FROZEN;
2571
2572 switch (Id)
2573 {
2574 case 1064: // Dazed
2575 return AURA_STATE_DAZED;
2576 case 32216: // Victorious
2577 return AURA_STATE_VICTORIOUS;
2578 case 71465: // Divine Surge
2579 case 50241: // Evasive Charges
2580 case 81262: // Efflorescence
2582 case 6950: // Faerie Fire
2583 case 9806: // Phantom Strike
2584 case 9991: // Touch of Zanzil
2585 case 13424: // Faerie Fire
2586 case 13752: // Faerie Fire
2587 case 16432: // Plague Mist
2588 case 20656: // Faerie Fire
2589 case 25602: // Faerie Fire
2590 case 32129: // Faerie Fire
2591 case 35325: // Glowing Blood
2592 case 35328: // Lambent Blood
2593 case 35329: // Vibrant Blood
2594 case 35331: // Black Blood
2595 case 49163: // Perpetual Instability
2596 case 65863: // Faerie Fire
2597 case 79559: // Luxscale Light
2598 case 82855: // Dazzling
2599 case 102953: // In the Rumpus
2600 case 127907: // Phosphorescence
2601 case 127913: // Phosphorescence
2602 case 129007: // Zijin Sting
2603 case 130159: // Fae Touch
2604 case 142537: // Spotter Smoke
2605 case 168455: // Spotted!
2606 case 176905: // Super Sticky Glitter Bomb
2607 case 189502: // Marked
2608 case 201785: // Intruder Alert!
2609 case 201786: // Intruder Alert!
2610 case 201935: // Spotted!
2611 case 239233: // Smoke Bomb
2612 case 319400: // Glitter Burst
2613 case 321470: // Dimensional Shifter Mishap
2614 case 331134: // Spotted
2616 default:
2617 break;
2618 }
2619
2620 return AURA_STATE_NONE;
2621 }();
2622}
2623
2625{
2626 return _spellSpecific;
2627};
2628
2630{
2632 {
2633 switch (SpellFamilyName)
2634 {
2636 {
2637 // Food / Drinks (mostly)
2639 {
2640 bool food = false;
2641 bool drink = false;
2642 for (SpellEffectInfo const& effect : GetEffects())
2643 {
2644 if (!effect.IsAura())
2645 continue;
2646 switch (effect.ApplyAuraName)
2647 {
2648 // Food
2651 food = true;
2652 break;
2653 // Drink
2656 drink = true;
2657 break;
2658 default:
2659 break;
2660 }
2661 }
2662
2663 if (food && drink)
2665 else if (food)
2666 return SPELL_SPECIFIC_FOOD;
2667 else if (drink)
2668 return SPELL_SPECIFIC_DRINK;
2669 }
2670 // scrolls effects
2671 else
2672 {
2673 SpellInfo const* firstRankSpellInfo = GetFirstRankSpell();
2674 switch (firstRankSpellInfo->Id)
2675 {
2676 case 8118: // Strength
2677 case 8099: // Stamina
2678 case 8112: // Spirit
2679 case 8096: // Intellect
2680 case 8115: // Agility
2681 case 8091: // Armor
2682 return SPELL_SPECIFIC_SCROLL;
2683 default:
2684 break;
2685 }
2686 }
2687 break;
2688 }
2689 case SPELLFAMILY_MAGE:
2690 {
2691 // family flags 18(Molten), 25(Frost/Ice), 28(Mage)
2692 if (SpellFamilyFlags[0] & 0x12040000)
2694
2695 // Arcane brillance and Arcane intelect (normal check fails because of flags difference)
2696 if (SpellFamilyFlags[0] & 0x400)
2698
2699 if ((SpellFamilyFlags[0] & 0x1000000) && GetEffect(EFFECT_0).IsAura(SPELL_AURA_MOD_CONFUSE))
2701
2702 break;
2703 }
2705 {
2706 if (Id == 12292) // Death Wish
2708
2709 break;
2710 }
2712 {
2713 // Warlock (Bane of Doom | Bane of Agony | Bane of Havoc)
2714 if (Id == 603 || Id == 980 || Id == 80240)
2715 return SPELL_SPECIFIC_BANE;
2716
2717 // only warlock curses have this
2718 if (Dispel == DISPEL_CURSE)
2719 return SPELL_SPECIFIC_CURSE;
2720
2721 // Warlock (Demon Armor | Demon Skin | Fel Armor)
2722 if (SpellFamilyFlags[1] & 0x20000020 || SpellFamilyFlags[2] & 0x00000010)
2724
2725 //seed of corruption and corruption
2726 if (SpellFamilyFlags[1] & 0x10 || SpellFamilyFlags[0] & 0x2)
2728 break;
2729 }
2730 case SPELLFAMILY_PRIEST:
2731 {
2732 // Divine Spirit and Prayer of Spirit
2733 if (SpellFamilyFlags[0] & 0x20)
2735
2736 break;
2737 }
2738 case SPELLFAMILY_HUNTER:
2739 {
2740 // only hunter stings have this
2741 if (Dispel == DISPEL_POISON)
2742 return SPELL_SPECIFIC_STING;
2743
2744 // only hunter aspects have this (but not all aspects in hunter family)
2745 if (SpellFamilyFlags & flag128(0x00200000, 0x00000000, 0x00001010, 0x00000000))
2746 return SPELL_SPECIFIC_ASPECT;
2747
2748 break;
2749 }
2751 {
2752 // Collection of all the seal family flags. No other paladin spell has any of those.
2753 if (SpellFamilyFlags[1] & 0xA2000800)
2754 return SPELL_SPECIFIC_SEAL;
2755
2756 if (SpellFamilyFlags[0] & 0x00002190)
2757 return SPELL_SPECIFIC_HAND;
2758
2759 // only paladin auras have this (for palaldin class family)
2760 switch (Id)
2761 {
2762 case 465: // Devotion Aura
2763 case 32223: // Crusader Aura
2764 case 183435: // Retribution Aura
2765 case 317920: // Concentration Aura
2766 return SPELL_SPECIFIC_AURA;
2767 default:
2768 break;
2769 }
2770
2771 break;
2772 }
2773 case SPELLFAMILY_SHAMAN:
2774 {
2775 // family flags 10 (Lightning), 42 (Earth), 37 (Water), proc shield from T2 8 pieces bonus
2776 if (SpellFamilyFlags[1] & 0x420
2777 || SpellFamilyFlags[0] & 0x00000400
2778 || Id == 23552)
2780
2781 break;
2782 }
2784 if (Id == 48266 || Id == 48263 || Id == 48265)
2786 break;
2787 }
2788
2789 for (SpellEffectInfo const& effect : GetEffects())
2790 {
2791 if (effect.IsEffect(SPELL_EFFECT_APPLY_AURA))
2792 {
2793 switch (effect.ApplyAuraName)
2794 {
2799 return SPELL_SPECIFIC_CHARM;
2802 if (Id == 30645) // Gas Cloud Tracking
2803 return SPELL_SPECIFIC_NORMAL;
2804 [[fallthrough]];
2808 default:
2809 break;
2810 }
2811 }
2812 }
2813 return SPELL_SPECIFIC_NORMAL;
2814 }();
2815}
2816
2818{
2819 auto diminishingGroupCompute = [this]() -> DiminishingGroup
2820 {
2821 if (IsPositive())
2822 return DIMINISHING_NONE;
2823
2825 return DIMINISHING_TAUNT;
2826
2827 switch (Id)
2828 {
2829 case 20549: // War Stomp (Racial - Tauren)
2830 case 24394: // Intimidation
2831 case 118345: // Pulverize (Primal Earth Elemental)
2832 case 118905: // Static Charge (Capacitor Totem)
2833 return DIMINISHING_STUN;
2834 case 107079: // Quaking Palm
2836 case 155145: // Arcane Torrent (Racial - Blood Elf)
2837 return DIMINISHING_SILENCE;
2838 case 108199: // Gorefiend's Grasp
2839 case 191244: // Sticky Bomb
2841 default:
2842 break;
2843 }
2844
2845 // Explicit Diminishing Groups
2846 switch (SpellFamilyName)
2847 {
2849 // Frost Tomb
2850 if (Id == 48400)
2851 return DIMINISHING_NONE;
2852 // Gnaw
2853 else if (Id == 47481)
2854 return DIMINISHING_STUN;
2855 // ToC Icehowl Arctic Breath
2856 else if (Id == 66689)
2857 return DIMINISHING_NONE;
2858 // Black Plague
2859 else if (Id == 64155)
2860 return DIMINISHING_NONE;
2861 // Screams of the Dead (King Ymiron)
2862 else if (Id == 51750)
2863 return DIMINISHING_NONE;
2864 // Crystallize (Keristrasza heroic)
2865 else if (Id == 48179)
2866 return DIMINISHING_NONE;
2867 break;
2868 case SPELLFAMILY_MAGE:
2869 {
2870 // Frost Nova -- 122
2871 if (SpellFamilyFlags[0] & 0x40)
2872 return DIMINISHING_ROOT;
2873 // Freeze (Water Elemental) -- 33395
2874 if (SpellFamilyFlags[2] & 0x200)
2875 return DIMINISHING_ROOT;
2876
2877 // Dragon's Breath -- 31661
2878 if (SpellFamilyFlags[0] & 0x800000)
2880 // Polymorph -- 118
2881 if (SpellFamilyFlags[0] & 0x1000000)
2883 // Ring of Frost -- 82691
2884 if (SpellFamilyFlags[2] & 0x40)
2886 // Ice Nova -- 157997
2887 if (SpellFamilyFlags[2] & 0x800000)
2889 break;
2890 }
2892 {
2893 // Shockwave -- 132168
2894 if (SpellFamilyFlags[1] & 0x8000)
2895 return DIMINISHING_STUN;
2896 // Storm Bolt -- 132169
2897 if (SpellFamilyFlags[2] & 0x1000)
2898 return DIMINISHING_STUN;
2899
2900 // Intimidating Shout -- 5246
2901 if (SpellFamilyFlags[0] & 0x40000)
2902 return DIMINISHING_DISORIENT;
2903 break;
2904 }
2906 {
2907 // Mortal Coil -- 6789
2908 if (SpellFamilyFlags[0] & 0x80000)
2910 // Banish -- 710
2911 if (SpellFamilyFlags[1] & 0x8000000)
2913
2914 // Fear -- 118699
2915 if (SpellFamilyFlags[1] & 0x400)
2916 return DIMINISHING_DISORIENT;
2917 // Howl of Terror -- 5484
2918 if (SpellFamilyFlags[1] & 0x8)
2919 return DIMINISHING_DISORIENT;
2920
2921 // Shadowfury -- 30283
2922 if (SpellFamilyFlags[1] & 0x1000)
2923 return DIMINISHING_STUN;
2924 // Summon Infernal -- 22703
2925 if (SpellFamilyFlags[0] & 0x1000)
2926 return DIMINISHING_STUN;
2927
2928 // 170995 -- Cripple
2929 if (Id == 170995)
2930 return DIMINISHING_LIMITONLY;
2931 break;
2932 }
2934 {
2935 // Fellash -- 115770
2936 // Whiplash -- 6360
2937 if (SpellFamilyFlags[0] & 0x8000000)
2939
2940 // Mesmerize (Shivarra pet) -- 115268
2941 // Seduction (Succubus pet) -- 6358
2942 if (SpellFamilyFlags[0] & 0x2000000)
2943 return DIMINISHING_DISORIENT;
2944
2945 // Axe Toss (Felguard pet) -- 89766
2946 if (SpellFamilyFlags[1] & 0x4)
2947 return DIMINISHING_STUN;
2948 break;
2949 }
2950 case SPELLFAMILY_DRUID:
2951 {
2952 // Maim -- 22570
2953 if (SpellFamilyFlags[1] & 0x80)
2954 return DIMINISHING_STUN;
2955 // Mighty Bash -- 5211
2956 if (SpellFamilyFlags[0] & 0x2000)
2957 return DIMINISHING_STUN;
2958 // Rake -- 163505 -- no flags on the stun
2959 if (Id == 163505)
2960 return DIMINISHING_STUN;
2961
2962 // Incapacitating Roar -- 99, no flags on the stun, 14
2963 if (SpellFamilyFlags[1] & 0x1)
2965
2966 // Cyclone -- 33786
2967 if (SpellFamilyFlags[1] & 0x20)
2968 return DIMINISHING_DISORIENT;
2969
2970 // Solar Beam -- 81261
2971 if (Id == 81261)
2972 return DIMINISHING_SILENCE;
2973
2974 // Typhoon -- 61391
2975 if (SpellFamilyFlags[1] & 0x1000000)
2977 // Ursol's Vortex -- 118283, no family flags
2978 if (Id == 118283)
2980
2981 // Entangling Roots -- 339
2982 if (SpellFamilyFlags[0] & 0x200)
2983 return DIMINISHING_ROOT;
2984 // Mass Entanglement -- 102359
2985 if (SpellFamilyFlags[2] & 0x4)
2986 return DIMINISHING_ROOT;
2987 break;
2988 }
2989 case SPELLFAMILY_ROGUE:
2990 {
2991 // Between the Eyes -- 199804
2992 if (SpellFamilyFlags[0] & 0x800000)
2993 return DIMINISHING_STUN;
2994 // Cheap Shot -- 1833
2995 if (SpellFamilyFlags[0] & 0x400)
2996 return DIMINISHING_STUN;
2997 // Kidney Shot -- 408
2998 if (SpellFamilyFlags[0] & 0x200000)
2999 return DIMINISHING_STUN;
3000
3001 // Gouge -- 1776
3002 if (SpellFamilyFlags[0] & 0x8)
3004 // Sap -- 6770
3005 if (SpellFamilyFlags[0] & 0x80)
3007
3008 // Blind -- 2094
3009 if (SpellFamilyFlags[0] & 0x1000000)
3010 return DIMINISHING_DISORIENT;
3011
3012 // Garrote -- 1330
3013 if (SpellFamilyFlags[1] & 0x20000000)
3014 return DIMINISHING_SILENCE;
3015 break;
3016 }
3017 case SPELLFAMILY_HUNTER:
3018 {
3019 // Charge (Tenacity pet) -- 53148, no flags
3020 if (Id == 53148)
3021 return DIMINISHING_ROOT;
3022 // Ranger's Net -- 200108
3023 // Tracker's Net -- 212638
3024 if (Id == 200108 || Id == 212638)
3025 return DIMINISHING_ROOT;
3026
3027 // Binding Shot -- 117526, no flags
3028 if (Id == 117526)
3029 return DIMINISHING_STUN;
3030
3031 // Freezing Trap -- 3355
3032 if (SpellFamilyFlags[0] & 0x8)
3034 // Wyvern Sting -- 19386
3035 if (SpellFamilyFlags[1] & 0x1000)
3037
3038 // Bursting Shot -- 224729
3039 if (SpellFamilyFlags[2] & 0x40)
3040 return DIMINISHING_DISORIENT;
3041 // Scatter Shot -- 213691
3042 if (SpellFamilyFlags[2] & 0x8000)
3043 return DIMINISHING_DISORIENT;
3044
3045 // Spider Sting -- 202933
3046 if (Id == 202933)
3047 return DIMINISHING_SILENCE;
3048 break;
3049 }
3051 {
3052 // Repentance -- 20066
3053 if (SpellFamilyFlags[0] & 0x4)
3055
3056 // Blinding Light -- 105421
3057 if (Id == 105421)
3058 return DIMINISHING_DISORIENT;
3059
3060 // Avenger's Shield -- 31935
3061 if (SpellFamilyFlags[0] & 0x4000)
3062 return DIMINISHING_SILENCE;
3063
3064 // Hammer of Justice -- 853
3065 if (SpellFamilyFlags[0] & 0x800)
3066 return DIMINISHING_STUN;
3067 break;
3068 }
3069 case SPELLFAMILY_SHAMAN:
3070 {
3071 // Hex -- 51514
3072 // Hex -- 196942 (Voodoo Totem)
3073 if (SpellFamilyFlags[1] & 0x8000)
3075
3076 // Thunderstorm -- 51490
3077 if (SpellFamilyFlags[1] & 0x2000)
3079
3080 // Earthgrab Totem -- 64695
3081 if (SpellFamilyFlags[2] & 0x4000)
3082 return DIMINISHING_ROOT;
3083
3084 // Lightning Lasso -- 204437
3085 if (SpellFamilyFlags[3] & 0x2000000)
3086 return DIMINISHING_STUN;
3087 break;
3088 }
3090 {
3091 // Chains of Ice -- 96294
3092 if (Id == 96294)
3093 return DIMINISHING_ROOT;
3094
3095 // Blinding Sleet -- 207167
3096 if (Id == 207167)
3097 return DIMINISHING_DISORIENT;
3098
3099 // Strangulate -- 47476
3100 if (SpellFamilyFlags[0] & 0x200)
3101 return DIMINISHING_SILENCE;
3102
3103 // Asphyxiate -- 108194
3104 if (SpellFamilyFlags[2] & 0x100000)
3105 return DIMINISHING_STUN;
3106 // Gnaw (Ghoul) -- 91800, no flags
3107 if (Id == 91800)
3108 return DIMINISHING_STUN;
3109 // Monstrous Blow (Ghoul w/ Dark Transformation active) -- 91797
3110 if (Id == 91797)
3111 return DIMINISHING_STUN;
3112 // Winter is Coming -- 207171
3113 if (Id == 207171)
3114 return DIMINISHING_STUN;
3115 break;
3116 }
3117 case SPELLFAMILY_PRIEST:
3118 {
3119 // Holy Word: Chastise -- 200200
3120 if (SpellFamilyFlags[2] & 0x20 && GetSpellVisual() == 52021)
3121 return DIMINISHING_STUN;
3122 // Mind Bomb -- 226943
3123 if (Id == 226943)
3124 return DIMINISHING_STUN;
3125
3126 // Mind Control -- 605
3127 if (SpellFamilyFlags[0] & 0x20000 && GetSpellVisual() == 39068)
3129 // Holy Word: Chastise -- 200196
3130 if (SpellFamilyFlags[2] & 0x20 && GetSpellVisual() == 52019)
3132
3133 // Psychic Scream -- 8122
3134 if (SpellFamilyFlags[0] & 0x10000)
3135 return DIMINISHING_DISORIENT;
3136
3137 // Silence -- 15487
3138 if (SpellFamilyFlags[1] & 0x200000 && GetSpellVisual() == 39025)
3139 return DIMINISHING_SILENCE;
3140
3141 // Shining Force -- 204263
3142 if (Id == 204263)
3144 break;
3145 }
3146 case SPELLFAMILY_MONK:
3147 {
3148 // Disable -- 116706, no flags
3149 if (Id == 116706)
3150 return DIMINISHING_ROOT;
3151
3152 // Fists of Fury -- 120086
3153 if (SpellFamilyFlags[1] & 0x800000 && !(SpellFamilyFlags[2] & 0x8))
3154 return DIMINISHING_STUN;
3155 // Leg Sweep -- 119381
3156 if (SpellFamilyFlags[1] & 0x200)
3157 return DIMINISHING_STUN;
3158
3159 // Incendiary Breath (honor talent) -- 202274, no flags
3160 if (Id == 202274)
3162 // Paralysis -- 115078
3163 if (SpellFamilyFlags[2] & 0x800000)
3165
3166 // Song of Chi-Ji -- 198909
3167 if (Id == 198909)
3168 return DIMINISHING_DISORIENT;
3169 break;
3170 }
3172 {
3173 switch (Id)
3174 {
3175 case 179057: // Chaos Nova
3176 case 211881: // Fel Eruption
3177 case 200166: // Metamorphosis
3178 case 205630: // Illidan's Grasp
3179 return DIMINISHING_STUN;
3180 case 217832: // Imprison
3181 case 221527: // Imprison
3183 default:
3184 break;
3185 }
3186 break;
3187 }
3188 default:
3189 break;
3190 }
3191
3192 return DIMINISHING_NONE;
3193 };
3194
3195 auto diminishingTypeCompute = [](DiminishingGroup group) -> DiminishingReturnsType
3196 {
3197 switch (group)
3198 {
3199 case DIMINISHING_TAUNT:
3200 case DIMINISHING_STUN:
3201 return DRTYPE_ALL;
3203 case DIMINISHING_NONE:
3204 return DRTYPE_NONE;
3205 default:
3206 return DRTYPE_PLAYER;
3207 }
3208 };
3209
3210 auto diminishingMaxLevelCompute = [](DiminishingGroup group) -> DiminishingLevels
3211 {
3212 switch (group)
3213 {
3214 case DIMINISHING_TAUNT:
3217 return DIMINISHING_LEVEL_2;
3218 default:
3220 }
3221 };
3222
3223 auto diminishingLimitDurationCompute = [this]() -> int32
3224 {
3225 // Explicit diminishing duration
3226 switch (SpellFamilyName)
3227 {
3228 case SPELLFAMILY_MAGE:
3229 {
3230 // Dragon's Breath - 3 seconds in PvP
3231 if (SpellFamilyFlags[0] & 0x800000)
3232 return 3 * IN_MILLISECONDS;
3233 break;
3234 }
3236 {
3237 // Cripple - 4 seconds in PvP
3238 if (Id == 170995)
3239 return 4 * IN_MILLISECONDS;
3240 break;
3241 }
3242 case SPELLFAMILY_HUNTER:
3243 {
3244 // Binding Shot - 3 seconds in PvP
3245 if (Id == 117526)
3246 return 3 * IN_MILLISECONDS;
3247
3248 // Wyvern Sting - 6 seconds in PvP
3249 if (SpellFamilyFlags[1] & 0x1000)
3250 return 6 * IN_MILLISECONDS;
3251 break;
3252 }
3253 case SPELLFAMILY_MONK:
3254 {
3255 // Paralysis - 4 seconds in PvP regardless of if they are facing you
3256 if (SpellFamilyFlags[2] & 0x800000)
3257 return 4 * IN_MILLISECONDS;
3258 break;
3259 }
3261 {
3262 switch (Id)
3263 {
3264 case 217832: // Imprison
3265 case 221527: // Imprison
3266 return 4 * IN_MILLISECONDS;
3267 default:
3268 break;
3269 }
3270 break;
3271 }
3272 default:
3273 break;
3274 }
3275
3276 return 8 * IN_MILLISECONDS;
3277 };
3278
3279 SpellDiminishInfo diminishInfo;
3280 diminishInfo.DiminishGroup = diminishingGroupCompute();
3281 diminishInfo.DiminishReturnType = diminishingTypeCompute(diminishInfo.DiminishGroup);
3282 diminishInfo.DiminishMaxLevel = diminishingMaxLevelCompute(diminishInfo.DiminishGroup);
3283 diminishInfo.DiminishDurationLimit = diminishingLimitDurationCompute();
3284
3285 _diminishInfo = diminishInfo;
3286}
3287
3289{
3291}
3292
3294{
3296}
3297
3299{
3301}
3302
3304{
3306}
3307
3309{
3310 std::unique_ptr<SpellEffectInfo::ImmunityInfo> workBuffer = std::make_unique<SpellEffectInfo::ImmunityInfo>();
3311
3312 for (SpellEffectInfo& effect : _effects)
3313 {
3314 uint32 schoolImmunityMask = 0;
3315 uint32 applyHarmfulAuraImmunityMask = 0;
3316 uint64 mechanicImmunityMask = 0;
3317 uint32 dispelImmunityMask = 0;
3318 uint32 damageImmunityMask = 0;
3319 uint8 otherImmunityMask = 0;
3320
3321 int32 miscVal = effect.MiscValue;
3322
3323 SpellEffectInfo::ImmunityInfo& immuneInfo = *workBuffer;
3324
3325 switch (effect.ApplyAuraName)
3326 {
3328 {
3329 if (CreatureImmunities const* creatureImmunities = SpellMgr::GetCreatureImmunities(miscVal))
3330 {
3331 schoolImmunityMask |= creatureImmunities->School.to_ulong();
3332 dispelImmunityMask |= creatureImmunities->DispelType.to_ulong();
3333 mechanicImmunityMask |= creatureImmunities->Mechanic.to_ullong();
3334 otherImmunityMask |= creatureImmunities->Other.AsUnderlyingType();
3335 for (SpellEffectName effectType : creatureImmunities->Effect)
3336 immuneInfo.SpellEffectImmune.insert(effectType);
3337 for (AuraType aura : creatureImmunities->Aura)
3338 immuneInfo.AuraTypeImmune.insert(aura);
3339 }
3340 break;
3341 }
3343 {
3344 switch (Id)
3345 {
3346 case 42292: // PvP trinket
3347 case 59752: // Every Man for Himself
3350 break;
3351 case 34471: // The Beast Within
3352 case 19574: // Bestial Wrath
3353 case 46227: // Medallion of Immunity
3354 case 53490: // Bullheaded
3355 case 65547: // PvP Trinket
3356 case 134946: // Supremacy of the Alliance
3357 case 134956: // Supremacy of the Horde
3358 case 195710: // Honorable Medallion
3359 case 208683: // Gladiator's Medallion
3361 break;
3362 case 54508: // Demonic Empowerment
3363 mechanicImmunityMask |= (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT) | (1 << MECHANIC_STUN);
3364 break;
3365 default:
3366 if (miscVal < 1)
3367 break;
3368
3369 mechanicImmunityMask |= UI64LIT(1) << miscVal;
3370 break;
3371 }
3372 break;
3373 }
3375 {
3376 immuneInfo.SpellEffectImmune.insert(static_cast<SpellEffectName>(miscVal));
3377 break;
3378 }
3380 {
3381 immuneInfo.AuraTypeImmune.insert(static_cast<AuraType>(miscVal));
3382 break;
3383 }
3385 {
3386 schoolImmunityMask |= uint32(miscVal);
3387 break;
3388 }
3390 {
3391 applyHarmfulAuraImmunityMask |= uint32(miscVal);
3392 break;
3393 }
3395 {
3396 damageImmunityMask |= uint32(miscVal);
3397 break;
3398 }
3400 {
3401 dispelImmunityMask = 1u << miscVal;
3402 break;
3403 }
3404 default:
3405 break;
3406 }
3407
3408 immuneInfo.SchoolImmuneMask = schoolImmunityMask;
3409 immuneInfo.ApplyHarmfulAuraImmuneMask = applyHarmfulAuraImmunityMask;
3410 immuneInfo.MechanicImmuneMask = mechanicImmunityMask;
3411 immuneInfo.DispelImmuneMask = dispelImmunityMask;
3412 immuneInfo.DamageSchoolMask = damageImmunityMask;
3413 immuneInfo.OtherImmuneMask = otherImmunityMask;
3414
3415 immuneInfo.AuraTypeImmune.shrink_to_fit();
3416 immuneInfo.SpellEffectImmune.shrink_to_fit();
3417
3418 if (immuneInfo.SchoolImmuneMask
3419 || immuneInfo.ApplyHarmfulAuraImmuneMask
3420 || immuneInfo.MechanicImmuneMask
3421 || immuneInfo.DispelImmuneMask
3422 || immuneInfo.DamageSchoolMask
3423 || immuneInfo.OtherImmuneMask
3424 || !immuneInfo.AuraTypeImmune.empty()
3425 || !immuneInfo.SpellEffectImmune.empty())
3426 {
3427 effect._immunityInfo = std::move(workBuffer);
3428 workBuffer = std::make_unique<SpellEffectInfo::ImmunityInfo>();
3429 }
3430
3432 }
3433
3435 {
3436 switch (Id)
3437 {
3438 case 22812: // Barkskin
3439 case 47585: // Dispersion
3441 (1 << MECHANIC_STUN) |
3442 (1 << MECHANIC_FREEZE) |
3443 (1 << MECHANIC_KNOCKOUT) |
3444 (1 << MECHANIC_SLEEP);
3445 break;
3446 case 49039: // Lichborne, don't allow normal stuns
3447 break;
3448 default:
3450 break;
3451 }
3452 }
3453
3456
3458 {
3459 switch (Id)
3460 {
3461 case 22812: // Barkskin
3462 case 47585: // Dispersion
3464 break;
3465 default:
3467 break;
3468 }
3469 }
3470}
3471
3472void SpellInfo::_LoadSqrtTargetLimit(int32 maxTargets, int32 numNonDiminishedTargets, Optional<SpellEffIndex> maxTargetsEffectValueHolder,
3473 Optional<SpellEffIndex> numNonDiminishedTargetsEffectValueHolder)
3474{
3475 SqrtDamageAndHealingDiminishing.MaxTargets = maxTargets;
3476 SqrtDamageAndHealingDiminishing.NumNonDiminishedTargets = numNonDiminishedTargets;
3477
3478 if (maxTargetsEffectValueHolder)
3479 {
3480 if (maxTargetsEffectValueHolder < GetEffects().size())
3481 {
3482 SpellEffectInfo const& valueHolder = GetEffect(*maxTargetsEffectValueHolder);
3483 int32 expectedValue = valueHolder.CalcBaseValue(nullptr, nullptr, 0, -1);
3484 if (maxTargets != expectedValue)
3485 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(maxTargets): Spell {} has different value in effect {} than expected, recheck target caps (expected {}, got {})",
3486 Id, AsUnderlyingType(*maxTargetsEffectValueHolder), maxTargets, expectedValue);
3487 }
3488 else
3489 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(maxTargets): Spell {} does not have effect {}", Id, AsUnderlyingType(*maxTargetsEffectValueHolder));
3490 }
3491
3492 if (numNonDiminishedTargetsEffectValueHolder)
3493 {
3494 if (numNonDiminishedTargetsEffectValueHolder < GetEffects().size())
3495 {
3496 SpellEffectInfo const& valueHolder = GetEffect(*numNonDiminishedTargetsEffectValueHolder);
3497 int32 expectedValue = valueHolder.CalcBaseValue(nullptr, nullptr, 0, -1);
3498 if (numNonDiminishedTargets != expectedValue)
3499 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(numNonDiminishedTargets): Spell {} has different value in effect {} than expected, recheck target caps (expected {}, got {})",
3500 Id, AsUnderlyingType(*numNonDiminishedTargetsEffectValueHolder), numNonDiminishedTargets, expectedValue);
3501 }
3502 else
3503 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(numNonDiminishedTargets): Spell {} does not have effect {}", Id, AsUnderlyingType(*numNonDiminishedTargetsEffectValueHolder));
3504 }
3505}
3506
3507void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& spellEffectInfo, bool apply) const
3508{
3509 SpellEffectInfo::ImmunityInfo const* immuneInfo = spellEffectInfo.GetImmunityInfo();
3510 if (!immuneInfo)
3511 return;
3512
3513 if (uint32 schoolImmunity = immuneInfo->SchoolImmuneMask)
3514 {
3515 target->ApplySpellImmune(Id, IMMUNITY_SCHOOL, schoolImmunity, apply);
3516
3518 {
3519 target->RemoveAppliedAuras([this, schoolImmunity](AuraApplication const* aurApp) -> bool
3520 {
3521 SpellInfo const* auraSpellInfo = aurApp->GetBase()->GetSpellInfo();
3522 return ((auraSpellInfo->GetSchoolMask() & schoolImmunity) != 0 && // Check for school mask
3523 CanDispelAura(auraSpellInfo) &&
3524 (IsPositive() != aurApp->IsPositive()) && // Check spell vs aura possitivity
3525 !auraSpellInfo->IsPassive() && // Don't remove passive auras
3526 auraSpellInfo->Id != Id); // Don't remove self
3527 });
3528 }
3529
3530 if (apply && schoolImmunity & SPELL_SCHOOL_MASK_NORMAL)
3532 }
3533
3534 if (uint64 mechanicImmunity = immuneInfo->MechanicImmuneMask)
3535 {
3536 for (uint32 i = 0; i < MAX_MECHANIC; ++i)
3537 if (mechanicImmunity & (UI64LIT(1) << i))
3539
3541 {
3542 if (apply)
3543 target->RemoveAurasWithMechanic(mechanicImmunity, AURA_REMOVE_BY_DEFAULT, Id);
3544 else
3545 {
3546 std::vector<Aura*> aurasToUpdateTargets;
3547 target->RemoveAppliedAuras([mechanicImmunity, &aurasToUpdateTargets](AuraApplication const* aurApp)
3548 {
3549 Aura* aura = aurApp->GetBase();
3550 if (aura->GetSpellInfo()->GetAllEffectsMechanicMask() & mechanicImmunity)
3551 aurasToUpdateTargets.push_back(aura);
3552
3553 // only update targets, don't remove anything
3554 return false;
3555 });
3556
3557 for (Aura* aura : aurasToUpdateTargets)
3558 aura->UpdateTargetMap(aura->GetCaster());
3559 }
3560 }
3561 }
3562
3563 if (uint32 dispelImmunity = immuneInfo->DispelImmuneMask)
3564 {
3565 for (uint32 i = 0; i < DISPEL_MAX; ++i)
3566 if (dispelImmunity & (1 << i))
3568
3570 {
3571 target->RemoveAppliedAuras([dispelImmunity](AuraApplication const* aurApp) -> bool
3572 {
3573 SpellInfo const* spellInfo = aurApp->GetBase()->GetSpellInfo();
3574 uint32 dispelMask = spellInfo->GetDispelMask();
3575 if ((dispelMask & dispelImmunity) == dispelMask)
3576 return true;
3577
3578 return false;
3579 });
3580 }
3581 }
3582
3583 if (uint32 damageImmunity = immuneInfo->DamageSchoolMask)
3584 {
3585 target->ApplySpellImmune(Id, IMMUNITY_DAMAGE, damageImmunity, apply);
3586
3587 if (apply && damageImmunity & SPELL_SCHOOL_MASK_NORMAL)
3589 }
3590
3591 for (AuraType auraType : immuneInfo->AuraTypeImmune)
3592 {
3593 target->ApplySpellImmune(Id, IMMUNITY_STATE, auraType, apply);
3595 target->RemoveAurasByType(auraType, [](AuraApplication const* aurApp) -> bool
3596 {
3597 // if the aura has SPELL_ATTR0_NO_IMMUNITIES, then it cannot be removed by immunity
3598 return !aurApp->GetBase()->GetSpellInfo()->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES);
3599 });
3600 }
3601
3602 for (SpellEffectName effectType : immuneInfo->SpellEffectImmune)
3603 target->ApplySpellImmune(Id, IMMUNITY_EFFECT, effectType, apply);
3604
3605 if (uint8 otherImmuneMask = immuneInfo->OtherImmuneMask)
3606 target->ApplySpellImmune(Id, IMMUNITY_OTHER, otherImmuneMask, apply);
3607}
3608
3610{
3611 if (!auraSpellInfo)
3612 return false;
3613
3614 for (SpellEffectInfo const& effectInfo : _effects)
3615 {
3616 if (!effectInfo.IsEffect())
3617 continue;
3618
3619 SpellEffectInfo::ImmunityInfo const* immuneInfo = effectInfo.GetImmunityInfo();
3620 if (!immuneInfo)
3621 continue;
3622
3624 {
3625 if (uint32 schoolImmunity = immuneInfo->SchoolImmuneMask)
3626 if ((auraSpellInfo->SchoolMask & schoolImmunity) != 0)
3627 return true;
3628 }
3629
3630 if (uint64 mechanicImmunity = immuneInfo->MechanicImmuneMask)
3631 if ((mechanicImmunity & (UI64LIT(1) << auraSpellInfo->Mechanic)) != 0)
3632 return true;
3633
3634 if (uint32 dispelImmunity = immuneInfo->DispelImmuneMask)
3635 if (auraSpellInfo->Dispel == dispelImmunity)
3636 return true;
3637
3638 bool immuneToAllEffects = true;
3639 for (SpellEffectInfo const& auraSpellEffectInfo : auraSpellInfo->GetEffects())
3640 {
3641 if (!auraSpellEffectInfo.IsEffect())
3642 continue;
3643
3644 auto spellImmuneItr = immuneInfo->SpellEffectImmune.find(auraSpellEffectInfo.Effect);
3645 if (spellImmuneItr == immuneInfo->SpellEffectImmune.end())
3646 {
3647 immuneToAllEffects = false;
3648 break;
3649 }
3650
3651 if (uint32 mechanic = auraSpellEffectInfo.Mechanic)
3652 {
3653 if (!(immuneInfo->MechanicImmuneMask & (UI64LIT(1) << mechanic)))
3654 {
3655 immuneToAllEffects = false;
3656 break;
3657 }
3658 }
3659
3660 if (!auraSpellInfo->HasAttribute(SPELL_ATTR3_ALWAYS_HIT))
3661 {
3662 if (AuraType auraName = auraSpellEffectInfo.ApplyAuraName)
3663 {
3664 bool isImmuneToAuraEffectApply = false;
3665 auto auraImmuneItr = immuneInfo->AuraTypeImmune.find(auraName);
3666 if (auraImmuneItr != immuneInfo->AuraTypeImmune.end())
3667 isImmuneToAuraEffectApply = true;
3668
3669 if (!isImmuneToAuraEffectApply && !auraSpellInfo->IsPositiveEffect(auraSpellEffectInfo.EffectIndex) && !auraSpellInfo->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES))
3670 {
3671 if (uint32 applyHarmfulAuraImmunityMask = immuneInfo->ApplyHarmfulAuraImmuneMask)
3672 if ((auraSpellInfo->GetSchoolMask() & applyHarmfulAuraImmunityMask) != 0)
3673 isImmuneToAuraEffectApply = true;
3674 }
3675
3676 if (!isImmuneToAuraEffectApply)
3677 {
3678 immuneToAllEffects = false;
3679 break;
3680 }
3681 }
3682 }
3683 }
3684
3685 if (immuneToAllEffects)
3686 return true;
3687 }
3688
3689 return false;
3690}
3691
3692// based on client Spell_C::CancelsAuraEffect
3694{
3696 return false;
3697
3699 return false;
3700
3701 for (SpellEffectInfo const& effect : GetEffects())
3702 {
3703 if (!effect.IsEffect(SPELL_EFFECT_APPLY_AURA))
3704 continue;
3705
3706 uint32 const miscValue = static_cast<uint32>(effect.MiscValue);
3707 switch (effect.ApplyAuraName)
3708 {
3710 if (miscValue != aurEff->GetAuraType())
3711 continue;
3712 break;
3715 if (aurEff->GetSpellInfo()->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES) || !(aurEff->GetSpellInfo()->SchoolMask & miscValue))
3716 continue;
3717 break;
3719 if (miscValue != aurEff->GetSpellInfo()->Dispel)
3720 continue;
3721 break;
3723 if (miscValue != aurEff->GetSpellInfo()->Mechanic)
3724 {
3725 if (miscValue != aurEff->GetSpellEffectInfo().Mechanic)
3726 continue;
3727 }
3728 break;
3729 default:
3730 continue;
3731 }
3732
3733 return true;
3734 }
3735
3736 return false;
3737}
3738
3740{
3741 return _allowedMechanicMask;
3742}
3743
3745{
3746 uint64 casterMechanicImmunityMask = caster->GetMechanicImmunityMask();
3747 uint64 mechanicImmunityMask = 0;
3748
3749 if (CanBeInterrupted(nullptr, caster, true))
3750 {
3751 if (casterMechanicImmunityMask & (1 << MECHANIC_SILENCE))
3752 mechanicImmunityMask |= (1 << MECHANIC_SILENCE);
3753
3754 if (casterMechanicImmunityMask & (1 << MECHANIC_INTERRUPT))
3755 mechanicImmunityMask |= (1 << MECHANIC_INTERRUPT);
3756 }
3757
3758 return mechanicImmunityMask;
3759}
3760
3761float SpellInfo::GetMinRange(bool positive /*= false*/) const
3762{
3763 if (!RangeEntry)
3764 return 0.0f;
3765 return RangeEntry->RangeMin[positive ? 1 : 0];
3766}
3767
3768float SpellInfo::GetMaxRange(bool positive /*= false*/, WorldObject* caster /*= nullptr*/, Spell* spell /*= nullptr*/) const
3769{
3770 if (!RangeEntry)
3771 return 0.0f;
3772 float range = RangeEntry->RangeMax[positive ? 1 : 0];
3773 if (caster)
3774 if (Player* modOwner = caster->GetSpellModOwner())
3775 modOwner->ApplySpellMod(this, SpellModOp::Range, range, spell);
3776
3777 return range;
3778}
3779
3780int32 SpellInfo::CalcDuration(WorldObject const* caster /*= nullptr*/) const
3781{
3782 int32 duration = GetDuration();
3783
3784 if (caster)
3785 if (Player* modOwner = caster->GetSpellModOwner())
3786 modOwner->ApplySpellMod(this, SpellModOp::Duration, duration);
3787
3788 return duration;
3789}
3790
3792{
3793 if (!DurationEntry)
3794 return IsPassive() ? -1 : 0;
3795 return (DurationEntry->Duration == -1) ? -1 : abs(DurationEntry->Duration);
3796}
3797
3799{
3800 if (!DurationEntry)
3801 return IsPassive() ? -1 : 0;
3802 return (DurationEntry->MaxDuration == -1) ? -1 : abs(DurationEntry->MaxDuration);
3803}
3804
3805uint32 SpellInfo::CalcCastTime(Spell* spell /*= nullptr*/) const
3806{
3807 int32 castTime = 0;
3808 if (CastTimeEntry)
3809 castTime = std::max(CastTimeEntry->Base, CastTimeEntry->Minimum);
3810
3811 if (castTime <= 0)
3812 return 0;
3813
3814 if (spell)
3815 spell->GetCaster()->ModSpellCastTime(this, castTime, spell);
3816
3818 castTime += 500;
3819
3820 return (castTime > 0) ? uint32(castTime) : 0;
3821}
3822
3824{
3825 uint32 totalTicks = 0;
3826 int32 DotDuration = GetDuration();
3827
3828 for (SpellEffectInfo const& effect : GetEffects())
3829 {
3830 if (effect.IsEffect(SPELL_EFFECT_APPLY_AURA))
3831 {
3832 switch (effect.ApplyAuraName)
3833 {
3848 // skip infinite periodics
3849 if (effect.ApplyAuraPeriod > 0 && DotDuration > 0)
3850 {
3851 totalTicks = static_cast<uint32>(DotDuration) / effect.ApplyAuraPeriod;
3853 ++totalTicks;
3854 }
3855 break;
3856 default:
3857 break;
3858 }
3859 }
3860 }
3861
3862 return totalTicks;
3863}
3864
3866{
3868}
3869
3870Optional<SpellPowerCost> SpellInfo::CalcPowerCost(Powers powerType, bool optionalCost, WorldObject const* caster, SpellSchoolMask schoolMask, Spell* spell /*= nullptr*/) const
3871{
3872 // gameobject casts don't use power
3873 Unit const* unitCaster = caster->ToUnit();
3874 if (!unitCaster)
3875 return {};
3876
3877 auto itr = std::find_if(PowerCosts.cbegin(), PowerCosts.cend(), [powerType](SpellPowerEntry const* spellPowerEntry)
3878 {
3879 return spellPowerEntry && spellPowerEntry->PowerType == powerType;
3880 });
3881 if (itr == PowerCosts.cend())
3882 return {};
3883
3884 return CalcPowerCost(*itr, optionalCost, caster, schoolMask, spell);
3885}
3886
3887Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power, bool optionalCost, WorldObject const* caster, SpellSchoolMask schoolMask, Spell* spell /*= nullptr*/) const
3888{
3889 // gameobject casts don't use power
3890 Unit const* unitCaster = caster->ToUnit();
3891 if (!unitCaster)
3892 return {};
3893
3894 if (power->RequiredAuraSpellID && !unitCaster->HasAura(power->RequiredAuraSpellID))
3895 return {};
3896
3897 // Spell drain all exist power on cast (Only paladin lay of Hands)
3899 {
3900 if (optionalCost)
3901 return {};
3902
3903 // If power type - health drain all
3904 if (power->PowerType == POWER_HEALTH)
3905 return SpellPowerCost{ .Power = POWER_HEALTH, .Amount = int32(unitCaster->GetHealth()) };
3906
3907 // Else drain all power
3908 if (power->PowerType < MAX_POWERS)
3909 return SpellPowerCost{ .Power = Powers(power->PowerType), .Amount = unitCaster->GetPower(Powers(power->PowerType)) };
3910
3911 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type '{}' in spell {}", power->PowerType, Id);
3912 return {};
3913 }
3914
3915 // Base powerCost
3916 int32 powerCost = 0;
3917 if (!optionalCost)
3918 {
3919 powerCost = power->ManaCost;
3920 // PCT cost from total amount
3921 if (power->PowerCostPct)
3922 {
3923 switch (power->PowerType)
3924 {
3925 // health as power used
3926 case POWER_HEALTH:
3927 if (G3D::fuzzyEq(power->PowerCostPct, 0.0f))
3928 powerCost += int32(CalculatePct(unitCaster->GetMaxHealth(), power->PowerCostMaxPct));
3929 else
3930 powerCost += int32(CalculatePct(unitCaster->GetMaxHealth(), power->PowerCostPct));
3931 break;
3932 case POWER_MANA:
3933 powerCost += int32(CalculatePct(unitCaster->GetCreateMana(), power->PowerCostPct));
3934 break;
3936 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type POWER_ALTERNATE_POWER in spell {}", Id);
3937 return {};
3938 default:
3939 {
3940 if (PowerTypeEntry const* powerTypeEntry = sDB2Manager.GetPowerTypeEntry(Powers(power->PowerType)))
3941 {
3942 powerCost += int32(CalculatePct(powerTypeEntry->MaxBasePower, power->PowerCostPct));
3943 break;
3944 }
3945
3946 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type '{}' in spell {}", power->PowerType, Id);
3947 return {};
3948 }
3949 }
3950 }
3951 }
3952 else
3953 {
3954 powerCost = int32(power->OptionalCost);
3955
3956 if (power->OptionalCostPct)
3957 {
3958 switch (power->PowerType)
3959 {
3960 // health as power used
3961 case POWER_HEALTH:
3962 powerCost += int32(CalculatePct(unitCaster->GetMaxHealth(), power->OptionalCostPct));
3963 break;
3964 case POWER_MANA:
3965 powerCost += int32(CalculatePct(unitCaster->GetCreateMana(), power->OptionalCostPct));
3966 break;
3968 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unsupported power type POWER_ALTERNATE_POWER in spell {} for optional cost percent", Id);
3969 return {};
3970 default:
3971 {
3972 if (PowerTypeEntry const* powerTypeEntry = sDB2Manager.GetPowerTypeEntry(Powers(power->PowerType)))
3973 {
3974 powerCost += int32(CalculatePct(powerTypeEntry->MaxBasePower, power->OptionalCostPct));
3975 break;
3976 }
3977
3978 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type '{}' in spell {} for optional cost percent", power->PowerType, Id);
3979 return {};
3980 }
3981 }
3982 }
3983
3984 powerCost += unitCaster->GetTotalAuraModifier(SPELL_AURA_MOD_ADDITIONAL_POWER_COST, [this, power](AuraEffect const* aurEff) -> bool
3985 {
3986 return aurEff->GetMiscValue() == power->PowerType
3987 && aurEff->IsAffectingSpell(this);
3988 });
3989 }
3990
3991 bool initiallyNegative = powerCost < 0;
3992
3993 // Shiv - costs 20 + weaponSpeed*10 energy (apply only to non-triggered spell with energy cost)
3995 {
3996 uint32 speed = 0;
3997 if (SpellShapeshiftFormEntry const* ss = sSpellShapeshiftFormStore.LookupEntry(unitCaster->GetShapeshiftForm()))
3998 speed = ss->CombatRoundTime;
3999 else
4000 {
4003 slot = OFF_ATTACK;
4004
4005 speed = unitCaster->GetBaseAttackTime(slot);
4006 }
4007
4008 powerCost += speed / 100;
4009 }
4010
4011 if (power->PowerType != POWER_HEALTH)
4012 {
4013 if (!optionalCost)
4014 {
4015 // Flat mod from caster auras by spell school and power type
4017 {
4018 if (!(aura->GetMiscValue() & schoolMask))
4019 continue;
4020
4021 if (!(aura->GetMiscValueB() & (1 << power->PowerType)))
4022 continue;
4023
4024 powerCost += aura->GetAmount();
4025 }
4026 }
4027
4028 // PCT mod from user auras by spell school and power type
4029 for (auto schoolCostPct : unitCaster->GetAuraEffectsByType(SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT))
4030 {
4031 if (!(schoolCostPct->GetMiscValue() & schoolMask))
4032 continue;
4033
4034 if (!(schoolCostPct->GetMiscValueB() & (1 << power->PowerType)))
4035 continue;
4036
4037 powerCost += CalculatePct(powerCost, schoolCostPct->GetAmount());
4038 }
4039 }
4040
4041 // Apply cost mod by spell
4042 if (Player* modOwner = unitCaster->GetSpellModOwner())
4043 {
4045 switch (power->OrderIndex)
4046 {
4047 case 0:
4049 break;
4050 case 1:
4052 break;
4053 case 2:
4055 break;
4056 default:
4057 break;
4058 }
4059
4060 if (mod)
4061 {
4062 if (!optionalCost)
4063 modOwner->ApplySpellMod(this, *mod, powerCost, spell);
4064 else
4065 {
4066 // optional cost ignores flat modifiers
4067 int32 flatMod = 0;
4068 float pctMod = 1.0f;
4069 modOwner->GetSpellModValues(this, *mod, spell, powerCost, &flatMod, &pctMod);
4070 powerCost = int32(powerCost * pctMod);
4071 }
4072 }
4073 }
4074
4075 if (!unitCaster->IsControlledByPlayer() && G3D::fuzzyEq(power->PowerCostPct, 0.0f) && SpellLevel && power->PowerType == POWER_MANA)
4076 {
4078 {
4080 GtNpcManaCostScalerEntry const* casterScaler = sNpcManaCostScalerGameTable.GetRow(unitCaster->GetLevel());
4081 if (spellScaler && casterScaler)
4082 powerCost *= casterScaler->Scaler / spellScaler->Scaler;
4083 }
4084 }
4085
4086 if (power->PowerType == POWER_MANA)
4087 powerCost = float(powerCost) * (1.0f + unitCaster->m_unitData->ManaCostMultiplier);
4088
4089 // power cost cannot become negative if initially positive
4090 if (initiallyNegative != (powerCost < 0))
4091 powerCost = 0;
4092
4093 return SpellPowerCost{ .Power = Powers(power->PowerType), .Amount = powerCost };
4094}
4095
4096std::vector<SpellPowerCost> SpellInfo::CalcPowerCost(WorldObject const* caster, SpellSchoolMask schoolMask, Spell* spell) const
4097{
4098 std::vector<SpellPowerCost> costs;
4099 if (caster->IsUnit())
4100 {
4101 costs.reserve(MAX_POWERS_PER_SPELL);
4102
4103 auto getOrCreatePowerCost = [&](Powers powerType) -> SpellPowerCost&
4104 {
4105 auto itr = std::find_if(costs.begin(), costs.end(), [powerType](SpellPowerCost const& cost)
4106 {
4107 return cost.Power == powerType;
4108 });
4109 if (itr != costs.end())
4110 return *itr;
4111
4112 return costs.emplace_back<SpellPowerCost>({ .Power = powerType, .Amount = 0 });
4113 };
4114
4115 for (SpellPowerEntry const* power : PowerCosts)
4116 {
4117 if (!power)
4118 continue;
4119
4120 if (Optional<SpellPowerCost> cost = CalcPowerCost(power, false, caster, schoolMask, spell))
4121 getOrCreatePowerCost(cost->Power).Amount += cost->Amount;
4122
4123 if (Optional<SpellPowerCost> optionalCost = CalcPowerCost(power, true, caster, schoolMask, spell))
4124 {
4125 SpellPowerCost& cost = getOrCreatePowerCost(optionalCost->Power);
4126 int32 remainingPower = caster->ToUnit()->GetPower(optionalCost->Power) - cost.Amount;
4127 if (remainingPower > 0)
4128 cost.Amount += std::min(optionalCost->Amount, remainingPower);
4129 }
4130 }
4131 }
4132
4133 return costs;
4134}
4135
4136inline float CalcPPMHasteMod(SpellProcsPerMinuteModEntry const* mod, Unit* caster)
4137{
4138 float haste = caster->m_unitData->ModHaste;
4139 float rangedHaste = caster->m_unitData->ModRangedHaste;
4140 float spellHaste = caster->m_unitData->ModSpellHaste;
4141 float regenHaste = caster->m_unitData->ModHasteRegen;
4142
4143 switch (mod->Param)
4144 {
4145 case 1:
4146 return (1.0f / haste - 1.0f) * mod->Coeff;
4147 case 2:
4148 return (1.0f / rangedHaste - 1.0f) * mod->Coeff;
4149 case 3:
4150 return (1.0f / spellHaste - 1.0f) * mod->Coeff;
4151 case 4:
4152 return (1.0f / regenHaste - 1.0f) * mod->Coeff;
4153 case 5:
4154 return (1.0f / std::min(std::min(std::min(haste, rangedHaste), spellHaste), regenHaste) - 1.0f) * mod->Coeff;
4155 default:
4156 break;
4157 }
4158
4159 return 0.0f;
4160}
4161
4162inline float CalcPPMCritMod(SpellProcsPerMinuteModEntry const* mod, Unit* caster)
4163{
4164 Player const* player = caster->ToPlayer();
4165 if (!player)
4166 return 0.0f;
4167
4168 float crit = player->m_activePlayerData->CritPercentage;
4169 float rangedCrit = player->m_activePlayerData->RangedCritPercentage;
4170 float spellCrit = player->m_activePlayerData->SpellCritPercentage;
4171
4172 switch (mod->Param)
4173 {
4174 case 1:
4175 return crit * mod->Coeff * 0.01f;
4176 case 2:
4177 return rangedCrit * mod->Coeff * 0.01f;
4178 case 3:
4179 return spellCrit * mod->Coeff * 0.01f;
4180 case 4:
4181 return std::min(std::min(crit, rangedCrit), spellCrit) * mod->Coeff * 0.01f;
4182 default:
4183 break;
4184 }
4185
4186 return 0.0f;
4187}
4188
4189inline float CalcPPMItemLevelMod(SpellProcsPerMinuteModEntry const* mod, int32 itemLevel)
4190{
4191 if (itemLevel == mod->Param)
4192 return 0.0f;
4193
4194 float itemLevelPoints = GetRandomPropertyPoints(itemLevel, ITEM_QUALITY_RARE, INVTYPE_CHEST, 0);
4195 float basePoints = GetRandomPropertyPoints(mod->Param, ITEM_QUALITY_RARE, INVTYPE_CHEST, 0);
4196 if (itemLevelPoints == basePoints)
4197 return 0.0f;
4198
4199 return ((itemLevelPoints / basePoints) - 1.0f) * mod->Coeff;
4200}
4201
4202float SpellInfo::CalcProcPPM(Unit* caster, int32 itemLevel) const
4203{
4204 float ppm = ProcBasePPM;
4205 if (!caster)
4206 return ppm;
4207
4208 for (SpellProcsPerMinuteModEntry const* mod : ProcPPMMods)
4209 {
4210 switch (mod->Type)
4211 {
4213 {
4214 ppm *= 1.0f + CalcPPMHasteMod(mod, caster);
4215 break;
4216 }
4217 case SPELL_PPM_MOD_CRIT:
4218 {
4219 ppm *= 1.0f + CalcPPMCritMod(mod, caster);
4220 break;
4221 }
4223 {
4224 if (caster->GetClassMask() & mod->Param)
4225 ppm *= 1.0f + mod->Coeff;
4226 break;
4227 }
4228 case SPELL_PPM_MOD_SPEC:
4229 {
4230 if (Player* plrCaster = caster->ToPlayer())
4231 if (plrCaster->GetPrimarySpecialization() == ChrSpecialization(mod->Param))
4232 ppm *= 1.0f + mod->Coeff;
4233 break;
4234 }
4235 case SPELL_PPM_MOD_RACE:
4236 {
4237 if (caster->GetRaceMask() & mod->Param)
4238 ppm *= 1.0f + mod->Coeff;
4239 break;
4240 }
4242 {
4243 ppm *= 1.0f + CalcPPMItemLevelMod(mod, itemLevel);
4244 break;
4245 }
4247 {
4248 if (caster->GetMap()->IsBattlegroundOrArena())
4249 ppm *= 1.0f + mod->Coeff;
4250 break;
4251 }
4252 default:
4253 break;
4254 }
4255 }
4256
4257 return ppm;
4258}
4259
4261{
4262 return ChainEntry != nullptr;
4263}
4264
4266{
4267 if (!ChainEntry)
4268 return 1;
4269 return ChainEntry->rank;
4270}
4271
4273{
4274 if (!ChainEntry)
4275 return this;
4276 return ChainEntry->first;
4277}
4278
4280{
4281 if (!ChainEntry)
4282 return nullptr;
4283 return ChainEntry->last;
4284}
4285
4287{
4288 if (!ChainEntry)
4289 return nullptr;
4290 return ChainEntry->next;
4291}
4292
4294{
4295 if (!ChainEntry)
4296 return nullptr;
4297 return ChainEntry->prev;
4298}
4299
4301{
4302 // ignore passive spells
4303 if (IsPassive())
4304 return this;
4305
4306 // Client ignores spell with these attributes (sub_53D9D0)
4308 return this;
4309
4310 bool needRankSelection = false;
4311 for (SpellEffectInfo const& effect : GetEffects())
4312 {
4313 if (IsPositiveEffect(effect.EffectIndex) &&
4314 (effect.Effect == SPELL_EFFECT_APPLY_AURA ||
4315 effect.Effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
4316 effect.Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID) &&
4317 !effect.Scaling.Coefficient)
4318 {
4319 needRankSelection = true;
4320 break;
4321 }
4322 }
4323
4324 // not required
4325 if (!needRankSelection)
4326 return this;
4327
4328 for (SpellInfo const* nextSpellInfo = this; nextSpellInfo != nullptr; nextSpellInfo = nextSpellInfo->GetPrevRankSpell())
4329 {
4330 // if found appropriate level
4331 if (uint32(level + 10) >= nextSpellInfo->SpellLevel)
4332 return nextSpellInfo;
4333
4334 // one rank less then
4335 }
4336
4337 // not found
4338 return nullptr;
4339}
4340
4341bool SpellInfo::IsRankOf(SpellInfo const* spellInfo) const
4342{
4343 return GetFirstRankSpell() == spellInfo->GetFirstRankSpell();
4344}
4345
4346bool SpellInfo::IsDifferentRankOf(SpellInfo const* spellInfo) const
4347{
4348 if (Id == spellInfo->Id)
4349 return false;
4350 return IsRankOf(spellInfo);
4351}
4352
4353bool SpellInfo::IsHighRankOf(SpellInfo const* spellInfo) const
4354{
4355 if (ChainEntry && spellInfo->ChainEntry)
4356 if (ChainEntry->first == spellInfo->ChainEntry->first)
4357 if (ChainEntry->rank > spellInfo->ChainEntry->rank)
4358 return true;
4359
4360 return false;
4361}
4362
4363uint32 SpellInfo::GetSpellXSpellVisualId(WorldObject const* caster /*= nullptr*/, WorldObject const* viewer /*= nullptr*/) const
4364{
4365 for (SpellXSpellVisualEntry const* visual : _visuals)
4366 {
4367 if (PlayerConditionEntry const* playerCondition = sPlayerConditionStore.LookupEntry(visual->CasterPlayerConditionID))
4368 if (!caster || !caster->IsPlayer() || !ConditionMgr::IsPlayerMeetingCondition(caster->ToPlayer(), playerCondition))
4369 continue;
4370
4371 if (UnitConditionEntry const* unitCondition = sUnitConditionStore.LookupEntry(visual->CasterUnitConditionID))
4372 if (!caster || !caster->IsUnit() || !ConditionMgr::IsUnitMeetingCondition(caster->ToUnit(), Object::ToUnit(viewer), unitCondition))
4373 continue;
4374
4375 return visual->ID;
4376 }
4377
4378 return 0;
4379}
4380
4381uint32 SpellInfo::GetSpellVisual(WorldObject const* caster /*= nullptr*/, WorldObject const* viewer /*= nullptr*/) const
4382{
4383 if (SpellXSpellVisualEntry const* visual = sSpellXSpellVisualStore.LookupEntry(GetSpellXSpellVisualId(caster, viewer)))
4384 {
4385 //if (visual->LowViolenceSpellVisualID && forPlayer->GetViolenceLevel() operator 2)
4386 // return visual->LowViolenceSpellVisualID;
4387
4388 return visual->SpellVisualID;
4389 }
4390
4391 return 0;
4392}
4393
4395{
4396 bool srcSet = false;
4397 bool dstSet = false;
4398 uint32 targetMask = Targets;
4399 // prepare target mask using effect target entries
4400 for (SpellEffectInfo const& effect : GetEffects())
4401 {
4402 if (!effect.IsEffect())
4403 continue;
4404
4405 targetMask |= effect.TargetA.GetExplicitTargetMask(srcSet, dstSet);
4406 targetMask |= effect.TargetB.GetExplicitTargetMask(srcSet, dstSet);
4407
4408 // add explicit target flags based on spell effects which have EFFECT_IMPLICIT_TARGET_EXPLICIT and no valid target provided
4409 if (effect.GetImplicitTargetType() != EFFECT_IMPLICIT_TARGET_EXPLICIT)
4410 continue;
4411
4412 // extend explicit target mask only if valid targets for effect could not be provided by target types
4413 uint32 effectTargetMask = effect.GetMissingTargetMask(srcSet, dstSet, targetMask);
4414
4415 // don't add explicit object/dest flags when spell has no max range
4416 if (GetMaxRange(true) == 0.0f && GetMaxRange(false) == 0.0f)
4418
4419 targetMask |= effectTargetMask;
4420 }
4421
4422 ExplicitTargetMask = targetMask;
4423}
4424
4425inline bool _isPositiveTarget(SpellEffectInfo const& effect)
4426{
4427 if (!effect.IsEffect())
4428 return true;
4429
4430 return (effect.TargetA.GetCheckType() != TARGET_CHECK_ENEMY &&
4432}
4433
4434bool _isPositiveEffectImpl(SpellInfo const* spellInfo, SpellEffectInfo const& effect, std::unordered_set<std::pair<SpellInfo const*, SpellEffIndex>>& visited)
4435{
4436 if (!effect.IsEffect())
4437 return true;
4438
4439 // attribute may be already set in DB
4440 if (!spellInfo->IsPositiveEffect(effect.EffectIndex))
4441 return false;
4442
4443 // passive auras like talents are all positive
4444 if (spellInfo->IsPassive())
4445 return true;
4446
4447 // not found a single positive spell with this attribute
4449 return false;
4450
4451 if (spellInfo->HasAttribute(SPELL_ATTR4_AURA_IS_BUFF))
4452 return true;
4453
4455 return false;
4456
4457 visited.insert({ spellInfo, effect.EffectIndex });
4458
4459 //We need scaling level info for some auras that compute bp 0 or positive but should be debuffs
4460 float bpScalePerLevel = effect.RealPointsPerLevel;
4461 int32 bp = effect.CalcValue();
4462 switch (spellInfo->SpellFamilyName)
4463 {
4465 switch (spellInfo->Id)
4466 {
4467 case 40268: // Spiritual Vengeance, Teron Gorefiend, Black Temple
4468 case 61987: // Avenging Wrath Marker
4469 case 61988: // Divine Shield exclude aura
4470 case 64412: // Phase Punch, Algalon the Observer, Ulduar
4471 case 72410: // Rune of Blood, Saurfang, Icecrown Citadel
4472 case 71204: // Touch of Insignificance, Lady Deathwhisper, Icecrown Citadel
4473 return false;
4474 case 24732: // Bat Costume
4475 case 30877: // Tag Murloc
4476 case 61716: // Rabbit Costume
4477 case 61734: // Noblegarden Bunny
4478 case 62344: // Fists of Stone
4479 case 50344: // Dream Funnel
4480 case 61819: // Manabonked! (item)
4481 case 61834: // Manabonked! (minigob)
4482 case 73523: // Rigor Mortis
4483 return true;
4484 default:
4485 break;
4486 }
4487 break;
4488 case SPELLFAMILY_ROGUE:
4489 switch (spellInfo->Id)
4490 {
4491 // Envenom must be considered as a positive effect even though it deals damage
4492 case 32645: // Envenom
4493 return true;
4494 case 40251: // Shadow of Death, Teron Gorefiend, Black Temple
4495 return false;
4496 default:
4497 break;
4498 }
4499 break;
4501 // Slam, Execute
4502 if ((spellInfo->SpellFamilyFlags[0] & 0x20200000) != 0)
4503 return false;
4504 break;
4505 default:
4506 break;
4507 }
4508
4509 switch (spellInfo->Mechanic)
4510 {
4512 return true;
4513 default:
4514 break;
4515 }
4516
4517 // Special case: effects which determine positivity of whole spell
4518 if (spellInfo->HasAttribute(SPELL_ATTR1_AURA_UNIQUE))
4519 {
4520 // check for targets, there seems to be an assortment of dummy triggering spells that should be negative
4521 for (SpellEffectInfo const& otherEffect : spellInfo->GetEffects())
4522 if (!_isPositiveTarget(otherEffect))
4523 return false;
4524 }
4525
4526 for (SpellEffectInfo const& otherEffect : spellInfo->GetEffects())
4527 {
4528 switch (otherEffect.Effect)
4529 {
4530 case SPELL_EFFECT_HEAL:
4534 return true;
4536 if (otherEffect.EffectIndex != effect.EffectIndex && // for spells like 38044: instakill effect is negative but auras on target must count as buff
4537 otherEffect.TargetA.GetTarget() == effect.TargetA.GetTarget() &&
4538 otherEffect.TargetB.GetTarget() == effect.TargetB.GetTarget())
4539 return false;
4540 break;
4541 default:
4542 break;
4543 }
4544
4545 if (otherEffect.IsAura())
4546 {
4547 switch (otherEffect.ApplyAuraName)
4548 {
4551 return true;
4553 case SPELL_AURA_EMPATHY:
4556 return false;
4557 default:
4558 break;
4559 }
4560 }
4561 }
4562
4563 switch (effect.Effect)
4564 {
4583 return false;
4589 return true;
4595 // check targets
4596 if (!_isPositiveTarget(effect))
4597 return false;
4598 break;
4600 // non-positive dispel
4601 switch (effect.MiscValue)
4602 {
4603 case DISPEL_STEALTH:
4605 case DISPEL_ENRAGE:
4606 return false;
4607 default:
4608 break;
4609 }
4610
4611 // also check targets
4612 if (!_isPositiveTarget(effect))
4613 return false;
4614 break;
4616 if (!_isPositiveTarget(effect))
4617 {
4618 // non-positive mechanic dispel on negative target
4619 switch (effect.MiscValue)
4620 {
4621 case MECHANIC_BANDAGE:
4622 case MECHANIC_SHIELD:
4623 case MECHANIC_MOUNT:
4625 return false;
4626 default:
4627 break;
4628 }
4629 }
4630 break;
4633 // check targets AND basepoints
4634 if (!_isPositiveTarget(effect) && bp > 0)
4635 return false;
4636 break;
4637 default:
4638 break;
4639 }
4640
4641 if (effect.IsAura())
4642 {
4643 // non-positive aura use
4644 switch (effect.ApplyAuraName)
4645 {
4646 case SPELL_AURA_MOD_STAT: // dependent from basepoint sign (negative -> negative)
4670 if (bp < 0 || bpScalePerLevel < 0) //TODO: What if both are 0? Should it be a buff or debuff?
4671 return false;
4672 break;
4673 case SPELL_AURA_MOD_ATTACKSPEED: // some buffs have negative bp, check both target and bp
4687 if (!_isPositiveTarget(effect) || bp < 0)
4688 return false;
4689 break;
4690 case SPELL_AURA_MOD_DAMAGE_TAKEN: // dependent from basepoint sign (positive -> negative)
4696 if (bp > 0)
4697 return false;
4698 break;
4699 case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN: // check targets and basepoints (ex Recklessness)
4700 if (!_isPositiveTarget(effect) && bp > 0)
4701 return false;
4702 break;
4703 case SPELL_AURA_MOD_HEALTH_REGEN_PERCENT: // check targets and basepoints (target enemy and negative bp -> negative)
4704 if (!_isPositiveTarget(effect) && bp < 0)
4705 return false;
4706 break;
4708 return true;
4711 if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(effect.TriggerSpell, spellInfo->Difficulty))
4712 {
4713 // negative targets of main spell return early
4714 for (SpellEffectInfo const& spellTriggeredEffect : spellTriggeredProto->GetEffects())
4715 {
4716 // already seen this
4717 if (visited.count({ spellTriggeredProto, spellTriggeredEffect.EffectIndex }) > 0)
4718 continue;
4719
4720 if (!spellTriggeredEffect.IsEffect())
4721 continue;
4722
4723 // if non-positive trigger cast targeted to positive target this main cast is non-positive
4724 // this will place this spell auras as debuffs
4725 if (_isPositiveTarget(spellTriggeredEffect) && !_isPositiveEffectImpl(spellTriggeredProto, spellTriggeredEffect, visited))
4726 return false;
4727 }
4728 }
4729 break;
4736 // special auras: they may have non negative target but still need to be marked as debuff
4737 // checked again after all effects (SpellInfo::_InitializeSpellPositivity)
4754 case SPELL_AURA_DUMMY:
4770 // check target for positive and negative spells
4771 if (!_isPositiveTarget(effect))
4772 return false;
4773 break;
4780 case SPELL_AURA_GHOST:
4790 return false;
4792 {
4793 // non-positive immunities
4794 switch (effect.MiscValue)
4795 {
4796 case MECHANIC_BANDAGE:
4797 case MECHANIC_SHIELD:
4798 case MECHANIC_MOUNT:
4800 return false;
4801 default:
4802 break;
4803 }
4804 break;
4805 }
4806 case SPELL_AURA_ADD_FLAT_MODIFIER: // mods
4810 {
4811 switch (SpellModOp(effect.MiscValue))
4812 {
4813 case SpellModOp::ChangeCastTime: // dependent from basepoint sign (positive -> negative)
4814 case SpellModOp::Period:
4817 if (bp > 0)
4818 return false;
4819 break;
4824 if (!spellInfo->IsPositive() && bp > 0) // dependent on prev effects too (ex Arcane Power)
4825 return false;
4826 break;
4827 case SpellModOp::PointsIndex0: // always positive
4832 case SpellModOp::Points:
4833 case SpellModOp::Hate:
4836 return true;
4841 if (!spellInfo->IsPositive() && bp < 0) // dependent on prev effects too
4842 return false;
4843 break;
4844 default: // dependent from basepoint sign (negative -> negative)
4845 if (bp < 0)
4846 return false;
4847 break;
4848 }
4849 break;
4850 }
4851 default:
4852 break;
4853 }
4854 }
4855
4856 // negative spell if triggered spell is negative
4857 if (!effect.ApplyAuraName && effect.TriggerSpell)
4858 {
4859 if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(effect.TriggerSpell, spellInfo->Difficulty))
4860 {
4861 // spells with at least one negative effect are considered negative
4862 // some self-applied spells have negative effects but in self casting case negative check ignored.
4863 for (SpellEffectInfo const& spellTriggeredEffect : spellTriggeredProto->GetEffects())
4864 {
4865 // already seen this
4866 if (visited.count({ spellTriggeredProto, spellTriggeredEffect.EffectIndex }) > 0)
4867 continue;
4868
4869 if (!spellTriggeredEffect.IsEffect())
4870 continue;
4871
4872 if (!_isPositiveEffectImpl(spellTriggeredProto, spellTriggeredEffect, visited))
4873 return false;
4874 }
4875 }
4876 }
4877
4878 // ok, positive
4879 return true;
4880}
4881
4883{
4884 std::unordered_set<std::pair<SpellInfo const*, SpellEffIndex /*effIndex*/>> visited;
4885
4886 for (SpellEffectInfo const& effect : GetEffects())
4887 if (!_isPositiveEffectImpl(this, effect, visited))
4888 NegativeEffects[effect.EffectIndex] = true;
4889
4890 // additional checks after effects marked
4891 for (SpellEffectInfo const& effect : GetEffects())
4892 {
4893 if (!effect.IsEffect() || !IsPositiveEffect(effect.EffectIndex))
4894 continue;
4895
4896 switch (effect.ApplyAuraName)
4897 {
4898 // has other non positive effect?
4899 // then it should be marked negative if has same target as negative effect (ex 8510, 8511, 8893, 10267)
4900 case SPELL_AURA_DUMMY:
4907 {
4908 for (size_t j = effect.EffectIndex + 1; j < GetEffects().size(); ++j)
4909 if (!IsPositiveEffect(j)
4910 && effect.TargetA.GetTarget() == GetEffect(SpellEffIndex(j)).TargetA.GetTarget()
4911 && effect.TargetB.GetTarget() == GetEffect(SpellEffIndex(j)).TargetB.GetTarget())
4912 NegativeEffects[effect.EffectIndex] = true;
4913 break;
4914 }
4915 default:
4916 break;
4917 }
4918 }
4919}
4920
4922{
4923 // find the same instances of ConditionList and delete them.
4924 for (SpellEffectInfo& effect : _effects)
4925 effect.ImplicitTargetConditions = nullptr;
4926}
4927
4929{
4931 return false;
4932
4934 return !playerCondition || ConditionMgr::IsPlayerMeetingCondition(player, playerCondition);
4935}
4936
4937bool SpellInfo::HasLabel(uint32 labelId) const
4938{
4939 return Labels.find(labelId) != Labels.end();
4940}
@ STATUS_WAIT_JOIN
Definition: Battleground.h:166
@ IN_MILLISECONDS
Definition: Common.h:35
#define M_PI
Definition: Common.h:115
@ CORPSE_BONES
Definition: Corpse.h:31
DB2Storage< RandPropPointsEntry > sRandPropPointsStore("RandPropPoints.db2", &RandPropPointsLoadInfo::Instance)
DB2Storage< SpellCategoryEntry > sSpellCategoryStore("SpellCategory.db2", &SpellCategoryLoadInfo::Instance)
DB2Storage< MapEntry > sMapStore("Map.db2", &MapLoadInfo::Instance)
DB2Storage< SpellXSpellVisualEntry > sSpellXSpellVisualStore("SpellXSpellVisual.db2", &SpellXSpellVisualLoadInfo::Instance)
DB2Storage< SpellRangeEntry > sSpellRangeStore("SpellRange.db2", &SpellRangeLoadInfo::Instance)
DB2Storage< SpellShapeshiftFormEntry > sSpellShapeshiftFormStore("SpellShapeshiftForm.db2", &SpellShapeshiftFormLoadInfo::Instance)
DB2Storage< SpellDurationEntry > sSpellDurationStore("SpellDuration.db2", &SpellDurationLoadInfo::Instance)
DB2Storage< UnitConditionEntry > sUnitConditionStore("UnitCondition.db2", &UnitConditionLoadInfo::Instance)
DB2Storage< SummonPropertiesEntry > sSummonPropertiesStore("SummonProperties.db2", &SummonPropertiesLoadInfo::Instance)
DB2Storage< SpellRadiusEntry > sSpellRadiusStore("SpellRadius.db2", &SpellRadiusLoadInfo::Instance)
DB2Storage< PlayerConditionEntry > sPlayerConditionStore("PlayerCondition.db2", &PlayerConditionLoadInfo::Instance)
DB2Storage< ContentTuningEntry > sContentTuningStore("ContentTuning.db2", &ContentTuningLoadInfo::Instance)
DB2Storage< ItemSparseEntry > sItemSparseStore("ItemSparse.db2", &ItemSparseLoadInfo::Instance)
DB2Storage< AreaTableEntry > sAreaTableStore("AreaTable.db2", &AreaTableLoadInfo::Instance)
DB2Storage< SpellProcsPerMinuteEntry > sSpellProcsPerMinuteStore("SpellProcsPerMinute.db2", &SpellProcsPerMinuteLoadInfo::Instance)
DB2Storage< SpellCastTimesEntry > sSpellCastTimesStore("SpellCastTimes.db2", &SpellCastTimesLoadInfo::Instance)
#define sDB2Manager
Definition: DB2Stores.h:538
@ VEHICLE_SEAT_FLAG_UNK2
Definition: DBCEnums.h:2447
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition: DBCEnums.h:2429
@ VEHICLE_SEAT_FLAG_CAN_CONTROL
Definition: DBCEnums.h:2428
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition: DBCEnums.h:2430
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition: DBCEnums.h:2431
SpellEffectAttributes
Definition: DBCEnums.h:1925
AreaMountFlags
Definition: DBCEnums.h:169
Difficulty
Definition: DBCEnums.h:873
constexpr std::size_t MAX_POWERS_PER_SPELL
Definition: DBCEnums.h:1985
@ SPELL_CATEGORY_FLAG_COOLDOWN_STARTS_ON_EVENT
Definition: DBCEnums.h:1920
ChrSpecialization
Definition: DBCEnums.h:357
ExpectedStatType
Definition: DBCEnums.h:927
@ SPELL_PPM_MOD_CRIT
Definition: DBCEnums.h:1977
@ SPELL_PPM_MOD_ITEM_LEVEL
Definition: DBCEnums.h:1981
@ SPELL_PPM_MOD_CLASS
Definition: DBCEnums.h:1978
@ SPELL_PPM_MOD_SPEC
Definition: DBCEnums.h:1979
@ SPELL_PPM_MOD_RACE
Definition: DBCEnums.h:1980
@ SPELL_PPM_MOD_HASTE
Definition: DBCEnums.h:1976
@ SPELL_PPM_MOD_BATTLEGROUND
Definition: DBCEnums.h:1982
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint64_t uint64
Definition: Define.h:141
#define UI64LIT(N)
Definition: Define.h:127
uint16_t uint16
Definition: Define.h:143
uint32_t uint32
Definition: Define.h:142
#define ASSERT
Definition: Errors.h:68
GameTable< GtSpellScalingEntry > sSpellScalingGameTable
Definition: GameTables.cpp:38
GameTable< GtStaminaMultByILvl > sStaminaMultByILvlGameTable
Definition: GameTables.cpp:39
float GetIlvlStatMultiplier(T const *row, InventoryType invType)
Definition: GameTables.cpp:149
GameTable< GtNpcManaCostScalerEntry > sNpcManaCostScalerGameTable
Definition: GameTables.cpp:37
GameTable< GtCombatRatingsMultByILvl > sCombatRatingsMultByILvlGameTable
Definition: GameTables.cpp:34
float GetSpellScalingColumnForClass(GtSpellScalingEntry const *row, int32 class_)
Definition: GameTables.h:246
TC_GAME_API float GetRandomPropertyPoints(uint32 itemLevel, uint32 quality, uint32 inventoryType, uint32 subClass)
#define ITEM_SUBCLASS_MASK_WEAPON_RANGED
Definition: ItemTemplate.h:503
InventoryType
Definition: ItemTemplate.h:378
@ INVTYPE_CHEST
Definition: ItemTemplate.h:384
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:165
LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template", "creature pickpocket lootid", true)
uint64 MAKE_PAIR64(uint32 l, uint32 h)
Definition: ObjectDefines.h:87
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:25
@ SPELLMOD_LABEL_PCT
Definition: Player.h:160
@ SPELLMOD_FLAT
Definition: Player.h:157
@ SPELLMOD_PCT
Definition: Player.h:158
@ SPELLMOD_LABEL_FLAT
Definition: Player.h:159
float frand(float min, float max)
Definition: Random.cpp:55
float rand_norm()
Definition: Random.cpp:75
if(posix_memalign(&__mallocedMemory, __align, __size)) return NULL
@ SPELL_ATTR11_SCALES_WITH_ITEM_LEVEL
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_1
Definition: SharedDefines.h:31
@ EFFECT_0
Definition: SharedDefines.h:30
@ SPELL_ATTR10_USE_SPELL_BASE_LEVEL_FOR_SCALING
@ SPELL_ATTR9_AIMED_SHOT
@ SPELL_ATTR7_BYPASS_NO_RESURRECT_AURA
@ SPELL_ATTR7_NO_UI_NOT_INTERRUPTIBLE
#define DISPEL_ALL_MASK
@ CLASS_NONE
@ SPELL_PREVENTION_TYPE_SILENCE
@ SPELL_ATTR5_EXTRA_INITIAL_PERIOD
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
@ SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC
@ SPELL_ATTR5_ALLOW_WHILE_FLEEING
@ SPELL_ATTR5_NOT_ON_PLAYER
@ SPELL_ATTR5_LIMIT_N
@ SPELL_ATTR5_ALLOW_WHILE_CONFUSED
SpellTargetIndex
Definition: SharedDefines.h:65
Targets
@ TARGET_DEST_CASTER_RANDOM
@ TARGET_DEST_DEST_RANDOM
@ TARGET_DEST_TARGET_RANDOM
@ TARGET_DEST_TRAJ
@ TOTAL_SPELL_TARGETS
@ TARGET_DEST_CASTER
@ TARGET_UNIT_CASTER
SpellSchoolMask
@ SPELL_SCHOOL_MASK_NORMAL
@ SPELL_SCHOOL_MASK_FROST
@ SPELL_ATTR2_AUTO_REPEAT
@ SPELL_ATTR2_ALLOW_WHILE_NOT_SHAPESHIFTED_CASTER_FORM
@ SPELL_ATTR2_NO_INITIAL_THREAT
@ SPELL_ATTR2_CANNOT_CAST_ON_TAPPED
@ SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF
@ SPELL_ATTR2_ALLOW_DEAD_TARGET
@ SPELL_ATTR2_NO_SCHOOL_IMMUNITIES
SpellAttr1
@ SPELL_ATTR1_NO_THREAT
@ SPELL_ATTR1_IS_SELF_CHANNELLED
@ SPELL_ATTR1_EXCLUDE_CASTER
@ SPELL_ATTR1_USE_ALL_MANA
@ SPELL_ATTR1_IS_CHANNELLED
@ SPELL_ATTR1_AURA_UNIQUE
@ SPELL_ATTR1_NO_AUTOCAST_AI
@ SPELL_ATTR1_IMMUNITY_PURGES_EFFECT
@ SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS
@ SPELL_ATTR1_ONLY_PEACEFUL_TARGETS
@ SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD
@ SPELL_ATTR3_ONLY_PROC_ON_CASTER
@ SPELL_ATTR3_ONLY_ON_GHOSTS
@ SPELL_ATTR3_NOT_ON_AOE_IMMUNE
@ SPELL_ATTR3_ALWAYS_HIT
@ SPELL_ATTR3_DOT_STACKING_RULE
@ SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON
@ SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON
@ SPELL_ATTR3_IGNORE_CASTER_MODIFIERS
@ SPELL_ATTR3_ONLY_ON_PLAYER
@ ITEM_QUALITY_RARE
@ SPELL_DAMAGE_CLASS_RANGED
@ SPELL_DAMAGE_CLASS_MELEE
SpellEffectName
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_POWER_BURN
@ SPELL_EFFECT_ENERGIZE_PCT
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
@ SPELL_EFFECT_APPLY_AREA_AURA_FRIEND
@ SPELL_EFFECT_SELF_RESURRECT
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY_NONRANDOM
@ SPELL_EFFECT_DISTRACT
@ SPELL_EFFECT_DURABILITY_DAMAGE
@ SPELL_EFFECT_CREATE_LOOT
@ SPELL_EFFECT_HEALTH_LEECH
@ SPELL_EFFECT_SKILL
@ SPELL_EFFECT_WEAPON_DAMAGE
@ SPELL_EFFECT_HEAL
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
@ SPELL_EFFECT_APPLY_AURA_ON_PET
@ SPELL_EFFECT_DAMAGE_FROM_MAX_HEALTH_PCT
@ SPELL_EFFECT_DISPEL_MECHANIC
@ SPELL_EFFECT_HEAL_MAX_HEALTH
@ SPELL_EFFECT_APPLY_AREA_AURA_PET
@ SPELL_EFFECT_DISPEL
@ SPELL_EFFECT_NONE
@ SPELL_EFFECT_TAMECREATURE
@ SPELL_EFFECT_ATTACK_ME
@ SPELL_EFFECT_PICKPOCKET
@ SPELL_EFFECT_HEAL_MECHANICAL
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
@ SPELL_EFFECT_MODIFY_THREAT_PERCENT
@ SPELL_EFFECT_DURABILITY_DAMAGE_PCT
@ SPELL_EFFECT_ENVIRONMENTAL_DAMAGE
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
@ SPELL_EFFECT_PERSISTENT_AREA_AURA
@ SPELL_EFFECT_SUMMON
@ SPELL_EFFECT_ENERGIZE
@ SPELL_EFFECT_POWER_DRAIN
@ SPELL_EFFECT_RESURRECT
@ SPELL_EFFECT_CHARGE
@ SPELL_EFFECT_KNOCK_BACK
@ SPELL_EFFECT_SCHOOL_DAMAGE
@ SPELL_EFFECT_GAMEOBJECT_DAMAGE
@ SPELL_EFFECT_LEARN_SPELL
@ SPELL_EFFECT_CREATE_RANDOM_ITEM
@ SPELL_EFFECT_INSTAKILL
@ SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
@ SPELL_EFFECT_HEAL_PCT
@ SPELL_EFFECT_INTERRUPT_CAST
@ SPELL_EFFECT_APPLY_AREA_AURA_SUMMONS
@ SPELL_EFFECT_THREAT
@ SPELL_EFFECT_SKILL_STEP
@ SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
@ SPELL_EFFECT_APPLY_AURA
@ SPELL_EFFECT_APPLY_AREA_AURA_OWNER
WeaponAttackType
@ OFF_ATTACK
@ BASE_ATTACK
@ RANGED_ATTACK
Mechanics
@ MECHANIC_DISARM
@ MECHANIC_NONE
@ MECHANIC_MOUNT
@ MECHANIC_FEAR
@ MECHANIC_INVULNERABILITY
@ MECHANIC_DISORIENTED
@ MECHANIC_KNOCKOUT
@ MECHANIC_STUN
@ MECHANIC_FREEZE
@ MECHANIC_INTERRUPT
@ MECHANIC_ROOT
@ MECHANIC_BANDAGE
@ MECHANIC_SLEEP
@ MECHANIC_BLEED
@ MECHANIC_BANISH
@ MAX_MECHANIC
@ MECHANIC_IMMUNE_SHIELD
@ MECHANIC_SNARE
@ MECHANIC_SILENCE
@ MECHANIC_SHIELD
@ MECHANIC_HORROR
@ IMMUNITY_STATE
@ IMMUNITY_EFFECT
@ IMMUNITY_DAMAGE
@ IMMUNITY_MECHANIC
@ IMMUNITY_SCHOOL
@ IMMUNITY_OTHER
@ IMMUNITY_DISPEL
Powers
@ MAX_POWERS
@ POWER_ALTERNATE_POWER
@ POWER_HEALTH
@ POWER_COMBO_POINTS
@ POWER_MANA
SpellAttr0
@ SPELL_ATTR0_ON_NEXT_SWING
@ SPELL_ATTR0_NOT_SHAPESHIFTED
@ SPELL_ATTR0_AURA_IS_DEBUFF
@ SPELL_ATTR0_ALLOW_WHILE_MOUNTED
@ SPELL_ATTR0_PASSIVE
@ SPELL_ATTR0_COOLDOWN_ON_EVENT
@ SPELL_ATTR0_NO_IMMUNITIES
@ SPELL_ATTR0_SCALES_WITH_CREATURE_LEVEL
@ SPELL_ATTR0_NOT_IN_COMBAT_ONLY_PEACEFUL
@ SPELL_ATTR0_USES_RANGED_SLOT
@ SPELL_ATTR0_ON_NEXT_SWING_NO_DAMAGE
DiminishingLevels
@ DIMINISHING_LEVEL_IMMUNE
@ DIMINISHING_LEVEL_TAUNT_IMMUNE
@ DIMINISHING_LEVEL_2
DiminishingGroup
@ DIMINISHING_AOE_KNOCKBACK
@ DIMINISHING_NONE
@ DIMINISHING_STUN
@ DIMINISHING_LIMITONLY
@ DIMINISHING_DISORIENT
@ DIMINISHING_ROOT
@ DIMINISHING_TAUNT
@ DIMINISHING_SILENCE
@ DIMINISHING_INCAPACITATE
TotemCategory
SpellCastResult
@ SPELL_FAILED_TARGET_NOT_PLAYER
@ SPELL_FAILED_NOT_HERE
@ SPELL_FAILED_TARGET_NO_POCKETS
@ SPELL_FAILED_INCORRECT_AREA
@ SPELL_FAILED_TARGET_IS_PLAYER
@ SPELL_FAILED_NOT_IN_BATTLEGROUND
@ SPELL_FAILED_TARGET_NOT_IN_INSTANCE
@ SPELL_FAILED_CANT_CAST_ON_TAPPED
@ SPELL_FAILED_TARGET_AURASTATE
@ SPELL_FAILED_NOT_IN_RAID_INSTANCE
@ SPELL_FAILED_BM_OR_INVISGOD
@ SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW
@ SPELL_FAILED_ONLY_SHAPESHIFT
@ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED
@ SPELL_FAILED_TARGETS_DEAD
@ SPELL_FAILED_TARGET_NOT_GHOST
@ SPELL_FAILED_BAD_TARGETS
@ SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED
@ SPELL_FAILED_NOT_SHAPESHIFT
@ SPELL_FAILED_TARGET_NO_WEAPONS
@ SPELL_CAST_OK
@ SPELL_FAILED_REQUIRES_AREA
@ SPELL_FAILED_TARGET_AFFECTING_COMBAT
AuraStateType
@ AURA_STATE_NONE
@ AURA_STATE_BLEED
@ AURA_STATE_FROZEN
@ AURA_STATE_VICTORIOUS
@ AURA_STATE_FAERIE_FIRE
@ AURA_STATE_ENRAGED
@ AURA_STATE_DAZED
@ AURA_STATE_DRUID_PERIODIC_HEAL
@ AURA_STATE_RAID_ENCOUNTER
@ AURA_STATE_ROGUE_POISONED
DiminishingReturnsType
@ DRTYPE_NONE
@ DRTYPE_PLAYER
@ DRTYPE_ALL
@ SPELLFAMILY_PRIEST
@ SPELLFAMILY_WARLOCK_PET
@ SPELLFAMILY_WARLOCK
@ SPELLFAMILY_MAGE
@ SPELLFAMILY_GENERIC
@ SPELLFAMILY_WARRIOR
@ SPELLFAMILY_PALADIN
@ SPELLFAMILY_HUNTER
@ SPELLFAMILY_DEMON_HUNTER
@ SPELLFAMILY_ROGUE
@ SPELLFAMILY_SHAMAN
@ SPELLFAMILY_DRUID
@ SPELLFAMILY_DEATHKNIGHT
@ SPELLFAMILY_MONK
@ AREA_WINTERGRASP
DispelType
@ DISPEL_ALL
@ DISPEL_ENRAGE
@ DISPEL_MAX
@ DISPEL_NONE
@ DISPEL_POISON
@ DISPEL_INVISIBILITY
@ DISPEL_STEALTH
@ DISPEL_CURSE
@ SPELL_ATTR4_ONLY_FLYING_AREAS
@ SPELL_ATTR4_NO_HARMFUL_THREAT
@ SPELL_ATTR4_AURA_IS_BUFF
@ SPELL_ATTR4_WEAPON_SPEED_COST_SCALING
@ SUMMON_CATEGORY_WILD
@ SPELL_ATTR8_ENFORCE_IN_COMBAT_RESSURECTION_LIMIT
@ SPELL_ATTR8_USE_TARGETS_LEVEL_FOR_SPELL_SCALING
@ SPELL_ATTR8_ONLY_TARGET_IF_SAME_CREATOR
@ SPELL_ATTR8_ONLY_TARGET_OWN_SUMMONS
@ SPELL_ATTR8_NOT_IN_BATTLEGROUND
@ SPELL_ATTR8_REMOVE_OUTSIDE_DUNGEONS_AND_RAIDS
constexpr uint64 IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK((1<< MECHANIC_CHARM)|(1<< MECHANIC_DISORIENTED)|(1<< MECHANIC_FEAR)|(1<< MECHANIC_ROOT)|(1<< MECHANIC_SLEEP)|(1<< MECHANIC_SNARE)|(1<< MECHANIC_STUN)|(1<< MECHANIC_FREEZE)|(1<< MECHANIC_SILENCE)|(1<< MECHANIC_DISARM)|(1<< MECHANIC_KNOCKOUT)|(1<< MECHANIC_POLYMORPH)|(1<< MECHANIC_BANISH)|(1<< MECHANIC_SHACKLE)|(1<< MECHANIC_TURN)|(1<< MECHANIC_HORROR)|(1<< MECHANIC_DAZE)|(1<< MECHANIC_SAPPED))
@ SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE
@ SPELL_ATTR6_DO_NOT_CHAIN_TO_CROWD_CONTROLLED_TARGETS
@ SPELL_ATTR6_IGNORE_PHASE_SHIFT
@ SPELL_ATTR6_NOT_IN_RAID_INSTANCES
@ AURA_REMOVE_BY_DEFAULT
AuraType
@ SPELL_AURA_PREVENT_RESURRECTION
@ SPELL_AURA_MOD_RECOVERY_RATE_BY_SPELL_LABEL
@ SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS
@ SPELL_AURA_MANA_SHIELD
@ SPELL_AURA_MOD_MAX_HEALTH
@ SPELL_AURA_DISPEL_IMMUNITY
@ SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE
@ SPELL_AURA_MOD_ATTACKSPEED
@ SPELL_AURA_MOD_ATTACK_POWER
@ SPELL_AURA_CHANNEL_DEATH_ITEM
@ SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE
@ SPELL_AURA_MOD_DISARM_RANGED
@ SPELL_AURA_PERIODIC_WEAPON_PERCENT_DAMAGE
@ SPELL_AURA_MOD_SKILL
@ SPELL_AURA_PERIODIC_DAMAGE
@ SPELL_AURA_TRACK_RESOURCES
@ SPELL_AURA_MOD_PARRY_PERCENT
@ SPELL_AURA_MOD_MAX_POWER
@ SPELL_AURA_MOD_SHAPESHIFT
@ SPELL_AURA_MOD_DISARM
@ SPELL_AURA_MOD_SPELL_HIT_CHANCE
@ SPELL_AURA_DAMAGE_SHIELD
@ SPELL_AURA_OBS_MOD_HEALTH
@ SPELL_AURA_MOD_THREAT
@ SPELL_AURA_PERIODIC_HEALTH_FUNNEL
@ SPELL_AURA_MELEE_SLOW
@ SPELL_AURA_ADD_PCT_MODIFIER
@ SPELL_AURA_PERIODIC_MANA_LEECH
@ SPELL_AURA_MOD_POSSESS_PET
@ SPELL_AURA_MOD_INCREASE_SPEED
@ SPELL_AURA_MOD_RESISTANCE
@ SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS
@ SPELL_AURA_MOD_BONUS_ARMOR
@ SPELL_AURA_PROC_TRIGGER_SPELL
@ SPELL_AURA_HASTE_SPELLS
@ SPELL_AURA_MOD_INCREASE_HEALTH
@ SPELL_AURA_MOD_FEAR
@ SPELL_AURA_MOD_POWER_REGEN
@ SPELL_AURA_MOD_HEALING_DONE_PERCENT
@ SPELL_AURA_PREVENT_INTERRUPT
@ SPELL_AURA_PREVENTS_FLEEING
@ SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS
@ SPELL_AURA_OBS_MOD_POWER
@ SPELL_AURA_ADD_FLAT_MODIFIER
@ SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE
@ SPELL_AURA_TRACK_STEALTHED
@ SPELL_AURA_MOD_MELEE_HASTE
@ SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS
@ SPELL_AURA_EMPATHY
@ SPELL_AURA_MOD_INCREASE_ENERGY
@ SPELL_AURA_MOD_STALKED
@ SPELL_AURA_SCHOOL_HEAL_ABSORB
@ SPELL_AURA_MOD_ROOT_2
@ SPELL_AURA_MOD_SPELL_CRIT_CHANCE
@ SPELL_AURA_MOD_RATING
@ SPELL_AURA_MOD_HIT_CHANCE
@ SPELL_AURA_PERIODIC_HEAL
@ SPELL_AURA_MOD_HEALTH_REGEN_PERCENT
@ SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE
@ SPELL_AURA_PERIODIC_DAMAGE_PERCENT
@ SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT
@ SPELL_AURA_DUMMY
@ SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN
@ SPELL_AURA_MOD_INCREASE_HEALTH_2
@ SPELL_AURA_MOD_DODGE_PERCENT
@ SPELL_AURA_MOD_INCREASE_SWIM_SPEED
@ SPELL_AURA_MOD_PACIFY
@ SPELL_AURA_MOD_SILENCE
@ SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT
@ SPELL_AURA_MOD_DISARM_OFFHAND
@ SPELL_AURA_ADD_TARGET_TRIGGER
@ SPELL_AURA_ALLOW_INTERRUPT_SPELL
@ SPELL_AURA_MOD_DETAUNT
@ SPELL_AURA_MOD_STAT
@ SPELL_AURA_MOD_HEALING_DONE
@ SPELL_AURA_MOD_RANGED_ATTACK_POWER
@ SPELL_AURA_MOD_HEALING_PCT
@ SPELL_AURA_ADD_FLAT_MODIFIER_BY_SPELL_LABEL
@ SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
@ SPELL_AURA_GHOST
@ SPELL_AURA_MOD_CHARM
@ SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE
@ SPELL_AURA_ALLOW_MOUNT_IN_COMBAT
@ SPELL_AURA_MOD_ROOT
@ SPELL_AURA_MOD_RANGED_HASTE
@ SPELL_AURA_SCHOOL_IMMUNITY
@ SPELL_AURA_MOUNTED
@ SPELL_AURA_MOUNT_RESTRICTIONS
@ SPELL_AURA_MOD_POWER_COST_SCHOOL
@ SPELL_AURA_MECHANIC_IMMUNITY
@ SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE
@ SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN
@ SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT
@ SPELL_AURA_MOD_DAMAGE_TAKEN
@ SPELL_AURA_MOD_TAUNT
@ SPELL_AURA_MOD_CRIT_PCT
@ SPELL_AURA_MOD_SPELL_DAMAGE_FROM_CASTER
@ SPELL_AURA_MOD_CHARGE_COOLDOWN
@ SPELL_AURA_MOD_PACIFY_SILENCE
@ SPELL_AURA_MOD_COOLDOWN
@ SPELL_AURA_AOE_CHARM
@ SPELL_AURA_MOD_SPEED_SLOW_ALL
@ SPELL_AURA_MOD_TARGET_RESISTANCE
@ SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS
@ SPELL_AURA_MOD_SPEED_ALWAYS
@ SPELL_AURA_EFFECT_IMMUNITY
@ SPELL_AURA_MOD_DECREASE_SPEED
@ SPELL_AURA_TRANSFORM
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE
@ SPELL_AURA_SCHOOL_ABSORB
@ SPELL_AURA_MOD_RESISTANCE_PCT
@ SPELL_AURA_PERIODIC_ENERGIZE
@ SPELL_AURA_MOD_BASE_RESISTANCE
@ SPELL_AURA_MOD_WEAPON_CRIT_PERCENT
@ SPELL_AURA_MOD_DAMAGE_DONE_CREATURE
@ SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL
@ SPELL_AURA_MOD_ADDITIONAL_POWER_COST
@ SPELL_AURA_PERIODIC_LEECH
@ SPELL_AURA_MOD_SKILL_2
@ SPELL_AURA_MOD_LANGUAGE
@ SPELL_AURA_IGNORE_SPELL_CREATURE_TYPE_REQUIREMENTS
@ SPELL_AURA_PROC_TRIGGER_DAMAGE
@ SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE
@ SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT
@ SPELL_AURA_DAMAGE_IMMUNITY
@ SPELL_AURA_POWER_BURN
@ SPELL_AURA_MOD_PERCENT_STAT
@ SPELL_AURA_MOD_HEALING
@ SPELL_AURA_MOD_DAMAGE_DONE
@ SPELL_AURA_MOD_CONFUSE
@ SPELL_AURA_TRACK_CREATURES
@ SPELL_AURA_MOD_POSSESS
@ SPELL_AURA_PERIODIC_DUMMY
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT
@ SPELL_AURA_STATE_IMMUNITY
@ SPELL_AURA_MOD_UNATTACKABLE
@ SPELL_AURA_ADD_PCT_MODIFIER_BY_SPELL_LABEL
@ SPELL_AURA_MOD_STEALTH
@ SPELL_AURA_MOD_DETECT_RANGE
@ SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
@ SPELL_AURA_MOD_MELEE_RANGED_HASTE
@ SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK
@ SPELL_AURA_MOD_REGEN
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
@ SPELL_AURA_MOD_ATTACK_POWER_PCT
@ SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
@ SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT
@ SPELL_AURA_MECHANIC_IMMUNITY_MASK
@ SPELL_AURA_SET_VEHICLE_ID
@ SPELL_AURA_MOD_STUN
SpellInterruptFlags
Definition: SpellDefines.h:58
SpellAuraInterruptFlags2
Definition: SpellDefines.h:117
SpellModOp
Definition: SpellDefines.h:149
@ TARGET_FLAG_GAMEOBJECT
Definition: SpellDefines.h:291
@ TARGET_FLAG_NONE
Definition: SpellDefines.h:279
@ TARGET_FLAG_UNIT_RAID
Definition: SpellDefines.h:282
@ TARGET_FLAG_UNIT_ENEMY
Definition: SpellDefines.h:287
@ TARGET_FLAG_CORPSE_ALLY
Definition: SpellDefines.h:295
@ TARGET_FLAG_ITEM
Definition: SpellDefines.h:284
@ TARGET_FLAG_UNIT_MINIPET
Definition: SpellDefines.h:296
@ TARGET_FLAG_UNIT_PASSENGER
Definition: SpellDefines.h:300
@ TARGET_FLAG_GAMEOBJECT_ITEM
Definition: SpellDefines.h:294
@ TARGET_FLAG_DEST_LOCATION
Definition: SpellDefines.h:286
@ TARGET_FLAG_UNIT_ALLY
Definition: SpellDefines.h:288
@ TARGET_FLAG_SOURCE_LOCATION
Definition: SpellDefines.h:285
@ TARGET_FLAG_UNIT
Definition: SpellDefines.h:281
@ TARGET_FLAG_UNIT_MASK
Definition: SpellDefines.h:307
@ TARGET_FLAG_UNIT_DEAD
Definition: SpellDefines.h:290
@ TARGET_FLAG_CORPSE_ENEMY
Definition: SpellDefines.h:289
@ TARGET_FLAG_CORPSE_MASK
Definition: SpellDefines.h:310
@ TARGET_FLAG_GAMEOBJECT_MASK
Definition: SpellDefines.h:309
@ TARGET_FLAG_UNIT_PARTY
Definition: SpellDefines.h:283
SpellAuraInterruptFlags
Definition: SpellDefines.h:76
bool _isPositiveTarget(SpellEffectInfo const &effect)
Definition: SpellInfo.cpp:4425
bool _isPositiveEffectImpl(SpellInfo const *spellInfo, SpellEffectInfo const &effect, std::unordered_set< std::pair< SpellInfo const *, SpellEffIndex > > &visited)
Definition: SpellInfo.cpp:4434
float CalcPPMHasteMod(SpellProcsPerMinuteModEntry const *mod, Unit *caster)
Definition: SpellInfo.cpp:4136
float CalcPPMCritMod(SpellProcsPerMinuteModEntry const *mod, Unit *caster)
Definition: SpellInfo.cpp:4162
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
Definition: SpellInfo.cpp:41
float CalcPPMItemLevelMod(SpellProcsPerMinuteModEntry const *mod, int32 itemLevel)
Definition: SpellInfo.cpp:4189
SpellTargetCheckTypes
Definition: SpellInfo.h:81
@ TARGET_CHECK_TAP
Definition: SpellInfo.h:92
@ TARGET_CHECK_PASSENGER
Definition: SpellInfo.h:89
@ TARGET_CHECK_PARTY
Definition: SpellInfo.h:86
@ TARGET_CHECK_ENEMY
Definition: SpellInfo.h:84
@ TARGET_CHECK_DEFAULT
Definition: SpellInfo.h:82
@ TARGET_CHECK_THREAT
Definition: SpellInfo.h:91
@ TARGET_CHECK_SUMMONED
Definition: SpellInfo.h:90
@ TARGET_CHECK_ENTRY
Definition: SpellInfo.h:83
@ TARGET_CHECK_RAID_CLASS
Definition: SpellInfo.h:88
@ TARGET_CHECK_ALLY
Definition: SpellInfo.h:85
@ TARGET_CHECK_RAID
Definition: SpellInfo.h:87
SpellEffectImplicitTargetTypes
Definition: SpellInfo.h:111
@ EFFECT_IMPLICIT_TARGET_CASTER
Definition: SpellInfo.h:114
@ EFFECT_IMPLICIT_TARGET_NONE
Definition: SpellInfo.h:112
@ EFFECT_IMPLICIT_TARGET_EXPLICIT
Definition: SpellInfo.h:113
SpellTargetSelectionCategories
Definition: SpellInfo.h:43
@ TARGET_SELECT_CATEGORY_CONE
Definition: SpellInfo.h:48
@ TARGET_SELECT_CATEGORY_AREA
Definition: SpellInfo.h:49
@ TARGET_SELECT_CATEGORY_DEFAULT
Definition: SpellInfo.h:45
@ TARGET_SELECT_CATEGORY_NEARBY
Definition: SpellInfo.h:47
@ TARGET_SELECT_CATEGORY_NYI
Definition: SpellInfo.h:44
@ TARGET_SELECT_CATEGORY_LINE
Definition: SpellInfo.h:51
@ TARGET_SELECT_CATEGORY_TRAJ
Definition: SpellInfo.h:50
@ TARGET_SELECT_CATEGORY_CHANNEL
Definition: SpellInfo.h:46
SpellTargetDirectionTypes
Definition: SpellInfo.h:96
@ TARGET_DIR_FRONT_RIGHT
Definition: SpellInfo.h:102
@ TARGET_DIR_NONE
Definition: SpellInfo.h:97
@ TARGET_DIR_BACK
Definition: SpellInfo.h:99
@ TARGET_DIR_BACK_RIGHT
Definition: SpellInfo.h:103
@ TARGET_DIR_RIGHT
Definition: SpellInfo.h:100
@ TARGET_DIR_FRONT_LEFT
Definition: SpellInfo.h:105
@ TARGET_DIR_FRONT
Definition: SpellInfo.h:98
@ TARGET_DIR_LEFT
Definition: SpellInfo.h:101
@ TARGET_DIR_BACK_LEFT
Definition: SpellInfo.h:104
@ TARGET_DIR_RANDOM
Definition: SpellInfo.h:106
SpellTargetObjectTypes
Definition: SpellInfo.h:65
@ TARGET_OBJECT_TYPE_UNIT
Definition: SpellInfo.h:69
@ TARGET_OBJECT_TYPE_ITEM
Definition: SpellInfo.h:73
@ TARGET_OBJECT_TYPE_CORPSE
Definition: SpellInfo.h:74
@ TARGET_OBJECT_TYPE_UNIT_AND_DEST
Definition: SpellInfo.h:70
@ TARGET_OBJECT_TYPE_NONE
Definition: SpellInfo.h:66
@ TARGET_OBJECT_TYPE_DEST
Definition: SpellInfo.h:68
@ TARGET_OBJECT_TYPE_GOBJ
Definition: SpellInfo.h:71
@ TARGET_OBJECT_TYPE_CORPSE_ALLY
Definition: SpellInfo.h:77
@ TARGET_OBJECT_TYPE_CORPSE_ENEMY
Definition: SpellInfo.h:76
@ TARGET_OBJECT_TYPE_GOBJ_ITEM
Definition: SpellInfo.h:72
@ TARGET_OBJECT_TYPE_SRC
Definition: SpellInfo.h:67
@ SPELL_ATTR0_CU_ALLOW_INFLIGHT_TARGET
Definition: SpellInfo.h:166
@ SPELL_ATTR0_CU_PICKPOCKET
Definition: SpellInfo.h:158
SpellSpecificType
Definition: SpellInfo.h:119
@ SPELL_SPECIFIC_FOOD
Definition: SpellInfo.h:132
@ SPELL_SPECIFIC_MAGE_ARMOR
Definition: SpellInfo.h:128
@ SPELL_SPECIFIC_NORMAL
Definition: SpellInfo.h:120
@ SPELL_SPECIFIC_STING
Definition: SpellInfo.h:123
@ SPELL_SPECIFIC_MAGE_ARCANE_BRILLANCE
Definition: SpellInfo.h:138
@ SPELL_SPECIFIC_ASPECT
Definition: SpellInfo.h:125
@ SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT
Definition: SpellInfo.h:140
@ SPELL_SPECIFIC_ELEMENTAL_SHIELD
Definition: SpellInfo.h:129
@ SPELL_SPECIFIC_WARLOCK_CORRUPTION
Definition: SpellInfo.h:131
@ SPELL_SPECIFIC_BANE
Definition: SpellInfo.h:143
@ SPELL_SPECIFIC_PRESENCE
Definition: SpellInfo.h:135
@ SPELL_SPECIFIC_CURSE
Definition: SpellInfo.h:124
@ SPELL_SPECIFIC_DRINK
Definition: SpellInfo.h:133
@ SPELL_SPECIFIC_HAND
Definition: SpellInfo.h:141
@ SPELL_SPECIFIC_AURA
Definition: SpellInfo.h:122
@ SPELL_SPECIFIC_WARRIOR_ENRAGE
Definition: SpellInfo.h:139
@ SPELL_SPECIFIC_WARLOCK_ARMOR
Definition: SpellInfo.h:127
@ SPELL_SPECIFIC_SCROLL
Definition: SpellInfo.h:137
@ SPELL_SPECIFIC_MAGE_POLYMORPH
Definition: SpellInfo.h:130
@ SPELL_SPECIFIC_TRACKER
Definition: SpellInfo.h:126
@ SPELL_SPECIFIC_SEAL
Definition: SpellInfo.h:121
@ SPELL_SPECIFIC_FOOD_AND_DRINK
Definition: SpellInfo.h:134
@ SPELL_SPECIFIC_CHARM
Definition: SpellInfo.h:136
SpellTargetReferenceTypes
Definition: SpellInfo.h:55
@ TARGET_REFERENCE_TYPE_SRC
Definition: SpellInfo.h:60
@ TARGET_REFERENCE_TYPE_TARGET
Definition: SpellInfo.h:58
@ TARGET_REFERENCE_TYPE_LAST
Definition: SpellInfo.h:59
@ TARGET_REFERENCE_TYPE_NONE
Definition: SpellInfo.h:56
@ TARGET_REFERENCE_TYPE_CASTER
Definition: SpellInfo.h:57
@ TARGET_REFERENCE_TYPE_DEST
Definition: SpellInfo.h:61
bool IsPrimaryProfessionSkill(uint32 skill)
Definition: SpellMgr.cpp:106
bool IsProfessionSkill(uint32 skill)
Definition: SpellMgr.h:647
std::pair< SpellAreaMap::const_iterator, SpellAreaMap::const_iterator > SpellAreaMapBounds
Definition: SpellMgr.h:554
#define sSpellMgr
Definition: SpellMgr.h:849
std::pair< SkillLineAbilityMap::const_iterator, SkillLineAbilityMap::const_iterator > SkillLineAbilityMapBounds
Definition: SpellMgr.h:621
ProcFlags
Definition: SpellMgr.h:134
@ UNIT_FLAG_PET_IN_COMBAT
Definition: UnitDefines.h:155
@ UNIT_STATE_IN_FLIGHT
Definition: Unit.h:263
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Definition: Util.h:491
T CalculatePct(T base, U pct)
Definition: Util.h:72
bool IsPositive() const
Definition: SpellAuras.h:84
Aura * GetBase() const
Definition: SpellAuras.h:78
SpellInfo const * GetSpellInfo() const
AuraType GetAuraType() const
SpellEffectInfo const & GetSpellEffectInfo() const
bool IsAffectingSpell(SpellInfo const *spell) const
int32 GetMiscValue() const
SpellInfo const * GetSpellInfo() const
Definition: SpellAuras.h:134
BattlegroundStatus GetStatus() const
Definition: Battleground.h:284
static bool IsPlayerMeetingCondition(Player const *player, PlayerConditionEntry const *condition)
static bool IsUnitMeetingCondition(Unit const *unit, Unit const *otherUnit, UnitConditionEntry const *condition)
Definition: Corpse.h:53
CreatureDifficulty const * GetCreatureDifficulty() const
Definition: Creature.h:252
bool CanHaveLoot() const
Definition: Creature.h:273
static bool IsInArea(uint32 objectAreaId, uint32 areaId)
Definition: DB2Stores.cpp:1907
constexpr bool HasFlag(T flag) const
Definition: EnumFlag.h:106
Definition: Item.h:170
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition: Item.cpp:1387
bool HaveLootFor(uint32 loot_id) const
Definition: LootMgr.h:83
Definition: Map.h:189
bool IsBattlegroundOrArena() const
Definition: Map.cpp:3340
InstanceMap * ToInstanceMap()
Definition: Map.h:454
bool IsEmpty() const
Definition: ObjectGuid.h:319
static Creature * ToCreature(Object *o)
Definition: Object.h:219
bool IsPlayer() const
Definition: Object.h:212
static Unit * ToUnit(Object *o)
Definition: Object.h:225
bool IsUnit() const
Definition: Object.h:224
TypeID GetTypeId() const
Definition: Object.h:173
static Corpse * ToCorpse(Object *o)
Definition: Object.h:237
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
static Player * ToPlayer(Object *o)
Definition: Object.h:213
Unit * ToUnit()
Definition: Object.h:227
bool InBattleground() const
Definition: Player.h:2394
Battleground * GetBattleground() const
Definition: Player.cpp:24976
bool IsGameMaster() const
Definition: Player.h:1178
UF::UpdateField< UF::ActivePlayerData, 0, TYPEID_ACTIVE_PLAYER > m_activePlayerData
Definition: Player.h:2864
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition: Player.cpp:9643
bool IsUseEquipedWeapon(bool mainhand) const
Definition: Player.cpp:13318
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3792
float PositionFacing
Definition: SpellInfo.h:230
Mechanics Mechanic
Definition: SpellInfo.h:229
static std::array< StaticData, TOTAL_SPELL_EFFECTS > _data
Definition: SpellInfo.h:294
bool IsUnitOwnedAuraEffect() const
Definition: SpellInfo.cpp:490
float CalcDamageMultiplier(WorldObject *caster, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:652
bool HasRadius(SpellTargetIndex targetIndex) const
Definition: SpellInfo.cpp:660
AuraType ApplyAuraName
Definition: SpellInfo.h:219
int32 CalcValue(WorldObject const *caster=nullptr, int32 const *basePoints=nullptr, Unit const *target=nullptr, float *variance=nullptr, uint32 castItemId=0, int32 itemLevel=-1) const
Definition: SpellInfo.cpp:495
int32 MiscValueB
Definition: SpellInfo.h:228
float CalcValueMultiplier(WorldObject *caster, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:644
struct SpellEffectInfo::ScalingInfo Scaling
uint32 TriggerSpell
Definition: SpellInfo.h:237
ImmunityInfo const * GetImmunityInfo() const
Definition: SpellInfo.h:283
uint32 GetMissingTargetMask(bool srcSet=false, bool dstSet=false, uint32 mask=0) const
Definition: SpellInfo.cpp:719
std::unique_ptr< ImmunityInfo > _immunityInfo
Definition: SpellInfo.h:296
bool IsAreaAuraEffect() const
Definition: SpellInfo.cpp:476
SpellInfo const * _spellInfo
Definition: SpellInfo.h:215
bool IsAura() const
Definition: SpellInfo.cpp:461
SpellEffectName Effect
Definition: SpellInfo.h:218
int32 CalcBaseValue(WorldObject const *caster, Unit const *target, uint32 itemId, int32 itemLevel) const
Definition: SpellInfo.cpp:554
SpellRadiusEntry const * TargetBRadiusEntry
Definition: SpellInfo.h:234
std::shared_ptr< std::vector< Condition > > ImplicitTargetConditions
Definition: SpellInfo.h:240
bool IsEffect() const
Definition: SpellInfo.cpp:451
flag128 SpellClassMask
Definition: SpellInfo.h:238
bool IsTargetingArea() const
Definition: SpellInfo.cpp:471
SpellRadiusEntry const * TargetARadiusEntry
Definition: SpellInfo.h:233
int32 ChainTargets
Definition: SpellInfo.h:235
SpellEffectImplicitTargetTypes GetImplicitTargetType() const
Definition: SpellInfo.cpp:743
float BonusCoefficientFromAP
Definition: SpellInfo.h:239
float BonusCoefficient
Definition: SpellInfo.h:226
ExpectedStatType GetScalingExpectedStat() const
Definition: SpellInfo.cpp:753
float ChainAmplitude
Definition: SpellInfo.h:225
uint32 ApplyAuraPeriod
Definition: SpellInfo.h:220
SpellTargetObjectTypes GetUsedTargetObjectType() const
Definition: SpellInfo.cpp:748
float RealPointsPerLevel
Definition: SpellInfo.h:222
uint32 ItemType
Definition: SpellInfo.h:236
EnumFlag< SpellEffectAttributes > EffectAttributes
Definition: SpellInfo.h:241
SpellEffIndex EffectIndex
Definition: SpellInfo.h:217
float BasePoints
Definition: SpellInfo.h:221
uint32 GetProvidedTargetMask() const
Definition: SpellInfo.cpp:714
SpellImplicitTargetInfo TargetA
Definition: SpellInfo.h:231
float CalcRadius(WorldObject *caster=nullptr, SpellTargetIndex targetIndex=SpellTargetIndex::TargetA, Spell *=nullptr) const
Definition: SpellInfo.cpp:673
float PointsPerResource
Definition: SpellInfo.h:223
SpellImplicitTargetInfo TargetB
Definition: SpellInfo.h:232
SpellTargetDirectionTypes GetDirectionType() const
Definition: SpellInfo.cpp:100
SpellTargetCheckTypes GetCheckType() const
Definition: SpellInfo.cpp:95
static std::array< StaticData, TOTAL_SPELL_TARGETS > _data
Definition: SpellInfo.h:209
SpellTargetReferenceTypes GetReferenceType() const
Definition: SpellInfo.cpp:85
SpellTargetSelectionCategories GetSelectionCategory() const
Definition: SpellInfo.cpp:80
SpellTargetObjectTypes GetObjectType() const
Definition: SpellInfo.cpp:90
float CalcDirectionAngle() const
Definition: SpellInfo.cpp:105
uint32 GetExplicitTargetMask(bool &srcSet, bool &dstSet) const
Definition: SpellInfo.cpp:137
Targets GetTarget() const
Definition: SpellInfo.cpp:132
std::array< SpellPowerEntry const *, MAX_POWERS_PER_SPELL > PowerCosts
Definition: SpellInfo.h:386
bool IsExplicitDiscovery() const
Definition: SpellInfo.cpp:1470
DiminishingLevels GetDiminishingReturnsMaxLevel() const
Definition: SpellInfo.cpp:3298
uint32 RequiresSpellFocus
Definition: SpellInfo.h:351
uint32 BaseLevel
Definition: SpellInfo.h:383
void _LoadSpellDiminishInfo()
Definition: SpellInfo.cpp:2817
uint32 MaxLevel
Definition: SpellInfo.h:382
uint32 SpellLevel
Definition: SpellInfo.h:384
uint32 AttributesEx13
Definition: SpellInfo.h:343
uint32 ActiveIconFileDataId
Definition: SpellInfo.h:400
uint32 GetSpellXSpellVisualId(WorldObject const *caster=nullptr, WorldObject const *viewer=nullptr) const
Definition: SpellInfo.cpp:4363
struct SpellInfo::@337 SqrtDamageAndHealingDiminishing
uint32 TargetAuraState
Definition: SpellInfo.h:354
bool IsRankOf(SpellInfo const *spellInfo) const
Definition: SpellInfo.cpp:4341
uint32 GetMaxTicks() const
Definition: SpellInfo.cpp:3823
std::array< int32, MAX_SPELL_REAGENTS > Reagent
Definition: SpellInfo.h:393
uint64 GetEffectMechanicMask(SpellEffIndex effIndex) const
Definition: SpellInfo.cpp:2483
uint32 ExcludeTargetAuraSpell
Definition: SpellInfo.h:360
bool CanDispelAura(SpellInfo const *auraSpellInfo) const
Definition: SpellInfo.cpp:1868
bool IsAffected(uint32 familyName, flag128 const &familyFlags) const
Definition: SpellInfo.cpp:1795
uint32 PreventionType
Definition: SpellInfo.h:411
uint32 CasterAuraSpell
Definition: SpellInfo.h:357
bool MeetsFutureSpellPlayerCondition(Player const *player) const
Definition: SpellInfo.cpp:4928
float Width
Definition: SpellInfo.h:405
uint32 MaxTargetLevel
Definition: SpellInfo.h:406
Optional< SpellPowerCost > CalcPowerCost(Powers powerType, bool optionalCost, WorldObject const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:3870
Mechanics GetEffectMechanic(SpellEffIndex effIndex) const
Definition: SpellInfo.cpp:2508
SpellInfo const * GetFirstRankSpell() const
Definition: SpellInfo.cpp:4272
bool IsAutocastable() const
Definition: SpellInfo.cpp:1597
float GetMaxRange(bool positive=false, WorldObject *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:3768
bool HasEffect(SpellEffectName effect) const
Definition: SpellInfo.cpp:1391
std::unordered_set< uint32 > Labels
Definition: SpellInfo.h:415
uint32 GetCategory() const
Definition: SpellInfo.cpp:1386
SpellCastResult CheckShapeshift(uint32 form) const
Definition: SpellInfo.cpp:1946
float CalcProcPPM(Unit *caster, int32 itemLevel) const
Definition: SpellInfo.cpp:4202
uint64 GetAllEffectsMechanicMask() const
Definition: SpellInfo.cpp:2470
bool IsRequiringDeadTarget() const
Definition: SpellInfo.cpp:1663
uint32 const Id
Definition: SpellInfo.h:325
uint64 GetMechanicImmunityMask(Unit const *caster) const
Definition: SpellInfo.cpp:3744
uint32 RecoveryTime
Definition: SpellInfo.h:366
EnumFlag< SpellAuraInterruptFlags2 > AuraInterruptFlags2
Definition: SpellInfo.h:373
uint32 AttributesEx8
Definition: SpellInfo.h:338
std::array< int16, MAX_SPELL_REAGENTS > ReagentCount
Definition: SpellInfo.h:394
bool IsAuraExclusiveBySpecificPerCasterWith(SpellInfo const *spellInfo) const
Definition: SpellInfo.cpp:1927
SpellInfo const * GetPrevRankSpell() const
Definition: SpellInfo.cpp:4293
bool IsGroupBuff() const
Definition: SpellInfo.cpp:1685
bool IsDeathPersistent() const
Definition: SpellInfo.cpp:1658
SpellVisualVector _visuals
Definition: SpellInfo.h:616
bool IsCooldownStartedOnEvent() const
Definition: SpellInfo.cpp:1649
EnumFlag< SpellAuraInterruptFlags > ChannelInterruptFlags
Definition: SpellInfo.h:374
bool IsPassive() const
Definition: SpellInfo.cpp:1592
uint32 StackAmount
Definition: SpellInfo.h:390
::Difficulty const Difficulty
Definition: SpellInfo.h:326
uint32 Mechanic
Definition: SpellInfo.h:329
bool IsAuraExclusiveBySpecificWith(SpellInfo const *spellInfo) const
Definition: SpellInfo.cpp:1895
uint8 GetRank() const
Definition: SpellInfo.cpp:4265
SpellRangeEntry const * RangeEntry
Definition: SpellInfo.h:387
uint32 ProcCharges
Definition: SpellInfo.h:378
bool HasAnyAuraInterruptFlag() const
Definition: SpellInfo.cpp:1465
bool IsLootCrafting() const
Definition: SpellInfo.cpp:1481
int32 RequiredAreasID
Definition: SpellInfo.h:412
uint32 ShowFutureSpellPlayerConditionID
Definition: SpellInfo.h:402
bool IsStackableOnOneSlotWithDifferentCasters() const
Definition: SpellInfo.cpp:1643
bool IsRanked() const
Definition: SpellInfo.cpp:4260
uint32 AttributesEx14
Definition: SpellInfo.h:344
bool HasOnlyDamageEffects() const
Definition: SpellInfo.cpp:1418
uint32 GetDispelMask() const
Definition: SpellInfo.cpp:2519
bool IsHighRankOf(SpellInfo const *spellInfo) const
Definition: SpellInfo.cpp:4353
uint32 CalcCastTime(Spell *spell=nullptr) const
Definition: SpellInfo.cpp:3805
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition: SpellInfo.cpp:4300
bool NeedsToBeTriggeredByCaster(SpellInfo const *triggeringSpell) const
Definition: SpellInfo.cpp:1556
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player const *player=nullptr) const
Definition: SpellInfo.cpp:1995
uint32 GetRecoveryTime() const
Definition: SpellInfo.cpp:3865
AuraStateType _auraState
Definition: SpellInfo.h:618
SpellSpecificType GetSpellSpecific() const
Definition: SpellInfo.cpp:2624
DiminishingReturnsType GetDiminishingReturnsGroupType() const
Definition: SpellInfo.cpp:3293
uint32 Dispel
Definition: SpellInfo.h:328
std::vector< SpellProcsPerMinuteModEntry const * > ProcPPMMods
Definition: SpellInfo.h:381
uint64 GetAllowedMechanicMask() const
Definition: SpellInfo.cpp:3739
bool HasTargetType(::Targets target) const
Definition: SpellInfo.cpp:1444
bool HasHitDelay() const
Definition: SpellInfo.cpp:1751
uint32 ExcludeCasterAuraState
Definition: SpellInfo.h:355
float Speed
Definition: SpellInfo.h:388
bool IsMultiSlotAura() const
Definition: SpellInfo.cpp:1638
void _UnloadImplicitTargetConditionLists()
Definition: SpellInfo.cpp:4921
float GetMinRange(bool positive=false) const
Definition: SpellInfo.cpp:3761
int32 GetMaxDuration() const
Definition: SpellInfo.cpp:3798
uint32 CooldownAuraSpellId
Definition: SpellInfo.h:370
int32 EquippedItemClass
Definition: SpellInfo.h:396
bool HasInitialAggro() const
Definition: SpellInfo.cpp:1746
std::vector< SpellEffectInfo > _effects
Definition: SpellInfo.h:615
int32 GetDiminishingReturnsLimitDuration() const
Definition: SpellInfo.cpp:3303
struct SpellInfo::ScalingInfo Scaling
DiminishingGroup GetDiminishingReturnsGroupForSpell() const
Definition: SpellInfo.cpp:3288
uint32 SchoolMask
Definition: SpellInfo.h:413
bool IsAbilityOfSkillType(uint32 skillType) const
Definition: SpellInfo.cpp:1521
uint32 CasterAuraState
Definition: SpellInfo.h:353
bool IsAffectedBySpellMod(SpellModifier const *mod) const
Definition: SpellInfo.cpp:1814
SpellCastResult CheckTarget(WorldObject const *caster, WorldObject const *target, bool implicit=true) const
Definition: SpellInfo.cpp:2175
bool CheckTargetCreatureType(Unit const *target) const
Definition: SpellInfo.cpp:2445
float ProcBasePPM
Definition: SpellInfo.h:380
bool IsStackableWithRanks() const
Definition: SpellInfo.cpp:1606
bool IsItemFitToSpellRequirements(Item const *item) const
Definition: SpellInfo.cpp:1782
uint32 CategoryRecoveryTime
Definition: SpellInfo.h:367
uint64 StancesNot
Definition: SpellInfo.h:348
AuraType TargetAuraType
Definition: SpellInfo.h:362
EnumFlag< SpellInterruptFlags > InterruptFlags
Definition: SpellInfo.h:371
flag128 SpellFamilyFlags
Definition: SpellInfo.h:409
uint32 ExplicitTargetMask
Definition: SpellInfo.h:425
bool IsAllowingDeadTarget() const
Definition: SpellInfo.cpp:1668
uint32 AttributesEx3
Definition: SpellInfo.h:333
float LaunchDelay
Definition: SpellInfo.h:389
void _InitializeSpellPositivity()
Definition: SpellInfo.cpp:4882
void _LoadImmunityInfo()
Definition: SpellInfo.cpp:3308
WeaponAttackType GetAttackType() const
Definition: SpellInfo.cpp:1756
SpellSchoolMask GetSchoolMask() const
Definition: SpellInfo.cpp:2465
bool IsPrimaryProfession() const
Definition: SpellInfo.cpp:1501
std::vector< SpellReagentsCurrencyEntry const * > ReagentsCurrency
Definition: SpellInfo.h:395
void ApplyAllSpellImmunitiesTo(Unit *target, SpellEffectInfo const &spellEffectInfo, bool apply) const
Definition: SpellInfo.cpp:3507
AuraStateType GetAuraState() const
Definition: SpellInfo.cpp:2538
bool IsChanneled() const
Definition: SpellInfo.cpp:1719
uint32 GetSpellVisual(WorldObject const *caster=nullptr, WorldObject const *viewer=nullptr) const
Definition: SpellInfo.cpp:4381
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:449
SpellDurationEntry const * DurationEntry
Definition: SpellInfo.h:385
bool IsNextMeleeSwingSpell() const
Definition: SpellInfo.cpp:1729
uint64 GetSpellMechanicMaskByEffectMask(uint32 effectMask) const
Definition: SpellInfo.cpp:2495
uint32 Attributes
Definition: SpellInfo.h:330
uint32 AttributesEx
Definition: SpellInfo.h:331
bool CanSpellProvideImmunityAgainstAura(SpellInfo const *auraSpellInfo) const
Definition: SpellInfo.cpp:3609
bool HasChannelInterruptFlag(SpellAuraInterruptFlags flag) const
Definition: SpellInfo.h:472
uint32 ChargeCategoryId
Definition: SpellInfo.h:414
bool IsPassiveStackableWithRanks() const
Definition: SpellInfo.cpp:1633
bool SpellCancelsAuraEffect(AuraEffect const *aurEff) const
Definition: SpellInfo.cpp:3693
uint32 IconFileDataId
Definition: SpellInfo.h:399
uint32 MaxAffectedTargets
Definition: SpellInfo.h:407
uint32 AttributesEx12
Definition: SpellInfo.h:342
int32 GetDuration() const
Definition: SpellInfo.cpp:3791
bool IsAffectedBySpellMods() const
Definition: SpellInfo.cpp:1809
SpellCastResult CheckVehicle(Unit const *caster) const
Definition: SpellInfo.cpp:2395
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition: SpellInfo.h:577
std::vector< SpellEffectInfo > const & GetEffects() const
Definition: SpellInfo.h:576
uint32 AttributesEx6
Definition: SpellInfo.h:336
uint32 AttributesEx7
Definition: SpellInfo.h:337
int32 EquippedItemSubClassMask
Definition: SpellInfo.h:397
SpellDiminishInfo _diminishInfo
Definition: SpellInfo.h:620
SpellSpecificType _spellSpecific
Definition: SpellInfo.h:617
SpellInfo(SpellNameEntry const *spellName, ::Difficulty difficulty, SpellInfoLoadHelper const &data)
Definition: SpellInfo.cpp:1164
uint32 GetExplicitTargetMask() const
Definition: SpellInfo.cpp:2533
uint32 AttributesEx9
Definition: SpellInfo.h:339
uint32 FacingCasterFlags
Definition: SpellInfo.h:352
SpellCastResult CheckExplicitTarget(WorldObject const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
Definition: SpellInfo.cpp:2359
uint32 StartRecoveryTime
Definition: SpellInfo.h:369
uint32 ContentTuningId
Definition: SpellInfo.h:401
uint32 TargetAuraSpell
Definition: SpellInfo.h:358
bool HasAreaAuraEffect() const
Definition: SpellInfo.cpp:1409
bool CanPierceImmuneAura(SpellInfo const *auraSpellInfo) const
Definition: SpellInfo.cpp:1841
SpellChainNode const * ChainEntry
Definition: SpellInfo.h:426
AuraType ExcludeTargetAuraType
Definition: SpellInfo.h:364
void _LoadSqrtTargetLimit(int32 maxTargets, int32 numNonDiminishedTargets, Optional< SpellEffIndex > maxTargetsEffectValueHolder, Optional< SpellEffIndex > numNonDiminishedTargetsEffectValueHolder)
Definition: SpellInfo.cpp:3472
uint32 AttributesEx10
Definition: SpellInfo.h:340
uint32 Targets
Definition: SpellInfo.h:349
void _InitializeExplicitTargetMask()
Definition: SpellInfo.cpp:4394
uint32 ProcCooldown
Definition: SpellInfo.h:379
bool IsDifferentRankOf(SpellInfo const *spellInfo) const
Definition: SpellInfo.cpp:4346
LocalizedString const * SpellName
Definition: SpellInfo.h:403
SpellInfo const * GetLastRankSpell() const
Definition: SpellInfo.cpp:4279
bool NeedsExplicitUnitTarget() const
Definition: SpellInfo.cpp:1551
SpellInfo const * GetNextRankSpell() const
Definition: SpellInfo.cpp:4286
SpellCastTimesEntry const * CastTimeEntry
Definition: SpellInfo.h:365
int32 EquippedItemInventoryTypeMask
Definition: SpellInfo.h:398
uint32 ExcludeTargetAuraState
Definition: SpellInfo.h:356
std::bitset< MAX_SPELL_EFFECTS > NegativeEffects
Definition: SpellInfo.h:346
EnumFlag< SpellAuraInterruptFlags2 > ChannelInterruptFlags2
Definition: SpellInfo.h:375
bool IsPrimaryProfessionFirstRank() const
Definition: SpellInfo.cpp:1516
void _LoadAuraState()
Definition: SpellInfo.cpp:2543
AuraType ExcludeCasterAuraType
Definition: SpellInfo.h:363
int32 CalcDuration(WorldObject const *caster=nullptr) const
Definition: SpellInfo.cpp:3780
bool IsAffectingArea() const
Definition: SpellInfo.cpp:1532
bool IsProfession() const
Definition: SpellInfo.cpp:1486
bool IsPositive() const
Definition: SpellInfo.cpp:1709
bool IsAutoRepeatRangedSpell() const
Definition: SpellInfo.cpp:1741
uint32 TargetCreatureType
Definition: SpellInfo.h:350
uint32 ProcChance
Definition: SpellInfo.h:377
uint32 AttributesEx2
Definition: SpellInfo.h:332
bool IsMoveAllowedChannel() const
Definition: SpellInfo.cpp:1724
uint32 DmgClass
Definition: SpellInfo.h:410
AuraType CasterAuraType
Definition: SpellInfo.h:361
uint32 AttributesEx5
Definition: SpellInfo.h:335
bool IsRangedWeaponSpell() const
Definition: SpellInfo.cpp:1734
uint32 AttributesEx4
Definition: SpellInfo.h:334
EnumFlag< SpellAuraInterruptFlags > AuraInterruptFlags
Definition: SpellInfo.h:372
uint32 ExcludeCasterAuraSpell
Definition: SpellInfo.h:359
bool HasAura(AuraType aura) const
Definition: SpellInfo.cpp:1400
bool IsTargetingArea() const
Definition: SpellInfo.cpp:1542
uint32 StartRecoveryCategory
Definition: SpellInfo.h:368
bool HasAuraInterruptFlag(SpellAuraInterruptFlags flag) const
Definition: SpellInfo.h:469
bool HasLabel(uint32 labelId) const
Definition: SpellInfo.cpp:4937
uint32 AttributesEx11
Definition: SpellInfo.h:341
uint32 CategoryId
Definition: SpellInfo.h:327
float ConeAngle
Definition: SpellInfo.h:404
uint32 SpellFamilyName
Definition: SpellInfo.h:408
bool CanBeInterrupted(WorldObject const *interruptCaster, Unit const *interruptTarget, bool ignoreImmunity=false) const
Definition: SpellInfo.cpp:1453
void _LoadSpellSpecific()
Definition: SpellInfo.cpp:2629
uint64 _allowedMechanicMask
Definition: SpellInfo.h:621
bool IsPositiveEffect(uint8 effIndex) const
Definition: SpellInfo.cpp:1714
bool IsSingleTarget() const
Definition: SpellInfo.cpp:1886
bool CanBeUsedInCombat(Unit const *caster) const
Definition: SpellInfo.cpp:1703
static CreatureImmunities const * GetCreatureImmunities(int32 creatureImmunitiesId)
Definition: SpellMgr.cpp:677
Definition: Spell.h:255
WorldObject * GetCaster() const
Definition: Spell.h:647
ObjectGuid GetSummonerGUID() const
Definition: Totem.h:31
Totem(SummonPropertiesEntry const *properties, Unit *owner)
Definition: Totem.cpp:29
auto find(Key const &value) const
Definition: FlatSet.h:41
std::pair< iterator, bool > insert(Key const &key)
Definition: FlatSet.h:73
Definition: Unit.h:627
void ApplySpellImmune(uint32 spellId, SpellImmunity op, uint32 type, bool apply)
Definition: Unit.cpp:7845
Vehicle * GetVehicle() const
Definition: Unit.h:1713
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3812
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1321
bool HasAuraTypeWithMiscvalue(AuraType auraType, int32 miscValue) const
Definition: Unit.cpp:4687
UF::UpdateField< UF::UnitData, 0, TYPEID_UNIT > m_unitData
Definition: Unit.h:1814
uint32 GetClassMask() const
Definition: Unit.h:754
ShapeshiftForm GetShapeshiftForm() const
Definition: Unit.h:1463
uint64 GetMechanicImmunityMask() const
Definition: Unit.cpp:7541
uint64 GetRaceMask() const
Definition: Unit.h:751
bool HasUnitFlag(UnitFlags flags) const
Definition: Unit.h:832
uint32 GetBaseAttackTime(WeaponAttackType att) const
Definition: Unit.cpp:10303
bool CanFreeMove() const
Definition: Unit.cpp:9323
bool IsAlive() const
Definition: Unit.h:1164
TempSummon * ToTempSummon()
Definition: Unit.h:1756
uint32 GetVirtualItemId(uint32 slot) const
Definition: Unit.cpp:13588
EnumFlag< SpellOtherImmunity > GetSpellOtherImmunityMask() const
Definition: Unit.cpp:7551
uint64 GetMaxHealth() const
Definition: Unit.h:777
uint64 GetHealth() const
Definition: Unit.h:776
bool IsSummon() const
Definition: Unit.h:738
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition: Unit.cpp:5961
bool IsVisible() const
Definition: Unit.cpp:8346
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:4674
ObjectGuid GetCritterGUID() const
Definition: Unit.h:1178
int32 GetTotalAuraModifier(AuraType auraType) const
Definition: Unit.cpp:4929
void RemoveAurasWithInterruptFlags(InterruptFlags flag, SpellInfo const *source=nullptr)
Definition: Unit.cpp:4101
void RemoveAppliedAuras(std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3758
int32 GetPower(Powers power) const
Definition: Unit.cpp:9401
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
bool IsMagnet() const
Definition: Unit.cpp:6388
bool IsInRaidWith(Unit const *unit) const
Definition: Unit.cpp:11546
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4664
void RemoveAurasWithMechanic(uint64 mechanicMaskToRemove, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, uint32 exceptSpellId=0, bool withEffectMechanics=false)
Definition: Unit.cpp:4162
bool IsControlledByPlayer() const
Definition: Unit.h:1193
uint32 GetCreatureTypeMask() const
Definition: Unit.cpp:8898
bool HasAuraTypeWithAffectMask(AuraType auraType, SpellInfo const *affectedSpell) const
Definition: Unit.cpp:4696
uint32 GetCreateMana() const
Definition: Unit.h:1396
MountCapabilityEntry const * GetMountCapability(uint32 mountType) const
Definition: Unit.cpp:7953
bool IsInPartyWith(Unit const *unit) const
Definition: Unit.cpp:11527
uint8 GetLevel() const
Definition: Unit.h:746
bool IsInCombat() const
Definition: Unit.h:1043
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger) const
Returns information on the seat of specified passenger, represented by the format in VehicleSeat....
Definition: Vehicle.cpp:647
Map * GetMap() const
Definition: Object.h:624
bool IsValidAttackTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition: Object.cpp:2991
bool CanSeeOrDetect(WorldObject const *obj, bool implicitDetect=false, bool distanceCheck=false, bool checkAlert=false) const
Definition: Object.cpp:1514
Player * GetSpellModOwner() const
Definition: Object.cpp:2272
bool IsValidAssistTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition: Object.cpp:3144
double ApplyEffectModifiers(SpellInfo const *spellInfo, uint8 effIndex, double value) const
Definition: Object.cpp:2333
void ModSpellCastTime(SpellInfo const *spellInfo, int32 &castTime, Spell *spell=nullptr) const
Definition: Object.cpp:2466
Player * GetAffectingPlayer() const
Definition: Object.cpp:2261
void apply(T *val)
Definition: ByteConverter.h:41
TC_GAME_API Player * FindPlayer(ObjectGuid const &)
decltype(auto) EnsureWritableVectorIndex(std::vector< T > &vec, typename std::vector< T >::size_type i)
Definition: Containers.h:295
constexpr std::size_t size()
Definition: UpdateField.h:796
STL namespace.
bool IsBattleground() const
bool IsDungeon() const
bool IsRaid() const
bool IsBattleArena() const
SpellInfo const * last
Definition: SpellMgr.h:565
SpellInfo const * next
Definition: SpellMgr.h:563
SpellInfo const * first
Definition: SpellMgr.h:564
SpellInfo const * prev
Definition: SpellMgr.h:562
int32 DiminishDurationLimit
Definition: SpellInfo.h:311
DiminishingReturnsType DiminishReturnType
Definition: SpellInfo.h:309
DiminishingLevels DiminishMaxLevel
Definition: SpellInfo.h:310
DiminishingGroup DiminishGroup
Definition: SpellInfo.h:308
std::array< int32, 2 > EffectMiscValue
float EffectChainAmplitude
float EffectBonusCoefficient
std::array< int16, 2 > ImplicitTarget
float EffectRealPointsPerLevel
std::array< uint32, 2 > EffectRadiusIndex
flag128 EffectSpellClassMask
SpellEffectAttributes GetEffectAttributes() const
float BonusCoefficientFromAP
float EffectPointsPerResource
ImmunityInfo(ImmunityInfo &&) noexcept=delete
Trinity::Containers::FlatSet< AuraType > AuraTypeImmune
Definition: SpellInfo.cpp:238
ImmunityInfo(ImmunityInfo const &)=delete
Trinity::Containers::FlatSet< SpellEffectName > SpellEffectImmune
Definition: SpellInfo.cpp:239
SpellCastingRequirementsEntry const * CastingRequirements
Definition: SpellMgr.h:665
SpellReagentsEntry const * Reagents
Definition: SpellMgr.h:676
std::vector< SpellXSpellVisualEntry const * > Visuals
Definition: SpellMgr.h:682
SpellTargetRestrictionsEntry const * TargetRestrictions
Definition: SpellMgr.h:680
std::vector< SpellLabelEntry const * > Labels
Definition: SpellMgr.h:672
SpellTotemsEntry const * Totems
Definition: SpellMgr.h:681
SpellAuraRestrictionsEntry const * AuraRestrictions
Definition: SpellMgr.h:664
SpellScalingEntry const * Scaling
Definition: SpellMgr.h:678
SpellInterruptsEntry const * Interrupts
Definition: SpellMgr.h:671
SpellCategoriesEntry const * Categories
Definition: SpellMgr.h:666
SpellMiscEntry const * Misc
Definition: SpellMgr.h:674
std::array< SpellPowerEntry const *, MAX_POWERS_PER_SPELL > Powers
Definition: SpellMgr.h:675
SpellEquippedItemsEntry const * EquippedItems
Definition: SpellMgr.h:670
SpellShapeshiftEntry const * Shapeshift
Definition: SpellMgr.h:679
SpellAuraOptionsEntry const * AuraOptions
Definition: SpellMgr.h:663
std::array< SpellEffectEntry const *, MAX_SPELL_EFFECTS > Effects
Definition: SpellMgr.h:669
SpellClassOptionsEntry const * ClassOptions
Definition: SpellMgr.h:667
std::vector< SpellReagentsCurrencyEntry const * > ReagentsCurrency
Definition: SpellMgr.h:677
SpellCooldownsEntry const * Cooldowns
Definition: SpellMgr.h:668
SpellLevelsEntry const * Levels
Definition: SpellMgr.h:673
SpellModType type
Definition: Player.h:230
uint32 spellId
Definition: Player.h:232
LocalizedString Name
Powers Power
Definition: SpellInfo.h:316
int32 RequiredAuraSpellID
std::array< float, 2 > RangeMin
std::array< float, 2 > RangeMax
EnumFlag< SpellShapeshiftFormFlags > GetFlags() const