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

#include "SpellMgr.h"

Public Member Functions

CreatureImmunities const * GetCreatureImmunities (int32 creatureImmunitiesId) const
 
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
 
Acore::IteratorPair< SpellRequiredMap::const_iterator > 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
 
SpellSpellGroupMapBounds GetSpellSpellGroupMapBounds (uint32 spell_id) const
 
bool IsSpellMemberOfSpellGroup (uint32 spell_id, SpellGroup group_id) const
 
SpellGroupSpellMapBounds GetSpellGroupSpellMapBounds (SpellGroup group_id) const
 
void GetSetOfSpellsInSpellGroup (SpellGroup group_id, std::set< uint32 > &foundSpells) const
 
void GetSetOfSpellsInSpellGroup (SpellGroup group_id, std::set< uint32 > &foundSpells, std::set< SpellGroup > &usedGroups) const
 
bool AddSameEffectStackRuleSpellGroups (SpellInfo const *spellInfo, uint32 auraType, int32 amount, std::map< SpellGroup, int32 > &groups) const
 
SpellGroupStackRule CheckSpellGroupStackRules (SpellInfo const *spellInfo1, SpellInfo const *spellInfo2) const
 
SpellGroupStackRule GetSpellGroupStackRule (SpellGroup group_id) 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 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 LoadCreatureImmunities ()
 
void LoadSpellCooldownOverrides ()
 
void UnloadSpellInfoStore ()
 
void UnloadSpellInfoImplicitTargetConditionLists ()
 
void LoadSpellInfoCustomAttributes ()
 
void LoadSpellInfoImmunities ()
 
void LoadSpellInfoCorrections ()
 
void LoadSpellSpecificAndAuraState ()
 
void LoadSpellJumpDistances ()
 

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
 
SpellSpellGroupMap mSpellSpellGroup
 
SpellGroupSpellMap mSpellGroupSpell
 
SpellGroupStackMap mSpellGroupStack
 
SameEffectStackMap mSpellSameEffectStack
 
SpellProcMap mSpellProcMap
 
CreatureImmunitiesMap mCreatureImmunities
 
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
402{
403}

◆ ~SpellMgr()

SpellMgr::~SpellMgr ( )
private
406{
408}
void UnloadSpellInfoStore()
Definition SpellMgr.cpp:2976

References UnloadSpellInfoStore().

Member Function Documentation

◆ _GetSpellInfo()

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

References GetSpellInfoStoreSize(), and mSpellInfoMap.

Referenced by LoadSpellInfoCustomAttributes(), and LoadSpellJumpDistances().

◆ AddSameEffectStackRuleSpellGroups()

bool SpellMgr::AddSameEffectStackRuleSpellGroups ( SpellInfo const *  spellInfo,
uint32  auraType,
int32  amount,
std::map< SpellGroup, int32 > &  groups 
) const
748{
749 uint32 spellId = spellInfo->GetFirstRankSpell()->Id;
750 auto spellGroupBounds = GetSpellSpellGroupMapBounds(spellId);
751 // Find group with SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT if it belongs to one
752 for (auto itr = spellGroupBounds.first; itr != spellGroupBounds.second; ++itr)
753 {
754 SpellGroup group = itr->second;
755 auto found = mSpellSameEffectStack.find(group);
756 if (found != mSpellSameEffectStack.end())
757 {
758 // check auraTypes
759 if (!found->second.count(auraType))
760 continue;
761
762 // Put the highest amount in the map
763 auto groupItr = groups.find(group);
764 if (groupItr == groups.end())
765 groups.emplace(group, amount);
766 else
767 {
768 int32 curr_amount = groups[group];
769 // Take absolute value because this also counts for the highest negative aura
770 if (std::abs(curr_amount) < std::abs(amount))
771 groupItr->second = amount;
772 }
773 // return because a spell should be in only one SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT group per auraType
774 return true;
775 }
776 }
777 // Not in a SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT group, so return false
778 return false;
779}
std::int32_t int32
Definition Define.h:103
std::uint32_t uint32
Definition Define.h:107
SpellGroup
Definition SpellMgr.h:331
SameEffectStackMap mSpellSameEffectStack
Definition SpellMgr.h:813
SpellSpellGroupMapBounds GetSpellSpellGroupMapBounds(uint32 spell_id) const
Definition SpellMgr.cpp:698

References SpellInfo::GetFirstRankSpell(), GetSpellSpellGroupMapBounds(), SpellInfo::Id, and mSpellSameEffectStack.

◆ AssertSpellInfo()

SpellInfo const * SpellMgr::AssertSpellInfo ( uint32  spellId) const
inline
736 {
737 ASSERT(spellId < GetSpellInfoStoreSize());
738 SpellInfo const* spellInfo = mSpellInfoMap[spellId];
739 ASSERT(spellInfo);
740 return spellInfo;
741 }
#define ASSERT
Definition Errors.h:68
Definition SpellInfo.h:340

References ASSERT, GetSpellInfoStoreSize(), and mSpellInfoMap.

Referenced by LoadSpellGroupStackRules().

◆ CanSpellTriggerProcOnEvent()

bool SpellMgr::CanSpellTriggerProcOnEvent ( SpellProcEntry const &  procEntry,
ProcEventInfo eventInfo 
) const
846{
847 // proc type doesn't match
848 if (!(eventInfo.GetTypeMask() & procEntry.ProcFlags))
849 return false;
850
851 // check XP or honor target requirement
852 if (procEntry.AttributesMask & PROC_ATTR_REQ_EXP_OR_HONOR)
853 if (Player* actor = eventInfo.GetActor()->ToPlayer())
854 if (eventInfo.GetActionTarget() && !actor->isHonorOrXPTarget(eventInfo.GetActionTarget()))
855 return false;
856
857 // check mana cost requirement (used by Clearcasting and similar effects)
858 if (procEntry.AttributesMask & PROC_ATTR_REQ_MANA_COST)
859 {
860 SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
861 if (!spellInfo || (!spellInfo->ManaCost && !spellInfo->ManaCostPercentage))
862 return false;
863 }
864
865 // always trigger for these types
867 return true;
868
869 // check school mask (if set) for other trigger types
870 if (procEntry.SchoolMask && !(eventInfo.GetSchoolMask() & procEntry.SchoolMask))
871 return false;
872
873 // check spell family name/flags (if set) for spells
874 if (eventInfo.GetTypeMask() & SPELL_PROC_FLAG_MASK)
875 if (SpellInfo const* eventSpellInfo = eventInfo.GetSpellInfo())
876 if (!eventSpellInfo->IsAffected(procEntry.SpellFamilyName, procEntry.SpellFamilyMask))
877 return false;
878
879 // check spell type mask (if set)
881 {
882 if (procEntry.SpellTypeMask && !(eventInfo.GetSpellTypeMask() & procEntry.SpellTypeMask))
883 return false;
884 }
885
886 // check spell phase mask
888 {
889 if (!(eventInfo.GetSpellPhaseMask() & procEntry.SpellPhaseMask))
890 return false;
891 }
892
893 // check hit mask (on taken hit or on done hit)
894 // For CAST phase with DONE flags, only check if HitMask is explicitly set (crit is pre-calculated for travel time spells)
895 if ((eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK) ||
896 ((eventInfo.GetTypeMask() & DONE_HIT_PROC_FLAG_MASK) &&
897 (!(eventInfo.GetSpellPhaseMask() & PROC_SPELL_PHASE_CAST) || procEntry.HitMask)))
898 {
899 uint32 hitMask = procEntry.HitMask;
900 // get default values if hit mask not set
901 if (!hitMask)
902 {
903 // for taken procs allow normal + critical hits by default
904 if (eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK)
906 // for done procs allow normal + critical + absorbs by default
907 else
909 }
910 if (!(eventInfo.GetHitMask() & hitMask))
911 return false;
912 }
913
914 return true;
915}
@ PROC_HIT_ABSORB
Definition SpellMgr.h:267
@ PROC_HIT_CRITICAL
Definition SpellMgr.h:258
@ PROC_HIT_NORMAL
Definition SpellMgr.h:257
@ PROC_ATTR_REQ_MANA_COST
Definition SpellMgr.h:278
@ PROC_ATTR_REQ_EXP_OR_HONOR
Definition SpellMgr.h:276
@ PROC_SPELL_PHASE_CAST
Definition SpellMgr.h:248
@ TAKEN_HIT_PROC_FLAG_MASK
Definition SpellMgr.h:178
@ PERIODIC_PROC_FLAG_MASK
Definition SpellMgr.h:169
@ PROC_FLAG_KILLED
Definition SpellMgr.h:110
@ PROC_FLAG_DEATH
Definition SpellMgr.h:146
@ REQ_SPELL_PHASE_PROC_FLAG_MASK
Definition SpellMgr.h:184
@ PROC_FLAG_KILL
Definition SpellMgr.h:111
@ SPELL_PROC_FLAG_MASK
Definition SpellMgr.h:159
@ DONE_HIT_PROC_FLAG_MASK
Definition SpellMgr.h:171
Player * ToPlayer()
Definition Object.h:202
Definition Player.h:1084
uint32 GetHitMask() const
Definition Unit.h:465
SpellSchoolMask GetSchoolMask() const
Definition Unit.cpp:314
Unit * GetActionTarget() const
Definition Unit.h:460
uint32 GetSpellTypeMask() const
Definition Unit.h:463
uint32 GetTypeMask() const
Definition Unit.h:462
SpellInfo const * GetSpellInfo() const
Definition Unit.cpp:300
Unit * GetActor()
Definition Unit.h:459
uint32 GetSpellPhaseMask() const
Definition Unit.h:464
uint32 ManaCostPercentage
Definition SpellInfo.h:391
uint32 ManaCost
Definition SpellInfo.h:387

References SpellProcEntry::AttributesMask, DONE_HIT_PROC_FLAG_MASK, ProcEventInfo::GetActionTarget(), ProcEventInfo::GetActor(), ProcEventInfo::GetHitMask(), ProcEventInfo::GetSchoolMask(), ProcEventInfo::GetSpellInfo(), ProcEventInfo::GetSpellPhaseMask(), ProcEventInfo::GetSpellTypeMask(), ProcEventInfo::GetTypeMask(), SpellProcEntry::HitMask, SpellInfo::ManaCost, SpellInfo::ManaCostPercentage, PERIODIC_PROC_FLAG_MASK, PROC_ATTR_REQ_EXP_OR_HONOR, PROC_ATTR_REQ_MANA_COST, PROC_FLAG_DEATH, 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, SpellProcEntry::SpellFamilyMask, SpellProcEntry::SpellFamilyName, SpellProcEntry::SpellPhaseMask, SpellProcEntry::SpellTypeMask, TAKEN_HIT_PROC_FLAG_MASK, and Object::ToPlayer().

◆ CheckSpellGroupStackRules()

SpellGroupStackRule SpellMgr::CheckSpellGroupStackRules ( SpellInfo const *  spellInfo1,
SpellInfo const *  spellInfo2 
) const
782{
783 ASSERT(spellInfo1);
784 ASSERT(spellInfo2);
785
786 uint32 spell_id1 = spellInfo1->GetFirstRankSpell()->Id;
787 uint32 spell_id2 = spellInfo2->GetFirstRankSpell()->Id;
788
789 // find SpellGroups which are common for both spells
791 std::set<SpellGroup> groups;
792 for (SpellSpellGroupMap::const_iterator itr = spellGroup1.first; itr != spellGroup1.second; ++itr)
793 {
794 if (IsSpellMemberOfSpellGroup(spell_id2, itr->second))
795 {
796 bool add = true;
798 for (SpellGroupSpellMap::const_iterator itr2 = groupSpell.first; itr2 != groupSpell.second; ++itr2)
799 {
800 if (itr2->second < 0)
801 {
802 SpellGroup currGroup = (SpellGroup)abs(itr2->second);
803 if (IsSpellMemberOfSpellGroup(spell_id1, currGroup) && IsSpellMemberOfSpellGroup(spell_id2, currGroup))
804 {
805 add = false;
806 break;
807 }
808 }
809 }
810 if (add)
811 groups.insert(itr->second);
812 }
813 }
814
816
817 for (std::set<SpellGroup>::iterator itr = groups.begin(); itr!= groups.end(); ++itr)
818 {
819 SpellGroupStackMap::const_iterator found = mSpellGroupStack.find(*itr);
820 if (found != mSpellGroupStack.end())
821 rule = found->second;
822 if (rule)
823 break;
824 }
825 return rule;
826}
std::pair< SpellSpellGroupMap::const_iterator, SpellSpellGroupMap::const_iterator > SpellSpellGroupMapBounds
Definition SpellMgr.h:354
SpellGroupStackRule
Definition SpellMgr.h:361
@ SPELL_GROUP_STACK_RULE_DEFAULT
Definition SpellMgr.h:362
std::pair< SpellGroupSpellMap::const_iterator, SpellGroupSpellMap::const_iterator > SpellGroupSpellMapBounds
Definition SpellMgr.h:358
SpellGroupSpellMapBounds GetSpellGroupSpellMapBounds(SpellGroup group_id) const
Definition SpellMgr.cpp:715
bool IsSpellMemberOfSpellGroup(uint32 spell_id, SpellGroup group_id) const
Definition SpellMgr.cpp:704
SpellGroupStackMap mSpellGroupStack
Definition SpellMgr.h:812

References ASSERT, SpellInfo::GetFirstRankSpell(), GetSpellGroupSpellMapBounds(), GetSpellSpellGroupMapBounds(), SpellInfo::Id, IsSpellMemberOfSpellGroup(), mSpellGroupStack, and SPELL_GROUP_STACK_RULE_DEFAULT.

◆ CheckSpellInfo()

SpellInfo const * SpellMgr::CheckSpellInfo ( uint32  spellId) const
inline
744 {
745 if (spellId >= GetSpellInfoStoreSize())
746 {
747 LOG_ERROR("server", "spellId {} is not lower than GetSpellInfoStoreSize() ({})", spellId, GetSpellInfoStoreSize());
748 return nullptr;
749 }
750 SpellInfo const* spellInfo = mSpellInfoMap[spellId];
751 if (!spellInfo)
752 {
753 LOG_ERROR("server", "spellId {} has invalid spellInfo", spellId);
754 return nullptr;
755 }
756 return spellInfo;
757 }
#define LOG_ERROR(filterType__,...)
Definition Log.h:145

References GetSpellInfoStoreSize(), LOG_ERROR, and mSpellInfoMap.

◆ CheckSpellValid()

bool SpellMgr::CheckSpellValid ( SpellInfo const *  spellInfo,
uint32  spellId,
bool  isTalent 
)
static
507{
508 if (!spellInfo)
509 {
511 LOG_ERROR("spells", "Player::{}: Non-existed in SpellStore spell #{} request.", (isTalent ? "AddTalent" : "addSpell"), spellId);
512 return false;
513 }
514
515 if (!IsSpellValid(spellInfo))
516 {
518 LOG_ERROR("spells", "Player::{}: Broken spell #{} learning not allowed.", (isTalent ? "AddTalent" : "addSpell"), spellId);
519 return false;
520 }
521
522 return true;
523}
void DeleteSpellFromAllPlayers(uint32 spellId)
Definition SpellMgr.cpp:495
static bool IsSpellValid(SpellInfo const *spellInfo)
Definition SpellMgr.cpp:488

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.

418{
419 // not exist
420 if (!spellInfo)
421 return false;
422
423 bool need_check_reagents = false;
424
425 // check effects
426 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
427 {
428 switch (spellInfo->Effects[i].Effect)
429 {
430 case 0:
431 continue;
432
433 // craft spell for crafting non-existed item (break client recipes list show)
436 {
437 if (spellInfo->Effects[i].ItemType == 0)
438 {
439 // skip auto-loot crafting spells, its not need explicit item info (but have special fake items sometime)
440 if (!spellInfo->IsLootCrafting())
441 {
442 if (msg)
443 LOG_ERROR("sql.sql", "Craft spell {} not have create item entry.", spellInfo->Id);
444 return false;
445 }
446 }
447 // also possible IsLootCrafting case but fake item must exist anyway
448 else if (!sObjectMgr->GetItemTemplate(spellInfo->Effects[i].ItemType))
449 {
450 if (msg)
451 LOG_ERROR("sql.sql", "Craft spell {} create not-exist in DB item (Entry: {}) and then...", spellInfo->Id, spellInfo->Effects[i].ItemType);
452 return false;
453 }
454
455 need_check_reagents = true;
456 break;
457 }
459 {
460 SpellInfo const* spellInfo2 = sSpellMgr->GetSpellInfo(spellInfo->Effects[i].TriggerSpell);
461 if (!ComputeIsSpellValid(spellInfo2, msg))
462 {
463 if (msg)
464 LOG_ERROR("sql.sql", "Spell {} learn to invalid spell {}, and then...", spellInfo->Id, spellInfo->Effects[i].TriggerSpell);
465 return false;
466 }
467 break;
468 }
469 }
470 }
471
472 if (need_check_reagents)
473 {
474 for (uint8 j = 0; j < MAX_SPELL_REAGENTS; ++j)
475 {
476 if (spellInfo->Reagent[j] > 0 && !sObjectMgr->GetItemTemplate(spellInfo->Reagent[j]))
477 {
478 if (msg)
479 LOG_ERROR("sql.sql", "Craft spell {} have not-exist reagent in DB item (Entry: {}) and then...", spellInfo->Id, spellInfo->Reagent[j]);
480 return false;
481 }
482 }
483 }
484
485 return true;
486}
#define MAX_SPELL_REAGENTS
Definition DBCStructure.h:1639
#define MAX_SPELL_EFFECTS
Definition DBCStructure.h:1637
std::uint8_t uint8
Definition Define.h:109
#define sObjectMgr
Definition ObjectMgr.h:1723
@ SPELL_EFFECT_CREATE_ITEM_2
Definition SharedDefines.h:923
@ SPELL_EFFECT_LEARN_SPELL
Definition SharedDefines.h:802
@ SPELL_EFFECT_CREATE_ITEM
Definition SharedDefines.h:790
#define sSpellMgr
Definition SpellMgr.h:836
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:417

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 ComputeIsSpellValid(), ObjectMgr::InitializeSpellInfoPrecomputedData(), and ObjectMgr::LoadQuests().

◆ GetCreatureImmunities()

CreatureImmunities const * SpellMgr::GetCreatureImmunities ( int32  creatureImmunitiesId) const
59{
60 return Acore::Containers::MapGetValuePtr(mCreatureImmunities, creatureImmunitiesId);
61}
CreatureImmunitiesMap mCreatureImmunities
Definition SpellMgr.h:815
auto MapGetValuePtr(M &map, typename M::key_type const &key) -> decltype(AddressOrSelf(map.find(key) ->second))
Definition Containers.h:216

References Acore::Containers::MapGetValuePtr(), and mCreatureImmunities.

◆ GetFirstSpellInChain()

uint32 SpellMgr::GetFirstSpellInChain ( uint32  spell_id) const
602{
603 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
604 return node->first->Id;
605
606 return spell_id;
607}
SpellChainNode const * GetSpellChainNode(uint32 spell_id) const
Definition SpellMgr.cpp:592
Definition SpellMgr.h:544

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

Referenced by GetSpellBonusData(), GetSpellSpellGroupMapBounds(), GetSpellThreatEntry(), and LoadSpellRequired().

◆ GetLastSpellInChain()

uint32 SpellMgr::GetLastSpellInChain ( uint32  spell_id) const
610{
611 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
612 return node->last->Id;
613
614 return spell_id;
615}

References GetSpellChainNode().

◆ GetNextSpellInChain()

uint32 SpellMgr::GetNextSpellInChain ( uint32  spell_id) const
618{
619 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
620 if (node->next)
621 return node->next->Id;
622
623 return 0;
624}

References GetSpellChainNode().

◆ GetPetAura()

