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

References UnloadSpellInfoStore().

Member Function Documentation

◆ _GetSpellInfo()

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

References GetSpellInfoStoreSize(), and mSpellInfoMap.

Referenced by LoadSpellInfoCustomAttributes().

◆ AssertSpellInfo()

SpellInfo const * SpellMgr::AssertSpellInfo ( uint32  spellId) const
inline
729 {
730 ASSERT(spellId < GetSpellInfoStoreSize());
731 SpellInfo const* spellInfo = mSpellInfoMap[spellId];
732 ASSERT(spellInfo);
733 return spellInfo;
734 }
#define ASSERT
Definition: Errors.h:68
Definition: SpellInfo.h: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:1056
uint32 GetHitMask() const
Definition: Unit.h:876
SpellSchoolMask GetSchoolMask() const
Definition: Unit.h:878
Unit * GetActionTarget() const
Definition: Unit.h:871
uint32 GetSpellTypeMask() const
Definition: Unit.h:874
uint32 GetTypeMask() const
Definition: Unit.h:873
SpellInfo const * GetSpellInfo() const
Definition: Unit.cpp:187
Unit * GetActor()
Definition: Unit.h:870
uint32 GetSpellPhaseMask() const
Definition: Unit.h:875
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:356
@ SPELL_GROUP_STACK_FLAG_EXCLUSIVE
Definition: SpellMgr.h:358
@ SPELL_GROUP_STACK_FLAG_FORCED_WEAKEST
Definition: SpellMgr.h:367
@ SPELL_GROUP_STACK_FLAG_FORCED_STRONGEST
Definition: SpellMgr.h:366
@ SPELL_GROUP_STACK_FLAG_NONE
Definition: SpellMgr.h:357
@ SPELL_GROUP_STACK_FLAG_NEVER_STACK
Definition: SpellMgr.h:361
SpellGroupSpecialFlags
Definition: SpellMgr.h:334
@ SPELL_GROUP_SPECIAL_FLAG_FORCED_STRONGEST
Definition: SpellMgr.h:341
@ SPELL_GROUP_SPECIAL_FLAG_SAME_SPELL_CHECK
Definition: SpellMgr.h:348
@ SPELL_GROUP_SPECIAL_FLAG_STACK_EXCLUSIVE_MAX
Definition: SpellMgr.h:340
uint32 GetSpellGroup(uint32 spellid) const
Definition: SpellMgr.cpp: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
737 {
738 if (spellId >= GetSpellInfoStoreSize())
739 {
740 LOG_ERROR("server", "spellId {} is not lower than GetSpellInfoStoreSize() ({})", spellId, GetSpellInfoStoreSize());
741 return nullptr;
742 }
743 SpellInfo const* spellInfo = mSpellInfoMap[spellId];
744 if (!spellInfo)
745 {
746 LOG_ERROR("server", "spellId {} has invalid spellInfo", spellId);
747 return nullptr;
748 }
749 return spellInfo;
750 }
#define LOG_ERROR(filterType__,...)
Definition: Log.h:157

References GetSpellInfoStoreSize(), LOG_ERROR, and mSpellInfoMap.

◆ CheckSpellValid()

bool SpellMgr::CheckSpellValid ( SpellInfo const *  spellInfo,
uint32  spellId,
bool  isTalent 
)
static
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:825
#define MAX_SPELL_REAGENTS
Definition: DBCStructure.h:1637
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:1635
@ SPELL_EFFECT_CREATE_ITEM_2
Definition: SharedDefines.h:935
@ SPELL_EFFECT_LEARN_SPELL
Definition: SharedDefines.h:814
@ SPELL_EFFECT_CREATE_ITEM
Definition: SharedDefines.h:802
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:554
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:802

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

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

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

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

References mSpellGroupMap.

◆ GetSkillLineAbilityMapBounds()

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

References mSkillLineAbilityMap.

◆ GetSpellAreaForAreaMapBounds()

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

References mSpellAreaForAreaMap.

◆ GetSpellAreaForAuraMapBounds()

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

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

References mSpellAreaForQuestEndMap.

◆ GetSpellAreaForQuestMapBounds()

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

