public void FlipY(ClipboardBuffer buffer) { Flip(buffer, false); }
public ClipboardBuffer GetSelectionBuffer() { World world = _wvm.CurrentWorld; XNA.Rectangle area = _wvm.Selection.SelectionArea; var buffer = new ClipboardBuffer(new Vector2Int32(area.Width, area.Height)); for (int x = 0; x < area.Width; x++) { for (int y = 0; y < area.Height; y++) { Tile curTile = (Tile)world.Tiles[x + area.X, y + area.Y].Clone(); if (Tile.IsChest(curTile.Type)) { if (buffer.GetChestAtTile(x, y) == null) { var anchor = world.GetAnchor(x + area.X, y + area.Y); if (anchor.X == x + area.X && anchor.Y == y + area.Y) { var data = world.GetChestAtTile(x + area.X, y + area.Y); if (data != null) { var newChest = data.Copy(); newChest.X = x; newChest.Y = y; buffer.Chests.Add(newChest); } } } } if (Tile.IsSign(curTile.Type)) { if (buffer.GetSignAtTile(x, y) == null) { var anchor = world.GetAnchor(x + area.X, y + area.Y); if (anchor.X == x + area.X && anchor.Y == y + area.Y) { var data = world.GetSignAtTile(x + area.X, y + area.Y); if (data != null) { var newSign = data.Copy(); newSign.X = x; newSign.Y = y; buffer.Signs.Add(newSign); } } } } if (Tile.IsTileEntity(curTile.Type)) { if (buffer.GetTileEntityAtTile(x, y) == null) { var anchor = world.GetAnchor(x + area.X, y + area.Y); if (anchor.X == x + area.X && anchor.Y == y + area.Y) { var data = world.GetTileEntityAtTile(x + area.X, y + area.Y); if (data != null) { var newEntity = data.Copy(); newEntity.PosX = (short)x; newEntity.PosY = (short)y; buffer.TileEntities.Add(newEntity); } } } } buffer.Tiles[x, y] = curTile; } } buffer.RenderBuffer(); return(buffer); }
// Reverse the buffer along the x- or y- axis public void Flip(ClipboardBuffer buffer, bool flipX) { ClipboardBuffer flippedBuffer = new ClipboardBuffer(buffer.Size); //var sprites = new Dictionary<Vector2Int32, Sprite>(); var spriteSizes = new Dictionary <Vector2Int32, Vector2Short>(); int maxX = buffer.Size.X - 1; int maxY = buffer.Size.Y - 1; for (int x = 0; x <= maxX; x++) { for (int y = 0; y <= maxY; y++) { int bufferX; int bufferY; if (flipX) { bufferX = maxX - x; bufferY = y; } else { bufferX = x; bufferY = maxY - y; } Tile tile = (Tile)buffer.Tiles[x, y].Clone(); var tileProperties = World.TileProperties[tile.Type]; // locate all the sprites and make a list if (tileProperties.IsFramed) { var loc = new Vector2Int32(x, y); if (tileProperties.IsOrigin(tile.GetUV())) { Vector2Short tileSize = tileProperties.GetFrameSize(tile.V); spriteSizes[loc] = tileSize; } } else { if (flipX) { // Ignore multi-width objects when flipping on x-axis // Flip brick-style switch (tile.BrickStyle) { case BrickStyle.SlopeTopRight: tile.BrickStyle = BrickStyle.SlopeTopLeft; break; case BrickStyle.SlopeTopLeft: tile.BrickStyle = BrickStyle.SlopeTopRight; break; case BrickStyle.SlopeBottomRight: tile.BrickStyle = BrickStyle.SlopeBottomLeft; break; case BrickStyle.SlopeBottomLeft: tile.BrickStyle = BrickStyle.SlopeBottomRight; break; } } else { // Ignore multi-height tiles when flipping on y-axis // Flip brick-style switch (tile.BrickStyle) { case BrickStyle.SlopeTopRight: tile.BrickStyle = BrickStyle.SlopeBottomRight; break; case BrickStyle.SlopeTopLeft: tile.BrickStyle = BrickStyle.SlopeBottomLeft; break; case BrickStyle.SlopeBottomRight: tile.BrickStyle = BrickStyle.SlopeTopRight; break; case BrickStyle.SlopeBottomLeft: tile.BrickStyle = BrickStyle.SlopeTopLeft; break; } } flippedBuffer.Tiles[bufferX, bufferY] = (Tile)tile; } } } foreach (var item in spriteSizes) { var flipOrigin = FlipFramed(buffer.Size, item.Key, item.Value, flipX); for (int y = 0; y < item.Value.Y; y++) { int sourceY = y + item.Key.Y; int targetY = y + flipOrigin.Y; for (int x = 0; x < item.Value.X; x++) { try { int sourceX = x + item.Key.X; int targetX = x + flipOrigin.X; Tile tile = (Tile)buffer.Tiles[sourceX, sourceY].Clone(); flippedBuffer.Tiles[targetX, targetY] = (Tile)tile; } catch (Exception) { } } } } foreach (var chest in buffer.Chests) { var flipOrigin = FlipFramed(buffer.Size, new Vector2Int32(chest.X, chest.Y), new Vector2Short(2, 2), flipX); chest.X = flipOrigin.X; chest.Y = flipOrigin.Y; flippedBuffer.Chests.Add(chest); } foreach (var sign in buffer.Signs) { var flipOrigin = FlipFramed(buffer.Size, new Vector2Int32(sign.X, sign.Y), new Vector2Short(2, 2), flipX); sign.X = flipOrigin.X; sign.Y = flipOrigin.Y; flippedBuffer.Signs.Add(sign); } foreach (var te in buffer.TileEntities) { var tileProperties = World.TileProperties[(int)te.TileType]; Vector2Short tileSize = tileProperties.FrameSize[0]; var flipOrigin = FlipFramed(buffer.Size, new Vector2Int32(te.PosX, te.PosY), tileSize, flipX); te.PosX = (short)flipOrigin.X; te.PosY = (short)flipOrigin.Y; flippedBuffer.TileEntities.Add(te); } // Replace the existing buffer with the new one int bufferIndex = LoadedBuffers.IndexOf(buffer); if (bufferIndex > -1) { LoadedBuffers.Insert(bufferIndex, flippedBuffer); LoadedBuffers.RemoveAt(bufferIndex + 1); } flippedBuffer.RenderBuffer(); if (Buffer == buffer) { Buffer = flippedBuffer; _wvm.PreviewChange(); } }
public void FlipX(ClipboardBuffer buffer) { Flip(buffer, true); }
public static ClipboardBuffer LoadOld(string filename) { using (var stream = new FileStream(filename, FileMode.Open)) { using (var reader = new BinaryReader(stream)) { string name = reader.ReadString(); int version = reader.ReadInt32(); int maxx = reader.ReadInt32(); int maxy = reader.ReadInt32(); var buffer = new ClipboardBuffer(new Vector2Int32(maxx, maxy)); buffer.Name = string.IsNullOrWhiteSpace(name) ? Path.GetFileNameWithoutExtension(filename) : name; try { for (int x = 0; x < buffer.Size.X; x++) { for (int y = 0; y < buffer.Size.Y; y++) { var tile = new Tile(); tile.IsActive = reader.ReadBoolean(); if (tile.IsActive) { tile.Type = reader.ReadByte(); if (tile.Type == (int)TileType.Platform) { tile.U = 0; tile.V = 0; } else if (World.TileProperties[tile.Type].IsFramed) { tile.U = reader.ReadInt16(); tile.V = reader.ReadInt16(); } else { tile.U = -1; tile.V = -1; } } // trash old lighted value reader.ReadBoolean(); if (reader.ReadBoolean()) { tile.Wall = reader.ReadByte(); } if (reader.ReadBoolean()) { tile.LiquidType = LiquidType.Water; tile.LiquidAmount = reader.ReadByte(); if (reader.ReadBoolean()) // lava { tile.LiquidType = LiquidType.Lava; } } buffer.Tiles[x, y] = tile; } } } catch (Exception) { for (int x = 0; x < buffer.Size.X; x++) { for (int y = 0; y < buffer.Size.Y; y++) { if (buffer.Tiles[x, y] == null) { buffer.Tiles[x, y] = new Tile(); } } } return(buffer); } for (int chestIndex = 0; chestIndex < 1000; chestIndex++) { if (reader.ReadBoolean()) { var chest = new Chest(); chest.X = reader.ReadInt32(); chest.Y = reader.ReadInt32(); for (int slot = 0; slot < 20; slot++) { byte stackSize = reader.ReadByte(); if (stackSize > 0) { string itemName = reader.ReadString(); chest.Items[slot].SetFromName(itemName); chest.Items[slot].StackSize = stackSize; } } //Chests[chestIndex] = chest; buffer.Chests.Add(chest); } } for (int signIndex = 0; signIndex < 1000; signIndex++) { if (reader.ReadBoolean()) { string signText = reader.ReadString(); int x = reader.ReadInt32(); int y = reader.ReadInt32(); if (buffer.Tiles[x, y].IsActive && Tile.IsSign(buffer.Tiles[x, y].Type)) // validate tile location { var sign = new Sign(x, y, signText); //Signs[signIndex] = sign; buffer.Signs.Add(sign); } } } int checkx = reader.ReadInt32(); int checky = reader.ReadInt32(); if (checkx == maxx && checky == maxy) { return(buffer); } } } return(null); }
public void PasteBufferIntoWorld(Vector2Int32 anchor) { if (Buffer == null) { return; } _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(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); 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 static ClipboardBuffer Load3(string filename, bool frame19 = false) { bool failed = false; try { using (var stream = new FileStream(filename, FileMode.Open)) { using (var br = new BinaryReader(stream)) { string name = br.ReadString(); int version = br.ReadInt32(); int sizeX = br.ReadInt32(); int sizeY = br.ReadInt32(); var buffer = new ClipboardBuffer(new Vector2Int32(sizeX, sizeY)); buffer.Name = name; for (int x = 0; x < sizeX; x++) { for (int y = 0; y < sizeY; y++) { var curTile = new Tile(); curTile.IsActive = br.ReadBoolean(); if (curTile.IsActive) { curTile.Type = br.ReadByte(); if (curTile.Type == (int)TileType.Platform) { curTile.U = 0; curTile.V = 0; if (frame19) { curTile.U = br.ReadInt16(); curTile.V = br.ReadInt16(); } } else if (World.TileProperties[curTile.Type].IsFramed) { curTile.U = br.ReadInt16(); curTile.V = br.ReadInt16(); if (curTile.Type == (int)TileType.Timer) { curTile.V = 0; } } else { curTile.U = -1; curTile.V = -1; } } if (br.ReadBoolean()) { curTile.Wall = br.ReadByte(); } if (br.ReadBoolean()) { curTile.LiquidType = LiquidType.Water; curTile.LiquidAmount = br.ReadByte(); if (br.ReadBoolean()) // lava byte { curTile.LiquidType = LiquidType.Lava; } } curTile.WireRed = br.ReadBoolean(); buffer.Tiles[x, y] = curTile; } } for (int chestIndex = 0; chestIndex < 1000; chestIndex++) { if (br.ReadBoolean()) { var curChest = new Chest(br.ReadInt32(), br.ReadInt32()); for (int j = 0; j < 20; ++j) { curChest.Items[j].StackSize = br.ReadByte(); if (curChest.Items[j].StackSize > 0) { if (version >= 3) { curChest.Items[j].NetId = br.ReadInt32(); } else { curChest.Items[j].SetFromName(br.ReadString()); } curChest.Items[j].Prefix = br.ReadByte(); } else { curChest.Items[j].SetFromName("[empty]"); } } buffer.Chests.Add(curChest); } } for (int signIndex = 0; signIndex < 1000; signIndex++) { if (br.ReadBoolean()) { string text = br.ReadString(); int x = br.ReadInt32(); int y = br.ReadInt32(); buffer.Signs.Add(new Sign(x, y, text)); } } if (buffer.Name != br.ReadString() || version != br.ReadInt32() || buffer.Size.X != br.ReadInt32() || buffer.Size.Y != br.ReadInt32()) { if (!frame19) { br.Close(); return(Load3(filename, true)); } else { System.Windows.MessageBox.Show("Verification failed. Some schematic data may be missing.", "Legacy Schematic Version"); } } br.Close(); return(buffer); } } } catch (Exception) { failed = true; } if (failed && !frame19) { return(Load3(filename, true)); } return(null); }
public static ClipboardBuffer Load2(string filename) { using (var stream = new FileStream(filename, FileMode.Open)) { using (var reader = new BinaryReader(stream)) { string name = reader.ReadString(); int version = reader.ReadInt32(); int maxx = reader.ReadInt32(); int maxy = reader.ReadInt32(); var buffer = new ClipboardBuffer(new Vector2Int32(maxx, maxy)); buffer.Name = string.IsNullOrWhiteSpace(name) ? Path.GetFileNameWithoutExtension(filename) : name; try { for (int x = 0; x < maxx; x++) { for (int y = 0; y < maxy; y++) { var curTile = new Tile(); curTile.IsActive = reader.ReadBoolean(); if (curTile.IsActive) { curTile.Type = reader.ReadByte(); if (curTile.Type == (int)TileType.Platform) { curTile.U = 0; curTile.V = 0; } else if (World.TileProperties[curTile.Type].IsFramed) { curTile.U = reader.ReadInt16(); curTile.V = reader.ReadInt16(); if (curTile.Type == (int)TileType.Timer) { curTile.V = 0; } } else { curTile.U = -1; curTile.V = -1; } } if (reader.ReadBoolean()) { curTile.Wall = reader.ReadByte(); } if (reader.ReadBoolean()) { curTile.LiquidAmount = reader.ReadByte(); bool lava = reader.ReadBoolean(); curTile.LiquidType = lava ? LiquidType.Lava : LiquidType.Water; } curTile.WireRed = reader.ReadBoolean(); buffer.Tiles[x, y] = curTile; } } } catch (Exception) { for (int x = 0; x < buffer.Size.X; x++) { for (int y = 0; y < buffer.Size.Y; y++) { if (buffer.Tiles[x, y] == null) { buffer.Tiles[x, y] = new Tile(); } } } return(buffer); } for (int chestIndex = 0; chestIndex < 1000; chestIndex++) { if (reader.ReadBoolean()) { var chest = new Chest(); chest.X = reader.ReadInt32(); chest.Y = reader.ReadInt32(); for (int slot = 0; slot < 20; slot++) { byte stackSize = reader.ReadByte(); if (stackSize > 0) { string itemName = reader.ReadString(); chest.Items[slot].SetFromName(itemName); chest.Items[slot].StackSize = stackSize; } } //Chests[chestIndex] = chest; buffer.Chests.Add(chest); } } for (int signIndex = 0; signIndex < 1000; signIndex++) { if (reader.ReadBoolean()) { string signText = reader.ReadString(); int x = reader.ReadInt32(); int y = reader.ReadInt32(); if (buffer.Tiles[x, y].IsActive && Tile.IsSign(buffer.Tiles[x, y].Type)) // validate tile location { var sign = new Sign(x, y, signText); //Signs[signIndex] = sign; buffer.Signs.Add(sign); } } } string checkName = reader.ReadString(); int checkversion = reader.ReadInt32(); int checkx = reader.ReadInt32(); int checky = reader.ReadInt32(); if (checkName != buffer.Name || checkversion != version || checkx != maxx || checky != maxy) { System.Windows.MessageBox.Show("Verification failed. Some schematic data may be missing.", "Legacy Schematic Version"); } return(buffer); } } }
public static ClipboardBuffer Load4(string filename) { using (var stream = new FileStream(filename, FileMode.Open)) { using (var b = new BinaryReader(stream)) { string name = b.ReadString(); int version = b.ReadInt32(); int sizeX = b.ReadInt32(); int sizeY = b.ReadInt32(); var buffer = new ClipboardBuffer(new Vector2Int32(sizeX, sizeY)); buffer.Name = name; for (int x = 0; x < sizeX; ++x) { for (int y = 0; y < sizeY; y++) { var tile = new Tile(); tile.IsActive = b.ReadBoolean(); TileProperty tileProperty = null; if (tile.IsActive) { tile.Type = b.ReadByte(); tileProperty = World.TileProperties[tile.Type]; if (tile.Type == (int)TileType.IceByRod) { tile.IsActive = false; } if (tileProperty.IsFramed) { tile.U = b.ReadInt16(); tile.V = b.ReadInt16(); if (tile.Type == (int)TileType.Timer) { tile.V = 0; } } else { tile.U = -1; tile.V = -1; } if (b.ReadBoolean()) { tile.TileColor = b.ReadByte(); } } if (b.ReadBoolean()) { tile.Wall = b.ReadByte(); if (b.ReadBoolean()) { tile.WallColor = b.ReadByte(); } } if (b.ReadBoolean()) { tile.LiquidType = LiquidType.Water; tile.LiquidAmount = b.ReadByte(); bool IsLava = b.ReadBoolean(); if (IsLava) { tile.LiquidType = LiquidType.Lava; } bool IsHoney = b.ReadBoolean(); if (IsHoney) { tile.LiquidType = LiquidType.Honey; } } tile.WireRed = b.ReadBoolean(); tile.WireGreen = b.ReadBoolean(); tile.WireBlue = b.ReadBoolean(); bool isHalfBrick = b.ReadBoolean(); var brickByte = b.ReadByte(); if (tileProperty == null || !tileProperty.IsSolid) { tile.BrickStyle = 0; } else { tile.BrickStyle = (BrickStyle)brickByte; } tile.Actuator = b.ReadBoolean(); tile.InActive = b.ReadBoolean(); // read complete, start compression buffer.Tiles[x, y] = tile; int rle = b.ReadInt16(); if (rle < 0) { throw new ApplicationException("Invalid Tile Data!"); } if (rle > 0) { for (int k = y + 1; k < y + rle + 1; k++) { var tcopy = (Tile)tile.Clone(); buffer.Tiles[x, k] = tcopy; } y = y + rle; } } } for (int i = 0; i < 1000; i++) { if (b.ReadBoolean()) { var chest = new Chest(b.ReadInt32(), b.ReadInt32()); for (int slot = 0; slot < Chest.MaxItems; slot++) { if (slot < Chest.MaxItems) { int stackSize = (int)b.ReadInt16(); chest.Items[slot].StackSize = stackSize; if (chest.Items[slot].StackSize > 0) { chest.Items[slot].NetId = b.ReadInt32(); chest.Items[slot].StackSize = stackSize; chest.Items[slot].Prefix = b.ReadByte(); } } } buffer.Chests.Add(chest); } } for (int i = 0; i < 1000; i++) { if (b.ReadBoolean()) { Sign sign = new Sign(); sign.Text = b.ReadString(); sign.X = b.ReadInt32(); sign.Y = b.ReadInt32(); if (buffer.Tiles[sign.X, sign.Y].IsActive && Tile.IsSign(buffer.Tiles[sign.X, sign.Y].Type)) { buffer.Signs.Add(sign); } } } string verifyName = b.ReadString(); int verifyVersion = b.ReadInt32(); int verifyX = b.ReadInt32(); int verifyY = b.ReadInt32(); if (buffer.Name == verifyName && version == verifyVersion && buffer.Size.X == verifyX && buffer.Size.Y == verifyY) { // valid; return(buffer); } b.Close(); return(null); } } }
private static ClipboardBuffer Load5(BinaryReader b, string name, uint tVersion, int version) { int sizeX = b.ReadInt32(); int sizeY = b.ReadInt32(); var buffer = new ClipboardBuffer(new Vector2Int32(sizeX, sizeY)); buffer.Name = name; for (int x = 0; x < sizeX; ++x) { for (int y = 0; y < sizeY; y++) { var tile = World.ReadTileDataFromStreamV1(b, tVersion); // read complete, start compression buffer.Tiles[x, y] = tile; int rle = b.ReadInt16(); if (rle < 0) { throw new ApplicationException("Invalid Tile Data!"); } if (rle > 0) { for (int k = y + 1; k < y + rle + 1; k++) { var tcopy = (Tile)tile.Clone(); buffer.Tiles[x, k] = tcopy; } y = y + rle; } } } buffer.Chests.Clear(); buffer.Chests.AddRange(World.ReadChestDataFromStreamV1(b, tVersion)); buffer.Signs.Clear(); foreach (Sign sign in World.ReadSignDataFromStreamV1(b)) { if (buffer.Tiles[sign.X, sign.Y].IsActive && Tile.IsSign(buffer.Tiles[sign.X, sign.Y].Type)) { buffer.Signs.Add(sign); } } string verifyName = b.ReadString(); int verifyVersion = b.ReadInt32(); int verifyX = b.ReadInt32(); int verifyY = b.ReadInt32(); if (buffer.Name == verifyName && version == verifyVersion && buffer.Size.X == verifyX && buffer.Size.Y == verifyY) { // valid; return(buffer); } b.Close(); return(null); }
// Reverse the buffer along the x- or y- axis public void Flip(ClipboardBuffer buffer, bool flipX) { ClipboardBuffer flippedBuffer = new ClipboardBuffer(buffer.Size); var sprites = new Dictionary <Vector2Int32, Sprite>(); for (int x = 0, maxX = buffer.Size.X - 1; x <= maxX; x++) { for (int y = 0, maxY = buffer.Size.Y - 1; y <= maxY; y++) { int bufferX; int bufferY; if (flipX) { bufferX = maxX - x; bufferY = y; } else { bufferX = x; bufferY = maxY - y; } Tile tile = (Tile)buffer.Tiles[x, y].Clone(); var tileProperties = World.TileProperties[tile.Type]; Vector2Short tileSize = tileProperties.FrameSize; // locate all the sprites and make a list if (tileProperties.IsFramed) { var loc = new Vector2Int32(x, y); var uv = tile.GetUV(); if (tileProperties.IsOrigin(uv, out var frame)) { var sprite = World.Sprites.FirstOrDefault(s => s.Tile == tile.Type && s.Origin == uv); sprites[loc] = sprite; } } if (flipX) { // Ignore multi-width objects when flipping on x-axis if (tileSize.X > 1) { ClearTile(tile); } // Flip brick-style switch (tile.BrickStyle) { case BrickStyle.SlopeTopRight: tile.BrickStyle = BrickStyle.SlopeTopLeft; break; case BrickStyle.SlopeTopLeft: tile.BrickStyle = BrickStyle.SlopeTopRight; break; case BrickStyle.SlopeBottomRight: tile.BrickStyle = BrickStyle.SlopeBottomLeft; break; case BrickStyle.SlopeBottomLeft: tile.BrickStyle = BrickStyle.SlopeBottomRight; break; } } else { // Ignore multi-height tiles when flipping on y-axis if (tileSize.Y > 1) { ClearTile(tile); } // Flip brick-style switch (tile.BrickStyle) { case BrickStyle.SlopeTopRight: tile.BrickStyle = BrickStyle.SlopeBottomRight; break; case BrickStyle.SlopeTopLeft: tile.BrickStyle = BrickStyle.SlopeBottomLeft; break; case BrickStyle.SlopeBottomRight: tile.BrickStyle = BrickStyle.SlopeTopRight; break; case BrickStyle.SlopeBottomLeft: tile.BrickStyle = BrickStyle.SlopeTopLeft; break; } } flippedBuffer.Tiles[bufferX, bufferY] = (Tile)tile; } } foreach (var sprite in sprites) { var flipOrigin = FlipSprite(buffer.Size, sprite.Key, sprite.Value.Size, flipX); Sprite.PlaceSprite(flipOrigin.X, flipOrigin.Y, sprite.Value, flippedBuffer); } foreach (var chest in buffer.Chests) { var flipOrigin = FlipSprite(buffer.Size, new Vector2Int32(chest.X, chest.Y), new Vector2Short(2, 2), flipX); chest.X = flipOrigin.X; chest.Y = flipOrigin.Y; flippedBuffer.Chests.Add(chest); } foreach (var sign in buffer.Signs) { var flipOrigin = FlipSprite(buffer.Size, new Vector2Int32(sign.X, sign.Y), new Vector2Short(2, 2), flipX); sign.X = flipOrigin.X; sign.Y = flipOrigin.Y; flippedBuffer.Signs.Add(sign); } foreach (var te in buffer.TileEntities) { var tileProperties = World.TileProperties[(int)te.TileType]; Vector2Short tileSize = tileProperties.FrameSize; var flipOrigin = FlipSprite(buffer.Size, new Vector2Int32(te.PosX, te.PosY), tileSize, flipX); te.PosX = (short)flipOrigin.X; te.PosY = (short)flipOrigin.Y; flippedBuffer.TileEntities.Add(te); } // Replace the existing buffer with the new one int bufferIndex = LoadedBuffers.IndexOf(buffer); if (bufferIndex > -1) { LoadedBuffers.Insert(bufferIndex, flippedBuffer); LoadedBuffers.RemoveAt(bufferIndex + 1); } flippedBuffer.RenderBuffer(); if (Buffer == buffer) { Buffer = flippedBuffer; _wvm.PreviewChange(); } }
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); }
// Reverse the buffer along the x- or y- axis public void Flip(ClipboardBuffer buffer, bool flipX) { ClipboardBuffer flippedBuffer = new ClipboardBuffer(buffer.Size); for (int x = 0, maxX = buffer.Size.X - 1; x <= maxX; x++) { for (int y = 0, maxY = buffer.Size.Y - 1; y <= maxY; y++) { int bufferX; int bufferY; if (flipX) { bufferX = maxX - x; bufferY = y; } else { bufferX = x; bufferY = maxY - y; } Tile tile = (Tile)buffer.Tiles[x, y].Clone(); Vector2Short tileSize = World.TileProperties[tile.Type].FrameSize; if (flipX) { // Ignore multi-width objects when flipping on x-axis if (tileSize.X > 1) { ClearTile(tile); } // Flip brick-style switch (tile.BrickStyle) { case BrickStyle.SlopeTopRight: tile.BrickStyle = BrickStyle.SlopeTopLeft; break; case BrickStyle.SlopeTopLeft: tile.BrickStyle = BrickStyle.SlopeTopRight; break; case BrickStyle.SlopeBottomRight: tile.BrickStyle = BrickStyle.SlopeBottomLeft; break; case BrickStyle.SlopeBottomLeft: tile.BrickStyle = BrickStyle.SlopeBottomRight; break; } } else { // Ignore multi-height tiles when flipping on y-axis if (tileSize.Y > 1) { ClearTile(tile); } // Flip brick-style switch (tile.BrickStyle) { case BrickStyle.SlopeTopRight: tile.BrickStyle = BrickStyle.SlopeBottomRight; break; case BrickStyle.SlopeTopLeft: tile.BrickStyle = BrickStyle.SlopeBottomLeft; break; case BrickStyle.SlopeBottomRight: tile.BrickStyle = BrickStyle.SlopeTopRight; break; case BrickStyle.SlopeBottomLeft: tile.BrickStyle = BrickStyle.SlopeTopLeft; break; } } flippedBuffer.Tiles[bufferX, bufferY] = (Tile)tile; } } // Replace the existing buffer with the new one int bufferIndex = LoadedBuffers.IndexOf(buffer); if (bufferIndex > -1) { LoadedBuffers.Insert(bufferIndex, flippedBuffer); LoadedBuffers.RemoveAt(bufferIndex + 1); } flippedBuffer.RenderBuffer(); if (Buffer == buffer) { Buffer = flippedBuffer; _wvm.PreviewChange(); } }