diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index 2214f252d..d39b84e0c 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -6462,7 +6462,7 @@ private static void GBuff(CommandArgs args) if (target == user) user.SendSuccessMessage(GetString($"You buffed yourself with {TShock.Utils.GetBuffName(id)} ({TShock.Utils.GetBuffDescription(id)}) for {time} seconds.")); else - target.SendSuccessMessage(GetString($"You have buffed {user.Name} with {TShock.Utils.GetBuffName(id)} ({TShock.Utils.GetBuffDescription(id)}) for {time} seconds!")); + user.SendSuccessMessage(GetString($"You have buffed {target.Name} with {TShock.Utils.GetBuffName(id)} ({TShock.Utils.GetBuffDescription(id)}) for {time} seconds!")); if (!args.Silent && target != user) target.SendSuccessMessage(GetString($"{user.Name} has buffed you with {TShock.Utils.GetBuffName(id)} ({TShock.Utils.GetBuffDescription(id)}) for {time} seconds!")); } @@ -6740,10 +6740,6 @@ private static void ToggleGodMode(CommandArgs args) playerToGod.GodMode = !playerToGod.GodMode; - var godPower = CreativePowerManager.Instance.GetPower(); - - godPower.SetEnabledState(playerToGod.Index, playerToGod.GodMode); - if (playerToGod != args.Player) { args.Player.SendSuccessMessage(playerToGod.GodMode diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index ef5c3c228..c9194c368 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -34,6 +34,7 @@ You should have received a copy of the GNU General Public License using TShockAPI.Net; using Timer = System.Timers.Timer; using System.Linq; +using Terraria.GameContent.Creative; namespace TShockAPI { @@ -935,9 +936,15 @@ public bool HasModifiedIceSuccessfully(int x, int y, short tileType, GetDataHand public bool LoginHarassed = false; /// - /// Player cant die, unless onehit + /// Controls the journey godmode /// - public bool GodMode = false; + public bool GodMode + { + get => + CreativePowerManager.Instance.GetPower().IsEnabledForPlayer(Index); + set => + CreativePowerManager.Instance.GetPower().SetEnabledState(Index, value); + } /// /// Players controls are inverted if using SSC @@ -981,7 +988,7 @@ public bool ConnectionAlive get { return RealPlayer - && (Netplay.Clients[Index] != null && Netplay.Clients[Index].IsActive && !Netplay.Clients[Index].PendingTermination); + && (Client != null && Client.IsActive && !Client.PendingTermination); } } @@ -998,8 +1005,8 @@ public Item SelectedItem /// public int State { - get { return Netplay.Clients[Index].State; } - set { Netplay.Clients[Index].State = value; } + get { return Client.State; } + set { Client.State = value; } } /// @@ -1007,7 +1014,7 @@ public int State /// public string UUID { - get { return RealPlayer ? Netplay.Clients[Index].ClientUUID : ""; } + get { return RealPlayer ? Client.ClientUUID : ""; } } /// @@ -1019,8 +1026,8 @@ public string IP { if (string.IsNullOrEmpty(CacheIP)) return - CacheIP = RealPlayer ? (Netplay.Clients[Index].Socket.IsConnected() - ? TShock.Utils.GetRealIP(Netplay.Clients[Index].Socket.GetRemoteAddress().ToString()) + CacheIP = RealPlayer ? (Client.Socket.IsConnected() + ? TShock.Utils.GetRealIP(Client.Socket.GetRemoteAddress().ToString()) : "") : "127.0.0.1"; else @@ -1103,6 +1110,11 @@ public bool SendServerCharacter() } + /// + /// Player RemoteClient. + /// + public RemoteClient Client => Netplay.Clients[Index]; + /// /// Gets the Terraria Player object associated with the player. /// @@ -1135,6 +1147,11 @@ public int Team get { return TPlayer.team; } } + /// + /// Gets PvP player mode. + /// + public bool Hostile => TPlayer.hostile; + /// /// Gets the player's X coordinate. /// @@ -1487,6 +1504,41 @@ public virtual bool SendTileRect(short x, short y, byte width = 10, byte length return false; } + /// + /// Changes the values of the array. + /// + /// The area of the sections you want to set a value to. + /// The minimum size should be set to 200x150. If null, then the entire map is specified. + /// Is the section loaded. + // The server does not send the player the whole world, it sends it in sections. To do this, it sets up visible and invisible sections. + // If the player was not in any section(Client.TileSections[x, y] == false) then the server will send the missing section of the world. + // This method allows you to simulate what the player has or has not seen these sections. + // For example, we can put some number of earths blocks in some vast area, for example, for the whole world, but the player will not see the changes, because some section is already loaded for him. At this point this method can come into effect! With it we will be able to select some zone and make it both visible and invisible to the player. + // The server will assume that the zone is not loaded on the player, and will resend the data, but with earth blocks. + public void UpdateSection(Rectangle? rectangle = null, bool isLoaded = false) + { + if (rectangle.HasValue) + { + for (int i = Netplay.GetSectionX(rectangle.Value.X); i < Netplay.GetSectionX(rectangle.Value.X + rectangle.Value.Width) && i < Main.maxSectionsX; i++) + { + for (int j = Netplay.GetSectionY(rectangle.Value.Y); j < Netplay.GetSectionY(rectangle.Value.Y + rectangle.Value.Height) && j < Main.maxSectionsY; j++) + { + Client.TileSections[i, j] = isLoaded; + } + } + } + else + { + for (int i = 0; i < Main.maxSectionsX; i++) + { + for (int j = 0; j < Main.maxSectionsY; j++) + { + Client.TileSections[i, j] = isLoaded; + } + } + } + } + /// /// Gives an item to the player. Includes banned item spawn prevention to check if the player can spawn the item. /// @@ -1519,6 +1571,15 @@ public virtual void GiveItem(int type, int stack, int prefix = 0) GiveItemByDrop(type, stack, prefix); } + /// + /// Gives an item to the player. + /// + /// Item with data to be given to the player. + public virtual void GiveItem(NetItem item) + { + GiveItem(item.NetId, item.Stack, item.PrefixId); + } + private Item EmptySentinelItem = new Item(); private bool Depleted(Item item) @@ -1815,7 +1876,17 @@ public void SendFileTextAsMessage(string file) /// The amount of damage the player will take. public virtual void DamagePlayer(int damage) { - NetMessage.SendPlayerHurt(Index, PlayerDeathReason.LegacyDefault(), damage, (new Random()).Next(-1, 1), false, false, 0, -1, -1); + DamagePlayer(damage, PlayerDeathReason.LegacyDefault()); + } + + /// + /// Wounds the player with the given damage. + /// + /// The amount of damage the player will take. + /// The reason for causing damage to player. + public virtual void DamagePlayer(int damage, PlayerDeathReason reason) + { + NetMessage.SendPlayerHurt(Index, reason, damage, (new Random()).Next(-1, 1), false, false, 0, -1, -1); } /// @@ -1823,7 +1894,16 @@ public virtual void DamagePlayer(int damage) /// public virtual void KillPlayer() { - NetMessage.SendPlayerDeath(Index, PlayerDeathReason.LegacyDefault(), 99999, (new Random()).Next(-1, 1), false, -1, -1); + KillPlayer(PlayerDeathReason.LegacyDefault()); + } + + /// + /// Kills the player. + /// + /// Reason for killing a player. + public virtual void KillPlayer(PlayerDeathReason reason) + { + NetMessage.SendPlayerDeath(Index, reason, 99999, (new Random()).Next(-1, 1), false, -1, -1); } /// @@ -1832,6 +1912,8 @@ public virtual void KillPlayer() /// The team color index. public virtual void SetTeam(int team) { + if (team < 0 || team >= Main.teamColor.Length) + throw new ArgumentException("The player's team is not in the range of available."); Main.player[Index].team = team; NetMessage.SendData((int)PacketTypes.PlayerTeam, -1, -1, NetworkText.Empty, Index); } @@ -1840,6 +1922,7 @@ public virtual void SetTeam(int team) /// Sets the player's pvp. /// /// The state of the pvp mode. + /// Whether a chat message about the change should be sent. public virtual void SetPvP(bool mode, bool withMsg = false) { Main.player[Index].hostile = mode; @@ -2064,7 +2147,7 @@ public virtual void SendRawData(byte[] data) if (!RealPlayer || !ConnectionAlive) return; - Netplay.Clients[Index].Socket.AsyncSend(data, 0, data.Length, Netplay.Clients[Index].ServerWriteCallBack); + Client.Socket.AsyncSend(data, 0, data.Length, Client.ServerWriteCallBack); } /// diff --git a/docs/changelog.md b/docs/changelog.md index ec7f000fe..4b4645c12 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -78,6 +78,17 @@ Use past tense when adding new entries; sign your name off when you add or chang * If there is no section called "Upcoming changes" below this line, please add one with `## Upcoming changes` as the first line, and then a bulleted item directly after with the first change. --> ## Upcoming changes +* Updated `TSPlayer.GodMode`. (@AgaSpace) + * Previously the field was used as some kind of dataset changed by /godmode command, but now it is a property that receives/changes data in journey mode. +* Added the `TSPlayer.Client` property. It allows the developer to get the `RemoteClient` player, without an additional call to `Terraria.Netplay.Clients`. (@AgaSpace) +* Updated the documentation for the `TSPlayer.SetPvP` method. The `sendMsg` parameter, which is responsible for sending a pvp mode change message, was not documented earlier. (@AgaSpace) +* Added methods `TSPlayer.KillPlayer` and `TSPlayer.DamagePlayer` for which you can specify the cause (`PlayerDeathReason`) in parameters. (@AgaSpace) +* Added an error when trying to change a `TSPlayer` team to, say, 9, when there are only 6. (@AgaSpace) +* Added an error when trying to call the `TSPlayer.SetTeam` method with an argument (team) greater than 5 or less than 0. (@AgaSpace) +* Added a method `TSPlayer.UpdateSection` with arguments `rectangle` and `isLoaded`, which will load some area from the server to the player. (@AgaSpace) +* Added a method `TSPlayer.GiveItem`, which has `TShockAPI.NetItem` structure in its arguments. (@AgaSpace) +* Added a property `TSPlayer.Hostile`, which gets pvp player mode. (@AgaSpace) +* Fixed typo in `/gbuff`. (@sgkoishi, #2955) * Added more modification options to `Group`. (@AgaSpace) ## TShock 5.2