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(); }
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."); }
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; }
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); } } }
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(); }
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."); }
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); }
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."); }
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."); }
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(); } }
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."); }
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."); }
void CreateMapPlayers() { var players = new MapPlayers(map.Rules, playerCount); map.PlayerDefinitions = players.ToMiniYaml(); }
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; }
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."); }
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."); }
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(); } }
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."); }