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:1081
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:1638
#define MAX_SPELL_EFFECTS
Definition DBCStructure.h:1636
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:1771
int32 SpellID[MAX_DIFFICULTY]
Definition DBCStructure.h:1773

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

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

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

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

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, SummonPropertiesEntry::Category, SpellInfo::CategoryEntry, DISPEL_MAGIC, DISPEL_NONE, DONE_HIT_PROC_FLAG_MASK, EFFECT_0, EFFECT_1, EFFECT_2, EFFECT_RADIUS_100_YARDS, EFFECT_RADIUS_10_YARDS, EFFECT_RADIUS_12_YARDS, EFFECT_RADIUS_150_YARDS, EFFECT_RADIUS_18_YARDS, EFFECT_RADIUS_1_YARD, EFFECT_RADIUS_200_YARDS, EFFECT_RADIUS_20_YARDS, EFFECT_RADIUS_25_YARDS, EFFECT_RADIUS_2_YARDS, EFFECT_RADIUS_3_YARDS, EFFECT_RADIUS_4_YARDS, EFFECT_RADIUS_50000_YARDS, EFFECT_RADIUS_500_YARDS, EFFECT_RADIUS_5_YARDS, EFFECT_RADIUS_6_YARDS, EFFECT_RADIUS_70_YARDS, EFFECT_RADIUS_7_YARDS, EFFECT_RADIUS_8_YARDS, SpellInfo::Effects, FORM_CAT, FORM_MOONKIN, FORM_TREE, FactionTemplateEntry::friendlyMask, SpellInfo::GetEffects(), getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), GetSpellInfoStoreSize(), FactionTemplateEntry::hostileMask, IN_MILLISECONDS, LOCK_KEY_NONE, LOG_INFO, VehicleSeatEntry::m_attachmentOffsetX, VehicleSeatEntry::m_attachmentOffsetY, VehicleSeatEntry::m_attachmentOffsetZ, VehicleSeatEntry::m_flags, AchievementEntry::mapID, MAX_SPELL_EFFECTS, MECHANIC_NONE, MECHANIC_SNARE, MECHANIC_STUN, mSpellInfoMap, POWER_MANA, PROC_FLAG_DONE_MELEE_AUTO_ATTACK, PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS, SpellInfo::RangeEntry, SpellRangeEntry::RangeMax, SpellInfo::RecoveryTime, FactionEntry::ReputationFlags, sAchievementStore, sAreaTableStore, CreatureDisplayInfoEntry::scale, sCreatureDisplayInfoStore, sFactionStore, sFactionTemplateStore, sGraveyard, sLockStore, SpellInfo::Speed, SPEED_CHARGE, SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD, SPELL_ATTR0_ALLOW_WHILE_SITTING, SPELL_ATTR0_AURA_IS_DEBUFF, SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_SINGLE_AURA_STACK, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_NO_AURA_CANCEL, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR0_NOT_SHAPESHIFTED, SPELL_ATTR0_PASSIVE, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_ATTR1_ALLOW_WHILE_STEALTHED, SPELL_ATTR1_EXCLUDE_CASTER, SPELL_ATTR1_IMMUNITY_PURGES_EFFECT, SPELL_ATTR1_NO_REDIRECTION, SPELL_ATTR1_NO_REFLECTION, SPELL_ATTR1_NO_THREAT, SPELL_ATTR2_ALLOW_DEAD_TARGET, SPELL_ATTR2_CANT_CRIT, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD, SPELL_ATTR3_ALWAYS_HIT, SPELL_ATTR3_CAN_PROC_FROM_PROCS, SPELL_ATTR3_COMPLETELY_BLOCKED, SPELL_ATTR3_DOT_STACKING_RULE, SPELL_ATTR3_IGNORE_CASTER_MODIFIERS, SPELL_ATTR3_ONLY_ON_PLAYER, SPELL_ATTR3_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_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_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_INTERRUPT_FLAG_INTERRUPT, 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:1917
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition DBCStructure.h:1837
#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:1846
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition DBCStructure.h:1843
Definition DBCStructure.h:1870
Definition DBCStructure.h:1922
std::array< uint32, MAX_TALENT_RANK > RankID
Definition DBCStructure.h:1927

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

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