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, WorldObject const *caster) const
 
SpellInfo const * GetSpellForDifficultyFromSpell (SpellInfo const *spell, WorldObject 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
 
std::vector< uint32 > GetSkillRankSpells (uint32 skillId) const
 
SpellTargetPosition const * GetSpellTargetPosition (uint32 spell_id, SpellEffIndex effIndex) const
 
SpellCone const * GetSpellCone (uint32 spell_id) 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 miscValue, 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
 
std::vector< int32 > const * 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 LoadSpellCones ()
 
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 SpellMgr * instance ()
 
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
 
SpellConeMap mSpellCones
 
SpellSpellGroupMap mSpellSpellGroup
 
SpellGroupSpellMap mSpellGroupSpell
 
SpellGroupStackMap mSpellGroupStack
 
SameEffectStackMap mSpellSameEffectStack
 
SameEffectStackSharedMiscMap mSpellSameEffectSharedMisc
 
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
404{
405}

◆ ~SpellMgr()

SpellMgr::~SpellMgr ( )
private
408{
410}
void UnloadSpellInfoStore()
Definition SpellMgr.cpp:3136

References UnloadSpellInfoStore().

Member Function Documentation

◆ _GetSpellInfo()

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

References GetSpellInfoStoreSize(), and mSpellInfoMap.

Referenced by LoadSpellInfoCustomAttributes(), and LoadSpellJumpDistances().

◆ AddSameEffectStackRuleSpellGroups()

bool SpellMgr::AddSameEffectStackRuleSpellGroups ( SpellInfo const *  spellInfo,
uint32  auraType,
int32  miscValue,
int32  amount,
std::map< SpellGroup, int32 > &  groups 
) const
779{
780 uint32 spellId = spellInfo->GetFirstRankSpell()->Id;
781 auto spellGroupBounds = GetSpellSpellGroupMapBounds(spellId);
782 // Find group with SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT if it belongs to one
783 // A spell can be in several such groups for the same auraType (one per stat, e.g. K'iru's Song of Victory),
784 // prefer the group where another spell has the same auraType and miscValue, else the first matching group
786 for (auto itr = spellGroupBounds.first; itr != spellGroupBounds.second; ++itr)
787 {
788 auto found = mSpellSameEffectStack.find(itr->second);
789 // check auraTypes
790 if (found == mSpellSameEffectStack.end() || !found->second.count(auraType))
791 continue;
792
793 if (group == SPELL_GROUP_NONE)
794 group = itr->second;
795
796 auto shared = mSpellSameEffectSharedMisc.find(itr->second);
797 if (shared != mSpellSameEffectSharedMisc.end() && shared->second.count({ auraType, miscValue }))
798 {
799 group = itr->second;
800 break;
801 }
802 }
803
804 // Not in a SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT group, so return false
805 if (group == SPELL_GROUP_NONE)
806 return false;
807
808 // Put the highest amount in the map
809 auto groupItr = groups.find(group);
810 if (groupItr == groups.end())
811 groups.emplace(group, amount);
812 else
813 {
814 int32 curr_amount = groups[group];
815 // Take absolute value because this also counts for the highest negative aura
816 if (std::abs(curr_amount) < std::abs(amount))
817 groupItr->second = amount;
818 }
819
820 return true;
821}
std::int32_t int32
Definition Define.h:103
std::uint32_t uint32
Definition Define.h:107
SpellGroup
Definition SpellMgr.h:331
@ SPELL_GROUP_NONE
Definition SpellMgr.h:332
SameEffectStackMap mSpellSameEffectStack
Definition SpellMgr.h:827
SpellSpellGroupMapBounds GetSpellSpellGroupMapBounds(uint32 spell_id) const
Definition SpellMgr.cpp:728
SameEffectStackSharedMiscMap mSpellSameEffectSharedMisc
Definition SpellMgr.h:828

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

◆ AssertSpellInfo()

SpellInfo const * SpellMgr::AssertSpellInfo ( uint32  spellId) const
inline
748 {
749 ASSERT(spellId < GetSpellInfoStoreSize());
750 SpellInfo const* spellInfo = mSpellInfoMap[spellId];
751 ASSERT(spellInfo);
752 return spellInfo;
753 }
#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
888{
889 // proc type doesn't match
890 if (!(eventInfo.GetTypeMask() & procEntry.ProcFlags))
891 return false;
892
893 // check XP or honor target requirement
894 if (procEntry.AttributesMask & PROC_ATTR_REQ_EXP_OR_HONOR)
895 if (Player* actor = eventInfo.GetActor()->ToPlayer())
896 if (eventInfo.GetActionTarget() && !actor->isHonorOrXPTarget(eventInfo.GetActionTarget()))
897 return false;
898
899 // check mana cost requirement (used by Clearcasting and similar effects)
900 if (procEntry.AttributesMask & PROC_ATTR_REQ_MANA_COST)
901 {
902 SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
903 if (!spellInfo || (!spellInfo->ManaCost && !spellInfo->ManaCostPercentage))
904 return false;
905 }
906
907 // always trigger for these types
909 return true;
910
911 // check school mask (if set) for other trigger types
912 if (procEntry.SchoolMask && !(eventInfo.GetSchoolMask() & procEntry.SchoolMask))
913 return false;
914
915 // check spell family name/flags (if set) for spells
916 if (eventInfo.GetTypeMask() & SPELL_PROC_FLAG_MASK)
917 if (SpellInfo const* eventSpellInfo = eventInfo.GetSpellInfo())
918 if (!eventSpellInfo->IsAffected(procEntry.SpellFamilyName, procEntry.SpellFamilyMask))
919 return false;
920
921 // check spell type mask (if set)
923 {
924 if (procEntry.SpellTypeMask && !(eventInfo.GetSpellTypeMask() & procEntry.SpellTypeMask))
925 return false;
926 }
927
928 // check spell phase mask
930 {
931 if (!(eventInfo.GetSpellPhaseMask() & procEntry.SpellPhaseMask))
932 return false;
933 }
934
935 // check hit mask (on taken hit or on done hit)
936 // For CAST phase with DONE flags, only check if HitMask is explicitly set (crit is pre-calculated for travel time spells)
937 if ((eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK) ||
938 ((eventInfo.GetTypeMask() & DONE_HIT_PROC_FLAG_MASK) &&
939 (!(eventInfo.GetSpellPhaseMask() & PROC_SPELL_PHASE_CAST) || procEntry.HitMask)))
940 {
941 uint32 hitMask = procEntry.HitMask;
942 // get default values if hit mask not set
943 if (!hitMask)
944 {
945 // for taken procs allow normal + critical hits by default
946 if (eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK)
948 // for done procs allow normal + critical + absorbs by default
949 else
951 }
952 if (!(eventInfo.GetHitMask() & hitMask))
953 return false;
954 }
955
956 return true;
957}
@ 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:208
Definition Player.h:1086
uint32 GetHitMask() const
Definition Unit.h:474
SpellSchoolMask GetSchoolMask() const
Definition Unit.cpp:315
Unit * GetActionTarget() const
Definition Unit.h:469
uint32 GetSpellTypeMask() const
Definition Unit.h:472
uint32 GetTypeMask() const
Definition Unit.h:471
SpellInfo const * GetSpellInfo() const
Definition Unit.cpp:301
Unit * GetActor()
Definition Unit.h:468
uint32 GetSpellPhaseMask() const
Definition Unit.h:473
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
824{
825 ASSERT(spellInfo1);
826 ASSERT(spellInfo2);
827
828 uint32 spell_id1 = spellInfo1->GetFirstRankSpell()->Id;
829 uint32 spell_id2 = spellInfo2->GetFirstRankSpell()->Id;
830
831 // find SpellGroups which are common for both spells
833 std::set<SpellGroup> groups;
834 for (SpellSpellGroupMap::const_iterator itr = spellGroup1.first; itr != spellGroup1.second; ++itr)
835 {
836 if (IsSpellMemberOfSpellGroup(spell_id2, itr->second))
837 {
838 bool add = true;
840 for (SpellGroupSpellMap::const_iterator itr2 = groupSpell.first; itr2 != groupSpell.second; ++itr2)
841 {
842 if (itr2->second < 0)
843 {
844 SpellGroup currGroup = (SpellGroup)abs(itr2->second);
845 if (IsSpellMemberOfSpellGroup(spell_id1, currGroup) && IsSpellMemberOfSpellGroup(spell_id2, currGroup))
846 {
847 add = false;
848 break;
849 }
850 }
851 }
852 if (add)
853 groups.insert(itr->second);
854 }
855 }
856
858
859 for (std::set<SpellGroup>::iterator itr = groups.begin(); itr!= groups.end(); ++itr)
860 {
861 SpellGroupStackMap::const_iterator found = mSpellGroupStack.find(*itr);
862 if (found != mSpellGroupStack.end())
863 rule = found->second;
864 if (rule)
865 break;
866 }
867 return rule;
868}
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:745
bool IsSpellMemberOfSpellGroup(uint32 spell_id, SpellGroup group_id) const
Definition SpellMgr.cpp:734
SpellGroupStackMap mSpellGroupStack
Definition SpellMgr.h:826

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
756 {
757 if (spellId >= GetSpellInfoStoreSize())
758 {
759 LOG_ERROR("server", "spellId {} is not lower than GetSpellInfoStoreSize() ({})", spellId, GetSpellInfoStoreSize());
760 return nullptr;
761 }
762 SpellInfo const* spellInfo = mSpellInfoMap[spellId];
763 if (!spellInfo)
764 {
765 LOG_ERROR("server", "spellId {} has invalid spellInfo", spellId);
766 return nullptr;
767 }
768 return spellInfo;
769 }
#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
509{
510 if (!spellInfo)
511 {
513 LOG_ERROR("spells", "Player::{}: Non-existed in SpellStore spell #{} request.", (isTalent ? "AddTalent" : "addSpell"), spellId);
514 return false;
515 }
516
517 if (!IsSpellValid(spellInfo))
518 {
520 LOG_ERROR("spells", "Player::{}: Broken spell #{} learning not allowed.", (isTalent ? "AddTalent" : "addSpell"), spellId);
521 return false;
522 }
523
524 return true;
525}
void DeleteSpellFromAllPlayers(uint32 spellId)
Definition SpellMgr.cpp:497
static bool IsSpellValid(SpellInfo const *spellInfo)
Definition SpellMgr.cpp:490

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.

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

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
61{
62 return Acore::Containers::MapGetValuePtr(mCreatureImmunities, creatureImmunitiesId);
63}
CreatureImmunitiesMap mCreatureImmunities
Definition SpellMgr.h:830
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
604{
605 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
606 return node->first->Id;
607
608 return spell_id;
609}
SpellChainNode const * GetSpellChainNode(uint32 spell_id) const
Definition SpellMgr.cpp:594
Definition SpellMgr.h:553

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

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

◆ GetLastSpellInChain()

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

References GetSpellChainNode().

◆ GetNextSpellInChain()

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

References GetSpellChainNode().

◆ GetPetAura()

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

References mSpellPetAuraMap.

◆ GetPetDefaultSpellsEntry()

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

References mPetDefaultSpellsMap.

◆ GetPetLevelupSpellList()

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

References mPetLevelupSpellMap.

◆ GetPrevSpellInChain()

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

References GetSpellChainNode().

◆ GetSetOfSpellsInSpellGroup() [1/2]

void SpellMgr::GetSetOfSpellsInSpellGroup ( SpellGroup  group_id,
std::set< uint32 > &  foundSpells 
) const
751{
752 std::set<SpellGroup> usedGroups;
753 GetSetOfSpellsInSpellGroup(group_id, foundSpells, usedGroups);
754}
void GetSetOfSpellsInSpellGroup(SpellGroup group_id, std::set< uint32 > &foundSpells) const
Definition SpellMgr.cpp:750

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
757{
758 if (usedGroups.find(group_id) != usedGroups.end())
759 return;
760 usedGroups.insert(group_id);
761
763 for (SpellGroupSpellMap::const_iterator itr = groupSpell.first; itr != groupSpell.second; ++itr)
764 {
765 if (itr->second < 0)
766 {
767 SpellGroup currGroup = (SpellGroup)abs(itr->second);
768 GetSetOfSpellsInSpellGroup(currGroup, foundSpells, usedGroups);
769 }
770 else
771 {
772 foundSpells.insert(itr->second);
773 }
774 }
775}

References GetSetOfSpellsInSpellGroup(), and GetSpellGroupSpellMapBounds().

◆ GetSkillLineAbilityMapBounds()

SkillLineAbilityMapBounds SpellMgr::GetSkillLineAbilityMapBounds ( uint32  spell_id) const
1000{
1001 return mSkillLineAbilityMap.equal_range(spell_id);
1002}
SkillLineAbilityMap mSkillLineAbilityMap
Definition SpellMgr.h:843

References mSkillLineAbilityMap.

◆ GetSkillRankSpells()

std::vector< uint32 > SpellMgr::GetSkillRankSpells ( uint32  skillId) const
693{
694 // Returns every spell that grants this skill via SPELL_EFFECT_SKILL,
695 // i.e. the profession rank/proficiency spells (Apprentice -> Grand Master),
696 // ordered by step. Not strictly limited to the six ranks: any skill-granting
697 // spell for the line is included.
698 std::vector<uint32> result;
699 for (auto const& [spellId, node] : mSpellLearnSkills)
700 if (node.skill == skillId)
701 result.push_back(spellId);
702
703 std::ranges::sort(result, [this](uint32 a, uint32 b)
704 {
705 return mSpellLearnSkills.at(a).step < mSpellLearnSkills.at(b).step;
706 });
707 return result;
708}
SpellLearnSkillMap mSpellLearnSkills
Definition SpellMgr.h:821

References mSpellLearnSkills.

◆ GetSpellAreaForAreaMapBounds()

SpellAreaForAreaMapBounds SpellMgr::GetSpellAreaForAreaMapBounds ( uint32  area_id) const
1070{
1071 return mSpellAreaForAreaMap.equal_range(area_id);
1072}
SpellAreaForAreaMap mSpellAreaForAreaMap
Definition SpellMgr.h:842

References mSpellAreaForAreaMap.

◆ GetSpellAreaForAuraMapBounds()

SpellAreaForAuraMapBounds SpellMgr::GetSpellAreaForAuraMapBounds ( uint32  spell_id) const
1065{
1066 return mSpellAreaForAuraMap.equal_range(spell_id);
1067}
SpellAreaForAuraMap mSpellAreaForAuraMap
Definition SpellMgr.h:841

References mSpellAreaForAuraMap.

Referenced by LoadSpellAreas().

◆ GetSpellAreaForQuestEndMapBounds()

SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestEndMapBounds ( uint32  quest_id) const
1060{
1061 return mSpellAreaForQuestEndMap.equal_range(quest_id);
1062}
SpellAreaForQuestMap mSpellAreaForQuestEndMap
Definition SpellMgr.h:840

References mSpellAreaForQuestEndMap.

◆ GetSpellAreaForQuestMapBounds()

SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestMapBounds ( uint32  quest_id) const
1055{
1056 return mSpellAreaForQuestMap.equal_range(quest_id);
1057}
SpellAreaForQuestMap mSpellAreaForQuestMap
Definition SpellMgr.h:839

References mSpellAreaForQuestMap.

◆ GetSpellAreaMapBounds()

SpellAreaMapBounds SpellMgr::GetSpellAreaMapBounds ( uint32  spell_id) const
1050{
1051 return mSpellAreaMap.equal_range(spell_id);
1052}
SpellAreaMap mSpellAreaMap
Definition SpellMgr.h:838

References mSpellAreaMap.

Referenced by LoadSpellAreas().

◆ GetSpellBonusData()

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

References GetFirstSpellInChain(), and mSpellBonusMap.

◆ GetSpellChainNode()

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

References mSpellChains.

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

◆ GetSpellCone()

SpellCone const * SpellMgr::GetSpellCone ( uint32  spell_id) const
719{
720 spell_id = GetFirstSpellInChain(spell_id);
721 auto itr = mSpellCones.find(spell_id);
722 if (itr != mSpellCones.end())
723 return &itr->second;
724
725 return nullptr;
726}
SpellConeMap mSpellCones
Definition SpellMgr.h:823

References GetFirstSpellInChain(), and mSpellCones.

◆ GetSpellCooldownOverride()

SpellCooldownOverride SpellMgr::GetSpellCooldownOverride ( uint32  spellId) const
3131{
3132 auto range = mSpellCooldownOverrideMap.find(spellId);
3133 return range->second;
3134}
SpellCooldownOverrideMap mSpellCooldownOverrideMap
Definition SpellMgr.h:847

References mSpellCooldownOverrideMap.

Referenced by LoadSpellInfoCustomAttributes().

◆ GetSpellDifficultyId()

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

References mSpellDifficultySearcherMap.

Referenced by GetSpellIdForDifficulty().

◆ GetSpellEnchantProcEvent()

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

References mSpellEnchantProcEventMap.

◆ GetSpellForDifficultyFromSpell()

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

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

◆ GetSpellGroupSpellMapBounds()

SpellGroupSpellMapBounds SpellMgr::GetSpellGroupSpellMapBounds ( SpellGroup  group_id) const
746{
747 return mSpellGroupSpell.equal_range(group_id);
748}
SpellGroupSpellMap mSpellGroupSpell
Definition SpellMgr.h:825

References mSpellGroupSpell.

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

◆ GetSpellGroupStackRule()

SpellGroupStackRule SpellMgr::GetSpellGroupStackRule ( SpellGroup  group_id) const
871{
872 SpellGroupStackMap::const_iterator itr = mSpellGroupStack.find(group);
873 if (itr != mSpellGroupStack.end())
874 return itr->second;
875
877}

References mSpellGroupStack, and SPELL_GROUP_STACK_RULE_DEFAULT.

◆ GetSpellIdForDifficulty()

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

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
684{
685 SpellLearnSkillMap::const_iterator itr = mSpellLearnSkills.find(spell_id);
686 if (itr != mSpellLearnSkills.end())
687 return &itr->second;
688 else
689 return nullptr;
690}

References mSpellLearnSkills.

◆ GetSpellLinked()

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

References mSpellLinkedMap.

◆ GetSpellMixologyBonus()

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

References mSpellMixologyMap.

◆ GetSpellProcEntry()

SpellProcEntry const * SpellMgr::GetSpellProcEntry ( uint32  spellId) const
880{
881 SpellProcMap::const_iterator itr = mSpellProcMap.find(spellId);
882 if (itr != mSpellProcMap.end())
883 return &itr->second;
884 return nullptr;
885}
SpellProcMap mSpellProcMap
Definition SpellMgr.h:829

References mSpellProcMap.

◆ GetSpellRank()

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

References GetSpellChainNode().

◆ GetSpellSpellGroupMapBounds()

SpellSpellGroupMapBounds SpellMgr::GetSpellSpellGroupMapBounds ( uint32  spell_id) const
729{
730 spell_id = GetFirstSpellInChain(spell_id);
731 return mSpellSpellGroup.equal_range(spell_id);
732}
SpellSpellGroupMap mSpellSpellGroup
Definition SpellMgr.h:824

References GetFirstSpellInChain(), and mSpellSpellGroup.

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

◆ GetSpellsRequiredForSpellBounds()

Acore::IteratorPair< SpellRequiredMap::const_iterator > SpellMgr::GetSpellsRequiredForSpellBounds ( uint32  spell_id) const
658{
660}
SpellRequiredMap mSpellReq
Definition SpellMgr.h:820
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
663{
664 return mSpellsReqSpell.equal_range(spell_id);
665}
SpellsRequiringSpellMap mSpellsReqSpell
Definition SpellMgr.h:819

References mSpellsReqSpell.

Referenced by IsSpellRequiringSpell().

◆ GetSpellTargetPosition()

SpellTargetPosition const * SpellMgr::GetSpellTargetPosition ( uint32  spell_id,
SpellEffIndex  effIndex 
) const
711{
712 SpellTargetPositionMap::const_iterator itr = mSpellTargetPositions.find(std::make_pair(spell_id, effIndex));
713 if (itr != mSpellTargetPositions.end())
714 return &itr->second;
715 return nullptr;
716}
SpellTargetPositionMap mSpellTargetPositions
Definition SpellMgr.h:822

References mSpellTargetPositions.

◆ GetSpellThreatEntry()

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

References GetFirstSpellInChain(), and mSpellThreatMap.

◆ GetSpellWithRank()

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

References GetSpellChainNode(), and GetSpellWithRank().

Referenced by GetSpellWithRank().

◆ HasSpellCooldownOverride()

bool SpellMgr::HasSpellCooldownOverride ( uint32  spellId) const
3126{
3127 return mSpellCooldownOverrideMap.find(spellId) != mSpellCooldownOverrideMap.end();
3128}

References mSpellCooldownOverrideMap.

Referenced by LoadSpellInfoCustomAttributes().

◆ instance()

SpellMgr * SpellMgr::instance ( )
static
413{
414 static SpellMgr instance;
415 return &instance;
416}
Definition SpellMgr.h:651
static SpellMgr * instance()
Definition SpellMgr.cpp:412

References instance().

Referenced by instance().

◆ IsAdditionalTalentSpell()

bool SpellMgr::IsAdditionalTalentSpell ( uint32  spellId) const
679{
680 return mTalentSpellAdditionalSet.find(spellId) != mTalentSpellAdditionalSet.end();
681}
TalentAdditionalSet mTalentSpellAdditionalSet
Definition SpellMgr.h:848

References mTalentSpellAdditionalSet.

◆ IsArenaAllowedEnchancment()

bool SpellMgr::IsArenaAllowedEnchancment ( uint32  ench_id) const
1022{
1023 return mEnchantCustomAttr[ench_id];
1024}
EnchantCustomAttribute mEnchantCustomAttr
Definition SpellMgr.h:837

References mEnchantCustomAttr.

◆ IsSpellMemberOfSpellGroup()

bool SpellMgr::IsSpellMemberOfSpellGroup ( uint32  spell_id,
SpellGroup  group_id 
) const
735{
737 for (SpellSpellGroupMap::const_iterator itr = spellGroup.first; itr != spellGroup.second; ++itr)
738 {
739 if (itr->second == group_id)
740 return true;
741 }
742 return false;
743}

References GetSpellSpellGroupMapBounds().

Referenced by CheckSpellGroupStackRules().

◆ IsSpellRequiringSpell()

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

References GetSpellsRequiringSpellBounds().

Referenced by LoadSpellRequired().

◆ IsSpellValid()

◆ LoadCreatureImmunities()

void SpellMgr::LoadCreatureImmunities ( )
66{
67 mCreatureImmunities.clear();
68 if (QueryResult result = WorldDatabase.Query("SELECT ID, SchoolMask, DispelTypeMask, MechanicsMask, Effects, Auras, ImmuneAoE, ImmuneChain FROM creature_immunities"))
69 {
70 do
71 {
72 Field* fields = result->Fetch();
73 int32 id = fields[0].Get<int32>();
74 uint8 school = fields[1].Get<uint8>();
75 uint16 dispelType = fields[2].Get<uint16>();
76 uint64 mechanics = fields[3].Get<uint64>();
78 immunities.School = school;
79 immunities.DispelType = dispelType;
80 immunities.Mechanic = mechanics;
81 immunities.ImmuneAoE = fields[6].Get<bool>();
82 immunities.ImmuneChain = fields[7].Get<bool>();
83 {
84 std::string effects = fields[4].Get<std::string>();
85 for (std::string_view token : Acore::Tokenize(effects, ',', false))
86 {
87 if (Optional<uint32> val = Acore::StringTo<uint32>(token); val && *val < uint32(TOTAL_SPELL_EFFECTS))
88 immunities.Effect.push_back(SpellEffects(*val));
89 else
90 LOG_ERROR("sql.sql", "Invalid effect type in `Effects` {} for creature immunities {}, skipped", token, id);
91 }
92 }
93 {
94 std::string auras = fields[5].Get<std::string>();
95 for (std::string_view token : Acore::Tokenize(auras, ',', false))
96 {
97 if (Optional<uint32> val = Acore::StringTo<uint32>(token); val && *val < TOTAL_AURAS)
98 immunities.Aura.push_back(AuraType(*val));
99 else
100 LOG_ERROR("sql.sql", "Invalid aura type in `Auras` {} for creature immunities {}, skipped", token, id);
101 }
102 }
103 } while (result->NextRow());
104 }
105}
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:99
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition Field.h:113
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:573
std::bitset< MAX_SPELL_SCHOOL > School
Definition SpellMgr.h:574

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
2540{
2541 uint32 oldMSTime = getMSTime();
2542
2543 uint32 size = sSpellItemEnchantmentStore.GetNumRows();
2544 mEnchantCustomAttr.resize(size);
2545
2546 for (uint32 i = 0; i < size; ++i)
2547 mEnchantCustomAttr[i] = 0;
2548
2549 uint32 count = 0;
2550 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2551 {
2552 SpellInfo const* spellInfo = GetSpellInfo(i);
2553 if (!spellInfo)
2554 continue;
2555
2557 // Xinef: commented second part, fixes warlock enchants like firestone, spellstone
2558 if (!spellInfo->HasAttribute(SPELL_ATTR2_ENCHANT_OWN_ITEM_ONLY)/* || !spellInfo->HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFTED)*/)
2559 continue;
2560
2561 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
2562 {
2563 if (spellInfo->Effects[j].Effect == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY)
2564 {
2565 uint32 enchId = spellInfo->Effects[j].MiscValue;
2566 SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchId);
2567 if (!ench)
2568 continue;
2569 mEnchantCustomAttr[enchId] = true;
2570 ++count;
2571 break;
2572 }
2573 }
2574 }
2575
2576 LOG_INFO("server.loading", ">> Loaded {} Custom Enchant Attributes in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2577 LOG_INFO("server.loading", " ");
2578}
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:1877

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 ( )
2773{
2774 uint32 oldMSTime = getMSTime();
2775
2776 mPetDefaultSpellsMap.clear();
2777
2778 uint32 countCreature = 0;
2779 uint32 countData = 0;
2780
2781 CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
2782 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
2783 {
2784 if (!itr->second.PetSpellDataId)
2785 continue;
2786
2787 // for creature with PetSpellDataId get default pet spells from dbc
2788 CreatureSpellDataEntry const* spellDataEntry = sCreatureSpellDataStore.LookupEntry(itr->second.PetSpellDataId);
2789 if (!spellDataEntry)
2790 continue;
2791
2792 int32 petSpellsId = -int32(itr->second.PetSpellDataId);
2793 PetDefaultSpellsEntry petDefSpells;
2794 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2795 petDefSpells.spellid[j] = spellDataEntry->spellId[j];
2796
2797 if (LoadPetDefaultSpells_helper(&itr->second, petDefSpells))
2798 {
2799 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2800 ++countData;
2801 }
2802 }
2803
2804 LOG_INFO("server.loading", ">> Loaded Addition Spells For {} Pet Spell Data Entries in {} ms", countData, GetMSTimeDiffToNow(oldMSTime));
2805 LOG_INFO("server.loading", " ");
2806
2807 LOG_INFO("server.loading", "Loading Summonable Creature Templates...");
2808 oldMSTime = getMSTime();
2809
2810 // different summon spells
2811 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2812 {
2813 SpellInfo const* spellInfo = GetSpellInfo(i);
2814 if (!spellInfo)
2815 continue;
2816
2817 for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
2818 {
2819 if (spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON || spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON_PET)
2820 {
2821 uint32 creature_id = spellInfo->Effects[k].MiscValue;
2822 CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id);
2823 if (!cInfo)
2824 continue;
2825
2826 // already loaded
2827 if (cInfo->PetSpellDataId)
2828 continue;
2829
2830 // for creature without PetSpellDataId get default pet spells from creature_template
2831 int32 petSpellsId = cInfo->Entry;
2832 if (mPetDefaultSpellsMap.find(cInfo->Entry) != mPetDefaultSpellsMap.end())
2833 continue;
2834
2835 PetDefaultSpellsEntry petDefSpells;
2836 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2837 petDefSpells.spellid[j] = cInfo->spells[j];
2838
2839 if (LoadPetDefaultSpells_helper(cInfo, petDefSpells))
2840 {
2841 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2842 ++countCreature;
2843 }
2844 }
2845 }
2846 }
2847
2848 LOG_INFO("server.loading", ">> Loaded {} Summonable Creature emplates in {} ms", countCreature, GetMSTimeDiffToNow(oldMSTime));
2849 LOG_INFO("server.loading", " ");
2850}
std::unordered_map< uint32, CreatureTemplate > CreatureTemplateContainer
Definition CreatureData.h:287
DBCStorage< CreatureSpellDataEntry > sCreatureSpellDataStore(CreatureSpellDatafmt)
#define MAX_CREATURE_SPELL_DATA_SLOT
Definition DBCStructure.h:834
@ 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:2724
Definition DBCStructure.h:837
uint32 spellId[MAX_CREATURE_SPELL_DATA_SLOT]
Definition DBCStructure.h:839
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:603
uint32 spellid[MAX_CREATURE_SPELL_DATA_SLOT]
Definition SpellMgr.h:604

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 ( )
2679{
2680 uint32 oldMSTime = getMSTime();
2681
2682 mPetLevelupSpellMap.clear(); // need for reload case
2683
2684 uint32 count = 0;
2685 uint32 family_count = 0;
2686
2687 for (uint32 i = 0; i < sCreatureFamilyStore.GetNumRows(); ++i)
2688 {
2689 CreatureFamilyEntry const* creatureFamily = sCreatureFamilyStore.LookupEntry(i);
2690 if (!creatureFamily) // not exist
2691 continue;
2692
2693 for (uint8 j = 0; j < 2; ++j)
2694 {
2695 if (!creatureFamily->skillLine[j])
2696 continue;
2697
2698 for (SkillLineAbilityEntry const* skillLine : GetSkillLineAbilitiesBySkillLine(creatureFamily->skillLine[j]))
2699 {
2700 if (skillLine->AcquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN)
2701 continue;
2702
2703 SpellInfo const* spell = GetSpellInfo(skillLine->Spell);
2704 if (!spell) // not exist or triggered or talent
2705 continue;
2706
2707 if (!spell->SpellLevel)
2708 continue;
2709
2710 PetLevelupSpellSet& spellSet = mPetLevelupSpellMap[creatureFamily->ID];
2711 if (spellSet.empty())
2712 ++family_count;
2713
2714 spellSet.insert(PetLevelupSpellSet::value_type(spell->SpellLevel, spell->Id));
2715 ++count;
2716 }
2717 }
2718 }
2719
2720 LOG_INFO("server.loading", ">> Loaded {} Pet Levelup And Default Spells For {} Families in {} ms", count, family_count, GetMSTimeDiffToNow(oldMSTime));
2721 LOG_INFO("server.loading", " ");
2722}
@ SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN
Definition DBCEnums.h:361
DBCStorage< CreatureFamilyEntry > sCreatureFamilyStore(CreatureFamilyfmt)
std::vector< SkillLineAbilityEntry const * > const & GetSkillLineAbilitiesBySkillLine(uint32 skillLine)
Definition DBCStores.cpp:939
std::multimap< uint32, uint32 > PetLevelupSpellSet
Definition SpellMgr.h:597
uint32 SpellLevel
Definition SpellInfo.h:384
Definition DBCStructure.h:781
uint32 ID
Definition DBCStructure.h:782
uint32 skillLine[2]
Definition DBCStructure.h:787
Definition DBCStructure.h:1634

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 ( )
2455{
2456 uint32 oldMSTime = getMSTime();
2457
2458 mSkillLineAbilityMap.clear();
2459
2460 uint32 count = 0;
2461
2462 for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); ++i)
2463 {
2464 SkillLineAbilityEntry const* SkillInfo = sSkillLineAbilityStore.LookupEntry(i);
2465 if (!SkillInfo)
2466 continue;
2467
2468 mSkillLineAbilityMap.insert(SkillLineAbilityMap::value_type(SkillInfo->Spell, SkillInfo));
2469 ++count;
2470 }
2471
2472 LOG_INFO("server.loading", ">> Loaded {} SkillLineAbility MultiMap Data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2473 LOG_INFO("server.loading", " ");
2474}
DBCStorage< SkillLineAbilityEntry > sSkillLineAbilityStore(SkillLineAbilityfmt)
uint32 Spell
Definition DBCStructure.h:1637

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

