public void Run(Utility utility, string[] args) { // HACK: The engine code assumes that Game.modData is set. Game.ModData = utility.ModData; var filename = args[1]; var file = new IniFile(File.Open(args[1], FileMode.Open)); var basic = file.GetSection("Basic"); var mapSection = file.GetSection("Map"); var tileset = mapSection.GetValue("Theater", ""); var iniSize = mapSection.GetValue("Size", "0, 0, 0, 0").Split(',').Select(int.Parse).ToArray(); var iniBounds = mapSection.GetValue("LocalSize", "0, 0, 0, 0").Split(',').Select(int.Parse).ToArray(); var size = new Size(iniSize[2], 2 * iniSize[3]); var map = new Map(Game.ModData, utility.ModData.DefaultTileSets[tileset], size.Width, size.Height) { Title = basic.GetValue("Name", Path.GetFileNameWithoutExtension(filename)), Author = "Westwood Studios", Bounds = new Rectangle(iniBounds[0], iniBounds[1], iniBounds[2], 2 * iniBounds[3] + 2 * iniBounds[1]), RequiresMod = utility.ModData.Manifest.Id }; var fullSize = new int2(iniSize[2], iniSize[3]); ReadTiles(map, file, fullSize); ReadActors(map, file, "Structures", fullSize); ReadActors(map, file, "Units", fullSize); ReadActors(map, file, "Infantry", fullSize); ReadTerrainActors(map, file, fullSize); ReadWaypoints(map, file, fullSize); ReadOverlay(map, file, fullSize); ReadLighting(map, file); var spawnCount = map.ActorDefinitions.Count(n => n.Value.Value == "mpspawn"); var mapPlayers = new MapPlayers(map.Rules, spawnCount); map.PlayerDefinitions = mapPlayers.ToMiniYaml(); var dest = Path.GetFileNameWithoutExtension(args[1]) + ".oramap"; map.Save(ZipFileLoader.Create(dest)); Console.WriteLine(dest + " saved."); }
static void ReadOverlay(Map map, IniFile file, int2 fullSize) { var overlaySection = file.GetSection("OverlayPack"); var overlayCompressed = Convert.FromBase64String(string.Concat(overlaySection.Select(kvp => kvp.Value))); var overlayPack = new byte[1 << 18]; var temp = new byte[1 << 18]; UnpackLCW(overlayCompressed, overlayPack, temp); var overlayDataSection = file.GetSection("OverlayDataPack"); var overlayDataCompressed = Convert.FromBase64String(string.Concat(overlayDataSection.Select(kvp => kvp.Value))); var overlayDataPack = new byte[1 << 18]; UnpackLCW(overlayDataCompressed, overlayDataPack, temp); var overlayIndex = new CellLayer <int>(map); overlayIndex.Clear(0xFF); for (var y = 0; y < fullSize.Y; y++) { for (var x = fullSize.X * 2 - 2; x >= 0; x--) { var dx = (ushort)x; var dy = (ushort)(y * 2 + x % 2); var uv = new MPos(dx / 2, dy); var rx = (ushort)((dx + dy) / 2 + 1); var ry = (ushort)(dy - rx + fullSize.X + 1); if (!map.Resources.Contains(uv)) { continue; } overlayIndex[uv] = rx + 512 * ry; } } foreach (var cell in map.AllCells) { var overlayType = overlayPack[overlayIndex[cell]]; if (overlayType == 0xFF) { continue; } string actorType; if (OverlayToActor.TryGetValue(overlayType, out actorType)) { if (string.IsNullOrEmpty(actorType)) { continue; } var shape = new Size(1, 1); if (OverlayShapes.TryGetValue(overlayType, out shape)) { // Only import the top-left cell of multi-celled overlays var aboveType = overlayPack[overlayIndex[cell - new CVec(1, 0)]]; if (shape.Width > 1 && aboveType != 0xFF) { string a; if (OverlayToActor.TryGetValue(aboveType, out a) && a == actorType) { continue; } } var leftType = overlayPack[overlayIndex[cell - new CVec(0, 1)]]; if (shape.Height > 1 && leftType != 0xFF) { string a; if (OverlayToActor.TryGetValue(leftType, out a) && a == actorType) { continue; } } } var ar = new ActorReference(actorType) { new LocationInit(cell), new OwnerInit("Neutral") }; DamageState damageState; if (OverlayToHealth.TryGetValue(overlayType, out damageState)) { var health = 100; if (damageState == DamageState.Critical) { health = 25; } else if (damageState == DamageState.Heavy) { health = 50; } else if (damageState == DamageState.Medium) { health = 75; } if (health != 100) { ar.Add(new HealthInit(health)); } } map.ActorDefinitions.Add(new MiniYamlNode("Actor" + map.ActorDefinitions.Count, ar.Save())); continue; } var resourceType = ResourceFromOverlay .Where(kv => kv.Value.Contains(overlayType)) .Select(kv => kv.Key) .FirstOrDefault(); if (resourceType != 0) { map.Resources[cell] = new ResourceTile(resourceType, overlayDataPack[overlayIndex[cell]]); continue; } Console.WriteLine("{0} unknown overlay {1}", cell, overlayType); } }