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

#include "SpellMgr.h"

Public Member Functions

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

Static Public Member Functions

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

Private Member Functions

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

Private Attributes

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

Detailed Description

Constructor & Destructor Documentation

◆ SpellMgr()

SpellMgr::SpellMgr ( )
private
355{
356}

◆ ~SpellMgr()

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

References UnloadSpellInfoStore().

Member Function Documentation

◆ _GetSpellInfo()

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

References GetSpellInfoStoreSize(), and mSpellInfoMap.

Referenced by LoadSpellInfoCustomAttributes().

◆ AssertSpellInfo()

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

References ASSERT, GetSpellInfoStoreSize(), and mSpellInfoMap.

◆ CanSpellTriggerProcOnEvent()

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

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

◆ CheckSpellGroupStackRules()

SpellGroupStackFlags SpellMgr::CheckSpellGroupStackRules ( SpellInfo const *  spellInfo1,
SpellInfo const *  spellInfo2,
bool  remove,
bool  areaAura 
) const
681{
682 uint32 spellid_1 = spellInfo1->GetFirstRankSpell()->Id;
683 uint32 spellid_2 = spellInfo2->GetFirstRankSpell()->Id;
684
685 uint32 groupId = GetSpellGroup(spellid_1);
686
688
689 // xinef: dunno why i added this
690 if (spellid_1 == spellid_2 && remove && !areaAura)
691 {
693 {
695 }
696
698 }
699
700 if (groupId > 0 && groupId == GetSpellGroup(spellid_2))
701 {
704 // xinef: first flags are used for elixir stacking rules
706 {
707 if (flag1 & flag2)
709 }
710 // xinef: check only flag1 (new spell)
715
716 return SpellGroupStackFlags(GetGroupStackFlags(groupId) | additionFlag);
717 }
718
720}
SpellGroupStackFlags
Definition SpellMgr.h:356
@ SPELL_GROUP_STACK_FLAG_EXCLUSIVE
Definition SpellMgr.h:358
@ SPELL_GROUP_STACK_FLAG_FORCED_WEAKEST
Definition SpellMgr.h:367
@ SPELL_GROUP_STACK_FLAG_FORCED_STRONGEST
Definition SpellMgr.h:366
@ SPELL_GROUP_STACK_FLAG_NONE
Definition SpellMgr.h:357
@ SPELL_GROUP_STACK_FLAG_NEVER_STACK
Definition SpellMgr.h:361
SpellGroupSpecialFlags
Definition SpellMgr.h:334
@ SPELL_GROUP_SPECIAL_FLAG_FORCED_STRONGEST
Definition SpellMgr.h:341
@ SPELL_GROUP_SPECIAL_FLAG_SAME_SPELL_CHECK
Definition SpellMgr.h:348
@ SPELL_GROUP_SPECIAL_FLAG_STACK_EXCLUSIVE_MAX
Definition SpellMgr.h:340
uint32 GetSpellGroup(uint32 spellid) const
Definition SpellMgr.cpp:660
SpellGroupStackFlags GetGroupStackFlags(uint32 groupid) const
Definition SpellMgr.cpp:651
SpellGroupSpecialFlags GetSpellGroupSpecialFlags(uint32 spell_id) const
Definition SpellMgr.cpp:670

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

◆ CheckSpellInfo()

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

References GetSpellInfoStoreSize(), LOG_ERROR, and mSpellInfoMap.

◆ CheckSpellValid()

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

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

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

◆ ComputeIsSpellValid()

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

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

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

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

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

◆ GetFirstSpellInChain()

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

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

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

◆ GetGroupStackFlags()

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

References mSpellGroupStackMap, and SPELL_GROUP_STACK_FLAG_NONE.

Referenced by CheckSpellGroupStackRules().

◆ GetLastSpellInChain()

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

References GetSpellChainNode().

◆ GetNextSpellInChain()

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

References GetSpellChainNode().

◆ GetPetAura()

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

References mSpellPetAuraMap.

◆ GetPetDefaultSpellsEntry()

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

References mPetDefaultSpellsMap.

◆ GetPetLevelupSpellList()

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

References mPetLevelupSpellMap.

◆ GetPrevSpellInChain()

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

References GetSpellChainNode().

◆ GetSetOfSpellsInSpellGroupWithFlag()

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

References mSpellGroupMap.

◆ GetSkillLineAbilityMapBounds()

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

