diff --git a/Content.Server/Administration/Commands/TagCommands.cs b/Content.Server/Administration/Commands/TagCommands.cs new file mode 100644 index 0000000000..790768be92 --- /dev/null +++ b/Content.Server/Administration/Commands/TagCommands.cs @@ -0,0 +1,113 @@ +using Content.Shared.Administration; +using Content.Shared.Tag; +using Robust.Shared.Console; + +namespace Content.Server.Administration.Commands +{ + [AdminCommand(AdminFlags.Debug)] + public sealed class AddTagCommand : LocalizedCommands + { + [Dependency] private readonly IEntityManager _entityManager = default!; + + public override string Command => "addtag"; + public override string Description => Loc.GetString("addtag-command-description"); + public override string Help => Loc.GetString("addtag-command-help"); + + public override void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (args.Length != 2) + { + shell.WriteError(Loc.GetString("shell-wrong-arguments-number")); + return; + } + + if (!EntityUid.TryParse(args[0], out var entityUid)) + { + shell.WriteError(Loc.GetString("shell-entity-uid-must-be-number")); + return; + } + + if (!_entityManager.TrySystem(out TagSystem? tagSystem)) + return; + _entityManager.EnsureComponent(entityUid); + + if (tagSystem.TryAddTag(entityUid, args[1])) + { + shell.WriteLine(Loc.GetString("addtag-command-success", ("tag", args[1]), ("target", entityUid))); + } + else + { + shell.WriteError(Loc.GetString("addtag-command-fail", ("tag", args[1]), ("target", entityUid))); + } + } + + public override CompletionResult GetCompletion(IConsoleShell shell, string[] args) + { + if (args.Length == 1) + { + return CompletionResult.FromHint(Loc.GetString("shell-argument-uid")); + } + + if (args.Length == 2) + { + return CompletionResult.FromHintOptions(CompletionHelper.PrototypeIDs(), + Loc.GetString("tag-command-arg-tag")); + } + + return CompletionResult.Empty; + } + } + + [AdminCommand(AdminFlags.Debug)] + public sealed class RemoveTagCommand : LocalizedCommands + { + [Dependency] private readonly IEntityManager _entityManager = default!; + + public override string Command => "removetag"; + public override string Description => Loc.GetString("removetag-command-description"); + public override string Help => Loc.GetString("removetag-command-help"); + + public override void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (args.Length != 2) + { + shell.WriteError(Loc.GetString("shell-wrong-arguments-number")); + return; + } + + if (!EntityUid.TryParse(args[0], out var entityUid)) + { + shell.WriteError(Loc.GetString("shell-entity-uid-must-be-number")); + return; + } + + if (!_entityManager.TrySystem(out TagSystem? tagSystem)) + return; + + if (tagSystem.RemoveTag(entityUid, args[1])) + { + shell.WriteLine(Loc.GetString("removetag-command-success", ("tag", args[1]), ("target", entityUid))); + } + else + { + shell.WriteError(Loc.GetString("removetag-command-fail", ("tag", args[1]), ("target", entityUid))); + } + } + + public override CompletionResult GetCompletion(IConsoleShell shell, string[] args) + { + if (args.Length == 1) + { + return CompletionResult.FromHint(Loc.GetString("shell-argument-uid")); + } + + if (args.Length == 2&& EntityUid.TryParse(args[0], out var entityUid) && _entityManager.TryGetComponent(entityUid, out TagComponent? tagComponent)) + { + return CompletionResult.FromHintOptions(tagComponent.Tags, + Loc.GetString("tag-command-arg-tag")); + } + + return CompletionResult.Empty; + } + } +} diff --git a/Content.Server/Mind/Mind.cs b/Content.Server/Mind/Mind.cs index ffdafe6d69..c022300b89 100644 --- a/Content.Server/Mind/Mind.cs +++ b/Content.Server/Mind/Mind.cs @@ -122,6 +122,13 @@ namespace Content.Server.Mind [DataField("preventGhosting")] public bool PreventGhosting { get; set; } + /// + /// Prevents user from suiciding + /// + [ViewVariables(VVAccess.ReadWrite)] + [DataField("preventSuicide")] + public bool PreventSuicide { get; set; } + /// /// The session of the player owning this mind. /// Can be null, in which case the player is currently not logged in. diff --git a/Content.Server/Mind/MindSystem.cs b/Content.Server/Mind/MindSystem.cs index 549f85e108..f9101234ce 100644 --- a/Content.Server/Mind/MindSystem.cs +++ b/Content.Server/Mind/MindSystem.cs @@ -5,6 +5,7 @@ using Content.Server.Mind.Components; using Content.Shared.Examine; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; +using Content.Shared.Interaction.Events; using Robust.Shared.Map; using Robust.Shared.Timing; @@ -23,6 +24,7 @@ public sealed class MindSystem : EntitySystem SubscribeLocalEvent(OnShutdown); SubscribeLocalEvent(OnExamined); + SubscribeLocalEvent(OnSuicide); } public void SetGhostOnShutdown(EntityUid uid, bool value, MindComponent? mind = null) @@ -157,4 +159,15 @@ public sealed class MindSystem : EntitySystem args.PushMarkup($"[color=yellow]{Loc.GetString("comp-mind-examined-ssd", ("ent", uid))}[/color]"); } } + + private void OnSuicide(EntityUid uid, MindComponent component, SuicideEvent args) + { + if (args.Handled) + return; + + if (component.HasMind && component.Mind!.PreventSuicide) + { + args.BlockSuicideAttempt(true); + } + } } diff --git a/Resources/Locale/en-US/administration/commands/tag-commands.ftl b/Resources/Locale/en-US/administration/commands/tag-commands.ftl new file mode 100644 index 0000000000..898b6f0f2d --- /dev/null +++ b/Resources/Locale/en-US/administration/commands/tag-commands.ftl @@ -0,0 +1,13 @@ +addtag-command-description = Adds a tag to a given entity +addtag-command-help = Usage: addtag + +addtag-command-success = Added {$tag} to {$target}. +addtag-command-fail = Could not add {$tag} to {$target}. + +removetag-command-description = Removes a tag from a given entity +removetag-command-help = Usage: removetag + +removetag-command-success = Removed {$tag} from {$target}. +removetag-command-fail = Could not remove {$tag} from {$target}. + +tag-command-arg-tag = Tag diff --git a/Resources/Locale/en-US/shell.ftl b/Resources/Locale/en-US/shell.ftl index bb91ffb18e..aa76563d54 100644 --- a/Resources/Locale/en-US/shell.ftl +++ b/Resources/Locale/en-US/shell.ftl @@ -19,6 +19,8 @@ shell-argument-must-be-boolean = Argument must be a boolean. shell-wrong-arguments-number = Wrong number of arguments. shell-need-between-arguments = Need {$lower} to {$upper} arguments! +shell-argument-uid = EntityUid + ## Guards shell-entity-is-not-mob = Target entity is not a mob!