References mSpellAreaForQuestMap.

◆ GetSpellAreaMapBounds()

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

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

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

References mSpellChains.

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

◆ GetSpellCooldownOverride()

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

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

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

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:169
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:726

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

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:278
#define MAX_DIFFICULTY
Definition: DBCEnums.h:291
uint32 GetSpellDifficultyId(uint32 spellId) const
Definition: SpellMgr.cpp:479
Definition: DBCStructure.h:1772
int32 SpellID[MAX_DIFFICULTY]
Definition: DBCStructure.h:1774

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

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

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

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

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

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

References mSpellReq.

◆ GetSpellsRequiringSpellBounds()

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

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

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

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
2763{
2764 return mSpellCooldownOverrideMap.find(spellId) != mSpellCooldownOverrideMap.end();
2765}

References mSpellCooldownOverrideMap.

◆ instance()

SpellMgr * SpellMgr::instance ( )
static
365{
366 static SpellMgr instance;
367 return &instance;
368}
Definition: SpellMgr.h:640
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:822

References mTalentSpellAdditionalSet.

◆ IsArenaAllowedEnchancment()

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

References mEnchantCustomAttr.

◆ IsSpellProcEventCanTriggeredBy()

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

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

Aura must have positive procflags for a HOT to proc

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

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

Aura must have positive procflags for a HOT to proc

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

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:297
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:570
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:165
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:832
@ SPELL_ATTR2_ENCHANT_OWN_ITEM_ONLY
Definition: SharedDefines.h:469
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:412
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition: SpellInfo.h:391
Definition: DBCStructure.h:1842

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

◆ LoadPetDefaultSpells()