PetAura const * SpellMgr::GetPetAura ( uint32  spell_id,
uint8  eff 
) const
963{
964 SpellPetAuraMap::const_iterator itr = mSpellPetAuraMap.find((spell_id << 8) + eff);
965 if (itr != mSpellPetAuraMap.end())
966 return &itr->second;
967 else
968 return nullptr;
969}
SpellPetAuraMap mSpellPetAuraMap
Definition SpellMgr.h:819

References mSpellPetAuraMap.

◆ GetPetDefaultSpellsEntry()

PetDefaultSpellsEntry const * SpellMgr::GetPetDefaultSpellsEntry ( int32  id) const
1000{
1001 PetDefaultSpellsMap::const_iterator itr = mPetDefaultSpellsMap.find(id);
1002 if (itr != mPetDefaultSpellsMap.end())
1003 return &itr->second;
1004 return nullptr;
1005}
PetDefaultSpellsMap mPetDefaultSpellsMap
Definition SpellMgr.h:830

References mPetDefaultSpellsMap.

◆ GetPetLevelupSpellList()

PetLevelupSpellSet const * SpellMgr::GetPetLevelupSpellList ( uint32  petFamily) const
991{
992 PetLevelupSpellMap::const_iterator itr = mPetLevelupSpellMap.find(petFamily);
993 if (itr != mPetLevelupSpellMap.end())
994 return &itr->second;
995 else
996 return nullptr;
997}
PetLevelupSpellMap mPetLevelupSpellMap
Definition SpellMgr.h:829

References mPetLevelupSpellMap.

◆ GetPrevSpellInChain()

uint32 SpellMgr::GetPrevSpellInChain ( uint32  spell_id) const
627{
628 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
629 if (node->prev)
630 return node->prev->Id;
631
632 return 0;
633}

References GetSpellChainNode().

◆ GetSetOfSpellsInSpellGroup() [1/2]

void SpellMgr::GetSetOfSpellsInSpellGroup ( SpellGroup  group_id,
std::set< uint32 > &  foundSpells 
) const
721{
722 std::set<SpellGroup> usedGroups;
723 GetSetOfSpellsInSpellGroup(group_id, foundSpells, usedGroups);
724}
void GetSetOfSpellsInSpellGroup(SpellGroup group_id, std::set< uint32 > &foundSpells) const
Definition SpellMgr.cpp:720

References GetSetOfSpellsInSpellGroup().

Referenced by GetSetOfSpellsInSpellGroup(), GetSetOfSpellsInSpellGroup(), LoadSpellGroups(), and LoadSpellGroupStackRules().

◆ GetSetOfSpellsInSpellGroup() [2/2]

void SpellMgr::GetSetOfSpellsInSpellGroup ( SpellGroup  group_id,
std::set< uint32 > &  foundSpells,
std::set< SpellGroup > &  usedGroups 
) const
727{
728 if (usedGroups.find(group_id) != usedGroups.end())
729 return;
730 usedGroups.insert(group_id);
731
733 for (SpellGroupSpellMap::const_iterator itr = groupSpell.first; itr != groupSpell.second; ++itr)
734 {
735 if (itr->second < 0)
736 {
737 SpellGroup currGroup = (SpellGroup)abs(itr->second);
738 GetSetOfSpellsInSpellGroup(currGroup, foundSpells, usedGroups);
739 }
740 else
741 {
742 foundSpells.insert(itr->second);
743 }
744 }
745}

References GetSetOfSpellsInSpellGroup(), and GetSpellGroupSpellMapBounds().

◆ GetSkillLineAbilityMapBounds()

SkillLineAbilityMapBounds SpellMgr::GetSkillLineAbilityMapBounds ( uint32  spell_id) const
958{
959 return mSkillLineAbilityMap.equal_range(spell_id);
960}
SkillLineAbilityMap mSkillLineAbilityMap
Definition SpellMgr.h:828

References mSkillLineAbilityMap.

◆ GetSpellAreaForAreaMapBounds()

SpellAreaForAreaMapBounds SpellMgr::GetSpellAreaForAreaMapBounds ( uint32  area_id) const
1028{
1029 return mSpellAreaForAreaMap.equal_range(area_id);
1030}
SpellAreaForAreaMap mSpellAreaForAreaMap
Definition SpellMgr.h:827

References mSpellAreaForAreaMap.

◆ GetSpellAreaForAuraMapBounds()

SpellAreaForAuraMapBounds SpellMgr::GetSpellAreaForAuraMapBounds ( uint32  spell_id) const
1023{
1024 return mSpellAreaForAuraMap.equal_range(spell_id);
1025}
SpellAreaForAuraMap mSpellAreaForAuraMap
Definition SpellMgr.h:826

References mSpellAreaForAuraMap.

Referenced by LoadSpellAreas().

◆ GetSpellAreaForQuestEndMapBounds()

SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestEndMapBounds ( uint32  quest_id) const
1018{
1019 return mSpellAreaForQuestEndMap.equal_range(quest_id);
1020}
SpellAreaForQuestMap mSpellAreaForQuestEndMap
Definition SpellMgr.h:825

References mSpellAreaForQuestEndMap.

◆ GetSpellAreaForQuestMapBounds()

SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestMapBounds ( uint32  quest_id) const
1013{
1014 return mSpellAreaForQuestMap.equal_range(quest_id);
1015}
SpellAreaForQuestMap mSpellAreaForQuestMap
Definition SpellMgr.h:824

References mSpellAreaForQuestMap.

◆ GetSpellAreaMapBounds()

SpellAreaMapBounds SpellMgr::GetSpellAreaMapBounds ( uint32  spell_id) const
1008{
1009 return mSpellAreaMap.equal_range(spell_id);
1010}
SpellAreaMap mSpellAreaMap
Definition SpellMgr.h:823

References mSpellAreaMap.

Referenced by LoadSpellAreas().

◆ GetSpellBonusData()

SpellBonusEntry const * SpellMgr::GetSpellBonusData ( uint32  spellId) const
918{
919 // Lookup data
920 SpellBonusMap::const_iterator itr = mSpellBonusMap.find(spellId);
921 if (itr != mSpellBonusMap.end())
922 return &itr->second;
923 // Not found, try lookup for 1 spell rank if exist
924 if (uint32 rank_1 = GetFirstSpellInChain(spellId))
925 {
926 SpellBonusMap::const_iterator itr2 = mSpellBonusMap.find(rank_1);
927 if (itr2 != mSpellBonusMap.end())
928 return &itr2->second;
929 }
930 return nullptr;
931}
uint32 GetFirstSpellInChain(uint32 spell_id) const
Definition SpellMgr.cpp:601
SpellBonusMap mSpellBonusMap
Definition SpellMgr.h:816

References GetFirstSpellInChain(), and mSpellBonusMap.

◆ GetSpellChainNode()

SpellChainNode const * SpellMgr::GetSpellChainNode ( uint32  spell_id) const
593{
594 SpellChainMap::const_iterator itr = mSpellChains.find(spell_id);
595 if (itr == mSpellChains.end())
596 return nullptr;
597
598 return &itr->second;
599}
SpellChainMap mSpellChains
Definition SpellMgr.h:805

References mSpellChains.

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

◆ GetSpellCooldownOverride()

SpellCooldownOverride SpellMgr::GetSpellCooldownOverride ( uint32  spellId) const
2971{
2972 auto range = mSpellCooldownOverrideMap.find(spellId);
2973 return range->second;
2974}
SpellCooldownOverrideMap mSpellCooldownOverrideMap
Definition SpellMgr.h:832

References mSpellCooldownOverrideMap.

Referenced by LoadSpellInfoCustomAttributes().

◆ GetSpellDifficultyId()

uint32 SpellMgr::GetSpellDifficultyId ( uint32  spellId) const
526{
527 SpellDifficultySearcherMap::const_iterator i = mSpellDifficultySearcherMap.find(spellId);
528 return i == mSpellDifficultySearcherMap.end() ? 0 : (*i).second;
529}
SpellDifficultySearcherMap mSpellDifficultySearcherMap
Definition SpellMgr.h:804

References mSpellDifficultySearcherMap.

Referenced by GetSpellIdForDifficulty().

◆ GetSpellEnchantProcEvent()

SpellEnchantProcEntry const * SpellMgr::GetSpellEnchantProcEvent ( uint32  enchId) const
972{
973 SpellEnchantProcEventMap::const_iterator itr = mSpellEnchantProcEventMap.find(enchId);
974 if (itr != mSpellEnchantProcEventMap.end())
975 return &itr->second;
976 return nullptr;
977}
SpellEnchantProcEventMap mSpellEnchantProcEventMap
Definition SpellMgr.h:821

References mSpellEnchantProcEventMap.

◆ GetSpellForDifficultyFromSpell()

SpellInfo const * SpellMgr::GetSpellForDifficultyFromSpell ( SpellInfo const *  spell,
Unit const *  caster 
) const
579{
580 uint32 newSpellId = GetSpellIdForDifficulty(spell->Id, caster);
581 SpellInfo const* newSpell = GetSpellInfo(newSpellId);
582 if (!newSpell)
583 {
584 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellForDifficultyFromSpell: spell {} not found. Check spelldifficulty_dbc!", newSpellId);
585 return spell;
586 }
587
588 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellForDifficultyFromSpell: Spell id for instance mode is {} (original {})", newSpell->Id, spell->Id);
589 return newSpell;
590}
#define LOG_DEBUG(filterType__,...)
Definition Log.h:157
uint32 Id
Definition SpellInfo.h:344
uint32 GetSpellIdForDifficulty(uint32 spellId, Unit const *caster) const
Definition SpellMgr.cpp:536
SpellInfo const * GetSpellInfo(uint32 spellId) const
Definition SpellMgr.h:733

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

◆ GetSpellGroupSpellMapBounds()

SpellGroupSpellMapBounds SpellMgr::GetSpellGroupSpellMapBounds ( SpellGroup  group_id) const
716{
717 return mSpellGroupSpell.equal_range(group_id);
718}
SpellGroupSpellMap mSpellGroupSpell
Definition SpellMgr.h:811

References mSpellGroupSpell.

Referenced by CheckSpellGroupStackRules(), GetSetOfSpellsInSpellGroup(), and LoadSpellGroupStackRules().

◆ GetSpellGroupStackRule()

SpellGroupStackRule SpellMgr::GetSpellGroupStackRule ( SpellGroup  group_id) const
829{
830 SpellGroupStackMap::const_iterator itr = mSpellGroupStack.find(group);
831 if (itr != mSpellGroupStack.end())
832 return itr->second;
833
835}

References mSpellGroupStack, and SPELL_GROUP_STACK_RULE_DEFAULT.

◆ GetSpellIdForDifficulty()

uint32 SpellMgr::GetSpellIdForDifficulty ( uint32  spellId,
Unit const *  caster 
) const
537{
538 if (!GetSpellInfo(spellId))
539 return spellId;
540
541 if (!caster || !caster->GetMap() || (!caster->GetMap()->IsDungeon() && !caster->GetMap()->IsBattleground()))
542 return spellId;
543
544 uint32 mode = uint32(caster->GetMap()->GetSpawnMode());
545 if (mode >= MAX_DIFFICULTY)
546 {
547 LOG_ERROR("spells", "SpellMgr::GetSpellIdForDifficulty: Incorrect Difficulty for spell {}.", spellId);
548 return spellId; //return source spell
549 }
550
551 uint32 difficultyId = GetSpellDifficultyId(spellId);
552 if (!difficultyId)
553 return spellId; //return source spell, it has only REGULAR_DIFFICULTY
554
555 SpellDifficultyEntry const* difficultyEntry = sSpellDifficultyStore.LookupEntry(difficultyId);
556 if (!difficultyEntry)
557 {
558 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellIdForDifficulty: SpellDifficultyEntry not found for spell {}. This should never happen.", spellId);
559 return spellId; //return source spell
560 }
561
562 if (difficultyEntry->SpellID[mode] <= 0 && mode > DUNGEON_DIFFICULTY_HEROIC)
563 {
564 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellIdForDifficulty: spell {} mode {} spell is nullptr, using mode {}", spellId, mode, mode - 2);
565 mode -= 2;
566 }
567
568 if (difficultyEntry->SpellID[mode] <= 0)
569 {
570 LOG_ERROR("sql.sql", "SpellMgr::GetSpellIdForDifficulty: spell {} mode {} spell is 0. Check spelldifficulty_dbc!", spellId, mode);
571 return spellId;
572 }
573
574 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellIdForDifficulty: spellid for spell {} in mode {} is {}", spellId, mode, difficultyEntry->SpellID[mode]);
575 return uint32(difficultyEntry->SpellID[mode]);
576}
@ DUNGEON_DIFFICULTY_HEROIC
Definition DBCEnums.h:270
#define MAX_DIFFICULTY
Definition DBCEnums.h:283
DBCStorage< SpellDifficultyEntry > sSpellDifficultyStore(SpellDifficultyfmt)
uint32 GetSpellDifficultyId(uint32 spellId) const
Definition SpellMgr.cpp:525
Definition DBCStructure.h:1772
int32 SpellID[MAX_DIFFICULTY]
Definition DBCStructure.h:1774

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

Referenced by GetSpellForDifficultyFromSpell().

◆ GetSpellInfo()

◆ GetSpellInfoStoreSize()

◆ GetSpellLearnSkill()

SpellLearnSkillNode const * SpellMgr::GetSpellLearnSkill ( uint32  spell_id) const
682{
683 SpellLearnSkillMap::const_iterator itr = mSpellLearnSkills.find(spell_id);
684 if (itr != mSpellLearnSkills.end())
685 return &itr->second;
686 else
687 return nullptr;
688}
SpellLearnSkillMap mSpellLearnSkills
Definition SpellMgr.h:808

References mSpellLearnSkills.

◆ GetSpellLinked()

const std::vector< int32 > * SpellMgr::GetSpellLinked ( int32  spell_id) const
985{
986 SpellLinkedMap::const_iterator itr = mSpellLinkedMap.find(spell_id);
987 return itr != mSpellLinkedMap.end() ? &(itr->second) : nullptr;
988}
SpellLinkedMap mSpellLinkedMap
Definition SpellMgr.h:820

References mSpellLinkedMap.

◆ GetSpellMixologyBonus()

float SpellMgr::GetSpellMixologyBonus ( uint32  spellId) const
949{
950 SpellMixologyMap::const_iterator itr = mSpellMixologyMap.find(spellId);
951 if (itr == mSpellMixologyMap.end())
952 return 30.0f;
953
954 return itr->second;
955}
SpellMixologyMap mSpellMixologyMap
Definition SpellMgr.h:818

References mSpellMixologyMap.

◆ GetSpellProcEntry()

SpellProcEntry const * SpellMgr::GetSpellProcEntry ( uint32  spellId) const
838{
839 SpellProcMap::const_iterator itr = mSpellProcMap.find(spellId);
840 if (itr != mSpellProcMap.end())
841 return &itr->second;
842 return nullptr;
843}
SpellProcMap mSpellProcMap
Definition SpellMgr.h:814

References mSpellProcMap.

◆ GetSpellRank()

uint8 SpellMgr::GetSpellRank ( uint32  spell_id) const
636{
637 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
638 return node->rank;
639
640 return 0;
641}

References GetSpellChainNode().

◆ GetSpellSpellGroupMapBounds()

SpellSpellGroupMapBounds SpellMgr::GetSpellSpellGroupMapBounds ( uint32  spell_id) const
699{
700 spell_id = GetFirstSpellInChain(spell_id);
701 return mSpellSpellGroup.equal_range(spell_id);
702}
SpellSpellGroupMap mSpellSpellGroup
Definition SpellMgr.h:810

References GetFirstSpellInChain(), and mSpellSpellGroup.

Referenced by AddSameEffectStackRuleSpellGroups(), CheckSpellGroupStackRules(), and IsSpellMemberOfSpellGroup().

◆ GetSpellsRequiredForSpellBounds()

Acore::IteratorPair< SpellRequiredMap::const_iterator > SpellMgr::GetSpellsRequiredForSpellBounds ( uint32  spell_id) const
656{
658}
SpellRequiredMap mSpellReq
Definition SpellMgr.h:807
auto MapEqualRange(M &map, typename M::key_type const &key) -> IteratorPair< decltype(map.begin())>
Definition IteratorPair.h:48

References Acore::Containers::MapEqualRange(), and mSpellReq.

◆ GetSpellsRequiringSpellBounds()

SpellsRequiringSpellMapBounds SpellMgr::GetSpellsRequiringSpellBounds ( uint32  spell_id) const
661{
662 return mSpellsReqSpell.equal_range(spell_id);
663}
SpellsRequiringSpellMap mSpellsReqSpell
Definition SpellMgr.h:806

References mSpellsReqSpell.

Referenced by IsSpellRequiringSpell().

◆ GetSpellTargetPosition()

SpellTargetPosition const * SpellMgr::GetSpellTargetPosition ( uint32  spell_id,
SpellEffIndex  effIndex 
) const
691{
692 SpellTargetPositionMap::const_iterator itr = mSpellTargetPositions.find(std::make_pair(spell_id, effIndex));
693 if (itr != mSpellTargetPositions.end())
694 return &itr->second;
695 return nullptr;
696}
SpellTargetPositionMap mSpellTargetPositions
Definition SpellMgr.h:809

References mSpellTargetPositions.

◆ GetSpellThreatEntry()

SpellThreatEntry const * SpellMgr::GetSpellThreatEntry ( uint32  spellID) const
934{
935 SpellThreatMap::const_iterator itr = mSpellThreatMap.find(spellID);
936 if (itr != mSpellThreatMap.end())
937 return &itr->second;
938 else
939 {
940 uint32 firstSpell = GetFirstSpellInChain(spellID);
941 itr = mSpellThreatMap.find(firstSpell);
942 if (itr != mSpellThreatMap.end())
943 return &itr->second;
944 }
945 return nullptr;
946}
SpellThreatMap mSpellThreatMap
Definition SpellMgr.h:817

References GetFirstSpellInChain(), and mSpellThreatMap.

◆ GetSpellWithRank()

uint32 SpellMgr::GetSpellWithRank ( uint32  spell_id,
uint32  rank,
bool  strict = false 
) const
644{
645 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
646 {
647 if (rank != node->rank)
648 return GetSpellWithRank(node->rank < rank ? node->next->Id : node->prev->Id, rank, strict);
649 }
650 else if (strict && rank > 1)
651 return 0;
652 return spell_id;
653}
uint32 GetSpellWithRank(uint32 spell_id, uint32 rank, bool strict=false) const
Definition SpellMgr.cpp:643

References GetSpellChainNode(), and GetSpellWithRank().

Referenced by GetSpellWithRank().

◆ HasSpellCooldownOverride()

bool SpellMgr::HasSpellCooldownOverride ( uint32  spellId) const
2966{
2967 return mSpellCooldownOverrideMap.find(spellId) != mSpellCooldownOverrideMap.end();
2968}

References mSpellCooldownOverrideMap.

Referenced by LoadSpellInfoCustomAttributes().

◆ instance()

SpellMgr * SpellMgr::instance ( )
static
411{
412 static SpellMgr instance;
413 return &instance;
414}
Definition SpellMgr.h:642
static SpellMgr * instance()
Definition SpellMgr.cpp:410

References instance().

Referenced by instance().

◆ IsAdditionalTalentSpell()

bool SpellMgr::IsAdditionalTalentSpell ( uint32  spellId) const
677{
678 return mTalentSpellAdditionalSet.find(spellId) != mTalentSpellAdditionalSet.end();
679}
TalentAdditionalSet mTalentSpellAdditionalSet
Definition SpellMgr.h:833

References mTalentSpellAdditionalSet.

◆ IsArenaAllowedEnchancment()

bool SpellMgr::IsArenaAllowedEnchancment ( uint32  ench_id) const
980{
981 return mEnchantCustomAttr[ench_id];
982}
EnchantCustomAttribute mEnchantCustomAttr
Definition SpellMgr.h:822

References mEnchantCustomAttr.

◆ IsSpellMemberOfSpellGroup()

