public override void Write(MapSet map, Stream mapdata) { // Make collections var buildwallids = new Dictionary <int, BuildWall>(map.Sidedefs.Count); var wallids = new Dictionary <Sidedef, int>(map.Sidedefs.Count); var sectorids = new Dictionary <Sector, int>(map.Sectors.Count); // Walls must be stored on per-sector basis... foreach (Sector s in map.Sectors) { if (s.Sidedefs == null || s.Sidedefs.Count < 3) { continue; } var sectorsidelists = Tools.GetSortedSectorSides(s); if (sectorsidelists.Count == 0) { continue; } foreach (List <Sidedef> sideslist in sectorsidelists) { // Add to lookup table for (int i = 0; i < sideslist.Count; i++) { wallids.Add(sideslist[i], wallids.Count); } // Create BuildWalls for (int i = 0; i < sideslist.Count; i++) { var bw = new BuildWall(sideslist[i]); int next = (i < sideslist.Count - 1 ? i + 1 : 0); // Connect last wall to the first one bw.NextWallIndex = wallids[sideslist[next]]; bw.Side = sideslist[i]; buildwallids.Add(buildwallids.Count, bw); } } sectorids.Add(s, sectorids.Count); } // Fill in OtherWallIndex and OtherSectorIndex foreach (var group in wallids) { if (group.Key.Other != null) { buildwallids[group.Value].OtherWallIndex = wallids[group.Key.Other]; buildwallids[group.Value].OtherSectorIndex = sectorids[group.Key.Other.Sector]; } } // Write map structures using (BinaryWriter writer = new BinaryWriter(mapdata)) { // Write map header writer.Write(Version); // First sprite must be player start Thing playerstart = map.GetThingByIndex(0); //TODO: check this BEFORE saving the map! if (playerstart == null) { throw new InvalidDataException("Map has no Player start!"); } if (playerstart.Sector == null || playerstart.Sector.IsDisposed) { playerstart.DetermineSector(); } if (playerstart.Sector == null) { throw new InvalidDataException("Player start must be inside a sector!"); } // Write player start point writer.Write((int)playerstart.Position.x); writer.Write((int)-playerstart.Position.y); // Transform to match Build coords... writer.Write(GetBuildHeight((int)playerstart.Position.z)); // Transform to match Build coords... // Write player starting angle writer.Write((ushort)Angle2D.RadToBuild(playerstart.Angle)); // Write sector number containing the start point writer.Write((ushort)sectorids[playerstart.Sector]); // Write sectors WriteSectors(writer, sectorids.Keys); // Write walls WriteWalls(writer, buildwallids.Values); // Write sprites WriteSprites(writer, map.Things, sectorids); } }