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

#include "SpellMgr.h"

Public Member Functions

CreatureImmunities const * GetCreatureImmunities (int32 creatureImmunitiesId) const
 
uint32 GetSpellDifficultyId (uint32 spellId) const
 
void SetSpellDifficultyId (uint32 spellId, uint32 id)
 
uint32 GetSpellIdForDifficulty (uint32 spellId, Unit const *caster) const
 
SpellInfo const * GetSpellForDifficultyFromSpell (SpellInfo const *spell, Unit const *caster) const
 
SpellChainNode const * GetSpellChainNode (uint32 spell_id) const
 
uint32 GetFirstSpellInChain (uint32 spell_id) const
 
uint32 GetLastSpellInChain (uint32 spell_id) const
 
uint32 GetNextSpellInChain (uint32 spell_id) const
 
uint32 GetPrevSpellInChain (uint32 spell_id) const
 
uint8 GetSpellRank (uint32 spell_id) const
 
uint32 GetSpellWithRank (uint32 spell_id, uint32 rank, bool strict=false) const
 
Acore::IteratorPair< SpellRequiredMap::const_iterator > GetSpellsRequiredForSpellBounds (uint32 spell_id) const
 
SpellsRequiringSpellMapBounds GetSpellsRequiringSpellBounds (uint32 spell_id) const
 
bool IsSpellRequiringSpell (uint32 spellid, uint32 req_spellid) const
 
SpellLearnSkillNode const * GetSpellLearnSkill (uint32 spell_id) const
 