bool SpellMgr::IsSpellMemberOfSpellGroup ( uint32  spell_id,
SpellGroup  group_id 
) const
705{
707 for (SpellSpellGroupMap::const_iterator itr = spellGroup.first; itr != spellGroup.second; ++itr)
708 {
709 if (itr->second == group_id)
710 return true;
711 }
712 return false;
713}

References GetSpellSpellGroupMapBounds().

Referenced by CheckSpellGroupStackRules().

◆ IsSpellRequiringSpell()

bool SpellMgr::IsSpellRequiringSpell ( uint32  spellid,
uint32  req_spellid 
) const
666{
667 SpellsRequiringSpellMapBounds spellsRequiringSpell = GetSpellsRequiringSpellBounds(req_spellid);
668 for (SpellsRequiringSpellMap::const_iterator itr = spellsRequiringSpell.first; itr != spellsRequiringSpell.second; ++itr)
669 {
670 if (itr->second == spellid)
671 return true;
672 }
673 return false;
674}
std::pair< SpellsRequiringSpellMap::const_iterator, SpellsRequiringSpellMap::const_iterator > SpellsRequiringSpellMapBounds
Definition SpellMgr.h:560
SpellsRequiringSpellMapBounds GetSpellsRequiringSpellBounds(uint32 spell_id) const
Definition SpellMgr.cpp:660

References GetSpellsRequiringSpellBounds().

Referenced by LoadSpellRequired().

◆ IsSpellValid()

◆ LoadCreatureImmunities()

void SpellMgr::LoadCreatureImmunities ( )
64{
65 mCreatureImmunities.clear();
66 if (QueryResult result = WorldDatabase.Query("SELECT ID, SchoolMask, DispelTypeMask, MechanicsMask, Effects, Auras, ImmuneAoE, ImmuneChain FROM creature_immunities"))
67 {
68 do
69 {
70 Field* fields = result->Fetch();
71 int32 id = fields[0].Get<int32>();
72 uint8 school = fields[1].Get<uint8>();
73 uint16 dispelType = fields[2].Get<uint16>();
74 uint64 mechanics = fields[3].Get<uint64>();
76 immunities.School = school;
77 immunities.DispelType = dispelType;
78 immunities.Mechanic = mechanics;
79 immunities.ImmuneAoE = fields[6].Get<bool>();
80 immunities.ImmuneChain = fields[7].Get<bool>();
81 {
82 std::string effects = fields[4].Get<std::string>();
83 for (std::string_view token : Acore::Tokenize(effects, ',', false))
84 {
85 if (Optional<uint32> val = Acore::StringTo<uint32>(token); val && *val < uint32(TOTAL_SPELL_EFFECTS))
86 immunities.Effect.push_back(SpellEffects(*val));
87 else
88 LOG_ERROR("sql.sql", "Invalid effect type in `Effects` {} for creature immunities {}, skipped", token, id);
89 }
90 }
91 {
92 std::string auras = fields[5].Get<std::string>();
93 for (std::string_view token : Acore::Tokenize(auras, ',', false))
94 {
95 if (Optional<uint32> val = Acore::StringTo<uint32>(token); val && *val < TOTAL_AURAS)
96 immunities.Aura.push_back(AuraType(*val));
97 else
98 LOG_ERROR("sql.sql", "Invalid aura type in `Auras` {} for creature immunities {}, skipped", token, id);
99 }
100 }
101 } while (result->NextRow());
102 }
103}
std::shared_ptr< ResultSet > QueryResult
Definition DatabaseEnvFwd.h:27
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
Definition DatabaseEnv.cpp:20
std::uint64_t uint64
Definition Define.h:106
std::uint16_t uint16
Definition Define.h:108
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:24
SpellEffects
Definition SharedDefines.h:766
@ TOTAL_SPELL_EFFECTS
Definition SharedDefines.h:931
AuraType
Definition SpellAuraDefines.h:62
@ TOTAL_AURAS
Definition SpellAuraDefines.h:380
Class used to access individual fields of database query result.
Definition Field.h:98
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition Field.h:112
Definition AsioHacksFwd.h:47
std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition Tokenize.cpp:20
Definition SpellMgr.h:564
std::bitset< MAX_SPELL_SCHOOL > School
Definition SpellMgr.h:565

References Field::Get(), LOG_ERROR, mCreatureImmunities, CreatureImmunities::School, Acore::Tokenize(), TOTAL_AURAS, TOTAL_SPELL_EFFECTS, and WorldDatabase.

Referenced by LoadSpellInfoStore().

◆ LoadEnchantCustomAttr()

void SpellMgr::LoadEnchantCustomAttr ( )
Todo:
: find a better check
2380{
2381 uint32 oldMSTime = getMSTime();
2382
2383 uint32 size = sSpellItemEnchantmentStore.GetNumRows();
2384 mEnchantCustomAttr.resize(size);
2385
2386 for (uint32 i = 0; i < size; ++i)
2387 mEnchantCustomAttr[i] = 0;
2388
2389 uint32 count = 0;
2390 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2391 {
2392 SpellInfo const* spellInfo = GetSpellInfo(i);
2393 if (!spellInfo)
2394 continue;
2395
2397 // Xinef: commented second part, fixes warlock enchants like firestone, spellstone
2398 if (!spellInfo->HasAttribute(SPELL_ATTR2_ENCHANT_OWN_ITEM_ONLY)/* || !spellInfo->HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFTED)*/)
2399 continue;
2400
2401 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
2402 {
2403 if (spellInfo->Effects[j].Effect == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY)
2404 {
2405 uint32 enchId = spellInfo->Effects[j].MiscValue;
2406 SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchId);
2407 if (!ench)
2408 continue;
2409 mEnchantCustomAttr[enchId] = true;
2410 ++count;
2411 break;
2412 }
2413 }
2414 }
2415
2416 LOG_INFO("server.loading", ">> Loaded {} Custom Enchant Attributes in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2417 LOG_INFO("server.loading", " ");
2418}
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
#define LOG_INFO(filterType__,...)
Definition Log.h:153
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition SharedDefines.h:820
@ SPELL_ATTR2_ENCHANT_OWN_ITEM_ONLY
Definition SharedDefines.h:457
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:131
uint32 getMSTime()
Definition Timer.h:103
bool HasAttribute(SpellAttr0 attribute) const
Definition SpellInfo.h:441
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition SpellInfo.h:417
Definition DBCStructure.h:1841

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 ( )
2613{
2614 uint32 oldMSTime = getMSTime();
2615
2616 mPetDefaultSpellsMap.clear();
2617
2618 uint32 countCreature = 0;
2619 uint32 countData = 0;
2620
2621 CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
2622 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
2623 {
2624 if (!itr->second.PetSpellDataId)
2625 continue;
2626
2627 // for creature with PetSpellDataId get default pet spells from dbc
2628 CreatureSpellDataEntry const* spellDataEntry = sCreatureSpellDataStore.LookupEntry(itr->second.PetSpellDataId);
2629 if (!spellDataEntry)
2630 continue;
2631
2632 int32 petSpellsId = -int32(itr->second.PetSpellDataId);
2633 PetDefaultSpellsEntry petDefSpells;
2634 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2635 petDefSpells.spellid[j] = spellDataEntry->spellId[j];
2636
2637 if (LoadPetDefaultSpells_helper(&itr->second, petDefSpells))
2638 {
2639 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2640 ++countData;
2641 }
2642 }
2643
2644 LOG_INFO("server.loading", ">> Loaded Addition Spells For {} Pet Spell Data Entries in {} ms", countData, GetMSTimeDiffToNow(oldMSTime));
2645 LOG_INFO("server.loading", " ");
2646
2647 LOG_INFO("server.loading", "Loading Summonable Creature Templates...");
2648 oldMSTime = getMSTime();
2649
2650 // different summon spells
2651 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2652 {
2653 SpellInfo const* spellInfo = GetSpellInfo(i);
2654 if (!spellInfo)
2655 continue;
2656
2657 for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
2658 {
2659 if (spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON || spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON_PET)
2660 {
2661 uint32 creature_id = spellInfo->Effects[k].MiscValue;
2662 CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id);
2663 if (!cInfo)
2664 continue;
2665
2666 // already loaded
2667 if (cInfo->PetSpellDataId)
2668 continue;
2669
2670 // for creature without PetSpellDataId get default pet spells from creature_template
2671 int32 petSpellsId = cInfo->Entry;
2672 if (mPetDefaultSpellsMap.find(cInfo->Entry) != mPetDefaultSpellsMap.end())
2673 continue;
2674
2675 PetDefaultSpellsEntry petDefSpells;
2676 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2677 petDefSpells.spellid[j] = cInfo->spells[j];
2678
2679 if (LoadPetDefaultSpells_helper(cInfo, petDefSpells))
2680 {
2681 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2682 ++countCreature;
2683 }
2684 }
2685 }
2686 }
2687
2688 LOG_INFO("server.loading", ">> Loaded {} Summonable Creature emplates in {} ms", countCreature, GetMSTimeDiffToNow(oldMSTime));
2689 LOG_INFO("server.loading", " ");
2690}
std::unordered_map< uint32, CreatureTemplate > CreatureTemplateContainer
Definition CreatureData.h:287
DBCStorage< CreatureSpellDataEntry > sCreatureSpellDataStore(CreatureSpellDatafmt)
#define MAX_CREATURE_SPELL_DATA_SLOT
Definition DBCStructure.h:807
@ SPELL_EFFECT_SUMMON_PET
Definition SharedDefines.h:822
@ SPELL_EFFECT_SUMMON
Definition SharedDefines.h:794
static bool LoadPetDefaultSpells_helper(CreatureTemplate const *cInfo, PetDefaultSpellsEntry &petDefSpells)
Definition SpellMgr.cpp:2564
Definition DBCStructure.h:810
uint32 spellId[MAX_CREATURE_SPELL_DATA_SLOT]
Definition DBCStructure.h:812
Definition CreatureData.h:187
uint32 Entry
Definition CreatureData.h:188
uint32 spells[MAX_CREATURE_SPELLS]
Definition CreatureData.h:224
uint32 PetSpellDataId
Definition CreatureData.h:225
Definition SpellMgr.h:594
uint32 spellid[MAX_CREATURE_SPELL_DATA_SLOT]
Definition SpellMgr.h:595

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 ( )
2519{
2520 uint32 oldMSTime = getMSTime();
2521
2522 mPetLevelupSpellMap.clear(); // need for reload case
2523
2524 uint32 count = 0;
2525 uint32 family_count = 0;
2526
2527 for (uint32 i = 0; i < sCreatureFamilyStore.GetNumRows(); ++i)
2528 {
2529 CreatureFamilyEntry const* creatureFamily = sCreatureFamilyStore.LookupEntry(i);
2530 if (!creatureFamily) // not exist
2531 continue;
2532
2533 for (uint8 j = 0; j < 2; ++j)
2534 {
2535 if (!creatureFamily->skillLine[j])
2536 continue;
2537
2538 for (SkillLineAbilityEntry const* skillLine : GetSkillLineAbilitiesBySkillLine(creatureFamily->skillLine[j]))
2539 {
2540 if (skillLine->AcquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN)
2541 continue;
2542
2543 SpellInfo const* spell = GetSpellInfo(skillLine->Spell);
2544 if (!spell) // not exist or triggered or talent
2545 continue;
2546
2547 if (!spell->SpellLevel)
2548 continue;
2549
2550 PetLevelupSpellSet& spellSet = mPetLevelupSpellMap[creatureFamily->ID];
2551 if (spellSet.empty())
2552 ++family_count;
2553
2554 spellSet.insert(PetLevelupSpellSet::value_type(spell->SpellLevel, spell->Id));
2555 ++count;
2556 }
2557 }
2558 }
2559
2560 LOG_INFO("server.loading", ">> Loaded {} Pet Levelup And Default Spells For {} Families in {} ms", count, family_count, GetMSTimeDiffToNow(oldMSTime));
2561 LOG_INFO("server.loading", " ");
2562}
@ SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN
Definition DBCEnums.h:361
const std::vector< SkillLineAbilityEntry const * > & GetSkillLineAbilitiesBySkillLine(uint32 skillLine)
Definition DBCStores.cpp:916
DBCStorage< CreatureFamilyEntry > sCreatureFamilyStore(CreatureFamilyfmt)
std::multimap< uint32, uint32 > PetLevelupSpellSet
Definition SpellMgr.h:588
uint32 SpellLevel
Definition SpellInfo.h:384
Definition DBCStructure.h:754
uint32 ID
Definition DBCStructure.h:755
uint32 skillLine[2]
Definition DBCStructure.h:760
Definition DBCStructure.h:1598

References getMSTime(), GetMSTimeDiffToNow(), GetSkillLineAbilitiesBySkillLine(), GetSpellInfo(), SpellInfo::Id, CreatureFamilyEntry::ID, LOG_INFO, mPetLevelupSpellMap, sCreatureFamilyStore, SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN, CreatureFamilyEntry::skillLine, and SpellInfo::SpellLevel.

◆ LoadSkillLineAbilityMap()

void SpellMgr::LoadSkillLineAbilityMap ( )
2295{
2296 uint32 oldMSTime = getMSTime();
2297
2298 mSkillLineAbilityMap.clear();
2299
2300 uint32 count = 0;
2301
2302 for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); ++i)
2303 {
2304 SkillLineAbilityEntry const* SkillInfo = sSkillLineAbilityStore.LookupEntry(i);
2305 if (!SkillInfo)
2306 continue;
2307
2308 mSkillLineAbilityMap.insert(SkillLineAbilityMap::value_type(SkillInfo->Spell, SkillInfo));
2309 ++count;
2310 }
2311
2312 LOG_INFO("server.loading", ">> Loaded {} SkillLineAbility MultiMap Data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2313 LOG_INFO("server.loading", " ");
2314}
DBCStorage< SkillLineAbilityEntry > sSkillLineAbilityStore(SkillLineAbilityfmt)
uint32 Spell
Definition DBCStructure.h:1601

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

◆ LoadSpellAreas()

void SpellMgr::LoadSpellAreas ( )
2693{
2694 uint32 oldMSTime = getMSTime();
2695
2696 mSpellAreaMap.clear(); // need for reload case
2697 mSpellAreaForQuestMap.clear();
2699 mSpellAreaForAuraMap.clear();
2700
2701 // 0 1 2 3 4 5 6 7 8 9
2702 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");
2703
2704 if (!result)
2705 {
2706 LOG_WARN("server.loading", ">> Loaded 0 spell area requirements. DB table `spell_area` is empty.");
2707 LOG_INFO("server.loading", " ");
2708 return;
2709 }
2710
2711 uint32 count = 0;
2712 do
2713 {
2714 Field* fields = result->Fetch();
2715
2716 uint32 spell = fields[0].Get<uint32>();
2717 SpellArea spellArea;
2718 spellArea.spellId = spell;
2719 spellArea.areaId = fields[1].Get<uint32>();
2720 spellArea.questStart = fields[2].Get<uint32>();
2721 spellArea.questStartStatus = fields[3].Get<uint32>();
2722 spellArea.questEndStatus = fields[4].Get<uint32>();
2723 spellArea.questEnd = fields[5].Get<uint32>();
2724 spellArea.auraSpell = fields[6].Get<int32>();
2725 spellArea.raceMask = fields[7].Get<uint32>();
2726 spellArea.gender = Gender(fields[8].Get<uint8>());
2727 spellArea.autocast = fields[9].Get<bool>();
2728
2729 if (SpellInfo const* spellInfo = GetSpellInfo(spell))
2730 {
2731 if (spellArea.autocast)
2732 const_cast<SpellInfo*>(spellInfo)->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
2733 }
2734 else
2735 {
2736 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` does not exist", spell);
2737 continue;
2738 }
2739
2740 {
2741 bool ok = true;
2742 SpellAreaMapBounds sa_bounds = GetSpellAreaMapBounds(spellArea.spellId);
2743 for (SpellAreaMap::const_iterator itr = sa_bounds.first; itr != sa_bounds.second; ++itr)
2744 {
2745 if (spellArea.spellId != itr->second.spellId)
2746 continue;
2747 if (spellArea.areaId != itr->second.areaId)
2748 continue;
2749 if (spellArea.questStart != itr->second.questStart)
2750 continue;
2751 if (spellArea.auraSpell != itr->second.auraSpell)
2752 continue;
2753 if ((spellArea.raceMask & itr->second.raceMask) == 0)
2754 continue;
2755 if (spellArea.gender != itr->second.gender)
2756 continue;
2757
2758 // duplicate by requirements
2759 ok = false;
2760 break;
2761 }
2762
2763 if (!ok)
2764 {
2765 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` already listed with similar requirements.", spell);
2766 continue;
2767 }
2768 }
2769
2770 if (spellArea.areaId && !sAreaTableStore.LookupEntry(spellArea.areaId))
2771 {
2772 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong area ({}) requirement", spell, spellArea.areaId);
2773 continue;
2774 }
2775
2776 if (spellArea.questStart && !sObjectMgr->GetQuestTemplate(spellArea.questStart))
2777 {
2778 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong start quest ({}) requirement", spell, spellArea.questStart);
2779 continue;
2780 }
2781
2782 if (spellArea.questEnd)
2783 {
2784 if (!sObjectMgr->GetQuestTemplate(spellArea.questEnd))
2785 {
2786 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong end quest ({}) requirement", spell, spellArea.questEnd);
2787 continue;
2788 }
2789 }
2790
2791 if (spellArea.auraSpell)
2792 {
2793 SpellInfo const* spellInfo = GetSpellInfo(std::abs(spellArea.auraSpell));
2794 if (!spellInfo)
2795 {
2796 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong aura spell ({}) requirement", spell, std::abs(spellArea.auraSpell));
2797 continue;
2798 }
2799
2800 if (uint32(std::abs(spellArea.auraSpell)) == spellArea.spellId)
2801 {
2802 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement for itself", spell, std::abs(spellArea.auraSpell));
2803 continue;
2804 }
2805
2806 // not allow autocast chains by auraSpell field (but allow use as alternative if not present)
2807 if (spellArea.autocast && spellArea.auraSpell > 0)
2808 {
2809 bool chain = false;
2810 SpellAreaForAuraMapBounds saBound = GetSpellAreaForAuraMapBounds(spellArea.spellId);
2811 for (SpellAreaForAuraMap::const_iterator itr = saBound.first; itr != saBound.second; ++itr)
2812 {
2813 if (itr->second->autocast && itr->second->auraSpell > 0)
2814 {
2815 chain = true;
2816 break;
2817 }
2818 }
2819
2820 if (chain)
2821 {
2822 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement that itself autocast from aura", spell, spellArea.auraSpell);
2823 continue;
2824 }
2825
2826 SpellAreaMapBounds saBound2 = GetSpellAreaMapBounds(spellArea.auraSpell);
2827 for (SpellAreaMap::const_iterator itr2 = saBound2.first; itr2 != saBound2.second; ++itr2)
2828 {
2829 if (itr2->second.autocast && itr2->second.auraSpell > 0)
2830 {
2831 chain = true;
2832 break;
2833 }
2834 }
2835
2836 if (chain)
2837 {
2838 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement that itself autocast from aura", spell, spellArea.auraSpell);
2839 continue;
2840 }
2841 }
2842 }
2843
2844 if (spellArea.raceMask && (spellArea.raceMask & sRaceMgr->GetPlayableRaceMask()) == 0)
2845 {
2846 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong race mask ({}) requirement", spell, spellArea.raceMask);
2847 continue;
2848 }
2849
2850 if (spellArea.gender != GENDER_NONE && spellArea.gender != GENDER_FEMALE && spellArea.gender != GENDER_MALE)
2851 {
2852 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong gender ({}) requirement", spell, spellArea.gender);
2853 continue;
2854 }
2855
2856 SpellArea const* sa = &mSpellAreaMap.insert(SpellAreaMap::value_type(spell, spellArea))->second;
2857
2858 // for search by current zone/subzone at zone/subzone change
2859 if (spellArea.areaId)
2860 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(spellArea.areaId, sa));
2861
2862 // for search at quest start/reward
2863 if (spellArea.questStart)
2864 mSpellAreaForQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa));
2865
2866 // for search at quest start/reward
2867 if (spellArea.questEnd)
2868 mSpellAreaForQuestEndMap.insert(SpellAreaForQuestMap::value_type(spellArea.questEnd, sa));
2869
2870 // for search at aura apply
2871 if (spellArea.auraSpell)
2872 mSpellAreaForAuraMap.insert(SpellAreaForAuraMap::value_type(std::abs(spellArea.auraSpell), sa));
2873
2874 ++count;
2875 } while (result->NextRow());
2876
2877 if (sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE) > 0)
2878 {
2879 LOG_INFO("server.loading", ">> Using ICC Buff Horde: {}", sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE));
2880 SpellArea spellAreaICCBuffHorde = { sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE), ICC_AREA, 0, 0, 0, ICC_RACEMASK_HORDE, Gender(2), 64, 11, 1 };
2881 SpellArea const* saICCBuffHorde = &mSpellAreaMap.insert(SpellAreaMap::value_type(sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE), spellAreaICCBuffHorde))->second;
2882 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(ICC_AREA, saICCBuffHorde));
2883 ++count;
2884 }
2885 else
2886 LOG_INFO("server.loading", ">> ICC Buff Horde: disabled");
2887
2888 if (sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE) > 0)
2889 {
2890 LOG_INFO("server.loading", ">> Using ICC Buff Alliance: {}", sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE));
2891 SpellArea spellAreaICCBuffAlliance = { sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE), ICC_AREA, 0, 0, 0, ICC_RACEMASK_ALLIANCE, Gender(2), 64, 11, 1 };
2892 SpellArea const* saICCBuffAlliance = &mSpellAreaMap.insert(SpellAreaMap::value_type(sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE), spellAreaICCBuffAlliance))->second;
2893 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(ICC_AREA, saICCBuffAlliance));
2894 ++count;
2895 }
2896 else
2897 LOG_INFO("server.loading", ">> ICC Buff Alliance: disabled");
2898
2899 LOG_INFO("server.loading", ">> Loaded {} Spell Area Requirements in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2900 LOG_INFO("server.loading", " ");
2901}
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
#define LOG_WARN(filterType__,...)
Definition Log.h:149
#define sRaceMgr
Definition RaceMgr.h:52
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:401
std::pair< SpellAreaMap::const_iterator, SpellAreaMap::const_iterator > SpellAreaMapBounds
Definition SpellMgr.h:537
@ ICC_RACEMASK_HORDE
Definition SpellMgr.h:512
@ ICC_AREA
Definition SpellMgr.h:511
@ ICC_RACEMASK_ALLIANCE
Definition SpellMgr.h:513
std::pair< SpellAreaForAuraMap::const_iterator, SpellAreaForAuraMap::const_iterator > SpellAreaForAuraMapBounds
Definition SpellMgr.h:539
@ CONFIG_ICC_BUFF_ALLIANCE
Definition WorldConfig.h:348
@ CONFIG_ICC_BUFF_HORDE
Definition WorldConfig.h:347
SpellAreaMapBounds GetSpellAreaMapBounds(uint32 spell_id) const
Definition SpellMgr.cpp:1007
SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds(uint32 spell_id) const
Definition SpellMgr.cpp:1022
#define sWorld
Definition World.h:317
Definition SpellMgr.h:517
uint32 spellId
Definition SpellMgr.h:518

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, sAreaTableStore, sObjectMgr, SPELL_ATTR0_NO_AURA_CANCEL, SpellArea::spellId, sRaceMgr, sWorld, and WorldDatabase.

