diff options
Diffstat (limited to 'src/server/game/Spells/SpellMgr.cpp')
-rw-r--r-- | src/server/game/Spells/SpellMgr.cpp | 85 |
1 files changed, 77 insertions, 8 deletions
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 9cedfdf922f..b1613e8a8cd 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -1187,23 +1187,88 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32 return true; } -void SpellMgr::LoadSpellRanks() +void SpellMgr::UnloadSpellInfoChains() { - uint32 oldMSTime = getMSTime(); + for (SpellChainMap::iterator itr = mSpellChains.begin(); itr != mSpellChains.end(); ++itr) + mSpellInfoMap[itr->first]->ChainEntry = NULL; + + mSpellChains.clear(); +} +void SpellMgr::LoadSpellTalentRanks() +{ // cleanup core data before reload - remove reference to ChainNode from SpellInfo - for (SpellChainMap::iterator itr = mSpellChains.begin(); itr != mSpellChains.end(); ++itr) + UnloadSpellInfoChains(); + + for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i) { - mSpellInfoMap[itr->first]->ChainEntry = NULL; + TalentEntry const* talentInfo = sTalentStore.LookupEntry(i); + if (!talentInfo) + continue; + + SpellInfo const* lastSpell = NULL; + for (uint8 rank = MAX_TALENT_RANK - 1; rank > 0; --rank) + { + if (talentInfo->RankID[rank]) + { + lastSpell = GetSpellInfo(talentInfo->RankID[rank]); + break; + } + } + + if (!lastSpell) + continue; + + SpellInfo const* firstSpell = GetSpellInfo(talentInfo->RankID[0]); + if (!firstSpell) + { + TC_LOG_ERROR(LOG_FILTER_SPELLS_AURAS, "SpellMgr::LoadSpellTalentRanks: First Rank Spell %u for TalentEntry %u does not exist.", talentInfo->RankID[0], i); + continue; + } + + SpellInfo const* prevSpell = NULL; + for (uint8 rank = 0; rank < MAX_TALENT_RANK; ++rank) + { + uint32 spellId = talentInfo->RankID[rank]; + if (!spellId) + break; + + SpellInfo const* currentSpell = GetSpellInfo(spellId); + if (!currentSpell) + { + TC_LOG_ERROR(LOG_FILTER_SPELLS_AURAS, "SpellMgr::LoadSpellTalentRanks: Spell %u (Rank: %u) for TalentEntry %u does not exist.", spellId, rank + 1, i); + break; + } + + SpellChainNode node; + node.first = firstSpell; + node.last = lastSpell; + node.rank = rank + 1; + + node.prev = prevSpell; + node.next = node.rank < MAX_TALENT_RANK ? GetSpellInfo(talentInfo->RankID[rank + 1]) : NULL; + + mSpellChains[spellId] = node; + mSpellInfoMap[spellId]->ChainEntry = &mSpellChains[spellId]; + + prevSpell = currentSpell; + } } - mSpellChains.clear(); +} + +void SpellMgr::LoadSpellRanks() +{ + // cleanup data and load spell ranks for talents from dbc + LoadSpellTalentRanks(); + + uint32 oldMSTime = getMSTime(); + // 0 1 2 QueryResult result = WorldDatabase.Query("SELECT first_spell_id, spell_id, rank from spell_ranks ORDER BY first_spell_id, rank"); if (!result) { TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 spell rank records. DB table `spell_ranks` is empty."); - return; } @@ -1280,6 +1345,10 @@ void SpellMgr::LoadSpellRanks() { ++count; int32 addedSpell = itr->first; + + if (mSpellInfoMap[addedSpell]->ChainEntry) + TC_LOG_ERROR(LOG_FILTER_SQL, "Spell %u (rank: %u, first: %u) listed in `spell_ranks` has already ChainEntry from dbc.", addedSpell, itr->second, lastSpell); + mSpellChains[addedSpell].first = GetSpellInfo(lastSpell); mSpellChains[addedSpell].last = GetSpellInfo(rankChain.back().first); mSpellChains[addedSpell].rank = itr->second; @@ -1296,10 +1365,10 @@ void SpellMgr::LoadSpellRanks() mSpellChains[addedSpell].next = GetSpellInfo(itr->first); } while (true); - } while (!finished); + } + while (!finished); TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Loaded %u spell rank records in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); - } void SpellMgr::LoadSpellRequired() |