예제 #1
0
 protected override BaseRun Clone(SortedSpan <int> newPointerSources) => new BSERun(Start, newPointerSources);
예제 #2
0
 protected override BaseRun Clone(SortedSpan <int> newPointerSources)
 {
     return(new MapListRun(Model, Start, newPointerSources));
 }
예제 #3
0
 protected override BaseRun Clone(SortedSpan <int> newPointerSources)
 {
     return(new PointerRun(Start, newPointerSources));
 }
 public ITableRun Duplicate(int start, SortedSpan <int> pointerSources, IReadOnlyList <ArrayRunElementSegment> segments)
 {
     return(new MapAnimationTilesRun(model, start, pointerSources));
 }
예제 #5
0
        private TrainerPokemonTeamRun(IDataModel model, int start, bool showFullIVByteRange, SortedSpan <int> sources, int primarySource) : base(start, sources)
        {
            this.model = model;
            this.showFullIVByteRange = showFullIVByteRange;
            StructType   = model[primarySource - TrainerFormat_PointerOffset];
            ElementCount = model[primarySource - TrainerFormat_PointerOffset + TrainerFormat_PokemonCountOffset];
            var segments = Initialize();

            ElementContent = segments;
            ElementLength  = ElementContent.Sum(segment => segment.Length);
        }
예제 #6
0
 protected override BaseRun Clone(SortedSpan <int> newPointerSources) => new PLMRun(model, Start, newPointerSources);
예제 #7
0
 protected override BaseRun Clone(SortedSpan <int> newPointerSources) => new LzPaletteRun(PaletteFormat, Model, Start, newPointerSources);
예제 #8
0
 public ITableRun Duplicate(int start, SortedSpan <int> pointerSources, IReadOnlyList <ArrayRunElementSegment> segments) => new TrainerPokemonTeamRun(model, start, showFullIVByteRange, pointerSources);
예제 #9
0
 protected override BaseRun Clone(SortedSpan <int> newPointerSources) => new LZRun(Model, Start, AllowLengthErrors, newPointerSources);
예제 #10
0
 public PagedLZRun(IDataModel data, int start, bool allowLengthErrors = false, SortedSpan <int> sources = null) : base(data, start, allowLengthErrors, sources)
 {
 }
예제 #11
0
        public OverworldSpriteListRun(IDataModel model, IReadOnlyList <ArrayRunElementSegment> parent, string paletteHint, int runIndex, int start, SortedSpan <int> sources = null) : base(start, sources)
        {
            this.model  = model;
            this.parent = parent;
            PaletteHint = paletteHint;
            RunIndex    = runIndex;

            var nextStartBuilder = new List <int>();
            int parentLength     = parent.Sum(seg => seg.Length);

            if (parent != null && sources != null && sources.Count > 0)
            {
                for (int nextSource = sources[0] + parentLength; true; nextSource += parentLength)
                {
                    var nextDest = model.ReadPointer(nextSource);
                    if (nextDest < 0 || nextDest >= model.Count)
                    {
                        break;
                    }
                    nextStartBuilder.Add(nextDest);
                }
            }
            var nextStart = nextStartBuilder.ToArray();

            var segments = new List <ArrayRunElementSegment> {
                new ArrayRunPointerSegment(model.FormatRunFactory, "sprite", "`ucs4x1x2`"),
                new ArrayRunElementSegment("length", ElementContentType.Integer, 2),
                new ArrayRunElementSegment("unused", ElementContentType.Integer, 2),
            };

            ElementContent = segments;
            ElementCount   = 1;
            Length         = ElementLength;
            SpriteFormat   = new SpriteFormat(4, 1, 1, string.Empty);

            if (sources == null || sources.Count == 0)
            {
                return;
            }

            // initialize format from parent info
            var listOffset   = GetOffset <ArrayRunPointerSegment>(parent, pSeg => pSeg.InnerFormat.StartsWith("`osl"));
            var widthOffset  = GetOffset(parent, seg => seg.Name == "width");
            var heightOffset = GetOffset(parent, seg => seg.Name == "height");
            var keyOffset    = GetOffset(parent, seg => seg.Name == "paletteid");

            if (widthOffset == parentLength)
            {
                widthOffset = -1;
            }
            if (heightOffset == parentLength)
            {
                heightOffset = -1;
            }
            if (keyOffset == parentLength)
            {
                keyOffset = -1;
            }

            var elementStart = sources[0] - listOffset;
            var width        = widthOffset >= 0 ? Math.Max(1, model.ReadMultiByteValue(elementStart + widthOffset, 2)) : 0;
            var height       = heightOffset >= 0 ? Math.Max(1, model.ReadMultiByteValue(elementStart + heightOffset, 2)) : 0;
            // if there was no height/width found, assume that it's square and based on the first element length
            var  pixelCount       = model.ReadMultiByteValue(start + 4, 4) * 2; // number of pixels is twice the number of bytes for all OW sprites
            bool adjustDimensions = true;

            if (width == 0)
            {
                width = (int)Math.Sqrt(pixelCount); adjustDimensions = true;
            }
            if (height == 0)
            {
                height = width; adjustDimensions = true;
            }
            var tileWidth  = (int)Math.Max(1, Math.Ceiling(width / 8.0));
            var tileHeight = (int)Math.Max(1, Math.Ceiling(height / 8.0));

            while (adjustDimensions && pixelCount > 0)
            {
                adjustDimensions = false;
                while (tileWidth * tileHeight * 64 > pixelCount)
                {
                    adjustDimensions = true;
                    tileHeight      -= 1;
                }
                if (tileHeight == 0)
                {
                    break;
                }
                while (tileWidth * tileHeight * 64 < pixelCount)
                {
                    if (tileWidth > 500)
                    {
                        break;
                    }
                    adjustDimensions = true;
                    tileWidth       += 1;
                }
            }

            var key  = model.ReadMultiByteValue(elementStart + keyOffset, 2);
            var hint = $"{HardcodeTablesModel.OverworldPalettes}:id={key:X4}";

            if (!string.IsNullOrEmpty(paletteHint))
            {
                hint = PaletteHint + $"={runIndex:X4}";
            }
            if (paletteHint != null && paletteHint.Contains("="))
            {
                hint = PaletteHint + $"{key:X4}";
            }

            var format = $"`ucs4x{tileWidth}x{tileHeight}|{hint}`";

            if (keyOffset == -1 && string.IsNullOrEmpty(paletteHint))
            {
                format = $"`ucs4x{tileWidth}x{tileHeight}`";
                hint   = string.Empty;
            }
            segments[0] = new ArrayRunPointerSegment(model.FormatRunFactory, "sprite", format);

            // calculate the element count
            var byteLength      = tileWidth * tileHeight * TileSize;
            var nextAnchorStart = model.GetNextAnchor(Start + 1).Start;

            ElementCount = 0;
            Length       = 0;
            while (Start + Length < nextAnchorStart)
            {
                var destination = model.ReadPointer(start + Length);
                if (destination < 0 || destination >= model.Count)
                {
                    break;
                }
                if (model.ReadMultiByteValue(start + Length + 4, 4) != byteLength)
                {
                    break;
                }
                var nextRun = model.GetNextRun(start + Length);
                if (Length > 0 && (start + Length).IsAny(nextStart))
                {
                    break;                                              // metric: if there's a pointer in the parent table that points here, then it's the next list, not this list.
                }
                ElementCount += 1;
                Length       += ElementLength;
                if (ElementCount == MaxOverworldSprites)
                {
                    break;                                  // overworld sprite lists can only have so many elements
                }
            }

            SpriteFormat = new SpriteFormat(4, tileWidth, tileHeight, hint);
            ElementNames = ElementCount.Range().Select(i => string.Empty).ToList();
        }
