From 090dd8cee8a5ddd2d6eb125849f243f453cc8ac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Aguilera=20Puerto?= <6766154+Zumorica@users.noreply.github.com> Date: Mon, 24 Feb 2020 03:49:40 +0100 Subject: [PATCH] ControlMob verb and command (#724) * ControlMob verb and command, mobs have MindComponent by default * Use IActorComponent instead of MindComponent for User entity. Fixes using Control Mob while aghosting/visiting an entity. * Use static Loc class --- Content.Server/Administration/ControlMob.cs | 66 +++++++++++++++++++ Content.Server/GlobalVerbs/ControlMobVerb.cs | 50 ++++++++++++++ Resources/Groups/groups.yml | 2 + Resources/Prototypes/Entities/mobs/human.yml | 1 + .../Prototypes/Entities/mobs/observer.yml | 1 + 5 files changed, 120 insertions(+) create mode 100644 Content.Server/Administration/ControlMob.cs create mode 100644 Content.Server/GlobalVerbs/ControlMobVerb.cs diff --git a/Content.Server/Administration/ControlMob.cs b/Content.Server/Administration/ControlMob.cs new file mode 100644 index 0000000000..ed170cac3f --- /dev/null +++ b/Content.Server/Administration/ControlMob.cs @@ -0,0 +1,66 @@ +using Content.Server.GameObjects.Components.Mobs; +using Content.Server.Mobs; +using Content.Server.Players; +using Robust.Server.Interfaces.Console; +using Robust.Server.Interfaces.Player; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Localization; + +namespace Content.Server.Administration +{ + class ControlMob : IClientCommand + { + public string Command => "controlmob"; + public string Description => Loc.GetString("Transfers user mind to the specified entity."); + public string Help => Loc.GetString("Usage: controlmob ."); + + public void Execute(IConsoleShell shell, IPlayerSession player, string[] args) + { + if (player == null) + { + shell.SendText((IPlayerSession) null, "Server cannot do this."); + return; + } + + if (args.Length != 1) + { + shell.SendText(player, Loc.GetString("Wrong number of arguments.")); + return; + } + + + var mind = player.ContentData().Mind; + var entityManager = IoCManager.Resolve(); + + if (!int.TryParse(args[0], out var targetId)) + { + shell.SendText(player, Loc.GetString("Argument must be a number.")); + return; + } + + var eUid = new EntityUid(targetId); + + if (!eUid.IsValid() || !entityManager.EntityExists(eUid)) + { + shell.SendText(player, Loc.GetString("Invalid entity ID.")); + return; + } + + var target = entityManager.GetEntity(eUid); + if (!target.TryGetComponent(out MindComponent mindComponent)) + { + shell.SendText(player, Loc.GetString("Target entity is not a mob!")); + return; + } + + if(mind.IsVisitingEntity) + mind.UnVisit(); + + mindComponent.Mind?.TransferTo(null); + mind.TransferTo(target); + + } + } +} diff --git a/Content.Server/GlobalVerbs/ControlMobVerb.cs b/Content.Server/GlobalVerbs/ControlMobVerb.cs new file mode 100644 index 0000000000..c9892beba5 --- /dev/null +++ b/Content.Server/GlobalVerbs/ControlMobVerb.cs @@ -0,0 +1,50 @@ +using Content.Server.GameObjects; +using Content.Server.GameObjects.Components.Mobs; +using Content.Server.GameObjects.Components.Nutrition; +using Content.Server.Players; +using Content.Shared.GameObjects; +using Robust.Server.Console; +using Robust.Server.Interfaces.GameObjects; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Log; + +namespace Content.Server.GlobalVerbs +{ + [GlobalVerb] + public class ControlMobVerb : GlobalVerb + { + public override string GetText(IEntity user, IEntity target) => "Control Mob"; + public override bool RequireInteractionRange => false; + + public override VerbVisibility GetVisibility(IEntity user, IEntity target) + { + var groupController = IoCManager.Resolve(); + if (user == target) return VerbVisibility.Invisible; + + if (user.TryGetComponent(out var player)) + { + if (!user.HasComponent() || !target.HasComponent()) + return VerbVisibility.Invisible; + + if (groupController.CanCommand(player.playerSession, "controlmob")) + return VerbVisibility.Visible; + } + + return VerbVisibility.Invisible; + } + + public override void Activate(IEntity user, IEntity target) + { + var userMind = user.GetComponent().playerSession.ContentData().Mind; + var targetMind = target.GetComponent(); + + if(userMind.IsVisitingEntity) + userMind.UnVisit(); + + targetMind.Mind?.TransferTo(null); + userMind.TransferTo(target); + } + } +} diff --git a/Resources/Groups/groups.yml b/Resources/Groups/groups.yml index 5a3b6882ea..d1fe708455 100644 --- a/Resources/Groups/groups.yml +++ b/Resources/Groups/groups.yml @@ -55,6 +55,7 @@ - respawn - rejuvenate - addcomp + - controlmob - kick - listplayers - loc @@ -94,6 +95,7 @@ - respawn - rejuvenate - addcomp + - controlmob - kick - listplayers - loc diff --git a/Resources/Prototypes/Entities/mobs/human.yml b/Resources/Prototypes/Entities/mobs/human.yml index 3ae50bfaa9..d455a96e7a 100644 --- a/Resources/Prototypes/Entities/mobs/human.yml +++ b/Resources/Prototypes/Entities/mobs/human.yml @@ -5,6 +5,7 @@ description: A miserable pile of secrets drawdepth: Mobs components: + - type: Mind - type: Hands hands: - left diff --git a/Resources/Prototypes/Entities/mobs/observer.yml b/Resources/Prototypes/Entities/mobs/observer.yml index 81ea97f64f..c99257b300 100644 --- a/Resources/Prototypes/Entities/mobs/observer.yml +++ b/Resources/Prototypes/Entities/mobs/observer.yml @@ -4,6 +4,7 @@ save: false description: Boo! components: + - type: Mind - type: Physics mass: 5 - type: Eye