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

References UnloadSpellInfoStore().

Member Function Documentation

◆ _GetSpellInfo()

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

References GetSpellInfoStoreSize(), and mSpellInfoMap.

Referenced by LoadSpellInfoCustomAttributes(), and LoadSpellJumpDistances().

◆ AddSameEffectStackRuleSpellGroups()

bool SpellMgr::AddSameEffectStackRuleSpellGroups ( SpellInfo const *  spellInfo,
uint32  auraType,
int32  amount,
std::map< SpellGroup, int32 > &  groups 
) const
778{
779 uint32 spellId = spellInfo->GetFirstRankSpell()->Id;
780 auto spellGroupBounds = GetSpellSpellGroupMapBounds(spellId);
781 // Find group with SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT if it belongs to one
782 for (auto itr = spellGroupBounds.first; itr != spellGroupBounds.second; ++itr)
783 {
784 SpellGroup group = itr->second;
785 auto found = mSpellSameEffectStack.find(group);
786 if (found != mSpellSameEffectStack.end())
787 {
788 // check auraTypes
789 if (!found->second.count(auraType))
790 continue;
791
792 // Put the highest amount in the map
793 auto groupItr = groups.find(group);
794 if (groupItr == groups.end())
795 groups.emplace(group, amount);
796 else
797 {
798 int32 curr_amount = groups[group];
799 // Take absolute value because this also counts for the highest negative aura
800 if (std::abs(curr_amount) < std::abs(amount))
801 groupItr->second = amount;
802 }
803 // return because a spell should be in only one SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT group per auraType
804 return true;
805 }
806 }
807 // Not in a SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT group, so return false
808 return false;
809}
std::int32_t int32
Definition Define.h:103
std::uint32_t uint32
Definition Define.h:107
SpellGroup
Definition SpellMgr.h:331
SameEffectStackMap mSpellSameEffectStack
Definition SpellMgr.h:824
SpellSpellGroupMapBounds GetSpellSpellGroupMapBounds(uint32 spell_id) const
Definition SpellMgr.cpp:728

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

◆ AssertSpellInfo()

SpellInfo const * SpellMgr::AssertSpellInfo ( uint32  spellId) const
inline
745 {
746 ASSERT(spellId < GetSpellInfoStoreSize());
747 SpellInfo const* spellInfo = mSpellInfoMap[spellId];
748 ASSERT(spellInfo);
749 return spellInfo;
750 }
#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
876{
877 // proc type doesn't match
878 if (!(eventInfo.GetTypeMask() & procEntry.ProcFlags))
879 return false;
880
881 // check XP or honor target requirement
882 if (procEntry.AttributesMask & PROC_ATTR_REQ_EXP_OR_HONOR)
883 if (Player* actor = eventInfo.GetActor()->ToPlayer())
884 if (eventInfo.GetActionTarget() && !actor->isHonorOrXPTarget(eventInfo.GetActionTarget()))
885 return false;
886
887 // check mana cost requirement (used by Clearcasting and similar effects)
888 if (procEntry.AttributesMask & PROC_ATTR_REQ_MANA_COST)
889 {
890 SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
891 if (!spellInfo || (!spellInfo->ManaCost && !spellInfo->ManaCostPercentage))
892 return false;
893 }
894
895 // always trigger for these types
897 return true;
898
899 // check school mask (if set) for other trigger types
900 if (procEntry.SchoolMask && !(eventInfo.GetSchoolMask() & procEntry.SchoolMask))
901 return false;
902
903 // check spell family name/flags (if set) for spells
904 if (eventInfo.GetTypeMask() & SPELL_PROC_FLAG_MASK)
905 if (SpellInfo const* eventSpellInfo = eventInfo.GetSpellInfo())
906 if (!eventSpellInfo->IsAffected(procEntry.SpellFamilyName, procEntry.SpellFamilyMask))
907 return false;
908
909 // check spell type mask (if set)
911 {
912 if (procEntry.SpellTypeMask && !(eventInfo.GetSpellTypeMask() & procEntry.SpellTypeMask))
913 return false;
914 }
915
916 // check spell phase mask
918 {
919 if (!(eventInfo.GetSpellPhaseMask() & procEntry.SpellPhaseMask))
920 return false;
921 }
922
923 // check hit mask (on taken hit or on done hit)
924 // For CAST phase with DONE flags, only check if HitMask is explicitly set (crit is pre-calculated for travel time spells)
925 if ((eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK) ||
926 ((eventInfo.GetTypeMask() & DONE_HIT_PROC_FLAG_MASK) &&
927 (!(eventInfo.GetSpellPhaseMask() & PROC_SPELL_PHASE_CAST) || procEntry.HitMask)))
928 {
929 uint32 hitMask = procEntry.HitMask;
930 // get default values if hit mask not set
931 if (!hitMask)
932 {
933 // for taken procs allow normal + critical hits by default
934 if (eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK)
936 // for done procs allow normal + critical + absorbs by default
937 else
939 }
940 if (!(eventInfo.GetHitMask() & hitMask))
941 return false;
942 }
943
944 return true;
945}
@ 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:468
SpellSchoolMask GetSchoolMask() const
Definition Unit.cpp:315
Unit * GetActionTarget() const
Definition Unit.h:463
uint32 GetSpellTypeMask() const
Definition Unit.h:466
uint32 GetTypeMask() const
Definition Unit.h:465
SpellInfo const * GetSpellInfo() const
Definition Unit.cpp:301
Unit * GetActor()
Definition Unit.h:462
uint32 GetSpellPhaseMask() const
Definition Unit.h:467
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
812{
813 ASSERT(spellInfo1);
814 ASSERT(spellInfo2);
815
816 uint32 spell_id1 = spellInfo1->GetFirstRankSpell()->Id;
817 uint32 spell_id2 = spellInfo2->GetFirstRankSpell()->Id;
818
819 // find SpellGroups which are common for both spells
821 std::set<SpellGroup> groups;
822 for (SpellSpellGroupMap::const_iterator itr = spellGroup1.first; itr != spellGroup1.second; ++itr)
823 {
824 if (IsSpellMemberOfSpellGroup(spell_id2, itr->second))
825 {
826 bool add = true;
828 for (SpellGroupSpellMap::const_iterator itr2 = groupSpell.first; itr2 != groupSpell.second; ++itr2)
829 {
830 if (itr2->second < 0)
831 {
832 SpellGroup currGroup = (SpellGroup)abs(itr2->second);
833 if (IsSpellMemberOfSpellGroup(spell_id1, currGroup) && IsSpellMemberOfSpellGroup(spell_id2, currGroup))
834 {
835 add = false;
836 break;
837 }
838 }
839 }
840 if (add)
841 groups.insert(itr->second);
842 }
843 }
844
846
847 for (std::set<SpellGroup>::iterator itr = groups.begin(); itr!= groups.end(); ++itr)
848 {
849 SpellGroupStackMap::const_iterator found = mSpellGroupStack.find(*itr);
850 if (found != mSpellGroupStack.end())
851 rule = found->second;
852 if (rule)
853 break;
854 }
855 return rule;
856}
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:823

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
753 {
754 if (spellId >= GetSpellInfoStoreSize())
755 {
756 LOG_ERROR("server", "spellId {} is not lower than GetSpellInfoStoreSize() ({})", spellId, GetSpellInfoStoreSize());
757 return nullptr;
758 }
759 SpellInfo const* spellInfo = mSpellInfoMap[spellId];
760 if (!spellInfo)
761 {
762 LOG_ERROR("server", "spellId {} has invalid spellInfo", spellId);
763 return nullptr;
764 }
765 return spellInfo;
766 }
#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:847
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:826
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:551

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
993{
994 SpellPetAuraMap::const_iterator itr = mSpellPetAuraMap.find((spell_id << 8) + eff);
995 if (itr != mSpellPetAuraMap.end())
996 return &itr->second;
997 else
998 return nullptr;
999}
SpellPetAuraMap mSpellPetAuraMap
Definition SpellMgr.h:830

References mSpellPetAuraMap.

◆ GetPetDefaultSpellsEntry()

PetDefaultSpellsEntry const * SpellMgr::GetPetDefaultSpellsEntry ( int32  id) const
1030{
1031 PetDefaultSpellsMap::const_iterator itr = mPetDefaultSpellsMap.find(id);
1032 if (itr != mPetDefaultSpellsMap.end())
1033 return &itr->second;
1034 return nullptr;
1035}
PetDefaultSpellsMap mPetDefaultSpellsMap
Definition SpellMgr.h:841

References mPetDefaultSpellsMap.

◆ GetPetLevelupSpellList()

PetLevelupSpellSet const * SpellMgr::GetPetLevelupSpellList ( uint32  petFamily) const
1021{
1022 PetLevelupSpellMap::const_iterator itr = mPetLevelupSpellMap.find(petFamily);
1023 if (itr != mPetLevelupSpellMap.end())
1024 return &itr->second;
1025 else
1026 return nullptr;
1027}
PetLevelupSpellMap mPetLevelupSpellMap
Definition SpellMgr.h:840

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
988{
989 return mSkillLineAbilityMap.equal_range(spell_id);
990}
SkillLineAbilityMap mSkillLineAbilityMap
Definition SpellMgr.h:839

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

References mSpellLearnSkills.

◆ GetSpellAreaForAreaMapBounds()

SpellAreaForAreaMapBounds SpellMgr::GetSpellAreaForAreaMapBounds ( uint32  area_id) const
1058{
1059 return mSpellAreaForAreaMap.equal_range(area_id);
1060}
SpellAreaForAreaMap mSpellAreaForAreaMap
Definition SpellMgr.h:838

References mSpellAreaForAreaMap.

◆ GetSpellAreaForAuraMapBounds()

SpellAreaForAuraMapBounds SpellMgr::GetSpellAreaForAuraMapBounds ( uint32  spell_id) const
1053{
1054 return mSpellAreaForAuraMap.equal_range(spell_id);
1055}
SpellAreaForAuraMap mSpellAreaForAuraMap
Definition SpellMgr.h:837

References mSpellAreaForAuraMap.

Referenced by LoadSpellAreas().

◆ GetSpellAreaForQuestEndMapBounds()

SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestEndMapBounds ( uint32  quest_id) const
1048{
1049 return mSpellAreaForQuestEndMap.equal_range(quest_id);
1050}
SpellAreaForQuestMap mSpellAreaForQuestEndMap
Definition SpellMgr.h:836

References mSpellAreaForQuestEndMap.

◆ GetSpellAreaForQuestMapBounds()

SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestMapBounds ( uint32  quest_id) const
1043{
1044 return mSpellAreaForQuestMap.equal_range(quest_id);
1045}
SpellAreaForQuestMap mSpellAreaForQuestMap
Definition SpellMgr.h:835

References mSpellAreaForQuestMap.

◆ GetSpellAreaMapBounds()

SpellAreaMapBounds SpellMgr::GetSpellAreaMapBounds ( uint32  spell_id) const
1038{
1039 return mSpellAreaMap.equal_range(spell_id);
1040}
SpellAreaMap mSpellAreaMap
Definition SpellMgr.h:834

References mSpellAreaMap.

Referenced by LoadSpellAreas().

◆ GetSpellBonusData()

SpellBonusEntry const * SpellMgr::GetSpellBonusData ( uint32  spellId) const
948{
949 // Lookup data
950 SpellBonusMap::const_iterator itr = mSpellBonusMap.find(spellId);
951 if (itr != mSpellBonusMap.end())
952 return &itr->second;
953 // Not found, try lookup for 1 spell rank if exist
954 if (uint32 rank_1 = GetFirstSpellInChain(spellId))
955 {
956 SpellBonusMap::const_iterator itr2 = mSpellBonusMap.find(rank_1);
957 if (itr2 != mSpellBonusMap.end())
958 return &itr2->second;
959 }
960 return nullptr;
961}
uint32 GetFirstSpellInChain(uint32 spell_id) const
Definition SpellMgr.cpp:603
SpellBonusMap mSpellBonusMap
Definition SpellMgr.h:827

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

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

References GetFirstSpellInChain(), and mSpellCones.

◆ GetSpellCooldownOverride()

SpellCooldownOverride SpellMgr::GetSpellCooldownOverride ( uint32  spellId) const
3090{
3091 auto range = mSpellCooldownOverrideMap.find(spellId);
3092 return range->second;
3093}
SpellCooldownOverrideMap mSpellCooldownOverrideMap
Definition SpellMgr.h:843

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

References mSpellDifficultySearcherMap.

Referenced by GetSpellIdForDifficulty().

◆ GetSpellEnchantProcEvent()

SpellEnchantProcEntry const * SpellMgr::GetSpellEnchantProcEvent ( uint32  enchId) const
1002{
1003 SpellEnchantProcEventMap::const_iterator itr = mSpellEnchantProcEventMap.find(enchId);
1004 if (itr != mSpellEnchantProcEventMap.end())
1005 return &itr->second;
1006 return nullptr;
1007}
SpellEnchantProcEventMap mSpellEnchantProcEventMap
Definition SpellMgr.h:832

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:742
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:822

References mSpellGroupSpell.

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

◆ GetSpellGroupStackRule()

SpellGroupStackRule SpellMgr::GetSpellGroupStackRule ( SpellGroup  group_id) const
859{
860 SpellGroupStackMap::const_iterator itr = mSpellGroupStack.find(group);
861 if (itr != mSpellGroupStack.end())
862 return itr->second;
863
865}

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
1015{
1016 SpellLinkedMap::const_iterator itr = mSpellLinkedMap.find(spell_id);
1017 return itr != mSpellLinkedMap.end() ? &(itr->second) : nullptr;
1018}
SpellLinkedMap mSpellLinkedMap
Definition SpellMgr.h:831

References mSpellLinkedMap.

◆ GetSpellMixologyBonus()

float SpellMgr::GetSpellMixologyBonus ( uint32  spellId) const
979{
980 SpellMixologyMap::const_iterator itr = mSpellMixologyMap.find(spellId);
981 if (itr == mSpellMixologyMap.end())
982 return 30.0f;
983
984 return itr->second;
985}
SpellMixologyMap mSpellMixologyMap
Definition SpellMgr.h:829

References mSpellMixologyMap.

◆ GetSpellProcEntry()

SpellProcEntry const * SpellMgr::GetSpellProcEntry ( uint32  spellId) const
868{
869 SpellProcMap::const_iterator itr = mSpellProcMap.find(spellId);
870 if (itr != mSpellProcMap.end())
871 return &itr->second;
872 return nullptr;
873}
SpellProcMap mSpellProcMap
Definition SpellMgr.h:825

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

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:817
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:816

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

References mSpellTargetPositions.

◆ GetSpellThreatEntry()

SpellThreatEntry const * SpellMgr::GetSpellThreatEntry ( uint32  spellID) const
964{
965 SpellThreatMap::const_iterator itr = mSpellThreatMap.find(spellID);
966 if (itr != mSpellThreatMap.end())
967 return &itr->second;
968 else
969 {
970 uint32 firstSpell = GetFirstSpellInChain(spellID);
971 itr = mSpellThreatMap.find(firstSpell);
972 if (itr != mSpellThreatMap.end())
973 return &itr->second;
974 }
975 return nullptr;
976}
SpellThreatMap mSpellThreatMap
Definition SpellMgr.h:828

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
3085{
3086 return mSpellCooldownOverrideMap.find(spellId) != mSpellCooldownOverrideMap.end();
3087}

References mSpellCooldownOverrideMap.

Referenced by LoadSpellInfoCustomAttributes().

◆ instance()

SpellMgr * SpellMgr::instance ( )
static
413{
414 static SpellMgr instance;
415 return &instance;
416}
Definition SpellMgr.h:649
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:844

References mTalentSpellAdditionalSet.

◆ IsArenaAllowedEnchancment()

bool SpellMgr::IsArenaAllowedEnchancment ( uint32  ench_id) const
1010{
1011 return mEnchantCustomAttr[ench_id];
1012}
EnchantCustomAttribute mEnchantCustomAttr
Definition SpellMgr.h:833

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:567
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:571
std::bitset< MAX_SPELL_SCHOOL > School
Definition SpellMgr.h:572

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
2499{
2500 uint32 oldMSTime = getMSTime();
2501
2502 uint32 size = sSpellItemEnchantmentStore.GetNumRows();
2503 mEnchantCustomAttr.resize(size);
2504
2505 for (uint32 i = 0; i < size; ++i)
2506 mEnchantCustomAttr[i] = 0;
2507
2508 uint32 count = 0;
2509 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2510 {
2511 SpellInfo const* spellInfo = GetSpellInfo(i);
2512 if (!spellInfo)
2513 continue;
2514
2516 // Xinef: commented second part, fixes warlock enchants like firestone, spellstone
2517 if (!spellInfo->HasAttribute(SPELL_ATTR2_ENCHANT_OWN_ITEM_ONLY)/* || !spellInfo->HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFTED)*/)
2518 continue;
2519
2520 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
2521 {
2522 if (spellInfo->Effects[j].Effect == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY)
2523 {
2524 uint32 enchId = spellInfo->Effects[j].MiscValue;
2525 SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchId);
2526 if (!ench)
2527 continue;
2528 mEnchantCustomAttr[enchId] = true;
2529 ++count;
2530 break;
2531 }
2532 }
2533 }
2534
2535 LOG_INFO("server.loading", ">> Loaded {} Custom Enchant Attributes in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2536 LOG_INFO("server.loading", " ");
2537}
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 ( )
2732{
2733 uint32 oldMSTime = getMSTime();
2734
2735 mPetDefaultSpellsMap.clear();
2736
2737 uint32 countCreature = 0;
2738 uint32 countData = 0;
2739
2740 CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
2741 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
2742 {
2743 if (!itr->second.PetSpellDataId)
2744 continue;
2745
2746 // for creature with PetSpellDataId get default pet spells from dbc
2747 CreatureSpellDataEntry const* spellDataEntry = sCreatureSpellDataStore.LookupEntry(itr->second.PetSpellDataId);
2748 if (!spellDataEntry)
2749 continue;
2750
2751 int32 petSpellsId = -int32(itr->second.PetSpellDataId);
2752 PetDefaultSpellsEntry petDefSpells;
2753 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2754 petDefSpells.spellid[j] = spellDataEntry->spellId[j];
2755
2756 if (LoadPetDefaultSpells_helper(&itr->second, petDefSpells))
2757 {
2758 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2759 ++countData;
2760 }
2761 }
2762
2763 LOG_INFO("server.loading", ">> Loaded Addition Spells For {} Pet Spell Data Entries in {} ms", countData, GetMSTimeDiffToNow(oldMSTime));
2764 LOG_INFO("server.loading", " ");
2765
2766 LOG_INFO("server.loading", "Loading Summonable Creature Templates...");
2767 oldMSTime = getMSTime();
2768
2769 // different summon spells
2770 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2771 {
2772 SpellInfo const* spellInfo = GetSpellInfo(i);
2773 if (!spellInfo)
2774 continue;
2775
2776 for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
2777 {
2778 if (spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON || spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON_PET)
2779 {
2780 uint32 creature_id = spellInfo->Effects[k].MiscValue;
2781 CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id);
2782 if (!cInfo)
2783 continue;
2784
2785 // already loaded
2786 if (cInfo->PetSpellDataId)
2787 continue;
2788
2789 // for creature without PetSpellDataId get default pet spells from creature_template
2790 int32 petSpellsId = cInfo->Entry;
2791 if (mPetDefaultSpellsMap.find(cInfo->Entry) != mPetDefaultSpellsMap.end())
2792 continue;
2793
2794 PetDefaultSpellsEntry petDefSpells;
2795 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2796 petDefSpells.spellid[j] = cInfo->spells[j];
2797
2798 if (LoadPetDefaultSpells_helper(cInfo, petDefSpells))
2799 {
2800 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2801 ++countCreature;
2802 }
2803 }
2804 }
2805 }
2806
2807 LOG_INFO("server.loading", ">> Loaded {} Summonable Creature emplates in {} ms", countCreature, GetMSTimeDiffToNow(oldMSTime));
2808 LOG_INFO("server.loading", " ");
2809}
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:2683
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:601
uint32 spellid[MAX_CREATURE_SPELL_DATA_SLOT]
Definition SpellMgr.h:602

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 ( )
2638{
2639 uint32 oldMSTime = getMSTime();
2640
2641 mPetLevelupSpellMap.clear(); // need for reload case
2642
2643 uint32 count = 0;
2644 uint32 family_count = 0;
2645
2646 for (uint32 i = 0; i < sCreatureFamilyStore.GetNumRows(); ++i)
2647 {
2648 CreatureFamilyEntry const* creatureFamily = sCreatureFamilyStore.LookupEntry(i);
2649 if (!creatureFamily) // not exist
2650 continue;
2651
2652 for (uint8 j = 0; j < 2; ++j)
2653 {
2654 if (!creatureFamily->skillLine[j])
2655 continue;
2656
2657 for (SkillLineAbilityEntry const* skillLine : GetSkillLineAbilitiesBySkillLine(creatureFamily->skillLine[j]))
2658 {
2659 if (skillLine->AcquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN)
2660 continue;
2661
2662 SpellInfo const* spell = GetSpellInfo(skillLine->Spell);
2663 if (!spell) // not exist or triggered or talent
2664 continue;
2665
2666 if (!spell->SpellLevel)
2667 continue;
2668
2669 PetLevelupSpellSet& spellSet = mPetLevelupSpellMap[creatureFamily->ID];
2670 if (spellSet.empty())
2671 ++family_count;
2672
2673 spellSet.insert(PetLevelupSpellSet::value_type(spell->SpellLevel, spell->Id));
2674 ++count;
2675 }
2676 }
2677 }
2678
2679 LOG_INFO("server.loading", ">> Loaded {} Pet Levelup And Default Spells For {} Families in {} ms", count, family_count, GetMSTimeDiffToNow(oldMSTime));
2680 LOG_INFO("server.loading", " ");
2681}
@ 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:934
std::multimap< uint32, uint32 > PetLevelupSpellSet
Definition SpellMgr.h:595
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 ( )
2414{
2415 uint32 oldMSTime = getMSTime();
2416
2417 mSkillLineAbilityMap.clear();
2418
2419 uint32 count = 0;
2420
2421 for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); ++i)
2422 {
2423 SkillLineAbilityEntry const* SkillInfo = sSkillLineAbilityStore.LookupEntry(i);
2424 if (!SkillInfo)
2425 continue;
2426
2427 mSkillLineAbilityMap.insert(SkillLineAbilityMap::value_type(SkillInfo->Spell, SkillInfo));
2428 ++count;
2429 }
2430
2431 LOG_INFO("server.loading", ">> Loaded {} SkillLineAbility MultiMap Data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2432 LOG_INFO("server.loading", " ");
2433}
DBCStorage< SkillLineAbilityEntry > sSkillLineAbilityStore(SkillLineAbilityfmt)
uint32 Spell
Definition DBCStructure.h:1637

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

◆ LoadSpellAreas()

