diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs index 0bbf77e5..77d602a7 100644 --- a/TShockAPI/Bouncer.cs +++ b/TShockAPI/Bouncer.cs @@ -1146,7 +1146,8 @@ namespace TShockAPI { for (int j = y; j < y + tileData.Height; j++) { - if (TShock.CheckTilePermission(args.Player, i, j, type, EditAction.PlaceTile)) + if (!args.Player.HasModifiedIceSuccessfully(i, j, type, EditAction.PlaceTile) + && !args.Player.HasBuildPermission(i, j)) { args.Player.SendTileSquare(i, j, 4); args.Handled = true; @@ -1477,7 +1478,8 @@ namespace TShockAPI return; } - if (TShock.CheckTilePermission(args.Player, tileX, tileY, editData, action)) + if (!args.Player.HasModifiedIceSuccessfully(tileX, tileY, editData, action) + && !args.Player.HasBuildPermission(tileX, tileY)) { args.Player.SendTileSquare(tileX, tileY, 4); args.Handled = true; diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 05d9844c..a5aa17f2 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -385,6 +385,46 @@ namespace TShockAPI return HasBuildPermission(x, y) || HasPermission(Permissions.canpaint); } + /// Checks if a player can place ice, and if they can, tracks ice placements and removals. + /// The x coordinate of the suspected ice block. + /// The y coordinate of the suspected ice block. + /// The tile type of the suspected ice block. + /// The EditAction on the suspected ice block. + /// True if a player successfully places an ice tile or removes one of their past ice tiles. + public bool HasModifiedIceSuccessfully(int x, int y, short tileType, GetDataHandlers.EditAction editAction) + { + // The goal is to short circuit ASAP. + // A subsequent call to HasBuildPermission can figure this out if not explicitly ice. + if (!TShock.Config.AllowIce) + { + return false; + } + + // They've placed some ice. Horrible! + if (editAction == GetDataHandlers.EditAction.PlaceTile && tileType == TileID.MagicalIceBlock) + { + IceTiles.Add(new Point(x, y)); + return true; + } + + // The edit wasn't an add, so we check to see if the position matches any of the known ice tiles + if (editAction == GetDataHandlers.EditAction.KillTile) + { + foreach (Point p in IceTiles) + { + // If they're trying to kill ice or dirt, and the tile was in the list, we allow it. + if (p.X == x && p.Y == y && (Main.tile[p.X, p.Y].type == TileID.Dirt || Main.tile[p.X, p.Y].type == TileID.MagicalIceBlock)) + { + IceTiles.Remove(p); + return true; + } + } + } + + // Only a small number of cases let this happen. + return false; + } + /// /// A list of points where ice tiles have been placed. /// diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index f35efda8..5c03f7ee 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -1757,91 +1757,6 @@ namespace TShockAPI e.Handled = true; } - /// CheckTilePermission - Checks to see if a player has permission to modify a tile in general. - /// player - The TSPlayer object. - /// tileX - The x coordinate of the tile. - /// tileY - The y coordinate of the tile. - /// tileType - The tile type. - /// actionType - The type of edit that took place. - /// bool - True if the player should not be able to modify a tile. - public static bool CheckTilePermission(TSPlayer player, int tileX, int tileY, short tileType, GetDataHandlers.EditAction actionType) - { - if (!player.HasPermission(Permissions.canbuild)) - { - if (TShock.Config.AllowIce && actionType != GetDataHandlers.EditAction.PlaceTile) - { - foreach (Point p in player.IceTiles) - { - if (p.X == tileX && p.Y == tileY && (Main.tile[p.X, p.Y].type == 0 || Main.tile[p.X, p.Y].type == 127)) - { - player.IceTiles.Remove(p); - return false; - } - } - - if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.BPm) > 2000) - { - player.SendErrorMessage("You do not have permission to build!"); - player.BPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; - } - return true; - } - - if (TShock.Config.AllowIce && actionType == GetDataHandlers.EditAction.PlaceTile && tileType == 127) - { - player.IceTiles.Add(new Point(tileX, tileY)); - return false; - } - - if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.BPm) > 2000) - { - player.SendErrorMessage("You do not have permission to build!"); - player.BPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; - } - return true; - } - - if (!Regions.CanBuild(tileX, tileY, player)) - { - if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.RPm) > 2000) - { - player.SendErrorMessage("This region is protected from changes."); - player.RPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; - } - return true; - } - - if (Config.DisableBuild) - { - if (!player.HasPermission(Permissions.antibuild)) - { - if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.WPm) > 2000) - { - player.SendErrorMessage("The world is protected from changes."); - player.WPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; - } - return true; - } - } - - if (Config.SpawnProtection) - { - if (!player.HasPermission(Permissions.editspawn)) - { - if (Utils.IsInSpawn(tileX, tileY)) - { - if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.SPm) > 2000) - { - player.SendErrorMessage("Spawn is protected from changes."); - player.SPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; - } - return true; - } - } - } - return false; - } - /// Distance - Determines the distance between two vectors. /// value1 - The first vector location. /// value2 - The second vector location.