void Initialize(string mapFile)
        {
            mapSize = new Size(stream.ReadUInt16(), stream.ReadUInt16());

            tileSet = Game.ModData.DefaultTileSets["ARRAKIS"];

            map = new Map(Game.ModData, tileSet, mapSize.Width + 2 * MapCordonWidth, mapSize.Height + 2 * MapCordonWidth)
            {
                Title  = Path.GetFileNameWithoutExtension(mapFile),
                Author = "Westwood Studios"
            };

            var tl = new PPos(MapCordonWidth, MapCordonWidth);
            var br = new PPos(MapCordonWidth + mapSize.Width - 1, MapCordonWidth + mapSize.Height - 1);

            map.SetBounds(tl, br);

            // Get all templates from the tileset YAML file that have at least one frame and an Image property corresponding to the requested tileset
            // Each frame is a tile from the Dune 2000 tileset files, with the Frame ID being the index of the tile in the original file
            tileSetsFromYaml = tileSet.Templates.Where(t => t.Value.Frames != null &&
                                                       t.Value.Images[0].ToLower() == tilesetName.ToLower()).Select(ts => ts.Value).ToList();

            var players = new MapPlayers(map.Rules, playerCount);

            map.PlayerDefinitions = players.ToMiniYaml();
        }
Exemplo n.º 2
0
        public virtual void Run(ModData modData, string[] args)
        {
            ModData = modData;

            // HACK: The engine code assumes that Game.modData is set.
            Game.ModData = modData;

            var filename = args[1];

            using (var stream = modData.DefaultFileSystem.Open(filename))
            {
                var file       = new IniFile(stream);
                var basic      = file.GetSection("Basic");
                var mapSection = file.GetSection("Map");

                var format = GetMapFormatVersion(basic);
                ValidateMapFormat(format);

                var tileset = GetTileset(mapSection);
                Map = new Map(modData, modData.DefaultTileSets[tileset], MapSize, MapSize)
                {
                    Title  = basic.GetValue("Name", Path.GetFileNameWithoutExtension(filename)),
                    Author = "Westwood Studios",
                };

                Map.RequiresMod = modData.Manifest.Mod.Id;

                SetBounds(Map, mapSection);

                ReadPacks(file, filename);
                ReadTrees(file);

                LoadVideos(file, "BASIC");
                LoadBriefing(file);

                ReadActors(file);

                LoadSmudges(file, "SMUDGE");

                var waypoints = file.GetSection("Waypoints");
                LoadWaypoints(waypoints);

                // Create default player definitions only if there are no players to import
                MapPlayers = new MapPlayers(Map.Rules, Players.Count == 0 ? spawnCount : 0);
                foreach (var p in Players)
                {
                    LoadPlayer(file, p);
                }

                Map.PlayerDefinitions = MapPlayers.ToMiniYaml();
            }

            Map.FixOpenAreas();

            var dest    = Path.GetFileNameWithoutExtension(args[1]) + ".oramap";
            var package = new ZipFile(modData.ModFiles, dest, true);

            Map.Save(package);
            Console.WriteLine(dest + " saved.");
        }
Exemplo n.º 3
0
        void LoadMap(string mapname)
        {
            tilePalette.Controls.Clear();
            actorPalette.Controls.Clear();
            resourcePalette.Controls.Clear();

            loadedMapName = mapname;

            // load the map
            var map = new Map(mapname);

            // upgrade maps that have no player definitions. editor doesnt care,
            // but this breaks the game pretty badly.
            if (map.PlayerDefinitions.Count == 0)
            {
                var players = new MapPlayers(map.Rules, map.SpawnPoints.Value.Length);
                map.PlayerDefinitions = players.ToMiniYaml();
            }

            PrepareMapResources(Game.ModData, map);

            // Calculate total net worth of resources in cash
            cashToolStripStatusLabel.Text = CalculateTotalResource().ToString();

            dirty = false;
        }
Exemplo n.º 4
0
        void NewClicked(object sender, EventArgs e)
        {
            using (var nmd = new NewMapDialog())
            {
                nmd.TheaterBox.Items.Clear();
                nmd.TheaterBox.Items.AddRange(Program.Rules.TileSets.Select(a => a.Value.Id).ToArray());
                nmd.TheaterBox.SelectedIndex = 0;

                if (DialogResult.OK == nmd.ShowDialog())
                {
                    var tileset = Program.Rules.TileSets[nmd.TheaterBox.SelectedItem as string];
                    var map     = Map.FromTileset(tileset);

                    map.Resize((int)nmd.MapWidth.Value, (int)nmd.MapHeight.Value);
                    map.ResizeCordon((int)nmd.CordonLeft.Value, (int)nmd.CordonTop.Value,
                                     (int)nmd.CordonRight.Value, (int)nmd.CordonBottom.Value);

                    var players = new MapPlayers(map.Rules, map.SpawnPoints.Value.Length);
                    map.PlayerDefinitions = players.ToMiniYaml();

                    map.FixOpenAreas(Program.Rules);

                    NewMap(map);
                }
            }
        }
Exemplo n.º 5
0
        void SetupDefaultPlayers(object sender, EventArgs e)
        {
            dirty = true;
            var players = new MapPlayers(surface1.Map.Rules, surface1.Map.SpawnPoints.Value.Length);

            surface1.Map.PlayerDefinitions = players.ToMiniYaml();

            surface1.Chunks.Clear();
            surface1.Invalidate();

            PopulateActorOwnerChooser();
        }