◆ LoadSpellBonuses()

void SpellMgr::LoadSpellBonuses ( )
2177{
2178 uint32 oldMSTime = getMSTime();
2179
2180 mSpellBonusMap.clear(); // need for reload case
2181
2182 // 0 1 2 3 4
2183 QueryResult result = WorldDatabase.Query("SELECT entry, direct_bonus, dot_bonus, ap_bonus, ap_dot_bonus FROM spell_bonus_data");
2184 if (!result)
2185 {
2186 LOG_WARN("server.loading", ">> Loaded 0 spell bonus data. DB table `spell_bonus_data` is empty.");
2187 LOG_INFO("server.loading", " ");
2188 return;
2189 }
2190
2191 uint32 count = 0;
2192 do
2193 {
2194 Field* fields = result->Fetch();
2195 uint32 entry = fields[0].Get<uint32>();
2196
2197 SpellInfo const* spell = GetSpellInfo(entry);
2198 if (!spell)
2199 {
2200 LOG_ERROR("sql.sql", "Spell {} listed in `spell_bonus_data` does not exist", entry);
2201 continue;
2202 }
2203
2204 SpellBonusEntry& sbe = mSpellBonusMap[entry];
2205 sbe.direct_damage = fields[1].Get<float>();
2206 sbe.dot_damage = fields[2].Get<float>();
2207 sbe.ap_bonus = fields[3].Get<float>();
2208 sbe.ap_dot_bonus = fields[4].Get<float>();
2209
2210 ++count;
2211 } while (result->NextRow());
2212
2213 LOG_INFO("server.loading", ">> Loaded {} Extra Spell Bonus Data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2214 LOG_INFO("server.loading", " ");
2215}
Definition SpellMgr.h:321
float ap_dot_bonus
Definition SpellMgr.h:325
float dot_damage
Definition SpellMgr.h:323
float ap_bonus
Definition SpellMgr.h:324
float direct_damage
Definition SpellMgr.h:322

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 ( )
2935{
2936 uint32 oldMSTime = getMSTime();
2937
2939
2940 QueryResult result = WorldDatabase.Query("SELECT Id, RecoveryTime, CategoryRecoveryTime, StartRecoveryTime, StartRecoveryCategory FROM spell_cooldown_overrides");
2941
2942 uint32 count = 0;
2943
2944 if (result)
2945 {
2946 do
2947 {
2948 Field* fields = result->Fetch();
2949 SpellCooldownOverride spellCooldown;
2950 uint32 spellId = fields[0].Get<uint32>();
2951 spellCooldown.RecoveryTime = fields[1].Get<uint32>();
2952 spellCooldown.CategoryRecoveryTime = fields[2].Get<uint32>();
2953 spellCooldown.StartRecoveryTime = fields[3].Get<uint32>();
2954 spellCooldown.StartRecoveryCategory = fields[4].Get<uint32>();
2955 mSpellCooldownOverrideMap[spellId] = spellCooldown;
2956
2957 ++count;
2958 } while (result->NextRow());
2959 }
2960
2961 LOG_INFO("server.loading", ">> Loaded {} Spell Cooldown Overrides entries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2962 LOG_INFO("server.loading", " ");
2963}
Definition SpellMgr.h:609
uint32 StartRecoveryTime
Definition SpellMgr.h:612
uint32 CategoryRecoveryTime
Definition SpellMgr.h:611
uint32 StartRecoveryCategory
Definition SpellMgr.h:613
uint32 RecoveryTime
Definition SpellMgr.h:610

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

◆ LoadSpellEnchantProcData()

void SpellMgr::LoadSpellEnchantProcData ( )
2421{
2422 uint32 oldMSTime = getMSTime();
2423
2424 mSpellEnchantProcEventMap.clear(); // need for reload case
2425
2426 // 0 1 2 3 4
2427 QueryResult result = WorldDatabase.Query("SELECT entry, customChance, PPMChance, procEx, attributeMask FROM spell_enchant_proc_data");
2428 if (!result)
2429 {
2430 LOG_WARN("server.loading", ">> Loaded 0 spell enchant proc event conditions. DB table `spell_enchant_proc_data` is empty.");
2431 LOG_INFO("server.loading", " ");
2432 return;
2433 }
2434
2435 uint32 count = 0;
2436 do
2437 {
2438 Field* fields = result->Fetch();
2439
2440 uint32 enchantId = fields[0].Get<uint32>();
2441
2442 SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchantId);
2443 if (!ench)
2444 {
2445 LOG_ERROR("sql.sql", "Enchancment {} listed in `spell_enchant_proc_data` does not exist", enchantId);
2446 continue;
2447 }
2448
2450
2451 spe.customChance = fields[1].Get<uint32>();
2452 spe.PPMChance = fields[2].Get<float>();
2453 spe.procEx = fields[3].Get<uint32>();
2454 spe.attributeMask = fields[4].Get<uint32>();
2455
2456 mSpellEnchantProcEventMap[enchantId] = spe;
2457
2458 ++count;
2459 } while (result->NextRow());
2460
2461 LOG_INFO("server.loading", ">> Loaded {} Enchant Proc Data Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2462 LOG_INFO("server.loading", " ");
2463}
Definition SpellMgr.h:311
uint32 procEx
Definition SpellMgr.h:314
uint32 attributeMask
Definition SpellMgr.h:315
uint32 customChance
Definition SpellMgr.h:312
float PPMChance
Definition SpellMgr.h:313

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 ( )
1582{
1583 uint32 oldMSTime = getMSTime();
1584
1585 mSpellSpellGroup.clear(); // need for reload case
1586 mSpellGroupSpell.clear();
1587
1588 // 0 1
1589 QueryResult result = WorldDatabase.Query("SELECT id, spell_id FROM spell_group");
1590 if (!result)
1591 {
1592 LOG_WARN("server.loading", ">> Loaded 0 spell group definitions. DB table `spell_group` is empty.");
1593 LOG_INFO("server.loading", " ");
1594 return;
1595 }
1596
1597 std::set<uint32> groups;
1598 uint32 count = 0;
1599 do
1600 {
1601 Field* fields = result->Fetch();
1602
1603 uint32 group_id = fields[0].Get<uint32>();
1604 if (group_id <= SPELL_GROUP_DB_RANGE_MIN && group_id >= SPELL_GROUP_CORE_RANGE_MAX)
1605 {
1606 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group` is in core range, but is not defined in core!", group_id);
1607 continue;
1608 }
1609 int32 spell_id = fields[1].Get<int32>();
1610
1611 groups.insert(group_id);
1612 mSpellGroupSpell.emplace(SpellGroup(group_id), spell_id);
1613
1614 } while (result->NextRow());
1615
1616 for (auto itr = mSpellGroupSpell.begin(); itr!= mSpellGroupSpell.end();)
1617 {
1618 if (itr->second < 0)
1619 {
1620 if (groups.find(abs(itr->second)) == groups.end())
1621 {
1622 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group` does not exist", abs(itr->second));
1623 itr = mSpellGroupSpell.erase(itr);
1624 }
1625 else
1626 ++itr;
1627 }
1628 else
1629 {
1630 SpellInfo const* spellInfo = GetSpellInfo(itr->second);
1631 if (!spellInfo)
1632 {
1633 LOG_ERROR("sql.sql", "Spell {} listed in `spell_group` does not exist", itr->second);
1634 itr = mSpellGroupSpell.erase(itr);
1635 }
1636 else if (spellInfo->GetRank() > 1)
1637 {
1638 LOG_ERROR("sql.sql", "Spell {} listed in `spell_group` is not first rank of spell.", itr->second);
1639 itr = mSpellGroupSpell.erase(itr);
1640 }
1641 else
1642 ++itr;
1643 }
1644 }
1645
1646 for (auto groupItr = groups.begin(); groupItr != groups.end(); ++groupItr)
1647 {
1648 std::set<uint32> spells;
1650
1651 for (auto spellItr = spells.begin(); spellItr != spells.end(); ++spellItr)
1652 {
1653 ++count;
1654 mSpellSpellGroup.emplace(*spellItr, SpellGroup(*groupItr));
1655 }
1656 }
1657
1658 LOG_INFO("server.loading", ">> Loaded {} spell group Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1659 LOG_INFO("server.loading", " ");
1660}
@ SPELL_GROUP_CORE_RANGE_MAX
Definition SpellMgr.h:335
spells
Definition boss_krystallus.cpp:26
uint8 GetRank() const
Definition SpellInfo.cpp:2896

References Field::Get(), getMSTime(), GetMSTimeDiffToNow(), SpellInfo::GetRank(), GetSetOfSpellsInSpellGroup(), GetSpellInfo(), LOG_ERROR, LOG_INFO, LOG_WARN, mSpellGroupSpell, mSpellSpellGroup, SPELL_GROUP_CORE_RANGE_MAX, and WorldDatabase.

◆ LoadSpellGroupStackRules()

void SpellMgr::LoadSpellGroupStackRules ( )
1663{
1664 uint32 oldMSTime = getMSTime();
1665
1666 mSpellGroupStack.clear(); // need for reload case
1667 mSpellSameEffectStack.clear();
1668
1669 std::vector<uint32> sameEffectGroups;
1670
1671 // 0 1
1672 QueryResult result = WorldDatabase.Query("SELECT group_id, stack_rule FROM spell_group_stack_rules");
1673 if (!result)
1674 {
1675 LOG_WARN("server.loading", ">> Loaded 0 spell group stack rules. DB table `spell_group_stack_rules` is empty.");
1676 LOG_INFO("server.loading", " ");
1677 return;
1678 }
1679
1680 uint32 count = 0;
1681 do
1682 {
1683 Field* fields = result->Fetch();
1684
1685 uint32 group_id = fields[0].Get<uint32>();
1686 uint8 stack_rule = fields[1].Get<int8>();
1687 if (stack_rule >= SPELL_GROUP_STACK_RULE_MAX)
1688 {
1689 LOG_ERROR("sql.sql", "SpellGroupStackRule {} listed in `spell_group_stack_rules` does not exist.", stack_rule);
1690 continue;
1691 }
1692
1693 auto bounds = GetSpellGroupSpellMapBounds((SpellGroup)group_id);
1694 if (bounds.first == bounds.second)
1695 {
1696 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group_stack_rules` does not exist.", group_id);
1697 continue;
1698 }
1699
1700 mSpellGroupStack.emplace(SpellGroup(group_id), SpellGroupStackRule(stack_rule));
1701
1702 // different container for same effect stack rules, need to check effect types
1704 sameEffectGroups.push_back(group_id);
1705
1706 ++count;
1707 } while (result->NextRow());
1708
1709 LOG_INFO("server.loading", ">> Loaded {} spell group stack rules in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1710 LOG_INFO("server.loading", " ");
1711
1712 count = 0;
1713 oldMSTime = getMSTime();
1714
1715 for (uint32 group_id : sameEffectGroups)
1716 {
1717 std::set<uint32> spellIds;
1718 GetSetOfSpellsInSpellGroup(SpellGroup(group_id), spellIds);
1719
1720 std::unordered_set<uint32> auraTypes;
1721
1722 // we have to 'guess' what effect this group corresponds to
1723 {
1724 std::unordered_multiset<uint32 /*auraName*/> frequencyContainer;
1725
1726 // only waylay for the moment (shared group)
1727 std::vector<std::vector<uint32 /*auraName*/>> const SubGroups =
1728 {
1730 };
1731
1732 for (uint32 spellId : spellIds)
1733 {
1734 SpellInfo const* spellInfo = AssertSpellInfo(spellId);
1735 for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
1736 {
1737 if (!spellEffectInfo.IsAura())
1738 continue;
1739
1740 uint32 auraName = spellEffectInfo.ApplyAuraName;
1741 for (std::vector<uint32> const& subGroup : SubGroups)
1742 {
1743 if (std::find(subGroup.begin(), subGroup.end(), auraName) != subGroup.end())
1744 {
1745 // count as first aura
1746 auraName = subGroup.front();
1747 break;
1748 }
1749 }
1750
1751 frequencyContainer.insert(auraName);
1752 }
1753 }
1754
1755 uint32 auraType = 0;
1756 size_t auraTypeCount = 0;
1757 for (uint32 auraName : frequencyContainer)
1758 {
1759 size_t currentCount = frequencyContainer.count(auraName);
1760 if (currentCount > auraTypeCount)
1761 {
1762 auraType = auraName;
1763 auraTypeCount = currentCount;
1764 }
1765 }
1766
1767 for (std::vector<uint32> const& subGroup : SubGroups)
1768 {
1769 if (auraType == subGroup.front())
1770 {
1771 auraTypes.insert(subGroup.begin(), subGroup.end());
1772 break;
1773 }
1774 }
1775
1776 if (auraTypes.empty())
1777 auraTypes.insert(auraType);
1778 }
1779
1780 // re-check spells against guessed group
1781 for (uint32 spellId : spellIds)
1782 {
1783 SpellInfo const* spellInfo = AssertSpellInfo(spellId);
1784
1785 bool found = false;
1786 while (spellInfo)
1787 {
1788 for (uint32 auraType : auraTypes)
1789 {
1790 if (spellInfo->HasAura(AuraType(auraType)))
1791 {
1792 found = true;
1793 break;
1794 }
1795 }
1796
1797 if (found)
1798 break;
1799
1800 spellInfo = spellInfo->GetNextRankSpell();
1801 }
1802
1803 // not found either, log error
1804 if (!found)
1805 LOG_ERROR("sql.sql", "SpellId {} listed in `spell_group` with stack rule 3 does not share aura assigned for group {}", spellId, group_id);
1806 }
1807
1808 mSpellSameEffectStack[SpellGroup(group_id)] = auraTypes;
1809 ++count;
1810 }
1811
1812 LOG_INFO("server.loading", ">> Loaded {} SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT stack rules in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1813 LOG_INFO("server.loading", " ");
1814}
std::int8_t int8
Definition Define.h:105
@ SPELL_AURA_MOD_MELEE_HASTE
Definition SpellAuraDefines.h:201
@ SPELL_AURA_MOD_RANGED_HASTE
Definition SpellAuraDefines.h:203
@ SPELL_AURA_MOD_MELEE_RANGED_HASTE
Definition SpellAuraDefines.h:255
@ SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT
Definition SpellMgr.h:365
@ SPELL_GROUP_STACK_RULE_MAX
Definition SpellMgr.h:367
Definition SpellInfo.h:270
SpellInfo const * GetNextRankSpell() const
Definition SpellInfo.cpp:2915
bool HasAura(AuraType aura) const
Definition SpellInfo.cpp:902
SpellInfo const * AssertSpellInfo(uint32 spellId) const
Definition SpellMgr.h:735

References AssertSpellInfo(), Field::Get(), SpellInfo::GetEffects(), getMSTime(), GetMSTimeDiffToNow(), SpellInfo::GetNextRankSpell(), GetSetOfSpellsInSpellGroup(), GetSpellGroupSpellMapBounds(), SpellInfo::HasAura(), LOG_ERROR, LOG_INFO, LOG_WARN, mSpellGroupStack, mSpellSameEffectStack, SPELL_AURA_MOD_MELEE_HASTE, SPELL_AURA_MOD_MELEE_RANGED_HASTE, SPELL_AURA_MOD_RANGED_HASTE, SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT, SPELL_GROUP_STACK_RULE_MAX, and WorldDatabase.

◆ LoadSpellInfoCorrections()

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

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

◆ LoadSpellInfoCustomAttributes()

void SpellMgr::LoadSpellInfoCustomAttributes ( )
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
3048{
3049 uint32 const oldMSTime = getMSTime();
3050 uint32 const customAttrTime = getMSTime();
3051 uint32 count;
3052
3053 QueryResult result = WorldDatabase.Query("SELECT spell_id, attributes FROM spell_custom_attr");
3054
3055 if (!result)
3056 {
3057 LOG_WARN("server.loading", ">> Loaded 0 Spell Custom Attributes From DB. DB table `spell_custom_attr` Is Empty.");
3058 }
3059 else
3060 {
3061 for (count = 0; result->NextRow(); ++count)
3062 {
3063 Field const* fields = result->Fetch();
3064
3065 uint32 const spellId = fields[0].Get<uint32>();
3066 uint32 attributes = fields[1].Get<uint32>();
3067
3068 SpellInfo* spellInfo = _GetSpellInfo(spellId);
3069 if (!spellInfo)
3070 {
3071 LOG_INFO("sql.sql", "Table `spell_custom_attr` has wrong spell (spell_id: {}), ignored.", spellId);
3072 continue;
3073 }
3074
3075 if (attributes & SPELL_ATTR0_CU_NEGATIVE)
3076 {
3077 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3078 {
3079 if (spellInfo->Effects[i].IsEffect())
3080 {
3081 if ((attributes & (SPELL_ATTR0_CU_NEGATIVE_EFF0 << i)) && (attributes & (SPELL_ATTR0_CU_POSITIVE_EFF0 << i)))
3082 {
3083 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);
3085 }
3086 continue;
3087 }
3088
3089 if (attributes & (SPELL_ATTR0_CU_NEGATIVE_EFF0 << i))
3090 {
3091 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));
3092 attributes &= ~(SPELL_ATTR0_CU_NEGATIVE_EFF0 << i);
3093 }
3094 }
3095 }
3096
3097 if (attributes & SPELL_ATTR0_CU_POSITIVE)
3098 {
3099 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3100 {
3101 if (spellInfo->Effects[i].IsEffect())
3102 {
3103 continue;
3104 }
3105
3106 if ((attributes & (SPELL_ATTR0_CU_POSITIVE_EFF0 << i)))
3107 {
3108 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));
3109 attributes &= ~(SPELL_ATTR0_CU_POSITIVE_EFF0 << i);
3110 }
3111 }
3112 }
3113
3114 if ((attributes & SPELL_ATTR0_CU_FORCE_AURA_SAVING) && (attributes & SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED))
3115 {
3116 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);
3118 }
3119
3120 spellInfo->AttributesCu |= attributes;
3121 }
3122 LOG_INFO("server.loading", ">> Loaded {} spell custom attributes from DB in {} ms", count, GetMSTimeDiffToNow(customAttrTime));
3123 }
3124
3125 // xinef: create talent spells set
3126 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
3127 {
3128 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
3129 if (!talentInfo)
3130 continue;
3131
3132 for (uint8 j = 0; j < MAX_TALENT_RANK; j++)
3133 if (uint32 spellId = talentInfo->RankID[j])
3134 if (SpellInfo const* spellInfo = GetSpellInfo(spellId))
3135 for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
3136 if (spellInfo->Effects[k].Effect == SPELL_EFFECT_LEARN_SPELL)
3137 if (SpellInfo const* learnSpell = GetSpellInfo(spellInfo->Effects[k].TriggerSpell))
3138 if (learnSpell->IsRanked() && !learnSpell->HasAttribute(SpellAttr0(SPELL_ATTR0_PASSIVE | SPELL_ATTR0_DO_NOT_DISPLAY)))
3139 mTalentSpellAdditionalSet.insert(learnSpell->Id);
3140 }
3141
3142 SpellInfo* spellInfo = nullptr;
3143 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3144 {
3145 spellInfo = mSpellInfoMap[i];
3146 if (!spellInfo)
3147 continue;
3148
3149 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3150 {
3151 switch (spellInfo->Effects[j].ApplyAuraName)
3152 {
3154 {
3155 switch (spellInfo->Id)
3156 {
3157 // Exceptions
3158 case 44801: // Spectral Invisibility (Kalecgos, SWP)
3159 case 46021: // Spectral Realm (SWP)
3160 case 52951: // Chapel Invisibility (DK starting zone)
3161 break;
3162 default:
3164 break;
3165 }
3166 }
3167 break;
3174 break;
3175 default:
3176 break;
3177 }
3178
3179 switch (spellInfo->Effects[j].ApplyAuraName)
3180 {
3181 case SPELL_AURA_CONVERT_RUNE: // Can't be saved - aura handler relies on calculated amount and changes it
3182 case SPELL_AURA_OPEN_STABLE: // No point in saving this, since the stable dialog can't be open on aura load anyway.
3183 // Auras that require both caster & target to be in world cannot be saved
3191 break;
3192 default:
3193 break;
3194 }
3195
3196 switch (spellInfo->Effects[j].ApplyAuraName)
3197 {
3205 break;
3208 break;
3209 default:
3210 break;
3211 }
3212
3213 switch (spellInfo->Effects[j].Effect)
3214 {
3220 case SPELL_EFFECT_HEAL:
3222 break;
3233 break;
3236 case SPELL_EFFECT_JUMP:
3239 spellInfo->AttributesCu |= SPELL_ATTR0_CU_CHARGE;
3240 break;
3243 break;
3248 {
3249 // Only Enchanting profession enchant procs can stack when dual-wielding
3250 // DK runes (e.g., Unholy Strength) should refresh, not stack
3252 {
3253 uint32 enchantId = spellInfo->Effects[j].MiscValue;
3254 SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId);
3255 if (!enchant)
3256 break;
3257
3258 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
3259 {
3260 if (enchant->type[s] != ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL)
3261 continue;
3262
3263 SpellInfo* procInfo = _GetSpellInfo(enchant->spellid[s]);
3264 if (!procInfo)
3265 continue;
3266
3267 // if proced directly from enchantment, not via proc aura
3268 // NOTE: Enchant Weapon - Blade Ward also has proc aura spell and is proced directly
3269 // however its not expected to stack so this check is good
3271 continue;
3272
3274 }
3275 }
3276 break;
3277 }
3278 }
3279 }
3280
3281 // Xinef: spells ignoring hit result should not be binary
3282 if (!spellInfo->HasAttribute(SPELL_ATTR3_ALWAYS_HIT))
3283 {
3284 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3285 {
3286 if (spellInfo->Effects[j].Effect)
3287 {
3288 switch (spellInfo->Effects[j].Effect)
3289 {
3297 continue;
3306 if (spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
3307 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE_PERCENT ||
3308 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_DUMMY ||
3309 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH ||
3310 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_HEALTH_FUNNEL ||
3311 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DUMMY)
3312 continue;
3313 [[fallthrough]];
3314 default:
3315 if (!(spellInfo->Effects[j].CalcValue() ||
3316 ((spellInfo->Effects[j].Effect == SPELL_EFFECT_INTERRUPT_CAST || spellInfo->HasAttribute(SPELL_ATTR0_CU_DONT_BREAK_STEALTH)) &&
3318 continue;
3319
3320 if (spellInfo->Id == 69649 || spellInfo->Id == 71056 || spellInfo->Id == 71057 || spellInfo->Id == 71058 ||
3321 spellInfo->Id == 73061 || spellInfo->Id == 73062 || spellInfo->Id == 73063 || spellInfo->Id == 73064)
3322 continue;
3323
3324 if (spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && (spellInfo->SpellFamilyFlags[0] & 0x20)) // Frostbolt
3325 continue;
3326
3327 if (spellInfo->Id == 55095) // Frost Fever
3328 continue;
3329
3330 if (spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK &&
3331 ((spellInfo->SpellFamilyFlags[1] & 0x40000) || (spellInfo->SpellFamilyFlags[0] & 0x4000))) // Haunt/Drain Soul
3332 continue;
3333
3335 break;
3336 }
3337 }
3338 }
3339 }
3340
3341 // pussywizard:
3342 if ((spellInfo->SchoolMask & SPELL_SCHOOL_MASK_NORMAL) && (spellInfo->SchoolMask & SPELL_SCHOOL_MASK_MAGIC))
3343 {
3344 spellInfo->SchoolMask &= ~SPELL_SCHOOL_MASK_NORMAL;
3346 }
3347
3348 if (!spellInfo->_IsPositiveEffect(EFFECT_0, false))
3350
3351 if (!spellInfo->_IsPositiveEffect(EFFECT_1, false))
3353
3354 if (!spellInfo->_IsPositiveEffect(EFFECT_2, false))
3356
3357 if (spellInfo->SpellVisual[0] == 3879)
3359
3360 switch (spellInfo->SpellFamilyName)
3361 {
3363 // Shout
3364 if (spellInfo->SpellFamilyFlags[0] & 0x20000 || spellInfo->SpellFamilyFlags[1] & 0x20)
3366 break;
3367 case SPELLFAMILY_DRUID:
3368 // Roar
3369 if (spellInfo->SpellFamilyFlags[0] & 0x8)
3371 break;
3372 case SPELLFAMILY_HUNTER:
3373 // Aspects
3374 if (spellInfo->GetCategory() == 47)
3375 {
3377 }
3378 // Aimed Shot
3379 if (spellInfo->SpellFamilyFlags[0] & 0x00020000)
3380 {
3382 }
3383 break;
3384 default:
3385 break;
3386 }
3387
3388 switch (spellInfo->Id)
3389 {
3390 // Xinef: additional spells which should be binary
3391 case 45145: // Snake Trap Effect
3393 break;
3394 case 1776: // Gouge
3395 case 1777:
3396 case 8629:
3397 case 11285:
3398 case 11286:
3399 case 12540:
3400 case 13579:
3401 case 24698:
3402 case 28456:
3403 case 29425:
3404 case 34940:
3405 case 36862:
3406 case 38764:
3407 case 38863:
3408 case 52743: // Head Smack
3410 break;
3411 case 53: // Backstab
3412 case 2589:
3413 case 2590:
3414 case 2591:
3415 case 7159:
3416 case 8627:
3417 case 8721:
3418 case 11279:
3419 case 11280:
3420 case 11281:
3421 case 15582:
3422 case 15657:
3423 case 22416:
3424 case 25300:
3425 case 26863:
3426 case 37685:
3427 case 48656:
3428 case 48657:
3429 case 703: // Garrote
3430 case 8631:
3431 case 8632:
3432 case 8633:
3433 case 11289:
3434 case 11290:
3435 case 26839:
3436 case 26884:
3437 case 48675:
3438 case 48676:
3439 case 5221: // Shred
3440 case 6800:
3441 case 8992:
3442 case 9829:
3443 case 9830:
3444 case 27001:
3445 case 27002:
3446 case 48571:
3447 case 48572:
3448 case 8676: // Ambush
3449 case 8724:
3450 case 8725:
3451 case 11267:
3452 case 11268:
3453 case 11269:
3454 case 27441:
3455 case 48689:
3456 case 48690:
3457 case 48691:
3458 case 6785: // Ravage
3459 case 6787:
3460 case 9866:
3461 case 9867:
3462 case 27005:
3463 case 48578:
3464 case 48579:
3465 case 21987: // Lash of Pain
3466 case 23959: // Test Stab R50
3467 case 24825: // Test Backstab
3468 case 58563: // Assassinate Restless Lookout
3469 case 63124: // quest There's Something About the Squire (13654)
3471 break;
3472 case 26029: // Dark Glare
3473 case 43140: // Flame Breath
3474 case 43215: // Flame Breath
3475 case 70461: // Coldflame Trap
3476 case 72133: // Pain and Suffering
3477 case 73788: // Pain and Suffering
3478 case 73789: // Pain and Suffering
3479 case 73790: // Pain and Suffering
3480 case 63293: // Mimiron - spinning damage
3481 case 68873: // Wailing Souls
3482 case 70324: // Wailing Souls
3483 case 64619: // Ulduar, Mimiron, Emergency Fire Bot, Water Spray
3485 break;
3486 case 58690: // Cyanigosa, Tail Sweep
3487 case 59283: // Cyanigosa, Tail Sweep
3489 break;
3490 case 24340: // Meteor
3491 case 26558: // Meteor
3492 case 28884: // Meteor
3493 case 36837: // Meteor
3494 case 38903: // Meteor
3495 case 41276: // Meteor
3496 case 57467: // Meteor
3497 case 26789: // Shard of the Fallen Star
3498 case 31436: // Malevolent Cleave
3499 case 40810: // Saber Lash
3500 case 43267: // Saber Lash
3501 case 43268: // Saber Lash
3502 case 42384: // Brutal Swipe
3503 case 45150: // Meteor Slash
3504 case 64688: // Sonic Screech
3505 case 72373: // Shared Suffering
3506 case 71904: // Chaos Bane
3507 case 70492: // Ooze Eruption
3508 case 72505: // Ooze Eruption
3509 case 72624: // Ooze Eruption
3510 case 72625: // Ooze Eruption
3511 // ONLY SPELLS WITH SPELLFAMILY_GENERIC and EFFECT_SCHOOL_DAMAGE, OR WEAPON_DMG_X
3512 case 66809: // Meteor Fists
3513 case 67331: // Meteor Fists
3514 case 66765: // Meteor Fists
3515 case 67333: // Meteor Fists
3517 break;
3518 case 18500: // Wing Buffet
3519 case 33086: // Wild Bite
3520 case 49749: // Piercing Blow
3521 case 52890: // Penetrating Strike
3522 case 53454: // Impale
3523 case 59446: // Impale
3524 case 62383: // Shatter
3525 case 64777: // Machine Gun
3526 case 65239: // Machine Gun
3527 case 69293: // Wing Buffet
3528 case 74439: // Machine Gun
3529 // Trial of the Crusader, Jaraxxus, Shivan Slash
3530 case 66378:
3531 case 67097:
3532 case 67098:
3533 case 67099:
3534 // Trial of the Crusader, Anub'arak, Impale
3535 case 65919:
3536 case 67858:
3537 case 67859:
3538 case 67860:
3539 case 63278: // Mark of the Faceless (General Vezax)
3540 case 64125: // Ulduar, Yogg-Saron, Squeeze
3541 case 64126: // Ulduar, Yogg-Saron, Squeeze
3542 case 62544: // Thrust (Argent Tournament)
3543 case 64588: // Thrust (Argent Tournament)
3544 case 66479: // Thrust (Argent Tournament)
3545 case 68505: // Thrust (Argent Tournament)
3546 case 62709: // Counterattack! (Argent Tournament)
3547 case 62626: // Break-Shield (Argent Tournament, Player)
3548 case 64590: // Break-Shield (Argent Tournament, Player)
3549 case 64342: // Break-Shield (Argent Tournament, NPC)
3550 case 64686: // Break-Shield (Argent Tournament, NPC)
3551 case 65147: // Break-Shield (Argent Tournament, NPC)
3552 case 68504: // Break-Shield (Argent Tournament, NPC)
3553 case 62874: // Charge (Argent Tournament, Player)
3554 case 68498: // Charge (Argent Tournament, Player)
3555 case 64591: // Charge (Argent Tournament, Player)
3556 case 63003: // Charge (Argent Tournament, NPC)
3557 case 63010: // Charge (Argent Tournament, NPC)
3558 case 68321: // Charge (Argent Tournament, NPC)
3559 case 72255: // Mark of the Fallen Champion (Deathbringer Saurfang)
3560 case 72444: // Mark of the Fallen Champion (Deathbringer Saurfang)
3561 case 72445: // Mark of the Fallen Champion (Deathbringer Saurfang)
3562 case 72446: // Mark of the Fallen Champion (Deathbringer Saurfang)
3563 case 72409: // Rune of Blood (Deathbringer Saurfang)
3564 case 72447: // Rune of Blood (Deathbringer Saurfang)
3565 case 72448: // Rune of Blood (Deathbringer Saurfang)
3566 case 72449: // Rune of Blood (Deathbringer Saurfang)
3567 case 49882: // Leviroth Self-Impale
3568 case 62775: // Ulduar: XT-002 Tympanic Tamparum
3570 break;
3571 case 64422: // Sonic Screech (Auriaya)
3574 break;
3575 case 72293: // Mark of the Fallen Champion (Deathbringer Saurfang)
3576 case 72347: // Lock Players and Tap Chest (Gunship Battle)
3578 break;
3579 default:
3580 break;
3581 case 63675: // Improved Devouring Plague
3582 case 17962: // Conflagrate
3583 case 32593: // Earth Shield aura
3584 case 32594: // Earth Shield aura
3585 case 49283: // Earth Shield aura
3586 case 49284: // Earth Shield aura
3587 case 50526: // Wandering Plague
3588 case 53353: // Chimera Shot - Serpent trigger
3589 case 52752: // Ancestral Awakening Heal
3591 break;
3592 case 65280: // Ulduar, Hodir, Singed
3593 case 28969: // Naxxramas, Crypt Guard, Acid Spit (10 normal)
3594 case 56098: // Naxxramas, Crypt Guard, Acid Spit (25 normal)
3595 case 27891: // Naxxramas, Sludge Belcher, Acidic Sludge (10 normal)
3596 case 54331: // Naxxramas, Sludge Belcher, Acidic Sludge (25 normal)
3597 case 29325: // Naxxramas, Stoneskin Gargoyle, Acid Volley (10 normal)
3598 case 54714: // Naxxramas, Stoneskin Gargoyle, Acid Volley (25 normal)
3599 case 65775: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (10 normal)
3600 case 67861: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (25 normal)
3601 case 67862: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (10 heroic)
3602 case 67863: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (25 heroic)
3603 case 55604: // Naxxramas, Unrelenting Trainee, Death Plague (10 normal)
3604 case 55645: // Naxxramas, Unrelenting Trainee, Death Plague (25 normal)
3605 case 67721: // Anub'arak, Nerubian Burrower, Expose Weakness (normal)
3606 case 67847: // Anub'arak, Nerubian Burrower, Expose Weakness (heroic)
3607 case 64638: // Ulduar, Winter Jormungar, Acidic Bite
3608 case 71157: // Icecrown Citadel, Plagued Zombie, Infected Wound
3609 case 72963: // Icecrown Citadel, Rot Worm, Flesh Rot (10 normal)
3610 case 72964: // Icecrown Citadel, Rot Worm, Flesh Rot (25 normal)
3611 case 72965: // Icecrown Citadel, Rot Worm, Flesh Rot (10 heroic)
3612 case 72966: // Icecrown Citadel, Rot Worm, Flesh Rot (25 heroic)
3613 case 72465: // Icecrown Citadel, Sindragosa, Respite for a Tormented Soul (weekly quest)
3614 case 45271: // Sunwell, Eredar Twins encounter, Dark Strike
3615 case 45347: // Sunwell, Eredar Twins encounter, Dark Touched
3616 case 45348: // Sunwell, Eredar Twins encounter, Flame Touched
3617 case 35859: // The Eye, Nether Vapor
3618 case 40520: // Black Temple, Shade Soul Channel
3619 case 40327: // Black Temple, Atrophy
3620 case 38449: // Serpentshrine Cavern, Blessing of the Tides
3621 case 38044: // Serpentshrine Cavern, Surge
3622 case 74507: // Ruby Sanctum, Siphoned Might
3623 case 49381: // Drak'tharon Keep, Consume
3624 case 59805: // Drak'tharon Keep, Consume
3625 case 55093: // Gundrak, Grip of Slad'ran
3626 case 30659: // Hellfire Ramparts, Fel Infusion
3627 case 54314: // Azjol'Nerub Drain Power
3628 case 59354: // Azjol'Nerub Drain Power
3629 case 34655: // Snake Trap, Deadly Poison
3630 case 11971: // Sunder Armor
3631 case 58567: // Player Sunder Armor
3632 case 12579: // Player Winter's Chill
3633 case 29306: // Naxxramas(Gluth's Zombies): Infected Wound
3634 case 61920: // Ulduar(Spellbreaker): Supercharge
3635 case 63978: // Ulduar(Rubble): Stone Nova
3636 case 15502: // Sunder Armor
3638 break;
3639 case 43138: // North Fleet Reservist Kill Credit
3641 break;
3642 case 6197: // Eagle Eye
3644 break;
3645 case 50315: // Disco Ball
3647 break;
3648 case 14183: // Premeditation
3650 break;
3651
3652 // Xinef: NOT CUSTOM, cant add in DBC CORRECTION because i need to swap effects, too much work to do there
3653 // Envenom
3654 case 32645:
3655 case 32684:
3656 case 57992:
3657 case 57993:
3658 {
3659 SpellEffectInfo info = spellInfo->Effects[EFFECT_0];
3660 spellInfo->Effects[EFFECT_0] = spellInfo->Effects[EFFECT_2];
3661 spellInfo->Effects[EFFECT_2] = info;
3662 break;
3663 }
3664
3665 // Xinef: Cooldown overwrites
3666 // Burst of Speed
3667 case 57493:
3668 spellInfo->RecoveryTime = 60000;
3669 spellInfo->_requireCooldownInfo = true;
3670 break;
3671 // Strafe Jotunheim Building
3672 case 7769:
3673 spellInfo->RecoveryTime = 1500;
3674 spellInfo->_requireCooldownInfo = true;
3675 break;
3676 case 44535: // Spirit Heal, abilities also have no cost
3677 spellInfo->Effects[EFFECT_0].MiscValue = 127;
3678 break;
3679 case 45537: // Cosmetic - Lightning Beam Channel
3681 break;
3682 }
3683
3684 if (spellInfo->Speed > 0.0f)
3685 {
3686 if (SpellVisualEntry const* spellVisual = sSpellVisualStore.LookupEntry(spellInfo->SpellVisual[0]))
3687 {
3688 if (spellVisual->HasMissile)
3689 {
3690 if (spellVisual->MissileModel == -4 || spellVisual->MissileModel == -5)
3691 {
3693 }
3694 }
3695 }
3696 }
3697
3698 spellInfo->_InitializeExplicitTargetMask();
3699
3700 if (HasSpellCooldownOverride(spellInfo->Id))
3701 {
3702 SpellCooldownOverride spellOverride = GetSpellCooldownOverride(spellInfo->Id);
3703
3704 if (spellInfo->RecoveryTime != spellOverride.RecoveryTime)
3705 {
3706 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3707 }
3708
3709 if (spellInfo->CategoryRecoveryTime != spellOverride.CategoryRecoveryTime)
3710 {
3711 spellInfo->CategoryRecoveryTime = spellOverride.CategoryRecoveryTime;
3712 }
3713
3714 if (spellInfo->StartRecoveryTime != spellOverride.StartRecoveryTime)
3715 {
3716 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3717 }
3718
3719 if (spellInfo->StartRecoveryCategory != spellOverride.StartRecoveryCategory)
3720 {
3721 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3722 }
3723 }
3724
3725 sScriptMgr->OnLoadSpellCustomAttr(spellInfo);
3726 }
3727
3728 // Xinef: addition for binary spells, ommit spells triggering other spells
3729 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3730 {
3731 spellInfo = mSpellInfoMap[i];
3732 if (!spellInfo)
3733 continue;
3734
3735 if (!(spellInfo->AttributesCu & SPELL_ATTR0_CU_BINARY_SPELL))
3736 continue;
3737
3738 bool allNonBinary = true;
3739 bool overrideAttr = false;
3740 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3741 {
3742 if (spellInfo->Effects[j].ApplyAuraName && spellInfo->Effects[j].TriggerSpell)
3743 {
3744 switch (spellInfo->Effects[j].ApplyAuraName)
3745 {
3749 if (SpellInfo const* triggerSpell = GetSpellInfo(spellInfo->Effects[j].TriggerSpell))
3750 {
3751 overrideAttr = true;
3752 if (triggerSpell->AttributesCu & SPELL_ATTR0_CU_BINARY_SPELL)
3753 allNonBinary = false;
3754 }
3755 break;
3756 default:
3757 break;
3758 }
3759 }
3760 }
3761
3762 if (overrideAttr && allNonBinary)
3763 spellInfo->AttributesCu &= ~SPELL_ATTR0_CU_BINARY_SPELL;
3764 }
3765
3766 LOG_INFO("server.loading", ">> Loaded SpellInfo Custom Attributes in {} ms", GetMSTimeDiffToNow(oldMSTime));
3767 LOG_INFO("server.loading", " ");
3768}
@ ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL
Definition DBCEnums.h:367
DBCStorage< SpellVisualEntry > sSpellVisualStore(SpellVisualfmt)
DBCStorage< TalentEntry > sTalentStore(TalentEntryfmt)
#define MAX_TALENT_RANK
Definition DBCStructure.h:1918
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition DBCStructure.h:1838
#define sScriptMgr
Definition ScriptMgr.h:736
@ SPELL_EFFECT_ENERGIZE_PCT
Definition SharedDefines.h:903
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
Definition SharedDefines.h:801
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition SharedDefines.h:858
@ SPELL_EFFECT_ENCHANT_ITEM
Definition SharedDefines.h:819
@ SPELL_EFFECT_HEALTH_LEECH
Definition SharedDefines.h:775
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition SharedDefines.h:824
@ SPELL_EFFECT_HEAL
Definition SharedDefines.h:776
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
Definition SharedDefines.h:887
@ SPELL_EFFECT_TRIGGER_SPELL
Definition SharedDefines.h:830
@ SPELL_EFFECT_HEAL_MAX_HEALTH
Definition SharedDefines.h:833
@ SPELL_EFFECT_APPLY_AREA_AURA_PET
Definition SharedDefines.h:885
@ SPELL_EFFECT_PICKPOCKET
Definition SharedDefines.h:837
@ SPELL_EFFECT_HEAL_MECHANICAL
Definition SharedDefines.h:841
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
Definition SharedDefines.h:797
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
Definition SharedDefines.h:831
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition SharedDefines.h:783
@ SPELL_EFFECT_PERSISTENT_AREA_AURA
Definition SharedDefines.h:793
@ SPELL_EFFECT_ENERGIZE
Definition SharedDefines.h:796
@ SPELL_EFFECT_POWER_DRAIN
Definition SharedDefines.h:774
@ SPELL_EFFECT_SCHOOL_DAMAGE
Definition SharedDefines.h:768
@ SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
Definition SharedDefines.h:895
@ SPELL_EFFECT_HEAL_PCT
Definition SharedDefines.h:902
@ SPELL_EFFECT_INTERRUPT_CAST
Definition SharedDefines.h:834
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition SharedDefines.h:922
@ SPELL_EFFECT_APPLY_AREA_AURA_OWNER
Definition SharedDefines.h:909
@ SPELLFAMILY_WARLOCK
Definition SharedDefines.h:3789
@ SPELLFAMILY_DRUID
Definition SharedDefines.h:3791
SpellAttr0
Definition SharedDefines.h:369
@ SPELL_ATTR0_DO_NOT_DISPLAY
Definition SharedDefines.h:377
@ SKILL_ENCHANTING
Definition SharedDefines.h:3187
@ SPELL_SCHOOL_MASK_NORMAL
Definition SharedDefines.h:285
@ SPELL_AURA_PERIODIC_DAMAGE
Definition SpellAuraDefines.h:66
@ SPELL_AURA_PERIODIC_HEALTH_FUNNEL
Definition SpellAuraDefines.h:125
@ SPELL_AURA_MOD_POSSESS_PET
Definition SpellAuraDefines.h:191
@ SPELL_AURA_CONVERT_RUNE
Definition SpellAuraDefines.h:312
@ SPELL_AURA_MOD_FEAR
Definition SpellAuraDefines.h:70
@ SPELL_AURA_CONTROL_VEHICLE
Definition SpellAuraDefines.h:299
@ SPELL_AURA_MOD_INVISIBILITY
Definition SpellAuraDefines.h:81
@ SPELL_AURA_PERIODIC_DAMAGE_PERCENT
Definition SpellAuraDefines.h:152
@ SPELL_AURA_AOE_CHARM
Definition SpellAuraDefines.h:240
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE
Definition SpellAuraDefines.h:290
@ SPELL_AURA_MOD_INVISIBILITY_DETECT
Definition SpellAuraDefines.h:82
@ SPELL_AURA_WATER_BREATHING
Definition SpellAuraDefines.h:145
@ SPELL_AURA_PERIODIC_LEECH
Definition SpellAuraDefines.h:116
@ SPELL_AURA_OPEN_STABLE
Definition SpellAuraDefines.h:355
@ SPELL_AURA_MOD_CONFUSE
Definition SpellAuraDefines.h:68
@ SPELL_AURA_TRACK_CREATURES
Definition SpellAuraDefines.h:107
@ SPELL_AURA_MOD_POSSESS
Definition SpellAuraDefines.h:65
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT
Definition SpellAuraDefines.h:111
@ SPELL_AURA_BIND_SIGHT
Definition SpellAuraDefines.h:64
@ SPELL_ATTR0_CU_IGNORE_ARMOR
Definition SpellInfo.h:192
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition SpellInfo.h:193
@ SPELL_ATTR0_CU_ALLOW_INFLIGHT_TARGET
Definition SpellInfo.h:195
@ SPELL_ATTR0_CU_ENCHANT_PROC
Definition SpellInfo.h:177
@ SPELL_ATTR0_CU_NO_POSITIVE_TAKEN_BONUS
Definition SpellInfo.h:198
@ SPELL_ATTR0_CU_FORCE_SEND_CATEGORY_COOLDOWNS
Definition SpellInfo.h:205
@ SPELL_ATTR0_CU_DIRECT_DAMAGE
Definition SpellInfo.h:185
@ SPELL_ATTR0_CU_POSITIVE
Definition SpellInfo.h:212
@ SPELL_ATTR0_CU_FORCE_AURA_SAVING
Definition SpellInfo.h:206
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition SpellInfo.h:184
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition SpellInfo.h:183
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition SpellInfo.h:194
@ SPELL_ATTR0_CU_CONE_BACK
Definition SpellInfo.h:178
@ SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED
Definition SpellInfo.h:201
@ SPELL_ATTR0_CU_NEGATIVE_EFF2
Definition SpellInfo.h:191
@ SPELL_ATTR0_CU_AURA_CC
Definition SpellInfo.h:182
@ SPELL_ATTR0_CU_NEGATIVE_EFF1
Definition SpellInfo.h:190
@ SPELL_ATTR0_CU_CHARGE
Definition SpellInfo.h:186
@ SPELL_ATTR0_CU_NEGATIVE
Definition SpellInfo.h:211
@ SPELL_ATTR0_CU_NEEDS_AMMO_DATA
Definition SpellInfo.h:196
@ SPELL_ATTR0_CU_POSITIVE_EFF0
Definition SpellInfo.h:202
@ SPELL_ATTR0_CU_NEGATIVE_EFF0
Definition SpellInfo.h:189
@ SPELL_ATTR0_CU_BINARY_SPELL
Definition SpellInfo.h:197
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition SpellInfo.h:180
@ SPELL_ATTR0_CU_SCHOOLMASK_NORMAL_WITH_MAGIC
Definition SpellInfo.h:200
@ SPELL_ATTR0_CU_IGNORE_EVADE
Definition SpellInfo.h:188
@ SPELL_ATTR0_CU_PICKPOCKET
Definition SpellInfo.h:187
@ SPELL_ATTR0_CU_CONE_LINE
Definition SpellInfo.h:179
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition SpellInfo.h:181
bool IsPartOfSkillLine(uint32 skillId, uint32 spellId)
Definition SpellMgr.cpp:48
uint32 GetCategory() const
Definition SpellInfo.cpp:880
uint32 AttributesCu
Definition SpellInfo.h:356
bool _requireCooldownInfo
Definition SpellInfo.h:427
uint32 SchoolMask
Definition SpellInfo.h:416
std::array< uint32, 2 > SpellVisual
Definition SpellInfo.h:403
uint32 CategoryRecoveryTime
Definition SpellInfo.h:373
bool _IsPositiveEffect(uint8 effIndex, bool deep) const
Definition SpellInfo.cpp:3026
uint32 StartRecoveryTime
Definition SpellInfo.h:375
void _InitializeExplicitTargetMask()
Definition SpellInfo.cpp:2998
uint32 StartRecoveryCategory
Definition SpellInfo.h:374
uint32 AuraInterruptFlags
Definition SpellInfo.h:377
SpellCooldownOverride GetSpellCooldownOverride(uint32 spellId) const
Definition SpellMgr.cpp:2970
SpellInfo * _GetSpellInfo(uint32 spellId)
Definition SpellMgr.h:767
bool HasSpellCooldownOverride(uint32 spellId) const
Definition SpellMgr.cpp:2965
uint32 spellid[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition DBCStructure.h:1847
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition DBCStructure.h:1844
Definition DBCStructure.h:1871
Definition DBCStructure.h:1923
std::array< uint32, MAX_TALENT_RANK > RankID
Definition DBCStructure.h:1928

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

◆ LoadSpellInfoImmunities()

void SpellMgr::LoadSpellInfoImmunities ( )
3771{
3772 uint32 oldMSTime = getMSTime();
3773
3774 for (SpellInfo* spellInfo : mSpellInfoMap)
3775 {
3776 if (!spellInfo)
3777 continue;
3778 spellInfo->_LoadImmunityInfo();
3779 }
3780
3781 LOG_INFO("server.loading", ">> Loaded SpellInfo immunity infos in {} ms", GetMSTimeDiffToNow(oldMSTime));
3782}

References getMSTime(), GetMSTimeDiffToNow(), LOG_INFO, and mSpellInfoMap.

◆ LoadSpellInfoStore()

void SpellMgr::LoadSpellInfoStore ( )
2904{
2905 uint32 oldMSTime = getMSTime();
2906
2908 mSpellInfoMap.resize(sSpellStore.GetNumRows(), nullptr);
2909
2910 for (SpellEntry const* spellEntry : sSpellStore)
2911 mSpellInfoMap[spellEntry->Id] = new SpellInfo(spellEntry);
2912
2913 for (uint32 spellIndex = 0; spellIndex < GetSpellInfoStoreSize(); ++spellIndex)
2914 {
2915 if (!mSpellInfoMap[spellIndex])
2916 continue;
2917
2918 for (SpellEffectInfo const& spellEffectInfo : mSpellInfoMap[spellIndex]->GetEffects())
2919 {
2920 //ASSERT(effect.EffectIndex < MAX_SPELL_EFFECTS, "MAX_SPELL_EFFECTS must be at least {}", effect.EffectIndex + 1);
2921 ASSERT(spellEffectInfo.Effect < TOTAL_SPELL_EFFECTS, "TOTAL_SPELL_EFFECTS must be at least {}", spellEffectInfo.Effect + 1);
2922 ASSERT(spellEffectInfo.ApplyAuraName < TOTAL_AURAS, "TOTAL_AURAS must be at least {}", spellEffectInfo.ApplyAuraName + 1);
2923 ASSERT(spellEffectInfo.TargetA.GetTarget() < TOTAL_SPELL_TARGETS, "TOTAL_SPELL_TARGETS must be at least {}", spellEffectInfo.TargetA.GetTarget() + 1);
2924 ASSERT(spellEffectInfo.TargetB.GetTarget() < TOTAL_SPELL_TARGETS, "TOTAL_SPELL_TARGETS must be at least {}", spellEffectInfo.TargetB.GetTarget() + 1);
2925 }
2926 }
2927
2929
2930 LOG_INFO("server.loading", ">> Loaded Spell Custom Attributes in {} ms", GetMSTimeDiffToNow(oldMSTime));
2931 LOG_INFO("server.loading", " ");
2932}
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
@ TOTAL_SPELL_TARGETS
Definition SharedDefines.h:1518
void LoadCreatureImmunities()
Definition SpellMgr.cpp:63
Definition DBCStructure.h:1642

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

◆ LoadSpellJumpDistances()

void SpellMgr::LoadSpellJumpDistances ( )
3012{
3013 uint32 oldMSTime = getMSTime();
3014
3015 QueryResult result = WorldDatabase.Query("SELECT ID, JumpDistance FROM spell_jump_distance");
3016
3017 if (!result)
3018 {
3019 LOG_WARN("server.loading", ">> Loaded 0 spell jump distances. DB table `spell_jump_distance` is empty.");
3020 LOG_INFO("server.loading", " ");
3021 return;
3022 }
3023
3024 uint32 count = 0;
3025 do
3026 {
3027 Field const* fields = result->Fetch();
3028
3029 uint32 const spellId = fields[0].Get<uint32>();
3030 float const jumpDistance = fields[1].Get<float>();
3031
3032 SpellInfo* spellInfo = _GetSpellInfo(spellId);
3033 if (!spellInfo)
3034 {
3035 LOG_ERROR("sql.sql", "Table `spell_jump_distance` has wrong spell (spell_id: {}), ignored.", spellId);
3036 continue;
3037 }
3038
3039 spellInfo->JumpDistance = jumpDistance;
3040 ++count;
3041 } while (result->NextRow());
3042
3043 LOG_INFO("server.loading", ">> Loaded {} spell jump distances in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3044 LOG_INFO("server.loading", " ");
3045}

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

◆ LoadSpellLearnSkills()

void SpellMgr::LoadSpellLearnSkills ( )
1424{
1425 uint32 oldMSTime = getMSTime();
1426
1427 mSpellLearnSkills.clear(); // need for reload case
1428
1429 // search auto-learned skills and add its to map also for use in unlearn spells/talents
1430 uint32 dbc_count = 0;
1431 for (uint32 spell = 0; spell < GetSpellInfoStoreSize(); ++spell)
1432 {
1433 SpellInfo const* entry = GetSpellInfo(spell);
1434
1435 if (!entry)
1436 continue;
1437
1438 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1439 {
1440 SpellLearnSkillNode dbc_node;
1441 switch (entry->Effects[i].Effect)
1442 {
1443 case SPELL_EFFECT_SKILL:
1444 dbc_node.skill = entry->Effects[i].MiscValue;
1445 dbc_node.step = entry->Effects[i].CalcValue();
1446 if (dbc_node.skill != SKILL_RIDING)
1447 {
1448 dbc_node.value = 1;
1449 }
1450 else
1451 {
1452 dbc_node.value = dbc_node.step * 75;
1453 }
1454 dbc_node.maxvalue = dbc_node.step * 75;
1455 break;
1457 dbc_node.skill = SKILL_DUAL_WIELD;
1458 dbc_node.step = 1;
1459 dbc_node.value = 1;
1460 dbc_node.maxvalue = 1;
1461 break;
1462 default:
1463 continue;
1464 }
1465
1466 mSpellLearnSkills[spell] = dbc_node;
1467 ++dbc_count;
1468 break;
1469 }
1470 }
1471
1472 LOG_INFO("server.loading", ">> Loaded {} Spell Learn Skills From DBC in {} ms", dbc_count, GetMSTimeDiffToNow(oldMSTime));
1473 LOG_INFO("server.loading", " ");
1474}
@ SPELL_EFFECT_SKILL
Definition SharedDefines.h:884
@ SPELL_EFFECT_DUAL_WIELD
Definition SharedDefines.h:806
@ SKILL_DUAL_WIELD
Definition SharedDefines.h:3121
@ SKILL_RIDING
Definition SharedDefines.h:3224
Definition SpellMgr.h:576
uint16 value
Definition SpellMgr.h:579
uint16 step
Definition SpellMgr.h:578
uint16 maxvalue
Definition SpellMgr.h:580
uint16 skill
Definition SpellMgr.h:577

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 ( )
2466{
2467 uint32 oldMSTime = getMSTime();
2468
2469 mSpellLinkedMap.clear(); // need for reload case
2470
2471 // 0 1 2
2472 QueryResult result = WorldDatabase.Query("SELECT spell_trigger, spell_effect, type FROM spell_linked_spell");
2473 if (!result)
2474 {
2475 LOG_WARN("server.loading", ">> Loaded 0 linked spells. DB table `spell_linked_spell` is empty.");
2476 LOG_INFO("server.loading", " ");
2477 return;
2478 }
2479
2480 uint32 count = 0;
2481 do
2482 {
2483 Field* fields = result->Fetch();
2484
2485 int32 trigger = fields[0].Get<int32>();
2486 int32 effect = fields[1].Get<int32>();
2487 int32 type = fields[2].Get<uint8>();
2488
2489 SpellInfo const* spellInfo = GetSpellInfo(std::abs(trigger));
2490 if (!spellInfo)
2491 {
2492 LOG_ERROR("sql.sql", "Spell {} listed in `spell_linked_spell` does not exist", std::abs(trigger));
2493 continue;
2494 }
2495 spellInfo = GetSpellInfo(std::abs(effect));
2496 if (!spellInfo)
2497 {
2498 LOG_ERROR("sql.sql", "Spell {} listed in `spell_linked_spell` does not exist", std::abs(effect));
2499 continue;
2500 }
2501
2502 if (type) //we will find a better way when more types are needed
2503 {
2504 if (trigger > 0)
2505 trigger += SPELL_LINKED_MAX_SPELLS * type;
2506 else
2507 trigger -= SPELL_LINKED_MAX_SPELLS * type;
2508 }
2509 mSpellLinkedMap[trigger].push_back(effect);
2510
2511 ++count;
2512 } while (result->NextRow());
2513
2514 LOG_INFO("server.loading", ">> Loaded {} Linked Spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2515 LOG_INFO("server.loading", " ");
2516}
#define SPELL_LINKED_MAX_SPELLS
Definition SpellMgr.h:95

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

◆ LoadSpellMixology()

void SpellMgr::LoadSpellMixology ( )
2259{
2260 uint32 oldMSTime = getMSTime();
2261
2262 mSpellMixologyMap.clear(); // need for reload case
2263
2264 // 0 1
2265 QueryResult result = WorldDatabase.Query("SELECT entry, pctMod FROM spell_mixology");
2266 if (!result)
2267 {
2268 LOG_WARN("server.loading", ">> Loaded 0 mixology bonuses. DB table `spell_mixology` is empty.");
2269 LOG_INFO("server.loading", " ");
2270 return;
2271 }
2272
2273 uint32 count = 0;
2274 do
2275 {
2276 Field* fields = result->Fetch();
2277
2278 uint32 entry = fields[0].Get<uint32>();
2279
2280 if (!GetSpellInfo(entry))
2281 {
2282 LOG_ERROR("sql.sql", "Spell {} listed in `spell_mixology` does not exist", entry);
2283 continue;
2284 }
2285
2286 mSpellMixologyMap[entry] = fields[1].Get<float>();
2287 ++count;
2288 } while (result->NextRow());
2289
2290 LOG_INFO("server.loading", ">> Loaded {} Mixology Bonuses in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2291 LOG_INFO("server.loading", " ");
2292}

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

◆ LoadSpellPetAuras()

void SpellMgr::LoadSpellPetAuras ( )
2317{
2318 uint32 oldMSTime = getMSTime();
2319
2320 mSpellPetAuraMap.clear(); // need for reload case
2321
2322 // 0 1 2 3
2323 QueryResult result = WorldDatabase.Query("SELECT spell, effectId, pet, aura FROM spell_pet_auras");
2324 if (!result)
2325 {
2326 LOG_WARN("server.loading", ">> Loaded 0 spell pet auras. DB table `spell_pet_auras` is empty.");
2327 LOG_INFO("server.loading", " ");
2328 return;
2329 }
2330
2331 uint32 count = 0;
2332 do
2333 {
2334 Field* fields = result->Fetch();
2335
2336 uint32 spell = fields[0].Get<uint32>();
2337 uint8 eff = fields[1].Get<uint8>();
2338 uint32 pet = fields[2].Get<uint32>();
2339 uint32 aura = fields[3].Get<uint32>();
2340
2341 SpellPetAuraMap::iterator itr = mSpellPetAuraMap.find((spell << 8) + eff);
2342 if (itr != mSpellPetAuraMap.end())
2343 itr->second.AddAura(pet, aura);
2344 else
2345 {
2346 SpellInfo const* spellInfo = GetSpellInfo(spell);
2347 if (!spellInfo)
2348 {
2349 LOG_ERROR("sql.sql", "Spell {} listed in `spell_pet_auras` does not exist", spell);
2350 continue;
2351 }
2352 if (spellInfo->Effects[eff].Effect != SPELL_EFFECT_DUMMY &&
2353 (spellInfo->Effects[eff].Effect != SPELL_EFFECT_APPLY_AURA ||
2354 spellInfo->Effects[eff].ApplyAuraName != SPELL_AURA_DUMMY))
2355 {
2356 LOG_ERROR("spells", "Spell {} listed in `spell_pet_auras` does not have dummy aura or dummy effect", spell);
2357 continue;
2358 }
2359
2360 SpellInfo const* spellInfo2 = GetSpellInfo(aura);
2361 if (!spellInfo2)
2362 {
2363 LOG_ERROR("sql.sql", "Aura {} listed in `spell_pet_auras` does not exist", aura);
2364 continue;
2365 }
2366
2367 PetAura pa(pet, aura, spellInfo->Effects[eff].TargetA.GetTarget() == TARGET_UNIT_PET, spellInfo->Effects[eff].CalcValue());
2368 mSpellPetAuraMap[(spell << 8) + eff] = pa;
2369 }
2370
2371 ++count;
2372 } while (result->NextRow());
2373
2374 LOG_INFO("server.loading", ">> Loaded {} Spell Pet Auras in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2375 LOG_INFO("server.loading", " ");
2376}
Definition SpellMgr.h:460

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.

◆ LoadSpellProcs()

void SpellMgr::LoadSpellProcs ( )
1888{
1889 uint32 oldMSTime = getMSTime();
1890
1891 mSpellProcMap.clear(); // need for reload case
1892
1893 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1894 QueryResult result = WorldDatabase.Query("SELECT SpellId, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, ProcFlags, SpellTypeMask, SpellPhaseMask, HitMask, AttributesMask, DisableEffectsMask, ProcsPerMinute, Chance, Cooldown, Charges FROM spell_proc");
1895 if (!result)
1896 {
1897 LOG_WARN("server.loading", ">> Loaded 0 Spell Proc Conditions And Data. DB table `spell_proc` Is Empty.");
1898 LOG_INFO("server.loading", " ");
1899 return;
1900 }
1901
1902 uint32 count = 0;
1903 do
1904 {
1905 Field* fields = result->Fetch();
1906
1907 int32 spellId = fields[0].Get<int32>();
1908
1909 bool allRanks = false;
1910 if (spellId < 0)
1911 {
1912 allRanks = true;
1913 spellId = -spellId;
1914 }
1915
1916 SpellInfo const* spellInfo = GetSpellInfo(spellId);
1917 if (!spellInfo)
1918 {
1919 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` does not exist", spellId);
1920 continue;
1921 }
1922
1923 if (allRanks)
1924 {
1925 if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId))
1926 {
1927 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` is not first rank of spell.", fields[0].Get<int32>());
1928 continue;
1929 }
1930 }
1931
1932 SpellProcEntry baseProcEntry;
1933
1934 baseProcEntry.SchoolMask = fields[1].Get<int8>();
1935 baseProcEntry.SpellFamilyName = fields[2].Get<uint16>();
1936 baseProcEntry.SpellFamilyMask[0] = fields[3].Get<uint32>();
1937 baseProcEntry.SpellFamilyMask[1] = fields[4].Get<uint32>();
1938 baseProcEntry.SpellFamilyMask[2] = fields[5].Get<uint32>();
1939 baseProcEntry.ProcFlags = fields[6].Get<uint32>();
1940 baseProcEntry.SpellTypeMask = fields[7].Get<uint32>();
1941 baseProcEntry.SpellPhaseMask = fields[8].Get<uint32>();
1942 baseProcEntry.HitMask = fields[9].Get<uint32>();
1943 baseProcEntry.AttributesMask = fields[10].Get<uint32>();
1944 baseProcEntry.DisableEffectsMask = fields[11].Get<uint32>();
1945 baseProcEntry.ProcsPerMinute = fields[12].Get<float>();
1946 baseProcEntry.Chance = fields[13].Get<float>();
1947 baseProcEntry.Cooldown = Milliseconds(fields[14].Get<uint32>());
1948 baseProcEntry.Charges = fields[15].Get<uint32>();
1949
1950 while (spellInfo)
1951 {
1952 if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end())
1953 {
1954 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` has duplicate entry in the table", spellId);
1955 break;
1956 }
1957 SpellProcEntry procEntry = SpellProcEntry(baseProcEntry);
1958
1959 // take defaults from dbcs
1960 if (!procEntry.ProcFlags)
1961 procEntry.ProcFlags = spellInfo->ProcFlags;
1962 if (!procEntry.Charges)
1963 procEntry.Charges = spellInfo->ProcCharges;
1964 if (!procEntry.Chance && !procEntry.ProcsPerMinute)
1965 procEntry.Chance = float(spellInfo->ProcChance);
1966
1967 // validate data
1968 if (procEntry.SchoolMask & ~SPELL_SCHOOL_MASK_ALL)
1969 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SchoolMask` set: {}", spellId, procEntry.SchoolMask);
1970 if (procEntry.SpellFamilyName && (procEntry.SpellFamilyName < 3 || procEntry.SpellFamilyName > 17 || procEntry.SpellFamilyName == 14 || procEntry.SpellFamilyName == 16))
1971 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellFamilyName` set: {}", spellId, procEntry.SpellFamilyName);
1972 if (procEntry.Chance < 0)
1973 {
1974 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `Chance` field", spellId);
1975 procEntry.Chance = 0;
1976 }
1977 if (procEntry.ProcsPerMinute < 0)
1978 {
1979 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `ProcsPerMinute` field", spellId);
1980 procEntry.ProcsPerMinute = 0;
1981 }
1982 if (procEntry.Charges > 99)
1983 {
1984 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has too big value in `Charges` field", spellId);
1985 procEntry.Charges = 99;
1986 }
1987 if (!procEntry.ProcFlags)
1988 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} doesn't have `ProcFlags` value defined, proc will not be triggered", spellId);
1989 if (procEntry.SpellTypeMask & ~PROC_SPELL_TYPE_MASK_ALL)
1990 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellTypeMask` set: {}", spellId, procEntry.SpellTypeMask);
1991 if (procEntry.SpellTypeMask && !(procEntry.ProcFlags & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK)))
1992 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);
1993 if (!procEntry.SpellPhaseMask && procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK)
1994 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);
1996 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellPhaseMask` set: {}", spellId, procEntry.SpellPhaseMask);
1997 if (procEntry.SpellPhaseMask && !(procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK))
1998 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);
1999 if (procEntry.HitMask & ~PROC_HIT_MASK_ALL)
2000 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `HitMask` set: {}", spellId, procEntry.HitMask);
2001 // HitMask is valid for: TAKEN procs, or DONE procs at any phase (CAST phase has pre-calculated crit for travel-time spells)
2002 if (procEntry.HitMask && !(procEntry.ProcFlags & TAKEN_HIT_PROC_FLAG_MASK || procEntry.ProcFlags & DONE_HIT_PROC_FLAG_MASK))
2003 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);
2004 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2005 if ((procEntry.DisableEffectsMask & (1u << i)) && !spellInfo->Effects[i].IsAura())
2006 LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId {} has DisableEffectsMask with effect {}, but effect {} is not an aura effect", spellId, static_cast<uint32>(i), static_cast<uint32>(i));
2007 if (procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD)
2008 {
2009 bool found = false;
2010 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2011 {
2012 if (!spellInfo->Effects[i].IsAura())
2013 continue;
2014
2015 if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_ADD_PCT_MODIFIER || spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_ADD_FLAT_MODIFIER
2016 || spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_SPELL_CRIT_CHANCE || spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL)
2017 {
2018 found = true;
2019 break;
2020 }
2021 }
2022
2023 if (!found)
2024 LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId {} has Attribute PROC_ATTR_REQ_SPELLMOD, but spell has no spell mods. Proc will not be triggered", spellId);
2025 }
2026
2027 mSpellProcMap[spellInfo->Id] = procEntry;
2028
2029 if (allRanks)
2030 spellInfo = spellInfo->GetNextRankSpell();
2031 else
2032 break;
2033 }
2034 ++count;
2035 } while (result->NextRow());
2036
2037 LOG_INFO("server.loading", ">> Loaded {} spell proc conditions and data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2038 LOG_INFO("server.loading", " ");
2039
2040 // Generate default procs for spells with proc flags but no explicit spell_proc entry
2041 // This ensures backward compatibility and covers spells that rely on DBC data
2042 LOG_INFO("server.loading", "Generating spell proc data from SpellMap...");
2043 count = 0;
2044 oldMSTime = getMSTime();
2045
2046 for (SpellInfo const* spellInfo : mSpellInfoMap)
2047 {
2048 if (!spellInfo)
2049 continue;
2050
2051 // Skip if already has explicit entry
2052 if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end())
2053 continue;
2054
2055 // Check if spell has any trigger aura effects
2056 bool found = false, addTriggerFlag = false;
2057 uint32 procSpellTypeMask = PROC_SPELL_TYPE_NONE;
2058 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2059 {
2060 if (!spellInfo->Effects[i].IsEffect())
2061 continue;
2062
2063 uint32 auraName = spellInfo->Effects[i].ApplyAuraName;
2064 if (!auraName)
2065 continue;
2066
2067 if (!isTriggerAura[auraName])
2068 continue;
2069
2070 found = true;
2071 procSpellTypeMask |= spellTypeMask[auraName];
2072
2073 if (!addTriggerFlag && isAlwaysTriggeredAura[auraName])
2074 addTriggerFlag = true;
2075
2076 // Many proc auras with taken procFlag mask don't have
2077 // attribute "can proc with triggered" — they should
2078 // proc nevertheless (e.g. mage armor spells with
2079 // judgement)
2080 if (!addTriggerFlag
2081 && (spellInfo->ProcFlags & TAKEN_HIT_PROC_FLAG_MASK))
2082 {
2083 switch (auraName)
2084 {
2087 addTriggerFlag = true;
2088 break;
2089 default:
2090 break;
2091 }
2092 }
2093 }
2094
2095 if (!found)
2096 continue;
2097
2098 // Skip if no proc flags in DBC
2099 if (!spellInfo->ProcFlags)
2100 continue;
2101
2102 // Generate default proc entry from DBC data
2103 SpellProcEntry procEntry;
2104 procEntry.SchoolMask = 0;
2105 procEntry.SpellFamilyMask[0] = 0;
2106 procEntry.SpellFamilyMask[1] = 0;
2107 procEntry.SpellFamilyMask[2] = 0;
2108 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2109 if (spellInfo->Effects[i].IsEffect() && isTriggerAura[spellInfo->Effects[i].ApplyAuraName])
2110 procEntry.SpellFamilyMask |= spellInfo->Effects[i].SpellClassMask;
2111
2112 if (procEntry.SpellFamilyMask)
2113 procEntry.SpellFamilyName = spellInfo->SpellFamilyName;
2114 else
2115 procEntry.SpellFamilyName = 0;
2116
2117 procEntry.ProcFlags = spellInfo->ProcFlags;
2118 procEntry.SpellTypeMask = procSpellTypeMask;
2120 procEntry.HitMask = PROC_HIT_NONE; // uses default proc @see SpellMgr::CanSpellTriggerProcOnEvent
2121
2122 // Reflect auras should only proc off reflects
2123 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2124 {
2125 if (spellInfo->Effects[i].IsAura(SPELL_AURA_REFLECT_SPELLS) || spellInfo->Effects[i].IsAura(SPELL_AURA_REFLECT_SPELLS_SCHOOL))
2126 {
2127 procEntry.HitMask = PROC_HIT_REFLECT;
2128 break;
2129 }
2130 }
2131
2132 procEntry.AttributesMask = 0;
2133 if (spellInfo->ProcFlags & PROC_FLAG_KILL)
2135 if (addTriggerFlag)
2137
2138 // Modifier auras with charges should require spellmod validation
2139 if (spellInfo->ProcCharges)
2140 {
2141 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2142 {
2143 if (spellInfo->Effects[i].IsAura(SPELL_AURA_ADD_FLAT_MODIFIER) ||
2144 spellInfo->Effects[i].IsAura(SPELL_AURA_ADD_PCT_MODIFIER))
2145 {
2147 break;
2148 }
2149 }
2150 }
2151
2152 // Calculate DisableEffectsMask for effects that shouldn't trigger procs
2153 uint32 nonProcMask = 0;
2154 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2155 {
2156 if (!spellInfo->Effects[i].IsAura())
2157 continue;
2158 if (!isTriggerAura[spellInfo->Effects[i].ApplyAuraName])
2159 nonProcMask |= 1u << i;
2160 }
2161 procEntry.DisableEffectsMask = nonProcMask;
2162
2163 procEntry.ProcsPerMinute = 0;
2164 procEntry.Chance = static_cast<float>(spellInfo->ProcChance);
2165 procEntry.Cooldown = Milliseconds::zero();
2166 procEntry.Charges = spellInfo->ProcCharges;
2167
2168 mSpellProcMap[spellInfo->Id] = procEntry;
2169 ++count;
2170 }
2171
2172 LOG_INFO("server.loading", ">> Generated spell proc data for {} spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2173 LOG_INFO("server.loading", " ");
2174}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:27
@ SPELL_SCHOOL_MASK_ALL
Definition SharedDefines.h:303
@ SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL
Definition SpellAuraDefines.h:134
@ SPELL_AURA_REFLECT_SPELLS
Definition SpellAuraDefines.h:91
@ SPELL_AURA_MOD_SPELL_CRIT_CHANCE
Definition SpellAuraDefines.h:120
@ SPELL_AURA_PROC_TRIGGER_DAMAGE
Definition SpellAuraDefines.h:106
@ SPELL_AURA_REFLECT_SPELLS_SCHOOL
Definition SpellAuraDefines.h:137
static bool isAlwaysTriggeredAura[TOTAL_AURAS]
Definition SpellMgr.cpp:1818
static uint32 spellTypeMask[TOTAL_AURAS]
Definition SpellMgr.cpp:1819
static bool isTriggerAura[TOTAL_AURAS]
Definition SpellMgr.cpp:1817
@ PROC_HIT_NONE
Definition SpellMgr.h:256
@ PROC_HIT_MASK_ALL
Definition SpellMgr.h:271
@ PROC_HIT_REFLECT
Definition SpellMgr.h:268
@ PROC_ATTR_TRIGGERED_CAN_PROC
Definition SpellMgr.h:277
@ PROC_ATTR_REQ_SPELLMOD
Definition SpellMgr.h:279
@ PROC_SPELL_TYPE_NONE
Definition SpellMgr.h:238
@ PROC_SPELL_TYPE_MASK_ALL
Definition SpellMgr.h:242
@ PROC_SPELL_PHASE_HIT
Definition SpellMgr.h:249
@ PROC_SPELL_PHASE_MASK_ALL
Definition SpellMgr.h:251
SpellInfo const * GetFirstRankSpell() const
Definition SpellInfo.cpp:2903
uint32 ProcCharges
Definition SpellInfo.h:381
uint32 ProcFlags
Definition SpellInfo.h:379
uint32 ProcChance
Definition SpellInfo.h:380
Definition SpellMgr.h:286
uint32 SpellFamilyName
Definition SpellMgr.h:288
float ProcsPerMinute
Definition SpellMgr.h:296
Milliseconds Cooldown
Definition SpellMgr.h:298
uint32 Charges
Definition SpellMgr.h:299
uint32 AttributesMask
Definition SpellMgr.h:294
flag96 SpellFamilyMask
Definition SpellMgr.h:289
uint32 HitMask
Definition SpellMgr.h:293
uint32 SpellTypeMask
Definition SpellMgr.h:291
uint32 ProcFlags
Definition SpellMgr.h:290
uint32 SpellPhaseMask
Definition SpellMgr.h:292
uint32 SchoolMask
Definition SpellMgr.h:287
uint32 DisableEffectsMask
Definition SpellMgr.h:295
float Chance
Definition SpellMgr.h:297

References SpellProcEntry::AttributesMask, SpellProcEntry::Chance, SpellProcEntry::Charges, SpellProcEntry::Cooldown, SpellProcEntry::DisableEffectsMask, DONE_HIT_PROC_FLAG_MASK, SpellInfo::Effects, Field::Get(), SpellInfo::GetFirstRankSpell(), getMSTime(), GetMSTimeDiffToNow(), SpellInfo::GetNextRankSpell(), GetSpellInfo(), SpellProcEntry::HitMask, SpellInfo::Id, isAlwaysTriggeredAura, isTriggerAura, LOG_ERROR, LOG_INFO, LOG_WARN, MAX_SPELL_EFFECTS, mSpellInfoMap, mSpellProcMap, PERIODIC_PROC_FLAG_MASK, PROC_ATTR_REQ_EXP_OR_HONOR, PROC_ATTR_REQ_SPELLMOD, PROC_ATTR_TRIGGERED_CAN_PROC, PROC_FLAG_KILL, PROC_HIT_MASK_ALL, PROC_HIT_NONE, PROC_HIT_REFLECT, PROC_SPELL_PHASE_HIT, PROC_SPELL_PHASE_MASK_ALL, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_TYPE_NONE, SpellInfo::ProcChance, SpellInfo::ProcCharges, SpellInfo::ProcFlags, SpellProcEntry::ProcFlags, SpellProcEntry::ProcsPerMinute, REQ_SPELL_PHASE_PROC_FLAG_MASK, SpellProcEntry::SchoolMask, SPELL_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_ADD_PCT_MODIFIER, SPELL_AURA_MOD_SPELL_CRIT_CHANCE, SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL, SPELL_AURA_PROC_TRIGGER_DAMAGE, SPELL_AURA_PROC_TRIGGER_SPELL, SPELL_AURA_REFLECT_SPELLS, SPELL_AURA_REFLECT_SPELLS_SCHOOL, SPELL_PROC_FLAG_MASK, SPELL_SCHOOL_MASK_ALL, SpellProcEntry::SpellFamilyMask, SpellProcEntry::SpellFamilyName, SpellProcEntry::SpellPhaseMask, spellTypeMask, SpellProcEntry::SpellTypeMask, TAKEN_HIT_PROC_FLAG_MASK, and WorldDatabase.

