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.
 
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
355{
356}

◆ ~SpellMgr()

SpellMgr::~SpellMgr ( )
private
359{
361}
void UnloadSpellInfoStore()
Definition SpellMgr.cpp:2761

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
898{
899 // proc type doesn't match
900 if (!(eventInfo.GetTypeMask() & procEntry.ProcFlags))
901 return false;
902
903 // check XP or honor target requirement
904 if (procEntry.AttributesMask & PROC_ATTR_REQ_EXP_OR_HONOR)
905 if (Player* actor = eventInfo.GetActor()->ToPlayer())
906 if (eventInfo.GetActionTarget() && !actor->isHonorOrXPTarget(eventInfo.GetActionTarget()))
907 return false;
908
909 // always trigger for these types
911 return true;
912
913 // check school mask (if set) for other trigger types
914 if (procEntry.SchoolMask && !(eventInfo.GetSchoolMask() & procEntry.SchoolMask))
915 return false;
916
917 // check spell family name/flags (if set) for spells
919 {
920 if (procEntry.SpellFamilyName && (procEntry.SpellFamilyName != eventInfo.GetSpellInfo()->SpellFamilyName))
921 return false;
922
923 if (procEntry.SpellFamilyMask && !(procEntry.SpellFamilyMask & eventInfo.GetSpellInfo()->SpellFamilyFlags))
924 return false;
925 }
926
927 // check spell type mask (if set)
929 {
930 if (procEntry.SpellTypeMask && !(eventInfo.GetSpellTypeMask() & procEntry.SpellTypeMask))
931 return false;
932 }
933
934 // check spell phase mask
936 {
937 if (!(eventInfo.GetSpellPhaseMask() & procEntry.SpellPhaseMask))
938 return false;
939 }
940
941 // check hit mask (on taken hit or on done hit, but not on spell cast phase)
942 if ((eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK) || ((eventInfo.GetTypeMask() & DONE_HIT_PROC_FLAG_MASK) && !(eventInfo.GetSpellPhaseMask() & PROC_SPELL_PHASE_CAST)))
943 {
944 uint32 hitMask = procEntry.HitMask;
945 // get default values if hit mask not set
946 if (!hitMask)
947 {
948 // for taken procs allow normal + critical hits by default
949 if (eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK)
951 // for done procs allow normal + critical + absorbs by default
952 else
954 }
955 if (!(eventInfo.GetHitMask() & hitMask))
956 return false;
957 }
958
959 return true;
960}
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:201
Definition Player.h:1082
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:184
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
681{
682 uint32 spellid_1 = spellInfo1->GetFirstRankSpell()->Id;
683 uint32 spellid_2 = spellInfo2->GetFirstRankSpell()->Id;
684
685 uint32 groupId = GetSpellGroup(spellid_1);
686
688
689 // xinef: dunno why i added this
690 if (spellid_1 == spellid_2 && remove && !areaAura)
691 {
693 {
695 }
696
698 }
699
700 if (groupId > 0 && groupId == GetSpellGroup(spellid_2))
701 {
704 // xinef: first flags are used for elixir stacking rules
706 {
707 if (flag1 & flag2)
709 }
710 // xinef: check only flag1 (new spell)
715
716 return SpellGroupStackFlags(GetGroupStackFlags(groupId) | additionFlag);
717 }
718
720}
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:660
SpellGroupStackFlags GetGroupStackFlags(uint32 groupid) const
Definition SpellMgr.cpp:651
SpellGroupSpecialFlags GetSpellGroupSpecialFlags(uint32 spell_id) const
Definition SpellMgr.cpp:670

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:157

References GetSpellInfoStoreSize(), LOG_ERROR, and mSpellInfoMap.

◆ CheckSpellValid()

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

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.

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

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
555{
556 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
557 return node->first->Id;
558
559 return spell_id;
560}
SpellChainNode const * GetSpellChainNode(uint32 spell_id) const
Definition SpellMgr.cpp:545
Definition SpellMgr.h:554

References SpellChainNode::first, GetSpellChainNode(), and SpellInfo::Id.

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

◆ GetGroupStackFlags()

SpellGroupStackFlags SpellMgr::GetGroupStackFlags ( uint32  groupid) const
652{
653 SpellGroupStackMap::const_iterator itr = mSpellGroupStackMap.find(groupid);
654 if (itr != mSpellGroupStackMap.end())
655 return itr->second;
656
658}
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
563{
564 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
565 return node->last->Id;
566
567 return spell_id;
568}

References GetSpellChainNode().

◆ GetNextSpellInChain()

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

References GetSpellChainNode().

◆ GetPetAura()

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

References mSpellPetAuraMap.

◆ GetPetDefaultSpellsEntry()

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

References mPetDefaultSpellsMap.

◆ GetPetLevelupSpellList()

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

References mPetLevelupSpellMap.

◆ GetPrevSpellInChain()

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

References GetSpellChainNode().

◆ GetSetOfSpellsInSpellGroupWithFlag()

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

References mSpellGroupMap.

◆ GetSkillLineAbilityMapBounds()

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

References mSkillLineAbilityMap.

◆ GetSpellAreaForAreaMapBounds()

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

References mSpellAreaForAreaMap.

