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

#include "SpellMgr.h"

Public Member Functions

CreatureImmunities const * GetCreatureImmunities (int32 creatureImmunitiesId) const
 
uint32 GetSpellDifficultyId (uint32 spellId) const
 
void SetSpellDifficultyId (uint32 spellId, uint32 id)
 
uint32 GetSpellIdForDifficulty (uint32 spellId, Unit const *caster) const
 
SpellInfo const * GetSpellForDifficultyFromSpell (SpellInfo const *spell, Unit const *caster) const
 
SpellChainNode const * GetSpellChainNode (uint32 spell_id) const
 
uint32 GetFirstSpellInChain (uint32 spell_id) const
 
uint32 GetLastSpellInChain (uint32 spell_id) const
 
uint32 GetNextSpellInChain (uint32 spell_id) const
 
uint32 GetPrevSpellInChain (uint32 spell_id) const
 
uint8 GetSpellRank (uint32 spell_id) const
 
uint32 GetSpellWithRank (uint32 spell_id, uint32 rank, bool strict=false) const
 
Acore::IteratorPair< SpellRequiredMap::const_iterator > GetSpellsRequiredForSpellBounds (uint32 spell_id) const
 
SpellsRequiringSpellMapBounds GetSpellsRequiringSpellBounds (uint32 spell_id) const
 
bool IsSpellRequiringSpell (uint32 spellid, uint32 req_spellid) const
 
SpellLearnSkillNode const * GetSpellLearnSkill (uint32 spell_id) const
 
SpellTargetPosition const * GetSpellTargetPosition (uint32 spell_id, SpellEffIndex effIndex) const
 
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
402{
403}

◆ ~SpellMgr()

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

References UnloadSpellInfoStore().

Member Function Documentation

◆ _GetSpellInfo()

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

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
758{
759 uint32 spellId = spellInfo->GetFirstRankSpell()->Id;
760 auto spellGroupBounds = GetSpellSpellGroupMapBounds(spellId);
761 // Find group with SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT if it belongs to one
762 for (auto itr = spellGroupBounds.first; itr != spellGroupBounds.second; ++itr)
763 {
764 SpellGroup group = itr->second;
765 auto found = mSpellSameEffectStack.find(group);
766 if (found != mSpellSameEffectStack.end())
767 {
768 // check auraTypes
769 if (!found->second.count(auraType))
770 continue;
771
772 // Put the highest amount in the map
773 auto groupItr = groups.find(group);
774 if (groupItr == groups.end())
775 groups.emplace(group, amount);
776 else
777 {
778 int32 curr_amount = groups[group];
779 // Take absolute value because this also counts for the highest negative aura
780 if (std::abs(curr_amount) < std::abs(amount))
781 groupItr->second = amount;
782 }
783 // return because a spell should be in only one SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT group per auraType
784 return true;
785 }
786 }
787 // Not in a SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT group, so return false
788 return false;
789}
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:823
SpellSpellGroupMapBounds GetSpellSpellGroupMapBounds(uint32 spell_id) const
Definition SpellMgr.cpp:708

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

◆ AssertSpellInfo()

SpellInfo const * SpellMgr::AssertSpellInfo ( uint32  spellId) const
inline
744 {
745 ASSERT(spellId < GetSpellInfoStoreSize());
746 SpellInfo const* spellInfo = mSpellInfoMap[spellId];
747 ASSERT(spellInfo);
748 return spellInfo;
749 }
#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
856{
857 // proc type doesn't match
858 if (!(eventInfo.GetTypeMask() & procEntry.ProcFlags))
859 return false;
860
861 // check XP or honor target requirement
862 if (procEntry.AttributesMask & PROC_ATTR_REQ_EXP_OR_HONOR)
863 if (Player* actor = eventInfo.GetActor()->ToPlayer())
864 if (eventInfo.GetActionTarget() && !actor->isHonorOrXPTarget(eventInfo.GetActionTarget()))
865 return false;
866
867 // check mana cost requirement (used by Clearcasting and similar effects)
868 if (procEntry.AttributesMask & PROC_ATTR_REQ_MANA_COST)
869 {
870 SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
871 if (!spellInfo || (!spellInfo->ManaCost && !spellInfo->ManaCostPercentage))
872 return false;
873 }
874
875 // always trigger for these types
877 return true;
878
879 // check school mask (if set) for other trigger types
880 if (procEntry.SchoolMask && !(eventInfo.GetSchoolMask() & procEntry.SchoolMask))
881 return false;
882
883 // check spell family name/flags (if set) for spells
884 if (eventInfo.GetTypeMask() & SPELL_PROC_FLAG_MASK)
885 if (SpellInfo const* eventSpellInfo = eventInfo.GetSpellInfo())
886 if (!eventSpellInfo->IsAffected(procEntry.SpellFamilyName, procEntry.SpellFamilyMask))
887 return false;
888
889 // check spell type mask (if set)
891 {
892 if (procEntry.SpellTypeMask && !(eventInfo.GetSpellTypeMask() & procEntry.SpellTypeMask))
893 return false;
894 }
895
896 // check spell phase mask
898 {
899 if (!(eventInfo.GetSpellPhaseMask() & procEntry.SpellPhaseMask))
900 return false;
901 }
902
903 // check hit mask (on taken hit or on done hit)
904 // For CAST phase with DONE flags, only check if HitMask is explicitly set (crit is pre-calculated for travel time spells)
905 if ((eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK) ||
906 ((eventInfo.GetTypeMask() & DONE_HIT_PROC_FLAG_MASK) &&
907 (!(eventInfo.GetSpellPhaseMask() & PROC_SPELL_PHASE_CAST) || procEntry.HitMask)))
908 {
909 uint32 hitMask = procEntry.HitMask;
910 // get default values if hit mask not set
911 if (!hitMask)
912 {
913 // for taken procs allow normal + critical hits by default
914 if (eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK)
916 // for done procs allow normal + critical + absorbs by default
917 else
919 }
920 if (!(eventInfo.GetHitMask() & hitMask))
921 return false;
922 }
923
924 return true;
925}
@ 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
792{
793 ASSERT(spellInfo1);
794 ASSERT(spellInfo2);
795
796 uint32 spell_id1 = spellInfo1->GetFirstRankSpell()->Id;
797 uint32 spell_id2 = spellInfo2->GetFirstRankSpell()->Id;
798
799 // find SpellGroups which are common for both spells
801 std::set<SpellGroup> groups;
802 for (SpellSpellGroupMap::const_iterator itr = spellGroup1.first; itr != spellGroup1.second; ++itr)
803 {
804 if (IsSpellMemberOfSpellGroup(spell_id2, itr->second))
805 {
806 bool add = true;
808 for (SpellGroupSpellMap::const_iterator itr2 = groupSpell.first; itr2 != groupSpell.second; ++itr2)
809 {
810 if (itr2->second < 0)
811 {
812 SpellGroup currGroup = (SpellGroup)abs(itr2->second);
813 if (IsSpellMemberOfSpellGroup(spell_id1, currGroup) && IsSpellMemberOfSpellGroup(spell_id2, currGroup))
814 {
815 add = false;
816 break;
817 }
818 }
819 }
820 if (add)
821 groups.insert(itr->second);
822 }
823 }
824
826
827 for (std::set<SpellGroup>::iterator itr = groups.begin(); itr!= groups.end(); ++itr)
828 {
829 SpellGroupStackMap::const_iterator found = mSpellGroupStack.find(*itr);
830 if (found != mSpellGroupStack.end())
831 rule = found->second;
832 if (rule)
833 break;
834 }
835 return rule;
836}
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:725
bool IsSpellMemberOfSpellGroup(uint32 spell_id, SpellGroup group_id) const
Definition SpellMgr.cpp:714
SpellGroupStackMap mSpellGroupStack
Definition SpellMgr.h:822

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

References GetSpellInfoStoreSize(), LOG_ERROR, and mSpellInfoMap.

◆ CheckSpellValid()

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

References DeleteSpellFromAllPlayers(), IsSpellValid(), and LOG_ERROR.

Referenced by Player::_addSpell(), and Player::addTalent().

◆ ComputeIsSpellValid()

bool SpellMgr::ComputeIsSpellValid ( SpellInfo const *  spellInfo,
bool  msg = true 
)
static

Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book, etc.

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

References ComputeIsSpellValid(), SpellInfo::Effects, SpellInfo::Id, SpellInfo::IsLootCrafting(), LOG_ERROR, MAX_SPELL_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::Reagent, sObjectMgr, SPELL_EFFECT_CREATE_ITEM, SPELL_EFFECT_CREATE_ITEM_2, SPELL_EFFECT_LEARN_SPELL, and sSpellMgr.

Referenced by ComputeIsSpellValid(), ObjectMgr::InitializeSpellInfoPrecomputedData(), and ObjectMgr::LoadQuests().

◆ GetCreatureImmunities()

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

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

◆ GetFirstSpellInChain()

uint32 SpellMgr::GetFirstSpellInChain ( uint32  spell_id) const
602{
603 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
604 return node->first->Id;
605
606 return spell_id;
607}
SpellChainNode const * GetSpellChainNode(uint32 spell_id) const
Definition SpellMgr.cpp:592
Definition SpellMgr.h: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
610{
611 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
612 return node->last->Id;
613
614 return spell_id;
615}

References GetSpellChainNode().

◆ GetNextSpellInChain()

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

References GetSpellChainNode().

◆ GetPetAura()

PetAura const * SpellMgr::GetPetAura ( uint32  spell_id,
uint8  eff 
) const
973{
974 SpellPetAuraMap::const_iterator itr = mSpellPetAuraMap.find((spell_id << 8) + eff);
975 if (itr != mSpellPetAuraMap.end())
976 return &itr->second;
977 else
978 return nullptr;
979}
SpellPetAuraMap mSpellPetAuraMap
Definition SpellMgr.h:829

References mSpellPetAuraMap.

◆ GetPetDefaultSpellsEntry()

PetDefaultSpellsEntry const * SpellMgr::GetPetDefaultSpellsEntry ( int32  id) const
1010{
1011 PetDefaultSpellsMap::const_iterator itr = mPetDefaultSpellsMap.find(id);
1012 if (itr != mPetDefaultSpellsMap.end())
1013 return &itr->second;
1014 return nullptr;
1015}
PetDefaultSpellsMap mPetDefaultSpellsMap
Definition SpellMgr.h:840

References mPetDefaultSpellsMap.

◆ GetPetLevelupSpellList()

PetLevelupSpellSet const * SpellMgr::GetPetLevelupSpellList ( uint32  petFamily) const
1001{
1002 PetLevelupSpellMap::const_iterator itr = mPetLevelupSpellMap.find(petFamily);
1003 if (itr != mPetLevelupSpellMap.end())
1004 return &itr->second;
1005 else
1006 return nullptr;
1007}
PetLevelupSpellMap mPetLevelupSpellMap
Definition SpellMgr.h:839

References mPetLevelupSpellMap.

◆ GetPrevSpellInChain()

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

References GetSpellChainNode().

◆ GetSetOfSpellsInSpellGroup() [1/2]

void SpellMgr::GetSetOfSpellsInSpellGroup ( SpellGroup  group_id,
std::set< uint32 > &  foundSpells 
) const
731{
732 std::set<SpellGroup> usedGroups;
733 GetSetOfSpellsInSpellGroup(group_id, foundSpells, usedGroups);
734}
void GetSetOfSpellsInSpellGroup(SpellGroup group_id, std::set< uint32 > &foundSpells) const
Definition SpellMgr.cpp:730

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
737{
738 if (usedGroups.find(group_id) != usedGroups.end())
739 return;
740 usedGroups.insert(group_id);
741
743 for (SpellGroupSpellMap::const_iterator itr = groupSpell.first; itr != groupSpell.second; ++itr)
744 {
745 if (itr->second < 0)
746 {
747 SpellGroup currGroup = (SpellGroup)abs(itr->second);
748 GetSetOfSpellsInSpellGroup(currGroup, foundSpells, usedGroups);
749 }
750 else
751 {
752 foundSpells.insert(itr->second);
753 }
754 }
755}

References GetSetOfSpellsInSpellGroup(), and GetSpellGroupSpellMapBounds().

◆ GetSkillLineAbilityMapBounds()

SkillLineAbilityMapBounds SpellMgr::GetSkillLineAbilityMapBounds ( uint32  spell_id) const
968{
969 return mSkillLineAbilityMap.equal_range(spell_id);
970}
SkillLineAbilityMap mSkillLineAbilityMap
Definition SpellMgr.h:838

References mSkillLineAbilityMap.

◆ GetSpellAreaForAreaMapBounds()

SpellAreaForAreaMapBounds SpellMgr::GetSpellAreaForAreaMapBounds ( uint32  area_id) const
1038{
1039 return mSpellAreaForAreaMap.equal_range(area_id);
1040}
SpellAreaForAreaMap mSpellAreaForAreaMap
Definition SpellMgr.h:837

References mSpellAreaForAreaMap.

◆ GetSpellAreaForAuraMapBounds()

SpellAreaForAuraMapBounds SpellMgr::GetSpellAreaForAuraMapBounds ( uint32  spell_id) const
1033{
1034 return mSpellAreaForAuraMap.equal_range(spell_id);
1035}
SpellAreaForAuraMap mSpellAreaForAuraMap
Definition SpellMgr.h:836

References mSpellAreaForAuraMap.

Referenced by LoadSpellAreas().

◆ GetSpellAreaForQuestEndMapBounds()

SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestEndMapBounds ( uint32  quest_id) const
1028{
1029 return mSpellAreaForQuestEndMap.equal_range(quest_id);
1030}
SpellAreaForQuestMap mSpellAreaForQuestEndMap
Definition SpellMgr.h:835

References mSpellAreaForQuestEndMap.

◆ GetSpellAreaForQuestMapBounds()

SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestMapBounds ( uint32  quest_id) const
1023{
1024 return mSpellAreaForQuestMap.equal_range(quest_id);
1025}
SpellAreaForQuestMap mSpellAreaForQuestMap
Definition SpellMgr.h:834

References mSpellAreaForQuestMap.

◆ GetSpellAreaMapBounds()

SpellAreaMapBounds SpellMgr::GetSpellAreaMapBounds ( uint32  spell_id) const
1018{
1019 return mSpellAreaMap.equal_range(spell_id);
1020}
SpellAreaMap mSpellAreaMap
Definition SpellMgr.h:833

References mSpellAreaMap.

Referenced by LoadSpellAreas().

◆ GetSpellBonusData()

SpellBonusEntry const * SpellMgr::GetSpellBonusData ( uint32  spellId) const
928{
929 // Lookup data
930 SpellBonusMap::const_iterator itr = mSpellBonusMap.find(spellId);
931 if (itr != mSpellBonusMap.end())
932 return &itr->second;
933 // Not found, try lookup for 1 spell rank if exist
934 if (uint32 rank_1 = GetFirstSpellInChain(spellId))
935 {
936 SpellBonusMap::const_iterator itr2 = mSpellBonusMap.find(rank_1);
937 if (itr2 != mSpellBonusMap.end())
938 return &itr2->second;
939 }
940 return nullptr;
941}
uint32 GetFirstSpellInChain(uint32 spell_id) const
Definition SpellMgr.cpp:601
SpellBonusMap mSpellBonusMap
Definition SpellMgr.h:826

References GetFirstSpellInChain(), and mSpellBonusMap.

◆ GetSpellChainNode()

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

References mSpellChains.

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

◆ GetSpellCone()

SpellCone const * SpellMgr::GetSpellCone ( uint32  spell_id) const
699{
700 spell_id = GetFirstSpellInChain(spell_id);
701 auto itr = mSpellCones.find(spell_id);
702 if (itr != mSpellCones.end())
703 return &itr->second;
704
705 return nullptr;
706}
SpellConeMap mSpellCones
Definition SpellMgr.h:819

References GetFirstSpellInChain(), and mSpellCones.

◆ GetSpellCooldownOverride()

SpellCooldownOverride SpellMgr::GetSpellCooldownOverride ( uint32  spellId) const
3070{
3071 auto range = mSpellCooldownOverrideMap.find(spellId);
3072 return range->second;
3073}
SpellCooldownOverrideMap mSpellCooldownOverrideMap
Definition SpellMgr.h:842

References mSpellCooldownOverrideMap.

Referenced by LoadSpellInfoCustomAttributes().

◆ GetSpellDifficultyId()

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

References mSpellDifficultySearcherMap.

Referenced by GetSpellIdForDifficulty().

◆ GetSpellEnchantProcEvent()

SpellEnchantProcEntry const * SpellMgr::GetSpellEnchantProcEvent ( uint32  enchId) const
982{
983 SpellEnchantProcEventMap::const_iterator itr = mSpellEnchantProcEventMap.find(enchId);
984 if (itr != mSpellEnchantProcEventMap.end())
985 return &itr->second;
986 return nullptr;
987}
SpellEnchantProcEventMap mSpellEnchantProcEventMap
Definition SpellMgr.h:831

References mSpellEnchantProcEventMap.

◆ GetSpellForDifficultyFromSpell()

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

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

◆ GetSpellGroupSpellMapBounds()

SpellGroupSpellMapBounds SpellMgr::GetSpellGroupSpellMapBounds ( SpellGroup  group_id) const
726{
727 return mSpellGroupSpell.equal_range(group_id);
728}
SpellGroupSpellMap mSpellGroupSpell
Definition SpellMgr.h:821

References mSpellGroupSpell.

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

◆ GetSpellGroupStackRule()

SpellGroupStackRule SpellMgr::GetSpellGroupStackRule ( SpellGroup  group_id) const
839{
840 SpellGroupStackMap::const_iterator itr = mSpellGroupStack.find(group);
841 if (itr != mSpellGroupStack.end())
842 return itr->second;
843
845}

References mSpellGroupStack, and SPELL_GROUP_STACK_RULE_DEFAULT.

◆ GetSpellIdForDifficulty()

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

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

Referenced by GetSpellForDifficultyFromSpell().

◆ GetSpellInfo()

◆ GetSpellInfoStoreSize()

◆ GetSpellLearnSkill()

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

References mSpellLearnSkills.

◆ GetSpellLinked()

const std::vector< int32 > * SpellMgr::GetSpellLinked ( int32  spell_id) const
995{
996 SpellLinkedMap::const_iterator itr = mSpellLinkedMap.find(spell_id);
997 return itr != mSpellLinkedMap.end() ? &(itr->second) : nullptr;
998}
SpellLinkedMap mSpellLinkedMap
Definition SpellMgr.h:830

References mSpellLinkedMap.

◆ GetSpellMixologyBonus()

float SpellMgr::GetSpellMixologyBonus ( uint32  spellId) const
959{
960 SpellMixologyMap::const_iterator itr = mSpellMixologyMap.find(spellId);
961 if (itr == mSpellMixologyMap.end())
962 return 30.0f;
963
964 return itr->second;
965}
SpellMixologyMap mSpellMixologyMap
Definition SpellMgr.h:828

References mSpellMixologyMap.

◆ GetSpellProcEntry()

SpellProcEntry const * SpellMgr::GetSpellProcEntry ( uint32  spellId) const
848{
849 SpellProcMap::const_iterator itr = mSpellProcMap.find(spellId);
850 if (itr != mSpellProcMap.end())
851 return &itr->second;
852 return nullptr;
853}
SpellProcMap mSpellProcMap
Definition SpellMgr.h:824

References mSpellProcMap.

◆ GetSpellRank()

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

References GetSpellChainNode().

◆ GetSpellSpellGroupMapBounds()

SpellSpellGroupMapBounds SpellMgr::GetSpellSpellGroupMapBounds ( uint32  spell_id) const
709{
710 spell_id = GetFirstSpellInChain(spell_id);
711 return mSpellSpellGroup.equal_range(spell_id);
712}
SpellSpellGroupMap mSpellSpellGroup
Definition SpellMgr.h:820

References GetFirstSpellInChain(), and mSpellSpellGroup.

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

◆ GetSpellsRequiredForSpellBounds()

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

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

◆ GetSpellsRequiringSpellBounds()

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

References mSpellsReqSpell.

Referenced by IsSpellRequiringSpell().

◆ GetSpellTargetPosition()

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

References mSpellTargetPositions.

◆ GetSpellThreatEntry()

SpellThreatEntry const * SpellMgr::GetSpellThreatEntry ( uint32  spellID) const
944{
945 SpellThreatMap::const_iterator itr = mSpellThreatMap.find(spellID);
946 if (itr != mSpellThreatMap.end())
947 return &itr->second;
948 else
949 {
950 uint32 firstSpell = GetFirstSpellInChain(spellID);
951 itr = mSpellThreatMap.find(firstSpell);
952 if (itr != mSpellThreatMap.end())
953 return &itr->second;
954 }
955 return nullptr;
956}
SpellThreatMap mSpellThreatMap
Definition SpellMgr.h:827

References GetFirstSpellInChain(), and mSpellThreatMap.

◆ GetSpellWithRank()

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

References GetSpellChainNode(), and GetSpellWithRank().

Referenced by GetSpellWithRank().

◆ HasSpellCooldownOverride()

bool SpellMgr::HasSpellCooldownOverride ( uint32  spellId) const
3065{
3066 return mSpellCooldownOverrideMap.find(spellId) != mSpellCooldownOverrideMap.end();
3067}

References mSpellCooldownOverrideMap.

Referenced by LoadSpellInfoCustomAttributes().

◆ instance()

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

References instance().

Referenced by instance().

◆ IsAdditionalTalentSpell()

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

References mTalentSpellAdditionalSet.

◆ IsArenaAllowedEnchancment()

bool SpellMgr::IsArenaAllowedEnchancment ( uint32  ench_id) const
990{
991 return mEnchantCustomAttr[ench_id];
992}
EnchantCustomAttribute mEnchantCustomAttr
Definition SpellMgr.h:832

References mEnchantCustomAttr.

◆ IsSpellMemberOfSpellGroup()

bool SpellMgr::IsSpellMemberOfSpellGroup ( uint32  spell_id,
SpellGroup  group_id 
) const
715{
717 for (SpellSpellGroupMap::const_iterator itr = spellGroup.first; itr != spellGroup.second; ++itr)
718 {
719 if (itr->second == group_id)
720 return true;
721 }
722 return false;
723}

References GetSpellSpellGroupMapBounds().

Referenced by CheckSpellGroupStackRules().

◆ IsSpellRequiringSpell()

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

References GetSpellsRequiringSpellBounds().

Referenced by LoadSpellRequired().

◆ IsSpellValid()

◆ LoadCreatureImmunities()

void SpellMgr::LoadCreatureImmunities ( )
64{
65 mCreatureImmunities.clear();
66 if (QueryResult result = WorldDatabase.Query("SELECT ID, SchoolMask, DispelTypeMask, MechanicsMask, Effects, Auras, ImmuneAoE, ImmuneChain FROM creature_immunities"))
67 {
68 do
69 {
70 Field* fields = result->Fetch();
71 int32 id = fields[0].Get<int32>();
72 uint8 school = fields[1].Get<uint8>();
73 uint16 dispelType = fields[2].Get<uint16>();
74 uint64 mechanics = fields[3].Get<uint64>();
76 immunities.School = school;
77 immunities.DispelType = dispelType;
78 immunities.Mechanic = mechanics;
79 immunities.ImmuneAoE = fields[6].Get<bool>();
80 immunities.ImmuneChain = fields[7].Get<bool>();
81 {
82 std::string effects = fields[4].Get<std::string>();
83 for (std::string_view token : Acore::Tokenize(effects, ',', false))
84 {
85 if (Optional<uint32> val = Acore::StringTo<uint32>(token); val && *val < uint32(TOTAL_SPELL_EFFECTS))
86 immunities.Effect.push_back(SpellEffects(*val));
87 else
88 LOG_ERROR("sql.sql", "Invalid effect type in `Effects` {} for creature immunities {}, skipped", token, id);
89 }
90 }
91 {
92 std::string auras = fields[5].Get<std::string>();
93 for (std::string_view token : Acore::Tokenize(auras, ',', false))
94 {
95 if (Optional<uint32> val = Acore::StringTo<uint32>(token); val && *val < TOTAL_AURAS)
96 immunities.Aura.push_back(AuraType(*val));
97 else
98 LOG_ERROR("sql.sql", "Invalid aura type in `Auras` {} for creature immunities {}, skipped", token, id);
99 }
100 }
101 } while (result->NextRow());
102 }
103}
std::shared_ptr< ResultSet > QueryResult
Definition DatabaseEnvFwd.h:27
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
Definition DatabaseEnv.cpp:20
std::uint64_t uint64
Definition Define.h:106
std::uint16_t uint16
Definition Define.h:108
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:24
SpellEffects
Definition SharedDefines.h:766
@ TOTAL_SPELL_EFFECTS
Definition SharedDefines.h:931
AuraType
Definition SpellAuraDefines.h:62
@ TOTAL_AURAS
Definition SpellAuraDefines.h:380
Class used to access individual fields of database query result.
Definition Field.h:98
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition Field.h:112
Definition AsioHacksFwd.h:47
std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition Tokenize.cpp:20
Definition SpellMgr.h: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
2479{
2480 uint32 oldMSTime = getMSTime();
2481
2482 uint32 size = sSpellItemEnchantmentStore.GetNumRows();
2483 mEnchantCustomAttr.resize(size);
2484
2485 for (uint32 i = 0; i < size; ++i)
2486 mEnchantCustomAttr[i] = 0;
2487
2488 uint32 count = 0;
2489 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2490 {
2491 SpellInfo const* spellInfo = GetSpellInfo(i);
2492 if (!spellInfo)
2493 continue;
2494
2496 // Xinef: commented second part, fixes warlock enchants like firestone, spellstone
2497 if (!spellInfo->HasAttribute(SPELL_ATTR2_ENCHANT_OWN_ITEM_ONLY)/* || !spellInfo->HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFTED)*/)
2498 continue;
2499
2500 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
2501 {
2502 if (spellInfo->Effects[j].Effect == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY)
2503 {
2504 uint32 enchId = spellInfo->Effects[j].MiscValue;
2505 SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchId);
2506 if (!ench)
2507 continue;
2508 mEnchantCustomAttr[enchId] = true;
2509 ++count;
2510 break;
2511 }
2512 }
2513 }
2514
2515 LOG_INFO("server.loading", ">> Loaded {} Custom Enchant Attributes in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2516 LOG_INFO("server.loading", " ");
2517}
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 ( )
2712{
2713 uint32 oldMSTime = getMSTime();
2714
2715 mPetDefaultSpellsMap.clear();
2716
2717 uint32 countCreature = 0;
2718 uint32 countData = 0;
2719
2720 CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
2721 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
2722 {
2723 if (!itr->second.PetSpellDataId)
2724 continue;
2725
2726 // for creature with PetSpellDataId get default pet spells from dbc
2727 CreatureSpellDataEntry const* spellDataEntry = sCreatureSpellDataStore.LookupEntry(itr->second.PetSpellDataId);
2728 if (!spellDataEntry)
2729 continue;
2730
2731 int32 petSpellsId = -int32(itr->second.PetSpellDataId);
2732 PetDefaultSpellsEntry petDefSpells;
2733 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2734 petDefSpells.spellid[j] = spellDataEntry->spellId[j];
2735
2736 if (LoadPetDefaultSpells_helper(&itr->second, petDefSpells))
2737 {
2738 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2739 ++countData;
2740 }
2741 }
2742
2743 LOG_INFO("server.loading", ">> Loaded Addition Spells For {} Pet Spell Data Entries in {} ms", countData, GetMSTimeDiffToNow(oldMSTime));
2744 LOG_INFO("server.loading", " ");
2745
2746 LOG_INFO("server.loading", "Loading Summonable Creature Templates...");
2747 oldMSTime = getMSTime();
2748
2749 // different summon spells
2750 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2751 {
2752 SpellInfo const* spellInfo = GetSpellInfo(i);
2753 if (!spellInfo)
2754 continue;
2755
2756 for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
2757 {
2758 if (spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON || spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON_PET)
2759 {
2760 uint32 creature_id = spellInfo->Effects[k].MiscValue;
2761 CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id);
2762 if (!cInfo)
2763 continue;
2764
2765 // already loaded
2766 if (cInfo->PetSpellDataId)
2767 continue;
2768
2769 // for creature without PetSpellDataId get default pet spells from creature_template
2770 int32 petSpellsId = cInfo->Entry;
2771 if (mPetDefaultSpellsMap.find(cInfo->Entry) != mPetDefaultSpellsMap.end())
2772 continue;
2773
2774 PetDefaultSpellsEntry petDefSpells;
2775 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2776 petDefSpells.spellid[j] = cInfo->spells[j];
2777
2778 if (LoadPetDefaultSpells_helper(cInfo, petDefSpells))
2779 {
2780 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2781 ++countCreature;
2782 }
2783 }
2784 }
2785 }
2786
2787 LOG_INFO("server.loading", ">> Loaded {} Summonable Creature emplates in {} ms", countCreature, GetMSTimeDiffToNow(oldMSTime));
2788 LOG_INFO("server.loading", " ");
2789}
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:2663
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 ( )
2618{
2619 uint32 oldMSTime = getMSTime();
2620
2621 mPetLevelupSpellMap.clear(); // need for reload case
2622
2623 uint32 count = 0;
2624 uint32 family_count = 0;
2625
2626 for (uint32 i = 0; i < sCreatureFamilyStore.GetNumRows(); ++i)
2627 {
2628 CreatureFamilyEntry const* creatureFamily = sCreatureFamilyStore.LookupEntry(i);
2629 if (!creatureFamily) // not exist
2630 continue;
2631
2632 for (uint8 j = 0; j < 2; ++j)
2633 {
2634 if (!creatureFamily->skillLine[j])
2635 continue;
2636
2637 for (SkillLineAbilityEntry const* skillLine : GetSkillLineAbilitiesBySkillLine(creatureFamily->skillLine[j]))
2638 {
2639 if (skillLine->AcquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN)
2640 continue;
2641
2642 SpellInfo const* spell = GetSpellInfo(skillLine->Spell);
2643 if (!spell) // not exist or triggered or talent
2644 continue;
2645
2646 if (!spell->SpellLevel)
2647 continue;
2648
2649 PetLevelupSpellSet& spellSet = mPetLevelupSpellMap[creatureFamily->ID];
2650 if (spellSet.empty())
2651 ++family_count;
2652
2653 spellSet.insert(PetLevelupSpellSet::value_type(spell->SpellLevel, spell->Id));
2654 ++count;
2655 }
2656 }
2657 }
2658
2659 LOG_INFO("server.loading", ">> Loaded {} Pet Levelup And Default Spells For {} Families in {} ms", count, family_count, GetMSTimeDiffToNow(oldMSTime));
2660 LOG_INFO("server.loading", " ");
2661}
@ 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 ( )
2394{
2395 uint32 oldMSTime = getMSTime();
2396
2397 mSkillLineAbilityMap.clear();
2398
2399 uint32 count = 0;
2400
2401 for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); ++i)
2402 {
2403 SkillLineAbilityEntry const* SkillInfo = sSkillLineAbilityStore.LookupEntry(i);
2404 if (!SkillInfo)
2405 continue;
2406
2407 mSkillLineAbilityMap.insert(SkillLineAbilityMap::value_type(SkillInfo->Spell, SkillInfo));
2408 ++count;
2409 }
2410
2411 LOG_INFO("server.loading", ">> Loaded {} SkillLineAbility MultiMap Data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2412 LOG_INFO("server.loading", " ");
2413}
DBCStorage< SkillLineAbilityEntry > sSkillLineAbilityStore(SkillLineAbilityfmt)
uint32 Spell
Definition DBCStructure.h:1601

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

◆ LoadSpellAreas()

