TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
SpellMgr Class Reference

#include <SpellMgr.h>

Public Member Functions

SpellChainNode constGetSpellChainNode (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 constGetSpellLearnSkill (uint32 spell_id) const
 
SpellLearnSpellMapBounds GetSpellLearnSpellMapBounds (uint32 spell_id) const
 
bool IsSpellLearnSpell (uint32 spell_id) const
 
bool IsSpellLearnToSpell (uint32 spell_id1, uint32 spell_id2) const
 
SpellTargetPosition constGetSpellTargetPosition (uint32 spell_id, SpellEffIndex effIndex) const
 
SpellSpellGroupMapBounds GetSpellSpellGroupMapBounds (uint32 spell_id) const
 
bool IsSpellMemberOfSpellGroup (uint32 spellid, SpellGroup groupid) 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, int32 amount, std::map< SpellGroup, int32 > &groups) const
 
SpellGroupStackRule CheckSpellGroupStackRules (SpellInfo const *spellInfo1, SpellInfo const *spellInfo2) const
 
SpellGroupStackRule GetSpellGroupStackRule (SpellGroup groupid) const
 
SpellProcEventEntry constGetSpellProcEvent (uint32 spellId) const
 
bool IsSpellProcEventCanTriggeredBy (SpellInfo const *spellProto, SpellProcEventEntry const *spellProcEvent, uint32 EventProcFlag, SpellInfo const *procSpell, uint32 procFlags, uint32 procExtra, bool active) const
 
SpellProcEntry constGetSpellProcEntry (uint32 spellId) const
 
bool CanSpellTriggerProcOnEvent (SpellProcEntry const &procEntry, ProcEventInfo &eventInfo) const
 
SpellThreatEntry constGetSpellThreatEntry (uint32 spellID) const
 
SkillLineAbilityMapBounds GetSkillLineAbilityMapBounds (uint32 spell_id) const
 
PetAura constGetPetAura (uint32 spell_id, uint8 eff) const
 
SpellEnchantProcEntry constGetSpellEnchantProcEvent (uint32 enchId) const
 
bool IsArenaAllowedEnchancment (uint32 ench_id) const
 
const std::vector< int32 > * GetSpellLinked (int32 spell_id) const
 
PetLevelupSpellSet constGetPetLevelupSpellList (uint32 petFamily) const
 
PetDefaultSpellsEntry constGetPetDefaultSpellsEntry (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 constGetSpellInfo (uint32 spellId) const
 
SpellInfo constAssertSpellInfo (uint32 spellId) const
 
uint32 GetSpellInfoStoreSize () const
 
void LoadPetFamilySpellsStore ()
 
void UnloadSpellInfoChains ()
 
void LoadSpellRanks ()
 
void LoadSpellRequired ()
 
void LoadSpellLearnSkills ()
 
void LoadSpellLearnSpells ()
 
void LoadSpellTargetPositions ()
 
void LoadSpellGroups ()
 
void LoadSpellGroupStackRules ()
 
void LoadSpellProcEvents ()
 
void LoadSpellProcs ()
 
void LoadSpellThreats ()
 
void LoadSkillLineAbilityMap ()
 
void LoadSpellPetAuras ()
 
void LoadEnchantCustomAttr ()
 
void LoadSpellEnchantProcData ()
 
void LoadSpellLinked ()
 
void LoadPetLevelupSpellMap ()
 
void LoadPetDefaultSpells ()
 
void LoadSpellAreas ()
 
void LoadSpellInfoStore ()
 
void UnloadSpellInfoStore ()
 
void UnloadSpellInfoImplicitTargetConditionLists ()
 
void LoadSpellInfoCustomAttributes ()
 
void LoadSpellInfoCorrections ()
 

Static Public Member Functions

static SpellMgrinstance ()
 
static bool IsSpellValid (SpellInfo const *spellInfo, Player *player=NULL, bool msg=true)
 Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book, etc. More...
 

Private Member Functions

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

Private Attributes

SpellDifficultySearcherMap mSpellDifficultySearcherMap
 
SpellChainMap mSpellChains
 
SpellsRequiringSpellMap mSpellsReqSpell
 
SpellRequiredMap mSpellReq
 
SpellLearnSkillMap mSpellLearnSkills
 
SpellLearnSpellMap mSpellLearnSpells
 
SpellTargetPositionMap mSpellTargetPositions
 
SpellSpellGroupMap mSpellSpellGroup
 
SpellGroupSpellMap mSpellGroupSpell
 
SpellGroupStackMap mSpellGroupStack
 
SpellProcEventMap mSpellProcEventMap
 
SpellProcMap mSpellProcMap
 
SpellThreatMap mSpellThreatMap
 
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
 

Constructor & Destructor Documentation

SpellMgr::SpellMgr ( )
private
468 { }
SpellMgr::~SpellMgr ( )
private
471 {
473 }
void UnloadSpellInfoStore()
Definition: SpellMgr.cpp:2781

+ Here is the call graph for this function:

Member Function Documentation

SpellInfo* SpellMgr::_GetSpellInfo ( uint32  spellId)
inlineprivate
696 { return spellId < GetSpellInfoStoreSize() ? mSpellInfoMap[spellId] : NULL; }
SpellInfoMap mSpellInfoMap
Definition: SpellMgr.h:753
arena_t NULL
Definition: jemalloc_internal.h:624
uint32 GetSpellInfoStoreSize() const
Definition: SpellMgr.h:691

+ Here is the caller graph for this function:

bool SpellMgr::AddSameEffectStackRuleSpellGroups ( SpellInfo const spellInfo,
int32  amount,
std::map< SpellGroup, int32 > &  groups 
) const
747 {
748  uint32 spellId = spellInfo->GetFirstRankSpell()->Id;
750  // Find group with SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT if it belongs to one
751  for (SpellSpellGroupMap::const_iterator itr = spellGroup.first; itr != spellGroup.second; ++itr)
752  {
753  SpellGroup group = itr->second;
754  SpellGroupStackMap::const_iterator found = mSpellGroupStack.find(group);
755  if (found != mSpellGroupStack.end())
756  {
758  {
759  // Put the highest amount in the map
760  if (groups.find(group) == groups.end())
761  groups[group] = amount;
762  else
763  {
764  int32 curr_amount = groups[group];
765  // Take absolute value because this also counts for the highest negative aura
766  if (abs(curr_amount) < abs(amount))
767  groups[group] = amount;
768  }
769  // return because a spell should be in only one SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT group
770  return true;
771  }
772  }
773  }
774  // Not in a SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT group, so return false
775  return false;
776 }
G3D::Matrix abs(const G3D::Matrix &M)
Definition: Matrix.h:632
SpellGroup
Definition: SpellMgr.h:317
std::pair< SpellSpellGroupMap::const_iterator, SpellSpellGroupMap::const_iterator > SpellSpellGroupMapBounds
Definition: SpellMgr.h:331
int32_t int32
Definition: Define.h:146
uint32_t uint32
Definition: Define.h:150
SpellGroupStackMap mSpellGroupStack
Definition: SpellMgr.h:737
SpellSpellGroupMapBounds GetSpellSpellGroupMapBounds(uint32 spell_id) const
Definition: SpellMgr.cpp:697

+ Here is the call graph for this function:

SpellInfo const* SpellMgr::AssertSpellInfo ( uint32  spellId) const
inline
685  {
686  ASSERT(spellId < GetSpellInfoStoreSize());
687  SpellInfo const* spellInfo = mSpellInfoMap[spellId];
688  ASSERT(spellInfo);
689  return spellInfo;
690  }
SpellInfoMap mSpellInfoMap
Definition: SpellMgr.h:753
Definition: SpellInfo.h:326
uint32 GetSpellInfoStoreSize() const
Definition: SpellMgr.h:691
#define ASSERT
Definition: Errors.h:55
bool SpellMgr::CanSpellTriggerProcOnEvent ( SpellProcEntry const procEntry,
ProcEventInfo eventInfo 
) const
1006 {
1007  // proc type doesn't match
1008  if (!(eventInfo.GetTypeMask() & procEntry.typeMask))
1009  return false;
1010 
1011  // check XP or honor target requirement
1012  if (procEntry.attributesMask & PROC_ATTR_REQ_EXP_OR_HONOR)
1013  if (Player* actor = eventInfo.GetActor()->ToPlayer())
1014  if (eventInfo.GetActionTarget() && !actor->isHonorOrXPTarget(eventInfo.GetActionTarget()))
1015  return false;
1016 
1017  // always trigger for these types
1019  return true;
1020 
1021  // check school mask (if set) for other trigger types
1022  if (procEntry.schoolMask && !(eventInfo.GetSchoolMask() & procEntry.schoolMask))
1023  return false;
1024 
1025  // check spell family name/flags (if set) for spells
1027  {
1028  SpellInfo const* eventSpellInfo = eventInfo.GetSpellInfo();
1029 
1030  if (procEntry.spellFamilyName && eventSpellInfo && (procEntry.spellFamilyName != eventSpellInfo->SpellFamilyName))
1031  return false;
1032 
1033  if (procEntry.spellFamilyMask && eventSpellInfo && !(procEntry.spellFamilyMask & eventSpellInfo->SpellFamilyFlags))
1034  return false;
1035  }
1036 
1037  // check spell type mask (if set)
1039  {
1040  if (procEntry.spellTypeMask && !(eventInfo.GetSpellTypeMask() & procEntry.spellTypeMask))
1041  return false;
1042  }
1043 
1044  // check spell phase mask
1045  if (eventInfo.GetTypeMask() & REQ_SPELL_PHASE_PROC_FLAG_MASK)
1046  {
1047  if (!(eventInfo.GetSpellPhaseMask() & procEntry.spellPhaseMask))
1048  return false;
1049  }
1050 
1051  // check hit mask (on taken hit or on done hit, but not on spell cast phase)
1052  if ((eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK) || ((eventInfo.GetTypeMask() & DONE_HIT_PROC_FLAG_MASK) && !(eventInfo.GetSpellPhaseMask() & PROC_SPELL_PHASE_CAST)))
1053  {
1054  uint32 hitMask = procEntry.hitMask;
1055  // get default values if hit mask not set
1056  if (!hitMask)
1057  {
1058  // for taken procs allow normal + critical hits by default
1059  if (eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK)
1060  hitMask |= PROC_HIT_NORMAL | PROC_HIT_CRITICAL;
1061  // for done procs allow normal + critical + absorbs by default
1062  else
1064  }
1065  if (!(eventInfo.GetHitMask() & hitMask))
1066  return false;
1067  }
1068 
1069  return true;
1070 }
Definition: SpellMgr.h:254
Definition: SpellMgr.h:112
uint32 GetSpellTypeMask() const
Definition: Unit.h:996
Definition: SpellMgr.h:172
Definition: SpellInfo.h:326
SpellInfo const * GetSpellInfo() const
Definition: Unit.cpp:173
flag128 SpellFamilyFlags
Definition: SpellInfo.h:397
uint32 GetSpellPhaseMask() const
Definition: Unit.h:997
uint32 GetHitMask() const
Definition: Unit.h:998
Definition: SpellMgr.h:245
Unit * GetActionTarget() const
Definition: Unit.h:992
Player * ToPlayer()
Definition: Object.h:191
Definition: SpellMgr.h:184
uint32 SpellFamilyName
Definition: SpellInfo.h:396
Definition: SpellMgr.h:161
Definition: SpellMgr.h:142
uint32_t uint32
Definition: Define.h:150
Definition: SpellMgr.h:111
SpellSchoolMask GetSchoolMask() const
Definition: Unit.cpp:185
Definition: SpellMgr.h:273
Unit * GetActor()
Definition: Unit.h:991
Definition: SpellMgr.h:170
Definition: SpellMgr.h:264
Definition: SpellMgr.h:147
uint32 GetTypeMask() const
Definition: Unit.h:995
Definition: SpellMgr.h:255
Definition: SpellMgr.h:178

+ Here is the call graph for this function:

SpellGroupStackRule SpellMgr::CheckSpellGroupStackRules ( SpellInfo const spellInfo1,
SpellInfo const spellInfo2 
) const
779 {
780  uint32 spellid_1 = spellInfo1->GetFirstRankSpell()->Id;
781  uint32 spellid_2 = spellInfo2->GetFirstRankSpell()->Id;
782  if (spellid_1 == spellid_2)
784  // find SpellGroups which are common for both spells
785  SpellSpellGroupMapBounds spellGroup1 = GetSpellSpellGroupMapBounds(spellid_1);
786  std::set<SpellGroup> groups;
787  for (SpellSpellGroupMap::const_iterator itr = spellGroup1.first; itr != spellGroup1.second; ++itr)
788  {
789  if (IsSpellMemberOfSpellGroup(spellid_2, itr->second))
790  {
791  bool add = true;
792  SpellGroupSpellMapBounds groupSpell = GetSpellGroupSpellMapBounds(itr->second);
793  for (SpellGroupSpellMap::const_iterator itr2 = groupSpell.first; itr2 != groupSpell.second; ++itr2)
794  {
795  if (itr2->second < 0)
796  {
797  SpellGroup currGroup = (SpellGroup)abs(itr2->second);
798  if (IsSpellMemberOfSpellGroup(spellid_1, currGroup) && IsSpellMemberOfSpellGroup(spellid_2, currGroup))
799  {
800  add = false;
801  break;
802  }
803  }
804  }
805  if (add)
806  groups.insert(itr->second);
807  }
808  }
809 
811 
812  for (std::set<SpellGroup>::iterator itr = groups.begin(); itr!= groups.end(); ++itr)
813  {
814  SpellGroupStackMap::const_iterator found = mSpellGroupStack.find(*itr);
815  if (found != mSpellGroupStack.end())
816  rule = found->second;
817  if (rule)
818  break;
819  }
820  return rule;
821 }
G3D::Matrix abs(const G3D::Matrix &M)
Definition: Matrix.h:632
SpellGroupSpellMapBounds GetSpellGroupSpellMapBounds(SpellGroup group_id) const
Definition: SpellMgr.cpp:714
std::pair< SpellGroupSpellMap::const_iterator, SpellGroupSpellMap::const_iterator > SpellGroupSpellMapBounds
Definition: SpellMgr.h:335
SpellGroup
Definition: SpellMgr.h:317
std::pair< SpellSpellGroupMap::const_iterator, SpellSpellGroupMap::const_iterator > SpellSpellGroupMapBounds
Definition: SpellMgr.h:331
uint32_t uint32
Definition: Define.h:150
bool IsSpellMemberOfSpellGroup(uint32 spellid, SpellGroup groupid) const
Definition: SpellMgr.cpp:703
SpellGroupStackRule
Definition: SpellMgr.h:337
SpellGroupStackMap mSpellGroupStack
Definition: SpellMgr.h:737
Definition: SpellMgr.h:339
SpellSpellGroupMapBounds GetSpellSpellGroupMapBounds(uint32 spell_id) const
Definition: SpellMgr.cpp:697

+ Here is the call graph for this function:

uint32 SpellMgr::GetFirstSpellInChain ( uint32  spell_id) const
587 {
588  if (SpellChainNode const* node = GetSpellChainNode(spell_id))
589  return node->first->Id;
590 
591  return spell_id;
592 }
SpellChainNode const * GetSpellChainNode(uint32 spell_id) const
Definition: SpellMgr.cpp:577
Definition: SpellMgr.h:507

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

uint32 SpellMgr::GetLastSpellInChain ( uint32  spell_id) const
595 {
596  if (SpellChainNode const* node = GetSpellChainNode(spell_id))
597  return node->last->Id;
598 
599  return spell_id;
600 }
SpellChainNode const * GetSpellChainNode(uint32 spell_id) const
Definition: SpellMgr.cpp:577
Definition: SpellMgr.h:507

+ Here is the call graph for this function:

uint32 SpellMgr::GetNextSpellInChain ( uint32  spell_id) const
603 {
604  if (SpellChainNode const* node = GetSpellChainNode(spell_id))
605  if (node->next)
606  return node->next->Id;
607 
608  return 0;
609 }
SpellChainNode const * GetSpellChainNode(uint32 spell_id) const
Definition: SpellMgr.cpp:577
Definition: SpellMgr.h:507

+ Here is the call graph for this function:

PetAura const * SpellMgr::GetPetAura ( uint32  spell_id,
uint8  eff 
) const
1093 {
1094  SpellPetAuraMap::const_iterator itr = mSpellPetAuraMap.find((spell_id<<8) + eff);
1095  if (itr != mSpellPetAuraMap.end())
1096  return &itr->second;
1097  else
1098  return NULL;
1099 }
SpellPetAuraMap mSpellPetAuraMap
Definition: SpellMgr.h:741
arena_t NULL
Definition: jemalloc_internal.h:624
PetDefaultSpellsEntry const * SpellMgr::GetPetDefaultSpellsEntry ( int32  id) const
1130 {
1131  PetDefaultSpellsMap::const_iterator itr = mPetDefaultSpellsMap.find(id);
1132  if (itr != mPetDefaultSpellsMap.end())
1133  return &itr->second;
1134  return NULL;
1135 }
arena_t NULL
Definition: jemalloc_internal.h:624
PetDefaultSpellsMap mPetDefaultSpellsMap
Definition: SpellMgr.h:752
PetLevelupSpellSet const * SpellMgr::GetPetLevelupSpellList ( uint32  petFamily) const
1121 {
1122  PetLevelupSpellMap::const_iterator itr = mPetLevelupSpellMap.find(petFamily);
1123  if (itr != mPetLevelupSpellMap.end())
1124  return &itr->second;
1125  else
1126  return NULL;
1127 }
PetLevelupSpellMap mPetLevelupSpellMap
Definition: SpellMgr.h:751
arena_t NULL
Definition: jemalloc_internal.h:624
uint32 SpellMgr::GetPrevSpellInChain ( uint32  spell_id) const
612 {
613  if (SpellChainNode const* node = GetSpellChainNode(spell_id))
614  if (node->prev)
615  return node->prev->Id;
616 
617  return 0;
618 }
SpellChainNode const * GetSpellChainNode(uint32 spell_id) const
Definition: SpellMgr.cpp:577
Definition: SpellMgr.h:507

+ Here is the call graph for this function:

void SpellMgr::GetSetOfSpellsInSpellGroup ( SpellGroup  group_id,
std::set< uint32 > &  foundSpells 
) const
720 {
721  std::set<SpellGroup> usedGroups;
722  GetSetOfSpellsInSpellGroup(group_id, foundSpells, usedGroups);
723 }
void GetSetOfSpellsInSpellGroup(SpellGroup group_id, std::set< uint32 > &foundSpells) const
Definition: SpellMgr.cpp:719

+ Here is the caller graph for this function:

void SpellMgr::GetSetOfSpellsInSpellGroup ( SpellGroup  group_id,
std::set< uint32 > &  foundSpells,
std::set< SpellGroup > &  usedGroups 
) const
726 {
727  if (usedGroups.find(group_id) != usedGroups.end())
728  return;
729  usedGroups.insert(group_id);
730 
732  for (SpellGroupSpellMap::const_iterator itr = groupSpell.first; itr != groupSpell.second; ++itr)
733  {
734  if (itr->second < 0)
735  {
736  SpellGroup currGroup = (SpellGroup)abs(itr->second);
737  GetSetOfSpellsInSpellGroup(currGroup, foundSpells, usedGroups);
738  }
739  else
740  {
741  foundSpells.insert(itr->second);
742  }
743  }
744 }
G3D::Matrix abs(const G3D::Matrix &M)
Definition: Matrix.h:632
SpellGroupSpellMapBounds GetSpellGroupSpellMapBounds(SpellGroup group_id) const
Definition: SpellMgr.cpp:714
std::pair< SpellGroupSpellMap::const_iterator, SpellGroupSpellMap::const_iterator > SpellGroupSpellMapBounds
Definition: SpellMgr.h:335
SpellGroup
Definition: SpellMgr.h:317
void GetSetOfSpellsInSpellGroup(SpellGroup group_id, std::set< uint32 > &foundSpells) const
Definition: SpellMgr.cpp:719

+ Here is the call graph for this function:

SkillLineAbilityMapBounds SpellMgr::GetSkillLineAbilityMapBounds ( uint32  spell_id) const
1088 {
1089  return mSkillLineAbilityMap.equal_range(spell_id);
1090 }
SkillLineAbilityMap mSkillLineAbilityMap
Definition: SpellMgr.h:750
SpellAreaForAreaMapBounds SpellMgr::GetSpellAreaForAreaMapBounds ( uint32  area_id) const
1158 {
1159  return mSpellAreaForAreaMap.equal_range(area_id);
1160 }
SpellAreaForAreaMap mSpellAreaForAreaMap
Definition: SpellMgr.h:749
SpellAreaForAuraMapBounds SpellMgr::GetSpellAreaForAuraMapBounds ( uint32  spell_id) const
1153 {
1154  return mSpellAreaForAuraMap.equal_range(spell_id);
1155 }
SpellAreaForAuraMap mSpellAreaForAuraMap
Definition: SpellMgr.h:748

+ Here is the caller graph for this function:

SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestEndMapBounds ( uint32  quest_id) const
1148 {
1149  return mSpellAreaForQuestEndMap.equal_range(quest_id);
1150 }
SpellAreaForQuestMap mSpellAreaForQuestEndMap
Definition: SpellMgr.h:747
SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestMapBounds ( uint32  quest_id) const
1143 {
1144  return mSpellAreaForQuestMap.equal_range(quest_id);
1145 }
SpellAreaForQuestMap mSpellAreaForQuestMap
Definition: SpellMgr.h:746
SpellAreaMapBounds SpellMgr::GetSpellAreaMapBounds ( uint32  spell_id) const
1138 {
1139  return mSpellAreaMap.equal_range(spell_id);
1140 }
SpellAreaMap mSpellAreaMap
Definition: SpellMgr.h:745

+ Here is the caller graph for this function:

SpellChainNode const * SpellMgr::GetSpellChainNode ( uint32  spell_id) const
578 {
579  SpellChainMap::const_iterator itr = mSpellChains.find(spell_id);
580  if (itr == mSpellChains.end())
581  return NULL;
582 
583  return &itr->second;
584 }
arena_t NULL
Definition: jemalloc_internal.h:624
SpellChainMap mSpellChains
Definition: SpellMgr.h:729

+ Here is the caller graph for this function:

SpellEnchantProcEntry const * SpellMgr::GetSpellEnchantProcEvent ( uint32  enchId) const
1102 {
1103  SpellEnchantProcEventMap::const_iterator itr = mSpellEnchantProcEventMap.find(enchId);
1104  if (itr != mSpellEnchantProcEventMap.end())
1105  return &itr->second;
1106  return NULL;
1107 }
SpellEnchantProcEventMap mSpellEnchantProcEventMap
Definition: SpellMgr.h:743
arena_t NULL
Definition: jemalloc_internal.h:624
SpellGroupSpellMapBounds SpellMgr::GetSpellGroupSpellMapBounds ( SpellGroup  group_id) const
715 {
716  return mSpellGroupSpell.equal_range(group_id);
717 }
SpellGroupSpellMap mSpellGroupSpell
Definition: SpellMgr.h:736

+ Here is the caller graph for this function:

SpellGroupStackRule SpellMgr::GetSpellGroupStackRule ( SpellGroup  groupid) const
824 {
825  SpellGroupStackMap::const_iterator itr = mSpellGroupStack.find(group);
826  if (itr != mSpellGroupStack.end())
827  return itr->second;
828 
830 }
SpellGroupStackMap mSpellGroupStack
Definition: SpellMgr.h:737
Definition: SpellMgr.h:339
SpellInfo const* SpellMgr::GetSpellInfo ( uint32  spellId) const
inline
682 { return spellId < GetSpellInfoStoreSize() ? mSpellInfoMap[spellId] : NULL; }
SpellInfoMap mSpellInfoMap
Definition: SpellMgr.h:753
arena_t NULL
Definition: jemalloc_internal.h:624
uint32 GetSpellInfoStoreSize() const
Definition: SpellMgr.h:691

+ Here is the caller graph for this function:

uint32 SpellMgr::GetSpellInfoStoreSize ( ) const
inline
691 { return uint32(mSpellInfoMap.size()); }
SpellInfoMap mSpellInfoMap
Definition: SpellMgr.h:753
uint32_t uint32
Definition: g3dmath.h:168

+ Here is the caller graph for this function:

SpellLearnSkillNode const * SpellMgr::GetSpellLearnSkill ( uint32  spell_id) const
662 {
663  SpellLearnSkillMap::const_iterator itr = mSpellLearnSkills.find(spell_id);
664  if (itr != mSpellLearnSkills.end())
665  return &itr->second;
666  else
667  return NULL;
668 }
arena_t NULL
Definition: jemalloc_internal.h:624
SpellLearnSkillMap mSpellLearnSkills
Definition: SpellMgr.h:732
SpellLearnSpellMapBounds SpellMgr::GetSpellLearnSpellMapBounds ( uint32  spell_id) const
671 {
672  return mSpellLearnSpells.equal_range(spell_id);
673 }
SpellLearnSpellMap mSpellLearnSpells
Definition: SpellMgr.h:733

+ Here is the caller graph for this function:

const std::vector< int32 > * SpellMgr::GetSpellLinked ( int32  spell_id) const
1115 {
1116  SpellLinkedMap::const_iterator itr = mSpellLinkedMap.find(spell_id);
1117  return itr != mSpellLinkedMap.end() ? &(itr->second) : NULL;
1118 }
arena_t NULL
Definition: jemalloc_internal.h:624
SpellLinkedMap mSpellLinkedMap
Definition: SpellMgr.h:742
SpellProcEntry const * SpellMgr::GetSpellProcEntry ( uint32  spellId) const
998 {
999  SpellProcMap::const_iterator itr = mSpellProcMap.find(spellId);
1000  if (itr != mSpellProcMap.end())
1001  return &itr->second;
1002  return NULL;
1003 }
arena_t NULL
Definition: jemalloc_internal.h:624
SpellProcMap mSpellProcMap
Definition: SpellMgr.h:739
SpellProcEventEntry const * SpellMgr::GetSpellProcEvent ( uint32  spellId) const
833 {
834  SpellProcEventMap::const_iterator itr = mSpellProcEventMap.find(spellId);
835  if (itr != mSpellProcEventMap.end())
836  return &itr->second;
837  return NULL;
838 }
SpellProcEventMap mSpellProcEventMap
Definition: SpellMgr.h:738
arena_t NULL
Definition: jemalloc_internal.h:624
uint8 SpellMgr::GetSpellRank ( uint32  spell_id) const
621 {
622  if (SpellChainNode const* node = GetSpellChainNode(spell_id))
623  return node->rank;
624 
625  return 0;
626 }
SpellChainNode const * GetSpellChainNode(uint32 spell_id) const
Definition: SpellMgr.cpp:577
Definition: SpellMgr.h:507

+ Here is the call graph for this function:

SpellSpellGroupMapBounds SpellMgr::GetSpellSpellGroupMapBounds ( uint32  spell_id) const
698 {
699  spell_id = GetFirstSpellInChain(spell_id);
700  return mSpellSpellGroup.equal_range(spell_id);
701 }
SpellSpellGroupMap mSpellSpellGroup
Definition: SpellMgr.h:735
uint32 GetFirstSpellInChain(uint32 spell_id) const
Definition: SpellMgr.cpp:586

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

SpellRequiredMapBounds SpellMgr::GetSpellsRequiredForSpellBounds ( uint32  spell_id) const
641 {
642  return mSpellReq.equal_range(spell_id);
643 }
SpellRequiredMap mSpellReq
Definition: SpellMgr.h:731
SpellsRequiringSpellMapBounds SpellMgr::GetSpellsRequiringSpellBounds ( uint32  spell_id) const
646 {
647  return mSpellsReqSpell.equal_range(spell_id);
648 }
SpellsRequiringSpellMap mSpellsReqSpell
Definition: SpellMgr.h:730

+ Here is the caller graph for this function:

SpellTargetPosition const * SpellMgr::GetSpellTargetPosition ( uint32  spell_id,
SpellEffIndex  effIndex 
) const
690 {
691  SpellTargetPositionMap::const_iterator itr = mSpellTargetPositions.find(std::make_pair(spell_id, effIndex));
692  if (itr != mSpellTargetPositions.end())
693  return &itr->second;
694  return NULL;
695 }
arena_t NULL
Definition: jemalloc_internal.h:624
SpellTargetPositionMap mSpellTargetPositions
Definition: SpellMgr.h:734
SpellThreatEntry const * SpellMgr::GetSpellThreatEntry ( uint32  spellID) const
1073 {
1074  SpellThreatMap::const_iterator itr = mSpellThreatMap.find(spellID);
1075  if (itr != mSpellThreatMap.end())
1076  return &itr->second;
1077  else
1078  {
1079  uint32 firstSpell = GetFirstSpellInChain(spellID);
1080  itr = mSpellThreatMap.find(firstSpell);
1081  if (itr != mSpellThreatMap.end())
1082  return &itr->second;
1083  }
1084  return NULL;
1085 }
arena_t NULL
Definition: jemalloc_internal.h:624
uint32 GetFirstSpellInChain(uint32 spell_id) const
Definition: SpellMgr.cpp:586
uint32_t uint32
Definition: Define.h:150
SpellThreatMap mSpellThreatMap
Definition: SpellMgr.h:740

+ Here is the call graph for this function:

uint32 SpellMgr::GetSpellWithRank ( uint32  spell_id,
uint32  rank,
bool  strict = false 
) const
629 {
630  if (SpellChainNode const* node = GetSpellChainNode(spell_id))
631  {
632  if (rank != node->rank)
633  return GetSpellWithRank(node->rank < rank ? node->next->Id : node->prev->Id, rank, strict);
634  }
635  else if (strict && rank > 1)
636  return 0;
637  return spell_id;
638 }
uint32 GetSpellWithRank(uint32 spell_id, uint32 rank, bool strict=false) const
Definition: SpellMgr.cpp:628
SpellChainNode const * GetSpellChainNode(uint32 spell_id) const
Definition: SpellMgr.cpp:577
Definition: SpellMgr.h:507

+ Here is the call graph for this function:

SpellMgr * SpellMgr::instance ( )
static
476 {
477  static SpellMgr instance;
478  return &instance;
479 }
Definition: SpellMgr.h:600
static SpellMgr * instance()
Definition: SpellMgr.cpp:475
bool SpellMgr::IsArenaAllowedEnchancment ( uint32  ench_id) const
1110 {
1111  return mEnchantCustomAttr[ench_id];
1112 }
EnchantCustomAttribute mEnchantCustomAttr
Definition: SpellMgr.h:744
bool SpellMgr::IsSpellLearnSpell ( uint32  spell_id) const
676 {
677  return mSpellLearnSpells.find(spell_id) != mSpellLearnSpells.end();
678 }
SpellLearnSpellMap mSpellLearnSpells
Definition: SpellMgr.h:733
bool SpellMgr::IsSpellLearnToSpell ( uint32  spell_id1,
uint32  spell_id2 
) const
681 {
683  for (SpellLearnSpellMap::const_iterator i = bounds.first; i != bounds.second; ++i)
684  if (i->second.Spell == spell_id2)
685  return true;
686  return false;
687 }
SpellLearnSpellMapBounds GetSpellLearnSpellMapBounds(uint32 spell_id) const
Definition: SpellMgr.cpp:670
std::pair< SpellLearnSpellMap::const_iterator, SpellLearnSpellMap::const_iterator > SpellLearnSpellMapBounds
Definition: SpellMgr.h:546

+ Here is the call graph for this function:

bool SpellMgr::IsSpellMemberOfSpellGroup ( uint32  spellid,
SpellGroup  groupid 
) const
704 {
706  for (SpellSpellGroupMap::const_iterator itr = spellGroup.first; itr != spellGroup.second; ++itr)
707  {
708  if (itr->second == groupid)
709  return true;
710  }
711  return false;
712 }
std::pair< SpellSpellGroupMap::const_iterator, SpellSpellGroupMap::const_iterator > SpellSpellGroupMapBounds
Definition: SpellMgr.h:331
SpellSpellGroupMapBounds GetSpellSpellGroupMapBounds(uint32 spell_id) const
Definition: SpellMgr.cpp:697

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool SpellMgr::IsSpellProcEventCanTriggeredBy ( SpellInfo const spellProto,
SpellProcEventEntry const spellProcEvent,
uint32  EventProcFlag,
SpellInfo const procSpell,
uint32  procFlags,
uint32  procExtra,
bool  active 
) const

Check auras procced by periodics

Only damaging Dots can proc auras with PROC_FLAG_TAKEN_DAMAGE

Only Dots can proc if ONLY has PROC_FLAG_DONE_PERIODIC or PROC_FLAG_TAKEN_PERIODIC.

Hots can proc if ONLY has PROC_FLAG_DONE_PERIODIC and spellfamily != 0

Only Dots can proc auras with PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG or PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG

Only Hots can proc auras with PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS or PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS

Only Dots can proc auras with PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG or PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG

Only Hots can proc auras with PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS or PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS

Parameters
procSpellthe spell proccing the aura
procFlagsproc_flags of spellProc
procExtraproc_EX of procSpell
EventProcFlagproc_flags of aura to be procced
spellProtoSpellInfo of aura to be procced

Quick Check - If PROC_FLAG_TAKEN_DAMAGE is set for aura and procSpell dealt damage, proc no matter what kind of spell that deals the damage.

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

841 {
842  // No extra req need
843  uint32 procEvent_procEx = PROC_EX_NONE;
844 
845  // check prockFlags for condition
846  if ((procFlags & EventProcFlag) == 0)
847  return false;
848 
849  bool hasFamilyMask = false;
850 
877  if (procFlags & PROC_FLAG_TAKEN_DAMAGE && EventProcFlag & PROC_FLAG_TAKEN_DAMAGE)
879  return true;
880 
881  if (procFlags & PROC_FLAG_DONE_PERIODIC && EventProcFlag & PROC_FLAG_DONE_PERIODIC)
882  {
883  if (procExtra & PROC_EX_INTERNAL_HOT)
884  {
885  if (EventProcFlag == PROC_FLAG_DONE_PERIODIC)
886  {
888  if (!spellProto->SpellFamilyName)
889  return false;
890  }
893  return false;
894  }
896  else if (EventProcFlag != PROC_FLAG_DONE_PERIODIC)
898  return false;
899  }
900 
901  if (procFlags & PROC_FLAG_TAKEN_PERIODIC && EventProcFlag & PROC_FLAG_TAKEN_PERIODIC)
902  {
903  if (procExtra & PROC_EX_INTERNAL_HOT)
904  {
906  if (EventProcFlag == PROC_FLAG_TAKEN_PERIODIC)
907  return false;
910  return false;
911  }
913  else if (EventProcFlag != PROC_FLAG_TAKEN_PERIODIC)
915  return false;
916  }
917  // Trap casts are active by default
918  if (procFlags & PROC_FLAG_DONE_TRAP_ACTIVATION)
919  active = true;
920 
921  // Always trigger for this
922  if (procFlags & (PROC_FLAG_KILLED | PROC_FLAG_KILL | PROC_FLAG_DEATH))
923  return true;
924 
925  if (spellProcEvent) // Exist event data
926  {
927  // Store extra req
928  procEvent_procEx = spellProcEvent->procEx;
929 
930  // For melee triggers
931  if (procSpell == NULL)
932  {
933  // Check (if set) for school (melee attack have Normal school)
934  if (spellProcEvent->schoolMask && (spellProcEvent->schoolMask & SPELL_SCHOOL_MASK_NORMAL) == 0)
935  return false;
936  }
937  else // For spells need check school/spell family/family mask
938  {
939  // Check (if set) for school
940  if (spellProcEvent->schoolMask && (spellProcEvent->schoolMask & procSpell->SchoolMask) == 0)
941  return false;
942 
943  // Check (if set) for spellFamilyName
944  if (spellProcEvent->spellFamilyName && (spellProcEvent->spellFamilyName != procSpell->SpellFamilyName))
945  return false;
946 
947  // spellFamilyName is Ok need check for spellFamilyMask if present
948  if (spellProcEvent->spellFamilyMask)
949  {
950  if (!(spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags))
951  return false;
952  hasFamilyMask = true;
953  // Some spells are not considered as active even with have spellfamilyflags
954  if (!(procEvent_procEx & PROC_EX_ONLY_ACTIVE_SPELL))
955  active = true;
956  }
957  }
958  }
959 
960  if (procExtra & (PROC_EX_INTERNAL_REQ_FAMILY))
961  {
962  if (!hasFamilyMask)
963  return false;
964  }
965 
966  // Check for extra req (if none) and hit/crit
967  if (procEvent_procEx == PROC_EX_NONE)
968  {
969  // No extra req, so can trigger only for hit/crit - spell has to be active
970  if ((procExtra & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) && active)
971  return true;
972  }
973  else // Passive spells hits here only if resist/reflect/immune/evade
974  {
975  if (procExtra & AURA_SPELL_PROC_EX_MASK)
976  {
977  // if spell marked as procing only from not active spells
978  if (active && procEvent_procEx & PROC_EX_NOT_ACTIVE_SPELL)
979  return false;
980  // if spell marked as procing only from active spells
981  if (!active && procEvent_procEx & PROC_EX_ONLY_ACTIVE_SPELL)
982  return false;
983  // Exist req for PROC_EX_EX_TRIGGER_ALWAYS
984  if (procEvent_procEx & PROC_EX_EX_TRIGGER_ALWAYS)
985  return true;
986  // PROC_EX_NOT_ACTIVE_SPELL and PROC_EX_ONLY_ACTIVE_SPELL flags handle: if passed checks before
987  if ((procExtra & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) && ((procEvent_procEx & (AURA_SPELL_PROC_EX_MASK)) == 0))
988  return true;
989  }
990  // Check Extra Requirement like (hit/crit/miss/resist/parry/dodge/block/immune/reflect/absorb and other)
991  if (procEvent_procEx & procExtra)
992  return true;
993  }
994  return false;
995 }
Definition: SpellMgr.h:200
Definition: SpellMgr.h:112
Definition: SpellMgr.h:198
Definition: SpellMgr.h:129
arena_t NULL
Definition: jemalloc_internal.h:624
Definition: SpellMgr.h:138
Definition: SpellMgr.h:139
Definition: SpellMgr.h:222
Definition: SpellMgr.h:214
Definition: SpellMgr.h:126
Definition: SharedDefines.h:288
Definition: SpellMgr.h:141
Definition: SpellMgr.h:142
Definition: SpellMgr.h:215
uint32_t uint32
Definition: Define.h:150
Definition: SpellMgr.h:111
Definition: SpellMgr.h:199
Definition: SpellMgr.h:217
Definition: SpellMgr.h:224
Definition: SpellMgr.h:147
#define AURA_SPELL_PROC_EX_MASK
Definition: SpellMgr.h:227
bool SpellMgr::IsSpellRequiringSpell ( uint32  spellid,
uint32  req_spellid 
) const
651 {
652  SpellsRequiringSpellMapBounds spellsRequiringSpell = GetSpellsRequiringSpellBounds(req_spellid);
653  for (SpellsRequiringSpellMap::const_iterator itr = spellsRequiringSpell.first; itr != spellsRequiringSpell.second; ++itr)
654  {
655  if (itr->second == spellid)
656  return true;
657  }
658  return false;
659 }
SpellsRequiringSpellMapBounds GetSpellsRequiringSpellBounds(uint32 spell_id) const
Definition: SpellMgr.cpp:645
std::pair< SpellsRequiringSpellMap::const_iterator, SpellsRequiringSpellMap::const_iterator > SpellsRequiringSpellMapBounds
Definition: SpellMgr.h:524

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool SpellMgr::IsSpellValid ( SpellInfo const spellInfo,
Player player = NULL,
bool  msg = true 
)
static

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

483 {
484  // not exist
485  if (!spellInfo)
486  return false;
487 
488  bool needCheckReagents = false;
489 
490  // check effects
491  for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(DIFFICULTY_NONE))
492  {
493  if (!effect)
494  continue;
495 
496  switch (effect->Effect)
497  {
498  case 0:
499  continue;
500 
501  // craft spell for crafting non-existed item (break client recipes list show)
504  {
505  if (effect->ItemType == 0)
506  {
507  // skip auto-loot crafting spells, its not need explicit item info (but have special fake items sometime)
508  if (!spellInfo->IsLootCrafting())
509  {
510  if (msg)
511  {
512  if (player)
513  ChatHandler(player->GetSession()).PSendSysMessage("Craft spell %u not have create item entry.", spellInfo->Id);
514  else
515  TC_LOG_ERROR("sql.sql", "Craft spell %u not have create item entry.", spellInfo->Id);
516  }
517  return false;
518  }
519 
520  }
521  // also possible IsLootCrafting case but fake item must exist anyway
522  else if (!sObjectMgr->GetItemTemplate(effect->ItemType))
523  {
524  if (msg)
525  {
526  if (player)
527  ChatHandler(player->GetSession()).PSendSysMessage("Craft spell %u create not-exist in DB item (Entry: %u) and then...", spellInfo->Id, effect->ItemType);
528  else
529  TC_LOG_ERROR("sql.sql", "Craft spell %u create not-exist in DB item (Entry: %u) and then...", spellInfo->Id, effect->ItemType);
530  }
531  return false;
532  }
533 
534  needCheckReagents = true;
535  break;
536  }
538  {
539  SpellInfo const* spellInfo2 = sSpellMgr->GetSpellInfo(effect->TriggerSpell);
540  if (!IsSpellValid(spellInfo2, player, msg))
541  {
542  if (msg)
543  {
544  if (player)
545  ChatHandler(player->GetSession()).PSendSysMessage("Spell %u learn to broken spell %u, and then...", spellInfo->Id, effect->TriggerSpell);
546  else
547  TC_LOG_ERROR("sql.sql", "Spell %u learn to invalid spell %u, and then...", spellInfo->Id, effect->TriggerSpell);
548  }
549  return false;
550  }
551  break;
552  }
553  }
554  }
555 
556  if (needCheckReagents)
557  {
558  for (uint8 j = 0; j < MAX_SPELL_REAGENTS; ++j)
559  {
560  if (spellInfo->Reagent[j] > 0 && !sObjectMgr->GetItemTemplate(spellInfo->Reagent[j]))
561  {
562  if (msg)
563  {
564  if (player)
565  ChatHandler(player->GetSession()).PSendSysMessage("Craft spell %u have not-exist reagent in DB item (Entry: %u) and then...", spellInfo->Id, spellInfo->Reagent[j]);
566  else
567  TC_LOG_ERROR("sql.sql", "Craft spell %u have not-exist reagent in DB item (Entry: %u) and then...", spellInfo->Id, spellInfo->Reagent[j]);
568  }
569  return false;
570  }
571  }
572  }
573 
574  return true;
575 }
Definition: DBCEnums.h:404
Definition: SpellInfo.h:326
Definition: SharedDefines.h:1046
#define sObjectMgr
Definition: ObjectMgr.h:1567
Definition: SharedDefines.h:1034
#define sSpellMgr
Definition: SpellMgr.h:756
Definition: SpellInfo.h:238
static bool IsSpellValid(SpellInfo const *spellInfo, Player *player=NULL, bool msg=true)
Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book...
Definition: SpellMgr.cpp:482
Definition: Chat.h:56
uint8_t uint8
Definition: Define.h:152
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
#define MAX_SPELL_REAGENTS
Definition: DB2Structure.h:1285
Definition: SharedDefines.h:1167

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SpellMgr::LoadEnchantCustomAttr ( )
Todo:
find a better check
2266 {
2267  uint32 oldMSTime = getMSTime();
2268 
2269  uint32 size = sSpellItemEnchantmentStore.GetNumRows();
2270  mEnchantCustomAttr.resize(size);
2271 
2272  for (uint32 i = 0; i < size; ++i)
2273  mEnchantCustomAttr[i] = 0;
2274 
2275  uint32 count = 0;
2276  for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2277  {
2278  SpellInfo const* spellInfo = GetSpellInfo(i);
2279  if (!spellInfo)
2280  continue;
2281 
2284  continue;
2285 
2286  for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(DIFFICULTY_NONE))
2287  {
2288  if (effect && effect->Effect == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY)
2289  {
2290  uint32 enchId = effect->MiscValue;
2291  SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchId);
2292  if (!ench)
2293  continue;
2294  mEnchantCustomAttr[enchId] = true;
2295  ++count;
2296  break;
2297  }
2298  }
2299  }
2300 
2301  TC_LOG_INFO("server.loading", ">> Loaded %u custom enchant attributes in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
2302 }
Definition: DBCEnums.h:404
Definition: SpellInfo.h:326
uint32 getMSTime()
Definition: Timer.h:24
Definition: DBCStructure.h:1214
Definition: SharedDefines.h:441
uint32 GetSpellInfoStoreSize() const
Definition: SpellMgr.h:691
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:462
Definition: SpellInfo.h:238
uint32_t uint32
Definition: Define.h:150
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
SpellInfo const * GetSpellInfo(uint32 spellId) const
Definition: SpellMgr.h:682
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
SpellEffectInfoVector GetEffectsForDifficulty(uint32 difficulty) const
Definition: SpellInfo.cpp:3311
Definition: SharedDefines.h:1064
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
Definition: SharedDefines.h:372
EnchantCustomAttribute mEnchantCustomAttr
Definition: SpellMgr.h:744

