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
356{
357}

◆ ~SpellMgr()

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

References UnloadSpellInfoStore().

Member Function Documentation

◆ _GetSpellInfo()

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

References GetSpellInfoStoreSize(), and mSpellInfoMap.

Referenced by LoadSpellInfoCustomAttributes().

◆ AssertSpellInfo()

SpellInfo const * SpellMgr::AssertSpellInfo ( uint32  spellId) const
inline
722 {
723 ASSERT(spellId < GetSpellInfoStoreSize());
724 SpellInfo const* spellInfo = mSpellInfoMap[spellId];
725 ASSERT(spellInfo);
726 return spellInfo;
727 }
#define ASSERT
Definition: Errors.h:68
Definition: SpellInfo.h:314

References ASSERT, GetSpellInfoStoreSize(), and mSpellInfoMap.

◆ CanSpellTriggerProcOnEvent()

bool SpellMgr::CanSpellTriggerProcOnEvent ( SpellProcEntry const &  procEntry,
ProcEventInfo eventInfo 
) const
899{
900 // proc type doesn't match
901 if (!(eventInfo.GetTypeMask() & procEntry.ProcFlags))
902 return false;
903
904 // check XP or honor target requirement
905 if (procEntry.AttributesMask & PROC_ATTR_REQ_EXP_OR_HONOR)
906 if (Player* actor = eventInfo.GetActor()->ToPlayer())
907 if (eventInfo.GetActionTarget() && !actor->isHonorOrXPTarget(eventInfo.GetActionTarget()))
908 return false;
909
910 // always trigger for these types
912 return true;
913
914 // check school mask (if set) for other trigger types
915 if (procEntry.SchoolMask && !(eventInfo.GetSchoolMask() & procEntry.SchoolMask))
916 return false;
917
918 // check spell family name/flags (if set) for spells
920 {
921 if (procEntry.SpellFamilyName && (procEntry.SpellFamilyName != eventInfo.GetSpellInfo()->SpellFamilyName))
922 return false;
923
924 if (procEntry.SpellFamilyMask && !(procEntry.SpellFamilyMask & eventInfo.GetSpellInfo()->SpellFamilyFlags))
925 return false;
926 }
927
928 // check spell type mask (if set)
930 {
931 if (procEntry.SpellTypeMask && !(eventInfo.GetSpellTypeMask() & procEntry.SpellTypeMask))
932 return false;
933 }
934
935 // check spell phase mask
937 {
938 if (!(eventInfo.GetSpellPhaseMask() & procEntry.SpellPhaseMask))
939 return false;
940 }
941
942 // check hit mask (on taken hit or on done hit, but not on spell cast phase)
943 if ((eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK) || ((eventInfo.GetTypeMask() & DONE_HIT_PROC_FLAG_MASK) && !(eventInfo.GetSpellPhaseMask() & PROC_SPELL_PHASE_CAST)))
944 {
945 uint32 hitMask = procEntry.HitMask;
946 // get default values if hit mask not set
947 if (!hitMask)
948 {
949 // for taken procs allow normal + critical hits by default
950 if (eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK)
952 // for done procs allow normal + critical + absorbs by default
953 else
955 }
956 if (!(eventInfo.GetHitMask() & hitMask))
957 return false;
958 }
959
960 return true;
961}
std::uint32_t uint32
Definition: Define.h:108
@ 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:195
Definition: Player.h:1046
uint32 GetHitMask() const
Definition: Unit.h:864
SpellSchoolMask GetSchoolMask() const
Definition: Unit.h:866
Unit * GetActionTarget() const
Definition: Unit.h:859
uint32 GetSpellTypeMask() const
Definition: Unit.h:862
uint32 GetTypeMask() const
Definition: Unit.h:861
SpellInfo const * GetSpellInfo() const
Definition: Unit.cpp:187
Unit * GetActor()
Definition: Unit.h:858
uint32 GetSpellPhaseMask() const
Definition: Unit.h:863
flag96 SpellFamilyFlags
Definition: SpellInfo.h:386
uint32 SpellFamilyName
Definition: SpellInfo.h:385

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

◆ CheckSpellGroupStackRules()

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

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

◆ CheckSpellInfo()

SpellInfo const * SpellMgr::CheckSpellInfo ( uint32  spellId) const
inline
730 {
731 if (spellId >= GetSpellInfoStoreSize())
732 {
733 LOG_ERROR("server", "spellId {} is not lower than GetSpellInfoStoreSize() ({})", spellId, GetSpellInfoStoreSize());
734 return nullptr;
735 }
736 SpellInfo const* spellInfo = mSpellInfoMap[spellId];
737 if (!spellInfo)
738 {
739 LOG_ERROR("server", "spellId {} has invalid spellInfo", spellId);
740 return nullptr;
741 }
742 return spellInfo;
743 }
#define LOG_ERROR(filterType__,...)
Definition: Log.h:159

References GetSpellInfoStoreSize(), LOG_ERROR, and mSpellInfoMap.

◆ CheckSpellValid()

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

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

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

◆ ComputeIsSpellValid()

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

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

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

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

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

◆ GetFirstSpellInChain()

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

References GetSpellChainNode().

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

◆ GetGroupStackFlags()

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

References mSpellGroupStackMap, and SPELL_GROUP_STACK_FLAG_NONE.

Referenced by CheckSpellGroupStackRules().

◆ GetLastSpellInChain()

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

References GetSpellChainNode().

◆ GetNextSpellInChain()

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

References GetSpellChainNode().

◆ GetPetAura()

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

References mSpellPetAuraMap.

◆ GetPetDefaultSpellsEntry()

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

References mPetDefaultSpellsMap.

◆ GetPetLevelupSpellList()

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

References mPetLevelupSpellMap.

◆ GetPrevSpellInChain()

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

References GetSpellChainNode().

◆ GetSetOfSpellsInSpellGroupWithFlag()

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

References mSpellGroupMap.

◆ GetSkillLineAbilityMapBounds()

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

References mSkillLineAbilityMap.

◆ GetSpellAreaForAreaMapBounds()

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

References mSpellAreaForAreaMap.

◆ GetSpellAreaForAuraMapBounds()

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

References mSpellAreaForAuraMap.

Referenced by LoadSpellAreas().

◆ GetSpellAreaForQuestEndMapBounds()

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

References mSpellAreaForQuestEndMap.

◆ GetSpellAreaForQuestMapBounds()

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

References mSpellAreaForQuestMap.

◆ GetSpellAreaMapBounds()

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

References mSpellAreaMap.

Referenced by LoadSpellAreas().

◆ GetSpellBonusData()

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

References GetFirstSpellInChain(), and mSpellBonusMap.

◆ GetSpellChainNode()

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

References mSpellChains.

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

◆ GetSpellCooldownOverride()

SpellCooldownOverride SpellMgr::GetSpellCooldownOverride ( uint32  spellId) const
2767{
2768 auto range = mSpellCooldownOverrideMap.find(spellId);
2769 return range->second;
2770}
SpellCooldownOverrideMap mSpellCooldownOverrideMap
Definition: SpellMgr.h:814

References mSpellCooldownOverrideMap.

◆ GetSpellDifficultyId()

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

References mSpellDifficultySearcherMap.

Referenced by GetSpellIdForDifficulty().

◆ GetSpellEnchantProcEvent()

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

References mSpellEnchantProcEventMap.

◆ GetSpellForDifficultyFromSpell()

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

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

◆ GetSpellGroup()

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

References GetFirstSpellInChain(), and mSpellGroupMap.

Referenced by CheckSpellGroupStackRules().

◆ GetSpellGroupSpecialFlags()

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

References GetFirstSpellInChain(), mSpellGroupMap, and SPELL_GROUP_SPECIAL_FLAG_NONE.

Referenced by CheckSpellGroupStackRules().

◆ GetSpellIdForDifficulty()

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

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

Referenced by GetSpellForDifficultyFromSpell().

◆ GetSpellInfo()

◆ GetSpellInfoStoreSize()

◆ GetSpellLearnSkill()

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

