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

#include "SpellMgr.h"

Public Member Functions

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

Static Public Member Functions

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

Private Member Functions

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

Private Attributes

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

Detailed Description

Constructor & Destructor Documentation

◆ SpellMgr()

SpellMgr::SpellMgr ( )
private
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}
std::uint8_t uint8
Definition: Define.h:109
#define MAX_SPELL_REAGENTS
Definition: DBCStructure.h:1638
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.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 sObjectMgr
Definition: ObjectMgr.h:1635
#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}
Definition: SpellMgr.h:554
SpellChainNode const * GetSpellChainNode(uint32 spell_id) const
Definition: SpellMgr.cpp:545

References GetSpellChainNode().

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
Definition: Spell.h:287
uint32 SchoolMask
Definition: SpellInfo.h:392

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

◆ IsSpellRequiringSpell()

bool SpellMgr::IsSpellRequiringSpell ( uint32  spellid,
uint32  req_spellid 
) const
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}
#define LOG_INFO(filterType__,...)
Definition: Log.h:165
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:131
uint32 getMSTime()
Definition: Timer.h:103
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition: SharedDefines.h:832
@ SPELL_ATTR2_ENCHANT_OWN_ITEM_ONLY
Definition: SharedDefines.h:469
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
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::int32_t int32
Definition: Define.h:103
#define MAX_CREATURE_SPELL_DATA_SLOT
Definition: DBCStructure.h:806
@ 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
std::unordered_map< uint32, CreatureTemplate > CreatureTemplateContainer
Definition: CreatureData.h:292
DBCStorage< CreatureSpellDataEntry > sCreatureSpellDataStore(CreatureSpellDatafmt)
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
Definition: DBCStructure.h:809
uint32 spellId[MAX_CREATURE_SPELL_DATA_SLOT]
Definition: DBCStructure.h:811

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
std::multimap< uint32, uint32 > PetLevelupSpellSet
Definition: SpellMgr.h:586
const std::vector< SkillLineAbilityEntry const * > & GetSkillLineAbilitiesBySkillLine(uint32 skillLine)
Definition: DBCStores.cpp:916
DBCStorage< CreatureFamilyEntry > sCreatureFamilyStore(CreatureFamilyfmt)
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}
#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
@ CONFIG_ICC_BUFF_ALLIANCE
Definition: IWorld.h:386
@ CONFIG_ICC_BUFF_HORDE
Definition: IWorld.h:385
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
#define sWorld
Definition: World.h:443
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
Definition: SpellMgr.h:527
uint32 spellId
Definition: SpellMgr.h:528
SpellAreaMapBounds GetSpellAreaMapBounds(uint32 spell_id) const
Definition: SpellMgr.cpp:1052
SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds(uint32 spell_id) const
Definition: SpellMgr.cpp:1067

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 });
1606
1608 31984, // Finger of Death
1609 35354 // Hand of Death
1610 }, [](SpellInfo* spellInfo)
1611 {
1612 // Spell doesn't need to ignore invulnerabilities
1613 spellInfo->Attributes = SPELL_ATTR0_IS_ABILITY;
1614 });
1615
1616 // Finger of Death
1617 ApplySpellFix({ 32111 }, [](SpellInfo* spellInfo)
1618 {
1619 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(0); // We only need the animation, no damage
1620 });
1621
1622 // Flame Breath, catapult spell
1623 ApplySpellFix({ 50989 }, [](SpellInfo* spellInfo)
1624 {
1625 spellInfo->Attributes &= ~SPELL_ATTR0_SCALES_WITH_CREATURE_LEVEL;
1626 });
1627
1628 // Koralon, Flaming Cinder
1629 ApplySpellFix({ 66690 }, [](SpellInfo* spellInfo)
1630 {
1631 // missing radius index
1632 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
1633 spellInfo->MaxAffectedTargets = 1;
1634 });
1635
1636 // Acid Volley
1637 ApplySpellFix({ 54714, 29325 }, [](SpellInfo* spellInfo)
1638 {
1639 spellInfo->MaxAffectedTargets = 1;
1640 });
1641
1642 // Summon Plagued Warrior
1643 ApplySpellFix({ 29237 }, [](SpellInfo* spellInfo)
1644 {
1645 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_DUMMY;
1646 spellInfo->Effects[EFFECT_1].Effect = spellInfo->Effects[EFFECT_2].Effect = 0;
1647 });
1648
1649 // Icebolt
1650 ApplySpellFix({ 28526 }, [](SpellInfo* spellInfo)
1651 {
1652 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
1653 });
1654
1655 // Infected Wound
1656 ApplySpellFix({ 29306 }, [](SpellInfo* spellInfo)
1657 {
1658 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
1659 });
1660
1661 // Hopeless
1662 ApplySpellFix({ 29125 }, [](SpellInfo* spellInfo)
1663 {
1664 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
1665 });
1666
1667 // Jagged Knife
1668 ApplySpellFix({ 55550 }, [](SpellInfo* spellInfo)
1669 {
1670 spellInfo->Attributes |= SPELL_ATTR0_USES_RANGED_SLOT;
1671 });
1672
1673 // Moorabi - Transformation
1674 ApplySpellFix({ 55098 }, [](SpellInfo* spellInfo)
1675 {
1676 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
1677 });
1678
1680 55521, // Poisoned Spear (Normal)
1681 58967, // Poisoned Spear (Heroic)
1682 55348, // Throw (Normal)
1683 58966 // Throw (Heroic)
1684 }, [](SpellInfo* spellInfo)
1685 {
1686 spellInfo->Attributes |= SPELL_ATTR0_USES_RANGED_SLOT;
1687 });
1688
1689 // Charged Chaotic rift aura, trigger
1690 ApplySpellFix({ 47737 }, [](SpellInfo* spellInfo)
1691 {
1692 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(37); // 50yd
1693 });
1694
1695 // Vanish
1696 ApplySpellFix({ 55964 }, [](SpellInfo* spellInfo)
1697 {
1698 spellInfo->Effects[EFFECT_1].Effect = 0;
1699 spellInfo->Effects[EFFECT_2].Effect = 0;
1700 });
1701
1702 // Trollgore - Summon Drakkari Invader
1703 ApplySpellFix({ 49456, 49457, 49458 }, [](SpellInfo* spellInfo)
1704 {
1705 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB);
1706 });
1707
1709 48278, // Paralyse
1710 47669 // Awaken subboss
1711 }, [](SpellInfo* spellInfo)
1712 {
1713 spellInfo->Effects[0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
1714 spellInfo->Effects[0].TargetB = SpellImplicitTargetInfo();
1715 });
1716
1717 // Flame Breath
1718 ApplySpellFix({ 47592 }, [](SpellInfo* spellInfo)
1719 {
1720 spellInfo->Effects[EFFECT_0].Amplitude = 200;
1721 });
1722
1723 // Skarvald, Charge
1724 ApplySpellFix({ 43651 }, [](SpellInfo* spellInfo)
1725 {
1726 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 0-50000yd
1727 });
1728
1729 // Ingvar the Plunderer, Woe Strike
1730 ApplySpellFix({ 42730 }, [](SpellInfo* spellInfo)
1731 {
1732 spellInfo->Effects[EFFECT_1].TriggerSpell = 42739;
1733 });
1734
1735 ApplySpellFix({ 59735 }, [](SpellInfo* spellInfo)
1736 {
1737 spellInfo->Effects[EFFECT_1].TriggerSpell = 59736;
1738 });
1739
1740 // Ingvar the Plunderer, Ingvar transform
1741 ApplySpellFix({ 42796 }, [](SpellInfo* spellInfo)
1742 {
1743 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
1744 });
1745
1747 42772, // Hurl Dagger (Normal)
1748 59685 // Hurl Dagger (Heroic)
1749 }, [](SpellInfo* spellInfo)
1750 {
1751 spellInfo->Attributes |= SPELL_ATTR0_USES_RANGED_SLOT;
1752 });
1753
1754 // Control Crystal Activation
1755 ApplySpellFix({ 57804 }, [](SpellInfo* spellInfo)
1756 {
1757 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(1);
1758 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1759 });
1760
1761 // Destroy Door Seal
1762 ApplySpellFix({ 58040 }, [](SpellInfo* spellInfo)
1763 {
1764 spellInfo->ChannelInterruptFlags &= ~(AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE);
1765 });
1766
1767 // Ichoron, Water Blast
1768 ApplySpellFix({ 54237, 59520 }, [](SpellInfo* spellInfo)
1769 {
1770 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
1771 });
1772
1773 // Krik'thir - Mind Flay
1774 ApplySpellFix({ 52586, 59367 }, [](SpellInfo* spellInfo)
1775 {
1776 spellInfo->ChannelInterruptFlags |= AURA_INTERRUPT_FLAG_MOVE;
1777 });
1778
1779 // Glare of the Tribunal
1780 ApplySpellFix({ 50988, 59870 }, [](SpellInfo* spellInfo)
1781 {
1782 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
1783 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1784 });
1785
1786 // Static Charge
1787 ApplySpellFix({ 50835, 59847 }, [](SpellInfo* spellInfo)
1788 {
1789 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
1790 });
1791
1792 // Lava Strike damage
1793 ApplySpellFix({ 57697 }, [](SpellInfo* spellInfo)
1794 {
1795 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
1796 });
1797
1798 // Lava Strike trigger
1799 ApplySpellFix({ 57578 }, [](SpellInfo* spellInfo)
1800 {
1801 spellInfo->MaxAffectedTargets = 1;
1802 });
1803
1804 // Gift of Twilight Shadow/Fire
1805 ApplySpellFix({ 57835, 58766 }, [](SpellInfo* spellInfo)
1806 {
1807 spellInfo->AttributesEx &= ~SPELL_ATTR1_IS_CHANNELED;
1808 });
1809
1810 // Pyrobuffet
1811 ApplySpellFix({ 57557 }, [](SpellInfo* spellInfo)
1812 {
1813 spellInfo->ExcludeTargetAuraSpell = 56911;
1814 });
1815
1816 // Arcane Barrage
1817 ApplySpellFix({ 56397 }, [](SpellInfo* spellInfo)
1818 {
1819 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
1820 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1821 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
1822 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
1823 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
1824 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo();
1825 });
1826
1828 55849, // Power Spark (ground +50% dmg aura)
1829 56438, // Arcane Overload (-50% dmg taken) - this is to prevent apply -> unapply -> apply ... dunno whether it's correct
1830 }, [](SpellInfo* spellInfo)
1831 {
1832 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
1833 });
1834
1835 // Vortex (Control Vehicle)
1836 ApplySpellFix({ 56263 }, [](SpellInfo* spellInfo)
1837 {
1838 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
1839 });
1840
1841 // Haste (Nexus Lord, increase run Speed of the disk)
1842 ApplySpellFix({ 57060 }, [](SpellInfo* spellInfo)
1843 {
1844 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_VEHICLE);
1845 });
1846
1847 // Arcane Overload
1848 ApplySpellFix({ 56430 }, [](SpellInfo* spellInfo)
1849 {
1850 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_TRIGGER_MISSILE;
1851 spellInfo->Effects[EFFECT_0].TriggerSpell = 56429;
1852 });
1853
1854 // Summon Arcane Bomb
1855 ApplySpellFix({ 56429 }, [](SpellInfo* spellInfo)
1856 {
1857 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
1858 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1859 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo();
1860 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
1861 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo();
1862 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo();
1863 });
1864
1865 // Destroy Platform Event
1866 ApplySpellFix({ 59099 }, [](SpellInfo* spellInfo)
1867 {
1868 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(22);
1869 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(15);
1870 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(22);
1871 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo(15);
1872 });
1873
1874 // Surge of Power (Phase 3)
1876 57407, // N
1877 }, [](SpellInfo* spellInfo)
1878 {
1879 spellInfo->MaxAffectedTargets = 1;
1880 spellInfo->InterruptFlags = 0;
1881 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS);
1882 spellInfo->AttributesEx4 |= SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING;
1883 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
1884 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
1885 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1886 });
1887
1888 // Surge of Power (Phase 3)
1890 60936 // H
1891 }, [](SpellInfo* spellInfo)
1892 {
1893 spellInfo->MaxAffectedTargets = 3;
1894 spellInfo->InterruptFlags = 0;
1895 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS);
1896 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
1897 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
1898 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1899 });
1900
1901 // Wyrmrest Drake - Life Burst
1902 ApplySpellFix({ 57143 }, [](SpellInfo* spellInfo)
1903 {
1904 spellInfo->Effects[EFFECT_0].Effect = 0;
1905 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo();
1906 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1907 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
1908 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
1909 spellInfo->Effects[EFFECT_1].PointsPerComboPoint = 2500;
1910 spellInfo->Effects[EFFECT_1].BasePoints = 2499;
1911 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(1);
1912 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1913 });
1914
1915 //Alexstrasza - Gift
1916 ApplySpellFix({ 61028 }, [](SpellInfo* spellInfo)
1917 {
1918 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
1919 });
1920
1921 // Vortex (freeze anim)
1922 ApplySpellFix({ 55883 }, [](SpellInfo* spellInfo)
1923 {
1924 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
1925 });
1926
1927 // Hurl Pyrite
1928 ApplySpellFix({ 62490 }, [](SpellInfo* spellInfo)
1929 {
1930 spellInfo->Effects[EFFECT_1].Effect = 0;
1931 });
1932
1933 // Ulduar, Mimiron, Magnetic Core (summon)
1934 // Meeting Stone Summon
1935 ApplySpellFix({ 64444, 23598 }, [](SpellInfo* spellInfo)
1936 {
1937 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
1938 });
1939
1940 // Ulduar, Mimiron, bomb bot explosion
1941 ApplySpellFix({ 63801 }, [](SpellInfo* spellInfo)
1942 {
1943 spellInfo->Effects[EFFECT_1].MiscValue = 17286;
1944 });
1945
1946 // Ulduar, Mimiron, Summon Flames Initial
1947 ApplySpellFix({ 64563 }, [](SpellInfo* spellInfo)
1948 {
1949 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1950 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
1951 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
1952 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1953 });
1954
1955 // Ulduar, Mimiron, Flames (damage)
1956 ApplySpellFix({ 64566 }, [](SpellInfo* spellInfo)
1957 {
1958 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1959 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
1960 });
1961
1962 // Ulduar, Hodir, Starlight
1963 ApplySpellFix({ 62807 }, [](SpellInfo* spellInfo)
1964 {
1965 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_1_YARD); // 1yd
1966 });
1967
1968 // Hodir Shatter Cache
1969 ApplySpellFix({ 62502 }, [](SpellInfo* spellInfo)
1970 {
1971 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
1972 });
1973
1974 // Ulduar, General Vezax, Mark of the Faceless
1975 ApplySpellFix({ 63278 }, [](SpellInfo* spellInfo)
1976 {
1977 spellInfo->Effects[EFFECT_0].Effect = 0;
1978 });
1979
1980 // Boom (XT-002)
1981 ApplySpellFix({ 62834 }, [](SpellInfo* spellInfo)
1982 {
1983 spellInfo->Effects[EFFECT_1].Effect = 0;
1984 });
1985
1986 // Supercharge
1987 ApplySpellFix({ 61920 }, [](SpellInfo* spellInfo)
1988 {
1989 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
1990 });
1991
1992 // Lightning Whirl
1993 ApplySpellFix({ 61916 }, [](SpellInfo* spellInfo)
1994 {
1995 spellInfo->MaxAffectedTargets = 3;
1996 });
1997
1998 ApplySpellFix({ 63482 }, [](SpellInfo* spellInfo)
1999 {
2000 spellInfo->MaxAffectedTargets = 8;
2001 });
2002
2003 // Stone Grip, remove absorb aura
2004 ApplySpellFix({ 62056, 63985 }, [](SpellInfo* spellInfo)
2005 {
2006 spellInfo->Effects[EFFECT_1].Effect = 0;
2007 });
2008
2009 // Sentinel Blast
2010 ApplySpellFix({ 64389, 64678 }, [](SpellInfo* spellInfo)
2011 {
2012 spellInfo->Dispel = DISPEL_MAGIC;
2013 });
2014
2015 // Potent Pheromones
2016 ApplySpellFix({ 62619 }, [](SpellInfo* spellInfo)
2017 {
2018 spellInfo->AttributesEx |= SPELL_ATTR1_IMMUNITY_PURGES_EFFECT;
2019 });
2020
2021 // Healthy spore summon periodic
2022 ApplySpellFix({ 62566 }, [](SpellInfo* spellInfo)
2023 {
2024 spellInfo->Effects[EFFECT_0].Amplitude = 2000;
2025 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PERIODIC_TRIGGER_SPELL;
2026 });
2027
2028 // Brightleaf Essence trigger
2029 ApplySpellFix({ 62968 }, [](SpellInfo* spellInfo)
2030 {
2031 spellInfo->Effects[EFFECT_1].Effect = 0; // duplicate
2032 });
2033
2034 // Potent Pheromones
2035 ApplySpellFix({ 64321 }, [](SpellInfo* spellInfo)
2036 {
2037 spellInfo->AttributesEx3 |= SPELL_ATTR3_ONLY_ON_PLAYER;
2038 spellInfo->AttributesEx |= SPELL_ATTR1_IMMUNITY_PURGES_EFFECT;
2039 });
2040
2041 // Lightning Orb Charged
2042 ApplySpellFix({ 62186 }, [](SpellInfo* spellInfo)
2043 {
2044 spellInfo->Effects[EFFECT_0].Amplitude = 5000; // Duration 5 secs, amplitude 8 secs...
2045 });
2046
2047 // Lightning Pillar
2048 ApplySpellFix({ 62976 }, [](SpellInfo* spellInfo)
2049 {
2050 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6);
2051 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(28); // 5 seconds, wrong DBC data?
2052 });
2053
2054 // Sif's Blizzard
2055 ApplySpellFix({ 62576, 62602 }, [](SpellInfo* spellInfo)
2056 {
2057 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_8_YARDS); // 8yd
2058 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_8_YARDS); // 8yd
2059 });
2060
2061 // Protective Gaze
2062 ApplySpellFix({ 64175 }, [](SpellInfo* spellInfo)
2063 {
2064 spellInfo->RecoveryTime = 25000;
2065 });
2066
2067 // Shadow Beacon
2068 ApplySpellFix({ 64465 }, [](SpellInfo* spellInfo)
2069 {
2070 spellInfo->Effects[EFFECT_0].TriggerSpell = 64467; // why do they need two script effects :/ (this one has visual effect)
2071 });
2072
2073 // Sanity
2074 ApplySpellFix({ 63050 }, [](SpellInfo* spellInfo)
2075 {
2076 spellInfo->AttributesEx6 |= SPELL_ATTR6_IGNORE_PHASE_SHIFT;
2077 });
2078
2079 // Shadow Nova
2080 ApplySpellFix({ 62714, 65209 }, [](SpellInfo* spellInfo)
2081 {
2082 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
2083 });
2084
2085 // Cosmic Smash (Algalon the Observer)
2086 ApplySpellFix({ 62293 }, [](SpellInfo* spellInfo)
2087 {
2088 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
2089 });
2090
2091 // Cosmic Smash (Algalon the Observer)
2092 ApplySpellFix({ 62311, 64596 }, [](SpellInfo* spellInfo)
2093 {
2094 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2095 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
2096 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
2097 });
2098
2099 // Constellation Phase Effect
2100 ApplySpellFix({ 65509 }, [](SpellInfo* spellInfo)
2101 {
2102 spellInfo->MaxAffectedTargets = 1;
2103 });
2104
2105 // Black Hole
2106 ApplySpellFix({ 62168, 65250, 62169 }, [](SpellInfo* spellInfo)
2107 {
2108 spellInfo->Attributes |= SPELL_ATTR0_AURA_IS_DEBUFF;
2109 });
2110
2111 // Ground Slam
2112 ApplySpellFix({ 62625 }, [](SpellInfo* spellInfo)
2113 {
2114 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
2115 });
2116
2117 // Onyxia's Lair, Onyxia, Flame Breath (TriggerSpell = 0 and spamming errors in console)
2118 ApplySpellFix({ 18435 }, [](SpellInfo* spellInfo)
2119 {
2120 spellInfo->Effects[EFFECT_1].Effect = 0;
2121 });
2122
2123 // Onyxia's Lair, Onyxia, Create Onyxia Spawner
2124 ApplySpellFix({ 17647 }, [](SpellInfo* spellInfo)
2125 {
2126 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(37);
2127 });
2128
2130 17646, // Onyxia's Lair, Onyxia, Summon Onyxia Whelp
2131 68968 // Onyxia's Lair, Onyxia, Summon Lair Guard
2132 }, [](SpellInfo* spellInfo)
2133 {
2134 spellInfo->Targets |= TARGET_FLAG_DEST_LOCATION;
2135 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2136 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
2137 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(5);
2138 });
2139
2140 // Onyxia's Lair, Onyxia, Eruption
2141 ApplySpellFix({ 17731, 69294 }, [](SpellInfo* spellInfo)
2142 {
2143 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_DUMMY;
2144 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(3);
2145 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_18_YARDS); // 18yd instead of 13yd to make sure all cracks erupt
2146 });
2147
2148 // Onyxia's Lair, Onyxia, Breath
2150 18576, 18578, 18579, 18580, 18581, 18582, 18583, 18609, 18611, 18612, 18613, 18614, 18615, 18616, 18584,
2151 18585, 18586, 18587, 18588, 18589, 18590, 18591, 18592, 18593, 18594, 18595, 18564, 18565, 18566, 18567,
2152 18568, 18569, 18570, 18571, 18572, 18573, 18574, 18575, 18596, 18597, 18598, 18599, 18600, 18601, 18602,
2153 18603, 18604, 18605, 18606, 18607, 18617, 18619, 18620, 18621, 18622, 18623, 18624, 18625, 18626, 18627,
2154 18628, 18618, 18351, 18352, 18353, 18354, 18355, 18356, 18357, 18358, 18359, 18360, 18361, 17086, 17087,
2155 17088, 17089, 17090, 17091, 17092, 17093, 17094, 17095, 17097, 22267, 22268, 21132, 21133, 21135, 21136,
2156 21137, 21138, 21139
2157 }, [](SpellInfo* spellInfo)
2158 {
2159 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(328); // 250ms
2160 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(1);
2161 if (spellInfo->Effects[EFFECT_1].Effect)
2162 {
2163 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
2164 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_PERIODIC_TRIGGER_SPELL;
2165 spellInfo->Effects[EFFECT_1].Amplitude = ((spellInfo->CastTimeEntry == sSpellCastTimesStore.LookupEntry(170)) ? 50 : 215);
2166 }
2167 });
2168
2170 48760, // Oculus, Teleport to Coldarra DND
2171 49305 // Oculus, Teleport to Boss 1 DND
2172 }, [](SpellInfo* spellInfo)
2173 {
2174 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
2175 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(17);
2176 });
2177
2178 // Oculus, Drake spell Stop Time
2179 ApplySpellFix({ 49838 }, [](SpellInfo* spellInfo)
2180 {
2181 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
2182 spellInfo->ExcludeTargetAuraSpell = 51162; // exclude planar shift
2183 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_150_YARDS);
2184 });
2185
2186 // Oculus, Varos Cloudstrider, Energize Cores
2187 ApplySpellFix({ 61407, 62136, 56251, 54069 }, [](SpellInfo* spellInfo)
2188 {
2189 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CONE_ENTRY);
2190 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2191 });
2192
2193 // Halls of Lightning, Arc Weld
2194 ApplySpellFix({ 59086 }, [](SpellInfo* spellInfo)
2195 {
2196 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(1);
2197 });
2198
2199 // Halls of Lightning, Arcing Burn
2200 ApplySpellFix({ 52671, 59834 }, [](SpellInfo* spellInfo)
2201 {
2202 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
2203 });
2204
2205 // Trial of the Champion, Death's Respite
2206 ApplySpellFix({ 68306 }, [](SpellInfo* spellInfo)
2207 {
2208 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
2209 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(25);
2210 });
2211
2212 // Trial of the Champion, Eadric Achievement (The Faceroller)
2213 ApplySpellFix({ 68197 }, [](SpellInfo* spellInfo)
2214 {
2215 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
2216 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD;
2217 });
2218
2219 // Trial of the Champion, Earth Shield
2220 ApplySpellFix({ 67530 }, [](SpellInfo* spellInfo)
2221 {
2222 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PROC_TRIGGER_SPELL; // will trigger 67537
2223 });
2224
2225 // Trial of the Champion, Hammer of the Righteous
2226 ApplySpellFix({ 66867 }, [](SpellInfo* spellInfo)
2227 {
2228 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_DUMMY;
2229 });
2230
2231 // Trial of the Champion, Summon Risen Jaeren/Arelas
2232 ApplySpellFix({ 67705, 67715 }, [](SpellInfo* spellInfo)
2233 {
2234 spellInfo->AttributesEx2 |= SPELL_ATTR2_ALLOW_DEAD_TARGET;
2235 });
2236
2237 // Trial of the Champion, Ghoul Explode
2238 ApplySpellFix({ 67751 }, [](SpellInfo* spellInfo)
2239 {
2240 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2241 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2242 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS);
2243 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2244 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2245 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS);
2246 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2247 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2248 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS);
2249 });
2250
2251 // Trial of the Champion, Desecration
2252 ApplySpellFix({ 67778, 67877 }, [](SpellInfo* spellInfo)
2253 {
2254 spellInfo->Effects[EFFECT_0].TriggerSpell = 68766;
2255 });
2256
2257 // Killing Spree (Off hand damage)
2258 ApplySpellFix({ 57842 }, [](SpellInfo* spellInfo)
2259 {
2260 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(2); // Melee Range
2261 });
2262
2263 // Trial of the Crusader, Jaraxxus Intro spell
2264 ApplySpellFix({ 67888 }, [](SpellInfo* spellInfo)
2265 {
2266 spellInfo->Attributes |= SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT;
2267 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
2268 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
2269 });
2270
2271 // Trial of the Crusader, Lich King Intro spell
2272 ApplySpellFix({ 68193 }, [](SpellInfo* spellInfo)
2273 {
2274 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
2275 });
2276
2277 // Trial of the Crusader, Gormok, player vehicle spell, CUSTOM! (default jump to hand, not used)
2278 ApplySpellFix({ 66342 }, [](SpellInfo* spellInfo)
2279 {
2280 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AURA;
2281 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_SET_VEHICLE_ID;
2282 spellInfo->Effects[EFFECT_0].MiscValue = 496;
2283 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21);
2284 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13);
2285 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
2286 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2287 spellInfo->AuraInterruptFlags = AURA_INTERRUPT_FLAG_CHANGE_MAP;
2288 });
2289
2290 // Trial of the Crusader, Gormok, Fire Bomb
2291 ApplySpellFix({ 66313 }, [](SpellInfo* spellInfo)
2292 {
2293 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2294 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ANY);
2295 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2296 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ANY);
2297 spellInfo->Effects[EFFECT_1].Effect = 0;
2298 });
2299
2300 ApplySpellFix({ 66317 }, [](SpellInfo* spellInfo)
2301 {
2302 spellInfo->Attributes |= SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT;
2303 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
2304 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
2305 });
2306
2307 ApplySpellFix({ 66318 }, [](SpellInfo* spellInfo)
2308 {
2309 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2310 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2311 spellInfo->Speed = 14.0f;
2312 spellInfo->Attributes |= SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT;
2313 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
2314 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
2315 });
2316
2317 ApplySpellFix({ 66320, 67472, 67473, 67475 }, [](SpellInfo* spellInfo)
2318 {
2319 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_2_YARDS);
2320 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_2_YARDS);
2321 });
2322
2323 // Trial of the Crusader, Acidmaw & Dreadscale, Emerge
2324 ApplySpellFix({ 66947 }, [](SpellInfo* spellInfo)
2325 {
2326 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_WHILE_STUNNED;
2327 });
2328
2329 // Trial of the Crusader, Jaraxxus, Curse of the Nether
2330 ApplySpellFix({ 66211 }, [](SpellInfo* spellInfo)
2331 {
2332 spellInfo->ExcludeTargetAuraSpell = 66209; // exclude Touch of Jaraxxus
2333 });
2334
2335 // Trial of the Crusader, Jaraxxus, Summon Volcano
2336 ApplySpellFix({ 66258, 67901 }, [](SpellInfo* spellInfo)
2337 {
2338 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(85); // summon for 18 seconds, 15 not enough
2339 });
2340
2341 // Trial of the Crusader, Jaraxxus, Spinning Pain Spike
2342 ApplySpellFix({ 66281 }, [](SpellInfo* spellInfo)
2343 {
2344 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_4_YARDS);
2345 });
2346
2347 ApplySpellFix({ 66287 }, [](SpellInfo* spellInfo)
2348 {
2349 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
2350 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_MOD_TAUNT;
2351 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_NEARBY_ENTRY);
2352 spellInfo->Effects[EFFECT_2].Effect = SPELL_EFFECT_APPLY_AURA;
2353 spellInfo->Effects[EFFECT_2].ApplyAuraName = SPELL_AURA_MOD_STUN;
2354 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
2355 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(35); // 4 secs
2356 });
2357
2358 // Trial of the Crusader, Jaraxxus, Fel Fireball
2359 ApplySpellFix({ 66532, 66963, 66964, 66965 }, [](SpellInfo* spellInfo)
2360 {
2361 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
2362 });
2363
2364 // tempfix, make Nether Power not stealable
2365 ApplySpellFix({ 66228, 67106, 67107, 67108 }, [](SpellInfo* spellInfo)
2366 {
2367 spellInfo->AttributesEx4 |= SPELL_ATTR4_CANNOT_BE_STOLEN;
2368 });
2369
2370 // Trial of the Crusader, Faction Champions, Druid - Tranquality
2371 ApplySpellFix({ 66086, 67974, 67975, 67976 }, [](SpellInfo* spellInfo)
2372 {
2373 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AREA_AURA_FRIEND;
2374 });
2375
2376 // Trial of the Crusader, Faction Champions, Shaman - Earth Shield
2377 ApplySpellFix({ 66063 }, [](SpellInfo* spellInfo)
2378 {
2379 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PROC_TRIGGER_SPELL;
2380 spellInfo->Effects[EFFECT_0].TriggerSpell = 66064;
2381 });
2382
2383 // Trial of the Crusader, Faction Champions, Priest - Mana Burn
2384 ApplySpellFix({ 66100 }, [](SpellInfo* spellInfo)
2385 {
2386 spellInfo->Effects[EFFECT_0].BasePoints = 5;
2387 spellInfo->Effects[EFFECT_0].DieSides = 0;
2388 });
2389
2390 ApplySpellFix({ 68026 }, [](SpellInfo* spellInfo)
2391 {
2392 spellInfo->Effects[EFFECT_0].BasePoints = 8;
2393 spellInfo->Effects[EFFECT_0].DieSides = 0;
2394 });
2395
2396 ApplySpellFix({ 68027 }, [](SpellInfo* spellInfo)
2397 {
2398 spellInfo->Effects[EFFECT_0].BasePoints = 6;
2399 spellInfo->Effects[EFFECT_0].DieSides = 0;
2400 });
2401
2402 ApplySpellFix({ 68028 }, [](SpellInfo* spellInfo)
2403 {
2404 spellInfo->Effects[EFFECT_0].BasePoints = 10;
2405 spellInfo->Effects[EFFECT_0].DieSides = 0;
2406 });
2407
2408 // Trial of the Crusader, Twin Valkyr, Touch of Light/Darkness, Light/Dark Surge
2410 65950 // light 0
2411 }, [](SpellInfo* spellInfo)
2412 {
2413 //spellInfo->EffectApplyAuraName[0] = SPELL_AURA_PERIODIC_DUMMY;
2414 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2415 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2416 spellInfo->Effects[EFFECT_1].Effect = 0;
2417 spellInfo->Effects[EFFECT_2].Effect = 0;
2418 });
2419
2421 65767 // light surge 0
2422 }, [](SpellInfo* spellInfo)
2423 {
2424 spellInfo->ExcludeTargetAuraSpell = 65686;
2425 });
2426
2428 67296 // light 1
2429 }, [](SpellInfo* spellInfo)
2430 {
2431 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2432 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2433 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2434 spellInfo->Effects[EFFECT_1].Effect = 0;
2435 spellInfo->Effects[EFFECT_2].Effect = 0;
2436 });
2437
2439 67274 // light surge 1
2440 }, [](SpellInfo* spellInfo)
2441 {
2442 spellInfo->ExcludeTargetAuraSpell = 67222;
2443 });
2444
2446 67297 // light 2
2447 }, [](SpellInfo* spellInfo)
2448 {
2449 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2450 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2451 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2452 spellInfo->Effects[EFFECT_1].Effect = 0;
2453 spellInfo->Effects[EFFECT_2].Effect = 0;
2454 });
2455
2457 67275 // light surge 2
2458 }, [](SpellInfo* spellInfo)
2459 {
2460 spellInfo->ExcludeTargetAuraSpell = 67223;
2461 });
2462
2464 67298 // light 3
2465 }, [](SpellInfo* spellInfo)
2466 {
2467 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2468 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2469 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2470 spellInfo->Effects[EFFECT_1].Effect = 0;
2471 spellInfo->Effects[EFFECT_2].Effect = 0;
2472 });
2473
2475 67276 // light surge 3
2476 }, [](SpellInfo* spellInfo)
2477 {
2478 spellInfo->ExcludeTargetAuraSpell = 67224;
2479 });
2480
2482 66001 // dark 0
2483 }, [](SpellInfo* spellInfo)
2484 {
2485 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2486 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2487 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2488 spellInfo->Effects[EFFECT_1].Effect = 0;
2489 spellInfo->Effects[EFFECT_2].Effect = 0;
2490 });
2491
2493 65769 // dark surge 0
2494 }, [](SpellInfo* spellInfo)
2495 {
2496 spellInfo->ExcludeTargetAuraSpell = 65684;
2497 });
2498
2500 67281 // dark 1
2501 }, [](SpellInfo* spellInfo)
2502 {
2503 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2504 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2505 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2506 spellInfo->Effects[EFFECT_1].Effect = 0;
2507 spellInfo->Effects[EFFECT_2].Effect = 0;
2508 });
2509
2511 67265 // dark surge 1
2512 }, [](SpellInfo* spellInfo)
2513 {
2514 spellInfo->ExcludeTargetAuraSpell = 67176;
2515 });
2516
2518 67282 // dark 2
2519 }, [](SpellInfo* spellInfo)
2520 {
2521 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2522 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2523 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2524 spellInfo->Effects[EFFECT_1].Effect = 0;
2525 spellInfo->Effects[EFFECT_2].Effect = 0;
2526 });
2527
2529 67266 // dark surge 2
2530 }, [](SpellInfo* spellInfo)
2531 {
2532 spellInfo->ExcludeTargetAuraSpell = 67177;
2533 });
2534
2536 67283 // dark 3
2537 }, [](SpellInfo* spellInfo)
2538 {
2539 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2540 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2541 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2542 spellInfo->Effects[EFFECT_1].Effect = 0;
2543 spellInfo->Effects[EFFECT_2].Effect = 0;
2544 });
2545
2547 67267 // dark surge 3
2548 }, [](SpellInfo* spellInfo)
2549 {
2550 spellInfo->ExcludeTargetAuraSpell = 67178;
2551 });
2552
2553 // Trial of the Crusader, Twin Valkyr, Twin's Pact
2554 ApplySpellFix({ 65875, 67303, 67304, 67305, 65876, 67306, 67307, 67308 }, [](SpellInfo* spellInfo)
2555 {
2556 spellInfo->Effects[EFFECT_1].Effect = 0;
2557 spellInfo->Effects[EFFECT_2].Effect = 0;
2558 });
2559
2560 // Trial of the Crusader, Anub'arak, Emerge
2561 ApplySpellFix({ 65982 }, [](SpellInfo* spellInfo)
2562 {
2563 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_WHILE_STUNNED;
2564 });
2565
2566 // Trial of the Crusader, Anub'arak, Penetrating Cold
2567 ApplySpellFix({ 66013, 67700, 68509, 68510 }, [](SpellInfo* spellInfo)
2568 {
2569 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
2570 });
2571
2572 // Trial of the Crusader, Anub'arak, Shadow Strike
2573 ApplySpellFix({ 66134 }, [](SpellInfo* spellInfo)
2574 {
2575 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
2576 spellInfo->Effects[EFFECT_0].Effect = 0;
2577 });
2578
2579 // Trial of the Crusader, Anub'arak, Pursuing Spikes
2580 ApplySpellFix({ 65920, 65922, 65923 }, [](SpellInfo* spellInfo)
2581 {
2582 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PERIODIC_DUMMY;
2583 //spellInfo->EffectTriggerSpell[0] = 0;
2584 });
2585
2586 // Trial of the Crusader, Anub'arak, Summon Scarab
2587 ApplySpellFix({ 66339 }, [](SpellInfo* spellInfo)
2588 {
2589 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(35);
2590 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
2591 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2592 });
2593
2594 // Trial of the Crusader, Anub'arak, Achievements: The Traitor King
2596 68186, // Anub'arak Scarab Achievement 10
2597 68515 // Anub'arak Scarab Achievement 25
2598 }, [](SpellInfo* spellInfo)
2599 {
2600 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2601 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
2602 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD;
2603 });
2604
2605 // Trial of the Crusader, Anub'arak, Spider Frenzy
2606 ApplySpellFix({ 66129 }, [](SpellInfo* spellInfo)
2607 {
2608 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
2609 });
2610
2611 // Soul Sickness
2612 ApplySpellFix({ 69131 }, [](SpellInfo* spellInfo)
2613 {
2614 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PERIODIC_TRIGGER_SPELL;
2615 spellInfo->Effects[EFFECT_0].Amplitude = 8000;
2616 spellInfo->Effects[EFFECT_0].TriggerSpell = 69133;
2617 });
2618
2619 // Phantom Blast
2620 ApplySpellFix({ 68982, 70322 }, [](SpellInfo* spellInfo)
2621 {
2622 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
2623 });
2624
2625 // Empowered Blizzard
2626 ApplySpellFix({ 70131 }, [](SpellInfo* spellInfo)
2627 {
2628 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2629 });
2630
2631 // Ice Lance Volley
2632 ApplySpellFix({ 70464 }, [](SpellInfo* spellInfo)
2633 {
2634 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2635 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2636 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_70_YARDS);
2637 });
2638
2640 70513, // Multi-Shot
2641 59514 // Shriek of the Highborne
2642 }, [](SpellInfo* spellInfo)
2643 {
2644 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CONE_ENTRY);
2645 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2646 });
2647
2648 // Icicle
2649 ApplySpellFix({ 69428, 69426 }, [](SpellInfo* spellInfo)
2650 {
2651 spellInfo->InterruptFlags = 0;
2652 spellInfo->AuraInterruptFlags = 0;
2653 spellInfo->ChannelInterruptFlags = 0;
2654 });
2655
2656 ApplySpellFix({ 70525, 70639 }, [](SpellInfo* spellInfo)
2657 {
2658 spellInfo->Effects[EFFECT_0].Effect = 0;
2659 spellInfo->Effects[EFFECT_1].Effect = 0;
2660 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2661 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2662 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_500_YARDS); // 500yd
2663 });
2664
2665 // Frost Nova
2666 ApplySpellFix({ 68198 }, [](SpellInfo* spellInfo)
2667 {
2668 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13);
2669 spellInfo->Targets |= TARGET_FLAG_DEST_LOCATION;
2670 });
2671
2672 // Blight
2673 ApplySpellFix({ 69604, 70286 }, [](SpellInfo* spellInfo)
2674 {
2675 spellInfo->MaxAffectedTargets = 1;
2676 spellInfo->AttributesEx3 |= (SPELL_ATTR3_ALWAYS_HIT | SPELL_ATTR3_ONLY_ON_PLAYER);
2677 });
2678
2679 // Chilling Wave
2680 ApplySpellFix({ 68778, 70333 }, [](SpellInfo* spellInfo)
2681 {
2682 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ENEMY);
2683 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2684 });
2685
2686 ApplySpellFix({ 68786, 70336 }, [](SpellInfo* spellInfo)
2687 {
2688 spellInfo->AttributesEx3 |= (SPELL_ATTR3_ALWAYS_HIT | SPELL_ATTR3_ONLY_ON_PLAYER);
2689 spellInfo->Effects[EFFECT_2].Effect = SPELL_EFFECT_DUMMY;
2690 });
2691
2692 // Pursuit
2693 ApplySpellFix({ 68987 }, [](SpellInfo* spellInfo)
2694 {
2695 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2696 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2697 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2698 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
2699 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
2700 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo();
2701 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100yd
2702 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
2703 });
2704
2705 ApplySpellFix({ 69029, 70850 }, [](SpellInfo* spellInfo)
2706 {
2707 spellInfo->Effects[EFFECT_2].Effect = 0;
2708 });
2709
2710 // Explosive Barrage
2711 ApplySpellFix({ 69263 }, [](SpellInfo* spellInfo)
2712 {
2713 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_MOD_STUN;
2714 });
2715
2716 // Overlord's Brand
2717 ApplySpellFix({ 69172 }, [](SpellInfo* spellInfo)
2718 {
2719 spellInfo->ProcFlags = DONE_HIT_PROC_FLAG_MASK & ~PROC_FLAG_DONE_PERIODIC;
2720 spellInfo->ProcChance = 100;
2721 });
2722
2723 // Icy Blast
2724 ApplySpellFix({ 69232 }, [](SpellInfo* spellInfo)
2725 {
2726 spellInfo->Effects[EFFECT_1].TriggerSpell = 69238;
2727 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2728 });
2729
2730 ApplySpellFix({ 69233, 69646 }, [](SpellInfo* spellInfo)
2731 {
2732 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2733 });
2734
2735 ApplySpellFix({ 69238, 69628 }, [](SpellInfo* spellInfo)
2736 {
2737 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2738 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_DEST_DYNOBJ_NONE);
2739 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2740 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_DEST_DYNOBJ_NONE);
2741 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2742 });
2743
2744 // Hoarfrost
2745 ApplySpellFix({ 69246, 69245, 69645 }, [](SpellInfo* spellInfo)
2746 {
2747 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2748 });
2749
2750 // Devour Humanoid
2751 ApplySpellFix({ 69503 }, [](SpellInfo* spellInfo)
2752 {
2753 spellInfo->ChannelInterruptFlags |= 0;
2754 spellInfo->AuraInterruptFlags = AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING;
2755 });
2756
2757 // Falric: Defiling Horror
2758 ApplySpellFix({ 72435, 72452 }, [](SpellInfo* spellInfo)
2759 {
2760 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
2761 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
2762 });
2763
2764 // Frostsworn General - Throw Shield
2765 ApplySpellFix({ 69222, 73076 }, [](SpellInfo* spellInfo)
2766 {
2767 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
2768 });
2769
2770 // Halls of Reflection Clone
2771 ApplySpellFix({ 69828 }, [](SpellInfo* spellInfo)
2772 {
2773 spellInfo->Effects[EFFECT_1].Effect = 0;
2774 spellInfo->Effects[EFFECT_2].Effect = 0;
2775 });
2776
2777 // Summon Ice Wall
2778 ApplySpellFix({ 69768 }, [](SpellInfo* spellInfo)
2779 {
2780 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2781 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL;
2782 });
2783
2784 ApplySpellFix({ 69767 }, [](SpellInfo* spellInfo)
2785 {
2786 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ANY);
2787 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2788 });
2789
2790 // Essence of the Captured
2791 ApplySpellFix({ 73035, 70719 }, [](SpellInfo* spellInfo)
2792 {
2793 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13);
2794 });
2795
2796 // Achievement Check
2797 ApplySpellFix({ 72830 }, [](SpellInfo* spellInfo)
2798 {
2799 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
2800 });
2801
2803 70781, // Light's Hammer Teleport
2804 70856, // Oratory of the Damned Teleport
2805 70857, // Rampart of Skulls Teleport
2806 70858, // Deathbringer's Rise Teleport
2807 70859, // Upper Spire Teleport
2808 70860, // Frozen Throne Teleport
2809 70861 // Sindragosa's Lair Teleport
2810 }, [](SpellInfo* spellInfo)
2811 {
2812 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2813 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2814 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB); // this target is for SPELL_EFFECT_TELEPORT_UNITS
2815 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
2816 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2817 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo();
2818 });
2819
2821 70960, // Bone Flurry
2822 71258 // Adrenaline Rush (Ymirjar Battle-Maiden)
2823 }, [](SpellInfo* spellInfo)
2824 {
2825 spellInfo->AttributesEx &= ~SPELL_ATTR1_IS_SELF_CHANNELED;
2826 });
2827
2828 // Saber Lash (Lord Marrowgar)
2829 ApplySpellFix({ 69055, 70814 }, [](SpellInfo* spellInfo)
2830 {
2831 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_5_YARDS); // 5yd
2832 });
2833
2834 // Impaled (Lord Marrowgar)
2835 ApplySpellFix({ 69065 }, [](SpellInfo* spellInfo)
2836 {
2837 spellInfo->Effects[EFFECT_0].Effect = 0; // remove stun so Dispersion can be used
2838 });
2839
2840 // Cold Flame (Lord Marrowgar)
2841 ApplySpellFix({ 72701, 72702, 72703, 72704 }, [](SpellInfo* spellInfo)
2842 {
2843 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
2844 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2845 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
2846 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(9); // 30 secs instead of 12, need him for longer, but will stop his actions after 12 secs
2847 });
2848
2849 ApplySpellFix({ 69138 }, [](SpellInfo* spellInfo)
2850 {
2851 spellInfo->Effects[EFFECT_0].Effect = 0;
2852 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2853 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(9); // 30 secs instead of 12, need him for longer, but will stop his actions after 12 secs
2854 });
2855
2856 ApplySpellFix({ 69146, 70823, 70824, 70825 }, [](SpellInfo* spellInfo)
2857 {
2858 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS); // 3yd instead of 5yd
2859 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
2860 });
2861
2862 // Dark Martyrdom (Lady Deathwhisper)
2863 ApplySpellFix({ 70897 }, [](SpellInfo* spellInfo)
2864 {
2865 spellInfo->AttributesEx2 |= SPELL_ATTR2_ALLOW_DEAD_TARGET;
2866 });
2867
2869 69075, // Bone Storm (Lord Marrowgar)
2870 70834, // Bone Storm (Lord Marrowgar)
2871 70835, // Bone Storm (Lord Marrowgar)
2872 70836, // Bone Storm (Lord Marrowgar)
2873 72378, // Blood Nova (Deathbringer Saurfang)
2874 73058, // Blood Nova (Deathbringer Saurfang)
2875 72769, // Scent of Blood (Deathbringer Saurfang)
2876 72385, // Boiling Blood (Deathbringer Saurfang)
2877 72441, // Boiling Blood (Deathbringer Saurfang)
2878 72442, // Boiling Blood (Deathbringer Saurfang)
2879 72443, // Boiling Blood (Deathbringer Saurfang)
2880 71160, // Plague Stench (Stinky)
2881 71161, // Plague Stench (Stinky)
2882 71123, // Decimate (Stinky & Precious)
2883 71464 // Divine Surge (Sister Svalna)
2884 }, [](SpellInfo* spellInfo)
2885 {
2886 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
2887 });
2888
2889 // Shadow's Fate
2890 ApplySpellFix({ 71169 }, [](SpellInfo* spellInfo)
2891 {
2892 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
2893 });
2894
2895 // Lock Players and Tap Chest
2896 ApplySpellFix({ 72347 }, [](SpellInfo* spellInfo)
2897 {
2898 spellInfo->AttributesEx3 &= ~SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
2899 });
2900
2901 // Award Reputation - Boss Kill
2902 ApplySpellFix({ 73843, 73844, 73845, 73846 }, [](SpellInfo* spellInfo)
2903 {
2904 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS);
2905 });
2906
2907 // Death Plague (Rotting Frost Giant)
2908 ApplySpellFix({ 72864 }, [](SpellInfo* spellInfo)
2909 {
2910 spellInfo->ExcludeTargetAuraSpell = 0;
2911 });
2912
2913 // Gunship Battle, spell Below Zero
2914 ApplySpellFix({ 69705 }, [](SpellInfo* spellInfo)
2915 {
2916 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
2917 });
2918
2919 // Resistant Skin (Deathbringer Saurfang adds)
2920 ApplySpellFix({ 72723 }, [](SpellInfo* spellInfo)
2921 {
2922 // this spell initially granted Shadow damage immunity, however it was removed but the data was left in client
2923 spellInfo->Effects[EFFECT_2].Effect = 0;
2924 });
2925
2926 // Mark of the Fallen Champion (Deathbringer Saurfang)
2927 ApplySpellFix({ 72255, 72444, 72445, 72446 }, [](SpellInfo* spellInfo)
2928 {
2929 // Patch 3.3.2 (2010-01-02): Deathbringer Saurfang will no longer gain blood power from Mark of the Fallen Champion.
2930 // prevented in script, effect needed for Prayer of Mending
2931 spellInfo->AttributesEx3 &= ~SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
2932 });
2933
2934 // Coldflame Jets (Traps after Saurfang)
2935 ApplySpellFix({ 70460 }, [](SpellInfo* spellInfo)
2936 {
2937 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(1); // 10 seconds
2938 });
2939
2941 70461, // Coldflame Jets (Traps after Saurfang)
2942 71289 // Dominate Mind (Lady Deathwhisper)
2943 }, [](SpellInfo* spellInfo)
2944 {
2945 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2946 });
2947
2948 // Severed Essence (Val'kyr Herald)
2949 ApplySpellFix({ 71906, 71942 }, [](SpellInfo* spellInfo)
2950 {
2951 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
2952 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2953 spellInfo->Effects[EFFECT_1].Effect = 0;
2954 });
2955
2957 71159, // Awaken Plagued Zombies (Precious)
2958 71302 // Awaken Ymirjar Fallen (Ymirjar Deathbringer)
2959 }, [](SpellInfo* spellInfo)
2960 {
2961 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21);
2962 });
2963
2964 // Blood Prince Council, Invocation of Blood
2965 ApplySpellFix({ 70981, 70982, 70952 }, [](SpellInfo* spellInfo)
2966 {
2967 spellInfo->Effects[EFFECT_0].Effect = 0; // clear share health aura
2968 });
2969
2970 // Ymirjar Frostbinder, Frozen Orb
2971 ApplySpellFix({ 71274 }, [](SpellInfo* spellInfo)
2972 {
2973 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2974 });
2975
2976 // Ooze Flood (Rotface)
2977 ApplySpellFix({ 69783, 69797, 69799, 69802 }, [](SpellInfo* spellInfo)
2978 {
2979 spellInfo->AttributesEx |= SPELL_ATTR1_EXCLUDE_CASTER;
2980 });
2981
2982 // Volatile Ooze Beam Protection
2983 ApplySpellFix({ 70530 }, [](SpellInfo* spellInfo)
2984 {
2985 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AURA; // blizzard typo, 65 instead of 6, aura itself is defined (dummy)
2986 });
2987
2988 // Professor Putricide, Gaseous Bloat (Orange Ooze Channel)
2989 ApplySpellFix({ 70672, 72455, 72832, 72833 }, [](SpellInfo* spellInfo)
2990 {
2991 // copied attributes from Green Ooze Channel
2992 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
2993 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
2994 });
2995
2997 71412, // Green Ooze Summon (Professor Putricide)
2998 71415 // Orange Ooze Summon (Professor Putricide)
2999 }, [](SpellInfo* spellInfo)
3000 {
3001 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3002 });
3003
3005 71621, // Create Concoction (Professor Putricide)
3006 72850,
3007 72851,
3008 72852,
3009 71893, // Guzzle Potions (Professor Putricide)
3010 73120,
3011 73121,
3012 73122
3013 }, [](SpellInfo* spellInfo)
3014 {
3015 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(15); // 4 sec
3016 });
3017
3018 // Mutated Plague (Professor Putricide)
3019 ApplySpellFix({ 72454, 72464, 72506, 72507 }, [](SpellInfo* spellInfo)
3020 {
3021 spellInfo->AttributesEx4 |= SPELL_ATTR4_NO_CAST_LOG;
3022 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3023 });
3024
3025 // Unbound Plague (Professor Putricide) (needs target selection script)
3026 ApplySpellFix({ 70911, 72854, 72855, 72856 }, [](SpellInfo* spellInfo)
3027 {
3028 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
3029 });
3030
3031 // Mutated Transformation (Professor Putricide)
3032 ApplySpellFix({ 70402, 72511, 72512, 72513 }, [](SpellInfo* spellInfo)
3033 {
3034 spellInfo->AttributesEx2 |= SPELL_ATTR2_CANT_CRIT;
3035 });
3036
3037 // Empowered Flare (Blood Prince Council)
3038 ApplySpellFix({ 71708, 72785, 72786, 72787 }, [](SpellInfo* spellInfo)
3039 {
3040 spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_MODIFIERS;
3041 });
3042
3044 71518, // Unholy Infusion Quest Credit (Professor Putricide)
3045 72934, // Blood Infusion Quest Credit (Blood-Queen Lana'thel)
3046 72289 // Frost Infusion Quest Credit (Sindragosa)
3047 }, [](SpellInfo* spellInfo)
3048 {
3049 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // another missing radius
3050 });
3051
3052 // Swarming Shadows
3053 ApplySpellFix({ 71266, 72890 }, [](SpellInfo* spellInfo)
3054 {
3055 spellInfo->AreaGroupId = 0; // originally, these require area 4522, which is... outside of Icecrown Citadel
3056 });
3057
3059 71301, // Summon Dream Portal (Valithria Dreamwalker)
3060 71977 // Summon Nightmare Portal (Valithria Dreamwalker)
3061 }, [](SpellInfo* spellInfo)
3062 {
3063 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
3064 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
3065 });
3066
3067 // Column of Frost (visual marker)
3068 ApplySpellFix({ 70715 }, [](SpellInfo* spellInfo)
3069 {
3070 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(32); // 6 seconds (missing)
3071 });
3072
3073 // Mana Void (periodic aura)
3074 ApplySpellFix({ 71085 }, [](SpellInfo* spellInfo)
3075 {
3076 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(9); // 30 seconds (missing)
3077 });
3078
3079 // Summon Suppressor (needs target selection script)
3080 ApplySpellFix({ 70936 }, [](SpellInfo* spellInfo)
3081 {
3082 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3083 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
3084 });
3085
3086 // Corruption
3087 ApplySpellFix({ 70602 }, [](SpellInfo* spellInfo)
3088 {
3089 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
3090 });
3091
3093 72706, // Achievement Check (Valithria Dreamwalker)
3094 71357 // Order Whelp
3095 }, [](SpellInfo* spellInfo)
3096 {
3097 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3098 });
3099
3100 // Sindragosa's Fury
3101 ApplySpellFix({ 70598 }, [](SpellInfo* spellInfo)
3102 {
3103 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
3104 });
3105
3106 // Tail Smash (Sindragosa)
3107 ApplySpellFix({ 71077 }, [](SpellInfo* spellInfo)
3108 {
3109 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER_BACK);
3110 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_DEST_AREA_ENEMY);
3111 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER_BACK);
3112 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_DEST_AREA_ENEMY);
3113 });
3114
3115 // Frost Bomb
3116 ApplySpellFix({ 69846 }, [](SpellInfo* spellInfo)
3117 {
3118 spellInfo->Speed = 0.0f; // This spell's summon happens instantly
3119 });
3120
3121 // Mystic Buffet (Sindragosa)
3122 ApplySpellFix({ 70127, 72528, 72529, 72530 }, [](SpellInfo* spellInfo)
3123 {
3124 spellInfo->Effects[EFFECT_1].Effect = 0; // remove obsolete spell effect with no targets
3125 });
3126
3127 // Sindragosa, Frost Aura
3128 ApplySpellFix({ 70084, 71050, 71051, 71052 }, [](SpellInfo* spellInfo)
3129 {
3130 spellInfo->Attributes &= ~SPELL_ATTR0_NO_IMMUNITIES;
3131 });
3132
3133 // Ice Lock
3134 ApplySpellFix({ 71614 }, [](SpellInfo* spellInfo)
3135 {
3136 spellInfo->Mechanic = MECHANIC_STUN;
3137 });
3138
3139 // Lich King, Infest
3140 ApplySpellFix({ 70541, 73779, 73780, 73781 }, [](SpellInfo* spellInfo)
3141 {
3142 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3143 });
3144
3145 // Lich King, Necrotic Plague
3146 ApplySpellFix({ 70337, 73912, 73913, 73914, 70338, 73785, 73786, 73787 }, [](SpellInfo* spellInfo)
3147 {
3148 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
3149 });
3150
3152 69099, // Ice Pulse 10n
3153 73776, // Ice Pulse 25n
3154 73777, // Ice Pulse 10h
3155 73778 // Ice Pulse 25h
3156 }, [](SpellInfo* spellInfo)
3157 {
3158 spellInfo->AttributesEx2 |= SPELL_ATTR2_CANT_CRIT;
3159 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
3160 });
3161
3162 // Fury of Frostmourne
3163 ApplySpellFix({ 72350 }, [](SpellInfo* spellInfo)
3164 {
3165 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3166 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3167 });
3168
3170 72351, // Fury of Frostmourne
3171 72431, // Jump (removes Fury of Frostmourne debuff)
3172 72429, // Mass Resurrection
3173 73159 // Play Movie
3174 }, [](SpellInfo* spellInfo)
3175 {
3176 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3177 });
3178
3179 // Raise Dead
3180 ApplySpellFix({ 72376 }, [](SpellInfo* spellInfo)
3181 {
3182 spellInfo->MaxAffectedTargets = 4;
3183 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3184 });
3185
3186 // Jump
3187 ApplySpellFix({ 71809 }, [](SpellInfo* spellInfo)
3188 {
3189 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(5); // 40yd
3190 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
3191 spellInfo->Effects[EFFECT_0].MiscValue = 190;
3192 });
3193
3194 // Broken Frostmourne
3195 ApplySpellFix({ 72405 }, [](SpellInfo* spellInfo)
3196 {
3197 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3198 });
3199
3200 // Summon Shadow Trap
3201 ApplySpellFix({ 73540 }, [](SpellInfo* spellInfo)
3202 {
3203 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(3); // 60 seconds
3204 });
3205
3206 // Shadow Trap (visual)
3207 ApplySpellFix({ 73530 }, [](SpellInfo* spellInfo)
3208 {
3209 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(28); // 5 seconds
3210 });
3211
3212 // Shadow Trap
3213 ApplySpellFix({ 73529 }, [](SpellInfo* spellInfo)
3214 {
3215 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
3216 });
3217
3218 // Shadow Trap (searcher)
3219 ApplySpellFix({ 74282 }, [](SpellInfo* spellInfo)
3220 {
3221 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS); // 3yd
3222 });
3223
3224 // Raging Spirit Visual
3225 ApplySpellFix({ 69198 }, [](SpellInfo* spellInfo)
3226 {
3227 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
3228 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3229 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
3230 });
3231
3232 // Defile
3233 ApplySpellFix({ 72762 }, [](SpellInfo* spellInfo)
3234 {
3235 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(559); // 53 seconds
3236 spellInfo->ExcludeCasterAuraSpell = 0;
3237 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
3239 });
3240
3241 // Defile
3242 ApplySpellFix({ 72743 }, [](SpellInfo* spellInfo)
3243 {
3244 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(22); // 45 seconds
3245 });
3246
3247 ApplySpellFix({ 72754, 73708, 73709, 73710 }, [](SpellInfo* spellInfo)
3248 {
3249 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3250 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3251 });
3252
3253 // Val'kyr Target Search
3254 ApplySpellFix({ 69030 }, [](SpellInfo* spellInfo)
3255 {
3256 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3257 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3258 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
3259 });
3260
3261 // Harvest Souls
3262 ApplySpellFix({ 73654, 74295, 74296, 74297 }, [](SpellInfo* spellInfo)
3263 {
3264 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3265 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3266 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3267 });
3268
3269 // Restore Soul
3270 ApplySpellFix({ 72595, 73650 }, [](SpellInfo* spellInfo)
3271 {
3272 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3273 });
3274
3275 // Kill Frostmourne Players
3276 ApplySpellFix({ 75127 }, [](SpellInfo* spellInfo)
3277 {
3278 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3279 });
3280
3281 // Harvest Soul
3282 ApplySpellFix({ 73655 }, [](SpellInfo* spellInfo)
3283 {
3284 spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_MODIFIERS;
3285 });
3286
3287 // Destroy Soul
3288 ApplySpellFix({ 74086 }, [](SpellInfo* spellInfo)
3289 {
3290 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3291 });
3292
3293 // Summon Spirit Bomb
3294 ApplySpellFix({ 74302, 74342 }, [](SpellInfo* spellInfo)
3295 {
3296 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3297 spellInfo->MaxAffectedTargets = 1;
3298 });
3299
3300 // Summon Spirit Bomb
3301 ApplySpellFix({ 74341, 74343 }, [](SpellInfo* spellInfo)
3302 {
3303 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3304 spellInfo->MaxAffectedTargets = 3;
3305 });
3306
3307 // Summon Spirit Bomb
3308 ApplySpellFix({ 73579 }, [](SpellInfo* spellInfo)
3309 {
3310 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_25_YARDS); // 25yd
3311 });
3312
3313 // Trigger Vile Spirit (Inside, Heroic)
3314 ApplySpellFix({ 73582 }, [](SpellInfo* spellInfo)
3315 {
3316 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3317 });
3318
3319 // Scale Aura (used during Dominate Mind from Lady Deathwhisper)
3320 ApplySpellFix({ 73261 }, [](SpellInfo* spellInfo)
3321 {
3322 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
3323 });
3324
3325 // Leap to a Random Location
3326 ApplySpellFix({ 70485 }, [](SpellInfo* spellInfo)
3327 {
3328 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100yd
3329 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS);
3330 spellInfo->Effects[EFFECT_0].MiscValue = 100;
3331 });
3332
3333 // Empowered Blood
3334 ApplySpellFix({ 70227, 70232 }, [](SpellInfo* spellInfo)
3335 {
3336 spellInfo->AreaGroupId = 2452; // Whole icc instead of Crimson Halls only, remove when area calculation is fixed
3337 });
3338
3339 ApplySpellFix({ 74509 }, [](SpellInfo* spellInfo)
3340 {
3341 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd
3342 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd
3343 });
3344
3345 // Rallying Shout
3346 ApplySpellFix({ 75414 }, [](SpellInfo* spellInfo)
3347 {
3348 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd
3349 });
3350
3351 // Barrier Channel
3352 ApplySpellFix({ 76221 }, [](SpellInfo* spellInfo)
3353 {
3354 spellInfo->ChannelInterruptFlags &= ~(AURA_INTERRUPT_FLAG_TURNING | AURA_INTERRUPT_FLAG_MOVE);
3355 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_NEARBY_ENTRY);
3356 });
3357
3358 // Intimidating Roar
3359 ApplySpellFix({ 74384 }, [](SpellInfo* spellInfo)
3360 {
3361 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3362 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3363 });
3364
3366 74562, // Fiery Combustion
3367 74792 // Soul Consumption
3368 }, [](SpellInfo* spellInfo)
3369 {
3370 spellInfo->AttributesEx |= SPELL_ATTR1_NO_REDIRECTION;
3371 });
3372
3373 // Combustion
3374 ApplySpellFix({ 75883, 75884 }, [](SpellInfo* spellInfo)
3375 {
3376 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_6_YARDS); // 6yd
3377 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_6_YARDS); // 6yd
3378 });
3379
3380 // Consumption
3381 ApplySpellFix({ 75875, 75876 }, [](SpellInfo* spellInfo)
3382 {
3383 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_6_YARDS); // 6yd
3384 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_6_YARDS); // 6yd
3385 spellInfo->Effects[EFFECT_0].Mechanic = MECHANIC_NONE;
3386 spellInfo->Effects[EFFECT_1].Mechanic = MECHANIC_SNARE;
3387 });
3388
3389 // Soul Consumption
3390 ApplySpellFix({ 74799 }, [](SpellInfo* spellInfo)
3391 {
3392 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_12_YARDS); // 12yd
3393 });
3394
3395 // Twilight Cutter
3396 ApplySpellFix({ 74769, 77844, 77845, 77846 }, [](SpellInfo* spellInfo)
3397 {
3398 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3399 });
3400
3401 // Twilight Mending
3402 ApplySpellFix({ 75509 }, [](SpellInfo* spellInfo)
3403 {
3404 spellInfo->AttributesEx6 |= SPELL_ATTR6_IGNORE_PHASE_SHIFT;
3405 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3406 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3407 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3408 });
3409
3410 // Meteor Strike
3411 ApplySpellFix({ 74637 }, [](SpellInfo* spellInfo)
3412 {
3413 spellInfo->Speed = 0;
3414 });
3415
3416 //Blazing Aura
3417 ApplySpellFix({ 75885, 75886 }, [](SpellInfo* spellInfo)
3418 {
3419 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
3420 });
3421
3423 75952, //Meteor Strike
3424 74629 //Combustion Periodic
3425 }, [](SpellInfo* spellInfo)
3426 {
3427 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
3428 });
3429
3430 // Going Bearback
3431 ApplySpellFix({ 54897 }, [](SpellInfo* spellInfo)
3432 {
3433 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_DUMMY;
3434 spellInfo->Effects[EFFECT_1].RadiusEntry = spellInfo->Effects[EFFECT_0].RadiusEntry;
3435 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_DEST_AREA_ENTRY);
3436 });
3437
3438 // Still At It
3439 ApplySpellFix({ 51931, 51932, 51933 }, [](SpellInfo* spellInfo)
3440 {
3441 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(38);
3442 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
3443 });
3444
3445 // Rallying the Troops
3446 ApplySpellFix({ 47394 }, [](SpellInfo* spellInfo)
3447 {
3448 spellInfo->ExcludeTargetAuraSpell = 47394;
3449 });
3450
3451 // A Tangled Skein
3452 ApplySpellFix({ 51165, 51173 }, [](SpellInfo* spellInfo)
3453 {
3454 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
3455 });
3456
3458 69563, // A Cloudlet of Classy Cologne
3459 69445, // A Perfect Puff of Perfume
3460 69489 // Bonbon Blitz
3461 }, [](SpellInfo* spellInfo)
3462 {
3463 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
3464 });
3465
3466 // Control
3467 ApplySpellFix({ 30790 }, [](SpellInfo* spellInfo)
3468 {
3469 spellInfo->Effects[EFFECT_1].MiscValue = 0;
3470 });
3471
3472 // Reclusive Runemaster
3473 ApplySpellFix({ 48028 }, [](SpellInfo* spellInfo)
3474 {
3475 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
3476 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
3477 });
3478
3479 // Mastery of
3480 ApplySpellFix({ 65147 }, [](SpellInfo* spellInfo)
3481 {
3482 spellInfo->CategoryEntry = sSpellCategoryStore.LookupEntry(1244);
3483 spellInfo->CategoryRecoveryTime = 1500;
3484 });
3485
3486 // Weakness to Lightning
3487 ApplySpellFix({ 46432 }, [](SpellInfo* spellInfo)
3488 {
3489 spellInfo->AttributesEx3 &= ~SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
3490 });
3491
3492 // Wrangle Some Aether Rays!
3493 ApplySpellFix({ 40856 }, [](SpellInfo* spellInfo)
3494 {
3495 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(27); // 3000ms
3496 });
3497
3498 // The Black Knight's Orders
3499 ApplySpellFix({ 63163 }, [](SpellInfo* spellInfo)
3500 {
3501 spellInfo->Effects[EFFECT_0].BasePoints = 52390;
3502 });
3503
3504 // The Warp Rifts
3505 ApplySpellFix({ 34888 }, [](SpellInfo* spellInfo)
3506 {
3507 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(5); // 300 secs
3508 });
3509
3510 // The Smallest Creatures
3511 ApplySpellFix({ 38544 }, [](SpellInfo* spellInfo)
3512 {
3513 spellInfo->Effects[EFFECT_0].MiscValueB = 427;
3514 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(1);
3515 spellInfo->Effects[EFFECT_1].Effect = 0;
3516 });
3517
3518 // Ridding the red rocket
3519 ApplySpellFix({ 49177 }, [](SpellInfo* spellInfo)
3520 {
3521 spellInfo->Effects[EFFECT_0].BasePoints = 1; // corrects seat id (points - 1 = seatId)
3522 });
3523
3524 // Jormungar Strike
3525 ApplySpellFix({ 56513 }, [](SpellInfo* spellInfo)
3526 {
3527 spellInfo->RecoveryTime = 2000;
3528 });
3529
3531 37851, // Tag Greater Felfire Diemetradon
3532 37918 // Arcano-pince
3533 }, [](SpellInfo* spellInfo)
3534 {
3535 spellInfo->RecoveryTime = 3000;
3536 });
3537
3539 54997, // Cast Net (tooltip says 10s but sniffs say 6s)
3540 56524 // Acid Breath
3541 }, [](SpellInfo* spellInfo)
3542 {
3543 spellInfo->RecoveryTime = 6000;
3544 });
3545
3547 47911, // EMP
3548 48620, // Wing Buffet
3549 51752 // Stampy's Stompy-Stomp
3550 }, [](SpellInfo* spellInfo)
3551 {
3552 spellInfo->RecoveryTime = 10000;
3553 });
3554
3556 37727, // Touch of Darkness
3557 54996 // Ice Slick (tooltip says 20s but sniffs say 12s)
3558 }, [](SpellInfo* spellInfo)
3559 {
3560 spellInfo->RecoveryTime = 12000;
3561 });
3562
3563 // Signal Helmet to Attack
3564 ApplySpellFix({ 51748 }, [](SpellInfo* spellInfo)
3565 {
3566 spellInfo->RecoveryTime = 15000;
3567 });
3568
3570 51756, // Charge
3571 37919, //Arcano-dismantle
3572 37917 //Arcano-Cloak
3573 }, [](SpellInfo* spellInfo)
3574 {
3575 spellInfo->RecoveryTime = 20000;
3576 });
3577
3578 // Kaw the Mammoth Destroyer
3579 ApplySpellFix({ 46260 }, [](SpellInfo* spellInfo)
3580 {
3581 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3582 });
3583
3584 // That's Abominable
3585 ApplySpellFix({ 59565 }, [](SpellInfo* spellInfo)
3586 {
3587 spellInfo->Effects[EFFECT_0].MiscValueB = 1721; // controlable guardian
3588 });
3589
3590 // Investigate the Blue Recluse (1920)
3591 // Investigate the Alchemist Shop (1960)
3592 ApplySpellFix({ 9095 }, [](SpellInfo* spellInfo)
3593 {
3594 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_DUMMY;
3595 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
3596 });
3597
3598 // Gauging the Resonant Frequency (10594)
3599 ApplySpellFix({ 37390 }, [](SpellInfo* spellInfo)
3600 {
3601 spellInfo->Effects[EFFECT_0].MiscValueB = 181;
3602 });
3603
3604 // Where in the World is Hemet Nesingwary? (12521)
3605 ApplySpellFix({ 50860 }, [](SpellInfo* spellInfo)
3606 {
3607 spellInfo->Effects[EFFECT_0].BasePoints = 50860;
3608 });
3609
3610 ApplySpellFix({ 50861 }, [](SpellInfo* spellInfo)
3611 {
3612 spellInfo->Effects[EFFECT_0].BasePoints = 0;
3613 });
3614
3615 // Riding Jokkum
3616 ApplySpellFix({ 56606 }, [](SpellInfo* spellInfo)
3617 {
3618 spellInfo->Effects[EFFECT_0].BasePoints = 1;
3619 });
3620
3621 // Blightbeasts be Damned! (12072)
3622 ApplySpellFix({ 47424 }, [](SpellInfo* spellInfo)
3623 {
3624 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_NOT_ABOVEWATER;
3625 });
3626
3627 // Dark Horizon (12664), Reunited (12663)
3628 ApplySpellFix({ 52190 }, [](SpellInfo* spellInfo)
3629 {
3630 spellInfo->Effects[EFFECT_0].BasePoints = 52391 - 1;
3631 });
3632
3633 // The Sum is Greater than the Parts (13043) - Chained Grip
3634 ApplySpellFix({ 60540 }, [](SpellInfo* spellInfo)
3635 {
3636 spellInfo->Effects[EFFECT_0].MiscValue = 300;
3637 });
3638
3639 // Not a Bug (13342)
3640 ApplySpellFix({ 60531 }, [](SpellInfo* spellInfo)
3641 {
3642 spellInfo->AttributesEx2 |= SPELL_ATTR2_ALLOW_DEAD_TARGET;
3643 });
3644
3645 // Frankly, It Makes No Sense... (10672)
3646 ApplySpellFix({ 37851 }, [](SpellInfo* spellInfo)
3647 {
3648 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
3649 });
3650
3651 // Honor Challenge (12939)
3652 ApplySpellFix({ 21855 }, [](SpellInfo* spellInfo)
3653 {
3654 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
3655 });
3656
3657 // Convocation at Zol'Heb (12730)
3658 ApplySpellFix({ 52956 }, [](SpellInfo* spellInfo)
3659 {
3660 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_DEST_AREA_ENTRY);
3661 });
3662
3663 // Mangletooth
3665 7764, // Wisdom of Agamaggan
3666 10767, // Rising Spirit
3667 16610, // Razorhide
3668 16612, // Agamaggan's Strength
3669 16618, // Spirit of the Wind
3670 17013 // Agamaggan's Agility
3671 }, [](SpellInfo* spellInfo)
3672
3673 {
3674 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3675 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT;
3676 });
3677
3678 //Crushing the Crown
3679 ApplySpellFix({ 71024 }, [](SpellInfo* spellInfo)
3680 {
3681 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DYNOBJ_NONE);
3682 });
3683
3684 // Battle for the Undercity
3686 59892 // Cyclone fall
3687 }, [](SpellInfo* spellInfo)
3688 {
3689 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AREA_AURA_FRIEND;
3690 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
3691 spellInfo->AttributesEx &= ~SPELL_ATTR0_NO_AURA_CANCEL;
3692 spellInfo->AttributesEx3 |= SPELL_ATTR3_ONLY_ON_PLAYER;
3693 });
3694
3695 // enchant Lightweave Embroidery
3696 ApplySpellFix({ 55637 }, [](SpellInfo* spellInfo)
3697 {
3698 spellInfo->Effects[EFFECT_1].MiscValue = 126;
3699 });
3700
3702 47977, // Magic Broom
3703 65917 // Magic Rooster
3704 }, [](SpellInfo* spellInfo)
3705 {
3706 // First two effects apply auras, which shouldn't be there
3707 // due to NO_TARGET applying aura on current caster (core bug)
3708 // Just wipe effect data, to mimic blizz-behavior
3709 spellInfo->Effects[EFFECT_0].Effect = 0;
3710 spellInfo->Effects[EFFECT_1].Effect = 0;
3711 });
3712
3713 // Titanium Seal of Dalaran, Toss your luck
3714 ApplySpellFix({ 60476 }, [](SpellInfo* spellInfo)
3715 {
3716 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
3717 });
3718
3719 // Mind Amplification Dish, change charm aura
3720 ApplySpellFix({ 26740 }, [](SpellInfo* spellInfo)
3721 {
3722 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_MOD_CHARM;
3723 });
3724
3725 // Persistent Shield
3726 ApplySpellFix({ 26467 }, [](SpellInfo* spellInfo)
3727 {
3728 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE;
3729 spellInfo->Effects[EFFECT_0].TriggerSpell = 26470;
3730 });
3731
3732 // Deadly Swiftness
3733 ApplySpellFix({ 31255 }, [](SpellInfo* spellInfo)
3734 {
3735 spellInfo->Effects[EFFECT_0].TriggerSpell = 22588;
3736 });
3737
3738 // Black Magic enchant
3739 ApplySpellFix({ 59630 }, [](SpellInfo* spellInfo)
3740 {
3741 spellInfo->Attributes |= SPELL_ATTR0_PASSIVE;
3742 });
3743
3744 // Precious's Ribbon
3745 ApplySpellFix({ 72968 }, [](SpellInfo* spellInfo)
3746 {
3747 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
3748 });
3749
3751 71646, // Item - Bauble of True Blood 10m
3752 71607, // Item - Bauble of True Blood 25m
3753 71610, // Item - Althor's Abacus trigger 10m
3754 71641 // Item - Althor's Abacus trigger 25m
3755 }, [](SpellInfo* spellInfo)
3756 {
3757 spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
3758 spellInfo->SpellLevel = 0;
3759 });
3760
3762 6789, // Warlock - Death Coil (Rank 1)
3763 17925, // Warlock - Death Coil (Rank 2)
3764 17926, // Warlock - Death Coil (Rank 3)
3765 27223, // Warlock - Death Coil (Rank 4)
3766 47859, // Warlock - Death Coil (Rank 5)
3767 71838, // Drain Life - Bryntroll Normal
3768 71839 // Drain Life - Bryntroll Heroic
3769 }, [](SpellInfo* spellInfo)
3770 {
3771 spellInfo->AttributesEx2 |= SPELL_ATTR2_CANT_CRIT;
3772 });
3773
3774 // Alchemist's Stone
3775 ApplySpellFix({ 17619 }, [](SpellInfo* spellInfo)
3776 {
3777 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
3778 });
3779
3780 // Stormchops
3781 ApplySpellFix({ 43730 }, [](SpellInfo* spellInfo)
3782 {
3783 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(1);
3784 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
3785 });
3786
3787 // Savory Deviate Delight (transformations), allow to mount while transformed
3788 ApplySpellFix({ 8219, 8220, 8221, 8222 }, [](SpellInfo* spellInfo)
3789 {
3790 spellInfo->Attributes &= ~SPELL_ATTR0_NO_IMMUNITIES;
3791 });
3792
3793 // Clamlette Magnifique
3794 ApplySpellFix({ 72623 }, [](SpellInfo* spellInfo)
3795 {
3796 spellInfo->Effects[EFFECT_0].BasePoints = spellInfo->Effects[EFFECT_1].BasePoints;
3797 });
3798
3799 // Compact Harvest Reaper
3800 ApplySpellFix({ 4078 }, [](SpellInfo* spellInfo)
3801 {
3802 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(6); // 10 minutes
3803 });
3804
3805 // Dragon Kite, Tuskarr Kite - Kite String
3806 ApplySpellFix({ 45192 }, [](SpellInfo* spellInfo)
3807 {
3808 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100yd
3809 });
3810
3811 // Frigid Frostling, Infrigidate
3812 ApplySpellFix({ 74960 }, [](SpellInfo* spellInfo)
3813 {
3814 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd
3815 });
3816
3817 // Apple Trap
3818 ApplySpellFix({ 43450 }, [](SpellInfo* spellInfo)
3819 {
3820 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
3821 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
3822 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_DUMMY;
3823 });
3824
3825 // Dark Iron Attack - spawn mole machine
3826 ApplySpellFix({ 43563 }, [](SpellInfo* spellInfo)
3827 {
3828 spellInfo->Effects[EFFECT_2].Effect = 0; // summon GO's manually
3829 });
3830
3831 // Throw Mug visual
3832 ApplySpellFix({ 42300 }, [](SpellInfo* spellInfo)
3833 {
3834 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3835 });
3836
3837 // Dark Iron knockback Aura
3838 ApplySpellFix({ 42299 }, [](SpellInfo* spellInfo)
3839 {
3840 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_DUMMY;
3841 spellInfo->Effects[EFFECT_0].MiscValue = 100;
3842 spellInfo->Effects[EFFECT_0].BasePoints = 79;
3843 });
3844
3845 // Chug and Chuck!
3846 ApplySpellFix({ 42436 }, [](SpellInfo* spellInfo)
3847 {
3848 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
3849 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
3850 spellInfo->MaxAffectedTargets = 0;
3851 spellInfo->ExcludeCasterAuraSpell = 42299;
3852 });
3853
3854 // Brewfest quests
3855 ApplySpellFix({ 47134, 51798 }, [](SpellInfo* spellInfo)
3856 {
3857 spellInfo->Effects[EFFECT_0].Effect = 0;
3858 });
3859
3860 // The Heart of The Storms (12998)
3861 ApplySpellFix({ 43528 }, [](SpellInfo* spellInfo)
3862 {
3863 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(18);
3864 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
3865 });
3866
3867 // Water splash
3868 ApplySpellFix({ 42348 }, [](SpellInfo* spellInfo)
3869 {
3870 spellInfo->Effects[EFFECT_0].Effect = 0;
3871 });
3872
3873 // Summon Lantersn
3874 ApplySpellFix({ 44255, 44231 }, [](SpellInfo* spellInfo)
3875 {
3876 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
3877 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
3878 });
3879
3880 // Throw Head Back
3881 ApplySpellFix({ 42401 }, [](SpellInfo* spellInfo)
3882 {
3883 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_NEARBY_ENTRY);
3884 });
3885
3886 // Food
3887 ApplySpellFix({ 65418 }, [](SpellInfo* spellInfo)
3888 {
3889 spellInfo->Effects[EFFECT_2].TriggerSpell = 65410;
3890 });
3891
3892 ApplySpellFix({ 65422 }, [](SpellInfo* spellInfo)
3893 {
3894 spellInfo->Effects[EFFECT_2].TriggerSpell = 65414;
3895 });
3896
3897 ApplySpellFix({ 65419 }, [](SpellInfo* spellInfo)
3898 {
3899 spellInfo->Effects[EFFECT_2].TriggerSpell = 65416;
3900 });
3901
3902 ApplySpellFix({ 65420 }, [](SpellInfo* spellInfo)
3903 {
3904 spellInfo->Effects[EFFECT_2].TriggerSpell = 65412;
3905 });
3906
3907 ApplySpellFix({ 65421 }, [](SpellInfo* spellInfo)
3908 {
3909 spellInfo->Effects[EFFECT_2].TriggerSpell = 65415;
3910 });
3911
3912 // Stamp Out Bonfire
3913 ApplySpellFix({ 45437 }, [](SpellInfo* spellInfo)
3914 {
3915 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_DUMMY;
3916 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_NEARBY_ENTRY);
3917 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3918 });
3919
3920 // Light Bonfire (DND)
3921 ApplySpellFix({ 29831 }, [](SpellInfo* spellInfo)
3922 {
3923 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3924 });
3925
3926 // Infernal
3927 ApplySpellFix({ 33240 }, [](SpellInfo* spellInfo)
3928 {
3929 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3930 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3931 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3932 });
3933
3935 47476, // Deathknight - Strangulate
3936 15487, // Priest - Silence
3937 5211, // Druid - Bash - R1
3938 6798, // Druid - Bash - R2
3939 8983 // Druid - Bash - R3
3940 }, [](SpellInfo* spellInfo)
3941 {
3942 spellInfo->AttributesEx7 |= SPELL_ATTR7_CAN_CAUSE_INTERRUPT;
3943 });
3944
3945 // Shadowmeld
3946 ApplySpellFix({ 58984 }, [](SpellInfo* spellInfo)
3947 {
3948 spellInfo->AttributesEx3 |= SPELL_ATTR3_ONLY_ON_PLAYER;
3949 });
3950
3951 // Flare activation speed
3952 ApplySpellFix({ 1543 }, [](SpellInfo* spellInfo)
3953 {
3954 spellInfo->Speed = 0.0f;
3955 });
3956
3957 // Light's Beacon
3958 ApplySpellFix({ 53651 }, [](SpellInfo* spellInfo)
3959 {
3960 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
3961 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3962 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
3963 });
3964
3965 // Shadow Hunter Vosh'gajin - Hex
3966 ApplySpellFix({ 16097 }, [](SpellInfo* spellInfo)
3967 {
3968 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(16);
3969 });
3970
3971 // Sacred Cleansing
3972 ApplySpellFix({ 53659 }, [](SpellInfo* spellInfo)
3973 {
3974 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(5); // 40yd
3975 });
3976
3977 // Silithyst
3978 ApplySpellFix({ 29519 }, [](SpellInfo* spellInfo)
3979 {
3980 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_MOD_DECREASE_SPEED;
3981 spellInfo->Effects[EFFECT_0].BasePoints = -25;
3982 });
3983
3984 // Focused Eyebeam Summon Trigger
3985 ApplySpellFix({ 63342 }, [](SpellInfo* spellInfo)
3986 {
3987 spellInfo->MaxAffectedTargets = 1;
3988 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
3989 });
3990
3991 // Eye of Kilrogg Passive (DND)
3992 ApplySpellFix({ 2585 }, [](SpellInfo* spellInfo)
3993 {
3994 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE;
3995 });
3996
3997 // Nefarius Corruption
3998 ApplySpellFix({ 23642 }, [](SpellInfo* spellInfo)
3999 {
4000 spellInfo->MaxAffectedTargets = 1;
4001 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
4002 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
4003 });
4004
4005 // Conflagration, Horseman's Cleave
4006 ApplySpellFix({ 42380, 42587 }, [](SpellInfo* spellInfo)
4007 {
4008 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
4009 });
4010
4011 // Serverside - Summon Arcane Disruptor
4012 ApplySpellFix({ 49591 }, [](SpellInfo* spellInfo)
4013 {
4014 spellInfo->ProcChance = 101;
4015 spellInfo->Effects[EFFECT_1].Effect = 24;
4016 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(25);
4017 spellInfo->Effects[EFFECT_1].ItemType = 37888;
4018 });
4019
4020 // Serverside - Create Rocket Pack
4021 ApplySpellFix({ 70055 }, [](SpellInfo* spellInfo)
4022 {
4023 spellInfo->ProcChance = 101;
4024 spellInfo->Effects[EFFECT_1].Effect = 24;
4025 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(25);
4026 spellInfo->Effects[EFFECT_1].ItemType = 49278;
4027 });
4028
4029 // Ashenvale Outrunner Sneak
4030 // Stealth
4031 ApplySpellFix({ 20540, 32199 }, [](SpellInfo* spellInfo)
4032 {
4033 spellInfo->AuraInterruptFlags |= (AURA_INTERRUPT_FLAG_MELEE_ATTACK | AURA_INTERRUPT_FLAG_CAST);
4034 });
4035
4036 // Arcane Bolt
4037 ApplySpellFix({ 15979 }, [](SpellInfo* spellInfo)
4038 {
4039 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(3); // 20y
4040 });
4041
4042 // Mortal Shots
4043 ApplySpellFix({ 19485, 19487, 19488, 19489, 19490 }, [](SpellInfo* spellInfo)
4044 {
4045 spellInfo->Effects[EFFECT_0].SpellClassMask[0] |= 0x00004000;
4046 spellInfo->Effects[EFFECT_1].Effect = 0;
4047 });
4048
4049 // Item - Death Knight T9 Melee 4P Bonus
4050 // Item - Hunter T9 2P Bonus
4051 // Item - Paladin T9 Retribution 2P Bonus (Righteous Vengeance)
4052 ApplySpellFix({ 67118, 67150, 67188 }, [](SpellInfo* spellInfo)
4053 {
4054 spellInfo->Effects[EFFECT_1].Effect = 0;
4055 });
4056
4057 // Green Beam
4058 ApplySpellFix({31628, 31630, 31631}, [](SpellInfo* spellInfo)
4059 {
4060 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
4061 spellInfo->MaxAffectedTargets = 1;
4062 });
4063
4065 20271, 57774, // Judgement of Light
4066 20425, // Judgement of Command
4067 32220, // Judgement of Blood
4068 53407, // Judgement of Justice
4069 53408, // Judgement of Wisdom
4070 53725 // Judgement of the Martyr
4071 }, [](SpellInfo* spellInfo)
4072 {
4073 spellInfo->AttributesEx3 &= ~SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
4074 });
4075
4076 // Chaos Bolt Passive
4077 ApplySpellFix({ 58284 }, [](SpellInfo* spellInfo)
4078 {
4079 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
4080 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST;
4081 spellInfo->Effects[EFFECT_1].BasePoints = 100;
4082 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
4083 spellInfo->Effects[EFFECT_1].MiscValue = 127;
4084 spellInfo->Effects[EFFECT_1].SpellClassMask[1] = 0x00020000;
4085 });
4086
4087 // Nefarian: Shadowbolt, Shadow Command
4088 ApplySpellFix({ 22667, 22677 }, [](SpellInfo* spellInfo)
4089 {
4090 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(152); // 150 yards
4091 });
4092
4093 // Manastorm
4094 ApplySpellFix({ 21097 }, [](SpellInfo* spellInfo)
4095 {
4096 spellInfo->InterruptFlags &= ~SPELL_INTERRUPT_FLAG_INTERRUPT;
4097 });
4098
4099 // Arcane Vacuum
4100 ApplySpellFix({ 21147 }, [](SpellInfo* spellInfo)
4101 {
4102 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(4); // 30 yards
4103 spellInfo->AttributesEx3 |= SPELL_ATTR3_ONLY_ON_PLAYER;
4104 });
4105
4106 // Reflection
4107 ApplySpellFix({ 22067 }, [](SpellInfo* spellInfo)
4108 {
4109 spellInfo->Dispel = DISPEL_NONE;
4110 });
4111
4112 // Focused Assault
4113 // Brutal Assault
4114 ApplySpellFix({ 46392, 46393 }, [](SpellInfo* spellInfo)
4115 {
4116 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
4117 });
4118
4119 // Improved Blessing Protection (Nefarian Class Call)
4120 ApplySpellFix({ 23415 }, [](SpellInfo* spellInfo)
4121 {
4122 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ENEMY);
4123 });
4124
4125 // Bestial Wrath
4126 ApplySpellFix({ 19574 }, [](SpellInfo* spellInfo)
4127 {
4128 spellInfo->AttributesEx4 |= SPELL_ATTR4_AURA_EXPIRES_OFFLINE;
4129 });
4130
4131 // Shadowflame
4132 ApplySpellFix({ 22539 }, [](SpellInfo* spellInfo)
4133 {
4134 spellInfo->InterruptFlags &= ~SPELL_INTERRUPT_FLAG_INTERRUPT;
4135 });
4136
4137 // PX-238 Winter Wondervolt
4138 ApplySpellFix({ 26157, 26272, 26273, 26274 }, [](SpellInfo* spellInfo)
4139 {
4140 spellInfo->Mechanic = 0;
4141 });
4142
4143 // Calm Dragonkin
4144 ApplySpellFix({ 19872 }, [](SpellInfo* spellInfo)
4145 {
4146 spellInfo->AttributesEx |= SPELL_ATTR1_EXCLUDE_CASTER;
4147 });
4148
4149 // Cosmetic - Lightning Beam Channel
4150 ApplySpellFix({ 45537 }, [](SpellInfo* spellInfo)
4151 {
4152 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4153 });
4154
4155 // Burning Adrenaline
4156 ApplySpellFix({ 23478 }, [](SpellInfo* spellInfo)
4157 {
4158 spellInfo->Effects[EFFECT_0].BasePoints = 4374;
4159 spellInfo->Effects[EFFECT_0].DieSides = 1250;
4160 });
4161
4162 // Explosion - Razorgore
4163 ApplySpellFix({ 20038 }, [](SpellInfo* spellInfo)
4164 {
4165 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS);
4166 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
4167 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4168 });
4169
4170 // Brood Power : Bronze
4171 ApplySpellFix({ 22311 }, [](SpellInfo* spellInfo)
4172 {
4173 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
4174 });
4175
4176 // Rapture
4177 ApplySpellFix({ 63652, 63653, 63654, 63655 }, [](SpellInfo* spellInfo)
4178 {
4179 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
4180 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4181 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
4182 });
4183
4184 // Everlasting Affliction
4185 ApplySpellFix({ 47422 }, [](SpellInfo* spellInfo)
4186 {
4187 spellInfo->SchoolMask = SPELL_SCHOOL_MASK_SHADOW;
4188 });
4189
4190 // Flametongue Weapon (Passive) (Rank 6)
4191 ApplySpellFix({ 16312 }, [](SpellInfo* spellInfo)
4192 {
4193 spellInfo->Attributes |= SPELL_ATTR0_PASSIVE;
4194 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21);
4195 });
4196
4197 // Mana Tide Totem
4198 // Cleansing Totem Effect
4199 ApplySpellFix({ 39609, 52025 }, [](SpellInfo* spellInfo)
4200 {
4201 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(5); // 40yd
4202 });
4203
4204 // Increased Totem Radius
4205 ApplySpellFix({ 21895 }, [](SpellInfo* spellInfo)
4206 {
4207 spellInfo->Effects[0].SpellClassMask = flag96(0x0603E000, 0x00200100);
4208 });
4209
4210 // Jokkum Summon
4211 ApplySpellFix({ 56541 }, [](SpellInfo* spellInfo)
4212 {
4213 spellInfo->Effects[EFFECT_0].MiscValueB = 844;
4214 });
4215
4216 // Hakkar Cause Insanity
4217 ApplySpellFix({ 24327 }, [](SpellInfo* spellInfo)
4218 {
4219 spellInfo->Dispel = DISPEL_NONE;
4220 });
4221
4222 // Summon Nightmare Illusions
4223 ApplySpellFix({ 24681, 24728, 24729 }, [](SpellInfo* spellInfo)
4224 {
4225 spellInfo->Effects[EFFECT_0].MiscValueB = 64;
4226 });
4227
4228 // Blood Siphon
4229 ApplySpellFix({ 24322, 24323 }, [](SpellInfo* spellInfo)
4230 {
4231 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_MOD_STUN;
4232 spellInfo->Effects[EFFECT_2].Effect = 0;
4233 spellInfo->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
4234 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL;
4235 spellInfo->ChannelInterruptFlags &= ~AURA_INTERRUPT_FLAG_MOVE;
4236 });
4237
4238 // Place Fake Fur
4239 ApplySpellFix({ 46085 }, [](SpellInfo* spellInfo)
4240 {
4241 spellInfo->Effects[EFFECT_0].MiscValue = 8;
4242 });
4243
4244 // Smash Mammoth Trap
4245 ApplySpellFix({ 46201 }, [](SpellInfo* spellInfo)
4246 {
4247 spellInfo->Effects[EFFECT_0].MiscValue = 8;
4248 });
4249
4250 // Elemental Mastery
4251 ApplySpellFix({ 16166 }, [](SpellInfo* spellInfo)
4252 {
4253 spellInfo->Effects[EFFECT_0].SpellClassMask = flag96(0x00000003, 0x00001000);
4254 });
4255
4256 // Elemental Vulnerability
4257 ApplySpellFix({ 28772 }, [](SpellInfo* spellInfo)
4258 {
4259 spellInfo->Speed = 1;
4260 });
4261
4262 // Find the Ancient Hero: Kill Credit
4263 ApplySpellFix({ 25729 }, [](SpellInfo* spellInfo)
4264 {
4265 spellInfo->Effects[EFFECT_0].TargetA = TARGET_UNIT_SUMMONER;
4266 });
4267
4268 // Artorius Demonic Doom
4269 ApplySpellFix({ 23298 }, [](SpellInfo* spellInfo)
4270 {
4271 spellInfo->AttributesEx4 |= SPELL_ATTR4_IGNORE_DAMAGE_TAKEN_MODIFIERS;
4272 spellInfo->AttributesEx6 |= SPELL_ATTR6_IGNORE_CASTER_DAMAGE_MODIFIERS;
4273 });
4274
4275 // Lash
4276 ApplySpellFix({ 25852 }, [](SpellInfo* spellInfo)
4277 {
4278 spellInfo->Effects[EFFECT_1].Effect = 0;
4279 });
4280
4281 // Explosion
4282 ApplySpellFix({ 5255 }, [](SpellInfo* spellInfo)
4283 {
4284 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4285 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
4286 });
4287
4288 // Death's Respite
4289 ApplySpellFix({ 67731, 68305 }, [](SpellInfo* spellInfo)
4290 {
4291 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
4292 });
4293
4294 // Wyvern Sting DoT
4295 ApplySpellFix({ 24131, 24134, 24135 }, [](SpellInfo* spellInfo)
4296 {
4297 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
4298 });
4299
4300 // Feed Pet
4301 ApplySpellFix({ 1539, 51284 }, [](SpellInfo* spellInfo)
4302 {
4303 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_WHILE_SITTING;
4304 });
4305
4306 // Judgement (Paladin T2 8P Bonus)
4307 // Battlegear of Eternal Justice
4308 ApplySpellFix({ 23591, 26135 }, [](SpellInfo* spellInfo)
4309 {
4310 spellInfo->ProcFlags = PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS;
4311 });
4312
4313 // Gift of Arthas
4314 ApplySpellFix({ 11371 }, [](SpellInfo* spellInfo)
4315 {
4316 spellInfo->SpellFamilyName = SPELLFAMILY_POTION;
4317 });
4318
4319 // Refocus (Renataki's charm of beasts)
4320 ApplySpellFix({ 24531 }, [](SpellInfo* spellInfo)
4321 {
4322 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
4323 });
4324
4325 // Collect Rookery Egg
4326 ApplySpellFix({ 15958 }, [](SpellInfo* spellInfo)
4327 {
4328 spellInfo->Effects[EFFECT_1].Effect = 0;
4329 });
4330
4331 // WotLK Prologue Frozen Shade Visual, temp used to restore visual after Dispersion
4332 ApplySpellFix({ 53444 }, [](SpellInfo* spellInfo)
4333 {
4334 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(27);
4335 });
4336
4337 // Rental Racing Ram
4338 ApplySpellFix({ 43883 }, [](SpellInfo* spellInfo)
4339 {
4340 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_NOT_ABOVEWATER;
4341 });
4342
4343 // Summon Worm
4344 ApplySpellFix({ 518, 25831, 25832 }, [](SpellInfo* spellInfo)
4345 {
4346 spellInfo->Effects[EFFECT_0].MiscValueB = 64;
4347 });
4348
4349 // Uppercut
4350 ApplySpellFix({ 26007 }, [](SpellInfo* spellInfo)
4351 {
4352 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
4353 });
4354
4355 // Digestive Acid (Temporary)
4356 ApplySpellFix({ 26476 }, [](SpellInfo* spellInfo)
4357 {
4358 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
4359 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4360 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
4361 });
4362
4363 // Drums of War/Battle/Speed/Restoration
4364 ApplySpellFix({ 35475, 35476, 35477, 35478 }, [](SpellInfo* spellInfo)
4365 {
4366 spellInfo->ExcludeTargetAuraSpell = 51120;
4367 });
4368
4369 // Slap!
4370 ApplySpellFix({ 6754 }, [](SpellInfo* spellInfo)
4371 {
4372 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
4373 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
4374 });
4375
4376 // Summon Cauldron Stuff
4377 ApplySpellFix({ 36549 }, [](SpellInfo* spellInfo)
4378 {
4379 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(28); // 5 seconds
4380 spellInfo->Effects[EFFECT_0].TargetB = TARGET_DEST_CASTER;
4381 });
4382
4383 // Hunter's Mark
4384 ApplySpellFix({ 31615 }, [](SpellInfo* spellInfo)
4385 {
4386 for (uint8 index = EFFECT_0; index <= EFFECT_1; ++index)
4387 {
4388 spellInfo->Effects[index].TargetA = TARGET_UNIT_TARGET_ENEMY;
4389 spellInfo->Effects[index].TargetB = 0;
4390 }
4391 });
4392
4393 // Self Visual - Sleep Until Cancelled(DND)
4394 ApplySpellFix({ 6606, 14915, 16093 }, [](SpellInfo* spellInfo)
4395 {
4396 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_NOT_SEATED;
4397 });
4398
4399 // Cleansing Totem, Healing Stream Totem, Mana Tide Totem
4400 ApplySpellFix({ 8171,52025, 52041, 52042, 52046, 52047, 52048, 52049, 52050, 58759, 58760, 58761, 39610, 39609 }, [](SpellInfo* spellInfo)
4401 {
4402 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4403 });
4404 // Game In Session
4405 ApplySpellFix({ 39331 }, [](SpellInfo* spellInfo)
4406 {
4407 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AURA;
4408 spellInfo->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
4409 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
4410 });
4411 // Death Ray Warning Visual, Death Ray Damage Visual
4412 ApplySpellFix({ 63882, 63886 }, [](SpellInfo* spellInfo)
4413 {
4414 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL;
4415 });
4416
4417 // Buffeting Winds of Susurrus
4418 ApplySpellFix({ 32474 }, [](SpellInfo* spellInfo)
4419 {
4420 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(556); // 28 seconds
4421 });
4422
4423 // Quest - Healing Salve
4424 ApplySpellFix({ 29314 }, [](SpellInfo* spellInfo)
4425 {
4426 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(1); // 0s
4427 });
4428
4429 // Seed of Corruption
4430 ApplySpellFix({ 27285, 47833, 47834 }, [](SpellInfo* spellInfo)
4431 {
4432 spellInfo->AttributesEx |= SPELL_ATTR1_NO_REFLECTION;
4433 });
4434
4435 // Turn the Tables
4436 ApplySpellFix({ 51627, 51628, 51629 }, [](SpellInfo* spellInfo)
4437 {
4438 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
4439 });
4440
4441 // Silence
4442 ApplySpellFix({ 18278 }, [](SpellInfo* spellInfo)
4443 {
4444 spellInfo->AttributesEx4 |= SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND;
4445 });
4446
4447 // Absorb Life
4448 ApplySpellFix({ 34239 }, [](SpellInfo* spellInfo)
4449 {
4450 spellInfo->Effects[EFFECT_0].ValueMultiplier = 1;
4451 });
4452
4453 // Summon a Warp Rift in Void Ridge
4454 ApplySpellFix({ 35036 }, [](SpellInfo* spellInfo)
4455 {
4456 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(1); // 0s
4457 });
4458
4459 // Hit Rating (Dungeon T3 - 2P Bonus - Wastewalker, Doomplate)
4460 ApplySpellFix({ 37608, 37610 }, [](SpellInfo* spellInfo)
4461 {
4462 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(0);
4463 spellInfo->Effects[EFFECT_0].MiscValue = 224;
4464 });
4465
4466 // Target Fissures
4467 ApplySpellFix({ 30745 }, [](SpellInfo* spellInfo)
4468 {
4469 spellInfo->MaxAffectedTargets = 1;
4470 });
4471
4472 // Acid Spit
4473 ApplySpellFix({ 34290 }, [](SpellInfo* spellInfo)
4474 {
4475 spellInfo->MaxAffectedTargets = 1;
4476 });
4477
4478 // Mulgore Hatchling (periodic)
4479 ApplySpellFix({ 62586 }, [](SpellInfo* spellInfo)
4480 {
4481 spellInfo->Effects[EFFECT_0].TriggerSpell = 62585; // Mulgore Hatchling (fear)
4482 });
4483
4484 // Poultryized!
4485 ApplySpellFix({ 30504 }, [](SpellInfo* spellInfo)
4486 {
4487 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_TAKE_DAMAGE;
4488 });
4489
4490 // Torment of the Worgen
4491 ApplySpellFix({ 30567 }, [](SpellInfo* spellInfo)
4492 {
4493 spellInfo->ProcChance = 3;
4494 });
4495
4496 // Summon Water Elementals
4497 ApplySpellFix({ 29962, 37051, 37052, 37053 }, [](SpellInfo* spellInfo)
4498 {
4499 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
4500 });
4501
4502 // Instill Lord Valthalak's Spirit DND
4503 ApplySpellFix({ 27360 }, [](SpellInfo* spellInfo)
4504 {
4505 spellInfo->ChannelInterruptFlags |= AURA_INTERRUPT_FLAG_MOVE;
4506 });
4507
4508 // Holiday - Midsummer, Ribbon Pole Periodic Visual
4509 ApplySpellFix({ 45406 }, [](SpellInfo* spellInfo)
4510 {
4511 spellInfo->AuraInterruptFlags |= ( AURA_INTERRUPT_FLAG_MOUNT | AURA_INTERRUPT_FLAG_CAST | AURA_INTERRUPT_FLAG_TALK );
4512 });
4513
4514 // Improved Mind Flay and Smite
4515 ApplySpellFix({ 37571 }, [](SpellInfo* spellInfo)
4516 {
4517 spellInfo->Effects[EFFECT_0].SpellClassMask[0] = 8388736;
4518 });
4519
4520 // Improved Corruption and Immolate (Updated)
4521 ApplySpellFix({ 61992 }, [](SpellInfo* spellInfo)
4522 {
4523 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
4524 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_ADD_PCT_MODIFIER;
4525 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
4526 spellInfo->Effects[EFFECT_1].BasePoints = 4;
4527 spellInfo->Effects[EFFECT_1].DieSides = 1;
4528 spellInfo->Effects[EFFECT_1].MiscValue = 22;
4529 spellInfo->Effects[EFFECT_1].SpellClassMask[0] = 6;
4530 });
4531
4532 // 46747 Fling torch
4533 ApplySpellFix({ 46747 }, [](SpellInfo* spellInfo)
4534 {
4535 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
4536 });
4537
4538 // Chains of Naberius
4539 ApplySpellFix({ 36146 }, [](SpellInfo* spellInfo)
4540 {
4541 spellInfo->MaxAffectedTargets = 1;
4542 });
4543
4544 // Force of Neltharaku
4545 ApplySpellFix({ 38762 }, [](SpellInfo* spellInfo)
4546 {
4547 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
4548 });
4549
4550 // Spotlight
4551 ApplySpellFix({ 29683, 32214 }, [](SpellInfo* spellInfo)
4552 {
4553 spellInfo->AttributesEx5 |= SPELL_ATTR5_DO_NOT_DISPLAY_DURATION;
4554 });
4555
4556 // Haunted
4557 ApplySpellFix({ 53768 }, [](SpellInfo* spellInfo)
4558 {
4559 spellInfo->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
4560 });
4561
4562 // Tidal Wave
4563 ApplySpellFix({ 37730 }, [](SpellInfo* spellInfo)
4564 {
4565 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4566 });
4567
4568 // Commanding Shout
4569 ApplySpellFix({ 469, 47439, 47440 }, [](SpellInfo* spellInfo)
4570 {
4571 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4572 });
4573
4574 // Battle Shout
4575 ApplySpellFix({ 2048, 5242, 6192, 6673, 11549, 11550, 11551, 25289, 47436 }, [](SpellInfo* spellInfo)
4576 {
4577 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4578 });
4579
4580 // Plague Effect
4581 ApplySpellFix({ 19594, 26557 }, [](SpellInfo* spellInfo)
4582 {
4583 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4584 });
4585
4586 // Prayer of Fortitude
4587 ApplySpellFix({ 21562, 21564, 25392, 48162 }, [](SpellInfo* spellInfo)
4588 {
4589 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4590 });
4591
4592 // Gift of the Wild
4593 ApplySpellFix({ 21849, 21850, 26991, 48470, 69381 }, [](SpellInfo* spellInfo)
4594 {
4595 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4596 });
4597
4598 // Arcane Brilliance
4599 ApplySpellFix({ 23028, 27127, 43002 }, [](SpellInfo* spellInfo)
4600 {
4601 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4602 });
4603
4604 // Prayer of Spirit
4605 ApplySpellFix({ 27681, 32999, 48074 }, [](SpellInfo* spellInfo)
4606 {
4607 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4608 });
4609
4610 // Prayer of Shadow Protection
4611 ApplySpellFix({ 27683, 39374, 48170 }, [](SpellInfo* spellInfo)
4612 {
4613 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4614 });
4615
4616 // Nagrand Fort Buff Reward Raid
4617 ApplySpellFix({ 33006 }, [](SpellInfo* spellInfo)
4618 {
4619 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4620 });
4621
4622 // Ancestral Awakening
4623 ApplySpellFix({ 52759 }, [](SpellInfo* spellInfo)
4624 {
4625 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4626 });
4627
4628 // Turn the Tables
4629 ApplySpellFix({ 52910, 52914, 52915 }, [](SpellInfo* spellInfo)
4630 {
4631 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4632 });
4633
4634 // Judgements of the Wise
4635 ApplySpellFix({ 54180 }, [](SpellInfo* spellInfo)
4636 {
4637 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4638 });
4639
4640 // Replenishment
4641 ApplySpellFix({ 57669 }, [](SpellInfo* spellInfo)
4642 {
4643 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4644 });
4645
4646 // Dalaran Brilliance
4647 ApplySpellFix({ 61316 }, [](SpellInfo* spellInfo)
4648 {
4649 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4650 });
4651
4652 // [DND] Dalaran Brilliance
4653 ApplySpellFix({ 61332 }, [](SpellInfo* spellInfo)
4654 {
4655 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4656 });
4657
4658 // Infinite Replenishment + Wisdom
4659 ApplySpellFix({ 61782 }, [](SpellInfo* spellInfo)
4660 {
4661 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4662 });
4663
4664 // Renewed Hope
4665 ApplySpellFix({ 63944 }, [](SpellInfo* spellInfo)
4666 {
4667 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4668 });
4669
4670 // Fortitude
4671 ApplySpellFix({ 69377 }, [](SpellInfo* spellInfo)
4672 {
4673 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4674 });
4675
4676 // Blessing of Forgotten Kings
4677 ApplySpellFix({ 69378 }, [](SpellInfo* spellInfo)
4678 {
4679 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4680 });
4681
4682 // Lucky Charm
4683 ApplySpellFix({ 69511 }, [](SpellInfo* spellInfo)
4684 {
4685 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4686 });
4687
4688 // Shiny Shard of the Scale Heal Targeter
4689 ApplySpellFix({ 69749 }, [](SpellInfo* spellInfo)
4690 {
4691 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4692 });
4693
4694 // Purified Shard of the Scale Heal Targeter
4695 ApplySpellFix({ 69754 }, [](SpellInfo* spellInfo)
4696 {
4697 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4698 });
4699
4700 // Brilliance
4701 ApplySpellFix({ 69994 }, [](SpellInfo* spellInfo)
4702 {
4703 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4704 });
4705
4706 // Domination
4707 ApplySpellFix({ 37135 }, [](SpellInfo* spellInfo)
4708 {
4709 spellInfo->MaxAffectedTargets = 5;
4710 });
4711
4712 // Presence Of Mind
4713 ApplySpellFix({ 12043 }, [](SpellInfo* spellInfo)
4714 {
4715 // It should not share cooldown mods with category[1151] spells (Arcane Power [12042], Decimate [47271])
4716 spellInfo->AttributesEx6 |= SPELL_ATTR6_NO_CATEGORY_COOLDOWN_MODS;
4717 });
4718
4719 // Eye of Grillok
4720 ApplySpellFix({ 38495 }, [](SpellInfo* spellInfo)
4721 {
4722 spellInfo->Effects[EFFECT_0].TriggerSpell = 38530; // Quest Credit for Eye of Grillok
4723 });
4724
4725 // Greater Fireball
4726 ApplySpellFix({ 33051 }, [](SpellInfo* spellInfo)
4727 {
4728 spellInfo->AttributesEx4 |= SPELL_ATTR4_NO_CAST_LOG;
4729 });
4730
4731 // Gor'drek's Ointment
4732 ApplySpellFix({ 32578 }, [](SpellInfo* spellInfo)
4733 {
4734 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
4735 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
4736 });
4737
4738 // Shadow Grasp
4739 ApplySpellFix({ 30410 }, [](SpellInfo* spellInfo)
4740 {
4741 spellInfo->AttributesEx6 |= SPELL_ATTR6_NO_PUSHBACK;
4742 });
4743
4745 471, // Palamino
4746 8980, // Skeletal Horse
4747 10788, // Leopard
4748 10790, // Tiger
4749 10792, // Spotted Panther
4750 60136, // Grand Caravan Mammoth
4751 60140 // Grand Caravan Mammoth
4752 }, [](SpellInfo* spellInfo)
4753 {
4754 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_NOT_ABOVEWATER;
4755 });
4756
4757 // Molten Punch
4758 ApplySpellFix({ 40126 }, [](SpellInfo* spellInfo)
4759 {
4760 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
4761 });
4762
4763 // Wing Buffet
4764 ApplySpellFix({ 37319 }, [](SpellInfo* spellInfo)
4765 {
4766 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CONE_ENEMY_24);
4767 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(0);
4768 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS);
4769 });
4770
4771 // Flame Wave
4772 ApplySpellFix({ 33800 }, [](SpellInfo* spellInfo)
4773 {
4774 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
4775 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_PERIODIC_TRIGGER_SPELL;
4776 spellInfo->Effects[EFFECT_1].Amplitude = 500;
4777 });
4778
4779 // Chromatic Resistance Aura
4780 ApplySpellFix({ 41453 }, [](SpellInfo* spellInfo)
4781 {
4782 spellInfo->Effects[EFFECT_0].MiscValue = 124;
4783 });
4784
4785 // Power of the Guardian
4786 ApplySpellFix({ 28142, 28143, 28144, 28145 }, [](SpellInfo* spellInfo)
4787 {
4788 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
4789 });
4790
4791 // Warrior stances passives
4793 2457, // Battle Stance
4794 2458, // Berserker Stance
4795 7376 // Defensive Stance Passive
4796 }, [](SpellInfo* spellInfo)
4797 {
4798 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
4799 });
4800
4801 // Conjure Refreshment Table (Rank 1, Rank 2)
4802 ApplySpellFix({ 43985, 58661 }, [](SpellInfo* spellInfo)
4803 {
4804 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER_FRONT);
4805 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_5_YARDS);
4806 });
4807
4809 698, // Ritual of Summoning (portal for clicking)
4810 61993 // Ritual of Summoning (summons the closet)
4811 }, [](SpellInfo* spellInfo)
4812 {
4813 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS);
4814 });
4815
4816 // Paralyze
4817 ApplySpellFix({ 41083 }, [](SpellInfo* spellInfo)
4818 {
4819 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL;
4820 });
4821
4822 // Fatal Attraction
4823 ApplySpellFix({ 40870 }, [](SpellInfo* spellInfo)
4824 {
4825 spellInfo->MaxAffectedTargets = 1;
4826 });
4827
4828 // Removing Dragonflayer Harpoon
4829 ApplySpellFix({ 42968 }, [](SpellInfo* spellInfo)
4830 {
4831 spellInfo->MaxAffectedTargets = 1;
4832 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(7);
4833 });
4834
4835 // Siphon Life (heal)
4836 ApplySpellFix({ 63106 }, [](SpellInfo* spellInfo)
4837 {
4838 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
4839 });
4840
4841 // Fury
4842 ApplySpellFix({ 40601 }, [](SpellInfo* spellInfo)
4843 {
4844 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
4845 });
4846
4847 // Claw Rage
4848 ApplySpellFix({ 43149 }, [](SpellInfo* spellInfo)
4849 {
4850 spellInfo->Effects[EFFECT_0].TriggerSpell = 0;
4851 });
4852
4853 // Black Qiraji Battle Tank
4854 ApplySpellFix({ 26655, 26656 }, [](SpellInfo* spellInfo)
4855 {
4856 spellInfo->AuraInterruptFlags &= ~(AURA_INTERRUPT_FLAG_CHANGE_MAP | AURA_INTERRUPT_FLAG_TELEPORTED);
4857 });
4858
4859 // Summon Cyclone
4860 ApplySpellFix({ 43112 }, [](SpellInfo* spellInfo)
4861 {
4862 spellInfo->RequiresSpellFocus = 0;
4863 });
4864
4865 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
4866 {
4867 SpellInfo* spellInfo = mSpellInfoMap[i];
4868 if (!spellInfo)
4869 {
4870 continue;
4871 }
4872
4873 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4874 {
4875 switch (spellInfo->Effects[j].Effect)
4876 {
4879 case SPELL_EFFECT_JUMP:
4882 if (!spellInfo->Speed && !spellInfo->SpellFamilyName)
4883 {
4884 spellInfo->Speed = SPEED_CHARGE;
4885 }
4886 break;
4887 }
4888
4889 // Xinef: i hope this will fix the problem with not working resurrection
4890 if (spellInfo->Effects[j].Effect == SPELL_EFFECT_SELF_RESURRECT)
4891 {
4892 spellInfo->Effects[j].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
4893 }
4894 }
4895
4896 // Fix range for trajectory triggered spell
4897 for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
4898 {
4899 if (spellEffectInfo.IsEffect() && (spellEffectInfo.TargetA.GetTarget() == TARGET_DEST_TRAJ || spellEffectInfo.TargetB.GetTarget() == TARGET_DEST_TRAJ))
4900 {
4901 // Get triggered spell if any
4902 if (SpellInfo* spellInfoTrigger = const_cast<SpellInfo*>(GetSpellInfo(spellEffectInfo.TriggerSpell)))
4903 {
4904 float maxRangeMain = spellInfo->RangeEntry ? spellInfo->RangeEntry->RangeMax[0] : 0.0f;
4905 float maxRangeTrigger = spellInfoTrigger->RangeEntry ? spellInfoTrigger->RangeEntry->RangeMax[0] : 0.0f;
4906
4907 // check if triggered spell has enough max range to cover trajectory
4908 if (maxRangeTrigger < maxRangeMain)
4909 spellInfoTrigger->RangeEntry = spellInfo->RangeEntry;
4910 }
4911 }
4912 }
4913
4914 if (spellInfo->ActiveIconID == 2158) // flight
4915 {
4916 spellInfo->Attributes |= SPELL_ATTR0_PASSIVE;
4917 }
4918
4919 switch (spellInfo->SpellFamilyName)
4920 {
4922 // Seals of the Pure should affect Seal of Righteousness
4923 if (spellInfo->SpellIconID == 25 && (spellInfo->Attributes & SPELL_ATTR0_PASSIVE))
4924 spellInfo->Effects[EFFECT_0].SpellClassMask[1] |= 0x20000000;
4925 break;
4927 // Icy Touch - extend FamilyFlags (unused value) for Sigil of the Frozen Conscience to use
4928 if (spellInfo->SpellIconID == 2721 && spellInfo->SpellFamilyFlags[0] & 0x2)
4929 spellInfo->SpellFamilyFlags[0] |= 0x40;
4930 break;
4931 case SPELLFAMILY_HUNTER:
4932 // Aimed Shot not affected by category cooldown modifiers
4933 if (spellInfo->SpellFamilyFlags[0] & 0x00020000)
4934 {
4936 spellInfo->RecoveryTime = 10 * IN_MILLISECONDS;
4937 }
4938 break;
4939 }
4940
4941 // Recklessness/Shield Wall/Retaliation
4942 if (spellInfo->CategoryEntry == sSpellCategoryStore.LookupEntry(132) && spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR)
4943 {
4945 }
4946 }
4947
4948 // Xinef: The Veiled Sea area in outlands (Draenei zone), client blocks casting flying mounts
4949 for (uint32 i = 0; i < sAreaTableStore.GetNumRows(); ++i)
4950 if (AreaTableEntry* areaEntry = const_cast<AreaTableEntry*>(sAreaTableStore.LookupEntry(i)))
4951 {
4952 if (areaEntry->ID == 3479)
4953 areaEntry->flags |= AREA_FLAG_NO_FLY_ZONE;
4954 // Xinef: Dun Morogh, Kharanos tavern, missing resting flag
4955 else if (areaEntry->ID == 2102)
4956 areaEntry->flags |= AREA_FLAG_REST_ZONE_ALLIANCE;
4957 }
4958
4959 // Xinef: fix for something?
4960 SummonPropertiesEntry* properties = const_cast<SummonPropertiesEntry*>(sSummonPropertiesStore.LookupEntry(121));
4961 properties->Type = SUMMON_TYPE_TOTEM;
4962 properties = const_cast<SummonPropertiesEntry*>(sSummonPropertiesStore.LookupEntry(647)); // 52893
4963 properties->Type = SUMMON_TYPE_TOTEM;
4964 if ((properties = const_cast<SummonPropertiesEntry*>(sSummonPropertiesStore.LookupEntry(628)))) // Hungry Plaguehound
4965 {
4966 properties->Category = SUMMON_CATEGORY_PET;
4967 properties->Type = SUMMON_TYPE_PET;
4968 }
4969
4970 // Correct Pet Size
4971 CreatureDisplayInfoEntry* displayEntry = const_cast<CreatureDisplayInfoEntry*>(sCreatureDisplayInfoStore.LookupEntry(17028)); // Kurken
4972 displayEntry->scale = 2.5f;
4973
4974 // Oracles and Frenzyheart faction
4975 FactionEntry* factionEntry = const_cast<FactionEntry*>(sFactionStore.LookupEntry(1104));
4976 factionEntry->ReputationFlags[0] = 0;
4977 factionEntry = const_cast<FactionEntry*>(sFactionStore.LookupEntry(1105));
4978 factionEntry->ReputationFlags[0] = 0;
4979
4980 // Various factions, added 14, 16 to hostile mask
4981 FactionTemplateEntry* factionTemplateEntry = const_cast<FactionTemplateEntry*>(sFactionTemplateStore.LookupEntry(1978)); // Warsong Offensive
4982 factionTemplateEntry->hostileMask |= 8;
4983 factionTemplateEntry = const_cast<FactionTemplateEntry*>(sFactionTemplateStore.LookupEntry(1921)); // The Taunka
4984 factionTemplateEntry->hostileMask |= 8;
4985
4986 // Remove 1 from guards friendly mask, making able to attack players
4987 factionTemplateEntry = const_cast<FactionTemplateEntry*>(sFactionTemplateStore.LookupEntry(1857)); // Area 52 Bruiser
4988 factionTemplateEntry->friendlyMask &= ~1;
4989 factionTemplateEntry = const_cast<FactionTemplateEntry*>(sFactionTemplateStore.LookupEntry(1806)); // Netherstorm Agent
4990 factionTemplateEntry->friendlyMask &= ~1;
4991 factionTemplateEntry = const_cast<FactionTemplateEntry*>(sFactionTemplateStore.LookupEntry(1812)); // K3 Bruiser
4992 factionTemplateEntry->friendlyMask &= ~1;
4993
4994 // Remove vehicles attr, making accessories selectable
4995 VehicleSeatEntry* vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(4689)); // Siege Engine, Accessory
4996 vse->m_flags &= ~VEHICLE_SEAT_FLAG_PASSENGER_NOT_SELECTABLE;
4997 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(4692)); // Siege Engine, Accessory
4998 vse->m_flags &= ~VEHICLE_SEAT_FLAG_PASSENGER_NOT_SELECTABLE;
4999 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(4693)); // Siege Engine, Accessory
5000 vse->m_flags &= ~VEHICLE_SEAT_FLAG_PASSENGER_NOT_SELECTABLE;
5001
5002 // pussywizard: fix z offset for some vehicles:
5003 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(6206)); // Marrowgar - Bone Spike
5004 vse->m_attachmentOffsetZ = 4.0f;
5005 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(3806)); // Mimiron - seat on VX-001 for ACU during last phase
5006 vse->m_attachmentOffsetZ = 15.0f;
5007 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(3566)); // Mimiron - Working seat
5008 vse->m_attachmentOffsetX = -3.5f;
5009 vse->m_attachmentOffsetY = 0.0f;
5010 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(3567)); // Mimiron - Working seat
5011 vse->m_attachmentOffsetX = 2.3f;
5012 vse->m_attachmentOffsetY = -2.3f;
5013
5014 // Pilgrim's Bounty offsets
5015 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(2841));
5016 vse->m_attachmentOffsetX += 1.65f;
5017 vse->m_attachmentOffsetY += 0.75f;
5018 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(2842));
5019 vse->m_attachmentOffsetX += 1.6f;
5020 vse->m_attachmentOffsetY += -1.0f;
5021 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(2843));
5022 vse->m_attachmentOffsetX += -1.2f;
5023 vse->m_attachmentOffsetY += 0.2f;
5024 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(2844));
5025 vse->m_attachmentOffsetX += -0.1f;
5026 vse->m_attachmentOffsetY += -1.6f;
5027 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(2845));
5028 vse->m_attachmentOffsetX += 0.0f;
5029 vse->m_attachmentOffsetY += 1.6f;
5030
5031 // Once Bitten, Twice Shy (10 player) - Icecrown Citadel
5032 AchievementEntry* achievement = const_cast<AchievementEntry*>(sAchievementStore.LookupEntry(4539));
5033 achievement->mapID = 631; // Correct map requirement (currently has Ulduar)
5034
5035 // Ring of Valor starting Locations
5036 GraveyardStruct const* entry = sGraveyard->GetGraveyard(1364);
5037 const_cast<GraveyardStruct*>(entry)->z += 6.0f;
5038 entry = sGraveyard->GetGraveyard(1365);
5039 const_cast<GraveyardStruct*>(entry)->z += 6.0f;
5040
5041 LockEntry* key = const_cast<LockEntry*>(sLockStore.LookupEntry(36)); // 3366 Opening, allows to open without proper key
5042 key->Type[2] = LOCK_KEY_NONE;
5043
5044 LOG_INFO("server.loading", ">> Loading spell dbc data corrections in {} ms", GetMSTimeDiffToNow(oldMSTime));
5045 LOG_INFO("server.loading", " ");
5046}
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
@ EFFECT_1
Definition: SharedDefines.h:32
@ EFFECT_0
Definition: SharedDefines.h:31
@ EFFECT_2
Definition: SharedDefines.h:33
@ POWER_MANA
Definition: SharedDefines.h:269
@ SPELL_ATTR7_DONT_CAUSE_SPELL_PUSHBACK
Definition: SharedDefines.h:647
@ SPELL_ATTR7_CAN_CAUSE_INTERRUPT
Definition: SharedDefines.h:652
@ SPELL_ATTR7_DISABLE_AURA_WHILE_DEAD
Definition: SharedDefines.h:643
@ SPELL_EFFECT_DUMMY
Definition: SharedDefines.h:781
@ SPELL_EFFECT_SCRIPT_EFFECT
Definition: SharedDefines.h:855
@ SPELL_EFFECT_POWER_BURN
Definition: SharedDefines.h:840
@ SPELL_EFFECT_APPLY_AREA_AURA_FRIEND
Definition: SharedDefines.h:906
@ SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
Definition: SharedDefines.h:920
@ SPELL_EFFECT_SELF_RESURRECT
Definition: SharedDefines.h:872
@ SPELL_EFFECT_TRIGGER_MISSILE
Definition: SharedDefines.h:810
@ SPELL_EFFECT_JUMP_DEST
Definition: SharedDefines.h:820
@ SPELL_EFFECT_MODIFY_THREAT_PERCENT
Definition: SharedDefines.h:903
@ SPELL_EFFECT_LEAP_BACK
Definition: SharedDefines.h:916
@ SPELL_EFFECT_CHARGE
Definition: SharedDefines.h:874
@ SPELL_EFFECT_CHARGE_DEST
Definition: SharedDefines.h:927
@ SPELL_EFFECT_JUMP
Definition: SharedDefines.h:819
@ SPELL_EFFECT_APPLY_AURA
Definition: SharedDefines.h:784
@ SPELL_PREVENTION_TYPE_NONE
Definition: SharedDefines.h:1553
@ SPELL_ATTR5_EXTRA_INITIAL_PERIOD
Definition: SharedDefines.h:576
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
Definition: SharedDefines.h:570
@ SPELL_ATTR5_DO_NOT_DISPLAY_DURATION
Definition: SharedDefines.h:577
@ SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL
Definition: SharedDefines.h:567
@ SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT
Definition: SharedDefines.h:593
@ TARGET_DEST_TARGET_ANY
Definition: SharedDefines.h:1467
@ TARGET_UNIT_CONE_ENTRY
Definition: SharedDefines.h:1464
@ TARGET_DEST_CASTER_FRONT
Definition: SharedDefines.h:1451
@ TARGET_DEST_DB
Definition: SharedDefines.h:1422
@ TARGET_UNIT_CASTER_AREA_PARTY
Definition: SharedDefines.h:1424
@ TARGET_UNIT_SRC_AREA_ENTRY
Definition: SharedDefines.h:1416
@ TARGET_UNIT_DEST_AREA_ENEMY
Definition: SharedDefines.h:1421
@ TARGET_UNIT_SRC_AREA_ALLY
Definition: SharedDefines.h:1434
@ TARGET_UNIT_TARGET_ALLY
Definition: SharedDefines.h:1425
@ TARGET_DEST_CASTER_BACK
Definition: SharedDefines.h:1452
@ TARGET_UNIT_VEHICLE
Definition: SharedDefines.h:1498
@ TARGET_UNIT_TARGET_ANY
Definition: SharedDefines.h:1429
@ TARGET_DEST_DEST
Definition: SharedDefines.h:1491
@ TARGET_UNIT_SRC_AREA_ENEMY
Definition: SharedDefines.h:1420
@ TARGET_DEST_TARGET_ENEMY
Definition: SharedDefines.h:1457
@ TARGET_UNIT_PET
Definition: SharedDefines.h:1414
@ TARGET_DEST_DYNOBJ_NONE
Definition: SharedDefines.h:1492
@ TARGET_UNIT_TARGET_ENEMY
Definition: SharedDefines.h:1415
@ TARGET_UNIT_MASTER
Definition: SharedDefines.h:1431
@ TARGET_DEST_TRAJ
Definition: SharedDefines.h:1493
@ TARGET_UNIT_DEST_AREA_ENTRY
Definition: SharedDefines.h:1417
@ TARGET_UNIT_NEARBY_ENTRY
Definition: SharedDefines.h:1442
@ TARGET_DEST_CASTER
Definition: SharedDefines.h:1423
@ TARGET_UNIT_CASTER
Definition: SharedDefines.h:1410
@ TARGET_UNIT_CONE_ENEMY_24
Definition: SharedDefines.h:1428
@ TARGET_SRC_CASTER
Definition: SharedDefines.h:1426
@ TARGET_UNIT_SUMMONER
Definition: SharedDefines.h:1496
@ SPELL_ATTR2_CANT_CRIT
Definition: SharedDefines.h:485
@ SPELL_ATTR2_ALLOW_DEAD_TARGET
Definition: SharedDefines.h:456
@ SPELL_ATTR2_IGNORE_LINE_OF_SIGHT
Definition: SharedDefines.h:458
@ SPELL_ATTR1_NO_THREAT
Definition: SharedDefines.h:429
@ SPELL_ATTR1_EXCLUDE_CASTER
Definition: SharedDefines.h:438
@ SPELL_ATTR1_ALLOW_WHILE_STEALTHED
Definition: SharedDefines.h:424
@ SPELL_ATTR1_IMMUNITY_PURGES_EFFECT
Definition: SharedDefines.h:434
@ SPELL_ATTR1_NO_REFLECTION
Definition: SharedDefines.h:426
@ SPELL_ATTR1_NO_REDIRECTION
Definition: SharedDefines.h:422
@ SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD
Definition: SharedDefines.h:513
@ SPELL_ATTR3_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
@ TARGET_FLAG_DEST_LOCATION
Definition: SpellInfo.h:52
void ApplySpellFix(std::initializer_list< uint32 > spellIds, void(*fix)(SpellInfo *))
Definition: SpellInfoCorrections.cpp:24
@ 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
@ 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
@ 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
#define sGraveyard
Definition: GameGraveyard.h:74
@ FORM_MOONKIN
Definition: UnitDefines.h:98
@ FORM_CAT
Definition: UnitDefines.h:70
@ FORM_TREE
Definition: UnitDefines.h:71
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 SPEED_CHARGE
Definition: MotionMaster.h:109
Definition: Util.h:451
Definition: GameGraveyard.h:27
Definition: SpellInfo.h:217
Definition: SpellInfo.h:249
uint32 RecoveryTime
Definition: SpellInfo.h:348
SpellRangeEntry const * RangeEntry
Definition: SpellInfo.h:369
uint32 ActiveIconID
Definition: SpellInfo.h:381
float Speed
Definition: SpellInfo.h:370
uint32 Attributes
Definition: SpellInfo.h:324
SpellCategoryEntry const * CategoryEntry
Definition: SpellInfo.h:321
uint32 AttributesEx6
Definition: SpellInfo.h:330
uint32 SpellIconID
Definition: SpellInfo.h:380
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > const & GetEffects() const
Definition: SpellInfo.h:527
Definition: DBCStructure.h: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: 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_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_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_ADD_PCT_MODIFIER, SPELL_AURA_DUMMY, SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST, SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT, SPELL_AURA_MOD_STUN, SPELL_AURA_MOD_TAUNT, SPELL_AURA_PERIODIC_DUMMY, SPELL_AURA_PERIODIC_HEAL, SPELL_AURA_PERIODIC_TRIGGER_SPELL, SPELL_AURA_PROC_TRIGGER_SPELL, SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE, SPELL_AURA_SCHOOL_ABSORB, SPELL_AURA_SET_VEHICLE_ID, SPELL_AURA_SPLIT_DAMAGE_PCT, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_APPLY_AREA_AURA_FRIEND, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_CHARGE, SPELL_EFFECT_CHARGE_DEST, SPELL_EFFECT_DUMMY, SPELL_EFFECT_JUMP, SPELL_EFFECT_JUMP_DEST, SPELL_EFFECT_LEAP_BACK, SPELL_EFFECT_MODIFY_THREAT_PERCENT, SPELL_EFFECT_POWER_BURN, SPELL_EFFECT_SCRIPT_EFFECT, SPELL_EFFECT_SELF_RESURRECT, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_TRIGGER_MISSILE, SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE, SPELL_INTERRUPT_FLAG_INTERRUPT, SPELL_PREVENTION_TYPE_NONE, SPELL_SCHOOL_MASK_MAGIC, SPELL_SCHOOL_MASK_SHADOW, SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_MAGE, SPELLFAMILY_PALADIN, SPELLFAMILY_POTION, SPELLFAMILY_ROGUE, SPELLFAMILY_UNK1, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, SPELLMOD_DAMAGE, SPELLMOD_EFFECT1, SPELLMOD_EFFECT2, sSpellCastTimesStore, sSpellCategoryStore, sSpellDurationStore, sSpellRadiusStore, sSpellRangeStore, sSummonPropertiesStore, SUMMON_CATEGORY_PET, SUMMON_TYPE_PET, SUMMON_TYPE_TOTEM, sVehicleSeatStore, TARGET_DEST_CASTER, TARGET_DEST_CASTER_BACK, TARGET_DEST_CASTER_FRONT, TARGET_DEST_DB, TARGET_DEST_DEST, TARGET_DEST_DYNOBJ_NONE, TARGET_DEST_TARGET_ANY, TARGET_DEST_TARGET_ENEMY, TARGET_DEST_TRAJ, TARGET_FLAG_DEST_LOCATION, TARGET_SRC_CASTER, TARGET_UNIT_CASTER, TARGET_UNIT_CASTER_AREA_PARTY, TARGET_UNIT_CONE_ENEMY_24, TARGET_UNIT_CONE_ENTRY, TARGET_UNIT_DEST_AREA_ENEMY, TARGET_UNIT_DEST_AREA_ENTRY, TARGET_UNIT_MASTER, TARGET_UNIT_NEARBY_ENTRY, TARGET_UNIT_PET, TARGET_UNIT_SRC_AREA_ALLY, TARGET_UNIT_SRC_AREA_ENEMY, TARGET_UNIT_SRC_AREA_ENTRY, TARGET_UNIT_SUMMONER, TARGET_UNIT_TARGET_ALLY, TARGET_UNIT_TARGET_ANY, TARGET_UNIT_TARGET_ENEMY, TARGET_UNIT_VEHICLE, LockEntry::Type, and SummonPropertiesEntry::Type.