void SpellMgr::LoadSpellAreas ( )
2792{
2793 uint32 oldMSTime = getMSTime();
2794
2795 mSpellAreaMap.clear(); // need for reload case
2796 mSpellAreaForQuestMap.clear();
2798 mSpellAreaForAuraMap.clear();
2799
2800 // 0 1 2 3 4 5 6 7 8 9
2801 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");
2802
2803 if (!result)
2804 {
2805 LOG_WARN("server.loading", ">> Loaded 0 spell area requirements. DB table `spell_area` is empty.");
2806 LOG_INFO("server.loading", " ");
2807 return;
2808 }
2809
2810 uint32 count = 0;
2811 do
2812 {
2813 Field* fields = result->Fetch();
2814
2815 uint32 spell = fields[0].Get<uint32>();
2816 SpellArea spellArea;
2817 spellArea.spellId = spell;
2818 spellArea.areaId = fields[1].Get<uint32>();
2819 spellArea.questStart = fields[2].Get<uint32>();
2820 spellArea.questStartStatus = fields[3].Get<uint32>();
2821 spellArea.questEndStatus = fields[4].Get<uint32>();
2822 spellArea.questEnd = fields[5].Get<uint32>();
2823 spellArea.auraSpell = fields[6].Get<int32>();
2824 spellArea.raceMask = fields[7].Get<uint32>();
2825 spellArea.gender = Gender(fields[8].Get<uint8>());
2826 spellArea.autocast = fields[9].Get<bool>();
2827
2828 if (SpellInfo const* spellInfo = GetSpellInfo(spell))
2829 {
2830 if (spellArea.autocast)
2831 const_cast<SpellInfo*>(spellInfo)->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
2832 }
2833 else
2834 {
2835 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` does not exist", spell);
2836 continue;
2837 }
2838
2839 {
2840 bool ok = true;
2841 SpellAreaMapBounds sa_bounds = GetSpellAreaMapBounds(spellArea.spellId);
2842 for (SpellAreaMap::const_iterator itr = sa_bounds.first; itr != sa_bounds.second; ++itr)
2843 {
2844 if (spellArea.spellId != itr->second.spellId)
2845 continue;
2846 if (spellArea.areaId != itr->second.areaId)
2847 continue;
2848 if (spellArea.questStart != itr->second.questStart)
2849 continue;
2850 if (spellArea.auraSpell != itr->second.auraSpell)
2851 continue;
2852 if ((spellArea.raceMask & itr->second.raceMask) == 0)
2853 continue;
2854 if (spellArea.gender != itr->second.gender)
2855 continue;
2856
2857 // duplicate by requirements
2858 ok = false;
2859 break;
2860 }
2861
2862 if (!ok)
2863 {
2864 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` already listed with similar requirements.", spell);
2865 continue;
2866 }
2867 }
2868
2869 if (spellArea.areaId && !sAreaTableStore.LookupEntry(spellArea.areaId))
2870 {
2871 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong area ({}) requirement", spell, spellArea.areaId);
2872 continue;
2873 }
2874
2875 if (spellArea.questStart && !sObjectMgr->GetQuestTemplate(spellArea.questStart))
2876 {
2877 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong start quest ({}) requirement", spell, spellArea.questStart);
2878 continue;
2879 }
2880
2881 if (spellArea.questEnd)
2882 {
2883 if (!sObjectMgr->GetQuestTemplate(spellArea.questEnd))
2884 {
2885 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong end quest ({}) requirement", spell, spellArea.questEnd);
2886 continue;
2887 }
2888 }
2889
2890 if (spellArea.auraSpell)
2891 {
2892 SpellInfo const* spellInfo = GetSpellInfo(std::abs(spellArea.auraSpell));
2893 if (!spellInfo)
2894 {
2895 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong aura spell ({}) requirement", spell, std::abs(spellArea.auraSpell));
2896 continue;
2897 }
2898
2899 if (uint32(std::abs(spellArea.auraSpell)) == spellArea.spellId)
2900 {
2901 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement for itself", spell, std::abs(spellArea.auraSpell));
2902 continue;
2903 }
2904
2905 // not allow autocast chains by auraSpell field (but allow use as alternative if not present)
2906 if (spellArea.autocast && spellArea.auraSpell > 0)
2907 {
2908 bool chain = false;
2909 SpellAreaForAuraMapBounds saBound = GetSpellAreaForAuraMapBounds(spellArea.spellId);
2910 for (SpellAreaForAuraMap::const_iterator itr = saBound.first; itr != saBound.second; ++itr)
2911 {
2912 if (itr->second->autocast && itr->second->auraSpell > 0)
2913 {
2914 chain = true;
2915 break;
2916 }
2917 }
2918
2919 if (chain)
2920 {
2921 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement that itself autocast from aura", spell, spellArea.auraSpell);
2922 continue;
2923 }
2924
2925 SpellAreaMapBounds saBound2 = GetSpellAreaMapBounds(spellArea.auraSpell);
2926 for (SpellAreaMap::const_iterator itr2 = saBound2.first; itr2 != saBound2.second; ++itr2)
2927 {
2928 if (itr2->second.autocast && itr2->second.auraSpell > 0)
2929 {
2930 chain = true;
2931 break;
2932 }
2933 }
2934
2935 if (chain)
2936 {
2937 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement that itself autocast from aura", spell, spellArea.auraSpell);
2938 continue;
2939 }
2940 }
2941 }
2942
2943 if (spellArea.raceMask && (spellArea.raceMask & sRaceMgr->GetPlayableRaceMask()) == 0)
2944 {
2945 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong race mask ({}) requirement", spell, spellArea.raceMask);
2946 continue;
2947 }
2948
2949 if (spellArea.gender != GENDER_NONE && spellArea.gender != GENDER_FEMALE && spellArea.gender != GENDER_MALE)
2950 {
2951 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong gender ({}) requirement", spell, spellArea.gender);
2952 continue;
2953 }
2954
2955 SpellArea const* sa = &mSpellAreaMap.insert(SpellAreaMap::value_type(spell, spellArea))->second;
2956
2957 // for search by current zone/subzone at zone/subzone change
2958 if (spellArea.areaId)
2959 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(spellArea.areaId, sa));
2960
2961 // for search at quest start/reward
2962 if (spellArea.questStart)
2963 mSpellAreaForQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa));
2964
2965 // for search at quest start/reward
2966 if (spellArea.questEnd)
2967 mSpellAreaForQuestEndMap.insert(SpellAreaForQuestMap::value_type(spellArea.questEnd, sa));
2968
2969 // for search at aura apply
2970 if (spellArea.auraSpell)
2971 mSpellAreaForAuraMap.insert(SpellAreaForAuraMap::value_type(std::abs(spellArea.auraSpell), sa));
2972
2973 ++count;
2974 } while (result->NextRow());
2975
2976 if (sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE) > 0)
2977 {
2978 LOG_INFO("server.loading", ">> Using ICC Buff Horde: {}", sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE));
2979 SpellArea spellAreaICCBuffHorde = { sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE), ICC_AREA, 0, 0, 0, ICC_RACEMASK_HORDE, Gender(2), 64, 11, 1 };
2980 SpellArea const* saICCBuffHorde = &mSpellAreaMap.insert(SpellAreaMap::value_type(sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE), spellAreaICCBuffHorde))->second;
2981 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(ICC_AREA, saICCBuffHorde));
2982 ++count;
2983 }
2984 else
2985 LOG_INFO("server.loading", ">> ICC Buff Horde: disabled");
2986
2987 if (sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE) > 0)
2988 {
2989 LOG_INFO("server.loading", ">> Using ICC Buff Alliance: {}", sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE));
2990 SpellArea spellAreaICCBuffAlliance = { sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE), ICC_AREA, 0, 0, 0, ICC_RACEMASK_ALLIANCE, Gender(2), 64, 11, 1 };
2991 SpellArea const* saICCBuffAlliance = &mSpellAreaMap.insert(SpellAreaMap::value_type(sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE), spellAreaICCBuffAlliance))->second;
2992 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(ICC_AREA, saICCBuffAlliance));
2993 ++count;
2994 }
2995 else
2996 LOG_INFO("server.loading", ">> ICC Buff Alliance: disabled");
2997
2998 LOG_INFO("server.loading", ">> Loaded {} Spell Area Requirements in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2999 LOG_INFO("server.loading", " ");
3000}
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:349
@ CONFIG_ICC_BUFF_HORDE
Definition WorldConfig.h:348
SpellAreaMapBounds GetSpellAreaMapBounds(uint32 spell_id) const
Definition SpellMgr.cpp:1017
SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds(uint32 spell_id) const
Definition SpellMgr.cpp:1032
#define sWorld
Definition World.h:317
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 ( )
2276{
2277 uint32 oldMSTime = getMSTime();
2278
2279 mSpellBonusMap.clear(); // need for reload case
2280
2281 // 0 1 2 3 4
2282 QueryResult result = WorldDatabase.Query("SELECT entry, direct_bonus, dot_bonus, ap_bonus, ap_dot_bonus FROM spell_bonus_data");
2283 if (!result)
2284 {
2285 LOG_WARN("server.loading", ">> Loaded 0 spell bonus data. DB table `spell_bonus_data` is empty.");
2286 LOG_INFO("server.loading", " ");
2287 return;
2288 }
2289
2290 uint32 count = 0;
2291 do
2292 {
2293 Field* fields = result->Fetch();
2294 uint32 entry = fields[0].Get<uint32>();
2295
2296 SpellInfo const* spell = GetSpellInfo(entry);
2297 if (!spell)
2298 {
2299 LOG_ERROR("sql.sql", "Spell {} listed in `spell_bonus_data` does not exist", entry);
2300 continue;
2301 }
2302
2303 SpellBonusEntry& sbe = mSpellBonusMap[entry];
2304 sbe.direct_damage = fields[1].Get<float>();
2305 sbe.dot_damage = fields[2].Get<float>();
2306 sbe.ap_bonus = fields[3].Get<float>();
2307 sbe.ap_dot_bonus = fields[4].Get<float>();
2308
2309 ++count;
2310 } while (result->NextRow());
2311
2312 LOG_INFO("server.loading", ">> Loaded {} Extra Spell Bonus Data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2313 LOG_INFO("server.loading", " ");
2314}
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 ( )
1594{
1595 uint32 oldMSTime = getMSTime();
1596
1597 mSpellCones.clear(); // need for reload case
1598
1599 // 0 1
1600 QueryResult result = WorldDatabase.Query("SELECT ID, ConeDegrees FROM spell_cone");
1601
1602 if (!result)
1603 {
1604 LOG_WARN("server.loading", ">> Loaded 0 spell cone definitions. DB table `spell_cone` is empty.");
1605 LOG_INFO("server.loading", " ");
1606 return;
1607 }
1608
1609 uint32 count = 0;
1610 do
1611 {
1612 Field* fields = result->Fetch();
1613
1614 uint32 spellId = fields[0].Get<uint32>();
1615 int16 coneDeg = fields[1].Get<int16>();
1616
1617 SpellInfo const* spellInfo = GetSpellInfo(spellId);
1618 if (!spellInfo)
1619 {
1620 LOG_ERROR("sql.sql", "Spell (ID:{}) listed in `spell_cone` does not exist.", spellId);
1621 continue;
1622 }
1623
1624 if (coneDeg < -360 || coneDeg > 360)
1625 {
1626 LOG_ERROR("sql.sql", "Spell (Id: {}) cone degrees {} out of range (-360..360).", spellId, coneDeg);
1627 continue;
1628 }
1629
1630 uint32 firstRankId = GetFirstSpellInChain(spellId);
1631 SpellInfo const* firstSpellInfo = GetSpellInfo(firstRankId);
1632
1633 SpellInfo const* checkInfo = firstSpellInfo ? firstSpellInfo : spellInfo;
1634
1635 bool hasCone = false;
1636 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1637 {
1638 if (checkInfo->Effects[i].TargetA.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CONE ||
1639 checkInfo->Effects[i].TargetB.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CONE)
1640 {
1641 hasCone = true;
1642 break;
1643 }
1644 }
1645
1646 if (!hasCone)
1647 {
1648 LOG_ERROR("sql.sql", "Spell (ID:{}) listed in `spell_cone` does not have a cone implicit target.", spellId);
1649 continue;
1650 }
1651
1652 if (firstRankId != spellId)
1653 LOG_INFO("server.loading", "Spell (ID:{}) listed in `spell_cone` is not first rank; mapping to first rank {}.", spellId, firstRankId);
1654
1655 SpellCone sc{};
1656 sc.cone_degrees = coneDeg;
1657
1658 // Avoid overwriting an existing first-rank entry with conflicting values
1659 auto itr = mSpellCones.find(firstRankId);
1660 if (itr != mSpellCones.end())
1661 {
1662 if (itr->second.cone_degrees != sc.cone_degrees)
1663 LOG_ERROR("sql.sql",
1664 "Conflicting `spell_cone` entries for first-rank spell ID {}: {} vs {}. Keeping first value.",
1665 firstRankId,
1666 itr->second.cone_degrees,
1667 sc.cone_degrees);
1668 }
1669 else
1670 {
1671 mSpellCones[firstRankId] = sc;
1672 ++count;
1673 }
1674 } while (result->NextRow());
1675
1676 LOG_INFO("server.loading", ">> Loaded {} Spell Cone definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1677 LOG_INFO("server.loading", " ");
1678}
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 ( )
3034{
3035 uint32 oldMSTime = getMSTime();
3036
3038
3039 QueryResult result = WorldDatabase.Query("SELECT Id, RecoveryTime, CategoryRecoveryTime, StartRecoveryTime, StartRecoveryCategory FROM spell_cooldown_overrides");
3040
3041 uint32 count = 0;
3042
3043 if (result)
3044 {
3045 do
3046 {
3047 Field* fields = result->Fetch();
3048 SpellCooldownOverride spellCooldown;
3049 uint32 spellId = fields[0].Get<uint32>();
3050 spellCooldown.RecoveryTime = fields[1].Get<uint32>();
3051 spellCooldown.CategoryRecoveryTime = fields[2].Get<uint32>();
3052 spellCooldown.StartRecoveryTime = fields[3].Get<uint32>();
3053 spellCooldown.StartRecoveryCategory = fields[4].Get<uint32>();
3054 mSpellCooldownOverrideMap[spellId] = spellCooldown;
3055
3056 ++count;
3057 } while (result->NextRow());
3058 }
3059
3060 LOG_INFO("server.loading", ">> Loaded {} Spell Cooldown Overrides entries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3061 LOG_INFO("server.loading", " ");
3062}
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 ( )
2520{
2521 uint32 oldMSTime = getMSTime();
2522
2523 mSpellEnchantProcEventMap.clear(); // need for reload case
2524
2525 // 0 1 2 3 4
2526 QueryResult result = WorldDatabase.Query("SELECT entry, customChance, PPMChance, procEx, attributeMask FROM spell_enchant_proc_data");
2527 if (!result)
2528 {
2529 LOG_WARN("server.loading", ">> Loaded 0 spell enchant proc event conditions. DB table `spell_enchant_proc_data` is empty.");
2530 LOG_INFO("server.loading", " ");
2531 return;
2532 }
2533
2534 uint32 count = 0;
2535 do
2536 {
2537 Field* fields = result->Fetch();
2538
2539 uint32 enchantId = fields[0].Get<uint32>();
2540
2541 SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchantId);
2542 if (!ench)
2543 {
2544 LOG_ERROR("sql.sql", "Enchancment {} listed in `spell_enchant_proc_data` does not exist", enchantId);
2545 continue;
2546 }
2547
2549
2550 spe.customChance = fields[1].Get<uint32>();
2551 spe.PPMChance = fields[2].Get<float>();
2552 spe.procEx = fields[3].Get<uint32>();
2553 spe.attributeMask = fields[4].Get<uint32>();
2554
2555 mSpellEnchantProcEventMap[enchantId] = spe;
2556
2557 ++count;
2558 } while (result->NextRow());
2559
2560 LOG_INFO("server.loading", ">> Loaded {} Enchant Proc Data Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2561 LOG_INFO("server.loading", " ");
2562}
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 ( )
1681{
1682 uint32 oldMSTime = getMSTime();
1683
1684 mSpellSpellGroup.clear(); // need for reload case
1685 mSpellGroupSpell.clear();
1686
1687 // 0 1
1688 QueryResult result = WorldDatabase.Query("SELECT id, spell_id FROM spell_group");
1689 if (!result)
1690 {
1691 LOG_WARN("server.loading", ">> Loaded 0 spell group definitions. DB table `spell_group` is empty.");
1692 LOG_INFO("server.loading", " ");
1693 return;
1694 }
1695
1696 std::set<uint32> groups;
1697 uint32 count = 0;
1698 do
1699 {
1700 Field* fields = result->Fetch();
1701
1702 uint32 group_id = fields[0].Get<uint32>();
1703 if (group_id <= SPELL_GROUP_DB_RANGE_MIN && group_id >= SPELL_GROUP_CORE_RANGE_MAX)
1704 {
1705 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group` is in core range, but is not defined in core!", group_id);
1706 continue;
1707 }
1708 int32 spell_id = fields[1].Get<int32>();
1709
1710 groups.insert(group_id);
1711 mSpellGroupSpell.emplace(SpellGroup(group_id), spell_id);
1712
1713 } while (result->NextRow());
1714
1715 for (auto itr = mSpellGroupSpell.begin(); itr!= mSpellGroupSpell.end();)
1716 {
1717 if (itr->second < 0)
1718 {
1719 if (groups.find(abs(itr->second)) == groups.end())
1720 {
1721 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group` does not exist", abs(itr->second));
1722 itr = mSpellGroupSpell.erase(itr);
1723 }
1724 else
1725 ++itr;
1726 }
1727 else
1728 {
1729 SpellInfo const* spellInfo = GetSpellInfo(itr->second);
1730 if (!spellInfo)
1731 {
1732 LOG_ERROR("sql.sql", "Spell {} listed in `spell_group` does not exist", itr->second);
1733 itr = mSpellGroupSpell.erase(itr);
1734 }
1735 else if (spellInfo->GetRank() > 1)
1736 {
1737 LOG_ERROR("sql.sql", "Spell {} listed in `spell_group` is not first rank of spell.", itr->second);
1738 itr = mSpellGroupSpell.erase(itr);
1739 }
1740 else
1741 ++itr;
1742 }
1743 }
1744
1745 for (auto groupItr = groups.begin(); groupItr != groups.end(); ++groupItr)
1746 {
1747 std::set<uint32> spells;
1749
1750 for (auto spellItr = spells.begin(); spellItr != spells.end(); ++spellItr)
1751 {
1752 ++count;
1753 mSpellSpellGroup.emplace(*spellItr, SpellGroup(*groupItr));
1754 }
1755 }
1756
1757 LOG_INFO("server.loading", ">> Loaded {} spell group Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1758 LOG_INFO("server.loading", " ");
1759}
@ 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 ( )
1762{
1763 uint32 oldMSTime = getMSTime();
1764
1765 mSpellGroupStack.clear(); // need for reload case
1766 mSpellSameEffectStack.clear();
1767
1768 std::vector<uint32> sameEffectGroups;
1769
1770 // 0 1
1771 QueryResult result = WorldDatabase.Query("SELECT group_id, stack_rule FROM spell_group_stack_rules");
1772 if (!result)
1773 {
1774 LOG_WARN("server.loading", ">> Loaded 0 spell group stack rules. DB table `spell_group_stack_rules` is empty.");
1775 LOG_INFO("server.loading", " ");
1776 return;
1777 }
1778
1779 uint32 count = 0;
1780 do
1781 {
1782 Field* fields = result->Fetch();
1783
1784 uint32 group_id = fields[0].Get<uint32>();
1785 uint8 stack_rule = fields[1].Get<int8>();
1786 if (stack_rule >= SPELL_GROUP_STACK_RULE_MAX)
1787 {
1788 LOG_ERROR("sql.sql", "SpellGroupStackRule {} listed in `spell_group_stack_rules` does not exist.", stack_rule);
1789 continue;
1790 }
1791
1792 auto bounds = GetSpellGroupSpellMapBounds((SpellGroup)group_id);
1793 if (bounds.first == bounds.second)
1794 {
1795 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group_stack_rules` does not exist.", group_id);
1796 continue;
1797 }
1798
1799 mSpellGroupStack.emplace(SpellGroup(group_id), SpellGroupStackRule(stack_rule));
1800
1801 // different container for same effect stack rules, need to check effect types
1803 sameEffectGroups.push_back(group_id);
1804
1805 ++count;
1806 } while (result->NextRow());
1807
1808 LOG_INFO("server.loading", ">> Loaded {} spell group stack rules in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1809 LOG_INFO("server.loading", " ");
1810
1811 count = 0;
1812 oldMSTime = getMSTime();
1813
1814 for (uint32 group_id : sameEffectGroups)
1815 {
1816 std::set<uint32> spellIds;
1817 GetSetOfSpellsInSpellGroup(SpellGroup(group_id), spellIds);
1818
1819 std::unordered_set<uint32> auraTypes;
1820
1821 // we have to 'guess' what effect this group corresponds to
1822 {
1823 std::unordered_multiset<uint32 /*auraName*/> frequencyContainer;
1824
1825 // only waylay for the moment (shared group)
1826 std::vector<std::vector<uint32 /*auraName*/>> const SubGroups =
1827 {
1829 };
1830
1831 for (uint32 spellId : spellIds)
1832 {
1833 SpellInfo const* spellInfo = AssertSpellInfo(spellId);
1834 for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
1835 {
1836 if (!spellEffectInfo.IsAura())
1837 continue;
1838
1839 uint32 auraName = spellEffectInfo.ApplyAuraName;
1840 for (std::vector<uint32> const& subGroup : SubGroups)
1841 {
1842 if (std::find(subGroup.begin(), subGroup.end(), auraName) != subGroup.end())
1843 {
1844 // count as first aura
1845 auraName = subGroup.front();
1846 break;
1847 }
1848 }
1849
1850 frequencyContainer.insert(auraName);
1851 }
1852 }
1853
1854 uint32 auraType = 0;
1855 size_t auraTypeCount = 0;
1856 for (uint32 auraName : frequencyContainer)
1857 {
1858 size_t currentCount = frequencyContainer.count(auraName);
1859 if (currentCount > auraTypeCount)
1860 {
1861 auraType = auraName;
1862 auraTypeCount = currentCount;
1863 }
1864 }
1865
1866 for (std::vector<uint32> const& subGroup : SubGroups)
1867 {
1868 if (auraType == subGroup.front())
1869 {
1870 auraTypes.insert(subGroup.begin(), subGroup.end());
1871 break;
1872 }
1873 }
1874
1875 if (auraTypes.empty())
1876 auraTypes.insert(auraType);
1877 }
1878
1879 // re-check spells against guessed group
1880 for (uint32 spellId : spellIds)
1881 {
1882 SpellInfo const* spellInfo = AssertSpellInfo(spellId);
1883
1884 bool found = false;
1885 while (spellInfo)
1886 {
1887 for (uint32 auraType : auraTypes)
1888 {
1889 if (spellInfo->HasAura(AuraType(auraType)))
1890 {
1891 found = true;
1892 break;
1893 }
1894 }
1895
1896 if (found)
1897 break;
1898
1899 spellInfo = spellInfo->GetNextRankSpell();
1900 }
1901
1902 // not found either, log error
1903 if (!found)
1904 LOG_ERROR("sql.sql", "SpellId {} listed in `spell_group` with stack rule 3 does not share aura assigned for group {}", spellId, group_id);
1905 }
1906
1907 mSpellSameEffectStack[SpellGroup(group_id)] = auraTypes;
1908 ++count;
1909 }
1910
1911 LOG_INFO("server.loading", ">> Loaded {} SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT stack rules in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1912 LOG_INFO("server.loading", " ");
1913}
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:743

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 });
1072
1073 // Evocation
1074 ApplySpellFix({ 12051 }, [](SpellInfo* spellInfo)
1075 {
1076 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
1077 });
1078
1079 // MI Fireblast, WE Frostbolt, MI Frostbolt
1080 ApplySpellFix({ 59637, 31707, 72898 }, [](SpellInfo* spellInfo)
1081 {
1082 spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
1083 });
1084
1085 // Blazing Speed
1086 ApplySpellFix({ 31641, 31642 }, [](SpellInfo* spellInfo)
1087 {
1088 spellInfo->Effects[EFFECT_0].TriggerSpell = 31643;
1089 });
1090
1091 // Summon Water Elemental (permanent)
1092 ApplySpellFix({ 70908 }, [](SpellInfo* spellInfo)
1093 {
1094 // treat it as pet
1095 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_SUMMON_PET;
1096 });
1097
1098 // // Burnout, trigger
1099 ApplySpellFix({ 44450 }, [](SpellInfo* spellInfo)
1100 {
1101 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_POWER_BURN;
1102 });
1103
1104 // Mirror Image - Summon Spells
1105 ApplySpellFix({ 58831, 58833, 58834, 65047 }, [](SpellInfo* spellInfo)
1106 {
1107 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
1108 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(0);
1109 });
1110
1111 // Initialize Images (Mirror Image)
1112 ApplySpellFix({ 58836 }, [](SpellInfo* spellInfo)
1113 {
1114 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
1115 });
1116
1117 // Arcane Blast, can't be dispelled
1118 ApplySpellFix({ 36032 }, [](SpellInfo* spellInfo)
1119 {
1120 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
1121 });
1122
1123 // Chilled (frost armor, ice armor proc)
1124 ApplySpellFix({ 6136, 7321 }, [](SpellInfo* spellInfo)
1125 {
1126 spellInfo->PreventionType = SPELL_PREVENTION_TYPE_NONE;
1127 });
1128
1129 // Mirror Image Frostbolt
1130 ApplySpellFix({ 59638 }, [](SpellInfo* spellInfo)
1131 {
1132 spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
1133 spellInfo->SpellFamilyName = SPELLFAMILY_MAGE;
1134 spellInfo->SpellFamilyFlags = flag96(0x20, 0x0, 0x0);
1135 });
1136
1137 // Fingers of Frost
1138 ApplySpellFix({ 44544 }, [](SpellInfo* spellInfo)
1139 {
1140 spellInfo->Dispel = DISPEL_NONE;
1141 spellInfo->AttributesEx4 |= SPELL_ATTR4_CANNOT_BE_STOLEN;
1142 spellInfo->Effects[EFFECT_0].SpellClassMask = flag96(685904631, 1151040, 32);
1143 });
1144
1145 // Fingers of Frost visual buff
1146 ApplySpellFix({ 74396 }, [](SpellInfo* spellInfo)
1147 {
1148 spellInfo->ProcCharges = 2;
1149 spellInfo->StackAmount = 0;
1150 });
1151
1152 // Glyph of blocking
1153 ApplySpellFix({ 58375 }, [](SpellInfo* spellInfo)
1154 {
1155 spellInfo->Effects[EFFECT_0].TriggerSpell = 58374;
1156 });
1157
1158 // Sweeping Strikes stance change
1159 ApplySpellFix({ 12328 }, [](SpellInfo* spellInfo)
1160 {
1161 spellInfo->Attributes |= SPELL_ATTR0_NOT_SHAPESHIFTED;
1162 });
1163
1164 // Damage Shield
1165 ApplySpellFix({ 59653 }, [](SpellInfo* spellInfo)
1166 {
1167 spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
1168 spellInfo->SpellLevel = 0;
1169 });
1170
1172 20230, // Retaliation
1173 871, // Shield Wall
1174 1719 // Recklessness
1175 }, [](SpellInfo* spellInfo)
1176 {
1177 // Strange shared cooldown
1178 spellInfo->AttributesEx6 |= SPELL_ATTR6_NO_CATEGORY_COOLDOWN_MODS;
1179 });
1180
1181 // Vigilance
1182 ApplySpellFix({ 50720 }, [](SpellInfo* spellInfo)
1183 {
1184 // fixes bug with empowered renew, single target aura
1185 spellInfo->SpellFamilyName = SPELLFAMILY_WARRIOR;
1186 });
1187
1188 // Sunder Armor - Old Ranks
1189 ApplySpellFix({ 7405, 8380, 11596, 11597, 25225, 47467 }, [](SpellInfo* spellInfo)
1190 {
1191 spellInfo->Effects[EFFECT_0].TriggerSpell = 11971;
1192 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE;
1193 });
1194
1195 // Improved Spell Reflection
1196 ApplySpellFix({ 59725 }, [](SpellInfo* spellInfo)
1197 {
1198 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER_AREA_PARTY);
1199 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1200 });
1201
1202 // Hymn of Hope
1203 ApplySpellFix({ 64904 }, [](SpellInfo* spellInfo)
1204 {
1205 // rewrite part of aura system or swap effects...
1206 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT;
1207 spellInfo->Effects[EFFECT_2].Effect = spellInfo->Effects[EFFECT_0].Effect;
1208 spellInfo->Effects[EFFECT_0].Effect = 0;
1209 spellInfo->Effects[EFFECT_2].DieSides = spellInfo->Effects[EFFECT_0].DieSides;
1210 spellInfo->Effects[EFFECT_2].TargetA = spellInfo->Effects[EFFECT_0].TargetB;
1211 spellInfo->Effects[EFFECT_2].RadiusEntry = spellInfo->Effects[EFFECT_0].RadiusEntry;
1212 spellInfo->Effects[EFFECT_2].BasePoints = spellInfo->Effects[EFFECT_0].BasePoints;
1213 });
1214
1215 // Divine Hymn
1216 ApplySpellFix({ 64844 }, [](SpellInfo* spellInfo)
1217 {
1218 spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
1219 spellInfo->SpellLevel = 0;
1220 });
1221
1223 14898, // Spiritual Healing affects prayer of mending
1224 15349,
1225 15354,
1226 15355,
1227 15356,
1228 47562, // Divine Providence affects prayer of mending
1229 47564,
1230 47565,
1231 47566,
1232 47567,
1233 47586, // Twin Disciplines affects prayer of mending
1234 47587,
1235 47588,
1236 52802,
1237 52803
1238 }, [](SpellInfo* spellInfo)
1239 {
1240 spellInfo->Effects[EFFECT_0].SpellClassMask[1] |= 0x20; // prayer of mending
1241 });
1242
1243 // Lifebloom final bloom
1244 ApplySpellFix({ 33778 }, [](SpellInfo* spellInfo)
1245 {
1246 spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
1247 spellInfo->SpellLevel = 0;
1248 spellInfo->SpellFamilyFlags = flag96(0, 0x10, 0);
1249 });
1250
1251 // Owlkin Frenzy
1252 ApplySpellFix({ 48391 }, [](SpellInfo* spellInfo)
1253 {
1254 spellInfo->Attributes |= SPELL_ATTR0_NOT_SHAPESHIFTED;
1255 });
1256
1257 // Item T10 Restoration 4P Bonus
1258 ApplySpellFix({ 70691 }, [](SpellInfo* spellInfo)
1259 {
1260 spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_MODIFIERS;
1261 });
1262
1264 770, // Faerie Fire
1265 16857 // Faerie Fire (Feral)
1266 }, [](SpellInfo* spellInfo)
1267 {
1268 spellInfo->AttributesEx &= ~SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS;
1269 });
1270
1271 ApplySpellFix({ 49376 }, [](SpellInfo* spellInfo)
1272 {
1273 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS); // 3yd
1274 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
1275 });
1276
1277 // Feral Charge - Cat
1278 ApplySpellFix({ 61138, 61132, 50259 }, [](SpellInfo* spellInfo)
1279 {
1280 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
1281 });
1282
1283 // Glyph of Barkskin
1284 ApplySpellFix({ 63058 }, [](SpellInfo* spellInfo)
1285 {
1286 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE;
1287 });
1288
1289 // Resurrection Sickness
1290 ApplySpellFix({ 15007 }, [](SpellInfo* spellInfo)
1291 {
1292 spellInfo->SpellFamilyName = SPELLFAMILY_GENERIC;
1293 });
1294
1295 // Luck of the Draw
1296 ApplySpellFix({ 72221 }, [](SpellInfo* spellInfo)
1297 {
1298 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
1299 });
1300
1301 // Bind
1302 ApplySpellFix({ 3286 }, [](SpellInfo* spellInfo)
1303 {
1304 spellInfo->Targets = 0; // neutral innkeepers not friendly?
1305 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
1306 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
1307 });
1308
1309 // Playback Speech
1310 ApplySpellFix({ 74209 }, [](SpellInfo* spellInfo)
1311 {
1312 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(1);
1313 });
1314
1316 2641, // Dismiss Pet
1317 23356 // Taming Lesson
1318 }, [](SpellInfo* spellInfo)
1319 {
1320 // remove creaturetargettype
1321 spellInfo->TargetCreatureType = 0;
1322 });
1323
1324 // Aspect of the Viper
1325 ApplySpellFix({ 34074 }, [](SpellInfo* spellInfo)
1326 {
1327 spellInfo->Effects[EFFECT_2].Effect = SPELL_EFFECT_APPLY_AURA;
1328 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(1);
1329 spellInfo->Effects[EFFECT_2].ApplyAuraName = SPELL_AURA_DUMMY;
1330 });
1331
1332 // Strength of Wrynn
1333 ApplySpellFix({ 60509 }, [](SpellInfo* spellInfo)
1334 {
1335 spellInfo->Effects[EFFECT_2].BasePoints = 1500;
1336 spellInfo->Effects[EFFECT_1].BasePoints = 150;
1337 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_PERIODIC_HEAL;
1338 });
1339
1340 // Winterfin First Responder
1341 ApplySpellFix({ 48739 }, [](SpellInfo* spellInfo)
1342 {
1343 spellInfo->Effects[EFFECT_0].BasePoints = 1;
1344 spellInfo->Effects[EFFECT_0].RealPointsPerLevel = 0;
1345 spellInfo->Effects[EFFECT_0].DieSides = 0;
1346 spellInfo->Effects[EFFECT_0].DamageMultiplier = 0;
1347 spellInfo->Effects[EFFECT_0].BonusMultiplier = 0;
1348 });
1349
1350 // Army of the Dead (trigger npc aura)
1351 ApplySpellFix({ 49099 }, [](SpellInfo* spellInfo)
1352 {
1353 spellInfo->Effects[EFFECT_0].Amplitude = 15000;
1354 });
1355
1356 // Frightening Shout
1357 ApplySpellFix({ 19134 }, [](SpellInfo* spellInfo)
1358 {
1359 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_DUMMY;
1360 });
1361
1362 // Isle of Conquest
1363 ApplySpellFix({ 66551 }, [](SpellInfo* spellInfo)
1364 {
1365 // Teleport in, missing range
1366 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
1367 });
1368
1370 57607, // WintergraspCatapult - Spell Plague Barrel - EffectRadiusIndex
1371 57619, // WintergraspDemolisher - Spell Hourl Boulder - EffectRadiusIndex
1372 57610 // Cannon (Siege Turret)
1373 }, [](SpellInfo* spellInfo)
1374 {
1375 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_25_YARDS); // SPELL_EFFECT_WMO_DAMAGE
1376 });
1377
1378 // WintergraspCannon - Spell Fire Cannon - EffectRadiusIndex
1379 ApplySpellFix({ 51422 }, [](SpellInfo* spellInfo)
1380 {
1381 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // SPELL_EFFECT_SCHOOL_DAMAGE
1382 });
1383
1384 // WintergraspDemolisher - Spell Ram - EffectRadiusIndex
1385 ApplySpellFix({ 54107 }, [](SpellInfo* spellInfo)
1386 {
1387 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS); // SPELL_EFFECT_KNOCK_BACK
1388 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS); // SPELL_EFFECT_SCHOOL_DAMAGE
1389 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS); // SPELL_EFFECT_WEAPON_DAMAGE
1390 });
1391
1392 // WintergraspSiegeEngine - Spell Ram - EffectRadiusIndex
1393 ApplySpellFix({ 51678 }, [](SpellInfo* spellInfo)
1394 {
1395 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // SPELL_EFFECT_KNOCK_BACK
1396 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // SPELL_EFFECT_SCHOOL_DAMAGE
1397 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // SPELL_EFFECT_WEAPON_DAMAGE
1398 });
1399
1400 // WintergraspCatapult - Spell Plague Barrell - Range
1401 ApplySpellFix({ 57606 }, [](SpellInfo* spellInfo)
1402 {
1403 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(164); // "Catapult Range"
1404 });
1405
1406 // Boulder (Demolisher)
1407 ApplySpellFix({ 50999 }, [](SpellInfo* spellInfo)
1408 {
1409 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
1410 });
1411
1412 // Flame Breath (Catapult)
1413 ApplySpellFix({ 50990 }, [](SpellInfo* spellInfo)
1414 {
1415 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_18_YARDS); // 18yd
1416 });
1417
1418 // Jormungar Bite
1419 ApplySpellFix({ 56103 }, [](SpellInfo* spellInfo)
1420 {
1421 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
1422 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1423 });
1424
1425 // Throw Proximity Bomb
1426 ApplySpellFix({ 34095 }, [](SpellInfo* spellInfo)
1427 {
1428 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ENEMY);
1429 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1430 });
1431
1433 53348, // DEATH KNIGHT SCARLET FIRE ARROW
1434 53117 // BALISTA
1435 }, [](SpellInfo* spellInfo)
1436 {
1437 spellInfo->RecoveryTime = 5000;
1438 spellInfo->CategoryRecoveryTime = 5000;
1439 });
1440
1441 // Teleport To Molten Core
1442 ApplySpellFix({ 25139 }, [](SpellInfo* spellInfo)
1443 {
1444 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
1445 });
1446
1447 // Landen Stilwell Transform
1448 ApplySpellFix({ 31310 }, [](SpellInfo* spellInfo)
1449 {
1450 spellInfo->Attributes |= SPELL_ATTR0_PASSIVE;
1451 });
1452
1453 // Shadowstalker Stealth
1454 ApplySpellFix({ 5916 }, [](SpellInfo* spellInfo)
1455 {
1456 spellInfo->Effects[EFFECT_0].RealPointsPerLevel = 5.0f;
1457 });
1458
1459 // Sneak
1460 ApplySpellFix({ 22766 }, [](SpellInfo* spellInfo)
1461 {
1462 spellInfo->Effects[EFFECT_0].RealPointsPerLevel = 5.0f;
1463 });
1464
1465 // Murmur's Touch
1466 ApplySpellFix({ 38794, 33711 }, [](SpellInfo* spellInfo)
1467 {
1468 spellInfo->MaxAffectedTargets = 1;
1469 spellInfo->Effects[EFFECT_0].TriggerSpell = 33760;
1470 });
1471
1472 // Negaton Field
1474 36729, // Normal
1475 38834 // Heroic
1476 }, [](SpellInfo* spellInfo)
1477 {
1478 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
1479 });
1480
1481 // Curse of the Doomsayer NORMAL
1482 ApplySpellFix({ 36173 }, [](SpellInfo* spellInfo)
1483 {
1484 spellInfo->Effects[EFFECT_0].TriggerSpell = 36174; // Currently triggers heroic version...
1485 });
1486
1487 // Crystal Channel
1488 ApplySpellFix({ 34156 }, [](SpellInfo* spellInfo)
1489 {
1490 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(35); // 35yd;
1491 spellInfo->ChannelInterruptFlags |= AURA_INTERRUPT_FLAG_MOVE;
1492 });
1493
1494 // Debris - Debris Visual
1495 ApplySpellFix({ 36449, 30632 }, [](SpellInfo* spellInfo)
1496 {
1497 spellInfo->Attributes |= SPELL_ATTR0_AURA_IS_DEBUFF;
1498 });
1499
1500 // Soul Channel
1501 ApplySpellFix({ 30531 }, [](SpellInfo* spellInfo)
1502 {
1503 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
1504 });
1505
1506 // Activate Sunblade Protector
1507 ApplySpellFix({ 46475, 46476 }, [](SpellInfo* spellInfo)
1508 {
1509 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(14); // 60yd
1510 });
1511
1512 // Break Ice
1513 ApplySpellFix({ 46638 }, [](SpellInfo* spellInfo)
1514 {
1515 spellInfo->AttributesEx3 &= ~SPELL_ATTR3_ONLY_ON_PLAYER; // Obvious fail, it targets gameobject...
1516 });
1517
1518 // Sinister Reflection Clone
1519 ApplySpellFix({ 45785 }, [](SpellInfo* spellInfo)
1520 {
1521 spellInfo->Speed = 0.0f;
1522 });
1523
1524 // Armageddon
1525 ApplySpellFix({ 45909 }, [](SpellInfo* spellInfo)
1526 {
1527 spellInfo->Speed = 8.0f;
1528 });
1529
1530 // Shadowmoon Reaver - Spell Absorption
1531 ApplySpellFix({ 41034 }, [](SpellInfo* spellInfo)
1532 {
1533 spellInfo->Effects[EFFECT_2].Effect = SPELL_EFFECT_APPLY_AURA;
1534 spellInfo->Effects[EFFECT_2].ApplyAuraName = SPELL_AURA_SCHOOL_ABSORB;
1535 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
1536 spellInfo->Effects[EFFECT_2].MiscValue = SPELL_SCHOOL_MASK_MAGIC;
1537 });
1538
1539 // Priestess of Delight and Priestess of Torment - Shared Bonds
1540 ApplySpellFix({ 41363 }, [](SpellInfo* spellInfo)
1541 {
1542 spellInfo->AttributesEx &= ~SPELL_ATTR1_IS_CHANNELED;
1543 });
1544
1545 // Illidari Council - Veras Darkshadow
1547 41485, // Deadly Poison
1548 41487 // Envenom
1549 }, [](SpellInfo* spellInfo)
1550 {
1551 spellInfo->AttributesEx6 |= SPELL_ATTR6_IGNORE_PHASE_SHIFT;
1552 });
1553
1554 // Illidan Stormrage - Parasitic Shadowfiend
1555 ApplySpellFix({ 41914 }, [](SpellInfo* spellInfo)
1556 {
1557 spellInfo->Attributes |= SPELL_ATTR0_AURA_IS_DEBUFF;
1558 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
1559 });
1560
1561 // Illidan Stormrage - Demon Fire
1562 ApplySpellFix({ 40030 }, [](SpellInfo* spellInfo)
1563 {
1564 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
1565 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
1566 });
1567
1568 // Illidan Stormrage - Teleport Maiev
1569 ApplySpellFix({ 41221 }, [](SpellInfo* spellInfo)
1570 {
1571 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 0-50000yd
1572 });
1573
1574 // Morogrim Tidewalker - Watery Grave Explosion
1575 ApplySpellFix({ 37852 }, [](SpellInfo* spellInfo)
1576 {
1577 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_WHILE_STUNNED;
1578 });
1579
1580 // Prince Malchezaar - Amplify Damage
1581 ApplySpellFix({ 39095 }, [](SpellInfo* spellInfo)
1582 {
1583 spellInfo->MaxAffectedTargets = 1;
1584 });
1585
1586 // Energy Feedback
1587 ApplySpellFix({ 44335 }, [](SpellInfo* spellInfo)
1588 {
1589 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
1590 spellInfo->AttributesCu |= SPELL_ATTR0_CU_SINGLE_AURA_STACK;
1591 });
1592
1593 // Archimonde
1595 31984, // Finger of Death
1596 35354 // Hand of Death
1597 }, [](SpellInfo* spellInfo)
1598 {
1599 // Spell doesn't need to ignore invulnerabilities
1600 spellInfo->Attributes = SPELL_ATTR0_IS_ABILITY;
1601 });
1602
1603 // Archimonde - Finger of Death
1604 ApplySpellFix({ 32111 }, [](SpellInfo* spellInfo)
1605 {
1606 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(0); // We only need the animation, no damage
1607 });
1608
1609 // Archimonde - Doomfire
1610 ApplySpellFix({ 31944, 31969 }, [](SpellInfo* spellInfo)
1611 {
1612 spellInfo->AttributesEx4 |= SPELL_ATTR4_NO_CAST_LOG;
1613 });
1614
1615 // Flame Breath, catapult spell
1616 ApplySpellFix({ 50989 }, [](SpellInfo* spellInfo)
1617 {
1618 spellInfo->Attributes &= ~SPELL_ATTR0_SCALES_WITH_CREATURE_LEVEL;
1619 });
1620
1621 // Koralon, Flaming Cinder
1622 ApplySpellFix({ 66690 }, [](SpellInfo* spellInfo)
1623 {
1624 // missing radius index
1625 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
1626 spellInfo->MaxAffectedTargets = 1;
1627 });
1628
1629 // Acid Volley
1630 ApplySpellFix({ 54714, 29325 }, [](SpellInfo* spellInfo)
1631 {
1632 spellInfo->MaxAffectedTargets = 1;
1633 });
1634
1635 // Summon Plagued Warrior
1636 ApplySpellFix({ 29237 }, [](SpellInfo* spellInfo)
1637 {
1638 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_DUMMY;
1639 spellInfo->Effects[EFFECT_1].Effect = spellInfo->Effects[EFFECT_2].Effect = 0;
1640 });
1641
1642 // Icebolt
1643 ApplySpellFix({ 28526 }, [](SpellInfo* spellInfo)
1644 {
1645 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
1646 });
1647
1648 // Infected Wound
1649 ApplySpellFix({ 29306 }, [](SpellInfo* spellInfo)
1650 {
1651 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
1652 });
1653
1654 // Hopeless
1655 ApplySpellFix({ 29125 }, [](SpellInfo* spellInfo)
1656 {
1657 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
1658 });
1659
1660 // Jagged Knife
1661 ApplySpellFix({ 55550 }, [](SpellInfo* spellInfo)
1662 {
1663 spellInfo->Attributes |= SPELL_ATTR0_USES_RANGED_SLOT;
1664 });
1665
1666 // Moorabi - Transformation
1667 ApplySpellFix({ 55098 }, [](SpellInfo* spellInfo)
1668 {
1669 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
1670 });
1671
1673 55521, // Poisoned Spear (Normal)
1674 58967, // Poisoned Spear (Heroic)
1675 55348, // Throw (Normal)
1676 58966 // Throw (Heroic)
1677 }, [](SpellInfo* spellInfo)
1678 {
1679 spellInfo->Attributes |= SPELL_ATTR0_USES_RANGED_SLOT;
1680 });
1681
1682 // Charged Chaotic rift aura, trigger
1683 ApplySpellFix({ 47737 }, [](SpellInfo* spellInfo)
1684 {
1685 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(37); // 50yd
1686 });
1687
1688 // Vanish
1689 ApplySpellFix({ 55964 }, [](SpellInfo* spellInfo)
1690 {
1691 spellInfo->Effects[EFFECT_1].Effect = 0;
1692 spellInfo->Effects[EFFECT_2].Effect = 0;
1693 });
1694
1695 // Trollgore - Summon Drakkari Invader
1696 ApplySpellFix({ 49456, 49457, 49458 }, [](SpellInfo* spellInfo)
1697 {
1698 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB);
1699 });
1700
1702 48278, // Paralyse
1703 47669 // Awaken subboss
1704 }, [](SpellInfo* spellInfo)
1705 {
1706 spellInfo->Effects[0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
1707 spellInfo->Effects[0].TargetB = SpellImplicitTargetInfo();
1708 });
1709
1710 // Skarvald, Charge
1711 ApplySpellFix({ 43651 }, [](SpellInfo* spellInfo)
1712 {
1713 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 0-50000yd
1714 });
1715
1716 // Ingvar the Plunderer, Woe Strike
1717 ApplySpellFix({ 42730 }, [](SpellInfo* spellInfo)
1718 {
1719 spellInfo->Effects[EFFECT_1].TriggerSpell = 42739;
1720 });
1721
1722 ApplySpellFix({ 59735 }, [](SpellInfo* spellInfo)
1723 {
1724 spellInfo->Effects[EFFECT_1].TriggerSpell = 59736;
1725 });
1726
1727 // Ingvar the Plunderer, Ingvar transform
1728 ApplySpellFix({ 42796 }, [](SpellInfo* spellInfo)
1729 {
1730 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
1731 });
1732
1734 42772, // Hurl Dagger (Normal)
1735 59685 // Hurl Dagger (Heroic)
1736 }, [](SpellInfo* spellInfo)
1737 {
1738 spellInfo->Attributes |= SPELL_ATTR0_USES_RANGED_SLOT;
1739 });
1740
1741 // Control Crystal Activation
1742 ApplySpellFix({ 57804 }, [](SpellInfo* spellInfo)
1743 {
1744 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(1);
1745 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1746 });
1747
1748 // Destroy Door Seal
1749 ApplySpellFix({ 58040 }, [](SpellInfo* spellInfo)
1750 {
1751 spellInfo->ChannelInterruptFlags &= ~(AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE);
1752 });
1753
1754 // Ichoron, Water Blast
1755 ApplySpellFix({ 54237, 59520 }, [](SpellInfo* spellInfo)
1756 {
1757 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
1758 });
1759
1760 // Krik'thir - Mind Flay
1761 ApplySpellFix({ 52586, 59367 }, [](SpellInfo* spellInfo)
1762 {
1763 spellInfo->ChannelInterruptFlags |= AURA_INTERRUPT_FLAG_MOVE;
1764 });
1765
1766 // Glare of the Tribunal
1767 ApplySpellFix({ 50988, 59870 }, [](SpellInfo* spellInfo)
1768 {
1769 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
1770 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1771 });
1772
1773 // Static Charge
1774 ApplySpellFix({ 50835, 59847 }, [](SpellInfo* spellInfo)
1775 {
1776 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
1777 });
1778
1779 // Lava Strike damage
1780 ApplySpellFix({ 57697 }, [](SpellInfo* spellInfo)
1781 {
1782 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
1783 });
1784
1785 // Lava Strike trigger
1786 ApplySpellFix({ 57578 }, [](SpellInfo* spellInfo)
1787 {
1788 spellInfo->MaxAffectedTargets = 1;
1789 });
1790
1791 // Gift of Twilight Shadow/Fire
1792 ApplySpellFix({ 57835, 58766 }, [](SpellInfo* spellInfo)
1793 {
1794 spellInfo->AttributesEx &= ~SPELL_ATTR1_IS_CHANNELED;
1795 });
1796
1797 // Pyrobuffet
1798 ApplySpellFix({ 57557 }, [](SpellInfo* spellInfo)
1799 {
1800 spellInfo->ExcludeTargetAuraSpell = 56911;
1801 });
1802
1803 // Arcane Barrage
1804 ApplySpellFix({ 56397 }, [](SpellInfo* spellInfo)
1805 {
1806 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
1807 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1808 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
1809 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
1810 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
1811 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo();
1812 });
1813
1815 55849, // Power Spark (ground +50% dmg aura)
1816 56438, // Arcane Overload (-50% dmg taken) - this is to prevent apply -> unapply -> apply ... dunno whether it's correct
1817 }, [](SpellInfo* spellInfo)
1818 {
1819 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
1820 });
1821
1822 // Vortex (Control Vehicle)
1823 ApplySpellFix({ 56263 }, [](SpellInfo* spellInfo)
1824 {
1825 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
1826 });
1827
1828 // Haste (Nexus Lord, increase run Speed of the disk)
1829 ApplySpellFix({ 57060 }, [](SpellInfo* spellInfo)
1830 {
1831 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_VEHICLE);
1832 });
1833
1834 // Arcane Overload
1835 ApplySpellFix({ 56430 }, [](SpellInfo* spellInfo)
1836 {
1837 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_TRIGGER_MISSILE;
1838 spellInfo->Effects[EFFECT_0].TriggerSpell = 56429;
1839 });
1840
1841 // Summon Arcane Bomb
1842 ApplySpellFix({ 56429 }, [](SpellInfo* spellInfo)
1843 {
1844 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
1845 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1846 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo();
1847 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
1848 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo();
1849 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo();
1850 });
1851
1852 // Destroy Platform Event
1853 ApplySpellFix({ 59099 }, [](SpellInfo* spellInfo)
1854 {
1855 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(22);
1856 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(15);
1857 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(22);
1858 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo(15);
1859 });
1860
1861 // Surge of Power (Phase 3)
1863 57407, // N
1864 }, [](SpellInfo* spellInfo)
1865 {
1866 spellInfo->MaxAffectedTargets = 1;
1867 spellInfo->InterruptFlags = 0;
1868 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS);
1869 spellInfo->AttributesEx4 |= SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING;
1870 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
1871 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
1872 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1873 });
1874
1875 // Surge of Power (Phase 3)
1877 60936 // H
1878 }, [](SpellInfo* spellInfo)
1879 {
1880 spellInfo->MaxAffectedTargets = 3;
1881 spellInfo->InterruptFlags = 0;
1882 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS);
1883 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
1884 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
1885 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1886 });
1887
1888 // Wyrmrest Drake - Life Burst
1889 ApplySpellFix({ 57143 }, [](SpellInfo* spellInfo)
1890 {
1891 spellInfo->Effects[EFFECT_0].Effect = 0;
1892 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo();
1893 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1894 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
1895 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
1896 spellInfo->Effects[EFFECT_1].PointsPerComboPoint = 2500;
1897 spellInfo->Effects[EFFECT_1].BasePoints = 2499;
1898 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(1);
1899 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1900 });
1901
1902 //Alexstrasza - Gift
1903 ApplySpellFix({ 61028 }, [](SpellInfo* spellInfo)
1904 {
1905 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
1906 });
1907
1908 // Hurl Pyrite
1909 ApplySpellFix({ 62490 }, [](SpellInfo* spellInfo)
1910 {
1911 spellInfo->Effects[EFFECT_1].Effect = 0;
1912 });
1913
1914 // Meeting Stone Summon
1915 ApplySpellFix({ 23598 }, [](SpellInfo* spellInfo)
1916 {
1917 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
1918 });
1919
1920 // Ulduar, Mimiron, bomb bot explosion
1921 ApplySpellFix({ 63801 }, [](SpellInfo* spellInfo)
1922 {
1923 spellInfo->Effects[EFFECT_1].MiscValue = 17286;
1924 });
1925
1926 // Ulduar, Mimiron, Summon Flames Initial
1927 ApplySpellFix({ 64563 }, [](SpellInfo* spellInfo)
1928 {
1929 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1930 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
1931 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
1932 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
1933 });
1934
1935 // Ulduar, Mimiron, Flames (damage)
1936 ApplySpellFix({ 64566 }, [](SpellInfo* spellInfo)
1937 {
1938 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
1939 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
1940 });
1941
1942 // Ulduar, Hodir, Starlight
1943 ApplySpellFix({ 62807 }, [](SpellInfo* spellInfo)
1944 {
1945 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_1_YARD); // 1yd
1946 });
1947
1948 // Hodir Shatter Cache
1949 ApplySpellFix({ 62502 }, [](SpellInfo* spellInfo)
1950 {
1951 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
1952 });
1953
1954 // Ulduar, General Vezax, Mark of the Faceless
1955 ApplySpellFix({ 63278 }, [](SpellInfo* spellInfo)
1956 {
1957 spellInfo->Effects[EFFECT_0].Effect = 0;
1958 });
1959
1960 // Boom (XT-002)
1961 ApplySpellFix({ 62834 }, [](SpellInfo* spellInfo)
1962 {
1963 spellInfo->Effects[EFFECT_1].Effect = 0;
1964 });
1965
1966 // Supercharge
1967 ApplySpellFix({ 61920 }, [](SpellInfo* spellInfo)
1968 {
1969 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
1970 });
1971
1972 // Lightning Whirl
1973 ApplySpellFix({ 61916 }, [](SpellInfo* spellInfo)
1974 {
1975 spellInfo->MaxAffectedTargets = 3;
1976 });
1977
1978 ApplySpellFix({ 63482 }, [](SpellInfo* spellInfo)
1979 {
1980 spellInfo->MaxAffectedTargets = 8;
1981 });
1982
1983 // Stone Grip, remove absorb aura
1984 ApplySpellFix({ 62056, 63985 }, [](SpellInfo* spellInfo)
1985 {
1986 spellInfo->Effects[EFFECT_1].Effect = 0;
1987 });
1988
1989 // Sentinel Blast
1990 ApplySpellFix({ 64389, 64678 }, [](SpellInfo* spellInfo)
1991 {
1992 spellInfo->Dispel = DISPEL_MAGIC;
1993 });
1994
1995 // Potent Pheromones
1996 ApplySpellFix({ 62619 }, [](SpellInfo* spellInfo)
1997 {
1998 spellInfo->AttributesEx |= SPELL_ATTR1_IMMUNITY_PURGES_EFFECT;
1999 });
2000
2001 // Healthy spore summon periodic
2002 ApplySpellFix({ 62566 }, [](SpellInfo* spellInfo)
2003 {
2004 spellInfo->Effects[EFFECT_0].Amplitude = 2000;
2005 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PERIODIC_TRIGGER_SPELL;
2006 });
2007
2008 // Brightleaf Essence trigger
2009 ApplySpellFix({ 62968 }, [](SpellInfo* spellInfo)
2010 {
2011 spellInfo->Effects[EFFECT_1].Effect = 0; // duplicate
2012 });
2013
2014 // Potent Pheromones
2015 ApplySpellFix({ 64321 }, [](SpellInfo* spellInfo)
2016 {
2017 spellInfo->AttributesEx3 |= SPELL_ATTR3_ONLY_ON_PLAYER;
2018 spellInfo->AttributesEx |= SPELL_ATTR1_IMMUNITY_PURGES_EFFECT;
2019 });
2020
2021 // Lightning Orb Charged
2022 ApplySpellFix({ 62186 }, [](SpellInfo* spellInfo)
2023 {
2024 spellInfo->Effects[EFFECT_0].Amplitude = 5000; // Duration 5 secs, amplitude 8 secs...
2025 });
2026
2027 // Lightning Pillar
2028 ApplySpellFix({ 62976 }, [](SpellInfo* spellInfo)
2029 {
2030 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6);
2031 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(28); // 5 seconds, wrong DBC data?
2032 });
2033
2034 // Sif's Blizzard
2035 ApplySpellFix({ 62576, 62602 }, [](SpellInfo* spellInfo)
2036 {
2037 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_8_YARDS); // 8yd
2038 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_8_YARDS); // 8yd
2039 });
2040
2041 // Protective Gaze
2042 ApplySpellFix({ 64175 }, [](SpellInfo* spellInfo)
2043 {
2044 spellInfo->RecoveryTime = 25000;
2045 });
2046
2047 // Shadow Beacon
2048 ApplySpellFix({ 64465 }, [](SpellInfo* spellInfo)
2049 {
2050 spellInfo->Effects[EFFECT_0].TriggerSpell = 64467; // why do they need two script effects :/ (this one has visual effect)
2051 });
2052
2053 // Sanity
2054 ApplySpellFix({ 63050 }, [](SpellInfo* spellInfo)
2055 {
2056 spellInfo->AttributesEx6 |= SPELL_ATTR6_IGNORE_PHASE_SHIFT;
2057 });
2058
2059 // Shadow Nova
2060 ApplySpellFix({ 62714, 65209 }, [](SpellInfo* spellInfo)
2061 {
2062 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
2063 });
2064
2065 // Cosmic Smash (Algalon the Observer)
2066 ApplySpellFix({ 62293 }, [](SpellInfo* spellInfo)
2067 {
2068 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
2069 });
2070
2071 // Cosmic Smash (Algalon the Observer)
2072 ApplySpellFix({ 62311, 64596 }, [](SpellInfo* spellInfo)
2073 {
2074 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2075 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
2076 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
2077 });
2078
2079 // Constellation Phase Effect
2080 ApplySpellFix({ 65509 }, [](SpellInfo* spellInfo)
2081 {
2082 spellInfo->MaxAffectedTargets = 1;
2083 });
2084
2085 // Black Hole
2086 ApplySpellFix({ 62168, 65250, 62169 }, [](SpellInfo* spellInfo)
2087 {
2088 spellInfo->Attributes |= SPELL_ATTR0_AURA_IS_DEBUFF;
2089 });
2090
2091 // Ground Slam
2092 ApplySpellFix({ 62625 }, [](SpellInfo* spellInfo)
2093 {
2094 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
2095 });
2096
2097 // Onyxia's Lair, Onyxia, Flame Breath (TriggerSpell = 0 and spamming errors in console)
2098 ApplySpellFix({ 18435 }, [](SpellInfo* spellInfo)
2099 {
2100 spellInfo->Effects[EFFECT_1].Effect = 0;
2101 });
2102
2103 // Onyxia's Lair, Onyxia, Create Onyxia Spawner
2104 ApplySpellFix({ 17647 }, [](SpellInfo* spellInfo)
2105 {
2106 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(37);
2107 });
2108
2110 17646, // Onyxia's Lair, Onyxia, Summon Onyxia Whelp
2111 68968 // Onyxia's Lair, Onyxia, Summon Lair Guard
2112 }, [](SpellInfo* spellInfo)
2113 {
2114 spellInfo->Targets |= TARGET_FLAG_DEST_LOCATION;
2115 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2116 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
2117 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(5);
2118 });
2119
2120 // Onyxia's Lair, Onyxia, Eruption
2121 ApplySpellFix({ 17731, 69294 }, [](SpellInfo* spellInfo)
2122 {
2123 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_DUMMY;
2124 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(3);
2125 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_18_YARDS); // 18yd instead of 13yd to make sure all cracks erupt
2126 });
2127
2128 // Onyxia's Lair, Onyxia, Breath
2130 18576, 18578, 18579, 18580, 18581, 18582, 18583, 18609, 18611, 18612, 18613, 18614, 18615, 18616, 18584,
2131 18585, 18586, 18587, 18588, 18589, 18590, 18591, 18592, 18593, 18594, 18595, 18564, 18565, 18566, 18567,
2132 18568, 18569, 18570, 18571, 18572, 18573, 18574, 18575, 18596, 18597, 18598, 18599, 18600, 18601, 18602,
2133 18603, 18604, 18605, 18606, 18607, 18617, 18619, 18620, 18621, 18622, 18623, 18624, 18625, 18626, 18627,
2134 18628, 18618, 18351, 18352, 18353, 18354, 18355, 18356, 18357, 18358, 18359, 18360, 18361, 17086, 17087,
2135 17088, 17089, 17090, 17091, 17092, 17093, 17094, 17095, 17097, 22267, 22268, 21132, 21133, 21135, 21136,
2136 21137, 21138, 21139
2137 }, [](SpellInfo* spellInfo)
2138 {
2139 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(328); // 250ms
2140 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(1);
2141 if (spellInfo->Effects[EFFECT_1].Effect)
2142 {
2143 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
2144 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_PERIODIC_TRIGGER_SPELL;
2145 spellInfo->Effects[EFFECT_1].Amplitude = ((spellInfo->CastTimeEntry == sSpellCastTimesStore.LookupEntry(170)) ? 50 : 215);
2146 }
2147 });
2148
2150 48760, // Oculus, Teleport to Coldarra DND
2151 49305 // Oculus, Teleport to Boss 1 DND
2152 }, [](SpellInfo* spellInfo)
2153 {
2154 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
2155 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(17);
2156 });
2157
2158 // Oculus, Drake spell Stop Time
2159 ApplySpellFix({ 49838 }, [](SpellInfo* spellInfo)
2160 {
2161 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
2162 spellInfo->ExcludeTargetAuraSpell = 51162; // exclude planar shift
2163 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_150_YARDS);
2164 });
2165
2166 // Oculus, Varos Cloudstrider, Energize Cores
2167 ApplySpellFix({ 61407, 62136, 56251, 54069 }, [](SpellInfo* spellInfo)
2168 {
2169 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CONE_ENTRY);
2170 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2171 });
2172
2173 // Halls of Lightning, Arc Weld
2174 ApplySpellFix({ 59086 }, [](SpellInfo* spellInfo)
2175 {
2176 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(1);
2177 });
2178
2179 // Trial of the Champion, Death's Respite
2180 ApplySpellFix({ 68306 }, [](SpellInfo* spellInfo)
2181 {
2182 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
2183 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(25);
2184 });
2185
2186 // Trial of the Champion, Eadric Achievement (The Faceroller)
2187 ApplySpellFix({ 68197 }, [](SpellInfo* spellInfo)
2188 {
2189 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
2190 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD;
2191 });
2192
2193 // Trial of the Champion, Earth Shield
2194 ApplySpellFix({ 67530 }, [](SpellInfo* spellInfo)
2195 {
2196 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PROC_TRIGGER_SPELL; // will trigger 67537
2197 });
2198
2199 // Trial of the Champion, Hammer of the Righteous
2200 ApplySpellFix({ 66867 }, [](SpellInfo* spellInfo)
2201 {
2202 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_DUMMY;
2203 });
2204
2205 // Trial of the Champion, Summon Risen Jaeren/Arelas
2206 ApplySpellFix({ 67705, 67715 }, [](SpellInfo* spellInfo)
2207 {
2208 spellInfo->AttributesEx2 |= SPELL_ATTR2_ALLOW_DEAD_TARGET;
2209 });
2210
2211 // Trial of the Champion, Ghoul Explode
2212 ApplySpellFix({ 67751 }, [](SpellInfo* spellInfo)
2213 {
2214 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2215 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2216 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS);
2217 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2218 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2219 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS);
2220 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2221 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2222 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS);
2223 });
2224
2225 // Trial of the Champion, Desecration
2226 ApplySpellFix({ 67778, 67877 }, [](SpellInfo* spellInfo)
2227 {
2228 spellInfo->Effects[EFFECT_0].TriggerSpell = 68766;
2229 });
2230
2231 // Killing Spree (Off hand damage)
2232 ApplySpellFix({ 57842 }, [](SpellInfo* spellInfo)
2233 {
2234 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(2); // Melee Range
2235 });
2236
2237 // Trial of the Crusader, Jaraxxus Intro spell
2238 ApplySpellFix({ 67888 }, [](SpellInfo* spellInfo)
2239 {
2240 spellInfo->Attributes |= SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT;
2241 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
2242 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
2243 });
2244
2245 // Trial of the Crusader, Lich King Intro spell
2246 ApplySpellFix({ 68193 }, [](SpellInfo* spellInfo)
2247 {
2248 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
2249 });
2250
2251 // Trial of the Crusader, Gormok, player vehicle spell, CUSTOM! (default jump to hand, not used)
2252 ApplySpellFix({ 66342 }, [](SpellInfo* spellInfo)
2253 {
2254 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AURA;
2255 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_SET_VEHICLE_ID;
2256 spellInfo->Effects[EFFECT_0].MiscValue = 496;
2257 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21);
2258 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13);
2259 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
2260 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2261 spellInfo->AuraInterruptFlags = AURA_INTERRUPT_FLAG_CHANGE_MAP;
2262 });
2263
2264 // Trial of the Crusader, Gormok, Fire Bomb
2265 ApplySpellFix({ 66313 }, [](SpellInfo* spellInfo)
2266 {
2267 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2268 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ANY);
2269 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2270 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ANY);
2271 spellInfo->Effects[EFFECT_1].Effect = 0;
2272 });
2273
2274 ApplySpellFix({ 66317 }, [](SpellInfo* spellInfo)
2275 {
2276 spellInfo->Attributes |= SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT;
2277 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
2278 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
2279 });
2280
2281 ApplySpellFix({ 66318 }, [](SpellInfo* spellInfo)
2282 {
2283 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2284 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2285 spellInfo->Speed = 14.0f;
2286 spellInfo->Attributes |= SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT;
2287 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
2288 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
2289 });
2290
2291 ApplySpellFix({ 66320, 67472, 67473, 67475 }, [](SpellInfo* spellInfo)
2292 {
2293 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_2_YARDS);
2294 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_2_YARDS);
2295 });
2296
2297 // Trial of the Crusader, Acidmaw & Dreadscale, Emerge
2298 ApplySpellFix({ 66947 }, [](SpellInfo* spellInfo)
2299 {
2300 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_WHILE_STUNNED;
2301 });
2302
2303 // Trial of the Crusader, Jaraxxus, Curse of the Nether
2304 ApplySpellFix({ 66211 }, [](SpellInfo* spellInfo)
2305 {
2306 spellInfo->ExcludeTargetAuraSpell = 66209; // exclude Touch of Jaraxxus
2307 });
2308
2309 // Trial of the Crusader, Jaraxxus, Summon Volcano
2310 ApplySpellFix({ 66258, 67901 }, [](SpellInfo* spellInfo)
2311 {
2312 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(85); // summon for 18 seconds, 15 not enough
2313 });
2314
2315 // Trial of the Crusader, Jaraxxus, Spinning Pain Spike
2316 ApplySpellFix({ 66281 }, [](SpellInfo* spellInfo)
2317 {
2318 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_4_YARDS);
2319 });
2320
2321 ApplySpellFix({ 66287 }, [](SpellInfo* spellInfo)
2322 {
2323 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
2324 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_MOD_TAUNT;
2325 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_NEARBY_ENTRY);
2326 spellInfo->Effects[EFFECT_2].Effect = SPELL_EFFECT_APPLY_AURA;
2327 spellInfo->Effects[EFFECT_2].ApplyAuraName = SPELL_AURA_MOD_STUN;
2328 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
2329 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(35); // 4 secs
2330 });
2331
2332 // Trial of the Crusader, Jaraxxus, Fel Fireball
2333 ApplySpellFix({ 66532, 66963, 66964, 66965 }, [](SpellInfo* spellInfo)
2334 {
2335 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
2336 });
2337
2338 // tempfix, make Nether Power not stealable
2339 ApplySpellFix({ 66228, 67106, 67107, 67108 }, [](SpellInfo* spellInfo)
2340 {
2341 spellInfo->AttributesEx4 |= SPELL_ATTR4_CANNOT_BE_STOLEN;
2342 });
2343
2344 // Trial of the Crusader, Faction Champions, Druid - Tranquality
2345 ApplySpellFix({ 66086, 67974, 67975, 67976 }, [](SpellInfo* spellInfo)
2346 {
2347 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AREA_AURA_FRIEND;
2348 });
2349
2350 // Trial of the Crusader, Faction Champions, Shaman - Earth Shield
2351 ApplySpellFix({ 66063 }, [](SpellInfo* spellInfo)
2352 {
2353 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PROC_TRIGGER_SPELL;
2354 spellInfo->Effects[EFFECT_0].TriggerSpell = 66064;
2355 });
2356
2357 // Trial of the Crusader, Faction Champions, Priest - Mana Burn
2358 ApplySpellFix({ 66100 }, [](SpellInfo* spellInfo)
2359 {
2360 spellInfo->Effects[EFFECT_0].BasePoints = 5;
2361 spellInfo->Effects[EFFECT_0].DieSides = 0;
2362 });
2363
2364 ApplySpellFix({ 68026 }, [](SpellInfo* spellInfo)
2365 {
2366 spellInfo->Effects[EFFECT_0].BasePoints = 8;
2367 spellInfo->Effects[EFFECT_0].DieSides = 0;
2368 });
2369
2370 ApplySpellFix({ 68027 }, [](SpellInfo* spellInfo)
2371 {
2372 spellInfo->Effects[EFFECT_0].BasePoints = 6;
2373 spellInfo->Effects[EFFECT_0].DieSides = 0;
2374 });
2375
2376 ApplySpellFix({ 68028 }, [](SpellInfo* spellInfo)
2377 {
2378 spellInfo->Effects[EFFECT_0].BasePoints = 10;
2379 spellInfo->Effects[EFFECT_0].DieSides = 0;
2380 });
2381
2382 // Trial of the Crusader, Twin Valkyr, Touch of Light/Darkness, Light/Dark Surge
2384 65950 // light 0
2385 }, [](SpellInfo* spellInfo)
2386 {
2387 //spellInfo->EffectApplyAuraName[0] = SPELL_AURA_PERIODIC_DUMMY;
2388 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2389 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2390 spellInfo->Effects[EFFECT_1].Effect = 0;
2391 spellInfo->Effects[EFFECT_2].Effect = 0;
2392 });
2393
2395 65767 // light surge 0
2396 }, [](SpellInfo* spellInfo)
2397 {
2398 spellInfo->ExcludeTargetAuraSpell = 65686;
2399 });
2400
2402 67296 // light 1
2403 }, [](SpellInfo* spellInfo)
2404 {
2405 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2406 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2407 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2408 spellInfo->Effects[EFFECT_1].Effect = 0;
2409 spellInfo->Effects[EFFECT_2].Effect = 0;
2410 });
2411
2413 67274 // light surge 1
2414 }, [](SpellInfo* spellInfo)
2415 {
2416 spellInfo->ExcludeTargetAuraSpell = 67222;
2417 });
2418
2420 67297 // light 2
2421 }, [](SpellInfo* spellInfo)
2422 {
2423 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2424 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2425 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2426 spellInfo->Effects[EFFECT_1].Effect = 0;
2427 spellInfo->Effects[EFFECT_2].Effect = 0;
2428 });
2429
2431 67275 // light surge 2
2432 }, [](SpellInfo* spellInfo)
2433 {
2434 spellInfo->ExcludeTargetAuraSpell = 67223;
2435 });
2436
2438 67298 // light 3
2439 }, [](SpellInfo* spellInfo)
2440 {
2441 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2442 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2443 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2444 spellInfo->Effects[EFFECT_1].Effect = 0;
2445 spellInfo->Effects[EFFECT_2].Effect = 0;
2446 });
2447
2449 67276 // light surge 3
2450 }, [](SpellInfo* spellInfo)
2451 {
2452 spellInfo->ExcludeTargetAuraSpell = 67224;
2453 });
2454
2456 66001 // dark 0
2457 }, [](SpellInfo* spellInfo)
2458 {
2459 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2460 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2461 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2462 spellInfo->Effects[EFFECT_1].Effect = 0;
2463 spellInfo->Effects[EFFECT_2].Effect = 0;
2464 });
2465
2467 65769 // dark surge 0
2468 }, [](SpellInfo* spellInfo)
2469 {
2470 spellInfo->ExcludeTargetAuraSpell = 65684;
2471 });
2472
2474 67281 // dark 1
2475 }, [](SpellInfo* spellInfo)
2476 {
2477 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2478 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2479 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2480 spellInfo->Effects[EFFECT_1].Effect = 0;
2481 spellInfo->Effects[EFFECT_2].Effect = 0;
2482 });
2483
2485 67265 // dark surge 1
2486 }, [](SpellInfo* spellInfo)
2487 {
2488 spellInfo->ExcludeTargetAuraSpell = 67176;
2489 });
2490
2492 67282 // dark 2
2493 }, [](SpellInfo* spellInfo)
2494 {
2495 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2496 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2497 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2498 spellInfo->Effects[EFFECT_1].Effect = 0;
2499 spellInfo->Effects[EFFECT_2].Effect = 0;
2500 });
2501
2503 67266 // dark surge 2
2504 }, [](SpellInfo* spellInfo)
2505 {
2506 spellInfo->ExcludeTargetAuraSpell = 67177;
2507 });
2508
2510 67283 // dark 3
2511 }, [](SpellInfo* spellInfo)
2512 {
2513 //spellInfo->Effects[EFFECT_0].ApplyAuraNames = SPELL_AURA_PERIODIC_DUMMY;
2514 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2515 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2516 spellInfo->Effects[EFFECT_1].Effect = 0;
2517 spellInfo->Effects[EFFECT_2].Effect = 0;
2518 });
2519
2521 67267 // dark surge 3
2522 }, [](SpellInfo* spellInfo)
2523 {
2524 spellInfo->ExcludeTargetAuraSpell = 67178;
2525 });
2526
2527 // Trial of the Crusader, Twin Valkyr, Twin's Pact
2528 ApplySpellFix({ 65875, 67303, 67304, 67305, 65876, 67306, 67307, 67308 }, [](SpellInfo* spellInfo)
2529 {
2530 spellInfo->Effects[EFFECT_1].Effect = 0;
2531 spellInfo->Effects[EFFECT_2].Effect = 0;
2532 });
2533
2534 // Trial of the Crusader, Anub'arak, Emerge
2535 ApplySpellFix({ 65982 }, [](SpellInfo* spellInfo)
2536 {
2537 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_WHILE_STUNNED;
2538 });
2539
2540 // Trial of the Crusader, Anub'arak, Penetrating Cold
2541 ApplySpellFix({ 66013, 67700, 68509, 68510 }, [](SpellInfo* spellInfo)
2542 {
2543 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
2544 });
2545
2546 // Trial of the Crusader, Anub'arak, Shadow Strike
2547 ApplySpellFix({ 66134 }, [](SpellInfo* spellInfo)
2548 {
2549 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
2550 spellInfo->Effects[EFFECT_0].Effect = 0;
2551 });
2552
2553 // Trial of the Crusader, Anub'arak, Pursuing Spikes
2554 ApplySpellFix({ 65920, 65922, 65923 }, [](SpellInfo* spellInfo)
2555 {
2556 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PERIODIC_DUMMY;
2557 //spellInfo->EffectTriggerSpell[0] = 0;
2558 });
2559
2560 // Trial of the Crusader, Anub'arak, Summon Scarab
2561 ApplySpellFix({ 66339 }, [](SpellInfo* spellInfo)
2562 {
2563 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(35);
2564 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
2565 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2566 });
2567
2568 // Trial of the Crusader, Anub'arak, Achievements: The Traitor King
2570 68186, // Anub'arak Scarab Achievement 10
2571 68515 // Anub'arak Scarab Achievement 25
2572 }, [](SpellInfo* spellInfo)
2573 {
2574 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2575 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
2576 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD;
2577 });
2578
2579 // Trial of the Crusader, Anub'arak, Spider Frenzy
2580 ApplySpellFix({ 66129 }, [](SpellInfo* spellInfo)
2581 {
2582 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
2583 });
2584
2585 // Soul Sickness
2586 ApplySpellFix({ 69131 }, [](SpellInfo* spellInfo)
2587 {
2588 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PERIODIC_TRIGGER_SPELL;
2589 spellInfo->Effects[EFFECT_0].Amplitude = 8000;
2590 spellInfo->Effects[EFFECT_0].TriggerSpell = 69133;
2591 });
2592
2593 // Phantom Blast
2594 ApplySpellFix({ 68982, 70322 }, [](SpellInfo* spellInfo)
2595 {
2596 spellInfo->InterruptFlags |= SPELL_INTERRUPT_FLAG_INTERRUPT;
2597 });
2598
2599 // Empowered Blizzard
2600 ApplySpellFix({ 70131 }, [](SpellInfo* spellInfo)
2601 {
2602 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2603 });
2604
2605 // Ice Lance Volley
2606 ApplySpellFix({ 70464 }, [](SpellInfo* spellInfo)
2607 {
2608 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2609 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2610 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_70_YARDS);
2611 });
2612
2614 70513, // Multi-Shot
2615 59514 // Shriek of the Highborne
2616 }, [](SpellInfo* spellInfo)
2617 {
2618 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CONE_ENTRY);
2619 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2620 });
2621
2622 // Icicle
2623 ApplySpellFix({ 69428, 69426 }, [](SpellInfo* spellInfo)
2624 {
2625 spellInfo->InterruptFlags = 0;
2626 spellInfo->AuraInterruptFlags = 0;
2627 spellInfo->ChannelInterruptFlags = 0;
2628 });
2629
2630 ApplySpellFix({ 70525, 70639 }, [](SpellInfo* spellInfo)
2631 {
2632 spellInfo->Effects[EFFECT_0].Effect = 0;
2633 spellInfo->Effects[EFFECT_1].Effect = 0;
2634 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
2635 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
2636 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_500_YARDS); // 500yd
2637 });
2638
2639 // Frost Nova
2640 ApplySpellFix({ 68198 }, [](SpellInfo* spellInfo)
2641 {
2642 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13);
2643 spellInfo->Targets |= TARGET_FLAG_DEST_LOCATION;
2644 });
2645
2646 // Blight
2647 ApplySpellFix({ 69604, 70286 }, [](SpellInfo* spellInfo)
2648 {
2649 spellInfo->MaxAffectedTargets = 1;
2650 spellInfo->AttributesEx3 |= (SPELL_ATTR3_ALWAYS_HIT | SPELL_ATTR3_ONLY_ON_PLAYER);
2651 });
2652
2653 // Chilling Wave
2654 ApplySpellFix({ 68778, 70333 }, [](SpellInfo* spellInfo)
2655 {
2656 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ENEMY);
2657 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2658 });
2659
2660 ApplySpellFix({ 68786, 70336 }, [](SpellInfo* spellInfo)
2661 {
2662 spellInfo->AttributesEx3 |= (SPELL_ATTR3_ALWAYS_HIT | SPELL_ATTR3_ONLY_ON_PLAYER);
2663 spellInfo->Effects[EFFECT_2].Effect = SPELL_EFFECT_DUMMY;
2664 });
2665
2666 // Pursuit
2667 ApplySpellFix({ 68987 }, [](SpellInfo* spellInfo)
2668 {
2669 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2670 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2671 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2672 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
2673 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
2674 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo();
2675 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100yd
2676 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
2677 });
2678
2679 ApplySpellFix({ 69029, 70850 }, [](SpellInfo* spellInfo)
2680 {
2681 spellInfo->Effects[EFFECT_2].Effect = 0;
2682 });
2683
2684 // Explosive Barrage
2685 ApplySpellFix({ 69263 }, [](SpellInfo* spellInfo)
2686 {
2687 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_MOD_STUN;
2688 });
2689
2690 // Overlord's Brand
2691 ApplySpellFix({ 69172 }, [](SpellInfo* spellInfo)
2692 {
2693 spellInfo->ProcFlags = DONE_HIT_PROC_FLAG_MASK & ~PROC_FLAG_DONE_PERIODIC;
2694 spellInfo->ProcChance = 100;
2695 });
2696
2697 // Icy Blast
2698 ApplySpellFix({ 69232 }, [](SpellInfo* spellInfo)
2699 {
2700 spellInfo->Effects[EFFECT_1].TriggerSpell = 69238;
2701 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2702 });
2703
2704 ApplySpellFix({ 69233, 69646 }, [](SpellInfo* spellInfo)
2705 {
2706 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2707 });
2708
2709 ApplySpellFix({ 69238, 69628 }, [](SpellInfo* spellInfo)
2710 {
2711 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2712 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_DEST_DYNOBJ_NONE);
2713 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2714 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_DEST_DYNOBJ_NONE);
2715 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2716 });
2717
2718 // Hoarfrost
2719 ApplySpellFix({ 69246, 69245, 69645 }, [](SpellInfo* spellInfo)
2720 {
2721 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2722 });
2723
2724 // Devour Humanoid
2725 ApplySpellFix({ 69503 }, [](SpellInfo* spellInfo)
2726 {
2727 spellInfo->ChannelInterruptFlags |= 0;
2728 spellInfo->AuraInterruptFlags = AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING;
2729 });
2730
2731 // Falric: Defiling Horror
2732 ApplySpellFix({ 72435, 72452 }, [](SpellInfo* spellInfo)
2733 {
2734 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
2735 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
2736 });
2737
2738 // Frostsworn General - Throw Shield
2739 ApplySpellFix({ 69222, 73076 }, [](SpellInfo* spellInfo)
2740 {
2741 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
2742 });
2743
2744 // Halls of Reflection Clone
2745 ApplySpellFix({ 69828 }, [](SpellInfo* spellInfo)
2746 {
2747 spellInfo->Effects[EFFECT_1].Effect = 0;
2748 spellInfo->Effects[EFFECT_2].Effect = 0;
2749 });
2750
2751 // Summon Ice Wall
2752 ApplySpellFix({ 69768 }, [](SpellInfo* spellInfo)
2753 {
2754 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2755 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL;
2756 });
2757
2758 ApplySpellFix({ 69767 }, [](SpellInfo* spellInfo)
2759 {
2760 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ANY);
2761 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2762 });
2763
2764 // Essence of the Captured
2765 ApplySpellFix({ 73035, 70719 }, [](SpellInfo* spellInfo)
2766 {
2767 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13);
2768 });
2769
2770 // Achievement Check
2771 ApplySpellFix({ 72830 }, [](SpellInfo* spellInfo)
2772 {
2773 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
2774 });
2775
2777 70781, // Light's Hammer Teleport
2778 70856, // Oratory of the Damned Teleport
2779 70857, // Rampart of Skulls Teleport
2780 70858, // Deathbringer's Rise Teleport
2781 70859, // Upper Spire Teleport
2782 70860, // Frozen Throne Teleport
2783 70861 // Sindragosa's Lair Teleport
2784 }, [](SpellInfo* spellInfo)
2785 {
2786 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2787 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2788 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB); // this target is for SPELL_EFFECT_TELEPORT_UNITS
2789 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
2790 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2791 spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo();
2792 });
2793
2795 70960, // Bone Flurry
2796 71258 // Adrenaline Rush (Ymirjar Battle-Maiden)
2797 }, [](SpellInfo* spellInfo)
2798 {
2799 spellInfo->AttributesEx &= ~SPELL_ATTR1_IS_SELF_CHANNELED;
2800 });
2801
2802 // Saber Lash (Lord Marrowgar)
2803 ApplySpellFix({ 69055, 70814 }, [](SpellInfo* spellInfo)
2804 {
2805 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_5_YARDS); // 5yd
2806 });
2807
2808 // Impaled (Lord Marrowgar)
2809 ApplySpellFix({ 69065 }, [](SpellInfo* spellInfo)
2810 {
2811 spellInfo->Effects[EFFECT_0].Effect = 0; // remove stun so Dispersion can be used
2812 });
2813
2814 // Cold Flame (Lord Marrowgar)
2815 ApplySpellFix({ 72701, 72702, 72703, 72704 }, [](SpellInfo* spellInfo)
2816 {
2817 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
2818 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2819 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
2820 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(9); // 30 secs instead of 12, need him for longer, but will stop his actions after 12 secs
2821 });
2822
2823 ApplySpellFix({ 69138 }, [](SpellInfo* spellInfo)
2824 {
2825 spellInfo->Effects[EFFECT_0].Effect = 0;
2826 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
2827 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(9); // 30 secs instead of 12, need him for longer, but will stop his actions after 12 secs
2828 });
2829
2830 ApplySpellFix({ 69146, 70823, 70824, 70825 }, [](SpellInfo* spellInfo)
2831 {
2832 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS); // 3yd instead of 5yd
2833 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
2834 });
2835
2836 // Dark Martyrdom (Lady Deathwhisper)
2837 ApplySpellFix({ 70897 }, [](SpellInfo* spellInfo)
2838 {
2839 spellInfo->AttributesEx2 |= SPELL_ATTR2_ALLOW_DEAD_TARGET;
2840 });
2841
2843 69075, // Bone Storm (Lord Marrowgar)
2844 70834, // Bone Storm (Lord Marrowgar)
2845 70835, // Bone Storm (Lord Marrowgar)
2846 70836, // Bone Storm (Lord Marrowgar)
2847 72378, // Blood Nova (Deathbringer Saurfang)
2848 73058, // Blood Nova (Deathbringer Saurfang)
2849 72769, // Scent of Blood (Deathbringer Saurfang)
2850 72385, // Boiling Blood (Deathbringer Saurfang)
2851 72441, // Boiling Blood (Deathbringer Saurfang)
2852 72442, // Boiling Blood (Deathbringer Saurfang)
2853 72443, // Boiling Blood (Deathbringer Saurfang)
2854 71160, // Plague Stench (Stinky)
2855 71161, // Plague Stench (Stinky)
2856 71123, // Decimate (Stinky & Precious)
2857 71464 // Divine Surge (Sister Svalna)
2858 }, [](SpellInfo* spellInfo)
2859 {
2860 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
2861 });
2862
2863 // Shadow's Fate
2864 ApplySpellFix({ 71169 }, [](SpellInfo* spellInfo)
2865 {
2866 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
2867 });
2868
2869 // Lock Players and Tap Chest
2870 ApplySpellFix({ 72347 }, [](SpellInfo* spellInfo)
2871 {
2872 spellInfo->AttributesEx3 &= ~SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
2873 });
2874
2875 // Award Reputation - Boss Kill
2876 ApplySpellFix({ 73843, 73844, 73845, 73846 }, [](SpellInfo* spellInfo)
2877 {
2878 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS);
2879 });
2880
2881 // Death Plague (Rotting Frost Giant)
2882 ApplySpellFix({ 72864 }, [](SpellInfo* spellInfo)
2883 {
2884 spellInfo->ExcludeTargetAuraSpell = 0;
2885 });
2886
2887 // Gunship Battle, spell Below Zero
2888 ApplySpellFix({ 69705 }, [](SpellInfo* spellInfo)
2889 {
2890 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
2891 });
2892
2893 // Resistant Skin (Deathbringer Saurfang adds)
2894 ApplySpellFix({ 72723 }, [](SpellInfo* spellInfo)
2895 {
2896 // this spell initially granted Shadow damage immunity, however it was removed but the data was left in client
2897 spellInfo->Effects[EFFECT_2].Effect = 0;
2898 });
2899
2900 // Mark of the Fallen Champion (Deathbringer Saurfang)
2901 ApplySpellFix({ 72255, 72444, 72445, 72446 }, [](SpellInfo* spellInfo)
2902 {
2903 // Patch 3.3.2 (2010-01-02): Deathbringer Saurfang will no longer gain blood power from Mark of the Fallen Champion.
2904 // prevented in script, effect needed for Prayer of Mending
2905 spellInfo->AttributesEx3 &= ~SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
2906 });
2907
2908 // Coldflame Jets (Traps after Saurfang)
2909 ApplySpellFix({ 70460 }, [](SpellInfo* spellInfo)
2910 {
2911 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(1); // 10 seconds
2912 });
2913
2915 70461, // Coldflame Jets (Traps after Saurfang)
2916 71289 // Dominate Mind (Lady Deathwhisper)
2917 }, [](SpellInfo* spellInfo)
2918 {
2919 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
2920 });
2921
2922 // Severed Essence (Val'kyr Herald)
2923 ApplySpellFix({ 71906, 71942 }, [](SpellInfo* spellInfo)
2924 {
2925 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
2926 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
2927 spellInfo->Effects[EFFECT_1].Effect = 0;
2928 });
2929
2931 71159, // Awaken Plagued Zombies (Precious)
2932 71302 // Awaken Ymirjar Fallen (Ymirjar Deathbringer)
2933 }, [](SpellInfo* spellInfo)
2934 {
2935 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21);
2936 });
2937
2938 // Blood Prince Council, Invocation of Blood
2939 ApplySpellFix({ 70981, 70982, 70952 }, [](SpellInfo* spellInfo)
2940 {
2941 spellInfo->Effects[EFFECT_0].Effect = 0; // clear share health aura
2942 });
2943
2944 // Ymirjar Frostbinder, Frozen Orb
2945 ApplySpellFix({ 71274 }, [](SpellInfo* spellInfo)
2946 {
2947 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(6);
2948 });
2949
2950 // Ooze Flood (Rotface)
2951 ApplySpellFix({ 69783, 69797, 69799, 69802 }, [](SpellInfo* spellInfo)
2952 {
2953 spellInfo->AttributesEx |= SPELL_ATTR1_EXCLUDE_CASTER;
2954 });
2955
2956 // Volatile Ooze Beam Protection
2957 ApplySpellFix({ 70530 }, [](SpellInfo* spellInfo)
2958 {
2959 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AURA; // blizzard typo, 65 instead of 6, aura itself is defined (dummy)
2960 });
2961
2962 // Professor Putricide, Gaseous Bloat (Orange Ooze Channel)
2963 ApplySpellFix({ 70672, 72455, 72832, 72833 }, [](SpellInfo* spellInfo)
2964 {
2965 // copied attributes from Green Ooze Channel
2966 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
2967 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
2968 });
2969
2971 71412, // Green Ooze Summon (Professor Putricide)
2972 71415 // Orange Ooze Summon (Professor Putricide)
2973 }, [](SpellInfo* spellInfo)
2974 {
2975 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
2976 });
2977
2979 71621, // Create Concoction (Professor Putricide)
2980 72850,
2981 72851,
2982 72852,
2983 71893, // Guzzle Potions (Professor Putricide)
2984 73120,
2985 73121,
2986 73122
2987 }, [](SpellInfo* spellInfo)
2988 {
2989 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(15); // 4 sec
2990 });
2991
2992 // Mutated Plague (Professor Putricide)
2993 ApplySpellFix({ 72454, 72464, 72506, 72507 }, [](SpellInfo* spellInfo)
2994 {
2995 spellInfo->AttributesEx4 |= SPELL_ATTR4_NO_CAST_LOG;
2996 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
2997 });
2998
2999 // Unbound Plague (Professor Putricide) (needs target selection script)
3000 ApplySpellFix({ 70911, 72854, 72855, 72856 }, [](SpellInfo* spellInfo)
3001 {
3002 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
3003 });
3004
3005 // Mutated Transformation (Professor Putricide)
3006 ApplySpellFix({ 70402, 72511, 72512, 72513 }, [](SpellInfo* spellInfo)
3007 {
3008 spellInfo->AttributesEx2 |= SPELL_ATTR2_CANT_CRIT;
3009 });
3010
3011 // Empowered Flare (Blood Prince Council)
3012 ApplySpellFix({ 71708, 72785, 72786, 72787 }, [](SpellInfo* spellInfo)
3013 {
3014 spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_MODIFIERS;
3015 });
3016
3018 71518, // Unholy Infusion Quest Credit (Professor Putricide)
3019 72934, // Blood Infusion Quest Credit (Blood-Queen Lana'thel)
3020 72289 // Frost Infusion Quest Credit (Sindragosa)
3021 }, [](SpellInfo* spellInfo)
3022 {
3023 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // another missing radius
3024 });
3025
3026 // Swarming Shadows
3027 ApplySpellFix({ 71266, 72890 }, [](SpellInfo* spellInfo)
3028 {
3029 spellInfo->AreaGroupId = 0; // originally, these require area 4522, which is... outside of Icecrown Citadel
3030 });
3031
3033 71301, // Summon Dream Portal (Valithria Dreamwalker)
3034 71977 // Summon Nightmare Portal (Valithria Dreamwalker)
3035 }, [](SpellInfo* spellInfo)
3036 {
3037 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
3038 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
3039 });
3040
3041 // Column of Frost (visual marker)
3042 ApplySpellFix({ 70715 }, [](SpellInfo* spellInfo)
3043 {
3044 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(32); // 6 seconds (missing)
3045 });
3046
3047 // Mana Void (periodic aura)
3048 ApplySpellFix({ 71085 }, [](SpellInfo* spellInfo)
3049 {
3050 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(9); // 30 seconds (missing)
3051 });
3052
3053 // Summon Suppressor (needs target selection script)
3054 ApplySpellFix({ 70936 }, [](SpellInfo* spellInfo)
3055 {
3056 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3057 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
3058 });
3059
3060 // Corruption
3061 ApplySpellFix({ 70602 }, [](SpellInfo* spellInfo)
3062 {
3063 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
3064 });
3065
3067 72706, // Achievement Check (Valithria Dreamwalker)
3068 71357 // Order Whelp
3069 }, [](SpellInfo* spellInfo)
3070 {
3071 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3072 });
3073
3074 // Sindragosa's Fury
3075 ApplySpellFix({ 70598 }, [](SpellInfo* spellInfo)
3076 {
3077 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
3078 });
3079
3080 // Tail Smash (Sindragosa)
3081 ApplySpellFix({ 71077 }, [](SpellInfo* spellInfo)
3082 {
3083 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3084 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER_BACK);
3085 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_DEST_AREA_ENEMY);
3086 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER_BACK);
3087 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_DEST_AREA_ENEMY);
3088 });
3089
3090 // Frost Bomb
3091 ApplySpellFix({ 69846 }, [](SpellInfo* spellInfo)
3092 {
3093 spellInfo->Speed = 0.0f; // This spell's summon happens instantly
3094 });
3095
3096 // Mystic Buffet (Sindragosa)
3097 ApplySpellFix({ 70127, 72528, 72529, 72530 }, [](SpellInfo* spellInfo)
3098 {
3099 spellInfo->Effects[EFFECT_1].Effect = 0; // remove obsolete spell effect with no targets
3100 });
3101
3102 // Sindragosa, Frost Aura
3103 ApplySpellFix({ 70084, 71050, 71051, 71052 }, [](SpellInfo* spellInfo)
3104 {
3105 spellInfo->Attributes &= ~SPELL_ATTR0_NO_IMMUNITIES;
3106 });
3107
3108 // Ice Lock
3109 ApplySpellFix({ 71614 }, [](SpellInfo* spellInfo)
3110 {
3111 spellInfo->Mechanic = MECHANIC_STUN;
3112 });
3113
3114 // Lich King, Infest
3115 ApplySpellFix({ 70541, 73779, 73780, 73781 }, [](SpellInfo* spellInfo)
3116 {
3117 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3118 });
3119
3120 // Lich King, Necrotic Plague
3121 ApplySpellFix({ 70337, 73912, 73913, 73914, 70338, 73785, 73786, 73787 }, [](SpellInfo* spellInfo)
3122 {
3123 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
3124 });
3125
3127 69099, // Ice Pulse 10n
3128 73776, // Ice Pulse 25n
3129 73777, // Ice Pulse 10h
3130 73778 // Ice Pulse 25h
3131 }, [](SpellInfo* spellInfo)
3132 {
3133 spellInfo->AttributesEx2 |= SPELL_ATTR2_CANT_CRIT;
3134 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
3135 });
3136
3137 // Fury of Frostmourne
3138 ApplySpellFix({ 72350 }, [](SpellInfo* spellInfo)
3139 {
3140 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3141 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3142 });
3143
3145 72351, // Fury of Frostmourne
3146 72431, // Jump (removes Fury of Frostmourne debuff)
3147 72429, // Mass Resurrection
3148 73159 // Play Movie
3149 }, [](SpellInfo* spellInfo)
3150 {
3151 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3152 });
3153
3154 // Raise Dead
3155 ApplySpellFix({ 72376 }, [](SpellInfo* spellInfo)
3156 {
3157 spellInfo->MaxAffectedTargets = 4;
3158 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3159 });
3160
3161 // Jump
3162 ApplySpellFix({ 71809 }, [](SpellInfo* spellInfo)
3163 {
3164 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(5); // 40yd
3165 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
3166 spellInfo->Effects[EFFECT_0].MiscValue = 190;
3167 });
3168
3169 // Broken Frostmourne
3170 ApplySpellFix({ 72405 }, [](SpellInfo* spellInfo)
3171 {
3172 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3173 });
3174
3175 // Summon Shadow Trap
3176 ApplySpellFix({ 73540 }, [](SpellInfo* spellInfo)
3177 {
3178 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(3); // 60 seconds
3179 });
3180
3181 // Shadow Trap (visual)
3182 ApplySpellFix({ 73530 }, [](SpellInfo* spellInfo)
3183 {
3184 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(28); // 5 seconds
3185 });
3186
3187 // Shadow Trap
3188 ApplySpellFix({ 73529 }, [](SpellInfo* spellInfo)
3189 {
3190 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
3191 });
3192
3193 // Shadow Trap (searcher)
3194 ApplySpellFix({ 74282 }, [](SpellInfo* spellInfo)
3195 {
3196 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS); // 3yd
3197 });
3198
3199 // Raging Spirit Visual
3200 ApplySpellFix({ 69198 }, [](SpellInfo* spellInfo)
3201 {
3202 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
3203 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3204 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
3205 });
3206
3207 // Defile
3208 ApplySpellFix({ 72762 }, [](SpellInfo* spellInfo)
3209 {
3210 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(559); // 53 seconds
3211 spellInfo->ExcludeCasterAuraSpell = 0;
3212 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
3214 });
3215
3216 // Defile
3217 ApplySpellFix({ 72743 }, [](SpellInfo* spellInfo)
3218 {
3219 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(22); // 45 seconds
3220 });
3221
3222 ApplySpellFix({ 72754, 73708, 73709, 73710 }, [](SpellInfo* spellInfo)
3223 {
3224 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3225 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3226 });
3227
3228 // Val'kyr Target Search
3229 ApplySpellFix({ 69030 }, [](SpellInfo* spellInfo)
3230 {
3231 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3232 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3233 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
3234 });
3235
3236 // Harvest Souls
3237 ApplySpellFix({ 73654, 74295, 74296, 74297 }, [](SpellInfo* spellInfo)
3238 {
3239 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3240 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3241 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3242 });
3243
3244 // Restore Soul
3245 ApplySpellFix({ 72595, 73650 }, [](SpellInfo* spellInfo)
3246 {
3247 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3248 });
3249
3250 // Kill Frostmourne Players
3251 ApplySpellFix({ 75127 }, [](SpellInfo* spellInfo)
3252 {
3253 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3254 });
3255
3256 // Harvest Soul
3257 ApplySpellFix({ 73655 }, [](SpellInfo* spellInfo)
3258 {
3259 spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_MODIFIERS;
3260 });
3261
3262 // Destroy Soul
3263 ApplySpellFix({ 74086 }, [](SpellInfo* spellInfo)
3264 {
3265 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3266 });
3267
3268 // Summon Spirit Bomb
3269 ApplySpellFix({ 74302, 74342 }, [](SpellInfo* spellInfo)
3270 {
3271 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3272 spellInfo->MaxAffectedTargets = 1;
3273 });
3274
3275 // Summon Spirit Bomb
3276 ApplySpellFix({ 74341, 74343 }, [](SpellInfo* spellInfo)
3277 {
3278 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3279 spellInfo->MaxAffectedTargets = 3;
3280 });
3281
3282 // Summon Spirit Bomb
3283 ApplySpellFix({ 73579 }, [](SpellInfo* spellInfo)
3284 {
3285 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_25_YARDS); // 25yd
3286 });
3287
3288 // Trigger Vile Spirit (Inside, Heroic)
3289 ApplySpellFix({ 73582 }, [](SpellInfo* spellInfo)
3290 {
3291 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3292 });
3293
3294 // Scale Aura (used during Dominate Mind from Lady Deathwhisper)
3295 ApplySpellFix({ 73261 }, [](SpellInfo* spellInfo)
3296 {
3297 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
3298 });
3299
3300 // Leap to a Random Location
3301 ApplySpellFix({ 70485 }, [](SpellInfo* spellInfo)
3302 {
3303 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100yd
3304 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS);
3305 spellInfo->Effects[EFFECT_0].MiscValue = 100;
3306 });
3307
3308 // Empowered Blood
3309 ApplySpellFix({ 70227, 70232 }, [](SpellInfo* spellInfo)
3310 {
3311 spellInfo->AreaGroupId = 2452; // Whole icc instead of Crimson Halls only, remove when area calculation is fixed
3312 });
3313
3314 ApplySpellFix({ 74509 }, [](SpellInfo* spellInfo)
3315 {
3316 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd
3317 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd
3318 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd
3319 });
3320
3321 // Rallying Shout
3322 ApplySpellFix({ 75414 }, [](SpellInfo* spellInfo)
3323 {
3324 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd
3325 });
3326
3327 // Barrier Channel
3328 ApplySpellFix({ 76221 }, [](SpellInfo* spellInfo)
3329 {
3330 spellInfo->ChannelInterruptFlags &= ~(AURA_INTERRUPT_FLAG_TURNING | AURA_INTERRUPT_FLAG_MOVE);
3331 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_NEARBY_ENTRY);
3332 });
3333
3334 // Intimidating Roar
3335 ApplySpellFix({ 74384 }, [](SpellInfo* spellInfo)
3336 {
3337 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3338 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3339 });
3340
3342 74562, // Fiery Combustion
3343 74792 // Soul Consumption
3344 }, [](SpellInfo* spellInfo)
3345 {
3346 spellInfo->AttributesEx |= SPELL_ATTR1_NO_REDIRECTION;
3347 });
3348
3349 // Combustion
3350 ApplySpellFix({ 75883, 75884 }, [](SpellInfo* spellInfo)
3351 {
3352 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_6_YARDS); // 6yd
3353 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_6_YARDS); // 6yd
3354 });
3355
3356 // Consumption
3357 ApplySpellFix({ 75875, 75876 }, [](SpellInfo* spellInfo)
3358 {
3359 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_6_YARDS); // 6yd
3360 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_6_YARDS); // 6yd
3361 spellInfo->Effects[EFFECT_0].Mechanic = MECHANIC_NONE;
3362 spellInfo->Effects[EFFECT_1].Mechanic = MECHANIC_SNARE;
3363 });
3364
3365 // Soul Consumption
3366 ApplySpellFix({ 74799 }, [](SpellInfo* spellInfo)
3367 {
3368 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_12_YARDS); // 12yd
3369 });
3370
3371 // Twilight Cutter
3372 ApplySpellFix({ 74769, 77844, 77845, 77846 }, [](SpellInfo* spellInfo)
3373 {
3374 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3375 });
3376
3377 // Twilight Mending
3378 ApplySpellFix({ 75509 }, [](SpellInfo* spellInfo)
3379 {
3380 spellInfo->AttributesEx6 |= SPELL_ATTR6_IGNORE_PHASE_SHIFT;
3381 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3382 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3383 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
3384 });
3385
3386 // Meteor Strike
3387 ApplySpellFix({ 74637 }, [](SpellInfo* spellInfo)
3388 {
3389 spellInfo->Speed = 0;
3390 });
3391
3392 //Blazing Aura
3393 ApplySpellFix({ 75885, 75886 }, [](SpellInfo* spellInfo)
3394 {
3395 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
3396 });
3397
3399 75952, //Meteor Strike
3400 74629 //Combustion Periodic
3401 }, [](SpellInfo* spellInfo)
3402 {
3403 spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
3404 });
3405
3406 // Going Bearback
3407 ApplySpellFix({ 54897 }, [](SpellInfo* spellInfo)
3408 {
3409 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_DUMMY;
3410 spellInfo->Effects[EFFECT_1].RadiusEntry = spellInfo->Effects[EFFECT_0].RadiusEntry;
3411 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_DEST_AREA_ENTRY);
3412 });
3413
3414 // Still At It
3415 ApplySpellFix({ 51931, 51932, 51933 }, [](SpellInfo* spellInfo)
3416 {
3417 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(38);
3418 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
3419 });
3420
3421 // Rallying the Troops
3422 ApplySpellFix({ 47394 }, [](SpellInfo* spellInfo)
3423 {
3424 spellInfo->ExcludeTargetAuraSpell = 47394;
3425 });
3426
3427 // A Tangled Skein
3428 ApplySpellFix({ 51165, 51173 }, [](SpellInfo* spellInfo)
3429 {
3430 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
3431 });
3432
3434 69563, // A Cloudlet of Classy Cologne
3435 69445, // A Perfect Puff of Perfume
3436 69489 // Bonbon Blitz
3437 }, [](SpellInfo* spellInfo)
3438 {
3439 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
3440 });
3441
3442 // Control
3443 ApplySpellFix({ 30790 }, [](SpellInfo* spellInfo)
3444 {
3445 spellInfo->Effects[EFFECT_1].MiscValue = 0;
3446 });
3447
3448 // Reclusive Runemaster
3449 ApplySpellFix({ 48028 }, [](SpellInfo* spellInfo)
3450 {
3451 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
3452 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
3453 });
3454
3455 // Mastery of
3456 ApplySpellFix({ 65147 }, [](SpellInfo* spellInfo)
3457 {
3458 spellInfo->CategoryEntry = sSpellCategoryStore.LookupEntry(1244);
3459 spellInfo->CategoryRecoveryTime = 1500;
3460 });
3461
3462 // Weakness to Lightning
3463 ApplySpellFix({ 46432 }, [](SpellInfo* spellInfo)
3464 {
3465 spellInfo->AttributesEx3 &= ~SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
3466 });
3467
3468 // Wrangle Some Aether Rays!
3469 ApplySpellFix({ 40856 }, [](SpellInfo* spellInfo)
3470 {
3471 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(27); // 3000ms
3472 });
3473
3474 // The Black Knight's Orders
3475 ApplySpellFix({ 63163 }, [](SpellInfo* spellInfo)
3476 {
3477 spellInfo->Effects[EFFECT_0].BasePoints = 52390;
3478 });
3479
3480 // The Warp Rifts
3481 ApplySpellFix({ 34888 }, [](SpellInfo* spellInfo)
3482 {
3483 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(5); // 300 secs
3484 });
3485
3486 // The Smallest Creatures
3487 ApplySpellFix({ 38544 }, [](SpellInfo* spellInfo)
3488 {
3489 spellInfo->Effects[EFFECT_0].MiscValueB = 427;
3490 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(1);
3491 spellInfo->Effects[EFFECT_1].Effect = 0;
3492 });
3493
3494 // Ridding the red rocket
3495 ApplySpellFix({ 49177 }, [](SpellInfo* spellInfo)
3496 {
3497 spellInfo->Effects[EFFECT_0].BasePoints = 1; // corrects seat id (points - 1 = seatId)
3498 });
3499
3500 // Jormungar Strike
3501 ApplySpellFix({ 56513 }, [](SpellInfo* spellInfo)
3502 {
3503 spellInfo->RecoveryTime = 2000;
3504 });
3505
3507 37851, // Tag Greater Felfire Diemetradon
3508 37918 // Arcano-pince
3509 }, [](SpellInfo* spellInfo)
3510 {
3511 spellInfo->RecoveryTime = 3000;
3512 });
3513
3515 54997, // Cast Net (tooltip says 10s but sniffs say 6s)
3516 56524 // Acid Breath
3517 }, [](SpellInfo* spellInfo)
3518 {
3519 spellInfo->RecoveryTime = 6000;
3520 });
3521
3523 47911, // EMP
3524 48620, // Wing Buffet
3525 51752 // Stampy's Stompy-Stomp
3526 }, [](SpellInfo* spellInfo)
3527 {
3528 spellInfo->RecoveryTime = 10000;
3529 });
3530
3532 37727, // Touch of Darkness
3533 54996 // Ice Slick (tooltip says 20s but sniffs say 12s)
3534 }, [](SpellInfo* spellInfo)
3535 {
3536 spellInfo->RecoveryTime = 12000;
3537 });
3538
3539 // Signal Helmet to Attack
3540 ApplySpellFix({ 51748 }, [](SpellInfo* spellInfo)
3541 {
3542 spellInfo->RecoveryTime = 15000;
3543 });
3544
3546 51756, // Charge
3547 37919, //Arcano-dismantle
3548 37917 //Arcano-Cloak
3549 }, [](SpellInfo* spellInfo)
3550 {
3551 spellInfo->RecoveryTime = 20000;
3552 });
3553
3554 // Kaw the Mammoth Destroyer
3555 ApplySpellFix({ 46260 }, [](SpellInfo* spellInfo)
3556 {
3557 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3558 });
3559
3560 // That's Abominable
3561 ApplySpellFix({ 59565 }, [](SpellInfo* spellInfo)
3562 {
3563 spellInfo->Effects[EFFECT_0].MiscValueB = 1721; // controllable guardian
3564 });
3565
3566 // Investigate the Blue Recluse (1920)
3567 // Investigate the Alchemist Shop (1960)
3568 ApplySpellFix({ 9095 }, [](SpellInfo* spellInfo)
3569 {
3570 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_DUMMY;
3571 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
3572 });
3573
3574 // Gauging the Resonant Frequency (10594)
3575 ApplySpellFix({ 37390 }, [](SpellInfo* spellInfo)
3576 {
3577 spellInfo->Effects[EFFECT_0].MiscValueB = 181;
3578 });
3579
3580 // Where in the World is Hemet Nesingwary? (12521)
3581 ApplySpellFix({ 50860 }, [](SpellInfo* spellInfo)
3582 {
3583 spellInfo->Effects[EFFECT_0].BasePoints = 50860;
3584 });
3585
3586 ApplySpellFix({ 50861 }, [](SpellInfo* spellInfo)
3587 {
3588 spellInfo->Effects[EFFECT_0].BasePoints = 0;
3589 });
3590
3591 // Riding Jokkum
3592 ApplySpellFix({ 56606 }, [](SpellInfo* spellInfo)
3593 {
3594 spellInfo->Effects[EFFECT_0].BasePoints = 1;
3595 });
3596
3597 // Blightbeasts be Damned! (12072)
3598 ApplySpellFix({ 47424 }, [](SpellInfo* spellInfo)
3599 {
3600 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_NOT_ABOVEWATER;
3601 });
3602
3603 // Dark Horizon (12664), Reunited (12663)
3604 ApplySpellFix({ 52190 }, [](SpellInfo* spellInfo)
3605 {
3606 spellInfo->Effects[EFFECT_0].BasePoints = 52391 - 1;
3607 });
3608
3609 // The Sum is Greater than the Parts (13043) - Chained Grip
3610 ApplySpellFix({ 60540 }, [](SpellInfo* spellInfo)
3611 {
3612 spellInfo->Effects[EFFECT_0].MiscValue = 300;
3613 });
3614
3615 // Not a Bug (13342)
3616 ApplySpellFix({ 60531 }, [](SpellInfo* spellInfo)
3617 {
3618 spellInfo->AttributesEx2 |= SPELL_ATTR2_ALLOW_DEAD_TARGET;
3619 });
3620
3621 // Frankly, It Makes No Sense... (10672)
3622 ApplySpellFix({ 37851 }, [](SpellInfo* spellInfo)
3623 {
3624 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
3625 });
3626
3627 // Honor Challenge (12939)
3628 ApplySpellFix({ 21855 }, [](SpellInfo* spellInfo)
3629 {
3630 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
3631 });
3632
3633 // Convocation at Zol'Heb (12730)
3634 ApplySpellFix({ 52956 }, [](SpellInfo* spellInfo)
3635 {
3636 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_DEST_AREA_ENTRY);
3637 });
3638
3639 // Mangletooth
3641 7764, // Wisdom of Agamaggan
3642 10767, // Rising Spirit
3643 16610, // Razorhide
3644 16612, // Agamaggan's Strength
3645 16618, // Spirit of the Wind
3646 17013 // Agamaggan's Agility
3647 }, [](SpellInfo* spellInfo)
3648
3649 {
3650 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3651 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT;
3652 });
3653
3654 // Battle for the Undercity
3656 59892 // Cyclone fall
3657 }, [](SpellInfo* spellInfo)
3658 {
3659 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AREA_AURA_FRIEND;
3660 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
3661 spellInfo->AttributesEx &= ~SPELL_ATTR0_NO_AURA_CANCEL;
3662 spellInfo->AttributesEx3 |= SPELL_ATTR3_ONLY_ON_PLAYER;
3663 });
3664
3665 // enchant Lightweave Embroidery
3666 ApplySpellFix({ 55637 }, [](SpellInfo* spellInfo)
3667 {
3668 spellInfo->Effects[EFFECT_1].MiscValue = 126;
3669 });
3670
3672 47977, // Magic Broom
3673 65917 // Magic Rooster
3674 }, [](SpellInfo* spellInfo)
3675 {
3676 // First two effects apply auras, which shouldn't be there
3677 // due to NO_TARGET applying aura on current caster (core bug)
3678 // Just wipe effect data, to mimic blizz-behavior
3679 spellInfo->Effects[EFFECT_0].Effect = 0;
3680 spellInfo->Effects[EFFECT_1].Effect = 0;
3681 });
3682
3683 // Titanium Seal of Dalaran, Toss your luck
3684 ApplySpellFix({ 60476 }, [](SpellInfo* spellInfo)
3685 {
3686 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
3687 });
3688
3689 // Mind Amplification Dish, change charm aura
3690 ApplySpellFix({ 26740 }, [](SpellInfo* spellInfo)
3691 {
3692 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_MOD_CHARM;
3693 });
3694
3695 // Deadly Swiftness
3696 ApplySpellFix({ 31255 }, [](SpellInfo* spellInfo)
3697 {
3698 spellInfo->Effects[EFFECT_0].TriggerSpell = 22588;
3699 });
3700
3701 // Black Magic enchant
3702 ApplySpellFix({ 59630 }, [](SpellInfo* spellInfo)
3703 {
3704 spellInfo->Attributes |= SPELL_ATTR0_PASSIVE;
3705 });
3706
3707 // Precious's Ribbon
3708 ApplySpellFix({ 72968 }, [](SpellInfo* spellInfo)
3709 {
3710 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
3711 });
3712
3714 71646, // Item - Bauble of True Blood 10m
3715 71607, // Item - Bauble of True Blood 25m
3716 71610, // Item - Althor's Abacus trigger 10m
3717 71641 // Item - Althor's Abacus trigger 25m
3718 }, [](SpellInfo* spellInfo)
3719 {
3720 spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
3721 spellInfo->SpellLevel = 0;
3722 });
3723
3725 6789, // Warlock - Death Coil (Rank 1)
3726 17925, // Warlock - Death Coil (Rank 2)
3727 17926, // Warlock - Death Coil (Rank 3)
3728 27223, // Warlock - Death Coil (Rank 4)
3729 47859, // Warlock - Death Coil (Rank 5)
3730 71838, // Drain Life - Bryntroll Normal
3731 71839 // Drain Life - Bryntroll Heroic
3732 }, [](SpellInfo* spellInfo)
3733 {
3734 spellInfo->AttributesEx2 |= SPELL_ATTR2_CANT_CRIT;
3735 });
3736
3737 // Alchemist's Stone
3738 ApplySpellFix({ 17619 }, [](SpellInfo* spellInfo)
3739 {
3740 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
3741 });
3742
3743 // Stormchops
3744 ApplySpellFix({ 43730 }, [](SpellInfo* spellInfo)
3745 {
3746 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(1);
3747 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
3748 });
3749
3750 // Savory Deviate Delight (transformations), allow to mount while transformed
3751 ApplySpellFix({ 8219, 8220, 8221, 8222 }, [](SpellInfo* spellInfo)
3752 {
3753 spellInfo->Attributes &= ~SPELL_ATTR0_NO_IMMUNITIES;
3754 });
3755
3756 // Clamlette Magnifique
3757 ApplySpellFix({ 72623 }, [](SpellInfo* spellInfo)
3758 {
3759 spellInfo->Effects[EFFECT_0].BasePoints = spellInfo->Effects[EFFECT_1].BasePoints;
3760 });
3761
3762 // Compact Harvest Reaper
3763 ApplySpellFix({ 4078 }, [](SpellInfo* spellInfo)
3764 {
3765 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(6); // 10 minutes
3766 });
3767
3768 // Dragon Kite, Tuskarr Kite - Kite String
3769 ApplySpellFix({ 45192 }, [](SpellInfo* spellInfo)
3770 {
3771 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100yd
3772 });
3773
3774 // Frigid Frostling, Infrigidate
3775 ApplySpellFix({ 74960 }, [](SpellInfo* spellInfo)
3776 {
3777 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd
3778 });
3779
3780 // Apple Trap
3781 ApplySpellFix({ 43450 }, [](SpellInfo* spellInfo)
3782 {
3783 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
3784 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
3785 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_DUMMY;
3786 });
3787
3788 // Dark Iron Attack - spawn mole machine
3789 ApplySpellFix({ 43563 }, [](SpellInfo* spellInfo)
3790 {
3791 spellInfo->Effects[EFFECT_2].Effect = 0; // summon GO's manually
3792 });
3793
3794 // Throw Mug visual
3795 ApplySpellFix({ 42300 }, [](SpellInfo* spellInfo)
3796 {
3797 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3798 });
3799
3800 // Dark Iron knockback Aura
3801 ApplySpellFix({ 42299 }, [](SpellInfo* spellInfo)
3802 {
3803 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_DUMMY;
3804 spellInfo->Effects[EFFECT_0].MiscValue = 100;
3805 spellInfo->Effects[EFFECT_0].BasePoints = 79;
3806 });
3807
3808 // Chug and Chuck!
3809 ApplySpellFix({ 42436 }, [](SpellInfo* spellInfo)
3810 {
3811 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
3812 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
3813 spellInfo->MaxAffectedTargets = 0;
3814 spellInfo->ExcludeCasterAuraSpell = 42299;
3815 });
3816
3817 // Brewfest quests
3818 ApplySpellFix({ 47134, 51798 }, [](SpellInfo* spellInfo)
3819 {
3820 spellInfo->Effects[EFFECT_0].Effect = 0;
3821 });
3822
3823 // The Heart of The Storms (12998)
3824 ApplySpellFix({ 43528 }, [](SpellInfo* spellInfo)
3825 {
3826 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(18);
3827 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(25);
3828 });
3829
3830 // Water splash
3831 ApplySpellFix({ 42348 }, [](SpellInfo* spellInfo)
3832 {
3833 spellInfo->Effects[EFFECT_0].Effect = 0;
3834 });
3835
3836 // Summon Lantersn
3837 ApplySpellFix({ 44255, 44231 }, [](SpellInfo* spellInfo)
3838 {
3839 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
3840 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
3841 });
3842
3843 // Throw Head Back
3844 ApplySpellFix({ 42401 }, [](SpellInfo* spellInfo)
3845 {
3846 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_NEARBY_ENTRY);
3847 });
3848
3849 // Food
3850 ApplySpellFix({ 65418 }, [](SpellInfo* spellInfo)
3851 {
3852 spellInfo->Effects[EFFECT_2].TriggerSpell = 65410;
3853 });
3854
3855 ApplySpellFix({ 65422 }, [](SpellInfo* spellInfo)
3856 {
3857 spellInfo->Effects[EFFECT_2].TriggerSpell = 65414;
3858 });
3859
3860 ApplySpellFix({ 65419 }, [](SpellInfo* spellInfo)
3861 {
3862 spellInfo->Effects[EFFECT_2].TriggerSpell = 65416;
3863 });
3864
3865 ApplySpellFix({ 65420 }, [](SpellInfo* spellInfo)
3866 {
3867 spellInfo->Effects[EFFECT_2].TriggerSpell = 65412;
3868 });
3869
3870 ApplySpellFix({ 65421 }, [](SpellInfo* spellInfo)
3871 {
3872 spellInfo->Effects[EFFECT_2].TriggerSpell = 65415;
3873 });
3874
3875 // Stamp Out Bonfire
3876 ApplySpellFix({ 45437 }, [](SpellInfo* spellInfo)
3877 {
3878 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_DUMMY;
3879 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_NEARBY_ENTRY);
3880 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3881 });
3882
3883 // Light Bonfire (DND)
3884 ApplySpellFix({ 29831 }, [](SpellInfo* spellInfo)
3885 {
3886 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3887 });
3888
3889 // Infernal
3890 ApplySpellFix({ 33240 }, [](SpellInfo* spellInfo)
3891 {
3892 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3893 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3894 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3895 });
3896
3898 47476, // Deathknight - Strangulate
3899 15487, // Priest - Silence
3900 5211, // Druid - Bash - R1
3901 6798, // Druid - Bash - R2
3902 8983 // Druid - Bash - R3
3903 }, [](SpellInfo* spellInfo)
3904 {
3905 spellInfo->AttributesEx7 |= SPELL_ATTR7_CAN_CAUSE_INTERRUPT;
3906 });
3907
3908 // Shadowmeld
3909 ApplySpellFix({ 58984 }, [](SpellInfo* spellInfo)
3910 {
3911 spellInfo->AttributesEx3 |= SPELL_ATTR3_ONLY_ON_PLAYER;
3912 });
3913
3914 // Flare activation speed
3915 ApplySpellFix({ 1543 }, [](SpellInfo* spellInfo)
3916 {
3917 spellInfo->Speed = 0.0f;
3918 });
3919
3920 // Light's Beacon
3921 ApplySpellFix({ 53651 }, [](SpellInfo* spellInfo)
3922 {
3923 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
3924 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
3925 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
3926 });
3927
3928 // Shadow Hunter Vosh'gajin - Hex
3929 ApplySpellFix({ 16097 }, [](SpellInfo* spellInfo)
3930 {
3931 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(16);
3932 });
3933
3934 // Sacred Cleansing
3935 ApplySpellFix({ 53659 }, [](SpellInfo* spellInfo)
3936 {
3937 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(5); // 40yd
3938 });
3939
3940 // Silithyst
3941 ApplySpellFix({ 29519 }, [](SpellInfo* spellInfo)
3942 {
3943 spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_MOD_DECREASE_SPEED;
3944 spellInfo->Effects[EFFECT_0].BasePoints = -25;
3945 });
3946
3947 // Eye of Kilrogg Passive (DND)
3948 ApplySpellFix({ 2585 }, [](SpellInfo* spellInfo)
3949 {
3950 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE;
3951 });
3952
3953 // Nefarius Corruption
3954 ApplySpellFix({ 23642 }, [](SpellInfo* spellInfo)
3955 {
3956 spellInfo->MaxAffectedTargets = 1;
3957 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
3958 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
3959 });
3960
3961 // Conflagration, Horseman's Cleave
3962 ApplySpellFix({ 42380, 42587 }, [](SpellInfo* spellInfo)
3963 {
3964 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
3965 });
3966
3967 // Serverside - Summon Arcane Disruptor
3968 ApplySpellFix({ 49591 }, [](SpellInfo* spellInfo)
3969 {
3970 spellInfo->ProcChance = 101;
3971 spellInfo->Effects[EFFECT_1].Effect = 24;
3972 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(25);
3973 spellInfo->Effects[EFFECT_1].ItemType = 37888;
3974 });
3975
3976 // Serverside - Create Rocket Pack
3977 ApplySpellFix({ 70055 }, [](SpellInfo* spellInfo)
3978 {
3979 spellInfo->ProcChance = 101;
3980 spellInfo->Effects[EFFECT_1].Effect = 24;
3981 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(25);
3982 spellInfo->Effects[EFFECT_1].ItemType = 49278;
3983 });
3984
3985 // Ashenvale Outrunner Sneak
3986 // Stealth
3987 ApplySpellFix({ 20540, 32199 }, [](SpellInfo* spellInfo)
3988 {
3989 spellInfo->AuraInterruptFlags |= (AURA_INTERRUPT_FLAG_MELEE_ATTACK | AURA_INTERRUPT_FLAG_CAST);
3990 });
3991
3992 // Arcane Bolt
3993 ApplySpellFix({ 15979 }, [](SpellInfo* spellInfo)
3994 {
3995 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(3); // 20y
3996 });
3997
3998 // Mortal Shots
3999 ApplySpellFix({ 19485, 19487, 19488, 19489, 19490 }, [](SpellInfo* spellInfo)
4000 {
4001 spellInfo->Effects[EFFECT_0].SpellClassMask[0] |= 0x00004000;
4002 spellInfo->Effects[EFFECT_1].Effect = 0;
4003 });
4004
4005 // Item - Death Knight T9 Melee 4P Bonus
4006 // Item - Hunter T9 2P Bonus
4007 // Item - Paladin T9 Retribution 2P Bonus (Righteous Vengeance)
4008 ApplySpellFix({ 67118, 67150, 67188 }, [](SpellInfo* spellInfo)
4009 {
4010 spellInfo->Effects[EFFECT_1].Effect = 0;
4011 });
4012
4013 // Green Beam
4014 ApplySpellFix({31628, 31630, 31631}, [](SpellInfo* spellInfo)
4015 {
4016 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
4017 spellInfo->MaxAffectedTargets = 1;
4018 });
4019
4021 20271, 57774, // Judgement of Light
4022 20425, // Judgement of Command
4023 32220, // Judgement of Blood
4024 53407, // Judgement of Justice
4025 53408, // Judgement of Wisdom
4026 53725 // Judgement of the Martyr
4027 }, [](SpellInfo* spellInfo)
4028 {
4029 spellInfo->AttributesEx3 &= ~SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
4030 });
4031
4032 // Chaos Bolt Passive
4033 ApplySpellFix({ 58284 }, [](SpellInfo* spellInfo)
4034 {
4035 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
4036 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST;
4037 spellInfo->Effects[EFFECT_1].BasePoints = 100;
4038 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
4039 spellInfo->Effects[EFFECT_1].MiscValue = 127;
4040 spellInfo->Effects[EFFECT_1].SpellClassMask[1] = 0x00020000;
4041 });
4042
4043 // Nefarian: Shadowbolt, Shadow Command
4044 ApplySpellFix({ 22667, 22677 }, [](SpellInfo* spellInfo)
4045 {
4046 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(152); // 150 yards
4047 });
4048
4049 // Manastorm
4050 ApplySpellFix({ 21097 }, [](SpellInfo* spellInfo)
4051 {
4052 spellInfo->InterruptFlags &= ~SPELL_INTERRUPT_FLAG_INTERRUPT;
4053 });
4054
4055 // Arcane Vacuum
4056 ApplySpellFix({ 21147 }, [](SpellInfo* spellInfo)
4057 {
4058 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(4); // 30 yards
4059 spellInfo->AttributesEx3 |= SPELL_ATTR3_ONLY_ON_PLAYER;
4060 });
4061
4062 // Reflection
4063 ApplySpellFix({ 22067 }, [](SpellInfo* spellInfo)
4064 {
4065 spellInfo->Dispel = DISPEL_NONE;
4066 });
4067
4068 // Focused Assault
4069 // Brutal Assault
4070 ApplySpellFix({ 46392, 46393 }, [](SpellInfo* spellInfo)
4071 {
4072 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
4073 });
4074
4075 // Improved Blessing Protection (Nefarian Class Call)
4076 ApplySpellFix({ 23415 }, [](SpellInfo* spellInfo)
4077 {
4078 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ENEMY);
4079 });
4080
4081 // Bestial Wrath
4082 ApplySpellFix({ 19574 }, [](SpellInfo* spellInfo)
4083 {
4084 spellInfo->AttributesEx4 |= SPELL_ATTR4_AURA_EXPIRES_OFFLINE;
4085 });
4086
4087 // Shadowflame
4088 ApplySpellFix({ 22539 }, [](SpellInfo* spellInfo)
4089 {
4090 spellInfo->InterruptFlags &= ~SPELL_INTERRUPT_FLAG_INTERRUPT;
4091 });
4092
4093 // PX-238 Winter Wondervolt
4094 ApplySpellFix({ 26157, 26272, 26273, 26274 }, [](SpellInfo* spellInfo)
4095 {
4096 spellInfo->Mechanic = 0;
4097 });
4098
4099 // Calm Dragonkin
4100 ApplySpellFix({ 19872 }, [](SpellInfo* spellInfo)
4101 {
4102 spellInfo->AttributesEx |= SPELL_ATTR1_EXCLUDE_CASTER;
4103 });
4104
4105 // Cosmetic - Lightning Beam Channel
4106 ApplySpellFix({ 45537 }, [](SpellInfo* spellInfo)
4107 {
4108 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4109 });
4110
4111 // Burning Adrenaline
4112 ApplySpellFix({ 23478 }, [](SpellInfo* spellInfo)
4113 {
4114 spellInfo->Effects[EFFECT_0].BasePoints = 4374;
4115 spellInfo->Effects[EFFECT_0].DieSides = 1250;
4116 });
4117
4118 // Explosion - Razorgore
4119 ApplySpellFix({ 20038 }, [](SpellInfo* spellInfo)
4120 {
4121 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS);
4122 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
4123 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4124 });
4125
4126 // Brood Power : Bronze
4127 ApplySpellFix({ 22311 }, [](SpellInfo* spellInfo)
4128 {
4129 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
4130 });
4131
4132 // Rapture
4133 ApplySpellFix({ 63652, 63653, 63654, 63655 }, [](SpellInfo* spellInfo)
4134 {
4135 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
4136 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4137 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
4138 });
4139
4140 // Everlasting Affliction
4141 ApplySpellFix({ 47422 }, [](SpellInfo* spellInfo)
4142 {
4143 spellInfo->SchoolMask = SPELL_SCHOOL_MASK_SHADOW;
4144 });
4145
4146 // Flametongue Weapon (Passive) (Rank 6)
4147 ApplySpellFix({ 16312 }, [](SpellInfo* spellInfo)
4148 {
4149 spellInfo->Attributes |= SPELL_ATTR0_PASSIVE;
4150 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21);
4151 });
4152
4153 // Mana Tide Totem
4154 // Cleansing Totem Effect
4155 ApplySpellFix({ 39609, 52025 }, [](SpellInfo* spellInfo)
4156 {
4157 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(5); // 40yd
4158 });
4159
4160 // Increased Totem Radius
4161 ApplySpellFix({ 21895 }, [](SpellInfo* spellInfo)
4162 {
4163 spellInfo->Effects[0].SpellClassMask = flag96(0x0603E000, 0x00200100);
4164 });
4165
4166 // Jokkum Summon
4167 ApplySpellFix({ 56541 }, [](SpellInfo* spellInfo)
4168 {
4169 spellInfo->Effects[EFFECT_0].MiscValueB = 844;
4170 });
4171
4172 // Hakkar Cause Insanity
4173 ApplySpellFix({ 24327 }, [](SpellInfo* spellInfo)
4174 {
4175 spellInfo->Dispel = DISPEL_NONE;
4176 });
4177
4178 // Summon Nightmare Illusions
4179 ApplySpellFix({ 24681, 24728, 24729 }, [](SpellInfo* spellInfo)
4180 {
4181 spellInfo->Effects[EFFECT_0].MiscValueB = 64;
4182 });
4183
4184 // Blood Siphon
4185 ApplySpellFix({ 24322, 24323 }, [](SpellInfo* spellInfo)
4186 {
4187 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_MOD_STUN;
4188 spellInfo->Effects[EFFECT_2].Effect = 0;
4189 spellInfo->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
4190 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL;
4191 spellInfo->ChannelInterruptFlags &= ~AURA_INTERRUPT_FLAG_MOVE;
4192 });
4193
4194 // Place Fake Fur
4195 ApplySpellFix({ 46085 }, [](SpellInfo* spellInfo)
4196 {
4197 spellInfo->Effects[EFFECT_0].MiscValue = 8;
4198 });
4199
4200 // Smash Mammoth Trap
4201 ApplySpellFix({ 46201 }, [](SpellInfo* spellInfo)
4202 {
4203 spellInfo->Effects[EFFECT_0].MiscValue = 8;
4204 });
4205
4206 // Elemental Mastery
4207 ApplySpellFix({ 16166 }, [](SpellInfo* spellInfo)
4208 {
4209 spellInfo->Effects[EFFECT_0].SpellClassMask = flag96(0x00000003, 0x00001000);
4210 });
4211
4212 // Elemental Vulnerability
4213 ApplySpellFix({ 28772 }, [](SpellInfo* spellInfo)
4214 {
4215 spellInfo->Speed = 1;
4216 });
4217
4218 // Find the Ancient Hero: Kill Credit
4219 ApplySpellFix({ 25729 }, [](SpellInfo* spellInfo)
4220 {
4221 spellInfo->Effects[EFFECT_0].TargetA = TARGET_UNIT_SUMMONER;
4222 });
4223
4224 // Artorius Demonic Doom
4225 ApplySpellFix({ 23298 }, [](SpellInfo* spellInfo)
4226 {
4227 spellInfo->AttributesEx4 |= SPELL_ATTR4_IGNORE_DAMAGE_TAKEN_MODIFIERS;
4228 spellInfo->AttributesEx6 |= SPELL_ATTR6_IGNORE_CASTER_DAMAGE_MODIFIERS;
4229 });
4230
4231 // Lash
4232 ApplySpellFix({ 25852 }, [](SpellInfo* spellInfo)
4233 {
4234 spellInfo->Effects[EFFECT_1].Effect = 0;
4235 });
4236
4237 // Explosion
4238 ApplySpellFix({ 5255 }, [](SpellInfo* spellInfo)
4239 {
4240 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4241 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
4242 });
4243
4244 // Death's Respite
4245 ApplySpellFix({ 67731, 68305 }, [](SpellInfo* spellInfo)
4246 {
4247 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
4248 });
4249
4250 // Wyvern Sting DoT
4251 ApplySpellFix({ 24131, 24134, 24135 }, [](SpellInfo* spellInfo)
4252 {
4253 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
4254 });
4255
4256 // Feed Pet
4257 ApplySpellFix({ 1539, 51284 }, [](SpellInfo* spellInfo)
4258 {
4259 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_WHILE_SITTING;
4260 });
4261
4262 // Judgement (Paladin T2 8P Bonus)
4263 // Battlegear of Eternal Justice
4264 ApplySpellFix({ 23591, 26135 }, [](SpellInfo* spellInfo)
4265 {
4266 spellInfo->ProcFlags = PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS;
4267 });
4268
4269 // Gift of Arthas
4270 ApplySpellFix({ 11371 }, [](SpellInfo* spellInfo)
4271 {
4272 spellInfo->SpellFamilyName = SPELLFAMILY_POTION;
4273 });
4274
4275 // Refocus (Renataki's charm of beasts)
4276 ApplySpellFix({ 24531 }, [](SpellInfo* spellInfo)
4277 {
4278 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
4279 });
4280
4281 // Collect Rookery Egg
4282 ApplySpellFix({ 15958 }, [](SpellInfo* spellInfo)
4283 {
4284 spellInfo->Effects[EFFECT_1].Effect = 0;
4285 });
4286
4287 // WotLK Prologue Frozen Shade Visual, temp used to restore visual after Dispersion
4288 ApplySpellFix({ 53444 }, [](SpellInfo* spellInfo)
4289 {
4290 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(27);
4291 });
4292
4293 // Rental Racing Ram
4294 ApplySpellFix({ 43883 }, [](SpellInfo* spellInfo)
4295 {
4296 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_NOT_ABOVEWATER;
4297 });
4298
4299 // Summon Worm
4300 ApplySpellFix({ 518, 25831, 25832 }, [](SpellInfo* spellInfo)
4301 {
4302 spellInfo->Effects[EFFECT_0].MiscValueB = 64;
4303 });
4304
4305 // Uppercut
4306 ApplySpellFix({ 26007 }, [](SpellInfo* spellInfo)
4307 {
4308 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
4309 });
4310
4311 // Digestive Acid (Temporary)
4312 ApplySpellFix({ 26476 }, [](SpellInfo* spellInfo)
4313 {
4314 spellInfo->Attributes |= SPELL_ATTR0_NO_IMMUNITIES;
4315 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4316 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
4317 });
4318
4319 // Drums of War/Battle/Speed/Restoration
4320 ApplySpellFix({ 35475, 35476, 35477, 35478 }, [](SpellInfo* spellInfo)
4321 {
4322 spellInfo->ExcludeTargetAuraSpell = 51120;
4323 });
4324
4325 // Slap!
4326 ApplySpellFix({ 6754 }, [](SpellInfo* spellInfo)
4327 {
4328 spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
4329 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
4330 });
4331
4332 // Summon Cauldron Stuff
4333 ApplySpellFix({ 36549 }, [](SpellInfo* spellInfo)
4334 {
4335 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(28); // 5 seconds
4336 spellInfo->Effects[EFFECT_0].TargetB = TARGET_DEST_CASTER;
4337 });
4338
4339 // Hunter's Mark
4340 ApplySpellFix({ 31615 }, [](SpellInfo* spellInfo)
4341 {
4342 for (uint8 index = EFFECT_0; index <= EFFECT_1; ++index)
4343 {
4344 spellInfo->Effects[index].TargetA = TARGET_UNIT_TARGET_ENEMY;
4345 spellInfo->Effects[index].TargetB = 0;
4346 }
4347 });
4348
4349 // Self Visual - Sleep Until Cancelled(DND)
4350 ApplySpellFix({ 6606, 14915, 16093 }, [](SpellInfo* spellInfo)
4351 {
4352 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_NOT_SEATED;
4353 });
4354
4355 // Cleansing Totem, Healing Stream Totem, Mana Tide Totem
4356 ApplySpellFix({ 8171,52025, 52041, 52042, 52046, 52047, 52048, 52049, 52050, 58759, 58760, 58761, 39610, 39609 }, [](SpellInfo* spellInfo)
4357 {
4358 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4359 });
4360 // Game In Session
4361 ApplySpellFix({ 39331 }, [](SpellInfo* spellInfo)
4362 {
4363 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AURA;
4364 spellInfo->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
4365 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
4366 });
4367 // Death Ray Warning Visual, Death Ray Damage Visual
4368 ApplySpellFix({ 63882, 63886 }, [](SpellInfo* spellInfo)
4369 {
4370 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL;
4371 });
4372
4373 // Buffeting Winds of Susurrus
4374 ApplySpellFix({ 32474 }, [](SpellInfo* spellInfo)
4375 {
4376 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(556); // 28 seconds
4377 });
4378
4379 // Quest - Healing Salve
4380 ApplySpellFix({ 29314 }, [](SpellInfo* spellInfo)
4381 {
4382 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(1); // 0s
4383 });
4384
4385 // Seed of Corruption
4386 ApplySpellFix({ 27285, 47833, 47834 }, [](SpellInfo* spellInfo)
4387 {
4388 spellInfo->AttributesEx |= SPELL_ATTR1_NO_REFLECTION;
4389 });
4390
4391 // Turn the Tables
4392 ApplySpellFix({ 51627, 51628, 51629 }, [](SpellInfo* spellInfo)
4393 {
4394 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
4395 });
4396
4397 // Silence
4398 ApplySpellFix({ 18278 }, [](SpellInfo* spellInfo)
4399 {
4400 spellInfo->AttributesEx4 |= SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND;
4401 });
4402
4403 // Honor Among Thieves - allow area aura from different casters to coexist
4404 ApplySpellFix({ 51698, 51700, 51701 }, [](SpellInfo* spellInfo)
4405 {
4406 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
4407 });
4408
4409 // Absorb Life
4410 ApplySpellFix({ 34239 }, [](SpellInfo* spellInfo)
4411 {
4412 spellInfo->Effects[EFFECT_0].ValueMultiplier = 1;
4413 });
4414
4415 // Summon a Warp Rift in Void Ridge
4416 ApplySpellFix({ 35036 }, [](SpellInfo* spellInfo)
4417 {
4418 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(1); // 0s
4419 });
4420
4421 // Hit Rating (Dungeon T3 - 2P Bonus - Wastewalker, Doomplate)
4422 ApplySpellFix({ 37608, 37610 }, [](SpellInfo* spellInfo)
4423 {
4424 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(0);
4425 spellInfo->Effects[EFFECT_0].MiscValue = 224;
4426 });
4427
4428 // Target Fissures
4429 ApplySpellFix({ 30745 }, [](SpellInfo* spellInfo)
4430 {
4431 spellInfo->MaxAffectedTargets = 1;
4432 });
4433
4434 // Acid Spit
4435 ApplySpellFix({ 34290 }, [](SpellInfo* spellInfo)
4436 {
4437 spellInfo->MaxAffectedTargets = 1;
4438 });
4439
4440 // Mulgore Hatchling (periodic)
4441 ApplySpellFix({ 62586 }, [](SpellInfo* spellInfo)
4442 {
4443 spellInfo->Effects[EFFECT_0].TriggerSpell = 62585; // Mulgore Hatchling (fear)
4444 });
4445
4446 // Poultryized!
4447 ApplySpellFix({ 30504 }, [](SpellInfo* spellInfo)
4448 {
4449 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_TAKE_DAMAGE;
4450 });
4451
4452 // Torment of the Worgen
4453 ApplySpellFix({ 30567 }, [](SpellInfo* spellInfo)
4454 {
4455 spellInfo->ProcChance = 3;
4456 });
4457
4458 // Summon Water Elementals
4459 ApplySpellFix({ 29962, 37051, 37052, 37053 }, [](SpellInfo* spellInfo)
4460 {
4461 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
4462 });
4463
4464 // Instill Lord Valthalak's Spirit DND
4465 ApplySpellFix({ 27360 }, [](SpellInfo* spellInfo)
4466 {
4467 spellInfo->ChannelInterruptFlags |= AURA_INTERRUPT_FLAG_MOVE;
4468 });
4469
4470 // Holiday - Midsummer, Ribbon Pole Periodic Visual
4471 ApplySpellFix({ 45406 }, [](SpellInfo* spellInfo)
4472 {
4473 spellInfo->AuraInterruptFlags |= ( AURA_INTERRUPT_FLAG_MOUNT | AURA_INTERRUPT_FLAG_CAST | AURA_INTERRUPT_FLAG_TALK );
4474 });
4475
4476 // Improved Mind Flay and Smite
4477 ApplySpellFix({ 37571 }, [](SpellInfo* spellInfo)
4478 {
4479 spellInfo->Effects[EFFECT_0].SpellClassMask[0] = 8388736;
4480 });
4481
4482 // Improved Corruption and Immolate (Updated)
4483 ApplySpellFix({ 61992 }, [](SpellInfo* spellInfo)
4484 {
4485 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
4486 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_ADD_PCT_MODIFIER;
4487 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
4488 spellInfo->Effects[EFFECT_1].BasePoints = 4;
4489 spellInfo->Effects[EFFECT_1].DieSides = 1;
4490 spellInfo->Effects[EFFECT_1].MiscValue = 22;
4491 spellInfo->Effects[EFFECT_1].SpellClassMask[0] = 6;
4492 });
4493
4494 // 46747 Fling torch
4495 ApplySpellFix({ 46747 }, [](SpellInfo* spellInfo)
4496 {
4497 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
4498 });
4499
4500 // Chains of Naberius
4501 ApplySpellFix({ 36146 }, [](SpellInfo* spellInfo)
4502 {
4503 spellInfo->MaxAffectedTargets = 1;
4504 });
4505
4506 // Force of Neltharaku
4507 ApplySpellFix({ 38762 }, [](SpellInfo* spellInfo)
4508 {
4509 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
4510 });
4511
4512 // Spotlight
4513 ApplySpellFix({ 29683, 32214 }, [](SpellInfo* spellInfo)
4514 {
4515 spellInfo->AttributesEx5 |= SPELL_ATTR5_DO_NOT_DISPLAY_DURATION;
4516 });
4517
4518 // Haunted
4519 ApplySpellFix({ 53768 }, [](SpellInfo* spellInfo)
4520 {
4521 spellInfo->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
4522 });
4523
4524 // Tidal Wave
4525 ApplySpellFix({ 37730 }, [](SpellInfo* spellInfo)
4526 {
4527 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4528 });
4529
4530 // Commanding Shout
4531 ApplySpellFix({ 469, 47439, 47440 }, [](SpellInfo* spellInfo)
4532 {
4533 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4534 });
4535
4536 // Battle Shout
4537 ApplySpellFix({ 2048, 5242, 6192, 6673, 11549, 11550, 11551, 25289, 47436 }, [](SpellInfo* spellInfo)
4538 {
4539 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4540 });
4541
4542 // Plague Effect
4543 ApplySpellFix({ 19594, 26557 }, [](SpellInfo* spellInfo)
4544 {
4545 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4546 });
4547
4548 // Prayer of Fortitude
4549 ApplySpellFix({ 21562, 21564, 25392, 48162 }, [](SpellInfo* spellInfo)
4550 {
4551 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4552 });
4553
4554 // Gift of the Wild
4555 ApplySpellFix({ 21849, 21850, 26991, 48470, 69381 }, [](SpellInfo* spellInfo)
4556 {
4557 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4558 });
4559
4560 // Arcane Brilliance
4561 ApplySpellFix({ 23028, 27127, 43002 }, [](SpellInfo* spellInfo)
4562 {
4563 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4564 });
4565
4566 // Prayer of Spirit
4567 ApplySpellFix({ 27681, 32999, 48074 }, [](SpellInfo* spellInfo)
4568 {
4569 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4570 });
4571
4572 // Prayer of Shadow Protection
4573 ApplySpellFix({ 27683, 39374, 48170 }, [](SpellInfo* spellInfo)
4574 {
4575 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4576 });
4577
4578 // Nagrand Fort Buff Reward Raid
4579 ApplySpellFix({ 33006 }, [](SpellInfo* spellInfo)
4580 {
4581 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4582 });
4583
4584 // Ancestral Awakening
4585 ApplySpellFix({ 52759 }, [](SpellInfo* spellInfo)
4586 {
4587 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4588 });
4589
4590 // Turn the Tables
4591 ApplySpellFix({ 52910, 52914, 52915 }, [](SpellInfo* spellInfo)
4592 {
4593 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4594 });
4595
4596 // Judgements of the Wise
4597 ApplySpellFix({ 54180 }, [](SpellInfo* spellInfo)
4598 {
4599 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4600 });
4601
4602 // Replenishment
4603 ApplySpellFix({ 57669 }, [](SpellInfo* spellInfo)
4604 {
4605 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4606 });
4607
4608 // Dalaran Brilliance
4609 ApplySpellFix({ 61316 }, [](SpellInfo* spellInfo)
4610 {
4611 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4612 });
4613
4614 // [DND] Dalaran Brilliance
4615 ApplySpellFix({ 61332 }, [](SpellInfo* spellInfo)
4616 {
4617 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4618 });
4619
4620 // Infinite Replenishment + Wisdom
4621 ApplySpellFix({ 61782 }, [](SpellInfo* spellInfo)
4622 {
4623 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4624 });
4625
4626 // Renewed Hope
4627 ApplySpellFix({ 63944 }, [](SpellInfo* spellInfo)
4628 {
4629 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4630 });
4631
4632 // Fortitude
4633 ApplySpellFix({ 69377 }, [](SpellInfo* spellInfo)
4634 {
4635 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4636 });
4637
4638 // Blessing of Forgotten Kings
4639 ApplySpellFix({ 69378 }, [](SpellInfo* spellInfo)
4640 {
4641 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4642 });
4643
4644 // Lucky Charm
4645 ApplySpellFix({ 69511 }, [](SpellInfo* spellInfo)
4646 {
4647 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4648 });
4649
4650 // Shiny Shard of the Scale Heal Targeter
4651 ApplySpellFix({ 69749 }, [](SpellInfo* spellInfo)
4652 {
4653 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4654 });
4655
4656 // Purified Shard of the Scale Heal Targeter
4657 ApplySpellFix({ 69754 }, [](SpellInfo* spellInfo)
4658 {
4659 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4660 });
4661
4662 // Brilliance
4663 ApplySpellFix({ 69994 }, [](SpellInfo* spellInfo)
4664 {
4665 spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4666 });
4667
4668 // Domination
4669 ApplySpellFix({ 37135 }, [](SpellInfo* spellInfo)
4670 {
4671 spellInfo->MaxAffectedTargets = 5;
4672 });
4673
4674 // Presence Of Mind
4675 ApplySpellFix({ 12043 }, [](SpellInfo* spellInfo)
4676 {
4677 // It should not share cooldown mods with category[1151] spells (Arcane Power [12042], Decimate [47271])
4678 spellInfo->AttributesEx6 |= SPELL_ATTR6_NO_CATEGORY_COOLDOWN_MODS;
4679 });
4680
4681 // Eye of Grillok
4682 ApplySpellFix({ 38495 }, [](SpellInfo* spellInfo)
4683 {
4684 spellInfo->Effects[EFFECT_0].TriggerSpell = 38530; // Quest Credit for Eye of Grillok
4685 });
4686
4687 // Greater Fireball
4688 ApplySpellFix({ 33051 }, [](SpellInfo* spellInfo)
4689 {
4690 spellInfo->AttributesEx4 |= SPELL_ATTR4_NO_CAST_LOG;
4691 });
4692
4693 // Gor'drek's Ointment
4694 ApplySpellFix({ 32578 }, [](SpellInfo* spellInfo)
4695 {
4696 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
4697 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
4698 });
4699
4700 // Shadow Grasp
4701 ApplySpellFix({ 30410 }, [](SpellInfo* spellInfo)
4702 {
4703 spellInfo->AttributesEx6 |= SPELL_ATTR6_NO_PUSHBACK;
4704 });
4705
4707 471, // Palamino
4708 8980, // Skeletal Horse
4709 10788, // Leopard
4710 10790, // Tiger
4711 10792, // Spotted Panther
4712 60136, // Grand Caravan Mammoth
4713 60140 // Grand Caravan Mammoth
4714 }, [](SpellInfo* spellInfo)
4715 {
4716 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_NOT_ABOVEWATER;
4717 });
4718
4719 // Molten Punch
4720 ApplySpellFix({ 40126 }, [](SpellInfo* spellInfo)
4721 {
4722 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
4723 });
4724
4725 // Wing Buffet
4726 ApplySpellFix({ 37319 }, [](SpellInfo* spellInfo)
4727 {
4728 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CONE_ENEMY_24);
4729 spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(0);
4730 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS);
4731 });
4732
4733 // Flame Wave
4734 ApplySpellFix({ 33800 }, [](SpellInfo* spellInfo)
4735 {
4736 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
4737 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_PERIODIC_TRIGGER_SPELL;
4738 spellInfo->Effects[EFFECT_1].Amplitude = 500;
4739 });
4740
4741 // Chromatic Resistance Aura
4742 ApplySpellFix({ 41453 }, [](SpellInfo* spellInfo)
4743 {
4744 spellInfo->Effects[EFFECT_0].MiscValue = 124;
4745 });
4746
4747 // Power of the Guardian
4748 ApplySpellFix({ 28142, 28143, 28144, 28145 }, [](SpellInfo* spellInfo)
4749 {
4750 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD;
4751 });
4752
4753 // Warrior stances passives
4755 2457, // Battle Stance
4756 2458, // Berserker Stance
4757 7376 // Defensive Stance Passive
4758 }, [](SpellInfo* spellInfo)
4759 {
4760 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
4761 });
4762
4763 // Conjure Refreshment Table (Rank 1, Rank 2)
4764 ApplySpellFix({ 43985, 58661 }, [](SpellInfo* spellInfo)
4765 {
4766 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER_FRONT);
4767 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_5_YARDS);
4768 });
4769
4771 698, // Ritual of Summoning (portal for clicking)
4772 61993 // Ritual of Summoning (summons the closet)
4773 }, [](SpellInfo* spellInfo)
4774 {
4775 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS);
4776 });
4777
4778 // Paralyze
4779 ApplySpellFix({ 41083 }, [](SpellInfo* spellInfo)
4780 {
4781 spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL;
4782 });
4783
4784 // Fatal Attraction
4785 ApplySpellFix({ 40869 }, [](SpellInfo* spellInfo)
4786 {
4787 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_DEST_CASTER); // target set by script
4788 });
4789
4790 // Fatal Attraction
4791 ApplySpellFix({ 40870 }, [](SpellInfo* spellInfo)
4792 {
4793 spellInfo->MaxAffectedTargets = 1;
4794 });
4795
4796 // Removing Dragonflayer Harpoon
4797 ApplySpellFix({ 42968 }, [](SpellInfo* spellInfo)
4798 {
4799 spellInfo->MaxAffectedTargets = 1;
4800 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(7);
4801 });
4802
4803 // Siphon Life (heal)
4804 ApplySpellFix({ 63106 }, [](SpellInfo* spellInfo)
4805 {
4806 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
4807 });
4808
4809 // Fury
4810 ApplySpellFix({ 40601 }, [](SpellInfo* spellInfo)
4811 {
4812 spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
4813 });
4814
4815 // Claw Rage
4816 ApplySpellFix({ 43149 }, [](SpellInfo* spellInfo)
4817 {
4818 spellInfo->Effects[EFFECT_0].TriggerSpell = 0;
4819 });
4820
4821 // Black Qiraji Battle Tank
4822 ApplySpellFix({ 26655, 26656 }, [](SpellInfo* spellInfo)
4823 {
4824 spellInfo->AuraInterruptFlags &= ~(AURA_INTERRUPT_FLAG_CHANGE_MAP | AURA_INTERRUPT_FLAG_TELEPORTED);
4825 });
4826
4827 // Summon Cyclone
4828 ApplySpellFix({ 43112 }, [](SpellInfo* spellInfo)
4829 {
4830 spellInfo->RequiresSpellFocus = 0;
4831 });
4832
4833 // Booming Voice
4834 ApplySpellFix({ 40080 }, [](SpellInfo* spellInfo)
4835 {
4836 spellInfo->Effects[EFFECT_0].RealPointsPerLevel = 0;
4837 });
4838
4839 // Mangle (Nalorakk)
4840 ApplySpellFix({ 42389 }, [](SpellInfo* spellInfo)
4841 {
4842 spellInfo->SchoolMask = SPELL_SCHOOL_MASK_NATURE;
4843 });
4844
4845 // Event food, fixes to give correct stamina and spirit of 25% of the character level
4846 ApplySpellFix({ 24870 }, [](SpellInfo* spellInfo)
4847 {
4848 spellInfo->Effects[EFFECT_1].BasePoints = 0;
4849 spellInfo->Effects[EFFECT_0].RealPointsPerLevel = 0.25;
4850 spellInfo->Effects[EFFECT_1].RealPointsPerLevel = 0.25;
4851 });
4852
4853 // Smash
4854 // Dark Smash
4855 ApplySpellFix({ 42669, 59706, 42723, 59709 }, [](SpellInfo* spellInfo)
4856 {
4857 spellInfo->AttributesEx2 &= ~SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4858 });
4859
4860 // Swoop (Moth hunter pet) root effect fix
4861 ApplySpellFix({ 52825 }, [](SpellInfo* spellInfo)
4862 {
4863 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
4864 });
4865
4866 // Felmyst Strafe (Top)
4867 ApplySpellFix({ 45585 }, [](SpellInfo* spellInfo)
4868 {
4869 spellInfo->MaxAffectedTargets = 3;
4870 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_70_YARDS);
4871 });
4872
4873 // Felmyst Strafe (Middle, Bottom)
4874 ApplySpellFix({ 45633, 45635 }, [](SpellInfo* spellInfo)
4875 {
4876 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_70_YARDS);
4877 });
4878
4880 45662, // Encapsulate
4881 45642 // Fire Bloom
4882 }, [](SpellInfo* spellInfo)
4883 {
4884 spellInfo->AttributesEx7 |= SPELL_ATTR7_TREAT_AS_NPC_AOE;
4885 });
4886
4887 // Torch (Death Knights near the Chapel)
4888 ApplySpellFix({ 52953 }, [](SpellInfo* spellInfo)
4889 {
4890 spellInfo->MaxAffectedTargets = 1;
4891 });
4892
4893 // Missile Barrage
4894 ApplySpellFix({ 44401 }, [](SpellInfo* spellInfo)
4895 {
4896 spellInfo->ProcCharges = 1;
4897 spellInfo->SpellPriority = 100;
4898 });
4899
4900 // Auto Shot
4901 ApplySpellFix({ 75 }, [](SpellInfo* spellInfo)
4902 {
4903 spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(1); // 0s
4904 spellInfo->InterruptFlags &= ~SPELL_INTERRUPT_UNK;
4905 });
4906
4907 // Life Tap
4908 ApplySpellFix({ 1454 }, [](SpellInfo* spellInfo)
4909 {
4910 spellInfo->Effects[EFFECT_0].RealPointsPerLevel = 0.0f;
4911 });
4912
4913 // Life Tap
4914 ApplySpellFix({ 1455, 1456, 11687, 11688, 11689, 27222, 57946 }, [](SpellInfo* spellInfo)
4915 {
4916 spellInfo->Effects[EFFECT_0].RealPointsPerLevel = 0.0f;
4917 spellInfo->MaxLevel = 16;
4918 spellInfo->BaseLevel = 6;
4919 spellInfo->SpellLevel = 6;
4920 });
4921
4922 // Explosive Sheep
4923 ApplySpellFix({ 4074 }, [](SpellInfo* spellInfo)
4924 {
4925 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(25);
4926 });
4927
4928 // Phase Shift
4929 ApplySpellFix({ 4511 }, [](SpellInfo* spellInfo)
4930 {
4931 spellInfo->AuraInterruptFlags &= ~AURA_INTERRUPT_FLAG_MELEE_ATTACK;
4932 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CAST;
4933 });
4934
4935 // Charge Stun
4936 ApplySpellFix({ 7922 }, [](SpellInfo* spellInfo)
4937 {
4938 spellInfo->Attributes |= SPELL_ATTR0_NO_ACTIVE_DEFENSE;
4939 });
4940
4941 // Tharnariun's Heal
4942 ApplySpellFix({ 9457 }, [](SpellInfo* spellInfo)
4943 {
4944 spellInfo->AttributesEx2 &= ~SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
4945 spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_AND_TARGET_RESTRICTIONS;
4946 spellInfo->Effects[EFFECT_0].DieSides = 0;
4947 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
4948 });
4949
4950 // Supercharge
4951 ApplySpellFix({ 10732 }, [](SpellInfo* spellInfo)
4952 {
4953 spellInfo->CategoryEntry = sSpellCategoryStore.LookupEntry(0);
4954 spellInfo->Attributes &= ~(SPELL_ATTR0_IS_ABILITY | SPELL_ATTR0_DO_NOT_SHEATH);
4955 spellInfo->Attributes |= SPELL_ATTR0_NOT_SHAPESHIFTED;
4956 spellInfo->AttributesEx |= SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL;
4957 spellInfo->AttributesEx2 |= SPELL_ATTR2_NO_TARGET_PER_SECOND_COST;
4958 spellInfo->AttributesEx3 |= SPELL_ATTR3_CAN_PROC_FROM_PROCS;
4959 spellInfo->FacingCasterFlags |= SPELL_FACING_FLAG_INFRONT;
4960 spellInfo->InterruptFlags |= (SPELL_INTERRUPT_FLAG_MOVEMENT | SPELL_INTERRUPT_FLAG_PUSH_BACK |
4962 spellInfo->ChannelInterruptFlags &= ~AURA_INTERRUPT_FLAG_JUMP;
4963 spellInfo->ChannelInterruptFlags |= AURA_INTERRUPT_FLAG_UNK14;
4964 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ALLY);
4965 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ALLY);
4966 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ALLY);
4967 spellInfo->Effects[EFFECT_0].Amplitude = 3000;
4968 spellInfo->Effects[EFFECT_1].Amplitude = 3000;
4969 spellInfo->Effects[EFFECT_2].Amplitude = 3000;
4970 spellInfo->SpellVisual[0] = 12656;
4971 });
4972
4973 // Intercept
4974 ApplySpellFix({ 20252 }, [](SpellInfo* spellInfo)
4975 {
4977 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_ITEM_SPELL_IN_PVP;
4978 });
4979
4980 // Intercept
4981 ApplySpellFix({ 20253 }, [](SpellInfo* spellInfo)
4982 {
4984 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_ITEM_SPELL_IN_PVP;
4985 spellInfo->AttributesEx7 |= (SPELL_ATTR7_NO_ATTACK_DODGE | SPELL_ATTR7_NO_ATTACK_PARRY);
4986 spellInfo->SpellLevel = 0;
4987 });
4988
4989 // Heart of the Crusader
4990 ApplySpellFix({ 20335, 20336, 20337 }, [](SpellInfo* spellInfo)
4991 {
4992 spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
4993 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
4994 spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_DUMMY;
4995 });
4996
4997 // Heart of the Crusader (Rank 1)
4998 ApplySpellFix({ 20335 }, [](SpellInfo* spellInfo)
4999 {
5000 spellInfo->Effects[EFFECT_1].TriggerSpell = 21183; // Heart of the Crusader (Rank 1)
5001 });
5002
5003 // Heart of the Crusader (Rank 2)
5004 ApplySpellFix({ 20336 }, [](SpellInfo* spellInfo)
5005 {
5006 spellInfo->Effects[EFFECT_1].TriggerSpell = 54498; // Heart of the Crusader (Rank 2)
5007 });
5008
5009 // Heart of the Crusader (Rank 3)
5010 ApplySpellFix({ 20337 }, [](SpellInfo* spellInfo)
5011 {
5012 spellInfo->Effects[EFFECT_1].TriggerSpell = 54499; // Heart of the Crusader (Rank 3)
5013 });
5014
5015 // Gordok Ogre Suit
5016 ApplySpellFix({ 22736 }, [](SpellInfo* spellInfo)
5017 {
5018 spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_MOUNT;
5019 });
5020
5021 // Soul Flame
5022 ApplySpellFix({ 23272 }, [](SpellInfo* spellInfo)
5023 {
5024 spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
5025 });
5026
5027 // Tree Disguise
5028 ApplySpellFix({ 30298 }, [](SpellInfo* spellInfo)
5029 {
5030 spellInfo->InterruptFlags |= (SPELL_INTERRUPT_FLAG_MOVEMENT | SPELL_INTERRUPT_FLAG_PUSH_BACK |
5032 spellInfo->Effects[EFFECT_2].ApplyAuraName = SPELL_AURA_MOD_STUN;
5033 });
5034
5035 // Internal Shake Camera w/ rumble sound
5036 ApplySpellFix({ 33271 }, [](SpellInfo* spellInfo)
5037 {
5038 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_WHILE_MOUNTED;
5039 });
5040
5041 // Glaive
5042 ApplySpellFix({ 36500 }, [](SpellInfo* spellInfo)
5043 {
5044 spellInfo->Attributes &= ~SPELL_ATTR0_SCALES_WITH_CREATURE_LEVEL;
5045 spellInfo->Effects[EFFECT_0].DieSides = 68;
5046 spellInfo->Effects[EFFECT_0].BasePoints = 201;
5047 });
5048
5049 // Create Anchorite Relic
5050 ApplySpellFix({ 39183 }, [](SpellInfo* spellInfo)
5051 {
5052 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(0);
5053 });
5054
5055 // Charge Rifts
5056 ApplySpellFix({ 47747 }, [](SpellInfo* spellInfo)
5057 {
5058 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_45_YARDS);
5059 });
5060
5061 // New Summon Test
5062 ApplySpellFix({ 49214 }, [](SpellInfo* spellInfo)
5063 {
5064 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(3);
5065 });
5066
5067 // Plague Strike
5068 ApplySpellFix({ 54469 }, [](SpellInfo* spellInfo)
5069 {
5070 spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_5_YARDS);
5071 spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_5_YARDS);
5072 spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_5_YARDS);
5073 });
5074
5075 // Glyph of Chains of Ice:
5076 ApplySpellFix({ 58620 }, [](SpellInfo* spellInfo)
5077 {
5078 spellInfo->SpellLevel = 0;
5079 });
5080
5081 // Exit Portal
5082 ApplySpellFix({ 60474 }, [](SpellInfo* spellInfo)
5083 {
5084 spellInfo->AttributesEx6 |= SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE;
5085 });
5086
5087 // Eye of Acherus Flight (Boost)
5088 ApplySpellFix({ 51923 }, [](SpellInfo* spellInfo)
5089 {
5090 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
5091 });
5092
5093 // Shattering Throw
5094 ApplySpellFix({ 64382 }, [](SpellInfo* spellInfo)
5095 {
5097 spellInfo->Attributes |= SPELL_ATTR0_ALLOW_ITEM_SPELL_IN_PVP;
5098 });
5099
5101 43444, // Explosive Trap (Hex Lord Malacrass)
5102 43447, // Freezing Trap (Hex Lord Malacrass)
5103 43449, // Snake Trap (Hex Lord Malacrass)
5104 }, [](SpellInfo* spellInfo)
5105 {
5106 spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_SUMMON_OBJECT_SLOT1;
5107 });
5108
5109 // Arcane Missiles
5110 ApplySpellFix({ 58529, 61592 }, [](SpellInfo* spellInfo)
5111 {
5112 spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
5113 });
5114
5115 // Siphon Bloodgem
5116 ApplySpellFix({ 34367 }, [](SpellInfo* spellInfo)
5117 {
5118 spellInfo->ChannelInterruptFlags &= ~AURA_INTERRUPT_FLAG_TURNING;
5119 });
5120
5121 // Summon Scourged Captive
5122 ApplySpellFix({ 51597 }, [](SpellInfo* spellInfo)
5123 {
5124 spellInfo->Effects[EFFECT_0].BasePoints = 1;
5125 spellInfo->Effects[EFFECT_0].DieSides = 0;
5126 });
5127
5128 // The Green Tower
5129 ApplySpellFix({ 18097 }, [](SpellInfo* spellInfo)
5130 {
5131 spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21); // -1
5132 });
5133
5135 28032, // Zap Crystal
5136 28056, // Zap Crystal Corpse
5137 }, [](SpellInfo* spellInfo)
5138 {
5139 spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
5140 });
5141
5142 // Earth Shield
5143 ApplySpellFix({ 55599, 58981 }, [](SpellInfo* spellInfo)
5144 {
5145 spellInfo->AttributesEx5 |= SPELL_ATTR5_LIMIT_N;
5146 });
5147
5148 // Acid Splash
5149 ApplySpellFix({ 52446, 59363 }, [](SpellInfo* spellInfo)
5150 {
5151 spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
5152 });
5153
5154 // King Mrlg-Mrgl's Spare Suit
5155 ApplySpellFix({ 45278 }, [](SpellInfo* spellInfo)
5156 {
5157 spellInfo->ProcCharges = 1;
5158 });
5159
5161 56917, // To Icecrown Airship - Teleport to Airship (A)
5162 57417, // To Icecrown Airship - Teleport to Airship (H)
5163 }, [](SpellInfo* spellInfo)
5164 {
5165 spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100 yards
5166 });
5167
5169 60586, // Mighty Spear Thrust
5170 60776, // Claw Swipe
5171 60881, // Fatal Strike
5172 60864, // Jaws of Death
5173 }, [](SpellInfo* spellInfo)
5174 {
5175 spellInfo->AttributesEx4 |= SPELL_ATTR4_IGNORE_DAMAGE_TAKEN_MODIFIERS;
5176 });
5177
5178 // The Brothers Bronzebeard
5180 56675, // Summon Brann Bronzebeard
5181 56676, // Summon Yorg Stormheart
5182 56697, // Summon Magni Bronzebeard
5183 }, [](SpellInfo* spellInfo)
5184 {
5185 spellInfo->Effects[EFFECT_0].MiscValueB = 64;
5186 });
5187
5189 57374, // Shadow Bolt (Lady Blaumeux 10m)
5190 57464, // Shadow Bolt (Lady Blaumeux 25m)
5191 57376, // Holy Bolt (Sir Zeliek 10m)
5192 57465, // Holy Bolt (Sir Zeliek 25m)
5193 }, [](SpellInfo* spellInfo)
5194 {
5195 spellInfo->InterruptFlags &= ~SPELL_INTERRUPT_FLAG_INTERRUPT;
5196 });
5197
5198 // Twilight Torment
5199 ApplySpellFix({ 57935, 58835 }, [](SpellInfo* spellInfo)
5200 {
5201 spellInfo->ProcCharges = 0;
5202 });
5203
5204 // 54933 Hyldnir Harpoon
5205 ApplySpellFix({ 54933 }, [](SpellInfo* spellInfo)
5206 {
5207 spellInfo->Effects[EFFECT_0].BasePoints = 1;
5208 });
5209
5210 // 26025 Impale
5211 ApplySpellFix({ 26025 }, [](SpellInfo* spellInfo)
5212 {
5213 spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CONE_ENEMY_54);
5214 spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(0);
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_UNIT_CONE_ENEMY_54
Definition SharedDefines.h:1462
@ 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_ENEMY_54, 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.
3147{
3148 uint32 const oldMSTime = getMSTime();
3149 uint32 const customAttrTime = getMSTime();
3150 uint32 count;
3151
3152 QueryResult result = WorldDatabase.Query("SELECT spell_id, attributes FROM spell_custom_attr");
3153
3154 if (!result)
3155 {
3156 LOG_WARN("server.loading", ">> Loaded 0 Spell Custom Attributes From DB. DB table `spell_custom_attr` Is Empty.");
3157 }
3158 else
3159 {
3160 for (count = 0; result->NextRow(); ++count)
3161 {
3162 Field const* fields = result->Fetch();
3163
3164 uint32 const spellId = fields[0].Get<uint32>();
3165 uint32 attributes = fields[1].Get<uint32>();
3166
3167 SpellInfo* spellInfo = _GetSpellInfo(spellId);
3168 if (!spellInfo)
3169 {
3170 LOG_INFO("sql.sql", "Table `spell_custom_attr` has wrong spell (spell_id: {}), ignored.", spellId);
3171 continue;
3172 }
3173
3174 if (attributes & SPELL_ATTR0_CU_NEGATIVE)
3175 {
3176 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3177 {
3178 if (spellInfo->Effects[i].IsEffect())
3179 {
3180 if ((attributes & (SPELL_ATTR0_CU_NEGATIVE_EFF0 << i)) && (attributes & (SPELL_ATTR0_CU_POSITIVE_EFF0 << i)))
3181 {
3182 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);
3184 }
3185 continue;
3186 }
3187
3188 if (attributes & (SPELL_ATTR0_CU_NEGATIVE_EFF0 << i))
3189 {
3190 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));
3191 attributes &= ~(SPELL_ATTR0_CU_NEGATIVE_EFF0 << i);
3192 }
3193 }
3194 }
3195
3196 if (attributes & SPELL_ATTR0_CU_POSITIVE)
3197 {
3198 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3199 {
3200 if (spellInfo->Effects[i].IsEffect())
3201 {
3202 continue;
3203 }
3204
3205 if ((attributes & (SPELL_ATTR0_CU_POSITIVE_EFF0 << i)))
3206 {
3207 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));
3208 attributes &= ~(SPELL_ATTR0_CU_POSITIVE_EFF0 << i);
3209 }
3210 }
3211 }
3212
3213 if ((attributes & SPELL_ATTR0_CU_FORCE_AURA_SAVING) && (attributes & SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED))
3214 {
3215 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);
3217 }
3218
3219 spellInfo->AttributesCu |= attributes;
3220 }
3221 LOG_INFO("server.loading", ">> Loaded {} spell custom attributes from DB in {} ms", count, GetMSTimeDiffToNow(customAttrTime));
3222 }
3223
3224 // xinef: create talent spells set
3225 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
3226 {
3227 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
3228 if (!talentInfo)
3229 continue;
3230
3231 for (uint8 j = 0; j < MAX_TALENT_RANK; j++)
3232 if (uint32 spellId = talentInfo->RankID[j])
3233 if (SpellInfo const* spellInfo = GetSpellInfo(spellId))
3234 for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
3235 if (spellInfo->Effects[k].Effect == SPELL_EFFECT_LEARN_SPELL)
3236 if (SpellInfo const* learnSpell = GetSpellInfo(spellInfo->Effects[k].TriggerSpell))
3237 if (learnSpell->IsRanked() && !learnSpell->HasAttribute(SpellAttr0(SPELL_ATTR0_PASSIVE | SPELL_ATTR0_DO_NOT_DISPLAY)))
3238 mTalentSpellAdditionalSet.insert(learnSpell->Id);
3239 }
3240
3241 SpellInfo* spellInfo = nullptr;
3242 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3243 {
3244 spellInfo = mSpellInfoMap[i];
3245 if (!spellInfo)
3246 continue;
3247
3248 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3249 {
3250 switch (spellInfo->Effects[j].ApplyAuraName)
3251 {
3253 {
3254 switch (spellInfo->Id)
3255 {
3256 // Exceptions
3257 case 44801: // Spectral Invisibility (Kalecgos, SWP)
3258 case 46021: // Spectral Realm (SWP)
3259 case 52951: // Chapel Invisibility (DK starting zone)
3260 break;
3261 default:
3263 break;
3264 }
3265 }
3266 break;
3273 break;
3274 default:
3275 break;
3276 }
3277
3278 switch (spellInfo->Effects[j].ApplyAuraName)
3279 {
3280 case SPELL_AURA_CONVERT_RUNE: // Can't be saved - aura handler relies on calculated amount and changes it
3281 case SPELL_AURA_OPEN_STABLE: // No point in saving this, since the stable dialog can't be open on aura load anyway.
3282 // Auras that require both caster & target to be in world cannot be saved
3290 break;
3291 default:
3292 break;
3293 }
3294
3295 switch (spellInfo->Effects[j].ApplyAuraName)
3296 {
3304 break;
3307 break;
3308 default:
3309 break;
3310 }
3311
3312 switch (spellInfo->Effects[j].Effect)
3313 {
3319 case SPELL_EFFECT_HEAL:
3321 break;
3332 break;
3335 case SPELL_EFFECT_JUMP:
3338 spellInfo->AttributesCu |= SPELL_ATTR0_CU_CHARGE;
3339 break;
3342 break;
3347 {
3348 // Only Enchanting profession enchant procs can stack when dual-wielding
3349 // DK runes (e.g., Unholy Strength) should refresh, not stack
3351 {
3352 uint32 enchantId = spellInfo->Effects[j].MiscValue;
3353 SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId);
3354 if (!enchant)
3355 break;
3356
3357 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
3358 {
3359 if (enchant->type[s] != ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL)
3360 continue;
3361
3362 SpellInfo* procInfo = _GetSpellInfo(enchant->spellid[s]);
3363 if (!procInfo)
3364 continue;
3365
3366 // if proced directly from enchantment, not via proc aura
3367 // NOTE: Enchant Weapon - Blade Ward also has proc aura spell and is proced directly
3368 // however its not expected to stack so this check is good
3370 continue;
3371
3373 }
3374 }
3375 break;
3376 }
3377 }
3378 }
3379
3380 // Xinef: spells ignoring hit result should not be binary
3381 if (!spellInfo->HasAttribute(SPELL_ATTR3_ALWAYS_HIT))
3382 {
3383 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3384 {
3385 if (spellInfo->Effects[j].Effect)
3386 {
3387 switch (spellInfo->Effects[j].Effect)
3388 {
3396 continue;
3405 if (spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
3406 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE_PERCENT ||
3407 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_DUMMY ||
3408 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH ||
3409 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_HEALTH_FUNNEL ||
3410 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DUMMY)
3411 continue;
3412 [[fallthrough]];
3413 default:
3414 if (!(spellInfo->Effects[j].CalcValue() ||
3415 ((spellInfo->Effects[j].Effect == SPELL_EFFECT_INTERRUPT_CAST || spellInfo->HasAttribute(SPELL_ATTR0_CU_DONT_BREAK_STEALTH)) &&
3417 continue;
3418
3419 if (spellInfo->Id == 69649 || spellInfo->Id == 71056 || spellInfo->Id == 71057 || spellInfo->Id == 71058 ||
3420 spellInfo->Id == 73061 || spellInfo->Id == 73062 || spellInfo->Id == 73063 || spellInfo->Id == 73064)
3421 continue;
3422
3423 if (spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && (spellInfo->SpellFamilyFlags[0] & 0x20)) // Frostbolt
3424 continue;
3425
3426 if (spellInfo->Id == 55095) // Frost Fever
3427 continue;
3428
3429 if (spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK &&
3430 ((spellInfo->SpellFamilyFlags[1] & 0x40000) || (spellInfo->SpellFamilyFlags[0] & 0x4000))) // Haunt/Drain Soul
3431 continue;
3432
3434 break;
3435 }
3436 }
3437 }
3438 }
3439
3440 // pussywizard:
3441 if ((spellInfo->SchoolMask & SPELL_SCHOOL_MASK_NORMAL) && (spellInfo->SchoolMask & SPELL_SCHOOL_MASK_MAGIC))
3442 {
3443 spellInfo->SchoolMask &= ~SPELL_SCHOOL_MASK_NORMAL;
3445 }
3446
3447 if (!spellInfo->_IsPositiveEffect(EFFECT_0, false))
3449
3450 if (!spellInfo->_IsPositiveEffect(EFFECT_1, false))
3452
3453 if (!spellInfo->_IsPositiveEffect(EFFECT_2, false))
3455
3456 if (spellInfo->SpellVisual[0] == 3879)
3458
3459 switch (spellInfo->SpellFamilyName)
3460 {
3462 // Shout
3463 if (spellInfo->SpellFamilyFlags[0] & 0x20000 || spellInfo->SpellFamilyFlags[1] & 0x20)
3465 break;
3466 case SPELLFAMILY_DRUID:
3467 // Roar
3468 if (spellInfo->SpellFamilyFlags[0] & 0x8)
3470 break;
3471 case SPELLFAMILY_HUNTER:
3472 // Aspects
3473 if (spellInfo->GetCategory() == 47)
3474 {
3476 }
3477 // Aimed Shot
3478 if (spellInfo->SpellFamilyFlags[0] & 0x00020000)
3479 {
3481 }
3482 break;
3483 default:
3484 break;
3485 }
3486
3487 switch (spellInfo->Id)
3488 {
3489 // Xinef: additional spells which should be binary
3490 case 45145: // Snake Trap Effect
3492 break;
3493 case 1776: // Gouge
3494 case 1777:
3495 case 8629:
3496 case 11285:
3497 case 11286:
3498 case 12540:
3499 case 13579:
3500 case 24698:
3501 case 28456:
3502 case 29425:
3503 case 34940:
3504 case 36862:
3505 case 38764:
3506 case 38863:
3507 case 52743: // Head Smack
3509 break;
3510 case 53: // Backstab
3511 case 2589:
3512 case 2590:
3513 case 2591:
3514 case 7159:
3515 case 8627:
3516 case 8721:
3517 case 11279:
3518 case 11280:
3519 case 11281:
3520 case 15582:
3521 case 15657:
3522 case 22416:
3523 case 25300:
3524 case 26863:
3525 case 37685:
3526 case 48656:
3527 case 48657:
3528 case 703: // Garrote
3529 case 8631:
3530 case 8632:
3531 case 8633:
3532 case 11289:
3533 case 11290:
3534 case 26839:
3535 case 26884:
3536 case 48675:
3537 case 48676:
3538 case 5221: // Shred
3539 case 6800:
3540 case 8992:
3541 case 9829:
3542 case 9830:
3543 case 27001:
3544 case 27002:
3545 case 48571:
3546 case 48572:
3547 case 8676: // Ambush
3548 case 8724:
3549 case 8725:
3550 case 11267:
3551 case 11268:
3552 case 11269:
3553 case 27441:
3554 case 48689:
3555 case 48690:
3556 case 48691:
3557 case 6785: // Ravage
3558 case 6787:
3559 case 9866:
3560 case 9867:
3561 case 27005:
3562 case 48578:
3563 case 48579:
3564 case 21987: // Lash of Pain
3565 case 23959: // Test Stab R50
3566 case 24825: // Test Backstab
3567 case 58563: // Assassinate Restless Lookout
3568 case 63124: // quest There's Something About the Squire (13654)
3570 break;
3571 case 26029: // Dark Glare
3572 case 43140: // Flame Breath
3573 case 43215: // Flame Breath
3574 case 70461: // Coldflame Trap
3575 case 72133: // Pain and Suffering
3576 case 73788: // Pain and Suffering
3577 case 73789: // Pain and Suffering
3578 case 73790: // Pain and Suffering
3579 case 63293: // Mimiron - spinning damage
3580 case 68873: // Wailing Souls
3581 case 70324: // Wailing Souls
3582 case 64619: // Ulduar, Mimiron, Emergency Fire Bot, Water Spray
3584 break;
3585 case 58690: // Cyanigosa, Tail Sweep
3586 case 59283: // Cyanigosa, Tail Sweep
3588 break;
3589 case 24340: // Meteor
3590 case 26558: // Meteor
3591 case 28884: // Meteor
3592 case 36837: // Meteor
3593 case 38903: // Meteor
3594 case 41276: // Meteor
3595 case 57467: // Meteor
3596 case 26789: // Shard of the Fallen Star
3597 case 31436: // Malevolent Cleave
3598 case 40810: // Saber Lash
3599 case 43267: // Saber Lash
3600 case 43268: // Saber Lash
3601 case 42384: // Brutal Swipe
3602 case 45150: // Meteor Slash
3603 case 64688: // Sonic Screech
3604 case 72373: // Shared Suffering
3605 case 71904: // Chaos Bane
3606 case 70492: // Ooze Eruption
3607 case 72505: // Ooze Eruption
3608 case 72624: // Ooze Eruption
3609 case 72625: // Ooze Eruption
3610 // ONLY SPELLS WITH SPELLFAMILY_GENERIC and EFFECT_SCHOOL_DAMAGE, OR WEAPON_DMG_X
3611 case 66809: // Meteor Fists
3612 case 67331: // Meteor Fists
3613 case 66765: // Meteor Fists
3614 case 67333: // Meteor Fists
3616 break;
3617 case 18500: // Wing Buffet
3618 case 33086: // Wild Bite
3619 case 49749: // Piercing Blow
3620 case 52890: // Penetrating Strike
3621 case 53454: // Impale
3622 case 59446: // Impale
3623 case 62383: // Shatter
3624 case 64777: // Machine Gun
3625 case 65239: // Machine Gun
3626 case 69293: // Wing Buffet
3627 case 74439: // Machine Gun
3628 // Trial of the Crusader, Jaraxxus, Shivan Slash
3629 case 66378:
3630 case 67097:
3631 case 67098:
3632 case 67099:
3633 // Trial of the Crusader, Anub'arak, Impale
3634 case 65919:
3635 case 67858:
3636 case 67859:
3637 case 67860:
3638 case 63278: // Mark of the Faceless (General Vezax)
3639 case 64125: // Ulduar, Yogg-Saron, Squeeze
3640 case 64126: // Ulduar, Yogg-Saron, Squeeze
3641 case 62544: // Thrust (Argent Tournament)
3642 case 64588: // Thrust (Argent Tournament)
3643 case 66479: // Thrust (Argent Tournament)
3644 case 68505: // Thrust (Argent Tournament)
3645 case 62709: // Counterattack! (Argent Tournament)
3646 case 62626: // Break-Shield (Argent Tournament, Player)
3647 case 64590: // Break-Shield (Argent Tournament, Player)
3648 case 64342: // Break-Shield (Argent Tournament, NPC)
3649 case 64686: // Break-Shield (Argent Tournament, NPC)
3650 case 65147: // Break-Shield (Argent Tournament, NPC)
3651 case 68504: // Break-Shield (Argent Tournament, NPC)
3652 case 62874: // Charge (Argent Tournament, Player)
3653 case 68498: // Charge (Argent Tournament, Player)
3654 case 64591: // Charge (Argent Tournament, Player)
3655 case 63003: // Charge (Argent Tournament, NPC)
3656 case 63010: // Charge (Argent Tournament, NPC)
3657 case 68321: // Charge (Argent Tournament, NPC)
3658 case 72255: // Mark of the Fallen Champion (Deathbringer Saurfang)
3659 case 72444: // Mark of the Fallen Champion (Deathbringer Saurfang)
3660 case 72445: // Mark of the Fallen Champion (Deathbringer Saurfang)
3661 case 72446: // Mark of the Fallen Champion (Deathbringer Saurfang)
3662 case 72409: // Rune of Blood (Deathbringer Saurfang)
3663 case 72447: // Rune of Blood (Deathbringer Saurfang)
3664 case 72448: // Rune of Blood (Deathbringer Saurfang)
3665 case 72449: // Rune of Blood (Deathbringer Saurfang)
3666 case 49882: // Leviroth Self-Impale
3667 case 62775: // Ulduar: XT-002 Tympanic Tamparum
3669 break;
3670 case 64422: // Sonic Screech (Auriaya)
3673 break;
3674 case 72293: // Mark of the Fallen Champion (Deathbringer Saurfang)
3675 case 72347: // Lock Players and Tap Chest (Gunship Battle)
3677 break;
3678 default:
3679 break;
3680 case 63675: // Improved Devouring Plague
3681 case 17962: // Conflagrate
3682 case 32593: // Earth Shield aura
3683 case 32594: // Earth Shield aura
3684 case 49283: // Earth Shield aura
3685 case 49284: // Earth Shield aura
3686 case 50526: // Wandering Plague
3687 case 53353: // Chimera Shot - Serpent trigger
3688 case 52752: // Ancestral Awakening Heal
3690 break;
3691 case 65280: // Ulduar, Hodir, Singed
3692 case 28969: // Naxxramas, Crypt Guard, Acid Spit (10 normal)
3693 case 56098: // Naxxramas, Crypt Guard, Acid Spit (25 normal)
3694 case 27891: // Naxxramas, Sludge Belcher, Acidic Sludge (10 normal)
3695 case 54331: // Naxxramas, Sludge Belcher, Acidic Sludge (25 normal)
3696 case 29325: // Naxxramas, Stoneskin Gargoyle, Acid Volley (10 normal)
3697 case 54714: // Naxxramas, Stoneskin Gargoyle, Acid Volley (25 normal)
3698 case 65775: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (10 normal)
3699 case 67861: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (25 normal)
3700 case 67862: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (10 heroic)
3701 case 67863: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (25 heroic)
3702 case 55604: // Naxxramas, Unrelenting Trainee, Death Plague (10 normal)
3703 case 55645: // Naxxramas, Unrelenting Trainee, Death Plague (25 normal)
3704 case 67721: // Anub'arak, Nerubian Burrower, Expose Weakness (normal)
3705 case 67847: // Anub'arak, Nerubian Burrower, Expose Weakness (heroic)
3706 case 64638: // Ulduar, Winter Jormungar, Acidic Bite
3707 case 71157: // Icecrown Citadel, Plagued Zombie, Infected Wound
3708 case 72963: // Icecrown Citadel, Rot Worm, Flesh Rot (10 normal)
3709 case 72964: // Icecrown Citadel, Rot Worm, Flesh Rot (25 normal)
3710 case 72965: // Icecrown Citadel, Rot Worm, Flesh Rot (10 heroic)
3711 case 72966: // Icecrown Citadel, Rot Worm, Flesh Rot (25 heroic)
3712 case 72465: // Icecrown Citadel, Sindragosa, Respite for a Tormented Soul (weekly quest)
3713 case 45271: // Sunwell, Eredar Twins encounter, Dark Strike
3714 case 45347: // Sunwell, Eredar Twins encounter, Dark Touched
3715 case 45348: // Sunwell, Eredar Twins encounter, Flame Touched
3716 case 35859: // The Eye, Nether Vapor
3717 case 40520: // Black Temple, Shade Soul Channel
3718 case 40327: // Black Temple, Atrophy
3719 case 38449: // Serpentshrine Cavern, Blessing of the Tides
3720 case 38044: // Serpentshrine Cavern, Surge
3721 case 74507: // Ruby Sanctum, Siphoned Might
3722 case 49381: // Drak'tharon Keep, Consume
3723 case 59805: // Drak'tharon Keep, Consume
3724 case 55093: // Gundrak, Grip of Slad'ran
3725 case 30659: // Hellfire Ramparts, Fel Infusion
3726 case 54314: // Azjol'Nerub Drain Power
3727 case 59354: // Azjol'Nerub Drain Power
3728 case 34655: // Snake Trap, Deadly Poison
3729 case 11971: // Sunder Armor
3730 case 58567: // Player Sunder Armor
3731 case 12579: // Player Winter's Chill
3732 case 29306: // Naxxramas(Gluth's Zombies): Infected Wound
3733 case 61920: // Ulduar(Spellbreaker): Supercharge
3734 case 63978: // Ulduar(Rubble): Stone Nova
3735 case 15502: // Sunder Armor
3737 break;
3738 case 43138: // North Fleet Reservist Kill Credit
3740 break;
3741 case 6197: // Eagle Eye
3743 break;
3744 case 50315: // Disco Ball
3746 break;
3747 case 14183: // Premeditation
3749 break;
3750
3751 // Xinef: NOT CUSTOM, cant add in DBC CORRECTION because i need to swap effects, too much work to do there
3752 // Envenom
3753 case 32645:
3754 case 32684:
3755 case 57992:
3756 case 57993:
3757 {
3758 SpellEffectInfo info = spellInfo->Effects[EFFECT_0];
3759 spellInfo->Effects[EFFECT_0] = spellInfo->Effects[EFFECT_2];
3760 spellInfo->Effects[EFFECT_2] = info;
3761 break;
3762 }
3763
3764 // Xinef: Cooldown overwrites
3765 // Burst of Speed
3766 case 57493:
3767 spellInfo->RecoveryTime = 60000;
3768 spellInfo->_requireCooldownInfo = true;
3769 break;
3770 // Strafe Jotunheim Building
3771 case 7769:
3772 spellInfo->RecoveryTime = 1500;
3773 spellInfo->_requireCooldownInfo = true;
3774 break;
3775 case 44535: // Spirit Heal, abilities also have no cost
3776 spellInfo->Effects[EFFECT_0].MiscValue = 127;
3777 break;
3778 case 45537: // Cosmetic - Lightning Beam Channel
3780 break;
3781 }
3782
3783 if (spellInfo->Speed > 0.0f)
3784 {
3785 if (SpellVisualEntry const* spellVisual = sSpellVisualStore.LookupEntry(spellInfo->SpellVisual[0]))
3786 {
3787 if (spellVisual->HasMissile)
3788 {
3789 if (spellVisual->MissileModel == -4 || spellVisual->MissileModel == -5)
3790 {
3792 }
3793 }
3794 }
3795 }
3796
3797 spellInfo->_InitializeExplicitTargetMask();
3798
3799 if (HasSpellCooldownOverride(spellInfo->Id))
3800 {
3801 SpellCooldownOverride spellOverride = GetSpellCooldownOverride(spellInfo->Id);
3802
3803 if (spellInfo->RecoveryTime != spellOverride.RecoveryTime)
3804 {
3805 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3806 }
3807
3808 if (spellInfo->CategoryRecoveryTime != spellOverride.CategoryRecoveryTime)
3809 {
3810 spellInfo->CategoryRecoveryTime = spellOverride.CategoryRecoveryTime;
3811 }
3812
3813 if (spellInfo->StartRecoveryTime != spellOverride.StartRecoveryTime)
3814 {
3815 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3816 }
3817
3818 if (spellInfo->StartRecoveryCategory != spellOverride.StartRecoveryCategory)
3819 {
3820 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3821 }
3822 }
3823
3824 sScriptMgr->OnLoadSpellCustomAttr(spellInfo);
3825 }
3826
3827 // Xinef: addition for binary spells, ommit spells triggering other spells
3828 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3829 {
3830 spellInfo = mSpellInfoMap[i];
3831 if (!spellInfo)
3832 continue;
3833
3834 if (!(spellInfo->AttributesCu & SPELL_ATTR0_CU_BINARY_SPELL))
3835 continue;
3836
3837 bool allNonBinary = true;
3838 bool overrideAttr = false;
3839 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3840 {
3841 if (spellInfo->Effects[j].ApplyAuraName && spellInfo->Effects[j].TriggerSpell)
3842 {
3843 switch (spellInfo->Effects[j].ApplyAuraName)
3844 {
3848 if (SpellInfo const* triggerSpell = GetSpellInfo(spellInfo->Effects[j].TriggerSpell))
3849 {
3850 overrideAttr = true;
3851 if (triggerSpell->AttributesCu & SPELL_ATTR0_CU_BINARY_SPELL)
3852 allNonBinary = false;
3853 }
3854 break;
3855 default:
3856 break;
3857 }
3858 }
3859 }
3860
3861 if (overrideAttr && allNonBinary)
3862 spellInfo->AttributesCu &= ~SPELL_ATTR0_CU_BINARY_SPELL;
3863 }
3864
3865 LOG_INFO("server.loading", ">> Loaded SpellInfo Custom Attributes in {} ms", GetMSTimeDiffToNow(oldMSTime));
3866 LOG_INFO("server.loading", " ");
3867}
@ 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:740
@ SPELL_EFFECT_ENERGIZE_PCT
Definition SharedDefines.h:903
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
Definition SharedDefines.h:801
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition SharedDefines.h:858
@ SPELL_EFFECT_ENCHANT_ITEM
Definition SharedDefines.h:819
@ SPELL_EFFECT_HEALTH_LEECH
Definition SharedDefines.h:775
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition SharedDefines.h:824
@ SPELL_EFFECT_HEAL
Definition SharedDefines.h:776
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
Definition SharedDefines.h:887
@ SPELL_EFFECT_TRIGGER_SPELL
Definition SharedDefines.h:830
@ SPELL_EFFECT_HEAL_MAX_HEALTH
Definition SharedDefines.h:833
@ SPELL_EFFECT_APPLY_AREA_AURA_PET
Definition SharedDefines.h:885
@ SPELL_EFFECT_PICKPOCKET
Definition SharedDefines.h:837
@ SPELL_EFFECT_HEAL_MECHANICAL
Definition SharedDefines.h:841
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
Definition SharedDefines.h:797
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
Definition SharedDefines.h:831
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition SharedDefines.h:783
@ SPELL_EFFECT_PERSISTENT_AREA_AURA
Definition SharedDefines.h:793
@ SPELL_EFFECT_ENERGIZE
Definition SharedDefines.h:796
@ SPELL_EFFECT_POWER_DRAIN
Definition SharedDefines.h:774
@ SPELL_EFFECT_SCHOOL_DAMAGE
Definition SharedDefines.h:768
@ SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
Definition SharedDefines.h:895
@ SPELL_EFFECT_HEAL_PCT
Definition SharedDefines.h:902
@ SPELL_EFFECT_INTERRUPT_CAST
Definition SharedDefines.h:834
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition SharedDefines.h:922
@ SPELL_EFFECT_APPLY_AREA_AURA_OWNER
Definition SharedDefines.h:909
@ SPELLFAMILY_WARLOCK
Definition SharedDefines.h:3789
@ SPELLFAMILY_DRUID
Definition SharedDefines.h:3791
SpellAttr0
Definition SharedDefines.h:369
@ SPELL_ATTR0_DO_NOT_DISPLAY
Definition SharedDefines.h:377
@ SKILL_ENCHANTING
Definition SharedDefines.h:3187
@ SPELL_SCHOOL_MASK_NORMAL
Definition SharedDefines.h:285
@ SPELL_AURA_PERIODIC_DAMAGE
Definition SpellAuraDefines.h:66
@ SPELL_AURA_PERIODIC_HEALTH_FUNNEL
Definition SpellAuraDefines.h:125
@ SPELL_AURA_MOD_POSSESS_PET
Definition SpellAuraDefines.h:191
@ SPELL_AURA_CONVERT_RUNE
Definition SpellAuraDefines.h:312
@ SPELL_AURA_MOD_FEAR
Definition SpellAuraDefines.h:70
@ SPELL_AURA_CONTROL_VEHICLE
Definition SpellAuraDefines.h:299
@ SPELL_AURA_MOD_INVISIBILITY
Definition SpellAuraDefines.h:81
@ SPELL_AURA_PERIODIC_DAMAGE_PERCENT
Definition SpellAuraDefines.h:152
@ SPELL_AURA_AOE_CHARM
Definition SpellAuraDefines.h:240
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE
Definition SpellAuraDefines.h:290
@ SPELL_AURA_MOD_INVISIBILITY_DETECT
Definition SpellAuraDefines.h:82
@ SPELL_AURA_WATER_BREATHING
Definition SpellAuraDefines.h:145
@ SPELL_AURA_PERIODIC_LEECH
Definition SpellAuraDefines.h:116
@ SPELL_AURA_OPEN_STABLE
Definition SpellAuraDefines.h:355
@ SPELL_AURA_MOD_CONFUSE
Definition SpellAuraDefines.h:68
@ SPELL_AURA_TRACK_CREATURES
Definition SpellAuraDefines.h:107
@ SPELL_AURA_MOD_POSSESS
Definition SpellAuraDefines.h:65
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT
Definition SpellAuraDefines.h:111
@ SPELL_AURA_BIND_SIGHT
Definition SpellAuraDefines.h:64
@ SPELL_ATTR0_CU_IGNORE_ARMOR
Definition SpellInfo.h:192
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition SpellInfo.h:193
@ SPELL_ATTR0_CU_ALLOW_INFLIGHT_TARGET
Definition SpellInfo.h:195
@ SPELL_ATTR0_CU_ENCHANT_PROC
Definition SpellInfo.h:177
@ SPELL_ATTR0_CU_NO_POSITIVE_TAKEN_BONUS
Definition SpellInfo.h:198
@ SPELL_ATTR0_CU_FORCE_SEND_CATEGORY_COOLDOWNS
Definition SpellInfo.h:205
@ SPELL_ATTR0_CU_DIRECT_DAMAGE
Definition SpellInfo.h:185
@ SPELL_ATTR0_CU_POSITIVE
Definition SpellInfo.h:212
@ SPELL_ATTR0_CU_FORCE_AURA_SAVING
Definition SpellInfo.h:206
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition SpellInfo.h:184
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition SpellInfo.h:183
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition SpellInfo.h:194
@ SPELL_ATTR0_CU_CONE_BACK
Definition SpellInfo.h:178
@ SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED
Definition SpellInfo.h:201
@ SPELL_ATTR0_CU_NEGATIVE_EFF2
Definition SpellInfo.h:191
@ SPELL_ATTR0_CU_AURA_CC
Definition SpellInfo.h:182
@ SPELL_ATTR0_CU_NEGATIVE_EFF1
Definition SpellInfo.h:190
@ SPELL_ATTR0_CU_CHARGE
Definition SpellInfo.h:186
@ SPELL_ATTR0_CU_NEGATIVE
Definition SpellInfo.h:211
@ SPELL_ATTR0_CU_NEEDS_AMMO_DATA
Definition SpellInfo.h:196
@ SPELL_ATTR0_CU_POSITIVE_EFF0
Definition SpellInfo.h:202
@ SPELL_ATTR0_CU_NEGATIVE_EFF0
Definition SpellInfo.h:189
@ SPELL_ATTR0_CU_BINARY_SPELL
Definition SpellInfo.h:197
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition SpellInfo.h:180
@ SPELL_ATTR0_CU_SCHOOLMASK_NORMAL_WITH_MAGIC
Definition SpellInfo.h:200
@ SPELL_ATTR0_CU_IGNORE_EVADE
Definition SpellInfo.h:188
@ SPELL_ATTR0_CU_PICKPOCKET
Definition SpellInfo.h:187
@ SPELL_ATTR0_CU_CONE_LINE
Definition SpellInfo.h:179
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition SpellInfo.h:181
bool IsPartOfSkillLine(uint32 skillId, uint32 spellId)
Definition SpellMgr.cpp:48
uint32 GetCategory() const
Definition SpellInfo.cpp:880
uint32 AttributesCu
Definition SpellInfo.h:356
bool _requireCooldownInfo
Definition SpellInfo.h:427
uint32 SchoolMask
Definition SpellInfo.h:416
std::array< uint32, 2 > SpellVisual
Definition SpellInfo.h:403
uint32 CategoryRecoveryTime
Definition SpellInfo.h:373
bool _IsPositiveEffect(uint8 effIndex, bool deep) const
Definition SpellInfo.cpp:3026
uint32 StartRecoveryTime
Definition SpellInfo.h:375
void _InitializeExplicitTargetMask()
Definition SpellInfo.cpp:2998
uint32 StartRecoveryCategory
Definition SpellInfo.h:374
uint32 AuraInterruptFlags
Definition SpellInfo.h:377
SpellCooldownOverride GetSpellCooldownOverride(uint32 spellId) const
Definition SpellMgr.cpp:3069
SpellInfo * _GetSpellInfo(uint32 spellId)
Definition SpellMgr.h:775
bool HasSpellCooldownOverride(uint32 spellId) const
Definition SpellMgr.cpp:3064
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 ( )
3870{
3871 uint32 oldMSTime = getMSTime();
3872
3873 for (SpellInfo* spellInfo : mSpellInfoMap)
3874 {
3875 if (!spellInfo)
3876 continue;
3877 spellInfo->_LoadImmunityInfo();
3878 }
3879
3880 LOG_INFO("server.loading", ">> Loaded SpellInfo immunity infos in {} ms", GetMSTimeDiffToNow(oldMSTime));
3881}

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

◆ LoadSpellInfoStore()

void SpellMgr::LoadSpellInfoStore ( )
3003{
3004 uint32 oldMSTime = getMSTime();
3005
3007 mSpellInfoMap.resize(sSpellStore.GetNumRows(), nullptr);
3008
3009 for (SpellEntry const* spellEntry : sSpellStore)
3010 mSpellInfoMap[spellEntry->Id] = new SpellInfo(spellEntry);
3011
3012 for (uint32 spellIndex = 0; spellIndex < GetSpellInfoStoreSize(); ++spellIndex)
3013 {
3014 if (!mSpellInfoMap[spellIndex])
3015 continue;
3016
3017 for (SpellEffectInfo const& spellEffectInfo : mSpellInfoMap[spellIndex]->GetEffects())
3018 {
3019 //ASSERT(effect.EffectIndex < MAX_SPELL_EFFECTS, "MAX_SPELL_EFFECTS must be at least {}", effect.EffectIndex + 1);
3020 ASSERT(spellEffectInfo.Effect < TOTAL_SPELL_EFFECTS, "TOTAL_SPELL_EFFECTS must be at least {}", spellEffectInfo.Effect + 1);
3021 ASSERT(spellEffectInfo.ApplyAuraName < TOTAL_AURAS, "TOTAL_AURAS must be at least {}", spellEffectInfo.ApplyAuraName + 1);
3022 ASSERT(spellEffectInfo.TargetA.GetTarget() < TOTAL_SPELL_TARGETS, "TOTAL_SPELL_TARGETS must be at least {}", spellEffectInfo.TargetA.GetTarget() + 1);
3023 ASSERT(spellEffectInfo.TargetB.GetTarget() < TOTAL_SPELL_TARGETS, "TOTAL_SPELL_TARGETS must be at least {}", spellEffectInfo.TargetB.GetTarget() + 1);
3024 }
3025 }
3026
3028
3029 LOG_INFO("server.loading", ">> Loaded Spell Custom Attributes in {} ms", GetMSTimeDiffToNow(oldMSTime));
3030 LOG_INFO("server.loading", " ");
3031}
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
@ TOTAL_SPELL_TARGETS
Definition SharedDefines.h:1518
void LoadCreatureImmunities()
Definition SpellMgr.cpp:63
Definition DBCStructure.h:1642

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

◆ LoadSpellJumpDistances()

void SpellMgr::LoadSpellJumpDistances ( )
3111{
3112 uint32 oldMSTime = getMSTime();
3113
3114 QueryResult result = WorldDatabase.Query("SELECT ID, JumpDistance FROM spell_jump_distance");
3115
3116 if (!result)
3117 {
3118 LOG_WARN("server.loading", ">> Loaded 0 spell jump distances. DB table `spell_jump_distance` is empty.");
3119 LOG_INFO("server.loading", " ");
3120 return;
3121 }
3122
3123 uint32 count = 0;
3124 do
3125 {
3126 Field const* fields = result->Fetch();
3127
3128 uint32 const spellId = fields[0].Get<uint32>();
3129 float const jumpDistance = fields[1].Get<float>();
3130
3131 SpellInfo* spellInfo = _GetSpellInfo(spellId);
3132 if (!spellInfo)
3133 {
3134 LOG_ERROR("sql.sql", "Table `spell_jump_distance` has wrong spell (spell_id: {}), ignored.", spellId);
3135 continue;
3136 }
3137
3138 spellInfo->JumpDistance = jumpDistance;
3139 ++count;
3140 } while (result->NextRow());
3141
3142 LOG_INFO("server.loading", ">> Loaded {} spell jump distances in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3143 LOG_INFO("server.loading", " ");
3144}

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

◆ LoadSpellLearnSkills()

void SpellMgr::LoadSpellLearnSkills ( )
1436{
1437 uint32 oldMSTime = getMSTime();
1438
1439 mSpellLearnSkills.clear(); // need for reload case
1440
1441 // search auto-learned skills and add its to map also for use in unlearn spells/talents
1442 uint32 dbc_count = 0;
1443 for (uint32 spell = 0; spell < GetSpellInfoStoreSize(); ++spell)
1444 {
1445 SpellInfo const* entry = GetSpellInfo(spell);
1446
1447 if (!entry)
1448 continue;
1449
1450 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1451 {
1452 SpellLearnSkillNode dbc_node;
1453 switch (entry->Effects[i].Effect)
1454 {
1455 case SPELL_EFFECT_SKILL:
1456 dbc_node.skill = entry->Effects[i].MiscValue;
1457 dbc_node.step = entry->Effects[i].CalcValue();
1458 if (dbc_node.skill != SKILL_RIDING)
1459 {
1460 dbc_node.value = 1;
1461 }
1462 else
1463 {
1464 dbc_node.value = dbc_node.step * 75;
1465 }
1466 dbc_node.maxvalue = dbc_node.step * 75;
1467 break;
1469 dbc_node.skill = SKILL_DUAL_WIELD;
1470 dbc_node.step = 1;
1471 dbc_node.value = 1;
1472 dbc_node.maxvalue = 1;
1473 break;
1474 default:
1475 continue;
1476 }
1477
1478 mSpellLearnSkills[spell] = dbc_node;
1479 ++dbc_count;
1480 break;
1481 }
1482 }
1483
1484 LOG_INFO("server.loading", ">> Loaded {} Spell Learn Skills From DBC in {} ms", dbc_count, GetMSTimeDiffToNow(oldMSTime));
1485 LOG_INFO("server.loading", " ");
1486}
@ 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 ( )
2565{
2566 uint32 oldMSTime = getMSTime();
2567
2568 mSpellLinkedMap.clear(); // need for reload case
2569
2570 // 0 1 2
2571 QueryResult result = WorldDatabase.Query("SELECT spell_trigger, spell_effect, type FROM spell_linked_spell");
2572 if (!result)
2573 {
2574 LOG_WARN("server.loading", ">> Loaded 0 linked spells. DB table `spell_linked_spell` is empty.");
2575 LOG_INFO("server.loading", " ");
2576 return;
2577 }
2578
2579 uint32 count = 0;
2580 do
2581 {
2582 Field* fields = result->Fetch();
2583
2584 int32 trigger = fields[0].Get<int32>();
2585 int32 effect = fields[1].Get<int32>();
2586 int32 type = fields[2].Get<uint8>();
2587
2588 SpellInfo const* spellInfo = GetSpellInfo(std::abs(trigger));
2589 if (!spellInfo)
2590 {
2591 LOG_ERROR("sql.sql", "Spell {} listed in `spell_linked_spell` does not exist", std::abs(trigger));
2592 continue;
2593 }
2594 spellInfo = GetSpellInfo(std::abs(effect));
2595 if (!spellInfo)
2596 {
2597 LOG_ERROR("sql.sql", "Spell {} listed in `spell_linked_spell` does not exist", std::abs(effect));
2598 continue;
2599 }
2600
2601 if (type) //we will find a better way when more types are needed
2602 {
2603 if (trigger > 0)
2604 trigger += SPELL_LINKED_MAX_SPELLS * type;
2605 else
2606 trigger -= SPELL_LINKED_MAX_SPELLS * type;
2607 }
2608 mSpellLinkedMap[trigger].push_back(effect);
2609
2610 ++count;
2611 } while (result->NextRow());
2612
2613 LOG_INFO("server.loading", ">> Loaded {} Linked Spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2614 LOG_INFO("server.loading", " ");
2615}
#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 ( )
2358{
2359 uint32 oldMSTime = getMSTime();
2360
2361 mSpellMixologyMap.clear(); // need for reload case
2362
2363 // 0 1
2364 QueryResult result = WorldDatabase.Query("SELECT entry, pctMod FROM spell_mixology");
2365 if (!result)
2366 {
2367 LOG_WARN("server.loading", ">> Loaded 0 mixology bonuses. DB table `spell_mixology` is empty.");
2368 LOG_INFO("server.loading", " ");
2369 return;
2370 }
2371
2372 uint32 count = 0;
2373 do
2374 {
2375 Field* fields = result->Fetch();
2376
2377 uint32 entry = fields[0].Get<uint32>();
2378
2379 if (!GetSpellInfo(entry))
2380 {
2381 LOG_ERROR("sql.sql", "Spell {} listed in `spell_mixology` does not exist", entry);
2382 continue;
2383 }
2384
2385 mSpellMixologyMap[entry] = fields[1].Get<float>();
2386 ++count;
2387 } while (result->NextRow());
2388
2389 LOG_INFO("server.loading", ">> Loaded {} Mixology Bonuses in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2390 LOG_INFO("server.loading", " ");
2391}

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

◆ LoadSpellPetAuras()

void SpellMgr::LoadSpellPetAuras ( )
2416{
2417 uint32 oldMSTime = getMSTime();
2418
2419 mSpellPetAuraMap.clear(); // need for reload case
2420
2421 // 0 1 2 3
2422 QueryResult result = WorldDatabase.Query("SELECT spell, effectId, pet, aura FROM spell_pet_auras");
2423 if (!result)
2424 {
2425 LOG_WARN("server.loading", ">> Loaded 0 spell pet auras. DB table `spell_pet_auras` is empty.");
2426 LOG_INFO("server.loading", " ");
2427 return;
2428 }
2429
2430 uint32 count = 0;
2431 do
2432 {
2433 Field* fields = result->Fetch();
2434
2435 uint32 spell = fields[0].Get<uint32>();
2436 uint8 eff = fields[1].Get<uint8>();
2437 uint32 pet = fields[2].Get<uint32>();
2438 uint32 aura = fields[3].Get<uint32>();
2439
2440 SpellPetAuraMap::iterator itr = mSpellPetAuraMap.find((spell << 8) + eff);
2441 if (itr != mSpellPetAuraMap.end())
2442 itr->second.AddAura(pet, aura);
2443 else
2444 {
2445 SpellInfo const* spellInfo = GetSpellInfo(spell);
2446 if (!spellInfo)
2447 {
2448 LOG_ERROR("sql.sql", "Spell {} listed in `spell_pet_auras` does not exist", spell);
2449 continue;
2450 }
2451 if (spellInfo->Effects[eff].Effect != SPELL_EFFECT_DUMMY &&
2452 (spellInfo->Effects[eff].Effect != SPELL_EFFECT_APPLY_AURA ||
2453 spellInfo->Effects[eff].ApplyAuraName != SPELL_AURA_DUMMY))
2454 {
2455 LOG_ERROR("spells", "Spell {} listed in `spell_pet_auras` does not have dummy aura or dummy effect", spell);
2456 continue;
2457 }
2458
2459 SpellInfo const* spellInfo2 = GetSpellInfo(aura);
2460 if (!spellInfo2)
2461 {
2462 LOG_ERROR("sql.sql", "Aura {} listed in `spell_pet_auras` does not exist", aura);
2463 continue;
2464 }
2465
2466 PetAura pa(pet, aura, spellInfo->Effects[eff].TargetA.GetTarget() == TARGET_UNIT_PET, spellInfo->Effects[eff].CalcValue());
2467 mSpellPetAuraMap[(spell << 8) + eff] = pa;
2468 }
2469
2470 ++count;
2471 } while (result->NextRow());
2472
2473 LOG_INFO("server.loading", ">> Loaded {} Spell Pet Auras in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2474 LOG_INFO("server.loading", " ");
2475}
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 ( )
1987{
1988 uint32 oldMSTime = getMSTime();
1989
1990 mSpellProcMap.clear(); // need for reload case
1991
1992 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1993 QueryResult result = WorldDatabase.Query("SELECT SpellId, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, ProcFlags, SpellTypeMask, SpellPhaseMask, HitMask, AttributesMask, DisableEffectsMask, ProcsPerMinute, Chance, Cooldown, Charges FROM spell_proc");
1994 if (!result)
1995 {
1996 LOG_WARN("server.loading", ">> Loaded 0 Spell Proc Conditions And Data. DB table `spell_proc` Is Empty.");
1997 LOG_INFO("server.loading", " ");
1998 return;
1999 }
2000
2001 uint32 count = 0;
2002 do
2003 {
2004 Field* fields = result->Fetch();
2005
2006 int32 spellId = fields[0].Get<int32>();
2007
2008 bool allRanks = false;
2009 if (spellId < 0)
2010 {
2011 allRanks = true;
2012 spellId = -spellId;
2013 }
2014
2015 SpellInfo const* spellInfo = GetSpellInfo(spellId);
2016 if (!spellInfo)
2017 {
2018 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` does not exist", spellId);
2019 continue;
2020 }
2021
2022 if (allRanks)
2023 {
2024 if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId))
2025 {
2026 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` is not first rank of spell.", fields[0].Get<int32>());
2027 continue;
2028 }
2029 }
2030
2031 SpellProcEntry baseProcEntry;
2032
2033 baseProcEntry.SchoolMask = fields[1].Get<int8>();
2034 baseProcEntry.SpellFamilyName = fields[2].Get<uint16>();
2035 baseProcEntry.SpellFamilyMask[0] = fields[3].Get<uint32>();
2036 baseProcEntry.SpellFamilyMask[1] = fields[4].Get<uint32>();
2037 baseProcEntry.SpellFamilyMask[2] = fields[5].Get<uint32>();
2038 baseProcEntry.ProcFlags = fields[6].Get<uint32>();
2039 baseProcEntry.SpellTypeMask = fields[7].Get<uint32>();
2040 baseProcEntry.SpellPhaseMask = fields[8].Get<uint32>();
2041 baseProcEntry.HitMask = fields[9].Get<uint32>();
2042 baseProcEntry.AttributesMask = fields[10].Get<uint32>();
2043 baseProcEntry.DisableEffectsMask = fields[11].Get<uint32>();
2044 baseProcEntry.ProcsPerMinute = fields[12].Get<float>();
2045 baseProcEntry.Chance = fields[13].Get<float>();
2046 baseProcEntry.Cooldown = Milliseconds(fields[14].Get<uint32>());
2047 baseProcEntry.Charges = fields[15].Get<uint32>();
2048
2049 while (spellInfo)
2050 {
2051 if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end())
2052 {
2053 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` has duplicate entry in the table", spellId);
2054 break;
2055 }
2056 SpellProcEntry procEntry = SpellProcEntry(baseProcEntry);
2057
2058 // take defaults from dbcs
2059 if (!procEntry.ProcFlags)
2060 procEntry.ProcFlags = spellInfo->ProcFlags;
2061 if (!procEntry.Charges)
2062 procEntry.Charges = spellInfo->ProcCharges;
2063 if (!procEntry.Chance && !procEntry.ProcsPerMinute)
2064 procEntry.Chance = float(spellInfo->ProcChance);
2065
2066 // validate data
2067 if (procEntry.SchoolMask & ~SPELL_SCHOOL_MASK_ALL)
2068 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SchoolMask` set: {}", spellId, procEntry.SchoolMask);
2069 if (procEntry.SpellFamilyName && (procEntry.SpellFamilyName < 3 || procEntry.SpellFamilyName > 17 || procEntry.SpellFamilyName == 14 || procEntry.SpellFamilyName == 16))
2070 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellFamilyName` set: {}", spellId, procEntry.SpellFamilyName);
2071 if (procEntry.Chance < 0)
2072 {
2073 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `Chance` field", spellId);
2074 procEntry.Chance = 0;
2075 }
2076 if (procEntry.ProcsPerMinute < 0)
2077 {
2078 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `ProcsPerMinute` field", spellId);
2079 procEntry.ProcsPerMinute = 0;
2080 }
2081 if (procEntry.Charges > 99)
2082 {
2083 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has too big value in `Charges` field", spellId);
2084 procEntry.Charges = 99;
2085 }
2086 if (!procEntry.ProcFlags)
2087 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} doesn't have `ProcFlags` value defined, proc will not be triggered", spellId);
2088 if (procEntry.SpellTypeMask & ~PROC_SPELL_TYPE_MASK_ALL)
2089 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellTypeMask` set: {}", spellId, procEntry.SpellTypeMask);
2090 if (procEntry.SpellTypeMask && !(procEntry.ProcFlags & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK)))
2091 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);
2092 if (!procEntry.SpellPhaseMask && procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK)
2093 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);
2095 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellPhaseMask` set: {}", spellId, procEntry.SpellPhaseMask);
2096 if (procEntry.SpellPhaseMask && !(procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK))
2097 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);
2098 if (procEntry.HitMask & ~PROC_HIT_MASK_ALL)
2099 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `HitMask` set: {}", spellId, procEntry.HitMask);
2100 // HitMask is valid for: TAKEN procs, or DONE procs at any phase (CAST phase has pre-calculated crit for travel-time spells)
2101 if (procEntry.HitMask && !(procEntry.ProcFlags & TAKEN_HIT_PROC_FLAG_MASK || procEntry.ProcFlags & DONE_HIT_PROC_FLAG_MASK))
2102 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);
2103 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2104 if ((procEntry.DisableEffectsMask & (1u << i)) && !spellInfo->Effects[i].IsAura())
2105 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));
2106 if (procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD)
2107 {
2108 bool found = false;
2109 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2110 {
2111 if (!spellInfo->Effects[i].IsAura())
2112 continue;
2113
2114 if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_ADD_PCT_MODIFIER || spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_ADD_FLAT_MODIFIER
2115 || spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_SPELL_CRIT_CHANCE || spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL)
2116 {
2117 found = true;
2118 break;
2119 }
2120 }
2121
2122 if (!found)
2123 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);
2124 }
2125
2126 mSpellProcMap[spellInfo->Id] = procEntry;
2127
2128 if (allRanks)
2129 spellInfo = spellInfo->GetNextRankSpell();
2130 else
2131 break;
2132 }
2133 ++count;
2134 } while (result->NextRow());
2135
2136 LOG_INFO("server.loading", ">> Loaded {} spell proc conditions and data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2137 LOG_INFO("server.loading", " ");
2138
2139 // Generate default procs for spells with proc flags but no explicit spell_proc entry
2140 // This ensures backward compatibility and covers spells that rely on DBC data
2141 LOG_INFO("server.loading", "Generating spell proc data from SpellMap...");
2142 count = 0;
2143 oldMSTime = getMSTime();
2144
2145 for (SpellInfo const* spellInfo : mSpellInfoMap)
2146 {
2147 if (!spellInfo)
2148 continue;
2149
2150 // Skip if already has explicit entry
2151 if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end())
2152 continue;
2153
2154 // Check if spell has any trigger aura effects
2155 bool found = false, addTriggerFlag = false;
2156 uint32 procSpellTypeMask = PROC_SPELL_TYPE_NONE;
2157 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2158 {
2159 if (!spellInfo->Effects[i].IsEffect())
2160 continue;
2161
2162 uint32 auraName = spellInfo->Effects[i].ApplyAuraName;
2163 if (!auraName)
2164 continue;
2165
2166 if (!isTriggerAura[auraName])
2167 continue;
2168
2169 found = true;
2170 procSpellTypeMask |= spellTypeMask[auraName];
2171
2172 if (!addTriggerFlag && isAlwaysTriggeredAura[auraName])
2173 addTriggerFlag = true;
2174
2175 // Many proc auras with taken procFlag mask don't have
2176 // attribute "can proc with triggered" — they should
2177 // proc nevertheless (e.g. mage armor spells with
2178 // judgement)
2179 if (!addTriggerFlag
2180 && (spellInfo->ProcFlags & TAKEN_HIT_PROC_FLAG_MASK))
2181 {
2182 switch (auraName)
2183 {
2186 addTriggerFlag = true;
2187 break;
2188 default:
2189 break;
2190 }
2191 }
2192 }
2193
2194 if (!found)
2195 continue;
2196
2197 // Skip if no proc flags in DBC
2198 if (!spellInfo->ProcFlags)
2199 continue;
2200
2201 // Generate default proc entry from DBC data
2202 SpellProcEntry procEntry;
2203 procEntry.SchoolMask = 0;
2204 procEntry.SpellFamilyMask[0] = 0;
2205 procEntry.SpellFamilyMask[1] = 0;
2206 procEntry.SpellFamilyMask[2] = 0;
2207 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2208 if (spellInfo->Effects[i].IsEffect() && isTriggerAura[spellInfo->Effects[i].ApplyAuraName])
2209 procEntry.SpellFamilyMask |= spellInfo->Effects[i].SpellClassMask;
2210
2211 if (procEntry.SpellFamilyMask)
2212 procEntry.SpellFamilyName = spellInfo->SpellFamilyName;
2213 else
2214 procEntry.SpellFamilyName = 0;
2215
2216 procEntry.ProcFlags = spellInfo->ProcFlags;
2217 procEntry.SpellTypeMask = procSpellTypeMask;
2219 procEntry.HitMask = PROC_HIT_NONE; // uses default proc @see SpellMgr::CanSpellTriggerProcOnEvent
2220
2221 // Reflect auras should only proc off reflects
2222 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2223 {
2224 if (spellInfo->Effects[i].IsAura(SPELL_AURA_REFLECT_SPELLS) || spellInfo->Effects[i].IsAura(SPELL_AURA_REFLECT_SPELLS_SCHOOL))
2225 {
2226 procEntry.HitMask = PROC_HIT_REFLECT;
2227 break;
2228 }
2229 }
2230
2231 procEntry.AttributesMask = 0;
2232 if (spellInfo->ProcFlags & PROC_FLAG_KILL)
2234 if (addTriggerFlag)
2236
2237 // Modifier auras with charges should require spellmod validation
2238 if (spellInfo->ProcCharges)
2239 {
2240 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2241 {
2242 if (spellInfo->Effects[i].IsAura(SPELL_AURA_ADD_FLAT_MODIFIER) ||
2243 spellInfo->Effects[i].IsAura(SPELL_AURA_ADD_PCT_MODIFIER))
2244 {
2246 break;
2247 }
2248 }
2249 }
2250
2251 // Calculate DisableEffectsMask for effects that shouldn't trigger procs
2252 uint32 nonProcMask = 0;
2253 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2254 {
2255 if (!spellInfo->Effects[i].IsAura())
2256 continue;
2257 if (!isTriggerAura[spellInfo->Effects[i].ApplyAuraName])
2258 nonProcMask |= 1u << i;
2259 }
2260 procEntry.DisableEffectsMask = nonProcMask;
2261
2262 procEntry.ProcsPerMinute = 0;
2263 procEntry.Chance = static_cast<float>(spellInfo->ProcChance);
2264 procEntry.Cooldown = Milliseconds::zero();
2265 procEntry.Charges = spellInfo->ProcCharges;
2266
2267 mSpellProcMap[spellInfo->Id] = procEntry;
2268 ++count;
2269 }
2270
2271 LOG_INFO("server.loading", ">> Generated spell proc data for {} spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2272 LOG_INFO("server.loading", " ");
2273}
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:1917
static uint32 spellTypeMask[TOTAL_AURAS]
Definition SpellMgr.cpp:1918
static bool isTriggerAura[TOTAL_AURAS]
Definition SpellMgr.cpp:1916
@ 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 ( )
1260{
1261 // cleanup data and load spell ranks for talents from dbc
1263
1264 uint32 oldMSTime = getMSTime();
1265
1266 // 0 1 2
1267 QueryResult result = WorldDatabase.Query("SELECT first_spell_id, spell_id, `rank` from spell_ranks ORDER BY first_spell_id, `rank`");
1268
1269 if (!result)
1270 {
1271 LOG_WARN("server.loading", ">> Loaded 0 spell rank records. DB table `spell_ranks` is empty.");
1272 LOG_INFO("server.loading", " ");
1273 return;
1274 }
1275
1276 uint32 count = 0;
1277 bool finished = false;
1278
1279 do
1280 {
1281 // spellid, rank
1282 std::list < std::pair < int32, int32 > > rankChain;
1283 int32 currentSpell = -1;
1284 int32 lastSpell = -1;
1285
1286 // fill one chain
1287 while (currentSpell == lastSpell && !finished)
1288 {
1289 Field* fields = result->Fetch();
1290
1291 currentSpell = fields[0].Get<uint32>();
1292 if (lastSpell == -1)
1293 lastSpell = currentSpell;
1294 uint32 spell_id = fields[1].Get<uint32>();
1295 uint32 rank = fields[2].Get<uint8>();
1296
1297 // don't drop the row if we're moving to the next rank
1298 if (currentSpell == lastSpell)
1299 {
1300 rankChain.push_back(std::make_pair(spell_id, rank));
1301 if (!result->NextRow())
1302 finished = true;
1303 }
1304 else
1305 break;
1306 }
1307 // check if chain is made with valid first spell
1308 SpellInfo const* first = GetSpellInfo(lastSpell);
1309 if (!first)
1310 {
1311 LOG_ERROR("sql.sql", "Spell rank identifier(first_spell_id) {} listed in `spell_ranks` does not exist!", lastSpell);
1312 continue;
1313 }
1314 // check if chain is long enough
1315 if (rankChain.size() < 2)
1316 {
1317 LOG_ERROR("sql.sql", "There is only 1 spell rank for identifier(first_spell_id) {} in `spell_ranks`, entry is not needed!", lastSpell);
1318 continue;
1319 }
1320 int32 curRank = 0;
1321 bool valid = true;
1322 // check spells in chain
1323 for (std::list<std::pair<int32, int32> >::iterator itr = rankChain.begin(); itr != rankChain.end(); ++itr)
1324 {
1325 SpellInfo const* spell = GetSpellInfo(itr->first);
1326 if (!spell)
1327 {
1328 LOG_ERROR("sql.sql", "Spell {} (rank {}) listed in `spell_ranks` for chain {} does not exist!", itr->first, itr->second, lastSpell);
1329 valid = false;
1330 break;
1331 }
1332 ++curRank;
1333 if (itr->second != curRank)
1334 {
1335 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);
1336 valid = false;
1337 break;
1338 }
1339 }
1340 if (!valid)
1341 continue;
1342 int32 prevRank = 0;
1343 // insert the chain
1344 std::list<std::pair<int32, int32> >::iterator itr = rankChain.begin();
1345 do
1346 {
1347 ++count;
1348 int32 addedSpell = itr->first;
1349 mSpellChains[addedSpell].first = GetSpellInfo(lastSpell);
1350 mSpellChains[addedSpell].last = GetSpellInfo(rankChain.back().first);
1351 mSpellChains[addedSpell].rank = itr->second;
1352 mSpellChains[addedSpell].prev = GetSpellInfo(prevRank);
1353 mSpellInfoMap[addedSpell]->ChainEntry = &mSpellChains[addedSpell];
1354 prevRank = addedSpell;
1355 ++itr;
1356 if (itr == rankChain.end())
1357 {
1358 mSpellChains[addedSpell].next = nullptr;
1359 break;
1360 }
1361 else
1362 mSpellChains[addedSpell].next = GetSpellInfo(itr->first);
1363 } while (true);
1364 } while (!finished);
1365
1366 LOG_INFO("server.loading", ">> Loaded {} spell rank records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1367 LOG_INFO("server.loading", " ");
1368}
void LoadSpellTalentRanks()
Definition SpellMgr.cpp:1198

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

