public override bool CanAppend(UndoRedoAction action) { if (this.type != EditTilemapActionType.DrawTile) { return(false); } EditTilemapAction editAction = action as EditTilemapAction; if (editAction == null) { return(false); } if (editAction.tilemap != this.tilemap) { return(false); } if (editAction.type != this.type) { return(false); } return(true); }
public override void Append(UndoRedoAction action, bool performAction) { base.Append(action, performAction); EditTilemapAction editAction = action as EditTilemapAction; // Perform the newly appended action individually if (performAction) { editAction.Do(); } // Update AutoTiles that we edited before if we're using direct-only AutoTiling mode, // so at least all the tiles in the edited mask are up-to-date. if (this.autoTileMode == AutoTilePaintMode.DirectOnly) { Tileset tileset = this.tilemap.Tileset.Res; if (tileset != null) { Grid <Tile> tiles = this.tilemap.BeginUpdateTiles(); Tile.UpdateAutoTileCon( tiles, this.editMaskAutoTile, this.origin.X, this.origin.Y, this.newTiles.Width, this.newTiles.Height, tileset); this.tilemap.EndUpdateTiles(this.origin.X, this.origin.Y, this.newTiles.Width, this.newTiles.Height); } } // Determine working data for merging the two tile grids Point2 originDiff = new Point2( editAction.origin.X - this.origin.X, editAction.origin.Y - this.origin.Y); Point2 minPos = new Point2( Math.Min(this.origin.X, editAction.origin.X), Math.Min(this.origin.Y, editAction.origin.Y)); Point2 maxPos = new Point2( Math.Max(this.origin.X + this.newTiles.Width, editAction.origin.X + editAction.newTiles.Width), Math.Max(this.origin.Y + this.newTiles.Height, editAction.origin.Y + editAction.newTiles.Height)); Point2 newSize = new Point2( maxPos.X - minPos.X, maxPos.Y - minPos.Y); Point2 growOffset = new Point2( Math.Min(0, originDiff.X), Math.Min(0, originDiff.Y)); Point2 drawOffset = new Point2( Math.Max(0, originDiff.X), Math.Max(0, originDiff.Y)); // Make sure to extend the tile data storage of this action, so the appended action can fit in this.newTiles.AssumeRect(growOffset.X, growOffset.Y, newSize.X, newSize.Y); this.editMask.AssumeRect(growOffset.X, growOffset.Y, newSize.X, newSize.Y); this.oldTiles.AssumeRect(growOffset.X, growOffset.Y, newSize.X, newSize.Y); this.editMaskAutoTile.AssumeRect(growOffset.X, growOffset.Y, newSize.X, newSize.Y); // Move the operation origin accordingly this.origin.X += growOffset.X; this.origin.Y += growOffset.Y; // Determine the tiles that are edited in the appended operation, but weren't before Grid <bool> newlyEditedMask = new Grid <bool>(editAction.editMaskAutoTile); { Point2 bounds = new Point2( Math.Min(newlyEditedMask.Width, this.editMaskAutoTile.Width - drawOffset.X), Math.Min(newlyEditedMask.Height, this.editMaskAutoTile.Height - drawOffset.Y)); for (int y = 0; y < bounds.Y; y++) { for (int x = 0; x < bounds.X; x++) { bool existingMask = this.editMaskAutoTile[x + drawOffset.X, y + drawOffset.Y]; bool appendedMask = editAction.editMaskAutoTile[x, y]; newlyEditedMask[x, y] = !existingMask && appendedMask; } } } // Apply new tile data from the appended action to this one MaskedCopyGrid(editAction.newTiles, this.newTiles, editAction.editMask, drawOffset.X, drawOffset.Y); MaskedCopyGrid(editAction.oldTiles, this.oldTiles, newlyEditedMask, drawOffset.X, drawOffset.Y); MaskedCopyGrid(editAction.editMask, this.editMask, editAction.editMask, drawOffset.X, drawOffset.Y); MaskedCopyGrid(editAction.editMaskAutoTile, this.editMaskAutoTile, editAction.editMaskAutoTile, drawOffset.X, drawOffset.Y); }