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
 
SpellRequiredMapBounds 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
 
SpellProcEventEntry const * GetSpellProcEvent (uint32 spellId) const
 
bool IsSpellProcEventCanTriggeredBy (SpellInfo const *spellProto, SpellProcEventEntry const *spellProcEvent, uint32 EventProcFlag, ProcEventInfo const &eventInfo, bool active) 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 LoadSpellProcEvents ()
 
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
 
SpellProcEventMap mSpellProcEventMap
 
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
352{
353}

◆ ~SpellMgr()

SpellMgr::~SpellMgr ( )
private
356{
358}
void UnloadSpellInfoStore()
Definition SpellMgr.cpp:2943

References UnloadSpellInfoStore().

Member Function Documentation

◆ _GetSpellInfo()

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

References GetSpellInfoStoreSize(), and mSpellInfoMap.

Referenced by LoadSpellInfoCustomAttributes().

◆ AddSameEffectStackRuleSpellGroups()

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

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

◆ AssertSpellInfo()

SpellInfo const * SpellMgr::AssertSpellInfo ( uint32  spellId) const
inline
727 {
728 ASSERT(spellId < GetSpellInfoStoreSize());
729 SpellInfo const* spellInfo = mSpellInfoMap[spellId];
730 ASSERT(spellInfo);
731 return spellInfo;
732 }
#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
956{
957 // proc type doesn't match
958 if (!(eventInfo.GetTypeMask() & procEntry.ProcFlags))
959 return false;
960
961 // check XP or honor target requirement
962 if (procEntry.AttributesMask & PROC_ATTR_REQ_EXP_OR_HONOR)
963 if (Player* actor = eventInfo.GetActor()->ToPlayer())
964 if (eventInfo.GetActionTarget() && !actor->isHonorOrXPTarget(eventInfo.GetActionTarget()))
965 return false;
966
967 // always trigger for these types
969 return true;
970
971 // check school mask (if set) for other trigger types
972 if (procEntry.SchoolMask && !(eventInfo.GetSchoolMask() & procEntry.SchoolMask))
973 return false;
974
975 // check spell family name/flags (if set) for spells
977 {
978 if (procEntry.SpellFamilyName && (procEntry.SpellFamilyName != eventInfo.GetSpellInfo()->SpellFamilyName))
979 return false;
980
981 if (procEntry.SpellFamilyMask && !(procEntry.SpellFamilyMask & eventInfo.GetSpellInfo()->SpellFamilyFlags))
982 return false;
983 }
984
985 // check spell type mask (if set)
987 {
988 if (procEntry.SpellTypeMask && !(eventInfo.GetSpellTypeMask() & procEntry.SpellTypeMask))
989 return false;
990 }
991
992 // check spell phase mask
994 {
995 if (!(eventInfo.GetSpellPhaseMask() & procEntry.SpellPhaseMask))
996 return false;
997 }
998
999 // check hit mask (on taken hit or on done hit, but not on spell cast phase)
1000 if ((eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK) || ((eventInfo.GetTypeMask() & DONE_HIT_PROC_FLAG_MASK) && !(eventInfo.GetSpellPhaseMask() & PROC_SPELL_PHASE_CAST)))
1001 {
1002 uint32 hitMask = procEntry.HitMask;
1003 // get default values if hit mask not set
1004 if (!hitMask)
1005 {
1006 // for taken procs allow normal + critical hits by default
1007 if (eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK)
1009 // for done procs allow normal + critical + absorbs by default
1010 else
1012 }
1013 if (!(eventInfo.GetHitMask() & hitMask))
1014 return false;
1015 }
1016
1017 return true;
1018}
@ PROC_HIT_ABSORB
Definition SpellMgr.h:261
@ PROC_HIT_CRITICAL
Definition SpellMgr.h:252
@ PROC_HIT_NORMAL
Definition SpellMgr.h:251
@ PROC_ATTR_REQ_EXP_OR_HONOR
Definition SpellMgr.h:270
@ PROC_SPELL_PHASE_CAST
Definition SpellMgr.h:242
@ TAKEN_HIT_PROC_FLAG_MASK
Definition SpellMgr.h:172
@ PERIODIC_PROC_FLAG_MASK
Definition SpellMgr.h:164
@ PROC_FLAG_KILLED
Definition SpellMgr.h:106
@ PROC_FLAG_DEATH
Definition SpellMgr.h:142
@ REQ_SPELL_PHASE_PROC_FLAG_MASK
Definition SpellMgr.h:178
@ PROC_FLAG_KILL
Definition SpellMgr.h:107
@ SPELL_PROC_FLAG_MASK
Definition SpellMgr.h:155
@ DONE_HIT_PROC_FLAG_MASK
Definition SpellMgr.h:166
@ PROC_FLAG_DONE_TRAP_ACTIVATION
Definition SpellMgr.h:137
Player * ToPlayer()
Definition Object.h:201
Definition Player.h:1071
uint32 GetHitMask() const
Definition Unit.h:452
SpellSchoolMask GetSchoolMask() const
Definition Unit.h:454
Unit * GetActionTarget() const
Definition Unit.h:447
uint32 GetSpellTypeMask() const
Definition Unit.h:450
uint32 GetTypeMask() const
Definition Unit.h:449
SpellInfo const * GetSpellInfo() const
Definition Unit.cpp:187
Unit * GetActor()
Definition Unit.h:446
uint32 GetSpellPhaseMask() const
Definition Unit.h:451
flag96 SpellFamilyFlags
Definition SpellInfo.h:388
uint32 SpellFamilyName
Definition SpellInfo.h:387

References SpellProcEntry::AttributesMask, DONE_HIT_PROC_FLAG_MASK, ProcEventInfo::GetActionTarget(), ProcEventInfo::GetActor(), ProcEventInfo::GetHitMask(), ProcEventInfo::GetSchoolMask(), ProcEventInfo::GetSpellInfo(), ProcEventInfo::GetSpellPhaseMask(), ProcEventInfo::GetSpellTypeMask(), ProcEventInfo::GetTypeMask(), SpellProcEntry::HitMask, PERIODIC_PROC_FLAG_MASK, PROC_ATTR_REQ_EXP_OR_HONOR, PROC_FLAG_DEATH, PROC_FLAG_DONE_TRAP_ACTIVATION, 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, SpellInfo::SpellFamilyFlags, SpellProcEntry::SpellFamilyMask, SpellInfo::SpellFamilyName, 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
732{
733 ASSERT(spellInfo1);
734 ASSERT(spellInfo2);
735
736 uint32 spell_id1 = spellInfo1->GetFirstRankSpell()->Id;
737 uint32 spell_id2 = spellInfo2->GetFirstRankSpell()->Id;
738
739 // find SpellGroups which are common for both spells
741 std::set<SpellGroup> groups;
742 for (SpellSpellGroupMap::const_iterator itr = spellGroup1.first; itr != spellGroup1.second; ++itr)
743 {
744 if (IsSpellMemberOfSpellGroup(spell_id2, itr->second))
745 {
746 bool add = true;
748 for (SpellGroupSpellMap::const_iterator itr2 = groupSpell.first; itr2 != groupSpell.second; ++itr2)
749 {
750 if (itr2->second < 0)
751 {
752 SpellGroup currGroup = (SpellGroup)abs(itr2->second);
753 if (IsSpellMemberOfSpellGroup(spell_id1, currGroup) && IsSpellMemberOfSpellGroup(spell_id2, currGroup))
754 {
755 add = false;
756 break;
757 }
758 }
759 }
760 if (add)
761 groups.insert(itr->second);
762 }
763 }
764
766
767 for (std::set<SpellGroup>::iterator itr = groups.begin(); itr!= groups.end(); ++itr)
768 {
769 SpellGroupStackMap::const_iterator found = mSpellGroupStack.find(*itr);
770 if (found != mSpellGroupStack.end())
771 rule = found->second;
772 if (rule)
773 break;
774 }
775 return rule;
776}
std::pair< SpellSpellGroupMap::const_iterator, SpellSpellGroupMap::const_iterator > SpellSpellGroupMapBounds
Definition SpellMgr.h:356
SpellGroupStackRule
Definition SpellMgr.h:363
@ SPELL_GROUP_STACK_RULE_DEFAULT
Definition SpellMgr.h:364
std::pair< SpellGroupSpellMap::const_iterator, SpellGroupSpellMap::const_iterator > SpellGroupSpellMapBounds
Definition SpellMgr.h:360
SpellGroupSpellMapBounds GetSpellGroupSpellMapBounds(SpellGroup group_id) const
Definition SpellMgr.cpp:665
bool IsSpellMemberOfSpellGroup(uint32 spell_id, SpellGroup group_id) const
Definition SpellMgr.cpp:654
SpellGroupStackMap mSpellGroupStack
Definition SpellMgr.h:801

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
735 {
736 if (spellId >= GetSpellInfoStoreSize())
737 {
738 LOG_ERROR("server", "spellId {} is not lower than GetSpellInfoStoreSize() ({})", spellId, GetSpellInfoStoreSize());
739 return nullptr;
740 }
741 SpellInfo const* spellInfo = mSpellInfoMap[spellId];
742 if (!spellInfo)
743 {
744 LOG_ERROR("server", "spellId {} has invalid spellInfo", spellId);
745 return nullptr;
746 }
747 return spellInfo;
748 }
#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
457{
458 if (!spellInfo)
459 {
461 LOG_ERROR("spells", "Player::{}: Non-existed in SpellStore spell #{} request.", (isTalent ? "AddTalent" : "addSpell"), spellId);
462 return false;
463 }
464
465 if (!IsSpellValid(spellInfo))
466 {
468 LOG_ERROR("spells", "Player::{}: Broken spell #{} learning not allowed.", (isTalent ? "AddTalent" : "addSpell"), spellId);
469 return false;
470 }
471
472 return true;
473}
void DeleteSpellFromAllPlayers(uint32 spellId)
Definition SpellMgr.cpp:445
static bool IsSpellValid(SpellInfo const *spellInfo)
Definition SpellMgr.cpp:438

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.

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

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 ObjectMgr::AddSpellToTrainer(), ComputeIsSpellValid(), ObjectMgr::InitializeSpellInfoPrecomputedData(), and ObjectMgr::LoadQuests().

◆ GetFirstSpellInChain()

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

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

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

◆ GetLastSpellInChain()

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

References GetSpellChainNode().

◆ GetNextSpellInChain()

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

References GetSpellChainNode().

◆ GetPetAura()

PetAura const * SpellMgr::GetPetAura ( uint32  spell_id,
uint8  eff 
) const
1066{
1067 SpellPetAuraMap::const_iterator itr = mSpellPetAuraMap.find((spell_id << 8) + eff);
1068 if (itr != mSpellPetAuraMap.end())
1069 return &itr->second;
1070 else
1071 return nullptr;
1072}
SpellPetAuraMap mSpellPetAuraMap
Definition SpellMgr.h:808

References mSpellPetAuraMap.

◆ GetPetDefaultSpellsEntry()

PetDefaultSpellsEntry const * SpellMgr::GetPetDefaultSpellsEntry ( int32  id) const
1103{
1104 PetDefaultSpellsMap::const_iterator itr = mPetDefaultSpellsMap.find(id);
1105 if (itr != mPetDefaultSpellsMap.end())
1106 return &itr->second;
1107 return nullptr;
1108}
PetDefaultSpellsMap mPetDefaultSpellsMap
Definition SpellMgr.h:819

References mPetDefaultSpellsMap.

◆ GetPetLevelupSpellList()

PetLevelupSpellSet const * SpellMgr::GetPetLevelupSpellList ( uint32  petFamily) const
1094{
1095 PetLevelupSpellMap::const_iterator itr = mPetLevelupSpellMap.find(petFamily);
1096 if (itr != mPetLevelupSpellMap.end())
1097 return &itr->second;
1098 else
1099 return nullptr;
1100}
PetLevelupSpellMap mPetLevelupSpellMap
Definition SpellMgr.h:818

References mPetLevelupSpellMap.

◆ GetPrevSpellInChain()

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

References GetSpellChainNode().

◆ GetSetOfSpellsInSpellGroup() [1/2]

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

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

References GetSetOfSpellsInSpellGroup(), and GetSpellGroupSpellMapBounds().

◆ GetSkillLineAbilityMapBounds()

SkillLineAbilityMapBounds SpellMgr::GetSkillLineAbilityMapBounds ( uint32  spell_id) const
1061{
1062 return mSkillLineAbilityMap.equal_range(spell_id);
1063}
SkillLineAbilityMap mSkillLineAbilityMap
Definition SpellMgr.h:817

References mSkillLineAbilityMap.

◆ GetSpellAreaForAreaMapBounds()

SpellAreaForAreaMapBounds SpellMgr::GetSpellAreaForAreaMapBounds ( uint32  area_id) const
1131{
1132 return mSpellAreaForAreaMap.equal_range(area_id);
1133}
SpellAreaForAreaMap mSpellAreaForAreaMap
Definition SpellMgr.h:816

References mSpellAreaForAreaMap.

◆ GetSpellAreaForAuraMapBounds()

SpellAreaForAuraMapBounds SpellMgr::GetSpellAreaForAuraMapBounds ( uint32  spell_id) const
1126{
1127 return mSpellAreaForAuraMap.equal_range(spell_id);
1128}
SpellAreaForAuraMap mSpellAreaForAuraMap
Definition SpellMgr.h:815

References mSpellAreaForAuraMap.

Referenced by LoadSpellAreas().

◆ GetSpellAreaForQuestEndMapBounds()

SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestEndMapBounds ( uint32  quest_id) const
1121{
1122 return mSpellAreaForQuestEndMap.equal_range(quest_id);
1123}
SpellAreaForQuestMap mSpellAreaForQuestEndMap
Definition SpellMgr.h:814

References mSpellAreaForQuestEndMap.

◆ GetSpellAreaForQuestMapBounds()

SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestMapBounds ( uint32  quest_id) const
1116{
1117 return mSpellAreaForQuestMap.equal_range(quest_id);
1118}
SpellAreaForQuestMap mSpellAreaForQuestMap
Definition SpellMgr.h:813

References mSpellAreaForQuestMap.

◆ GetSpellAreaMapBounds()

SpellAreaMapBounds SpellMgr::GetSpellAreaMapBounds ( uint32  spell_id) const
1111{
1112 return mSpellAreaMap.equal_range(spell_id);
1113}
SpellAreaMap mSpellAreaMap
Definition SpellMgr.h:812

References mSpellAreaMap.

Referenced by LoadSpellAreas().

◆ GetSpellBonusData()

SpellBonusEntry const * SpellMgr::GetSpellBonusData ( uint32  spellId) const
1021{
1022 // Lookup data
1023 SpellBonusMap::const_iterator itr = mSpellBonusMap.find(spellId);
1024 if (itr != mSpellBonusMap.end())
1025 return &itr->second;
1026 // Not found, try lookup for 1 spell rank if exist
1027 if (uint32 rank_1 = GetFirstSpellInChain(spellId))
1028 {
1029 SpellBonusMap::const_iterator itr2 = mSpellBonusMap.find(rank_1);
1030 if (itr2 != mSpellBonusMap.end())
1031 return &itr2->second;
1032 }
1033 return nullptr;
1034}
uint32 GetFirstSpellInChain(uint32 spell_id) const
Definition SpellMgr.cpp:551
SpellBonusMap mSpellBonusMap
Definition SpellMgr.h:805

References GetFirstSpellInChain(), and mSpellBonusMap.

◆ GetSpellChainNode()

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

References mSpellChains.

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

◆ GetSpellCooldownOverride()

SpellCooldownOverride SpellMgr::GetSpellCooldownOverride ( uint32  spellId) const
2938{
2939 auto range = mSpellCooldownOverrideMap.find(spellId);
2940 return range->second;
2941}
SpellCooldownOverrideMap mSpellCooldownOverrideMap
Definition SpellMgr.h:821

References mSpellCooldownOverrideMap.

Referenced by LoadSpellInfoCustomAttributes().

◆ GetSpellDifficultyId()

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

References mSpellDifficultySearcherMap.

Referenced by GetSpellIdForDifficulty().

◆ GetSpellEnchantProcEvent()

SpellEnchantProcEntry const * SpellMgr::GetSpellEnchantProcEvent ( uint32  enchId) const
1075{
1076 SpellEnchantProcEventMap::const_iterator itr = mSpellEnchantProcEventMap.find(enchId);
1077 if (itr != mSpellEnchantProcEventMap.end())
1078 return &itr->second;
1079 return nullptr;
1080}
SpellEnchantProcEventMap mSpellEnchantProcEventMap
Definition SpellMgr.h:810

References mSpellEnchantProcEventMap.

◆ GetSpellForDifficultyFromSpell()

SpellInfo const * SpellMgr::GetSpellForDifficultyFromSpell ( SpellInfo const *  spell,
Unit const *  caster 
) const
529{
530 uint32 newSpellId = GetSpellIdForDifficulty(spell->Id, caster);
531 SpellInfo const* newSpell = GetSpellInfo(newSpellId);
532 if (!newSpell)
533 {
534 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellForDifficultyFromSpell: spell {} not found. Check spelldifficulty_dbc!", newSpellId);
535 return spell;
536 }
537
538 LOG_DEBUG("spells.aura", "SpellMgr::GetSpellForDifficultyFromSpell: Spell id for instance mode is {} (original {})", newSpell->Id, spell->Id);
539 return newSpell;
540}
#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:486
SpellInfo const * GetSpellInfo(uint32 spellId) const
Definition SpellMgr.h:724

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

◆ GetSpellGroupSpellMapBounds()

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

References mSpellGroupSpell.

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

◆ GetSpellGroupStackRule()

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

References mSpellGroupStack, and SPELL_GROUP_STACK_RULE_DEFAULT.

◆ GetSpellIdForDifficulty()

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

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
632{
633 SpellLearnSkillMap::const_iterator itr = mSpellLearnSkills.find(spell_id);
634 if (itr != mSpellLearnSkills.end())
635 return &itr->second;
636 else
637 return nullptr;
638}
SpellLearnSkillMap mSpellLearnSkills
Definition SpellMgr.h:797

References mSpellLearnSkills.

◆ GetSpellLinked()

const std::vector< int32 > * SpellMgr::GetSpellLinked ( int32  spell_id) const
1088{
1089 SpellLinkedMap::const_iterator itr = mSpellLinkedMap.find(spell_id);
1090 return itr != mSpellLinkedMap.end() ? &(itr->second) : nullptr;
1091}
SpellLinkedMap mSpellLinkedMap
Definition SpellMgr.h:809

References mSpellLinkedMap.

◆ GetSpellMixologyBonus()

float SpellMgr::GetSpellMixologyBonus ( uint32  spellId) const
1052{
1053 SpellMixologyMap::const_iterator itr = mSpellMixologyMap.find(spellId);
1054 if (itr == mSpellMixologyMap.end())
1055 return 30.0f;
1056
1057 return itr->second;
1058}
SpellMixologyMap mSpellMixologyMap
Definition SpellMgr.h:807

References mSpellMixologyMap.

◆ GetSpellProcEntry()

SpellProcEntry const * SpellMgr::GetSpellProcEntry ( uint32  spellId) const
948{
949 SpellProcMap::const_iterator itr = mSpellProcMap.find(spellId);
950 if (itr != mSpellProcMap.end())
951 return &itr->second;
952 return nullptr;
953}
SpellProcMap mSpellProcMap
Definition SpellMgr.h:804

References mSpellProcMap.

◆ GetSpellProcEvent()

SpellProcEventEntry const * SpellMgr::GetSpellProcEvent ( uint32  spellId) const
788{
789 SpellProcEventMap::const_iterator itr = mSpellProcEventMap.find(spellId);
790 if (itr != mSpellProcEventMap.end())
791 return &itr->second;
792 return nullptr;
793}
SpellProcEventMap mSpellProcEventMap
Definition SpellMgr.h:803

References mSpellProcEventMap.

◆ GetSpellRank()

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

References GetSpellChainNode().

◆ GetSpellSpellGroupMapBounds()

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

References GetFirstSpellInChain(), and mSpellSpellGroup.

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

◆ GetSpellsRequiredForSpellBounds()

SpellRequiredMapBounds SpellMgr::GetSpellsRequiredForSpellBounds ( uint32  spell_id) const
606{
607 return mSpellReq.equal_range(spell_id);
608}
SpellRequiredMap mSpellReq
Definition SpellMgr.h:796

References mSpellReq.

◆ GetSpellsRequiringSpellBounds()

SpellsRequiringSpellMapBounds SpellMgr::GetSpellsRequiringSpellBounds ( uint32  spell_id) const
611{
612 return mSpellsReqSpell.equal_range(spell_id);
613}
SpellsRequiringSpellMap mSpellsReqSpell
Definition SpellMgr.h:795

References mSpellsReqSpell.

Referenced by IsSpellRequiringSpell().

◆ GetSpellTargetPosition()

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

References mSpellTargetPositions.

◆ GetSpellThreatEntry()

SpellThreatEntry const * SpellMgr::GetSpellThreatEntry ( uint32  spellID) const
1037{
1038 SpellThreatMap::const_iterator itr = mSpellThreatMap.find(spellID);
1039 if (itr != mSpellThreatMap.end())
1040 return &itr->second;
1041 else
1042 {
1043 uint32 firstSpell = GetFirstSpellInChain(spellID);
1044 itr = mSpellThreatMap.find(firstSpell);
1045 if (itr != mSpellThreatMap.end())
1046 return &itr->second;
1047 }
1048 return nullptr;
1049}
SpellThreatMap mSpellThreatMap
Definition SpellMgr.h:806

References GetFirstSpellInChain(), and mSpellThreatMap.

◆ GetSpellWithRank()

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

References GetSpellChainNode(), and GetSpellWithRank().

Referenced by GetSpellWithRank().

◆ HasSpellCooldownOverride()

bool SpellMgr::HasSpellCooldownOverride ( uint32  spellId) const
2933{
2934 return mSpellCooldownOverrideMap.find(spellId) != mSpellCooldownOverrideMap.end();
2935}

References mSpellCooldownOverrideMap.

Referenced by LoadSpellInfoCustomAttributes().

◆ instance()

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

References instance().

Referenced by instance().

◆ IsAdditionalTalentSpell()

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

References mTalentSpellAdditionalSet.

◆ IsArenaAllowedEnchancment()

bool SpellMgr::IsArenaAllowedEnchancment ( uint32  ench_id) const
1083{
1084 return mEnchantCustomAttr[ench_id];
1085}
EnchantCustomAttribute mEnchantCustomAttr
Definition SpellMgr.h:811

References mEnchantCustomAttr.