◆ GetSpellAreaForAuraMapBounds()

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

References mSpellAreaForAuraMap.

Referenced by LoadSpellAreas().

◆ GetSpellAreaForQuestEndMapBounds()

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

References mSpellAreaForQuestEndMap.

◆ GetSpellAreaForQuestMapBounds()

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

References mSpellAreaForQuestMap.

◆ GetSpellAreaMapBounds()

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

References mSpellAreaMap.

Referenced by LoadSpellAreas().

◆ GetSpellBonusData()

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

References GetFirstSpellInChain(), and mSpellBonusMap.

◆ GetSpellChainNode()

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

References mSpellChains.

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

◆ GetSpellCooldownOverride()

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

References mSpellCooldownOverrideMap.

◆ GetSpellDifficultyId()

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

References mSpellDifficultySearcherMap.

Referenced by GetSpellIdForDifficulty().

◆ GetSpellEnchantProcEvent()

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

References mSpellEnchantProcEventMap.

◆ GetSpellForDifficultyFromSpell()

SpellInfo const * SpellMgr::GetSpellForDifficultyFromSpell ( SpellInfo const *  spell,
Unit const *  caster 
) const
532{
533 uint32 newSpellId = GetSpellIdForDifficulty(spell->Id, caster);
534 SpellInfo const* newSpell = GetSpellInfo(newSpellId);
535 if (!newSpell)
536 {
537 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellForDifficultyFromSpell: spell {} not found. Check spelldifficulty_dbc!", newSpellId);
538 return spell;
539 }
540
541 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellForDifficultyFromSpell: Spell id for instance mode is {} (original {})", newSpell->Id, spell->Id);
542 return newSpell;
543}
#define LOG_DEBUG(filterType__,...)
Definition Log.h:169
uint32 Id
Definition SpellInfo.h:320
uint32 GetSpellIdForDifficulty(uint32 spellId, Unit const *caster) const
Definition SpellMgr.cpp:489
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
661{
662 uint32 first_rank = GetFirstSpellInChain(spell_id);
663 SpellGroupMap::const_iterator itr = mSpellGroupMap.find(first_rank);
664 if (itr != mSpellGroupMap.end())
665 return itr->second.groupId;
666
667 return 0;
668}

References GetFirstSpellInChain(), and mSpellGroupMap.

Referenced by CheckSpellGroupStackRules().

◆ GetSpellGroupSpecialFlags()

SpellGroupSpecialFlags SpellMgr::GetSpellGroupSpecialFlags ( uint32  spell_id) const
671{
672 uint32 first_rank = GetFirstSpellInChain(spell_id);
673 SpellGroupMap::const_iterator itr = mSpellGroupMap.find(first_rank);
674 if (itr != mSpellGroupMap.end())
675 return itr->second.specialFlags;
676
678}
@ 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
490{
491 if (!GetSpellInfo(spellId))
492 return spellId;
493
494 if (!caster || !caster->GetMap() || (!caster->GetMap()->IsDungeon() && !caster->GetMap()->IsBattleground()))
495 return spellId;
496
497 uint32 mode = uint32(caster->GetMap()->GetSpawnMode());
498 if (mode >= MAX_DIFFICULTY)
499 {
500 LOG_ERROR("spells", "SpellMgr::GetSpellIdForDifficulty: Incorrect Difficulty for spell {}.", spellId);
501 return spellId; //return source spell
502 }
503
504 uint32 difficultyId = GetSpellDifficultyId(spellId);
505 if (!difficultyId)
506 return spellId; //return source spell, it has only REGULAR_DIFFICULTY
507
508 SpellDifficultyEntry const* difficultyEntry = sSpellDifficultyStore.LookupEntry(difficultyId);
509 if (!difficultyEntry)
510 {
511 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellIdForDifficulty: SpellDifficultyEntry not found for spell {}. This should never happen.", spellId);
512 return spellId; //return source spell
513 }
514
515 if (difficultyEntry->SpellID[mode] <= 0 && mode > DUNGEON_DIFFICULTY_HEROIC)
516 {
517 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellIdForDifficulty: spell {} mode {} spell is nullptr, using mode {}", spellId, mode, mode - 2);
518 mode -= 2;
519 }
520
521 if (difficultyEntry->SpellID[mode] <= 0)
522 {
523 LOG_ERROR("sql.sql", "SpellMgr::GetSpellIdForDifficulty: spell {} mode {} spell is 0. Check spelldifficulty_dbc!", spellId, mode);
524 return spellId;
525 }
526
527 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellIdForDifficulty: spellid for spell {} in mode {} is {}", spellId, mode, difficultyEntry->SpellID[mode]);
528 return uint32(difficultyEntry->SpellID[mode]);
529}
@ DUNGEON_DIFFICULTY_HEROIC
Definition DBCEnums.h:270
#define MAX_DIFFICULTY
Definition DBCEnums.h:283
DBCStorage< SpellDifficultyEntry > sSpellDifficultyStore(SpellDifficultyfmt)
uint32 GetSpellDifficultyId(uint32 spellId) const
Definition SpellMgr.cpp:478
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
635{
636 SpellLearnSkillMap::const_iterator itr = mSpellLearnSkills.find(spell_id);
637 if (itr != mSpellLearnSkills.end())
638 return &itr->second;
639 else
640 return nullptr;
641}
SpellLearnSkillMap mSpellLearnSkills
Definition SpellMgr.h:799

