public override void MouseUp(MouseEventArgs e) { base.MouseUp(e); if (e.LeftButton != e.OldLeftButton) { if (!Editor.CanUndo) { Editor.CanUndo = true; TileGroupUndoAction.GetLatest().Ready = true; } } if (!e.LeftButton && !e.RightButton) { OriginPoint = null; } }
public void DrawTiles(int oldx, int oldy, int newx, int newy, int layer) { MapViewerTiles MapViewer = this.MapViewer as MapViewerTiles; // Avoid drawing a line from top left to current tile if (oldx == -1 || oldy == -1) { oldx = newx; oldy = newy; } Point Origin = MapViewer.OriginPoint; bool blanktile = Editor.MainWindow.MapWidget.MapViewerTiles.TilesPanel.EraserButton.Selected; bool point = oldx == newx && oldy == newy; bool line = !point; List <Point> TempCoords = new List <Point>(); if (Editor.MainWindow.MapWidget.MapViewerTiles.TilesPanel.FillButton.Selected) { int sx, sy, ex, ey; if (MapViewer.SelectionX != -1 && MapViewer.SelectionY != -1 && MapViewer.SelectionWidth != 0 && MapViewer.SelectionHeight != 0 && MapViewer.SelectionBackground.Visible) { int mx = (int)Math.Floor(newx / 32d); int my = (int)Math.Floor(newy / 32d); sx = MapViewer.SelectionX; ex = MapViewer.SelectionX + MapViewer.SelectionWidth; sy = MapViewer.SelectionY; ey = MapViewer.SelectionY + MapViewer.SelectionHeight; if (!(mx >= sx && mx < ex && my >= sy && my < ey)) { return; // Outside selection } } else { sx = 0; sy = 0; ex = MapData.Width; ey = MapData.Height; } for (int y = sy; y < ey; y++) { for (int x = sx; x < ex; x++) { TempCoords.Add(new Point(x, y)); } } } else if (line) // Draw tiles between several tiles - use simple line drawing algorithm to determine the tiles to draw on { int x1 = oldx; int y1 = oldy; int x2 = newx; int y2 = newy; for (int x = x1 > x2 ? x2 : x1; (x1 > x2) ? (x <= x1) : (x <= x2); x++) { double fact = ((double)x - x1) / (x2 - x1); int y = (int)Math.Round(y1 + ((y2 - y1) * fact)); int tilex = (int)Math.Floor(x / 32d); int tiley = (int)Math.Floor(y / 32d); if (!TempCoords.Exists(c => c.X == tilex && c.Y == tiley)) { TempCoords.Add(new Point(tilex, tiley)); } } int sy = y1 > y2 ? y2 : y1; for (int y = y1 > y2 ? y2 : y1; (y1 > y2) ? (y <= y1) : (y <= y2); y++) { double fact = ((double)y - y1) / (y2 - y1); int x = (int)Math.Round(x1 + ((x2 - x1) * fact)); int tilex = (int)Math.Floor(x / 32d); int tiley = (int)Math.Floor(y / 32d); if (!TempCoords.Exists(c => c.X == tilex && c.Y == tiley)) { TempCoords.Add(new Point(tilex, tiley)); } } } else if (point) // Just one singular tile { TempCoords.Add(new Point((int)Math.Floor(newx / 32d), (int)Math.Floor(newy / 32d))); } SetLayerLocked(layer, false); for (int i = 0; i < TempCoords.Count; i++) { // Both of these depend on the origin, but we need them both at the top left as we begin drawing there // and to be able to compare them to use in the modulus, they both have to be adjusted int MapTileX = TempCoords[i].X; int MapTileY = TempCoords[i].Y; int OriginX = MapViewer.OriginPoint.X; int OriginY = MapViewer.OriginPoint.Y; if (MapViewer.CursorOrigin == Location.TopRight || MapViewer.CursorOrigin == Location.BottomRight) { MapTileX -= MapViewer.CursorWidth; OriginX -= MapViewer.CursorWidth; } if (MapViewer.CursorOrigin == Location.BottomLeft || MapViewer.CursorOrigin == Location.BottomRight) { MapTileY -= MapViewer.CursorHeight; OriginY -= MapViewer.CursorHeight; } // MapTileX and MapTileY are now the top left no matter the origin point int SelArea = MapViewer.TileDataList.Count; int OriginDiffX = (OriginX - MapTileX) % (MapViewer.CursorWidth + 1); int OriginDiffY = (OriginY - MapTileY) % (MapViewer.CursorHeight + 1); for (int j = 0; j < SelArea; j++) { bool Blank = blanktile; int actualx = MapTileX + (j % (MapViewer.CursorWidth + 1)); int actualy = MapTileY + (int)Math.Floor((double)j / (MapViewer.CursorWidth + 1)); int MapPosition = actualx + actualy * MapData.Width; if (actualx < 0 || actualx >= MapData.Width || actualy < 0 || actualy >= MapData.Height) { continue; } if (MapViewer.SelectionX != -1 && MapViewer.SelectionY != -1 && MapViewer.SelectionWidth != 0 && MapViewer.SelectionHeight != 0 && MapViewer.SelectionBackground.Visible) { // NOT within the selection if (!(actualx >= MapViewer.SelectionX && actualx < MapViewer.SelectionX + MapViewer.SelectionWidth && actualy >= MapViewer.SelectionY && actualy < MapViewer.SelectionY + MapViewer.SelectionHeight)) { continue; } } int selx = j % (MapViewer.CursorWidth + 1); if (OriginDiffX < 0) { selx -= OriginDiffX; } if (OriginDiffX > 0) { selx -= OriginDiffX; } if (selx < 0) { selx += MapViewer.CursorWidth + 1; } selx %= MapViewer.CursorWidth + 1; int sely = (int)Math.Floor((double)j / (MapViewer.CursorWidth + 1)); if (OriginDiffY < 0) { sely -= OriginDiffY; } if (OriginDiffY > 0) { sely -= OriginDiffY; } if (sely < 0) { sely += MapViewer.CursorHeight + 1; } sely %= MapViewer.CursorHeight + 1; TileData tiledata = MapViewer.TileDataList[sely * (MapViewer.CursorWidth + 1) + selx]; TileType tiletype = TileType.Tileset; int tileid = -1; int index = -1; if (tiledata != null) { tiletype = tiledata.TileType; tileid = tiledata.ID; index = tiledata.Index; } else { Blank = true; } TileData OldTile = MapData.Layers[layer].Tiles[MapPosition]; TileData NewTile = null; if (!Blank) { NewTile = new TileData { TileType = tiletype, Index = index, ID = tileid }; } bool SameTile = true; if (OldTile == null && NewTile != null || OldTile != null && NewTile == null) { SameTile = false; } else if (OldTile != null && OldTile.TileType != NewTile.TileType) { SameTile = false; } else if (OldTile != null && OldTile.Index != NewTile.Index) { SameTile = false; } else if (OldTile != null && OldTile.TileType != TileType.Autotile && OldTile.ID != NewTile.ID) { SameTile = false; } if (!SameTile) { MapData.Layers[layer].Tiles[MapPosition] = NewTile; if (TileGroupUndoAction.GetLatest() == null || TileGroupUndoAction.GetLatest().Ready) { Editor.CanUndo = false; TileGroupUndoAction.Log(MapID, layer); } TileGroupUndoAction.AddToLatest(MapPosition, NewTile, OldTile); DrawTile(actualx, actualy, layer, NewTile, OldTile); } } } SetLayerLocked(layer, true); }