◆ IsSpellMemberOfSpellGroup()

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

References GetSpellSpellGroupMapBounds().

Referenced by CheckSpellGroupStackRules().

◆ IsSpellProcEventCanTriggeredBy()

bool SpellMgr::IsSpellProcEventCanTriggeredBy ( SpellInfo const *  spellProto,
SpellProcEventEntry const *  spellProcEvent,
uint32  EventProcFlag,
ProcEventInfo const &  eventInfo,
bool  active 
) const

no aura with only PROC_FLAG_DONE_PERIODIC and spellFamilyName == 0 can proc from a HOT.

Aura must have positive procflags for a HOT to proc

Aura must have negative or neutral(PROC_FLAG_DONE_PERIODIC only) procflags for a DOT to proc

No aura that only has PROC_FLAG_TAKEN_PERIODIC can proc from a HOT.

Aura must have positive procflags for a HOT to proc

Aura must have negative or neutral(PROC_FLAG_TAKEN_PERIODIC only) procflags for a DOT to proc

796{
797 // No extra req need
798 uint32 procEvent_procEx = PROC_EX_NONE;
799 uint32 procEvent_procPhase = PROC_SPELL_PHASE_HIT;
800
801 uint32 procFlags = eventInfo.GetTypeMask();
802 uint32 procExtra = eventInfo.GetHitMask();
803 uint32 procPhase = eventInfo.GetSpellPhaseMask();
804 SpellInfo const* procSpellInfo = eventInfo.GetSpellInfo();
805
806 // check prockFlags for condition
807 if ((procFlags & EventProcFlag) == 0)
808 return false;
809
810 // Xinef: Always trigger for this, including TAKEN_DAMAGE
812 return true;
813
814 bool hasFamilyMask = false;
815
816 if (procFlags & PROC_FLAG_DONE_PERIODIC)
817 {
818 if (procExtra & PROC_EX_INTERNAL_HOT)
819 {
820 if (EventProcFlag == PROC_FLAG_DONE_PERIODIC)
821 {
823 if (!spellProto->SpellFamilyName)
824 return false;
825 }
828 return false;
829 }
831 else if (EventProcFlag != PROC_FLAG_DONE_PERIODIC)
833 return false;
834 }
835
836 if (procFlags & PROC_FLAG_TAKEN_PERIODIC)
837 {
838 if (procExtra & PROC_EX_INTERNAL_HOT)
839 {
841 if (EventProcFlag == PROC_FLAG_TAKEN_PERIODIC)
842 return false;
845 return false;
846 }
848 else if (EventProcFlag != PROC_FLAG_TAKEN_PERIODIC)
850 return false;
851 }
852
853 // Trap casts are active by default
854 if (procFlags & PROC_FLAG_DONE_TRAP_ACTIVATION)
855 active = true;
856
857 if (spellProcEvent) // Exist event data
858 {
859 // Store extra req
860 procEvent_procEx = spellProcEvent->procEx;
861 procEvent_procPhase = spellProcEvent->procPhase;
862
863 // For melee triggers
864 if (!procSpellInfo)
865 {
866 // Check (if set) for school (melee attack have Normal school)
867 if (spellProcEvent->schoolMask && (spellProcEvent->schoolMask & SPELL_SCHOOL_MASK_NORMAL) == 0)
868 return false;
869 }
870 else // For spells need check school/spell family/family mask
871 {
872 // Check (if set) for school
873 if (spellProcEvent->schoolMask && (spellProcEvent->schoolMask & procSpellInfo->SchoolMask) == 0)
874 return false;
875
876 // Check (if set) for spellFamilyName
877 if (spellProcEvent->spellFamilyName && (spellProcEvent->spellFamilyName != procSpellInfo->SpellFamilyName))
878 return false;
879
880 // spellFamilyName is Ok need check for spellFamilyMask if present
881 if (spellProcEvent->spellFamilyMask)
882 {
883 if (!(spellProcEvent->spellFamilyMask & procSpellInfo->SpellFamilyFlags))
884 return false;
885 hasFamilyMask = true;
886 // Some spells are not considered as active even with have spellfamilyflags
887 if (!(procEvent_procEx & PROC_EX_ONLY_ACTIVE_SPELL))
888 active = true;
889 }
890
891 // Check tick numbers
892 if (procEvent_procEx & PROC_EX_ONLY_FIRST_TICK)
893 {
894 if (Spell const* procSpell = eventInfo.GetProcSpell())
895 {
896 if (procSpell->GetTriggeredByAuraTickNumber() > 1)
897 {
898 return false;
899 }
900 }
901 }
902 }
903 }
904
905 if (procExtra & (PROC_EX_INTERNAL_REQ_FAMILY))
906 {
907 if (!hasFamilyMask)
908 return false;
909 }
910
911 if (!(procEvent_procPhase & procPhase))
912 {
913 return false;
914 }
915
916 // Check for extra req (if none) and hit/crit
917 if (procEvent_procEx == PROC_EX_NONE)
918 {
919 // No extra req, so can trigger only for hit/crit - spell has to be active
920 if ((procExtra & (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT)) && active)
921 return true;
922 }
923 else // Passive spells hits here only if resist/reflect/immune/evade
924 {
925 if (procExtra & AURA_SPELL_PROC_EX_MASK)
926 {
927 // if spell marked as procing only from not active spells
928 if (active && procEvent_procEx & PROC_EX_NOT_ACTIVE_SPELL)
929 return false;
930 // if spell marked as procing only from active spells
931 if (!active && procEvent_procEx & PROC_EX_ONLY_ACTIVE_SPELL)
932 return false;
933 // Exist req for PROC_EX_EX_TRIGGER_ALWAYS
934 if (procEvent_procEx & PROC_EX_EX_TRIGGER_ALWAYS)
935 return true;
936 // PROC_EX_NOT_ACTIVE_SPELL and PROC_EX_ONLY_ACTIVE_SPELL flags handle: if passed checks before
937 if ((procExtra & (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT)) && ((procEvent_procEx & (AURA_SPELL_PROC_EX_MASK)) == 0))
938 return true;
939 }
940 // Check Extra Requirement like (hit/crit/miss/resist/parry/dodge/block/immune/reflect/absorb and other)
941 if (procEvent_procEx & procExtra)
942 return true;
943 }
944 return false;
945}
@ SPELL_SCHOOL_MASK_NORMAL
Definition SharedDefines.h:308
#define AURA_SPELL_PROC_EX_MASK
Definition SpellMgr.h:224
@ PROC_EX_NONE
Definition SpellMgr.h:192
@ PROC_EX_CRITICAL_HIT
Definition SpellMgr.h:194
@ PROC_EX_NORMAL_HIT
Definition SpellMgr.h:193
@ PROC_EX_INTERNAL_HOT
Definition SpellMgr.h:219
@ PROC_EX_ONLY_ACTIVE_SPELL
Definition SpellMgr.h:211
@ PROC_EX_ONLY_FIRST_TICK
Definition SpellMgr.h:214
@ PROC_EX_EX_TRIGGER_ALWAYS
Definition SpellMgr.h:209
@ PROC_EX_NOT_ACTIVE_SPELL
Definition SpellMgr.h:208
@ PROC_EX_INTERNAL_REQ_FAMILY
Definition SpellMgr.h:221
@ PROC_SPELL_PHASE_HIT
Definition SpellMgr.h:243
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS
Definition SpellMgr.h:127
@ PROC_FLAG_DONE_PERIODIC
Definition SpellMgr.h:133
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS
Definition SpellMgr.h:121
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG
Definition SpellMgr.h:131
@ PROC_FLAG_TAKEN_PERIODIC
Definition SpellMgr.h:134
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG
Definition SpellMgr.h:125
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG
Definition SpellMgr.h:124
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS
Definition SpellMgr.h:128
@ PROC_FLAG_TAKEN_DAMAGE
Definition SpellMgr.h:136
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS
Definition SpellMgr.h:122
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
Definition SpellMgr.h:130
uint32 SchoolMask
Definition SpellInfo.h:392
Definition Spell.h:295

References AURA_SPELL_PROC_EX_MASK, ProcEventInfo::GetHitMask(), ProcEventInfo::GetProcSpell(), ProcEventInfo::GetSpellInfo(), ProcEventInfo::GetSpellPhaseMask(), ProcEventInfo::GetTypeMask(), PROC_EX_CRITICAL_HIT, PROC_EX_EX_TRIGGER_ALWAYS, PROC_EX_INTERNAL_HOT, PROC_EX_INTERNAL_REQ_FAMILY, PROC_EX_NONE, PROC_EX_NORMAL_HIT, PROC_EX_NOT_ACTIVE_SPELL, PROC_EX_ONLY_ACTIVE_SPELL, PROC_EX_ONLY_FIRST_TICK, PROC_FLAG_DEATH, PROC_FLAG_DONE_PERIODIC, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_DONE_TRAP_ACTIVATION, PROC_FLAG_KILL, PROC_FLAG_KILLED, PROC_FLAG_TAKEN_DAMAGE, PROC_FLAG_TAKEN_PERIODIC, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS, PROC_SPELL_PHASE_HIT, SpellProcEventEntry::procEx, SpellProcEventEntry::procPhase, SpellInfo::SchoolMask, SpellProcEventEntry::schoolMask, SPELL_SCHOOL_MASK_NORMAL, SpellInfo::SpellFamilyFlags, SpellProcEventEntry::spellFamilyMask, SpellInfo::SpellFamilyName, and SpellProcEventEntry::spellFamilyName.

◆ IsSpellRequiringSpell()

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

References GetSpellsRequiringSpellBounds().

Referenced by LoadSpellRequired().

◆ IsSpellValid()

◆ LoadEnchantCustomAttr()