void SpellMgr::LoadSpellAreas ( )
2812{
2813 uint32 oldMSTime = getMSTime();
2814
2815 mSpellAreaMap.clear(); // need for reload case
2816 mSpellAreaForQuestMap.clear();
2818 mSpellAreaForAuraMap.clear();
2819
2820 // 0 1 2 3 4 5 6 7 8 9
2821 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");
2822
2823 if (!result)
2824 {
2825 LOG_WARN("server.loading", ">> Loaded 0 spell area requirements. DB table `spell_area` is empty.");
2826 LOG_INFO("server.loading", " ");
2827 return;
2828 }
2829
2830 uint32 count = 0;
2831 do
2832 {
2833 Field* fields = result->Fetch();
2834
2835 uint32 spell = fields[0].Get<uint32>();
2836 SpellArea spellArea;
2837 spellArea.spellId = spell;
2838 spellArea.areaId = fields[1].Get<uint32>();
2839 spellArea.questStart = fields[2].Get<uint32>();
2840 spellArea.questStartStatus = fields[3].Get<uint32>();
2841 spellArea.questEndStatus = fields[4].Get<uint32>();
2842 spellArea.questEnd = fields[5].Get<uint32>();
2843 spellArea.auraSpell = fields[6].Get<int32>();
2844 spellArea.raceMask = fields[7].Get<uint32>();
2845 spellArea.gender = Gender(fields[8].Get<uint8>());
2846 spellArea.autocast = fields[9].Get<bool>();
2847
2848 if (SpellInfo const* spellInfo = GetSpellInfo(spell))
2849 {
2850 if (spellArea.autocast)
2851 const_cast<SpellInfo*>(spellInfo)->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
2852 }
2853 else
2854 {
2855 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` does not exist", spell);
2856 continue;
2857 }
2858
2859 {
2860 bool ok = true;
2861 SpellAreaMapBounds sa_bounds = GetSpellAreaMapBounds(spellArea.spellId);
2862 for (SpellAreaMap::const_iterator itr = sa_bounds.first; itr != sa_bounds.second; ++itr)
2863 {
2864 if (spellArea.spellId != itr->second.spellId)
2865 continue;
2866 if (spellArea.areaId != itr->second.areaId)
2867 continue;
2868 if (spellArea.questStart != itr->second.questStart)
2869 continue;
2870 if (spellArea.auraSpell != itr->second.auraSpell)
2871 continue;
2872 if ((spellArea.raceMask & itr->second.raceMask) == 0)
2873 continue;
2874 if (spellArea.gender != itr->second.gender)
2875 continue;
2876
2877 // duplicate by requirements
2878 ok = false;
2879 break;
2880 }
2881
2882 if (!ok)
2883 {
2884 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` already listed with similar requirements.", spell);
2885 continue;
2886 }
2887 }
2888
2889 if (spellArea.areaId && !sAreaTableStore.LookupEntry(spellArea.areaId))
2890 {
2891 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong area ({}) requirement", spell, spellArea.areaId);
2892 continue;
2893 }
2894
2895 if (spellArea.questStart && !sObjectMgr->GetQuestTemplate(spellArea.questStart))
2896 {
2897 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong start quest ({}) requirement", spell, spellArea.questStart);
2898 continue;
2899 }
2900
2901 if (spellArea.questEnd)
2902 {
2903 if (!sObjectMgr->GetQuestTemplate(spellArea.questEnd))
2904 {
2905 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong end quest ({}) requirement", spell, spellArea.questEnd);
2906 continue;
2907 }
2908 }
2909
2910 if (spellArea.auraSpell)
2911 {
2912 SpellInfo const* spellInfo = GetSpellInfo(std::abs(spellArea.auraSpell));
2913 if (!spellInfo)
2914 {
2915 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong aura spell ({}) requirement", spell, std::abs(spellArea.auraSpell));
2916 continue;
2917 }
2918
2919 if (uint32(std::abs(spellArea.auraSpell)) == spellArea.spellId)
2920 {
2921 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement for itself", spell, std::abs(spellArea.auraSpell));
2922 continue;
2923 }
2924
2925 // not allow autocast chains by auraSpell field (but allow use as alternative if not present)
2926 if (spellArea.autocast && spellArea.auraSpell > 0)
2927 {
2928 bool chain = false;
2929 SpellAreaForAuraMapBounds saBound = GetSpellAreaForAuraMapBounds(spellArea.spellId);
2930 for (SpellAreaForAuraMap::const_iterator itr = saBound.first; itr != saBound.second; ++itr)
2931 {
2932 if (itr->second->autocast && itr->second->auraSpell > 0)
2933 {
2934 chain = true;
2935 break;
2936 }
2937 }
2938
2939 if (chain)
2940 {
2941 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement that itself autocast from aura", spell, spellArea.auraSpell);
2942 continue;
2943 }
2944
2945 SpellAreaMapBounds saBound2 = GetSpellAreaMapBounds(spellArea.auraSpell);
2946 for (SpellAreaMap::const_iterator itr2 = saBound2.first; itr2 != saBound2.second; ++itr2)
2947 {
2948 if (itr2->second.autocast && itr2->second.auraSpell > 0)
2949 {
2950 chain = true;
2951 break;
2952 }
2953 }
2954
2955 if (chain)
2956 {
2957 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement that itself autocast from aura", spell, spellArea.auraSpell);
2958 continue;
2959 }
2960 }
2961 }
2962
2963 if (spellArea.raceMask && (spellArea.raceMask & sRaceMgr->GetPlayableRaceMask()) == 0)
2964 {
2965 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong race mask ({}) requirement", spell, spellArea.raceMask);
2966 continue;
2967 }
2968
2969 if (spellArea.gender != GENDER_NONE && spellArea.gender != GENDER_FEMALE && spellArea.gender != GENDER_MALE)
2970 {
2971 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong gender ({}) requirement", spell, spellArea.gender);
2972 continue;
2973 }
2974
2975 SpellArea const* sa = &mSpellAreaMap.insert(SpellAreaMap::value_type(spell, spellArea))->second;
2976
2977 // for search by current zone/subzone at zone/subzone change
2978 if (spellArea.areaId)
2979 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(spellArea.areaId, sa));
2980
2981 // for search at quest start/reward
2982 if (spellArea.questStart)
2983 mSpellAreaForQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa));
2984
2985 // for search at quest start/reward
2986 if (spellArea.questEnd)
2987 mSpellAreaForQuestEndMap.insert(SpellAreaForQuestMap::value_type(spellArea.questEnd, sa));
2988
2989 // for search at aura apply
2990 if (spellArea.auraSpell)
2991 mSpellAreaForAuraMap.insert(SpellAreaForAuraMap::value_type(std::abs(spellArea.auraSpell), sa));
2992
2993 ++count;
2994 } while (result->NextRow());
2995
2996 if (sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE) > 0)
2997 {
2998 LOG_INFO("server.loading", ">> Using ICC Buff Horde: {}", sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE));
2999 SpellArea spellAreaICCBuffHorde = { sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE), ICC_AREA, 0, 0, 0, ICC_RACEMASK_HORDE, Gender(2), 64, 11, 1 };
3000 SpellArea const* saICCBuffHorde = &mSpellAreaMap.insert(SpellAreaMap::value_type(sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE), spellAreaICCBuffHorde))->second;
3001 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(ICC_AREA, saICCBuffHorde));
3002 ++count;
3003 }
3004 else
3005 LOG_INFO("server.loading", ">> ICC Buff Horde: disabled");
3006
3007 if (sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE) > 0)
3008 {
3009 LOG_INFO("server.loading", ">> Using ICC Buff Alliance: {}", sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE));
3010 SpellArea spellAreaICCBuffAlliance = { sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE), ICC_AREA, 0, 0, 0, ICC_RACEMASK_ALLIANCE, Gender(2), 64, 11, 1 };
3011 SpellArea const* saICCBuffAlliance = &mSpellAreaMap.insert(SpellAreaMap::value_type(sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE), spellAreaICCBuffAlliance))->second;
3012 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(ICC_AREA, saICCBuffAlliance));
3013 ++count;
3014 }
3015 else
3016 LOG_INFO("server.loading", ">> ICC Buff Alliance: disabled");
3017
3018 LOG_INFO("server.loading", ">> Loaded {} Spell Area Requirements in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3019 LOG_INFO("server.loading", " ");
3020}
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:544
@ ICC_RACEMASK_HORDE
Definition SpellMgr.h:519
@ ICC_AREA
Definition SpellMgr.h:518
@ ICC_RACEMASK_ALLIANCE
Definition SpellMgr.h:520
std::pair< SpellAreaForAuraMap::const_iterator, SpellAreaForAuraMap::const_iterator > SpellAreaForAuraMapBounds
Definition SpellMgr.h:546
@ 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:1037
SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds(uint32 spell_id) const
Definition SpellMgr.cpp:1052
#define sWorld
Definition World.h:318
Definition SpellMgr.h:524
uint32 spellId
Definition SpellMgr.h:525

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 ( )
2296{
2297 uint32 oldMSTime = getMSTime();
2298
2299 mSpellBonusMap.clear(); // need for reload case
2300
2301 // 0 1 2 3 4
2302 QueryResult result = WorldDatabase.Query("SELECT entry, direct_bonus, dot_bonus, ap_bonus, ap_dot_bonus FROM spell_bonus_data");
2303 if (!result)
2304 {
2305 LOG_WARN("server.loading", ">> Loaded 0 spell bonus data. DB table `spell_bonus_data` is empty.");
2306 LOG_INFO("server.loading", " ");
2307 return;
2308 }
2309
2310 uint32 count = 0;
2311 do
2312 {
2313 Field* fields = result->Fetch();
2314 uint32 entry = fields[0].Get<uint32>();
2315
2316 SpellInfo const* spell = GetSpellInfo(entry);
2317 if (!spell)
2318 {
2319 LOG_ERROR("sql.sql", "Spell {} listed in `spell_bonus_data` does not exist", entry);
2320 continue;
2321 }
2322
2323 SpellBonusEntry& sbe = mSpellBonusMap[entry];
2324 sbe.direct_damage = fields[1].Get<float>();
2325 sbe.dot_damage = fields[2].Get<float>();
2326 sbe.ap_bonus = fields[3].Get<float>();
2327 sbe.ap_dot_bonus = fields[4].Get<float>();
2328
2329 ++count;
2330 } while (result->NextRow());
2331
2332 LOG_INFO("server.loading", ">> Loaded {} Extra Spell Bonus Data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2333 LOG_INFO("server.loading", " ");
2334}
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 ( )
1614{
1615 uint32 oldMSTime = getMSTime();
1616
1617 mSpellCones.clear(); // need for reload case
1618
1619 // 0 1
1620 QueryResult result = WorldDatabase.Query("SELECT ID, ConeDegrees FROM spell_cone");
1621
1622 if (!result)
1623 {
1624 LOG_WARN("server.loading", ">> Loaded 0 spell cone definitions. DB table `spell_cone` is empty.");
1625 LOG_INFO("server.loading", " ");
1626 return;
1627 }
1628
1629 uint32 count = 0;
1630 do
1631 {
1632 Field* fields = result->Fetch();
1633
1634 uint32 spellId = fields[0].Get<uint32>();
1635 int16 coneDeg = fields[1].Get<int16>();
1636
1637 SpellInfo const* spellInfo = GetSpellInfo(spellId);
1638 if (!spellInfo)
1639 {
1640 LOG_ERROR("sql.sql", "Spell (ID:{}) listed in `spell_cone` does not exist.", spellId);
1641 continue;
1642 }
1643
1644 if (coneDeg < -360 || coneDeg > 360)
1645 {
1646 LOG_ERROR("sql.sql", "Spell (Id: {}) cone degrees {} out of range (-360..360).", spellId, coneDeg);
1647 continue;
1648 }
1649
1650 uint32 firstRankId = GetFirstSpellInChain(spellId);
1651 SpellInfo const* firstSpellInfo = GetSpellInfo(firstRankId);
1652
1653 SpellInfo const* checkInfo = firstSpellInfo ? firstSpellInfo : spellInfo;
1654
1655 bool hasCone = false;
1656 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1657 {
1658 if (checkInfo->Effects[i].TargetA.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CONE ||
1659 checkInfo->Effects[i].TargetB.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CONE)
1660 {
1661 hasCone = true;
1662 break;
1663 }
1664 }
1665
1666 if (!hasCone)
1667 {
1668 LOG_ERROR("sql.sql", "Spell (ID:{}) listed in `spell_cone` does not have a cone implicit target.", spellId);
1669 continue;
1670 }
1671
1672 if (firstRankId != spellId)
1673 LOG_INFO("server.loading", "Spell (ID:{}) listed in `spell_cone` is not first rank; mapping to first rank {}.", spellId, firstRankId);
1674
1675 SpellCone sc{};
1676 sc.cone_degrees = coneDeg;
1677
1678 // Avoid overwriting an existing first-rank entry with conflicting values
1679 auto itr = mSpellCones.find(firstRankId);
1680 if (itr != mSpellCones.end())
1681 {
1682 if (itr->second.cone_degrees != sc.cone_degrees)
1683 LOG_ERROR("sql.sql",
1684 "Conflicting `spell_cone` entries for first-rank spell ID {}: {} vs {}. Keeping first value.",
1685 firstRankId,
1686 itr->second.cone_degrees,
1687 sc.cone_degrees);
1688 }
1689 else
1690 {
1691 mSpellCones[firstRankId] = sc;
1692 ++count;
1693 }
1694 } while (result->NextRow());
1695
1696 LOG_INFO("server.loading", ">> Loaded {} Spell Cone definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1697 LOG_INFO("server.loading", " ");
1698}
std::int16_t int16
Definition Define.h:104
@ TARGET_SELECT_CATEGORY_CONE
Definition SpellInfo.h:82
Definition SpellMgr.h:397
int16_t cone_degrees
Definition SpellMgr.h:398

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 ( )
3054{
3055 uint32 oldMSTime = getMSTime();
3056
3058
3059 QueryResult result = WorldDatabase.Query("SELECT Id, RecoveryTime, CategoryRecoveryTime, StartRecoveryTime, StartRecoveryCategory FROM spell_cooldown_overrides");
3060
3061 uint32 count = 0;
3062
3063 if (result)
3064 {
3065 do
3066 {
3067 Field* fields = result->Fetch();
3068 SpellCooldownOverride spellCooldown;
3069 uint32 spellId = fields[0].Get<uint32>();
3070 spellCooldown.RecoveryTime = fields[1].Get<uint32>();
3071 spellCooldown.CategoryRecoveryTime = fields[2].Get<uint32>();
3072 spellCooldown.StartRecoveryTime = fields[3].Get<uint32>();
3073 spellCooldown.StartRecoveryCategory = fields[4].Get<uint32>();
3074 mSpellCooldownOverrideMap[spellId] = spellCooldown;
3075
3076 ++count;
3077 } while (result->NextRow());
3078 }
3079
3080 LOG_INFO("server.loading", ">> Loaded {} Spell Cooldown Overrides entries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3081 LOG_INFO("server.loading", " ");
3082}
Definition SpellMgr.h:616
uint32 StartRecoveryTime
Definition SpellMgr.h:619
uint32 CategoryRecoveryTime
Definition SpellMgr.h:618
uint32 StartRecoveryCategory
Definition SpellMgr.h:620
uint32 RecoveryTime
Definition SpellMgr.h:617

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

◆ LoadSpellEnchantProcData()

void SpellMgr::LoadSpellEnchantProcData ( )
2540{
2541 uint32 oldMSTime = getMSTime();
2542
2543 mSpellEnchantProcEventMap.clear(); // need for reload case
2544
2545 // 0 1 2 3 4
2546 QueryResult result = WorldDatabase.Query("SELECT entry, customChance, PPMChance, procEx, attributeMask FROM spell_enchant_proc_data");
2547 if (!result)
2548 {
2549 LOG_WARN("server.loading", ">> Loaded 0 spell enchant proc event conditions. DB table `spell_enchant_proc_data` is empty.");
2550 LOG_INFO("server.loading", " ");
2551 return;
2552 }
2553
2554 uint32 count = 0;
2555 do
2556 {
2557 Field* fields = result->Fetch();
2558
2559 uint32 enchantId = fields[0].Get<uint32>();
2560
2561 SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchantId);
2562 if (!ench)
2563 {
2564 LOG_ERROR("sql.sql", "Enchancment {} listed in `spell_enchant_proc_data` does not exist", enchantId);
2565 continue;
2566 }
2567
2569
2570 spe.customChance = fields[1].Get<uint32>();
2571 spe.PPMChance = fields[2].Get<float>();
2572 spe.procEx = fields[3].Get<uint32>();
2573 spe.attributeMask = fields[4].Get<uint32>();
2574
2575 mSpellEnchantProcEventMap[enchantId] = spe;
2576
2577 ++count;
2578 } while (result->NextRow());
2579
2580 LOG_INFO("server.loading", ">> Loaded {} Enchant Proc Data Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2581 LOG_INFO("server.loading", " ");
2582}
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 ( )
1701{
1702 uint32 oldMSTime = getMSTime();
1703
1704 mSpellSpellGroup.clear(); // need for reload case
1705 mSpellGroupSpell.clear();
1706
1707 // 0 1
1708 QueryResult result = WorldDatabase.Query("SELECT id, spell_id FROM spell_group");
1709 if (!result)
1710 {
1711 LOG_WARN("server.loading", ">> Loaded 0 spell group definitions. DB table `spell_group` is empty.");
1712 LOG_INFO("server.loading", " ");
1713 return;
1714 }
1715
1716 std::set<uint32> groups;
1717 uint32 count = 0;
1718 do
1719 {
1720 Field* fields = result->Fetch();
1721
1722 uint32 group_id = fields[0].Get<uint32>();
1723 if (group_id <= SPELL_GROUP_DB_RANGE_MIN && group_id >= SPELL_GROUP_CORE_RANGE_MAX)
1724 {
1725 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group` is in core range, but is not defined in core!", group_id);
1726 continue;
1727 }
1728 int32 spell_id = fields[1].Get<int32>();
1729
1730 groups.insert(group_id);
1731 mSpellGroupSpell.emplace(SpellGroup(group_id), spell_id);
1732
1733 } while (result->NextRow());
1734
1735 for (auto itr = mSpellGroupSpell.begin(); itr!= mSpellGroupSpell.end();)
1736 {
1737 if (itr->second < 0)
1738 {
1739 if (groups.find(abs(itr->second)) == groups.end())
1740 {
1741 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group` does not exist", abs(itr->second));
1742 itr = mSpellGroupSpell.erase(itr);
1743 }
1744 else
1745 ++itr;
1746 }
1747 else
1748 {
1749 SpellInfo const* spellInfo = GetSpellInfo(itr->second);
1750 if (!spellInfo)
1751 {
1752 LOG_ERROR("sql.sql", "Spell {} listed in `spell_group` does not exist", itr->second);
1753 itr = mSpellGroupSpell.erase(itr);
1754 }
1755 else if (spellInfo->GetRank() > 1)
1756 {
1757 LOG_ERROR("sql.sql", "Spell {} listed in `spell_group` is not first rank of spell.", itr->second);
1758 itr = mSpellGroupSpell.erase(itr);
1759 }
1760 else
1761 ++itr;
1762 }
1763 }
1764
1765 for (auto groupItr = groups.begin(); groupItr != groups.end(); ++groupItr)
1766 {
1767 std::set<uint32> spells;
1769
1770 for (auto spellItr = spells.begin(); spellItr != spells.end(); ++spellItr)
1771 {
1772 ++count;
1773 mSpellSpellGroup.emplace(*spellItr, SpellGroup(*groupItr));
1774 }
1775 }
1776
1777 LOG_INFO("server.loading", ">> Loaded {} spell group Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1778 LOG_INFO("server.loading", " ");
1779}
@ 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 ( )
1782{
1783 uint32 oldMSTime = getMSTime();
1784
1785 mSpellGroupStack.clear(); // need for reload case
1786 mSpellSameEffectStack.clear();
1787
1788 std::vector<uint32> sameEffectGroups;
1789
1790 // 0 1
1791 QueryResult result = WorldDatabase.Query("SELECT group_id, stack_rule FROM spell_group_stack_rules");
1792 if (!result)
1793 {
1794 LOG_WARN("server.loading", ">> Loaded 0 spell group stack rules. DB table `spell_group_stack_rules` is empty.");
1795 LOG_INFO("server.loading", " ");
1796 return;
1797 }
1798
1799 uint32 count = 0;
1800 do
1801 {
1802 Field* fields = result->Fetch();
1803
1804 uint32 group_id = fields[0].Get<uint32>();
1805 uint8 stack_rule = fields[1].Get<int8>();
1806 if (stack_rule >= SPELL_GROUP_STACK_RULE_MAX)
1807 {
1808 LOG_ERROR("sql.sql", "SpellGroupStackRule {} listed in `spell_group_stack_rules` does not exist.", stack_rule);
1809 continue;
1810 }
1811
1812 auto bounds = GetSpellGroupSpellMapBounds((SpellGroup)group_id);
1813 if (bounds.first == bounds.second)
1814 {
1815 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group_stack_rules` does not exist.", group_id);
1816 continue;
1817 }
1818
1819 mSpellGroupStack.emplace(SpellGroup(group_id), SpellGroupStackRule(stack_rule));
1820
1821 // different container for same effect stack rules, need to check effect types
1823 sameEffectGroups.push_back(group_id);
1824
1825 ++count;
1826 } while (result->NextRow());
1827
1828 LOG_INFO("server.loading", ">> Loaded {} spell group stack rules in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1829 LOG_INFO("server.loading", " ");
1830
1831 count = 0;
1832 oldMSTime = getMSTime();
1833
1834 for (uint32 group_id : sameEffectGroups)
1835 {
1836 std::set<uint32> spellIds;
1837 GetSetOfSpellsInSpellGroup(SpellGroup(group_id), spellIds);
1838
1839 std::unordered_set<uint32> auraTypes;
1840
1841 // we have to 'guess' what effect this group corresponds to
1842 {
1843 std::unordered_multiset<uint32 /*auraName*/> frequencyContainer;
1844
1845 // only waylay for the moment (shared group)
1846 std::vector<std::vector<uint32 /*auraName*/>> const SubGroups =
1847 {
1849 };
1850
1851 for (uint32 spellId : spellIds)
1852 {
1853 SpellInfo const* spellInfo = AssertSpellInfo(spellId);
1854 for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
1855 {
1856 if (!spellEffectInfo.IsAura())
1857 continue;
1858
1859 uint32 auraName = spellEffectInfo.ApplyAuraName;
1860 for (std::vector<uint32> const& subGroup : SubGroups)
1861 {
1862 if (std::find(subGroup.begin(), subGroup.end(), auraName) != subGroup.end())
1863 {
1864 // count as first aura
1865 auraName = subGroup.front();
1866 break;
1867 }
1868 }
1869
1870 frequencyContainer.insert(auraName);
1871 }
1872 }
1873
1874 uint32 auraType = 0;
1875 size_t auraTypeCount = 0;
1876 for (uint32 auraName : frequencyContainer)
1877 {
1878 size_t currentCount = frequencyContainer.count(auraName);
1879 if (currentCount > auraTypeCount)
1880 {
1881 auraType = auraName;
1882 auraTypeCount = currentCount;
1883 }
1884 }
1885
1886 for (std::vector<uint32> const& subGroup : SubGroups)
1887 {
1888 if (auraType == subGroup.front())
1889 {
1890 auraTypes.insert(subGroup.begin(), subGroup.end());
1891 break;
1892 }
1893 }
1894
1895 if (auraTypes.empty())
1896 auraTypes.insert(auraType);
1897 }
1898
1899 // re-check spells against guessed group
1900 for (uint32 spellId : spellIds)
1901 {
1902 SpellInfo const* spellInfo = AssertSpellInfo(spellId);
1903
1904 bool found = false;
1905 while (spellInfo)
1906 {
1907 for (uint32 auraType : auraTypes)
1908 {
1909 if (spellInfo->HasAura(AuraType(auraType)))
1910 {
1911 found = true;
1912 break;
1913 }
1914 }
1915
1916 if (found)
1917 break;
1918
1919 spellInfo = spellInfo->GetNextRankSpell();
1920 }
1921
1922 // not found either, log error
1923 if (!found)
1924 LOG_ERROR("sql.sql", "SpellId {} listed in `spell_group` with stack rule 3 does not share aura assigned for group {}", spellId, group_id);
1925 }
1926
1927 mSpellSameEffectStack[SpellGroup(group_id)] = auraTypes;
1928 ++count;
1929 }
1930
1931 LOG_INFO("server.loading", ">> Loaded {} SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT stack rules in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1932 LOG_INFO("server.loading", " ");
1933}
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:744

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

◆ LoadSpellInfoCorrections()

void SpellMgr::LoadSpellInfoCorrections ( )
40{
41 uint32 oldMSTime = getMSTime();
42
44 467, // Thorns (Rank 1)
45 782, // Thorns (Rank 2)
46 1075, // Thorns (Rank 3)
47 8914, // Thorns (Rank 4)
48 9756, // Thorns (Rank 5)
49 9910, // Thorns (Rank 6)
50 26992, // Thorns (Rank 7)
51 53307, // Thorns (Rank 8)
52 53352, // Explosive Shot (trigger)
53 50783, // Slam (Triggered spell)
54 20647 // Execute (Triggered spell)
55 }, [](SpellInfo* spellInfo)
56 {
57 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
58 });
59
60 // Scarlet Raven Priest Image
61 ApplySpellFix({ 48763, 48761 }, [](SpellInfo* spellInfo)
62 {
63 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_SPELL_ATTACK;
64 });
65
66 // Has Brewfest Mug
67 ApplySpellFix({ 42533 }, [](SpellInfo* spellInfo)
68 {
69 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(347); // 15 min
70 });
71
72 // 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, Mimiron, bomb bot explosion
1916 ApplySpellFix({ 63801 }, [](SpellInfo* spellInfo)
1917 {
1918 spellInfo->Effects[EFFECT_1].MiscValue = 17286;
1919 });
1920
1921 // Ulduar, Mimiron, Summon Flames Initial
1922 ApplySpellFix({ 64563 }, [](SpellInfo* spellInfo)
1923 {
1924 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1925 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
1926 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
1927 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1928 });
1929
1930 // Ulduar, Mimiron, Flames (damage)
1931 ApplySpellFix({ 64566 }, [](SpellInfo* spellInfo)
1932 {
1933 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1934 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
1935 });
1936
1937 // Ulduar, Hodir, Starlight
1938 ApplySpellFix({ 62807 }, [](SpellInfo* spellInfo)
1939 {
1940 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_1_YARD); // 1yd
1941 });
1942
1943 // Hodir Shatter Cache
1944 ApplySpellFix({ 62502 }, [](SpellInfo* spellInfo)
1945 {
1946 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
1947 });
1948
1949 // Ulduar, General Vezax, Mark of the Faceless
1950 ApplySpellFix({ 63278 }, [](SpellInfo* spellInfo)
1951 {
1952 spellInfo->Effects[EFFECT_0].Effect = 0;
1953 });
1954
1955 // Ulduar, General Vezax, Shadow Crash (area aura)
1956 ApplySpellFix({ 63277 }, [](SpellInfo* spellInfo)
1957 {
1958 spellInfo->AttributesEx5 |= SPELL_ATTR5_DO_NOT_DISPLAY_DURATION;
1959 });
1960
1961 // Boom (XT-002)
1962 ApplySpellFix({ 62834 }, [](SpellInfo* spellInfo)
1963 {
1964 spellInfo->Effects[EFFECT_1].Effect = 0;
1965 });
1966
1967 // Supercharge
1968 ApplySpellFix({ 61920 }, [](SpellInfo* spellInfo)
1969 {
1970 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
1971 });
1972
1973 // Lightning Whirl
1974 ApplySpellFix({ 61916 }, [](SpellInfo* spellInfo)
1975 {
1976 spellInfo->MaxAffectedTargets = 3;
1977 });
1978
1979 ApplySpellFix({ 63482 }, [](SpellInfo* spellInfo)
1980 {
1981 spellInfo->MaxAffectedTargets = 8;
1982 });
1983
1984 // Stone Grip, remove absorb aura
1985 ApplySpellFix({ 62056, 63985 }, [](SpellInfo* spellInfo)
1986 {
1987 spellInfo->Effects[EFFECT_1].Effect = 0;
1988 });
1989
1990 // Sentinel Blast
1991 ApplySpellFix({ 64389, 64678 }, [](SpellInfo* spellInfo)
1992 {
1993 spellInfo->Dispel = DISPEL_MAGIC;
1994 });
1995
1996 // Potent Pheromones
1997 ApplySpellFix({ 62619 }, [](SpellInfo* spellInfo)
1998 {
1999 spellInfo->AttributesEx |= SPELL_ATTR1_IMMUNITY_PURGES_EFFECT;
2000 });
2001
2002 // Healthy spore summon periodic
2003 ApplySpellFix({ 62566 }, [](SpellInfo* spellInfo)
2004 {
2005 spellInfo->Effects[EFFECT_0].Amplitude = 2000;
2006 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PERIODIC_TRIGGER_SPELL;
2007 });
2008
2009 // Brightleaf Essence trigger
2010 ApplySpellFix({ 62968 }, [](SpellInfo* spellInfo)
2011 {
2012 spellInfo->Effects[EFFECT_1].Effect = 0; // duplicate
2013 });
2014
2015 // Potent Pheromones
2016 ApplySpellFix({ 64321 }, [](SpellInfo* spellInfo)
2017 {
2018 spellInfo->AttributesEx |= SPELL_ATTR1_IMMUNITY_PURGES_EFFECT;
2019 });
2020
2021 // Lightning Orb Charged
2022 ApplySpellFix({ 62186 }, [](SpellInfo* spellInfo)
2023 {
2024 spellInfo->Effects[EFFECT_0].Amplitude = 5000; // Duration 5 secs, amplitude 8 secs...
2025 });
2026
2027 // Lightning Pillar
2028 ApplySpellFix({ 62976 }, [](SpellInfo* spellInfo)
2029 {
2030 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6);
2031 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(28); // 5 seconds, wrong DBC data?
2032 });
2033
2034 // Sif's Blizzard
2035 ApplySpellFix({ 62576, 62602 }, [](SpellInfo* spellInfo)
2036 {
2037 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_8_YARDS); // 8yd
2038 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_8_YARDS); // 8yd
2039 });
2040
2041 // Protective Gaze
2042 ApplySpellFix({ 64175 }, [](SpellInfo* spellInfo)
2043 {
2044 spellInfo->RecoveryTime = 25000;
2045 });
2046
2047 // Shadow Beacon
2048 ApplySpellFix({ 64465 }, [](SpellInfo* spellInfo)
2049 {
2050 spellInfo->Effects[EFFECT_0].TriggerSpell = 64467; // why do they need two script effects :/ (this one has visual effect)
2051 });
2052
2053 // Sanity
2054 ApplySpellFix({ 63050 }, [](SpellInfo* spellInfo)
2055 {
2056 spellInfo->AttributesEx6 |= SPELL_ATTR6_IGNORE_PHASE_SHIFT;
2057 });
2058
2059 // Shadow Nova (Sara)
2060 ApplySpellFix({ 65719 }, [](SpellInfo* spellInfo)
2061 {
2062 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
2063 spellInfo->AttributesEx4 |= SPELL_ATTR4_NO_CAST_LOG;
2064 });
2065
2066 // Cosmic Smash (Algalon the Observer)
2067 ApplySpellFix({ 62311, 64596 }, [](SpellInfo* spellInfo)
2068 {
2069 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2070 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
2071 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
2072 });
2073
2074 // Constellation Phase Effect
2075 ApplySpellFix({ 65509 }, [](SpellInfo* spellInfo)
2076 {
2077 spellInfo->MaxAffectedTargets = 1;
2078 });
2079
2080 // Black Hole
2081 ApplySpellFix({ 62168, 65250, 62169 }, [](SpellInfo* spellInfo)
2082 {
2083 spellInfo->Attributes |= SPELL_ATTR0_AURA_IS_DEBUFF;
2084 spellInfo->AttributesEx3 |= SPELL_ATTR3_ONLY_ON_PLAYER; // pets phased away from their owner get despawned
2085 });
2086
2087 // Ground Slam
2088 ApplySpellFix({ 62625 }, [](SpellInfo* spellInfo)
2089 {
2090 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
2091 });
2092
2093 // Onyxia's Lair, Onyxia, Flame Breath (TriggerSpell = 0 and spamming errors in console)
2094 ApplySpellFix({ 18435 }, [](SpellInfo* spellInfo)
2095 {
2096 spellInfo->Effects[EFFECT_1].Effect = 0;
2097 });
2098
2099 // Onyxia's Lair, Onyxia, Create Onyxia Spawner
2100 ApplySpellFix({ 17647 }, [](SpellInfo* spellInfo)
2101 {
2102 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(37);
2103 });
2104
2106 17646, // Onyxia's Lair, Onyxia, Summon Onyxia Whelp
2107 68968 // Onyxia's Lair, Onyxia, Summon Lair Guard
2108 }, [](SpellInfo* spellInfo)
2109 {
2110 spellInfo->Targets |= TARGET_FLAG_DEST_LOCATION;
2111 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2112 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
2113 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(5);
2114 });
2115
2116 // Onyxia's Lair, Onyxia, Eruption
2117 ApplySpellFix({ 17731, 69294 }, [](SpellInfo* spellInfo)
2118 {
2119 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_DUMMY;
2120 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(3);
2121 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_18_YARDS); // 18yd instead of 13yd to make sure all cracks erupt
2122 });
2123
2124 // Onyxia's Lair, Onyxia, Breath
2126 18576, 18578, 18579, 18580, 18581, 18582, 18583, 18609, 18611, 18612, 18613, 18614, 18615, 18616, 18584,
2127 18585, 18586, 18587, 18588, 18589, 18590, 18591, 18592, 18593, 18594, 18595, 18564, 18565, 18566, 18567,
2128 18568, 18569, 18570, 18571, 18572, 18573, 18574, 18575, 18596, 18597, 18598, 18599, 18600, 18601, 18602,
2129 18603, 18604, 18605, 18606, 18607, 18617, 18619, 18620, 18621, 18622, 18623, 18624, 18625, 18626, 18627,
2130 18628, 18618, 18351, 18352, 18353, 18354, 18355, 18356, 18357, 18358, 18359, 18360, 18361, 17086, 17087,
2131 17088, 17089, 17090, 17091, 17092, 17093, 17094, 17095, 17097, 22267, 22268, 21132, 21133, 21135, 21136,
2132 21137, 21138, 21139
2133 }, [](SpellInfo* spellInfo)
2134 {
2135 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(328); // 250ms
2136 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(1);
2137 if (spellInfo->Effects[EFFECT_1].Effect)
2138 {
2139 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
2140 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_PERIODIC_TRIGGER_SPELL;
2141 spellInfo->Effects[EFFECT_1].Amplitude = ((spellInfo->CastTimeEntry == sSpellCastTimesStore.LookupEntry(170)) ? 50 : 215);
2142 }
2143 });
2144
2146 48760, // Oculus, Teleport to Coldarra DND
2147 49305 // Oculus, Teleport to Boss 1 DND
2148 }, [](SpellInfo* spellInfo)
2149 {
2150 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
2151 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(17);
2152 });
2153
2154 // Oculus, Drake spell Stop Time
2155 ApplySpellFix({ 49838 }, [](SpellInfo* spellInfo)
2156 {
2157 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
2158 spellInfo->ExcludeTargetAuraSpell = 51162; // exclude planar shift
2159 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_150_YARDS);
2160 });
2161
2162 // Oculus, Varos Cloudstrider, Energize Cores
2163 ApplySpellFix({ 61407, 62136, 56251, 54069 }, [](SpellInfo* spellInfo)
2164 {
2165 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CONE_ENTRY);
2166 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2167 });
2168
2169 // Halls of Lightning, Arc Weld
2170 ApplySpellFix({ 59086 }, [](SpellInfo* spellInfo)
2171 {
2172 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(1);
2173 });
2174
2175 // Trial of the Champion, Death's Respite
2176 ApplySpellFix({ 68306 }, [](SpellInfo* spellInfo)
2177 {
2178 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
2179 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(25);
2180 });
2181
2182 // Trial of the Champion, Eadric Achievement (The Faceroller)
2183 ApplySpellFix({ 68197 }, [](SpellInfo* spellInfo)
2184 {
2185 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
2186 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD;
2187 });
2188
2189 // Trial of the Champion, Earth Shield
2190 ApplySpellFix({ 67530 }, [](SpellInfo* spellInfo)
2191 {
2192 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PROC_TRIGGER_SPELL; // will trigger 67537
2193 });
2194
2195 // Trial of the Champion, Hammer of the Righteous
2196 ApplySpellFix({ 66867 }, [](SpellInfo* spellInfo)
2197 {
2198 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_DUMMY;
2199 });
2200
2201 // Trial of the Champion, Summon Risen Jaeren/Arelas
2202 ApplySpellFix({ 67705, 67715 }, [](SpellInfo* spellInfo)
2203 {
2204 spellInfo->AttributesEx2 |= SPELL_ATTR2_ALLOW_DEAD_TARGET;
2205 });
2206
2207 // Trial of the Champion, Ghoul Explode
2208 ApplySpellFix({ 67751 }, [](SpellInfo* spellInfo)
2209 {
2210 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2211 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2212 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS);
2213 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2214 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2215 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS);
2216 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2217 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2218 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS);
2219 });
2220
2221 // Trial of the Champion, Desecration
2222 ApplySpellFix({ 67778, 67877 }, [](SpellInfo* spellInfo)
2223 {
2224 spellInfo->Effects[EFFECT_0].TriggerSpell = 68766;
2225 });
2226
2227 // Killing Spree (Off hand damage)
2228 ApplySpellFix({ 57842 }, [](SpellInfo* spellInfo)
2229 {
2230 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(2); // Melee Range
2231 });
2232
2233 // Trial of the Crusader, Jaraxxus Intro spell
2234 ApplySpellFix({ 67888 }, [](SpellInfo* spellInfo)
2235 {
2236 spellInfo->Attributes |= SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT;
2237 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
2238 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
2239 });
2240
2241 // Trial of the Crusader, Lich King Intro spell
2242 ApplySpellFix({ 68193 }, [](SpellInfo* spellInfo)
2243 {
2244 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
2245 });
2246
2247 // Trial of the Crusader, Gormok, player vehicle spell, CUSTOM! (default jump to hand, not used)
2248 ApplySpellFix({ 66342 }, [](SpellInfo* spellInfo)
2249 {
2250 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AURA;
2251 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_SET_VEHICLE_ID;
2252 spellInfo->Effects[EFFECT_0].MiscValue = 496;
2253 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21);
2254 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13);
2255 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
2256 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2257 spellInfo->AuraInterruptFlags = AURA_INTERRUPT_FLAG_CHANGE_MAP;
2258 });
2259
2260 // Trial of the Crusader, Gormok, Fire Bomb
2261 ApplySpellFix({ 66313 }, [](SpellInfo* spellInfo)
2262 {
2263 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2264 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ANY);
2265 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2266 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ANY);
2267 spellInfo->Effects[EFFECT_1].Effect = 0;
2268 });
2269
2270 ApplySpellFix({ 66317 }, [](SpellInfo* spellInfo)
2271 {
2272 spellInfo->Attributes |= SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT;
2273 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
2274 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
2275 });
2276
2277 ApplySpellFix({ 66318 }, [](SpellInfo* spellInfo)
2278 {
2279 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2280 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2281 spellInfo->Speed = 14.0f;
2282 spellInfo->Attributes |= SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT;
2283 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
2284 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
2285 });
2286
2287 ApplySpellFix({ 66320, 67472, 67473, 67475 }, [](SpellInfo* spellInfo)
2288 {
2289 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_2_YARDS);
2290 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_2_YARDS);
2291 });
2292
2293 // Trial of the Crusader, Acidmaw & Dreadscale, Emerge
2294 ApplySpellFix({ 66947 }, [](SpellInfo* spellInfo)
2295 {
2296 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_WHILE_STUNNED;
2297 });
2298
2299 // Trial of the Crusader, Jaraxxus, Curse of the Nether
2300 ApplySpellFix({ 66211 }, [](SpellInfo* spellInfo)
2301 {
2302 spellInfo->ExcludeTargetAuraSpell = 66209; // exclude Touch of Jaraxxus
2303 });
2304
2305 // Trial of the Crusader, Jaraxxus, Summon Volcano
2306 ApplySpellFix({ 66258, 67901 }, [](SpellInfo* spellInfo)
2307 {
2308 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(85); // summon for 18 seconds, 15 not enough
2309 });
2310
2311 // Trial of the Crusader, Jaraxxus, Spinning Pain Spike
2312 ApplySpellFix({ 66281 }, [](SpellInfo* spellInfo)
2313 {
2314 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_4_YARDS);
2315 });
2316
2317 ApplySpellFix({ 66287 }, [](SpellInfo* spellInfo)
2318 {
2319 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
2320 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_MOD_TAUNT;
2321 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_NEARBY_ENTRY);
2322 spellInfo->Effects[EFFECT_2].Effect = SPELL_EFFECT_APPLY_AURA;
2323 spellInfo->Effects[EFFECT_2].ApplyAuraName = SPELL_AURA_MOD_STUN;
2324 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
2325 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(35); // 4 secs
2326 });
2327
2328 // Trial of the Crusader, Jaraxxus, Fel Fireball
2329 ApplySpellFix({ 66532, 66963, 66964, 66965 }, [](SpellInfo* spellInfo)
2330 {
2331 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
2332 });
2333
2334 // tempfix, make Nether Power not stealable
2335 ApplySpellFix({ 66228, 67106, 67107, 67108 }, [](SpellInfo* spellInfo)
2336 {
2337 spellInfo->AttributesEx4 |= SPELL_ATTR4_CANNOT_BE_STOLEN;
2338 });
2339
2340 // Trial of the Crusader, Faction Champions, Druid - Tranquality
2341 ApplySpellFix({ 66086, 67974, 67975, 67976 }, [](SpellInfo* spellInfo)
2342 {
2343 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AREA_AURA_FRIEND;
2344 });
2345
2346 // Trial of the Crusader, Faction Champions, Shaman - Earth Shield
2347 ApplySpellFix({ 66063 }, [](SpellInfo* spellInfo)
2348 {
2349 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PROC_TRIGGER_SPELL;
2350 spellInfo->Effects[EFFECT_0].TriggerSpell = 66064;
2351 });
2352
2353 // Trial of the Crusader, Faction Champions, Priest - Mana Burn
2354 ApplySpellFix({ 66100 }, [](SpellInfo* spellInfo)
2355 {
2356 spellInfo->Effects[EFFECT_0].BasePoints = 5;
2357 spellInfo->Effects[EFFECT_0].DieSides = 0;
2358 });
2359
2360 ApplySpellFix({ 68026 }, [](SpellInfo* spellInfo)
2361 {
2362 spellInfo->Effects[EFFECT_0].BasePoints = 8;
2363 spellInfo->Effects[EFFECT_0].DieSides = 0;
2364 });
2365
2366 ApplySpellFix({ 68027 }, [](SpellInfo* spellInfo)
2367 {
2368 spellInfo->Effects[EFFECT_0].BasePoints = 6;
2369 spellInfo->Effects[EFFECT_0].DieSides = 0;
2370 });
2371
2372 ApplySpellFix({ 68028 }, [](SpellInfo* spellInfo)
2373 {
2374 spellInfo->Effects[EFFECT_0].BasePoints = 10;
2375 spellInfo->Effects[EFFECT_0].DieSides = 0;
2376 });
2377
2378 // Trial of the Crusader, Twin Valkyr, Touch of Light/Darkness, Light/Dark Surge
2380 65950 // light 0
2381 }, [](SpellInfo* spellInfo)
2382 {
2383 //spellInfo->EffectApplyAuraName[0] = SPELL_AURA_PERIODIC_DUMMY;
2384 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2385 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2386 spellInfo->Effects[EFFECT_1].Effect = 0;
2387 spellInfo->Effects[EFFECT_2].Effect = 0;
2388 });
2389
2391 65767 // light surge 0
2392 }, [](SpellInfo* spellInfo)
2393 {
2394 spellInfo->ExcludeTargetAuraSpell = 65686;
2395 });
2396
2398 67296 // light 1
2399 }, [](SpellInfo* spellInfo)
2400 {
2401 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2402 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2403 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2404 spellInfo->Effects[EFFECT_1].Effect = 0;
2405 spellInfo->Effects[EFFECT_2].Effect = 0;
2406 });
2407
2409 67274 // light surge 1
2410 }, [](SpellInfo* spellInfo)
2411 {
2412 spellInfo->ExcludeTargetAuraSpell = 67222;
2413 });
2414
2416 67297 // light 2
2417 }, [](SpellInfo* spellInfo)
2418 {
2419 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2420 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2421 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2422 spellInfo->Effects[EFFECT_1].Effect = 0;
2423 spellInfo->Effects[EFFECT_2].Effect = 0;
2424 });
2425
2427 67275 // light surge 2
2428 }, [](SpellInfo* spellInfo)
2429 {
2430 spellInfo->ExcludeTargetAuraSpell = 67223;
2431 });
2432
2434 67298 // light 3
2435 }, [](SpellInfo* spellInfo)
2436 {
2437 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2438 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2439 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2440 spellInfo->Effects[EFFECT_1].Effect = 0;
2441 spellInfo->Effects[EFFECT_2].Effect = 0;
2442 });
2443
2445 67276 // light surge 3
2446 }, [](SpellInfo* spellInfo)
2447 {
2448 spellInfo->ExcludeTargetAuraSpell = 67224;
2449 });
2450
2452 66001 // dark 0
2453 }, [](SpellInfo* spellInfo)
2454 {
2455 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2456 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2457 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2458 spellInfo->Effects[EFFECT_1].Effect = 0;
2459 spellInfo->Effects[EFFECT_2].Effect = 0;
2460 });
2461
2463 65769 // dark surge 0
2464 }, [](SpellInfo* spellInfo)
2465 {
2466 spellInfo->ExcludeTargetAuraSpell = 65684;
2467 });
2468
2470 67281 // dark 1
2471 }, [](SpellInfo* spellInfo)
2472 {
2473 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2474 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2475 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2476 spellInfo->Effects[EFFECT_1].Effect = 0;
2477 spellInfo->Effects[EFFECT_2].Effect = 0;
2478 });
2479
2481 67265 // dark surge 1
2482 }, [](SpellInfo* spellInfo)
2483 {
2484 spellInfo->ExcludeTargetAuraSpell = 67176;
2485 });
2486
2488 67282 // dark 2
2489 }, [](SpellInfo* spellInfo)
2490 {
2491 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2492 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2493 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2494 spellInfo->Effects[EFFECT_1].Effect = 0;
2495 spellInfo->Effects[EFFECT_2].Effect = 0;
2496 });
2497
2499 67266 // dark surge 2
2500 }, [](SpellInfo* spellInfo)
2501 {
2502 spellInfo->ExcludeTargetAuraSpell = 67177;
2503 });
2504
2506 67283 // dark 3
2507 }, [](SpellInfo* spellInfo)
2508 {
2509 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2510 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2511 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2512 spellInfo->Effects[EFFECT_1].Effect = 0;
2513 spellInfo->Effects[EFFECT_2].Effect = 0;
2514 });
2515
2517 67267 // dark surge 3
2518 }, [](SpellInfo* spellInfo)
2519 {
2520 spellInfo->ExcludeTargetAuraSpell = 67178;
2521 });
2522
2523 // Trial of the Crusader, Twin Valkyr, Twin's Pact
2524 ApplySpellFix({ 65875, 67303, 67304, 67305, 65876, 67306, 67307, 67308 }, [](SpellInfo* spellInfo)
2525 {
2526 spellInfo->Effects[EFFECT_1].Effect = 0;
2527 spellInfo->Effects[EFFECT_2].Effect = 0;
2528 });
2529
2530 // Trial of the Crusader, Anub'arak, Emerge
2531 ApplySpellFix({ 65982 }, [](SpellInfo* spellInfo)
2532 {
2533 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_WHILE_STUNNED;
2534 });
2535
2536 // Trial of the Crusader, Anub'arak, Penetrating Cold
2537 ApplySpellFix({ 66013, 67700, 68509, 68510 }, [](SpellInfo* spellInfo)
2538 {
2539 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
2540 });
2541
2542 // Trial of the Crusader, Anub'arak, Shadow Strike
2543 ApplySpellFix({ 66134 }, [](SpellInfo* spellInfo)
2544 {
2545 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
2546 spellInfo->Effects[EFFECT_0].Effect = 0;
2547 });
2548
2549 // Trial of the Crusader, Anub'arak, Pursuing Spikes
2550 ApplySpellFix({ 65920, 65922, 65923 }, [](SpellInfo* spellInfo)
2551 {
2552 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PERIODIC_DUMMY;
2553 //spellInfo->EffectTriggerSpell[0] = 0;
2554 });
2555
2556 // Trial of the Crusader, Anub'arak, Summon Scarab
2557 ApplySpellFix({ 66339 }, [](SpellInfo* spellInfo)
2558 {
2559 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(35);
2560 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
2561 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2562 });
2563
2564 // Trial of the Crusader, Anub'arak, Achievements: The Traitor King
2566 68186, // Anub'arak Scarab Achievement 10
2567 68515 // Anub'arak Scarab Achievement 25
2568 }, [](SpellInfo* spellInfo)
2569 {
2570 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2571 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
2572 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD;
2573 });
2574
2575 // Trial of the Crusader, Anub'arak, Spider Frenzy
2576 ApplySpellFix({ 66129 }, [](SpellInfo* spellInfo)
2577 {
2578 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
2579 });
2580
2581 // Soul Sickness
2582 ApplySpellFix({ 69131 }, [](SpellInfo* spellInfo)
2583 {
2584 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PERIODIC_TRIGGER_SPELL;
2585 spellInfo->Effects[EFFECT_0].Amplitude = 8000;
2586 spellInfo->Effects[EFFECT_0].TriggerSpell = 69133;
2587 });
2588
2589 // Phantom Blast
2590 ApplySpellFix({ 68982, 70322 }, [](SpellInfo* spellInfo)
2591 {
2592 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
2593 });
2594
2595 // Empowered Blizzard
2596 ApplySpellFix({ 70131 }, [](SpellInfo* spellInfo)
2597 {
2598 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2599 });
2600
2601 // Ice Lance Volley
2602 ApplySpellFix({ 70464 }, [](SpellInfo* spellInfo)
2603 {
2604 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2605 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2606 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_70_YARDS);
2607 });
2608
2610 70513, // Multi-Shot
2611 59514 // Shriek of the Highborne
2612 }, [](SpellInfo* spellInfo)
2613 {
2614 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CONE_ENTRY);
2615 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2616 });
2617
2618 // Icicle
2619 ApplySpellFix({ 69428, 69426 }, [](SpellInfo* spellInfo)
2620 {
2621 spellInfo->InterruptFlags = 0;
2622 spellInfo->AuraInterruptFlags = 0;
2623 spellInfo->ChannelInterruptFlags = 0;
2624 });
2625
2626 ApplySpellFix({ 70525, 70639 }, [](SpellInfo* spellInfo)
2627 {
2628 spellInfo->Effects[EFFECT_0].Effect = 0;
2629 spellInfo->Effects[EFFECT_1].Effect = 0;
2630 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2631 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2632 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_500_YARDS); // 500yd
2633 });
2634
2635 // Frost Nova
2636 ApplySpellFix({ 68198 }, [](SpellInfo* spellInfo)
2637 {
2638 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13);
2639 spellInfo->Targets |= TARGET_FLAG_DEST_LOCATION;
2640 });
2641
2642 // Blight
2643 ApplySpellFix({ 69604, 70286 }, [](SpellInfo* spellInfo)
2644 {
2645 spellInfo->MaxAffectedTargets = 1;
2646 spellInfo->AttributesEx3 |= (SPELL_ATTR3_ALWAYS_HIT | SPELL_ATTR3_ONLY_ON_PLAYER);
2647 });
2648
2649 // Chilling Wave
2650 ApplySpellFix({ 68778, 70333 }, [](SpellInfo* spellInfo)
2651 {
2652 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ENEMY);
2653 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2654 });
2655
2656 ApplySpellFix({ 68786, 70336 }, [](SpellInfo* spellInfo)
2657 {
2658 spellInfo->AttributesEx3 |= (SPELL_ATTR3_ALWAYS_HIT | SPELL_ATTR3_ONLY_ON_PLAYER);
2659 spellInfo->Effects[EFFECT_2].Effect = SPELL_EFFECT_DUMMY;
2660 });
2661
2662 // Pursuit
2663 ApplySpellFix({ 68987 }, [](SpellInfo* spellInfo)
2664 {
2665 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2666 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2667 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2668 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
2669 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
2670 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo();
2671 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100yd
2672 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
2673 });
2674
2675 ApplySpellFix({ 69029, 70850 }, [](SpellInfo* spellInfo)
2676 {
2677 spellInfo->Effects[EFFECT_2].Effect = 0;
2678 });
2679
2680 // Explosive Barrage
2681 ApplySpellFix({ 69263 }, [](SpellInfo* spellInfo)
2682 {
2683 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_MOD_STUN;
2684 });
2685
2686 // Overlord's Brand
2687 ApplySpellFix({ 69172 }, [](SpellInfo* spellInfo)
2688 {
2689 spellInfo->ProcFlags = DONE_HIT_PROC_FLAG_MASK & ~PROC_FLAG_DONE_PERIODIC;
2690 spellInfo->ProcChance = 100;
2691 });
2692
2693 // Icy Blast
2694 ApplySpellFix({ 69232 }, [](SpellInfo* spellInfo)
2695 {
2696 spellInfo->Effects[EFFECT_1].TriggerSpell = 69238;
2697 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2698 });
2699
2700 ApplySpellFix({ 69233, 69646 }, [](SpellInfo* spellInfo)
2701 {
2702 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2703 });
2704
2705 ApplySpellFix({ 69238, 69628 }, [](SpellInfo* spellInfo)
2706 {
2707 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2708 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_DEST_DYNOBJ_NONE);
2709 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2710 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_DEST_DYNOBJ_NONE);
2711 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2712 });
2713
2714 // Hoarfrost
2715 ApplySpellFix({ 69246, 69245, 69645 }, [](SpellInfo* spellInfo)
2716 {
2717 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2718 });
2719
2720 // Devour Humanoid
2721 ApplySpellFix({ 69503 }, [](SpellInfo* spellInfo)
2722 {
2723 spellInfo->ChannelInterruptFlags |= 0;
2724 spellInfo->AuraInterruptFlags = AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING;
2725 });
2726
2727 // Falric: Defiling Horror
2728 ApplySpellFix({ 72435, 72452 }, [](SpellInfo* spellInfo)
2729 {
2730 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
2731 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
2732 });
2733
2734 // Frostsworn General - Throw Shield
2735 ApplySpellFix({ 69222, 73076 }, [](SpellInfo* spellInfo)
2736 {
2737 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
2738 });
2739
2740 // Halls of Reflection Clone
2741 ApplySpellFix({ 69828 }, [](SpellInfo* spellInfo)
2742 {
2743 spellInfo->Effects[EFFECT_1].Effect = 0;
2744 spellInfo->Effects[EFFECT_2].Effect = 0;
2745 });
2746
2747 // Summon Ice Wall
2748 ApplySpellFix({ 69768 }, [](SpellInfo* spellInfo)
2749 {
2750 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2751 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL;
2752 });
2753
2754 ApplySpellFix({ 69767 }, [](SpellInfo* spellInfo)
2755 {
2756 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ANY);
2757 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2758 });
2759
2760 // Essence of the Captured
2761 ApplySpellFix({ 73035, 70719 }, [](SpellInfo* spellInfo)
2762 {
2763 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13);
2764 });
2765
2766 // Achievement Check
2767 ApplySpellFix({ 72830 }, [](SpellInfo* spellInfo)
2768 {
2769 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
2770 });
2771
2773 70781, // Light's Hammer Teleport
2774 70856, // Oratory of the Damned Teleport
2775 70857, // Rampart of Skulls Teleport
2776 70858, // Deathbringer's Rise Teleport
2777 70859, // Upper Spire Teleport
2778 70860, // Frozen Throne Teleport
2779 70861 // Sindragosa's Lair Teleport
2780 }, [](SpellInfo* spellInfo)
2781 {
2782 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2783 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2784 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB); // this target is for SPELL_EFFECT_TELEPORT_UNITS
2785 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
2786 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2787 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo();
2788 });
2789
2791 70960, // Bone Flurry
2792 71258 // Adrenaline Rush (Ymirjar Battle-Maiden)
2793 }, [](SpellInfo* spellInfo)
2794 {
2795 spellInfo->AttributesEx &= ~SPELL_ATTR1_IS_SELF_CHANNELED;
2796 });
2797
2798 // Saber Lash (Lord Marrowgar)
2799 ApplySpellFix({ 69055, 70814 }, [](SpellInfo* spellInfo)
2800 {
2801 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_5_YARDS); // 5yd
2802 });
2803
2804 // Impaled (Lord Marrowgar)
2805 ApplySpellFix({ 69065 }, [](SpellInfo* spellInfo)
2806 {
2807 spellInfo->Effects[EFFECT_0].Effect = 0; // remove stun so Dispersion can be used
2808 });
2809
2810 // Cold Flame (Lord Marrowgar)
2811 ApplySpellFix({ 72701, 72702, 72703, 72704 }, [](SpellInfo* spellInfo)
2812 {
2813 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
2814 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2815 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
2816 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(9); // 30 secs instead of 12, need him for longer, but will stop his actions after 12 secs
2817 });
2818
2819 ApplySpellFix({ 69138 }, [](SpellInfo* spellInfo)
2820 {
2821 spellInfo->Effects[EFFECT_0].Effect = 0;
2822 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2823 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(9); // 30 secs instead of 12, need him for longer, but will stop his actions after 12 secs
2824 });
2825
2826 ApplySpellFix({ 69146, 70823, 70824, 70825 }, [](SpellInfo* spellInfo)
2827 {
2828 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS); // 3yd instead of 5yd
2829 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
2830 });
2831
2832 // Dark Martyrdom (Lady Deathwhisper)
2833 ApplySpellFix({ 70897 }, [](SpellInfo* spellInfo)
2834 {
2835 spellInfo->AttributesEx2 |= SPELL_ATTR2_ALLOW_DEAD_TARGET;
2836 });
2837
2839 69075, // Bone Storm (Lord Marrowgar)
2840 70834, // Bone Storm (Lord Marrowgar)
2841 70835, // Bone Storm (Lord Marrowgar)
2842 70836, // Bone Storm (Lord Marrowgar)
2843 72378, // Blood Nova (Deathbringer Saurfang)
2844 73058, // Blood Nova (Deathbringer Saurfang)
2845 72769, // Scent of Blood (Deathbringer Saurfang)
2846 72385, // Boiling Blood (Deathbringer Saurfang)
2847 72441, // Boiling Blood (Deathbringer Saurfang)
2848 72442, // Boiling Blood (Deathbringer Saurfang)
2849 72443, // Boiling Blood (Deathbringer Saurfang)
2850 71160, // Plague Stench (Stinky)
2851 71161, // Plague Stench (Stinky)
2852 71123, // Decimate (Stinky & Precious)
2853 71464 // Divine Surge (Sister Svalna)
2854 }, [](SpellInfo* spellInfo)
2855 {
2856 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
2857 });
2858
2859 // Shadow's Fate
2860 ApplySpellFix({ 71169 }, [](SpellInfo* spellInfo)
2861 {
2862 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
2863 });
2864
2865 // Lock Players and Tap Chest
2866 ApplySpellFix({ 72347 }, [](SpellInfo* spellInfo)
2867 {
2868 spellInfo->AttributesEx3 &= ~SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
2869 });
2870
2871 // Award Reputation - Boss Kill
2872 ApplySpellFix({ 73843, 73844, 73845, 73846 }, [](SpellInfo* spellInfo)
2873 {
2874 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS);
2875 });
2876
2877 // Death Plague (Rotting Frost Giant)
2878 ApplySpellFix({ 72864 }, [](SpellInfo* spellInfo)
2879 {
2880 spellInfo->ExcludeTargetAuraSpell = 0;
2881 });
2882
2883 // Gunship Battle, spell Below Zero
2884 ApplySpellFix({ 69705 }, [](SpellInfo* spellInfo)
2885 {
2886 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
2887 });
2888
2889 // Resistant Skin (Deathbringer Saurfang adds)
2890 ApplySpellFix({ 72723 }, [](SpellInfo* spellInfo)
2891 {
2892 // this spell initially granted Shadow damage immunity, however it was removed but the data was left in client
2893 spellInfo->Effects[EFFECT_2].Effect = 0;
2894 });
2895
2896 // Mark of the Fallen Champion (Deathbringer Saurfang)
2897 ApplySpellFix({ 72255, 72444, 72445, 72446 }, [](SpellInfo* spellInfo)
2898 {
2899 // Patch 3.3.2 (2010-01-02): Deathbringer Saurfang will no longer gain blood power from Mark of the Fallen Champion.
2900 // prevented in script, effect needed for Prayer of Mending
2901 spellInfo->AttributesEx3 &= ~SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
2902 });
2903
2904 // Coldflame Jets (Traps after Saurfang)
2905 ApplySpellFix({ 70460 }, [](SpellInfo* spellInfo)
2906 {
2907 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(1); // 10 seconds
2908 });
2909
2911 70461, // Coldflame Jets (Traps after Saurfang)
2912 71289 // Dominate Mind (Lady Deathwhisper)
2913 }, [](SpellInfo* spellInfo)
2914 {
2915 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2916 });
2917
2918 // Severed Essence (Val'kyr Herald)
2919 ApplySpellFix({ 71906, 71942 }, [](SpellInfo* spellInfo)
2920 {
2921 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
2922 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2923 spellInfo->Effects[EFFECT_1].Effect = 0;
2924 });
2925
2927 71159, // Awaken Plagued Zombies (Precious)
2928 71302 // Awaken Ymirjar Fallen (Ymirjar Deathbringer)
2929 }, [](SpellInfo* spellInfo)
2930 {
2931 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21);
2932 });
2933
2934 // Blood Prince Council, Invocation of Blood
2935 ApplySpellFix({ 70981, 70982, 70952 }, [](SpellInfo* spellInfo)
2936 {
2937 spellInfo->Effects[EFFECT_0].Effect = 0; // clear share health aura
2938 });
2939
2940 // Ymirjar Frostbinder, Frozen Orb
2941 ApplySpellFix({ 71274 }, [](SpellInfo* spellInfo)
2942 {
2943 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2944 });
2945
2946 // Ooze Flood (Rotface)
2947 ApplySpellFix({ 69783, 69797, 69799, 69802 }, [](SpellInfo* spellInfo)
2948 {
2949 spellInfo->AttributesEx |= SPELL_ATTR1_EXCLUDE_CASTER;
2950 });
2951
2952 // Volatile Ooze Beam Protection
2953 ApplySpellFix({ 70530 }, [](SpellInfo* spellInfo)
2954 {
2955 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AURA; // blizzard typo, 65 instead of 6, aura itself is defined (dummy)
2956 });
2957
2958 // Professor Putricide, Gaseous Bloat (Orange Ooze Channel)
2959 ApplySpellFix({ 70672, 72455, 72832, 72833 }, [](SpellInfo* spellInfo)
2960 {
2961 // copied attributes from Green Ooze Channel
2962 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
2963 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
2964 });
2965
2967 71412, // Green Ooze Summon (Professor Putricide)
2968 71415 // Orange Ooze Summon (Professor Putricide)
2969 }, [](SpellInfo* spellInfo)
2970 {
2971 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2972 });
2973
2975 71621, // Create Concoction (Professor Putricide)
2976 72850,
2977 72851,
2978 72852,
2979 71893, // Guzzle Potions (Professor Putricide)
2980 73120,
2981 73121,
2982 73122
2983 }, [](SpellInfo* spellInfo)
2984 {
2985 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(15); // 4 sec
2986 });
2987
2988 // Mutated Plague (Professor Putricide)
2989 ApplySpellFix({ 72454, 72464, 72506, 72507 }, [](SpellInfo* spellInfo)
2990 {
2991 spellInfo->AttributesEx4 |= SPELL_ATTR4_NO_CAST_LOG;
2992 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
2993 });
2994
2995 // Unbound Plague (Professor Putricide) (needs target selection script)
2996 ApplySpellFix({ 70911, 72854, 72855, 72856 }, [](SpellInfo* spellInfo)
2997 {
2998 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
2999 });
3000
3001 // Mutated Transformation (Professor Putricide)
3002 ApplySpellFix({ 70402, 72511, 72512, 72513 }, [](SpellInfo* spellInfo)
3003 {
3004 spellInfo->AttributesEx2 |= SPELL_ATTR2_CANT_CRIT;
3005 });
3006
3007 // Empowered Flare (Blood Prince Council)
3008 ApplySpellFix({ 71708, 72785, 72786, 72787 }, [](SpellInfo* spellInfo)
3009 {
3010 spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_MODIFIERS;
3011 });
3012
3014 71518, // Unholy Infusion Quest Credit (Professor Putricide)
3015 72934, // Blood Infusion Quest Credit (Blood-Queen Lana'thel)
3016 72289 // Frost Infusion Quest Credit (Sindragosa)
3017 }, [](SpellInfo* spellInfo)
3018 {
3019 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // another missing radius
3020 });
3021
3022 // Swarming Shadows
3023 ApplySpellFix({ 71266, 72890 }, [](SpellInfo* spellInfo)
3024 {
3025 spellInfo->AreaGroupId = 0; // originally, these require area 4522, which is... outside of Icecrown Citadel
3026 });
3027
3029 71301, // Summon Dream Portal (Valithria Dreamwalker)
3030 71977 // Summon Nightmare Portal (Valithria Dreamwalker)
3031 }, [](SpellInfo* spellInfo)
3032 {
3033 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
3034 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
3035 });
3036
3037 // Column of Frost (visual marker)
3038 ApplySpellFix({ 70715 }, [](SpellInfo* spellInfo)
3039 {
3040 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(32); // 6 seconds (missing)
3041 });
3042
3043 // Mana Void (periodic aura)
3044 ApplySpellFix({ 71085 }, [](SpellInfo* spellInfo)
3045 {
3046 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(9); // 30 seconds (missing)
3047 });
3048
3049 // Summon Suppressor (needs target selection script)
3050 ApplySpellFix({ 70936 }, [](SpellInfo* spellInfo)
3051 {
3052 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3053 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
3054 });
3055
3056 // Corruption
3057 ApplySpellFix({ 70602 }, [](SpellInfo* spellInfo)
3058 {
3059 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
3060 });
3061
3063 72706, // Achievement Check (Valithria Dreamwalker)
3064 71357 // Order Whelp
3065 }, [](SpellInfo* spellInfo)
3066 {
3067 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3068 });
3069
3070 // Sindragosa's Fury
3071 ApplySpellFix({ 70598 }, [](SpellInfo* spellInfo)
3072 {
3073 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
3074 });
3075
3076 // Tail Smash (Sindragosa)
3077 ApplySpellFix({ 71077 }, [](SpellInfo* spellInfo)
3078 {
3079 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3080 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER_BACK);
3081 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_DEST_AREA_ENEMY);
3082 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER_BACK);
3083 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_DEST_AREA_ENEMY);
3084 });
3085
3086 // Frost Bomb
3087 ApplySpellFix({ 69846 }, [](SpellInfo* spellInfo)
3088 {
3089 spellInfo->Speed = 0.0f; // This spell's summon happens instantly
3090 });
3091
3092 // Mystic Buffet (Sindragosa)
3093 ApplySpellFix({ 70127, 72528, 72529, 72530 }, [](SpellInfo* spellInfo)
3094 {
3095 spellInfo->Effects[EFFECT_1].Effect = 0; // remove obsolete spell effect with no targets
3096 });
3097
3098 // Sindragosa, Frost Aura
3099 ApplySpellFix({ 70084, 71050, 71051, 71052 }, [](SpellInfo* spellInfo)
3100 {
3101 spellInfo->Attributes &= ~SPELL_ATTR0_NO_IMMUNITIES;
3102 });
3103
3104 // Ice Lock
3105 ApplySpellFix({ 71614 }, [](SpellInfo* spellInfo)
3106 {
3107 spellInfo->Mechanic = MECHANIC_STUN;
3108 });
3109
3110 // Lich King, Infest
3111 ApplySpellFix({ 70541, 73779, 73780, 73781 }, [](SpellInfo* spellInfo)
3112 {
3113 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3114 });
3115
3116 // Lich King, Necrotic Plague
3117 ApplySpellFix({ 70337, 73912, 73913, 73914, 70338, 73785, 73786, 73787 }, [](SpellInfo* spellInfo)
3118 {
3119 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
3120 });
3121
3123 69099, // Ice Pulse 10n
3124 73776, // Ice Pulse 25n
3125 73777, // Ice Pulse 10h
3126 73778 // Ice Pulse 25h
3127 }, [](SpellInfo* spellInfo)
3128 {
3129 spellInfo->AttributesEx2 |= SPELL_ATTR2_CANT_CRIT;
3130 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
3131 });
3132
3133 // Fury of Frostmourne
3134 ApplySpellFix({ 72350 }, [](SpellInfo* spellInfo)
3135 {
3136 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3137 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3138 });
3139
3141 72351, // Fury of Frostmourne
3142 72431, // Jump (removes Fury of Frostmourne debuff)
3143 72429, // Mass Resurrection
3144 73159 // Play Movie
3145 }, [](SpellInfo* spellInfo)
3146 {
3147 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3148 });
3149
3150 // Raise Dead
3151 ApplySpellFix({ 72376 }, [](SpellInfo* spellInfo)
3152 {
3153 spellInfo->MaxAffectedTargets = 4;
3154 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3155 });
3156
3157 // Jump
3158 ApplySpellFix({ 71809 }, [](SpellInfo* spellInfo)
3159 {
3160 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(5); // 40yd
3161 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
3162 spellInfo->Effects[EFFECT_0].MiscValue = 190;
3163 });
3164
3165 // Broken Frostmourne
3166 ApplySpellFix({ 72405 }, [](SpellInfo* spellInfo)
3167 {
3168 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3169 });
3170
3171 // Summon Shadow Trap
3172 ApplySpellFix({ 73540 }, [](SpellInfo* spellInfo)
3173 {
3174 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(3); // 60 seconds
3175 });
3176
3177 // Shadow Trap (visual)
3178 ApplySpellFix({ 73530 }, [](SpellInfo* spellInfo)
3179 {
3180 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(28); // 5 seconds
3181 });
3182
3183 // Shadow Trap
3184 ApplySpellFix({ 73529 }, [](SpellInfo* spellInfo)
3185 {
3186 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
3187 });
3188
3189 // Shadow Trap (searcher)
3190 ApplySpellFix({ 74282 }, [](SpellInfo* spellInfo)
3191 {
3192 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS); // 3yd
3193 });
3194
3195 // Raging Spirit Visual
3196 ApplySpellFix({ 69198 }, [](SpellInfo* spellInfo)
3197 {
3198 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
3199 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3200 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
3201 });
3202
3203 // Defile
3204 ApplySpellFix({ 72762 }, [](SpellInfo* spellInfo)
3205 {
3206 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(559); // 53 seconds
3207 spellInfo->ExcludeCasterAuraSpell = 0;
3208 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
3210 });
3211
3212 // Defile
3213 ApplySpellFix({ 72743 }, [](SpellInfo* spellInfo)
3214 {
3215 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(22); // 45 seconds
3216 });
3217
3218 ApplySpellFix({ 72754, 73708, 73709, 73710 }, [](SpellInfo* spellInfo)
3219 {
3220 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3221 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3222 });
3223
3224 // Val'kyr Target Search
3225 ApplySpellFix({ 69030 }, [](SpellInfo* spellInfo)
3226 {
3227 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3228 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3229 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
3230 });
3231
3232 // Harvest Souls
3233 ApplySpellFix({ 73654, 74295, 74296, 74297 }, [](SpellInfo* spellInfo)
3234 {
3235 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3236 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3237 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3238 });
3239
3240 // Restore Soul
3241 ApplySpellFix({ 72595, 73650 }, [](SpellInfo* spellInfo)
3242 {
3243 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3244 });
3245
3246 // Kill Frostmourne Players
3247 ApplySpellFix({ 75127 }, [](SpellInfo* spellInfo)
3248 {
3249 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3250 });
3251
3252 // Harvest Soul
3253 ApplySpellFix({ 73655 }, [](SpellInfo* spellInfo)
3254 {
3255 spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_MODIFIERS;
3256 });
3257
3258 // Destroy Soul
3259 ApplySpellFix({ 74086 }, [](SpellInfo* spellInfo)
3260 {
3261 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3262 });
3263
3264 // Summon Spirit Bomb
3265 ApplySpellFix({ 74302, 74342 }, [](SpellInfo* spellInfo)
3266 {
3267 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3268 spellInfo->MaxAffectedTargets = 1;
3269 });
3270
3271 // Summon Spirit Bomb
3272 ApplySpellFix({ 74341, 74343 }, [](SpellInfo* spellInfo)
3273 {
3274 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3275 spellInfo->MaxAffectedTargets = 3;
3276 });
3277
3278 // Summon Spirit Bomb
3279 ApplySpellFix({ 73579 }, [](SpellInfo* spellInfo)
3280 {
3281 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_25_YARDS); // 25yd
3282 });
3283
3284 // Trigger Vile Spirit (Inside, Heroic)
3285 ApplySpellFix({ 73582 }, [](SpellInfo* spellInfo)
3286 {
3287 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3288 });
3289
3290 // Scale Aura (used during Dominate Mind from Lady Deathwhisper)
3291 ApplySpellFix({ 73261 }, [](SpellInfo* spellInfo)
3292 {
3293 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
3294 });
3295
3296 // Leap to a Random Location
3297 ApplySpellFix({ 70485 }, [](SpellInfo* spellInfo)
3298 {
3299 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100yd
3300 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS);
3301 spellInfo->Effects[EFFECT_0].MiscValue = 100;
3302 });
3303
3304 ApplySpellFix({ 74509 }, [](SpellInfo* spellInfo)
3305 {
3306 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd
3307 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd
3308 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd
3309 });
3310
3311 // Rallying Shout
3312 ApplySpellFix({ 75414 }, [](SpellInfo* spellInfo)
3313 {
3314 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd
3315 });
3316
3317 // Barrier Channel
3318 ApplySpellFix({ 76221 }, [](SpellInfo* spellInfo)
3319 {
3320 spellInfo->ChannelInterruptFlags &= ~(AURA_INTERRUPT_FLAG_TURNING | AURA_INTERRUPT_FLAG_MOVE);
3321 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_NEARBY_ENTRY);
3322 });
3323
3324 // Intimidating Roar
3325 ApplySpellFix({ 74384 }, [](SpellInfo* spellInfo)
3326 {
3327 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3328 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3329 });
3330
3332 74562, // Fiery Combustion
3333 74792 // Soul Consumption
3334 }, [](SpellInfo* spellInfo)
3335 {
3336 spellInfo->AttributesEx |= SPELL_ATTR1_NO_REDIRECTION;
3337 });
3338
3339 // Combustion
3340 ApplySpellFix({ 75883, 75884 }, [](SpellInfo* spellInfo)
3341 {
3342 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_6_YARDS); // 6yd
3343 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_6_YARDS); // 6yd
3344 });
3345
3346 // Consumption
3347 ApplySpellFix({ 75875, 75876 }, [](SpellInfo* spellInfo)
3348 {
3349 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_6_YARDS); // 6yd
3350 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_6_YARDS); // 6yd
3351 spellInfo->Effects[EFFECT_0].Mechanic = MECHANIC_NONE;
3352 spellInfo->Effects[EFFECT_1].Mechanic = MECHANIC_SNARE;
3353 });
3354
3355 // Soul Consumption
3356 ApplySpellFix({ 74799 }, [](SpellInfo* spellInfo)
3357 {
3358 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_12_YARDS); // 12yd
3359 });
3360
3361 // Twilight Cutter
3362 ApplySpellFix({ 74769, 77844, 77845, 77846 }, [](SpellInfo* spellInfo)
3363 {
3364 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3365 });
3366
3367 // Twilight Mending
3368 ApplySpellFix({ 75509 }, [](SpellInfo* spellInfo)
3369 {
3370 spellInfo->AttributesEx6 |= SPELL_ATTR6_IGNORE_PHASE_SHIFT;
3371 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3372 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3373 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3374 });
3375
3376 // Meteor Strike
3377 ApplySpellFix({ 74637 }, [](SpellInfo* spellInfo)
3378 {
3379 spellInfo->Speed = 0;
3380 });
3381
3382 //Blazing Aura
3383 ApplySpellFix({ 75885, 75886 }, [](SpellInfo* spellInfo)
3384 {
3385 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
3386 });
3387
3389 75952, //Meteor Strike
3390 74629 //Combustion Periodic
3391 }, [](SpellInfo* spellInfo)
3392 {
3393 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
3394 });
3395
3396 // Going Bearback
3397 ApplySpellFix({ 54897 }, [](SpellInfo* spellInfo)
3398 {
3399 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_DUMMY;
3400 spellInfo->Effects[EFFECT_1].RadiusEntry = spellInfo->Effects[EFFECT_0].RadiusEntry;
3401 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_DEST_AREA_ENTRY);
3402 });
3403
3404 // Still At It
3405 ApplySpellFix({ 51931, 51932, 51933 }, [](SpellInfo* spellInfo)
3406 {
3407 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(38);
3408 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
3409 });
3410
3411 // Rallying the Troops
3412 ApplySpellFix({ 47394 }, [](SpellInfo* spellInfo)
3413 {
3414 spellInfo->ExcludeTargetAuraSpell = 47394;
3415 });
3416
3417 // A Tangled Skein
3418 ApplySpellFix({ 51165, 51173 }, [](SpellInfo* spellInfo)
3419 {
3420 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
3421 });
3422
3424 69563, // A Cloudlet of Classy Cologne
3425 69445, // A Perfect Puff of Perfume
3426 69489 // Bonbon Blitz
3427 }, [](SpellInfo* spellInfo)
3428 {
3429 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
3430 });
3431
3432 // Control
3433 ApplySpellFix({ 30790 }, [](SpellInfo* spellInfo)
3434 {
3435 spellInfo->Effects[EFFECT_1].MiscValue = 0;
3436 });
3437
3438 // Reclusive Runemaster
3439 ApplySpellFix({ 48028 }, [](SpellInfo* spellInfo)
3440 {
3441 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
3442 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
3443 });
3444
3445 // Mastery of
3446 ApplySpellFix({ 65147 }, [](SpellInfo* spellInfo)
3447 {
3448 spellInfo->CategoryEntry = sSpellCategoryStore.LookupEntry(1244);
3449 spellInfo->CategoryRecoveryTime = 1500;
3450 });
3451
3452 // Weakness to Lightning
3453 ApplySpellFix({ 46432 }, [](SpellInfo* spellInfo)
3454 {
3455 spellInfo->AttributesEx3 &= ~SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
3456 });
3457
3458 // Wrangle Some Aether Rays!
3459 ApplySpellFix({ 40856 }, [](SpellInfo* spellInfo)
3460 {
3461 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(27); // 3000ms
3462 });
3463
3464 // The Black Knight's Orders
3465 ApplySpellFix({ 63163 }, [](SpellInfo* spellInfo)
3466 {
3467 spellInfo->Effects[EFFECT_0].BasePoints = 52390;
3468 });
3469
3470 // The Warp Rifts
3471 ApplySpellFix({ 34888 }, [](SpellInfo* spellInfo)
3472 {
3473 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(5); // 300 secs
3474 });
3475
3476 // The Smallest Creatures
3477 ApplySpellFix({ 38544 }, [](SpellInfo* spellInfo)
3478 {
3479 spellInfo->Effects[EFFECT_0].MiscValueB = 427;
3480 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(1);
3481 spellInfo->Effects[EFFECT_1].Effect = 0;
3482 });
3483
3484 // Ridding the red rocket
3485 ApplySpellFix({ 49177 }, [](SpellInfo* spellInfo)
3486 {
3487 spellInfo->Effects[EFFECT_0].BasePoints = 1; // corrects seat id (points - 1 = seatId)
3488 });
3489
3490 // Jormungar Strike
3491 ApplySpellFix({ 56513 }, [](SpellInfo* spellInfo)
3492 {
3493 spellInfo->RecoveryTime = 2000;
3494 });
3495
3497 37851, // Tag Greater Felfire Diemetradon
3498 37918 // Arcano-pince
3499 }, [](SpellInfo* spellInfo)
3500 {
3501 spellInfo->RecoveryTime = 3000;
3502 });
3503
3505 54997, // Cast Net (tooltip says 10s but sniffs say 6s)
3506 56524 // Acid Breath
3507 }, [](SpellInfo* spellInfo)
3508 {
3509 spellInfo->RecoveryTime = 6000;
3510 });
3511
3513 47911, // EMP
3514 48620, // Wing Buffet
3515 51752 // Stampy's Stompy-Stomp
3516 }, [](SpellInfo* spellInfo)
3517 {
3518 spellInfo->RecoveryTime = 10000;
3519 });
3520
3522 37727, // Touch of Darkness
3523 54996 // Ice Slick (tooltip says 20s but sniffs say 12s)
3524 }, [](SpellInfo* spellInfo)
3525 {
3526 spellInfo->RecoveryTime = 12000;
3527 });
3528
3529 // Signal Helmet to Attack
3530 ApplySpellFix({ 51748 }, [](SpellInfo* spellInfo)
3531 {
3532 spellInfo->RecoveryTime = 15000;
3533 });
3534
3536 51756, // Charge
3537 37919, //Arcano-dismantle
3538 37917 //Arcano-Cloak
3539 }, [](SpellInfo* spellInfo)
3540 {
3541 spellInfo->RecoveryTime = 20000;
3542 });
3543
3544 // Kaw the Mammoth Destroyer
3545 ApplySpellFix({ 46260 }, [](SpellInfo* spellInfo)
3546 {
3547 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3548 });
3549
3550 // That's Abominable
3551 ApplySpellFix({ 59565 }, [](SpellInfo* spellInfo)
3552 {
3553 spellInfo->Effects[EFFECT_0].MiscValueB = 1721; // controllable guardian
3554 });
3555
3556 // Investigate the Blue Recluse (1920)
3557 // Investigate the Alchemist Shop (1960)
3558 ApplySpellFix({ 9095 }, [](SpellInfo* spellInfo)
3559 {
3560 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_DUMMY;
3561 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
3562 });
3563
3564 // Gauging the Resonant Frequency (10594)
3565 ApplySpellFix({ 37390 }, [](SpellInfo* spellInfo)
3566 {
3567 spellInfo->Effects[EFFECT_0].MiscValueB = 181;
3568 });
3569
3570 // Where in the World is Hemet Nesingwary? (12521)
3571 ApplySpellFix({ 50860 }, [](SpellInfo* spellInfo)
3572 {
3573 spellInfo->Effects[EFFECT_0].BasePoints = 50860;
3574 });
3575
3576 ApplySpellFix({ 50861 }, [](SpellInfo* spellInfo)
3577 {
3578 spellInfo->Effects[EFFECT_0].BasePoints = 0;
3579 });
3580
3581 // Riding Jokkum
3582 ApplySpellFix({ 56606 }, [](SpellInfo* spellInfo)
3583 {
3584 spellInfo->Effects[EFFECT_0].BasePoints = 1;
3585 });
3586
3587 // Blightbeasts be Damned! (12072)
3588 ApplySpellFix({ 47424 }, [](SpellInfo* spellInfo)
3589 {
3590 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_NOT_ABOVEWATER;
3591 });
3592
3593 // Dark Horizon (12664), Reunited (12663)
3594 ApplySpellFix({ 52190 }, [](SpellInfo* spellInfo)
3595 {
3596 spellInfo->Effects[EFFECT_0].BasePoints = 52391 - 1;
3597 });
3598
3599 // The Sum is Greater than the Parts (13043) - Chained Grip
3600 ApplySpellFix({ 60540 }, [](SpellInfo* spellInfo)
3601 {
3602 spellInfo->Effects[EFFECT_0].MiscValue = 300;
3603 });
3604
3605 // Not a Bug (13342)
3606 ApplySpellFix({ 60531 }, [](SpellInfo* spellInfo)
3607 {
3608 spellInfo->AttributesEx2 |= SPELL_ATTR2_ALLOW_DEAD_TARGET;
3609 });
3610
3611 // Frankly, It Makes No Sense... (10672)
3612 ApplySpellFix({ 37851 }, [](SpellInfo* spellInfo)
3613 {
3614 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
3615 });
3616
3617 // Honor Challenge (12939)
3618 ApplySpellFix({ 21855 }, [](SpellInfo* spellInfo)
3619 {
3620 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
3621 });
3622
3623 // Convocation at Zol'Heb (12730)
3624 ApplySpellFix({ 52956 }, [](SpellInfo* spellInfo)
3625 {
3626 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_DEST_AREA_ENTRY);
3627 });
3628
3629 // Mangletooth
3631 7764, // Wisdom of Agamaggan
3632 10767, // Rising Spirit
3633 16610, // Razorhide
3634 16612, // Agamaggan's Strength
3635 16618, // Spirit of the Wind
3636 17013 // Agamaggan's Agility
3637 }, [](SpellInfo* spellInfo)
3638
3639 {
3640 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3641 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT;
3642 });
3643
3644 // Battle for the Undercity
3646 59892 // Cyclone fall
3647 }, [](SpellInfo* spellInfo)
3648 {
3649 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AREA_AURA_FRIEND;
3650 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
3651 spellInfo->AttributesEx &= ~SPELL_ATTR0_NO_AURA_CANCEL;
3652 spellInfo->AttributesEx3 |= SPELL_ATTR3_ONLY_ON_PLAYER;
3653 });
3654
3655 // enchant Lightweave Embroidery
3656 ApplySpellFix({ 55637 }, [](SpellInfo* spellInfo)
3657 {
3658 spellInfo->Effects[EFFECT_1].MiscValue = 126;
3659 });
3660
3662 47977, // Magic Broom
3663 65917 // Magic Rooster
3664 }, [](SpellInfo* spellInfo)
3665 {
3666 // First two effects apply auras, which shouldn't be there
3667 // due to NO_TARGET applying aura on current caster (core bug)
3668 // Just wipe effect data, to mimic blizz-behavior
3669 spellInfo->Effects[EFFECT_0].Effect = 0;
3670 spellInfo->Effects[EFFECT_1].Effect = 0;
3671 });
3672
3673 // Titanium Seal of Dalaran, Toss your luck
3674 ApplySpellFix({ 60476 }, [](SpellInfo* spellInfo)
3675 {
3676 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
3677 });
3678
3679 // Mind Amplification Dish, change charm aura
3680 ApplySpellFix({ 26740 }, [](SpellInfo* spellInfo)
3681 {
3682 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_MOD_CHARM;
3683 });
3684
3685 // Deadly Swiftness
3686 ApplySpellFix({ 31255 }, [](SpellInfo* spellInfo)
3687 {
3688 spellInfo->Effects[EFFECT_0].TriggerSpell = 22588;
3689 });
3690
3691 // Black Magic enchant
3692 ApplySpellFix({ 59630 }, [](SpellInfo* spellInfo)
3693 {
3694 spellInfo->Attributes |= SPELL_ATTR0_PASSIVE;
3695 });
3696
3697 // Precious's Ribbon
3698 ApplySpellFix({ 72968 }, [](SpellInfo* spellInfo)
3699 {
3700 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
3701 });
3702
3704 71646, // Item - Bauble of True Blood 10m
3705 71607, // Item - Bauble of True Blood 25m
3706 71610, // Item - Althor's Abacus trigger 10m
3707 71641 // Item - Althor's Abacus trigger 25m
3708 }, [](SpellInfo* spellInfo)
3709 {
3710 spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
3711 spellInfo->SpellLevel = 0;
3712 });
3713
3715 6789, // Warlock - Death Coil (Rank 1)
3716 17925, // Warlock - Death Coil (Rank 2)
3717 17926, // Warlock - Death Coil (Rank 3)
3718 27223, // Warlock - Death Coil (Rank 4)
3719 47859, // Warlock - Death Coil (Rank 5)
3720 71838, // Drain Life - Bryntroll Normal
3721 71839 // Drain Life - Bryntroll Heroic
3722 }, [](SpellInfo* spellInfo)
3723 {
3724 spellInfo->AttributesEx2 |= SPELL_ATTR2_CANT_CRIT;
3725 });
3726
3727 // Alchemist's Stone
3728 ApplySpellFix({ 17619 }, [](SpellInfo* spellInfo)
3729 {
3730 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
3731 });
3732
3733 // Stormchops
3734 ApplySpellFix({ 43730 }, [](SpellInfo* spellInfo)
3735 {
3736 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(1);
3737 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
3738 });
3739
3740 // Savory Deviate Delight (transformations), allow to mount while transformed
3741 ApplySpellFix({ 8219, 8220, 8221, 8222 }, [](SpellInfo* spellInfo)
3742 {
3743 spellInfo->Attributes &= ~SPELL_ATTR0_NO_IMMUNITIES;
3744 });
3745
3746 // Clamlette Magnifique
3747 ApplySpellFix({ 72623 }, [](SpellInfo* spellInfo)
3748 {
3749 spellInfo->Effects[EFFECT_0].BasePoints = spellInfo->Effects[EFFECT_1].BasePoints;
3750 });
3751
3752 // Compact Harvest Reaper
3753 ApplySpellFix({ 4078 }, [](SpellInfo* spellInfo)
3754 {
3755 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(6); // 10 minutes
3756 });
3757
3758 // Dragon Kite, Tuskarr Kite - Kite String
3759 ApplySpellFix({ 45192 }, [](SpellInfo* spellInfo)
3760 {
3761 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100yd
3762 });
3763
3764 // Frigid Frostling, Infrigidate
3765 ApplySpellFix({ 74960 }, [](SpellInfo* spellInfo)
3766 {
3767 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd
3768 });
3769
3770 // Apple Trap
3771 ApplySpellFix({ 43450 }, [](SpellInfo* spellInfo)
3772 {
3773 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
3774 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
3775 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_DUMMY;
3776 });
3777
3778 // Dark Iron Attack - spawn mole machine
3779 ApplySpellFix({ 43563 }, [](SpellInfo* spellInfo)
3780 {
3781 spellInfo->Effects[EFFECT_2].Effect = 0; // summon GO's manually
3782 });
3783
3784 // Throw Mug visual
3785 ApplySpellFix({ 42300 }, [](SpellInfo* spellInfo)
3786 {
3787 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3788 });
3789
3790 // Dark Iron knockback Aura
3791 ApplySpellFix({ 42299 }, [](SpellInfo* spellInfo)
3792 {
3793 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_DUMMY;
3794 spellInfo->Effects[EFFECT_0].MiscValue = 100;
3795 spellInfo->Effects[EFFECT_0].BasePoints = 79;
3796 });
3797
3798 // Chug and Chuck!
3799 ApplySpellFix({ 42436 }, [](SpellInfo* spellInfo)
3800 {
3801 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
3802 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
3803 spellInfo->MaxAffectedTargets = 0;
3804 spellInfo->ExcludeCasterAuraSpell = 42299;
3805 });
3806
3807 // Brewfest quests
3808 ApplySpellFix({ 47134, 51798 }, [](SpellInfo* spellInfo)
3809 {
3810 spellInfo->Effects[EFFECT_0].Effect = 0;
3811 });
3812
3813 // The Heart of The Storms (12998)
3814 ApplySpellFix({ 43528 }, [](SpellInfo* spellInfo)
3815 {
3816 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(18);
3817 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
3818 });
3819
3820 // Water splash
3821 ApplySpellFix({ 42348 }, [](SpellInfo* spellInfo)
3822 {
3823 spellInfo->Effects[EFFECT_0].Effect = 0;
3824 });
3825
3826 // Summon Lantersn
3827 ApplySpellFix({ 44255, 44231 }, [](SpellInfo* spellInfo)
3828 {
3829 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
3830 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
3831 });
3832
3833 // Throw Head Back
3834 ApplySpellFix({ 42401 }, [](SpellInfo* spellInfo)
3835 {
3836 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_NEARBY_ENTRY);
3837 });
3838
3839 // Food
3840 ApplySpellFix({ 65418 }, [](SpellInfo* spellInfo)
3841 {
3842 spellInfo->Effects[EFFECT_2].TriggerSpell = 65410;
3843 });
3844
3845 ApplySpellFix({ 65422 }, [](SpellInfo* spellInfo)
3846 {
3847 spellInfo->Effects[EFFECT_2].TriggerSpell = 65414;
3848 });
3849
3850 ApplySpellFix({ 65419 }, [](SpellInfo* spellInfo)
3851 {
3852 spellInfo->Effects[EFFECT_2].TriggerSpell = 65416;
3853 });
3854
3855 ApplySpellFix({ 65420 }, [](SpellInfo* spellInfo)
3856 {
3857 spellInfo->Effects[EFFECT_2].TriggerSpell = 65412;
3858 });
3859
3860 ApplySpellFix({ 65421 }, [](SpellInfo* spellInfo)
3861 {
3862 spellInfo->Effects[EFFECT_2].TriggerSpell = 65415;
3863 });
3864
3865 // Stamp Out Bonfire
3866 ApplySpellFix({ 45437 }, [](SpellInfo* spellInfo)
3867 {
3868 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_DUMMY;
3869 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_NEARBY_ENTRY);
3870 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3871 });
3872
3873 // Light Bonfire (DND)
3874 ApplySpellFix({ 29831 }, [](SpellInfo* spellInfo)
3875 {
3876 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3877 });
3878
3879 // Infernal
3880 ApplySpellFix({ 33240 }, [](SpellInfo* spellInfo)
3881 {
3882 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3883 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3884 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3885 });
3886
3888 47476, // Deathknight - Strangulate
3889 15487, // Priest - Silence
3890 5211, // Druid - Bash - R1
3891 6798, // Druid - Bash - R2
3892 8983 // Druid - Bash - R3
3893 }, [](SpellInfo* spellInfo)
3894 {
3895 spellInfo->AttributesEx7 |= SPELL_ATTR7_CAN_CAUSE_INTERRUPT;
3896 });
3897
3898 // Shadowmeld
3899 ApplySpellFix({ 58984 }, [](SpellInfo* spellInfo)
3900 {
3901 spellInfo->AttributesEx3 |= SPELL_ATTR3_ONLY_ON_PLAYER;
3902 });
3903
3904 // Flare activation speed
3905 ApplySpellFix({ 1543 }, [](SpellInfo* spellInfo)
3906 {
3907 spellInfo->Speed = 0.0f;
3908 });
3909
3910 // Light's Beacon
3911 ApplySpellFix({ 53651 }, [](SpellInfo* spellInfo)
3912 {
3913 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
3914 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3915 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
3916 });
3917
3918 // Shadow Hunter Vosh'gajin - Hex
3919 ApplySpellFix({ 16097 }, [](SpellInfo* spellInfo)
3920 {
3921 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(16);
3922 });
3923
3924 // Sacred Cleansing
3925 ApplySpellFix({ 53659 }, [](SpellInfo* spellInfo)
3926 {
3927 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(5); // 40yd
3928 });
3929
3930 // Silithyst
3931 ApplySpellFix({ 29519 }, [](SpellInfo* spellInfo)
3932 {
3933 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_MOD_DECREASE_SPEED;
3934 spellInfo->Effects[EFFECT_0].BasePoints = -25;
3935 });
3936
3937 // Eye of Kilrogg Passive (DND)
3938 ApplySpellFix({ 2585 }, [](SpellInfo* spellInfo)
3939 {
3940 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE;
3941 });
3942
3943 // Nefarius Corruption
3944 ApplySpellFix({ 23642 }, [](SpellInfo* spellInfo)
3945 {
3946 spellInfo->MaxAffectedTargets = 1;
3947 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3948 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
3949 });
3950
3951 // Conflagration, Horseman's Cleave
3952 ApplySpellFix({ 42380, 42587 }, [](SpellInfo* spellInfo)
3953 {
3954 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
3955 });
3956
3957 // Serverside - Summon Arcane Disruptor
3958 ApplySpellFix({ 49591 }, [](SpellInfo* spellInfo)
3959 {
3960 spellInfo->ProcChance = 101;
3961 spellInfo->Effects[EFFECT_1].Effect = 24;
3962 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(25);
3963 spellInfo->Effects[EFFECT_1].ItemType = 37888;
3964 });
3965
3966 // Serverside - Create Rocket Pack
3967 ApplySpellFix({ 70055 }, [](SpellInfo* spellInfo)
3968 {
3969 spellInfo->ProcChance = 101;
3970 spellInfo->Effects[EFFECT_1].Effect = 24;
3971 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(25);
3972 spellInfo->Effects[EFFECT_1].ItemType = 49278;
3973 });
3974
3975 // Ashenvale Outrunner Sneak
3976 // Stealth
3977 ApplySpellFix({ 20540, 32199 }, [](SpellInfo* spellInfo)
3978 {
3979 spellInfo->AuraInterruptFlags |= (AURA_INTERRUPT_FLAG_MELEE_ATTACK | AURA_INTERRUPT_FLAG_CAST);
3980 });
3981
3982 // Arcane Bolt
3983 ApplySpellFix({ 15979 }, [](SpellInfo* spellInfo)
3984 {
3985 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(3); // 20y
3986 });
3987
3988 // Mortal Shots
3989 ApplySpellFix({ 19485, 19487, 19488, 19489, 19490 }, [](SpellInfo* spellInfo)
3990 {
3991 spellInfo->Effects[EFFECT_0].SpellClassMask[0] |= 0x00004000;
3992 spellInfo->Effects[EFFECT_1].Effect = 0;
3993 });
3994
3995 // Item - Death Knight T9 Melee 4P Bonus
3996 // Item - Hunter T9 2P Bonus
3997 // Item - Paladin T9 Retribution 2P Bonus (Righteous Vengeance)
3998 ApplySpellFix({ 67118, 67150, 67188 }, [](SpellInfo* spellInfo)
3999 {
4000 spellInfo->Effects[EFFECT_1].Effect = 0;
4001 });
4002
4003 // Green Beam
4004 ApplySpellFix({31628, 31630, 31631}, [](SpellInfo* spellInfo)
4005 {
4006 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
4007 spellInfo->MaxAffectedTargets = 1;
4008 });
4009
4011 20271, 57774, // Judgement of Light
4012 20425, // Judgement of Command
4013 32220, // Judgement of Blood
4014 53407, // Judgement of Justice
4015 53408, // Judgement of Wisdom
4016 53725 // Judgement of the Martyr
4017 }, [](SpellInfo* spellInfo)
4018 {
4019 spellInfo->AttributesEx3 &= ~SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
4020 });
4021
4022 // Chaos Bolt Passive
4023 ApplySpellFix({ 58284 }, [](SpellInfo* spellInfo)
4024 {
4025 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
4026 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST;
4027 spellInfo->Effects[EFFECT_1].BasePoints = 100;
4028 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
4029 spellInfo->Effects[EFFECT_1].MiscValue = 127;
4030 spellInfo->Effects[EFFECT_1].SpellClassMask[1] = 0x00020000;
4031 });
4032
4033 // Nefarian: Shadowbolt, Shadow Command
4034 ApplySpellFix({ 22667, 22677 }, [](SpellInfo* spellInfo)
4035 {
4036 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(152); // 150 yards
4037 });
4038
4039 // Manastorm
4040 ApplySpellFix({ 21097 }, [](SpellInfo* spellInfo)
4041 {
4042 spellInfo->InterruptFlags &= ~SPELL_INTERRUPT_FLAG_INTERRUPT;
4043 });
4044
4045 // Arcane Vacuum
4046 ApplySpellFix({ 21147 }, [](SpellInfo* spellInfo)
4047 {
4048 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(4); // 30 yards
4049 spellInfo->AttributesEx3 |= SPELL_ATTR3_ONLY_ON_PLAYER;
4050 });
4051
4052 // Reflection
4053 ApplySpellFix({ 22067 }, [](SpellInfo* spellInfo)
4054 {
4055 spellInfo->Dispel = DISPEL_NONE;
4056 });
4057
4058 // Focused Assault
4059 // Brutal Assault
4060 ApplySpellFix({ 46392, 46393 }, [](SpellInfo* spellInfo)
4061 {
4062 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
4063 });
4064
4065 // Improved Blessing Protection (Nefarian Class Call)
4066 ApplySpellFix({ 23415 }, [](SpellInfo* spellInfo)
4067 {
4068 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ENEMY);
4069 });
4070
4071 // Bestial Wrath
4072 ApplySpellFix({ 19574 }, [](SpellInfo* spellInfo)
4073 {
4074 spellInfo->AttributesEx4 |= SPELL_ATTR4_AURA_EXPIRES_OFFLINE;
4075 });
4076
4077 // Shadowflame
4078 ApplySpellFix({ 22539 }, [](SpellInfo* spellInfo)
4079 {
4080 spellInfo->InterruptFlags &= ~SPELL_INTERRUPT_FLAG_INTERRUPT;
4081 });
4082
4083 // PX-238 Winter Wondervolt
4084 ApplySpellFix({ 26157, 26272, 26273, 26274 }, [](SpellInfo* spellInfo)
4085 {
4086 spellInfo->Mechanic = 0;
4087 });
4088
4089 // Calm Dragonkin
4090 ApplySpellFix({ 19872 }, [](SpellInfo* spellInfo)
4091 {
4092 spellInfo->AttributesEx |= SPELL_ATTR1_EXCLUDE_CASTER;
4093 });
4094
4095 // Cosmetic - Lightning Beam Channel
4096 ApplySpellFix({ 45537 }, [](SpellInfo* spellInfo)
4097 {
4098 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4099 });
4100
4101 // Burning Adrenaline
4102 ApplySpellFix({ 23478 }, [](SpellInfo* spellInfo)
4103 {
4104 spellInfo->Effects[EFFECT_0].BasePoints = 4374;
4105 spellInfo->Effects[EFFECT_0].DieSides = 1250;
4106 });
4107
4108 // Explosion - Razorgore
4109 ApplySpellFix({ 20038 }, [](SpellInfo* spellInfo)
4110 {
4111 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS);
4112 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
4113 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4114 });
4115
4116 // Brood Power : Bronze
4117 ApplySpellFix({ 22311 }, [](SpellInfo* spellInfo)
4118 {
4119 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
4120 });
4121
4122 // Rapture
4123 ApplySpellFix({ 63652, 63653, 63654, 63655 }, [](SpellInfo* spellInfo)
4124 {
4125 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
4126 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4127 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
4128 });
4129
4130 // Everlasting Affliction
4131 ApplySpellFix({ 47422 }, [](SpellInfo* spellInfo)
4132 {
4133 spellInfo->SchoolMask = SPELL_SCHOOL_MASK_SHADOW;
4134 });
4135
4136 // Flametongue Weapon (Passive) (Rank 6)
4137 ApplySpellFix({ 16312 }, [](SpellInfo* spellInfo)
4138 {
4139 spellInfo->Attributes |= SPELL_ATTR0_PASSIVE;
4140 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21);
4141 });
4142
4143 // Mana Tide Totem
4144 // Cleansing Totem Effect
4145 ApplySpellFix({ 39609, 52025 }, [](SpellInfo* spellInfo)
4146 {
4147 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(5); // 40yd
4148 });
4149
4150 // Increased Totem Radius
4151 ApplySpellFix({ 21895 }, [](SpellInfo* spellInfo)
4152 {
4153 spellInfo->Effects[0].SpellClassMask = flag96(0x0603E000, 0x00200100);
4154 });
4155
4156 // Jokkum Summon
4157 ApplySpellFix({ 56541 }, [](SpellInfo* spellInfo)
4158 {
4159 spellInfo->Effects[EFFECT_0].MiscValueB = 844;
4160 });
4161
4162 // Hakkar Cause Insanity
4163 ApplySpellFix({ 24327 }, [](SpellInfo* spellInfo)
4164 {
4165 spellInfo->Dispel = DISPEL_NONE;
4166 });
4167
4168 // Summon Nightmare Illusions
4169 ApplySpellFix({ 24681, 24728, 24729 }, [](SpellInfo* spellInfo)
4170 {
4171 spellInfo->Effects[EFFECT_0].MiscValueB = 64;
4172 });
4173
4174 // Blood Siphon
4175 ApplySpellFix({ 24322, 24323 }, [](SpellInfo* spellInfo)
4176 {
4177 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_MOD_STUN;
4178 spellInfo->Effects[EFFECT_2].Effect = 0;
4179 spellInfo->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
4180 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL;
4181 spellInfo->ChannelInterruptFlags &= ~AURA_INTERRUPT_FLAG_MOVE;
4182 });
4183
4184 // Place Fake Fur
4185 ApplySpellFix({ 46085 }, [](SpellInfo* spellInfo)
4186 {
4187 spellInfo->Effects[EFFECT_0].MiscValue = 8;
4188 });
4189
4190 // Smash Mammoth Trap
4191 ApplySpellFix({ 46201 }, [](SpellInfo* spellInfo)
4192 {
4193 spellInfo->Effects[EFFECT_0].MiscValue = 8;
4194 });
4195
4196 // Elemental Mastery
4197 ApplySpellFix({ 16166 }, [](SpellInfo* spellInfo)
4198 {
4199 spellInfo->Effects[EFFECT_0].SpellClassMask = flag96(0x00000003, 0x00001000);
4200 });
4201
4202 // Elemental Vulnerability
4203 ApplySpellFix({ 28772 }, [](SpellInfo* spellInfo)
4204 {
4205 spellInfo->Speed = 1;
4206 });
4207
4208 // Find the Ancient Hero: Kill Credit
4209 ApplySpellFix({ 25729 }, [](SpellInfo* spellInfo)
4210 {
4211 spellInfo->Effects[EFFECT_0].TargetA = TARGET_UNIT_SUMMONER;
4212 });
4213
4214 // Artorius Demonic Doom
4215 ApplySpellFix({ 23298 }, [](SpellInfo* spellInfo)
4216 {
4217 spellInfo->AttributesEx4 |= SPELL_ATTR4_IGNORE_DAMAGE_TAKEN_MODIFIERS;
4218 spellInfo->AttributesEx6 |= SPELL_ATTR6_IGNORE_CASTER_DAMAGE_MODIFIERS;
4219 });
4220
4221 // Lash
4222 ApplySpellFix({ 25852 }, [](SpellInfo* spellInfo)
4223 {
4224 spellInfo->Effects[EFFECT_1].Effect = 0;
4225 });
4226
4227 // Explosion
4228 ApplySpellFix({ 5255 }, [](SpellInfo* spellInfo)
4229 {
4230 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4231 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
4232 });
4233
4234 // Death's Respite
4235 ApplySpellFix({ 67731, 68305 }, [](SpellInfo* spellInfo)
4236 {
4237 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
4238 });
4239
4240 // Wyvern Sting DoT
4241 ApplySpellFix({ 24131, 24134, 24135 }, [](SpellInfo* spellInfo)
4242 {
4243 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
4244 });
4245
4246 // Feed Pet
4247 ApplySpellFix({ 1539, 51284 }, [](SpellInfo* spellInfo)
4248 {
4249 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_WHILE_SITTING;
4250 });
4251
4252 // Judgement (Paladin T2 8P Bonus)
4253 // Battlegear of Eternal Justice
4254 ApplySpellFix({ 23591, 26135 }, [](SpellInfo* spellInfo)
4255 {
4256 spellInfo->ProcFlags = PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS;
4257 });
4258
4259 // Gift of Arthas
4260 ApplySpellFix({ 11371 }, [](SpellInfo* spellInfo)
4261 {
4262 spellInfo->SpellFamilyName = SPELLFAMILY_POTION;
4263 });
4264
4265 // Refocus (Renataki's charm of beasts)
4266 ApplySpellFix({ 24531 }, [](SpellInfo* spellInfo)
4267 {
4268 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
4269 });
4270
4271 // Collect Rookery Egg
4272 ApplySpellFix({ 15958 }, [](SpellInfo* spellInfo)
4273 {
4274 spellInfo->Effects[EFFECT_1].Effect = 0;
4275 });
4276
4277 // WotLK Prologue Frozen Shade Visual, temp used to restore visual after Dispersion
4278 ApplySpellFix({ 53444 }, [](SpellInfo* spellInfo)
4279 {
4280 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(27);
4281 });
4282
4283 // Rental Racing Ram
4284 ApplySpellFix({ 43883 }, [](SpellInfo* spellInfo)
4285 {
4286 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_NOT_ABOVEWATER;
4287 });
4288
4289 // Summon Worm
4290 ApplySpellFix({ 518, 25831, 25832 }, [](SpellInfo* spellInfo)
4291 {
4292 spellInfo->Effects[EFFECT_0].MiscValueB = 64;
4293 });
4294
4295 // Uppercut
4296 ApplySpellFix({ 26007 }, [](SpellInfo* spellInfo)
4297 {
4298 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
4299 });
4300
4301 // Digestive Acid (Temporary)
4302 ApplySpellFix({ 26476 }, [](SpellInfo* spellInfo)
4303 {
4304 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
4305 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4306 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
4307 });
4308
4309 // Drums of War/Battle/Speed/Restoration
4310 ApplySpellFix({ 35475, 35476, 35477, 35478 }, [](SpellInfo* spellInfo)
4311 {
4312 spellInfo->ExcludeTargetAuraSpell = 51120;
4313 });
4314
4315 // Slap!
4316 ApplySpellFix({ 6754 }, [](SpellInfo* spellInfo)
4317 {
4318 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
4319 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
4320 });
4321
4322 // Summon Cauldron Stuff
4323 ApplySpellFix({ 36549 }, [](SpellInfo* spellInfo)
4324 {
4325 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(28); // 5 seconds
4326 spellInfo->Effects[EFFECT_0].TargetB = TARGET_DEST_CASTER;
4327 });
4328
4329 // Hunter's Mark
4330 ApplySpellFix({ 31615 }, [](SpellInfo* spellInfo)
4331 {
4332 for (uint8 index = EFFECT_0; index <= EFFECT_1; ++index)
4333 {
4334 spellInfo->Effects[index].TargetA = TARGET_UNIT_TARGET_ENEMY;
4335 spellInfo->Effects[index].TargetB = 0;
4336 }
4337 });
4338
4339 // Self Visual - Sleep Until Cancelled(DND)
4340 ApplySpellFix({ 6606, 14915, 16093 }, [](SpellInfo* spellInfo)
4341 {
4342 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_NOT_SEATED;
4343 });
4344
4345 // Cleansing Totem, Healing Stream Totem, Mana Tide Totem
4346 ApplySpellFix({ 8171,52025, 52041, 52042, 52046, 52047, 52048, 52049, 52050, 58759, 58760, 58761, 39610, 39609 }, [](SpellInfo* spellInfo)
4347 {
4348 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4349 });
4350 // Game In Session
4351 ApplySpellFix({ 39331 }, [](SpellInfo* spellInfo)
4352 {
4353 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AURA;
4354 spellInfo->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
4355 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
4356 });
4357 // Death Ray Warning Visual, Death Ray Damage Visual
4358 ApplySpellFix({ 63882, 63886 }, [](SpellInfo* spellInfo)
4359 {
4360 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL;
4361 });
4362
4363 // Buffeting Winds of Susurrus
4364 ApplySpellFix({ 32474 }, [](SpellInfo* spellInfo)
4365 {
4366 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(556); // 28 seconds
4367 });
4368
4369 // Quest - Healing Salve
4370 ApplySpellFix({ 29314 }, [](SpellInfo* spellInfo)
4371 {
4372 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(1); // 0s
4373 });
4374
4375 // Seed of Corruption
4376 ApplySpellFix({ 27285, 47833, 47834 }, [](SpellInfo* spellInfo)
4377 {
4378 spellInfo->AttributesEx |= SPELL_ATTR1_NO_REFLECTION;
4379 });
4380
4381 // Turn the Tables
4382 ApplySpellFix({ 51627, 51628, 51629 }, [](SpellInfo* spellInfo)
4383 {
4384 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
4385 });
4386
4387 // Silence
4388 ApplySpellFix({ 18278 }, [](SpellInfo* spellInfo)
4389 {
4390 spellInfo->AttributesEx4 |= SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND;
4391 });
4392
4393 // Honor Among Thieves - allow area aura from different casters to coexist
4394 ApplySpellFix({ 51698, 51700, 51701 }, [](SpellInfo* spellInfo)
4395 {
4396 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
4397 });
4398
4399 // Absorb Life
4400 ApplySpellFix({ 34239 }, [](SpellInfo* spellInfo)
4401 {
4402 spellInfo->Effects[EFFECT_0].ValueMultiplier = 1;
4403 });
4404
4405 // Summon a Warp Rift in Void Ridge
4406 ApplySpellFix({ 35036 }, [](SpellInfo* spellInfo)
4407 {
4408 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(1); // 0s
4409 });
4410
4411 // Hit Rating (Dungeon T3 - 2P Bonus - Wastewalker, Doomplate)
4412 ApplySpellFix({ 37608, 37610 }, [](SpellInfo* spellInfo)
4413 {
4414 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(0);
4415 spellInfo->Effects[EFFECT_0].MiscValue = 224;
4416 });
4417
4418 // Target Fissures
4419 ApplySpellFix({ 30745 }, [](SpellInfo* spellInfo)
4420 {
4421 spellInfo->MaxAffectedTargets = 1;
4422 });
4423
4424 // Acid Spit
4425 ApplySpellFix({ 34290 }, [](SpellInfo* spellInfo)
4426 {
4427 spellInfo->MaxAffectedTargets = 1;
4428 });
4429
4430 // Mulgore Hatchling (periodic)
4431 ApplySpellFix({ 62586 }, [](SpellInfo* spellInfo)
4432 {
4433 spellInfo->Effects[EFFECT_0].TriggerSpell = 62585; // Mulgore Hatchling (fear)
4434 });
4435
4436 // Poultryized!
4437 ApplySpellFix({ 30504 }, [](SpellInfo* spellInfo)
4438 {
4439 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_TAKE_DAMAGE;
4440 });
4441
4442 // Torment of the Worgen
4443 ApplySpellFix({ 30567 }, [](SpellInfo* spellInfo)
4444 {
4445 spellInfo->ProcChance = 3;
4446 });
4447
4448 // Summon Water Elementals
4449 ApplySpellFix({ 29962, 37051, 37052, 37053 }, [](SpellInfo* spellInfo)
4450 {
4451 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
4452 });
4453
4454 // Instill Lord Valthalak's Spirit DND
4455 ApplySpellFix({ 27360 }, [](SpellInfo* spellInfo)
4456 {
4457 spellInfo->ChannelInterruptFlags |= AURA_INTERRUPT_FLAG_MOVE;
4458 });
4459
4460 // Holiday - Midsummer, Ribbon Pole Periodic Visual
4461 ApplySpellFix({ 45406 }, [](SpellInfo* spellInfo)
4462 {
4463 spellInfo->AuraInterruptFlags |= ( AURA_INTERRUPT_FLAG_MOUNT | AURA_INTERRUPT_FLAG_CAST | AURA_INTERRUPT_FLAG_TALK );
4464 });
4465
4466 // Improved Mind Flay and Smite
4467 ApplySpellFix({ 37571 }, [](SpellInfo* spellInfo)
4468 {
4469 spellInfo->Effects[EFFECT_0].SpellClassMask[0] = 8388736;
4470 });
4471
4472 // Improved Corruption and Immolate (Updated)
4473 ApplySpellFix({ 61992 }, [](SpellInfo* spellInfo)
4474 {
4475 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
4476 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_ADD_PCT_MODIFIER;
4477 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
4478 spellInfo->Effects[EFFECT_1].BasePoints = 4;
4479 spellInfo->Effects[EFFECT_1].DieSides = 1;
4480 spellInfo->Effects[EFFECT_1].MiscValue = 22;
4481 spellInfo->Effects[EFFECT_1].SpellClassMask[0] = 6;
4482 });
4483
4484 // 46747 Fling torch
4485 ApplySpellFix({ 46747 }, [](SpellInfo* spellInfo)
4486 {
4487 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
4488 });
4489
4490 // Chains of Naberius
4491 ApplySpellFix({ 36146 }, [](SpellInfo* spellInfo)
4492 {
4493 spellInfo->MaxAffectedTargets = 1;
4494 });
4495
4496 // Force of Neltharaku
4497 ApplySpellFix({ 38762 }, [](SpellInfo* spellInfo)
4498 {
4499 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
4500 });
4501
4502 // Spotlight
4503 ApplySpellFix({ 29683, 32214 }, [](SpellInfo* spellInfo)
4504 {
4505 spellInfo->AttributesEx5 |= SPELL_ATTR5_DO_NOT_DISPLAY_DURATION;
4506 });
4507
4508 // Haunted
4509 ApplySpellFix({ 53768 }, [](SpellInfo* spellInfo)
4510 {
4511 spellInfo->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
4512 });
4513
4514 // Tidal Wave
4515 ApplySpellFix({ 37730 }, [](SpellInfo* spellInfo)
4516 {
4517 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4518 });
4519
4520 // Commanding Shout
4521 ApplySpellFix({ 469, 47439, 47440 }, [](SpellInfo* spellInfo)
4522 {
4523 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4524 });
4525
4526 // Battle Shout
4527 ApplySpellFix({ 2048, 5242, 6192, 6673, 11549, 11550, 11551, 25289, 47436 }, [](SpellInfo* spellInfo)
4528 {
4529 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4530 });
4531
4532 // Plague Effect
4533 ApplySpellFix({ 19594, 26557 }, [](SpellInfo* spellInfo)
4534 {
4535 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4536 });
4537
4538 // Prayer of Fortitude
4539 ApplySpellFix({ 21562, 21564, 25392, 48162 }, [](SpellInfo* spellInfo)
4540 {
4541 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4542 });
4543
4544 // Gift of the Wild
4545 ApplySpellFix({ 21849, 21850, 26991, 48470, 69381 }, [](SpellInfo* spellInfo)
4546 {
4547 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4548 });
4549
4550 // Arcane Brilliance
4551 ApplySpellFix({ 23028, 27127, 43002 }, [](SpellInfo* spellInfo)
4552 {
4553 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4554 });
4555
4556 // Prayer of Spirit
4557 ApplySpellFix({ 27681, 32999, 48074 }, [](SpellInfo* spellInfo)
4558 {
4559 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4560 });
4561
4562 // Prayer of Shadow Protection
4563 ApplySpellFix({ 27683, 39374, 48170 }, [](SpellInfo* spellInfo)
4564 {
4565 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4566 });
4567
4568 // Nagrand Fort Buff Reward Raid
4569 ApplySpellFix({ 33006 }, [](SpellInfo* spellInfo)
4570 {
4571 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4572 });
4573
4574 // Ancestral Awakening
4575 ApplySpellFix({ 52759 }, [](SpellInfo* spellInfo)
4576 {
4577 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4578 });
4579
4580 // Turn the Tables
4581 ApplySpellFix({ 52910, 52914, 52915 }, [](SpellInfo* spellInfo)
4582 {
4583 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4584 });
4585
4586 // Judgements of the Wise
4587 ApplySpellFix({ 54180 }, [](SpellInfo* spellInfo)
4588 {
4589 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4590 });
4591
4592 // Replenishment
4593 ApplySpellFix({ 57669 }, [](SpellInfo* spellInfo)
4594 {
4595 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4596 });
4597
4598 // Dalaran Brilliance
4599 ApplySpellFix({ 61316 }, [](SpellInfo* spellInfo)
4600 {
4601 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4602 });
4603
4604 // [DND] Dalaran Brilliance
4605 ApplySpellFix({ 61332 }, [](SpellInfo* spellInfo)
4606 {
4607 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4608 });
4609
4610 // Infinite Replenishment + Wisdom
4611 ApplySpellFix({ 61782 }, [](SpellInfo* spellInfo)
4612 {
4613 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4614 });
4615
4616 // Renewed Hope
4617 ApplySpellFix({ 63944 }, [](SpellInfo* spellInfo)
4618 {
4619 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4620 });
4621
4622 // Fortitude
4623 ApplySpellFix({ 69377 }, [](SpellInfo* spellInfo)
4624 {
4625 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4626 });
4627
4628 // Blessing of Forgotten Kings
4629 ApplySpellFix({ 69378 }, [](SpellInfo* spellInfo)
4630 {
4631 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4632 });
4633
4634 // Lucky Charm
4635 ApplySpellFix({ 69511 }, [](SpellInfo* spellInfo)
4636 {
4637 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4638 });
4639
4640 // Shiny Shard of the Scale Heal Targeter
4641 ApplySpellFix({ 69749 }, [](SpellInfo* spellInfo)
4642 {
4643 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4644 });
4645
4646 // Purified Shard of the Scale Heal Targeter
4647 ApplySpellFix({ 69754 }, [](SpellInfo* spellInfo)
4648 {
4649 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4650 });
4651
4652 // Brilliance
4653 ApplySpellFix({ 69994 }, [](SpellInfo* spellInfo)
4654 {
4655 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4656 });
4657
4658 // Domination
4659 ApplySpellFix({ 37135 }, [](SpellInfo* spellInfo)
4660 {
4661 spellInfo->MaxAffectedTargets = 5;
4662 });
4663
4664 // Presence Of Mind
4665 ApplySpellFix({ 12043 }, [](SpellInfo* spellInfo)
4666 {
4667 // It should not share cooldown mods with category[1151] spells (Arcane Power [12042], Decimate [47271])
4668 spellInfo->AttributesEx6 |= SPELL_ATTR6_NO_CATEGORY_COOLDOWN_MODS;
4669 });
4670
4671 // Eye of Grillok
4672 ApplySpellFix({ 38495 }, [](SpellInfo* spellInfo)
4673 {
4674 spellInfo->Effects[EFFECT_0].TriggerSpell = 38530; // Quest Credit for Eye of Grillok
4675 });
4676
4677 // Greater Fireball
4678 ApplySpellFix({ 33051 }, [](SpellInfo* spellInfo)
4679 {
4680 spellInfo->AttributesEx4 |= SPELL_ATTR4_NO_CAST_LOG;
4681 });
4682
4683 // Gor'drek's Ointment
4684 ApplySpellFix({ 32578 }, [](SpellInfo* spellInfo)
4685 {
4686 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
4687 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
4688 });
4689
4690 // Shadow Grasp
4691 ApplySpellFix({ 30410 }, [](SpellInfo* spellInfo)
4692 {
4693 spellInfo->AttributesEx6 |= SPELL_ATTR6_NO_PUSHBACK;
4694 });
4695
4697 471, // Palamino
4698 8980, // Skeletal Horse
4699 10788, // Leopard
4700 10790, // Tiger
4701 10792, // Spotted Panther
4702 60136, // Grand Caravan Mammoth
4703 60140 // Grand Caravan Mammoth
4704 }, [](SpellInfo* spellInfo)
4705 {
4706 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_NOT_ABOVEWATER;
4707 });
4708
4709 // Molten Punch
4710 ApplySpellFix({ 40126 }, [](SpellInfo* spellInfo)
4711 {
4712 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
4713 });
4714
4715 // Wing Buffet
4716 ApplySpellFix({ 37319 }, [](SpellInfo* spellInfo)
4717 {
4718 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CONE_ENEMY_24);
4719 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(0);
4720 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS);
4721 });
4722
4723 // Flame Wave
4724 ApplySpellFix({ 33800 }, [](SpellInfo* spellInfo)
4725 {
4726 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
4727 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_PERIODIC_TRIGGER_SPELL;
4728 spellInfo->Effects[EFFECT_1].Amplitude = 500;
4729 });
4730
4731 // Chromatic Resistance Aura
4732 ApplySpellFix({ 41453 }, [](SpellInfo* spellInfo)
4733 {
4734 spellInfo->Effects[EFFECT_0].MiscValue = 124;
4735 });
4736
4737 // Power of the Guardian
4738 ApplySpellFix({ 28142, 28143, 28144, 28145 }, [](SpellInfo* spellInfo)
4739 {
4740 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
4741 });
4742
4743 // Warrior stances passives
4745 2457, // Battle Stance
4746 2458, // Berserker Stance
4747 7376 // Defensive Stance Passive
4748 }, [](SpellInfo* spellInfo)
4749 {
4750 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
4751 });
4752
4753 // Conjure Refreshment Table (Rank 1, Rank 2)
4754 ApplySpellFix({ 43985, 58661 }, [](SpellInfo* spellInfo)
4755 {
4756 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER_FRONT);
4757 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_5_YARDS);
4758 });
4759
4761 698, // Ritual of Summoning (portal for clicking)
4762 61993 // Ritual of Summoning (summons the closet)
4763 }, [](SpellInfo* spellInfo)
4764 {
4765 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS);
4766 });
4767
4768 // Paralyze
4769 ApplySpellFix({ 41083 }, [](SpellInfo* spellInfo)
4770 {
4771 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL;
4772 });
4773
4774 // Fatal Attraction
4775 ApplySpellFix({ 40869 }, [](SpellInfo* spellInfo)
4776 {
4777 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_DEST_CASTER); // target set by script
4778 });
4779
4780 // Fatal Attraction
4781 ApplySpellFix({ 40870 }, [](SpellInfo* spellInfo)
4782 {
4783 spellInfo->MaxAffectedTargets = 1;
4784 });
4785
4786 // Removing Dragonflayer Harpoon
4787 ApplySpellFix({ 42968 }, [](SpellInfo* spellInfo)
4788 {
4789 spellInfo->MaxAffectedTargets = 1;
4790 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(7);
4791 });
4792
4793 // Siphon Life (heal)
4794 ApplySpellFix({ 63106 }, [](SpellInfo* spellInfo)
4795 {
4796 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
4797 });
4798
4799 // Fury
4800 ApplySpellFix({ 40601 }, [](SpellInfo* spellInfo)
4801 {
4802 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
4803 });
4804
4805 // Claw Rage
4806 ApplySpellFix({ 43149 }, [](SpellInfo* spellInfo)
4807 {
4808 spellInfo->Effects[EFFECT_0].TriggerSpell = 0;
4809 });
4810
4811 // Black Qiraji Battle Tank
4812 ApplySpellFix({ 26655, 26656 }, [](SpellInfo* spellInfo)
4813 {
4814 spellInfo->AuraInterruptFlags &= ~(AURA_INTERRUPT_FLAG_CHANGE_MAP | AURA_INTERRUPT_FLAG_TELEPORTED);
4815 });
4816
4817 // Summon Cyclone
4818 ApplySpellFix({ 43112 }, [](SpellInfo* spellInfo)
4819 {
4820 spellInfo->RequiresSpellFocus = 0;
4821 });
4822
4823 // Booming Voice
4824 ApplySpellFix({ 40080 }, [](SpellInfo* spellInfo)
4825 {
4826 spellInfo->Effects[EFFECT_0].RealPointsPerLevel = 0;
4827 });
4828
4829 // Mangle (Nalorakk)
4830 ApplySpellFix({ 42389 }, [](SpellInfo* spellInfo)
4831 {
4832 spellInfo->SchoolMask = SPELL_SCHOOL_MASK_NATURE;
4833 });
4834
4835 // Event food, fixes to give correct stamina and spirit of 25% of the character level
4836 ApplySpellFix({ 24870 }, [](SpellInfo* spellInfo)
4837 {
4838 spellInfo->Effects[EFFECT_1].BasePoints = 0;
4839 spellInfo->Effects[EFFECT_0].RealPointsPerLevel = 0.25;
4840 spellInfo->Effects[EFFECT_1].RealPointsPerLevel = 0.25;
4841 });
4842
4843 // Smash
4844 // Dark Smash
4845 ApplySpellFix({ 42669, 59706, 42723, 59709 }, [](SpellInfo* spellInfo)
4846 {
4847 spellInfo->AttributesEx2 &= ~SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4848 });
4849
4850 // Swoop (Moth hunter pet) root effect fix
4851 ApplySpellFix({ 52825 }, [](SpellInfo* spellInfo)
4852 {
4853 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
4854 });
4855
4856 // Felmyst Strafe (Top)
4857 ApplySpellFix({ 45585 }, [](SpellInfo* spellInfo)
4858 {
4859 spellInfo->MaxAffectedTargets = 3;
4860 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_70_YARDS);
4861 });
4862
4863 // Felmyst Strafe (Middle, Bottom)
4864 ApplySpellFix({ 45633, 45635 }, [](SpellInfo* spellInfo)
4865 {
4866 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_70_YARDS);
4867 });
4868
4870 45662, // Encapsulate
4871 45642 // Fire Bloom
4872 }, [](SpellInfo* spellInfo)
4873 {
4874 spellInfo->AttributesEx7 |= SPELL_ATTR7_TREAT_AS_NPC_AOE;
4875 });
4876
4877 // Torch (Death Knights near the Chapel)
4878 ApplySpellFix({ 52953 }, [](SpellInfo* spellInfo)
4879 {
4880 spellInfo->MaxAffectedTargets = 1;
4881 });
4882
4883 // Missile Barrage
4884 ApplySpellFix({ 44401 }, [](SpellInfo* spellInfo)
4885 {
4886 spellInfo->ProcCharges = 1;
4887 spellInfo->SpellPriority = 100;
4888 });
4889
4890 // Item - Mage T8 4P Bonus
4891 ApplySpellFix({ 64869 }, [](SpellInfo* spellInfo)
4892 {
4893 // DBC amount is 10, but the chance to not consume Missile Barrage,
4894 // Hot Streak or Brain Freeze is 20% according to the available sources
4895 spellInfo->Effects[EFFECT_0].BasePoints = 20;
4896 spellInfo->Effects[EFFECT_0].DieSides = 0;
4897 });
4898
4899 // Auto Shot
4900 ApplySpellFix({ 75 }, [](SpellInfo* spellInfo)
4901 {
4902 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(1); // 0s
4903 spellInfo->InterruptFlags &= ~SPELL_INTERRUPT_UNK;
4904 });
4905
4906 // Life Tap
4907 ApplySpellFix({ 1454 }, [](SpellInfo* spellInfo)
4908 {
4909 spellInfo->Effects[EFFECT_0].RealPointsPerLevel = 0.0f;
4910 });
4911
4912 // Life Tap
4913 ApplySpellFix({ 1455, 1456, 11687, 11688, 11689, 27222, 57946 }, [](SpellInfo* spellInfo)
4914 {
4915 spellInfo->Effects[EFFECT_0].RealPointsPerLevel = 0.0f;
4916 spellInfo->MaxLevel = 16;
4917 spellInfo->BaseLevel = 6;
4918 spellInfo->SpellLevel = 6;
4919 });
4920
4921 // Explosive Sheep
4922 ApplySpellFix({ 4074 }, [](SpellInfo* spellInfo)
4923 {
4924 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(25);
4925 });
4926
4927 // Phase Shift
4928 ApplySpellFix({ 4511 }, [](SpellInfo* spellInfo)
4929 {
4930 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_MELEE_ATTACK;
4931 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CAST;
4932 });
4933
4934 // Charge Stun
4935 ApplySpellFix({ 7922 }, [](SpellInfo* spellInfo)
4936 {
4937 spellInfo->Attributes |= SPELL_ATTR0_NO_ACTIVE_DEFENSE;
4938 });
4939
4940 // Tharnariun's Heal
4941 ApplySpellFix({ 9457 }, [](SpellInfo* spellInfo)
4942 {
4943 spellInfo->AttributesEx2 &= ~SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4944 spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_AND_TARGET_RESTRICTIONS;
4945 spellInfo->Effects[EFFECT_0].DieSides = 0;
4946 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
4947 });
4948
4949 // Supercharge
4950 ApplySpellFix({ 10732 }, [](SpellInfo* spellInfo)
4951 {
4952 spellInfo->CategoryEntry = sSpellCategoryStore.LookupEntry(0);
4953 spellInfo->Attributes &= ~(SPELL_ATTR0_IS_ABILITY | SPELL_ATTR0_DO_NOT_SHEATH);
4954 spellInfo->Attributes |= SPELL_ATTR0_NOT_SHAPESHIFTED;
4955 spellInfo->AttributesEx |= SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL;
4956 spellInfo->AttributesEx2 |= SPELL_ATTR2_NO_TARGET_PER_SECOND_COST;
4957 spellInfo->AttributesEx3 |= SPELL_ATTR3_CAN_PROC_FROM_PROCS;
4958 spellInfo->FacingCasterFlags |= SPELL_FACING_FLAG_INFRONT;
4959 spellInfo->InterruptFlags |= (SPELL_INTERRUPT_FLAG_MOVEMENT | SPELL_INTERRUPT_FLAG_PUSH_BACK |
4961 spellInfo->ChannelInterruptFlags &= ~AURA_INTERRUPT_FLAG_JUMP;
4962 spellInfo->ChannelInterruptFlags |= AURA_INTERRUPT_FLAG_UNK14;
4963 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ALLY);
4964 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ALLY);
4965 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ALLY);
4966 spellInfo->Effects[EFFECT_0].Amplitude = 3000;
4967 spellInfo->Effects[EFFECT_1].Amplitude = 3000;
4968 spellInfo->Effects[EFFECT_2].Amplitude = 3000;
4969 spellInfo->SpellVisual[0] = 12656;
4970 });
4971
4972 // Intercept
4973 ApplySpellFix({ 20252 }, [](SpellInfo* spellInfo)
4974 {
4976 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_ITEM_SPELL_IN_PVP;
4977 });
4978
4979 // Intercept
4980 ApplySpellFix({ 20253 }, [](SpellInfo* spellInfo)
4981 {
4983 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_ITEM_SPELL_IN_PVP;
4984 spellInfo->AttributesEx7 |= (SPELL_ATTR7_NO_ATTACK_DODGE | SPELL_ATTR7_NO_ATTACK_PARRY);
4985 spellInfo->SpellLevel = 0;
4986 });
4987
4988 // Heart of the Crusader
4989 ApplySpellFix({ 20335, 20336, 20337 }, [](SpellInfo* spellInfo)
4990 {
4991 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
4992 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
4993 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_DUMMY;
4994 });
4995
4996 // Heart of the Crusader (Rank 1)
4997 ApplySpellFix({ 20335 }, [](SpellInfo* spellInfo)
4998 {
4999 spellInfo->Effects[EFFECT_1].TriggerSpell = 21183; // Heart of the Crusader (Rank 1)
5000 });
5001
5002 // Heart of the Crusader (Rank 2)
5003 ApplySpellFix({ 20336 }, [](SpellInfo* spellInfo)
5004 {
5005 spellInfo->Effects[EFFECT_1].TriggerSpell = 54498; // Heart of the Crusader (Rank 2)
5006 });
5007
5008 // Heart of the Crusader (Rank 3)
5009 ApplySpellFix({ 20337 }, [](SpellInfo* spellInfo)
5010 {
5011 spellInfo->Effects[EFFECT_1].TriggerSpell = 54499; // Heart of the Crusader (Rank 3)
5012 });
5013
5014 // Gordok Ogre Suit
5015 ApplySpellFix({ 22736 }, [](SpellInfo* spellInfo)
5016 {
5017 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_MOUNT;
5018 });
5019
5020 // Soul Flame
5021 ApplySpellFix({ 23272 }, [](SpellInfo* spellInfo)
5022 {
5023 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
5024 });
5025
5026 // Tree Disguise
5027 ApplySpellFix({ 30298 }, [](SpellInfo* spellInfo)
5028 {
5029 spellInfo->InterruptFlags |= (SPELL_INTERRUPT_FLAG_MOVEMENT | SPELL_INTERRUPT_FLAG_PUSH_BACK |
5031 spellInfo->Effects[EFFECT_2].ApplyAuraName = SPELL_AURA_MOD_STUN;
5032 });
5033
5034 // Internal Shake Camera w/ rumble sound
5035 ApplySpellFix({ 33271 }, [](SpellInfo* spellInfo)
5036 {
5037 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_WHILE_MOUNTED;
5038 });
5039
5040 // Glaive
5041 ApplySpellFix({ 36500 }, [](SpellInfo* spellInfo)
5042 {
5043 spellInfo->Attributes &= ~SPELL_ATTR0_SCALES_WITH_CREATURE_LEVEL;
5044 spellInfo->Effects[EFFECT_0].DieSides = 68;
5045 spellInfo->Effects[EFFECT_0].BasePoints = 201;
5046 });
5047
5048 // Create Anchorite Relic
5049 ApplySpellFix({ 39183 }, [](SpellInfo* spellInfo)
5050 {
5051 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(0);
5052 });
5053
5054 // Charge Rifts
5055 ApplySpellFix({ 47747 }, [](SpellInfo* spellInfo)
5056 {
5057 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_45_YARDS);
5058 });
5059
5060 // New Summon Test
5061 ApplySpellFix({ 49214 }, [](SpellInfo* spellInfo)
5062 {
5063 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(3);
5064 });
5065
5066 // Plague Strike
5067 ApplySpellFix({ 54469 }, [](SpellInfo* spellInfo)
5068 {
5069 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_5_YARDS);
5070 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_5_YARDS);
5071 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_5_YARDS);
5072 });
5073
5074 // Glyph of Chains of Ice:
5075 ApplySpellFix({ 58620 }, [](SpellInfo* spellInfo)
5076 {
5077 spellInfo->SpellLevel = 0;
5078 });
5079
5080 // Exit Portal
5081 ApplySpellFix({ 60474 }, [](SpellInfo* spellInfo)
5082 {
5083 spellInfo->AttributesEx6 |= SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE;
5084 });
5085
5086 // Eye of Acherus Flight (Boost)
5087 ApplySpellFix({ 51923 }, [](SpellInfo* spellInfo)
5088 {
5089 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
5090 });
5091
5092 // Shattering Throw
5093 ApplySpellFix({ 64382 }, [](SpellInfo* spellInfo)
5094 {
5096 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_ITEM_SPELL_IN_PVP;
5097 });
5098
5100 43444, // Explosive Trap (Hex Lord Malacrass)
5101 43447, // Freezing Trap (Hex Lord Malacrass)
5102 43449, // Snake Trap (Hex Lord Malacrass)
5103 }, [](SpellInfo* spellInfo)
5104 {
5105 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_SUMMON_OBJECT_SLOT1;
5106 });
5107
5108 // Arcane Missiles
5109 ApplySpellFix({ 58529, 61592 }, [](SpellInfo* spellInfo)
5110 {
5111 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
5112 });
5113
5114 // Siphon Bloodgem
5115 ApplySpellFix({ 34367 }, [](SpellInfo* spellInfo)
5116 {
5117 spellInfo->ChannelInterruptFlags &= ~AURA_INTERRUPT_FLAG_TURNING;
5118 });
5119
5120 // Summon Scourged Captive
5121 ApplySpellFix({ 51597 }, [](SpellInfo* spellInfo)
5122 {
5123 spellInfo->Effects[EFFECT_0].BasePoints = 1;
5124 spellInfo->Effects[EFFECT_0].DieSides = 0;
5125 });
5126
5127 // The Green Tower
5128 ApplySpellFix({ 18097 }, [](SpellInfo* spellInfo)
5129 {
5130 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21); // -1
5131 });
5132
5134 28032, // Zap Crystal
5135 28056, // Zap Crystal Corpse
5136 }, [](SpellInfo* spellInfo)
5137 {
5138 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
5139 });
5140
5141 // Earth Shield
5142 ApplySpellFix({ 55599, 58981 }, [](SpellInfo* spellInfo)
5143 {
5144 spellInfo->AttributesEx5 |= SPELL_ATTR5_LIMIT_N;
5145 });
5146
5147 // Acid Splash
5148 ApplySpellFix({ 52446, 59363 }, [](SpellInfo* spellInfo)
5149 {
5150 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
5151 });
5152
5153 // King Mrlg-Mrgl's Spare Suit
5154 ApplySpellFix({ 45278 }, [](SpellInfo* spellInfo)
5155 {
5156 spellInfo->ProcCharges = 1;
5157 });
5158
5160 56917, // To Icecrown Airship - Teleport to Airship (A)
5161 57417, // To Icecrown Airship - Teleport to Airship (H)
5162 }, [](SpellInfo* spellInfo)
5163 {
5164 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100 yards
5165 });
5166
5168 60586, // Mighty Spear Thrust
5169 60776, // Claw Swipe
5170 60881, // Fatal Strike
5171 60864, // Jaws of Death
5172 }, [](SpellInfo* spellInfo)
5173 {
5174 spellInfo->AttributesEx4 |= SPELL_ATTR4_IGNORE_DAMAGE_TAKEN_MODIFIERS;
5175 });
5176
5177 // The Brothers Bronzebeard
5179 56675, // Summon Brann Bronzebeard
5180 56676, // Summon Yorg Stormheart
5181 56697, // Summon Magni Bronzebeard
5182 }, [](SpellInfo* spellInfo)
5183 {
5184 spellInfo->Effects[EFFECT_0].MiscValueB = 64;
5185 });
5186
5188 57374, // Shadow Bolt (Lady Blaumeux 10m)
5189 57464, // Shadow Bolt (Lady Blaumeux 25m)
5190 57376, // Holy Bolt (Sir Zeliek 10m)
5191 57465, // Holy Bolt (Sir Zeliek 25m)
5192 }, [](SpellInfo* spellInfo)
5193 {
5194 spellInfo->InterruptFlags &= ~SPELL_INTERRUPT_FLAG_INTERRUPT;
5195 });
5196
5197 // Twilight Torment
5198 ApplySpellFix({ 57935, 58835 }, [](SpellInfo* spellInfo)
5199 {
5200 spellInfo->ProcCharges = 0;
5201 });
5202
5203 // 54933 Hyldnir Harpoon
5204 ApplySpellFix({ 54933 }, [](SpellInfo* spellInfo)
5205 {
5206 spellInfo->Effects[EFFECT_0].BasePoints = 1;
5207 });
5208
5210 42292, // PvP Trinket
5211 59752, // Every Man for Himself
5212 19574, // Bestial Wrath
5213 34471 // The Beast Within
5214 }, [](SpellInfo* spellInfo)
5215 {
5216 spellInfo->AttributesEx2 |= SPELL_ATTR2_NO_SCHOOL_IMMUNITIES;
5217 });
5218
5219 // 51036 Summon Venture Co. Air Patrol
5220 ApplySpellFix({ 51036 }, [](SpellInfo* spellInfo)
5221 {
5222 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
5223 });
5224
5225 // 68415 Corrupted Rage
5226 ApplySpellFix({ 68415 }, [](SpellInfo* spellInfo)
5227 {
5228 spellInfo->Effects[EFFECT_1].SpellClassMask = flag96(0, 0x20000, 0);
5229 });
5230
5231 // 31930 Judgements of the Wise
5232 ApplySpellFix({ 31930 }, [](SpellInfo* spellInfo)
5233 {
5234 spellInfo->SpellFamilyName = SPELLFAMILY_PALADIN;
5235 spellInfo->SpellFamilyFlags = flag96(0x200, 0, 0);
5236 });
5237
5238 // 64646 Corrupted Wisdom
5239 ApplySpellFix({ 64646 }, [](SpellInfo* spellInfo)
5240 {
5241 spellInfo->Effects[EFFECT_1].SpellClassMask = flag96(0x200, 0, 0);
5242 });
5243
5244 // Shadowhorn Charge (Rank 1)
5245 ApplySpellFix({ 6921 }, [](SpellInfo* spellInfo)
5246 {
5247 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
5248 });
5249
5250 // Drag Mine Cart
5251 ApplySpellFix({ 52414 }, [](SpellInfo* spellInfo)
5252 {
5253 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
5254 });
5255
5256 // Boulder Assault (Sorlof's Booty)
5257 ApplySpellFix({ 44966 }, [](SpellInfo* spellInfo)
5258 {
5259 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
5260 });
5261
5262 // Cannon Assault (Sorlof's Booty)
5263 ApplySpellFix({ 45008 }, [](SpellInfo* spellInfo)
5264 {
5265 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
5266 });
5267
5268 // Heroic Strike
5270 45026,
5271 29426
5272 }, [](SpellInfo* spellInfo)
5273 {
5274 spellInfo->SpellLevel = 10;
5275 });
5276
5277 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
5278 {
5279 SpellInfo* spellInfo = mSpellInfoMap[i];
5280 if (!spellInfo)
5281 {
5282 continue;
5283 }
5284
5285 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
5286 {
5287 switch (spellInfo->Effects[j].Effect)
5288 {
5291 case SPELL_EFFECT_JUMP:
5294 if (!spellInfo->Speed && !spellInfo->SpellFamilyName)
5295 {
5296 spellInfo->Speed = SPEED_CHARGE;
5297 }
5298 break;
5299 }
5300
5301 // Xinef: i hope this will fix the problem with not working resurrection
5302 if (spellInfo->Effects[j].Effect == SPELL_EFFECT_SELF_RESURRECT)
5303 {
5304 spellInfo->Effects[j].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
5305 }
5306 }
5307
5308 // Fix range for trajectory triggered spell
5309 for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
5310 {
5311 if (spellEffectInfo.IsEffect() && (spellEffectInfo.TargetA.GetTarget() == TARGET_DEST_TRAJ || spellEffectInfo.TargetB.GetTarget() == TARGET_DEST_TRAJ))
5312 {
5313 // Get triggered spell if any
5314 if (SpellInfo* spellInfoTrigger = const_cast<SpellInfo*>(GetSpellInfo(spellEffectInfo.TriggerSpell)))
5315 {
5316 float maxRangeMain = spellInfo->RangeEntry ? spellInfo->RangeEntry->RangeMax[0] : 0.0f;
5317 float maxRangeTrigger = spellInfoTrigger->RangeEntry ? spellInfoTrigger->RangeEntry->RangeMax[0] : 0.0f;
5318
5319 // check if triggered spell has enough max range to cover trajectory
5320 if (maxRangeTrigger < maxRangeMain)
5321 spellInfoTrigger->RangeEntry = spellInfo->RangeEntry;
5322 }
5323 }
5324 }
5325
5326 if (spellInfo->ActiveIconID == 2158) // flight
5327 {
5328 spellInfo->Attributes |= SPELL_ATTR0_PASSIVE;
5329 }
5330
5331 switch (spellInfo->SpellFamilyName)
5332 {
5334 // Seals of the Pure should affect Seal of Righteousness
5335 if (spellInfo->SpellIconID == 25 && (spellInfo->Attributes & SPELL_ATTR0_PASSIVE))
5336 spellInfo->Effects[EFFECT_0].SpellClassMask[1] |= 0x20000000;
5337 break;
5339 // Icy Touch - extend FamilyFlags (unused value) for Sigil of the Frozen Conscience to use
5340 if (spellInfo->SpellIconID == 2721 && spellInfo->SpellFamilyFlags[0] & 0x2)
5341 spellInfo->SpellFamilyFlags[0] |= 0x40;
5342 break;
5343 case SPELLFAMILY_HUNTER:
5344 // Aimed Shot not affected by category cooldown modifiers
5345 if (spellInfo->SpellFamilyFlags[0] & 0x00020000)
5346 {
5348 spellInfo->RecoveryTime = 10 * IN_MILLISECONDS;
5349 }
5350 break;
5351 }
5352
5353 // Recklessness/Shield Wall/Retaliation
5354 if (spellInfo->CategoryEntry == sSpellCategoryStore.LookupEntry(132) && spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR)
5355 {
5357 }
5358 }
5359
5360 // Xinef: The Veiled Sea area in outlands (Draenei zone), client blocks casting flying mounts
5361 for (uint32 i = 0; i < sAreaTableStore.GetNumRows(); ++i)
5362 if (AreaTableEntry* areaEntry = const_cast<AreaTableEntry*>(sAreaTableStore.LookupEntry(i)))
5363 {
5364 if (areaEntry->ID == 3479)
5365 areaEntry->flags |= AREA_FLAG_NO_FLY_ZONE;
5366 // Xinef: Dun Morogh, Kharanos tavern, missing resting flag
5367 else if (areaEntry->ID == 2102)
5368 areaEntry->flags |= AREA_FLAG_REST_ZONE_ALLIANCE;
5369 }
5370
5371 // Xinef: fix for something?
5372 SummonPropertiesEntry* properties = const_cast<SummonPropertiesEntry*>(sSummonPropertiesStore.LookupEntry(121));
5373 properties->Type = SUMMON_TYPE_TOTEM;
5374 properties = const_cast<SummonPropertiesEntry*>(sSummonPropertiesStore.LookupEntry(647)); // 52893
5375 properties->Type = SUMMON_TYPE_TOTEM;
5376 if ((properties = const_cast<SummonPropertiesEntry*>(sSummonPropertiesStore.LookupEntry(628)))) // Hungry Plaguehound
5377 {
5378 properties->Category = SUMMON_CATEGORY_PET;
5379 properties->Type = SUMMON_TYPE_PET;
5380 }
5381
5382 // Correct Pet Size
5383 CreatureDisplayInfoEntry* displayEntry = const_cast<CreatureDisplayInfoEntry*>(sCreatureDisplayInfoStore.LookupEntry(17028)); // Kurken
5384 displayEntry->scale = 2.5f;
5385
5386 // Oracles and Frenzyheart faction
5387 FactionEntry* factionEntry = const_cast<FactionEntry*>(sFactionStore.LookupEntry(1104));
5388 factionEntry->ReputationFlags[0] = 0;
5389 factionEntry = const_cast<FactionEntry*>(sFactionStore.LookupEntry(1105));
5390 factionEntry->ReputationFlags[0] = 0;
5391
5392 // Various factions, added 14, 16 to hostile mask
5393 FactionTemplateEntry* factionTemplateEntry = const_cast<FactionTemplateEntry*>(sFactionTemplateStore.LookupEntry(1978)); // Warsong Offensive
5394 factionTemplateEntry->hostileMask |= 8;
5395 factionTemplateEntry = const_cast<FactionTemplateEntry*>(sFactionTemplateStore.LookupEntry(1921)); // The Taunka
5396 factionTemplateEntry->hostileMask |= 8;
5397
5398 // Remove vehicles attr, making accessories selectable
5399 VehicleSeatEntry* vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(4689)); // Siege Engine, Accessory
5400 vse->m_flags &= ~VEHICLE_SEAT_FLAG_PASSENGER_NOT_SELECTABLE;
5401 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(4692)); // Siege Engine, Accessory
5402 vse->m_flags &= ~VEHICLE_SEAT_FLAG_PASSENGER_NOT_SELECTABLE;
5403 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(4693)); // Siege Engine, Accessory
5404 vse->m_flags &= ~VEHICLE_SEAT_FLAG_PASSENGER_NOT_SELECTABLE;
5405 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(1520)); // Wyrmrest Vanquisher
5407
5408 // Salvaged Siege Engine (Ulduar) extra passenger seats: the only salvaged vehicle seats
5409 // without this flag, leaving those passengers targetable by Flame Leviathan's AoE
5410 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(4026));
5412 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(4027));
5414
5415 // pussywizard: fix z offset for some vehicles:
5416 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(6206)); // Marrowgar - Bone Spike
5417 vse->m_attachmentOffsetZ = 4.0f;
5418 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(3806)); // Mimiron - seat on VX-001 for ACU during last phase
5419 vse->m_attachmentOffsetZ = 15.0f;
5420 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(3566)); // Mimiron - Working seat
5421 vse->m_attachmentOffsetX = -3.5f;
5422 vse->m_attachmentOffsetY = 0.0f;
5423 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(3567)); // Mimiron - Working seat
5424 vse->m_attachmentOffsetX = 2.3f;
5425 vse->m_attachmentOffsetY = -2.3f;
5426
5427 // Pilgrim's Bounty offsets
5428 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(2841));
5429 vse->m_attachmentOffsetX += 1.65f;
5430 vse->m_attachmentOffsetY += 0.75f;
5431 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(2842));
5432 vse->m_attachmentOffsetX += 1.6f;
5433 vse->m_attachmentOffsetY += -1.0f;
5434 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(2843));
5435 vse->m_attachmentOffsetX += -1.2f;
5436 vse->m_attachmentOffsetY += 0.2f;
5437 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(2844));
5438 vse->m_attachmentOffsetX += -0.1f;
5439 vse->m_attachmentOffsetY += -1.6f;
5440 vse = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(2845));
5441 vse->m_attachmentOffsetX += 0.0f;
5442 vse->m_attachmentOffsetY += 1.6f;
5443
5444 // Once Bitten, Twice Shy (10 player) - Icecrown Citadel
5445 AchievementEntry* achievement = const_cast<AchievementEntry*>(sAchievementStore.LookupEntry(4539));
5446 achievement->mapID = 631; // Correct map requirement (currently has Ulduar)
5447
5448 // Ring of Valor starting Locations
5449 GraveyardStruct const* entry = sGraveyard->GetGraveyard(1364);
5450 const_cast<GraveyardStruct*>(entry)->z += 6.0f;
5451 entry = sGraveyard->GetGraveyard(1365);
5452 const_cast<GraveyardStruct*>(entry)->z += 6.0f;
5453
5454 LockEntry* key = const_cast<LockEntry*>(sLockStore.LookupEntry(36)); // 3366 Opening, allows to open without proper key
5455 key->Type[2] = LOCK_KEY_NONE;
5456
5457 LOG_INFO("server.loading", ">> Loading spell dbc data corrections in {} ms", GetMSTimeDiffToNow(oldMSTime));
5458 LOG_INFO("server.loading", " ");
5459}
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_TREAT_AS_NPC_AOE
Definition SharedDefines.h:655
@ SPELL_ATTR7_NO_ATTACK_DODGE
Definition SharedDefines.h:652
@ SPELL_ATTR7_DISABLE_AURA_WHILE_DEAD
Definition SharedDefines.h:631
@ SPELL_EFFECT_DUMMY
Definition SharedDefines.h:769
@ SPELL_EFFECT_SCRIPT_EFFECT
Definition SharedDefines.h:843
@ SPELL_EFFECT_POWER_BURN
Definition SharedDefines.h:828
@ SPELL_EFFECT_APPLY_AREA_AURA_FRIEND
Definition SharedDefines.h:894
@ SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
Definition SharedDefines.h:908
@ SPELL_EFFECT_SELF_RESURRECT
Definition SharedDefines.h:860
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT1
Definition SharedDefines.h:870
@ SPELL_EFFECT_TRIGGER_MISSILE
Definition SharedDefines.h:798
@ SPELL_EFFECT_JUMP_DEST
Definition SharedDefines.h:808
@ SPELL_EFFECT_MODIFY_THREAT_PERCENT
Definition SharedDefines.h:891
@ SPELL_EFFECT_LEAP_BACK
Definition SharedDefines.h:904
@ SPELL_EFFECT_CHARGE
Definition SharedDefines.h:862
@ SPELL_EFFECT_CHARGE_DEST
Definition SharedDefines.h:915
@ SPELL_EFFECT_JUMP
Definition SharedDefines.h:807
@ SPELL_EFFECT_APPLY_AURA
Definition SharedDefines.h:772
@ SPELL_PREVENTION_TYPE_NONE
Definition SharedDefines.h:1557
@ SPELL_ATTR5_EXTRA_INITIAL_PERIOD
Definition SharedDefines.h:564
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
Definition SharedDefines.h:558
@ SPELL_ATTR5_DO_NOT_DISPLAY_DURATION
Definition SharedDefines.h:565
@ SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL
Definition SharedDefines.h:555
@ SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT
Definition SharedDefines.h:581
@ SPELL_ATTR5_LIMIT_N
Definition SharedDefines.h:560
@ TARGET_DEST_TARGET_ANY
Definition SharedDefines.h:1471
@ TARGET_UNIT_CONE_ENTRY
Definition SharedDefines.h:1468
@ TARGET_DEST_CASTER_FRONT
Definition SharedDefines.h:1455
@ TARGET_DEST_DB
Definition SharedDefines.h:1426
@ TARGET_UNIT_CASTER_AREA_PARTY
Definition SharedDefines.h:1428
@ TARGET_UNIT_SRC_AREA_ENTRY
Definition SharedDefines.h:1420
@ TARGET_UNIT_DEST_AREA_ENEMY
Definition SharedDefines.h:1425
@ TARGET_UNIT_SRC_AREA_ALLY
Definition SharedDefines.h:1438
@ TARGET_UNIT_TARGET_ALLY
Definition SharedDefines.h:1429
@ TARGET_DEST_CASTER_BACK
Definition SharedDefines.h:1456
@ TARGET_UNIT_VEHICLE
Definition SharedDefines.h:1502
@ TARGET_UNIT_TARGET_ANY
Definition SharedDefines.h:1433
@ TARGET_DEST_DEST
Definition SharedDefines.h:1495
@ TARGET_UNIT_SRC_AREA_ENEMY
Definition SharedDefines.h:1424
@ TARGET_DEST_TARGET_ENEMY
Definition SharedDefines.h:1461
@ TARGET_UNIT_PET
Definition SharedDefines.h:1418
@ TARGET_DEST_DYNOBJ_NONE
Definition SharedDefines.h:1496
@ TARGET_UNIT_TARGET_ENEMY
Definition SharedDefines.h:1419
@ TARGET_UNIT_MASTER
Definition SharedDefines.h:1435
@ TARGET_DEST_TRAJ
Definition SharedDefines.h:1497
@ TARGET_UNIT_DEST_AREA_ENTRY
Definition SharedDefines.h:1421
@ TARGET_UNIT_NEARBY_ENTRY
Definition SharedDefines.h:1446
@ TARGET_DEST_CASTER
Definition SharedDefines.h:1427
@ TARGET_UNIT_CASTER
Definition SharedDefines.h:1414
@ TARGET_UNIT_CONE_ENEMY_24
Definition SharedDefines.h:1432
@ TARGET_SRC_CASTER
Definition SharedDefines.h:1430
@ TARGET_UNIT_SUMMONER
Definition SharedDefines.h:1500
@ SPELL_ATTR2_CANT_CRIT
Definition SharedDefines.h:473
@ SPELL_ATTR2_NO_TARGET_PER_SECOND_COST
Definition SharedDefines.h:455
@ SPELL_ATTR2_ALLOW_DEAD_TARGET
Definition SharedDefines.h:444
@ SPELL_ATTR2_IGNORE_LINE_OF_SIGHT
Definition SharedDefines.h:446
@ SPELL_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_SET_VEHICLE_ID
Definition SpellAuraDefines.h:359
@ SPELL_AURA_MOD_STUN
Definition SpellAuraDefines.h:75
@ 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:429
@ EFFECT_RADIUS_7_YARDS
Definition SpellMgr.h:435
@ EFFECT_RADIUS_100_YARDS
Definition SpellMgr.h:411
@ EFFECT_RADIUS_20_YARDS
Definition SpellMgr.h:408
@ EFFECT_RADIUS_8_YARDS
Definition SpellMgr.h:413
@ EFFECT_RADIUS_45_YARDS
Definition SpellMgr.h:410
@ EFFECT_RADIUS_2_YARDS
Definition SpellMgr.h:406
@ EFFECT_RADIUS_1_YARD
Definition SpellMgr.h:415
@ EFFECT_RADIUS_4_YARDS
Definition SpellMgr.h:425
@ EFFECT_RADIUS_25_YARDS
Definition SpellMgr.h:419
@ EFFECT_RADIUS_5_YARDS
Definition SpellMgr.h:407
@ EFFECT_RADIUS_70_YARDS
Definition SpellMgr.h:424
@ EFFECT_RADIUS_3_YARDS
Definition SpellMgr.h:414
@ EFFECT_RADIUS_50000_YARDS
Definition SpellMgr.h:427
@ EFFECT_RADIUS_18_YARDS
Definition SpellMgr.h:418
@ EFFECT_RADIUS_200_YARDS
Definition SpellMgr.h:421
@ EFFECT_RADIUS_12_YARDS
Definition SpellMgr.h:431
@ EFFECT_RADIUS_10_YARDS
Definition SpellMgr.h:412
@ EFFECT_RADIUS_150_YARDS
Definition SpellMgr.h:439
@ EFFECT_RADIUS_6_YARDS
Definition SpellMgr.h:428
@ 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, 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_ATTR7_TREAT_AS_NPC_AOE, SPELL_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_ADD_PCT_MODIFIER, SPELL_AURA_DUMMY, SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST, SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT, SPELL_AURA_MOD_STUN, SPELL_AURA_MOD_TAUNT, SPELL_AURA_PERIODIC_DUMMY, SPELL_AURA_PERIODIC_HEAL, SPELL_AURA_PERIODIC_TRIGGER_SPELL, SPELL_AURA_PROC_TRIGGER_SPELL, SPELL_AURA_SCHOOL_ABSORB, SPELL_AURA_SET_VEHICLE_ID, SPELL_AURA_SPLIT_DAMAGE_PCT, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_APPLY_AREA_AURA_FRIEND, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_CHARGE, SPELL_EFFECT_CHARGE_DEST, SPELL_EFFECT_DUMMY, SPELL_EFFECT_JUMP, SPELL_EFFECT_JUMP_DEST, SPELL_EFFECT_LEAP_BACK, SPELL_EFFECT_MODIFY_THREAT_PERCENT, SPELL_EFFECT_POWER_BURN, SPELL_EFFECT_SCRIPT_EFFECT, SPELL_EFFECT_SELF_RESURRECT, SPELL_EFFECT_SUMMON_OBJECT_SLOT1, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_TRIGGER_MISSILE, SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE, SPELL_FACING_FLAG_INFRONT, SPELL_INTERRUPT_FLAG_INTERRUPT, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_INTERRUPT_FLAG_PUSH_BACK, SPELL_INTERRUPT_FLAG_UNK3, SPELL_PREVENTION_TYPE_NONE, SPELL_SCHOOL_MASK_MAGIC, SPELL_SCHOOL_MASK_NATURE, SPELL_SCHOOL_MASK_SHADOW, SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_MAGE, SPELLFAMILY_PALADIN, SPELLFAMILY_POTION, SPELLFAMILY_ROGUE, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, SPELLMOD_DAMAGE, SPELLMOD_EFFECT1, SPELLMOD_EFFECT2, sSpellCastTimesStore, sSpellCategoryStore, sSpellDurationStore, sSpellRadiusStore, sSpellRangeStore, sSummonPropertiesStore, SUMMON_CATEGORY_PET, SUMMON_TYPE_PET, SUMMON_TYPE_TOTEM, sVehicleSeatStore, TARGET_DEST_CASTER, TARGET_DEST_CASTER_BACK, TARGET_DEST_CASTER_FRONT, TARGET_DEST_DB, TARGET_DEST_DEST, TARGET_DEST_DYNOBJ_NONE, TARGET_DEST_TARGET_ANY, TARGET_DEST_TARGET_ENEMY, TARGET_DEST_TRAJ, TARGET_FLAG_DEST_LOCATION, TARGET_SRC_CASTER, TARGET_UNIT_CASTER, TARGET_UNIT_CASTER_AREA_PARTY, TARGET_UNIT_CONE_ENEMY_24, TARGET_UNIT_CONE_ENTRY, TARGET_UNIT_DEST_AREA_ENEMY, TARGET_UNIT_DEST_AREA_ENTRY, TARGET_UNIT_MASTER, TARGET_UNIT_NEARBY_ENTRY, TARGET_UNIT_PET, TARGET_UNIT_SRC_AREA_ALLY, TARGET_UNIT_SRC_AREA_ENEMY, TARGET_UNIT_SRC_AREA_ENTRY, TARGET_UNIT_SUMMONER, TARGET_UNIT_TARGET_ALLY, TARGET_UNIT_TARGET_ANY, TARGET_UNIT_TARGET_ENEMY, TARGET_UNIT_VEHICLE, LockEntry::Type, SummonPropertiesEntry::Type, and VEHICLE_SEAT_FLAG_PASSENGER_NOT_SELECTABLE.

◆ LoadSpellInfoCustomAttributes()

void SpellMgr::LoadSpellInfoCustomAttributes ( )
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
3167{
3168 uint32 const oldMSTime = getMSTime();
3169 uint32 const customAttrTime = getMSTime();
3170 uint32 count;
3171
3172 QueryResult result = WorldDatabase.Query("SELECT spell_id, attributes FROM spell_custom_attr");
3173
3174 if (!result)
3175 {
3176 LOG_WARN("server.loading", ">> Loaded 0 Spell Custom Attributes From DB. DB table `spell_custom_attr` Is Empty.");
3177 }
3178 else
3179 {
3180 count = 0;
3181
3182 do
3183 {
3184 ++count;
3185
3186 Field const* fields = result->Fetch();
3187
3188 uint32 const spellId = fields[0].Get<uint32>();
3189 uint32 attributes = fields[1].Get<uint32>();
3190
3191 SpellInfo* spellInfo = _GetSpellInfo(spellId);
3192 if (!spellInfo)
3193 {
3194 LOG_INFO("sql.sql", "Table `spell_custom_attr` has wrong spell (spell_id: {}), ignored.", spellId);
3195 continue;
3196 }
3197
3198 if (attributes & SPELL_ATTR0_CU_NEGATIVE)
3199 {
3200 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3201 {
3202 if (spellInfo->Effects[i].IsEffect())
3203 {
3204 if ((attributes & (SPELL_ATTR0_CU_NEGATIVE_EFF0 << i)) && (attributes & (SPELL_ATTR0_CU_POSITIVE_EFF0 << i)))
3205 {
3206 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);
3208 }
3209 continue;
3210 }
3211
3212 if (attributes & (SPELL_ATTR0_CU_NEGATIVE_EFF0 << i))
3213 {
3214 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));
3215 attributes &= ~(SPELL_ATTR0_CU_NEGATIVE_EFF0 << i);
3216 }
3217 }
3218 }
3219
3220 if (attributes & SPELL_ATTR0_CU_POSITIVE)
3221 {
3222 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3223 {
3224 if (spellInfo->Effects[i].IsEffect())
3225 {
3226 continue;
3227 }
3228
3229 if ((attributes & (SPELL_ATTR0_CU_POSITIVE_EFF0 << i)))
3230 {
3231 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));
3232 attributes &= ~(SPELL_ATTR0_CU_POSITIVE_EFF0 << i);
3233 }
3234 }
3235 }
3236
3237 if ((attributes & SPELL_ATTR0_CU_FORCE_AURA_SAVING) && (attributes & SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED))
3238 {
3239 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);
3241 }
3242
3243 spellInfo->AttributesCu |= attributes;
3244 } while (result->NextRow());
3245
3246 LOG_INFO("server.loading", ">> Loaded {} spell custom attributes from DB in {} ms", count, GetMSTimeDiffToNow(customAttrTime));
3247 }
3248
3249 // xinef: create talent spells set
3250 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
3251 {
3252 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
3253 if (!talentInfo)
3254 continue;
3255
3256 for (uint8 j = 0; j < MAX_TALENT_RANK; j++)
3257 if (uint32 spellId = talentInfo->RankID[j])
3258 if (SpellInfo const* spellInfo = GetSpellInfo(spellId))
3259 for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
3260 if (spellInfo->Effects[k].Effect == SPELL_EFFECT_LEARN_SPELL)
3261 if (SpellInfo const* learnSpell = GetSpellInfo(spellInfo->Effects[k].TriggerSpell))
3262 if (learnSpell->IsRanked() && !learnSpell->HasAttribute(SpellAttr0(SPELL_ATTR0_PASSIVE | SPELL_ATTR0_DO_NOT_DISPLAY)))
3263 mTalentSpellAdditionalSet.insert(learnSpell->Id);
3264 }
3265
3266 SpellInfo* spellInfo = nullptr;
3267 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3268 {
3269 spellInfo = mSpellInfoMap[i];
3270 if (!spellInfo)
3271 continue;
3272
3273 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3274 {
3275 switch (spellInfo->Effects[j].ApplyAuraName)
3276 {
3278 {
3279 switch (spellInfo->Id)
3280 {
3281 // Exceptions
3282 case 44801: // Spectral Invisibility (Kalecgos, SWP)
3283 case 46021: // Spectral Realm (SWP)
3284 case 52951: // Chapel Invisibility (DK starting zone)
3285 case 43062: // Alpha Worg: Garwal's Invisibility
3286 case 45614: // Shroud of the Scourge (Blending In, Temple City of En'kilah)
3287 break;
3288 default:
3290 break;
3291 }
3292 }
3293 break;
3300 break;
3301 default:
3302 break;
3303 }
3304
3305 switch (spellInfo->Effects[j].ApplyAuraName)
3306 {
3307 case SPELL_AURA_CONVERT_RUNE: // Can't be saved - aura handler relies on calculated amount and changes it
3308 case SPELL_AURA_OPEN_STABLE: // No point in saving this, since the stable dialog can't be open on aura load anyway.
3309 // Auras that require both caster & target to be in world cannot be saved
3317 break;
3318 default:
3319 break;
3320 }
3321
3322 switch (spellInfo->Effects[j].ApplyAuraName)
3323 {
3331 break;
3334 break;
3335 default:
3336 break;
3337 }
3338
3339 switch (spellInfo->Effects[j].Effect)
3340 {
3346 case SPELL_EFFECT_HEAL:
3348 break;
3359 break;
3362 case SPELL_EFFECT_JUMP:
3365 spellInfo->AttributesCu |= SPELL_ATTR0_CU_CHARGE;
3366 break;
3369 break;
3374 {
3375 // Only Enchanting profession enchant procs can stack when dual-wielding
3376 // DK runes (e.g., Unholy Strength) should refresh, not stack
3378 {
3379 uint32 enchantId = spellInfo->Effects[j].MiscValue;
3380 SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId);
3381 if (!enchant)
3382 break;
3383
3384 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
3385 {
3386 if (enchant->type[s] != ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL)
3387 continue;
3388
3389 SpellInfo* procInfo = _GetSpellInfo(enchant->spellid[s]);
3390 if (!procInfo)
3391 continue;
3392
3393 // if proced directly from enchantment, not via proc aura
3394 // NOTE: Enchant Weapon - Blade Ward also has proc aura spell and is proced directly
3395 // however its not expected to stack so this check is good
3397 continue;
3398
3400 }
3401 }
3402 break;
3403 }
3404 }
3405 }
3406
3407 // Xinef: spells ignoring hit result should not be binary
3408 if (!spellInfo->HasAttribute(SPELL_ATTR3_ALWAYS_HIT))
3409 {
3410 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3411 {
3412 if (spellInfo->Effects[j].Effect)
3413 {
3414 switch (spellInfo->Effects[j].Effect)
3415 {
3423 continue;
3432 if (spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
3433 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE_PERCENT ||
3434 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_DUMMY ||
3435 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH ||
3436 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_HEALTH_FUNNEL ||
3437 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DUMMY)
3438 continue;
3439 [[fallthrough]];
3440 default:
3441 if (!(spellInfo->Effects[j].CalcValue() ||
3442 ((spellInfo->Effects[j].Effect == SPELL_EFFECT_INTERRUPT_CAST || spellInfo->HasAttribute(SPELL_ATTR0_CU_DONT_BREAK_STEALTH)) &&
3444 continue;
3445
3446 if (spellInfo->Id == 69649 || spellInfo->Id == 71056 || spellInfo->Id == 71057 || spellInfo->Id == 71058 ||
3447 spellInfo->Id == 73061 || spellInfo->Id == 73062 || spellInfo->Id == 73063 || spellInfo->Id == 73064)
3448 continue;
3449
3450 if (spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && (spellInfo->SpellFamilyFlags[0] & 0x20)) // Frostbolt
3451 continue;
3452
3453 if (spellInfo->Id == 55095) // Frost Fever
3454 continue;
3455
3456 if (spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK &&
3457 ((spellInfo->SpellFamilyFlags[1] & 0x40000) || (spellInfo->SpellFamilyFlags[0] & 0x4000))) // Haunt/Drain Soul
3458 continue;
3459
3461 break;
3462 }
3463 }
3464 }
3465 }
3466
3467 // pussywizard:
3468 if ((spellInfo->SchoolMask & SPELL_SCHOOL_MASK_NORMAL) && (spellInfo->SchoolMask & SPELL_SCHOOL_MASK_MAGIC))
3469 {
3470 spellInfo->SchoolMask &= ~SPELL_SCHOOL_MASK_NORMAL;
3472 }
3473
3474 if (!spellInfo->_IsPositiveEffect(EFFECT_0, false))
3476
3477 if (!spellInfo->_IsPositiveEffect(EFFECT_1, false))
3479
3480 if (!spellInfo->_IsPositiveEffect(EFFECT_2, false))
3482
3483 if (spellInfo->SpellVisual[0] == 3879)
3485
3486 switch (spellInfo->SpellFamilyName)
3487 {
3489 // Shout
3490 if (spellInfo->SpellFamilyFlags[0] & 0x20000 || spellInfo->SpellFamilyFlags[1] & 0x20)
3492 break;
3493 case SPELLFAMILY_DRUID:
3494 // Roar
3495 if (spellInfo->SpellFamilyFlags[0] & 0x8)
3497 break;
3498 case SPELLFAMILY_HUNTER:
3499 // Aspects
3500 if (spellInfo->GetCategory() == 47)
3501 {
3503 }
3504 // Aimed Shot
3505 if (spellInfo->SpellFamilyFlags[0] & 0x00020000)
3506 {
3508 }
3509 break;
3510 default:
3511 break;
3512 }
3513
3514 switch (spellInfo->Id)
3515 {
3516 // Xinef: NOT CUSTOM, cant add in DBC CORRECTION because i need to swap effects, too much work to do there
3517 // Envenom
3518 case 32645:
3519 case 32684:
3520 case 57992:
3521 case 57993:
3522 {
3523 SpellEffectInfo info = spellInfo->Effects[EFFECT_0];
3524 spellInfo->Effects[EFFECT_0] = spellInfo->Effects[EFFECT_2];
3525 spellInfo->Effects[EFFECT_2] = info;
3526 break;
3527 }
3528
3529 // Xinef: Cooldown overwrites
3530 // Burst of Speed
3531 case 57493:
3532 spellInfo->RecoveryTime = 60000;
3533 spellInfo->_requireCooldownInfo = true;
3534 break;
3535 // Strafe Jotunheim Building
3536 case 7769:
3537 spellInfo->RecoveryTime = 1500;
3538 spellInfo->_requireCooldownInfo = true;
3539 break;
3540 case 44535: // Spirit Heal, abilities also have no cost
3541 spellInfo->Effects[EFFECT_0].MiscValue = 127;
3542 break;
3543 default:
3544 break;
3545 }
3546
3547 if (spellInfo->Speed > 0.0f)
3548 {
3549 if (SpellVisualEntry const* spellVisual = sSpellVisualStore.LookupEntry(spellInfo->SpellVisual[0]))
3550 {
3551 if (spellVisual->HasMissile)
3552 {
3553 if (spellVisual->MissileModel == -4 || spellVisual->MissileModel == -5)
3554 {
3556 }
3557 }
3558 }
3559 }
3560
3561 spellInfo->_InitializeExplicitTargetMask();
3562
3563 if (HasSpellCooldownOverride(spellInfo->Id))
3564 {
3565 SpellCooldownOverride spellOverride = GetSpellCooldownOverride(spellInfo->Id);
3566
3567 if (spellInfo->RecoveryTime != spellOverride.RecoveryTime)
3568 {
3569 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3570 }
3571
3572 if (spellInfo->CategoryRecoveryTime != spellOverride.CategoryRecoveryTime)
3573 {
3574 spellInfo->CategoryRecoveryTime = spellOverride.CategoryRecoveryTime;
3575 }
3576
3577 if (spellInfo->StartRecoveryTime != spellOverride.StartRecoveryTime)
3578 {
3579 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3580 }
3581
3582 if (spellInfo->StartRecoveryCategory != spellOverride.StartRecoveryCategory)
3583 {
3584 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3585 }
3586 }
3587
3588 sScriptMgr->OnLoadSpellCustomAttr(spellInfo);
3589 }
3590
3591 // Xinef: addition for binary spells, ommit spells triggering other spells
3592 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3593 {
3594 spellInfo = mSpellInfoMap[i];
3595 if (!spellInfo)
3596 continue;
3597
3598 if (!(spellInfo->AttributesCu & SPELL_ATTR0_CU_BINARY_SPELL))
3599 continue;
3600
3601 bool allNonBinary = true;
3602 bool overrideAttr = false;
3603 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3604 {
3605 if (spellInfo->Effects[j].ApplyAuraName && spellInfo->Effects[j].TriggerSpell)
3606 {
3607 switch (spellInfo->Effects[j].ApplyAuraName)
3608 {
3612 if (SpellInfo const* triggerSpell = GetSpellInfo(spellInfo->Effects[j].TriggerSpell))
3613 {
3614 overrideAttr = true;
3615 if (triggerSpell->AttributesCu & SPELL_ATTR0_CU_BINARY_SPELL)
3616 allNonBinary = false;
3617 }
3618 break;
3619 default:
3620 break;
3621 }
3622 }
3623 }
3624
3625 if (overrideAttr && allNonBinary)
3626 spellInfo->AttributesCu &= ~SPELL_ATTR0_CU_BINARY_SPELL;
3627 }
3628
3629 LOG_INFO("server.loading", ">> Loaded SpellInfo Custom Attributes in {} ms", GetMSTimeDiffToNow(oldMSTime));
3630 LOG_INFO("server.loading", " ");
3631}
@ 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:766
@ 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_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_CHARGE
Definition SpellInfo.h:186
@ SPELL_ATTR0_CU_NEGATIVE
Definition SpellInfo.h:211
@ SPELL_ATTR0_CU_NEEDS_AMMO_DATA
Definition SpellInfo.h:196
@ SPELL_ATTR0_CU_POSITIVE_EFF0
Definition SpellInfo.h:202
@ SPELL_ATTR0_CU_NEGATIVE_EFF0
Definition SpellInfo.h:189
@ SPELL_ATTR0_CU_BINARY_SPELL
Definition SpellInfo.h:197
@ SPELL_ATTR0_CU_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:3089
SpellInfo * _GetSpellInfo(uint32 spellId)
Definition SpellMgr.h:776
bool HasSpellCooldownOverride(uint32 spellId) const
Definition SpellMgr.cpp:3084
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_CHARGE, 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_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_CHARGE, SPELL_EFFECT_CHARGE_DEST, SPELL_EFFECT_CREATE_ITEM, SPELL_EFFECT_ENCHANT_HELD_ITEM, SPELL_EFFECT_ENCHANT_ITEM, SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY, SPELL_EFFECT_ENERGIZE, SPELL_EFFECT_ENERGIZE_PCT, SPELL_EFFECT_HEAL, SPELL_EFFECT_HEAL_MAX_HEALTH, SPELL_EFFECT_HEAL_MECHANICAL, SPELL_EFFECT_HEAL_PCT, SPELL_EFFECT_HEALTH_LEECH, SPELL_EFFECT_INTERRUPT_CAST, SPELL_EFFECT_JUMP, SPELL_EFFECT_JUMP_DEST, SPELL_EFFECT_LEAP_BACK, SPELL_EFFECT_LEARN_SPELL, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_PERSISTENT_AREA_AURA, SPELL_EFFECT_PICKPOCKET, SPELL_EFFECT_POWER_BURN, SPELL_EFFECT_POWER_DRAIN, SPELL_EFFECT_SCHOOL_DAMAGE, SPELL_EFFECT_TRIGGER_SPELL, SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, SPELL_SCHOOL_MASK_NORMAL, SPELLFAMILY_DRUID, SPELLFAMILY_HUNTER, SPELLFAMILY_MAGE, SPELLFAMILY_WARLOCK, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellItemEnchantmentEntry::spellid, SpellInfo::SpellVisual, sScriptMgr, sSpellItemEnchantmentStore, sSpellVisualStore, sTalentStore, SpellInfo::StartRecoveryCategory, SpellCooldownOverride::StartRecoveryCategory, SpellInfo::StartRecoveryTime, SpellCooldownOverride::StartRecoveryTime, SpellItemEnchantmentEntry::type, and WorldDatabase.

◆ LoadSpellInfoImmunities()

void SpellMgr::LoadSpellInfoImmunities ( )
3634{
3635 uint32 oldMSTime = getMSTime();
3636
3637 for (SpellInfo* spellInfo : mSpellInfoMap)
3638 {
3639 if (!spellInfo)
3640 continue;
3641 spellInfo->_LoadImmunityInfo();
3642 }
3643
3644 LOG_INFO("server.loading", ">> Loaded SpellInfo immunity infos in {} ms", GetMSTimeDiffToNow(oldMSTime));
3645}

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

◆ LoadSpellInfoStore()

void SpellMgr::LoadSpellInfoStore ( )
3023{
3024 uint32 oldMSTime = getMSTime();
3025
3027 mSpellInfoMap.resize(sSpellStore.GetNumRows(), nullptr);
3028
3029 for (SpellEntry const* spellEntry : sSpellStore)
3030 mSpellInfoMap[spellEntry->Id] = new SpellInfo(spellEntry);
3031
3032 for (uint32 spellIndex = 0; spellIndex < GetSpellInfoStoreSize(); ++spellIndex)
3033 {
3034 if (!mSpellInfoMap[spellIndex])
3035 continue;
3036
3037 for (SpellEffectInfo const& spellEffectInfo : mSpellInfoMap[spellIndex]->GetEffects())
3038 {
3039 //ASSERT(effect.EffectIndex < MAX_SPELL_EFFECTS, "MAX_SPELL_EFFECTS must be at least {}", effect.EffectIndex + 1);
3040 ASSERT(spellEffectInfo.Effect < TOTAL_SPELL_EFFECTS, "TOTAL_SPELL_EFFECTS must be at least {}", spellEffectInfo.Effect + 1);
3041 ASSERT(spellEffectInfo.ApplyAuraName < TOTAL_AURAS, "TOTAL_AURAS must be at least {}", spellEffectInfo.ApplyAuraName + 1);
3042 ASSERT(spellEffectInfo.TargetA.GetTarget() < TOTAL_SPELL_TARGETS, "TOTAL_SPELL_TARGETS must be at least {}", spellEffectInfo.TargetA.GetTarget() + 1);
3043 ASSERT(spellEffectInfo.TargetB.GetTarget() < TOTAL_SPELL_TARGETS, "TOTAL_SPELL_TARGETS must be at least {}", spellEffectInfo.TargetB.GetTarget() + 1);
3044 }
3045 }
3046
3048
3049 LOG_INFO("server.loading", ">> Loaded Spell Custom Attributes in {} ms", GetMSTimeDiffToNow(oldMSTime));
3050 LOG_INFO("server.loading", " ");
3051}
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 ( )
3131{
3132 uint32 oldMSTime = getMSTime();
3133
3134 QueryResult result = WorldDatabase.Query("SELECT ID, JumpDistance FROM spell_jump_distance");
3135
3136 if (!result)
3137 {
3138 LOG_WARN("server.loading", ">> Loaded 0 spell jump distances. DB table `spell_jump_distance` is empty.");
3139 LOG_INFO("server.loading", " ");
3140 return;
3141 }
3142
3143 uint32 count = 0;
3144 do
3145 {
3146 Field const* fields = result->Fetch();
3147
3148 uint32 const spellId = fields[0].Get<uint32>();
3149 float const jumpDistance = fields[1].Get<float>();
3150
3151 SpellInfo* spellInfo = _GetSpellInfo(spellId);
3152 if (!spellInfo)
3153 {
3154 LOG_ERROR("sql.sql", "Table `spell_jump_distance` has wrong spell (spell_id: {}), ignored.", spellId);
3155 continue;
3156 }
3157
3158 spellInfo->JumpDistance = jumpDistance;
3159 ++count;
3160 } while (result->NextRow());
3161
3162 LOG_INFO("server.loading", ">> Loaded {} spell jump distances in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3163 LOG_INFO("server.loading", " ");
3164}

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

◆ LoadSpellLearnSkills()

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

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 ( )
2585{
2586 uint32 oldMSTime = getMSTime();
2587
2588 mSpellLinkedMap.clear(); // need for reload case
2589
2590 // 0 1 2
2591 QueryResult result = WorldDatabase.Query("SELECT spell_trigger, spell_effect, type FROM spell_linked_spell");
2592 if (!result)
2593 {
2594 LOG_WARN("server.loading", ">> Loaded 0 linked spells. DB table `spell_linked_spell` is empty.");
2595 LOG_INFO("server.loading", " ");
2596 return;
2597 }
2598
2599 uint32 count = 0;
2600 do
2601 {
2602 Field* fields = result->Fetch();
2603
2604 int32 trigger = fields[0].Get<int32>();
2605 int32 effect = fields[1].Get<int32>();
2606 int32 type = fields[2].Get<uint8>();
2607
2608 SpellInfo const* spellInfo = GetSpellInfo(std::abs(trigger));
2609 if (!spellInfo)
2610 {
2611 LOG_ERROR("sql.sql", "Spell {} listed in `spell_linked_spell` does not exist", std::abs(trigger));
2612 continue;
2613 }
2614 spellInfo = GetSpellInfo(std::abs(effect));
2615 if (!spellInfo)
2616 {
2617 LOG_ERROR("sql.sql", "Spell {} listed in `spell_linked_spell` does not exist", std::abs(effect));
2618 continue;
2619 }
2620
2621 if (type) //we will find a better way when more types are needed
2622 {
2623 if (trigger > 0)
2624 trigger += SPELL_LINKED_MAX_SPELLS * type;
2625 else
2626 trigger -= SPELL_LINKED_MAX_SPELLS * type;
2627 }
2628 mSpellLinkedMap[trigger].push_back(effect);
2629
2630 ++count;
2631 } while (result->NextRow());
2632
2633 LOG_INFO("server.loading", ">> Loaded {} Linked Spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2634 LOG_INFO("server.loading", " ");
2635}
#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 ( )
2378{
2379 uint32 oldMSTime = getMSTime();
2380
2381 mSpellMixologyMap.clear(); // need for reload case
2382
2383 // 0 1
2384 QueryResult result = WorldDatabase.Query("SELECT entry, pctMod FROM spell_mixology");
2385 if (!result)
2386 {
2387 LOG_WARN("server.loading", ">> Loaded 0 mixology bonuses. DB table `spell_mixology` 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_mixology` does not exist", entry);
2402 continue;
2403 }
2404
2405 mSpellMixologyMap[entry] = fields[1].Get<float>();
2406 ++count;
2407 } while (result->NextRow());
2408
2409 LOG_INFO("server.loading", ">> Loaded {} Mixology Bonuses in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2410 LOG_INFO("server.loading", " ");
2411}

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

◆ LoadSpellPetAuras()

void SpellMgr::LoadSpellPetAuras ( )
2436{
2437 uint32 oldMSTime = getMSTime();
2438
2439 mSpellPetAuraMap.clear(); // need for reload case
2440
2441 // 0 1 2 3
2442 QueryResult result = WorldDatabase.Query("SELECT spell, effectId, pet, aura FROM spell_pet_auras");
2443 if (!result)
2444 {
2445 LOG_WARN("server.loading", ">> Loaded 0 spell pet auras. DB table `spell_pet_auras` is empty.");
2446 LOG_INFO("server.loading", " ");
2447 return;
2448 }
2449
2450 uint32 count = 0;
2451 do
2452 {
2453 Field* fields = result->Fetch();
2454
2455 uint32 spell = fields[0].Get<uint32>();
2456 uint8 eff = fields[1].Get<uint8>();
2457 uint32 pet = fields[2].Get<uint32>();
2458 uint32 aura = fields[3].Get<uint32>();
2459
2460 SpellPetAuraMap::iterator itr = mSpellPetAuraMap.find((spell << 8) + eff);
2461 if (itr != mSpellPetAuraMap.end())
2462 itr->second.AddAura(pet, aura);
2463 else
2464 {
2465 SpellInfo const* spellInfo = GetSpellInfo(spell);
2466 if (!spellInfo)
2467 {
2468 LOG_ERROR("sql.sql", "Spell {} listed in `spell_pet_auras` does not exist", spell);
2469 continue;
2470 }
2471 if (spellInfo->Effects[eff].Effect != SPELL_EFFECT_DUMMY &&
2472 (spellInfo->Effects[eff].Effect != SPELL_EFFECT_APPLY_AURA ||
2473 spellInfo->Effects[eff].ApplyAuraName != SPELL_AURA_DUMMY))
2474 {
2475 LOG_ERROR("spells", "Spell {} listed in `spell_pet_auras` does not have dummy aura or dummy effect", spell);
2476 continue;
2477 }
2478
2479 SpellInfo const* spellInfo2 = GetSpellInfo(aura);
2480 if (!spellInfo2)
2481 {
2482 LOG_ERROR("sql.sql", "Aura {} listed in `spell_pet_auras` does not exist", aura);
2483 continue;
2484 }
2485
2486 PetAura pa(pet, aura, spellInfo->Effects[eff].TargetA.GetTarget() == TARGET_UNIT_PET, spellInfo->Effects[eff].CalcValue());
2487 mSpellPetAuraMap[(spell << 8) + eff] = pa;
2488 }
2489
2490 ++count;
2491 } while (result->NextRow());
2492
2493 LOG_INFO("server.loading", ">> Loaded {} Spell Pet Auras in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2494 LOG_INFO("server.loading", " ");
2495}
Definition SpellMgr.h:467

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

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

◆ LoadSpellRequired()

void SpellMgr::LoadSpellRequired ( )
1391{
1392 uint32 oldMSTime = getMSTime();
1393
1394 mSpellsReqSpell.clear(); // need for reload case
1395 mSpellReq.clear(); // need for reload case
1396
1397 // 0 1
1398 QueryResult result = WorldDatabase.Query("SELECT spell_id, req_spell from spell_required");
1399
1400 if (!result)
1401 {
1402 LOG_WARN("server.loading", ">> Loaded 0 spell required records. DB table `spell_required` is empty.");
1403 LOG_INFO("server.loading", " ");
1404 return;
1405 }
1406
1407 uint32 count = 0;
1408 do
1409 {
1410 Field* fields = result->Fetch();
1411
1412 uint32 spellId = fields[0].Get<uint32>();
1413 uint32 spellReq = fields[1].Get<uint32>();
1414
1415 // check if chain is made with valid first spell
1416 SpellInfo const* spellInfo = GetSpellInfo(spellId);
1417 if (!spellInfo)
1418 {
1419 LOG_ERROR("sql.sql", "spell_id {} in `spell_required` table is not found in dbcs, skipped", spellId);
1420 continue;
1421 }
1422
1423 SpellInfo const* reqSpellInfo = GetSpellInfo(spellReq);
1424 if (!reqSpellInfo)
1425 {
1426 LOG_ERROR("sql.sql", "req_spell {} in `spell_required` table is not found in dbcs, skipped", spellReq);
1427 continue;
1428 }
1429
1430 if (GetFirstSpellInChain(spellId) == GetFirstSpellInChain(spellReq))
1431 {
1432 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);
1433 continue;
1434 }
1435
1436 if (IsSpellRequiringSpell(spellId, spellReq))
1437 {
1438 LOG_ERROR("sql.sql", "duplicated entry of req_spell {} and spell_id {} in `spell_required`, skipped", spellReq, spellId);
1439 continue;
1440 }
1441
1442 mSpellReq.insert (std::pair<uint32, uint32>(spellId, spellReq));
1443 mSpellsReqSpell.insert (std::pair<uint32, uint32>(spellReq, spellId));
1444 ++count;
1445
1446 // xinef: fill additionalTalentInfo data, currently Blessing of Sanctuary only
1447 if (GetTalentSpellCost(spellReq) > 0)
1448 mTalentSpellAdditionalSet.insert(spellId);
1449 } while (result->NextRow());
1450
1451 LOG_INFO("server.loading", ">> Loaded {} Spell Required Records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1452 LOG_INFO("server.loading", " ");
1453}
uint32 GetTalentSpellCost(uint32 spellId)
Definition DBCStores.cpp:698
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 ( )
3113{
3114 uint32 oldMSTime = getMSTime();
3115
3116 SpellInfo* spellInfo = nullptr;
3117 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3118 {
3119 spellInfo = mSpellInfoMap[i];
3120 if (!spellInfo)
3121 continue;
3122 spellInfo->_spellSpecific = spellInfo->LoadSpellSpecific();
3123 spellInfo->_auraState = spellInfo->LoadAuraState();
3124 }
3125
3126 LOG_INFO("server.loading", ">> Loaded Spell Specific And Aura State in {} ms", GetMSTimeDiffToNow(oldMSTime));
3127 LOG_INFO("server.loading", " ");
3128}
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 ( )
1219{
1220 // cleanup core data before reload - remove reference to ChainNode from SpellInfo
1222
1223 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1224 {
1225 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
1226 if (!talentInfo)
1227 continue;
1228
1229 SpellInfo const* lastSpell = nullptr;
1230 for (uint8 rank = MAX_TALENT_RANK - 1; rank > 0; --rank)
1231 {
1232 if (talentInfo->RankID[rank])
1233 {
1234 lastSpell = GetSpellInfo(talentInfo->RankID[rank]);
1235 break;
1236 }
1237 }
1238
1239 if (!lastSpell)
1240 continue;
1241
1242 SpellInfo const* firstSpell = GetSpellInfo(talentInfo->RankID[0]);
1243 if (!firstSpell)
1244 {
1245 LOG_ERROR("sql.sql", "SpellMgr::LoadSpellTalentRanks: First Rank Spell {} for TalentEntry {} does not exist.", talentInfo->RankID[0], i);
1246 continue;
1247 }
1248
1249 SpellInfo const* prevSpell = nullptr;
1250 for (uint8 rank = 0; rank < MAX_TALENT_RANK; ++rank)
1251 {
1252 uint32 spellId = talentInfo->RankID[rank];
1253 if (!spellId)
1254 break;
1255
1256 SpellInfo const* currentSpell = GetSpellInfo(spellId);
1257 if (!currentSpell)
1258 {
1259 LOG_ERROR("sql.sql", "SpellMgr::LoadSpellTalentRanks: Spell {} (Rank: {}) for TalentEntry {} does not exist.", spellId, rank + 1, i);
1260 break;
1261 }
1262
1263 SpellChainNode node;
1264 node.first = firstSpell;
1265 node.last = lastSpell;
1266 node.rank = rank + 1;
1267
1268 node.prev = prevSpell;
1269 node.next = node.rank < MAX_TALENT_RANK ? GetSpellInfo(talentInfo->RankID[node.rank]) : nullptr;
1270
1271 mSpellChains[spellId] = node;
1272 mSpellInfoMap[spellId]->ChainEntry = &mSpellChains[spellId];
1273
1274 prevSpell = currentSpell;
1275 }
1276 }
1277}
void UnloadSpellInfoChains()
Definition SpellMgr.cpp:1210
SpellInfo const * last
Definition SpellMgr.h:555
SpellInfo const * next
Definition SpellMgr.h:553
uint8 rank
Definition SpellMgr.h:556
SpellInfo const * first
Definition SpellMgr.h:554
SpellInfo const * prev
Definition SpellMgr.h:552

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

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

◆ LoadSpellThreats()

void SpellMgr::LoadSpellThreats ( )
2337{
2338 uint32 oldMSTime = getMSTime();
2339
2340 mSpellThreatMap.clear(); // need for reload case
2341
2342 // 0 1 2 3
2343 QueryResult result = WorldDatabase.Query("SELECT entry, flatMod, pctMod, apPctMod FROM spell_threat");
2344 if (!result)
2345 {
2346 LOG_WARN("server.loading", ">> Loaded 0 aggro generating spells. DB table `spell_threat` is empty.");
2347 LOG_INFO("server.loading", " ");
2348 return;
2349 }
2350
2351 uint32 count = 0;
2352 do
2353 {
2354 Field* fields = result->Fetch();
2355
2356 uint32 entry = fields[0].Get<uint32>();
2357
2358 if (!GetSpellInfo(entry))
2359 {
2360 LOG_ERROR("sql.sql", "Spell {} listed in `spell_threat` does not exist", entry);
2361 continue;
2362 }
2363
2364 SpellThreatEntry ste;
2365 ste.flatMod = fields[1].Get<int32>();
2366 ste.pctMod = fields[2].Get<float>();
2367 ste.apPctMod = fields[3].Get<float>();
2368
2369 mSpellThreatMap[entry] = ste;
2370 ++count;
2371 } while (result->NextRow());
2372
2373 LOG_INFO("server.loading", ">> Loaded {} SpellThreatEntries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2374 LOG_INFO("server.loading", " ");
2375}
Definition SpellMgr.h:375
int32 flatMod
Definition SpellMgr.h:376
float apPctMod
Definition SpellMgr.h:378
float pctMod
Definition SpellMgr.h:377

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

◆ SetSpellDifficultyId()

void SpellMgr::SetSpellDifficultyId ( uint32  spellId,
uint32  id 
)
534{
535 mSpellDifficultySearcherMap[spellId] = id;
536}

References mSpellDifficultySearcherMap.

◆ UnloadSpellInfoChains()

void SpellMgr::UnloadSpellInfoChains ( )
1211{
1212 for (SpellChainMap::iterator itr = mSpellChains.begin(); itr != mSpellChains.end(); ++itr)
1213 mSpellInfoMap[itr->first]->ChainEntry = nullptr;
1214
1215 mSpellChains.clear();
1216}

References mSpellChains, and mSpellInfoMap.

Referenced by LoadSpellTalentRanks().

◆ UnloadSpellInfoImplicitTargetConditionLists()

void SpellMgr::UnloadSpellInfoImplicitTargetConditionLists ( )
3104{
3105 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3106 {
3107 if (mSpellInfoMap[i])
3108 mSpellInfoMap[i]->_UnloadImplicitTargetConditionLists();
3109 }
3110}

References GetSpellInfoStoreSize(), and mSpellInfoMap.

◆ UnloadSpellInfoStore()

void SpellMgr::UnloadSpellInfoStore ( )
3096{
3097 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3098 delete mSpellInfoMap[i];
3099
3100 mSpellInfoMap.clear();
3101}

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

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