*Use prev_spell data calculated on startup instead of sql column.
*Changed map structure of req spell. *Added precalculated data for next spell in rank and last one. *Removed duplicated rank entries for some spells and used req_spell column instead. *Allow required spell to have required spell. --HG-- branch : trunk
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
-- added missing entry for 3rd rank of gift of the wild
|
||||
|
||||
DELETE FROM spell_chain WHERE spell_id = 21849;
|
||||
DELETE FROM spell_chain WHERE spell_id = 21850;
|
||||
DELETE FROM spell_chain WHERE spell_id = 26991;
|
||||
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (21849,0,21849,1,0);
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (21850,21849,21849,2,0);
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (26991,21850,21849,3,0);
|
||||
|
||||
-- weaponsmith and armorsmith as blacksmith req spells
|
||||
|
||||
DELETE FROM spell_chain WHERE spell_id = 9787;
|
||||
DELETE FROM spell_chain WHERE spell_id = 9788;
|
||||
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (9787,0,9787,1,9785);
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (9788,0,9788,1,9785);
|
||||
|
||||
-- axe/sword/hammer smith req weaponsmith
|
||||
|
||||
DELETE FROM spell_chain WHERE spell_id = 17039;
|
||||
DELETE FROM spell_chain WHERE spell_id = 17040;
|
||||
DELETE FROM spell_chain WHERE spell_id = 17041;
|
||||
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (17039,0,17039,1,9787);
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (17040,0,17040,1,9787);
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (17041,0,17041,1,9787);
|
||||
|
||||
-- letherworking specs req spells
|
||||
|
||||
DELETE FROM spell_chain WHERE spell_id = 10660;
|
||||
DELETE FROM spell_chain WHERE spell_id = 10658;
|
||||
DELETE FROM spell_chain WHERE spell_id = 10656;
|
||||
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (10660,0,10660,1,10662);
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (10658,0,10658,1,10662);
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (10656,0,10656,1,10662);
|
||||
|
||||
-- alchemy specs req spells
|
||||
|
||||
DELETE FROM spell_chain WHERE spell_id = 28672;
|
||||
DELETE FROM spell_chain WHERE spell_id = 28675;
|
||||
DELETE FROM spell_chain WHERE spell_id = 28677;
|
||||
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (28672,0,28672,1,28596);
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (28675,0,28675,1,28596);
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (28677,0,28677,1,28596);
|
||||
|
||||
-- tailoring specs req spells
|
||||
|
||||
DELETE FROM spell_chain WHERE spell_id = 26801;
|
||||
DELETE FROM spell_chain WHERE spell_id = 26798;
|
||||
DELETE FROM spell_chain WHERE spell_id = 26797;
|
||||
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (26801,0,26801,1,26790);
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (26798,0,26798,1,26790);
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (26797,0,26797,1,26790);
|
||||
|
||||
-- engineering specs req spells
|
||||
|
||||
DELETE FROM spell_chain WHERE spell_id = 20222;
|
||||
DELETE FROM spell_chain WHERE spell_id = 20219;
|
||||
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (20222,0,20222,1,12656);
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (20219,0,20219,1,12656);
|
||||
|
||||
-- divine spirit req spells
|
||||
|
||||
DELETE FROM spell_chain WHERE spell_id = 27681;
|
||||
DELETE FROM spell_chain WHERE spell_id = 32999;
|
||||
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (27681,0,27681,1,14752);
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (32999,27681,27681,2,0);
|
||||
|
||||
-- judgement of justice req seal of justice(dunno what is this for)
|
||||
|
||||
DELETE FROM spell_chain WHERE spell_id = 20184;
|
||||
DELETE FROM spell_chain WHERE spell_id = 31896;
|
||||
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (20184,0,20184,1,20164);
|
||||
INSERT INTO spell_chain (spell_id,prev_spell,first_spell,rank,req_spell) VALUES (31896,20184,20184,2,0);
|
||||
|
||||
ALTER TABLE spell_chain DROP COLUMN prev_spell;␍
|
||||
+8
-4
@@ -1769,12 +1769,16 @@ bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
|
||||
|
||||
static void learnAllHighRanks(Player* player, uint32 spellid)
|
||||
{
|
||||
SpellChainMapNext const& nextMap = spellmgr.GetSpellChainNext();
|
||||
for(SpellChainMapNext::const_iterator itr = nextMap.lower_bound(spellid); itr != nextMap.upper_bound(spellid); ++itr)
|
||||
SpellChainNode const* node;
|
||||
do
|
||||
{
|
||||
player->learnSpell(itr->second);
|
||||
learnAllHighRanks(player,itr->second);
|
||||
node = spellmgr.GetSpellChainNode(spellid);
|
||||
player->learnSpell(spellid);
|
||||
if (!node)
|
||||
break;
|
||||
spellid=node->next;
|
||||
}
|
||||
while (node->next);
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
|
||||
|
||||
+16
-9
@@ -2911,12 +2911,12 @@ void Player::learnSpell(uint32 spell_id)
|
||||
bool learning = addSpell(spell_id,active);
|
||||
|
||||
// learn all disabled higher ranks (recursive)
|
||||
SpellChainMapNext const& nextMap = spellmgr.GetSpellChainNext();
|
||||
for(SpellChainMapNext::const_iterator i = nextMap.lower_bound(spell_id); i != nextMap.upper_bound(spell_id); ++i)
|
||||
SpellChainNode const* node = spellmgr.GetSpellChainNode(spell_id);
|
||||
if (node)
|
||||
{
|
||||
PlayerSpellMap::iterator iter = m_spells.find(i->second);
|
||||
if (disabled && iter != m_spells.end() && iter->second->disabled)
|
||||
learnSpell(i->second);
|
||||
PlayerSpellMap::iterator iter = m_spells.find(node->next);
|
||||
if (disabled && iter != m_spells.end() && iter->second->disabled )
|
||||
learnSpell(node->next);
|
||||
}
|
||||
|
||||
// prevent duplicated entires in spell book
|
||||
@@ -2938,10 +2938,17 @@ void Player::removeSpell(uint32 spell_id, bool disabled)
|
||||
return;
|
||||
|
||||
// unlearn non talent higher ranks (recursive)
|
||||
SpellChainMapNext const& nextMap = spellmgr.GetSpellChainNext();
|
||||
for(SpellChainMapNext::const_iterator itr2 = nextMap.lower_bound(spell_id); itr2 != nextMap.upper_bound(spell_id); ++itr2)
|
||||
if(HasSpell(itr2->second) && !GetTalentSpellPos(itr2->second))
|
||||
removeSpell(itr2->second,disabled);
|
||||
SpellChainNode const* node = spellmgr.GetSpellChainNode(spell_id);
|
||||
if (node)
|
||||
{
|
||||
if(HasSpell(node->next) && !GetTalentSpellPos(node->next))
|
||||
removeSpell(node->next,disabled);
|
||||
}
|
||||
//unlearn spells dependent from recently removed spells
|
||||
SpellRequiredMap const& reqMap = spellmgr.GetSpellRequiredMap();
|
||||
SpellRequiredMap::const_iterator itr2 = reqMap.find(spell_id);
|
||||
for (uint32 i=reqMap.count(spell_id);i>0;i--,itr2++)
|
||||
removeSpell(itr2->second,disabled);
|
||||
|
||||
// removing
|
||||
WorldPacket data(SMSG_REMOVED_SPELL, 4);
|
||||
|
||||
+92
-67
@@ -1156,11 +1156,6 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool
|
||||
{
|
||||
//if(spellId_1 == spellId_2) // auras due to the same spell
|
||||
// return false;
|
||||
|
||||
//use data of highest rank spell(needed for spells which ranks have different effects)
|
||||
//spellId_1=GetLastSpellInChain(spellId_1);
|
||||
//spellId_2=GetLastSpellInChain(spellId_2);
|
||||
|
||||
SpellEntry const *spellInfo_1 = sSpellStore.LookupEntry(spellId_1);
|
||||
SpellEntry const *spellInfo_2 = sSpellStore.LookupEntry(spellId_2);
|
||||
|
||||
@@ -1217,14 +1212,19 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool
|
||||
}
|
||||
}
|
||||
|
||||
if(spellInfo_1->SpellFamilyName && IsRankSpellDueToSpell(spellInfo_1, spellId_2))
|
||||
return true;
|
||||
// not needed now because we compare effects last rank of spells
|
||||
// if(spellInfo_1->SpellFamilyName && IsRankSpellDueToSpell(spellInfo_1, spellId_2))
|
||||
// return true;
|
||||
|
||||
//use data of highest rank spell(needed for spells which ranks have different effects)
|
||||
SpellEntry const *spellInfo1=sSpellStore.LookupEntry(GetLastSpellInChain(spellId_1));
|
||||
SpellEntry const *spellInfo2=sSpellStore.LookupEntry(GetLastSpellInChain(spellId_2));
|
||||
|
||||
//if spells have exactly the same effect they cannot stack
|
||||
for(uint32 i = 0; i < 3; ++i)
|
||||
if(spellInfo_1->Effect[i] != spellInfo_2->Effect[i]
|
||||
|| spellInfo_1->EffectApplyAuraName[i] != spellInfo_2->EffectApplyAuraName[i]
|
||||
|| spellInfo_1->EffectMiscValue[i] != spellInfo_2->EffectMiscValue[i]) // paladin resist aura
|
||||
if(spellInfo1->Effect[i] != spellInfo2->Effect[i]
|
||||
|| spellInfo1->EffectApplyAuraName[i] != spellInfo2->EffectApplyAuraName[i]
|
||||
|| spellInfo1->EffectMiscValue[i] != spellInfo2->EffectMiscValue[i]) // paladin resist aura
|
||||
return false; // need itemtype check? need an example to add that check
|
||||
|
||||
return true;
|
||||
@@ -1305,9 +1305,18 @@ SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spell
|
||||
void SpellMgr::LoadSpellChains()
|
||||
{
|
||||
mSpellChains.clear(); // need for reload case
|
||||
mSpellChainsNext.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");
|
||||
|
||||
struct SpellChainEntry
|
||||
{
|
||||
uint32 spell;
|
||||
uint32 first;
|
||||
uint32 req;
|
||||
uint8 rank;
|
||||
};
|
||||
|
||||
QueryResult *result = WorldDatabase.Query("SELECT spell_id, prev_spell, first_spell, rank, req_spell FROM spell_chain");
|
||||
if(result == NULL)
|
||||
{
|
||||
barGoLink bar( 1 );
|
||||
@@ -1318,8 +1327,9 @@ void SpellMgr::LoadSpellChains()
|
||||
sLog.outErrorDb("`spell_chains` table is empty!");
|
||||
return;
|
||||
}
|
||||
uint32 rows = 0;
|
||||
|
||||
uint32 count = 0;
|
||||
SpellChainEntry *SpellChainTable = new SpellChainEntry [result->GetRowCount()];
|
||||
|
||||
barGoLink bar( result->GetRowCount() );
|
||||
do
|
||||
@@ -1327,13 +1337,65 @@ void SpellMgr::LoadSpellChains()
|
||||
bar.step();
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
uint32 spell_id = fields[0].GetUInt32();
|
||||
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));
|
||||
|
||||
++rows;
|
||||
} while( result->NextRow() );
|
||||
delete result;
|
||||
uint32 cur_row=0;
|
||||
do
|
||||
{
|
||||
uint32 spell_id=SpellChainTable[cur_row].spell;
|
||||
SpellChainNode node;
|
||||
node.prev = fields[1].GetUInt32();
|
||||
node.first = fields[2].GetUInt32();
|
||||
node.rank = fields[3].GetUInt8();
|
||||
node.req = fields[4].GetUInt32();
|
||||
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;
|
||||
|
||||
//get field "next"
|
||||
if (cur_row==rows-1 || SpellChainTable[cur_row+1].first!= node.first )
|
||||
{
|
||||
//get field "last"
|
||||
for (uint32 last_row=1;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;
|
||||
}
|
||||
|
||||
|
||||
cur_row++;
|
||||
|
||||
if(!sSpellStore.LookupEntry(spell_id))
|
||||
{
|
||||
@@ -1341,34 +1403,17 @@ void SpellMgr::LoadSpellChains()
|
||||
continue;
|
||||
}
|
||||
|
||||
if(node.prev!=0 && !sSpellStore.LookupEntry(node.prev))
|
||||
{
|
||||
sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has not existed previous rank spell.",
|
||||
spell_id,node.prev,node.first,node.rank,node.req);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!sSpellStore.LookupEntry(node.first))
|
||||
{
|
||||
sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has not existing first rank spell.",
|
||||
spell_id,node.prev,node.first,node.rank,node.req);
|
||||
continue;
|
||||
}
|
||||
|
||||
// check basic spell chain data integrity (note: rank can be equal 0 or 1 for first/single spell)
|
||||
if( (spell_id == node.first) != (node.rank <= 1) ||
|
||||
(spell_id == node.first) != (node.prev == 0) ||
|
||||
(node.rank <= 1) != (node.prev == 0) )
|
||||
{
|
||||
sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has not compatible chain data.",
|
||||
spell_id,node.prev,node.first,node.rank,node.req);
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(node.req!=0 && !sSpellStore.LookupEntry(node.req))
|
||||
{
|
||||
sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has not existing required spell.",
|
||||
spell_id,node.prev,node.first,node.rank,node.req);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1377,8 +1422,8 @@ void SpellMgr::LoadSpellChains()
|
||||
{
|
||||
if(node.rank!=pos->rank+1)
|
||||
{
|
||||
sLog.outErrorDb("Talent %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has wrong rank.",
|
||||
spell_id,node.prev,node.first,node.rank,node.req);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1386,8 +1431,8 @@ void SpellMgr::LoadSpellChains()
|
||||
{
|
||||
if(node.first!=talentEntry->RankID[0])
|
||||
{
|
||||
sLog.outErrorDb("Talent %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has wrong first rank spell.",
|
||||
spell_id,node.prev,node.first,node.rank,node.req);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1397,26 +1442,14 @@ void SpellMgr::LoadSpellChains()
|
||||
spell_id,node.prev,node.first,node.rank,node.req);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(node.req!=talentEntry->DependsOnSpell)
|
||||
{
|
||||
sLog.outErrorDb("Talent %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has wrong required spell.",
|
||||
spell_id,node.prev,node.first,node.rank,node.req);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mSpellChains[spell_id] = node;
|
||||
}
|
||||
while( cur_row<rows );
|
||||
|
||||
if(node.prev)
|
||||
mSpellChainsNext.insert(SpellChainMapNext::value_type(node.prev,spell_id));
|
||||
|
||||
if(node.req)
|
||||
mSpellChainsNext.insert(SpellChainMapNext::value_type(node.req,spell_id));
|
||||
|
||||
++count;
|
||||
} while( result->NextRow() );
|
||||
delete[] SpellChainTable;
|
||||
|
||||
// additional integrity checks
|
||||
for(SpellChainMap::iterator i = mSpellChains.begin(); i != mSpellChains.end(); ++i)
|
||||
@@ -1457,19 +1490,11 @@ void SpellMgr::LoadSpellChains()
|
||||
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);
|
||||
}
|
||||
else if( i_req->second.req )
|
||||
{
|
||||
sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has required rank spell with required spell (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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u spell chain records", count );
|
||||
sLog.outString( ">> Loaded %u spell chain records", rows );
|
||||
}
|
||||
|
||||
void SpellMgr::LoadSpellLearnSkills()
|
||||
|
||||
+8
-8
@@ -634,13 +634,15 @@ typedef std::map<uint16, PetAura> SpellPetAuraMap;
|
||||
struct SpellChainNode
|
||||
{
|
||||
uint32 prev;
|
||||
uint32 next;
|
||||
uint32 first;
|
||||
uint32 last;
|
||||
uint32 req;
|
||||
uint8 rank;
|
||||
};
|
||||
|
||||
typedef UNORDERED_MAP<uint32, SpellChainNode> SpellChainMap;
|
||||
typedef std::multimap<uint32, uint32> SpellChainMapNext;
|
||||
typedef std::multimap<uint32, uint32> SpellRequiredMap;
|
||||
|
||||
// Spell learning properties (accessed using SpellMgr functions)
|
||||
struct SpellLearnSkillNode
|
||||
@@ -781,7 +783,7 @@ class SpellMgr
|
||||
return 0;
|
||||
}
|
||||
|
||||
SpellChainMapNext const& GetSpellChainNext() const { return mSpellChainsNext; }
|
||||
SpellRequiredMap const& GetSpellRequiredMap() const { return mSpellReq; }
|
||||
|
||||
// Note: not use rank for compare to spell ranks: spell chains isn't linear order
|
||||
// Use IsHighRankOfSpell instead
|
||||
@@ -795,11 +797,9 @@ class SpellMgr
|
||||
|
||||
uint32 GetLastSpellInChain(uint32 spell_id) const
|
||||
{
|
||||
if (!GetSpellChainNode(spell_id))
|
||||
return spell_id;
|
||||
SpellChainMapNext const& nextMap = GetSpellChainNext();
|
||||
for(SpellChainMapNext::const_iterator itr = nextMap.lower_bound(spell_id); itr != nextMap.upper_bound(spell_id); ++itr)
|
||||
spell_id=itr->second;
|
||||
if(SpellChainNode const* node = GetSpellChainNode(spell_id))
|
||||
return node->last;
|
||||
|
||||
return spell_id;
|
||||
}
|
||||
|
||||
@@ -940,7 +940,7 @@ class SpellMgr
|
||||
private:
|
||||
SpellScriptTarget mSpellScriptTarget;
|
||||
SpellChainMap mSpellChains;
|
||||
SpellChainMapNext mSpellChainsNext;
|
||||
SpellRequiredMap mSpellReq;
|
||||
SpellLearnSkillMap mSpellLearnSkills;
|
||||
SpellLearnSpellMap mSpellLearnSpells;
|
||||
SpellTargetPositionMap mSpellTargetPositions;
|
||||
|
||||
Reference in New Issue
Block a user