From e030d54bd63d6fffcc09de7e53e631669bc7bb51 Mon Sep 17 00:00:00 2001 From: Chris <2648373+QuiCM@users.noreply.github.com> Date: Mon, 1 Jun 2020 16:40:34 +0930 Subject: [PATCH] Fix trapdoors too --- TShockAPI/Handlers/SendTileSquareHandler.cs | 123 ++++++++++++-------- 1 file changed, 72 insertions(+), 51 deletions(-) diff --git a/TShockAPI/Handlers/SendTileSquareHandler.cs b/TShockAPI/Handlers/SendTileSquareHandler.cs index 0f027d01..a5f4534e 100644 --- a/TShockAPI/Handlers/SendTileSquareHandler.cs +++ b/TShockAPI/Handlers/SendTileSquareHandler.cs @@ -2,8 +2,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; using Terraria; using Terraria.DataStructures; using Terraria.GameContent.Tile_Entities; @@ -57,11 +55,7 @@ namespace TShockAPI.Handlers public static void UpdateTile(ITile tile, NetTile newTile) { tile.active(newTile.Active); - - if (newTile.Active && !newTile.Inactive) - { - tile.type = newTile.Type; - } + tile.type = newTile.Type; if (newTile.FrameImportant) { @@ -153,23 +147,23 @@ namespace TShockAPI.Handlers if ( ((TileID.Sets.Conversion.Stone[tile.type] || Main.tileMoss[tile.type]) && (TileID.Sets.Conversion.Stone[newTile.Type] || Main.tileMoss[newTile.Type])) || ((tile.type == 0 || tile.type == 59) && (newTile.Type == 0 || newTile.Type == 59)) || - TileID.Sets.Conversion.Grass[tile.type] && TileID.Sets.Conversion.Grass[newTile.Type] || - TileID.Sets.Conversion.Ice[tile.type] && TileID.Sets.Conversion.Ice[newTile.Type] || - TileID.Sets.Conversion.Sand[tile.type] && TileID.Sets.Conversion.Sand[newTile.Type] || - TileID.Sets.Conversion.Sandstone[tile.type] && TileID.Sets.Conversion.Sandstone[newTile.Type] || - TileID.Sets.Conversion.HardenedSand[tile.type] && TileID.Sets.Conversion.HardenedSand[newTile.Type] || - TileID.Sets.Conversion.Thorn[tile.type] && TileID.Sets.Conversion.Thorn[newTile.Type] || - TileID.Sets.Conversion.Moss[tile.type] && TileID.Sets.Conversion.Moss[newTile.Type] || - TileID.Sets.Conversion.MossBrick[tile.type] && TileID.Sets.Conversion.MossBrick[newTile.Type] || - WallID.Sets.Conversion.Stone[tile.wall] && WallID.Sets.Conversion.Stone[newTile.Wall] || - WallID.Sets.Conversion.Grass[tile.wall] && WallID.Sets.Conversion.Grass[newTile.Wall] || - WallID.Sets.Conversion.Sandstone[tile.wall] && WallID.Sets.Conversion.Sandstone[newTile.Wall] || - WallID.Sets.Conversion.HardenedSand[tile.wall] && WallID.Sets.Conversion.HardenedSand[newTile.Wall] || - WallID.Sets.Conversion.PureSand[tile.wall] && WallID.Sets.Conversion.PureSand[newTile.Wall] || - WallID.Sets.Conversion.NewWall1[tile.wall] && WallID.Sets.Conversion.NewWall1[newTile.Wall] || - WallID.Sets.Conversion.NewWall2[tile.wall] && WallID.Sets.Conversion.NewWall2[newTile.Wall] || - WallID.Sets.Conversion.NewWall3[tile.wall] && WallID.Sets.Conversion.NewWall3[newTile.Wall] || - WallID.Sets.Conversion.NewWall4[tile.wall] && WallID.Sets.Conversion.NewWall4[newTile.Wall] + TileID.Sets.Conversion.Grass[tile.type] && TileID.Sets.Conversion.Grass[newTile.Type] || + TileID.Sets.Conversion.Ice[tile.type] && TileID.Sets.Conversion.Ice[newTile.Type] || + TileID.Sets.Conversion.Sand[tile.type] && TileID.Sets.Conversion.Sand[newTile.Type] || + TileID.Sets.Conversion.Sandstone[tile.type] && TileID.Sets.Conversion.Sandstone[newTile.Type] || + TileID.Sets.Conversion.HardenedSand[tile.type] && TileID.Sets.Conversion.HardenedSand[newTile.Type] || + TileID.Sets.Conversion.Thorn[tile.type] && TileID.Sets.Conversion.Thorn[newTile.Type] || + TileID.Sets.Conversion.Moss[tile.type] && TileID.Sets.Conversion.Moss[newTile.Type] || + TileID.Sets.Conversion.MossBrick[tile.type] && TileID.Sets.Conversion.MossBrick[newTile.Type] || + WallID.Sets.Conversion.Stone[tile.wall] && WallID.Sets.Conversion.Stone[newTile.Wall] || + WallID.Sets.Conversion.Grass[tile.wall] && WallID.Sets.Conversion.Grass[newTile.Wall] || + WallID.Sets.Conversion.Sandstone[tile.wall] && WallID.Sets.Conversion.Sandstone[newTile.Wall] || + WallID.Sets.Conversion.HardenedSand[tile.wall] && WallID.Sets.Conversion.HardenedSand[newTile.Wall] || + WallID.Sets.Conversion.PureSand[tile.wall] && WallID.Sets.Conversion.PureSand[newTile.Wall] || + WallID.Sets.Conversion.NewWall1[tile.wall] && WallID.Sets.Conversion.NewWall1[newTile.Wall] || + WallID.Sets.Conversion.NewWall2[tile.wall] && WallID.Sets.Conversion.NewWall2[newTile.Wall] || + WallID.Sets.Conversion.NewWall3[tile.wall] && WallID.Sets.Conversion.NewWall3[newTile.Wall] || + WallID.Sets.Conversion.NewWall4[tile.wall] && WallID.Sets.Conversion.NewWall4[newTile.Wall] ) { TShock.Log.ConsoleDebug("Bouncer / SendTileSquare processing a conversion update - [{0}|{1}] -> [{2}|{3}]", tile.type, tile.wall, newTile.Type, newTile.Wall); @@ -216,24 +210,25 @@ namespace TShockAPI.Handlers /// Processes a tile object consisting of multiple tiles from the tile square packet /// /// The tile type the object is comprised of - /// TileObjectData describing the tile object /// 2D array of NetTile containing the new tiles properties /// X position at the top left of the object /// Y position at the top left of the object + /// Width of the tile object + /// Height of the tile object /// SendTileSquareEventArgs containing event information - public void ProcessTileObject(int tileType, TileObjectData data, NetTile[,] newTiles, int realx, int realy, GetDataHandlers.SendTileSquareEventArgs args) + public void ProcessTileObject(int tileType, int realx, int realy, int width, int height, NetTile[,] newTiles, GetDataHandlers.SendTileSquareEventArgs args) { // As long as the player has permission to build, we should allow a tile object to be placed // More in depth checks should take place in handlers for the Place Object (79), Update Tile Entity (86), and Place Tile Entity (87) packets - if (!args.Player.HasBuildPermissionForTileObject(realx, realy, data.Width, data.Height)) + if (!args.Player.HasBuildPermissionForTileObject(realx, realy, width, height)) { TShock.Log.ConsoleDebug("Bouncer / SendTileSquare rejected from no permission for tile object from {0}", args.Player.Name); return; } - for (int x = 0; x < data.Width; x++) + for (int x = 0; x < width; x++) { - for (int y = 0; y < data.Height; y++) + for (int y = 0; y < height; y++) { // Update all tiles in the tile object. These will be synced back to the player later UpdateTile(Main.tile[realx + x, realy + y], newTiles[x, y]); @@ -247,6 +242,17 @@ namespace TShockAPI.Handlers } } + private void ProcessClosedTrapDoor(int realx, int realy, NetTile[,] newTiles) + { + for (int x = 0; x < 2; x++) + { + for (int y = 0; y < 3; y++) + { + UpdateTile(Main.tile[realx + x, realy + y], newTiles[x, y]); + } + } + } + /// /// Invoked when a SendTileSquare packet is received /// @@ -336,17 +342,41 @@ namespace TShockAPI.Handlers // and process them as a tile object if (newTile.Type < TileObjectData._data.Count && (data = TileObjectData._data[newTile.Type]) != null) { - NetTile[,] newTiles = new NetTile[data.Width, data.Height]; - for (int i = 0; i < data.Width; i++) + NetTile[,] newTiles; + + if (newTile.Type == TileID.TrapdoorClosed) { - for (int j = 0; j < data.Height; j++) + // Trapdoors can modify a 2x3 space. When it closes it will have leftover tiles either on top or bottom. + // If we don't update these tiles, the trapdoor gets confused and disappears. + // So we capture all 6 possible tiles and process them all + newTiles = new NetTile[2, 3]; + + for (int i = 0; i < 2; i++) { - newTiles[i, j] = tiles[x + i, y + j]; - processed[x + i, y + j] = true; + for (int j = 0; j < 3; j++) + { + newTiles[i, j] = tiles[x + i, y + j - 1]; // -1 will give us the tile above the closed door, the closed door, the tile below the closed door + processed[x + i, y + j] = true; + } } + // Use realy - 1 to target the correct tile, otherwise we will write a closed trapdoor a block below where it should be + ProcessTileObject(newTile.Type, realx, realy - 1, width: 2, height: 3, newTiles, args); + } + else + { + newTiles = new NetTile[data.Width, data.Height]; + + for (int i = 0; i < data.Width; i++) + { + for (int j = 0; j < data.Height; j++) + { + newTiles[i, j] = tiles[x + i, y + j]; + processed[x + i, y + j] = true; + } + } + ProcessTileObject(newTile.Type, realx, realy, data.Width, data.Height, newTiles, args); } - ProcessTileObject(newTile.Type, data, newTiles, realx, realy, args); continue; } @@ -358,18 +388,18 @@ namespace TShockAPI.Handlers // Uncommenting this function will send the same tile square 10 blocks above you for visualisation. This will modify your world and overwrite existing blocks. // Use in test worlds only. - //Debug.DisplayTileSetInGame(tileX, tileY - 10, size, size, tiles, args.Player); + Debug.DisplayTileSetInGame(tileX, tileY - 10, size, size, tiles, args.Player); + Debug.VisualiseTileSetDiff(tileX, tileY, size, size, tiles); // If we are handling this event then we have updated the server's Main.tile state the way we want it. // At this point we should send our state back to the client so they remain in sync with the server if (args.Handled == true) { - args.Player.SendTileSquare(tileX, tileY, size); + args.Player.SendTileSquare(tileX, tileY, size + 1); TShock.Log.ConsoleDebug("Bouncer / SendTileSquare reimplemented from spaghetti from {0}", args.Player.Name); } } - class Debug { /// @@ -393,24 +423,15 @@ namespace TShockAPI.Handlers int realX = x + tileX; ushort type = Main.tile[realX, realY].type; string type2 = type.ToString(); - Console.Write((type2.ToString()).PadLeft(3, pad) + " "); + Console.Write((type2.ToString()).PadLeft(3, pad) + (Main.tile[realX, realY].active() ? "a" : "-") + " "); } Console.Write(" -> "); for (int x = 0; x < width; x++) { int realX = x + tileX; - if (newTiles[x, y].Active) - { - ushort type = newTiles[x, y].Type; - string type2 = type.ToString(); - Console.Write((type2.ToString()).PadLeft(3, pad) + " "); - } - else - { - ushort type = Main.tile[realX, realY].type; - string type2 = type.ToString(); - Console.Write((type2.ToString()).PadLeft(3, pad) + " "); - } + ushort type = newTiles[x, y].Type; + string type2 = type.ToString(); + Console.Write((type2.ToString()).PadLeft(3, pad) + (newTiles[x, y].Active ? "a" : "-") + " "); } Console.Write("\n"); }