public bool CompareTile(EditorTile targetTile, FillTile replacementTile) { return targetTile.Tileset == replacementTile.Tileset && targetTile.SrcX == replacementTile.X && targetTile.SrcY == replacementTile.Y && targetTile.Terrain == replacementTile.Terrain; }
/// <summary> /// Re-sizes the map based on the anchor and size. /// </summary> /// <param name="width">New width of the map.</param> /// <param name="height">New height of the map.</param> /// <param name="tilewidth">New width of the tiles.</param> /// <param name="tileheight">New height of the tiles.</param> /// <param name="anchor">Anchor point to resize around.</param> public void ResizeMap(int width, int height, int tilewidth, int tileheight, AnchorPoints anchor) { if (tilewidth != TileWidth) TileWidth = tilewidth; if (tileheight != TileHeight) TileHeight = tileheight; if (Width == width && Height == height) return; using (UndoRedoArea.Start("Map Size Changed")) { /* * The actual re-sizing the array (when it's actually resized) is in the * property changed events for the "Width" and "Height" properties. * * Here we'll simply move the tiles around based on the anchor point passed * by the user. * * We cannot destroy objects, so we'll be copying over data between tiles * directly in to the tile properties. This allows us to retain the undo/redo * stack of each tile without moving the objects themselves. * * After that, setting the Width and Height properties will cause the array * itself to resize (or not, depending) and pass through the changes * to the ScrollMap controls accordingly. * * If the new width is less than the old one, then we'll move the tiles * before changing the size. * * If the new width is more than the old one, then we'll change the size * and then move the tiles. * */ var oldWidth = Width; var oldHeight = Height; var difference = 0; _building = true; if (width < oldWidth) { switch (anchor) { case AnchorPoints.Right: case AnchorPoints.UpRight: case AnchorPoints.DownRight: difference = oldWidth - width; foreach (var layer in Layers) { for (int x = 0; x < oldWidth; x++) { for (int y = 0; y < oldHeight; y++) { if (x < oldWidth - difference) { var tile = layer.Tiles[x + difference, y]; layer.Tiles[x, y].SrcX = tile.SrcX; layer.Tiles[x, y].SrcY = tile.SrcY; layer.Tiles[x, y].Terrain = tile.Terrain; layer.Tiles[x, y].Tileset = tile.Tileset; } } } } break; case AnchorPoints.Center: case AnchorPoints.Up: case AnchorPoints.Down: difference = (oldWidth / 2) - (width / 2); foreach (var layer in Layers) { for (int x = 0; x < oldWidth; x++) { for (int y = 0; y < oldHeight; y++) { if (x < oldWidth - (oldWidth - width)) { var tile = layer.Tiles[x + difference, y]; layer.Tiles[x, y].SrcX = tile.SrcX; layer.Tiles[x, y].SrcY = tile.SrcY; layer.Tiles[x, y].Terrain = tile.Terrain; layer.Tiles[x, y].Tileset = tile.Tileset; } } } } break; } } if (height < oldHeight) { switch (anchor) { case AnchorPoints.Down: case AnchorPoints.DownRight: case AnchorPoints.DownLeft: difference = oldHeight - height; foreach (var layer in Layers) { for (int x = 0; x < oldWidth; x++) { for (int y = 0; y < oldHeight; y++) { if (y < oldHeight - difference) { var tile = layer.Tiles[x, y + difference]; layer.Tiles[x, y].SrcX = tile.SrcX; layer.Tiles[x, y].SrcY = tile.SrcY; layer.Tiles[x, y].Terrain = tile.Terrain; layer.Tiles[x, y].Tileset = tile.Tileset; } } } } break; case AnchorPoints.Center: case AnchorPoints.Left: case AnchorPoints.Right: difference = (oldHeight / 2) - (height / 2); foreach (var layer in Layers) { for (int x = 0; x < oldWidth; x++) { for (int y = 0; y < oldHeight; y++) { if (y < oldHeight - (oldHeight - height)) { var tile = layer.Tiles[x, y + difference]; layer.Tiles[x, y].SrcX = tile.SrcX; layer.Tiles[x, y].SrcY = tile.SrcY; layer.Tiles[x, y].Terrain = tile.Terrain; layer.Tiles[x, y].Tileset = tile.Tileset; } } } } break; } } Width = width; Height = height; // resize foreach (var layer in Layers) { if (width > layer.Tiles.GetLength(0) || height > layer.Tiles.GetLength(1)) { EditorTile[,] tmpArray = layer.Tiles; var newwidth = Math.Max(width, layer.Tiles.GetLength(0)); var newheight = Math.Max(height, layer.Tiles.GetLength(1)); layer.Tiles = new EditorTile[newwidth, newheight]; layer.Sprites = new Sprite[width, height]; layer.TerrainCache = new TerrainCache[width, height]; for (int x = 0; x < newwidth; x++) { for (int y = 0; y < newheight; y++) { if (x >= tmpArray.GetLength(0) || y >= tmpArray.GetLength(1)) { var tile = new EditorTile(x, y, 0, 0, 0, 0, layer); layer.Tiles[x, y] = tile; layer.Tiles[x, y].PropertyChanged += Tile_PropertyChanged; } else { layer.Tiles[x, y] = tmpArray[x, y]; layer.Tiles[x, y].X = x; layer.Tiles[x, y].Y = y; } } } } if (width < layer.Tiles.GetLength(0) || height < layer.Tiles.GetLength(1)) { var arrwidth = layer.Tiles.GetLength(0); var arrheight = layer.Tiles.GetLength(1); var newwidth = Math.Min(width, arrwidth); var newheight = Math.Min(height, arrheight); for (int x = 0; x < arrwidth; x++) { for (int y = 0; y < arrheight; y++) { if (x > newwidth || y > newheight) { layer.Tiles[x, y].SrcX = 0; layer.Tiles[x, y].SrcY = 0; layer.Tiles[x, y].Terrain = 0; layer.Tiles[x, y].Tileset = 0; } } } } } // end resize if (width > oldWidth) { switch (anchor) { case AnchorPoints.Right: case AnchorPoints.UpRight: case AnchorPoints.DownRight: difference = width - oldWidth; foreach (var layer in Layers) { for (int x = width - 1; x > 0; x--) { for (int y = 0; y < Height; y++) { if (x - difference >= 0) { var tile = layer.Tiles[x - difference, y]; layer.Tiles[x, y].SrcX = tile.SrcX; layer.Tiles[x, y].SrcY = tile.SrcY; layer.Tiles[x, y].Terrain = tile.Terrain; layer.Tiles[x, y].Tileset = tile.Tileset; } } } for (int x = 0; x < difference; x++) { for (int y = 0; y < Height; y++) { layer.Tiles[x, y].SrcX = 0; layer.Tiles[x, y].SrcY = 0; layer.Tiles[x, y].Terrain = 0; layer.Tiles[x, y].Tileset = 0; } } } break; case AnchorPoints.Center: case AnchorPoints.Up: case AnchorPoints.Down: difference = (width / 2) - (oldWidth / 2); foreach (var layer in Layers) { for (int x = width - 1; x > 0; x--) { for (int y = 0; y < Height; y++) { if (x - difference >= 0) { var tile = layer.Tiles[x - difference, y]; layer.Tiles[x, y].SrcX = tile.SrcX; layer.Tiles[x, y].SrcY = tile.SrcY; layer.Tiles[x, y].Terrain = tile.Terrain; layer.Tiles[x, y].Tileset = tile.Tileset; } } } for (int x = 0; x < difference; x++) { for (int y = 0; y < Height; y++) { layer.Tiles[x, y].SrcX = 0; layer.Tiles[x, y].SrcY = 0; layer.Tiles[x, y].Terrain = 0; layer.Tiles[x, y].Tileset = 0; } } } break; } } if (height > oldHeight) { switch (anchor) { case AnchorPoints.Down: case AnchorPoints.DownRight: case AnchorPoints.DownLeft: difference = height - oldHeight; foreach (var layer in Layers) { for (int x = 0; x < Width; x++) { for (int y = height - 1; y > 0; y--) { if (y - difference >= 0) { var tile = layer.Tiles[x, y - difference]; layer.Tiles[x, y].SrcX = tile.SrcX; layer.Tiles[x, y].SrcY = tile.SrcY; layer.Tiles[x, y].Terrain = tile.Terrain; layer.Tiles[x, y].Tileset = tile.Tileset; } } } for (int x = 0; x < Width; x++) { for (int y = 0; y < difference; y++) { layer.Tiles[x, y].SrcX = 0; layer.Tiles[x, y].SrcY = 0; layer.Tiles[x, y].Terrain = 0; layer.Tiles[x, y].Tileset = 0; } } } break; case AnchorPoints.Center: case AnchorPoints.Left: case AnchorPoints.Right: difference = (height / 2) - (oldHeight / 2); foreach (var layer in Layers) { for (int x = 0; x < Width; x++) { for (int y = height - 1; y > 0; y--) { if (y - difference >= 0) { var tile = layer.Tiles[x, y - difference]; layer.Tiles[x, y].SrcX = tile.SrcX; layer.Tiles[x, y].SrcY = tile.SrcY; layer.Tiles[x, y].Terrain = tile.Terrain; layer.Tiles[x, y].Tileset = tile.Tileset; } } } for (int x = 0; x < Width; x++) { for (int y = 0; y < difference; y++) { layer.Tiles[x, y].SrcX = 0; layer.Tiles[x, y].SrcY = 0; layer.Tiles[x, y].Terrain = 0; layer.Tiles[x, y].Tileset = 0; } } } break; } } UnsavedChanges = true; _building = false; CacheAllTiles(); SizeChanged.Invoke(this, new EventArgs()); UndoRedoArea.Commit(); }; }
private void FillTiles(EditorTile tile, FillTile originalTile, FillTile replacementTile) { var open = new Queue<Point>(); open.Enqueue(new Point(tile.X, tile.Y)); while (open.Count > 0) { var current = open.Dequeue(); var x = current.X; var y = current.Y; CheckFillTile(open, x, y, originalTile, replacementTile); if (x > 0) CheckFillTile(open, x - 1, y, originalTile, replacementTile); if (x < Width - 1) CheckFillTile(open, x + 1, y, originalTile, replacementTile); if (y > 0) CheckFillTile(open, x, y - 1, originalTile, replacementTile); if (y < Height - 1) CheckFillTile(open, x, y + 1, originalTile, replacementTile); } SelectedLayer.Tiles = _tileMap; foreach (var tmp in SelectedLayer.Tiles) { tmp.PropertyChanged += Tile_PropertyChanged; } foreach (var point in _tilesToCache) { CacheTile(SelectedLayer, SelectedLayer.Tiles[point.X, point.Y]); } }
/// <summary> /// Event handler for the LayerAdded event of the <see cref="EditorTileMap"/> object. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="LayerAddedEventArgs"/> instance containing the event data.</param> private void EditorMap_LayerAdded(object sender, LayerAddedEventArgs e) { e.Layer.Tiles = new EditorTile[Width, Height]; e.Layer.Sprites = new Sprite[Width, Height]; e.Layer.TerrainCache = new TerrainCache[Width, Height]; for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { var tile = new EditorTile(x, y, 0, 0, 0, 0, e.Layer); e.Layer.Tiles[x, y] = tile; e.Layer.Tiles[x, y].PropertyChanged += Tile_PropertyChanged; } } e.Layer.PropertyChanged += Layer_PropertyChanged; }
/// <summary> /// Caches an individual tile's sprite. /// </summary> /// <param name="layer">Layer of the tile.</param> /// <param name="tile">Tile to cache.</param> private void CacheTile(EditorTileLayer layer, EditorTile tile) { layer.TerrainCache[tile.X, tile.Y] = null; var tileset = TilesetManager.Instance.GetTileset(tile.Tileset); if (tileset == null) { layer.Sprites[tile.X, tile.Y] = null; return; } layer.Sprites[tile.X, tile.Y] = new Sprite { Texture = ResourceManager.Instance.LoadTexture(tileset.Image), Position = new Vector2f(tile.X * tileset.TileWidth, tile.Y * tileset.TileHeight), TextureRect = new IntRect(tile.SrcX * tileset.TileWidth, tile.SrcY * tileset.TileHeight, tileset.TileWidth, tileset.TileHeight) }; }
/// <summary> /// Caches an individual terrain tile's sprite. /// </summary> /// <param name="layer">Layer of the tile.</param> /// <param name="tile">Tile to cache.</param> private void CacheTerrainTile(EditorTileLayer layer, EditorTile tile) { layer.Sprites[tile.X, tile.Y] = null; var terrain = TerrainManager.Instance.GetTerrain(tile.Terrain); if (terrain == null) { layer.TerrainCache[tile.X, tile.Y] = null; return; } layer.TerrainCache[tile.X, tile.Y] = new TerrainCache(); EditorTile NW; EditorTile N; EditorTile NE; EditorTile E; EditorTile SE; EditorTile S; EditorTile SW; EditorTile W; EditorTile forcedTile; if (!UndoRedoManager.IsCommandStarted && !UndoRedoArea.IsCommandStarted) { using (UndoRedoManager.Start("Creating fake tile")) { forcedTile = new EditorTile(0, 0, 0, 0, 0, tile.Terrain); UndoRedoManager.Commit(); } } else { forcedTile = new EditorTile(0, 0, 0, 0, 0, tile.Terrain); } if (!(tile.X - 1 < 0 || tile.Y - 1 < 0)) NW = layer.Tiles[tile.X - 1, tile.Y - 1]; else NW = forcedTile; if (!(tile.Y - 1 < 0)) N = layer.Tiles[tile.X, tile.Y - 1]; else N = forcedTile; if (!(tile.X + 1 > Width - 1 || tile.Y - 1 < 0)) NE = layer.Tiles[tile.X + 1, tile.Y - 1]; else NE = forcedTile; if (!(tile.X + 1 > Width - 1)) E = layer.Tiles[tile.X + 1, tile.Y]; else E = forcedTile; if (!(tile.X + 1 > Width - 1 || tile.Y + 1 > Height - 1)) SE = layer.Tiles[tile.X + 1, tile.Y + 1]; else SE = forcedTile; if (!(tile.Y + 1 > Height - 1)) S = layer.Tiles[tile.X, tile.Y + 1]; else S = forcedTile; if (!(tile.X - 1 < 0 || tile.Y + 1 > Height - 1)) SW = layer.Tiles[tile.X - 1, tile.Y + 1]; else SW = forcedTile; if (!(tile.X - 1 < 0)) W = layer.Tiles[tile.X - 1, tile.Y]; else W = forcedTile; layer.TerrainCache[tile.X, tile.Y].Cache(tile.X, tile.Y, tile.Terrain, NW.Terrain, N.Terrain, NE.Terrain, E.Terrain, SE.Terrain, S.Terrain, SW.Terrain, W.Terrain); }
private void CacheSurroundingTerrain(EditorTileLayer layer, EditorTile tile) { var tiles = new List<EditorTile>(); if (!(tile.X - 1 < 0 || tile.Y - 1 < 0)) tiles.Add(layer.Tiles[tile.X - 1, tile.Y - 1]); if (!(tile.Y - 1 < 0)) tiles.Add(layer.Tiles[tile.X, tile.Y - 1]); if (!(tile.X + 1 > Width - 1 || tile.Y - 1 < 0)) tiles.Add(layer.Tiles[tile.X + 1, tile.Y - 1]); if (!(tile.X + 1 > Width - 1)) tiles.Add(layer.Tiles[tile.X + 1, tile.Y]); if (!(tile.X + 1 > Width - 1 || tile.Y + 1 > Height - 1)) tiles.Add(layer.Tiles[tile.X + 1, tile.Y + 1]); if (!(tile.Y + 1 > Height - 1)) tiles.Add(layer.Tiles[tile.X, tile.Y + 1]); if (!(tile.X - 1 < 0 || tile.Y + 1 > Height - 1)) tiles.Add(layer.Tiles[tile.X - 1, tile.Y + 1]); if (!(tile.X - 1 < 0)) tiles.Add(layer.Tiles[tile.X - 1, tile.Y]); foreach (var item in tiles) { if (item.Terrain > 0) CacheTerrainTile(layer, item); } }