Exemple #1
0
        private static void WriteSprites(BinaryWriter writer, ICollection <Thing> sprites, Dictionary <Sector, int> sectorids)
        {
            List <Thing> validsprites = new List <Thing>(sprites.Count);

            bool first = true;

            foreach (var s in sprites)
            {
                // Skip player start sprite...
                if (first)
                {
                    first = false;
                    continue;
                }

                // Sprites must be inside an existing sector
                if (s.Sector == null || s.Sector.IsDisposed)
                {
                    s.DetermineSector();
                }
                if (s.Sector == null)
                {
                    continue;
                }
                validsprites.Add(s);
            }

            // UINT16LE Number of sprites in the map
            writer.Write((ushort)validsprites.Count);

            foreach (Thing s in validsprites)
            {
                // INT32LE x, y, z
                writer.Write((int)s.Position.x);
                writer.Write((int)-s.Position.y);                 // Transform to match Build coords...
                writer.Write(GetBuildHeight((int)s.Position.z));  // Transform to match Build coords...

                // INT16LE cstat
                writer.Write((ushort)FlagsToInt(s.Flags));

                // INT16LE picnum
                writer.Write((short)s.TileIndex);

                // INT8 shade, UINT8 pal
                writer.Write((sbyte)s.Shade);
                writer.Write((byte)s.PaletteIndex);

                // UINT8 clipdist, filler
                writer.Write((byte)s.ClipDistance);
                writer.Write((byte)0);

                // UINT8 xrepeat, yrepeat, xpanning, ypanning
                writer.Write((byte)s.RepeatX);
                writer.Write((byte)s.RepeatY);
                writer.Write((byte)s.OffsetX);
                writer.Write((byte)s.OffsetY);

                // INT16LE sectnum, statnum, ang, owner
                writer.Write((short)sectorids[s.Sector]);
                writer.Write((short)s.Status);
                writer.Write((short)Angle2D.RadToBuild(s.Angle));
                writer.Write((short)s.Owner);

                // INT16LE xvel, yvel, zvel
                writer.Write((short)s.Velocity.x);
                writer.Write((short)s.Velocity.y);
                writer.Write((short)s.Velocity.z);

                // INT16LE lotag, hitag, extra
                writer.Write((short)s.LoTag);
                writer.Write((short)s.HiTag);
                writer.Write((short)s.Extra);
            }
        }
Exemple #2
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);
            }
        }