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

#include "SpellMgr.h"

Public Member Functions

uint32 GetSpellDifficultyId (uint32 spellId) const
 
void SetSpellDifficultyId (uint32 spellId, uint32 id)
 
uint32 GetSpellIdForDifficulty (uint32 spellId, Unit const *caster) const
 
SpellInfo const * GetSpellForDifficultyFromSpell (SpellInfo const *spell, Unit const *caster) const
 
SpellChainNode const * GetSpellChainNode (uint32 spell_id) const
 
uint32 GetFirstSpellInChain (uint32 spell_id) const
 
uint32 GetLastSpellInChain (uint32 spell_id) const
 
uint32 GetNextSpellInChain (uint32 spell_id) const
 
uint32 GetPrevSpellInChain (uint32 spell_id) const
 
uint8 GetSpellRank (uint32 spell_id) const
 
uint32 GetSpellWithRank (uint32 spell_id, uint32 rank, bool strict=false) const
 
Acore::IteratorPair< SpellRequiredMap::const_iterator > GetSpellsRequiredForSpellBounds (uint32 spell_id) const
 
SpellsRequiringSpellMapBounds GetSpellsRequiringSpellBounds (uint32 spell_id) const
 
bool IsSpellRequiringSpell (uint32 spellid, uint32 req_spellid) const
 
SpellLearnSkillNode const * GetSpellLearnSkill (uint32 spell_id) const
 
SpellTargetPosition const * GetSpellTargetPosition (uint32 spell_id, SpellEffIndex effIndex) const
 
SpellSpellGroupMapBounds GetSpellSpellGroupMapBounds (uint32 spell_id) const
 
bool IsSpellMemberOfSpellGroup (uint32 spell_id, SpellGroup group_id) const
 
SpellGroupSpellMapBounds GetSpellGroupSpellMapBounds (SpellGroup group_id) const
 
void GetSetOfSpellsInSpellGroup (SpellGroup group_id, std::set< uint32 > &foundSpells) const
 
void GetSetOfSpellsInSpellGroup (SpellGroup group_id, std::set< uint32 > &foundSpells, std::set< SpellGroup > &usedGroups) const
 
bool AddSameEffectStackRuleSpellGroups (SpellInfo const *spellInfo, uint32 auraType, int32 amount, std::map< SpellGroup, int32 > &groups) const
 
SpellGroupStackRule CheckSpellGroupStackRules (SpellInfo const *spellInfo1, SpellInfo const *spellInfo2) const
 
SpellGroupStackRule GetSpellGroupStackRule (SpellGroup group_id) const
 
SpellProcEntry const * GetSpellProcEntry (uint32 spellId) const
 
bool CanSpellTriggerProcOnEvent (SpellProcEntry const &procEntry, ProcEventInfo &eventInfo) const
 
SpellBonusEntry const * GetSpellBonusData (uint32 spellId) const
 
SpellThreatEntry const * GetSpellThreatEntry (uint32 spellID) const
 
float GetSpellMixologyBonus (uint32 spellId) const
 
SkillLineAbilityMapBounds GetSkillLineAbilityMapBounds (uint32 spell_id) const
 
PetAura const * GetPetAura (uint32 spell_id, uint8 eff) const
 
SpellEnchantProcEntry const * GetSpellEnchantProcEvent (uint32 enchId) const
 
bool IsArenaAllowedEnchancment (uint32 ench_id) const
 
const std::vector< int32 > * GetSpellLinked (int32 spell_id) const
 
PetLevelupSpellSet const * GetPetLevelupSpellList (uint32 petFamily) const
 
PetDefaultSpellsEntry const * GetPetDefaultSpellsEntry (int32 id) const
 
SpellAreaMapBounds GetSpellAreaMapBounds (uint32 spell_id) const
 
SpellAreaForQuestMapBounds GetSpellAreaForQuestMapBounds (uint32 quest_id) const
 
SpellAreaForQuestMapBounds GetSpellAreaForQuestEndMapBounds (uint32 quest_id) const
 
SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds (uint32 spell_id) const
 
SpellAreaForAreaMapBounds GetSpellAreaForAreaMapBounds (uint32 area_id) const
 
SpellInfo const * GetSpellInfo (uint32 spellId) const
 
SpellInfo const * AssertSpellInfo (uint32 spellId) const
 
SpellInfo const * CheckSpellInfo (uint32 spellId) const
 
uint32 GetSpellInfoStoreSize () const
 
bool IsAdditionalTalentSpell (uint32 spellId) const
 
bool HasSpellCooldownOverride (uint32 spellId) const
 
SpellCooldownOverride GetSpellCooldownOverride (uint32 spellId) const
 
void UnloadSpellInfoChains ()
 
void LoadSpellTalentRanks ()
 
void LoadSpellRanks ()
 
void LoadSpellRequired ()
 
void LoadSpellLearnSkills ()
 
void LoadSpellTargetPositions ()
 
void LoadSpellGroups ()
 
void LoadSpellGroupStackRules ()
 
void LoadSpellProcs ()
 
void LoadSpellBonuses ()
 
void LoadSpellThreats ()
 
void LoadSpellMixology ()
 
void LoadSkillLineAbilityMap ()
 
void LoadSpellPetAuras ()
 
void LoadEnchantCustomAttr ()
 
void LoadSpellEnchantProcData ()
 
void LoadSpellLinked ()
 
void LoadPetLevelupSpellMap ()
 
void LoadPetDefaultSpells ()
 
void LoadSpellAreas ()
 
void LoadSpellInfoStore ()
 
void LoadSpellCooldownOverrides ()
 
void UnloadSpellInfoStore ()
 
void UnloadSpellInfoImplicitTargetConditionLists ()
 
void LoadSpellInfoCustomAttributes ()
 
void LoadSpellInfoCorrections ()
 
void LoadSpellSpecificAndAuraState ()
 

Static Public Member Functions

static SpellMgrinstance ()
 
static bool ComputeIsSpellValid (SpellInfo const *spellInfo, bool msg=true)
 Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book, etc.
 
static bool IsSpellValid (SpellInfo const *spellInfo)
 
static bool CheckSpellValid (SpellInfo const *spellInfo, uint32 spellId, bool isTalent)
 

Private Member Functions

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

Private Attributes

SpellDifficultySearcherMap mSpellDifficultySearcherMap
 
SpellChainMap mSpellChains
 
SpellsRequiringSpellMap mSpellsReqSpell
 
SpellRequiredMap mSpellReq
 
SpellLearnSkillMap mSpellLearnSkills
 
SpellTargetPositionMap mSpellTargetPositions
 
SpellSpellGroupMap mSpellSpellGroup
 
SpellGroupSpellMap mSpellGroupSpell
 
SpellGroupStackMap mSpellGroupStack
 
SameEffectStackMap mSpellSameEffectStack
 
SpellProcMap mSpellProcMap
 
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
353{
354}

◆ ~SpellMgr()

SpellMgr::~SpellMgr ( )
private
357{
359}
void UnloadSpellInfoStore()
Definition SpellMgr.cpp:2931

References UnloadSpellInfoStore().

Member Function Documentation

◆ _GetSpellInfo()

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

References GetSpellInfoStoreSize(), and mSpellInfoMap.

Referenced by LoadSpellInfoCustomAttributes().

◆ AddSameEffectStackRuleSpellGroups()

bool SpellMgr::AddSameEffectStackRuleSpellGroups ( SpellInfo const *  spellInfo,
uint32  auraType,
int32  amount,
std::map< SpellGroup, int32 > &  groups 
) const
699{
700 uint32 spellId = spellInfo->GetFirstRankSpell()->Id;
701 auto spellGroupBounds = GetSpellSpellGroupMapBounds(spellId);
702 // Find group with SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT if it belongs to one
703 for (auto itr = spellGroupBounds.first; itr != spellGroupBounds.second; ++itr)
704 {
705 SpellGroup group = itr->second;
706 auto found = mSpellSameEffectStack.find(group);
707 if (found != mSpellSameEffectStack.end())
708 {
709 // check auraTypes
710 if (!found->second.count(auraType))
711 continue;
712
713 // Put the highest amount in the map
714 auto groupItr = groups.find(group);
715 if (groupItr == groups.end())
716 groups.emplace(group, amount);
717 else
718 {
719 int32 curr_amount = groups[group];
720 // Take absolute value because this also counts for the highest negative aura
721 if (std::abs(curr_amount) < std::abs(amount))
722 groupItr->second = amount;
723 }
724 // return because a spell should be in only one SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT group per auraType
725 return true;
726 }
727 }
728 // Not in a SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT group, so return false
729 return false;
730}
std::int32_t int32
Definition Define.h:103
std::uint32_t uint32
Definition Define.h:107
SpellGroup
Definition SpellMgr.h:328
SameEffectStackMap mSpellSameEffectStack
Definition SpellMgr.h:792
SpellSpellGroupMapBounds GetSpellSpellGroupMapBounds(uint32 spell_id) const
Definition SpellMgr.cpp:649

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

◆ AssertSpellInfo()

SpellInfo const * SpellMgr::AssertSpellInfo ( uint32  spellId) const
inline
718 {
719 ASSERT(spellId < GetSpellInfoStoreSize());
720 SpellInfo const* spellInfo = mSpellInfoMap[spellId];
721 ASSERT(spellInfo);
722 return spellInfo;
723 }
#define ASSERT
Definition Errors.h:68
Definition SpellInfo.h:316

References ASSERT, GetSpellInfoStoreSize(), and mSpellInfoMap.

Referenced by LoadSpellGroupStackRules().

◆ CanSpellTriggerProcOnEvent()

bool SpellMgr::CanSpellTriggerProcOnEvent ( SpellProcEntry const &  procEntry,
ProcEventInfo eventInfo 
) const
797{
798 // proc type doesn't match
799 if (!(eventInfo.GetTypeMask() & procEntry.ProcFlags))
800 return false;
801
802 // check XP or honor target requirement
803 if (procEntry.AttributesMask & PROC_ATTR_REQ_EXP_OR_HONOR)
804 if (Player* actor = eventInfo.GetActor()->ToPlayer())
805 if (eventInfo.GetActionTarget() && !actor->isHonorOrXPTarget(eventInfo.GetActionTarget()))
806 return false;
807
808 // check mana cost requirement (used by Clearcasting and similar effects)
809 if (procEntry.AttributesMask & PROC_ATTR_REQ_MANA_COST)
810 {
811 SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
812 if (!spellInfo || (!spellInfo->ManaCost && !spellInfo->ManaCostPercentage))
813 return false;
814 }
815
816 // always trigger for these types
818 return true;
819
820 // check school mask (if set) for other trigger types
821 if (procEntry.SchoolMask && !(eventInfo.GetSchoolMask() & procEntry.SchoolMask))
822 return false;
823
824 // check spell family name/flags (if set) for spells
825 if (eventInfo.GetTypeMask() & SPELL_PROC_FLAG_MASK)
826 {
827 if (SpellInfo const* eventSpellInfo = eventInfo.GetSpellInfo())
828 {
829 if (procEntry.SpellFamilyName && procEntry.SpellFamilyName != eventSpellInfo->SpellFamilyName)
830 return false;
831
832 if (procEntry.SpellFamilyMask && !(procEntry.SpellFamilyMask & eventSpellInfo->SpellFamilyFlags))
833 return false;
834 }
835 }
836
837 // check spell type mask (if set)
839 {
840 if (procEntry.SpellTypeMask && !(eventInfo.GetSpellTypeMask() & procEntry.SpellTypeMask))
841 return false;
842 }
843
844 // check spell phase mask
846 {
847 if (!(eventInfo.GetSpellPhaseMask() & procEntry.SpellPhaseMask))
848 return false;
849 }
850
851 // check hit mask (on taken hit or on done hit)
852 // For CAST phase with DONE flags, only check if HitMask is explicitly set (crit is pre-calculated for travel time spells)
853 if ((eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK) ||
854 ((eventInfo.GetTypeMask() & DONE_HIT_PROC_FLAG_MASK) &&
855 (!(eventInfo.GetSpellPhaseMask() & PROC_SPELL_PHASE_CAST) || procEntry.HitMask)))
856 {
857 uint32 hitMask = procEntry.HitMask;
858 // get default values if hit mask not set
859 if (!hitMask)
860 {
861 // for taken procs allow normal + critical hits by default
862 if (eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK)
864 // for done procs allow normal + critical + absorbs by default
865 else
867 }
868 if (!(eventInfo.GetHitMask() & hitMask))
869 return false;
870 }
871
872 return true;
873}
@ PROC_HIT_ABSORB
Definition SpellMgr.h:264
@ PROC_HIT_CRITICAL
Definition SpellMgr.h:255
@ PROC_HIT_NORMAL
Definition SpellMgr.h:254
@ PROC_ATTR_REQ_MANA_COST
Definition SpellMgr.h:275
@ PROC_ATTR_REQ_EXP_OR_HONOR
Definition SpellMgr.h:273
@ PROC_SPELL_PHASE_CAST
Definition SpellMgr.h:245
@ TAKEN_HIT_PROC_FLAG_MASK
Definition SpellMgr.h:175
@ PERIODIC_PROC_FLAG_MASK
Definition SpellMgr.h:166
@ PROC_FLAG_KILLED
Definition SpellMgr.h:107
@ PROC_FLAG_DEATH
Definition SpellMgr.h:143
@ REQ_SPELL_PHASE_PROC_FLAG_MASK
Definition SpellMgr.h:181
@ PROC_FLAG_KILL
Definition SpellMgr.h:108
@ SPELL_PROC_FLAG_MASK
Definition SpellMgr.h:156
@ DONE_HIT_PROC_FLAG_MASK
Definition SpellMgr.h:168
Player * ToPlayer()
Definition Object.h:201
Definition Player.h:1084
uint32 GetHitMask() const
Definition Unit.h:466
SpellSchoolMask GetSchoolMask() const
Definition Unit.cpp:295
Unit * GetActionTarget() const
Definition Unit.h:461
uint32 GetSpellTypeMask() const
Definition Unit.h:464
uint32 GetTypeMask() const
Definition Unit.h:463
SpellInfo const * GetSpellInfo() const
Definition Unit.cpp:281
Unit * GetActor()
Definition Unit.h:460
uint32 GetSpellPhaseMask() const
Definition Unit.h:465
uint32 ManaCostPercentage
Definition SpellInfo.h:367
uint32 ManaCost
Definition SpellInfo.h:363

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
733{
734 ASSERT(spellInfo1);
735 ASSERT(spellInfo2);
736
737 uint32 spell_id1 = spellInfo1->GetFirstRankSpell()->Id;
738 uint32 spell_id2 = spellInfo2->GetFirstRankSpell()->Id;
739
740 // find SpellGroups which are common for both spells
742 std::set<SpellGroup> groups;
743 for (SpellSpellGroupMap::const_iterator itr = spellGroup1.first; itr != spellGroup1.second; ++itr)
744 {
745 if (IsSpellMemberOfSpellGroup(spell_id2, itr->second))
746 {
747 bool add = true;
749 for (SpellGroupSpellMap::const_iterator itr2 = groupSpell.first; itr2 != groupSpell.second; ++itr2)
750 {
751 if (itr2->second < 0)
752 {
753 SpellGroup currGroup = (SpellGroup)abs(itr2->second);
754 if (IsSpellMemberOfSpellGroup(spell_id1, currGroup) && IsSpellMemberOfSpellGroup(spell_id2, currGroup))
755 {
756 add = false;
757 break;
758 }
759 }
760 }
761 if (add)
762 groups.insert(itr->second);
763 }
764 }
765
767
768 for (std::set<SpellGroup>::iterator itr = groups.begin(); itr!= groups.end(); ++itr)
769 {
770 SpellGroupStackMap::const_iterator found = mSpellGroupStack.find(*itr);
771 if (found != mSpellGroupStack.end())
772 rule = found->second;
773 if (rule)
774 break;
775 }
776 return rule;
777}
std::pair< SpellSpellGroupMap::const_iterator, SpellSpellGroupMap::const_iterator > SpellSpellGroupMapBounds
Definition SpellMgr.h:351
SpellGroupStackRule
Definition SpellMgr.h:358
@ SPELL_GROUP_STACK_RULE_DEFAULT
Definition SpellMgr.h:359
std::pair< SpellGroupSpellMap::const_iterator, SpellGroupSpellMap::const_iterator > SpellGroupSpellMapBounds
Definition SpellMgr.h:355
SpellGroupSpellMapBounds GetSpellGroupSpellMapBounds(SpellGroup group_id) const
Definition SpellMgr.cpp:666
bool IsSpellMemberOfSpellGroup(uint32 spell_id, SpellGroup group_id) const
Definition SpellMgr.cpp:655
SpellGroupStackMap mSpellGroupStack
Definition SpellMgr.h:791

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
726 {
727 if (spellId >= GetSpellInfoStoreSize())
728 {
729 LOG_ERROR("server", "spellId {} is not lower than GetSpellInfoStoreSize() ({})", spellId, GetSpellInfoStoreSize());
730 return nullptr;
731 }
732 SpellInfo const* spellInfo = mSpellInfoMap[spellId];
733 if (!spellInfo)
734 {
735 LOG_ERROR("server", "spellId {} has invalid spellInfo", spellId);
736 return nullptr;
737 }
738 return spellInfo;
739 }
#define LOG_ERROR(filterType__,...)
Definition Log.h:158

References GetSpellInfoStoreSize(), LOG_ERROR, and mSpellInfoMap.

◆ CheckSpellValid()

bool SpellMgr::CheckSpellValid ( SpellInfo const *  spellInfo,
uint32  spellId,
bool  isTalent 
)
static
458{
459 if (!spellInfo)
460 {
462 LOG_ERROR("spells", "Player::{}: Non-existed in SpellStore spell #{} request.", (isTalent ? "AddTalent" : "addSpell"), spellId);
463 return false;
464 }
465
466 if (!IsSpellValid(spellInfo))
467 {
469 LOG_ERROR("spells", "Player::{}: Broken spell #{} learning not allowed.", (isTalent ? "AddTalent" : "addSpell"), spellId);
470 return false;
471 }
472
473 return true;
474}
void DeleteSpellFromAllPlayers(uint32 spellId)
Definition SpellMgr.cpp:446
static bool IsSpellValid(SpellInfo const *spellInfo)
Definition SpellMgr.cpp:439

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.

369{
370 // not exist
371 if (!spellInfo)
372 return false;
373
374 bool need_check_reagents = false;
375
376 // check effects
377 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
378 {
379 switch (spellInfo->Effects[i].Effect)
380 {
381 case 0:
382 continue;
383
384 // craft spell for crafting non-existed item (break client recipes list show)
387 {
388 if (spellInfo->Effects[i].ItemType == 0)
389 {
390 // skip auto-loot crafting spells, its not need explicit item info (but have special fake items sometime)
391 if (!spellInfo->IsLootCrafting())
392 {
393 if (msg)
394 LOG_ERROR("sql.sql", "Craft spell {} not have create item entry.", spellInfo->Id);
395 return false;
396 }
397 }
398 // also possible IsLootCrafting case but fake item must exist anyway
399 else if (!sObjectMgr->GetItemTemplate(spellInfo->Effects[i].ItemType))
400 {
401 if (msg)
402 LOG_ERROR("sql.sql", "Craft spell {} create not-exist in DB item (Entry: {}) and then...", spellInfo->Id, spellInfo->Effects[i].ItemType);
403 return false;
404 }
405
406 need_check_reagents = true;
407 break;
408 }
410 {
411 SpellInfo const* spellInfo2 = sSpellMgr->GetSpellInfo(spellInfo->Effects[i].TriggerSpell);
412 if (!ComputeIsSpellValid(spellInfo2, msg))
413 {
414 if (msg)
415 LOG_ERROR("sql.sql", "Spell {} learn to invalid spell {}, and then...", spellInfo->Id, spellInfo->Effects[i].TriggerSpell);
416 return false;
417 }
418 break;
419 }
420 }
421 }
422
423 if (need_check_reagents)
424 {
425 for (uint8 j = 0; j < MAX_SPELL_REAGENTS; ++j)
426 {
427 if (spellInfo->Reagent[j] > 0 && !sObjectMgr->GetItemTemplate(spellInfo->Reagent[j]))
428 {
429 if (msg)
430 LOG_ERROR("sql.sql", "Craft spell {} have not-exist reagent in DB item (Entry: {}) and then...", spellInfo->Id, spellInfo->Reagent[j]);
431 return false;
432 }
433 }
434 }
435
436 return true;
437}
#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:1699
@ 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:814
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:368

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

◆ GetFirstSpellInChain()

uint32 SpellMgr::GetFirstSpellInChain ( uint32  spell_id) const
553{
554 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
555 return node->first->Id;
556
557 return spell_id;
558}
SpellChainNode const * GetSpellChainNode(uint32 spell_id) const
Definition SpellMgr.cpp:543
Definition SpellMgr.h:541

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

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

◆ GetLastSpellInChain()

uint32 SpellMgr::GetLastSpellInChain ( uint32  spell_id) const
561{
562 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
563 return node->last->Id;
564
565 return spell_id;
566}

References GetSpellChainNode().

◆ GetNextSpellInChain()

uint32 SpellMgr::GetNextSpellInChain ( uint32  spell_id) const
569{
570 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
571 if (node->next)
572 return node->next->Id;
573
574 return 0;
575}

References GetSpellChainNode().

◆ GetPetAura()

PetAura const * SpellMgr::GetPetAura ( uint32  spell_id,
uint8  eff 
) const
921{
922 SpellPetAuraMap::const_iterator itr = mSpellPetAuraMap.find((spell_id << 8) + eff);
923 if (itr != mSpellPetAuraMap.end())
924 return &itr->second;
925 else
926 return nullptr;
927}
SpellPetAuraMap mSpellPetAuraMap
Definition SpellMgr.h:797

References mSpellPetAuraMap.

◆ GetPetDefaultSpellsEntry()

PetDefaultSpellsEntry const * SpellMgr::GetPetDefaultSpellsEntry ( int32  id) const
958{
959 PetDefaultSpellsMap::const_iterator itr = mPetDefaultSpellsMap.find(id);
960 if (itr != mPetDefaultSpellsMap.end())
961 return &itr->second;
962 return nullptr;
963}
PetDefaultSpellsMap mPetDefaultSpellsMap
Definition SpellMgr.h:808

References mPetDefaultSpellsMap.

◆ GetPetLevelupSpellList()

PetLevelupSpellSet const * SpellMgr::GetPetLevelupSpellList ( uint32  petFamily) const
949{
950 PetLevelupSpellMap::const_iterator itr = mPetLevelupSpellMap.find(petFamily);
951 if (itr != mPetLevelupSpellMap.end())
952 return &itr->second;
953 else
954 return nullptr;
955}
PetLevelupSpellMap mPetLevelupSpellMap
Definition SpellMgr.h:807

References mPetLevelupSpellMap.

◆ GetPrevSpellInChain()

uint32 SpellMgr::GetPrevSpellInChain ( uint32  spell_id) const
578{
579 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
580 if (node->prev)
581 return node->prev->Id;
582
583 return 0;
584}

References GetSpellChainNode().

◆ GetSetOfSpellsInSpellGroup() [1/2]

void SpellMgr::GetSetOfSpellsInSpellGroup ( SpellGroup  group_id,
std::set< uint32 > &  foundSpells 
) const
672{
673 std::set<SpellGroup> usedGroups;
674 GetSetOfSpellsInSpellGroup(group_id, foundSpells, usedGroups);
675}
void GetSetOfSpellsInSpellGroup(SpellGroup group_id, std::set< uint32 > &foundSpells) const
Definition SpellMgr.cpp:671

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
678{
679 if (usedGroups.find(group_id) != usedGroups.end())
680 return;
681 usedGroups.insert(group_id);
682
684 for (SpellGroupSpellMap::const_iterator itr = groupSpell.first; itr != groupSpell.second; ++itr)
685 {
686 if (itr->second < 0)
687 {
688 SpellGroup currGroup = (SpellGroup)abs(itr->second);
689 GetSetOfSpellsInSpellGroup(currGroup, foundSpells, usedGroups);
690 }
691 else
692 {
693 foundSpells.insert(itr->second);
694 }
695 }
696}

References GetSetOfSpellsInSpellGroup(), and GetSpellGroupSpellMapBounds().

◆ GetSkillLineAbilityMapBounds()

SkillLineAbilityMapBounds SpellMgr::GetSkillLineAbilityMapBounds ( uint32  spell_id) const
916{
917 return mSkillLineAbilityMap.equal_range(spell_id);
918}
SkillLineAbilityMap mSkillLineAbilityMap
Definition SpellMgr.h:806

References mSkillLineAbilityMap.

◆ GetSpellAreaForAreaMapBounds()

SpellAreaForAreaMapBounds SpellMgr::GetSpellAreaForAreaMapBounds ( uint32  area_id) const
986{
987 return mSpellAreaForAreaMap.equal_range(area_id);
988}
SpellAreaForAreaMap mSpellAreaForAreaMap
Definition SpellMgr.h:805

References mSpellAreaForAreaMap.

◆ GetSpellAreaForAuraMapBounds()

SpellAreaForAuraMapBounds SpellMgr::GetSpellAreaForAuraMapBounds ( uint32  spell_id) const
981{
982 return mSpellAreaForAuraMap.equal_range(spell_id);
983}
SpellAreaForAuraMap mSpellAreaForAuraMap
Definition SpellMgr.h:804

References mSpellAreaForAuraMap.

Referenced by LoadSpellAreas().

◆ GetSpellAreaForQuestEndMapBounds()

SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestEndMapBounds ( uint32  quest_id) const
976{
977 return mSpellAreaForQuestEndMap.equal_range(quest_id);
978}
SpellAreaForQuestMap mSpellAreaForQuestEndMap
Definition SpellMgr.h:803

References mSpellAreaForQuestEndMap.

◆ GetSpellAreaForQuestMapBounds()

SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestMapBounds ( uint32  quest_id) const
971{
972 return mSpellAreaForQuestMap.equal_range(quest_id);
973}
SpellAreaForQuestMap mSpellAreaForQuestMap
Definition SpellMgr.h:802

References mSpellAreaForQuestMap.

◆ GetSpellAreaMapBounds()

SpellAreaMapBounds SpellMgr::GetSpellAreaMapBounds ( uint32  spell_id) const
966{
967 return mSpellAreaMap.equal_range(spell_id);
968}
SpellAreaMap mSpellAreaMap
Definition SpellMgr.h:801

References mSpellAreaMap.

Referenced by LoadSpellAreas().

◆ GetSpellBonusData()

SpellBonusEntry const * SpellMgr::GetSpellBonusData ( uint32  spellId) const
876{
877 // Lookup data
878 SpellBonusMap::const_iterator itr = mSpellBonusMap.find(spellId);
879 if (itr != mSpellBonusMap.end())
880 return &itr->second;
881 // Not found, try lookup for 1 spell rank if exist
882 if (uint32 rank_1 = GetFirstSpellInChain(spellId))
883 {
884 SpellBonusMap::const_iterator itr2 = mSpellBonusMap.find(rank_1);
885 if (itr2 != mSpellBonusMap.end())
886 return &itr2->second;
887 }
888 return nullptr;
889}
uint32 GetFirstSpellInChain(uint32 spell_id) const
Definition SpellMgr.cpp:552
SpellBonusMap mSpellBonusMap
Definition SpellMgr.h:794

References GetFirstSpellInChain(), and mSpellBonusMap.

◆ GetSpellChainNode()

SpellChainNode const * SpellMgr::GetSpellChainNode ( uint32  spell_id) const
544{
545 SpellChainMap::const_iterator itr = mSpellChains.find(spell_id);
546 if (itr == mSpellChains.end())
547 return nullptr;
548
549 return &itr->second;
550}
SpellChainMap mSpellChains
Definition SpellMgr.h:784

References mSpellChains.

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

◆ GetSpellCooldownOverride()

SpellCooldownOverride SpellMgr::GetSpellCooldownOverride ( uint32  spellId) const
2926{
2927 auto range = mSpellCooldownOverrideMap.find(spellId);
2928 return range->second;
2929}
SpellCooldownOverrideMap mSpellCooldownOverrideMap
Definition SpellMgr.h:810

References mSpellCooldownOverrideMap.

Referenced by LoadSpellInfoCustomAttributes().

◆ GetSpellDifficultyId()

uint32 SpellMgr::GetSpellDifficultyId ( uint32  spellId) const
477{
478 SpellDifficultySearcherMap::const_iterator i = mSpellDifficultySearcherMap.find(spellId);
479 return i == mSpellDifficultySearcherMap.end() ? 0 : (*i).second;
480}
SpellDifficultySearcherMap mSpellDifficultySearcherMap
Definition SpellMgr.h:783

References mSpellDifficultySearcherMap.

Referenced by GetSpellIdForDifficulty().

◆ GetSpellEnchantProcEvent()

SpellEnchantProcEntry const * SpellMgr::GetSpellEnchantProcEvent ( uint32  enchId) const
930{
931 SpellEnchantProcEventMap::const_iterator itr = mSpellEnchantProcEventMap.find(enchId);
932 if (itr != mSpellEnchantProcEventMap.end())
933 return &itr->second;
934 return nullptr;
935}
SpellEnchantProcEventMap mSpellEnchantProcEventMap
Definition SpellMgr.h:799

References mSpellEnchantProcEventMap.

◆ GetSpellForDifficultyFromSpell()

SpellInfo const * SpellMgr::GetSpellForDifficultyFromSpell ( SpellInfo const *  spell,
Unit const *  caster 
) const
530{
531 uint32 newSpellId = GetSpellIdForDifficulty(spell->Id, caster);
532 SpellInfo const* newSpell = GetSpellInfo(newSpellId);
533 if (!newSpell)
534 {
535 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellForDifficultyFromSpell: spell {} not found. Check spelldifficulty_dbc!", newSpellId);
536 return spell;
537 }
538
539 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellForDifficultyFromSpell: Spell id for instance mode is {} (original {})", newSpell->Id, spell->Id);
540 return newSpell;
541}
#define LOG_DEBUG(filterType__,...)
Definition Log.h:170
uint32 Id
Definition SpellInfo.h:320
uint32 GetSpellIdForDifficulty(uint32 spellId, Unit const *caster) const
Definition SpellMgr.cpp:487
SpellInfo const * GetSpellInfo(uint32 spellId) const
Definition SpellMgr.h:715

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

◆ GetSpellGroupSpellMapBounds()

SpellGroupSpellMapBounds SpellMgr::GetSpellGroupSpellMapBounds ( SpellGroup  group_id) const
667{
668 return mSpellGroupSpell.equal_range(group_id);
669}
SpellGroupSpellMap mSpellGroupSpell
Definition SpellMgr.h:790

References mSpellGroupSpell.

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

◆ GetSpellGroupStackRule()

SpellGroupStackRule SpellMgr::GetSpellGroupStackRule ( SpellGroup  group_id) const
780{
781 SpellGroupStackMap::const_iterator itr = mSpellGroupStack.find(group);
782 if (itr != mSpellGroupStack.end())
783 return itr->second;
784
786}

References mSpellGroupStack, and SPELL_GROUP_STACK_RULE_DEFAULT.

◆ GetSpellIdForDifficulty()

uint32 SpellMgr::GetSpellIdForDifficulty ( uint32  spellId,
Unit const *  caster 
) const
488{
489 if (!GetSpellInfo(spellId))
490 return spellId;
491
492 if (!caster || !caster->GetMap() || (!caster->GetMap()->IsDungeon() && !caster->GetMap()->IsBattleground()))
493 return spellId;
494
495 uint32 mode = uint32(caster->GetMap()->GetSpawnMode());
496 if (mode >= MAX_DIFFICULTY)
497 {
498 LOG_ERROR("spells", "SpellMgr::GetSpellIdForDifficulty: Incorrect Difficulty for spell {}.", spellId);
499 return spellId; //return source spell
500 }
501
502 uint32 difficultyId = GetSpellDifficultyId(spellId);
503 if (!difficultyId)
504 return spellId; //return source spell, it has only REGULAR_DIFFICULTY
505
506 SpellDifficultyEntry const* difficultyEntry = sSpellDifficultyStore.LookupEntry(difficultyId);
507 if (!difficultyEntry)
508 {
509 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellIdForDifficulty: SpellDifficultyEntry not found for spell {}. This should never happen.", spellId);
510 return spellId; //return source spell
511 }
512
513 if (difficultyEntry->SpellID[mode] <= 0 && mode > DUNGEON_DIFFICULTY_HEROIC)
514 {
515 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellIdForDifficulty: spell {} mode {} spell is nullptr, using mode {}", spellId, mode, mode - 2);
516 mode -= 2;
517 }
518
519 if (difficultyEntry->SpellID[mode] <= 0)
520 {
521 LOG_ERROR("sql.sql", "SpellMgr::GetSpellIdForDifficulty: spell {} mode {} spell is 0. Check spelldifficulty_dbc!", spellId, mode);
522 return spellId;
523 }
524
525 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellIdForDifficulty: spellid for spell {} in mode {} is {}", spellId, mode, difficultyEntry->SpellID[mode]);
526 return uint32(difficultyEntry->SpellID[mode]);
527}
@ 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:476
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
633{
634 SpellLearnSkillMap::const_iterator itr = mSpellLearnSkills.find(spell_id);
635 if (itr != mSpellLearnSkills.end())
636 return &itr->second;
637 else
638 return nullptr;
639}
SpellLearnSkillMap mSpellLearnSkills
Definition SpellMgr.h:787

References mSpellLearnSkills.

◆ GetSpellLinked()

const std::vector< int32 > * SpellMgr::GetSpellLinked ( int32  spell_id) const
943{
944 SpellLinkedMap::const_iterator itr = mSpellLinkedMap.find(spell_id);
945 return itr != mSpellLinkedMap.end() ? &(itr->second) : nullptr;
946}
SpellLinkedMap mSpellLinkedMap
Definition SpellMgr.h:798

References mSpellLinkedMap.

◆ GetSpellMixologyBonus()

float SpellMgr::GetSpellMixologyBonus ( uint32  spellId) const
907{
908 SpellMixologyMap::const_iterator itr = mSpellMixologyMap.find(spellId);
909 if (itr == mSpellMixologyMap.end())
910 return 30.0f;
911
912 return itr->second;
913}
SpellMixologyMap mSpellMixologyMap
Definition SpellMgr.h:796

References mSpellMixologyMap.

◆ GetSpellProcEntry()

SpellProcEntry const * SpellMgr::GetSpellProcEntry ( uint32  spellId) const
789{
790 SpellProcMap::const_iterator itr = mSpellProcMap.find(spellId);
791 if (itr != mSpellProcMap.end())
792 return &itr->second;
793 return nullptr;
794}
SpellProcMap mSpellProcMap
Definition SpellMgr.h:793

References mSpellProcMap.

◆ GetSpellRank()

uint8 SpellMgr::GetSpellRank ( uint32  spell_id) const
587{
588 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
589 return node->rank;
590
591 return 0;
592}

References GetSpellChainNode().

◆ GetSpellSpellGroupMapBounds()

SpellSpellGroupMapBounds SpellMgr::GetSpellSpellGroupMapBounds ( uint32  spell_id) const
650{
651 spell_id = GetFirstSpellInChain(spell_id);
652 return mSpellSpellGroup.equal_range(spell_id);
653}
SpellSpellGroupMap mSpellSpellGroup
Definition SpellMgr.h:789

References GetFirstSpellInChain(), and mSpellSpellGroup.

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

◆ GetSpellsRequiredForSpellBounds()

Acore::IteratorPair< SpellRequiredMap::const_iterator > SpellMgr::GetSpellsRequiredForSpellBounds ( uint32  spell_id) const
607{
609}
SpellRequiredMap mSpellReq
Definition SpellMgr.h:786
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
612{
613 return mSpellsReqSpell.equal_range(spell_id);
614}
SpellsRequiringSpellMap mSpellsReqSpell
Definition SpellMgr.h:785

References mSpellsReqSpell.

Referenced by IsSpellRequiringSpell().

◆ GetSpellTargetPosition()

SpellTargetPosition const * SpellMgr::GetSpellTargetPosition ( uint32  spell_id,
SpellEffIndex  effIndex 
) const
642{
643 SpellTargetPositionMap::const_iterator itr = mSpellTargetPositions.find(std::make_pair(spell_id, effIndex));
644 if (itr != mSpellTargetPositions.end())
645 return &itr->second;
646 return nullptr;
647}
SpellTargetPositionMap mSpellTargetPositions
Definition SpellMgr.h:788

References mSpellTargetPositions.

◆ GetSpellThreatEntry()

SpellThreatEntry const * SpellMgr::GetSpellThreatEntry ( uint32  spellID) const
892{
893 SpellThreatMap::const_iterator itr = mSpellThreatMap.find(spellID);
894 if (itr != mSpellThreatMap.end())
895 return &itr->second;
896 else
897 {
898 uint32 firstSpell = GetFirstSpellInChain(spellID);
899 itr = mSpellThreatMap.find(firstSpell);
900 if (itr != mSpellThreatMap.end())
901 return &itr->second;
902 }
903 return nullptr;
904}
SpellThreatMap mSpellThreatMap
Definition SpellMgr.h:795

References GetFirstSpellInChain(), and mSpellThreatMap.

◆ GetSpellWithRank()

uint32 SpellMgr::GetSpellWithRank ( uint32  spell_id,
uint32  rank,
bool  strict = false 
) const
595{
596 if (SpellChainNode const* node = GetSpellChainNode(spell_id))
597 {
598 if (rank != node->rank)
599 return GetSpellWithRank(node->rank < rank ? node->next->Id : node->prev->Id, rank, strict);
600 }
601 else if (strict && rank > 1)
602 return 0;
603 return spell_id;
604}
uint32 GetSpellWithRank(uint32 spell_id, uint32 rank, bool strict=false) const
Definition SpellMgr.cpp:594

References GetSpellChainNode(), and GetSpellWithRank().

Referenced by GetSpellWithRank().

◆ HasSpellCooldownOverride()

bool SpellMgr::HasSpellCooldownOverride ( uint32  spellId) const
2921{
2922 return mSpellCooldownOverrideMap.find(spellId) != mSpellCooldownOverrideMap.end();
2923}

References mSpellCooldownOverrideMap.

Referenced by LoadSpellInfoCustomAttributes().

◆ instance()

SpellMgr * SpellMgr::instance ( )
static
362{
363 static SpellMgr instance;
364 return &instance;
365}
Definition SpellMgr.h:627
static SpellMgr * instance()
Definition SpellMgr.cpp:361

References instance().

Referenced by instance().

◆ IsAdditionalTalentSpell()

bool SpellMgr::IsAdditionalTalentSpell ( uint32  spellId) const
628{
629 return mTalentSpellAdditionalSet.find(spellId) != mTalentSpellAdditionalSet.end();
630}
TalentAdditionalSet mTalentSpellAdditionalSet
Definition SpellMgr.h:811

References mTalentSpellAdditionalSet.

◆ IsArenaAllowedEnchancment()

bool SpellMgr::IsArenaAllowedEnchancment ( uint32  ench_id) const
938{
939 return mEnchantCustomAttr[ench_id];
940}
EnchantCustomAttribute mEnchantCustomAttr
Definition SpellMgr.h:800

References mEnchantCustomAttr.

◆ IsSpellMemberOfSpellGroup()

bool SpellMgr::IsSpellMemberOfSpellGroup ( uint32  spell_id,
SpellGroup  group_id 
) const
656{
658 for (SpellSpellGroupMap::const_iterator itr = spellGroup.first; itr != spellGroup.second; ++itr)
659 {
660 if (itr->second == group_id)
661 return true;
662 }
663 return false;
664}

References GetSpellSpellGroupMapBounds().

Referenced by CheckSpellGroupStackRules().

◆ IsSpellRequiringSpell()

bool SpellMgr::IsSpellRequiringSpell ( uint32  spellid,
uint32  req_spellid 
) const
617{
618 SpellsRequiringSpellMapBounds spellsRequiringSpell = GetSpellsRequiringSpellBounds(req_spellid);
619 for (SpellsRequiringSpellMap::const_iterator itr = spellsRequiringSpell.first; itr != spellsRequiringSpell.second; ++itr)
620 {
621 if (itr->second == spellid)
622 return true;
623 }
624 return false;
625}
std::pair< SpellsRequiringSpellMap::const_iterator, SpellsRequiringSpellMap::const_iterator > SpellsRequiringSpellMapBounds
Definition SpellMgr.h:557
SpellsRequiringSpellMapBounds GetSpellsRequiringSpellBounds(uint32 spell_id) const
Definition SpellMgr.cpp:611

References GetSpellsRequiringSpellBounds().

Referenced by LoadSpellRequired().

◆ IsSpellValid()

◆ LoadEnchantCustomAttr()

void SpellMgr::LoadEnchantCustomAttr ( )
Todo:
: find a better check
2337{
2338 uint32 oldMSTime = getMSTime();
2339
2340 uint32 size = sSpellItemEnchantmentStore.GetNumRows();
2341 mEnchantCustomAttr.resize(size);
2342
2343 for (uint32 i = 0; i < size; ++i)
2344 mEnchantCustomAttr[i] = 0;
2345
2346 uint32 count = 0;
2347 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2348 {
2349 SpellInfo const* spellInfo = GetSpellInfo(i);
2350 if (!spellInfo)
2351 continue;
2352
2354 // Xinef: commented second part, fixes warlock enchants like firestone, spellstone
2355 if (!spellInfo->HasAttribute(SPELL_ATTR2_ENCHANT_OWN_ITEM_ONLY)/* || !spellInfo->HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFTED)*/)
2356 continue;
2357
2358 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
2359 {
2360 if (spellInfo->Effects[j].Effect == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY)
2361 {
2362 uint32 enchId = spellInfo->Effects[j].MiscValue;
2363 SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchId);
2364 if (!ench)
2365 continue;
2366 mEnchantCustomAttr[enchId] = true;
2367 ++count;
2368 break;
2369 }
2370 }
2371 }
2372
2373 LOG_INFO("server.loading", ">> Loaded {} Custom Enchant Attributes in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2374 LOG_INFO("server.loading", " ");
2375}
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
#define LOG_INFO(filterType__,...)
Definition Log.h:166
@ 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:415
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition SpellInfo.h:393
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 ( )
2570{
2571 uint32 oldMSTime = getMSTime();
2572
2573 mPetDefaultSpellsMap.clear();
2574
2575 uint32 countCreature = 0;
2576 uint32 countData = 0;
2577
2578 CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
2579 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
2580 {
2581 if (!itr->second.PetSpellDataId)
2582 continue;
2583
2584 // for creature with PetSpellDataId get default pet spells from dbc
2585 CreatureSpellDataEntry const* spellDataEntry = sCreatureSpellDataStore.LookupEntry(itr->second.PetSpellDataId);
2586 if (!spellDataEntry)
2587 continue;
2588
2589 int32 petSpellsId = -int32(itr->second.PetSpellDataId);
2590 PetDefaultSpellsEntry petDefSpells;
2591 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2592 petDefSpells.spellid[j] = spellDataEntry->spellId[j];
2593
2594 if (LoadPetDefaultSpells_helper(&itr->second, petDefSpells))
2595 {
2596 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2597 ++countData;
2598 }
2599 }
2600
2601 LOG_INFO("server.loading", ">> Loaded Addition Spells For {} Pet Spell Data Entries in {} ms", countData, GetMSTimeDiffToNow(oldMSTime));
2602 LOG_INFO("server.loading", " ");
2603
2604 LOG_INFO("server.loading", "Loading Summonable Creature Templates...");
2605 oldMSTime = getMSTime();
2606
2607 // different summon spells
2608 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2609 {
2610 SpellInfo const* spellInfo = GetSpellInfo(i);
2611 if (!spellInfo)
2612 continue;
2613
2614 for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
2615 {
2616 if (spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON || spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON_PET)
2617 {
2618 uint32 creature_id = spellInfo->Effects[k].MiscValue;
2619 CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id);
2620 if (!cInfo)
2621 continue;
2622
2623 // already loaded
2624 if (cInfo->PetSpellDataId)
2625 continue;
2626
2627 // for creature without PetSpellDataId get default pet spells from creature_template
2628 int32 petSpellsId = cInfo->Entry;
2629 if (mPetDefaultSpellsMap.find(cInfo->Entry) != mPetDefaultSpellsMap.end())
2630 continue;
2631
2632 PetDefaultSpellsEntry petDefSpells;
2633 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2634 petDefSpells.spellid[j] = cInfo->spells[j];
2635
2636 if (LoadPetDefaultSpells_helper(cInfo, petDefSpells))
2637 {
2638 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2639 ++countCreature;
2640 }
2641 }
2642 }
2643 }
2644
2645 LOG_INFO("server.loading", ">> Loaded {} Summonable Creature emplates in {} ms", countCreature, GetMSTimeDiffToNow(oldMSTime));
2646 LOG_INFO("server.loading", " ");
2647}
std::unordered_map< uint32, CreatureTemplate > CreatureTemplateContainer
Definition CreatureData.h:288
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:2521
Definition DBCStructure.h:810
uint32 spellId[MAX_CREATURE_SPELL_DATA_SLOT]
Definition DBCStructure.h:812
Definition CreatureData.h:186
uint32 Entry
Definition CreatureData.h:187
uint32 spells[MAX_CREATURE_SPELLS]
Definition CreatureData.h:224
uint32 PetSpellDataId
Definition CreatureData.h:225
Definition SpellMgr.h:579
uint32 spellid[MAX_CREATURE_SPELL_DATA_SLOT]
Definition SpellMgr.h:580

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 ( )
2476{
2477 uint32 oldMSTime = getMSTime();
2478
2479 mPetLevelupSpellMap.clear(); // need for reload case
2480
2481 uint32 count = 0;
2482 uint32 family_count = 0;
2483
2484 for (uint32 i = 0; i < sCreatureFamilyStore.GetNumRows(); ++i)
2485 {
2486 CreatureFamilyEntry const* creatureFamily = sCreatureFamilyStore.LookupEntry(i);
2487 if (!creatureFamily) // not exist
2488 continue;
2489
2490 for (uint8 j = 0; j < 2; ++j)
2491 {
2492 if (!creatureFamily->skillLine[j])
2493 continue;
2494
2495 for (SkillLineAbilityEntry const* skillLine : GetSkillLineAbilitiesBySkillLine(creatureFamily->skillLine[j]))
2496 {
2497 if (skillLine->AcquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN)
2498 continue;
2499
2500 SpellInfo const* spell = GetSpellInfo(skillLine->Spell);
2501 if (!spell) // not exist or triggered or talent
2502 continue;
2503
2504 if (!spell->SpellLevel)
2505 continue;
2506
2507 PetLevelupSpellSet& spellSet = mPetLevelupSpellMap[creatureFamily->ID];
2508 if (spellSet.empty())
2509 ++family_count;
2510
2511 spellSet.insert(PetLevelupSpellSet::value_type(spell->SpellLevel, spell->Id));
2512 ++count;
2513 }
2514 }
2515 }
2516
2517 LOG_INFO("server.loading", ">> Loaded {} Pet Levelup And Default Spells For {} Families in {} ms", count, family_count, GetMSTimeDiffToNow(oldMSTime));
2518 LOG_INFO("server.loading", " ");
2519}
@ 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:573
uint32 SpellLevel
Definition SpellInfo.h:360
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 ( )
2252{
2253 uint32 oldMSTime = getMSTime();
2254
2255 mSkillLineAbilityMap.clear();
2256
2257 uint32 count = 0;
2258
2259 for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); ++i)
2260 {
2261 SkillLineAbilityEntry const* SkillInfo = sSkillLineAbilityStore.LookupEntry(i);
2262 if (!SkillInfo)
2263 continue;
2264
2265 mSkillLineAbilityMap.insert(SkillLineAbilityMap::value_type(SkillInfo->Spell, SkillInfo));
2266 ++count;
2267 }
2268
2269 LOG_INFO("server.loading", ">> Loaded {} SkillLineAbility MultiMap Data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2270 LOG_INFO("server.loading", " ");
2271}
DBCStorage< SkillLineAbilityEntry > sSkillLineAbilityStore(SkillLineAbilityfmt)
uint32 Spell
Definition DBCStructure.h:1601

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

◆ LoadSpellAreas()

void SpellMgr::LoadSpellAreas ( )
2650{
2651 uint32 oldMSTime = getMSTime();
2652
2653 mSpellAreaMap.clear(); // need for reload case
2654 mSpellAreaForQuestMap.clear();
2656 mSpellAreaForAuraMap.clear();
2657
2658 // 0 1 2 3 4 5 6 7 8 9
2659 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");
2660
2661 if (!result)
2662 {
2663 LOG_WARN("server.loading", ">> Loaded 0 spell area requirements. DB table `spell_area` is empty.");
2664 LOG_INFO("server.loading", " ");
2665 return;
2666 }
2667
2668 uint32 count = 0;
2669 do
2670 {
2671 Field* fields = result->Fetch();
2672
2673 uint32 spell = fields[0].Get<uint32>();
2674 SpellArea spellArea;
2675 spellArea.spellId = spell;
2676 spellArea.areaId = fields[1].Get<uint32>();
2677 spellArea.questStart = fields[2].Get<uint32>();
2678 spellArea.questStartStatus = fields[3].Get<uint32>();
2679 spellArea.questEndStatus = fields[4].Get<uint32>();
2680 spellArea.questEnd = fields[5].Get<uint32>();
2681 spellArea.auraSpell = fields[6].Get<int32>();
2682 spellArea.raceMask = fields[7].Get<uint32>();
2683 spellArea.gender = Gender(fields[8].Get<uint8>());
2684 spellArea.autocast = fields[9].Get<bool>();
2685
2686 if (SpellInfo const* spellInfo = GetSpellInfo(spell))
2687 {
2688 if (spellArea.autocast)
2689 const_cast<SpellInfo*>(spellInfo)->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
2690 }
2691 else
2692 {
2693 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` does not exist", spell);
2694 continue;
2695 }
2696
2697 {
2698 bool ok = true;
2699 SpellAreaMapBounds sa_bounds = GetSpellAreaMapBounds(spellArea.spellId);
2700 for (SpellAreaMap::const_iterator itr = sa_bounds.first; itr != sa_bounds.second; ++itr)
2701 {
2702 if (spellArea.spellId != itr->second.spellId)
2703 continue;
2704 if (spellArea.areaId != itr->second.areaId)
2705 continue;
2706 if (spellArea.questStart != itr->second.questStart)
2707 continue;
2708 if (spellArea.auraSpell != itr->second.auraSpell)
2709 continue;
2710 if ((spellArea.raceMask & itr->second.raceMask) == 0)
2711 continue;
2712 if (spellArea.gender != itr->second.gender)
2713 continue;
2714
2715 // duplicate by requirements
2716 ok = false;
2717 break;
2718 }
2719
2720 if (!ok)
2721 {
2722 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` already listed with similar requirements.", spell);
2723 continue;
2724 }
2725 }
2726
2727 if (spellArea.areaId && !sAreaTableStore.LookupEntry(spellArea.areaId))
2728 {
2729 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong area ({}) requirement", spell, spellArea.areaId);
2730 continue;
2731 }
2732
2733 if (spellArea.questStart && !sObjectMgr->GetQuestTemplate(spellArea.questStart))
2734 {
2735 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong start quest ({}) requirement", spell, spellArea.questStart);
2736 continue;
2737 }
2738
2739 if (spellArea.questEnd)
2740 {
2741 if (!sObjectMgr->GetQuestTemplate(spellArea.questEnd))
2742 {
2743 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong end quest ({}) requirement", spell, spellArea.questEnd);
2744 continue;
2745 }
2746 }
2747
2748 if (spellArea.auraSpell)
2749 {
2750 SpellInfo const* spellInfo = GetSpellInfo(std::abs(spellArea.auraSpell));
2751 if (!spellInfo)
2752 {
2753 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong aura spell ({}) requirement", spell, std::abs(spellArea.auraSpell));
2754 continue;
2755 }
2756
2757 if (uint32(std::abs(spellArea.auraSpell)) == spellArea.spellId)
2758 {
2759 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement for itself", spell, std::abs(spellArea.auraSpell));
2760 continue;
2761 }
2762
2763 // not allow autocast chains by auraSpell field (but allow use as alternative if not present)
2764 if (spellArea.autocast && spellArea.auraSpell > 0)
2765 {
2766 bool chain = false;
2767 SpellAreaForAuraMapBounds saBound = GetSpellAreaForAuraMapBounds(spellArea.spellId);
2768 for (SpellAreaForAuraMap::const_iterator itr = saBound.first; itr != saBound.second; ++itr)
2769 {
2770 if (itr->second->autocast && itr->second->auraSpell > 0)
2771 {
2772 chain = true;
2773 break;
2774 }
2775 }
2776
2777 if (chain)
2778 {
2779 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement that itself autocast from aura", spell, spellArea.auraSpell);
2780 continue;
2781 }
2782
2783 SpellAreaMapBounds saBound2 = GetSpellAreaMapBounds(spellArea.auraSpell);
2784 for (SpellAreaMap::const_iterator itr2 = saBound2.first; itr2 != saBound2.second; ++itr2)
2785 {
2786 if (itr2->second.autocast && itr2->second.auraSpell > 0)
2787 {
2788 chain = true;
2789 break;
2790 }
2791 }
2792
2793 if (chain)
2794 {
2795 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement that itself autocast from aura", spell, spellArea.auraSpell);
2796 continue;
2797 }
2798 }
2799 }
2800
2801 if (spellArea.raceMask && (spellArea.raceMask & sRaceMgr->GetPlayableRaceMask()) == 0)
2802 {
2803 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong race mask ({}) requirement", spell, spellArea.raceMask);
2804 continue;
2805 }
2806
2807 if (spellArea.gender != GENDER_NONE && spellArea.gender != GENDER_FEMALE && spellArea.gender != GENDER_MALE)
2808 {
2809 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong gender ({}) requirement", spell, spellArea.gender);
2810 continue;
2811 }
2812
2813 SpellArea const* sa = &mSpellAreaMap.insert(SpellAreaMap::value_type(spell, spellArea))->second;
2814
2815 // for search by current zone/subzone at zone/subzone change
2816 if (spellArea.areaId)
2817 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(spellArea.areaId, sa));
2818
2819 // for search at quest start/reward
2820 if (spellArea.questStart)
2821 mSpellAreaForQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa));
2822
2823 // for search at quest start/reward
2824 if (spellArea.questEnd)
2825 mSpellAreaForQuestEndMap.insert(SpellAreaForQuestMap::value_type(spellArea.questEnd, sa));
2826
2827 // for search at aura apply
2828 if (spellArea.auraSpell)
2829 mSpellAreaForAuraMap.insert(SpellAreaForAuraMap::value_type(std::abs(spellArea.auraSpell), sa));
2830
2831 ++count;
2832 } while (result->NextRow());
2833
2834 if (sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE) > 0)
2835 {
2836 LOG_INFO("server.loading", ">> Using ICC Buff Horde: {}", sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE));
2837 SpellArea spellAreaICCBuffHorde = { sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE), ICC_AREA, 0, 0, 0, ICC_RACEMASK_HORDE, Gender(2), 64, 11, 1 };
2838 SpellArea const* saICCBuffHorde = &mSpellAreaMap.insert(SpellAreaMap::value_type(sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE), spellAreaICCBuffHorde))->second;
2839 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(ICC_AREA, saICCBuffHorde));
2840 ++count;
2841 }
2842 else
2843 LOG_INFO("server.loading", ">> ICC Buff Horde: disabled");
2844
2845 if (sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE) > 0)
2846 {
2847 LOG_INFO("server.loading", ">> Using ICC Buff Alliance: {}", sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE));
2848 SpellArea spellAreaICCBuffAlliance = { sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE), ICC_AREA, 0, 0, 0, ICC_RACEMASK_ALLIANCE, Gender(2), 64, 11, 1 };
2849 SpellArea const* saICCBuffAlliance = &mSpellAreaMap.insert(SpellAreaMap::value_type(sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE), spellAreaICCBuffAlliance))->second;
2850 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(ICC_AREA, saICCBuffAlliance));
2851 ++count;
2852 }
2853 else
2854 LOG_INFO("server.loading", ">> ICC Buff Alliance: disabled");
2855
2856 LOG_INFO("server.loading", ">> Loaded {} Spell Area Requirements in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2857 LOG_INFO("server.loading", " ");
2858}
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
std::shared_ptr< ResultSet > QueryResult
Definition DatabaseEnvFwd.h:27
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
Definition DatabaseEnv.cpp:20
#define LOG_WARN(filterType__,...)
Definition Log.h:162
#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:534
@ ICC_RACEMASK_HORDE
Definition SpellMgr.h:509
@ ICC_AREA
Definition SpellMgr.h:508
@ ICC_RACEMASK_ALLIANCE
Definition SpellMgr.h:510
std::pair< SpellAreaForAuraMap::const_iterator, SpellAreaForAuraMap::const_iterator > SpellAreaForAuraMapBounds
Definition SpellMgr.h:536
@ CONFIG_ICC_BUFF_ALLIANCE
Definition WorldConfig.h:344
@ CONFIG_ICC_BUFF_HORDE
Definition WorldConfig.h:343
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
SpellAreaMapBounds GetSpellAreaMapBounds(uint32 spell_id) const
Definition SpellMgr.cpp:965
SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds(uint32 spell_id) const
Definition SpellMgr.cpp:980
#define sWorld
Definition World.h:316
Definition SpellMgr.h:514
uint32 spellId
Definition SpellMgr.h:515

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 ( )
2134{
2135 uint32 oldMSTime = getMSTime();
2136
2137 mSpellBonusMap.clear(); // need for reload case
2138
2139 // 0 1 2 3 4
2140 QueryResult result = WorldDatabase.Query("SELECT entry, direct_bonus, dot_bonus, ap_bonus, ap_dot_bonus FROM spell_bonus_data");
2141 if (!result)
2142 {
2143 LOG_WARN("server.loading", ">> Loaded 0 spell bonus data. DB table `spell_bonus_data` is empty.");
2144 LOG_INFO("server.loading", " ");
2145 return;
2146 }
2147
2148 uint32 count = 0;
2149 do
2150 {
2151 Field* fields = result->Fetch();
2152 uint32 entry = fields[0].Get<uint32>();
2153
2154 SpellInfo const* spell = GetSpellInfo(entry);
2155 if (!spell)
2156 {
2157 LOG_ERROR("sql.sql", "Spell {} listed in `spell_bonus_data` does not exist", entry);
2158 continue;
2159 }
2160
2161 SpellBonusEntry& sbe = mSpellBonusMap[entry];
2162 sbe.direct_damage = fields[1].Get<float>();
2163 sbe.dot_damage = fields[2].Get<float>();
2164 sbe.ap_bonus = fields[3].Get<float>();
2165 sbe.ap_dot_bonus = fields[4].Get<float>();
2166
2167 ++count;
2168 } while (result->NextRow());
2169
2170 LOG_INFO("server.loading", ">> Loaded {} Extra Spell Bonus Data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2171 LOG_INFO("server.loading", " ");
2172}
Definition SpellMgr.h:318
float ap_dot_bonus
Definition SpellMgr.h:322
float dot_damage
Definition SpellMgr.h:320
float ap_bonus
Definition SpellMgr.h:321
float direct_damage
Definition SpellMgr.h:319

References SpellBonusEntry::ap_bonus, SpellBonusEntry::ap_dot_bonus, SpellBonusEntry::direct_damage, SpellBonusEntry::dot_damage, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), GetSpellInfo(), LOG_ERROR, LOG_INFO, LOG_WARN, mSpellBonusMap, and WorldDatabase.

◆ LoadSpellCooldownOverrides()

void SpellMgr::LoadSpellCooldownOverrides ( )
2890{
2891 uint32 oldMSTime = getMSTime();
2892
2894
2895 QueryResult result = WorldDatabase.Query("SELECT Id, RecoveryTime, CategoryRecoveryTime, StartRecoveryTime, StartRecoveryCategory FROM spell_cooldown_overrides");
2896
2897 uint32 count = 0;
2898
2899 if (result)
2900 {
2901 do
2902 {
2903 Field* fields = result->Fetch();
2904 SpellCooldownOverride spellCooldown;
2905 uint32 spellId = fields[0].Get<uint32>();
2906 spellCooldown.RecoveryTime = fields[1].Get<uint32>();
2907 spellCooldown.CategoryRecoveryTime = fields[2].Get<uint32>();
2908 spellCooldown.StartRecoveryTime = fields[3].Get<uint32>();
2909 spellCooldown.StartRecoveryCategory = fields[4].Get<uint32>();
2910 mSpellCooldownOverrideMap[spellId] = spellCooldown;
2911
2912 ++count;
2913 } while (result->NextRow());
2914 }
2915
2916 LOG_INFO("server.loading", ">> Loaded {} Spell Cooldown Overrides entries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2917 LOG_INFO("server.loading", " ");
2918}
Definition SpellMgr.h:594
uint32 StartRecoveryTime
Definition SpellMgr.h:597
uint32 CategoryRecoveryTime
Definition SpellMgr.h:596
uint32 StartRecoveryCategory
Definition SpellMgr.h:598
uint32 RecoveryTime
Definition SpellMgr.h:595

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

◆ LoadSpellEnchantProcData()

void SpellMgr::LoadSpellEnchantProcData ( )
2378{
2379 uint32 oldMSTime = getMSTime();
2380
2381 mSpellEnchantProcEventMap.clear(); // need for reload case
2382
2383 // 0 1 2 3 4
2384 QueryResult result = WorldDatabase.Query("SELECT entry, customChance, PPMChance, procEx, attributeMask FROM spell_enchant_proc_data");
2385 if (!result)
2386 {
2387 LOG_WARN("server.loading", ">> Loaded 0 spell enchant proc event conditions. DB table `spell_enchant_proc_data` is empty.");
2388 LOG_INFO("server.loading", " ");
2389 return;
2390 }
2391
2392 uint32 count = 0;
2393 do
2394 {
2395 Field* fields = result->Fetch();
2396
2397 uint32 enchantId = fields[0].Get<uint32>();
2398
2399 SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchantId);
2400 if (!ench)
2401 {
2402 LOG_ERROR("sql.sql", "Enchancment {} listed in `spell_enchant_proc_data` does not exist", enchantId);
2403 continue;
2404 }
2405
2407
2408 spe.customChance = fields[1].Get<uint32>();
2409 spe.PPMChance = fields[2].Get<float>();
2410 spe.procEx = fields[3].Get<uint32>();
2411 spe.attributeMask = fields[4].Get<uint32>();
2412
2413 mSpellEnchantProcEventMap[enchantId] = spe;
2414
2415 ++count;
2416 } while (result->NextRow());
2417
2418 LOG_INFO("server.loading", ">> Loaded {} Enchant Proc Data Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2419 LOG_INFO("server.loading", " ");
2420}
Definition SpellMgr.h:308
uint32 procEx
Definition SpellMgr.h:311
uint32 attributeMask
Definition SpellMgr.h:312
uint32 customChance
Definition SpellMgr.h:309
float PPMChance
Definition SpellMgr.h:310

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 ( )
1540{
1541 uint32 oldMSTime = getMSTime();
1542
1543 mSpellSpellGroup.clear(); // need for reload case
1544 mSpellGroupSpell.clear();
1545
1546 // 0 1
1547 QueryResult result = WorldDatabase.Query("SELECT id, spell_id FROM spell_group");
1548 if (!result)
1549 {
1550 LOG_WARN("server.loading", ">> Loaded 0 spell group definitions. DB table `spell_group` is empty.");
1551 LOG_INFO("server.loading", " ");
1552 return;
1553 }
1554
1555 std::set<uint32> groups;
1556 uint32 count = 0;
1557 do
1558 {
1559 Field* fields = result->Fetch();
1560
1561 uint32 group_id = fields[0].Get<uint32>();
1562 if (group_id <= SPELL_GROUP_DB_RANGE_MIN && group_id >= SPELL_GROUP_CORE_RANGE_MAX)
1563 {
1564 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group` is in core range, but is not defined in core!", group_id);
1565 continue;
1566 }
1567 int32 spell_id = fields[1].Get<int32>();
1568
1569 groups.insert(group_id);
1570 mSpellGroupSpell.emplace(SpellGroup(group_id), spell_id);
1571
1572 } while (result->NextRow());
1573
1574 for (auto itr = mSpellGroupSpell.begin(); itr!= mSpellGroupSpell.end();)
1575 {
1576 if (itr->second < 0)
1577 {
1578 if (groups.find(abs(itr->second)) == groups.end())
1579 {
1580 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group` does not exist", abs(itr->second));
1581 itr = mSpellGroupSpell.erase(itr);
1582 }
1583 else
1584 ++itr;
1585 }
1586 else
1587 {
1588 SpellInfo const* spellInfo = GetSpellInfo(itr->second);
1589 if (!spellInfo)
1590 {
1591 LOG_ERROR("sql.sql", "Spell {} listed in `spell_group` does not exist", itr->second);
1592 itr = mSpellGroupSpell.erase(itr);
1593 }
1594 else if (spellInfo->GetRank() > 1)
1595 {
1596 LOG_ERROR("sql.sql", "Spell {} listed in `spell_group` is not first rank of spell.", itr->second);
1597 itr = mSpellGroupSpell.erase(itr);
1598 }
1599 else
1600 ++itr;
1601 }
1602 }
1603
1604 for (auto groupItr = groups.begin(); groupItr != groups.end(); ++groupItr)
1605 {
1606 std::set<uint32> spells;
1608
1609 for (auto spellItr = spells.begin(); spellItr != spells.end(); ++spellItr)
1610 {
1611 ++count;
1612 mSpellSpellGroup.emplace(*spellItr, SpellGroup(*groupItr));
1613 }
1614 }
1615
1616 LOG_INFO("server.loading", ">> Loaded {} spell group Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1617 LOG_INFO("server.loading", " ");
1618}
@ SPELL_GROUP_CORE_RANGE_MAX
Definition SpellMgr.h:332
spells
Definition boss_krystallus.cpp:26
uint8 GetRank() const
Definition SpellInfo.cpp:2389

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 ( )
1621{
1622 uint32 oldMSTime = getMSTime();
1623
1624 mSpellGroupStack.clear(); // need for reload case
1625 mSpellSameEffectStack.clear();
1626
1627 std::vector<uint32> sameEffectGroups;
1628
1629 // 0 1
1630 QueryResult result = WorldDatabase.Query("SELECT group_id, stack_rule FROM spell_group_stack_rules");
1631 if (!result)
1632 {
1633 LOG_WARN("server.loading", ">> Loaded 0 spell group stack rules. DB table `spell_group_stack_rules` is empty.");
1634 LOG_INFO("server.loading", " ");
1635 return;
1636 }
1637
1638 uint32 count = 0;
1639 do
1640 {
1641 Field* fields = result->Fetch();
1642
1643 uint32 group_id = fields[0].Get<uint32>();
1644 uint8 stack_rule = fields[1].Get<int8>();
1645 if (stack_rule >= SPELL_GROUP_STACK_RULE_MAX)
1646 {
1647 LOG_ERROR("sql.sql", "SpellGroupStackRule {} listed in `spell_group_stack_rules` does not exist.", stack_rule);
1648 continue;
1649 }
1650
1651 auto bounds = GetSpellGroupSpellMapBounds((SpellGroup)group_id);
1652 if (bounds.first == bounds.second)
1653 {
1654 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group_stack_rules` does not exist.", group_id);
1655 continue;
1656 }
1657
1658 mSpellGroupStack.emplace(SpellGroup(group_id), SpellGroupStackRule(stack_rule));
1659
1660 // different container for same effect stack rules, need to check effect types
1662 sameEffectGroups.push_back(group_id);
1663
1664 ++count;
1665 } while (result->NextRow());
1666
1667 LOG_INFO("server.loading", ">> Loaded {} spell group stack rules in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1668 LOG_INFO("server.loading", " ");
1669
1670 count = 0;
1671 oldMSTime = getMSTime();
1672
1673 for (uint32 group_id : sameEffectGroups)
1674 {
1675 std::set<uint32> spellIds;
1676 GetSetOfSpellsInSpellGroup(SpellGroup(group_id), spellIds);
1677
1678 std::unordered_set<uint32> auraTypes;
1679
1680 // we have to 'guess' what effect this group corresponds to
1681 {
1682 std::unordered_multiset<uint32 /*auraName*/> frequencyContainer;
1683
1684 // only waylay for the moment (shared group)
1685 std::vector<std::vector<uint32 /*auraName*/>> const SubGroups =
1686 {
1688 };
1689
1690 for (uint32 spellId : spellIds)
1691 {
1692 SpellInfo const* spellInfo = AssertSpellInfo(spellId);
1693 for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
1694 {
1695 if (!spellEffectInfo.IsAura())
1696 continue;
1697
1698 uint32 auraName = spellEffectInfo.ApplyAuraName;
1699 for (std::vector<uint32> const& subGroup : SubGroups)
1700 {
1701 if (std::find(subGroup.begin(), subGroup.end(), auraName) != subGroup.end())
1702 {
1703 // count as first aura
1704 auraName = subGroup.front();
1705 break;
1706 }
1707 }
1708
1709 frequencyContainer.insert(auraName);
1710 }
1711 }
1712
1713 uint32 auraType = 0;
1714 size_t auraTypeCount = 0;
1715 for (uint32 auraName : frequencyContainer)
1716 {
1717 size_t currentCount = frequencyContainer.count(auraName);
1718 if (currentCount > auraTypeCount)
1719 {
1720 auraType = auraName;
1721 auraTypeCount = currentCount;
1722 }
1723 }
1724
1725 for (std::vector<uint32> const& subGroup : SubGroups)
1726 {
1727 if (auraType == subGroup.front())
1728 {
1729 auraTypes.insert(subGroup.begin(), subGroup.end());
1730 break;
1731 }
1732 }
1733
1734 if (auraTypes.empty())
1735 auraTypes.insert(auraType);
1736 }
1737
1738 // re-check spells against guessed group
1739 for (uint32 spellId : spellIds)
1740 {
1741 SpellInfo const* spellInfo = AssertSpellInfo(spellId);
1742
1743 bool found = false;
1744 while (spellInfo)
1745 {
1746 for (uint32 auraType : auraTypes)
1747 {
1748 if (spellInfo->HasAura(AuraType(auraType)))
1749 {
1750 found = true;
1751 break;
1752 }
1753 }
1754
1755 if (found)
1756 break;
1757
1758 spellInfo = spellInfo->GetNextRankSpell();
1759 }
1760
1761 // not found either, log error
1762 if (!found)
1763 LOG_ERROR("sql.sql", "SpellId {} listed in `spell_group` with stack rule 3 does not share aura assigned for group {}", spellId, group_id);
1764 }
1765
1766 mSpellSameEffectStack[SpellGroup(group_id)] = auraTypes;
1767 ++count;
1768 }
1769
1770 LOG_INFO("server.loading", ">> Loaded {} SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT stack rules in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1771 LOG_INFO("server.loading", " ");
1772}
std::int8_t int8
Definition Define.h:105
AuraType
Definition SpellAuraDefines.h:62
@ 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:362
@ SPELL_GROUP_STACK_RULE_MAX
Definition SpellMgr.h:364
Definition SpellInfo.h:249
SpellInfo const * GetNextRankSpell() const
Definition SpellInfo.cpp:2408
bool HasAura(AuraType aura) const
Definition SpellInfo.cpp:893
SpellInfo const * AssertSpellInfo(uint32 spellId) const
Definition SpellMgr.h:717

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

◆ LoadSpellInfoCorrections()

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

◆ LoadSpellInfoCustomAttributes()

void SpellMgr::LoadSpellInfoCustomAttributes ( )
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
2967{
2968 uint32 const oldMSTime = getMSTime();
2969 uint32 const customAttrTime = getMSTime();
2970 uint32 count;
2971
2972 QueryResult result = WorldDatabase.Query("SELECT spell_id, attributes FROM spell_custom_attr");
2973
2974 if (!result)
2975 {
2976 LOG_WARN("server.loading", ">> Loaded 0 Spell Custom Attributes From DB. DB table `spell_custom_attr` Is Empty.");
2977 }
2978 else
2979 {
2980 for (count = 0; result->NextRow(); ++count)
2981 {
2982 Field const* fields = result->Fetch();
2983
2984 uint32 const spellId = fields[0].Get<uint32>();
2985 uint32 attributes = fields[1].Get<uint32>();
2986
2987 SpellInfo* spellInfo = _GetSpellInfo(spellId);
2988 if (!spellInfo)
2989 {
2990 LOG_INFO("sql.sql", "Table `spell_custom_attr` has wrong spell (spell_id: {}), ignored.", spellId);
2991 continue;
2992 }
2993
2994 if (attributes & SPELL_ATTR0_CU_NEGATIVE)
2995 {
2996 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2997 {
2998 if (spellInfo->Effects[i].IsEffect())
2999 {
3000 if ((attributes & (SPELL_ATTR0_CU_NEGATIVE_EFF0 << i)) && (attributes & (SPELL_ATTR0_CU_POSITIVE_EFF0 << i)))
3001 {
3002 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);
3004 }
3005 continue;
3006 }
3007
3008 if (attributes & (SPELL_ATTR0_CU_NEGATIVE_EFF0 << i))
3009 {
3010 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));
3011 attributes &= ~(SPELL_ATTR0_CU_NEGATIVE_EFF0 << i);
3012 }
3013 }
3014 }
3015
3016 if (attributes & SPELL_ATTR0_CU_POSITIVE)
3017 {
3018 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3019 {
3020 if (spellInfo->Effects[i].IsEffect())
3021 {
3022 continue;
3023 }
3024
3025 if ((attributes & (SPELL_ATTR0_CU_POSITIVE_EFF0 << i)))
3026 {
3027 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));
3028 attributes &= ~(SPELL_ATTR0_CU_POSITIVE_EFF0 << i);
3029 }
3030 }
3031 }
3032
3033 if ((attributes & SPELL_ATTR0_CU_FORCE_AURA_SAVING) && (attributes & SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED))
3034 {
3035 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);
3037 }
3038
3039 spellInfo->AttributesCu |= attributes;
3040 }
3041 LOG_INFO("server.loading", ">> Loaded {} spell custom attributes from DB in {} ms", count, GetMSTimeDiffToNow(customAttrTime));
3042 }
3043
3044 // xinef: create talent spells set
3045 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
3046 {
3047 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
3048 if (!talentInfo)
3049 continue;
3050
3051 for (uint8 j = 0; j < MAX_TALENT_RANK; j++)
3052 if (uint32 spellId = talentInfo->RankID[j])
3053 if (SpellInfo const* spellInfo = GetSpellInfo(spellId))
3054 for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
3055 if (spellInfo->Effects[k].Effect == SPELL_EFFECT_LEARN_SPELL)
3056 if (SpellInfo const* learnSpell = GetSpellInfo(spellInfo->Effects[k].TriggerSpell))
3057 if (learnSpell->IsRanked() && !learnSpell->HasAttribute(SpellAttr0(SPELL_ATTR0_PASSIVE | SPELL_ATTR0_DO_NOT_DISPLAY)))
3058 mTalentSpellAdditionalSet.insert(learnSpell->Id);
3059 }
3060
3061 SpellInfo* spellInfo = nullptr;
3062 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3063 {
3064 spellInfo = mSpellInfoMap[i];
3065 if (!spellInfo)
3066 continue;
3067
3068 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3069 {
3070 switch (spellInfo->Effects[j].ApplyAuraName)
3071 {
3073 {
3074 switch (spellInfo->Id)
3075 {
3076 // Exceptions
3077 case 44801: // Spectral Invisibility (Kalecgos, SWP)
3078 case 46021: // Spectral Realm (SWP)
3079 break;
3080 default:
3082 break;
3083 }
3084 }
3085 break;
3092 break;
3093 default:
3094 break;
3095 }
3096
3097 switch (spellInfo->Effects[j].ApplyAuraName)
3098 {
3099 case SPELL_AURA_CONVERT_RUNE: // Can't be saved - aura handler relies on calculated amount and changes it
3100 case SPELL_AURA_OPEN_STABLE: // No point in saving this, since the stable dialog can't be open on aura load anyway.
3101 // Auras that require both caster & target to be in world cannot be saved
3109 break;
3110 default:
3111 break;
3112 }
3113
3114 switch (spellInfo->Effects[j].ApplyAuraName)
3115 {
3123 break;
3126 break;
3127 default:
3128 break;
3129 }
3130
3131 switch (spellInfo->Effects[j].Effect)
3132 {
3138 case SPELL_EFFECT_HEAL:
3140 break;
3151 break;
3154 case SPELL_EFFECT_JUMP:
3157 spellInfo->AttributesCu |= SPELL_ATTR0_CU_CHARGE;
3158 break;
3161 break;
3166 {
3167 // Only Enchanting profession enchant procs can stack when dual-wielding
3168 // DK runes (e.g., Unholy Strength) should refresh, not stack
3170 {
3171 uint32 enchantId = spellInfo->Effects[j].MiscValue;
3172 SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId);
3173 if (!enchant)
3174 break;
3175
3176 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
3177 {
3178 if (enchant->type[s] != ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL)
3179 continue;
3180
3181 SpellInfo* procInfo = _GetSpellInfo(enchant->spellid[s]);
3182 if (!procInfo)
3183 continue;
3184
3185 // if proced directly from enchantment, not via proc aura
3186 // NOTE: Enchant Weapon - Blade Ward also has proc aura spell and is proced directly
3187 // however its not expected to stack so this check is good
3189 continue;
3190
3192 }
3193 }
3194 break;
3195 }
3196 }
3197 }
3198
3199 // Xinef: spells ignoring hit result should not be binary
3200 if (!spellInfo->HasAttribute(SPELL_ATTR3_ALWAYS_HIT))
3201 {
3202 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3203 {
3204 if (spellInfo->Effects[j].Effect)
3205 {
3206 switch (spellInfo->Effects[j].Effect)
3207 {
3215 continue;
3224 if (spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
3225 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE_PERCENT ||
3226 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_DUMMY ||
3227 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH ||
3228 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_HEALTH_FUNNEL ||
3229 spellInfo->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DUMMY)
3230 continue;
3231 [[fallthrough]];
3232 default:
3233 if (!(spellInfo->Effects[j].CalcValue() &&
3234 ((spellInfo->Effects[j].Effect == SPELL_EFFECT_INTERRUPT_CAST || spellInfo->HasAttribute(SPELL_ATTR0_CU_DONT_BREAK_STEALTH)) &&
3236 continue;
3237
3238 if (spellInfo->Id == 69649 || spellInfo->Id == 71056 || spellInfo->Id == 71057 || spellInfo->Id == 71058 ||
3239 spellInfo->Id == 73061 || spellInfo->Id == 73062 || spellInfo->Id == 73063 || spellInfo->Id == 73064)
3240 continue;
3241
3242 if (spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && (spellInfo->SpellFamilyFlags[0] & 0x20)) // Frostbolt
3243 continue;
3244
3245 if (spellInfo->Id == 55095) // Frost Fever
3246 continue;
3247
3248 if (spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK &&
3249 ((spellInfo->SpellFamilyFlags[1] & 0x40000) || (spellInfo->SpellFamilyFlags[0] & 0x4000))) // Haunt/Drain Soul
3250 continue;
3251
3253 break;
3254 }
3255 }
3256 }
3257 }
3258
3259 // pussywizard:
3260 if ((spellInfo->SchoolMask & SPELL_SCHOOL_MASK_NORMAL) && (spellInfo->SchoolMask & SPELL_SCHOOL_MASK_MAGIC))
3261 {
3262 spellInfo->SchoolMask &= ~SPELL_SCHOOL_MASK_NORMAL;
3264 }
3265
3266 if (!spellInfo->_IsPositiveEffect(EFFECT_0, false))
3268
3269 if (!spellInfo->_IsPositiveEffect(EFFECT_1, false))
3271
3272 if (!spellInfo->_IsPositiveEffect(EFFECT_2, false))
3274
3275 if (spellInfo->SpellVisual[0] == 3879)
3277
3278 switch (spellInfo->SpellFamilyName)
3279 {
3281 // Shout
3282 if (spellInfo->SpellFamilyFlags[0] & 0x20000 || spellInfo->SpellFamilyFlags[1] & 0x20)
3284 break;
3285 case SPELLFAMILY_DRUID:
3286 // Roar
3287 if (spellInfo->SpellFamilyFlags[0] & 0x8)
3289 break;
3290 case SPELLFAMILY_HUNTER:
3291 // Aspects
3292 if (spellInfo->GetCategory() == 47)
3293 {
3295 }
3296 // Aimed Shot
3297 if (spellInfo->SpellFamilyFlags[0] & 0x00020000)
3298 {
3300 }
3301 break;
3302 default:
3303 break;
3304 }
3305
3306 switch (spellInfo->Id)
3307 {
3308 // Xinef: additional spells which should be binary
3309 case 45145: // Snake Trap Effect
3311 break;
3312 case 1776: // Gouge
3313 case 1777:
3314 case 8629:
3315 case 11285:
3316 case 11286:
3317 case 12540:
3318 case 13579:
3319 case 24698:
3320 case 28456:
3321 case 29425:
3322 case 34940:
3323 case 36862:
3324 case 38764:
3325 case 38863:
3326 case 52743: // Head Smack
3328 break;
3329 case 53: // Backstab
3330 case 2589:
3331 case 2590:
3332 case 2591:
3333 case 7159:
3334 case 8627:
3335 case 8721:
3336 case 11279:
3337 case 11280:
3338 case 11281:
3339 case 15582:
3340 case 15657:
3341 case 22416:
3342 case 25300:
3343 case 26863:
3344 case 37685:
3345 case 48656:
3346 case 48657:
3347 case 703: // Garrote
3348 case 8631:
3349 case 8632:
3350 case 8633:
3351 case 11289:
3352 case 11290:
3353 case 26839:
3354 case 26884:
3355 case 48675:
3356 case 48676:
3357 case 5221: // Shred
3358 case 6800:
3359 case 8992:
3360 case 9829:
3361 case 9830:
3362 case 27001:
3363 case 27002:
3364 case 48571:
3365 case 48572:
3366 case 8676: // Ambush
3367 case 8724:
3368 case 8725:
3369 case 11267:
3370 case 11268:
3371 case 11269:
3372 case 27441:
3373 case 48689:
3374 case 48690:
3375 case 48691:
3376 case 6785: // Ravage
3377 case 6787:
3378 case 9866:
3379 case 9867:
3380 case 27005:
3381 case 48578:
3382 case 48579:
3383 case 21987: // Lash of Pain
3384 case 23959: // Test Stab R50
3385 case 24825: // Test Backstab
3386 case 58563: // Assassinate Restless Lookout
3387 case 63124: // quest There's Something About the Squire (13654)
3389 break;
3390 case 26029: // Dark Glare
3391 case 43140: // Flame Breath
3392 case 43215: // Flame Breath
3393 case 70461: // Coldflame Trap
3394 case 72133: // Pain and Suffering
3395 case 73788: // Pain and Suffering
3396 case 73789: // Pain and Suffering
3397 case 73790: // Pain and Suffering
3398 case 63293: // Mimiron - spinning damage
3399 case 68873: // Wailing Souls
3400 case 70324: // Wailing Souls
3401 case 64619: // Ulduar, Mimiron, Emergency Fire Bot, Water Spray
3403 break;
3404 case 58690: // Cyanigosa, Tail Sweep
3405 case 59283: // Cyanigosa, Tail Sweep
3407 break;
3408 case 24340: // Meteor
3409 case 26558: // Meteor
3410 case 28884: // Meteor
3411 case 36837: // Meteor
3412 case 38903: // Meteor
3413 case 41276: // Meteor
3414 case 57467: // Meteor
3415 case 26789: // Shard of the Fallen Star
3416 case 31436: // Malevolent Cleave
3417 case 40810: // Saber Lash
3418 case 43267: // Saber Lash
3419 case 43268: // Saber Lash
3420 case 42384: // Brutal Swipe
3421 case 45150: // Meteor Slash
3422 case 64688: // Sonic Screech
3423 case 72373: // Shared Suffering
3424 case 71904: // Chaos Bane
3425 case 70492: // Ooze Eruption
3426 case 72505: // Ooze Eruption
3427 case 72624: // Ooze Eruption
3428 case 72625: // Ooze Eruption
3429 // ONLY SPELLS WITH SPELLFAMILY_GENERIC and EFFECT_SCHOOL_DAMAGE, OR WEAPON_DMG_X
3430 case 66809: // Meteor Fists
3431 case 67331: // Meteor Fists
3432 case 66765: // Meteor Fists
3433 case 67333: // Meteor Fists
3435 break;
3436 case 18500: // Wing Buffet
3437 case 33086: // Wild Bite
3438 case 49749: // Piercing Blow
3439 case 52890: // Penetrating Strike
3440 case 53454: // Impale
3441 case 59446: // Impale
3442 case 62383: // Shatter
3443 case 64777: // Machine Gun
3444 case 65239: // Machine Gun
3445 case 69293: // Wing Buffet
3446 case 74439: // Machine Gun
3447 // Trial of the Crusader, Jaraxxus, Shivan Slash
3448 case 66378:
3449 case 67097:
3450 case 67098:
3451 case 67099:
3452 // Trial of the Crusader, Anub'arak, Impale
3453 case 65919:
3454 case 67858:
3455 case 67859:
3456 case 67860:
3457 case 63278: // Mark of the Faceless (General Vezax)
3458 case 64125: // Ulduar, Yogg-Saron, Squeeze
3459 case 64126: // Ulduar, Yogg-Saron, Squeeze
3460 case 62544: // Thrust (Argent Tournament)
3461 case 64588: // Thrust (Argent Tournament)
3462 case 66479: // Thrust (Argent Tournament)
3463 case 68505: // Thrust (Argent Tournament)
3464 case 62709: // Counterattack! (Argent Tournament)
3465 case 62626: // Break-Shield (Argent Tournament, Player)
3466 case 64590: // Break-Shield (Argent Tournament, Player)
3467 case 64342: // Break-Shield (Argent Tournament, NPC)
3468 case 64686: // Break-Shield (Argent Tournament, NPC)
3469 case 65147: // Break-Shield (Argent Tournament, NPC)
3470 case 68504: // Break-Shield (Argent Tournament, NPC)
3471 case 62874: // Charge (Argent Tournament, Player)
3472 case 68498: // Charge (Argent Tournament, Player)
3473 case 64591: // Charge (Argent Tournament, Player)
3474 case 63003: // Charge (Argent Tournament, NPC)
3475 case 63010: // Charge (Argent Tournament, NPC)
3476 case 68321: // Charge (Argent Tournament, NPC)
3477 case 72255: // Mark of the Fallen Champion (Deathbringer Saurfang)
3478 case 72444: // Mark of the Fallen Champion (Deathbringer Saurfang)
3479 case 72445: // Mark of the Fallen Champion (Deathbringer Saurfang)
3480 case 72446: // Mark of the Fallen Champion (Deathbringer Saurfang)
3481 case 72409: // Rune of Blood (Deathbringer Saurfang)
3482 case 72447: // Rune of Blood (Deathbringer Saurfang)
3483 case 72448: // Rune of Blood (Deathbringer Saurfang)
3484 case 72449: // Rune of Blood (Deathbringer Saurfang)
3485 case 49882: // Leviroth Self-Impale
3486 case 62775: // Ulduar: XT-002 Tympanic Tamparum
3488 break;
3489 case 64422: // Sonic Screech (Auriaya)
3492 break;
3493 case 72293: // Mark of the Fallen Champion (Deathbringer Saurfang)
3494 case 72347: // Lock Players and Tap Chest (Gunship Battle)
3496 break;
3497 default:
3498 break;
3499 case 63675: // Improved Devouring Plague
3500 case 17962: // Conflagrate
3501 case 32593: // Earth Shield aura
3502 case 32594: // Earth Shield aura
3503 case 49283: // Earth Shield aura
3504 case 49284: // Earth Shield aura
3505 case 50526: // Wandering Plague
3506 case 53353: // Chimera Shot - Serpent trigger
3507 case 52752: // Ancestral Awakening Heal
3509 break;
3510 case 65280: // Ulduar, Hodir, Singed
3511 case 28969: // Naxxramas, Crypt Guard, Acid Spit (10 normal)
3512 case 56098: // Naxxramas, Crypt Guard, Acid Spit (25 normal)
3513 case 27891: // Naxxramas, Sludge Belcher, Acidic Sludge (10 normal)
3514 case 54331: // Naxxramas, Sludge Belcher, Acidic Sludge (25 normal)
3515 case 29325: // Naxxramas, Stoneskin Gargoyle, Acid Volley (10 normal)
3516 case 54714: // Naxxramas, Stoneskin Gargoyle, Acid Volley (25 normal)
3517 case 65775: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (10 normal)
3518 case 67861: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (25 normal)
3519 case 67862: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (10 heroic)
3520 case 67863: // Anub'arak, Swarm Scarab, Acid-Drenched Mandibles (25 heroic)
3521 case 55604: // Naxxramas, Unrelenting Trainee, Death Plague (10 normal)
3522 case 55645: // Naxxramas, Unrelenting Trainee, Death Plague (25 normal)
3523 case 67721: // Anub'arak, Nerubian Burrower, Expose Weakness (normal)
3524 case 67847: // Anub'arak, Nerubian Burrower, Expose Weakness (heroic)
3525 case 64638: // Ulduar, Winter Jormungar, Acidic Bite
3526 case 71157: // Icecrown Citadel, Plagued Zombie, Infected Wound
3527 case 72963: // Icecrown Citadel, Rot Worm, Flesh Rot (10 normal)
3528 case 72964: // Icecrown Citadel, Rot Worm, Flesh Rot (25 normal)
3529 case 72965: // Icecrown Citadel, Rot Worm, Flesh Rot (10 heroic)
3530 case 72966: // Icecrown Citadel, Rot Worm, Flesh Rot (25 heroic)
3531 case 72465: // Icecrown Citadel, Sindragosa, Respite for a Tormented Soul (weekly quest)
3532 case 45271: // Sunwell, Eredar Twins encounter, Dark Strike
3533 case 45347: // Sunwell, Eredar Twins encounter, Dark Touched
3534 case 45348: // Sunwell, Eredar Twins encounter, Flame Touched
3535 case 35859: // The Eye, Nether Vapor
3536 case 40520: // Black Temple, Shade Soul Channel
3537 case 40327: // Black Temple, Atrophy
3538 case 38449: // Serpentshrine Cavern, Blessing of the Tides
3539 case 38044: // Serpentshrine Cavern, Surge
3540 case 74507: // Ruby Sanctum, Siphoned Might
3541 case 49381: // Drak'tharon Keep, Consume
3542 case 59805: // Drak'tharon Keep, Consume
3543 case 55093: // Gundrak, Grip of Slad'ran
3544 case 30659: // Hellfire Ramparts, Fel Infusion
3545 case 54314: // Azjol'Nerub Drain Power
3546 case 59354: // Azjol'Nerub Drain Power
3547 case 34655: // Snake Trap, Deadly Poison
3548 case 11971: // Sunder Armor
3549 case 58567: // Player Sunder Armor
3550 case 12579: // Player Winter's Chill
3551 case 29306: // Naxxramas(Gluth's Zombies): Infected Wound
3552 case 61920: // Ulduar(Spellbreaker): Supercharge
3553 case 63978: // Ulduar(Rubble): Stone Nova
3554 case 15502: // Sunder Armor
3556 break;
3557 case 43138: // North Fleet Reservist Kill Credit
3559 break;
3560 case 6197: // Eagle Eye
3562 break;
3563 case 50315: // Disco Ball
3565 break;
3566 case 14183: // Premeditation
3568 break;
3569
3570 // Xinef: NOT CUSTOM, cant add in DBC CORRECTION because i need to swap effects, too much work to do there
3571 // Envenom
3572 case 32645:
3573 case 32684:
3574 case 57992:
3575 case 57993:
3576 {
3577 SpellEffectInfo info = spellInfo->Effects[EFFECT_0];
3578 spellInfo->Effects[EFFECT_0] = spellInfo->Effects[EFFECT_2];
3579 spellInfo->Effects[EFFECT_2] = info;
3580 break;
3581 }
3582
3583 // Xinef: Cooldown overwrites
3584 // Burst of Speed
3585 case 57493:
3586 spellInfo->RecoveryTime = 60000;
3587 spellInfo->_requireCooldownInfo = true;
3588 break;
3589 // Strafe Jotunheim Building
3590 case 7769:
3591 spellInfo->RecoveryTime = 1500;
3592 spellInfo->_requireCooldownInfo = true;
3593 break;
3594 case 44535: // Spirit Heal, abilities also have no cost
3595 spellInfo->Effects[EFFECT_0].MiscValue = 127;
3596 break;
3597 case 45537: // Cosmetic - Lightning Beam Channel
3599 break;
3600 }
3601
3602 if (spellInfo->Speed > 0.0f)
3603 {
3604 if (SpellVisualEntry const* spellVisual = sSpellVisualStore.LookupEntry(spellInfo->SpellVisual[0]))
3605 {
3606 if (spellVisual->HasMissile)
3607 {
3608 if (spellVisual->MissileModel == -4 || spellVisual->MissileModel == -5)
3609 {
3611 }
3612 }
3613 }
3614 }
3615
3616 spellInfo->_InitializeExplicitTargetMask();
3617
3618 if (HasSpellCooldownOverride(spellInfo->Id))
3619 {
3620 SpellCooldownOverride spellOverride = GetSpellCooldownOverride(spellInfo->Id);
3621
3622 if (spellInfo->RecoveryTime != spellOverride.RecoveryTime)
3623 {
3624 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3625 }
3626
3627 if (spellInfo->CategoryRecoveryTime != spellOverride.CategoryRecoveryTime)
3628 {
3629 spellInfo->CategoryRecoveryTime = spellOverride.CategoryRecoveryTime;
3630 }
3631
3632 if (spellInfo->StartRecoveryTime != spellOverride.StartRecoveryTime)
3633 {
3634 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3635 }
3636
3637 if (spellInfo->StartRecoveryCategory != spellOverride.StartRecoveryCategory)
3638 {
3639 spellInfo->RecoveryTime = spellOverride.RecoveryTime;
3640 }
3641 }
3642
3643 sScriptMgr->OnLoadSpellCustomAttr(spellInfo);
3644 }
3645
3646 // Xinef: addition for binary spells, ommit spells triggering other spells
3647 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
3648 {
3649 spellInfo = mSpellInfoMap[i];
3650 if (!spellInfo)
3651 continue;
3652
3653 if (!(spellInfo->AttributesCu & SPELL_ATTR0_CU_BINARY_SPELL))
3654 continue;
3655
3656 bool allNonBinary = true;
3657 bool overrideAttr = false;
3658 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
3659 {
3660 if (spellInfo->Effects[j].ApplyAuraName && spellInfo->Effects[j].TriggerSpell)
3661 {
3662 switch (spellInfo->Effects[j].ApplyAuraName)
3663 {
3667 if (SpellInfo const* triggerSpell = GetSpellInfo(spellInfo->Effects[j].TriggerSpell))
3668 {
3669 overrideAttr = true;
3670 if (triggerSpell->AttributesCu & SPELL_ATTR0_CU_BINARY_SPELL)
3671 allNonBinary = false;
3672 }
3673 break;
3674 default:
3675 break;
3676 }
3677 }
3678 }
3679
3680 if (overrideAttr && allNonBinary)
3681 spellInfo->AttributesCu &= ~SPELL_ATTR0_CU_BINARY_SPELL;
3682 }
3683
3684 LOG_INFO("server.loading", ">> Loaded SpellInfo Custom Attributes in {} ms", GetMSTimeDiffToNow(oldMSTime));
3685 LOG_INFO("server.loading", " ");
3686}
@ 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:733
@ 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:3773
@ SPELLFAMILY_DRUID
Definition SharedDefines.h:3775
SpellAttr0
Definition SharedDefines.h:369
@ SPELL_ATTR0_DO_NOT_DISPLAY
Definition SharedDefines.h:377
@ SKILL_ENCHANTING
Definition SharedDefines.h:3171
@ 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:191
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition SpellInfo.h:192
@ SPELL_ATTR0_CU_ALLOW_INFLIGHT_TARGET
Definition SpellInfo.h:194
@ SPELL_ATTR0_CU_ENCHANT_PROC
Definition SpellInfo.h:176
@ SPELL_ATTR0_CU_NO_POSITIVE_TAKEN_BONUS
Definition SpellInfo.h:197
@ SPELL_ATTR0_CU_FORCE_SEND_CATEGORY_COOLDOWNS
Definition SpellInfo.h:204
@ SPELL_ATTR0_CU_DIRECT_DAMAGE
Definition SpellInfo.h:184
@ SPELL_ATTR0_CU_POSITIVE
Definition SpellInfo.h:211
@ SPELL_ATTR0_CU_FORCE_AURA_SAVING
Definition SpellInfo.h:205
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition SpellInfo.h:183
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition SpellInfo.h:182
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition SpellInfo.h:193
@ SPELL_ATTR0_CU_CONE_BACK
Definition SpellInfo.h:177
@ SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED
Definition SpellInfo.h:200
@ SPELL_ATTR0_CU_NEGATIVE_EFF2
Definition SpellInfo.h:190
@ SPELL_ATTR0_CU_AURA_CC
Definition SpellInfo.h:181
@ SPELL_ATTR0_CU_NEGATIVE_EFF1
Definition SpellInfo.h:189
@ SPELL_ATTR0_CU_CHARGE
Definition SpellInfo.h:185
@ SPELL_ATTR0_CU_NEGATIVE
Definition SpellInfo.h:210
@ SPELL_ATTR0_CU_NEEDS_AMMO_DATA
Definition SpellInfo.h:195
@ SPELL_ATTR0_CU_POSITIVE_EFF0
Definition SpellInfo.h:201
@ SPELL_ATTR0_CU_NEGATIVE_EFF0
Definition SpellInfo.h:188
@ SPELL_ATTR0_CU_BINARY_SPELL
Definition SpellInfo.h:196
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition SpellInfo.h:179
@ SPELL_ATTR0_CU_SCHOOLMASK_NORMAL_WITH_MAGIC
Definition SpellInfo.h:199
@ SPELL_ATTR0_CU_IGNORE_EVADE
Definition SpellInfo.h:187
@ SPELL_ATTR0_CU_PICKPOCKET
Definition SpellInfo.h:186
@ SPELL_ATTR0_CU_CONE_LINE
Definition SpellInfo.h:178
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition SpellInfo.h:180
bool IsPartOfSkillLine(uint32 skillId, uint32 spellId)
Definition SpellMgr.cpp:46
uint32 GetCategory() const
Definition SpellInfo.cpp:871
uint32 AttributesCu
Definition SpellInfo.h:332
bool _requireCooldownInfo
Definition SpellInfo.h:403
uint32 SchoolMask
Definition SpellInfo.h:392
std::array< uint32, 2 > SpellVisual
Definition SpellInfo.h:379
uint32 CategoryRecoveryTime
Definition SpellInfo.h:349
bool _IsPositiveEffect(uint8 effIndex, bool deep) const
Definition SpellInfo.cpp:2519
uint32 StartRecoveryTime
Definition SpellInfo.h:351
void _InitializeExplicitTargetMask()
Definition SpellInfo.cpp:2491
uint32 StartRecoveryCategory
Definition SpellInfo.h:350
uint32 AuraInterruptFlags
Definition SpellInfo.h:353
SpellCooldownOverride GetSpellCooldownOverride(uint32 spellId) const
Definition SpellMgr.cpp:2925
SpellInfo * _GetSpellInfo(uint32 spellId)
Definition SpellMgr.h:749
bool HasSpellCooldownOverride(uint32 spellId) const
Definition SpellMgr.cpp:2920
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.

◆ LoadSpellInfoStore()

void SpellMgr::LoadSpellInfoStore ( )
2861{
2862 uint32 oldMSTime = getMSTime();
2863
2865 mSpellInfoMap.resize(sSpellStore.GetNumRows(), nullptr);
2866
2867 for (SpellEntry const* spellEntry : sSpellStore)
2868 mSpellInfoMap[spellEntry->Id] = new SpellInfo(spellEntry);
2869
2870 for (uint32 spellIndex = 0; spellIndex < GetSpellInfoStoreSize(); ++spellIndex)
2871 {
2872 if (!mSpellInfoMap[spellIndex])
2873 continue;
2874
2875 for (SpellEffectInfo const& spellEffectInfo : mSpellInfoMap[spellIndex]->GetEffects())
2876 {
2877 //ASSERT(effect.EffectIndex < MAX_SPELL_EFFECTS, "MAX_SPELL_EFFECTS must be at least {}", effect.EffectIndex + 1);
2878 ASSERT(spellEffectInfo.Effect < TOTAL_SPELL_EFFECTS, "TOTAL_SPELL_EFFECTS must be at least {}", spellEffectInfo.Effect + 1);
2879 ASSERT(spellEffectInfo.ApplyAuraName < TOTAL_AURAS, "TOTAL_AURAS must be at least {}", spellEffectInfo.ApplyAuraName + 1);
2880 ASSERT(spellEffectInfo.TargetA.GetTarget() < TOTAL_SPELL_TARGETS, "TOTAL_SPELL_TARGETS must be at least {}", spellEffectInfo.TargetA.GetTarget() + 1);
2881 ASSERT(spellEffectInfo.TargetB.GetTarget() < TOTAL_SPELL_TARGETS, "TOTAL_SPELL_TARGETS must be at least {}", spellEffectInfo.TargetB.GetTarget() + 1);
2882 }
2883 }
2884
2885 LOG_INFO("server.loading", ">> Loaded Spell Custom Attributes in {} ms", GetMSTimeDiffToNow(oldMSTime));
2886 LOG_INFO("server.loading", " ");
2887}
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
@ TOTAL_SPELL_EFFECTS
Definition SharedDefines.h:931
@ TOTAL_SPELL_TARGETS
Definition SharedDefines.h:1502
@ TOTAL_AURAS
Definition SpellAuraDefines.h:380
Definition DBCStructure.h:1642

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

◆ LoadSpellLearnSkills()

void SpellMgr::LoadSpellLearnSkills ( )
1382{
1383 uint32 oldMSTime = getMSTime();
1384
1385 mSpellLearnSkills.clear(); // need for reload case
1386
1387 // search auto-learned skills and add its to map also for use in unlearn spells/talents
1388 uint32 dbc_count = 0;
1389 for (uint32 spell = 0; spell < GetSpellInfoStoreSize(); ++spell)
1390 {
1391 SpellInfo const* entry = GetSpellInfo(spell);
1392
1393 if (!entry)
1394 continue;
1395
1396 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1397 {
1398 SpellLearnSkillNode dbc_node;
1399 switch (entry->Effects[i].Effect)
1400 {
1401 case SPELL_EFFECT_SKILL:
1402 dbc_node.skill = entry->Effects[i].MiscValue;
1403 dbc_node.step = entry->Effects[i].CalcValue();
1404 if (dbc_node.skill != SKILL_RIDING)
1405 {
1406 dbc_node.value = 1;
1407 }
1408 else
1409 {
1410 dbc_node.value = dbc_node.step * 75;
1411 }
1412 dbc_node.maxvalue = dbc_node.step * 75;
1413 break;
1415 dbc_node.skill = SKILL_DUAL_WIELD;
1416 dbc_node.step = 1;
1417 dbc_node.value = 1;
1418 dbc_node.maxvalue = 1;
1419 break;
1420 default:
1421 continue;
1422 }
1423
1424 mSpellLearnSkills[spell] = dbc_node;
1425 ++dbc_count;
1426 break;
1427 }
1428 }
1429
1430 LOG_INFO("server.loading", ">> Loaded {} Spell Learn Skills From DBC in {} ms", dbc_count, GetMSTimeDiffToNow(oldMSTime));
1431 LOG_INFO("server.loading", " ");
1432}
@ SPELL_EFFECT_SKILL
Definition SharedDefines.h:884
@ SPELL_EFFECT_DUAL_WIELD
Definition SharedDefines.h:806
@ SKILL_DUAL_WIELD
Definition SharedDefines.h:3105
@ SKILL_RIDING
Definition SharedDefines.h:3208
Definition SpellMgr.h:561
uint16 value
Definition SpellMgr.h:564
uint16 step
Definition SpellMgr.h:563
uint16 maxvalue
Definition SpellMgr.h:565
uint16 skill
Definition SpellMgr.h:562

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 ( )
2423{
2424 uint32 oldMSTime = getMSTime();
2425
2426 mSpellLinkedMap.clear(); // need for reload case
2427
2428 // 0 1 2
2429 QueryResult result = WorldDatabase.Query("SELECT spell_trigger, spell_effect, type FROM spell_linked_spell");
2430 if (!result)
2431 {
2432 LOG_WARN("server.loading", ">> Loaded 0 linked spells. DB table `spell_linked_spell` is empty.");
2433 LOG_INFO("server.loading", " ");
2434 return;
2435 }
2436
2437 uint32 count = 0;
2438 do
2439 {
2440 Field* fields = result->Fetch();
2441
2442 int32 trigger = fields[0].Get<int32>();
2443 int32 effect = fields[1].Get<int32>();
2444 int32 type = fields[2].Get<uint8>();
2445
2446 SpellInfo const* spellInfo = GetSpellInfo(std::abs(trigger));
2447 if (!spellInfo)
2448 {
2449 LOG_ERROR("sql.sql", "Spell {} listed in `spell_linked_spell` does not exist", std::abs(trigger));
2450 continue;
2451 }
2452 spellInfo = GetSpellInfo(std::abs(effect));
2453 if (!spellInfo)
2454 {
2455 LOG_ERROR("sql.sql", "Spell {} listed in `spell_linked_spell` does not exist", std::abs(effect));
2456 continue;
2457 }
2458
2459 if (type) //we will find a better way when more types are needed
2460 {
2461 if (trigger > 0)
2462 trigger += SPELL_LINKED_MAX_SPELLS * type;
2463 else
2464 trigger -= SPELL_LINKED_MAX_SPELLS * type;
2465 }
2466 mSpellLinkedMap[trigger].push_back(effect);
2467
2468 ++count;
2469 } while (result->NextRow());
2470
2471 LOG_INFO("server.loading", ">> Loaded {} Linked Spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2472 LOG_INFO("server.loading", " ");
2473}
#define SPELL_LINKED_MAX_SPELLS
Definition SpellMgr.h:92

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

◆ LoadSpellMixology()

void SpellMgr::LoadSpellMixology ( )
2216{
2217 uint32 oldMSTime = getMSTime();
2218
2219 mSpellMixologyMap.clear(); // need for reload case
2220
2221 // 0 1
2222 QueryResult result = WorldDatabase.Query("SELECT entry, pctMod FROM spell_mixology");
2223 if (!result)
2224 {
2225 LOG_WARN("server.loading", ">> Loaded 0 mixology bonuses. DB table `spell_mixology` is empty.");
2226 LOG_INFO("server.loading", " ");
2227 return;
2228 }
2229
2230 uint32 count = 0;
2231 do
2232 {
2233 Field* fields = result->Fetch();
2234
2235 uint32 entry = fields[0].Get<uint32>();
2236
2237 if (!GetSpellInfo(entry))
2238 {
2239 LOG_ERROR("sql.sql", "Spell {} listed in `spell_mixology` does not exist", entry);
2240 continue;
2241 }
2242
2243 mSpellMixologyMap[entry] = fields[1].Get<float>();
2244 ++count;
2245 } while (result->NextRow());
2246
2247 LOG_INFO("server.loading", ">> Loaded {} Mixology Bonuses in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2248 LOG_INFO("server.loading", " ");
2249}

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

◆ LoadSpellPetAuras()

void SpellMgr::LoadSpellPetAuras ( )
2274{
2275 uint32 oldMSTime = getMSTime();
2276
2277 mSpellPetAuraMap.clear(); // need for reload case
2278
2279 // 0 1 2 3
2280 QueryResult result = WorldDatabase.Query("SELECT spell, effectId, pet, aura FROM spell_pet_auras");
2281 if (!result)
2282 {
2283 LOG_WARN("server.loading", ">> Loaded 0 spell pet auras. DB table `spell_pet_auras` is empty.");
2284 LOG_INFO("server.loading", " ");
2285 return;
2286 }
2287
2288 uint32 count = 0;
2289 do
2290 {
2291 Field* fields = result->Fetch();
2292
2293 uint32 spell = fields[0].Get<uint32>();
2294 uint8 eff = fields[1].Get<uint8>();
2295 uint32 pet = fields[2].Get<uint32>();
2296 uint32 aura = fields[3].Get<uint32>();
2297
2298 SpellPetAuraMap::iterator itr = mSpellPetAuraMap.find((spell << 8) + eff);
2299 if (itr != mSpellPetAuraMap.end())
2300 itr->second.AddAura(pet, aura);
2301 else
2302 {
2303 SpellInfo const* spellInfo = GetSpellInfo(spell);
2304 if (!spellInfo)
2305 {
2306 LOG_ERROR("sql.sql", "Spell {} listed in `spell_pet_auras` does not exist", spell);
2307 continue;
2308 }
2309 if (spellInfo->Effects[eff].Effect != SPELL_EFFECT_DUMMY &&
2310 (spellInfo->Effects[eff].Effect != SPELL_EFFECT_APPLY_AURA ||
2311 spellInfo->Effects[eff].ApplyAuraName != SPELL_AURA_DUMMY))
2312 {
2313 LOG_ERROR("spells", "Spell {} listed in `spell_pet_auras` does not have dummy aura or dummy effect", spell);
2314 continue;
2315 }
2316
2317 SpellInfo const* spellInfo2 = GetSpellInfo(aura);
2318 if (!spellInfo2)
2319 {
2320 LOG_ERROR("sql.sql", "Aura {} listed in `spell_pet_auras` does not exist", aura);
2321 continue;
2322 }
2323
2324 PetAura pa(pet, aura, spellInfo->Effects[eff].TargetA.GetTarget() == TARGET_UNIT_PET, spellInfo->Effects[eff].CalcValue());
2325 mSpellPetAuraMap[(spell << 8) + eff] = pa;
2326 }
2327
2328 ++count;
2329 } while (result->NextRow());
2330
2331 LOG_INFO("server.loading", ">> Loaded {} Spell Pet Auras in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2332 LOG_INFO("server.loading", " ");
2333}
Definition SpellMgr.h:457

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 ( )
1846{
1847 uint32 oldMSTime = getMSTime();
1848
1849 mSpellProcMap.clear(); // need for reload case
1850
1851 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1852 QueryResult result = WorldDatabase.Query("SELECT SpellId, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, ProcFlags, SpellTypeMask, SpellPhaseMask, HitMask, AttributesMask, DisableEffectsMask, ProcsPerMinute, Chance, Cooldown, Charges FROM spell_proc");
1853 if (!result)
1854 {
1855 LOG_WARN("server.loading", ">> Loaded 0 Spell Proc Conditions And Data. DB table `spell_proc` Is Empty.");
1856 LOG_INFO("server.loading", " ");
1857 return;
1858 }
1859
1860 uint32 count = 0;
1861 do
1862 {
1863 Field* fields = result->Fetch();
1864
1865 int32 spellId = fields[0].Get<int32>();
1866
1867 bool allRanks = false;
1868 if (spellId < 0)
1869 {
1870 allRanks = true;
1871 spellId = -spellId;
1872 }
1873
1874 SpellInfo const* spellInfo = GetSpellInfo(spellId);
1875 if (!spellInfo)
1876 {
1877 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` does not exist", spellId);
1878 continue;
1879 }
1880
1881 if (allRanks)
1882 {
1883 if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId))
1884 {
1885 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` is not first rank of spell.", fields[0].Get<int32>());
1886 continue;
1887 }
1888 }
1889
1890 SpellProcEntry baseProcEntry;
1891
1892 baseProcEntry.SchoolMask = fields[1].Get<int8>();
1893 baseProcEntry.SpellFamilyName = fields[2].Get<uint16>();
1894 baseProcEntry.SpellFamilyMask[0] = fields[3].Get<uint32>();
1895 baseProcEntry.SpellFamilyMask[1] = fields[4].Get<uint32>();
1896 baseProcEntry.SpellFamilyMask[2] = fields[5].Get<uint32>();
1897 baseProcEntry.ProcFlags = fields[6].Get<uint32>();
1898 baseProcEntry.SpellTypeMask = fields[7].Get<uint32>();
1899 baseProcEntry.SpellPhaseMask = fields[8].Get<uint32>();
1900 baseProcEntry.HitMask = fields[9].Get<uint32>();
1901 baseProcEntry.AttributesMask = fields[10].Get<uint32>();
1902 baseProcEntry.DisableEffectsMask = fields[11].Get<uint32>();
1903 baseProcEntry.ProcsPerMinute = fields[12].Get<float>();
1904 baseProcEntry.Chance = fields[13].Get<float>();
1905 baseProcEntry.Cooldown = Milliseconds(fields[14].Get<uint32>());
1906 baseProcEntry.Charges = fields[15].Get<uint32>();
1907
1908 while (spellInfo)
1909 {
1910 if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end())
1911 {
1912 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` has duplicate entry in the table", spellId);
1913 break;
1914 }
1915 SpellProcEntry procEntry = SpellProcEntry(baseProcEntry);
1916
1917 // take defaults from dbcs
1918 if (!procEntry.ProcFlags)
1919 procEntry.ProcFlags = spellInfo->ProcFlags;
1920 if (!procEntry.Charges)
1921 procEntry.Charges = spellInfo->ProcCharges;
1922 if (!procEntry.Chance && !procEntry.ProcsPerMinute)
1923 procEntry.Chance = float(spellInfo->ProcChance);
1924
1925 // validate data
1926 if (procEntry.SchoolMask & ~SPELL_SCHOOL_MASK_ALL)
1927 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SchoolMask` set: {}", spellId, procEntry.SchoolMask);
1928 if (procEntry.SpellFamilyName && (procEntry.SpellFamilyName < 3 || procEntry.SpellFamilyName > 17 || procEntry.SpellFamilyName == 14 || procEntry.SpellFamilyName == 16))
1929 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellFamilyName` set: {}", spellId, procEntry.SpellFamilyName);
1930 if (procEntry.Chance < 0)
1931 {
1932 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `Chance` field", spellId);
1933 procEntry.Chance = 0;
1934 }
1935 if (procEntry.ProcsPerMinute < 0)
1936 {
1937 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `ProcsPerMinute` field", spellId);
1938 procEntry.ProcsPerMinute = 0;
1939 }
1940 if (procEntry.Charges > 99)
1941 {
1942 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has too big value in `Charges` field", spellId);
1943 procEntry.Charges = 99;
1944 }
1945 if (!procEntry.ProcFlags)
1946 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} doesn't have `ProcFlags` value defined, proc will not be triggered", spellId);
1947 if (procEntry.SpellTypeMask & ~PROC_SPELL_TYPE_MASK_ALL)
1948 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellTypeMask` set: {}", spellId, procEntry.SpellTypeMask);
1949 if (procEntry.SpellTypeMask && !(procEntry.ProcFlags & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK)))
1950 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);
1951 if (!procEntry.SpellPhaseMask && procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK)
1952 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);
1954 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellPhaseMask` set: {}", spellId, procEntry.SpellPhaseMask);
1955 if (procEntry.SpellPhaseMask && !(procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK))
1956 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);
1957 if (procEntry.HitMask & ~PROC_HIT_MASK_ALL)
1958 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `HitMask` set: {}", spellId, procEntry.HitMask);
1959 // HitMask is valid for: TAKEN procs, or DONE procs at any phase (CAST phase has pre-calculated crit for travel-time spells)
1960 if (procEntry.HitMask && !(procEntry.ProcFlags & TAKEN_HIT_PROC_FLAG_MASK || procEntry.ProcFlags & DONE_HIT_PROC_FLAG_MASK))
1961 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);
1962 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1963 if ((procEntry.DisableEffectsMask & (1u << i)) && !spellInfo->Effects[i].IsAura())
1964 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));
1965 if (procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD)
1966 {
1967 bool found = false;
1968 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1969 {
1970 if (!spellInfo->Effects[i].IsAura())
1971 continue;
1972
1973 if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_ADD_PCT_MODIFIER || spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_ADD_FLAT_MODIFIER)
1974 {
1975 found = true;
1976 break;
1977 }
1978 }
1979
1980 if (!found)
1981 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);
1982 }
1983
1984 mSpellProcMap[spellInfo->Id] = procEntry;
1985
1986 if (allRanks)
1987 spellInfo = spellInfo->GetNextRankSpell();
1988 else
1989 break;
1990 }
1991 ++count;
1992 } while (result->NextRow());
1993
1994 LOG_INFO("server.loading", ">> Loaded {} spell proc conditions and data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1995 LOG_INFO("server.loading", " ");
1996
1997 // Generate default procs for spells with proc flags but no explicit spell_proc entry
1998 // This ensures backward compatibility and covers spells that rely on DBC data
1999 LOG_INFO("server.loading", "Generating spell proc data from SpellMap...");
2000 count = 0;
2001 oldMSTime = getMSTime();
2002
2003 for (SpellInfo const* spellInfo : mSpellInfoMap)
2004 {
2005 if (!spellInfo)
2006 continue;
2007
2008 // Skip if already has explicit entry
2009 if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end())
2010 continue;
2011
2012 // Check if spell has any trigger aura effects
2013 bool found = false, addTriggerFlag = false;
2014 uint32 procSpellTypeMask = PROC_SPELL_TYPE_NONE;
2015 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2016 {
2017 if (!spellInfo->Effects[i].IsEffect())
2018 continue;
2019
2020 uint32 auraName = spellInfo->Effects[i].ApplyAuraName;
2021 if (!auraName)
2022 continue;
2023
2024 if (!isTriggerAura[auraName])
2025 continue;
2026
2027 found = true;
2028 procSpellTypeMask |= spellTypeMask[auraName];
2029
2030 if (!addTriggerFlag && isAlwaysTriggeredAura[auraName])
2031 addTriggerFlag = true;
2032
2033 // Many proc auras with taken procFlag mask don't have
2034 // attribute "can proc with triggered" — they should
2035 // proc nevertheless (e.g. mage armor spells with
2036 // judgement)
2037 if (!addTriggerFlag
2038 && (spellInfo->ProcFlags & TAKEN_HIT_PROC_FLAG_MASK))
2039 {
2040 switch (auraName)
2041 {
2044 addTriggerFlag = true;
2045 break;
2046 default:
2047 break;
2048 }
2049 }
2050 }
2051
2052 if (!found)
2053 continue;
2054
2055 // Skip if no proc flags in DBC
2056 if (!spellInfo->ProcFlags)
2057 continue;
2058
2059 // Generate default proc entry from DBC data
2060 SpellProcEntry procEntry;
2061 procEntry.SchoolMask = 0;
2062 procEntry.SpellFamilyMask[0] = 0;
2063 procEntry.SpellFamilyMask[1] = 0;
2064 procEntry.SpellFamilyMask[2] = 0;
2065 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2066 if (spellInfo->Effects[i].IsEffect() && isTriggerAura[spellInfo->Effects[i].ApplyAuraName])
2067 procEntry.SpellFamilyMask |= spellInfo->Effects[i].SpellClassMask;
2068
2069 if (procEntry.SpellFamilyMask)
2070 procEntry.SpellFamilyName = spellInfo->SpellFamilyName;
2071 else
2072 procEntry.SpellFamilyName = 0;
2073
2074 procEntry.ProcFlags = spellInfo->ProcFlags;
2075 procEntry.SpellTypeMask = procSpellTypeMask;
2077 procEntry.HitMask = PROC_HIT_NONE; // uses default proc @see SpellMgr::CanSpellTriggerProcOnEvent
2078
2079 // Reflect auras should only proc off reflects
2080 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2081 {
2082 if (spellInfo->Effects[i].IsAura(SPELL_AURA_REFLECT_SPELLS) || spellInfo->Effects[i].IsAura(SPELL_AURA_REFLECT_SPELLS_SCHOOL))
2083 {
2084 procEntry.HitMask = PROC_HIT_REFLECT;
2085 break;
2086 }
2087 }
2088
2089 procEntry.AttributesMask = 0;
2090 if (spellInfo->ProcFlags & PROC_FLAG_KILL)
2092 if (addTriggerFlag)
2094
2095 // Modifier auras with charges should require spellmod validation
2096 if (spellInfo->ProcCharges)
2097 {
2098 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2099 {
2100 if (spellInfo->Effects[i].IsAura(SPELL_AURA_ADD_FLAT_MODIFIER) ||
2101 spellInfo->Effects[i].IsAura(SPELL_AURA_ADD_PCT_MODIFIER))
2102 {
2104 break;
2105 }
2106 }
2107 }
2108
2109 // Calculate DisableEffectsMask for effects that shouldn't trigger procs
2110 uint32 nonProcMask = 0;
2111 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2112 {
2113 if (!spellInfo->Effects[i].IsAura())
2114 continue;
2115 if (!isTriggerAura[spellInfo->Effects[i].ApplyAuraName])
2116 nonProcMask |= 1u << i;
2117 }
2118 procEntry.DisableEffectsMask = nonProcMask;
2119
2120 procEntry.ProcsPerMinute = 0;
2121 procEntry.Chance = static_cast<float>(spellInfo->ProcChance);
2122 procEntry.Cooldown = Milliseconds::zero();
2123 procEntry.Charges = spellInfo->ProcCharges;
2124
2125 mSpellProcMap[spellInfo->Id] = procEntry;
2126 ++count;
2127 }
2128
2129 LOG_INFO("server.loading", ">> Generated spell proc data for {} spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2130 LOG_INFO("server.loading", " ");
2131}
std::uint16_t uint16
Definition Define.h:108
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:27
@ SPELL_SCHOOL_MASK_ALL
Definition SharedDefines.h:303
@ SPELL_AURA_REFLECT_SPELLS
Definition SpellAuraDefines.h:91
@ 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:1776
static uint32 spellTypeMask[TOTAL_AURAS]
Definition SpellMgr.cpp:1777
static bool isTriggerAura[TOTAL_AURAS]
Definition SpellMgr.cpp:1775
@ PROC_HIT_NONE
Definition SpellMgr.h:253
@ PROC_HIT_MASK_ALL
Definition SpellMgr.h:268
@ PROC_HIT_REFLECT
Definition SpellMgr.h:265
@ PROC_ATTR_TRIGGERED_CAN_PROC
Definition SpellMgr.h:274
@ PROC_ATTR_REQ_SPELLMOD
Definition SpellMgr.h:276
@ PROC_SPELL_TYPE_NONE
Definition SpellMgr.h:235
@ PROC_SPELL_TYPE_MASK_ALL
Definition SpellMgr.h:239
@ PROC_SPELL_PHASE_HIT
Definition SpellMgr.h:246
@ PROC_SPELL_PHASE_MASK_ALL
Definition SpellMgr.h:248
SpellInfo const * GetFirstRankSpell() const
Definition SpellInfo.cpp:2396
uint32 ProcCharges
Definition SpellInfo.h:357
uint32 ProcFlags
Definition SpellInfo.h:355
uint32 ProcChance
Definition SpellInfo.h:356
Definition SpellMgr.h:283
uint32 SpellFamilyName
Definition SpellMgr.h:285
float ProcsPerMinute
Definition SpellMgr.h:293
Milliseconds Cooldown
Definition SpellMgr.h:295
uint32 Charges
Definition SpellMgr.h:296
uint32 AttributesMask
Definition SpellMgr.h:291
flag96 SpellFamilyMask
Definition SpellMgr.h:286
uint32 HitMask
Definition SpellMgr.h:290
uint32 SpellTypeMask
Definition SpellMgr.h:288
uint32 ProcFlags
Definition SpellMgr.h:287
uint32 SpellPhaseMask
Definition SpellMgr.h:289
uint32 SchoolMask
Definition SpellMgr.h:284
uint32 DisableEffectsMask
Definition SpellMgr.h:292
float Chance
Definition SpellMgr.h:294

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_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 ( )
1206{
1207 // cleanup data and load spell ranks for talents from dbc
1209
1210 uint32 oldMSTime = getMSTime();
1211
1212 // 0 1 2
1213 QueryResult result = WorldDatabase.Query("SELECT first_spell_id, spell_id, `rank` from spell_ranks ORDER BY first_spell_id, `rank`");
1214
1215 if (!result)
1216 {
1217 LOG_WARN("server.loading", ">> Loaded 0 spell rank records. DB table `spell_ranks` is empty.");
1218 LOG_INFO("server.loading", " ");
1219 return;
1220 }
1221
1222 uint32 count = 0;
1223 bool finished = false;
1224
1225 do
1226 {
1227 // spellid, rank
1228 std::list < std::pair < int32, int32 > > rankChain;
1229 int32 currentSpell = -1;
1230 int32 lastSpell = -1;
1231
1232 // fill one chain
1233 while (currentSpell == lastSpell && !finished)
1234 {
1235 Field* fields = result->Fetch();
1236
1237 currentSpell = fields[0].Get<uint32>();
1238 if (lastSpell == -1)
1239 lastSpell = currentSpell;
1240 uint32 spell_id = fields[1].Get<uint32>();
1241 uint32 rank = fields[2].Get<uint8>();
1242
1243 // don't drop the row if we're moving to the next rank
1244 if (currentSpell == lastSpell)
1245 {
1246 rankChain.push_back(std::make_pair(spell_id, rank));
1247 if (!result->NextRow())
1248 finished = true;
1249 }
1250 else
1251 break;
1252 }
1253 // check if chain is made with valid first spell
1254 SpellInfo const* first = GetSpellInfo(lastSpell);
1255 if (!first)
1256 {
1257 LOG_ERROR("sql.sql", "Spell rank identifier(first_spell_id) {} listed in `spell_ranks` does not exist!", lastSpell);
1258 continue;
1259 }
1260 // check if chain is long enough
1261 if (rankChain.size() < 2)
1262 {
1263 LOG_ERROR("sql.sql", "There is only 1 spell rank for identifier(first_spell_id) {} in `spell_ranks`, entry is not needed!", lastSpell);
1264 continue;
1265 }
1266 int32 curRank = 0;
1267 bool valid = true;
1268 // check spells in chain
1269 for (std::list<std::pair<int32, int32> >::iterator itr = rankChain.begin(); itr != rankChain.end(); ++itr)
1270 {
1271 SpellInfo const* spell = GetSpellInfo(itr->first);
1272 if (!spell)
1273 {
1274 LOG_ERROR("sql.sql", "Spell {} (rank {}) listed in `spell_ranks` for chain {} does not exist!", itr->first, itr->second, lastSpell);
1275 valid = false;
1276 break;
1277 }
1278 ++curRank;
1279 if (itr->second != curRank)
1280 {
1281 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);
1282 valid = false;
1283 break;
1284 }
1285 }
1286 if (!valid)
1287 continue;
1288 int32 prevRank = 0;
1289 // insert the chain
1290 std::list<std::pair<int32, int32> >::iterator itr = rankChain.begin();
1291 do
1292 {
1293 ++count;
1294 int32 addedSpell = itr->first;
1295 mSpellChains[addedSpell].first = GetSpellInfo(lastSpell);
1296 mSpellChains[addedSpell].last = GetSpellInfo(rankChain.back().first);
1297 mSpellChains[addedSpell].rank = itr->second;
1298 mSpellChains[addedSpell].prev = GetSpellInfo(prevRank);
1299 mSpellInfoMap[addedSpell]->ChainEntry = &mSpellChains[addedSpell];
1300 prevRank = addedSpell;
1301 ++itr;
1302 if (itr == rankChain.end())
1303 {
1304 mSpellChains[addedSpell].next = nullptr;
1305 break;
1306 }
1307 else
1308 mSpellChains[addedSpell].next = GetSpellInfo(itr->first);
1309 } while (true);
1310 } while (!finished);
1311
1312 LOG_INFO("server.loading", ">> Loaded {} spell rank records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1313 LOG_INFO("server.loading", " ");
1314}
void LoadSpellTalentRanks()
Definition SpellMgr.cpp:1144

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

◆ LoadSpellRequired()

void SpellMgr::LoadSpellRequired ( )
1317{
1318 uint32 oldMSTime = getMSTime();
1319
1320 mSpellsReqSpell.clear(); // need for reload case
1321 mSpellReq.clear(); // need for reload case
1322
1323 // 0 1
1324 QueryResult result = WorldDatabase.Query("SELECT spell_id, req_spell from spell_required");
1325
1326 if (!result)
1327 {
1328 LOG_WARN("server.loading", ">> Loaded 0 spell required records. DB table `spell_required` is empty.");
1329 LOG_INFO("server.loading", " ");
1330 return;
1331 }
1332
1333 uint32 count = 0;
1334 do
1335 {
1336 Field* fields = result->Fetch();
1337
1338 uint32 spellId = fields[0].Get<uint32>();
1339 uint32 spellReq = fields[1].Get<uint32>();
1340
1341 // check if chain is made with valid first spell
1342 SpellInfo const* spellInfo = GetSpellInfo(spellId);
1343 if (!spellInfo)
1344 {
1345 LOG_ERROR("sql.sql", "spell_id {} in `spell_required` table is not found in dbcs, skipped", spellId);
1346 continue;
1347 }
1348
1349 SpellInfo const* reqSpellInfo = GetSpellInfo(spellReq);
1350 if (!reqSpellInfo)
1351 {
1352 LOG_ERROR("sql.sql", "req_spell {} in `spell_required` table is not found in dbcs, skipped", spellReq);
1353 continue;
1354 }
1355
1356 if (GetFirstSpellInChain(spellId) == GetFirstSpellInChain(spellReq))
1357 {
1358 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);
1359 continue;
1360 }
1361
1362 if (IsSpellRequiringSpell(spellId, spellReq))
1363 {
1364 LOG_ERROR("sql.sql", "duplicated entry of req_spell {} and spell_id {} in `spell_required`, skipped", spellReq, spellId);
1365 continue;
1366 }
1367
1368 mSpellReq.insert (std::pair<uint32, uint32>(spellId, spellReq));
1369 mSpellsReqSpell.insert (std::pair<uint32, uint32>(spellReq, spellId));
1370 ++count;
1371
1372 // xinef: fill additionalTalentInfo data, currently Blessing of Sanctuary only
1373 if (GetTalentSpellCost(spellReq) > 0)
1374 mTalentSpellAdditionalSet.insert(spellId);
1375 } while (result->NextRow());
1376
1377 LOG_INFO("server.loading", ">> Loaded {} Spell Required Records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1378 LOG_INFO("server.loading", " ");
1379}
uint32 GetTalentSpellCost(uint32 spellId)
Definition DBCStores.cpp:686
bool IsSpellRequiringSpell(uint32 spellid, uint32 req_spellid) const
Definition SpellMgr.cpp:616

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