void SpellMgr::LoadPetDefaultSpells ( )
2412{
2413 uint32 oldMSTime = getMSTime();
2414
2415 mPetDefaultSpellsMap.clear();
2416
2417 uint32 countCreature = 0;
2418 uint32 countData = 0;
2419
2420 CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
2421 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
2422 {
2423 if (!itr->second.PetSpellDataId)
2424 continue;
2425
2426 // for creature with PetSpellDataId get default pet spells from dbc
2427 CreatureSpellDataEntry const* spellDataEntry = sCreatureSpellDataStore.LookupEntry(itr->second.PetSpellDataId);
2428 if (!spellDataEntry)
2429 continue;
2430
2431 int32 petSpellsId = -int32(itr->second.PetSpellDataId);
2432 PetDefaultSpellsEntry petDefSpells;
2433 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2434 petDefSpells.spellid[j] = spellDataEntry->spellId[j];
2435
2436 if (LoadPetDefaultSpells_helper(&itr->second, petDefSpells))
2437 {
2438 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2439 ++countData;
2440 }
2441 }
2442
2443 LOG_INFO("server.loading", ">> Loaded Addition Spells For {} Pet Spell Data Entries in {} ms", countData, GetMSTimeDiffToNow(oldMSTime));
2444 LOG_INFO("server.loading", " ");
2445
2446 LOG_INFO("server.loading", "Loading Summonable Creature Templates...");
2447 oldMSTime = getMSTime();
2448
2449 // different summon spells
2450 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2451 {
2452 SpellInfo const* spellInfo = GetSpellInfo(i);
2453 if (!spellInfo)
2454 continue;
2455
2456 for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
2457 {
2458 if (spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON || spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON_PET)
2459 {
2460 uint32 creature_id = spellInfo->Effects[k].MiscValue;
2461 CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id);
2462 if (!cInfo)
2463 continue;
2464
2465 // already loaded
2466 if (cInfo->PetSpellDataId)
2467 continue;
2468
2469 // for creature without PetSpellDataId get default pet spells from creature_template
2470 int32 petSpellsId = cInfo->Entry;
2471 if (mPetDefaultSpellsMap.find(cInfo->Entry) != mPetDefaultSpellsMap.end())
2472 continue;
2473
2474 PetDefaultSpellsEntry petDefSpells;
2475 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2476 petDefSpells.spellid[j] = cInfo->spells[j];
2477
2478 if (LoadPetDefaultSpells_helper(cInfo, petDefSpells))
2479 {
2480 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2481 ++countCreature;
2482 }
2483 }
2484 }
2485 }
2486
2487 LOG_INFO("server.loading", ">> Loaded {} Summonable Creature emplates in {} ms", countCreature, GetMSTimeDiffToNow(oldMSTime));
2488 LOG_INFO("server.loading", " ");
2489}
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:2363
#define MAX_CREATURE_SPELL_DATA_SLOT
Definition: DBCStructure.h:798
@ SPELL_EFFECT_SUMMON_PET
Definition: SharedDefines.h:834
@ SPELL_EFFECT_SUMMON
Definition: SharedDefines.h:806
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:592
uint32 spellid[MAX_CREATURE_SPELL_DATA_SLOT]
Definition: SpellMgr.h:593
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 ( )
2307{
2308 uint32 oldMSTime = getMSTime();
2309
2310 mPetLevelupSpellMap.clear(); // need for reload case
2311
2312 uint32 count = 0;
2313 uint32 family_count = 0;
2314
2315 for (uint32 i = 0; i < sCreatureFamilyStore.GetNumRows(); ++i)
2316 {
2317 CreatureFamilyEntry const* creatureFamily = sCreatureFamilyStore.LookupEntry(i);
2318 if (!creatureFamily) // not exist
2319 continue;
2320
2321 for (uint8 j = 0; j < 2; ++j)
2322 {
2323 if (!creatureFamily->skillLine[j])
2324 continue;
2325
2326 for (uint32 k = 0; k < sSkillLineAbilityStore.GetNumRows(); ++k)
2327 {
2328 SkillLineAbilityEntry const* skillLine = sSkillLineAbilityStore.LookupEntry(k);
2329 if (!skillLine)
2330 continue;
2331
2332 //if (skillLine->skillId != creatureFamily->skillLine[0] &&
2333 // (!creatureFamily->skillLine[1] || skillLine->skillId != creatureFamily->skillLine[1]))
2334 // continue;
2335
2336 if (skillLine->SkillLine != creatureFamily->skillLine[j])
2337 continue;
2338
2340 continue;
2341
2342 SpellInfo const* spell = GetSpellInfo(skillLine->Spell);
2343 if (!spell) // not exist or triggered or talent
2344 continue;
2345
2346 if (!spell->SpellLevel)
2347 continue;
2348
2349 PetLevelupSpellSet& spellSet = mPetLevelupSpellMap[creatureFamily->ID];
2350 if (spellSet.empty())
2351 ++family_count;
2352
2353 spellSet.insert(PetLevelupSpellSet::value_type(spell->SpellLevel, spell->Id));
2354 ++count;
2355 }
2356 }
2357 }
2358
2359 LOG_INFO("server.loading", ">> Loaded {} Pet Levelup And Default Spells For {} Families in {} ms", count, family_count, GetMSTimeDiffToNow(oldMSTime));
2360 LOG_INFO("server.loading", " ");
2361}
DBCStorage< CreatureFamilyEntry > sCreatureFamilyStore(CreatureFamilyfmt)
DBCStorage< SkillLineAbilityEntry > sSkillLineAbilityStore(SkillLineAbilityfmt)
std::multimap< uint32, uint32 > PetLevelupSpellSet
Definition: SpellMgr.h:586
@ SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN
Definition: DBCEnums.h:369
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:1596
uint32 SkillLine
Definition: DBCStructure.h:1598
uint32 Spell
Definition: DBCStructure.h:1599
uint32 AcquireMethod
Definition: DBCStructure.h:1606

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

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

◆ LoadSpellCooldownOverrides()

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

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

◆ LoadSpellEnchantProcData()