std::vector< uint32GetSkillRankSpells (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
 
const std::vector< int32 > * GetSpellLinked (int32 spell_id) const
 
PetLevelupSpellSet const * GetPetLevelupSpellList (uint32 petFamily) const
 
PetDefaultSpellsEntry const * GetPetDefaultSpellsEntry (int32 id) const
 
SpellAreaMapBounds GetSpellAreaMapBounds (uint32 spell_id) const
 
SpellAreaForQuestMapBounds GetSpellAreaForQuestMapBounds (uint32 quest_id) const
 
SpellAreaForQuestMapBounds GetSpellAreaForQuestEndMapBounds (uint32 quest_id) const
 
SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds (uint32 spell_id) const
 
SpellAreaForAreaMapBounds GetSpellAreaForAreaMapBounds (uint32 area_id) const
 
SpellInfo const * GetSpellInfo (uint32 spellId) const
 
SpellInfo const * AssertSpellInfo (uint32 spellId) const
 
SpellInfo const * CheckSpellInfo (uint32 spellId) const
 
uint32 GetSpellInfoStoreSize () const
 
bool IsAdditionalTalentSpell (uint32 spellId) const
 
bool HasSpellCooldownOverride (uint32 spellId) const
 
SpellCooldownOverride GetSpellCooldownOverride (uint32 spellId) const
 
void UnloadSpellInfoChains ()
 
void LoadSpellTalentRanks ()
 
void LoadSpellRanks ()
 
void LoadSpellRequired ()
 
void LoadSpellLearnSkills ()
 
void LoadSpellTargetPositions ()
 
void 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 SpellMgrinstance ()
 
static bool ComputeIsSpellValid (SpellInfo const *spellInfo, bool msg=true)
 Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book, etc.
 
static bool IsSpellValid (SpellInfo const *spellInfo)
 
static bool CheckSpellValid (SpellInfo const *spellInfo, uint32 spellId, bool isTalent)
 

Private Member Functions

 SpellMgr ()
 
 ~SpellMgr ()
 
SpellInfo_GetSpellInfo (uint32 spellId)
 

Private Attributes

SpellDifficultySearcherMap mSpellDifficultySearcherMap
 
SpellChainMap mSpellChains
 
SpellsRequiringSpellMap mSpellsReqSpell
 
SpellRequiredMap mSpellReq
 
SpellLearnSkillMap mSpellLearnSkills
 
SpellTargetPositionMap mSpellTargetPositions
 
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:202
Definition Player.h:1084
uint32 GetHitMask() const
Definition Unit.h:465
SpellSchoolMask GetSchoolMask() const
Definition Unit.cpp:314
Unit * GetActionTarget() const
Definition Unit.h:460
uint32 GetSpellTypeMask() const
Definition Unit.h:463
uint32 GetTypeMask() const
Definition Unit.h:462
SpellInfo const * GetSpellInfo() const
Definition Unit.cpp:300
Unit * GetActor()
Definition Unit.h:459
uint32 GetSpellPhaseMask() const
Definition Unit.h:464
uint32 ManaCostPercentage
Definition SpellInfo.h:391
uint32 ManaCost
Definition SpellInfo.h:387

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

◆ CheckSpellGroupStackRules()

SpellGroupStackRule SpellMgr::CheckSpellGroupStackRules ( SpellInfo const *  spellInfo1,
SpellInfo const *  spellInfo2 
) const
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:1639
#define MAX_SPELL_EFFECTS
Definition DBCStructure.h:1637
std::uint8_t uint8
Definition Define.h:109
#define sObjectMgr
Definition ObjectMgr.h:1732
@ 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,
Unit 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
uint32 GetSpellIdForDifficulty(uint32 spellId, Unit const *caster) const
Definition SpellMgr.cpp:538
SpellInfo const * GetSpellInfo(uint32 spellId) const
Definition SpellMgr.h:742

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,
Unit 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:1772
int32 SpellID[MAX_DIFFICULTY]
Definition DBCStructure.h:1774

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

Referenced by GetSpellForDifficultyFromSpell().

◆ GetSpellInfo()

◆ GetSpellInfoStoreSize()

◆ GetSpellLearnSkill()

SpellLearnSkillNode const * SpellMgr::GetSpellLearnSkill ( uint32  spell_id) const
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()

const std::vector< int32 > * 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:98
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition Field.h:112
Definition AsioHacksFwd.h:47
std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition Tokenize.cpp:20
Definition SpellMgr.h: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:1841

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

◆ LoadPetDefaultSpells()

void SpellMgr::LoadPetDefaultSpells ( )
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:807
@ SPELL_EFFECT_SUMMON_PET
Definition SharedDefines.h:822
@ SPELL_EFFECT_SUMMON
Definition SharedDefines.h:794
static bool LoadPetDefaultSpells_helper(CreatureTemplate const *cInfo, PetDefaultSpellsEntry &petDefSpells)
Definition SpellMgr.cpp:2683
Definition DBCStructure.h:810
uint32 spellId[MAX_CREATURE_SPELL_DATA_SLOT]
Definition DBCStructure.h:812
Definition CreatureData.h:187
uint32 Entry
Definition CreatureData.h:188
uint32 spells[MAX_CREATURE_SPELLS]
Definition CreatureData.h:224
uint32 PetSpellDataId
Definition CreatureData.h:225
Definition SpellMgr.h: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
const std::vector< SkillLineAbilityEntry const * > & GetSkillLineAbilitiesBySkillLine(uint32 skillLine)
Definition DBCStores.cpp:916
DBCStorage< CreatureFamilyEntry > sCreatureFamilyStore(CreatureFamilyfmt)
std::multimap< uint32, uint32 > PetLevelupSpellSet
Definition SpellMgr.h:595
uint32 SpellLevel
Definition SpellInfo.h:384
Definition DBCStructure.h:754
uint32 ID
Definition DBCStructure.h:755
uint32 skillLine[2]
Definition DBCStructure.h:760
Definition DBCStructure.h:1598

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

◆ LoadSkillLineAbilityMap()

void SpellMgr::LoadSkillLineAbilityMap ( )
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:1601

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:350
@ CONFIG_ICC_BUFF_HORDE
Definition WorldConfig.h:349
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:2896

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

◆ LoadSpellGroupStackRules()

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

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

◆ LoadSpellInfoCustomAttributes()

void SpellMgr::LoadSpellInfoCustomAttributes ( )
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
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 for (count = 0; result->NextRow(); ++count)
3181 {
3182 Field const* fields = result->Fetch();
3183
3184 uint32 const spellId = fields[0].Get<uint32>();
3185 uint32 attributes = fields[1].Get<uint32>();
3186
3187 SpellInfo* spellInfo = _GetSpellInfo(spellId);
3188 if (!spellInfo)
3189 {
3190 LOG_INFO("sql.sql", "Table `spell_custom_attr` has wrong spell (spell_id: {}), ignored.", spellId);
3191 continue;
3192 }
3193
3194 if (attributes & SPELL_ATTR0_CU_NEGATIVE)
3195 {
3196 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3197 {
3198 if (spellInfo->Effects[i].IsEffect())
3199 {
3200 if ((attributes & (SPELL_ATTR0_CU_NEGATIVE_EFF0 << i)) && (attributes & (SPELL_ATTR0_CU_POSITIVE_EFF0 << i)))
3201 {
3202 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);
3204 }
3205 continue;
3206 }
3207
3208 if (attributes & (SPELL_ATTR0_CU_NEGATIVE_EFF0 << i))
3209 {
3210 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));
3211 attributes &= ~(SPELL_ATTR0_CU_NEGATIVE_EFF0 << i);
3212 }
3213 }
3214 }
3215
3216 if (attributes & SPELL_ATTR0_CU_POSITIVE)
3217 {
3218 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3219 {
3220 if (spellInfo->Effects[i].IsEffect())
3221 {
3222 continue;
3223 }
3224
3225 if ((attributes & (SPELL_ATTR0_CU_POSITIVE_EFF0 << i)))
3226 {
3227 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));
3228 attributes &= ~(SPELL_ATTR0_CU_POSITIVE_EFF0 << i);
3229 }
3230 }
3231 }
3232
3233 if ((attributes & SPELL_ATTR0_CU_FORCE_AURA_SAVING) && (attributes & SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED))
3234 {
3235 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);
3237 }
3238
3239 spellInfo->AttributesCu |= attributes;
3240 }
3241 LOG_INFO("server.loading", ">> Loaded {} spell custom attributes from DB in {} ms", count, GetMSTimeDiffToNow(customAttrTime));
3242 }
3243
3244 // xinef: create talent spells set
3245 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
3246 {
3247 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
3248 if (!talentInfo)
3249 continue;
3250
3251 for (uint8 j = 0; j < MAX_TALENT_RANK; j++)
3252 if (uint32 spellId = talentInfo->RankID[j])
3253 if (SpellInfo const* spellInfo = GetSpellInfo(spellId))
3254 for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
3255 if (spellInfo->Effects[k].Effect == SPELL_EFFECT_LEARN_SPELL)
3256 if (SpellInfo const* learnSpell = GetSpellInfo(spellInfo->Effects[k].TriggerSpell))
3257 if (learnSpell->IsRanked() && !learnSpell->HasAttribute(SpellAttr0(SPELL_ATTR0_PASSIVE | SPELL_ATTR0_DO_NOT_DISPLAY)))
3258 mTalentSpellAdditionalSet.insert(learnSpell->Id);
3259 }
3260
3261 SpellInfo* spellInfo = nullptr;
3262 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3263 {
3264 spellInfo = mSpellInfoMap[i];
3265 if (!spellInfo)
3266 continue;
3267
3268 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3269 {
3270 switch (spellInfo->Effects[j].ApplyAuraName)
3271 {
3273 {
3274 switch (spellInfo->Id)
3275 {
3276 // Exceptions
3277 case 44801: // Spectral Invisibility (Kalecgos, SWP)
3278 case 46021: // Spectral Realm (SWP)
3279 case 52951: // Chapel Invisibility (DK starting zone)
3280 case 43062: // Alpha Worg: Garwal's Invisibility
3281 break;
3282 default:
3284 break;
3285 }
3286 }
3287 break;
3294 break;
3295 default:
3296 break;
3297 }
3298
3299 switch (spellInfo->Effects[j].ApplyAuraName)
3300 {
3301 case SPELL_AURA_CONVERT_RUNE: // Can't be saved - aura handler relies on calculated amount and changes it
3302 case SPELL_AURA_OPEN_STABLE: // No point in saving this, since the stable dialog can't be open on aura load anyway.
3303 // Auras that require both caster & target to be in world cannot be saved
3311 break;
3312 default:
3313 break;
3314 }
3315
3316 switch (spellInfo->Effects[j].ApplyAuraName)
3317 {
3325 break;
3328 break;
3329 default:
3330 break;
3331 }
3332
3333 switch (spellInfo->Effects[j].Effect)
3334 {
3340 case SPELL_EFFECT_HEAL:
3342 break;
3353 break;
3356 case SPELL_EFFECT_JUMP:
3359 spellInfo->AttributesCu |= SPELL_ATTR0_CU_CHARGE;
3360 break;
3363 break;
3368 {
3369 // Only Enchanting profession enchant procs can stack when dual-wielding
3370 // DK runes (e.g., Unholy Strength) should refresh, not stack
3372 {
3373 uint32 enchantId = spellInfo->Effects[j].MiscValue;
3374 SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId);
3375 if (!enchant)
3376 break;
3377
3378 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
3379 {
3380 if (enchant->type[s] != ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL)
3381 continue;
3382
3383 SpellInfo* procInfo = _GetSpellInfo(enchant->spellid[s]);
3384 if (!procInfo)
3385 continue;
3386
3387 // if proced directly from enchantment, not via proc aura
3388 // NOTE: Enchant Weapon - Blade Ward also has proc aura spell and is proced directly
3389 // however its not expected to stack so this check is good
3391 continue;
3392
3394 }
3395 }
3396 break;
3397 }
3398 }
3399 }
3400
3401 // Xinef: spells ignoring hit result should not be binary
3402 if (!spellInfo->HasAttribute(SPELL_ATTR3_ALWAYS_HIT))
3403 {
3404 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3405 {
3406 if (spellInfo->Effects[j].Effect)
3407 {
3408 switch (spellInfo->Effects[j].Effect)
3409 {
3417 continue;
3426 if (spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
3427 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE_PERCENT ||
3428 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_DUMMY ||
3429 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH ||
3430 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_HEALTH_FUNNEL ||
3431 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DUMMY)
3432 continue;
3433 [[fallthrough]];
3434 default:
3435 if (!(spellInfo->Effects[j].CalcValue() ||
3436 ((spellInfo->Effects[j].Effect == SPELL_EFFECT_INTERRUPT_CAST || spellInfo->HasAttribute(SPELL_ATTR0_CU_DONT_BREAK_STEALTH)) &&
3438 continue;
3439
3440 if (spellInfo->Id == 69649 || spellInfo->Id == 71056 || spellInfo->Id == 71057 || spellInfo->Id == 71058 ||
3441 spellInfo->Id == 73061 || spellInfo->Id == 73062 || spellInfo->Id == 73063 || spellInfo->Id == 73064)
3442 continue;
3443
3444 if (spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && (spellInfo->SpellFamilyFlags[0] & 0x20)) // Frostbolt
3445 continue;
3446
3447 if (spellInfo->Id == 55095) // Frost Fever
3448 continue;
3449
3450 if (spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK &&
3451 ((spellInfo->SpellFamilyFlags[1] & 0x40000) || (spellInfo->SpellFamilyFlags[0] & 0x4000))) // Haunt/Drain Soul
3452 continue;
3453
3455 break;
3456 }
3457 }
3458 }
3459 }
3460
3461 // pussywizard:
3462 if ((spellInfo->SchoolMask & SPELL_SCHOOL_MASK_NORMAL) && (spellInfo->SchoolMask & SPELL_SCHOOL_MASK_MAGIC))
3463 {
3464 spellInfo->SchoolMask &= ~SPELL_SCHOOL_MASK_NORMAL;
3466 }
3467
3468 if (!spellInfo->_IsPositiveEffect(EFFECT_0, false))
3470
3471 if (!spellInfo->_IsPositiveEffect(EFFECT_1, false))
3473
3474 if (!spellInfo->_IsPositiveEffect(EFFECT_2, false))
3476
3477 if (spellInfo->SpellVisual[0] == 3879)
3479
3480 switch (spellInfo->SpellFamilyName)
3481 {
3483 // Shout
3484 if (spellInfo->SpellFamilyFlags[0] & 0x20000 || spellInfo->SpellFamilyFlags[1] & 0x20)
3486 break;
3487 case SPELLFAMILY_DRUID:
3488 // Roar
3489 if (spellInfo->SpellFamilyFlags[0] & 0x8)
3491 break;
3492 case SPELLFAMILY_HUNTER:
3493 // Aspects
3494 if (spellInfo->GetCategory() == 47)
3495 {
3497 }
3498 // Aimed Shot
3499 if (spellInfo->SpellFamilyFlags[0] & 0x00020000)
3500 {
3502 }
3503 break;
3504 default:
3505 break;
3506 }
3507
3508 switch (spellInfo->Id)
3509 {
3510 // Xinef: additional spells which should be binary
3511 case 45145: // Snake Trap Effect
3513 break;
3514 case 1776: // Gouge
3515 case 1777:
3516 case 8629:
3517 case 11285:
3518 case 11286:
3519 case 12540:
3520 case 13579:
3521 case 24698:
3522 case 28456:
3523 case 29425:
3524 case 34940:
3525 case 36862:
3526 case 38764:
3527 case 38863:
3528 case 52743: // Head Smack
3530 break;
3531 case 53: // Backstab
3532 case 2589:
3533 case 2590:
3534 case 2591:
3535 case 7159:
3536 case 8627:
3537 case 8721:
3538 case 11279:
3539 case 11280:
3540 case 11281:
3541 case 15582:
3542 case 15657:
3543 case 22416:
3544 case 25300:
3545 case 26863:
3546 case 37685:
3547 case 48656:
3548 case 48657:
3549 case 703: // Garrote
3550 case 8631:
3551 case 8632:
3552 case 8633:
3553 case 11289:
3554 case 11290:
3555 case 26839:
3556 case 26884:
3557 case 48675:
3558 case 48676:
3559 case 5221: // Shred
3560 case 6800:
3561 case 8992:
3562 case 9829:
3563 case 9830:
3564 case 27001:
3565 case 27002:
3566 case 48571:
3567 case 48572:
3568 case 8676: // Ambush
3569 case 8724:
3570 case 8725:
3571 case 11267:
3572 case 11268:
3573 case 11269:
3574 case 27441:
3575 case 48689:
3576 case 48690:
3577 case 48691:
3578 case 6785: // Ravage
3579 case 6787:
3580 case 9866:
3581 case 9867:
3582 case 27005:
3583 case 48578:
3584 case 48579:
3585 case 21987: // Lash of Pain
3586 case 23959: // Test Stab R50
3587 case 24825: // Test Backstab
3588 case 58563: // Assassinate Restless Lookout
3589 case 63124: // quest There's Something About the Squire (13654)
3591 break;
3592 case 26029: // Dark Glare
3593 case 43140: // Flame Breath
3594 case 43215: // Flame Breath
3595 case 70461: // Coldflame Trap
3596 case 72133: // Pain and Suffering
3597 case 73788: // Pain and Suffering
3598 case 73789: // Pain and Suffering
3599 case 73790: // Pain and Suffering
3600 case 63293: // Mimiron - spinning damage
3601 case 68873: // Wailing Souls
3602 case 70324: // Wailing Souls
3603 case 64619: // Ulduar, Mimiron, Emergency Fire Bot, Water Spray
3605 break;
3606 case 58690: // Cyanigosa, Tail Sweep
3607 case 59283: // Cyanigosa, Tail Sweep
3609 break;
3610 case 24340: // Meteor
3611 case 26558: // Meteor
3612 case 28884: // Meteor
3613 case 36837: // Meteor
3614 case 38903: // Meteor
3615 case 41276: // Meteor
3616 case 57467: // Meteor
3617 case 26789: // Shard of the Fallen Star
3618 case 31436: // Malevolent Cleave
3619 case 40810: // Saber Lash
3620 case 43267: // Saber Lash
3621 case 43268: // Saber Lash
3622 case 42384: // Brutal Swipe
3623 case 45150: // Meteor Slash
3624 case 64688: // Sonic Screech
3625 case 72373: // Shared Suffering
3626 case 71904: // Chaos Bane
3627 case 70492: // Ooze Eruption
3628 case 72505: // Ooze Eruption
3629 case 72624: // Ooze Eruption
3630 case 72625: // Ooze Eruption
3631 // ONLY SPELLS WITH SPELLFAMILY_GENERIC and EFFECT_SCHOOL_DAMAGE, OR WEAPON_DMG_X
3632 case 66809: // Meteor Fists
3633 case 67331: // Meteor Fists
3634 case 66765: // Meteor Fists
3635 case 67333: // Meteor Fists
3637 break;
3638 case 18500: // Wing Buffet
3639 case 33086: // Wild Bite
3640 case 49749: // Piercing Blow
3641 case 52890: // Penetrating Strike
3642 case 53454: // Impale
3643 case 59446: // Impale
3644 case 62383: // Shatter
3645 case 64777: // Machine Gun
3646 case 65239: // Machine Gun
3647 case 69293: // Wing Buffet
3648 case 74439: // Machine Gun
3649 // Trial of the Crusader, Jaraxxus, Shivan Slash
3650 case 66378:
3651 case 67097:
3652 case 67098:
3653 case 67099:
3654 // Trial of the Crusader, Anub'arak, Impale
3655 case 65919:
3656 case 67858:
3657 case 67859:
3658 case 67860:
3659 case 63278: // Mark of the Faceless (General Vezax)
3660 case 64125: // Ulduar, Yogg-Saron, Squeeze
3661 case 64126: // Ulduar, Yogg-Saron, Squeeze
3662 case 62544: // Thrust (Argent Tournament)
3663 case 64588: // Thrust (Argent Tournament)
3664 case 66479: // Thrust (Argent Tournament)
3665 case 68505: // Thrust (Argent Tournament)
3666 case 62709: // Counterattack! (Argent Tournament)
3667 case 62626: // Break-Shield (Argent Tournament, Player)
3668 case 64590: // Break-Shield (Argent Tournament, Player)
3669 case 64342: // Break-Shield (Argent Tournament, NPC)
3670 case 64686: // Break-Shield (Argent Tournament, NPC)
3671 case 65147: // Break-Shield (Argent Tournament, NPC)
3672 case 68504: // Break-Shield (Argent Tournament, NPC)
3673 case 62874: // Charge (Argent Tournament, Player)
3674 case 68498: // Charge (Argent Tournament, Player)
3675 case 64591: // Charge (Argent Tournament, Player)
3676 case 63003: // Charge (Argent Tournament, NPC)
3677 case 63010: // Charge (Argent Tournament, NPC)
3678 case 68321: // Charge (Argent Tournament, NPC)
3679 case 72255: // Mark of the Fallen Champion (Deathbringer Saurfang)
3680 case 72444: // Mark of the Fallen Champion (Deathbringer Saurfang)
3681 case 72445: // Mark of the Fallen Champion (Deathbringer Saurfang)
3682 case 72446: // Mark of the Fallen Champion (Deathbringer Saurfang)
3683 case 72409: // Rune of Blood (Deathbringer Saurfang)
3684 case 72447: // Rune of Blood (Deathbringer Saurfang)
3685 case 72448: // Rune of Blood (Deathbringer Saurfang)
3686 case 72449: // Rune of Blood (Deathbringer Saurfang)
3687 case 49882: // Leviroth Self-Impale
3688 case 62775: // Ulduar: XT-002 Tympanic Tamparum
3690 break;
3691 case 64422: // Sonic Screech (Auriaya)
3694 break;
3695 case 72293: // Mark of the Fallen Champion (Deathbringer Saurfang)
3696 case 72347: // Lock Players and Tap Chest (Gunship Battle)
3698 break;
3699 default:
3700 break;
3701 case 63675: // Improved Devouring Plague
3702 case 17962: // Conflagrate
3703 case 32593: // Earth Shield aura
3704 case 32594: // Earth Shield aura
3705 case 49283: // Earth Shield aura
3706 case 49284: // Earth Shield aura
3707 case 50526: // Wandering Plague
3708 case 53353: // Chimera Shot - Serpent trigger
3709 case 52752: // Ancestral Awakening Heal
3711 break;
3712 case 65280: // Ulduar, Hodir, Singed
3713 case 28969: // Naxxramas, Crypt Guard, Acid Spit (10 normal)
3714 case 56098: // Naxxramas, Crypt Guard, Acid Spit (25 normal)
3715 case 27891: // Naxxramas, Sludge Belcher, Acidic Sludge (10 normal)
3716 case 54331: // Naxxramas, Sludge Belcher, Acidic Sludge (25 normal)
3717 case 29325: // Naxxramas, Stoneskin Gargoyle, Acid Volley (10 normal)
3718 case 54714: // Naxxramas, Stoneskin Gargoyle, Acid Volley (25 normal)
3719 case 65775: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (10 normal)
3720 case 67861: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (25 normal)
3721 case 67862: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (10 heroic)
3722 case 67863: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (25 heroic)
3723 case 55604: // Naxxramas, Unrelenting Trainee, Death Plague (10 normal)
3724 case 55645: // Naxxramas, Unrelenting Trainee, Death Plague (25 normal)
3725 case 67721: // Anub'arak, Nerubian Burrower, Expose Weakness (normal)
3726 case 67847: // Anub'arak, Nerubian Burrower, Expose Weakness (heroic)
3727 case 64638: // Ulduar, Winter Jormungar, Acidic Bite
3728 case 71157: // Icecrown Citadel, Plagued Zombie, Infected Wound
3729 case 72963: // Icecrown Citadel, Rot Worm, Flesh Rot (10 normal)
3730 case 72964: // Icecrown Citadel, Rot Worm, Flesh Rot (25 normal)
3731 case 72965: // Icecrown Citadel, Rot Worm, Flesh Rot (10 heroic)
3732 case 72966: // Icecrown Citadel, Rot Worm, Flesh Rot (25 heroic)
3733 case 72465: // Icecrown Citadel, Sindragosa, Respite for a Tormented Soul (weekly quest)
3734 case 45271: // Sunwell, Eredar Twins encounter, Dark Strike
3735 case 45347: // Sunwell, Eredar Twins encounter, Dark Touched
3736 case 45348: // Sunwell, Eredar Twins encounter, Flame Touched
3737 case 35859: // The Eye, Nether Vapor
3738 case 40520: // Black Temple, Shade Soul Channel
3739 case 40327: // Black Temple, Atrophy
3740 case 38449: // Serpentshrine Cavern, Blessing of the Tides
3741 case 38044: // Serpentshrine Cavern, Surge
3742 case 74507: // Ruby Sanctum, Siphoned Might
3743 case 49381: // Drak'tharon Keep, Consume
3744 case 59805: // Drak'tharon Keep, Consume
3745 case 55093: // Gundrak, Grip of Slad'ran
3746 case 30659: // Hellfire Ramparts, Fel Infusion
3747 case 54314: // Azjol'Nerub Drain Power
3748 case 59354: // Azjol'Nerub Drain Power
3749 case 34655: // Snake Trap, Deadly Poison
3750 case 11971: // Sunder Armor
3751 case 58567: // Player Sunder Armor
3752 case 12579: // Player Winter's Chill
3753 case 29306: // Naxxramas(Gluth's Zombies): Infected Wound
3754 case 61920: // Ulduar(Spellbreaker): Supercharge
3755 case 63978: // Ulduar(Rubble): Stone Nova
3756 case 15502: // Sunder Armor
3758 break;
3759 case 43138: // North Fleet Reservist Kill Credit
3761 break;
3762 case 6197: // Eagle Eye
3764 break;
3765 case 50315: // Disco Ball
3767 break;
3768 case 14183: // Premeditation
3770 break;
3771
3772 // Xinef: NOT CUSTOM, cant add in DBC CORRECTION because i need to swap effects, too much work to do there
3773 // Envenom
3774 case 32645:
3775 case 32684:
3776 case 57992:
3777 case 57993:
3778 {
3779 SpellEffectInfo info = spellInfo->Effects[EFFECT_0];
3780 spellInfo->Effects[EFFECT_0] = spellInfo->Effects[EFFECT_2];
3781 spellInfo->Effects[EFFECT_2] = info;
3782 break;
3783 }
3784
3785 // Xinef: Cooldown overwrites
3786 // Burst of Speed
3787 case 57493:
3788 spellInfo->RecoveryTime = 60000;
3789 spellInfo->_requireCooldownInfo = true;
3790 break;
3791 // Strafe Jotunheim Building
3792 case 7769:
3793 spellInfo->RecoveryTime = 1500;
3794 spellInfo->_requireCooldownInfo = true;
3795 break;
3796 case 44535: // Spirit Heal, abilities also have no cost
3797 spellInfo->Effects[EFFECT_0].MiscValue = 127;
3798 break;
3799 case 45537: // Cosmetic - Lightning Beam Channel
3801 break;
3802 }
3803
3804 if (spellInfo->Speed > 0.0f)
3805 {
3806 if (SpellVisualEntry const* spellVisual = sSpellVisualStore.LookupEntry(spellInfo->SpellVisual[0]))
3807 {
3808 if (spellVisual->HasMissile)
3809 {
3810 if (spellVisual->MissileModel == -4 || spellVisual->MissileModel == -5)
3811 {
3813 }
3814 }
3815 }
3816 }
3817
3818 spellInfo->_InitializeExplicitTargetMask();
3819
3820 if (HasSpellCooldownOverride(spellInfo->Id))
3821 {
3822 SpellCooldownOverride spellOverride = GetSpellCooldownOverride(spellInfo->Id);
3823
3824 if (spellInfo->RecoveryTime != spellOverride.RecoveryTime)
3825 {
3826 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3827 }
3828
3829 if (spellInfo->CategoryRecoveryTime != spellOverride.CategoryRecoveryTime)
3830 {
3831 spellInfo->CategoryRecoveryTime = spellOverride.CategoryRecoveryTime;
3832 }
3833
3834 if (spellInfo->StartRecoveryTime != spellOverride.StartRecoveryTime)
3835 {
3836 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3837 }
3838
3839 if (spellInfo->StartRecoveryCategory != spellOverride.StartRecoveryCategory)
3840 {
3841 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3842 }
3843 }
3844
3845 sScriptMgr->OnLoadSpellCustomAttr(spellInfo);
3846 }
3847
3848 // Xinef: addition for binary spells, ommit spells triggering other spells
3849 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3850 {
3851 spellInfo = mSpellInfoMap[i];
3852 if (!spellInfo)
3853 continue;
3854
3855 if (!(spellInfo->AttributesCu & SPELL_ATTR0_CU_BINARY_SPELL))
3856 continue;
3857
3858 bool allNonBinary = true;
3859 bool overrideAttr = false;
3860 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3861 {
3862 if (spellInfo->Effects[j].ApplyAuraName && spellInfo->Effects[j].TriggerSpell)
3863 {
3864 switch (spellInfo->Effects[j].ApplyAuraName)
3865 {
3869 if (SpellInfo const* triggerSpell = GetSpellInfo(spellInfo->Effects[j].TriggerSpell))
3870 {
3871 overrideAttr = true;
3872 if (triggerSpell->AttributesCu & SPELL_ATTR0_CU_BINARY_SPELL)
3873 allNonBinary = false;
3874 }
3875 break;
3876 default:
3877 break;
3878 }
3879 }
3880 }
3881
3882 if (overrideAttr && allNonBinary)
3883 spellInfo->AttributesCu &= ~SPELL_ATTR0_CU_BINARY_SPELL;
3884 }
3885
3886 LOG_INFO("server.loading", ">> Loaded SpellInfo Custom Attributes in {} ms", GetMSTimeDiffToNow(oldMSTime));
3887 LOG_INFO("server.loading", " ");
3888}
@ ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL
Definition DBCEnums.h:367
DBCStorage< SpellVisualEntry > sSpellVisualStore(SpellVisualfmt)
DBCStorage< TalentEntry > sTalentStore(TalentEntryfmt)
#define MAX_TALENT_RANK
Definition DBCStructure.h:1918
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition DBCStructure.h:1838
#define sScriptMgr
Definition ScriptMgr.h:742
@ SPELL_EFFECT_ENERGIZE_PCT
Definition SharedDefines.h:903
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
Definition SharedDefines.h:801
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition SharedDefines.h:858
@ SPELL_EFFECT_ENCHANT_ITEM
Definition SharedDefines.h:819
@ SPELL_EFFECT_HEALTH_LEECH
Definition SharedDefines.h:775
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition SharedDefines.h:824
@ SPELL_EFFECT_HEAL
Definition SharedDefines.h:776
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
Definition SharedDefines.h:887
@ SPELL_EFFECT_TRIGGER_SPELL
Definition SharedDefines.h:830
@ SPELL_EFFECT_HEAL_MAX_HEALTH
Definition SharedDefines.h:833
@ SPELL_EFFECT_APPLY_AREA_AURA_PET
Definition SharedDefines.h:885
@ SPELL_EFFECT_PICKPOCKET
Definition SharedDefines.h:837
@ SPELL_EFFECT_HEAL_MECHANICAL
Definition SharedDefines.h:841
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
Definition SharedDefines.h:797
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
Definition SharedDefines.h:831
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition SharedDefines.h:783
@ SPELL_EFFECT_PERSISTENT_AREA_AURA
Definition SharedDefines.h:793
@ SPELL_EFFECT_ENERGIZE
Definition SharedDefines.h:796
@ SPELL_EFFECT_POWER_DRAIN
Definition SharedDefines.h:774
@ SPELL_EFFECT_SCHOOL_DAMAGE
Definition SharedDefines.h:768
@ SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
Definition SharedDefines.h:895
@ SPELL_EFFECT_HEAL_PCT
Definition SharedDefines.h:902
@ SPELL_EFFECT_INTERRUPT_CAST
Definition SharedDefines.h:834
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition SharedDefines.h:922
@ SPELL_EFFECT_APPLY_AREA_AURA_OWNER
Definition SharedDefines.h:909
@ SPELLFAMILY_WARLOCK
Definition SharedDefines.h:3789
@ SPELLFAMILY_DRUID
Definition SharedDefines.h:3791
SpellAttr0
Definition SharedDefines.h:369
@ SPELL_ATTR0_DO_NOT_DISPLAY
Definition SharedDefines.h:377
@ SKILL_ENCHANTING
Definition SharedDefines.h:3187
@ SPELL_SCHOOL_MASK_NORMAL
Definition SharedDefines.h:285
@ SPELL_AURA_PERIODIC_DAMAGE
Definition SpellAuraDefines.h:66
@ SPELL_AURA_PERIODIC_HEALTH_FUNNEL
Definition SpellAuraDefines.h:125
@ SPELL_AURA_MOD_POSSESS_PET
Definition SpellAuraDefines.h:191
@ SPELL_AURA_CONVERT_RUNE
Definition SpellAuraDefines.h:312
@ SPELL_AURA_MOD_FEAR
Definition SpellAuraDefines.h:70
@ SPELL_AURA_CONTROL_VEHICLE
Definition SpellAuraDefines.h:299
@ SPELL_AURA_MOD_INVISIBILITY
Definition SpellAuraDefines.h:81
@ SPELL_AURA_PERIODIC_DAMAGE_PERCENT
Definition SpellAuraDefines.h:152
@ SPELL_AURA_AOE_CHARM
Definition SpellAuraDefines.h:240
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE
Definition SpellAuraDefines.h:290
@ SPELL_AURA_MOD_INVISIBILITY_DETECT
Definition SpellAuraDefines.h:82
@ SPELL_AURA_WATER_BREATHING
Definition SpellAuraDefines.h:145
@ SPELL_AURA_PERIODIC_LEECH
Definition SpellAuraDefines.h:116
@ SPELL_AURA_OPEN_STABLE
Definition SpellAuraDefines.h:355
@ SPELL_AURA_MOD_CONFUSE
Definition SpellAuraDefines.h:68
@ SPELL_AURA_TRACK_CREATURES
Definition SpellAuraDefines.h:107
@ SPELL_AURA_MOD_POSSESS
Definition SpellAuraDefines.h:65
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT
Definition SpellAuraDefines.h:111
@ SPELL_AURA_BIND_SIGHT
Definition SpellAuraDefines.h:64
@ SPELL_ATTR0_CU_IGNORE_ARMOR
Definition SpellInfo.h:192
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition SpellInfo.h:193
@ SPELL_ATTR0_CU_ALLOW_INFLIGHT_TARGET
Definition SpellInfo.h:195
@ SPELL_ATTR0_CU_ENCHANT_PROC
Definition SpellInfo.h:177
@ SPELL_ATTR0_CU_NO_POSITIVE_TAKEN_BONUS
Definition SpellInfo.h:198
@ SPELL_ATTR0_CU_FORCE_SEND_CATEGORY_COOLDOWNS
Definition SpellInfo.h:205
@ SPELL_ATTR0_CU_DIRECT_DAMAGE
Definition SpellInfo.h:185
@ SPELL_ATTR0_CU_POSITIVE
Definition SpellInfo.h:212
@ SPELL_ATTR0_CU_FORCE_AURA_SAVING
Definition SpellInfo.h:206
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition SpellInfo.h:184
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition SpellInfo.h:183
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition SpellInfo.h:194
@ SPELL_ATTR0_CU_CONE_BACK
Definition SpellInfo.h:178
@ SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED
Definition SpellInfo.h:201
@ SPELL_ATTR0_CU_NEGATIVE_EFF2
Definition SpellInfo.h:191
@ SPELL_ATTR0_CU_AURA_CC
Definition SpellInfo.h:182
@ SPELL_ATTR0_CU_NEGATIVE_EFF1
Definition SpellInfo.h:190
@ SPELL_ATTR0_CU_CHARGE
Definition SpellInfo.h:186
@ SPELL_ATTR0_CU_NEGATIVE
Definition SpellInfo.h:211
@ SPELL_ATTR0_CU_NEEDS_AMMO_DATA
Definition SpellInfo.h:196
@ SPELL_ATTR0_CU_POSITIVE_EFF0
Definition SpellInfo.h:202
@ SPELL_ATTR0_CU_NEGATIVE_EFF0
Definition SpellInfo.h:189
@ SPELL_ATTR0_CU_BINARY_SPELL
Definition SpellInfo.h:197
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition SpellInfo.h:180
@ SPELL_ATTR0_CU_SCHOOLMASK_NORMAL_WITH_MAGIC
Definition SpellInfo.h:200
@ SPELL_ATTR0_CU_IGNORE_EVADE
Definition SpellInfo.h:188
@ SPELL_ATTR0_CU_PICKPOCKET
Definition SpellInfo.h:187
@ SPELL_ATTR0_CU_CONE_LINE
Definition SpellInfo.h:179
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition SpellInfo.h:181
bool IsPartOfSkillLine(uint32 skillId, uint32 spellId)
Definition SpellMgr.cpp:50
uint32 GetCategory() const
Definition SpellInfo.cpp:880
uint32 AttributesCu
Definition SpellInfo.h:356
bool _requireCooldownInfo
Definition SpellInfo.h:427
uint32 SchoolMask
Definition SpellInfo.h:416
std::array< uint32, 2 > SpellVisual
Definition SpellInfo.h:403
uint32 CategoryRecoveryTime
Definition SpellInfo.h:373
bool _IsPositiveEffect(uint8 effIndex, bool deep) const
Definition SpellInfo.cpp:3026
uint32 StartRecoveryTime
Definition SpellInfo.h:375
void _InitializeExplicitTargetMask()
Definition SpellInfo.cpp:2998
uint32 StartRecoveryCategory
Definition SpellInfo.h:374
uint32 AuraInterruptFlags
Definition SpellInfo.h:377
SpellCooldownOverride GetSpellCooldownOverride(uint32 spellId) const
Definition SpellMgr.cpp: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:1847
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition DBCStructure.h:1844
Definition DBCStructure.h:1871
Definition DBCStructure.h:1923
std::array< uint32, MAX_TALENT_RANK > RankID
Definition DBCStructure.h:1928

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

◆ LoadSpellInfoImmunities()

void SpellMgr::LoadSpellInfoImmunities ( )
3891{
3892 uint32 oldMSTime = getMSTime();
3893
3894 for (SpellInfo* spellInfo : mSpellInfoMap)
3895 {
3896 if (!spellInfo)
3897 continue;
3898 spellInfo->_LoadImmunityInfo();
3899 }
3900
3901 LOG_INFO("server.loading", ">> Loaded SpellInfo immunity infos in {} ms", GetMSTimeDiffToNow(oldMSTime));
3902}

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

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

◆ LoadSpellJumpDistances()

void SpellMgr::LoadSpellJumpDistances ( )
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:2903
uint32 ProcCharges
Definition SpellInfo.h:381
uint32 ProcFlags
Definition SpellInfo.h:379
uint32 ProcChance
Definition SpellInfo.h:380
Definition SpellMgr.h:286
uint32 SpellFamilyName
Definition SpellMgr.h:288
float ProcsPerMinute
Definition SpellMgr.h:296
Milliseconds Cooldown
Definition SpellMgr.h:298
uint32 Charges
Definition SpellMgr.h:299
uint32 AttributesMask
Definition SpellMgr.h:294
flag96 SpellFamilyMask
Definition SpellMgr.h:289
uint32 HitMask
Definition SpellMgr.h:293
uint32 SpellTypeMask
Definition SpellMgr.h:291
uint32 ProcFlags
Definition SpellMgr.h:290
uint32 SpellPhaseMask
Definition SpellMgr.h:292
uint32 SchoolMask
Definition SpellMgr.h:287
uint32 DisableEffectsMask
Definition SpellMgr.h:295
float Chance
Definition SpellMgr.h:297

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

◆ LoadSpellRanks()

void SpellMgr::LoadSpellRanks ( )
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:686
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:2054
AuraStateType LoadAuraState() const
Definition SpellInfo.cpp:1972
AuraStateType _auraState
Definition SpellInfo.h:422
SpellSpecificType _spellSpecific
Definition SpellInfo.h:423

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

◆ LoadSpellTalentRanks()

void SpellMgr::LoadSpellTalentRanks ( )
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:1325
Definition SpellMgr.h:386
float target_Z
Definition SpellMgr.h:390
uint32 target_mapId
Definition SpellMgr.h:387
float target_Y
Definition SpellMgr.h:389
float target_Orientation
Definition SpellMgr.h:391
float target_X
Definition SpellMgr.h:388

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

◆ LoadSpellThreats()

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