◆ LoadSpellSpecificAndAuraState()

void SpellMgr::LoadSpellSpecificAndAuraState ( )
2949{
2950 uint32 oldMSTime = getMSTime();
2951
2952 SpellInfo* spellInfo = nullptr;
2953 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2954 {
2955 spellInfo = mSpellInfoMap[i];
2956 if (!spellInfo)
2957 continue;
2958 spellInfo->_spellSpecific = spellInfo->LoadSpellSpecific();
2959 spellInfo->_auraState = spellInfo->LoadAuraState();
2960 }
2961
2962 LOG_INFO("server.loading", ">> Loaded Spell Specific And Aura State in {} ms", GetMSTimeDiffToNow(oldMSTime));
2963 LOG_INFO("server.loading", " ");
2964}
SpellSpecificType LoadSpellSpecific() const
Definition SpellInfo.cpp:2033
AuraStateType LoadAuraState() const
Definition SpellInfo.cpp:1955
AuraStateType _auraState
Definition SpellInfo.h:398
SpellSpecificType _spellSpecific
Definition SpellInfo.h:399

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

◆ LoadSpellTalentRanks()

void SpellMgr::LoadSpellTalentRanks ( )
1145{
1146 // cleanup core data before reload - remove reference to ChainNode from SpellInfo
1148
1149 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1150 {
1151 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
1152 if (!talentInfo)
1153 continue;
1154
1155 SpellInfo const* lastSpell = nullptr;
1156 for (uint8 rank = MAX_TALENT_RANK - 1; rank > 0; --rank)
1157 {
1158 if (talentInfo->RankID[rank])
1159 {
1160 lastSpell = GetSpellInfo(talentInfo->RankID[rank]);
1161 break;
1162 }
1163 }
1164
1165 if (!lastSpell)
1166 continue;
1167
1168 SpellInfo const* firstSpell = GetSpellInfo(talentInfo->RankID[0]);
1169 if (!firstSpell)
1170 {
1171 LOG_ERROR("sql.sql", "SpellMgr::LoadSpellTalentRanks: First Rank Spell {} for TalentEntry {} does not exist.", talentInfo->RankID[0], i);
1172 continue;
1173 }
1174
1175 SpellInfo const* prevSpell = nullptr;
1176 for (uint8 rank = 0; rank < MAX_TALENT_RANK; ++rank)
1177 {
1178 uint32 spellId = talentInfo->RankID[rank];
1179 if (!spellId)
1180 break;
1181
1182 SpellInfo const* currentSpell = GetSpellInfo(spellId);
1183 if (!currentSpell)
1184 {
1185 LOG_ERROR("sql.sql", "SpellMgr::LoadSpellTalentRanks: Spell {} (Rank: {}) for TalentEntry {} does not exist.", spellId, rank + 1, i);
1186 break;
1187 }
1188
1189 SpellChainNode node;
1190 node.first = firstSpell;
1191 node.last = lastSpell;
1192 node.rank = rank + 1;
1193
1194 node.prev = prevSpell;
1195 node.next = node.rank < MAX_TALENT_RANK ? GetSpellInfo(talentInfo->RankID[node.rank]) : nullptr;
1196
1197 mSpellChains[spellId] = node;
1198 mSpellInfoMap[spellId]->ChainEntry = &mSpellChains[spellId];
1199
1200 prevSpell = currentSpell;
1201 }
1202 }
1203}
void UnloadSpellInfoChains()
Definition SpellMgr.cpp:1136
SpellInfo const * last
Definition SpellMgr.h:545
SpellInfo const * next
Definition SpellMgr.h:543
uint8 rank
Definition SpellMgr.h:546
SpellInfo const * first
Definition SpellMgr.h:544
SpellInfo const * prev
Definition SpellMgr.h:542

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 ( )
1435{
1436 uint32 oldMSTime = getMSTime();
1437
1438 mSpellTargetPositions.clear(); // need for reload case
1439
1440 // 0 1 2 3 4 5 6
1441 QueryResult result = WorldDatabase.Query("SELECT ID, EffectIndex, MapID, PositionX, PositionY, PositionZ, Orientation FROM spell_target_position");
1442
1443 if (!result)
1444 {
1445 LOG_WARN("server.loading", ">> Loaded 0 spell target coordinates. DB table `spell_target_position` is empty.");
1446 LOG_INFO("server.loading", " ");
1447 return;
1448 }
1449
1450 uint32 count = 0;
1451 do
1452 {
1453 Field* fields = result->Fetch();
1454
1455 uint32 Spell_ID = fields[0].Get<uint32>();
1456
1457 SpellEffIndex effIndex = SpellEffIndex(fields[1].Get<uint8>());
1458
1460
1461 st.target_mapId = fields[2].Get<uint16>();
1462 st.target_X = fields[3].Get<float>();
1463 st.target_Y = fields[4].Get<float>();
1464 st.target_Z = fields[5].Get<float>();
1465 st.target_Orientation = fields[6].Get<float>();
1466
1467 MapEntry const* mapEntry = sMapStore.LookupEntry(st.target_mapId);
1468 if (!mapEntry)
1469 {
1470 LOG_ERROR("sql.sql", "Spell (Id: {}, effIndex: {}) target map (ID: {}) does not exist in `Map.dbc`.", Spell_ID, effIndex, st.target_mapId);
1471 continue;
1472 }
1473
1474 if (st.target_X == 0 && st.target_Y == 0 && st.target_Z == 0)
1475 {
1476 LOG_ERROR("sql.sql", "Spell (Id: {}, effIndex: {}) target coordinates not provided.", Spell_ID, effIndex);
1477 continue;
1478 }
1479
1480 SpellInfo const* spellInfo = GetSpellInfo(Spell_ID);
1481 if (!spellInfo)
1482 {
1483 LOG_ERROR("sql.sql", "Spell (ID:{}) listed in `spell_target_position` does not exist.", Spell_ID);
1484 continue;
1485 }
1486
1487 if (spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_DEST_DB || spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_DEST_DB)
1488 {
1489 std::pair<uint32, SpellEffIndex> key = std::make_pair(Spell_ID, effIndex);
1490 mSpellTargetPositions[key] = st;
1491 ++count;
1492 }
1493 else
1494 {
1495 LOG_ERROR("sql.sql", "Spell (Id: {}, effIndex: {}) listed in `spell_target_position` does not have target TARGET_DEST_DB (17).", Spell_ID, effIndex);
1496 continue;
1497 }
1498 } while (result->NextRow());
1499
1500 /*
1501 // Check all spells
1502 for (uint32 i = 1; i < GetSpellInfoStoreSize; ++i)
1503 {
1504 SpellInfo const* spellInfo = GetSpellInfo(i);
1505 if (!spellInfo)
1506 continue;
1507
1508 bool found = false;
1509 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
1510 {
1511 switch (spellInfo->Effects[j].TargetA)
1512 {
1513 case TARGET_DEST_DB:
1514 found = true;
1515 break;
1516 }
1517 if (found)
1518 break;
1519 switch (spellInfo->Effects[j].TargetB)
1520 {
1521 case TARGET_DEST_DB:
1522 found = true;
1523 break;
1524 }
1525 if (found)
1526 break;
1527 }
1528 if (found)
1529 {
1530 if (!GetSpellTargetPosition(i))
1531 LOG_DEBUG("spells.aura", "Spell (ID: {}) does not have record in `spell_target_position`", i);
1532 }
1533 }*/
1534
1535 LOG_INFO("server.loading", ">> Loaded {} Spell Teleport Coordinates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1536 LOG_INFO("server.loading", " ");
1537}
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
SpellEffIndex
Definition SharedDefines.h:30
Definition DBCStructure.h:1325
Definition SpellMgr.h:383
float target_Z
Definition SpellMgr.h:387
uint32 target_mapId
Definition SpellMgr.h:384
float target_Y
Definition SpellMgr.h:386
float target_Orientation
Definition SpellMgr.h:388
float target_X
Definition SpellMgr.h:385

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 ( )
2175{
2176 uint32 oldMSTime = getMSTime();
2177
2178 mSpellThreatMap.clear(); // need for reload case
2179
2180 // 0 1 2 3
2181 QueryResult result = WorldDatabase.Query("SELECT entry, flatMod, pctMod, apPctMod FROM spell_threat");
2182 if (!result)
2183 {
2184 LOG_WARN("server.loading", ">> Loaded 0 aggro generating spells. DB table `spell_threat` is empty.");
2185 LOG_INFO("server.loading", " ");
2186 return;
2187 }
2188
2189 uint32 count = 0;
2190 do
2191 {
2192 Field* fields = result->Fetch();
2193
2194 uint32 entry = fields[0].Get<uint32>();
2195
2196 if (!GetSpellInfo(entry))
2197 {
2198 LOG_ERROR("sql.sql", "Spell {} listed in `spell_threat` does not exist", entry);
2199 continue;
2200 }
2201
2202 SpellThreatEntry ste;
2203 ste.flatMod = fields[1].Get<int32>();
2204 ste.pctMod = fields[2].Get<float>();
2205 ste.apPctMod = fields[3].Get<float>();
2206
2207 mSpellThreatMap[entry] = ste;
2208 ++count;
2209 } while (result->NextRow());
2210
2211 LOG_INFO("server.loading", ">> Loaded {} SpellThreatEntries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2212 LOG_INFO("server.loading", " ");
2213}
Definition SpellMgr.h:372
int32 flatMod
Definition SpellMgr.h:373
float apPctMod
Definition SpellMgr.h:375
float pctMod
Definition SpellMgr.h:374

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 
)
483{
484 mSpellDifficultySearcherMap[spellId] = id;
485}

References mSpellDifficultySearcherMap.

◆ UnloadSpellInfoChains()

void SpellMgr::UnloadSpellInfoChains ( )
1137{
1138 for (SpellChainMap::iterator itr = mSpellChains.begin(); itr != mSpellChains.end(); ++itr)
1139 mSpellInfoMap[itr->first]->ChainEntry = nullptr;
1140
1141 mSpellChains.clear();
1142}

References mSpellChains, and mSpellInfoMap.

Referenced by LoadSpellTalentRanks().

◆ UnloadSpellInfoImplicitTargetConditionLists()

void SpellMgr::UnloadSpellInfoImplicitTargetConditionLists ( )
2940{
2941 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2942 {
2943 if (mSpellInfoMap[i])
2944 mSpellInfoMap[i]->_UnloadImplicitTargetConditionLists();
2945 }
2946}

References GetSpellInfoStoreSize(), and mSpellInfoMap.

◆ UnloadSpellInfoStore()

void SpellMgr::UnloadSpellInfoStore ( )
2932{
2933 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2934 delete mSpellInfoMap[i];
2935
2936 mSpellInfoMap.clear();
2937}

References GetSpellInfoStoreSize(), and mSpellInfoMap.

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

Member Data Documentation

◆ mEnchantCustomAttr

EnchantCustomAttribute SpellMgr::mEnchantCustomAttr
private

◆ mPetDefaultSpellsMap

PetDefaultSpellsMap SpellMgr::mPetDefaultSpellsMap
private

◆ mPetLevelupSpellMap

PetLevelupSpellMap SpellMgr::mPetLevelupSpellMap
private

◆ mSkillLineAbilityMap

SkillLineAbilityMap SpellMgr::mSkillLineAbilityMap
private

◆ mSpellAreaForAreaMap

SpellAreaForAreaMap SpellMgr::mSpellAreaForAreaMap
private

◆ mSpellAreaForAuraMap

SpellAreaForAuraMap SpellMgr::mSpellAreaForAuraMap
private

◆ mSpellAreaForQuestEndMap

SpellAreaForQuestMap SpellMgr::mSpellAreaForQuestEndMap
private

◆ mSpellAreaForQuestMap

SpellAreaForQuestMap SpellMgr::mSpellAreaForQuestMap
private

◆ mSpellAreaMap

SpellAreaMap SpellMgr::mSpellAreaMap
private

◆ mSpellBonusMap

SpellBonusMap SpellMgr::mSpellBonusMap
private

◆ mSpellChains

◆ mSpellCooldownOverrideMap

SpellCooldownOverrideMap SpellMgr::mSpellCooldownOverrideMap
private

◆ mSpellDifficultySearcherMap

SpellDifficultySearcherMap SpellMgr::mSpellDifficultySearcherMap
private

◆ mSpellEnchantProcEventMap

SpellEnchantProcEventMap SpellMgr::mSpellEnchantProcEventMap
private

◆ mSpellGroupSpell

SpellGroupSpellMap SpellMgr::mSpellGroupSpell
private

◆ mSpellGroupStack

◆ mSpellInfoMap

◆ mSpellLearnSkills

SpellLearnSkillMap SpellMgr::mSpellLearnSkills
private

◆ mSpellLinkedMap

SpellLinkedMap SpellMgr::mSpellLinkedMap
private

Referenced by GetSpellLinked(), and LoadSpellLinked().

◆ mSpellMixologyMap

SpellMixologyMap SpellMgr::mSpellMixologyMap
private

◆ mSpellPetAuraMap

SpellPetAuraMap SpellMgr::mSpellPetAuraMap
private

Referenced by GetPetAura(), and LoadSpellPetAuras().

◆ mSpellProcMap

SpellProcMap SpellMgr::mSpellProcMap
private

◆ mSpellReq

SpellRequiredMap SpellMgr::mSpellReq
private

◆ mSpellSameEffectStack

SameEffectStackMap SpellMgr::mSpellSameEffectStack
private

◆ mSpellSpellGroup

SpellSpellGroupMap SpellMgr::mSpellSpellGroup
private

◆ mSpellsReqSpell

SpellsRequiringSpellMap SpellMgr::mSpellsReqSpell
private

◆ mSpellTargetPositions

SpellTargetPositionMap SpellMgr::mSpellTargetPositions
private

◆ mSpellThreatMap

SpellThreatMap SpellMgr::mSpellThreatMap
private

◆ mTalentSpellAdditionalSet

TalentAdditionalSet SpellMgr::mTalentSpellAdditionalSet
private

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