References mSkillLineAbilityMap.

◆ GetSpellAreaForAreaMapBounds()

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

References mSpellAreaForAreaMap.

◆ GetSpellAreaForAuraMapBounds()

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

References mSpellAreaForAuraMap.

Referenced by LoadSpellAreas().

◆ GetSpellAreaForQuestEndMapBounds()

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

References mSpellAreaForQuestEndMap.

◆ GetSpellAreaForQuestMapBounds()

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

References mSpellAreaForQuestMap.

◆ GetSpellAreaMapBounds()

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

References mSpellAreaMap.

Referenced by LoadSpellAreas().

◆ GetSpellBonusData()

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

References GetFirstSpellInChain(), and mSpellBonusMap.

◆ GetSpellChainNode()

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

References mSpellChains.

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

◆ GetSpellCooldownOverride()

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

References mSpellCooldownOverrideMap.

◆ GetSpellDifficultyId()

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

References mSpellDifficultySearcherMap.

Referenced by GetSpellIdForDifficulty().

◆ GetSpellEnchantProcEvent()

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

References mSpellEnchantProcEventMap.

◆ GetSpellForDifficultyFromSpell()

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

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

◆ GetSpellGroup()

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

References GetFirstSpellInChain(), and mSpellGroupMap.

Referenced by CheckSpellGroupStackRules().

◆ GetSpellGroupSpecialFlags()

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

References GetFirstSpellInChain(), mSpellGroupMap, and SPELL_GROUP_SPECIAL_FLAG_NONE.

Referenced by CheckSpellGroupStackRules().

◆ GetSpellIdForDifficulty()

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

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

Referenced by GetSpellForDifficultyFromSpell().

◆ GetSpellInfo()

◆ GetSpellInfoStoreSize()

◆ GetSpellLearnSkill()

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

References mSpellLearnSkills.

◆ GetSpellLinked()

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

References mSpellLinkedMap.

◆ GetSpellMixologyBonus()

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

References mSpellMixologyMap.

◆ GetSpellProcEntry()

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

References mSpellProcMap.

◆ GetSpellProcEvent()

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

References mSpellProcEventMap.

◆ GetSpellRank()

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

References GetSpellChainNode().

◆ GetSpellsRequiredForSpellBounds()

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

References mSpellReq.

◆ GetSpellsRequiringSpellBounds()

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

References mSpellsReqSpell.

Referenced by IsSpellRequiringSpell().

◆ GetSpellTargetPosition()

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

References mSpellTargetPositions.

◆ GetSpellThreatEntry()

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

References GetFirstSpellInChain(), and mSpellThreatMap.

◆ GetSpellWithRank()

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

References GetSpellChainNode(), and GetSpellWithRank().

Referenced by GetSpellWithRank().

◆ HasSpellCooldownOverride()

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

References mSpellCooldownOverrideMap.

◆ instance()

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

References instance().

Referenced by instance().

◆ IsAdditionalTalentSpell()

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

References mTalentSpellAdditionalSet.

◆ IsArenaAllowedEnchancment()

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

References mEnchantCustomAttr.

◆ IsSpellProcEventCanTriggeredBy()

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

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

Aura must have positive procflags for a HOT to proc

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

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

Aura must have positive procflags for a HOT to proc

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

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

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

◆ IsSpellRequiringSpell()

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

References GetSpellsRequiringSpellBounds().

Referenced by LoadSpellRequired().

◆ IsSpellValid()

◆ LoadEnchantCustomAttr()

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

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

◆ LoadPetDefaultSpells()

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

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

◆ LoadPetLevelupSpellMap()

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

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

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

◆ LoadSpellAreas()

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

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

◆ LoadSpellBonuses()

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

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

◆ LoadSpellCooldownOverrides()

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

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

◆ LoadSpellEnchantProcData()

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

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

◆ LoadSpellGroups()

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

