public void ImportTree(string fileName, int memory) { byte[] serializedInput = File.ReadAllBytes(fileName); LevelIndex = new SortedDictionary <int, Node> [Controller.MAX_LEVEL]; for (int l = 0; l < LevelIndex.Length; l++) { LevelIndex[l] = new SortedDictionary <int, Node>(); } RootNode = null; bool skipAhead = memory > 0; for (int i = 0; i < serializedInput.Length;) { Node node = new Node(); node.Level = serializedInput[i]; node.HP = BitConverter.ToUInt16(serializedInput, i + 1); node.MP = BitConverter.ToUInt16(serializedInput, i + 3); if (skipAhead && memory / 10000000 < node.Level) { skipAhead = false; } if (!skipAhead || memory == node.Level * 10000000 + node.HP * 1000 + node.MP) { node.ChildNodes = new List <NodeLink>(); LevelIndex[node.Level - 1].Add(node.HP * 1000 + node.MP, node); if (RootNode == null) { RootNode = node; } } i += 5; if (i < serializedInput.Length) { if (serializedInput[i] == Controller.IO_LISTSTART) { i++; node.ParentNodes = new List <NodeLink>(); do { Node parentNode; if (LevelIndex[node.Level - 2].TryGetValue(BitConverter.ToUInt16(serializedInput, i + 3) * 1000 + BitConverter.ToUInt16(serializedInput, i + 5), out parentNode)) { NodeLink link = new NodeLink(parentNode, node, serializedInput[i], serializedInput[i + 1], serializedInput[i + 2]); node.ParentNodes.Add(link); bool found = false; foreach (NodeLink child in parentNode.ChildNodes) { if (child.Child.HP == node.HP && child.Child.MP == node.MP) { found = true; break; } } if (!found) { parentNode.ChildNodes.Add(link); } } i += 7; }while (serializedInput[i] != Controller.IO_LISTEND); i++; } } } }
public void AddLevelDepthFirst(Node parent) { if (parent.Level >= Controller.MAX_LEVEL) { return; } byte level = (byte)(parent.Level + 1); HPMPGradientBase table = Character.GetTable(level); short hpDiffBase = (short)((short)(100 * (table.HP_BASE + (level - 1) * table.HP_GRADIENT) / parent.HP) - 100), mpDiffBase = (short)((short)(100 * (table.MP_BASE + (short)((level - 1) * table.MP_GRADIENT / 10)) / parent.MP) - 100); ushort[] hps = new ushort[Controller.RNG_LIST.GetLength(0)], mps = new ushort[Controller.RNG_LIST.GetLength(1)]; for (int h = 0; h < hps.Length; h++) { hps[h] = (ushort)Math.Min(parent.HP + (ushort)(table.HP_GRADIENT * Controller.HP_GAIN[Math.Min(Math.Max((int)((h + 1) + hpDiffBase), 0), 11)] / 100), 9999); } for (int m = 0; m < mps.Length; m++) { mps[m] = (ushort)Math.Min(parent.MP + (ushort)((((ushort)(level * table.MP_GRADIENT / 10) - (ushort)((level - 1) * table.MP_GRADIENT / 10)) * Controller.MP_GAIN[Math.Min(Math.Max((int)((m + 1) + mpDiffBase), 0), 11)]) / 100), 999); } byte[,] overallProb = new byte[hps.Length, mps.Length]; Dictionary <int, ushort> probs = new Dictionary <int, ushort>(); for (int h = 0; h < Controller.RNG_LIST.GetLength(0); h++) { for (int m = 0; m < Controller.RNG_LIST.GetLength(1); m++) { if (!probs.ContainsKey(hps[h] * 1000 + mps[m])) { probs.Add(hps[h] * 1000 + mps[m], 0); } } } for (int h = 0; h < Controller.RNG_LIST.GetLength(0); h++) { for (int m = 0; m < Controller.RNG_LIST.GetLength(1); m++) { probs[hps[h] * 1000 + mps[m]] += Controller.RNG_LIST[h, m]; } } for (int h = 0; h < Controller.RNG_LIST.GetLength(0); h++) { for (int m = 0; m < Controller.RNG_LIST.GetLength(1); m++) { if (Controller.RNG_LIST[h, m] > 0) { ushort prob = probs[hps[h] * 1000 + mps[m]]; if (prob == 256) { //if 100% chance, store value as 255, which is byte max //since no paths can have a 255/256 chance, this special case of 255 will later be converted to 256 prob--; } overallProb[h, m] = (byte)prob; } } } for (int h = 0; h < hps.Length; h++) { for (int m = 0; m < mps.Length; m++) { if (overallProb[h, m] > 0) { //search in local nodes bool found = false; foreach (NodeLink child in parent.ChildNodes) { if (child.Child != null) { if (child.Child.HP == hps[h] && child.Child.MP == mps[m]) { //TODO: Possibly in the future add this HPRNG AND MPRNG (h + 1 & m + 1) to the NodeLink found = true; break; } } } if (!found) { //search in global nodes found = false; Node n; if (LevelIndex[level - 1].TryGetValue(hps[h] * 1000 + mps[m], out n)) { if (n != null) { NodeLink link = new NodeLink(parent, n, (byte)(h + 1), (byte)(m + 1), overallProb[h, m]); parent.ChildNodes.Add(link); n.ParentNodes.Add(link); found = true; } } if (!found) { Node node = new Node(); node.Level = level; node.HP = hps[h]; node.MP = mps[m]; node.ParentNodes = new List <NodeLink>(); node.ChildNodes = new List <NodeLink>(); NodeLink link = new NodeLink(parent, node, (byte)(h + 1), (byte)(m + 1), overallProb[h, m]); parent.ChildNodes.Add(link); node.ParentNodes.Add(link); LevelIndex[node.Level - 1].Add(node.HP * 1000 + node.MP, node); AddLevelDepthFirst(node); } } } } } if (level == Controller.MAX_LEVEL) { for (int n = 0; n < parent.ChildNodes.Count; n++) { if (parent.ChildNodes[n] != null) { if (parent.ChildNodes[n].Child.HP > Character.HPMax) { //HP has new MAX!!! level = level; } else if (parent.ChildNodes[n].Child.MP > Character.MPMaxAbs) { //MP has new MAX!!! level = level; } else if (parent.ChildNodes[n].Child.HP >= Character.HPMax && parent.ChildNodes[n].Child.MP > Character.MPMax) { //MP has new combined MAX!!! level = level; } else if (parent.ChildNodes[n].Child.HP >= Character.HPMax && parent.ChildNodes[n].Child.MP >= Character.MPMax) { //Found the usual MAX level = level; } } } } }