예제 #12
0
 public ITableRun Duplicate(int start, SortedSpan <int> pointerSources, IReadOnlyList <ArrayRunElementSegment> segments) => throw new NotImplementedException();
예제 #13
0
 protected override BaseRun Clone(SortedSpan <int> newPointerSources) => new OverworldSpriteListRun(model, parent, PaletteHint, RunIndex, Start, newPointerSources);
예제 #14
0
 protected override BaseRun Clone(SortedSpan <int> newPointerSources) => new TableStreamRun(model, Start, newPointerSources, FormatString, ElementContent, endStream);
예제 #15
0
 public override IFormattedRun WriteNewRun(IDataModel owner, ModelDelta token, int source, int destination, string name, IReadOnlyList <ArrayRunElementSegment> sourceSegments)
 {
     return(new MetatileRun(owner, destination, SortedSpan.One(source)));
 }
예제 #16
0
 protected override BaseRun Clone(SortedSpan <int> newPointerSources) => new TrainerPokemonTeamRun(model, Start, showFullIVByteRange, newPointerSources);
예제 #17
0
 public BaseRun(int start, SortedSpan <int> sources = null)
 {
     Start          = start;
     PointerSources = sources;
 }
예제 #18
0
        public TrainerPokemonTeamRun(IDataModel model, int start, bool showFullIVByteRange, SortedSpan <int> sources) : base(start, sources)
        {
            this.model = model;
            this.showFullIVByteRange = showFullIVByteRange;

            // trainer format (abbreviated):
            //     0           1       2         3        4-15     16     18      20     22       24          28       32         36          40 total
            // [structType. class. introMusic. sprite. name\"\"12 item1: item2: item3: item4: doubleBattle:: ai:: pokemonCount:: pokemon<>]
            StructType   = 0;
            ElementCount = 1;
            foreach (var source in sources)
            {
                if (!(model.GetNextRun(source) is ITableRun))
                {
                    continue;
                }
                StructType   = model[source - TrainerFormat_PointerOffset];
                ElementCount = model.ReadMultiByteValue(source - TrainerFormat_PointerOffset + TrainerFormat_PokemonCountOffset, 4);
                break;
            }

            var segments = Initialize();

            ElementContent = segments;
            ElementLength  = ElementContent.Sum(segment => segment.Length);
        }
예제 #19
0
 protected abstract BaseRun Clone(SortedSpan <int> newPointerSources);
예제 #20
0
 public AsciiRun(IDataModel model, int start, int length, SortedSpan <int> pointerSources = null) : base(start, pointerSources) => (this.model, Length) = (model, length);
예제 #21
0
 public NoInfoRun(int start, SortedSpan <int> sources = null) : base(start, sources)
 {
 }
예제 #22
0
 public PointerRun(int start, SortedSpan <int> sources = null) : base(start, sources)
 {
 }
예제 #23
0
 public OffsetPointerRun(int start, int offset, SortedSpan <int> sources = null) : base(start, sources) => Offset = offset;
 protected override BaseRun Clone(SortedSpan <int> newPointerSources) => new MapAnimationTilesRun(model, Start, newPointerSources);
예제 #25
0
 protected override BaseRun Clone(SortedSpan <int> newPointerSources) => new LzTilesetRun(Format, Model, Start, newPointerSources);
예제 #26
0
 public AsciiRun(int start, int length, SortedSpan <int> pointerSources = null) : base(start, pointerSources) => Length = length;
예제 #27
0
 public PCSRun(IDataModel model, int start, int length, SortedSpan <int> sources = null) : base(start, sources) => (this.model, Length) = (model, length);