Ejemplo n.º 1
0
        public void Run(ModData modData, string[] args)
        {
            // HACK: The engine code assumes that Game.modData is set.
            Game.ModData = modData;
            GlobalFileSystem.LoadFromManifest(Game.ModData.Manifest);

            var imageField             = typeof(TerrainTemplateInfo).GetField("Image");
            var pickAnyField           = typeof(TerrainTemplateInfo).GetField("PickAny");
            var tileInfoField          = typeof(TerrainTemplateInfo).GetField("tileInfo", BindingFlags.NonPublic | BindingFlags.Instance);
            var terrainTypeField       = typeof(TerrainTileInfo).GetField("TerrainType");
            var terrainLeftColorField  = typeof(TerrainTileInfo).GetField("LeftColor");
            var terrainRightColorField = typeof(TerrainTileInfo).GetField("RightColor");
            var empty = new Size(0, 0);
            var single = new int2(1, 1);
            var exts = new[] { "" }.Concat(args[1].Split(','));

            foreach (var t in Game.ModData.Manifest.TileSets)
            {
                var ts         = new TileSet(Game.ModData, t);
                var frameCache = new FrameCache(Game.ModData.SpriteLoaders);

                Console.WriteLine("Tileset: " + ts.Name);
                foreach (var template in ts.Templates.Values)
                {
                    // Find the sprite associated with this template
                    foreach (var ext in exts)
                    {
                        Stream s;
                        if (!GlobalFileSystem.TryOpen(template.Images[0] + ext, out s))
                        {
                            continue;
                        }

                        // Rewrite the template image (normally readonly) using reflection
                        imageField.SetValue(template, template.Images[0] + ext);

                        // Fetch the private tileInfo array so that we can write new entries
                        var tileInfo = (TerrainTileInfo[])tileInfoField.GetValue(template);

                        // Open the file and search for any implicit frames
                        var allFrames = frameCache[template.Images[0]];
                        var frames    = template.Frames != null?template.Frames.Select(f => allFrames[f]).ToArray() : allFrames;

                        // Resize array for new entries
                        if (frames.Length > template.TilesCount)
                        {
                            var ti = new TerrainTileInfo[frames.Length];
                            Array.Copy(tileInfo, ti, template.TilesCount);
                            tileInfoField.SetValue(template, ti);
                            tileInfo = ti;
                        }

                        for (var i = 0; i < template.TilesCount; i++)
                        {
                            if (template[i] == null && frames[i] != null && frames[i].Size != empty)
                            {
                                tileInfo[i] = new TerrainTileInfo();
                                var ti = ts.GetTerrainIndex("Clear");
                                terrainTypeField.SetValue(tileInfo[i], ti);
                                terrainLeftColorField.SetValue(tileInfo[i], ts[ti].Color);
                                terrainRightColorField.SetValue(tileInfo[i], ts[ti].Color);
                                Console.WriteLine("Fixing entry for {0}:{1}", template.Images[0], i);
                            }
                        }

                        if (template.TilesCount > 1 && template.Size == single)
                        {
                            pickAnyField.SetValue(template, true);
                        }

                        s.Dispose();
                    }
                }

                ts.Save(t);
            }
        }