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 "Corpse.h"
21#include "Creature.h"
22#include "DBCStores.h"
23#include "FlatSet.h"
24#include "Item.h"
25#include "ItemTemplate.h"
26#include "Log.h"
27#include "ObjectAccessor.h"
28#include "Player.h"
29#include "Random.h"
30#include "Spell.h"
31#include "SpellAuraEffects.h"
32#include "SpellMgr.h"
33#include "Vehicle.h"
34
63
68
73
78
83
88
90{
91 return _data[_target].SelectionCheckType;
92}
93
98
100{
101 switch (GetDirectionType())
102 {
103 case TARGET_DIR_FRONT:
104 return 0.0f;
105 case TARGET_DIR_BACK:
106 return static_cast<float>(M_PI);
107 case TARGET_DIR_RIGHT:
108 return static_cast<float>(-M_PI/2);
109 case TARGET_DIR_LEFT:
110 return static_cast<float>(M_PI/2);
112 return static_cast<float>(-M_PI/4);
114 return static_cast<float>(-3*M_PI/4);
116 return static_cast<float>(3*M_PI/4);
118 return static_cast<float>(M_PI/4);
120 return float(rand_norm())*static_cast<float>(2*M_PI);
121 default:
122 return 0.0f;
123 }
124}
125
130
132{
133 uint32 targetMask = 0;
135 {
136 if (!srcSet)
137 targetMask = TARGET_FLAG_SOURCE_LOCATION;
138 if (!dstSet)
139 targetMask |= TARGET_FLAG_DEST_LOCATION;
140 }
141 else
142 {
143 switch (GetReferenceType())
144 {
146 if (srcSet)
147 break;
148 targetMask = TARGET_FLAG_SOURCE_LOCATION;
149 break;
151 if (dstSet)
152 break;
153 targetMask = TARGET_FLAG_DEST_LOCATION;
154 break;
156 switch (GetObjectType())
157 {
159 targetMask = TARGET_FLAG_GAMEOBJECT;
160 break;
162 targetMask = TARGET_FLAG_GAMEOBJECT_ITEM;
163 break;
167 switch (GetCheckType())
168 {
170 targetMask = TARGET_FLAG_UNIT_ENEMY;
171 break;
173 targetMask = TARGET_FLAG_UNIT_ALLY;
174 break;
176 targetMask = TARGET_FLAG_UNIT_PARTY;
177 break;
179 targetMask = TARGET_FLAG_UNIT_RAID;
180 break;
182 targetMask = TARGET_FLAG_UNIT_PASSENGER;
183 break;
185 [[fallthrough]];
186 default:
187 targetMask = TARGET_FLAG_UNIT;
188 break;
189 }
190 break;
191 default:
192 break;
193 }
194 break;
195 default:
196 break;
197 }
198 }
199
200 switch (GetObjectType())
201 {
203 srcSet = true;
204 break;
207 dstSet = true;
208 break;
209 default:
210 break;
211 }
212 return targetMask;
213}
214
235
237{ {
349} };
350
357
358SpellEffectInfo::SpellEffectInfo(SpellEntry const* spellEntry, SpellInfo const* spellInfo, uint8 effIndex)
359{
360 _spellInfo = spellInfo;
361 EffectIndex = SpellEffIndex(effIndex);
362 Effect = SpellEffects(spellEntry->Effect[effIndex]);
363 ApplyAuraName = AuraType(spellEntry->EffectAura[effIndex]);
364 ApplyAuraPeriod = spellEntry->EffectAuraPeriod[effIndex];
365 DieSides = spellEntry->EffectDieSides[effIndex];
366 RealPointsPerLevel = spellEntry->EffectRealPointsPerLevel[effIndex];
367 BasePoints = spellEntry->EffectBasePoints[effIndex];
368 PointsPerComboPoint = spellEntry->EffectPointsPerCombo[effIndex];
369 Amplitude = spellEntry->EffectAmplitude[effIndex];
370 ChainAmplitude = spellEntry->EffectChainAmplitude[effIndex];
371 BonusCoefficient = spellEntry->EffectBonusCoefficient[effIndex];
372 MiscValue = spellEntry->EffectMiscValue[effIndex];
373 MiscValueB = spellEntry->EffectMiscValueB[effIndex];
374 Mechanic = Mechanics(spellEntry->EffectMechanic[effIndex]);
377 RadiusEntry = spellEntry->EffectRadiusIndex[effIndex] ? sSpellRadiusStore.LookupEntry(spellEntry->EffectRadiusIndex[effIndex]) : nullptr;
378 ChainTargets = spellEntry->EffectChainTargets[effIndex];
379 ItemType = spellEntry->EffectItemType[effIndex];
380 TriggerSpell = spellEntry->EffectTriggerSpell[effIndex];
381 SpellClassMask = spellEntry->EffectSpellClassMask[effIndex];
382 ImplicitTargetConditions = nullptr;
383 _immunityInfo = nullptr;
384}
385
387SpellEffectInfo& SpellEffectInfo::operator=(SpellEffectInfo&&) noexcept = default;
388
389SpellEffectInfo::~SpellEffectInfo() = default;
390
391bool SpellEffectInfo::IsEffect() const
392{
393 return Effect != 0;
394}
395
397{
398 return Effect == effectName;
399}
400
405
407{
408 return IsAura() && ApplyAuraName == aura;
409}
410
412{
413 return TargetA.IsArea() || TargetB.IsArea();
414}
415
427
432
433int32 SpellEffectInfo::CalcValue(WorldObject const* caster /*= nullptr*/, int32 const* bp /*= nullptr*/) const
434{
435 float basePointsPerLevel = RealPointsPerLevel;
436 int32 basePoints = bp ? *bp : BasePoints;
437 int32 randomPoints = int32(DieSides);
438
439 Unit const* casterUnit = nullptr;
440 if (caster)
441 casterUnit = caster->ToUnit();
442
443 // base amount modification based on spell lvl vs caster lvl
444 if (casterUnit && basePointsPerLevel != 0.0f)
445 {
446 int32 level = int32(casterUnit->GetLevel());
447 if (level > int32(_spellInfo->MaxLevel) && _spellInfo->MaxLevel > 0)
448 level = int32(_spellInfo->MaxLevel);
449 else if (level < int32(_spellInfo->BaseLevel))
450 level = int32(_spellInfo->BaseLevel);
451
452 // if base level is greater than spell level, reduce by base level (eg. pilgrims foods)
453 level -= int32(std::max(_spellInfo->BaseLevel, _spellInfo->SpellLevel));
454 basePoints += int32(level * basePointsPerLevel);
455 }
456
457 // roll in a range <1;EffectDieSides> as of patch 3.3.3
458 switch (randomPoints)
459 {
460 case 0: break;
461 case 1: basePoints += 1; break; // range 1..1
462 default:
463 // range can have positive (1..rand) and negative (rand..1) values, so order its for irand
464 int32 randvalue = (randomPoints >= 1)
465 ? irand(1, randomPoints)
466 : irand(randomPoints, 1);
467
468 basePoints += randvalue;
469 break;
470 }
471
472 float value = float(basePoints);
473
474 // random damage
475 if (casterUnit)
476 {
477 // bonus amount from combo points
478 if (uint8 comboPoints = casterUnit->GetComboPoints())
479 value += PointsPerComboPoint * comboPoints;
480 }
481
482 if (caster)
483 value = caster->ApplyEffectModifiers(_spellInfo, EffectIndex, value);
484
485 if (casterUnit)
486 {
487 // amount multiplication based on caster's level
488 if (!casterUnit->IsControlledByPlayer() &&
489 _spellInfo->SpellLevel && _spellInfo->SpellLevel != casterUnit->GetLevel() &&
491 {
492 bool canEffectScale = false;
493 switch (Effect)
494 {
507 canEffectScale = true;
508 break;
509 default:
510 break;
511 }
512
513 switch (ApplyAuraName)
514 {
516 case SPELL_AURA_DUMMY:
524 canEffectScale = true;
525 break;
526 default:
527 break;
528 }
529
530 if (canEffectScale)
531 {
532 GtNPCManaCostScalerEntry const* spellScaler = sGtNPCManaCostScalerStore.LookupEntry(_spellInfo->SpellLevel - 1);
533 GtNPCManaCostScalerEntry const* casterScaler = sGtNPCManaCostScalerStore.LookupEntry(casterUnit->GetLevel() - 1);
534 if (spellScaler && casterScaler)
535 value *= casterScaler->Data / spellScaler->Data;
536 }
537 }
538 }
539
540 return int32(value);
541}
542
544{
545 if (DieSides == 0)
546 return value;
547 else
548 return value - 1;
549}
550
551float SpellEffectInfo::CalcValueMultiplier(WorldObject* caster, Spell* spell /*= nullptr*/) const
552{
553 float multiplier = Amplitude;
554 if (Player* modOwner = (caster ? caster->GetSpellModOwner() : nullptr))
555 modOwner->ApplySpellMod(_spellInfo->Id, SPELLMOD_VALUE_MULTIPLIER, multiplier, spell);
556
557 return multiplier;
558}
559
560float SpellEffectInfo::CalcDamageMultiplier(WorldObject* caster, Spell* spell /*= nullptr*/) const
561{
562 float multiplierPercent = ChainAmplitude * 100.0f;
563 if (Player* modOwner = (caster ? caster->GetSpellModOwner() : nullptr))
564 modOwner->ApplySpellMod(_spellInfo->Id, SPELLMOD_DAMAGE_MULTIPLIER, multiplierPercent, spell);
565
566 return multiplierPercent / 100.0f;
567}
568
570{
571 return RadiusEntry != nullptr;
572}
573
574float SpellEffectInfo::CalcRadius(WorldObject* caster /*= nullptr*/, Spell* spell /*= nullptr*/) const
575{
576 if (!HasRadius())
577 return 0.0f;
578
579 float radius = RadiusEntry->Radius;
580 if (caster)
581 {
582 if (Unit* casterUnit = caster->ToUnit())
583 radius += RadiusEntry->RadiusPerLevel * casterUnit->GetLevel();
584
585 radius = std::min(radius, RadiusEntry->RadiusMax);
586
587 if (Player* modOwner = caster->GetSpellModOwner())
588 modOwner->ApplySpellMod(_spellInfo->Id, SPELLMOD_RADIUS, radius, spell);
589 }
590
591 return radius;
592}
593
598
599uint32 SpellEffectInfo::GetMissingTargetMask(bool srcSet /*= false*/, bool dstSet /*= false*/, uint32 mask /*=0*/) const
600{
601 uint32 effImplicitTargetMask = GetTargetFlagMask(GetUsedTargetObjectType());
602 uint32 providedTargetMask = GetProvidedTargetMask() | mask;
603
604 // remove all flags covered by effect target mask
605 if (providedTargetMask & TARGET_FLAG_UNIT_MASK)
606 effImplicitTargetMask &= ~(TARGET_FLAG_UNIT_MASK);
607 if (providedTargetMask & TARGET_FLAG_CORPSE_MASK)
608 effImplicitTargetMask &= ~(TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK);
609 if (providedTargetMask & TARGET_FLAG_GAMEOBJECT_ITEM)
611 if (providedTargetMask & TARGET_FLAG_GAMEOBJECT)
612 effImplicitTargetMask &= ~(TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM);
613 if (providedTargetMask & TARGET_FLAG_ITEM)
614 effImplicitTargetMask &= ~(TARGET_FLAG_ITEM | TARGET_FLAG_GAMEOBJECT_ITEM);
615 if (dstSet || providedTargetMask & TARGET_FLAG_DEST_LOCATION)
616 effImplicitTargetMask &= ~(TARGET_FLAG_DEST_LOCATION);
617 if (srcSet || providedTargetMask & TARGET_FLAG_SOURCE_LOCATION)
618 effImplicitTargetMask &= ~(TARGET_FLAG_SOURCE_LOCATION);
619
620 return effImplicitTargetMask;
621}
622
627
629{
630 return _data[Effect].UsedTargetObjectType;
631}
632
633std::array<SpellEffectInfo::StaticData, TOTAL_SPELL_EFFECTS> SpellEffectInfo::_data =
634{ {
635 // implicit target type used target object type
637 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 1 SPELL_EFFECT_INSTAKILL
638 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 2 SPELL_EFFECT_SCHOOL_DAMAGE
639 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 3 SPELL_EFFECT_DUMMY
640 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 4 SPELL_EFFECT_PORTAL_TELEPORT
641 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 5 SPELL_EFFECT_TELEPORT_UNITS
642 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 6 SPELL_EFFECT_APPLY_AURA
643 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 7 SPELL_EFFECT_ENVIRONMENTAL_DAMAGE
644 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 8 SPELL_EFFECT_POWER_DRAIN
645 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 9 SPELL_EFFECT_HEALTH_LEECH
648 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 12 SPELL_EFFECT_PORTAL
649 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 13 SPELL_EFFECT_RITUAL_BASE
650 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 14 SPELL_EFFECT_RITUAL_SPECIALIZE
651 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 15 SPELL_EFFECT_RITUAL_ACTIVATE_PORTAL
652 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 16 SPELL_EFFECT_QUEST_COMPLETE
653 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 17 SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
655 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 19 SPELL_EFFECT_ADD_EXTRA_ATTACKS
656 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 20 SPELL_EFFECT_DODGE
657 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 21 SPELL_EFFECT_EVADE
658 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 22 SPELL_EFFECT_PARRY
659 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 23 SPELL_EFFECT_BLOCK
660 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 24 SPELL_EFFECT_CREATE_ITEM
661 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 25 SPELL_EFFECT_WEAPON
662 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 26 SPELL_EFFECT_DEFENSE
663 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 27 SPELL_EFFECT_PERSISTENT_AREA_AURA
664 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 28 SPELL_EFFECT_SUMMON
666 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 30 SPELL_EFFECT_ENERGIZE
667 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 31 SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
668 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 32 SPELL_EFFECT_TRIGGER_MISSILE
670 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 34 SPELL_EFFECT_SUMMON_CHANGE_ITEM
671 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 35 SPELL_EFFECT_APPLY_AREA_AURA_PARTY
672 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 36 SPELL_EFFECT_LEARN_SPELL
673 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 37 SPELL_EFFECT_SPELL_DEFENSE
674 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 38 SPELL_EFFECT_DISPEL
675 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 39 SPELL_EFFECT_LANGUAGE
676 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 40 SPELL_EFFECT_DUAL_WIELD
678 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 42 SPELL_EFFECT_JUMP_DEST
679 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 43 SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
680 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 44 SPELL_EFFECT_SKILL_STEP
681 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 45 SPELL_EFFECT_ADD_HONOR
682 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 46 SPELL_EFFECT_SPAWN
683 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 47 SPELL_EFFECT_TRADE_SKILL
684 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 48 SPELL_EFFECT_STEALTH
685 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 49 SPELL_EFFECT_DETECT
686 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 50 SPELL_EFFECT_TRANS_DOOR
687 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 51 SPELL_EFFECT_FORCE_CRITICAL_HIT
688 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 52 SPELL_EFFECT_GUARANTEE_HIT
689 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 53 SPELL_EFFECT_ENCHANT_ITEM
690 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 54 SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
691 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 55 SPELL_EFFECT_TAMECREATURE
692 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 56 SPELL_EFFECT_SUMMON_PET
693 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 57 SPELL_EFFECT_LEARN_PET_SPELL
694 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 58 SPELL_EFFECT_WEAPON_DAMAGE
695 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 59 SPELL_EFFECT_CREATE_RANDOM_ITEM
696 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 60 SPELL_EFFECT_PROFICIENCY
697 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 61 SPELL_EFFECT_SEND_EVENT
698 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 62 SPELL_EFFECT_POWER_BURN
699 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 63 SPELL_EFFECT_THREAT
700 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 64 SPELL_EFFECT_TRIGGER_SPELL
701 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 65 SPELL_EFFECT_APPLY_AREA_AURA_RAID
702 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 66 SPELL_EFFECT_CREATE_MANA_GEM
703 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 67 SPELL_EFFECT_HEAL_MAX_HEALTH
704 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 68 SPELL_EFFECT_INTERRUPT_CAST
707 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 71 SPELL_EFFECT_PICKPOCKET
708 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 72 SPELL_EFFECT_ADD_FARSIGHT
709 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 73 SPELL_EFFECT_UNTRAIN_TALENTS
710 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 74 SPELL_EFFECT_APPLY_GLYPH
711 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 75 SPELL_EFFECT_HEAL_MECHANICAL
712 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 76 SPELL_EFFECT_SUMMON_OBJECT_WILD
713 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 77 SPELL_EFFECT_SCRIPT_EFFECT
714 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 78 SPELL_EFFECT_ATTACK
715 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 79 SPELL_EFFECT_SANCTUARY
716 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 80 SPELL_EFFECT_ADD_COMBO_POINTS
717 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 81 SPELL_EFFECT_CREATE_HOUSE
718 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 82 SPELL_EFFECT_BIND_SIGHT
720 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 84 SPELL_EFFECT_STUCK
721 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 85 SPELL_EFFECT_SUMMON_PLAYER
722 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 86 SPELL_EFFECT_ACTIVATE_OBJECT
723 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 87 SPELL_EFFECT_GAMEOBJECT_DAMAGE
724 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 88 SPELL_EFFECT_GAMEOBJECT_REPAIR
725 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 89 SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
726 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 90 SPELL_EFFECT_KILL_CREDIT
727 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 91 SPELL_EFFECT_THREAT_ALL
728 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM
729 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 93 SPELL_EFFECT_FORCE_DESELECT
730 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 94 SPELL_EFFECT_SELF_RESURRECT
731 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 95 SPELL_EFFECT_SKINNING
732 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 96 SPELL_EFFECT_CHARGE
733 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 97 SPELL_EFFECT_CAST_BUTTON
734 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 98 SPELL_EFFECT_KNOCK_BACK
735 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 99 SPELL_EFFECT_DISENCHANT
736 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 100 SPELL_EFFECT_INEBRIATE
737 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 101 SPELL_EFFECT_FEED_PET
738 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 102 SPELL_EFFECT_DISMISS_PET
739 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 103 SPELL_EFFECT_REPUTATION
740 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 104 SPELL_EFFECT_SUMMON_OBJECT_SLOT1
741 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 105 SPELL_EFFECT_SUMMON_OBJECT_SLOT2
742 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 106 SPELL_EFFECT_SUMMON_OBJECT_SLOT3
743 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 107 SPELL_EFFECT_SUMMON_OBJECT_SLOT4
744 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 108 SPELL_EFFECT_DISPEL_MECHANIC
745 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 109 SPELL_EFFECT_SUMMON_DEAD_PET
746 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 110 SPELL_EFFECT_DESTROY_ALL_TOTEMS
747 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 111 SPELL_EFFECT_DURABILITY_DAMAGE
749 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_CORPSE_ALLY}, // 113 SPELL_EFFECT_RESURRECT_NEW
750 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 114 SPELL_EFFECT_ATTACK_ME
751 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 115 SPELL_EFFECT_DURABILITY_DAMAGE_PCT
752 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_CORPSE_ENEMY}, // 116 SPELL_EFFECT_SKIN_PLAYER_CORPSE
753 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 117 SPELL_EFFECT_SPIRIT_HEAL
754 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 118 SPELL_EFFECT_SKILL
755 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 119 SPELL_EFFECT_APPLY_AREA_AURA_PET
756 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 120 SPELL_EFFECT_TELEPORT_GRAVEYARD
757 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 121 SPELL_EFFECT_NORMALIZED_WEAPON_DMG
758 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 122 SPELL_EFFECT_122
759 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 123 SPELL_EFFECT_SEND_TAXI
760 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 124 SPELL_EFFECT_PULL_TOWARDS
761 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 125 SPELL_EFFECT_MODIFY_THREAT_PERCENT
762 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 126 SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
763 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 127 SPELL_EFFECT_PROSPECTING
764 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 128 SPELL_EFFECT_APPLY_AREA_AURA_FRIEND
765 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
766 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 130 SPELL_EFFECT_REDIRECT_THREAT
767 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 131 SPELL_EFFECT_PLAY_SOUND
768 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 132 SPELL_EFFECT_PLAY_MUSIC
769 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 133 SPELL_EFFECT_UNLEARN_SPECIALIZATION
770 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 134 SPELL_EFFECT_KILL_CREDIT2
771 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 135 SPELL_EFFECT_CALL_PET
772 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 136 SPELL_EFFECT_HEAL_PCT
773 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 137 SPELL_EFFECT_ENERGIZE_PCT
774 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 138 SPELL_EFFECT_LEAP_BACK
775 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 139 SPELL_EFFECT_CLEAR_QUEST
776 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 140 SPELL_EFFECT_FORCE_CAST
777 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 141 SPELL_EFFECT_FORCE_CAST_WITH_VALUE
778 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
779 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER
780 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 144 SPELL_EFFECT_KNOCK_BACK_DEST
781 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 145 SPELL_EFFECT_PULL_TOWARDS_DEST
782 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 146 SPELL_EFFECT_ACTIVATE_RUNE
783 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 147 SPELL_EFFECT_QUEST_FAIL
784 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 148 SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
785 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 149 SPELL_EFFECT_CHARGE_DEST
786 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 150 SPELL_EFFECT_QUEST_START
787 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 151 SPELL_EFFECT_TRIGGER_SPELL_2
788 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 152 SPELL_EFFECT_SUMMON_RAF_FRIEND
789 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 153 SPELL_EFFECT_CREATE_TAMED_PET
790 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 154 SPELL_EFFECT_DISCOVER_TAXI
791 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 155 SPELL_EFFECT_TITAN_GRIP
792 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 156 SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
793 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 157 SPELL_EFFECT_CREATE_ITEM_2
794 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 158 SPELL_EFFECT_MILLING
795 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 159 SPELL_EFFECT_ALLOW_RENAME_PET
796 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 160 SPELL_EFFECT_FORCE_CAST_2
797 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 161 SPELL_EFFECT_TALENT_SPEC_COUNT
798 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 162 SPELL_EFFECT_TALENT_SPEC_SELECT
800 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 164 SPELL_EFFECT_REMOVE_AURA
801} };
802
804{
805 Id = spellEntry->ID;
806 CategoryEntry = spellEntry->Category ? sSpellCategoryStore.LookupEntry(spellEntry->Category) : nullptr;
807 Dispel = spellEntry->DispelType;
808 Mechanic = spellEntry->Mechanic;
809 Attributes = spellEntry->Attributes;
810 AttributesEx = spellEntry->AttributesEx;
811 AttributesEx2 = spellEntry->AttributesExB;
812 AttributesEx3 = spellEntry->AttributesExC;
813 AttributesEx4 = spellEntry->AttributesExD;
814 AttributesEx5 = spellEntry->AttributesExE;
815 AttributesEx6 = spellEntry->AttributesExF;
816 AttributesEx7 = spellEntry->AttributesExG;
817 AttributesCu = 0;
818 Stances = MAKE_PAIR64(spellEntry->ShapeshiftMask[0], spellEntry->ShapeshiftMask[1]);
819 StancesNot = MAKE_PAIR64(spellEntry->ShapeshiftExclude[0], spellEntry->ShapeshiftExclude[1]);
820 Targets = spellEntry->Targets;
824 CasterAuraState = spellEntry->CasterAuraState;
825 TargetAuraState = spellEntry->TargetAuraState;
828 CasterAuraSpell = spellEntry->CasterAuraSpell;
829 TargetAuraSpell = spellEntry->TargetAuraSpell;
832 CastTimeEntry = spellEntry->CastingTimeIndex ? sSpellCastTimesStore.LookupEntry(spellEntry->CastingTimeIndex) : nullptr;
833 RecoveryTime = spellEntry->RecoveryTime;
837 InterruptFlags = spellEntry->InterruptFlags;
840 ProcFlags = spellEntry->ProcTypeMask;
841 ProcChance = spellEntry->ProcChance;
842 ProcCharges = spellEntry->ProcCharges;
843 MaxLevel = spellEntry->MaxLevel;
844 BaseLevel = spellEntry->BaseLevel;
845 SpellLevel = spellEntry->SpellLevel;
846 DurationEntry = spellEntry->DurationIndex ? sSpellDurationStore.LookupEntry(spellEntry->DurationIndex) : nullptr;
847 PowerType = static_cast<Powers>(spellEntry->PowerType);
848 ManaCost = spellEntry->ManaCost;
850 ManaPerSecond = spellEntry->ManaPerSecond;
852 ManaCostPercentage = spellEntry->ManaCostPct;
853 RuneCostID = spellEntry->RuneCostID;
854 RangeEntry = spellEntry->RangeIndex ? sSpellRangeStore.LookupEntry(spellEntry->RangeIndex) : nullptr;
855 Speed = spellEntry->Speed;
856 StackAmount = spellEntry->CumulativeAura;
857 Totem = spellEntry->Totem;
858 Reagent = spellEntry->Reagent;
859 ReagentCount = spellEntry->ReagentCount;
864 SpellVisual = spellEntry->SpellVisualID;
865 SpellIconID = spellEntry->SpellIconID;
866 ActiveIconID = spellEntry->ActiveIconID;
867 Priority = spellEntry->SpellPriority;
868 SpellName = spellEntry->Name;
869 Rank = spellEntry->NameSubtext;
870 MaxTargetLevel = spellEntry->MaxTargetLevel;
871 MaxAffectedTargets = spellEntry->MaxTargets;
872 SpellFamilyName = spellEntry->SpellClassSet;
873 SpellFamilyFlags = spellEntry->SpellClassMask;
874 DmgClass = spellEntry->DefenseType;
875 PreventionType = spellEntry->PreventionType;
876 RequiredAreasID = spellEntry->RequiredAreasID;
877 SchoolMask = spellEntry->SchoolMask;
878 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
879 _effects[i] = SpellEffectInfo(spellEntry, this, i);
880
881 ChainEntry = nullptr;
883
886
888}
889
894
896{
897 return CategoryEntry ? CategoryEntry->ID : 0;
898}
899
901{
902 for (SpellEffectInfo const& eff : GetEffects())
903 if (eff.IsEffect(effect))
904 return true;
905
906 return false;
907}
908
910{
911 for (SpellEffectInfo const& effect : GetEffects())
912 if (effect.IsAura(aura))
913 return true;
914
915 return false;
916}
917
919{
920 for (SpellEffectInfo const& effect : GetEffects())
921 if (effect.IsAreaAuraEffect())
922 return true;
923
924 return false;
925}
926
928{
929 for (SpellEffectInfo const& effect : GetEffects())
930 {
931 if (effect.IsEffect())
932 {
933 switch (effect.Effect)
934 {
942 continue;
943 default:
944 return false;
945 }
946 }
947 }
948
949 return true;
950}
951
959
961{
963 // different random cards from Inscription (121==Virtuoso Inking Set category) r without explicit item
965 ((TotemCategory[0] != 0 || (Totem[0] != 0 && SpellIconID == 1)) || GetEffect(EFFECT_0).ItemType == 0)));
966}
967
969{
970 for (SpellEffectInfo const& effect : GetEffects())
971 {
972 if (effect.Effect == SPELL_EFFECT_SKILL)
973 {
974 uint32 skill = effect.MiscValue;
975
976 if (IsProfessionOrRidingSkill(skill))
977 return true;
978 }
979 }
980 return false;
981}
982
984{
985 for (SpellEffectInfo const& effect : GetEffects())
986 {
987 if (effect.Effect == SPELL_EFFECT_SKILL)
988 {
989 uint32 skill = effect.MiscValue;
990
991 if (IsProfessionSkill(skill))
992 return true;
993 }
994 }
995 return false;
996}
997
999{
1000 for (SpellEffectInfo const& effect : GetEffects())
1001 {
1002 if (effect.Effect == SPELL_EFFECT_SKILL)
1003 {
1004 uint32 skill = effect.MiscValue;
1005
1006 if (IsPrimaryProfessionSkill(skill))
1007 return true;
1008 }
1009 }
1010 return false;
1011}
1012
1014{
1015 return IsPrimaryProfession() && GetRank() == 1;
1016}
1017
1019{
1020 SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(Id);
1021
1022 for (SkillLineAbilityMap::const_iterator _spell_idx = bounds.first; _spell_idx != bounds.second; ++_spell_idx)
1023 {
1024 SkillLineAbilityEntry const* pAbility = _spell_idx->second;
1025 if (!pAbility || pAbility->AcquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_VALUE)
1026 continue;
1027
1028 if (pAbility->MinSkillLineRank > 0)
1029 return true;
1030 }
1031
1032 return false;
1033}
1034
1036{
1037 SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(Id);
1038
1039 for (SkillLineAbilityMap::const_iterator _spell_idx = bounds.first; _spell_idx != bounds.second; ++_spell_idx)
1040 if (_spell_idx->second->SkillLine == uint32(skillType))
1041 return true;
1042
1043 return false;
1044}
1045
1047{
1048 for (SpellEffectInfo const& effect : GetEffects())
1049 if (effect.IsEffect() && (effect.IsTargetingArea() || effect.IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) || effect.IsAreaAuraEffect()))
1050 return true;
1051 return false;
1052}
1053
1054// checks if spell targets are selected from area, doesn't include spell effects in check (like area wide auras for example)
1056{
1057 for (SpellEffectInfo const& effect : GetEffects())
1058 if (effect.IsEffect() && effect.IsTargetingArea())
1059 return true;
1060 return false;
1061}
1062
1067
1068bool SpellInfo::NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell) const
1069{
1071 return true;
1072
1073 /*
1074 for (SpellEffectInfo const& effect : GetEffects())
1075 {
1076 if (effect.IsEffect())
1077 {
1078 if (effect.TargetA.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CHANNEL
1079 || effect.TargetB.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CHANNEL)
1080 return true;
1081 }
1082 }
1083 */
1084
1085 if (triggeringSpell->IsChanneled())
1086 {
1087 uint32 mask = 0;
1088 for (SpellEffectInfo const& effect : GetEffects())
1089 {
1090 if (effect.TargetA.GetTarget() != TARGET_UNIT_CASTER && effect.TargetA.GetTarget() != TARGET_DEST_CASTER
1091 && effect.TargetB.GetTarget() != TARGET_UNIT_CASTER && effect.TargetB.GetTarget() != TARGET_DEST_CASTER)
1092 {
1093 mask |= effect.GetProvidedTargetMask();
1094 }
1095 }
1096
1097 if (mask & TARGET_FLAG_UNIT_MASK)
1098 return true;
1099 }
1100
1101 return false;
1102}
1103
1105{
1106 for (SpellEffectInfo const& effect : GetEffects())
1107 if (effect.Effect && effect.TargetA.GetTarget() != TARGET_UNIT_CASTER)
1108 return false;
1109 return true;
1110}
1111
1113{
1115}
1116
1118{
1119 if (IsPassive())
1120 return false;
1122 return false;
1123 return true;
1124}
1125
1127{
1128 if (IsPassive())
1129 return false;
1131 return false;
1133 return false;
1134
1136 return false;
1137
1138 // All stance spells. if any better way, change it.
1139 switch (SpellFamilyName)
1140 {
1142 // Paladin aura Spell
1144 return false;
1145 // Seal of Righteousness
1146 if (SpellFamilyFlags[1] & 0x20000000)
1147 return false;
1148 break;
1149 case SPELLFAMILY_DRUID:
1150 // Druid form Spell
1152 return false;
1153 break;
1154 }
1155
1156 return true;
1157}
1158
1163
1165{
1166 return IsPassive() || Id == 55849 || Id == 40075 || Id == 44413; // Power Spark, Fel Flak Fire, Incanter's Absorption
1167}
1168
1174
1182
1187
1192
1197
1199{
1200 for (SpellEffectInfo const& effect : GetEffects())
1201 {
1202 switch (effect.TargetA.GetCheckType())
1203 {
1204 case TARGET_CHECK_PARTY:
1205 case TARGET_CHECK_RAID:
1207 return true;
1208 default:
1209 break;
1210 }
1211 }
1212
1213 return false;
1214}
1215
1220
1222{
1224}
1225
1227{
1228 switch (effIndex)
1229 {
1230 default:
1231 case 0:
1233 case 1:
1235 case 2:
1237 }
1238}
1239
1244
1249
1254
1259
1264
1266{
1267 return (SpellFamilyName == SPELLFAMILY_HUNTER && !(SpellFamilyFlags[1] & 0x10000000)) // for 53352, cannot find better way
1270}
1271
1276
1281
1283{
1284 WeaponAttackType result;
1285 switch (DmgClass)
1286 {
1289 result = OFF_ATTACK;
1290 else
1291 result = BASE_ATTACK;
1292 break;
1295 break;
1296 default:
1297 // Wands
1299 result = RANGED_ATTACK;
1300 else
1301 result = BASE_ATTACK;
1302 break;
1303 }
1304
1305 return result;
1306}
1307
1309{
1310 // item neutral spell
1311 if (EquippedItemClass == -1)
1312 return true;
1313
1314 // item dependent spell
1315 if (item && item->IsFitToSpellRequirements(this))
1316 return true;
1317
1318 return false;
1319}
1320
1321bool SpellInfo::IsAffected(uint32 familyName, flag96 const& familyFlags) const
1322{
1323 if (!familyName)
1324 return true;
1325
1326 if (familyName != SpellFamilyName)
1327 return false;
1328
1329 if (familyFlags && !(familyFlags & SpellFamilyFlags))
1330 return false;
1331
1332 return true;
1333}
1334
1339
1341{
1342 if (!IsAffectedBySpellMods())
1343 return false;
1344
1345 SpellInfo const* affectSpell = sSpellMgr->GetSpellInfo(mod->spellId);
1346 if (!affectSpell)
1347 return false;
1348
1349 return IsAffected(affectSpell->SpellFamilyName, mod->mask);
1350}
1351
1352bool SpellInfo::CanPierceImmuneAura(SpellInfo const* auraSpellInfo) const
1353{
1354 // aura can't be pierced
1355 if (!auraSpellInfo || auraSpellInfo->HasAttribute(SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY))
1356 return false;
1357
1358 // these spells pierce all available spells (Resurrection Sickness for example)
1360 return true;
1361
1362 // these spells (Cyclone for example) can pierce all...
1364 {
1365 // ...but not these (Divine shield, Ice block, Cyclone and Banish for example)
1366 if (auraSpellInfo->Mechanic != MECHANIC_IMMUNE_SHIELD &&
1367 auraSpellInfo->Mechanic != MECHANIC_INVULNERABILITY &&
1368 auraSpellInfo->Mechanic != MECHANIC_BANISH)
1369 return true;
1370 }
1371
1372 // Dispels other auras on immunity, check if this spell makes the unit immune to aura
1374 return true;
1375
1376 return false;
1377}
1378
1379bool SpellInfo::CanDispelAura(SpellInfo const* auraSpellInfo) const
1380{
1381 // These auras (like Divine Shield) can't be dispelled
1383 return false;
1384
1385 // These spells (like Mass Dispel) can dispel all auras
1387 return true;
1388
1389 // These auras (Cyclone for example) are not dispelable
1390 if ((auraSpellInfo->HasAttribute(SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE) && auraSpellInfo->Mechanic != MECHANIC_NONE)
1392 return false;
1393
1394 return true;
1395}
1396
1398{
1399 // all other single target spells have if it has AttributesEx5
1401 return true;
1402
1403 return false;
1404}
1405
1407{
1408 SpellSpecificType spellSpec1 = GetSpellSpecific();
1409 SpellSpecificType spellSpec2 = spellInfo->GetSpellSpecific();
1410 switch (spellSpec1)
1411 {
1423 return spellSpec1 == spellSpec2;
1425 return spellSpec2 == SPELL_SPECIFIC_FOOD
1426 || spellSpec2 == SPELL_SPECIFIC_FOOD_AND_DRINK;
1428 return spellSpec2 == SPELL_SPECIFIC_DRINK
1429 || spellSpec2 == SPELL_SPECIFIC_FOOD_AND_DRINK;
1431 return spellSpec2 == SPELL_SPECIFIC_FOOD
1432 || spellSpec2 == SPELL_SPECIFIC_DRINK
1433 || spellSpec2 == SPELL_SPECIFIC_FOOD_AND_DRINK;
1434 default:
1435 return false;
1436 }
1437}
1438
1440{
1441 SpellSpecificType spellSpec = GetSpellSpecific();
1442 switch (spellSpec)
1443 {
1452 return spellSpec == spellInfo->GetSpellSpecific();
1453 default:
1454 return false;
1455 }
1456}
1457
1459{
1460 // talents that learn spells can have stance requirements that need ignore
1461 // (this requirement only for client-side stance show in talent description)
1463 return SPELL_CAST_OK;
1464
1465 uint64 stanceMask = (form ? UI64LIT(1) << (form - 1) : 0);
1466
1467 if (stanceMask & StancesNot) // can explicitly not be cast in this stance
1469
1470 if (stanceMask & Stances) // can explicitly be cast in this stance
1471 return SPELL_CAST_OK;
1472
1473 bool actAsShifted = false;
1474 SpellShapeshiftFormEntry const* shapeInfo = nullptr;
1475 if (form > 0)
1476 {
1477 shapeInfo = sSpellShapeshiftFormStore.LookupEntry(form);
1478 if (!shapeInfo)
1479 {
1480 TC_LOG_ERROR("spells", "GetErrorAtShapeshiftedCast: unknown shapeshift {}", form);
1481 return SPELL_CAST_OK;
1482 }
1483 actAsShifted = !(shapeInfo->Flags & 1); // shapeshift acts as normal form for spells
1484 }
1485
1486 if (actAsShifted)
1487 {
1488 if (HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFT)) // not while shapeshifted
1490 else if (Stances != 0) // needs other shapeshift
1492 }
1493 else
1494 {
1495 // needs shapeshift
1498 }
1499
1500 // Check if stance disables cast of not-stance spells
1501 // Example: cannot cast any other spells in zombie or ghoul form
1503 if (shapeInfo && shapeInfo->Flags & 0x400)
1504 {
1505 if (!(stanceMask & Stances))
1507 }
1508
1509 return SPELL_CAST_OK;
1510}
1511
1512SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player /*= nullptr*/, bool strict /*= true*/) const
1513{
1514 // normal case
1515 if (RequiredAreasID > 0)
1516 {
1517 bool found = false;
1518 AreaGroupEntry const* groupEntry = sAreaGroupStore.LookupEntry(RequiredAreasID);
1519 while (groupEntry)
1520 {
1521 for (uint8 i = 0; i < MAX_GROUP_AREA_IDS; ++i)
1522 if (groupEntry->AreaID[i] == zone_id || groupEntry->AreaID[i] == area_id)
1523 found = true;
1524 if (found || !groupEntry->NextAreaID)
1525 break;
1526 // Try search in next group
1527 groupEntry = sAreaGroupStore.LookupEntry(groupEntry->NextAreaID);
1528 }
1529
1530 if (!found)
1532 }
1533
1534 // continent limitation (virtual continent)
1536 {
1537 if (strict)
1538 {
1539 AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(area_id);
1540 if (!areaEntry)
1541 areaEntry = sAreaTableStore.LookupEntry(zone_id);
1542
1543 if (!areaEntry || !areaEntry->IsFlyable() || !player->CanFlyInZone(map_id, zone_id, this))
1545 }
1546 else
1547 {
1548 uint32 const v_map = GetVirtualMapForMapAndZone(map_id, zone_id);
1549 MapEntry const* mapEntry = sMapStore.LookupEntry(v_map);
1550 if (!mapEntry || mapEntry->Expansion() < 1 || !mapEntry->IsContinent())
1552 }
1553 }
1554
1555 // raid instance limitation
1557 {
1558 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
1559 if (!mapEntry || mapEntry->IsRaid())
1561 }
1562
1563 // DB base check (if non empty then must fit at least single for allow)
1564 SpellAreaMapBounds saBounds = sSpellMgr->GetSpellAreaMapBounds(Id);
1565 if (saBounds.first != saBounds.second)
1566 {
1567 for (SpellAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
1568 {
1569 if (itr->second.IsFitToRequirements(player, zone_id, area_id))
1570 return SPELL_CAST_OK;
1571 }
1573 }
1574
1575 // bg spell checks
1576 switch (Id)
1577 {
1578 case 23333: // Warsong Flag
1579 case 23335: // Silverwing Flag
1580 return map_id == 489 && player && player->InBattleground() ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
1581 case 34976: // Netherstorm Flag
1582 return map_id == 566 && player && player->InBattleground() ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
1583 case 2584: // Waiting to Resurrect
1584 case 22011: // Spirit Heal Channel
1585 case 22012: // Spirit Heal
1586 case 42792: // Recently Dropped Flag
1587 case 43681: // Inactive
1588 case 44535: // Spirit Heal (mana)
1589 {
1590 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
1591 if (!mapEntry)
1593
1594 return zone_id == AREA_WINTERGRASP || (mapEntry->IsBattleground() && player && player->InBattleground()) ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
1595 }
1596 case 44521: // Preparation
1597 {
1598 if (!player)
1600
1601 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
1602 if (!mapEntry)
1604
1605 if (!mapEntry->IsBattleground())
1607
1608 Battleground* bg = player->GetBattleground();
1610 }
1611 case 32724: // Gold Team (Alliance)
1612 case 32725: // Green Team (Alliance)
1613 case 35774: // Gold Team (Horde)
1614 case 35775: // Green Team (Horde)
1615 {
1616 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
1617 if (!mapEntry)
1619
1620 return mapEntry->IsBattleArena() && player && player->InBattleground() ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
1621 }
1622 case 32727: // Arena Preparation
1623 {
1624 if (!player)
1626
1627 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
1628 if (!mapEntry)
1630
1631 if (!mapEntry->IsBattleArena())
1633
1634 Battleground* bg = player->GetBattleground();
1636 }
1637 }
1638
1639 return SPELL_CAST_OK;
1640}
1641
1642SpellCastResult SpellInfo::CheckTarget(WorldObject const* caster, WorldObject const* target, bool implicit /*= true*/) const
1643{
1644 if (HasAttribute(SPELL_ATTR1_CANT_TARGET_SELF) && caster == target)
1646
1647 // check visibility - ignore invisibility/stealth for implicit (area) targets
1648 if (!HasAttribute(SPELL_ATTR6_CAN_TARGET_INVISIBLE) && !caster->CanSeeOrDetect(target, implicit))
1650
1651 Unit const* unitTarget = target->ToUnit();
1652
1653 // creature/player specific target checks
1654 if (unitTarget)
1655 {
1656 // spells cannot be cast if target has a pet in combat either
1659
1660 // only spells with SPELL_ATTR3_ONLY_TARGET_GHOSTS can target ghosts
1662 {
1665 else
1667 }
1668
1669 if (caster != unitTarget)
1670 {
1671 if (caster->GetTypeId() == TYPEID_PLAYER)
1672 {
1673 // Do not allow these spells to target creatures not tapped by us (Banish, Polymorph, many quest spells)
1675 if (Creature const* targetCreature = unitTarget->ToCreature())
1676 if (targetCreature->hasLootRecipient() && !targetCreature->isTappedBy(caster->ToPlayer()))
1678
1680 {
1681 if (unitTarget->GetTypeId() == TYPEID_PLAYER)
1683 else if ((unitTarget->GetCreatureTypeMask() & CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD) == 0)
1685 }
1686
1687 // Not allow disarm unarmed player
1689 {
1690 if (unitTarget->GetTypeId() == TYPEID_PLAYER)
1691 {
1692 Player const* player = unitTarget->ToPlayer();
1693 if (!player->GetWeaponForAttack(BASE_ATTACK) || !player->IsUseEquipedWeapon(true))
1695 }
1696 else if (!unitTarget->GetVirtualItemId(0))
1698 }
1699 }
1700 }
1701 }
1702 // corpse specific target checks
1703 else if (Corpse const* corpseTarget = target->ToCorpse())
1704 {
1705 // cannot target bare bones
1706 if (corpseTarget->GetType() == CORPSE_BONES)
1708 // we have to use owner for some checks (aura preventing resurrection for example)
1709 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
1710 unitTarget = owner;
1711 // we're not interested in corpses without owner
1712 else
1714 }
1715 // other types of objects - always valid
1716 else return SPELL_CAST_OK;
1717
1718 // corpseOwner and unit specific target checks
1721
1722 if (!IsAllowingDeadTarget() && !unitTarget->IsAlive())
1724
1725 // check this flag only for implicit targets (chain and area), allow to explicitly target units for spells like Shield of Righteousness
1726 if (implicit && HasAttribute(SPELL_ATTR6_CANT_TARGET_CROWD_CONTROLLED) && !unitTarget->CanFreeMove())
1728
1729 // checked in Unit::IsValidAttack/AssistTarget, shouldn't be checked for ENTRY targets
1730 //if (!HasAttribute(SPELL_ATTR6_CAN_TARGET_UNTARGETABLE) && target->HasUnitFlag(UNIT_FLAG_UNINTERACTIBLE))
1731 // return SPELL_FAILED_BAD_TARGETS;
1732
1733 //if (!HasAttribute(SPELL_ATTR6_CAN_TARGET_POSSESSED_FRIENDS))
1734
1735 if (!CheckTargetCreatureType(unitTarget))
1736 {
1737 if (target->GetTypeId() == TYPEID_PLAYER)
1739 else
1741 }
1742
1743 // check GM mode and GM invisibility - only for player casts (npc casts are controlled by AI) and negative spells
1744 if (unitTarget != caster && (caster->GetAffectingPlayer() || !IsPositive()) && unitTarget->GetTypeId() == TYPEID_PLAYER)
1745 {
1746 if (!unitTarget->ToPlayer()->IsVisible())
1748
1749 if (unitTarget->ToPlayer()->IsGameMaster())
1751 }
1752
1753 // not allow casting on flying player
1756
1757 /* TARGET_UNIT_MASTER gets blocked here for passengers, because the whole idea of this check is to
1758 not allow passengers to be implicitly hit by spells, however this target type should be an exception,
1759 if this is left it kills spells that award kill credit from vehicle to master (few spells),
1760 the use of these 2 covers passenger target check, logically, if vehicle cast this to master it should always hit
1761 him, because it would be it's passenger, there's no such case where this gets to fail legitimacy, this problem
1762 cannot be solved from within the check in other way since target type cannot be called for the spell currently
1763 Spell examples: [ID - 52864 Devour Water, ID - 52862 Devour Wind, ID - 49370 Wyrmrest Defender: Destabilize Azure Dragonshrine Effect] */
1764 if (Unit const* unitCaster = caster->ToUnit())
1765 {
1766 if (!unitCaster->IsVehicle() && !(unitCaster->GetCharmerOrOwner() == target))
1767 {
1768 if (TargetAuraState && !unitTarget->HasAuraState(AuraStateType(TargetAuraState), this, unitCaster))
1770
1771 if (ExcludeTargetAuraState && unitTarget->HasAuraState(AuraStateType(ExcludeTargetAuraState), this, unitCaster))
1773 }
1774 }
1775
1776 if (TargetAuraSpell && !unitTarget->HasAura(sSpellMgr->GetSpellIdForDifficulty(TargetAuraSpell, caster)))
1778
1779 if (ExcludeTargetAuraSpell && unitTarget->HasAura(sSpellMgr->GetSpellIdForDifficulty(ExcludeTargetAuraSpell, caster)))
1781
1785
1786 return SPELL_CAST_OK;
1787}
1788
1789SpellCastResult SpellInfo::CheckExplicitTarget(WorldObject const* caster, WorldObject const* target, Item const* itemTarget /*= nullptr*/) const
1790{
1791 uint32 neededTargets = GetExplicitTargetMask();
1792 if (!target)
1793 {
1795 if (!(neededTargets & TARGET_FLAG_GAMEOBJECT_ITEM) || !itemTarget)
1797 return SPELL_CAST_OK;
1798 }
1799
1800 if (Unit const* unitTarget = target->ToUnit())
1801 {
1803 {
1804 Unit const* unitCaster = caster->ToUnit();
1805 if (neededTargets & TARGET_FLAG_UNIT_ENEMY)
1806 if (caster->IsValidAttackTarget(unitTarget, this))
1807 return SPELL_CAST_OK;
1808 if ((neededTargets & TARGET_FLAG_UNIT_ALLY)
1809 || ((neededTargets & TARGET_FLAG_UNIT_PARTY) && unitCaster && unitCaster->IsInPartyWith(unitTarget))
1810 || ((neededTargets & TARGET_FLAG_UNIT_RAID) && unitCaster && unitCaster->IsInRaidWith(unitTarget)))
1811 if (caster->IsValidAssistTarget(unitTarget, this))
1812 return SPELL_CAST_OK;
1813 if ((neededTargets & TARGET_FLAG_UNIT_MINIPET) && unitCaster)
1814 if (unitTarget->GetGUID() == unitCaster->GetCritterGUID())
1815 return SPELL_CAST_OK;
1816 if ((neededTargets & TARGET_FLAG_UNIT_PASSENGER) && unitCaster)
1817 if (unitTarget->IsOnVehicle(unitCaster))
1818 return SPELL_CAST_OK;
1820 }
1821 }
1822 return SPELL_CAST_OK;
1823}
1824
1826{
1827 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
1828 if (caster->GetTypeId() != TYPEID_PLAYER)
1829 return SPELL_CAST_OK;
1830
1831 Vehicle* vehicle = caster->GetVehicle();
1832 if (vehicle)
1833 {
1834 uint16 checkMask = 0;
1835 for (SpellEffectInfo const& effect : GetEffects())
1836 {
1837 if (effect.IsAura(SPELL_AURA_MOD_SHAPESHIFT))
1838 {
1839 SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effect.MiscValue);
1840 if (shapeShiftEntry && (shapeShiftEntry->Flags & 1) == 0) // unk flag
1841 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
1842 break;
1843 }
1844 }
1845
1848
1849 if (!checkMask)
1850 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
1851
1852 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(caster);
1854 && (vehicleSeat->Flags & checkMask) != checkMask)
1856
1857 // Can only summon uncontrolled minions/guardians when on controlled vehicle
1859 {
1860 for (SpellEffectInfo const& effect : GetEffects())
1861 {
1862 if (!effect.IsEffect(SPELL_EFFECT_SUMMON))
1863 continue;
1864
1865 SummonPropertiesEntry const* props = sSummonPropertiesStore.LookupEntry(effect.MiscValueB);
1866 if (props && props->Control != SUMMON_CATEGORY_WILD)
1868 }
1869 }
1870 }
1871
1872 return SPELL_CAST_OK;
1873}
1874
1876{
1877 // Curse of Doom & Exorcism: not find another way to fix spell target check :/
1879 {
1880 // not allow cast at player
1881 if (target->GetTypeId() == TYPEID_PLAYER)
1882 return false;
1883 else
1884 return true;
1885 }
1886
1887 // if target is magnet (i.e Grounding Totem) the check is skipped
1888 if (target->IsMagnet())
1889 return true;
1890
1891 uint32 creatureType = target->GetCreatureTypeMask();
1892 return !TargetCreatureType || !creatureType || (creatureType & TargetCreatureType);
1893}
1894
1899
1901{
1902 uint32 mask = 0;
1903 if (Mechanic)
1904 mask |= 1 << Mechanic;
1905
1906 for (SpellEffectInfo const& effect : GetEffects())
1907 if (effect.IsEffect() && effect.Mechanic)
1908 mask |= 1 << effect.Mechanic;
1909
1910 return mask;
1911}
1912
1914{
1915 uint32 mask = 0;
1916 if (Mechanic)
1917 mask |= 1 << Mechanic;
1918
1919 if (GetEffect(effIndex).IsEffect() && GetEffect(effIndex).Mechanic)
1920 mask |= 1 << GetEffect(effIndex).Mechanic;
1921
1922 return mask;
1923}
1924
1926{
1927 uint32 mask = 0;
1928 if (Mechanic)
1929 mask |= 1 << Mechanic;
1930
1931 for (SpellEffectInfo const& effect : GetEffects())
1932 if ((effectMask & (1 << effect.EffectIndex)) && effect.Mechanic)
1933 mask |= 1 << effect.Mechanic;
1934
1935 return mask;
1936}
1937
1939{
1940 if (GetEffect(effIndex).IsEffect() && GetEffect(effIndex).Mechanic)
1941 return GetEffect(effIndex).Mechanic;
1942
1943 if (Mechanic)
1944 return Mechanics(Mechanic);
1945
1946 return MECHANIC_NONE;
1947}
1948
1953
1955{
1956 // If dispel all
1957 if (type == DISPEL_ALL)
1958 return DISPEL_ALL_MASK;
1959 else
1960 return uint32(1 << type);
1961}
1962
1967
1969{
1970 return _auraState;
1971}
1972
1974{
1975 _auraState = [this]() -> AuraStateType
1976 {
1977 // Seals
1979 return AURA_STATE_JUDGEMENT;
1980
1981 // Conflagrate aura state on Immolate and Shadowflame
1983 // Immolate
1984 ((SpellFamilyFlags[0] & 4) ||
1985 // Shadowflame
1986 (SpellFamilyFlags[2] & 2)))
1988
1989 // Faerie Fire (druid versions)
1992
1993 // Sting (hunter's pet ability)
1994 if (GetCategory() == 1133)
1996
1997 // Victorious
1998 if (SpellFamilyName == SPELLFAMILY_WARRIOR && SpellFamilyFlags[1] & 0x00040000)
2000
2001 // Swiftmend state on Regrowth & Rejuvenation
2003 return AURA_STATE_SWIFTMEND;
2004
2005 // Deadly poison aura state
2006 if (SpellFamilyName == SPELLFAMILY_ROGUE && SpellFamilyFlags[0] & 0x10000)
2008
2009 // Enrage aura state
2010 if (Dispel == DISPEL_ENRAGE)
2011 return AURA_STATE_ENRAGE;
2012
2013 // Bleeding aura state
2015 return AURA_STATE_BLEEDING;
2016
2018 for (SpellEffectInfo const& effect : GetEffects())
2019 if (effect.IsAura(SPELL_AURA_MOD_STUN) || effect.IsAura(SPELL_AURA_MOD_ROOT))
2020 return AURA_STATE_FROZEN;
2021
2022 switch (Id)
2023 {
2024 case 71465: // Divine Surge
2025 case 50241: // Evasive Charges
2026 return AURA_STATE_UNKNOWN22;
2027 case 9991: // Touch of Zanzil
2028 case 35325: // Glowing Blood
2029 case 35328: // Lambent Blood
2030 case 35329: // Vibrant Blood
2031 case 35331: // Black Blood
2032 case 49163: // Perpetual Instability
2034 default:
2035 break;
2036 }
2037
2038 return AURA_STATE_NONE;
2039 }();
2040}
2041
2046
2048{
2049 _spellSpecific = [this]() -> SpellSpecificType
2050 {
2051 switch (SpellFamilyName)
2052 {
2054 {
2055 // Food / Drinks (mostly)
2057 {
2058 bool food = false;
2059 bool drink = false;
2060 for (SpellEffectInfo const& effect : GetEffects())
2061 {
2062 if (!effect.IsAura())
2063 continue;
2064 switch (effect.ApplyAuraName)
2065 {
2066 // Food
2069 food = true;
2070 break;
2071 // Drink
2074 drink = true;
2075 break;
2076 default:
2077 break;
2078 }
2079 }
2080
2081 if (food && drink)
2083 else if (food)
2084 return SPELL_SPECIFIC_FOOD;
2085 else if (drink)
2086 return SPELL_SPECIFIC_DRINK;
2087 }
2088 // scrolls effects
2089 else
2090 {
2091 SpellInfo const* firstRankSpellInfo = GetFirstRankSpell();
2092 switch (firstRankSpellInfo->Id)
2093 {
2094 case 8118: // Strength
2095 case 8099: // Stamina
2096 case 8112: // Spirit
2097 case 8096: // Intellect
2098 case 8115: // Agility
2099 case 8091: // Armor
2100 return SPELL_SPECIFIC_SCROLL;
2101 default:
2102 break;
2103 }
2104
2105 switch (Id)
2106 {
2107 case 12880: // Enrage (Enrage)
2108 case 14201:
2109 case 14202:
2110 case 14203:
2111 case 14204:
2112 case 57518: // Enrage (Wrecking Crew)
2113 case 57519:
2114 case 57520:
2115 case 57521:
2116 case 57522:
2117 case 57514: // Enrage (Imp. Defensive Stance)
2118 case 57516:
2120 default:
2121 break;
2122 }
2123 }
2124 break;
2125 }
2126 case SPELLFAMILY_MAGE:
2127 {
2128 // family flags 18(Molten), 25(Frost/Ice), 28(Mage)
2129 if (SpellFamilyFlags[0] & 0x12040000)
2131
2132 // Arcane brillance and Arcane intelect (normal check fails because of flags difference)
2133 if (SpellFamilyFlags[0] & 0x400)
2135
2136 if ((SpellFamilyFlags[0] & 0x1000000) && GetEffect(EFFECT_0).IsAura(SPELL_AURA_MOD_CONFUSE))
2138
2139 break;
2140 }
2142 {
2143 if (Id == 12292) // Death Wish
2145
2146 break;
2147 }
2149 {
2150 // only warlock curses have this
2151 if (Dispel == DISPEL_CURSE)
2152 return SPELL_SPECIFIC_CURSE;
2153
2154 // Warlock (Demon Armor | Demon Skin | Fel Armor)
2155 if (SpellFamilyFlags[1] & 0x20000020 || SpellFamilyFlags[2] & 0x00000010)
2157
2158 //seed of corruption and corruption
2159 if (SpellFamilyFlags[1] & 0x10 || SpellFamilyFlags[0] & 0x2)
2161 break;
2162 }
2163 case SPELLFAMILY_PRIEST:
2164 {
2165 // Divine Spirit and Prayer of Spirit
2166 if (SpellFamilyFlags[0] & 0x20)
2168
2169 break;
2170 }
2171 case SPELLFAMILY_HUNTER:
2172 {
2173 // only hunter stings have this
2174 if (Dispel == DISPEL_POISON)
2175 return SPELL_SPECIFIC_STING;
2176
2177 // only hunter aspects have this (but not all aspects in hunter family)
2178 if (SpellFamilyFlags & flag96(0x00380000, 0x00440000, 0x00001010))
2179 return SPELL_SPECIFIC_ASPECT;
2180
2181 break;
2182 }
2184 {
2185 // Collection of all the seal family flags. No other paladin spell has any of those.
2186 if (SpellFamilyFlags[1] & 0x26000C00
2187 || SpellFamilyFlags[0] & 0x0A000000)
2188 return SPELL_SPECIFIC_SEAL;
2189
2190 if (SpellFamilyFlags[0] & 0x00002190)
2191 return SPELL_SPECIFIC_HAND;
2192
2193 // Judgement of Wisdom, Judgement of Light, Judgement of Justice
2194 if (Id == 20184 || Id == 20185 || Id == 20186)
2196
2197 // only paladin auras have this (for palaldin class family)
2198 if (SpellFamilyFlags[2] & 0x00000020)
2199 return SPELL_SPECIFIC_AURA;
2200
2201 break;
2202 }
2203 case SPELLFAMILY_SHAMAN:
2204 {
2205 // family flags 10 (Lightning), 42 (Earth), 37 (Water), proc shield from T2 8 pieces bonus
2206 if (SpellFamilyFlags[1] & 0x420
2207 || SpellFamilyFlags[0] & 0x00000400
2208 || Id == 23552)
2210
2211 break;
2212 }
2214 if (Id == 48266 || Id == 48263 || Id == 48265)
2216 break;
2217 }
2218
2219 for (SpellEffectInfo const& effect : GetEffects())
2220 {
2221 if (effect.IsEffect(SPELL_EFFECT_APPLY_AURA))
2222 {
2223 switch (effect.ApplyAuraName)
2224 {
2229 return SPELL_SPECIFIC_CHARM;
2232 if (Id == 30645) // Gas Cloud Tracking
2233 return SPELL_SPECIFIC_NORMAL;
2234 [[fallthrough]];
2238 default:
2239 break;
2240 }
2241 }
2242 }
2243
2244 return SPELL_SPECIFIC_NORMAL;
2245 }();
2246}
2247
2249{
2250 auto diminishingGroupCompute = [this](bool triggered) -> DiminishingGroup
2251 {
2252 if (IsPositive())
2253 return DIMINISHING_NONE;
2254
2256 return DIMINISHING_TAUNT;
2257
2258 // Explicit Diminishing Groups
2259 switch (SpellFamilyName)
2260 {
2262 {
2263 // Pet charge effects (Infernal Awakening, Demon Charge)
2264 if (SpellVisual[0] == 2816 && SpellIconID == 15)
2266 // Frost Tomb
2267 else if (Id == 48400)
2268 return DIMINISHING_NONE;
2269 // Gnaw
2270 else if (Id == 47481)
2272 // ToC Icehowl Arctic Breath
2273 else if (SpellVisual[0] == 14153)
2274 return DIMINISHING_NONE;
2275 // Black Plague
2276 else if (Id == 64155)
2277 return DIMINISHING_NONE;
2278 // Screams of the Dead (King Ymiron)
2279 else if (Id == 51750)
2280 return DIMINISHING_NONE;
2281 // Crystallize (Keristrasza heroic)
2282 else if (Id == 48179)
2283 return DIMINISHING_NONE;
2284 break;
2285 }
2286 // Event spells
2287 case SPELLFAMILY_UNK1:
2288 return DIMINISHING_NONE;
2289 case SPELLFAMILY_MAGE:
2290 {
2291 // Frostbite
2292 if (SpellFamilyFlags[1] & 0x80000000)
2293 return DIMINISHING_ROOT;
2294 // Shattered Barrier
2295 else if (SpellVisual[0] == 12297)
2296 return DIMINISHING_ROOT;
2297 // Deep Freeze
2298 else if (SpellIconID == 2939 && SpellVisual[0] == 9963)
2300 // Frost Nova / Freeze (Water Elemental)
2301 else if (SpellIconID == 193)
2303 // Dragon's Breath
2304 else if (SpellFamilyFlags[0] & 0x800000)
2306 break;
2307 }
2309 {
2310 // Hamstring - limit duration to 10s in PvP
2311 if (SpellFamilyFlags[0] & 0x2)
2312 return DIMINISHING_LIMITONLY;
2313 // Charge Stun (own diminishing)
2314 else if (SpellFamilyFlags[0] & 0x01000000)
2315 return DIMINISHING_CHARGE;
2316 break;
2317 }
2319 {
2320 // Curses/etc
2321 if ((SpellFamilyFlags[0] & 0x80000000) || (SpellFamilyFlags[1] & 0x200))
2322 return DIMINISHING_LIMITONLY;
2323 // Seduction
2324 else if (SpellFamilyFlags[1] & 0x10000000)
2325 return DIMINISHING_FEAR;
2326 break;
2327 }
2328 case SPELLFAMILY_DRUID:
2329 {
2330 // Pounce
2331 if (SpellFamilyFlags[0] & 0x20000)
2333 // Cyclone
2334 else if (SpellFamilyFlags[1] & 0x20)
2335 return DIMINISHING_CYCLONE;
2336 // Entangling Roots
2337 // Nature's Grasp
2338 else if (SpellFamilyFlags[0] & 0x00000200)
2340 // Faerie Fire
2341 else if (SpellFamilyFlags[0] & 0x400)
2342 return DIMINISHING_LIMITONLY;
2343 break;
2344 }
2345 case SPELLFAMILY_ROGUE:
2346 {
2347 // Gouge
2348 if (SpellFamilyFlags[0] & 0x8)
2349 return DIMINISHING_DISORIENT;
2350 // Blind
2351 else if (SpellFamilyFlags[0] & 0x1000000)
2352 return DIMINISHING_FEAR;
2353 // Cheap Shot
2354 else if (SpellFamilyFlags[0] & 0x400)
2356 // Crippling poison - Limit to 10 seconds in PvP (No SpellFamilyFlags)
2357 else if (SpellIconID == 163)
2358 return DIMINISHING_LIMITONLY;
2359 break;
2360 }
2361 case SPELLFAMILY_HUNTER:
2362 {
2363 // Hunter's Mark
2364 if ((SpellFamilyFlags[0] & 0x400) && SpellIconID == 538)
2365 return DIMINISHING_LIMITONLY;
2366 // Scatter Shot (own diminishing)
2367 else if ((SpellFamilyFlags[0] & 0x40000) && SpellIconID == 132)
2369 // Entrapment (own diminishing)
2370 else if (SpellVisual[0] == 7484 && SpellIconID == 20)
2372 // Wyvern Sting mechanic is MECHANIC_SLEEP but the diminishing is DIMINISHING_DISORIENT
2373 else if ((SpellFamilyFlags[1] & 0x1000) && SpellIconID == 1721)
2374 return DIMINISHING_DISORIENT;
2375 // Freezing Arrow
2376 else if (SpellFamilyFlags[0] & 0x8)
2377 return DIMINISHING_DISORIENT;
2378 break;
2379 }
2381 {
2382 // Judgement of Justice - limit duration to 10s in PvP
2383 if (SpellFamilyFlags[0] & 0x100000)
2384 return DIMINISHING_LIMITONLY;
2385 // Turn Evil
2386 else if ((SpellFamilyFlags[1] & 0x804000) && SpellIconID == 309)
2387 return DIMINISHING_FEAR;
2388 break;
2389 }
2390 case SPELLFAMILY_SHAMAN:
2391 {
2392 // Storm, Earth and Fire - Earthgrab
2393 if (SpellFamilyFlags[2] & 0x4000)
2394 return DIMINISHING_NONE;
2395 break;
2396 }
2398 {
2399 // Hungering Cold (no flags)
2400 if (SpellIconID == 2797)
2401 return DIMINISHING_DISORIENT;
2402 // Mark of Blood
2403 else if ((SpellFamilyFlags[0] & 0x10000000) && SpellIconID == 2285)
2404 return DIMINISHING_LIMITONLY;
2405 break;
2406 }
2407 default:
2408 break;
2409 }
2410
2411 // Lastly - Set diminishing depending on mechanic
2412 uint32 mechanic = GetAllEffectsMechanicMask();
2413 if (mechanic & (1 << MECHANIC_CHARM))
2415 if (mechanic & (1 << MECHANIC_SILENCE))
2416 return DIMINISHING_SILENCE;
2417 if (mechanic & (1 << MECHANIC_SLEEP))
2418 return DIMINISHING_SLEEP;
2419 if (mechanic & ((1 << MECHANIC_SAPPED) | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_SHACKLE)))
2420 return DIMINISHING_DISORIENT;
2421 // Mechanic Knockout, except Blast Wave
2422 if (mechanic & (1 << MECHANIC_KNOCKOUT) && SpellIconID != 292)
2423 return DIMINISHING_DISORIENT;
2424 if (mechanic & (1 << MECHANIC_DISARM))
2425 return DIMINISHING_DISARM;
2426 if (mechanic & (1 << MECHANIC_FEAR))
2427 return DIMINISHING_FEAR;
2428 if (mechanic & (1 << MECHANIC_STUN))
2429 return triggered ? DIMINISHING_STUN : DIMINISHING_CONTROLLED_STUN;
2430 if (mechanic & (1 << MECHANIC_BANISH))
2431 return DIMINISHING_BANISH;
2432 if (mechanic & (1 << MECHANIC_ROOT))
2433 return triggered ? DIMINISHING_ROOT : DIMINISHING_CONTROLLED_ROOT;
2434 if (mechanic & (1 << MECHANIC_HORROR))
2435 return DIMINISHING_HORROR;
2436
2437 return DIMINISHING_NONE;
2438 };
2439
2440 auto diminishingTypeCompute = [](DiminishingGroup group) -> DiminishingReturnsType
2441 {
2442 switch (group)
2443 {
2444 case DIMINISHING_TAUNT:
2446 case DIMINISHING_STUN:
2449 case DIMINISHING_CHARGE:
2450 return DRTYPE_ALL;
2452 case DIMINISHING_NONE:
2453 return DRTYPE_NONE;
2454 default:
2455 return DRTYPE_PLAYER;
2456 }
2457 };
2458
2459 auto diminishingMaxLevelCompute = [](DiminishingGroup group) -> DiminishingLevels
2460 {
2461 switch (group)
2462 {
2463 case DIMINISHING_TAUNT:
2465 default:
2467 }
2468 };
2469
2470 auto diminishingLimitDurationCompute = [this](DiminishingGroup group) -> int32
2471 {
2472 auto isGroupDurationLimited = [group]() -> bool
2473 {
2474 switch (group)
2475 {
2476 case DIMINISHING_BANISH:
2482 case DIMINISHING_FEAR:
2483 case DIMINISHING_HORROR:
2486 case DIMINISHING_ROOT:
2487 case DIMINISHING_STUN:
2488 case DIMINISHING_SLEEP:
2490 return true;
2491 default:
2492 return false;
2493 }
2494 };
2495
2496 if (!isGroupDurationLimited())
2497 return 0;
2498
2499 // Explicit diminishing duration
2500 switch (SpellFamilyName)
2501 {
2502 case SPELLFAMILY_DRUID:
2503 {
2504 // Faerie Fire - limit to 40 seconds in PvP (3.1)
2505 if (SpellFamilyFlags[0] & 0x400)
2506 return 40 * IN_MILLISECONDS;
2507 break;
2508 }
2509 case SPELLFAMILY_HUNTER:
2510 {
2511 // Wyvern Sting
2512 if (SpellFamilyFlags[1] & 0x1000)
2513 return 6 * IN_MILLISECONDS;
2514 // Hunter's Mark
2515 if (SpellFamilyFlags[0] & 0x400)
2516 return 120 * IN_MILLISECONDS;
2517 break;
2518 }
2520 {
2521 // Repentance - limit to 6 seconds in PvP
2522 if (SpellFamilyFlags[0] & 0x4)
2523 return 6 * IN_MILLISECONDS;
2524 break;
2525 }
2527 {
2528 // Banish - limit to 6 seconds in PvP
2529 if (SpellFamilyFlags[1] & 0x8000000)
2530 return 6 * IN_MILLISECONDS;
2531 // Curse of Tongues - limit to 12 seconds in PvP
2532 else if (SpellFamilyFlags[2] & 0x800)
2533 return 12 * IN_MILLISECONDS;
2534 // Curse of Elements - limit to 120 seconds in PvP
2535 else if (SpellFamilyFlags[1] & 0x200)
2536 return 120 * IN_MILLISECONDS;
2537 break;
2538 }
2539 default:
2540 break;
2541 }
2542
2543 return 10 * IN_MILLISECONDS;
2544 };
2545
2546 SpellDiminishInfo triggeredInfo, normalInfo;
2547 triggeredInfo.DiminishGroup = diminishingGroupCompute(true);
2548 triggeredInfo.DiminishReturnType = diminishingTypeCompute(triggeredInfo.DiminishGroup);
2549 triggeredInfo.DiminishMaxLevel = diminishingMaxLevelCompute(triggeredInfo.DiminishGroup);
2550 triggeredInfo.DiminishDurationLimit = diminishingLimitDurationCompute(triggeredInfo.DiminishGroup);
2551
2552 normalInfo.DiminishGroup = diminishingGroupCompute(false);
2553 normalInfo.DiminishReturnType = diminishingTypeCompute(normalInfo.DiminishGroup);
2554 normalInfo.DiminishMaxLevel = diminishingMaxLevelCompute(normalInfo.DiminishGroup);
2555 normalInfo.DiminishDurationLimit = diminishingLimitDurationCompute(normalInfo.DiminishGroup);
2556
2557 _diminishInfoTriggered = triggeredInfo;
2558 _diminishInfoNonTriggered = normalInfo;
2559}
2560
2565
2570
2575
2580
2582{
2583 std::unique_ptr<SpellEffectInfo::ImmunityInfo> workBuffer = std::make_unique<SpellEffectInfo::ImmunityInfo>();
2584
2585 for (SpellEffectInfo& effect : _GetEffects())
2586 {
2587 uint32 schoolImmunityMask = 0;
2588 uint32 applyHarmfulAuraImmunityMask = 0;
2589 uint32 mechanicImmunityMask = 0;
2590 uint32 dispelImmunity = 0;
2591 uint32 damageImmunityMask = 0;
2592 bool removeEffectsWithMechanic = false;
2593
2594 int32 miscVal = effect.MiscValue;
2595 int32 amount = effect.CalcValue();
2596
2597 SpellEffectInfo::ImmunityInfo& immuneInfo = *workBuffer;
2598
2599 switch (effect.ApplyAuraName)
2600 {
2602 {
2603 switch (miscVal)
2604 {
2605 case 96: // Free Friend, Uncontrollable Frenzy, Warlord's Presence
2606 {
2608
2614 break;
2615 }
2616 case 1615: // Incite Rage, Wolf Spirit, Overload, Lightning Tendrils
2617 {
2618 switch (Id)
2619 {
2620 case 43292: // Incite Rage
2621 case 49172: // Wolf Spirit
2623
2629 [[fallthrough]];
2630 case 61869: // Overload
2631 case 63481:
2632 case 61887: // Lightning Tendrils
2633 case 63486:
2634 mechanicImmunityMask |= (1 << MECHANIC_INTERRUPT) | (1 << MECHANIC_SILENCE);
2635
2638 break;
2639 default:
2640 break;
2641 }
2642 break;
2643 }
2644 case 679: // Mind Control, Avenging Fury
2645 {
2646 if (Id == 57742) // Avenging Fury
2647 {
2649
2655 }
2656 break;
2657 }
2658 case 1557: // Startling Roar, Warlord Roar, Break Bonds, Stormshield
2659 {
2660 if (Id == 64187) // Stormshield
2661 {
2662 mechanicImmunityMask |= (1 << MECHANIC_STUN);
2664 }
2665 else
2666 {
2668
2674 }
2675 break;
2676 }
2677 case 1614: // Fixate
2678 case 1694: // Fixated, Lightning Tendrils
2679 {
2682 break;
2683 }
2684 case 1630: // Fervor, Berserk
2685 {
2686 if (Id == 64112) // Berserk
2687 {
2690 }
2691 else
2692 {
2694
2700 }
2701 break;
2702 }
2703 case 477: // Bladestorm
2704 case 1733: // Bladestorm, Killing Spree
2705 {
2706 if (!amount)
2707 {
2709
2712
2718 }
2719 break;
2720 }
2721 case 878: // Whirlwind, Fog of Corruption, Determination
2722 {
2723 if (Id == 66092) // Determination
2724 {
2725 mechanicImmunityMask |= (1 << MECHANIC_SNARE) | (1 << MECHANIC_STUN)
2726 | (1 << MECHANIC_DISORIENTED) | (1 << MECHANIC_FREEZE);
2727
2730 }
2731 break;
2732 }
2733 default:
2734 break;
2735 }
2736
2737 if (immuneInfo.AuraTypeImmune.empty())
2738 {
2739 if (miscVal & (1 << 10))
2741 if (miscVal & (1 << 1))
2743
2744 // These flag can be recognized wrong:
2745 if (miscVal & (1 << 6))
2747 if (miscVal & (1 << 0))
2749 if (miscVal & (1 << 2))
2751 if (miscVal & (1 << 9))
2753 if (miscVal & (1 << 7))
2755 }
2756 break;
2757 }
2759 {
2760 switch (Id)
2761 {
2762 case 42292: // PvP trinket
2763 case 59752: // Every Man for Himself
2766 removeEffectsWithMechanic = true;
2767 break;
2768 case 34471: // The Beast Within
2769 case 19574: // Bestial Wrath
2770 case 53490: // Bullheaded
2772 removeEffectsWithMechanic = true;
2773 break;
2774 case 54508: // Demonic Empowerment
2775 mechanicImmunityMask |= (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT) | (1 << MECHANIC_STUN);
2776 break;
2777 default:
2778 if (miscVal < 1)
2779 break;
2780
2781 mechanicImmunityMask |= 1 << miscVal;
2782 break;
2783 }
2784
2785 // Special 100 ms duration spells - PvP trinket, Every Man for Himself and some other
2786 if (GetMaxDuration() == 100)
2787 removeEffectsWithMechanic = true;
2788
2789 break;
2790 }
2792 {
2793 immuneInfo.SpellEffectImmune.insert(static_cast<SpellEffects>(miscVal));
2794 break;
2795 }
2797 {
2798 immuneInfo.AuraTypeImmune.insert(static_cast<AuraType>(miscVal));
2799 break;
2800 }
2802 {
2803 schoolImmunityMask |= uint32(miscVal);
2804 break;
2805 }
2807 {
2808 applyHarmfulAuraImmunityMask |= uint32(miscVal);
2809 break;
2810 }
2812 {
2813 damageImmunityMask |= uint32(miscVal);
2814 break;
2815 }
2817 {
2818 dispelImmunity = uint32(miscVal);
2819 break;
2820 }
2821 default:
2822 break;
2823 }
2824
2825 immuneInfo.SchoolImmuneMask = schoolImmunityMask;
2826 immuneInfo.ApplyHarmfulAuraImmuneMask = applyHarmfulAuraImmunityMask;
2827 immuneInfo.MechanicImmuneMask = mechanicImmunityMask;
2828 immuneInfo.DispelImmune = dispelImmunity;
2829 immuneInfo.DamageSchoolMask = damageImmunityMask;
2830 immuneInfo.RemoveEffectsWithMechanic = removeEffectsWithMechanic;
2831
2832 immuneInfo.AuraTypeImmune.shrink_to_fit();
2833 immuneInfo.SpellEffectImmune.shrink_to_fit();
2834
2835 if (immuneInfo.SchoolImmuneMask
2836 || immuneInfo.ApplyHarmfulAuraImmuneMask
2837 || immuneInfo.MechanicImmuneMask
2838 || immuneInfo.DispelImmune
2839 || immuneInfo.DamageSchoolMask
2840 || !immuneInfo.AuraTypeImmune.empty()
2841 || !immuneInfo.SpellEffectImmune.empty())
2842 {
2843 effect._immunityInfo = std::move(workBuffer);
2844 workBuffer = std::make_unique<SpellEffectInfo::ImmunityInfo>();
2845 }
2846
2848 }
2849
2851 {
2852 switch (Id)
2853 {
2854 case 22812: // Barkskin
2855 case 47585: // Dispersion
2857 (1 << MECHANIC_STUN) |
2858 (1 << MECHANIC_FREEZE) |
2859 (1 << MECHANIC_KNOCKOUT) |
2860 (1 << MECHANIC_SLEEP);
2861 break;
2862 case 49039: // Lichborne, don't allow normal stuns
2863 break;
2864 default:
2866 break;
2867 }
2868 }
2869
2872
2874 {
2875 switch (Id)
2876 {
2877 case 22812: // Barkskin
2878 case 47585: // Dispersion
2880 break;
2881 default:
2883 break;
2884 }
2885 }
2886}
2887
2888void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& spellEffectInfo, bool apply) const
2889{
2890 SpellEffectInfo::ImmunityInfo const* immuneInfo = spellEffectInfo.GetImmunityInfo();
2891 if (!immuneInfo)
2892 return;
2893
2894 if (uint32 schoolImmunity = immuneInfo->SchoolImmuneMask)
2895 {
2896 target->ApplySpellImmune(Id, IMMUNITY_SCHOOL, schoolImmunity, apply);
2897
2899 {
2900 target->RemoveAppliedAuras([this, schoolImmunity](AuraApplication const* aurApp) -> bool
2901 {
2902 SpellInfo const* auraSpellInfo = aurApp->GetBase()->GetSpellInfo();
2903 return ((auraSpellInfo->GetSchoolMask() & schoolImmunity) != 0 && // Check for school mask
2904 CanDispelAura(auraSpellInfo) &&
2905 (IsPositive() != aurApp->IsPositive()) && // Check spell vs aura possitivity
2906 !auraSpellInfo->IsPassive() && // Don't remove passive auras
2907 auraSpellInfo->Id != Id); // Don't remove self
2908 });
2909 }
2910 }
2911
2912 if (uint32 mechanicImmunity = immuneInfo->MechanicImmuneMask)
2913 {
2914 for (uint32 i = 0; i < MAX_MECHANIC; ++i)
2915 if (mechanicImmunity & (1 << i))
2916 target->ApplySpellImmune(Id, IMMUNITY_MECHANIC, i, apply);
2917
2919 {
2920 if (apply)
2921 target->RemoveAurasWithMechanic(mechanicImmunity, AURA_REMOVE_BY_DEFAULT, Id, immuneInfo->RemoveEffectsWithMechanic);
2922 else if (!immuneInfo->RemoveEffectsWithMechanic)
2923 {
2924 std::vector<Aura*> aurasToUpdateTargets;
2925 target->RemoveAppliedAuras([mechanicImmunity, &aurasToUpdateTargets](AuraApplication const* aurApp)
2926 {
2927 Aura* aura = aurApp->GetBase();
2928 if (aura->GetSpellInfo()->GetAllEffectsMechanicMask() & mechanicImmunity)
2929 aurasToUpdateTargets.push_back(aura);
2930
2931 // only update targets, don't remove anything
2932 return false;
2933 });
2934
2935 for (Aura* aura : aurasToUpdateTargets)
2936 aura->UpdateTargetMap(aura->GetCaster());
2937 }
2938 }
2939 }
2940
2941 if (uint32 dispelImmunity = immuneInfo->DispelImmune)
2942 {
2943 target->ApplySpellImmune(Id, IMMUNITY_DISPEL, dispelImmunity, apply);
2944
2946 {
2947 target->RemoveAppliedAuras([dispelImmunity](AuraApplication const* aurApp) -> bool
2948 {
2949 SpellInfo const* spellInfo = aurApp->GetBase()->GetSpellInfo();
2950 if (spellInfo->Dispel == dispelImmunity)
2951 return true;
2952
2953 return false;
2954 });
2955 }
2956 }
2957
2958 if (uint32 damageImmunity = immuneInfo->DamageSchoolMask)
2959 target->ApplySpellImmune(Id, IMMUNITY_DAMAGE, damageImmunity, apply);
2960
2961 for (AuraType auraType : immuneInfo->AuraTypeImmune)
2962 {
2963 target->ApplySpellImmune(Id, IMMUNITY_STATE, auraType, apply);
2965 target->RemoveAurasByType(auraType, [](AuraApplication const* aurApp) -> bool
2966 {
2967 // if the aura has SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY, then it cannot be removed by immunity
2969 });
2970 }
2971
2972 for (SpellEffects effectType : immuneInfo->SpellEffectImmune)
2973 target->ApplySpellImmune(Id, IMMUNITY_EFFECT, effectType, apply);
2974}
2975
2977{
2978 if (!auraSpellInfo)
2979 return false;
2980
2981 for (SpellEffectInfo const& effectInfo : _effects)
2982 {
2983 if (!effectInfo.IsEffect())
2984 continue;
2985
2986 SpellEffectInfo::ImmunityInfo const* immuneInfo = effectInfo.GetImmunityInfo();
2987 if (!immuneInfo)
2988 continue;
2989
2991 {
2992 if (uint32 schoolImmunity = immuneInfo->SchoolImmuneMask)
2993 if ((auraSpellInfo->SchoolMask & schoolImmunity) != 0)
2994 return true;
2995 }
2996
2997 if (uint32 mechanicImmunity = immuneInfo->MechanicImmuneMask)
2998 if ((mechanicImmunity & (1 << auraSpellInfo->Mechanic)) != 0)
2999 return true;
3000
3001 if (uint32 dispelImmunity = immuneInfo->DispelImmune)
3002 if (auraSpellInfo->Dispel == dispelImmunity)
3003 return true;
3004
3005 bool immuneToAllEffects = true;
3006 for (SpellEffectInfo const& auraSpellEffectInfo : auraSpellInfo->GetEffects())
3007 {
3008 if (!auraSpellEffectInfo.IsEffect())
3009 continue;
3010
3011 auto spellImmuneItr = immuneInfo->SpellEffectImmune.find(auraSpellEffectInfo.Effect);
3012 if (spellImmuneItr == immuneInfo->SpellEffectImmune.end())
3013 {
3014 immuneToAllEffects = false;
3015 break;
3016 }
3017
3018 if (uint32 mechanic = auraSpellEffectInfo.Mechanic)
3019 {
3020 if (!(immuneInfo->MechanicImmuneMask & (1 << mechanic)))
3021 {
3022 immuneToAllEffects = false;
3023 break;
3024 }
3025 }
3026
3027 if (!auraSpellInfo->HasAttribute(SPELL_ATTR3_IGNORE_HIT_RESULT))
3028 {
3029 if (AuraType auraName = auraSpellEffectInfo.ApplyAuraName)
3030 {
3031 bool isImmuneToAuraEffectApply = false;
3032 auto auraImmuneItr = immuneInfo->AuraTypeImmune.find(auraName);
3033 if (auraImmuneItr != immuneInfo->AuraTypeImmune.end())
3034 isImmuneToAuraEffectApply = true;
3035
3036 if (!isImmuneToAuraEffectApply && !auraSpellInfo->IsPositiveEffect(auraSpellEffectInfo.EffectIndex) && !auraSpellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE))
3037 {
3038 if (uint32 applyHarmfulAuraImmunityMask = immuneInfo->ApplyHarmfulAuraImmuneMask)
3039 if ((auraSpellInfo->GetSchoolMask() & applyHarmfulAuraImmunityMask) != 0)
3040 isImmuneToAuraEffectApply = true;
3041 }
3042
3043 if (!isImmuneToAuraEffectApply)
3044 {
3045 immuneToAllEffects = false;
3046 break;
3047 }
3048 }
3049 }
3050 }
3051
3052 if (immuneToAllEffects)
3053 return true;
3054 }
3055
3056 return false;
3057}
3058
3059// based on client Spell_C::CancelsAuraEffect
3061{
3063 return false;
3064
3066 return false;
3067
3068 for (SpellEffectInfo const& effect : GetEffects())
3069 {
3070 if (!effect.IsEffect(SPELL_EFFECT_APPLY_AURA))
3071 continue;
3072
3073 uint32 const miscValue = static_cast<uint32>(effect.MiscValue);
3074 switch (effect.ApplyAuraName)
3075 {
3077 if (miscValue != aurEff->GetAuraType())
3078 continue;
3079 break;
3083 continue;
3084 break;
3086 if (miscValue != aurEff->GetSpellInfo()->Dispel)
3087 continue;
3088 break;
3090 if (miscValue != aurEff->GetSpellInfo()->Mechanic)
3091 {
3092 if (miscValue != aurEff->GetSpellEffectInfo().Mechanic)
3093 continue;
3094 }
3095 break;
3096 default:
3097 continue;
3098 }
3099
3100 return true;
3101 }
3102
3103 return false;
3104}
3105
3110
3112{
3113 uint32 casterMechanicImmunityMask = caster->GetMechanicImmunityMask();
3114 uint32 mechanicImmunityMask = 0;
3115
3116 // @todo: research other interrupt flags
3118 {
3119 if (casterMechanicImmunityMask & (1 << MECHANIC_SILENCE))
3120 mechanicImmunityMask |= (1 << MECHANIC_SILENCE);
3121
3122 if (casterMechanicImmunityMask & (1 << MECHANIC_INTERRUPT))
3123 mechanicImmunityMask |= (1 << MECHANIC_INTERRUPT);
3124 }
3125
3126 return mechanicImmunityMask;
3127}
3128
3129float SpellInfo::GetMinRange(bool positive /*= false*/) const
3130{
3131 if (!RangeEntry)
3132 return 0.0f;
3133 if (positive)
3134 return RangeEntry->RangeMin[1];
3135 return RangeEntry->RangeMin[0];
3136}
3137
3138float SpellInfo::GetMaxRange(bool positive /*= false*/, WorldObject* caster /*= nullptr*/, Spell* spell /*= nullptr*/) const
3139{
3140 if (!RangeEntry)
3141 return 0.0f;
3142 float range;
3143 if (positive)
3144 range = RangeEntry->RangeMax[1];
3145 else
3146 range = RangeEntry->RangeMax[0];
3147 if (caster)
3148 if (Player* modOwner = caster->GetSpellModOwner())
3149 modOwner->ApplySpellMod(Id, SPELLMOD_RANGE, range, spell);
3150
3151 return range;
3152}
3153
3155{
3156 if (!DurationEntry)
3157 return IsPassive() ? -1 : 0;
3158 return (DurationEntry->Duration == -1) ? -1 : abs(DurationEntry->Duration);
3159}
3160
3162{
3163 if (!DurationEntry)
3164 return IsPassive() ? -1 : 0;
3165 return (DurationEntry->MaxDuration == -1) ? -1 : abs(DurationEntry->MaxDuration);
3166}
3167
3168uint32 SpellInfo::CalcCastTime(Spell* spell /*= nullptr*/) const
3169{
3170 // not all spells have cast time index and this is all is pasiive abilities
3171 if (!CastTimeEntry)
3172 return 0;
3173
3174 int32 castTime = CastTimeEntry->Base;
3175
3176 if (spell)
3177 spell->GetCaster()->ModSpellCastTime(this, castTime, spell);
3178
3180 castTime += 500;
3181
3182 return (castTime > 0) ? uint32(castTime) : 0;
3183}
3184
3186{
3187 uint32 totalTicks = 0;
3188 int32 DotDuration = GetDuration();
3189
3190 for (SpellEffectInfo const& effect : GetEffects())
3191 {
3192 if (effect.IsEffect(SPELL_EFFECT_APPLY_AURA))
3193 {
3194 switch (effect.ApplyAuraName)
3195 {
3211 // skip infinite periodics
3212 if (effect.ApplyAuraPeriod > 0 && DotDuration > 0)
3213 {
3214 totalTicks = static_cast<uint32>(DotDuration) / effect.ApplyAuraPeriod;
3216 ++totalTicks;
3217 }
3218 break;
3219 default:
3220 break;
3221 }
3222 }
3223 }
3224
3225 return totalTicks;
3226}
3227
3232
3233int32 SpellInfo::CalcPowerCost(WorldObject const* caster, SpellSchoolMask schoolMask, Spell* spell) const
3234{
3235 // gameobject casts don't use power
3236 Unit const* unitCaster = caster->ToUnit();
3237 if (!unitCaster)
3238 return 0;
3239
3240 // Spell drain all exist power on cast (Only paladin lay of Hands)
3242 {
3243 // If power type - health drain all
3244 if (PowerType == POWER_HEALTH)
3245 return unitCaster->GetHealth();
3246 // Else drain all power
3247 if (PowerType < MAX_POWERS)
3248 return unitCaster->GetPower(PowerType);
3249 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type '{}' in spell {}", PowerType, Id);
3250 return 0;
3251 }
3252
3253 // Base powerCost
3254 int32 powerCost = ManaCost;
3255 // PCT cost from total amount
3257 {
3258 switch (PowerType)
3259 {
3260 // health as power used
3261 case POWER_HEALTH:
3262 powerCost += int32(CalculatePct(unitCaster->GetCreateHealth(), ManaCostPercentage));
3263 break;
3264 case POWER_MANA:
3265 powerCost += int32(CalculatePct(unitCaster->GetCreateMana(), ManaCostPercentage));
3266 break;
3267 case POWER_RAGE:
3268 case POWER_FOCUS:
3269 case POWER_ENERGY:
3270 case POWER_HAPPINESS:
3271 powerCost += int32(CalculatePct(unitCaster->GetMaxPower(PowerType), ManaCostPercentage));
3272 break;
3273 case POWER_RUNE:
3274 case POWER_RUNIC_POWER:
3275 TC_LOG_DEBUG("spells", "CalculateManaCost: Not implemented yet!");
3276 break;
3277 default:
3278 TC_LOG_ERROR("spells", "CalculateManaCost: Unknown power type '{}' in spell {}", PowerType, Id);
3279 return 0;
3280 }
3281 }
3282
3283 // Flat mod from caster auras by spell school and power type
3285 for (Unit::AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
3286 {
3287 if (!((*i)->GetMiscValue() & schoolMask))
3288 continue;
3289 if (!((*i)->GetMiscValueB() & (1 << PowerType)))
3290 continue;
3291 powerCost += (*i)->GetAmount();
3292 }
3293 // Shiv - costs 20 + weaponSpeed*10 energy (apply only to non-triggered spell with energy cost)
3295 {
3296 uint32 speed = 0;
3297 if (SpellShapeshiftFormEntry const* ss = sSpellShapeshiftFormStore.LookupEntry(unitCaster->GetShapeshiftForm()))
3298 speed = ss->CombatRoundTime;
3299 else
3300 speed = unitCaster->GetAttackTime(GetAttackType());
3301
3302 powerCost += speed / 100;
3303 }
3304
3305 // Apply cost mod by spell
3306 if (Player* modOwner = unitCaster->GetSpellModOwner())
3307 modOwner->ApplySpellMod(Id, SPELLMOD_COST, powerCost, spell);
3308
3309 if (!unitCaster->IsControlledByPlayer())
3310 {
3312 {
3313 GtNPCManaCostScalerEntry const* spellScaler = sGtNPCManaCostScalerStore.LookupEntry(SpellLevel - 1);
3314 GtNPCManaCostScalerEntry const* casterScaler = sGtNPCManaCostScalerStore.LookupEntry(unitCaster->GetLevel() - 1);
3315 if (spellScaler && casterScaler)
3316 powerCost *= casterScaler->Data / spellScaler->Data;
3317 }
3318 }
3319
3320 // PCT mod from user auras by spell school and power type
3322 for (Unit::AuraEffectList::const_iterator i = aurasPct.begin(); i != aurasPct.end(); ++i)
3323 {
3324 if (!((*i)->GetMiscValue() & schoolMask))
3325 continue;
3326 if (!((*i)->GetMiscValueB() & (1 << PowerType)))
3327 continue;
3328 powerCost += CalculatePct(powerCost, (*i)->GetAmount());
3329 }
3330 if (powerCost < 0)
3331 powerCost = 0;
3332 return powerCost;
3333}
3334
3336{
3337 return ChainEntry != nullptr;
3338}
3339
3341{
3342 if (!ChainEntry)
3343 return 1;
3344 return ChainEntry->rank;
3345}
3346
3348{
3349 if (!ChainEntry)
3350 return this;
3351 return ChainEntry->first;
3352}
3354{
3355 if (!ChainEntry)
3356 return nullptr;
3357 return ChainEntry->last;
3358}
3360{
3361 if (!ChainEntry)
3362 return nullptr;
3363 return ChainEntry->next;
3364}
3366{
3367 if (!ChainEntry)
3368 return nullptr;
3369 return ChainEntry->prev;
3370}
3371
3373{
3374 // ignore passive spells
3375 if (IsPassive())
3376 return this;
3377
3378 // Client ignores spell with these attributes (sub_53D9D0)
3380 return this;
3381
3382 bool needRankSelection = false;
3383 for (SpellEffectInfo const& effect : GetEffects())
3384 {
3385 if (IsPositiveEffect(effect.EffectIndex) &&
3386 (effect.Effect == SPELL_EFFECT_APPLY_AURA ||
3387 effect.Effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
3388 effect.Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID))
3389 {
3390 needRankSelection = true;
3391 break;
3392 }
3393 }
3394
3395 // not required
3396 if (!needRankSelection)
3397 return this;
3398
3399 for (SpellInfo const* nextSpellInfo = this; nextSpellInfo != nullptr; nextSpellInfo = nextSpellInfo->GetPrevRankSpell())
3400 {
3401 // if found appropriate level
3402 if (uint32(level + 10) >= nextSpellInfo->SpellLevel)
3403 return nextSpellInfo;
3404
3405 // one rank less then
3406 }
3407
3408 // not found
3409 return nullptr;
3410}
3411
3412bool SpellInfo::IsRankOf(SpellInfo const* spellInfo) const
3413{
3414 return GetFirstRankSpell() == spellInfo->GetFirstRankSpell();
3415}
3416
3417bool SpellInfo::IsDifferentRankOf(SpellInfo const* spellInfo) const
3418{
3419 if (Id == spellInfo->Id)
3420 return false;
3421 return IsRankOf(spellInfo);
3422}
3423
3424bool SpellInfo::IsHighRankOf(SpellInfo const* spellInfo) const
3425{
3426 if (ChainEntry && spellInfo->ChainEntry)
3427 if (ChainEntry->first == spellInfo->ChainEntry->first)
3428 if (ChainEntry->rank > spellInfo->ChainEntry->rank)
3429 return true;
3430
3431 return false;
3432}
3433
3435{
3436 bool srcSet = false;
3437 bool dstSet = false;
3438 uint32 targetMask = Targets;
3439 // prepare target mask using effect target entries
3440 for (SpellEffectInfo const& effect : GetEffects())
3441 {
3442 if (!effect.IsEffect())
3443 continue;
3444
3445 targetMask |= effect.TargetA.GetExplicitTargetMask(srcSet, dstSet);
3446 targetMask |= effect.TargetB.GetExplicitTargetMask(srcSet, dstSet);
3447
3448 // add explicit target flags based on spell effects which have EFFECT_IMPLICIT_TARGET_EXPLICIT and no valid target provided
3449 if (effect.GetImplicitTargetType() != EFFECT_IMPLICIT_TARGET_EXPLICIT)
3450 continue;
3451
3452 // extend explicit target mask only if valid targets for effect could not be provided by target types
3453 uint32 effectTargetMask = effect.GetMissingTargetMask(srcSet, dstSet, targetMask);
3454
3455 // don't add explicit object/dest flags when spell has no max range
3456 if (GetMaxRange(true) == 0.0f && GetMaxRange(false) == 0.0f)
3458
3459 targetMask |= effectTargetMask;
3460 }
3461
3462 ExplicitTargetMask = targetMask;
3463}
3464
3465inline bool _isPositiveTarget(SpellEffectInfo const& effect)
3466{
3467 if (!effect.IsEffect())
3468 return true;
3469
3470 return (effect.TargetA.GetCheckType() != TARGET_CHECK_ENEMY &&
3472}
3473
3474bool _isPositiveEffectImpl(SpellInfo const* spellInfo, SpellEffectInfo const& effect, std::unordered_set<std::pair<uint32, SpellEffIndex>>& visited)
3475{
3476 if (!effect.IsEffect())
3477 return true;
3478
3479 // attribute may be already set in DB
3480 if (!spellInfo->IsPositiveEffect(effect.EffectIndex))
3481 return false;
3482
3483 // passive auras like talents are all positive
3484 if (spellInfo->IsPassive())
3485 return true;
3486
3487 // not found a single positive spell with this attribute
3488 if (spellInfo->HasAttribute(SPELL_ATTR0_NEGATIVE_1))
3489 return false;
3490
3491 visited.insert({ spellInfo->Id, effect.EffectIndex });
3492
3493 //We need scaling level info for some auras that compute bp 0 or positive but should be debuffs
3494 float bpScalePerLevel = effect.RealPointsPerLevel;
3495 int32 bp = effect.CalcValue();
3496 switch (spellInfo->SpellFamilyName)
3497 {
3499 switch (spellInfo->Id)
3500 {
3501 case 40268: // Spiritual Vengeance, Teron Gorefiend, Black Temple
3502 case 61987: // Avenging Wrath Marker
3503 case 61988: // Divine Shield exclude aura
3504 case 64412: // Phase Punch, Algalon the Observer, Ulduar
3505 case 72410: // Rune of Blood, Saurfang, Icecrown Citadel
3506 case 71204: // Touch of Insignificance, Lady Deathwhisper, Icecrown Citadel
3507 return false;
3508 case 24732: // Bat Costume
3509 case 30877: // Tag Murloc
3510 case 61716: // Rabbit Costume
3511 case 61734: // Noblegarden Bunny
3512 case 62344: // Fists of Stone
3513 case 50344: // Dream Funnel
3514 case 61819: // Manabonked! (item)
3515 case 61834: // Manabonked! (minigob)
3516 return true;
3517 default:
3518 break;
3519 }
3520 break;
3521 case SPELLFAMILY_ROGUE:
3522 // Shadow of Death, Teron Gorefiend, Black Temple
3523 if (spellInfo->Id == 40251)
3524 return false;
3525 break;
3526 case SPELLFAMILY_MAGE:
3527 // Amplify Magic, Dampen Magic
3528 if (spellInfo->SpellFamilyFlags[0] == 0x00002000)
3529 return true;
3530 // Permafrost (due to zero basepoint)
3531 if (spellInfo->SpellFamilyFlags[2] == 0x00000010)
3532 return false;
3533 // Arcane Missiles
3534 if (spellInfo->SpellFamilyFlags[0] == 0x00000800)
3535 return false;
3536 break;
3538 // Slam, Execute
3539 if ((spellInfo->SpellFamilyFlags[0] & 0x20200000) != 0)
3540 return false;
3541 break;
3543 // assortment of judgement related spells
3544 if (spellInfo->SpellFamilyFlags & flag96(0x208C0000, 0x00000208, 0x00000008))
3545 return false;
3546 break;
3547 case SPELLFAMILY_HUNTER:
3548 // Aspect of the Viper
3549 if (spellInfo->Id == 34074)
3550 return true;
3551 // Explosive Shot
3553 return false;
3554 break;
3555 case SPELLFAMILY_DRUID:
3556 // Starfall
3557 if (spellInfo->SpellFamilyFlags[2] == 0x00000100)
3558 return false;
3559 break;
3561 if (spellInfo->SpellFamilyFlags[2] == 0x00000010) // Ebon Plague
3562 return false;
3563 break;
3564 default:
3565 break;
3566 }
3567
3568 switch (spellInfo->Mechanic)
3569 {
3571 return true;
3572 default:
3573 break;
3574 }
3575
3576 // Special case: effects which determine positivity of whole spell
3577 // Note: this check was written before the attribute name was discovered so it might require to be adjusted
3579 {
3580 // check for targets, there seems to be an assortment of dummy triggering spells that should be negative
3581 for (SpellEffectInfo const& otherEffect : spellInfo->GetEffects())
3582 if (!_isPositiveTarget(otherEffect))
3583 return false;
3584 }
3585
3586 for (SpellEffectInfo const& otherEffect : spellInfo->GetEffects())
3587 {
3588 switch (otherEffect.Effect)
3589 {
3590 case SPELL_EFFECT_HEAL:
3594 return true;
3596 if (otherEffect.EffectIndex != effect.EffectIndex &&
3597 // for spells like 38044: instakill effect is negative but auras on target must count as buff
3598 otherEffect.TargetA.GetTarget() == effect.TargetA.GetTarget() &&
3599 otherEffect.TargetB.GetTarget() == effect.TargetB.GetTarget())
3600 return false;
3601 break;
3602 default:
3603 break;
3604 }
3605
3606 if (otherEffect.IsAura())
3607 {
3608 switch (otherEffect.ApplyAuraName)
3609 {
3612 return true;
3614 case SPELL_AURA_EMPATHY:
3617 return false;
3618 default:
3619 break;
3620 }
3621 }
3622 }
3623
3624 switch (effect.Effect)
3625 {
3644 return false;
3650 return true;
3656 // check targets
3657 if (!_isPositiveTarget(effect))
3658 return false;
3659 break;
3661 // non-positive dispel
3662 switch (effect.MiscValue)
3663 {
3664 case DISPEL_STEALTH:
3666 case DISPEL_ENRAGE:
3667 return false;
3668 default:
3669 break;
3670 }
3671
3672 // also check targets
3673 if (!_isPositiveTarget(effect))
3674 return false;
3675 break;
3677 if (!_isPositiveTarget(effect))
3678 {
3679 // non-positive mechanic dispel on negative target
3680 switch (effect.MiscValue)
3681 {
3682 case MECHANIC_BANDAGE:
3683 case MECHANIC_SHIELD:
3684 case MECHANIC_MOUNT:
3686 return false;
3687 default:
3688 break;
3689 }
3690 }
3691 break;
3694 // check targets AND basepoints
3695 if (!_isPositiveTarget(effect) && bp > 0)
3696 return false;
3697 break;
3698 default:
3699 break;
3700 }
3701
3702 if (effect.IsAura())
3703 {
3704 // non-positive aura use
3705 switch (effect.ApplyAuraName)
3706 {
3707 case SPELL_AURA_MOD_STAT: // dependent from basepoint sign (negative -> negative)
3730 if (bp < 0 || bpScalePerLevel < 0) //TODO: What if both are 0? Should it be a buff or debuff?
3731 return false;
3732 break;
3733 case SPELL_AURA_MOD_ATTACKSPEED: // some buffs have negative bp, check both target and bp
3748 if (!_isPositiveTarget(effect) || bp < 0)
3749 return false;
3750 break;
3751 case SPELL_AURA_MOD_DAMAGE_TAKEN: // dependent from basepoint sign (positive -> negative)
3759 if (bp > 0)
3760 return false;
3761 break;
3762 case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN: // check targets and basepoints (ex Recklessness)
3763 if (!_isPositiveTarget(effect) && bp > 0)
3764 return false;
3765 break;
3766 case SPELL_AURA_MOD_HEALTH_REGEN_PERCENT: // check targets and basepoints (target enemy and negative bp -> negative)
3767 if (!_isPositiveTarget(effect) && bp < 0)
3768 return false;
3769 break;
3771 return true;
3774 if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(effect.TriggerSpell))
3775 {
3776 // negative targets of main spell return early
3777 for (SpellEffectInfo const& spellTriggeredEffect : spellTriggeredProto->GetEffects())
3778 {
3779 // already seen this
3780 if (visited.count({ spellTriggeredProto->Id, spellTriggeredEffect.EffectIndex }) > 0)
3781 continue;
3782
3783 if (!spellTriggeredEffect.IsEffect())
3784 continue;
3785
3786 // if non-positive trigger cast targeted to positive target this main cast is non-positive
3787 // this will place this spell auras as debuffs
3788 if (_isPositiveTarget(spellTriggeredEffect) && !_isPositiveEffectImpl(spellTriggeredProto, spellTriggeredEffect, visited))
3789 return false;
3790 }
3791 }
3792 break;
3799 // special auras: they may have non negative target but still need to be marked as debuff
3800 // checked again after all effects (SpellInfo::_InitializeSpellPositivity)
3820 case SPELL_AURA_DUMMY:
3835 // check target for positive and negative spells
3836 if (!_isPositiveTarget(effect))
3837 return false;
3838 break;
3844 case SPELL_AURA_GHOST:
3853 return false;
3855 {
3856 // non-positive immunities
3857 switch (effect.MiscValue)
3858 {
3859 case MECHANIC_BANDAGE:
3860 case MECHANIC_SHIELD:
3861 case MECHANIC_MOUNT:
3863 return false;
3864 default:
3865 break;
3866 }
3867 break;
3868 }
3869 case SPELL_AURA_ADD_FLAT_MODIFIER: // mods
3871 {
3872 switch (effect.MiscValue)
3873 {
3874 case SPELLMOD_CASTING_TIME: // dependent from basepoint sign (positive -> negative)
3878 if (bp > 0)
3879 return false;
3880 break;
3881 case SPELLMOD_COOLDOWN:
3882 case SPELLMOD_COST:
3883 if (!spellInfo->IsPositive() && bp > 0) // dependent on prev effects too (ex Arcane Power)
3884 return false;
3885 break;
3886 case SPELLMOD_EFFECT1: // always positive
3887 case SPELLMOD_EFFECT2:
3888 case SPELLMOD_EFFECT3:
3890 case SPELLMOD_THREAT:
3893 return true;
3894 case SPELLMOD_DURATION:
3896 case SPELLMOD_DAMAGE:
3898 if (!spellInfo->IsPositive() && bp < 0) // dependent on prev effects too
3899 return false;
3900 break;
3901 default: // dependent from basepoint sign (negative -> negative)
3902 if (bp < 0)
3903 return false;
3904 break;
3905 }
3906 break;
3907 }
3908 default:
3909 break;
3910 }
3911 }
3912
3913 // negative spell if triggered spell is negative
3914 if (!effect.ApplyAuraName && effect.TriggerSpell)
3915 {
3916 if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(effect.TriggerSpell))
3917 {
3918 // spells with at least one negative effect are considered negative
3919 // some self-applied spells have negative effects but in self casting case negative check ignored.
3920 for (SpellEffectInfo const& spellTriggeredEffect : spellTriggeredProto->GetEffects())
3921 {
3922 // already seen this
3923 if (visited.count({ spellTriggeredProto->Id, spellTriggeredEffect.EffectIndex }) > 0)
3924 continue;
3925
3926 if (!spellTriggeredEffect.IsEffect())
3927 continue;
3928
3929 if (!_isPositiveEffectImpl(spellTriggeredProto, spellTriggeredEffect, visited))
3930 return false;
3931 }
3932 }
3933 }
3934
3935 // ok, positive
3936 return true;
3937}
3938
3940{
3941 std::unordered_set<std::pair<uint32 /*spellId*/, SpellEffIndex /*effIndex*/>> visited;
3942
3943 for (SpellEffectInfo const& effect : GetEffects())
3944 if (!_isPositiveEffectImpl(this, effect, visited))
3945 AttributesCu |= (SPELL_ATTR0_CU_NEGATIVE_EFF0 << effect.EffectIndex);
3946
3947 // additional checks after effects marked
3948 for (SpellEffectInfo const& effect : GetEffects())
3949 {
3950 if (!effect.IsEffect() || !IsPositiveEffect(effect.EffectIndex))
3951 continue;
3952
3953 switch (effect.ApplyAuraName)
3954 {
3955 // has other non positive effect?
3956 // then it should be marked negative if has same target as negative effect (ex 8510, 8511, 8893, 10267)
3957 case SPELL_AURA_DUMMY:
3964 {
3965 for (size_t j = effect.EffectIndex + 1; j < GetEffects().size(); ++j)
3966 if (!IsPositiveEffect(j)
3967 && effect.TargetA.GetTarget() == GetEffect(SpellEffIndex(j)).TargetA.GetTarget()
3968 && effect.TargetB.GetTarget() == GetEffect(SpellEffIndex(j)).TargetB.GetTarget())
3969 AttributesCu |= (SPELL_ATTR0_CU_NEGATIVE_EFF0 << effect.EffectIndex);
3970 break;
3971 }
3972 default:
3973 break;
3974 }
3975 }
3976}
3977
3979{
3980 // find the same instances of ConditionList and delete them.
3981 for (SpellEffectInfo const& effect : GetEffects())
3982 {
3983 ConditionContainer* cur = effect.ImplicitTargetConditions;
3984 if (!cur)
3985 continue;
3986
3987 for (size_t j = effect.EffectIndex; j < GetEffects().size(); ++j)
3989 _GetEffect(SpellEffIndex(j)).ImplicitTargetConditions = nullptr;
3990
3991 delete cur;
3992 }
3993}
@ STATUS_WAIT_JOIN
@ IN_MILLISECONDS
Definition Common.h:35
#define M_PI
Definition Common.h:72
std::vector< Condition * > ConditionContainer
@ CORPSE_BONES
Definition Corpse.h:29
@ VEHICLE_SEAT_FLAG_UNK2
Definition DBCEnums.h:499
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition DBCEnums.h:481
@ VEHICLE_SEAT_FLAG_CAN_CONTROL
Definition DBCEnums.h:480
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition DBCEnums.h:482
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition DBCEnums.h:483
@ SPELL_CATEGORY_FLAG_COOLDOWN_STARTS_ON_EVENT
Definition DBCEnums.h:385
@ SKILL_LINE_ABILITY_LEARNED_ON_SKILL_VALUE
Definition DBCEnums.h:349
#define MAX_SPELL_EFFECTS
Definition DBCEnums.h:388
DBCStorage< SpellShapeshiftFormEntry > sSpellShapeshiftFormStore(SpellShapeshiftFormfmt)
DBCStorage< SpellRadiusEntry > sSpellRadiusStore(SpellRadiusfmt)
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
DBCStorage< SpellCategoryEntry > sSpellCategoryStore(SpellCategoryfmt)
DBCStorage< SpellCastTimesEntry > sSpellCastTimesStore(SpellCastTimefmt)
DBCStorage< SpellRangeEntry > sSpellRangeStore(SpellRangefmt)
uint32 GetTalentSpellCost(uint32 spellId)
uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId)
DBCStorage< GtNPCManaCostScalerEntry > sGtNPCManaCostScalerStore(GtNPCManaCostScalerfmt)
DBCStorage< AreaGroupEntry > sAreaGroupStore(AreaGroupEntryfmt)
DBCStorage< SpellDurationEntry > sSpellDurationStore(SpellDurationfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
#define MAX_GROUP_AREA_IDS
uint8_t uint8
Definition Define.h:135
int32_t int32
Definition Define.h:129
uint64_t uint64
Definition Define.h:132
#define UI64LIT(N)
Definition Define.h:118
uint16_t uint16
Definition Define.h:134
uint32_t uint32
Definition Define.h:133
#define ITEM_SUBCLASS_MASK_WEAPON_RANGED
#define TC_LOG_DEBUG(filterType__,...)
Definition Log.h:156
#define TC_LOG_ERROR(filterType__,...)
Definition Log.h:165
uint64 MAKE_PAIR64(uint32 l, uint32 h)
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
int32 irand(int32 min, int32 max)
Definition Random.cpp:35
double rand_norm()
Definition Random.cpp:75
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ SPELL_ATTR7_BYPASS_NO_RESURRECT_AURA
SpellEffects
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_POWER_BURN
@ SPELL_EFFECT_ENERGIZE_PCT
@ SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
@ SPELL_EFFECT_APPLY_AREA_AURA_FRIEND
@ SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
@ SPELL_EFFECT_SELF_RESURRECT
@ SPELL_EFFECT_DISTRACT
@ SPELL_EFFECT_DURABILITY_DAMAGE
@ SPELL_EFFECT_HEALTH_LEECH
@ SPELL_EFFECT_SKILL
@ SPELL_EFFECT_WEAPON_DAMAGE
@ SPELL_EFFECT_HEAL
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
@ 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_KNOCK_BACK_DEST
@ SPELL_EFFECT_MODIFY_THREAT_PERCENT
@ SPELL_EFFECT_DURABILITY_DAMAGE_PCT
@ SPELL_EFFECT_ENVIRONMENTAL_DAMAGE
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
@ SPELL_EFFECT_CREATE_ITEM_2
@ 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_RESURRECT_NEW
@ 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_FORCE_CAST_WITH_VALUE
@ SPELL_EFFECT_THREAT
@ SPELL_EFFECT_SKILL_STEP
@ SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
@ SPELL_EFFECT_APPLY_AURA
@ SPELL_EFFECT_APPLY_AREA_AURA_OWNER
#define DISPEL_ALL_MASK
@ SPELL_ATTR5_USABLE_WHILE_CONFUSED
@ SPELL_ATTR5_USABLE_WHILE_FEARED
@ SPELL_ATTR5_START_PERIODIC_AT_APPLY
@ SPELL_ATTR5_SINGLE_TARGET_SPELL
@ SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING
@ SPELL_ATTR5_USABLE_WHILE_STUNNED
Targets
@ TARGET_DEST_TRAJ
@ TOTAL_SPELL_TARGETS
@ TARGET_DEST_CASTER
@ TARGET_UNIT_CASTER
SpellSchoolMask
@ SPELL_SCHOOL_MASK_FROST
@ SPELL_ATTR2_CANT_TARGET_TAPPED
@ SPELL_ATTR2_AUTOREPEAT_FLAG
@ SPELL_ATTR2_CAN_TARGET_DEAD
@ SPELL_ATTR2_NOT_NEED_SHAPESHIFT
@ SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE
@ SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF
SpellAttr1
@ SPELL_ATTR1_NO_THREAT
@ SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY
@ SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE
@ SPELL_ATTR1_DRAIN_ALL_POWER
@ SPELL_ATTR1_NOT_BREAK_STEALTH
@ SPELL_ATTR1_UNAUTOCASTABLE_BY_PET
@ SPELL_ATTR1_DONT_REFRESH_DURATION_ON_RECAST
@ SPELL_ATTR1_CHANNELED_1
@ SPELL_ATTR1_CHANNELED_2
@ SPELL_ATTR1_REQ_COMBO_POINTS2
@ SPELL_ATTR1_REQ_COMBO_POINTS1
@ SPELL_ATTR1_CANT_TARGET_SELF
@ SPELL_ATTR1_CANT_TARGET_IN_COMBAT
@ SPELL_ATTR3_STACK_FOR_DIFF_CASTERS
@ SPELL_ATTR3_DEATH_PERSISTENT
@ SPELL_ATTR3_NO_DONE_BONUS
@ SPELL_ATTR3_ONLY_TARGET_PLAYERS
@ SPELL_ATTR3_DRAIN_SOUL
@ SPELL_ATTR3_ONLY_TARGET_GHOSTS
@ SPELL_ATTR3_NO_INITIAL_AGGRO
@ SPELL_ATTR3_REQ_OFFHAND
@ SPELL_ATTR3_IGNORE_HIT_RESULT
@ SPELL_DAMAGE_CLASS_RANGED
@ SPELL_DAMAGE_CLASS_MELEE
WeaponAttackType
@ OFF_ATTACK
@ BASE_ATTACK
@ RANGED_ATTACK
Mechanics
@ MECHANIC_DISARM
@ MECHANIC_NONE
@ MECHANIC_MOUNT
@ MECHANIC_FEAR
@ MECHANIC_INVULNERABILITY
@ MECHANIC_DISORIENTED
@ MECHANIC_KNOCKOUT
@ MECHANIC_CHARM
@ MECHANIC_STUN
@ MECHANIC_FREEZE
@ MECHANIC_INTERRUPT
@ MECHANIC_ROOT
@ MECHANIC_BANDAGE
@ MECHANIC_SLEEP
@ MECHANIC_BLEED
@ MECHANIC_POLYMORPH
@ MECHANIC_BANISH
@ MAX_MECHANIC
@ MECHANIC_IMMUNE_SHIELD
@ MECHANIC_SNARE
@ MECHANIC_SILENCE
@ MECHANIC_SHACKLE
@ MECHANIC_SAPPED
@ MECHANIC_SHIELD
@ MECHANIC_HORROR
@ IMMUNITY_STATE
@ IMMUNITY_EFFECT
@ IMMUNITY_DAMAGE
@ IMMUNITY_MECHANIC
@ IMMUNITY_SCHOOL
@ IMMUNITY_DISPEL
@ SPELLFAMILY_PRIEST
@ SPELLFAMILY_WARLOCK
@ SPELLFAMILY_MAGE
@ SPELLFAMILY_GENERIC
@ SPELLFAMILY_WARRIOR
@ SPELLFAMILY_PALADIN
@ SPELLFAMILY_HUNTER
@ SPELLFAMILY_ROGUE
@ SPELLFAMILY_SHAMAN
@ SPELLFAMILY_DRUID
@ SPELLFAMILY_DEATHKNIGHT
@ SPELLFAMILY_UNK1
Powers
@ MAX_POWERS
@ POWER_RAGE
@ POWER_HEALTH
@ POWER_RUNIC_POWER
@ POWER_HAPPINESS
@ POWER_ENERGY
@ POWER_MANA
@ POWER_RUNE
@ POWER_FOCUS
SpellAttr0
@ SPELL_ATTR0_ON_NEXT_SWING
@ SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY
@ SPELL_ATTR0_DISABLED_WHILE_ACTIVE
@ SPELL_ATTR0_NEGATIVE_1
@ SPELL_ATTR0_PASSIVE
@ SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION
@ SPELL_ATTR0_REQ_AMMO
@ SPELL_ATTR0_ON_NEXT_SWING_2
@ SPELL_ATTR0_NOT_SHAPESHIFT
@ SPELL_ATTR0_CASTABLE_WHILE_MOUNTED
@ SPELL_ATTR0_CANT_USED_IN_COMBAT
uint32 const CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD
DiminishingLevels
@ DIMINISHING_LEVEL_IMMUNE
@ DIMINISHING_LEVEL_TAUNT_IMMUNE
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK
DiminishingGroup
@ DIMINISHING_MIND_CONTROL
@ DIMINISHING_HORROR
@ DIMINISHING_DRAGONS_BREATH
@ DIMINISHING_CONTROLLED_STUN
@ DIMINISHING_CYCLONE
@ DIMINISHING_BANISH
@ DIMINISHING_CONTROLLED_ROOT
@ DIMINISHING_NONE
@ DIMINISHING_SLEEP
@ DIMINISHING_STUN
@ DIMINISHING_DISARM
@ DIMINISHING_ENTRAPMENT
@ DIMINISHING_FEAR
@ DIMINISHING_SCATTER_SHOT
@ DIMINISHING_LIMITONLY
@ DIMINISHING_OPENING_STUN
@ DIMINISHING_DISORIENT
@ DIMINISHING_ROOT
@ DIMINISHING_TAUNT
@ DIMINISHING_CHARGE
@ DIMINISHING_SILENCE
TotemCategory
AuraStateType
@ AURA_STATE_NONE
@ AURA_STATE_FROZEN
@ AURA_STATE_DEADLY_POISON
@ AURA_STATE_BLEEDING
@ AURA_STATE_FAERIE_FIRE
@ AURA_STATE_ENRAGE
@ AURA_STATE_WARRIOR_VICTORY_RUSH
@ AURA_STATE_UNKNOWN22
@ AURA_STATE_JUDGEMENT
@ AURA_STATE_SWIFTMEND
@ AURA_STATE_CONFLAGRATE
DiminishingReturnsType
@ DRTYPE_NONE
@ DRTYPE_PLAYER
@ DRTYPE_ALL
@ AREA_WINTERGRASP
DispelType
@ DISPEL_ALL
@ DISPEL_ENRAGE
@ DISPEL_POISON
@ DISPEL_INVISIBILITY
@ DISPEL_STEALTH
@ DISPEL_CURSE
SpellCastResult
@ SPELL_FAILED_TARGET_NOT_PLAYER
@ SPELL_FAILED_TARGET_NO_POCKETS
@ SPELL_FAILED_INCORRECT_AREA
@ SPELL_FAILED_TARGET_IS_PLAYER
@ SPELL_FAILED_CANT_CAST_ON_TAPPED
@ SPELL_FAILED_TARGET_AURASTATE
@ SPELL_FAILED_NOT_IN_RAID_INSTANCE
@ SPELL_FAILED_BM_OR_INVISGOD
@ SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW
@ SPELL_FAILED_ONLY_SHAPESHIFT
@ SPELL_FAILED_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
@ SPELL_ATTR4_SPELL_VS_EXTEND_COST
@ SPELL_ATTR4_CAST_ONLY_IN_OUTLAND
@ SUMMON_CATEGORY_WILD
@ SPELL_ATTR6_CAN_TARGET_INVISIBLE
@ SPELL_ATTR6_NOT_IN_RAID_INSTANCE
@ SPELL_ATTR6_CANT_TARGET_CROWD_CONTROLLED
@ SPELL_ATTR6_CASTABLE_WHILE_ON_VEHICLE
@ AURA_REMOVE_BY_DEFAULT
@ SPELL_AURA_PREVENT_RESURRECTION
@ SPELL_AURA_HASTE_RANGED
@ 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_MOD_SKILL
@ SPELL_AURA_PERIODIC_DAMAGE
@ SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE
@ SPELL_AURA_TRACK_RESOURCES
@ SPELL_AURA_MOD_PARRY_PERCENT
@ 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_PROC_TRIGGER_SPELL
@ SPELL_AURA_HASTE_SPELLS
@ SPELL_AURA_MOD_INCREASE_HEALTH
@ SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE
@ SPELL_AURA_MOD_FEAR
@ SPELL_AURA_MOD_POWER_REGEN
@ SPELL_AURA_MOD_HEALING_DONE_PERCENT
@ SPELL_AURA_PREVENTS_FLEEING
@ 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_RESISTANCE_EXCLUSIVE
@ SPELL_AURA_MOD_STALKED
@ SPELL_AURA_SCHOOL_HEAL_ABSORB
@ 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_DUMMY
@ SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN
@ 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_MOD_DETAUNT
@ SPELL_AURA_MOD_STAT
@ SPELL_AURA_MOD_HEALING_DONE
@ SPELL_AURA_MOD_RANGED_ATTACK_POWER
@ SPELL_AURA_MOD_HEALING_PCT
@ SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
@ SPELL_AURA_GHOST
@ SPELL_AURA_MOD_CHARM
@ SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE
@ SPELL_AURA_MOD_ROOT
@ SPELL_AURA_MOD_RANGED_HASTE
@ SPELL_AURA_SCHOOL_IMMUNITY
@ SPELL_AURA_MOUNTED
@ SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE
@ SPELL_AURA_MOD_POWER_COST_SCHOOL
@ SPELL_AURA_MECHANIC_IMMUNITY
@ SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE
@ SPELL_AURA_MOD_SCHOOL_CRIT_DMG_TAKEN
@ 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_ATTACKER_SPELL_CRIT_CHANCE
@ SPELL_AURA_MOD_CRIT_PCT
@ SPELL_AURA_MOD_PACIFY_SILENCE
@ SPELL_AURA_MOD_COOLDOWN
@ SPELL_AURA_AOE_CHARM
@ SPELL_AURA_MOD_SPEED_SLOW_ALL
@ 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_WEAPON_CRIT_PERCENT
@ SPELL_AURA_MOD_DAMAGE_DONE_CREATURE
@ SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL
@ SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR
@ SPELL_AURA_PERIODIC_LEECH
@ SPELL_AURA_MOD_LANGUAGE
@ SPELL_AURA_PROC_TRIGGER_DAMAGE
@ SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE
@ SPELL_AURA_MOD_DAMAGE_FROM_CASTER
@ 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_MOD_STEALTH
@ SPELL_AURA_NONE
@ 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
@ SPELL_INTERRUPT_FLAG_INTERRUPT
@ SPELLMOD_RANGE
@ SPELLMOD_EFFECT2
@ SPELLMOD_DAMAGE
@ SPELLMOD_ALL_EFFECTS
@ SPELLMOD_CRITICAL_CHANCE
@ SPELLMOD_EFFECT3
@ SPELLMOD_SPELL_COST_REFUND_ON_FAIL
@ SPELLMOD_VALUE_MULTIPLIER
@ SPELLMOD_DAMAGE_MULTIPLIER
@ SPELLMOD_GLOBAL_COOLDOWN
@ SPELLMOD_THREAT
@ SPELLMOD_ACTIVATION_TIME
@ SPELLMOD_COOLDOWN
@ SPELLMOD_EFFECT1
@ SPELLMOD_DURATION
@ SPELLMOD_JUMP_TARGETS
@ SPELLMOD_CASTING_TIME
@ SPELLMOD_RADIUS
@ SPELLMOD_COST
@ 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
@ AURA_INTERRUPT_FLAG_MOVE
@ AURA_INTERRUPT_FLAG_TURNING
@ AURA_INTERRUPT_FLAG_NOT_SEATED
bool _isPositiveTarget(SpellEffectInfo const &effect)
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
Definition SpellInfo.cpp:35
bool _isPositiveEffectImpl(SpellInfo const *spellInfo, SpellEffectInfo const &effect, std::unordered_set< std::pair< uint32, SpellEffIndex > > &visited)
SpellTargetCheckTypes
Definition SpellInfo.h:78
@ TARGET_CHECK_PASSENGER
Definition SpellInfo.h:86
@ TARGET_CHECK_PARTY
Definition SpellInfo.h:83
@ TARGET_CHECK_ENEMY
Definition SpellInfo.h:81
@ TARGET_CHECK_DEFAULT
Definition SpellInfo.h:79
@ TARGET_CHECK_ENTRY
Definition SpellInfo.h:80
@ TARGET_CHECK_RAID_CLASS
Definition SpellInfo.h:85
@ TARGET_CHECK_ALLY
Definition SpellInfo.h:82
@ TARGET_CHECK_RAID
Definition SpellInfo.h:84
SpellEffectImplicitTargetTypes
Definition SpellInfo.h:105
@ EFFECT_IMPLICIT_TARGET_NONE
Definition SpellInfo.h:106
@ EFFECT_IMPLICIT_TARGET_EXPLICIT
Definition SpellInfo.h:107
SpellTargetSelectionCategories
Definition SpellInfo.h:41
@ TARGET_SELECT_CATEGORY_CONE
Definition SpellInfo.h:46
@ TARGET_SELECT_CATEGORY_AREA
Definition SpellInfo.h:47
@ TARGET_SELECT_CATEGORY_DEFAULT
Definition SpellInfo.h:43
@ TARGET_SELECT_CATEGORY_NEARBY
Definition SpellInfo.h:45
@ TARGET_SELECT_CATEGORY_NYI
Definition SpellInfo.h:42
@ TARGET_SELECT_CATEGORY_TRAJ
Definition SpellInfo.h:48
@ TARGET_SELECT_CATEGORY_CHANNEL
Definition SpellInfo.h:44
SpellTargetDirectionTypes
Definition SpellInfo.h:90
@ TARGET_DIR_FRONT_RIGHT
Definition SpellInfo.h:96
@ TARGET_DIR_NONE
Definition SpellInfo.h:91
@ TARGET_DIR_BACK
Definition SpellInfo.h:93
@ TARGET_DIR_BACK_RIGHT
Definition SpellInfo.h:97
@ TARGET_DIR_RIGHT
Definition SpellInfo.h:94
@ TARGET_DIR_FRONT_LEFT
Definition SpellInfo.h:99
@ TARGET_DIR_FRONT
Definition SpellInfo.h:92
@ TARGET_DIR_LEFT
Definition SpellInfo.h:95
@ TARGET_DIR_BACK_LEFT
Definition SpellInfo.h:98
@ TARGET_DIR_RANDOM
Definition SpellInfo.h:100
SpellTargetObjectTypes
Definition SpellInfo.h:62
@ TARGET_OBJECT_TYPE_UNIT
Definition SpellInfo.h:66
@ TARGET_OBJECT_TYPE_ITEM
Definition SpellInfo.h:70
@ TARGET_OBJECT_TYPE_CORPSE
Definition SpellInfo.h:71
@ TARGET_OBJECT_TYPE_UNIT_AND_DEST
Definition SpellInfo.h:67
@ TARGET_OBJECT_TYPE_NONE
Definition SpellInfo.h:63
@ TARGET_OBJECT_TYPE_DEST
Definition SpellInfo.h:65
@ TARGET_OBJECT_TYPE_GOBJ
Definition SpellInfo.h:68
@ TARGET_OBJECT_TYPE_CORPSE_ALLY
Definition SpellInfo.h:74
@ TARGET_OBJECT_TYPE_CORPSE_ENEMY
Definition SpellInfo.h:73
@ TARGET_OBJECT_TYPE_GOBJ_ITEM
Definition SpellInfo.h:69
@ TARGET_OBJECT_TYPE_SRC
Definition SpellInfo.h:64
@ SPELL_ATTR0_CU_ALLOW_INFLIGHT_TARGET
Definition SpellInfo.h:159
@ SPELL_ATTR0_CU_NEGATIVE_EFF2
Definition SpellInfo.h:155
@ SPELL_ATTR0_CU_NEGATIVE_EFF1
Definition SpellInfo.h:154
@ SPELL_ATTR0_CU_NEGATIVE
Definition SpellInfo.h:168
@ SPELL_ATTR0_CU_NEGATIVE_EFF0
Definition SpellInfo.h:153
@ SPELL_ATTR0_CU_PICKPOCKET
Definition SpellInfo.h:151
SpellSpecificType
Definition SpellInfo.h:113
@ SPELL_SPECIFIC_FOOD
Definition SpellInfo.h:127
@ SPELL_SPECIFIC_MAGE_ARMOR
Definition SpellInfo.h:122
@ SPELL_SPECIFIC_NORMAL
Definition SpellInfo.h:114
@ SPELL_SPECIFIC_STING
Definition SpellInfo.h:117
@ SPELL_SPECIFIC_MAGE_ARCANE_BRILLANCE
Definition SpellInfo.h:133
@ SPELL_SPECIFIC_ASPECT
Definition SpellInfo.h:119
@ SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT
Definition SpellInfo.h:135
@ SPELL_SPECIFIC_ELEMENTAL_SHIELD
Definition SpellInfo.h:123
@ SPELL_SPECIFIC_WARLOCK_CORRUPTION
Definition SpellInfo.h:126
@ SPELL_SPECIFIC_PRESENCE
Definition SpellInfo.h:130
@ SPELL_SPECIFIC_CURSE
Definition SpellInfo.h:118
@ SPELL_SPECIFIC_JUDGEMENT
Definition SpellInfo.h:125
@ SPELL_SPECIFIC_DRINK
Definition SpellInfo.h:128
@ SPELL_SPECIFIC_HAND
Definition SpellInfo.h:136
@ SPELL_SPECIFIC_AURA
Definition SpellInfo.h:116
@ SPELL_SPECIFIC_WARRIOR_ENRAGE
Definition SpellInfo.h:134
@ SPELL_SPECIFIC_WARLOCK_ARMOR
Definition SpellInfo.h:121
@ SPELL_SPECIFIC_SCROLL
Definition SpellInfo.h:132
@ SPELL_SPECIFIC_MAGE_POLYMORPH
Definition SpellInfo.h:124
@ SPELL_SPECIFIC_TRACKER
Definition SpellInfo.h:120
@ SPELL_SPECIFIC_SEAL
Definition SpellInfo.h:115
@ SPELL_SPECIFIC_FOOD_AND_DRINK
Definition SpellInfo.h:129
@ SPELL_SPECIFIC_CHARM
Definition SpellInfo.h:131
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
Definition SpellInfo.cpp:35
SpellTargetReferenceTypes
Definition SpellInfo.h:52
@ TARGET_REFERENCE_TYPE_SRC
Definition SpellInfo.h:57
@ TARGET_REFERENCE_TYPE_TARGET
Definition SpellInfo.h:55
@ TARGET_REFERENCE_TYPE_LAST
Definition SpellInfo.h:56
@ TARGET_REFERENCE_TYPE_NONE
Definition SpellInfo.h:53
@ TARGET_REFERENCE_TYPE_CASTER
Definition SpellInfo.h:54
@ TARGET_REFERENCE_TYPE_DEST
Definition SpellInfo.h:58
bool IsPrimaryProfessionSkill(uint32 skill)
Definition SpellMgr.cpp:35
bool IsProfessionOrRidingSkill(uint32 skill)
Definition SpellMgr.h:565
@ SPELLFAMILYFLAG1_HUNTER_EXPLOSIVE_SHOT
Definition SpellMgr.h:77
bool IsProfessionSkill(uint32 skill)
Definition SpellMgr.h:560
std::pair< SpellAreaMap::const_iterator, SpellAreaMap::const_iterator > SpellAreaMapBounds
Definition SpellMgr.h:490
#define sSpellMgr
Definition SpellMgr.h:738
std::pair< SkillLineAbilityMap::const_iterator, SkillLineAbilityMap::const_iterator > SkillLineAbilityMapBounds
Definition SpellMgr.h:537
ProcFlags
Definition SpellMgr.h:112
@ UNIT_FLAG_PET_IN_COMBAT
@ UNIT_STATE_IN_FLIGHT
Definition Unit.h:228
T CalculatePct(T base, U pct)
Definition Util.h:71
PowerType
bool IsPositive() const
Definition SpellAuras.h:73
Aura * GetBase() const
Definition SpellAuras.h:67
SpellInfo const * GetSpellInfo() const
AuraType GetAuraType() const
SpellEffectInfo const & GetSpellEffectInfo() const
SpellInfo const * GetSpellInfo() const
Definition SpellAuras.h:115
BattlegroundStatus GetStatus() const
Definition Item.h:62
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition Item.cpp:847
static Creature * ToCreature(Object *o)
Definition Object.h:186
static Unit * ToUnit(Object *o)
Definition Object.h:192
TypeID GetTypeId() const
Definition Object.h:93
static Corpse * ToCorpse(Object *o)
Definition Object.h:204
static Player * ToPlayer(Object *o)
Definition Object.h:180
bool InBattleground() const
Definition Player.h:1982
Battleground * GetBattleground() const
Definition Player.cpp:23049
bool IsGameMaster() const
Definition Player.h:998
bool CanFlyInZone(uint32 mapid, uint32 zone, SpellInfo const *bySpell) const
Definition Player.cpp:24658
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition Player.cpp:9607
bool IsUseEquipedWeapon(bool mainhand) const
Definition Player.cpp:13140
Mechanics Mechanic
Definition SpellInfo.h:222
static std::array< StaticData, TOTAL_SPELL_EFFECTS > _data
Definition SpellInfo.h:633
bool IsUnitOwnedAuraEffect() const
float CalcDamageMultiplier(WorldObject *caster, Spell *spell=nullptr) const
float PointsPerComboPoint
Definition SpellInfo.h:216
AuraType ApplyAuraName
Definition SpellInfo.h:211
float CalcRadius(WorldObject *caster=nullptr, Spell *=nullptr) const
float CalcValueMultiplier(WorldObject *caster, Spell *spell=nullptr) const
uint32 TriggerSpell
Definition SpellInfo.h:228
ImmunityInfo const * GetImmunityInfo() const
Definition SpellInfo.h:263
SpellEffects Effect
Definition SpellInfo.h:210
std::unique_ptr< ImmunityInfo > _immunityInfo
Definition SpellInfo.h:273
bool IsAreaAuraEffect() const
flag96 SpellClassMask
Definition SpellInfo.h:229
SpellInfo const * _spellInfo
Definition SpellInfo.h:207
bool IsAura() const
uint32 GetMissingTargetMask(bool srcSet=false, bool destSet=false, uint32 mask=0) const
uint32 ChainTargets
Definition SpellInfo.h:226
bool HasRadius() const
bool IsEffect() const
int32 CalcValue(WorldObject const *caster=nullptr, int32 const *basePoints=nullptr) const
bool IsTargetingArea() const
SpellEffectImplicitTargetTypes GetImplicitTargetType() const
float BonusCoefficient
Definition SpellInfo.h:219
float ChainAmplitude
Definition SpellInfo.h:218
uint32 ApplyAuraPeriod
Definition SpellInfo.h:212
SpellTargetObjectTypes GetUsedTargetObjectType() const
std::vector< Condition * > * ImplicitTargetConditions
Definition SpellInfo.h:230
float RealPointsPerLevel
Definition SpellInfo.h:214
SpellRadiusEntry const * RadiusEntry
Definition SpellInfo.h:225
SpellEffIndex EffectIndex
Definition SpellInfo.h:209
uint32 GetProvidedTargetMask() const
SpellImplicitTargetInfo TargetA
Definition SpellInfo.h:223
int32 CalcBaseValue(int32 value) const
SpellImplicitTargetInfo TargetB
Definition SpellInfo.h:224
SpellTargetDirectionTypes GetDirectionType() const
Definition SpellInfo.cpp:94
SpellTargetCheckTypes GetCheckType() const
Definition SpellInfo.cpp:89
static std::array< StaticData, TOTAL_SPELL_TARGETS > _data
Definition SpellInfo.h:236
SpellTargetReferenceTypes GetReferenceType() const
Definition SpellInfo.cpp:79
SpellTargetSelectionCategories GetSelectionCategory() const
Definition SpellInfo.cpp:74
SpellTargetObjectTypes GetObjectType() const
Definition SpellInfo.cpp:84
float CalcDirectionAngle() const
Definition SpellInfo.cpp:99
uint32 GetExplicitTargetMask(bool &srcSet, bool &dstSet) const
Targets GetTarget() const
uint32 ChannelInterruptFlags
Definition SpellInfo.h:323
bool IsExplicitDiscovery() const
uint32 RequiresSpellFocus
Definition SpellInfo.h:306
uint32 BaseLevel
Definition SpellInfo.h:328
void _LoadSpellDiminishInfo()
uint32 MaxLevel
Definition SpellInfo.h:327
uint32 SpellLevel
Definition SpellInfo.h:329
uint32 TargetAuraState
Definition SpellInfo.h:309
bool IsRankOf(SpellInfo const *spellInfo) const
uint32 GetMaxTicks() const
std::array< int32, MAX_SPELL_REAGENTS > Reagent
Definition SpellInfo.h:342
uint32 ExcludeTargetAuraSpell
Definition SpellInfo.h:315
bool CanDispelAura(SpellInfo const *auraSpellInfo) const
uint32 Priority
Definition SpellInfo.h:351
uint32 PreventionType
Definition SpellInfo.h:359
uint32 CasterAuraSpell
Definition SpellInfo.h:312
bool IsProfessionOrRiding() const
uint32 RuneCostID
Definition SpellInfo.h:337
uint32 MaxTargetLevel
Definition SpellInfo.h:354
Mechanics GetEffectMechanic(SpellEffIndex effIndex) const
SpellInfo const * GetFirstRankSpell() const
bool IsAutocastable() const
float GetMaxRange(bool positive=false, WorldObject *caster=nullptr, Spell *spell=nullptr) const
uint32 GetCategory() const
SpellCastResult CheckShapeshift(uint32 form) const
bool IsRequiringDeadTarget() const
uint32 ManaCostPerlevel
Definition SpellInfo.h:333
flag96 SpellFamilyFlags
Definition SpellInfo.h:357
bool IsAffected(uint32 familyName, flag96 const &familyFlags) const
uint32 AttributesCu
Definition SpellInfo.h:301
uint32 RecoveryTime
Definition SpellInfo.h:317
SpellEffectInfo & _GetEffect(SpellEffIndex index)
Definition SpellInfo.h:510
SpellDiminishInfo _diminishInfoNonTriggered
Definition SpellInfo.h:518
DiminishingLevels GetDiminishingReturnsMaxLevel(bool triggered) const
SpellInfo(SpellEntry const *spellEntry)
bool IsAuraExclusiveBySpecificPerCasterWith(SpellInfo const *spellInfo) const
SpellInfo const * GetPrevRankSpell() const
uint32 ManaPerSecondPerLevel
Definition SpellInfo.h:335
bool IsGroupBuff() const
bool IsDeathPersistent() const
bool IsCooldownStartedOnEvent() const
uint64 Stances
Definition SpellInfo.h:302
bool IsPassive() const
uint32 StackAmount
Definition SpellInfo.h:340
uint32 Mechanic
Definition SpellInfo.h:292
bool IsAuraExclusiveBySpecificWith(SpellInfo const *spellInfo) const
uint32 Id
Definition SpellInfo.h:289
uint8 GetRank() const
SpellRangeEntry const * RangeEntry
Definition SpellInfo.h:338
uint32 ProcCharges
Definition SpellInfo.h:326
bool IsLootCrafting() const
int32 RequiredAreasID
Definition SpellInfo.h:360
bool IsStackableOnOneSlotWithDifferentCasters() const
bool IsRanked() const
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
uint32 GetRecoveryTime() const
AuraStateType _auraState
Definition SpellInfo.h:516
SpellSpecificType GetSpellSpecific() const
uint32 Dispel
Definition SpellInfo.h:291
uint32 ExcludeCasterAuraState
Definition SpellInfo.h:310
uint32 ActiveIconID
Definition SpellInfo.h:350
float Speed
Definition SpellInfo.h:339
bool IsSelfCast() const
bool IsMultiSlotAura() const
void _UnloadImplicitTargetConditionLists()
float GetMinRange(bool positive=false) const
int32 GetMaxDuration() const
int32 EquippedItemClass
Definition SpellInfo.h:344
bool HasInitialAggro() const
uint32 SchoolMask
Definition SpellInfo.h:361
bool IsAbilityOfSkillType(uint32 skillType) const
uint32 _allowedMechanicMask
Definition SpellInfo.h:521
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > & _GetEffects()
Definition SpellInfo.h:509
uint32 CasterAuraState
Definition SpellInfo.h:308
bool IsAffectedBySpellMod(SpellModifier const *mod) const
SpellCastResult CheckTarget(WorldObject const *caster, WorldObject const *target, bool implicit=true) const
std::array< uint32, 2 > SpellVisual
Definition SpellInfo.h:348
SpellDiminishInfo _diminishInfoTriggered
Definition SpellInfo.h:519
bool CheckTargetCreatureType(Unit const *target) const
DiminishingGroup GetDiminishingReturnsGroupForSpell(bool triggered) const
bool IsStackableWithRanks() const
bool IsItemFitToSpellRequirements(Item const *item) const
bool CanBeUsedInCombat() const
uint32 CategoryRecoveryTime
Definition SpellInfo.h:318
uint32 GetSpellMechanicMaskByEffectMask(uint32 effectMask) const
uint64 StancesNot
Definition SpellInfo.h:303
uint32 ExplicitTargetMask
Definition SpellInfo.h:363
bool IsAbilityLearnedWithProfession() const
bool IsAllowingDeadTarget() const
uint32 AttributesEx3
Definition SpellInfo.h:296
void _InitializeSpellPositivity()
void _LoadImmunityInfo()
WeaponAttackType GetAttackType() const
SpellSchoolMask GetSchoolMask() const
bool IsPrimaryProfession() const
uint32 ManaPerSecond
Definition SpellInfo.h:334
std::array< uint32, MAX_SPELL_REAGENTS > ReagentCount
Definition SpellInfo.h:343
void ApplyAllSpellImmunitiesTo(Unit *target, SpellEffectInfo const &spellEffectInfo, bool apply) const
bool NeedsComboPoints() const
AuraStateType GetAuraState() const
bool IsChanneled() const
bool HasAttribute(SpellAttr0 attribute) const
Definition SpellInfo.h:375
uint32 InterruptFlags
Definition SpellInfo.h:321
SpellDurationEntry const * DurationEntry
Definition SpellInfo.h:330
bool IsNextMeleeSwingSpell() const
uint32 Attributes
Definition SpellInfo.h:293
uint32 AttributesEx
Definition SpellInfo.h:294
int32 CalcPowerCost(WorldObject const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
bool CanSpellProvideImmunityAgainstAura(SpellInfo const *auraSpellInfo) const
uint32 GetEffectMechanicMask(SpellEffIndex effIndex) const
bool IsPassiveStackableWithRanks() const
bool SpellCancelsAuraEffect(AuraEffect const *aurEff) const
SpellCategoryEntry const * CategoryEntry
Definition SpellInfo.h:290
int32 GetDiminishingReturnsLimitDuration(bool triggered) const
uint32 MaxAffectedTargets
Definition SpellInfo.h:355
int32 GetDuration() const
bool IsAffectedBySpellMods() const
SpellCastResult CheckVehicle(Unit const *caster) const
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition SpellInfo.h:483
uint32 ManaCostPercentage
Definition SpellInfo.h:336
uint32 AttributesEx6
Definition SpellInfo.h:299
uint32 AttributesEx7
Definition SpellInfo.h:300
int32 EquippedItemSubClassMask
Definition SpellInfo.h:345
SpellSpecificType _spellSpecific
Definition SpellInfo.h:515
uint32 GetExplicitTargetMask() const
uint32 FacingCasterFlags
Definition SpellInfo.h:307
SpellCastResult CheckExplicitTarget(WorldObject const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
uint32 StartRecoveryTime
Definition SpellInfo.h:320
uint32 TargetAuraSpell
Definition SpellInfo.h:313
bool HasAreaAuraEffect() const
uint32 GetAllowedMechanicMask() const
uint32 GetAllEffectsMechanicMask() const
bool CanPierceImmuneAura(SpellInfo const *auraSpellInfo) const
uint32 SpellIconID
Definition SpellInfo.h:349
SpellChainNode const * ChainEntry
Definition SpellInfo.h:364
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > _effects
Definition SpellInfo.h:362
uint32 Targets
Definition SpellInfo.h:304
void _InitializeExplicitTargetMask()
bool IsDifferentRankOf(SpellInfo const *spellInfo) const
uint32 GetMechanicImmunityMask(Unit *caster) const
SpellInfo const * GetLastRankSpell() const
bool NeedsExplicitUnitTarget() const
SpellInfo const * GetNextRankSpell() const
SpellCastTimesEntry const * CastTimeEntry
Definition SpellInfo.h:316
DiminishingReturnsType GetDiminishingReturnsGroupType(bool triggered) const
int32 EquippedItemInventoryTypeMask
Definition SpellInfo.h:346
uint32 ExcludeTargetAuraState
Definition SpellInfo.h:311
bool IsPrimaryProfessionFirstRank() const
bool HasEffect(SpellEffects effect) const
void _LoadAuraState()
bool IsAffectingArea() const
bool IsProfession() const
bool IsPositive() const
bool IsAutoRepeatRangedSpell() const
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player const *player=nullptr, bool strict=true) const
uint32 TargetCreatureType
Definition SpellInfo.h:305
uint32 ProcChance
Definition SpellInfo.h:325
uint32 AttributesEx2
Definition SpellInfo.h:295
bool IsMoveAllowedChannel() const
uint32 DmgClass
Definition SpellInfo.h:358
uint32 AttributesEx5
Definition SpellInfo.h:298
bool IsRangedWeaponSpell() const
uint32 AttributesEx4
Definition SpellInfo.h:297
uint32 ExcludeCasterAuraSpell
Definition SpellInfo.h:314
bool HasAura(AuraType aura) const
bool IsTargetingArea() const
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > const & GetEffects() const
Definition SpellInfo.h:482
uint32 StartRecoveryCategory
Definition SpellInfo.h:319
uint32 SpellFamilyName
Definition SpellInfo.h:356
uint32 ManaCost
Definition SpellInfo.h:332
std::array< char const *, 16 > SpellName
Definition SpellInfo.h:352
uint32 AuraInterruptFlags
Definition SpellInfo.h:322
void _LoadSpellSpecific()
bool IsBreakingStealth() const
bool IsPositiveEffect(uint8 effIndex) const
std::array< char const *, 16 > Rank
Definition SpellInfo.h:353
bool IsSingleTarget() const
Definition Spell.h:152
WorldObject * GetCaster() const
Definition Spell.h:450
Definition Totem.h:39
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:769
Vehicle * GetVehicle() const
Definition Unit.h:1737
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3765
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1384
uint32 GetMechanicImmunityMask() const
Definition Unit.cpp:7801
ShapeshiftForm GetShapeshiftForm() const
Definition Unit.h:1490
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:953
bool CanFreeMove() const
Definition Unit.cpp:9338
bool IsAlive() const
Definition Unit.h:1234
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:4535
void RemoveAurasWithMechanic(uint32 mechanicMaskToRemove, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, uint32 exceptSpellId=0, bool withEffectMechanics=false)
Definition Unit.cpp:4077
uint32 GetVirtualItemId(uint32 slot) const
Definition Unit.cpp:13860
uint32 GetMaxPower(Powers power) const
Definition Unit.h:936
uint32 GetHealth() const
Definition Unit.h:913
uint32 GetCreateHealth() const
Definition Unit.h:1450
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition Unit.cpp:5815
bool IsVisible() const
Definition Unit.cpp:8508
bool HasAuraType(AuraType auraType) const
Definition Unit.cpp:4542
uint32 GetAttackTime(WeaponAttackType att) const
Definition Unit.cpp:8471
ObjectGuid GetCritterGUID() const
Definition Unit.h:1249
void RemoveAppliedAuras(std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3711
bool HasUnitState(const uint32 f) const
Definition Unit.h:876
void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply)
Definition Unit.cpp:8142
bool IsMagnet() const
Definition Unit.cpp:6212
bool IsInRaidWith(Unit const *unit) const
Definition Unit.cpp:11892
uint8 GetComboPoints(Unit const *who=nullptr) const
--------—Combo point system----------------—
Definition Unit.h:1695
bool IsControlledByPlayer() const
Definition Unit.h:1258
uint32 GetPower(Powers power) const
Definition Unit.h:934
uint32 GetCreatureTypeMask() const
Definition Unit.cpp:8958
std::list< AuraEffect * > AuraEffectList
Definition Unit.h:787
uint32 GetCreateMana() const
Definition Unit.h:1452
bool IsInPartyWith(Unit const *unit) const
Definition Unit.cpp:11873
uint8 GetLevel() const
Definition Unit.h:889
bool IsInCombat() const
Definition Unit.h:1144
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger) const
Returns information on the seat of specified passenger, represented by the format in VehicleSeat....
Definition Vehicle.cpp:646
bool IsValidAttackTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition Object.cpp:2856
bool CanSeeOrDetect(WorldObject const *obj, bool implicitDetect=false, bool distanceCheck=false, bool checkAlert=false) const
Definition Object.cpp:1547
float ApplyEffectModifiers(SpellInfo const *spellInfo, uint8 effIndex, float value) const
Definition Object.cpp:2281
Player * GetSpellModOwner() const
Definition Object.cpp:2223
bool IsValidAssistTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition Object.cpp:3000
void ModSpellCastTime(SpellInfo const *spellInfo, int32 &castTime, Spell *spell=nullptr) const
Definition Object.cpp:2414
Player * GetAffectingPlayer() const
Definition Object.cpp:2212
Definition Util.h:412
TC_GAME_API Player * FindPlayer(ObjectGuid const &)
STL namespace.
uint32 AreaID[MAX_GROUP_AREA_IDS]
bool IsFlyable() const
bool IsBattleground() const
uint32 Expansion() const
bool IsContinent() const
bool IsRaid() const
bool IsBattleArena() const
SpellInfo const * last
Definition SpellMgr.h:501
SpellInfo const * next
Definition SpellMgr.h:499
SpellInfo const * first
Definition SpellMgr.h:500
SpellInfo const * prev
Definition SpellMgr.h:498
int32 DiminishDurationLimit
Definition SpellInfo.h:281
DiminishingReturnsType DiminishReturnType
Definition SpellInfo.h:279
DiminishingLevels DiminishMaxLevel
Definition SpellInfo.h:280
DiminishingGroup DiminishGroup
Definition SpellInfo.h:278
Trinity::Containers::FlatSet< SpellEffects > SpellEffectImmune
ImmunityInfo(ImmunityInfo &&) noexcept=delete
Trinity::Containers::FlatSet< AuraType > AuraTypeImmune
ImmunityInfo(ImmunityInfo const &)=delete
uint32 Mechanic
uint32 AuraInterruptFlags
std::array< float, MAX_SPELL_EFFECTS > EffectBonusCoefficient
std::array< int32, MAX_SPELL_EFFECTS > EffectMiscValue
uint32 DispelType
std::array< uint32, 2 > ShapeshiftExclude
std::array< flag96, MAX_SPELL_EFFECTS > EffectSpellClassMask
uint32 CumulativeAura
uint32 SpellPriority
uint32 DurationIndex
std::array< uint32, MAX_SPELL_EFFECTS > EffectChainTargets
uint32 AttributesExB
flag96 SpellClassMask
uint32 ManaPerSecond
std::array< uint32, 2 > SpellVisualID
uint32 ManaCost
uint32 CategoryRecoveryTime
int32 EquippedItemClass
std::array< uint32, MAX_SPELL_EFFECTS > EffectTriggerSpell
uint32 SpellClassSet
std::array< uint32, MAX_SPELL_EFFECTS > EffectMechanic
uint32 TargetCreatureType
uint32 SchoolMask
uint32 CasterAuraSpell
std::array< uint32, MAX_SPELL_EFFECTS > EffectAuraPeriod
uint32 CasterAuraState
uint32 AttributesEx
uint32 ManaCostPerLevel
std::array< uint32, 2 > RequiredTotemCategoryID
std::array< uint32, MAX_SPELL_EFFECTS > EffectImplicitTargetA
std::array< uint32, MAX_SPELL_EFFECTS > EffectRadiusIndex
std::array< uint32, MAX_SPELL_EFFECTS > EffectItemType
uint32 InterruptFlags
uint32 AttributesExE
uint32 ActiveIconID
uint32 TargetAuraState
uint32 TargetAuraSpell
std::array< char const *, 16 > Name
uint32 CastingTimeIndex
uint32 ProcTypeMask
uint32 RuneCostID
uint32 StartRecoveryCategory
uint32 RecoveryTime
std::array< uint32, MAX_SPELL_EFFECTS > EffectAura
int32 EquippedItemSubclass
uint32 Attributes
std::array< int32, MAX_SPELL_EFFECTS > EffectBasePoints
std::array< float, MAX_SPELL_EFFECTS > EffectPointsPerCombo
uint32 MaxLevel
uint32 StartRecoveryTime
std::array< uint32, MAX_SPELL_EFFECTS > EffectImplicitTargetB
uint32 PowerType
uint32 ExcludeTargetAuraSpell
int32 RequiredAreasID
uint32 ExcludeCasterAuraState
uint32 AttributesExC
uint32 ChannelInterruptFlags
uint32 ProcChance
std::array< uint32, MAX_SPELL_EFFECTS > Effect
std::array< float, MAX_SPELL_EFFECTS > EffectChainAmplitude
uint32 SpellLevel
uint32 RequiresSpellFocus
std::array< char const *, 16 > NameSubtext
uint32 ProcCharges
uint32 AttributesExF
uint32 SpellIconID
uint32 BaseLevel
uint32 RangeIndex
uint32 FacingCasterFlags
uint32 MaxTargetLevel
std::array< float, MAX_SPELL_EFFECTS > EffectAmplitude
uint32 PreventionType
uint32 Category
std::array< float, MAX_SPELL_EFFECTS > EffectRealPointsPerLevel
uint32 ExcludeCasterAuraSpell
int32 EquippedItemInvTypes
std::array< int32, MAX_SPELL_EFFECTS > EffectMiscValueB
std::array< uint32, 2 > Totem
std::array< uint32, 2 > ShapeshiftMask
uint32 DefenseType
std::array< uint32, MAX_SPELL_REAGENTS > ReagentCount
uint32 ManaPerSecondPerLevel
uint32 AttributesExD
uint32 AttributesExG
uint32 MaxTargets
std::array< int32, MAX_SPELL_REAGENTS > Reagent
std::array< int32, MAX_SPELL_EFFECTS > EffectDieSides
uint32 ManaCostPct
uint32 ExcludeTargetAuraState
uint32 spellId
Definition Player.h:173
flag96 mask
Definition Player.h:172