◆ LoadSpellAreas()

void SpellMgr::LoadSpellAreas ( )
2853{
2854 uint32 oldMSTime = getMSTime();
2855
2856 mSpellAreaMap.clear(); // need for reload case
2857 mSpellAreaForQuestMap.clear();
2859 mSpellAreaForAuraMap.clear();
2860
2861 // 0 1 2 3 4 5 6 7 8 9
2862 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");
2863
2864 if (!result)
2865 {
2866 LOG_WARN("server.loading", ">> Loaded 0 spell area requirements. DB table `spell_area` is empty.");
2867 LOG_INFO("server.loading", " ");
2868 return;
2869 }
2870
2871 uint32 count = 0;
2872 do
2873 {
2874 Field* fields = result->Fetch();
2875
2876 uint32 spell = fields[0].Get<uint32>();
2877 SpellArea spellArea;
2878 spellArea.spellId = spell;
2879 spellArea.areaId = fields[1].Get<uint32>();
2880 spellArea.questStart = fields[2].Get<uint32>();
2881 spellArea.questStartStatus = fields[3].Get<uint32>();
2882 spellArea.questEndStatus = fields[4].Get<uint32>();
2883 spellArea.questEnd = fields[5].Get<uint32>();
2884 spellArea.auraSpell = fields[6].Get<int32>();
2885 spellArea.raceMask = fields[7].Get<uint32>();
2886 spellArea.gender = Gender(fields[8].Get<uint8>());
2887 spellArea.autocast = fields[9].Get<bool>();
2888
2889 if (SpellInfo const* spellInfo = GetSpellInfo(spell))
2890 {
2891 if (spellArea.autocast)
2892 const_cast<SpellInfo*>(spellInfo)->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
2893 }
2894 else
2895 {
2896 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` does not exist", spell);
2897 continue;
2898 }
2899
2900 {
2901 bool ok = true;
2902 SpellAreaMapBounds sa_bounds = GetSpellAreaMapBounds(spellArea.spellId);
2903 for (SpellAreaMap::const_iterator itr = sa_bounds.first; itr != sa_bounds.second; ++itr)
2904 {
2905 if (spellArea.spellId != itr->second.spellId)
2906 continue;
2907 if (spellArea.areaId != itr->second.areaId)
2908 continue;
2909 if (spellArea.questStart != itr->second.questStart)
2910 continue;
2911 if (spellArea.auraSpell != itr->second.auraSpell)
2912 continue;
2913 if ((spellArea.raceMask & itr->second.raceMask) == 0)
2914 continue;
2915 if (spellArea.gender != itr->second.gender)
2916 continue;
2917
2918 // duplicate by requirements
2919 ok = false;
2920 break;
2921 }
2922
2923 if (!ok)
2924 {
2925 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` already listed with similar requirements.", spell);
2926 continue;
2927 }
2928 }
2929
2930 if (spellArea.areaId && !sAreaTableStore.LookupEntry(spellArea.areaId))
2931 {
2932 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong area ({}) requirement", spell, spellArea.areaId);
2933 continue;
2934 }
2935
2936 if (spellArea.questStart && !sObjectMgr->GetQuestTemplate(spellArea.questStart))
2937 {
2938 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong start quest ({}) requirement", spell, spellArea.questStart);
2939 continue;
2940 }
2941
2942 if (spellArea.questEnd)
2943 {
2944 if (!sObjectMgr->GetQuestTemplate(spellArea.questEnd))
2945 {
2946 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong end quest ({}) requirement", spell, spellArea.questEnd);
2947 continue;
2948 }
2949 }
2950
2951 if (spellArea.auraSpell)
2952 {
2953 SpellInfo const* spellInfo = GetSpellInfo(std::abs(spellArea.auraSpell));
2954 if (!spellInfo)
2955 {
2956 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong aura spell ({}) requirement", spell, std::abs(spellArea.auraSpell));
2957 continue;
2958 }
2959
2960 if (uint32(std::abs(spellArea.auraSpell)) == spellArea.spellId)
2961 {
2962 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement for itself", spell, std::abs(spellArea.auraSpell));
2963 continue;
2964 }
2965
2966 // not allow autocast chains by auraSpell field (but allow use as alternative if not present)
2967 if (spellArea.autocast && spellArea.auraSpell > 0)
2968 {
2969 bool chain = false;
2970 SpellAreaForAuraMapBounds saBound = GetSpellAreaForAuraMapBounds(spellArea.spellId);
2971 for (SpellAreaForAuraMap::const_iterator itr = saBound.first; itr != saBound.second; ++itr)
2972 {
2973 if (itr->second->autocast && itr->second->auraSpell > 0)
2974 {
2975 chain = true;
2976 break;
2977 }
2978 }
2979
2980 if (chain)
2981 {
2982 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement that itself autocast from aura", spell, spellArea.auraSpell);
2983 continue;
2984 }
2985
2986 SpellAreaMapBounds saBound2 = GetSpellAreaMapBounds(spellArea.auraSpell);
2987 for (SpellAreaMap::const_iterator itr2 = saBound2.first; itr2 != saBound2.second; ++itr2)
2988 {
2989 if (itr2->second.autocast && itr2->second.auraSpell > 0)
2990 {
2991 chain = true;
2992 break;
2993 }
2994 }
2995
2996 if (chain)
2997 {
2998 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement that itself autocast from aura", spell, spellArea.auraSpell);
2999 continue;
3000 }
3001 }
3002 }
3003
3004 if (spellArea.raceMask && (spellArea.raceMask & sRaceMgr->GetPlayableRaceMask()) == 0)
3005 {
3006 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong race mask ({}) requirement", spell, spellArea.raceMask);
3007 continue;
3008 }
3009
3010 if (spellArea.gender != GENDER_NONE && spellArea.gender != GENDER_FEMALE && spellArea.gender != GENDER_MALE)
3011 {
3012 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong gender ({}) requirement", spell, spellArea.gender);
3013 continue;
3014 }
3015
3016 SpellArea const* sa = &mSpellAreaMap.insert(SpellAreaMap::value_type(spell, spellArea))->second;
3017
3018 // for search by current zone/subzone at zone/subzone change
3019 if (spellArea.areaId)
3020 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(spellArea.areaId, sa));
3021
3022 // for search at quest start/reward
3023 if (spellArea.questStart)
3024 mSpellAreaForQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa));
3025
3026 // for search at quest start/reward
3027 if (spellArea.questEnd)
3028 mSpellAreaForQuestEndMap.insert(SpellAreaForQuestMap::value_type(spellArea.questEnd, sa));
3029
3030 // for search at aura apply
3031 if (spellArea.auraSpell)
3032 mSpellAreaForAuraMap.insert(SpellAreaForAuraMap::value_type(std::abs(spellArea.auraSpell), sa));
3033
3034 ++count;
3035 } while (result->NextRow());
3036
3037 if (sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE) > 0)
3038 {
3039 LOG_INFO("server.loading", ">> Using ICC Buff Horde: {}", sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE));
3040 SpellArea spellAreaICCBuffHorde = { sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE), ICC_AREA, 0, 0, 0, ICC_RACEMASK_HORDE, Gender(2), 64, 11, 1 };
3041 SpellArea const* saICCBuffHorde = &mSpellAreaMap.insert(SpellAreaMap::value_type(sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE), spellAreaICCBuffHorde))->second;
3042 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(ICC_AREA, saICCBuffHorde));
3043 ++count;
3044 }
3045 else
3046 LOG_INFO("server.loading", ">> ICC Buff Horde: disabled");
3047
3048 if (sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE) > 0)
3049 {
3050 LOG_INFO("server.loading", ">> Using ICC Buff Alliance: {}", sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE));
3051 SpellArea spellAreaICCBuffAlliance = { sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE), ICC_AREA, 0, 0, 0, ICC_RACEMASK_ALLIANCE, Gender(2), 64, 11, 1 };
3052 SpellArea const* saICCBuffAlliance = &mSpellAreaMap.insert(SpellAreaMap::value_type(sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE), spellAreaICCBuffAlliance))->second;
3053 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(ICC_AREA, saICCBuffAlliance));
3054 ++count;
3055 }
3056 else
3057 LOG_INFO("server.loading", ">> ICC Buff Alliance: disabled");
3058
3059 LOG_INFO("server.loading", ">> Loaded {} Spell Area Requirements in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3060 LOG_INFO("server.loading", " ");
3061}
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:546
@ ICC_RACEMASK_HORDE
Definition SpellMgr.h:521
@ ICC_AREA
Definition SpellMgr.h:520
@ ICC_RACEMASK_ALLIANCE
Definition SpellMgr.h:522
std::pair< SpellAreaForAuraMap::const_iterator, SpellAreaForAuraMap::const_iterator > SpellAreaForAuraMapBounds
Definition SpellMgr.h:548
@ CONFIG_ICC_BUFF_ALLIANCE
Definition WorldConfig.h:357
@ CONFIG_ICC_BUFF_HORDE
Definition WorldConfig.h:356
SpellAreaMapBounds GetSpellAreaMapBounds(uint32 spell_id) const
Definition SpellMgr.cpp:1049
SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds(uint32 spell_id) const
Definition SpellMgr.cpp:1064
#define sWorld
Definition World.h:337
Definition SpellMgr.h:526
uint32 spellId
Definition SpellMgr.h:527

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 ( )
2337{
2338 uint32 oldMSTime = getMSTime();
2339
2340 mSpellBonusMap.clear(); // need for reload case
2341
2342 // 0 1 2 3 4
2343 QueryResult result = WorldDatabase.Query("SELECT entry, direct_bonus, dot_bonus, ap_bonus, ap_dot_bonus FROM spell_bonus_data");
2344 if (!result)
2345 {
2346 LOG_WARN("server.loading", ">> Loaded 0 spell bonus data. DB table `spell_bonus_data` is empty.");
2347 LOG_INFO("server.loading", " ");
2348 return;
2349 }
2350
2351 uint32 count = 0;
2352 do
2353 {
2354 Field* fields = result->Fetch();
2355 uint32 entry = fields[0].Get<uint32>();
2356
2357 SpellInfo const* spell = GetSpellInfo(entry);
2358 if (!spell)
2359 {
2360 LOG_ERROR("sql.sql", "Spell {} listed in `spell_bonus_data` does not exist", entry);
2361 continue;
2362 }
2363
2364 SpellBonusEntry& sbe = mSpellBonusMap[entry];
2365 sbe.direct_damage = fields[1].Get<float>();
2366 sbe.dot_damage = fields[2].Get<float>();
2367 sbe.ap_bonus = fields[3].Get<float>();
2368 sbe.ap_dot_bonus = fields[4].Get<float>();
2369
2370 ++count;
2371 } while (result->NextRow());
2372
2373 LOG_INFO("server.loading", ">> Loaded {} Extra Spell Bonus Data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2374 LOG_INFO("server.loading", " ");
2375}
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.

◆ LoadSpellCones()

void SpellMgr::LoadSpellCones ( )
1626{
1627 uint32 oldMSTime = getMSTime();
1628
1629 mSpellCones.clear(); // need for reload case
1630
1631 // 0 1
1632 QueryResult result = WorldDatabase.Query("SELECT ID, ConeDegrees FROM spell_cone");
1633
1634 if (!result)
1635 {
1636 LOG_WARN("server.loading", ">> Loaded 0 spell cone definitions. DB table `spell_cone` is empty.");
1637 LOG_INFO("server.loading", " ");
1638 return;
1639 }
1640
1641 uint32 count = 0;
1642 do
1643 {
1644 Field* fields = result->Fetch();
1645
1646 uint32 spellId = fields[0].Get<uint32>();
1647 int16 coneDeg = fields[1].Get<int16>();
1648
1649 SpellInfo const* spellInfo = GetSpellInfo(spellId);
1650 if (!spellInfo)
1651 {
1652 LOG_ERROR("sql.sql", "Spell (ID:{}) listed in `spell_cone` does not exist.", spellId);
1653 continue;
1654 }
1655
1656 if (coneDeg < -360 || coneDeg > 360)
1657 {
1658 LOG_ERROR("sql.sql", "Spell (Id: {}) cone degrees {} out of range (-360..360).", spellId, coneDeg);
1659 continue;
1660 }
1661
1662 uint32 firstRankId = GetFirstSpellInChain(spellId);
1663 SpellInfo const* firstSpellInfo = GetSpellInfo(firstRankId);
1664
1665 SpellInfo const* checkInfo = firstSpellInfo ? firstSpellInfo : spellInfo;
1666
1667 bool hasCone = false;
1668 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1669 {
1670 if (checkInfo->Effects[i].TargetA.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CONE ||
1671 checkInfo->Effects[i].TargetB.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CONE)
1672 {
1673 hasCone = true;
1674 break;
1675 }
1676 }
1677
1678 if (!hasCone)
1679 {
1680 LOG_ERROR("sql.sql", "Spell (ID:{}) listed in `spell_cone` does not have a cone implicit target.", spellId);
1681 continue;
1682 }
1683
1684 if (firstRankId != spellId)
1685 LOG_INFO("server.loading", "Spell (ID:{}) listed in `spell_cone` is not first rank; mapping to first rank {}.", spellId, firstRankId);
1686
1687 SpellCone sc{};
1688 sc.cone_degrees = coneDeg;
1689
1690 // Avoid overwriting an existing first-rank entry with conflicting values
1691 auto itr = mSpellCones.find(firstRankId);
1692 if (itr != mSpellCones.end())
1693 {
1694 if (itr->second.cone_degrees != sc.cone_degrees)
1695 LOG_ERROR("sql.sql",
1696 "Conflicting `spell_cone` entries for first-rank spell ID {}: {} vs {}. Keeping first value.",
1697 firstRankId,
1698 itr->second.cone_degrees,
1699 sc.cone_degrees);
1700 }
1701 else
1702 {
1703 mSpellCones[firstRankId] = sc;
1704 ++count;
1705 }
1706 } while (result->NextRow());
1707
1708 LOG_INFO("server.loading", ">> Loaded {} Spell Cone definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1709 LOG_INFO("server.loading", " ");
1710}
std::int16_t int16
Definition Define.h:104
@ TARGET_SELECT_CATEGORY_CONE
Definition SpellInfo.h:82
Definition SpellMgr.h:399
int16_t cone_degrees
Definition SpellMgr.h:400

References SpellCone::cone_degrees, SpellInfo::Effects, Field::Get(), GetFirstSpellInChain(), getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), LOG_ERROR, LOG_INFO, LOG_WARN, MAX_SPELL_EFFECTS, mSpellCones, TARGET_SELECT_CATEGORY_CONE, and WorldDatabase.

◆ LoadSpellCooldownOverrides()

void SpellMgr::LoadSpellCooldownOverrides ( )
3095{
3096 uint32 oldMSTime = getMSTime();
3097
3099
3100 QueryResult result = WorldDatabase.Query("SELECT Id, RecoveryTime, CategoryRecoveryTime, StartRecoveryTime, StartRecoveryCategory FROM spell_cooldown_overrides");
3101
3102 uint32 count = 0;
3103
3104 if (result)
3105 {
3106 do
3107 {
3108 Field* fields = result->Fetch();
3109 SpellCooldownOverride spellCooldown;
3110 uint32 spellId = fields[0].Get<uint32>();
3111 spellCooldown.RecoveryTime = fields[1].Get<uint32>();
3112 spellCooldown.CategoryRecoveryTime = fields[2].Get<uint32>();
3113 spellCooldown.StartRecoveryTime = fields[3].Get<uint32>();
3114 spellCooldown.StartRecoveryCategory = fields[4].Get<uint32>();
3115 mSpellCooldownOverrideMap[spellId] = spellCooldown;
3116
3117 ++count;
3118 } while (result->NextRow());
3119 }
3120
3121 LOG_INFO("server.loading", ">> Loaded {} Spell Cooldown Overrides entries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3122 LOG_INFO("server.loading", " ");
3123}
Definition SpellMgr.h:618
uint32 StartRecoveryTime
Definition SpellMgr.h:621
uint32 CategoryRecoveryTime
Definition SpellMgr.h:620
uint32 StartRecoveryCategory
Definition SpellMgr.h:622
uint32 RecoveryTime
Definition SpellMgr.h:619

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

◆ LoadSpellEnchantProcData()

void SpellMgr::LoadSpellEnchantProcData ( )
2581{
2582 uint32 oldMSTime = getMSTime();
2583
2584 mSpellEnchantProcEventMap.clear(); // need for reload case
2585
2586 // 0 1 2 3 4
2587 QueryResult result = WorldDatabase.Query("SELECT entry, customChance, PPMChance, procEx, attributeMask FROM spell_enchant_proc_data");
2588 if (!result)
2589 {
2590 LOG_WARN("server.loading", ">> Loaded 0 spell enchant proc event conditions. DB table `spell_enchant_proc_data` is empty.");
2591 LOG_INFO("server.loading", " ");
2592 return;
2593 }
2594
2595 uint32 count = 0;
2596 do
2597 {
2598 Field* fields = result->Fetch();
2599
2600 uint32 enchantId = fields[0].Get<uint32>();
2601
2602 SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchantId);
2603 if (!ench)
2604 {
2605 LOG_ERROR("sql.sql", "Enchancment {} listed in `spell_enchant_proc_data` does not exist", enchantId);
2606 continue;
2607 }
2608
2610
2611 spe.customChance = fields[1].Get<uint32>();
2612 spe.PPMChance = fields[2].Get<float>();
2613 spe.procEx = fields[3].Get<uint32>();
2614 spe.attributeMask = fields[4].Get<uint32>();
2615
2616 mSpellEnchantProcEventMap[enchantId] = spe;
2617
2618 ++count;
2619 } while (result->NextRow());
2620
2621 LOG_INFO("server.loading", ">> Loaded {} Enchant Proc Data Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2622 LOG_INFO("server.loading", " ");
2623}
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 ( )
1713{
1714 uint32 oldMSTime = getMSTime();
1715
1716 mSpellSpellGroup.clear(); // need for reload case
1717 mSpellGroupSpell.clear();
1718
1719 // 0 1
1720 QueryResult result = WorldDatabase.Query("SELECT id, spell_id FROM spell_group");
1721 if (!result)
1722 {
1723 LOG_WARN("server.loading", ">> Loaded 0 spell group definitions. DB table `spell_group` is empty.");
1724 LOG_INFO("server.loading", " ");
1725 return;
1726 }
1727
1728 std::set<uint32> groups;
1729 uint32 count = 0;
1730 do
1731 {
1732 Field* fields = result->Fetch();
1733
1734 uint32 group_id = fields[0].Get<uint32>();
1735 if (group_id <= SPELL_GROUP_DB_RANGE_MIN && group_id >= SPELL_GROUP_CORE_RANGE_MAX)
1736 {
1737 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group` is in core range, but is not defined in core!", group_id);
1738 continue;
1739 }
1740 int32 spell_id = fields[1].Get<int32>();
1741
1742 groups.insert(group_id);
1743 mSpellGroupSpell.emplace(SpellGroup(group_id), spell_id);
1744
1745 } while (result->NextRow());
1746
1747 for (auto itr = mSpellGroupSpell.begin(); itr!= mSpellGroupSpell.end();)
1748 {
1749 if (itr->second < 0)
1750 {
1751 if (groups.find(abs(itr->second)) == groups.end())
1752 {
1753 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group` does not exist", abs(itr->second));
1754 itr = mSpellGroupSpell.erase(itr);
1755 }
1756 else
1757 ++itr;
1758 }
1759 else
1760 {
1761 SpellInfo const* spellInfo = GetSpellInfo(itr->second);
1762 if (!spellInfo)
1763 {
1764 LOG_ERROR("sql.sql", "Spell {} listed in `spell_group` does not exist", itr->second);
1765 itr = mSpellGroupSpell.erase(itr);
1766 }
1767 else if (spellInfo->GetRank() > 1)
1768 {
1769 LOG_ERROR("sql.sql", "Spell {} listed in `spell_group` is not first rank of spell.", itr->second);
1770 itr = mSpellGroupSpell.erase(itr);
1771 }
1772 else
1773 ++itr;
1774 }
1775 }
1776
1777 for (auto groupItr = groups.begin(); groupItr != groups.end(); ++groupItr)
1778 {
1779 std::set<uint32> spells;
1781
1782 for (auto spellItr = spells.begin(); spellItr != spells.end(); ++spellItr)
1783 {
1784 ++count;
1785 mSpellSpellGroup.emplace(*spellItr, SpellGroup(*groupItr));
1786 }
1787 }
1788
1789 LOG_INFO("server.loading", ">> Loaded {} spell group Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1790 LOG_INFO("server.loading", " ");
1791}
@ SPELL_GROUP_CORE_RANGE_MAX
Definition SpellMgr.h:335
spells
Definition boss_krystallus.cpp:26
uint8 GetRank() const
Definition SpellInfo.cpp:2927

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 ( )
1794{
1795 uint32 oldMSTime = getMSTime();
1796
1797 mSpellGroupStack.clear(); // need for reload case
1798 mSpellSameEffectStack.clear();
1800
1801 std::vector<uint32> sameEffectGroups;
1802
1803 // 0 1
1804 QueryResult result = WorldDatabase.Query("SELECT group_id, stack_rule FROM spell_group_stack_rules");
1805 if (!result)
1806 {
1807 LOG_WARN("server.loading", ">> Loaded 0 spell group stack rules. DB table `spell_group_stack_rules` is empty.");
1808 LOG_INFO("server.loading", " ");
1809 return;
1810 }
1811
1812 uint32 count = 0;
1813 do
1814 {
1815 Field* fields = result->Fetch();
1816
1817 uint32 group_id = fields[0].Get<uint32>();
1818 uint8 stack_rule = fields[1].Get<int8>();
1819 if (stack_rule >= SPELL_GROUP_STACK_RULE_MAX)
1820 {
1821 LOG_ERROR("sql.sql", "SpellGroupStackRule {} listed in `spell_group_stack_rules` does not exist.", stack_rule);
1822 continue;
1823 }
1824
1825 auto bounds = GetSpellGroupSpellMapBounds((SpellGroup)group_id);
1826 if (bounds.first == bounds.second)
1827 {
1828 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group_stack_rules` does not exist.", group_id);
1829 continue;
1830 }
1831
1832 mSpellGroupStack.emplace(SpellGroup(group_id), SpellGroupStackRule(stack_rule));
1833
1834 // different container for same effect stack rules, need to check effect types
1836 sameEffectGroups.push_back(group_id);
1837
1838 ++count;
1839 } while (result->NextRow());
1840
1841 LOG_INFO("server.loading", ">> Loaded {} spell group stack rules in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1842 LOG_INFO("server.loading", " ");
1843
1844 count = 0;
1845 oldMSTime = getMSTime();
1846
1847 for (uint32 group_id : sameEffectGroups)
1848 {
1849 std::set<uint32> spellIds;
1850 GetSetOfSpellsInSpellGroup(SpellGroup(group_id), spellIds);
1851
1852 std::unordered_set<uint32> auraTypes;
1853
1854 // we have to 'guess' what effect this group corresponds to
1855 {
1856 std::unordered_multiset<uint32 /*auraName*/> frequencyContainer;
1857
1858 // only waylay for the moment (shared group)
1859 std::vector<std::vector<uint32 /*auraName*/>> const SubGroups =
1860 {
1862 };
1863
1864 for (uint32 spellId : spellIds)
1865 {
1866 SpellInfo const* spellInfo = AssertSpellInfo(spellId);
1867 for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
1868 {
1869 if (!spellEffectInfo.IsAura())
1870 continue;
1871
1872 uint32 auraName = spellEffectInfo.ApplyAuraName;
1873 for (std::vector<uint32> const& subGroup : SubGroups)
1874 {
1875 if (std::find(subGroup.begin(), subGroup.end(), auraName) != subGroup.end())
1876 {
1877 // count as first aura
1878 auraName = subGroup.front();
1879 break;
1880 }
1881 }
1882
1883 frequencyContainer.insert(auraName);
1884 }
1885 }
1886
1887 uint32 auraType = 0;
1888 size_t auraTypeCount = 0;
1889 for (uint32 auraName : frequencyContainer)
1890 {
1891 size_t currentCount = frequencyContainer.count(auraName);
1892 if (currentCount > auraTypeCount)
1893 {
1894 auraType = auraName;
1895 auraTypeCount = currentCount;
1896 }
1897 }
1898
1899 for (std::vector<uint32> const& subGroup : SubGroups)
1900 {
1901 if (auraType == subGroup.front())
1902 {
1903 auraTypes.insert(subGroup.begin(), subGroup.end());
1904 break;
1905 }
1906 }
1907
1908 if (auraTypes.empty())
1909 auraTypes.insert(auraType);
1910 }
1911
1912 // re-check spells against guessed group
1913 for (uint32 spellId : spellIds)
1914 {
1915 SpellInfo const* spellInfo = AssertSpellInfo(spellId);
1916
1917 bool found = false;
1918 while (spellInfo)
1919 {
1920 for (uint32 auraType : auraTypes)
1921 {
1922 if (spellInfo->HasAura(AuraType(auraType)))
1923 {
1924 found = true;
1925 break;
1926 }
1927 }
1928
1929 if (found)
1930 break;
1931
1932 spellInfo = spellInfo->GetNextRankSpell();
1933 }
1934
1935 // not found either, log error
1936 if (!found)
1937 LOG_ERROR("sql.sql", "SpellId {} listed in `spell_group` with stack rule 3 does not share aura assigned for group {}", spellId, group_id);
1938 }
1939
1940 // a spell can be in several groups for the same aura type (one per stat, e.g. K'iru's Song of Victory),
1941 // keep the (auraType, miscValue) pairs carried by at least two spells to tell which group an effect is in
1942 {
1943 std::map<std::pair<uint32 /*auraName*/, int32 /*miscValue*/>, uint32 /*spellCount*/> miscCount;
1944 for (uint32 spellId : spellIds)
1945 {
1946 std::set<std::pair<uint32, int32>> spellPairs;
1947 SpellInfo const* spellInfo = AssertSpellInfo(spellId);
1948 for (; spellInfo; spellInfo = spellInfo->GetNextRankSpell())
1949 {
1950 for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
1951 {
1952 if (!spellEffectInfo.IsAura() || !auraTypes.count(spellEffectInfo.ApplyAuraName))
1953 continue;
1954
1955 spellPairs.emplace(uint32(spellEffectInfo.ApplyAuraName), spellEffectInfo.MiscValue);
1956 }
1957 }
1958
1959 for (auto const& spellPair : spellPairs)
1960 ++miscCount[spellPair];
1961 }
1962
1963 for (auto const& [spellPair, spellCount] : miscCount)
1964 if (spellCount >= 2)
1965 mSpellSameEffectSharedMisc[SpellGroup(group_id)].insert(spellPair);
1966 }
1967
1968 mSpellSameEffectStack[SpellGroup(group_id)] = auraTypes;
1969 ++count;
1970 }
1971
1972 LOG_INFO("server.loading", ">> Loaded {} SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT stack rules in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1973 LOG_INFO("server.loading", " ");
1974}
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:2946
bool HasAura(AuraType aura) const
Definition SpellInfo.cpp:906
SpellInfo const * AssertSpellInfo(uint32 spellId) const
Definition SpellMgr.h:747

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

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, CHANNEL_INTERRUPT_FLAG_INTERRUPT, 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_SCHOOL_IMMUNITIES, 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_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_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.
3208{
3209 uint32 const oldMSTime = getMSTime();
3210 uint32 const customAttrTime = getMSTime();
3211 uint32 count;
3212
3213 QueryResult result = WorldDatabase.Query("SELECT spell_id, attributes FROM spell_custom_attr");
3214
3215 if (!result)
3216 {
3217 LOG_WARN("server.loading", ">> Loaded 0 Spell Custom Attributes From DB. DB table `spell_custom_attr` Is Empty.");
3218 }
3219 else
3220 {
3221 count = 0;
3222
3223 do
3224 {
3225 ++count;
3226
3227 Field const* fields = result->Fetch();
3228
3229 uint32 const spellId = fields[0].Get<uint32>();
3230 uint32 attributes = fields[1].Get<uint32>();
3231
3232 SpellInfo* spellInfo = _GetSpellInfo(spellId);
3233 if (!spellInfo)
3234 {
3235 LOG_INFO("sql.sql", "Table `spell_custom_attr` has wrong spell (spell_id: {}), ignored.", spellId);
3236 continue;
3237 }
3238
3239 if (attributes & SPELL_ATTR0_CU_NEGATIVE)
3240 {
3241 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3242 {
3243 if (spellInfo->Effects[i].IsEffect())
3244 {
3245 if ((attributes & (SPELL_ATTR0_CU_NEGATIVE_EFF0 << i)) && (attributes & (SPELL_ATTR0_CU_POSITIVE_EFF0 << i)))
3246 {
3247 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);
3249 }
3250 continue;
3251 }
3252
3253 if (attributes & (SPELL_ATTR0_CU_NEGATIVE_EFF0 << i))
3254 {
3255 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));
3256 attributes &= ~(SPELL_ATTR0_CU_NEGATIVE_EFF0 << i);
3257 }
3258 }
3259 }
3260
3261 if (attributes & SPELL_ATTR0_CU_POSITIVE)
3262 {
3263 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3264 {
3265 if (spellInfo->Effects[i].IsEffect())
3266 {
3267 continue;
3268 }
3269
3270 if ((attributes & (SPELL_ATTR0_CU_POSITIVE_EFF0 << i)))
3271 {
3272 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));
3273 attributes &= ~(SPELL_ATTR0_CU_POSITIVE_EFF0 << i);
3274 }
3275 }
3276 }
3277
3278 if ((attributes & SPELL_ATTR0_CU_FORCE_AURA_SAVING) && (attributes & SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED))
3279 {
3280 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);
3282 }
3283
3284 spellInfo->AttributesCu |= attributes;
3285 } while (result->NextRow());
3286
3287 LOG_INFO("server.loading", ">> Loaded {} spell custom attributes from DB in {} ms", count, GetMSTimeDiffToNow(customAttrTime));
3288 }
3289
3290 // xinef: create talent spells set
3291 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
3292 {
3293 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
3294 if (!talentInfo)
3295 continue;
3296
3297 for (uint8 j = 0; j < MAX_TALENT_RANK; j++)
3298 if (uint32 spellId = talentInfo->RankID[j])
3299 if (SpellInfo const* spellInfo = GetSpellInfo(spellId))
3300 for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
3301 if (spellInfo->Effects[k].Effect == SPELL_EFFECT_LEARN_SPELL)
3302 if (SpellInfo const* learnSpell = GetSpellInfo(spellInfo->Effects[k].TriggerSpell))
3303 if (learnSpell->IsRanked() && !learnSpell->HasAttribute(SpellAttr0(SPELL_ATTR0_PASSIVE | SPELL_ATTR0_DO_NOT_DISPLAY)))
3304 mTalentSpellAdditionalSet.insert(learnSpell->Id);
3305 }
3306
3307 SpellInfo* spellInfo = nullptr;
3308 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3309 {
3310 spellInfo = mSpellInfoMap[i];
3311 if (!spellInfo)
3312 continue;
3313
3314 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3315 {
3316 switch (spellInfo->Effects[j].ApplyAuraName)
3317 {
3319 {
3320 switch (spellInfo->Id)
3321 {
3322 // Exceptions
3323 case 44801: // Spectral Invisibility (Kalecgos, SWP)
3324 case 46021: // Spectral Realm (SWP)
3325 case 52951: // Chapel Invisibility (DK starting zone)
3326 case 43062: // Alpha Worg: Garwal's Invisibility
3327 case 45614: // Shroud of the Scourge (Blending In, Temple City of En'kilah)
3328 break;
3329 default:
3331 break;
3332 }
3333 }
3334 break;
3341 break;
3342 default:
3343 break;
3344 }
3345
3346 switch (spellInfo->Effects[j].ApplyAuraName)
3347 {
3348 case SPELL_AURA_CONVERT_RUNE: // Can't be saved - aura handler relies on calculated amount and changes it
3349 case SPELL_AURA_OPEN_STABLE: // No point in saving this, since the stable dialog can't be open on aura load anyway.
3350 // Auras that require both caster & target to be in world cannot be saved
3358 break;
3359 default:
3360 break;
3361 }
3362
3363 switch (spellInfo->Effects[j].ApplyAuraName)
3364 {
3372 break;
3375 break;
3376 default:
3377 break;
3378 }
3379
3380 switch (spellInfo->Effects[j].Effect)
3381 {
3387 case SPELL_EFFECT_HEAL:
3389 break;
3400 break;
3403 break;
3408 {
3409 // Only Enchanting profession enchant procs can stack when dual-wielding
3410 // DK runes (e.g., Unholy Strength) should refresh, not stack
3412 {
3413 uint32 enchantId = spellInfo->Effects[j].MiscValue;
3414 SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId);
3415 if (!enchant)
3416 break;
3417
3418 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
3419 {
3420 if (enchant->type[s] != ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL)
3421 continue;
3422
3423 SpellInfo* procInfo = _GetSpellInfo(enchant->spellid[s]);
3424 if (!procInfo)
3425 continue;
3426
3427 // if proced directly from enchantment, not via proc aura
3428 // NOTE: Enchant Weapon - Blade Ward also has proc aura spell and is proced directly
3429 // however its not expected to stack so this check is good
3431 continue;
3432
3434 }
3435 }
3436 break;
3437 }
3438 }
3439 }
3440
3441 // Xinef: spells ignoring hit result should not be binary
3443 {
3444 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3445 {
3446 if (spellInfo->Effects[j].Effect)
3447 {
3448 switch (spellInfo->Effects[j].Effect)
3449 {
3457 continue;
3466 if (spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
3467 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE_PERCENT ||
3468 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_DUMMY ||
3469 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH ||
3470 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_HEALTH_FUNNEL ||
3471 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DUMMY)
3472 continue;
3473 [[fallthrough]];
3474 default:
3475 if (!(spellInfo->Effects[j].CalcValue() ||
3476 ((spellInfo->Effects[j].Effect == SPELL_EFFECT_INTERRUPT_CAST || spellInfo->HasAttribute(SPELL_ATTR0_CU_DONT_BREAK_STEALTH)) &&
3478 continue;
3479
3480 if (spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && (spellInfo->SpellFamilyFlags[0] & 0x20)) // Frostbolt
3481 continue;
3482
3483 if (spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK &&
3484 ((spellInfo->SpellFamilyFlags[1] & 0x40000) || (spellInfo->SpellFamilyFlags[0] & 0x4000))) // Haunt/Drain Soul
3485 continue;
3486
3488 break;
3489 }
3490 }
3491 }
3492 }
3493
3494 // pussywizard:
3495 if ((spellInfo->SchoolMask & SPELL_SCHOOL_MASK_NORMAL) && (spellInfo->SchoolMask & SPELL_SCHOOL_MASK_MAGIC))
3496 {
3497 spellInfo->SchoolMask &= ~SPELL_SCHOOL_MASK_NORMAL;
3499 }
3500
3501 if (!spellInfo->_IsPositiveEffect(EFFECT_0, false))
3503
3504 if (!spellInfo->_IsPositiveEffect(EFFECT_1, false))
3506
3507 if (!spellInfo->_IsPositiveEffect(EFFECT_2, false))
3509
3510 if (spellInfo->SpellVisual[0] == 3879)
3512
3513 switch (spellInfo->SpellFamilyName)
3514 {
3516 // Shout
3517 if (spellInfo->SpellFamilyFlags[0] & 0x20000 || spellInfo->SpellFamilyFlags[1] & 0x20)
3519 break;
3520 case SPELLFAMILY_DRUID:
3521 // Roar
3522 if (spellInfo->SpellFamilyFlags[0] & 0x8)
3524 break;
3525 case SPELLFAMILY_HUNTER:
3526 // Aspects
3527 if (spellInfo->GetCategory() == 47)
3528 {
3530 }
3531 // Aimed Shot
3532 if (spellInfo->SpellFamilyFlags[0] & 0x00020000)
3533 {
3535 }
3536 break;
3537 default:
3538 break;
3539 }
3540
3541 switch (spellInfo->Id)
3542 {
3543 // Xinef: NOT CUSTOM, cant add in DBC CORRECTION because i need to swap effects, too much work to do there
3544 // Envenom
3545 case 32645:
3546 case 32684:
3547 case 57992:
3548 case 57993:
3549 {
3550 SpellEffectInfo info = spellInfo->Effects[EFFECT_0];
3551 spellInfo->Effects[EFFECT_0] = spellInfo->Effects[EFFECT_2];
3552 spellInfo->Effects[EFFECT_2] = info;
3553 break;
3554 }
3555
3556 // Xinef: Cooldown overwrites
3557 // Burst of Speed
3558 case 57493:
3559 spellInfo->RecoveryTime = 60000;
3560 spellInfo->_requireCooldownInfo = true;
3561 break;
3562 // Strafe Jotunheim Building
3563 case 7769:
3564 spellInfo->RecoveryTime = 1500;
3565 spellInfo->_requireCooldownInfo = true;
3566 break;
3567 case 44535: // Spirit Heal, abilities also have no cost
3568 spellInfo->Effects[EFFECT_0].MiscValue = 127;
3569 break;
3570 default:
3571 break;
3572 }
3573
3574 if (spellInfo->Speed > 0.0f)
3575 {
3576 if (SpellVisualEntry const* spellVisual = sSpellVisualStore.LookupEntry(spellInfo->SpellVisual[0]))
3577 {
3578 if (spellVisual->HasMissile)
3579 {
3580 if (spellVisual->MissileModel == -4 || spellVisual->MissileModel == -5)
3581 {
3583 }
3584 }
3585 }
3586 }
3587
3588 spellInfo->_InitializeExplicitTargetMask();
3589
3590 if (HasSpellCooldownOverride(spellInfo->Id))
3591 {
3592 SpellCooldownOverride spellOverride = GetSpellCooldownOverride(spellInfo->Id);
3593
3594 if (spellInfo->RecoveryTime != spellOverride.RecoveryTime)
3595 {
3596 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3597 }
3598
3599 if (spellInfo->CategoryRecoveryTime != spellOverride.CategoryRecoveryTime)
3600 {
3601 spellInfo->CategoryRecoveryTime = spellOverride.CategoryRecoveryTime;
3602 }
3603
3604 if (spellInfo->StartRecoveryTime != spellOverride.StartRecoveryTime)
3605 {
3606 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3607 }
3608
3609 if (spellInfo->StartRecoveryCategory != spellOverride.StartRecoveryCategory)
3610 {
3611 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3612 }
3613 }
3614
3615 sScriptMgr->OnLoadSpellCustomAttr(spellInfo);
3616 }
3617
3618 // Xinef: addition for binary spells, ommit spells triggering other spells
3619 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3620 {
3621 spellInfo = mSpellInfoMap[i];
3622 if (!spellInfo)
3623 continue;
3624
3625 if (!(spellInfo->AttributesCu & SPELL_ATTR0_CU_BINARY_SPELL))
3626 continue;
3627
3628 bool allNonBinary = true;
3629 bool overrideAttr = false;
3630 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3631 {
3632 if (spellInfo->Effects[j].ApplyAuraName && spellInfo->Effects[j].TriggerSpell)
3633 {
3634 switch (spellInfo->Effects[j].ApplyAuraName)
3635 {
3639 if (SpellInfo const* triggerSpell = GetSpellInfo(spellInfo->Effects[j].TriggerSpell))
3640 {
3641 overrideAttr = true;
3642 if (triggerSpell->AttributesCu & SPELL_ATTR0_CU_BINARY_SPELL)
3643 allNonBinary = false;
3644 }
3645 break;
3646 default:
3647 break;
3648 }
3649 }
3650 }
3651
3652 if (overrideAttr && allNonBinary)
3653 spellInfo->AttributesCu &= ~SPELL_ATTR0_CU_BINARY_SPELL;
3654 }
3655
3656 LOG_INFO("server.loading", ">> Loaded SpellInfo Custom Attributes in {} ms", GetMSTimeDiffToNow(oldMSTime));
3657 LOG_INFO("server.loading", " ");
3658}
@ ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL
Definition DBCEnums.h:367
DBCStorage< SpellVisualEntry > sSpellVisualStore(SpellVisualfmt)
DBCStorage< TalentEntry > sTalentStore(TalentEntryfmt)
#define MAX_TALENT_RANK
Definition DBCStructure.h:1954
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition DBCStructure.h:1874
#define sScriptMgr
Definition ScriptMgr.h:768
@ 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_BINARY
Definition SpellInfo.h:186
@ SPELL_ATTR0_CU_ENCHANT_PROC
Definition SpellInfo.h:177
@ 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_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_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_SCHOOLMASK_NORMAL_WITH_MAGIC
Definition SpellInfo.h:200
@ SPELL_ATTR0_CU_PICKPOCKET
Definition SpellInfo.h:187
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition SpellInfo.h:181
bool IsPartOfSkillLine(uint32 skillId, uint32 spellId)
Definition SpellMgr.cpp:50
uint32 GetCategory() const
Definition SpellInfo.cpp:884
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:3057
uint32 StartRecoveryTime
Definition SpellInfo.h:375
void _InitializeExplicitTargetMask()
Definition SpellInfo.cpp:3029
uint32 StartRecoveryCategory
Definition SpellInfo.h:374
uint32 AuraInterruptFlags
Definition SpellInfo.h:377
SpellCooldownOverride GetSpellCooldownOverride(uint32 spellId) const
Definition SpellMgr.cpp:3130
SpellInfo * _GetSpellInfo(uint32 spellId)
Definition SpellMgr.h:779
bool HasSpellCooldownOverride(uint32 spellId) const
Definition SpellMgr.cpp:3125
uint32 spellid[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition DBCStructure.h:1883
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition DBCStructure.h:1880
Definition DBCStructure.h:1907
Definition DBCStructure.h:1959
std::array< uint32, MAX_TALENT_RANK > RankID
Definition DBCStructure.h:1964

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_AURA_CANNOT_BE_SAVED, SPELL_ATTR0_CU_AURA_CC, SPELL_ATTR0_CU_BINARY_SPELL, SPELL_ATTR0_CU_CONE_BACK, 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_BINARY, 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_PVP_FLAG, SPELL_ATTR0_CU_PICKPOCKET, SPELL_ATTR0_CU_POSITIVE, SPELL_ATTR0_CU_POSITIVE_EFF0, SPELL_ATTR0_CU_SCHOOLMASK_NORMAL_WITH_MAGIC, 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_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_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 ( )
3661{
3662 uint32 oldMSTime = getMSTime();
3663
3664 for (SpellInfo* spellInfo : mSpellInfoMap)
3665 {
3666 if (!spellInfo)
3667 continue;
3668 spellInfo->_LoadImmunityInfo();
3669 }
3670
3671 LOG_INFO("server.loading", ">> Loaded SpellInfo immunity infos in {} ms", GetMSTimeDiffToNow(oldMSTime));
3672}

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

◆ LoadSpellInfoStore()

void SpellMgr::LoadSpellInfoStore ( )
3064{
3065 uint32 oldMSTime = getMSTime();
3066
3068 mSpellInfoMap.resize(sSpellStore.GetNumRows(), nullptr);
3069
3070 for (SpellEntry const* spellEntry : sSpellStore)
3071 mSpellInfoMap[spellEntry->Id] = new SpellInfo(spellEntry);
3072
3073 for (uint32 spellIndex = 0; spellIndex < GetSpellInfoStoreSize(); ++spellIndex)
3074 {
3075 if (!mSpellInfoMap[spellIndex])
3076 continue;
3077
3078 for (SpellEffectInfo const& spellEffectInfo : mSpellInfoMap[spellIndex]->GetEffects())
3079 {
3080 //ASSERT(effect.EffectIndex < MAX_SPELL_EFFECTS, "MAX_SPELL_EFFECTS must be at least {}", effect.EffectIndex + 1);
3081 ASSERT(spellEffectInfo.Effect < TOTAL_SPELL_EFFECTS, "TOTAL_SPELL_EFFECTS must be at least {}", spellEffectInfo.Effect + 1);
3082 ASSERT(spellEffectInfo.ApplyAuraName < TOTAL_AURAS, "TOTAL_AURAS must be at least {}", spellEffectInfo.ApplyAuraName + 1);
3083 ASSERT(spellEffectInfo.TargetA.GetTarget() < TOTAL_SPELL_TARGETS, "TOTAL_SPELL_TARGETS must be at least {}", spellEffectInfo.TargetA.GetTarget() + 1);
3084 ASSERT(spellEffectInfo.TargetB.GetTarget() < TOTAL_SPELL_TARGETS, "TOTAL_SPELL_TARGETS must be at least {}", spellEffectInfo.TargetB.GetTarget() + 1);
3085 }
3086 }
3087
3089
3090 LOG_INFO("server.loading", ">> Loaded Spell Custom Attributes in {} ms", GetMSTimeDiffToNow(oldMSTime));
3091 LOG_INFO("server.loading", " ");
3092}
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
@ TOTAL_SPELL_TARGETS
Definition SharedDefines.h:1518
void LoadCreatureImmunities()
Definition SpellMgr.cpp:65
Definition DBCStructure.h:1678

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

◆ LoadSpellJumpDistances()

void SpellMgr::LoadSpellJumpDistances ( )
3172{
3173 uint32 oldMSTime = getMSTime();
3174
3175 QueryResult result = WorldDatabase.Query("SELECT ID, JumpDistance FROM spell_jump_distance");
3176
3177 if (!result)
3178 {
3179 LOG_WARN("server.loading", ">> Loaded 0 spell jump distances. DB table `spell_jump_distance` is empty.");
3180 LOG_INFO("server.loading", " ");
3181 return;
3182 }
3183
3184 uint32 count = 0;
3185 do
3186 {
3187 Field const* fields = result->Fetch();
3188
3189 uint32 const spellId = fields[0].Get<uint32>();
3190 float const jumpDistance = fields[1].Get<float>();
3191
3192 SpellInfo* spellInfo = _GetSpellInfo(spellId);
3193 if (!spellInfo)
3194 {
3195 LOG_ERROR("sql.sql", "Table `spell_jump_distance` has wrong spell (spell_id: {}), ignored.", spellId);
3196 continue;
3197 }
3198
3199 spellInfo->JumpDistance = jumpDistance;
3200 ++count;
3201 } while (result->NextRow());
3202
3203 LOG_INFO("server.loading", ">> Loaded {} spell jump distances in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3204 LOG_INFO("server.loading", " ");
3205}

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

◆ LoadSpellLearnSkills()

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

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 ( )
2626{
2627 uint32 oldMSTime = getMSTime();
2628
2629 mSpellLinkedMap.clear(); // need for reload case
2630
2631 // 0 1 2
2632 QueryResult result = WorldDatabase.Query("SELECT spell_trigger, spell_effect, type FROM spell_linked_spell");
2633 if (!result)
2634 {
2635 LOG_WARN("server.loading", ">> Loaded 0 linked spells. DB table `spell_linked_spell` is empty.");
2636 LOG_INFO("server.loading", " ");
2637 return;
2638 }
2639
2640 uint32 count = 0;
2641 do
2642 {
2643 Field* fields = result->Fetch();
2644
2645 int32 trigger = fields[0].Get<int32>();
2646 int32 effect = fields[1].Get<int32>();
2647 int32 type = fields[2].Get<uint8>();
2648
2649 SpellInfo const* spellInfo = GetSpellInfo(std::abs(trigger));
2650 if (!spellInfo)
2651 {
2652 LOG_ERROR("sql.sql", "Spell {} listed in `spell_linked_spell` does not exist", std::abs(trigger));
2653 continue;
2654 }
2655 spellInfo = GetSpellInfo(std::abs(effect));
2656 if (!spellInfo)
2657 {
2658 LOG_ERROR("sql.sql", "Spell {} listed in `spell_linked_spell` does not exist", std::abs(effect));
2659 continue;
2660 }
2661
2662 if (type) //we will find a better way when more types are needed
2663 {
2664 if (trigger > 0)
2665 trigger += SPELL_LINKED_MAX_SPELLS * type;
2666 else
2667 trigger -= SPELL_LINKED_MAX_SPELLS * type;
2668 }
2669 mSpellLinkedMap[trigger].push_back(effect);
2670
2671 ++count;
2672 } while (result->NextRow());
2673
2674 LOG_INFO("server.loading", ">> Loaded {} Linked Spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2675 LOG_INFO("server.loading", " ");
2676}
#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 ( )
2419{
2420 uint32 oldMSTime = getMSTime();
2421
2422 mSpellMixologyMap.clear(); // need for reload case
2423
2424 // 0 1
2425 QueryResult result = WorldDatabase.Query("SELECT entry, pctMod FROM spell_mixology");
2426 if (!result)
2427 {
2428 LOG_WARN("server.loading", ">> Loaded 0 mixology bonuses. DB table `spell_mixology` is empty.");
2429 LOG_INFO("server.loading", " ");
2430 return;
2431 }
2432
2433 uint32 count = 0;
2434 do
2435 {
2436 Field* fields = result->Fetch();
2437
2438 uint32 entry = fields[0].Get<uint32>();
2439
2440 if (!GetSpellInfo(entry))
2441 {
2442 LOG_ERROR("sql.sql", "Spell {} listed in `spell_mixology` does not exist", entry);
2443 continue;
2444 }
2445
2446 mSpellMixologyMap[entry] = fields[1].Get<float>();
2447 ++count;
2448 } while (result->NextRow());
2449
2450 LOG_INFO("server.loading", ">> Loaded {} Mixology Bonuses in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2451 LOG_INFO("server.loading", " ");
2452}

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

◆ LoadSpellPetAuras()

void SpellMgr::LoadSpellPetAuras ( )
2477{
2478 uint32 oldMSTime = getMSTime();
2479
2480 mSpellPetAuraMap.clear(); // need for reload case
2481
2482 // 0 1 2 3
2483 QueryResult result = WorldDatabase.Query("SELECT spell, effectId, pet, aura FROM spell_pet_auras");
2484 if (!result)
2485 {
2486 LOG_WARN("server.loading", ">> Loaded 0 spell pet auras. DB table `spell_pet_auras` is empty.");
2487 LOG_INFO("server.loading", " ");
2488 return;
2489 }
2490
2491 uint32 count = 0;
2492 do
2493 {
2494 Field* fields = result->Fetch();
2495
2496 uint32 spell = fields[0].Get<uint32>();
2497 uint8 eff = fields[1].Get<uint8>();
2498 uint32 pet = fields[2].Get<uint32>();
2499 uint32 aura = fields[3].Get<uint32>();
2500
2501 SpellPetAuraMap::iterator itr = mSpellPetAuraMap.find((spell << 8) + eff);
2502 if (itr != mSpellPetAuraMap.end())
2503 itr->second.AddAura(pet, aura);
2504 else
2505 {
2506 SpellInfo const* spellInfo = GetSpellInfo(spell);
2507 if (!spellInfo)
2508 {
2509 LOG_ERROR("sql.sql", "Spell {} listed in `spell_pet_auras` does not exist", spell);
2510 continue;
2511 }
2512 if (spellInfo->Effects[eff].Effect != SPELL_EFFECT_DUMMY &&
2513 (spellInfo->Effects[eff].Effect != SPELL_EFFECT_APPLY_AURA ||
2514 spellInfo->Effects[eff].ApplyAuraName != SPELL_AURA_DUMMY))
2515 {
2516 LOG_ERROR("spells", "Spell {} listed in `spell_pet_auras` does not have dummy aura or dummy effect", spell);
2517 continue;
2518 }
2519
2520 SpellInfo const* spellInfo2 = GetSpellInfo(aura);
2521 if (!spellInfo2)
2522 {
2523 LOG_ERROR("sql.sql", "Aura {} listed in `spell_pet_auras` does not exist", aura);
2524 continue;
2525 }
2526
2527 PetAura pa(pet, aura, spellInfo->Effects[eff].TargetA.GetTarget() == TARGET_UNIT_PET, spellInfo->Effects[eff].CalcValue());
2528 mSpellPetAuraMap[(spell << 8) + eff] = pa;
2529 }
2530
2531 ++count;
2532 } while (result->NextRow());
2533
2534 LOG_INFO("server.loading", ">> Loaded {} Spell Pet Auras in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2535 LOG_INFO("server.loading", " ");
2536}
Definition SpellMgr.h:469

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 ( )
2048{
2049 uint32 oldMSTime = getMSTime();
2050
2051 mSpellProcMap.clear(); // need for reload case
2052
2053 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
2054 QueryResult result = WorldDatabase.Query("SELECT SpellId, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, ProcFlags, SpellTypeMask, SpellPhaseMask, HitMask, AttributesMask, DisableEffectsMask, ProcsPerMinute, Chance, Cooldown, Charges FROM spell_proc");
2055 if (!result)
2056 {
2057 LOG_WARN("server.loading", ">> Loaded 0 Spell Proc Conditions And Data. DB table `spell_proc` Is Empty.");
2058 LOG_INFO("server.loading", " ");
2059 return;
2060 }
2061
2062 uint32 count = 0;
2063 do
2064 {
2065 Field* fields = result->Fetch();
2066
2067 int32 spellId = fields[0].Get<int32>();
2068
2069 bool allRanks = false;
2070 if (spellId < 0)
2071 {
2072 allRanks = true;
2073 spellId = -spellId;
2074 }
2075
2076 SpellInfo const* spellInfo = GetSpellInfo(spellId);
2077 if (!spellInfo)
2078 {
2079 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` does not exist", spellId);
2080 continue;
2081 }
2082
2083 if (allRanks)
2084 {
2085 if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId))
2086 {
2087 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` is not first rank of spell.", fields[0].Get<int32>());
2088 continue;
2089 }
2090 }
2091
2092 SpellProcEntry baseProcEntry;
2093
2094 baseProcEntry.SchoolMask = fields[1].Get<int8>();
2095 baseProcEntry.SpellFamilyName = fields[2].Get<uint16>();
2096 baseProcEntry.SpellFamilyMask[0] = fields[3].Get<uint32>();
2097 baseProcEntry.SpellFamilyMask[1] = fields[4].Get<uint32>();
2098 baseProcEntry.SpellFamilyMask[2] = fields[5].Get<uint32>();
2099 baseProcEntry.ProcFlags = fields[6].Get<uint32>();
2100 baseProcEntry.SpellTypeMask = fields[7].Get<uint32>();
2101 baseProcEntry.SpellPhaseMask = fields[8].Get<uint32>();
2102 baseProcEntry.HitMask = fields[9].Get<uint32>();
2103 baseProcEntry.AttributesMask = fields[10].Get<uint32>();
2104 baseProcEntry.DisableEffectsMask = fields[11].Get<uint32>();
2105 baseProcEntry.ProcsPerMinute = fields[12].Get<float>();
2106 baseProcEntry.Chance = fields[13].Get<float>();
2107 baseProcEntry.Cooldown = Milliseconds(fields[14].Get<uint32>());
2108 baseProcEntry.Charges = fields[15].Get<uint32>();
2109
2110 while (spellInfo)
2111 {
2112 if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end())
2113 {
2114 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` has duplicate entry in the table", spellId);
2115 break;
2116 }
2117 SpellProcEntry procEntry = SpellProcEntry(baseProcEntry);
2118
2119 // take defaults from dbcs
2120 if (!procEntry.ProcFlags)
2121 procEntry.ProcFlags = spellInfo->ProcFlags;
2122 if (!procEntry.Charges)
2123 procEntry.Charges = spellInfo->ProcCharges;
2124 if (!procEntry.Chance && !procEntry.ProcsPerMinute)
2125 procEntry.Chance = float(spellInfo->ProcChance);
2126
2127 // validate data
2128 if (procEntry.SchoolMask & ~SPELL_SCHOOL_MASK_ALL)
2129 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SchoolMask` set: {}", spellId, procEntry.SchoolMask);
2130 if (procEntry.SpellFamilyName && (procEntry.SpellFamilyName < 3 || procEntry.SpellFamilyName > 17 || procEntry.SpellFamilyName == 14 || procEntry.SpellFamilyName == 16))
2131 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellFamilyName` set: {}", spellId, procEntry.SpellFamilyName);
2132 if (procEntry.Chance < 0)
2133 {
2134 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `Chance` field", spellId);
2135 procEntry.Chance = 0;
2136 }
2137 if (procEntry.ProcsPerMinute < 0)
2138 {
2139 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `ProcsPerMinute` field", spellId);
2140 procEntry.ProcsPerMinute = 0;
2141 }
2142 if (procEntry.Charges > 99)
2143 {
2144 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has too big value in `Charges` field", spellId);
2145 procEntry.Charges = 99;
2146 }
2147 if (!procEntry.ProcFlags)
2148 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} doesn't have `ProcFlags` value defined, proc will not be triggered", spellId);
2149 if (procEntry.SpellTypeMask & ~PROC_SPELL_TYPE_MASK_ALL)
2150 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellTypeMask` set: {}", spellId, procEntry.SpellTypeMask);
2151 if (procEntry.SpellTypeMask && !(procEntry.ProcFlags & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK)))
2152 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);
2153 if (!procEntry.SpellPhaseMask && procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK)
2154 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);
2156 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellPhaseMask` set: {}", spellId, procEntry.SpellPhaseMask);
2157 if (procEntry.SpellPhaseMask && !(procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK))
2158 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);
2159 if (procEntry.HitMask & ~PROC_HIT_MASK_ALL)
2160 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `HitMask` set: {}", spellId, procEntry.HitMask);
2161 // HitMask is valid for: TAKEN procs, or DONE procs at any phase (CAST phase has pre-calculated crit for travel-time spells)
2162 if (procEntry.HitMask && !(procEntry.ProcFlags & TAKEN_HIT_PROC_FLAG_MASK || procEntry.ProcFlags & DONE_HIT_PROC_FLAG_MASK))
2163 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);
2164 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2165 if ((procEntry.DisableEffectsMask & (1u << i)) && !spellInfo->Effects[i].IsAura())
2166 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));
2167 if (procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD)
2168 {
2169 bool found = false;
2170 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2171 {
2172 if (!spellInfo->Effects[i].IsAura())
2173 continue;
2174
2175 if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_ADD_PCT_MODIFIER || spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_ADD_FLAT_MODIFIER
2176 || spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_SPELL_CRIT_CHANCE || spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL)
2177 {
2178 found = true;
2179 break;
2180 }
2181 }
2182
2183 if (!found)
2184 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);
2185 }
2186
2187 mSpellProcMap[spellInfo->Id] = procEntry;
2188
2189 if (allRanks)
2190 spellInfo = spellInfo->GetNextRankSpell();
2191 else
2192 break;
2193 }
2194 ++count;
2195 } while (result->NextRow());
2196
2197 LOG_INFO("server.loading", ">> Loaded {} spell proc conditions and data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2198 LOG_INFO("server.loading", " ");
2199
2200 // Generate default procs for spells with proc flags but no explicit spell_proc entry
2201 // This ensures backward compatibility and covers spells that rely on DBC data
2202 LOG_INFO("server.loading", "Generating spell proc data from SpellMap...");
2203 count = 0;
2204 oldMSTime = getMSTime();
2205
2206 for (SpellInfo const* spellInfo : mSpellInfoMap)
2207 {
2208 if (!spellInfo)
2209 continue;
2210
2211 // Skip if already has explicit entry
2212 if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end())
2213 continue;
2214
2215 // Check if spell has any trigger aura effects
2216 bool found = false, addTriggerFlag = false;
2217 uint32 procSpellTypeMask = PROC_SPELL_TYPE_NONE;
2218 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2219 {
2220 if (!spellInfo->Effects[i].IsEffect())
2221 continue;
2222
2223 uint32 auraName = spellInfo->Effects[i].ApplyAuraName;
2224 if (!auraName)
2225 continue;
2226
2227 if (!isTriggerAura[auraName])
2228 continue;
2229
2230 found = true;
2231 procSpellTypeMask |= spellTypeMask[auraName];
2232
2233 if (!addTriggerFlag && isAlwaysTriggeredAura[auraName])
2234 addTriggerFlag = true;
2235
2236 // Many proc auras with taken procFlag mask don't have
2237 // attribute "can proc with triggered" — they should
2238 // proc nevertheless (e.g. mage armor spells with
2239 // judgement)
2240 if (!addTriggerFlag
2241 && (spellInfo->ProcFlags & TAKEN_HIT_PROC_FLAG_MASK))
2242 {
2243 switch (auraName)
2244 {
2247 addTriggerFlag = true;
2248 break;
2249 default:
2250 break;
2251 }
2252 }
2253 }
2254
2255 if (!found)
2256 continue;
2257
2258 // Skip if no proc flags in DBC
2259 if (!spellInfo->ProcFlags)
2260 continue;
2261
2262 // Generate default proc entry from DBC data
2263 SpellProcEntry procEntry;
2264 procEntry.SchoolMask = 0;
2265 procEntry.SpellFamilyMask[0] = 0;
2266 procEntry.SpellFamilyMask[1] = 0;
2267 procEntry.SpellFamilyMask[2] = 0;
2268 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2269 if (spellInfo->Effects[i].IsEffect() && isTriggerAura[spellInfo->Effects[i].ApplyAuraName])
2270 procEntry.SpellFamilyMask |= spellInfo->Effects[i].SpellClassMask;
2271
2272 if (procEntry.SpellFamilyMask)
2273 procEntry.SpellFamilyName = spellInfo->SpellFamilyName;
2274 else
2275 procEntry.SpellFamilyName = 0;
2276
2277 procEntry.ProcFlags = spellInfo->ProcFlags;
2278 procEntry.SpellTypeMask = procSpellTypeMask;
2280 procEntry.HitMask = PROC_HIT_NONE; // uses default proc @see SpellMgr::CanSpellTriggerProcOnEvent
2281
2282 // Reflect auras should only proc off reflects
2283 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2284 {
2285 if (spellInfo->Effects[i].IsAura(SPELL_AURA_REFLECT_SPELLS) || spellInfo->Effects[i].IsAura(SPELL_AURA_REFLECT_SPELLS_SCHOOL))
2286 {
2287 procEntry.HitMask = PROC_HIT_REFLECT;
2288 break;
2289 }
2290 }
2291
2292 procEntry.AttributesMask = 0;
2293 if (spellInfo->ProcFlags & PROC_FLAG_KILL)
2295 if (addTriggerFlag)
2297
2298 // Modifier auras with charges should require spellmod validation
2299 if (spellInfo->ProcCharges)
2300 {
2301 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2302 {
2303 if (spellInfo->Effects[i].IsAura(SPELL_AURA_ADD_FLAT_MODIFIER) ||
2304 spellInfo->Effects[i].IsAura(SPELL_AURA_ADD_PCT_MODIFIER))
2305 {
2307 break;
2308 }
2309 }
2310 }
2311
2312 // Calculate DisableEffectsMask for effects that shouldn't trigger procs
2313 uint32 nonProcMask = 0;
2314 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2315 {
2316 if (!spellInfo->Effects[i].IsAura())
2317 continue;
2318 if (!isTriggerAura[spellInfo->Effects[i].ApplyAuraName])
2319 nonProcMask |= 1u << i;
2320 }
2321 procEntry.DisableEffectsMask = nonProcMask;
2322
2323 procEntry.ProcsPerMinute = 0;
2324 procEntry.Chance = static_cast<float>(spellInfo->ProcChance);
2325 procEntry.Cooldown = Milliseconds::zero();
2326 procEntry.Charges = spellInfo->ProcCharges;
2327
2328 mSpellProcMap[spellInfo->Id] = procEntry;
2329 ++count;
2330 }
2331
2332 LOG_INFO("server.loading", ">> Generated spell proc data for {} spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2333 LOG_INFO("server.loading", " ");
2334}
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:1978
static uint32 spellTypeMask[TOTAL_AURAS]
Definition SpellMgr.cpp:1979
static bool isTriggerAura[TOTAL_AURAS]
Definition SpellMgr.cpp:1977
@ 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:2934
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 ( )
1292{
1293 // cleanup data and load spell ranks for talents from dbc
1295
1296 uint32 oldMSTime = getMSTime();
1297
1298 // 0 1 2
1299 QueryResult result = WorldDatabase.Query("SELECT first_spell_id, spell_id, `rank` from spell_ranks ORDER BY first_spell_id, `rank`");
1300
1301 if (!result)
1302 {
1303 LOG_WARN("server.loading", ">> Loaded 0 spell rank records. DB table `spell_ranks` is empty.");
1304 LOG_INFO("server.loading", " ");
1305 return;
1306 }
1307
1308 uint32 count = 0;
1309 bool finished = false;
1310
1311 do
1312 {
1313 // spellid, rank
1314 std::list < std::pair < int32, int32 > > rankChain;
1315 int32 currentSpell = -1;
1316 int32 lastSpell = -1;
1317
1318 // fill one chain
1319 while (currentSpell == lastSpell && !finished)
1320 {
1321 Field* fields = result->Fetch();
1322
1323 currentSpell = fields[0].Get<uint32>();
1324 if (lastSpell == -1)
1325 lastSpell = currentSpell;
1326 uint32 spell_id = fields[1].Get<uint32>();
1327 uint32 rank = fields[2].Get<uint8>();
1328
1329 // don't drop the row if we're moving to the next rank
1330 if (currentSpell == lastSpell)
1331 {
1332 rankChain.push_back(std::make_pair(spell_id, rank));
1333 if (!result->NextRow())
1334 finished = true;
1335 }
1336 else
1337 break;
1338 }
1339 // check if chain is made with valid first spell
1340 SpellInfo const* first = GetSpellInfo(lastSpell);
1341 if (!first)
1342 {
1343 LOG_ERROR("sql.sql", "Spell rank identifier(first_spell_id) {} listed in `spell_ranks` does not exist!", lastSpell);
1344 continue;
1345 }
1346 // check if chain is long enough
1347 if (rankChain.size() < 2)
1348 {
1349 LOG_ERROR("sql.sql", "There is only 1 spell rank for identifier(first_spell_id) {} in `spell_ranks`, entry is not needed!", lastSpell);
1350 continue;
1351 }
1352 int32 curRank = 0;
1353 bool valid = true;
1354 // check spells in chain
1355 for (std::list<std::pair<int32, int32> >::iterator itr = rankChain.begin(); itr != rankChain.end(); ++itr)
1356 {
1357 SpellInfo const* spell = GetSpellInfo(itr->first);
1358 if (!spell)
1359 {
1360 LOG_ERROR("sql.sql", "Spell {} (rank {}) listed in `spell_ranks` for chain {} does not exist!", itr->first, itr->second, lastSpell);
1361 valid = false;
1362 break;
1363 }
1364 ++curRank;
1365 if (itr->second != curRank)
1366 {
1367 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);
1368 valid = false;
1369 break;
1370 }
1371 }
1372 if (!valid)
1373 continue;
1374 int32 prevRank = 0;
1375 // insert the chain
1376 std::list<std::pair<int32, int32> >::iterator itr = rankChain.begin();
1377 do
1378 {
1379 ++count;
1380 int32 addedSpell = itr->first;
1381 mSpellChains[addedSpell].first = GetSpellInfo(lastSpell);
1382 mSpellChains[addedSpell].last = GetSpellInfo(rankChain.back().first);
1383 mSpellChains[addedSpell].rank = itr->second;
1384 mSpellChains[addedSpell].prev = GetSpellInfo(prevRank);
1385 mSpellInfoMap[addedSpell]->ChainEntry = &mSpellChains[addedSpell];
1386 prevRank = addedSpell;
1387 ++itr;
1388 if (itr == rankChain.end())
1389 {
1390 mSpellChains[addedSpell].next = nullptr;
1391 break;
1392 }
1393 else
1394 mSpellChains[addedSpell].next = GetSpellInfo(itr->first);
1395 } while (true);
1396 } while (!finished);
1397
1398 LOG_INFO("server.loading", ">> Loaded {} spell rank records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1399 LOG_INFO("server.loading", " ");
1400}
void LoadSpellTalentRanks()
Definition SpellMgr.cpp:1230

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

