Exemplo n.º 1
0
        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);
            }
        }