/// <summary> /// Get a list of the dependencies contained within a given logic string. Compound dependencies call this recursively /// </summary> /// <param name="logic">The logic string to parse</param> /// <returns>The list of dependencies contained in the logic</returns> public List <Dependency> GetDependencies(string logic) { List <Dependency> dependencies = new List <Dependency>(); List <string> subLogic = SplitDependencies(logic); foreach (string sequence in subLogic) { if (string.IsNullOrEmpty(sequence)) { continue; } switch (sequence[0]) { // If the first character of the string is & or |, it's a compound dependency // These are handled recursively, with the first character chopped off case '&': List <Dependency> andList = GetDependencies(sequence.Substring(1)); AndDependency andDependency = new AndDependency(andList); dependencies.Add(andDependency); break; case '|': List <Dependency> orList = GetDependencies(sequence.Substring(1)); OrDependency orDependency = new OrDependency(orList); dependencies.Add(orDependency); break; case '+': Dictionary <Dependency, int> valueDict = new Dictionary <Dependency, int>(); var reqValueString = sequence.Split(',')[0]; if (!StringUtil.ParseString(reqValueString.Substring(1), out int reqValue)) { throw new ParserException($"Invalid total for counter! {reqValueString.Substring(1)}"); } string[] depStrings = sequence.Substring(reqValueString.Length + 1).Split(','); foreach (var depString in depStrings) { string dependencyString = depString; int depValue = 1; string[] values = dependencyString.Split(':'); if (values.Length >= 3) { if (!StringUtil.ParseString(values[2], out depValue)) { depValue = 1; dependencyString = dependencyString.Substring(0, dependencyString.Length - (values[2].Length + 1)); } } List <Dependency> temp = GetDependencies(dependencyString); valueDict.Add(temp[0], depValue); } dependencies.Add(new CounterDependency(valueDict, reqValue)); break; default: string[] splitSequence = sequence.Split(':'); string requirement = splitSequence[0]; string dungeon = ""; int count = 1; if (splitSequence.Length >= 2) { dungeon = splitSequence[1]; if (splitSequence.Length >= 3) { if (!StringUtil.ParseString(splitSequence[2], out count)) { throw new ParserException($"Invalid amount on\"{sequence}\"!"); } } } string[] dependencyParts = requirement.Split('.'); if (dependencyParts.Length < 2) { throw new ParserException($"Invalid logic \"{logic}\"!"); } switch (dependencyParts[0]) { case "Locations": case "Helpers": LocationDependency locationDependency = new LocationDependency(dependencyParts[1]); dependencies.Add(locationDependency); break; case "Items": Item item = new Item(sequence, " Parse"); ItemDependency itemDependency = new ItemDependency(item, count); dependencies.Add(itemDependency); break; default: throw new ParserException($"\"{dependencyParts[0]}\" is not a valid dependency type!"); } break; } } return(dependencies); }
/// <summary> /// Get a list of the dependencies contained within a given logic string. Compound dependencies call this recursively /// </summary> /// <param name="logic">The logic string to parse</param> /// <returns>The list of dependencies contained in the logic</returns> public List <Dependency> GetDependencies(string logic) { List <Dependency> dependencies = new List <Dependency>(); List <string> subLogic = SplitDependencies(logic); foreach (string sequence in subLogic) { if (string.IsNullOrEmpty(sequence)) { continue; } switch (sequence[0]) { // If the first character of the string is & or |, it's a compound dependency // These are handled recursively, with the first character chopped off case '&': List <Dependency> andList = GetDependencies(sequence.Substring(1)); AndDependency andDependency = new AndDependency(andList); dependencies.Add(andDependency); break; case '|': List <Dependency> orList = GetDependencies(sequence.Substring(1)); OrDependency orDependency = new OrDependency(orList); dependencies.Add(orDependency); break; case '+': Dictionary <Item, int> valueDict = new Dictionary <Item, int>(); var reqValueString = sequence.Split(',')[0]; if (!int.TryParse(reqValueString.Substring(1), out int reqValue)) { throw new ParserException($"Invalid total for counter! {reqValueString.Substring(1)}"); } string[] itemStrings = sequence.Substring(reqValueString.Length + 1).Split(','); foreach (var itemString in itemStrings) { string dungeonval = ""; int itemval = 1; string[] values = itemString.Split(':'); if (values.Length >= 2) { dungeonval = values[1]; if (values.Length >= 3) { if (!int.TryParse(values[2], out itemval)) { itemval = 1; } } } var itemParts = values[0].Split('.'); ItemType type = ItemType.Untyped; if (!Enum.TryParse(itemParts[1], out type)) { throw new ParserException($"Could not parse item value! {itemParts[1]}"); } byte itemSub = 0; if (itemParts.Length >= 3) { if (!byte.TryParse(itemParts[2], out itemSub)) { throw new ParserException($"Could not parse item subvalue! {itemParts[2]}"); } } var item = new Item(type, itemSub, dungeonval); valueDict.Add(item, itemval); } dependencies.Add(new CounterDependency(valueDict, reqValue)); break; default: string[] splitSequence = sequence.Split(':'); string requirement = splitSequence[0]; string dungeon = ""; int count = 1; if (splitSequence.Length >= 2) { dungeon = splitSequence[1]; if (splitSequence.Length >= 3) { if (!int.TryParse(splitSequence[2], out count)) { count = 1; } } } string[] dependencyParts = requirement.Split('.'); if (dependencyParts.Length < 2) { break; } switch (dependencyParts[0]) { case "Locations": case "Helpers": LocationDependency locationDependency = new LocationDependency(dependencyParts[1]); dependencies.Add(locationDependency); break; case "Items": if (Enum.TryParse(dependencyParts[1], out ItemType type)) { byte subType = 0; if (dependencyParts.Length >= 3) { if (!byte.TryParse(dependencyParts[2], NumberStyles.HexNumber, null, out subType)) { if (Enum.TryParse(dependencyParts[2], out KinstoneType subKinstoneType)) { subType = (byte)subKinstoneType; } } } ItemDependency itemDependency = new ItemDependency(new Item(type, subType, dungeon), count); dependencies.Add(itemDependency); } else { throw new ParserException($"Item {dependencyParts[1]} could not be found!"); } break; default: throw new ParserException($"\"{dependencyParts[0]}\" is not a valid dependency type!"); } break; } } return(dependencies); }