void SpellMgr::LoadEnchantCustomAttr ( )
Todo:
: find a better check
2349{
2350 uint32 oldMSTime = getMSTime();
2351
2352 uint32 size = sSpellItemEnchantmentStore.GetNumRows();
2353 mEnchantCustomAttr.resize(size);
2354
2355 for (uint32 i = 0; i < size; ++i)
2356 mEnchantCustomAttr[i] = 0;
2357
2358 uint32 count = 0;
2359 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2360 {
2361 SpellInfo const* spellInfo = GetSpellInfo(i);
2362 if (!spellInfo)
2363 continue;
2364
2366 // Xinef: commented second part, fixes warlock enchants like firestone, spellstone
2367 if (!spellInfo->HasAttribute(SPELL_ATTR2_ENCHANT_OWN_ITEM_ONLY)/* || !spellInfo->HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFTED)*/)
2368 continue;
2369
2370 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
2371 {
2372 if (spellInfo->Effects[j].Effect == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY)
2373 {
2374 uint32 enchId = spellInfo->Effects[j].MiscValue;
2375 SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchId);
2376 if (!ench)
2377 continue;
2378 mEnchantCustomAttr[enchId] = true;
2379 ++count;
2380 break;
2381 }
2382 }
2383 }
2384
2385 LOG_INFO("server.loading", ">> Loaded {} Custom Enchant Attributes in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2386 LOG_INFO("server.loading", " ");
2387}
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
#define LOG_INFO(filterType__,...)
Definition Log.h:166
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition SharedDefines.h:843
@ SPELL_ATTR2_ENCHANT_OWN_ITEM_ONLY
Definition SharedDefines.h:480
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:1839

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 ( )
2582{
2583 uint32 oldMSTime = getMSTime();
2584
2585 mPetDefaultSpellsMap.clear();
2586
2587 uint32 countCreature = 0;
2588 uint32 countData = 0;
2589
2590 CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
2591 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
2592 {
2593 if (!itr->second.PetSpellDataId)
2594 continue;
2595
2596 // for creature with PetSpellDataId get default pet spells from dbc
2597 CreatureSpellDataEntry const* spellDataEntry = sCreatureSpellDataStore.LookupEntry(itr->second.PetSpellDataId);
2598 if (!spellDataEntry)
2599 continue;
2600
2601 int32 petSpellsId = -int32(itr->second.PetSpellDataId);
2602 PetDefaultSpellsEntry petDefSpells;
2603 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2604 petDefSpells.spellid[j] = spellDataEntry->spellId[j];
2605
2606 if (LoadPetDefaultSpells_helper(&itr->second, petDefSpells))
2607 {
2608 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2609 ++countData;
2610 }
2611 }
2612
2613 LOG_INFO("server.loading", ">> Loaded Addition Spells For {} Pet Spell Data Entries in {} ms", countData, GetMSTimeDiffToNow(oldMSTime));
2614 LOG_INFO("server.loading", " ");
2615
2616 LOG_INFO("server.loading", "Loading Summonable Creature Templates...");
2617 oldMSTime = getMSTime();
2618
2619 // different summon spells
2620 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2621 {
2622 SpellInfo const* spellInfo = GetSpellInfo(i);
2623 if (!spellInfo)
2624 continue;
2625
2626 for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
2627 {
2628 if (spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON || spellInfo->Effects[k].Effect == SPELL_EFFECT_SUMMON_PET)
2629 {
2630 uint32 creature_id = spellInfo->Effects[k].MiscValue;
2631 CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id);
2632 if (!cInfo)
2633 continue;
2634
2635 // already loaded
2636 if (cInfo->PetSpellDataId)
2637 continue;
2638
2639 // for creature without PetSpellDataId get default pet spells from creature_template
2640 int32 petSpellsId = cInfo->Entry;
2641 if (mPetDefaultSpellsMap.find(cInfo->Entry) != mPetDefaultSpellsMap.end())
2642 continue;
2643
2644 PetDefaultSpellsEntry petDefSpells;
2645 for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2646 petDefSpells.spellid[j] = cInfo->spells[j];
2647
2648 if (LoadPetDefaultSpells_helper(cInfo, petDefSpells))
2649 {
2650 mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2651 ++countCreature;
2652 }
2653 }
2654 }
2655 }
2656
2657 LOG_INFO("server.loading", ">> Loaded {} Summonable Creature emplates in {} ms", countCreature, GetMSTimeDiffToNow(oldMSTime));
2658 LOG_INFO("server.loading", " ");
2659}
std::unordered_map< uint32, CreatureTemplate > CreatureTemplateContainer
Definition CreatureData.h:292
DBCStorage< CreatureSpellDataEntry > sCreatureSpellDataStore(CreatureSpellDatafmt)
#define MAX_CREATURE_SPELL_DATA_SLOT
Definition DBCStructure.h:807
@ SPELL_EFFECT_SUMMON_PET
Definition SharedDefines.h:845
@ SPELL_EFFECT_SUMMON
Definition SharedDefines.h:817
static bool LoadPetDefaultSpells_helper(CreatureTemplate const *cInfo, PetDefaultSpellsEntry &petDefSpells)
Definition SpellMgr.cpp:2533
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:228
uint32 PetSpellDataId
Definition CreatureData.h:229
Definition SpellMgr.h:584
uint32 spellid[MAX_CREATURE_SPELL_DATA_SLOT]
Definition SpellMgr.h:585

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 ( )
2488{
2489 uint32 oldMSTime = getMSTime();
2490
2491 mPetLevelupSpellMap.clear(); // need for reload case
2492
2493 uint32 count = 0;
2494 uint32 family_count = 0;
2495
2496 for (uint32 i = 0; i < sCreatureFamilyStore.GetNumRows(); ++i)
2497 {
2498 CreatureFamilyEntry const* creatureFamily = sCreatureFamilyStore.LookupEntry(i);
2499 if (!creatureFamily) // not exist
2500 continue;
2501
2502 for (uint8 j = 0; j < 2; ++j)
2503 {
2504 if (!creatureFamily->skillLine[j])
2505 continue;
2506
2507 for (SkillLineAbilityEntry const* skillLine : GetSkillLineAbilitiesBySkillLine(creatureFamily->skillLine[j]))
2508 {
2509 if (skillLine->AcquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN)
2510 continue;
2511
2512 SpellInfo const* spell = GetSpellInfo(skillLine->Spell);
2513 if (!spell) // not exist or triggered or talent
2514 continue;
2515
2516 if (!spell->SpellLevel)
2517 continue;
2518
2519 PetLevelupSpellSet& spellSet = mPetLevelupSpellMap[creatureFamily->ID];
2520 if (spellSet.empty())
2521 ++family_count;
2522
2523 spellSet.insert(PetLevelupSpellSet::value_type(spell->SpellLevel, spell->Id));
2524 ++count;
2525 }
2526 }
2527 }
2528
2529 LOG_INFO("server.loading", ">> Loaded {} Pet Levelup And Default Spells For {} Families in {} ms", count, family_count, GetMSTimeDiffToNow(oldMSTime));
2530 LOG_INFO("server.loading", " ");
2531}
@ 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:578
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:1596

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 ( )
2264{
2265 uint32 oldMSTime = getMSTime();
2266
2267 mSkillLineAbilityMap.clear();
2268
2269 uint32 count = 0;
2270
2271 for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); ++i)
2272 {
2273 SkillLineAbilityEntry const* SkillInfo = sSkillLineAbilityStore.LookupEntry(i);
2274 if (!SkillInfo)
2275 continue;
2276
2277 mSkillLineAbilityMap.insert(SkillLineAbilityMap::value_type(SkillInfo->Spell, SkillInfo));
2278 ++count;
2279 }
2280
2281 LOG_INFO("server.loading", ">> Loaded {} SkillLineAbility MultiMap Data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2282 LOG_INFO("server.loading", " ");
2283}
DBCStorage< SkillLineAbilityEntry > sSkillLineAbilityStore(SkillLineAbilityfmt)
uint32 Spell
Definition DBCStructure.h:1599

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

◆ LoadSpellAreas()

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

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, RACEMASK_ALL_PLAYABLE, sAreaTableStore, sObjectMgr, SPELL_ATTR0_NO_AURA_CANCEL, SpellArea::spellId, sWorld, and WorldDatabase.

◆ LoadSpellBonuses()

