diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e3de480..e9243d03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Added more usage examples for the `ban` command under `ban help examples` to explain how users can ban: offline players by account, offline players by IP, and online players by player index - useful for banning hard to type character names. (@moisterrific) * Changed `/login` and `/register` to provide login help depending on if UUID login is enabled or disabled, and whether or not a player can login via any username or not. In addition, the message parameters will now be differentiated by colour instead of `<>` (@moisterrific, @hakusaro) * Added a new `DisablePrimeBombs` config option (`false` by default). Highly recommended to set this to `true` in order to prevent griefing on servers doing a `for the worthy` play-through, since the prime bombs on this seed can destroy most tiles and bypass region protection. (@moisterrific) +* Added a new `/respawn` command that lets you respawn yourself or another player. Respawning yourself requires the `tshock.respawn` permission and respawning others requires the `tshock.respawn.other` permission. The full command syntax is `/respawn [player]`. (@moisterrific) * Added a notification message and silent command support for permanently changing a target player's user group. Now players who received a group change will be notified of their new group if they are currently online. (@moisterrific, @QuiCM) ## TShock 4.5.5 diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index 6a76c651..3961bf1f 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -599,6 +599,10 @@ namespace TShockAPI { HelpText = "Sends all tiles from the server to the player to resync the client with the actual world state." }); + add(new Command(Permissions.respawn, Respawn, "respawn") + { + HelpText = "Respawn yourself or another player." + }); #endregion add(new Command(Aliases, "aliases") @@ -5664,6 +5668,55 @@ namespace TShockAPI plr.SendErrorMessage("{0} just killed you!", args.Player.Name); } } + + private static void Respawn(CommandArgs args) + { + if (!args.Player.RealPlayer) + { + args.Player.SendErrorMessage("You can't respawn the server console!"); + return; + } + TSPlayer playerToRespawn; + if (args.Parameters.Count > 0) + { + if (!args.Player.HasPermission(Permissions.respawnother)) + { + args.Player.SendErrorMessage("You do not have permission to respawn another player."); + return; + } + string plStr = String.Join(" ", args.Parameters); + var players = TSPlayer.FindByNameOrID(plStr); + if (players.Count == 0) + { + args.Player.SendErrorMessage($"Could not find any player named \"{plStr}\""); + return; + } + if (players.Count > 1) + { + args.Player.SendMultipleMatchError(players.Select(p => p.Name)); + return; + } + playerToRespawn = players[0]; + } + else + playerToRespawn = args.Player; + + if (!playerToRespawn.Dead) + { + args.Player.SendErrorMessage($"{(playerToRespawn == args.Player ? "You" : playerToRespawn.Name)} {(playerToRespawn == args.Player ? "are" : "is")} not dead."); + return; + } + playerToRespawn.Spawn(PlayerSpawnContext.ReviveFromDeath); + + if (playerToRespawn != args.Player) + { + args.Player.SendSuccessMessage($"You have respawned {playerToRespawn.Name}"); + if (!args.Silent) + playerToRespawn.SendSuccessMessage($"{args.Player.Name} has respawned you."); + } + else + playerToRespawn.SendSuccessMessage("You have respawned yourself."); + } private static void Butcher(CommandArgs args) { diff --git a/TShockAPI/Permissions.cs b/TShockAPI/Permissions.cs index 7df1ca83..7de195d2 100644 --- a/TShockAPI/Permissions.cs +++ b/TShockAPI/Permissions.cs @@ -436,6 +436,12 @@ namespace TShockAPI [Description("User can kill others.")] public static readonly string kill = "tshock.kill"; + + [Description("Player can respawn themselves.")] + public static readonly string respawn = "tshock.respawn"; + + [Description("Player can respawn others.")] + public static readonly string respawnother = "tshock.respawn.other"; [Description("Allows you to bypass the max slots for up to 5 slots above your max.")] public static readonly string reservedslot = "tshock.reservedslot";