References SpellInfo::ActiveIconID, ApplySpellFix(), AREA_FLAG_NO_FLY_ZONE, AREA_FLAG_REST_ZONE_ALLIANCE, SpellInfo::Attributes, SpellInfo::AttributesEx6, AURA_INTERRUPT_FLAG_CAST, AURA_INTERRUPT_FLAG_CHANGE_MAP, AURA_INTERRUPT_FLAG_HITBYSPELL, AURA_INTERRUPT_FLAG_MELEE_ATTACK, AURA_INTERRUPT_FLAG_MOUNT, AURA_INTERRUPT_FLAG_MOVE, AURA_INTERRUPT_FLAG_TAKE_DAMAGE, AURA_INTERRUPT_FLAG_TALK, AURA_INTERRUPT_FLAG_TELEPORTED, AURA_INTERRUPT_FLAG_TURNING, AURA_INTERRUPT_FLAG_UNK14, SummonPropertiesEntry::Category, SpellInfo::CategoryEntry, DISPEL_MAGIC, DISPEL_NONE, DONE_HIT_PROC_FLAG_MASK, EFFECT_0, EFFECT_1, EFFECT_2, EFFECT_RADIUS_100_YARDS, EFFECT_RADIUS_10_YARDS, EFFECT_RADIUS_12_YARDS, EFFECT_RADIUS_150_YARDS, EFFECT_RADIUS_18_YARDS, EFFECT_RADIUS_1_YARD, EFFECT_RADIUS_200_YARDS, EFFECT_RADIUS_20_YARDS, EFFECT_RADIUS_25_YARDS, EFFECT_RADIUS_2_YARDS, EFFECT_RADIUS_3_YARDS, EFFECT_RADIUS_45_YARDS, EFFECT_RADIUS_4_YARDS, EFFECT_RADIUS_50000_YARDS, EFFECT_RADIUS_500_YARDS, EFFECT_RADIUS_5_YARDS, EFFECT_RADIUS_6_YARDS, EFFECT_RADIUS_70_YARDS, EFFECT_RADIUS_7_YARDS, EFFECT_RADIUS_8_YARDS, SpellInfo::Effects, FORM_CAT, FORM_MOONKIN, FORM_TREE, FactionTemplateEntry::friendlyMask, SpellInfo::GetEffects(), getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), GetSpellInfoStoreSize(), FactionTemplateEntry::hostileMask, IN_MILLISECONDS, LOCK_KEY_NONE, LOG_INFO, VehicleSeatEntry::m_attachmentOffsetX, VehicleSeatEntry::m_attachmentOffsetY, VehicleSeatEntry::m_attachmentOffsetZ, VehicleSeatEntry::m_flags, AchievementEntry::mapID, MAX_SPELL_EFFECTS, MECHANIC_NONE, MECHANIC_SNARE, MECHANIC_STUN, mSpellInfoMap, POWER_MANA, PROC_FLAG_DONE_MELEE_AUTO_ATTACK, PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS, SpellInfo::RangeEntry, SpellRangeEntry::RangeMax, SpellInfo::RecoveryTime, FactionEntry::ReputationFlags, sAchievementStore, sAreaTableStore, CreatureDisplayInfoEntry::scale, sCreatureDisplayInfoStore, sFactionStore, sFactionTemplateStore, sGraveyard, sLockStore, SpellInfo::Speed, SPEED_CHARGE, SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD, SPELL_ATTR0_ALLOW_ITEM_SPELL_IN_PVP, SPELL_ATTR0_ALLOW_WHILE_MOUNTED, SPELL_ATTR0_ALLOW_WHILE_SITTING, SPELL_ATTR0_AURA_IS_DEBUFF, SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_SINGLE_AURA_STACK, SPELL_ATTR0_DO_NOT_SHEATH, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_NO_ACTIVE_DEFENSE, SPELL_ATTR0_NO_AURA_CANCEL, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR0_NOT_SHAPESHIFTED, SPELL_ATTR0_PASSIVE, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_ATTR1_ALLOW_WHILE_STEALTHED, SPELL_ATTR1_EXCLUDE_CASTER, SPELL_ATTR1_IMMUNITY_PURGES_EFFECT, SPELL_ATTR1_NO_REDIRECTION, SPELL_ATTR1_NO_REFLECTION, SPELL_ATTR1_NO_THREAT, SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL, SPELL_ATTR2_ALLOW_DEAD_TARGET, SPELL_ATTR2_CANT_CRIT, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_ATTR2_NO_TARGET_PER_SECOND_COST, SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD, SPELL_ATTR3_ALWAYS_HIT, SPELL_ATTR3_CAN_PROC_FROM_PROCS, SPELL_ATTR3_COMPLETELY_BLOCKED, SPELL_ATTR3_DOT_STACKING_RULE, SPELL_ATTR3_IGNORE_CASTER_AND_TARGET_RESTRICTIONS, SPELL_ATTR3_IGNORE_CASTER_MODIFIERS, SPELL_ATTR3_ONLY_ON_PLAYER, SPELL_ATTR3_SUPPRESS_CASTER_PROCS, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING, SPELL_ATTR4_ALLOW_ENETRING_ARENA, SPELL_ATTR4_AURA_EXPIRES_OFFLINE, SPELL_ATTR4_CANNOT_BE_STOLEN, SPELL_ATTR4_IGNORE_DAMAGE_TAKEN_MODIFIERS, SPELL_ATTR4_NO_CAST_LOG, SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND, SPELL_ATTR4_REACTIVE_DAMAGE_PROC, SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL, SPELL_ATTR5_ALLOW_WHILE_STUNNED, SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT, SPELL_ATTR5_DO_NOT_DISPLAY_DURATION, SPELL_ATTR5_EXTRA_INITIAL_PERIOD, SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE, SPELL_ATTR6_CAN_TARGET_UNTARGETABLE, SPELL_ATTR6_IGNORE_CASTER_DAMAGE_MODIFIERS, SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_ATTR6_NO_CATEGORY_COOLDOWN_MODS, SPELL_ATTR6_NO_PUSHBACK, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_ATTR7_DISABLE_AURA_WHILE_DEAD, SPELL_ATTR7_DONT_CAUSE_SPELL_PUSHBACK, SPELL_ATTR7_NO_ATTACK_DODGE, SPELL_ATTR7_NO_ATTACK_PARRY, SPELL_ATTR7_TREAT_AS_NPC_AOE, SPELL_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_ADD_PCT_MODIFIER, SPELL_AURA_DUMMY, SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST, SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT, SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED, 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_OBJECT_SLOT1, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_TRIGGER_MISSILE, SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE, SPELL_FACING_FLAG_INFRONT, SPELL_INTERRUPT_FLAG_INTERRUPT, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_INTERRUPT_FLAG_PUSH_BACK, SPELL_INTERRUPT_FLAG_UNK3, SPELL_PREVENTION_TYPE_NONE, SPELL_SCHOOL_MASK_MAGIC, SPELL_SCHOOL_MASK_NATURE, SPELL_SCHOOL_MASK_SHADOW, SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_MAGE, SPELLFAMILY_PALADIN, SPELLFAMILY_POTION, SPELLFAMILY_ROGUE, SPELLFAMILY_UNK1, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, SPELLMOD_DAMAGE, SPELLMOD_EFFECT1, SPELLMOD_EFFECT2, sSpellCastTimesStore, sSpellCategoryStore, sSpellDurationStore, sSpellRadiusStore, sSpellRangeStore, sSummonPropertiesStore, SUMMON_CATEGORY_PET, SUMMON_TYPE_PET, SUMMON_TYPE_TOTEM, sVehicleSeatStore, TARGET_DEST_CASTER, TARGET_DEST_CASTER_BACK, TARGET_DEST_CASTER_FRONT, TARGET_DEST_DB, TARGET_DEST_DEST, TARGET_DEST_DYNOBJ_NONE, TARGET_DEST_TARGET_ANY, TARGET_DEST_TARGET_ENEMY, TARGET_DEST_TRAJ, TARGET_FLAG_DEST_LOCATION, TARGET_SRC_CASTER, TARGET_UNIT_CASTER, TARGET_UNIT_CASTER_AREA_PARTY, TARGET_UNIT_CONE_ENEMY_24, TARGET_UNIT_CONE_ENTRY, TARGET_UNIT_DEST_AREA_ENEMY, TARGET_UNIT_DEST_AREA_ENTRY, TARGET_UNIT_MASTER, TARGET_UNIT_NEARBY_ENTRY, TARGET_UNIT_PET, TARGET_UNIT_SRC_AREA_ALLY, TARGET_UNIT_SRC_AREA_ENEMY, TARGET_UNIT_SRC_AREA_ENTRY, TARGET_UNIT_SUMMONER, TARGET_UNIT_TARGET_ALLY, TARGET_UNIT_TARGET_ANY, TARGET_UNIT_TARGET_ENEMY, TARGET_UNIT_VEHICLE, LockEntry::Type, and SummonPropertiesEntry::Type.