void SpellMgr::LoadSpellBonuses ( )
2146{
2147 uint32 oldMSTime = getMSTime();
2148
2149 mSpellBonusMap.clear(); // need for reload case
2150
2151 // 0 1 2 3 4
2152 QueryResult result = WorldDatabase.Query("SELECT entry, direct_bonus, dot_bonus, ap_bonus, ap_dot_bonus FROM spell_bonus_data");
2153 if (!result)
2154 {
2155 LOG_WARN("server.loading", ">> Loaded 0 spell bonus data. DB table `spell_bonus_data` is empty.");
2156 LOG_INFO("server.loading", " ");
2157 return;
2158 }
2159
2160 uint32 count = 0;
2161 do
2162 {
2163 Field* fields = result->Fetch();
2164 uint32 entry = fields[0].Get<uint32>();
2165
2166 SpellInfo const* spell = GetSpellInfo(entry);
2167 if (!spell)
2168 {
2169 LOG_ERROR("sql.sql", "Spell {} listed in `spell_bonus_data` does not exist", entry);
2170 continue;
2171 }
2172
2173 SpellBonusEntry& sbe = mSpellBonusMap[entry];
2174 sbe.direct_damage = fields[1].Get<float>();
2175 sbe.dot_damage = fields[2].Get<float>();
2176 sbe.ap_bonus = fields[3].Get<float>();
2177 sbe.ap_dot_bonus = fields[4].Get<float>();
2178
2179 ++count;
2180 } while (result->NextRow());
2181
2182 LOG_INFO("server.loading", ">> Loaded {} Extra Spell Bonus Data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2183 LOG_INFO("server.loading", " ");
2184}
Definition SpellMgr.h:323
float ap_dot_bonus
Definition SpellMgr.h:327
float dot_damage
Definition SpellMgr.h:325
float ap_bonus
Definition SpellMgr.h:326
float direct_damage
Definition SpellMgr.h:324

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 ( )
2902{
2903 uint32 oldMSTime = getMSTime();
2904
2906
2907 QueryResult result = WorldDatabase.Query("SELECT Id, RecoveryTime, CategoryRecoveryTime, StartRecoveryTime, StartRecoveryCategory FROM spell_cooldown_overrides");
2908
2909 uint32 count = 0;
2910
2911 if (result)
2912 {
2913 do
2914 {
2915 Field* fields = result->Fetch();
2916 SpellCooldownOverride spellCooldown;
2917 uint32 spellId = fields[0].Get<uint32>();
2918 spellCooldown.RecoveryTime = fields[1].Get<uint32>();
2919 spellCooldown.CategoryRecoveryTime = fields[2].Get<uint32>();
2920 spellCooldown.StartRecoveryTime = fields[3].Get<uint32>();
2921 spellCooldown.StartRecoveryCategory = fields[4].Get<uint32>();
2922 mSpellCooldownOverrideMap[spellId] = spellCooldown;
2923
2924 ++count;
2925 } while (result->NextRow());
2926 }
2927
2928 LOG_INFO("server.loading", ">> Loaded {} Spell Cooldown Overrides entries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2929 LOG_INFO("server.loading", " ");
2930}
Definition SpellMgr.h:599
uint32 StartRecoveryTime
Definition SpellMgr.h:602
uint32 CategoryRecoveryTime
Definition SpellMgr.h:601
uint32 StartRecoveryCategory
Definition SpellMgr.h:603
uint32 RecoveryTime
Definition SpellMgr.h:600

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

◆ LoadSpellEnchantProcData()

void SpellMgr::LoadSpellEnchantProcData ( )
2390{
2391 uint32 oldMSTime = getMSTime();
2392
2393 mSpellEnchantProcEventMap.clear(); // need for reload case
2394
2395 // 0 1 2 3 4
2396 QueryResult result = WorldDatabase.Query("SELECT entry, customChance, PPMChance, procEx, attributeMask FROM spell_enchant_proc_data");
2397 if (!result)
2398 {
2399 LOG_WARN("server.loading", ">> Loaded 0 spell enchant proc event conditions. DB table `spell_enchant_proc_data` is empty.");
2400 LOG_INFO("server.loading", " ");
2401 return;
2402 }
2403
2404 uint32 count = 0;
2405 do
2406 {
2407 Field* fields = result->Fetch();
2408
2409 uint32 enchantId = fields[0].Get<uint32>();
2410
2411 SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchantId);
2412 if (!ench)
2413 {
2414 LOG_ERROR("sql.sql", "Enchancment {} listed in `spell_enchant_proc_data` does not exist", enchantId);
2415 continue;
2416 }
2417
2419
2420 spe.customChance = fields[1].Get<uint32>();
2421 spe.PPMChance = fields[2].Get<float>();
2422 spe.procEx = fields[3].Get<uint32>();
2423 spe.attributeMask = fields[4].Get<uint32>();
2424
2425 mSpellEnchantProcEventMap[enchantId] = spe;
2426
2427 ++count;
2428 } while (result->NextRow());
2429
2430 LOG_INFO("server.loading", ">> Loaded {} Enchant Proc Data Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2431 LOG_INFO("server.loading", " ");
2432}
Definition SpellMgr.h:313
uint32 procEx
Definition SpellMgr.h:316
uint32 attributeMask
Definition SpellMgr.h:317
uint32 customChance
Definition SpellMgr.h:314
float PPMChance
Definition SpellMgr.h:315

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 ( )
1685{
1686 uint32 oldMSTime = getMSTime();
1687
1688 mSpellSpellGroup.clear(); // need for reload case
1689 mSpellGroupSpell.clear();
1690
1691 // 0 1
1692 QueryResult result = WorldDatabase.Query("SELECT id, spell_id FROM spell_group");
1693 if (!result)
1694 {
1695 LOG_WARN("server.loading", ">> Loaded 0 spell group definitions. DB table `spell_group` is empty.");
1696 LOG_INFO("server.loading", " ");
1697 return;
1698 }
1699
1700 std::set<uint32> groups;
1701 uint32 count = 0;
1702 do
1703 {
1704 Field* fields = result->Fetch();
1705
1706 uint32 group_id = fields[0].Get<uint32>();
1707 if (group_id <= SPELL_GROUP_DB_RANGE_MIN && group_id >= SPELL_GROUP_CORE_RANGE_MAX)
1708 {
1709 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group` is in core range, but is not defined in core!", group_id);
1710 continue;
1711 }
1712 int32 spell_id = fields[1].Get<int32>();
1713
1714 groups.insert(group_id);
1715 mSpellGroupSpell.emplace(SpellGroup(group_id), spell_id);
1716
1717 } while (result->NextRow());
1718
1719 for (auto itr = mSpellGroupSpell.begin(); itr!= mSpellGroupSpell.end();)
1720 {
1721 if (itr->second < 0)
1722 {
1723 if (groups.find(abs(itr->second)) == groups.end())
1724 {
1725 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group` does not exist", abs(itr->second));
1726 itr = mSpellGroupSpell.erase(itr);
1727 }
1728 else
1729 ++itr;
1730 }
1731 else
1732 {
1733 SpellInfo const* spellInfo = GetSpellInfo(itr->second);
1734 if (!spellInfo)
1735 {
1736 LOG_ERROR("sql.sql", "Spell {} listed in `spell_group` does not exist", itr->second);
1737 itr = mSpellGroupSpell.erase(itr);
1738 }
1739 else if (spellInfo->GetRank() > 1)
1740 {
1741 LOG_ERROR("sql.sql", "Spell {} listed in `spell_group` is not first rank of spell.", itr->second);
1742 itr = mSpellGroupSpell.erase(itr);
1743 }
1744 else
1745 ++itr;
1746 }
1747 }
1748
1749 for (auto groupItr = groups.begin(); groupItr != groups.end(); ++groupItr)
1750 {
1751 std::set<uint32> spells;
1753
1754 for (auto spellItr = spells.begin(); spellItr != spells.end(); ++spellItr)
1755 {
1756 ++count;
1757 mSpellSpellGroup.emplace(*spellItr, SpellGroup(*groupItr));
1758 }
1759 }
1760
1761 LOG_INFO("server.loading", ">> Loaded {} spell group Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1762 LOG_INFO("server.loading", " ");
1763}
@ SPELL_GROUP_CORE_RANGE_MAX
Definition SpellMgr.h:337
spells
Definition boss_krystallus.cpp:26
uint8 GetRank() const
Definition SpellInfo.cpp:2390

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 ( )
1766{
1767 uint32 oldMSTime = getMSTime();
1768
1769 mSpellGroupStack.clear(); // need for reload case
1770 mSpellSameEffectStack.clear();
1771
1772 std::vector<uint32> sameEffectGroups;
1773
1774 // 0 1
1775 QueryResult result = WorldDatabase.Query("SELECT group_id, stack_rule FROM spell_group_stack_rules");
1776 if (!result)
1777 {
1778 LOG_WARN("server.loading", ">> Loaded 0 spell group stack rules. DB table `spell_group_stack_rules` is empty.");
1779 LOG_INFO("server.loading", " ");
1780 return;
1781 }
1782
1783 uint32 count = 0;
1784 do
1785 {
1786 Field* fields = result->Fetch();
1787
1788 uint32 group_id = fields[0].Get<uint32>();
1789 uint8 stack_rule = fields[1].Get<int8>();
1790 if (stack_rule >= SPELL_GROUP_STACK_RULE_MAX)
1791 {
1792 LOG_ERROR("sql.sql", "SpellGroupStackRule {} listed in `spell_group_stack_rules` does not exist.", stack_rule);
1793 continue;
1794 }
1795
1796 auto bounds = GetSpellGroupSpellMapBounds((SpellGroup)group_id);
1797 if (bounds.first == bounds.second)
1798 {
1799 LOG_ERROR("sql.sql", "SpellGroup id {} listed in `spell_group_stack_rules` does not exist.", group_id);
1800 continue;
1801 }
1802
1803 mSpellGroupStack.emplace(SpellGroup(group_id), SpellGroupStackRule(stack_rule));
1804
1805 // different container for same effect stack rules, need to check effect types
1807 sameEffectGroups.push_back(group_id);
1808
1809 ++count;
1810 } while (result->NextRow());
1811
1812 LOG_INFO("server.loading", ">> Loaded {} spell group stack rules in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1813 LOG_INFO("server.loading", " ");
1814
1815 count = 0;
1816 oldMSTime = getMSTime();
1817
1818 for (uint32 group_id : sameEffectGroups)
1819 {
1820 std::set<uint32> spellIds;
1821 GetSetOfSpellsInSpellGroup(SpellGroup(group_id), spellIds);
1822
1823 std::unordered_set<uint32> auraTypes;
1824
1825 // we have to 'guess' what effect this group corresponds to
1826 {
1827 std::unordered_multiset<uint32 /*auraName*/> frequencyContainer;
1828
1829 // only waylay for the moment (shared group)
1830 std::vector<std::vector<uint32 /*auraName*/>> const SubGroups =
1831 {
1833 };
1834
1835 for (uint32 spellId : spellIds)
1836 {
1837 SpellInfo const* spellInfo = AssertSpellInfo(spellId);
1838 for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
1839 {
1840 if (!spellEffectInfo.IsAura())
1841 continue;
1842
1843 uint32 auraName = spellEffectInfo.ApplyAuraName;
1844 for (std::vector<uint32> const& subGroup : SubGroups)
1845 {
1846 if (std::find(subGroup.begin(), subGroup.end(), auraName) != subGroup.end())
1847 {
1848 // count as first aura
1849 auraName = subGroup.front();
1850 break;
1851 }
1852 }
1853
1854 frequencyContainer.insert(auraName);
1855 }
1856 }
1857
1858 uint32 auraType = 0;
1859 size_t auraTypeCount = 0;
1860 for (uint32 auraName : frequencyContainer)
1861 {
1862 size_t currentCount = frequencyContainer.count(auraName);
1863 if (currentCount > auraTypeCount)
1864 {
1865 auraType = auraName;
1866 auraTypeCount = currentCount;
1867 }
1868 }
1869
1870 for (std::vector<uint32> const& subGroup : SubGroups)
1871 {
1872 if (auraType == subGroup.front())
1873 {
1874 auraTypes.insert(subGroup.begin(), subGroup.end());
1875 break;
1876 }
1877 }
1878
1879 if (auraTypes.empty())
1880 auraTypes.insert(auraType);
1881 }
1882
1883 // re-check spells against guessed group
1884 for (uint32 spellId : spellIds)
1885 {
1886 SpellInfo const* spellInfo = AssertSpellInfo(spellId);
1887
1888 bool found = false;
1889 while (spellInfo)
1890 {
1891 for (uint32 auraType : auraTypes)
1892 {
1893 if (spellInfo->HasAura(AuraType(auraType)))
1894 {
1895 found = true;
1896 break;
1897 }
1898 }
1899
1900 if (found)
1901 break;
1902
1903 spellInfo = spellInfo->GetNextRankSpell();
1904 }
1905
1906 // not found either, log error
1907 if (!found)
1908 LOG_ERROR("sql.sql", "SpellId {} listed in `spell_group` with stack rule 3 does not share aura assigned for group {}", spellId, group_id);
1909 }
1910
1911 mSpellSameEffectStack[SpellGroup(group_id)] = auraTypes;
1912 ++count;
1913 }
1914
1915 LOG_INFO("server.loading", ">> Loaded {} SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT stack rules in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1916 LOG_INFO("server.loading", " ");
1917}
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:367
@ SPELL_GROUP_STACK_RULE_MAX
Definition SpellMgr.h:369
Definition SpellInfo.h:249
SpellInfo const * GetNextRankSpell() const
Definition SpellInfo.cpp:2409
bool HasAura(AuraType aura) const
Definition SpellInfo.cpp:893
SpellInfo const * AssertSpellInfo(uint32 spellId) const
Definition SpellMgr.h:726

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

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

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 ( )
2873{
2874 uint32 oldMSTime = getMSTime();
2875
2877 mSpellInfoMap.resize(sSpellStore.GetNumRows(), nullptr);
2878
2879 for (SpellEntry const* spellEntry : sSpellStore)
2880 mSpellInfoMap[spellEntry->Id] = new SpellInfo(spellEntry);
2881
2882 for (uint32 spellIndex = 0; spellIndex < GetSpellInfoStoreSize(); ++spellIndex)
2883 {
2884 if (!mSpellInfoMap[spellIndex])
2885 continue;
2886
2887 for (SpellEffectInfo const& spellEffectInfo : mSpellInfoMap[spellIndex]->GetEffects())
2888 {
2889 //ASSERT(effect.EffectIndex < MAX_SPELL_EFFECTS, "MAX_SPELL_EFFECTS must be at least {}", effect.EffectIndex + 1);
2890 ASSERT(spellEffectInfo.Effect < TOTAL_SPELL_EFFECTS, "TOTAL_SPELL_EFFECTS must be at least {}", spellEffectInfo.Effect + 1);
2891 ASSERT(spellEffectInfo.ApplyAuraName < TOTAL_AURAS, "TOTAL_AURAS must be at least {}", spellEffectInfo.ApplyAuraName + 1);
2892 ASSERT(spellEffectInfo.TargetA.GetTarget() < TOTAL_SPELL_TARGETS, "TOTAL_SPELL_TARGETS must be at least {}", spellEffectInfo.TargetA.GetTarget() + 1);
2893 ASSERT(spellEffectInfo.TargetB.GetTarget() < TOTAL_SPELL_TARGETS, "TOTAL_SPELL_TARGETS must be at least {}", spellEffectInfo.TargetB.GetTarget() + 1);
2894 }
2895 }
2896
2897 LOG_INFO("server.loading", ">> Loaded Spell Custom Attributes in {} ms", GetMSTimeDiffToNow(oldMSTime));
2898 LOG_INFO("server.loading", " ");
2899}
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
@ TOTAL_SPELL_EFFECTS
Definition SharedDefines.h:954
@ TOTAL_SPELL_TARGETS
Definition SharedDefines.h:1525
@ TOTAL_AURAS
Definition SpellAuraDefines.h:380
Definition DBCStructure.h:1640

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

◆ LoadSpellLearnSkills()

void SpellMgr::LoadSpellLearnSkills ( )
1527{
1528 uint32 oldMSTime = getMSTime();
1529
1530 mSpellLearnSkills.clear(); // need for reload case
1531
1532 // search auto-learned skills and add its to map also for use in unlearn spells/talents
1533 uint32 dbc_count = 0;
1534 for (uint32 spell = 0; spell < GetSpellInfoStoreSize(); ++spell)
1535 {
1536 SpellInfo const* entry = GetSpellInfo(spell);
1537
1538 if (!entry)
1539 continue;
1540
1541 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1542 {
1543 SpellLearnSkillNode dbc_node;
1544 switch (entry->Effects[i].Effect)
1545 {
1546 case SPELL_EFFECT_SKILL:
1547 dbc_node.skill = entry->Effects[i].MiscValue;
1548 dbc_node.step = entry->Effects[i].CalcValue();
1549 if (dbc_node.skill != SKILL_RIDING)
1550 {
1551 dbc_node.value = 1;
1552 }
1553 else
1554 {
1555 dbc_node.value = dbc_node.step * 75;
1556 }
1557 dbc_node.maxvalue = dbc_node.step * 75;
1558 break;
1560 dbc_node.skill = SKILL_DUAL_WIELD;
1561 dbc_node.step = 1;
1562 dbc_node.value = 1;
1563 dbc_node.maxvalue = 1;
1564 break;
1565 default:
1566 continue;
1567 }
1568
1569 mSpellLearnSkills[spell] = dbc_node;
1570 ++dbc_count;
1571 break;
1572 }
1573 }
1574
1575 LOG_INFO("server.loading", ">> Loaded {} Spell Learn Skills From DBC in {} ms", dbc_count, GetMSTimeDiffToNow(oldMSTime));
1576 LOG_INFO("server.loading", " ");
1577}
@ SPELL_EFFECT_SKILL
Definition SharedDefines.h:907
@ SPELL_EFFECT_DUAL_WIELD
Definition SharedDefines.h:829
@ SKILL_DUAL_WIELD
Definition SharedDefines.h:3138
@ SKILL_RIDING
Definition SharedDefines.h:3241
Definition SpellMgr.h:566
uint16 value
Definition SpellMgr.h:569
uint16 step
Definition SpellMgr.h:568
uint16 maxvalue
Definition SpellMgr.h:570
uint16 skill
Definition SpellMgr.h:567

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

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

◆ LoadSpellMixology()

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

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

◆ LoadSpellPetAuras()

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

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.

◆ LoadSpellProcEvents()

void SpellMgr::LoadSpellProcEvents ( )
1920{
1921 uint32 oldMSTime = getMSTime();
1922
1923 mSpellProcEventMap.clear(); // need for reload case
1924
1925 // 0 1 2 3 4 5 6 7 8 9 10 11
1926 QueryResult result = WorldDatabase.Query("SELECT entry, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, procFlags, procEx, procPhase, ppmRate, CustomChance, Cooldown FROM spell_proc_event");
1927 if (!result)
1928 {
1929 LOG_WARN("server.loading", ">> Loaded 0 spell proc event conditions. DB table `spell_proc_event` is empty.");
1930 return;
1931 }
1932
1933 uint32 count = 0;
1934
1935 do
1936 {
1937 Field* fields = result->Fetch();
1938
1939 int32 spellId = fields[0].Get<int32>();
1940
1941 bool allRanks = false;
1942 if (spellId < 0)
1943 {
1944 allRanks = true;
1945 spellId = -spellId;
1946 }
1947
1948 SpellInfo const* spellInfo = GetSpellInfo(spellId);
1949 if (!spellInfo)
1950 {
1951 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` does not exist", spellId);
1952 continue;
1953 }
1954
1955 if (allRanks)
1956 {
1957 if (!spellInfo->IsRanked())
1958 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` with all ranks, but spell has no ranks.", spellId);
1959
1960 if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId))
1961 {
1962 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` is not first rank of spell.", spellId);
1963 continue;
1964 }
1965 }
1966
1967 SpellProcEventEntry spellProcEvent;
1968
1969 spellProcEvent.schoolMask = fields[1].Get<int8>();
1970 spellProcEvent.spellFamilyName = fields[2].Get<uint16>();
1971 spellProcEvent.spellFamilyMask[0] = fields[3].Get<uint32>();
1972 spellProcEvent.spellFamilyMask[1] = fields[4].Get<uint32>();
1973 spellProcEvent.spellFamilyMask[2] = fields[5].Get<uint32>();
1974 spellProcEvent.procFlags = fields[6].Get<uint32>();
1975 spellProcEvent.procEx = fields[7].Get<uint32>();
1976 spellProcEvent.procPhase = fields[8].Get<uint32>();
1977 spellProcEvent.ppmRate = fields[9].Get<float>();
1978 spellProcEvent.customChance = fields[10].Get<float>();
1979 spellProcEvent.cooldown = fields[11].Get<uint32>();
1980
1981 // PROC_SPELL_PHASE_NONE is by default PROC_SPELL_PHASE_HIT
1982 if (spellProcEvent.procPhase == PROC_SPELL_PHASE_NONE)
1983 {
1984 spellProcEvent.procPhase = PROC_SPELL_PHASE_HIT;
1985 }
1986
1987 while (spellInfo)
1988 {
1989 if (mSpellProcEventMap.find(spellInfo->Id) != mSpellProcEventMap.end())
1990 {
1991 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` already has its first rank in table.", spellInfo->Id);
1992 break;
1993 }
1994
1995 if (!spellInfo->ProcFlags && !spellProcEvent.procFlags)
1996 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` probally not triggered spell", spellInfo->Id);
1997
1998 mSpellProcEventMap[spellInfo->Id] = spellProcEvent;
1999
2000 if (allRanks)
2001 spellInfo = spellInfo->GetNextRankSpell();
2002 else
2003 break;
2004 }
2005
2006 ++count;
2007 } while (result->NextRow());
2008
2009 LOG_INFO("server.loading", ">> Loaded {} Extra Spell Proc Event Conditions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2010 LOG_INFO("server.loading", " ");
2011}
std::uint16_t uint16
Definition Define.h:108
@ PROC_SPELL_PHASE_NONE
Definition SpellMgr.h:241
SpellInfo const * GetFirstRankSpell() const
Definition SpellInfo.cpp:2397
bool IsRanked() const
Definition SpellInfo.cpp:2385
uint32 ProcFlags
Definition SpellInfo.h:355
Definition SpellMgr.h:274
uint32 cooldown
Definition SpellMgr.h:283
uint32 procPhase
Definition SpellMgr.h:280
flag96 spellFamilyMask
Definition SpellMgr.h:277
uint32 spellFamilyName
Definition SpellMgr.h:276
uint32 procEx
Definition SpellMgr.h:279
float ppmRate
Definition SpellMgr.h:281
uint32 schoolMask
Definition SpellMgr.h:275
float customChance
Definition SpellMgr.h:282
uint32 procFlags
Definition SpellMgr.h:278

References SpellProcEventEntry::cooldown, SpellProcEventEntry::customChance, Field::Get(), SpellInfo::GetFirstRankSpell(), getMSTime(), GetMSTimeDiffToNow(), SpellInfo::GetNextRankSpell(), GetSpellInfo(), SpellInfo::Id, SpellInfo::IsRanked(), LOG_ERROR, LOG_INFO, LOG_WARN, mSpellProcEventMap, SpellProcEventEntry::ppmRate, PROC_SPELL_PHASE_HIT, PROC_SPELL_PHASE_NONE, SpellProcEventEntry::procEx, SpellInfo::ProcFlags, SpellProcEventEntry::procFlags, SpellProcEventEntry::procPhase, SpellProcEventEntry::schoolMask, SpellProcEventEntry::spellFamilyMask, SpellProcEventEntry::spellFamilyName, and WorldDatabase.

◆ LoadSpellProcs()

void SpellMgr::LoadSpellProcs ( )
2014{
2015 uint32 oldMSTime = getMSTime();
2016
2017 mSpellProcMap.clear(); // need for reload case
2018
2019 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
2020 QueryResult result = WorldDatabase.Query("SELECT SpellId, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, ProcFlags, SpellTypeMask, SpellPhaseMask, HitMask, AttributesMask, ProcsPerMinute, Chance, Cooldown, Charges FROM spell_proc");
2021 if (!result)
2022 {
2023 LOG_WARN("server.loading", ">> Loaded 0 Spell Proc Conditions And Data. DB table `spell_proc` Is Empty.");
2024 LOG_INFO("server.loading", " ");
2025 return;
2026 }
2027
2028 uint32 count = 0;
2029 do
2030 {
2031 Field* fields = result->Fetch();
2032
2033 int32 spellId = fields[0].Get<int32>();
2034
2035 bool allRanks = false;
2036 if (spellId < 0)
2037 {
2038 allRanks = true;
2039 spellId = -spellId;
2040 }
2041
2042 SpellInfo const* spellInfo = GetSpellInfo(spellId);
2043 if (!spellInfo)
2044 {
2045 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` does not exist", spellId);
2046 continue;
2047 }
2048
2049 if (allRanks)
2050 {
2051 if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId))
2052 {
2053 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` is not first rank of spell.", fields[0].Get<int32>());
2054 continue;
2055 }
2056 }
2057
2058 SpellProcEntry baseProcEntry;
2059
2060 baseProcEntry.SchoolMask = fields[1].Get<int8>();
2061 baseProcEntry.SpellFamilyName = fields[2].Get<uint16>();
2062 baseProcEntry.SpellFamilyMask[0] = fields[3].Get<uint32>();
2063 baseProcEntry.SpellFamilyMask[1] = fields[4].Get<uint32>();
2064 baseProcEntry.SpellFamilyMask[2] = fields[5].Get<uint32>();
2065 baseProcEntry.ProcFlags = fields[6].Get<uint32>();
2066 baseProcEntry.SpellTypeMask = fields[7].Get<uint32>();
2067 baseProcEntry.SpellPhaseMask = fields[8].Get<uint32>();
2068 baseProcEntry.HitMask = fields[9].Get<uint32>();
2069 baseProcEntry.AttributesMask = fields[10].Get<uint32>();
2070 baseProcEntry.ProcsPerMinute = fields[11].Get<float>();
2071 baseProcEntry.Chance = fields[12].Get<float>();
2072 baseProcEntry.Cooldown = Milliseconds(fields[13].Get<uint32>());
2073 baseProcEntry.Charges = fields[14].Get<uint32>();
2074
2075 while (spellInfo)
2076 {
2077 if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end())
2078 {
2079 LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` has duplicate entry in the table", spellId);
2080 break;
2081 }
2082 SpellProcEntry procEntry = SpellProcEntry(baseProcEntry);
2083
2084 // take defaults from dbcs
2085 if (!procEntry.ProcFlags)
2086 procEntry.ProcFlags = spellInfo->ProcFlags;
2087 if (!procEntry.Charges)
2088 procEntry.Charges = spellInfo->ProcCharges;
2089 if (!procEntry.Chance && !procEntry.ProcsPerMinute)
2090 procEntry.Chance = float(spellInfo->ProcChance);
2091
2092 // validate data
2093 if (procEntry.SchoolMask & ~SPELL_SCHOOL_MASK_ALL)
2094 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SchoolMask` set: {}", spellId, procEntry.SchoolMask);
2095 if (procEntry.SpellFamilyName && (procEntry.SpellFamilyName < 3 || procEntry.SpellFamilyName > 17 || procEntry.SpellFamilyName == 14 || procEntry.SpellFamilyName == 16))
2096 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellFamilyName` set: {}", spellId, procEntry.SpellFamilyName);
2097 if (procEntry.Chance < 0)
2098 {
2099 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `Chance` field", spellId);
2100 procEntry.Chance = 0;
2101 }
2102 if (procEntry.ProcsPerMinute < 0)
2103 {
2104 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `ProcsPerMinute` field", spellId);
2105 procEntry.ProcsPerMinute = 0;
2106 }
2107 if (procEntry.Chance == 0 && procEntry.ProcsPerMinute == 0)
2108 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} doesn't have `Chance` and `ProcsPerMinute` values defined, proc will not be triggered", spellId);
2109 if (procEntry.Charges > 99)
2110 {
2111 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has too big value in `Charges` field", spellId);
2112 procEntry.Charges = 99;
2113 }
2114 if (!procEntry.ProcFlags)
2115 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} doesn't have `ProcFlags` value defined, proc will not be triggered", spellId);
2116 if (procEntry.SpellTypeMask & ~PROC_SPELL_TYPE_MASK_ALL)
2117 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellTypeMask` set: {}", spellId, procEntry.SpellTypeMask);
2118 if (procEntry.SpellTypeMask && !(procEntry.ProcFlags & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK)))
2119 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);
2120 if (!procEntry.SpellPhaseMask && procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK)
2121 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);
2123 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellPhaseMask` set: {}", spellId, procEntry.SpellPhaseMask);
2124 if (procEntry.SpellPhaseMask && !(procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK))
2125 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);
2126 if (procEntry.HitMask & ~PROC_HIT_MASK_ALL)
2127 LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `HitMask` set: {}", spellId, procEntry.HitMask);
2128 if (procEntry.HitMask && !(procEntry.ProcFlags & TAKEN_HIT_PROC_FLAG_MASK || (procEntry.ProcFlags & DONE_HIT_PROC_FLAG_MASK && (!procEntry.SpellPhaseMask || procEntry.SpellPhaseMask & (PROC_SPELL_PHASE_HIT | PROC_SPELL_PHASE_FINISH)))))
2129 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);
2130
2131 mSpellProcMap[spellInfo->Id] = procEntry;
2132
2133 if (allRanks)
2134 spellInfo = spellInfo->GetNextRankSpell();
2135 else
2136 break;
2137 }
2138 ++count;
2139 } while (result->NextRow());
2140
2141 LOG_INFO("server.loading", ">> Loaded {} spell proc conditions and data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2142 LOG_INFO("server.loading", " ");
2143}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:27
@ SPELL_SCHOOL_MASK_ALL
Definition SharedDefines.h:326
@ PROC_HIT_MASK_ALL
Definition SpellMgr.h:265
@ PROC_SPELL_TYPE_MASK_ALL
Definition SpellMgr.h:236
@ PROC_SPELL_PHASE_FINISH
Definition SpellMgr.h:244
@ PROC_SPELL_PHASE_MASK_ALL
Definition SpellMgr.h:245
uint32 ProcCharges
Definition SpellInfo.h:357
uint32 ProcChance
Definition SpellInfo.h:356
Definition SpellMgr.h:289
uint32 SpellFamilyName
Definition SpellMgr.h:291
float ProcsPerMinute
Definition SpellMgr.h:298
Milliseconds Cooldown
Definition SpellMgr.h:300
uint32 Charges
Definition SpellMgr.h:301
uint32 AttributesMask
Definition SpellMgr.h:297
flag96 SpellFamilyMask
Definition SpellMgr.h:292
uint32 HitMask
Definition SpellMgr.h:296
uint32 SpellTypeMask
Definition SpellMgr.h:294
uint32 ProcFlags
Definition SpellMgr.h:293
uint32 SpellPhaseMask
Definition SpellMgr.h:295
uint32 SchoolMask
Definition SpellMgr.h:290
float Chance
Definition SpellMgr.h:299