◆ LoadSpellRanks()

void SpellMgr::LoadSpellRanks ( )
1248{
1249 // cleanup data and load spell ranks for talents from dbc
1251
1252 uint32 oldMSTime = getMSTime();
1253
1254 // 0 1 2
1255 QueryResult result = WorldDatabase.Query("SELECT first_spell_id, spell_id, `rank` from spell_ranks ORDER BY first_spell_id, `rank`");
1256
1257 if (!result)
1258 {
1259 LOG_WARN("server.loading", ">> Loaded 0 spell rank records. DB table `spell_ranks` is empty.");
1260 LOG_INFO("server.loading", " ");
1261 return;
1262 }
1263
1264 uint32 count = 0;
1265 bool finished = false;
1266
1267 do
1268 {
1269 // spellid, rank
1270 std::list < std::pair < int32, int32 > > rankChain;
1271 int32 currentSpell = -1;
1272 int32 lastSpell = -1;
1273
1274 // fill one chain
1275 while (currentSpell == lastSpell && !finished)
1276 {
1277 Field* fields = result->Fetch();
1278
1279 currentSpell = fields[0].Get<uint32>();
1280 if (lastSpell == -1)
1281 lastSpell = currentSpell;
1282 uint32 spell_id = fields[1].Get<uint32>();
1283 uint32 rank = fields[2].Get<uint8>();
1284
1285 // don't drop the row if we're moving to the next rank
1286 if (currentSpell == lastSpell)
1287 {
1288 rankChain.push_back(std::make_pair(spell_id, rank));
1289 if (!result->NextRow())
1290 finished = true;
1291 }
1292 else
1293 break;
1294 }
1295 // check if chain is made with valid first spell
1296 SpellInfo const* first = GetSpellInfo(lastSpell);
1297 if (!first)
1298 {
1299 LOG_ERROR("sql.sql", "Spell rank identifier(first_spell_id) {} listed in `spell_ranks` does not exist!", lastSpell);
1300 continue;
1301 }
1302 // check if chain is long enough
1303 if (rankChain.size() < 2)
1304 {
1305 LOG_ERROR("sql.sql", "There is only 1 spell rank for identifier(first_spell_id) {} in `spell_ranks`, entry is not needed!", lastSpell);
1306 continue;
1307 }
1308 int32 curRank = 0;
1309 bool valid = true;
1310 // check spells in chain
1311 for (std::list<std::pair<int32, int32> >::iterator itr = rankChain.begin(); itr != rankChain.end(); ++itr)
1312 {
1313 SpellInfo const* spell = GetSpellInfo(itr->first);
1314 if (!spell)
1315 {
1316 LOG_ERROR("sql.sql", "Spell {} (rank {}) listed in `spell_ranks` for chain {} does not exist!", itr->first, itr->second, lastSpell);
1317 valid = false;
1318 break;
1319 }
1320 ++curRank;
1321 if (itr->second != curRank)
1322 {
1323 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);
1324 valid = false;
1325 break;
1326 }
1327 }
1328 if (!valid)
1329 continue;
1330 int32 prevRank = 0;
1331 // insert the chain
1332 std::list<std::pair<int32, int32> >::iterator itr = rankChain.begin();
1333 do
1334 {
1335 ++count;
1336 int32 addedSpell = itr->first;
1337 mSpellChains[addedSpell].first = GetSpellInfo(lastSpell);
1338 mSpellChains[addedSpell].last = GetSpellInfo(rankChain.back().first);
1339 mSpellChains[addedSpell].rank = itr->second;
1340 mSpellChains[addedSpell].prev = GetSpellInfo(prevRank);
1341 mSpellInfoMap[addedSpell]->ChainEntry = &mSpellChains[addedSpell];
1342 prevRank = addedSpell;
1343 ++itr;
1344 if (itr == rankChain.end())
1345 {
1346 mSpellChains[addedSpell].next = nullptr;
1347 break;
1348 }
1349 else
1350 mSpellChains[addedSpell].next = GetSpellInfo(itr->first);
1351 } while (true);
1352 } while (!finished);
1353
1354 LOG_INFO("server.loading", ">> Loaded {} spell rank records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1355 LOG_INFO("server.loading", " ");
1356}
void LoadSpellTalentRanks()
Definition SpellMgr.cpp:1186

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