+ Here is the call graph for this function:

void SpellMgr::LoadPetDefaultSpells ( )
2510 {
2511  uint32 oldMSTime = getMSTime();
2512 
2513  mPetDefaultSpellsMap.clear();
2514 
2515  uint32 countCreature = 0;
2516 
2517  TC_LOG_INFO("server.loading", "Loading summonable creature templates...");
2518  oldMSTime = getMSTime();
2519 
2520  // different summon spells
2521  for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2522  {
2523  SpellInfo const* spellEntry = GetSpellInfo(i);
2524  if (!spellEntry)
2525  continue;
2526 
2527  for (SpellEffectInfo const* effect : spellEntry->GetEffectsForDifficulty(DIFFICULTY_NONE))
2528  {
2529  if (effect && (effect->Effect == SPELL_EFFECT_SUMMON || effect->Effect == SPELL_EFFECT_SUMMON_PET))
2530  {
2531  uint32 creature_id = effect->MiscValue;
2532  CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id);
2533  if (!cInfo)
2534  continue;
2535 
2536  // get default pet spells from creature_template
2537  int32 petSpellsId = cInfo->Entry;
2538  if (mPetDefaultSpellsMap.find(cInfo->Entry) != mPetDefaultSpellsMap.end())
2539  continue;
2540 
2541  PetDefaultSpellsEntry petDefSpells;
2542  for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
2543  petDefSpells.spellid[j] = cInfo->spells[j];
2544 
2545  if (LoadPetDefaultSpells_helper(cInfo, petDefSpells))
2546  {
2547  mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
2548  ++countCreature;
2549  }
2550  }
2551  }
2552  }
2553 
2554  TC_LOG_INFO("server.loading", ">> Loaded %u summonable creature templates in %u ms", countCreature, GetMSTimeDiffToNow(oldMSTime));
2555 }
Definition: DBCEnums.h:404
uint32 spells[CREATURE_MAX_SPELLS]
Definition: Creature.h:123
#define MAX_CREATURE_SPELL_DATA_SLOT
Definition: SpellMgr.h:559
bool LoadPetDefaultSpells_helper(CreatureTemplate const *cInfo, PetDefaultSpellsEntry &petDefSpells)
Definition: SpellMgr.cpp:2461
Definition: SpellInfo.h:326
uint32 getMSTime()
Definition: Timer.h:24
Definition: SharedDefines.h:1038
#define sObjectMgr
Definition: ObjectMgr.h:1567
uint32 spellid[MAX_CREATURE_SPELL_DATA_SLOT]
Definition: SpellMgr.h:563
Definition: SharedDefines.h:1066
uint32 Entry
Definition: Creature.h:81
uint32 GetSpellInfoStoreSize() const
Definition: SpellMgr.h:691
Definition: SpellInfo.h:238
int32_t int32
Definition: Define.h:146
uint32_t uint32
Definition: Define.h:150
PetDefaultSpellsMap mPetDefaultSpellsMap
Definition: SpellMgr.h:752
SpellInfo const * GetSpellInfo(uint32 spellId) const
Definition: SpellMgr.h:682
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
SpellEffectInfoVector GetEffectsForDifficulty(uint32 difficulty) const
Definition: SpellInfo.cpp:3311
uint8_t uint8
Definition: Define.h:152
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
Definition: Creature.h:79
Definition: SpellMgr.h:561

+ Here is the call graph for this function:

void SpellMgr::LoadPetFamilySpellsStore ( )
3557 {
3558  for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
3559  {
3560  SkillLineAbilityEntry const* skillLine = sSkillLineAbilityStore.LookupEntry(j);
3561  if (!skillLine)
3562  continue;
3563 
3564  SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->SpellID);
3565  if (!spellInfo)
3566  continue;
3567 
3568  SpellLevelsEntry const* levels = sSpellLevelsStore.LookupEntry(spellInfo->LevelsID);
3569  if (spellInfo->LevelsID && (!levels || levels->SpellLevel))
3570  continue;
3571 
3572  if (SpellMiscEntry const* spellMisc = sSpellMiscStore.LookupEntry(spellInfo->MiscID))
3573  {
3574  if (spellMisc->Attributes & SPELL_ATTR0_PASSIVE)
3575  {
3576  for (uint32 i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i)
3577  {
3578  CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i);
3579  if (!cFamily)
3580  continue;
3581 
3582  if (skillLine->SkillLine != cFamily->SkillLine[0] && skillLine->SkillLine != cFamily->SkillLine[1])
3583  continue;
3584 
3586  continue;
3587 
3588  sPetFamilySpellsStore[i].insert(spellInfo->ID);
3589  }
3590  }
3591  }
3592  }
3593 }
uint32 LevelsID
Definition: DBCStructure.h:1073
uint32 MiscID
Definition: DBCStructure.h:1079
Definition: DBCStructure.h:1148
Definition: SharedDefines.h:362
uint32 AquireMethod
Definition: DBCStructure.h:974
DBCStorage< SpellLevelsEntry > sSpellLevelsStore(SpellLevelsfmt)
uint32 SpellLevel
Definition: DBCStructure.h:1155
uint32 SkillLine
Definition: DBCStructure.h:968
uint32 SpellID
Definition: DBCStructure.h:969
DBCStorage< SpellEntry > sSpellStore(Spellfmt)
DB2Storage< SpellMiscEntry > sSpellMiscStore("SpellMisc.db2", SpellMiscFormat, HOTFIX_SEL_SPELL_MISC)
Definition: DB2Structure.h:1211
uint32_t uint32
Definition: Define.h:150
DBCStorage< CreatureFamilyEntry > sCreatureFamilyStore(CreatureFamilyfmt)
PetFamilySpellsStore sPetFamilySpellsStore
Definition: SpellMgr.cpp:31
Definition: DBCStructure.h:1054
uint32 SkillLine[2]
Definition: DBCStructure.h:286
uint32 ID
Definition: DBCStructure.h:1056
Definition: DBCStructure.h:965
Definition: DBCStructure.h:279
DBCStorage< SkillLineAbilityEntry > sSkillLineAbilityStore(SkillLineAbilityfmt)
void SpellMgr::LoadPetLevelupSpellMap ( )
2406 {
2407  uint32 oldMSTime = getMSTime();
2408 
2409  mPetLevelupSpellMap.clear(); // need for reload case
2410 
2411  uint32 count = 0;
2412  uint32 family_count = 0;
2413 
2414  for (uint32 i = 0; i < sCreatureFamilyStore.GetNumRows(); ++i)
2415  {
2416  CreatureFamilyEntry const* creatureFamily = sCreatureFamilyStore.LookupEntry(i);
2417  if (!creatureFamily) // not exist
2418  continue;
2419 
2420  for (uint8 j = 0; j < 2; ++j)
2421  {
2422  if (!creatureFamily->SkillLine[j])
2423  continue;
2424 
2425  for (uint32 k = 0; k < sSkillLineAbilityStore.GetNumRows(); ++k)
2426  {
2427  SkillLineAbilityEntry const* skillLine = sSkillLineAbilityStore.LookupEntry(k);
2428  if (!skillLine)
2429  continue;
2430 
2431  //if (skillLine->skillId != creatureFamily->SkillLine[0] &&
2432  // (!creatureFamily->SkillLine[1] || skillLine->skillId != creatureFamily->SkillLine[1]))
2433  // continue;
2434 
2435  if (skillLine->SkillLine != creatureFamily->SkillLine[j])
2436  continue;
2437 
2439  continue;
2440 
2441  SpellInfo const* spell = GetSpellInfo(skillLine->SpellID);
2442  if (!spell) // not exist or triggered or talent
2443  continue;
2444 
2445  if (!spell->SpellLevel)
2446  continue;
2447 
2448  PetLevelupSpellSet& spellSet = mPetLevelupSpellMap[creatureFamily->ID];
2449  if (spellSet.empty())
2450  ++family_count;
2451 
2452  spellSet.insert(PetLevelupSpellSet::value_type(spell->SpellLevel, spell->Id));
2453  ++count;
2454  }
2455  }
2456  }
2457 
2458  TC_LOG_INFO("server.loading", ">> Loaded %u pet levelup and default spells for %u families in %u ms", count, family_count, GetMSTimeDiffToNow(oldMSTime));
2459 }
uint32 ID
Definition: DBCStructure.h:281
uint32 Id
Definition: SpellInfo.h:329
uint32 SpellLevel
Definition: SpellInfo.h:375
Definition: SpellInfo.h:326
PetLevelupSpellMap mPetLevelupSpellMap
Definition: SpellMgr.h:751
uint32 getMSTime()
Definition: Timer.h:24
uint32 AquireMethod
Definition: DBCStructure.h:974
uint32 SkillLine
Definition: DBCStructure.h:968
uint32 SpellID
Definition: DBCStructure.h:969
uint32_t uint32
Definition: Define.h:150
DBCStorage< CreatureFamilyEntry > sCreatureFamilyStore(CreatureFamilyfmt)
std::multimap< uint32, uint32 > PetLevelupSpellSet
Definition: SpellMgr.h:554
SpellInfo const * GetSpellInfo(uint32 spellId) const
Definition: SpellMgr.h:682
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
uint32 SkillLine[2]
Definition: DBCStructure.h:286
Definition: DBCStructure.h:965
uint8_t uint8
Definition: Define.h:152
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
Definition: DBCStructure.h:279
DBCStorage< SkillLineAbilityEntry > sSkillLineAbilityStore(SkillLineAbilityfmt)

+ Here is the call graph for this function:

void SpellMgr::LoadSkillLineAbilityMap ( )
2177 {
2178  uint32 oldMSTime = getMSTime();
2179 
2180  mSkillLineAbilityMap.clear();
2181 
2182  uint32 count = 0;
2183 
2184  for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); ++i)
2185  {
2186  SkillLineAbilityEntry const* SkillInfo = sSkillLineAbilityStore.LookupEntry(i);
2187  if (!SkillInfo)
2188  continue;
2189 
2190  mSkillLineAbilityMap.insert(SkillLineAbilityMap::value_type(SkillInfo->SpellID, SkillInfo));
2191  ++count;
2192  }
2193 
2194  TC_LOG_INFO("server.loading", ">> Loaded %u SkillLineAbility MultiMap Data in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
2195 }
uint32 getMSTime()
Definition: Timer.h:24
SkillLineAbilityMap mSkillLineAbilityMap
Definition: SpellMgr.h:750
uint32 SpellID
Definition: DBCStructure.h:969
uint32_t uint32
Definition: Define.h:150
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
Definition: DBCStructure.h:965
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
DBCStorage< SkillLineAbilityEntry > sSkillLineAbilityStore(SkillLineAbilityfmt)

+ Here is the call graph for this function:

void SpellMgr::LoadSpellAreas ( )
2558 {
2559  uint32 oldMSTime = getMSTime();
2560 
2561  mSpellAreaMap.clear(); // need for reload case
2562  mSpellAreaForQuestMap.clear();
2563  mSpellAreaForQuestEndMap.clear();
2564  mSpellAreaForAuraMap.clear();
2565 
2566  // 0 1 2 3 4 5 6 7 8 9
2567  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");
2568  if (!result)
2569  {
2570  TC_LOG_INFO("server.loading", ">> Loaded 0 spell area requirements. DB table `spell_area` is empty.");
2571 
2572  return;
2573  }
2574 
2575  uint32 count = 0;
2576  do
2577  {
2578  Field* fields = result->Fetch();
2579 
2580  uint32 spell = fields[0].GetUInt32();
2581  SpellArea spellArea;
2582  spellArea.spellId = spell;
2583  spellArea.areaId = fields[1].GetUInt32();
2584  spellArea.questStart = fields[2].GetUInt32();
2585  spellArea.questStartStatus = fields[3].GetUInt32();
2586  spellArea.questEndStatus = fields[4].GetUInt32();
2587  spellArea.questEnd = fields[5].GetUInt32();
2588  spellArea.auraSpell = fields[6].GetInt32();
2589  spellArea.raceMask = fields[7].GetUInt32();
2590  spellArea.gender = Gender(fields[8].GetUInt8());
2591  spellArea.autocast = fields[9].GetBool();
2592 
2593  if (SpellInfo const* spellInfo = GetSpellInfo(spell))
2594  {
2595  if (spellArea.autocast)
2596  const_cast<SpellInfo*>(spellInfo)->Attributes |= SPELL_ATTR0_CANT_CANCEL;
2597  }
2598  else
2599  {
2600  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` does not exist", spell);
2601  continue;
2602  }
2603 
2604  {
2605  bool ok = true;
2606  SpellAreaMapBounds sa_bounds = GetSpellAreaMapBounds(spellArea.spellId);
2607  for (SpellAreaMap::const_iterator itr = sa_bounds.first; itr != sa_bounds.second; ++itr)
2608  {
2609  if (spellArea.spellId != itr->second.spellId)
2610  continue;
2611  if (spellArea.areaId != itr->second.areaId)
2612  continue;
2613  if (spellArea.questStart != itr->second.questStart)
2614  continue;
2615  if (spellArea.auraSpell != itr->second.auraSpell)
2616  continue;
2617  if ((spellArea.raceMask & itr->second.raceMask) == 0)
2618  continue;
2619  if (spellArea.gender != itr->second.gender)
2620  continue;
2621 
2622  // duplicate by requirements
2623  ok = false;
2624  break;
2625  }
2626 
2627  if (!ok)
2628  {
2629  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` already listed with similar requirements.", spell);
2630  continue;
2631  }
2632  }
2633 
2634  if (spellArea.areaId && !sAreaTableStore.LookupEntry(spellArea.areaId))
2635  {
2636  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` have wrong area (%u) requirement", spell, spellArea.areaId);
2637  continue;
2638  }
2639 
2640  if (spellArea.questStart && !sObjectMgr->GetQuestTemplate(spellArea.questStart))
2641  {
2642  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` have wrong start quest (%u) requirement", spell, spellArea.questStart);
2643  continue;
2644  }
2645 
2646  if (spellArea.questEnd)
2647  {
2648  if (!sObjectMgr->GetQuestTemplate(spellArea.questEnd))
2649  {
2650  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` have wrong end quest (%u) requirement", spell, spellArea.questEnd);
2651  continue;
2652  }
2653  }
2654 
2655  if (spellArea.auraSpell)
2656  {
2657  SpellInfo const* spellInfo = GetSpellInfo(abs(spellArea.auraSpell));
2658  if (!spellInfo)
2659  {
2660  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` have wrong aura spell (%u) requirement", spell, abs(spellArea.auraSpell));
2661  continue;
2662  }
2663 
2664  if (uint32(abs(spellArea.auraSpell)) == spellArea.spellId)
2665  {
2666  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` have aura spell (%u) requirement for itself", spell, abs(spellArea.auraSpell));
2667  continue;
2668  }
2669 
2670  // not allow autocast chains by auraSpell field (but allow use as alternative if not present)
2671  if (spellArea.autocast && spellArea.auraSpell > 0)
2672  {
2673  bool chain = false;
2675  for (SpellAreaForAuraMap::const_iterator itr = saBound.first; itr != saBound.second; ++itr)
2676  {
2677  if (itr->second->autocast && itr->second->auraSpell > 0)
2678  {
2679  chain = true;
2680  break;
2681  }
2682  }
2683 
2684  if (chain)
2685  {
2686  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` have aura spell (%u) requirement that itself autocast from aura", spell, spellArea.auraSpell);
2687  continue;
2688  }
2689 
2690  SpellAreaMapBounds saBound2 = GetSpellAreaMapBounds(spellArea.auraSpell);
2691  for (SpellAreaMap::const_iterator itr2 = saBound2.first; itr2 != saBound2.second; ++itr2)
2692  {
2693  if (itr2->second.autocast && itr2->second.auraSpell > 0)
2694  {
2695  chain = true;
2696  break;
2697  }
2698  }
2699 
2700  if (chain)
2701  {
2702  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` have aura spell (%u) requirement that itself autocast from aura", spell, spellArea.auraSpell);
2703  continue;
2704  }
2705  }
2706  }
2707 
2708  if (spellArea.raceMask && (spellArea.raceMask & RACEMASK_ALL_PLAYABLE) == 0)
2709  {
2710  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` have wrong race mask (%u) requirement", spell, spellArea.raceMask);
2711  continue;
2712  }
2713 
2714  if (spellArea.gender != GENDER_NONE && spellArea.gender != GENDER_FEMALE && spellArea.gender != GENDER_MALE)
2715  {
2716  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` have wrong gender (%u) requirement", spell, spellArea.gender);
2717  continue;
2718  }
2719 
2720  SpellArea const* sa = &mSpellAreaMap.insert(SpellAreaMap::value_type(spell, spellArea))->second;
2721 
2722  // for search by current zone/subzone at zone/subzone change
2723  if (spellArea.areaId)
2724  mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(spellArea.areaId, sa));
2725 
2726  // for search at quest start/reward
2727  if (spellArea.questStart)
2728  mSpellAreaForQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa));
2729 
2730  // for search at quest start/reward
2731  if (spellArea.questEnd)
2732  mSpellAreaForQuestEndMap.insert(SpellAreaForQuestMap::value_type(spellArea.questEnd, sa));
2733 
2734  // for search at aura apply
2735  if (spellArea.auraSpell)
2736  mSpellAreaForAuraMap.insert(SpellAreaForAuraMap::value_type(abs(spellArea.auraSpell), sa));
2737 
2738  ++count;
2739  } while (result->NextRow());
2740 
2741  TC_LOG_INFO("server.loading", ">> Loaded %u spell area requirements in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
2742 }
G3D::Matrix abs(const G3D::Matrix &M)
Definition: Matrix.h:632
int32 auraSpell
Definition: SpellMgr.h:486
uint32 questEndStatus
Definition: SpellMgr.h:490
SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds(uint32 spell_id) const
Definition: SpellMgr.cpp:1152
Definition: SpellInfo.h:326
uint32 raceMask
Definition: SpellMgr.h:487
uint32 areaId
Definition: SpellMgr.h:483
Class used to access individual fields of database query result.
Definition: Field.h:56
uint32 getMSTime()
Definition: Timer.h:24
uint32 questStartStatus
Definition: SpellMgr.h:489
WorldDatabaseWorkerPool WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
uint32 spellId
Definition: SpellMgr.h:482
#define sObjectMgr
Definition: ObjectMgr.h:1567
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTablefmt)
Definition: SharedDefines.h:93
Definition: SharedDefines.h:94
SpellAreaMap mSpellAreaMap
Definition: SpellMgr.h:745
Gender
Definition: SharedDefines.h:90
SpellAreaMapBounds GetSpellAreaMapBounds(uint32 spell_id) const
Definition: SpellMgr.cpp:1137
SpellAreaForQuestMap mSpellAreaForQuestEndMap
Definition: SpellMgr.h:747
std::pair< SpellAreaMap::const_iterator, SpellAreaMap::const_iterator > SpellAreaMapBounds
Definition: SpellMgr.h:501
uint32_t uint32
Definition: Define.h:150
SpellAreaForQuestMap mSpellAreaForQuestMap
Definition: SpellMgr.h:746
std::shared_ptr< ResultSet > QueryResult
Definition: QueryResult.h:61
Gender gender
Definition: SpellMgr.h:488
Definition: SpellMgr.h:480
Definition: SharedDefines.h:387
int32 GetInt32() const
Definition: Field.h:165
SpellInfo const * GetSpellInfo(uint32 spellId) const
Definition: SpellMgr.h:682
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
std::pair< SpellAreaForAuraMap::const_iterator, SpellAreaForAuraMap::const_iterator > SpellAreaForAuraMapBounds
Definition: SpellMgr.h:503
QueryResult Query(const char *sql, T *connection=nullptr)
Definition: DatabaseWorkerPool.cpp:113
SpellAreaForAreaMap mSpellAreaForAreaMap
Definition: SpellMgr.h:749
#define RACEMASK_ALL_PLAYABLE
Definition: SharedDefines.h:133
uint32 GetUInt32() const
Definition: Field.h:146
uint32 questStart
Definition: SpellMgr.h:484
SpellAreaForAuraMap mSpellAreaForAuraMap
Definition: SpellMgr.h:748
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
uint32_t uint32
Definition: g3dmath.h:168
bool GetBool() const
Definition: Field.h:65
bool autocast
Definition: SpellMgr.h:491
Definition: SharedDefines.h:95
uint32 questEnd
Definition: SpellMgr.h:485

+ Here is the call graph for this function:

void SpellMgr::LoadSpellEnchantProcData ( )
2305 {
2306  uint32 oldMSTime = getMSTime();
2307 
2308  mSpellEnchantProcEventMap.clear(); // need for reload case
2309 
2310  // 0 1 2 3
2311  QueryResult result = WorldDatabase.Query("SELECT entry, customChance, PPMChance, procEx FROM spell_enchant_proc_data");
2312  if (!result)
2313  {
2314  TC_LOG_INFO("server.loading", ">> Loaded 0 spell enchant proc event conditions. DB table `spell_enchant_proc_data` is empty.");
2315  return;
2316  }
2317 
2318  uint32 count = 0;
2319  do
2320  {
2321  Field* fields = result->Fetch();
2322 
2323  uint32 enchantId = fields[0].GetUInt32();
2324 
2325  SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchantId);
2326  if (!ench)
2327  {
2328  TC_LOG_ERROR("sql.sql", "Enchancment %u listed in `spell_enchant_proc_data` does not exist", enchantId);
2329  continue;
2330  }
2331 
2333 
2334  spe.customChance = fields[1].GetUInt32();
2335  spe.PPMChance = fields[2].GetFloat();
2336  spe.procEx = fields[3].GetUInt32();
2337 
2338  mSpellEnchantProcEventMap[enchantId] = spe;
2339 
2340  ++count;
2341  } while (result->NextRow());
2342 
2343  TC_LOG_INFO("server.loading", ">> Loaded %u enchant proc data definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
2344 }
float GetFloat() const
Definition: Field.h:222
Class used to access individual fields of database query result.
Definition: Field.h:56
SpellEnchantProcEventMap mSpellEnchantProcEventMap
Definition: SpellMgr.h:743
uint32 getMSTime()
Definition: Timer.h:24
WorldDatabaseWorkerPool WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
Definition: DBCStructure.h:1214
Definition: SpellMgr.h:308
uint32 customChance
Definition: SpellMgr.h:310
uint32_t uint32
Definition: Define.h:150
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
std::shared_ptr< ResultSet > QueryResult
Definition: QueryResult.h:61
uint32 procEx
Definition: SpellMgr.h:312
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
QueryResult Query(const char *sql, T *connection=nullptr)
Definition: DatabaseWorkerPool.cpp:113
uint32 GetUInt32() const
Definition: Field.h:146
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
float PPMChance
Definition: SpellMgr.h:311

+ Here is the call graph for this function:

void SpellMgr::LoadSpellGroups ( )
1785 {
1786  uint32 oldMSTime = getMSTime();
1787 
1788  mSpellSpellGroup.clear(); // need for reload case
1789  mSpellGroupSpell.clear();
1790 
1791  // 0 1
1792  QueryResult result = WorldDatabase.Query("SELECT id, spell_id FROM spell_group");
1793  if (!result)
1794  {
1795  TC_LOG_INFO("server.loading", ">> Loaded 0 spell group definitions. DB table `spell_group` is empty.");
1796  return;
1797  }
1798 
1799  std::set<uint32> groups;
1800  uint32 count = 0;
1801  do
1802  {
1803  Field* fields = result->Fetch();
1804 
1805  uint32 group_id = fields[0].GetUInt32();
1806  if (group_id <= SPELL_GROUP_DB_RANGE_MIN && group_id >= SPELL_GROUP_CORE_RANGE_MAX)
1807  {
1808  TC_LOG_ERROR("sql.sql", "SpellGroup id %u listed in `spell_group` is in core range, but is not defined in core!", group_id);
1809  continue;
1810  }
1811  int32 spell_id = fields[1].GetInt32();
1812 
1813  groups.insert(std::set<uint32>::value_type(group_id));
1814  mSpellGroupSpell.insert(SpellGroupSpellMap::value_type((SpellGroup)group_id, spell_id));
1815 
1816  } while (result->NextRow());
1817 
1818  for (SpellGroupSpellMap::iterator itr = mSpellGroupSpell.begin(); itr!= mSpellGroupSpell.end();)
1819  {
1820  if (itr->second < 0)
1821  {
1822  if (groups.find(abs(itr->second)) == groups.end())
1823  {
1824  TC_LOG_ERROR("sql.sql", "SpellGroup id %u listed in `spell_group` does not exist", abs(itr->second));
1825  mSpellGroupSpell.erase(itr++);
1826  }
1827  else
1828  ++itr;
1829  }
1830  else
1831  {
1832  SpellInfo const* spellInfo = GetSpellInfo(itr->second);
1833 
1834  if (!spellInfo)
1835  {
1836  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_group` does not exist", itr->second);
1837  mSpellGroupSpell.erase(itr++);
1838  }
1839  else if (spellInfo->GetRank() > 1)
1840  {
1841  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_group` is not first rank of spell", itr->second);
1842  mSpellGroupSpell.erase(itr++);
1843  }
1844  else
1845  ++itr;
1846  }
1847  }
1848 
1849  for (std::set<uint32>::iterator groupItr = groups.begin(); groupItr != groups.end(); ++groupItr)
1850  {
1851  std::set<uint32> spells;
1852  GetSetOfSpellsInSpellGroup(SpellGroup(*groupItr), spells);
1853 
1854  for (std::set<uint32>::iterator spellItr = spells.begin(); spellItr != spells.end(); ++spellItr)
1855  {
1856  ++count;
1857  mSpellSpellGroup.insert(SpellSpellGroupMap::value_type(*spellItr, SpellGroup(*groupItr)));
1858  }
1859  }
1860 
1861  TC_LOG_INFO("server.loading", ">> Loaded %u spell group definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
1862 }
G3D::Matrix abs(const G3D::Matrix &M)
Definition: Matrix.h:632
Definition: SpellInfo.h:326
Definition: SpellMgr.h:324
SpellSpellGroupMap mSpellSpellGroup
Definition: SpellMgr.h:735
Class used to access individual fields of database query result.
Definition: Field.h:56
uint32 getMSTime()
Definition: Timer.h:24
WorldDatabaseWorkerPool WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
SpellGroup
Definition: SpellMgr.h:317
int32_t int32
Definition: Define.h:146
uint32_t uint32
Definition: Define.h:150
void GetSetOfSpellsInSpellGroup(SpellGroup group_id, std::set< uint32 > &foundSpells) const
Definition: SpellMgr.cpp:719
std::shared_ptr< ResultSet > QueryResult
Definition: QueryResult.h:61
SpellGroupSpellMap mSpellGroupSpell
Definition: SpellMgr.h:736
int32 GetInt32() const
Definition: Field.h:165
SpellInfo const * GetSpellInfo(uint32 spellId) const
Definition: SpellMgr.h:682
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
QueryResult Query(const char *sql, T *connection=nullptr)
Definition: DatabaseWorkerPool.cpp:113
uint32 GetUInt32() const
Definition: Field.h:146
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
uint8 GetRank() const
Definition: SpellInfo.cpp:2746

+ Here is the call graph for this function:

void SpellMgr::LoadSpellGroupStackRules ( )
1865 {
1866  uint32 oldMSTime = getMSTime();
1867 
1868  mSpellGroupStack.clear(); // need for reload case
1869 
1870  // 0 1
1871  QueryResult result = WorldDatabase.Query("SELECT group_id, stack_rule FROM spell_group_stack_rules");
1872  if (!result)
1873  {
1874  TC_LOG_INFO("server.loading", ">> Loaded 0 spell group stack rules. DB table `spell_group_stack_rules` is empty.");
1875  return;
1876  }
1877 
1878  uint32 count = 0;
1879  do
1880  {
1881  Field* fields = result->Fetch();
1882 
1883  uint32 group_id = fields[0].GetUInt32();
1884  uint8 stack_rule = fields[1].GetInt8();
1885  if (stack_rule >= SPELL_GROUP_STACK_RULE_MAX)
1886  {
1887  TC_LOG_ERROR("sql.sql", "SpellGroupStackRule %u listed in `spell_group_stack_rules` does not exist", stack_rule);
1888  continue;
1889  }
1890 
1892 
1893  if (spellGroup.first == spellGroup.second)
1894  {
1895  TC_LOG_ERROR("sql.sql", "SpellGroup id %u listed in `spell_group_stack_rules` does not exist", group_id);
1896  continue;
1897  }
1898 
1899  mSpellGroupStack[(SpellGroup)group_id] = (SpellGroupStackRule)stack_rule;
1900 
1901  ++count;
1902  } while (result->NextRow());
1903 
1904  TC_LOG_INFO("server.loading", ">> Loaded %u spell group stack rules in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
1905 }
SpellGroupSpellMapBounds GetSpellGroupSpellMapBounds(SpellGroup group_id) const
Definition: SpellMgr.cpp:714
Class used to access individual fields of database query result.
Definition: Field.h:56
uint32 getMSTime()
Definition: Timer.h:24
std::pair< SpellGroupSpellMap::const_iterator, SpellGroupSpellMap::const_iterator > SpellGroupSpellMapBounds
Definition: SpellMgr.h:335
WorldDatabaseWorkerPool WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
SpellGroup
Definition: SpellMgr.h:317
uint32_t uint32
Definition: Define.h:150
std::shared_ptr< ResultSet > QueryResult
Definition: QueryResult.h:61
SpellGroupStackRule
Definition: SpellMgr.h:337
SpellGroupStackMap mSpellGroupStack
Definition: SpellMgr.h:737
Definition: SpellMgr.h:344
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
QueryResult Query(const char *sql, T *connection=nullptr)
Definition: DatabaseWorkerPool.cpp:113
uint32 GetUInt32() const
Definition: Field.h:146
uint8_t uint8
Definition: Define.h:152
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
int8 GetInt8() const
Definition: Field.h:89

+ Here is the call graph for this function:

void SpellMgr::LoadSpellInfoCorrections ( )
Todo:
: remove this when basepoints of all Ride Vehicle auras are calculated correctly

HACK: This spell break quest complete for alliance and on retail not used °_O

2976 {
2977  uint32 oldMSTime = getMSTime();
2978 
2979  SpellInfo* spellInfo = NULL;
2980  for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2981  {
2982  spellInfo = (SpellInfo*)mSpellInfoMap[i];
2983  if (!spellInfo)
2984  continue;
2985 
2986  for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(DIFFICULTY_NONE))
2987  {
2988  if (!effect)
2989  continue;
2990  switch (effect->Effect)
2991  {
2992  case SPELL_EFFECT_CHARGE:
2994  case SPELL_EFFECT_JUMP:
2997  if (!spellInfo->Speed && !spellInfo->SpellFamilyName)
2998  spellInfo->Speed = SPEED_CHARGE;
2999  break;
3000  }
3001  }
3002 
3003  if (spellInfo->ActiveIconID == 2158) // flight
3004  spellInfo->Attributes |= SPELL_ATTR0_PASSIVE;
3005 
3006  switch (spellInfo->Id)
3007  {
3008  case 63026: // Summon Aspirant Test NPC (HACK: Target shouldn't be changed)
3009  case 63137: // Summon Valiant Test (HACK: Target shouldn't be changed; summon position should be untied from spell destination)
3010  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB);
3011  break;
3012  case 42436: // Drink! (Brewfest)
3014  break;
3015  case 52611: // Summon Skeletons
3016  case 52612: // Summon Skeletons
3017  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->MiscValueB = 64;
3018  break;
3019  case 40244: // Simon Game Visual
3020  case 40245: // Simon Game Visual
3021  case 40246: // Simon Game Visual
3022  case 40247: // Simon Game Visual
3023  case 42835: // Spout, remove damage effect, only anim is needed
3024  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->Effect = 0;
3025  break;
3026  case 30657: // Quake
3027  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TriggerSpell = 30571;
3028  break;
3029  case 30541: // Blaze (needs conditions entry)
3031  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetB = SpellImplicitTargetInfo();
3032  break;
3033  case 63665: // Charge (Argent Tournament emote on riders)
3034  case 31298: // Sleep (needs target selection script)
3035  case 51904: // Summon Ghouls On Scarlet Crusade (this should use conditions table, script for this spell needs to be fixed)
3036  case 68933: // Wrath of Air Totem rank 2 (Aura)
3037  case 29200: // Purify Helboar Meat
3038  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
3039  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetB = SpellImplicitTargetInfo();
3040  break;
3041  case 31344: // Howl of Azgalor
3042  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yards instead of 50000?!
3043  break;
3044  case 42818: // Headless Horseman - Wisp Flight Port
3045  case 42821: // Headless Horseman - Wisp Flight Missile
3046  spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100 yards
3047  break;
3048  case 36350: // They Must Burn Bomb Aura (self)
3049  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TriggerSpell = 36325; // They Must Burn Bomb Drop (DND)
3050  break;
3051  case 49838: // Stop Time
3052  case 69438: // Sample Satisfaction
3053  case 69445: // Perfume Spritz
3054  case 69489: // Chocolate Sample
3055  case 69563: // Cologne Spritz
3057  break;
3058  case 61407: // Energize Cores
3059  case 62136: // Energize Cores
3060  case 54069: // Energize Cores
3061  case 56251: // Energize Cores
3063  break;
3064  case 50785: // Energize Cores
3065  case 59372: // Energize Cores
3067  break;
3068  case 63320: // Glyph of Life Tap
3069  // Entries were not updated after spell effect change, we have to do that manually :/
3071  break;
3072  case 5308: // Execute
3074  break;
3075  case 31347: // Doom
3076  case 36327: // Shoot Arcane Explosion Arrow
3077  case 39365: // Thundering Storm
3078  case 41071: // Raise Dead (HACK)
3079  case 42442: // Vengeance Landing Cannonfire
3080  case 42611: // Shoot
3081  case 44978: // Wild Magic
3082  case 45001: // Wild Magic
3083  case 45002: // Wild Magic
3084  case 45004: // Wild Magic
3085  case 45006: // Wild Magic
3086  case 45010: // Wild Magic
3087  case 45761: // Shoot Gun
3088  case 45863: // Cosmetic - Incinerate to Random Target
3089  case 48246: // Ball of Flame
3090  case 41635: // Prayer of Mending
3091  case 44869: // Spectral Blast
3092  case 45027: // Revitalize
3093  case 45976: // Muru Portal Channel
3094  case 52124: // Sky Darkener Assault
3095  case 53096: // Quetz'lun's Judgment
3096  case 70743: // AoD Special
3097  case 70614: // AoD Special - Vegard
3098  case 4020: // Safirdrang's Chill
3099  case 52479: // Gift of the Harvester
3100  case 61588: // Blazing Harpoon
3101  case 55479: // Force Obedience
3102  spellInfo->MaxAffectedTargets = 1;
3103  break;
3104  case 36384: // Skartax Purple Beam
3105  spellInfo->MaxAffectedTargets = 2;
3106  break;
3107  case 28542: // Life Drain - Sapphiron
3108  case 29213: // Curse of the Plaguebringer - Noth
3109  case 29576: // Multi-Shot
3110  case 37790: // Spread Shot
3111  case 39992: // Needle Spine
3112  case 40816: // Saber Lash
3113  case 41303: // Soul Drain
3114  case 41376: // Spite
3115  case 45248: // Shadow Blades
3116  case 46771: // Flame Sear
3117  case 66588: // Flaming Spear
3118  spellInfo->MaxAffectedTargets = 3;
3119  break;
3120  case 38310: // Multi-Shot
3121  case 53385: // Divine Storm (Damage)
3122  spellInfo->MaxAffectedTargets = 4;
3123  break;
3124  case 42005: // Bloodboil
3125  case 38296: // Spitfire Totem
3126  case 37676: // Insidious Whisper
3127  case 46008: // Negative Energy
3128  case 45641: // Fire Bloom
3129  case 55665: // Life Drain - Sapphiron (H)
3130  case 28796: // Poison Bolt Volly - Faerlina
3131  spellInfo->MaxAffectedTargets = 5;
3132  break;
3133  case 54835: // Curse of the Plaguebringer - Noth (H)
3134  spellInfo->MaxAffectedTargets = 8;
3135  break;
3136  case 40827: // Sinful Beam
3137  case 40859: // Sinister Beam
3138  case 40860: // Vile Beam
3139  case 40861: // Wicked Beam
3140  case 54098: // Poison Bolt Volly - Faerlina (H)
3141  spellInfo->MaxAffectedTargets = 10;
3142  break;
3143  case 50312: // Unholy Frenzy
3144  spellInfo->MaxAffectedTargets = 15;
3145  break;
3146  case 33711: // Murmur's Touch
3147  case 38794: // Murmur's Touch
3148  spellInfo->MaxAffectedTargets = 1;
3149  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TriggerSpell = 33760;
3150  break;
3151  case 17941: // Shadow Trance
3152  case 22008: // Netherwind Focus
3153  case 34477: // Misdirection
3154  case 48108: // Hot Streak
3155  case 51124: // Killing Machine
3156  case 57761: // Fireball!
3157  case 64823: // Item - Druid T8 Balance 4P Bonus
3158  case 88819: // Daybreak
3159  spellInfo->ProcCharges = 1;
3160  break;
3161  case 44544: // Fingers of Frost
3162  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->SpellClassMask = flag128(685904631, 1151048, 0, 0);
3163  break;
3164  case 28200: // Ascendance (Talisman of Ascendance trinket)
3165  spellInfo->ProcCharges = 6;
3166  break;
3167  case 37408: // Oscillation Field
3169  break;
3170  case 51852: // The Eye of Acherus (no spawn in phase 2 in db)
3171  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->MiscValue |= 1;
3172  break;
3173  case 51912: // Crafty's Ultra-Advanced Proto-Typical Shortening Blaster
3174  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->ApplyAuraPeriod = 3000;
3175  break;
3176  case 30421: // Nether Portal - Perseverence
3177  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_2))->BasePoints += 30000;
3178  break;
3179  case 41913: // Parasitic Shadowfiend Passive
3180  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->ApplyAuraName = SPELL_AURA_DUMMY; // proc debuff, and summon infinite fiends
3181  break;
3182  case 27892: // To Anchor 1
3183  case 27928: // To Anchor 1
3184  case 27935: // To Anchor 1
3185  case 27915: // Anchor to Skulls
3186  case 27931: // Anchor to Skulls
3187  case 27937: // Anchor to Skulls
3188  spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(EFFECT_RADIUS_10_YARDS);
3189  break;
3190  // target allys instead of enemies, target A is src_caster, spells with effect like that have ally target
3191  // this is the only known exception, probably just wrong data
3192  case 29214: // Wrath of the Plaguebringer
3193  case 54836: // Wrath of the Plaguebringer
3196  break;
3197  case 15290: // Vampiric Embrace
3199  break;
3200  case 8145: // Tremor Totem (instant pulse)
3202  /*no break*/
3203  case 6474: // Earthbind Totem (instant pulse)
3205  break;
3206  case 5176: // Wrath
3207  case 2912: // Starfire
3208  //case 78674: // Starsurge 6.x effect 1 is no more
3209  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->Effect = SPELL_EFFECT_DUMMY;
3210  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->TargetA = TARGET_UNIT_CASTER;
3211  break;
3212  case 70728: // Exploit Weakness (needs target selection script)
3213  case 70840: // Devious Minds (needs target selection script)
3214  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
3215  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetB = SpellImplicitTargetInfo(TARGET_UNIT_PET);
3216  break;
3217  case 45602: // Ride Carpet
3218  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->BasePoints = 0; // force seat 0, vehicle doesn't have the required seat flags for "no seat specified (-1)"
3219  break;
3220  case 61719: // Easter Lay Noblegarden Egg Aura - Interrupt flags copied from aura which this aura is linked with
3222  break;
3223  case 71838: // Drain Life - Bryntroll Normal
3224  case 71839: // Drain Life - Bryntroll Heroic
3225  spellInfo->AttributesEx2 |= SPELL_ATTR2_CANT_CRIT;
3226  break;
3227  case 56606: // Ride Jokkum
3228  case 61791: // Ride Vehicle (Yogg-Saron)
3230  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->BasePoints = 1;
3231  break;
3232  case 59630: // Black Magic
3233  spellInfo->Attributes |= SPELL_ATTR0_PASSIVE;
3234  break;
3235  case 17364: // Stormstrike
3236  case 48278: // Paralyze
3238  break;
3239  case 51798: // Brewfest - Relay Race - Intro - Quest Complete
3240  case 47134: // Quest Complete
3242  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->Effect = 0;
3243  break;
3244  // VIOLET HOLD SPELLS
3245  //
3246  case 54258: // Water Globule (Ichoron)
3247  case 54264: // Water Globule (Ichoron)
3248  case 54265: // Water Globule (Ichoron)
3249  case 54266: // Water Globule (Ichoron)
3250  case 54267: // Water Globule (Ichoron)
3251  // in 3.3.5 there is only one radius in dbc which is 0 yards in this case
3252  // use max radius from 4.3.4
3253  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_25_YARDS);
3254  break;
3255  // ENDOF VIOLET HOLD
3256  //
3257  // ULDUAR SPELLS
3258  //
3259  case 62374: // Pursued (Flame Leviathan)
3260  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
3261  break;
3262  case 63342: // Focused Eyebeam Summon Trigger (Kologarn)
3263  spellInfo->MaxAffectedTargets = 1;
3264  break;
3265  case 65584: // Growth of Nature (Freya)
3266  case 64381: // Strength of the Pack (Auriaya)
3268  break;
3269  case 63018: // Searing Light (XT-002)
3270  case 65121: // Searing Light (25m) (XT-002)
3271  case 63024: // Gravity Bomb (XT-002)
3272  case 64234: // Gravity Bomb (25m) (XT-002)
3273  spellInfo->MaxAffectedTargets = 1;
3274  break;
3275  case 62834: // Boom (XT-002)
3276  // This hack is here because we suspect our implementation of spell effect execution on targets
3277  // is done in the wrong order. We suspect that EFFECT_0 needs to be applied on all targets,
3278  // then EFFECT_1, etc - instead of applying each effect on target1, then target2, etc.
3279  // The above situation causes the visual for this spell to be bugged, so we remove the instakill
3280  // effect and implement a script hack for that.
3281  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->Effect = 0;
3282  break;
3283  case 64386: // Terrifying Screech (Auriaya)
3284  case 64389: // Sentinel Blast (Auriaya)
3285  case 64678: // Sentinel Blast (Auriaya)
3286  spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(28); // 5 seconds, wrong DBC data?
3287  break;
3288  case 64321: // Potent Pheromones (Freya)
3289  // spell should dispel area aura, but doesn't have the attribute
3290  // may be db data bug, or blizz may keep reapplying area auras every update with checking immunity
3291  // that will be clear if we get more spells with problem like this
3293  break;
3294  case 63414: // Spinning Up (Mimiron)
3295  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetB = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
3296  spellInfo->ChannelInterruptFlags = 0;
3297  break;
3298  case 63036: // Rocket Strike (Mimiron)
3299  spellInfo->Speed = 0;
3300  break;
3301  case 64668: // Magnetic Field (Mimiron)
3302  spellInfo->Mechanic = MECHANIC_NONE;
3303  break;
3304  case 64468: // Empowering Shadows (Yogg-Saron)
3305  case 64486: // Empowering Shadows (Yogg-Saron)
3306  spellInfo->MaxAffectedTargets = 3; // same for both modes?
3307  break;
3308  case 62301: // Cosmic Smash (Algalon the Observer)
3309  spellInfo->MaxAffectedTargets = 1;
3310  break;
3311  case 64598: // Cosmic Smash (Algalon the Observer)
3312  spellInfo->MaxAffectedTargets = 3;
3313  break;
3314  case 62293: // Cosmic Smash (Algalon the Observer)
3315  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetB = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
3316  break;
3317  case 62311: // Cosmic Smash (Algalon the Observer)
3318  case 64596: // Cosmic Smash (Algalon the Observer)
3319  spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100yd
3320  break;
3321  case 64014: // Expedition Base Camp Teleport
3322  case 64024: // Conservatory Teleport
3323  case 64025: // Halls of Invention Teleport
3324  case 64028: // Colossal Forge Teleport
3325  case 64029: // Shattered Walkway Teleport
3326  case 64030: // Antechamber Teleport
3327  case 64031: // Scrapyard Teleport
3328  case 64032: // Formation Grounds Teleport
3329  case 65042: // Prison of Yogg-Saron Teleport
3330  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB);
3331  break;
3332  // ENDOF ULDUAR SPELLS
3333  //
3334  // TRIAL OF THE CRUSADER SPELLS
3335  //
3336  case 66258: // Infernal Eruption
3337  // increase duration from 15 to 18 seconds because caster is already
3338  // unsummoned when spell missile hits the ground so nothing happen in result
3339  spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(85);
3340  break;
3341  // ENDOF TRIAL OF THE CRUSADER SPELLS
3342  //
3343  // ICECROWN CITADEL SPELLS
3344  //
3345  // THESE SPELLS ARE WORKING CORRECTLY EVEN WITHOUT THIS HACK
3346  // THE ONLY REASON ITS HERE IS THAT CURRENT GRID SYSTEM
3347  // DOES NOT ALLOW FAR OBJECT SELECTION (dist > 333)
3348  case 70781: // Light's Hammer Teleport
3349  case 70856: // Oratory of the Damned Teleport
3350  case 70857: // Rampart of Skulls Teleport
3351  case 70858: // Deathbringer's Rise Teleport
3352  case 70859: // Upper Spire Teleport
3353  case 70860: // Frozen Throne Teleport
3354  case 70861: // Sindragosa's Lair Teleport
3355  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB);
3356  break;
3357  case 71169: // Shadow's Fate
3359  break;
3360  case 72347: // Lock Players and Tap Chest
3362  break;
3363  case 72723: // Resistant Skin (Deathbringer Saurfang adds)
3364  // this spell initially granted Shadow damage immunity, however it was removed but the data was left in client
3365  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_2))->Effect = 0;
3366  break;
3367  case 70460: // Coldflame Jets (Traps after Saurfang)
3368  spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(1); // 10 seconds
3369  break;
3370  case 71412: // Green Ooze Summon (Professor Putricide)
3371  case 71415: // Orange Ooze Summon (Professor Putricide)
3373  break;
3374  case 71159: // Awaken Plagued Zombies
3375  spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21);
3376  break;
3377  case 70530: // Volatile Ooze Beam Protection (Professor Putricide)
3378  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->Effect = SPELL_EFFECT_APPLY_AURA; // for an unknown reason this was SPELL_EFFECT_APPLY_AREA_AURA_RAID
3379  break;
3380  // THIS IS HERE BECAUSE COOLDOWN ON CREATURE PROCS IS NOT IMPLEMENTED
3381  case 71604: // Mutated Strength (Professor Putricide)
3382  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->Effect = 0;
3383  break;
3384  case 70911: // Unbound Plague (Professor Putricide) (needs target selection script)
3386  break;
3387  case 71708: // Empowered Flare (Blood Prince Council)
3389  break;
3390  case 71266: // Swarming Shadows
3391  spellInfo->RequiredAreasID = 0; // originally, these require area 4522, which is... outside of Icecrown Citadel
3392  break;
3393  case 70602: // Corruption
3395  break;
3396  case 70715: // Column of Frost (visual marker)
3397  spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(32); // 6 seconds (missing)
3398  break;
3399  case 71085: // Mana Void (periodic aura)
3400  spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(9); // 30 seconds (missing)
3401  break;
3402  case 70936: // Summon Suppressor (needs target selection script)
3404  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetB = SpellImplicitTargetInfo();
3405  break;
3406  case 70598: // Sindragosa's Fury
3407  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
3408  break;
3409  case 69846: // Frost Bomb
3410  spellInfo->Speed = 0.0f; // This spell's summon happens instantly
3411  break;
3412  case 71614: // Ice Lock
3413  spellInfo->Mechanic = MECHANIC_STUN;
3414  break;
3415  case 72762: // Defile
3416  spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(559); // 53 seconds
3417  break;
3418  case 72743: // Defile
3419  spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(22); // 45 seconds
3420  break;
3421  case 72754: // Defile
3422  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3423  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3424  break;
3425  case 69198: // Raging Spirit Visual
3426  spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
3427  break;
3428  case 73655: // Harvest Soul
3430  break;
3431  case 73540: // Summon Shadow Trap
3432  spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(23); // 90 seconds
3433  break;
3434  case 73530: // Shadow Trap (visual)
3435  spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(28); // 5 seconds
3436  break;
3437  case 74302: // Summon Spirit Bomb
3438  spellInfo->MaxAffectedTargets = 2;
3439  break;
3440  case 73579: // Summon Spirit Bomb
3441  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_25_YARDS); // 25yd
3442  break;
3443  case 72376: // Raise Dead
3444  spellInfo->MaxAffectedTargets = 3;
3445  break;
3446  case 71809: // Jump
3447  spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(3); // 20yd
3448  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_25_YARDS); // 25yd
3449  break;
3450  case 72405: // Broken Frostmourne
3451  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
3452  break;
3453  // ENDOF ICECROWN CITADEL SPELLS
3454  //
3455  // RUBY SANCTUM SPELLS
3456  //
3457  case 74799: // Soul Consumption
3458  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_12_YARDS);
3459  break;
3460  case 75509: // Twilight Mending
3463  break;
3464  case 75888: // Awaken Flames
3466  break;
3467  // ENDOF RUBY SANCTUM SPELLS
3468  //
3469  // EYE OF ETERNITY SPELLS
3470  // All spells below work even without these changes. The LOS attribute is due to problem
3471  // from collision between maps & gos with active destroyed state.
3472  case 57473: // Arcane Storm bonus explicit visual spell
3473  case 57431: // Summon Static Field
3474  case 56091: // Flame Spike (Wyrmrest Skytalon)
3475  case 56092: // Engulf in Flames (Wyrmrest Skytalon)
3476  case 57090: // Revivify (Wyrmrest Skytalon)
3477  case 57143: // Life Burst (Wyrmrest Skytalon)
3479  break;
3480  // This would never crit on retail and it has attribute for SPELL_ATTR3_NO_DONE_BONUS because is handled from player,
3481  // until someone figures how to make scions not critting without hack and without making them main casters this should stay here.
3482  case 63934: // Arcane Barrage (cast by players and NONMELEEDAMAGELOG with caster Scion of Eternity (original caster)).
3483  spellInfo->AttributesEx2 |= SPELL_ATTR2_CANT_CRIT;
3484  break;
3485  // ENDOF EYE OF ETERNITY SPELLS
3486  //
3487  case 40055: // Introspection
3488  case 40165: // Introspection
3489  case 40166: // Introspection
3490  case 40167: // Introspection
3491  spellInfo->Attributes |= SPELL_ATTR0_NEGATIVE_1;
3492  break;
3493  // Stonecore spells
3494  case 95284: // Teleport (from entrance to Slabhide)
3495  case 95285: // Teleport (from Slabhide to entrance)
3496  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetB = SpellImplicitTargetInfo(TARGET_DEST_DB);
3497  break;
3498  // Halls Of Origination spells
3499  // Temple Guardian Anhuur
3500  case 76606: // Disable Beacon Beams L
3501  case 76608: // Disable Beacon Beams R
3502  // Little hack, Increase the radius so it can hit the Cave In Stalkers in the platform.
3503  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->MaxRadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_45_YARDS);
3504  break;
3505  case 75323: // Reverberating Hymn
3506  // Aura is refreshed at 3 seconds, and the tick should happen at the fourth.
3508  break;
3509  case 24314: // Threatening Gaze
3511  break;
3512  case 5420: // Tree of Life (Passive)
3513  spellInfo->Stances = UI64LIT(1) << (FORM_TREE - 1);
3514  break;
3515  case 49376: // Feral Charge (Cat Form)
3517  break;
3518  case 45257: // Using Steam Tonk Controller
3519  case 45440: // Steam Tonk Controller
3520  case 60256: // Collect Sample
3521  // Crashes client on pressing ESC
3523  break;
3524  case 96942: // Gaze of Occu'thar
3525  spellInfo->AttributesEx &= ~SPELL_ATTR1_CHANNELED_1;
3526  break;
3527  case 75610: // Evolution
3528  spellInfo->MaxAffectedTargets = 1;
3529  break;
3530  case 75697: // Evolution
3532  break;
3533  // ISLE OF CONQUEST SPELLS
3534  //
3535  case 66551: // Teleport
3536  spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
3537  break;
3538  // ENDOF ISLE OF CONQUEST SPELLS
3539  //
3540  case 102445: // Summon Master Li Fei
3541  const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB);
3542  break;
3543  default:
3544  break;
3545  }
3546  }
3547 
3548  if (SummonPropertiesEntry* properties = const_cast<SummonPropertiesEntry*>(sSummonPropertiesStore.LookupEntry(121)))
3549  properties->Type = SUMMON_TYPE_TOTEM;
3550  if (SummonPropertiesEntry* properties = const_cast<SummonPropertiesEntry*>(sSummonPropertiesStore.LookupEntry(647))) // 52893
3551  properties->Type = SUMMON_TYPE_TOTEM;
3552 
3553  TC_LOG_INFO("server.loading", ">> Loaded SpellInfo corrections in %u ms", GetMSTimeDiffToNow(oldMSTime));
3554 }
Definition: SharedDefines.h:1899
Definition: Unit.h:56
Definition: DBCEnums.h:404
Definition: SharedDefines.h:1881
uint32 Id
Definition: SpellInfo.h:329
Definition: SpellMgr.h:386
Definition: SharedDefines.h:1106
Definition: SharedDefines.h:490
Definition: SharedDefines.h:430
Definition: SharedDefines.h:481
Definition: SharedDefines.h:1802
DB2Storage< SpellRadiusEntry > sSpellRadiusStore("SpellRadius.db2", SpellRadiusFormat, HOTFIX_SEL_SPELL_RADIUS)
Definition: SharedDefines.h:29
Definition: SharedDefines.h:1879
Definition: Unit.h:57
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
SpellInfoMap mSpellInfoMap
Definition: SpellMgr.h:753
Definition: SpellInfo.h:326
uint32 AttributesEx
Definition: SpellInfo.h:334
Definition: SharedDefines.h:28
uint32 ProcCharges
Definition: SpellInfo.h:372
uint32 AttributesEx8
Definition: SpellInfo.h:341
Definition: SharedDefines.h:1148
uint32 ActiveIconID
Definition: SpellInfo.h:391
uint32 getMSTime()
Definition: Timer.h:24
#define UI64LIT(N)
Definition: Define.h:138
arena_t NULL
Definition: jemalloc_internal.h:624
uint32 AuraInterruptFlags
Definition: SpellInfo.h:368
uint32 Mechanic
Definition: SpellInfo.h:332
Definition: SharedDefines.h:362
uint32 Attributes
Definition: SpellInfo.h:333
Definition: SharedDefines.h:1894
Definition: SharedDefines.h:1016
Definition: SharedDefines.h:545
Definition: SharedDefines.h:411
Definition: SpellMgr.h:394
uint32 AttributesEx3
Definition: SpellInfo.h:336
Definition: SharedDefines.h:1885
Definition: Unit.h:59
Definition: Unit.h:55
Definition: SpellMgr.h:379
Definition: SharedDefines.h:407
SpellRangeEntry const * RangeEntry
Definition: SpellInfo.h:379
uint32 AttributesEx2
Definition: SpellInfo.h:335
uint32 SpellFamilyName
Definition: SpellInfo.h:396
int32 RequiredAreasID
Definition: SpellInfo.h:400
uint32 GetSpellInfoStoreSize() const
Definition: SpellMgr.h:691
uint32 MaxAffectedTargets
Definition: SpellInfo.h:395
Definition: Util.h:362
uint64 Stances
Definition: SpellInfo.h:348
SpellDurationEntry const * DurationEntry
Definition: SpellInfo.h:376
Definition: SpellInfo.h:238
Definition: SharedDefines.h:480
Definition: SpellMgr.h:388
uint32_t uint32
Definition: Define.h:150
Definition: SharedDefines.h:1051
Definition: SharedDefines.h:457
Definition: SpellMgr.h:378
Definition: SharedDefines.h:493
Definition: SharedDefines.h:1956
Definition: SharedDefines.h:585
Definition: SharedDefines.h:1159
float Speed
Definition: SpellInfo.h:380
SpellEffectInfo const * GetEffect(uint32 difficulty, uint32 index) const
Definition: SpellInfo.cpp:3348
Definition: SpellInfo.h:207
uint32 AttributesEx5
Definition: SpellInfo.h:338
Definition: SharedDefines.h:1013
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
uint32 ChannelInterruptFlags
Definition: SpellInfo.h:369
Definition: SharedDefines.h:394
DB2Storage< SpellDurationEntry > sSpellDurationStore("SpellDuration.db2", SpellDurationFormat, HOTFIX_SEL_SPELL_DURATION)
Definition: Unit.h:54
Definition: SharedDefines.h:1887
#define SPEED_CHARGE
Definition: MotionMaster.h:80
SpellEffectInfoVector GetEffectsForDifficulty(uint32 difficulty) const
Definition: SpellInfo.cpp:3311
Definition: SpellMgr.h:377
Definition: SpellAuraDefines.h:64
Definition: SharedDefines.h:1052
DB2Storage< SpellRangeEntry > sSpellRangeStore("SpellRange.db2", SpellRangeFormat, HOTFIX_SEL_SPELL_RANGE)
uint32 AttributesEx6
Definition: SpellInfo.h:339
Definition: SharedDefines.h:471
Definition: SharedDefines.h:1880
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
Definition: SharedDefines.h:382
Definition: SharedDefines.h:30
Definition: SharedDefines.h:1875
Definition: SpellMgr.h:398
Definition: Unit.h:264
Definition: SharedDefines.h:507
Definition: SharedDefines.h:653
uint32 AttributesEx4
Definition: SpellInfo.h:337
Definition: SharedDefines.h:1790
Definition: SharedDefines.h:1888
Definition: SharedDefines.h:4399
Definition: DBCStructure.h:1242

+ Here is the call graph for this function:

void SpellMgr::LoadSpellInfoCustomAttributes ( )
2797 {
2798  uint32 oldMSTime = getMSTime();
2799  uint32 oldMSTime2 = oldMSTime;
2800  SpellInfo* spellInfo = NULL;
2801 
2802  QueryResult result = WorldDatabase.Query("SELECT entry, attributes FROM spell_custom_attr");
2803 
2804  if (!result)
2805  TC_LOG_INFO("server.loading", ">> Loaded 0 spell custom attributes from DB. DB table `spell_custom_attr` is empty.");
2806  else
2807  {
2808  uint32 count = 0;
2809  do
2810  {
2811  Field* fields = result->Fetch();
2812 
2813  uint32 spellId = fields[0].GetUInt32();
2814  uint32 attributes = fields[1].GetUInt32();
2815 
2816  spellInfo = _GetSpellInfo(spellId);
2817  if (!spellInfo)
2818  {
2819  TC_LOG_ERROR("sql.sql", "Table `spell_custom_attr` has wrong spell (entry: %u), ignored.", spellId);
2820  continue;
2821  }
2822 
2823  // TODO: validate attributes
2824 
2825  spellInfo->AttributesCu |= attributes;
2826  ++count;
2827  } while (result->NextRow());
2828 
2829  TC_LOG_INFO("server.loading", ">> Loaded %u spell custom attributes from DB in %u ms", count, GetMSTimeDiffToNow(oldMSTime2));
2830  }
2831 
2832  std::set<uint32> talentSpells;
2833  for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
2834  if (TalentEntry const* talentInfo = sTalentStore.LookupEntry(i))
2835  talentSpells.insert(talentInfo->SpellID);
2836 
2837  for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
2838  {
2839  spellInfo = mSpellInfoMap[i];
2840  if (!spellInfo)
2841  continue;
2842 
2843  for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(DIFFICULTY_NONE))
2844  {
2845  if (!effect)
2846  continue;
2847 
2848  switch (effect->ApplyAuraName)
2849  {
2852  case SPELL_AURA_MOD_CHARM:
2853  case SPELL_AURA_AOE_CHARM:
2854  case SPELL_AURA_MOD_FEAR:
2855  case SPELL_AURA_MOD_STUN:
2856  spellInfo->AttributesCu |= SPELL_ATTR0_CU_AURA_CC;
2857  break;
2867  case SPELL_AURA_POWER_BURN:
2869  break;
2870  }
2871 
2872  switch (effect->Effect)
2873  {
2879  case SPELL_EFFECT_HEAL:
2881  break;
2886  case SPELL_EFFECT_HEAL_PCT:
2888  case SPELL_EFFECT_ENERGIZE:
2891  break;
2892  case SPELL_EFFECT_CHARGE:
2894  case SPELL_EFFECT_JUMP:
2897  spellInfo->AttributesCu |= SPELL_ATTR0_CU_CHARGE;
2898  break;
2901  break;
2906  {
2907  // only enchanting profession enchantments procs can stack
2909  {
2910  uint32 enchantId = effect->MiscValue;
2911  SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId);
2912  if (!enchant)
2913  break;
2914 
2915  for (uint8 s = 0; s < MAX_ITEM_ENCHANTMENT_EFFECTS; ++s)
2916  {
2917  if (enchant->Effect[s] != ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL)
2918  continue;
2919 
2920  SpellInfo* procInfo = _GetSpellInfo(enchant->EffectSpellID[s]);
2921  if (!procInfo)
2922  continue;
2923 
2924  // if proced directly from enchantment, not via proc aura
2925  // NOTE: Enchant Weapon - Blade Ward also has proc aura spell and is proced directly
2926  // however its not expected to stack so this check is good
2928  continue;
2929 
2931  }
2932  }
2933  break;
2934  }
2935  }
2936  }
2937 
2938  if (!spellInfo->_IsPositiveEffect(EFFECT_0, false))
2940 
2941  if (!spellInfo->_IsPositiveEffect(EFFECT_1, false))
2943 
2944  if (!spellInfo->_IsPositiveEffect(EFFECT_2, false))
2946 
2947  if (spellInfo->GetSpellVisual(DIFFICULTY_NONE) == 3879)
2948  spellInfo->AttributesCu |= SPELL_ATTR0_CU_CONE_BACK;
2949 
2950  if (talentSpells.count(spellInfo->Id))
2951  spellInfo->AttributesCu |= SPELL_ATTR0_CU_IS_TALENT;
2952 
2953  switch (spellInfo->SpellFamilyName)
2954  {
2955  case SPELLFAMILY_WARRIOR:
2956  // Shout
2957  if (spellInfo->SpellFamilyFlags[0] & 0x20000 || spellInfo->SpellFamilyFlags[1] & 0x20)
2958  spellInfo->AttributesCu |= SPELL_ATTR0_CU_AURA_CC;
2959  break;
2960  case SPELLFAMILY_DRUID:
2961  // Roar
2962  if (spellInfo->SpellFamilyFlags[0] & 0x8)
2963  spellInfo->AttributesCu |= SPELL_ATTR0_CU_AURA_CC;
2964  break;
2965  default:
2966  break;
2967  }
2968 
2969  spellInfo->_InitializeExplicitTargetMask();
2970  }
2971 
2972  TC_LOG_INFO("server.loading", ">> Loaded SpellInfo custom attributes in %u ms", GetMSTimeDiffToNow(oldMSTime));
2973 }
Definition: SpellAuraDefines.h:68
Definition: SpellAuraDefines.h:63
Definition: DBCEnums.h:404
Definition: SharedDefines.h:1102
uint32 Id
Definition: SpellInfo.h:329
Definition: SharedDefines.h:1106
Definition: SpellAuraDefines.h:222
Definition: SpellInfo.h:194
Definition: SpellAuraDefines.h:66
Definition: SharedDefines.h:29
Definition: SharedDefines.h:1166
Definition: SpellAuraDefines.h:72
SpellInfoMap mSpellInfoMap
Definition: SpellMgr.h:753
Definition: SpellInfo.h:326
Definition: SharedDefines.h:1019
Definition: SharedDefines.h:1040
Definition: SharedDefines.h:28
Definition: SharedDefines.h:1072
Definition: SpellInfo.h:192
Definition: SharedDefines.h:3973
Class used to access individual fields of database query result.
Definition: Field.h:56
Definition: SpellAuraDefines.h:80
#define MAX_ITEM_ENCHANTMENT_EFFECTS
Definition: DBCStructure.h:1212
flag128 SpellFamilyFlags
Definition: SpellInfo.h:397
Definition: SharedDefines.h:1148
Definition: SharedDefines.h:1018
uint32 getMSTime()
Definition: Timer.h:24
Definition: SpellAuraDefines.h:67
arena_t NULL
Definition: jemalloc_internal.h:624
WorldDatabaseWorkerPool WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
Definition: SpellInfo.h:188
Definition: SpellAuraDefines.h:62
Definition: DBCStructure.h:1214
Definition: SharedDefines.h:1085
Definition: SharedDefines.h:1027
uint32 GetSpellVisual(Difficulty difficulty, Player *forPlayer=nullptr) const
Definition: SpellInfo.cpp:2860
bool HasAura(uint32 difficulty, AuraType aura) const
Definition: SpellInfo.cpp:1193
SpellInfo * _GetSpellInfo(uint32 spellId)
Definition: SpellMgr.h:696
Definition: SpellInfo.h:196
Definition: SpellInfo.h:184
Definition: SpellInfo.h:190
uint32 SpellFamilyName
Definition: SpellInfo.h:396
Definition: SharedDefines.h:1081
uint32 GetSpellInfoStoreSize() const
Definition: SpellMgr.h:691
Definition: SharedDefines.h:1077
Definition: SpellInfo.h:238
uint32_t uint32
Definition: Define.h:150
Definition: SharedDefines.h:1068
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
Definition: SharedDefines.h:1051
std::shared_ptr< ResultSet > QueryResult
Definition: QueryResult.h:61
Definition: SharedDefines.h:1020
Definition: SharedDefines.h:4630
uint32 AttributesCu
Definition: SpellInfo.h:347
Definition: SharedDefines.h:1159
Definition: SpellAuraDefines.h:124
Definition: SpellAuraDefines.h:81
Definition: SpellInfo.h:195
DBCStorage< TalentEntry > sTalentStore(Talentfmt)
Definition: DBCEnums.h:510
Definition: SpellAuraDefines.h:237
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
Definition: SpellAuraDefines.h:84
Definition: SpellAuraDefines.h:102
bool _IsPositiveEffect(uint32 effIndex, bool deep) const
Definition: SpellInfo.cpp:2907
QueryResult Query(const char *sql, T *connection=nullptr)
Definition: DatabaseWorkerPool.cpp:113
void _InitializeExplicitTargetMask()
Definition: SpellInfo.cpp:2873
uint32 EffectSpellID[MAX_ITEM_ENCHANTMENT_EFFECTS]
Definition: DBCStructure.h:1220
Definition: SpellInfo.h:193
Definition: SharedDefines.h:1063
Definition: SpellInfo.h:191
Definition: SharedDefines.h:4627
uint32 GetUInt32() const
Definition: Field.h:146
Definition: SharedDefines.h:1041
SpellEffectInfoVector GetEffectsForDifficulty(uint32 difficulty) const
Definition: SpellInfo.cpp:3311
Definition: SharedDefines.h:1146
Definition: SharedDefines.h:1052
uint8_t uint8
Definition: Define.h:152
Definition: SharedDefines.h:1064
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
Definition: SharedDefines.h:30
Definition: SpellAuraDefines.h:113
Definition: SpellAuraDefines.h:149
Definition: DBCStructure.h:1255
Definition: SpellInfo.h:185
Definition: SpellAuraDefines.h:65
Definition: SharedDefines.h:1012
uint32 Effect[MAX_ITEM_ENCHANTMENT_EFFECTS]
Definition: DBCStructure.h:1218
Definition: SharedDefines.h:1131
Definition: SpellAuraDefines.h:122
bool IsPartOfSkillLine(uint32 skillId, uint32 spellId)
Definition: SpellMgr.cpp:45
Definition: SharedDefines.h:1147
Definition: SpellInfo.h:189

+ Here is the call graph for this function:

void SpellMgr::LoadSpellInfoStore ( )
2747 {
2748  uint32 oldMSTime = getMSTime();
2749 
2751  mSpellInfoMap.resize(sSpellStore.GetNumRows(), NULL);
2752 
2753  std::unordered_map<uint32, SpellEffectEntryMap> effectsBySpell;
2754  std::unordered_map<uint32, SpellVisualMap> visualsBySpell;
2755 
2756  for (SpellEffectEntry const* effect : sSpellEffectStore)
2757  {
2758  if (effect->EffectIndex >= MAX_SPELL_EFFECTS)
2759  {
2760  TC_LOG_ERROR("server.loading", "Spell %u has invalid EffectIndex %u, max is %u, skipped", effect->SpellID, effect->EffectIndex, uint32(MAX_SPELL_EFFECTS));
2761  continue;
2762  }
2763 
2764  SpellEffectEntryVector& effectsForDifficulty = effectsBySpell[effect->SpellID][effect->DifficultyID];
2765  if (effectsForDifficulty.size() <= effect->EffectIndex)
2766  effectsForDifficulty.resize(effect->EffectIndex + 1);
2767 
2768  effectsForDifficulty[effect->EffectIndex] = effect;
2769  }
2770 
2771  for (SpellXSpellVisualEntry const* visual : sSpellXSpellVisualStore)
2772  visualsBySpell[visual->SpellID][visual->DifficultyID].push_back(visual);
2773 
2774  for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i)
2775  if (SpellEntry const* spellEntry = sSpellStore.LookupEntry(i))
2776  mSpellInfoMap[i] = new SpellInfo(spellEntry, effectsBySpell[i], std::move(visualsBySpell[i]));
2777 
2778  TC_LOG_INFO("server.loading", ">> Loaded SpellInfo store in %u ms", GetMSTimeDiffToNow(oldMSTime));
2779 }
SpellInfoMap mSpellInfoMap
Definition: SpellMgr.h:753
Definition: SpellInfo.h:326
uint32 getMSTime()
Definition: Timer.h:24
arena_t NULL
Definition: jemalloc_internal.h:624
Definition: DBCStructure.h:995
DBCStorage< SpellEntry > sSpellStore(Spellfmt)
uint32_t uint32
Definition: Define.h:150
void UnloadSpellInfoStore()
Definition: SpellMgr.cpp:2781
Definition: DB2Structure.h:1313
DB2Storage< SpellXSpellVisualEntry > sSpellXSpellVisualStore("SpellXSpellVisual.db2", SpellXSpellVisualFormat, HOTFIX_SEL_SPELL_X_SPELL_VISUAL)
std::vector< SpellEffectEntry const * > SpellEffectEntryVector
Definition: SpellInfo.h:318
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
Definition: DBCStructure.h:1054
DBCStorage< SpellEffectEntry > sSpellEffectStore(SpellEffectfmt)
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:1026
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207

+ Here is the call graph for this function:

void SpellMgr::LoadSpellLearnSkills ( )
1435 {
1436  uint32 oldMSTime = getMSTime();
1437 
1438  mSpellLearnSkills.clear(); // need for reload case
1439 
1440  // search auto-learned skills and add its to map also for use in unlearn spells/talents
1441  uint32 dbc_count = 0;
1442  for (uint32 spell = 0; spell < GetSpellInfoStoreSize(); ++spell)
1443  {
1444  SpellInfo const* entry = GetSpellInfo(spell);
1445 
1446  if (!entry)
1447  continue;
1448 
1449  for (SpellEffectInfo const* effect : entry->GetEffectsForDifficulty(DIFFICULTY_NONE))
1450  {
1451  if (effect && effect->Effect == SPELL_EFFECT_SKILL)
1452  {
1453  SpellLearnSkillNode dbc_node;
1454  dbc_node.skill = effect->MiscValue;
1455  dbc_node.step = effect->CalcValue();
1456  if (dbc_node.skill != SKILL_RIDING)
1457  dbc_node.value = 1;
1458  else
1459  dbc_node.value = dbc_node.step * 75;
1460  dbc_node.maxvalue = dbc_node.step * 75;
1461  mSpellLearnSkills[spell] = dbc_node;
1462  ++dbc_count;
1463  break;
1464  }
1465  }
1466  }
1467 
1468  TC_LOG_INFO("server.loading", ">> Loaded %u Spell Learn Skills from DBC in %u ms", dbc_count, GetMSTimeDiffToNow(oldMSTime));
1469 }
Definition: DBCEnums.h:404
Definition: SpellInfo.h:326
uint32 getMSTime()
Definition: Timer.h:24
uint16 value
Definition: SpellMgr.h:531
Definition: SpellMgr.h:527
uint32 GetSpellInfoStoreSize() const
Definition: SpellMgr.h:691
Definition: SharedDefines.h:4010
Definition: SpellInfo.h:238
uint32_t uint32
Definition: Define.h:150
SpellLearnSkillMap mSpellLearnSkills
Definition: SpellMgr.h:732
uint16 step
Definition: SpellMgr.h:530
SpellInfo const * GetSpellInfo(uint32 spellId) const
Definition: SpellMgr.h:682
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
uint16 maxvalue
Definition: SpellMgr.h:532
SpellEffectInfoVector GetEffectsForDifficulty(uint32 difficulty) const
Definition: SpellInfo.cpp:3311
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
Definition: SharedDefines.h:1128
uint16 skill
Definition: SpellMgr.h:529

+ Here is the call graph for this function:

void SpellMgr::LoadSpellLearnSpells ( )
1472 {
1473  uint32 oldMSTime = getMSTime();
1474 
1475  mSpellLearnSpells.clear(); // need for reload case
1476 
1477  // 0 1 2
1478  QueryResult result = WorldDatabase.Query("SELECT entry, SpellID, Active FROM spell_learn_spell");
1479  if (!result)
1480  {
1481  TC_LOG_INFO("server.loading", ">> Loaded 0 spell learn spells. DB table `spell_learn_spell` is empty.");
1482  return;
1483  }
1484 
1485  uint32 count = 0;
1486  do
1487  {
1488  Field* fields = result->Fetch();
1489 
1490  uint32 spell_id = fields[0].GetUInt32();
1491 
1492  SpellLearnSpellNode node;
1493  node.Spell = fields[1].GetUInt32();
1494  node.OverridesSpell = 0;
1495  node.Active = fields[2].GetBool();
1496  node.AutoLearned = false;
1497 
1498  SpellInfo const* spellInfo = GetSpellInfo(spell_id);
1499  if (!spellInfo)
1500  {
1501  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_learn_spell` does not exist", spell_id);
1502  continue;
1503  }
1504 
1505  if (!GetSpellInfo(node.Spell))
1506  {
1507  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_learn_spell` learning not existed spell %u", spell_id, node.Spell);
1508  continue;
1509  }
1510 
1511  if (spellInfo->HasAttribute(SPELL_ATTR0_CU_IS_TALENT))
1512  {
1513  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_learn_spell` attempt learning talent spell %u, skipped", spell_id, node.Spell);
1514  continue;
1515  }
1516 
1517  mSpellLearnSpells.insert(SpellLearnSpellMap::value_type(spell_id, node));
1518 
1519  ++count;
1520  } while (result->NextRow());
1521 
1522  // copy state loaded from db
1523  SpellLearnSpellMap dbSpellLearnSpells = mSpellLearnSpells;
1524 
1525  // search auto-learned spells and add its to map also for use in unlearn spells/talents
1526  uint32 dbc_count = 0;
1527  for (uint32 spell = 0; spell < GetSpellInfoStoreSize(); ++spell)
1528  {
1529  SpellInfo const* entry = GetSpellInfo(spell);
1530 
1531  if (!entry)
1532  continue;
1533 
1534  for (SpellEffectInfo const* effect : entry->GetEffectsForDifficulty(DIFFICULTY_NONE))
1535  {
1536  if (effect && effect->Effect == SPELL_EFFECT_LEARN_SPELL)
1537  {
1538  SpellLearnSpellNode dbc_node;
1539  dbc_node.Spell = effect->TriggerSpell;
1540  dbc_node.Active = true; // all dbc based learned spells is active (show in spell book or hide by client itself)
1541  dbc_node.OverridesSpell = 0;
1542 
1543  // ignore learning not existed spells (broken/outdated/or generic learnig spell 483
1544  if (!GetSpellInfo(dbc_node.Spell))
1545  continue;
1546 
1547  // talent or passive spells or skill-step spells auto-cast and not need dependent learning,
1548  // pet teaching spells must not be dependent learning (cast)
1549  // other required explicit dependent learning
1550  dbc_node.AutoLearned = effect->TargetA.GetTarget() == TARGET_UNIT_PET || entry->HasAttribute(SPELL_ATTR0_CU_IS_TALENT) || entry->IsPassive() || entry->HasEffect(SPELL_EFFECT_SKILL_STEP);
1551 
1552  SpellLearnSpellMapBounds db_node_bounds = dbSpellLearnSpells.equal_range(spell);
1553 
1554  bool found = false;
1555  for (SpellLearnSpellMap::const_iterator itr = db_node_bounds.first; itr != db_node_bounds.second; ++itr)
1556  {
1557  if (itr->second.Spell == dbc_node.Spell)
1558  {
1559  TC_LOG_ERROR("sql.sql", "Spell %u auto-learn spell %u in spell.dbc then the record in `spell_learn_spell` is redundant, please fix DB.",
1560  spell, dbc_node.Spell);
1561  found = true;
1562  break;
1563  }
1564  }
1565 
1566  if (!found) // add new spell-spell pair if not found
1567  {
1568  mSpellLearnSpells.insert(SpellLearnSpellMap::value_type(spell, dbc_node));
1569  ++dbc_count;
1570  }
1571  }
1572  }
1573  }
1574 
1575  for (SpellLearnSpellEntry const* spellLearnSpell : sSpellLearnSpellStore)
1576  {
1577  if (!GetSpellInfo(spellLearnSpell->SpellID))
1578  continue;
1579 
1580  SpellLearnSpellMapBounds db_node_bounds = dbSpellLearnSpells.equal_range(spellLearnSpell->LearnSpellID);
1581  bool found = false;
1582  for (SpellLearnSpellMap::const_iterator itr = db_node_bounds.first; itr != db_node_bounds.second; ++itr)
1583  {
1584  if (itr->second.Spell == spellLearnSpell->SpellID)
1585  {
1586  TC_LOG_ERROR("sql.sql", "Found redundant record (entry: %u, SpellID: %u) in `spell_learn_spell`, spell added automatically from SpellLearnSpell.db2", spellLearnSpell->LearnSpellID, spellLearnSpell->SpellID);
1587  found = true;
1588  break;
1589  }
1590  }
1591 
1592  if (found)
1593  continue;
1594 
1595  // Check if it is already found in Spell.dbc, ignore silently if yes
1596  SpellLearnSpellMapBounds dbc_node_bounds = GetSpellLearnSpellMapBounds(spellLearnSpell->LearnSpellID);
1597  found = false;
1598  for (SpellLearnSpellMap::const_iterator itr = dbc_node_bounds.first; itr != dbc_node_bounds.second; ++itr)
1599  {
1600  if (itr->second.Spell == spellLearnSpell->SpellID)
1601  {
1602  found = true;
1603  break;
1604  }
1605  }
1606 
1607  if (found)
1608  continue;
1609 
1610  SpellLearnSpellNode dbcLearnNode;
1611  dbcLearnNode.Spell = spellLearnSpell->SpellID;
1612  dbcLearnNode.OverridesSpell = spellLearnSpell->OverridesSpellID;
1613  dbcLearnNode.Active = true;
1614  dbcLearnNode.AutoLearned = false;
1615 
1616  mSpellLearnSpells.insert(SpellLearnSpellMap::value_type(spellLearnSpell->LearnSpellID, dbcLearnNode));
1617  ++dbc_count;
1618  }
1619 
1620  uint32 mastery_count = 0;
1621  for (uint32 i = 0; i < sChrSpecializationStore.GetNumRows(); ++i)
1622  {
1623  ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(i);
1624  if (!chrSpec)
1625  continue;
1626 
1627  if (chrSpec->ClassID >= MAX_CLASSES)
1628  continue;
1629 
1630  uint32 masteryMainSpell = MasterySpells[chrSpec->ClassID];
1631 
1632  for (uint32 m = 0; m < MAX_MASTERY_SPELLS; ++m)
1633  {
1634  uint32 mastery = chrSpec->MasterySpellID[m];
1635  if (!mastery)
1636  continue;
1637 
1638  SpellLearnSpellMapBounds db_node_bounds = dbSpellLearnSpells.equal_range(masteryMainSpell);
1639  bool found = false;
1640  for (SpellLearnSpellMap::const_iterator itr = db_node_bounds.first; itr != db_node_bounds.second; ++itr)
1641  {
1642  if (itr->second.Spell == mastery)
1643  {
1644  TC_LOG_ERROR("sql.sql", "Found redundant record (entry: %u, SpellID: %u) in `spell_learn_spell`, spell added automatically as mastery learned spell from ChrSpecialization.dbc", masteryMainSpell, mastery);
1645  found = true;
1646  break;
1647  }
1648  }
1649 
1650  if (found)
1651  continue;
1652 
1653  // Check if it is already found in Spell.dbc, ignore silently if yes
1654  SpellLearnSpellMapBounds dbc_node_bounds = GetSpellLearnSpellMapBounds(masteryMainSpell);
1655  found = false;
1656  for (SpellLearnSpellMap::const_iterator itr = dbc_node_bounds.first; itr != dbc_node_bounds.second; ++itr)
1657  {
1658  if (itr->second.Spell == mastery)
1659  {
1660  found = true;
1661  break;
1662  }
1663  }
1664 
1665  if (found)
1666  continue;
1667 
1668  SpellLearnSpellNode masteryNode;
1669  masteryNode.Spell = mastery;
1670  masteryNode.OverridesSpell = 0;
1671  masteryNode.Active = true;
1672  masteryNode.AutoLearned = false;
1673 
1674  mSpellLearnSpells.insert(SpellLearnSpellMap::value_type(masteryMainSpell, masteryNode));
1675  ++mastery_count;
1676  }
1677  }
1678 
1679  TC_LOG_INFO("server.loading", ">> Loaded %u spell learn spells, %u found in Spell.dbc and %u from TalentTab.dbc in %u ms", count, dbc_count, mastery_count, GetMSTimeDiffToNow(oldMSTime));
1680 }
Definition: DBCEnums.h:404
#define MAX_MASTERY_SPELLS
Definition: DBCStructure.h:243
uint32 Spell
Definition: SpellMgr.h:539
bool IsPassive() const
Definition: SpellInfo.cpp:1403
Definition: SharedDefines.h:1879
Definition: DB2Structure.h:1203
Definition: SpellInfo.h:326
Class used to access individual fields of database query result.
Definition: Field.h:56
uint32 getMSTime()
Definition: Timer.h:24
uint32 const MasterySpells[MAX_CLASSES]
Definition: Player.cpp:114
WorldDatabaseWorkerPool WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
uint32 OverridesSpell
Definition: SpellMgr.h:540
Definition: SharedDefines.h:1046
Definition: DBCStructure.h:245
uint32 MasterySpellID[MAX_MASTERY_SPELLS]
Definition: DBCStructure.h:250
Definition: SpellMgr.h:537
uint32 GetSpellInfoStoreSize() const
Definition: SpellMgr.h:691
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:462
uint32 ClassID
Definition: DBCStructure.h:249
Definition: SpellInfo.h:238
uint32_t uint32
Definition: Define.h:150
std::shared_ptr< ResultSet > QueryResult
Definition: QueryResult.h:61
SpellLearnSpellMapBounds GetSpellLearnSpellMapBounds(uint32 spell_id) const
Definition: SpellMgr.cpp:670
bool HasEffect(uint32 difficulty, SpellEffectName effect) const
Definition: SpellInfo.cpp:1169
bool AutoLearned
Definition: SpellMgr.h:542
SpellLearnSpellMap mSpellLearnSpells
Definition: SpellMgr.h:733
#define MAX_CLASSES
Definition: SharedDefines.h:181
Definition: SharedDefines.h:1054
DB2Storage< SpellLearnSpellEntry > sSpellLearnSpellStore("SpellLearnSpell.db2", SpellLearnSpellFormat, HOTFIX_SEL_SPELL_LEARN_SPELL)
DBCStorage< ChrSpecializationEntry > sChrSpecializationStore(ChrSpecializationfmt)
SpellInfo const * GetSpellInfo(uint32 spellId) const
Definition: SpellMgr.h:682
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
QueryResult Query(const char *sql, T *connection=nullptr)
Definition: DatabaseWorkerPool.cpp:113
uint32 GetUInt32() const
Definition: Field.h:146
SpellEffectInfoVector GetEffectsForDifficulty(uint32 difficulty) const
Definition: SpellInfo.cpp:3311
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
bool GetBool() const
Definition: Field.h:65
bool Active
Definition: SpellMgr.h:541
std::multimap< uint32, SpellLearnSpellNode > SpellLearnSpellMap
Definition: SpellMgr.h:545
std::pair< SpellLearnSpellMap::const_iterator, SpellLearnSpellMap::const_iterator > SpellLearnSpellMapBounds
Definition: SpellMgr.h:546
Definition: SpellInfo.h:189

+ Here is the call graph for this function:

void SpellMgr::LoadSpellLinked ( )
2347 {
2348  uint32 oldMSTime = getMSTime();
2349 
2350  mSpellLinkedMap.clear(); // need for reload case
2351 
2352  // 0 1 2
2353  QueryResult result = WorldDatabase.Query("SELECT spell_trigger, spell_effect, type FROM spell_linked_spell");
2354  if (!result)
2355  {
2356  TC_LOG_INFO("server.loading", ">> Loaded 0 linked spells. DB table `spell_linked_spell` is empty.");
2357  return;
2358  }
2359 
2360  uint32 count = 0;
2361  do
2362  {
2363  Field* fields = result->Fetch();
2364 
2365  int32 trigger = fields[0].GetInt32();
2366  int32 effect = fields[1].GetInt32();
2367  int32 type = fields[2].GetUInt8();
2368 
2369  SpellInfo const* spellInfo = GetSpellInfo(abs(trigger));
2370  if (!spellInfo)
2371  {
2372  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_linked_spell` does not exist", abs(trigger));
2373  continue;
2374  }
2375 
2376  if (effect >= 0)
2377  for (SpellEffectInfo const* eff : spellInfo->GetEffectsForDifficulty(DIFFICULTY_NONE))
2378  {
2379  if (eff && eff->CalcValue() == abs(effect))
2380  TC_LOG_ERROR("sql.sql", "Spell %u Effect: %u listed in `spell_linked_spell` has same bp%u like effect (possible hack)", abs(trigger), abs(effect), eff->EffectIndex);
2381  }
2382 
2383  spellInfo = GetSpellInfo(abs(effect));
2384  if (!spellInfo)
2385  {
2386  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_linked_spell` does not exist", abs(effect));
2387  continue;
2388  }
2389 
2390  if (type) //we will find a better way when more types are needed
2391  {
2392  if (trigger > 0)
2393  trigger += SPELL_LINKED_MAX_SPELLS * type;
2394  else
2395  trigger -= SPELL_LINKED_MAX_SPELLS * type;
2396  }
2397  mSpellLinkedMap[trigger].push_back(effect);
2398 
2399  ++count;
2400  } while (result->NextRow());
2401 
2402  TC_LOG_INFO("server.loading", ">> Loaded %u linked spells in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
2403 }
G3D::Matrix abs(const G3D::Matrix &M)
Definition: Matrix.h:632
Definition: DBCEnums.h:404
Definition: SpellInfo.h:326
Class used to access individual fields of database query result.
Definition: Field.h:56
uint32 getMSTime()
Definition: Timer.h:24
WorldDatabaseWorkerPool WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
uint8 GetUInt8() const
Definition: Field.h:70
Definition: SpellInfo.h:238
int32_t int32
Definition: Define.h:146
uint32_t uint32
Definition: Define.h:150
SpellLinkedMap mSpellLinkedMap
Definition: SpellMgr.h:742
std::shared_ptr< ResultSet > QueryResult
Definition: QueryResult.h:61
int32 GetInt32() const
Definition: Field.h:165
SpellInfo const * GetSpellInfo(uint32 spellId) const
Definition: SpellMgr.h:682
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
QueryResult Query(const char *sql, T *connection=nullptr)
Definition: DatabaseWorkerPool.cpp:113
SpellEffectInfoVector GetEffectsForDifficulty(uint32 difficulty) const
Definition: SpellInfo.cpp:3311
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
#define SPELL_LINKED_MAX_SPELLS
Definition: SpellMgr.h:95

+ Here is the call graph for this function:

void SpellMgr::LoadSpellPetAuras ( )
2198 {
2199  uint32 oldMSTime = getMSTime();
2200 
2201  mSpellPetAuraMap.clear(); // need for reload case
2202 
2203  // 0 1 2 3
2204  QueryResult result = WorldDatabase.Query("SELECT spell, effectId, pet, aura FROM spell_pet_auras");
2205  if (!result)
2206  {
2207  TC_LOG_INFO("server.loading", ">> Loaded 0 spell pet auras. DB table `spell_pet_auras` is empty.");
2208  return;
2209  }
2210 
2211  uint32 count = 0;
2212  do
2213  {
2214  Field* fields = result->Fetch();
2215 
2216  uint32 spell = fields[0].GetUInt32();
2217  uint8 eff = fields[1].GetUInt8();
2218  uint32 pet = fields[2].GetUInt32();
2219  uint32 aura = fields[3].GetUInt32();
2220 
2221  SpellPetAuraMap::iterator itr = mSpellPetAuraMap.find((spell<<8) + eff);
2222  if (itr != mSpellPetAuraMap.end())
2223  itr->second.AddAura(pet, aura);
2224  else
2225  {
2226  SpellInfo const* spellInfo = GetSpellInfo(spell);
2227  if (!spellInfo)
2228  {
2229  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_pet_auras` does not exist", spell);
2230  continue;
2231  }
2232  SpellEffectInfo const* effect = spellInfo->GetEffect(eff);
2233  if (!effect)
2234  {
2235  TC_LOG_ERROR("spells", "Spell %u listed in `spell_pet_auras` does not have effect at index %u", spell, uint32(eff));
2236  continue;
2237  }
2238 
2239  if (effect->Effect != SPELL_EFFECT_DUMMY &&
2240  (effect->Effect != SPELL_EFFECT_APPLY_AURA ||
2241  effect->ApplyAuraName != SPELL_AURA_DUMMY))
2242  {
2243  TC_LOG_ERROR("spells", "Spell %u listed in `spell_pet_auras` does not have dummy aura or dummy effect", spell);
2244  continue;
2245  }
2246 
2247  SpellInfo const* spellInfo2 = GetSpellInfo(aura);
2248  if (!spellInfo2)
2249  {
2250  TC_LOG_ERROR("sql.sql", "Aura %u listed in `spell_pet_auras` does not exist", aura);
2251  continue;
2252  }
2253 
2254  PetAura pa(pet, aura, effect->TargetA.GetTarget() == TARGET_UNIT_PET, effect->CalcValue());
2255  mSpellPetAuraMap[(spell<<8) + eff] = pa;
2256  }
2257 
2258  ++count;
2259  } while (result->NextRow());
2260 
2261  TC_LOG_INFO("server.loading", ">> Loaded %u spell pet auras in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
2262 }
SpellPetAuraMap mSpellPetAuraMap
Definition: SpellMgr.h:741
Definition: SharedDefines.h:1879
Definition: SpellInfo.h:326
Class used to access individual fields of database query result.
Definition: Field.h:56
uint32 ApplyAuraName
Definition: SpellInfo.h:244
uint32 getMSTime()
Definition: Timer.h:24
WorldDatabaseWorkerPool WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
Definition: SharedDefines.h:1016
SpellImplicitTargetInfo TargetA
Definition: SpellInfo.h:257
uint8 GetUInt8() const
Definition: Field.h:70
Definition: SpellMgr.h:433
Targets GetTarget() const
Definition: SpellInfo.cpp:121
Definition: SpellInfo.h:238
uint32_t uint32
Definition: Define.h:150
std::shared_ptr< ResultSet > QueryResult
Definition: QueryResult.h:61
SpellEffectInfo const * GetEffect(uint32 difficulty, uint32 index) const
Definition: SpellInfo.cpp:3348
int32 CalcValue(Unit const *caster=nullptr, int32 const *basePoints=nullptr, Unit const *target=nullptr, float *variance=nullptr, int32 itemLevel=-1) const
Definition: SpellInfo.cpp:455
SpellInfo const * GetSpellInfo(uint32 spellId) const
Definition: SpellMgr.h:682
Definition: SharedDefines.h:1013
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
QueryResult Query(const char *sql, T *connection=nullptr)
Definition: DatabaseWorkerPool.cpp:113
uint32 GetUInt32() const
Definition: Field.h:146
Definition: SpellAuraDefines.h:64
uint8_t uint8
Definition: Define.h:152
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
uint32_t uint32
Definition: g3dmath.h:168
uint32 Effect
Definition: SpellInfo.h:243

+ Here is the call graph for this function:

void SpellMgr::LoadSpellProcEvents ( )
1908 {
1909  uint32 oldMSTime = getMSTime();
1910 
1911  mSpellProcEventMap.clear(); // need for reload case
1912 
1913  // 0 1 2 3 4 5 6 7 8 9 10 11
1914  QueryResult result = WorldDatabase.Query("SELECT entry, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, SpellFamilyMask3, procFlags, procEx, ppmRate, CustomChance, Cooldown FROM spell_proc_event");
1915  if (!result)
1916  {
1917  TC_LOG_INFO("server.loading", ">> Loaded 0 spell proc event conditions. DB table `spell_proc_event` is empty.");
1918  return;
1919  }
1920 
1921  uint32 count = 0;
1922 
1923  do
1924  {
1925  Field* fields = result->Fetch();
1926 
1927  int32 spellId = fields[0].GetInt32();
1928 
1929  bool allRanks = false;
1930  if (spellId < 0)
1931  {
1932  allRanks = true;
1933  spellId = -spellId;
1934  }
1935 
1936  SpellInfo const* spellInfo = GetSpellInfo(spellId);
1937  if (!spellInfo)
1938  {
1939  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_proc_event` does not exist", spellId);
1940  continue;
1941  }
1942 
1943  if (allRanks)
1944  {
1945  if (!spellInfo->IsRanked())
1946  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_proc_event` with all ranks, but spell has no ranks.", spellId);
1947 
1948  if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId))
1949  {
1950  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_proc_event` is not first rank of spell.", spellId);
1951  continue;
1952  }
1953  }
1954 
1955  SpellProcEventEntry spellProcEvent;
1956 
1957  spellProcEvent.schoolMask = fields[1].GetInt8();
1958  spellProcEvent.spellFamilyName = fields[2].GetUInt16();
1959  spellProcEvent.spellFamilyMask[0] = fields[3].GetUInt32();
1960  spellProcEvent.spellFamilyMask[1] = fields[4].GetUInt32();
1961  spellProcEvent.spellFamilyMask[2] = fields[5].GetUInt32();
1962  spellProcEvent.spellFamilyMask[3] = fields[6].GetUInt32();
1963  spellProcEvent.procFlags = fields[7].GetUInt32();
1964  spellProcEvent.procEx = fields[8].GetUInt32();
1965  spellProcEvent.ppmRate = fields[9].GetFloat();
1966  spellProcEvent.customChance = fields[10].GetFloat();
1967  spellProcEvent.cooldown = fields[11].GetUInt32();
1968 
1969  while (spellInfo)
1970  {
1971  if (mSpellProcEventMap.find(spellInfo->Id) != mSpellProcEventMap.end())
1972  {
1973  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_proc_event` already has its first rank in table.", spellInfo->Id);
1974  break;
1975  }
1976 
1977  if (!spellInfo->ProcFlags && !spellProcEvent.procFlags)
1978  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_proc_event` probably not triggered spell", spellInfo->Id);
1979 
1980  mSpellProcEventMap[spellInfo->Id] = spellProcEvent;
1981 
1982  if (allRanks)
1983  spellInfo = spellInfo->GetNextRankSpell();
1984  else
1985  break;
1986  }
1987 
1988  ++count;
1989  }
1990  while (result->NextRow());
1991 
1992  TC_LOG_INFO("server.loading", ">> Loaded %u extra spell proc event conditions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
1993 }
uint32 Id
Definition: SpellInfo.h:329
uint32 spellFamilyName
Definition: SpellMgr.h:279
SpellProcEventMap mSpellProcEventMap
Definition: SpellMgr.h:738
float GetFloat() const
Definition: Field.h:222
Definition: SpellInfo.h:326
flag128 spellFamilyMask
Definition: SpellMgr.h:280
Class used to access individual fields of database query result.
Definition: Field.h:56
uint32 getMSTime()
Definition: Timer.h:24
WorldDatabaseWorkerPool WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
float ppmRate
Definition: SpellMgr.h:283
uint32 ProcFlags
Definition: SpellInfo.h:370
Definition: SpellMgr.h:276
SpellInfo const * GetFirstRankSpell() const
Definition: SpellInfo.cpp:2753
int32_t int32
Definition: Define.h:146
uint32_t uint32
Definition: Define.h:150
std::shared_ptr< ResultSet > QueryResult
Definition: QueryResult.h:61
uint16 GetUInt16() const
Definition: Field.h:108
bool IsRanked() const
Definition: SpellInfo.cpp:2741
int32 GetInt32() const
Definition: Field.h:165
uint32 procEx
Definition: SpellMgr.h:282
uint32 procFlags
Definition: SpellMgr.h:281
SpellInfo const * GetSpellInfo(uint32 spellId) const
Definition: SpellMgr.h:682
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
SpellInfo const * GetNextRankSpell() const
Definition: SpellInfo.cpp:2765
QueryResult Query(const char *sql, T *connection=nullptr)
Definition: DatabaseWorkerPool.cpp:113
float customChance
Definition: SpellMgr.h:284
uint32 GetUInt32() const
Definition: Field.h:146
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
uint32_t uint32
Definition: g3dmath.h:168
int8 GetInt8() const
Definition: Field.h:89
uint32 schoolMask
Definition: SpellMgr.h:278
uint32 cooldown
Definition: SpellMgr.h:285

+ Here is the call graph for this function:

void SpellMgr::LoadSpellProcs ( )
1996 {
1997  uint32 oldMSTime = getMSTime();
1998 
1999  mSpellProcMap.clear(); // need for reload case
2000 
2001  // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
2002  QueryResult result = WorldDatabase.Query("SELECT spellId, schoolMask, spellFamilyName, spellFamilyMask0, spellFamilyMask1, spellFamilyMask2, spellFamilyMask3, typeMask, spellTypeMask, spellPhaseMask, hitMask, attributesMask, ratePerMinute, chance, cooldown, charges FROM spell_proc");
2003  if (!result)
2004  {
2005  TC_LOG_INFO("server.loading", ">> Loaded 0 spell proc conditions and data. DB table `spell_proc` is empty.");
2006  return;
2007  }
2008 
2009  uint32 count = 0;
2010  do
2011  {
2012  Field* fields = result->Fetch();
2013 
2014  int32 spellId = fields[0].GetInt32();
2015 
2016  bool allRanks = false;
2017  if (spellId < 0)
2018  {
2019  allRanks = true;
2020  spellId = -spellId;
2021  }
2022 
2023  SpellInfo const* spellInfo = GetSpellInfo(spellId);
2024  if (!spellInfo)
2025  {
2026  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_proc` does not exist", spellId);
2027  continue;
2028  }
2029 
2030  if (allRanks)
2031  {
2032  if (!spellInfo->IsRanked())
2033  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_proc` with all ranks, but spell has no ranks.", spellId);
2034 
2035  if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId))
2036  {
2037  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_proc` is not first rank of spell.", spellId);
2038  continue;
2039  }
2040  }
2041 
2042  SpellProcEntry baseProcEntry;
2043 
2044  baseProcEntry.schoolMask = fields[1].GetInt8();
2045  baseProcEntry.spellFamilyName = fields[2].GetUInt16();
2046  baseProcEntry.spellFamilyMask[0] = fields[3].GetUInt32();
2047  baseProcEntry.spellFamilyMask[1] = fields[4].GetUInt32();
2048  baseProcEntry.spellFamilyMask[2] = fields[5].GetUInt32();
2049  baseProcEntry.spellFamilyMask[3] = fields[6].GetUInt32();
2050  baseProcEntry.typeMask = fields[7].GetUInt32();
2051  baseProcEntry.spellTypeMask = fields[8].GetUInt32();
2052  baseProcEntry.spellPhaseMask = fields[9].GetUInt32();
2053  baseProcEntry.hitMask = fields[10].GetUInt32();
2054  baseProcEntry.attributesMask = fields[11].GetUInt32();
2055  baseProcEntry.ratePerMinute = fields[12].GetFloat();
2056  baseProcEntry.chance = fields[13].GetFloat();
2057  float cooldown = fields[14].GetFloat();
2058  baseProcEntry.cooldown = uint32(cooldown);
2059  baseProcEntry.charges = fields[15].GetUInt32();
2060 
2061  while (spellInfo)
2062  {
2063  if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end())
2064  {
2065  TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_proc` already has its first rank in table.", spellInfo->Id);
2066  break;
2067  }
2068 
2069  SpellProcEntry procEntry = SpellProcEntry(baseProcEntry);
2070 
2071  // take defaults from dbcs
2072  if (!procEntry.typeMask)
2073  procEntry.typeMask = spellInfo->ProcFlags;
2074  if (!procEntry.charges)
2075  procEntry.charges = spellInfo->ProcCharges;
2076  if (!procEntry.chance && !procEntry.ratePerMinute)
2077  procEntry.chance = float(spellInfo->ProcChance);
2078 
2079  // validate data
2080  if (procEntry.schoolMask & ~SPELL_SCHOOL_MASK_ALL)
2081  TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `schoolMask` set: %u", spellInfo->Id, procEntry.schoolMask);
2082  if (procEntry.spellFamilyName && (procEntry.spellFamilyName < 3 || procEntry.spellFamilyName > 17 || procEntry.spellFamilyName == 14 || procEntry.spellFamilyName == 16))
2083  TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `spellFamilyName` set: %u", spellInfo->Id, procEntry.spellFamilyName);
2084  if (procEntry.chance < 0)
2085  {
2086  TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has negative value in `chance` field", spellInfo->Id);
2087  procEntry.chance = 0;
2088  }
2089  if (procEntry.ratePerMinute < 0)
2090  {
2091  TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has negative value in `ratePerMinute` field", spellInfo->Id);
2092  procEntry.ratePerMinute = 0;
2093  }
2094  if (cooldown < 0)
2095  {
2096  TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has negative value in `cooldown` field", spellInfo->Id);
2097  procEntry.cooldown = 0;
2098  }
2099  if (procEntry.chance == 0 && procEntry.ratePerMinute == 0)
2100  TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u doesn't have `chance` and `ratePerMinute` values defined, proc will not be triggered", spellInfo->Id);
2101  if (procEntry.charges > 99)
2102  {
2103  TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has too big value in `charges` field", spellInfo->Id);
2104  procEntry.charges = 99;
2105  }
2106  if (!procEntry.typeMask)
2107  TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u doesn't have `typeMask` value defined, proc will not be triggered", spellInfo->Id);
2108  if (procEntry.spellTypeMask & ~PROC_SPELL_TYPE_MASK_ALL)
2109  TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `spellTypeMask` set: %u", spellInfo->Id, procEntry.spellTypeMask);
2110  if (procEntry.spellTypeMask && !(procEntry.typeMask & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK)))
2111  TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has `spellTypeMask` value defined, but it won't be used for defined `typeMask` value", spellInfo->Id);
2112  if (!procEntry.spellPhaseMask && procEntry.typeMask & REQ_SPELL_PHASE_PROC_FLAG_MASK)
2113  TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u doesn't have `spellPhaseMask` value defined, but it's required for defined `typeMask` value, proc will not be triggered", spellInfo->Id);
2114  if (procEntry.spellPhaseMask & ~PROC_SPELL_PHASE_MASK_ALL)
2115  TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `spellPhaseMask` set: %u", spellInfo->Id, procEntry.spellPhaseMask);
2116  if (procEntry.spellPhaseMask && !(procEntry.typeMask & REQ_SPELL_PHASE_PROC_FLAG_MASK))
2117  TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has `spellPhaseMask` value defined, but it won't be used for defined `typeMask` value", spellInfo->Id);
2118  if (procEntry.hitMask & ~PROC_HIT_MASK_ALL)
2119  TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `hitMask` set: %u", spellInfo->Id, procEntry.hitMask);
2120  if (procEntry.hitMask && !(procEntry.typeMask & TAKEN_HIT_PROC_FLAG_MASK || (procEntry.typeMask & DONE_HIT_PROC_FLAG_MASK && (!procEntry.spellPhaseMask || procEntry.spellPhaseMask & (PROC_SPELL_PHASE_HIT | PROC_SPELL_PHASE_FINISH)))))
2121  TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has `hitMask` value defined, but it won't be used for defined `typeMask` and `spellPhaseMask` values", spellInfo->Id);
2122 
2123  mSpellProcMap[spellInfo->Id] = procEntry;
2124 
2125  if (allRanks)
2126  spellInfo = spellInfo->GetNextRankSpell();
2127  else
2128  break;
2129  }
2130  ++count;
2131  }
2132  while (result->NextRow());
2133 
2134  TC_LOG_INFO("server.loading", ">> Loaded %u spell proc conditions and data in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
2135 }
uint32 spellFamilyName
Definition: SpellMgr.h:293
uint32 Id
Definition: SpellInfo.h:329
Definition: SpellMgr.h:172
float GetFloat() const
Definition: Field.h:222
Definition: SpellMgr.h:247
Definition: SpellInfo.h:326
uint32 ProcCharges
Definition: SpellInfo.h:372
Class used to access individual fields of database query result.
Definition: Field.h:56
uint32 attributesMask
Definition: SpellMgr.h:299
uint32 getMSTime()
Definition: Timer.h:24
uint32 charges
Definition: SpellMgr.h:303
uint32 spellPhaseMask
Definition: SpellMgr.h:297
WorldDatabaseWorkerPool WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
float chance
Definition: SpellMgr.h:301
uint32 typeMask
Definition: SpellMgr.h:295
Definition: SpellMgr.h:246
uint32 ProcFlags
Definition: SpellInfo.h:370
SpellInfo const * GetFirstRankSpell() const
Definition: SpellInfo.cpp:2753
Definition: SpellMgr.h:184
Definition: SpellMgr.h:290
uint32 ProcChance
Definition: SpellInfo.h:371
Definition: SpellMgr.h:161
uint32 hitMask
Definition: SpellMgr.h:298
int32_t int32
Definition: Define.h:146
uint32_t uint32
Definition: Define.h:150
std::shared_ptr< ResultSet > QueryResult
Definition: QueryResult.h:61
uint16 GetUInt16() const
Definition: Field.h:108
bool IsRanked() const
Definition: SpellInfo.cpp:2741
Definition: SpellMgr.h:239
SpellProcMap mSpellProcMap
Definition: SpellMgr.h:739
Definition: SpellMgr.h:268
Definition: SpellMgr.h:170
int32 GetInt32() const
Definition: Field.h:165
SpellInfo const * GetSpellInfo(uint32 spellId) const
Definition: SpellMgr.h:682
float ratePerMinute
Definition: SpellMgr.h:300
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
SpellInfo const * GetNextRankSpell() const
Definition: SpellInfo.cpp:2765
QueryResult Query(const char *sql, T *connection=nullptr)
Definition: DatabaseWorkerPool.cpp:113
uint32 schoolMask
Definition: SpellMgr.h:292
uint32 GetUInt32() const
Definition: Field.h:146
uint32 spellTypeMask
Definition: SpellMgr.h:296
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
uint32_t uint32
Definition: g3dmath.h:168
int8 GetInt8() const
Definition: Field.h:89
uint32 cooldown
Definition: SpellMgr.h:302
Definition: SpellMgr.h:178
flag128 spellFamilyMask
Definition: SpellMgr.h:294
Definition: SpellMgr.h:248
Definition: SharedDefines.h:306

+ Here is the call graph for this function:

void SpellMgr::LoadSpellRanks ( )
1261 {
1262  uint32 oldMSTime = getMSTime();
1263 
1264  // 0 1 2
1265  QueryResult result = WorldDatabase.Query("SELECT first_spell_id, spell_id, rank from spell_ranks ORDER BY first_spell_id, rank");
1266 
1267  if (!result)
1268  {
1269  TC_LOG_INFO("server.loading", ">> Loaded 0 spell rank records. DB table `spell_ranks` is empty.");
1270  return;
1271  }
1272 
1273  uint32 count = 0;
1274  bool finished = false;
1275 
1276  do
1277  {
1278  // spellid, rank
1279  std::list < std::pair < int32, int32 > > rankChain;
1280  int32 currentSpell = -1;
1281  int32 lastSpell = -1;
1282 
1283  // fill one chain
1284  while (currentSpell == lastSpell && !finished)
1285  {
1286  Field* fields = result->Fetch();
1287 
1288  currentSpell = fields[0].GetUInt32();
1289  if (lastSpell == -1)
1290  lastSpell = currentSpell;
1291  uint32 spell_id = fields[1].GetUInt32();
1292  uint32 rank = fields[2].GetUInt8();
1293 
1294  // don't drop the row if we're moving to the next rank
1295  if (currentSpell == lastSpell)
1296  {
1297  rankChain.push_back(std::make_pair(spell_id, rank));
1298  if (!result->NextRow())
1299  finished = true;
1300  }
1301  else
1302  break;
1303  }
1304  // check if chain is made with valid first spell
1305  SpellInfo const* first = GetSpellInfo(lastSpell);
1306  if (!first)
1307  {
1308  TC_LOG_ERROR("sql.sql", "Spell rank identifier(first_spell_id) %u listed in `spell_ranks` does not exist!", lastSpell);
1309  continue;
1310  }
1311  // check if chain is long enough
1312  if (rankChain.size() < 2)
1313  {
1314  TC_LOG_ERROR("sql.sql", "There is only 1 spell rank for identifier(first_spell_id) %u in `spell_ranks`, entry is not needed!", lastSpell);
1315  continue;
1316  }
1317  int32 curRank = 0;
1318  bool valid = true;
1319  // check spells in chain
1320  for (std::list<std::pair<int32, int32> >::iterator itr = rankChain.begin(); itr!= rankChain.end(); ++itr)
1321  {
1322  SpellInfo const* spell = GetSpellInfo(itr->first);
1323  if (!spell)
1324  {
1325  TC_LOG_ERROR("sql.sql", "Spell %u (rank %u) listed in `spell_ranks` for chain %u does not exist!", itr->first, itr->second, lastSpell);
1326  valid = false;
1327  break;
1328  }
1329  ++curRank;
1330  if (itr->second != curRank)
1331  {
1332  TC_LOG_ERROR("sql.sql", "Spell %u (rank %u) listed in `spell_ranks` for chain %u does not have proper rank value(should be %u)!", itr->first, itr->second, lastSpell, curRank);
1333  valid = false;
1334  break;
1335  }
1336  }
1337  if (!valid)
1338  continue;
1339  int32 prevRank = 0;
1340  // insert the chain
1341  std::list<std::pair<int32, int32> >::iterator itr = rankChain.begin();
1342  do
1343  {
1344  ++count;
1345  int32 addedSpell = itr->first;
1346 
1347  if (mSpellInfoMap[addedSpell]->ChainEntry)
1348  TC_LOG_ERROR("sql.sql", "Spell %u (rank: %u, first: %u) listed in `spell_ranks` has already ChainEntry from dbc.", addedSpell, itr->second, lastSpell);
1349 
1350  mSpellChains[addedSpell].first = GetSpellInfo(lastSpell);
1351  mSpellChains[addedSpell].last = GetSpellInfo(rankChain.back().first);
1352  mSpellChains[addedSpell].rank = itr->second;
1353  mSpellChains[addedSpell].prev = GetSpellInfo(prevRank);
1354  mSpellInfoMap[addedSpell]->ChainEntry = &mSpellChains[addedSpell];
1355  prevRank = addedSpell;
1356  ++itr;
1357 
1358  if (itr == rankChain.end())
1359  {
1360  mSpellChains[addedSpell].next = NULL;
1361  break;
1362  }
1363  else
1364  mSpellChains[addedSpell].next = GetSpellInfo(itr->first);
1365  }
1366  while (true);
1367  }
1368  while (!finished);
1369 
1370  TC_LOG_INFO("server.loading", ">> Loaded %u spell rank records in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
1371 }
SpellInfoMap mSpellInfoMap
Definition: SpellMgr.h:753
Definition: SpellInfo.h:326
Class used to access individual fields of database query result.
Definition: Field.h:56
uint32 getMSTime()
Definition: Timer.h:24
arena_t NULL
Definition: jemalloc_internal.h:624
WorldDatabaseWorkerPool WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
uint8 GetUInt8() const
Definition: Field.h:70
int32_t int32
Definition: Define.h:146
uint32_t uint32
Definition: Define.h:150
std::shared_ptr< ResultSet > QueryResult
Definition: QueryResult.h:61
SpellInfo const * GetSpellInfo(uint32 spellId) const
Definition: SpellMgr.h:682
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
QueryResult Query(const char *sql, T *connection=nullptr)
Definition: DatabaseWorkerPool.cpp:113
uint32 GetUInt32() const
Definition: Field.h:146
SpellChainMap mSpellChains
Definition: SpellMgr.h:729
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207

+ Here is the call graph for this function:

void SpellMgr::LoadSpellRequired ( )
1374 {
1375  uint32 oldMSTime = getMSTime();
1376 
1377  mSpellsReqSpell.clear(); // need for reload case
1378  mSpellReq.clear(); // need for reload case
1379 
1380  // 0 1
1381  QueryResult result = WorldDatabase.Query("SELECT spell_id, req_spell from spell_required");
1382 
1383  if (!result)
1384  {
1385  TC_LOG_INFO("server.loading", ">> Loaded 0 spell required records. DB table `spell_required` is empty.");
1386 
1387  return;
1388  }
1389 
1390  uint32 count = 0;
1391  do
1392  {
1393  Field* fields = result->Fetch();
1394 
1395  uint32 spell_id = fields[0].GetUInt32();
1396  uint32 spell_req = fields[1].GetUInt32();
1397 
1398  // check if chain is made with valid first spell
1399  SpellInfo const* spell = GetSpellInfo(spell_id);
1400  if (!spell)
1401  {
1402  TC_LOG_ERROR("sql.sql", "spell_id %u in `spell_required` table is not found in dbcs, skipped", spell_id);
1403  continue;
1404  }
1405 
1406  SpellInfo const* reqSpell = GetSpellInfo(spell_req);
1407  if (!reqSpell)
1408  {
1409  TC_LOG_ERROR("sql.sql", "req_spell %u in `spell_required` table is not found in dbcs, skipped", spell_req);
1410  continue;
1411  }
1412 
1413  if (spell->IsRankOf(reqSpell))
1414  {
1415  TC_LOG_ERROR("sql.sql", "req_spell %u and spell_id %u in `spell_required` table are ranks of the same spell, entry not needed, skipped", spell_req, spell_id);
1416  continue;
1417  }
1418 
1419  if (IsSpellRequiringSpell(spell_id, spell_req))
1420  {
1421  TC_LOG_ERROR("sql.sql", "duplicated entry of req_spell %u and spell_id %u in `spell_required`, skipped", spell_req, spell_id);
1422  continue;
1423  }
1424 
1425  mSpellReq.insert (std::pair<uint32, uint32>(spell_id, spell_req));
1426  mSpellsReqSpell.insert (std::pair<uint32, uint32>(spell_req, spell_id));
1427  ++count;
1428  } while (result->NextRow());
1429 
1430  TC_LOG_INFO("server.loading", ">> Loaded %u spell required records in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
1431 
1432 }
Definition: SpellInfo.h:326
Class used to access individual fields of database query result.
Definition: Field.h:56
SpellRequiredMap mSpellReq
Definition: SpellMgr.h:731
uint32 getMSTime()
Definition: Timer.h:24
WorldDatabaseWorkerPool WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
bool IsSpellRequiringSpell(uint32 spellid, uint32 req_spellid) const
Definition: SpellMgr.cpp:650
uint32_t uint32
Definition: Define.h:150
std::shared_ptr< ResultSet > QueryResult
Definition: QueryResult.h:61
bool IsRankOf(SpellInfo const *spellInfo) const
Definition: SpellInfo.cpp:2815
SpellInfo const * GetSpellInfo(uint32 spellId) const
Definition: SpellMgr.h:682
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
SpellsRequiringSpellMap mSpellsReqSpell
Definition: SpellMgr.h:730
QueryResult Query(const char *sql, T *connection=nullptr)
Definition: DatabaseWorkerPool.cpp:113
uint32 GetUInt32() const
Definition: Field.h:146
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207

+ Here is the call graph for this function:

void SpellMgr::LoadSpellTargetPositions ( )
1683 {
1684  uint32 oldMSTime = getMSTime();
1685 
1686  mSpellTargetPositions.clear(); // need for reload case
1687 
1688  // 0 1 2 3 4 5
1689  QueryResult result = WorldDatabase.Query("SELECT ID, EffectIndex, MapID, PositionX, PositionY, PositionZ FROM spell_target_position");
1690  if (!result)
1691  {
1692  TC_LOG_INFO("server.loading", ">> Loaded 0 spell target coordinates. DB table `spell_target_position` is empty.");
1693  return;
1694  }
1695 
1696  uint32 count = 0;
1697  do
1698  {
1699  Field* fields = result->Fetch();
1700 
1701  uint32 spellId = fields[0].GetUInt32();
1702  SpellEffIndex effIndex = SpellEffIndex(fields[1].GetUInt8());
1703 
1705 
1706  st.target_mapId = fields[2].GetUInt16();
1707  st.target_X = fields[3].GetFloat();
1708  st.target_Y = fields[4].GetFloat();
1709  st.target_Z = fields[5].GetFloat();
1710 
1711  MapEntry const* mapEntry = sMapStore.LookupEntry(st.target_mapId);
1712  if (!mapEntry)
1713  {
1714  TC_LOG_ERROR("sql.sql", "Spell (Id: %u, EffectIndex: %u) is using a non-existant MapID (ID: %u).", spellId, effIndex, st.target_mapId);
1715  continue;
1716  }
1717 
1718  if (st.target_X == 0 && st.target_Y == 0 && st.target_Z == 0)
1719  {
1720  TC_LOG_ERROR("sql.sql", "Spell (Id: %u, EffectIndex: %u): target coordinates not provided.", spellId, effIndex);
1721  continue;
1722  }
1723 
1724