References SpellProcEntry::AttributesMask, SpellProcEntry::Chance, SpellProcEntry::Charges, SpellProcEntry::Cooldown, DONE_HIT_PROC_FLAG_MASK, Field::Get(), SpellInfo::GetFirstRankSpell(), getMSTime(), GetMSTimeDiffToNow(), SpellInfo::GetNextRankSpell(), GetSpellInfo(), SpellProcEntry::HitMask, SpellInfo::Id, LOG_ERROR, LOG_INFO, LOG_WARN, mSpellProcMap, PERIODIC_PROC_FLAG_MASK, PROC_HIT_MASK_ALL, PROC_SPELL_PHASE_FINISH, PROC_SPELL_PHASE_HIT, PROC_SPELL_PHASE_MASK_ALL, PROC_SPELL_TYPE_MASK_ALL, SpellInfo::ProcChance, SpellInfo::ProcCharges, SpellInfo::ProcFlags, SpellProcEntry::ProcFlags, SpellProcEntry::ProcsPerMinute, REQ_SPELL_PHASE_PROC_FLAG_MASK, SpellProcEntry::SchoolMask, SPELL_PROC_FLAG_MASK, SPELL_SCHOOL_MASK_ALL, SpellProcEntry::SpellFamilyMask, SpellProcEntry::SpellFamilyName, SpellProcEntry::SpellPhaseMask, SpellProcEntry::SpellTypeMask, TAKEN_HIT_PROC_FLAG_MASK, and WorldDatabase.