◆ LoadSpellRequired()

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

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

◆ LoadSpellSpecificAndAuraState()

void SpellMgr::LoadSpellSpecificAndAuraState ( )
3093{
3094 uint32 oldMSTime = getMSTime();
3095
3096 SpellInfo* spellInfo = nullptr;
3097 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3098 {
3099 spellInfo = mSpellInfoMap[i];
3100 if (!spellInfo)
3101 continue;
3102 spellInfo->_spellSpecific = spellInfo->LoadSpellSpecific();
3103 spellInfo->_auraState = spellInfo->LoadAuraState();
3104 }
3105
3106 LOG_INFO("server.loading", ">> Loaded Spell Specific And Aura State in {} ms", GetMSTimeDiffToNow(oldMSTime));
3107 LOG_INFO("server.loading", " ");
3108}
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 ( )
1199{
1200 // cleanup core data before reload - remove reference to ChainNode from SpellInfo
1202
1203 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1204 {
1205 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
1206 if (!talentInfo)
1207 continue;
1208
1209 SpellInfo const* lastSpell = nullptr;
1210 for (uint8 rank = MAX_TALENT_RANK - 1; rank > 0; --rank)
1211 {
1212 if (talentInfo->RankID[rank])
1213 {
1214 lastSpell = GetSpellInfo(talentInfo->RankID[rank]);
1215 break;
1216 }
1217 }
1218
1219 if (!lastSpell)
1220 continue;
1221
1222 SpellInfo const* firstSpell = GetSpellInfo(talentInfo->RankID[0]);
1223 if (!firstSpell)
1224 {
1225 LOG_ERROR("sql.sql", "SpellMgr::LoadSpellTalentRanks: First Rank Spell {} for TalentEntry {} does not exist.", talentInfo->RankID[0], i);
1226 continue;
1227 }
1228
1229 SpellInfo const* prevSpell = nullptr;
1230 for (uint8 rank = 0; rank < MAX_TALENT_RANK; ++rank)
1231 {
1232 uint32 spellId = talentInfo->RankID[rank];
1233 if (!spellId)
1234 break;
1235
1236 SpellInfo const* currentSpell = GetSpellInfo(spellId);
1237 if (!currentSpell)
1238 {
1239 LOG_ERROR("sql.sql", "SpellMgr::LoadSpellTalentRanks: Spell {} (Rank: {}) for TalentEntry {} does not exist.", spellId, rank + 1, i);
1240 break;
1241 }
1242
1243 SpellChainNode node;
1244 node.first = firstSpell;
1245 node.last = lastSpell;
1246 node.rank = rank + 1;
1247
1248 node.prev = prevSpell;
1249 node.next = node.rank < MAX_TALENT_RANK ? GetSpellInfo(talentInfo->RankID[node.rank]) : nullptr;
1250
1251 mSpellChains[spellId] = node;
1252 mSpellInfoMap[spellId]->ChainEntry = &mSpellChains[spellId];
1253
1254 prevSpell = currentSpell;
1255 }
1256 }
1257}
void UnloadSpellInfoChains()
Definition SpellMgr.cpp:1190
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 ( )
1489{
1490 uint32 oldMSTime = getMSTime();
1491
1492 mSpellTargetPositions.clear(); // need for reload case
1493
1494 // 0 1 2 3 4 5 6
1495 QueryResult result = WorldDatabase.Query("SELECT ID, EffectIndex, MapID, PositionX, PositionY, PositionZ, Orientation FROM spell_target_position");
1496
1497 if (!result)
1498 {
1499 LOG_WARN("server.loading", ">> Loaded 0 spell target coordinates. DB table `spell_target_position` is empty.");
1500 LOG_INFO("server.loading", " ");
1501 return;
1502 }
1503
1504 uint32 count = 0;
1505 do
1506 {
1507 Field* fields = result->Fetch();
1508
1509 uint32 Spell_ID = fields[0].Get<uint32>();
1510
1511 SpellEffIndex effIndex = SpellEffIndex(fields[1].Get<uint8>());
1512
1514
1515 st.target_mapId = fields[2].Get<uint16>();
1516 st.target_X = fields[3].Get<float>();
1517 st.target_Y = fields[4].Get<float>();
1518 st.target_Z = fields[5].Get<float>();
1519 st.target_Orientation = fields[6].Get<float>();
1520
1521 MapEntry const* mapEntry = sMapStore.LookupEntry(st.target_mapId);
1522 if (!mapEntry)
1523 {
1524 LOG_ERROR("sql.sql", "Spell (Id: {}, effIndex: {}) target map (ID: {}) does not exist in `Map.dbc`.", Spell_ID, effIndex, st.target_mapId);
1525 continue;
1526 }
1527
1528 if (st.target_X == 0 && st.target_Y == 0 && st.target_Z == 0)
1529 {
1530 LOG_ERROR("sql.sql", "Spell (Id: {}, effIndex: {}) target coordinates not provided.", Spell_ID, effIndex);
1531 continue;
1532 }
1533
1534 SpellInfo const* spellInfo = GetSpellInfo(Spell_ID);
1535 if (!spellInfo)
1536 {
1537 LOG_ERROR("sql.sql", "Spell (ID:{}) listed in `spell_target_position` does not exist.", Spell_ID);
1538 continue;
1539 }
1540
1541 if (spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_DEST_DB || spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_DEST_DB)
1542 {
1543 std::pair<uint32, SpellEffIndex> key = std::make_pair(Spell_ID, effIndex);
1544 mSpellTargetPositions[key] = st;
1545 ++count;
1546 }
1547 else
1548 {
1549 LOG_ERROR("sql.sql", "Spell (Id: {}, effIndex: {}) listed in `spell_target_position` does not have target TARGET_DEST_DB (17).", Spell_ID, effIndex);
1550 continue;
1551 }
1552 } while (result->NextRow());
1553
1554 /*
1555 // Check all spells
1556 for (uint32 i = 1; i < GetSpellInfoStoreSize; ++i)
1557 {
1558 SpellInfo const* spellInfo = GetSpellInfo(i);
1559 if (!spellInfo)
1560 continue;
1561
1562 bool found = false;
1563 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
1564 {
1565 switch (spellInfo->Effects[j].TargetA)
1566 {
1567 case TARGET_DEST_DB:
1568 found = true;
1569 break;
1570 }
1571 if (found)
1572 break;
1573 switch (spellInfo->Effects[j].TargetB)
1574 {
1575 case TARGET_DEST_DB:
1576 found = true;
1577 break;
1578 }
1579 if (found)
1580 break;
1581 }
1582 if (found)
1583 {
1584 if (!GetSpellTargetPosition(i))
1585 LOG_DEBUG("spells.aura", "Spell (ID: {}) does not have record in `spell_target_position`", i);
1586 }
1587 }*/
1588
1589 LOG_INFO("server.loading", ">> Loaded {} Spell Teleport Coordinates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1590 LOG_INFO("server.loading", " ");
1591}
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 ( )
2317{
2318 uint32 oldMSTime = getMSTime();
2319
2320 mSpellThreatMap.clear(); // need for reload case
2321
2322 // 0 1 2 3
2323 QueryResult result = WorldDatabase.Query("SELECT entry, flatMod, pctMod, apPctMod FROM spell_threat");
2324 if (!result)
2325 {
2326 LOG_WARN("server.loading", ">> Loaded 0 aggro generating spells. DB table `spell_threat` is empty.");
2327 LOG_INFO("server.loading", " ");
2328 return;
2329 }
2330
2331 uint32 count = 0;
2332 do
2333 {
2334 Field* fields = result->Fetch();
2335
2336 uint32 entry = fields[0].Get<uint32>();
2337
2338 if (!GetSpellInfo(entry))
2339 {
2340 LOG_ERROR("sql.sql", "Spell {} listed in `spell_threat` does not exist", entry);
2341 continue;
2342 }
2343
2344 SpellThreatEntry ste;
2345 ste.flatMod = fields[1].Get<int32>();
2346 ste.pctMod = fields[2].Get<float>();
2347 ste.apPctMod = fields[3].Get<float>();
2348
2349 mSpellThreatMap[entry] = ste;
2350 ++count;
2351 } while (result->NextRow());
2352
2353 LOG_INFO("server.loading", ">> Loaded {} SpellThreatEntries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2354 LOG_INFO("server.loading", " ");
2355}
Definition SpellMgr.h:375
int32 flatMod
Definition SpellMgr.h:376
float apPctMod
Definition SpellMgr.h:378
float pctMod
Definition SpellMgr.h:377

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

◆ SetSpellDifficultyId()

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

References mSpellDifficultySearcherMap.

◆ UnloadSpellInfoChains()

void SpellMgr::UnloadSpellInfoChains ( )
1191{
1192 for (SpellChainMap::iterator itr = mSpellChains.begin(); itr != mSpellChains.end(); ++itr)
1193 mSpellInfoMap[itr->first]->ChainEntry = nullptr;
1194
1195 mSpellChains.clear();
1196}

References mSpellChains, and mSpellInfoMap.

Referenced by LoadSpellTalentRanks().

◆ UnloadSpellInfoImplicitTargetConditionLists()

void SpellMgr::UnloadSpellInfoImplicitTargetConditionLists ( )
3084{
3085 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3086 {
3087 if (mSpellInfoMap[i])
3088 mSpellInfoMap[i]->_UnloadImplicitTargetConditionLists();
3089 }
3090}

References GetSpellInfoStoreSize(), and mSpellInfoMap.

◆ UnloadSpellInfoStore()

void SpellMgr::UnloadSpellInfoStore ( )
3076{
3077 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3078 delete mSpellInfoMap[i];
3079
3080 mSpellInfoMap.clear();
3081}

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: