AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
SpellMgr Class Reference

#include "SpellMgr.h"

Public Member Functions

uint32 GetSpellDifficultyId (uint32 spellId) const
 
void SetSpellDifficultyId (uint32 spellId, uint32 id)
 
uint32 GetSpellIdForDifficulty (uint32 spellId, Unit const *caster) const
 
SpellInfo const * GetSpellForDifficultyFromSpell (SpellInfo const *spell, Unit const *caster) const
 
SpellChainNode const * GetSpellChainNode (uint32 spell_id) const
 
uint32 GetFirstSpellInChain (uint32 spell_id) const
 
uint32 GetLastSpellInChain (uint32 spell_id) const
 
uint32 GetNextSpellInChain (uint32 spell_id) const
 
uint32 GetPrevSpellInChain (uint32 spell_id) const
 
uint8 GetSpellRank (uint32 spell_id) const
 
uint32 GetSpellWithRank (uint32 spell_id, uint32 rank, bool strict=false) const
 
SpellRequiredMapBounds GetSpellsRequiredForSpellBounds (uint32 spell_id) const
 
SpellsRequiringSpellMapBounds GetSpellsRequiringSpellBounds (uint32 spell_id) const
 
bool IsSpellRequiringSpell (uint32 spellid, uint32 req_spellid) const
 
SpellLearnSkillNode const * GetSpellLearnSkill (uint32 spell_id) const
 
SpellTargetPosition const * GetSpellTargetPosition (uint32 spell_id, SpellEffIndex effIndex) const
 
uint32 GetSpellGroup (uint32 spellid) const
 
SpellGroupSpecialFlags GetSpellGroupSpecialFlags (uint32 spell_id) const
 
SpellGroupStackFlags GetGroupStackFlags (uint32 groupid) const
 
SpellGroupStackFlags CheckSpellGroupStackRules (SpellInfo const *spellInfo1, SpellInfo const *spellInfo2, bool remove, bool areaAura) const
 
void GetSetOfSpellsInSpellGroupWithFlag (uint32 group_id, SpellGroupSpecialFlags flag, std::set< uint32 > &availableElixirs) const
 
SpellProcEventEntry const * GetSpellProcEvent (uint32 spellId) const
 
bool IsSpellProcEventCanTriggeredBy (SpellInfo const *spellProto, SpellProcEventEntry const *spellProcEvent, uint32 EventProcFlag, ProcEventInfo const &eventInfo, bool active) const
 
SpellProcEntry const * GetSpellProcEntry (uint32 spellId) const
 
bool CanSpellTriggerProcOnEvent (SpellProcEntry const &procEntry, ProcEventInfo &eventInfo) const
 
SpellBonusEntry const * GetSpellBonusData (uint32 spellId) const
 
SpellThreatEntry const * GetSpellThreatEntry (uint32 spellID) const
 
float GetSpellMixologyBonus (uint32 spellId) const
 
SkillLineAbilityMapBounds GetSkillLineAbilityMapBounds (uint32 spell_id) const
 
PetAura const * GetPetAura (uint32 spell_id, uint8 eff) const
 
SpellEnchantProcEntry const * GetSpellEnchantProcEvent (uint32 enchId) const
 
bool IsArenaAllowedEnchancment (uint32 ench_id) const
 
const std::vector< int32 > * GetSpellLinked (int32 spell_id) const
 
PetLevelupSpellSet const * GetPetLevelupSpellList (uint32 petFamily) const
 
PetDefaultSpellsEntry const * GetPetDefaultSpellsEntry (int32 id) const
 
SpellAreaMapBounds GetSpellAreaMapBounds (uint32 spell_id) const
 
SpellAreaForQuestMapBounds GetSpellAreaForQuestMapBounds (uint32 quest_id) const
 
SpellAreaForQuestMapBounds GetSpellAreaForQuestEndMapBounds (uint32 quest_id) const
 
SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds (uint32 spell_id) const
 
SpellAreaForAreaMapBounds GetSpellAreaForAreaMapBounds (uint32 area_id) const
 
SpellInfo const * GetSpellInfo (uint32 spellId) const
 
SpellInfo const * AssertSpellInfo (uint32 spellId) const
 
SpellInfo const * CheckSpellInfo (uint32 spellId) const
 
uint32 GetSpellInfoStoreSize () const
 
bool IsAdditionalTalentSpell (uint32 spellId) const
 
bool HasSpellCooldownOverride (uint32 spellId) const
 
SpellCooldownOverride GetSpellCooldownOverride (uint32 spellId) const
 
void UnloadSpellInfoChains ()
 
void LoadSpellTalentRanks ()
 
void LoadSpellRanks ()
 
void LoadSpellRequired ()
 
void LoadSpellLearnSkills ()
 
void LoadSpellTargetPositions ()
 
void LoadSpellGroups ()
 
void LoadSpellGroupStackRules ()
 
void LoadSpellProcEvents ()
 
void LoadSpellProcs ()
 
void LoadSpellBonuses ()
 
void LoadSpellThreats ()
 
void LoadSpellMixology ()
 
void LoadSkillLineAbilityMap ()
 
void LoadSpellPetAuras ()
 
void LoadEnchantCustomAttr ()
 
void LoadSpellEnchantProcData ()
 
void LoadSpellLinked ()
 
void LoadPetLevelupSpellMap ()
 
void LoadPetDefaultSpells ()
 
void LoadSpellAreas ()
 
void LoadSpellInfoStore ()
 
void LoadSpellCooldownOverrides ()
 
void UnloadSpellInfoStore ()
 
void UnloadSpellInfoImplicitTargetConditionLists ()
 
void LoadSpellInfoCustomAttributes ()
 
void LoadSpellInfoCorrections ()
 
void LoadSpellSpecificAndAuraState ()
 

Static Public Member Functions

static SpellMgrinstance ()
 
static bool ComputeIsSpellValid (SpellInfo const *spellInfo, bool msg=true)
 Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book, etc. More...
 
static bool IsSpellValid (SpellInfo const *spellInfo)
 
static bool CheckSpellValid (SpellInfo const *spellInfo, uint32 spellId, bool isTalent)
 

Private Member Functions

 SpellMgr ()
 
 ~SpellMgr ()
 
SpellInfo_GetSpellInfo (uint32 spellId)
 

Private Attributes

SpellDifficultySearcherMap mSpellDifficultySearcherMap
 
SpellChainMap mSpellChains
 
SpellsRequiringSpellMap mSpellsReqSpell
 
SpellRequiredMap mSpellReq
 
SpellLearnSkillMap mSpellLearnSkills
 
SpellTargetPositionMap mSpellTargetPositions
 
SpellGroupMap mSpellGroupMap
 
SpellGroupStackMap mSpellGroupStackMap
 
SpellProcEventMap mSpellProcEventMap
 
SpellProcMap mSpellProcMap
 
SpellBonusMap mSpellBonusMap
 
SpellThreatMap mSpellThreatMap
 
SpellMixologyMap mSpellMixologyMap
 
SpellPetAuraMap mSpellPetAuraMap
 
SpellLinkedMap mSpellLinkedMap
 
SpellEnchantProcEventMap mSpellEnchantProcEventMap
 
EnchantCustomAttribute mEnchantCustomAttr
 
SpellAreaMap mSpellAreaMap
 
SpellAreaForQuestMap mSpellAreaForQuestMap
 
SpellAreaForQuestMap mSpellAreaForQuestEndMap
 
SpellAreaForAuraMap mSpellAreaForAuraMap
 
SpellAreaForAreaMap mSpellAreaForAreaMap
 
SkillLineAbilityMap mSkillLineAbilityMap
 
PetLevelupSpellMap mPetLevelupSpellMap
 
PetDefaultSpellsMap mPetDefaultSpellsMap
 
SpellInfoMap mSpellInfoMap
 
SpellCooldownOverrideMap mSpellCooldownOverrideMap
 
TalentAdditionalSet mTalentSpellAdditionalSet
 

Detailed Description

Constructor & Destructor Documentation

◆ SpellMgr()

SpellMgr::SpellMgr ( )
private
356{
357}

◆ ~SpellMgr()

SpellMgr::~SpellMgr ( )
private
360{
362}
void UnloadSpellInfoStore()
Definition: SpellMgr.cpp:2762

References UnloadSpellInfoStore().

Member Function Documentation

◆ _GetSpellInfo()

SpellInfo * SpellMgr::_GetSpellInfo ( uint32  spellId)
inlineprivate
760{ return spellId < GetSpellInfoStoreSize() ? mSpellInfoMap[spellId] : nullptr; }
uint32 GetSpellInfoStoreSize() const
Definition: SpellMgr.h:751
SpellInfoMap mSpellInfoMap
Definition: SpellMgr.h:820

References GetSpellInfoStoreSize(), and mSpellInfoMap.

Referenced by LoadSpellInfoCustomAttributes().

◆ AssertSpellInfo()

SpellInfo const * SpellMgr::AssertSpellInfo ( uint32  spellId) const
inline
729 {
730 ASSERT(spellId < GetSpellInfoStoreSize());
731 SpellInfo const* spellInfo = mSpellInfoMap[spellId];
732 ASSERT(spellInfo);
733 return spellInfo;
734 }
#define ASSERT
Definition: Errors.h:68
Definition: SpellInfo.h:316

References ASSERT, GetSpellInfoStoreSize(), and mSpellInfoMap.

◆ CanSpellTriggerProcOnEvent()

bool SpellMgr::CanSpellTriggerProcOnEvent ( SpellProcEntry const &  procEntry,
ProcEventInfo eventInfo 
) const
899{
900 // proc type doesn't match
901 if (!(eventInfo.GetTypeMask() & procEntry.ProcFlags))
902 return false;
903
904 // check XP or honor target requirement
905 if (procEntry.AttributesMask & PROC_ATTR_REQ_EXP_OR_HONOR)
906 if (Player* actor = eventInfo.GetActor()->ToPlayer())
907 if (eventInfo.GetActionTarget() && !actor->isHonorOrXPTarget(eventInfo.GetActionTarget()))
908 return false;
909
910 // always trigger for these types
912 return true;
913
914 // check school mask (if set) for other trigger types
915 if (procEntry.SchoolMask && !(eventInfo.GetSchoolMask() & procEntry.SchoolMask))
916 return false;
917
918 // check spell family name/flags (if set) for spells
920 {
921 if (procEntry.SpellFamilyName && (procEntry.SpellFamilyName != eventInfo.GetSpellInfo()->SpellFamilyName))
922 return false;
923
924 if (procEntry.SpellFamilyMask && !(procEntry.SpellFamilyMask & eventInfo.GetSpellInfo()->SpellFamilyFlags))
925 return false;
926 }
927
928 // check spell type mask (if set)
930 {
931 if (procEntry.SpellTypeMask && !(eventInfo.GetSpellTypeMask() & procEntry.SpellTypeMask))
932 return false;
933 }
934
935 // check spell phase mask
937 {
938 if (!(eventInfo.GetSpellPhaseMask() & procEntry.SpellPhaseMask))
939 return false;
940 }
941
942 // check hit mask (on taken hit or on done hit, but not on spell cast phase)
943 if ((eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK) || ((eventInfo.GetTypeMask() & DONE_HIT_PROC_FLAG_MASK) && !(eventInfo.GetSpellPhaseMask() & PROC_SPELL_PHASE_CAST)))
944 {
945 uint32 hitMask = procEntry.HitMask;
946 // get default values if hit mask not set
947 if (!hitMask)
948 {
949 // for taken procs allow normal + critical hits by default
950 if (eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK)
952 // for done procs allow normal + critical + absorbs by default
953 else
955 }
956 if (!(eventInfo.GetHitMask() & hitMask))
957 return false;
958 }
959
960 return true;
961}
std::uint32_t uint32
Definition: Define.h:107
@ PROC_HIT_ABSORB
Definition: SpellMgr.h:262
@ PROC_HIT_CRITICAL
Definition: SpellMgr.h:253
@ PROC_HIT_NORMAL
Definition: SpellMgr.h:252
@ PROC_ATTR_REQ_EXP_OR_HONOR
Definition: SpellMgr.h:271
@ PROC_SPELL_PHASE_CAST
Definition: SpellMgr.h:243
@ TAKEN_HIT_PROC_FLAG_MASK
Definition: SpellMgr.h:173
@ PERIODIC_PROC_FLAG_MASK
Definition: SpellMgr.h:165
@ PROC_FLAG_KILLED
Definition: SpellMgr.h:107
@ PROC_FLAG_DEATH
Definition: SpellMgr.h:143
@ REQ_SPELL_PHASE_PROC_FLAG_MASK
Definition: SpellMgr.h:179
@ PROC_FLAG_KILL
Definition: SpellMgr.h:108
@ SPELL_PROC_FLAG_MASK
Definition: SpellMgr.h:156
@ DONE_HIT_PROC_FLAG_MASK
Definition: SpellMgr.h:167
@ PROC_FLAG_DONE_TRAP_ACTIVATION
Definition: SpellMgr.h:138
Player * ToPlayer()
Definition: Object.h:198
Definition: Player.h:1064
uint32 GetHitMask() const
Definition: Unit.h:445
SpellSchoolMask GetSchoolMask() const
Definition: Unit.h:447
Unit * GetActionTarget() const
Definition: Unit.h:440
uint32 GetSpellTypeMask() const
Definition: Unit.h:443
uint32 GetTypeMask() const
Definition: Unit.h:442
SpellInfo const * GetSpellInfo() const
Definition: Unit.cpp:185
Unit * GetActor()
Definition: Unit.h:439
uint32 GetSpellPhaseMask() const
Definition: Unit.h:444
flag96 SpellFamilyFlags
Definition: SpellInfo.h:388
uint32 SpellFamilyName
Definition: SpellInfo.h:387

References SpellProcEntry::AttributesMask, DONE_HIT_PROC_FLAG_MASK, ProcEventInfo::GetActionTarget(), ProcEventInfo::GetActor(), ProcEventInfo::GetHitMask(), ProcEventInfo::GetSchoolMask(), ProcEventInfo::GetSpellInfo(), ProcEventInfo::GetSpellPhaseMask(), ProcEventInfo::GetSpellTypeMask(), ProcEventInfo::GetTypeMask(), SpellProcEntry::HitMask, PERIODIC_PROC_FLAG_MASK, PROC_ATTR_REQ_EXP_OR_HONOR, PROC_FLAG_DEATH, PROC_FLAG_DONE_TRAP_ACTIVATION, PROC_FLAG_KILL, PROC_FLAG_KILLED, PROC_HIT_ABSORB, PROC_HIT_CRITICAL, PROC_HIT_NORMAL, PROC_SPELL_PHASE_CAST, SpellProcEntry::ProcFlags, REQ_SPELL_PHASE_PROC_FLAG_MASK, SpellProcEntry::SchoolMask, SPELL_PROC_FLAG_MASK, SpellInfo::SpellFamilyFlags, SpellProcEntry::SpellFamilyMask, SpellInfo::SpellFamilyName, SpellProcEntry::SpellFamilyName, SpellProcEntry::SpellPhaseMask, SpellProcEntry::SpellTypeMask, TAKEN_HIT_PROC_FLAG_MASK, and Object::ToPlayer().

◆ CheckSpellGroupStackRules()

SpellGroupStackFlags SpellMgr::CheckSpellGroupStackRules ( SpellInfo const *  spellInfo1,
SpellInfo const *  spellInfo2,
bool  remove,
bool  areaAura 
) const
682{
683 uint32 spellid_1 = spellInfo1->GetFirstRankSpell()->Id;
684 uint32 spellid_2 = spellInfo2->GetFirstRankSpell()->Id;
685
686 uint32 groupId = GetSpellGroup(spellid_1);
687
689
690 // xinef: dunno why i added this
691 if (spellid_1 == spellid_2 && remove && !areaAura)
692 {
694 {
696 }
697
699 }
700
701 if (groupId > 0 && groupId == GetSpellGroup(spellid_2))
702 {
705 // xinef: first flags are used for elixir stacking rules
707 {
708 if (flag1 & flag2)
710 }
711 // xinef: check only flag1 (new spell)
716
717 return SpellGroupStackFlags(GetGroupStackFlags(groupId) | additionFlag);
718 }
719
721}
SpellGroupStackFlags
Definition: SpellMgr.h:356
@ SPELL_GROUP_STACK_FLAG_EXCLUSIVE
Definition: SpellMgr.h:358
@ SPELL_GROUP_STACK_FLAG_FORCED_WEAKEST
Definition: SpellMgr.h:367
@ SPELL_GROUP_STACK_FLAG_FORCED_STRONGEST
Definition: SpellMgr.h:366
@ SPELL_GROUP_STACK_FLAG_NONE
Definition: SpellMgr.h:357
@ SPELL_GROUP_STACK_FLAG_NEVER_STACK
Definition: SpellMgr.h:361
SpellGroupSpecialFlags
Definition: SpellMgr.h:334
@ SPELL_GROUP_SPECIAL_FLAG_FORCED_STRONGEST
Definition: SpellMgr.h:341
@ SPELL_GROUP_SPECIAL_FLAG_SAME_SPELL_CHECK
Definition: SpellMgr.h:348
@ SPELL_GROUP_SPECIAL_FLAG_STACK_EXCLUSIVE_MAX
Definition: SpellMgr.h:340
uint32 GetSpellGroup(uint32 spellid) const
Definition: SpellMgr.cpp:661
SpellGroupStackFlags GetGroupStackFlags(uint32 groupid) const
Definition: SpellMgr.cpp:652
SpellGroupSpecialFlags GetSpellGroupSpecialFlags(uint32 spell_id) const
Definition: SpellMgr.cpp:671

References SpellInfo::GetFirstRankSpell(), GetGroupStackFlags(), GetSpellGroup(), GetSpellGroupSpecialFlags(), SpellInfo::Id, SPELL_GROUP_SPECIAL_FLAG_FORCED_STRONGEST, SPELL_GROUP_SPECIAL_FLAG_SAME_SPELL_CHECK, SPELL_GROUP_SPECIAL_FLAG_STACK_EXCLUSIVE_MAX, SPELL_GROUP_STACK_FLAG_EXCLUSIVE, SPELL_GROUP_STACK_FLAG_FORCED_STRONGEST, SPELL_GROUP_STACK_FLAG_FORCED_WEAKEST, SPELL_GROUP_STACK_FLAG_NEVER_STACK, and SPELL_GROUP_STACK_FLAG_NONE.

◆ CheckSpellInfo()

SpellInfo const * SpellMgr::CheckSpellInfo ( uint32  spellId) const
inline
737 {
738 if (spellId >= GetSpellInfoStoreSize())
739 {
740 LOG_ERROR("server", "spellId {} is not lower than GetSpellInfoStoreSize() ({})", spellId, GetSpellInfoStoreSize());
741 return nullptr;
742 }
743 SpellInfo const* spellInfo = mSpellInfoMap[spellId];
744 if (!spellInfo)
745 {
746 LOG_ERROR("server", "spellId {} has invalid spellInfo", spellId);
747 return nullptr;
748 }
749 return spellInfo;
750 }
#define LOG_ERROR(filterType__,...)
Definition: Log.h:156

References GetSpellInfoStoreSize(), LOG_ERROR, and mSpellInfoMap.

◆ CheckSpellValid()

bool SpellMgr::CheckSpellValid ( SpellInfo const *  spellInfo,
uint32  spellId,
bool  isTalent 
)
static
461{
462 if (!spellInfo)
463 {
465 LOG_ERROR("spells", "Player::{}: Non-existed in SpellStore spell #{} request.", (isTalent ? "AddTalent" : "addSpell"), spellId);
466 return false;
467 }
468
469 if (!IsSpellValid(spellInfo))
470 {
472 LOG_ERROR("spells", "Player::{}: Broken spell #{} learning not allowed.", (isTalent ? "AddTalent" : "addSpell"), spellId);
473 return false;
474 }
475
476 return true;
477}
void DeleteSpellFromAllPlayers(uint32 spellId)
Definition: SpellMgr.cpp:449
static bool IsSpellValid(SpellInfo const *spellInfo)
Definition: SpellMgr.cpp:442

References DeleteSpellFromAllPlayers(), IsSpellValid(), and LOG_ERROR.

Referenced by Player::_addSpell(), and Player::addTalent().

◆ ComputeIsSpellValid()

bool SpellMgr::ComputeIsSpellValid ( SpellInfo const *  spellInfo,
bool  msg = true 
)
static

Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book, etc.

372{
373 // not exist
374 if (!spellInfo)
375 return false;
376
377 bool need_check_reagents = false;
378
379 // check effects
380 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
381 {
382 switch (spellInfo->Effects[i].Effect)
383 {
384 case 0:
385 continue;
386
387 // craft spell for crafting non-existed item (break client recipes list show)
390 {
391 if (spellInfo->Effects[i].ItemType == 0)
392 {
393 // skip auto-loot crafting spells, its not need explicit item info (but have special fake items sometime)
394 if (!spellInfo->IsLootCrafting())
395 {
396 if (msg)
397 LOG_ERROR("sql.sql", "Craft spell {} not have create item entry.", spellInfo->Id);
398 return false;
399 }
400 }
401 // also possible IsLootCrafting case but fake item must exist anyway
402 else if (!sObjectMgr->GetItemTemplate(spellInfo->Effects[i].ItemType))
403 {
404 if (msg)
405 LOG_ERROR("sql.sql", "Craft spell {} create not-exist in DB item (Entry: {}) and then...", spellInfo->Id, spellInfo->Effects[i].ItemType);
406 return false;
407 }
408
409 need_check_reagents = true;
410 break;
411 }
413 {
414 SpellInfo const* spellInfo2 = sSpellMgr->GetSpellInfo(spellInfo->Effects[i].TriggerSpell);
415 if (!ComputeIsSpellValid(spellInfo2, msg))
416 {
417 if (msg)
418 LOG_ERROR("sql.sql", "Spell {} learn to invalid spell {}, and then...", spellInfo->Id, spellInfo->Effects[i].TriggerSpell);
419 return false;
420 }
421 break;
422 }
423 }
424 }
425
426 if (need_check_reagents)
427 {
428 for (uint8 j = 0; j < MAX_SPELL_REAGENTS; ++j)
429 {
430 if (spellInfo->Reagent[j] > 0 && !sObjectMgr->GetItemTemplate(spellInfo->Reagent[j]))
431 {
432 if (msg)
433 LOG_ERROR("sql.sql", "Craft spell {} have not-exist reagent in DB item (Entry: {}) and then...", spellInfo->Id, spellInfo->Reagent[j]);
434 return false;
435 }
436 }
437 }
438
439 return true;
440}
std::uint8_t uint8
Definition: Define.h:109
#define sObjectMgr
Definition: ObjectMgr.h:1623
#define sSpellMgr
Definition: SpellMgr.h:825
@ SPELL_EFFECT_CREATE_ITEM_2
Definition: SharedDefines.h:935
@ SPELL_EFFECT_LEARN_SPELL
Definition: SharedDefines.h:814
@ SPELL_EFFECT_CREATE_ITEM
Definition: SharedDefines.h:802
#define MAX_SPELL_REAGENTS
Definition: DBCStructure.h:1639
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:1637
static bool ComputeIsSpellValid(SpellInfo const *spellInfo, bool msg=true)
Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book,...
Definition: SpellMgr.cpp:371

References ComputeIsSpellValid(), SpellInfo::Effects, SpellInfo::Id, SpellInfo::IsLootCrafting(), LOG_ERROR, MAX_SPELL_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::Reagent, sObjectMgr, SPELL_EFFECT_CREATE_ITEM, SPELL_EFFECT_CREATE_ITEM_2, SPELL_EFFECT_LEARN_SPELL, and sSpellMgr.

Referenced by ObjectMgr::AddSpellToTrainer(), ComputeIsSpellValid(), ObjectMgr::InitializeSpellInfoPrecomputedData(), and ObjectMgr::LoadQuests().

◆ GetFirstSpellInChain()

uint32 SpellMgr::GetFirstSpellInChain ( uint32  spell_id) const
556{
557 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
558 return node->first->Id;
559
560 return spell_id;
561}
Definition: SpellMgr.h:554
SpellChainNode const * GetSpellChainNode(uint32 spell_id) const
Definition: SpellMgr.cpp:546

References GetSpellChainNode().

Referenced by GetSpellBonusData(), GetSpellGroup(), GetSpellGroupSpecialFlags(), GetSpellThreatEntry(), and LoadSpellRequired().

◆ GetGroupStackFlags()

SpellGroupStackFlags SpellMgr::GetGroupStackFlags ( uint32  groupid) const
653{
654 SpellGroupStackMap::const_iterator itr = mSpellGroupStackMap.find(groupid);
655 if (itr != mSpellGroupStackMap.end())
656 return itr->second;
657
659}
SpellGroupStackMap mSpellGroupStackMap
Definition: SpellMgr.h:802

References mSpellGroupStackMap, and SPELL_GROUP_STACK_FLAG_NONE.

Referenced by CheckSpellGroupStackRules().

◆ GetLastSpellInChain()

uint32 SpellMgr::GetLastSpellInChain ( uint32  spell_id) const
564{
565 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
566 return node->last->Id;
567
568 return spell_id;
569}

References GetSpellChainNode().

◆ GetNextSpellInChain()

uint32 SpellMgr::GetNextSpellInChain ( uint32  spell_id) const
572{
573 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
574 if (node->next)
575 return node->next->Id;
576
577 return 0;
578}

References GetSpellChainNode().

◆ GetPetAura()

PetAura const * SpellMgr::GetPetAura ( uint32  spell_id,
uint8  eff 
) const
1009{
1010 SpellPetAuraMap::const_iterator itr = mSpellPetAuraMap.find((spell_id << 8) + eff);
1011 if (itr != mSpellPetAuraMap.end())
1012 return &itr->second;
1013 else
1014 return nullptr;
1015}
SpellPetAuraMap mSpellPetAuraMap
Definition: SpellMgr.h:808

References mSpellPetAuraMap.

◆ GetPetDefaultSpellsEntry()

PetDefaultSpellsEntry const * SpellMgr::GetPetDefaultSpellsEntry ( int32  id) const
1046{
1047 PetDefaultSpellsMap::const_iterator itr = mPetDefaultSpellsMap.find(id);
1048 if (itr != mPetDefaultSpellsMap.end())
1049 return &itr->second;
1050 return nullptr;
1051}
PetDefaultSpellsMap mPetDefaultSpellsMap
Definition: SpellMgr.h:819

References mPetDefaultSpellsMap.

◆ GetPetLevelupSpellList()

PetLevelupSpellSet const * SpellMgr::GetPetLevelupSpellList ( uint32  petFamily) const
1037{
1038 PetLevelupSpellMap::const_iterator itr = mPetLevelupSpellMap.find(petFamily);
1039 if (itr != mPetLevelupSpellMap.end())
1040 return &itr->second;
1041 else
1042 return nullptr;
1043}
PetLevelupSpellMap mPetLevelupSpellMap
Definition: SpellMgr.h:818

References mPetLevelupSpellMap.

◆ GetPrevSpellInChain()

uint32 SpellMgr::GetPrevSpellInChain ( uint32  spell_id) const
581{
582 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
583 if (node->prev)
584 return node->prev->Id;
585
586 return 0;
587}

References GetSpellChainNode().

◆ GetSetOfSpellsInSpellGroupWithFlag()

void SpellMgr::GetSetOfSpellsInSpellGroupWithFlag ( uint32  group_id,
SpellGroupSpecialFlags  flag,
std::set< uint32 > &  availableElixirs 
) const
724{
725 for (SpellGroupMap::const_iterator itr = mSpellGroupMap.begin(); itr != mSpellGroupMap.end(); ++itr)
726 if (itr->second.groupId == group_id && itr->second.specialFlags == flag)
727 availableElixirs.insert(itr->first); // insert spell id
728}
SpellGroupMap mSpellGroupMap
Definition: SpellMgr.h:801

References mSpellGroupMap.

◆ GetSkillLineAbilityMapBounds()

SkillLineAbilityMapBounds SpellMgr::GetSkillLineAbilityMapBounds ( uint32  spell_id) const
1004{
1005 return mSkillLineAbilityMap.equal_range(spell_id);
1006}
SkillLineAbilityMap mSkillLineAbilityMap
Definition: SpellMgr.h:817

References mSkillLineAbilityMap.

◆ GetSpellAreaForAreaMapBounds()

SpellAreaForAreaMapBounds SpellMgr::GetSpellAreaForAreaMapBounds ( uint32  area_id) const
1074{
1075 return mSpellAreaForAreaMap.equal_range(area_id);
1076}
SpellAreaForAreaMap mSpellAreaForAreaMap
Definition: SpellMgr.h:816

References mSpellAreaForAreaMap.

◆ GetSpellAreaForAuraMapBounds()

SpellAreaForAuraMapBounds SpellMgr::GetSpellAreaForAuraMapBounds ( uint32  spell_id) const
1069{
1070 return mSpellAreaForAuraMap.equal_range(spell_id);
1071}
SpellAreaForAuraMap mSpellAreaForAuraMap
Definition: SpellMgr.h:815

References mSpellAreaForAuraMap.

Referenced by LoadSpellAreas().

◆ GetSpellAreaForQuestEndMapBounds()

SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestEndMapBounds ( uint32  quest_id) const
1064{
1065 return mSpellAreaForQuestEndMap.equal_range(quest_id);
1066}
SpellAreaForQuestMap mSpellAreaForQuestEndMap
Definition: SpellMgr.h:814

References mSpellAreaForQuestEndMap.

◆ GetSpellAreaForQuestMapBounds()

SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestMapBounds ( uint32  quest_id) const
1059{
1060 return mSpellAreaForQuestMap.equal_range(quest_id);
1061}
SpellAreaForQuestMap mSpellAreaForQuestMap
Definition: SpellMgr.h:813

References mSpellAreaForQuestMap.

◆ GetSpellAreaMapBounds()

SpellAreaMapBounds SpellMgr::GetSpellAreaMapBounds ( uint32  spell_id) const
1054{
1055 return mSpellAreaMap.equal_range(spell_id);
1056}
SpellAreaMap mSpellAreaMap
Definition: SpellMgr.h:812

References mSpellAreaMap.

Referenced by LoadSpellAreas().

◆ GetSpellBonusData()

SpellBonusEntry const * SpellMgr::GetSpellBonusData ( uint32  spellId) const
964{
965 // Lookup data
966 SpellBonusMap::const_iterator itr = mSpellBonusMap.find(spellId);
967 if (itr != mSpellBonusMap.end())
968 return &itr->second;
969 // Not found, try lookup for 1 spell rank if exist
970 if (uint32 rank_1 = GetFirstSpellInChain(spellId))
971 {
972 SpellBonusMap::const_iterator itr2 = mSpellBonusMap.find(rank_1);
973 if (itr2 != mSpellBonusMap.end())
974 return &itr2->second;
975 }
976 return nullptr;
977}
uint32 GetFirstSpellInChain(uint32 spell_id) const
Definition: SpellMgr.cpp:555
SpellBonusMap mSpellBonusMap
Definition: SpellMgr.h:805

References GetFirstSpellInChain(), and mSpellBonusMap.

◆ GetSpellChainNode()

SpellChainNode const * SpellMgr::GetSpellChainNode ( uint32  spell_id) const
547{
548 SpellChainMap::const_iterator itr = mSpellChains.find(spell_id);
549 if (itr == mSpellChains.end())
550 return nullptr;
551
552 return &itr->second;
553}
SpellChainMap mSpellChains
Definition: SpellMgr.h:796

References mSpellChains.

Referenced by GetFirstSpellInChain(), GetLastSpellInChain(), GetNextSpellInChain(), GetPrevSpellInChain(), GetSpellRank(), and GetSpellWithRank().

◆ GetSpellCooldownOverride()

SpellCooldownOverride SpellMgr::GetSpellCooldownOverride ( uint32  spellId) const
2757{
2758 auto range = mSpellCooldownOverrideMap.find(spellId);
2759 return range->second;
2760}
SpellCooldownOverrideMap mSpellCooldownOverrideMap
Definition: SpellMgr.h:821

References mSpellCooldownOverrideMap.

◆ GetSpellDifficultyId()

uint32 SpellMgr::GetSpellDifficultyId ( uint32  spellId) const
480{
481 SpellDifficultySearcherMap::const_iterator i = mSpellDifficultySearcherMap.find(spellId);
482 return i == mSpellDifficultySearcherMap.end() ? 0 : (*i).second;
483}
SpellDifficultySearcherMap mSpellDifficultySearcherMap
Definition: SpellMgr.h:795

References mSpellDifficultySearcherMap.

Referenced by GetSpellIdForDifficulty().

◆ GetSpellEnchantProcEvent()

SpellEnchantProcEntry const * SpellMgr::GetSpellEnchantProcEvent ( uint32  enchId) const
1018{
1019 SpellEnchantProcEventMap::const_iterator itr = mSpellEnchantProcEventMap.find(enchId);
1020 if (itr != mSpellEnchantProcEventMap.end())
1021 return &itr->second;
1022 return nullptr;
1023}
SpellEnchantProcEventMap mSpellEnchantProcEventMap
Definition: SpellMgr.h:810

References mSpellEnchantProcEventMap.

◆ GetSpellForDifficultyFromSpell()

SpellInfo const * SpellMgr::GetSpellForDifficultyFromSpell ( SpellInfo const *  spell,
Unit const *  caster 
) const
533{
534 uint32 newSpellId = GetSpellIdForDifficulty(spell->Id, caster);
535 SpellInfo const* newSpell = GetSpellInfo(newSpellId);
536 if (!newSpell)
537 {
538 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellForDifficultyFromSpell: spell {} not found. Check spelldifficulty_dbc!", newSpellId);
539 return spell;
540 }
541
542 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellForDifficultyFromSpell: Spell id for instance mode is {} (original {})", newSpell->Id, spell->Id);
543 return newSpell;
544}
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:168
uint32 Id
Definition: SpellInfo.h:320
uint32 GetSpellIdForDifficulty(uint32 spellId, Unit const *caster) const
Definition: SpellMgr.cpp:490
SpellInfo const * GetSpellInfo(uint32 spellId) const
Definition: SpellMgr.h:726

References GetSpellIdForDifficulty(), GetSpellInfo(), SpellInfo::Id, and LOG_DEBUG.

◆ GetSpellGroup()

uint32 SpellMgr::GetSpellGroup ( uint32  spellid) const
662{
663 uint32 first_rank = GetFirstSpellInChain(spell_id);
664 SpellGroupMap::const_iterator itr = mSpellGroupMap.find(first_rank);
665 if (itr != mSpellGroupMap.end())
666 return itr->second.groupId;
667
668 return 0;
669}

References GetFirstSpellInChain(), and mSpellGroupMap.

Referenced by CheckSpellGroupStackRules().

◆ GetSpellGroupSpecialFlags()

SpellGroupSpecialFlags SpellMgr::GetSpellGroupSpecialFlags ( uint32  spell_id) const
672{
673 uint32 first_rank = GetFirstSpellInChain(spell_id);
674 SpellGroupMap::const_iterator itr = mSpellGroupMap.find(first_rank);
675 if (itr != mSpellGroupMap.end())
676 return itr->second.specialFlags;
677
679}
@ SPELL_GROUP_SPECIAL_FLAG_NONE
Definition: SpellMgr.h:335

References GetFirstSpellInChain(), mSpellGroupMap, and SPELL_GROUP_SPECIAL_FLAG_NONE.

Referenced by CheckSpellGroupStackRules().

◆ GetSpellIdForDifficulty()

uint32 SpellMgr::GetSpellIdForDifficulty ( uint32  spellId,
Unit const *  caster 
) const
491{
492 if (!GetSpellInfo(spellId))
493 return spellId;
494
495 if (!caster || !caster->GetMap() || (!caster->GetMap()->IsDungeon() && !caster->GetMap()->IsBattleground()))
496 return spellId;
497
498 uint32 mode = uint32(caster->GetMap()->GetSpawnMode());
499 if (mode >= MAX_DIFFICULTY)
500 {
501 LOG_ERROR("spells", "SpellMgr::GetSpellIdForDifficulty: Incorrect Difficulty for spell {}.", spellId);
502 return spellId; //return source spell
503 }
504
505 uint32 difficultyId = GetSpellDifficultyId(spellId);
506 if (!difficultyId)
507 return spellId; //return source spell, it has only REGULAR_DIFFICULTY
508
509 SpellDifficultyEntry const* difficultyEntry = sSpellDifficultyStore.LookupEntry(difficultyId);
510 if (!difficultyEntry)
511 {
512 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellIdForDifficulty: SpellDifficultyEntry not found for spell {}. This should never happen.", spellId);
513 return spellId; //return source spell
514 }
515
516 if (difficultyEntry->SpellID[mode] <= 0 && mode > DUNGEON_DIFFICULTY_HEROIC)
517 {
518 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellIdForDifficulty: spell {} mode {} spell is nullptr, using mode {}", spellId, mode, mode - 2);
519 mode -= 2;
520 }
521
522 if (difficultyEntry->SpellID[mode] <= 0)
523 {
524 LOG_ERROR("sql.sql", "SpellMgr::GetSpellIdForDifficulty: spell {} mode {} spell is 0. Check spelldifficulty_dbc!", spellId, mode);
525 return spellId;
526 }
527
528 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellIdForDifficulty: spellid for spell {} in mode {} is {}", spellId, mode, difficultyEntry->SpellID[mode]);
529 return uint32(difficultyEntry->SpellID[mode]);
530}
DBCStorage< SpellDifficultyEntry > sSpellDifficultyStore(SpellDifficultyfmt)
@ DUNGEON_DIFFICULTY_HEROIC
Definition: DBCEnums.h:270
#define MAX_DIFFICULTY
Definition: DBCEnums.h:283
uint32 GetSpellDifficultyId(uint32 spellId) const
Definition: SpellMgr.cpp:479
Definition: DBCStructure.h:1772
int32 SpellID[MAX_DIFFICULTY]
Definition: DBCStructure.h:1774

References DUNGEON_DIFFICULTY_HEROIC, WorldObject::GetMap(), Map::GetSpawnMode(), GetSpellDifficultyId(), GetSpellInfo(), Map::IsBattleground(), Map::IsDungeon(), LOG_DEBUG, LOG_ERROR, MAX_DIFFICULTY, SpellDifficultyEntry::SpellID, and sSpellDifficultyStore.

Referenced by GetSpellForDifficultyFromSpell().

◆ GetSpellInfo()

◆ GetSpellInfoStoreSize()

◆ GetSpellLearnSkill()

SpellLearnSkillNode const * SpellMgr::GetSpellLearnSkill ( uint32  spell_id) const
636{
637 SpellLearnSkillMap::const_iterator itr = mSpellLearnSkills.find(spell_id);
638 if (itr != mSpellLearnSkills.end())
639 return &itr->second;
640 else
641 return nullptr;
642}
SpellLearnSkillMap mSpellLearnSkills
Definition: SpellMgr.h:799

References mSpellLearnSkills.

◆ GetSpellLinked()

const std::vector< int32 > * SpellMgr::GetSpellLinked ( int32  spell_id) const
1031{
1032 SpellLinkedMap::const_iterator itr = mSpellLinkedMap.find(spell_id);
1033 return itr != mSpellLinkedMap.end() ? &(itr->second) : nullptr;
1034}
SpellLinkedMap mSpellLinkedMap
Definition: SpellMgr.h:809

References mSpellLinkedMap.

◆ GetSpellMixologyBonus()

float SpellMgr::GetSpellMixologyBonus ( uint32  spellId) const
995{
996 SpellMixologyMap::const_iterator itr = mSpellMixologyMap.find(spellId);
997 if (itr == mSpellMixologyMap.end())
998 return 30.0f;
999
1000 return itr->second;
1001}
SpellMixologyMap mSpellMixologyMap
Definition: SpellMgr.h:807

References mSpellMixologyMap.

◆ GetSpellProcEntry()

SpellProcEntry const * SpellMgr::GetSpellProcEntry ( uint32  spellId) const
891{
892 SpellProcMap::const_iterator itr = mSpellProcMap.find(spellId);
893 if (itr != mSpellProcMap.end())
894 return &itr->second;
895 return nullptr;
896}
SpellProcMap mSpellProcMap
Definition: SpellMgr.h:804

References mSpellProcMap.

◆ GetSpellProcEvent()

SpellProcEventEntry const * SpellMgr::GetSpellProcEvent ( uint32  spellId) const
731{
732 SpellProcEventMap::const_iterator itr = mSpellProcEventMap.find(spellId);
733 if (itr != mSpellProcEventMap.end())
734 return &itr->second;
735 return nullptr;
736}
SpellProcEventMap mSpellProcEventMap
Definition: SpellMgr.h:803

References mSpellProcEventMap.

◆ GetSpellRank()

uint8 SpellMgr::GetSpellRank ( uint32  spell_id) const
590{
591 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
592 return node->rank;
593
594 return 0;
595}

References GetSpellChainNode().

◆ GetSpellsRequiredForSpellBounds()

SpellRequiredMapBounds SpellMgr::GetSpellsRequiredForSpellBounds ( uint32  spell_id) const
610{
611 return mSpellReq.equal_range(spell_id);
612}
SpellRequiredMap mSpellReq
Definition: SpellMgr.h:798

References mSpellReq.

◆ GetSpellsRequiringSpellBounds()

SpellsRequiringSpellMapBounds SpellMgr::GetSpellsRequiringSpellBounds ( uint32  spell_id) const
615{
616 return mSpellsReqSpell.equal_range(spell_id);
617}
SpellsRequiringSpellMap mSpellsReqSpell
Definition: SpellMgr.h:797

References mSpellsReqSpell.

Referenced by IsSpellRequiringSpell().

◆ GetSpellTargetPosition()

SpellTargetPosition const * SpellMgr::GetSpellTargetPosition ( uint32  spell_id,
SpellEffIndex  effIndex 
) const
645{
646 SpellTargetPositionMap::const_iterator itr = mSpellTargetPositions.find(std::make_pair(spell_id, effIndex));
647 if (itr != mSpellTargetPositions.end())
648 return &itr->second;
649 return nullptr;
650}
SpellTargetPositionMap mSpellTargetPositions
Definition: SpellMgr.h:800

References mSpellTargetPositions.

◆ GetSpellThreatEntry()

SpellThreatEntry const * SpellMgr::GetSpellThreatEntry ( uint32  spellID) const
980{
981 SpellThreatMap::const_iterator itr = mSpellThreatMap.find(spellID);
982 if (itr != mSpellThreatMap.end())
983 return &itr->second;
984 else
985 {
986 uint32 firstSpell = GetFirstSpellInChain(spellID);
987 itr = mSpellThreatMap.find(firstSpell);
988 if (itr != mSpellThreatMap.end())
989 return &itr->second;
990 }
991 return nullptr;
992}
SpellThreatMap mSpellThreatMap
Definition: SpellMgr.h:806

References GetFirstSpellInChain(), and mSpellThreatMap.

◆ GetSpellWithRank()

uint32 SpellMgr::GetSpellWithRank ( uint32  spell_id,
uint32  rank,
bool  strict = false 
) const
598{
599 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
600 {
601 if (rank != node->rank)
602 return GetSpellWithRank(node->rank < rank ? node->next->Id : node->prev->Id, rank, strict);
603 }
604 else if (strict && rank > 1)
605 return 0;
606 return spell_id;
607}
uint32 GetSpellWithRank(uint32 spell_id, uint32 rank, bool strict=false) const
Definition: SpellMgr.cpp:597

References GetSpellChainNode(), and GetSpellWithRank().

Referenced by GetSpellWithRank().

◆ HasSpellCooldownOverride()

bool SpellMgr::HasSpellCooldownOverride ( uint32  spellId) const
2752{
2753 return mSpellCooldownOverrideMap.find(spellId) != mSpellCooldownOverrideMap.end();
2754}

References mSpellCooldownOverrideMap.

◆ instance()

SpellMgr * SpellMgr::instance ( )
static
365{
366 static SpellMgr instance;
367 return &instance;
368}
Definition: SpellMgr.h:640
static SpellMgr * instance()
Definition: SpellMgr.cpp:364

References instance().

Referenced by instance().

◆ IsAdditionalTalentSpell()

bool SpellMgr::IsAdditionalTalentSpell ( uint32  spellId) const
631{
632 return mTalentSpellAdditionalSet.find(spellId) != mTalentSpellAdditionalSet.end();
633}
TalentAdditionalSet mTalentSpellAdditionalSet
Definition: SpellMgr.h:822

References mTalentSpellAdditionalSet.

◆ IsArenaAllowedEnchancment()

bool SpellMgr::IsArenaAllowedEnchancment ( uint32  ench_id) const
1026{
1027 return mEnchantCustomAttr[ench_id];
1028}
EnchantCustomAttribute mEnchantCustomAttr
Definition: SpellMgr.h:811

References mEnchantCustomAttr.

◆ IsSpellProcEventCanTriggeredBy()

bool SpellMgr::IsSpellProcEventCanTriggeredBy ( SpellInfo const *  spellProto,
SpellProcEventEntry const *  spellProcEvent,
uint32  EventProcFlag,
ProcEventInfo const &  eventInfo,
bool  active 
) const

no aura with only PROC_FLAG_DONE_PERIODIC and spellFamilyName == 0 can proc from a HOT.

Aura must have positive procflags for a HOT to proc

Aura must have negative or neutral(PROC_FLAG_DONE_PERIODIC only) procflags for a DOT to proc

No aura that only has PROC_FLAG_TAKEN_PERIODIC can proc from a HOT.

Aura must have positive procflags for a HOT to proc

Aura must have negative or neutral(PROC_FLAG_TAKEN_PERIODIC only) procflags for a DOT to proc

739{
740 // No extra req need
741 uint32 procEvent_procEx = PROC_EX_NONE;
742 uint32 procEvent_procPhase = PROC_SPELL_PHASE_HIT;
743
744 uint32 procFlags = eventInfo.GetTypeMask();
745 uint32 procExtra = eventInfo.GetHitMask();
746 uint32 procPhase = eventInfo.GetSpellPhaseMask();
747 SpellInfo const* procSpellInfo = eventInfo.GetSpellInfo();
748
749 // check prockFlags for condition
750 if ((procFlags & EventProcFlag) == 0)
751 return false;
752
753 // Xinef: Always trigger for this, including TAKEN_DAMAGE
755 return true;
756
757 bool hasFamilyMask = false;
758
759 if (procFlags & PROC_FLAG_DONE_PERIODIC)
760 {
761 if (procExtra & PROC_EX_INTERNAL_HOT)
762 {
763 if (EventProcFlag == PROC_FLAG_DONE_PERIODIC)
764 {
766 if (!spellProto->SpellFamilyName)
767 return false;
768 }
771 return false;
772 }
774 else if (EventProcFlag != PROC_FLAG_DONE_PERIODIC)
776 return false;
777 }
778
779 if (procFlags & PROC_FLAG_TAKEN_PERIODIC)
780 {
781 if (procExtra & PROC_EX_INTERNAL_HOT)
782 {
784 if (EventProcFlag == PROC_FLAG_TAKEN_PERIODIC)
785 return false;
788 return false;
789 }
791 else if (EventProcFlag != PROC_FLAG_TAKEN_PERIODIC)
793 return false;
794 }
795
796 // Trap casts are active by default
797 if (procFlags & PROC_FLAG_DONE_TRAP_ACTIVATION)
798 active = true;
799
800 if (spellProcEvent) // Exist event data
801 {
802 // Store extra req
803 procEvent_procEx = spellProcEvent->procEx;
804 procEvent_procPhase = spellProcEvent->procPhase;
805
806 // For melee triggers
807 if (!procSpellInfo)
808 {
809 // Check (if set) for school (melee attack have Normal school)
810 if (spellProcEvent->schoolMask && (spellProcEvent->schoolMask & SPELL_SCHOOL_MASK_NORMAL) == 0)
811 return false;
812 }
813 else // For spells need check school/spell family/family mask
814 {
815 // Check (if set) for school
816 if (spellProcEvent->schoolMask && (spellProcEvent->schoolMask & procSpellInfo->SchoolMask) == 0)
817 return false;
818
819 // Check (if set) for spellFamilyName
820 if (spellProcEvent->spellFamilyName && (spellProcEvent->spellFamilyName != procSpellInfo->SpellFamilyName))
821 return false;
822
823 // spellFamilyName is Ok need check for spellFamilyMask if present
824 if (spellProcEvent->spellFamilyMask)
825 {
826 if (!(spellProcEvent->spellFamilyMask & procSpellInfo->SpellFamilyFlags))
827 return false;
828 hasFamilyMask = true;
829 // Some spells are not considered as active even with have spellfamilyflags
830 if (!(procEvent_procEx & PROC_EX_ONLY_ACTIVE_SPELL))
831 active = true;
832 }
833
834 // Check tick numbers
835 if (procEvent_procEx & PROC_EX_ONLY_FIRST_TICK)
836 {
837 if (Spell const* procSpell = eventInfo.GetProcSpell())
838 {
839 if (procSpell->GetTriggeredByAuraTickNumber() > 1)
840 {
841 return false;
842 }
843 }
844 }
845 }
846 }
847
848 if (procExtra & (PROC_EX_INTERNAL_REQ_FAMILY))
849 {
850 if (!hasFamilyMask)
851 return false;
852 }
853
854 if (!(procEvent_procPhase & procPhase))
855 {
856 return false;
857 }
858
859 // Check for extra req (if none) and hit/crit
860 if (procEvent_procEx == PROC_EX_NONE)
861 {
862 // No extra req, so can trigger only for hit/crit - spell has to be active
863 if ((procExtra & (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT)) && active)
864 return true;
865 }
866 else // Passive spells hits here only if resist/reflect/immune/evade
867 {
868 if (procExtra & AURA_SPELL_PROC_EX_MASK)
869 {
870 // if spell marked as procing only from not active spells
871 if (active && procEvent_procEx & PROC_EX_NOT_ACTIVE_SPELL)
872 return false;
873 // if spell marked as procing only from active spells
874 if (!active && procEvent_procEx & PROC_EX_ONLY_ACTIVE_SPELL)
875 return false;
876 // Exist req for PROC_EX_EX_TRIGGER_ALWAYS
877 if (procEvent_procEx & PROC_EX_EX_TRIGGER_ALWAYS)
878 return true;
879 // PROC_EX_NOT_ACTIVE_SPELL and PROC_EX_ONLY_ACTIVE_SPELL flags handle: if passed checks before
880 if ((procExtra & (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT)) && ((procEvent_procEx & (AURA_SPELL_PROC_EX_MASK)) == 0))
881 return true;
882 }
883 // Check Extra Requirement like (hit/crit/miss/resist/parry/dodge/block/immune/reflect/absorb and other)
884 if (procEvent_procEx & procExtra)
885 return true;
886 }
887 return false;
888}
#define AURA_SPELL_PROC_EX_MASK
Definition: SpellMgr.h:225
@ PROC_EX_NONE
Definition: SpellMgr.h:193
@ PROC_EX_CRITICAL_HIT
Definition: SpellMgr.h:195
@ PROC_EX_NORMAL_HIT
Definition: SpellMgr.h:194
@ PROC_EX_INTERNAL_HOT
Definition: SpellMgr.h:220
@ PROC_EX_ONLY_ACTIVE_SPELL
Definition: SpellMgr.h:212
@ PROC_EX_ONLY_FIRST_TICK
Definition: SpellMgr.h:215
@ PROC_EX_EX_TRIGGER_ALWAYS
Definition: SpellMgr.h:210
@ PROC_EX_NOT_ACTIVE_SPELL
Definition: SpellMgr.h:209
@ PROC_EX_INTERNAL_REQ_FAMILY
Definition: SpellMgr.h:222
@ PROC_SPELL_PHASE_HIT
Definition: SpellMgr.h:244
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS
Definition: SpellMgr.h:128
@ PROC_FLAG_DONE_PERIODIC
Definition: SpellMgr.h:134
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS
Definition: SpellMgr.h:122
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG
Definition: SpellMgr.h:132
@ PROC_FLAG_TAKEN_PERIODIC
Definition: SpellMgr.h:135
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG
Definition: SpellMgr.h:126
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG
Definition: SpellMgr.h:125
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS
Definition: SpellMgr.h:129
@ PROC_FLAG_TAKEN_DAMAGE
Definition: SpellMgr.h:137
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS
Definition: SpellMgr.h:123
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
Definition: SpellMgr.h:131
@ SPELL_SCHOOL_MASK_NORMAL
Definition: SharedDefines.h:297
Definition: Spell.h:284
uint32 SchoolMask
Definition: SpellInfo.h:392

References AURA_SPELL_PROC_EX_MASK, ProcEventInfo::GetHitMask(), ProcEventInfo::GetProcSpell(), ProcEventInfo::GetSpellInfo(), ProcEventInfo::GetSpellPhaseMask(), ProcEventInfo::GetTypeMask(), PROC_EX_CRITICAL_HIT, PROC_EX_EX_TRIGGER_ALWAYS, PROC_EX_INTERNAL_HOT, PROC_EX_INTERNAL_REQ_FAMILY, PROC_EX_NONE, PROC_EX_NORMAL_HIT, PROC_EX_NOT_ACTIVE_SPELL, PROC_EX_ONLY_ACTIVE_SPELL, PROC_EX_ONLY_FIRST_TICK, PROC_FLAG_DEATH, PROC_FLAG_DONE_PERIODIC, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_DONE_TRAP_ACTIVATION, PROC_FLAG_KILL, PROC_FLAG_KILLED, PROC_FLAG_TAKEN_DAMAGE, PROC_FLAG_TAKEN_PERIODIC, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS, PROC_SPELL_PHASE_HIT, SpellProcEventEntry::procEx, SpellProcEventEntry::procPhase, SpellInfo::SchoolMask, SpellProcEventEntry::schoolMask, SPELL_SCHOOL_MASK_NORMAL, SpellInfo::SpellFamilyFlags, SpellProcEventEntry::spellFamilyMask, SpellInfo::SpellFamilyName, and SpellProcEventEntry::spellFamilyName.

◆ IsSpellRequiringSpell()

bool SpellMgr::IsSpellRequiringSpell ( uint32  spellid,
uint32  req_spellid 
) const
620{
621 SpellsRequiringSpellMapBounds spellsRequiringSpell = GetSpellsRequiringSpellBounds(req_spellid);
622 for (SpellsRequiringSpellMap::const_iterator itr = spellsRequiringSpell.first; itr != spellsRequiringSpell.second; ++itr)
623 {
624 if (itr->second == spellid)
625 return true;
626 }
627 return false;
628}
std::pair< SpellsRequiringSpellMap::const_iterator, SpellsRequiringSpellMap::const_iterator > SpellsRequiringSpellMapBounds
Definition: SpellMgr.h:570
SpellsRequiringSpellMapBounds GetSpellsRequiringSpellBounds(uint32 spell_id) const
Definition: SpellMgr.cpp:614

References GetSpellsRequiringSpellBounds().

Referenced by LoadSpellRequired().

◆ IsSpellValid()

◆ LoadEnchantCustomAttr()

void SpellMgr::LoadEnchantCustomAttr ( )
Todo:
: find a better check
2168{
2169 uint32 oldMSTime = getMSTime();
2170
2171 uint32 size = sSpellItemEnchantmentStore.GetNumRows();
2172 mEnchantCustomAttr.resize(size);
2173
2174 for (uint32 i = 0; i < size; ++i)
2175 mEnchantCustomAttr[i] = 0;
2176
2177 uint32 count = 0;
2178 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2179 {
2180 SpellInfo const* spellInfo = GetSpellInfo(i);
2181 if (!spellInfo)
2182 continue;
2183
2185 // Xinef: commented second part, fixes warlock enchants like firestone, spellstone
2186 if (!spellInfo->HasAttribute(SPELL_ATTR2_ENCHANT_OWN_ITEM_ONLY)/* || !spellInfo->HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFTED)*/)
2187 continue;
2188
2189 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
2190 {
2191 if (spellInfo->Effects[j].Effect == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY)
2192 {
2193 uint32 enchId = spellInfo->Effects[j].MiscValue;
2194 SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchId);
2195 if (!ench)
2196 continue;
2197 mEnchantCustomAttr[enchId] = true;
2198 ++count;
2199 break;
2200 }
2201 }
2202 }
2203
2204 LOG_INFO("server.loading", ">> Loaded {} Custom Enchant Attributes in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2205 LOG_INFO("server.loading", " ");
2206}
#define LOG_INFO(filterType__,...)
Definition: Log.h:164
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:131
uint32 getMSTime()
Definition: Timer.h:103
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition: SharedDefines.h:832
@ SPELL_ATTR2_ENCHANT_OWN_ITEM_ONLY
Definition: SharedDefines.h:469
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:415
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition: SpellInfo.h:393
Definition: DBCStructure.h:1841

References SpellInfo::Effects, getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), GetSpellInfoStoreSize(), SpellInfo::HasAttribute(), LOG_INFO, MAX_SPELL_EFFECTS, mEnchantCustomAttr, SPELL_ATTR2_ENCHANT_OWN_ITEM_ONLY, SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY, and sSpellItemEnchantmentStore.

◆ LoadPetDefaultSpells()

void SpellMgr::LoadPetDefaultSpells ( )
2401{
2402 uint32 oldMSTime = getMSTime();
2403
2404 mPetDefaultSpellsMap.clear();
2405
2406 uint32 countCreature = 0;
2407 uint32 countData = 0;
2408
2409 CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
2410 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
2411 {
2412 if (!itr->second.PetSpellDataId)
2413 continue;
2414
2415 // for creature with PetSpellDataId get default pet spells from dbc
2416 CreatureSpellDataEntry const* spellDataEntry = sCreatureSpellDataStore.LookupEntry(itr->second.PetSpellDataId);
2417 if (!spellDataEntry)
2418 continue;
2419
2420 int32 petSpellsId = -int32(itr->second.PetSpellDataId);
2421 PetDefaultSpellsEntry petDefSpells;
2422 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2423 petDefSpells.spellid[j] = spellDataEntry->spellId[j];
2424
2425 if (LoadPetDefaultSpells_helper(&itr->second, petDefSpells))
2426 {
2427 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2428 ++countData;
2429 }
2430 }
2431
2432 LOG_INFO("server.loading", ">> Loaded Addition Spells For {} Pet Spell Data Entries in {} ms", countData, GetMSTimeDiffToNow(oldMSTime));
2433 LOG_INFO("server.loading", " ");
2434
2435 LOG_INFO("server.loading", "Loading Summonable Creature Templates...");
2436 oldMSTime = getMSTime();
2437
2438 // different summon spells
2439 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2440 {
2441 SpellInfo const* spellInfo = GetSpellInfo(i);
2442 if (!spellInfo)
2443 continue;
2444
2445 for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
2446 {
2447 if (spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON || spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON_PET)
2448 {
2449 uint32 creature_id = spellInfo->Effects[k].MiscValue;
2450 CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id);
2451 if (!cInfo)
2452 continue;
2453
2454 // already loaded
2455 if (cInfo->PetSpellDataId)
2456 continue;
2457
2458 // for creature without PetSpellDataId get default pet spells from creature_template
2459 int32 petSpellsId = cInfo->Entry;
2460 if (mPetDefaultSpellsMap.find(cInfo->Entry) != mPetDefaultSpellsMap.end())
2461 continue;
2462
2463 PetDefaultSpellsEntry petDefSpells;
2464 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2465 petDefSpells.spellid[j] = cInfo->spells[j];
2466
2467 if (LoadPetDefaultSpells_helper(cInfo, petDefSpells))
2468 {
2469 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2470 ++countCreature;
2471 }
2472 }
2473 }
2474 }
2475
2476 LOG_INFO("server.loading", ">> Loaded {} Summonable Creature emplates in {} ms", countCreature, GetMSTimeDiffToNow(oldMSTime));
2477 LOG_INFO("server.loading", " ");
2478}
std::int32_t int32
Definition: Define.h:103
DBCStorage< CreatureSpellDataEntry > sCreatureSpellDataStore(CreatureSpellDatafmt)
std::unordered_map< uint32, CreatureTemplate > CreatureTemplateContainer
Definition: CreatureData.h:295
bool LoadPetDefaultSpells_helper(CreatureTemplate const *cInfo, PetDefaultSpellsEntry &petDefSpells)
Definition: SpellMgr.cpp:2352
@ SPELL_EFFECT_SUMMON_PET
Definition: SharedDefines.h:834
@ SPELL_EFFECT_SUMMON
Definition: SharedDefines.h:806
#define MAX_CREATURE_SPELL_DATA_SLOT
Definition: DBCStructure.h:807
Definition: CreatureData.h:189
uint32 Entry
Definition: CreatureData.h:190
uint32 spells[MAX_CREATURE_SPELLS]
Definition: CreatureData.h:231
uint32 PetSpellDataId
Definition: CreatureData.h:232
Definition: SpellMgr.h:592
uint32 spellid[MAX_CREATURE_SPELL_DATA_SLOT]
Definition: SpellMgr.h:593
Definition: DBCStructure.h:810
uint32 spellId[MAX_CREATURE_SPELL_DATA_SLOT]
Definition: DBCStructure.h:812

References SpellInfo::Effects, CreatureTemplate::Entry, getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), GetSpellInfoStoreSize(), LoadPetDefaultSpells_helper(), LOG_INFO, MAX_CREATURE_SPELL_DATA_SLOT, MAX_SPELL_EFFECTS, mPetDefaultSpellsMap, CreatureTemplate::PetSpellDataId, sCreatureSpellDataStore, sObjectMgr, SPELL_EFFECT_SUMMON, SPELL_EFFECT_SUMMON_PET, PetDefaultSpellsEntry::spellid, CreatureSpellDataEntry::spellId, and CreatureTemplate::spells.

◆ LoadPetLevelupSpellMap()

void SpellMgr::LoadPetLevelupSpellMap ( )
2307{
2308 uint32 oldMSTime = getMSTime();
2309
2310 mPetLevelupSpellMap.clear(); // need for reload case
2311
2312 uint32 count = 0;
2313 uint32 family_count = 0;
2314
2315 for (uint32 i = 0; i < sCreatureFamilyStore.GetNumRows(); ++i)
2316 {
2317 CreatureFamilyEntry const* creatureFamily = sCreatureFamilyStore.LookupEntry(i);
2318 if (!creatureFamily) // not exist
2319 continue;
2320
2321 for (uint8 j = 0; j < 2; ++j)
2322 {
2323 if (!creatureFamily->skillLine[j])
2324 continue;
2325
2326 for (SkillLineAbilityEntry const* skillLine : GetSkillLineAbilitiesBySkillLine(creatureFamily->skillLine[j]))
2327 {
2328 if (skillLine->AcquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN)
2329 continue;
2330
2331 SpellInfo const* spell = GetSpellInfo(skillLine->Spell);
2332 if (!spell) // not exist or triggered or talent
2333 continue;
2334
2335 if (!spell->SpellLevel)
2336 continue;
2337
2338 PetLevelupSpellSet& spellSet = mPetLevelupSpellMap[creatureFamily->ID];
2339 if (spellSet.empty())
2340 ++family_count;
2341
2342 spellSet.insert(PetLevelupSpellSet::value_type(spell->SpellLevel, spell->Id));
2343 ++count;
2344 }
2345 }
2346 }
2347
2348 LOG_INFO("server.loading", ">> Loaded {} Pet Levelup And Default Spells For {} Families in {} ms", count, family_count, GetMSTimeDiffToNow(oldMSTime));
2349 LOG_INFO("server.loading", " ");
2350}
const std::vector< SkillLineAbilityEntry const * > & GetSkillLineAbilitiesBySkillLine(uint32 skillLine)
Definition: DBCStores.cpp:916
DBCStorage< CreatureFamilyEntry > sCreatureFamilyStore(CreatureFamilyfmt)
std::multimap< uint32, uint32 > PetLevelupSpellSet
Definition: SpellMgr.h:586
@ SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN
Definition: DBCEnums.h:361
uint32 SpellLevel
Definition: SpellInfo.h:360
Definition: DBCStructure.h:754
uint32 ID
Definition: DBCStructure.h:755
uint32 skillLine[2]
Definition: DBCStructure.h:760
Definition: DBCStructure.h:1598

References getMSTime(), GetMSTimeDiffToNow(), GetSkillLineAbilitiesBySkillLine(), GetSpellInfo(), SpellInfo::Id, CreatureFamilyEntry::ID, LOG_INFO, mPetLevelupSpellMap, sCreatureFamilyStore, SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN, CreatureFamilyEntry::skillLine, and SpellInfo::SpellLevel.

◆ LoadSkillLineAbilityMap()

void SpellMgr::LoadSkillLineAbilityMap ( )
2083{
2084 uint32 oldMSTime = getMSTime();
2085
2086 mSkillLineAbilityMap.clear();
2087
2088 uint32 count = 0;
2089
2090 for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); ++i)
2091 {
2092 SkillLineAbilityEntry const* SkillInfo = sSkillLineAbilityStore.LookupEntry(i);
2093 if (!SkillInfo)
2094 continue;
2095
2096 mSkillLineAbilityMap.insert(SkillLineAbilityMap::value_type(SkillInfo->Spell, SkillInfo));
2097 ++count;
2098 }
2099
2100 LOG_INFO("server.loading", ">> Loaded {} SkillLineAbility MultiMap Data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2101 LOG_INFO("server.loading", " ");
2102}
DBCStorage< SkillLineAbilityEntry > sSkillLineAbilityStore(SkillLineAbilityfmt)
uint32 Spell
Definition: DBCStructure.h:1601

References getMSTime(), GetMSTimeDiffToNow(), LOG_INFO, mSkillLineAbilityMap, SkillLineAbilityEntry::Spell, and sSkillLineAbilityStore.

◆ LoadSpellAreas()

void SpellMgr::LoadSpellAreas ( )
2481{
2482 uint32 oldMSTime = getMSTime();
2483
2484 mSpellAreaMap.clear(); // need for reload case
2485 mSpellAreaForQuestMap.clear();
2487 mSpellAreaForAuraMap.clear();
2488
2489 // 0 1 2 3 4 5 6 7 8 9
2490 QueryResult result = WorldDatabase.Query("SELECT spell, area, quest_start, quest_start_status, quest_end_status, quest_end, aura_spell, racemask, gender, autocast FROM spell_area");
2491
2492 if (!result)
2493 {
2494 LOG_WARN("server.loading", ">> Loaded 0 spell area requirements. DB table `spell_area` is empty.");
2495 LOG_INFO("server.loading", " ");
2496 return;
2497 }
2498
2499 uint32 count = 0;
2500 do
2501 {
2502 Field* fields = result->Fetch();
2503
2504 uint32 spell = fields[0].Get<uint32>();
2505 SpellArea spellArea;
2506 spellArea.spellId = spell;
2507 spellArea.areaId = fields[1].Get<uint32>();
2508 spellArea.questStart = fields[2].Get<uint32>();
2509 spellArea.questStartStatus = fields[3].Get<uint32>();
2510 spellArea.questEndStatus = fields[4].Get<uint32>();
2511 spellArea.questEnd = fields[5].Get<uint32>();
2512 spellArea.auraSpell = fields[6].Get<int32>();
2513 spellArea.raceMask = fields[7].Get<uint32>();
2514 spellArea.gender = Gender(fields[8].Get<uint8>());
2515 spellArea.autocast = fields[9].Get<bool>();
2516
2517 if (SpellInfo const* spellInfo = GetSpellInfo(spell))
2518 {
2519 if (spellArea.autocast)
2520 const_cast<SpellInfo*>(spellInfo)->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
2521 }
2522 else
2523 {
2524 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` does not exist", spell);
2525 continue;
2526 }
2527
2528 {
2529 bool ok = true;
2530 SpellAreaMapBounds sa_bounds = GetSpellAreaMapBounds(spellArea.spellId);
2531 for (SpellAreaMap::const_iterator itr = sa_bounds.first; itr != sa_bounds.second; ++itr)
2532 {
2533 if (spellArea.spellId != itr->second.spellId)
2534 continue;
2535 if (spellArea.areaId != itr->second.areaId)
2536 continue;
2537 if (spellArea.questStart != itr->second.questStart)
2538 continue;
2539 if (spellArea.auraSpell != itr->second.auraSpell)
2540 continue;
2541 if ((spellArea.raceMask & itr->second.raceMask) == 0)
2542 continue;
2543 if (spellArea.gender != itr->second.gender)
2544 continue;
2545
2546 // duplicate by requirements
2547 ok = false;
2548 break;
2549 }
2550
2551 if (!ok)
2552 {
2553 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` already listed with similar requirements.", spell);
2554 continue;
2555 }
2556 }
2557
2558 if (spellArea.areaId && !sAreaTableStore.LookupEntry(spellArea.areaId))
2559 {
2560 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong area ({}) requirement", spell, spellArea.areaId);
2561 continue;
2562 }
2563
2564 if (spellArea.questStart && !sObjectMgr->GetQuestTemplate(spellArea.questStart))
2565 {
2566 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong start quest ({}) requirement", spell, spellArea.questStart);
2567 continue;
2568 }
2569
2570 if (spellArea.questEnd)
2571 {
2572 if (!sObjectMgr->GetQuestTemplate(spellArea.questEnd))
2573 {
2574 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong end quest ({}) requirement", spell, spellArea.questEnd);
2575 continue;
2576 }
2577 }
2578
2579 if (spellArea.auraSpell)
2580 {
2581 SpellInfo const* spellInfo = GetSpellInfo(std::abs(spellArea.auraSpell));
2582 if (!spellInfo)
2583 {
2584 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong aura spell ({}) requirement", spell, std::abs(spellArea.auraSpell));
2585 continue;
2586 }
2587
2588 if (uint32(std::abs(spellArea.auraSpell)) == spellArea.spellId)
2589 {
2590 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement for itself", spell, std::abs(spellArea.auraSpell));
2591 continue;
2592 }
2593
2594 // not allow autocast chains by auraSpell field (but allow use as alternative if not present)
2595 if (spellArea.autocast && spellArea.auraSpell > 0)
2596 {
2597 bool chain = false;
2598 SpellAreaForAuraMapBounds saBound = GetSpellAreaForAuraMapBounds(spellArea.spellId);
2599 for (SpellAreaForAuraMap::const_iterator itr = saBound.first; itr != saBound.second; ++itr)
2600 {
2601 if (itr->second->autocast && itr->second->auraSpell > 0)
2602 {
2603 chain = true;
2604 break;
2605 }
2606 }
2607
2608 if (chain)
2609 {
2610 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement that itself autocast from aura", spell, spellArea.auraSpell);
2611 continue;
2612 }
2613
2614 SpellAreaMapBounds saBound2 = GetSpellAreaMapBounds(spellArea.auraSpell);
2615 for (SpellAreaMap::const_iterator itr2 = saBound2.first; itr2 != saBound2.second; ++itr2)
2616 {
2617 if (itr2->second.autocast && itr2->second.auraSpell > 0)
2618 {
2619 chain = true;
2620 break;
2621 }
2622 }
2623
2624 if (chain)
2625 {
2626 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement that itself autocast from aura", spell, spellArea.auraSpell);
2627 continue;
2628 }
2629 }
2630 }
2631
2632 if (spellArea.raceMask && (spellArea.raceMask & RACEMASK_ALL_PLAYABLE) == 0)
2633 {
2634 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong race mask ({}) requirement", spell, spellArea.raceMask);
2635 continue;
2636 }
2637
2638 if (spellArea.gender != GENDER_NONE && spellArea.gender != GENDER_FEMALE && spellArea.gender != GENDER_MALE)
2639 {
2640 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong gender ({}) requirement", spell, spellArea.gender);
2641 continue;
2642 }
2643
2644 SpellArea const* sa = &mSpellAreaMap.insert(SpellAreaMap::value_type(spell, spellArea))->second;
2645
2646 // for search by current zone/subzone at zone/subzone change
2647 if (spellArea.areaId)
2648 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(spellArea.areaId, sa));
2649
2650 // for search at quest start/reward
2651 if (spellArea.questStart)
2652 mSpellAreaForQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa));
2653
2654 // for search at quest start/reward
2655 if (spellArea.questEnd)
2656 mSpellAreaForQuestEndMap.insert(SpellAreaForQuestMap::value_type(spellArea.questEnd, sa));
2657
2658 // for search at aura apply
2659 if (spellArea.auraSpell)
2660 mSpellAreaForAuraMap.insert(SpellAreaForAuraMap::value_type(std::abs(spellArea.auraSpell), sa));
2661
2662 ++count;
2663 } while (result->NextRow());
2664
2665 if (sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE) > 0)
2666 {
2667 LOG_INFO("server.loading", ">> Using ICC Buff Horde: {}", sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE));
2668 SpellArea spellAreaICCBuffHorde = { sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE), ICC_AREA, 0, 0, 0, ICC_RACEMASK_HORDE, Gender(2), 64, 11, 1 };
2669 SpellArea const* saICCBuffHorde = &mSpellAreaMap.insert(SpellAreaMap::value_type(sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE), spellAreaICCBuffHorde))->second;
2670 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(ICC_AREA, saICCBuffHorde));
2671 ++count;
2672 }
2673 else
2674 LOG_INFO("server.loading", ">> ICC Buff Horde: disabled");
2675
2676 if (sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE) > 0)
2677 {
2678 LOG_INFO("server.loading", ">> Using ICC Buff Alliance: {}", sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE));
2679 SpellArea spellAreaICCBuffAlliance = { sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE), ICC_AREA, 0, 0, 0, ICC_RACEMASK_ALLIANCE, Gender(2), 64, 11, 1 };
2680 SpellArea const* saICCBuffAlliance = &mSpellAreaMap.insert(SpellAreaMap::value_type(sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE), spellAreaICCBuffAlliance))->second;
2681 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(ICC_AREA, saICCBuffAlliance));
2682 ++count;
2683 }
2684 else
2685 LOG_INFO("server.loading", ">> ICC Buff Alliance: disabled");
2686
2687 LOG_INFO("server.loading", ">> Loaded {} Spell Area Requirements in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2688 LOG_INFO("server.loading", " ");
2689}
#define LOG_WARN(filterType__,...)
Definition: Log.h:160
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
@ CONFIG_ICC_BUFF_ALLIANCE
Definition: IWorld.h:389
@ CONFIG_ICC_BUFF_HORDE
Definition: IWorld.h:388
std::pair< SpellAreaMap::const_iterator, SpellAreaMap::const_iterator > SpellAreaMapBounds
Definition: SpellMgr.h:547
@ ICC_RACEMASK_HORDE
Definition: SpellMgr.h:522
@ ICC_AREA
Definition: SpellMgr.h:521
@ ICC_RACEMASK_ALLIANCE
Definition: SpellMgr.h:523
std::pair< SpellAreaForAuraMap::const_iterator, SpellAreaForAuraMap::const_iterator > SpellAreaForAuraMapBounds
Definition: SpellMgr.h:549
std::shared_ptr< ResultSet > QueryResult
Definition: DatabaseEnvFwd.h:28
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
Gender
Definition: SharedDefines.h:60
@ GENDER_MALE
Definition: SharedDefines.h:61
@ GENDER_FEMALE
Definition: SharedDefines.h:62
@ GENDER_NONE
Definition: SharedDefines.h:63
@ SPELL_ATTR0_NO_AURA_CANCEL
Definition: SharedDefines.h:413
#define RACEMASK_ALL_PLAYABLE
Definition: SharedDefines.h:97
#define sWorld
Definition: World.h:444
Class used to access individual fields of database query result.
Definition: Field.h:99
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition: Field.h:113
Definition: SpellMgr.h:527
uint32 spellId
Definition: SpellMgr.h:528
SpellAreaMapBounds GetSpellAreaMapBounds(uint32 spell_id) const
Definition: SpellMgr.cpp:1053
SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds(uint32 spell_id) const
Definition: SpellMgr.cpp:1068

References CONFIG_ICC_BUFF_ALLIANCE, CONFIG_ICC_BUFF_HORDE, GENDER_FEMALE, GENDER_MALE, GENDER_NONE, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), GetSpellAreaForAuraMapBounds(), GetSpellAreaMapBounds(), GetSpellInfo(), ICC_AREA, ICC_RACEMASK_ALLIANCE, ICC_RACEMASK_HORDE, LOG_ERROR, LOG_INFO, LOG_WARN, mSpellAreaForAreaMap, mSpellAreaForAuraMap, mSpellAreaForQuestEndMap, mSpellAreaForQuestMap, mSpellAreaMap, RACEMASK_ALL_PLAYABLE, sAreaTableStore, sObjectMgr, SPELL_ATTR0_NO_AURA_CANCEL, SpellArea::spellId, sWorld, and WorldDatabase.

◆ LoadSpellBonuses()

void SpellMgr::LoadSpellBonuses ( )
1965{
1966 uint32 oldMSTime = getMSTime();
1967
1968 mSpellBonusMap.clear(); // need for reload case
1969
1970 // 0 1 2 3 4
1971 QueryResult result = WorldDatabase.Query("SELECT entry, direct_bonus, dot_bonus, ap_bonus, ap_dot_bonus FROM spell_bonus_data");
1972 if (!result)
1973 {
1974 LOG_WARN("server.loading", ">> Loaded 0 spell bonus data. DB table `spell_bonus_data` is empty.");
1975 LOG_INFO("server.loading", " ");
1976 return;
1977 }
1978
1979 uint32 count = 0;
1980 do
1981 {
1982 Field* fields = result->Fetch();
1983 uint32 entry = fields[0].Get<uint32>();
1984
1985 SpellInfo const* spell = GetSpellInfo(entry);
1986 if (!spell)
1987 {
1988 LOG_ERROR("sql.sql", "Spell {} listed in `spell_bonus_data` does not exist", entry);
1989 continue;
1990 }
1991
1992 SpellBonusEntry& sbe = mSpellBonusMap[entry];
1993 sbe.direct_damage = fields[1].Get<float>();
1994 sbe.dot_damage = fields[2].Get<float>();
1995 sbe.ap_bonus = fields[3].Get<float>();
1996 sbe.ap_dot_bonus = fields[4].Get<float>();
1997
1998 ++count;
1999 } while (result->NextRow());
2000
2001 LOG_INFO("server.loading", ">> Loaded {} Extra Spell Bonus Data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2002 LOG_INFO("server.loading", " ");
2003}
Definition: SpellMgr.h:324
float ap_dot_bonus
Definition: SpellMgr.h:328
float dot_damage
Definition: SpellMgr.h:326
float ap_bonus
Definition: SpellMgr.h:327
float direct_damage
Definition: SpellMgr.h:325

References SpellBonusEntry::ap_bonus, SpellBonusEntry::ap_dot_bonus, SpellBonusEntry::direct_damage, SpellBonusEntry::dot_damage, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), LOG_ERROR, LOG_INFO, LOG_WARN, mSpellBonusMap, and WorldDatabase.

◆ LoadSpellCooldownOverrides()

void SpellMgr::LoadSpellCooldownOverrides ( )
2721{
2722 uint32 oldMSTime = getMSTime();
2723
2725
2726 QueryResult result = WorldDatabase.Query("SELECT Id, RecoveryTime, CategoryRecoveryTime, StartRecoveryTime, StartRecoveryCategory FROM spell_cooldown_overrides");
2727
2728 uint32 count = 0;
2729
2730 if (result)
2731 {
2732 do
2733 {
2734 Field* fields = result->Fetch();
2735 SpellCooldownOverride spellCooldown;
2736 uint32 spellId = fields[0].Get<uint32>();
2737 spellCooldown.RecoveryTime = fields[1].Get<uint32>();
2738 spellCooldown.CategoryRecoveryTime = fields[2].Get<uint32>();
2739 spellCooldown.StartRecoveryTime = fields[3].Get<uint32>();
2740 spellCooldown.StartRecoveryCategory = fields[4].Get<uint32>();
2741 mSpellCooldownOverrideMap[spellId] = spellCooldown;
2742
2743 ++count;
2744 } while (result->NextRow());
2745 }
2746
2747 LOG_INFO("server.loading", ">> Loaded {} Spell Cooldown Overrides entries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2748 LOG_INFO("server.loading", " ");
2749}
Definition: SpellMgr.h:607
uint32 StartRecoveryTime
Definition: SpellMgr.h:610
uint32 CategoryRecoveryTime
Definition: SpellMgr.h:609
uint32 StartRecoveryCategory
Definition: SpellMgr.h:611
uint32 RecoveryTime
Definition: SpellMgr.h:608

References SpellCooldownOverride::CategoryRecoveryTime, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_INFO, mSpellCooldownOverrideMap, SpellCooldownOverride::RecoveryTime, SpellCooldownOverride::StartRecoveryCategory, SpellCooldownOverride::StartRecoveryTime, and WorldDatabase.

◆ LoadSpellEnchantProcData()

void SpellMgr::LoadSpellEnchantProcData ( )
2209{
2210 uint32 oldMSTime = getMSTime();
2211
2212 mSpellEnchantProcEventMap.clear(); // need for reload case
2213
2214 // 0 1 2 3 4
2215 QueryResult result = WorldDatabase.Query("SELECT entry, customChance, PPMChance, procEx, attributeMask FROM spell_enchant_proc_data");
2216 if (!result)
2217 {
2218 LOG_WARN("server.loading", ">> Loaded 0 spell enchant proc event conditions. DB table `spell_enchant_proc_data` is empty.");
2219 LOG_INFO("server.loading", " ");
2220 return;
2221 }
2222
2223 uint32 count = 0;
2224 do
2225 {
2226 Field* fields = result->Fetch();
2227
2228 uint32 enchantId = fields[0].Get<uint32>();
2229
2230 SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchantId);
2231 if (!ench)
2232 {
2233 LOG_ERROR("sql.sql", "Enchancment {} listed in `spell_enchant_proc_data` does not exist", enchantId);
2234 continue;
2235 }
2236
2238
2239 spe.customChance = fields[1].Get<uint32>();
2240 spe.PPMChance = fields[2].Get<float>();
2241 spe.procEx = fields[3].Get<uint32>();
2242 spe.attributeMask = fields[4].Get<uint32>();
2243
2244 mSpellEnchantProcEventMap[enchantId] = spe;
2245
2246 ++count;
2247 } while (result->NextRow());
2248
2249 LOG_INFO("server.loading", ">> Loaded {} Enchant Proc Data Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2250 LOG_INFO("server.loading", " ");
2251}
Definition: SpellMgr.h:314
uint32 procEx
Definition: SpellMgr.h:317
uint32 attributeMask
Definition: SpellMgr.h:318
uint32 customChance
Definition: SpellMgr.h:315
float PPMChance
Definition: SpellMgr.h:316

References SpellEnchantProcEntry::attributeMask, SpellEnchantProcEntry::customChance, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, mSpellEnchantProcEventMap, SpellEnchantProcEntry::PPMChance, SpellEnchantProcEntry::procEx, sSpellItemEnchantmentStore, and WorldDatabase.

◆ LoadSpellGroups()

void SpellMgr::LoadSpellGroups ( )
1628{
1629 uint32 oldMSTime = getMSTime();
1630
1631 mSpellGroupMap.clear(); // need for reload case
1632
1633 // 0 1 2
1634 QueryResult result = WorldDatabase.Query("SELECT id, spell_id, special_flag FROM spell_group");
1635 if (!result)
1636 {
1637 LOG_WARN("server.loading", ">> Loaded 0 spell group definitions. DB table `spell_group` is empty.");
1638 LOG_INFO("server.loading", " ");
1639 return;
1640 }
1641
1642 uint32 count = 0;
1643 do
1644 {
1645 Field* fields = result->Fetch();
1646
1647 uint32 group_id = fields[0].Get<uint32>();
1648 int32 spell_id = fields[1].Get<uint32>();
1649 SpellGroupSpecialFlags specialFlag = (SpellGroupSpecialFlags)fields[2].Get<uint32>();
1650 SpellInfo const* spellInfo = GetSpellInfo(spell_id);
1651
1652 if (!spellInfo)
1653 {
1654 LOG_ERROR("sql.sql", "Spell {} listed in `spell_group` does not exist", spell_id);
1655 continue;
1656 }
1657 else if (spellInfo->GetRank() > 1)
1658 {
1659 LOG_ERROR("sql.sql", "Spell {} listed in `spell_group` is not first rank of spell", spell_id);
1660 continue;
1661 }
1662
1663 if (mSpellGroupMap.find(spell_id) != mSpellGroupMap.end())
1664 {
1665 LOG_ERROR("sql.sql", "Spell {} listed in `spell_group` has more than one group", spell_id);
1666 continue;
1667 }
1668
1669 if (specialFlag >= SPELL_GROUP_SPECIAL_FLAG_MAX)
1670 {
1671 LOG_ERROR("sql.sql", "Spell {} listed in `spell_group` has invalid special flag!", spell_id);
1672 continue;
1673 }
1674
1675 SpellStackInfo ssi;
1676 ssi.groupId = group_id;
1677 ssi.specialFlags = specialFlag;
1678 mSpellGroupMap[spell_id] = ssi;
1679
1680 ++count;
1681 } while (result->NextRow());
1682
1683 LOG_INFO("server.loading", ">> Loaded {} Spell Group Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1684 LOG_INFO("server.loading", " ");
1685}
@ SPELL_GROUP_SPECIAL_FLAG_MAX
Definition: SpellMgr.h:350
uint8 GetRank() const
Definition: SpellInfo.cpp:2493
Definition: SpellMgr.h:376
SpellGroupSpecialFlags specialFlags
Definition: SpellMgr.h:378
uint32 groupId
Definition: SpellMgr.h:377

References Field::Get(), getMSTime(), GetMSTimeDiffToNow(), SpellInfo::GetRank(), GetSpellInfo(), SpellStackInfo::groupId, LOG_ERROR, LOG_INFO, LOG_WARN, mSpellGroupMap, SpellStackInfo::specialFlags, SPELL_GROUP_SPECIAL_FLAG_MAX, and WorldDatabase.

◆ LoadSpellGroupStackRules()

void SpellMgr::LoadSpellGroupStackRules ( )
1688{
1689 uint32 oldMSTime = getMSTime();
1690
1691 mSpellGroupStackMap.clear(); // need for reload case
1692
1693 // 0 1
1694 QueryResult result = WorldDatabase.Query("SELECT group_id, stack_rule FROM spell_group_stack_rules");
1695 if (!result)
1696 {
1697 LOG_WARN("server.loading", ">> Loaded 0 spell group stack rules. DB table `spell_group_stack_rules` is empty.");
1698 LOG_INFO("server.loading", " ");
1699 return;
1700 }
1701
1702 uint32 count = 0;
1703 do
1704 {
1705 Field* fields = result->Fetch();
1706
1707 uint32 group_id = fields[0].Get<uint32>();
1708 uint8 stack_rule = fields[1].Get<int8>();
1709 if (stack_rule >= SPELL_GROUP_STACK_FLAG_MAX)
1710 {
1711 LOG_ERROR("sql.sql", "SpellGroupStackRule {} listed in `spell_group_stack_rules` does not exist", stack_rule);
1712 continue;
1713 }
1714
1715 bool present = false;
1716 for (SpellGroupMap::const_iterator itr = mSpellGroupMap.begin(); itr != mSpellGroupMap.end(); ++itr)
1717 if (itr->second.groupId == group_id)
1718 {
1719 present = true;
1720 break;
1721 }
1722
1723 if (!present)
1724 {
1725 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group_stack_rules` does not exist", group_id);
1726 continue;
1727 }
1728
1729 mSpellGroupStackMap[group_id] = (SpellGroupStackFlags)stack_rule;
1730
1731 ++count;
1732 } while (result->NextRow());
1733
1734 LOG_INFO("server.loading", ">> Loaded {} Spell Group Stack Rules in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1735 LOG_INFO("server.loading", " ");
1736}
std::int8_t int8
Definition: Define.h:105
@ SPELL_GROUP_STACK_FLAG_MAX
Definition: SpellMgr.h:363

References Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, mSpellGroupMap, mSpellGroupStackMap, SPELL_GROUP_STACK_FLAG_MAX, and WorldDatabase.

◆ LoadSpellInfoCorrections()

void SpellMgr::LoadSpellInfoCorrections ( )
40{
41 uint32 oldMSTime = getMSTime();
42
44 467, // Thorns (Rank 1)
45 782, // Thorns (Rank 2)
46 1075, // Thorns (Rank 3)
47 8914, // Thorns (Rank 4)
48 9756, // Thorns (Rank 5)
49 9910, // Thorns (Rank 6)
50 26992, // Thorns (Rank 7)
51 53307, // Thorns (Rank 8)
52 53352, // Explosive Shot (trigger)
53 50783, // Slam (Triggered spell)
54 20647 // Execute (Triggered spell)
55 }, [](SpellInfo* spellInfo)
56 {
57 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
58 });
59
60 // Scarlet Raven Priest Image
61 ApplySpellFix({ 48763, 48761 }, [](SpellInfo* spellInfo)
62 {
63 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_SPELL_ATTACK;
64 });
65
66 // Has Brewfest Mug
67 ApplySpellFix({ 42533 }, [](SpellInfo* spellInfo)
68 {
69 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(347); // 15 min
70 });
71
72 // Elixir of Minor Fortitude
73 ApplySpellFix({ 2378 }, [](SpellInfo* spellInfo)
74 {
75 spellInfo->ManaCost = 0;
76 spellInfo->ManaPerSecond = 0;
77 });
78
79 // Elixir of Detect Undead
80 ApplySpellFix({ 11389 }, [](SpellInfo* spellInfo)
81 {
82 spellInfo->PowerType = POWER_MANA;
83 spellInfo->ManaCost = 0;
84 spellInfo->ManaPerSecond = 0;
85 });
86
87 // Evergrove Druid Transform Crow
88 ApplySpellFix({ 38776 }, [](SpellInfo* spellInfo)
89 {
90 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(4); // 120 seconds
91 });
92
94 63026, // Force Cast (HACK: Target shouldn't be changed)
95 63137 // Force Cast (HACK: Target shouldn't be changed; summon position should be untied from spell destination)
96 }, [](SpellInfo* spellInfo)
97 {
98 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB);
99 });
100
102 53096, // Quetz'lun's Judgment
103 70743, // AoD Special
104 70614 // AoD Special - Vegard
105 }, [](SpellInfo* spellInfo)
106 {
107 spellInfo->MaxAffectedTargets = 1;
108 });
109
110 // Summon Skeletons
111 ApplySpellFix({ 52611, 52612 }, [](SpellInfo* spellInfo)
112 {
113 spellInfo->Effects[EFFECT_0].MiscValueB = 64;
114 });
115
117 40244, // Simon Game Visual
118 40245, // Simon Game Visual
119 40246, // Simon Game Visual
120 40247, // Simon Game Visual
121 42835 // Spout, remove damage effect, only anim is needed
122 }, [](SpellInfo* spellInfo)
123 {
124 spellInfo->Effects[EFFECT_0].Effect = 0;
125 });
126
128 63665, // Charge (Argent Tournament emote on riders)
129 2895, // Wrath of Air Totem rank 1 (Aura)
130 68933, // Wrath of Air Totem rank 2 (Aura)
131 29200 // Purify Helboar Meat
132 }, [](SpellInfo* spellInfo)
133 {
134 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
135 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(0);
136 });
137
138 // Howl of Azgalor
139 ApplySpellFix({ 31344 }, [](SpellInfo* spellInfo)
140 {
141 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yards instead of 50000?!
142 });
143
145 42818, // Headless Horseman - Wisp Flight Port
146 42821 // Headless Horseman - Wisp Flight Missile
147 }, [](SpellInfo* spellInfo)
148 {
149 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100 yards
150 });
151
152 // Spirit of Kirith
153 ApplySpellFix({ 10853 }, [](SpellInfo* spellInfo)
154 {
155 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(3); // 1min
156 });
157
158 // Headless Horseman - Start Fire
159 ApplySpellFix({ 42132 }, [](SpellInfo* spellInfo)
160 {
161 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100 yards
162 });
163
164 //They Must Burn Bomb Aura (self)
165 ApplySpellFix({ 36350 }, [](SpellInfo* spellInfo)
166 {
167 spellInfo->Effects[EFFECT_0].TriggerSpell = 36325; // They Must Burn Bomb Drop (DND)
168 });
169
170 // Mana Shield (rank 2)
171 ApplySpellFix({ 8494 }, [](SpellInfo* spellInfo)
172 {
173 spellInfo->ProcChance = 0; // because of bug in dbc
174 });
175
177 63320, // Glyph of Life Tap
178 20335, // Heart of the Crusader
179 20336, // Heart of the Crusader
180 20337, // Heart of the Crusader
181 53228, // Rapid Killing (Rank 1)
182 53232, // Rapid Killing (Rank 2)
183 }, [](SpellInfo* spellInfo)
184 {
185 spellInfo->AttributesEx3 |= SPELL_ATTR3_CAN_PROC_FROM_PROCS; // Entries were not updated after spell effect change, we have to do that manually
186 });
187
189 31347, // Doom
190 41635, // Prayer of Mending
191 39365, // Thundering Storm
192 52124, // Sky Darkener Assault
193 42442, // Vengeance Landing Cannonfire
194 45863, // Cosmetic - Incinerate to Random Target
195 25425, // Shoot
196 45761, // Shoot
197 42611, // Shoot
198 61588, // Blazing Harpoon
199 36327 // Shoot Arcane Explosion Arrow
200 }, [](SpellInfo* spellInfo)
201 {
202 spellInfo->MaxAffectedTargets = 1;
203 });
204
205 // Skartax Purple Beam
206 ApplySpellFix({ 36384 }, [](SpellInfo* spellInfo)
207 {
208 spellInfo->MaxAffectedTargets = 2;
209 });
210
212 37790, // Spread Shot
213 54172, // Divine Storm (heal)
214 66588 // Flaming Spear
215 }, [](SpellInfo* spellInfo)
216 {
217 spellInfo->MaxAffectedTargets = 3;
218 });
219
220 // Divine Storm
221 ApplySpellFix({ 54171 }, [](SpellInfo* spellInfo)
222 {
223 spellInfo->MaxAffectedTargets = 3;
224 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
225 });
226
227 // Divine Storm (Damage)
228 ApplySpellFix({ 53385 }, [](SpellInfo* spellInfo)
229 {
230 spellInfo->MaxAffectedTargets = 4;
231 });
232
234 20424, // Seal of Command
235 42463, // Seal of Vengeance
236 53739 // Seal of Corruption
237 }, [](SpellInfo* spellInfo)
238 {
239 spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_MODIFIERS;
240 });
241
242 // Spitfire Totem
243 ApplySpellFix({ 38296 }, [](SpellInfo* spellInfo)
244 {
245 spellInfo->MaxAffectedTargets = 5;
246 });
247
249 40827, // Sinful Beam
250 40859, // Sinister Beam
251 40860, // Vile Beam
252 40861 // Wicked Beam
253 }, [](SpellInfo* spellInfo)
254 {
255 spellInfo->MaxAffectedTargets = 10;
256 });
257
258 // Unholy Frenzy
259 ApplySpellFix({ 50312 }, [](SpellInfo* spellInfo)
260 {
261 spellInfo->MaxAffectedTargets = 15;
262 });
263
265 17941, // Shadow Trance
266 22008, // Netherwind Focus
267 31834, // Light's Grace
268 34754, // Clearcasting
269 34936, // Backlash
270 48108, // Hot Streak
271 51124, // Killing Machine
272 54741, // Firestarter
273 64823, // Item - Druid T8 Balance 4P Bonus
274 34477, // Misdirection
275 44401, // Missile Barrage
276 18820 // Insight
277 }, [](SpellInfo* spellInfo)
278 {
279 spellInfo->ProcCharges = 1;
280 });
281
282 // Fireball
283 ApplySpellFix({ 57761 }, [](SpellInfo* spellInfo)
284 {
285 spellInfo->ProcCharges = 1;
286 spellInfo->SpellPriority = 50;
287 });
288
289 // Tidal Wave
290 ApplySpellFix({ 53390 }, [](SpellInfo* spellInfo)
291 {
292 spellInfo->ProcCharges = 2;
293 });
294
295 // Oscillation Field
296 ApplySpellFix({ 37408 }, [](SpellInfo* spellInfo)
297 {
298 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
299 });
300
301 // Ascendance (Talisman of Ascendance trinket)
302 ApplySpellFix({ 28200 }, [](SpellInfo* spellInfo)
303 {
304 spellInfo->ProcCharges = 6;
305 });
306
307 // The Eye of Acherus (no spawn in phase 2 in db)
308 ApplySpellFix({ 51852 }, [](SpellInfo* spellInfo)
309 {
310 spellInfo->Effects[EFFECT_0].MiscValue |= 1;
311 });
312
313 // Crafty's Ultra-Advanced Proto-Typical Shortening Blaster
314 ApplySpellFix({ 51912 }, [](SpellInfo* spellInfo)
315 {
316 spellInfo->Effects[EFFECT_0].Amplitude = 3000;
317 });
318
319 // Desecration Arm - 36 instead of 37 - typo?
320 ApplySpellFix({ 29809 }, [](SpellInfo* spellInfo)
321 {
322 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_7_YARDS);
323 });
324
325 // Sic'em
326 ApplySpellFix({ 42767 }, [](SpellInfo* spellInfo)
327 {
328 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_NEARBY_ENTRY);
329 });
330
331 // Master Shapeshifter: missing stance data for forms other than bear - bear version has correct data
332 // To prevent aura staying on target after talent unlearned
333 ApplySpellFix({ 48420 }, [](SpellInfo* spellInfo)
334 {
335 spellInfo->Stances = 1 << (FORM_CAT - 1);
336 });
337
338 ApplySpellFix({ 48421 }, [](SpellInfo* spellInfo)
339 {
340 spellInfo->Stances = 1 << (FORM_MOONKIN - 1);
341 });
342
343 ApplySpellFix({ 48422 }, [](SpellInfo* spellInfo)
344 {
345 spellInfo->Stances = 1 << (FORM_TREE - 1);
346 });
347
348 // Elemental Oath
349 ApplySpellFix({ 51466, 51470 }, [](SpellInfo* spellInfo)
350 {
351 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
352 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_ADD_FLAT_MODIFIER;
353 spellInfo->Effects[EFFECT_1].MiscValue = SPELLMOD_EFFECT2;
354 spellInfo->Effects[EFFECT_1].SpellClassMask = flag96(0x00000000, 0x00004000, 0x00000000);
355 });
356
357 // Improved Shadowform (Rank 1)
358 ApplySpellFix({ 47569 }, [](SpellInfo* spellInfo)
359 {
360 spellInfo->Attributes &= ~SPELL_ATTR0_NOT_SHAPESHIFTED; // with this spell atrribute aura can be stacked several times
361 });
362
363 // Natural shapeshifter
364 ApplySpellFix({ 16834, 16835 }, [](SpellInfo* spellInfo)
365 {
366 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21);
367 });
368
369 // Ebon Plague
370 ApplySpellFix({ 51735, 51734, 51726 }, [](SpellInfo* spellInfo)
371 {
372 spellInfo->SpellFamilyFlags[2] = 0x10;
373 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN;
374 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
375 });
376
377 // Parasitic Shadowfiend Passive
378 ApplySpellFix({ 41013 }, [](SpellInfo* spellInfo)
379 {
380 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_DUMMY; // proc debuff, and summon infinite fiends
381 });
382
384 27892, // To Anchor 1
385 27928, // To Anchor 1
386 27935, // To Anchor 1
387 }, [](SpellInfo* spellInfo)
388 {
389 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS);
390 });
391
392 // Wrath of the Plaguebringer
393 ApplySpellFix({ 29214, 54836 }, [](SpellInfo* spellInfo)
394 {
395 // target allys instead of enemies, target A is src_caster, spells with effect like that have ally target
396 // this is the only known exception, probably just wrong data
397 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
398 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
399 });
400
401 // Wind Shear
402 ApplySpellFix({ 57994 }, [](SpellInfo* spellInfo)
403 {
404 // improper data for EFFECT_1 in 3.3.5 DBC, but is correct in 4.x
405 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_MODIFY_THREAT_PERCENT;
406 spellInfo->Effects[EFFECT_1].BasePoints = -6; // -5%
407 });
408
409 // Improved Devouring Plague
410 ApplySpellFix({ 63675 }, [](SpellInfo* spellInfo)
411 {
412 spellInfo->Effects[EFFECT_0].BonusMultiplier = 0;
413 spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_MODIFIERS;
414 });
415
417 8145, // Tremor Totem (instant pulse)
418 6474 // Earthbind Totem (instant pulse)
419 }, [](SpellInfo* spellInfo)
420 {
421 spellInfo->AttributesEx5 |= SPELL_ATTR5_EXTRA_INITIAL_PERIOD;
422 });
423
424 // Marked for Death
425 ApplySpellFix({ 53241, 53243, 53244, 53245, 53246 }, [](SpellInfo* spellInfo)
426 {
427 spellInfo->Effects[EFFECT_0].SpellClassMask = flag96(399361, 276955137, 1);
428 });
429
431 70728, // Exploit Weakness
432 70840 // Devious Minds
433 }, [](SpellInfo* spellInfo)
434 {
435 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
436 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_PET);
437 });
438
439 // Culling The Herd
440 ApplySpellFix({ 70893 }, [](SpellInfo* spellInfo)
441 {
442 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
443 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_MASTER);
444 });
445
446 // Sigil of the Frozen Conscience
447 ApplySpellFix({ 54800 }, [](SpellInfo* spellInfo)
448 {
449 // change class mask to custom extended flags of Icy Touch
450 // this is done because another spell also uses the same SpellFamilyFlags as Icy Touch
451 // SpellFamilyFlags[0] & 0x00000040 in SPELLFAMILY_DEATHKNIGHT is currently unused (3.3.5a)
452 // this needs research on modifier applying rules, does not seem to be in Attributes fields
453 spellInfo->Effects[EFFECT_0].SpellClassMask = flag96(0x00000040, 0x00000000, 0x00000000);
454 });
455
456 // Idol of the Flourishing Life
457 ApplySpellFix({ 64949 }, [](SpellInfo* spellInfo)
458 {
459 spellInfo->Effects[EFFECT_0].SpellClassMask = flag96(0x00000000, 0x02000000, 0x00000000);
460 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_ADD_FLAT_MODIFIER;
461 });
462
464 34231, // Libram of the Lightbringer
465 60792, // Libram of Tolerance
466 64956 // Libram of the Resolute
467 }, [](SpellInfo* spellInfo)
468 {
469 spellInfo->Effects[EFFECT_0].SpellClassMask = flag96(0x80000000, 0x00000000, 0x00000000);
470 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_ADD_FLAT_MODIFIER;
471 });
472
474 28851, // Libram of Light
475 28853, // Libram of Divinity
476 32403 // Blessed Book of Nagrand
477 }, [](SpellInfo* spellInfo)
478 {
479 spellInfo->Effects[EFFECT_0].SpellClassMask = flag96(0x40000000, 0x00000000, 0x00000000);
480 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_ADD_FLAT_MODIFIER;
481 });
482
483 // Ride Carpet
484 ApplySpellFix({ 45602 }, [](SpellInfo* spellInfo)
485 {
486 spellInfo->Effects[EFFECT_0].BasePoints = 0; // force seat 0, vehicle doesn't have the required seat flags for "no seat specified (-1)"
487 });
488
490 64745, // Item - Death Knight T8 Tank 4P Bonus
491 64936 // Item - Warrior T8 Protection 4P Bonus
492 }, [](SpellInfo* spellInfo)
493 {
494 spellInfo->Effects[EFFECT_0].BasePoints = 100; // 100% chance of procc'ing, not -10% (chance calculated in PrepareTriggersExecutedOnHit)
495 });
496
497 // Easter Lay Noblegarden Egg Aura
498 ApplySpellFix({ 61719 }, [](SpellInfo* spellInfo)
499 {
500 // Interrupt flags copied from aura which this aura is linked with
501 spellInfo->AuraInterruptFlags = AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE;
502 });
503
504 // Bleh, need to change FamilyFlags :/ (have the same as original aura - bad!)
505 ApplySpellFix({ 63510 }, [](SpellInfo* spellInfo)
506 {
507 spellInfo->SpellFamilyFlags[EFFECT_0] = 0;
508 spellInfo->SpellFamilyFlags[EFFECT_2] = 0x4000000;
509 });
510
511 ApplySpellFix({ 63514 }, [](SpellInfo* spellInfo)
512 {
513 spellInfo->SpellFamilyFlags[EFFECT_0] = 0;
514 spellInfo->SpellFamilyFlags[EFFECT_2] = 0x2000000;
515 });
516
517 ApplySpellFix({ 63531 }, [](SpellInfo* spellInfo)
518 {
519 spellInfo->SpellFamilyFlags[EFFECT_0] = 0;
520 spellInfo->SpellFamilyFlags[EFFECT_2] = 0x8000000;
521 });
522
523 // And affecting spells
525 20138, // Improved Devotion Aura
526 20139,
527 20140
528 }, [](SpellInfo* spellInfo)
529 {
530 spellInfo->Effects[EFFECT_1].SpellClassMask[0] = 0;
531 spellInfo->Effects[EFFECT_1].SpellClassMask[2] = 0x2000000;
532 });
533
535 20254, // Improved concentration aura
536 20255,
537 20256
538 }, [](SpellInfo* spellInfo)
539 {
540 spellInfo->Effects[EFFECT_1].SpellClassMask[0] = 0;
541 spellInfo->Effects[EFFECT_1].SpellClassMask[2] = 0x4000000;
542 spellInfo->Effects[EFFECT_2].SpellClassMask[0] = 0;
543 spellInfo->Effects[EFFECT_2].SpellClassMask[2] = 0x4000000;
544 });
545
547 53379, // Swift Retribution
548 53484,
549 53648
550 }, [](SpellInfo* spellInfo)
551 {
552 spellInfo->Effects[EFFECT_0].SpellClassMask[0] = 0;
553 spellInfo->Effects[EFFECT_0].SpellClassMask[2] = 0x8000000;
554 });
555
556 // Sanctified Retribution
557 ApplySpellFix({ 31869 }, [](SpellInfo* spellInfo)
558 {
559 spellInfo->Effects[EFFECT_0].SpellClassMask[0] = 0;
560 spellInfo->Effects[EFFECT_0].SpellClassMask[2] = 0x8000000;
561 });
562
563 // Seal of Light trigger
564 ApplySpellFix({ 20167 }, [](SpellInfo* spellInfo)
565 {
566 spellInfo->SpellLevel = 0;
567 spellInfo->BaseLevel = 0;
568 spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
569 });
570
571 // Hand of Reckoning
572 ApplySpellFix({ 62124 }, [](SpellInfo* spellInfo)
573 {
574 spellInfo->AttributesEx |= SPELL_ATTR1_NO_REDIRECTION;
575 });
576
577 // Redemption
578 ApplySpellFix({ 7328, 10322, 10324, 20772, 20773, 48949, 48950 }, [](SpellInfo* spellInfo)
579 {
580 spellInfo->SpellFamilyName = SPELLFAMILY_PALADIN;
581 });
582
584 20184, // Judgement of Justice
585 20185, // Judgement of Light
586 20186, // Judgement of Wisdom
587 68055 // Judgements of the Just
588 }, [](SpellInfo* spellInfo)
589 {
590 // hack for seal of light and few spells, judgement consists of few single casts and each of them can proc
591 // some spell, base one has disabled proc flag but those dont have this flag
592 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_CASTER_PROCS;
593 });
594
595 // Blessing of sanctuary stats
596 ApplySpellFix({ 67480 }, [](SpellInfo* spellInfo)
597 {
598 spellInfo->Effects[EFFECT_0].MiscValue = -1;
599 spellInfo->SpellFamilyName = SPELLFAMILY_UNK1; // allows stacking
600 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_DUMMY; // just a marker
601 });
602
604 6940, // Hand of Sacrifice
605 64205 // Divine Sacrifice
606 }, [](SpellInfo* spellInfo)
607 {
608 spellInfo->AttributesEx7 |= SPELL_ATTR7_DONT_CAUSE_SPELL_PUSHBACK;
609 });
610
611 // Seal of Command trigger
612 ApplySpellFix({ 20424 }, [](SpellInfo* spellInfo)
613 {
614 spellInfo->AttributesEx3 &= ~SPELL_ATTR3_SUPRESS_CASTER_PROCS;
615 });
616
618 54968, // Glyph of Holy Light, Damage Class should be magic
619 53652, // Beacon of Light heal, Damage Class should be magic
620 53654
621 }, [](SpellInfo* spellInfo)
622 {
623 spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_MODIFIERS;
624 spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
625 });
626
627 // Wild Hunt
628 ApplySpellFix({ 62758, 62762 }, [](SpellInfo* spellInfo)
629 {
630 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AURA;
631 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_DUMMY;
632 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
633 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_DUMMY;
634 });
635
636 // Intervene
637 ApplySpellFix({ 3411 }, [](SpellInfo* spellInfo)
638 {
639 spellInfo->Attributes |= SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT;
640 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_TARGET_PROCS;
641 });
642
643 // Roar of Sacrifice
644 ApplySpellFix({ 53480 }, [](SpellInfo* spellInfo)
645 {
646 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
647 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_SPLIT_DAMAGE_PCT;
648 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ALLY);
649 spellInfo->Effects[EFFECT_1].DieSides = 1;
650 spellInfo->Effects[EFFECT_1].BasePoints = 19;
651 spellInfo->Effects[EFFECT_1].BasePoints = 127; // all schools
652 });
653
654 // Silencing Shot
655 ApplySpellFix({ 34490, 41084, 42671 }, [](SpellInfo* spellInfo)
656 {
657 spellInfo->Speed = 0.0f;
658 });
659
660 // Monstrous Bite
661 ApplySpellFix({ 54680, 55495, 55496, 55497, 55498, 55499 }, [](SpellInfo* spellInfo)
662 {
663 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
664 });
665
666 // Hunter's Mark
667 ApplySpellFix({ 1130, 14323, 14324, 14325, 53338 }, [](SpellInfo* spellInfo)
668 {
669 spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
670 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
671 });
672
673 // Cobra Strikes
674 ApplySpellFix({ 53257 }, [](SpellInfo* spellInfo)
675 {
676 spellInfo->ProcCharges = 2;
677 spellInfo->StackAmount = 0;
678 });
679
680 // Kill Command
681 // Kill Command, Overpower
682 ApplySpellFix({ 34027, 37529 }, [](SpellInfo* spellInfo)
683 {
684 spellInfo->ProcCharges = 0;
685 });
686
687 // Kindred Spirits, damage aura
688 ApplySpellFix({ 57458 }, [](SpellInfo* spellInfo)
689 {
690 spellInfo->AttributesEx4 |= SPELL_ATTR4_ALLOW_ENETRING_ARENA;
691 });
692
693 // Chimera Shot - Serpent trigger
694 ApplySpellFix({ 53353 }, [](SpellInfo* spellInfo)
695 {
696 spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_MODIFIERS;
697 });
698
699 // Entrapment trigger
700 ApplySpellFix({ 19185, 64803, 64804 }, [](SpellInfo* spellInfo)
701 {
702 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ENEMY);
703 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_DEST_AREA_ENEMY);
704 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT;
705 });
706
707 // Improved Stings (Rank 2)
708 ApplySpellFix({ 19465 }, [](SpellInfo* spellInfo)
709 {
710 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
711 });
712
713 // Heart of the Phoenix (triggered)
714 ApplySpellFix({ 54114 }, [](SpellInfo* spellInfo)
715 {
716 spellInfo->AttributesEx &= ~SPELL_ATTR1_DISMISS_PET_FIRST;
717 spellInfo->RecoveryTime = 8 * 60 * IN_MILLISECONDS; // prev 600000
718 });
719
720 // Master of Subtlety
721 ApplySpellFix({ 31221, 31222, 31223 }, [](SpellInfo* spellInfo)
722 {
723 spellInfo->SpellFamilyName = SPELLFAMILY_ROGUE;
724 });
725
727 31666, // Master of Subtlety triggers
728 58428 // Overkill
729 }, [](SpellInfo* spellInfo)
730 {
731 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_SCRIPT_EFFECT;
732 });
733
734 // Honor Among Thieves
735 ApplySpellFix({ 51698, 51700, 51701 }, [](SpellInfo* spellInfo)
736 {
737 spellInfo->Effects[EFFECT_0].TriggerSpell = 51699;
738 });
739
741 5171, // Slice and Dice
742 6774 // Slice and Dice
743 }, [](SpellInfo* spellInfo)
744 {
745 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_TARGET_PROCS;
746 });
747
748 // Envenom
749 ApplySpellFix({ 32645, 32684, 57992, 57993 }, [](SpellInfo* spellInfo)
750 {
751 spellInfo->Dispel = DISPEL_NONE;
752 });
753
755 64014, // Expedition Base Camp Teleport
756 64032, // Formation Grounds Teleport
757 64028, // Colossal Forge Teleport
758 64031, // Scrapyard Teleport
759 64030, // Antechamber Teleport
760 64029, // Shattered Walkway Teleport
761 64024, // Conservatory Teleport
762 64025, // Halls of Invention Teleport
763 65042 // Prison of Yogg-Saron Teleport
764 }, [](SpellInfo* spellInfo)
765 {
766 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_DEST_DB);
767 });
768
769 // Killing Spree (teleport)
770 ApplySpellFix({ 57840 }, [](SpellInfo* spellInfo)
771 {
772 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100 yards
773 });
774
775 // Killing Spree
776 ApplySpellFix({ 51690 }, [](SpellInfo* spellInfo)
777 {
778 spellInfo->AttributesEx |= SPELL_ATTR1_ALLOW_WHILE_STEALTHED;
779 });
780
781 // Blood Tap visual cd reset
782 ApplySpellFix({ 47804 }, [](SpellInfo* spellInfo)
783 {
784 spellInfo->Effects[EFFECT_2].Effect = 0;
785 spellInfo->Effects[EFFECT_1].Effect = 0;
786 spellInfo->RuneCostID = 442;
787 });
788
789 // Chains of Ice
790 ApplySpellFix({ 45524 }, [](SpellInfo* spellInfo)
791 {
792 spellInfo->Effects[EFFECT_2].Effect = 0;
793 });
794
795 // Impurity
796 ApplySpellFix({ 49220, 49633, 49635, 49636, 49638 }, [](SpellInfo* spellInfo)
797 {
798 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AURA;
799 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_DUMMY;
800 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
801 spellInfo->SpellFamilyName = SPELLFAMILY_DEATHKNIGHT;
802 });
803
804 // Deadly Aggression (Deadly Gladiator's Death Knight Relic, item: 42620)
805 ApplySpellFix({ 60549 }, [](SpellInfo* spellInfo)
806 {
807 spellInfo->Effects[EFFECT_1].Effect = 0;
808 });
809
810 // Magic Suppression
811 ApplySpellFix({ 49224, 49610, 49611 }, [](SpellInfo* spellInfo)
812 {
813 spellInfo->ProcCharges = 0;
814 });
815
816 // Wandering Plague
817 ApplySpellFix({ 50526 }, [](SpellInfo* spellInfo)
818 {
819 spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_MODIFIERS;
820 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_TARGET_PROCS;
821 });
822
823 // Dancing Rune Weapon
824 ApplySpellFix({ 49028 }, [](SpellInfo* spellInfo)
825 {
826 spellInfo->Effects[EFFECT_2].Effect = 0;
827 spellInfo->ProcFlags |= PROC_FLAG_DONE_MELEE_AUTO_ATTACK;
828 });
829
830 // Death and Decay
831 ApplySpellFix({ 52212 }, [](SpellInfo* spellInfo)
832 {
833 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
834 spellInfo->AttributesEx6 |= SPELL_ATTR6_IGNORE_PHASE_SHIFT;
835 });
836
837 // T9 blood plague crit bonus
838 ApplySpellFix({ 67118 }, [](SpellInfo* spellInfo)
839 {
840 spellInfo->Effects[EFFECT_1].Effect = 0;
841 });
842
843 // Pestilence
844 ApplySpellFix({ 50842 }, [](SpellInfo* spellInfo)
845 {
846 spellInfo->Effects[EFFECT_2].TargetA = TARGET_DEST_TARGET_ENEMY;
847 });
848
849 // Horn of Winter, stacking issues
850 ApplySpellFix({ 57330, 57623 }, [](SpellInfo* spellInfo)
851 {
852 spellInfo->Effects[EFFECT_1].TargetA = 0;
853 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
854 });
855
856 // Scourge Strike trigger
857 ApplySpellFix({ 70890 }, [](SpellInfo* spellInfo)
858 {
859 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_CASTER_PROCS;
860 });
861
862 // Blood-caked Blade - Blood-caked Strike trigger
863 ApplySpellFix({ 50463 }, [](SpellInfo* spellInfo)
864 {
865 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_CASTER_PROCS;
866 });
867
868 // Blood Gorged
869 ApplySpellFix({ 61274, 61275, 61276, 61277,61278 }, [](SpellInfo* spellInfo)
870 {
871 // ARP affect Death Strike and Rune Strike
872 spellInfo->Effects[EFFECT_0].SpellClassMask = flag96(0x1400011, 0x20000000, 0x0);
873 });
874
875 // Death Grip
876 ApplySpellFix({ 49576, 49560 }, [](SpellInfo* spellInfo)
877 {
878 // remove main grip mechanic, leave only effect one
879 // should fix taunt on bosses and not break the pull protection at the same time (no aura provides immunity to grip mechanic)
880 spellInfo->Mechanic = 0;
881 });
882
883 // Death Grip Jump Dest
884 ApplySpellFix({ 57604 }, [](SpellInfo* spellInfo)
885 {
886 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
887 });
888
889 // Death Pact
890 ApplySpellFix({ 48743 }, [](SpellInfo* spellInfo)
891 {
892 spellInfo->AttributesEx &= ~SPELL_ATTR1_EXCLUDE_CASTER;
893 });
894
895 // Raise Ally (trigger)
896 ApplySpellFix({ 46619 }, [](SpellInfo* spellInfo)
897 {
898 spellInfo->Attributes &= ~SPELL_ATTR0_NO_AURA_CANCEL;
899 });
900
901 // Frost Strike
902 ApplySpellFix({ 49143, 51416, 51417, 51418, 51419, 55268 }, [](SpellInfo* spellInfo)
903 {
904 spellInfo->AttributesEx3 |= SPELL_ATTR3_COMPLETELY_BLOCKED;
905 });
906
907 // Death Knight T10 Tank 2p Bonus
908 ApplySpellFix({ 70650 }, [](SpellInfo* spellInfo)
909 {
910 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_ADD_PCT_MODIFIER;
911 });
912
913 ApplySpellFix({ 45297, 45284 }, [](SpellInfo* spellInfo)
914 {
915 spellInfo->CategoryRecoveryTime = 0;
916 spellInfo->RecoveryTime = 0;
917 spellInfo->AttributesEx6 |= SPELL_ATTR6_IGNORE_CASTER_DAMAGE_MODIFIERS;
918 });
919
920 // Improved Earth Shield
921 ApplySpellFix({ 51560, 51561 }, [](SpellInfo* spellInfo)
922 {
923 spellInfo->Effects[EFFECT_1].MiscValue = SPELLMOD_DAMAGE;
924 });
925
926 // Tidal Force
927 ApplySpellFix({ 55166, 55198 }, [](SpellInfo* spellInfo)
928 {
929 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(18);
930 spellInfo->ProcCharges = 0;
931 });
932
933 // Healing Stream Totem
934 ApplySpellFix({ 52042 }, [](SpellInfo* spellInfo)
935 {
936 spellInfo->SpellLevel = 0;
937 spellInfo->BaseLevel = 0;
938 spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
939 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(5); // 40yd
940 });
941
942 // Earth Shield
943 ApplySpellFix({ 379 }, [](SpellInfo* spellInfo)
944 {
945 spellInfo->SpellLevel = 0;
946 spellInfo->BaseLevel = 0;
947 spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
948 spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_MODIFIERS;
949 });
950
951 // Stormstrike
952 ApplySpellFix({ 17364 }, [](SpellInfo* spellInfo)
953 {
954 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
955 });
956
957 // Strength of Earth totem effect
958 ApplySpellFix({ 8076, 8162, 8163, 10441, 25362, 25527, 57621, 58646 }, [](SpellInfo* spellInfo)
959 {
960 spellInfo->Effects[EFFECT_1].RadiusEntry = spellInfo->Effects[EFFECT_0].RadiusEntry;
961 spellInfo->Effects[EFFECT_2].RadiusEntry = spellInfo->Effects[EFFECT_0].RadiusEntry;
962 });
963
964 // Flametongue Totem effect
965 ApplySpellFix({ 52109, 52110, 52111, 52112, 52113, 58651, 58654, 58655 }, [](SpellInfo* spellInfo)
966 {
967 spellInfo->Effects[EFFECT_2].TargetB = spellInfo->Effects[EFFECT_1].TargetB = spellInfo->Effects[EFFECT_0].TargetB = 0;
968 spellInfo->Effects[EFFECT_2].TargetA = spellInfo->Effects[EFFECT_1].TargetA = spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
969 });
970
971 // Sentry Totem
972 ApplySpellFix({ 6495 }, [](SpellInfo* spellInfo)
973 {
974 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(0);
975 });
976
977 // Bind Sight (PT)
978 ApplySpellFix({ 6277 }, [](SpellInfo* spellInfo)
979 {
980 // because it is passive, needs this to be properly removed at death in RemoveAllAurasOnDeath()
981 spellInfo->AttributesEx &= ~SPELL_ATTR1_IS_CHANNELED;
982 spellInfo->Attributes |= SPELL_ATTR0_PASSIVE;
983 spellInfo->AttributesEx7 |= SPELL_ATTR7_DISABLE_AURA_WHILE_DEAD;
984 });
985
986 // Ancestral Awakening Heal
987 ApplySpellFix({ 52752 }, [](SpellInfo* spellInfo)
988 {
989 spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_MODIFIERS;
990 });
991
992 // Heroism
993 ApplySpellFix({ 32182 }, [](SpellInfo* spellInfo)
994 {
995 spellInfo->ExcludeTargetAuraSpell = 57723; // Exhaustion
996 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
997 });
998
999 // Bloodlust
1000 ApplySpellFix({ 2825 }, [](SpellInfo* spellInfo)
1001 {
1002 spellInfo->ExcludeTargetAuraSpell = 57724; // Sated
1003 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1004 });
1005
1006 // Improved Succubus
1007 ApplySpellFix({ 18754, 18755, 18756 }, [](SpellInfo* spellInfo)
1008 {
1009 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
1010 });
1011
1012 // Unstable Affliction
1013 ApplySpellFix({ 31117 }, [](SpellInfo* spellInfo)
1014 {
1015 spellInfo->PreventionType = SPELL_PREVENTION_TYPE_NONE;
1016 });
1017
1018 // Shadowflame - trigger
1020 47960, // r1
1021 61291 // r2
1022 }, [](SpellInfo* spellInfo)
1023 {
1024 spellInfo->AttributesEx |= SPELL_ATTR1_NO_REDIRECTION;
1025 });
1026
1027 // Curse of Doom
1028 ApplySpellFix({ 18662 }, [](SpellInfo* spellInfo)
1029 {
1030 // summoned doomguard duration fix
1031 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(6);
1032 });
1033
1034 // Everlasting Affliction
1035 ApplySpellFix({ 47201, 47202, 47203, 47204, 47205 }, [](SpellInfo* spellInfo)
1036 {
1037 spellInfo->Effects[EFFECT_1].SpellClassMask[0] |= 2; // add corruption to affected spells
1038 });
1039
1040 // Death's Embrace
1041 ApplySpellFix({ 47198, 47199, 47200 }, [](SpellInfo* spellInfo)
1042 {
1043 spellInfo->Effects[EFFECT_1].SpellClassMask[0] |= 0x4000; // include Drain Soul
1044 });
1045
1046 // Improved Demonic Tactics
1047 ApplySpellFix({ 54347, 54348, 54349 }, [](SpellInfo* spellInfo)
1048 {
1049 spellInfo->Effects[EFFECT_1].Effect = spellInfo->Effects[EFFECT_0].Effect;
1050 spellInfo->Effects[EFFECT_1].ApplyAuraName = spellInfo->Effects[EFFECT_0].ApplyAuraName;
1051 spellInfo->Effects[EFFECT_1].TargetA = spellInfo->Effects[EFFECT_0].TargetA;
1052 spellInfo->Effects[EFFECT_0].MiscValue = SPELLMOD_EFFECT1;
1053 spellInfo->Effects[EFFECT_1].MiscValue = SPELLMOD_EFFECT2;
1054 });
1055
1056 // Rain of Fire (Doomguard)
1057 ApplySpellFix({ 42227 }, [](SpellInfo* spellInfo)
1058 {
1059 spellInfo->Speed = 0.0f;
1060 });
1061
1062 // Ritual Enslavement
1063 ApplySpellFix({ 22987 }, [](SpellInfo* spellInfo)
1064 {
1065 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_MOD_CHARM;
1066 });
1067
1068 // Combustion, make this passive
1069 ApplySpellFix({ 11129 }, [](SpellInfo* spellInfo)
1070 {
1071 spellInfo->Dispel = DISPEL_NONE;
1072 });
1073
1074 // Magic Absorption
1075 ApplySpellFix({ 29441, 29444 }, [](SpellInfo* spellInfo)
1076 {
1077 spellInfo->SpellLevel = 0;
1078 });
1079
1080 // Living Bomb
1081 ApplySpellFix({ 44461, 55361, 55362 }, [](SpellInfo* spellInfo)
1082 {
1083 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_TARGET_PROCS;
1084 spellInfo->AttributesEx4 |= SPELL_ATTR4_REACTIVE_DAMAGE_PROC;
1085 });
1086
1087 // Evocation
1088 ApplySpellFix({ 12051 }, [](SpellInfo* spellInfo)
1089 {
1090 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
1091 });
1092
1093 // MI Fireblast, WE Frostbolt, MI Frostbolt
1094 ApplySpellFix({ 59637, 31707, 72898 }, [](SpellInfo* spellInfo)
1095 {
1096 spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
1097 });
1098
1099 // Blazing Speed
1100 ApplySpellFix({ 31641, 31642 }, [](SpellInfo* spellInfo)
1101 {
1102 spellInfo->Effects[EFFECT_0].TriggerSpell = 31643;
1103 });
1104
1105 // Summon Water Elemental (permanent)
1106 ApplySpellFix({ 70908 }, [](SpellInfo* spellInfo)
1107 {
1108 // treat it as pet
1109 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_SUMMON_PET;
1110 });
1111
1112 // // Burnout, trigger
1113 ApplySpellFix({ 44450 }, [](SpellInfo* spellInfo)
1114 {
1115 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_POWER_BURN;
1116 });
1117
1118 // Mirror Image - Summon Spells
1119 ApplySpellFix({ 58831, 58833, 58834, 65047 }, [](SpellInfo* spellInfo)
1120 {
1121 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
1122 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(0);
1123 });
1124
1125 // Initialize Images (Mirror Image)
1126 ApplySpellFix({ 58836 }, [](SpellInfo* spellInfo)
1127 {
1128 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
1129 });
1130
1131 // Arcane Blast, can't be dispelled
1132 ApplySpellFix({ 36032 }, [](SpellInfo* spellInfo)
1133 {
1134 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
1135 });
1136
1137 // Chilled (frost armor, ice armor proc)
1138 ApplySpellFix({ 6136, 7321 }, [](SpellInfo* spellInfo)
1139 {
1140 spellInfo->PreventionType = SPELL_PREVENTION_TYPE_NONE;
1141 });
1142
1143 // Mirror Image Frostbolt
1144 ApplySpellFix({ 59638 }, [](SpellInfo* spellInfo)
1145 {
1146 spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
1147 spellInfo->SpellFamilyName = SPELLFAMILY_MAGE;
1148 spellInfo->SpellFamilyFlags = flag96(0x20, 0x0, 0x0);
1149 });
1150
1151 // Fingers of Frost
1152 ApplySpellFix({ 44544 }, [](SpellInfo* spellInfo)
1153 {
1154 spellInfo->Dispel = DISPEL_NONE;
1155 spellInfo->AttributesEx4 |= SPELL_ATTR4_CANNOT_BE_STOLEN;
1156 spellInfo->Effects[EFFECT_0].SpellClassMask = flag96(685904631, 1151040, 32);
1157 });
1158
1159 // Fingers of Frost visual buff
1160 ApplySpellFix({ 74396 }, [](SpellInfo* spellInfo)
1161 {
1162 spellInfo->ProcCharges = 2;
1163 spellInfo->StackAmount = 0;
1164 });
1165
1166 // Glyph of blocking
1167 ApplySpellFix({ 58375 }, [](SpellInfo* spellInfo)
1168 {
1169 spellInfo->Effects[EFFECT_0].TriggerSpell = 58374;
1170 });
1171
1172 // Sweeping Strikes stance change
1173 ApplySpellFix({ 12328 }, [](SpellInfo* spellInfo)
1174 {
1175 spellInfo->Attributes |= SPELL_ATTR0_NOT_SHAPESHIFTED;
1176 });
1177
1178 // Damage Shield
1179 ApplySpellFix({ 59653 }, [](SpellInfo* spellInfo)
1180 {
1181 spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
1182 spellInfo->SpellLevel = 0;
1183 });
1184
1186 20230, // Retaliation
1187 871, // Shield Wall
1188 1719 // Recklessness
1189 }, [](SpellInfo* spellInfo)
1190 {
1191 // Strange shared cooldown
1192 spellInfo->AttributesEx6 |= SPELL_ATTR6_NO_CATEGORY_COOLDOWN_MODS;
1193 });
1194
1195 // Vigilance
1196 ApplySpellFix({ 50720 }, [](SpellInfo* spellInfo)
1197 {
1198 // fixes bug with empowered renew, single target aura
1199 spellInfo->SpellFamilyName = SPELLFAMILY_WARRIOR;
1200 });
1201
1202 // Sunder Armor - Old Ranks
1203 ApplySpellFix({ 7405, 8380, 11596, 11597, 25225, 47467 }, [](SpellInfo* spellInfo)
1204 {
1205 spellInfo->Effects[EFFECT_0].TriggerSpell = 11971;
1206 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE;
1207 });
1208
1209 // Improved Spell Reflection
1210 ApplySpellFix({ 59725 }, [](SpellInfo* spellInfo)
1211 {
1212 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER_AREA_PARTY);
1213 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1214 });
1215
1216 // Hymn of Hope
1217 ApplySpellFix({ 64904 }, [](SpellInfo* spellInfo)
1218 {
1219 // rewrite part of aura system or swap effects...
1220 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT;
1221 spellInfo->Effects[EFFECT_2].Effect = spellInfo->Effects[EFFECT_0].Effect;
1222 spellInfo->Effects[EFFECT_0].Effect = 0;
1223 spellInfo->Effects[EFFECT_2].DieSides = spellInfo->Effects[EFFECT_0].DieSides;
1224 spellInfo->Effects[EFFECT_2].TargetA = spellInfo->Effects[EFFECT_0].TargetB;
1225 spellInfo->Effects[EFFECT_2].RadiusEntry = spellInfo->Effects[EFFECT_0].RadiusEntry;
1226 spellInfo->Effects[EFFECT_2].BasePoints = spellInfo->Effects[EFFECT_0].BasePoints;
1227 });
1228
1229 // Divine Hymn
1230 ApplySpellFix({ 64844 }, [](SpellInfo* spellInfo)
1231 {
1232 spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
1233 spellInfo->SpellLevel = 0;
1234 });
1235
1237 14898, // Spiritual Healing affects prayer of mending
1238 15349,
1239 15354,
1240 15355,
1241 15356,
1242 47562, // Divine Providence affects prayer of mending
1243 47564,
1244 47565,
1245 47566,
1246 47567,
1247 47586, // Twin Disciplines affects prayer of mending
1248 47587,
1249 47588,
1250 52802,
1251 52803
1252 }, [](SpellInfo* spellInfo)
1253 {
1254 spellInfo->Effects[EFFECT_0].SpellClassMask[1] |= 0x20; // prayer of mending
1255 });
1256
1257 // Power Infusion
1258 ApplySpellFix({ 10060 }, [](SpellInfo* spellInfo)
1259 {
1260 // hack to fix stacking with arcane power
1261 spellInfo->Effects[EFFECT_2].Effect = SPELL_EFFECT_APPLY_AURA;
1262 spellInfo->Effects[EFFECT_2].ApplyAuraName = SPELL_AURA_ADD_PCT_MODIFIER;
1263 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ALLY);
1264 });
1265
1266 // Lifebloom final bloom
1267 ApplySpellFix({ 33778 }, [](SpellInfo* spellInfo)
1268 {
1269 spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
1270 spellInfo->SpellLevel = 0;
1271 spellInfo->SpellFamilyFlags = flag96(0, 0x10, 0);
1272 });
1273
1274 // Owlkin Frenzy
1275 ApplySpellFix({ 48391 }, [](SpellInfo* spellInfo)
1276 {
1277 spellInfo->Attributes |= SPELL_ATTR0_NOT_SHAPESHIFTED;
1278 });
1279
1280 // Item T10 Restoration 4P Bonus
1281 ApplySpellFix({ 70691 }, [](SpellInfo* spellInfo)
1282 {
1283 spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_MODIFIERS;
1284 });
1285
1287 770, // Faerie Fire
1288 16857 // Faerie Fire (Feral)
1289 }, [](SpellInfo* spellInfo)
1290 {
1291 spellInfo->AttributesEx &= ~SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS;
1292 });
1293
1294 ApplySpellFix({ 49376 }, [](SpellInfo* spellInfo)
1295 {
1296 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS); // 3yd
1297 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_TARGET_PROCS;
1298 });
1299
1300 // Feral Charge - Cat
1301 ApplySpellFix({ 61138, 61132, 50259 }, [](SpellInfo* spellInfo)
1302 {
1303 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_TARGET_PROCS;
1304 });
1305
1306 // Glyph of Barkskin
1307 ApplySpellFix({ 63058 }, [](SpellInfo* spellInfo)
1308 {
1309 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE;
1310 });
1311
1312 // Resurrection Sickness
1313 ApplySpellFix({ 15007 }, [](SpellInfo* spellInfo)
1314 {
1315 spellInfo->SpellFamilyName = SPELLFAMILY_GENERIC;
1316 });
1317
1318 // Luck of the Draw
1319 ApplySpellFix({ 72221 }, [](SpellInfo* spellInfo)
1320 {
1321 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
1322 });
1323
1324 // Bind
1325 ApplySpellFix({ 3286 }, [](SpellInfo* spellInfo)
1326 {
1327 spellInfo->Targets = 0; // neutral innkeepers not friendly?
1328 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
1329 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
1330 });
1331
1332 // Playback Speech
1333 ApplySpellFix({ 74209 }, [](SpellInfo* spellInfo)
1334 {
1335 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(1);
1336 });
1337
1339 2641, // Dismiss Pet
1340 23356 // Taming Lesson
1341 }, [](SpellInfo* spellInfo)
1342 {
1343 // remove creaturetargettype
1344 spellInfo->TargetCreatureType = 0;
1345 });
1346
1347 // Aspect of the Viper
1348 ApplySpellFix({ 34074 }, [](SpellInfo* spellInfo)
1349 {
1350 spellInfo->Effects[EFFECT_2].Effect = SPELL_EFFECT_APPLY_AURA;
1351 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(1);
1352 spellInfo->Effects[EFFECT_2].ApplyAuraName = SPELL_AURA_DUMMY;
1353 });
1354
1355 // Strength of Wrynn
1356 ApplySpellFix({ 60509 }, [](SpellInfo* spellInfo)
1357 {
1358 spellInfo->Effects[EFFECT_2].BasePoints = 1500;
1359 spellInfo->Effects[EFFECT_1].BasePoints = 150;
1360 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_PERIODIC_HEAL;
1361 });
1362
1363 // Winterfin First Responder
1364 ApplySpellFix({ 48739 }, [](SpellInfo* spellInfo)
1365 {
1366 spellInfo->Effects[EFFECT_0].BasePoints = 1;
1367 spellInfo->Effects[EFFECT_0].RealPointsPerLevel = 0;
1368 spellInfo->Effects[EFFECT_0].DieSides = 0;
1369 spellInfo->Effects[EFFECT_0].DamageMultiplier = 0;
1370 spellInfo->Effects[EFFECT_0].BonusMultiplier = 0;
1371 });
1372
1373 // Army of the Dead (trigger npc aura)
1374 ApplySpellFix({ 49099 }, [](SpellInfo* spellInfo)
1375 {
1376 spellInfo->Effects[EFFECT_0].Amplitude = 15000;
1377 });
1378
1379 // Frightening Shout
1380 ApplySpellFix({ 19134 }, [](SpellInfo* spellInfo)
1381 {
1382 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_DUMMY;
1383 });
1384
1385 // Isle of Conquest
1386 ApplySpellFix({ 66551 }, [](SpellInfo* spellInfo)
1387 {
1388 // Teleport in, missing range
1389 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
1390 });
1391
1392 // A'dal's Song of Battle
1393 ApplySpellFix({ 39953 }, [](SpellInfo* spellInfo)
1394 {
1395 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
1396 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
1397 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
1398 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
1399 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
1400 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
1401 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(367); // 2 Hours
1402 });
1403
1405 57607, // WintergraspCatapult - Spell Plague Barrel - EffectRadiusIndex
1406 57619, // WintergraspDemolisher - Spell Hourl Boulder - EffectRadiusIndex
1407 57610 // Cannon (Siege Turret)
1408 }, [](SpellInfo* spellInfo)
1409 {
1410 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_25_YARDS); // SPELL_EFFECT_WMO_DAMAGE
1411 });
1412
1413 // WintergraspCannon - Spell Fire Cannon - EffectRadiusIndex
1414 ApplySpellFix({ 51422 }, [](SpellInfo* spellInfo)
1415 {
1416 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // SPELL_EFFECT_SCHOOL_DAMAGE
1417 });
1418
1419 // WintergraspDemolisher - Spell Ram - EffectRadiusIndex
1420 ApplySpellFix({ 54107 }, [](SpellInfo* spellInfo)
1421 {
1422 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS); // SPELL_EFFECT_KNOCK_BACK
1423 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS); // SPELL_EFFECT_SCHOOL_DAMAGE
1424 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS); // SPELL_EFFECT_WEAPON_DAMAGE
1425 });
1426
1427 // WintergraspSiegeEngine - Spell Ram - EffectRadiusIndex
1428 ApplySpellFix({ 51678 }, [](SpellInfo* spellInfo)
1429 {
1430 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // SPELL_EFFECT_KNOCK_BACK
1431 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // SPELL_EFFECT_SCHOOL_DAMAGE
1432 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // SPELL_EFFECT_WEAPON_DAMAGE
1433 });
1434
1435 // WintergraspCatapult - Spell Plague Barrell - Range
1436 ApplySpellFix({ 57606 }, [](SpellInfo* spellInfo)
1437 {
1438 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(164); // "Catapult Range"
1439 });
1440
1441 // Boulder (Demolisher)
1442 ApplySpellFix({ 50999 }, [](SpellInfo* spellInfo)
1443 {
1444 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
1445 });
1446
1447 // Flame Breath (Catapult)
1448 ApplySpellFix({ 50990 }, [](SpellInfo* spellInfo)
1449 {
1450 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_18_YARDS); // 18yd
1451 });
1452
1453 // Jormungar Bite
1454 ApplySpellFix({ 56103 }, [](SpellInfo* spellInfo)
1455 {
1456 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
1457 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1458 });
1459
1460 // Throw Proximity Bomb
1461 ApplySpellFix({ 34095 }, [](SpellInfo* spellInfo)
1462 {
1463 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ENEMY);
1464 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1465 });
1466
1468 53348, // DEATH KNIGHT SCARLET FIRE ARROW
1469 53117 // BALISTA
1470 }, [](SpellInfo* spellInfo)
1471 {
1472 spellInfo->RecoveryTime = 5000;
1473 spellInfo->CategoryRecoveryTime = 5000;
1474 });
1475
1476 // Teleport To Molten Core
1477 ApplySpellFix({ 25139 }, [](SpellInfo* spellInfo)
1478 {
1479 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
1480 });
1481
1482 // Landen Stilwell Transform
1483 ApplySpellFix({ 31310 }, [](SpellInfo* spellInfo)
1484 {
1485 spellInfo->Attributes |= SPELL_ATTR0_PASSIVE;
1486 });
1487
1488 // Shadowstalker Stealth
1489 ApplySpellFix({ 5916 }, [](SpellInfo* spellInfo)
1490 {
1491 spellInfo->Effects[EFFECT_0].RealPointsPerLevel = 5.0f;
1492 });
1493
1494 // Sneak
1495 ApplySpellFix({ 22766 }, [](SpellInfo* spellInfo)
1496 {
1497 spellInfo->Effects[EFFECT_0].RealPointsPerLevel = 5.0f;
1498 });
1499
1500 // Murmur's Touch
1501 ApplySpellFix({ 38794, 33711 }, [](SpellInfo* spellInfo)
1502 {
1503 spellInfo->MaxAffectedTargets = 1;
1504 spellInfo->Effects[EFFECT_0].TriggerSpell = 33760;
1505 });
1506
1507 // Negaton Field
1509 36729, // Normal
1510 38834 // Heroic
1511 }, [](SpellInfo* spellInfo)
1512 {
1513 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
1514 });
1515
1516 // Curse of the Doomsayer NORMAL
1517 ApplySpellFix({ 36173 }, [](SpellInfo* spellInfo)
1518 {
1519 spellInfo->Effects[EFFECT_0].TriggerSpell = 36174; // Currently triggers heroic version...
1520 });
1521
1522 // Crystal Channel
1523 ApplySpellFix({ 34156 }, [](SpellInfo* spellInfo)
1524 {
1525 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(35); // 35yd;
1526 spellInfo->ChannelInterruptFlags |= AURA_INTERRUPT_FLAG_MOVE;
1527 });
1528
1529 // Debris - Debris Visual
1530 ApplySpellFix({ 36449, 30632 }, [](SpellInfo* spellInfo)
1531 {
1532 spellInfo->Attributes |= SPELL_ATTR0_AURA_IS_DEBUFF;
1533 });
1534
1535 // Soul Channel
1536 ApplySpellFix({ 30531 }, [](SpellInfo* spellInfo)
1537 {
1538 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
1539 });
1540
1541 // Activate Sunblade Protecto
1542 ApplySpellFix({ 46475, 46476 }, [](SpellInfo* spellInfo)
1543 {
1544 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(14); // 60yd
1545 });
1546
1547 // Break Ice
1548 ApplySpellFix({ 46638 }, [](SpellInfo* spellInfo)
1549 {
1550 spellInfo->AttributesEx3 &= ~SPELL_ATTR3_ONLY_ON_PLAYER; // Obvious fail, it targets gameobject...
1551 });
1552
1553 // Sinister Reflection Clone
1554 ApplySpellFix({ 45785 }, [](SpellInfo* spellInfo)
1555 {
1556 spellInfo->Speed = 0.0f;
1557 });
1558
1559 // Armageddon
1560 ApplySpellFix({ 45909 }, [](SpellInfo* spellInfo)
1561 {
1562 spellInfo->Speed = 8.0f;
1563 });
1564
1565 // Spell Absorption
1566 ApplySpellFix({ 41034 }, [](SpellInfo* spellInfo)
1567 {
1568 spellInfo->Effects[EFFECT_2].Effect = SPELL_EFFECT_APPLY_AURA;
1569 spellInfo->Effects[EFFECT_2].ApplyAuraName = SPELL_AURA_SCHOOL_ABSORB;
1570 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
1571 spellInfo->Effects[EFFECT_2].MiscValue = SPELL_SCHOOL_MASK_MAGIC;
1572 });
1573
1574 // Shared Bonds
1575 ApplySpellFix({ 41363 }, [](SpellInfo* spellInfo)
1576 {
1577 spellInfo->AttributesEx &= ~SPELL_ATTR1_IS_CHANNELED;
1578 });
1579
1581 41485, // Deadly Poison
1582 41487 // Envenom
1583 }, [](SpellInfo* spellInfo)
1584 {
1585 spellInfo->AttributesEx6 |= SPELL_ATTR6_IGNORE_PHASE_SHIFT;
1586 });
1587
1588 // Parasitic Shadowfiend
1589 ApplySpellFix({ 41914 }, [](SpellInfo* spellInfo)
1590 {
1591 spellInfo->Attributes |= SPELL_ATTR0_AURA_IS_DEBUFF;
1592 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
1593 });
1594
1595 // Teleport Maiev
1596 ApplySpellFix({ 41221 }, [](SpellInfo* spellInfo)
1597 {
1598 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 0-50000yd
1599 });
1600
1601 // Watery Grave Explosion
1602 ApplySpellFix({ 37852 }, [](SpellInfo* spellInfo)
1603 {
1604 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_WHILE_STUNNED;
1605 });
1606
1607 // Amplify Damage
1608 ApplySpellFix({ 39095 }, [](SpellInfo* spellInfo)
1609 {
1610 spellInfo->MaxAffectedTargets = 1;
1611 });
1612
1613 // Energy Feedback
1614 ApplySpellFix({ 44335 }, [](SpellInfo* spellInfo)
1615 {
1616 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
1617 });
1618
1620 31984, // Finger of Death
1621 35354 // Hand of Death
1622 }, [](SpellInfo* spellInfo)
1623 {
1624 // Spell doesn't need to ignore invulnerabilities
1625 spellInfo->Attributes = SPELL_ATTR0_IS_ABILITY;
1626 });
1627
1628 // Finger of Death
1629 ApplySpellFix({ 32111 }, [](SpellInfo* spellInfo)
1630 {
1631 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(0); // We only need the animation, no damage
1632 });
1633
1634 // Flame Breath, catapult spell
1635 ApplySpellFix({ 50989 }, [](SpellInfo* spellInfo)
1636 {
1637 spellInfo->Attributes &= ~SPELL_ATTR0_SCALES_WITH_CREATURE_LEVEL;
1638 });
1639
1640 // Koralon, Flaming Cinder
1641 ApplySpellFix({ 66690 }, [](SpellInfo* spellInfo)
1642 {
1643 // missing radius index
1644 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
1645 spellInfo->MaxAffectedTargets = 1;
1646 });
1647
1648 // Acid Volley
1649 ApplySpellFix({ 54714, 29325 }, [](SpellInfo* spellInfo)
1650 {
1651 spellInfo->MaxAffectedTargets = 1;
1652 });
1653
1654 // Summon Plagued Warrior
1655 ApplySpellFix({ 29237 }, [](SpellInfo* spellInfo)
1656 {
1657 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_DUMMY;
1658 spellInfo->Effects[EFFECT_1].Effect = spellInfo->Effects[EFFECT_2].Effect = 0;
1659 });
1660
1661 // Icebolt
1662 ApplySpellFix({ 28526 }, [](SpellInfo* spellInfo)
1663 {
1664 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
1665 });
1666
1667 // Infected Wound
1668 ApplySpellFix({ 29306 }, [](SpellInfo* spellInfo)
1669 {
1670 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
1671 });
1672
1673 // Hopeless
1674 ApplySpellFix({ 29125 }, [](SpellInfo* spellInfo)
1675 {
1676 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
1677 });
1678
1679 // Jagged Knife
1680 ApplySpellFix({ 55550 }, [](SpellInfo* spellInfo)
1681 {
1682 spellInfo->Attributes |= SPELL_ATTR0_USES_RANGED_SLOT;
1683 });
1684
1685 // Moorabi - Transformation
1686 ApplySpellFix({ 55098 }, [](SpellInfo* spellInfo)
1687 {
1688 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
1689 });
1690
1692 55521, // Poisoned Spear (Normal)
1693 58967, // Poisoned Spear (Heroic)
1694 55348, // Throw (Normal)
1695 58966 // Throw (Heroic)
1696 }, [](SpellInfo* spellInfo)
1697 {
1698 spellInfo->Attributes |= SPELL_ATTR0_USES_RANGED_SLOT;
1699 });
1700
1701 // Charged Chaotic rift aura, trigger
1702 ApplySpellFix({ 47737 }, [](SpellInfo* spellInfo)
1703 {
1704 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(37); // 50yd
1705 });
1706
1707 // Vanish
1708 ApplySpellFix({ 55964 }, [](SpellInfo* spellInfo)
1709 {
1710 spellInfo->Effects[EFFECT_1].Effect = 0;
1711 spellInfo->Effects[EFFECT_2].Effect = 0;
1712 });
1713
1714 // Trollgore - Summon Drakkari Invader
1715 ApplySpellFix({ 49456, 49457, 49458 }, [](SpellInfo* spellInfo)
1716 {
1717 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB);
1718 });
1719
1721 48278, // Paralyse
1722 47669 // Awaken subboss
1723 }, [](SpellInfo* spellInfo)
1724 {
1725 spellInfo->Effects[0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
1726 spellInfo->Effects[0].TargetB = SpellImplicitTargetInfo();
1727 });
1728
1729 // Flame Breath
1730 ApplySpellFix({ 47592 }, [](SpellInfo* spellInfo)
1731 {
1732 spellInfo->Effects[EFFECT_0].Amplitude = 200;
1733 });
1734
1735 // Skarvald, Charge
1736 ApplySpellFix({ 43651 }, [](SpellInfo* spellInfo)
1737 {
1738 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 0-50000yd
1739 });
1740
1741 // Ingvar the Plunderer, Woe Strike
1742 ApplySpellFix({ 42730 }, [](SpellInfo* spellInfo)
1743 {
1744 spellInfo->Effects[EFFECT_1].TriggerSpell = 42739;
1745 });
1746
1747 ApplySpellFix({ 59735 }, [](SpellInfo* spellInfo)
1748 {
1749 spellInfo->Effects[EFFECT_1].TriggerSpell = 59736;
1750 });
1751
1752 // Ingvar the Plunderer, Ingvar transform
1753 ApplySpellFix({ 42796 }, [](SpellInfo* spellInfo)
1754 {
1755 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
1756 });
1757
1759 42772, // Hurl Dagger (Normal)
1760 59685 // Hurl Dagger (Heroic)
1761 }, [](SpellInfo* spellInfo)
1762 {
1763 spellInfo->Attributes |= SPELL_ATTR0_USES_RANGED_SLOT;
1764 });
1765
1766 // Control Crystal Activation
1767 ApplySpellFix({ 57804 }, [](SpellInfo* spellInfo)
1768 {
1769 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(1);
1770 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1771 });
1772
1773 // Destroy Door Seal
1774 ApplySpellFix({ 58040 }, [](SpellInfo* spellInfo)
1775 {
1776 spellInfo->ChannelInterruptFlags &= ~(AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE);
1777 });
1778
1779 // Ichoron, Water Blast
1780 ApplySpellFix({ 54237, 59520 }, [](SpellInfo* spellInfo)
1781 {
1782 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
1783 });
1784
1785 // Krik'thir - Mind Flay
1786 ApplySpellFix({ 52586, 59367 }, [](SpellInfo* spellInfo)
1787 {
1788 spellInfo->ChannelInterruptFlags |= AURA_INTERRUPT_FLAG_MOVE;
1789 });
1790
1791 // Glare of the Tribunal
1792 ApplySpellFix({ 50988, 59870 }, [](SpellInfo* spellInfo)
1793 {
1794 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
1795 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1796 });
1797
1798 // Static Charge
1799 ApplySpellFix({ 50835, 59847 }, [](SpellInfo* spellInfo)
1800 {
1801 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
1802 });
1803
1804 // Lava Strike damage
1805 ApplySpellFix({ 57697 }, [](SpellInfo* spellInfo)
1806 {
1807 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
1808 });
1809
1810 // Lava Strike trigger
1811 ApplySpellFix({ 57578 }, [](SpellInfo* spellInfo)
1812 {
1813 spellInfo->MaxAffectedTargets = 1;
1814 });
1815
1816 // Gift of Twilight Shadow/Fire
1817 ApplySpellFix({ 57835, 58766 }, [](SpellInfo* spellInfo)
1818 {
1819 spellInfo->AttributesEx &= ~SPELL_ATTR1_IS_CHANNELED;
1820 });
1821
1822 // Pyrobuffet
1823 ApplySpellFix({ 57557 }, [](SpellInfo* spellInfo)
1824 {
1825 spellInfo->ExcludeTargetAuraSpell = 56911;
1826 });
1827
1828 // Arcane Barrage
1829 ApplySpellFix({ 56397 }, [](SpellInfo* spellInfo)
1830 {
1831 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
1832 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1833 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
1834 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
1835 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
1836 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo();
1837 });
1838
1840 55849, // Power Spark (ground +50% dmg aura)
1841 56438, // Arcane Overload (-50% dmg taken) - this is to prevent apply -> unapply -> apply ... dunno whether it's correct
1842 }, [](SpellInfo* spellInfo)
1843 {
1844 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
1845 });
1846
1847 // Vortex (Control Vehicle)
1848 ApplySpellFix({ 56263 }, [](SpellInfo* spellInfo)
1849 {
1850 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
1851 });
1852
1853 // Haste (Nexus Lord, increase run Speed of the disk)
1854 ApplySpellFix({ 57060 }, [](SpellInfo* spellInfo)
1855 {
1856 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_VEHICLE);
1857 });
1858
1859 // Arcane Overload
1860 ApplySpellFix({ 56430 }, [](SpellInfo* spellInfo)
1861 {
1862 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_TRIGGER_MISSILE;
1863 spellInfo->Effects[EFFECT_0].TriggerSpell = 56429;
1864 });
1865
1866 // Summon Arcane Bomb
1867 ApplySpellFix({ 56429 }, [](SpellInfo* spellInfo)
1868 {
1869 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
1870 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1871 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo();
1872 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
1873 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo();
1874 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo();
1875 });
1876
1877 // Destroy Platform Event
1878 ApplySpellFix({ 59099 }, [](SpellInfo* spellInfo)
1879 {
1880 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(22);
1881 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(15);
1882 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(22);
1883 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo(15);
1884 });
1885
1886 // Surge of Power (Phase 3)
1888 57407, // N
1889 }, [](SpellInfo* spellInfo)
1890 {
1891 spellInfo->MaxAffectedTargets = 1;
1892 spellInfo->InterruptFlags = 0;
1893 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS);
1894 spellInfo->AttributesEx4 |= SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING;
1895 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
1896 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
1897 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1898 });
1899
1900 // Surge of Power (Phase 3)
1902 60936 // H
1903 }, [](SpellInfo* spellInfo)
1904 {
1905 spellInfo->MaxAffectedTargets = 3;
1906 spellInfo->InterruptFlags = 0;
1907 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS);
1908 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
1909 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
1910 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1911 });
1912
1913 // Wyrmrest Drake - Life Burst
1914 ApplySpellFix({ 57143 }, [](SpellInfo* spellInfo)
1915 {
1916 spellInfo->Effects[EFFECT_0].Effect = 0;
1917 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo();
1918 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1919 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
1920 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
1921 spellInfo->Effects[EFFECT_1].PointsPerComboPoint = 2500;
1922 spellInfo->Effects[EFFECT_1].BasePoints = 2499;
1923 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(1);
1924 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1925 });
1926
1927 //Alexstrasza - Gift
1928 ApplySpellFix({ 61028 }, [](SpellInfo* spellInfo)
1929 {
1930 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
1931 });
1932
1933 // Vortex (freeze anim)
1934 ApplySpellFix({ 55883 }, [](SpellInfo* spellInfo)
1935 {
1936 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
1937 });
1938
1939 // Hurl Pyrite
1940 ApplySpellFix({ 62490 }, [](SpellInfo* spellInfo)
1941 {
1942 spellInfo->Effects[EFFECT_1].Effect = 0;
1943 });
1944
1945 // Ulduar, Mimiron, Magnetic Core (summon)
1946 // Meeting Stone Summon
1947 ApplySpellFix({ 64444, 23598 }, [](SpellInfo* spellInfo)
1948 {
1949 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
1950 });
1951
1952 // Ulduar, Mimiron, bomb bot explosion
1953 ApplySpellFix({ 63801 }, [](SpellInfo* spellInfo)
1954 {
1955 spellInfo->Effects[EFFECT_1].MiscValue = 17286;
1956 });
1957
1958 // Ulduar, Mimiron, Summon Flames Initial
1959 ApplySpellFix({ 64563 }, [](SpellInfo* spellInfo)
1960 {
1961 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1962 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
1963 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
1964 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1965 });
1966
1967 // Ulduar, Mimiron, Flames (damage)
1968 ApplySpellFix({ 64566 }, [](SpellInfo* spellInfo)
1969 {
1970 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1971 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
1972 });
1973
1974 // Ulduar, Hodir, Starlight
1975 ApplySpellFix({ 62807 }, [](SpellInfo* spellInfo)
1976 {
1977 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_1_YARD); // 1yd
1978 });
1979
1980 // Hodir Shatter Cache
1981 ApplySpellFix({ 62502 }, [](SpellInfo* spellInfo)
1982 {
1983 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
1984 });
1985
1986 // Ulduar, General Vezax, Mark of the Faceless
1987 ApplySpellFix({ 63278 }, [](SpellInfo* spellInfo)
1988 {
1989 spellInfo->Effects[EFFECT_0].Effect = 0;
1990 });
1991
1992 // Boom (XT-002)
1993 ApplySpellFix({ 62834 }, [](SpellInfo* spellInfo)
1994 {
1995 spellInfo->Effects[EFFECT_1].Effect = 0;
1996 });
1997
1998 // Supercharge
1999 ApplySpellFix({ 61920 }, [](SpellInfo* spellInfo)
2000 {
2001 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
2002 });
2003
2004 // Lightning Whirl
2005 ApplySpellFix({ 61916 }, [](SpellInfo* spellInfo)
2006 {
2007 spellInfo->MaxAffectedTargets = 3;
2008 });
2009
2010 ApplySpellFix({ 63482 }, [](SpellInfo* spellInfo)
2011 {
2012 spellInfo->MaxAffectedTargets = 8;
2013 });
2014
2015 // Stone Grip, remove absorb aura
2016 ApplySpellFix({ 62056, 63985 }, [](SpellInfo* spellInfo)
2017 {
2018 spellInfo->Effects[EFFECT_1].Effect = 0;
2019 });
2020
2021 // Sentinel Blast
2022 ApplySpellFix({ 64389, 64678 }, [](SpellInfo* spellInfo)
2023 {
2024 spellInfo->Dispel = DISPEL_MAGIC;
2025 });
2026
2027 // Potent Pheromones
2028 ApplySpellFix({ 62619 }, [](SpellInfo* spellInfo)
2029 {
2030 spellInfo->AttributesEx |= SPELL_ATTR1_IMMUNITY_PURGES_EFFECT;
2031 });
2032
2033 // Healthy spore summon periodic
2034 ApplySpellFix({ 62566 }, [](SpellInfo* spellInfo)
2035 {
2036 spellInfo->Effects[EFFECT_0].Amplitude = 2000;
2037 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PERIODIC_TRIGGER_SPELL;
2038 });
2039
2040 // Brightleaf Essence trigger
2041 ApplySpellFix({ 62968 }, [](SpellInfo* spellInfo)
2042 {
2043 spellInfo->Effects[EFFECT_1].Effect = 0; // duplicate
2044 });
2045
2046 // Potent Pheromones
2047 ApplySpellFix({ 64321 }, [](SpellInfo* spellInfo)
2048 {
2049 spellInfo->AttributesEx3 |= SPELL_ATTR3_ONLY_ON_PLAYER;
2050 spellInfo->AttributesEx |= SPELL_ATTR1_IMMUNITY_PURGES_EFFECT;
2051 });
2052
2053 // Lightning Orb Charged
2054 ApplySpellFix({ 62186 }, [](SpellInfo* spellInfo)
2055 {
2056 spellInfo->Effects[EFFECT_0].Amplitude = 5000; // Duration 5 secs, amplitude 8 secs...
2057 });
2058
2059 // Lightning Pillar
2060 ApplySpellFix({ 62976 }, [](SpellInfo* spellInfo)
2061 {
2062 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6);
2063 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(28); // 5 seconds, wrong DBC data?
2064 });
2065
2066 // Sif's Blizzard
2067 ApplySpellFix({ 62576, 62602 }, [](SpellInfo* spellInfo)
2068 {
2069 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_8_YARDS); // 8yd
2070 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_8_YARDS); // 8yd
2071 });
2072
2073 // Protective Gaze
2074 ApplySpellFix({ 64175 }, [](SpellInfo* spellInfo)
2075 {
2076 spellInfo->RecoveryTime = 25000;
2077 });
2078
2079 // Shadow Beacon
2080 ApplySpellFix({ 64465 }, [](SpellInfo* spellInfo)
2081 {
2082 spellInfo->Effects[EFFECT_0].TriggerSpell = 64467; // why do they need two script effects :/ (this one has visual effect)
2083 });
2084
2085 // Sanity
2086 ApplySpellFix({ 63050 }, [](SpellInfo* spellInfo)
2087 {
2088 spellInfo->AttributesEx6 |= SPELL_ATTR6_IGNORE_PHASE_SHIFT;
2089 });
2090
2091 // Shadow Nova
2092 ApplySpellFix({ 62714, 65209 }, [](SpellInfo* spellInfo)
2093 {
2094 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
2095 });
2096
2097 // Cosmic Smash (Algalon the Observer)
2098 ApplySpellFix({ 62293 }, [](SpellInfo* spellInfo)
2099 {
2100 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
2101 });
2102
2103 // Cosmic Smash (Algalon the Observer)
2104 ApplySpellFix({ 62311, 64596 }, [](SpellInfo* spellInfo)
2105 {
2106 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2107 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
2108 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
2109 });
2110
2111 // Constellation Phase Effect
2112 ApplySpellFix({ 65509 }, [](SpellInfo* spellInfo)
2113 {
2114 spellInfo->MaxAffectedTargets = 1;
2115 });
2116
2117 // Black Hole
2118 ApplySpellFix({ 62168, 65250, 62169 }, [](SpellInfo* spellInfo)
2119 {
2120 spellInfo->Attributes |= SPELL_ATTR0_AURA_IS_DEBUFF;
2121 });
2122
2123 // Ground Slam
2124 ApplySpellFix({ 62625 }, [](SpellInfo* spellInfo)
2125 {
2126 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
2127 });
2128
2129 // Onyxia's Lair, Onyxia, Flame Breath (TriggerSpell = 0 and spamming errors in console)
2130 ApplySpellFix({ 18435 }, [](SpellInfo* spellInfo)
2131 {
2132 spellInfo->Effects[EFFECT_1].Effect = 0;
2133 });
2134
2135 // Onyxia's Lair, Onyxia, Create Onyxia Spawner
2136 ApplySpellFix({ 17647 }, [](SpellInfo* spellInfo)
2137 {
2138 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(37);
2139 });
2140
2142 17646, // Onyxia's Lair, Onyxia, Summon Onyxia Whelp
2143 68968 // Onyxia's Lair, Onyxia, Summon Lair Guard
2144 }, [](SpellInfo* spellInfo)
2145 {
2146 spellInfo->Targets |= TARGET_FLAG_DEST_LOCATION;
2147 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2148 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
2149 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(5);
2150 });
2151
2152 // Onyxia's Lair, Onyxia, Eruption
2153 ApplySpellFix({ 17731, 69294 }, [](SpellInfo* spellInfo)
2154 {
2155 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_DUMMY;
2156 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(3);
2157 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_18_YARDS); // 18yd instead of 13yd to make sure all cracks erupt
2158 });
2159
2160 // Onyxia's Lair, Onyxia, Breath
2162 18576, 18578, 18579, 18580, 18581, 18582, 18583, 18609, 18611, 18612, 18613, 18614, 18615, 18616, 18584,
2163 18585, 18586, 18587, 18588, 18589, 18590, 18591, 18592, 18593, 18594, 18595, 18564, 18565, 18566, 18567,
2164 18568, 18569, 18570, 18571, 18572, 18573, 18574, 18575, 18596, 18597, 18598, 18599, 18600, 18601, 18602,
2165 18603, 18604, 18605, 18606, 18607, 18617, 18619, 18620, 18621, 18622, 18623, 18624, 18625, 18626, 18627,
2166 18628, 18618, 18351, 18352, 18353, 18354, 18355, 18356, 18357, 18358, 18359, 18360, 18361, 17086, 17087,
2167 17088, 17089, 17090, 17091, 17092, 17093, 17094, 17095, 17097, 22267, 22268, 21132, 21133, 21135, 21136,
2168 21137, 21138, 21139
2169 }, [](SpellInfo* spellInfo)
2170 {
2171 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(328); // 250ms
2172 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(1);
2173 if (spellInfo->Effects[EFFECT_1].Effect)
2174 {
2175 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
2176 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_PERIODIC_TRIGGER_SPELL;
2177 spellInfo->Effects[EFFECT_1].Amplitude = ((spellInfo->CastTimeEntry == sSpellCastTimesStore.LookupEntry(170)) ? 50 : 215);
2178 }
2179 });
2180
2182 48760, // Oculus, Teleport to Coldarra DND
2183 49305 // Oculus, Teleport to Boss 1 DND
2184 }, [](SpellInfo* spellInfo)
2185 {
2186 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
2187 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(17);
2188 });
2189
2190 // Oculus, Drake spell Stop Time
2191 ApplySpellFix({ 49838 }, [](SpellInfo* spellInfo)
2192 {
2193 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_TARGET_PROCS;
2194 spellInfo->ExcludeTargetAuraSpell = 51162; // exclude planar shift
2195 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_150_YARDS);
2196 });
2197
2198 // Oculus, Varos Cloudstrider, Energize Cores
2199 ApplySpellFix({ 61407, 62136, 56251, 54069 }, [](SpellInfo* spellInfo)
2200 {
2201 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CONE_ENTRY);
2202 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2203 });
2204
2205 // Halls of Lightning, Arc Weld
2206 ApplySpellFix({ 59086 }, [](SpellInfo* spellInfo)
2207 {
2208 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(1);
2209 });
2210
2211 // Halls of Lightning, Arcing Burn
2212 ApplySpellFix({ 52671, 59834 }, [](SpellInfo* spellInfo)
2213 {
2214 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
2215 });
2216
2217 // Trial of the Champion, Death's Respite
2218 ApplySpellFix({ 68306 }, [](SpellInfo* spellInfo)
2219 {
2220 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
2221 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(25);
2222 });
2223
2224 // Trial of the Champion, Eadric Achievement (The Faceroller)
2225 ApplySpellFix({ 68197 }, [](SpellInfo* spellInfo)
2226 {
2227 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
2228 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD;
2229 });
2230
2231 // Trial of the Champion, Earth Shield
2232 ApplySpellFix({ 67530 }, [](SpellInfo* spellInfo)
2233 {
2234 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PROC_TRIGGER_SPELL; // will trigger 67537
2235 });
2236
2237 // Trial of the Champion, Hammer of the Righteous
2238 ApplySpellFix({ 66867 }, [](SpellInfo* spellInfo)
2239 {
2240 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_DUMMY;
2241 });
2242
2243 // Trial of the Champion, Summon Risen Jaeren/Arelas
2244 ApplySpellFix({ 67705, 67715 }, [](SpellInfo* spellInfo)
2245 {
2246 spellInfo->AttributesEx2 |= SPELL_ATTR2_ALLOW_DEAD_TARGET;
2247 });
2248
2249 // Trial of the Champion, Ghoul Explode
2250 ApplySpellFix({ 67751 }, [](SpellInfo* spellInfo)
2251 {
2252 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2253 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2254 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS);
2255 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2256 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2257 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS);
2258 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2259 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2260 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS);
2261 });
2262
2263 // Trial of the Champion, Desecration
2264 ApplySpellFix({ 67778, 67877 }, [](SpellInfo* spellInfo)
2265 {
2266 spellInfo->Effects[EFFECT_0].TriggerSpell = 68766;
2267 });
2268
2269 // Killing Spree (Off hand damage)
2270 ApplySpellFix({ 57842 }, [](SpellInfo* spellInfo)
2271 {
2272 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(2); // Melee Range
2273 });
2274
2275 // Trial of the Crusader, Jaraxxus Intro spell
2276 ApplySpellFix({ 67888 }, [](SpellInfo* spellInfo)
2277 {
2278 spellInfo->Attributes |= SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT;
2279 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
2280 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_TARGET_PROCS;
2281 });
2282
2283 // Trial of the Crusader, Lich King Intro spell
2284 ApplySpellFix({ 68193 }, [](SpellInfo* spellInfo)
2285 {
2286 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
2287 });
2288
2289 // Trial of the Crusader, Gormok, player vehicle spell, CUSTOM! (default jump to hand, not used)
2290 ApplySpellFix({ 66342 }, [](SpellInfo* spellInfo)
2291 {
2292 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AURA;
2293 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_SET_VEHICLE_ID;
2294 spellInfo->Effects[EFFECT_0].MiscValue = 496;
2295 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21);
2296 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13);
2297 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
2298 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2299 spellInfo->AuraInterruptFlags = AURA_INTERRUPT_FLAG_CHANGE_MAP;
2300 });
2301
2302 // Trial of the Crusader, Gormok, Fire Bomb
2303 ApplySpellFix({ 66313 }, [](SpellInfo* spellInfo)
2304 {
2305 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2306 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ANY);
2307 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2308 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ANY);
2309 spellInfo->Effects[EFFECT_1].Effect = 0;
2310 });
2311
2312 ApplySpellFix({ 66317 }, [](SpellInfo* spellInfo)
2313 {
2314 spellInfo->Attributes |= SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT;
2315 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
2316 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_TARGET_PROCS;
2317 });
2318
2319 ApplySpellFix({ 66318 }, [](SpellInfo* spellInfo)
2320 {
2321 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2322 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2323 spellInfo->Speed = 14.0f;
2324 spellInfo->Attributes |= SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT;
2325 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
2326 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_TARGET_PROCS;
2327 });
2328
2329 ApplySpellFix({ 66320, 67472, 67473, 67475 }, [](SpellInfo* spellInfo)
2330 {
2331 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_2_YARDS);
2332 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_2_YARDS);
2333 });
2334
2335 // Trial of the Crusader, Acidmaw & Dreadscale, Emerge
2336 ApplySpellFix({ 66947 }, [](SpellInfo* spellInfo)
2337 {
2338 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_WHILE_STUNNED;
2339 });
2340
2341 // Trial of the Crusader, Jaraxxus, Curse of the Nether
2342 ApplySpellFix({ 66211 }, [](SpellInfo* spellInfo)
2343 {
2344 spellInfo->ExcludeTargetAuraSpell = 66209; // exclude Touch of Jaraxxus
2345 });
2346
2347 // Trial of the Crusader, Jaraxxus, Summon Volcano
2348 ApplySpellFix({ 66258, 67901 }, [](SpellInfo* spellInfo)
2349 {
2350 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(85); // summon for 18 seconds, 15 not enough
2351 });
2352
2353 // Trial of the Crusader, Jaraxxus, Spinning Pain Spike
2354 ApplySpellFix({ 66281 }, [](SpellInfo* spellInfo)
2355 {
2356 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_4_YARDS);
2357 });
2358
2359 ApplySpellFix({ 66287 }, [](SpellInfo* spellInfo)
2360 {
2361 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
2362 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_MOD_TAUNT;
2363 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_NEARBY_ENTRY);
2364 spellInfo->Effects[EFFECT_2].Effect = SPELL_EFFECT_APPLY_AURA;
2365 spellInfo->Effects[EFFECT_2].ApplyAuraName = SPELL_AURA_MOD_STUN;
2366 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
2367 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(35); // 4 secs
2368 });
2369
2370 // Trial of the Crusader, Jaraxxus, Fel Fireball
2371 ApplySpellFix({ 66532, 66963, 66964, 66965 }, [](SpellInfo* spellInfo)
2372 {
2373 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
2374 });
2375
2376 // tempfix, make Nether Power not stealable
2377 ApplySpellFix({ 66228, 67106, 67107, 67108 }, [](SpellInfo* spellInfo)
2378 {
2379 spellInfo->AttributesEx4 |= SPELL_ATTR4_CANNOT_BE_STOLEN;
2380 });
2381
2382 // Trial of the Crusader, Faction Champions, Druid - Tranquality
2383 ApplySpellFix({ 66086, 67974, 67975, 67976 }, [](SpellInfo* spellInfo)
2384 {
2385 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AREA_AURA_FRIEND;
2386 });
2387
2388 // Trial of the Crusader, Faction Champions, Shaman - Earth Shield
2389 ApplySpellFix({ 66063 }, [](SpellInfo* spellInfo)
2390 {
2391 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PROC_TRIGGER_SPELL;
2392 spellInfo->Effects[EFFECT_0].TriggerSpell = 66064;
2393 });
2394
2395 // Trial of the Crusader, Faction Champions, Priest - Mana Burn
2396 ApplySpellFix({ 66100 }, [](SpellInfo* spellInfo)
2397 {
2398 spellInfo->Effects[EFFECT_0].BasePoints = 5;
2399 spellInfo->Effects[EFFECT_0].DieSides = 0;
2400 });
2401
2402 ApplySpellFix({ 68026 }, [](SpellInfo* spellInfo)
2403 {
2404 spellInfo->Effects[EFFECT_0].BasePoints = 8;
2405 spellInfo->Effects[EFFECT_0].DieSides = 0;
2406 });
2407
2408 ApplySpellFix({ 68027 }, [](SpellInfo* spellInfo)
2409 {
2410 spellInfo->Effects[EFFECT_0].BasePoints = 6;
2411 spellInfo->Effects[EFFECT_0].DieSides = 0;
2412 });
2413
2414 ApplySpellFix({ 68028 }, [](SpellInfo* spellInfo)
2415 {
2416 spellInfo->Effects[EFFECT_0].BasePoints = 10;
2417 spellInfo->Effects[EFFECT_0].DieSides = 0;
2418 });
2419
2420 // Trial of the Crusader, Twin Valkyr, Touch of Light/Darkness, Light/Dark Surge
2422 65950 // light 0
2423 }, [](SpellInfo* spellInfo)
2424 {
2425 //spellInfo->EffectApplyAuraName[0] = SPELL_AURA_PERIODIC_DUMMY;
2426 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2427 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2428 spellInfo->Effects[EFFECT_1].Effect = 0;
2429 spellInfo->Effects[EFFECT_2].Effect = 0;
2430 });
2431
2433 65767 // light surge 0
2434 }, [](SpellInfo* spellInfo)
2435 {
2436 spellInfo->ExcludeTargetAuraSpell = 65686;
2437 });
2438
2440 67296 // light 1
2441 }, [](SpellInfo* spellInfo)
2442 {
2443 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2444 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2445 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2446 spellInfo->Effects[EFFECT_1].Effect = 0;
2447 spellInfo->Effects[EFFECT_2].Effect = 0;
2448 });
2449
2451 67274 // light surge 1
2452 }, [](SpellInfo* spellInfo)
2453 {
2454 spellInfo->ExcludeTargetAuraSpell = 67222;
2455 });
2456
2458 67297 // light 2
2459 }, [](SpellInfo* spellInfo)
2460 {
2461 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2462 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2463 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2464 spellInfo->Effects[EFFECT_1].Effect = 0;
2465 spellInfo->Effects[EFFECT_2].Effect = 0;
2466 });
2467
2469 67275 // light surge 2
2470 }, [](SpellInfo* spellInfo)
2471 {
2472 spellInfo->ExcludeTargetAuraSpell = 67223;
2473 });
2474
2476 67298 // light 3
2477 }, [](SpellInfo* spellInfo)
2478 {
2479 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2480 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2481 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2482 spellInfo->Effects[EFFECT_1].Effect = 0;
2483 spellInfo->Effects[EFFECT_2].Effect = 0;
2484 });
2485
2487 67276 // light surge 3
2488 }, [](SpellInfo* spellInfo)
2489 {
2490 spellInfo->ExcludeTargetAuraSpell = 67224;
2491 });
2492
2494 66001 // dark 0
2495 }, [](SpellInfo* spellInfo)
2496 {
2497 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2498 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2499 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2500 spellInfo->Effects[EFFECT_1].Effect = 0;
2501 spellInfo->Effects[EFFECT_2].Effect = 0;
2502 });
2503
2505 65769 // dark surge 0
2506 }, [](SpellInfo* spellInfo)
2507 {
2508 spellInfo->ExcludeTargetAuraSpell = 65684;
2509 });
2510
2512 67281 // dark 1
2513 }, [](SpellInfo* spellInfo)
2514 {
2515 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2516 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2517 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2518 spellInfo->Effects[EFFECT_1].Effect = 0;
2519 spellInfo->Effects[EFFECT_2].Effect = 0;
2520 });
2521
2523 67265 // dark surge 1
2524 }, [](SpellInfo* spellInfo)
2525 {
2526 spellInfo->ExcludeTargetAuraSpell = 67176;
2527 });
2528
2530 67282 // dark 2
2531 }, [](SpellInfo* spellInfo)
2532 {
2533 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2534 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2535 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2536 spellInfo->Effects[EFFECT_1].Effect = 0;
2537 spellInfo->Effects[EFFECT_2].Effect = 0;
2538 });
2539
2541 67266 // dark surge 2
2542 }, [](SpellInfo* spellInfo)
2543 {
2544 spellInfo->ExcludeTargetAuraSpell = 67177;
2545 });
2546
2548 67283 // dark 3
2549 }, [](SpellInfo* spellInfo)
2550 {
2551 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2552 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2553 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2554 spellInfo->Effects[EFFECT_1].Effect = 0;
2555 spellInfo->Effects[EFFECT_2].Effect = 0;
2556 });
2557
2559 67267 // dark surge 3
2560 }, [](SpellInfo* spellInfo)
2561 {
2562 spellInfo->ExcludeTargetAuraSpell = 67178;
2563 });
2564
2565 // Trial of the Crusader, Twin Valkyr, Twin's Pact
2566 ApplySpellFix({ 65875, 67303, 67304, 67305, 65876, 67306, 67307, 67308 }, [](SpellInfo* spellInfo)
2567 {
2568 spellInfo->Effects[EFFECT_1].Effect = 0;
2569 spellInfo->Effects[EFFECT_2].Effect = 0;
2570 });
2571
2572 // Trial of the Crusader, Anub'arak, Emerge
2573 ApplySpellFix({ 65982 }, [](SpellInfo* spellInfo)
2574 {
2575 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_WHILE_STUNNED;
2576 });
2577
2578 // Trial of the Crusader, Anub'arak, Penetrating Cold
2579 ApplySpellFix({ 66013, 67700, 68509, 68510 }, [](SpellInfo* spellInfo)
2580 {
2581 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
2582 });
2583
2584 // Trial of the Crusader, Anub'arak, Shadow Strike
2585 ApplySpellFix({ 66134 }, [](SpellInfo* spellInfo)
2586 {
2587 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
2588 spellInfo->Effects[EFFECT_0].Effect = 0;
2589 });
2590
2591 // Trial of the Crusader, Anub'arak, Pursuing Spikes
2592 ApplySpellFix({ 65920, 65922, 65923 }, [](SpellInfo* spellInfo)
2593 {
2594 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PERIODIC_DUMMY;
2595 //spellInfo->EffectTriggerSpell[0] = 0;
2596 });
2597
2598 // Trial of the Crusader, Anub'arak, Summon Scarab
2599 ApplySpellFix({ 66339 }, [](SpellInfo* spellInfo)
2600 {
2601 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(35);
2602 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
2603 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2604 });
2605
2606 // Trial of the Crusader, Anub'arak, Achievements: The Traitor King
2608 68186, // Anub'arak Scarab Achievement 10
2609 68515 // Anub'arak Scarab Achievement 25
2610 }, [](SpellInfo* spellInfo)
2611 {
2612 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2613 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
2614 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD;
2615 });
2616
2617 // Trial of the Crusader, Anub'arak, Spider Frenzy
2618 ApplySpellFix({ 66129 }, [](SpellInfo* spellInfo)
2619 {
2620 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
2621 });
2622
2623 // Soul Sickness
2624 ApplySpellFix({ 69131 }, [](SpellInfo* spellInfo)
2625 {
2626 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PERIODIC_TRIGGER_SPELL;
2627 spellInfo->Effects[EFFECT_0].Amplitude = 8000;
2628 spellInfo->Effects[EFFECT_0].TriggerSpell = 69133;
2629 });
2630
2631 // Phantom Blast
2632 ApplySpellFix({ 68982, 70322 }, [](SpellInfo* spellInfo)
2633 {
2634 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
2635 });
2636
2637 // Empowered Blizzard
2638 ApplySpellFix({ 70131 }, [](SpellInfo* spellInfo)
2639 {
2640 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2641 });
2642
2643 // Ice Lance Volley
2644 ApplySpellFix({ 70464 }, [](SpellInfo* spellInfo)
2645 {
2646 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2647 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2648 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_70_YARDS);
2649 });
2650
2652 70513, // Multi-Shot
2653 59514 // Shriek of the Highborne
2654 }, [](SpellInfo* spellInfo)
2655 {
2656 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CONE_ENTRY);
2657 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2658 });
2659
2660 // Icicle
2661 ApplySpellFix({ 69428, 69426 }, [](SpellInfo* spellInfo)
2662 {
2663 spellInfo->InterruptFlags = 0;
2664 spellInfo->AuraInterruptFlags = 0;
2665 spellInfo->ChannelInterruptFlags = 0;
2666 });
2667
2668 ApplySpellFix({ 70525, 70639 }, [](SpellInfo* spellInfo)
2669 {
2670 spellInfo->Effects[EFFECT_0].Effect = 0;
2671 spellInfo->Effects[EFFECT_1].Effect = 0;
2672 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2673 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2674 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_500_YARDS); // 500yd
2675 });
2676
2677 // Frost Nova
2678 ApplySpellFix({ 68198 }, [](SpellInfo* spellInfo)
2679 {
2680 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13);
2681 spellInfo->Targets |= TARGET_FLAG_DEST_LOCATION;
2682 });
2683
2684 // Blight
2685 ApplySpellFix({ 69604, 70286 }, [](SpellInfo* spellInfo)
2686 {
2687 spellInfo->MaxAffectedTargets = 1;
2688 spellInfo->AttributesEx3 |= (SPELL_ATTR3_ALWAYS_HIT | SPELL_ATTR3_ONLY_ON_PLAYER);
2689 });
2690
2691 // Chilling Wave
2692 ApplySpellFix({ 68778, 70333 }, [](SpellInfo* spellInfo)
2693 {
2694 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ENEMY);
2695 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2696 });
2697
2698 ApplySpellFix({ 68786, 70336 }, [](SpellInfo* spellInfo)
2699 {
2700 spellInfo->AttributesEx3 |= (SPELL_ATTR3_ALWAYS_HIT | SPELL_ATTR3_ONLY_ON_PLAYER);
2701 spellInfo->Effects[EFFECT_2].Effect = SPELL_EFFECT_DUMMY;
2702 });
2703
2704 // Pursuit
2705 ApplySpellFix({ 68987 }, [](SpellInfo* spellInfo)
2706 {
2707 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2708 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2709 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2710 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
2711 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
2712 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo();
2713 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100yd
2714 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
2715 });
2716
2717 ApplySpellFix({ 69029, 70850 }, [](SpellInfo* spellInfo)
2718 {
2719 spellInfo->Effects[EFFECT_2].Effect = 0;
2720 });
2721
2722 // Explosive Barrage
2723 ApplySpellFix({ 69263 }, [](SpellInfo* spellInfo)
2724 {
2725 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_MOD_STUN;
2726 });
2727
2728 // Overlord's Brand
2729 ApplySpellFix({ 69172 }, [](SpellInfo* spellInfo)
2730 {
2731 spellInfo->ProcFlags = DONE_HIT_PROC_FLAG_MASK & ~PROC_FLAG_DONE_PERIODIC;
2732 spellInfo->ProcChance = 100;
2733 });
2734
2735 // Icy Blast
2736 ApplySpellFix({ 69232 }, [](SpellInfo* spellInfo)
2737 {
2738 spellInfo->Effects[EFFECT_1].TriggerSpell = 69238;
2739 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2740 });
2741
2742 ApplySpellFix({ 69233, 69646 }, [](SpellInfo* spellInfo)
2743 {
2744 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2745 });
2746
2747 ApplySpellFix({ 69238, 69628 }, [](SpellInfo* spellInfo)
2748 {
2749 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2750 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_DEST_DYNOBJ_NONE);
2751 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2752 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_DEST_DYNOBJ_NONE);
2753 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2754 });
2755
2756 // Hoarfrost
2757 ApplySpellFix({ 69246, 69245, 69645 }, [](SpellInfo* spellInfo)
2758 {
2759 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2760 });
2761
2762 // Devour Humanoid
2763 ApplySpellFix({ 69503 }, [](SpellInfo* spellInfo)
2764 {
2765 spellInfo->ChannelInterruptFlags |= 0;
2766 spellInfo->AuraInterruptFlags = AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING;
2767 });
2768
2769 // Falric: Defiling Horror
2770 ApplySpellFix({ 72435, 72452 }, [](SpellInfo* spellInfo)
2771 {
2772 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
2773 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
2774 });
2775
2776 // Frostsworn General - Throw Shield
2777 ApplySpellFix({ 69222, 73076 }, [](SpellInfo* spellInfo)
2778 {
2779 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
2780 });
2781
2782 // Halls of Reflection Clone
2783 ApplySpellFix({ 69828 }, [](SpellInfo* spellInfo)
2784 {
2785 spellInfo->Effects[EFFECT_1].Effect = 0;
2786 spellInfo->Effects[EFFECT_2].Effect = 0;
2787 });
2788
2789 // Summon Ice Wall
2790 ApplySpellFix({ 69768 }, [](SpellInfo* spellInfo)
2791 {
2792 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2793 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL;
2794 });
2795
2796 ApplySpellFix({ 69767 }, [](SpellInfo* spellInfo)
2797 {
2798 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ANY);
2799 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2800 });
2801
2802 // Essence of the Captured
2803 ApplySpellFix({ 73035, 70719 }, [](SpellInfo* spellInfo)
2804 {
2805 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13);
2806 });
2807
2808 // Achievement Check
2809 ApplySpellFix({ 72830 }, [](SpellInfo* spellInfo)
2810 {
2811 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
2812 });
2813
2815 70781, // Light's Hammer Teleport
2816 70856, // Oratory of the Damned Teleport
2817 70857, // Rampart of Skulls Teleport
2818 70858, // Deathbringer's Rise Teleport
2819 70859, // Upper Spire Teleport
2820 70860, // Frozen Throne Teleport
2821 70861 // Sindragosa's Lair Teleport
2822 }, [](SpellInfo* spellInfo)
2823 {
2824 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2825 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2826 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB); // this target is for SPELL_EFFECT_TELEPORT_UNITS
2827 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
2828 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2829 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo();
2830 });
2831
2833 70960, // Bone Flurry
2834 71258 // Adrenaline Rush (Ymirjar Battle-Maiden)
2835 }, [](SpellInfo* spellInfo)
2836 {
2837 spellInfo->AttributesEx &= ~SPELL_ATTR1_IS_SELF_CHANNELED;
2838 });
2839
2840 // Saber Lash (Lord Marrowgar)
2841 ApplySpellFix({ 69055, 70814 }, [](SpellInfo* spellInfo)
2842 {
2843 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_5_YARDS); // 5yd
2844 });
2845
2846 // Impaled (Lord Marrowgar)
2847 ApplySpellFix({ 69065 }, [](SpellInfo* spellInfo)
2848 {
2849 spellInfo->Effects[EFFECT_0].Effect = 0; // remove stun so Dispersion can be used
2850 });
2851
2852 // Cold Flame (Lord Marrowgar)
2853 ApplySpellFix({ 72701, 72702, 72703, 72704 }, [](SpellInfo* spellInfo)
2854 {
2855 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
2856 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2857 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
2858 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(9); // 30 secs instead of 12, need him for longer, but will stop his actions after 12 secs
2859 });
2860
2861 ApplySpellFix({ 69138 }, [](SpellInfo* spellInfo)
2862 {
2863 spellInfo->Effects[EFFECT_0].Effect = 0;
2864 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2865 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(9); // 30 secs instead of 12, need him for longer, but will stop his actions after 12 secs
2866 });
2867
2868 ApplySpellFix({ 69146, 70823, 70824, 70825 }, [](SpellInfo* spellInfo)
2869 {
2870 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS); // 3yd instead of 5yd
2871 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
2872 });
2873
2874 // Dark Martyrdom (Lady Deathwhisper)
2875 ApplySpellFix({ 70897 }, [](SpellInfo* spellInfo)
2876 {
2877 spellInfo->AttributesEx2 |= SPELL_ATTR2_ALLOW_DEAD_TARGET;
2878 });
2879
2881 69075, // Bone Storm (Lord Marrowgar)
2882 70834, // Bone Storm (Lord Marrowgar)
2883 70835, // Bone Storm (Lord Marrowgar)
2884 70836, // Bone Storm (Lord Marrowgar)
2885 72378, // Blood Nova (Deathbringer Saurfang)
2886 73058, // Blood Nova (Deathbringer Saurfang)
2887 72769, // Scent of Blood (Deathbringer Saurfang)
2888 72385, // Boiling Blood (Deathbringer Saurfang)
2889 72441, // Boiling Blood (Deathbringer Saurfang)
2890 72442, // Boiling Blood (Deathbringer Saurfang)
2891 72443, // Boiling Blood (Deathbringer Saurfang)
2892 71160, // Plague Stench (Stinky)
2893 71161, // Plague Stench (Stinky)
2894 71123, // Decimate (Stinky & Precious)
2895 71464 // Divine Surge (Sister Svalna)
2896 }, [](SpellInfo* spellInfo)
2897 {
2898 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
2899 });
2900
2901 // Shadow's Fate
2902 ApplySpellFix({ 71169 }, [](SpellInfo* spellInfo)
2903 {
2904 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
2905 });
2906
2907 // Lock Players and Tap Chest
2908 ApplySpellFix({ 72347 }, [](SpellInfo* spellInfo)
2909 {
2910 spellInfo->AttributesEx3 &= ~SPELL_ATTR3_SUPRESS_TARGET_PROCS;
2911 });
2912
2913 // Award Reputation - Boss Kill
2914 ApplySpellFix({ 73843, 73844, 73845, 73846 }, [](SpellInfo* spellInfo)
2915 {
2916 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS);
2917 });
2918
2919 // Death Plague (Rotting Frost Giant)
2920 ApplySpellFix({ 72864 }, [](SpellInfo* spellInfo)
2921 {
2922 spellInfo->ExcludeTargetAuraSpell = 0;
2923 });
2924
2925 // Gunship Battle, spell Below Zero
2926 ApplySpellFix({ 69705 }, [](SpellInfo* spellInfo)
2927 {
2928 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
2929 });
2930
2931 // Resistant Skin (Deathbringer Saurfang adds)
2932 ApplySpellFix({ 72723 }, [](SpellInfo* spellInfo)
2933 {
2934 // this spell initially granted Shadow damage immunity, however it was removed but the data was left in client
2935 spellInfo->Effects[EFFECT_2].Effect = 0;
2936 });
2937
2938 // Mark of the Fallen Champion (Deathbringer Saurfang)
2939 ApplySpellFix({ 72255, 72444, 72445, 72446 }, [](SpellInfo* spellInfo)
2940 {
2941 // Patch 3.3.2 (2010-01-02): Deathbringer Saurfang will no longer gain blood power from Mark of the Fallen Champion.
2942 // prevented in script, effect needed for Prayer of Mending
2943 spellInfo->AttributesEx3 &= ~SPELL_ATTR3_SUPRESS_CASTER_PROCS;
2944 });
2945
2946 // Coldflame Jets (Traps after Saurfang)
2947 ApplySpellFix({ 70460 }, [](SpellInfo* spellInfo)
2948 {
2949 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(1); // 10 seconds
2950 });
2951
2953 70461, // Coldflame Jets (Traps after Saurfang)
2954 71289 // Dominate Mind (Lady Deathwhisper)
2955 }, [](SpellInfo* spellInfo)
2956 {
2957 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2958 });
2959
2960 // Severed Essence (Val'kyr Herald)
2961 ApplySpellFix({ 71906, 71942 }, [](SpellInfo* spellInfo)
2962 {
2963 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
2964 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2965 spellInfo->Effects[EFFECT_1].Effect = 0;
2966 });
2967
2969 71159, // Awaken Plagued Zombies (Precious)
2970 71302 // Awaken Ymirjar Fallen (Ymirjar Deathbringer)
2971 }, [](SpellInfo* spellInfo)
2972 {
2973 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21);
2974 });
2975
2976 // Blood Prince Council, Invocation of Blood
2977 ApplySpellFix({ 70981, 70982, 70952 }, [](SpellInfo* spellInfo)
2978 {
2979 spellInfo->Effects[EFFECT_0].Effect = 0; // clear share health aura
2980 });
2981
2982 // Ymirjar Frostbinder, Frozen Orb
2983 ApplySpellFix({ 71274 }, [](SpellInfo* spellInfo)
2984 {
2985 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2986 });
2987
2988 // Ooze Flood (Rotface)
2989 ApplySpellFix({ 69783, 69797, 69799, 69802 }, [](SpellInfo* spellInfo)
2990 {
2991 spellInfo->AttributesEx |= SPELL_ATTR1_EXCLUDE_CASTER;
2992 });
2993
2994 // Volatile Ooze Beam Protection
2995 ApplySpellFix({ 70530 }, [](SpellInfo* spellInfo)
2996 {
2997 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AURA; // blizzard typo, 65 instead of 6, aura itself is defined (dummy)
2998 });
2999
3000 // Professor Putricide, Gaseous Bloat (Orange Ooze Channel)
3001 ApplySpellFix({ 70672, 72455, 72832, 72833 }, [](SpellInfo* spellInfo)
3002 {
3003 // copied attributes from Green Ooze Channel
3004 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
3005 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
3006 });
3007
3009 71412, // Green Ooze Summon (Professor Putricide)
3010 71415 // Orange Ooze Summon (Professor Putricide)
3011 }, [](SpellInfo* spellInfo)
3012 {
3013 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3014 });
3015
3017 71621, // Create Concoction (Professor Putricide)
3018 72850,
3019 72851,
3020 72852,
3021 71893, // Guzzle Potions (Professor Putricide)
3022 73120,
3023 73121,
3024 73122
3025 }, [](SpellInfo* spellInfo)
3026 {
3027 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(15); // 4 sec
3028 });
3029
3030 // Mutated Plague (Professor Putricide)
3031 ApplySpellFix({ 72454, 72464, 72506, 72507 }, [](SpellInfo* spellInfo)
3032 {
3033 spellInfo->AttributesEx4 |= SPELL_ATTR4_NO_CAST_LOG;
3034 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3035 });
3036
3037 // Unbound Plague (Professor Putricide) (needs target selection script)
3038 ApplySpellFix({ 70911, 72854, 72855, 72856 }, [](SpellInfo* spellInfo)
3039 {
3040 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
3041 });
3042
3043 // Mutated Transformation (Professor Putricide)
3044 ApplySpellFix({ 70402, 72511, 72512, 72513 }, [](SpellInfo* spellInfo)
3045 {
3046 spellInfo->AttributesEx2 |= SPELL_ATTR2_CANT_CRIT;
3047 });
3048
3049 // Empowered Flare (Blood Prince Council)
3050 ApplySpellFix({ 71708, 72785, 72786, 72787 }, [](SpellInfo* spellInfo)
3051 {
3052 spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_MODIFIERS;
3053 });
3054
3056 71518, // Unholy Infusion Quest Credit (Professor Putricide)
3057 72934, // Blood Infusion Quest Credit (Blood-Queen Lana'thel)
3058 72289 // Frost Infusion Quest Credit (Sindragosa)
3059 }, [](SpellInfo* spellInfo)
3060 {
3061 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // another missing radius
3062 });
3063
3064 // Swarming Shadows
3065 ApplySpellFix({ 71266, 72890 }, [](SpellInfo* spellInfo)
3066 {
3067 spellInfo->AreaGroupId = 0; // originally, these require area 4522, which is... outside of Icecrown Citadel
3068 });
3069
3071 71301, // Summon Dream Portal (Valithria Dreamwalker)
3072 71977 // Summon Nightmare Portal (Valithria Dreamwalker)
3073 }, [](SpellInfo* spellInfo)
3074 {
3075 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
3076 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
3077 });
3078
3079 // Column of Frost (visual marker)
3080 ApplySpellFix({ 70715 }, [](SpellInfo* spellInfo)
3081 {
3082 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(32); // 6 seconds (missing)
3083 });
3084
3085 // Mana Void (periodic aura)
3086 ApplySpellFix({ 71085 }, [](SpellInfo* spellInfo)
3087 {
3088 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(9); // 30 seconds (missing)
3089 });
3090
3091 // Summon Suppressor (needs target selection script)
3092 ApplySpellFix({ 70936 }, [](SpellInfo* spellInfo)
3093 {
3094 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3095 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
3096 });
3097
3098 // Corruption
3099 ApplySpellFix({ 70602 }, [](SpellInfo* spellInfo)
3100 {
3101 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
3102 });
3103
3105 72706, // Achievement Check (Valithria Dreamwalker)
3106 71357 // Order Whelp
3107 }, [](SpellInfo* spellInfo)
3108 {
3109 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3110 });
3111
3112 // Sindragosa's Fury
3113 ApplySpellFix({ 70598 }, [](SpellInfo* spellInfo)
3114 {
3115 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
3116 });
3117
3118 // Tail Smash (Sindragosa)
3119 ApplySpellFix({ 71077 }, [](SpellInfo* spellInfo)
3120 {
3121 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER_BACK);
3122 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_DEST_AREA_ENEMY);
3123 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER_BACK);
3124 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_DEST_AREA_ENEMY);
3125 });
3126
3127 // Frost Bomb
3128 ApplySpellFix({ 69846 }, [](SpellInfo* spellInfo)
3129 {
3130 spellInfo->Speed = 0.0f; // This spell's summon happens instantly
3131 });
3132
3133 // Mystic Buffet (Sindragosa)
3134 ApplySpellFix({ 70127, 72528, 72529, 72530 }, [](SpellInfo* spellInfo)
3135 {
3136 spellInfo->Effects[EFFECT_1].Effect = 0; // remove obsolete spell effect with no targets
3137 });
3138
3139 // Sindragosa, Frost Aura
3140 ApplySpellFix({ 70084, 71050, 71051, 71052 }, [](SpellInfo* spellInfo)
3141 {
3142 spellInfo->Attributes &= ~SPELL_ATTR0_NO_IMMUNITIES;
3143 });
3144
3145 // Ice Lock
3146 ApplySpellFix({ 71614 }, [](SpellInfo* spellInfo)
3147 {
3148 spellInfo->Mechanic = MECHANIC_STUN;
3149 });
3150
3151 // Lich King, Infest
3152 ApplySpellFix({ 70541, 73779, 73780, 73781 }, [](SpellInfo* spellInfo)
3153 {
3154 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3155 });
3156
3157 // Lich King, Necrotic Plague
3158 ApplySpellFix({ 70337, 73912, 73913, 73914, 70338, 73785, 73786, 73787 }, [](SpellInfo* spellInfo)
3159 {
3160 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
3161 });
3162
3164 69099, // Ice Pulse 10n
3165 73776, // Ice Pulse 25n
3166 73777, // Ice Pulse 10h
3167 73778 // Ice Pulse 25h
3168 }, [](SpellInfo* spellInfo)
3169 {
3170 spellInfo->AttributesEx2 |= SPELL_ATTR2_CANT_CRIT;
3171 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
3172 });
3173
3174 // Fury of Frostmourne
3175 ApplySpellFix({ 72350 }, [](SpellInfo* spellInfo)
3176 {
3177 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3178 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3179 });
3180
3182 72351, // Fury of Frostmourne
3183 72431, // Jump (removes Fury of Frostmourne debuff)
3184 72429, // Mass Resurrection
3185 73159 // Play Movie
3186 }, [](SpellInfo* spellInfo)
3187 {
3188 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3189 });
3190
3191 // Raise Dead
3192 ApplySpellFix({ 72376 }, [](SpellInfo* spellInfo)
3193 {
3194 spellInfo->MaxAffectedTargets = 4;
3195 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3196 });
3197
3198 // Jump
3199 ApplySpellFix({ 71809 }, [](SpellInfo* spellInfo)
3200 {
3201 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(5); // 40yd
3202 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
3203 spellInfo->Effects[EFFECT_0].MiscValue = 190;
3204 });
3205
3206 // Broken Frostmourne
3207 ApplySpellFix({ 72405 }, [](SpellInfo* spellInfo)
3208 {
3209 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3210 });
3211
3212 // Summon Shadow Trap
3213 ApplySpellFix({ 73540 }, [](SpellInfo* spellInfo)
3214 {
3215 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(3); // 60 seconds
3216 });
3217
3218 // Shadow Trap (visual)
3219 ApplySpellFix({ 73530 }, [](SpellInfo* spellInfo)
3220 {
3221 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(28); // 5 seconds
3222 });
3223
3224 // Shadow Trap
3225 ApplySpellFix({ 73529 }, [](SpellInfo* spellInfo)
3226 {
3227 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
3228 });
3229
3230 // Shadow Trap (searcher)
3231 ApplySpellFix({ 74282 }, [](SpellInfo* spellInfo)
3232 {
3233 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS); // 3yd
3234 });
3235
3236 // Raging Spirit Visual
3237 ApplySpellFix({ 69198 }, [](SpellInfo* spellInfo)
3238 {
3239 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
3240 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3241 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
3242 });
3243
3244 // Defile
3245 ApplySpellFix({ 72762 }, [](SpellInfo* spellInfo)
3246 {
3247 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(559); // 53 seconds
3248 spellInfo->ExcludeCasterAuraSpell = 0;
3249 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
3251 });
3252
3253 // Defile
3254 ApplySpellFix({ 72743 }, [](SpellInfo* spellInfo)
3255 {
3256 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(22); // 45 seconds
3257 });
3258
3259 ApplySpellFix({ 72754, 73708, 73709, 73710 }, [](SpellInfo* spellInfo)
3260 {
3261 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3262 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3263 });
3264
3265 // Val'kyr Target Search
3266 ApplySpellFix({ 69030 }, [](SpellInfo* spellInfo)
3267 {
3268 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3269 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3270 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
3271 });
3272
3273 // Harvest Souls
3274 ApplySpellFix({ 73654, 74295, 74296, 74297 }, [](SpellInfo* spellInfo)
3275 {
3276 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3277 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3278 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3279 });
3280
3281 // Restore Soul
3282 ApplySpellFix({ 72595, 73650 }, [](SpellInfo* spellInfo)
3283 {
3284 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3285 });
3286
3287 // Kill Frostmourne Players
3288 ApplySpellFix({ 75127 }, [](SpellInfo* spellInfo)
3289 {
3290 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3291 });
3292
3293 // Harvest Soul
3294 ApplySpellFix({ 73655 }, [](SpellInfo* spellInfo)
3295 {
3296 spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_MODIFIERS;
3297 });
3298
3299 // Destroy Soul
3300 ApplySpellFix({ 74086 }, [](SpellInfo* spellInfo)
3301 {
3302 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3303 });
3304
3305 // Summon Spirit Bomb
3306 ApplySpellFix({ 74302, 74342 }, [](SpellInfo* spellInfo)
3307 {
3308 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3309 spellInfo->MaxAffectedTargets = 1;
3310 });
3311
3312 // Summon Spirit Bomb
3313 ApplySpellFix({ 74341, 74343 }, [](SpellInfo* spellInfo)
3314 {
3315 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3316 spellInfo->MaxAffectedTargets = 3;
3317 });
3318
3319 // Summon Spirit Bomb
3320 ApplySpellFix({ 73579 }, [](SpellInfo* spellInfo)
3321 {
3322 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_25_YARDS); // 25yd
3323 });
3324
3325 // Trigger Vile Spirit (Inside, Heroic)
3326 ApplySpellFix({ 73582 }, [](SpellInfo* spellInfo)
3327 {
3328 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3329 });
3330
3331 // Scale Aura (used during Dominate Mind from Lady Deathwhisper)
3332 ApplySpellFix({ 73261 }, [](SpellInfo* spellInfo)
3333 {
3334 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
3335 });
3336
3337 // Leap to a Random Location
3338 ApplySpellFix({ 70485 }, [](SpellInfo* spellInfo)
3339 {
3340 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100yd
3341 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS);
3342 spellInfo->Effects[EFFECT_0].MiscValue = 100;
3343 });
3344
3345 // Empowered Blood
3346 ApplySpellFix({ 70227, 70232 }, [](SpellInfo* spellInfo)
3347 {
3348 spellInfo->AreaGroupId = 2452; // Whole icc instead of Crimson Halls only, remove when area calculation is fixed
3349 });
3350
3351 ApplySpellFix({ 74509 }, [](SpellInfo* spellInfo)
3352 {
3353 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd
3354 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd
3355 });
3356
3357 // Rallying Shout
3358 ApplySpellFix({ 75414 }, [](SpellInfo* spellInfo)
3359 {
3360 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd
3361 });
3362
3363 // Barrier Channel
3364 ApplySpellFix({ 76221 }, [](SpellInfo* spellInfo)
3365 {
3366 spellInfo->ChannelInterruptFlags &= ~(AURA_INTERRUPT_FLAG_TURNING | AURA_INTERRUPT_FLAG_MOVE);
3367 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_NEARBY_ENTRY);
3368 });
3369
3370 // Intimidating Roar
3371 ApplySpellFix({ 74384 }, [](SpellInfo* spellInfo)
3372 {
3373 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3374 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3375 });
3376
3378 74562, // Fiery Combustion
3379 74792 // Soul Consumption
3380 }, [](SpellInfo* spellInfo)
3381 {
3382 spellInfo->AttributesEx |= SPELL_ATTR1_NO_REDIRECTION;
3383 });
3384
3385 // Combustion
3386 ApplySpellFix({ 75883, 75884 }, [](SpellInfo* spellInfo)
3387 {
3388 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_6_YARDS); // 6yd
3389 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_6_YARDS); // 6yd
3390 });
3391
3392 // Consumption
3393 ApplySpellFix({ 75875, 75876 }, [](SpellInfo* spellInfo)
3394 {
3395 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_6_YARDS); // 6yd
3396 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_6_YARDS); // 6yd
3397 spellInfo->Effects[EFFECT_0].Mechanic = MECHANIC_NONE;
3398 spellInfo->Effects[EFFECT_1].Mechanic = MECHANIC_SNARE;
3399 });
3400
3401 // Soul Consumption
3402 ApplySpellFix({ 74799 }, [](SpellInfo* spellInfo)
3403 {
3404 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_12_YARDS); // 12yd
3405 });
3406
3407 // Twilight Cutter
3408 ApplySpellFix({ 74769, 77844, 77845, 77846 }, [](SpellInfo* spellInfo)
3409 {
3410 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3411 });
3412
3413 // Twilight Mending
3414 ApplySpellFix({ 75509 }, [](SpellInfo* spellInfo)
3415 {
3416 spellInfo->AttributesEx6 |= SPELL_ATTR6_IGNORE_PHASE_SHIFT;
3417 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3418 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3419 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3420 });
3421
3422 // Meteor Strike
3423 ApplySpellFix({ 74637 }, [](SpellInfo* spellInfo)
3424 {
3425 spellInfo->Speed = 0;
3426 });
3427
3428 //Blazing Aura
3429 ApplySpellFix({ 75885, 75886 }, [](SpellInfo* spellInfo)
3430 {
3431 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
3432 });
3433
3435 75952, //Meteor Strike
3436 74629 //Combustion Periodic
3437 }, [](SpellInfo* spellInfo)
3438 {
3439 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
3440 });
3441
3442 // Going Bearback
3443 ApplySpellFix({ 54897 }, [](SpellInfo* spellInfo)
3444 {
3445 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_DUMMY;
3446 spellInfo->Effects[EFFECT_1].RadiusEntry = spellInfo->Effects[EFFECT_0].RadiusEntry;
3447 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_DEST_AREA_ENTRY);
3448 });
3449
3450 // Still At It
3451 ApplySpellFix({ 51931, 51932, 51933 }, [](SpellInfo* spellInfo)
3452 {
3453 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(38);
3454 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
3455 });
3456
3457 // Rallying the Troops
3458 ApplySpellFix({ 47394 }, [](SpellInfo* spellInfo)
3459 {
3460 spellInfo->ExcludeTargetAuraSpell = 47394;
3461 });
3462
3463 // A Tangled Skein
3464 ApplySpellFix({ 51165, 51173 }, [](SpellInfo* spellInfo)
3465 {
3466 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_TARGET_PROCS;
3467 });
3468
3470 69563, // A Cloudlet of Classy Cologne
3471 69445, // A Perfect Puff of Perfume
3472 69489 // Bonbon Blitz
3473 }, [](SpellInfo* spellInfo)
3474 {
3475 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
3476 });
3477
3478 // Control
3479 ApplySpellFix({ 30790 }, [](SpellInfo* spellInfo)
3480 {
3481 spellInfo->Effects[EFFECT_1].MiscValue = 0;
3482 });
3483
3484 // Reclusive Runemaster
3485 ApplySpellFix({ 48028 }, [](SpellInfo* spellInfo)
3486 {
3487 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
3488 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
3489 });
3490
3491 // Mastery of
3492 ApplySpellFix({ 65147 }, [](SpellInfo* spellInfo)
3493 {
3494 spellInfo->CategoryEntry = sSpellCategoryStore.LookupEntry(1244);
3495 spellInfo->CategoryRecoveryTime = 1500;
3496 });
3497
3498 // Weakness to Lightning
3499 ApplySpellFix({ 46432 }, [](SpellInfo* spellInfo)
3500 {
3501 spellInfo->AttributesEx3 &= ~SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
3502 });
3503
3504 // Wrangle Some Aether Rays!
3505 ApplySpellFix({ 40856 }, [](SpellInfo* spellInfo)
3506 {
3507 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(27); // 3000ms
3508 });
3509
3510 // The Black Knight's Orders
3511 ApplySpellFix({ 63163 }, [](SpellInfo* spellInfo)
3512 {
3513 spellInfo->Effects[EFFECT_0].BasePoints = 52390;
3514 });
3515
3516 // The Warp Rifts
3517 ApplySpellFix({ 34888 }, [](SpellInfo* spellInfo)
3518 {
3519 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(5); // 300 secs
3520 });
3521
3522 // The Smallest Creatures
3523 ApplySpellFix({ 38544 }, [](SpellInfo* spellInfo)
3524 {
3525 spellInfo->Effects[EFFECT_0].MiscValueB = 427;
3526 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(1);
3527 spellInfo->Effects[EFFECT_1].Effect = 0;
3528 });
3529
3530 // Ridding the red rocket
3531 ApplySpellFix({ 49177 }, [](SpellInfo* spellInfo)
3532 {
3533 spellInfo->Effects[EFFECT_0].BasePoints = 1; // corrects seat id (points - 1 = seatId)
3534 });
3535
3536 // Jormungar Strike
3537 ApplySpellFix({ 56513 }, [](SpellInfo* spellInfo)
3538 {
3539 spellInfo->RecoveryTime = 2000;
3540 });
3541
3543 37851, // Tag Greater Felfire Diemetradon
3544 37918 // Arcano-pince
3545 }, [](SpellInfo* spellInfo)
3546 {
3547 spellInfo->RecoveryTime = 3000;
3548 });
3549
3551 54997, // Cast Net (tooltip says 10s but sniffs say 6s)
3552 56524 // Acid Breath
3553 }, [](SpellInfo* spellInfo)
3554 {
3555 spellInfo->RecoveryTime = 6000;
3556 });
3557
3559 47911, // EMP
3560 48620, // Wing Buffet
3561 51752 // Stampy's Stompy-Stomp
3562 }, [](SpellInfo* spellInfo)
3563 {
3564 spellInfo->RecoveryTime = 10000;
3565 });
3566
3568 37727, // Touch of Darkness
3569 54996 // Ice Slick (tooltip says 20s but sniffs say 12s)
3570 }, [](SpellInfo* spellInfo)
3571 {
3572 spellInfo->RecoveryTime = 12000;
3573 });
3574
3575 // Signal Helmet to Attack
3576 ApplySpellFix({ 51748 }, [](SpellInfo* spellInfo)
3577 {
3578 spellInfo->RecoveryTime = 15000;
3579 });
3580
3582 51756, // Charge
3583 37919, //Arcano-dismantle
3584 37917 //Arcano-Cloak
3585 }, [](SpellInfo* spellInfo)
3586 {
3587 spellInfo->RecoveryTime = 20000;
3588 });
3589
3590 // Kaw the Mammoth Destroyer
3591 ApplySpellFix({ 46260 }, [](SpellInfo* spellInfo)
3592 {
3593 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3594 });
3595
3596 // That's Abominable
3597 ApplySpellFix({ 59565 }, [](SpellInfo* spellInfo)
3598 {
3599 spellInfo->Effects[EFFECT_0].MiscValueB = 1721; // controlable guardian
3600 });
3601
3602 // Investigate the Blue Recluse (1920)
3603 // Investigate the Alchemist Shop (1960)
3604 ApplySpellFix({ 9095 }, [](SpellInfo* spellInfo)
3605 {
3606 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_DUMMY;
3607 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
3608 });
3609
3610 // Gauging the Resonant Frequency (10594)
3611 ApplySpellFix({ 37390 }, [](SpellInfo* spellInfo)
3612 {
3613 spellInfo->Effects[EFFECT_0].MiscValueB = 181;
3614 });
3615
3616 // Where in the World is Hemet Nesingwary? (12521)
3617 ApplySpellFix({ 50860 }, [](SpellInfo* spellInfo)
3618 {
3619 spellInfo->Effects[EFFECT_0].BasePoints = 50860;
3620 });
3621
3622 ApplySpellFix({ 50861 }, [](SpellInfo* spellInfo)
3623 {
3624 spellInfo->Effects[EFFECT_0].BasePoints = 0;
3625 });
3626
3627 // Riding Jokkum
3628 ApplySpellFix({ 56606 }, [](SpellInfo* spellInfo)
3629 {
3630 spellInfo->Effects[EFFECT_0].BasePoints = 1;
3631 });
3632
3633 // Blightbeasts be Damned! (12072)
3634 ApplySpellFix({ 47424 }, [](SpellInfo* spellInfo)
3635 {
3636 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_NOT_ABOVEWATER;
3637 });
3638
3639 // Dark Horizon (12664), Reunited (12663)
3640 ApplySpellFix({ 52190 }, [](SpellInfo* spellInfo)
3641 {
3642 spellInfo->Effects[EFFECT_0].BasePoints = 52391 - 1;
3643 });
3644
3645 // The Sum is Greater than the Parts (13043) - Chained Grip
3646 ApplySpellFix({ 60540 }, [](SpellInfo* spellInfo)
3647 {
3648 spellInfo->Effects[EFFECT_0].MiscValue = 300;
3649 });
3650
3651 // Not a Bug (13342)
3652 ApplySpellFix({ 60531 }, [](SpellInfo* spellInfo)
3653 {
3654 spellInfo->AttributesEx2 |= SPELL_ATTR2_ALLOW_DEAD_TARGET;
3655 });
3656
3657 // Frankly, It Makes No Sense... (10672)
3658 ApplySpellFix({ 37851 }, [](SpellInfo* spellInfo)
3659 {
3660 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_TARGET_PROCS;
3661 });
3662
3663 // Honor Challenge (12939)
3664 ApplySpellFix({ 21855 }, [](SpellInfo* spellInfo)
3665 {
3666 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_TARGET_PROCS;
3667 });
3668
3669 // Convocation at Zol'Heb (12730)
3670 ApplySpellFix({ 52956 }, [](SpellInfo* spellInfo)
3671 {
3672 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_DEST_AREA_ENTRY);
3673 });
3674
3675 // Mangletooth
3677 7764, // Wisdom of Agamaggan
3678 10767, // Rising Spirit
3679 16610, // Razorhide
3680 16612, // Agamaggan's Strength
3681 16618, // Spirit of the Wind
3682 17013 // Agamaggan's Agility
3683 }, [](SpellInfo* spellInfo)
3684
3685 {
3686 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3687 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT;
3688 });
3689
3690 //Crushing the Crown
3691 ApplySpellFix({ 71024 }, [](SpellInfo* spellInfo)
3692 {
3693 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DYNOBJ_NONE);
3694 });
3695
3696 // Battle for the Undercity
3698 59892 // Cyclone fall
3699 }, [](SpellInfo* spellInfo)
3700 {
3701 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AREA_AURA_FRIEND;
3702 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
3703 spellInfo->AttributesEx &= ~SPELL_ATTR0_NO_AURA_CANCEL;
3704 spellInfo->AttributesEx3 |= SPELL_ATTR3_ONLY_ON_PLAYER;
3705 });
3706
3707 // enchant Lightweave Embroidery
3708 ApplySpellFix({ 55637 }, [](SpellInfo* spellInfo)
3709 {
3710 spellInfo->Effects[EFFECT_1].MiscValue = 126;
3711 });
3712
3714 47977, // Magic Broom
3715 65917 // Magic Rooster
3716 }, [](SpellInfo* spellInfo)
3717 {
3718 // First two effects apply auras, which shouldn't be there
3719 // due to NO_TARGET applying aura on current caster (core bug)
3720 // Just wipe effect data, to mimic blizz-behavior
3721 spellInfo->Effects[EFFECT_0].Effect = 0;
3722 spellInfo->Effects[EFFECT_1].Effect = 0;
3723 });
3724
3725 // Titanium Seal of Dalaran, Toss your luck
3726 ApplySpellFix({ 60476 }, [](SpellInfo* spellInfo)
3727 {
3728 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
3729 });
3730
3731 // Mind Amplification Dish, change charm aura
3732 ApplySpellFix({ 26740 }, [](SpellInfo* spellInfo)
3733 {
3734 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_MOD_CHARM;
3735 });
3736
3737 // Persistent Shield
3738 ApplySpellFix({ 26467 }, [](SpellInfo* spellInfo)
3739 {
3740 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE;
3741 spellInfo->Effects[EFFECT_0].TriggerSpell = 26470;
3742 });
3743
3744 // Deadly Swiftness
3745 ApplySpellFix({ 31255 }, [](SpellInfo* spellInfo)
3746 {
3747 spellInfo->Effects[EFFECT_0].TriggerSpell = 22588;
3748 });
3749
3750 // Black Magic enchant
3751 ApplySpellFix({ 59630 }, [](SpellInfo* spellInfo)
3752 {
3753 spellInfo->Attributes |= SPELL_ATTR0_PASSIVE;
3754 });
3755
3756 // Precious's Ribbon
3757 ApplySpellFix({ 72968 }, [](SpellInfo* spellInfo)
3758 {
3759 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
3760 });
3761
3763 71646, // Item - Bauble of True Blood 10m
3764 71607, // Item - Bauble of True Blood 25m
3765 71610, // Item - Althor's Abacus trigger 10m
3766 71641 // Item - Althor's Abacus trigger 25m
3767 }, [](SpellInfo* spellInfo)
3768 {
3769 spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
3770 spellInfo->SpellLevel = 0;
3771 });
3772
3774 6789, // Warlock - Death Coil (Rank 1)
3775 17925, // Warlock - Death Coil (Rank 2)
3776 17926, // Warlock - Death Coil (Rank 3)
3777 27223, // Warlock - Death Coil (Rank 4)
3778 47859, // Warlock - Death Coil (Rank 5)
3779 71838, // Drain Life - Bryntroll Normal
3780 71839 // Drain Life - Bryntroll Heroic
3781 }, [](SpellInfo* spellInfo)
3782 {
3783 spellInfo->AttributesEx2 |= SPELL_ATTR2_CANT_CRIT;
3784 });
3785
3786 // Alchemist's Stone
3787 ApplySpellFix({ 17619 }, [](SpellInfo* spellInfo)
3788 {
3789 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
3790 });
3791
3792 // Stormchops
3793 ApplySpellFix({ 43730 }, [](SpellInfo* spellInfo)
3794 {
3795 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(1);
3796 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
3797 });
3798
3799 // Savory Deviate Delight (transformations), allow to mount while transformed
3800 ApplySpellFix({ 8219, 8220, 8221, 8222 }, [](SpellInfo* spellInfo)
3801 {
3802 spellInfo->Attributes &= ~SPELL_ATTR0_NO_IMMUNITIES;
3803 });
3804
3805 // Clamlette Magnifique
3806 ApplySpellFix({ 72623 }, [](SpellInfo* spellInfo)
3807 {
3808 spellInfo->Effects[EFFECT_0].BasePoints = spellInfo->Effects[EFFECT_1].BasePoints;
3809 });
3810
3811 // Compact Harvest Reaper
3812 ApplySpellFix({ 4078 }, [](SpellInfo* spellInfo)
3813 {
3814 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(6); // 10 minutes
3815 });
3816
3817 // Dragon Kite, Tuskarr Kite - Kite String
3818 ApplySpellFix({ 45192 }, [](SpellInfo* spellInfo)
3819 {
3820 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100yd
3821 });
3822
3823 // Frigid Frostling, Infrigidate
3824 ApplySpellFix({ 74960 }, [](SpellInfo* spellInfo)
3825 {
3826 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd
3827 });
3828
3829 // Apple Trap
3830 ApplySpellFix({ 43450 }, [](SpellInfo* spellInfo)
3831 {
3832 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
3833 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
3834 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_DUMMY;
3835 });
3836
3837 // Dark Iron Attack - spawn mole machine
3838 ApplySpellFix({ 43563 }, [](SpellInfo* spellInfo)
3839 {
3840 spellInfo->Effects[EFFECT_2].Effect = 0; // summon GO's manually
3841 });
3842
3843 // Throw Mug visual
3844 ApplySpellFix({ 42300 }, [](SpellInfo* spellInfo)
3845 {
3846 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3847 });
3848
3849 // Dark Iron knockback Aura
3850 ApplySpellFix({ 42299 }, [](SpellInfo* spellInfo)
3851 {
3852 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_DUMMY;
3853 spellInfo->Effects[EFFECT_0].MiscValue = 100;
3854 spellInfo->Effects[EFFECT_0].BasePoints = 79;
3855 });
3856
3857 // Chug and Chuck!
3858 ApplySpellFix({ 42436 }, [](SpellInfo* spellInfo)
3859 {
3860 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
3861 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
3862 spellInfo->MaxAffectedTargets = 0;
3863 spellInfo->ExcludeCasterAuraSpell = 42299;
3864 });
3865
3866 // Brewfest quests
3867 ApplySpellFix({ 47134, 51798 }, [](SpellInfo* spellInfo)
3868 {
3869 spellInfo->Effects[EFFECT_0].Effect = 0;
3870 });
3871
3872 // The Heart of The Storms (12998)
3873 ApplySpellFix({ 43528 }, [](SpellInfo* spellInfo)
3874 {
3875 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(18);
3876 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
3877 });
3878
3879 // Water splash
3880 ApplySpellFix({ 42348 }, [](SpellInfo* spellInfo)
3881 {
3882 spellInfo->Effects[EFFECT_0].Effect = 0;
3883 });
3884
3885 // Summon Lantersn
3886 ApplySpellFix({ 44255, 44231 }, [](SpellInfo* spellInfo)
3887 {
3888 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
3889 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
3890 });
3891
3892 // Throw Head Back
3893 ApplySpellFix({ 42401 }, [](SpellInfo* spellInfo)
3894 {
3895 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_NEARBY_ENTRY);
3896 });
3897
3898 // Food
3899 ApplySpellFix({ 65418 }, [](SpellInfo* spellInfo)
3900 {
3901 spellInfo->Effects[EFFECT_2].TriggerSpell = 65410;
3902 });
3903
3904 ApplySpellFix({ 65422 }, [](SpellInfo* spellInfo)
3905 {
3906 spellInfo->Effects[EFFECT_2].TriggerSpell = 65414;
3907 });
3908
3909 ApplySpellFix({ 65419 }, [](SpellInfo* spellInfo)
3910 {
3911 spellInfo->Effects[EFFECT_2].TriggerSpell = 65416;
3912 });
3913
3914 ApplySpellFix({ 65420 }, [](SpellInfo* spellInfo)
3915 {
3916 spellInfo->Effects[EFFECT_2].TriggerSpell = 65412;
3917 });
3918
3919 ApplySpellFix({ 65421 }, [](SpellInfo* spellInfo)
3920 {
3921 spellInfo->Effects[EFFECT_2].TriggerSpell = 65415;
3922 });
3923
3924 // Stamp Out Bonfire
3925 ApplySpellFix({ 45437 }, [](SpellInfo* spellInfo)
3926 {
3927 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_DUMMY;
3928 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_NEARBY_ENTRY);
3929 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3930 });
3931
3932 // Light Bonfire (DND)
3933 ApplySpellFix({ 29831 }, [](SpellInfo* spellInfo)
3934 {
3935 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3936 });
3937
3938 // Infernal
3939 ApplySpellFix({ 33240 }, [](SpellInfo* spellInfo)
3940 {
3941 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3942 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3943 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3944 });
3945
3947 47476, // Deathknight - Strangulate
3948 15487, // Priest - Silence
3949 5211, // Druid - Bash - R1
3950 6798, // Druid - Bash - R2
3951 8983 // Druid - Bash - R3
3952 }, [](SpellInfo* spellInfo)
3953 {
3954 spellInfo->AttributesEx7 |= SPELL_ATTR7_CAN_CAUSE_INTERRUPT;
3955 });
3956
3957 // Shadowmeld
3958 ApplySpellFix({ 58984 }, [](SpellInfo* spellInfo)
3959 {
3960 spellInfo->AttributesEx3 |= SPELL_ATTR3_ONLY_ON_PLAYER;
3961 });
3962
3963 // Flare activation speed
3964 ApplySpellFix({ 1543 }, [](SpellInfo* spellInfo)
3965 {
3966 spellInfo->Speed = 0.0f;
3967 });
3968
3969 // Light's Beacon
3970 ApplySpellFix({ 53651 }, [](SpellInfo* spellInfo)
3971 {
3972 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
3973 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3974 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
3975 });
3976
3977 // Shadow Hunter Vosh'gajin - Hex
3978 ApplySpellFix({ 16097 }, [](SpellInfo* spellInfo)
3979 {
3980 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(16);
3981 });
3982
3983 // Sacred Cleansing
3984 ApplySpellFix({ 53659 }, [](SpellInfo* spellInfo)
3985 {
3986 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(5); // 40yd
3987 });
3988
3989 // Silithyst
3990 ApplySpellFix({ 29519 }, [](SpellInfo* spellInfo)
3991 {
3992 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_MOD_DECREASE_SPEED;
3993 spellInfo->Effects[EFFECT_0].BasePoints = -25;
3994 });
3995
3996 // Focused Eyebeam Summon Trigger
3997 ApplySpellFix({ 63342 }, [](SpellInfo* spellInfo)
3998 {
3999 spellInfo->MaxAffectedTargets = 1;
4000 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
4001 });
4002
4003 // Luffa
4004 ApplySpellFix({ 23595 }, [](SpellInfo* spellInfo)
4005 {
4006 spellInfo->Effects[EFFECT_0].BasePoints = 1; // Remove only 1 bleed effect
4007 });
4008
4009 // Eye of Kilrogg Passive (DND)
4010 ApplySpellFix({ 2585 }, [](SpellInfo* spellInfo)
4011 {
4012 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE;
4013 });
4014
4015 // Nefarius Corruption
4016 ApplySpellFix({ 23642 }, [](SpellInfo* spellInfo)
4017 {
4018 spellInfo->MaxAffectedTargets = 1;
4019 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
4020 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
4021 });
4022
4023 // Conflagration, Horseman's Cleave
4024 ApplySpellFix({ 42380, 42587 }, [](SpellInfo* spellInfo)
4025 {
4026 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
4027 });
4028
4029 // Serverside - Summon Arcane Disruptor
4030 ApplySpellFix({ 49591 }, [](SpellInfo* spellInfo)
4031 {
4032 spellInfo->ProcChance = 101;
4033 spellInfo->Effects[EFFECT_1].Effect = 24;
4034 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(25);
4035 spellInfo->Effects[EFFECT_1].ItemType = 37888;
4036 });
4037
4038 // Serverside - Create Rocket Pack
4039 ApplySpellFix({ 70055 }, [](SpellInfo* spellInfo)
4040 {
4041 spellInfo->ProcChance = 101;
4042 spellInfo->Effects[EFFECT_1].Effect = 24;
4043 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(25);
4044 spellInfo->Effects[EFFECT_1].ItemType = 49278;
4045 });
4046
4047 // Ashenvale Outrunner Sneak
4048 // Stealth
4049 ApplySpellFix({ 20540, 32199 }, [](SpellInfo* spellInfo)
4050 {
4051 spellInfo->AuraInterruptFlags |= (AURA_INTERRUPT_FLAG_MELEE_ATTACK | AURA_INTERRUPT_FLAG_CAST);
4052 });
4053
4054 // Arcane Bolt
4055 ApplySpellFix({ 15979 }, [](SpellInfo* spellInfo)
4056 {
4057 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(3); // 20y
4058 });
4059
4060 // Mortal Shots
4061 ApplySpellFix({ 19485, 19487, 19488, 19489, 19490 }, [](SpellInfo* spellInfo)
4062 {
4063 spellInfo->Effects[EFFECT_0].SpellClassMask[0] |= 0x00004000;
4064 spellInfo->Effects[EFFECT_1].Effect = 0;
4065 });
4066
4067 // Item - Death Knight T9 Melee 4P Bonus
4068 // Item - Hunter T9 2P Bonus
4069 // Item - Paladin T9 Retribution 2P Bonus (Righteous Vengeance)
4070 ApplySpellFix({ 67118, 67150, 67188 }, [](SpellInfo* spellInfo)
4071 {
4072 spellInfo->Effects[EFFECT_1].Effect = 0;
4073 });
4074
4075 // Green Beam
4076 ApplySpellFix({31628, 31630, 31631}, [](SpellInfo* spellInfo)
4077 {
4078 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
4079 spellInfo->MaxAffectedTargets = 1;
4080 });
4081
4083 20271, 57774, // Judgement of Light
4084 20425, // Judgement of Command
4085 32220, // Judgement of Blood
4086 53407, // Judgement of Justice
4087 53408, // Judgement of Wisdom
4088 53725 // Judgement of the Martyr
4089 }, [](SpellInfo* spellInfo)
4090 {
4091 spellInfo->AttributesEx3 &= ~SPELL_ATTR3_SUPRESS_TARGET_PROCS;
4092 });
4093
4094 // Chaos Bolt Passive
4095 ApplySpellFix({ 58284 }, [](SpellInfo* spellInfo)
4096 {
4097 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
4098 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST;
4099 spellInfo->Effects[EFFECT_1].BasePoints = 100;
4100 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
4101 spellInfo->Effects[EFFECT_1].MiscValue = 127;
4102 spellInfo->Effects[EFFECT_1].SpellClassMask[1] = 0x00020000;
4103 });
4104
4105 // Nefarian: Shadowbolt, Shadow Command
4106 ApplySpellFix({ 22667, 22677 }, [](SpellInfo* spellInfo)
4107 {
4108 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(152); // 150 yards
4109 });
4110
4111 // Manastorm
4112 ApplySpellFix({ 21097 }, [](SpellInfo* spellInfo)
4113 {
4114 spellInfo->InterruptFlags &= ~SPELL_INTERRUPT_FLAG_INTERRUPT;
4115 });
4116
4117 // Arcane Vacuum
4118 ApplySpellFix({ 21147 }, [](SpellInfo* spellInfo)
4119 {
4120 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(4); // 30 yards
4121 spellInfo->AttributesEx3 |= SPELL_ATTR3_ONLY_ON_PLAYER;
4122 });
4123
4124 // Reflection
4125 ApplySpellFix({ 22067 }, [](SpellInfo* spellInfo)
4126 {
4127 spellInfo->Dispel = DISPEL_NONE;
4128 });
4129
4130 // Focused Assault
4131 // Brutal Assault
4132 ApplySpellFix({ 46392, 46393 }, [](SpellInfo* spellInfo)
4133 {
4134 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
4135 });
4136
4137 // Improved Blessing Protection (Nefarian Class Call)
4138 ApplySpellFix({ 23415 }, [](SpellInfo* spellInfo)
4139 {
4140 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ENEMY);
4141 });
4142
4143 // Bestial Wrath
4144 ApplySpellFix({ 19574 }, [](SpellInfo* spellInfo)
4145 {
4146 spellInfo->AttributesEx4 |= SPELL_ATTR4_AURA_EXPIRES_OFFLINE;
4147 });
4148
4149 // Shadowflame
4150 ApplySpellFix({ 22539 }, [](SpellInfo* spellInfo)
4151 {
4152 spellInfo->InterruptFlags &= ~SPELL_INTERRUPT_FLAG_INTERRUPT;
4153 });
4154
4155 // PX-238 Winter Wondervolt
4156 ApplySpellFix({ 26157, 26272, 26273, 26274 }, [](SpellInfo* spellInfo)
4157 {
4158 spellInfo->Mechanic = 0;
4159 });
4160
4161 // Calm Dragonkin
4162 ApplySpellFix({ 19872 }, [](SpellInfo* spellInfo)
4163 {
4164 spellInfo->AttributesEx |= SPELL_ATTR1_EXCLUDE_CASTER;
4165 });
4166
4167 // Cosmetic - Lightning Beam Channel
4168 ApplySpellFix({ 45537 }, [](SpellInfo* spellInfo)
4169 {
4170 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4171 });
4172
4173 // Burning Adrenaline
4174 ApplySpellFix({ 23478 }, [](SpellInfo* spellInfo)
4175 {
4176 spellInfo->Effects[EFFECT_0].BasePoints = 4374;
4177 spellInfo->Effects[EFFECT_0].DieSides = 1250;
4178 });
4179
4180 // Explosion - Razorgore
4181 ApplySpellFix({ 20038 }, [](SpellInfo* spellInfo)
4182 {
4183 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS);
4184 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
4185 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4186 });
4187
4188 // Brood Power : Bronze
4189 ApplySpellFix({ 22311 }, [](SpellInfo* spellInfo)
4190 {
4191 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_CASTER_PROCS;
4192 });
4193
4194 // Rapture
4195 ApplySpellFix({ 63652, 63653, 63654, 63655 }, [](SpellInfo* spellInfo)
4196 {
4197 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
4198 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4199 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_TARGET_PROCS;
4200 });
4201
4202 // Everlasting Affliction
4203 ApplySpellFix({ 47422 }, [](SpellInfo* spellInfo)
4204 {
4205 spellInfo->SchoolMask = SPELL_SCHOOL_MASK_SHADOW;
4206 });
4207
4208 // Flametongue Weapon (Passive) (Rank 6)
4209 ApplySpellFix({ 16312 }, [](SpellInfo* spellInfo)
4210 {
4211 spellInfo->Attributes |= SPELL_ATTR0_PASSIVE;
4212 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21);
4213 });
4214
4215 // Mana Tide Totem
4216 // Cleansing Totem Effect
4217 ApplySpellFix({ 39609, 52025 }, [](SpellInfo* spellInfo)
4218 {
4219 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(5); // 40yd
4220 });
4221
4222 // Increased Totem Radius
4223 ApplySpellFix({ 21895 }, [](SpellInfo* spellInfo)
4224 {
4225 spellInfo->Effects[0].SpellClassMask = flag96(0x0603E000, 0x00200100);
4226 });
4227
4228 // Jokkum Summon
4229 ApplySpellFix({ 56541 }, [](SpellInfo* spellInfo)
4230 {
4231 spellInfo->Effects[EFFECT_0].MiscValueB = 844;
4232 });
4233
4234 // Hakkar Cause Insanity
4235 ApplySpellFix({ 24327 }, [](SpellInfo* spellInfo)
4236 {
4237 spellInfo->Dispel = DISPEL_NONE;
4238 });
4239
4240 // Summon Nightmare Illusions
4241 ApplySpellFix({ 24681, 24728, 24729 }, [](SpellInfo* spellInfo)
4242 {
4243 spellInfo->Effects[EFFECT_0].MiscValueB = 64;
4244 });
4245
4246 // Blood Siphon
4247 ApplySpellFix({ 24322, 24323 }, [](SpellInfo* spellInfo)
4248 {
4249 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_MOD_STUN;
4250 spellInfo->Effects[EFFECT_2].Effect = 0;
4251 spellInfo->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
4252 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL;
4253 spellInfo->ChannelInterruptFlags &= ~AURA_INTERRUPT_FLAG_MOVE;
4254 });
4255
4256 // Place Fake Fur
4257 ApplySpellFix({ 46085 }, [](SpellInfo* spellInfo)
4258 {
4259 spellInfo->Effects[EFFECT_0].MiscValue = 8;
4260 });
4261
4262 // Smash Mammoth Trap
4263 ApplySpellFix({ 46201 }, [](SpellInfo* spellInfo)
4264 {
4265 spellInfo->Effects[EFFECT_0].MiscValue = 8;
4266 });
4267
4268 // Elemental Mastery
4269 ApplySpellFix({ 16166 }, [](SpellInfo* spellInfo)
4270 {
4271 spellInfo->Effects[EFFECT_0].SpellClassMask = flag96(0x00000003, 0x00001000);
4272 });
4273
4274 // Elemental Vulnerability
4275 ApplySpellFix({ 28772 }, [](SpellInfo* spellInfo)
4276 {
4277 spellInfo->Speed = 1;
4278 });
4279
4280 // Find the Ancient Hero: Kill Credit
4281 ApplySpellFix({ 25729 }, [](SpellInfo* spellInfo)
4282 {
4283 spellInfo->Effects[EFFECT_0].TargetA = TARGET_UNIT_SUMMONER;
4284 });
4285
4286 // Artorius Demonic Doom
4287 ApplySpellFix({ 23298 }, [](SpellInfo* spellInfo)
4288 {
4289 spellInfo->AttributesEx4 |= SPELL_ATTR4_IGNORE_DAMAGE_TAKEN_MODIFIERS;
4290 spellInfo->AttributesEx6 |= SPELL_ATTR6_IGNORE_CASTER_DAMAGE_MODIFIERS;
4291 });
4292
4293 // Lash
4294 ApplySpellFix({ 25852 }, [](SpellInfo* spellInfo)
4295 {
4296 spellInfo->Effects[EFFECT_1].Effect = 0;
4297 });
4298
4299 // Explosion
4300 ApplySpellFix({ 5255 }, [](SpellInfo* spellInfo)
4301 {
4302 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4303 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
4304 });
4305
4306 // Death's Respite
4307 ApplySpellFix({ 67731, 68305 }, [](SpellInfo* spellInfo)
4308 {
4309 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_TARGET_PROCS;
4310 });
4311
4312 // Wyvern Sting DoT
4313 ApplySpellFix({ 24131, 24134, 24135 }, [](SpellInfo* spellInfo)
4314 {
4315 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
4316 });
4317
4318 // Feed Pet
4319 ApplySpellFix({ 1539, 51284 }, [](SpellInfo* spellInfo)
4320 {
4321 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_WHILE_SITTING;
4322 });
4323
4324 // Judgement (Paladin T2 8P Bonus)
4325 // Battlegear of Eternal Justice
4326 ApplySpellFix({ 23591, 26135 }, [](SpellInfo* spellInfo)
4327 {
4328 spellInfo->ProcFlags = PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS;
4329 });
4330
4331 // Gift of Arthas
4332 ApplySpellFix({ 11371 }, [](SpellInfo* spellInfo)
4333 {
4334 spellInfo->SpellFamilyName = SPELLFAMILY_POTION;
4335 });
4336
4337 // Refocus (Renataki's charm of beasts)
4338 ApplySpellFix({ 24531 }, [](SpellInfo* spellInfo)
4339 {
4340 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
4341 });
4342
4343 // Collect Rookery Egg
4344 ApplySpellFix({ 15958 }, [](SpellInfo* spellInfo)
4345 {
4346 spellInfo->Effects[EFFECT_1].Effect = 0;
4347 });
4348
4349 // WotLK Prologue Frozen Shade Visual, temp used to restore visual after Dispersion
4350 ApplySpellFix({ 53444 }, [](SpellInfo* spellInfo)
4351 {
4352 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(27);
4353 });
4354
4355 // Rental Racing Ram
4356 ApplySpellFix({ 43883 }, [](SpellInfo* spellInfo)
4357 {
4358 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_NOT_ABOVEWATER;
4359 });
4360
4361 // Summon Worm
4362 ApplySpellFix({ 518, 25831, 25832 }, [](SpellInfo* spellInfo)
4363 {
4364 spellInfo->Effects[EFFECT_0].MiscValueB = 64;
4365 });
4366
4367 // Uppercut
4368 ApplySpellFix({ 26007 }, [](SpellInfo* spellInfo)
4369 {
4370 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_CASTER_PROCS;
4371 });
4372
4373 // Digestive Acid (Temporary)
4374 ApplySpellFix({ 26476 }, [](SpellInfo* spellInfo)
4375 {
4376 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
4377 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4378 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
4379 });
4380
4381 // Drums of War/Battle/Speed/Restoration
4382 ApplySpellFix({ 35475, 35476, 35477, 35478 }, [](SpellInfo* spellInfo)
4383 {
4384 spellInfo->ExcludeTargetAuraSpell = 51120;
4385 });
4386
4387 // Slap!
4388 ApplySpellFix({ 6754 }, [](SpellInfo* spellInfo)
4389 {
4390 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
4391 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_TARGET_PROCS;
4392 });
4393
4394 // Summon Cauldron Stuff
4395 ApplySpellFix({ 36549 }, [](SpellInfo* spellInfo)
4396 {
4397 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(28); // 5 seconds
4398 spellInfo->Effects[EFFECT_0].TargetB = TARGET_DEST_CASTER;
4399 });
4400
4401 // Hunter's Mark
4402 ApplySpellFix({ 31615 }, [](SpellInfo* spellInfo)
4403 {
4404 for (uint8 index = EFFECT_0; index <= EFFECT_1; ++index)
4405 {
4406 spellInfo->Effects[index].TargetA = TARGET_UNIT_TARGET_ENEMY;
4407 spellInfo->Effects[index].TargetB = 0;
4408 }
4409 });
4410
4411 // Self Visual - Sleep Until Cancelled(DND)
4412 ApplySpellFix({ 6606, 14915, 16093 }, [](SpellInfo* spellInfo)
4413 {
4414 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_NOT_SEATED;
4415 });
4416
4417 // Cleansing Totem, Healing Stream Totem, Mana Tide Totem
4418 ApplySpellFix({ 8171,52025, 52041, 52042, 52046, 52047, 52048, 52049, 52050, 58759, 58760, 58761, 39610, 39609 }, [](SpellInfo* spellInfo)
4419 {
4420 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4421 });
4422 // Game In Session
4423 ApplySpellFix({ 39331 }, [](SpellInfo* spellInfo)
4424 {
4425 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AURA;
4426 spellInfo->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
4427 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
4428 });
4429 // Death Ray Warning Visual, Death Ray Damage Visual
4430 ApplySpellFix({ 63882, 63886 }, [](SpellInfo* spellInfo)
4431 {
4432 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL;
4433 });
4434
4435 // Buffeting Winds of Susurrus
4436 ApplySpellFix({ 32474 }, [](SpellInfo* spellInfo)
4437 {
4438 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(556); // 28 seconds
4439 });
4440
4441 // Quest - Healing Salve
4442 ApplySpellFix({ 29314 }, [](SpellInfo* spellInfo)
4443 {
4444 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(1); // 0s
4445 });
4446
4447 // Seed of Corruption
4448 ApplySpellFix({ 27285, 47833, 47834 }, [](SpellInfo* spellInfo)
4449 {
4450 spellInfo->AttributesEx |= SPELL_ATTR1_NO_REFLECTION;
4451 });
4452
4453 // Turn the Tables
4454 ApplySpellFix({ 51627, 51628, 51629 }, [](SpellInfo* spellInfo)
4455 {
4456 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
4457 });
4458
4459 // Silence
4460 ApplySpellFix({ 18278 }, [](SpellInfo* spellInfo)
4461 {
4462 spellInfo->AttributesEx4 |= SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND;
4463 });
4464
4465 // Absorb Life
4466 ApplySpellFix({ 34239 }, [](SpellInfo* spellInfo)
4467 {
4468 spellInfo->Effects[EFFECT_0].ValueMultiplier = 1;
4469 });
4470
4471 // Summon a Warp Rift in Void Ridge
4472 ApplySpellFix({ 35036 }, [](SpellInfo* spellInfo)
4473 {
4474 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(1); // 0s
4475 });
4476
4477 // Hit Rating (Dungeon T3 - 2P Bonus - Wastewalker, Doomplate)
4478 ApplySpellFix({ 37608, 37610 }, [](SpellInfo* spellInfo)
4479 {
4480 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(0);
4481 spellInfo->Effects[EFFECT_0].MiscValue = 224;
4482 });
4483
4484 // Target Fissures
4485 ApplySpellFix({ 30745 }, [](SpellInfo* spellInfo)
4486 {
4487 spellInfo->MaxAffectedTargets = 1;
4488 });
4489
4490 // Acid Spit
4491 ApplySpellFix({ 34290 }, [](SpellInfo* spellInfo)
4492 {
4493 spellInfo->MaxAffectedTargets = 1;
4494 });
4495
4496 // Mulgore Hatchling (periodic)
4497 ApplySpellFix({ 62586 }, [](SpellInfo* spellInfo)
4498 {
4499 spellInfo->Effects[EFFECT_0].TriggerSpell = 62585; // Mulgore Hatchling (fear)
4500 });
4501
4502 // Poultryized!
4503 ApplySpellFix({ 30504 }, [](SpellInfo* spellInfo)
4504 {
4505 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_TAKE_DAMAGE;
4506 });
4507
4508 // Torment of the Worgen
4509 ApplySpellFix({ 30567 }, [](SpellInfo* spellInfo)
4510 {
4511 spellInfo->ProcChance = 3;
4512 });
4513
4514 // Summon Water Elementals
4515 ApplySpellFix({ 29962, 37051, 37052, 37053 }, [](SpellInfo* spellInfo)
4516 {
4517 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
4518 });
4519
4520 // Instill Lord Valthalak's Spirit DND
4521 ApplySpellFix({ 27360 }, [](SpellInfo* spellInfo)
4522 {
4523 spellInfo->ChannelInterruptFlags |= AURA_INTERRUPT_FLAG_MOVE;
4524 });
4525
4526 // Holiday - Midsummer, Ribbon Pole Periodic Visual
4527 ApplySpellFix({ 45406 }, [](SpellInfo* spellInfo)
4528 {
4529 spellInfo->AuraInterruptFlags |= ( AURA_INTERRUPT_FLAG_MOUNT | AURA_INTERRUPT_FLAG_CAST | AURA_INTERRUPT_FLAG_TALK );
4530 });
4531
4532 // Improved Mind Flay and Smite
4533 ApplySpellFix({ 37571 }, [](SpellInfo* spellInfo)
4534 {
4535 spellInfo->Effects[EFFECT_0].SpellClassMask[0] = 8388736;
4536 });
4537
4538 // Improved Corruption and Immolate (Updated)
4539 ApplySpellFix({ 61992 }, [](SpellInfo* spellInfo)
4540 {
4541 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
4542 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_ADD_PCT_MODIFIER;
4543 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
4544 spellInfo->Effects[EFFECT_1].BasePoints = 4;
4545 spellInfo->Effects[EFFECT_1].DieSides = 1;
4546 spellInfo->Effects[EFFECT_1].MiscValue = 22;
4547 spellInfo->Effects[EFFECT_1].SpellClassMask[0] = 6;
4548 });
4549
4550 // 46747 Fling torch
4551 ApplySpellFix({ 46747 }, [](SpellInfo* spellInfo)
4552 {
4553 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
4554 });
4555
4556 // Chains of Naberius
4557 ApplySpellFix({ 36146 }, [](SpellInfo* spellInfo)
4558 {
4559 spellInfo->MaxAffectedTargets = 1;
4560 });
4561
4562 // Force of Neltharaku
4563 ApplySpellFix({ 38762 }, [](SpellInfo* spellInfo)
4564 {
4565 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
4566 });
4567
4568 // Spotlight
4569 ApplySpellFix({ 29683, 32214 }, [](SpellInfo* spellInfo)
4570 {
4571 spellInfo->AttributesEx5 |= SPELL_ATTR5_DO_NOT_DISPLAY_DURATION;
4572 });
4573
4574 // Haunted
4575 ApplySpellFix({ 53768 }, [](SpellInfo* spellInfo)
4576 {
4577 spellInfo->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
4578 });
4579
4580 // Tidal Wave
4581 ApplySpellFix({ 37730 }, [](SpellInfo* spellInfo)
4582 {
4583 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4584 });
4585
4586 // Commanding Shout
4587 ApplySpellFix({ 469, 47439, 47440 }, [](SpellInfo* spellInfo)
4588 {
4589 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4590 });
4591
4592 // Battle Shout
4593 ApplySpellFix({ 2048, 5242, 6192, 6673, 11549, 11550, 11551, 25289, 47436 }, [](SpellInfo* spellInfo)
4594 {
4595 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4596 });
4597
4598 // Plague Effect
4599 ApplySpellFix({ 19594, 26557 }, [](SpellInfo* spellInfo)
4600 {
4601 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4602 });
4603
4604 // Prayer of Fortitude
4605 ApplySpellFix({ 21562, 21564, 25392, 48162 }, [](SpellInfo* spellInfo)
4606 {
4607 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4608 });
4609
4610 // Gift of the Wild
4611 ApplySpellFix({ 21849, 21850, 26991, 48470, 69381 }, [](SpellInfo* spellInfo)
4612 {
4613 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4614 });
4615
4616 // Arcane Brilliance
4617 ApplySpellFix({ 23028, 27127, 43002 }, [](SpellInfo* spellInfo)
4618 {
4619 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4620 });
4621
4622 // Prayer of Spirit
4623 ApplySpellFix({ 27681, 32999, 48074 }, [](SpellInfo* spellInfo)
4624 {
4625 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4626 });
4627
4628 // Prayer of Shadow Protection
4629 ApplySpellFix({ 27683, 39374, 48170 }, [](SpellInfo* spellInfo)
4630 {
4631 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4632 });
4633
4634 // Nagrand Fort Buff Reward Raid
4635 ApplySpellFix({ 33006 }, [](SpellInfo* spellInfo)
4636 {
4637 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4638 });
4639
4640 // Ancestral Awakening
4641 ApplySpellFix({ 52759 }, [](SpellInfo* spellInfo)
4642 {
4643 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4644 });
4645
4646 // Turn the Tables
4647 ApplySpellFix({ 52910, 52914, 52915 }, [](SpellInfo* spellInfo)
4648 {
4649 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4650 });
4651
4652 // Judgements of the Wise
4653 ApplySpellFix({ 54180 }, [](SpellInfo* spellInfo)
4654 {
4655 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4656 });
4657
4658 // Replenishment
4659 ApplySpellFix({ 57669 }, [](SpellInfo* spellInfo)
4660 {
4661 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4662 });
4663
4664 // Dalaran Brilliance
4665 ApplySpellFix({ 61316 }, [](SpellInfo* spellInfo)
4666 {
4667 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4668 });
4669
4670 // [DND] Dalaran Brilliance
4671 ApplySpellFix({ 61332 }, [](SpellInfo* spellInfo)
4672 {
4673 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4674 });
4675
4676 // Infinite Replenishment + Wisdom
4677 ApplySpellFix({ 61782 }, [](SpellInfo* spellInfo)
4678 {
4679 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4680 });
4681
4682 // Renewed Hope
4683 ApplySpellFix({ 63944 }, [](SpellInfo* spellInfo)
4684 {
4685 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4686 });
4687
4688 // Fortitude
4689 ApplySpellFix({ 69377 }, [](SpellInfo* spellInfo)
4690 {
4691 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4692 });
4693
4694 // Blessing of Forgotten Kings
4695 ApplySpellFix({ 69378 }, [](SpellInfo* spellInfo)
4696 {
4697 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4698 });
4699
4700 // Lucky Charm
4701 ApplySpellFix({ 69511 }, [](SpellInfo* spellInfo)
4702 {
4703 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4704 });
4705
4706 // Shiny Shard of the Scale Heal Targeter
4707 ApplySpellFix({ 69749 }, [](SpellInfo* spellInfo)
4708 {
4709 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4710 });
4711
4712 // Purified Shard of the Scale Heal Targeter
4713 ApplySpellFix({ 69754 }, [](SpellInfo* spellInfo)
4714 {
4715 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4716 });
4717
4718 // Brilliance
4719 ApplySpellFix({ 69994 }, [](SpellInfo* spellInfo)
4720 {
4721 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4722 });
4723
4724 // Domination
4725 ApplySpellFix({ 37135 }, [](SpellInfo* spellInfo)
4726 {
4727 spellInfo->MaxAffectedTargets = 5;
4728 });
4729
4730 // Presence Of Mind
4731 ApplySpellFix({ 12043 }, [](SpellInfo* spellInfo)
4732 {
4733 // It should not share cooldown mods with category[1151] spells (Arcane Power [12042], Decimate [47271])
4734 spellInfo->AttributesEx6 |= SPELL_ATTR6_NO_CATEGORY_COOLDOWN_MODS;
4735 });
4736
4737 // Eye of Grillok
4738 ApplySpellFix({ 38495 }, [](SpellInfo* spellInfo)
4739 {
4740 spellInfo->Effects[EFFECT_0].TriggerSpell = 38530; // Quest Credit for Eye of Grillok
4741 });
4742
4743 // Greater Fireball
4744 ApplySpellFix({ 33051 }, [](SpellInfo* spellInfo)
4745 {
4746 spellInfo->AttributesEx4 |= SPELL_ATTR4_NO_CAST_LOG;
4747 });
4748
4749 // Gor'drek's Ointment
4750 ApplySpellFix({ 32578 }, [](SpellInfo* spellInfo)
4751 {
4752 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_CASTER_PROCS;
4753 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_TARGET_PROCS;
4754 });
4755
4756 // Shadow Grasp
4757 ApplySpellFix({ 30410 }, [](SpellInfo* spellInfo)
4758 {
4759 spellInfo->AttributesEx6 |= SPELL_ATTR6_NO_PUSHBACK;
4760 });
4761
4763 471, // Palamino
4764 8980, // Skeletal Horse
4765 10788, // Leopard
4766 10790, // Tiger
4767 10792, // Spotted Panther
4768 60136, // Grand Caravan Mammoth
4769 60140 // Grand Caravan Mammoth
4770 }, [](SpellInfo* spellInfo)
4771 {
4772 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_NOT_ABOVEWATER;
4773 });
4774
4775 // Molten Punch
4776 ApplySpellFix({ 40126 }, [](SpellInfo* spellInfo)
4777 {
4778 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
4779 });
4780
4781 // Wing Buffet
4782 ApplySpellFix({ 37319 }, [](SpellInfo* spellInfo)
4783 {
4784 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CONE_ENEMY_24);
4785 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(0);
4786 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS);
4787 });
4788
4789 // Flame Wave
4790 ApplySpellFix({ 33800 }, [](SpellInfo* spellInfo)
4791 {
4792 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
4793 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_PERIODIC_TRIGGER_SPELL;
4794 spellInfo->Effects[EFFECT_1].Amplitude = 500;
4795 });
4796
4797 // Chromatic Resistance Aura
4798 ApplySpellFix({ 41453 }, [](SpellInfo* spellInfo)
4799 {
4800 spellInfo->Effects[EFFECT_0].MiscValue = 124;
4801 });
4802
4803 // Power of the Guardian
4804 ApplySpellFix({ 28142, 28143, 28144, 28145 }, [](SpellInfo* spellInfo)
4805 {
4806 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
4807 });
4808
4809 // Warrior stances passives
4811 2457, // Battle Stance
4812 2458, // Berserker Stance
4813 7376 // Defensive Stance Passive
4814 }, [](SpellInfo* spellInfo)
4815 {
4816 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_CASTER_PROCS;
4817 });
4818
4819 // Conjure Refreshment Table (Rank 1, Rank 2)
4820 ApplySpellFix({ 43985, 58661 }, [](SpellInfo* spellInfo)
4821 {
4822 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER_FRONT);
4823 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_5_YARDS);
4824 });
4825
4827 698, // Ritual of Summoning (portal for clicking)
4828 61993 // Ritual of Summoning (summons the closet)
4829 }, [](SpellInfo* spellInfo)
4830 {
4831 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS);
4832 });
4833
4834 // Paralyze
4835 ApplySpellFix({ 41083 }, [](SpellInfo* spellInfo)
4836 {
4837 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL;
4838 });
4839
4840 // Fatal Attraction
4841 ApplySpellFix({ 40870 }, [](SpellInfo* spellInfo)
4842 {
4843 spellInfo->MaxAffectedTargets = 1;
4844 });
4845
4846 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
4847 {
4848 SpellInfo* spellInfo = mSpellInfoMap[i];
4849 if (!spellInfo)
4850 {
4851 continue;
4852 }
4853
4854 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4855 {
4856 switch (spellInfo->Effects[j].Effect)
4857 {
4860 case SPELL_EFFECT_JUMP:
4863 if (!spellInfo->Speed && !spellInfo->SpellFamilyName)
4864 {
4865 spellInfo->Speed = SPEED_CHARGE;
4866 }
4867 break;
4868 }
4869
4870 // Xinef: i hope this will fix the problem with not working resurrection
4871 if (spellInfo->Effects[j].Effect == SPELL_EFFECT_SELF_RESURRECT)
4872 {
4873 spellInfo->Effects[j].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
4874 }
4875 }
4876
4877 // Fix range for trajectory triggered spell
4878 for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
4879 {
4880 if (spellEffectInfo.IsEffect() && (spellEffectInfo.TargetA.GetTarget() == TARGET_DEST_TRAJ || spellEffectInfo.TargetB.GetTarget() == TARGET_DEST_TRAJ))
4881 {
4882 // Get triggered spell if any
4883 if (SpellInfo* spellInfoTrigger = const_cast<SpellInfo*>(GetSpellInfo(spellEffectInfo.TriggerSpell)))
4884 {
4885 float maxRangeMain = spellInfo->RangeEntry ? spellInfo->RangeEntry->RangeMax[0] : 0.0f;
4886 float maxRangeTrigger = spellInfoTrigger->RangeEntry ? spellInfoTrigger->RangeEntry->RangeMax[0] : 0.0f;
4887
4888 // check if triggered spell has enough max range to cover trajectory
4889 if (maxRangeTrigger < maxRangeMain)
4890 spellInfoTrigger->RangeEntry = spellInfo->RangeEntry;
4891 }
4892 }
4893 }
4894
4895 if (spellInfo->ActiveIconID == 2158) // flight
4896 {
4897 spellInfo->Attributes |= SPELL_ATTR0_PASSIVE;
4898 }
4899
4900 switch (spellInfo->SpellFamilyName)
4901 {
4903 // Seals of the Pure should affect Seal of Righteousness
4904 if (spellInfo->SpellIconID == 25 && (spellInfo->Attributes & SPELL_ATTR0_PASSIVE))
4905 spellInfo->Effects[EFFECT_0].SpellClassMask[1] |= 0x20000000;
4906 break;
4908 // Icy Touch - extend FamilyFlags (unused value) for Sigil of the Frozen Conscience to use
4909 if (spellInfo->SpellIconID == 2721 && spellInfo->SpellFamilyFlags[0] & 0x2)
4910 spellInfo->SpellFamilyFlags[0] |= 0x40;
4911 break;
4912 case SPELLFAMILY_HUNTER:
4913 // Aimed Shot not affected by category cooldown modifiers
4914 if (spellInfo->SpellFamilyFlags[0] & 0x00020000)
4915 {
4917 spellInfo->RecoveryTime = 10 * IN_MILLISECONDS;
4918 }
4919 break;
4920 }
4921
4922 // Recklessness/Shield Wall/Retaliation
4923 if (spellInfo->CategoryEntry == sSpellCategoryStore.LookupEntry(132) && spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR)
4924 {
4926 }
4927 }
4928
4929 // Xinef: The Veiled Sea area in outlands (Draenei zone), client blocks casting flying mounts
4930 for (uint32 i = 0; i < sAreaTableStore.GetNumRows(); ++i)
4931 if (AreaTableEntry* areaEntry = const_cast<AreaTableEntry*>(sAreaTableStore.LookupEntry(i)))
4932 {
4933 if (areaEntry->ID == 3479)
4934 areaEntry->flags |= AREA_FLAG_NO_FLY_ZONE;
4935 // Xinef: Dun Morogh, Kharanos tavern, missing resting flag
4936 else if (areaEntry->ID == 2102)
4937 areaEntry->flags |= AREA_FLAG_REST_ZONE_ALLIANCE;
4938 }
4939
4940 // Xinef: fix for something?
4941 SummonPropertiesEntry* properties = const_cast<SummonPropertiesEntry*>(sSummonPropertiesStore.LookupEntry(121));
4942 properties->Type = SUMMON_TYPE_TOTEM;
4943 properties = const_cast<SummonPropertiesEntry*>(sSummonPropertiesStore.LookupEntry(647)); // 52893
4944 properties->Type = SUMMON_TYPE_TOTEM;
4945 if ((properties = const_cast<SummonPropertiesEntry*>(sSummonPropertiesStore.LookupEntry(628)))) // Hungry Plaguehound
4946 {
4947 properties->Category = SUMMON_CATEGORY_PET;
4948 properties->Type = SUMMON_TYPE_PET;
4949 }
4950
4951 // Correct Pet Size
4952 CreatureDisplayInfoEntry* displayEntry = const_cast<CreatureDisplayInfoEntry*>(sCreatureDisplayInfoStore.LookupEntry(17028)); // Kurken
4953 displayEntry->scale = 2.5f;
4954
4955 // Oracles and Frenzyheart faction
4956 FactionEntry* factionEntry = const_cast<FactionEntry*>(sFactionStore.LookupEntry(1104));
4957 factionEntry->ReputationFlags[0] = 0;
4958 factionEntry = const_cast<FactionEntry*>(sFactionStore.LookupEntry(1105));
4959 factionEntry->ReputationFlags[0] = 0;
4960
4961 // Various factions, added 14, 16 to hostile mask
4962 FactionTemplateEntry* factionTemplateEntry = const_cast<FactionTemplateEntry*>(sFactionTemplateStore.LookupEntry(1978)); // Warsong Offensive
4963 factionTemplateEntry->hostileMask |= 8;
4964 factionTemplateEntry = const_cast<FactionTemplateEntry*>(sFactionTemplateStore.LookupEntry(1921)); // The Taunka
4965 factionTemplateEntry->hostileMask |= 8;
4966
4967 // Remove 1 from guards friendly mask, making able to attack players
4968 factionTemplateEntry = const_cast<FactionTemplateEntry*>(sFactionTemplateStore.LookupEntry(1857)); // Area 52 Bruiser
4969 factionTemplateEntry->friendlyMask &= ~1;
4970 factionTemplateEntry = const_cast<FactionTemplateEntry*>(sFactionTemplateStore.LookupEntry(1806)); // Netherstorm Agent
4971 factionTemplateEntry->friendlyMask &= ~1;
4972 factionTemplateEntry = const_cast<FactionTemplateEntry*>(sFactionTemplateStore.LookupEntry(1812)); // K3 Bruiser
4973 factionTemplateEntry->friendlyMask &= ~1;
4974
4975 // Remove vehicles attr, making accessories selectable
4976 VehicleSeatEntry* vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(4689)); // Siege Engine, Accessory
4977 vse->m_flags &= ~VEHICLE_SEAT_FLAG_PASSENGER_NOT_SELECTABLE;
4978 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(4692)); // Siege Engine, Accessory
4979 vse->m_flags &= ~VEHICLE_SEAT_FLAG_PASSENGER_NOT_SELECTABLE;
4980 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(4693)); // Siege Engine, Accessory
4981 vse->m_flags &= ~VEHICLE_SEAT_FLAG_PASSENGER_NOT_SELECTABLE;
4982 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(3011)); // Salvaged Demolisher, Ulduar - not allow to change seats
4983 vse->m_flags &= ~VEHICLE_SEAT_FLAG_CAN_SWITCH;
4984 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(3077)); // Salvaged Demolisher Seat, Ulduar - not allow to change seats
4985 vse->m_flags &= ~VEHICLE_SEAT_FLAG_CAN_SWITCH;
4986
4987 // pussywizard: fix z offset for some vehicles:
4988 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(6206)); // Marrowgar - Bone Spike
4989 vse->m_attachmentOffsetZ = 4.0f;
4990 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(3806)); // Mimiron - seat on VX-001 for ACU during last phase
4991 vse->m_attachmentOffsetZ = 15.0f;
4992 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(3566)); // Mimiron - Working seat
4993 vse->m_attachmentOffsetX = -3.5f;
4994 vse->m_attachmentOffsetY = 0.0f;
4995 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(3567)); // Mimiron - Working seat
4996 vse->m_attachmentOffsetX = 2.3f;
4997 vse->m_attachmentOffsetY = -2.3f;
4998
4999 // Pilgrim's Bounty offsets
5000 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(2841));
5001 vse->m_attachmentOffsetX += 1.65f;
5002 vse->m_attachmentOffsetY += 0.75f;
5003 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(2842));
5004 vse->m_attachmentOffsetX += 1.6f;
5005 vse->m_attachmentOffsetY += -1.0f;
5006 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(2843));
5007 vse->m_attachmentOffsetX += -1.2f;
5008 vse->m_attachmentOffsetY += 0.2f;
5009 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(2844));
5010 vse->m_attachmentOffsetX += -0.1f;
5011 vse->m_attachmentOffsetY += -1.6f;
5012 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(2845));
5013 vse->m_attachmentOffsetX += 0.0f;
5014 vse->m_attachmentOffsetY += 1.6f;
5015
5016 // Once Bitten, Twice Shy (10 player) - Icecrown Citadel
5017 AchievementEntry* achievement = const_cast<AchievementEntry*>(sAchievementStore.LookupEntry(4539));
5018 achievement->mapID = 631; // Correct map requirement (currently has Ulduar)
5019
5020 // Ring of Valor starting Locations
5021 GraveyardStruct const* entry = sGraveyard->GetGraveyard(1364);
5022 const_cast<GraveyardStruct*>(entry)->z += 6.0f;
5023 entry = sGraveyard->GetGraveyard(1365);
5024 const_cast<GraveyardStruct*>(entry)->z += 6.0f;
5025
5026 LockEntry* key = const_cast<LockEntry*>(sLockStore.LookupEntry(36)); // 3366 Opening, allows to open without proper key
5027 key->Type[2] = LOCK_KEY_NONE;
5028
5029 LOG_INFO("server.loading", ">> Loading spell dbc data corrections in {} ms", GetMSTimeDiffToNow(oldMSTime));
5030 LOG_INFO("server.loading", " ");
5031}
constexpr auto IN_MILLISECONDS
Definition: Common.h:53
#define sGraveyard
Definition: GameGraveyard.h:75
#define SPEED_CHARGE
Definition: MotionMaster.h:107
DBCStorage< VehicleSeatEntry > sVehicleSeatStore(VehicleSeatEntryfmt)
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
DBCStorage< SpellRadiusEntry > sSpellRadiusStore(SpellRadiusfmt)
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
DBCStorage< SpellCategoryEntry > sSpellCategoryStore(SpellCategoryfmt)
DBCStorage< CreatureDisplayInfoEntry > sCreatureDisplayInfoStore(CreatureDisplayInfofmt)
DBCStorage< SpellCastTimesEntry > sSpellCastTimesStore(SpellCastTimefmt)
DBCStorage< SpellRangeEntry > sSpellRangeStore(SpellRangefmt)
DBCStorage< AchievementEntry > sAchievementStore(Achievementfmt)
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
DBCStorage< SpellDurationEntry > sSpellDurationStore(SpellDurationfmt)
@ FORM_MOONKIN
Definition: UnitDefines.h:98
@ FORM_CAT
Definition: UnitDefines.h:70
@ FORM_TREE
Definition: UnitDefines.h:71
@ SPELL_AURA_ADD_PCT_MODIFIER
Definition: SpellAuraDefines.h:171
@ SPELL_AURA_PROC_TRIGGER_SPELL
Definition: SpellAuraDefines.h:105
@ SPELL_AURA_ADD_FLAT_MODIFIER
Definition: SpellAuraDefines.h:170
@ SPELL_AURA_PERIODIC_HEAL
Definition: SpellAuraDefines.h:71
@ SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE
Definition: SpellAuraDefines.h:294
@ SPELL_AURA_DUMMY
Definition: SpellAuraDefines.h:67
@ SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN
Definition: SpellAuraDefines.h:150
@ SPELL_AURA_SPLIT_DAMAGE_PCT
Definition: SpellAuraDefines.h:144
@ SPELL_AURA_MOD_CHARM
Definition: SpellAuraDefines.h:69
@ SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE
Definition: SpellAuraDefines.h:250
@ SPELL_AURA_MOD_TAUNT
Definition: SpellAuraDefines.h:74
@ SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT
Definition: SpellAuraDefines.h:195
@ SPELL_AURA_MOD_DECREASE_SPEED
Definition: SpellAuraDefines.h:96
@ SPELL_AURA_SCHOOL_ABSORB
Definition: SpellAuraDefines.h:132
@ SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST
Definition: SpellAuraDefines.h:333
@ SPELL_AURA_PERIODIC_DUMMY
Definition: SpellAuraDefines.h:289
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
Definition: SpellAuraDefines.h:86
@ SPELL_AURA_SET_VEHICLE_ID
Definition: SpellAuraDefines.h:359
@ SPELL_AURA_MOD_STUN
Definition: SpellAuraDefines.h:75
@ AURA_INTERRUPT_FLAG_TAKE_DAMAGE
Definition: SpellDefines.h:45
@ AURA_INTERRUPT_FLAG_CAST
Definition: SpellDefines.h:46
@ AURA_INTERRUPT_FLAG_TALK
Definition: SpellDefines.h:54
@ AURA_INTERRUPT_FLAG_HITBYSPELL
Definition: SpellDefines.h:44
@ AURA_INTERRUPT_FLAG_MOVE
Definition: SpellDefines.h:47
@ AURA_INTERRUPT_FLAG_TURNING
Definition: SpellDefines.h:48
@ AURA_INTERRUPT_FLAG_MELEE_ATTACK
Definition: SpellDefines.h:56
@ AURA_INTERRUPT_FLAG_CHANGE_MAP
Definition: SpellDefines.h:63
@ AURA_INTERRUPT_FLAG_MOUNT
Definition: SpellDefines.h:61
@ SPELLMOD_EFFECT2
Definition: SpellDefines.h:89
@ SPELLMOD_DAMAGE
Definition: SpellDefines.h:77
@ SPELLMOD_EFFECT1
Definition: SpellDefines.h:80
@ SPELL_INTERRUPT_FLAG_INTERRUPT
Definition: SpellDefines.h:30
@ EFFECT_RADIUS_500_YARDS
Definition: SpellMgr.h:432
@ EFFECT_RADIUS_7_YARDS
Definition: SpellMgr.h:438
@ EFFECT_RADIUS_100_YARDS
Definition: SpellMgr.h:414
@ EFFECT_RADIUS_20_YARDS
Definition: SpellMgr.h:411
@ EFFECT_RADIUS_8_YARDS
Definition: SpellMgr.h:416
@ EFFECT_RADIUS_2_YARDS
Definition: SpellMgr.h:409
@ EFFECT_RADIUS_1_YARD
Definition: SpellMgr.h:418
@ EFFECT_RADIUS_4_YARDS
Definition: SpellMgr.h:428
@ EFFECT_RADIUS_25_YARDS
Definition: SpellMgr.h:422
@ EFFECT_RADIUS_5_YARDS
Definition: SpellMgr.h:410
@ EFFECT_RADIUS_70_YARDS
Definition: SpellMgr.h:427
@ EFFECT_RADIUS_3_YARDS
Definition: SpellMgr.h:417
@ EFFECT_RADIUS_50000_YARDS
Definition: SpellMgr.h:430
@ EFFECT_RADIUS_18_YARDS
Definition: SpellMgr.h:421
@ EFFECT_RADIUS_200_YARDS
Definition: SpellMgr.h:424
@ EFFECT_RADIUS_12_YARDS
Definition: SpellMgr.h:434
@ EFFECT_RADIUS_10_YARDS
Definition: SpellMgr.h:415
@ EFFECT_RADIUS_150_YARDS
Definition: SpellMgr.h:442
@ EFFECT_RADIUS_6_YARDS
Definition: SpellMgr.h:431
@ PROC_FLAG_DONE_MELEE_AUTO_ATTACK
Definition: SpellMgr.h:110
@ PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS
Definition: SpellMgr.h:113
@ TARGET_FLAG_DEST_LOCATION
Definition: SpellInfo.h:52
void ApplySpellFix(std::initializer_list< uint32 > spellIds, void(*fix)(SpellInfo *))
Definition: SpellInfoCorrections.cpp:24
@ EFFECT_1
Definition: SharedDefines.h:32
@ EFFECT_0
Definition: SharedDefines.h:31
@ EFFECT_2
Definition: SharedDefines.h:33
@ POWER_MANA
Definition: SharedDefines.h:269
@ SPELL_ATTR7_DONT_CAUSE_SPELL_PUSHBACK
Definition: SharedDefines.h:647
@ SPELL_ATTR7_CAN_CAUSE_INTERRUPT
Definition: SharedDefines.h:652
@ SPELL_ATTR7_DISABLE_AURA_WHILE_DEAD
Definition: SharedDefines.h:643
@ SPELL_EFFECT_DUMMY
Definition: SharedDefines.h:781
@ SPELL_EFFECT_SCRIPT_EFFECT
Definition: SharedDefines.h:855
@ SPELL_EFFECT_POWER_BURN
Definition: SharedDefines.h:840
@ SPELL_EFFECT_APPLY_AREA_AURA_FRIEND
Definition: SharedDefines.h:906
@ SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
Definition: SharedDefines.h:920
@ SPELL_EFFECT_SELF_RESURRECT
Definition: SharedDefines.h:872
@ SPELL_EFFECT_TRIGGER_MISSILE
Definition: SharedDefines.h:810
@ SPELL_EFFECT_JUMP_DEST
Definition: SharedDefines.h:820
@ SPELL_EFFECT_MODIFY_THREAT_PERCENT
Definition: SharedDefines.h:903
@ SPELL_EFFECT_LEAP_BACK
Definition: SharedDefines.h:916
@ SPELL_EFFECT_CHARGE
Definition: SharedDefines.h:874
@ SPELL_EFFECT_CHARGE_DEST
Definition: SharedDefines.h:927
@ SPELL_EFFECT_JUMP
Definition: SharedDefines.h:819
@ SPELL_EFFECT_APPLY_AURA
Definition: SharedDefines.h:784
@ SPELL_PREVENTION_TYPE_NONE
Definition: SharedDefines.h:1553
@ SPELL_ATTR5_EXTRA_INITIAL_PERIOD
Definition: SharedDefines.h:576
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
Definition: SharedDefines.h:570
@ SPELL_ATTR5_DO_NOT_DISPLAY_DURATION
Definition: SharedDefines.h:577
@ SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL
Definition: SharedDefines.h:567
@ SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT
Definition: SharedDefines.h:593
@ TARGET_DEST_TARGET_ANY
Definition: SharedDefines.h:1467
@ TARGET_UNIT_CONE_ENTRY
Definition: SharedDefines.h:1464
@ TARGET_DEST_CASTER_FRONT
Definition: SharedDefines.h:1451
@ TARGET_DEST_DB
Definition: SharedDefines.h:1422
@ TARGET_UNIT_CASTER_AREA_PARTY
Definition: SharedDefines.h:1424
@ TARGET_UNIT_SRC_AREA_ENTRY
Definition: SharedDefines.h:1416
@ TARGET_UNIT_DEST_AREA_ENEMY
Definition: SharedDefines.h:1421
@ TARGET_UNIT_SRC_AREA_ALLY
Definition: SharedDefines.h:1434
@ TARGET_UNIT_TARGET_ALLY
Definition: SharedDefines.h:1425
@ TARGET_DEST_CASTER_BACK
Definition: SharedDefines.h:1452
@ TARGET_UNIT_VEHICLE
Definition: SharedDefines.h:1498
@ TARGET_UNIT_TARGET_ANY
Definition: SharedDefines.h:1429
@ TARGET_DEST_DEST
Definition: SharedDefines.h:1491
@ TARGET_UNIT_SRC_AREA_ENEMY
Definition: SharedDefines.h:1420
@ TARGET_DEST_TARGET_ENEMY
Definition: SharedDefines.h:1457
@ TARGET_UNIT_PET
Definition: SharedDefines.h:1414
@ TARGET_DEST_DYNOBJ_NONE
Definition: SharedDefines.h:1492
@ TARGET_UNIT_TARGET_ENEMY
Definition: SharedDefines.h:1415
@ TARGET_UNIT_MASTER
Definition: SharedDefines.h:1431
@ TARGET_DEST_TRAJ
Definition: SharedDefines.h:1493
@ TARGET_UNIT_DEST_AREA_ENTRY
Definition: SharedDefines.h:1417
@ TARGET_UNIT_NEARBY_ENTRY
Definition: SharedDefines.h:1442
@ TARGET_DEST_CASTER
Definition: SharedDefines.h:1423
@ TARGET_UNIT_CASTER
Definition: SharedDefines.h:1410
@ TARGET_UNIT_CONE_ENEMY_24
Definition: SharedDefines.h:1428
@ TARGET_SRC_CASTER
Definition: SharedDefines.h:1426
@ TARGET_UNIT_SUMMONER
Definition: SharedDefines.h:1496
@ SPELL_ATTR2_CANT_CRIT
Definition: SharedDefines.h:485
@ SPELL_ATTR2_ALLOW_DEAD_TARGET
Definition: SharedDefines.h:456
@ SPELL_ATTR2_IGNORE_LINE_OF_SIGHT
Definition: SharedDefines.h:458
@ SPELL_ATTR1_NO_THREAT
Definition: SharedDefines.h:429
@ SPELL_ATTR1_EXCLUDE_CASTER
Definition: SharedDefines.h:438
@ SPELL_ATTR1_ALLOW_WHILE_STEALTHED
Definition: SharedDefines.h:424
@ SPELL_ATTR1_IMMUNITY_PURGES_EFFECT
Definition: SharedDefines.h:434
@ SPELL_ATTR1_NO_REFLECTION
Definition: SharedDefines.h:426
@ SPELL_ATTR1_NO_REDIRECTION
Definition: SharedDefines.h:422
@ SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD
Definition: SharedDefines.h:513
@ SPELL_ATTR3_ALWAYS_HIT
Definition: SharedDefines.h:511
@ SPELL_ATTR3_DOT_STACKING_RULE
Definition: SharedDefines.h:500
@ SPELL_ATTR3_CAN_PROC_FROM_PROCS
Definition: SharedDefines.h:519
@ SPELL_ATTR3_SUPRESS_CASTER_PROCS
Definition: SharedDefines.h:509
@ SPELL_ATTR3_SUPRESS_TARGET_PROCS
Definition: SharedDefines.h:510
@ SPELL_ATTR3_COMPLETELY_BLOCKED
Definition: SharedDefines.h:496
@ SPELL_ATTR3_IGNORE_CASTER_MODIFIERS
Definition: SharedDefines.h:522
@ SPELL_ATTR3_ONLY_ON_PLAYER
Definition: SharedDefines.h:501
@ SPELL_DAMAGE_CLASS_MAGIC
Definition: SharedDefines.h:1546
@ LOCK_KEY_NONE
Definition: SharedDefines.h:2584
@ SUMMON_TYPE_PET
Definition: SharedDefines.h:3295
@ SUMMON_TYPE_TOTEM
Definition: SharedDefines.h:3298
@ MECHANIC_NONE
Definition: SharedDefines.h:1325
@ MECHANIC_STUN
Definition: SharedDefines.h:1337
@ MECHANIC_SNARE
Definition: SharedDefines.h:1336
@ SPELLFAMILY_MAGE
Definition: SharedDefines.h:3531
@ SPELLFAMILY_GENERIC
Definition: SharedDefines.h:3528
@ SPELLFAMILY_WARRIOR
Definition: SharedDefines.h:3532
@ SPELLFAMILY_PALADIN
Definition: SharedDefines.h:3538
@ SPELLFAMILY_HUNTER
Definition: SharedDefines.h:3537
@ SPELLFAMILY_POTION
Definition: SharedDefines.h:3541
@ SPELLFAMILY_ROGUE
Definition: SharedDefines.h:3536
@ SPELLFAMILY_DEATHKNIGHT
Definition: SharedDefines.h:3543
@ SPELLFAMILY_UNK1
Definition: SharedDefines.h:3529
@ SPELL_ATTR0_NOT_SHAPESHIFTED
Definition: SharedDefines.h:398
@ SPELL_ATTR0_ALLOW_WHILE_SITTING
Definition: SharedDefines.h:409
@ SPELL_ATTR0_AURA_IS_DEBUFF
Definition: SharedDefines.h:408
@ SPELL_ATTR0_PASSIVE
Definition: SharedDefines.h:388
@ SPELL_ATTR0_IS_ABILITY
Definition: SharedDefines.h:386
@ SPELL_ATTR0_NO_IMMUNITIES
Definition: SharedDefines.h:411
@ SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT
Definition: SharedDefines.h:402
@ SPELL_ATTR0_USES_RANGED_SLOT
Definition: SharedDefines.h:383
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
Definition: SharedDefines.h:405
@ DISPEL_MAGIC
Definition: SharedDefines.h:1373
@ DISPEL_NONE
Definition: SharedDefines.h:1372
@ SPELL_ATTR4_AURA_EXPIRES_OFFLINE
Definition: SharedDefines.h:532
@ SPELL_ATTR4_ALLOW_ENETRING_ARENA
Definition: SharedDefines.h:551
@ SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND
Definition: SharedDefines.h:546
@ SPELL_ATTR4_IGNORE_DAMAGE_TAKEN_MODIFIERS
Definition: SharedDefines.h:538
@ SPELL_ATTR4_NO_CAST_LOG
Definition: SharedDefines.h:530
@ SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING
Definition: SharedDefines.h:537
@ SPELL_ATTR4_CANNOT_BE_STOLEN
Definition: SharedDefines.h:536
@ SPELL_ATTR4_REACTIVE_DAMAGE_PROC
Definition: SharedDefines.h:544
@ SUMMON_CATEGORY_PET
Definition: SharedDefines.h:3285
@ SPELL_ATTR6_NO_PUSHBACK
Definition: SharedDefines.h:619
@ SPELL_ATTR6_CAN_TARGET_UNTARGETABLE
Definition: SharedDefines.h:628
@ SPELL_ATTR6_IGNORE_CASTER_DAMAGE_MODIFIERS
Definition: SharedDefines.h:633
@ SPELL_ATTR6_IGNORE_PHASE_SHIFT
Definition: SharedDefines.h:617
@ SPELL_ATTR6_NO_CATEGORY_COOLDOWN_MODS
Definition: SharedDefines.h:635
@ SPELL_SCHOOL_MASK_SHADOW
Definition: SharedDefines.h:302
@ SPELL_SCHOOL_MASK_MAGIC
Definition: SharedDefines.h:312
@ AREA_FLAG_REST_ZONE_ALLIANCE
Definition: DBCEnums.h:257
@ AREA_FLAG_NO_FLY_ZONE
Definition: DBCEnums.h:262
Definition: Util.h:451
Definition: GameGraveyard.h:28
Definition: SpellInfo.h:217
Definition: SpellInfo.h:249
uint32 RecoveryTime
Definition: SpellInfo.h:348
SpellRangeEntry const * RangeEntry
Definition: SpellInfo.h:369
uint32 ActiveIconID
Definition: SpellInfo.h:381
float Speed
Definition: SpellInfo.h:370
uint32 Attributes
Definition: SpellInfo.h:324
SpellCategoryEntry const * CategoryEntry
Definition: SpellInfo.h:321
uint32 AttributesEx6
Definition: SpellInfo.h:330
uint32 SpellIconID
Definition: SpellInfo.h:380
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > const & GetEffects() const
Definition: SpellInfo.h:527
Definition: DBCStructure.h:40
int32 mapID
Definition: DBCStructure.h:43
Definition: DBCStructure.h:519
Definition: DBCStructure.h:721
float scale
Definition: DBCStructure.h:726
Definition: DBCStructure.h:907
uint32 ReputationFlags[4]
Definition: DBCStructure.h:913
Definition: DBCStructure.h:939
uint32 friendlyMask
Definition: DBCStructure.h:944
uint32 hostileMask
Definition: DBCStructure.h:945
Definition: DBCStructure.h:1308
uint32 Type[MAX_LOCK_CASE]
Definition: DBCStructure.h:1310
float RangeMax[2]
Definition: DBCStructure.h:1796
Definition: DBCStructure.h:1909
uint32 Type
Definition: DBCStructure.h:1913
uint32 Category
Definition: DBCStructure.h:1911
Definition: DBCStructure.h:2064
float m_attachmentOffsetX
Definition: DBCStructure.h:2068
float m_attachmentOffsetY
Definition: DBCStructure.h:2069
float m_attachmentOffsetZ
Definition: DBCStructure.h:2070
uint32 m_flags
Definition: DBCStructure.h:2066

References SpellInfo::ActiveIconID, ApplySpellFix(), AREA_FLAG_NO_FLY_ZONE, AREA_FLAG_REST_ZONE_ALLIANCE, SpellInfo::Attributes, SpellInfo::AttributesEx6, AURA_INTERRUPT_FLAG_CAST, AURA_INTERRUPT_FLAG_CHANGE_MAP, AURA_INTERRUPT_FLAG_HITBYSPELL, AURA_INTERRUPT_FLAG_MELEE_ATTACK, AURA_INTERRUPT_FLAG_MOUNT, AURA_INTERRUPT_FLAG_MOVE, AURA_INTERRUPT_FLAG_TAKE_DAMAGE, AURA_INTERRUPT_FLAG_TALK, AURA_INTERRUPT_FLAG_TURNING, SummonPropertiesEntry::Category, SpellInfo::CategoryEntry, DISPEL_MAGIC, DISPEL_NONE, DONE_HIT_PROC_FLAG_MASK, EFFECT_0, EFFECT_1, EFFECT_2, EFFECT_RADIUS_100_YARDS, EFFECT_RADIUS_10_YARDS, EFFECT_RADIUS_12_YARDS, EFFECT_RADIUS_150_YARDS, EFFECT_RADIUS_18_YARDS, EFFECT_RADIUS_1_YARD, EFFECT_RADIUS_200_YARDS, EFFECT_RADIUS_20_YARDS, EFFECT_RADIUS_25_YARDS, EFFECT_RADIUS_2_YARDS, EFFECT_RADIUS_3_YARDS, EFFECT_RADIUS_4_YARDS, EFFECT_RADIUS_50000_YARDS, EFFECT_RADIUS_500_YARDS, EFFECT_RADIUS_5_YARDS, EFFECT_RADIUS_6_YARDS, EFFECT_RADIUS_70_YARDS, EFFECT_RADIUS_7_YARDS, EFFECT_RADIUS_8_YARDS, SpellInfo::Effects, FORM_CAT, FORM_MOONKIN, FORM_TREE, FactionTemplateEntry::friendlyMask, SpellInfo::GetEffects(), getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), GetSpellInfoStoreSize(), FactionTemplateEntry::hostileMask, IN_MILLISECONDS, LOCK_KEY_NONE, LOG_INFO, VehicleSeatEntry::m_attachmentOffsetX, VehicleSeatEntry::m_attachmentOffsetY, VehicleSeatEntry::m_attachmentOffsetZ, VehicleSeatEntry::m_flags, AchievementEntry::mapID, MAX_SPELL_EFFECTS, MECHANIC_NONE, MECHANIC_SNARE, MECHANIC_STUN, mSpellInfoMap, POWER_MANA, PROC_FLAG_DONE_MELEE_AUTO_ATTACK, PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS, SpellInfo::RangeEntry, SpellRangeEntry::RangeMax, SpellInfo::RecoveryTime, FactionEntry::ReputationFlags, sAchievementStore, sAreaTableStore, CreatureDisplayInfoEntry::scale, sCreatureDisplayInfoStore, sFactionStore, sFactionTemplateStore, sGraveyard, sLockStore, SpellInfo::Speed, SPEED_CHARGE, SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD, SPELL_ATTR0_ALLOW_WHILE_SITTING, SPELL_ATTR0_AURA_IS_DEBUFF, SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_NO_AURA_CANCEL, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR0_NOT_SHAPESHIFTED, SPELL_ATTR0_PASSIVE, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_ATTR1_ALLOW_WHILE_STEALTHED, SPELL_ATTR1_EXCLUDE_CASTER, SPELL_ATTR1_IMMUNITY_PURGES_EFFECT, SPELL_ATTR1_NO_REDIRECTION, SPELL_ATTR1_NO_REFLECTION, SPELL_ATTR1_NO_THREAT, SPELL_ATTR2_ALLOW_DEAD_TARGET, SPELL_ATTR2_CANT_CRIT, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD, SPELL_ATTR3_ALWAYS_HIT, SPELL_ATTR3_CAN_PROC_FROM_PROCS, SPELL_ATTR3_COMPLETELY_BLOCKED, SPELL_ATTR3_DOT_STACKING_RULE, SPELL_ATTR3_IGNORE_CASTER_MODIFIERS, SPELL_ATTR3_ONLY_ON_PLAYER, SPELL_ATTR3_SUPRESS_CASTER_PROCS, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING, SPELL_ATTR4_ALLOW_ENETRING_ARENA, SPELL_ATTR4_AURA_EXPIRES_OFFLINE, SPELL_ATTR4_CANNOT_BE_STOLEN, SPELL_ATTR4_IGNORE_DAMAGE_TAKEN_MODIFIERS, SPELL_ATTR4_NO_CAST_LOG, SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND, SPELL_ATTR4_REACTIVE_DAMAGE_PROC, SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL, SPELL_ATTR5_ALLOW_WHILE_STUNNED, SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT, SPELL_ATTR5_DO_NOT_DISPLAY_DURATION, SPELL_ATTR5_EXTRA_INITIAL_PERIOD, SPELL_ATTR6_CAN_TARGET_UNTARGETABLE, SPELL_ATTR6_IGNORE_CASTER_DAMAGE_MODIFIERS, SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_ATTR6_NO_CATEGORY_COOLDOWN_MODS, SPELL_ATTR6_NO_PUSHBACK, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_ATTR7_DISABLE_AURA_WHILE_DEAD, SPELL_ATTR7_DONT_CAUSE_SPELL_PUSHBACK, SPELL_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_ADD_PCT_MODIFIER, SPELL_AURA_DUMMY, SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST, SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT, SPELL_AURA_MOD_STUN, SPELL_AURA_MOD_TAUNT, SPELL_AURA_PERIODIC_DUMMY, SPELL_AURA_PERIODIC_HEAL, SPELL_AURA_PERIODIC_TRIGGER_SPELL, SPELL_AURA_PROC_TRIGGER_SPELL, SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE, SPELL_AURA_SCHOOL_ABSORB, SPELL_AURA_SET_VEHICLE_ID, SPELL_AURA_SPLIT_DAMAGE_PCT, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_APPLY_AREA_AURA_FRIEND, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_CHARGE, SPELL_EFFECT_CHARGE_DEST, SPELL_EFFECT_DUMMY, SPELL_EFFECT_JUMP, SPELL_EFFECT_JUMP_DEST, SPELL_EFFECT_LEAP_BACK, SPELL_EFFECT_MODIFY_THREAT_PERCENT, SPELL_EFFECT_POWER_BURN, SPELL_EFFECT_SCRIPT_EFFECT, SPELL_EFFECT_SELF_RESURRECT, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_TRIGGER_MISSILE, SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE, SPELL_INTERRUPT_FLAG_INTERRUPT, SPELL_PREVENTION_TYPE_NONE, SPELL_SCHOOL_MASK_MAGIC, SPELL_SCHOOL_MASK_SHADOW, SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_MAGE, SPELLFAMILY_PALADIN, SPELLFAMILY_POTION, SPELLFAMILY_ROGUE, SPELLFAMILY_UNK1, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, SPELLMOD_DAMAGE, SPELLMOD_EFFECT1, SPELLMOD_EFFECT2, sSpellCastTimesStore, sSpellCategoryStore, sSpellDurationStore, sSpellRadiusStore, sSpellRangeStore, sSummonPropertiesStore, SUMMON_CATEGORY_PET, SUMMON_TYPE_PET, SUMMON_TYPE_TOTEM, sVehicleSeatStore, TARGET_DEST_CASTER, TARGET_DEST_CASTER_BACK, TARGET_DEST_CASTER_FRONT, TARGET_DEST_DB, TARGET_DEST_DEST, TARGET_DEST_DYNOBJ_NONE, TARGET_DEST_TARGET_ANY, TARGET_DEST_TARGET_ENEMY, TARGET_DEST_TRAJ, TARGET_FLAG_DEST_LOCATION, TARGET_SRC_CASTER, TARGET_UNIT_CASTER, TARGET_UNIT_CASTER_AREA_PARTY, TARGET_UNIT_CONE_ENEMY_24, TARGET_UNIT_CONE_ENTRY, TARGET_UNIT_DEST_AREA_ENEMY, TARGET_UNIT_DEST_AREA_ENTRY, TARGET_UNIT_MASTER, TARGET_UNIT_NEARBY_ENTRY, TARGET_UNIT_PET, TARGET_UNIT_SRC_AREA_ALLY, TARGET_UNIT_SRC_AREA_ENEMY, TARGET_UNIT_SRC_AREA_ENTRY, TARGET_UNIT_SUMMONER, TARGET_UNIT_TARGET_ALLY, TARGET_UNIT_TARGET_ANY, TARGET_UNIT_TARGET_ENEMY, TARGET_UNIT_VEHICLE, LockEntry::Type, and SummonPropertiesEntry::Type.

◆ LoadSpellInfoCustomAttributes()

void SpellMgr::LoadSpellInfoCustomAttributes ( )
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
2798{
2799 uint32 const oldMSTime = getMSTime();
2800 uint32 const customAttrTime = getMSTime();
2801 uint32 count;
2802
2803 QueryResult result = WorldDatabase.Query("SELECT spell_id, attributes FROM spell_custom_attr");
2804
2805 if (!result)
2806 {
2807 LOG_WARN("server.loading", ">> Loaded 0 Spell Custom Attributes From DB. DB table `spell_custom_attr` Is Empty.");
2808 }
2809 else
2810 {
2811 for (count = 0; result->NextRow(); ++count)
2812 {
2813 Field const* fields = result->Fetch();
2814
2815 uint32 const spellId = fields[0].Get<uint32>();
2816 uint32 attributes = fields[1].Get<uint32>();
2817
2818 SpellInfo* spellInfo = _GetSpellInfo(spellId);
2819 if (!spellInfo)
2820 {
2821 LOG_INFO("sql.sql", "Table `spell_custom_attr` has wrong spell (spell_id: {}), ignored.", spellId);
2822 continue;
2823 }
2824
2825 if (attributes & SPELL_ATTR0_CU_NEGATIVE)
2826 {
2827 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2828 {
2829 if (spellInfo->Effects[i].IsEffect())
2830 {
2831 if ((attributes & (SPELL_ATTR0_CU_NEGATIVE_EFF0 << i)) && (attributes & (SPELL_ATTR0_CU_POSITIVE_EFF0 << i)))
2832 {
2833 LOG_ERROR("sql.sql", "Table `spell_custom_attr` has attribute SPELL_ATTR0_CU_NEGATIVE_EFF{} and SPELL_ATTR0_CU_POSITIVE_EFF{} attributes for spell {} which cannot stack together. Attributes will not get applied", static_cast<uint32>(i), static_cast<uint32>(i), spellId);
2835 }
2836 continue;
2837 }
2838
2839 if (attributes & (SPELL_ATTR0_CU_NEGATIVE_EFF0 << i))
2840 {
2841 LOG_ERROR("sql.sql", "Table `spell_custom_attr` has attribute SPELL_ATTR0_CU_NEGATIVE_EFF{} for spell {} with no EFFECT_{}", static_cast<uint32>(i), spellId, static_cast<uint32>(i));
2842 attributes &= ~(SPELL_ATTR0_CU_NEGATIVE_EFF0 << i);
2843 }
2844 }
2845 }
2846
2847 if (attributes & SPELL_ATTR0_CU_POSITIVE)
2848 {
2849 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2850 {
2851 if (spellInfo->Effects[i].IsEffect())
2852 {
2853 continue;
2854 }
2855
2856 if ((attributes & (SPELL_ATTR0_CU_POSITIVE_EFF0 << i)))
2857 {
2858 LOG_ERROR("sql.sql", "Table `spell_custom_attr` has attribute SPELL_ATTR0_CU_POSITIVE_EFF{} for spell {} with no EFFECT_{}", uint32(i), spellId, uint32(i));
2859 attributes &= ~(SPELL_ATTR0_CU_POSITIVE_EFF0 << i);
2860 }
2861 }
2862 }
2863
2864 if ((attributes & SPELL_ATTR0_CU_FORCE_AURA_SAVING) && (attributes & SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED))
2865 {
2866 LOG_ERROR("sql.sql", "Table `spell_custom_attr` attribute1 field has attributes SPELL_ATTR1_CU_FORCE_AURA_SAVING and SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED which cannot stack for spell {}. Both attributes will be ignored.", spellId);
2868 }
2869
2870 spellInfo->AttributesCu |= attributes;
2871 }
2872 LOG_INFO("server.loading", ">> Loaded {} spell custom attributes from DB in {} ms", count, GetMSTimeDiffToNow(customAttrTime));
2873 }
2874
2875 // xinef: create talent spells set
2876 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
2877 {
2878 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
2879 if (!talentInfo)
2880 continue;
2881
2882 for (uint8 j = 0; j < MAX_TALENT_RANK; j++)
2883 if (uint32 spellId = talentInfo->RankID[j])
2884 if (SpellInfo const* spellInfo = GetSpellInfo(spellId))
2885 for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
2886 if (spellInfo->Effects[k].Effect == SPELL_EFFECT_LEARN_SPELL)
2887 if (SpellInfo const* learnSpell = GetSpellInfo(spellInfo->Effects[k].TriggerSpell))
2888 if (learnSpell->IsRanked() && !learnSpell->HasAttribute(SpellAttr0(SPELL_ATTR0_PASSIVE | SPELL_ATTR0_DO_NOT_DISPLAY)))
2889 mTalentSpellAdditionalSet.insert(learnSpell->Id);
2890 }
2891
2892 SpellInfo* spellInfo = nullptr;
2893 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2894 {
2895 spellInfo = mSpellInfoMap[i];
2896 if (!spellInfo)
2897 continue;
2898
2899 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
2900 {
2901 switch (spellInfo->Effects[j].ApplyAuraName)
2902 {
2904 {
2905 switch (spellInfo->Id)
2906 {
2907 // Exceptions
2908 case 44801: // Spectral Invisibility (Kalecgos, SWP)
2909 case 46021: // Spectral Realm (SWP)
2910 break;
2911 default:
2913 break;
2914 }
2915 }
2916 break;
2933 break;
2934 }
2935
2936 switch (spellInfo->Effects[j].ApplyAuraName)
2937 {
2938 case SPELL_AURA_CONVERT_RUNE: // Can't be saved - aura handler relies on calculated amount and changes it
2939 case SPELL_AURA_OPEN_STABLE: // No point in saving this, since the stable dialog can't be open on aura load anyway.
2940 // Auras that require both caster & target to be in world cannot be saved
2948 break;
2949 default:
2950 break;
2951 }
2952
2953 switch (spellInfo->Effects[j].ApplyAuraName)
2954 {
2962 break;
2965 break;
2966 default:
2967 break;
2968 }
2969
2970 switch (spellInfo->Effects[j].Effect)
2971 {
2977 case SPELL_EFFECT_HEAL:
2979 break;
2990 break;
2993 case SPELL_EFFECT_JUMP:
2996 spellInfo->AttributesCu |= SPELL_ATTR0_CU_CHARGE;
2997 break;
3000 break;
3005 {
3006 // only enchanting profession enchantments procs can stack
3008 {
3009 uint32 enchantId = spellInfo->Effects[j].MiscValue;
3010 SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId);
3011 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
3012 {
3013 if (enchant->type[s] != ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL)
3014 continue;
3015
3016 SpellInfo* procInfo = _GetSpellInfo(enchant->spellid[s]);
3017 if (!procInfo)
3018 continue;
3019
3020 // if proced directly from enchantment, not via proc aura
3021 // NOTE: Enchant Weapon - Blade Ward also has proc aura spell and is proced directly
3022 // however its not expected to stack so this check is good
3024 continue;
3025
3027 }
3028 }
3029 break;
3030 }
3031 }
3032 }
3033
3034 // Xinef: spells ignoring hit result should not be binary
3035 if (!spellInfo->HasAttribute(SPELL_ATTR3_ALWAYS_HIT))
3036 {
3037 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3038 {
3039 if (spellInfo->Effects[j].Effect)
3040 {
3041 switch (spellInfo->Effects[j].Effect)
3042 {
3050 continue;
3059 if (spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
3060 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE_PERCENT ||
3061 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_DUMMY ||
3062 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH ||
3063 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_HEALTH_FUNNEL ||
3064 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DUMMY)
3065 continue;
3066 [[fallthrough]];
3067 default:
3068 if (!(spellInfo->Effects[j].CalcValue() &&
3069 ((spellInfo->Effects[j].Effect == SPELL_EFFECT_INTERRUPT_CAST || spellInfo->HasAttribute(SPELL_ATTR0_CU_DONT_BREAK_STEALTH)) &&
3071 continue;
3072
3073 if (spellInfo->Id == 69649 || spellInfo->Id == 71056 || spellInfo->Id == 71057 || spellInfo->Id == 71058 ||
3074 spellInfo->Id == 73061 || spellInfo->Id == 73062 || spellInfo->Id == 73063 || spellInfo->Id == 73064)
3075 continue;
3076
3077 if (spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && (spellInfo->SpellFamilyFlags[0] & 0x20)) // Frostbolt
3078 continue;
3079
3080 if (spellInfo->Id == 55095) // Frost Fever
3081 continue;
3082
3083 if (spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK &&
3084 ((spellInfo->SpellFamilyFlags[1] & 0x40000) || (spellInfo->SpellFamilyFlags[0] & 0x4000))) // Haunt/Drain Soul
3085 continue;
3086
3088 break;
3089 }
3090 }
3091 }
3092 }
3093
3094 // pussywizard:
3095 if ((spellInfo->SchoolMask & SPELL_SCHOOL_MASK_NORMAL) && (spellInfo->SchoolMask & SPELL_SCHOOL_MASK_MAGIC))
3096 {
3097 spellInfo->SchoolMask &= ~SPELL_SCHOOL_MASK_NORMAL;
3099 }
3100
3101 if (!spellInfo->_IsPositiveEffect(EFFECT_0, false))
3103
3104 if (!spellInfo->_IsPositiveEffect(EFFECT_1, false))
3106
3107 if (!spellInfo->_IsPositiveEffect(EFFECT_2, false))
3109
3110 if (spellInfo->SpellVisual[0] == 3879)
3112
3113 switch (spellInfo->SpellFamilyName)
3114 {
3116 // Shout
3117 if (spellInfo->SpellFamilyFlags[0] & 0x20000 || spellInfo->SpellFamilyFlags[1] & 0x20)
3119 break;
3120 case SPELLFAMILY_DRUID:
3121 // Roar
3122 if (spellInfo->SpellFamilyFlags[0] & 0x8)
3124 break;
3125 case SPELLFAMILY_HUNTER:
3126 // Aspects
3127 if (spellInfo->GetCategory() == 47)
3128 {
3130 }
3131 // Aimed Shot
3132 if (spellInfo->SpellFamilyFlags[0] & 0x00020000)
3133 {
3135 }
3136 break;
3137 default:
3138 break;
3139 }
3140
3141 switch (spellInfo->Id)
3142 {
3143 // Xinef: additional spells which should be binary
3144 case 45145: // Snake Trap Effect
3146 break;
3147 case 1776: // Gouge
3148 case 1777:
3149 case 8629:
3150 case 11285:
3151 case 11286:
3152 case 12540:
3153 case 13579:
3154 case 24698:
3155 case 28456:
3156 case 29425:
3157 case 34940:
3158 case 36862:
3159 case 38764:
3160 case 38863:
3161 case 52743: // Head Smack
3163 break;
3164 case 53: // Backstab
3165 case 2589:
3166 case 2590:
3167 case 2591:
3168 case 7159:
3169 case 8627:
3170 case 8721:
3171 case 11279:
3172 case 11280:
3173 case 11281:
3174 case 15582:
3175 case 15657:
3176 case 22416:
3177 case 25300:
3178 case 26863:
3179 case 37685:
3180 case 48656:
3181 case 48657:
3182 case 703: // Garrote
3183 case 8631:
3184 case 8632:
3185 case 8633:
3186 case 11289:
3187 case 11290:
3188 case 26839:
3189 case 26884:
3190 case 48675:
3191 case 48676:
3192 case 5221: // Shred
3193 case 6800:
3194 case 8992:
3195 case 9829:
3196 case 9830:
3197 case 27001:
3198 case 27002:
3199 case 48571:
3200 case 48572:
3201 case 8676: // Ambush
3202 case 8724:
3203 case 8725:
3204 case 11267:
3205 case 11268:
3206 case 11269:
3207 case 27441:
3208 case 48689:
3209 case 48690:
3210 case 48691:
3211 case 6785: // Ravage
3212 case 6787:
3213 case 9866:
3214 case 9867:
3215 case 27005:
3216 case 48578:
3217 case 48579:
3218 case 21987: // Lash of Pain
3219 case 23959: // Test Stab R50
3220 case 24825: // Test Backstab
3221 case 58563: // Assassinate Restless Lookout
3222 case 63124: // quest There's Something About the Squire (13654)
3224 break;
3225 case 26029: // Dark Glare
3226 case 43140: // Flame Breath
3227 case 43215: // Flame Breath
3228 case 70461: // Coldflame Trap
3229 case 72133: // Pain and Suffering
3230 case 73788: // Pain and Suffering
3231 case 73789: // Pain and Suffering
3232 case 73790: // Pain and Suffering
3233 case 63293: // Mimiron - spinning damage
3234 case 68873: // Wailing Souls
3235 case 70324: // Wailing Souls
3236 case 64619: // Ulduar, Mimiron, Emergency Fire Bot, Water Spray
3238 break;
3239 case 58690: // Cyanigosa, Tail Sweep
3240 case 59283: // Cyanigosa, Tail Sweep
3242 break;
3243 case 24340: // Meteor
3244 case 26558: // Meteor
3245 case 28884: // Meteor
3246 case 36837: // Meteor
3247 case 38903: // Meteor
3248 case 41276: // Meteor
3249 case 57467: // Meteor
3250 case 26789: // Shard of the Fallen Star
3251 case 31436: // Malevolent Cleave
3252 case 40810: // Saber Lash
3253 case 43267: // Saber Lash
3254 case 43268: // Saber Lash
3255 case 42384: // Brutal Swipe
3256 case 45150: // Meteor Slash
3257 case 64688: // Sonic Screech
3258 case 72373: // Shared Suffering
3259 case 71904: // Chaos Bane
3260 case 70492: // Ooze Eruption
3261 case 72505: // Ooze Eruption
3262 case 72624: // Ooze Eruption
3263 case 72625: // Ooze Eruption
3264 // ONLY SPELLS WITH SPELLFAMILY_GENERIC and EFFECT_SCHOOL_DAMAGE, OR WEAPON_DMG_X
3265 case 66809: // Meteor Fists
3266 case 67331: // Meteor Fists
3267 case 66765: // Meteor Fists
3268 case 67333: // Meteor Fists
3270 break;
3271 case 18500: // Wing Buffet
3272 case 33086: // Wild Bite
3273 case 49749: // Piercing Blow
3274 case 52890: // Penetrating Strike
3275 case 53454: // Impale
3276 case 59446: // Impale
3277 case 62383: // Shatter
3278 case 64777: // Machine Gun
3279 case 65239: // Machine Gun
3280 case 69293: // Wing Buffet
3281 case 74439: // Machine Gun
3282 // Trial of the Crusader, Jaraxxus, Shivan Slash
3283 case 66378:
3284 case 67097:
3285 case 67098:
3286 case 67099:
3287 // Trial of the Crusader, Anub'arak, Impale
3288 case 65919:
3289 case 67858:
3290 case 67859:
3291 case 67860:
3292 case 63278: // Mark of the Faceless (General Vezax)
3293 case 64125: // Ulduar, Yogg-Saron, Squeeze
3294 case 64126: // Ulduar, Yogg-Saron, Squeeze
3295 case 62544: // Thrust (Argent Tournament)
3296 case 64588: // Thrust (Argent Tournament)
3297 case 66479: // Thrust (Argent Tournament)
3298 case 68505: // Thrust (Argent Tournament)
3299 case 62709: // Counterattack! (Argent Tournament)
3300 case 62626: // Break-Shield (Argent Tournament, Player)
3301 case 64590: // Break-Shield (Argent Tournament, Player)
3302 case 64342: // Break-Shield (Argent Tournament, NPC)
3303 case 64686: // Break-Shield (Argent Tournament, NPC)
3304 case 65147: // Break-Shield (Argent Tournament, NPC)
3305 case 68504: // Break-Shield (Argent Tournament, NPC)
3306 case 62874: // Charge (Argent Tournament, Player)
3307 case 68498: // Charge (Argent Tournament, Player)
3308 case 64591: // Charge (Argent Tournament, Player)
3309 case 63003: // Charge (Argent Tournament, NPC)
3310 case 63010: // Charge (Argent Tournament, NPC)
3311 case 68321: // Charge (Argent Tournament, NPC)
3312 case 72255: // Mark of the Fallen Champion (Deathbringer Saurfang)
3313 case 72444: // Mark of the Fallen Champion (Deathbringer Saurfang)
3314 case 72445: // Mark of the Fallen Champion (Deathbringer Saurfang)
3315 case 72446: // Mark of the Fallen Champion (Deathbringer Saurfang)
3316 case 72409: // Rune of Blood (Deathbringer Saurfang)
3317 case 72447: // Rune of Blood (Deathbringer Saurfang)
3318 case 72448: // Rune of Blood (Deathbringer Saurfang)
3319 case 72449: // Rune of Blood (Deathbringer Saurfang)
3320 case 49882: // Leviroth Self-Impale
3321 case 62775: // Ulduar: XT-002 Tympanic Tamparum
3323 break;
3324 case 64422: // Sonic Screech (Auriaya)
3327 break;
3328 case 72293: // Mark of the Fallen Champion (Deathbringer Saurfang)
3329 case 72347: // Lock Players and Tap Chest (Gunship Battle)
3331 break;
3332 default:
3333 break;
3334 case 63675: // Improved Devouring Plague
3335 case 17962: // Conflagrate
3336 case 32593: // Earth Shield aura
3337 case 32594: // Earth Shield aura
3338 case 49283: // Earth Shield aura
3339 case 49284: // Earth Shield aura
3340 case 50526: // Wandering Plague
3341 case 53353: // Chimera Shot - Serpent trigger
3342 case 52752: // Ancestral Awakening Heal
3344 break;
3345 case 65280: // Ulduar, Hodir, Singed
3346 case 28969: // Naxxramas, Crypt Guard, Acid Spit (10 normal)
3347 case 56098: // Naxxramas, Crypt Guard, Acid Spit (25 normal)
3348 case 27891: // Naxxramas, Sludge Belcher, Acidic Sludge (10 normal)
3349 case 54331: // Naxxramas, Sludge Belcher, Acidic Sludge (25 normal)
3350 case 29325: // Naxxramas, Stoneskin Gargoyle, Acid Volley (10 normal)
3351 case 54714: // Naxxramas, Stoneskin Gargoyle, Acid Volley (25 normal)
3352 case 65775: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (10 normal)
3353 case 67861: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (25 normal)
3354 case 67862: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (10 heroic)
3355 case 67863: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (25 heroic)
3356 case 55604: // Naxxramas, Unrelenting Trainee, Death Plague (10 normal)
3357 case 55645: // Naxxramas, Unrelenting Trainee, Death Plague (25 normal)
3358 case 67721: // Anub'arak, Nerubian Burrower, Expose Weakness (normal)
3359 case 67847: // Anub'arak, Nerubian Burrower, Expose Weakness (heroic)
3360 case 64638: // Ulduar, Winter Jormungar, Acidic Bite
3361 case 71157: // Icecrown Citadel, Plagued Zombie, Infected Wound
3362 case 72963: // Icecrown Citadel, Rot Worm, Flesh Rot (10 normal)
3363 case 72964: // Icecrown Citadel, Rot Worm, Flesh Rot (25 normal)
3364 case 72965: // Icecrown Citadel, Rot Worm, Flesh Rot (10 heroic)
3365 case 72966: // Icecrown Citadel, Rot Worm, Flesh Rot (25 heroic)
3366 case 72465: // Icecrown Citadel, Sindragosa, Respite for a Tormented Soul (weekly quest)
3367 case 45271: // Sunwell, Eredar Twins encounter, Dark Strike
3368 case 45347: // Sunwell, Eredar Twins encounter, Dark Touched
3369 case 45348: // Sunwell, Eredar Twins encounter, Flame Touched
3370 case 35859: // The Eye, Nether Vapor
3371 case 40520: // Black Temple, Shade Soul Channel
3372 case 40327: // Black Temple, Atrophy
3373 case 38449: // Serpentshrine Cavern, Blessing of the Tides
3374 case 38044: // Serpentshrine Cavern, Surge
3375 case 74507: // Ruby Sanctum, Siphoned Might
3376 case 49381: // Drak'tharon Keep, Consume
3377 case 59805: // Drak'tharon Keep, Consume
3378 case 55093: // Gundrak, Grip of Slad'ran
3379 case 30659: // Hellfire Ramparts, Fel Infusion
3380 case 54314: // Azjol'Nerub Drain Power
3381 case 59354: // Azjol'Nerub Drain Power
3382 case 34655: // Snake Trap, Deadly Poison
3383 case 11971: // Sunder Armor
3384 case 58567: // Player Sunder Armor
3385 case 12579: // Player Winter's Chill
3386 case 29306: // Naxxramas(Gluth's Zombies): Infected Wound
3387 case 61920: // Ulduar(Spellbreaker): Supercharge
3388 case 63978: // Ulduar(Rubble): Stone Nova
3389 case 15502: // Sunder Armor
3391 break;
3392 case 43138: // North Fleet Reservist Kill Credit
3394 break;
3395 case 6197: // Eagle Eye
3397 break;
3398 case 50315: // Disco Ball
3400 break;
3401 case 14183: // Premeditation
3403 break;
3404
3405 // Xinef: NOT CUSTOM, cant add in DBC CORRECTION because i need to swap effects, too much work to do there
3406 // Envenom
3407 case 32645:
3408 case 32684:
3409 case 57992:
3410 case 57993:
3411 {
3412 SpellEffectInfo info = spellInfo->Effects[EFFECT_0];
3413 spellInfo->Effects[EFFECT_0] = spellInfo->Effects[EFFECT_2];
3414 spellInfo->Effects[EFFECT_2] = info;
3415 break;
3416 }
3417
3418 // Xinef: Cooldown overwrites
3419 // Jotunheim Rapid-Fire Harpoon: Energy Reserve
3420 case 56585:
3421 spellInfo->RecoveryTime = 30000;
3422 spellInfo->_requireCooldownInfo = true;
3423 break;
3424 // Jotunheim Rapid-Fire Harpoon: Rapid-Fire Harpoon
3425 case 56570:
3426 spellInfo->RecoveryTime = 200;
3427 break;
3428 // Burst of Speed
3429 case 57493:
3430 spellInfo->RecoveryTime = 60000;
3431 spellInfo->_requireCooldownInfo = true;
3432 break;
3433 // Strafe Jotunheim Building
3434 case 7769:
3435 spellInfo->RecoveryTime = 1500;
3436 spellInfo->_requireCooldownInfo = true;
3437 break;
3438 case 44535: // Spirit Heal, abilities also have no cost
3439 spellInfo->Effects[EFFECT_0].MiscValue = 127;
3440 break;
3441 case 45537: // Cosmetic - Lightning Beam Channel
3443 break;
3444 }
3445
3446 if (spellInfo->Speed > 0.0f)
3447 {
3448 if (SpellVisualEntry const* spellVisual = sSpellVisualStore.LookupEntry(spellInfo->SpellVisual[0]))
3449 {
3450 if (spellVisual->HasMissile)
3451 {
3452 if (spellVisual->MissileModel == -4 || spellVisual->MissileModel == -5)
3453 {
3455 }
3456 }
3457 }
3458 }
3459
3460 spellInfo->_InitializeExplicitTargetMask();
3461
3462 if (sSpellMgr->HasSpellCooldownOverride(spellInfo->Id))
3463 {
3464 SpellCooldownOverride spellOverride = sSpellMgr->GetSpellCooldownOverride(spellInfo->Id);
3465
3466 if (spellInfo->RecoveryTime != spellOverride.RecoveryTime)
3467 {
3468 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3469 }
3470
3471 if (spellInfo->CategoryRecoveryTime != spellOverride.CategoryRecoveryTime)
3472 {
3473 spellInfo->CategoryRecoveryTime = spellOverride.CategoryRecoveryTime;
3474 }
3475
3476 if (spellInfo->StartRecoveryTime != spellOverride.StartRecoveryTime)
3477 {
3478 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3479 }
3480
3481 if (spellInfo->StartRecoveryCategory != spellOverride.StartRecoveryCategory)
3482 {
3483 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3484 }
3485 }
3486
3487 sScriptMgr->OnLoadSpellCustomAttr(spellInfo);
3488 }
3489
3490 // Xinef: addition for binary spells, ommit spells triggering other spells
3491 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3492 {
3493 spellInfo = mSpellInfoMap[i];
3494 if (!spellInfo)
3495 continue;
3496
3497 if (!(spellInfo->AttributesCu & SPELL_ATTR0_CU_BINARY_SPELL))
3498 continue;
3499
3500 bool allNonBinary = true;
3501 bool overrideAttr = false;
3502 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3503 {
3504 if (spellInfo->Effects[j].ApplyAuraName && spellInfo->Effects[j].TriggerSpell)
3505 {
3506 switch (spellInfo->Effects[j].ApplyAuraName)
3507 {
3511 if (SpellInfo const* triggerSpell = sSpellMgr->GetSpellInfo(spellInfo->Effects[j].TriggerSpell))
3512 {
3513 overrideAttr = true;
3514 if (triggerSpell->AttributesCu & SPELL_ATTR0_CU_BINARY_SPELL)
3515 allNonBinary = false;
3516 }
3517 }
3518 }
3519 }
3520
3521 if (overrideAttr && allNonBinary)
3522 spellInfo->AttributesCu &= ~SPELL_ATTR0_CU_BINARY_SPELL;
3523 }
3524
3525 LOG_INFO("server.loading", ">> Loaded SpellInfo Custom Attributes in {} ms", GetMSTimeDiffToNow(oldMSTime));
3526 LOG_INFO("server.loading", " ");
3527}
#define sScriptMgr
Definition: ScriptMgr.h:708
DBCStorage< SpellVisualEntry > sSpellVisualStore(SpellVisualfmt)
DBCStorage< TalentEntry > sTalentStore(TalentEntryfmt)
@ SPELL_AURA_PERIODIC_DAMAGE
Definition: SpellAuraDefines.h:66
@ SPELL_AURA_OBS_MOD_HEALTH
Definition: SpellAuraDefines.h:83
@ SPELL_AURA_PERIODIC_HEALTH_FUNNEL
Definition: SpellAuraDefines.h:125
@ SPELL_AURA_PERIODIC_MANA_LEECH
Definition: SpellAuraDefines.h:127
@ SPELL_AURA_MOD_POSSESS_PET
Definition: SpellAuraDefines.h:191
@ SPELL_AURA_CONVERT_RUNE
Definition: SpellAuraDefines.h:312
@ SPELL_AURA_MOD_FEAR
Definition: SpellAuraDefines.h:70
@ SPELL_AURA_OBS_MOD_POWER
Definition: SpellAuraDefines.h:84
@ SPELL_AURA_CONTROL_VEHICLE
Definition: SpellAuraDefines.h:299
@ SPELL_AURA_MOD_INVISIBILITY
Definition: SpellAuraDefines.h:81
@ SPELL_AURA_PERIODIC_DAMAGE_PERCENT
Definition: SpellAuraDefines.h:152
@ SPELL_AURA_MOD_RANGED_HASTE
Definition: SpellAuraDefines.h:203
@ SPELL_AURA_AOE_CHARM
Definition: SpellAuraDefines.h:240
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE
Definition: SpellAuraDefines.h:290
@ SPELL_AURA_PERIODIC_ENERGIZE
Definition: SpellAuraDefines.h:87
@ SPELL_AURA_MOD_INVISIBILITY_DETECT
Definition: SpellAuraDefines.h:82
@ SPELL_AURA_WATER_BREATHING
Definition: SpellAuraDefines.h:145
@ SPELL_AURA_PERIODIC_LEECH
Definition: SpellAuraDefines.h:116
@ SPELL_AURA_POWER_BURN
Definition: SpellAuraDefines.h:225
@ SPELL_AURA_OPEN_STABLE
Definition: SpellAuraDefines.h:355
@ SPELL_AURA_MOD_CONFUSE
Definition: SpellAuraDefines.h:68
@ SPELL_AURA_TRACK_CREATURES
Definition: SpellAuraDefines.h:107
@ SPELL_AURA_MOD_POSSESS
Definition: SpellAuraDefines.h:65
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT
Definition: SpellAuraDefines.h:111
@ SPELL_AURA_BIND_SIGHT
Definition: SpellAuraDefines.h:64
bool IsPartOfSkillLine(uint32 skillId, uint32 spellId)
Definition: SpellMgr.cpp:49
@ SPELL_ATTR0_CU_IGNORE_ARMOR
Definition: SpellInfo.h:191
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition: SpellInfo.h:192
@ SPELL_ATTR0_CU_ALLOW_INFLIGHT_TARGET
Definition: SpellInfo.h:194
@ SPELL_ATTR0_CU_ENCHANT_PROC
Definition: SpellInfo.h:176
@ SPELL_ATTR0_CU_NO_POSITIVE_TAKEN_BONUS
Definition: SpellInfo.h:197
@ SPELL_ATTR0_CU_FORCE_SEND_CATEGORY_COOLDOWNS
Definition: SpellInfo.h:204
@ SPELL_ATTR0_CU_DIRECT_DAMAGE
Definition: SpellInfo.h:184
@ SPELL_ATTR0_CU_POSITIVE
Definition: SpellInfo.h:211
@ SPELL_ATTR0_CU_FORCE_AURA_SAVING
Definition: SpellInfo.h:205
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition: SpellInfo.h:183
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition: SpellInfo.h:182
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition: SpellInfo.h:193
@ SPELL_ATTR0_CU_CONE_BACK
Definition: SpellInfo.h:177
@ SPELL_ATTR0_CU_SINGLE_AURA_STACK
Definition: SpellInfo.h:198
@ SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED
Definition: SpellInfo.h:200
@ SPELL_ATTR0_CU_NEGATIVE_EFF2
Definition: SpellInfo.h:190
@ SPELL_ATTR0_CU_AURA_CC
Definition: SpellInfo.h:181
@ SPELL_ATTR0_CU_NEGATIVE_EFF1
Definition: SpellInfo.h:189
@ SPELL_ATTR0_CU_CHARGE
Definition: SpellInfo.h:185
@ SPELL_ATTR0_CU_NEGATIVE
Definition: SpellInfo.h:210
@ SPELL_ATTR0_CU_NEEDS_AMMO_DATA
Definition: SpellInfo.h:195
@ SPELL_ATTR0_CU_POSITIVE_EFF0
Definition: SpellInfo.h:201
@ SPELL_ATTR0_CU_NEGATIVE_EFF0
Definition: SpellInfo.h:188
@ SPELL_ATTR0_CU_BINARY_SPELL
Definition: SpellInfo.h:196
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition: SpellInfo.h:179
@ SPELL_ATTR0_CU_SCHOOLMASK_NORMAL_WITH_MAGIC
Definition: SpellInfo.h:199
@ SPELL_ATTR0_CU_IGNORE_EVADE
Definition: SpellInfo.h:187
@ SPELL_ATTR0_CU_PICKPOCKET
Definition: SpellInfo.h:186
@ SPELL_ATTR0_CU_CONE_LINE
Definition: SpellInfo.h:178
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition: SpellInfo.h:180
@ SPELL_EFFECT_ENERGIZE_PCT
Definition: SharedDefines.h:915
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
Definition: SharedDefines.h:813
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition: SharedDefines.h:870
@ SPELL_EFFECT_ENCHANT_ITEM
Definition: SharedDefines.h:831
@ SPELL_EFFECT_HEALTH_LEECH
Definition: SharedDefines.h:787
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition: SharedDefines.h:836
@ SPELL_EFFECT_HEAL
Definition: SharedDefines.h:788
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
Definition: SharedDefines.h:899
@ SPELL_EFFECT_TRIGGER_SPELL
Definition: SharedDefines.h:842
@ SPELL_EFFECT_HEAL_MAX_HEALTH
Definition: SharedDefines.h:845
@ SPELL_EFFECT_APPLY_AREA_AURA_PET
Definition: SharedDefines.h:897
@ SPELL_EFFECT_PICKPOCKET
Definition: SharedDefines.h:849
@ SPELL_EFFECT_HEAL_MECHANICAL
Definition: SharedDefines.h:853
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
Definition: SharedDefines.h:809
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
Definition: SharedDefines.h:843
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition: SharedDefines.h:795
@ SPELL_EFFECT_PERSISTENT_AREA_AURA
Definition: SharedDefines.h:805
@ SPELL_EFFECT_ENERGIZE
Definition: SharedDefines.h:808
@ SPELL_EFFECT_POWER_DRAIN
Definition: SharedDefines.h:786
@ SPELL_EFFECT_SCHOOL_DAMAGE
Definition: SharedDefines.h:780
@ SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
Definition: SharedDefines.h:907
@ SPELL_EFFECT_HEAL_PCT
Definition: SharedDefines.h:914
@ SPELL_EFFECT_INTERRUPT_CAST
Definition: SharedDefines.h:846
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition: SharedDefines.h:934
@ SPELL_EFFECT_APPLY_AREA_AURA_OWNER
Definition: SharedDefines.h:921
@ SPELLFAMILY_WARLOCK
Definition: SharedDefines.h:3533
@ SPELLFAMILY_DRUID
Definition: SharedDefines.h:3535
SpellAttr0
Definition: SharedDefines.h:381
@ SPELL_ATTR0_DO_NOT_DISPLAY
Definition: SharedDefines.h:389
@ SKILL_ENCHANTING
Definition: SharedDefines.h:2954
#define MAX_TALENT_RANK
Definition: DBCStructure.h:1918
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition: DBCStructure.h:1838
@ ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL
Definition: DBCEnums.h:367
uint32 GetCategory() const
Definition: SpellInfo.cpp:870
uint32 AttributesCu
Definition: SpellInfo.h:332
bool _requireCooldownInfo
Definition: SpellInfo.h:403
std::array< uint32, 2 > SpellVisual
Definition: SpellInfo.h:379
uint32 CategoryRecoveryTime
Definition: SpellInfo.h:349
bool _IsPositiveEffect(uint8 effIndex, bool deep) const
Definition: SpellInfo.cpp:2619
uint32 StartRecoveryTime
Definition: SpellInfo.h:351
void _InitializeExplicitTargetMask()
Definition: SpellInfo.cpp:2591
bool HasAura(AuraType aura) const
Definition: SpellInfo.cpp:892
uint32 StartRecoveryCategory
Definition: SpellInfo.h:350
uint32 AuraInterruptFlags
Definition: SpellInfo.h:353
SpellInfo * _GetSpellInfo(uint32 spellId)
Definition: SpellMgr.h:760
uint32 spellid[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition: DBCStructure.h:1847
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition: DBCStructure.h:1844
Definition: DBCStructure.h:1871
Definition: DBCStructure.h:1923
std::array< uint32, MAX_TALENT_RANK > RankID
Definition: DBCStructure.h:1928

References _GetSpellInfo(), SpellInfo::_InitializeExplicitTargetMask(), SpellInfo::_IsPositiveEffect(), SpellInfo::_requireCooldownInfo, SpellInfo::AttributesCu, AURA_INTERRUPT_FLAG_CAST, SpellInfo::AuraInterruptFlags, SpellInfo::CategoryRecoveryTime, SpellCooldownOverride::CategoryRecoveryTime, EFFECT_0, EFFECT_1, EFFECT_2, SpellInfo::Effects, Field::Get(), SpellInfo::GetCategory(), getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), GetSpellInfoStoreSize(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), SpellInfo::Id, IsPartOfSkillLine(), ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL, LOG_ERROR, LOG_INFO, LOG_WARN, MAX_SPELL_EFFECTS, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, MAX_TALENT_RANK, mSpellInfoMap, mTalentSpellAdditionalSet, TalentEntry::RankID, SpellInfo::RecoveryTime, SpellCooldownOverride::RecoveryTime, SpellInfo::SchoolMask, SKILL_ENCHANTING, SpellInfo::Speed, SPELL_ATTR0_CU_ALLOW_INFLIGHT_TARGET, SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED, SPELL_ATTR0_CU_AURA_CC, SPELL_ATTR0_CU_BINARY_SPELL, SPELL_ATTR0_CU_CHARGE, SPELL_ATTR0_CU_CONE_BACK, SPELL_ATTR0_CU_CONE_LINE, SPELL_ATTR0_CU_DIRECT_DAMAGE, SPELL_ATTR0_CU_DONT_BREAK_STEALTH, SPELL_ATTR0_CU_ENCHANT_PROC, SPELL_ATTR0_CU_FORCE_AURA_SAVING, SPELL_ATTR0_CU_FORCE_SEND_CATEGORY_COOLDOWNS, SPELL_ATTR0_CU_IGNORE_ARMOR, SPELL_ATTR0_CU_IGNORE_EVADE, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_CU_NEGATIVE, SPELL_ATTR0_CU_NEGATIVE_EFF0, SPELL_ATTR0_CU_NEGATIVE_EFF1, SPELL_ATTR0_CU_NEGATIVE_EFF2, SPELL_ATTR0_CU_NO_INITIAL_THREAT, SPELL_ATTR0_CU_NO_POSITIVE_TAKEN_BONUS, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR0_CU_PICKPOCKET, SPELL_ATTR0_CU_POSITIVE, SPELL_ATTR0_CU_POSITIVE_EFF0, SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET, SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER, SPELL_ATTR0_CU_SCHOOLMASK_NORMAL_WITH_MAGIC, SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_ATTR0_CU_SINGLE_AURA_STACK, SPELL_ATTR0_DO_NOT_DISPLAY, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR0_PASSIVE, SPELL_ATTR3_ALWAYS_HIT, SPELL_AURA_AOE_CHARM, SPELL_AURA_BIND_SIGHT, SPELL_AURA_CONTROL_VEHICLE, SPELL_AURA_CONVERT_RUNE, SPELL_AURA_DUMMY, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_CONFUSE, SPELL_AURA_MOD_FEAR, SPELL_AURA_MOD_INVISIBILITY, SPELL_AURA_MOD_INVISIBILITY_DETECT, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_AURA_MOD_RANGED_HASTE, SPELL_AURA_MOD_STUN, SPELL_AURA_OBS_MOD_HEALTH, SPELL_AURA_OBS_MOD_POWER, SPELL_AURA_OPEN_STABLE, SPELL_AURA_PERIODIC_DAMAGE, SPELL_AURA_PERIODIC_DAMAGE_PERCENT, SPELL_AURA_PERIODIC_DUMMY, SPELL_AURA_PERIODIC_ENERGIZE, SPELL_AURA_PERIODIC_HEAL, SPELL_AURA_PERIODIC_HEALTH_FUNNEL, SPELL_AURA_PERIODIC_LEECH, SPELL_AURA_PERIODIC_MANA_LEECH, SPELL_AURA_PERIODIC_TRIGGER_SPELL, SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT, SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE, SPELL_AURA_POWER_BURN, SPELL_AURA_PROC_TRIGGER_SPELL, SPELL_AURA_TRACK_CREATURES, SPELL_AURA_WATER_BREATHING, SPELL_EFFECT_APPLY_AREA_AURA_ENEMY, SPELL_EFFECT_APPLY_AREA_AURA_FRIEND, SPELL_EFFECT_APPLY_AREA_AURA_OWNER, SPELL_EFFECT_APPLY_AREA_AURA_PARTY, SPELL_EFFECT_APPLY_AREA_AURA_PET, SPELL_EFFECT_APPLY_AREA_AURA_RAID, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_CHARGE, SPELL_EFFECT_CHARGE_DEST, SPELL_EFFECT_CREATE_ITEM, SPELL_EFFECT_ENCHANT_HELD_ITEM, SPELL_EFFECT_ENCHANT_ITEM, SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY, SPELL_EFFECT_ENERGIZE, SPELL_EFFECT_ENERGIZE_PCT, SPELL_EFFECT_HEAL, SPELL_EFFECT_HEAL_MAX_HEALTH, SPELL_EFFECT_HEAL_MECHANICAL, SPELL_EFFECT_HEAL_PCT, SPELL_EFFECT_HEALTH_LEECH, SPELL_EFFECT_INTERRUPT_CAST, SPELL_EFFECT_JUMP, SPELL_EFFECT_JUMP_DEST, SPELL_EFFECT_LEAP_BACK, SPELL_EFFECT_LEARN_SPELL, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_PERSISTENT_AREA_AURA, SPELL_EFFECT_PICKPOCKET, SPELL_EFFECT_POWER_BURN, SPELL_EFFECT_POWER_DRAIN, SPELL_EFFECT_SCHOOL_DAMAGE, SPELL_EFFECT_TRIGGER_SPELL, SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, SPELL_SCHOOL_MASK_NORMAL, SPELLFAMILY_DRUID, SPELLFAMILY_HUNTER, SPELLFAMILY_MAGE, SPELLFAMILY_WARLOCK, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellItemEnchantmentEntry::spellid, SpellInfo::SpellVisual, sScriptMgr, sSpellItemEnchantmentStore, sSpellMgr, sSpellVisualStore, sTalentStore, SpellInfo::StartRecoveryCategory, SpellCooldownOverride::StartRecoveryCategory, SpellInfo::StartRecoveryTime, SpellCooldownOverride::StartRecoveryTime, SpellItemEnchantmentEntry::type, and WorldDatabase.

◆ LoadSpellInfoStore()

void SpellMgr::LoadSpellInfoStore ( )
2692{
2693 uint32 oldMSTime = getMSTime();
2694
2696 mSpellInfoMap.resize(sSpellStore.GetNumRows(), nullptr);
2697
2698 for (SpellEntry const* spellEntry : sSpellStore)
2699 mSpellInfoMap[spellEntry->Id] = new SpellInfo(spellEntry);
2700
2701 for (uint32 spellIndex = 0; spellIndex < GetSpellInfoStoreSize(); ++spellIndex)
2702 {
2703 if (!mSpellInfoMap[spellIndex])
2704 continue;
2705
2706 for (SpellEffectInfo const& spellEffectInfo : mSpellInfoMap[spellIndex]->GetEffects())
2707 {
2708 //ASSERT(effect.EffectIndex < MAX_SPELL_EFFECTS, "MAX_SPELL_EFFECTS must be at least {}", effect.EffectIndex + 1);
2709 ASSERT(spellEffectInfo.Effect < TOTAL_SPELL_EFFECTS, "TOTAL_SPELL_EFFECTS must be at least {}", spellEffectInfo.Effect + 1);
2710 ASSERT(spellEffectInfo.ApplyAuraName < TOTAL_AURAS, "TOTAL_AURAS must be at least {}", spellEffectInfo.ApplyAuraName + 1);
2711 ASSERT(spellEffectInfo.TargetA.GetTarget() < TOTAL_SPELL_TARGETS, "TOTAL_SPELL_TARGETS must be at least {}", spellEffectInfo.TargetA.GetTarget() + 1);
2712 ASSERT(spellEffectInfo.TargetB.GetTarget() < TOTAL_SPELL_TARGETS, "TOTAL_SPELL_TARGETS must be at least {}", spellEffectInfo.TargetB.GetTarget() + 1);
2713 }
2714 }
2715
2716 LOG_INFO("server.loading", ">> Loaded Spell Custom Attributes in {} ms", GetMSTimeDiffToNow(oldMSTime));
2717 LOG_INFO("server.loading", " ");
2718}
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
@ TOTAL_AURAS
Definition: SpellAuraDefines.h:380
@ TOTAL_SPELL_EFFECTS
Definition: SharedDefines.h:943
@ TOTAL_SPELL_TARGETS
Definition: SharedDefines.h:1514
Definition: DBCStructure.h:1642

References ASSERT, getMSTime(), GetMSTimeDiffToNow(), GetSpellInfoStoreSize(), LOG_INFO, mSpellInfoMap, sSpellStore, TOTAL_AURAS, TOTAL_SPELL_EFFECTS, TOTAL_SPELL_TARGETS, and UnloadSpellInfoStore().

◆ LoadSpellLearnSkills()

void SpellMgr::LoadSpellLearnSkills ( )
1470{
1471 uint32 oldMSTime = getMSTime();
1472
1473 mSpellLearnSkills.clear(); // need for reload case
1474
1475 // search auto-learned skills and add its to map also for use in unlearn spells/talents
1476 uint32 dbc_count = 0;
1477 for (uint32 spell = 0; spell < GetSpellInfoStoreSize(); ++spell)
1478 {
1479 SpellInfo const* entry = GetSpellInfo(spell);
1480
1481 if (!entry)
1482 continue;
1483
1484 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1485 {
1486 SpellLearnSkillNode dbc_node;
1487 switch (entry->Effects[i].Effect)
1488 {
1489 case SPELL_EFFECT_SKILL:
1490 dbc_node.skill = entry->Effects[i].MiscValue;
1491 dbc_node.step = entry->Effects[i].CalcValue();
1492 if (dbc_node.skill != SKILL_RIDING)
1493 {
1494 dbc_node.value = 1;
1495 }
1496 else
1497 {
1498 dbc_node.value = dbc_node.step * 75;
1499 }
1500 dbc_node.maxvalue = dbc_node.step * 75;
1501 break;
1503 dbc_node.skill = SKILL_DUAL_WIELD;
1504 dbc_node.step = 1;
1505 dbc_node.value = 1;
1506 dbc_node.maxvalue = 1;
1507 break;
1508 default:
1509 continue;
1510 }
1511
1512 mSpellLearnSkills[spell] = dbc_node;
1513 ++dbc_count;
1514 break;
1515 }
1516 }
1517
1518 LOG_INFO("server.loading", ">> Loaded {} Spell Learn Skills From DBC in {} ms", dbc_count, GetMSTimeDiffToNow(oldMSTime));
1519 LOG_INFO("server.loading", " ");
1520}
@ SPELL_EFFECT_SKILL
Definition: SharedDefines.h:896
@ SPELL_EFFECT_DUAL_WIELD
Definition: SharedDefines.h:818
@ SKILL_DUAL_WIELD
Definition: SharedDefines.h:2888
@ SKILL_RIDING
Definition: SharedDefines.h:2991
Definition: SpellMgr.h:574
uint16 value
Definition: SpellMgr.h:577
uint16 step
Definition: SpellMgr.h:576
uint16 maxvalue
Definition: SpellMgr.h:578
uint16 skill
Definition: SpellMgr.h:575

References SpellInfo::Effects, getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), GetSpellInfoStoreSize(), LOG_INFO, MAX_SPELL_EFFECTS, SpellLearnSkillNode::maxvalue, mSpellLearnSkills, SpellLearnSkillNode::skill, SKILL_DUAL_WIELD, SKILL_RIDING, SPELL_EFFECT_DUAL_WIELD, SPELL_EFFECT_SKILL, SpellLearnSkillNode::step, and SpellLearnSkillNode::value.

◆ LoadSpellLinked()

void SpellMgr::LoadSpellLinked ( )
2254{
2255 uint32 oldMSTime = getMSTime();
2256
2257 mSpellLinkedMap.clear(); // need for reload case
2258
2259 // 0 1 2
2260 QueryResult result = WorldDatabase.Query("SELECT spell_trigger, spell_effect, type FROM spell_linked_spell");
2261 if (!result)
2262 {
2263 LOG_WARN("server.loading", ">> Loaded 0 linked spells. DB table `spell_linked_spell` is empty.");
2264 LOG_INFO("server.loading", " ");
2265 return;
2266 }
2267
2268 uint32 count = 0;
2269 do
2270 {
2271 Field* fields = result->Fetch();
2272
2273 int32 trigger = fields[0].Get<int32>();
2274 int32 effect = fields[1].Get<int32>();
2275 int32 type = fields[2].Get<uint8>();
2276
2277 SpellInfo const* spellInfo = GetSpellInfo(std::abs(trigger));
2278 if (!spellInfo)
2279 {
2280 LOG_ERROR("sql.sql", "Spell {} listed in `spell_linked_spell` does not exist", std::abs(trigger));
2281 continue;
2282 }
2283 spellInfo = GetSpellInfo(std::abs(effect));
2284 if (!spellInfo)
2285 {
2286 LOG_ERROR("sql.sql", "Spell {} listed in `spell_linked_spell` does not exist", std::abs(effect));
2287 continue;
2288 }
2289
2290 if (type) //we will find a better way when more types are needed
2291 {
2292 if (trigger > 0)
2293 trigger += SPELL_LINKED_MAX_SPELLS * type;
2294 else
2295 trigger -= SPELL_LINKED_MAX_SPELLS * type;
2296 }
2297 mSpellLinkedMap[trigger].push_back(effect);
2298
2299 ++count;
2300 } while (result->NextRow());
2301
2302 LOG_INFO("server.loading", ">> Loaded {} Linked Spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2303 LOG_INFO("server.loading", " ");
2304}
#define SPELL_LINKED_MAX_SPELLS
Definition: SpellMgr.h:92

References Field::Get(), getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), LOG_ERROR, LOG_INFO, LOG_WARN, mSpellLinkedMap, SPELL_LINKED_MAX_SPELLS, and WorldDatabase.

◆ LoadSpellMixology()

void SpellMgr::LoadSpellMixology ( )
2047{
2048 uint32 oldMSTime = getMSTime();
2049
2050 mSpellMixologyMap.clear(); // need for reload case
2051
2052 // 0 1
2053 QueryResult result = WorldDatabase.Query("SELECT entry, pctMod FROM spell_mixology");
2054 if (!result)
2055 {
2056 LOG_WARN("server.loading", ">> Loaded 0 mixology bonuses. DB table `spell_mixology` is empty.");
2057 LOG_INFO("server.loading", " ");
2058 return;
2059 }
2060
2061 uint32 count = 0;
2062 do
2063 {
2064 Field* fields = result->Fetch();
2065
2066 uint32 entry = fields[0].Get<uint32>();
2067
2068 if (!GetSpellInfo(entry))
2069 {
2070 LOG_ERROR("sql.sql", "Spell {} listed in `spell_mixology` does not exist", entry);
2071 continue;
2072 }
2073
2074 mSpellMixologyMap[entry] = fields[1].Get<float>();
2075 ++count;
2076 } while (result->NextRow());
2077
2078 LOG_INFO("server.loading", ">> Loaded {} Mixology Bonuses in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2079 LOG_INFO("server.loading", " ");
2080}

References Field::Get(), getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), LOG_ERROR, LOG_INFO, LOG_WARN, mSpellMixologyMap, and WorldDatabase.

◆ LoadSpellPetAuras()

void SpellMgr::LoadSpellPetAuras ( )
2105{
2106 uint32 oldMSTime = getMSTime();
2107
2108 mSpellPetAuraMap.clear(); // need for reload case
2109
2110 // 0 1 2 3
2111 QueryResult result = WorldDatabase.Query("SELECT spell, effectId, pet, aura FROM spell_pet_auras");
2112 if (!result)
2113 {
2114 LOG_WARN("server.loading", ">> Loaded 0 spell pet auras. DB table `spell_pet_auras` is empty.");
2115 LOG_INFO("server.loading", " ");
2116 return;
2117 }
2118
2119 uint32 count = 0;
2120 do
2121 {
2122 Field* fields = result->Fetch();
2123
2124 uint32 spell = fields[0].Get<uint32>();
2125 uint8 eff = fields[1].Get<uint8>();
2126 uint32 pet = fields[2].Get<uint32>();
2127 uint32 aura = fields[3].Get<uint32>();
2128
2129 SpellPetAuraMap::iterator itr = mSpellPetAuraMap.find((spell << 8) + eff);
2130 if (itr != mSpellPetAuraMap.end())
2131 itr->second.AddAura(pet, aura);
2132 else
2133 {
2134 SpellInfo const* spellInfo = GetSpellInfo(spell);
2135 if (!spellInfo)
2136 {
2137 LOG_ERROR("sql.sql", "Spell {} listed in `spell_pet_auras` does not exist", spell);
2138 continue;
2139 }
2140 if (spellInfo->Effects[eff].Effect != SPELL_EFFECT_DUMMY &&
2141 (spellInfo->Effects[eff].Effect != SPELL_EFFECT_APPLY_AURA ||
2142 spellInfo->Effects[eff].ApplyAuraName != SPELL_AURA_DUMMY))
2143 {
2144 LOG_ERROR("spells", "Spell {} listed in `spell_pet_auras` does not have dummy aura or dummy effect", spell);
2145 continue;
2146 }
2147
2148 SpellInfo const* spellInfo2 = GetSpellInfo(aura);
2149 if (!spellInfo2)
2150 {
2151 LOG_ERROR("sql.sql", "Aura {} listed in `spell_pet_auras` does not exist", aura);
2152 continue;
2153 }
2154
2155 PetAura pa(pet, aura, spellInfo->Effects[eff].TargetA.GetTarget() == TARGET_UNIT_PET, spellInfo->Effects[eff].CalcValue());
2156 mSpellPetAuraMap[(spell << 8) + eff] = pa;
2157 }
2158
2159 ++count;
2160 } while (result->NextRow());
2161
2162 LOG_INFO("server.loading", ">> Loaded {} Spell Pet Auras in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2163 LOG_INFO("server.loading", " ");
2164}
Definition: SpellMgr.h:470

References SpellInfo::Effects, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), LOG_ERROR, LOG_INFO, LOG_WARN, mSpellPetAuraMap, SPELL_AURA_DUMMY, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_DUMMY, TARGET_UNIT_PET, and WorldDatabase.

◆ LoadSpellProcEvents()

void SpellMgr::LoadSpellProcEvents ( )
1739{
1740 uint32 oldMSTime = getMSTime();
1741
1742 mSpellProcEventMap.clear(); // need for reload case
1743
1744 // 0 1 2 3 4 5 6 7 8 9 10 11
1745 QueryResult result = WorldDatabase.Query("SELECT entry, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, procFlags, procEx, procPhase, ppmRate, CustomChance, Cooldown FROM spell_proc_event");
1746 if (!result)
1747 {
1748 LOG_WARN("server.loading", ">> Loaded 0 spell proc event conditions. DB table `spell_proc_event` is empty.");
1749 return;
1750 }
1751
1752 uint32 count = 0;
1753
1754 do
1755 {
1756 Field* fields = result->Fetch();
1757
1758 int32 spellId = fields[0].Get<int32>();
1759
1760 bool allRanks = false;
1761 if (spellId < 0)
1762 {
1763 allRanks = true;
1764 spellId = -spellId;
1765 }
1766
1767 SpellInfo const* spellInfo = GetSpellInfo(spellId);
1768 if (!spellInfo)
1769 {
1770 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` does not exist", spellId);
1771 continue;
1772 }
1773
1774 if (allRanks)
1775 {
1776 if (!spellInfo->IsRanked())
1777 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` with all ranks, but spell has no ranks.", spellId);
1778
1779 if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId))
1780 {
1781 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` is not first rank of spell.", spellId);
1782 continue;
1783 }
1784 }
1785
1786 SpellProcEventEntry spellProcEvent;
1787
1788 spellProcEvent.schoolMask = fields[1].Get<int8>();
1789 spellProcEvent.spellFamilyName = fields[2].Get<uint16>();
1790 spellProcEvent.spellFamilyMask[0] = fields[3].Get<uint32>();
1791 spellProcEvent.spellFamilyMask[1] = fields[4].Get<uint32>();
1792 spellProcEvent.spellFamilyMask[2] = fields[5].Get<uint32>();
1793 spellProcEvent.procFlags = fields[6].Get<uint32>();
1794 spellProcEvent.procEx = fields[7].Get<uint32>();
1795 spellProcEvent.procPhase = fields[8].Get<uint32>();
1796 spellProcEvent.ppmRate = fields[9].Get<float>();
1797 spellProcEvent.customChance = fields[10].Get<float>();
1798 spellProcEvent.cooldown = fields[11].Get<uint32>();
1799
1800 // PROC_SPELL_PHASE_NONE is by default PROC_SPELL_PHASE_HIT
1801 if (spellProcEvent.procPhase == PROC_SPELL_PHASE_NONE)
1802 {
1803 spellProcEvent.procPhase = PROC_SPELL_PHASE_HIT;
1804 }
1805
1806 while (spellInfo)
1807 {
1808 if (mSpellProcEventMap.find(spellInfo->Id) != mSpellProcEventMap.end())
1809 {
1810 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` already has its first rank in table.", spellInfo->Id);
1811 break;
1812 }
1813
1814 if (!spellInfo->ProcFlags && !spellProcEvent.procFlags)
1815 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` probally not triggered spell", spellInfo->Id);
1816
1817 mSpellProcEventMap[spellInfo->Id] = spellProcEvent;
1818
1819 if (allRanks)
1820 spellInfo = spellInfo->GetNextRankSpell();
1821 else
1822 break;
1823 }
1824
1825 ++count;
1826 } while (result->NextRow());
1827
1828 LOG_INFO("server.loading", ">> Loaded {} Extra Spell Proc Event Conditions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1829 LOG_INFO("server.loading", " ");
1830}
std::uint16_t uint16
Definition: Define.h:108
@ PROC_SPELL_PHASE_NONE
Definition: SpellMgr.h:242
SpellInfo const * GetFirstRankSpell() const
Definition: SpellInfo.cpp:2500
bool IsRanked() const
Definition: SpellInfo.cpp:2488
uint32 ProcFlags
Definition: SpellInfo.h:355
SpellInfo const * GetNextRankSpell() const
Definition: SpellInfo.cpp:2512
Definition: SpellMgr.h:275
uint32 cooldown
Definition: SpellMgr.h:284
uint32 procPhase
Definition: SpellMgr.h:281
flag96 spellFamilyMask
Definition: SpellMgr.h:278
uint32 spellFamilyName
Definition: SpellMgr.h:277
uint32 procEx
Definition: SpellMgr.h:280
float ppmRate
Definition: SpellMgr.h:282
uint32 schoolMask
Definition: SpellMgr.h:276
float customChance
Definition: SpellMgr.h:283
uint32 procFlags
Definition: SpellMgr.h:279

References SpellProcEventEntry::cooldown, SpellProcEventEntry::customChance, Field::Get(), SpellInfo::GetFirstRankSpell(), getMSTime(), GetMSTimeDiffToNow(), SpellInfo::GetNextRankSpell(), GetSpellInfo(), SpellInfo::Id, SpellInfo::IsRanked(), LOG_ERROR, LOG_INFO, LOG_WARN, mSpellProcEventMap, SpellProcEventEntry::ppmRate, PROC_SPELL_PHASE_HIT, PROC_SPELL_PHASE_NONE, SpellProcEventEntry::procEx, SpellInfo::ProcFlags, SpellProcEventEntry::procFlags, SpellProcEventEntry::procPhase, SpellProcEventEntry::schoolMask, SpellProcEventEntry::spellFamilyMask, SpellProcEventEntry::spellFamilyName, and WorldDatabase.

◆ LoadSpellProcs()

void SpellMgr::LoadSpellProcs ( )
1833{
1834 uint32 oldMSTime = getMSTime();
1835
1836 mSpellProcMap.clear(); // need for reload case
1837
1838 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
1839 QueryResult result = WorldDatabase.Query("SELECT SpellId, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, ProcFlags, SpellTypeMask, SpellPhaseMask, HitMask, AttributesMask, ProcsPerMinute, Chance, Cooldown, Charges FROM spell_proc");
1840 if (!result)
1841 {
1842 LOG_WARN("server.loading", ">> Loaded 0 Spell Proc Conditions And Data. DB table `spell_proc` Is Empty.");
1843 LOG_INFO("server.loading", " ");
1844 return;
1845 }
1846
1847 uint32 count = 0;
1848 do
1849 {
1850 Field* fields = result->Fetch();
1851
1852 int32 spellId = fields[0].Get<int32>();
1853
1854 bool allRanks = false;
1855 if (spellId < 0)
1856 {
1857 allRanks = true;
1858 spellId = -spellId;
1859 }
1860
1861 SpellInfo const* spellInfo = GetSpellInfo(spellId);
1862 if (!spellInfo)
1863 {
1864 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` does not exist", spellId);
1865 continue;
1866 }
1867
1868 if (allRanks)
1869 {
1870 if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId))
1871 {
1872 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` is not first rank of spell.", fields[0].Get<int32>());
1873 continue;
1874 }
1875 }
1876
1877 SpellProcEntry baseProcEntry;
1878
1879 baseProcEntry.SchoolMask = fields[1].Get<int8>();
1880 baseProcEntry.SpellFamilyName = fields[2].Get<uint16>();
1881 baseProcEntry.SpellFamilyMask[0] = fields[3].Get<uint32>();
1882 baseProcEntry.SpellFamilyMask[1] = fields[4].Get<uint32>();
1883 baseProcEntry.SpellFamilyMask[2] = fields[5].Get<uint32>();
1884 baseProcEntry.ProcFlags = fields[6].Get<uint32>();
1885 baseProcEntry.SpellTypeMask = fields[7].Get<uint32>();
1886 baseProcEntry.SpellPhaseMask = fields[8].Get<uint32>();
1887 baseProcEntry.HitMask = fields[9].Get<uint32>();
1888 baseProcEntry.AttributesMask = fields[10].Get<uint32>();
1889 baseProcEntry.ProcsPerMinute = fields[11].Get<float>();
1890 baseProcEntry.Chance = fields[12].Get<float>();
1891 baseProcEntry.Cooldown = Milliseconds(fields[13].Get<uint32>());
1892 baseProcEntry.Charges = fields[14].Get<uint32>();
1893
1894 while (spellInfo)
1895 {
1896 if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end())
1897 {
1898 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` has duplicate entry in the table", spellId);
1899 break;
1900 }
1901 SpellProcEntry procEntry = SpellProcEntry(baseProcEntry);
1902
1903 // take defaults from dbcs
1904 if (!procEntry.ProcFlags)
1905 procEntry.ProcFlags = spellInfo->ProcFlags;
1906 if (!procEntry.Charges)
1907 procEntry.Charges = spellInfo->ProcCharges;
1908 if (!procEntry.Chance && !procEntry.ProcsPerMinute)
1909 procEntry.Chance = float(spellInfo->ProcChance);
1910
1911 // validate data
1912 if (procEntry.SchoolMask & ~SPELL_SCHOOL_MASK_ALL)
1913 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SchoolMask` set: {}", spellId, procEntry.SchoolMask);
1914 if (procEntry.SpellFamilyName && (procEntry.SpellFamilyName < 3 || procEntry.SpellFamilyName > 17 || procEntry.SpellFamilyName == 14 || procEntry.SpellFamilyName == 16))
1915 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellFamilyName` set: {}", spellId, procEntry.SpellFamilyName);
1916 if (procEntry.Chance < 0)
1917 {
1918 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `Chance` field", spellId);
1919 procEntry.Chance = 0;
1920 }
1921 if (procEntry.ProcsPerMinute < 0)
1922 {
1923 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `ProcsPerMinute` field", spellId);
1924 procEntry.ProcsPerMinute = 0;
1925 }
1926 if (procEntry.Chance == 0 && procEntry.ProcsPerMinute == 0)
1927 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} doesn't have `Chance` and `ProcsPerMinute` values defined, proc will not be triggered", spellId);
1928 if (procEntry.Charges > 99)
1929 {
1930 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has too big value in `Charges` field", spellId);
1931 procEntry.Charges = 99;
1932 }
1933 if (!procEntry.ProcFlags)
1934 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} doesn't have `ProcFlags` value defined, proc will not be triggered", spellId);
1935 if (procEntry.SpellTypeMask & ~PROC_SPELL_TYPE_MASK_ALL)
1936 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellTypeMask` set: {}", spellId, procEntry.SpellTypeMask);
1937 if (procEntry.SpellTypeMask && !(procEntry.ProcFlags & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK)))
1938 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has `SpellTypeMask` value defined, but it won't be used for defined `ProcFlags` value", spellId);
1939 if (!procEntry.SpellPhaseMask && procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK)
1940 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} doesn't have `SpellPhaseMask` value defined, but it's required for defined `ProcFlags` value, proc will not be triggered", spellId);
1942 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellPhaseMask` set: {}", spellId, procEntry.SpellPhaseMask);
1943 if (procEntry.SpellPhaseMask && !(procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK))
1944 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has `SpellPhaseMask` value defined, but it won't be used for defined `ProcFlags` value", spellId);
1945 if (procEntry.HitMask & ~PROC_HIT_MASK_ALL)
1946 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `HitMask` set: {}", spellId, procEntry.HitMask);
1947 if (procEntry.HitMask && !(procEntry.ProcFlags & TAKEN_HIT_PROC_FLAG_MASK || (procEntry.ProcFlags & DONE_HIT_PROC_FLAG_MASK && (!procEntry.SpellPhaseMask || procEntry.SpellPhaseMask & (PROC_SPELL_PHASE_HIT | PROC_SPELL_PHASE_FINISH)))))
1948 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has `HitMask` value defined, but it won't be used for defined `ProcFlags` and `SpellPhaseMask` values", spellId);
1949
1950 mSpellProcMap[spellInfo->Id] = procEntry;
1951
1952 if (allRanks)
1953 spellInfo = spellInfo->GetNextRankSpell();
1954 else
1955 break;
1956 }
1957 ++count;
1958 } while (result->NextRow());
1959
1960 LOG_INFO("server.loading", ">> Loaded {} spell proc conditions and data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1961 LOG_INFO("server.loading", " ");
1962}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:27
@ PROC_HIT_MASK_ALL
Definition: SpellMgr.h:266
@ PROC_SPELL_TYPE_MASK_ALL
Definition: SpellMgr.h:237
@ PROC_SPELL_PHASE_FINISH
Definition: SpellMgr.h:245
@ PROC_SPELL_PHASE_MASK_ALL
Definition: SpellMgr.h:246
@ SPELL_SCHOOL_MASK_ALL
Definition: SharedDefines.h:315
uint32 ProcCharges
Definition: SpellInfo.h:357
uint32 ProcChance
Definition: SpellInfo.h:356
Definition: SpellMgr.h:290
uint32 SpellFamilyName
Definition: SpellMgr.h:292
float ProcsPerMinute
Definition: SpellMgr.h:299
Milliseconds Cooldown
Definition: SpellMgr.h:301
uint32 Charges
Definition: SpellMgr.h:302
uint32 AttributesMask
Definition: SpellMgr.h:298
flag96 SpellFamilyMask
Definition: SpellMgr.h:293
uint32 HitMask
Definition: SpellMgr.h:297
uint32 SpellTypeMask
Definition: SpellMgr.h:295
uint32 ProcFlags
Definition: SpellMgr.h:294
uint32 SpellPhaseMask
Definition: SpellMgr.h:296
uint32 SchoolMask
Definition: SpellMgr.h:291
float Chance
Definition: SpellMgr.h:300

References SpellProcEntry::AttributesMask, SpellProcEntry::Chance, SpellProcEntry::Charges, SpellProcEntry::Cooldown, DONE_HIT_PROC_FLAG_MASK, Field::Get(), SpellInfo::GetFirstRankSpell(), getMSTime(), GetMSTimeDiffToNow(), SpellInfo::GetNextRankSpell(), GetSpellInfo(), SpellProcEntry::HitMask, SpellInfo::Id, LOG_ERROR, LOG_INFO, LOG_WARN, mSpellProcMap, PERIODIC_PROC_FLAG_MASK, PROC_HIT_MASK_ALL, PROC_SPELL_PHASE_FINISH, PROC_SPELL_PHASE_HIT, PROC_SPELL_PHASE_MASK_ALL, PROC_SPELL_TYPE_MASK_ALL, SpellInfo::ProcChance, SpellInfo::ProcCharges, SpellInfo::ProcFlags, SpellProcEntry::ProcFlags, SpellProcEntry::ProcsPerMinute, REQ_SPELL_PHASE_PROC_FLAG_MASK, SpellProcEntry::SchoolMask, SPELL_PROC_FLAG_MASK, SPELL_SCHOOL_MASK_ALL, SpellProcEntry::SpellFamilyMask, SpellProcEntry::SpellFamilyName, SpellProcEntry::SpellPhaseMask, SpellProcEntry::SpellTypeMask, TAKEN_HIT_PROC_FLAG_MASK, and WorldDatabase.

◆ LoadSpellRanks()

void SpellMgr::LoadSpellRanks ( )
1294{
1295 // cleanup data and load spell ranks for talents from dbc
1297
1298 uint32 oldMSTime = getMSTime();
1299
1300 // 0 1 2
1301 QueryResult result = WorldDatabase.Query("SELECT first_spell_id, spell_id, `rank` from spell_ranks ORDER BY first_spell_id, `rank`");
1302
1303 if (!result)
1304 {
1305 LOG_WARN("server.loading", ">> Loaded 0 spell rank records. DB table `spell_ranks` is empty.");
1306 LOG_INFO("server.loading", " ");
1307 return;
1308 }
1309
1310 uint32 count = 0;
1311 bool finished = false;
1312
1313 do
1314 {
1315 // spellid, rank
1316 std::list < std::pair < int32, int32 > > rankChain;
1317 int32 currentSpell = -1;
1318 int32 lastSpell = -1;
1319
1320 // fill one chain
1321 while (currentSpell == lastSpell && !finished)
1322 {
1323 Field* fields = result->Fetch();
1324
1325 currentSpell = fields[0].Get<uint32>();
1326 if (lastSpell == -1)
1327 lastSpell = currentSpell;
1328 uint32 spell_id = fields[1].Get<uint32>();
1329 uint32 rank = fields[2].Get<uint8>();
1330
1331 // don't drop the row if we're moving to the next rank
1332 if (currentSpell == lastSpell)
1333 {
1334 rankChain.push_back(std::make_pair(spell_id, rank));
1335 if (!result->NextRow())
1336 finished = true;
1337 }
1338 else
1339 break;
1340 }
1341 // check if chain is made with valid first spell
1342 SpellInfo const* first = GetSpellInfo(lastSpell);
1343 if (!first)
1344 {
1345 LOG_ERROR("sql.sql", "Spell rank identifier(first_spell_id) {} listed in `spell_ranks` does not exist!", lastSpell);
1346 continue;
1347 }
1348 // check if chain is long enough
1349 if (rankChain.size() < 2)
1350 {
1351 LOG_ERROR("sql.sql", "There is only 1 spell rank for identifier(first_spell_id) {} in `spell_ranks`, entry is not needed!", lastSpell);
1352 continue;
1353 }
1354 int32 curRank = 0;
1355 bool valid = true;
1356 // check spells in chain
1357 for (std::list<std::pair<int32, int32> >::iterator itr = rankChain.begin(); itr != rankChain.end(); ++itr)
1358 {
1359 SpellInfo const* spell = GetSpellInfo(itr->first);
1360 if (!spell)
1361 {
1362 LOG_ERROR("sql.sql", "Spell {} (rank {}) listed in `spell_ranks` for chain {} does not exist!", itr->first, itr->second, lastSpell);
1363 valid = false;
1364 break;
1365 }
1366 ++curRank;
1367 if (itr->second != curRank)
1368 {
1369 LOG_ERROR("sql.sql", "Spell {} (rank {}) listed in `spell_ranks` for chain {} does not have proper rank value(should be {})!", itr->first, itr->second, lastSpell, curRank);
1370 valid = false;
1371 break;
1372 }
1373 }
1374 if (!valid)
1375 continue;
1376 int32 prevRank = 0;
1377 // insert the chain
1378 std::list<std::pair<int32, int32> >::iterator itr = rankChain.begin();
1379 do
1380 {
1381 ++count;
1382 int32 addedSpell = itr->first;
1383 mSpellChains[addedSpell].first = GetSpellInfo(lastSpell);
1384 mSpellChains[addedSpell].last = GetSpellInfo(rankChain.back().first);
1385 mSpellChains[addedSpell].rank = itr->second;
1386 mSpellChains[addedSpell].prev = GetSpellInfo(prevRank);
1387 mSpellInfoMap[addedSpell]->ChainEntry = &mSpellChains[addedSpell];
1388 prevRank = addedSpell;
1389 ++itr;
1390 if (itr == rankChain.end())
1391 {
1392 mSpellChains[addedSpell].next = nullptr;
1393 break;
1394 }
1395 else
1396 mSpellChains[addedSpell].next = GetSpellInfo(itr->first);
1397 } while (true);
1398 } while (!finished);
1399
1400 LOG_INFO("server.loading", ">> Loaded {} spell rank records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1401 LOG_INFO("server.loading", " ");
1402}
void LoadSpellTalentRanks()
Definition: SpellMgr.cpp:1232

References Field::Get(), getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), LoadSpellTalentRanks(), LOG_ERROR, LOG_INFO, LOG_WARN, mSpellChains, mSpellInfoMap, and WorldDatabase.

◆ LoadSpellRequired()

void SpellMgr::LoadSpellRequired ( )
1405{
1406 uint32 oldMSTime = getMSTime();
1407
1408 mSpellsReqSpell.clear(); // need for reload case
1409 mSpellReq.clear(); // need for reload case
1410
1411 // 0 1
1412 QueryResult result = WorldDatabase.Query("SELECT spell_id, req_spell from spell_required");
1413
1414 if (!result)
1415 {
1416 LOG_WARN("server.loading", ">> Loaded 0 spell required records. DB table `spell_required` is empty.");
1417 LOG_INFO("server.loading", " ");
1418 return;
1419 }
1420
1421 uint32 count = 0;
1422 do
1423 {
1424 Field* fields = result->Fetch();
1425
1426 uint32 spellId = fields[0].Get<uint32>();
1427 uint32 spellReq = fields[1].Get<uint32>();
1428
1429 // check if chain is made with valid first spell
1430 SpellInfo const* spellInfo = GetSpellInfo(spellId);
1431 if (!spellInfo)
1432 {
1433 LOG_ERROR("sql.sql", "spell_id {} in `spell_required` table is not found in dbcs, skipped", spellId);
1434 continue;
1435 }
1436
1437 SpellInfo const* reqSpellInfo = GetSpellInfo(spellReq);
1438 if (!reqSpellInfo)
1439 {
1440 LOG_ERROR("sql.sql", "req_spell {} in `spell_required` table is not found in dbcs, skipped", spellReq);
1441 continue;
1442 }
1443
1444 if (GetFirstSpellInChain(spellId) == GetFirstSpellInChain(spellReq))
1445 {
1446 LOG_ERROR("sql.sql", "req_spell {} and spell_id {} in `spell_required` table are ranks of the same spell, entry not needed, skipped", spellReq, spellId);
1447 continue;
1448 }
1449
1450 if (IsSpellRequiringSpell(spellId, spellReq))
1451 {
1452 LOG_ERROR("sql.sql", "duplicated entry of req_spell {} and spell_id {} in `spell_required`, skipped", spellReq, spellId);
1453 continue;
1454 }
1455
1456 mSpellReq.insert (std::pair<uint32, uint32>(spellId, spellReq));
1457 mSpellsReqSpell.insert (std::pair<uint32, uint32>(spellReq, spellId));
1458 ++count;
1459
1460 // xinef: fill additionalTalentInfo data, currently Blessing of Sanctuary only
1461 if (GetTalentSpellCost(spellReq) > 0)
1462 mTalentSpellAdditionalSet.insert(spellId);
1463 } while (result->NextRow());
1464
1465 LOG_INFO("server.loading", ">> Loaded {} Spell Required Records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1466 LOG_INFO("server.loading", " ");
1467}
uint32 GetTalentSpellCost(uint32 spellId)
Definition: DBCStores.cpp:686
bool IsSpellRequiringSpell(uint32 spellid, uint32 req_spellid) const
Definition: SpellMgr.cpp:619

References Field::Get(), GetFirstSpellInChain(), getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), GetTalentSpellCost(), IsSpellRequiringSpell(), LOG_ERROR, LOG_INFO, LOG_WARN, mSpellReq, mSpellsReqSpell, mTalentSpellAdditionalSet, and WorldDatabase.

◆ LoadSpellSpecificAndAuraState()

void SpellMgr::LoadSpellSpecificAndAuraState ( )
2780{
2781 uint32 oldMSTime = getMSTime();
2782
2783 SpellInfo* spellInfo = nullptr;
2784 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2785 {
2786 spellInfo = mSpellInfoMap[i];
2787 if (!spellInfo)
2788 continue;
2789 spellInfo->_spellSpecific = spellInfo->LoadSpellSpecific();
2790 spellInfo->_auraState = spellInfo->LoadAuraState();
2791 }
2792
2793 LOG_INFO("server.loading", ">> Loaded Spell Specific And Aura State in {} ms", GetMSTimeDiffToNow(oldMSTime));
2794 LOG_INFO("server.loading", " ");
2795}
SpellSpecificType LoadSpellSpecific() const
Definition: SpellInfo.cpp:2141
AuraStateType LoadAuraState() const
Definition: SpellInfo.cpp:2064
AuraStateType _auraState
Definition: SpellInfo.h:398
SpellSpecificType _spellSpecific
Definition: SpellInfo.h:399

References SpellInfo::_auraState, SpellInfo::_spellSpecific, getMSTime(), GetMSTimeDiffToNow(), GetSpellInfoStoreSize(), SpellInfo::LoadAuraState(), SpellInfo::LoadSpellSpecific(), LOG_INFO, and mSpellInfoMap.

◆ LoadSpellTalentRanks()

void SpellMgr::LoadSpellTalentRanks ( )
1233{
1234 // cleanup core data before reload - remove reference to ChainNode from SpellInfo
1236
1237 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1238 {
1239 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
1240 if (!talentInfo)
1241 continue;
1242
1243 SpellInfo const* lastSpell = nullptr;
1244 for (uint8 rank = MAX_TALENT_RANK - 1; rank > 0; --rank)
1245 {
1246 if (talentInfo->RankID[rank])
1247 {
1248 lastSpell = GetSpellInfo(talentInfo->RankID[rank]);
1249 break;
1250 }
1251 }
1252
1253 if (!lastSpell)
1254 continue;
1255
1256 SpellInfo const* firstSpell = GetSpellInfo(talentInfo->RankID[0]);
1257 if (!firstSpell)
1258 {
1259 LOG_ERROR("sql.sql", "SpellMgr::LoadSpellTalentRanks: First Rank Spell {} for TalentEntry {} does not exist.", talentInfo->RankID[0], i);
1260 continue;
1261 }
1262
1263 SpellInfo const* prevSpell = nullptr;
1264 for (uint8 rank = 0; rank < MAX_TALENT_RANK; ++rank)
1265 {
1266 uint32 spellId = talentInfo->RankID[rank];
1267 if (!spellId)
1268 break;
1269
1270 SpellInfo const* currentSpell = GetSpellInfo(spellId);
1271 if (!currentSpell)
1272 {
1273 LOG_ERROR("sql.sql", "SpellMgr::LoadSpellTalentRanks: Spell {} (Rank: {}) for TalentEntry {} does not exist.", spellId, rank + 1, i);
1274 break;
1275 }
1276
1277 SpellChainNode node;
1278 node.first = firstSpell;
1279 node.last = lastSpell;
1280 node.rank = rank + 1;
1281
1282 node.prev = prevSpell;
1283 node.next = node.rank < MAX_TALENT_RANK ? GetSpellInfo(talentInfo->RankID[node.rank]) : nullptr;
1284
1285 mSpellChains[spellId] = node;
1286 mSpellInfoMap[spellId]->ChainEntry = &mSpellChains[spellId];
1287
1288 prevSpell = currentSpell;
1289 }
1290 }
1291}
SpellInfo const * last
Definition: SpellMgr.h:558
SpellInfo const * next
Definition: SpellMgr.h:556
uint8 rank
Definition: SpellMgr.h:559
SpellInfo const * first
Definition: SpellMgr.h:557
SpellInfo const * prev
Definition: SpellMgr.h:555
void UnloadSpellInfoChains()
Definition: SpellMgr.cpp:1224

References SpellChainNode::first, GetSpellInfo(), SpellChainNode::last, LOG_ERROR, MAX_TALENT_RANK, mSpellChains, mSpellInfoMap, SpellChainNode::next, SpellChainNode::prev, SpellChainNode::rank, TalentEntry::RankID, sTalentStore, and UnloadSpellInfoChains().

Referenced by LoadSpellRanks().

◆ LoadSpellTargetPositions()

void SpellMgr::LoadSpellTargetPositions ( )
1523{
1524 uint32 oldMSTime = getMSTime();
1525
1526 mSpellTargetPositions.clear(); // need for reload case
1527
1528 // 0 1 2 3 4 5 6
1529 QueryResult result = WorldDatabase.Query("SELECT ID, EffectIndex, MapID, PositionX, PositionY, PositionZ, Orientation FROM spell_target_position");
1530
1531 if (!result)
1532 {
1533 LOG_WARN("server.loading", ">> Loaded 0 spell target coordinates. DB table `spell_target_position` is empty.");
1534 LOG_INFO("server.loading", " ");
1535 return;
1536 }
1537
1538 uint32 count = 0;
1539 do
1540 {
1541 Field* fields = result->Fetch();
1542
1543 uint32 Spell_ID = fields[0].Get<uint32>();
1544
1545 SpellEffIndex effIndex = SpellEffIndex(fields[1].Get<uint8>());
1546
1548
1549 st.target_mapId = fields[2].Get<uint16>();
1550 st.target_X = fields[3].Get<float>();
1551 st.target_Y = fields[4].Get<float>();
1552 st.target_Z = fields[5].Get<float>();
1553 st.target_Orientation = fields[6].Get<float>();
1554
1555 MapEntry const* mapEntry = sMapStore.LookupEntry(st.target_mapId);
1556 if (!mapEntry)
1557 {
1558 LOG_ERROR("sql.sql", "Spell (Id: {}, effIndex: {}) target map (ID: {}) does not exist in `Map.dbc`.", Spell_ID, effIndex, st.target_mapId);
1559 continue;
1560 }
1561
1562 if (st.target_X == 0 && st.target_Y == 0 && st.target_Z == 0)
1563 {
1564 LOG_ERROR("sql.sql", "Spell (Id: {}, effIndex: {}) target coordinates not provided.", Spell_ID, effIndex);
1565 continue;
1566 }
1567
1568 SpellInfo const* spellInfo = GetSpellInfo(Spell_ID);
1569 if (!spellInfo)
1570 {
1571 LOG_ERROR("sql.sql", "Spell (ID:{}) listed in `spell_target_position` does not exist.", Spell_ID);
1572 continue;
1573 }
1574
1575 if (spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_DEST_DB || spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_DEST_DB)
1576 {
1577 std::pair<uint32, SpellEffIndex> key = std::make_pair(Spell_ID, effIndex);
1578 mSpellTargetPositions[key] = st;
1579 ++count;
1580 }
1581 else
1582 {
1583 LOG_ERROR("sql.sql", "Spell (Id: {}, effIndex: {}) listed in `spell_target_position` does not have target TARGET_DEST_DB (17).", Spell_ID, effIndex);
1584 continue;
1585 }
1586 } while (result->NextRow());
1587
1588 /*
1589 // Check all spells
1590 for (uint32 i = 1; i < GetSpellInfoStoreSize; ++i)
1591 {
1592 SpellInfo const* spellInfo = GetSpellInfo(i);
1593 if (!spellInfo)
1594 continue;
1595
1596 bool found = false;
1597 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
1598 {
1599 switch (spellInfo->Effects[j].TargetA)
1600 {
1601 case TARGET_DEST_DB:
1602 found = true;
1603 break;
1604 }
1605 if (found)
1606 break;
1607 switch (spellInfo->Effects[j].TargetB)
1608 {
1609 case TARGET_DEST_DB:
1610 found = true;
1611 break;
1612 }
1613 if (found)
1614 break;
1615 }
1616 if (found)
1617 {
1618 if (!sSpellMgr->GetSpellTargetPosition(i))
1619 LOG_DEBUG("spells.aura", "Spell (ID: {}) does not have record in `spell_target_position`", i);
1620 }
1621 }*/
1622
1623 LOG_INFO("server.loading", ">> Loaded {} Spell Teleport Coordinates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1624 LOG_INFO("server.loading", " ");
1625}
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
SpellEffIndex
Definition: SharedDefines.h:30
Definition: SpellMgr.h:396
float target_Z
Definition: SpellMgr.h:400
uint32 target_mapId
Definition: SpellMgr.h:397
float target_Y
Definition: SpellMgr.h:399
float target_Orientation
Definition: SpellMgr.h:401
float target_X
Definition: SpellMgr.h:398
Definition: DBCStructure.h:1325

References SpellInfo::Effects, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), LOG_ERROR, LOG_INFO, LOG_WARN, mSpellTargetPositions, sMapStore, TARGET_DEST_DB, SpellTargetPosition::target_mapId, SpellTargetPosition::target_Orientation, SpellTargetPosition::target_X, SpellTargetPosition::target_Y, SpellTargetPosition::target_Z, and WorldDatabase.

◆ LoadSpellThreats()

void SpellMgr::LoadSpellThreats ( )
2006{
2007 uint32 oldMSTime = getMSTime();
2008
2009 mSpellThreatMap.clear(); // need for reload case
2010
2011 // 0 1 2 3
2012 QueryResult result = WorldDatabase.Query("SELECT entry, flatMod, pctMod, apPctMod FROM spell_threat");
2013 if (!result)
2014 {
2015 LOG_WARN("server.loading", ">> Loaded 0 aggro generating spells. DB table `spell_threat` is empty.");
2016 LOG_INFO("server.loading", " ");
2017 return;
2018 }
2019
2020 uint32 count = 0;
2021 do
2022 {
2023 Field* fields = result->Fetch();
2024
2025 uint32 entry = fields[0].Get<uint32>();
2026
2027 if (!GetSpellInfo(entry))
2028 {
2029 LOG_ERROR("sql.sql", "Spell {} listed in `spell_threat` does not exist", entry);
2030 continue;
2031 }
2032
2033 SpellThreatEntry ste;
2034 ste.flatMod = fields[1].Get<int32>();
2035 ste.pctMod = fields[2].Get<float>();
2036 ste.apPctMod = fields[3].Get<float>();
2037
2038 mSpellThreatMap[entry] = ste;
2039 ++count;
2040 } while (result->NextRow());
2041
2042 LOG_INFO("server.loading", ">> Loaded {} SpellThreatEntries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2043 LOG_INFO("server.loading", " ");
2044}
Definition: SpellMgr.h:385
int32 flatMod
Definition: SpellMgr.h:386
float apPctMod
Definition: SpellMgr.h:388
float pctMod
Definition: SpellMgr.h:387

References SpellThreatEntry::apPctMod, SpellThreatEntry::flatMod, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), LOG_ERROR, LOG_INFO, LOG_WARN, mSpellThreatMap, SpellThreatEntry::pctMod, and WorldDatabase.

◆ SetSpellDifficultyId()

void SpellMgr::SetSpellDifficultyId ( uint32  spellId,
uint32  id 
)
486{
487 mSpellDifficultySearcherMap[spellId] = id;
488}

References mSpellDifficultySearcherMap.

◆ UnloadSpellInfoChains()

void SpellMgr::UnloadSpellInfoChains ( )
1225{
1226 for (SpellChainMap::iterator itr = mSpellChains.begin(); itr != mSpellChains.end(); ++itr)
1227 mSpellInfoMap[itr->first]->ChainEntry = nullptr;
1228
1229 mSpellChains.clear();
1230}

References mSpellChains, and mSpellInfoMap.

Referenced by LoadSpellTalentRanks().

◆ UnloadSpellInfoImplicitTargetConditionLists()

void SpellMgr::UnloadSpellInfoImplicitTargetConditionLists ( )
2771{
2772 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2773 {
2774 if (mSpellInfoMap[i])
2775 mSpellInfoMap[i]->_UnloadImplicitTargetConditionLists();
2776 }
2777}

References GetSpellInfoStoreSize(), and mSpellInfoMap.

◆ UnloadSpellInfoStore()

void SpellMgr::UnloadSpellInfoStore ( )
2763{
2764 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2765 delete mSpellInfoMap[i];
2766
2767 mSpellInfoMap.clear();
2768}

References GetSpellInfoStoreSize(), and mSpellInfoMap.

Referenced by LoadSpellInfoStore(), and ~SpellMgr().

Member Data Documentation

◆ mEnchantCustomAttr

EnchantCustomAttribute SpellMgr::mEnchantCustomAttr
private

◆ mPetDefaultSpellsMap

PetDefaultSpellsMap SpellMgr::mPetDefaultSpellsMap
private

◆ mPetLevelupSpellMap

PetLevelupSpellMap SpellMgr::mPetLevelupSpellMap
private

◆ mSkillLineAbilityMap

SkillLineAbilityMap SpellMgr::mSkillLineAbilityMap
private

◆ mSpellAreaForAreaMap

SpellAreaForAreaMap SpellMgr::mSpellAreaForAreaMap
private

◆ mSpellAreaForAuraMap

SpellAreaForAuraMap SpellMgr::mSpellAreaForAuraMap
private

◆ mSpellAreaForQuestEndMap

SpellAreaForQuestMap SpellMgr::mSpellAreaForQuestEndMap
private

◆ mSpellAreaForQuestMap

SpellAreaForQuestMap SpellMgr::mSpellAreaForQuestMap
private

◆ mSpellAreaMap

SpellAreaMap SpellMgr::mSpellAreaMap
private

◆ mSpellBonusMap

SpellBonusMap SpellMgr::mSpellBonusMap
private

◆ mSpellChains

◆ mSpellCooldownOverrideMap

SpellCooldownOverrideMap SpellMgr::mSpellCooldownOverrideMap
private

◆ mSpellDifficultySearcherMap

SpellDifficultySearcherMap SpellMgr::mSpellDifficultySearcherMap
private

◆ mSpellEnchantProcEventMap

SpellEnchantProcEventMap SpellMgr::mSpellEnchantProcEventMap
private

◆ mSpellGroupMap

◆ mSpellGroupStackMap

SpellGroupStackMap SpellMgr::mSpellGroupStackMap
private

◆ mSpellInfoMap

◆ mSpellLearnSkills

SpellLearnSkillMap SpellMgr::mSpellLearnSkills
private

◆ mSpellLinkedMap

SpellLinkedMap SpellMgr::mSpellLinkedMap
private

Referenced by GetSpellLinked(), and LoadSpellLinked().

◆ mSpellMixologyMap

SpellMixologyMap SpellMgr::mSpellMixologyMap
private

◆ mSpellPetAuraMap

SpellPetAuraMap SpellMgr::mSpellPetAuraMap
private

Referenced by GetPetAura(), and LoadSpellPetAuras().

◆ mSpellProcEventMap

SpellProcEventMap SpellMgr::mSpellProcEventMap
private

◆ mSpellProcMap

SpellProcMap SpellMgr::mSpellProcMap
private

◆ mSpellReq

SpellRequiredMap SpellMgr::mSpellReq
private

◆ mSpellsReqSpell

SpellsRequiringSpellMap SpellMgr::mSpellsReqSpell
private

◆ mSpellTargetPositions

SpellTargetPositionMap SpellMgr::mSpellTargetPositions
private

◆ mSpellThreatMap

SpellThreatMap SpellMgr::mSpellThreatMap
private

◆ mTalentSpellAdditionalSet

TalentAdditionalSet SpellMgr::mTalentSpellAdditionalSet
private