References mSpellLearnSkills.

◆ GetSpellLinked()

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

References mSpellLinkedMap.

◆ GetSpellMixologyBonus()

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

References mSpellMixologyMap.

◆ GetSpellProcEntry()

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

References mSpellProcMap.

◆ GetSpellProcEvent()

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

References mSpellProcEventMap.

◆ GetSpellRank()

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

References GetSpellChainNode().

◆ GetSpellsRequiredForSpellBounds()

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

References mSpellReq.

◆ GetSpellsRequiringSpellBounds()

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

References mSpellsReqSpell.

Referenced by IsSpellRequiringSpell().

◆ GetSpellTargetPosition()

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

References mSpellTargetPositions.

◆ GetSpellThreatEntry()

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

References GetFirstSpellInChain(), and mSpellThreatMap.

◆ GetSpellWithRank()

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

References GetSpellChainNode(), and GetSpellWithRank().

Referenced by GetSpellWithRank().

◆ HasSpellCooldownOverride()

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

References mSpellCooldownOverrideMap.

◆ instance()

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

References instance().

Referenced by instance().

◆ IsAdditionalTalentSpell()

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

References mTalentSpellAdditionalSet.

◆ IsArenaAllowedEnchancment()

bool SpellMgr::IsArenaAllowedEnchancment ( uint32  ench_id) const
1025{
1026 return mEnchantCustomAttr[ench_id];
1027}
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

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

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

References GetSpellsRequiringSpellBounds().

Referenced by LoadSpellRequired().

◆ IsSpellValid()

◆ LoadEnchantCustomAttr()

