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); }
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); }
public override void Draw(GameTime gameTime) { if (m_map != null) { int screenWidth = GraphicsDevice.Viewport.Width; int screenHeight = GraphicsDevice.Viewport.Height; GraphicsDevice.SetRenderTarget(screenGround); GraphicsDevice.Clear(Color.Black); Rectangle bounds = AnglerGame.MainPlayer.Bounds; int x = bounds.X < 0 ? 0 : bounds.X; int y = bounds.Y < 0 ? 0 : bounds.Y; Rectangle clipRectangle = new Rectangle( x, y, bounds.X + bounds.Width > screenWidth ? screenWidth - x : (bounds.X < 0 ? bounds.Width + bounds.X : bounds.Width), bounds.Y + bounds.Height > screenHeight ? screenHeight - y : (bounds.Y < 0 ? bounds.Height + bounds.Y : bounds.Height)); //draw the tile texture tiles across the screen GraphicsDevice.ScissorRectangle = clipRectangle; SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState, StencilState, RasterizerState); // Draw graphics and special tiles solids.Clear(); for (int i = m_map.VisibleBounds.Left; i < m_map.VisibleBounds.Right; i++) { for (int j = m_map.VisibleBounds.Top; j < m_map.VisibleBounds.Bottom; j++) { Rectangle rect = m_map.PositionOnVisibleMap(i, j); Tile tile = World.CurrentMap.GetTile(i, j, LAYERS.Graphic); if (tile is GraphicTile) { GraphicTile gt = tile as GraphicTile; SpriteBatch.Draw(FXCollection.Textures[gt.Graphic], new Vector2(rect.X, rect.Y), Color.White); } tile = World.CurrentMap.GetTile(i, j, LAYERS.Special); if (tile != null && (tile as SpecialTile).Type == SpecialTileSpec.NONE) { continue; } if (tile is SpecialTile) { SpecialTile st = tile as SpecialTile; if (st.Type == SpecialTileSpec.WALL) { locatedTexture locText = new locatedTexture(new Point(i, j), FXCollection.Textures[st.Graphic]); if (!solids.ContainsKey(st.Density)) { solids.Add(st.Density, new List <locatedTexture>()); } solids[st.Density].Add(locText); SpriteBatch.Draw(FXCollection.Textures[st.Graphic], new Vector2(rect.X, rect.Y), Color.White); } } } } SpriteBatch.End(); // Draw shadows to the ground render target foreach (var pair in solids) { Texture2D[] textures = pair.Value.Select(i => i.texture).ToArray(); Point[] locations = pair.Value.Select(i => i.location).ToArray(); shadowCaster.DrawShadows(textures, locations, screenGround, screenLights, pair.Key); } // Draw the resulting graphic GraphicsDevice.SetRenderTarget(null); GraphicsDevice.ScissorRectangle = clipRectangle; GraphicsDevice.Clear(Color.Black); SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState, StencilState, RasterizerState); SpriteBatch.Draw(screenGround, Vector2.Zero, Color.White); for (int i = m_map.VisibleBounds.Left; i < m_map.VisibleBounds.Right; i++) { for (int j = m_map.VisibleBounds.Top; j < m_map.VisibleBounds.Bottom; j++) { Rectangle rect = m_map.PositionOnVisibleMap(i, j); Tile tile = World.CurrentMap.GetTile(i, j, LAYERS.Special); if (tile == null) { continue; } if (tile is SpecialTile) { SpecialTile st = tile as SpecialTile; if (st.Type == SpecialTileSpec.NONE || st.Density <= 0.25) { continue; } SpriteBatch.Draw(FXCollection.Textures[st.Graphic], new Vector2(rect.X, rect.Y), Color.White); } } } SpriteBatch.End(); GraphicsDevice.ScissorRectangle = GraphicsDevice.Viewport.Bounds; } base.Draw(gameTime); }