public void LoadSpellRanks() { // cleanup core data before reload - remove reference to ChainNode from SpellInfo foreach (var chain in SpellChainList) { SpellInfoList[chain.Key].ChainEntry = new SpellChainNode(); } SpellChainList.Clear(); SQLResult result = DB.World.Select("SELECT first_spell_id, spell_id, rank from spell_ranks ORDER BY first_spell_id, rank"); if (result.Count == 0) { Log.outError("Loaded 0 spell rank records. DB table `spell_ranks` is empty."); return; } bool finished = false; int i = 0; int count = 0; do { List <Tuple <uint, uint> > rankChain = new List <Tuple <uint, uint> >(); int currentSpell = -1; int lastSpell = -1; while (currentSpell == lastSpell && !finished) { currentSpell = result.Read <int>(i, 0); if (lastSpell == -1) { lastSpell = currentSpell; } uint spell_id = result.Read <uint>(i, 1); uint rank = result.Read <uint>(i, 2); // don't drop the row if we're moving to the next rank if (currentSpell == lastSpell) { rankChain.Add(new Tuple <uint, uint>(spell_id, rank)); if (i == result.Count - 1) { finished = true; } } else { break; } i++; } // check if chain is made with valid first spell SpellInfo first = GetSpellInfo((uint)lastSpell); if (first.Id == 0) { Log.outError("Spell rank identifier(first_spell_id) {0} listed in `spell_ranks` does not exist!", lastSpell); continue; } // check if chain is long enough if (rankChain.Count < 2) { Log.outError("There is only 1 spell rank for identifier(first_spell_id) {0} in `spell_ranks`, entry is not needed!", lastSpell); continue; } int curRank = 0; bool valid = true; // check spells in chain foreach (var chain in rankChain) { SpellInfo spell = GetSpellInfo(chain.Item1); if (spell.Id == 0) { Log.outError("Spell {0} (rank {1}) listed in `spell_ranks` for chain {2}%u does not exist!", chain.Item1, chain.Item2, lastSpell); valid = false; break; } ++curRank; if (chain.Item2 != curRank) { Log.outError("Spell {0} (rank {1}) listed in `spell_ranks` for chain {2} does not have proper rank value(should be {3})!", chain.Item1, chain.Item2, lastSpell, curRank); valid = false; break; } } if (!valid) { continue; } int prevRank = 0; // insert the chain for (var b = 0; b < rankChain.Count; b++) { count++; uint addedSpell = rankChain[b].Item1; SpellChainNode node = new SpellChainNode() { first = (uint)lastSpell, rank = (byte)rankChain[b].Item2, prev = (uint)prevRank, }; if (b != 0) { node.last = rankChain[b - 1].Item1; } prevRank = (int)addedSpell; if (b == rankChain.Count - 1) { node.next = 0; break; } else { node.next = rankChain[b].Item1; } SpellChainList.Add(addedSpell, node); SpellInfoList[addedSpell].ChainEntry = node; } } while (!finished); Log.outInfo("Loaded {0} spell rank records", count); Log.outInit(); }
public SpellChainNode GetSpellChainNode(uint spell_id) { return(SpellChainList.LookupByKey(spell_id)); }