From 0172613a7deabe4a16ded890203b52d9b336543a Mon Sep 17 00:00:00 2001 From: DrSmugleaf Date: Sun, 20 Dec 2020 04:31:39 +0100 Subject: [PATCH] Remove wireless surgery (#2785) * Remove wireless surgery * Change surgery window title to Surgery * Remove todo * Check only tools with a window open --- .../Components/Body/Surgery/SurgeryWindow.cs | 2 +- .../Messages/SurgeryWindowCloseMessage.cs | 12 +++ .../Messages/SurgeryWindowOpenMessage.cs | 14 ++++ .../Body/Surgery/SurgeryToolComponent.cs | 79 +++++++++++-------- .../Body/Surgery/SurgeryToolSystem.cs | 64 +++++++++++++++ 5 files changed, 136 insertions(+), 35 deletions(-) create mode 100644 Content.Server/GameObjects/Components/Body/Surgery/Messages/SurgeryWindowCloseMessage.cs create mode 100644 Content.Server/GameObjects/Components/Body/Surgery/Messages/SurgeryWindowOpenMessage.cs create mode 100644 Content.Server/GameObjects/EntitySystems/Body/Surgery/SurgeryToolSystem.cs diff --git a/Content.Client/GameObjects/Components/Body/Surgery/SurgeryWindow.cs b/Content.Client/GameObjects/Components/Body/Surgery/SurgeryWindow.cs index d380569b46..656aeda4a7 100644 --- a/Content.Client/GameObjects/Components/Body/Surgery/SurgeryWindow.cs +++ b/Content.Client/GameObjects/Components/Body/Surgery/SurgeryWindow.cs @@ -19,7 +19,7 @@ namespace Content.Client.GameObjects.Components.Body.Surgery public SurgeryWindow() { - Title = Loc.GetString("Select surgery target..."); + Title = Loc.GetString("Surgery"); RectClipContent = true; var vSplitContainer = new VBoxContainer diff --git a/Content.Server/GameObjects/Components/Body/Surgery/Messages/SurgeryWindowCloseMessage.cs b/Content.Server/GameObjects/Components/Body/Surgery/Messages/SurgeryWindowCloseMessage.cs new file mode 100644 index 0000000000..e149aa40d4 --- /dev/null +++ b/Content.Server/GameObjects/Components/Body/Surgery/Messages/SurgeryWindowCloseMessage.cs @@ -0,0 +1,12 @@ +namespace Content.Server.GameObjects.Components.Body.Surgery.Messages +{ + public class SurgeryWindowCloseMessage + { + public SurgeryWindowCloseMessage(SurgeryToolComponent tool) + { + Tool = tool; + } + + public SurgeryToolComponent Tool { get; } + } +} diff --git a/Content.Server/GameObjects/Components/Body/Surgery/Messages/SurgeryWindowOpenMessage.cs b/Content.Server/GameObjects/Components/Body/Surgery/Messages/SurgeryWindowOpenMessage.cs new file mode 100644 index 0000000000..5b79acb0a6 --- /dev/null +++ b/Content.Server/GameObjects/Components/Body/Surgery/Messages/SurgeryWindowOpenMessage.cs @@ -0,0 +1,14 @@ +using Robust.Shared.GameObjects; + +namespace Content.Server.GameObjects.Components.Body.Surgery.Messages +{ + public class SurgeryWindowOpenMessage : ComponentMessage + { + public SurgeryWindowOpenMessage(SurgeryToolComponent tool) + { + Tool = tool; + } + + public SurgeryToolComponent Tool { get; } + } +} diff --git a/Content.Server/GameObjects/Components/Body/Surgery/SurgeryToolComponent.cs b/Content.Server/GameObjects/Components/Body/Surgery/SurgeryToolComponent.cs index 7173bde58f..ac1aaa3ad7 100644 --- a/Content.Server/GameObjects/Components/Body/Surgery/SurgeryToolComponent.cs +++ b/Content.Server/GameObjects/Components/Body/Surgery/SurgeryToolComponent.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using Content.Server.GameObjects.Components.Body.Surgery.Messages; using Content.Server.Utility; using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Body; @@ -37,18 +38,18 @@ namespace Content.Server.GameObjects.Components.Body.Surgery private float _baseOperateTime; - private IBody? _bodyCache; - private ISurgeon.MechanismRequestCallback? _callbackCache; private int _idHash; - private IEntity? _performerCache; - private SurgeryType _surgeryType; [ViewVariables] private BoundUserInterface? UserInterface => Owner.GetUIOrNull(SurgeryUIKey.Key); + public IBody? BodyCache { get; private set; } + + public IEntity? PerformerCache { get; private set; } + async Task IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (eventArgs.Target == null) @@ -62,11 +63,6 @@ namespace Content.Server.GameObjects.Components.Body.Surgery } CloseAllSurgeryUIs(); - _optionsCache.Clear(); - - _performerCache = null; - _bodyCache = null; - _callbackCache = null; // Attempt surgery on a body by sending a list of operable parts for the client to choose from if (eventArgs.Target.TryGetComponent(out IBody? body)) @@ -88,8 +84,8 @@ namespace Content.Server.GameObjects.Components.Body.Surgery { OpenSurgeryUI(actor.playerSession); UpdateSurgeryUIBodyPartRequest(actor.playerSession, toSend); - _performerCache = eventArgs.User; // Also, cache the data. - _bodyCache = body; + PerformerCache = eventArgs.User; // Also, cache the data. + BodyCache = body; } else // If surgery cannot be performed, show message saying so. { @@ -99,7 +95,7 @@ namespace Content.Server.GameObjects.Components.Body.Surgery else if (eventArgs.Target.TryGetComponent(out var part)) { // Attempt surgery on a DroppedBodyPart - there's only one possible target so no need for selection UI - _performerCache = eventArgs.User; + PerformerCache = eventArgs.User; // If surgery can be performed... if (!part.SurgeryCheck(_surgeryType)) @@ -132,10 +128,10 @@ namespace Content.Server.GameObjects.Components.Body.Surgery toSend.Add(mechanism.Name, _idHash++); } - if (_optionsCache.Count > 0 && _performerCache != null) + if (_optionsCache.Count > 0 && PerformerCache != null) { - OpenSurgeryUI(_performerCache.GetComponent().playerSession); - UpdateSurgeryUIMechanismRequest(_performerCache.GetComponent().playerSession, + OpenSurgeryUI(PerformerCache.GetComponent().playerSession); + UpdateSurgeryUIMechanismRequest(PerformerCache.GetComponent().playerSession, toSend); _callbackCache = callback; } @@ -146,6 +142,14 @@ namespace Content.Server.GameObjects.Components.Body.Surgery } } + public override void ExposeData(ObjectSerializer serializer) + { + base.ExposeData(serializer); + + serializer.DataField(ref _surgeryType, "surgeryType", SurgeryType.Incision); + serializer.DataField(ref _baseOperateTime, "baseOperateTime", 5); + } + public override void Initialize() { base.Initialize(); @@ -156,10 +160,14 @@ namespace Content.Server.GameObjects.Components.Body.Surgery } } - // TODO BODY add checks to close UI if user walks too far away from tool or target. private void OpenSurgeryUI(IPlayerSession session) { UserInterface?.Open(session); + + var message = new SurgeryWindowOpenMessage(this); + + SendMessage(message); + Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local, message); } private void UpdateSurgeryUIBodyPartRequest(IPlayerSession session, Dictionary options) @@ -172,14 +180,25 @@ namespace Content.Server.GameObjects.Components.Body.Surgery UserInterface?.SendMessage(new RequestMechanismSurgeryUIMessage(options), session); } + private void ClearUIData() + { + _optionsCache.Clear(); + + PerformerCache = null; + BodyCache = null; + _callbackCache = null; + } + private void CloseSurgeryUI(IPlayerSession session) { UserInterface?.Close(session); + ClearUIData(); } - private void CloseAllSurgeryUIs() + public void CloseAllSurgeryUIs() { UserInterface?.CloseAll(); + ClearUIData(); } private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage message) @@ -201,8 +220,8 @@ namespace Content.Server.GameObjects.Components.Body.Surgery /// private void HandleReceiveBodyPart(int key) { - if (_performerCache == null || - !_performerCache.TryGetComponent(out IActorComponent? actor)) + if (PerformerCache == null || + !PerformerCache.TryGetComponent(out IActorComponent? actor)) { return; } @@ -210,7 +229,7 @@ namespace Content.Server.GameObjects.Components.Body.Surgery CloseSurgeryUI(actor.playerSession); // TODO: sanity checks to see whether user is in range, user is still able-bodied, target is still the same, etc etc if (!_optionsCache.TryGetValue(key, out var targetObject) || - _bodyCache == null) + BodyCache == null) { NotUsefulAnymorePopup(); return; @@ -219,7 +238,7 @@ namespace Content.Server.GameObjects.Components.Body.Surgery var target = (IBodyPart) targetObject!; // TODO BODY Reconsider - if (!target.AttemptSurgery(_surgeryType, _bodyCache, this, _performerCache)) + if (!target.AttemptSurgery(_surgeryType, BodyCache, this, PerformerCache)) { NotUsefulAnymorePopup(); } @@ -233,8 +252,8 @@ namespace Content.Server.GameObjects.Components.Body.Surgery { // TODO: sanity checks to see whether user is in range, user is still able-bodied, target is still the same, etc etc if (!_optionsCache.TryGetValue(key, out var targetObject) || - _performerCache == null || - !_performerCache.TryGetComponent(out IActorComponent? actor)) + PerformerCache == null || + !PerformerCache.TryGetComponent(out IActorComponent? actor)) { NotUsefulAnymorePopup(); return; @@ -243,27 +262,19 @@ namespace Content.Server.GameObjects.Components.Body.Surgery var target = targetObject as MechanismComponent; CloseSurgeryUI(actor.playerSession); - _callbackCache?.Invoke(target, _bodyCache, this, _performerCache); + _callbackCache?.Invoke(target, BodyCache, this, PerformerCache); } private void NotUsefulPopup() { - _bodyCache?.Owner.PopupMessage(_performerCache, + BodyCache?.Owner.PopupMessage(PerformerCache, Loc.GetString("You see no useful way to use {0:theName}.", Owner)); } private void NotUsefulAnymorePopup() { - _bodyCache?.Owner.PopupMessage(_performerCache, + BodyCache?.Owner.PopupMessage(PerformerCache, Loc.GetString("You see no useful way to use {0:theName} anymore.", Owner)); } - - public override void ExposeData(ObjectSerializer serializer) - { - base.ExposeData(serializer); - - serializer.DataField(ref _surgeryType, "surgeryType", SurgeryType.Incision); - serializer.DataField(ref _baseOperateTime, "baseOperateTime", 5); - } } } diff --git a/Content.Server/GameObjects/EntitySystems/Body/Surgery/SurgeryToolSystem.cs b/Content.Server/GameObjects/EntitySystems/Body/Surgery/SurgeryToolSystem.cs new file mode 100644 index 0000000000..a7e6205e0c --- /dev/null +++ b/Content.Server/GameObjects/EntitySystems/Body/Surgery/SurgeryToolSystem.cs @@ -0,0 +1,64 @@ +using System.Collections.Generic; +using Content.Server.GameObjects.Components.Body.Surgery; +using Content.Server.GameObjects.Components.Body.Surgery.Messages; +using Content.Shared.GameObjects.EntitySystems; +using Content.Shared.GameTicking; +using Content.Shared.Utility; +using JetBrains.Annotations; +using Robust.Shared.GameObjects.Systems; + +namespace Content.Server.GameObjects.EntitySystems.Body.Surgery +{ + [UsedImplicitly] + public class SurgeryToolSystem : EntitySystem, IResettingEntitySystem + { + private readonly HashSet _openSurgeryUIs = new(); + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnSurgeryWindowOpen); + SubscribeLocalEvent(OnSurgeryWindowClose); + } + + public void Reset() + { + _openSurgeryUIs.Clear(); + } + + private void OnSurgeryWindowOpen(SurgeryWindowOpenMessage ev) + { + _openSurgeryUIs.Add(ev.Tool); + } + + private void OnSurgeryWindowClose(SurgeryWindowCloseMessage ev) + { + _openSurgeryUIs.Remove(ev.Tool); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + foreach (var tool in _openSurgeryUIs) + { + if (tool.PerformerCache == null) + { + continue; + } + + if (tool.BodyCache == null) + { + continue; + } + + if (!ActionBlockerSystem.CanInteract(tool.PerformerCache) || + !tool.PerformerCache.InRangeUnobstructed(tool.BodyCache)) + { + tool.CloseAllSurgeryUIs(); + } + } + } + } +}