◆ LoadSpellRequired()

void SpellMgr::LoadSpellRequired ( )
1359{
1360 uint32 oldMSTime = getMSTime();
1361
1362 mSpellsReqSpell.clear(); // need for reload case
1363 mSpellReq.clear(); // need for reload case
1364
1365 // 0 1
1366 QueryResult result = WorldDatabase.Query("SELECT spell_id, req_spell from spell_required");
1367
1368 if (!result)
1369 {
1370 LOG_WARN("server.loading", ">> Loaded 0 spell required records. DB table `spell_required` is empty.");
1371 LOG_INFO("server.loading", " ");
1372 return;
1373 }
1374
1375 uint32 count = 0;
1376 do
1377 {
1378 Field* fields = result->Fetch();
1379
1380 uint32 spellId = fields[0].Get<uint32>();
1381 uint32 spellReq = fields[1].Get<uint32>();
1382
1383 // check if chain is made with valid first spell
1384 SpellInfo const* spellInfo = GetSpellInfo(spellId);
1385 if (!spellInfo)
1386 {
1387 LOG_ERROR("sql.sql", "spell_id {} in `spell_required` table is not found in dbcs, skipped", spellId);
1388 continue;
1389 }
1390
1391 SpellInfo const* reqSpellInfo = GetSpellInfo(spellReq);
1392 if (!reqSpellInfo)
1393 {
1394 LOG_ERROR("sql.sql", "req_spell {} in `spell_required` table is not found in dbcs, skipped", spellReq);
1395 continue;
1396 }
1397
1398 if (GetFirstSpellInChain(spellId) == GetFirstSpellInChain(spellReq))
1399 {
1400 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);
1401 continue;
1402 }
1403
1404 if (IsSpellRequiringSpell(spellId, spellReq))
1405 {
1406 LOG_ERROR("sql.sql", "duplicated entry of req_spell {} and spell_id {} in `spell_required`, skipped", spellReq, spellId);
1407 continue;
1408 }
1409
1410 mSpellReq.insert (std::pair<uint32, uint32>(spellId, spellReq));
1411 mSpellsReqSpell.insert (std::pair<uint32, uint32>(spellReq, spellId));
1412 ++count;
1413
1414 // xinef: fill additionalTalentInfo data, currently Blessing of Sanctuary only
1415 if (GetTalentSpellCost(spellReq) > 0)
1416 mTalentSpellAdditionalSet.insert(spellId);
1417 } while (result->NextRow());
1418
1419 LOG_INFO("server.loading", ">> Loaded {} Spell Required Records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1420 LOG_INFO("server.loading", " ");
1421}
uint32 GetTalentSpellCost(uint32 spellId)
Definition DBCStores.cpp:686
bool IsSpellRequiringSpell(uint32 spellid, uint32 req_spellid) const
Definition SpellMgr.cpp:665

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