void SpellMgr::LoadSpellEnchantProcData ( )
2209{
2210 uint32 oldMSTime = getMSTime();
2211
2212 mSpellEnchantProcEventMap.clear(); // need for reload case
2213
2214 // 0 1 2 3 4
2215 QueryResult result = WorldDatabase.Query("SELECT entry, customChance, PPMChance, procEx, attributeMask 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 spe.attributeMask = fields[4].Get<uint32>();
2243
2244 mSpellEnchantProcEventMap[enchantId] = spe;
2245
2246 ++count;
2247 } while (result->NextRow());
2248
2249 LOG_INFO("server.loading", ">> Loaded {} Enchant Proc Data Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2250 LOG_INFO("server.loading", " ");
2251}
Definition: SpellMgr.h:314
uint32 procEx
Definition: SpellMgr.h:317
uint32 attributeMask
Definition: SpellMgr.h:318
uint32 customChance
Definition: SpellMgr.h:315
float PPMChance
Definition: SpellMgr.h:316

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

◆ LoadSpellGroups()

void SpellMgr::LoadSpellGroups ( )
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:350
uint8 GetRank() const
Definition: SpellInfo.cpp:2480
Definition: SpellMgr.h:376
SpellGroupSpecialFlags specialFlags
Definition: SpellMgr.h:378
uint32 groupId
Definition: SpellMgr.h:377

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

◆ LoadSpellGroupStackRules()

void SpellMgr::LoadSpellGroupStackRules ( )
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:363

References Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, mSpellGroupMap, mSpellGroupStackMap, SPELL_GROUP_STACK_FLAG_MAX, and WorldDatabase.

◆ LoadSpellInfoCorrections()

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

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

References _GetSpellInfo(), SpellInfo::_InitializeExplicitTargetMask(), SpellInfo::_IsPositiveEffect(), SpellInfo::_requireCooldownInfo, SpellInfo::AttributesCu, AURA_INTERRUPT_FLAG_CAST, SpellInfo::AuraInterruptFlags, SpellInfo::CategoryRecoveryTime, SpellCooldownOverride::CategoryRecoveryTime, EFFECT_0, EFFECT_1, EFFECT_2, SpellInfo::Effects, Field::Get(), SpellInfo::GetCategory(), getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), GetSpellInfoStoreSize(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), SpellInfo::Id, IsPartOfSkillLine(), ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL, LOG_ERROR, LOG_INFO, LOG_WARN, MAX_SPELL_EFFECTS, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, MAX_TALENT_RANK, mSpellInfoMap, mTalentSpellAdditionalSet, TalentEntry::RankID, SpellInfo::RecoveryTime, SpellCooldownOverride::RecoveryTime, SpellInfo::SchoolMask, SKILL_ENCHANTING, SpellInfo::Speed, SPELL_ATTR0_CU_ALLOW_INFLIGHT_TARGET, SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED, SPELL_ATTR0_CU_AURA_CC, SPELL_ATTR0_CU_BINARY_SPELL, SPELL_ATTR0_CU_CHARGE, SPELL_ATTR0_CU_CONE_BACK, SPELL_ATTR0_CU_CONE_LINE, SPELL_ATTR0_CU_DIRECT_DAMAGE, SPELL_ATTR0_CU_DONT_BREAK_STEALTH, SPELL_ATTR0_CU_ENCHANT_PROC, SPELL_ATTR0_CU_FORCE_AURA_SAVING, SPELL_ATTR0_CU_FORCE_SEND_CATEGORY_COOLDOWNS, SPELL_ATTR0_CU_IGNORE_ARMOR, SPELL_ATTR0_CU_IGNORE_EVADE, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_CU_NEGATIVE, SPELL_ATTR0_CU_NEGATIVE_EFF0, SPELL_ATTR0_CU_NEGATIVE_EFF1, SPELL_ATTR0_CU_NEGATIVE_EFF2, SPELL_ATTR0_CU_NO_INITIAL_THREAT, SPELL_ATTR0_CU_NO_POSITIVE_TAKEN_BONUS, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR0_CU_PICKPOCKET, SPELL_ATTR0_CU_POSITIVE, SPELL_ATTR0_CU_POSITIVE_EFF0, SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET, SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER, SPELL_ATTR0_CU_SCHOOLMASK_NORMAL_WITH_MAGIC, SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_ATTR0_CU_SINGLE_AURA_STACK, SPELL_ATTR0_DO_NOT_DISPLAY, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR0_PASSIVE, SPELL_ATTR3_ALWAYS_HIT, SPELL_AURA_AOE_CHARM, SPELL_AURA_BIND_SIGHT, SPELL_AURA_CONTROL_VEHICLE, SPELL_AURA_CONVERT_RUNE, SPELL_AURA_DUMMY, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_CONFUSE, SPELL_AURA_MOD_FEAR, SPELL_AURA_MOD_INVISIBILITY, SPELL_AURA_MOD_INVISIBILITY_DETECT, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_AURA_MOD_RANGED_HASTE, SPELL_AURA_MOD_STUN, SPELL_AURA_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 ( )
2703{
2704 uint32 oldMSTime = getMSTime();
2705
2707 mSpellInfoMap.resize(sSpellStore.GetNumRows(), nullptr);
2708
2709 for (SpellEntry const* spellEntry : sSpellStore)
2710 mSpellInfoMap[spellEntry->Id] = new SpellInfo(spellEntry);
2711
2712 for (uint32 spellIndex = 0; spellIndex < GetSpellInfoStoreSize(); ++spellIndex)
2713 {
2714 if (!mSpellInfoMap[spellIndex])
2715 continue;
2716
2717 for (SpellEffectInfo const& spellEffectInfo : mSpellInfoMap[spellIndex]->GetEffects())
2718 {
2719 //ASSERT(effect.EffectIndex < MAX_SPELL_EFFECTS, "MAX_SPELL_EFFECTS must be at least {}", effect.EffectIndex + 1);
2720 ASSERT(spellEffectInfo.Effect < TOTAL_SPELL_EFFECTS, "TOTAL_SPELL_EFFECTS must be at least {}", spellEffectInfo.Effect + 1);
2721 ASSERT(spellEffectInfo.ApplyAuraName < TOTAL_AURAS, "TOTAL_AURAS must be at least {}", spellEffectInfo.ApplyAuraName + 1);
2722 ASSERT(spellEffectInfo.TargetA.GetTarget() < TOTAL_SPELL_TARGETS, "TOTAL_SPELL_TARGETS must be at least {}", spellEffectInfo.TargetA.GetTarget() + 1);
2723 ASSERT(spellEffectInfo.TargetB.GetTarget() < TOTAL_SPELL_TARGETS, "TOTAL_SPELL_TARGETS must be at least {}", spellEffectInfo.TargetB.GetTarget() + 1);
2724 }
2725 }
2726
2727 LOG_INFO("server.loading", ">> Loaded Spell Custom Attributes in {} ms", GetMSTimeDiffToNow(oldMSTime));
2728 LOG_INFO("server.loading", " ");
2729}
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
@ TOTAL_AURAS
Definition: SpellAuraDefines.h:380
@ TOTAL_SPELL_EFFECTS
Definition: SharedDefines.h:943
@ TOTAL_SPELL_TARGETS
Definition: SharedDefines.h:1514
Definition: DBCStructure.h:1640

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:896
@ SPELL_EFFECT_DUAL_WIELD
Definition: SharedDefines.h:818
@ SKILL_DUAL_WIELD
Definition: SharedDefines.h:2888
@ SKILL_RIDING
Definition: SharedDefines.h:2991
Definition: SpellMgr.h:574
uint16 value
Definition: SpellMgr.h:577
uint16 step
Definition: SpellMgr.h:576
uint16 maxvalue
Definition: SpellMgr.h:578
uint16 skill
Definition: SpellMgr.h:575

References SpellInfo::Effects, getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), GetSpellInfoStoreSize(), LOG_INFO, MAX_SPELL_EFFECTS, SpellLearnSkillNode::maxvalue, mSpellLearnSkills, SpellLearnSkillNode::skill, SKILL_DUAL_WIELD, SKILL_RIDING, SPELL_EFFECT_DUAL_WIELD, SPELL_EFFECT_SKILL, SpellLearnSkillNode::step, and SpellLearnSkillNode::value.

◆ LoadSpellLinked()

void SpellMgr::LoadSpellLinked ( )
2254{
2255 uint32 oldMSTime = getMSTime();
2256
2257 mSpellLinkedMap.clear(); // need for reload case
2258
2259 // 0 1 2
2260 QueryResult result = WorldDatabase.Query("SELECT spell_trigger, spell_effect, type FROM spell_linked_spell");
2261 if (!result)
2262 {
2263 LOG_WARN("server.loading", ">> Loaded 0 linked spells. DB table `spell_linked_spell` is empty.");
2264 LOG_INFO("server.loading", " ");
2265 return;
2266 }
2267
2268 uint32 count = 0;
2269 do
2270 {
2271 Field* fields = result->Fetch();
2272
2273 int32 trigger = fields[0].Get<int32>();
2274 int32 effect = fields[1].Get<int32>();
2275 int32 type = fields[2].Get<uint8>();
2276
2277 SpellInfo const* spellInfo = GetSpellInfo(std::abs(trigger));
2278 if (!spellInfo)
2279 {
2280 LOG_ERROR("sql.sql", "Spell {} listed in `spell_linked_spell` does not exist", std::abs(trigger));
2281 continue;
2282 }
2283 spellInfo = GetSpellInfo(std::abs(effect));
2284 if (!spellInfo)
2285 {
2286 LOG_ERROR("sql.sql", "Spell {} listed in `spell_linked_spell` does not exist", std::abs(effect));
2287 continue;
2288 }
2289
2290 if (type) //we will find a better way when more types are needed
2291 {
2292 if (trigger > 0)
2293 trigger += SPELL_LINKED_MAX_SPELLS * type;
2294 else
2295 trigger -= SPELL_LINKED_MAX_SPELLS * type;
2296 }
2297 mSpellLinkedMap[trigger].push_back(effect);
2298
2299 ++count;
2300 } while (result->NextRow());
2301
2302 LOG_INFO("server.loading", ">> Loaded {} Linked Spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2303 LOG_INFO("server.loading", " ");
2304}
#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:470

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

◆ LoadSpellProcEvents()

void SpellMgr::LoadSpellProcEvents ( )
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:2487
bool IsRanked() const
Definition: SpellInfo.cpp:2475
uint32 ProcFlags
Definition: SpellInfo.h:353
SpellInfo const * GetNextRankSpell() const
Definition: SpellInfo.cpp:2499
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:315
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:682
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 ( )
2791{
2792 uint32 oldMSTime = getMSTime();
2793
2794 SpellInfo* spellInfo = nullptr;
2795 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2796 {
2797 spellInfo = mSpellInfoMap[i];
2798 if (!spellInfo)
2799 continue;
2800 spellInfo->_spellSpecific = spellInfo->LoadSpellSpecific();
2801 spellInfo->_auraState = spellInfo->LoadAuraState();
2802 }
2803
2804 LOG_INFO("server.loading", ">> Loaded Spell Specific And Aura State in {} ms", GetMSTimeDiffToNow(oldMSTime));
2805 LOG_INFO("server.loading", " ");
2806}
SpellSpecificType LoadSpellSpecific() const
Definition: SpellInfo.cpp:2128
AuraStateType LoadAuraState() const
Definition: SpellInfo.cpp:2052
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:558
SpellInfo const * next
Definition: SpellMgr.h:556
uint8 rank
Definition: SpellMgr.h:559
SpellInfo const * first
Definition: SpellMgr.h:557
SpellInfo const * prev
Definition: SpellMgr.h:555
void UnloadSpellInfoChains()
Definition: SpellMgr.cpp: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:30
Definition: SpellMgr.h:396
float target_Z
Definition: SpellMgr.h:400
uint32 target_mapId
Definition: SpellMgr.h:397
float target_Y
Definition: SpellMgr.h:399
float target_Orientation
Definition: SpellMgr.h:401
float target_X
Definition: SpellMgr.h:398
Definition: DBCStructure.h:1323

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:385
int32 flatMod
Definition: SpellMgr.h:386
float apPctMod
Definition: SpellMgr.h:388
float pctMod
Definition: SpellMgr.h:387

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

◆ SetSpellDifficultyId()

void SpellMgr::SetSpellDifficultyId ( uint32  spellId,
uint32  id 
)
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 ( )
2782{
2783 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2784 {
2785 if (mSpellInfoMap[i])
2786 mSpellInfoMap[i]->_UnloadImplicitTargetConditionLists();
2787 }
2788}

References GetSpellInfoStoreSize(), and mSpellInfoMap.

◆ UnloadSpellInfoStore()

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

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