◆ LoadSpellRanks()

void SpellMgr::LoadSpellRanks ( )
1351{
1352 // cleanup data and load spell ranks for talents from dbc
1354
1355 uint32 oldMSTime = getMSTime();
1356
1357 // 0 1 2
1358 QueryResult result = WorldDatabase.Query("SELECT first_spell_id, spell_id, `rank` from spell_ranks ORDER BY first_spell_id, `rank`");
1359
1360 if (!result)
1361 {
1362 LOG_WARN("server.loading", ">> Loaded 0 spell rank records. DB table `spell_ranks` is empty.");
1363 LOG_INFO("server.loading", " ");
1364 return;
1365 }
1366
1367 uint32 count = 0;
1368 bool finished = false;
1369
1370 do
1371 {
1372 // spellid, rank
1373 std::list < std::pair < int32, int32 > > rankChain;
1374 int32 currentSpell = -1;
1375 int32 lastSpell = -1;
1376
1377 // fill one chain
1378 while (currentSpell == lastSpell && !finished)
1379 {
1380 Field* fields = result->Fetch();
1381
1382 currentSpell = fields[0].Get<uint32>();
1383 if (lastSpell == -1)
1384 lastSpell = currentSpell;
1385 uint32 spell_id = fields[1].Get<uint32>();
1386 uint32 rank = fields[2].Get<uint8>();
1387
1388 // don't drop the row if we're moving to the next rank
1389 if (currentSpell == lastSpell)
1390 {
1391 rankChain.push_back(std::make_pair(spell_id, rank));
1392 if (!result->NextRow())
1393 finished = true;
1394 }
1395 else
1396 break;
1397 }
1398 // check if chain is made with valid first spell
1399 SpellInfo const* first = GetSpellInfo(lastSpell);
1400 if (!first)
1401 {
1402 LOG_ERROR("sql.sql", "Spell rank identifier(first_spell_id) {} listed in `spell_ranks` does not exist!", lastSpell);
1403 continue;
1404 }
1405 // check if chain is long enough
1406 if (rankChain.size() < 2)
1407 {
1408 LOG_ERROR("sql.sql", "There is only 1 spell rank for identifier(first_spell_id) {} in `spell_ranks`, entry is not needed!", lastSpell);
1409 continue;
1410 }
1411 int32 curRank = 0;
1412 bool valid = true;
1413 // check spells in chain
1414 for (std::list<std::pair<int32, int32> >::iterator itr = rankChain.begin(); itr != rankChain.end(); ++itr)
1415 {
1416 SpellInfo const* spell = GetSpellInfo(itr->first);
1417 if (!spell)
1418 {
1419 LOG_ERROR("sql.sql", "Spell {} (rank {}) listed in `spell_ranks` for chain {} does not exist!", itr->first, itr->second, lastSpell);
1420 valid = false;
1421 break;
1422 }
1423 ++curRank;
1424 if (itr->second != curRank)
1425 {
1426 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);
1427 valid = false;
1428 break;
1429 }
1430 }
1431 if (!valid)
1432 continue;
1433 int32 prevRank = 0;
1434 // insert the chain
1435 std::list<std::pair<int32, int32> >::iterator itr = rankChain.begin();
1436 do
1437 {
1438 ++count;
1439 int32 addedSpell = itr->first;
1440 mSpellChains[addedSpell].first = GetSpellInfo(lastSpell);
1441 mSpellChains[addedSpell].last = GetSpellInfo(rankChain.back().first);
1442 mSpellChains[addedSpell].rank = itr->second;
1443 mSpellChains[addedSpell].prev = GetSpellInfo(prevRank);
1444 mSpellInfoMap[addedSpell]->ChainEntry = &mSpellChains[addedSpell];
1445 prevRank = addedSpell;
1446 ++itr;
1447 if (itr == rankChain.end())
1448 {
1449 mSpellChains[addedSpell].next = nullptr;
1450 break;
1451 }
1452 else
1453 mSpellChains[addedSpell].next = GetSpellInfo(itr->first);
1454 } while (true);
1455 } while (!finished);
1456
1457 LOG_INFO("server.loading", ">> Loaded {} spell rank records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1458 LOG_INFO("server.loading", " ");
1459}
void LoadSpellTalentRanks()
Definition SpellMgr.cpp:1289

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

◆ LoadSpellRequired()

void SpellMgr::LoadSpellRequired ( )
1462{
1463 uint32 oldMSTime = getMSTime();
1464
1465 mSpellsReqSpell.clear(); // need for reload case
1466 mSpellReq.clear(); // need for reload case
1467
1468 // 0 1
1469 QueryResult result = WorldDatabase.Query("SELECT spell_id, req_spell from spell_required");
1470
1471 if (!result)
1472 {
1473 LOG_WARN("server.loading", ">> Loaded 0 spell required records. DB table `spell_required` is empty.");
1474 LOG_INFO("server.loading", " ");
1475 return;
1476 }
1477
1478 uint32 count = 0;
1479 do
1480 {
1481 Field* fields = result->Fetch();
1482
1483 uint32 spellId = fields[0].Get<uint32>();
1484 uint32 spellReq = fields[1].Get<uint32>();
1485
1486 // check if chain is made with valid first spell
1487 SpellInfo const* spellInfo = GetSpellInfo(spellId);
1488 if (!spellInfo)
1489 {
1490 LOG_ERROR("sql.sql", "spell_id {} in `spell_required` table is not found in dbcs, skipped", spellId);
1491 continue;
1492 }
1493
1494 SpellInfo const* reqSpellInfo = GetSpellInfo(spellReq);
1495 if (!reqSpellInfo)
1496 {
1497 LOG_ERROR("sql.sql", "req_spell {} in `spell_required` table is not found in dbcs, skipped", spellReq);
1498 continue;
1499 }
1500
1501 if (GetFirstSpellInChain(spellId) == GetFirstSpellInChain(spellReq))
1502 {
1503 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);
1504 continue;
1505 }
1506
1507 if (IsSpellRequiringSpell(spellId, spellReq))
1508 {
1509 LOG_ERROR("sql.sql", "duplicated entry of req_spell {} and spell_id {} in `spell_required`, skipped", spellReq, spellId);
1510 continue;
1511 }
1512
1513 mSpellReq.insert (std::pair<uint32, uint32>(spellId, spellReq));
1514 mSpellsReqSpell.insert (std::pair<uint32, uint32>(spellReq, spellId));
1515 ++count;
1516
1517 // xinef: fill additionalTalentInfo data, currently Blessing of Sanctuary only
1518 if (GetTalentSpellCost(spellReq) > 0)
1519 mTalentSpellAdditionalSet.insert(spellId);
1520 } while (result->NextRow());
1521
1522 LOG_INFO("server.loading", ">> Loaded {} Spell Required Records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1523 LOG_INFO("server.loading", " ");
1524}
uint32 GetTalentSpellCost(uint32 spellId)
Definition DBCStores.cpp:686
bool IsSpellRequiringSpell(uint32 spellid, uint32 req_spellid) const
Definition SpellMgr.cpp:615

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