◆ LoadSpellSpecificAndAuraState()

void SpellMgr::LoadSpellSpecificAndAuraState ( )
2994{
2995 uint32 oldMSTime = getMSTime();
2996
2997 SpellInfo* spellInfo = nullptr;
2998 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2999 {
3000 spellInfo = mSpellInfoMap[i];
3001 if (!spellInfo)
3002 continue;
3003 spellInfo->_spellSpecific = spellInfo->LoadSpellSpecific();
3004 spellInfo->_auraState = spellInfo->LoadAuraState();
3005 }
3006
3007 LOG_INFO("server.loading", ">> Loaded Spell Specific And Aura State in {} ms", GetMSTimeDiffToNow(oldMSTime));
3008 LOG_INFO("server.loading", " ");
3009}
SpellSpecificType LoadSpellSpecific() const
Definition SpellInfo.cpp:2054
AuraStateType LoadAuraState() const
Definition SpellInfo.cpp:1972
AuraStateType _auraState
Definition SpellInfo.h:422
SpellSpecificType _spellSpecific
Definition SpellInfo.h:423

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

◆ LoadSpellTalentRanks()

void SpellMgr::LoadSpellTalentRanks ( )
1187{
1188 // cleanup core data before reload - remove reference to ChainNode from SpellInfo
1190
1191 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1192 {
1193 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
1194 if (!talentInfo)
1195 continue;
1196
1197 SpellInfo const* lastSpell = nullptr;
1198 for (uint8 rank = MAX_TALENT_RANK - 1; rank > 0; --rank)
1199 {
1200 if (talentInfo->RankID[rank])
1201 {
1202 lastSpell = GetSpellInfo(talentInfo->RankID[rank]);
1203 break;
1204 }
1205 }
1206
1207 if (!lastSpell)
1208 continue;
1209
1210 SpellInfo const* firstSpell = GetSpellInfo(talentInfo->RankID[0]);
1211 if (!firstSpell)
1212 {
1213 LOG_ERROR("sql.sql", "SpellMgr::LoadSpellTalentRanks: First Rank Spell {} for TalentEntry {} does not exist.", talentInfo->RankID[0], i);
1214 continue;
1215 }
1216
1217 SpellInfo const* prevSpell = nullptr;
1218 for (uint8 rank = 0; rank < MAX_TALENT_RANK; ++rank)
1219 {
1220 uint32 spellId = talentInfo->RankID[rank];
1221 if (!spellId)
1222 break;
1223
1224 SpellInfo const* currentSpell = GetSpellInfo(spellId);
1225 if (!currentSpell)
1226 {
1227 LOG_ERROR("sql.sql", "SpellMgr::LoadSpellTalentRanks: Spell {} (Rank: {}) for TalentEntry {} does not exist.", spellId, rank + 1, i);
1228 break;
1229 }
1230
1231 SpellChainNode node;
1232 node.first = firstSpell;
1233 node.last = lastSpell;
1234 node.rank = rank + 1;
1235
1236 node.prev = prevSpell;
1237 node.next = node.rank < MAX_TALENT_RANK ? GetSpellInfo(talentInfo->RankID[node.rank]) : nullptr;
1238
1239 mSpellChains[spellId] = node;
1240 mSpellInfoMap[spellId]->ChainEntry = &mSpellChains[spellId];
1241
1242 prevSpell = currentSpell;
1243 }
1244 }
1245}
void UnloadSpellInfoChains()
Definition SpellMgr.cpp:1178
SpellInfo const * last
Definition SpellMgr.h:548
SpellInfo const * next
Definition SpellMgr.h:546
uint8 rank
Definition SpellMgr.h:549
SpellInfo const * first
Definition SpellMgr.h:547
SpellInfo const * prev
Definition SpellMgr.h:545

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 ( )
1477{
1478 uint32 oldMSTime = getMSTime();
1479
1480 mSpellTargetPositions.clear(); // need for reload case
1481
1482 // 0 1 2 3 4 5 6
1483 QueryResult result = WorldDatabase.Query("SELECT ID, EffectIndex, MapID, PositionX, PositionY, PositionZ, Orientation FROM spell_target_position");
1484
1485 if (!result)
1486 {
1487 LOG_WARN("server.loading", ">> Loaded 0 spell target coordinates. DB table `spell_target_position` is empty.");
1488 LOG_INFO("server.loading", " ");
1489 return;
1490 }
1491
1492 uint32 count = 0;
1493 do
1494 {
1495 Field* fields = result->Fetch();
1496
1497 uint32 Spell_ID = fields[0].Get<uint32>();
1498
1499 SpellEffIndex effIndex = SpellEffIndex(fields[1].Get<uint8>());
1500
1502
1503 st.target_mapId = fields[2].Get<uint16>();
1504 st.target_X = fields[3].Get<float>();
1505 st.target_Y = fields[4].Get<float>();
1506 st.target_Z = fields[5].Get<float>();
1507 st.target_Orientation = fields[6].Get<float>();
1508
1509 MapEntry const* mapEntry = sMapStore.LookupEntry(st.target_mapId);
1510 if (!mapEntry)
1511 {
1512 LOG_ERROR("sql.sql", "Spell (Id: {}, effIndex: {}) target map (ID: {}) does not exist in `Map.dbc`.", Spell_ID, effIndex, st.target_mapId);
1513 continue;
1514 }
1515
1516 if (st.target_X == 0 && st.target_Y == 0 && st.target_Z == 0)
1517 {
1518 LOG_ERROR("sql.sql", "Spell (Id: {}, effIndex: {}) target coordinates not provided.", Spell_ID, effIndex);
1519 continue;
1520 }
1521
1522 SpellInfo const* spellInfo = GetSpellInfo(Spell_ID);
1523 if (!spellInfo)
1524 {
1525 LOG_ERROR("sql.sql", "Spell (ID:{}) listed in `spell_target_position` does not exist.", Spell_ID);
1526 continue;
1527 }
1528
1529 if (spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_DEST_DB || spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_DEST_DB)
1530 {
1531 std::pair<uint32, SpellEffIndex> key = std::make_pair(Spell_ID, effIndex);
1532 mSpellTargetPositions[key] = st;
1533 ++count;
1534 }
1535 else
1536 {
1537 LOG_ERROR("sql.sql", "Spell (Id: {}, effIndex: {}) listed in `spell_target_position` does not have target TARGET_DEST_DB (17).", Spell_ID, effIndex);
1538 continue;
1539 }
1540 } while (result->NextRow());
1541
1542 /*
1543 // Check all spells
1544 for (uint32 i = 1; i < GetSpellInfoStoreSize; ++i)
1545 {
1546 SpellInfo const* spellInfo = GetSpellInfo(i);
1547 if (!spellInfo)
1548 continue;
1549
1550 bool found = false;
1551 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
1552 {
1553 switch (spellInfo->Effects[j].TargetA)
1554 {
1555 case TARGET_DEST_DB:
1556 found = true;
1557 break;
1558 }
1559 if (found)
1560 break;
1561 switch (spellInfo->Effects[j].TargetB)
1562 {
1563 case TARGET_DEST_DB:
1564 found = true;
1565 break;
1566 }
1567 if (found)
1568 break;
1569 }
1570 if (found)
1571 {
1572 if (!GetSpellTargetPosition(i))
1573 LOG_DEBUG("spells.aura", "Spell (ID: {}) does not have record in `spell_target_position`", i);
1574 }
1575 }*/
1576
1577 LOG_INFO("server.loading", ">> Loaded {} Spell Teleport Coordinates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1578 LOG_INFO("server.loading", " ");
1579}
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
SpellEffIndex
Definition SharedDefines.h:30
Definition DBCStructure.h:1325
Definition SpellMgr.h:386
float target_Z
Definition SpellMgr.h:390
uint32 target_mapId
Definition SpellMgr.h:387
float target_Y
Definition SpellMgr.h:389
float target_Orientation
Definition SpellMgr.h:391
float target_X
Definition SpellMgr.h:388

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 ( )
2218{
2219 uint32 oldMSTime = getMSTime();
2220
2221 mSpellThreatMap.clear(); // need for reload case
2222
2223 // 0 1 2 3
2224 QueryResult result = WorldDatabase.Query("SELECT entry, flatMod, pctMod, apPctMod FROM spell_threat");
2225 if (!result)
2226 {
2227 LOG_WARN("server.loading", ">> Loaded 0 aggro generating spells. DB table `spell_threat` is empty.");
2228 LOG_INFO("server.loading", " ");
2229 return;
2230 }
2231
2232 uint32 count = 0;
2233 do
2234 {
2235 Field* fields = result->Fetch();
2236
2237 uint32 entry = fields[0].Get<uint32>();
2238
2239 if (!GetSpellInfo(entry))
2240 {
2241 LOG_ERROR("sql.sql", "Spell {} listed in `spell_threat` does not exist", entry);
2242 continue;
2243 }
2244
2245 SpellThreatEntry ste;
2246 ste.flatMod = fields[1].Get<int32>();
2247 ste.pctMod = fields[2].Get<float>();
2248 ste.apPctMod = fields[3].Get<float>();
2249
2250 mSpellThreatMap[entry] = ste;
2251 ++count;
2252 } while (result->NextRow());
2253
2254 LOG_INFO("server.loading", ">> Loaded {} SpellThreatEntries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2255 LOG_INFO("server.loading", " ");
2256}
Definition SpellMgr.h:375
int32 flatMod
Definition SpellMgr.h:376
float apPctMod
Definition SpellMgr.h:378
float pctMod
Definition SpellMgr.h:377

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 
)
532{
533 mSpellDifficultySearcherMap[spellId] = id;
534}

References mSpellDifficultySearcherMap.

◆ UnloadSpellInfoChains()

void SpellMgr::UnloadSpellInfoChains ( )
1179{
1180 for (SpellChainMap::iterator itr = mSpellChains.begin(); itr != mSpellChains.end(); ++itr)
1181 mSpellInfoMap[itr->first]->ChainEntry = nullptr;
1182
1183 mSpellChains.clear();
1184}

References mSpellChains, and mSpellInfoMap.

Referenced by LoadSpellTalentRanks().

◆ UnloadSpellInfoImplicitTargetConditionLists()

void SpellMgr::UnloadSpellInfoImplicitTargetConditionLists ( )
2985{
2986 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2987 {
2988 if (mSpellInfoMap[i])
2989 mSpellInfoMap[i]->_UnloadImplicitTargetConditionLists();
2990 }
2991}

References GetSpellInfoStoreSize(), and mSpellInfoMap.

◆ UnloadSpellInfoStore()

void SpellMgr::UnloadSpellInfoStore ( )
2977{
2978 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2979 delete mSpellInfoMap[i];
2980
2981 mSpellInfoMap.clear();
2982}

References GetSpellInfoStoreSize(), and mSpellInfoMap.

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

Member Data Documentation

◆ mCreatureImmunities

CreatureImmunitiesMap SpellMgr::mCreatureImmunities
private

◆ 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

◆ mSpellGroupSpell

SpellGroupSpellMap SpellMgr::mSpellGroupSpell
private

◆ mSpellGroupStack

◆ 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().

◆ mSpellProcMap

SpellProcMap SpellMgr::mSpellProcMap
private

◆ mSpellReq

SpellRequiredMap SpellMgr::mSpellReq
private

◆ mSpellSameEffectStack

SameEffectStackMap SpellMgr::mSpellSameEffectStack
private

◆ mSpellSpellGroup

SpellSpellGroupMap SpellMgr::mSpellSpellGroup
private

◆ mSpellsReqSpell

SpellsRequiringSpellMap SpellMgr::mSpellsReqSpell
private

◆ mSpellTargetPositions

SpellTargetPositionMap SpellMgr::mSpellTargetPositions
private

◆ mSpellThreatMap

SpellThreatMap SpellMgr::mSpellThreatMap
private

◆ mTalentSpellAdditionalSet

TalentAdditionalSet SpellMgr::mTalentSpellAdditionalSet
private

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