Beispiel #1
0
            public void SetDefaultItems()
            {
                ItemsIncluded = true;
                items.Clear();
                var pokemonTable = model.GetTable(HardcodeTablesModel.PokemonStatsTable);

                items.AddRange(pokemons.Select(p => pokemonTable?.ReadValue(model, p, "item1") ?? 0));
            }
Beispiel #2
0
        public static ErrorInfo RefactorMoveByteFieldInTable(ThumbParser parser, IDataModel model, ModelDelta token, string tableName, string fieldName, int newOffset)
        {
            // setup
            var table = model.GetTable(tableName) as ArrayRun;

            if (table == null)
            {
                return(new ErrorInfo($"Couldn't find table {tableName}."));
            }
            var segToMove = table.ElementContent.FirstOrDefault(seg => seg.Name == fieldName);

            if (segToMove == null)
            {
                return(new ErrorInfo($"Couldn't find field {fieldName} in {tableName}."));
            }
            if (segToMove.Length != 1)
            {
                return(new ErrorInfo($"{fieldName} must be a 1-byte field to refactor."));
            }
            if (newOffset >= table.ElementLength)
            {
                return(new ErrorInfo($"Trying to move {fieldName} to offset {newOffset}, but the table is only {table.ElementLength} bytes wide."));
            }
            var oldFieldIndex   = table.ElementContent.IndexOf(segToMove);
            var newFieldIndex   = 0;
            var remainingOffset = newOffset;

            while (remainingOffset > 0)
            {
                remainingOffset -= table.ElementContent[newFieldIndex].Length;
                newFieldIndex   += 1;
            }
            var segToReplace = table.ElementContent[newFieldIndex];

            if (segToReplace.Length != 1)
            {
                return(new ErrorInfo($"{segToReplace.Name} must be a 1-byte field to be replaced."));
            }
            int oldOffset = table.ElementContent.Until(seg => seg == segToMove).Sum(seg => seg.Length);

            // update table format
            var format = table.FormatString;

            format = format.ReplaceOne(segToMove.SerializeFormat, "#invalidtabletoken#");
            format = format.ReplaceOne(segToReplace.SerializeFormat, segToMove.SerializeFormat);
            format = format.ReplaceOne("#invalidtabletoken#", segToReplace.SerializeFormat);
            var error = ArrayRun.TryParse(model, format, table.Start, table.PointerSources, out var newTable);

            if (error.HasError)
            {
                return(new ErrorInfo($"Failed to create a table from new format {format}: {error.ErrorMessage}."));
            }

            // update code
            var ldrbWriter = new TupleSegment(default, 5);
        public static int ParseValue(IDataModel model, ITableRun table, int elementIndex, string content)
        {
            if (string.IsNullOrEmpty(content))
            {
                return(0);
            }
            if (int.TryParse(content, out int simpleValue))
            {
                return(simpleValue);
            }
            if (content == "last")
            {
                return(table.ElementCount - 1);
            }

            if (table != null && table.ElementContent.Any(seg => seg.Name == content))
            {
                return(table.ReadValue(model, elementIndex, content));
            }

            if (content.MatchesPartial("(/=)/"))
            {
                var parts   = content.Split("(/=)".ToCharArray());
                var message = $"Expected {content} to fit the form (table/field=local)/field. But it didn't.";
                if (parts.Length != 6)
                {
                    throw new NotImplementedException(message);
                }
                if (!string.IsNullOrEmpty(parts[0]) || !string.IsNullOrEmpty(parts[4]))
                {
                    throw new NotImplementedException(message);
                }
                var matchTableName  = parts[1];
                var matchTableField = parts[2];
                var matchLocalField = parts[3];
                var localFieldValue = ParseValue(model, table, elementIndex, matchLocalField);
                var valueField      = parts[5];
                var matchTable      = model.GetTable(matchTableName);
                if (matchTable == null)
                {
                    return(0);
                }
                for (int i = 0; i < matchTable.ElementCount; i++)
                {
                    if (matchTable.ReadValue(model, i, matchTableField) != localFieldValue)
                    {
                        continue;
                    }
                    return(ParseValue(model, matchTable, i, valueField));
                }
                return(ParseValue(model, matchTable, matchTable.ElementCount - 1, valueField));
            }
            if (content.MatchesPartial("//"))
            {
                var parts   = content.Split("/");
                var message = $"Expected {content} to fit the form field/index/field. But it didn't.";
                if (parts.Length != 3)
                {
                    throw new NotImplementedException(message);
                }
                var destination = table.ReadPointer(model, elementIndex, parts[0]);
                if (destination == Pointer.NULL)
                {
                    return(0);
                }
                var childTable = model.GetNextRun(destination) as ITableRun;
                if (childTable == null)
                {
                    throw new NotImplementedException(message);
                }
                var childTableIndex = ParseValue(model, childTable, elementIndex, parts[1]);
                return(ParseValue(model, childTable, childTableIndex, parts[2]));
            }

            throw new NotImplementedException();
        }