Exemplo n.º 6
0
        void IUtilityCommand.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 author     = args.Length > 2
                                ? args[2]
                                : "Westwood Studios";

            if (!utility.ModData.DefaultTerrainInfo.TryGetValue(tileset, out var terrainInfo))
            {
                throw new InvalidDataException("Unknown tileset {0}".F(tileset));
            }

            var map = new Map(Game.ModData, terrainInfo, size.Width, size.Height)
            {
                Title       = basic.GetValue("Name", Path.GetFileNameWithoutExtension(filename)),
                Author      = author,
                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);
            ReadLamps(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.");
        }
Exemplo n.º 7
0
        public static Map Import(string filename, string mod, string tileset, Ruleset rules)
        {
            var map = new D2kMapImporter(filename, tileset, rules).map;

            if (map == null)
            {
                return(null);
            }

            map.RequiresMod = mod;
            var players = new MapPlayers(map.Rules, map.SpawnPoints.Value.Length);

            map.PlayerDefinitions = players.ToMiniYaml();

            return(map);
        }
Exemplo n.º 8
0
        void IUtilityCommand.Run(ModData modData, string[] args)
        {
            // HACK: The engine code assumes that Game.modData is set.
            Game.ModData = 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, 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 = modData.Manifest.Mod.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";
            var package = new ZipFile(modData.DefaultFileSystem, dest, true);

            map.Save(package);
            Console.WriteLine(dest + " saved.");
        }
Exemplo n.º 9
0
        MapImporter(string filename, string tileset)
        {
            tilesetName = tileset;
            clearTile   = new TerrainTile(0, 0);

            try
            {
                stream = File.OpenRead(filename);

                if (stream.Length == 0)
                {
                    throw new InvalidDataException("File is empty.");
                }

                var magic = stream.ReadASCII(82);
                var type  = stream.ReadASCII(82);

                if (!(magic.Contains("GameA.DDF") || magic.Contains("Game.DDF")) || !type.Contains("Landscape"))
                {
                    throw new ArgumentException("The map is in an unrecognized format!", "filename");
                }

                Initialize(filename);
                FillMap();
                LoadActors();

                map.PlayerDefinitions = mapPlayers.ToMiniYaml();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                map = null;
            }
            finally
            {
                stream.Close();
            }
        }
		void IUtilityCommand.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(ZipFile.Create(dest, new Folder(".")));
			Console.WriteLine(dest + " saved.");
		}
Exemplo n.º 11
0
        void Initialize(string mapFile)
        {
            mapSize = new Size(stream.ReadUInt16(), stream.ReadUInt16());

            tileSet = Game.ModData.DefaultTileSets["ARRAKIS"];

            map = new Map(Game.ModData, tileSet, mapSize.Width + 2 * MapCordonWidth, mapSize.Height + 2 * MapCordonWidth)
            {
                Title = Path.GetFileNameWithoutExtension(mapFile),
                Author = "Westwood Studios"
            };

            var tl = new PPos(MapCordonWidth, MapCordonWidth);
            var br = new PPos(MapCordonWidth + mapSize.Width - 1, MapCordonWidth + mapSize.Height - 1);
            map.SetBounds(tl, br);

            // Get all templates from the tileset YAML file that have at least one frame and an Image property corresponding to the requested tileset
            // Each frame is a tile from the Dune 2000 tileset files, with the Frame ID being the index of the tile in the original file
            tileSetsFromYaml = tileSet.Templates.Where(t => t.Value.Frames != null
                && t.Value.Images[0].ToLower() == tilesetName.ToLower()).Select(ts => ts.Value).ToList();

            var players = new MapPlayers(map.Rules, playerCount);
            map.PlayerDefinitions = players.ToMiniYaml();
        }
Exemplo n.º 12
0
		enum IniMapFormat { RedAlert = 3 } // otherwise, cnc (2 variants exist, we don't care to differentiate)

		public void ConvertIniMap(string iniFile)
		{
			using (var stream = GlobalFileSystem.Open(iniFile))
			{
				var file = new IniFile(stream);
				var basic = file.GetSection("Basic");
				var mapSection = file.GetSection("Map");
				var legacyMapFormat = (IniMapFormat)Exts.ParseIntegerInvariant(basic.GetValue("NewINIFormat", "0"));
				var offsetX = Exts.ParseIntegerInvariant(mapSection.GetValue("X", "0"));
				var offsetY = Exts.ParseIntegerInvariant(mapSection.GetValue("Y", "0"));
				var width = Exts.ParseIntegerInvariant(mapSection.GetValue("Width", "0"));
				var height = Exts.ParseIntegerInvariant(mapSection.GetValue("Height", "0"));
				mapSize = (legacyMapFormat == IniMapFormat.RedAlert) ? 128 : 64;

				var tileset = Truncate(mapSection.GetValue("Theater", "TEMPERAT"), 8);
				map = new Map(rules.TileSets[tileset], mapSize, mapSize)
				{
					Title = basic.GetValue("Name", Path.GetFileNameWithoutExtension(iniFile)),
					Author = "Westwood Studios"
				};

				var tl = new PPos(offsetX, offsetY);
				var br = new PPos(offsetX + width - 1, offsetY + height - 1);
				map.SetBounds(tl, br);

				if (legacyMapFormat == IniMapFormat.RedAlert)
				{
					UnpackRATileData(ReadPackedSection(file.GetSection("MapPack")));
					UnpackRAOverlayData(ReadPackedSection(file.GetSection("OverlayPack")));
					ReadRATrees(file);
				}
				else
				{
					// CnC
					using (var s = GlobalFileSystem.Open(iniFile.Substring(0, iniFile.Length - 4) + ".bin"))
						UnpackCncTileData(s);
					ReadCncOverlay(file);
					ReadCncTrees(file);
				}

				LoadVideos(file, "BASIC");
				LoadActors(file, "STRUCTURES");
				LoadActors(file, "UNITS");
				LoadActors(file, "INFANTRY");
				LoadActors(file, "SHIPS");
				LoadSmudges(file, "SMUDGE");

				var wps = file.GetSection("Waypoints")
						.Where(kv => Exts.ParseIntegerInvariant(kv.Value) > 0)
						.Select(kv => Pair.New(Exts.ParseIntegerInvariant(kv.Key),
							LocationFromMapOffset(Exts.ParseIntegerInvariant(kv.Value), mapSize)));

				// Add waypoint actors
				foreach (var kv in wps)
				{
					if (kv.First <= 7)
					{
						var ar = new ActorReference("mpspawn")
						{
							new LocationInit((CPos)kv.Second),
							new OwnerInit("Neutral")
						};

						map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save()));
					}
					else
					{
						var ar = new ActorReference("waypoint")
						{
							new LocationInit((CPos)kv.Second),
							new OwnerInit("Neutral")
						};

						map.ActorDefinitions.Add(new MiniYamlNode("waypoint" + kv.First, ar.Save()));
					}
				}

				// Create default player definitions only if there are no players to import
				mapPlayers = new MapPlayers(map.Rules, (players.Count == 0) ? map.SpawnPoints.Value.Length : 0);
				foreach (var p in players)
					LoadPlayer(file, p, legacyMapFormat == IniMapFormat.RedAlert);
				map.PlayerDefinitions = mapPlayers.ToMiniYaml();
			}
		}
Exemplo n.º 13
0
        protected void Run(Utility utility, string[] args)
        {
            // HACK: The engine code assumes that Game.modData is set.
            Game.ModData = ModData = utility.ModData;

            var filename = args[1];

            using (var stream = File.OpenRead(filename))
            {
                var headerString = stream.ReadASCII(4);
                var headerVers   = stream.ReadInt32();

                if (headerString != "MAP_")
                {
                    throw new ArgumentException("Map file did not start with MAP_");
                }

                if (headerVers < 0x300)
                {
                    throw new ArgumentException("Map version was too low.");
                }

                var width  = stream.ReadInt32();
                var height = stream.ReadInt32();
                stream.ReadInt32();                 // Tileset num???
                var tilesetName = "BARREN";

                filename = filename.ToLowerInvariant();

                var scnFilename = filename.Replace(".map", ".scn");
                using (var scn = File.OpenRead(scnFilename))
                {
                    var scnFile = new ScnFile(scn);
                    foreach (var scnSection in scnFile.Entries)
                    {
                        if (scnSection.Name != "SetDefaultTerrain")
                        {
                            continue;
                        }

                        tilesetName = scnSection.ValuesStr.ToUpperInvariant();
                    }
                }

                Map = new Map(ModData, ModData.DefaultTileSets[tilesetName], width + 2, height + 2)
                {
                    Title  = Path.GetFileNameWithoutExtension(filename),
                    Author = "Dark Reign",
                };

                Map.RequiresMod = ModData.Manifest.Id;

                SetBounds(Map, width + 2, height + 2);

                var byte1Hash           = new HashSet <byte>();
                var byte2Hash           = new HashSet <byte>();
                var byte3Hash           = new HashSet <byte>();
                var byte4Hash           = new HashSet <byte>();
                var byte5Hash           = new HashSet <byte>();
                var byte6Hash           = new HashSet <byte>();
                var unknownTileTypeHash = new HashSet <int>();

                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        var byte1 = stream.ReadUInt8();                         // Tile type 0-63, with art variations repeated 1-4
                        var byte2 = stream.ReadUInt8();                         // Which art variation to use. 0 = 1-4, 1 = 5-8
                        var byte3 = stream.ReadUInt8();                         // Base elevation, defaults to 2.
                        var byte4 = stream.ReadUInt8();                         // Unknown, defaults to 36. Seems to be elevation related.
                        var byte5 = stream.ReadUInt8();                         // Unknown, defaults to 73. Seems to be elevation related.
                        var byte6 = stream.ReadUInt8();                         // Unknown, defaults to 146. Seems to be elevation related.

                        if (!byte1Hash.Contains(byte1))
                        {
                            byte1Hash.Add(byte1);
                        }
                        if (!byte2Hash.Contains(byte2))
                        {
                            byte2Hash.Add(byte2);
                        }
                        if (!byte3Hash.Contains(byte3))
                        {
                            byte3Hash.Add(byte3);
                        }
                        if (!byte4Hash.Contains(byte4))
                        {
                            byte4Hash.Add(byte4);
                        }
                        if (!byte5Hash.Contains(byte5))
                        {
                            byte5Hash.Add(byte5);
                        }
                        if (!byte6Hash.Contains(byte6))
                        {
                            byte6Hash.Add(byte6);
                        }

                        var  subindex  = (byte)(byte1 / 64);
                        byte variation = (byte)(subindex * (byte2 + 1));
                        int  tileType  = byte1 % 64;

                        if (tileType >= 16)
                        {
                            unknownTileTypeHash.Add(tileType);
                            tileType = 1;                             // TODO: Handle edge sprites
                        }

                        Map.Tiles[new CPos(x + 1, y + 1)] = new TerrainTile((ushort)tileType, variation);                         // types[i, j], byte1
                    }
                }

                // What's after the tiles? Water/Taelon?
                stream.ReadInt32();                 // Always one
                stream.ReadInt32();                 // Always 256
                int length = stream.ReadInt32();    // Byte length of remaining data

                byte1Hash = new HashSet <byte>();
                var byteList = new List <byte>();
                for (int i = 0; i < length; i++)
                {
                    var byte1 = stream.ReadUInt8();
                    if (!byte1Hash.Contains(byte1))
                    {
                        byte1Hash.Add(byte1);
                    }

                    byteList.Add(byte1);
                }

                using (var scn = File.OpenRead(scnFilename))
                {
                    var scnFile = new ScnFile(scn);

                    MapPlayers = new MapPlayers(Map.Rules, 0);
                    SetMapPlayers(scnFile, Players, MapPlayers);

                    // Place start locations
                    int i = 0;
                    foreach (var scnSection in scnFile.Entries)
                    {
                        if (scnSection.Name != "SetStartLocation")
                        {
                            continue;
                        }

                        int divisor = 24;
                        int x       = Convert.ToInt32(scnSection.Values[0]) / divisor;
                        int y       = Convert.ToInt32(scnSection.Values[1]) / divisor;
                        if (x != 0 && y != 0)
                        {
                            var ar = new ActorReference("mpspawn")
                            {
                                new LocationInit(new CPos(x + 1, y + 1)),
                                new OwnerInit("Neutral")
                            };

                            Map.ActorDefinitions.Add(new MiniYamlNode("Actor" + i++, ar.Save()));
                        }
                    }

                    // Parse map thingies
                    foreach (var scnSection in scnFile.Entries)
                    {
                        if (scnSection.Name != "AddThingAt")
                        {
                            continue;
                        }

                        string type = scnSection.Values[1];
                        int    x    = Convert.ToInt32(scnSection.Values[2]);
                        int    y    = Convert.ToInt32(scnSection.Values[3]);

                        var matchingActor = string.Empty;

                        if (thingNames.ContainsKey(type))
                        {
                            matchingActor = thingNames[type];
                        }
                        else if (!knownUnknownThings.Contains(type))
                        {
                            throw new Exception("Unknown thing name: " + type);
                        }

                        if (x >= 0 && y >= 0 && !string.IsNullOrEmpty(matchingActor))
                        {
                            var ar = new ActorReference(matchingActor)
                            {
                                new LocationInit(new CPos(x + 1, y + 1)),
                                new OwnerInit("Neutral")
                            };

                            Map.ActorDefinitions.Add(new MiniYamlNode("Actor" + i++, ar.Save()));
                        }
                    }

                    int currentTeam = 0;

                    if (!skipActors)
                    {
                        // Units
                        foreach (var scnSection in scnFile.Entries)
                        {
                            if (scnSection.Name == "SetDefaultTeam")
                            {
                                currentTeam = Convert.ToInt32(scnSection.ValuesStr);
                                continue;
                            }

                            if (scnSection.Name != "PutUnitAt")
                            {
                                continue;
                            }

                            int playerIndex = GetMatchingPlayerIndex(currentTeam);                             // to skip creeps and neutral if necessary

                            string type = scnSection.Values[1];
                            int    x    = Convert.ToInt32(scnSection.Values[2]);
                            int    y    = Convert.ToInt32(scnSection.Values[3]);

                            var matchingActor = string.Empty;

                            if (unitNames.ContainsKey(type))
                            {
                                matchingActor = unitNames[type];
                            }
                            else if (!knownUnknownUnits.Contains(type))
                            {
                                throw new Exception("Unknown unit name: " + type);
                            }

                            if (x >= 0 && y >= 0 && !string.IsNullOrEmpty(matchingActor))
                            {
                                var ar = new ActorReference(matchingActor)
                                {
                                    new LocationInit(new CPos(x + 1, y + 1)),
                                    new OwnerInit(MapPlayers.Players.Values.First(p => p.Team == playerIndex).Name)
                                };

                                Map.ActorDefinitions.Add(new MiniYamlNode("Actor" + i++, ar.Save()));
                            }
                        }

                        // Do buildings
                        foreach (var scnSection in scnFile.Entries)
                        {
                            if (scnSection.Name == "SetDefaultTeam")
                            {
                                currentTeam = Convert.ToInt32(scnSection.ValuesStr);
                                continue;
                            }

                            if (scnSection.Name != "AddBuildingAt")
                            {
                                continue;
                            }

                            int playerIndex = GetMatchingPlayerIndex(currentTeam);                             // to skip creeps and neutral if necessary

                            string type = scnSection.Values[1];
                            int    x    = Convert.ToInt32(scnSection.Values[2]);
                            int    y    = Convert.ToInt32(scnSection.Values[3]);

                            var matchingActor = string.Empty;

                            if (buildingNames.ContainsKey(type))
                            {
                                matchingActor = buildingNames[type];
                            }
                            else if (!knownUnknownBuildings.Contains(type))
                            {
                                throw new Exception("Unknown building name: " + type);
                            }

                            var isResource = type == "impww" || type == "impmn";
                            var ownerName  = isResource
                                                                ? "Neutral"
                                                                : MapPlayers.Players.Values.First(p => p.Team == playerIndex).Name;

                            if (isResource == true)
                            {
                                throw new ArgumentException("FART");
                            }

                            if (x >= 0 && y >= 0 && !string.IsNullOrEmpty(matchingActor))
                            {
                                var ar = new ActorReference(matchingActor)
                                {
                                    new LocationInit(new CPos(x + 1, y + 1)),
                                    new OwnerInit(ownerName)
                                };

                                Map.ActorDefinitions.Add(new MiniYamlNode("Actor" + i++, ar.Save()));
                            }
                        }
                    }

                    // Do resources
                    foreach (var scnSection in scnFile.Entries)
                    {
                        if (scnSection.Name != "AddBuildingAt")
                        {
                            continue;
                        }

                        string type = scnSection.Values[1];
                        int    x    = Convert.ToInt32(scnSection.Values[2]);
                        int    y    = Convert.ToInt32(scnSection.Values[3]);

                        var isResource = type == "impww" || type == "impmn";
                        if (!isResource)
                        {
                            continue;
                        }

                        var matchingActor = string.Empty;

                        if (buildingNames.ContainsKey(type))
                        {
                            matchingActor = buildingNames[type];
                        }

                        if (x >= 0 && y >= 0 && !string.IsNullOrEmpty(matchingActor))
                        {
                            var ar = new ActorReference(matchingActor)
                            {
                                new LocationInit(new CPos(x + 1, y + 1)),
                                new OwnerInit("Neutral")
                            };

                            Map.ActorDefinitions.Add(new MiniYamlNode("Actor" + i++, ar.Save()));
                        }
                    }
                }

                // Reset teams var
                foreach (var playersValue in MapPlayers.Players.Values)
                {
                    playersValue.Team = 0;
                }

                Map.PlayerDefinitions = MapPlayers.ToMiniYaml();
            }

            Map.FixOpenAreas();

            var dest = Path.GetFileNameWithoutExtension(args[1]) + ".oramap";

            Map.Save(ZipFileLoader.Create(dest));
            Console.WriteLine(dest + " saved.");
        }
Exemplo n.º 14
0
        protected void Run(Utility utility, string[] args)
        {
            // HACK: The engine code assumes that Game.modData is set.
            Game.ModData = ModData = utility.ModData;

            var filename = args[1];

            using (var stream = File.OpenRead(filename))
            {
                var file  = new IniFile(stream);
                var basic = file.GetSection("Basic");

                var player = basic.GetValue("Player", string.Empty);
                if (!string.IsNullOrEmpty(player))
                {
                    singlePlayer = !player.StartsWith("Multi");
                }

                var mapSection = file.GetSection("Map");

                var format = GetMapFormatVersion(basic);
                ValidateMapFormat(format);

                // The original game isn't case sensitive, but we are.
                var tileset = GetTileset(mapSection).ToUpperInvariant();
                if (!ModData.DefaultTileSets.ContainsKey(tileset))
                {
                    throw new InvalidDataException("Unknown tileset {0}".F(tileset));
                }

                Map = new Map(ModData, ModData.DefaultTileSets[tileset], MapSize, MapSize)
                {
                    Title  = basic.GetValue("Name", Path.GetFileNameWithoutExtension(filename)),
                    Author = "Westwood Studios",
                };

                Map.RequiresMod = ModData.Manifest.Id;

                SetBounds(Map, mapSection);

                ReadPacks(file, filename);
                ReadTrees(file);

                LoadVideos(file, "BASIC");
                LoadBriefing(file);

                ReadActors(file);

                LoadSmudges(file, "SMUDGE");

                var waypoints = file.GetSection("Waypoints");
                LoadWaypoints(waypoints);

                // Create default player definitions only if there are no players to import
                MapPlayers = new MapPlayers(Map.Rules, Players.Count == 0 ? spawnCount : 0);
                foreach (var p in Players)
                {
                    LoadPlayer(file, p);
                }

                Map.PlayerDefinitions = MapPlayers.ToMiniYaml();
            }

            Map.FixOpenAreas();

            var dest = Path.GetFileNameWithoutExtension(args[1]) + ".oramap";

            Map.Save(ZipFile.Create(dest, new Folder(".")));
            Console.WriteLine(dest + " saved.");
        }
Exemplo n.º 15
0
        void CreateMapPlayers()
        {
            var players = new MapPlayers(map.Rules, playerCount);

            map.PlayerDefinitions = players.ToMiniYaml();
        }
Exemplo n.º 16
0
        public static Map Import(string filename, string mod, string tileset, Ruleset rules)
        {
            var map = new D2kMapImporter(filename, tileset, rules).map;
            if (map == null)
                return null;

            map.RequiresMod = mod;
            var players = new MapPlayers(map.Rules, map.SpawnPoints.Value.Length);
            map.PlayerDefinitions = players.ToMiniYaml();

            return map;
        }
Exemplo n.º 17
0
        protected void Run(Utility utility, string[] args)
        {
            // HACK: The engine code assumes that Game.modData is set.
            Game.ModData = ModData = utility.ModData;

            var filename = args[1];
            using (var stream = File.OpenRead(filename))
            {
                var file = new IniFile(stream);
                var basic = file.GetSection("Basic");

                var player = basic.GetValue("Player", string.Empty);
                if (!string.IsNullOrEmpty(player))
                    singlePlayer = !player.StartsWith("Multi");

                var mapSection = file.GetSection("Map");

                var format = GetMapFormatVersion(basic);
                ValidateMapFormat(format);

                // The original game isn't case sensitive, but we are.
                var tileset = GetTileset(mapSection).ToUpperInvariant();
                if (!ModData.DefaultTileSets.ContainsKey(tileset))
                    throw new InvalidDataException("Unknown tileset {0}".F(tileset));

                Map = new Map(ModData, ModData.DefaultTileSets[tileset], MapSize, MapSize)
                {
                    Title = basic.GetValue("Name", Path.GetFileNameWithoutExtension(filename)),
                    Author = "Westwood Studios",
                };

                Map.RequiresMod = ModData.Manifest.Id;

                SetBounds(Map, mapSection);

                ReadPacks(file, filename);
                ReadTrees(file);

                LoadVideos(file, "BASIC");
                LoadBriefing(file);

                ReadActors(file);

                LoadSmudges(file, "SMUDGE");

                var waypoints = file.GetSection("Waypoints");
                LoadWaypoints(waypoints);

                // Create default player definitions only if there are no players to import
                MapPlayers = new MapPlayers(Map.Rules, Players.Count == 0 ? spawnCount : 0);
                foreach (var p in Players)
                    LoadPlayer(file, p);

                Map.PlayerDefinitions = MapPlayers.ToMiniYaml();
            }

            Map.FixOpenAreas();

            var dest = Path.GetFileNameWithoutExtension(args[1]) + ".oramap";

            Map.Save(ZipFile.Create(dest, new Folder(".")));
            Console.WriteLine(dest + " saved.");
        }
Exemplo n.º 18
0
        void LoadMap(string mapname)
        {
            tilePalette.Controls.Clear();
            actorPalette.Controls.Clear();
            resourcePalette.Controls.Clear();

            loadedMapName = mapname;

            // load the map
            var map = new Map(mapname);

            // upgrade maps that have no player definitions. editor doesnt care,
            // but this breaks the game pretty badly.
            if (map.PlayerDefinitions.Count == 0)
            {
                var players = new MapPlayers(map.Rules, map.SpawnPoints.Value.Length);
                map.PlayerDefinitions = players.ToMiniYaml();
            }

            PrepareMapResources(Game.ModData, map);

            // Calculate total net worth of resources in cash
            cashToolStripStatusLabel.Text = CalculateTotalResource().ToString();

            dirty = false;
        }
Exemplo n.º 19
0
        protected void Run(Utility utility, string[] args)
        {
            // HACK: The engine code assumes that Game.modData is set.
            Game.ModData = ModData = utility.ModData;

            var filename = args[1];
            var flag     = args[2];

            if (string.IsNullOrWhiteSpace(flag))
            {
                flag = "VH";
            }

            bool flipHorizontal = flag.Contains("H");
            bool flipVertical   = flag.Contains("V");

            MirrorType mirrorType = MirrorType.Horizontal;

            if (flipVertical)
            {
                mirrorType = MirrorType.Vertical;
            }
            if (flipHorizontal && flipVertical)
            {
                mirrorType = MirrorType.HorizontalAndVertical;
            }

            var targetPath = "..\\mods\\dr\\maps";

            var package = new Folder(targetPath).OpenPackage(filename, ModData.ModFiles);

            if (package == null)
            {
                Console.WriteLine("Couldn't find map file: " + filename);
                return;
            }

            Map = new Map(ModData, package);
            var size = Map.MapSize;

            switch (mirrorType)
            {
            case MirrorType.Horizontal:
                size = size.WithX(size.X / 2);
                break;

            case MirrorType.Vertical:
                size = size.WithY(size.Y / 2);
                break;

            case MirrorType.HorizontalAndVertical:
                size = size / 2;
                break;
            }

            // Tiles
            for (int x = 0; x < size.X; x++)
            {
                for (int y = 0; y < size.Y; y++)
                {
                    var pos           = new CPos(x, y);
                    var transformTile = new TileTransform()
                    {
                        Tile       = Map.Tiles[pos],
                        MirrorType = mirrorType,
                        Position   = pos
                    };

                    foreach (var tt in transformTile.GetTransforms(Map))
                    {
                        var newPos = tt.Position;
                        Map.Tiles[newPos] = tt.Tile;
                    }
                }
            }

            // Actors
            actorIndex = GetHighestActorIndex();
            int multiCount = 0;

            var actorDefs    = new List <ActorReference>();
            var removeActors = new List <MiniYamlNode>();

            foreach (var a in Map.ActorDefinitions)
            {
                var existing = new ActorReference(a.Value.Value, a.Value.ToDictionary());
                var pos      = existing.GetOrDefault <LocationInit>().Value;
                var owner    = existing.Get <OwnerInit>();

                if (pos.X < 0 || pos.X >= size.X ||
                    pos.Y < 0 || pos.Y >= size.Y)
                {
                    removeActors.Add(a);
                    continue;
                }

                var actor = new ActorTransform()
                {
                    Actor      = existing,
                    Position   = pos,
                    MirrorType = mirrorType,
                };

                if (actor.Actor.Type == "mpspawn")
                {
                    multiCount++;
                }

                foreach (var at in actor.GetTransforms(Map))
                {
                    var ar = new ActorReference(actor.Actor.Type)
                    {
                        new LocationInit(at.Position),
                        owner
                    };

                    actorDefs.Add(ar);

                    if (at.Actor.Type == "mpspawn")
                    {
                        multiCount++;
                    }
                }
            }

            foreach (var a in actorDefs)
            {
                Map.ActorDefinitions.Add(new MiniYamlNode("Actor" + ++actorIndex, a.Save()));
            }

            foreach (var a in removeActors)
            {
                Map.ActorDefinitions.Remove(a);
            }

            if (multiCount > 0)
            {
                var mapPlayers = new MapPlayers(Map.Rules, multiCount);
                Map.PlayerDefinitions = mapPlayers.ToMiniYaml();
            }

            // Resources
            for (int x = 0; x < size.X; x++)
            {
                for (int y = 0; y < size.Y; y++)
                {
                    var pos      = new CPos(x, y);
                    var resource = new ResourceTransform()
                    {
                        Tile       = Map.Resources[pos],
                        MirrorType = mirrorType,
                        Position   = pos
                    };

                    foreach (var rt in resource.GetTransforms(Map))
                    {
                        var newPos = rt.Position;
                        Map.Resources[newPos] = rt.Tile;
                    }
                }
            }

            var dest = Path.Combine(targetPath, Path.GetFileNameWithoutExtension(filename) + ".oramap");

            Map.Save(ZipFileLoader.Create(dest));
            Console.WriteLine(dest + " saved.");
        }
Exemplo n.º 20
0
        void SetupDefaultPlayers(object sender, EventArgs e)
        {
            dirty = true;
            var players = new MapPlayers(surface1.Map.Rules, surface1.Map.SpawnPoints.Value.Length);
            surface1.Map.PlayerDefinitions = players.ToMiniYaml();

            surface1.Chunks.Clear();
            surface1.Invalidate();

            PopulateActorOwnerChooser();
        }
Exemplo n.º 21
0
        void NewClicked(object sender, EventArgs e)
        {
            using (var nmd = new NewMapDialog())
            {
                nmd.TheaterBox.Items.Clear();
                nmd.TheaterBox.Items.AddRange(Program.Rules.TileSets.Select(a => a.Value.Id).ToArray());
                nmd.TheaterBox.SelectedIndex = 0;

                if (DialogResult.OK == nmd.ShowDialog())
                {
                    var tileset = Program.Rules.TileSets[nmd.TheaterBox.SelectedItem as string];
                    var map = Map.FromTileset(tileset);

                    map.Resize((int)nmd.MapWidth.Value, (int)nmd.MapHeight.Value);
                    map.ResizeCordon((int)nmd.CordonLeft.Value, (int)nmd.CordonTop.Value,
                        (int)nmd.CordonRight.Value, (int)nmd.CordonBottom.Value);

                    var players = new MapPlayers(map.Rules, map.SpawnPoints.Value.Length);
                    map.PlayerDefinitions = players.ToMiniYaml();

                    map.FixOpenAreas(Program.Rules);

                    NewMap(map);
                }
            }
        }
Exemplo n.º 22
0
        enum IniMapFormat { RedAlert = 3 }         // otherwise, cnc (2 variants exist, we don't care to differentiate)

        public void ConvertIniMap(string iniFile)
        {
            using (var stream = GlobalFileSystem.Open(iniFile))
            {
                var file            = new IniFile(stream);
                var basic           = file.GetSection("Basic");
                var mapSection      = file.GetSection("Map");
                var legacyMapFormat = (IniMapFormat)Exts.ParseIntegerInvariant(basic.GetValue("NewINIFormat", "0"));
                var offsetX         = Exts.ParseIntegerInvariant(mapSection.GetValue("X", "0"));
                var offsetY         = Exts.ParseIntegerInvariant(mapSection.GetValue("Y", "0"));
                var width           = Exts.ParseIntegerInvariant(mapSection.GetValue("Width", "0"));
                var height          = Exts.ParseIntegerInvariant(mapSection.GetValue("Height", "0"));
                mapSize = (legacyMapFormat == IniMapFormat.RedAlert) ? 128 : 64;

                var tileset = Truncate(mapSection.GetValue("Theater", "TEMPERAT"), 8);
                map = new Map(rules.TileSets[tileset], mapSize, mapSize)
                {
                    Title  = basic.GetValue("Name", Path.GetFileNameWithoutExtension(iniFile)),
                    Author = "Westwood Studios"
                };

                var tl = new PPos(offsetX, offsetY);
                var br = new PPos(offsetX + width - 1, offsetY + height - 1);
                map.SetBounds(tl, br);

                if (legacyMapFormat == IniMapFormat.RedAlert)
                {
                    UnpackRATileData(ReadPackedSection(file.GetSection("MapPack")));
                    UnpackRAOverlayData(ReadPackedSection(file.GetSection("OverlayPack")));
                    ReadRATrees(file);
                }
                else
                {
                    // CnC
                    using (var s = GlobalFileSystem.Open(iniFile.Substring(0, iniFile.Length - 4) + ".bin"))
                        UnpackCncTileData(s);
                    ReadCncOverlay(file);
                    ReadCncTrees(file);
                }

                LoadVideos(file, "BASIC");
                LoadActors(file, "STRUCTURES");
                LoadActors(file, "UNITS");
                LoadActors(file, "INFANTRY");
                LoadActors(file, "SHIPS");
                LoadSmudges(file, "SMUDGE");

                var wps = file.GetSection("Waypoints")
                          .Where(kv => Exts.ParseIntegerInvariant(kv.Value) > 0)
                          .Select(kv => Pair.New(Exts.ParseIntegerInvariant(kv.Key),
                                                 LocationFromMapOffset(Exts.ParseIntegerInvariant(kv.Value), mapSize)));

                // Add waypoint actors
                foreach (var kv in wps)
                {
                    if (kv.First <= 7)
                    {
                        var ar = new ActorReference("mpspawn")
                        {
                            new LocationInit((CPos)kv.Second),
                            new OwnerInit("Neutral")
                        };

                        map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save()));
                    }
                    else
                    {
                        var ar = new ActorReference("waypoint")
                        {
                            new LocationInit((CPos)kv.Second),
                            new OwnerInit("Neutral")
                        };

                        map.ActorDefinitions.Add(new MiniYamlNode("waypoint" + kv.First, ar.Save()));
                    }
                }

                // Create default player definitions only if there are no players to import
                mapPlayers = new MapPlayers(map.Rules, (players.Count == 0) ? map.SpawnPoints.Value.Length : 0);
                foreach (var p in players)
                {
                    LoadPlayer(file, p, legacyMapFormat == IniMapFormat.RedAlert);
                }
                map.PlayerDefinitions = mapPlayers.ToMiniYaml();
            }
        }
Exemplo n.º 23
0
        private void Run(Utility utility, string[] args)
        {
            // HACK: The engine code assumes that Game.modData is set.
            Game.ModData = modData = utility.ModData;

            var filename = args[1];

            if (!Game.ModData.DefaultFileSystem.Exists(filename))
            {
                throw new IOException($"Couldn't find map {filename} in maps.vol or filesystem.");
            }

            using (var stream = Game.ModData.DefaultFileSystem.Open(filename))
            {
                var tag         = stream.ReadUInt32();         // always 4113
                var unknown     = stream.ReadUInt32();         // always 0
                var lgTileWidth = stream.ReadInt32();
                var tileHeight  = stream.ReadInt32();          // always 64
                var numTileSets = stream.ReadInt32();          // always 512

                // Update map header fields
                // Round height up to nearest power of 2
                var newHeight = tileHeight;
                newHeight -= 1;
                newHeight |= (newHeight >> 1);
                newHeight |= (newHeight >> 2);
                newHeight |= (newHeight >> 4);
                newHeight |= (newHeight >> 8);
                newHeight |= (newHeight >> 16);
                newHeight++;
                var width  = 1 << lgTileWidth;                // Calculate map width
                var height = newHeight;

                map = new Map(modData, modData.DefaultTileSets["default"], width + 2, (int)height + 2)
                {
                    Title       = Path.GetFileNameWithoutExtension(filename),
                    Author      = "OpenOP2",
                    RequiresMod = modData.Manifest.Id,
                };

                var tiles = new List <int>();
                for (var i = 0; i < width * height; i++)
                {
                    var tile = stream.ReadInt32();
                    tiles.Add(tile);
                }

                var clipRect = new ClipRect()
                {
                    X1 = stream.ReadInt32(),
                    Y1 = stream.ReadInt32(),
                    X2 = stream.ReadInt32(),
                    Y2 = stream.ReadInt32(),
                };

                SetBounds(map, width, height);

                // map.SetBounds(new PPos(clipRect.X1, clipRect.Y1), new PPos(width - clipRect.X2, (int)height - clipRect.Y2));
                // map.SetBounds(new PPos(clipRect.X1, clipRect.Y1), new PPos(clipRect.X1 + clipRect.X2, clipRect.Y1 - clipRect.Y2));
                // Read in tileset mappings
                var tileIds             = new List <TileSetInfo>();
                var tilesetStartIndices = new List <uint>();
                var tilesetTileIndex    = 0;
                for (int i = 0; i < numTileSets; i++)
                {
                    var stringLength = stream.ReadInt32();
                    if (stringLength <= 0)
                    {
                        continue;
                    }

                    var tilesetMapping = new TileSetInfo()
                    {
                        TileSetName = stream.ReadASCII(stringLength),
                        NumTiles    = stream.ReadInt32(),
                    };

                    tilesetStartIndices.Add((uint)tilesetTileIndex);
                    tilesetTileIndex += tilesetMapping.NumTiles;

                    tileIds.Add(tilesetMapping);
                }

                var testString = stream.ReadASCII(10);
                if (!testString.StartsWith("TILE SET"))
                {
                    throw new IOException("Couldn't find TILE SET tag.");
                }

                var numMappings = stream.ReadInt32();
                var mappings    = new TileSetMapping[numMappings];
                for (var i = 0; i < numMappings; i++)
                {
                    mappings[i] = new TileSetMapping
                    {
                        TileSetIndex        = stream.ReadInt16(),
                        TileIndex           = stream.ReadInt16(),
                        NumTileReplacements = stream.ReadInt16(),
                        CycleDelay          = stream.ReadInt16(),
                    };
                }

                var numTerrainTypes = stream.ReadInt32();
                var terrains        = new TerrainType[numTerrainTypes];

                stream.Seek(numTerrainTypes * 264, SeekOrigin.Current);

                var checkTag = stream.ReadUInt32();
                if (checkTag != tag)
                {
                    throw new IOException("Format error: Tag did not match header tag.");
                }

                var checkTag2 = stream.ReadInt32();                 // the same all the time?
                var numActors = stream.ReadInt32();                 // I think?

                // TODO: The rest of the tiles
                // Actually place the tiles
                for (var y = 0; y < height; y++)
                {
                    for (var x = 0; x < width; x++)
                    {
                        var tileXUpper = x >> 5;
                        var tileXLower = x & 0x1F;
                        var tileOffset = (((tileXUpper * height) + y) << 5) + tileXLower;
                        var tile       = tiles[tileOffset];

                        var tile2XUpper = tile >> 5;
                        var tile2XLower = tile & 0x1F;

                        // Get the tile mapping index
                        var cellType          = (tile & 0x1F);
                        var tileMappingIndex  = (tile & 0xFFE0) >> 5;
                        var actorMappingIndex = (tile & 0x7FF0000) >> 11;
                        var lava           = (tile & 0x00000001) >> 27;
                        var lavaPossible   = (tile & 0x00000001) >> 28;
                        var expand         = (tile & 0x00000001) >> 29;
                        var microbe        = (tile & 0x00000001) >> 30;
                        var wallOrBuilding = (tile & 0x00000001) >> 31;
                        if (actorMappingIndex != 0 || lavaPossible != 0 || wallOrBuilding != 0)
                        {
                            throw new Exception("Actor mapping was " + actorMappingIndex);
                        }

                        var thisMapping = mappings[tileMappingIndex];
                        var startIndex  = tilesetStartIndices[thisMapping.TileSetIndex];

                        map.Tiles[new CPos(x + 1, y + 1)] = new TerrainTile((ushort)(startIndex + thisMapping.TileIndex), 0);
                    }
                }
            }

            mapPlayers            = new MapPlayers(map.Rules, 0);
            map.PlayerDefinitions = mapPlayers.ToMiniYaml();
            map.FixOpenAreas();

            var dest         = Path.GetFileNameWithoutExtension(args[1]) + ".oramap";
            var mapLocations = Game.ModData.Manifest.MapFolders;
            var userMapPath  = mapLocations.First(mapLocation => mapLocation.Value == "User");
            var targetPath   = Path.Combine(Platform.ResolvePath(userMapPath.Key.Substring(1)), dest);

            map.Save(ZipFileLoader.Create(targetPath));

            Console.WriteLine(targetPath + " saved.");
        }