◆ LoadSpellRequired()

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

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

◆ LoadSpellSpecificAndAuraState()

void SpellMgr::LoadSpellSpecificAndAuraState ( )
3154{
3155 uint32 oldMSTime = getMSTime();
3156
3157 SpellInfo* spellInfo = nullptr;
3158 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3159 {
3160 spellInfo = mSpellInfoMap[i];
3161 if (!spellInfo)
3162 continue;
3163 spellInfo->_spellSpecific = spellInfo->LoadSpellSpecific();
3164 spellInfo->_auraState = spellInfo->LoadAuraState();
3165 }
3166
3167 LOG_INFO("server.loading", ">> Loaded Spell Specific And Aura State in {} ms", GetMSTimeDiffToNow(oldMSTime));
3168 LOG_INFO("server.loading", " ");
3169}
SpellSpecificType LoadSpellSpecific() const
Definition SpellInfo.cpp:2081
AuraStateType LoadAuraState() const
Definition SpellInfo.cpp:1999
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 ( )
1231{
1232 // cleanup core data before reload - remove reference to ChainNode from SpellInfo
1234
1235 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1236 {
1237 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
1238 if (!talentInfo)
1239 continue;
1240
1241 SpellInfo const* lastSpell = nullptr;
1242 for (uint8 rank = MAX_TALENT_RANK - 1; rank > 0; --rank)
1243 {
1244 if (talentInfo->RankID[rank])
1245 {
1246 lastSpell = GetSpellInfo(talentInfo->RankID[rank]);
1247 break;
1248 }
1249 }
1250
1251 if (!lastSpell)
1252 continue;
1253
1254 SpellInfo const* firstSpell = GetSpellInfo(talentInfo->RankID[0]);
1255 if (!firstSpell)
1256 {
1257 LOG_ERROR("sql.sql", "SpellMgr::LoadSpellTalentRanks: First Rank Spell {} for TalentEntry {} does not exist.", talentInfo->RankID[0], i);
1258 continue;
1259 }
1260
1261 SpellInfo const* prevSpell = nullptr;
1262 for (uint8 rank = 0; rank < MAX_TALENT_RANK; ++rank)
1263 {
1264 uint32 spellId = talentInfo->RankID[rank];
1265 if (!spellId)
1266 break;
1267
1268 SpellInfo const* currentSpell = GetSpellInfo(spellId);
1269 if (!currentSpell)
1270 {
1271 LOG_ERROR("sql.sql", "SpellMgr::LoadSpellTalentRanks: Spell {} (Rank: {}) for TalentEntry {} does not exist.", spellId, rank + 1, i);
1272 break;
1273 }
1274
1275 SpellChainNode node;
1276 node.first = firstSpell;
1277 node.last = lastSpell;
1278 node.rank = rank + 1;
1279
1280 node.prev = prevSpell;
1281 node.next = node.rank < MAX_TALENT_RANK ? GetSpellInfo(talentInfo->RankID[node.rank]) : nullptr;
1282
1283 mSpellChains[spellId] = node;
1284 mSpellInfoMap[spellId]->ChainEntry = &mSpellChains[spellId];
1285
1286 prevSpell = currentSpell;
1287 }
1288 }
1289}
void UnloadSpellInfoChains()
Definition SpellMgr.cpp:1222
SpellInfo const * last
Definition SpellMgr.h:557
SpellInfo const * next
Definition SpellMgr.h:555
uint8 rank
Definition SpellMgr.h:558
SpellInfo const * first
Definition SpellMgr.h:556
SpellInfo const * prev
Definition SpellMgr.h:554

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

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 ( )
2378{
2379 uint32 oldMSTime = getMSTime();
2380
2381 mSpellThreatMap.clear(); // need for reload case
2382
2383 // 0 1 2 3
2384 QueryResult result = WorldDatabase.Query("SELECT entry, flatMod, pctMod, apPctMod FROM spell_threat");
2385 if (!result)
2386 {
2387 LOG_WARN("server.loading", ">> Loaded 0 aggro generating spells. DB table `spell_threat` is empty.");
2388 LOG_INFO("server.loading", " ");
2389 return;
2390 }
2391
2392 uint32 count = 0;
2393 do
2394 {
2395 Field* fields = result->Fetch();
2396
2397 uint32 entry = fields[0].Get<uint32>();
2398
2399 if (!GetSpellInfo(entry))
2400 {
2401 LOG_ERROR("sql.sql", "Spell {} listed in `spell_threat` does not exist", entry);
2402 continue;
2403 }
2404
2405 SpellThreatEntry ste;
2406 ste.flatMod = fields[1].Get<int32>();
2407 ste.pctMod = fields[2].Get<float>();
2408 ste.apPctMod = fields[3].Get<float>();
2409
2410 mSpellThreatMap[entry] = ste;
2411 ++count;
2412 } while (result->NextRow());
2413
2414 LOG_INFO("server.loading", ">> Loaded {} SpellThreatEntries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2415 LOG_INFO("server.loading", " ");
2416}
Definition SpellMgr.h:377
int32 flatMod
Definition SpellMgr.h:378
float apPctMod
Definition SpellMgr.h:380
float pctMod
Definition SpellMgr.h:379

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

References mSpellDifficultySearcherMap.

◆ UnloadSpellInfoChains()

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

References mSpellChains, and mSpellInfoMap.

Referenced by LoadSpellTalentRanks().

◆ UnloadSpellInfoImplicitTargetConditionLists()

void SpellMgr::UnloadSpellInfoImplicitTargetConditionLists ( )
3145{
3146 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3147 {
3148 if (mSpellInfoMap[i])
3149 mSpellInfoMap[i]->_UnloadImplicitTargetConditionLists();
3150 }
3151}

References GetSpellInfoStoreSize(), and mSpellInfoMap.

◆ UnloadSpellInfoStore()

void SpellMgr::UnloadSpellInfoStore ( )
3137{
3138 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3139 delete mSpellInfoMap[i];
3140
3141 mSpellInfoMap.clear();
3142}

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

◆ mSpellCones

SpellConeMap SpellMgr::mSpellCones
private

Referenced by GetSpellCone(), and LoadSpellCones().

◆ 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

◆ mSpellSameEffectSharedMisc

SameEffectStackSharedMiscMap SpellMgr::mSpellSameEffectSharedMisc
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: