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

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 if (SpellInfo const* eventSpellInfo = eventInfo.GetSpellInfo())
827 if (!eventSpellInfo->IsAffected(procEntry.SpellFamilyName, procEntry.SpellFamilyMask))
828 return false;
829
830 // check spell type mask (if set)
832 {
833 if (procEntry.SpellTypeMask && !(eventInfo.GetSpellTypeMask() & procEntry.SpellTypeMask))
834 return false;
835 }
836
837 // check spell phase mask
839 {
840 if (!(eventInfo.GetSpellPhaseMask() & procEntry.SpellPhaseMask))
841 return false;
842 }
843
844 // check hit mask (on taken hit or on done hit)
845 // For CAST phase with DONE flags, only check if HitMask is explicitly set (crit is pre-calculated for travel time spells)
846 if ((eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK) ||
847 ((eventInfo.GetTypeMask() & DONE_HIT_PROC_FLAG_MASK) &&
848 (!(eventInfo.GetSpellPhaseMask() & PROC_SPELL_PHASE_CAST) || procEntry.HitMask)))
849 {
850 uint32 hitMask = procEntry.HitMask;
851 // get default values if hit mask not set
852 if (!hitMask)
853 {
854 // for taken procs allow normal + critical hits by default
855 if (eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK)
857 // for done procs allow normal + critical + absorbs by default
858 else
860 }
861 if (!(eventInfo.GetHitMask() & hitMask))
862 return false;
863 }
864
865 return true;
866}
@ 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:296
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:282
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
914{
915 SpellPetAuraMap::const_iterator itr = mSpellPetAuraMap.find((spell_id << 8) + eff);
916 if (itr != mSpellPetAuraMap.end())
917 return &itr->second;
918 else
919 return nullptr;
920}
SpellPetAuraMap mSpellPetAuraMap
Definition SpellMgr.h:797

References mSpellPetAuraMap.

◆ GetPetDefaultSpellsEntry()

PetDefaultSpellsEntry const * SpellMgr::GetPetDefaultSpellsEntry ( int32  id) const
951{
952 PetDefaultSpellsMap::const_iterator itr = mPetDefaultSpellsMap.find(id);
953 if (itr != mPetDefaultSpellsMap.end())
954 return &itr->second;
955 return nullptr;
956}
PetDefaultSpellsMap mPetDefaultSpellsMap
Definition SpellMgr.h:808

References mPetDefaultSpellsMap.

◆ GetPetLevelupSpellList()

PetLevelupSpellSet const * SpellMgr::GetPetLevelupSpellList ( uint32  petFamily) const
942{
943 PetLevelupSpellMap::const_iterator itr = mPetLevelupSpellMap.find(petFamily);
944 if (itr != mPetLevelupSpellMap.end())
945 return &itr->second;
946 else
947 return nullptr;
948}
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
909{
910 return mSkillLineAbilityMap.equal_range(spell_id);
911}
SkillLineAbilityMap mSkillLineAbilityMap
Definition SpellMgr.h:806

References mSkillLineAbilityMap.

◆ GetSpellAreaForAreaMapBounds()

SpellAreaForAreaMapBounds SpellMgr::GetSpellAreaForAreaMapBounds ( uint32  area_id) const
979{
980 return mSpellAreaForAreaMap.equal_range(area_id);
981}
SpellAreaForAreaMap mSpellAreaForAreaMap
Definition SpellMgr.h:805

References mSpellAreaForAreaMap.

◆ GetSpellAreaForAuraMapBounds()

SpellAreaForAuraMapBounds SpellMgr::GetSpellAreaForAuraMapBounds ( uint32  spell_id) const
974{
975 return mSpellAreaForAuraMap.equal_range(spell_id);
976}
SpellAreaForAuraMap mSpellAreaForAuraMap
Definition SpellMgr.h:804

References mSpellAreaForAuraMap.

Referenced by LoadSpellAreas().

◆ GetSpellAreaForQuestEndMapBounds()

SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestEndMapBounds ( uint32  quest_id) const
969{
970 return mSpellAreaForQuestEndMap.equal_range(quest_id);
971}
SpellAreaForQuestMap mSpellAreaForQuestEndMap
Definition SpellMgr.h:803

References mSpellAreaForQuestEndMap.

◆ GetSpellAreaForQuestMapBounds()

SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestMapBounds ( uint32  quest_id) const
964{
965 return mSpellAreaForQuestMap.equal_range(quest_id);
966}
SpellAreaForQuestMap mSpellAreaForQuestMap
Definition SpellMgr.h:802

References mSpellAreaForQuestMap.

◆ GetSpellAreaMapBounds()

SpellAreaMapBounds SpellMgr::GetSpellAreaMapBounds ( uint32  spell_id) const
959{
960 return mSpellAreaMap.equal_range(spell_id);
961}
SpellAreaMap mSpellAreaMap
Definition SpellMgr.h:801

References mSpellAreaMap.

Referenced by LoadSpellAreas().

◆ GetSpellBonusData()

SpellBonusEntry const * SpellMgr::GetSpellBonusData ( uint32  spellId) const
869{
870 // Lookup data
871 SpellBonusMap::const_iterator itr = mSpellBonusMap.find(spellId);
872 if (itr != mSpellBonusMap.end())
873 return &itr->second;
874 // Not found, try lookup for 1 spell rank if exist
875 if (uint32 rank_1 = GetFirstSpellInChain(spellId))
876 {
877 SpellBonusMap::const_iterator itr2 = mSpellBonusMap.find(rank_1);
878 if (itr2 != mSpellBonusMap.end())
879 return &itr2->second;
880 }
881 return nullptr;
882}
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
2919{
2920 auto range = mSpellCooldownOverrideMap.find(spellId);
2921 return range->second;
2922}
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
923{
924 SpellEnchantProcEventMap::const_iterator itr = mSpellEnchantProcEventMap.find(enchId);
925 if (itr != mSpellEnchantProcEventMap.end())
926 return &itr->second;
927 return nullptr;
928}
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
936{
937 SpellLinkedMap::const_iterator itr = mSpellLinkedMap.find(spell_id);
938 return itr != mSpellLinkedMap.end() ? &(itr->second) : nullptr;
939}
SpellLinkedMap mSpellLinkedMap
Definition SpellMgr.h:798

References mSpellLinkedMap.

◆ GetSpellMixologyBonus()

float SpellMgr::GetSpellMixologyBonus ( uint32  spellId) const
900{
901 SpellMixologyMap::const_iterator itr = mSpellMixologyMap.find(spellId);
902 if (itr == mSpellMixologyMap.end())
903 return 30.0f;
904
905 return itr->second;
906}
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
885{
886 SpellThreatMap::const_iterator itr = mSpellThreatMap.find(spellID);
887 if (itr != mSpellThreatMap.end())
888 return &itr->second;
889 else
890 {
891 uint32 firstSpell = GetFirstSpellInChain(spellID);
892 itr = mSpellThreatMap.find(firstSpell);
893 if (itr != mSpellThreatMap.end())
894 return &itr->second;
895 }
896 return nullptr;
897}
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
2914{
2915 return mSpellCooldownOverrideMap.find(spellId) != mSpellCooldownOverrideMap.end();
2916}

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
931{
932 return mEnchantCustomAttr[ench_id];
933}
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
2330{
2331 uint32 oldMSTime = getMSTime();
2332
2333 uint32 size = sSpellItemEnchantmentStore.GetNumRows();
2334 mEnchantCustomAttr.resize(size);
2335
2336 for (uint32 i = 0; i < size; ++i)
2337 mEnchantCustomAttr[i] = 0;
2338
2339 uint32 count = 0;
2340 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2341 {
2342 SpellInfo const* spellInfo = GetSpellInfo(i);
2343 if (!spellInfo)
2344 continue;
2345
2347 // Xinef: commented second part, fixes warlock enchants like firestone, spellstone
2348 if (!spellInfo->HasAttribute(SPELL_ATTR2_ENCHANT_OWN_ITEM_ONLY)/* || !spellInfo->HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFTED)*/)
2349 continue;
2350
2351 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
2352 {
2353 if (spellInfo->Effects[j].Effect == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY)
2354 {
2355 uint32 enchId = spellInfo->Effects[j].MiscValue;
2356 SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchId);
2357 if (!ench)
2358 continue;
2359 mEnchantCustomAttr[enchId] = true;
2360 ++count;
2361 break;
2362 }
2363 }
2364 }
2365
2366 LOG_INFO("server.loading", ">> Loaded {} Custom Enchant Attributes in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2367 LOG_INFO("server.loading", " ");
2368}
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 ( )
2563{
2564 uint32 oldMSTime = getMSTime();
2565
2566 mPetDefaultSpellsMap.clear();
2567
2568 uint32 countCreature = 0;
2569 uint32 countData = 0;
2570
2571 CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
2572 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
2573 {
2574 if (!itr->second.PetSpellDataId)
2575 continue;
2576
2577 // for creature with PetSpellDataId get default pet spells from dbc
2578 CreatureSpellDataEntry const* spellDataEntry = sCreatureSpellDataStore.LookupEntry(itr->second.PetSpellDataId);
2579 if (!spellDataEntry)
2580 continue;
2581
2582 int32 petSpellsId = -int32(itr->second.PetSpellDataId);
2583 PetDefaultSpellsEntry petDefSpells;
2584 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2585 petDefSpells.spellid[j] = spellDataEntry->spellId[j];
2586
2587 if (LoadPetDefaultSpells_helper(&itr->second, petDefSpells))
2588 {
2589 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2590 ++countData;
2591 }
2592 }
2593
2594 LOG_INFO("server.loading", ">> Loaded Addition Spells For {} Pet Spell Data Entries in {} ms", countData, GetMSTimeDiffToNow(oldMSTime));
2595 LOG_INFO("server.loading", " ");
2596
2597 LOG_INFO("server.loading", "Loading Summonable Creature Templates...");
2598 oldMSTime = getMSTime();
2599
2600 // different summon spells
2601 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2602 {
2603 SpellInfo const* spellInfo = GetSpellInfo(i);
2604 if (!spellInfo)
2605 continue;
2606
2607 for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
2608 {
2609 if (spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON || spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON_PET)
2610 {
2611 uint32 creature_id = spellInfo->Effects[k].MiscValue;
2612 CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id);
2613 if (!cInfo)
2614 continue;
2615
2616 // already loaded
2617 if (cInfo->PetSpellDataId)
2618 continue;
2619
2620 // for creature without PetSpellDataId get default pet spells from creature_template
2621 int32 petSpellsId = cInfo->Entry;
2622 if (mPetDefaultSpellsMap.find(cInfo->Entry) != mPetDefaultSpellsMap.end())
2623 continue;
2624
2625 PetDefaultSpellsEntry petDefSpells;
2626 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2627 petDefSpells.spellid[j] = cInfo->spells[j];
2628
2629 if (LoadPetDefaultSpells_helper(cInfo, petDefSpells))
2630 {
2631 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2632 ++countCreature;
2633 }
2634 }
2635 }
2636 }
2637
2638 LOG_INFO("server.loading", ">> Loaded {} Summonable Creature emplates in {} ms", countCreature, GetMSTimeDiffToNow(oldMSTime));
2639 LOG_INFO("server.loading", " ");
2640}
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:2514
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 ( )
2469{
2470 uint32 oldMSTime = getMSTime();
2471
2472 mPetLevelupSpellMap.clear(); // need for reload case
2473
2474 uint32 count = 0;
2475 uint32 family_count = 0;
2476
2477 for (uint32 i = 0; i < sCreatureFamilyStore.GetNumRows(); ++i)
2478 {
2479 CreatureFamilyEntry const* creatureFamily = sCreatureFamilyStore.LookupEntry(i);
2480 if (!creatureFamily) // not exist
2481 continue;
2482
2483 for (uint8 j = 0; j < 2; ++j)
2484 {
2485 if (!creatureFamily->skillLine[j])
2486 continue;
2487
2488 for (SkillLineAbilityEntry const* skillLine : GetSkillLineAbilitiesBySkillLine(creatureFamily->skillLine[j]))
2489 {
2490 if (skillLine->AcquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN)
2491 continue;
2492
2493 SpellInfo const* spell = GetSpellInfo(skillLine->Spell);
2494 if (!spell) // not exist or triggered or talent
2495 continue;
2496
2497 if (!spell->SpellLevel)
2498 continue;
2499
2500 PetLevelupSpellSet& spellSet = mPetLevelupSpellMap[creatureFamily->ID];
2501 if (spellSet.empty())
2502 ++family_count;
2503
2504 spellSet.insert(PetLevelupSpellSet::value_type(spell->SpellLevel, spell->Id));
2505 ++count;
2506 }
2507 }
2508 }
2509
2510 LOG_INFO("server.loading", ">> Loaded {} Pet Levelup And Default Spells For {} Families in {} ms", count, family_count, GetMSTimeDiffToNow(oldMSTime));
2511 LOG_INFO("server.loading", " ");
2512}
@ 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 ( )
2245{
2246 uint32 oldMSTime = getMSTime();
2247
2248 mSkillLineAbilityMap.clear();
2249
2250 uint32 count = 0;
2251
2252 for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); ++i)
2253 {
2254 SkillLineAbilityEntry const* SkillInfo = sSkillLineAbilityStore.LookupEntry(i);
2255 if (!SkillInfo)
2256 continue;
2257
2258 mSkillLineAbilityMap.insert(SkillLineAbilityMap::value_type(SkillInfo->Spell, SkillInfo));
2259 ++count;
2260 }
2261
2262 LOG_INFO("server.loading", ">> Loaded {} SkillLineAbility MultiMap Data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2263 LOG_INFO("server.loading", " ");
2264}
DBCStorage< SkillLineAbilityEntry > sSkillLineAbilityStore(SkillLineAbilityfmt)
uint32 Spell
Definition DBCStructure.h:1601

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

◆ LoadSpellAreas()