References mSpellLearnSkills.

◆ GetSpellLinked()

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

References mSpellLinkedMap.

◆ GetSpellMixologyBonus()

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

References mSpellMixologyMap.

◆ GetSpellProcEntry()

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

References mSpellProcMap.

◆ GetSpellProcEvent()

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

References mSpellProcEventMap.

◆ GetSpellRank()

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

References GetSpellChainNode().

◆ GetSpellsRequiredForSpellBounds()

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

References mSpellReq.

◆ GetSpellsRequiringSpellBounds()

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

References mSpellsReqSpell.

Referenced by IsSpellRequiringSpell().

◆ GetSpellTargetPosition()

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

References mSpellTargetPositions.

◆ GetSpellThreatEntry()

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

References GetFirstSpellInChain(), and mSpellThreatMap.

◆ GetSpellWithRank()

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

References GetSpellChainNode(), and GetSpellWithRank().

Referenced by GetSpellWithRank().

◆ HasSpellCooldownOverride()

bool SpellMgr::HasSpellCooldownOverride ( uint32  spellId) const
2762{
2763 return mSpellCooldownOverrideMap.find(spellId) != mSpellCooldownOverrideMap.end();
2764}

References mSpellCooldownOverrideMap.

◆ instance()

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

References instance().

Referenced by instance().

◆ IsAdditionalTalentSpell()

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

References mTalentSpellAdditionalSet.

◆ IsArenaAllowedEnchancment()

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

References mEnchantCustomAttr.

◆ IsSpellProcEventCanTriggeredBy()

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

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

Aura must have positive procflags for a HOT to proc

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

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

Aura must have positive procflags for a HOT to proc

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

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

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

◆ IsSpellRequiringSpell()

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

References GetSpellsRequiringSpellBounds().

Referenced by LoadSpellRequired().

◆ IsSpellValid()

◆ LoadEnchantCustomAttr()

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

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 ( )
2411{
2412 uint32 oldMSTime = getMSTime();
2413
2414 mPetDefaultSpellsMap.clear();
2415
2416 uint32 countCreature = 0;
2417 uint32 countData = 0;
2418
2419 CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
2420 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
2421 {
2422 if (!itr->second.PetSpellDataId)
2423 continue;
2424
2425 // for creature with PetSpellDataId get default pet spells from dbc
2426 CreatureSpellDataEntry const* spellDataEntry = sCreatureSpellDataStore.LookupEntry(itr->second.PetSpellDataId);
2427 if (!spellDataEntry)
2428 continue;
2429
2430 int32 petSpellsId = -int32(itr->second.PetSpellDataId);
2431 PetDefaultSpellsEntry petDefSpells;
2432 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2433 petDefSpells.spellid[j] = spellDataEntry->spellId[j];
2434
2435 if (LoadPetDefaultSpells_helper(&itr->second, petDefSpells))
2436 {
2437 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2438 ++countData;
2439 }
2440 }
2441
2442 LOG_INFO("server.loading", ">> Loaded Addition Spells For {} Pet Spell Data Entries in {} ms", countData, GetMSTimeDiffToNow(oldMSTime));
2443 LOG_INFO("server.loading", " ");
2444
2445 LOG_INFO("server.loading", "Loading Summonable Creature Templates...");
2446 oldMSTime = getMSTime();
2447
2448 // different summon spells
2449 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2450 {
2451 SpellInfo const* spellEntry = GetSpellInfo(i);
2452 if (!spellEntry)
2453 continue;
2454
2455 for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
2456 {
2457 if (spellEntry->Effects[k].Effect == SPELL_EFFECT_SUMMON || spellEntry->Effects[k].Effect == SPELL_EFFECT_SUMMON_PET)
2458 {
2459 uint32 creature_id = spellEntry->Effects[k].MiscValue;
2460 CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id);
2461 if (!cInfo)
2462 continue;
2463
2464 // already loaded
2465 if (cInfo->PetSpellDataId)
2466 continue;
2467
2468 // for creature without PetSpellDataId get default pet spells from creature_template
2469 int32 petSpellsId = cInfo->Entry;
2470 if (mPetDefaultSpellsMap.find(cInfo->Entry) != mPetDefaultSpellsMap.end())
2471 continue;
2472
2473 PetDefaultSpellsEntry petDefSpells;
2474 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2475 petDefSpells.spellid[j] = cInfo->spells[j];
2476
2477 if (LoadPetDefaultSpells_helper(cInfo, petDefSpells))
2478 {
2479 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2480 ++countCreature;
2481 }
2482 }
2483 }
2484 }
2485
2486 LOG_INFO("server.loading", ">> Loaded {} Summonable Creature emplates in {} ms", countCreature, GetMSTimeDiffToNow(oldMSTime));
2487 LOG_INFO("server.loading", " ");
2488}
std::int32_t int32
Definition: Define.h:104
DBCStorage< CreatureSpellDataEntry > sCreatureSpellDataStore(CreatureSpellDatafmt)
std::unordered_map< uint32, CreatureTemplate > CreatureTemplateContainer
Definition: CreatureData.h:281
bool LoadPetDefaultSpells_helper(CreatureTemplate const *cInfo, PetDefaultSpellsEntry &petDefSpells)
Definition: SpellMgr.cpp:2362
#define MAX_CREATURE_SPELL_DATA_SLOT
Definition: DBCStructure.h:798
@ SPELL_EFFECT_SUMMON_PET
Definition: SharedDefines.h:806
@ SPELL_EFFECT_SUMMON
Definition: SharedDefines.h:778
Definition: CreatureData.h:176
uint32 Entry
Definition: CreatureData.h:177
uint32 spells[MAX_CREATURE_SPELLS]
Definition: CreatureData.h:221
uint32 PetSpellDataId
Definition: CreatureData.h:222
Definition: SpellMgr.h:585
uint32 spellid[MAX_CREATURE_SPELL_DATA_SLOT]
Definition: SpellMgr.h:586
Definition: DBCStructure.h:801
uint32 spellId[MAX_CREATURE_SPELL_DATA_SLOT]
Definition: DBCStructure.h:803

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 (uint32 k = 0; k < sSkillLineAbilityStore.GetNumRows(); ++k)
2326 {
2327 SkillLineAbilityEntry const* skillLine = sSkillLineAbilityStore.LookupEntry(k);
2328 if (!skillLine)
2329 continue;
2330
2331 //if (skillLine->skillId != creatureFamily->skillLine[0] &&
2332 // (!creatureFamily->skillLine[1] || skillLine->skillId != creatureFamily->skillLine[1]))
2333 // continue;
2334
2335 if (skillLine->SkillLine != creatureFamily->skillLine[j])
2336 continue;
2337
2339 continue;
2340
2341 SpellInfo const* spell = GetSpellInfo(skillLine->Spell);
2342 if (!spell) // not exist or triggered or talent
2343 continue;
2344
2345 if (!spell->SpellLevel)
2346 continue;
2347
2348 PetLevelupSpellSet& spellSet = mPetLevelupSpellMap[creatureFamily->ID];
2349 if (spellSet.empty())
2350 ++family_count;
2351
2352 spellSet.insert(PetLevelupSpellSet::value_type(spell->SpellLevel, spell->Id));
2353 ++count;
2354 }
2355 }
2356 }
2357
2358 LOG_INFO("server.loading", ">> Loaded {} Pet Levelup And Default Spells For {} Families in {} ms", count, family_count, GetMSTimeDiffToNow(oldMSTime));
2359 LOG_INFO("server.loading", " ");
2360}
DBCStorage< CreatureFamilyEntry > sCreatureFamilyStore(CreatureFamilyfmt)
DBCStorage< SkillLineAbilityEntry > sSkillLineAbilityStore(SkillLineAbilityfmt)
std::multimap< uint32, uint32 > PetLevelupSpellSet
Definition: SpellMgr.h:579
@ SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN
Definition: DBCEnums.h:366
uint32 SpellLevel
Definition: SpellInfo.h:358
Definition: DBCStructure.h:754
uint32 ID
Definition: DBCStructure.h:755
uint32 skillLine[2]
Definition: DBCStructure.h:760
Definition: DBCStructure.h:1571
uint32 SkillLine
Definition: DBCStructure.h:1573
uint32 Spell
Definition: DBCStructure.h:1574
uint32 AcquireMethod
Definition: DBCStructure.h:1581