◆ LoadSpellInfoCustomAttributes()

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

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

◆ LoadSpellInfoStore()

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

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:2502
bool IsRanked() const
Definition SpellInfo.cpp:2490
uint32 ProcFlags
Definition SpellInfo.h:355
SpellInfo const * GetNextRankSpell() const
Definition SpellInfo.cpp:2514
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:2143
AuraStateType LoadAuraState() const
Definition SpellInfo.cpp:2065
AuraStateType _auraState
Definition SpellInfo.h:398
SpellSpecificType _spellSpecific
Definition SpellInfo.h:399

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

◆ LoadSpellTalentRanks()

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

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

Referenced by LoadSpellRanks().

◆ LoadSpellTargetPositions()

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

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

◆ LoadSpellThreats()

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

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

◆ SetSpellDifficultyId()

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

References mSpellDifficultySearcherMap.

◆ UnloadSpellInfoChains()

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

References mSpellChains, and mSpellInfoMap.

Referenced by LoadSpellTalentRanks().

◆ UnloadSpellInfoImplicitTargetConditionLists()

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

References GetSpellInfoStoreSize(), and mSpellInfoMap.

◆ UnloadSpellInfoStore()

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

References GetSpellInfoStoreSize(), and mSpellInfoMap.

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

Member Data Documentation