◆ LoadSpellInfoCustomAttributes()

void SpellMgr::LoadSpellInfoCustomAttributes ( )
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
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;
2932 break;
2933 }
2934
2935 switch (spellInfo->Effects[j].ApplyAuraName)
2936 {
2937 case SPELL_AURA_CONVERT_RUNE: // Can't be saved - aura handler relies on calculated amount and changes it
2938 case SPELL_AURA_OPEN_STABLE: // No point in saving this, since the stable dialog can't be open on aura load anyway.
2939 // Auras that require both caster & target to be in world cannot be saved
2947 break;
2948 default:
2949 break;
2950 }
2951
2952 switch (spellInfo->Effects[j].ApplyAuraName)
2953 {
2961 break;
2964 break;
2965 default:
2966 break;
2967 }
2968
2969 switch (spellInfo->Effects[j].Effect)
2970 {
2976 case SPELL_EFFECT_HEAL:
2978 break;
2989 break;
2992 case SPELL_EFFECT_JUMP:
2995 spellInfo->AttributesCu |= SPELL_ATTR0_CU_CHARGE;
2996 break;
2999 break;
3004 {
3005 // only enchanting profession enchantments procs can stack
3007 {
3008 uint32 enchantId = spellInfo->Effects[j].MiscValue;
3009 SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId);
3010 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
3011 {
3012 if (enchant->type[s] != ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL)
3013 continue;
3014
3015 SpellInfo* procInfo = _GetSpellInfo(enchant->spellid[s]);
3016 if (!procInfo)
3017 continue;
3018
3019 // if proced directly from enchantment, not via proc aura
3020 // NOTE: Enchant Weapon - Blade Ward also has proc aura spell and is proced directly
3021 // however its not expected to stack so this check is good
3023 continue;
3024
3026 }
3027 }
3028 break;
3029 }
3030 }
3031 }
3032
3033 // Xinef: spells ignoring hit result should not be binary
3034 if (!spellInfo->HasAttribute(SPELL_ATTR3_ALWAYS_HIT))
3035 {
3036 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3037 {
3038 if (spellInfo->Effects[j].Effect)
3039 {
3040 switch (spellInfo->Effects[j].Effect)
3041 {
3049 continue;
3058 if (spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
3059 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE_PERCENT ||
3060 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_DUMMY ||
3061 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH ||
3062 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_HEALTH_FUNNEL ||
3063 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DUMMY)
3064 continue;
3065 [[fallthrough]];
3066 default:
3067 if (!(spellInfo->Effects[j].CalcValue() &&
3068 ((spellInfo->Effects[j].Effect == SPELL_EFFECT_INTERRUPT_CAST || spellInfo->HasAttribute(SPELL_ATTR0_CU_DONT_BREAK_STEALTH)) &&
3070 continue;
3071
3072 if (spellInfo->Id == 69649 || spellInfo->Id == 71056 || spellInfo->Id == 71057 || spellInfo->Id == 71058 ||
3073 spellInfo->Id == 73061 || spellInfo->Id == 73062 || spellInfo->Id == 73063 || spellInfo->Id == 73064)
3074 continue;
3075
3076 if (spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && (spellInfo->SpellFamilyFlags[0] & 0x20)) // Frostbolt
3077 continue;
3078
3079 if (spellInfo->Id == 55095) // Frost Fever
3080 continue;
3081
3082 if (spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK &&
3083 ((spellInfo->SpellFamilyFlags[1] & 0x40000) || (spellInfo->SpellFamilyFlags[0] & 0x4000))) // Haunt/Drain Soul
3084 continue;
3085
3087 break;
3088 }
3089 }
3090 }
3091 }
3092
3093 // pussywizard:
3094 if ((spellInfo->SchoolMask & SPELL_SCHOOL_MASK_NORMAL) && (spellInfo->SchoolMask & SPELL_SCHOOL_MASK_MAGIC))
3095 {
3096 spellInfo->SchoolMask &= ~SPELL_SCHOOL_MASK_NORMAL;
3098 }
3099
3100 if (!spellInfo->_IsPositiveEffect(EFFECT_0, false))
3102
3103 if (!spellInfo->_IsPositiveEffect(EFFECT_1, false))
3105
3106 if (!spellInfo->_IsPositiveEffect(EFFECT_2, false))
3108
3109 if (spellInfo->SpellVisual[0] == 3879)
3111
3112 switch (spellInfo->SpellFamilyName)
3113 {
3115 // Shout
3116 if (spellInfo->SpellFamilyFlags[0] & 0x20000 || spellInfo->SpellFamilyFlags[1] & 0x20)
3118 break;
3119 case SPELLFAMILY_DRUID:
3120 // Roar
3121 if (spellInfo->SpellFamilyFlags[0] & 0x8)
3123 break;
3124 case SPELLFAMILY_HUNTER:
3125 // Aspects
3126 if (spellInfo->GetCategory() == 47)
3127 {
3129 }
3130 // Aimed Shot
3131 if (spellInfo->SpellFamilyFlags[0] & 0x00020000)
3132 {
3134 }
3135 break;
3136 default:
3137 break;
3138 }
3139
3140 switch (spellInfo->Id)
3141 {
3142 // Xinef: additional spells which should be binary
3143 case 45145: // Snake Trap Effect
3145 break;
3146 case 1776: // Gouge
3147 case 1777:
3148 case 8629:
3149 case 11285:
3150 case 11286:
3151 case 12540:
3152 case 13579:
3153 case 24698:
3154 case 28456:
3155 case 29425:
3156 case 34940:
3157 case 36862:
3158 case 38764:
3159 case 38863:
3160 case 52743: // Head Smack
3162 break;
3163 case 53: // Backstab
3164 case 2589:
3165 case 2590:
3166 case 2591:
3167 case 7159:
3168 case 8627:
3169 case 8721:
3170 case 11279:
3171 case 11280:
3172 case 11281:
3173 case 15582:
3174 case 15657:
3175 case 22416:
3176 case 25300:
3177 case 26863:
3178 case 37685:
3179 case 48656:
3180 case 48657:
3181 case 703: // Garrote
3182 case 8631:
3183 case 8632:
3184 case 8633:
3185 case 11289:
3186 case 11290:
3187 case 26839:
3188 case 26884:
3189 case 48675:
3190 case 48676:
3191 case 5221: // Shred
3192 case 6800:
3193 case 8992:
3194 case 9829:
3195 case 9830:
3196 case 27001:
3197 case 27002:
3198 case 48571:
3199 case 48572:
3200 case 8676: // Ambush
3201 case 8724:
3202 case 8725:
3203 case 11267:
3204 case 11268:
3205 case 11269:
3206 case 27441:
3207 case 48689:
3208 case 48690:
3209 case 48691:
3210 case 6785: // Ravage
3211 case 6787:
3212 case 9866:
3213 case 9867:
3214 case 27005:
3215 case 48578:
3216 case 48579:
3217 case 21987: // Lash of Pain
3218 case 23959: // Test Stab R50
3219 case 24825: // Test Backstab
3220 case 58563: // Assassinate Restless Lookout
3221 case 63124: // quest There's Something About the Squire (13654)
3223 break;
3224 case 26029: // Dark Glare
3225 case 43140: // Flame Breath
3226 case 43215: // Flame Breath
3227 case 70461: // Coldflame Trap
3228 case 72133: // Pain and Suffering
3229 case 73788: // Pain and Suffering
3230 case 73789: // Pain and Suffering
3231 case 73790: // Pain and Suffering
3232 case 63293: // Mimiron - spinning damage
3233 case 68873: // Wailing Souls
3234 case 70324: // Wailing Souls
3235 case 64619: // Ulduar, Mimiron, Emergency Fire Bot, Water Spray
3237 break;
3238 case 58690: // Cyanigosa, Tail Sweep
3239 case 59283: // Cyanigosa, Tail Sweep
3241 break;
3242 case 24340: // Meteor
3243 case 26558: // Meteor
3244 case 28884: // Meteor
3245 case 36837: // Meteor
3246 case 38903: // Meteor
3247 case 41276: // Meteor
3248 case 57467: // Meteor
3249 case 26789: // Shard of the Fallen Star
3250 case 31436: // Malevolent Cleave
3251 case 40810: // Saber Lash
3252 case 43267: // Saber Lash
3253 case 43268: // Saber Lash
3254 case 42384: // Brutal Swipe
3255 case 45150: // Meteor Slash
3256 case 64688: // Sonic Screech
3257 case 72373: // Shared Suffering
3258 case 71904: // Chaos Bane
3259 case 70492: // Ooze Eruption
3260 case 72505: // Ooze Eruption
3261 case 72624: // Ooze Eruption
3262 case 72625: // Ooze Eruption
3263 // ONLY SPELLS WITH SPELLFAMILY_GENERIC and EFFECT_SCHOOL_DAMAGE, OR WEAPON_DMG_X
3264 case 66809: // Meteor Fists
3265 case 67331: // Meteor Fists
3266 case 66765: // Meteor Fists
3267 case 67333: // Meteor Fists
3269 break;
3270 case 18500: // Wing Buffet
3271 case 33086: // Wild Bite
3272 case 49749: // Piercing Blow
3273 case 52890: // Penetrating Strike
3274 case 53454: // Impale
3275 case 59446: // Impale
3276 case 62383: // Shatter
3277 case 64777: // Machine Gun
3278 case 65239: // Machine Gun
3279 case 69293: // Wing Buffet
3280 case 74439: // Machine Gun
3281 // Trial of the Crusader, Jaraxxus, Shivan Slash
3282 case 66378:
3283 case 67097:
3284 case 67098:
3285 case 67099:
3286 // Trial of the Crusader, Anub'arak, Impale
3287 case 65919:
3288 case 67858:
3289 case 67859:
3290 case 67860:
3291 case 63278: // Mark of the Faceless (General Vezax)
3292 case 64125: // Ulduar, Yogg-Saron, Squeeze
3293 case 64126: // Ulduar, Yogg-Saron, Squeeze
3294 case 62544: // Thrust (Argent Tournament)
3295 case 64588: // Thrust (Argent Tournament)
3296 case 66479: // Thrust (Argent Tournament)
3297 case 68505: // Thrust (Argent Tournament)
3298 case 62709: // Counterattack! (Argent Tournament)
3299 case 62626: // Break-Shield (Argent Tournament, Player)
3300 case 64590: // Break-Shield (Argent Tournament, Player)
3301 case 64342: // Break-Shield (Argent Tournament, NPC)
3302 case 64686: // Break-Shield (Argent Tournament, NPC)
3303 case 65147: // Break-Shield (Argent Tournament, NPC)
3304 case 68504: // Break-Shield (Argent Tournament, NPC)
3305 case 62874: // Charge (Argent Tournament, Player)
3306 case 68498: // Charge (Argent Tournament, Player)
3307 case 64591: // Charge (Argent Tournament, Player)
3308 case 63003: // Charge (Argent Tournament, NPC)
3309 case 63010: // Charge (Argent Tournament, NPC)
3310 case 68321: // Charge (Argent Tournament, NPC)
3311 case 72255: // Mark of the Fallen Champion (Deathbringer Saurfang)
3312 case 72444: // Mark of the Fallen Champion (Deathbringer Saurfang)
3313 case 72445: // Mark of the Fallen Champion (Deathbringer Saurfang)
3314 case 72446: // Mark of the Fallen Champion (Deathbringer Saurfang)
3315 case 72409: // Rune of Blood (Deathbringer Saurfang)
3316 case 72447: // Rune of Blood (Deathbringer Saurfang)
3317 case 72448: // Rune of Blood (Deathbringer Saurfang)
3318 case 72449: // Rune of Blood (Deathbringer Saurfang)
3319 case 49882: // Leviroth Self-Impale
3320 case 62775: // Ulduar: XT-002 Tympanic Tamparum
3322 break;
3323 case 64422: // Sonic Screech (Auriaya)
3326 break;
3327 case 72293: // Mark of the Fallen Champion (Deathbringer Saurfang)
3328 case 72347: // Lock Players and Tap Chest (Gunship Battle)
3330 break;
3331 default:
3332 break;
3333 case 63675: // Improved Devouring Plague
3334 case 17962: // Conflagrate
3335 case 32593: // Earth Shield aura
3336 case 32594: // Earth Shield aura
3337 case 49283: // Earth Shield aura
3338 case 49284: // Earth Shield aura
3339 case 50526: // Wandering Plague
3340 case 53353: // Chimera Shot - Serpent trigger
3341 case 52752: // Ancestral Awakening Heal
3343 break;
3344 case 65280: // Ulduar, Hodir, Singed
3345 case 28969: // Naxxramas, Crypt Guard, Acid Spit (10 normal)
3346 case 56098: // Naxxramas, Crypt Guard, Acid Spit (25 normal)
3347 case 27891: // Naxxramas, Sludge Belcher, Acidic Sludge (10 normal)
3348 case 54331: // Naxxramas, Sludge Belcher, Acidic Sludge (25 normal)
3349 case 29325: // Naxxramas, Stoneskin Gargoyle, Acid Volley (10 normal)
3350 case 54714: // Naxxramas, Stoneskin Gargoyle, Acid Volley (25 normal)
3351 case 65775: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (10 normal)
3352 case 67861: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (25 normal)
3353 case 67862: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (10 heroic)
3354 case 67863: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (25 heroic)
3355 case 55604: // Naxxramas, Unrelenting Trainee, Death Plague (10 normal)
3356 case 55645: // Naxxramas, Unrelenting Trainee, Death Plague (25 normal)
3357 case 67721: // Anub'arak, Nerubian Burrower, Expose Weakness (normal)
3358 case 67847: // Anub'arak, Nerubian Burrower, Expose Weakness (heroic)
3359 case 64638: // Ulduar, Winter Jormungar, Acidic Bite
3360 case 71157: // Icecrown Citadel, Plagued Zombie, Infected Wound
3361 case 72963: // Icecrown Citadel, Rot Worm, Flesh Rot (10 normal)
3362 case 72964: // Icecrown Citadel, Rot Worm, Flesh Rot (25 normal)
3363 case 72965: // Icecrown Citadel, Rot Worm, Flesh Rot (10 heroic)
3364 case 72966: // Icecrown Citadel, Rot Worm, Flesh Rot (25 heroic)
3365 case 72465: // Icecrown Citadel, Sindragosa, Respite for a Tormented Soul (weekly quest)
3366 case 45271: // Sunwell, Eredar Twins encounter, Dark Strike
3367 case 45347: // Sunwell, Eredar Twins encounter, Dark Touched
3368 case 45348: // Sunwell, Eredar Twins encounter, Flame Touched
3369 case 35859: // The Eye, Nether Vapor
3370 case 40520: // Black Temple, Shade Soul Channel
3371 case 40327: // Black Temple, Atrophy
3372 case 38449: // Serpentshrine Cavern, Blessing of the Tides
3373 case 38044: // Serpentshrine Cavern, Surge
3374 case 74507: // Ruby Sanctum, Siphoned Might
3375 case 49381: // Drak'tharon Keep, Consume
3376 case 59805: // Drak'tharon Keep, Consume
3377 case 55093: // Gundrak, Grip of Slad'ran
3378 case 30659: // Hellfire Ramparts, Fel Infusion
3379 case 54314: // Azjol'Nerub Drain Power
3380 case 59354: // Azjol'Nerub Drain Power
3381 case 34655: // Snake Trap, Deadly Poison
3382 case 11971: // Sunder Armor
3383 case 58567: // Player Sunder Armor
3384 case 12579: // Player Winter's Chill
3385 case 29306: // Naxxramas(Gluth's Zombies): Infected Wound
3386 case 61920: // Ulduar(Spellbreaker): Supercharge
3387 case 63978: // Ulduar(Rubble): Stone Nova
3388 case 15502: // Sunder Armor
3390 break;
3391 case 43138: // North Fleet Reservist Kill Credit
3393 break;
3394 case 6197: // Eagle Eye
3396 break;
3397 case 50315: // Disco Ball
3399 break;
3400 case 14183: // Premeditation
3402 break;
3403
3404 // Xinef: NOT CUSTOM, cant add in DBC CORRECTION because i need to swap effects, too much work to do there
3405 // Envenom
3406 case 32645:
3407 case 32684:
3408 case 57992:
3409 case 57993:
3410 {
3411 SpellEffectInfo info = spellInfo->Effects[EFFECT_0];
3412 spellInfo->Effects[EFFECT_0] = spellInfo->Effects[EFFECT_2];
3413 spellInfo->Effects[EFFECT_2] = info;
3414 break;
3415 }
3416
3417 // Xinef: Cooldown overwrites
3418 // Jotunheim Rapid-Fire Harpoon: Energy Reserve
3419 case 56585:
3420 spellInfo->RecoveryTime = 30000;
3421 spellInfo->_requireCooldownInfo = true;
3422 break;
3423 // Jotunheim Rapid-Fire Harpoon: Rapid-Fire Harpoon
3424 case 56570:
3425 spellInfo->RecoveryTime = 200;
3426 break;
3427 // Burst of Speed
3428 case 57493:
3429 spellInfo->RecoveryTime = 60000;
3430 spellInfo->_requireCooldownInfo = true;
3431 break;
3432 // Strafe Jotunheim Building
3433 case 7769:
3434 spellInfo->RecoveryTime = 1500;
3435 spellInfo->_requireCooldownInfo = true;
3436 break;
3437 case 44535: // Spirit Heal, abilities also have no cost
3438 spellInfo->Effects[EFFECT_0].MiscValue = 127;
3439 break;
3440 case 45537: // Cosmetic - Lightning Beam Channel
3442 break;
3443 }
3444
3445 if (spellInfo->Speed > 0.0f)
3446 {
3447 if (SpellVisualEntry const* spellVisual = sSpellVisualStore.LookupEntry(spellInfo->SpellVisual[0]))
3448 {
3449 if (spellVisual->HasMissile)
3450 {
3451 if (spellVisual->MissileModel == -4 || spellVisual->MissileModel == -5)
3452 {
3454 }
3455 }
3456 }
3457 }
3458
3459 spellInfo->_InitializeExplicitTargetMask();
3460
3461 if (sSpellMgr->HasSpellCooldownOverride(spellInfo->Id))
3462 {
3463 SpellCooldownOverride spellOverride = sSpellMgr->GetSpellCooldownOverride(spellInfo->Id);
3464
3465 if (spellInfo->RecoveryTime != spellOverride.RecoveryTime)
3466 {
3467 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3468 }
3469
3470 if (spellInfo->CategoryRecoveryTime != spellOverride.CategoryRecoveryTime)
3471 {
3472 spellInfo->CategoryRecoveryTime = spellOverride.CategoryRecoveryTime;
3473 }
3474
3475 if (spellInfo->StartRecoveryTime != spellOverride.StartRecoveryTime)
3476 {
3477 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3478 }
3479
3480 if (spellInfo->StartRecoveryCategory != spellOverride.StartRecoveryCategory)
3481 {
3482 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3483 }
3484 }
3485
3486 sScriptMgr->OnLoadSpellCustomAttr(spellInfo);
3487 }
3488
3489 // Xinef: addition for binary spells, ommit spells triggering other spells
3490 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3491 {
3492 spellInfo = mSpellInfoMap[i];
3493 if (!spellInfo)
3494 continue;
3495
3496 if (!(spellInfo->AttributesCu & SPELL_ATTR0_CU_BINARY_SPELL))
3497 continue;
3498
3499 bool allNonBinary = true;
3500 bool overrideAttr = false;
3501 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3502 {
3503 if (spellInfo->Effects[j].ApplyAuraName && spellInfo->Effects[j].TriggerSpell)
3504 {
3505 switch (spellInfo->Effects[j].ApplyAuraName)
3506 {
3510 if (SpellInfo const* triggerSpell = sSpellMgr->GetSpellInfo(spellInfo->Effects[j].TriggerSpell))
3511 {
3512 overrideAttr = true;
3513 if (triggerSpell->AttributesCu & SPELL_ATTR0_CU_BINARY_SPELL)
3514 allNonBinary = false;
3515 }
3516 }
3517 }
3518 }
3519
3520 if (overrideAttr && allNonBinary)
3521 spellInfo->AttributesCu &= ~SPELL_ATTR0_CU_BINARY_SPELL;
3522 }
3523
3524 LOG_INFO("server.loading", ">> Loaded SpellInfo Custom Attributes in {} ms", GetMSTimeDiffToNow(oldMSTime));
3525 LOG_INFO("server.loading", " ");
3526}
#define MAX_TALENT_RANK
Definition: DBCStructure.h:1917
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition: DBCStructure.h:1837
@ ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL
Definition: DBCEnums.h:367
@ 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_ATTR0_CU_IGNORE_ARMOR
Definition: SpellInfo.h:191
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition: SpellInfo.h:192
@ SPELL_ATTR0_CU_ALLOW_INFLIGHT_TARGET
Definition: SpellInfo.h:194
@ SPELL_ATTR0_CU_ENCHANT_PROC
Definition: SpellInfo.h:176
@ SPELL_ATTR0_CU_NO_POSITIVE_TAKEN_BONUS
Definition: SpellInfo.h:197
@ SPELL_ATTR0_CU_FORCE_SEND_CATEGORY_COOLDOWNS
Definition: SpellInfo.h:204
@ SPELL_ATTR0_CU_DIRECT_DAMAGE
Definition: SpellInfo.h:184
@ SPELL_ATTR0_CU_POSITIVE
Definition: SpellInfo.h:211
@ SPELL_ATTR0_CU_FORCE_AURA_SAVING
Definition: SpellInfo.h:205
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition: SpellInfo.h:183
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition: SpellInfo.h:182
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition: SpellInfo.h:193
@ SPELL_ATTR0_CU_CONE_BACK
Definition: SpellInfo.h:177
@ SPELL_ATTR0_CU_SINGLE_AURA_STACK
Definition: SpellInfo.h:198
@ SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED
Definition: SpellInfo.h:200
@ SPELL_ATTR0_CU_NEGATIVE_EFF2
Definition: SpellInfo.h:190
@ SPELL_ATTR0_CU_AURA_CC
Definition: SpellInfo.h:181
@ SPELL_ATTR0_CU_NEGATIVE_EFF1
Definition: SpellInfo.h:189
@ SPELL_ATTR0_CU_CHARGE
Definition: SpellInfo.h:185
@ SPELL_ATTR0_CU_NEGATIVE
Definition: SpellInfo.h:210
@ SPELL_ATTR0_CU_NEEDS_AMMO_DATA
Definition: SpellInfo.h:195
@ SPELL_ATTR0_CU_POSITIVE_EFF0
Definition: SpellInfo.h:201
@ SPELL_ATTR0_CU_NEGATIVE_EFF0
Definition: SpellInfo.h:188
@ SPELL_ATTR0_CU_BINARY_SPELL
Definition: SpellInfo.h:196
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition: SpellInfo.h:179
@ SPELL_ATTR0_CU_SCHOOLMASK_NORMAL_WITH_MAGIC
Definition: SpellInfo.h:199
@ SPELL_ATTR0_CU_IGNORE_EVADE
Definition: SpellInfo.h:187
@ SPELL_ATTR0_CU_PICKPOCKET
Definition: SpellInfo.h:186
@ SPELL_ATTR0_CU_CONE_LINE
Definition: SpellInfo.h:178
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition: SpellInfo.h:180
@ SPELL_AURA_PERIODIC_DAMAGE
Definition: SpellAuraDefines.h:66
@ SPELL_AURA_OBS_MOD_HEALTH
Definition: SpellAuraDefines.h:83
@ SPELL_AURA_PERIODIC_HEALTH_FUNNEL
Definition: SpellAuraDefines.h:125
@ SPELL_AURA_PERIODIC_MANA_LEECH
Definition: SpellAuraDefines.h:127
@ SPELL_AURA_MOD_POSSESS_PET
Definition: SpellAuraDefines.h:191
@ SPELL_AURA_CONVERT_RUNE
Definition: SpellAuraDefines.h:312
@ SPELL_AURA_MOD_FEAR
Definition: SpellAuraDefines.h:70
@ SPELL_AURA_OBS_MOD_POWER
Definition: SpellAuraDefines.h:84
@ SPELL_AURA_CONTROL_VEHICLE
Definition: SpellAuraDefines.h:299
@ SPELL_AURA_MOD_INVISIBILITY
Definition: SpellAuraDefines.h:81
@ SPELL_AURA_PERIODIC_DAMAGE_PERCENT
Definition: SpellAuraDefines.h:152
@ SPELL_AURA_MOD_RANGED_HASTE
Definition: SpellAuraDefines.h:203
@ SPELL_AURA_AOE_CHARM
Definition: SpellAuraDefines.h:240
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE
Definition: SpellAuraDefines.h:290
@ SPELL_AURA_PERIODIC_ENERGIZE
Definition: SpellAuraDefines.h:87
@ SPELL_AURA_MOD_INVISIBILITY_DETECT
Definition: SpellAuraDefines.h:82
@ SPELL_AURA_WATER_BREATHING
Definition: SpellAuraDefines.h:145
@ SPELL_AURA_PERIODIC_LEECH
Definition: SpellAuraDefines.h:116
@ SPELL_AURA_POWER_BURN
Definition: SpellAuraDefines.h:225
@ SPELL_AURA_OPEN_STABLE
Definition: SpellAuraDefines.h:355
@ SPELL_AURA_MOD_CONFUSE
Definition: SpellAuraDefines.h:68
@ SPELL_AURA_TRACK_CREATURES
Definition: SpellAuraDefines.h:107
@ SPELL_AURA_MOD_POSSESS
Definition: SpellAuraDefines.h:65
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT
Definition: SpellAuraDefines.h:111
@ SPELL_AURA_BIND_SIGHT
Definition: SpellAuraDefines.h:64
bool IsPartOfSkillLine(uint32 skillId, uint32 spellId)
Definition: SpellMgr.cpp:48
DBCStorage< SpellVisualEntry > sSpellVisualStore(SpellVisualfmt)
DBCStorage< TalentEntry > sTalentStore(TalentEntryfmt)
#define sScriptMgr
Definition: ScriptMgr.h:709
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:2620
uint32 StartRecoveryTime
Definition: SpellInfo.h:351
void _InitializeExplicitTargetMask()
Definition: SpellInfo.cpp:2592
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_OBS_MOD_HEALTH, SPELL_AURA_OBS_MOD_POWER, SPELL_AURA_OPEN_STABLE, SPELL_AURA_PERIODIC_DAMAGE, SPELL_AURA_PERIODIC_DAMAGE_PERCENT, SPELL_AURA_PERIODIC_DUMMY, SPELL_AURA_PERIODIC_ENERGIZE, SPELL_AURA_PERIODIC_HEAL, SPELL_AURA_PERIODIC_HEALTH_FUNNEL, SPELL_AURA_PERIODIC_LEECH, SPELL_AURA_PERIODIC_MANA_LEECH, SPELL_AURA_PERIODIC_TRIGGER_SPELL, SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT, SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE, SPELL_AURA_POWER_BURN, SPELL_AURA_PROC_TRIGGER_SPELL, SPELL_AURA_TRACK_CREATURES, SPELL_AURA_WATER_BREATHING, SPELL_EFFECT_APPLY_AREA_AURA_ENEMY, SPELL_EFFECT_APPLY_AREA_AURA_FRIEND, SPELL_EFFECT_APPLY_AREA_AURA_OWNER, SPELL_EFFECT_APPLY_AREA_AURA_PARTY, SPELL_EFFECT_APPLY_AREA_AURA_PET, SPELL_EFFECT_APPLY_AREA_AURA_RAID, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_CHARGE, SPELL_EFFECT_CHARGE_DEST, SPELL_EFFECT_CREATE_ITEM, SPELL_EFFECT_ENCHANT_HELD_ITEM, SPELL_EFFECT_ENCHANT_ITEM, SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY, SPELL_EFFECT_ENERGIZE, SPELL_EFFECT_ENERGIZE_PCT, SPELL_EFFECT_HEAL, SPELL_EFFECT_HEAL_MAX_HEALTH, SPELL_EFFECT_HEAL_MECHANICAL, SPELL_EFFECT_HEAL_PCT, SPELL_EFFECT_HEALTH_LEECH, SPELL_EFFECT_INTERRUPT_CAST, SPELL_EFFECT_JUMP, SPELL_EFFECT_JUMP_DEST, SPELL_EFFECT_LEAP_BACK, SPELL_EFFECT_LEARN_SPELL, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_PERSISTENT_AREA_AURA, SPELL_EFFECT_PICKPOCKET, SPELL_EFFECT_POWER_BURN, SPELL_EFFECT_POWER_DRAIN, SPELL_EFFECT_SCHOOL_DAMAGE, SPELL_EFFECT_TRIGGER_SPELL, SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, SPELL_SCHOOL_MASK_NORMAL, SPELLFAMILY_DRUID, SPELLFAMILY_HUNTER, SPELLFAMILY_MAGE, SPELLFAMILY_WARLOCK, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellItemEnchantmentEntry::spellid, SpellInfo::SpellVisual, sScriptMgr, sSpellItemEnchantmentStore, sSpellMgr, sSpellVisualStore, sTalentStore, SpellInfo::StartRecoveryCategory, SpellCooldownOverride::StartRecoveryCategory, SpellInfo::StartRecoveryTime, SpellCooldownOverride::StartRecoveryTime, SpellItemEnchantmentEntry::type, and WorldDatabase.

◆ LoadSpellInfoStore()

void SpellMgr::LoadSpellInfoStore ( )
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}
@ TOTAL_SPELL_EFFECTS
Definition: SharedDefines.h:943
@ TOTAL_SPELL_TARGETS
Definition: SharedDefines.h:1514
@ TOTAL_AURAS
Definition: SpellAuraDefines.h:380
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
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}
SpellInfo const * last
Definition: SpellMgr.h:558
SpellInfo const * next
Definition: SpellMgr.h:556
uint8 rank
Definition: SpellMgr.h:559
SpellInfo const * first
Definition: SpellMgr.h:557
SpellInfo const * prev
Definition: SpellMgr.h:555
void UnloadSpellInfoChains()
Definition: SpellMgr.cpp:1223

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}
SpellEffIndex
Definition: SharedDefines.h:30
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
Definition: SpellMgr.h:396
float target_Z
Definition: SpellMgr.h:400
uint32 target_mapId
Definition: SpellMgr.h:397
float target_Y
Definition: SpellMgr.h:399
float target_Orientation
Definition: SpellMgr.h:401
float target_X
Definition: SpellMgr.h:398
Definition: DBCStructure.h:1324

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