void SpellMgr::LoadEnchantCustomAttr ( )
Todo:
: find a better check
2167{
2168 uint32 oldMSTime = getMSTime();
2169
2170 uint32 size = sSpellItemEnchantmentStore.GetNumRows();
2171 mEnchantCustomAttr.resize(size);
2172
2173 for (uint32 i = 0; i < size; ++i)
2174 mEnchantCustomAttr[i] = 0;
2175
2176 uint32 count = 0;
2177 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2178 {
2179 SpellInfo const* spellInfo = GetSpellInfo(i);
2180 if (!spellInfo)
2181 continue;
2182
2184 // Xinef: commented second part, fixes warlock enchants like firestone, spellstone
2185 if (!spellInfo->HasAttribute(SPELL_ATTR2_ENCHANT_OWN_ITEM_ONLY)/* || !spellInfo->HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFTED)*/)
2186 continue;
2187
2188 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
2189 {
2190 if (spellInfo->Effects[j].Effect == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY)
2191 {
2192 uint32 enchId = spellInfo->Effects[j].MiscValue;
2193 SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchId);
2194 if (!ench)
2195 continue;
2196 mEnchantCustomAttr[enchId] = true;
2197 ++count;
2198 break;
2199 }
2200 }
2201 }
2202
2203 LOG_INFO("server.loading", ">> Loaded {} Custom Enchant Attributes in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2204 LOG_INFO("server.loading", " ");
2205}
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
#define LOG_INFO(filterType__,...)
Definition Log.h:165
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition SharedDefines.h:832
@ SPELL_ATTR2_ENCHANT_OWN_ITEM_ONLY
Definition SharedDefines.h:469
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:131
uint32 getMSTime()
Definition Timer.h:103
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 ( )
2400{
2401 uint32 oldMSTime = getMSTime();
2402
2403 mPetDefaultSpellsMap.clear();
2404
2405 uint32 countCreature = 0;
2406 uint32 countData = 0;
2407
2408 CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
2409 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
2410 {
2411 if (!itr->second.PetSpellDataId)
2412 continue;
2413
2414 // for creature with PetSpellDataId get default pet spells from dbc
2415 CreatureSpellDataEntry const* spellDataEntry = sCreatureSpellDataStore.LookupEntry(itr->second.PetSpellDataId);
2416 if (!spellDataEntry)
2417 continue;
2418
2419 int32 petSpellsId = -int32(itr->second.PetSpellDataId);
2420 PetDefaultSpellsEntry petDefSpells;
2421 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2422 petDefSpells.spellid[j] = spellDataEntry->spellId[j];
2423
2424 if (LoadPetDefaultSpells_helper(&itr->second, petDefSpells))
2425 {
2426 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2427 ++countData;
2428 }
2429 }
2430
2431 LOG_INFO("server.loading", ">> Loaded Addition Spells For {} Pet Spell Data Entries in {} ms", countData, GetMSTimeDiffToNow(oldMSTime));
2432 LOG_INFO("server.loading", " ");
2433
2434 LOG_INFO("server.loading", "Loading Summonable Creature Templates...");
2435 oldMSTime = getMSTime();
2436
2437 // different summon spells
2438 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2439 {
2440 SpellInfo const* spellInfo = GetSpellInfo(i);
2441 if (!spellInfo)
2442 continue;
2443
2444 for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
2445 {
2446 if (spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON || spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON_PET)
2447 {
2448 uint32 creature_id = spellInfo->Effects[k].MiscValue;
2449 CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id);
2450 if (!cInfo)
2451 continue;
2452
2453 // already loaded
2454 if (cInfo->PetSpellDataId)
2455 continue;
2456
2457 // for creature without PetSpellDataId get default pet spells from creature_template
2458 int32 petSpellsId = cInfo->Entry;
2459 if (mPetDefaultSpellsMap.find(cInfo->Entry) != mPetDefaultSpellsMap.end())
2460 continue;
2461
2462 PetDefaultSpellsEntry petDefSpells;
2463 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2464 petDefSpells.spellid[j] = cInfo->spells[j];
2465
2466 if (LoadPetDefaultSpells_helper(cInfo, petDefSpells))
2467 {
2468 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2469 ++countCreature;
2470 }
2471 }
2472 }
2473 }
2474
2475 LOG_INFO("server.loading", ">> Loaded {} Summonable Creature emplates in {} ms", countCreature, GetMSTimeDiffToNow(oldMSTime));
2476 LOG_INFO("server.loading", " ");
2477}
std::unordered_map< uint32, CreatureTemplate > CreatureTemplateContainer
Definition CreatureData.h:292
DBCStorage< CreatureSpellDataEntry > sCreatureSpellDataStore(CreatureSpellDatafmt)
#define MAX_CREATURE_SPELL_DATA_SLOT
Definition DBCStructure.h:806
std::int32_t int32
Definition Define.h:103
@ SPELL_EFFECT_SUMMON_PET
Definition SharedDefines.h:834
@ SPELL_EFFECT_SUMMON
Definition SharedDefines.h:806
bool LoadPetDefaultSpells_helper(CreatureTemplate const *cInfo, PetDefaultSpellsEntry &petDefSpells)
Definition SpellMgr.cpp:2351
Definition DBCStructure.h:809
uint32 spellId[MAX_CREATURE_SPELL_DATA_SLOT]
Definition DBCStructure.h:811
Definition CreatureData.h:186
uint32 Entry
Definition CreatureData.h:187
uint32 spells[MAX_CREATURE_SPELLS]
Definition CreatureData.h:228
uint32 PetSpellDataId
Definition CreatureData.h:229
Definition SpellMgr.h:592
uint32 spellid[MAX_CREATURE_SPELL_DATA_SLOT]
Definition SpellMgr.h:593

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 ( )
2306{
2307 uint32 oldMSTime = getMSTime();
2308
2309 mPetLevelupSpellMap.clear(); // need for reload case
2310
2311 uint32 count = 0;
2312 uint32 family_count = 0;
2313
2314 for (uint32 i = 0; i < sCreatureFamilyStore.GetNumRows(); ++i)
2315 {
2316 CreatureFamilyEntry const* creatureFamily = sCreatureFamilyStore.LookupEntry(i);
2317 if (!creatureFamily) // not exist
2318 continue;
2319
2320 for (uint8 j = 0; j < 2; ++j)
2321 {
2322 if (!creatureFamily->skillLine[j])
2323 continue;
2324
2325 for (SkillLineAbilityEntry const* skillLine : GetSkillLineAbilitiesBySkillLine(creatureFamily->skillLine[j]))
2326 {
2327 if (skillLine->AcquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN)
2328 continue;
2329
2330 SpellInfo const* spell = GetSpellInfo(skillLine->Spell);
2331 if (!spell) // not exist or triggered or talent
2332 continue;
2333
2334 if (!spell->SpellLevel)
2335 continue;
2336
2337 PetLevelupSpellSet& spellSet = mPetLevelupSpellMap[creatureFamily->ID];
2338 if (spellSet.empty())
2339 ++family_count;
2340
2341 spellSet.insert(PetLevelupSpellSet::value_type(spell->SpellLevel, spell->Id));
2342 ++count;
2343 }
2344 }
2345 }
2346
2347 LOG_INFO("server.loading", ">> Loaded {} Pet Levelup And Default Spells For {} Families in {} ms", count, family_count, GetMSTimeDiffToNow(oldMSTime));
2348 LOG_INFO("server.loading", " ");
2349}
@ SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN
Definition DBCEnums.h:361
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
uint32 SpellLevel
Definition SpellInfo.h:360
Definition DBCStructure.h:753
uint32 ID
Definition DBCStructure.h:754
uint32 skillLine[2]
Definition DBCStructure.h:759
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 ( )
2082{
2083 uint32 oldMSTime = getMSTime();
2084
2085 mSkillLineAbilityMap.clear();
2086
2087 uint32 count = 0;
2088
2089 for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); ++i)
2090 {
2091 SkillLineAbilityEntry const* SkillInfo = sSkillLineAbilityStore.LookupEntry(i);
2092 if (!SkillInfo)
2093 continue;
2094
2095 mSkillLineAbilityMap.insert(SkillLineAbilityMap::value_type(SkillInfo->Spell, SkillInfo));
2096 ++count;
2097 }
2098
2099 LOG_INFO("server.loading", ">> Loaded {} SkillLineAbility MultiMap Data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2100 LOG_INFO("server.loading", " ");
2101}
DBCStorage< SkillLineAbilityEntry > sSkillLineAbilityStore(SkillLineAbilityfmt)
uint32 Spell
Definition DBCStructure.h:1601

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

