コード例 #1
0
        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);
                        }
                    }
                }
            }
        }
コード例 #2
0
        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);
                    }
                }
            }
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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);
                }
            }
        }
コード例 #8
0
        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);
        }
コード例 #9
0
        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));
        }
コード例 #10
0
        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();
        }
コード例 #11
0
 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);
             }
         }
     }
 }
コード例 #12
0
        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);
                    }
                }
            }
        }
コード例 #13
0
        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);
                    }
                }
            }
        }
コード例 #14
0
        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);
                    }
                }
            }
        }
コード例 #15
0
        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);
        }
コード例 #16
0
        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();
        }
コード例 #17
0
        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);
        }
コード例 #18
0
        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);
        }
コード例 #19
0
        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);
        }
コード例 #20
0
        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);
        }
コード例 #21
0
        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);
        }