◆ mEnchantCustomAttr

EnchantCustomAttribute SpellMgr::mEnchantCustomAttr
private

◆ mPetDefaultSpellsMap

PetDefaultSpellsMap SpellMgr::mPetDefaultSpellsMap
private

◆ mPetLevelupSpellMap

PetLevelupSpellMap SpellMgr::mPetLevelupSpellMap
private

◆ mSkillLineAbilityMap

SkillLineAbilityMap SpellMgr::mSkillLineAbilityMap
private

◆ mSpellAreaForAreaMap

SpellAreaForAreaMap SpellMgr::mSpellAreaForAreaMap
private

◆ mSpellAreaForAuraMap

SpellAreaForAuraMap SpellMgr::mSpellAreaForAuraMap
private

◆ mSpellAreaForQuestEndMap

SpellAreaForQuestMap SpellMgr::mSpellAreaForQuestEndMap
private

◆ mSpellAreaForQuestMap

SpellAreaForQuestMap SpellMgr::mSpellAreaForQuestMap
private

◆ mSpellAreaMap

SpellAreaMap SpellMgr::mSpellAreaMap
private

◆ mSpellBonusMap

SpellBonusMap SpellMgr::mSpellBonusMap
private

◆ mSpellChains

◆ mSpellCooldownOverrideMap

SpellCooldownOverrideMap SpellMgr::mSpellCooldownOverrideMap
private

◆ mSpellDifficultySearcherMap

SpellDifficultySearcherMap SpellMgr::mSpellDifficultySearcherMap
private

◆ mSpellEnchantProcEventMap

SpellEnchantProcEventMap SpellMgr::mSpellEnchantProcEventMap
private

◆ mSpellGroupMap

◆ mSpellGroupStackMap

SpellGroupStackMap SpellMgr::mSpellGroupStackMap
private

◆ mSpellInfoMap

◆ mSpellLearnSkills

SpellLearnSkillMap SpellMgr::mSpellLearnSkills
private

◆ mSpellLinkedMap

SpellLinkedMap SpellMgr::mSpellLinkedMap
private

Referenced by GetSpellLinked(), and LoadSpellLinked().

◆ mSpellMixologyMap

SpellMixologyMap SpellMgr::mSpellMixologyMap
private

◆ mSpellPetAuraMap

SpellPetAuraMap SpellMgr::mSpellPetAuraMap
private

Referenced by GetPetAura(), and LoadSpellPetAuras().

◆ mSpellProcEventMap

SpellProcEventMap SpellMgr::mSpellProcEventMap
private

◆ mSpellProcMap

SpellProcMap SpellMgr::mSpellProcMap
private

◆ mSpellReq

SpellRequiredMap SpellMgr::mSpellReq
private

◆ mSpellsReqSpell

SpellsRequiringSpellMap SpellMgr::mSpellsReqSpell
private

◆ mSpellTargetPositions

SpellTargetPositionMap SpellMgr::mSpellTargetPositions
private

◆ mSpellThreatMap

SpellThreatMap SpellMgr::mSpellThreatMap
private

◆ mTalentSpellAdditionalSet

TalentAdditionalSet SpellMgr::mTalentSpellAdditionalSet
private

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