Пример #1
0
        public bool Save(string filename, bool saveAs = false)
        {
            if (isSaved && !saveAs)
            {
                return(true);
            }

            // Initially, write to a memory stream so we can CRC the data
            uint crcVal = 0;

            byte[] allBytes = null;
            using (MemoryStream ms = new MemoryStream())
            {
                ms.WriteInt(Const.MAGIC_NUMBER);

                // Map info
                ms.WriteInt((int)MapField.MapInfo);
                ms.WriteInt(w);
                ms.WriteInt(h);
                ms.WriteInt((int)Type);
                ms.WriteString(MapName);
                ms.WriteInt(Warp);
                ms.WriteInt(PlayerSpawn.X);
                ms.WriteInt(PlayerSpawn.Y);
                ms.WriteInt(layers.Length);

                // Write map layers
                foreach (SortedList <string, Tile> layer in this.layers)
                {
                    ms.WriteInt((int)MapField.MapLayer);

                    // Write number of tiles
                    ms.WriteInt(layer.Count);

                    foreach (Tile t in layer.Values)
                    {
                        if (t is AnimatedTile)
                        {
                            AnimatedTile at = (AnimatedTile)t;

                            ms.WriteInt((int)TileType.Animated);
                            ms.WriteInt(at.X);
                            ms.WriteInt(at.Y);
                            ms.WriteInt(at.Graphic);
                        }
                        else if (t is GraphicTile)
                        {
                            GraphicTile gt = (GraphicTile)t;

                            ms.WriteInt((int)TileType.Graphic);
                            ms.WriteInt(gt.X);
                            ms.WriteInt(gt.Y);
                            ms.WriteInt(gt.Graphic);
                        }
                        else if (t is SpecialTile)
                        {
                            SpecialTile st = (SpecialTile)t;

                            ms.WriteInt((int)TileType.Special);
                            ms.WriteInt(st.X);
                            ms.WriteInt(st.Y);
                            ms.WriteInt((int)st.Type);

                            switch (st.Type)
                            {
                            case SpecialTileSpec.CAVE:
                            case SpecialTileSpec.GRASS:
                            case SpecialTileSpec.WATER:
                                ms.WriteInt((int)st.SpawnID);
                                break;

                            case SpecialTileSpec.WARP:
                                ms.WriteInt(st.WarpMap);
                                ms.WriteInt(st.WarpX);
                                ms.WriteInt(st.WarpY);
                                ms.WriteInt((int)st.WarpAnim);
                                break;
                            }
                        }
                    }
                }

                // Write spawns
                int numSpawnsWritten = 0;
                foreach (Spawn sp in Spawns)
                {
                    // If this happens, we shouldn't write any more. Might as well stop now.
                    if (numSpawnsWritten > this.Spawns.Count)
                    {
                        break;
                    }

                    ms.WriteInt((int)MapField.SpawnInfo);
                    ms.WriteInt(sp.SpawnID);
                    ms.WriteString(sp.Name);
                    ms.WriteInt(sp.Spawns.Count);

                    int numPairsWritten = 0;
                    foreach (KeyValuePair <int, int> pair in sp.Spawns)
                    {
                        // Same error condition as before
                        if (numPairsWritten > sp.Spawns.Count)
                        {
                            break;
                        }

                        ms.WriteInt(pair.Key);
                        ms.WriteInt(pair.Value);

                        numPairsWritten++;
                    }

                    numSpawnsWritten++;
                }

                allBytes = new byte[ms.Length];
                ms.Seek(0, SeekOrigin.Begin);
                ms.Read(allBytes, 0, allBytes.Length);
                CRC32 crc = new CRC32();
                crcVal = crc.Check(allBytes);
            }

            using (BinaryWriter bw = new BinaryWriter(File.OpenWrite(filename)))
            {
                bw.Write(allBytes);
                bw.Write(ByteConverter.ToBytes(crcVal));
            }

            isSaved  = true;
            fileName = filename;

            return(isSaved);
        }
