diff --git a/RegionVision/Player.cs b/RegionVision/Player.cs new file mode 100644 index 0000000..3948e45 --- /dev/null +++ b/RegionVision/Player.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using TShockAPI; + +namespace RegionVision { + /// + /// Associates data with an online player + /// + public class Player { + /// The player's index number. + public int index { get; private set; } + /// Returns this player's TSPlayer instance. + public TSPlayer TSPlayer { get { return TShock.Players[index]; } } + /// The list of regions this player is viewing. + public List regions { get; private set; } + /// True if the player has elected to see regions near them. + public bool viewingNearby { get; set; } + + /// Creates a new instance of the Player class. + /// The player's index number. + public Player(int index) { + this.index = index; + this.regions = new List(); + this.viewingNearby = false; + } + } +} diff --git a/RegionVision/Properties/AssemblyInfo.cs b/RegionVision/Properties/AssemblyInfo.cs index d6f92b7..f587425 100644 --- a/RegionVision/Properties/AssemblyInfo.cs +++ b/RegionVision/Properties/AssemblyInfo.cs @@ -10,7 +10,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Andrio Celos")] [assembly: AssemblyProduct("Region Vision")] -[assembly: AssemblyCopyright("2014 Andrio Celos")] +[assembly: AssemblyCopyright("2014-5 Andrio Celos")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.1.0.0")] -[assembly: AssemblyFileVersion("1.1.0.0")] +[assembly: AssemblyVersion("1.2.0.0")] +[assembly: AssemblyFileVersion("1.2.0.0")] diff --git a/RegionVision/Region.cs b/RegionVision/Region.cs new file mode 100644 index 0000000..42cda10 --- /dev/null +++ b/RegionVision/Region.cs @@ -0,0 +1,177 @@ +using System; + +using Terraria; +using TShockAPI; + +namespace RegionVision { + /// Represents a TShock region and stores some data about how it's being shown to a player. + public class Region { + /// Returns the name of the region. + public string name { get; private set; } + /// The area bounded by the region. + public Rectangle area; + /// The part of the region border that will be shown to players. + /// This will be a small part of the region if the region is very large. + public Rectangle showArea; + /// Returns the colour of paint used on phantom tiles for this region's border. + public byte colour { get; private set; } + /// True if the region was selected using a command; false if it's visible only because it's near the player. + public bool command { get; set; } + + private Tile[] realTile; // Holds the real tiles of the region while the phantom ones are created. + + /// The maximum width or height of a region border that will be shown. + public const int MaximumSize = 256; + + /// Creates a new instance of the Region class. + /// The name of the region + /// The area bounded by the region + /// Set to false if the region was automatically shown. + public Region(string name, Rectangle area, bool command = true) { + this.name = name; + this.area = area; + this.showArea = area; + this.command = command; + + int total = 0; + for (int i = 0; i < name.Length; i++) total += (int) name[i]; + colour = (byte) (total % 12 + 13); + } + + /// Calculates what part of the region border to show for a large region. + public void calculateArea(TSPlayer tPlayer) { + this.showArea = this.area; + + // If the region is large, only part of its border will be shown. + if (this.showArea.Width >= MaximumSize) { + this.showArea.X = (int) (tPlayer.X / 16) - MaximumSize / 2; + this.showArea.Width = MaximumSize - 1; + if (this.showArea.Left < this.area.Left) this.showArea.X = this.area.Left; + else if (this.showArea.Right > this.area.Right) this.showArea.X = this.area.Right - (MaximumSize - 1); + } + if (this.showArea.Height >= MaximumSize) { + this.showArea.Y = (int) (tPlayer.Y / 16) - MaximumSize / 2; + this.showArea.Height = MaximumSize - 1; + if (this.showArea.Top < this.area.Top) this.showArea.Y = this.area.Top; + else if (this.showArea.Bottom > this.area.Bottom) this.showArea.Y = this.area.Bottom - (MaximumSize - 1); + } + + // Ensure the region boundary is within the world. + if (this.showArea.Left < 1) this.showArea.X = 1; + else if (this.showArea.Left >= Main.maxTilesX - 1) this.showArea.X = Main.maxTilesX - 1; + + if (this.showArea.Top < 1) this.showArea.Y = 1; + else if (this.showArea.Top >= Main.maxTilesY - 1) this.showArea.Y = Main.maxTilesY - 1; + + if (this.showArea.Right >= Main.maxTilesX - 1) this.showArea.Width = Main.maxTilesX - this.showArea.X - 2; + if (this.showArea.Bottom >= Main.maxTilesY - 1) this.showArea.Height = Main.maxTilesY - this.showArea.Y - 2; + } + + /// Spawns fake tiles for the region border. + /// Fake tiles have already been set, which would cause a desync. + public void setFakeTiles() { + int d; int index = 0; + + if (this.realTile != null) throw new InvalidOperationException("Fake tiles have already been set for the region."); + + // Initialise the temporary tile array. + if (this.showArea.Width == 0) + this.realTile = new Tile[this.showArea.Height + 1]; + else if (this.showArea.Height == 0) + this.realTile = new Tile[this.showArea.Width + 1]; + else + this.realTile = new Tile[(this.showArea.Width + this.showArea.Height) * 2]; + + // Top boundary + if (this.showArea.Top == this.area.Top) + for (d = 0; d <= this.showArea.Width; d++) setFakeTile(index++, this.showArea.Left + d, this.showArea.Top); + // East boundary + if (this.showArea.Right == this.area.Right) + for (d = 1; d <= this.showArea.Height; d++) setFakeTile(index++, this.showArea.Right, this.showArea.Top + d); + // West boundary + if (this.showArea.Width > 0 && this.showArea.Left == this.area.Left) + for (d = 1; d <= this.showArea.Height; d++) setFakeTile(index++, this.showArea.Left, this.showArea.Top + d); + // Bottom boundary + if (this.showArea.Height > 0 && this.showArea.Bottom == this.area.Bottom) + for (d = 1; d < this.showArea.Width; d++) setFakeTile(index++, this.showArea.Left + d, this.showArea.Bottom); + } + + /// Removes fake tiles for the region, reverting to the real tiles. + /// Fake tiles have not been set. + public void unsetFakeTiles() { + int d; int index = 0; + + if (this.realTile == null) throw new InvalidOperationException("Fake tiles have not been set for the region."); + + // Top boundary + if (this.showArea.Top == this.area.Top) + for (d = 0; d <= this.showArea.Width; d++) unsetFakeTile(index++, this.showArea.Left + d, this.showArea.Top); + // East boundary + if (this.showArea.Right == this.area.Right) + for (d = 1; d <= this.showArea.Height; d++) unsetFakeTile(index++, this.showArea.Right, this.showArea.Top + d); + // West boundary + if (this.showArea.Width > 0 && this.showArea.Left == this.area.Left) + for (d = 1; d <= this.showArea.Height; d++) unsetFakeTile(index++, this.showArea.Left, this.showArea.Top + d); + // Bottom boundary + if (this.showArea.Height > 0 && this.showArea.Bottom == this.area.Bottom) + for (d = 1; d < this.showArea.Width; d++) unsetFakeTile(index++, this.showArea.Left + d, this.showArea.Bottom); + + this.realTile = null; + } + + /// Adds a single fake tile. If a tile exists, this will replace it with a painted clone. Otherwise, this will place an inactive magical ice tile with the same paint. + /// The index in the realTile array into which to store the existing tile + /// The x coordinate of the tile position + /// The y coordinate of the tile position + public void setFakeTile(int index, int x, int y) { + if (x < 0 || y < 0 || x >= Main.maxTilesX || y >= Main.maxTilesY) return; + + this.realTile[index] = Main.tile[x, y]; + Tile fakeTile; + if (this.realTile[index] == null) fakeTile = new Tile(); + else fakeTile = new Tile(this.realTile[index]); + if (this.realTile[index] != null && this.realTile[index].active()) { + if (this.realTile[index].type == Terraria.ID.TileID.RainbowBrick) fakeTile.type = Terraria.ID.TileID.GrayBrick; + fakeTile.color(this.colour); + } else { + if (Main.rand == null) Main.rand = new Random(); + fakeTile.active(true); + fakeTile.inActive(true); + fakeTile.type = Terraria.ID.TileID.MagicalIceBlock; + fakeTile.frameX = (short) (162 + Main.rand.Next(0, 2) * 18); + fakeTile.frameY = 54; + fakeTile.color(this.colour); + } + Main.tile[x, y] = fakeTile; + } + + /// Removes a single fake tile, reverting to the real tile. + /// The index in the realTile array from which to retrieve the existing tile + /// The x coordinate of the tile position + /// The y coordinate of the tile position + public void unsetFakeTile(int index, int x, int y) { + if (x < 0 || y < 0 || x >= Main.maxTilesX || y >= Main.maxTilesY) return; + Main.tile[x, y] = this.realTile[index]; + } + + /// Sends tile updates for a region border to a client. + /// The player to send to. + public void refresh(TShockAPI.TSPlayer player) { + // Due to the way the Rectangle class works, the Width and Height values are one tile less than the actual dimensions of the region. + if (this.showArea.Width <= 3 || this.showArea.Height <= 3) { + player.SendData(PacketTypes.TileSendSection, "", this.showArea.Left - 1, this.showArea.Top - 1, this.showArea.Width + 3, this.showArea.Height + 3, 0); + } else { + if (this.showArea.Top == this.area.Top) + player.SendData(PacketTypes.TileSendSection, "", this.showArea.Left - 1, this.showArea.Top - 1, this.showArea.Width + 3, 3, 0); + if (this.showArea.Left == this.area.Left) + player.SendData(PacketTypes.TileSendSection, "", this.showArea.Left - 1, this.showArea.Top + 2, 3, this.showArea.Height, 0); + if (this.showArea.Right == this.area.Right) + player.SendData(PacketTypes.TileSendSection, "", this.showArea.Right - 1, this.showArea.Top + 2, 3, this.showArea.Height, 0); + if (this.showArea.Bottom == this.area.Bottom) + player.SendData(PacketTypes.TileSendSection, "", this.showArea.Left + 2, this.showArea.Bottom - 1, this.showArea.Width - 3, 3, 0); + } + + player.SendData(PacketTypes.TileFrameSection, "", (int) (this.showArea.Left / 200), (int) (this.showArea.Top / 150), (int) (this.showArea.Right / 200), (int) (this.showArea.Bottom / 150), 0); + } + } +} diff --git a/RegionVision/RegionVision.cs b/RegionVision/RegionVision.cs index 04874a9..65ffd81 100644 --- a/RegionVision/RegionVision.cs +++ b/RegionVision/RegionVision.cs @@ -8,273 +8,37 @@ using TerrariaApi.Server; using TShockAPI; +using TShockAPI.Hooks; namespace RegionVision { - /// - /// Associates data with an online player - /// - public class Player - { - /// - /// The player's index number - /// - public int index { get; private set; } - /// - /// Returns this player's TSPlayer instance - /// - public TSPlayer TSPlayer { get { return TShock.Players[index]; } } - /// - /// The list of regions this player is viewing - /// - public List regions { get; private set; } - /// - /// True if the player has elected to see regions near them - /// - public bool viewingNearby { get; set; } - - /// - /// Creates a new instance of the Player class - /// - /// The player's index number - public Player(int index) - { - this.index = index; - this.regions = new List(); - this.viewingNearby = false; - } - } - - /// - /// Represents a TShock region and stores some data about how it's being shown to a player - /// - public class Region - { - /// - /// Returns the name of the region - /// - public string name { get; private set; } - /// - /// The area bounded by the region - /// - public Rectangle area; - /// - /// The part of the region border that will be shown to players - /// - public Rectangle showArea; - /// - /// Returns the colour of paint used on phantom tiles for this region's border - /// - public byte colour { get; private set; } - /// - /// True if the region was selected using a command; false if it's visible only because it's near the player - /// - public bool command { get; set; } - - private Tile[] realTile; - - /// - /// The maximum width or height of a region border that will be shown - /// - public const int MaximumSize = 256; - - /// - /// Creates a new instance of the Region class. - /// - /// The name of the region - /// The area bounded by the region - /// Set to false if the region was automatically shown. - public Region(string name, Rectangle area, bool command = true) { - this.name = name; - this.area = area; - this.showArea = area; - this.command = command; - - int total = 0; - for (int i = 0; i < name.Length; i++) total += (int) name[i]; - colour = (byte) (total % 12 + 13); - } - - /// - /// Calculates what part of the region border to show for a large region. - /// - public void calculateArea(TSPlayer tPlayer) { - this.showArea = this.area; - - // If the region is large, only part of its border will be shown. - if (this.showArea.Width >= MaximumSize) { - this.showArea.X = (int) (tPlayer.X / 16) - MaximumSize / 2; - this.showArea.Width = MaximumSize - 1; - if (this.showArea.Left < this.area.Left) this.showArea.X = this.area.Left; - else if (this.showArea.Right > this.area.Right) this.showArea.X = this.area.Right - (MaximumSize - 1); - } - if (this.showArea.Height >= MaximumSize) { - this.showArea.Y = (int) (tPlayer.Y / 16) - MaximumSize / 2; - this.showArea.Height = MaximumSize - 1; - if (this.showArea.Top < this.area.Top) this.showArea.Y = this.area.Top; - else if (this.showArea.Bottom > this.area.Bottom) this.showArea.Y = this.area.Bottom - (MaximumSize - 1); - } - - // Ensure the region boundary is within the world. - if (this.showArea.Left < 1) this.showArea.X = 1; - else if (this.showArea.Left >= Main.maxTilesX - 1) this.showArea.X = Main.maxTilesX - 1; - - if (this.showArea.Top < 1) this.showArea.Y = 1; - else if (this.showArea.Top >= Main.maxTilesY - 1) this.showArea.Y = Main.maxTilesY - 1; - - if (this.showArea.Right >= Main.maxTilesX - 1) this.showArea.Width = Main.maxTilesX - this.showArea.X - 2; - if (this.showArea.Bottom >= Main.maxTilesY - 1) this.showArea.Height = Main.maxTilesY - this.showArea.Y - 2; - } - - /// - /// Spawns fake tiles for the region border - /// - /// Fake tiles have already been set, which would cause a desync. - public void setFakeTiles() { - int d; int index = 0; - - if (this.realTile != null) throw new InvalidOperationException("Fake tiles have already been set for the region."); - - // Initialise the temporary tile array. - if (this.showArea.Width == 0) - this.realTile = new Tile[this.showArea.Height + 1]; - else if (this.showArea.Height == 0) - this.realTile = new Tile[this.showArea.Width + 1]; - else - this.realTile = new Tile[(this.showArea.Width + this.showArea.Height) * 2]; - - // Top boundary - if (this.showArea.Top == this.area.Top) - for (d = 0; d <= this.showArea.Width ; d++) setFakeTile(index++, this.showArea.Left + d, this.showArea.Top ); - // East boundary - if (this.showArea.Right == this.area.Right) - for (d = 1; d <= this.showArea.Height; d++) setFakeTile(index++, this.showArea.Right , this.showArea.Top + d ); - // West boundary - if (this.showArea.Width > 0 && this.showArea.Left == this.area.Left) - for (d = 1; d <= this.showArea.Height; d++) setFakeTile(index++, this.showArea.Left , this.showArea.Top + d); - // Bottom boundary - if (this.showArea.Height > 0 && this.showArea.Bottom == this.area.Bottom) - for (d = 1; d < this.showArea.Width ; d++) setFakeTile(index++, this.showArea.Left + d, this.showArea.Bottom ); - } - - /// - /// Removes fake tiles for the region, reverting to the real tiles. - /// - /// Fake tiles have not been set. - public void unsetFakeTiles() { - int d; int index = 0; - - if (this.realTile == null) throw new InvalidOperationException("Fake tiles have not been set for the region."); - - // Top boundary - if (this.showArea.Top == this.area.Top) - for (d = 0; d <= this.showArea.Width; d++) unsetFakeTile(index++, this.showArea.Left + d, this.showArea.Top); - // East boundary - if (this.showArea.Right == this.area.Right) - for (d = 1; d <= this.showArea.Height; d++) unsetFakeTile(index++, this.showArea.Right, this.showArea.Top + d); - // West boundary - if (this.showArea.Width > 0 && this.showArea.Left == this.area.Left) - for (d = 1; d <= this.showArea.Height; d++) unsetFakeTile(index++, this.showArea.Left, this.showArea.Top + d); - // Bottom boundary - if (this.showArea.Height > 0 && this.showArea.Bottom == this.area.Bottom) - for (d = 1; d < this.showArea.Width; d++) unsetFakeTile(index++, this.showArea.Left + d, this.showArea.Bottom); - - this.realTile = null; - } - - /// Adds a single fake tile. If a tile exists, this will replace it with a painted clone. Otherwise, this will place an inactive magical ice tile with the same paint. - /// The index in the realTile array into which to store the existing tile - /// The x coordinate of the tile position - /// The y coordinate of the tile position - public void setFakeTile(int index, int x, int y) { - if (x < 0 || y < 0 || x >= Main.maxTilesX || y >= Main.maxTilesY) return; - - this.realTile[index] = Main.tile[x, y]; - Tile fakeTile; - if (this.realTile[index] == null) fakeTile = new Tile(); - else fakeTile = new Tile(this.realTile[index]); - if (this.realTile[index] != null && this.realTile[index].active()) { - if (this.realTile[index].type == Terraria.ID.TileID.RainbowBrick) fakeTile.type = Terraria.ID.TileID.GrayBrick; - fakeTile.color(this.colour); - } else { - if (Main.rand == null) Main.rand = new Random(); - fakeTile.active(true); - fakeTile.inActive(true); - fakeTile.type = Terraria.ID.TileID.MagicalIceBlock; - fakeTile.frameX = (short) (162 + Main.rand.Next(0, 2) * 18); - fakeTile.frameY = 54; - fakeTile.color(this.colour); - } - Main.tile[x, y] = fakeTile; - } - - /// Removes a single fake tile, reverting to the real tile - /// The index in the realTile array from which to retrieve the existing tile - /// The x coordinate of the tile position - /// The y coordinate of the tile position - public void unsetFakeTile(int index, int x, int y) { - if (x < 0 || y < 0 || x >= Main.maxTilesX || y >= Main.maxTilesY) return; - Main.tile[x, y] = this.realTile[index]; - } - - /// Sends tile updates for a region border to a client. - /// The player to send to - public void refresh(TShockAPI.TSPlayer player) { - // Due to the way the Rectangle class works, the Width and Height values are one tile less than the actual dimensions of the region. - if (this.showArea.Width <= 3 || this.showArea.Height <= 3) { - player.SendData(PacketTypes.TileSendSection, "", this.showArea.Left - 1, this.showArea.Top - 1, this.showArea.Width + 3, this.showArea.Height + 3, 0); - } else { - if (this.showArea.Top == this.area.Top ) - player.SendData(PacketTypes.TileSendSection, "", this.showArea.Left - 1, this.showArea.Top - 1, this.showArea.Width + 3, 3, 0); - if (this.showArea.Left == this.area.Left ) - player.SendData(PacketTypes.TileSendSection, "", this.showArea.Left - 1, this.showArea.Top + 2, 3, this.showArea.Height, 0); - if (this.showArea.Right == this.area.Right ) - player.SendData(PacketTypes.TileSendSection, "", this.showArea.Right - 1, this.showArea.Top + 2, 3, this.showArea.Height, 0); - if (this.showArea.Bottom == this.area.Bottom) - player.SendData(PacketTypes.TileSendSection, "", this.showArea.Left + 2, this.showArea.Bottom - 1, this.showArea.Width - 3, 3, 0); - } - - player.SendData(PacketTypes.TileFrameSection, "", (int) (this.showArea.Left / 200), (int) (this.showArea.Top / 150), (int) (this.showArea.Right / 200), (int) (this.showArea.Bottom / 150), 0); - } - } - - [ApiVersion(1, 16)] + [ApiVersion(1, 17)] public class RegionVisionPlugin : TerrariaPlugin { - /// - /// The list of players being tracked by this plugin - /// + /// The list of players being tracked by this plugin. public List players { get; private set; } - private Timer refreshTimer = new Timer(7000); + private Timer refreshTimer = new Timer(5000); - public override Version Version - { - get { return new Version(1, 1, 0, 0); } + public override Version Version { + get { return new Version(1, 2, 0, 0); } } - public override string Name - { + public override string Name { get { return "Region Vision"; } } - public override string Author - { + public override string Author { get { return "Andrio Celos"; } } - public override string Description - { + public override string Description { get { return "See your regions"; } } - /// - /// The range, in tiles, within which region borders may be automatically shown - /// + /// The range, in tiles, within which region borders may be automatically shown. public const int NearRange = 100; - /// - /// The array from which the colour of the 'You are now viewing...' message is retrieved, to match the colour of the border - /// + /// The array from which the colour of the 'You are now viewing...' message is retrieved, to match the colour of the border. public readonly static Color[] textColour = {new Color(244, 93, 93), new Color(244, 169, 93), new Color(244, 244, 93), @@ -313,6 +77,8 @@ public override void Initialize() Commands.ChatCommands.Add(viewNearbyCommand); GetDataHandlers.TileEdit += TShockAPI.HandlerList.Create(OnTileEdit, HandlerPriority.High, false); + TShockAPI.Hooks.RegionHooks.RegionCreated += RegionHooks_RegionCreated; + TShockAPI.Hooks.RegionHooks.RegionDeleted += RegionHooks_RegionDeleted; ServerApi.Hooks.ServerJoin.Register(this, onPlayerJoin); ServerApi.Hooks.ServerLeave.Register(this, onPlayerLeave); TShockAPI.Hooks.PlayerHooks.PlayerCommand += onPlayerCommand; @@ -321,9 +87,40 @@ public override void Initialize() refreshTimer.Elapsed += refreshTimer_Elapsed; } - /// - /// Returns the Player instance for a given index number - /// + void RegionHooks_RegionDeleted(RegionHooks.RegionDeletedEventArgs args) { + Console.WriteLine("Region {0} was deleted.", args.Region.Name); + if (args.Region.WorldID != Main.worldID.ToString()) return; + + // If any players were viewing this region, clear its border. + lock (players) { + foreach (Player player in players) { + for (int i = 0; i < player.regions.Count; i++) { + Region region = player.regions[i]; + if (region.name.Equals(args.Region.Name)) { + player.TSPlayer.SendMessage("Region " + region.name + " has been deleted.", textColour[region.colour - 13]); + region.refresh(player.TSPlayer); + player.regions.RemoveAt(i); + + foreach (Region region2 in player.regions) + region2.setFakeTiles(); + foreach (Region region2 in player.regions) + region2.refresh(player.TSPlayer); + foreach (Region region2 in player.regions.Reverse()) + region2.unsetFakeTiles(); + + break; + } + } + } + } + } + void RegionHooks_RegionCreated(RegionHooks.RegionCreatedEventArgs args) { + Console.WriteLine("Region {0} was created. ({1})", args.Region.Name, args.Region.Area); + refreshTimer.Stop(); + refreshTimer_Elapsed(this, null); + } + + /// Returns the Player instance for the player with a given index number. public Player findPlayer(int index) { foreach (Player player in players) if (player.index == index) return player; @@ -406,7 +203,37 @@ private void commandView(CommandArgs args) foreach (Region _region in player.regions.Reverse()) _region.unsetFakeTiles(); - args.Player.SendMessage("You are now viewing " + region.name + ".", textColour[region.colour - 13]); + string message = "You are now viewing " + region.name + "."; + // Show how large the region is if it's large. + if (tRegion.Area.Width >= Region.MaximumSize || tRegion.Area.Height >= Region.MaximumSize) { + int num; int num2; + if (tRegion.Area.Bottom < args.Player.TileY) { + num = args.Player.TileY - tRegion.Area.Bottom; + message += " Borders are " + num + (num == 1 ? " tile" : " tiles") + " above you"; + } else if (tRegion.Area.Top > args.Player.TileY) { + num = tRegion.Area.Top - args.Player.TileY; + message += " Borders are " + (tRegion.Area.Top - args.Player.TileY) + (num == 1 ? " tile" : " tiles") + " below you"; + } else { + num = args.Player.TileY - tRegion.Area.Top; + num2 = tRegion.Area.Bottom - args.Player.TileY; + message += " Borders are " + (args.Player.TileY - tRegion.Area.Top) + (num == 1 ? " tile" : " tiles") + " above, " + + (tRegion.Area.Bottom - args.Player.TileY) + (num2 == 1 ? " tile" : " tiles") + " below you"; + } + if (tRegion.Area.Right < args.Player.TileX) { + num = args.Player.TileX - tRegion.Area.Right; + message += ", " + (args.Player.TileX - tRegion.Area.Right) + (num == 1 ? " tile" : " tiles") + " west of you."; + } else if (tRegion.Area.Left > args.Player.TileX) { + num = tRegion.Area.Left - args.Player.TileX; + message += ", " + (tRegion.Area.Left - args.Player.TileX) + (num == 1 ? " tile" : " tiles") + " east of you."; + } else { + num = args.Player.TileX - tRegion.Area.Left; + num2 = tRegion.Area.Right - args.Player.TileX; + message += ", " + (args.Player.TileX - tRegion.Area.Left) + (num == 1 ? " tile" : " tiles") + " west, " + + (tRegion.Area.Right - args.Player.TileX) + (num2 == 1 ? " tile" : " tiles") + " east of you."; + } + } + args.Player.SendMessage(message, textColour[region.colour - 13]); + refreshTimer.Interval = 7000; refreshTimer.Enabled = true; } @@ -438,9 +265,7 @@ private void commandViewNearby(CommandArgs args) { } } - /// - /// Removes all region borders from a player's view - /// + /// Removes all region borders from a player's view. /// The player to reset public void clearRegions(Player player) { foreach (Region region in player.regions) @@ -466,7 +291,7 @@ private void OnTileEdit(object sender, TShockAPI.GetDataHandlers.TileEditEventAr e.X >= region.showArea.Left - 1 && e.X <= region.showArea.Right + 1 && e.Y >= region.showArea.Top - 1 && e.Y <= region.showArea.Bottom + 1 && !(e.X >= region.showArea.Left + 2 && e.X <= region.showArea.Right - 2 && e.Y >= region.showArea.Top + 2 && e.Y <= region.showArea.Bottom - 2)) { e.Handled = true; - clearRegions(player); + //clearRegions(player); break; } if ((e.Action == GetDataHandlers.EditAction.PlaceTile || e.Action == GetDataHandlers.EditAction.PlaceWall) && !tileValidityCheck(region, e.X, e.Y, e.Action)) { @@ -481,14 +306,12 @@ private void OnTileEdit(object sender, TShockAPI.GetDataHandlers.TileEditEventAr } } - /// - /// Checks whether a player's attempted tile edit is valid. A tile edit is considered invalid if it's only possible due to the presence of phantom tiles. - /// - /// The region to check - /// The x coordinate of the edited tile - /// The y coordinate of the edited tile - /// The type of the edit - /// true if the edit was valid; false if it wasn't + /// Checks whether a player's attempted tile edit is valid. A tile edit is considered invalid if it's only possible due to the presence of phantom tiles. + /// The region to check. + /// The x coordinate of the edited tile. + /// The y coordinate of the edited tile. + /// The type of the edit. + /// true if the edit was valid; false if it wasn't. public bool tileValidityCheck(Region region, int x, int y, GetDataHandlers.EditAction editType) { // Check if there's a wall or another tile next to this tile. if (editType == GetDataHandlers.EditAction.PlaceWall) { @@ -531,12 +354,10 @@ private void onPlayerLeave(TerrariaApi.Server.LeaveEventArgs e) { } } - /// - /// Returns the item used to attempt a rejected foreground tile edit to the player - /// + /// Returns the item used to attempt a rejected foreground tile edit to the player. /// The player attempting the edit /// The data from the edit event - void giveTile(Player player, TShockAPI.GetDataHandlers.TileEditEventArgs e) { + public void giveTile(Player player, TShockAPI.GetDataHandlers.TileEditEventArgs e) { Item item = new Item(); bool found = false; for (int i = 1; i <= Terraria.ID.ItemID.Count; i++) { item.SetDefaults(i, true); @@ -549,12 +370,10 @@ void giveTile(Player player, TShockAPI.GetDataHandlers.TileEditEventArgs e) { if (found) giveItem(player, item); } - /// - /// Returns the item used to attempt a rejected background wall edit to the player - /// + /// Returns the item used to attempt a rejected background wall edit to the player. /// The player attempting the edit /// The data from the edit event - void giveWall(Player player, TShockAPI.GetDataHandlers.TileEditEventArgs e) { + public void giveWall(Player player, TShockAPI.GetDataHandlers.TileEditEventArgs e) { Item item = new Item(); bool found = false; for (int i = 1; i <= Terraria.ID.ItemID.Count; i++) { item.SetDefaults(i, true); @@ -566,12 +385,10 @@ void giveWall(Player player, TShockAPI.GetDataHandlers.TileEditEventArgs e) { if (found) giveItem(player, item); } - /// - /// Gives an item to a player - /// + /// Gives an item to a player. /// The player to receive the item /// The item to give - void giveItem(Player player, Item item) { + public void giveItem(Player player, Item item) { int itemID = Item.NewItem((int) player.TSPlayer.X, (int) player.TSPlayer.Y, item.width, item.height, item.type, 1, true, 0, true); Terraria.Main.item[itemID].owner = player.index; NetMessage.SendData((int) PacketTypes.ItemDrop, -1, -1, "", itemID, 0f, 0f, 0f); @@ -665,9 +482,7 @@ private void refreshTimer_Elapsed(object sender, ElapsedEventArgs e) { } } - /// - /// Checks whether a given player is near a given region - /// + /// Checks whether a given player is near a given region. /// The player to check /// The region to check /// true if the player is within 100 tiles of the region; false otherwise diff --git a/RegionVision/RegionVision.csproj b/RegionVision/RegionVision.csproj index 9280758..f26c21a 100644 --- a/RegionVision/RegionVision.csproj +++ b/RegionVision/RegionVision.csproj @@ -45,6 +45,8 @@ + + diff --git a/bins/RegionVision.dll b/bins/RegionVision.dll index be7d547..7e36d68 100644 Binary files a/bins/RegionVision.dll and b/bins/RegionVision.dll differ diff --git a/changelog.md b/changelog.md index 93ce08e..ba02703 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,9 @@ +Version 1.2 – 9 March 2015 +-------------------------- + +* Updated for the Terraria Server API version 1.17. +* I now use the RegionDeleted hook to inform users immediately and descriptively when a region they are viewing is deleted. It turns out I can't use RegionEntered and RegionLeft, because they don't work when regions overlap. + Version 1.1 – 21 July 2014 -------------------------- diff --git a/refs/TShockAPI.dll b/refs/TShockAPI.dll index d672eb1..3b5b70a 100644 Binary files a/refs/TShockAPI.dll and b/refs/TShockAPI.dll differ diff --git a/refs/TerrariaServer.exe b/refs/TerrariaServer.exe index 2c6dde0..ec9f53a 100644 Binary files a/refs/TerrariaServer.exe and b/refs/TerrariaServer.exe differ