References SkillLineAbilityEntry::AcquireMethod, getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), SpellInfo::Id, CreatureFamilyEntry::ID, LOG_INFO, mPetLevelupSpellMap, sCreatureFamilyStore, SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN, CreatureFamilyEntry::skillLine, SkillLineAbilityEntry::SkillLine, SkillLineAbilityEntry::Spell, SpellInfo::SpellLevel, and sSkillLineAbilityStore.

◆ LoadSkillLineAbilityMap()

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

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

◆ LoadSpellAreas()

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

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

◆ LoadSpellBonuses()

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

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 ( )
2731{
2732 uint32 oldMSTime = getMSTime();
2733
2735
2736 QueryResult result = WorldDatabase.Query("SELECT Id, RecoveryTime, CategoryRecoveryTime, StartRecoveryTime, StartRecoveryCategory FROM spell_cooldown_overrides");
2737
2738 uint32 count = 0;
2739
2740 if (result)
2741 {
2742 do
2743 {
2744 Field* fields = result->Fetch();
2745 SpellCooldownOverride spellCooldown;
2746 uint32 spellId = fields[0].Get<uint32>();
2747 spellCooldown.RecoveryTime = fields[1].Get<uint32>();
2748 spellCooldown.CategoryRecoveryTime = fields[2].Get<uint32>();
2749 spellCooldown.StartRecoveryTime = fields[3].Get<uint32>();
2750 spellCooldown.StartRecoveryCategory = fields[4].Get<uint32>();
2751 mSpellCooldownOverrideMap[spellId] = spellCooldown;
2752
2753 ++count;
2754 } while (result->NextRow());
2755 }
2756
2757 LOG_INFO("server.loading", ">> Loaded {} Spell Cooldown Overrides entries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2758 LOG_INFO("server.loading", " ");
2759}
Definition: SpellMgr.h:600
uint32 StartRecoveryTime
Definition: SpellMgr.h:603
uint32 CategoryRecoveryTime
Definition: SpellMgr.h:602
uint32 StartRecoveryCategory
Definition: SpellMgr.h:604
uint32 RecoveryTime
Definition: SpellMgr.h:601

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

◆ LoadSpellEnchantProcData()

void SpellMgr::LoadSpellEnchantProcData ( )
2209{
2210 uint32 oldMSTime = getMSTime();
2211
2212 mSpellEnchantProcEventMap.clear(); // need for reload case
2213
2214 // 0 1 2 3
2215 QueryResult result = WorldDatabase.Query("SELECT entry, customChance, PPMChance, procEx FROM spell_enchant_proc_data");
2216 if (!result)
2217 {
2218 LOG_WARN("server.loading", ">> Loaded 0 spell enchant proc event conditions. DB table `spell_enchant_proc_data` is empty.");
2219 LOG_INFO("server.loading", " ");
2220 return;
2221 }
2222
2223 uint32 count = 0;
2224 do
2225 {
2226 Field* fields = result->Fetch();
2227
2228 uint32 enchantId = fields[0].Get<uint32>();
2229
2230 SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchantId);
2231 if (!ench)
2232 {
2233 LOG_ERROR("sql.sql", "Enchancment {} listed in `spell_enchant_proc_data` does not exist", enchantId);
2234 continue;
2235 }
2236
2238
2239 spe.customChance = fields[1].Get<uint32>();
2240 spe.PPMChance = fields[2].Get<float>();
2241 spe.procEx = fields[3].Get<uint32>();
2242
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:308
uint32 procEx
Definition: SpellMgr.h:311
uint32 customChance
Definition: SpellMgr.h:309
float PPMChance
Definition: SpellMgr.h:310

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

◆ LoadSpellGroups()

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

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

◆ LoadSpellGroupStackRules()

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

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

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_MOVE, AURA_INTERRUPT_FLAG_TAKE_DAMAGE, AURA_INTERRUPT_FLAG_TURNING, SummonPropertiesEntry::Category, SpellInfo::CategoryEntry, DISPEL_MAGIC, DISPEL_NONE, DONE_HIT_PROC_FLAG_MASK, EFFECT_0, EFFECT_1, EFFECT_2, EFFECT_RADIUS_100_YARDS, EFFECT_RADIUS_10_YARDS, EFFECT_RADIUS_12_YARDS, EFFECT_RADIUS_150_YARDS, EFFECT_RADIUS_18_YARDS, EFFECT_RADIUS_1_YARD, EFFECT_RADIUS_200_YARDS, EFFECT_RADIUS_20_YARDS, EFFECT_RADIUS_25_YARDS, EFFECT_RADIUS_2_YARDS, EFFECT_RADIUS_3_YARDS, EFFECT_RADIUS_4_YARDS, EFFECT_RADIUS_50000_YARDS, EFFECT_RADIUS_500_YARDS, EFFECT_RADIUS_5_YARDS, EFFECT_RADIUS_6_YARDS, EFFECT_RADIUS_70_YARDS, EFFECT_RADIUS_7_YARDS, EFFECT_RADIUS_8_YARDS, SpellInfo::Effects, FORM_CAT, FORM_MOONKIN, FORM_TREE, SpellInfo::GetEffects(), getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), GetSpellInfoStoreSize(), FactionTemplateEntry::hostileMask, IN_MILLISECONDS, LOCK_KEY_NONE, LOG_INFO, VehicleSeatEntry::m_attachmentOffsetX, VehicleSeatEntry::m_attachmentOffsetY, VehicleSeatEntry::m_attachmentOffsetZ, VehicleSeatEntry::m_flags, AchievementEntry::mapID, MAX_SPELL_EFFECTS, MECHANIC_NONE, MECHANIC_SNARE, MECHANIC_STUN, mSpellInfoMap, POWER_MANA, PROC_FLAG_DONE_MELEE_AUTO_ATTACK, PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS, SpellInfo::RangeEntry, SpellRangeEntry::RangeMax, SpellInfo::RecoveryTime, FactionEntry::ReputationFlags, sAchievementStore, sAreaTableStore, CreatureDisplayInfoEntry::scale, sCreatureDisplayInfoStore, sFactionStore, sFactionTemplateStore, sGraveyard, sLockStore, SpellInfo::Speed, SPEED_CHARGE, SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD, SPELL_ATTR0_ALLOW_WHILE_SITTING, SPELL_ATTR0_AURA_IS_DEBUFF, SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_NO_AURA_CANCEL, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR0_NOT_SHAPESHIFTED, SPELL_ATTR0_PASSIVE, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_ATTR1_ALLOW_WHILE_STEALTHED, SPELL_ATTR1_EXCLUDE_CASTER, SPELL_ATTR1_IMMUNITY_PURGES_EFFECT, SPELL_ATTR1_NO_REDIRECTION, SPELL_ATTR1_NO_THREAT, SPELL_ATTR2_ALLOW_DEAD_TARGET, SPELL_ATTR2_CANT_CRIT, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD, SPELL_ATTR3_ALWAYS_HIT, SPELL_ATTR3_CAN_PROC_FROM_PROCS, SPELL_ATTR3_COMPLETELY_BLOCKED, SPELL_ATTR3_DOT_STACKING_RULE, SPELL_ATTR3_IGNORE_CASTER_MODIFIERS, SPELL_ATTR3_ONLY_ON_PLAYER, SPELL_ATTR3_SUPRESS_CASTER_PROCS, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING, SPELL_ATTR4_ALLOW_ENETRING_ARENA, SPELL_ATTR4_AURA_EXPIRES_OFFLINE, SPELL_ATTR4_CANNOT_BE_STOLEN, SPELL_ATTR4_IGNORE_DAMAGE_TAKEN_MODIFIERS, SPELL_ATTR4_NO_CAST_LOG, SPELL_ATTR4_REACTIVE_DAMAGE_PROC, SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL, SPELL_ATTR5_ALLOW_WHILE_STUNNED, SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT, SPELL_ATTR5_EXTRA_INITIAL_PERIOD, SPELL_ATTR6_CAN_TARGET_UNTARGETABLE, SPELL_ATTR6_IGNORE_CASTER_DAMAGE_MODIFIERS, SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_ATTR6_NO_CATEGORY_COOLDOWN_MODS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_ATTR7_DISABLE_AURA_WHILE_DEAD, SPELL_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_ADD_PCT_MODIFIER, SPELL_AURA_DUMMY, SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST, SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT, SPELL_AURA_MOD_STUN, SPELL_AURA_MOD_TAUNT, SPELL_AURA_PERIODIC_DUMMY, SPELL_AURA_PERIODIC_HEAL, SPELL_AURA_PERIODIC_TRIGGER_SPELL, SPELL_AURA_PROC_TRIGGER_SPELL, SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE, SPELL_AURA_SCHOOL_ABSORB, SPELL_AURA_SET_VEHICLE_ID, SPELL_AURA_SPLIT_DAMAGE_PCT, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_APPLY_AREA_AURA_FRIEND, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_CHARGE, SPELL_EFFECT_CHARGE_DEST, SPELL_EFFECT_DUMMY, SPELL_EFFECT_JUMP, SPELL_EFFECT_JUMP_DEST, SPELL_EFFECT_LEAP_BACK, SPELL_EFFECT_MODIFY_THREAT_PERCENT, SPELL_EFFECT_POWER_BURN, SPELL_EFFECT_SCRIPT_EFFECT, SPELL_EFFECT_SELF_RESURRECT, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_TRIGGER_MISSILE, SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE, SPELL_INTERRUPT_FLAG_INTERRUPT, SPELL_PREVENTION_TYPE_NONE, SPELL_SCHOOL_MASK_MAGIC, SPELL_SCHOOL_MASK_SHADOW, SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_MAGE, SPELLFAMILY_PALADIN, SPELLFAMILY_POTION, SPELLFAMILY_ROGUE, SPELLFAMILY_UNK1, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, SPELLMOD_DAMAGE, SPELLMOD_EFFECT1, SPELLMOD_EFFECT2, sSpellCastTimesStore, sSpellCategoryStore, sSpellDurationStore, sSpellRadiusStore, sSpellRangeStore, sSummonPropertiesStore, SUMMON_CATEGORY_PET, SUMMON_TYPE_PET, SUMMON_TYPE_TOTEM, sVehicleSeatStore, TARGET_DEST_CASTER, TARGET_DEST_CASTER_BACK, TARGET_DEST_DB, TARGET_DEST_DEST, TARGET_DEST_DYNOBJ_ALLY, 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_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.
2808{
2809 uint32 const oldMSTime = getMSTime();
2810 uint32 const customAttrTime = getMSTime();
2811 uint32 count;
2812
2813 QueryResult result = WorldDatabase.Query("SELECT spell_id, attributes FROM spell_custom_attr");
2814
2815 if (!result)
2816 {
2817 LOG_WARN("server.loading", ">> Loaded 0 Spell Custom Attributes From DB. DB table `spell_custom_attr` Is Empty.");
2818 }
2819 else
2820 {
2821 for (count = 0; result->NextRow(); ++count)
2822 {
2823 Field const* fields = result->Fetch();
2824
2825 uint32 const spellId = fields[0].Get<uint32>();
2826 uint32 attributes = fields[1].Get<uint32>();
2827
2828 SpellInfo* spellInfo = _GetSpellInfo(spellId);
2829 if (!spellInfo)
2830 {
2831 LOG_INFO("sql.sql", "Table `spell_custom_attr` has wrong spell (spell_id: {}), ignored.", spellId);
2832 continue;
2833 }
2834
2835 if (attributes & SPELL_ATTR0_CU_NEGATIVE)
2836 {
2837 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2838 {
2839 if (spellInfo->Effects[i].IsEffect())
2840 {
2841 if ((attributes & (SPELL_ATTR0_CU_NEGATIVE_EFF0 << i)) && (attributes & (SPELL_ATTR0_CU_POSITIVE_EFF0 << i)))
2842 {
2843 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);
2845 }
2846 continue;
2847 }
2848
2849 if (attributes & (SPELL_ATTR0_CU_NEGATIVE_EFF0 << i))
2850 {
2851 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));
2852 attributes &= ~(SPELL_ATTR0_CU_NEGATIVE_EFF0 << i);
2853 }
2854 }
2855 }
2856
2857 if (attributes & SPELL_ATTR0_CU_POSITIVE)
2858 {
2859 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2860 {
2861 if (spellInfo->Effects[i].IsEffect())
2862 {
2863 continue;
2864 }
2865
2866 if ((attributes & (SPELL_ATTR0_CU_POSITIVE_EFF0 << i)))
2867 {
2868 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));
2869 attributes &= ~(SPELL_ATTR0_CU_POSITIVE_EFF0 << i);
2870 }
2871 }
2872 }
2873
2874 if ((attributes & SPELL_ATTR0_CU_FORCE_AURA_SAVING) && (attributes & SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED))
2875 {
2876 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);
2878 }
2879
2880 spellInfo->AttributesCu |= attributes;
2881 }
2882 LOG_INFO("server.loading", ">> Loaded {} spell custom attributes from DB in {} ms", count, GetMSTimeDiffToNow(customAttrTime));
2883 }
2884
2885 // xinef: create talent spells set
2886 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
2887 {
2888 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
2889 if (!talentInfo)
2890 continue;
2891
2892 for (uint8 j = 0; j < MAX_TALENT_RANK; j++)
2893 if (uint32 spellId = talentInfo->RankID[j])
2894 if (SpellInfo const* spellInfo = GetSpellInfo(spellId))
2895 for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
2896 if (spellInfo->Effects[k].Effect == SPELL_EFFECT_LEARN_SPELL)
2897 if (SpellInfo const* learnSpell = GetSpellInfo(spellInfo->Effects[k].TriggerSpell))
2898 if (learnSpell->IsRanked() && !learnSpell->HasAttribute(SpellAttr0(SPELL_ATTR0_PASSIVE | SPELL_ATTR0_DO_NOT_DISPLAY)))
2899 mTalentSpellAdditionalSet.insert(learnSpell->Id);
2900 }
2901
2902 SpellInfo* spellInfo = nullptr;
2903 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2904 {
2905 spellInfo = mSpellInfoMap[i];
2906 if (!spellInfo)
2907 continue;
2908
2909 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
2910 {
2911 switch (spellInfo->Effects[j].ApplyAuraName)
2912 {
2914 {
2915 switch (spellInfo->Id)
2916 {
2917 // Exceptions
2918 case 44801: // Spectral Invisibility (Kalecgos, SWP)
2919 case 46021: // Spectral Realm (SWP)
2920 break;
2921 default:
2923 break;
2924 }
2925 }
2926 break;
2943 break;
2944 }
2945
2946 switch (spellInfo->Effects[j].ApplyAuraName)
2947 {
2948 case SPELL_AURA_CONVERT_RUNE: // Can't be saved - aura handler relies on calculated amount and changes it
2949 case SPELL_AURA_OPEN_STABLE: // No point in saving this, since the stable dialog can't be open on aura load anyway.
2950 // Auras that require both caster & target to be in world cannot be saved
2958 break;
2959 default:
2960 break;
2961 }
2962
2963 switch (spellInfo->Effects[j].ApplyAuraName)
2964 {
2972 break;
2975 break;
2976 default:
2977 break;
2978 }
2979
2980 switch (spellInfo->Effects[j].Effect)
2981 {
2987 case SPELL_EFFECT_HEAL:
2989 break;
3000 break;
3003 case SPELL_EFFECT_JUMP:
3006 spellInfo->AttributesCu |= SPELL_ATTR0_CU_CHARGE;
3007 break;
3010 break;
3015 {
3016 // only enchanting profession enchantments procs can stack
3018 {
3019 uint32 enchantId = spellInfo->Effects[j].MiscValue;
3020 SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId);
3021 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
3022 {
3023 if (enchant->type[s] != ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL)
3024 continue;
3025
3026 SpellInfo* procInfo = _GetSpellInfo(enchant->spellid[s]);
3027 if (!procInfo)
3028 continue;
3029
3030 // if proced directly from enchantment, not via proc aura
3031 // NOTE: Enchant Weapon - Blade Ward also has proc aura spell and is proced directly
3032 // however its not expected to stack so this check is good
3034 continue;
3035
3037 }
3038 }
3039 break;
3040 }
3041 }
3042 }
3043
3044 // Xinef: spells ignoring hit result should not be binary
3045 if (!spellInfo->HasAttribute(SPELL_ATTR3_ALWAYS_HIT))
3046 {
3047 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3048 {
3049 if (spellInfo->Effects[j].Effect)
3050 {
3051 switch(spellInfo->Effects[j].Effect)
3052 {
3060 continue;
3069 if (spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
3070 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE_PERCENT ||
3071 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_DUMMY ||
3072 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH ||
3073 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_HEALTH_FUNNEL ||
3074 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DUMMY)
3075 continue;
3076 [[fallthrough]];
3077 default:
3078 if (spellInfo->Effects[j].CalcValue() || ((spellInfo->Effects[j].Effect == SPELL_EFFECT_INTERRUPT_CAST || spellInfo->HasAttribute(SPELL_ATTR0_CU_DONT_BREAK_STEALTH)) && !spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES)))
3079 if (spellInfo->Id != 69649 && spellInfo->Id != 71056 && spellInfo->Id != 71057 && spellInfo->Id != 71058 && spellInfo->Id != 73061 && spellInfo->Id != 73062 && spellInfo->Id != 73063 && spellInfo->Id != 73064) // Sindragosa Frost Breath
3080 if (spellInfo->SpellFamilyName != SPELLFAMILY_MAGE || !(spellInfo->SpellFamilyFlags[0] & 0x20)) // frostbolt
3081 if (spellInfo->Id != 55095) // frost fever
3082 if (spellInfo->SpellFamilyName != SPELLFAMILY_WARLOCK || !(spellInfo->SpellFamilyFlags[1] & 0x40000)) // Haunt
3083 {
3085 break;
3086 }
3087 continue;
3088 }
3089 }
3090 }
3091 }
3092
3093 // pussywizard:
3094 if ((spellInfo->SchoolMask & SPELL_SCHOOL_MASK_NORMAL) && (spellInfo->SchoolMask & SPELL_SCHOOL_MASK_MAGIC))
3095 {
3096 spellInfo->SchoolMask &= ~SPELL_SCHOOL_MASK_NORMAL;
3098 }
3099
3100 if (!spellInfo->_IsPositiveEffect(EFFECT_0, false))
3102
3103 if (!spellInfo->_IsPositiveEffect(EFFECT_1, false))
3105
3106 if (!spellInfo->_IsPositiveEffect(EFFECT_2, false))
3108
3109 if (spellInfo->SpellVisual[0] == 3879)
3111
3112 switch (spellInfo->SpellFamilyName)
3113 {
3115 // Shout
3116 if (spellInfo->SpellFamilyFlags[0] & 0x20000 || spellInfo->SpellFamilyFlags[1] & 0x20)
3118 break;
3119 case SPELLFAMILY_DRUID:
3120 // Roar
3121 if (spellInfo->SpellFamilyFlags[0] & 0x8)
3123 break;
3124 case SPELLFAMILY_HUNTER:
3125 // Aspects
3126 if (spellInfo->GetCategory() == 47)
3127 {
3129 }
3130 // Aimed Shot
3131 if (spellInfo->SpellFamilyFlags[0] & 0x00020000)
3132 {
3134 }
3135 break;
3136 default:
3137 break;
3138 }
3139
3140 switch (spellInfo->Id)
3141 {
3142 // Xinef: additional spells which should be binary
3143 case 45145: // Snake Trap Effect
3145 break;
3146 case 1776: // Gouge
3147 case 1777:
3148 case 8629:
3149 case 11285:
3150 case 11286:
3151 case 12540:
3152 case 13579:
3153 case 24698:
3154 case 28456:
3155 case 29425:
3156 case 34940:
3157 case 36862:
3158 case 38764:
3159 case 38863:
3160 case 52743: // Head Smack
3162 break;
3163 case 53: // Backstab
3164 case 2589:
3165 case 2590:
3166 case 2591:
3167 case 7159:
3168 case 8627:
3169 case 8721:
3170 case 11279:
3171 case 11280:
3172 case 11281:
3173 case 15582:
3174 case 15657:
3175 case 22416:
3176 case 25300:
3177 case 26863:
3178 case 37685:
3179 case 48656:
3180 case 48657:
3181 case 703: // Garrote
3182 case 8631:
3183 case 8632:
3184 case 8633:
3185 case 11289:
3186 case 11290:
3187 case 26839:
3188 case 26884:
3189 case 48675:
3190 case 48676:
3191 case 5221: // Shred
3192 case 6800:
3193 case 8992:
3194 case 9829:
3195 case 9830:
3196 case 27001:
3197 case 27002:
3198 case 48571:
3199 case 48572:
3200 case 8676: // Ambush
3201 case 8724:
3202 case 8725:
3203 case 11267:
3204 case 11268:
3205 case 11269:
3206 case 27441:
3207 case 48689:
3208 case 48690:
3209 case 48691:
3210 case 6785: // Ravage
3211 case 6787:
3212 case 9866:
3213 case 9867:
3214 case 27005:
3215 case 48578:
3216 case 48579:
3217 case 21987: // Lash of Pain
3218 case 23959: // Test Stab R50
3219 case 24825: // Test Backstab
3220 case 58563: // Assassinate Restless Lookout
3221 case 63124: // quest There's Something About the Squire (13654)
3223 break;
3224 case 26029: // Dark Glare
3225 case 43140: // Flame Breath
3226 case 43215: // Flame Breath
3227 case 70461: // Coldflame Trap
3228 case 72133: // Pain and Suffering
3229 case 73788: // Pain and Suffering
3230 case 73789: // Pain and Suffering
3231 case 73790: // Pain and Suffering
3232 case 63293: // Mimiron - spinning damage
3233 case 68873: // Wailing Souls
3234 case 70324: // Wailing Souls
3235 case 64619: // Ulduar, Mimiron, Emergency Fire Bot, Water Spray
3237 break;
3238 case 58690: // Cyanigosa, Tail Sweep
3239 case 59283: // Cyanigosa, Tail Sweep
3241 break;
3242 case 24340: // Meteor
3243 case 26558: // Meteor
3244 case 28884: // Meteor
3245 case 36837: // Meteor
3246 case 38903: // Meteor
3247 case 41276: // Meteor
3248 case 57467: // Meteor
3249 case 26789: // Shard of the Fallen Star
3250 case 31436: // Malevolent Cleave
3251 case 35181: // Dive Bomb
3252 case 40810: // Saber Lash
3253 case 43267: // Saber Lash
3254 case 43268: // Saber Lash
3255 case 42384: // Brutal Swipe
3256 case 45150: // Meteor Slash
3257 case 64688: // Sonic Screech
3258 case 72373: // Shared Suffering
3259 case 71904: // Chaos Bane
3260 case 70492: // Ooze Eruption
3261 case 72505: // Ooze Eruption
3262 case 72624: // Ooze Eruption
3263 case 72625: // Ooze Eruption
3264 // ONLY SPELLS WITH SPELLFAMILY_GENERIC and EFFECT_SCHOOL_DAMAGE, OR WEAPON_DMG_X
3265 case 66809: // Meteor Fists
3266 case 67331: // Meteor Fists
3267 case 66765: // Meteor Fists
3268 case 67333: // Meteor Fists
3270 break;
3271 case 18500: // Wing Buffet
3272 case 33086: // Wild Bite
3273 case 49749: // Piercing Blow
3274 case 52890: // Penetrating Strike
3275 case 53454: // Impale
3276 case 59446: // Impale
3277 case 62383: // Shatter
3278 case 64777: // Machine Gun
3279 case 65239: // Machine Gun
3280 case 69293: // Wing Buffet
3281 case 74439: // Machine Gun
3282 // Trial of the Crusader, Jaraxxus, Shivan Slash
3283 case 66378:
3284 case 67097:
3285 case 67098:
3286 case 67099:
3287 // Trial of the Crusader, Anub'arak, Impale
3288 case 65919:
3289 case 67858:
3290 case 67859:
3291 case 67860:
3292 case 63278: // Mark of the Faceless (General Vezax)
3293 case 64125: // Ulduar, Yogg-Saron, Squeeze
3294 case 64126: // Ulduar, Yogg-Saron, Squeeze
3295 case 62544: // Thrust (Argent Tournament)
3296 case 64588: // Thrust (Argent Tournament)
3297 case 66479: // Thrust (Argent Tournament)
3298 case 68505: // Thrust (Argent Tournament)
3299 case 62709: // Counterattack! (Argent Tournament)
3300 case 62626: // Break-Shield (Argent Tournament, Player)
3301 case 64590: // Break-Shield (Argent Tournament, Player)
3302 case 64342: // Break-Shield (Argent Tournament, NPC)
3303 case 64686: // Break-Shield (Argent Tournament, NPC)
3304 case 65147: // Break-Shield (Argent Tournament, NPC)
3305 case 68504: // Break-Shield (Argent Tournament, NPC)
3306 case 62874: // Charge (Argent Tournament, Player)
3307 case 68498: // Charge (Argent Tournament, Player)
3308 case 64591: // Charge (Argent Tournament, Player)
3309 case 63003: // Charge (Argent Tournament, NPC)
3310 case 63010: // Charge (Argent Tournament, NPC)
3311 case 68321: // Charge (Argent Tournament, NPC)
3312 case 72255: // Mark of the Fallen Champion (Deathbringer Saurfang)
3313 case 72444: // Mark of the Fallen Champion (Deathbringer Saurfang)
3314 case 72445: // Mark of the Fallen Champion (Deathbringer Saurfang)
3315 case 72446: // Mark of the Fallen Champion (Deathbringer Saurfang)
3316 case 72409: // Rune of Blood (Deathbringer Saurfang)
3317 case 72447: // Rune of Blood (Deathbringer Saurfang)
3318 case 72448: // Rune of Blood (Deathbringer Saurfang)
3319 case 72449: // Rune of Blood (Deathbringer Saurfang)
3320 case 49882: // Leviroth Self-Impale
3321 case 62775: // Ulduar: XT-002 Tympanic Tamparum
3323 break;
3324 case 64422: // Sonic Screech (Auriaya)
3327 break;
3328 case 72293: // Mark of the Fallen Champion (Deathbringer Saurfang)
3329 case 72347: // Lock Players and Tap Chest (Gunship Battle)
3331 break;
3332 default:
3333 break;
3334 case 63675: // Improved Devouring Plague
3335 case 17962: // Conflagrate
3336 case 32593: // Earth Shield aura
3337 case 32594: // Earth Shield aura
3338 case 49283: // Earth Shield aura
3339 case 49284: // Earth Shield aura
3340 case 50526: // Wandering Plague
3341 case 53353: // Chimera Shot - Serpent trigger
3342 case 52752: // Ancestral Awakening Heal
3344 break;
3345 case 65280: // Ulduar, Hodir, Singed
3346 case 28969: // Naxxramas, Crypt Guard, Acid Spit (10 normal)
3347 case 56098: // Naxxramas, Crypt Guard, Acid Spit (25 normal)
3348 case 27891: // Naxxramas, Sludge Belcher, Acidic Sludge (10 normal)
3349 case 54331: // Naxxramas, Sludge Belcher, Acidic Sludge (25 normal)
3350 case 29325: // Naxxramas, Stoneskin Gargoyle, Acid Volley (10 normal)
3351 case 54714: // Naxxramas, Stoneskin Gargoyle, Acid Volley (25 normal)
3352 case 65775: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (10 normal)
3353 case 67861: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (25 normal)
3354 case 67862: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (10 heroic)
3355 case 67863: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (25 heroic)
3356 case 55604: // Naxxramas, Unrelenting Trainee, Death Plague (10 normal)
3357 case 55645: // Naxxramas, Unrelenting Trainee, Death Plague (25 normal)
3358 case 67721: // Anub'arak, Nerubian Burrower, Expose Weakness (normal)
3359 case 67847: // Anub'arak, Nerubian Burrower, Expose Weakness (heroic)
3360 case 64638: // Ulduar, Winter Jormungar, Acidic Bite
3361 case 71157: // Icecrown Citadel, Plagued Zombie, Infected Wound
3362 case 72963: // Icecrown Citadel, Rot Worm, Flesh Rot (10 normal)
3363 case 72964: // Icecrown Citadel, Rot Worm, Flesh Rot (25 normal)
3364 case 72965: // Icecrown Citadel, Rot Worm, Flesh Rot (10 heroic)
3365 case 72966: // Icecrown Citadel, Rot Worm, Flesh Rot (25 heroic)
3366 case 72465: // Icecrown Citadel, Sindragosa, Respite for a Tormented Soul (weekly quest)
3367 case 45271: // Sunwell, Eredar Twins encounter, Dark Strike
3368 case 45347: // Sunwell, Eredar Twins encounter, Dark Touched
3369 case 45348: // Sunwell, Eredar Twins encounter, Flame Touched
3370 case 35859: // The Eye, Nether Vapor
3371 case 40520: // Black Temple, Shade Soul Channel
3372 case 40327: // Black Temple, Atrophy
3373 case 38449: // Serpentshrine Cavern, Blessing of the Tides
3374 case 38044: // Serpentshrine Cavern, Surge
3375 case 74507: // Ruby Sanctum, Siphoned Might
3376 case 49381: // Drak'tharon Keep, Consume
3377 case 59805: // Drak'tharon Keep, Consume
3378 case 55093: // Gundrak, Grip of Slad'ran
3379 case 30659: // Hellfire Ramparts, Fel Infusion
3380 case 54314: // Azjol'Nerub Drain Power
3381 case 59354: // Azjol'Nerub Drain Power
3382 case 34655: // Snake Trap, Deadly Poison
3383 case 11971: // Sunder Armor
3384 case 58567: // Player Sunder Armor
3385 case 12579: // Player Winter's Chill
3386 case 29306: // Naxxramas(Gluth's Zombies): Infected Wound
3387 case 61920: // Ulduar(Spellbreaker): Supercharge
3388 case 63978: // Ulduar(Rubble): Stone Nova
3389 case 15502: // Sunder Armor
3391 break;
3392 case 43138: // North Fleet Reservist Kill Credit
3394 break;
3395 case 6197: // Eagle Eye
3397 break;
3398 case 50315: // Disco Ball
3400 break;
3401 case 14183: // Premeditation
3403 break;
3404
3405 // Xinef: NOT CUSTOM, cant add in DBC CORRECTION because i need to swap effects, too much work to do there
3406 // Envenom
3407 case 32645:
3408 case 32684:
3409 case 57992:
3410 case 57993:
3411 {
3412 SpellEffectInfo info = spellInfo->Effects[EFFECT_0];
3413 spellInfo->Effects[EFFECT_0] = spellInfo->Effects[EFFECT_2];
3414 spellInfo->Effects[EFFECT_2] = info;
3415 break;
3416 }
3417
3418 // Xinef: Cooldown overwrites
3419 // Jotunheim Rapid-Fire Harpoon: Energy Reserve
3420 case 56585:
3421 spellInfo->RecoveryTime = 30000;
3422 spellInfo->_requireCooldownInfo = true;
3423 break;
3424 // Jotunheim Rapid-Fire Harpoon: Rapid-Fire Harpoon
3425 case 56570:
3426 spellInfo->RecoveryTime = 200;
3427 break;
3428 // Burst of Speed
3429 case 57493:
3430 spellInfo->RecoveryTime = 60000;
3431 spellInfo->_requireCooldownInfo = true;
3432 break;
3433 // Strafe Jotunheim Building
3434 case 7769:
3435 spellInfo->RecoveryTime = 1500;
3436 spellInfo->_requireCooldownInfo = true;
3437 break;
3438 case 44535: // Spirit Heal, abilities also have no cost
3439 spellInfo->Effects[EFFECT_0].MiscValue = 127;
3440 break;
3441 case 45537: // Cosmetic - Lightning Beam Channel
3443 break;
3444 }
3445
3446 if (spellInfo->Speed > 0.0f)
3447 {
3448 if (SpellVisualEntry const* spellVisual = sSpellVisualStore.LookupEntry(spellInfo->SpellVisual[0]))
3449 {
3450 if (spellVisual->HasMissile)
3451 {
3452 if (spellVisual->MissileModel == -4 || spellVisual->MissileModel == -5)
3453 {
3455 }
3456 }
3457 }
3458 }
3459
3460 spellInfo->_InitializeExplicitTargetMask();
3461
3462 if (sSpellMgr->HasSpellCooldownOverride(spellInfo->Id))
3463 {
3464 SpellCooldownOverride spellOverride = sSpellMgr->GetSpellCooldownOverride(spellInfo->Id);
3465
3466 if (spellInfo->RecoveryTime != spellOverride.RecoveryTime)
3467 {
3468 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3469 }
3470
3471 if (spellInfo->CategoryRecoveryTime != spellOverride.CategoryRecoveryTime)
3472 {
3473 spellInfo->CategoryRecoveryTime = spellOverride.CategoryRecoveryTime;
3474 }
3475
3476 if (spellInfo->StartRecoveryTime != spellOverride.StartRecoveryTime)
3477 {
3478 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3479 }
3480
3481 if (spellInfo->StartRecoveryCategory != spellOverride.StartRecoveryCategory)
3482 {
3483 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3484 }
3485 }
3486
3487 sScriptMgr->OnLoadSpellCustomAttr(spellInfo);
3488 }
3489
3490 // Xinef: addition for binary spells, ommit spells triggering other spells
3491 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3492 {
3493 spellInfo = mSpellInfoMap[i];
3494 if (!spellInfo)
3495 continue;
3496
3497 if (!(spellInfo->AttributesCu & SPELL_ATTR0_CU_BINARY_SPELL))
3498 continue;
3499
3500 bool allNonBinary = true;
3501 bool overrideAttr = false;
3502 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3503 {
3504 if (spellInfo->Effects[j].ApplyAuraName && spellInfo->Effects[j].TriggerSpell)
3505 {
3506 switch(spellInfo->Effects[j].ApplyAuraName)
3507 {
3511 if (SpellInfo const* triggerSpell = sSpellMgr->GetSpellInfo(spellInfo->Effects[j].TriggerSpell))
3512 {
3513 overrideAttr = true;
3514 if (triggerSpell->AttributesCu & SPELL_ATTR0_CU_BINARY_SPELL)
3515 allNonBinary = false;
3516 }
3517 }
3518 }
3519 }
3520
3521 if (overrideAttr && allNonBinary)
3522 spellInfo->AttributesCu &= ~SPELL_ATTR0_CU_BINARY_SPELL;
3523 }
3524
3525 LOG_INFO("server.loading", ">> Loaded SpellInfo Custom Attributes in {} ms", GetMSTimeDiffToNow(oldMSTime));
3526 LOG_INFO("server.loading", " ");
3527}
DBCStorage< SpellVisualEntry > sSpellVisualStore(SpellVisualfmt)
DBCStorage< TalentEntry > sTalentStore(TalentEntryfmt)
#define sScriptMgr
Definition: ScriptMgr.h:2702
@ SPELL_AURA_PERIODIC_DAMAGE
Definition: SpellAuraDefines.h:66
@ SPELL_AURA_OBS_MOD_HEALTH
Definition: SpellAuraDefines.h:83
@ SPELL_AURA_PERIODIC_HEALTH_FUNNEL
Definition: SpellAuraDefines.h:125
@ SPELL_AURA_PERIODIC_MANA_LEECH
Definition: SpellAuraDefines.h:127
@ SPELL_AURA_MOD_POSSESS_PET
Definition: SpellAuraDefines.h:191
@ SPELL_AURA_CONVERT_RUNE
Definition: SpellAuraDefines.h:312
@ SPELL_AURA_MOD_FEAR
Definition: SpellAuraDefines.h:70
@ SPELL_AURA_OBS_MOD_POWER
Definition: SpellAuraDefines.h:84
@ SPELL_AURA_CONTROL_VEHICLE
Definition: SpellAuraDefines.h:299
@ SPELL_AURA_MOD_INVISIBILITY
Definition: SpellAuraDefines.h:81
@ SPELL_AURA_PERIODIC_DAMAGE_PERCENT
Definition: SpellAuraDefines.h:152
@ SPELL_AURA_MOD_RANGED_HASTE
Definition: SpellAuraDefines.h:203
@ SPELL_AURA_AOE_CHARM
Definition: SpellAuraDefines.h:240
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE
Definition: SpellAuraDefines.h:290
@ SPELL_AURA_PERIODIC_ENERGIZE
Definition: SpellAuraDefines.h:87
@ SPELL_AURA_MOD_INVISIBILITY_DETECT
Definition: SpellAuraDefines.h:82
@ SPELL_AURA_WATER_BREATHING
Definition: SpellAuraDefines.h:145
@ SPELL_AURA_PERIODIC_LEECH
Definition: SpellAuraDefines.h:116
@ SPELL_AURA_POWER_BURN
Definition: SpellAuraDefines.h:225
@ SPELL_AURA_OPEN_STABLE
Definition: SpellAuraDefines.h:355
@ SPELL_AURA_MOD_CONFUSE
Definition: SpellAuraDefines.h:68
@ SPELL_AURA_TRACK_CREATURES
Definition: SpellAuraDefines.h:107
@ SPELL_AURA_MOD_POSSESS
Definition: SpellAuraDefines.h:65
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT
Definition: SpellAuraDefines.h:111
@ SPELL_AURA_BIND_SIGHT
Definition: SpellAuraDefines.h:64
@ 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:209
@ SPELL_ATTR0_CU_FORCE_AURA_SAVING
Definition: SpellInfo.h:205
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition: SpellInfo.h:183
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition: SpellInfo.h:182
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition: SpellInfo.h:193
@ SPELL_ATTR0_CU_CONE_BACK
Definition: SpellInfo.h:177
@ SPELL_ATTR0_CU_SINGLE_AURA_STACK
Definition: SpellInfo.h:198
@ SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED
Definition: SpellInfo.h:200
@ SPELL_ATTR0_CU_NEGATIVE_EFF2
Definition: SpellInfo.h:190
@ SPELL_ATTR0_CU_AURA_CC
Definition: SpellInfo.h:181
@ SPELL_ATTR0_CU_NEGATIVE_EFF1
Definition: SpellInfo.h:189
@ SPELL_ATTR0_CU_CHARGE
Definition: SpellInfo.h:185
@ SPELL_ATTR0_CU_NEGATIVE
Definition: SpellInfo.h:208
@ 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:49
@ ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL
Definition: DBCEnums.h:372
#define MAX_TALENT_RANK
Definition: DBCStructure.h:1894
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition: DBCStructure.h:1814
@ SPELL_EFFECT_ENERGIZE_PCT
Definition: SharedDefines.h:887
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
Definition: SharedDefines.h:785
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition: SharedDefines.h:842
@ SPELL_EFFECT_ENCHANT_ITEM
Definition: SharedDefines.h:803
@ SPELL_EFFECT_HEALTH_LEECH
Definition: SharedDefines.h:759
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition: SharedDefines.h:808
@ SPELL_EFFECT_HEAL
Definition: SharedDefines.h:760
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
Definition: SharedDefines.h:871
@ SPELL_EFFECT_TRIGGER_SPELL
Definition: SharedDefines.h:814
@ SPELL_EFFECT_HEAL_MAX_HEALTH
Definition: SharedDefines.h:817
@ SPELL_EFFECT_APPLY_AREA_AURA_PET
Definition: SharedDefines.h:869
@ SPELL_EFFECT_PICKPOCKET
Definition: SharedDefines.h:821
@ SPELL_EFFECT_HEAL_MECHANICAL
Definition: SharedDefines.h:825
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
Definition: SharedDefines.h:781
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
Definition: SharedDefines.h:815
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition: SharedDefines.h:767
@ SPELL_EFFECT_PERSISTENT_AREA_AURA
Definition: SharedDefines.h:777
@ SPELL_EFFECT_ENERGIZE
Definition: SharedDefines.h:780
@ SPELL_EFFECT_POWER_DRAIN
Definition: SharedDefines.h:758
@ SPELL_EFFECT_SCHOOL_DAMAGE
Definition: SharedDefines.h:752
@ SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
Definition: SharedDefines.h:879
@ SPELL_EFFECT_HEAL_PCT
Definition: SharedDefines.h:886
@ SPELL_EFFECT_INTERRUPT_CAST
Definition: SharedDefines.h:818
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition: SharedDefines.h:906
@ SPELL_EFFECT_APPLY_AREA_AURA_OWNER
Definition: SharedDefines.h:893
@ SPELLFAMILY_WARLOCK
Definition: SharedDefines.h:3505
@ SPELLFAMILY_DRUID
Definition: SharedDefines.h:3507
SpellAttr0
Definition: SharedDefines.h:353
@ SPELL_ATTR0_DO_NOT_DISPLAY
Definition: SharedDefines.h:361
@ SKILL_ENCHANTING
Definition: SharedDefines.h:2926
uint32 GetCategory() const
Definition: SpellInfo.cpp:864
uint32 AttributesCu
Definition: SpellInfo.h:330
bool _requireCooldownInfo
Definition: SpellInfo.h:401
std::array< uint32, 2 > SpellVisual
Definition: SpellInfo.h:377
uint32 CategoryRecoveryTime
Definition: SpellInfo.h:347
bool _IsPositiveEffect(uint8 effIndex, bool deep) const
Definition: SpellInfo.cpp:2603
uint32 StartRecoveryTime
Definition: SpellInfo.h:349
void _InitializeExplicitTargetMask()
Definition: SpellInfo.cpp:2575
bool HasAura(AuraType aura) const
Definition: SpellInfo.cpp:877
uint32 StartRecoveryCategory
Definition: SpellInfo.h:348
uint32 AuraInterruptFlags
Definition: SpellInfo.h:351
SpellInfo * _GetSpellInfo(uint32 spellId)
Definition: SpellMgr.h:753
uint32 spellid[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition: DBCStructure.h:1823
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition: DBCStructure.h:1820
Definition: DBCStructure.h:1847
Definition: DBCStructure.h:1899
std::array< uint32, MAX_TALENT_RANK > RankID
Definition: DBCStructure.h:1904

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

◆ LoadSpellInfoStore()

void SpellMgr::LoadSpellInfoStore ( )
2702{
2703 uint32 oldMSTime = getMSTime();
2704
2706 mSpellInfoMap.resize(sSpellStore.GetNumRows(), nullptr);
2707
2708 for (SpellEntry const* spellEntry : sSpellStore)
2709 mSpellInfoMap[spellEntry->Id] = new SpellInfo(spellEntry);
2710
2711 for (uint32 spellIndex = 0; spellIndex < GetSpellInfoStoreSize(); ++spellIndex)
2712 {
2713 if (!mSpellInfoMap[spellIndex])
2714 continue;
2715
2716 for (SpellEffectInfo const& spellEffectInfo : mSpellInfoMap[spellIndex]->GetEffects())
2717 {
2718 //ASSERT(effect.EffectIndex < MAX_SPELL_EFFECTS, "MAX_SPELL_EFFECTS must be at least %u", effect.EffectIndex + 1);
2719 ASSERT(spellEffectInfo.Effect < TOTAL_SPELL_EFFECTS, "TOTAL_SPELL_EFFECTS must be at least %u", spellEffectInfo.Effect + 1);
2720 ASSERT(spellEffectInfo.ApplyAuraName < TOTAL_AURAS, "TOTAL_AURAS must be at least %u", spellEffectInfo.ApplyAuraName + 1);
2721 ASSERT(spellEffectInfo.TargetA.GetTarget() < TOTAL_SPELL_TARGETS, "TOTAL_SPELL_TARGETS must be at least %u", spellEffectInfo.TargetA.GetTarget() + 1);
2722 ASSERT(spellEffectInfo.TargetB.GetTarget() < TOTAL_SPELL_TARGETS, "TOTAL_SPELL_TARGETS must be at least %u", spellEffectInfo.TargetB.GetTarget() + 1);
2723 }
2724 }
2725
2726 LOG_INFO("server.loading", ">> Loaded Spell Custom Attributes in {} ms", GetMSTimeDiffToNow(oldMSTime));
2727 LOG_INFO("server.loading", " ");
2728}
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
@ TOTAL_AURAS
Definition: SpellAuraDefines.h:380
@ TOTAL_SPELL_EFFECTS
Definition: SharedDefines.h:915
@ TOTAL_SPELL_TARGETS
Definition: SharedDefines.h:1486
Definition: DBCStructure.h:1615

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

◆ LoadSpellLearnSkills()

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

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

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

◆ LoadSpellPetAuras()

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

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

◆ LoadSpellProcEvents()

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

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

◆ LoadSpellProcs()

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

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

◆ LoadSpellRanks()

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

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

◆ LoadSpellRequired()

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

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

◆ LoadSpellSpecificAndAuraState()

void SpellMgr::LoadSpellSpecificAndAuraState ( )
2790{
2791 uint32 oldMSTime = getMSTime();
2792
2793 SpellInfo* spellInfo = nullptr;
2794 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2795 {
2796 spellInfo = mSpellInfoMap[i];
2797 if (!spellInfo)
2798 continue;
2799 spellInfo->_spellSpecific = spellInfo->LoadSpellSpecific();
2800 spellInfo->_auraState = spellInfo->LoadAuraState();
2801 }
2802
2803 LOG_INFO("server.loading", ">> Loaded Spell Specific And Aura State in {} ms", GetMSTimeDiffToNow(oldMSTime));
2804 LOG_INFO("server.loading", " ");
2805}
SpellSpecificType LoadSpellSpecific() const
Definition: SpellInfo.cpp:2125
AuraStateType LoadAuraState() const
Definition: SpellInfo.cpp:2050
AuraStateType _auraState
Definition: SpellInfo.h:396
SpellSpecificType _spellSpecific
Definition: SpellInfo.h:397

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

◆ LoadSpellTalentRanks()

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

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

Referenced by LoadSpellRanks().

◆ LoadSpellTargetPositions()

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

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

◆ LoadSpellThreats()

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

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

◆ SetSpellDifficultyId()

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

References mSpellDifficultySearcherMap.

◆ UnloadSpellInfoChains()

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

References mSpellChains, and mSpellInfoMap.

Referenced by LoadSpellTalentRanks().

◆ UnloadSpellInfoImplicitTargetConditionLists()

void SpellMgr::UnloadSpellInfoImplicitTargetConditionLists ( )
2781{
2782 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2783 {
2784 if (mSpellInfoMap[i])
2785 mSpellInfoMap[i]->_UnloadImplicitTargetConditionLists();
2786 }
2787}

References GetSpellInfoStoreSize(), and mSpellInfoMap.

◆ UnloadSpellInfoStore()

void SpellMgr::UnloadSpellInfoStore ( )
2773{
2774 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2775 delete mSpellInfoMap[i];
2776
2777 mSpellInfoMap.clear();
2778}

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