void SpellMgr::LoadSpellAreas ( )
2643{
2644 uint32 oldMSTime = getMSTime();
2645
2646 mSpellAreaMap.clear(); // need for reload case
2647 mSpellAreaForQuestMap.clear();
2649 mSpellAreaForAuraMap.clear();
2650
2651 // 0 1 2 3 4 5 6 7 8 9
2652 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");
2653
2654 if (!result)
2655 {
2656 LOG_WARN("server.loading", ">> Loaded 0 spell area requirements. DB table `spell_area` is empty.");
2657 LOG_INFO("server.loading", " ");
2658 return;
2659 }
2660
2661 uint32 count = 0;
2662 do
2663 {
2664 Field* fields = result->Fetch();
2665
2666 uint32 spell = fields[0].Get<uint32>();
2667 SpellArea spellArea;
2668 spellArea.spellId = spell;
2669 spellArea.areaId = fields[1].Get<uint32>();
2670 spellArea.questStart = fields[2].Get<uint32>();
2671 spellArea.questStartStatus = fields[3].Get<uint32>();
2672 spellArea.questEndStatus = fields[4].Get<uint32>();
2673 spellArea.questEnd = fields[5].Get<uint32>();
2674 spellArea.auraSpell = fields[6].Get<int32>();
2675 spellArea.raceMask = fields[7].Get<uint32>();
2676 spellArea.gender = Gender(fields[8].Get<uint8>());
2677 spellArea.autocast = fields[9].Get<bool>();
2678
2679 if (SpellInfo const* spellInfo = GetSpellInfo(spell))
2680 {
2681 if (spellArea.autocast)
2682 const_cast<SpellInfo*>(spellInfo)->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
2683 }
2684 else
2685 {
2686 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` does not exist", spell);
2687 continue;
2688 }
2689
2690 {
2691 bool ok = true;
2692 SpellAreaMapBounds sa_bounds = GetSpellAreaMapBounds(spellArea.spellId);
2693 for (SpellAreaMap::const_iterator itr = sa_bounds.first; itr != sa_bounds.second; ++itr)
2694 {
2695 if (spellArea.spellId != itr->second.spellId)
2696 continue;
2697 if (spellArea.areaId != itr->second.areaId)
2698 continue;
2699 if (spellArea.questStart != itr->second.questStart)
2700 continue;
2701 if (spellArea.auraSpell != itr->second.auraSpell)
2702 continue;
2703 if ((spellArea.raceMask & itr->second.raceMask) == 0)
2704 continue;
2705 if (spellArea.gender != itr->second.gender)
2706 continue;
2707
2708 // duplicate by requirements
2709 ok = false;
2710 break;
2711 }
2712
2713 if (!ok)
2714 {
2715 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` already listed with similar requirements.", spell);
2716 continue;
2717 }
2718 }
2719
2720 if (spellArea.areaId && !sAreaTableStore.LookupEntry(spellArea.areaId))
2721 {
2722 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong area ({}) requirement", spell, spellArea.areaId);
2723 continue;
2724 }
2725
2726 if (spellArea.questStart && !sObjectMgr->GetQuestTemplate(spellArea.questStart))
2727 {
2728 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong start quest ({}) requirement", spell, spellArea.questStart);
2729 continue;
2730 }
2731
2732 if (spellArea.questEnd)
2733 {
2734 if (!sObjectMgr->GetQuestTemplate(spellArea.questEnd))
2735 {
2736 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong end quest ({}) requirement", spell, spellArea.questEnd);
2737 continue;
2738 }
2739 }
2740
2741 if (spellArea.auraSpell)
2742 {
2743 SpellInfo const* spellInfo = GetSpellInfo(std::abs(spellArea.auraSpell));
2744 if (!spellInfo)
2745 {
2746 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong aura spell ({}) requirement", spell, std::abs(spellArea.auraSpell));
2747 continue;
2748 }
2749
2750 if (uint32(std::abs(spellArea.auraSpell)) == spellArea.spellId)
2751 {
2752 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement for itself", spell, std::abs(spellArea.auraSpell));
2753 continue;
2754 }
2755
2756 // not allow autocast chains by auraSpell field (but allow use as alternative if not present)
2757 if (spellArea.autocast && spellArea.auraSpell > 0)
2758 {
2759 bool chain = false;
2760 SpellAreaForAuraMapBounds saBound = GetSpellAreaForAuraMapBounds(spellArea.spellId);
2761 for (SpellAreaForAuraMap::const_iterator itr = saBound.first; itr != saBound.second; ++itr)
2762 {
2763 if (itr->second->autocast && itr->second->auraSpell > 0)
2764 {
2765 chain = true;
2766 break;
2767 }
2768 }
2769
2770 if (chain)
2771 {
2772 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement that itself autocast from aura", spell, spellArea.auraSpell);
2773 continue;
2774 }
2775
2776 SpellAreaMapBounds saBound2 = GetSpellAreaMapBounds(spellArea.auraSpell);
2777 for (SpellAreaMap::const_iterator itr2 = saBound2.first; itr2 != saBound2.second; ++itr2)
2778 {
2779 if (itr2->second.autocast && itr2->second.auraSpell > 0)
2780 {
2781 chain = true;
2782 break;
2783 }
2784 }
2785
2786 if (chain)
2787 {
2788 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have aura spell ({}) requirement that itself autocast from aura", spell, spellArea.auraSpell);
2789 continue;
2790 }
2791 }
2792 }
2793
2794 if (spellArea.raceMask && (spellArea.raceMask & sRaceMgr->GetPlayableRaceMask()) == 0)
2795 {
2796 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong race mask ({}) requirement", spell, spellArea.raceMask);
2797 continue;
2798 }
2799
2800 if (spellArea.gender != GENDER_NONE && spellArea.gender != GENDER_FEMALE && spellArea.gender != GENDER_MALE)
2801 {
2802 LOG_ERROR("sql.sql", "Spell {} listed in `spell_area` have wrong gender ({}) requirement", spell, spellArea.gender);
2803 continue;
2804 }
2805
2806 SpellArea const* sa = &mSpellAreaMap.insert(SpellAreaMap::value_type(spell, spellArea))->second;
2807
2808 // for search by current zone/subzone at zone/subzone change
2809 if (spellArea.areaId)
2810 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(spellArea.areaId, sa));
2811
2812 // for search at quest start/reward
2813 if (spellArea.questStart)
2814 mSpellAreaForQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa));
2815
2816 // for search at quest start/reward
2817 if (spellArea.questEnd)
2818 mSpellAreaForQuestEndMap.insert(SpellAreaForQuestMap::value_type(spellArea.questEnd, sa));
2819
2820 // for search at aura apply
2821 if (spellArea.auraSpell)
2822 mSpellAreaForAuraMap.insert(SpellAreaForAuraMap::value_type(std::abs(spellArea.auraSpell), sa));
2823
2824 ++count;
2825 } while (result->NextRow());
2826
2827 if (sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE) > 0)
2828 {
2829 LOG_INFO("server.loading", ">> Using ICC Buff Horde: {}", sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE));
2830 SpellArea spellAreaICCBuffHorde = { sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE), ICC_AREA, 0, 0, 0, ICC_RACEMASK_HORDE, Gender(2), 64, 11, 1 };
2831 SpellArea const* saICCBuffHorde = &mSpellAreaMap.insert(SpellAreaMap::value_type(sWorld->getIntConfig(CONFIG_ICC_BUFF_HORDE), spellAreaICCBuffHorde))->second;
2832 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(ICC_AREA, saICCBuffHorde));
2833 ++count;
2834 }
2835 else
2836 LOG_INFO("server.loading", ">> ICC Buff Horde: disabled");
2837
2838 if (sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE) > 0)
2839 {
2840 LOG_INFO("server.loading", ">> Using ICC Buff Alliance: {}", sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE));
2841 SpellArea spellAreaICCBuffAlliance = { sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE), ICC_AREA, 0, 0, 0, ICC_RACEMASK_ALLIANCE, Gender(2), 64, 11, 1 };
2842 SpellArea const* saICCBuffAlliance = &mSpellAreaMap.insert(SpellAreaMap::value_type(sWorld->getIntConfig(CONFIG_ICC_BUFF_ALLIANCE), spellAreaICCBuffAlliance))->second;
2843 mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(ICC_AREA, saICCBuffAlliance));
2844 ++count;
2845 }
2846 else
2847 LOG_INFO("server.loading", ">> ICC Buff Alliance: disabled");
2848
2849 LOG_INFO("server.loading", ">> Loaded {} Spell Area Requirements in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2850 LOG_INFO("server.loading", " ");
2851}
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:958
SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds(uint32 spell_id) const
Definition SpellMgr.cpp:973
#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 ( )
2127{
2128 uint32 oldMSTime = getMSTime();
2129
2130 mSpellBonusMap.clear(); // need for reload case
2131
2132 // 0 1 2 3 4
2133 QueryResult result = WorldDatabase.Query("SELECT entry, direct_bonus, dot_bonus, ap_bonus, ap_dot_bonus FROM spell_bonus_data");
2134 if (!result)
2135 {
2136 LOG_WARN("server.loading", ">> Loaded 0 spell bonus data. DB table `spell_bonus_data` is empty.");
2137 LOG_INFO("server.loading", " ");
2138 return;
2139 }
2140
2141 uint32 count = 0;
2142 do
2143 {
2144 Field* fields = result->Fetch();
2145 uint32 entry = fields[0].Get<uint32>();
2146
2147 SpellInfo const* spell = GetSpellInfo(entry);
2148 if (!spell)
2149 {
2150 LOG_ERROR("sql.sql", "Spell {} listed in `spell_bonus_data` does not exist", entry);
2151 continue;
2152 }
2153
2154 SpellBonusEntry& sbe = mSpellBonusMap[entry];
2155 sbe.direct_damage = fields[1].Get<float>();
2156 sbe.dot_damage = fields[2].Get<float>();
2157 sbe.ap_bonus = fields[3].Get<float>();
2158 sbe.ap_dot_bonus = fields[4].Get<float>();
2159
2160 ++count;
2161 } while (result->NextRow());
2162
2163 LOG_INFO("server.loading", ">> Loaded {} Extra Spell Bonus Data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2164 LOG_INFO("server.loading", " ");
2165}
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 ( )
2883{
2884 uint32 oldMSTime = getMSTime();
2885
2887
2888 QueryResult result = WorldDatabase.Query("SELECT Id, RecoveryTime, CategoryRecoveryTime, StartRecoveryTime, StartRecoveryCategory FROM spell_cooldown_overrides");
2889
2890 uint32 count = 0;
2891
2892 if (result)
2893 {
2894 do
2895 {
2896 Field* fields = result->Fetch();
2897 SpellCooldownOverride spellCooldown;
2898 uint32 spellId = fields[0].Get<uint32>();
2899 spellCooldown.RecoveryTime = fields[1].Get<uint32>();
2900 spellCooldown.CategoryRecoveryTime = fields[2].Get<uint32>();
2901 spellCooldown.StartRecoveryTime = fields[3].Get<uint32>();
2902 spellCooldown.StartRecoveryCategory = fields[4].Get<uint32>();
2903 mSpellCooldownOverrideMap[spellId] = spellCooldown;
2904
2905 ++count;
2906 } while (result->NextRow());
2907 }
2908
2909 LOG_INFO("server.loading", ">> Loaded {} Spell Cooldown Overrides entries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2910 LOG_INFO("server.loading", " ");
2911}
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 ( )
2371{
2372 uint32 oldMSTime = getMSTime();
2373
2374 mSpellEnchantProcEventMap.clear(); // need for reload case
2375
2376 // 0 1 2 3 4
2377 QueryResult result = WorldDatabase.Query("SELECT entry, customChance, PPMChance, procEx, attributeMask FROM spell_enchant_proc_data");
2378 if (!result)
2379 {
2380 LOG_WARN("server.loading", ">> Loaded 0 spell enchant proc event conditions. DB table `spell_enchant_proc_data` is empty.");
2381 LOG_INFO("server.loading", " ");
2382 return;
2383 }
2384
2385 uint32 count = 0;
2386 do
2387 {
2388 Field* fields = result->Fetch();
2389
2390 uint32 enchantId = fields[0].Get<uint32>();
2391
2392 SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchantId);
2393 if (!ench)
2394 {
2395 LOG_ERROR("sql.sql", "Enchancment {} listed in `spell_enchant_proc_data` does not exist", enchantId);
2396 continue;
2397 }
2398
2400
2401 spe.customChance = fields[1].Get<uint32>();
2402 spe.PPMChance = fields[2].Get<float>();
2403 spe.procEx = fields[3].Get<uint32>();
2404 spe.attributeMask = fields[4].Get<uint32>();
2405
2406 mSpellEnchantProcEventMap[enchantId] = spe;
2407
2408 ++count;
2409 } while (result->NextRow());
2410
2411 LOG_INFO("server.loading", ">> Loaded {} Enchant Proc Data Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2412 LOG_INFO("server.loading", " ");
2413}
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 ( )
1533{
1534 uint32 oldMSTime = getMSTime();
1535
1536 mSpellSpellGroup.clear(); // need for reload case
1537 mSpellGroupSpell.clear();
1538
1539 // 0 1
1540 QueryResult result = WorldDatabase.Query("SELECT id, spell_id FROM spell_group");
1541 if (!result)
1542 {
1543 LOG_WARN("server.loading", ">> Loaded 0 spell group definitions. DB table `spell_group` is empty.");
1544 LOG_INFO("server.loading", " ");
1545 return;
1546 }
1547
1548 std::set<uint32> groups;
1549 uint32 count = 0;
1550 do
1551 {
1552 Field* fields = result->Fetch();
1553
1554 uint32 group_id = fields[0].Get<uint32>();
1555 if (group_id <= SPELL_GROUP_DB_RANGE_MIN && group_id >= SPELL_GROUP_CORE_RANGE_MAX)
1556 {
1557 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group` is in core range, but is not defined in core!", group_id);
1558 continue;
1559 }
1560 int32 spell_id = fields[1].Get<int32>();
1561
1562 groups.insert(group_id);
1563 mSpellGroupSpell.emplace(SpellGroup(group_id), spell_id);
1564
1565 } while (result->NextRow());
1566
1567 for (auto itr = mSpellGroupSpell.begin(); itr!= mSpellGroupSpell.end();)
1568 {
1569 if (itr->second < 0)
1570 {
1571 if (groups.find(abs(itr->second)) == groups.end())
1572 {
1573 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group` does not exist", abs(itr->second));
1574 itr = mSpellGroupSpell.erase(itr);
1575 }
1576 else
1577 ++itr;
1578 }
1579 else
1580 {
1581 SpellInfo const* spellInfo = GetSpellInfo(itr->second);
1582 if (!spellInfo)
1583 {
1584 LOG_ERROR("sql.sql", "Spell {} listed in `spell_group` does not exist", itr->second);
1585 itr = mSpellGroupSpell.erase(itr);
1586 }
1587 else if (spellInfo->GetRank() > 1)
1588 {
1589 LOG_ERROR("sql.sql", "Spell {} listed in `spell_group` is not first rank of spell.", itr->second);
1590 itr = mSpellGroupSpell.erase(itr);
1591 }
1592 else
1593 ++itr;
1594 }
1595 }
1596
1597 for (auto groupItr = groups.begin(); groupItr != groups.end(); ++groupItr)
1598 {
1599 std::set<uint32> spells;
1601
1602 for (auto spellItr = spells.begin(); spellItr != spells.end(); ++spellItr)
1603 {
1604 ++count;
1605 mSpellSpellGroup.emplace(*spellItr, SpellGroup(*groupItr));
1606 }
1607 }
1608
1609 LOG_INFO("server.loading", ">> Loaded {} spell group Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1610 LOG_INFO("server.loading", " ");
1611}
@ SPELL_GROUP_CORE_RANGE_MAX
Definition SpellMgr.h:332
spells
Definition boss_krystallus.cpp:26
uint8 GetRank() const
Definition SpellInfo.cpp:2392

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

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

◆ LoadSpellPetAuras()

void SpellMgr::LoadSpellPetAuras ( )
2267{
2268 uint32 oldMSTime = getMSTime();
2269
2270 mSpellPetAuraMap.clear(); // need for reload case
2271
2272 // 0 1 2 3
2273 QueryResult result = WorldDatabase.Query("SELECT spell, effectId, pet, aura FROM spell_pet_auras");
2274 if (!result)
2275 {
2276 LOG_WARN("server.loading", ">> Loaded 0 spell pet auras. DB table `spell_pet_auras` is empty.");
2277 LOG_INFO("server.loading", " ");
2278 return;
2279 }
2280
2281 uint32 count = 0;
2282 do
2283 {
2284 Field* fields = result->Fetch();
2285
2286 uint32 spell = fields[0].Get<uint32>();
2287 uint8 eff = fields[1].Get<uint8>();
2288 uint32 pet = fields[2].Get<uint32>();
2289 uint32 aura = fields[3].Get<uint32>();
2290
2291 SpellPetAuraMap::iterator itr = mSpellPetAuraMap.find((spell << 8) + eff);
2292 if (itr != mSpellPetAuraMap.end())
2293 itr->second.AddAura(pet, aura);
2294 else
2295 {
2296 SpellInfo const* spellInfo = GetSpellInfo(spell);
2297 if (!spellInfo)
2298 {
2299 LOG_ERROR("sql.sql", "Spell {} listed in `spell_pet_auras` does not exist", spell);
2300 continue;
2301 }
2302 if (spellInfo->Effects[eff].Effect != SPELL_EFFECT_DUMMY &&
2303 (spellInfo->Effects[eff].Effect != SPELL_EFFECT_APPLY_AURA ||
2304 spellInfo->Effects[eff].ApplyAuraName != SPELL_AURA_DUMMY))
2305 {
2306 LOG_ERROR("spells", "Spell {} listed in `spell_pet_auras` does not have dummy aura or dummy effect", spell);
2307 continue;
2308 }
2309
2310 SpellInfo const* spellInfo2 = GetSpellInfo(aura);
2311 if (!spellInfo2)
2312 {
2313 LOG_ERROR("sql.sql", "Aura {} listed in `spell_pet_auras` does not exist", aura);
2314 continue;
2315 }
2316
2317 PetAura pa(pet, aura, spellInfo->Effects[eff].TargetA.GetTarget() == TARGET_UNIT_PET, spellInfo->Effects[eff].CalcValue());
2318 mSpellPetAuraMap[(spell << 8) + eff] = pa;
2319 }
2320
2321 ++count;
2322 } while (result->NextRow());
2323
2324 LOG_INFO("server.loading", ">> Loaded {} Spell Pet Auras in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2325 LOG_INFO("server.loading", " ");
2326}
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 ( )
1839{
1840 uint32 oldMSTime = getMSTime();
1841
1842 mSpellProcMap.clear(); // need for reload case
1843
1844 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1845 QueryResult result = WorldDatabase.Query("SELECT SpellId, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, ProcFlags, SpellTypeMask, SpellPhaseMask, HitMask, AttributesMask, DisableEffectsMask, ProcsPerMinute, Chance, Cooldown, Charges FROM spell_proc");
1846 if (!result)
1847 {
1848 LOG_WARN("server.loading", ">> Loaded 0 Spell Proc Conditions And Data. DB table `spell_proc` Is Empty.");
1849 LOG_INFO("server.loading", " ");
1850 return;
1851 }
1852
1853 uint32 count = 0;
1854 do
1855 {
1856 Field* fields = result->Fetch();
1857
1858 int32 spellId = fields[0].Get<int32>();
1859
1860 bool allRanks = false;
1861 if (spellId < 0)
1862 {
1863 allRanks = true;
1864 spellId = -spellId;
1865 }
1866
1867 SpellInfo const* spellInfo = GetSpellInfo(spellId);
1868 if (!spellInfo)
1869 {
1870 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` does not exist", spellId);
1871 continue;
1872 }
1873
1874 if (allRanks)
1875 {
1876 if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId))
1877 {
1878 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` is not first rank of spell.", fields[0].Get<int32>());
1879 continue;
1880 }
1881 }
1882
1883 SpellProcEntry baseProcEntry;
1884
1885 baseProcEntry.SchoolMask = fields[1].Get<int8>();
1886 baseProcEntry.SpellFamilyName = fields[2].Get<uint16>();
1887 baseProcEntry.SpellFamilyMask[0] = fields[3].Get<uint32>();
1888 baseProcEntry.SpellFamilyMask[1] = fields[4].Get<uint32>();
1889 baseProcEntry.SpellFamilyMask[2] = fields[5].Get<uint32>();
1890 baseProcEntry.ProcFlags = fields[6].Get<uint32>();
1891 baseProcEntry.SpellTypeMask = fields[7].Get<uint32>();
1892 baseProcEntry.SpellPhaseMask = fields[8].Get<uint32>();
1893 baseProcEntry.HitMask = fields[9].Get<uint32>();
1894 baseProcEntry.AttributesMask = fields[10].Get<uint32>();
1895 baseProcEntry.DisableEffectsMask = fields[11].Get<uint32>();
1896 baseProcEntry.ProcsPerMinute = fields[12].Get<float>();
1897 baseProcEntry.Chance = fields[13].Get<float>();
1898 baseProcEntry.Cooldown = Milliseconds(fields[14].Get<uint32>());
1899 baseProcEntry.Charges = fields[15].Get<uint32>();
1900
1901 while (spellInfo)
1902 {
1903 if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end())
1904 {
1905 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` has duplicate entry in the table", spellId);
1906 break;
1907 }
1908 SpellProcEntry procEntry = SpellProcEntry(baseProcEntry);
1909
1910 // take defaults from dbcs
1911 if (!procEntry.ProcFlags)
1912 procEntry.ProcFlags = spellInfo->ProcFlags;
1913 if (!procEntry.Charges)
1914 procEntry.Charges = spellInfo->ProcCharges;
1915 if (!procEntry.Chance && !procEntry.ProcsPerMinute)
1916 procEntry.Chance = float(spellInfo->ProcChance);
1917
1918 // validate data
1919 if (procEntry.SchoolMask & ~SPELL_SCHOOL_MASK_ALL)
1920 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SchoolMask` set: {}", spellId, procEntry.SchoolMask);
1921 if (procEntry.SpellFamilyName && (procEntry.SpellFamilyName < 3 || procEntry.SpellFamilyName > 17 || procEntry.SpellFamilyName == 14 || procEntry.SpellFamilyName == 16))
1922 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellFamilyName` set: {}", spellId, procEntry.SpellFamilyName);
1923 if (procEntry.Chance < 0)
1924 {
1925 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `Chance` field", spellId);
1926 procEntry.Chance = 0;
1927 }
1928 if (procEntry.ProcsPerMinute < 0)
1929 {
1930 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `ProcsPerMinute` field", spellId);
1931 procEntry.ProcsPerMinute = 0;
1932 }
1933 if (procEntry.Charges > 99)
1934 {
1935 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has too big value in `Charges` field", spellId);
1936 procEntry.Charges = 99;
1937 }
1938 if (!procEntry.ProcFlags)
1939 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} doesn't have `ProcFlags` value defined, proc will not be triggered", spellId);
1940 if (procEntry.SpellTypeMask & ~PROC_SPELL_TYPE_MASK_ALL)
1941 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellTypeMask` set: {}", spellId, procEntry.SpellTypeMask);
1942 if (procEntry.SpellTypeMask && !(procEntry.ProcFlags & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK)))
1943 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);
1944 if (!procEntry.SpellPhaseMask && procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK)
1945 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);
1947 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellPhaseMask` set: {}", spellId, procEntry.SpellPhaseMask);
1948 if (procEntry.SpellPhaseMask && !(procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK))
1949 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);
1950 if (procEntry.HitMask & ~PROC_HIT_MASK_ALL)
1951 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `HitMask` set: {}", spellId, procEntry.HitMask);
1952 // HitMask is valid for: TAKEN procs, or DONE procs at any phase (CAST phase has pre-calculated crit for travel-time spells)
1953 if (procEntry.HitMask && !(procEntry.ProcFlags & TAKEN_HIT_PROC_FLAG_MASK || procEntry.ProcFlags & DONE_HIT_PROC_FLAG_MASK))
1954 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);
1955 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1956 if ((procEntry.DisableEffectsMask & (1u << i)) && !spellInfo->Effects[i].IsAura())
1957 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));
1958 if (procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD)
1959 {
1960 bool found = false;
1961 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1962 {
1963 if (!spellInfo->Effects[i].IsAura())
1964 continue;
1965
1966 if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_ADD_PCT_MODIFIER || spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_ADD_FLAT_MODIFIER)
1967 {
1968 found = true;
1969 break;
1970 }
1971 }
1972
1973 if (!found)
1974 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);
1975 }
1976
1977 mSpellProcMap[spellInfo->Id] = procEntry;
1978
1979 if (allRanks)
1980 spellInfo = spellInfo->GetNextRankSpell();
1981 else
1982 break;
1983 }
1984 ++count;
1985 } while (result->NextRow());
1986
1987 LOG_INFO("server.loading", ">> Loaded {} spell proc conditions and data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1988 LOG_INFO("server.loading", " ");
1989
1990 // Generate default procs for spells with proc flags but no explicit spell_proc entry
1991 // This ensures backward compatibility and covers spells that rely on DBC data
1992 LOG_INFO("server.loading", "Generating spell proc data from SpellMap...");
1993 count = 0;
1994 oldMSTime = getMSTime();
1995
1996 for (SpellInfo const* spellInfo : mSpellInfoMap)
1997 {
1998 if (!spellInfo)
1999 continue;
2000
2001 // Skip if already has explicit entry
2002 if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end())
2003 continue;
2004
2005 // Check if spell has any trigger aura effects
2006 bool found = false, addTriggerFlag = false;
2007 uint32 procSpellTypeMask = PROC_SPELL_TYPE_NONE;
2008 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2009 {
2010 if (!spellInfo->Effects[i].IsEffect())
2011 continue;
2012
2013 uint32 auraName = spellInfo->Effects[i].ApplyAuraName;
2014 if (!auraName)
2015 continue;
2016
2017 if (!isTriggerAura[auraName])
2018 continue;
2019
2020 found = true;
2021 procSpellTypeMask |= spellTypeMask[auraName];
2022
2023 if (!addTriggerFlag && isAlwaysTriggeredAura[auraName])
2024 addTriggerFlag = true;
2025
2026 // Many proc auras with taken procFlag mask don't have
2027 // attribute "can proc with triggered" — they should
2028 // proc nevertheless (e.g. mage armor spells with
2029 // judgement)
2030 if (!addTriggerFlag
2031 && (spellInfo->ProcFlags & TAKEN_HIT_PROC_FLAG_MASK))
2032 {
2033 switch (auraName)
2034 {
2037 addTriggerFlag = true;
2038 break;
2039 default:
2040 break;
2041 }
2042 }
2043 }
2044
2045 if (!found)
2046 continue;
2047
2048 // Skip if no proc flags in DBC
2049 if (!spellInfo->ProcFlags)
2050 continue;
2051
2052 // Generate default proc entry from DBC data
2053 SpellProcEntry procEntry;
2054 procEntry.SchoolMask = 0;
2055 procEntry.SpellFamilyMask[0] = 0;
2056 procEntry.SpellFamilyMask[1] = 0;
2057 procEntry.SpellFamilyMask[2] = 0;
2058 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2059 if (spellInfo->Effects[i].IsEffect() && isTriggerAura[spellInfo->Effects[i].ApplyAuraName])
2060 procEntry.SpellFamilyMask |= spellInfo->Effects[i].SpellClassMask;
2061
2062 if (procEntry.SpellFamilyMask)
2063 procEntry.SpellFamilyName = spellInfo->SpellFamilyName;
2064 else
2065 procEntry.SpellFamilyName = 0;
2066
2067 procEntry.ProcFlags = spellInfo->ProcFlags;
2068 procEntry.SpellTypeMask = procSpellTypeMask;
2070 procEntry.HitMask = PROC_HIT_NONE; // uses default proc @see SpellMgr::CanSpellTriggerProcOnEvent
2071
2072 // Reflect auras should only proc off reflects
2073 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2074 {
2075 if (spellInfo->Effects[i].IsAura(SPELL_AURA_REFLECT_SPELLS) || spellInfo->Effects[i].IsAura(SPELL_AURA_REFLECT_SPELLS_SCHOOL))
2076 {
2077 procEntry.HitMask = PROC_HIT_REFLECT;
2078 break;
2079 }
2080 }
2081
2082 procEntry.AttributesMask = 0;
2083 if (spellInfo->ProcFlags & PROC_FLAG_KILL)
2085 if (addTriggerFlag)
2087
2088 // Modifier auras with charges should require spellmod validation
2089 if (spellInfo->ProcCharges)
2090 {
2091 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2092 {
2093 if (spellInfo->Effects[i].IsAura(SPELL_AURA_ADD_FLAT_MODIFIER) ||
2094 spellInfo->Effects[i].IsAura(SPELL_AURA_ADD_PCT_MODIFIER))
2095 {
2097 break;
2098 }
2099 }
2100 }
2101
2102 // Calculate DisableEffectsMask for effects that shouldn't trigger procs
2103 uint32 nonProcMask = 0;
2104 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2105 {
2106 if (!spellInfo->Effects[i].IsAura())
2107 continue;
2108 if (!isTriggerAura[spellInfo->Effects[i].ApplyAuraName])
2109 nonProcMask |= 1u << i;
2110 }
2111 procEntry.DisableEffectsMask = nonProcMask;
2112
2113 procEntry.ProcsPerMinute = 0;
2114 procEntry.Chance = static_cast<float>(spellInfo->ProcChance);
2115 procEntry.Cooldown = Milliseconds::zero();
2116 procEntry.Charges = spellInfo->ProcCharges;
2117
2118 mSpellProcMap[spellInfo->Id] = procEntry;
2119 ++count;
2120 }
2121
2122 LOG_INFO("server.loading", ">> Generated spell proc data for {} spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2123 LOG_INFO("server.loading", " ");
2124}
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:1769
static uint32 spellTypeMask[TOTAL_AURAS]
Definition SpellMgr.cpp:1770
static bool isTriggerAura[TOTAL_AURAS]
Definition SpellMgr.cpp:1768
@ 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:2399
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 ( )
1199{
1200 // cleanup data and load spell ranks for talents from dbc
1202
1203 uint32 oldMSTime = getMSTime();
1204
1205 // 0 1 2
1206 QueryResult result = WorldDatabase.Query("SELECT first_spell_id, spell_id, `rank` from spell_ranks ORDER BY first_spell_id, `rank`");
1207
1208 if (!result)
1209 {
1210 LOG_WARN("server.loading", ">> Loaded 0 spell rank records. DB table `spell_ranks` is empty.");
1211 LOG_INFO("server.loading", " ");
1212 return;
1213 }
1214
1215 uint32 count = 0;
1216 bool finished = false;
1217
1218 do
1219 {
1220 // spellid, rank
1221 std::list < std::pair < int32, int32 > > rankChain;
1222 int32 currentSpell = -1;
1223 int32 lastSpell = -1;
1224
1225 // fill one chain
1226 while (currentSpell == lastSpell && !finished)
1227 {
1228 Field* fields = result->Fetch();
1229
1230 currentSpell = fields[0].Get<uint32>();
1231 if (lastSpell == -1)
1232 lastSpell = currentSpell;
1233 uint32 spell_id = fields[1].Get<uint32>();
1234 uint32 rank = fields[2].Get<uint8>();
1235
1236 // don't drop the row if we're moving to the next rank
1237 if (currentSpell == lastSpell)
1238 {
1239 rankChain.push_back(std::make_pair(spell_id, rank));
1240 if (!result->NextRow())
1241 finished = true;
1242 }
1243 else
1244 break;
1245 }
1246 // check if chain is made with valid first spell
1247 SpellInfo const* first = GetSpellInfo(lastSpell);
1248 if (!first)
1249 {
1250 LOG_ERROR("sql.sql", "Spell rank identifier(first_spell_id) {} listed in `spell_ranks` does not exist!", lastSpell);
1251 continue;
1252 }
1253 // check if chain is long enough
1254 if (rankChain.size() < 2)
1255 {
1256 LOG_ERROR("sql.sql", "There is only 1 spell rank for identifier(first_spell_id) {} in `spell_ranks`, entry is not needed!", lastSpell);
1257 continue;
1258 }
1259 int32 curRank = 0;
1260 bool valid = true;
1261 // check spells in chain
1262 for (std::list<std::pair<int32, int32> >::iterator itr = rankChain.begin(); itr != rankChain.end(); ++itr)
1263 {
1264 SpellInfo const* spell = GetSpellInfo(itr->first);
1265 if (!spell)
1266 {
1267 LOG_ERROR("sql.sql", "Spell {} (rank {}) listed in `spell_ranks` for chain {} does not exist!", itr->first, itr->second, lastSpell);
1268 valid = false;
1269 break;
1270 }
1271 ++curRank;
1272 if (itr->second != curRank)
1273 {
1274 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);
1275 valid = false;
1276 break;
1277 }
1278 }
1279 if (!valid)
1280 continue;
1281 int32 prevRank = 0;
1282 // insert the chain
1283 std::list<std::pair<int32, int32> >::iterator itr = rankChain.begin();
1284 do
1285 {
1286 ++count;
1287 int32 addedSpell = itr->first;
1288 mSpellChains[addedSpell].first = GetSpellInfo(lastSpell);
1289 mSpellChains[addedSpell].last = GetSpellInfo(rankChain.back().first);
1290 mSpellChains[addedSpell].rank = itr->second;
1291 mSpellChains[addedSpell].prev = GetSpellInfo(prevRank);
1292 mSpellInfoMap[addedSpell]->ChainEntry = &mSpellChains[addedSpell];
1293 prevRank = addedSpell;
1294 ++itr;
1295 if (itr == rankChain.end())
1296 {
1297 mSpellChains[addedSpell].next = nullptr;
1298 break;
1299 }
1300 else
1301 mSpellChains[addedSpell].next = GetSpellInfo(itr->first);
1302 } while (true);
1303 } while (!finished);
1304
1305 LOG_INFO("server.loading", ">> Loaded {} spell rank records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1306 LOG_INFO("server.loading", " ");
1307}
void LoadSpellTalentRanks()
Definition SpellMgr.cpp:1137

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

◆ LoadSpellRequired()

void SpellMgr::LoadSpellRequired ( )
1310{
1311 uint32 oldMSTime = getMSTime();
1312
1313 mSpellsReqSpell.clear(); // need for reload case
1314 mSpellReq.clear(); // need for reload case
1315
1316 // 0 1
1317 QueryResult result = WorldDatabase.Query("SELECT spell_id, req_spell from spell_required");
1318
1319 if (!result)
1320 {
1321 LOG_WARN("server.loading", ">> Loaded 0 spell required records. DB table `spell_required` is empty.");
1322 LOG_INFO("server.loading", " ");
1323 return;
1324 }
1325
1326 uint32 count = 0;
1327 do
1328 {
1329 Field* fields = result->Fetch();
1330
1331 uint32 spellId = fields[0].Get<uint32>();
1332 uint32 spellReq = fields[1].Get<uint32>();
1333
1334 // check if chain is made with valid first spell
1335 SpellInfo const* spellInfo = GetSpellInfo(spellId);
1336 if (!spellInfo)
1337 {
1338 LOG_ERROR("sql.sql", "spell_id {} in `spell_required` table is not found in dbcs, skipped", spellId);
1339 continue;
1340 }
1341
1342 SpellInfo const* reqSpellInfo = GetSpellInfo(spellReq);
1343 if (!reqSpellInfo)
1344 {
1345 LOG_ERROR("sql.sql", "req_spell {} in `spell_required` table is not found in dbcs, skipped", spellReq);
1346 continue;
1347 }
1348
1349 if (GetFirstSpellInChain(spellId) == GetFirstSpellInChain(spellReq))
1350 {
1351 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);
1352 continue;
1353 }
1354
1355 if (IsSpellRequiringSpell(spellId, spellReq))
1356 {
1357 LOG_ERROR("sql.sql", "duplicated entry of req_spell {} and spell_id {} in `spell_required`, skipped", spellReq, spellId);
1358 continue;
1359 }
1360
1361 mSpellReq.insert (std::pair<uint32, uint32>(spellId, spellReq));
1362 mSpellsReqSpell.insert (std::pair<uint32, uint32>(spellReq, spellId));
1363 ++count;
1364
1365 // xinef: fill additionalTalentInfo data, currently Blessing of Sanctuary only
1366 if (GetTalentSpellCost(spellReq) > 0)
1367 mTalentSpellAdditionalSet.insert(spellId);
1368 } while (result->NextRow());
1369
1370 LOG_INFO("server.loading", ">> Loaded {} Spell Required Records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1371 LOG_INFO("server.loading", " ");
1372}
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 ( )
2942{
2943 uint32 oldMSTime = getMSTime();
2944
2945 SpellInfo* spellInfo = nullptr;
2946 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2947 {
2948 spellInfo = mSpellInfoMap[i];
2949 if (!spellInfo)
2950 continue;
2951 spellInfo->_spellSpecific = spellInfo->LoadSpellSpecific();
2952 spellInfo->_auraState = spellInfo->LoadAuraState();
2953 }
2954
2955 LOG_INFO("server.loading", ">> Loaded Spell Specific And Aura State in {} ms", GetMSTimeDiffToNow(oldMSTime));
2956 LOG_INFO("server.loading", " ");
2957}
SpellSpecificType LoadSpellSpecific() const
Definition SpellInfo.cpp:2036
AuraStateType LoadAuraState() const
Definition SpellInfo.cpp:1958
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 ( )
1138{
1139 // cleanup core data before reload - remove reference to ChainNode from SpellInfo
1141
1142 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1143 {
1144 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
1145 if (!talentInfo)
1146 continue;
1147
1148 SpellInfo const* lastSpell = nullptr;
1149 for (uint8 rank = MAX_TALENT_RANK - 1; rank > 0; --rank)
1150 {
1151 if (talentInfo->RankID[rank])
1152 {
1153 lastSpell = GetSpellInfo(talentInfo->RankID[rank]);
1154 break;
1155 }
1156 }
1157
1158 if (!lastSpell)
1159 continue;
1160
1161 SpellInfo const* firstSpell = GetSpellInfo(talentInfo->RankID[0]);
1162 if (!firstSpell)
1163 {
1164 LOG_ERROR("sql.sql", "SpellMgr::LoadSpellTalentRanks: First Rank Spell {} for TalentEntry {} does not exist.", talentInfo->RankID[0], i);
1165 continue;
1166 }
1167
1168 SpellInfo const* prevSpell = nullptr;
1169 for (uint8 rank = 0; rank < MAX_TALENT_RANK; ++rank)
1170 {
1171 uint32 spellId = talentInfo->RankID[rank];
1172 if (!spellId)
1173 break;
1174
1175 SpellInfo const* currentSpell = GetSpellInfo(spellId);
1176 if (!currentSpell)
1177 {
1178 LOG_ERROR("sql.sql", "SpellMgr::LoadSpellTalentRanks: Spell {} (Rank: {}) for TalentEntry {} does not exist.", spellId, rank + 1, i);
1179 break;
1180 }
1181
1182 SpellChainNode node;
1183 node.first = firstSpell;
1184 node.last = lastSpell;
1185 node.rank = rank + 1;
1186
1187 node.prev = prevSpell;
1188 node.next = node.rank < MAX_TALENT_RANK ? GetSpellInfo(talentInfo->RankID[node.rank]) : nullptr;
1189
1190 mSpellChains[spellId] = node;
1191 mSpellInfoMap[spellId]->ChainEntry = &mSpellChains[spellId];
1192
1193 prevSpell = currentSpell;
1194 }
1195 }
1196}
void UnloadSpellInfoChains()
Definition SpellMgr.cpp:1129
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 ( )
1428{
1429 uint32 oldMSTime = getMSTime();
1430
1431 mSpellTargetPositions.clear(); // need for reload case
1432
1433 // 0 1 2 3 4 5 6
1434 QueryResult result = WorldDatabase.Query("SELECT ID, EffectIndex, MapID, PositionX, PositionY, PositionZ, Orientation FROM spell_target_position");
1435
1436 if (!result)
1437 {
1438 LOG_WARN("server.loading", ">> Loaded 0 spell target coordinates. DB table `spell_target_position` is empty.");
1439 LOG_INFO("server.loading", " ");
1440 return;
1441 }
1442
1443 uint32 count = 0;
1444 do
1445 {
1446 Field* fields = result->Fetch();
1447
1448 uint32 Spell_ID = fields[0].Get<uint32>();
1449
1450 SpellEffIndex effIndex = SpellEffIndex(fields[1].Get<uint8>());
1451
1453
1454 st.target_mapId = fields[2].Get<uint16>();
1455 st.target_X = fields[3].Get<float>();
1456 st.target_Y = fields[4].Get<float>();
1457 st.target_Z = fields[5].Get<float>();
1458 st.target_Orientation = fields[6].Get<float>();
1459
1460 MapEntry const* mapEntry = sMapStore.LookupEntry(st.target_mapId);
1461 if (!mapEntry)
1462 {
1463 LOG_ERROR("sql.sql", "Spell (Id: {}, effIndex: {}) target map (ID: {}) does not exist in `Map.dbc`.", Spell_ID, effIndex, st.target_mapId);
1464 continue;
1465 }
1466
1467 if (st.target_X == 0 && st.target_Y == 0 && st.target_Z == 0)
1468 {
1469 LOG_ERROR("sql.sql", "Spell (Id: {}, effIndex: {}) target coordinates not provided.", Spell_ID, effIndex);
1470 continue;
1471 }
1472
1473 SpellInfo const* spellInfo = GetSpellInfo(Spell_ID);
1474 if (!spellInfo)
1475 {
1476 LOG_ERROR("sql.sql", "Spell (ID:{}) listed in `spell_target_position` does not exist.", Spell_ID);
1477 continue;
1478 }
1479
1480 if (spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_DEST_DB || spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_DEST_DB)
1481 {
1482 std::pair<uint32, SpellEffIndex> key = std::make_pair(Spell_ID, effIndex);
1483 mSpellTargetPositions[key] = st;
1484 ++count;
1485 }
1486 else
1487 {
1488 LOG_ERROR("sql.sql", "Spell (Id: {}, effIndex: {}) listed in `spell_target_position` does not have target TARGET_DEST_DB (17).", Spell_ID, effIndex);
1489 continue;
1490 }
1491 } while (result->NextRow());
1492
1493 /*
1494 // Check all spells
1495 for (uint32 i = 1; i < GetSpellInfoStoreSize; ++i)
1496 {
1497 SpellInfo const* spellInfo = GetSpellInfo(i);
1498 if (!spellInfo)
1499 continue;
1500
1501 bool found = false;
1502 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
1503 {
1504 switch (spellInfo->Effects[j].TargetA)
1505 {
1506 case TARGET_DEST_DB:
1507 found = true;
1508 break;
1509 }
1510 if (found)
1511 break;
1512 switch (spellInfo->Effects[j].TargetB)
1513 {
1514 case TARGET_DEST_DB:
1515 found = true;
1516 break;
1517 }
1518 if (found)
1519 break;
1520 }
1521 if (found)
1522 {
1523 if (!GetSpellTargetPosition(i))
1524 LOG_DEBUG("spells.aura", "Spell (ID: {}) does not have record in `spell_target_position`", i);
1525 }
1526 }*/
1527
1528 LOG_INFO("server.loading", ">> Loaded {} Spell Teleport Coordinates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1529 LOG_INFO("server.loading", " ");
1530}
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 ( )
2168{
2169 uint32 oldMSTime = getMSTime();
2170
2171 mSpellThreatMap.clear(); // need for reload case
2172
2173 // 0 1 2 3
2174 QueryResult result = WorldDatabase.Query("SELECT entry, flatMod, pctMod, apPctMod FROM spell_threat");
2175 if (!result)
2176 {
2177 LOG_WARN("server.loading", ">> Loaded 0 aggro generating spells. DB table `spell_threat` is empty.");
2178 LOG_INFO("server.loading", " ");
2179 return;
2180 }
2181
2182 uint32 count = 0;
2183 do
2184 {
2185 Field* fields = result->Fetch();
2186
2187 uint32 entry = fields[0].Get<uint32>();
2188
2189 if (!GetSpellInfo(entry))
2190 {
2191 LOG_ERROR("sql.sql", "Spell {} listed in `spell_threat` does not exist", entry);
2192 continue;
2193 }
2194
2195 SpellThreatEntry ste;
2196 ste.flatMod = fields[1].Get<int32>();
2197 ste.pctMod = fields[2].Get<float>();
2198 ste.apPctMod = fields[3].Get<float>();
2199
2200 mSpellThreatMap[entry] = ste;
2201 ++count;
2202 } while (result->NextRow());
2203
2204 LOG_INFO("server.loading", ">> Loaded {} SpellThreatEntries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2205 LOG_INFO("server.loading", " ");
2206}
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 ( )
1130{
1131 for (SpellChainMap::iterator itr = mSpellChains.begin(); itr != mSpellChains.end(); ++itr)
1132 mSpellInfoMap[itr->first]->ChainEntry = nullptr;
1133
1134 mSpellChains.clear();
1135}

References mSpellChains, and mSpellInfoMap.

Referenced by LoadSpellTalentRanks().

◆ UnloadSpellInfoImplicitTargetConditionLists()

void SpellMgr::UnloadSpellInfoImplicitTargetConditionLists ( )
2933{
2934 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2935 {
2936 if (mSpellInfoMap[i])
2937 mSpellInfoMap[i]->_UnloadImplicitTargetConditionLists();
2938 }
2939}

References GetSpellInfoStoreSize(), and mSpellInfoMap.

◆ UnloadSpellInfoStore()

void SpellMgr::UnloadSpellInfoStore ( )
2925{
2926 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2927 delete mSpellInfoMap[i];
2928
2929 mSpellInfoMap.clear();
2930}

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: