protected override void FillSolid(IList <Vector2Int32> area) { foreach (var pixel in area) { if (!_wvm.CurrentWorld.ValidTileLocation(pixel)) { continue; } int index = pixel.X + pixel.Y * _wvm.CurrentWorld.TilesWide; if (!_wvm.CheckTiles[index]) { _wvm.CheckTiles[index] = true; if (_wvm.Selection.IsValid(pixel)) { var p = GetBrickStyle(pixel); if (p != null) { _wvm.UndoManager.SaveTile(pixel); _wvm.CurrentWorld.Tiles[pixel.X, pixel.Y].BrickStyle = p.Value; BlendRules.ResetUVCache(_wvm, pixel.X, pixel.Y, 1, 1); } } } } }
private void FillSolid(IEnumerable <Vector2Int32> area) { foreach (Vector2Int32 pixel in area) { bool test1 = _wvm.CurrentWorld.ValidTileLocation(pixel); bool test2 = _wvm.CurrentWorld.ValidTileLocation(pixel.X, pixel.Y); bool test3 = _wvm.CurrentWorld.ValidTileLocation(pixel.X, pixel.Y); if (!test1 && !test2 && !test3) { continue; } int index = pixel.X + pixel.Y * _wvm.CurrentWorld.TilesWide; if (!_wvm.CheckTiles[index]) { _wvm.CheckTiles[index] = true; if (_wvm.Selection.IsValid(pixel)) { _wvm.UndoManager.SaveTile(pixel); _wvm.SetPixel(pixel.X, pixel.Y); /* Heathtech */ BlendRules.ResetUVCache(_wvm, pixel.X, pixel.Y, 1, 1); } } } }
public override void MouseDown(TileMouseState e) { if (_wvm.SelectedSprite == null) { return; } Vector2Short[,] tiles = _wvm.SelectedSprite.GetTiles(); for (int x = 0; x < _wvm.SelectedSprite.Size.X; x++) { int tilex = x + e.Location.X; for (int y = 0; y < _wvm.SelectedSprite.Size.Y; y++) { int tiley = y + e.Location.Y; _wvm.UndoManager.SaveTile(tilex, tiley); Tile curtile = _wvm.CurrentWorld.Tiles[tilex, tiley]; curtile.IsActive = true; curtile.Type = _wvm.SelectedSprite.Tile; curtile.U = tiles[x, y].X; curtile.V = tiles[x, y].Y; _wvm.UpdateRenderPixel(tilex, tiley); } } _wvm.UndoManager.SaveUndo(); /* Heathtech */ BlendRules.ResetUVCache(_wvm, e.Location.X, e.Location.Y, _wvm.SelectedSprite.Size.X, _wvm.SelectedSprite.Size.Y); }
private void LinearFloodFill(ref int x, ref int y, ref Tile originTile) { int bitmapWidth = _wvm.CurrentWorld.TilesWide; int bitmapHeight = _wvm.CurrentWorld.TilesHigh; //FIND LEFT EDGE OF COLOR AREA int lFillLoc = x; //the location to check/fill on the left int tileIndex = (bitmapWidth * y) + x; while (true) { if (!_wvm.CheckTiles[tileIndex]) { _wvm.UndoManager.SaveTile(lFillLoc, y); _wvm.SetPixel(lFillLoc, y); _wvm.UpdateRenderPixel(lFillLoc, y); _wvm.CheckTiles[tileIndex] = true; } lFillLoc--; tileIndex--; if (lFillLoc <= 0 || _wvm.CheckTiles[tileIndex] || !CheckTileMatch(ref originTile, ref _wvm.CurrentWorld.Tiles[lFillLoc, y]) || !_wvm.Selection.IsValid(lFillLoc, y)) break; //exit loop if we're at edge of bitmap or color area } /* Heathtech */ BlendRules.ResetUVCache(_wvm, lFillLoc + 1, y, x - lFillLoc, 1); lFillLoc++; if (lFillLoc < _minX) _minX = lFillLoc; //FIND RIGHT EDGE OF COLOR AREA int rFillLoc = x; //the location to check/fill on the left tileIndex = (bitmapWidth * y) + x; while (true) { if (!_wvm.CheckTiles[tileIndex]) { _wvm.UndoManager.SaveTile(rFillLoc, y); _wvm.SetPixel(rFillLoc, y); _wvm.UpdateRenderPixel(rFillLoc, y); _wvm.CheckTiles[tileIndex] = true; BlendRules.ResetUVCache(_wvm, rFillLoc, y, 1, 1); } rFillLoc++; tileIndex++; if (rFillLoc >= bitmapWidth || _wvm.CheckTiles[tileIndex] || !CheckTileMatch(ref originTile, ref _wvm.CurrentWorld.Tiles[rFillLoc, y]) || !_wvm.Selection.IsValid(rFillLoc, y)) break; //exit loop if we're at edge of bitmap or color area } /* Heathtech */ BlendRules.ResetUVCache(_wvm, x, y, rFillLoc - x, 1); rFillLoc--; if (rFillLoc > _maxX) _maxX = rFillLoc; var r = new FloodFillRange(lFillLoc, rFillLoc, y); _ranges.Enqueue(ref r); }
private void PasteClipboard(Vector2Int32 anchor) { _wvm.Clipboard.PasteBufferIntoWorld(anchor); _wvm.UpdateRenderRegion(new Rectangle(anchor.X, anchor.Y, _wvm.Clipboard.Buffer.Size.X, _wvm.Clipboard.Buffer.Size.Y)); /* Heathtech */ BlendRules.ResetUVCache(_wvm, anchor.X, anchor.Y, _wvm.Clipboard.Buffer.Size.X, _wvm.Clipboard.Buffer.Size.Y); }
public void Redo() { if (_currentIndex > _maxIndex || _currentIndex < 0) { return; } using (var stream = new FileStream(string.Format(RedoFile, _currentIndex), FileMode.Open)) using (BinaryReader br = new BinaryReader(stream)) { foreach (var undoTile in UndoBuffer.ReadUndoTilesFromStream(br)) { var curTile = (Tile)_wvm.CurrentWorld.Tiles[undoTile.Location.X, undoTile.Location.Y]; if (Tile.IsChest(curTile.Type)) { var curchest = _wvm.CurrentWorld.GetChestAtTile(undoTile.Location.X, undoTile.Location.Y); if (curchest != null) { _wvm.CurrentWorld.Chests.Remove(curchest); } } if (Tile.IsSign(curTile.Type)) { var cursign = _wvm.CurrentWorld.GetSignAtTile(undoTile.Location.X, undoTile.Location.Y); if (cursign != null) { _wvm.CurrentWorld.Signs.Remove(cursign); } } if (Tile.IsTileEntity(curTile.Type)) { var curTe = _wvm.CurrentWorld.GetTileEntityAtTile(undoTile.Location.X, undoTile.Location.Y); if (curTe != null) { _wvm.CurrentWorld.TileEntities.Remove(curTe); } } _wvm.CurrentWorld.Tiles[undoTile.Location.X, undoTile.Location.Y] = (Tile)undoTile.Tile; _wvm.UpdateRenderPixel(undoTile.Location); /* Heathtech */ BlendRules.ResetUVCache(_wvm, undoTile.Location.X, undoTile.Location.Y, 1, 1); } foreach (var chest in World.LoadChestData(br)) { _wvm.CurrentWorld.Chests.Add(chest); } foreach (var sign in World.LoadSignData(br)) { _wvm.CurrentWorld.Signs.Add(sign); } } _currentIndex++; _wvm.CurrentWorld.UpgradeLegacyTileEntities(); OnRedid(this, EventArgs.Empty); }
private void FillHollow(IEnumerable <Vector2Int32> area, IEnumerable <Vector2Int32> interrior) { IEnumerable <Vector2Int32> border = area.Except(interrior); // Draw the border if (_wvm.TilePicker.PaintMode == PaintMode.Tile || _wvm.TilePicker.PaintMode == PaintMode.TileAndWall) { foreach (Vector2Int32 pixel in border) { if (!_wvm.CurrentWorld.ValidTileLocation(pixel)) { continue; } int index = pixel.X + pixel.Y * _wvm.CurrentWorld.TilesWide; if (!_wvm.CheckTiles[index]) { _wvm.CheckTiles[index] = true; if (_wvm.Selection.IsValid(pixel)) { _wvm.UndoManager.SaveTile(pixel); _wvm.SetPixel(pixel.X, pixel.Y, mode: PaintMode.Tile); /* Heathtech */ BlendRules.ResetUVCache(_wvm, pixel.X, pixel.Y, 1, 1); } } } } // Draw the wall in the interrior, exclude the border so no overlaps foreach (Vector2Int32 pixel in interrior) { if (!_wvm.CurrentWorld.ValidTileLocation(pixel)) { continue; } if (_wvm.Selection.IsValid(pixel)) { _wvm.UndoManager.SaveTile(pixel); _wvm.SetPixel(pixel.X, pixel.Y, erase: true); if (_wvm.TilePicker.PaintMode == PaintMode.Wall || _wvm.TilePicker.PaintMode == PaintMode.TileAndWall) { _wvm.SetPixel(pixel.X, pixel.Y, mode: PaintMode.Wall); } /* Heathtech */ BlendRules.ResetUVCache(_wvm, pixel.X, pixel.Y, 1, 1); } } }
public void Undo() { if (_currentIndex <= 0) { return; } ErrorLogging.TelemetryClient?.TrackEvent(nameof(Undo)); string undoFileName = string.Format(UndoFile, _currentIndex - 1); // load previous undo file string redoFileName = string.Format(RedoFile, _currentIndex); // create redo file at current index UndoBuffer redo = new UndoBuffer(redoFileName); Debug.WriteLine($"Opening undo file for undo: {Path.GetFileNameWithoutExtension(undoFileName)}"); using (var stream = new FileStream(undoFileName, FileMode.Open)) using (BinaryReader br = new BinaryReader(stream, System.Text.Encoding.UTF8, false)) { foreach (var undoTile in UndoBuffer.ReadUndoTilesFromStream(br)) { Vector2Int32 pixel = undoTile.Location; SaveTileToBuffer(redo, pixel.X, pixel.Y, true); _wvm.CurrentWorld.Tiles[pixel.X, pixel.Y] = (Tile)undoTile.Tile; _wvm.UpdateRenderPixel(pixel); /* Heathtech */ BlendRules.ResetUVCache(_wvm, pixel.X, pixel.Y, 1, 1); } redo.Close(); redo.Dispose(); redo = null; foreach (var chest in World.LoadChestData(br)) { _wvm.CurrentWorld.Chests.Add(chest); } foreach (var sign in World.LoadSignData(br)) { _wvm.CurrentWorld.Signs.Add(sign); } foreach (var te in World.LoadTileEntityData(br, World.CompatibleVersion)) { _wvm.CurrentWorld.TileEntities.Add(te); } } _currentIndex--; // move index back one, create a new buffer CreateBuffer(); //_wvm.CurrentWorld.UpgradeLegacyTileEntities(); OnUndid(this, EventArgs.Empty); }
public void Undo() { if (_currentIndex <= 0) { return; } _currentIndex--; var buffer = UndoBuffer.Read(string.Format(UndoFile, _currentIndex)); var redo = new UndoBuffer(); foreach (var undoTile in buffer.Tiles) { var curTile = (Tile)_wvm.CurrentWorld.Tiles[undoTile.Location.X, undoTile.Location.Y].Clone(); if (curTile.Type == 21) { var curchest = _wvm.CurrentWorld.GetChestAtTile(undoTile.Location.X, undoTile.Location.Y); if (curchest != null) { _wvm.CurrentWorld.Chests.Remove(curchest); var chest = curchest.Copy(); redo.Chests.Add(chest); } } if (curTile.Type == 55 || curTile.Type == 85) { var cursign = _wvm.CurrentWorld.GetSignAtTile(undoTile.Location.X, undoTile.Location.Y); if (cursign != null) { _wvm.CurrentWorld.Signs.Remove(cursign); var sign = cursign.Copy(); redo.Signs.Add(sign); } } redo.Tiles.Add(new UndoTile(undoTile.Location, curTile)); _wvm.CurrentWorld.Tiles[undoTile.Location.X, undoTile.Location.Y] = (Tile)undoTile.Tile.Clone(); _wvm.UpdateRenderPixel(undoTile.Location); /* Heathtech */ BlendRules.ResetUVCache(_wvm, undoTile.Location.X, undoTile.Location.Y, 1, 1); } foreach (var chest in buffer.Chests) { _wvm.CurrentWorld.Chests.Add(chest.Copy()); } foreach (var sign in buffer.Signs) { _wvm.CurrentWorld.Signs.Add(sign.Copy()); } redo.Write(string.Format(RedoFile, _currentIndex)); }
public override void Execute() { if (_wvm.CurrentWorld == null) { return; } int[] _tileSand = { 53, // Sand Block 112, // Ebonsand Block 116, // Pearlsand 123, // silt 224, // slush block 234, // Crimsand block }; for (int y = _wvm.CurrentWorld.TilesHigh - 1; y > 0; y--) { for (int x = 0; x < _wvm.CurrentWorld.TilesWide; x++) { var curTile = _wvm.CurrentWorld.Tiles[x, y]; if (_tileSand.Contains(curTile.Type)) { // check if tile below current tile is empty and move sand to there if it is. int shiftAmmount = 1; while (shiftAmmount + y < _wvm.CurrentWorld.TilesHigh && !_wvm.CurrentWorld.Tiles[x, y + shiftAmmount].IsActive) { shiftAmmount++; } shiftAmmount--; if (shiftAmmount > 0) { var belowTile = _wvm.CurrentWorld.Tiles[x, y + shiftAmmount]; if (!belowTile.IsActive) { _wvm.UndoManager.SaveTile(x, y + shiftAmmount); _wvm.UndoManager.SaveTile(x, y); belowTile.IsActive = true; belowTile.Type = curTile.Type; curTile.IsActive = false; BlendRules.ResetUVCache(_wvm, x, y, 1, 1 + shiftAmmount); _wvm.UpdateRenderPixel(x, y); _wvm.UpdateRenderPixel(x, y + shiftAmmount); } } } } } _wvm.UndoManager.SaveUndo(); }
private void DrawLineP2P(Vector2Int32 endPoint) { foreach (Vector2Int32 pixel in Shape.DrawLineTool(_startPoint, _endPoint)) { if (!_wvm.CurrentWorld.ValidTileLocation(pixel)) { continue; } int index = pixel.X + pixel.Y * _wvm.CurrentWorld.TilesWide; if (!_wvm.CheckTiles[index]) { _wvm.CheckTiles[index] = true; if (_wvm.Selection.IsValid(pixel)) { if (_wvm.SelectedSprite == null) { return; } tiles = _wvm.SelectedSprite.GetTiles(); for (int x = 0; x < _wvm.SelectedSprite.Size.X; x++) { tilex = x + pixel.X; for (int y = 0; y < _wvm.SelectedSprite.Size.Y; y++) { tiley = y + pixel.Y; _wvm.UndoManager.SaveTile(tilex, tiley); Tile curtile = _wvm.CurrentWorld.Tiles[tilex, tiley]; curtile.IsActive = true; curtile.Type = _wvm.SelectedSprite.Tile; curtile.U = tiles[x, y].X; curtile.V = tiles[x, y].Y; _wvm.UpdateRenderPixel(tilex, tiley); } } // Heathtech BlendRules.ResetUVCache(_wvm, pixel.X, pixel.Y, _wvm.SelectedSprite.Size.X, _wvm.SelectedSprite.Size.Y); } } } }
private void FillSlope(Vector2Int32 point) { if (_wvm.Brush.Shape == BrushShape.Right) { _leftPoint = new Vector2Int32(point.X - _wvm.Brush.Width / 2, point.Y + _wvm.Brush.Height / 2); _rightPoint = new Vector2Int32(point.X + _wvm.Brush.Width / 2, point.Y - _wvm.Brush.Height / 2); } else { _leftPoint = new Vector2Int32(point.X - _wvm.Brush.Width / 2, point.Y - _wvm.Brush.Height / 2); _rightPoint = new Vector2Int32(point.X + _wvm.Brush.Width / 2, point.Y + _wvm.Brush.Height / 2); } IEnumerable <Vector2Int32> area = Shape.DrawLine(_leftPoint, _rightPoint); foreach (Vector2Int32 pixel in area) { bool test1 = _wvm.CurrentWorld.ValidTileLocation(pixel); bool test2 = _wvm.CurrentWorld.ValidTileLocation(pixel.X, pixel.Y); bool test3 = _wvm.CurrentWorld.ValidTileLocation(pixel.X, pixel.Y); if (!test1 && !test2 && !test3) { continue; } int index = pixel.X + pixel.Y * _wvm.CurrentWorld.TilesWide; if (!_wvm.CheckTiles[index]) { _wvm.CheckTiles[index] = true; if (_wvm.Selection.IsValid(pixel)) { _wvm.UndoManager.SaveTile(pixel); _wvm.SetPixel(pixel.X, pixel.Y); /* Heathtech */ BlendRules.ResetUVCache(_wvm, pixel.X, pixel.Y, 1, 1); } } } }
private void DrawLine(Vector2Int32 to) { foreach (Vector2Int32 pixel in Shape.DrawLineTool(_startPoint, to)) { if (!_wvm.CurrentWorld.ValidTileLocation(pixel)) { continue; } int index = pixel.X + pixel.Y * _wvm.CurrentWorld.TilesWide; if (!_wvm.CheckTiles[index]) { _wvm.CheckTiles[index] = true; if (_wvm.Selection.IsValid(pixel)) { _wvm.UndoManager.SaveTile(pixel); _wvm.SetPixel(pixel.X, pixel.Y); /* Heathtech */ BlendRules.ResetUVCache(_wvm, pixel.X, pixel.Y, 1, 1); } } } }
protected virtual void FillSolid(IList <Vector2Int32> area) { foreach (Vector2Int32 pixel in area) { if (!_wvm.CurrentWorld.ValidTileLocation(pixel)) { continue; } int index = pixel.X + pixel.Y * _wvm.CurrentWorld.TilesWide; if (!_wvm.CheckTiles[index]) { _wvm.CheckTiles[index] = true; if (_wvm.Selection.IsValid(pixel)) { _wvm.UndoManager.SaveTile(pixel); _wvm.SetPixel(pixel.X, pixel.Y); /* Heathtech */ BlendRules.ResetUVCache(_wvm, pixel.X, pixel.Y, 1, 1); } } } }
public void PasteBufferIntoWorld(Vector2Int32 anchor) { if (Buffer == null) { return; } if (!PasteTiles && !PasteLiquids && !PasteWalls && !PasteWires) { return; } ErrorLogging.TelemetryClient?.TrackEvent("Paste"); _wvm.Selection.IsActive = false; // clear selection when pasting to prevent "unable to use pencil" issue World world = _wvm.CurrentWorld; ClipboardBuffer buffer = _wvm.Clipboard.Buffer; for (int x = 0; x < buffer.Size.X; x++) { for (int y = 0; y < buffer.Size.Y; y++) { int worldX = x + anchor.X; int worldY = y + anchor.Y; if (!world.ValidTileLocation(new Vector2Int32(worldX, worldY))) { continue; } //HistMan.AddTileToBuffer(worldX, worldY, ref world.UndoTiles[worldX, worldY]); Tile worldTile = world.Tiles[worldX, worldY]; Tile curTile = (Tile)buffer.Tiles[x, y].Clone(); if (!PasteTiles) { curTile.IsActive = worldTile.IsActive; curTile.Type = worldTile.Type; curTile.TileColor = worldTile.TileColor; curTile.U = worldTile.U; curTile.V = worldTile.V; curTile.BrickStyle = worldTile.BrickStyle; } if (!PasteEmpty && curTile.IsEmpty) { // skip tiles that are empty if paste empty is not true continue; } if (!PasteWalls) { // if pasting walls is disabled, use the existing wall curTile.Wall = worldTile.Wall; curTile.WallColor = worldTile.WallColor; } if (!PasteLiquids) { // if pasting liquids is disabled, use any existing liquid curTile.LiquidAmount = worldTile.LiquidAmount; curTile.LiquidType = worldTile.LiquidType; } if (!PasteWires) { // if pasting wires is disabled, use any existing wire curTile.WireRed = worldTile.WireRed; curTile.WireGreen = worldTile.WireGreen; curTile.WireBlue = worldTile.WireBlue; curTile.WireYellow = worldTile.WireYellow; curTile.Actuator = worldTile.Actuator; curTile.InActive = worldTile.InActive; } // save undo _wvm.UndoManager.SaveTile(worldX, worldY); // update world tile world.Tiles[worldX, worldY] = curTile; // Update chest/sign data only if we've pasted tiles if (PasteTiles) { // Add new chest data if (Tile.IsChest(curTile.Type)) { var existingChest = world.GetChestAtTile(worldX, worldY); if (existingChest != null) { world.Chests.Remove(existingChest); } var data = buffer.GetChestAtTile(x, y); if (data != null) // allow? chest copying may not work... { // Copied chest var newChest = data.Copy(); newChest.X = worldX; newChest.Y = worldY; world.Chests.Add(newChest); } } // Add new sign data if (Tile.IsSign(curTile.Type)) { if (world.GetSignAtTile(worldX, worldY) == null) { var data = buffer.GetSignAtTile(x, y); if (data != null) { // Copied sign var newSign = data.Copy(); newSign.X = worldX; newSign.Y = worldY; world.Signs.Add(newSign); } } } // Add new tile entity data if (Tile.IsTileEntity(curTile.Type)) { if (world.GetTileEntityAtTile(worldX, worldY) == null) { var data = buffer.GetTileEntityAtTile(x, y); if (data != null) { // Copied sign var newEntity = data.Copy(); newEntity.PosX = (short)(worldX); newEntity.PosY = (short)(worldY); world.TileEntities.Add(newEntity); } } } } } } _wvm.UndoManager.SaveUndo(); _wvm.CurrentWorld.UpgradeLegacyTileEntities(); /* Heathtech */ BlendRules.ResetUVCache(_wvm, anchor.X, anchor.Y, buffer.Size.X, buffer.Size.Y); }
private void PerformReplace() { if (_wvm.CurrentWorld == null) { return; } bool replaceTiles = false; bool replaceWalls = false; if (_wvm.TilePicker.PaintMode == PaintMode.TileAndWall) { if (_wvm.TilePicker.TileStyleActive) { replaceTiles = true; } if (_wvm.TilePicker.WallStyleActive) { replaceWalls = true; } } if (replaceTiles && _wvm.TilePicker.TileMaskMode == MaskMode.Off) { MessageBox.Show("Enable masking tiles to enable replace."); return; } if (replaceWalls && _wvm.TilePicker.WallMaskMode == MaskMode.Off) { MessageBox.Show("Enable masking walls to enable replace."); return; } int wallMask = _wvm.TilePicker.WallMask; int tileMask = _wvm.TilePicker.TileMask; int tileTarget = _wvm.TilePicker.Tile; int wallTarget = _wvm.TilePicker.Wall; for (int x = (_wvm.Selection.IsActive) ? _wvm.Selection.SelectionArea.X : 0; x < ((_wvm.Selection.IsActive) ? _wvm.Selection.SelectionArea.X + _wvm.Selection.SelectionArea.Width : _wvm.CurrentWorld.TilesWide); x++) { for (int y = (_wvm.Selection.IsActive) ? _wvm.Selection.SelectionArea.Y : 0; y < ((_wvm.Selection.IsActive) ? _wvm.Selection.SelectionArea.Y + _wvm.Selection.SelectionArea.Height : _wvm.CurrentWorld.TilesHigh); y++) { bool doReplaceTile = false; bool doReplaceWall = false; Tile curTile = _wvm.CurrentWorld.Tiles[x, y]; if (replaceTiles) { if ((_wvm.Selection.IsValid(x, y)) && (curTile.IsActive && curTile.Type == tileMask && _wvm.TilePicker.TileMaskMode == MaskMode.Match) || (!curTile.IsActive && _wvm.TilePicker.TileMaskMode == MaskMode.Empty) || (curTile.Type != tileMask && _wvm.TilePicker.TileMaskMode == MaskMode.NotMatching)) { doReplaceTile = true; } } if (replaceWalls) { if ((_wvm.Selection.IsValid(x, y)) && (curTile.Wall == wallMask && _wvm.TilePicker.WallMaskMode == MaskMode.Match) || (curTile.Wall == 0 && _wvm.TilePicker.WallMaskMode == MaskMode.Empty) || (curTile.Wall != wallMask && _wvm.TilePicker.WallMaskMode == MaskMode.NotMatching)) { doReplaceWall = true; } } if (doReplaceTile || doReplaceWall) { _wvm.UndoManager.SaveTile(x, y); if (doReplaceTile) { curTile.Type = (ushort)tileTarget; curTile.IsActive = true; if (World.TileProperties[curTile.Type].IsSolid) { curTile.U = -1; curTile.V = -1; BlendRules.ResetUVCache(_wvm, x, y, 1, 1); } if (_wvm.TilePicker.TilePaintActive) { curTile.TileColor = (byte)_wvm.TilePicker.TileColor; } } if (doReplaceWall) { curTile.Wall = (byte)wallTarget; if (_wvm.TilePicker.WallPaintActive) { if (curTile.Wall != 0) { curTile.WallColor = (byte)_wvm.TilePicker.WallColor; } else { curTile.WallColor = (byte)0; } } } _wvm.UpdateRenderPixel(x, y); } } } _wvm.UndoManager.SaveUndo(); }
public void PasteBufferIntoWorld(Vector2Int32 anchor) { if (Buffer == null) { return; } World world = _wvm.CurrentWorld; ClipboardBuffer buffer = _wvm.Clipboard.Buffer; for (int x = 0; x < buffer.Size.X; x++) { for (int y = 0; y < buffer.Size.Y; y++) { int worldX = x + anchor.X; int worldY = y + anchor.Y; if (world.ValidTileLocation(new Vector2Int32(x + anchor.X, y + anchor.Y))) { //HistMan.AddTileToBuffer(x + anchor.X, y + anchor.Y, ref world.UndoTiles[x + anchor.X, y + anchor.Y]); Tile curTile; if (PasteTiles) { curTile = (Tile)buffer.Tiles[x, y].Clone(); curTile.TileColor = buffer.Tiles[x, y].TileColor; } else { // if pasting tiles is disabled, use the existing tile with buffer's wall & extras curTile = (Tile)world.Tiles[worldX, worldY].Clone(); curTile.Wall = buffer.Tiles[x, y].Wall; curTile.WallColor = buffer.Tiles[x, y].WallColor; curTile.LiquidAmount = buffer.Tiles[x, y].LiquidAmount; curTile.LiquidType = buffer.Tiles[x, y].LiquidType; curTile.WireRed = buffer.Tiles[x, y].WireRed; curTile.WireGreen = buffer.Tiles[x, y].WireGreen; curTile.WireBlue = buffer.Tiles[x, y].WireBlue; curTile.WireYellow = buffer.Tiles[x, y].WireYellow; curTile.Actuator = buffer.Tiles[x, y].Actuator; curTile.InActive = buffer.Tiles[x, y].InActive; } if (!PasteEmpty && (curTile.LiquidAmount == 0 && !curTile.IsActive && curTile.Wall == 0 && !curTile.WireRed && !curTile.WireBlue && !curTile.WireGreen && !curTile.WireYellow)) { // skip tiles that are empty if paste empty is not true continue; } if (!PasteWalls) { // if pasting walls is disabled, use the existing wall curTile.Wall = world.Tiles[worldX, worldY].Wall; curTile.WallColor = world.Tiles[worldX, worldY].WallColor; } if (!PasteLiquids) { // if pasting liquids is disabled, use any existing liquid curTile.LiquidAmount = world.Tiles[worldX, worldY].LiquidAmount; curTile.LiquidType = world.Tiles[worldX, worldY].LiquidType; } if (!PasteWires) { // if pasting wires is disabled, use any existing wire Tile worldTile = world.Tiles[worldX, worldY]; curTile.WireRed = worldTile.WireRed; curTile.WireGreen = worldTile.WireGreen; curTile.WireBlue = worldTile.WireBlue; curTile.WireYellow = worldTile.WireYellow; curTile.Actuator = worldTile.Actuator; curTile.InActive = worldTile.InActive; } // Update chest/sign data only if we've pasted tiles if (PasteTiles) { // Remove overwritten chests data if (Tile.IsChest(world.Tiles[x + anchor.X, y + anchor.Y].Type)) { var data = world.GetChestAtTile(x + anchor.X, y + anchor.Y); if (data != null) { _wvm.UndoManager.Buffer.Chests.Add(data); world.Chests.Remove(data); } } // Remove overwritten sign data if (Tile.IsSign(world.Tiles[x + anchor.X, y + anchor.Y].Type)) { var data = world.GetSignAtTile(x + anchor.X, y + anchor.Y); if (data != null) { _wvm.UndoManager.Buffer.Signs.Add(data); world.Signs.Remove(data); } } // Remove overwritten tile entity data if (Tile.IsTileEntity(world.Tiles[x + anchor.X, y + anchor.Y].Type)) { var data = world.GetTileEntityAtTile(x + anchor.X, y + anchor.Y); if (data != null) { // add this function to UndoManager // _wvm.UndoManager.Buffer.TileEntities.Add(data); world.TileEntities.Remove(data); } } // Add new chest data if (Tile.IsChest(curTile.Type)) { if (world.GetChestAtTile(x + anchor.X, y + anchor.Y) == null) { var data = buffer.GetChestAtTile(x, y, curTile.Type); if (data != null) // allow? chest copying may not work... { // Copied chest var newChest = data.Copy(); newChest.X = x + anchor.X; newChest.Y = y + anchor.Y; world.Chests.Add(newChest); } } } // Add new sign data if (Tile.IsSign(curTile.Type)) { if (world.GetSignAtTile(x + anchor.X, y + anchor.Y) == null) { var data = buffer.GetSignAtTile(x, y); if (data != null) { // Copied sign var newSign = data.Copy(); newSign.X = x + anchor.X; newSign.Y = y + anchor.Y; world.Signs.Add(newSign); } } } // Add new tile entity data if (Tile.IsTileEntity(curTile.Type)) { if (world.GetTileEntityAtTile(x + anchor.X, y + anchor.Y) == null) { var data = buffer.GetTileEntityAtTile(x, y); if (data != null) { // Copied sign var newEntity = data.Copy(); newEntity.PosX = (short)(x + anchor.X); newEntity.PosY = (short)(y + anchor.Y); world.TileEntities.Add(newEntity); } } } } _wvm.UndoManager.SaveTile(x + anchor.X, y + anchor.Y); world.Tiles[x + anchor.X, y + anchor.Y] = curTile; } } } _wvm.UndoManager.SaveUndo(); _wvm.CurrentWorld.UpgradeLegacyTileEntities(); /* Heathtech */ BlendRules.ResetUVCache(_wvm, anchor.X, anchor.Y, buffer.Size.X, buffer.Size.Y); }
public void Redo() { if (_currentIndex > _maxIndex || _currentIndex < 0) { return; } ErrorLogging.TelemetryClient?.TrackEvent(nameof(Redo)); // close current undo buffer and get a new one with a new name after redo string redoFileName = string.Format(RedoFile, _currentIndex + 1); // load redo file at +1 Debug.WriteLine($"Opening redo file for redo: {Path.GetFileNameWithoutExtension(redoFileName)}"); using (var stream = new FileStream(redoFileName, FileMode.Open)) using (BinaryReader br = new BinaryReader(stream)) { foreach (var undoTile in UndoBuffer.ReadUndoTilesFromStream(br)) { var curTile = (Tile)_wvm.CurrentWorld.Tiles[undoTile.Location.X, undoTile.Location.Y]; SaveTile(undoTile.Location); if (Tile.IsChest(curTile.Type)) { var curchest = _wvm.CurrentWorld.GetChestAtTile(undoTile.Location.X, undoTile.Location.Y); if (curchest != null) { _wvm.CurrentWorld.Chests.Remove(curchest); } } if (Tile.IsSign(curTile.Type)) { var cursign = _wvm.CurrentWorld.GetSignAtTile(undoTile.Location.X, undoTile.Location.Y); if (cursign != null) { _wvm.CurrentWorld.Signs.Remove(cursign); } } if (Tile.IsTileEntity(curTile.Type)) { var curTe = _wvm.CurrentWorld.GetTileEntityAtTile(undoTile.Location.X, undoTile.Location.Y); if (curTe != null) { _wvm.CurrentWorld.TileEntities.Remove(curTe); } } _wvm.CurrentWorld.Tiles[undoTile.Location.X, undoTile.Location.Y] = (Tile)undoTile.Tile; _wvm.UpdateRenderPixel(undoTile.Location); /* Heathtech */ BlendRules.ResetUVCache(_wvm, undoTile.Location.X, undoTile.Location.Y, 1, 1); } foreach (var chest in World.LoadChestData(br)) { _wvm.CurrentWorld.Chests.Add(chest); } foreach (var sign in World.LoadSignData(br)) { _wvm.CurrentWorld.Signs.Add(sign); } foreach (var te in World.LoadTileEntityData(br, World.CompatibleVersion)) { _wvm.CurrentWorld.TileEntities.Add(te); } } SaveUndo(updateMax: false); _wvm.CurrentWorld.UpgradeLegacyTileEntities(); OnRedid(this, EventArgs.Empty); }
public void Undo() { if (_currentIndex <= 0) { return; } _currentIndex--; List <Chest> Chests = new List <Chest>(); List <Sign> Signs = new List <Sign>(); using (var ws = new FileStream(string.Format(RedoFile, _currentIndex), FileMode.Create)) using (var bw = new BinaryWriter(ws)) using (var stream = new FileStream(string.Format(UndoFile, _currentIndex), FileMode.Open)) using (BinaryReader br = new BinaryReader(stream)) { int count = br.ReadInt32(); br.BaseStream.Position -= 4; bw.Write(count); foreach (var undoTile in UndoBuffer.ReadUndoTilesFromStream(br)) { var curTile = (Tile)_wvm.CurrentWorld.Tiles[undoTile.Location.X, undoTile.Location.Y]; if (curTile.Type == 21) { var curchest = _wvm.CurrentWorld.GetChestAtTile(undoTile.Location.X, undoTile.Location.Y); if (curchest != null) { _wvm.CurrentWorld.Chests.Remove(curchest); var chest = curchest.Copy(); Chests.Add(chest); } } if (curTile.Type == 55 || curTile.Type == 85) { var cursign = _wvm.CurrentWorld.GetSignAtTile(undoTile.Location.X, undoTile.Location.Y); if (cursign != null) { _wvm.CurrentWorld.Signs.Remove(cursign); var sign = cursign.Copy(); Signs.Add(sign); } } bw.Write(undoTile.Location.X); bw.Write(undoTile.Location.Y); World.WriteTileDataToStream(curTile, bw); _wvm.CurrentWorld.Tiles[undoTile.Location.X, undoTile.Location.Y] = (Tile)undoTile.Tile; _wvm.UpdateRenderPixel(undoTile.Location); /* Heathtech */ BlendRules.ResetUVCache(_wvm, undoTile.Location.X, undoTile.Location.Y, 1, 1); } World.WriteChestDataToStream(Chests, bw); World.WriteSignDataToStream(Signs, bw); foreach (var chest in World.ReadChestDataFromStream(br, World.CompatibleVersion)) { _wvm.CurrentWorld.Chests.Add(chest); } foreach (var sign in World.ReadSignDataFromStream(br)) { _wvm.CurrentWorld.Signs.Add(sign); } } OnUndid(this, EventArgs.Empty); }
public void PasteBufferIntoWorld(Vector2Int32 anchor) { if (Buffer == null) { return; } World world = _wvm.CurrentWorld; ClipboardBuffer buffer = _wvm.Clipboard.Buffer; for (int x = 0; x < buffer.Size.X; x++) { for (int y = 0; y < buffer.Size.Y; y++) { int worldX = x + anchor.X; int worldY = y + anchor.Y; if (world.ValidTileLocation(new Vector2Int32(x + anchor.X, y + anchor.Y))) { //HistMan.AddTileToBuffer(x + anchor.X, y + anchor.Y, ref world.Tiles[x + anchor.X, y + anchor.Y]); Tile curTile; if (PasteTiles) { curTile = (Tile)buffer.Tiles[x, y].Clone(); curTile.Color = buffer.Tiles[x, y].Color; } else { // if pasting tiles is disabled, use the existing tile with buffer's wall & extras curTile = (Tile)world.Tiles[worldX, worldY].Clone(); curTile.Wall = buffer.Tiles[x, y].Wall; curTile.WallColor = buffer.Tiles[x, y].WallColor; curTile.Liquid = buffer.Tiles[x, y].Liquid; curTile.IsLava = buffer.Tiles[x, y].IsLava; curTile.IsHoney = buffer.Tiles[x, y].IsHoney; curTile.HasWire = buffer.Tiles[x, y].HasWire; curTile.HasWire2 = buffer.Tiles[x, y].HasWire2; curTile.HasWire3 = buffer.Tiles[x, y].HasWire3; curTile.Actuator = buffer.Tiles[x, y].Actuator; curTile.InActive = buffer.Tiles[x, y].InActive; } if (!PasteEmpty && (curTile.Liquid == 0 && !curTile.IsActive && curTile.Wall == 0 && !curTile.HasWire)) { // skip tiles that are empty if paste empty is not true continue; } if (!PasteWalls) { // if pasting walls is disabled, use the existing wall curTile.Wall = world.Tiles[worldX, worldY].Wall; curTile.WallColor = world.Tiles[worldX, worldY].WallColor; } if (!PasteLiquids) { // if pasting liquids is disabled, use any existing liquid curTile.Liquid = world.Tiles[worldX, worldY].Liquid; curTile.IsLava = world.Tiles[worldX, worldY].IsLava; curTile.IsHoney = world.Tiles[worldX, worldY].IsHoney; } if (!PasteWires) { // if pasting wires is disabled, use any existing wire curTile.HasWire = buffer.Tiles[x, y].HasWire; curTile.HasWire2 = buffer.Tiles[x, y].HasWire2; curTile.HasWire3 = buffer.Tiles[x, y].HasWire3; curTile.Actuator = buffer.Tiles[x, y].Actuator; curTile.InActive = buffer.Tiles[x, y].InActive; } // Update chest/sign data only if we've pasted tiles if (PasteTiles) { // Remove overwritten chests data if (world.Tiles[x + anchor.X, y + anchor.Y].Type == 21) { var data = world.GetChestAtTile(x + anchor.X, y + anchor.Y); if (data != null) { _wvm.UndoManager.Buffer.Chests.Add(data); world.Chests.Remove(data); } } // Remove overwritten sign data if (world.Tiles[x + anchor.X, y + anchor.Y].Type == 55 || world.Tiles[x + anchor.X, y + anchor.Y].Type == 85) { var data = world.GetSignAtTile(x + anchor.X, y + anchor.Y); if (data != null) { _wvm.UndoManager.Buffer.Signs.Add(data); world.Signs.Remove(data); } } // Add new chest data if (curTile.Type == 21) { if (world.GetChestAtTile(x + anchor.X, y + anchor.Y) == null) { var data = buffer.GetChestAtTile(x, y); if (data != null) // allow? chest copying may not work... { // Copied chest var newChest = data.Copy(); newChest.X = x + anchor.X; newChest.Y = y + anchor.Y; world.Chests.Add(newChest); } else { // Empty chest world.Chests.Add(new Chest(x + anchor.X, y + anchor.Y)); } } } // Add new sign data if (curTile.Type == 55 || curTile.Type == 85) { if (world.GetSignAtTile(x + anchor.X, y + anchor.Y) == null) { var data = buffer.GetSignAtTile(x, y); if (data != null) { // Copied sign var newSign = data.Copy(); newSign.X = x + anchor.X; newSign.Y = y + anchor.Y; world.Signs.Add(newSign); } else { world.Signs.Add(new Sign(x + anchor.X, y + anchor.Y, string.Empty)); } } } } _wvm.UndoManager.SaveTile(x + anchor.X, y + anchor.Y); world.Tiles[x + anchor.X, y + anchor.Y] = curTile; } } } _wvm.UndoManager.SaveUndo(); /* Heathtech */ BlendRules.ResetUVCache(_wvm, anchor.X, anchor.Y, buffer.Size.X, buffer.Size.Y); }
public void Undo() { if (_currentIndex <= 0) { return; } _currentIndex--; UndoBuffer redo = new UndoBuffer(string.Format(RedoFile, _currentIndex)); using (var stream = new FileStream(string.Format(UndoFile, _currentIndex), FileMode.Open)) using (BinaryReader br = new BinaryReader(stream)) { foreach (var undoTile in UndoBuffer.ReadUndoTilesFromStream(br)) { var curTile = (Tile)_wvm.CurrentWorld.Tiles[undoTile.Location.X, undoTile.Location.Y]; redo.Add(undoTile.Location, curTile); if (Tile.IsChest(curTile.Type)) { var curchest = _wvm.CurrentWorld.GetChestAtTile(undoTile.Location.X, undoTile.Location.Y); if (curchest != null) { _wvm.CurrentWorld.Chests.Remove(curchest); var chest = curchest.Copy(); redo.Chests.Add(chest); } } if (Tile.IsSign(curTile.Type)) { var cursign = _wvm.CurrentWorld.GetSignAtTile(undoTile.Location.X, undoTile.Location.Y); if (cursign != null) { _wvm.CurrentWorld.Signs.Remove(cursign); var sign = cursign.Copy(); redo.Signs.Add(sign); } } _wvm.CurrentWorld.Tiles[undoTile.Location.X, undoTile.Location.Y] = (Tile)undoTile.Tile; _wvm.UpdateRenderPixel(undoTile.Location); /* Heathtech */ BlendRules.ResetUVCache(_wvm, undoTile.Location.X, undoTile.Location.Y, 1, 1); } redo.Close(); redo.Dispose(); redo = null; foreach (var chest in World.LoadChestData(br)) { _wvm.CurrentWorld.Chests.Add(chest); } foreach (var sign in World.LoadSignData(br)) { _wvm.CurrentWorld.Signs.Add(sign); } } OnUndid(this, EventArgs.Empty); }