◆ LoadSpellAreas()

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

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

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

◆ LoadSpellPetAuras()

void SpellMgr::LoadSpellPetAuras ( )
2104{
2105 uint32 oldMSTime = getMSTime();
2106
2107 mSpellPetAuraMap.clear(); // need for reload case
2108
2109 // 0 1 2 3
2110 QueryResult result = WorldDatabase.Query("SELECT spell, effectId, pet, aura FROM spell_pet_auras");
2111 if (!result)
2112 {
2113 LOG_WARN("server.loading", ">> Loaded 0 spell pet auras. DB table `spell_pet_auras` is empty.");
2114 LOG_INFO("server.loading", " ");
2115 return;
2116 }
2117
2118 uint32 count = 0;
2119 do
2120 {
2121 Field* fields = result->Fetch();
2122
2123 uint32 spell = fields[0].Get<uint32>();
2124 uint8 eff = fields[1].Get<uint8>();
2125 uint32 pet = fields[2].Get<uint32>();
2126 uint32 aura = fields[3].Get<uint32>();
2127
2128 SpellPetAuraMap::iterator itr = mSpellPetAuraMap.find((spell << 8) + eff);
2129 if (itr != mSpellPetAuraMap.end())
2130 itr->second.AddAura(pet, aura);
2131 else
2132 {
2133 SpellInfo const* spellInfo = GetSpellInfo(spell);
2134 if (!spellInfo)
2135 {
2136 LOG_ERROR("sql.sql", "Spell {} listed in `spell_pet_auras` does not exist", spell);
2137 continue;
2138 }
2139 if (spellInfo->Effects[eff].Effect != SPELL_EFFECT_DUMMY &&
2140 (spellInfo->Effects[eff].Effect != SPELL_EFFECT_APPLY_AURA ||
2141 spellInfo->Effects[eff].ApplyAuraName != SPELL_AURA_DUMMY))
2142 {
2143 LOG_ERROR("spells", "Spell {} listed in `spell_pet_auras` does not have dummy aura or dummy effect", spell);
2144 continue;
2145 }
2146
2147 SpellInfo const* spellInfo2 = GetSpellInfo(aura);
2148 if (!spellInfo2)
2149 {
2150 LOG_ERROR("sql.sql", "Aura {} listed in `spell_pet_auras` does not exist", aura);
2151 continue;
2152 }
2153
2154 PetAura pa(pet, aura, spellInfo->Effects[eff].TargetA.GetTarget() == TARGET_UNIT_PET, spellInfo->Effects[eff].CalcValue());
2155 mSpellPetAuraMap[(spell << 8) + eff] = pa;
2156 }
2157
2158 ++count;
2159 } while (result->NextRow());
2160
2161 LOG_INFO("server.loading", ">> Loaded {} Spell Pet Auras in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2162 LOG_INFO("server.loading", " ");
2163}
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 ( )
1738{
1739 uint32 oldMSTime = getMSTime();
1740
1741 mSpellProcEventMap.clear(); // need for reload case
1742
1743 // 0 1 2 3 4 5 6 7 8 9 10 11
1744 QueryResult result = WorldDatabase.Query("SELECT entry, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, procFlags, procEx, procPhase, ppmRate, CustomChance, Cooldown FROM spell_proc_event");
1745 if (!result)
1746 {
1747 LOG_WARN("server.loading", ">> Loaded 0 spell proc event conditions. DB table `spell_proc_event` is empty.");
1748 return;
1749 }
1750
1751 uint32 count = 0;
1752
1753 do
1754 {
1755 Field* fields = result->Fetch();
1756
1757 int32 spellId = fields[0].Get<int32>();
1758
1759 bool allRanks = false;
1760 if (spellId < 0)
1761 {
1762 allRanks = true;
1763 spellId = -spellId;
1764 }
1765
1766 SpellInfo const* spellInfo = GetSpellInfo(spellId);
1767 if (!spellInfo)
1768 {
1769 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` does not exist", spellId);
1770 continue;
1771 }
1772
1773 if (allRanks)
1774 {
1775 if (!spellInfo->IsRanked())
1776 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` with all ranks, but spell has no ranks.", spellId);
1777
1778 if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId))
1779 {
1780 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` is not first rank of spell.", spellId);
1781 continue;
1782 }
1783 }
1784
1785 SpellProcEventEntry spellProcEvent;
1786
1787 spellProcEvent.schoolMask = fields[1].Get<int8>();
1788 spellProcEvent.spellFamilyName = fields[2].Get<uint16>();
1789 spellProcEvent.spellFamilyMask[0] = fields[3].Get<uint32>();
1790 spellProcEvent.spellFamilyMask[1] = fields[4].Get<uint32>();
1791 spellProcEvent.spellFamilyMask[2] = fields[5].Get<uint32>();
1792 spellProcEvent.procFlags = fields[6].Get<uint32>();
1793 spellProcEvent.procEx = fields[7].Get<uint32>();
1794 spellProcEvent.procPhase = fields[8].Get<uint32>();
1795 spellProcEvent.ppmRate = fields[9].Get<float>();
1796 spellProcEvent.customChance = fields[10].Get<float>();
1797 spellProcEvent.cooldown = fields[11].Get<uint32>();
1798
1799 // PROC_SPELL_PHASE_NONE is by default PROC_SPELL_PHASE_HIT
1800 if (spellProcEvent.procPhase == PROC_SPELL_PHASE_NONE)
1801 {
1802 spellProcEvent.procPhase = PROC_SPELL_PHASE_HIT;
1803 }
1804
1805 while (spellInfo)
1806 {
1807 if (mSpellProcEventMap.find(spellInfo->Id) != mSpellProcEventMap.end())
1808 {
1809 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` already has its first rank in table.", spellInfo->Id);
1810 break;
1811 }
1812
1813 if (!spellInfo->ProcFlags && !spellProcEvent.procFlags)
1814 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` probally not triggered spell", spellInfo->Id);
1815
1816 mSpellProcEventMap[spellInfo->Id] = spellProcEvent;
1817
1818 if (allRanks)
1819 spellInfo = spellInfo->GetNextRankSpell();
1820 else
1821 break;
1822 }
1823
1824 ++count;
1825 } while (result->NextRow());
1826
1827 LOG_INFO("server.loading", ">> Loaded {} Extra Spell Proc Event Conditions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1828 LOG_INFO("server.loading", " ");
1829}
std::uint16_t uint16
Definition Define.h:108
@ PROC_SPELL_PHASE_NONE
Definition SpellMgr.h:242
SpellInfo const * GetFirstRankSpell() const
Definition SpellInfo.cpp:2501
bool IsRanked() const
Definition SpellInfo.cpp:2489
uint32 ProcFlags
Definition SpellInfo.h:355
SpellInfo const * GetNextRankSpell() const
Definition SpellInfo.cpp:2513
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 ( )
1832{
1833 uint32 oldMSTime = getMSTime();
1834
1835 mSpellProcMap.clear(); // need for reload case
1836
1837 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
1838 QueryResult result = WorldDatabase.Query("SELECT SpellId, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, ProcFlags, SpellTypeMask, SpellPhaseMask, HitMask, AttributesMask, ProcsPerMinute, Chance, Cooldown, Charges FROM spell_proc");
1839 if (!result)
1840 {
1841 LOG_WARN("server.loading", ">> Loaded 0 Spell Proc Conditions And Data. DB table `spell_proc` Is Empty.");
1842 LOG_INFO("server.loading", " ");
1843 return;
1844 }
1845
1846 uint32 count = 0;
1847 do
1848 {
1849 Field* fields = result->Fetch();
1850
1851 int32 spellId = fields[0].Get<int32>();
1852
1853 bool allRanks = false;
1854 if (spellId < 0)
1855 {
1856 allRanks = true;
1857 spellId = -spellId;
1858 }
1859
1860 SpellInfo const* spellInfo = GetSpellInfo(spellId);
1861 if (!spellInfo)
1862 {
1863 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` does not exist", spellId);
1864 continue;
1865 }
1866
1867 if (allRanks)
1868 {
1869 if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId))
1870 {
1871 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` is not first rank of spell.", fields[0].Get<int32>());
1872 continue;
1873 }
1874 }
1875
1876 SpellProcEntry baseProcEntry;
1877
1878 baseProcEntry.SchoolMask = fields[1].Get<int8>();
1879 baseProcEntry.SpellFamilyName = fields[2].Get<uint16>();
1880 baseProcEntry.SpellFamilyMask[0] = fields[3].Get<uint32>();
1881 baseProcEntry.SpellFamilyMask[1] = fields[4].Get<uint32>();
1882 baseProcEntry.SpellFamilyMask[2] = fields[5].Get<uint32>();
1883 baseProcEntry.ProcFlags = fields[6].Get<uint32>();
1884 baseProcEntry.SpellTypeMask = fields[7].Get<uint32>();
1885 baseProcEntry.SpellPhaseMask = fields[8].Get<uint32>();
1886 baseProcEntry.HitMask = fields[9].Get<uint32>();
1887 baseProcEntry.AttributesMask = fields[10].Get<uint32>();
1888 baseProcEntry.ProcsPerMinute = fields[11].Get<float>();
1889 baseProcEntry.Chance = fields[12].Get<float>();
1890 baseProcEntry.Cooldown = Milliseconds(fields[13].Get<uint32>());
1891 baseProcEntry.Charges = fields[14].Get<uint32>();
1892
1893 while (spellInfo)
1894 {
1895 if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end())
1896 {
1897 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` has duplicate entry in the table", spellId);
1898 break;
1899 }
1900 SpellProcEntry procEntry = SpellProcEntry(baseProcEntry);
1901
1902 // take defaults from dbcs
1903 if (!procEntry.ProcFlags)
1904 procEntry.ProcFlags = spellInfo->ProcFlags;
1905 if (!procEntry.Charges)
1906 procEntry.Charges = spellInfo->ProcCharges;
1907 if (!procEntry.Chance && !procEntry.ProcsPerMinute)
1908 procEntry.Chance = float(spellInfo->ProcChance);
1909
1910 // validate data
1911 if (procEntry.SchoolMask & ~SPELL_SCHOOL_MASK_ALL)
1912 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SchoolMask` set: {}", spellId, procEntry.SchoolMask);
1913 if (procEntry.SpellFamilyName && (procEntry.SpellFamilyName < 3 || procEntry.SpellFamilyName > 17 || procEntry.SpellFamilyName == 14 || procEntry.SpellFamilyName == 16))
1914 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellFamilyName` set: {}", spellId, procEntry.SpellFamilyName);
1915 if (procEntry.Chance < 0)
1916 {
1917 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `Chance` field", spellId);
1918 procEntry.Chance = 0;
1919 }
1920 if (procEntry.ProcsPerMinute < 0)
1921 {
1922 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `ProcsPerMinute` field", spellId);
1923 procEntry.ProcsPerMinute = 0;
1924 }
1925 if (procEntry.Chance == 0 && procEntry.ProcsPerMinute == 0)
1926 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} doesn't have `Chance` and `ProcsPerMinute` values defined, proc will not be triggered", spellId);
1927 if (procEntry.Charges > 99)
1928 {
1929 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has too big value in `Charges` field", spellId);
1930 procEntry.Charges = 99;
1931 }
1932 if (!procEntry.ProcFlags)
1933 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} doesn't have `ProcFlags` value defined, proc will not be triggered", spellId);
1934 if (procEntry.SpellTypeMask & ~PROC_SPELL_TYPE_MASK_ALL)
1935 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellTypeMask` set: {}", spellId, procEntry.SpellTypeMask);
1936 if (procEntry.SpellTypeMask && !(procEntry.ProcFlags & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK)))
1937 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);
1938 if (!procEntry.SpellPhaseMask && procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK)
1939 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);
1941 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellPhaseMask` set: {}", spellId, procEntry.SpellPhaseMask);
1942 if (procEntry.SpellPhaseMask && !(procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK))
1943 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);
1944 if (procEntry.HitMask & ~PROC_HIT_MASK_ALL)
1945 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `HitMask` set: {}", spellId, procEntry.HitMask);
1946 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)))))
1947 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);
1948
1949 mSpellProcMap[spellInfo->Id] = procEntry;
1950
1951 if (allRanks)
1952 spellInfo = spellInfo->GetNextRankSpell();
1953 else
1954 break;
1955 }
1956 ++count;
1957 } while (result->NextRow());
1958
1959 LOG_INFO("server.loading", ">> Loaded {} spell proc conditions and data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1960 LOG_INFO("server.loading", " ");
1961}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:27
@ SPELL_SCHOOL_MASK_ALL
Definition SharedDefines.h:315
@ 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
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 ( )
1293{
1294 // cleanup data and load spell ranks for talents from dbc
1296
1297 uint32 oldMSTime = getMSTime();
1298
1299 // 0 1 2
1300 QueryResult result = WorldDatabase.Query("SELECT first_spell_id, spell_id, `rank` from spell_ranks ORDER BY first_spell_id, `rank`");
1301
1302 if (!result)
1303 {
1304 LOG_WARN("server.loading", ">> Loaded 0 spell rank records. DB table `spell_ranks` is empty.");
1305 LOG_INFO("server.loading", " ");
1306 return;
1307 }
1308
1309 uint32 count = 0;
1310 bool finished = false;
1311
1312 do
1313 {
1314 // spellid, rank
1315 std::list < std::pair < int32, int32 > > rankChain;
1316 int32 currentSpell = -1;
1317 int32 lastSpell = -1;
1318
1319 // fill one chain
1320 while (currentSpell == lastSpell && !finished)
1321 {
1322 Field* fields = result->Fetch();
1323
1324 currentSpell = fields[0].Get<uint32>();
1325 if (lastSpell == -1)
1326 lastSpell = currentSpell;
1327 uint32 spell_id = fields[1].Get<uint32>();
1328 uint32 rank = fields[2].Get<uint8>();
1329
1330 // don't drop the row if we're moving to the next rank
1331 if (currentSpell == lastSpell)
1332 {
1333 rankChain.push_back(std::make_pair(spell_id, rank));
1334 if (!result->NextRow())
1335 finished = true;
1336 }
1337 else
1338 break;
1339 }
1340 // check if chain is made with valid first spell
1341 SpellInfo const* first = GetSpellInfo(lastSpell);
1342 if (!first)
1343 {
1344 LOG_ERROR("sql.sql", "Spell rank identifier(first_spell_id) {} listed in `spell_ranks` does not exist!", lastSpell);
1345 continue;
1346 }
1347 // check if chain is long enough
1348 if (rankChain.size() < 2)
1349 {
1350 LOG_ERROR("sql.sql", "There is only 1 spell rank for identifier(first_spell_id) {} in `spell_ranks`, entry is not needed!", lastSpell);
1351 continue;
1352 }
1353 int32 curRank = 0;
1354 bool valid = true;
1355 // check spells in chain
1356 for (std::list<std::pair<int32, int32> >::iterator itr = rankChain.begin(); itr != rankChain.end(); ++itr)
1357 {
1358 SpellInfo const* spell = GetSpellInfo(itr->first);
1359 if (!spell)
1360 {
1361 LOG_ERROR("sql.sql", "Spell {} (rank {}) listed in `spell_ranks` for chain {} does not exist!", itr->first, itr->second, lastSpell);
1362 valid = false;
1363 break;
1364 }
1365 ++curRank;
1366 if (itr->second != curRank)
1367 {
1368 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);
1369 valid = false;
1370 break;
1371 }
1372 }
1373 if (!valid)
1374 continue;
1375 int32 prevRank = 0;
1376 // insert the chain
1377 std::list<std::pair<int32, int32> >::iterator itr = rankChain.begin();
1378 do
1379 {
1380 ++count;
1381 int32 addedSpell = itr->first;
1382 mSpellChains[addedSpell].first = GetSpellInfo(lastSpell);
1383 mSpellChains[addedSpell].last = GetSpellInfo(rankChain.back().first);
1384 mSpellChains[addedSpell].rank = itr->second;
1385 mSpellChains[addedSpell].prev = GetSpellInfo(prevRank);
1386 mSpellInfoMap[addedSpell]->ChainEntry = &mSpellChains[addedSpell];
1387 prevRank = addedSpell;
1388 ++itr;
1389 if (itr == rankChain.end())
1390 {
1391 mSpellChains[addedSpell].next = nullptr;
1392 break;
1393 }
1394 else
1395 mSpellChains[addedSpell].next = GetSpellInfo(itr->first);
1396 } while (true);
1397 } while (!finished);
1398
1399 LOG_INFO("server.loading", ">> Loaded {} spell rank records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1400 LOG_INFO("server.loading", " ");
1401}
void LoadSpellTalentRanks()
Definition SpellMgr.cpp:1231

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