◆ LoadSpellSpecificAndAuraState()

void SpellMgr::LoadSpellSpecificAndAuraState ( )
2961{
2962 uint32 oldMSTime = getMSTime();
2963
2964 SpellInfo* spellInfo = nullptr;
2965 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2966 {
2967 spellInfo = mSpellInfoMap[i];
2968 if (!spellInfo)
2969 continue;
2970 spellInfo->_spellSpecific = spellInfo->LoadSpellSpecific();
2971 spellInfo->_auraState = spellInfo->LoadAuraState();
2972 }
2973
2974 LOG_INFO("server.loading", ">> Loaded Spell Specific And Aura State in {} ms", GetMSTimeDiffToNow(oldMSTime));
2975 LOG_INFO("server.loading", " ");
2976}
SpellSpecificType LoadSpellSpecific() const
Definition SpellInfo.cpp:2034
AuraStateType LoadAuraState() const
Definition SpellInfo.cpp:1956
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 ( )
1290{
1291 // cleanup core data before reload - remove reference to ChainNode from SpellInfo
1293
1294 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1295 {
1296 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
1297 if (!talentInfo)
1298 continue;
1299
1300 SpellInfo const* lastSpell = nullptr;
1301 for (uint8 rank = MAX_TALENT_RANK - 1; rank > 0; --rank)
1302 {
1303 if (talentInfo->RankID[rank])
1304 {
1305 lastSpell = GetSpellInfo(talentInfo->RankID[rank]);
1306 break;
1307 }
1308 }
1309
1310 if (!lastSpell)
1311 continue;
1312
1313 SpellInfo const* firstSpell = GetSpellInfo(talentInfo->RankID[0]);
1314 if (!firstSpell)
1315 {
1316 LOG_ERROR("sql.sql", "SpellMgr::LoadSpellTalentRanks: First Rank Spell {} for TalentEntry {} does not exist.", talentInfo->RankID[0], i);
1317 continue;
1318 }
1319
1320 SpellInfo const* prevSpell = nullptr;
1321 for (uint8 rank = 0; rank < MAX_TALENT_RANK; ++rank)
1322 {
1323 uint32 spellId = talentInfo->RankID[rank];
1324 if (!spellId)
1325 break;
1326
1327 SpellInfo const* currentSpell = GetSpellInfo(spellId);
1328 if (!currentSpell)
1329 {
1330 LOG_ERROR("sql.sql", "SpellMgr::LoadSpellTalentRanks: Spell {} (Rank: {}) for TalentEntry {} does not exist.", spellId, rank + 1, i);
1331 break;
1332 }
1333
1334 SpellChainNode node;
1335 node.first = firstSpell;
1336 node.last = lastSpell;
1337 node.rank = rank + 1;
1338
1339 node.prev = prevSpell;
1340 node.next = node.rank < MAX_TALENT_RANK ? GetSpellInfo(talentInfo->RankID[node.rank]) : nullptr;
1341
1342 mSpellChains[spellId] = node;
1343 mSpellInfoMap[spellId]->ChainEntry = &mSpellChains[spellId];
1344
1345 prevSpell = currentSpell;
1346 }
1347 }
1348}
void UnloadSpellInfoChains()
Definition SpellMgr.cpp:1281
SpellInfo const * last
Definition SpellMgr.h:550
SpellInfo const * next
Definition SpellMgr.h:548
uint8 rank
Definition SpellMgr.h:551
SpellInfo const * first
Definition SpellMgr.h:549
SpellInfo const * prev
Definition SpellMgr.h:547

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 ( )
1580{
1581 uint32 oldMSTime = getMSTime();
1582
1583 mSpellTargetPositions.clear(); // need for reload case
1584
1585 // 0 1 2 3 4 5 6
1586 QueryResult result = WorldDatabase.Query("SELECT ID, EffectIndex, MapID, PositionX, PositionY, PositionZ, Orientation FROM spell_target_position");
1587
1588 if (!result)
1589 {
1590 LOG_WARN("server.loading", ">> Loaded 0 spell target coordinates. DB table `spell_target_position` is empty.");
1591 LOG_INFO("server.loading", " ");
1592 return;
1593 }
1594
1595 uint32 count = 0;
1596 do
1597 {
1598 Field* fields = result->Fetch();
1599
1600 uint32 Spell_ID = fields[0].Get<uint32>();
1601
1602 SpellEffIndex effIndex = SpellEffIndex(fields[1].Get<uint8>());
1603
1605
1606 st.target_mapId = fields[2].Get<uint16>();
1607 st.target_X = fields[3].Get<float>();
1608 st.target_Y = fields[4].Get<float>();
1609 st.target_Z = fields[5].Get<float>();
1610 st.target_Orientation = fields[6].Get<float>();
1611
1612 MapEntry const* mapEntry = sMapStore.LookupEntry(st.target_mapId);
1613 if (!mapEntry)
1614 {
1615 LOG_ERROR("sql.sql", "Spell (Id: {}, effIndex: {}) target map (ID: {}) does not exist in `Map.dbc`.", Spell_ID, effIndex, st.target_mapId);
1616 continue;
1617 }
1618
1619 if (st.target_X == 0 && st.target_Y == 0 && st.target_Z == 0)
1620 {
1621 LOG_ERROR("sql.sql", "Spell (Id: {}, effIndex: {}) target coordinates not provided.", Spell_ID, effIndex);
1622 continue;
1623 }
1624
1625 SpellInfo const* spellInfo = GetSpellInfo(Spell_ID);
1626 if (!spellInfo)
1627 {
1628 LOG_ERROR("sql.sql", "Spell (ID:{}) listed in `spell_target_position` does not exist.", Spell_ID);
1629 continue;
1630 }
1631
1632 if (spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_DEST_DB || spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_DEST_DB)
1633 {
1634 std::pair<uint32, SpellEffIndex> key = std::make_pair(Spell_ID, effIndex);
1635 mSpellTargetPositions[key] = st;
1636 ++count;
1637 }
1638 else
1639 {
1640 LOG_ERROR("sql.sql", "Spell (Id: {}, effIndex: {}) listed in `spell_target_position` does not have target TARGET_DEST_DB (17).", Spell_ID, effIndex);
1641 continue;
1642 }
1643 } while (result->NextRow());
1644
1645 /*
1646 // Check all spells
1647 for (uint32 i = 1; i < GetSpellInfoStoreSize; ++i)
1648 {
1649 SpellInfo const* spellInfo = GetSpellInfo(i);
1650 if (!spellInfo)
1651 continue;
1652
1653 bool found = false;
1654 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
1655 {
1656 switch (spellInfo->Effects[j].TargetA)
1657 {
1658 case TARGET_DEST_DB:
1659 found = true;
1660 break;
1661 }
1662 if (found)
1663 break;
1664 switch (spellInfo->Effects[j].TargetB)
1665 {
1666 case TARGET_DEST_DB:
1667 found = true;
1668 break;
1669 }
1670 if (found)
1671 break;
1672 }
1673 if (found)
1674 {
1675 if (!GetSpellTargetPosition(i))
1676 LOG_DEBUG("spells.aura", "Spell (ID: {}) does not have record in `spell_target_position`", i);
1677 }
1678 }*/
1679
1680 LOG_INFO("server.loading", ">> Loaded {} Spell Teleport Coordinates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1681 LOG_INFO("server.loading", " ");
1682}
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
SpellEffIndex
Definition SharedDefines.h:30
Definition DBCStructure.h:1323
Definition SpellMgr.h:388
float target_Z
Definition SpellMgr.h:392
uint32 target_mapId
Definition SpellMgr.h:389
float target_Y
Definition SpellMgr.h:391
float target_Orientation
Definition SpellMgr.h:393
float target_X
Definition SpellMgr.h:390

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 ( )
2187{
2188 uint32 oldMSTime = getMSTime();
2189
2190 mSpellThreatMap.clear(); // need for reload case
2191
2192 // 0 1 2 3
2193 QueryResult result = WorldDatabase.Query("SELECT entry, flatMod, pctMod, apPctMod FROM spell_threat");
2194 if (!result)
2195 {
2196 LOG_WARN("server.loading", ">> Loaded 0 aggro generating spells. DB table `spell_threat` is empty.");
2197 LOG_INFO("server.loading", " ");
2198 return;
2199 }
2200
2201 uint32 count = 0;
2202 do
2203 {
2204 Field* fields = result->Fetch();
2205
2206 uint32 entry = fields[0].Get<uint32>();
2207
2208 if (!GetSpellInfo(entry))
2209 {
2210 LOG_ERROR("sql.sql", "Spell {} listed in `spell_threat` does not exist", entry);
2211 continue;
2212 }
2213
2214 SpellThreatEntry ste;
2215 ste.flatMod = fields[1].Get<int32>();
2216 ste.pctMod = fields[2].Get<float>();
2217 ste.apPctMod = fields[3].Get<float>();
2218
2219 mSpellThreatMap[entry] = ste;
2220 ++count;
2221 } while (result->NextRow());
2222
2223 LOG_INFO("server.loading", ">> Loaded {} SpellThreatEntries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2224 LOG_INFO("server.loading", " ");
2225}
Definition SpellMgr.h:377
int32 flatMod
Definition SpellMgr.h:378
float apPctMod
Definition SpellMgr.h:380
float pctMod
Definition SpellMgr.h:379

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

References mSpellDifficultySearcherMap.

◆ UnloadSpellInfoChains()

void SpellMgr::UnloadSpellInfoChains ( )
1282{
1283 for (SpellChainMap::iterator itr = mSpellChains.begin(); itr != mSpellChains.end(); ++itr)
1284 mSpellInfoMap[itr->first]->ChainEntry = nullptr;
1285
1286 mSpellChains.clear();
1287}

References mSpellChains, and mSpellInfoMap.

Referenced by LoadSpellTalentRanks().

◆ UnloadSpellInfoImplicitTargetConditionLists()

void SpellMgr::UnloadSpellInfoImplicitTargetConditionLists ( )
2952{
2953 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2954 {
2955 if (mSpellInfoMap[i])
2956 mSpellInfoMap[i]->_UnloadImplicitTargetConditionLists();
2957 }
2958}

References GetSpellInfoStoreSize(), and mSpellInfoMap.

◆ UnloadSpellInfoStore()

void SpellMgr::UnloadSpellInfoStore ( )
2944{
2945 for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2946 delete mSpellInfoMap[i];
2947
2948 mSpellInfoMap.clear();
2949}

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

◆ mSpellProcEventMap

SpellProcEventMap SpellMgr::mSpellProcEventMap
private

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