예제 #1
0
파일: Parser.cs 프로젝트: Rylux/randomizer
        /// <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);
        }
예제 #2
0
        /// <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);
        }