◆ LoadSpellRequired()

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

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

◆ LoadSpellSpecificAndAuraState()

void SpellMgr::LoadSpellSpecificAndAuraState ( )
2779{
2780 uint32 oldMSTime = getMSTime();
2781
2782 SpellInfo* spellInfo = nullptr;
2783 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2784 {
2785 spellInfo = mSpellInfoMap[i];
2786 if (!spellInfo)
2787 continue;
2788 spellInfo->_spellSpecific = spellInfo->LoadSpellSpecific();
2789 spellInfo->_auraState = spellInfo->LoadAuraState();
2790 }
2791
2792 LOG_INFO("server.loading", ">> Loaded Spell Specific And Aura State in {} ms", GetMSTimeDiffToNow(oldMSTime));
2793 LOG_INFO("server.loading", " ");
2794}
SpellSpecificType LoadSpellSpecific() const
Definition SpellInfo.cpp:2142
AuraStateType LoadAuraState() const
Definition SpellInfo.cpp:2065
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 ( )
1232{
1233 // cleanup core data before reload - remove reference to ChainNode from SpellInfo
1235
1236 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1237 {
1238 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
1239 if (!talentInfo)
1240 continue;
1241
1242 SpellInfo const* lastSpell = nullptr;
1243 for (uint8 rank = MAX_TALENT_RANK - 1; rank > 0; --rank)
1244 {
1245 if (talentInfo->RankID[rank])
1246 {
1247 lastSpell = GetSpellInfo(talentInfo->RankID[rank]);
1248 break;
1249 }
1250 }
1251
1252 if (!lastSpell)
1253 continue;
1254
1255 SpellInfo const* firstSpell = GetSpellInfo(talentInfo->RankID[0]);
1256 if (!firstSpell)
1257 {
1258 LOG_ERROR("sql.sql", "SpellMgr::LoadSpellTalentRanks: First Rank Spell {} for TalentEntry {} does not exist.", talentInfo->RankID[0], i);
1259 continue;
1260 }
1261
1262 SpellInfo const* prevSpell = nullptr;
1263 for (uint8 rank = 0; rank < MAX_TALENT_RANK; ++rank)
1264 {
1265 uint32 spellId = talentInfo->RankID[rank];
1266 if (!spellId)
1267 break;
1268
1269 SpellInfo const* currentSpell = GetSpellInfo(spellId);
1270 if (!currentSpell)
1271 {
1272 LOG_ERROR("sql.sql", "SpellMgr::LoadSpellTalentRanks: Spell {} (Rank: {}) for TalentEntry {} does not exist.", spellId, rank + 1, i);
1273 break;
1274 }
1275
1276 SpellChainNode node;
1277 node.first = firstSpell;
1278 node.last = lastSpell;
1279 node.rank = rank + 1;
1280
1281 node.prev = prevSpell;
1282 node.next = node.rank < MAX_TALENT_RANK ? GetSpellInfo(talentInfo->RankID[node.rank]) : nullptr;
1283
1284 mSpellChains[spellId] = node;
1285 mSpellInfoMap[spellId]->ChainEntry = &mSpellChains[spellId];
1286
1287 prevSpell = currentSpell;
1288 }
1289 }
1290}
void UnloadSpellInfoChains()
Definition SpellMgr.cpp:1223
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

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

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

References mSpellDifficultySearcherMap.

◆ UnloadSpellInfoChains()

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

References mSpellChains, and mSpellInfoMap.

Referenced by LoadSpellTalentRanks().

◆ UnloadSpellInfoImplicitTargetConditionLists()

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

References GetSpellInfoStoreSize(), and mSpellInfoMap.

◆ UnloadSpellInfoStore()

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

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

The documentation for this class was generated from the following files: