TrinityCore
Loading...
Searching...
No Matches
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 "TraitMgr.h"
39#include "Vehicle.h"
40#include <boost/container/small_vector.hpp>
41#include <G3D/g3dmath.h>
42#include <bit>
43
72
77
82
87
92
97
99{
100 return _data[_target].SelectionCheckType;
101}
102
107
109{
110 switch (GetDirectionType())
111 {
112 case TARGET_DIR_FRONT:
113 return 0.0f;
114 case TARGET_DIR_BACK:
115 return static_cast<float>(M_PI);
116 case TARGET_DIR_RIGHT:
117 return static_cast<float>(-M_PI/2);
118 case TARGET_DIR_LEFT:
119 return static_cast<float>(M_PI/2);
121 return static_cast<float>(-M_PI/4);
123 return static_cast<float>(-3*M_PI/4);
125 return static_cast<float>(3*M_PI/4);
127 return static_cast<float>(M_PI/4);
129 return rand_norm() * static_cast<float>(2 * M_PI);
130 default:
131 return 0.0f;
132 }
133}
134
139
141{
142 uint32 targetMask = 0;
144 {
145 if (!srcSet)
146 targetMask = TARGET_FLAG_SOURCE_LOCATION;
147 if (!dstSet)
148 targetMask |= TARGET_FLAG_DEST_LOCATION;
149 }
150 else
151 {
152 switch (GetReferenceType())
153 {
155 if (srcSet)
156 break;
157 targetMask = TARGET_FLAG_SOURCE_LOCATION;
158 break;
160 if (dstSet)
161 break;
162 targetMask = TARGET_FLAG_DEST_LOCATION;
163 break;
165 switch (GetObjectType())
166 {
168 targetMask = TARGET_FLAG_GAMEOBJECT;
169 break;
171 targetMask = TARGET_FLAG_GAMEOBJECT_ITEM;
172 break;
176 switch (GetCheckType())
177 {
179 targetMask = TARGET_FLAG_UNIT_ENEMY;
180 break;
182 targetMask = TARGET_FLAG_UNIT_ALLY;
183 break;
185 targetMask = TARGET_FLAG_UNIT_PARTY;
186 break;
188 targetMask = TARGET_FLAG_UNIT_RAID;
189 break;
191 targetMask = TARGET_FLAG_UNIT_PASSENGER;
192 break;
194 [[fallthrough]];
195 default:
196 targetMask = TARGET_FLAG_UNIT;
197 break;
198 }
199 break;
200 default:
201 break;
202 }
203 break;
204 default:
205 break;
206 }
207 }
208
209 switch (GetObjectType())
210 {
212 srcSet = true;
213 break;
216 dstSet = true;
217 break;
218 default:
219 break;
220 }
221 return targetMask;
222}
223
245
247{ {
401} };
402
411
413 : EffectAttributes(SpellEffectAttributes::None)
414{
415 ASSERT(spellInfo);
416
417 _spellInfo = spellInfo;
419 Effect = SpellEffects(_effect.Effect);
425 Amplitude = _effect.EffectAmplitude;
428 MiscValue = _effect.EffectMiscValue[0];
429 MiscValueB = _effect.EffectMiscValue[1];
437 ItemType = _effect.EffectItemType;
441 Scaling.Class = _effect.ScalingClass;
443 Scaling.Variance = _effect.Variance;
445 ImplicitTargetConditions = nullptr;
447 _immunityInfo = nullptr;
448}
449
451SpellEffectInfo& SpellEffectInfo::operator=(SpellEffectInfo&&) noexcept = default;
452
453SpellEffectInfo::~SpellEffectInfo() = default;
454
455bool SpellEffectInfo::IsEffect() const
456{
457 return Effect != 0;
458}
459
461{
462 return Effect == effectName;
463}
464
469
471{
472 return IsAura() && ApplyAuraName == aura;
473}
474
476{
477 return TargetA.IsArea() || TargetB.IsArea();
478}
479
493
498
500{
501 if (!ApplyAuraPeriod)
502 return 0;
503
504 int32 duration = _spellInfo->GetDuration();
505 // skip infinite periodics
506 if (duration <= 0)
507 return 0;
508
509 uint32 totalTicks = static_cast<uint32>(duration) / ApplyAuraPeriod;
511 ++totalTicks;
512
513 return totalTicks;
514}
515
516int32 SpellEffectInfo::CalcValueAsInt(WorldObject const* caster /*= nullptr*/, SpellEffectValue const* basePoints /*= nullptr*/, Unit const* target /*= nullptr*/, float* variance /*= nullptr*/, uint32 castItemId /*= 0*/, int32 itemLevel /*= -1*/) const
517{
518 return int32(CalcValue(caster, basePoints, target, variance, castItemId, itemLevel));
519}
520
521SpellEffectValue SpellEffectInfo::CalcValue(WorldObject const* caster /*= nullptr*/, SpellEffectValue const* bp /*= nullptr*/, Unit const* target /*= nullptr*/, float* variance /*= nullptr*/, uint32 castItemId /*= 0*/, int32 itemLevel /*= -1*/) const
522{
523 SpellEffectValue basePoints = CalcBaseValue(caster, target, castItemId, itemLevel);
524 SpellEffectValue value = bp ? *bp : basePoints;
525 SpellEffectValue basePointsPerLevel = RealPointsPerLevel;
527
528 Unit const* casterUnit = nullptr;
529 if (caster)
530 {
531 casterUnit = caster->ToUnit();
532 if (Player const* playerCaster = caster->ToPlayer())
533 {
534 if (Optional<PlayerSpellTrait> trait = playerCaster->GetTraitInfoForSpell(_spellInfo->Id))
535 {
536 if (std::vector<TraitDefinitionEffectPointsEntry const*> const* traitDefinitionEffectPoints = TraitMgr::GetTraitDefinitionEffectPointModifiers(trait->DefinitionId))
537 {
538 auto pointsOverride = std::ranges::find(*traitDefinitionEffectPoints, EffectIndex, &TraitDefinitionEffectPointsEntry::EffectIndex);
539 if (pointsOverride != traitDefinitionEffectPoints->end())
540 {
541 float traitBasePoints = sDB2Manager.GetCurveValueAt((*pointsOverride)->CurveID, trait->Rank);
542 switch ((*pointsOverride)->GetOperationType())
543 {
545 value = traitBasePoints;
546 break;
548 value *= traitBasePoints;
549 break;
551 default:
552 break;
553 }
554 }
555 }
556 }
557 }
558 }
559
560 if (Scaling.Variance)
561 {
562 float delta = fabs(Scaling.Variance * 0.5f);
563 float valueVariance = frand(-delta, delta);
564 value += basePoints * valueVariance;
565
566 if (variance)
567 *variance = valueVariance;
568 }
569
570 // base amount modification based on spell lvl vs caster lvl
571 if (Scaling.Coefficient != 0.0f)
572 {
574 comboDamage = value * Scaling.ResourceCoefficient;
575 }
577 {
578 if (casterUnit && basePointsPerLevel != 0.0)
579 {
580 int32 level = int32(casterUnit->GetLevel());
581 if (level > int32(_spellInfo->MaxLevel) && _spellInfo->MaxLevel > 0)
582 level = int32(_spellInfo->MaxLevel);
583
584 // if base level is greater than spell level, reduce by base level (eg. pilgrims foods)
585 level -= int32(std::max(_spellInfo->BaseLevel, _spellInfo->SpellLevel));
586 level = std::max(level, 0);
587 value += level * basePointsPerLevel;
588 }
589 }
590
591 // random damage
592 if (casterUnit)
593 {
594 // bonus amount from combo points
595 if (comboDamage)
596 if (int32 comboPoints = casterUnit->GetPower(POWER_COMBO_POINTS))
597 value += comboDamage * comboPoints;
598 }
599
601 if (Player const* playerCaster = Object::ToPlayer(caster))
602 value += *playerCaster->m_activePlayerData->Mastery * BonusCoefficient;
603
604 if (caster)
605 value = caster->ApplyEffectModifiers(_spellInfo, EffectIndex, value);
606
607 switch (Effect)
608 {
622 value = std::round(value);
623 break;
634 switch (ApplyAuraName)
635 {
649 value = std::round(value);
650 break;
651 default:
652 break;
653 }
654 break;
655 default:
656 break;
657 }
658
659 return std::clamp(value, MinValue, MaxValue);
660}
661
662SpellEffectValue SpellEffectInfo::CalcBaseValue(WorldObject const* caster, Unit const* target, uint32 itemId, int32 itemLevel) const
663{
664 if (Scaling.Coefficient != 0.0f)
665 {
668 level = target->GetLevel();
669 else if (caster && caster->IsUnit())
670 level = caster->ToUnit()->GetLevel();
671
673 level = _spellInfo->BaseLevel;
674
677
680
681 float value = 0.0f;
682 if (level > 0)
683 {
684 if (!Scaling.Class)
685 return 0;
686
687 uint32 effectiveItemLevel = itemLevel != -1 ? uint32(itemLevel) : 1u;
689 {
690 if (Scaling.Class == -8 || Scaling.Class == -9)
691 {
692 RandPropPointsEntry const* randPropPoints = sRandPropPointsStore.LookupEntry(effectiveItemLevel);
693 if (!randPropPoints)
694 randPropPoints = sRandPropPointsStore.AssertEntry(sRandPropPointsStore.GetNumRows() - 1);
695
696 value = Scaling.Class == -8 ? randPropPoints->DamageReplaceStatF : randPropPoints->DamageSecondaryF;
697 }
698 else
699 value = GetRandomPropertyPoints(effectiveItemLevel, ITEM_QUALITY_RARE, INVTYPE_CHEST, 0);
700 }
701 else
703
704 if (Scaling.Class == -7)
705 if (GtCombatRatingsMultByILvl const* ratingMult = sCombatRatingsMultByILvlGameTable.GetRow(effectiveItemLevel))
706 if (ItemSparseEntry const* itemSparse = sItemSparseStore.LookupEntry(itemId))
707 value *= GetIlvlStatMultiplier(ratingMult, InventoryType(itemSparse->InventoryType));
708
709 if (Scaling.Class == -6)
710 if (GtStaminaMultByILvl const* staminaMult = sStaminaMultByILvlGameTable.GetRow(effectiveItemLevel))
711 if (ItemSparseEntry const* itemSparse = sItemSparseStore.LookupEntry(itemId))
712 value *= GetIlvlStatMultiplier(staminaMult, InventoryType(itemSparse->InventoryType));
713 }
714
715 value *= Scaling.Coefficient;
716 if (value > 0.0f && value < 1.0f)
717 value = 1.0f;
718
720 value = round(value);
721
722 return value;
723 }
724 else
725 {
726 float value = BasePoints;
728 if (stat != ExpectedStatType::None)
729 {
732
733 // TODO - add expansion and content tuning id args?
734 uint32 contentTuningId = _spellInfo->ContentTuningId; // content tuning should be passed as arg, the one stored in SpellInfo is fallback
735 int32 expansion = -2;
736 if (ContentTuningEntry const* contentTuning = sContentTuningStore.LookupEntry(contentTuningId))
737 expansion = contentTuning->ExpansionID;
738
739 int32 level = 1;
741 level = target->GetLevel();
742 else if (caster && caster->IsUnit())
743 level = caster->ToUnit()->GetLevel();
744
745 value = sDB2Manager.EvaluateExpectedStat(stat, level, expansion, 0, CLASS_NONE, 0) * value / 100.0f;
747 value = round(value);
748 }
749
750 return value;
751 }
752}
753
754float SpellEffectInfo::CalcValueMultiplier(WorldObject* caster, Spell* spell /*= nullptr*/) const
755{
756 float multiplier = Amplitude;
757 if (Player* modOwner = (caster ? caster->GetSpellModOwner() : nullptr))
758 modOwner->ApplySpellMod(_spellInfo, SpellModOp::Amplitude, multiplier, spell);
759 return multiplier;
760}
761
762float SpellEffectInfo::CalcDamageMultiplier(WorldObject* caster, Spell* spell /*= nullptr*/) const
763{
764 float multiplierPercent = ChainAmplitude * 100.0f;
765 if (Player* modOwner = (caster ? caster->GetSpellModOwner() : nullptr))
766 modOwner->ApplySpellMod(_spellInfo, SpellModOp::ChainAmplitude, multiplierPercent, spell);
767 return multiplierPercent / 100.0f;
768}
769
771{
772 switch (targetIndex)
773 {
775 return TargetARadiusEntry != nullptr;
777 return TargetBRadiusEntry != nullptr;
778 default:
779 return false;
780 }
781}
782
783SpellRange SpellEffectInfo::CalcRadius(WorldObject const* caster /*= nullptr*/, SpellTargetIndex targetIndex /*=SpellTargetIndex::TargetA*/, Spell* spell /*= nullptr*/) const
784{
785 // TargetA -> TargetARadiusEntry
786 // TargetB -> TargetBRadiusEntry
787 // Aura effects have TargetARadiusEntry == TargetBRadiusEntry (mostly)
790 if (targetIndex == SpellTargetIndex::TargetB && HasRadius(targetIndex))
791 {
792 target = TargetB;
793 entry = TargetBRadiusEntry;
794 }
795
796 SpellRange radius;
797 if (!entry)
798 return radius;
799
800 radius = { .Min = entry->RadiusMin, .Max = entry->RadiusMax };
801
802 if (caster)
803 {
804 if (Unit const* casterUnit = caster->ToUnit())
805 radius.Max = std::min(entry->Radius + entry->RadiusPerLevel * casterUnit->GetLevel(), radius.Max);
806
807 if (Player* modOwner = caster->GetSpellModOwner())
808 modOwner->ApplySpellMod(_spellInfo, SpellModOp::Radius, radius.Max, spell);
809
811 {
812 if (Unit const* casterUnit = caster->ToUnit(); casterUnit && Spell::CanIncreaseRangeByMovement(casterUnit))
813 {
814 radius.Min = std::max(radius.Min - 2.0f, 0.0f);
815 radius.Max += 2.0f;
816 }
817 }
818 }
819
820 // Random targets use random value between RadiusMin and RadiusMax
821 // For other cases, client uses RadiusMax if RadiusMin is 0
822 if (target.GetTarget() == TARGET_DEST_CASTER_RANDOM ||
825 radius.Max = (radius.Max - radius.Min) * std::sqrt(rand_norm());
826
827 return radius;
828}
829
834
835uint32 SpellEffectInfo::GetMissingTargetMask(bool srcSet /*= false*/, bool dstSet /*= false*/, uint32 mask /*=0*/) const
836{
837 uint32 effImplicitTargetMask = GetTargetFlagMask(GetUsedTargetObjectType());
838 uint32 providedTargetMask = GetProvidedTargetMask() | mask;
839
840 // remove all flags covered by effect target mask
841 if (providedTargetMask & TARGET_FLAG_UNIT_MASK)
842 effImplicitTargetMask &= ~(TARGET_FLAG_UNIT_MASK);
843 if (providedTargetMask & TARGET_FLAG_CORPSE_MASK)
844 effImplicitTargetMask &= ~(TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK);
845 if (providedTargetMask & TARGET_FLAG_GAMEOBJECT_ITEM)
847 if (providedTargetMask & TARGET_FLAG_GAMEOBJECT)
848 effImplicitTargetMask &= ~(TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM);
849 if (providedTargetMask & TARGET_FLAG_ITEM)
850 effImplicitTargetMask &= ~(TARGET_FLAG_ITEM | TARGET_FLAG_GAMEOBJECT_ITEM);
851 if (dstSet || providedTargetMask & TARGET_FLAG_DEST_LOCATION)
852 effImplicitTargetMask &= ~(TARGET_FLAG_DEST_LOCATION);
853 if (srcSet || providedTargetMask & TARGET_FLAG_SOURCE_LOCATION)
854 effImplicitTargetMask &= ~(TARGET_FLAG_SOURCE_LOCATION);
855
856 return effImplicitTargetMask;
857}
858
863
865{
866 return _data[Effect].UsedTargetObjectType;
867}
868
870{
871 switch (Effect)
872 {
884 if (MiscValue == POWER_MANA)
900 switch (ApplyAuraName)
901 {
945 if (MiscValue == POWER_MANA)
948 default:
949 break;
950 }
951 break;
952 default:
953 break;
954 }
955
957}
958
959std::array<SpellEffectInfo::StaticData, TOTAL_SPELL_EFFECTS> SpellEffectInfo::_data =
960{ {
961 // implicit target type used target object type
963 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 1 SPELL_EFFECT_INSTAKILL
964 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 2 SPELL_EFFECT_SCHOOL_DAMAGE
965 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 3 SPELL_EFFECT_DUMMY
966 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 4 SPELL_EFFECT_PORTAL_TELEPORT
968 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 6 SPELL_EFFECT_APPLY_AURA
969 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 7 SPELL_EFFECT_ENVIRONMENTAL_DAMAGE
970 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 8 SPELL_EFFECT_POWER_DRAIN
971 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 9 SPELL_EFFECT_HEALTH_LEECH
974 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 12 SPELL_EFFECT_PORTAL
975 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 13 SPELL_EFFECT_TELEPORT_TO_RETURN_POINT
976 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 14 SPELL_EFFECT_INCREASE_CURRENCY_CAP
977 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 15 SPELL_EFFECT_TELEPORT_WITH_SPELL_VISUAL_KIT_LOADING_SCREEN
978 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 16 SPELL_EFFECT_QUEST_COMPLETE
979 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 17 SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
981 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 19 SPELL_EFFECT_ADD_EXTRA_ATTACKS
982 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 20 SPELL_EFFECT_DODGE
983 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 21 SPELL_EFFECT_EVADE
984 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 22 SPELL_EFFECT_PARRY
985 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 23 SPELL_EFFECT_BLOCK
986 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 24 SPELL_EFFECT_CREATE_ITEM
987 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 25 SPELL_EFFECT_WEAPON
988 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 26 SPELL_EFFECT_DEFENSE
989 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 27 SPELL_EFFECT_PERSISTENT_AREA_AURA
990 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 28 SPELL_EFFECT_SUMMON
992 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 30 SPELL_EFFECT_ENERGIZE
993 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 31 SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
994 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 32 SPELL_EFFECT_TRIGGER_MISSILE
996 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 34 SPELL_EFFECT_SUMMON_CHANGE_ITEM
997 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 35 SPELL_EFFECT_APPLY_AREA_AURA_PARTY
998 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 36 SPELL_EFFECT_LEARN_SPELL
999 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 37 SPELL_EFFECT_SPELL_DEFENSE
1000 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 38 SPELL_EFFECT_DISPEL
1001 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 39 SPELL_EFFECT_LANGUAGE
1002 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 40 SPELL_EFFECT_DUAL_WIELD
1004 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 42 SPELL_EFFECT_JUMP_DEST
1005 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 43 SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
1006 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 44 SPELL_EFFECT_SKILL_STEP
1007 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 45 SPELL_EFFECT_ADD_HONOR
1008 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 46 SPELL_EFFECT_SPAWN
1009 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 47 SPELL_EFFECT_TRADE_SKILL
1010 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 48 SPELL_EFFECT_STEALTH
1011 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 49 SPELL_EFFECT_DETECT
1012 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 50 SPELL_EFFECT_TRANS_DOOR
1013 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 51 SPELL_EFFECT_FORCE_CRITICAL_HIT
1014 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 52 SPELL_EFFECT_SET_MAX_BATTLE_PET_COUNT
1015 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 53 SPELL_EFFECT_ENCHANT_ITEM
1016 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 54 SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
1017 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 55 SPELL_EFFECT_TAMECREATURE
1018 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 56 SPELL_EFFECT_SUMMON_PET
1019 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 57 SPELL_EFFECT_LEARN_PET_SPELL
1020 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 58 SPELL_EFFECT_WEAPON_DAMAGE
1021 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 59 SPELL_EFFECT_CREATE_RANDOM_ITEM
1022 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 60 SPELL_EFFECT_PROFICIENCY
1023 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 61 SPELL_EFFECT_SEND_EVENT
1024 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 62 SPELL_EFFECT_POWER_BURN
1025 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 63 SPELL_EFFECT_THREAT
1026 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 64 SPELL_EFFECT_TRIGGER_SPELL
1027 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 65 SPELL_EFFECT_APPLY_AREA_AURA_RAID
1028 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 66 SPELL_EFFECT_RECHARGE_ITEM
1029 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 67 SPELL_EFFECT_HEAL_MAX_HEALTH
1030 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 68 SPELL_EFFECT_INTERRUPT_CAST
1032 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 70 SPELL_EFFECT_COMPLETE_AND_REWARD_WORLD_QUEST
1033 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 71 SPELL_EFFECT_PICKPOCKET
1034 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 72 SPELL_EFFECT_ADD_FARSIGHT
1035 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 73 SPELL_EFFECT_UNTRAIN_TALENTS
1036 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 74 SPELL_EFFECT_APPLY_GLYPH
1037 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 75 SPELL_EFFECT_HEAL_MECHANICAL
1038 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 76 SPELL_EFFECT_SUMMON_OBJECT_WILD
1039 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 77 SPELL_EFFECT_SCRIPT_EFFECT
1040 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 78 SPELL_EFFECT_ATTACK
1041 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 79 SPELL_EFFECT_SANCTUARY
1042 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 80 SPELL_EFFECT_MODIFY_FOLLOWER_ITEM_LEVEL
1043 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 81 SPELL_EFFECT_PUSH_ABILITY_TO_ACTION_BAR
1044 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 82 SPELL_EFFECT_BIND_SIGHT
1046 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 84 SPELL_EFFECT_STUCK
1047 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 85 SPELL_EFFECT_SUMMON_PLAYER
1048 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 86 SPELL_EFFECT_ACTIVATE_OBJECT
1049 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 87 SPELL_EFFECT_GAMEOBJECT_DAMAGE
1050 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 88 SPELL_EFFECT_GAMEOBJECT_REPAIR
1051 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 89 SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
1052 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 90 SPELL_EFFECT_KILL_CREDIT
1053 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 91 SPELL_EFFECT_THREAT_ALL
1054 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM
1055 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 93 SPELL_EFFECT_FORCE_DESELECT
1056 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 94 SPELL_EFFECT_SELF_RESURRECT
1057 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 95 SPELL_EFFECT_SKINNING
1058 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 96 SPELL_EFFECT_CHARGE
1059 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 97 SPELL_EFFECT_CAST_BUTTON
1060 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 98 SPELL_EFFECT_KNOCK_BACK
1061 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 99 SPELL_EFFECT_DISENCHANT
1062 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 100 SPELL_EFFECT_INEBRIATE
1063 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 101 SPELL_EFFECT_FEED_PET
1064 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 102 SPELL_EFFECT_DISMISS_PET
1065 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 103 SPELL_EFFECT_REPUTATION
1066 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 104 SPELL_EFFECT_SUMMON_OBJECT_SLOT1
1067 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 105 SPELL_EFFECT_SURVEY
1068 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 106 SPELL_EFFECT_CHANGE_RAID_MARKER
1069 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 107 SPELL_EFFECT_SHOW_CORPSE_LOOT
1070 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 108 SPELL_EFFECT_DISPEL_MECHANIC
1071 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 109 SPELL_EFFECT_RESURRECT_PET
1072 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 110 SPELL_EFFECT_DESTROY_ALL_TOTEMS
1073 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 111 SPELL_EFFECT_DURABILITY_DAMAGE
1075 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 113 SPELL_EFFECT_CANCEL_CONVERSATION
1076 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 114 SPELL_EFFECT_ATTACK_ME
1077 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 115 SPELL_EFFECT_DURABILITY_DAMAGE_PCT
1078 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_CORPSE_ENEMY}, // 116 SPELL_EFFECT_SKIN_PLAYER_CORPSE
1079 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 117 SPELL_EFFECT_SPIRIT_HEAL
1080 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 118 SPELL_EFFECT_SKILL
1081 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 119 SPELL_EFFECT_APPLY_AREA_AURA_PET
1082 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 120 SPELL_EFFECT_TELEPORT_GRAVEYARD
1083 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 121 SPELL_EFFECT_NORMALIZED_WEAPON_DMG
1084 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 122 SPELL_EFFECT_122
1085 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 123 SPELL_EFFECT_SEND_TAXI
1086 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 124 SPELL_EFFECT_PULL_TOWARDS
1087 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 125 SPELL_EFFECT_MODIFY_THREAT_PERCENT
1088 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 126 SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
1089 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 127 SPELL_EFFECT_PROSPECTING
1090 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 128 SPELL_EFFECT_APPLY_AREA_AURA_FRIEND
1091 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
1092 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 130 SPELL_EFFECT_REDIRECT_THREAT
1093 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 131 SPELL_EFFECT_PLAY_SOUND
1094 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 132 SPELL_EFFECT_PLAY_MUSIC
1095 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 133 SPELL_EFFECT_UNLEARN_SPECIALIZATION
1096 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 134 SPELL_EFFECT_KILL_CREDIT2
1097 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 135 SPELL_EFFECT_CALL_PET
1098 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 136 SPELL_EFFECT_HEAL_PCT
1099 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 137 SPELL_EFFECT_ENERGIZE_PCT
1100 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 138 SPELL_EFFECT_LEAP_BACK
1101 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 139 SPELL_EFFECT_CLEAR_QUEST
1102 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 140 SPELL_EFFECT_FORCE_CAST
1103 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 141 SPELL_EFFECT_FORCE_CAST_WITH_VALUE
1104 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
1105 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER
1106 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 144 SPELL_EFFECT_KNOCK_BACK_DEST
1107 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 145 SPELL_EFFECT_PULL_TOWARDS_DEST
1108 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 146 SPELL_EFFECT_RESTORE_GARRISON_TROOP_VITALITY
1109 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 147 SPELL_EFFECT_QUEST_FAIL
1110 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 148 SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
1111 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 149 SPELL_EFFECT_CHARGE_DEST
1112 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 150 SPELL_EFFECT_QUEST_START
1113 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 151 SPELL_EFFECT_TRIGGER_SPELL_2
1114 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 152 SPELL_EFFECT_SUMMON_RAF_FRIEND
1115 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 153 SPELL_EFFECT_CREATE_TAMED_PET
1116 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 154 SPELL_EFFECT_DISCOVER_TAXI
1117 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 155 SPELL_EFFECT_TITAN_GRIP
1118 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 156 SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
1119 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 157 SPELL_EFFECT_CREATE_LOOT
1120 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 158 SPELL_EFFECT_MILLING
1121 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 159 SPELL_EFFECT_ALLOW_RENAME_PET
1122 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 160 SPELL_EFFECT_FORCE_CAST_2
1123 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 161 SPELL_EFFECT_TALENT_SPEC_COUNT
1124 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 162 SPELL_EFFECT_TALENT_SPEC_SELECT
1125 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 163 SPELL_EFFECT_OBLITERATE_ITEM
1126 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 164 SPELL_EFFECT_REMOVE_AURA
1127 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 165 SPELL_EFFECT_DAMAGE_FROM_MAX_HEALTH_PCT
1128 {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 166 SPELL_EFFECT_GIVE_CURRENCY
1129 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 167 SPELL_EFFECT_UPDATE_PLAYER_PHASE
1130 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 168 SPELL_EFFECT_ALLOW_CONTROL_PET
1131 {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 169 SPELL_EFFECT_DESTROY_ITEM
1132 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 170 SPELL_EFFECT_UPDATE_ZONE_AURAS_AND_PHASES
1133 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 171 SPELL_EFFECT_SUMMON_PERSONAL_GAMEOBJECT
1134 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_CORPSE_ALLY}, // 172 SPELL_EFFECT_RESURRECT_WITH_AURA
1135 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 173 SPELL_EFFECT_UNLOCK_GUILD_VAULT_TAB
1136 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 174 SPELL_EFFECT_APPLY_AURA_ON_PET
1137 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 175 SPELL_EFFECT_175
1138 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 176 SPELL_EFFECT_SANCTUARY_2
1139 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 177 SPELL_EFFECT_DESPAWN_PERSISTENT_AREA_AURA
1140 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 178 SPELL_EFFECT_178
1141 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 179 SPELL_EFFECT_CREATE_AREATRIGGER
1142 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 180 SPELL_EFFECT_UPDATE_AREATRIGGER
1143 {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 181 SPELL_EFFECT_REMOVE_TALENT
1144 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 182 SPELL_EFFECT_DESPAWN_AREATRIGGER
1145 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 183 SPELL_EFFECT_183
1146 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 184 SPELL_EFFECT_REPUTATION_2
1147 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 185 SPELL_EFFECT_185
1148 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 186 SPELL_EFFECT_186
1149 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 187 SPELL_EFFECT_RANDOMIZE_ARCHAEOLOGY_DIGSITES
1150 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 188 SPELL_EFFECT_SUMMON_STABLED_PET_AS_GUARDIAN
1151 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 189 SPELL_EFFECT_LOOT
1152 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 190 SPELL_EFFECT_CHANGE_PARTY_MEMBERS
1153 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 191 SPELL_EFFECT_TELEPORT_TO_DIGSITE
1154 {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 192 SPELL_EFFECT_UNCAGE_BATTLEPET
1155 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 193 SPELL_EFFECT_START_PET_BATTLE
1156 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 194 SPELL_EFFECT_194
1157 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 195 SPELL_EFFECT_PLAY_SCENE_SCRIPT_PACKAGE
1158 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 196 SPELL_EFFECT_CREATE_SCENE_OBJECT
1159 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 197 SPELL_EFFECT_CREATE_PERSONAL_SCENE_OBJECT
1160 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 198 SPELL_EFFECT_PLAY_SCENE
1161 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 199 SPELL_EFFECT_DESPAWN_SUMMON
1162 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 200 SPELL_EFFECT_HEAL_BATTLEPET_PCT
1163 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 201 SPELL_EFFECT_ENABLE_BATTLE_PETS
1164 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 202 SPELL_EFFECT_APPLY_AREA_AURA_SUMMONS
1165 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 203 SPELL_EFFECT_REMOVE_AURA_2
1166 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 204 SPELL_EFFECT_CHANGE_BATTLEPET_QUALITY
1167 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 205 SPELL_EFFECT_LAUNCH_QUEST_CHOICE
1168 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 206 SPELL_EFFECT_ALTER_IETM
1169 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 207 SPELL_EFFECT_LAUNCH_QUEST_TASK
1170 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 208 SPELL_EFFECT_SET_REPUTATION
1171 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 209 SPELL_EFFECT_209
1172 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 210 SPELL_EFFECT_LEARN_GARRISON_BUILDING
1173 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 211 SPELL_EFFECT_LEARN_GARRISON_SPECIALIZATION
1174 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 212 SPELL_EFFECT_REMOVE_AURA_BY_SPELL_LABEL
1175 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 213 SPELL_EFFECT_JUMP_DEST_2
1176 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 214 SPELL_EFFECT_CREATE_GARRISON
1177 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 215 SPELL_EFFECT_UPGRADE_CHARACTER_SPELLS
1178 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 216 SPELL_EFFECT_CREATE_SHIPMENT
1179 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 217 SPELL_EFFECT_UPGRADE_GARRISON
1180 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 218 SPELL_EFFECT_218
1181 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 219 SPELL_EFFECT_CREATE_CONVERSATION
1182 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 220 SPELL_EFFECT_ADD_GARRISON_FOLLOWER
1183 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 221 SPELL_EFFECT_ADD_GARRISON_MISSION
1184 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 222 SPELL_EFFECT_CREATE_HEIRLOOM_ITEM
1185 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 223 SPELL_EFFECT_CHANGE_ITEM_BONUSES
1186 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 224 SPELL_EFFECT_ACTIVATE_GARRISON_BUILDING
1187 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 225 SPELL_EFFECT_GRANT_BATTLEPET_LEVEL
1188 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 226 SPELL_EFFECT_TRIGGER_ACTION_SET
1189 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 227 SPELL_EFFECT_TELEPORT_TO_LFG_DUNGEON
1190 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 228 SPELL_EFFECT_228
1191 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 229 SPELL_EFFECT_SET_FOLLOWER_QUALITY
1193 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 231 SPELL_EFFECT_INCREASE_FOLLOWER_EXPERIENCE
1194 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 232 SPELL_EFFECT_REMOVE_PHASE
1195 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 233 SPELL_EFFECT_RANDOMIZE_FOLLOWER_ABILITIES
1196 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 234 SPELL_EFFECT_234
1197 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 235 SPELL_EFFECT_235
1198 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 236 SPELL_EFFECT_GIVE_EXPERIENCE
1199 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 237 SPELL_EFFECT_GIVE_RESTED_EXPERIENCE_BONUS
1200 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 238 SPELL_EFFECT_INCREASE_SKILL
1201 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 239 SPELL_EFFECT_END_GARRISON_BUILDING_CONSTRUCTION
1202 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 240 SPELL_EFFECT_GIVE_ARTIFACT_POWER
1203 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 241 SPELL_EFFECT_241
1204 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 242 SPELL_EFFECT_GIVE_ARTIFACT_POWER_NO_BONUS
1205 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 243 SPELL_EFFECT_APPLY_ENCHANT_ILLUSION
1206 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 244 SPELL_EFFECT_LEARN_FOLLOWER_ABILITY
1207 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 245 SPELL_EFFECT_UPGRADE_HEIRLOOM
1208 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 246 SPELL_EFFECT_FINISH_GARRISON_MISSION
1209 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 247 SPELL_EFFECT_ADD_GARRISON_MISSION_SET
1210 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 248 SPELL_EFFECT_FINISH_SHIPMENT
1211 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 249 SPELL_EFFECT_FORCE_EQUIP_ITEM
1212 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 250 SPELL_EFFECT_TAKE_SCREENSHOT
1213 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 251 SPELL_EFFECT_SET_GARRISON_CACHE_SIZE
1214 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 252 SPELL_EFFECT_TELEPORT_UNITS
1215 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 253 SPELL_EFFECT_GIVE_HONOR
1216 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 254 SPELL_EFFECT_JUMP_CHARGE
1217 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 255 SPELL_EFFECT_LEARN_TRANSMOG_SET
1218 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 256 SPELL_EFFECT_256
1219 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 257 SPELL_EFFECT_257
1220 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 258 SPELL_EFFECT_MODIFY_KEYSTONE
1221 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 259 SPELL_EFFECT_RESPEC_AZERITE_EMPOWERED_ITEM
1222 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 260 SPELL_EFFECT_SUMMON_STABLED_PET
1223 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 261 SPELL_EFFECT_SCRAP_ITEM
1224 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 262 SPELL_EFFECT_262
1225 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 263 SPELL_EFFECT_REPAIR_ITEM
1226 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 264 SPELL_EFFECT_REMOVE_GEM
1227 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 265 SPELL_EFFECT_LEARN_AZERITE_ESSENCE_POWER
1228 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 266 SPELL_EFFECT_SET_ITEM_BONUS_LIST_GROUP_ENTRY
1229 {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 267 SPELL_EFFECT_CREATE_PRIVATE_CONVERSATION
1230 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 268 SPELL_EFFECT_APPLY_MOUNT_EQUIPMENT
1231 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 269 SPELL_EFFECT_INCREASE_ITEM_BONUS_LIST_GROUP_STEP
1233 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 271 SPELL_EFFECT_APPLY_AREA_AURA_PARTY_NONRANDOM
1234 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 272 SPELL_EFFECT_SET_COVENANT
1235 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 273 SPELL_EFFECT_CRAFT_RUNEFORGE_LEGENDARY
1236 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 274 SPELL_EFFECT_274
1237 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 275 SPELL_EFFECT_275
1238 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 276 SPELL_EFFECT_LEARN_TRANSMOG_ILLUSION
1239 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 277 SPELL_EFFECT_SET_CHROMIE_TIME
1240 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 278 SPELL_EFFECT_278
1241 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 279 SPELL_EFFECT_LEARN_GARR_TALENT
1242 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 280 SPELL_EFFECT_280
1243 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 281 SPELL_EFFECT_LEARN_SOULBIND_CONDUIT
1244 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 282 SPELL_EFFECT_CONVERT_ITEMS_TO_CURRENCY
1245 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 283 SPELL_EFFECT_COMPLETE_CAMPAIGN
1246 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 284 SPELL_EFFECT_SEND_CHAT_MESSAGE
1247 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 285 SPELL_EFFECT_MODIFY_KEYSTONE_2
1248 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 286 SPELL_EFFECT_GRANT_BATTLEPET_EXPERIENCE
1249 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 287 SPELL_EFFECT_SET_GARRISON_FOLLOWER_LEVEL
1250 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 288 SPELL_EFFECT_CRAFT_ITEM
1251 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 289 SPELL_EFFECT_MODIFY_AURA_STACKS
1252 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 290 SPELL_EFFECT_MODIFY_COOLDOWN
1253 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 291 SPELL_EFFECT_MODIFY_COOLDOWNS
1254 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 292 SPELL_EFFECT_MODIFY_COOLDOWNS_BY_CATEGORY
1255 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 293 SPELL_EFFECT_MODIFY_CHARGES
1256 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 294 SPELL_EFFECT_CRAFT_LOOT
1257 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 295 SPELL_EFFECT_SALVAGE_ITEM
1258 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 296 SPELL_EFFECT_CRAFT_SALVAGE_ITEM
1259 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 297 SPELL_EFFECT_RECRAFT_ITEM
1260 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 298 SPELL_EFFECT_CANCEL_ALL_PRIVATE_CONVERSATIONS
1261 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 299 SPELL_EFFECT_299
1262 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 300 SPELL_EFFECT_300
1263 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 301 SPELL_EFFECT_CRAFT_ENCHANT
1264 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_NONE}, // 302 SPELL_EFFECT_GATHERING
1265 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 303 SPELL_EFFECT_CREATE_TRAIT_TREE_CONFIG
1266 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 304 SPELL_EFFECT_CHANGE_ACTIVE_COMBAT_TRAIT_CONFIG
1267 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 305 SPELL_EFFECT_305
1268 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 306 SPELL_EFFECT_UPDATE_INTERACTIONS
1269 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 307 SPELL_EFFECT_307
1270 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 308 SPELL_EFFECT_CANCEL_PRELOAD_WORLD
1271 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 309 SPELL_EFFECT_PRELOAD_WORLD
1272 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 310 SPELL_EFFECT_310
1273 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 311 SPELL_EFFECT_SKIP_QUESTLINE
1274 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 312 SPELL_EFFECT_312
1275 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 313 SPELL_EFFECT_CHANGE_ITEM_BONUSES_2
1276 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 314 SPELL_EFFECT_ADD_SOCKET_BONUS
1277 {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 315 SPELL_EFFECT_LEARN_TRANSMOG_APPEARANCE_FROM_ITEM_MOD_APPEARANCE_GROUP
1278 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 316 SPELL_EFFECT_KILL_CREDIT_LABEL_1
1279 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 317 SPELL_EFFECT_KILL_CREDIT_LABEL_2
1280 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 318 SPELL_EFFECT_318
1281 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 319 SPELL_EFFECT_319
1282 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 320 SPELL_EFFECT_320
1283 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 321 SPELL_EFFECT_321
1284 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 322 SPELL_EFFECT_322
1285 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 323 SPELL_EFFECT_323
1286 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 324 SPELL_EFFECT_324
1287 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 325 SPELL_EFFECT_325
1288 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 326 SPELL_EFFECT_326
1289 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 327 SPELL_EFFECT_327
1290 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 328 SPELL_EFFECT_328
1291 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 329 SPELL_EFFECT_329
1292 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 330 SPELL_EFFECT_330
1293 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 331 SPELL_EFFECT_331
1294 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 332 SPELL_EFFECT_332
1295 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 333 SPELL_EFFECT_333
1296 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 334 SPELL_EFFECT_334
1297 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 335 SPELL_EFFECT_SET_PLAYER_DATA_ELEMENT_ACCOUNT
1298 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 336 SPELL_EFFECT_SET_PLAYER_DATA_ELEMENT_CHARACTER
1299 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 337 SPELL_EFFECT_SET_PLAYER_DATA_FLAG_ACCOUNT
1300 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 338 SPELL_EFFECT_SET_PLAYER_DATA_FLAG_CHARACTER
1301 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 339 SPELL_EFFECT_UI_ACTION
1302 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 340 SPELL_EFFECT_340
1303 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 341 SPELL_EFFECT_LEARN_WARBAND_SCENE
1304 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 342 SPELL_EFFECT_342
1305 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 343 SPELL_EFFECT_343
1306 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 344 SPELL_EFFECT_344
1307 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 345 SPELL_EFFECT_ASSIST_ACTION
1308 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 346 SPELL_EFFECT_346
1309 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 347 SPELL_EFFECT_EQUIP_TRANSMOG_OUTFIT
1310 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 348 SPELL_EFFECT_GIVE_HOUSE_LEVEL
1311 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 349 SPELL_EFFECT_LEARN_HOUSE_ROOM
1312 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 350 SPELL_EFFECT_LEARN_HOUSE_EXTERIOR_COMPONENT
1313 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 351 SPELL_EFFECT_LEARN_HOUSE_THEME
1314 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 352 SPELL_EFFECT_LEARN_HOUSE_ROOM_COMPONENT_TEXTURE
1315 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 353 SPELL_EFFECT_CREATE_AREATRIGGER_2
1316 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 354 SPELL_EFFECT_SET_NEIGHBORHOOD_INITIATIVE
1317 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 355 SPELL_EFFECT_LEARN_HOUSE_TYPE
1318 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 356 SPELL_EFFECT_356
1322} };
1323
1325 : Id(spellName->ID), Difficulty(difficulty)
1326{
1327 _effects.reserve(32);
1328 for (SpellEffectEntry const* spellEffect : data.Effects)
1329 {
1330 if (!spellEffect)
1331 continue;
1332
1333 Trinity::Containers::EnsureWritableVectorIndex(_effects, spellEffect->EffectIndex) = SpellEffectInfo(this, *spellEffect);
1334 }
1335
1336 // Correct EffectIndex for blank effects
1337 for (size_t i = 0; i < _effects.size(); ++i)
1338 {
1339 _effects[i]._spellInfo = this;
1340 _effects[i].EffectIndex = SpellEffIndex(i);
1341 }
1342
1343 _effects.shrink_to_fit();
1344
1345 SpellName = &spellName->Name;
1346
1347 // SpellMiscEntry
1348 if (SpellMiscEntry const* _misc = data.Misc)
1349 {
1350 Attributes = _misc->Attributes[0];
1351 AttributesEx = _misc->Attributes[1];
1352 AttributesEx2 = _misc->Attributes[2];
1353 AttributesEx3 = _misc->Attributes[3];
1354 AttributesEx4 = _misc->Attributes[4];
1355 AttributesEx5 = _misc->Attributes[5];
1356 AttributesEx6 = _misc->Attributes[6];
1357 AttributesEx7 = _misc->Attributes[7];
1358 AttributesEx8 = _misc->Attributes[8];
1359 AttributesEx9 = _misc->Attributes[9];
1360 AttributesEx10 = _misc->Attributes[10];
1361 AttributesEx11 = _misc->Attributes[11];
1362 AttributesEx12 = _misc->Attributes[12];
1363 AttributesEx13 = _misc->Attributes[13];
1364 AttributesEx14 = _misc->Attributes[14];
1365 AttributesEx15 = _misc->Attributes[15];
1366 AttributesEx16 = _misc->Attributes[16];
1367 CastTimeEntry = sSpellCastTimesStore.LookupEntry(_misc->CastingTimeIndex);
1368 DurationEntry = sSpellDurationStore.LookupEntry(_misc->DurationIndex);
1369 RangeEntry = sSpellRangeStore.LookupEntry(_misc->RangeIndex);
1370 Speed = _misc->Speed;
1371 LaunchDelay = _misc->LaunchDelay;
1372 MinDuration = _misc->MinDuration;
1373 SchoolMask = _misc->SchoolMask;
1374 IconFileDataId = _misc->SpellIconFileDataID;
1375 ActiveIconFileDataId = _misc->ActiveIconFileDataID;
1376 ContentTuningId = _misc->ContentTuningID;
1377 ShowFutureSpellPlayerConditionID = _misc->ShowFutureSpellPlayerConditionID;
1378 }
1379
1380 // SpellScalingEntry
1381 if (SpellScalingEntry const* _scaling = data.Scaling)
1382 {
1383 Scaling.MinScalingLevel = _scaling->MinScalingLevel;
1384 Scaling.MaxScalingLevel = _scaling->MaxScalingLevel;
1385 }
1386
1387 // SpellAuraOptionsEntry
1388 if (SpellAuraOptionsEntry const* _options = data.AuraOptions)
1389 {
1390 ProcFlags = _options->ProcTypeMask;
1391 ProcChance = _options->ProcChance;
1392 ProcCharges = _options->ProcCharges;
1393 ProcCooldown = _options->ProcCategoryRecovery;
1394 StackAmount = _options->CumulativeAura;
1395 if (SpellProcsPerMinuteEntry const* _ppm = sSpellProcsPerMinuteStore.LookupEntry(_options->SpellProcsPerMinuteID))
1396 {
1397 ProcBasePPM = _ppm->BaseProcRate;
1398 ProcPPMMods = sDB2Manager.GetSpellProcsPerMinuteMods(_ppm->ID);
1399 }
1400 }
1401
1402 // SpellAuraRestrictionsEntry
1403 if (SpellAuraRestrictionsEntry const* _aura = data.AuraRestrictions)
1404 {
1405 CasterAuraState = _aura->CasterAuraState;
1406 TargetAuraState = _aura->TargetAuraState;
1407 ExcludeCasterAuraState = _aura->ExcludeCasterAuraState;
1408 ExcludeTargetAuraState = _aura->ExcludeTargetAuraState;
1409 CasterAuraSpell = _aura->CasterAuraSpell;
1410 TargetAuraSpell = _aura->TargetAuraSpell;
1411 ExcludeCasterAuraSpell = _aura->ExcludeCasterAuraSpell;
1412 ExcludeTargetAuraSpell = _aura->ExcludeTargetAuraSpell;
1413 CasterAuraType = AuraType(_aura->CasterAuraType);
1414 TargetAuraType = AuraType(_aura->TargetAuraType);
1415 ExcludeCasterAuraType = AuraType(_aura->ExcludeCasterAuraType);
1416 ExcludeTargetAuraType = AuraType(_aura->ExcludeTargetAuraType);
1417 }
1418
1419 // SpellCastingRequirementsEntry
1420 if (SpellCastingRequirementsEntry const* _castreq = data.CastingRequirements)
1421 {
1422 RequiresSpellFocus = _castreq->RequiresSpellFocus;
1423 FacingCasterFlags = _castreq->FacingCasterFlags;
1424 RequiredAreasID = _castreq->RequiredAreasID;
1425 }
1426
1427 // SpellCategoriesEntry
1428 if (SpellCategoriesEntry const* _categories = data.Categories)
1429 {
1430 CategoryId = _categories->Category;
1431 Dispel = _categories->DispelType;
1432 Mechanic = _categories->Mechanic;
1433 StartRecoveryCategory = _categories->StartRecoveryCategory;
1434 DmgClass = _categories->DefenseType;
1435 PreventionType = _categories->PreventionType;
1436 ChargeCategoryId = _categories->ChargeCategory;
1437 }
1438
1439 // SpellClassOptionsEntry
1440 if (SpellClassOptionsEntry const* _class = data.ClassOptions)
1441 {
1442 SpellFamilyName = _class->SpellClassSet;
1443 SpellFamilyFlags = _class->SpellClassMask;
1444 }
1445
1446 // SpellCooldownsEntry
1447 if (SpellCooldownsEntry const* _cooldowns = data.Cooldowns)
1448 {
1449 RecoveryTime = _cooldowns->RecoveryTime;
1450 CategoryRecoveryTime = _cooldowns->CategoryRecoveryTime;
1451 StartRecoveryTime = _cooldowns->StartRecoveryTime;
1452 CooldownAuraSpellId = _cooldowns->AuraSpellID;
1453 }
1454
1455 // SpellEmpowerStageEntry
1456 std::ranges::transform(data.EmpowerStages, std::back_inserter(EmpowerStageThresholds), [](SpellEmpowerStageEntry const* stage) { return Milliseconds(stage->DurationMs); });
1457
1458 // SpellEquippedItemsEntry
1459 if (SpellEquippedItemsEntry const* _equipped = data.EquippedItems)
1460 {
1461 EquippedItemClass = _equipped->EquippedItemClass;
1462 EquippedItemSubClassMask = _equipped->EquippedItemSubclass;
1463 EquippedItemInventoryTypeMask = _equipped->EquippedItemInvTypes;
1464 }
1465
1466 // SpellInterruptsEntry
1467 if (SpellInterruptsEntry const* _interrupt = data.Interrupts)
1468 {
1469 InterruptFlags = SpellInterruptFlags(_interrupt->InterruptFlags);
1470 AuraInterruptFlags = SpellAuraInterruptFlags(_interrupt->AuraInterruptFlags[0]);
1471 AuraInterruptFlags2 = SpellAuraInterruptFlags2(_interrupt->AuraInterruptFlags[1]);
1472 ChannelInterruptFlags = SpellAuraInterruptFlags(_interrupt->ChannelInterruptFlags[0]);
1473 ChannelInterruptFlags2 = SpellAuraInterruptFlags2(_interrupt->ChannelInterruptFlags[1]);
1474 }
1475
1476 for (SpellLabelEntry const* label : data.Labels)
1477 Labels.insert(label->LabelID);
1478
1479 // SpellLevelsEntry
1480 if (SpellLevelsEntry const* _levels = data.Levels)
1481 {
1482 MaxLevel = _levels->MaxLevel;
1483 BaseLevel = _levels->BaseLevel;
1484 SpellLevel = _levels->SpellLevel;
1485 }
1486
1487 // SpellPowerEntry
1488 PowerCosts = data.Powers;
1489
1490 // SpellReagentsEntry
1491 if (SpellReagentsEntry const* _reagents = data.Reagents)
1492 {
1493 Reagent = _reagents->Reagent;
1494 ReagentCount = _reagents->ReagentCount;
1495 }
1496
1498
1499 // SpellShapeshiftEntry
1500 if (SpellShapeshiftEntry const* _shapeshift = data.Shapeshift)
1501 {
1502 Stances = MAKE_PAIR64(_shapeshift->ShapeshiftMask[0], _shapeshift->ShapeshiftMask[1]);
1503 StancesNot = MAKE_PAIR64(_shapeshift->ShapeshiftExclude[0], _shapeshift->ShapeshiftExclude[1]);
1504 }
1505
1506 // SpellTargetRestrictionsEntry
1507 if (SpellTargetRestrictionsEntry const* _target = data.TargetRestrictions)
1508 {
1509 ConeAngle = _target->ConeDegrees;
1510 Width = _target->Width;
1511 Targets = _target->Targets;
1512 TargetCreatureType = _target->TargetCreatureType;
1513 MaxAffectedTargets = _target->MaxTargets;
1514 MaxTargetLevel = _target->MaxTargetLevel;
1515 }
1516
1517 // SpellTotemsEntry
1518 if (SpellTotemsEntry const* _totem = data.Totems)
1519 {
1520 TotemCategory = _totem->RequiredTotemCategoryID;
1521 Totem = _totem->Totem;
1522 }
1523
1524 _visuals = data.Visuals;
1525}
1526
1527SpellInfo::SpellInfo(SpellNameEntry const* spellName, ::Difficulty difficulty, std::vector<SpellEffectEntry> const& effects)
1528 : Id(spellName->ID), Difficulty(difficulty)
1529{
1530 SpellName = &spellName->Name;
1531
1532 _effects.reserve(32);
1533 for (SpellEffectEntry const& spellEffect : effects)
1534 Trinity::Containers::EnsureWritableVectorIndex(_effects, spellEffect.EffectIndex) = SpellEffectInfo(this, spellEffect);
1535
1536 // Correct EffectIndex for blank effects
1537 for (size_t i = 0; i < _effects.size(); ++i)
1538 {
1539 _effects[i]._spellInfo = this;
1540 _effects[i].EffectIndex = SpellEffIndex(i);
1541 }
1542
1543 _effects.shrink_to_fit();
1544}
1545
1550
1552{
1553 return CategoryId;
1554}
1555
1557{
1558 for (SpellEffectInfo const& eff : GetEffects())
1559 if (eff.IsEffect(effect))
1560 return true;
1561
1562 return false;
1563}
1564
1566{
1567 for (SpellEffectInfo const& effect : GetEffects())
1568 if (effect.IsAura(aura))
1569 return true;
1570
1571 return false;
1572}
1573
1575{
1576 for (SpellEffectInfo const& effect : GetEffects())
1577 if (effect.IsAreaAuraEffect())
1578 return true;
1579
1580 return false;
1581}
1582
1584{
1585 for (SpellEffectInfo const& effect : GetEffects())
1586 {
1587 if (effect.IsEffect())
1588 {
1589 switch (effect.Effect)
1590 {
1599 continue;
1600 default:
1601 return false;
1602 }
1603 }
1604 }
1605
1606 return true;
1607}
1608
1610{
1611 for (SpellEffectInfo const& effect : GetEffects())
1612 if (effect.TargetA.GetTarget() == target || effect.TargetB.GetTarget() == target)
1613 return true;
1614
1615 return false;
1616}
1617
1618bool SpellInfo::CanBeInterrupted(WorldObject const* interruptCaster, Unit const* interruptTarget, bool ignoreImmunity /*= false*/) const
1619{
1624 || (interruptCaster && interruptCaster->IsUnit() && interruptCaster->ToUnit()->HasAuraTypeWithMiscvalue(SPELL_AURA_ALLOW_INTERRUPT_SPELL, Id))
1625 || ((!(interruptTarget->GetMechanicImmunityMask() & (1 << MECHANIC_INTERRUPT)) || ignoreImmunity)
1628}
1629
1634
1636{
1637 if (GetEffects().size() < 2)
1638 return false;
1639
1643 || Id == 64323;
1644}
1645
1650
1652{
1653 for (SpellEffectInfo const& effect : GetEffects())
1654 {
1655 if (effect.Effect == SPELL_EFFECT_SKILL)
1656 {
1657 uint32 skill = effect.MiscValue;
1658
1659 if (IsProfessionSkill(skill))
1660 return true;
1661 }
1662 }
1663 return false;
1664}
1665
1667{
1668 for (SpellEffectInfo const& effect : GetEffects())
1669 {
1670 if (effect.Effect == SPELL_EFFECT_SKILL)
1671 {
1672 uint32 skill = effect.MiscValue;
1673
1674 if (IsPrimaryProfessionSkill(skill))
1675 return true;
1676 }
1677 }
1678 return false;
1679}
1680
1682{
1683 return IsPrimaryProfession() && GetRank() == 1;
1684}
1685
1687{
1688 SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(Id);
1689
1690 for (SkillLineAbilityMap::const_iterator _spell_idx = bounds.first; _spell_idx != bounds.second; ++_spell_idx)
1691 if (_spell_idx->second->SkillLine == skillType)
1692 return true;
1693
1694 return false;
1695}
1696
1698{
1699 for (SpellEffectInfo const& effect : GetEffects())
1700 if (effect.IsEffect() && (effect.IsTargetingArea() || effect.IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) || effect.IsAreaAuraEffect()))
1701 return true;
1702
1703 return false;
1704}
1705
1706// checks if spell targets are selected from area, doesn't include spell effects in check (like area wide auras for example)
1708{
1709 for (SpellEffectInfo const& effect : GetEffects())
1710 if (effect.IsEffect() && effect.IsTargetingArea())
1711 return true;
1712
1713 return false;
1714}
1715
1720
1721bool SpellInfo::NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell) const
1722{
1724 return true;
1725
1726 /*
1727 for (SpellEffectInfo const& effect : GetEffects())
1728 {
1729 if (effect.IsEffect())
1730 {
1731 if (effect.TargetA.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CHANNEL
1732 || effect.TargetB.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CHANNEL)
1733 return true;
1734 }
1735 }
1736 */
1737
1738 if (triggeringSpell->IsChanneled())
1739 {
1740 uint32 mask = 0;
1741 for (SpellEffectInfo const& effect : GetEffects())
1742 {
1743 if (effect.TargetA.GetTarget() != TARGET_UNIT_CASTER && effect.TargetA.GetTarget() != TARGET_DEST_CASTER
1744 && effect.TargetB.GetTarget() != TARGET_UNIT_CASTER && effect.TargetB.GetTarget() != TARGET_DEST_CASTER)
1745 {
1746 mask |= effect.GetProvidedTargetMask();
1747 }
1748 }
1749
1750 if (mask & TARGET_FLAG_UNIT_MASK)
1751 return true;
1752 }
1753
1754 return false;
1755}
1756
1758{
1760}
1761
1763{
1764 if (IsPassive())
1765 return false;
1767 return false;
1768 return true;
1769}
1770
1775
1777{
1778 if (IsPassive())
1779 return false;
1780
1781 // All stance spells. if any better way, change it.
1782 switch (SpellFamilyName)
1783 {
1785 // Paladin aura Spell
1787 return false;
1788 // Seal of Righteousness
1789 if (SpellFamilyFlags[1] & 0x20000000)
1790 return false;
1791 break;
1792 case SPELLFAMILY_DRUID:
1793 // Druid form Spell
1795 return false;
1796 break;
1797 }
1798
1799 return true;
1800}
1801
1806
1808{
1809 return IsPassive() || Id == 55849 || Id == 40075 || Id == 44413; // Power Spark, Fel Flak Fire, Incanter's Absorption
1810}
1811
1817
1819{
1821 return true;
1822
1824}
1825
1827{
1828 SpellCategoryEntry const* category = sSpellCategoryStore.LookupEntry(CategoryId);
1829 return category && category->GetFlags().HasFlag(SpellCategoryFlags::CooldownEventOnLeaveCombat);
1830}
1831
1836
1841
1843{
1845 return true;
1846
1847 for (SpellEffectInfo const& effect : GetEffects())
1848 {
1849 if (!effect.IsEffect())
1850 continue;
1851
1852 if (effect.TargetA.GetObjectType() == TARGET_OBJECT_TYPE_CORPSE || effect.TargetB.GetObjectType() == TARGET_OBJECT_TYPE_CORPSE)
1853 return true;
1854 }
1855
1856 return false;
1857}
1858
1860{
1861 for (SpellEffectInfo const& effect : GetEffects())
1862 {
1863 switch (effect.TargetA.GetCheckType())
1864 {
1865 case TARGET_CHECK_PARTY:
1866 case TARGET_CHECK_RAID:
1868 return true;
1869 default:
1870 break;
1871 }
1872 }
1873
1874 return false;
1875}
1876
1882
1884{
1885 return NegativeEffects.none();
1886}
1887
1889{
1890 return !NegativeEffects.test(effIndex);
1891}
1892
1897
1902
1907
1909{
1911}
1912
1914{
1915 return (SpellFamilyName == SPELLFAMILY_HUNTER && !(SpellFamilyFlags[1] & 0x10000000)) // for 53352, cannot find better way
1918}
1919
1924
1926{
1927 return !EmpowerStageThresholds.empty();
1928}
1929
1934
1936{
1937 return Speed > 0.0f || LaunchDelay > 0.0f;
1938}
1939
1941{
1942 WeaponAttackType result;
1943 switch (DmgClass)
1944 {
1947 result = OFF_ATTACK;
1948 else
1949 result = BASE_ATTACK;
1950 break;
1953 break;
1954 default:
1955 // Wands
1957 result = RANGED_ATTACK;
1958 else
1959 result = BASE_ATTACK;
1960 break;
1961 }
1962
1963 return result;
1964}
1965
1967{
1968 // item neutral spell
1969 if (EquippedItemClass == -1)
1970 return true;
1971
1972 // item dependent spell
1973 if (item && item->IsFitToSpellRequirements(this))
1974 return true;
1975
1976 return false;
1977}
1978
1979bool SpellInfo::IsAffected(uint32 familyName, flag128 const& familyFlags) const
1980{
1981 if (!familyName)
1982 return true;
1983
1984 if (familyName != SpellFamilyName)
1985 return false;
1986
1987 if (familyFlags && !(familyFlags & SpellFamilyFlags))
1988 return false;
1989
1990 return true;
1991}
1992
1997
1999{
2000 SpellInfo const* affectSpell = sSpellMgr->GetSpellInfo(mod->spellId, Difficulty);
2001 if (!affectSpell)
2002 return false;
2003
2004 switch (mod->type)
2005 {
2006 case SPELLMOD_FLAT:
2007 case SPELLMOD_PCT:
2008 {
2009 // TEMP: dont use IsAffected - !familyName and !familyFlags are not valid options for spell mods
2010 // TODO: investigate if the !familyName and !familyFlags conditions are even valid for all other (nonmod) uses of SpellInfo::IsAffected
2011 if (affectSpell->SpellFamilyName != SpellFamilyName)
2012 return false;
2013
2014 // spell modifiers should apply as many times as number of matched SpellFamilyFlags bits (verified with spell 1218116 with modifier 384451 in patch 11.1.0 and client tooltip code since at least 3.3.5)
2015 // unknown if this is a bug or strange design choice...
2016 FlagsArray<uint32, 4> matched = static_cast<SpellModifierByClassMask const*>(mod)->mask & SpellFamilyFlags;
2017 return std::popcount(matched[0]) + std::popcount(matched[1]) + std::popcount(matched[2]) + std::popcount(matched[3]);
2018 }
2020 return HasLabel(static_cast<SpellFlatModifierByLabel const*>(mod)->value.LabelID) ? 1 : 0;
2021 case SPELLMOD_LABEL_PCT:
2022 return HasLabel(static_cast<SpellPctModifierByLabel const*>(mod)->value.LabelID) ? 1 : 0;
2023 default:
2024 break;
2025 }
2026
2027 return false;
2028}
2029
2031{
2032 switch (Id)
2033 {
2034 case 384669: // Overflowing Maelstrom
2035 return true;
2036 default:
2037 break;
2038 }
2039
2040 return false;
2041}
2042
2043bool SpellInfo::CanPierceImmuneAura(SpellInfo const* auraSpellInfo) const
2044{
2045 // Dispels other auras on immunity, check if this spell makes the unit immune to aura
2047 return true;
2048
2049 return false;
2050}
2051
2052bool SpellInfo::CanDispelAura(SpellInfo const* auraSpellInfo) const
2053{
2054 // These auras (like Divine Shield) can't be dispelled
2055 if (auraSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES))
2056 return false;
2057
2058 return true;
2059}
2060
2062{
2063 // all other single target spells have if it has AttributesEx5
2065 return true;
2066
2067 return false;
2068}
2069
2071{
2072 SpellSpecificType spellSpec1 = GetSpellSpecific();
2073 SpellSpecificType spellSpec2 = spellInfo->GetSpellSpecific();
2074 switch (spellSpec1)
2075 {
2086 return spellSpec1 == spellSpec2;
2088 return spellSpec2 == SPELL_SPECIFIC_FOOD
2089 || spellSpec2 == SPELL_SPECIFIC_FOOD_AND_DRINK;
2091 return spellSpec2 == SPELL_SPECIFIC_DRINK
2092 || spellSpec2 == SPELL_SPECIFIC_FOOD_AND_DRINK;
2094 return spellSpec2 == SPELL_SPECIFIC_FOOD
2095 || spellSpec2 == SPELL_SPECIFIC_DRINK
2096 || spellSpec2 == SPELL_SPECIFIC_FOOD_AND_DRINK;
2097 default:
2098 return false;
2099 }
2100}
2101
2103{
2104 SpellSpecificType spellSpec = GetSpellSpecific();
2105 switch (spellSpec)
2106 {
2114 return spellSpec == spellInfo->GetSpellSpecific();
2115 default:
2116 return false;
2117 }
2118}
2119
2121{
2122 // talents that learn spells can have stance requirements that need ignore
2123 // (this requirement only for client-side stance show in talent description)
2124 /* TODO: 6.x fix this in proper way (probably spell flags/attributes?)
2125 if (GetTalentSpellCost(Id) > 0 && HasEffect(SPELL_EFFECT_LEARN_SPELL))
2126 return SPELL_CAST_OK;*/
2127
2128 //if (HasAttribute(SPELL_ATTR13_ACTIVATES_REQUIRED_SHAPESHIFT))
2129 // return SPELL_CAST_OK;
2130
2131 uint64 stanceMask = (form ? UI64LIT(1) << (form - 1) : 0);
2132
2133 if (stanceMask & StancesNot) // can explicitly not be cast in this stance
2135
2136 if (stanceMask & Stances) // can explicitly be cast in this stance
2137 return SPELL_CAST_OK;
2138
2139 bool actAsShifted = false;
2140 SpellShapeshiftFormEntry const* shapeInfo = nullptr;
2141 if (form > 0)
2142 {
2143 shapeInfo = sSpellShapeshiftFormStore.LookupEntry(form);
2144 if (!shapeInfo)
2145 {
2146 TC_LOG_ERROR("spells", "GetErrorAtShapeshiftedCast: unknown shapeshift {}", form);
2147 return SPELL_CAST_OK;
2148 }
2149 actAsShifted = !shapeInfo->GetFlags().HasFlag(SpellShapeshiftFormFlags::Stance);
2150 }
2151
2152 if (actAsShifted)
2153 {
2154 if (HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFTED) || (shapeInfo && shapeInfo->GetFlags().HasFlag(SpellShapeshiftFormFlags::CanOnlyCastShapeshiftSpells))) // not while shapeshifted
2156 else if (Stances != 0) // needs other shapeshift
2158 }
2159 else
2160 {
2161 // needs shapeshift
2164 }
2165
2166 return SPELL_CAST_OK;
2167}
2168
2169SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player) const
2170{
2171 // normal case
2172 if (RequiredAreasID > 0)
2173 {
2174 bool found = false;
2175 std::vector<uint32> areaGroupMembers = sDB2Manager.GetAreasForGroup(RequiredAreasID);
2176 for (uint32 areaId : areaGroupMembers)
2177 {
2178 if (DB2Manager::IsInArea(area_id, areaId))
2179 {
2180 found = true;
2181 break;
2182 }
2183 }
2184
2185 if (!found)
2187 }
2188
2189 // continent limitation (virtual continent)
2191 {
2193 if (player && player->HasAuraType(SPELL_AURA_MOUNT_RESTRICTIONS))
2194 {
2195 for (AuraEffect const* auraEffect : player->GetAuraEffectsByType(SPELL_AURA_MOUNT_RESTRICTIONS))
2196 mountFlags |= AreaMountFlags(auraEffect->GetMiscValue());
2197 }
2198 else if (AreaTableEntry const* areaTable = sAreaTableStore.LookupEntry(area_id))
2199 mountFlags = areaTable->GetMountFlags();
2200
2201 if (!(mountFlags.HasFlag(AreaMountFlags::AllowFlyingMounts)))
2203
2204 if (player && !ConditionMgr::IsPlayerMeetingCondition(player, 72968)) // Hardcoded PlayerCondition id for attribute check in client
2206 }
2207
2208 // raid instance limitation
2210 {
2211 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2212 if (!mapEntry || mapEntry->IsRaid())
2214 }
2215
2217 {
2218 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2219 if (!mapEntry || !mapEntry->IsDungeon())
2221 }
2222
2224 {
2225 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2226 if (!mapEntry || mapEntry->IsBattleground())
2228 }
2229
2230 // DB base check (if non empty then must fit at least single for allow)
2231 SpellAreaMapBounds saBounds = sSpellMgr->GetSpellAreaMapBounds(Id);
2232 if (saBounds.first != saBounds.second)
2233 {
2234 for (SpellAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
2235 {
2236 if (itr->second.IsFitToRequirements(player, zone_id, area_id))
2237 return SPELL_CAST_OK;
2238 }
2240 }
2241
2242 // bg spell checks
2243 switch (Id)
2244 {
2245 case 23333: // Warsong Flag
2246 case 23335: // Silverwing Flag
2247 return map_id == 489 && player && player->InBattleground() ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
2248 case 2584: // Waiting to Resurrect
2249 case 42792: // Recently Dropped Flag
2250 case 43681: // Inactive
2251 case 44535: // Spirit Heal (mana)
2252 {
2253 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2254 if (!mapEntry)
2256
2257 return zone_id == AREA_WINTERGRASP || (mapEntry->IsBattleground() && player && player->InBattleground()) ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
2258 }
2259 case 44521: // Preparation
2260 {
2261 if (!player)
2263
2264 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2265 if (!mapEntry)
2267
2268 if (!mapEntry->IsBattleground())
2270
2271 Battleground* bg = player->GetBattleground();
2273 }
2274 case 32724: // Gold Team (Alliance)
2275 case 32725: // Green Team (Alliance)
2276 case 35774: // Gold Team (Horde)
2277 case 35775: // Green Team (Horde)
2278 {
2279 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2280 if (!mapEntry)
2282
2283 return mapEntry->IsBattleArena() && player && player->InBattleground() ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
2284 }
2285 case 32727: // Arena Preparation
2286 {
2287 if (!player)
2289
2290 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2291 if (!mapEntry)
2293
2294 if (!mapEntry->IsBattleArena())
2296
2297 Battleground* bg = player->GetBattleground();
2299 }
2300 }
2301
2302 // aura limitations
2303 if (player)
2304 {
2305 for (SpellEffectInfo const& effect : GetEffects())
2306 {
2307 if (!effect.IsAura())
2308 continue;
2309
2310 switch (effect.ApplyAuraName)
2311 {
2313 {
2314 if (SpellShapeshiftFormEntry const* spellShapeshiftForm = sSpellShapeshiftFormStore.LookupEntry(effect.MiscValue))
2315 if (uint32 mountType = spellShapeshiftForm->MountTypeID)
2316 if (!player->GetMountCapability(mountType))
2317 return SPELL_FAILED_NOT_HERE;
2318 break;
2319 }
2320 case SPELL_AURA_MOUNTED:
2321 {
2322 uint32 mountType = effect.MiscValueB;
2323 if (MountEntry const* mountEntry = sDB2Manager.GetMount(Id))
2324 mountType = mountEntry->MountTypeID;
2325 if (mountType && !player->GetMountCapability(mountType))
2326 return SPELL_FAILED_NOT_HERE;
2327 break;
2328 }
2329 default:
2330 break;
2331 }
2332 }
2333 }
2334
2335 return SPELL_CAST_OK;
2336}
2337
2338SpellCastResult SpellInfo::CheckTarget(WorldObject const* caster, WorldObject const* target, bool implicit /*= true*/) const
2339{
2340 if (HasAttribute(SPELL_ATTR1_EXCLUDE_CASTER) && caster == target)
2342
2343 // check visibility - Ignore invisibility/stealth for implicit (area) targets
2344 CanSeeOrDetectExtraArgs const& canSeeOrDetectExtraArgs = CanSeeOrDetectExtraArgs{
2345 .ImplicitDetection = implicit,
2346 .IgnorePhaseShift = HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT),
2349 };
2350 if (!caster->CanSeeOrDetect(target, canSeeOrDetectExtraArgs))
2352
2353 Unit const* unitTarget = target->ToUnit();
2354
2356 {
2357 auto getCreatorOrSelf = [](WorldObject const* obj)
2358 {
2359 ObjectGuid creator = obj->GetCreatorGUID();
2360 if (creator.IsEmpty())
2361 creator = obj->GetGUID();
2362
2363 return creator;
2364 };
2365 if (getCreatorOrSelf(caster) != getCreatorOrSelf(target))
2367 }
2368
2369 // creature/player specific target checks
2370 if (unitTarget)
2371 {
2372 // spells cannot be cast if target has a pet in combat either
2375
2376 // only spells with SPELL_ATTR3_ONLY_TARGET_GHOSTS can target ghosts
2378 {
2381 else
2383 }
2384
2385 if (caster != unitTarget)
2386 {
2387 if (caster->GetTypeId() == TYPEID_PLAYER)
2388 {
2389 // Do not allow these spells to target creatures not tapped by us (Banish, Polymorph, many quest spells)
2391 if (Creature const* targetCreature = unitTarget->ToCreature())
2392 if (targetCreature->hasLootRecipient() && !targetCreature->isTappedBy(caster->ToPlayer()))
2394
2396 {
2397 Creature const* targetCreature = unitTarget->ToCreature();
2398 if (!targetCreature)
2400
2401 if (!targetCreature->CanHaveLoot() || !LootTemplates_Pickpocketing.HaveLootFor(targetCreature->GetCreatureDifficulty()->PickPocketLootID))
2403 }
2404
2405 // Not allow disarm unarmed player
2407 {
2408 if (unitTarget->GetTypeId() == TYPEID_PLAYER)
2409 {
2410 Player const* player = unitTarget->ToPlayer();
2411 if (!player->GetWeaponForAttack(BASE_ATTACK) || !player->IsUseEquipedWeapon(true))
2413 }
2414 else if (!unitTarget->GetVirtualItemId(0))
2416 }
2417 }
2418 }
2419
2421 if (!unitTarget->IsSummon() || unitTarget->ToTempSummon()->GetSummonerGUID() != caster->GetGUID())
2423
2427
2431 }
2432 // corpse specific target checks
2433 else if (Corpse const* corpseTarget = target->ToCorpse())
2434 {
2435 // cannot target bare bones
2436 if (corpseTarget->GetType() == CORPSE_BONES)
2438 // we have to use owner for some checks (aura preventing resurrection for example)
2439 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2440 unitTarget = owner;
2441 // we're not interested in corpses without owner
2442 else
2444 }
2445 // other types of objects - always valid
2446 else return SPELL_CAST_OK;
2447
2448 // corpseOwner and unit specific target checks
2449 if (!unitTarget->IsPlayer())
2450 {
2453
2456 }
2459
2460 if (!IsAllowingDeadTarget() && !unitTarget->IsAlive())
2462
2463 // check this flag only for implicit targets (chain and area), allow to explicitly target units for spells like Shield of Righteousness
2466
2467 // checked in Unit::IsValidAttack/AssistTarget, shouldn't be checked for ENTRY targets
2468 //if (!HasAttribute(SPELL_ATTR6_CAN_TARGET_UNTARGETABLE) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE))
2469 // return SPELL_FAILED_BAD_TARGETS;
2470
2471 if (!CheckTargetCreatureType(unitTarget))
2472 {
2473 if (target->GetTypeId() == TYPEID_PLAYER)
2475 else
2477 }
2478
2479 // check GM mode and GM invisibility - only for player casts (npc casts are controlled by AI) and negative spells
2480 if (unitTarget != caster && (caster->GetAffectingPlayer() || !IsPositive()) && unitTarget->GetTypeId() == TYPEID_PLAYER)
2481 {
2482 if (!unitTarget->ToPlayer()->IsVisible())
2484
2485 if (unitTarget->ToPlayer()->IsGameMaster())
2487 }
2488
2489 // not allow casting on flying player
2492
2493 /* TARGET_UNIT_MASTER gets blocked here for passengers, because the whole idea of this check is to
2494 not allow passengers to be implicitly hit by spells, however this target type should be an exception,
2495 if this is left it kills spells that award kill credit from vehicle to master (few spells),
2496 the use of these 2 covers passenger target check, logically, if vehicle cast this to master it should always hit
2497 him, because it would be it's passenger, there's no such case where this gets to fail legitimacy, this problem
2498 cannot be solved from within the check in other way since target type cannot be called for the spell currently
2499 Spell examples: [ID - 52864 Devour Water, ID - 52862 Devour Wind, ID - 49370 Wyrmrest Defender: Destabilize Azure Dragonshrine Effect] */
2500 if (Unit const* unitCaster = caster->ToUnit())
2501 {
2502 if (!unitCaster->IsVehicle() && !(unitCaster->GetCharmerOrOwner() == target))
2503 {
2504 if (TargetAuraState && !unitTarget->HasAuraState(AuraStateType(TargetAuraState), this, unitCaster))
2506
2507 if (ExcludeTargetAuraState && unitTarget->HasAuraState(AuraStateType(ExcludeTargetAuraState), this, unitCaster))
2509 }
2510 }
2511
2512 if (TargetAuraSpell && !unitTarget->HasAura(TargetAuraSpell))
2514
2517
2518 if (TargetAuraType && !unitTarget->HasAuraType(TargetAuraType))
2520
2523
2527
2529 if (Map* map = caster->GetMap())
2530 if (InstanceMap* iMap = map->ToInstanceMap())
2531 if (InstanceScript* instance = iMap->GetInstanceScript())
2532 if (instance->GetCombatResurrectionCharges() == 0 && instance->IsEncounterInProgress())
2534
2535 return SPELL_CAST_OK;
2536}
2537
2538SpellCastResult SpellInfo::CheckExplicitTarget(WorldObject const* caster, WorldObject const* target, Item const* itemTarget /*= nullptr*/) const
2539{
2540 uint32 neededTargets = RequiredExplicitTargetMask;
2541 if (!target)
2542 {
2544 if (!(neededTargets & TARGET_FLAG_GAMEOBJECT_ITEM) || !itemTarget)
2546 return SPELL_CAST_OK;
2547 }
2548
2549 if (Unit const* unitTarget = target->ToUnit())
2550 {
2552 {
2553 Unit const* unitCaster = caster->ToUnit();
2554 if (neededTargets & TARGET_FLAG_UNIT_ENEMY)
2555 if (caster->IsValidAttackTarget(unitTarget, this))
2556 return SPELL_CAST_OK;
2557 if ((neededTargets & TARGET_FLAG_UNIT_ALLY)
2558 || ((neededTargets & TARGET_FLAG_UNIT_PARTY) && unitCaster && unitCaster->IsInPartyWith(unitTarget))
2559 || ((neededTargets & TARGET_FLAG_UNIT_RAID) && unitCaster && unitCaster->IsInRaidWith(unitTarget)))
2560 if (caster->IsValidAssistTarget(unitTarget, this))
2561 return SPELL_CAST_OK;
2562 if ((neededTargets & TARGET_FLAG_UNIT_MINIPET) && unitCaster)
2563 if (unitTarget->GetGUID() == unitCaster->GetCritterGUID())
2564 return SPELL_CAST_OK;
2565 if ((neededTargets & TARGET_FLAG_UNIT_PASSENGER) && unitCaster)
2566 if (unitTarget->IsOnVehicle(unitCaster))
2567 return SPELL_CAST_OK;
2569 }
2570 }
2571 return SPELL_CAST_OK;
2572}
2573
2575{
2576 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
2577 if (caster->GetTypeId() != TYPEID_PLAYER)
2578 return SPELL_CAST_OK;
2579
2580 Vehicle* vehicle = caster->GetVehicle();
2581 if (vehicle)
2582 {
2583 uint16 checkMask = 0;
2584 for (SpellEffectInfo const& effect : GetEffects())
2585 {
2586 if (effect.IsAura(SPELL_AURA_MOD_SHAPESHIFT))
2587 {
2588 SpellShapeshiftFormEntry const* shapeShiftFromEntry = sSpellShapeshiftFormStore.LookupEntry(effect.MiscValue);
2589 if (shapeShiftFromEntry && (shapeShiftFromEntry->Flags & 1) == 0) // unk flag
2590 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
2591 break;
2592 }
2593 }
2594
2597
2598 if (!checkMask)
2599 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
2600
2601 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(caster);
2603 && (vehicleSeat->Flags & checkMask) != checkMask)
2605
2606 // Can only summon uncontrolled minions/guardians when on controlled vehicle
2608 {
2609 for (SpellEffectInfo const& effect : GetEffects())
2610 {
2611 if (!effect.IsEffect(SPELL_EFFECT_SUMMON))
2612 continue;
2613
2614 SummonPropertiesEntry const* props = sSummonPropertiesStore.LookupEntry(effect.MiscValueB);
2615 if (props && props->Control != SUMMON_CATEGORY_WILD)
2617 }
2618 }
2619 }
2620
2621 return SPELL_CAST_OK;
2622}
2623
2625{
2626 // Curse of Doom & Exorcism: not find another way to fix spell target check :/
2628 {
2629 // not allow cast at player
2630 if (target->GetTypeId() == TYPEID_PLAYER)
2631 return false;
2632 else
2633 return true;
2634 }
2635
2636 // if target is magnet (i.e Grounding Totem) the check is skipped
2637 if (target->IsMagnet())
2638 return true;
2639
2640 uint32 creatureType = target->GetCreatureTypeMask();
2641 return !TargetCreatureType || !creatureType || (creatureType & TargetCreatureType) || target->HasAuraType(SPELL_AURA_IGNORE_SPELL_CREATURE_TYPE_REQUIREMENTS);
2642}
2643
2648
2650{
2651 uint64 mask = 0;
2652 if (Mechanic)
2653 mask |= UI64LIT(1) << Mechanic;
2654
2655 for (SpellEffectInfo const& effect : GetEffects())
2656 if (effect.IsEffect() && effect.Mechanic)
2657 mask |= UI64LIT(1) << effect.Mechanic;
2658
2659 return mask;
2660}
2661
2663{
2664 uint64 mask = 0;
2665 if (Mechanic)
2666 mask |= UI64LIT(1) << Mechanic;
2667
2668 if (GetEffect(effIndex).IsEffect() && GetEffect(effIndex).Mechanic)
2669 mask |= UI64LIT(1) << GetEffect(effIndex).Mechanic;
2670
2671 return mask;
2672}
2673
2675{
2676 uint64 mask = 0;
2677 if (Mechanic)
2678 mask |= UI64LIT(1) << Mechanic;
2679
2680 for (SpellEffectInfo const& effect : GetEffects())
2681 if ((effectMask & (1 << effect.EffectIndex)) && effect.Mechanic)
2682 mask |= UI64LIT(1) << effect.Mechanic;
2683
2684 return mask;
2685}
2686
2688{
2689 if (GetEffect(effIndex).IsEffect() && GetEffect(effIndex).Mechanic)
2690 return GetEffect(effIndex).Mechanic;
2691
2692 if (Mechanic)
2693 return Mechanics(Mechanic);
2694
2695 return MECHANIC_NONE;
2696}
2697
2702
2704{
2705 // If dispel all
2706 if (type == DISPEL_ALL)
2707 return DISPEL_ALL_MASK;
2708 else
2709 return uint32(1 << type);
2710}
2711
2716
2718{
2719 return _auraState;
2720}
2721
2723{
2724 _auraState = [this]()->AuraStateType
2725 {
2726 // Faerie Fire (Feral)
2727 if (GetCategory() == 1133)
2729
2730 // Swiftmend state on Regrowth, Rejuvenation, Wild Growth
2731 if (SpellFamilyName == SPELLFAMILY_DRUID && (SpellFamilyFlags[0] & 0x50 || SpellFamilyFlags[1] & 0x4000000))
2733
2734 // Deadly poison aura state
2735 if (SpellFamilyName == SPELLFAMILY_ROGUE && SpellFamilyFlags[0] & 0x10000)
2737
2738 // Enrage aura state
2739 if (Dispel == DISPEL_ENRAGE)
2740 return AURA_STATE_ENRAGED;
2741
2742 // Bleeding aura state
2744 return AURA_STATE_BLEED;
2745
2747 for (SpellEffectInfo const& effect : GetEffects())
2748 if (effect.IsAura(SPELL_AURA_MOD_STUN) || effect.IsAura(SPELL_AURA_MOD_ROOT) || effect.IsAura(SPELL_AURA_MOD_ROOT_2))
2749 return AURA_STATE_FROZEN;
2750
2751 switch (Id)
2752 {
2753 case 1064: // Dazed
2754 return AURA_STATE_DAZED;
2755 case 32216: // Victorious
2756 return AURA_STATE_VICTORIOUS;
2757 case 71465: // Divine Surge
2758 case 50241: // Evasive Charges
2759 case 81262: // Efflorescence
2761 case 6950: // Faerie Fire
2762 case 9806: // Phantom Strike
2763 case 9991: // Touch of Zanzil
2764 case 13424: // Faerie Fire
2765 case 13752: // Faerie Fire
2766 case 16432: // Plague Mist
2767 case 20656: // Faerie Fire
2768 case 25602: // Faerie Fire
2769 case 32129: // Faerie Fire
2770 case 35325: // Glowing Blood
2771 case 35328: // Lambent Blood
2772 case 35329: // Vibrant Blood
2773 case 35331: // Black Blood
2774 case 49163: // Perpetual Instability
2775 case 65863: // Faerie Fire
2776 case 79559: // Luxscale Light
2777 case 82855: // Dazzling
2778 case 102953: // In the Rumpus
2779 case 127907: // Phosphorescence
2780 case 127913: // Phosphorescence
2781 case 129007: // Zijin Sting
2782 case 130159: // Fae Touch
2783 case 142537: // Spotter Smoke
2784 case 168455: // Spotted!
2785 case 176905: // Super Sticky Glitter Bomb
2786 case 189502: // Marked
2787 case 201785: // Intruder Alert!
2788 case 201786: // Intruder Alert!
2789 case 201935: // Spotted!
2790 case 239233: // Smoke Bomb
2791 case 319400: // Glitter Burst
2792 case 321470: // Dimensional Shifter Mishap
2793 case 331134: // Spotted
2795 default:
2796 break;
2797 }
2798
2800 return AURA_STATE_BANISHED;
2801
2802 return AURA_STATE_NONE;
2803 }();
2804}
2805
2810
2812{
2814 {
2815 switch (SpellFamilyName)
2816 {
2818 {
2819 // Food / Drinks (mostly)
2821 {
2822 bool food = false;
2823 bool drink = false;
2824 for (SpellEffectInfo const& effect : GetEffects())
2825 {
2826 if (!effect.IsAura())
2827 continue;
2828 switch (effect.ApplyAuraName)
2829 {
2830 // Food
2833 food = true;
2834 break;
2835 // Drink
2838 drink = true;
2839 break;
2840 default:
2841 break;
2842 }
2843 }
2844
2845 if (food && drink)
2847 else if (food)
2848 return SPELL_SPECIFIC_FOOD;
2849 else if (drink)
2850 return SPELL_SPECIFIC_DRINK;
2851 }
2852 // scrolls effects
2853 else
2854 {
2855 SpellInfo const* firstRankSpellInfo = GetFirstRankSpell();
2856 switch (firstRankSpellInfo->Id)
2857 {
2858 case 8118: // Strength
2859 case 8099: // Stamina
2860 case 8112: // Spirit
2861 case 8096: // Intellect
2862 case 8115: // Agility
2863 case 8091: // Armor
2864 return SPELL_SPECIFIC_SCROLL;
2865 default:
2866 break;
2867 }
2868 }
2869 break;
2870 }
2871 case SPELLFAMILY_MAGE:
2872 {
2873 // family flags 18(Molten), 25(Frost/Ice), 28(Mage)
2874 if (SpellFamilyFlags[0] & 0x12040000)
2876
2877 // Arcane brillance and Arcane intelect (normal check fails because of flags difference)
2878 if (SpellFamilyFlags[0] & 0x400)
2880
2881 if ((SpellFamilyFlags[0] & 0x1000000) && GetEffect(EFFECT_0).IsAura(SPELL_AURA_MOD_CONFUSE))
2883
2884 break;
2885 }
2887 {
2888 if (Id == 12292) // Death Wish
2890
2891 break;
2892 }
2894 {
2895 // Warlock (Bane of Doom | Bane of Agony | Bane of Havoc)
2896 if (Id == 603 || Id == 980 || Id == 80240)
2897 return SPELL_SPECIFIC_BANE;
2898
2899 // only warlock curses have this
2900 if (Dispel == DISPEL_CURSE)
2901 return SPELL_SPECIFIC_CURSE;
2902
2903 // Warlock (Demon Armor | Demon Skin | Fel Armor)
2904 if (SpellFamilyFlags[1] & 0x20000020 || SpellFamilyFlags[2] & 0x00000010)
2906 break;
2907 }
2908 case SPELLFAMILY_PRIEST:
2909 {
2910 // Divine Spirit and Prayer of Spirit
2911 if (SpellFamilyFlags[0] & 0x20)
2913
2914 break;
2915 }
2916 case SPELLFAMILY_HUNTER:
2917 {
2918 // only hunter stings have this
2919 if (Dispel == DISPEL_POISON)
2920 return SPELL_SPECIFIC_STING;
2921
2922 // only hunter aspects have this (but not all aspects in hunter family)
2923 if (SpellFamilyFlags & flag128(0x00200000, 0x00000000, 0x00001010, 0x00000000))
2924 return SPELL_SPECIFIC_ASPECT;
2925
2926 break;
2927 }
2929 {
2930 // Collection of all the seal family flags. No other paladin spell has any of those.
2931 if (SpellFamilyFlags[1] & 0xA2000800)
2932 return SPELL_SPECIFIC_SEAL;
2933
2934 if (SpellFamilyFlags[0] & 0x00002190)
2935 return SPELL_SPECIFIC_HAND;
2936
2937 // only paladin auras have this (for palaldin class family)
2938 switch (Id)
2939 {
2940 case 465: // Devotion Aura
2941 case 32223: // Crusader Aura
2942 case 183435: // Retribution Aura
2943 case 317920: // Concentration Aura
2944 return SPELL_SPECIFIC_AURA;
2945 default:
2946 break;
2947 }
2948
2949 break;
2950 }
2951 case SPELLFAMILY_SHAMAN:
2952 {
2953 // family flags 10 (Lightning), 42 (Earth), 37 (Water), proc shield from T2 8 pieces bonus
2954 if (SpellFamilyFlags[1] & 0x420
2955 || SpellFamilyFlags[0] & 0x00000400
2956 || Id == 23552)
2958
2959 break;
2960 }
2962 if (Id == 48266 || Id == 48263 || Id == 48265)
2964 break;
2965 }
2966
2967 for (SpellEffectInfo const& effect : GetEffects())
2968 {
2969 if (effect.IsEffect(SPELL_EFFECT_APPLY_AURA))
2970 {
2971 switch (effect.ApplyAuraName)
2972 {
2977 return SPELL_SPECIFIC_CHARM;
2980 if (Id == 30645) // Gas Cloud Tracking
2981 return SPELL_SPECIFIC_NORMAL;
2982 [[fallthrough]];
2986 default:
2987 break;
2988 }
2989 }
2990 }
2991 return SPELL_SPECIFIC_NORMAL;
2992 }();
2993}
2994
2996{
2997 auto diminishingGroupCompute = [this]() -> DiminishingGroup
2998 {
2999 if (IsPositive())
3000 return DIMINISHING_NONE;
3001
3003 return DIMINISHING_TAUNT;
3004
3005 switch (Id)
3006 {
3007 case 20549: // War Stomp (Racial - Tauren)
3008 case 24394: // Intimidation
3009 case 118345: // Pulverize (Primal Earth Elemental)
3010 case 118905: // Static Charge (Capacitor Totem)
3011 return DIMINISHING_STUN;
3012 case 107079: // Quaking Palm
3014 case 155145: // Arcane Torrent (Racial - Blood Elf)
3015 return DIMINISHING_SILENCE;
3016 case 108199: // Gorefiend's Grasp
3017 case 191244: // Sticky Bomb
3019 default:
3020 break;
3021 }
3022
3023 // Explicit Diminishing Groups
3024 switch (SpellFamilyName)
3025 {
3027 // Frost Tomb
3028 if (Id == 48400)
3029 return DIMINISHING_NONE;
3030 // Gnaw
3031 else if (Id == 47481)
3032 return DIMINISHING_STUN;
3033 // ToC Icehowl Arctic Breath
3034 else if (Id == 66689)
3035 return DIMINISHING_NONE;
3036 // Black Plague
3037 else if (Id == 64155)
3038 return DIMINISHING_NONE;
3039 // Screams of the Dead (King Ymiron)
3040 else if (Id == 51750)
3041 return DIMINISHING_NONE;
3042 // Crystallize (Keristrasza heroic)
3043 else if (Id == 48179)
3044 return DIMINISHING_NONE;
3045 break;
3046 case SPELLFAMILY_MAGE:
3047 {
3048 // Frost Nova -- 122
3049 if (SpellFamilyFlags[0] & 0x40)
3050 return DIMINISHING_ROOT;
3051 // Freeze (Water Elemental) -- 33395
3052 if (SpellFamilyFlags[2] & 0x200)
3053 return DIMINISHING_ROOT;
3054
3055 // Dragon's Breath -- 31661
3056 if (SpellFamilyFlags[0] & 0x800000)
3058 // Polymorph -- 118
3059 if (SpellFamilyFlags[0] & 0x1000000)
3061 // Ring of Frost -- 82691
3062 if (SpellFamilyFlags[2] & 0x40)
3064 // Ice Nova -- 157997
3065 if (SpellFamilyFlags[2] & 0x800000)
3067 break;
3068 }
3070 {
3071 // Shockwave -- 132168
3072 if (SpellFamilyFlags[1] & 0x8000)
3073 return DIMINISHING_STUN;
3074 // Storm Bolt -- 132169
3075 if (SpellFamilyFlags[2] & 0x1000)
3076 return DIMINISHING_STUN;
3077
3078 // Intimidating Shout -- 5246
3079 if (SpellFamilyFlags[0] & 0x40000)
3080 return DIMINISHING_DISORIENT;
3081 break;
3082 }
3084 {
3085 // Mortal Coil -- 6789
3086 if (SpellFamilyFlags[0] & 0x80000)
3088 // Banish -- 710
3089 if (SpellFamilyFlags[1] & 0x8000000)
3091
3092 // Fear -- 118699
3093 if (SpellFamilyFlags[1] & 0x400)
3094 return DIMINISHING_DISORIENT;
3095 // Howl of Terror -- 5484
3096 if (SpellFamilyFlags[1] & 0x8)
3097 return DIMINISHING_DISORIENT;
3098
3099 // Shadowfury -- 30283
3100 if (SpellFamilyFlags[1] & 0x1000)
3101 return DIMINISHING_STUN;
3102 // Summon Infernal -- 22703
3103 if (SpellFamilyFlags[0] & 0x1000)
3104 return DIMINISHING_STUN;
3105
3106 // 170995 -- Cripple
3107 if (Id == 170995)
3108 return DIMINISHING_LIMITONLY;
3109 break;
3110 }
3112 {
3113 // Fellash -- 115770
3114 // Whiplash -- 6360
3115 if (SpellFamilyFlags[0] & 0x8000000)
3117
3118 // Mesmerize (Shivarra pet) -- 115268
3119 // Seduction (Succubus pet) -- 6358
3120 if (SpellFamilyFlags[0] & 0x2000000)
3121 return DIMINISHING_DISORIENT;
3122
3123 // Axe Toss (Felguard pet) -- 89766
3124 if (SpellFamilyFlags[1] & 0x4)
3125 return DIMINISHING_STUN;
3126 break;
3127 }
3128 case SPELLFAMILY_DRUID:
3129 {
3130 // Maim -- 22570
3131 if (SpellFamilyFlags[1] & 0x80)
3132 return DIMINISHING_STUN;
3133 // Mighty Bash -- 5211
3134 if (SpellFamilyFlags[0] & 0x2000)
3135 return DIMINISHING_STUN;
3136 // Rake -- 163505 -- no flags on the stun
3137 if (Id == 163505)
3138 return DIMINISHING_STUN;
3139
3140 // Incapacitating Roar -- 99, no flags on the stun, 14
3141 if (SpellFamilyFlags[1] & 0x1)
3143
3144 // Cyclone -- 33786
3145 if (SpellFamilyFlags[1] & 0x20)
3146 return DIMINISHING_DISORIENT;
3147
3148 // Solar Beam -- 81261
3149 if (Id == 81261)
3150 return DIMINISHING_SILENCE;
3151
3152 // Typhoon -- 61391
3153 if (SpellFamilyFlags[1] & 0x1000000)
3155 // Ursol's Vortex -- 118283, no family flags
3156 if (Id == 118283)
3158
3159 // Entangling Roots -- 339
3160 if (SpellFamilyFlags[0] & 0x200)
3161 return DIMINISHING_ROOT;
3162 // Mass Entanglement -- 102359
3163 if (SpellFamilyFlags[2] & 0x4)
3164 return DIMINISHING_ROOT;
3165 break;
3166 }
3167 case SPELLFAMILY_ROGUE:
3168 {
3169 // Between the Eyes -- 199804
3170 if (SpellFamilyFlags[0] & 0x800000)
3171 return DIMINISHING_STUN;
3172 // Cheap Shot -- 1833
3173 if (SpellFamilyFlags[0] & 0x400)
3174 return DIMINISHING_STUN;
3175 // Kidney Shot -- 408
3176 if (SpellFamilyFlags[0] & 0x200000)
3177 return DIMINISHING_STUN;
3178
3179 // Gouge -- 1776
3180 if (SpellFamilyFlags[0] & 0x8)
3182 // Sap -- 6770
3183 if (SpellFamilyFlags[0] & 0x80)
3185
3186 // Blind -- 2094
3187 if (SpellFamilyFlags[0] & 0x1000000)
3188 return DIMINISHING_DISORIENT;
3189
3190 // Garrote -- 1330
3191 if (SpellFamilyFlags[1] & 0x20000000)
3192 return DIMINISHING_SILENCE;
3193 break;
3194 }
3195 case SPELLFAMILY_HUNTER:
3196 {
3197 // Charge (Tenacity pet) -- 53148, no flags
3198 if (Id == 53148)
3199 return DIMINISHING_ROOT;
3200 // Ranger's Net -- 200108
3201 // Tracker's Net -- 212638
3202 if (Id == 200108 || Id == 212638)
3203 return DIMINISHING_ROOT;
3204
3205 // Binding Shot -- 117526, no flags
3206 if (Id == 117526)
3207 return DIMINISHING_STUN;
3208
3209 // Freezing Trap -- 3355
3210 if (SpellFamilyFlags[0] & 0x8)
3212 // Wyvern Sting -- 19386
3213 if (SpellFamilyFlags[1] & 0x1000)
3215
3216 // Bursting Shot -- 224729
3217 if (SpellFamilyFlags[2] & 0x40)
3218 return DIMINISHING_DISORIENT;
3219 // Scatter Shot -- 213691
3220 if (SpellFamilyFlags[2] & 0x8000)
3221 return DIMINISHING_DISORIENT;
3222
3223 // Spider Sting -- 202933
3224 if (Id == 202933)
3225 return DIMINISHING_SILENCE;
3226 break;
3227 }
3229 {
3230 // Repentance -- 20066
3231 if (SpellFamilyFlags[0] & 0x4)
3233
3234 // Blinding Light -- 105421
3235 if (Id == 105421)
3236 return DIMINISHING_DISORIENT;
3237
3238 // Avenger's Shield -- 31935
3239 if (SpellFamilyFlags[0] & 0x4000)
3240 return DIMINISHING_SILENCE;
3241
3242 // Hammer of Justice -- 853
3243 if (SpellFamilyFlags[0] & 0x800)
3244 return DIMINISHING_STUN;
3245 break;
3246 }
3247 case SPELLFAMILY_SHAMAN:
3248 {
3249 // Hex -- 51514
3250 // Hex -- 196942 (Voodoo Totem)
3251 if (SpellFamilyFlags[1] & 0x8000)
3253
3254 // Thunderstorm -- 51490
3255 if (SpellFamilyFlags[1] & 0x2000)
3257
3258 // Earthgrab Totem -- 64695
3259 if (SpellFamilyFlags[2] & 0x4000)
3260 return DIMINISHING_ROOT;
3261
3262 // Lightning Lasso -- 204437
3263 if (SpellFamilyFlags[3] & 0x2000000)
3264 return DIMINISHING_STUN;
3265 break;
3266 }
3268 {
3269 // Chains of Ice -- 96294
3270 if (Id == 96294)
3271 return DIMINISHING_ROOT;
3272
3273 // Blinding Sleet -- 207167
3274 if (Id == 207167)
3275 return DIMINISHING_DISORIENT;
3276
3277 // Strangulate -- 47476
3278 if (SpellFamilyFlags[0] & 0x200)
3279 return DIMINISHING_SILENCE;
3280
3281 // Asphyxiate -- 108194
3282 if (SpellFamilyFlags[2] & 0x100000)
3283 return DIMINISHING_STUN;
3284 // Gnaw (Ghoul) -- 91800, no flags
3285 if (Id == 91800)
3286 return DIMINISHING_STUN;
3287 // Monstrous Blow (Ghoul w/ Dark Transformation active) -- 91797
3288 if (Id == 91797)
3289 return DIMINISHING_STUN;
3290 // Winter is Coming -- 207171
3291 if (Id == 207171)
3292 return DIMINISHING_STUN;
3293 break;
3294 }
3295 case SPELLFAMILY_PRIEST:
3296 {
3297 // Holy Word: Chastise -- 200200
3298 if (SpellFamilyFlags[2] & 0x20 && GetSpellVisual() == 52021)
3299 return DIMINISHING_STUN;
3300 // Mind Bomb -- 226943
3301 if (Id == 226943)
3302 return DIMINISHING_STUN;
3303
3304 // Mind Control -- 605
3305 if (SpellFamilyFlags[0] & 0x20000 && GetSpellVisual() == 39068)
3307 // Holy Word: Chastise -- 200196
3308 if (SpellFamilyFlags[2] & 0x20 && GetSpellVisual() == 52019)
3310
3311 // Psychic Scream -- 8122
3312 if (SpellFamilyFlags[0] & 0x10000)
3313 return DIMINISHING_DISORIENT;
3314
3315 // Silence -- 15487
3316 if (SpellFamilyFlags[1] & 0x200000 && GetSpellVisual() == 39025)
3317 return DIMINISHING_SILENCE;
3318
3319 // Shining Force -- 204263
3320 if (Id == 204263)
3322 break;
3323 }
3324 case SPELLFAMILY_MONK:
3325 {
3326 // Disable -- 116706, no flags
3327 if (Id == 116706)
3328 return DIMINISHING_ROOT;
3329
3330 // Fists of Fury -- 120086
3331 if (SpellFamilyFlags[1] & 0x800000 && !(SpellFamilyFlags[2] & 0x8))
3332 return DIMINISHING_STUN;
3333 // Leg Sweep -- 119381
3334 if (SpellFamilyFlags[1] & 0x200)
3335 return DIMINISHING_STUN;
3336
3337 // Incendiary Breath (honor talent) -- 202274, no flags
3338 if (Id == 202274)
3340 // Paralysis -- 115078
3341 if (SpellFamilyFlags[2] & 0x800000)
3343
3344 // Song of Chi-Ji -- 198909
3345 if (Id == 198909)
3346 return DIMINISHING_DISORIENT;
3347 break;
3348 }
3350 {
3351 switch (Id)
3352 {
3353 case 179057: // Chaos Nova
3354 case 211881: // Fel Eruption
3355 case 200166: // Metamorphosis
3356 case 205630: // Illidan's Grasp
3357 return DIMINISHING_STUN;
3358 case 217832: // Imprison
3359 case 221527: // Imprison
3361 default:
3362 break;
3363 }
3364 break;
3365 }
3366 default:
3367 break;
3368 }
3369
3370 return DIMINISHING_NONE;
3371 };
3372
3373 auto diminishingTypeCompute = [](DiminishingGroup group) -> DiminishingReturnsType
3374 {
3375 switch (group)
3376 {
3377 case DIMINISHING_TAUNT:
3378 case DIMINISHING_STUN:
3379 return DRTYPE_ALL;
3381 case DIMINISHING_NONE:
3382 return DRTYPE_NONE;
3383 default:
3384 return DRTYPE_PLAYER;
3385 }
3386 };
3387
3388 auto diminishingMaxLevelCompute = [](DiminishingGroup group) -> DiminishingLevels
3389 {
3390 switch (group)
3391 {
3392 case DIMINISHING_TAUNT:
3395 return DIMINISHING_LEVEL_2;
3396 default:
3398 }
3399 };
3400
3401 auto diminishingLimitDurationCompute = [this]() -> int32
3402 {
3403 // Explicit diminishing duration
3404 switch (SpellFamilyName)
3405 {
3406 case SPELLFAMILY_MAGE:
3407 {
3408 // Dragon's Breath - 3 seconds in PvP
3409 if (SpellFamilyFlags[0] & 0x800000)
3410 return 3 * IN_MILLISECONDS;
3411 break;
3412 }
3414 {
3415 // Cripple - 4 seconds in PvP
3416 if (Id == 170995)
3417 return 4 * IN_MILLISECONDS;
3418 break;
3419 }
3420 case SPELLFAMILY_HUNTER:
3421 {
3422 // Binding Shot - 3 seconds in PvP
3423 if (Id == 117526)
3424 return 3 * IN_MILLISECONDS;
3425
3426 // Wyvern Sting - 6 seconds in PvP
3427 if (SpellFamilyFlags[1] & 0x1000)
3428 return 6 * IN_MILLISECONDS;
3429 break;
3430 }
3431 case SPELLFAMILY_MONK:
3432 {
3433 // Paralysis - 4 seconds in PvP regardless of if they are facing you
3434 if (SpellFamilyFlags[2] & 0x800000)
3435 return 4 * IN_MILLISECONDS;
3436 break;
3437 }
3439 {
3440 switch (Id)
3441 {
3442 case 217832: // Imprison
3443 case 221527: // Imprison
3444 return 4 * IN_MILLISECONDS;
3445 default:
3446 break;
3447 }
3448 break;
3449 }
3450 default:
3451 break;
3452 }
3453
3454 return 8 * IN_MILLISECONDS;
3455 };
3456
3457 SpellDiminishInfo diminishInfo;
3458 diminishInfo.DiminishGroup = diminishingGroupCompute();
3459 diminishInfo.DiminishReturnType = diminishingTypeCompute(diminishInfo.DiminishGroup);
3460 diminishInfo.DiminishMaxLevel = diminishingMaxLevelCompute(diminishInfo.DiminishGroup);
3461 diminishInfo.DiminishDurationLimit = diminishingLimitDurationCompute();
3462
3463 _diminishInfo = diminishInfo;
3464}
3465
3470
3475
3480
3485
3487{
3488 std::unique_ptr<SpellEffectInfo::ImmunityInfo> workBuffer = std::make_unique<SpellEffectInfo::ImmunityInfo>();
3489
3490 for (SpellEffectInfo& effect : _effects)
3491 {
3492 uint32 schoolImmunityMask = 0;
3493 uint32 applyHarmfulAuraImmunityMask = 0;
3494 uint64 mechanicImmunityMask = 0;
3495 uint32 dispelImmunityMask = 0;
3496 uint32 damageImmunityMask = 0;
3497 uint8 otherImmunityMask = 0;
3498 bool removeEffectsWithMechanic = false;
3499
3500 int32 miscVal = effect.MiscValue;
3501
3502 SpellEffectInfo::ImmunityInfo& immuneInfo = *workBuffer;
3503
3504 switch (effect.ApplyAuraName)
3505 {
3507 {
3508 if (CreatureImmunities const* creatureImmunities = SpellMgr::GetCreatureImmunities(miscVal))
3509 {
3510 schoolImmunityMask |= creatureImmunities->School.to_ulong();
3511 dispelImmunityMask |= creatureImmunities->DispelType.to_ulong();
3512 mechanicImmunityMask |= creatureImmunities->Mechanic.to_ullong();
3513 otherImmunityMask |= creatureImmunities->Other.AsUnderlyingType();
3514 for (SpellEffects effectType : creatureImmunities->Effect)
3515 immuneInfo.SpellEffectImmune.insert(effectType);
3516 for (AuraType aura : creatureImmunities->Aura)
3517 immuneInfo.AuraTypeImmune.insert(aura);
3518 }
3519 break;
3520 }
3522 {
3523 switch (Id)
3524 {
3525 case 42292: // PvP trinket
3526 case 59752: // Every Man for Himself
3529 removeEffectsWithMechanic = true;
3530 break;
3531 case 34471: // The Beast Within
3532 case 19574: // Bestial Wrath
3533 case 46227: // Medallion of Immunity
3534 case 53490: // Bullheaded
3535 case 65547: // PvP Trinket
3536 case 134946: // Supremacy of the Alliance
3537 case 134956: // Supremacy of the Horde
3538 case 195710: // Honorable Medallion
3539 case 208683: // Gladiator's Medallion
3541 removeEffectsWithMechanic = true;
3542 break;
3543 case 54508: // Demonic Empowerment
3544 mechanicImmunityMask |= (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT) | (1 << MECHANIC_STUN);
3545 break;
3546 default:
3547 if (miscVal < 1)
3548 break;
3549
3550 mechanicImmunityMask |= UI64LIT(1) << miscVal;
3551 break;
3552 }
3553
3554 // Special 100 ms duration spells - PvP trinket, Every Man for Himself and some other
3555 if (GetMaxDuration() == 100)
3556 removeEffectsWithMechanic = true;
3557
3558 break;
3559 }
3561 {
3562 immuneInfo.SpellEffectImmune.insert(static_cast<SpellEffects>(miscVal));
3563 break;
3564 }
3566 {
3567 immuneInfo.AuraTypeImmune.insert(static_cast<AuraType>(miscVal));
3568 break;
3569 }
3571 {
3572 schoolImmunityMask |= uint32(miscVal);
3573 break;
3574 }
3576 {
3577 applyHarmfulAuraImmunityMask |= uint32(miscVal);
3578 break;
3579 }
3581 {
3582 damageImmunityMask |= uint32(miscVal);
3583 break;
3584 }
3586 {
3587 dispelImmunityMask = 1u << miscVal;
3588 break;
3589 }
3590 default:
3591 break;
3592 }
3593
3594 immuneInfo.SchoolImmuneMask = schoolImmunityMask;
3595 immuneInfo.ApplyHarmfulAuraImmuneMask = applyHarmfulAuraImmunityMask;
3596 immuneInfo.MechanicImmuneMask = mechanicImmunityMask;
3597 immuneInfo.DispelImmuneMask = dispelImmunityMask;
3598 immuneInfo.DamageSchoolMask = damageImmunityMask;
3599 immuneInfo.OtherImmuneMask = otherImmunityMask;
3600 immuneInfo.RemoveEffectsWithMechanic = removeEffectsWithMechanic;
3601
3602 immuneInfo.AuraTypeImmune.shrink_to_fit();
3603 immuneInfo.SpellEffectImmune.shrink_to_fit();
3604
3605 if (immuneInfo.SchoolImmuneMask
3606 || immuneInfo.ApplyHarmfulAuraImmuneMask
3607 || immuneInfo.MechanicImmuneMask
3608 || immuneInfo.DispelImmuneMask
3609 || immuneInfo.DamageSchoolMask
3610 || immuneInfo.OtherImmuneMask
3611 || !immuneInfo.AuraTypeImmune.empty()
3612 || !immuneInfo.SpellEffectImmune.empty())
3613 {
3614 effect._immunityInfo = std::move(workBuffer);
3615 workBuffer = std::make_unique<SpellEffectInfo::ImmunityInfo>();
3616 }
3617
3619 }
3620
3622 {
3623 switch (Id)
3624 {
3625 case 22812: // Barkskin
3626 case 47585: // Dispersion
3628 (1 << MECHANIC_STUN) |
3629 (1 << MECHANIC_FREEZE) |
3630 (1 << MECHANIC_KNOCKOUT) |
3631 (1 << MECHANIC_SLEEP);
3632 break;
3633 case 49039: // Lichborne, don't allow normal stuns
3634 break;
3635 default:
3637 break;
3638 }
3639 }
3640
3643
3645 {
3646 switch (Id)
3647 {
3648 case 22812: // Barkskin
3649 case 47585: // Dispersion
3651 break;
3652 default:
3654 break;
3655 }
3656 }
3657}
3658
3659void SpellInfo::_LoadSqrtTargetLimit(int32 maxTargets, int32 numNonDiminishedTargets,
3660 Optional<uint32> maxTargetsValueHolderSpell, Optional<SpellEffIndex> maxTargetsValueHolderEffect,
3661 Optional<uint32> numNonDiminishedTargetsValueHolderSpell, Optional<SpellEffIndex> numNonDiminishedTargetsValueHolderEffect)
3662{
3663 SqrtDamageAndHealingDiminishing.MaxTargets = maxTargets;
3664 SqrtDamageAndHealingDiminishing.NumNonDiminishedTargets = numNonDiminishedTargets;
3665
3666 if (maxTargetsValueHolderEffect)
3667 {
3668 SpellInfo const* maxTargetValueHolder = this;
3669 if (maxTargetsValueHolderSpell)
3670 maxTargetValueHolder = sSpellMgr->GetSpellInfo(*maxTargetsValueHolderSpell, Difficulty);
3671
3672 if (!maxTargetValueHolder)
3673 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(maxTargets): Spell {} does not exist", *maxTargetsValueHolderSpell);
3674 else if (*maxTargetsValueHolderEffect >= maxTargetValueHolder->GetEffects().size())
3675 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(maxTargets): Spell {} does not have effect {}",
3676 maxTargetValueHolder->Id, AsUnderlyingType(*maxTargetsValueHolderEffect));
3677 else
3678 {
3679 SpellEffectInfo const& valueHolder = maxTargetValueHolder->GetEffect(*maxTargetsValueHolderEffect);
3680 int32 expectedValue = int32(valueHolder.CalcBaseValue(nullptr, nullptr, 0, -1));
3681 if (maxTargets != expectedValue)
3682 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(maxTargets): Spell {} has different value in effect {} than expected, recheck target caps (expected {}, got {})",
3683 maxTargetValueHolder->Id, AsUnderlyingType(*maxTargetsValueHolderEffect), maxTargets, expectedValue);
3684 }
3685 }
3686
3687 if (numNonDiminishedTargetsValueHolderEffect)
3688 {
3689 SpellInfo const* numNonDiminishedTargetsValueHolder = this;
3690 if (numNonDiminishedTargetsValueHolderSpell)
3691 numNonDiminishedTargetsValueHolder = sSpellMgr->GetSpellInfo(*numNonDiminishedTargetsValueHolderSpell, Difficulty);
3692
3693 if (!numNonDiminishedTargetsValueHolder)
3694 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(numNonDiminishedTargets): Spell {} does not exist", *numNonDiminishedTargetsValueHolderSpell);
3695 else if (*numNonDiminishedTargetsValueHolderEffect >= numNonDiminishedTargetsValueHolder->GetEffects().size())
3696 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(numNonDiminishedTargets): Spell {} does not have effect {}",
3697 numNonDiminishedTargetsValueHolder->Id, AsUnderlyingType(*numNonDiminishedTargetsValueHolderEffect));
3698 else
3699 {
3700 SpellEffectInfo const& valueHolder = numNonDiminishedTargetsValueHolder->GetEffect(*numNonDiminishedTargetsValueHolderEffect);
3701 int32 expectedValue = int32(valueHolder.CalcBaseValue(nullptr, nullptr, 0, -1));
3702 if (numNonDiminishedTargets != expectedValue)
3703 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(numNonDiminishedTargets): Spell {} has different value in effect {} than expected, recheck target caps (expected {}, got {})",
3704 numNonDiminishedTargetsValueHolder->Id, AsUnderlyingType(*numNonDiminishedTargetsValueHolderEffect), numNonDiminishedTargets, expectedValue);
3705 }
3706 }
3707}
3708
3709void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& spellEffectInfo, bool apply) const
3710{
3711 SpellEffectInfo::ImmunityInfo const* immuneInfo = spellEffectInfo.GetImmunityInfo();
3712 if (!immuneInfo)
3713 return;
3714
3715 if (uint32 schoolImmunity = immuneInfo->SchoolImmuneMask)
3716 {
3717 target->ApplySpellImmune(Id, IMMUNITY_SCHOOL, schoolImmunity, apply);
3718
3720 {
3721 target->RemoveAppliedAuras([this, schoolImmunity](AuraApplication const* aurApp) -> bool
3722 {
3723 SpellInfo const* auraSpellInfo = aurApp->GetBase()->GetSpellInfo();
3724 if (auraSpellInfo->Id == Id) // Don't remove self
3725 return false;
3726 if (auraSpellInfo->IsPassive()) // Don't remove passive auras
3727 return false;
3728 if (!(auraSpellInfo->GetSchoolMask() & schoolImmunity)) // Check for school mask
3729 return false;
3730 if (!CanDispelAura(auraSpellInfo))
3731 return false;
3732 if (aurApp->IsPositive() && !HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS)) // Check spell vs aura possitivity
3733 return false;
3734 return true;
3735 });
3736 }
3737
3738 if (apply && schoolImmunity & SPELL_SCHOOL_MASK_NORMAL)
3740 }
3741
3742 if (uint64 mechanicImmunity = immuneInfo->MechanicImmuneMask)
3743 {
3744 for (uint32 i = 0; i < MAX_MECHANIC; ++i)
3745 if (mechanicImmunity & (UI64LIT(1) << i))
3746 target->ApplySpellImmune(Id, IMMUNITY_MECHANIC, i, apply);
3747
3749 {
3750 if (apply)
3751 target->RemoveAurasWithMechanic(mechanicImmunity, AURA_REMOVE_BY_DEFAULT, Id, immuneInfo->RemoveEffectsWithMechanic);
3752 else if (!immuneInfo->RemoveEffectsWithMechanic)
3753 {
3754 std::vector<Aura*> aurasToUpdateTargets;
3755 target->RemoveAppliedAuras([mechanicImmunity, &aurasToUpdateTargets](AuraApplication const* aurApp)
3756 {
3757 Aura* aura = aurApp->GetBase();
3758 if (aura->GetSpellInfo()->GetAllEffectsMechanicMask() & mechanicImmunity)
3759 aurasToUpdateTargets.push_back(aura);
3760
3761 // only update targets, don't remove anything
3762 return false;
3763 });
3764
3765 for (Aura* aura : aurasToUpdateTargets)
3766 aura->UpdateTargetMap(aura->GetCaster());
3767 }
3768 }
3769 }
3770
3771 if (uint32 dispelImmunity = immuneInfo->DispelImmuneMask)
3772 {
3773 for (uint32 i = 0; i < DISPEL_MAX; ++i)
3774 if (dispelImmunity & (1 << i))
3775 target->ApplySpellImmune(Id, IMMUNITY_DISPEL, i, apply);
3776
3778 {
3779 target->RemoveAppliedAuras([dispelImmunity](AuraApplication const* aurApp) -> bool
3780 {
3781 SpellInfo const* spellInfo = aurApp->GetBase()->GetSpellInfo();
3782 uint32 dispelMask = spellInfo->GetDispelMask();
3783 if ((dispelMask & dispelImmunity) == dispelMask)
3784 return true;
3785
3786 return false;
3787 });
3788 }
3789 }
3790
3791 if (uint32 damageImmunity = immuneInfo->DamageSchoolMask)
3792 {
3793 target->ApplySpellImmune(Id, IMMUNITY_DAMAGE, damageImmunity, apply);
3794
3795 if (apply && damageImmunity & SPELL_SCHOOL_MASK_NORMAL)
3797 }
3798
3799 for (AuraType auraType : immuneInfo->AuraTypeImmune)
3800 {
3801 target->ApplySpellImmune(Id, IMMUNITY_STATE, auraType, apply);
3803 target->RemoveAurasByType(auraType, [this](AuraApplication const* aurApp) -> bool
3804 {
3805 return CanDispelAura(aurApp->GetBase()->GetSpellInfo());
3806 });
3807 }
3808
3809 for (SpellEffects effectType : immuneInfo->SpellEffectImmune)
3810 target->ApplySpellImmune(Id, IMMUNITY_EFFECT, effectType, apply);
3811
3812 if (uint8 otherImmuneMask = immuneInfo->OtherImmuneMask)
3813 target->ApplySpellImmune(Id, IMMUNITY_OTHER, otherImmuneMask, apply);
3814}
3815
3817{
3818 if (!auraSpellInfo)
3819 return false;
3820
3821 for (SpellEffectInfo const& effectInfo : _effects)
3822 {
3823 if (!effectInfo.IsEffect())
3824 continue;
3825
3826 SpellEffectInfo::ImmunityInfo const* immuneInfo = effectInfo.GetImmunityInfo();
3827 if (!immuneInfo)
3828 continue;
3829
3831 if (uint32 schoolImmunity = immuneInfo->SchoolImmuneMask)
3832 if ((auraSpellInfo->SchoolMask & schoolImmunity) != 0)
3833 return true;
3834
3835 if (uint64 mechanicImmunity = immuneInfo->MechanicImmuneMask)
3836 if ((mechanicImmunity & (UI64LIT(1) << auraSpellInfo->Mechanic)) != 0)
3837 return true;
3838
3839 if (uint32 dispelImmunity = immuneInfo->DispelImmuneMask)
3840 if (auraSpellInfo->Dispel == dispelImmunity)
3841 return true;
3842
3843 bool immuneToAllEffects = true;
3844 for (SpellEffectInfo const& auraSpellEffectInfo : auraSpellInfo->GetEffects())
3845 {
3846 if (!auraSpellEffectInfo.IsAura())
3847 continue;
3848
3849 if (uint64 mechanicImmunity = immuneInfo->MechanicImmuneMask)
3850 if ((mechanicImmunity & (UI64LIT(1) << auraSpellEffectInfo.Mechanic)) != 0)
3851 continue;
3852
3853 if (AuraType auraName = auraSpellEffectInfo.ApplyAuraName)
3854 {
3855 if (immuneInfo->AuraTypeImmune.find(auraName) != immuneInfo->AuraTypeImmune.end())
3856 continue;
3857
3858 if (!auraSpellInfo->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES) && !auraSpellInfo->IsPositiveEffect(auraSpellEffectInfo.EffectIndex))
3859 if (uint32 applyHarmfulAuraImmunityMask = immuneInfo->ApplyHarmfulAuraImmuneMask)
3860 if ((auraSpellInfo->GetSchoolMask() & applyHarmfulAuraImmunityMask) != 0)
3861 continue;
3862 }
3863
3864 immuneToAllEffects = false;
3865 }
3866
3867 if (immuneToAllEffects)
3868 return true;
3869 }
3870
3871 return false;
3872}
3873
3874bool SpellInfo::CanSpellEffectProvideImmunityAgainstAuraEffect(SpellEffectInfo const& immunityEffectInfo, SpellInfo const* auraSpellInfo, SpellEffectInfo const& auraEffectInfo) const
3875{
3876 SpellEffectInfo::ImmunityInfo const* immuneInfo = immunityEffectInfo.GetImmunityInfo();
3877 if (!immuneInfo)
3878 return false;
3879
3881 {
3882 if (uint32 schoolImmunity = immuneInfo->SchoolImmuneMask)
3883 if ((auraSpellInfo->SchoolMask & schoolImmunity) != 0)
3884 return true;
3885
3886 if (uint32 applyHarmfulAuraImmunityMask = immuneInfo->ApplyHarmfulAuraImmuneMask)
3887 if ((auraSpellInfo->GetSchoolMask() & applyHarmfulAuraImmunityMask) != 0)
3888 return true;
3889 }
3890
3891 if (uint64 mechanicImmunity = immuneInfo->MechanicImmuneMask)
3892 {
3893 if ((mechanicImmunity & (UI64LIT(1) << auraSpellInfo->Mechanic)) != 0)
3894 return true;
3895 if ((mechanicImmunity & (UI64LIT(1) << auraEffectInfo.Mechanic)) != 0)
3896 return true;
3897 }
3898
3899 if (uint32 dispelImmunity = immuneInfo->DispelImmuneMask)
3900 if (auraSpellInfo->Dispel == dispelImmunity)
3901 return true;
3902
3903 if (immuneInfo->AuraTypeImmune.find(auraEffectInfo.ApplyAuraName) != immuneInfo->AuraTypeImmune.end())
3904 return true;
3905
3906 return false;
3907}
3908
3909// based on client Spell_C::CancelsAuraEffect
3911{
3913 return false;
3914
3916 return false;
3917
3919 return false;
3920
3921 for (SpellEffectInfo const& effect : GetEffects())
3923 return true;
3924
3925 return false;
3926}
3927
3932
3934{
3935 uint64 casterMechanicImmunityMask = caster->GetMechanicImmunityMask();
3936 uint64 mechanicImmunityMask = 0;
3937
3938 if (CanBeInterrupted(nullptr, caster, true))
3939 {
3940 if (casterMechanicImmunityMask & (1 << MECHANIC_SILENCE))
3941 mechanicImmunityMask |= (1 << MECHANIC_SILENCE);
3942
3943 if (casterMechanicImmunityMask & (1 << MECHANIC_INTERRUPT))
3944 mechanicImmunityMask |= (1 << MECHANIC_INTERRUPT);
3945 }
3946
3947 return mechanicImmunityMask;
3948}
3949
3950float SpellInfo::GetMinRange(bool positive /*= false*/) const
3951{
3952 if (!RangeEntry)
3953 return 0.0f;
3954 return RangeEntry->RangeMin[positive ? 1 : 0];
3955}
3956
3957float SpellInfo::GetMaxRange(bool positive /*= false*/, WorldObject const* caster /*= nullptr*/, Spell* spell /*= nullptr*/) const
3958{
3959 if (!RangeEntry)
3960 return 0.0f;
3961 float range = RangeEntry->RangeMax[positive ? 1 : 0];
3962 if (caster)
3963 if (Player* modOwner = caster->GetSpellModOwner())
3964 modOwner->ApplySpellMod(this, SpellModOp::Range, range, spell);
3965
3966 return range;
3967}
3968
3969SpellRange SpellInfo::GetMinMaxRange(bool positive, WorldObject const* caster, Spell* spell) const
3970{
3971 SpellRange range;
3972 if (!RangeEntry)
3973 return range;
3974
3975 range = { .Min = RangeEntry->RangeMin[positive ? 1 : 0], .Max = RangeEntry->RangeMax[positive ? 1 : 0] };
3976 if (caster)
3977 if (Player* modOwner = caster->GetSpellModOwner())
3978 modOwner->ApplySpellMod(this, SpellModOp::Range, range.Max, spell);
3979
3980 return range;
3981}
3982
3983int32 SpellInfo::CalcDuration(WorldObject const* caster /*= nullptr*/) const
3984{
3985 int32 duration = GetDuration();
3986
3987 if (caster)
3988 if (Player* modOwner = caster->GetSpellModOwner())
3989 modOwner->ApplySpellMod(this, SpellModOp::Duration, duration);
3990
3991 return duration;
3992}
3993
3995{
3996 if (!DurationEntry)
3997 return IsPassive() ? -1 : 0;
3998 return (DurationEntry->Duration == -1) ? -1 : abs(DurationEntry->Duration);
3999}
4000
4002{
4003 if (!DurationEntry)
4004 return IsPassive() ? -1 : 0;
4005 return (DurationEntry->MaxDuration == -1) ? -1 : abs(DurationEntry->MaxDuration);
4006}
4007
4008uint32 SpellInfo::CalcCastTime(Spell* spell /*= nullptr*/) const
4009{
4010 int32 castTime = 0;
4011 if (CastTimeEntry)
4012 castTime = std::max(CastTimeEntry->Base, CastTimeEntry->Minimum);
4013
4014 if (castTime <= 0)
4015 return 0;
4016
4017 if (spell)
4018 spell->GetCaster()->ModSpellCastTime(this, castTime, spell);
4019
4020 return (castTime > 0) ? uint32(castTime) : 0;
4021}
4022
4027
4028Optional<SpellPowerCost> SpellInfo::CalcPowerCost(Powers powerType, bool optionalCost, WorldObject const* caster, SpellSchoolMask schoolMask, Spell* spell /*= nullptr*/) const
4029{
4030 // gameobject casts don't use power
4031 Unit const* unitCaster = caster->ToUnit();
4032 if (!unitCaster)
4033 return {};
4034
4035 auto itr = std::find_if(PowerCosts.cbegin(), PowerCosts.cend(), [powerType](SpellPowerEntry const* spellPowerEntry)
4036 {
4037 return spellPowerEntry && spellPowerEntry->PowerType == powerType;
4038 });
4039 if (itr == PowerCosts.cend())
4040 return {};
4041
4042 return CalcPowerCost(*itr, optionalCost, caster, schoolMask, spell);
4043}
4044
4045Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power, bool optionalCost, WorldObject const* caster, SpellSchoolMask schoolMask, Spell* spell /*= nullptr*/) const
4046{
4047 // gameobject casts don't use power
4048 Unit const* unitCaster = caster->ToUnit();
4049 if (!unitCaster)
4050 return {};
4051
4052 if (power->RequiredAuraSpellID && !unitCaster->HasAura(power->RequiredAuraSpellID))
4053 return {};
4054
4055 // Spell drain all exist power on cast (Only paladin lay of Hands)
4057 {
4058 if (optionalCost)
4059 return {};
4060
4061 // If power type - health drain all
4062 if (power->PowerType == POWER_HEALTH)
4063 return SpellPowerCost{ .Power = POWER_HEALTH, .Amount = int32(unitCaster->GetHealth()) };
4064
4065 // Else drain all power
4066 if (power->PowerType < MAX_POWERS)
4067 return SpellPowerCost{ .Power = Powers(power->PowerType), .Amount = unitCaster->GetPower(Powers(power->PowerType)) };
4068
4069 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type '{}' in spell {}", power->PowerType, Id);
4070 return {};
4071 }
4072
4073 // Base powerCost
4074 int32 powerCost = 0;
4075 if (!optionalCost)
4076 {
4077 powerCost = power->ManaCost;
4078 // PCT cost from total amount
4079 if (power->PowerCostPct)
4080 {
4081 switch (power->PowerType)
4082 {
4083 // health as power used
4084 case POWER_HEALTH:
4085 if (G3D::fuzzyEq(power->PowerCostPct, 0.0f))
4086 powerCost += int32(CalculatePct(unitCaster->GetMaxHealth(), power->PowerCostMaxPct));
4087 else
4088 powerCost += int32(CalculatePct(unitCaster->GetMaxHealth(), power->PowerCostPct));
4089 break;
4090 case POWER_MANA:
4091 powerCost += int32(CalculatePct(unitCaster->GetCreateMana(), power->PowerCostPct));
4092 break;
4094 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type POWER_ALTERNATE_POWER in spell {}", Id);
4095 return {};
4096 default:
4097 {
4098 if (PowerTypeEntry const* powerTypeEntry = sDB2Manager.GetPowerTypeEntry(Powers(power->PowerType)))
4099 {
4100 powerCost += int32(CalculatePct(powerTypeEntry->MaxBasePower, power->PowerCostPct));
4101 break;
4102 }
4103
4104 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type '{}' in spell {}", power->PowerType, Id);
4105 return {};
4106 }
4107 }
4108 }
4109 }
4110 else
4111 {
4112 powerCost = int32(power->OptionalCost);
4113
4114 if (power->OptionalCostPct)
4115 {
4116 switch (power->PowerType)
4117 {
4118 // health as power used
4119 case POWER_HEALTH:
4120 powerCost += int32(CalculatePct(unitCaster->GetMaxHealth(), power->OptionalCostPct));
4121 break;
4122 case POWER_MANA:
4123 powerCost += int32(CalculatePct(unitCaster->GetCreateMana(), power->OptionalCostPct));
4124 break;
4126 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unsupported power type POWER_ALTERNATE_POWER in spell {} for optional cost percent", Id);
4127 return {};
4128 default:
4129 {
4130 if (PowerTypeEntry const* powerTypeEntry = sDB2Manager.GetPowerTypeEntry(Powers(power->PowerType)))
4131 {
4132 powerCost += int32(CalculatePct(powerTypeEntry->MaxBasePower, power->OptionalCostPct));
4133 break;
4134 }
4135
4136 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type '{}' in spell {} for optional cost percent", power->PowerType, Id);
4137 return {};
4138 }
4139 }
4140 }
4141
4142 powerCost += unitCaster->GetTotalAuraModifier(SPELL_AURA_MOD_ADDITIONAL_POWER_COST, [this, power](AuraEffect const* aurEff) -> bool
4143 {
4144 return aurEff->GetMiscValue() == power->PowerType
4145 && aurEff->IsAffectingSpell(this);
4146 });
4147 }
4148
4149 bool initiallyNegative = powerCost < 0;
4150
4151 // Shiv - costs 20 + weaponSpeed*10 energy (apply only to non-triggered spell with energy cost)
4153 {
4154 uint32 speed = 0;
4155 if (SpellShapeshiftFormEntry const* ss = sSpellShapeshiftFormStore.LookupEntry(unitCaster->GetShapeshiftForm()))
4156 speed = ss->CombatRoundTime;
4157 else
4158 {
4161 slot = OFF_ATTACK;
4162
4163 speed = unitCaster->GetBaseAttackTime(slot);
4164 }
4165
4166 powerCost += speed / 100;
4167 }
4168
4169 if (power->PowerType != POWER_HEALTH)
4170 {
4171 if (!optionalCost)
4172 {
4173 // Flat mod from caster auras by spell school and power type
4175 {
4176 if (!(aura->GetMiscValue() & schoolMask))
4177 continue;
4178
4179 if (!(aura->GetMiscValueB() & (1 << power->PowerType)))
4180 continue;
4181
4182 powerCost += aura->GetAmount();
4183 }
4184 }
4185
4186 // PCT mod from user auras by spell school and power type
4187 for (auto schoolCostPct : unitCaster->GetAuraEffectsByType(SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT))
4188 {
4189 if (!(schoolCostPct->GetMiscValue() & schoolMask))
4190 continue;
4191
4192 if (!(schoolCostPct->GetMiscValueB() & (1 << power->PowerType)))
4193 continue;
4194
4195 powerCost += CalculatePct(powerCost, schoolCostPct->GetAmount());
4196 }
4197 }
4198
4199 // Apply cost mod by spell
4200 if (Player* modOwner = unitCaster->GetSpellModOwner())
4201 {
4203 switch (power->OrderIndex)
4204 {
4205 case 0:
4207 break;
4208 case 1:
4210 break;
4211 case 2:
4213 break;
4214 default:
4215 break;
4216 }
4217
4218 if (mod)
4219 {
4220 if (!optionalCost)
4221 modOwner->ApplySpellMod(this, *mod, powerCost, spell);
4222 else
4223 {
4224 // optional cost ignores flat modifiers
4225 int32 flatMod = 0;
4226 float pctMod = 1.0f;
4227 modOwner->GetSpellModValues(this, *mod, spell, powerCost, &flatMod, &pctMod);
4228 powerCost = int32(powerCost * pctMod);
4229 }
4230 }
4231 }
4232
4233 if (!unitCaster->IsControlledByPlayer() && G3D::fuzzyEq(power->PowerCostPct, 0.0f) && SpellLevel && power->PowerType == POWER_MANA)
4234 {
4236 {
4238 GtNpcManaCostScalerEntry const* casterScaler = sNpcManaCostScalerGameTable.GetRow(unitCaster->GetLevel());
4239 if (spellScaler && casterScaler)
4240 powerCost *= casterScaler->Scaler / spellScaler->Scaler;
4241 }
4242 }
4243
4244 if (power->PowerType == POWER_MANA)
4245 powerCost = float(powerCost) * (1.0f + unitCaster->m_unitData->ManaCostMultiplier);
4246
4247 // power cost cannot become negative if initially positive
4248 if (initiallyNegative != (powerCost < 0))
4249 powerCost = 0;
4250
4251 return SpellPowerCost{ .Power = Powers(power->PowerType), .Amount = powerCost };
4252}
4253
4254std::vector<SpellPowerCost> SpellInfo::CalcPowerCost(WorldObject const* caster, SpellSchoolMask schoolMask, Spell* spell) const
4255{
4256 std::vector<SpellPowerCost> costs;
4257 if (caster->IsUnit())
4258 {
4259 costs.reserve(MAX_POWERS_PER_SPELL);
4260
4261 auto getOrCreatePowerCost = [&](Powers powerType) -> SpellPowerCost&
4262 {
4263 auto itr = std::find_if(costs.begin(), costs.end(), [powerType](SpellPowerCost const& cost)
4264 {
4265 return cost.Power == powerType;
4266 });
4267 if (itr != costs.end())
4268 return *itr;
4269
4270 return costs.emplace_back<SpellPowerCost>({ .Power = powerType, .Amount = 0 });
4271 };
4272
4273 for (SpellPowerEntry const* power : PowerCosts)
4274 {
4275 if (!power)
4276 continue;
4277
4278 if (Optional<SpellPowerCost> cost = CalcPowerCost(power, false, caster, schoolMask, spell))
4279 getOrCreatePowerCost(cost->Power).Amount += cost->Amount;
4280
4281 if (Optional<SpellPowerCost> optionalCost = CalcPowerCost(power, true, caster, schoolMask, spell))
4282 {
4283 SpellPowerCost& cost = getOrCreatePowerCost(optionalCost->Power);
4284 int32 remainingPower = caster->ToUnit()->GetPower(optionalCost->Power) - cost.Amount;
4285 if (remainingPower > 0)
4286 cost.Amount += std::min(optionalCost->Amount, remainingPower);
4287 }
4288 }
4289 }
4290
4291 return costs;
4292}
4293
4294inline float CalcPPMHasteMod(SpellProcsPerMinuteModEntry const* mod, Unit* caster)
4295{
4296 float haste = caster->m_unitData->ModHaste;
4297 float rangedHaste = caster->m_unitData->ModRangedHaste;
4298 float spellHaste = caster->m_unitData->ModSpellHaste;
4299 float regenHaste = caster->m_unitData->ModHasteRegen;
4300
4301 switch (mod->Param)
4302 {
4303 case 1:
4304 return (1.0f / haste - 1.0f) * mod->Coeff;
4305 case 2:
4306 return (1.0f / rangedHaste - 1.0f) * mod->Coeff;
4307 case 3:
4308 return (1.0f / spellHaste - 1.0f) * mod->Coeff;
4309 case 4:
4310 return (1.0f / regenHaste - 1.0f) * mod->Coeff;
4311 case 5:
4312 return (1.0f / std::min(std::min(std::min(haste, rangedHaste), spellHaste), regenHaste) - 1.0f) * mod->Coeff;
4313 default:
4314 break;
4315 }
4316
4317 return 0.0f;
4318}
4319
4320inline float CalcPPMCritMod(SpellProcsPerMinuteModEntry const* mod, Unit* caster)
4321{
4322 Player const* player = caster->ToPlayer();
4323 if (!player)
4324 return 0.0f;
4325
4326 float crit = player->m_activePlayerData->CritPercentage;
4327 float rangedCrit = player->m_activePlayerData->RangedCritPercentage;
4328 float spellCrit = player->m_activePlayerData->SpellCritPercentage;
4329
4330 switch (mod->Param)
4331 {
4332 case 1:
4333 return crit * mod->Coeff * 0.01f;
4334 case 2:
4335 return rangedCrit * mod->Coeff * 0.01f;
4336 case 3:
4337 return spellCrit * mod->Coeff * 0.01f;
4338 case 4:
4339 return std::min(std::min(crit, rangedCrit), spellCrit) * mod->Coeff * 0.01f;
4340 default:
4341 break;
4342 }
4343
4344 return 0.0f;
4345}
4346
4347inline float CalcPPMItemLevelMod(SpellProcsPerMinuteModEntry const* mod, int32 itemLevel)
4348{
4349 if (itemLevel == mod->Param)
4350 return 0.0f;
4351
4352 float itemLevelPoints = GetRandomPropertyPoints(itemLevel, ITEM_QUALITY_RARE, INVTYPE_CHEST, 0);
4353 float basePoints = GetRandomPropertyPoints(mod->Param, ITEM_QUALITY_RARE, INVTYPE_CHEST, 0);
4354 if (itemLevelPoints == basePoints)
4355 return 0.0f;
4356
4357 return ((itemLevelPoints / basePoints) - 1.0f) * mod->Coeff;
4358}
4359
4360float SpellInfo::CalcProcPPM(Unit* caster, int32 itemLevel) const
4361{
4362 float ppm = ProcBasePPM;
4363 if (!caster)
4364 return ppm;
4365
4366 for (SpellProcsPerMinuteModEntry const* mod : ProcPPMMods)
4367 {
4368 switch (mod->Type)
4369 {
4371 {
4372 ppm *= 1.0f + CalcPPMHasteMod(mod, caster);
4373 break;
4374 }
4375 case SPELL_PPM_MOD_CRIT:
4376 {
4377 ppm *= 1.0f + CalcPPMCritMod(mod, caster);
4378 break;
4379 }
4381 {
4382 if (caster->GetClassMask() & mod->Param)
4383 ppm *= 1.0f + mod->Coeff;
4384 break;
4385 }
4386 case SPELL_PPM_MOD_SPEC:
4387 {
4388 if (Player* plrCaster = caster->ToPlayer())
4389 if (plrCaster->GetPrimarySpecialization() == ChrSpecialization(mod->Param))
4390 ppm *= 1.0f + mod->Coeff;
4391 break;
4392 }
4393 case SPELL_PPM_MOD_RACE:
4394 {
4395 if (Trinity::RaceMask<int32>{ mod->Param }.HasRace(caster->GetRace()))
4396 ppm *= 1.0f + mod->Coeff;
4397 break;
4398 }
4400 {
4401 ppm *= 1.0f + CalcPPMItemLevelMod(mod, itemLevel);
4402 break;
4403 }
4405 {
4406 if (caster->GetMap()->IsBattlegroundOrArena())
4407 ppm *= 1.0f + mod->Coeff;
4408 break;
4409 }
4410 case SPELL_PPM_MOD_AURA:
4411 {
4412 if (caster->HasAura(mod->Param))
4413 ppm *= 1.0f + mod->Coeff;
4414 break;
4415 }
4416 default:
4417 break;
4418 }
4419 }
4420
4421 return ppm;
4422}
4423
4425{
4426 return ChainEntry != nullptr;
4427}
4428
4430{
4431 if (!ChainEntry)
4432 return 1;
4433 return ChainEntry->rank;
4434}
4435
4437{
4438 if (!ChainEntry)
4439 return this;
4440 return ChainEntry->first;
4441}
4442
4444{
4445 if (!ChainEntry)
4446 return nullptr;
4447 return ChainEntry->last;
4448}
4449
4451{
4452 if (!ChainEntry)
4453 return nullptr;
4454 return ChainEntry->next;
4455}
4456
4458{
4459 if (!ChainEntry)
4460 return nullptr;
4461 return ChainEntry->prev;
4462}
4463
4465{
4466 // ignore passive spells
4467 if (IsPassive())
4468 return this;
4469
4470 // Client ignores spell with these attributes (sub_53D9D0)
4472 return this;
4473
4474 bool needRankSelection = false;
4475 for (SpellEffectInfo const& effect : GetEffects())
4476 {
4477 if (IsPositiveEffect(effect.EffectIndex) &&
4478 (effect.Effect == SPELL_EFFECT_APPLY_AURA ||
4479 effect.Effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
4480 effect.Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID) &&
4481 !effect.Scaling.Coefficient)
4482 {
4483 needRankSelection = true;
4484 break;
4485 }
4486 }
4487
4488 // not required
4489 if (!needRankSelection)
4490 return this;
4491
4492 for (SpellInfo const* nextSpellInfo = this; nextSpellInfo != nullptr; nextSpellInfo = nextSpellInfo->GetPrevRankSpell())
4493 {
4494 // if found appropriate level
4495 if (uint32(level + 10) >= nextSpellInfo->SpellLevel)
4496 return nextSpellInfo;
4497
4498 // one rank less then
4499 }
4500
4501 // not found
4502 return nullptr;
4503}
4504
4505bool SpellInfo::IsRankOf(SpellInfo const* spellInfo) const
4506{
4507 return GetFirstRankSpell() == spellInfo->GetFirstRankSpell();
4508}
4509
4510bool SpellInfo::IsDifferentRankOf(SpellInfo const* spellInfo) const
4511{
4512 if (Id == spellInfo->Id)
4513 return false;
4514 return IsRankOf(spellInfo);
4515}
4516
4517bool SpellInfo::IsHighRankOf(SpellInfo const* spellInfo) const
4518{
4519 if (ChainEntry && spellInfo->ChainEntry)
4520 if (ChainEntry->first == spellInfo->ChainEntry->first)
4521 if (ChainEntry->rank > spellInfo->ChainEntry->rank)
4522 return true;
4523
4524 return false;
4525}
4526
4527uint32 SpellInfo::GetSpellXSpellVisualId(WorldObject const* caster /*= nullptr*/, WorldObject const* viewer /*= nullptr*/) const
4528{
4529 auto canUseSpellVisual = [=](SpellXSpellVisualEntry const* visual)
4530 {
4531 if (visual->CasterPlayerConditionID)
4532 if (!caster || !caster->IsPlayer() || !ConditionMgr::IsPlayerMeetingCondition(caster->ToPlayer(), visual->CasterPlayerConditionID))
4533 return false;
4534
4535 if (UnitConditionEntry const* unitCondition = sUnitConditionStore.LookupEntry(visual->CasterUnitConditionID))
4536 if (!caster || !caster->IsUnit() || !ConditionMgr::IsUnitMeetingCondition(caster->ToUnit(), Object::ToUnit(viewer), unitCondition))
4537 return false;
4538
4539 return true;
4540 };
4541
4542 for (auto itr = _visuals.begin(), end = _visuals.end(); itr != end; ++itr)
4543 {
4544 if (!canUseSpellVisual(*itr))
4545 continue;
4546
4547 // match found, now select among all visuals with the same priority
4548 boost::container::small_vector<SpellXSpellVisualEntry const*, 4> visualCandidates;
4549 visualCandidates.push_back(*itr);
4550
4551 for (auto itr2 = itr + 1; itr2 != end && (*itr)->Priority == (*itr2)->Priority; ++itr2)
4552 if (canUseSpellVisual(*itr2))
4553 visualCandidates.push_back(*itr2);
4554
4555 if (visualCandidates.size() == 1)
4556 return visualCandidates.front()->ID; // special case, ignores Probability
4557
4558 return (*Trinity::Containers::SelectRandomWeightedContainerElement(visualCandidates, [](SpellXSpellVisualEntry const* visual) { return visual->Probability; }))->ID;
4559 }
4560
4561 return 0;
4562}
4563
4564uint32 SpellInfo::GetSpellVisual(WorldObject const* caster /*= nullptr*/, WorldObject const* viewer /*= nullptr*/) const
4565{
4566 if (SpellXSpellVisualEntry const* visual = sSpellXSpellVisualStore.LookupEntry(GetSpellXSpellVisualId(caster, viewer)))
4567 {
4568 //if (visual->LowViolenceSpellVisualID && forPlayer->GetViolenceLevel() operator 2)
4569 // return visual->LowViolenceSpellVisualID;
4570
4571 return visual->SpellVisualID;
4572 }
4573
4574 return 0;
4575}
4576
4578{
4579 bool srcSet = false;
4580 bool dstSet = false;
4581 // prepare target mask using effect target entries
4582 for (SpellEffectInfo const& effect : GetEffects())
4583 {
4584 if (!effect.IsEffect())
4585 continue;
4586
4587 uint32 targetMask = 0;
4588 targetMask |= effect.TargetA.GetExplicitTargetMask(srcSet, dstSet);
4589 targetMask |= effect.TargetB.GetExplicitTargetMask(srcSet, dstSet);
4590
4591 // add explicit target flags based on spell effects which have EFFECT_IMPLICIT_TARGET_EXPLICIT and no valid target provided
4592 if (effect.GetImplicitTargetType() == EFFECT_IMPLICIT_TARGET_EXPLICIT)
4593 {
4594 // extend explicit target mask only if valid targets for effect could not be provided by target types
4595 uint32 effectTargetMask = effect.GetMissingTargetMask(srcSet, dstSet, targetMask);
4596
4597 // don't add explicit object/dest flags when spell has no max range
4598 if (GetMaxRange(true) == 0.0f && GetMaxRange(false) == 0.0f)
4600
4601 targetMask |= effectTargetMask;
4602 }
4603
4604 ExplicitTargetMask |= targetMask;
4605 if (!effect.EffectAttributes.HasFlag(SpellEffectAttributes::DontFailSpellOnTargetingFailure))
4606 RequiredExplicitTargetMask |= targetMask;
4607 }
4608
4612}
4613
4614inline bool _isPositiveTarget(SpellEffectInfo const& effect)
4615{
4616 if (!effect.IsEffect())
4617 return true;
4618
4619 return (effect.TargetA.GetCheckType() != TARGET_CHECK_ENEMY &&
4621}
4622
4623bool _isPositiveEffectImpl(SpellInfo const* spellInfo, SpellEffectInfo const& effect, std::unordered_set<std::pair<SpellInfo const*, SpellEffIndex>>& visited)
4624{
4625 if (!effect.IsEffect())
4626 return true;
4627
4628 // attribute may be already set in DB
4629 if (!spellInfo->IsPositiveEffect(effect.EffectIndex))
4630 return false;
4631
4632 // passive auras like talents are all positive
4633 if (spellInfo->IsPassive())
4634 return true;
4635
4636 // not found a single positive spell with this attribute
4638 return false;
4639
4640 if (spellInfo->HasAttribute(SPELL_ATTR4_AURA_IS_BUFF))
4641 return true;
4642
4644 return false;
4645
4646 visited.insert({ spellInfo, effect.EffectIndex });
4647
4648 //We need scaling level info for some auras that compute bp 0 or positive but should be debuffs
4649 float bpScalePerLevel = effect.RealPointsPerLevel;
4650 SpellEffectValue bp = effect.CalcValue();
4651 switch (spellInfo->SpellFamilyName)
4652 {
4654 switch (spellInfo->Id)
4655 {
4656 case 40268: // Spiritual Vengeance, Teron Gorefiend, Black Temple
4657 case 61987: // Avenging Wrath Marker
4658 case 61988: // Divine Shield exclude aura
4659 case 64412: // Phase Punch, Algalon the Observer, Ulduar
4660 case 72410: // Rune of Blood, Saurfang, Icecrown Citadel
4661 case 71204: // Touch of Insignificance, Lady Deathwhisper, Icecrown Citadel
4662 return false;
4663 case 24732: // Bat Costume
4664 case 30877: // Tag Murloc
4665 case 61716: // Rabbit Costume
4666 case 61734: // Noblegarden Bunny
4667 case 62344: // Fists of Stone
4668 case 50344: // Dream Funnel
4669 case 61819: // Manabonked! (item)
4670 case 61834: // Manabonked! (minigob)
4671 case 73523: // Rigor Mortis
4672 return true;
4673 default:
4674 break;
4675 }
4676 break;
4677 case SPELLFAMILY_ROGUE:
4678 switch (spellInfo->Id)
4679 {
4680 // Envenom must be considered as a positive effect even though it deals damage
4681 case 32645: // Envenom
4682 return true;
4683 case 40251: // Shadow of Death, Teron Gorefiend, Black Temple
4684 return false;
4685 default:
4686 break;
4687 }
4688 break;
4690 // Slam, Execute
4691 if ((spellInfo->SpellFamilyFlags[0] & 0x20200000) != 0)
4692 return false;
4693 break;
4694 default:
4695 break;
4696 }
4697
4698 switch (spellInfo->Mechanic)
4699 {
4701 return true;
4702 default:
4703 break;
4704 }
4705
4706 // Special case: effects which determine positivity of whole spell
4707 if (spellInfo->HasAttribute(SPELL_ATTR1_AURA_UNIQUE))
4708 {
4709 // check for targets, there seems to be an assortment of dummy triggering spells that should be negative
4710 for (SpellEffectInfo const& otherEffect : spellInfo->GetEffects())
4711 if (!_isPositiveTarget(otherEffect))
4712 return false;
4713 }
4714
4715 for (SpellEffectInfo const& otherEffect : spellInfo->GetEffects())
4716 {
4717 switch (otherEffect.Effect)
4718 {
4719 case SPELL_EFFECT_HEAL:
4723 return true;
4725 if (otherEffect.EffectIndex != effect.EffectIndex && // for spells like 38044: instakill effect is negative but auras on target must count as buff
4726 otherEffect.TargetA.GetTarget() == effect.TargetA.GetTarget() &&
4727 otherEffect.TargetB.GetTarget() == effect.TargetB.GetTarget())
4728 return false;
4729 break;
4730 default:
4731 break;
4732 }
4733
4734 if (otherEffect.IsAura())
4735 {
4736 switch (otherEffect.ApplyAuraName)
4737 {
4740 return true;
4742 case SPELL_AURA_EMPATHY:
4745 return false;
4746 default:
4747 break;
4748 }
4749 }
4750 }
4751
4752 switch (effect.Effect)
4753 {
4772 return false;
4778 return true;
4784 // check targets
4785 if (!_isPositiveTarget(effect))
4786 return false;
4787 break;
4789 // non-positive dispel
4790 switch (effect.MiscValue)
4791 {
4792 case DISPEL_STEALTH:
4794 case DISPEL_ENRAGE:
4795 return false;
4796 default:
4797 break;
4798 }
4799
4800 // also check targets
4801 if (!_isPositiveTarget(effect))
4802 return false;
4803 break;
4805 if (!_isPositiveTarget(effect))
4806 {
4807 // non-positive mechanic dispel on negative target
4808 switch (effect.MiscValue)
4809 {
4810 case MECHANIC_BANDAGE:
4811 case MECHANIC_SHIELD:
4812 case MECHANIC_MOUNT:
4814 return false;
4815 default:
4816 break;
4817 }
4818 }
4819 break;
4822 // check targets AND basepoints
4823 if (!_isPositiveTarget(effect) && bp > 0)
4824 return false;
4825 break;
4826 default:
4827 break;
4828 }
4829
4830 if (effect.IsAura())
4831 {
4832 // non-positive aura use
4833 switch (effect.ApplyAuraName)
4834 {
4835 case SPELL_AURA_MOD_STAT: // dependent from basepoint sign (negative -> negative)
4864 if (bp < 0 || bpScalePerLevel < 0) //TODO: What if both are 0? Should it be a buff or debuff?
4865 return false;
4866 break;
4867 case SPELL_AURA_MOD_ATTACKSPEED: // some buffs have negative bp, check both target and bp
4882 if (!_isPositiveTarget(effect) || bp < 0)
4883 return false;
4884 break;
4885 case SPELL_AURA_MOD_DAMAGE_TAKEN: // dependent from basepoint sign (positive -> negative)
4891 if (bp > 0)
4892 return false;
4893 break;
4894 case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN: // check targets and basepoints (ex Recklessness)
4895 if (!_isPositiveTarget(effect) && bp > 0)
4896 return false;
4897 break;
4898 case SPELL_AURA_MOD_HEALTH_REGEN_PERCENT: // check targets and basepoints (target enemy and negative bp -> negative)
4899 if (!_isPositiveTarget(effect) && bp < 0)
4900 return false;
4901 break;
4903 return true;
4906 if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(effect.TriggerSpell, spellInfo->Difficulty))
4907 {
4908 // negative targets of main spell return early
4909 for (SpellEffectInfo const& spellTriggeredEffect : spellTriggeredProto->GetEffects())
4910 {
4911 // already seen this
4912 if (visited.count({ spellTriggeredProto, spellTriggeredEffect.EffectIndex }) > 0)
4913 continue;
4914
4915 if (!spellTriggeredEffect.IsEffect())
4916 continue;
4917
4918 // if non-positive trigger cast targeted to positive target this main cast is non-positive
4919 // this will place this spell auras as debuffs
4920 if (_isPositiveTarget(spellTriggeredEffect) && !_isPositiveEffectImpl(spellTriggeredProto, spellTriggeredEffect, visited))
4921 return false;
4922 }
4923 }
4924 break;
4931 // special auras: they may have non negative target but still need to be marked as debuff
4932 // checked again after all effects (SpellInfo::_InitializeSpellPositivity)
4949 case SPELL_AURA_DUMMY:
4965 // check target for positive and negative spells
4966 if (!_isPositiveTarget(effect))
4967 return false;
4968 break;
4975 case SPELL_AURA_GHOST:
4985 return false;
4987 {
4988 // non-positive immunities
4989 switch (effect.MiscValue)
4990 {
4991 case MECHANIC_BANDAGE:
4992 case MECHANIC_SHIELD:
4993 case MECHANIC_MOUNT:
4995 return false;
4996 default:
4997 break;
4998 }
4999 break;
5000 }
5001 case SPELL_AURA_ADD_FLAT_MODIFIER: // mods
5005 {
5006 switch (SpellModOp(effect.MiscValue))
5007 {
5008 case SpellModOp::ChangeCastTime: // dependent from basepoint sign (positive -> negative)
5009 case SpellModOp::Period:
5012 if (bp > 0)
5013 return false;
5014 break;
5019 if (!spellInfo->IsPositive() && bp > 0) // dependent on prev effects too (ex Arcane Power)
5020 return false;
5021 break;
5022 case SpellModOp::PointsIndex0: // always positive
5027 case SpellModOp::Points:
5028 case SpellModOp::Hate:
5031 return true;
5036 if (!spellInfo->IsPositive() && bp < 0) // dependent on prev effects too
5037 return false;
5038 break;
5039 default: // dependent from basepoint sign (negative -> negative)
5040 if (bp < 0)
5041 return false;
5042 break;
5043 }
5044 break;
5045 }
5046 default:
5047 break;
5048 }
5049 }
5050
5051 // negative spell if triggered spell is negative
5052 if (!effect.ApplyAuraName && effect.TriggerSpell)
5053 {
5054 if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(effect.TriggerSpell, spellInfo->Difficulty))
5055 {
5056 // spells with at least one negative effect are considered negative
5057 // some self-applied spells have negative effects but in self casting case negative check ignored.
5058 for (SpellEffectInfo const& spellTriggeredEffect : spellTriggeredProto->GetEffects())
5059 {
5060 // already seen this
5061 if (visited.count({ spellTriggeredProto, spellTriggeredEffect.EffectIndex }) > 0)
5062 continue;
5063
5064 if (!spellTriggeredEffect.IsEffect())
5065 continue;
5066
5067 if (!_isPositiveEffectImpl(spellTriggeredProto, spellTriggeredEffect, visited))
5068 return false;
5069 }
5070 }
5071 }
5072
5073 // ok, positive
5074 return true;
5075}
5076
5078{
5079 std::unordered_set<std::pair<SpellInfo const*, SpellEffIndex /*effIndex*/>> visited;
5080
5081 for (SpellEffectInfo const& effect : GetEffects())
5082 if (!_isPositiveEffectImpl(this, effect, visited))
5083 NegativeEffects[effect.EffectIndex] = true;
5084
5085 // additional checks after effects marked
5086 for (SpellEffectInfo const& effect : GetEffects())
5087 {
5088 if (!effect.IsEffect() || !IsPositiveEffect(effect.EffectIndex))
5089 continue;
5090
5091 switch (effect.ApplyAuraName)
5092 {
5093 // has other non positive effect?
5094 // then it should be marked negative if has same target as negative effect (ex 8510, 8511, 8893, 10267)
5095 case SPELL_AURA_DUMMY:
5102 {
5103 for (size_t j = effect.EffectIndex + 1; j < GetEffects().size(); ++j)
5104 if (!IsPositiveEffect(j)
5105 && effect.TargetA.GetTarget() == GetEffect(SpellEffIndex(j)).TargetA.GetTarget()
5106 && effect.TargetB.GetTarget() == GetEffect(SpellEffIndex(j)).TargetB.GetTarget())
5107 NegativeEffects[effect.EffectIndex] = true;
5108 break;
5109 }
5110 default:
5111 break;
5112 }
5113 }
5114}
5115
5117{
5118 // find the same instances of ConditionList and delete them.
5119 for (SpellEffectInfo& effect : _effects)
5120 effect.ImplicitTargetConditions = nullptr;
5121}
5122
5124{
5126 return false;
5127
5129}
5130
5131bool SpellInfo::HasLabel(uint32 labelId) const
5132{
5133 return Labels.contains(labelId);
5134}
@ STATUS_WAIT_JOIN
@ IN_MILLISECONDS
Definition Common.h:38
#define M_PI
Definition Common.h:118
@ 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< 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:579
@ VEHICLE_SEAT_FLAG_UNK2
Definition DBCEnums.h:3142
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition DBCEnums.h:3124
@ VEHICLE_SEAT_FLAG_CAN_CONTROL
Definition DBCEnums.h:3123
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition DBCEnums.h:3125
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition DBCEnums.h:3126
SpellEffectAttributes
Definition DBCEnums.h:2421
AreaMountFlags
Definition DBCEnums.h:163
constexpr std::size_t MAX_POWERS_PER_SPELL
Definition DBCEnums.h:2483
ChrSpecialization
Definition DBCEnums.h:400
Difficulty
Definition DBCEnums.h:935
ExpectedStatType
Definition DBCEnums.h:989
@ SPELL_PPM_MOD_CRIT
Definition DBCEnums.h:2474
@ SPELL_PPM_MOD_AURA
Definition DBCEnums.h:2480
@ SPELL_PPM_MOD_ITEM_LEVEL
Definition DBCEnums.h:2478
@ SPELL_PPM_MOD_CLASS
Definition DBCEnums.h:2475
@ SPELL_PPM_MOD_SPEC
Definition DBCEnums.h:2476
@ SPELL_PPM_MOD_RACE
Definition DBCEnums.h:2477
@ SPELL_PPM_MOD_HASTE
Definition DBCEnums.h:2473
@ SPELL_PPM_MOD_BATTLEGROUND
Definition DBCEnums.h:2479
uint8_t uint8
Definition Define.h:156
int32_t int32
Definition Define.h:150
uint64_t uint64
Definition Define.h:153
#define UI64LIT(N)
Definition Define.h:139
uint16_t uint16
Definition Define.h:155
uint32_t uint32
Definition Define.h:154
#define ASSERT
Definition Errors.h:72
GameTable< GtSpellScalingEntry > sSpellScalingGameTable
GameTable< GtStaminaMultByILvl > sStaminaMultByILvlGameTable
float GetIlvlStatMultiplier(T const *row, InventoryType invType)
GameTable< GtNpcManaCostScalerEntry > sNpcManaCostScalerGameTable
GameTable< GtCombatRatingsMultByILvl > sCombatRatingsMultByILvlGameTable
float GetSpellScalingColumnForClass(GtSpellScalingEntry const *row, int32 class_)
Definition GameTables.h:256
float GetRandomPropertyPoints(uint32 itemLevel, uint32 quality, uint32 inventoryType, uint32 subClass)
#define ITEM_SUBCLASS_MASK_WEAPON_RANGED
InventoryType
@ INVTYPE_CHEST
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:182
LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template", "creature pickpocket lootid", true)
@ MOVEMENTFLAG_FLYING
@ MOVEMENTFLAG_FALLING
@ MOVEMENTFLAG_SWIMMING
@ MOVEMENTFLAG_HOVER
@ MOVEMENTFLAG_ADV_FLYING
uint64 MAKE_PAIR64(uint32 l, uint32 h)
@ TYPEID_PLAYER
Definition ObjectGuid.h:44
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:25
@ SPELLMOD_LABEL_PCT
Definition Player.h:181
@ SPELLMOD_FLAT
Definition Player.h:178
@ SPELLMOD_PCT
Definition Player.h:179
@ SPELLMOD_LABEL_FLAT
Definition Player.h:180
float frand(float min, float max)
Definition Random.cpp:56
float rand_norm()
Definition Random.cpp:76
@ SPELL_ATTR11_SCALES_WITH_ITEM_LEVEL
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ SPELL_ATTR10_USE_SPELL_BASE_LEVEL_FOR_SCALING
@ SPELL_ATTR9_AUTOCAST_OFF_BY_DEFAULT
@ SPELL_ATTR9_TARGET_MUST_BE_GROUNDED
@ SPELL_ATTR9_NO_MOVEMENT_RADIUS_BONUS
@ SPELL_ATTR7_BYPASS_NO_RESURRECT_AURA
@ SPELL_ATTR7_NO_UI_NOT_INTERRUPTIBLE
SpellEffects
@ 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
#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
@ ITEM_QUALITY_RARE
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_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
@ SPELL_DAMAGE_CLASS_RANGED
@ SPELL_DAMAGE_CLASS_MELEE
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
@ SPELL_ATTR12_USE_FLOAT_VALUES_FOR_SCALING_AMOUNTS
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_TARGET_NOT_GROUNDED
@ 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
@ AURA_STATE_BANISHED
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
@ SPELL_ATTR13_DO_NOT_FAIL_IF_NO_TARGET
DispelType
@ DISPEL_ALL
@ DISPEL_ENRAGE
@ DISPEL_MAX
@ 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
@ SPELL_ATTR8_ALLOW_TARGETS_HIDDEN_BY_SPAWN_TRACKING
@ SPELL_ATTR8_MASTERY_AFFECTS_POINTS
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
@ 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_MOD_CHARGE_RECOVERY_BY_TYPE_MASK
@ 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_MOD_CASTING_SPEED
@ SPELL_AURA_TRACK_RESOURCES
@ SPELL_AURA_MOD_PARRY_PERCENT
@ SPELL_AURA_MOD_MAX_POWER
@ SPELL_AURA_MOD_MELEE_RANGED_HASTE_NO_REGEN
@ 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_ADD_PCT_MODIFIER
@ SPELL_AURA_PERIODIC_MANA_LEECH
@ SPELL_AURA_MOD_POSSESS_PET
@ SPELL_AURA_MOD_INCREASE_SPEED
@ SPELL_AURA_MOD_MELEE_SLOW_NO_STACK
@ SPELL_AURA_MOD_RESISTANCE
@ SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS
@ SPELL_AURA_MOD_BONUS_ARMOR
@ SPELL_AURA_PROC_TRIGGER_SPELL
@ 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_RANGED_SLOW_NO_STACK
@ SPELL_AURA_MOD_MELEE_HASTE
@ SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS
@ SPELL_AURA_MOD_MELEE_RANGED_CASTING_SLOW_NO_STACK
@ 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_CASTING_SLOW_NO_STACK
@ 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_MOD_MELEE_HASTE_NO_REGEN
@ SPELL_AURA_MOUNTED
@ SPELL_AURA_MOD_RANGED_HASTE_NO_REGEN
@ 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_PACIFY_SILENCE
@ SPELL_AURA_MOD_COOLDOWN
@ SPELL_AURA_AOE_CHARM
@ 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_SPELL_SLOW_NO_STACK
@ SPELL_AURA_MOD_DETECT_RANGE
@ SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
@ SPELL_AURA_MOD_MELEE_RANGED_HASTE
@ 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_MOD_MELEE_RANGED_CASTING_HASTE
@ SPELL_AURA_SET_VEHICLE_ID
@ SPELL_AURA_MOD_STUN
SpellInterruptFlags
double SpellEffectValue
This is a double instead of float to be able to store full range of int32.
SpellAuraInterruptFlags2
SpellModOp
@ TARGET_FLAG_GAMEOBJECT
@ TARGET_FLAG_NONE
@ TARGET_FLAG_UNIT_RAID
@ TARGET_FLAG_UNIT_ENEMY
@ TARGET_FLAG_CORPSE_ALLY
@ TARGET_FLAG_ITEM
@ TARGET_FLAG_UNIT_MINIPET
@ TARGET_FLAG_UNIT_PASSENGER
@ TARGET_FLAG_GAMEOBJECT_ITEM
@ TARGET_FLAG_DEST_LOCATION
@ TARGET_FLAG_UNIT_ALLY
@ TARGET_FLAG_SOURCE_LOCATION
@ TARGET_FLAG_UNIT
@ TARGET_FLAG_UNIT_MASK
@ TARGET_FLAG_UNIT_DEAD
@ TARGET_FLAG_CORPSE_ENEMY
@ TARGET_FLAG_CORPSE_MASK
@ TARGET_FLAG_GAMEOBJECT_MASK
@ TARGET_FLAG_UNIT_PARTY
SpellAuraInterruptFlags
bool _isPositiveTarget(SpellEffectInfo const &effect)
bool _isPositiveEffectImpl(SpellInfo const *spellInfo, SpellEffectInfo const &effect, std::unordered_set< std::pair< SpellInfo const *, SpellEffIndex > > &visited)
float CalcPPMHasteMod(SpellProcsPerMinuteModEntry const *mod, Unit *caster)
float CalcPPMCritMod(SpellProcsPerMinuteModEntry const *mod, Unit *caster)
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
Definition SpellInfo.cpp:44
float CalcPPMItemLevelMod(SpellProcsPerMinuteModEntry const *mod, int32 itemLevel)
SpellTargetCheckTypes
Definition SpellInfo.h:80
@ TARGET_CHECK_PASSENGER
Definition SpellInfo.h:88
@ TARGET_CHECK_PARTY
Definition SpellInfo.h:85
@ TARGET_CHECK_ENEMY
Definition SpellInfo.h:83
@ TARGET_CHECK_DEFAULT
Definition SpellInfo.h:81
@ TARGET_CHECK_SUMMONED
Definition SpellInfo.h:89
@ TARGET_CHECK_ENTRY
Definition SpellInfo.h:82
@ TARGET_CHECK_RAID_CLASS
Definition SpellInfo.h:87
@ TARGET_CHECK_ALLY
Definition SpellInfo.h:84
@ TARGET_CHECK_RAID
Definition SpellInfo.h:86
SpellEffectImplicitTargetTypes
Definition SpellInfo.h:108
@ EFFECT_IMPLICIT_TARGET_CASTER
Definition SpellInfo.h:111
@ EFFECT_IMPLICIT_TARGET_NONE
Definition SpellInfo.h:109
@ EFFECT_IMPLICIT_TARGET_EXPLICIT
Definition SpellInfo.h:110
SpellTargetSelectionCategories
Definition SpellInfo.h:42
@ TARGET_SELECT_CATEGORY_CONE
Definition SpellInfo.h:47
@ TARGET_SELECT_CATEGORY_AREA
Definition SpellInfo.h:48
@ TARGET_SELECT_CATEGORY_DEFAULT
Definition SpellInfo.h:44
@ TARGET_SELECT_CATEGORY_NEARBY
Definition SpellInfo.h:46
@ TARGET_SELECT_CATEGORY_NYI
Definition SpellInfo.h:43
@ TARGET_SELECT_CATEGORY_LINE
Definition SpellInfo.h:50
@ TARGET_SELECT_CATEGORY_TRAJ
Definition SpellInfo.h:49
@ TARGET_SELECT_CATEGORY_CHANNEL
Definition SpellInfo.h:45
SpellTargetDirectionTypes
Definition SpellInfo.h:93
@ TARGET_DIR_FRONT_RIGHT
Definition SpellInfo.h:99
@ TARGET_DIR_NONE
Definition SpellInfo.h:94
@ TARGET_DIR_BACK
Definition SpellInfo.h:96
@ TARGET_DIR_BACK_RIGHT
Definition SpellInfo.h:100
@ TARGET_DIR_RIGHT
Definition SpellInfo.h:97
@ TARGET_DIR_FRONT_LEFT
Definition SpellInfo.h:102
@ TARGET_DIR_FRONT
Definition SpellInfo.h:95
@ TARGET_DIR_LEFT
Definition SpellInfo.h:98
@ TARGET_DIR_BACK_LEFT
Definition SpellInfo.h:101
@ TARGET_DIR_RANDOM
Definition SpellInfo.h:103
SpellTargetObjectTypes
Definition SpellInfo.h:64
@ TARGET_OBJECT_TYPE_UNIT
Definition SpellInfo.h:68
@ TARGET_OBJECT_TYPE_ITEM
Definition SpellInfo.h:72
@ TARGET_OBJECT_TYPE_CORPSE
Definition SpellInfo.h:73
@ TARGET_OBJECT_TYPE_UNIT_AND_DEST
Definition SpellInfo.h:69
@ TARGET_OBJECT_TYPE_NONE
Definition SpellInfo.h:65
@ TARGET_OBJECT_TYPE_DEST
Definition SpellInfo.h:67
@ TARGET_OBJECT_TYPE_GOBJ
Definition SpellInfo.h:70
@ TARGET_OBJECT_TYPE_CORPSE_ALLY
Definition SpellInfo.h:76
@ TARGET_OBJECT_TYPE_CORPSE_ENEMY
Definition SpellInfo.h:75
@ TARGET_OBJECT_TYPE_GOBJ_ITEM
Definition SpellInfo.h:71
@ TARGET_OBJECT_TYPE_SRC
Definition SpellInfo.h:66
@ SPELL_ATTR0_CU_CAN_TARGET_ANY_PRIVATE_OBJECT
Definition SpellInfo.h:169
@ SPELL_ATTR0_CU_ALLOW_INFLIGHT_TARGET
Definition SpellInfo.h:162
@ SPELL_ATTR0_CU_PICKPOCKET
Definition SpellInfo.h:154
SpellSpecificType
Definition SpellInfo.h:116
@ SPELL_SPECIFIC_FOOD
Definition SpellInfo.h:128
@ SPELL_SPECIFIC_MAGE_ARMOR
Definition SpellInfo.h:125
@ SPELL_SPECIFIC_NORMAL
Definition SpellInfo.h:117
@ SPELL_SPECIFIC_STING
Definition SpellInfo.h:120
@ SPELL_SPECIFIC_MAGE_ARCANE_BRILLANCE
Definition SpellInfo.h:134
@ SPELL_SPECIFIC_ASPECT
Definition SpellInfo.h:122
@ SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT
Definition SpellInfo.h:136
@ SPELL_SPECIFIC_ELEMENTAL_SHIELD
Definition SpellInfo.h:126
@ SPELL_SPECIFIC_BANE
Definition SpellInfo.h:139
@ SPELL_SPECIFIC_PRESENCE
Definition SpellInfo.h:131
@ SPELL_SPECIFIC_CURSE
Definition SpellInfo.h:121
@ SPELL_SPECIFIC_DRINK
Definition SpellInfo.h:129
@ SPELL_SPECIFIC_HAND
Definition SpellInfo.h:137
@ SPELL_SPECIFIC_AURA
Definition SpellInfo.h:119
@ SPELL_SPECIFIC_WARRIOR_ENRAGE
Definition SpellInfo.h:135
@ SPELL_SPECIFIC_WARLOCK_ARMOR
Definition SpellInfo.h:124
@ SPELL_SPECIFIC_SCROLL
Definition SpellInfo.h:133
@ SPELL_SPECIFIC_MAGE_POLYMORPH
Definition SpellInfo.h:127
@ SPELL_SPECIFIC_TRACKER
Definition SpellInfo.h:123
@ SPELL_SPECIFIC_SEAL
Definition SpellInfo.h:118
@ SPELL_SPECIFIC_FOOD_AND_DRINK
Definition SpellInfo.h:130
@ SPELL_SPECIFIC_CHARM
Definition SpellInfo.h:132
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
Definition SpellInfo.cpp:44
SpellTargetReferenceTypes
Definition SpellInfo.h:54
@ TARGET_REFERENCE_TYPE_SRC
Definition SpellInfo.h:59
@ TARGET_REFERENCE_TYPE_TARGET
Definition SpellInfo.h:57
@ TARGET_REFERENCE_TYPE_LAST
Definition SpellInfo.h:58
@ TARGET_REFERENCE_TYPE_NONE
Definition SpellInfo.h:55
@ TARGET_REFERENCE_TYPE_CASTER
Definition SpellInfo.h:56
@ TARGET_REFERENCE_TYPE_DEST
Definition SpellInfo.h:60
bool IsPrimaryProfessionSkill(uint32 skill)
Definition SpellMgr.cpp:107
bool IsProfessionSkill(uint32 skill)
Definition SpellMgr.h:605
std::pair< SpellAreaMap::const_iterator, SpellAreaMap::const_iterator > SpellAreaMapBounds
Definition SpellMgr.h:509
#define sSpellMgr
Definition SpellMgr.h:812
std::pair< SkillLineAbilityMap::const_iterator, SkillLineAbilityMap::const_iterator > SkillLineAbilityMapBounds
Definition SpellMgr.h:579
ProcFlags
Definition SpellMgr.h:91
@ UNIT_FLAG_PET_IN_COMBAT
@ UNIT_STATE_IN_FLIGHT
Definition Unit.h:283
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Definition Util.h:565
T CalculatePct(T base, U pct)
Definition Util.h:72
bool IsPositive() const
Definition SpellAuras.h:88
Aura * GetBase() const
Definition SpellAuras.h:82
SpellInfo const * GetSpellInfo() const
SpellEffectInfo const & GetSpellEffectInfo() const
bool IsAffectingSpell(SpellInfo const *spell) const
int32 GetMiscValue() const
SpellInfo const * GetSpellInfo() const
Definition SpellAuras.h:182
bool IsUnit() const
Definition BaseEntity.h:171
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
bool IsPlayer() const
Definition BaseEntity.h:173
TypeID GetTypeId() const
Definition BaseEntity.h:166
BattlegroundStatus GetStatus() const
static bool IsUnitMeetingCondition(Unit const *unit, Unit const *otherUnit, UnitConditionEntry const *condition)
static bool IsPlayerMeetingCondition(Player const *player, uint32 conditionId)
CreatureDifficulty const * GetCreatureDifficulty() const
Definition Creature.h:276
bool CanHaveLoot() const
Definition Creature.h:303
static bool IsInArea(uint32 objectAreaId, uint32 areaId)
constexpr bool HasFlag(T flag) const
Definition EnumFlag.h:106
Definition Item.h:185
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition Item.cpp:1477
bool HaveLootFor(uint32 loot_id) const
Definition LootMgr.h:92
Definition Map.h:227
bool IsBattlegroundOrArena() const
Definition Map.cpp:3405
InstanceMap * ToInstanceMap()
Definition Map.h:495
bool IsEmpty() const
Definition ObjectGuid.h:362
Corpse * ToCorpse()
Definition Object.h:136
Player * ToPlayer()
Definition Object.h:126
Creature * ToCreature()
Definition Object.h:121
Unit * ToUnit()
Definition Object.h:116
UF::UpdateField< UF::ActivePlayerData, int32(WowCS::EntityFragment::CGObject), TYPEID_ACTIVE_PLAYER > m_activePlayerData
Definition Player.h:3048
bool InBattleground() const
Definition Player.h:2570
Battleground * GetBattleground() const
Definition Player.cpp:25650
bool IsGameMaster() const
Definition Player.h:1293
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition Player.cpp:9577
bool IsUseEquipedWeapon(bool mainhand) const
Definition Player.cpp:13114
float PositionFacing
Definition SpellInfo.h:227
Mechanics Mechanic
Definition SpellInfo.h:226
static std::array< StaticData, TOTAL_SPELL_EFFECTS > _data
Definition SpellInfo.h:959
bool IsUnitOwnedAuraEffect() const
float CalcDamageMultiplier(WorldObject *caster, Spell *spell=nullptr) const
bool HasRadius(SpellTargetIndex targetIndex) const
SpellEffectValue CalcValue(WorldObject const *caster=nullptr, SpellEffectValue const *basePoints=nullptr, Unit const *target=nullptr, float *variance=nullptr, uint32 castItemId=0, int32 itemLevel=-1) const
AuraType ApplyAuraName
Definition SpellInfo.h:216
float CalcValueMultiplier(WorldObject *caster, Spell *spell=nullptr) const
struct SpellEffectInfo::ScalingInfo Scaling
uint32 GetPeriodicTickCount() const
uint32 TriggerSpell
Definition SpellInfo.h:234
ImmunityInfo const * GetImmunityInfo() const
Definition SpellInfo.h:286
uint32 GetMissingTargetMask(bool srcSet=false, bool dstSet=false, uint32 mask=0) const
SpellEffects Effect
Definition SpellInfo.h:215
std::unique_ptr< ImmunityInfo > _immunityInfo
Definition SpellInfo.h:299
bool IsAreaAuraEffect() const
SpellInfo const * _spellInfo
Definition SpellInfo.h:212
bool IsAura() const
SpellRadiusEntry const * TargetBRadiusEntry
Definition SpellInfo.h:231
std::shared_ptr< std::vector< Condition > > ImplicitTargetConditions
Definition SpellInfo.h:237
bool IsEffect() const
flag128 SpellClassMask
Definition SpellInfo.h:235
bool IsTargetingArea() const
SpellRadiusEntry const * TargetARadiusEntry
Definition SpellInfo.h:230
SpellEffectImplicitTargetTypes GetImplicitTargetType() const
float BonusCoefficientFromAP
Definition SpellInfo.h:236
int32 CalcValueAsInt(WorldObject const *caster=nullptr, SpellEffectValue const *basePoints=nullptr, Unit const *target=nullptr, float *variance=nullptr, uint32 castItemId=0, int32 itemLevel=-1) const
static constexpr SpellEffectValue MaxValue
Definition SpellInfo.h:267
float BonusCoefficient
Definition SpellInfo.h:223
SpellRange CalcRadius(WorldObject const *caster=nullptr, SpellTargetIndex targetIndex=SpellTargetIndex::TargetA, Spell *spell=nullptr) const
ExpectedStatType GetScalingExpectedStat() const
float ChainAmplitude
Definition SpellInfo.h:222
uint32 ApplyAuraPeriod
Definition SpellInfo.h:217
SpellTargetObjectTypes GetUsedTargetObjectType() const
SpellEffectValue CalcBaseValue(WorldObject const *caster, Unit const *target, uint32 itemId, int32 itemLevel) const
float RealPointsPerLevel
Definition SpellInfo.h:219
static constexpr SpellEffectValue MinValue
Definition SpellInfo.h:266
EnumFlag< SpellEffectAttributes > EffectAttributes
Definition SpellInfo.h:238
SpellEffIndex EffectIndex
Definition SpellInfo.h:214
uint32 GetProvidedTargetMask() const
SpellImplicitTargetInfo TargetA
Definition SpellInfo.h:228
float PointsPerResource
Definition SpellInfo.h:220
SpellImplicitTargetInfo TargetB
Definition SpellInfo.h:229
SpellTargetDirectionTypes GetDirectionType() const
SpellTargetCheckTypes GetCheckType() const
Definition SpellInfo.cpp:98
static std::array< StaticData, TOTAL_SPELL_TARGETS > _data
Definition SpellInfo.h:246
SpellTargetReferenceTypes GetReferenceType() const
Definition SpellInfo.cpp:88
SpellTargetSelectionCategories GetSelectionCategory() const
Definition SpellInfo.cpp:83
SpellTargetObjectTypes GetObjectType() const
Definition SpellInfo.cpp:93
float CalcDirectionAngle() const
uint32 GetExplicitTargetMask(bool &srcSet, bool &dstSet) const
Targets GetTarget() const
std::array< SpellPowerEntry const *, MAX_POWERS_PER_SPELL > PowerCosts
Definition SpellInfo.h:391
bool IsExplicitDiscovery() const
DiminishingLevels GetDiminishingReturnsMaxLevel() const
uint32 RequiresSpellFocus
Definition SpellInfo.h:356
uint32 BaseLevel
Definition SpellInfo.h:388
void _LoadSpellDiminishInfo()
uint32 MaxLevel
Definition SpellInfo.h:387
uint32 SpellLevel
Definition SpellInfo.h:389
uint32 AttributesEx13
Definition SpellInfo.h:346
uint32 ActiveIconFileDataId
Definition SpellInfo.h:406
uint32 GetSpellXSpellVisualId(WorldObject const *caster=nullptr, WorldObject const *viewer=nullptr) const
uint32 TargetAuraState
Definition SpellInfo.h:359
bool IsRankOf(SpellInfo const *spellInfo) const
std::array< int32, MAX_SPELL_REAGENTS > Reagent
Definition SpellInfo.h:399
uint64 GetEffectMechanicMask(SpellEffIndex effIndex) const
uint32 ExcludeTargetAuraSpell
Definition SpellInfo.h:365
bool CanDispelAura(SpellInfo const *auraSpellInfo) const
bool IsAffected(uint32 familyName, flag128 const &familyFlags) const
SpellRange GetMinMaxRange(bool positive=false, WorldObject const *caster=nullptr, Spell *spell=nullptr) const
bool IsAutocastEnabledByDefault() const
uint32 PreventionType
Definition SpellInfo.h:417
uint32 CasterAuraSpell
Definition SpellInfo.h:362
bool MeetsFutureSpellPlayerCondition(Player const *player) const
float Width
Definition SpellInfo.h:411
uint32 MaxTargetLevel
Definition SpellInfo.h:412
Optional< SpellPowerCost > CalcPowerCost(Powers powerType, bool optionalCost, WorldObject const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
float GetMaxRange(bool positive=false, WorldObject const *caster=nullptr, Spell *spell=nullptr) const
Mechanics GetEffectMechanic(SpellEffIndex effIndex) const
SpellInfo const * GetFirstRankSpell() const
bool IsAutocastable() const
std::unordered_set< uint32 > Labels
Definition SpellInfo.h:421
uint32 GetCategory() const
SpellCastResult CheckShapeshift(uint32 form) const
float CalcProcPPM(Unit *caster, int32 itemLevel) const
uint64 GetAllEffectsMechanicMask() const
bool IsRequiringDeadTarget() const
uint32 const Id
Definition SpellInfo.h:328
uint64 GetMechanicImmunityMask(Unit const *caster) const
uint32 RecoveryTime
Definition SpellInfo.h:371
float MinDuration
Definition SpellInfo.h:395
EnumFlag< SpellAuraInterruptFlags2 > AuraInterruptFlags2
Definition SpellInfo.h:378
std::vector< Milliseconds > EmpowerStageThresholds
Definition SpellInfo.h:422
uint32 AttributesEx8
Definition SpellInfo.h:341
std::array< int16, MAX_SPELL_REAGENTS > ReagentCount
Definition SpellInfo.h:400
bool IsAuraExclusiveBySpecificPerCasterWith(SpellInfo const *spellInfo) const
SpellInfo const * GetPrevRankSpell() const
int32 IsAffectedBySpellMod(SpellModifier const *mod) const
bool IsGroupBuff() const
bool IsDeathPersistent() const
SpellVisualVector _visuals
Definition SpellInfo.h:630
bool IsCooldownStartedOnEvent() const
uint64 Stances
Definition SpellInfo.h:352
EnumFlag< SpellAuraInterruptFlags > ChannelInterruptFlags
Definition SpellInfo.h:379
bool IsPassive() const
uint32 StackAmount
Definition SpellInfo.h:396
::Difficulty const Difficulty
Definition SpellInfo.h:329
uint32 Mechanic
Definition SpellInfo.h:332
bool IsAuraExclusiveBySpecificWith(SpellInfo const *spellInfo) const
uint8 GetRank() const
SpellRangeEntry const * RangeEntry
Definition SpellInfo.h:392
uint32 ProcCharges
Definition SpellInfo.h:383
bool HasAnyAuraInterruptFlag() const
bool IsLootCrafting() const
int32 RequiredAreasID
Definition SpellInfo.h:418
bool IsUpdatingTemporaryAuraValuesBySpellMod() const
uint32 ShowFutureSpellPlayerConditionID
Definition SpellInfo.h:408
bool IsAutoShot() const
bool IsStackableOnOneSlotWithDifferentCasters() const
bool IsRanked() const
uint32 AttributesEx14
Definition SpellInfo.h:347
bool HasOnlyDamageEffects() const
uint32 GetDispelMask() const
bool IsHighRankOf(SpellInfo const *spellInfo) const
uint32 CalcCastTime(Spell *spell=nullptr) const
SpellInfo const * GetAuraRankForLevel(uint8 level) const
bool NeedsToBeTriggeredByCaster(SpellInfo const *triggeringSpell) const
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player const *player=nullptr) const
uint32 GetRecoveryTime() const
AuraStateType _auraState
Definition SpellInfo.h:632
SpellSpecificType GetSpellSpecific() const
DiminishingReturnsType GetDiminishingReturnsGroupType() const
uint32 Dispel
Definition SpellInfo.h:331
std::vector< SpellProcsPerMinuteModEntry const * > ProcPPMMods
Definition SpellInfo.h:386
uint64 GetAllowedMechanicMask() const
bool HasTargetType(::Targets target) const
bool HasHitDelay() const
uint32 ExcludeCasterAuraState
Definition SpellInfo.h:360
float Speed
Definition SpellInfo.h:393
bool IsMultiSlotAura() const
void _UnloadImplicitTargetConditionLists()
float GetMinRange(bool positive=false) const
int32 GetMaxDuration() const
uint32 CooldownAuraSpellId
Definition SpellInfo.h:375
int32 EquippedItemClass
Definition SpellInfo.h:402
bool HasInitialAggro() const
std::vector< SpellEffectInfo > _effects
Definition SpellInfo.h:629
int32 GetDiminishingReturnsLimitDuration() const
struct SpellInfo::ScalingInfo Scaling
DiminishingGroup GetDiminishingReturnsGroupForSpell() const
uint32 SchoolMask
Definition SpellInfo.h:419
bool IsAbilityOfSkillType(uint32 skillType) const
uint32 CasterAuraState
Definition SpellInfo.h:358
SpellCastResult CheckTarget(WorldObject const *caster, WorldObject const *target, bool implicit=true) const
bool CheckTargetCreatureType(Unit const *target) const
float ProcBasePPM
Definition SpellInfo.h:385
bool IsStackableWithRanks() const
bool IsItemFitToSpellRequirements(Item const *item) const
uint32 CategoryRecoveryTime
Definition SpellInfo.h:372
uint64 StancesNot
Definition SpellInfo.h:353
AuraType TargetAuraType
Definition SpellInfo.h:367
EnumFlag< SpellInterruptFlags > InterruptFlags
Definition SpellInfo.h:376
flag128 SpellFamilyFlags
Definition SpellInfo.h:415
uint32 ExplicitTargetMask
Definition SpellInfo.h:431
bool IsAllowingDeadTarget() const
uint32 AttributesEx3
Definition SpellInfo.h:336
float LaunchDelay
Definition SpellInfo.h:394
void _InitializeSpellPositivity()
void _LoadImmunityInfo()
WeaponAttackType GetAttackType() const
SpellSchoolMask GetSchoolMask() const
bool CanSpellEffectProvideImmunityAgainstAuraEffect(SpellEffectInfo const &immunityEffectInfo, SpellInfo const *auraSpellInfo, SpellEffectInfo const &auraEffectInfo) const
bool IsPrimaryProfession() const
std::vector< SpellReagentsCurrencyEntry const * > ReagentsCurrency
Definition SpellInfo.h:401
void ApplyAllSpellImmunitiesTo(Unit *target, SpellEffectInfo const &spellEffectInfo, bool apply) const
AuraStateType GetAuraState() const
bool IsChanneled() const
uint32 GetSpellVisual(WorldObject const *caster=nullptr, WorldObject const *viewer=nullptr) const
bool HasAttribute(SpellAttr0 attribute) const
Definition SpellInfo.h:456
SpellDurationEntry const * DurationEntry
Definition SpellInfo.h:390
bool IsNextMeleeSwingSpell() const
uint64 GetSpellMechanicMaskByEffectMask(uint32 effectMask) const
uint32 Attributes
Definition SpellInfo.h:333
uint32 AttributesEx
Definition SpellInfo.h:334
bool CanSpellProvideImmunityAgainstAura(SpellInfo const *auraSpellInfo) const
bool HasChannelInterruptFlag(SpellAuraInterruptFlags flag) const
Definition SpellInfo.h:481
uint32 RequiredExplicitTargetMask
Definition SpellInfo.h:432
uint32 ChargeCategoryId
Definition SpellInfo.h:420
bool IsPassiveStackableWithRanks() const
bool SpellCancelsAuraEffect(AuraEffect const *aurEff) const
bool IsCooldownStartedOnEventAfterCombat() const
uint32 IconFileDataId
Definition SpellInfo.h:405
uint32 AttributesEx15
Definition SpellInfo.h:348
uint32 MaxAffectedTargets
Definition SpellInfo.h:413
uint32 AttributesEx12
Definition SpellInfo.h:345
int32 GetDuration() const
bool IsAffectedBySpellMods() const
SpellCastResult CheckVehicle(Unit const *caster) const
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition SpellInfo.h:590
std::vector< SpellEffectInfo > const & GetEffects() const
Definition SpellInfo.h:589
uint32 AttributesEx6
Definition SpellInfo.h:339
uint32 AttributesEx7
Definition SpellInfo.h:340
int32 EquippedItemSubClassMask
Definition SpellInfo.h:403
bool IsEmpowerSpell() const
SpellDiminishInfo _diminishInfo
Definition SpellInfo.h:634
SpellSpecificType _spellSpecific
Definition SpellInfo.h:631
SpellInfo(SpellNameEntry const *spellName, ::Difficulty difficulty, SpellInfoLoadHelper const &data)
uint32 GetExplicitTargetMask() const
uint32 AttributesEx9
Definition SpellInfo.h:342
uint32 FacingCasterFlags
Definition SpellInfo.h:357
SpellCastResult CheckExplicitTarget(WorldObject const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
uint32 StartRecoveryTime
Definition SpellInfo.h:374
uint32 ContentTuningId
Definition SpellInfo.h:407
uint32 TargetAuraSpell
Definition SpellInfo.h:363
bool HasAreaAuraEffect() const
bool CanPierceImmuneAura(SpellInfo const *auraSpellInfo) const
SpellChainNode const * ChainEntry
Definition SpellInfo.h:433
AuraType ExcludeTargetAuraType
Definition SpellInfo.h:369
uint32 AttributesEx10
Definition SpellInfo.h:343
uint32 Targets
Definition SpellInfo.h:354
void _InitializeExplicitTargetMask()
uint32 ProcCooldown
Definition SpellInfo.h:384
bool IsDifferentRankOf(SpellInfo const *spellInfo) const
LocalizedString const * SpellName
Definition SpellInfo.h:409
SpellInfo const * GetLastRankSpell() const
bool NeedsExplicitUnitTarget() const
SpellInfo const * GetNextRankSpell() const
SpellCastTimesEntry const * CastTimeEntry
Definition SpellInfo.h:370
int32 EquippedItemInventoryTypeMask
Definition SpellInfo.h:404
uint32 ExcludeTargetAuraState
Definition SpellInfo.h:361
std::bitset< MAX_SPELL_EFFECTS > NegativeEffects
Definition SpellInfo.h:351
EnumFlag< SpellAuraInterruptFlags2 > ChannelInterruptFlags2
Definition SpellInfo.h:380
bool IsPrimaryProfessionFirstRank() const
struct SpellInfo::@328 SqrtDamageAndHealingDiminishing
bool HasEffect(SpellEffects effect) const
void _LoadAuraState()
AuraType ExcludeCasterAuraType
Definition SpellInfo.h:368
int32 CalcDuration(WorldObject const *caster=nullptr) const
uint32 AttributesEx16
Definition SpellInfo.h:349
bool IsAffectingArea() const
bool IsProfession() const
bool IsPositive() const
bool IsAutoRepeatRangedSpell() const
uint32 TargetCreatureType
Definition SpellInfo.h:355
uint32 ProcChance
Definition SpellInfo.h:382
uint32 AttributesEx2
Definition SpellInfo.h:335
bool IsMoveAllowedChannel() const
uint32 DmgClass
Definition SpellInfo.h:416
AuraType CasterAuraType
Definition SpellInfo.h:366
uint32 AttributesEx5
Definition SpellInfo.h:338
bool IsRangedWeaponSpell() const
uint32 AttributesEx4
Definition SpellInfo.h:337
EnumFlag< SpellAuraInterruptFlags > AuraInterruptFlags
Definition SpellInfo.h:377
uint32 ExcludeCasterAuraSpell
Definition SpellInfo.h:364
bool HasAura(AuraType aura) const
bool IsTargetingArea() const
uint32 StartRecoveryCategory
Definition SpellInfo.h:373
bool HasAuraInterruptFlag(SpellAuraInterruptFlags flag) const
Definition SpellInfo.h:478
bool HasLabel(uint32 labelId) const
uint32 AttributesEx11
Definition SpellInfo.h:344
uint32 CategoryId
Definition SpellInfo.h:330
float ConeAngle
Definition SpellInfo.h:410
uint32 SpellFamilyName
Definition SpellInfo.h:414
bool CanBeInterrupted(WorldObject const *interruptCaster, Unit const *interruptTarget, bool ignoreImmunity=false) const
void _LoadSpellSpecific()
uint64 _allowedMechanicMask
Definition SpellInfo.h:635
bool IsPositiveEffect(uint8 effIndex) const
bool IsSingleTarget() const
void _LoadSqrtTargetLimit(int32 maxTargets, int32 numNonDiminishedTargets, Optional< uint32 > maxTargetsValueHolderSpell, Optional< SpellEffIndex > maxTargetsValueHolderEffect, Optional< uint32 > numNonDiminishedTargetsValueHolderSpell, Optional< SpellEffIndex > numNonDiminishedTargetsValueHolderEffect)
bool CanBeUsedInCombat(Unit const *caster) const
static CreatureImmunities const * GetCreatureImmunities(int32 creatureImmunitiesId)
Definition SpellMgr.cpp:687
Definition Spell.h:277
static bool CanIncreaseRangeByMovement(Unit const *unit)
Definition Spell.cpp:7325
WorldObject * GetCaster() const
Definition Spell.h:699
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:47
std::pair< iterator, bool > insert(Key const &key)
Definition FlatSet.h:82
Definition Unit.h:647
void ApplySpellImmune(uint32 spellId, SpellImmunity op, uint32 type, bool apply)
Definition Unit.cpp:8261
Vehicle * GetVehicle() const
Definition Unit.h:1800
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3973
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1362
bool HasAuraTypeWithMiscvalue(AuraType auraType, int32 miscValue) const
Definition Unit.cpp:4845
uint32 GetClassMask() const
Definition Unit.h:778
ShapeshiftForm GetShapeshiftForm() const
Definition Unit.h:1527
uint64 GetMechanicImmunityMask() const
Definition Unit.cpp:7854
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:860
uint32 GetBaseAttackTime(WeaponAttackType att) const
Definition Unit.cpp:11007
bool IsAlive() const
Definition Unit.h:1205
TempSummon * ToTempSummon()
Definition Unit.h:1844
uint32 GetVirtualItemId(uint32 slot) const
Definition Unit.cpp:14505
EnumFlag< SpellOtherImmunity > GetSpellOtherImmunityMask() const
Definition Unit.cpp:7864
uint64 GetMaxHealth() const
Definition Unit.h:801
uint64 GetHealth() const
Definition Unit.h:800
bool IsSummon() const
Definition Unit.h:761
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition Unit.cpp:6165
float GetTotalAuraModifier(AuraType auraType) const
Definition Unit.cpp:5087
bool IsVisible() const
Definition Unit.cpp:8782
bool HasAuraType(AuraType auraType) const
Definition Unit.cpp:4832
ObjectGuid GetCritterGUID() const
Definition Unit.h:1219
void RemoveAurasWithInterruptFlags(InterruptFlags flag, SpellInfo const *source=nullptr)
Definition Unit.cpp:4259
void RemoveAppliedAuras(std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3919
UF::UpdateField< UF::UnitData, int32(WowCS::EntityFragment::CGObject), TYPEID_UNIT > m_unitData
Definition Unit.h:1897
int32 GetPower(Powers power) const
Definition Unit.cpp:10096
bool HasUnitState(const uint32 f) const
Definition Unit.h:755
bool IsMagnet() const
Definition Unit.cpp:6592
bool IsInRaidWith(Unit const *unit) const
Definition Unit.cpp:12272
bool HasUnitMovementFlag(MovementFlags f) const
Definition Unit.h:1761
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4822
void RemoveAurasWithMechanic(uint64 mechanicMaskToRemove, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, uint32 exceptSpellId=0, bool withEffectMechanics=false)
Definition Unit.cpp:4320
bool IsControlledByPlayer() const
Definition Unit.h:1234
bool HasBreakableByDamageCrowdControlAura(Unit const *excludeCasterChannel=nullptr) const
Definition Unit.cpp:783
uint32 GetCreatureTypeMask() const
Definition Unit.cpp:9496
bool HasAuraTypeWithAffectMask(AuraType auraType, SpellInfo const *affectedSpell) const
Definition Unit.cpp:4854
uint32 GetCreateMana() const
Definition Unit.h:1437
MountCapabilityEntry const * GetMountCapability(uint32 mountType) const
Definition Unit.cpp:8381
bool IsInPartyWith(Unit const *unit) const
Definition Unit.cpp:12253
uint8 GetLevel() const
Definition Unit.h:769
uint8 GetRace() const
Definition Unit.h:773
bool IsInCombat() const
Definition Unit.h:1073
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger) const
Returns information on the seat of specified passenger, represented by the format in VehicleSeat....
Definition Vehicle.cpp:670
Map * GetMap() const
Definition Object.h:411
bool IsValidAttackTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition Object.cpp:2329
bool CanSeeOrDetect(WorldObject const *obj, CanSeeOrDetectExtraArgs const &args={ }) const
Definition Object.cpp:855
Player * GetSpellModOwner() const
Definition Object.cpp:1646
bool IsValidAssistTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition Object.cpp:2487
SpellEffectValue ApplyEffectModifiers(SpellInfo const *spellInfo, uint8 effIndex, SpellEffectValue value) const
Definition Object.cpp:1676
void ModSpellCastTime(SpellInfo const *spellInfo, int32 &castTime, Spell *spell=nullptr) const
Definition Object.cpp:1790
Player * GetAffectingPlayer() const
Definition Object.cpp:1635
TC_GAME_API Player * FindPlayer(ObjectGuid const &)
std::vector< TraitDefinitionEffectPointsEntry const * > const * GetTraitDefinitionEffectPointModifiers(int32 traitDefinitionId)
auto SelectRandomWeightedContainerElement(C const &container, std::span< double > const &weights) -> decltype(std::ranges::begin(container))
Definition Containers.h:127
constexpr decltype(auto) EnsureWritableVectorIndex(std::vector< T > &vec, typename std::vector< T >::size_type i)
Definition Containers.h:299
STL namespace.
bool IsBattleground() const
bool IsDungeon() const
bool IsRaid() const
bool IsBattleArena() const
EnumFlag< SpellCategoryFlags > GetFlags() const
SpellInfo const * last
Definition SpellMgr.h:520
SpellInfo const * next
Definition SpellMgr.h:518
SpellInfo const * first
Definition SpellMgr.h:519
SpellInfo const * prev
Definition SpellMgr.h:517
int32 DiminishDurationLimit
Definition SpellInfo.h:314
DiminishingReturnsType DiminishReturnType
Definition SpellInfo.h:312
DiminishingLevels DiminishMaxLevel
Definition SpellInfo.h:313
DiminishingGroup DiminishGroup
Definition SpellInfo.h:311
std::array< int32, 2 > EffectMiscValue
std::array< int16, 2 > ImplicitTarget
float EffectRealPointsPerLevel
std::array< uint32, 2 > EffectRadiusIndex
flag128 EffectSpellClassMask
SpellEffectAttributes GetEffectAttributes() const
float EffectPointsPerResource
Trinity::Containers::FlatSet< SpellEffects > SpellEffectImmune
ImmunityInfo(ImmunityInfo &&) noexcept=delete
Trinity::Containers::FlatSet< AuraType > AuraTypeImmune
ImmunityInfo(ImmunityInfo const &)=delete
SpellCastingRequirementsEntry const * CastingRequirements
Definition SpellMgr.h:623
SpellReagentsEntry const * Reagents
Definition SpellMgr.h:635
std::vector< SpellXSpellVisualEntry const * > Visuals
Definition SpellMgr.h:641
SpellTargetRestrictionsEntry const * TargetRestrictions
Definition SpellMgr.h:639
std::vector< SpellLabelEntry const * > Labels
Definition SpellMgr.h:631
SpellTotemsEntry const * Totems
Definition SpellMgr.h:640
SpellAuraRestrictionsEntry const * AuraRestrictions
Definition SpellMgr.h:622
SpellScalingEntry const * Scaling
Definition SpellMgr.h:637
std::vector< SpellEmpowerStageEntry const * > EmpowerStages
Definition SpellMgr.h:628
SpellInterruptsEntry const * Interrupts
Definition SpellMgr.h:630
SpellCategoriesEntry const * Categories
Definition SpellMgr.h:624
SpellMiscEntry const * Misc
Definition SpellMgr.h:633
std::array< SpellPowerEntry const *, MAX_POWERS_PER_SPELL > Powers
Definition SpellMgr.h:634
SpellEquippedItemsEntry const * EquippedItems
Definition SpellMgr.h:629
SpellShapeshiftEntry const * Shapeshift
Definition SpellMgr.h:638
SpellAuraOptionsEntry const * AuraOptions
Definition SpellMgr.h:621
std::array< SpellEffectEntry const *, MAX_SPELL_EFFECTS > Effects
Definition SpellMgr.h:627
SpellClassOptionsEntry const * ClassOptions
Definition SpellMgr.h:625
std::vector< SpellReagentsCurrencyEntry const * > ReagentsCurrency
Definition SpellMgr.h:636
SpellCooldownsEntry const * Cooldowns
Definition SpellMgr.h:626
SpellLevelsEntry const * Levels
Definition SpellMgr.h:632
SpellModType type
Definition Player.h:258
uint32 spellId
Definition Player.h:260
LocalizedString Name
std::array< float, 2 > RangeMin
std::array< float, 2 > RangeMax
EnumFlag< SpellShapeshiftFormFlags > GetFlags() const
constexpr bool HasRace(uint32 raceId) const
Definition RaceMask.h:149