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
244
246{ {
400} };
401
410
412 : EffectAttributes(SpellEffectAttributes::None)
413{
414 ASSERT(spellInfo);
415
416 _spellInfo = spellInfo;
418 Effect = SpellEffectName(_effect.Effect);
424 Amplitude = _effect.EffectAmplitude;
427 MiscValue = _effect.EffectMiscValue[0];
428 MiscValueB = _effect.EffectMiscValue[1];
436 ItemType = _effect.EffectItemType;
440 Scaling.Class = _effect.ScalingClass;
442 Scaling.Variance = _effect.Variance;
444 ImplicitTargetConditions = nullptr;
446 _immunityInfo = nullptr;
447}
448
450SpellEffectInfo& SpellEffectInfo::operator=(SpellEffectInfo&&) noexcept = default;
451
452SpellEffectInfo::~SpellEffectInfo() = default;
453
454bool SpellEffectInfo::IsEffect() const
455{
456 return Effect != 0;
457}
458
460{
461 return Effect == effectName;
462}
463
468
470{
471 return IsAura() && ApplyAuraName == aura;
472}
473
475{
476 return TargetA.IsArea() || TargetB.IsArea();
477}
478
492
497
499{
500 if (!ApplyAuraPeriod)
501 return 0;
502
503 int32 duration = _spellInfo->GetDuration();
504 // skip infinite periodics
505 if (duration <= 0)
506 return 0;
507
508 uint32 totalTicks = static_cast<uint32>(duration) / ApplyAuraPeriod;
510 ++totalTicks;
511
512 return totalTicks;
513}
514
515int32 SpellEffectInfo::CalcValueAsInt(WorldObject const* caster /*= nullptr*/, SpellEffectValue const* basePoints /*= nullptr*/, Unit const* target /*= nullptr*/, float* variance /*= nullptr*/, uint32 castItemId /*= 0*/, int32 itemLevel /*= -1*/) const
516{
517 return int32(CalcValue(caster, basePoints, target, variance, castItemId, itemLevel));
518}
519
520SpellEffectValue SpellEffectInfo::CalcValue(WorldObject const* caster /*= nullptr*/, SpellEffectValue const* bp /*= nullptr*/, Unit const* target /*= nullptr*/, float* variance /*= nullptr*/, uint32 castItemId /*= 0*/, int32 itemLevel /*= -1*/) const
521{
522 SpellEffectValue basePoints = CalcBaseValue(caster, target, castItemId, itemLevel);
523 SpellEffectValue value = bp ? *bp : basePoints;
524 SpellEffectValue basePointsPerLevel = RealPointsPerLevel;
526
527 Unit const* casterUnit = nullptr;
528 if (caster)
529 {
530 casterUnit = caster->ToUnit();
531 if (Player const* playerCaster = caster->ToPlayer())
532 {
533 if (Optional<PlayerSpellTrait> trait = playerCaster->GetTraitInfoForSpell(_spellInfo->Id))
534 {
535 if (std::vector<TraitDefinitionEffectPointsEntry const*> const* traitDefinitionEffectPoints = TraitMgr::GetTraitDefinitionEffectPointModifiers(trait->DefinitionId))
536 {
537 auto pointsOverride = std::ranges::find(*traitDefinitionEffectPoints, EffectIndex, &TraitDefinitionEffectPointsEntry::EffectIndex);
538 if (pointsOverride != traitDefinitionEffectPoints->end())
539 {
540 float traitBasePoints = sDB2Manager.GetCurveValueAt((*pointsOverride)->CurveID, trait->Rank);
541 switch ((*pointsOverride)->GetOperationType())
542 {
544 value = traitBasePoints;
545 break;
547 value *= traitBasePoints;
548 break;
550 default:
551 break;
552 }
553 }
554 }
555 }
556 }
557 }
558
559 if (Scaling.Variance)
560 {
561 float delta = fabs(Scaling.Variance * 0.5f);
562 float valueVariance = frand(-delta, delta);
563 value += basePoints * valueVariance;
564
565 if (variance)
566 *variance = valueVariance;
567 }
568
569 // base amount modification based on spell lvl vs caster lvl
570 if (Scaling.Coefficient != 0.0f)
571 {
573 comboDamage = value * Scaling.ResourceCoefficient;
574 }
576 {
577 if (casterUnit && basePointsPerLevel != 0.0)
578 {
579 int32 level = int32(casterUnit->GetLevel());
580 if (level > int32(_spellInfo->MaxLevel) && _spellInfo->MaxLevel > 0)
581 level = int32(_spellInfo->MaxLevel);
582
583 // if base level is greater than spell level, reduce by base level (eg. pilgrims foods)
584 level -= int32(std::max(_spellInfo->BaseLevel, _spellInfo->SpellLevel));
585 level = std::max(level, 0);
586 value += level * basePointsPerLevel;
587 }
588 }
589
590 // random damage
591 if (casterUnit)
592 {
593 // bonus amount from combo points
594 if (comboDamage)
595 if (int32 comboPoints = casterUnit->GetPower(POWER_COMBO_POINTS))
596 value += comboDamage * comboPoints;
597 }
598
600 if (Player const* playerCaster = Object::ToPlayer(caster))
601 value += *playerCaster->m_activePlayerData->Mastery * BonusCoefficient;
602
603 if (caster)
604 value = caster->ApplyEffectModifiers(_spellInfo, EffectIndex, value);
605
606 switch (Effect)
607 {
621 value = std::round(value);
622 break;
633 switch (ApplyAuraName)
634 {
648 value = std::round(value);
649 break;
650 default:
651 break;
652 }
653 break;
654 default:
655 break;
656 }
657
658 return std::clamp(value, MinValue, MaxValue);
659}
660
661SpellEffectValue SpellEffectInfo::CalcBaseValue(WorldObject const* caster, Unit const* target, uint32 itemId, int32 itemLevel) const
662{
663 if (Scaling.Coefficient != 0.0f)
664 {
667 level = target->GetLevel();
668 else if (caster && caster->IsUnit())
669 level = caster->ToUnit()->GetLevel();
670
672 level = _spellInfo->BaseLevel;
673
676
679
680 float value = 0.0f;
681 if (level > 0)
682 {
683 if (!Scaling.Class)
684 return 0;
685
686 uint32 effectiveItemLevel = itemLevel != -1 ? uint32(itemLevel) : 1u;
688 {
689 if (Scaling.Class == -8 || Scaling.Class == -9)
690 {
691 RandPropPointsEntry const* randPropPoints = sRandPropPointsStore.LookupEntry(effectiveItemLevel);
692 if (!randPropPoints)
693 randPropPoints = sRandPropPointsStore.AssertEntry(sRandPropPointsStore.GetNumRows() - 1);
694
695 value = Scaling.Class == -8 ? randPropPoints->DamageReplaceStatF : randPropPoints->DamageSecondaryF;
696 }
697 else
698 value = GetRandomPropertyPoints(effectiveItemLevel, ITEM_QUALITY_RARE, INVTYPE_CHEST, 0);
699 }
700 else
702
703 if (Scaling.Class == -7)
704 if (GtCombatRatingsMultByILvl const* ratingMult = sCombatRatingsMultByILvlGameTable.GetRow(effectiveItemLevel))
705 if (ItemSparseEntry const* itemSparse = sItemSparseStore.LookupEntry(itemId))
706 value *= GetIlvlStatMultiplier(ratingMult, InventoryType(itemSparse->InventoryType));
707
708 if (Scaling.Class == -6)
709 if (GtStaminaMultByILvl const* staminaMult = sStaminaMultByILvlGameTable.GetRow(effectiveItemLevel))
710 if (ItemSparseEntry const* itemSparse = sItemSparseStore.LookupEntry(itemId))
711 value *= GetIlvlStatMultiplier(staminaMult, InventoryType(itemSparse->InventoryType));
712 }
713
714 value *= Scaling.Coefficient;
715 if (value > 0.0f && value < 1.0f)
716 value = 1.0f;
717
719 value = round(value);
720
721 return value;
722 }
723 else
724 {
725 float value = BasePoints;
727 if (stat != ExpectedStatType::None)
728 {
731
732 // TODO - add expansion and content tuning id args?
733 uint32 contentTuningId = _spellInfo->ContentTuningId; // content tuning should be passed as arg, the one stored in SpellInfo is fallback
734 int32 expansion = -2;
735 if (ContentTuningEntry const* contentTuning = sContentTuningStore.LookupEntry(contentTuningId))
736 expansion = contentTuning->ExpansionID;
737
738 int32 level = 1;
740 level = target->GetLevel();
741 else if (caster && caster->IsUnit())
742 level = caster->ToUnit()->GetLevel();
743
744 value = sDB2Manager.EvaluateExpectedStat(stat, level, expansion, 0, CLASS_NONE, 0) * value / 100.0f;
746 value = round(value);
747 }
748
749 return value;
750 }
751}
752
753float SpellEffectInfo::CalcValueMultiplier(WorldObject* caster, Spell* spell /*= nullptr*/) const
754{
755 float multiplier = Amplitude;
756 if (Player* modOwner = (caster ? caster->GetSpellModOwner() : nullptr))
757 modOwner->ApplySpellMod(_spellInfo, SpellModOp::Amplitude, multiplier, spell);
758 return multiplier;
759}
760
761float SpellEffectInfo::CalcDamageMultiplier(WorldObject* caster, Spell* spell /*= nullptr*/) const
762{
763 float multiplierPercent = ChainAmplitude * 100.0f;
764 if (Player* modOwner = (caster ? caster->GetSpellModOwner() : nullptr))
765 modOwner->ApplySpellMod(_spellInfo, SpellModOp::ChainAmplitude, multiplierPercent, spell);
766 return multiplierPercent / 100.0f;
767}
768
770{
771 switch (targetIndex)
772 {
774 return TargetARadiusEntry != nullptr;
776 return TargetBRadiusEntry != nullptr;
777 default:
778 return false;
779 }
780}
781
782SpellRange SpellEffectInfo::CalcRadius(WorldObject const* caster /*= nullptr*/, SpellTargetIndex targetIndex /*=SpellTargetIndex::TargetA*/, Spell* spell /*= nullptr*/) const
783{
784 // TargetA -> TargetARadiusEntry
785 // TargetB -> TargetBRadiusEntry
786 // Aura effects have TargetARadiusEntry == TargetBRadiusEntry (mostly)
789 if (targetIndex == SpellTargetIndex::TargetB && HasRadius(targetIndex))
790 {
791 target = TargetB;
792 entry = TargetBRadiusEntry;
793 }
794
795 SpellRange radius;
796 if (!entry)
797 return radius;
798
799 radius = { .Min = entry->RadiusMin, .Max = entry->RadiusMax };
800
801 if (caster)
802 {
803 if (Unit const* casterUnit = caster->ToUnit())
804 radius.Max = std::min(entry->Radius + entry->RadiusPerLevel * casterUnit->GetLevel(), radius.Max);
805
806 if (Player* modOwner = caster->GetSpellModOwner())
807 modOwner->ApplySpellMod(_spellInfo, SpellModOp::Radius, radius.Max, spell);
808
810 {
811 if (Unit const* casterUnit = caster->ToUnit(); casterUnit && Spell::CanIncreaseRangeByMovement(casterUnit))
812 {
813 radius.Min = std::max(radius.Min - 2.0f, 0.0f);
814 radius.Max += 2.0f;
815 }
816 }
817 }
818
819 // Random targets use random value between RadiusMin and RadiusMax
820 // For other cases, client uses RadiusMax if RadiusMin is 0
821 if (target.GetTarget() == TARGET_DEST_CASTER_RANDOM ||
824 radius.Max = (radius.Max - radius.Min) * std::sqrt(rand_norm());
825
826 return radius;
827}
828
833
834uint32 SpellEffectInfo::GetMissingTargetMask(bool srcSet /*= false*/, bool dstSet /*= false*/, uint32 mask /*=0*/) const
835{
836 uint32 effImplicitTargetMask = GetTargetFlagMask(GetUsedTargetObjectType());
837 uint32 providedTargetMask = GetProvidedTargetMask() | mask;
838
839 // remove all flags covered by effect target mask
840 if (providedTargetMask & TARGET_FLAG_UNIT_MASK)
841 effImplicitTargetMask &= ~(TARGET_FLAG_UNIT_MASK);
842 if (providedTargetMask & TARGET_FLAG_CORPSE_MASK)
843 effImplicitTargetMask &= ~(TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK);
844 if (providedTargetMask & TARGET_FLAG_GAMEOBJECT_ITEM)
846 if (providedTargetMask & TARGET_FLAG_GAMEOBJECT)
847 effImplicitTargetMask &= ~(TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM);
848 if (providedTargetMask & TARGET_FLAG_ITEM)
849 effImplicitTargetMask &= ~(TARGET_FLAG_ITEM | TARGET_FLAG_GAMEOBJECT_ITEM);
850 if (dstSet || providedTargetMask & TARGET_FLAG_DEST_LOCATION)
851 effImplicitTargetMask &= ~(TARGET_FLAG_DEST_LOCATION);
852 if (srcSet || providedTargetMask & TARGET_FLAG_SOURCE_LOCATION)
853 effImplicitTargetMask &= ~(TARGET_FLAG_SOURCE_LOCATION);
854
855 return effImplicitTargetMask;
856}
857
862
864{
865 return _data[Effect].UsedTargetObjectType;
866}
867
869{
870 switch (Effect)
871 {
883 if (MiscValue == POWER_MANA)
899 switch (ApplyAuraName)
900 {
944 if (MiscValue == POWER_MANA)
947 default:
948 break;
949 }
950 break;
951 default:
952 break;
953 }
954
956}
957
958std::array<SpellEffectInfo::StaticData, TOTAL_SPELL_EFFECTS> SpellEffectInfo::_data =
959{ {
960 // implicit target type used target object type
962 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 1 SPELL_EFFECT_INSTAKILL
963 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 2 SPELL_EFFECT_SCHOOL_DAMAGE
964 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 3 SPELL_EFFECT_DUMMY
965 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 4 SPELL_EFFECT_PORTAL_TELEPORT
967 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 6 SPELL_EFFECT_APPLY_AURA
968 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 7 SPELL_EFFECT_ENVIRONMENTAL_DAMAGE
969 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 8 SPELL_EFFECT_POWER_DRAIN
970 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 9 SPELL_EFFECT_HEALTH_LEECH
973 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 12 SPELL_EFFECT_PORTAL
974 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 13 SPELL_EFFECT_TELEPORT_TO_RETURN_POINT
975 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 14 SPELL_EFFECT_INCREASE_CURRENCY_CAP
976 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 15 SPELL_EFFECT_TELEPORT_WITH_SPELL_VISUAL_KIT_LOADING_SCREEN
977 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 16 SPELL_EFFECT_QUEST_COMPLETE
978 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 17 SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
980 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 19 SPELL_EFFECT_ADD_EXTRA_ATTACKS
981 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 20 SPELL_EFFECT_DODGE
982 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 21 SPELL_EFFECT_EVADE
983 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 22 SPELL_EFFECT_PARRY
984 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 23 SPELL_EFFECT_BLOCK
985 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 24 SPELL_EFFECT_CREATE_ITEM
986 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 25 SPELL_EFFECT_WEAPON
987 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 26 SPELL_EFFECT_DEFENSE
988 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 27 SPELL_EFFECT_PERSISTENT_AREA_AURA
989 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 28 SPELL_EFFECT_SUMMON
991 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 30 SPELL_EFFECT_ENERGIZE
992 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 31 SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
993 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 32 SPELL_EFFECT_TRIGGER_MISSILE
995 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 34 SPELL_EFFECT_SUMMON_CHANGE_ITEM
996 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 35 SPELL_EFFECT_APPLY_AREA_AURA_PARTY
997 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 36 SPELL_EFFECT_LEARN_SPELL
998 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 37 SPELL_EFFECT_SPELL_DEFENSE
999 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 38 SPELL_EFFECT_DISPEL
1000 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 39 SPELL_EFFECT_LANGUAGE
1001 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 40 SPELL_EFFECT_DUAL_WIELD
1003 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 42 SPELL_EFFECT_JUMP_DEST
1004 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 43 SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
1005 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 44 SPELL_EFFECT_SKILL_STEP
1006 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 45 SPELL_EFFECT_ADD_HONOR
1007 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 46 SPELL_EFFECT_SPAWN
1008 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 47 SPELL_EFFECT_TRADE_SKILL
1009 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 48 SPELL_EFFECT_STEALTH
1010 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 49 SPELL_EFFECT_DETECT
1011 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 50 SPELL_EFFECT_TRANS_DOOR
1012 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 51 SPELL_EFFECT_FORCE_CRITICAL_HIT
1013 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 52 SPELL_EFFECT_SET_MAX_BATTLE_PET_COUNT
1014 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 53 SPELL_EFFECT_ENCHANT_ITEM
1015 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 54 SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
1016 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 55 SPELL_EFFECT_TAMECREATURE
1017 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 56 SPELL_EFFECT_SUMMON_PET
1018 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 57 SPELL_EFFECT_LEARN_PET_SPELL
1019 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 58 SPELL_EFFECT_WEAPON_DAMAGE
1020 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 59 SPELL_EFFECT_CREATE_RANDOM_ITEM
1021 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 60 SPELL_EFFECT_PROFICIENCY
1022 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 61 SPELL_EFFECT_SEND_EVENT
1023 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 62 SPELL_EFFECT_POWER_BURN
1024 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 63 SPELL_EFFECT_THREAT
1025 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 64 SPELL_EFFECT_TRIGGER_SPELL
1026 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 65 SPELL_EFFECT_APPLY_AREA_AURA_RAID
1027 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 66 SPELL_EFFECT_RECHARGE_ITEM
1028 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 67 SPELL_EFFECT_HEAL_MAX_HEALTH
1029 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 68 SPELL_EFFECT_INTERRUPT_CAST
1031 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 70 SPELL_EFFECT_COMPLETE_AND_REWARD_WORLD_QUEST
1032 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 71 SPELL_EFFECT_PICKPOCKET
1033 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 72 SPELL_EFFECT_ADD_FARSIGHT
1034 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 73 SPELL_EFFECT_UNTRAIN_TALENTS
1035 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 74 SPELL_EFFECT_APPLY_GLYPH
1036 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 75 SPELL_EFFECT_HEAL_MECHANICAL
1037 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 76 SPELL_EFFECT_SUMMON_OBJECT_WILD
1038 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 77 SPELL_EFFECT_SCRIPT_EFFECT
1039 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 78 SPELL_EFFECT_ATTACK
1040 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 79 SPELL_EFFECT_SANCTUARY
1041 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 80 SPELL_EFFECT_MODIFY_FOLLOWER_ITEM_LEVEL
1042 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 81 SPELL_EFFECT_PUSH_ABILITY_TO_ACTION_BAR
1043 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 82 SPELL_EFFECT_BIND_SIGHT
1045 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 84 SPELL_EFFECT_STUCK
1046 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 85 SPELL_EFFECT_SUMMON_PLAYER
1047 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 86 SPELL_EFFECT_ACTIVATE_OBJECT
1048 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 87 SPELL_EFFECT_GAMEOBJECT_DAMAGE
1049 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 88 SPELL_EFFECT_GAMEOBJECT_REPAIR
1050 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 89 SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
1051 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 90 SPELL_EFFECT_KILL_CREDIT
1052 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 91 SPELL_EFFECT_THREAT_ALL
1053 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM
1054 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 93 SPELL_EFFECT_FORCE_DESELECT
1055 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 94 SPELL_EFFECT_SELF_RESURRECT
1056 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 95 SPELL_EFFECT_SKINNING
1057 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 96 SPELL_EFFECT_CHARGE
1058 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 97 SPELL_EFFECT_CAST_BUTTON
1059 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 98 SPELL_EFFECT_KNOCK_BACK
1060 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 99 SPELL_EFFECT_DISENCHANT
1061 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 100 SPELL_EFFECT_INEBRIATE
1062 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 101 SPELL_EFFECT_FEED_PET
1063 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 102 SPELL_EFFECT_DISMISS_PET
1064 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 103 SPELL_EFFECT_REPUTATION
1065 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 104 SPELL_EFFECT_SUMMON_OBJECT_SLOT1
1066 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 105 SPELL_EFFECT_SURVEY
1067 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 106 SPELL_EFFECT_CHANGE_RAID_MARKER
1068 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 107 SPELL_EFFECT_SHOW_CORPSE_LOOT
1069 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 108 SPELL_EFFECT_DISPEL_MECHANIC
1070 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 109 SPELL_EFFECT_RESURRECT_PET
1071 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 110 SPELL_EFFECT_DESTROY_ALL_TOTEMS
1072 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 111 SPELL_EFFECT_DURABILITY_DAMAGE
1074 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 113 SPELL_EFFECT_CANCEL_CONVERSATION
1075 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 114 SPELL_EFFECT_ATTACK_ME
1076 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 115 SPELL_EFFECT_DURABILITY_DAMAGE_PCT
1077 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_CORPSE_ENEMY}, // 116 SPELL_EFFECT_SKIN_PLAYER_CORPSE
1078 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 117 SPELL_EFFECT_SPIRIT_HEAL
1079 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 118 SPELL_EFFECT_SKILL
1080 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 119 SPELL_EFFECT_APPLY_AREA_AURA_PET
1081 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 120 SPELL_EFFECT_TELEPORT_GRAVEYARD
1082 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 121 SPELL_EFFECT_NORMALIZED_WEAPON_DMG
1083 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 122 SPELL_EFFECT_122
1084 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 123 SPELL_EFFECT_SEND_TAXI
1085 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 124 SPELL_EFFECT_PULL_TOWARDS
1086 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 125 SPELL_EFFECT_MODIFY_THREAT_PERCENT
1087 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 126 SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
1088 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 127 SPELL_EFFECT_PROSPECTING
1089 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 128 SPELL_EFFECT_APPLY_AREA_AURA_FRIEND
1090 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
1091 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 130 SPELL_EFFECT_REDIRECT_THREAT
1092 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 131 SPELL_EFFECT_PLAY_SOUND
1093 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 132 SPELL_EFFECT_PLAY_MUSIC
1094 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 133 SPELL_EFFECT_UNLEARN_SPECIALIZATION
1095 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 134 SPELL_EFFECT_KILL_CREDIT2
1096 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 135 SPELL_EFFECT_CALL_PET
1097 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 136 SPELL_EFFECT_HEAL_PCT
1098 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 137 SPELL_EFFECT_ENERGIZE_PCT
1099 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 138 SPELL_EFFECT_LEAP_BACK
1100 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 139 SPELL_EFFECT_CLEAR_QUEST
1101 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 140 SPELL_EFFECT_FORCE_CAST
1102 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 141 SPELL_EFFECT_FORCE_CAST_WITH_VALUE
1103 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
1104 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER
1105 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 144 SPELL_EFFECT_KNOCK_BACK_DEST
1106 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 145 SPELL_EFFECT_PULL_TOWARDS_DEST
1107 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 146 SPELL_EFFECT_RESTORE_GARRISON_TROOP_VITALITY
1108 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 147 SPELL_EFFECT_QUEST_FAIL
1109 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 148 SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
1110 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 149 SPELL_EFFECT_CHARGE_DEST
1111 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 150 SPELL_EFFECT_QUEST_START
1112 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 151 SPELL_EFFECT_TRIGGER_SPELL_2
1113 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 152 SPELL_EFFECT_SUMMON_RAF_FRIEND
1114 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 153 SPELL_EFFECT_CREATE_TAMED_PET
1115 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 154 SPELL_EFFECT_DISCOVER_TAXI
1116 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 155 SPELL_EFFECT_TITAN_GRIP
1117 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 156 SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
1118 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 157 SPELL_EFFECT_CREATE_LOOT
1119 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 158 SPELL_EFFECT_MILLING
1120 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 159 SPELL_EFFECT_ALLOW_RENAME_PET
1121 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 160 SPELL_EFFECT_FORCE_CAST_2
1122 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 161 SPELL_EFFECT_TALENT_SPEC_COUNT
1123 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 162 SPELL_EFFECT_TALENT_SPEC_SELECT
1124 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 163 SPELL_EFFECT_OBLITERATE_ITEM
1125 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 164 SPELL_EFFECT_REMOVE_AURA
1126 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 165 SPELL_EFFECT_DAMAGE_FROM_MAX_HEALTH_PCT
1127 {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 166 SPELL_EFFECT_GIVE_CURRENCY
1128 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 167 SPELL_EFFECT_UPDATE_PLAYER_PHASE
1129 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 168 SPELL_EFFECT_ALLOW_CONTROL_PET
1130 {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 169 SPELL_EFFECT_DESTROY_ITEM
1131 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 170 SPELL_EFFECT_UPDATE_ZONE_AURAS_AND_PHASES
1132 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 171 SPELL_EFFECT_SUMMON_PERSONAL_GAMEOBJECT
1133 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_CORPSE_ALLY}, // 172 SPELL_EFFECT_RESURRECT_WITH_AURA
1134 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 173 SPELL_EFFECT_UNLOCK_GUILD_VAULT_TAB
1135 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 174 SPELL_EFFECT_APPLY_AURA_ON_PET
1136 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 175 SPELL_EFFECT_175
1137 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 176 SPELL_EFFECT_SANCTUARY_2
1138 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 177 SPELL_EFFECT_DESPAWN_PERSISTENT_AREA_AURA
1139 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 178 SPELL_EFFECT_178
1140 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 179 SPELL_EFFECT_CREATE_AREATRIGGER
1141 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 180 SPELL_EFFECT_UPDATE_AREATRIGGER
1142 {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 181 SPELL_EFFECT_REMOVE_TALENT
1143 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 182 SPELL_EFFECT_DESPAWN_AREATRIGGER
1144 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 183 SPELL_EFFECT_183
1145 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 184 SPELL_EFFECT_REPUTATION_2
1146 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 185 SPELL_EFFECT_185
1147 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 186 SPELL_EFFECT_186
1148 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 187 SPELL_EFFECT_RANDOMIZE_ARCHAEOLOGY_DIGSITES
1149 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 188 SPELL_EFFECT_SUMMON_STABLED_PET_AS_GUARDIAN
1150 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 189 SPELL_EFFECT_LOOT
1151 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 190 SPELL_EFFECT_CHANGE_PARTY_MEMBERS
1152 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 191 SPELL_EFFECT_TELEPORT_TO_DIGSITE
1153 {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 192 SPELL_EFFECT_UNCAGE_BATTLEPET
1154 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 193 SPELL_EFFECT_START_PET_BATTLE
1155 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 194 SPELL_EFFECT_194
1156 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 195 SPELL_EFFECT_PLAY_SCENE_SCRIPT_PACKAGE
1157 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 196 SPELL_EFFECT_CREATE_SCENE_OBJECT
1158 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 197 SPELL_EFFECT_CREATE_PERSONAL_SCENE_OBJECT
1159 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 198 SPELL_EFFECT_PLAY_SCENE
1160 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 199 SPELL_EFFECT_DESPAWN_SUMMON
1161 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 200 SPELL_EFFECT_HEAL_BATTLEPET_PCT
1162 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 201 SPELL_EFFECT_ENABLE_BATTLE_PETS
1163 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 202 SPELL_EFFECT_APPLY_AREA_AURA_SUMMONS
1164 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 203 SPELL_EFFECT_REMOVE_AURA_2
1165 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 204 SPELL_EFFECT_CHANGE_BATTLEPET_QUALITY
1166 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 205 SPELL_EFFECT_LAUNCH_QUEST_CHOICE
1167 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 206 SPELL_EFFECT_ALTER_IETM
1168 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 207 SPELL_EFFECT_LAUNCH_QUEST_TASK
1169 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 208 SPELL_EFFECT_SET_REPUTATION
1170 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 209 SPELL_EFFECT_209
1171 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 210 SPELL_EFFECT_LEARN_GARRISON_BUILDING
1172 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 211 SPELL_EFFECT_LEARN_GARRISON_SPECIALIZATION
1173 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 212 SPELL_EFFECT_REMOVE_AURA_BY_SPELL_LABEL
1174 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 213 SPELL_EFFECT_JUMP_DEST_2
1175 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 214 SPELL_EFFECT_CREATE_GARRISON
1176 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 215 SPELL_EFFECT_UPGRADE_CHARACTER_SPELLS
1177 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 216 SPELL_EFFECT_CREATE_SHIPMENT
1178 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 217 SPELL_EFFECT_UPGRADE_GARRISON
1179 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 218 SPELL_EFFECT_218
1180 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 219 SPELL_EFFECT_CREATE_CONVERSATION
1181 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 220 SPELL_EFFECT_ADD_GARRISON_FOLLOWER
1182 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 221 SPELL_EFFECT_ADD_GARRISON_MISSION
1183 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 222 SPELL_EFFECT_CREATE_HEIRLOOM_ITEM
1184 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 223 SPELL_EFFECT_CHANGE_ITEM_BONUSES
1185 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 224 SPELL_EFFECT_ACTIVATE_GARRISON_BUILDING
1186 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 225 SPELL_EFFECT_GRANT_BATTLEPET_LEVEL
1187 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 226 SPELL_EFFECT_TRIGGER_ACTION_SET
1188 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 227 SPELL_EFFECT_TELEPORT_TO_LFG_DUNGEON
1189 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 228 SPELL_EFFECT_228
1190 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 229 SPELL_EFFECT_SET_FOLLOWER_QUALITY
1192 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 231 SPELL_EFFECT_INCREASE_FOLLOWER_EXPERIENCE
1193 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 232 SPELL_EFFECT_REMOVE_PHASE
1194 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 233 SPELL_EFFECT_RANDOMIZE_FOLLOWER_ABILITIES
1195 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 234 SPELL_EFFECT_234
1196 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 235 SPELL_EFFECT_235
1197 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 236 SPELL_EFFECT_GIVE_EXPERIENCE
1198 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 237 SPELL_EFFECT_GIVE_RESTED_EXPERIENCE_BONUS
1199 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 238 SPELL_EFFECT_INCREASE_SKILL
1200 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 239 SPELL_EFFECT_END_GARRISON_BUILDING_CONSTRUCTION
1201 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 240 SPELL_EFFECT_GIVE_ARTIFACT_POWER
1202 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 241 SPELL_EFFECT_241
1203 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 242 SPELL_EFFECT_GIVE_ARTIFACT_POWER_NO_BONUS
1204 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 243 SPELL_EFFECT_APPLY_ENCHANT_ILLUSION
1205 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 244 SPELL_EFFECT_LEARN_FOLLOWER_ABILITY
1206 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 245 SPELL_EFFECT_UPGRADE_HEIRLOOM
1207 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 246 SPELL_EFFECT_FINISH_GARRISON_MISSION
1208 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 247 SPELL_EFFECT_ADD_GARRISON_MISSION_SET
1209 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 248 SPELL_EFFECT_FINISH_SHIPMENT
1210 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 249 SPELL_EFFECT_FORCE_EQUIP_ITEM
1211 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 250 SPELL_EFFECT_TAKE_SCREENSHOT
1212 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 251 SPELL_EFFECT_SET_GARRISON_CACHE_SIZE
1213 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 252 SPELL_EFFECT_TELEPORT_UNITS
1214 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 253 SPELL_EFFECT_GIVE_HONOR
1215 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 254 SPELL_EFFECT_JUMP_CHARGE
1216 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 255 SPELL_EFFECT_LEARN_TRANSMOG_SET
1217 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 256 SPELL_EFFECT_256
1218 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 257 SPELL_EFFECT_257
1219 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 258 SPELL_EFFECT_MODIFY_KEYSTONE
1220 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 259 SPELL_EFFECT_RESPEC_AZERITE_EMPOWERED_ITEM
1221 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 260 SPELL_EFFECT_SUMMON_STABLED_PET
1222 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 261 SPELL_EFFECT_SCRAP_ITEM
1223 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 262 SPELL_EFFECT_262
1224 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 263 SPELL_EFFECT_REPAIR_ITEM
1225 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 264 SPELL_EFFECT_REMOVE_GEM
1226 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 265 SPELL_EFFECT_LEARN_AZERITE_ESSENCE_POWER
1227 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 266 SPELL_EFFECT_SET_ITEM_BONUS_LIST_GROUP_ENTRY
1228 {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 267 SPELL_EFFECT_CREATE_PRIVATE_CONVERSATION
1229 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 268 SPELL_EFFECT_APPLY_MOUNT_EQUIPMENT
1230 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 269 SPELL_EFFECT_INCREASE_ITEM_BONUS_LIST_GROUP_STEP
1232 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 271 SPELL_EFFECT_APPLY_AREA_AURA_PARTY_NONRANDOM
1233 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 272 SPELL_EFFECT_SET_COVENANT
1234 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 273 SPELL_EFFECT_CRAFT_RUNEFORGE_LEGENDARY
1235 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 274 SPELL_EFFECT_274
1236 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 275 SPELL_EFFECT_275
1237 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 276 SPELL_EFFECT_LEARN_TRANSMOG_ILLUSION
1238 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 277 SPELL_EFFECT_SET_CHROMIE_TIME
1239 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 278 SPELL_EFFECT_278
1240 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 279 SPELL_EFFECT_LEARN_GARR_TALENT
1241 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 280 SPELL_EFFECT_280
1242 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 281 SPELL_EFFECT_LEARN_SOULBIND_CONDUIT
1243 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 282 SPELL_EFFECT_CONVERT_ITEMS_TO_CURRENCY
1244 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 283 SPELL_EFFECT_COMPLETE_CAMPAIGN
1245 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 284 SPELL_EFFECT_SEND_CHAT_MESSAGE
1246 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 285 SPELL_EFFECT_MODIFY_KEYSTONE_2
1247 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 286 SPELL_EFFECT_GRANT_BATTLEPET_EXPERIENCE
1248 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 287 SPELL_EFFECT_SET_GARRISON_FOLLOWER_LEVEL
1249 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 288 SPELL_EFFECT_CRAFT_ITEM
1250 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 289 SPELL_EFFECT_MODIFY_AURA_STACKS
1251 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 290 SPELL_EFFECT_MODIFY_COOLDOWN
1252 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 291 SPELL_EFFECT_MODIFY_COOLDOWNS
1253 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 292 SPELL_EFFECT_MODIFY_COOLDOWNS_BY_CATEGORY
1254 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 293 SPELL_EFFECT_MODIFY_CHARGES
1255 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 294 SPELL_EFFECT_CRAFT_LOOT
1256 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 295 SPELL_EFFECT_SALVAGE_ITEM
1257 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 296 SPELL_EFFECT_CRAFT_SALVAGE_ITEM
1258 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 297 SPELL_EFFECT_RECRAFT_ITEM
1259 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 298 SPELL_EFFECT_CANCEL_ALL_PRIVATE_CONVERSATIONS
1260 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 299 SPELL_EFFECT_299
1261 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 300 SPELL_EFFECT_300
1262 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 301 SPELL_EFFECT_CRAFT_ENCHANT
1263 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_NONE}, // 302 SPELL_EFFECT_GATHERING
1264 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 303 SPELL_EFFECT_CREATE_TRAIT_TREE_CONFIG
1265 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 304 SPELL_EFFECT_CHANGE_ACTIVE_COMBAT_TRAIT_CONFIG
1266 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 305 SPELL_EFFECT_305
1267 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 306 SPELL_EFFECT_UPDATE_INTERACTIONS
1268 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 307 SPELL_EFFECT_307
1269 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 308 SPELL_EFFECT_CANCEL_PRELOAD_WORLD
1270 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 309 SPELL_EFFECT_PRELOAD_WORLD
1271 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 310 SPELL_EFFECT_310
1272 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 311 SPELL_EFFECT_SKIP_QUESTLINE
1273 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 312 SPELL_EFFECT_312
1274 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 313 SPELL_EFFECT_CHANGE_ITEM_BONUSES_2
1275 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 314 SPELL_EFFECT_ADD_SOCKET_BONUS
1276 {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 315 SPELL_EFFECT_LEARN_TRANSMOG_APPEARANCE_FROM_ITEM_MOD_APPEARANCE_GROUP
1277 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 316 SPELL_EFFECT_KILL_CREDIT_LABEL_1
1278 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 317 SPELL_EFFECT_KILL_CREDIT_LABEL_2
1279 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 318 SPELL_EFFECT_318
1280 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 319 SPELL_EFFECT_319
1281 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 320 SPELL_EFFECT_320
1282 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 321 SPELL_EFFECT_321
1283 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 322 SPELL_EFFECT_322
1284 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 323 SPELL_EFFECT_323
1285 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 324 SPELL_EFFECT_324
1286 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 325 SPELL_EFFECT_325
1287 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 326 SPELL_EFFECT_326
1288 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 327 SPELL_EFFECT_327
1289 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 328 SPELL_EFFECT_328
1290 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 329 SPELL_EFFECT_329
1291 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 330 SPELL_EFFECT_330
1292 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 331 SPELL_EFFECT_331
1293 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 332 SPELL_EFFECT_332
1294 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 333 SPELL_EFFECT_333
1295 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 334 SPELL_EFFECT_334
1296 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 335 SPELL_EFFECT_SET_PLAYER_DATA_ELEMENT_ACCOUNT
1297 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 336 SPELL_EFFECT_SET_PLAYER_DATA_ELEMENT_CHARACTER
1298 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 337 SPELL_EFFECT_SET_PLAYER_DATA_FLAG_ACCOUNT
1299 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 338 SPELL_EFFECT_SET_PLAYER_DATA_FLAG_CHARACTER
1300 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 339 SPELL_EFFECT_UI_ACTION
1301 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 340 SPELL_EFFECT_340
1302 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 341 SPELL_EFFECT_LEARN_WARBAND_SCENE
1303 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 342 SPELL_EFFECT_342
1304 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 343 SPELL_EFFECT_343
1305 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 344 SPELL_EFFECT_344
1306 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 345 SPELL_EFFECT_ASSIST_ACTION
1307 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 346 SPELL_EFFECT_346
1308 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 347 SPELL_EFFECT_EQUIP_TRANSMOG_OUTFIT
1309 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 348 SPELL_EFFECT_GIVE_HOUSE_LEVEL
1310 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 349 SPELL_EFFECT_LEARN_HOUSE_ROOM
1311 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 350 SPELL_EFFECT_LEARN_HOUSE_EXTERIOR_COMPONENT
1312 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 351 SPELL_EFFECT_LEARN_HOUSE_THEME
1313 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 352 SPELL_EFFECT_LEARN_HOUSE_ROOM_COMPONENT_TEXTURE
1314 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 353 SPELL_EFFECT_CREATE_AREATRIGGER_2
1315 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 354 SPELL_EFFECT_SET_NEIGHBORHOOD_INITIATIVE
1316 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 355 SPELL_EFFECT_LEARN_HOUSE_TYPE
1317} };
1318
1320 : Id(spellName->ID), Difficulty(difficulty)
1321{
1322 _effects.reserve(32);
1323 for (SpellEffectEntry const* spellEffect : data.Effects)
1324 {
1325 if (!spellEffect)
1326 continue;
1327
1328 Trinity::Containers::EnsureWritableVectorIndex(_effects, spellEffect->EffectIndex) = SpellEffectInfo(this, *spellEffect);
1329 }
1330
1331 // Correct EffectIndex for blank effects
1332 for (size_t i = 0; i < _effects.size(); ++i)
1333 {
1334 _effects[i]._spellInfo = this;
1335 _effects[i].EffectIndex = SpellEffIndex(i);
1336 }
1337
1338 _effects.shrink_to_fit();
1339
1340 SpellName = &spellName->Name;
1341
1342 // SpellMiscEntry
1343 if (SpellMiscEntry const* _misc = data.Misc)
1344 {
1345 Attributes = _misc->Attributes[0];
1346 AttributesEx = _misc->Attributes[1];
1347 AttributesEx2 = _misc->Attributes[2];
1348 AttributesEx3 = _misc->Attributes[3];
1349 AttributesEx4 = _misc->Attributes[4];
1350 AttributesEx5 = _misc->Attributes[5];
1351 AttributesEx6 = _misc->Attributes[6];
1352 AttributesEx7 = _misc->Attributes[7];
1353 AttributesEx8 = _misc->Attributes[8];
1354 AttributesEx9 = _misc->Attributes[9];
1355 AttributesEx10 = _misc->Attributes[10];
1356 AttributesEx11 = _misc->Attributes[11];
1357 AttributesEx12 = _misc->Attributes[12];
1358 AttributesEx13 = _misc->Attributes[13];
1359 AttributesEx14 = _misc->Attributes[14];
1360 AttributesEx15 = _misc->Attributes[15];
1361 AttributesEx16 = _misc->Attributes[16];
1362 CastTimeEntry = sSpellCastTimesStore.LookupEntry(_misc->CastingTimeIndex);
1363 DurationEntry = sSpellDurationStore.LookupEntry(_misc->DurationIndex);
1364 RangeEntry = sSpellRangeStore.LookupEntry(_misc->RangeIndex);
1365 Speed = _misc->Speed;
1366 LaunchDelay = _misc->LaunchDelay;
1367 MinDuration = _misc->MinDuration;
1368 SchoolMask = _misc->SchoolMask;
1369 IconFileDataId = _misc->SpellIconFileDataID;
1370 ActiveIconFileDataId = _misc->ActiveIconFileDataID;
1371 ContentTuningId = _misc->ContentTuningID;
1372 ShowFutureSpellPlayerConditionID = _misc->ShowFutureSpellPlayerConditionID;
1373 }
1374
1375 // SpellScalingEntry
1376 if (SpellScalingEntry const* _scaling = data.Scaling)
1377 {
1378 Scaling.MinScalingLevel = _scaling->MinScalingLevel;
1379 Scaling.MaxScalingLevel = _scaling->MaxScalingLevel;
1380 }
1381
1382 // SpellAuraOptionsEntry
1383 if (SpellAuraOptionsEntry const* _options = data.AuraOptions)
1384 {
1385 ProcFlags = _options->ProcTypeMask;
1386 ProcChance = _options->ProcChance;
1387 ProcCharges = _options->ProcCharges;
1388 ProcCooldown = _options->ProcCategoryRecovery;
1389 StackAmount = _options->CumulativeAura;
1390 if (SpellProcsPerMinuteEntry const* _ppm = sSpellProcsPerMinuteStore.LookupEntry(_options->SpellProcsPerMinuteID))
1391 {
1392 ProcBasePPM = _ppm->BaseProcRate;
1393 ProcPPMMods = sDB2Manager.GetSpellProcsPerMinuteMods(_ppm->ID);
1394 }
1395 }
1396
1397 // SpellAuraRestrictionsEntry
1398 if (SpellAuraRestrictionsEntry const* _aura = data.AuraRestrictions)
1399 {
1400 CasterAuraState = _aura->CasterAuraState;
1401 TargetAuraState = _aura->TargetAuraState;
1402 ExcludeCasterAuraState = _aura->ExcludeCasterAuraState;
1403 ExcludeTargetAuraState = _aura->ExcludeTargetAuraState;
1404 CasterAuraSpell = _aura->CasterAuraSpell;
1405 TargetAuraSpell = _aura->TargetAuraSpell;
1406 ExcludeCasterAuraSpell = _aura->ExcludeCasterAuraSpell;
1407 ExcludeTargetAuraSpell = _aura->ExcludeTargetAuraSpell;
1408 CasterAuraType = AuraType(_aura->CasterAuraType);
1409 TargetAuraType = AuraType(_aura->TargetAuraType);
1410 ExcludeCasterAuraType = AuraType(_aura->ExcludeCasterAuraType);
1411 ExcludeTargetAuraType = AuraType(_aura->ExcludeTargetAuraType);
1412 }
1413
1414 // SpellCastingRequirementsEntry
1415 if (SpellCastingRequirementsEntry const* _castreq = data.CastingRequirements)
1416 {
1417 RequiresSpellFocus = _castreq->RequiresSpellFocus;
1418 FacingCasterFlags = _castreq->FacingCasterFlags;
1419 RequiredAreasID = _castreq->RequiredAreasID;
1420 }
1421
1422 // SpellCategoriesEntry
1423 if (SpellCategoriesEntry const* _categories = data.Categories)
1424 {
1425 CategoryId = _categories->Category;
1426 Dispel = _categories->DispelType;
1427 Mechanic = _categories->Mechanic;
1428 StartRecoveryCategory = _categories->StartRecoveryCategory;
1429 DmgClass = _categories->DefenseType;
1430 PreventionType = _categories->PreventionType;
1431 ChargeCategoryId = _categories->ChargeCategory;
1432 }
1433
1434 // SpellClassOptionsEntry
1435 if (SpellClassOptionsEntry const* _class = data.ClassOptions)
1436 {
1437 SpellFamilyName = _class->SpellClassSet;
1438 SpellFamilyFlags = _class->SpellClassMask;
1439 }
1440
1441 // SpellCooldownsEntry
1442 if (SpellCooldownsEntry const* _cooldowns = data.Cooldowns)
1443 {
1444 RecoveryTime = _cooldowns->RecoveryTime;
1445 CategoryRecoveryTime = _cooldowns->CategoryRecoveryTime;
1446 StartRecoveryTime = _cooldowns->StartRecoveryTime;
1447 CooldownAuraSpellId = _cooldowns->AuraSpellID;
1448 }
1449
1450 // SpellEmpowerStageEntry
1451 std::ranges::transform(data.EmpowerStages, std::back_inserter(EmpowerStageThresholds), [](SpellEmpowerStageEntry const* stage) { return Milliseconds(stage->DurationMs); });
1452
1453 // SpellEquippedItemsEntry
1454 if (SpellEquippedItemsEntry const* _equipped = data.EquippedItems)
1455 {
1456 EquippedItemClass = _equipped->EquippedItemClass;
1457 EquippedItemSubClassMask = _equipped->EquippedItemSubclass;
1458 EquippedItemInventoryTypeMask = _equipped->EquippedItemInvTypes;
1459 }
1460
1461 // SpellInterruptsEntry
1462 if (SpellInterruptsEntry const* _interrupt = data.Interrupts)
1463 {
1464 InterruptFlags = SpellInterruptFlags(_interrupt->InterruptFlags);
1465 AuraInterruptFlags = SpellAuraInterruptFlags(_interrupt->AuraInterruptFlags[0]);
1466 AuraInterruptFlags2 = SpellAuraInterruptFlags2(_interrupt->AuraInterruptFlags[1]);
1467 ChannelInterruptFlags = SpellAuraInterruptFlags(_interrupt->ChannelInterruptFlags[0]);
1468 ChannelInterruptFlags2 = SpellAuraInterruptFlags2(_interrupt->ChannelInterruptFlags[1]);
1469 }
1470
1471 for (SpellLabelEntry const* label : data.Labels)
1472 Labels.insert(label->LabelID);
1473
1474 // SpellLevelsEntry
1475 if (SpellLevelsEntry const* _levels = data.Levels)
1476 {
1477 MaxLevel = _levels->MaxLevel;
1478 BaseLevel = _levels->BaseLevel;
1479 SpellLevel = _levels->SpellLevel;
1480 }
1481
1482 // SpellPowerEntry
1483 PowerCosts = data.Powers;
1484
1485 // SpellReagentsEntry
1486 if (SpellReagentsEntry const* _reagents = data.Reagents)
1487 {
1488 Reagent = _reagents->Reagent;
1489 ReagentCount = _reagents->ReagentCount;
1490 }
1491
1493
1494 // SpellShapeshiftEntry
1495 if (SpellShapeshiftEntry const* _shapeshift = data.Shapeshift)
1496 {
1497 Stances = MAKE_PAIR64(_shapeshift->ShapeshiftMask[0], _shapeshift->ShapeshiftMask[1]);
1498 StancesNot = MAKE_PAIR64(_shapeshift->ShapeshiftExclude[0], _shapeshift->ShapeshiftExclude[1]);
1499 }
1500
1501 // SpellTargetRestrictionsEntry
1502 if (SpellTargetRestrictionsEntry const* _target = data.TargetRestrictions)
1503 {
1504 ConeAngle = _target->ConeDegrees;
1505 Width = _target->Width;
1506 Targets = _target->Targets;
1507 TargetCreatureType = _target->TargetCreatureType;
1508 MaxAffectedTargets = _target->MaxTargets;
1509 MaxTargetLevel = _target->MaxTargetLevel;
1510 }
1511
1512 // SpellTotemsEntry
1513 if (SpellTotemsEntry const* _totem = data.Totems)
1514 {
1515 TotemCategory = _totem->RequiredTotemCategoryID;
1516 Totem = _totem->Totem;
1517 }
1518
1519 _visuals = data.Visuals;
1520}
1521
1522SpellInfo::SpellInfo(SpellNameEntry const* spellName, ::Difficulty difficulty, std::vector<SpellEffectEntry> const& effects)
1523 : Id(spellName->ID), Difficulty(difficulty)
1524{
1525 SpellName = &spellName->Name;
1526
1527 _effects.reserve(32);
1528 for (SpellEffectEntry const& spellEffect : effects)
1529 Trinity::Containers::EnsureWritableVectorIndex(_effects, spellEffect.EffectIndex) = SpellEffectInfo(this, spellEffect);
1530
1531 // Correct EffectIndex for blank effects
1532 for (size_t i = 0; i < _effects.size(); ++i)
1533 {
1534 _effects[i]._spellInfo = this;
1535 _effects[i].EffectIndex = SpellEffIndex(i);
1536 }
1537
1538 _effects.shrink_to_fit();
1539}
1540
1545
1547{
1548 return CategoryId;
1549}
1550
1552{
1553 for (SpellEffectInfo const& eff : GetEffects())
1554 if (eff.IsEffect(effect))
1555 return true;
1556
1557 return false;
1558}
1559
1561{
1562 for (SpellEffectInfo const& effect : GetEffects())
1563 if (effect.IsAura(aura))
1564 return true;
1565
1566 return false;
1567}
1568
1570{
1571 for (SpellEffectInfo const& effect : GetEffects())
1572 if (effect.IsAreaAuraEffect())
1573 return true;
1574
1575 return false;
1576}
1577
1579{
1580 for (SpellEffectInfo const& effect : GetEffects())
1581 {
1582 if (effect.IsEffect())
1583 {
1584 switch (effect.Effect)
1585 {
1594 continue;
1595 default:
1596 return false;
1597 }
1598 }
1599 }
1600
1601 return true;
1602}
1603
1605{
1606 for (SpellEffectInfo const& effect : GetEffects())
1607 if (effect.TargetA.GetTarget() == target || effect.TargetB.GetTarget() == target)
1608 return true;
1609
1610 return false;
1611}
1612
1613bool SpellInfo::CanBeInterrupted(WorldObject const* interruptCaster, Unit const* interruptTarget, bool ignoreImmunity /*= false*/) const
1614{
1619 || (interruptCaster && interruptCaster->IsUnit() && interruptCaster->ToUnit()->HasAuraTypeWithMiscvalue(SPELL_AURA_ALLOW_INTERRUPT_SPELL, Id))
1620 || ((!(interruptTarget->GetMechanicImmunityMask() & (1 << MECHANIC_INTERRUPT)) || ignoreImmunity)
1623}
1624
1629
1631{
1632 if (GetEffects().size() < 2)
1633 return false;
1634
1638 || Id == 64323;
1639}
1640
1645
1647{
1648 for (SpellEffectInfo const& effect : GetEffects())
1649 {
1650 if (effect.Effect == SPELL_EFFECT_SKILL)
1651 {
1652 uint32 skill = effect.MiscValue;
1653
1654 if (IsProfessionSkill(skill))
1655 return true;
1656 }
1657 }
1658 return false;
1659}
1660
1662{
1663 for (SpellEffectInfo const& effect : GetEffects())
1664 {
1665 if (effect.Effect == SPELL_EFFECT_SKILL)
1666 {
1667 uint32 skill = effect.MiscValue;
1668
1669 if (IsPrimaryProfessionSkill(skill))
1670 return true;
1671 }
1672 }
1673 return false;
1674}
1675
1677{
1678 return IsPrimaryProfession() && GetRank() == 1;
1679}
1680
1682{
1683 SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(Id);
1684
1685 for (SkillLineAbilityMap::const_iterator _spell_idx = bounds.first; _spell_idx != bounds.second; ++_spell_idx)
1686 if (_spell_idx->second->SkillLine == skillType)
1687 return true;
1688
1689 return false;
1690}
1691
1693{
1694 for (SpellEffectInfo const& effect : GetEffects())
1695 if (effect.IsEffect() && (effect.IsTargetingArea() || effect.IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) || effect.IsAreaAuraEffect()))
1696 return true;
1697
1698 return false;
1699}
1700
1701// checks if spell targets are selected from area, doesn't include spell effects in check (like area wide auras for example)
1703{
1704 for (SpellEffectInfo const& effect : GetEffects())
1705 if (effect.IsEffect() && effect.IsTargetingArea())
1706 return true;
1707
1708 return false;
1709}
1710
1715
1716bool SpellInfo::NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell) const
1717{
1719 return true;
1720
1721 /*
1722 for (SpellEffectInfo const& effect : GetEffects())
1723 {
1724 if (effect.IsEffect())
1725 {
1726 if (effect.TargetA.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CHANNEL
1727 || effect.TargetB.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CHANNEL)
1728 return true;
1729 }
1730 }
1731 */
1732
1733 if (triggeringSpell->IsChanneled())
1734 {
1735 uint32 mask = 0;
1736 for (SpellEffectInfo const& effect : GetEffects())
1737 {
1738 if (effect.TargetA.GetTarget() != TARGET_UNIT_CASTER && effect.TargetA.GetTarget() != TARGET_DEST_CASTER
1739 && effect.TargetB.GetTarget() != TARGET_UNIT_CASTER && effect.TargetB.GetTarget() != TARGET_DEST_CASTER)
1740 {
1741 mask |= effect.GetProvidedTargetMask();
1742 }
1743 }
1744
1745 if (mask & TARGET_FLAG_UNIT_MASK)
1746 return true;
1747 }
1748
1749 return false;
1750}
1751
1753{
1755}
1756
1758{
1759 if (IsPassive())
1760 return false;
1762 return false;
1763 return true;
1764}
1765
1770
1772{
1773 if (IsPassive())
1774 return false;
1775
1776 // All stance spells. if any better way, change it.
1777 for (SpellEffectInfo const& effect : GetEffects())
1778 {
1779 switch (SpellFamilyName)
1780 {
1782 // Paladin aura Spell
1783 if (effect.Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID)
1784 return false;
1785 break;
1786 case SPELLFAMILY_DRUID:
1787 // Druid form Spell
1788 if (effect.Effect == SPELL_EFFECT_APPLY_AURA &&
1789 effect.ApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT)
1790 return false;
1791 break;
1792 }
1793 }
1794
1795 return true;
1796}
1797
1802
1804{
1805 return IsPassive() || Id == 55849 || Id == 40075 || Id == 44413; // Power Spark, Fel Flak Fire, Incanter's Absorption
1806}
1807
1813
1815{
1817 return true;
1818
1819 SpellCategoryEntry const* category = sSpellCategoryStore.LookupEntry(CategoryId);
1820 return category && category->GetFlags().HasFlag(SpellCategoryFlags::CooldownEventOnLeaveCombat);
1821}
1822
1827
1832
1834{
1836 return true;
1837
1838 for (SpellEffectInfo const& effect : GetEffects())
1839 {
1840 if (!effect.IsEffect())
1841 continue;
1842
1843 if (effect.TargetA.GetObjectType() == TARGET_OBJECT_TYPE_CORPSE || effect.TargetB.GetObjectType() == TARGET_OBJECT_TYPE_CORPSE)
1844 return true;
1845 }
1846
1847 return false;
1848}
1849
1851{
1852 for (SpellEffectInfo const& effect : GetEffects())
1853 {
1854 switch (effect.TargetA.GetCheckType())
1855 {
1856 case TARGET_CHECK_PARTY:
1857 case TARGET_CHECK_RAID:
1859 return true;
1860 default:
1861 break;
1862 }
1863 }
1864
1865 return false;
1866}
1867
1873
1875{
1876 return NegativeEffects.none();
1877}
1878
1880{
1881 return !NegativeEffects.test(effIndex);
1882}
1883
1888
1893
1898
1900{
1901 return (SpellFamilyName == SPELLFAMILY_HUNTER && !(SpellFamilyFlags[1] & 0x10000000)) // for 53352, cannot find better way
1904}
1905
1910
1912{
1913 return !EmpowerStageThresholds.empty();
1914}
1915
1920
1922{
1923 return Speed > 0.0f || LaunchDelay > 0.0f;
1924}
1925
1927{
1928 WeaponAttackType result;
1929 switch (DmgClass)
1930 {
1933 result = OFF_ATTACK;
1934 else
1935 result = BASE_ATTACK;
1936 break;
1939 break;
1940 default:
1941 // Wands
1943 result = RANGED_ATTACK;
1944 else
1945 result = BASE_ATTACK;
1946 break;
1947 }
1948
1949 return result;
1950}
1951
1953{
1954 // item neutral spell
1955 if (EquippedItemClass == -1)
1956 return true;
1957
1958 // item dependent spell
1959 if (item && item->IsFitToSpellRequirements(this))
1960 return true;
1961
1962 return false;
1963}
1964
1965bool SpellInfo::IsAffected(uint32 familyName, flag128 const& familyFlags) const
1966{
1967 if (!familyName)
1968 return true;
1969
1970 if (familyName != SpellFamilyName)
1971 return false;
1972
1973 if (familyFlags && !(familyFlags & SpellFamilyFlags))
1974 return false;
1975
1976 return true;
1977}
1978
1983
1985{
1986 SpellInfo const* affectSpell = sSpellMgr->GetSpellInfo(mod->spellId, Difficulty);
1987 if (!affectSpell)
1988 return false;
1989
1990 switch (mod->type)
1991 {
1992 case SPELLMOD_FLAT:
1993 case SPELLMOD_PCT:
1994 {
1995 // TEMP: dont use IsAffected - !familyName and !familyFlags are not valid options for spell mods
1996 // TODO: investigate if the !familyName and !familyFlags conditions are even valid for all other (nonmod) uses of SpellInfo::IsAffected
1997 if (affectSpell->SpellFamilyName != SpellFamilyName)
1998 return false;
1999
2000 // 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)
2001 // unknown if this is a bug or strange design choice...
2002 FlagsArray<uint32, 4> matched = static_cast<SpellModifierByClassMask const*>(mod)->mask & SpellFamilyFlags;
2003 return std::popcount(matched[0]) + std::popcount(matched[1]) + std::popcount(matched[2]) + std::popcount(matched[3]);
2004 }
2006 return HasLabel(static_cast<SpellFlatModifierByLabel const*>(mod)->value.LabelID) ? 1 : 0;
2007 case SPELLMOD_LABEL_PCT:
2008 return HasLabel(static_cast<SpellPctModifierByLabel const*>(mod)->value.LabelID) ? 1 : 0;
2009 default:
2010 break;
2011 }
2012
2013 return false;
2014}
2015
2017{
2018 switch (Id)
2019 {
2020 case 384669: // Overflowing Maelstrom
2021 return true;
2022 default:
2023 break;
2024 }
2025
2026 return false;
2027}
2028
2029bool SpellInfo::CanPierceImmuneAura(SpellInfo const* auraSpellInfo) const
2030{
2031 // Dispels other auras on immunity, check if this spell makes the unit immune to aura
2033 return true;
2034
2035 return false;
2036}
2037
2038bool SpellInfo::CanDispelAura(SpellInfo const* auraSpellInfo) const
2039{
2040 // These auras (like Divine Shield) can't be dispelled
2041 if (auraSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES))
2042 return false;
2043
2044 return true;
2045}
2046
2048{
2049 // all other single target spells have if it has AttributesEx5
2051 return true;
2052
2053 return false;
2054}
2055
2057{
2058 SpellSpecificType spellSpec1 = GetSpellSpecific();
2059 SpellSpecificType spellSpec2 = spellInfo->GetSpellSpecific();
2060 switch (spellSpec1)
2061 {
2072 return spellSpec1 == spellSpec2;
2074 return spellSpec2 == SPELL_SPECIFIC_FOOD
2075 || spellSpec2 == SPELL_SPECIFIC_FOOD_AND_DRINK;
2077 return spellSpec2 == SPELL_SPECIFIC_DRINK
2078 || spellSpec2 == SPELL_SPECIFIC_FOOD_AND_DRINK;
2080 return spellSpec2 == SPELL_SPECIFIC_FOOD
2081 || spellSpec2 == SPELL_SPECIFIC_DRINK
2082 || spellSpec2 == SPELL_SPECIFIC_FOOD_AND_DRINK;
2083 default:
2084 return false;
2085 }
2086}
2087
2089{
2090 SpellSpecificType spellSpec = GetSpellSpecific();
2091 switch (spellSpec)
2092 {
2100 return spellSpec == spellInfo->GetSpellSpecific();
2101 default:
2102 return false;
2103 }
2104}
2105
2107{
2108 // talents that learn spells can have stance requirements that need ignore
2109 // (this requirement only for client-side stance show in talent description)
2110 /* TODO: 6.x fix this in proper way (probably spell flags/attributes?)
2111 if (GetTalentSpellCost(Id) > 0 && HasEffect(SPELL_EFFECT_LEARN_SPELL))
2112 return SPELL_CAST_OK;*/
2113
2114 //if (HasAttribute(SPELL_ATTR13_ACTIVATES_REQUIRED_SHAPESHIFT))
2115 // return SPELL_CAST_OK;
2116
2117 uint64 stanceMask = (form ? UI64LIT(1) << (form - 1) : 0);
2118
2119 if (stanceMask & StancesNot) // can explicitly not be cast in this stance
2121
2122 if (stanceMask & Stances) // can explicitly be cast in this stance
2123 return SPELL_CAST_OK;
2124
2125 bool actAsShifted = false;
2126 SpellShapeshiftFormEntry const* shapeInfo = nullptr;
2127 if (form > 0)
2128 {
2129 shapeInfo = sSpellShapeshiftFormStore.LookupEntry(form);
2130 if (!shapeInfo)
2131 {
2132 TC_LOG_ERROR("spells", "GetErrorAtShapeshiftedCast: unknown shapeshift {}", form);
2133 return SPELL_CAST_OK;
2134 }
2135 actAsShifted = !shapeInfo->GetFlags().HasFlag(SpellShapeshiftFormFlags::Stance);
2136 }
2137
2138 if (actAsShifted)
2139 {
2140 if (HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFTED) || (shapeInfo && shapeInfo->GetFlags().HasFlag(SpellShapeshiftFormFlags::CanOnlyCastShapeshiftSpells))) // not while shapeshifted
2142 else if (Stances != 0) // needs other shapeshift
2144 }
2145 else
2146 {
2147 // needs shapeshift
2150 }
2151
2152 return SPELL_CAST_OK;
2153}
2154
2155SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player) const
2156{
2157 // normal case
2158 if (RequiredAreasID > 0)
2159 {
2160 bool found = false;
2161 std::vector<uint32> areaGroupMembers = sDB2Manager.GetAreasForGroup(RequiredAreasID);
2162 for (uint32 areaId : areaGroupMembers)
2163 {
2164 if (DB2Manager::IsInArea(area_id, areaId))
2165 {
2166 found = true;
2167 break;
2168 }
2169 }
2170
2171 if (!found)
2173 }
2174
2175 // continent limitation (virtual continent)
2177 {
2179 if (player && player->HasAuraType(SPELL_AURA_MOUNT_RESTRICTIONS))
2180 {
2181 for (AuraEffect const* auraEffect : player->GetAuraEffectsByType(SPELL_AURA_MOUNT_RESTRICTIONS))
2182 mountFlags |= AreaMountFlags(auraEffect->GetMiscValue());
2183 }
2184 else if (AreaTableEntry const* areaTable = sAreaTableStore.LookupEntry(area_id))
2185 mountFlags = areaTable->GetMountFlags();
2186
2187 if (!(mountFlags.HasFlag(AreaMountFlags::AllowFlyingMounts)))
2189
2190 if (player && !ConditionMgr::IsPlayerMeetingCondition(player, 72968)) // Hardcoded PlayerCondition id for attribute check in client
2192 }
2193
2194 // raid instance limitation
2196 {
2197 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2198 if (!mapEntry || mapEntry->IsRaid())
2200 }
2201
2203 {
2204 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2205 if (!mapEntry || !mapEntry->IsDungeon())
2207 }
2208
2210 {
2211 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2212 if (!mapEntry || mapEntry->IsBattleground())
2214 }
2215
2216 // DB base check (if non empty then must fit at least single for allow)
2217 SpellAreaMapBounds saBounds = sSpellMgr->GetSpellAreaMapBounds(Id);
2218 if (saBounds.first != saBounds.second)
2219 {
2220 for (SpellAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
2221 {
2222 if (itr->second.IsFitToRequirements(player, zone_id, area_id))
2223 return SPELL_CAST_OK;
2224 }
2226 }
2227
2228 // bg spell checks
2229 switch (Id)
2230 {
2231 case 23333: // Warsong Flag
2232 case 23335: // Silverwing Flag
2233 return map_id == 489 && player && player->InBattleground() ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
2234 case 2584: // Waiting to Resurrect
2235 case 42792: // Recently Dropped Flag
2236 case 43681: // Inactive
2237 case 44535: // Spirit Heal (mana)
2238 {
2239 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2240 if (!mapEntry)
2242
2243 return zone_id == AREA_WINTERGRASP || (mapEntry->IsBattleground() && player && player->InBattleground()) ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
2244 }
2245 case 44521: // Preparation
2246 {
2247 if (!player)
2249
2250 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2251 if (!mapEntry)
2253
2254 if (!mapEntry->IsBattleground())
2256
2257 Battleground* bg = player->GetBattleground();
2259 }
2260 case 32724: // Gold Team (Alliance)
2261 case 32725: // Green Team (Alliance)
2262 case 35774: // Gold Team (Horde)
2263 case 35775: // Green Team (Horde)
2264 {
2265 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2266 if (!mapEntry)
2268
2269 return mapEntry->IsBattleArena() && player && player->InBattleground() ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
2270 }
2271 case 32727: // Arena Preparation
2272 {
2273 if (!player)
2275
2276 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2277 if (!mapEntry)
2279
2280 if (!mapEntry->IsBattleArena())
2282
2283 Battleground* bg = player->GetBattleground();
2285 }
2286 }
2287
2288 // aura limitations
2289 if (player)
2290 {
2291 for (SpellEffectInfo const& effect : GetEffects())
2292 {
2293 if (!effect.IsAura())
2294 continue;
2295
2296 switch (effect.ApplyAuraName)
2297 {
2299 {
2300 if (SpellShapeshiftFormEntry const* spellShapeshiftForm = sSpellShapeshiftFormStore.LookupEntry(effect.MiscValue))
2301 if (uint32 mountType = spellShapeshiftForm->MountTypeID)
2302 if (!player->GetMountCapability(mountType))
2303 return SPELL_FAILED_NOT_HERE;
2304 break;
2305 }
2306 case SPELL_AURA_MOUNTED:
2307 {
2308 uint32 mountType = effect.MiscValueB;
2309 if (MountEntry const* mountEntry = sDB2Manager.GetMount(Id))
2310 mountType = mountEntry->MountTypeID;
2311 if (mountType && !player->GetMountCapability(mountType))
2312 return SPELL_FAILED_NOT_HERE;
2313 break;
2314 }
2315 default:
2316 break;
2317 }
2318 }
2319 }
2320
2321 return SPELL_CAST_OK;
2322}
2323
2324SpellCastResult SpellInfo::CheckTarget(WorldObject const* caster, WorldObject const* target, bool implicit /*= true*/) const
2325{
2326 if (HasAttribute(SPELL_ATTR1_EXCLUDE_CASTER) && caster == target)
2328
2329 // check visibility - Ignore invisibility/stealth for implicit (area) targets
2330 CanSeeOrDetectExtraArgs const& canSeeOrDetectExtraArgs = CanSeeOrDetectExtraArgs{
2331 .ImplicitDetection = implicit,
2332 .IgnorePhaseShift = HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT),
2335 };
2336 if (!caster->CanSeeOrDetect(target, canSeeOrDetectExtraArgs))
2338
2339 Unit const* unitTarget = target->ToUnit();
2340
2342 {
2343 auto getCreatorOrSelf = [](WorldObject const* obj)
2344 {
2345 ObjectGuid creator = obj->GetCreatorGUID();
2346 if (creator.IsEmpty())
2347 creator = obj->GetGUID();
2348
2349 return creator;
2350 };
2351 if (getCreatorOrSelf(caster) != getCreatorOrSelf(target))
2353 }
2354
2355 // creature/player specific target checks
2356 if (unitTarget)
2357 {
2358 // spells cannot be cast if target has a pet in combat either
2361
2362 // only spells with SPELL_ATTR3_ONLY_TARGET_GHOSTS can target ghosts
2364 {
2367 else
2369 }
2370
2371 if (caster != unitTarget)
2372 {
2373 if (caster->GetTypeId() == TYPEID_PLAYER)
2374 {
2375 // Do not allow these spells to target creatures not tapped by us (Banish, Polymorph, many quest spells)
2377 if (Creature const* targetCreature = unitTarget->ToCreature())
2378 if (targetCreature->hasLootRecipient() && !targetCreature->isTappedBy(caster->ToPlayer()))
2380
2382 {
2383 Creature const* targetCreature = unitTarget->ToCreature();
2384 if (!targetCreature)
2386
2387 if (!targetCreature->CanHaveLoot() || !LootTemplates_Pickpocketing.HaveLootFor(targetCreature->GetCreatureDifficulty()->PickPocketLootID))
2389 }
2390
2391 // Not allow disarm unarmed player
2393 {
2394 if (unitTarget->GetTypeId() == TYPEID_PLAYER)
2395 {
2396 Player const* player = unitTarget->ToPlayer();
2397 if (!player->GetWeaponForAttack(BASE_ATTACK) || !player->IsUseEquipedWeapon(true))
2399 }
2400 else if (!unitTarget->GetVirtualItemId(0))
2402 }
2403 }
2404 }
2405
2407 if (!unitTarget->IsSummon() || unitTarget->ToTempSummon()->GetSummonerGUID() != caster->GetGUID())
2409
2413
2418 }
2419 // corpse specific target checks
2420 else if (Corpse const* corpseTarget = target->ToCorpse())
2421 {
2422 // cannot target bare bones
2423 if (corpseTarget->GetType() == CORPSE_BONES)
2425 // we have to use owner for some checks (aura preventing resurrection for example)
2426 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2427 unitTarget = owner;
2428 // we're not interested in corpses without owner
2429 else
2431 }
2432 // other types of objects - always valid
2433 else return SPELL_CAST_OK;
2434
2435 // corpseOwner and unit specific target checks
2436 if (!unitTarget->IsPlayer())
2437 {
2440
2443 }
2446
2447 if (!IsAllowingDeadTarget() && !unitTarget->IsAlive())
2449
2450 // check this flag only for implicit targets (chain and area), allow to explicitly target units for spells like Shield of Righteousness
2453
2454 // checked in Unit::IsValidAttack/AssistTarget, shouldn't be checked for ENTRY targets
2455 //if (!HasAttribute(SPELL_ATTR6_CAN_TARGET_UNTARGETABLE) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE))
2456 // return SPELL_FAILED_BAD_TARGETS;
2457
2458 if (!CheckTargetCreatureType(unitTarget))
2459 {
2460 if (target->GetTypeId() == TYPEID_PLAYER)
2462 else
2464 }
2465
2466 // check GM mode and GM invisibility - only for player casts (npc casts are controlled by AI) and negative spells
2467 if (unitTarget != caster && (caster->GetAffectingPlayer() || !IsPositive()) && unitTarget->GetTypeId() == TYPEID_PLAYER)
2468 {
2469 if (!unitTarget->ToPlayer()->IsVisible())
2471
2472 if (unitTarget->ToPlayer()->IsGameMaster())
2474 }
2475
2476 // not allow casting on flying player
2479
2480 /* TARGET_UNIT_MASTER gets blocked here for passengers, because the whole idea of this check is to
2481 not allow passengers to be implicitly hit by spells, however this target type should be an exception,
2482 if this is left it kills spells that award kill credit from vehicle to master (few spells),
2483 the use of these 2 covers passenger target check, logically, if vehicle cast this to master it should always hit
2484 him, because it would be it's passenger, there's no such case where this gets to fail legitimacy, this problem
2485 cannot be solved from within the check in other way since target type cannot be called for the spell currently
2486 Spell examples: [ID - 52864 Devour Water, ID - 52862 Devour Wind, ID - 49370 Wyrmrest Defender: Destabilize Azure Dragonshrine Effect] */
2487 if (Unit const* unitCaster = caster->ToUnit())
2488 {
2489 if (!unitCaster->IsVehicle() && !(unitCaster->GetCharmerOrOwner() == target))
2490 {
2491 if (TargetAuraState && !unitTarget->HasAuraState(AuraStateType(TargetAuraState), this, unitCaster))
2493
2494 if (ExcludeTargetAuraState && unitTarget->HasAuraState(AuraStateType(ExcludeTargetAuraState), this, unitCaster))
2496 }
2497 }
2498
2499 if (TargetAuraSpell && !unitTarget->HasAura(TargetAuraSpell))
2501
2504
2505 if (TargetAuraType && !unitTarget->HasAuraType(TargetAuraType))
2507
2510
2514
2516 if (Map* map = caster->GetMap())
2517 if (InstanceMap* iMap = map->ToInstanceMap())
2518 if (InstanceScript* instance = iMap->GetInstanceScript())
2519 if (instance->GetCombatResurrectionCharges() == 0 && instance->IsEncounterInProgress())
2521
2522 return SPELL_CAST_OK;
2523}
2524
2525SpellCastResult SpellInfo::CheckExplicitTarget(WorldObject const* caster, WorldObject const* target, Item const* itemTarget /*= nullptr*/) const
2526{
2527 uint32 neededTargets = RequiredExplicitTargetMask;
2528 if (!target)
2529 {
2531 if (!(neededTargets & TARGET_FLAG_GAMEOBJECT_ITEM) || !itemTarget)
2533 return SPELL_CAST_OK;
2534 }
2535
2536 if (Unit const* unitTarget = target->ToUnit())
2537 {
2539 {
2540 Unit const* unitCaster = caster->ToUnit();
2541 if (neededTargets & TARGET_FLAG_UNIT_ENEMY)
2542 if (caster->IsValidAttackTarget(unitTarget, this))
2543 return SPELL_CAST_OK;
2544 if ((neededTargets & TARGET_FLAG_UNIT_ALLY)
2545 || ((neededTargets & TARGET_FLAG_UNIT_PARTY) && unitCaster && unitCaster->IsInPartyWith(unitTarget))
2546 || ((neededTargets & TARGET_FLAG_UNIT_RAID) && unitCaster && unitCaster->IsInRaidWith(unitTarget)))
2547 if (caster->IsValidAssistTarget(unitTarget, this))
2548 return SPELL_CAST_OK;
2549 if ((neededTargets & TARGET_FLAG_UNIT_MINIPET) && unitCaster)
2550 if (unitTarget->GetGUID() == unitCaster->GetCritterGUID())
2551 return SPELL_CAST_OK;
2552 if ((neededTargets & TARGET_FLAG_UNIT_PASSENGER) && unitCaster)
2553 if (unitTarget->IsOnVehicle(unitCaster))
2554 return SPELL_CAST_OK;
2556 }
2557 }
2558 return SPELL_CAST_OK;
2559}
2560
2562{
2563 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
2564 if (caster->GetTypeId() != TYPEID_PLAYER)
2565 return SPELL_CAST_OK;
2566
2567 Vehicle* vehicle = caster->GetVehicle();
2568 if (vehicle)
2569 {
2570 uint16 checkMask = 0;
2571 for (SpellEffectInfo const& effect : GetEffects())
2572 {
2573 if (effect.IsAura(SPELL_AURA_MOD_SHAPESHIFT))
2574 {
2575 SpellShapeshiftFormEntry const* shapeShiftFromEntry = sSpellShapeshiftFormStore.LookupEntry(effect.MiscValue);
2576 if (shapeShiftFromEntry && (shapeShiftFromEntry->Flags & 1) == 0) // unk flag
2577 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
2578 break;
2579 }
2580 }
2581
2584
2585 if (!checkMask)
2586 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
2587
2588 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(caster);
2590 && (vehicleSeat->Flags & checkMask) != checkMask)
2592
2593 // Can only summon uncontrolled minions/guardians when on controlled vehicle
2595 {
2596 for (SpellEffectInfo const& effect : GetEffects())
2597 {
2598 if (!effect.IsEffect(SPELL_EFFECT_SUMMON))
2599 continue;
2600
2601 SummonPropertiesEntry const* props = sSummonPropertiesStore.LookupEntry(effect.MiscValueB);
2602 if (props && props->Control != SUMMON_CATEGORY_WILD)
2604 }
2605 }
2606 }
2607
2608 return SPELL_CAST_OK;
2609}
2610
2612{
2613 // Curse of Doom & Exorcism: not find another way to fix spell target check :/
2615 {
2616 // not allow cast at player
2617 if (target->GetTypeId() == TYPEID_PLAYER)
2618 return false;
2619 else
2620 return true;
2621 }
2622
2623 // if target is magnet (i.e Grounding Totem) the check is skipped
2624 if (target->IsMagnet())
2625 return true;
2626
2627 uint32 creatureType = target->GetCreatureTypeMask();
2628 return !TargetCreatureType || !creatureType || (creatureType & TargetCreatureType) || target->HasAuraType(SPELL_AURA_IGNORE_SPELL_CREATURE_TYPE_REQUIREMENTS);
2629}
2630
2635
2637{
2638 uint64 mask = 0;
2639 if (Mechanic)
2640 mask |= UI64LIT(1) << Mechanic;
2641
2642 for (SpellEffectInfo const& effect : GetEffects())
2643 if (effect.IsEffect() && effect.Mechanic)
2644 mask |= UI64LIT(1) << effect.Mechanic;
2645
2646 return mask;
2647}
2648
2650{
2651 uint64 mask = 0;
2652 if (Mechanic)
2653 mask |= UI64LIT(1) << Mechanic;
2654
2655 if (GetEffect(effIndex).IsEffect() && GetEffect(effIndex).Mechanic)
2656 mask |= UI64LIT(1) << GetEffect(effIndex).Mechanic;
2657
2658 return mask;
2659}
2660
2662{
2663 uint64 mask = 0;
2664 if (Mechanic)
2665 mask |= UI64LIT(1) << Mechanic;
2666
2667 for (SpellEffectInfo const& effect : GetEffects())
2668 if ((effectMask & (1 << effect.EffectIndex)) && effect.Mechanic)
2669 mask |= UI64LIT(1) << effect.Mechanic;
2670
2671 return mask;
2672}
2673
2675{
2676 if (GetEffect(effIndex).IsEffect() && GetEffect(effIndex).Mechanic)
2677 return GetEffect(effIndex).Mechanic;
2678
2679 if (Mechanic)
2680 return Mechanics(Mechanic);
2681
2682 return MECHANIC_NONE;
2683}
2684
2689
2691{
2692 // If dispel all
2693 if (type == DISPEL_ALL)
2694 return DISPEL_ALL_MASK;
2695 else
2696 return uint32(1 << type);
2697}
2698
2703
2705{
2706 return _auraState;
2707}
2708
2710{
2711 _auraState = [this]()->AuraStateType
2712 {
2713 // Faerie Fire (Feral)
2714 if (GetCategory() == 1133)
2716
2717 // Swiftmend state on Regrowth, Rejuvenation, Wild Growth
2718 if (SpellFamilyName == SPELLFAMILY_DRUID && (SpellFamilyFlags[0] & 0x50 || SpellFamilyFlags[1] & 0x4000000))
2720
2721 // Deadly poison aura state
2722 if (SpellFamilyName == SPELLFAMILY_ROGUE && SpellFamilyFlags[0] & 0x10000)
2724
2725 // Enrage aura state
2726 if (Dispel == DISPEL_ENRAGE)
2727 return AURA_STATE_ENRAGED;
2728
2729 // Bleeding aura state
2731 return AURA_STATE_BLEED;
2732
2734 for (SpellEffectInfo const& effect : GetEffects())
2735 if (effect.IsAura(SPELL_AURA_MOD_STUN) || effect.IsAura(SPELL_AURA_MOD_ROOT) || effect.IsAura(SPELL_AURA_MOD_ROOT_2))
2736 return AURA_STATE_FROZEN;
2737
2738 switch (Id)
2739 {
2740 case 1064: // Dazed
2741 return AURA_STATE_DAZED;
2742 case 32216: // Victorious
2743 return AURA_STATE_VICTORIOUS;
2744 case 71465: // Divine Surge
2745 case 50241: // Evasive Charges
2746 case 81262: // Efflorescence
2748 case 6950: // Faerie Fire
2749 case 9806: // Phantom Strike
2750 case 9991: // Touch of Zanzil
2751 case 13424: // Faerie Fire
2752 case 13752: // Faerie Fire
2753 case 16432: // Plague Mist
2754 case 20656: // Faerie Fire
2755 case 25602: // Faerie Fire
2756 case 32129: // Faerie Fire
2757 case 35325: // Glowing Blood
2758 case 35328: // Lambent Blood
2759 case 35329: // Vibrant Blood
2760 case 35331: // Black Blood
2761 case 49163: // Perpetual Instability
2762 case 65863: // Faerie Fire
2763 case 79559: // Luxscale Light
2764 case 82855: // Dazzling
2765 case 102953: // In the Rumpus
2766 case 127907: // Phosphorescence
2767 case 127913: // Phosphorescence
2768 case 129007: // Zijin Sting
2769 case 130159: // Fae Touch
2770 case 142537: // Spotter Smoke
2771 case 168455: // Spotted!
2772 case 176905: // Super Sticky Glitter Bomb
2773 case 189502: // Marked
2774 case 201785: // Intruder Alert!
2775 case 201786: // Intruder Alert!
2776 case 201935: // Spotted!
2777 case 239233: // Smoke Bomb
2778 case 319400: // Glitter Burst
2779 case 321470: // Dimensional Shifter Mishap
2780 case 331134: // Spotted
2782 default:
2783 break;
2784 }
2785
2787 return AURA_STATE_BANISHED;
2788
2789 return AURA_STATE_NONE;
2790 }();
2791}
2792
2797
2799{
2801 {
2802 switch (SpellFamilyName)
2803 {
2805 {
2806 // Food / Drinks (mostly)
2808 {
2809 bool food = false;
2810 bool drink = false;
2811 for (SpellEffectInfo const& effect : GetEffects())
2812 {
2813 if (!effect.IsAura())
2814 continue;
2815 switch (effect.ApplyAuraName)
2816 {
2817 // Food
2820 food = true;
2821 break;
2822 // Drink
2825 drink = true;
2826 break;
2827 default:
2828 break;
2829 }
2830 }
2831
2832 if (food && drink)
2834 else if (food)
2835 return SPELL_SPECIFIC_FOOD;
2836 else if (drink)
2837 return SPELL_SPECIFIC_DRINK;
2838 }
2839 // scrolls effects
2840 else
2841 {
2842 SpellInfo const* firstRankSpellInfo = GetFirstRankSpell();
2843 switch (firstRankSpellInfo->Id)
2844 {
2845 case 8118: // Strength
2846 case 8099: // Stamina
2847 case 8112: // Spirit
2848 case 8096: // Intellect
2849 case 8115: // Agility
2850 case 8091: // Armor
2851 return SPELL_SPECIFIC_SCROLL;
2852 default:
2853 break;
2854 }
2855 }
2856 break;
2857 }
2858 case SPELLFAMILY_MAGE:
2859 {
2860 // family flags 18(Molten), 25(Frost/Ice), 28(Mage)
2861 if (SpellFamilyFlags[0] & 0x12040000)
2863
2864 // Arcane brillance and Arcane intelect (normal check fails because of flags difference)
2865 if (SpellFamilyFlags[0] & 0x400)
2867
2868 if ((SpellFamilyFlags[0] & 0x1000000) && GetEffect(EFFECT_0).IsAura(SPELL_AURA_MOD_CONFUSE))
2870
2871 break;
2872 }
2874 {
2875 if (Id == 12292) // Death Wish
2877
2878 break;
2879 }
2881 {
2882 // Warlock (Bane of Doom | Bane of Agony | Bane of Havoc)
2883 if (Id == 603 || Id == 980 || Id == 80240)
2884 return SPELL_SPECIFIC_BANE;
2885
2886 // only warlock curses have this
2887 if (Dispel == DISPEL_CURSE)
2888 return SPELL_SPECIFIC_CURSE;
2889
2890 // Warlock (Demon Armor | Demon Skin | Fel Armor)
2891 if (SpellFamilyFlags[1] & 0x20000020 || SpellFamilyFlags[2] & 0x00000010)
2893 break;
2894 }
2895 case SPELLFAMILY_PRIEST:
2896 {
2897 // Divine Spirit and Prayer of Spirit
2898 if (SpellFamilyFlags[0] & 0x20)
2900
2901 break;
2902 }
2903 case SPELLFAMILY_HUNTER:
2904 {
2905 // only hunter stings have this
2906 if (Dispel == DISPEL_POISON)
2907 return SPELL_SPECIFIC_STING;
2908
2909 // only hunter aspects have this (but not all aspects in hunter family)
2910 if (SpellFamilyFlags & flag128(0x00200000, 0x00000000, 0x00001010, 0x00000000))
2911 return SPELL_SPECIFIC_ASPECT;
2912
2913 break;
2914 }
2916 {
2917 // Collection of all the seal family flags. No other paladin spell has any of those.
2918 if (SpellFamilyFlags[1] & 0xA2000800)
2919 return SPELL_SPECIFIC_SEAL;
2920
2921 if (SpellFamilyFlags[0] & 0x00002190)
2922 return SPELL_SPECIFIC_HAND;
2923
2924 // only paladin auras have this (for palaldin class family)
2925 switch (Id)
2926 {
2927 case 465: // Devotion Aura
2928 case 32223: // Crusader Aura
2929 case 183435: // Retribution Aura
2930 case 317920: // Concentration Aura
2931 return SPELL_SPECIFIC_AURA;
2932 default:
2933 break;
2934 }
2935
2936 break;
2937 }
2938 case SPELLFAMILY_SHAMAN:
2939 {
2940 // family flags 10 (Lightning), 42 (Earth), 37 (Water), proc shield from T2 8 pieces bonus
2941 if (SpellFamilyFlags[1] & 0x420
2942 || SpellFamilyFlags[0] & 0x00000400
2943 || Id == 23552)
2945
2946 break;
2947 }
2949 if (Id == 48266 || Id == 48263 || Id == 48265)
2951 break;
2952 }
2953
2954 for (SpellEffectInfo const& effect : GetEffects())
2955 {
2956 if (effect.IsEffect(SPELL_EFFECT_APPLY_AURA))
2957 {
2958 switch (effect.ApplyAuraName)
2959 {
2964 return SPELL_SPECIFIC_CHARM;
2967 if (Id == 30645) // Gas Cloud Tracking
2968 return SPELL_SPECIFIC_NORMAL;
2969 [[fallthrough]];
2973 default:
2974 break;
2975 }
2976 }
2977 }
2978 return SPELL_SPECIFIC_NORMAL;
2979 }();
2980}
2981
2983{
2984 auto diminishingGroupCompute = [this]() -> DiminishingGroup
2985 {
2986 if (IsPositive())
2987 return DIMINISHING_NONE;
2988
2990 return DIMINISHING_TAUNT;
2991
2992 switch (Id)
2993 {
2994 case 20549: // War Stomp (Racial - Tauren)
2995 case 24394: // Intimidation
2996 case 118345: // Pulverize (Primal Earth Elemental)
2997 case 118905: // Static Charge (Capacitor Totem)
2998 return DIMINISHING_STUN;
2999 case 107079: // Quaking Palm
3001 case 155145: // Arcane Torrent (Racial - Blood Elf)
3002 return DIMINISHING_SILENCE;
3003 case 108199: // Gorefiend's Grasp
3004 case 191244: // Sticky Bomb
3006 default:
3007 break;
3008 }
3009
3010 // Explicit Diminishing Groups
3011 switch (SpellFamilyName)
3012 {
3014 // Frost Tomb
3015 if (Id == 48400)
3016 return DIMINISHING_NONE;
3017 // Gnaw
3018 else if (Id == 47481)
3019 return DIMINISHING_STUN;
3020 // ToC Icehowl Arctic Breath
3021 else if (Id == 66689)
3022 return DIMINISHING_NONE;
3023 // Black Plague
3024 else if (Id == 64155)
3025 return DIMINISHING_NONE;
3026 // Screams of the Dead (King Ymiron)
3027 else if (Id == 51750)
3028 return DIMINISHING_NONE;
3029 // Crystallize (Keristrasza heroic)
3030 else if (Id == 48179)
3031 return DIMINISHING_NONE;
3032 break;
3033 case SPELLFAMILY_MAGE:
3034 {
3035 // Frost Nova -- 122
3036 if (SpellFamilyFlags[0] & 0x40)
3037 return DIMINISHING_ROOT;
3038 // Freeze (Water Elemental) -- 33395
3039 if (SpellFamilyFlags[2] & 0x200)
3040 return DIMINISHING_ROOT;
3041
3042 // Dragon's Breath -- 31661
3043 if (SpellFamilyFlags[0] & 0x800000)
3045 // Polymorph -- 118
3046 if (SpellFamilyFlags[0] & 0x1000000)
3048 // Ring of Frost -- 82691
3049 if (SpellFamilyFlags[2] & 0x40)
3051 // Ice Nova -- 157997
3052 if (SpellFamilyFlags[2] & 0x800000)
3054 break;
3055 }
3057 {
3058 // Shockwave -- 132168
3059 if (SpellFamilyFlags[1] & 0x8000)
3060 return DIMINISHING_STUN;
3061 // Storm Bolt -- 132169
3062 if (SpellFamilyFlags[2] & 0x1000)
3063 return DIMINISHING_STUN;
3064
3065 // Intimidating Shout -- 5246
3066 if (SpellFamilyFlags[0] & 0x40000)
3067 return DIMINISHING_DISORIENT;
3068 break;
3069 }
3071 {
3072 // Mortal Coil -- 6789
3073 if (SpellFamilyFlags[0] & 0x80000)
3075 // Banish -- 710
3076 if (SpellFamilyFlags[1] & 0x8000000)
3078
3079 // Fear -- 118699
3080 if (SpellFamilyFlags[1] & 0x400)
3081 return DIMINISHING_DISORIENT;
3082 // Howl of Terror -- 5484
3083 if (SpellFamilyFlags[1] & 0x8)
3084 return DIMINISHING_DISORIENT;
3085
3086 // Shadowfury -- 30283
3087 if (SpellFamilyFlags[1] & 0x1000)
3088 return DIMINISHING_STUN;
3089 // Summon Infernal -- 22703
3090 if (SpellFamilyFlags[0] & 0x1000)
3091 return DIMINISHING_STUN;
3092
3093 // 170995 -- Cripple
3094 if (Id == 170995)
3095 return DIMINISHING_LIMITONLY;
3096 break;
3097 }
3099 {
3100 // Fellash -- 115770
3101 // Whiplash -- 6360
3102 if (SpellFamilyFlags[0] & 0x8000000)
3104
3105 // Mesmerize (Shivarra pet) -- 115268
3106 // Seduction (Succubus pet) -- 6358
3107 if (SpellFamilyFlags[0] & 0x2000000)
3108 return DIMINISHING_DISORIENT;
3109
3110 // Axe Toss (Felguard pet) -- 89766
3111 if (SpellFamilyFlags[1] & 0x4)
3112 return DIMINISHING_STUN;
3113 break;
3114 }
3115 case SPELLFAMILY_DRUID:
3116 {
3117 // Maim -- 22570
3118 if (SpellFamilyFlags[1] & 0x80)
3119 return DIMINISHING_STUN;
3120 // Mighty Bash -- 5211
3121 if (SpellFamilyFlags[0] & 0x2000)
3122 return DIMINISHING_STUN;
3123 // Rake -- 163505 -- no flags on the stun
3124 if (Id == 163505)
3125 return DIMINISHING_STUN;
3126
3127 // Incapacitating Roar -- 99, no flags on the stun, 14
3128 if (SpellFamilyFlags[1] & 0x1)
3130
3131 // Cyclone -- 33786
3132 if (SpellFamilyFlags[1] & 0x20)
3133 return DIMINISHING_DISORIENT;
3134
3135 // Solar Beam -- 81261
3136 if (Id == 81261)
3137 return DIMINISHING_SILENCE;
3138
3139 // Typhoon -- 61391
3140 if (SpellFamilyFlags[1] & 0x1000000)
3142 // Ursol's Vortex -- 118283, no family flags
3143 if (Id == 118283)
3145
3146 // Entangling Roots -- 339
3147 if (SpellFamilyFlags[0] & 0x200)
3148 return DIMINISHING_ROOT;
3149 // Mass Entanglement -- 102359
3150 if (SpellFamilyFlags[2] & 0x4)
3151 return DIMINISHING_ROOT;
3152 break;
3153 }
3154 case SPELLFAMILY_ROGUE:
3155 {
3156 // Between the Eyes -- 199804
3157 if (SpellFamilyFlags[0] & 0x800000)
3158 return DIMINISHING_STUN;
3159 // Cheap Shot -- 1833
3160 if (SpellFamilyFlags[0] & 0x400)
3161 return DIMINISHING_STUN;
3162 // Kidney Shot -- 408
3163 if (SpellFamilyFlags[0] & 0x200000)
3164 return DIMINISHING_STUN;
3165
3166 // Gouge -- 1776
3167 if (SpellFamilyFlags[0] & 0x8)
3169 // Sap -- 6770
3170 if (SpellFamilyFlags[0] & 0x80)
3172
3173 // Blind -- 2094
3174 if (SpellFamilyFlags[0] & 0x1000000)
3175 return DIMINISHING_DISORIENT;
3176
3177 // Garrote -- 1330
3178 if (SpellFamilyFlags[1] & 0x20000000)
3179 return DIMINISHING_SILENCE;
3180 break;
3181 }
3182 case SPELLFAMILY_HUNTER:
3183 {
3184 // Charge (Tenacity pet) -- 53148, no flags
3185 if (Id == 53148)
3186 return DIMINISHING_ROOT;
3187 // Ranger's Net -- 200108
3188 // Tracker's Net -- 212638
3189 if (Id == 200108 || Id == 212638)
3190 return DIMINISHING_ROOT;
3191
3192 // Binding Shot -- 117526, no flags
3193 if (Id == 117526)
3194 return DIMINISHING_STUN;
3195
3196 // Freezing Trap -- 3355
3197 if (SpellFamilyFlags[0] & 0x8)
3199 // Wyvern Sting -- 19386
3200 if (SpellFamilyFlags[1] & 0x1000)
3202
3203 // Bursting Shot -- 224729
3204 if (SpellFamilyFlags[2] & 0x40)
3205 return DIMINISHING_DISORIENT;
3206 // Scatter Shot -- 213691
3207 if (SpellFamilyFlags[2] & 0x8000)
3208 return DIMINISHING_DISORIENT;
3209
3210 // Spider Sting -- 202933
3211 if (Id == 202933)
3212 return DIMINISHING_SILENCE;
3213 break;
3214 }
3216 {
3217 // Repentance -- 20066
3218 if (SpellFamilyFlags[0] & 0x4)
3220
3221 // Blinding Light -- 105421
3222 if (Id == 105421)
3223 return DIMINISHING_DISORIENT;
3224
3225 // Avenger's Shield -- 31935
3226 if (SpellFamilyFlags[0] & 0x4000)
3227 return DIMINISHING_SILENCE;
3228
3229 // Hammer of Justice -- 853
3230 if (SpellFamilyFlags[0] & 0x800)
3231 return DIMINISHING_STUN;
3232 break;
3233 }
3234 case SPELLFAMILY_SHAMAN:
3235 {
3236 // Hex -- 51514
3237 // Hex -- 196942 (Voodoo Totem)
3238 if (SpellFamilyFlags[1] & 0x8000)
3240
3241 // Thunderstorm -- 51490
3242 if (SpellFamilyFlags[1] & 0x2000)
3244
3245 // Earthgrab Totem -- 64695
3246 if (SpellFamilyFlags[2] & 0x4000)
3247 return DIMINISHING_ROOT;
3248
3249 // Lightning Lasso -- 204437
3250 if (SpellFamilyFlags[3] & 0x2000000)
3251 return DIMINISHING_STUN;
3252 break;
3253 }
3255 {
3256 // Chains of Ice -- 96294
3257 if (Id == 96294)
3258 return DIMINISHING_ROOT;
3259
3260 // Blinding Sleet -- 207167
3261 if (Id == 207167)
3262 return DIMINISHING_DISORIENT;
3263
3264 // Strangulate -- 47476
3265 if (SpellFamilyFlags[0] & 0x200)
3266 return DIMINISHING_SILENCE;
3267
3268 // Asphyxiate -- 108194
3269 if (SpellFamilyFlags[2] & 0x100000)
3270 return DIMINISHING_STUN;
3271 // Gnaw (Ghoul) -- 91800, no flags
3272 if (Id == 91800)
3273 return DIMINISHING_STUN;
3274 // Monstrous Blow (Ghoul w/ Dark Transformation active) -- 91797
3275 if (Id == 91797)
3276 return DIMINISHING_STUN;
3277 // Winter is Coming -- 207171
3278 if (Id == 207171)
3279 return DIMINISHING_STUN;
3280 break;
3281 }
3282 case SPELLFAMILY_PRIEST:
3283 {
3284 // Holy Word: Chastise -- 200200
3285 if (SpellFamilyFlags[2] & 0x20 && GetSpellVisual() == 52021)
3286 return DIMINISHING_STUN;
3287 // Mind Bomb -- 226943
3288 if (Id == 226943)
3289 return DIMINISHING_STUN;
3290
3291 // Mind Control -- 605
3292 if (SpellFamilyFlags[0] & 0x20000 && GetSpellVisual() == 39068)
3294 // Holy Word: Chastise -- 200196
3295 if (SpellFamilyFlags[2] & 0x20 && GetSpellVisual() == 52019)
3297
3298 // Psychic Scream -- 8122
3299 if (SpellFamilyFlags[0] & 0x10000)
3300 return DIMINISHING_DISORIENT;
3301
3302 // Silence -- 15487
3303 if (SpellFamilyFlags[1] & 0x200000 && GetSpellVisual() == 39025)
3304 return DIMINISHING_SILENCE;
3305
3306 // Shining Force -- 204263
3307 if (Id == 204263)
3309 break;
3310 }
3311 case SPELLFAMILY_MONK:
3312 {
3313 // Disable -- 116706, no flags
3314 if (Id == 116706)
3315 return DIMINISHING_ROOT;
3316
3317 // Fists of Fury -- 120086
3318 if (SpellFamilyFlags[1] & 0x800000 && !(SpellFamilyFlags[2] & 0x8))
3319 return DIMINISHING_STUN;
3320 // Leg Sweep -- 119381
3321 if (SpellFamilyFlags[1] & 0x200)
3322 return DIMINISHING_STUN;
3323
3324 // Incendiary Breath (honor talent) -- 202274, no flags
3325 if (Id == 202274)
3327 // Paralysis -- 115078
3328 if (SpellFamilyFlags[2] & 0x800000)
3330
3331 // Song of Chi-Ji -- 198909
3332 if (Id == 198909)
3333 return DIMINISHING_DISORIENT;
3334 break;
3335 }
3337 {
3338 switch (Id)
3339 {
3340 case 179057: // Chaos Nova
3341 case 211881: // Fel Eruption
3342 case 200166: // Metamorphosis
3343 case 205630: // Illidan's Grasp
3344 return DIMINISHING_STUN;
3345 case 217832: // Imprison
3346 case 221527: // Imprison
3348 default:
3349 break;
3350 }
3351 break;
3352 }
3353 default:
3354 break;
3355 }
3356
3357 return DIMINISHING_NONE;
3358 };
3359
3360 auto diminishingTypeCompute = [](DiminishingGroup group) -> DiminishingReturnsType
3361 {
3362 switch (group)
3363 {
3364 case DIMINISHING_TAUNT:
3365 case DIMINISHING_STUN:
3366 return DRTYPE_ALL;
3368 case DIMINISHING_NONE:
3369 return DRTYPE_NONE;
3370 default:
3371 return DRTYPE_PLAYER;
3372 }
3373 };
3374
3375 auto diminishingMaxLevelCompute = [](DiminishingGroup group) -> DiminishingLevels
3376 {
3377 switch (group)
3378 {
3379 case DIMINISHING_TAUNT:
3382 return DIMINISHING_LEVEL_2;
3383 default:
3385 }
3386 };
3387
3388 auto diminishingLimitDurationCompute = [this]() -> int32
3389 {
3390 // Explicit diminishing duration
3391 switch (SpellFamilyName)
3392 {
3393 case SPELLFAMILY_MAGE:
3394 {
3395 // Dragon's Breath - 3 seconds in PvP
3396 if (SpellFamilyFlags[0] & 0x800000)
3397 return 3 * IN_MILLISECONDS;
3398 break;
3399 }
3401 {
3402 // Cripple - 4 seconds in PvP
3403 if (Id == 170995)
3404 return 4 * IN_MILLISECONDS;
3405 break;
3406 }
3407 case SPELLFAMILY_HUNTER:
3408 {
3409 // Binding Shot - 3 seconds in PvP
3410 if (Id == 117526)
3411 return 3 * IN_MILLISECONDS;
3412
3413 // Wyvern Sting - 6 seconds in PvP
3414 if (SpellFamilyFlags[1] & 0x1000)
3415 return 6 * IN_MILLISECONDS;
3416 break;
3417 }
3418 case SPELLFAMILY_MONK:
3419 {
3420 // Paralysis - 4 seconds in PvP regardless of if they are facing you
3421 if (SpellFamilyFlags[2] & 0x800000)
3422 return 4 * IN_MILLISECONDS;
3423 break;
3424 }
3426 {
3427 switch (Id)
3428 {
3429 case 217832: // Imprison
3430 case 221527: // Imprison
3431 return 4 * IN_MILLISECONDS;
3432 default:
3433 break;
3434 }
3435 break;
3436 }
3437 default:
3438 break;
3439 }
3440
3441 return 8 * IN_MILLISECONDS;
3442 };
3443
3444 SpellDiminishInfo diminishInfo;
3445 diminishInfo.DiminishGroup = diminishingGroupCompute();
3446 diminishInfo.DiminishReturnType = diminishingTypeCompute(diminishInfo.DiminishGroup);
3447 diminishInfo.DiminishMaxLevel = diminishingMaxLevelCompute(diminishInfo.DiminishGroup);
3448 diminishInfo.DiminishDurationLimit = diminishingLimitDurationCompute();
3449
3450 _diminishInfo = diminishInfo;
3451}
3452
3457
3462
3467
3472
3474{
3475 std::unique_ptr<SpellEffectInfo::ImmunityInfo> workBuffer = std::make_unique<SpellEffectInfo::ImmunityInfo>();
3476
3477 for (SpellEffectInfo& effect : _effects)
3478 {
3479 uint32 schoolImmunityMask = 0;
3480 uint32 applyHarmfulAuraImmunityMask = 0;
3481 uint64 mechanicImmunityMask = 0;
3482 uint32 dispelImmunityMask = 0;
3483 uint32 damageImmunityMask = 0;
3484 uint8 otherImmunityMask = 0;
3485
3486 int32 miscVal = effect.MiscValue;
3487
3488 SpellEffectInfo::ImmunityInfo& immuneInfo = *workBuffer;
3489
3490 switch (effect.ApplyAuraName)
3491 {
3493 {
3494 if (CreatureImmunities const* creatureImmunities = SpellMgr::GetCreatureImmunities(miscVal))
3495 {
3496 schoolImmunityMask |= creatureImmunities->School.to_ulong();
3497 dispelImmunityMask |= creatureImmunities->DispelType.to_ulong();
3498 mechanicImmunityMask |= creatureImmunities->Mechanic.to_ullong();
3499 otherImmunityMask |= creatureImmunities->Other.AsUnderlyingType();
3500 for (SpellEffectName effectType : creatureImmunities->Effect)
3501 immuneInfo.SpellEffectImmune.insert(effectType);
3502 for (AuraType aura : creatureImmunities->Aura)
3503 immuneInfo.AuraTypeImmune.insert(aura);
3504 }
3505 break;
3506 }
3508 {
3509 switch (Id)
3510 {
3511 case 42292: // PvP trinket
3512 case 59752: // Every Man for Himself
3515 break;
3516 case 34471: // The Beast Within
3517 case 19574: // Bestial Wrath
3518 case 46227: // Medallion of Immunity
3519 case 53490: // Bullheaded
3520 case 65547: // PvP Trinket
3521 case 134946: // Supremacy of the Alliance
3522 case 134956: // Supremacy of the Horde
3523 case 195710: // Honorable Medallion
3524 case 208683: // Gladiator's Medallion
3526 break;
3527 case 54508: // Demonic Empowerment
3528 mechanicImmunityMask |= (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT) | (1 << MECHANIC_STUN);
3529 break;
3530 default:
3531 if (miscVal < 1)
3532 break;
3533
3534 mechanicImmunityMask |= UI64LIT(1) << miscVal;
3535 break;
3536 }
3537 break;
3538 }
3540 {
3541 immuneInfo.SpellEffectImmune.insert(static_cast<SpellEffectName>(miscVal));
3542 break;
3543 }
3545 {
3546 immuneInfo.AuraTypeImmune.insert(static_cast<AuraType>(miscVal));
3547 break;
3548 }
3550 {
3551 schoolImmunityMask |= uint32(miscVal);
3552 break;
3553 }
3555 {
3556 applyHarmfulAuraImmunityMask |= uint32(miscVal);
3557 break;
3558 }
3560 {
3561 damageImmunityMask |= uint32(miscVal);
3562 break;
3563 }
3565 {
3566 dispelImmunityMask = 1u << miscVal;
3567 break;
3568 }
3569 default:
3570 break;
3571 }
3572
3573 immuneInfo.SchoolImmuneMask = schoolImmunityMask;
3574 immuneInfo.ApplyHarmfulAuraImmuneMask = applyHarmfulAuraImmunityMask;
3575 immuneInfo.MechanicImmuneMask = mechanicImmunityMask;
3576 immuneInfo.DispelImmuneMask = dispelImmunityMask;
3577 immuneInfo.DamageSchoolMask = damageImmunityMask;
3578 immuneInfo.OtherImmuneMask = otherImmunityMask;
3579
3580 immuneInfo.AuraTypeImmune.shrink_to_fit();
3581 immuneInfo.SpellEffectImmune.shrink_to_fit();
3582
3583 if (immuneInfo.SchoolImmuneMask
3584 || immuneInfo.ApplyHarmfulAuraImmuneMask
3585 || immuneInfo.MechanicImmuneMask
3586 || immuneInfo.DispelImmuneMask
3587 || immuneInfo.DamageSchoolMask
3588 || immuneInfo.OtherImmuneMask
3589 || !immuneInfo.AuraTypeImmune.empty()
3590 || !immuneInfo.SpellEffectImmune.empty())
3591 {
3592 effect._immunityInfo = std::move(workBuffer);
3593 workBuffer = std::make_unique<SpellEffectInfo::ImmunityInfo>();
3594 }
3595
3597 }
3598
3600 {
3601 switch (Id)
3602 {
3603 case 22812: // Barkskin
3604 case 47585: // Dispersion
3606 (1 << MECHANIC_STUN) |
3607 (1 << MECHANIC_FREEZE) |
3608 (1 << MECHANIC_KNOCKOUT) |
3609 (1 << MECHANIC_SLEEP);
3610 break;
3611 case 49039: // Lichborne, don't allow normal stuns
3612 break;
3613 default:
3615 break;
3616 }
3617 }
3618
3621
3623 {
3624 switch (Id)
3625 {
3626 case 22812: // Barkskin
3627 case 47585: // Dispersion
3629 break;
3630 default:
3632 break;
3633 }
3634 }
3635}
3636
3637void SpellInfo::_LoadSqrtTargetLimit(int32 maxTargets, int32 numNonDiminishedTargets,
3638 Optional<uint32> maxTargetsValueHolderSpell, Optional<SpellEffIndex> maxTargetsValueHolderEffect,
3639 Optional<uint32> numNonDiminishedTargetsValueHolderSpell, Optional<SpellEffIndex> numNonDiminishedTargetsValueHolderEffect)
3640{
3641 SqrtDamageAndHealingDiminishing.MaxTargets = maxTargets;
3642 SqrtDamageAndHealingDiminishing.NumNonDiminishedTargets = numNonDiminishedTargets;
3643
3644 if (maxTargetsValueHolderEffect)
3645 {
3646 SpellInfo const* maxTargetValueHolder = this;
3647 if (maxTargetsValueHolderSpell)
3648 maxTargetValueHolder = sSpellMgr->GetSpellInfo(*maxTargetsValueHolderSpell, Difficulty);
3649
3650 if (!maxTargetValueHolder)
3651 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(maxTargets): Spell {} does not exist", *maxTargetsValueHolderSpell);
3652 else if (*maxTargetsValueHolderEffect >= maxTargetValueHolder->GetEffects().size())
3653 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(maxTargets): Spell {} does not have effect {}",
3654 maxTargetValueHolder->Id, AsUnderlyingType(*maxTargetsValueHolderEffect));
3655 else
3656 {
3657 SpellEffectInfo const& valueHolder = maxTargetValueHolder->GetEffect(*maxTargetsValueHolderEffect);
3658 int32 expectedValue = int32(valueHolder.CalcBaseValue(nullptr, nullptr, 0, -1));
3659 if (maxTargets != expectedValue)
3660 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(maxTargets): Spell {} has different value in effect {} than expected, recheck target caps (expected {}, got {})",
3661 maxTargetValueHolder->Id, AsUnderlyingType(*maxTargetsValueHolderEffect), maxTargets, expectedValue);
3662 }
3663 }
3664
3665 if (numNonDiminishedTargetsValueHolderEffect)
3666 {
3667 SpellInfo const* numNonDiminishedTargetsValueHolder = this;
3668 if (numNonDiminishedTargetsValueHolderSpell)
3669 numNonDiminishedTargetsValueHolder = sSpellMgr->GetSpellInfo(*numNonDiminishedTargetsValueHolderSpell, Difficulty);
3670
3671 if (!numNonDiminishedTargetsValueHolder)
3672 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(numNonDiminishedTargets): Spell {} does not exist", *numNonDiminishedTargetsValueHolderSpell);
3673 else if (*numNonDiminishedTargetsValueHolderEffect >= numNonDiminishedTargetsValueHolder->GetEffects().size())
3674 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(numNonDiminishedTargets): Spell {} does not have effect {}",
3675 numNonDiminishedTargetsValueHolder->Id, AsUnderlyingType(*numNonDiminishedTargetsValueHolderEffect));
3676 else
3677 {
3678 SpellEffectInfo const& valueHolder = numNonDiminishedTargetsValueHolder->GetEffect(*numNonDiminishedTargetsValueHolderEffect);
3679 int32 expectedValue = int32(valueHolder.CalcBaseValue(nullptr, nullptr, 0, -1));
3680 if (numNonDiminishedTargets != expectedValue)
3681 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(numNonDiminishedTargets): Spell {} has different value in effect {} than expected, recheck target caps (expected {}, got {})",
3682 numNonDiminishedTargetsValueHolder->Id, AsUnderlyingType(*numNonDiminishedTargetsValueHolderEffect), numNonDiminishedTargets, expectedValue);
3683 }
3684 }
3685}
3686
3687void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& spellEffectInfo, bool apply) const
3688{
3689 SpellEffectInfo::ImmunityInfo const* immuneInfo = spellEffectInfo.GetImmunityInfo();
3690 if (!immuneInfo)
3691 return;
3692
3693 if (uint32 schoolImmunity = immuneInfo->SchoolImmuneMask)
3694 {
3695 target->ApplySpellImmune(Id, IMMUNITY_SCHOOL, schoolImmunity, apply);
3696
3698 {
3699 target->RemoveAppliedAuras([this, schoolImmunity](AuraApplication const* aurApp) -> bool
3700 {
3701 SpellInfo const* auraSpellInfo = aurApp->GetBase()->GetSpellInfo();
3702 if (auraSpellInfo->Id == Id) // Don't remove self
3703 return false;
3704 if (auraSpellInfo->IsPassive()) // Don't remove passive auras
3705 return false;
3706 if (!(auraSpellInfo->GetSchoolMask() & schoolImmunity)) // Check for school mask
3707 return false;
3708 if (!CanDispelAura(auraSpellInfo))
3709 return false;
3710 if (aurApp->IsPositive() && !HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS)) // Check spell vs aura possitivity
3711 return false;
3712 return true;
3713 });
3714 }
3715
3716 if (apply && schoolImmunity & SPELL_SCHOOL_MASK_NORMAL)
3718 }
3719
3720 if (uint64 mechanicImmunity = immuneInfo->MechanicImmuneMask)
3721 {
3722 for (uint32 i = 0; i < MAX_MECHANIC; ++i)
3723 if (mechanicImmunity & (UI64LIT(1) << i))
3724 target->ApplySpellImmune(Id, IMMUNITY_MECHANIC, i, apply);
3725
3727 {
3728 if (apply)
3729 target->RemoveAurasWithMechanic(mechanicImmunity, AURA_REMOVE_BY_DEFAULT, Id);
3730 else
3731 {
3732 std::vector<Aura*> aurasToUpdateTargets;
3733 target->RemoveAppliedAuras([mechanicImmunity, &aurasToUpdateTargets](AuraApplication const* aurApp)
3734 {
3735 Aura* aura = aurApp->GetBase();
3736 if (aura->GetSpellInfo()->GetAllEffectsMechanicMask() & mechanicImmunity)
3737 aurasToUpdateTargets.push_back(aura);
3738
3739 // only update targets, don't remove anything
3740 return false;
3741 });
3742
3743 for (Aura* aura : aurasToUpdateTargets)
3744 aura->UpdateTargetMap(aura->GetCaster());
3745 }
3746 }
3747 }
3748
3749 if (uint32 dispelImmunity = immuneInfo->DispelImmuneMask)
3750 {
3751 for (uint32 i = 0; i < DISPEL_MAX; ++i)
3752 if (dispelImmunity & (1 << i))
3753 target->ApplySpellImmune(Id, IMMUNITY_DISPEL, i, apply);
3754
3756 {
3757 target->RemoveAppliedAuras([dispelImmunity](AuraApplication const* aurApp) -> bool
3758 {
3759 SpellInfo const* spellInfo = aurApp->GetBase()->GetSpellInfo();
3760 uint32 dispelMask = spellInfo->GetDispelMask();
3761 if ((dispelMask & dispelImmunity) == dispelMask)
3762 return true;
3763
3764 return false;
3765 });
3766 }
3767 }
3768
3769 if (uint32 damageImmunity = immuneInfo->DamageSchoolMask)
3770 {
3771 target->ApplySpellImmune(Id, IMMUNITY_DAMAGE, damageImmunity, apply);
3772
3773 if (apply && damageImmunity & SPELL_SCHOOL_MASK_NORMAL)
3775 }
3776
3777 for (AuraType auraType : immuneInfo->AuraTypeImmune)
3778 {
3779 target->ApplySpellImmune(Id, IMMUNITY_STATE, auraType, apply);
3781 target->RemoveAurasByType(auraType, [this](AuraApplication const* aurApp) -> bool
3782 {
3783 return CanDispelAura(aurApp->GetBase()->GetSpellInfo());
3784 });
3785 }
3786
3787 for (SpellEffectName effectType : immuneInfo->SpellEffectImmune)
3788 target->ApplySpellImmune(Id, IMMUNITY_EFFECT, effectType, apply);
3789
3790 if (uint8 otherImmuneMask = immuneInfo->OtherImmuneMask)
3791 target->ApplySpellImmune(Id, IMMUNITY_OTHER, otherImmuneMask, apply);
3792}
3793
3795{
3796 if (!auraSpellInfo)
3797 return false;
3798
3799 for (SpellEffectInfo const& effectInfo : _effects)
3800 {
3801 if (!effectInfo.IsEffect())
3802 continue;
3803
3804 SpellEffectInfo::ImmunityInfo const* immuneInfo = effectInfo.GetImmunityInfo();
3805 if (!immuneInfo)
3806 continue;
3807
3809 if (uint32 schoolImmunity = immuneInfo->SchoolImmuneMask)
3810 if ((auraSpellInfo->SchoolMask & schoolImmunity) != 0)
3811 return true;
3812
3813 if (uint64 mechanicImmunity = immuneInfo->MechanicImmuneMask)
3814 if ((mechanicImmunity & (UI64LIT(1) << auraSpellInfo->Mechanic)) != 0)
3815 return true;
3816
3817 if (uint32 dispelImmunity = immuneInfo->DispelImmuneMask)
3818 if (auraSpellInfo->Dispel == dispelImmunity)
3819 return true;
3820
3821 bool immuneToAllEffects = true;
3822 for (SpellEffectInfo const& auraSpellEffectInfo : auraSpellInfo->GetEffects())
3823 {
3824 if (!auraSpellEffectInfo.IsAura())
3825 continue;
3826
3827 if (uint64 mechanicImmunity = immuneInfo->MechanicImmuneMask)
3828 if ((mechanicImmunity & (UI64LIT(1) << auraSpellEffectInfo.Mechanic)) != 0)
3829 continue;
3830
3831 if (AuraType auraName = auraSpellEffectInfo.ApplyAuraName)
3832 {
3833 if (immuneInfo->AuraTypeImmune.find(auraName) != immuneInfo->AuraTypeImmune.end())
3834 continue;
3835
3836 if (!auraSpellInfo->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES) && !auraSpellInfo->IsPositiveEffect(auraSpellEffectInfo.EffectIndex))
3837 if (uint32 applyHarmfulAuraImmunityMask = immuneInfo->ApplyHarmfulAuraImmuneMask)
3838 if ((auraSpellInfo->GetSchoolMask() & applyHarmfulAuraImmunityMask) != 0)
3839 continue;
3840 }
3841
3842 immuneToAllEffects = false;
3843 }
3844
3845 if (immuneToAllEffects)
3846 return true;
3847 }
3848
3849 return false;
3850}
3851
3852bool SpellInfo::CanSpellEffectProvideImmunityAgainstAuraEffect(SpellEffectInfo const& immunityEffectInfo, SpellInfo const* auraSpellInfo, SpellEffectInfo const& auraEffectInfo) const
3853{
3854 SpellEffectInfo::ImmunityInfo const* immuneInfo = immunityEffectInfo.GetImmunityInfo();
3855 if (!immuneInfo)
3856 return false;
3857
3859 {
3860 if (uint32 schoolImmunity = immuneInfo->SchoolImmuneMask)
3861 if ((auraSpellInfo->SchoolMask & schoolImmunity) != 0)
3862 return true;
3863
3864 if (uint32 applyHarmfulAuraImmunityMask = immuneInfo->ApplyHarmfulAuraImmuneMask)
3865 if ((auraSpellInfo->GetSchoolMask() & applyHarmfulAuraImmunityMask) != 0)
3866 return true;
3867 }
3868
3869 if (uint64 mechanicImmunity = immuneInfo->MechanicImmuneMask)
3870 {
3871 if ((mechanicImmunity & (UI64LIT(1) << auraSpellInfo->Mechanic)) != 0)
3872 return true;
3873 if ((mechanicImmunity & (UI64LIT(1) << auraEffectInfo.Mechanic)) != 0)
3874 return true;
3875 }
3876
3877 if (uint32 dispelImmunity = immuneInfo->DispelImmuneMask)
3878 if (auraSpellInfo->Dispel == dispelImmunity)
3879 return true;
3880
3881 if (immuneInfo->AuraTypeImmune.find(auraEffectInfo.ApplyAuraName) != immuneInfo->AuraTypeImmune.end())
3882 return true;
3883
3884 return false;
3885}
3886
3887// based on client Spell_C::CancelsAuraEffect
3889{
3891 return false;
3892
3894 return false;
3895
3897 return false;
3898
3899 for (SpellEffectInfo const& effect : GetEffects())
3901 return true;
3902
3903 return false;
3904}
3905
3910
3912{
3913 uint64 casterMechanicImmunityMask = caster->GetMechanicImmunityMask();
3914 uint64 mechanicImmunityMask = 0;
3915
3916 if (CanBeInterrupted(nullptr, caster, true))
3917 {
3918 if (casterMechanicImmunityMask & (1 << MECHANIC_SILENCE))
3919 mechanicImmunityMask |= (1 << MECHANIC_SILENCE);
3920
3921 if (casterMechanicImmunityMask & (1 << MECHANIC_INTERRUPT))
3922 mechanicImmunityMask |= (1 << MECHANIC_INTERRUPT);
3923 }
3924
3925 return mechanicImmunityMask;
3926}
3927
3928float SpellInfo::GetMinRange(bool positive /*= false*/) const
3929{
3930 if (!RangeEntry)
3931 return 0.0f;
3932 return RangeEntry->RangeMin[positive ? 1 : 0];
3933}
3934
3935float SpellInfo::GetMaxRange(bool positive /*= false*/, WorldObject const* caster /*= nullptr*/, Spell* spell /*= nullptr*/) const
3936{
3937 if (!RangeEntry)
3938 return 0.0f;
3939 float range = RangeEntry->RangeMax[positive ? 1 : 0];
3940 if (caster)
3941 if (Player* modOwner = caster->GetSpellModOwner())
3942 modOwner->ApplySpellMod(this, SpellModOp::Range, range, spell);
3943
3944 return range;
3945}
3946
3947SpellRange SpellInfo::GetMinMaxRange(bool positive, WorldObject const* caster, Spell* spell) const
3948{
3949 SpellRange range;
3950 if (!RangeEntry)
3951 return range;
3952
3953 range = { .Min = RangeEntry->RangeMin[positive ? 1 : 0], .Max = RangeEntry->RangeMax[positive ? 1 : 0] };
3954 if (caster)
3955 if (Player* modOwner = caster->GetSpellModOwner())
3956 modOwner->ApplySpellMod(this, SpellModOp::Range, range.Max, spell);
3957
3958 return range;
3959}
3960
3961int32 SpellInfo::CalcDuration(WorldObject const* caster /*= nullptr*/) const
3962{
3963 int32 duration = GetDuration();
3964
3965 if (caster)
3966 if (Player* modOwner = caster->GetSpellModOwner())
3967 modOwner->ApplySpellMod(this, SpellModOp::Duration, duration);
3968
3969 return duration;
3970}
3971
3973{
3974 if (!DurationEntry)
3975 return IsPassive() ? -1 : 0;
3976 return (DurationEntry->Duration == -1) ? -1 : abs(DurationEntry->Duration);
3977}
3978
3980{
3981 if (!DurationEntry)
3982 return IsPassive() ? -1 : 0;
3983 return (DurationEntry->MaxDuration == -1) ? -1 : abs(DurationEntry->MaxDuration);
3984}
3985
3986uint32 SpellInfo::CalcCastTime(Spell* spell /*= nullptr*/) const
3987{
3988 int32 castTime = 0;
3989 if (CastTimeEntry)
3990 castTime = std::max(CastTimeEntry->Base, CastTimeEntry->Minimum);
3991
3992 if (castTime <= 0)
3993 return 0;
3994
3995 if (spell)
3996 spell->GetCaster()->ModSpellCastTime(this, castTime, spell);
3997
3999 castTime += 500;
4000
4001 return (castTime > 0) ? uint32(castTime) : 0;
4002}
4003
4008
4009Optional<SpellPowerCost> SpellInfo::CalcPowerCost(Powers powerType, bool optionalCost, WorldObject const* caster, SpellSchoolMask schoolMask, Spell* spell /*= nullptr*/) const
4010{
4011 // gameobject casts don't use power
4012 Unit const* unitCaster = caster->ToUnit();
4013 if (!unitCaster)
4014 return {};
4015
4016 auto itr = std::find_if(PowerCosts.cbegin(), PowerCosts.cend(), [powerType](SpellPowerEntry const* spellPowerEntry)
4017 {
4018 return spellPowerEntry && spellPowerEntry->PowerType == powerType;
4019 });
4020 if (itr == PowerCosts.cend())
4021 return {};
4022
4023 return CalcPowerCost(*itr, optionalCost, caster, schoolMask, spell);
4024}
4025
4026Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power, bool optionalCost, WorldObject const* caster, SpellSchoolMask schoolMask, Spell* spell /*= nullptr*/) const
4027{
4028 // gameobject casts don't use power
4029 Unit const* unitCaster = caster->ToUnit();
4030 if (!unitCaster)
4031 return {};
4032
4033 if (power->RequiredAuraSpellID && !unitCaster->HasAura(power->RequiredAuraSpellID))
4034 return {};
4035
4036 // Spell drain all exist power on cast (Only paladin lay of Hands)
4038 {
4039 if (optionalCost)
4040 return {};
4041
4042 // If power type - health drain all
4043 if (power->PowerType == POWER_HEALTH)
4044 return SpellPowerCost{ .Power = POWER_HEALTH, .Amount = int32(unitCaster->GetHealth()) };
4045
4046 // Else drain all power
4047 if (power->PowerType < MAX_POWERS)
4048 return SpellPowerCost{ .Power = Powers(power->PowerType), .Amount = unitCaster->GetPower(Powers(power->PowerType)) };
4049
4050 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type '{}' in spell {}", power->PowerType, Id);
4051 return {};
4052 }
4053
4054 // Base powerCost
4055 int32 powerCost = 0;
4056 if (!optionalCost)
4057 {
4058 powerCost = power->ManaCost;
4059 // PCT cost from total amount
4060 if (power->PowerCostPct)
4061 {
4062 switch (power->PowerType)
4063 {
4064 // health as power used
4065 case POWER_HEALTH:
4066 if (G3D::fuzzyEq(power->PowerCostPct, 0.0f))
4067 powerCost += int32(CalculatePct(unitCaster->GetMaxHealth(), power->PowerCostMaxPct));
4068 else
4069 powerCost += int32(CalculatePct(unitCaster->GetMaxHealth(), power->PowerCostPct));
4070 break;
4071 case POWER_MANA:
4072 powerCost += int32(CalculatePct(unitCaster->GetCreateMana(), power->PowerCostPct));
4073 break;
4075 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type POWER_ALTERNATE_POWER in spell {}", Id);
4076 return {};
4077 default:
4078 {
4079 if (PowerTypeEntry const* powerTypeEntry = sDB2Manager.GetPowerTypeEntry(Powers(power->PowerType)))
4080 {
4081 powerCost += int32(CalculatePct(powerTypeEntry->MaxBasePower, power->PowerCostPct));
4082 break;
4083 }
4084
4085 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type '{}' in spell {}", power->PowerType, Id);
4086 return {};
4087 }
4088 }
4089 }
4090 }
4091 else
4092 {
4093 powerCost = int32(power->OptionalCost);
4094
4095 if (power->OptionalCostPct)
4096 {
4097 switch (power->PowerType)
4098 {
4099 // health as power used
4100 case POWER_HEALTH:
4101 powerCost += int32(CalculatePct(unitCaster->GetMaxHealth(), power->OptionalCostPct));
4102 break;
4103 case POWER_MANA:
4104 powerCost += int32(CalculatePct(unitCaster->GetCreateMana(), power->OptionalCostPct));
4105 break;
4107 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unsupported power type POWER_ALTERNATE_POWER in spell {} for optional cost percent", Id);
4108 return {};
4109 default:
4110 {
4111 if (PowerTypeEntry const* powerTypeEntry = sDB2Manager.GetPowerTypeEntry(Powers(power->PowerType)))
4112 {
4113 powerCost += int32(CalculatePct(powerTypeEntry->MaxBasePower, power->OptionalCostPct));
4114 break;
4115 }
4116
4117 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type '{}' in spell {} for optional cost percent", power->PowerType, Id);
4118 return {};
4119 }
4120 }
4121 }
4122
4123 powerCost += unitCaster->GetTotalAuraModifier(SPELL_AURA_MOD_ADDITIONAL_POWER_COST, [this, power](AuraEffect const* aurEff) -> bool
4124 {
4125 return aurEff->GetMiscValue() == power->PowerType
4126 && aurEff->IsAffectingSpell(this);
4127 });
4128 }
4129
4130 bool initiallyNegative = powerCost < 0;
4131
4132 // Shiv - costs 20 + weaponSpeed*10 energy (apply only to non-triggered spell with energy cost)
4134 {
4135 uint32 speed = 0;
4136 if (SpellShapeshiftFormEntry const* ss = sSpellShapeshiftFormStore.LookupEntry(unitCaster->GetShapeshiftForm()))
4137 speed = ss->CombatRoundTime;
4138 else
4139 {
4142 slot = OFF_ATTACK;
4143
4144 speed = unitCaster->GetBaseAttackTime(slot);
4145 }
4146
4147 powerCost += speed / 100;
4148 }
4149
4150 if (power->PowerType != POWER_HEALTH)
4151 {
4152 if (!optionalCost)
4153 {
4154 // Flat mod from caster auras by spell school and power type
4156 {
4157 if (!(aura->GetMiscValue() & schoolMask))
4158 continue;
4159
4160 if (!(aura->GetMiscValueB() & (1 << power->PowerType)))
4161 continue;
4162
4163 powerCost += aura->GetAmount();
4164 }
4165 }
4166
4167 // PCT mod from user auras by spell school and power type
4168 for (auto schoolCostPct : unitCaster->GetAuraEffectsByType(SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT))
4169 {
4170 if (!(schoolCostPct->GetMiscValue() & schoolMask))
4171 continue;
4172
4173 if (!(schoolCostPct->GetMiscValueB() & (1 << power->PowerType)))
4174 continue;
4175
4176 powerCost += CalculatePct(powerCost, schoolCostPct->GetAmount());
4177 }
4178 }
4179
4180 // Apply cost mod by spell
4181 if (Player* modOwner = unitCaster->GetSpellModOwner())
4182 {
4184 switch (power->OrderIndex)
4185 {
4186 case 0:
4188 break;
4189 case 1:
4191 break;
4192 case 2:
4194 break;
4195 default:
4196 break;
4197 }
4198
4199 if (mod)
4200 {
4201 if (!optionalCost)
4202 modOwner->ApplySpellMod(this, *mod, powerCost, spell);
4203 else
4204 {
4205 // optional cost ignores flat modifiers
4206 int32 flatMod = 0;
4207 float pctMod = 1.0f;
4208 modOwner->GetSpellModValues(this, *mod, spell, powerCost, &flatMod, &pctMod);
4209 powerCost = int32(powerCost * pctMod);
4210 }
4211 }
4212 }
4213
4214 if (!unitCaster->IsControlledByPlayer() && G3D::fuzzyEq(power->PowerCostPct, 0.0f) && SpellLevel && power->PowerType == POWER_MANA)
4215 {
4217 {
4219 GtNpcManaCostScalerEntry const* casterScaler = sNpcManaCostScalerGameTable.GetRow(unitCaster->GetLevel());
4220 if (spellScaler && casterScaler)
4221 powerCost *= casterScaler->Scaler / spellScaler->Scaler;
4222 }
4223 }
4224
4225 if (power->PowerType == POWER_MANA)
4226 powerCost = float(powerCost) * (1.0f + unitCaster->m_unitData->ManaCostMultiplier);
4227
4228 // power cost cannot become negative if initially positive
4229 if (initiallyNegative != (powerCost < 0))
4230 powerCost = 0;
4231
4232 return SpellPowerCost{ .Power = Powers(power->PowerType), .Amount = powerCost };
4233}
4234
4235std::vector<SpellPowerCost> SpellInfo::CalcPowerCost(WorldObject const* caster, SpellSchoolMask schoolMask, Spell* spell) const
4236{
4237 std::vector<SpellPowerCost> costs;
4238 if (caster->IsUnit())
4239 {
4240 costs.reserve(MAX_POWERS_PER_SPELL);
4241
4242 auto getOrCreatePowerCost = [&](Powers powerType) -> SpellPowerCost&
4243 {
4244 auto itr = std::find_if(costs.begin(), costs.end(), [powerType](SpellPowerCost const& cost)
4245 {
4246 return cost.Power == powerType;
4247 });
4248 if (itr != costs.end())
4249 return *itr;
4250
4251 return costs.emplace_back<SpellPowerCost>({ .Power = powerType, .Amount = 0 });
4252 };
4253
4254 for (SpellPowerEntry const* power : PowerCosts)
4255 {
4256 if (!power)
4257 continue;
4258
4259 if (Optional<SpellPowerCost> cost = CalcPowerCost(power, false, caster, schoolMask, spell))
4260 getOrCreatePowerCost(cost->Power).Amount += cost->Amount;
4261
4262 if (Optional<SpellPowerCost> optionalCost = CalcPowerCost(power, true, caster, schoolMask, spell))
4263 {
4264 SpellPowerCost& cost = getOrCreatePowerCost(optionalCost->Power);
4265 int32 remainingPower = caster->ToUnit()->GetPower(optionalCost->Power) - cost.Amount;
4266 if (remainingPower > 0)
4267 cost.Amount += std::min(optionalCost->Amount, remainingPower);
4268 }
4269 }
4270 }
4271
4272 return costs;
4273}
4274
4275inline float CalcPPMHasteMod(SpellProcsPerMinuteModEntry const* mod, Unit* caster)
4276{
4277 float haste = caster->m_unitData->ModHaste;
4278 float rangedHaste = caster->m_unitData->ModRangedHaste;
4279 float spellHaste = caster->m_unitData->ModSpellHaste;
4280 float regenHaste = caster->m_unitData->ModHasteRegen;
4281
4282 switch (mod->Param)
4283 {
4284 case 1:
4285 return (1.0f / haste - 1.0f) * mod->Coeff;
4286 case 2:
4287 return (1.0f / rangedHaste - 1.0f) * mod->Coeff;
4288 case 3:
4289 return (1.0f / spellHaste - 1.0f) * mod->Coeff;
4290 case 4:
4291 return (1.0f / regenHaste - 1.0f) * mod->Coeff;
4292 case 5:
4293 return (1.0f / std::min(std::min(std::min(haste, rangedHaste), spellHaste), regenHaste) - 1.0f) * mod->Coeff;
4294 default:
4295 break;
4296 }
4297
4298 return 0.0f;
4299}
4300
4301inline float CalcPPMCritMod(SpellProcsPerMinuteModEntry const* mod, Unit* caster)
4302{
4303 Player const* player = caster->ToPlayer();
4304 if (!player)
4305 return 0.0f;
4306
4307 float crit = player->m_activePlayerData->CritPercentage;
4308 float rangedCrit = player->m_activePlayerData->RangedCritPercentage;
4309 float spellCrit = player->m_activePlayerData->SpellCritPercentage;
4310
4311 switch (mod->Param)
4312 {
4313 case 1:
4314 return crit * mod->Coeff * 0.01f;
4315 case 2:
4316 return rangedCrit * mod->Coeff * 0.01f;
4317 case 3:
4318 return spellCrit * mod->Coeff * 0.01f;
4319 case 4:
4320 return std::min(std::min(crit, rangedCrit), spellCrit) * mod->Coeff * 0.01f;
4321 default:
4322 break;
4323 }
4324
4325 return 0.0f;
4326}
4327
4328inline float CalcPPMItemLevelMod(SpellProcsPerMinuteModEntry const* mod, int32 itemLevel)
4329{
4330 if (itemLevel == mod->Param)
4331 return 0.0f;
4332
4333 float itemLevelPoints = GetRandomPropertyPoints(itemLevel, ITEM_QUALITY_RARE, INVTYPE_CHEST, 0);
4334 float basePoints = GetRandomPropertyPoints(mod->Param, ITEM_QUALITY_RARE, INVTYPE_CHEST, 0);
4335 if (itemLevelPoints == basePoints)
4336 return 0.0f;
4337
4338 return ((itemLevelPoints / basePoints) - 1.0f) * mod->Coeff;
4339}
4340
4341float SpellInfo::CalcProcPPM(Unit* caster, int32 itemLevel) const
4342{
4343 float ppm = ProcBasePPM;
4344 if (!caster)
4345 return ppm;
4346
4347 for (SpellProcsPerMinuteModEntry const* mod : ProcPPMMods)
4348 {
4349 switch (mod->Type)
4350 {
4352 {
4353 ppm *= 1.0f + CalcPPMHasteMod(mod, caster);
4354 break;
4355 }
4356 case SPELL_PPM_MOD_CRIT:
4357 {
4358 ppm *= 1.0f + CalcPPMCritMod(mod, caster);
4359 break;
4360 }
4362 {
4363 if (caster->GetClassMask() & mod->Param)
4364 ppm *= 1.0f + mod->Coeff;
4365 break;
4366 }
4367 case SPELL_PPM_MOD_SPEC:
4368 {
4369 if (Player* plrCaster = caster->ToPlayer())
4370 if (plrCaster->GetPrimarySpecialization() == ChrSpecialization(mod->Param))
4371 ppm *= 1.0f + mod->Coeff;
4372 break;
4373 }
4374 case SPELL_PPM_MOD_RACE:
4375 {
4376 if (caster->GetRaceMask() & mod->Param)
4377 ppm *= 1.0f + mod->Coeff;
4378 break;
4379 }
4381 {
4382 ppm *= 1.0f + CalcPPMItemLevelMod(mod, itemLevel);
4383 break;
4384 }
4386 {
4387 if (caster->GetMap()->IsBattlegroundOrArena())
4388 ppm *= 1.0f + mod->Coeff;
4389 break;
4390 }
4391 case SPELL_PPM_MOD_AURA:
4392 {
4393 if (caster->HasAura(mod->Param))
4394 ppm *= 1.0f + mod->Coeff;
4395 break;
4396 }
4397 default:
4398 break;
4399 }
4400 }
4401
4402 return ppm;
4403}
4404
4406{
4407 return ChainEntry != nullptr;
4408}
4409
4411{
4412 if (!ChainEntry)
4413 return 1;
4414 return ChainEntry->rank;
4415}
4416
4418{
4419 if (!ChainEntry)
4420 return this;
4421 return ChainEntry->first;
4422}
4423
4425{
4426 if (!ChainEntry)
4427 return nullptr;
4428 return ChainEntry->last;
4429}
4430
4432{
4433 if (!ChainEntry)
4434 return nullptr;
4435 return ChainEntry->next;
4436}
4437
4439{
4440 if (!ChainEntry)
4441 return nullptr;
4442 return ChainEntry->prev;
4443}
4444
4446{
4447 // ignore passive spells
4448 if (IsPassive())
4449 return this;
4450
4451 // Client ignores spell with these attributes (sub_53D9D0)
4453 return this;
4454
4455 bool needRankSelection = false;
4456 for (SpellEffectInfo const& effect : GetEffects())
4457 {
4458 if (IsPositiveEffect(effect.EffectIndex) &&
4459 (effect.Effect == SPELL_EFFECT_APPLY_AURA ||
4460 effect.Effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
4461 effect.Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID) &&
4462 !effect.Scaling.Coefficient)
4463 {
4464 needRankSelection = true;
4465 break;
4466 }
4467 }
4468
4469 // not required
4470 if (!needRankSelection)
4471 return this;
4472
4473 for (SpellInfo const* nextSpellInfo = this; nextSpellInfo != nullptr; nextSpellInfo = nextSpellInfo->GetPrevRankSpell())
4474 {
4475 // if found appropriate level
4476 if (uint32(level + 10) >= nextSpellInfo->SpellLevel)
4477 return nextSpellInfo;
4478
4479 // one rank less then
4480 }
4481
4482 // not found
4483 return nullptr;
4484}
4485
4486bool SpellInfo::IsRankOf(SpellInfo const* spellInfo) const
4487{
4488 return GetFirstRankSpell() == spellInfo->GetFirstRankSpell();
4489}
4490
4491bool SpellInfo::IsDifferentRankOf(SpellInfo const* spellInfo) const
4492{
4493 if (Id == spellInfo->Id)
4494 return false;
4495 return IsRankOf(spellInfo);
4496}
4497
4498bool SpellInfo::IsHighRankOf(SpellInfo const* spellInfo) const
4499{
4500 if (ChainEntry && spellInfo->ChainEntry)
4501 if (ChainEntry->first == spellInfo->ChainEntry->first)
4502 if (ChainEntry->rank > spellInfo->ChainEntry->rank)
4503 return true;
4504
4505 return false;
4506}
4507
4508uint32 SpellInfo::GetSpellXSpellVisualId(WorldObject const* caster /*= nullptr*/, WorldObject const* viewer /*= nullptr*/) const
4509{
4510 auto canUseSpellVisual = [=](SpellXSpellVisualEntry const* visual)
4511 {
4512 if (visual->CasterPlayerConditionID)
4513 if (!caster || !caster->IsPlayer() || !ConditionMgr::IsPlayerMeetingCondition(caster->ToPlayer(), visual->CasterPlayerConditionID))
4514 return false;
4515
4516 if (UnitConditionEntry const* unitCondition = sUnitConditionStore.LookupEntry(visual->CasterUnitConditionID))
4517 if (!caster || !caster->IsUnit() || !ConditionMgr::IsUnitMeetingCondition(caster->ToUnit(), Object::ToUnit(viewer), unitCondition))
4518 return false;
4519
4520 return true;
4521 };
4522
4523 for (auto itr = _visuals.begin(), end = _visuals.end(); itr != end; ++itr)
4524 {
4525 if (!canUseSpellVisual(*itr))
4526 continue;
4527
4528 // match found, now select among all visuals with the same priority
4529 boost::container::small_vector<SpellXSpellVisualEntry const*, 4> visualCandidates;
4530 visualCandidates.push_back(*itr);
4531
4532 for (auto itr2 = itr + 1; itr2 != end && (*itr)->Priority == (*itr2)->Priority; ++itr2)
4533 if (canUseSpellVisual(*itr2))
4534 visualCandidates.push_back(*itr2);
4535
4536 if (visualCandidates.size() == 1)
4537 return visualCandidates.front()->ID; // special case, ignores Probability
4538
4539 return (*Trinity::Containers::SelectRandomWeightedContainerElement(visualCandidates, [](SpellXSpellVisualEntry const* visual) { return visual->Probability; }))->ID;
4540 }
4541
4542 return 0;
4543}
4544
4545uint32 SpellInfo::GetSpellVisual(WorldObject const* caster /*= nullptr*/, WorldObject const* viewer /*= nullptr*/) const
4546{
4547 if (SpellXSpellVisualEntry const* visual = sSpellXSpellVisualStore.LookupEntry(GetSpellXSpellVisualId(caster, viewer)))
4548 {
4549 //if (visual->LowViolenceSpellVisualID && forPlayer->GetViolenceLevel() operator 2)
4550 // return visual->LowViolenceSpellVisualID;
4551
4552 return visual->SpellVisualID;
4553 }
4554
4555 return 0;
4556}
4557
4559{
4560 bool srcSet = false;
4561 bool dstSet = false;
4562 // prepare target mask using effect target entries
4563 for (SpellEffectInfo const& effect : GetEffects())
4564 {
4565 if (!effect.IsEffect())
4566 continue;
4567
4568 uint32 targetMask = 0;
4569 targetMask |= effect.TargetA.GetExplicitTargetMask(srcSet, dstSet);
4570 targetMask |= effect.TargetB.GetExplicitTargetMask(srcSet, dstSet);
4571
4572 // add explicit target flags based on spell effects which have EFFECT_IMPLICIT_TARGET_EXPLICIT and no valid target provided
4573 if (effect.GetImplicitTargetType() == EFFECT_IMPLICIT_TARGET_EXPLICIT)
4574 {
4575 // extend explicit target mask only if valid targets for effect could not be provided by target types
4576 uint32 effectTargetMask = effect.GetMissingTargetMask(srcSet, dstSet, targetMask);
4577
4578 // don't add explicit object/dest flags when spell has no max range
4579 if (GetMaxRange(true) == 0.0f && GetMaxRange(false) == 0.0f)
4581
4582 targetMask |= effectTargetMask;
4583 }
4584
4585 ExplicitTargetMask |= targetMask;
4586 if (!effect.EffectAttributes.HasFlag(SpellEffectAttributes::DontFailSpellOnTargetingFailure))
4587 RequiredExplicitTargetMask |= targetMask;
4588 }
4589
4593}
4594
4595inline bool _isPositiveTarget(SpellEffectInfo const& effect)
4596{
4597 if (!effect.IsEffect())
4598 return true;
4599
4600 return (effect.TargetA.GetCheckType() != TARGET_CHECK_ENEMY &&
4602}
4603
4604bool _isPositiveEffectImpl(SpellInfo const* spellInfo, SpellEffectInfo const& effect, std::unordered_set<std::pair<SpellInfo const*, SpellEffIndex>>& visited)
4605{
4606 if (!effect.IsEffect())
4607 return true;
4608
4609 // attribute may be already set in DB
4610 if (!spellInfo->IsPositiveEffect(effect.EffectIndex))
4611 return false;
4612
4613 // passive auras like talents are all positive
4614 if (spellInfo->IsPassive())
4615 return true;
4616
4617 // not found a single positive spell with this attribute
4619 return false;
4620
4621 if (spellInfo->HasAttribute(SPELL_ATTR4_AURA_IS_BUFF))
4622 return true;
4623
4625 return false;
4626
4627 visited.insert({ spellInfo, effect.EffectIndex });
4628
4629 //We need scaling level info for some auras that compute bp 0 or positive but should be debuffs
4630 float bpScalePerLevel = effect.RealPointsPerLevel;
4631 SpellEffectValue bp = effect.CalcValue();
4632 switch (spellInfo->SpellFamilyName)
4633 {
4635 switch (spellInfo->Id)
4636 {
4637 case 40268: // Spiritual Vengeance, Teron Gorefiend, Black Temple
4638 case 61987: // Avenging Wrath Marker
4639 case 61988: // Divine Shield exclude aura
4640 case 64412: // Phase Punch, Algalon the Observer, Ulduar
4641 case 72410: // Rune of Blood, Saurfang, Icecrown Citadel
4642 case 71204: // Touch of Insignificance, Lady Deathwhisper, Icecrown Citadel
4643 return false;
4644 case 24732: // Bat Costume
4645 case 30877: // Tag Murloc
4646 case 61716: // Rabbit Costume
4647 case 61734: // Noblegarden Bunny
4648 case 62344: // Fists of Stone
4649 case 50344: // Dream Funnel
4650 case 61819: // Manabonked! (item)
4651 case 61834: // Manabonked! (minigob)
4652 case 73523: // Rigor Mortis
4653 return true;
4654 default:
4655 break;
4656 }
4657 break;
4658 case SPELLFAMILY_ROGUE:
4659 switch (spellInfo->Id)
4660 {
4661 // Envenom must be considered as a positive effect even though it deals damage
4662 case 32645: // Envenom
4663 return true;
4664 case 40251: // Shadow of Death, Teron Gorefiend, Black Temple
4665 return false;
4666 default:
4667 break;
4668 }
4669 break;
4671 // Slam, Execute
4672 if ((spellInfo->SpellFamilyFlags[0] & 0x20200000) != 0)
4673 return false;
4674 break;
4675 default:
4676 break;
4677 }
4678
4679 switch (spellInfo->Mechanic)
4680 {
4682 return true;
4683 default:
4684 break;
4685 }
4686
4687 // Special case: effects which determine positivity of whole spell
4688 if (spellInfo->HasAttribute(SPELL_ATTR1_AURA_UNIQUE))
4689 {
4690 // check for targets, there seems to be an assortment of dummy triggering spells that should be negative
4691 for (SpellEffectInfo const& otherEffect : spellInfo->GetEffects())
4692 if (!_isPositiveTarget(otherEffect))
4693 return false;
4694 }
4695
4696 for (SpellEffectInfo const& otherEffect : spellInfo->GetEffects())
4697 {
4698 switch (otherEffect.Effect)
4699 {
4700 case SPELL_EFFECT_HEAL:
4704 return true;
4706 if (otherEffect.EffectIndex != effect.EffectIndex && // for spells like 38044: instakill effect is negative but auras on target must count as buff
4707 otherEffect.TargetA.GetTarget() == effect.TargetA.GetTarget() &&
4708 otherEffect.TargetB.GetTarget() == effect.TargetB.GetTarget())
4709 return false;
4710 break;
4711 default:
4712 break;
4713 }
4714
4715 if (otherEffect.IsAura())
4716 {
4717 switch (otherEffect.ApplyAuraName)
4718 {
4721 return true;
4723 case SPELL_AURA_EMPATHY:
4726 return false;
4727 default:
4728 break;
4729 }
4730 }
4731 }
4732
4733 switch (effect.Effect)
4734 {
4753 return false;
4759 return true;
4765 // check targets
4766 if (!_isPositiveTarget(effect))
4767 return false;
4768 break;
4770 // non-positive dispel
4771 switch (effect.MiscValue)
4772 {
4773 case DISPEL_STEALTH:
4775 case DISPEL_ENRAGE:
4776 return false;
4777 default:
4778 break;
4779 }
4780
4781 // also check targets
4782 if (!_isPositiveTarget(effect))
4783 return false;
4784 break;
4786 if (!_isPositiveTarget(effect))
4787 {
4788 // non-positive mechanic dispel on negative target
4789 switch (effect.MiscValue)
4790 {
4791 case MECHANIC_BANDAGE:
4792 case MECHANIC_SHIELD:
4793 case MECHANIC_MOUNT:
4795 return false;
4796 default:
4797 break;
4798 }
4799 }
4800 break;
4803 // check targets AND basepoints
4804 if (!_isPositiveTarget(effect) && bp > 0)
4805 return false;
4806 break;
4807 default:
4808 break;
4809 }
4810
4811 if (effect.IsAura())
4812 {
4813 // non-positive aura use
4814 switch (effect.ApplyAuraName)
4815 {
4816 case SPELL_AURA_MOD_STAT: // dependent from basepoint sign (negative -> negative)
4840 if (bp < 0 || bpScalePerLevel < 0) //TODO: What if both are 0? Should it be a buff or debuff?
4841 return false;
4842 break;
4843 case SPELL_AURA_MOD_ATTACKSPEED: // some buffs have negative bp, check both target and bp
4857 if (!_isPositiveTarget(effect) || bp < 0)
4858 return false;
4859 break;
4860 case SPELL_AURA_MOD_DAMAGE_TAKEN: // dependent from basepoint sign (positive -> negative)
4866 if (bp > 0)
4867 return false;
4868 break;
4869 case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN: // check targets and basepoints (ex Recklessness)
4870 if (!_isPositiveTarget(effect) && bp > 0)
4871 return false;
4872 break;
4873 case SPELL_AURA_MOD_HEALTH_REGEN_PERCENT: // check targets and basepoints (target enemy and negative bp -> negative)
4874 if (!_isPositiveTarget(effect) && bp < 0)
4875 return false;
4876 break;
4878 return true;
4881 if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(effect.TriggerSpell, spellInfo->Difficulty))
4882 {
4883 // negative targets of main spell return early
4884 for (SpellEffectInfo const& spellTriggeredEffect : spellTriggeredProto->GetEffects())
4885 {
4886 // already seen this
4887 if (visited.count({ spellTriggeredProto, spellTriggeredEffect.EffectIndex }) > 0)
4888 continue;
4889
4890 if (!spellTriggeredEffect.IsEffect())
4891 continue;
4892
4893 // if non-positive trigger cast targeted to positive target this main cast is non-positive
4894 // this will place this spell auras as debuffs
4895 if (_isPositiveTarget(spellTriggeredEffect) && !_isPositiveEffectImpl(spellTriggeredProto, spellTriggeredEffect, visited))
4896 return false;
4897 }
4898 }
4899 break;
4906 // special auras: they may have non negative target but still need to be marked as debuff
4907 // checked again after all effects (SpellInfo::_InitializeSpellPositivity)
4924 case SPELL_AURA_DUMMY:
4940 // check target for positive and negative spells
4941 if (!_isPositiveTarget(effect))
4942 return false;
4943 break;
4950 case SPELL_AURA_GHOST:
4960 return false;
4962 {
4963 // non-positive immunities
4964 switch (effect.MiscValue)
4965 {
4966 case MECHANIC_BANDAGE:
4967 case MECHANIC_SHIELD:
4968 case MECHANIC_MOUNT:
4970 return false;
4971 default:
4972 break;
4973 }
4974 break;
4975 }
4976 case SPELL_AURA_ADD_FLAT_MODIFIER: // mods
4980 {
4981 switch (SpellModOp(effect.MiscValue))
4982 {
4983 case SpellModOp::ChangeCastTime: // dependent from basepoint sign (positive -> negative)
4984 case SpellModOp::Period:
4987 if (bp > 0)
4988 return false;
4989 break;
4994 if (!spellInfo->IsPositive() && bp > 0) // dependent on prev effects too (ex Arcane Power)
4995 return false;
4996 break;
4997 case SpellModOp::PointsIndex0: // always positive
5002 case SpellModOp::Points:
5003 case SpellModOp::Hate:
5006 return true;
5011 if (!spellInfo->IsPositive() && bp < 0) // dependent on prev effects too
5012 return false;
5013 break;
5014 default: // dependent from basepoint sign (negative -> negative)
5015 if (bp < 0)
5016 return false;
5017 break;
5018 }
5019 break;
5020 }
5021 default:
5022 break;
5023 }
5024 }
5025
5026 // negative spell if triggered spell is negative
5027 if (!effect.ApplyAuraName && effect.TriggerSpell)
5028 {
5029 if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(effect.TriggerSpell, spellInfo->Difficulty))
5030 {
5031 // spells with at least one negative effect are considered negative
5032 // some self-applied spells have negative effects but in self casting case negative check ignored.
5033 for (SpellEffectInfo const& spellTriggeredEffect : spellTriggeredProto->GetEffects())
5034 {
5035 // already seen this
5036 if (visited.count({ spellTriggeredProto, spellTriggeredEffect.EffectIndex }) > 0)
5037 continue;
5038
5039 if (!spellTriggeredEffect.IsEffect())
5040 continue;
5041
5042 if (!_isPositiveEffectImpl(spellTriggeredProto, spellTriggeredEffect, visited))
5043 return false;
5044 }
5045 }
5046 }
5047
5048 // ok, positive
5049 return true;
5050}
5051
5053{
5054 std::unordered_set<std::pair<SpellInfo const*, SpellEffIndex /*effIndex*/>> visited;
5055
5056 for (SpellEffectInfo const& effect : GetEffects())
5057 if (!_isPositiveEffectImpl(this, effect, visited))
5058 NegativeEffects[effect.EffectIndex] = true;
5059
5060 // additional checks after effects marked
5061 for (SpellEffectInfo const& effect : GetEffects())
5062 {
5063 if (!effect.IsEffect() || !IsPositiveEffect(effect.EffectIndex))
5064 continue;
5065
5066 switch (effect.ApplyAuraName)
5067 {
5068 // has other non positive effect?
5069 // then it should be marked negative if has same target as negative effect (ex 8510, 8511, 8893, 10267)
5070 case SPELL_AURA_DUMMY:
5077 {
5078 for (size_t j = effect.EffectIndex + 1; j < GetEffects().size(); ++j)
5079 if (!IsPositiveEffect(j)
5080 && effect.TargetA.GetTarget() == GetEffect(SpellEffIndex(j)).TargetA.GetTarget()
5081 && effect.TargetB.GetTarget() == GetEffect(SpellEffIndex(j)).TargetB.GetTarget())
5082 NegativeEffects[effect.EffectIndex] = true;
5083 break;
5084 }
5085 default:
5086 break;
5087 }
5088 }
5089}
5090
5092{
5093 // find the same instances of ConditionList and delete them.
5094 for (SpellEffectInfo& effect : _effects)
5095 effect.ImplicitTargetConditions = nullptr;
5096}
5097
5099{
5101 return false;
5102
5104}
5105
5106bool SpellInfo::HasLabel(uint32 labelId) const
5107{
5108 return Labels.contains(labelId);
5109}
@ 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:569
@ VEHICLE_SEAT_FLAG_UNK2
Definition DBCEnums.h:3122
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition DBCEnums.h:3104
@ VEHICLE_SEAT_FLAG_CAN_CONTROL
Definition DBCEnums.h:3103
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition DBCEnums.h:3105
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition DBCEnums.h:3106
SpellEffectAttributes
Definition DBCEnums.h:2401
AreaMountFlags
Definition DBCEnums.h:163
constexpr std::size_t MAX_POWERS_PER_SPELL
Definition DBCEnums.h:2463
ChrSpecialization
Definition DBCEnums.h:398
Difficulty
Definition DBCEnums.h:932
ExpectedStatType
Definition DBCEnums.h:986
@ SPELL_PPM_MOD_CRIT
Definition DBCEnums.h:2454
@ SPELL_PPM_MOD_AURA
Definition DBCEnums.h:2460
@ SPELL_PPM_MOD_ITEM_LEVEL
Definition DBCEnums.h:2458
@ SPELL_PPM_MOD_CLASS
Definition DBCEnums.h:2455
@ SPELL_PPM_MOD_SPEC
Definition DBCEnums.h:2456
@ SPELL_PPM_MOD_RACE
Definition DBCEnums.h:2457
@ SPELL_PPM_MOD_HASTE
Definition DBCEnums.h:2453
@ SPELL_PPM_MOD_BATTLEGROUND
Definition DBCEnums.h:2459
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:80
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
TC_GAME_API 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:190
LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template", "creature pickpocket lootid", true)
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:180
@ SPELLMOD_FLAT
Definition Player.h:177
@ SPELLMOD_PCT
Definition Player.h:178
@ SPELLMOD_LABEL_FLAT
Definition Player.h:179
float frand(float min, float max)
Definition Random.cpp:55
float rand_norm()
Definition Random.cpp:75
@ 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_COOLDOWN_IGNORES_RANGED_WEAPON
@ SPELL_ATTR9_NO_MOVEMENT_RADIUS_BONUS
@ SPELL_ATTR7_BYPASS_NO_RESURRECT_AURA
@ SPELL_ATTR7_NO_UI_NOT_INTERRUPTIBLE
#define DISPEL_ALL_MASK
@ CLASS_NONE
@ SPELL_PREVENTION_TYPE_SILENCE
@ SPELL_ATTR5_EXTRA_INITIAL_PERIOD
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
@ SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC
@ SPELL_ATTR5_ALLOW_WHILE_FLEEING
@ SPELL_ATTR5_NOT_ON_PLAYER
@ SPELL_ATTR5_LIMIT_N
@ SPELL_ATTR5_ALLOW_WHILE_CONFUSED
SpellTargetIndex
@ 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
SpellEffectName
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_POWER_BURN
@ SPELL_EFFECT_ENERGIZE_PCT
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
@ SPELL_EFFECT_APPLY_AREA_AURA_FRIEND
@ SPELL_EFFECT_SELF_RESURRECT
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY_NONRANDOM
@ SPELL_EFFECT_DISTRACT
@ SPELL_EFFECT_DURABILITY_DAMAGE
@ SPELL_EFFECT_CREATE_LOOT
@ SPELL_EFFECT_HEALTH_LEECH
@ SPELL_EFFECT_SKILL
@ SPELL_EFFECT_WEAPON_DAMAGE
@ SPELL_EFFECT_HEAL
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
@ SPELL_EFFECT_APPLY_AURA_ON_PET
@ SPELL_EFFECT_DAMAGE_FROM_MAX_HEALTH_PCT
@ SPELL_EFFECT_DISPEL_MECHANIC
@ SPELL_EFFECT_HEAL_MAX_HEALTH
@ SPELL_EFFECT_APPLY_AREA_AURA_PET
@ SPELL_EFFECT_DISPEL
@ SPELL_EFFECT_NONE
@ SPELL_EFFECT_TAMECREATURE
@ SPELL_EFFECT_ATTACK_ME
@ SPELL_EFFECT_PICKPOCKET
@ SPELL_EFFECT_HEAL_MECHANICAL
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
@ SPELL_EFFECT_MODIFY_THREAT_PERCENT
@ SPELL_EFFECT_DURABILITY_DAMAGE_PCT
@ SPELL_EFFECT_ENVIRONMENTAL_DAMAGE
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
@ SPELL_EFFECT_PERSISTENT_AREA_AURA
@ SPELL_EFFECT_SUMMON
@ SPELL_EFFECT_ENERGIZE
@ SPELL_EFFECT_POWER_DRAIN
@ SPELL_EFFECT_RESURRECT
@ SPELL_EFFECT_CHARGE
@ SPELL_EFFECT_KNOCK_BACK
@ SPELL_EFFECT_SCHOOL_DAMAGE
@ SPELL_EFFECT_GAMEOBJECT_DAMAGE
@ SPELL_EFFECT_LEARN_SPELL
@ SPELL_EFFECT_CREATE_RANDOM_ITEM
@ SPELL_EFFECT_INSTAKILL
@ SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
@ SPELL_EFFECT_HEAL_PCT
@ SPELL_EFFECT_INTERRUPT_CAST
@ SPELL_EFFECT_APPLY_AREA_AURA_SUMMONS
@ SPELL_EFFECT_THREAT
@ SPELL_EFFECT_SKILL_STEP
@ SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
@ SPELL_EFFECT_APPLY_AURA
@ SPELL_EFFECT_APPLY_AREA_AURA_OWNER
WeaponAttackType
@ OFF_ATTACK
@ BASE_ATTACK
@ RANGED_ATTACK
Mechanics
@ MECHANIC_DISARM
@ MECHANIC_NONE
@ MECHANIC_MOUNT
@ MECHANIC_FEAR
@ MECHANIC_INVULNERABILITY
@ MECHANIC_DISORIENTED
@ MECHANIC_KNOCKOUT
@ MECHANIC_STUN
@ MECHANIC_FREEZE
@ MECHANIC_INTERRUPT
@ MECHANIC_ROOT
@ MECHANIC_BANDAGE
@ MECHANIC_SLEEP
@ MECHANIC_BLEED
@ MECHANIC_BANISH
@ MAX_MECHANIC
@ MECHANIC_IMMUNE_SHIELD
@ MECHANIC_SNARE
@ MECHANIC_SILENCE
@ MECHANIC_SHIELD
@ MECHANIC_HORROR
@ IMMUNITY_STATE
@ IMMUNITY_EFFECT
@ IMMUNITY_DAMAGE
@ IMMUNITY_MECHANIC
@ IMMUNITY_SCHOOL
@ IMMUNITY_OTHER
@ IMMUNITY_DISPEL
Powers
@ MAX_POWERS
@ POWER_ALTERNATE_POWER
@ POWER_HEALTH
@ POWER_COMBO_POINTS
@ POWER_MANA
SpellAttr0
@ SPELL_ATTR0_ON_NEXT_SWING
@ SPELL_ATTR0_NOT_SHAPESHIFTED
@ SPELL_ATTR0_AURA_IS_DEBUFF
@ SPELL_ATTR0_ALLOW_WHILE_MOUNTED
@ SPELL_ATTR0_PASSIVE
@ SPELL_ATTR0_COOLDOWN_ON_EVENT
@ SPELL_ATTR0_NO_IMMUNITIES
@ SPELL_ATTR0_SCALES_WITH_CREATURE_LEVEL
@ SPELL_ATTR0_NOT_IN_COMBAT_ONLY_PEACEFUL
@ SPELL_ATTR0_USES_RANGED_SLOT
@ SPELL_ATTR0_ON_NEXT_SWING_NO_DAMAGE
DiminishingLevels
@ DIMINISHING_LEVEL_IMMUNE
@ DIMINISHING_LEVEL_TAUNT_IMMUNE
@ DIMINISHING_LEVEL_2
@ 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_TRACK_RESOURCES
@ SPELL_AURA_MOD_PARRY_PERCENT
@ SPELL_AURA_MOD_MAX_POWER
@ SPELL_AURA_MOD_SHAPESHIFT
@ SPELL_AURA_MOD_DISARM
@ SPELL_AURA_MOD_SPELL_HIT_CHANCE
@ SPELL_AURA_DAMAGE_SHIELD
@ SPELL_AURA_OBS_MOD_HEALTH
@ SPELL_AURA_MOD_THREAT
@ SPELL_AURA_PERIODIC_HEALTH_FUNNEL
@ SPELL_AURA_MELEE_SLOW
@ SPELL_AURA_ADD_PCT_MODIFIER
@ SPELL_AURA_PERIODIC_MANA_LEECH
@ SPELL_AURA_MOD_POSSESS_PET
@ SPELL_AURA_MOD_INCREASE_SPEED
@ SPELL_AURA_MOD_RESISTANCE
@ SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS
@ SPELL_AURA_MOD_BONUS_ARMOR
@ SPELL_AURA_PROC_TRIGGER_SPELL
@ SPELL_AURA_HASTE_SPELLS
@ SPELL_AURA_MOD_INCREASE_HEALTH
@ SPELL_AURA_MOD_FEAR
@ SPELL_AURA_MOD_POWER_REGEN
@ SPELL_AURA_MOD_HEALING_DONE_PERCENT
@ SPELL_AURA_PREVENT_INTERRUPT
@ SPELL_AURA_PREVENTS_FLEEING
@ SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS
@ SPELL_AURA_OBS_MOD_POWER
@ SPELL_AURA_ADD_FLAT_MODIFIER
@ SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE
@ SPELL_AURA_TRACK_STEALTHED
@ SPELL_AURA_MOD_MELEE_HASTE
@ SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS
@ SPELL_AURA_EMPATHY
@ SPELL_AURA_MOD_INCREASE_ENERGY
@ SPELL_AURA_MOD_STALKED
@ SPELL_AURA_SCHOOL_HEAL_ABSORB
@ SPELL_AURA_MOD_ROOT_2
@ SPELL_AURA_MOD_SPELL_CRIT_CHANCE
@ SPELL_AURA_MOD_RATING
@ SPELL_AURA_MOD_HIT_CHANCE
@ SPELL_AURA_PERIODIC_HEAL
@ SPELL_AURA_MOD_HEALTH_REGEN_PERCENT
@ SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE
@ SPELL_AURA_PERIODIC_DAMAGE_PERCENT
@ SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT
@ SPELL_AURA_DUMMY
@ SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN
@ SPELL_AURA_MOD_INCREASE_HEALTH_2
@ SPELL_AURA_MOD_DODGE_PERCENT
@ SPELL_AURA_MOD_INCREASE_SWIM_SPEED
@ SPELL_AURA_MOD_PACIFY
@ SPELL_AURA_MOD_SILENCE
@ SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT
@ SPELL_AURA_MOD_DISARM_OFFHAND
@ SPELL_AURA_ADD_TARGET_TRIGGER
@ SPELL_AURA_ALLOW_INTERRUPT_SPELL
@ SPELL_AURA_MOD_DETAUNT
@ SPELL_AURA_MOD_STAT
@ SPELL_AURA_MOD_HEALING_DONE
@ SPELL_AURA_MOD_RANGED_ATTACK_POWER
@ SPELL_AURA_MOD_HEALING_PCT
@ SPELL_AURA_ADD_FLAT_MODIFIER_BY_SPELL_LABEL
@ SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
@ SPELL_AURA_GHOST
@ SPELL_AURA_MOD_CHARM
@ SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE
@ SPELL_AURA_ALLOW_MOUNT_IN_COMBAT
@ SPELL_AURA_MOD_ROOT
@ SPELL_AURA_MOD_RANGED_HASTE
@ SPELL_AURA_SCHOOL_IMMUNITY
@ SPELL_AURA_MOUNTED
@ SPELL_AURA_MOUNT_RESTRICTIONS
@ SPELL_AURA_MOD_POWER_COST_SCHOOL
@ SPELL_AURA_MECHANIC_IMMUNITY
@ SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE
@ SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN
@ SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT
@ SPELL_AURA_MOD_DAMAGE_TAKEN
@ SPELL_AURA_MOD_TAUNT
@ SPELL_AURA_MOD_CRIT_PCT
@ SPELL_AURA_MOD_SPELL_DAMAGE_FROM_CASTER
@ SPELL_AURA_MOD_PACIFY_SILENCE
@ SPELL_AURA_MOD_COOLDOWN
@ SPELL_AURA_AOE_CHARM
@ SPELL_AURA_MOD_SPEED_SLOW_ALL
@ SPELL_AURA_MOD_TARGET_RESISTANCE
@ SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS
@ SPELL_AURA_MOD_SPEED_ALWAYS
@ SPELL_AURA_EFFECT_IMMUNITY
@ SPELL_AURA_MOD_DECREASE_SPEED
@ SPELL_AURA_TRANSFORM
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE
@ SPELL_AURA_SCHOOL_ABSORB
@ SPELL_AURA_MOD_RESISTANCE_PCT
@ SPELL_AURA_PERIODIC_ENERGIZE
@ SPELL_AURA_MOD_BASE_RESISTANCE
@ SPELL_AURA_MOD_WEAPON_CRIT_PERCENT
@ SPELL_AURA_MOD_DAMAGE_DONE_CREATURE
@ SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL
@ SPELL_AURA_MOD_ADDITIONAL_POWER_COST
@ SPELL_AURA_PERIODIC_LEECH
@ SPELL_AURA_MOD_SKILL_2
@ SPELL_AURA_MOD_LANGUAGE
@ SPELL_AURA_IGNORE_SPELL_CREATURE_TYPE_REQUIREMENTS
@ SPELL_AURA_PROC_TRIGGER_DAMAGE
@ SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE
@ SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT
@ SPELL_AURA_DAMAGE_IMMUNITY
@ SPELL_AURA_POWER_BURN
@ SPELL_AURA_MOD_PERCENT_STAT
@ SPELL_AURA_MOD_HEALING
@ SPELL_AURA_MOD_DAMAGE_DONE
@ SPELL_AURA_MOD_CONFUSE
@ SPELL_AURA_TRACK_CREATURES
@ SPELL_AURA_MOD_POSSESS
@ SPELL_AURA_PERIODIC_DUMMY
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT
@ SPELL_AURA_STATE_IMMUNITY
@ SPELL_AURA_MOD_UNATTACKABLE
@ SPELL_AURA_ADD_PCT_MODIFIER_BY_SPELL_LABEL
@ SPELL_AURA_MOD_STEALTH
@ SPELL_AURA_MOD_DETECT_RANGE
@ SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
@ SPELL_AURA_MOD_MELEE_RANGED_HASTE
@ SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK
@ SPELL_AURA_MOD_REGEN
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
@ SPELL_AURA_MOD_ATTACK_POWER_PCT
@ SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
@ SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT
@ SPELL_AURA_MECHANIC_IMMUNITY_MASK
@ SPELL_AURA_SET_VEHICLE_ID
@ SPELL_AURA_MOD_STUN
SpellInterruptFlags
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
@ MOVEMENTFLAG_FLYING
@ MOVEMENTFLAG_FALLING
@ MOVEMENTFLAG_SWIMMING
@ MOVEMENTFLAG_HOVER
@ MOVEMENTFLAG3_ADV_FLYING
@ UNIT_FLAG_PET_IN_COMBAT
@ UNIT_STATE_IN_FLIGHT
Definition Unit.h:269
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:268
bool CanHaveLoot() const
Definition Creature.h:295
static bool IsInArea(uint32 objectAreaId, uint32 areaId)
constexpr bool HasFlag(T flag) const
Definition EnumFlag.h:106
Definition Item.h:179
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition Item.cpp:1477
bool HaveLootFor(uint32 loot_id) const
Definition LootMgr.h:92
Definition Map.h:225
bool IsBattlegroundOrArena() const
Definition Map.cpp:3369
InstanceMap * ToInstanceMap()
Definition Map.h:490
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:3062
bool InBattleground() const
Definition Player.h:2584
Battleground * GetBattleground() const
Definition Player.cpp:25719
bool IsGameMaster() const
Definition Player.h:1309
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition Player.cpp:9669
bool IsUseEquipedWeapon(bool mainhand) const
Definition Player.cpp:13196
float PositionFacing
Definition SpellInfo.h:227
Mechanics Mechanic
Definition SpellInfo.h:226
static std::array< StaticData, TOTAL_SPELL_EFFECTS > _data
Definition SpellInfo.h:958
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
std::unique_ptr< ImmunityInfo > _immunityInfo
Definition SpellInfo.h:299
bool IsAreaAuraEffect() const
SpellInfo const * _spellInfo
Definition SpellInfo.h:212
bool IsAura() const
SpellEffectName Effect
Definition SpellInfo.h:215
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:245
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
bool HasEffect(SpellEffectName effect) 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:628
bool IsCooldownStartedOnEvent() const
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 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:630
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:627
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
struct SpellInfo::@326 SqrtDamageAndHealingDiminishing
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
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:588
std::vector< SpellEffectInfo > const & GetEffects() const
Definition SpellInfo.h:587
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:632
SpellSpecificType _spellSpecific
Definition SpellInfo.h:629
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
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:633
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:7392
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:635
void ApplySpellImmune(uint32 spellId, SpellImmunity op, uint32 type, bool apply)
Definition Unit.cpp:8242
Vehicle * GetVehicle() const
Definition Unit.h:1784
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3955
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1342
bool HasAuraTypeWithMiscvalue(AuraType auraType, int32 miscValue) const
Definition Unit.cpp:4827
uint32 GetClassMask() const
Definition Unit.h:766
ShapeshiftForm GetShapeshiftForm() const
Definition Unit.h:1504
uint64 GetMechanicImmunityMask() const
Definition Unit.cpp:7835
uint64 GetRaceMask() const
Definition Unit.h:763
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:845
uint32 GetBaseAttackTime(WeaponAttackType att) const
Definition Unit.cpp:10934
bool IsAlive() const
Definition Unit.h:1185
TempSummon * ToTempSummon()
Definition Unit.h:1828
uint32 GetVirtualItemId(uint32 slot) const
Definition Unit.cpp:14358
EnumFlag< SpellOtherImmunity > GetSpellOtherImmunityMask() const
Definition Unit.cpp:7845
uint64 GetMaxHealth() const
Definition Unit.h:789
bool HasUnitMovementFlag(uint32 f) const
Definition Unit.h:1734
uint64 GetHealth() const
Definition Unit.h:788
bool IsSummon() const
Definition Unit.h:749
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition Unit.cpp:6146
float GetTotalAuraModifier(AuraType auraType) const
Definition Unit.cpp:5069
bool IsVisible() const
Definition Unit.cpp:8763
bool HasAuraType(AuraType auraType) const
Definition Unit.cpp:4814
ObjectGuid GetCritterGUID() const
Definition Unit.h:1199
void RemoveAurasWithInterruptFlags(InterruptFlags flag, SpellInfo const *source=nullptr)
Definition Unit.cpp:4241
void RemoveAppliedAuras(std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3901
UF::UpdateField< UF::UnitData, int32(WowCS::EntityFragment::CGObject), TYPEID_UNIT > m_unitData
Definition Unit.h:1881
int32 GetPower(Powers power) const
Definition Unit.cpp:10028
bool HasExtraUnitMovementFlag2(uint32 f) const
Definition Unit.h:1746
bool HasUnitState(const uint32 f) const
Definition Unit.h:743
bool IsMagnet() const
Definition Unit.cpp:6573
bool IsInRaidWith(Unit const *unit) const
Definition Unit.cpp:12177
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4804
void RemoveAurasWithMechanic(uint64 mechanicMaskToRemove, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, uint32 exceptSpellId=0, bool withEffectMechanics=false)
Definition Unit.cpp:4302
bool IsControlledByPlayer() const
Definition Unit.h:1214
bool HasBreakableByDamageCrowdControlAura(Unit const *excludeCasterChannel=nullptr) const
Definition Unit.cpp:778
uint32 GetCreatureTypeMask() const
Definition Unit.cpp:9469
bool HasAuraTypeWithAffectMask(AuraType auraType, SpellInfo const *affectedSpell) const
Definition Unit.cpp:4836
uint32 GetCreateMana() const
Definition Unit.h:1417
MountCapabilityEntry const * GetMountCapability(uint32 mountType) const
Definition Unit.cpp:8362
bool IsInPartyWith(Unit const *unit) const
Definition Unit.cpp:12158
uint8 GetLevel() const
Definition Unit.h:757
bool IsInCombat() const
Definition Unit.h:1058
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:2324
bool CanSeeOrDetect(WorldObject const *obj, CanSeeOrDetectExtraArgs const &args={ }) const
Definition Object.cpp:857
Player * GetSpellModOwner() const
Definition Object.cpp:1641
bool IsValidAssistTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition Object.cpp:2482
SpellEffectValue ApplyEffectModifiers(SpellInfo const *spellInfo, uint8 effIndex, SpellEffectValue value) const
Definition Object.cpp:1671
void ModSpellCastTime(SpellInfo const *spellInfo, int32 &castTime, Spell *spell=nullptr) const
Definition Object.cpp:1785
Player * GetAffectingPlayer() const
Definition Object.cpp:1630
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
ImmunityInfo(ImmunityInfo &&) noexcept=delete
Trinity::Containers::FlatSet< AuraType > AuraTypeImmune
ImmunityInfo(ImmunityInfo const &)=delete
Trinity::Containers::FlatSet< SpellEffectName > SpellEffectImmune
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:259
uint32 spellId
Definition Player.h:261
LocalizedString Name
std::array< float, 2 > RangeMin
std::array< float, 2 > RangeMax
EnumFlag< SpellShapeshiftFormFlags > GetFlags() const