aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/Chat.cpp2
-rw-r--r--src/game/Chat.h2
-rw-r--r--src/game/Level3.cpp10
-rw-r--r--src/game/NPCHandler.cpp5
-rw-r--r--src/game/Player.cpp9
-rw-r--r--src/game/SpellMgr.cpp293
-rw-r--r--src/game/SpellMgr.h20
-rw-r--r--src/game/World.cpp3
8 files changed, 197 insertions, 147 deletions
diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp
index 4a4a6f8d2be..0a646c93e83 100644
--- a/src/game/Chat.cpp
+++ b/src/game/Chat.cpp
@@ -281,7 +281,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "skill_fishing_base_level", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSkillFishingBaseLevelCommand, "", NULL },
{ "skinning_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesSkinningCommand, "", NULL },
{ "spell_affect", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellAffectCommand, "", NULL },
- { "spell_chain", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellChainCommand, "", NULL },
+ { "spell_required", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellRequiredCommand, "", NULL },
{ "spell_elixir", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellElixirCommand, "", NULL },
{ "spell_learn_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellLearnSpellCommand, "", NULL },
{ "spell_pet_auras", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellPetAurasCommand, "", NULL },
diff --git a/src/game/Chat.h b/src/game/Chat.h
index 2a7b1b62bdd..7356835bfb8 100644
--- a/src/game/Chat.h
+++ b/src/game/Chat.h
@@ -248,7 +248,7 @@ class ChatHandler
bool HandleReloadSkillExtraItemTemplateCommand(const char* args);
bool HandleReloadSkillFishingBaseLevelCommand(const char* args);
bool HandleReloadSpellAffectCommand(const char* args);
- bool HandleReloadSpellChainCommand(const char* args);
+ bool HandleReloadSpellRequiredCommand(const char* args);
bool HandleReloadSpellElixirCommand(const char* args);
bool HandleReloadSpellLearnSpellCommand(const char* args);
bool HandleReloadSpellProcEventCommand(const char* args);
diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
index 13f6b101a7b..34a3592db8e 100644
--- a/src/game/Level3.cpp
+++ b/src/game/Level3.cpp
@@ -145,7 +145,7 @@ bool ChatHandler::HandleReloadAllSpellCommand(const char*)
HandleReloadSkillDiscoveryTemplateCommand("a");
HandleReloadSkillExtraItemTemplateCommand("a");
HandleReloadSpellAffectCommand("a");
- HandleReloadSpellChainCommand("a");
+ HandleReloadSpellRequiredCommand("a");
HandleReloadSpellElixirCommand("a");
HandleReloadSpellLearnSpellCommand("a");
HandleReloadSpellProcEventCommand("a");
@@ -423,11 +423,11 @@ bool ChatHandler::HandleReloadSpellAffectCommand(const char*)
return true;
}
-bool ChatHandler::HandleReloadSpellChainCommand(const char*)
+bool ChatHandler::HandleReloadSpellRequiredCommand(const char*)
{
- sLog.outString( "Re-Loading Spell Chain Data... " );
- spellmgr.LoadSpellChains();
- SendGlobalSysMessage("DB table `spell_chain` (spell ranks) reloaded.");
+ sLog.outString( "Re-Loading Spell Required Data... " );
+ spellmgr.LoadSpellRequired();
+ SendGlobalSysMessage("DB table `spell_required` reloaded.");
return true;
}
diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp
index 04c31ff8f8d..6bb916d9fe0 100644
--- a/src/game/NPCHandler.cpp
+++ b/src/game/NPCHandler.cpp
@@ -174,6 +174,7 @@ void WorldSession::SendTrainerList( uint64 guid, const std::string& strTitle )
bool primary_prof_first_rank = spellmgr.IsPrimaryProfessionFirstRankSpell(tSpell->spell);
SpellChainNode const* chain_node = spellmgr.GetSpellChainNode(tSpell->spell);
+ uint32 req_spell = spellmgr.GetSpellRequired(tSpell->spell);
data << uint32(tSpell->spell);
data << uint8(_player->GetTrainerSpellState(tSpell));
@@ -184,8 +185,8 @@ void WorldSession::SendTrainerList( uint64 guid, const std::string& strTitle )
data << uint8(tSpell->reqlevel);
data << uint32(tSpell->reqskill);
data << uint32(tSpell->reqskillvalue);
- data << uint32(chain_node ? (chain_node->prev ? chain_node->prev : chain_node->req) : 0);
- data << uint32(chain_node && chain_node->prev ? chain_node->req : 0);
+ data << uint32(chain_node && chain_node->prev ? chain_node->prev : req_spell);
+ data << uint32(chain_node && chain_node->prev ? req_spell : 0);
data << uint32(0);
}
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index e9a7a0f73ed..314e6c5ac09 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -2952,8 +2952,8 @@ void Player::removeSpell(uint32 spell_id, bool disabled)
removeSpell(node->next,disabled);
}
//unlearn spells dependent from recently removed spells
- SpellRequiredMap const& reqMap = spellmgr.GetSpellRequiredMap();
- SpellRequiredMap::const_iterator itr2 = reqMap.find(spell_id);
+ SpellsRequiringSpellMap const& reqMap = spellmgr.GetSpellsRequiringSpell();
+ SpellsRequiringSpellMap::const_iterator itr2 = reqMap.find(spell_id);
for (uint32 i=reqMap.count(spell_id);i>0;i--,itr2++)
removeSpell(itr2->second,disabled);
@@ -3546,9 +3546,12 @@ TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell
// check prev.rank requirement
if(spell_chain->prev && !HasSpell(spell_chain->prev))
return TRAINER_SPELL_RED;
+ }
+ if(uint32 spell_req = spellmgr.GetSpellRequired(trainer_spell->spell))
+ {
// check additional spell requirement
- if(spell_chain->req && !HasSpell(spell_chain->req))
+ if(!HasSpell(spell_req))
return TRAINER_SPELL_RED;
}
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index cddf7d83e72..fb14164b98e 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -1411,20 +1411,12 @@ SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spell
return NULL;
}
-void SpellMgr::LoadSpellChains()
+void SpellMgr::LoadSpellRequired()
{
- mSpellChains.clear(); // need for reload case
- mSpellReq.clear(); // need for reload case
-
- QueryResult *result = WorldDatabase.Query("SELECT spell_id, first_spell, rank, req_spell from spell_chain ORDER BY first_spell, rank");
+ mSpellsReqSpell.clear(); // need for reload case
+ mSpellReq.clear(); // need for reload case
- struct SpellChainEntry
- {
- uint32 spell;
- uint32 first;
- uint32 req;
- uint8 rank;
- };
+ QueryResult *result = WorldDatabase.Query("SELECT spell_id, req_spell from spell_required");
if(result == NULL)
{
@@ -1438,172 +1430,209 @@ void SpellMgr::LoadSpellChains()
}
uint32 rows = 0;
- SpellChainEntry *SpellChainTable = new SpellChainEntry [result->GetRowCount()];
-
barGoLink bar( result->GetRowCount() );
do
{
bar.step();
Field *fields = result->Fetch();
- SpellChainTable[rows].spell = fields[0].GetUInt32();
- SpellChainTable[rows].first = fields[1].GetUInt32();
- SpellChainTable[rows].rank = fields[2].GetUInt32();
- SpellChainTable[rows].req = fields[3].GetUInt32();
-
- if (SpellChainTable[rows].req)
- mSpellReq.insert (std::pair<uint32, uint32>(SpellChainTable[rows].req, SpellChainTable[rows].spell));
+ uint32 spell_id = fields[0].GetUInt32();
+ uint32 spell_req = fields[1].GetUInt32();
+ mSpellsReqSpell.insert (std::pair<uint32, uint32>(spell_req, spell_id));
+ mSpellReq[spell_id] = spell_req;
++rows;
} while( result->NextRow() );
delete result;
- uint32 cur_row=0;
- do
- {
- uint32 spell_id=SpellChainTable[cur_row].spell;
- SpellChainNode node;
- node.first = SpellChainTable[cur_row].first;
- node.rank = SpellChainTable[cur_row].rank;
- node.req = SpellChainTable[cur_row].req;
- //get field "prev"
- if (spell_id == node.first || cur_row==0)
- {
- if (node.rank!=1)
- sLog.outErrorDb("Incorrect rank for entry: %u",spell_id);
- node.prev = 0;
- }
- else if (SpellChainTable[cur_row-1].rank!=node.rank-1)
- {
- sLog.outErrorDb("Spells %u and %u (first: %u, rank: %d, req: %u) listed in `spell_chain` have not compatible rank data."
- ,spell_id,SpellChainTable[cur_row-1].spell,node.first,node.rank,node.req);
- node.prev = 0;
- }
- else
- node.prev=SpellChainTable[cur_row-1].spell;
+ sLog.outString();
+ sLog.outString( ">> Loaded %u spell required records", rows );
+}
- //get field "next"
- if (cur_row==rows-1 || SpellChainTable[cur_row+1].first!= node.first )
- {
- //get field "last"
- for (uint32 last_row = 1; cur_row - last_row < rows && SpellChainTable[cur_row - last_row].first == node.first; ++last_row)
- mSpellChains[SpellChainTable[cur_row-last_row].spell].last = spell_id;
- node.last = spell_id;
- node.next = 0;
- }
- else if (SpellChainTable[cur_row+1].rank!=node.rank+1)
- {
- sLog.outErrorDb("Spells %u and %u (first: %u, rank: %d, req: %u) listed in `spell_chain` have not compatible rank data."
- ,spell_id,SpellChainTable[cur_row+1].spell,node.first,node.rank,node.req);
- node.next = 0;
- }
- else
- {
- node.next=SpellChainTable[cur_row+1].spell;
- node.last=0;
- }
+void SpellMgr::LoadSpellChains()
+{
+ mSpellChains.clear(); // need for reload case
+ struct SpellRankEntry
+ {
+ uint32 SkillId;
+ char const *SpellName;
+ uint32 DurationIndex;
+ uint32 RangeIndex;
+ uint32 SpellVisual;
+ uint32 ProcFlags;
+ uint64 SpellFamilyFlags;
+ uint32 TargetAuraState;
+ uint32 ManaCost;
+
+ bool operator()(const SpellRankEntry & _Left,const SpellRankEntry & _Right)const
+ {
+ return (_Left.SkillId != _Right.SkillId ? _Left.SkillId < _Right.SkillId
+ : _Left.SpellName!=_Right.SpellName ? _Left.SpellName < _Right.SpellName
+ : _Left.ProcFlags!=_Right.ProcFlags ? _Left.ProcFlags < _Right.ProcFlags
+ : _Left.SpellFamilyFlags!=_Right.SpellFamilyFlags ? _Left.SpellFamilyFlags < _Right.SpellFamilyFlags
+ : (_Left.SpellVisual!=_Right.SpellVisual) && (!_Left.SpellVisual || !_Right.SpellVisual) ? _Left.SpellVisual < _Right.SpellVisual
+ : (_Left.ManaCost!=_Right.ManaCost) && (!_Left.ManaCost || !_Right.ManaCost) ? _Left.ManaCost < _Right.ManaCost
+ : (_Left.DurationIndex!=_Right.DurationIndex) && (!_Left.DurationIndex || !_Right.DurationIndex)? _Left.DurationIndex < _Right.DurationIndex
+ : (_Left.RangeIndex!=_Right.RangeIndex) && (!_Left.RangeIndex || !_Right.RangeIndex || _Left.RangeIndex==1 || !_Right.RangeIndex==1) ? _Left.RangeIndex < _Right.RangeIndex
+ : _Left.TargetAuraState < _Right.TargetAuraState
+ );
+ }
+ };
+ struct SpellRankValue
+ {
+ uint32 Id;
+ char const *Rank;
+ };
- cur_row++;
+ std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry> RankMap;
- if(!sSpellStore.LookupEntry(spell_id))
- {
- sLog.outErrorDb("Spell %u listed in `spell_chain` does not exist",spell_id);
+ for (uint32 ability_id=0;ability_id<sSkillLineAbilityStore.GetNumRows();ability_id++)
+ {
+ SkillLineAbilityEntry const *AbilityInfo=sSkillLineAbilityStore.LookupEntry(ability_id);
+ if (!AbilityInfo)
continue;
- }
- if(!sSpellStore.LookupEntry(node.first))
- {
- sLog.outErrorDb("Spell %u (first: %u, rank: %d, req: %u) listed in `spell_chain` has not existing first rank spell.",
- spell_id,node.first,node.rank,node.req);
+ //get only spell with lowest ability_id to prevent doubles
+ uint32 spell_id=AbilityInfo->spellId;
+ if(mSkillLineAbilityMap.lower_bound(spell_id)->second->id!=ability_id)
continue;
- }
+ SpellEntry const *SpellInfo=sSpellStore.LookupEntry(spell_id);
+ if (!SpellInfo)
+ continue;
+ std::string sRank = SpellInfo->Rank[sWorld.GetDefaultDbcLocale()];
+ if(sRank.empty())
+ continue;
+
+ SpellRankEntry entry;
+ SpellRankValue value;
+ entry.SkillId=AbilityInfo->skillId;
+ entry.SpellName=SpellInfo->SpellName[sWorld.GetDefaultDbcLocale()];
+ entry.DurationIndex=SpellInfo->DurationIndex;
+ entry.RangeIndex=SpellInfo->rangeIndex;
+ entry.ProcFlags=SpellInfo->procFlags;
+ entry.SpellFamilyFlags=SpellInfo->SpellFamilyFlags;
+ entry.TargetAuraState=SpellInfo->TargetAuraState;
+ entry.SpellVisual=SpellInfo->SpellVisual;
+ entry.ManaCost=SpellInfo->manaCost;
+
+ value.Id=spell_id;
+ value.Rank=SpellInfo->Rank[sWorld.GetDefaultDbcLocale()];
+ RankMap.insert(std::pair<SpellRankEntry, SpellRankValue>(entry,value));
+ }
- if(node.req!=0 && !sSpellStore.LookupEntry(node.req))
+ barGoLink bar(RankMap.size());
+
+ uint32 count=0;
+
+ for (std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator itr = RankMap.begin();itr!=RankMap.end();)
+ {
+ SpellRankEntry entry=itr->first;
+ //trac errors in extracted data
+ std::multimap<char const *, std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator> RankErrorMap;
+ for (std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator itr2 = RankMap.lower_bound(entry);itr2!=RankMap.upper_bound(entry);itr2++)
{
- sLog.outErrorDb("Spell %u (first: %u, rank: %d, req: %u) listed in `spell_chain` has not existing required spell.",
- spell_id,node.first,node.rank,node.req);
- continue;
+ bar.step();
+ RankErrorMap.insert(std::pair<char const *, std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator>(itr2->second.Rank,itr2));
}
-
- // talents not required data in spell chain for work, but must be checked if present for intergrity
- if(TalentSpellPos const* pos = GetTalentSpellPos(spell_id))
+ for (std::multimap<char const *, std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator>::iterator itr2 = RankErrorMap.begin();itr2!=RankErrorMap.end();)
{
- if(node.rank!=pos->rank+1)
- {
- sLog.outErrorDb("Talent %u (first: %u, rank: %d, req: %u) listed in `spell_chain` has wrong rank.",
- spell_id,node.first,node.rank,node.req);
- continue;
- }
-
- if(TalentEntry const* talentEntry = sTalentStore.LookupEntry(pos->talent_id))
+ char const * err_entry=itr2->first;
+ uint32 rank_count=RankErrorMap.count(itr2->first);
+ if (rank_count>1)
+ for (itr2 = RankErrorMap.lower_bound(err_entry);itr2!=RankErrorMap.upper_bound(err_entry);itr2++)
{
- if(node.first!=talentEntry->RankID[0])
- {
- sLog.outErrorDb("Talent %u (first: %u, rank: %d, req: %u) listed in `spell_chain` has wrong first rank spell.",
- spell_id,node.first,node.rank,node.req);
- continue;
- }
-
- if(node.rank > 1 && node.prev != talentEntry->RankID[node.rank-1-1])
+ sLog.outDebug("There is a duplicate rank entry (%s) for spell: %u",itr2->first,itr2->second->second.Id);
+ if (itr2->second->second.Id!=21084) //only one exception to these rules (not needed in 3.0.3)
{
- sLog.outErrorDb("Talent %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has wrong prev rank spell.",
- spell_id,node.prev,node.first,node.rank,node.req);
- continue;
+ sLog.outDebug("Spell %u removed from chain data.",itr2->second->second.Id);
+ RankMap.erase(itr2->second);
+ itr=RankMap.lower_bound(entry);
}
}
+ else
+ itr2++;
}
- mSpellChains[spell_id] = node;
- }
- while( cur_row<rows );
+ //do not proceed for spells with less than 2 ranks
+ uint32 spell_max_rank=RankMap.count(entry);
+ if (spell_max_rank<2)
+ {
+ itr=RankMap.upper_bound(entry);
+ continue;
+ }
- delete[] SpellChainTable;
+ itr=RankMap.upper_bound(entry);
- // additional integrity checks
- for(SpellChainMap::iterator i = mSpellChains.begin(); i != mSpellChains.end(); ++i)
- {
- if(i->second.prev)
+ //order spells by spells by spellLevel
+ std::list<uint32> RankedSpells;
+ uint32 min_spell_lvl=0;
+ std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator min_itr;
+ for (;RankMap.count(entry);)
{
- SpellChainMap::iterator i_prev = mSpellChains.find(i->second.prev);
- if(i_prev == mSpellChains.end())
+ for (std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator itr2 = RankMap.lower_bound(entry);itr2!=RankMap.upper_bound(entry);itr2++)
{
- sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has not found previous rank spell in table.",
- i->first,i->second.prev,i->second.first,i->second.rank,i->second.req);
+ SpellEntry const *SpellInfo=sSpellStore.LookupEntry(itr2->second.Id);
+ if (SpellInfo->spellLevel<min_spell_lvl || itr2==RankMap.lower_bound(entry))
+ {
+ min_spell_lvl=SpellInfo->spellLevel;
+ min_itr=itr2;
+ }
}
- else if( i_prev->second.first != i->second.first )
+ RankedSpells.push_back(min_itr->second.Id);
+ RankMap.erase(min_itr);
+ }
+
+ //use data from talent.dbc
+ uint16 talent_id=0;
+ for(std::list<uint32>::iterator itr2 = RankedSpells.begin();itr2!=RankedSpells.end();)
+ {
+ if (TalentSpellPos const* TalentPos=GetTalentSpellPos(*itr2))
{
- sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has different first spell in chain compared to previous rank spell (prev: %u, first: %u, rank: %d, req: %u).",
- i->first,i->second.prev,i->second.first,i->second.rank,i->second.req,
- i_prev->second.prev,i_prev->second.first,i_prev->second.rank,i_prev->second.req);
+ talent_id=TalentPos->talent_id;
+ RankedSpells.erase(itr2);
+ itr2 = RankedSpells.begin();
}
- else if( i_prev->second.rank+1 != i->second.rank )
+ else
+ itr2++;
+ }
+ if (talent_id)
+ {
+ TalentEntry const *TalentInfo = sTalentStore.LookupEntry(talent_id);
+ for (uint8 rank=5;rank;rank--)
{
- sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has different rank compared to previous rank spell (prev: %u, first: %u, rank: %d, req: %u).",
- i->first,i->second.prev,i->second.first,i->second.rank,i->second.req,
- i_prev->second.prev,i_prev->second.first,i_prev->second.rank,i_prev->second.req);
+ if (TalentInfo->RankID[rank-1])
+ RankedSpells.push_front(TalentInfo->RankID[rank-1]);
}
}
- if(i->second.req)
+ count++;
+
+ itr=RankMap.upper_bound(entry);
+ uint32 spell_rank=1;
+ for(std::list<uint32>::iterator itr2 = RankedSpells.begin();itr2!=RankedSpells.end();spell_rank++)
{
- SpellChainMap::iterator i_req = mSpellChains.find(i->second.req);
- if(i_req == mSpellChains.end())
- {
- sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has not found required rank spell in table.",
- i->first,i->second.prev,i->second.first,i->second.rank,i->second.req);
- }
- else if( i_req->second.first == i->second.first )
+ uint32 spell_id=*itr2;
+ mSpellChains[spell_id].rank=spell_rank;
+ mSpellChains[spell_id].first=RankedSpells.front();
+ mSpellChains[spell_id].last=RankedSpells.back();
+
+ itr2++;
+ if (spell_rank<2)
+ mSpellChains[spell_id].prev=0;
+
+ if (spell_id==RankedSpells.back())
+ mSpellChains[spell_id].next=0;
+ else
{
- sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has required rank spell from same spell chain (prev: %u, first: %u, rank: %d, req: %u).",
- i->first,i->second.prev,i->second.first,i->second.rank,i->second.req,
- i_req->second.prev,i_req->second.first,i_req->second.rank,i_req->second.req);
+ mSpellChains[*itr2].prev=spell_id;
+ mSpellChains[spell_id].next=*itr2;
}
}
}
sLog.outString();
- sLog.outString( ">> Loaded %u spell chain records", rows );
+ sLog.outString( ">> Loaded %u spell chains",count);
}
void SpellMgr::LoadSpellLearnSkills()
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index e3bc4c55b99..abe0c39d9d0 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -657,12 +657,15 @@ struct SpellChainNode
uint32 next;
uint32 first;
uint32 last;
- uint32 req;
uint8 rank;
};
typedef UNORDERED_MAP<uint32, SpellChainNode> SpellChainMap;
-typedef std::multimap<uint32, uint32> SpellRequiredMap;
+
+// spell_id req_spell
+typedef UNORDERED_MAP<uint32, uint32> SpellRequiredMap;
+
+typedef std::multimap<uint32, uint32> SpellsRequiringSpellMap;
// Spell learning properties (accessed using SpellMgr functions)
struct SpellLearnSkillNode
@@ -787,6 +790,15 @@ class SpellMgr
return &itr->second;
}
+ uint32 GetSpellRequired(uint32 spell_id) const
+ {
+ SpellRequiredMap::const_iterator itr = mSpellReq.find(spell_id);
+ if(itr == mSpellReq.end())
+ return NULL;
+
+ return itr->second;
+ }
+
uint32 GetFirstSpellInChain(uint32 spell_id) const
{
if(SpellChainNode const* node = GetSpellChainNode(spell_id))
@@ -803,7 +815,7 @@ class SpellMgr
return 0;
}
- SpellRequiredMap const& GetSpellRequiredMap() const { return mSpellReq; }
+ SpellsRequiringSpellMap const& GetSpellsRequiringSpell() const { return mSpellsReqSpell; }
// Note: not use rank for compare to spell ranks: spell chains isn't linear order
// Use IsHighRankOfSpell instead
@@ -947,6 +959,7 @@ class SpellMgr
// Loading data at server startup
void LoadSpellChains();
+ void LoadSpellRequired();
void LoadSpellLearnSkills();
void LoadSpellLearnSpells();
void LoadSpellScriptTarget();
@@ -963,6 +976,7 @@ class SpellMgr
private:
SpellScriptTarget mSpellScriptTarget;
SpellChainMap mSpellChains;
+ SpellsRequiringSpellMap mSpellsReqSpell;
SpellRequiredMap mSpellReq;
SpellLearnSkillMap mSpellLearnSkills;
SpellLearnSpellMap mSpellLearnSpells;
diff --git a/src/game/World.cpp b/src/game/World.cpp
index baecc8871fb..47598dafc65 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -1091,6 +1091,9 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Spell Chain Data..." );
spellmgr.LoadSpellChains();
+ sLog.outString( "Loading Spell Required Data..." );
+ spellmgr.LoadSpellRequired();
+
sLog.outString( "Loading Spell Elixir types..." );
spellmgr.LoadSpellElixirs();