/// <summary> /// Sets the metadata for a certain tile. An empty string or null = remove metadata. /// </summary> /// <param name="layer">The layer the tile is on.</param> /// <param name="x">The X position of the tile.</param> /// <param name="y">The Y position of the tile.</param> /// <param name="metadata">The metadata string, or null.</param> public void SetMetadata(Tile.MapLayer layer, int x, int y, TileMetadata metadata) { if (HasMetadata(layer, x, y)) { ushort slot = GetMetadataSlot(layer, x, y); LayerToMetadataArray(layer).RemoveAt(slot - 1); LayerToTileArray(layer)[(y * Width) + x] = LayerToTileArray(layer)[(y * Width) + x] & 0xff; for (int i = 0; i < Width * Height; i++) { if ((LayerToTileArray(layer)[i] & 0xFFFF0000) >> 16 >= slot) { ushort lastMetadataAttr = (ushort)((LayerToTileArray(layer)[i] & 0xFFFF0000) >> 16); lastMetadataAttr--; LayerToTileArray(layer)[i] = (uint)((LayerToTileArray(layer)[i] & 0xFFFF) | (lastMetadataAttr << 16)); } } } if (metadata != null && metadata.HasValuesSet) { LayerToMetadataArray(layer).Add(metadata); LayerToTileArray(layer)[(y * Width) + x] = (uint)((LayerToTileArray(layer)[(y * Width) + x] & 0xFFFF) | ((LayerToMetadataArray(layer).Count) << 16)); } }
private static void ReadJSONLayer(JsonReader reader, Map map, Tile.MapLayer layer) { int pos = 0; while (reader.Read()) { int x = (int)Math.Floor(pos / (double)map.Height); int y = pos % map.Height; if (reader.TokenType == JsonToken.String) { string id = reader.Value as string; if (Tile.Exists(id, layer)) { map[layer, x, y] = Tile.Find(id, layer); } pos++; } else if (reader.TokenType == JsonToken.StartObject) { ReadJSONComplexTileObject(reader, map, layer, x, y); pos++; } else if (reader.TokenType == JsonToken.EndArray) { return; } } }
/// <summary> /// Gets the metadata for the specified tile. If the tile doesn't have any metadata an empty string is returned. /// </summary> /// <param name="layer">The layer the tile is on.</param> /// <param name="x">The X position of the tile.</param> /// <param name="y">The Y position of the tile.</param> /// <returns>The metadata or null.</returns> public TileMetadata GetMetadata(Tile.MapLayer layer, int x, int y) { // TODO: MetadataAccess class helper if (HasMetadata(layer, x, y)) { if (LayerToMetadataArray(layer).Count <= GetMetadataSlot(layer, x, y) - 1) { return(null); } return(LayerToMetadataArray(layer)[GetMetadataSlot(layer, x, y) - 1]); } return(null); }
private uint[] LayerToTileArray(Tile.MapLayer layer) { switch (layer) { case Tile.MapLayer.Terrain: return(_layerTerrain); case Tile.MapLayer.Decoration: return(_layerDecoration); case Tile.MapLayer.NPC: return(_layerNPC); case Tile.MapLayer.Control: return(_layerControl); } return(null); }
private List <TileMetadata> LayerToMetadataArray(Tile.MapLayer layer) { switch (layer) { case Tile.MapLayer.Terrain: return(_metadataTerrain); case Tile.MapLayer.Decoration: return(_metadataDecoration); case Tile.MapLayer.NPC: return(_metadataNPC); case Tile.MapLayer.Control: return(_metadataControl); } return(null); }
private Tile[] LayerToIDMap(Tile.MapLayer layer) { switch (layer) { case Tile.MapLayer.Terrain: return(_idmapTerrain); case Tile.MapLayer.Decoration: return(_idmapDecoration); case Tile.MapLayer.NPC: return(_idmapNPC); case Tile.MapLayer.Control: return(_idmapControl); } return(null); }
private static void ReadJSONComplexTileObject(JsonReader reader, Map map, Tile.MapLayer layer, int x, int y) { string id = ""; TileMetadata metadata = new TileMetadata(); while (reader.Read()) { if (reader.TokenType == JsonToken.PropertyName) { switch (reader.Value) { case "id": id = reader.ReadAsString(); break; case "metadata": while (reader.Read()) { if (reader.TokenType == JsonToken.PropertyName) { metadata[(string)reader.Value] = reader.ReadAsString(); } else if (reader.TokenType == JsonToken.EndObject) { break; } } break; } } else if (reader.TokenType == JsonToken.EndObject) { break; } } map[layer, x, y] = Tile.Find(id, layer); map.SetMetadata(layer, x, y, metadata); }
/// <summary> /// Draws this map. /// </summary> /// <param name="layer">Layer to draw.</param> /// <param name="game">Game class.</param> /// <param name="rectangle">The cropped part of the map to draw. null - draw whole map</param> public void Draw(Tile.MapLayer layer, Game game, Rectangle?rectangle = null) { if (Atlas != null && Atlas.Game != game) { Atlas.Dispose(); Atlas = null; } if (Atlas == null) { Atlas = new TileAtlas(game); } if (TransitionCache != null && TransitionCache.Game != game) { TransitionCache.Dispose(); TransitionCache = null; } if (TransitionCache == null) { TransitionCache = new TileTransitionCache(game); } int xMin = 0; int yMin = 0; int xMax = Width - 1; int yMax = Height - 1; if (rectangle.HasValue) { xMin = Math.Max(0, (int)Math.Floor(rectangle.Value.X / 16.0)); yMin = Math.Max(0, (int)Math.Floor(rectangle.Value.Y / 16.0)); xMax = Math.Min(Width - 1, (int)Math.Ceiling((rectangle.Value.X + rectangle.Value.Width - 1) / 16.0)); yMax = Math.Min(Height - 1, (int)Math.Ceiling((rectangle.Value.Y + rectangle.Value.Height - 1) / 16.0)); } // Add one more to allow for transitions outside the rectangle. if (xMin > 0) { xMin--; } if (yMin > 0) { yMin--; } if (xMax < Width - 1) { xMax++; } if (yMax < Height - 1) { yMax++; } Rectangle drawRectangle = new Rectangle(xMin, yMin, xMax - xMin, yMax - yMin); drawRectangle.X *= 16; drawRectangle.Y *= 16; drawRectangle.Width *= 16; drawRectangle.Height *= 16; drawRectangle.Width += 16; drawRectangle.Height += 16; if (layer == Tile.MapLayer.Terrain) { (WaterTiles.DeepWaterOrVoid as AnimatedTile).UpdateCurrentFrameWithGame(game, new Point(0, 0)); if (Info.Environment == Environment.Inside) { game.Batch.Rectangle(drawRectangle, Color.Black); } else { game.Batch.Texture(drawRectangle, game.Assets.Get <Texture2D>(WaterTiles.DeepWaterOrVoid.TextureName()), Color.White, drawRectangle); } } int x, y; for (x = xMin; x <= xMax; x++) { for (y = yMin; y <= yMax; y++) { Tile tile = this[layer, x, y]; if (tile.ID != "") // water will be drawn by the map manually here { tile.Draw(game, new Point(x, y), this, GetMetadata(layer, x, y), Info.Environment); } } } for (x = xMin; x <= xMax; x++) { for (y = yMin; y <= yMax; y++) { Tile tile = this[layer, x, y]; if (layer == Tile.MapLayer.Terrain || tile.ID != "") { Point p1 = new Point(x - 1, y); Point p2 = new Point(x + 1, y); Point p3 = new Point(x, y - 1); Point p4 = new Point(x, y + 1); for (int i = 0; i < 4; i++) { Point point = i == 0 ? p1 : i == 1 ? p2 : i == 2 ? p3 : p4; if (point.X >= 0 && point.Y >= 0 && point.X < Width && point.Y < Height && tile.UseTransition( new Point(x, y), point, this, this[layer, point.X, point.Y], GetMetadata(layer, x, y), GetMetadata(layer, point.X, point.Y))) { Point transitionPoint; Texture2D transitionTexture = TransitionCache.TextureForTile( tile, GetMetadata(layer, x, y), Info.Environment, out transitionPoint); float rotation = 0; SpriteEffects effects = SpriteEffects.None; if (point == new Point(x + 1, y)) { effects = SpriteEffects.FlipHorizontally; } if (point == new Point(x, y - 1)) { rotation = MathHelper.PiOver2; } if (point == new Point(x, y + 1)) { rotation = MathHelper.Pi + MathHelper.PiOver2; } Rectangle textureRectangle = new Rectangle( transitionPoint.X * 16, transitionPoint.Y * 16, 16, 16); game.Batch.Texture( new Vector2( point.X * 16 + (rotation == MathHelper.PiOver2 ? 16 : 0), point.Y * 16 + (rotation == MathHelper.Pi + MathHelper.PiOver2 ? 16 : 0)), transitionTexture, Color.White, Vector2.One, textureRectangle, rotation, null, effects); } } } } } for (x = xMin; x <= xMax; x++) { for (y = yMin; y <= yMax; y++) { Tile tile = this[layer, x, y]; if (layer == Tile.MapLayer.Terrain || tile.ID != "") { tile.DrawAfterTransition(game, new Point(x, y), this, GetMetadata(layer, x, y), Info.Environment); } } } }
public ushort GetMetadataSlot(Tile.MapLayer layer, int x, int y) { return((ushort)((LayerToTileArray(layer)[(y * Width) + x] & 0xFFFF0000) >> 16)); }
/// <param name="layer">The layer the tile is on.</param> /// <param name="x">The X position of the tile.</param> /// <param name="y">The Y position of the tile.</param> /// <returns>If the tile has any metadata attached to it.</returns> public bool HasMetadata(Tile.MapLayer layer, int x, int y) { return(GetMetadataSlot(layer, x, y) != 0); }
public Tile this[Tile.MapLayer layer, int x, int y] { get { // & 0xFFFF = lower 16 bits return(LayerToIDMap(layer)[(ushort)(LayerToTileArray(layer)[(y * Width) + x] & 0xFFFF)]); } set { SetMetadata(layer, x, y, null); /*Tile oldTile = this[layer, x, y]; * * bool oldTileExists = oldTile == value; * if(!oldTileExists) * { * int ix, iy; * for(ix = 0; ix < Width; ix++) * { * for(iy = 0; iy < Height; iy++) * { * if(ix != x || iy != y) * { * if(this[layer, ix, iy] == oldTile) * { * oldTileExists = true; * break; * } * } * } * } * } * if(!oldTileExists) * LayerToIDMap(layer).Remove((ushort)(LayerToTileArray(layer)[(y * Width) + x] & 0xFFFF)); */ // TODO: behövs det här??? int newValue = Array.IndexOf(LayerToIDMap(layer), value); if (newValue == -1) { if (_idmapTerrain[_idmapTerrain.Length - 1] != null) { Array.Resize(ref _idmapTerrain, _idmapTerrain.Length * 2); } if (_idmapDecoration[_idmapDecoration.Length - 1] != null) { Array.Resize(ref _idmapDecoration, _idmapDecoration.Length * 2); } if (_idmapNPC[_idmapNPC.Length - 1] != null) { Array.Resize(ref _idmapNPC, _idmapNPC.Length * 2); } if (_idmapControl[_idmapControl.Length - 1] != null) { Array.Resize(ref _idmapControl, _idmapControl.Length * 2); } for (int i = 0; i < LayerToIDMap(layer).Length; i++) { if (LayerToIDMap(layer)[i] == null) { newValue = i; break; } } LayerToIDMap(layer)[newValue] = value; } LayerToTileArray(layer)[(y * Width) + x] = (ushort)newValue; } }