Пример #2
0
        public bool LoadFromStream(Stream s)
        {
            isLoaded = false;

            byte[] all;
            using (var memoryStream = new MemoryStream())
            {
                s.CopyTo(memoryStream);
                all = memoryStream.ToArray();
            }

            CRC32 crc    = new CRC32();
            uint  crcVal = crc.Check(all, 0, (uint)all.Length - 4); //crc everything except the value of the crc

            s.Seek(-sizeof(int), SeekOrigin.End);                   //last four bytes (int) is CRC value
            uint fileVal = (uint)s.ReadInt();

            if (crcVal != fileVal)
            {
                return(isLoaded);
            }

            s.Seek(0, SeekOrigin.Begin);

            if (s.ReadInt() != Const.MAGIC_NUMBER)
            {
                return(isLoaded);
            }

            spawns = new List <Spawn>();

            int loadedLayers = 0;

            while (s.Position < s.Length - 4)
            {
                switch ((MapField)s.ReadInt())
                {
                case MapField.MapInfo:
                    w           = s.ReadInt();
                    h           = s.ReadInt();
                    Type        = (MapType)s.ReadInt();
                    mapname     = s.ReadString();
                    Warp        = s.ReadInt();
                    PlayerSpawn = new Microsoft.Xna.Framework.Point(s.ReadInt(), s.ReadInt());
                    int numLayers = s.ReadInt();

                    if (numLayers != this.layers.Length)
                    {
                        throw new Exception("Invalid number of layers!");
                    }
                    break;

                case MapField.MapLayer:
                    int numTiles = s.ReadInt();
                    var newLayer = layers[loadedLayers] = new SortedList <string, Tile>(numTiles);

                    for (int i = 0; i < numTiles; i++)
                    {
                        Tile   toAdd = null;
                        LAYERS layer = LAYERS.Graphic;

                        switch ((TileType)s.ReadInt())
                        {
                        case TileType.Animated:
                            toAdd = new AnimatedTile(s.ReadInt(), s.ReadInt(), s.ReadInt());
                            layer = LAYERS.Graphic;
                            break;

                        case TileType.Graphic:
                            toAdd = new GraphicTile(s.ReadInt(), s.ReadInt(), s.ReadInt());
                            break;

                        case TileType.Special:
                            SpecialTile st = new SpecialTile(s.ReadInt(), s.ReadInt());

                            SpecialTileSpec tt    = (SpecialTileSpec)s.ReadInt();
                            object[]        param = null;
                            switch (tt)
                            {
                            case SpecialTileSpec.CAVE:
                            case SpecialTileSpec.GRASS:
                            case SpecialTileSpec.WATER:
                                param = new object[] { s.ReadInt() };
                                break;

                            case SpecialTileSpec.WARP:
                                param = new object[] { s.ReadInt(), s.ReadInt(), s.ReadInt(), (WarpAnim)s.ReadInt() };
                                break;
                            }

                            st.SetType(tt, param);
                            break;
                        }

                        if (toAdd != null)
                        {
                            AddTile(toAdd.X, toAdd.Y, layer, toAdd);
                        }
                    }

                    layers[loadedLayers++] = newLayer;
                    break;

                case MapField.SpawnInfo:
                    Spawn sp = new Spawn(s.ReadInt(), s.ReadString());

                    int numPairs = s.ReadInt();
                    for (int i = 0; i < numPairs; i++)
                    {
                        sp.AddSpawnPair(s.ReadInt(), s.ReadInt());
                    }
                    break;
                }
            }

            // Make sure we don't have any null layers (they cause problems later)
            for (int i = 0; i < layers.Length; i++)
            {
                if (layers[i] == null)
                {
                    layers[i] = new SortedList <string, Tile>();
                }
            }

            fileName = "";
            isLoaded = true;
            isSaved  = true;

            return(isLoaded);
        }