Remove wireless surgery (#2785)

* Remove wireless surgery

* Change surgery window title to Surgery

* Remove todo

* Check only tools with a window open
This commit is contained in:
DrSmugleaf
2020-12-20 04:31:39 +01:00
committed by GitHub
parent a3fdcd3a68
commit 0172613a7d
5 changed files with 136 additions and 35 deletions

View File

@@ -19,7 +19,7 @@ namespace Content.Client.GameObjects.Components.Body.Surgery
public SurgeryWindow() public SurgeryWindow()
{ {
Title = Loc.GetString("Select surgery target..."); Title = Loc.GetString("Surgery");
RectClipContent = true; RectClipContent = true;
var vSplitContainer = new VBoxContainer var vSplitContainer = new VBoxContainer

View File

@@ -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; }
}
}

View File

@@ -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; }
}
}

View File

@@ -2,6 +2,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Body.Surgery.Messages;
using Content.Server.Utility; using Content.Server.Utility;
using Content.Shared.GameObjects; using Content.Shared.GameObjects;
using Content.Shared.GameObjects.Components.Body; using Content.Shared.GameObjects.Components.Body;
@@ -37,18 +38,18 @@ namespace Content.Server.GameObjects.Components.Body.Surgery
private float _baseOperateTime; private float _baseOperateTime;
private IBody? _bodyCache;
private ISurgeon.MechanismRequestCallback? _callbackCache; private ISurgeon.MechanismRequestCallback? _callbackCache;
private int _idHash; private int _idHash;
private IEntity? _performerCache;
private SurgeryType _surgeryType; private SurgeryType _surgeryType;
[ViewVariables] private BoundUserInterface? UserInterface => Owner.GetUIOrNull(SurgeryUIKey.Key); [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) async Task IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
{ {
if (eventArgs.Target == null) if (eventArgs.Target == null)
@@ -62,11 +63,6 @@ namespace Content.Server.GameObjects.Components.Body.Surgery
} }
CloseAllSurgeryUIs(); 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 // 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)) if (eventArgs.Target.TryGetComponent(out IBody? body))
@@ -88,8 +84,8 @@ namespace Content.Server.GameObjects.Components.Body.Surgery
{ {
OpenSurgeryUI(actor.playerSession); OpenSurgeryUI(actor.playerSession);
UpdateSurgeryUIBodyPartRequest(actor.playerSession, toSend); UpdateSurgeryUIBodyPartRequest(actor.playerSession, toSend);
_performerCache = eventArgs.User; // Also, cache the data. PerformerCache = eventArgs.User; // Also, cache the data.
_bodyCache = body; BodyCache = body;
} }
else // If surgery cannot be performed, show message saying so. 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<IBodyPart>(out var part)) else if (eventArgs.Target.TryGetComponent<IBodyPart>(out var part))
{ {
// Attempt surgery on a DroppedBodyPart - there's only one possible target so no need for selection UI // 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 surgery can be performed...
if (!part.SurgeryCheck(_surgeryType)) if (!part.SurgeryCheck(_surgeryType))
@@ -132,10 +128,10 @@ namespace Content.Server.GameObjects.Components.Body.Surgery
toSend.Add(mechanism.Name, _idHash++); toSend.Add(mechanism.Name, _idHash++);
} }
if (_optionsCache.Count > 0 && _performerCache != null) if (_optionsCache.Count > 0 && PerformerCache != null)
{ {
OpenSurgeryUI(_performerCache.GetComponent<BasicActorComponent>().playerSession); OpenSurgeryUI(PerformerCache.GetComponent<BasicActorComponent>().playerSession);
UpdateSurgeryUIMechanismRequest(_performerCache.GetComponent<BasicActorComponent>().playerSession, UpdateSurgeryUIMechanismRequest(PerformerCache.GetComponent<BasicActorComponent>().playerSession,
toSend); toSend);
_callbackCache = callback; _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() public override void Initialize()
{ {
base.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) private void OpenSurgeryUI(IPlayerSession session)
{ {
UserInterface?.Open(session); UserInterface?.Open(session);
var message = new SurgeryWindowOpenMessage(this);
SendMessage(message);
Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local, message);
} }
private void UpdateSurgeryUIBodyPartRequest(IPlayerSession session, Dictionary<string, int> options) private void UpdateSurgeryUIBodyPartRequest(IPlayerSession session, Dictionary<string, int> options)
@@ -172,14 +180,25 @@ namespace Content.Server.GameObjects.Components.Body.Surgery
UserInterface?.SendMessage(new RequestMechanismSurgeryUIMessage(options), session); UserInterface?.SendMessage(new RequestMechanismSurgeryUIMessage(options), session);
} }
private void ClearUIData()
{
_optionsCache.Clear();
PerformerCache = null;
BodyCache = null;
_callbackCache = null;
}
private void CloseSurgeryUI(IPlayerSession session) private void CloseSurgeryUI(IPlayerSession session)
{ {
UserInterface?.Close(session); UserInterface?.Close(session);
ClearUIData();
} }
private void CloseAllSurgeryUIs() public void CloseAllSurgeryUIs()
{ {
UserInterface?.CloseAll(); UserInterface?.CloseAll();
ClearUIData();
} }
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage message) private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage message)
@@ -201,8 +220,8 @@ namespace Content.Server.GameObjects.Components.Body.Surgery
/// </summary> /// </summary>
private void HandleReceiveBodyPart(int key) private void HandleReceiveBodyPart(int key)
{ {
if (_performerCache == null || if (PerformerCache == null ||
!_performerCache.TryGetComponent(out IActorComponent? actor)) !PerformerCache.TryGetComponent(out IActorComponent? actor))
{ {
return; return;
} }
@@ -210,7 +229,7 @@ namespace Content.Server.GameObjects.Components.Body.Surgery
CloseSurgeryUI(actor.playerSession); 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 // 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) || if (!_optionsCache.TryGetValue(key, out var targetObject) ||
_bodyCache == null) BodyCache == null)
{ {
NotUsefulAnymorePopup(); NotUsefulAnymorePopup();
return; return;
@@ -219,7 +238,7 @@ namespace Content.Server.GameObjects.Components.Body.Surgery
var target = (IBodyPart) targetObject!; var target = (IBodyPart) targetObject!;
// TODO BODY Reconsider // TODO BODY Reconsider
if (!target.AttemptSurgery(_surgeryType, _bodyCache, this, _performerCache)) if (!target.AttemptSurgery(_surgeryType, BodyCache, this, PerformerCache))
{ {
NotUsefulAnymorePopup(); 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 // 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) || if (!_optionsCache.TryGetValue(key, out var targetObject) ||
_performerCache == null || PerformerCache == null ||
!_performerCache.TryGetComponent(out IActorComponent? actor)) !PerformerCache.TryGetComponent(out IActorComponent? actor))
{ {
NotUsefulAnymorePopup(); NotUsefulAnymorePopup();
return; return;
@@ -243,27 +262,19 @@ namespace Content.Server.GameObjects.Components.Body.Surgery
var target = targetObject as MechanismComponent; var target = targetObject as MechanismComponent;
CloseSurgeryUI(actor.playerSession); CloseSurgeryUI(actor.playerSession);
_callbackCache?.Invoke(target, _bodyCache, this, _performerCache); _callbackCache?.Invoke(target, BodyCache, this, PerformerCache);
} }
private void NotUsefulPopup() private void NotUsefulPopup()
{ {
_bodyCache?.Owner.PopupMessage(_performerCache, BodyCache?.Owner.PopupMessage(PerformerCache,
Loc.GetString("You see no useful way to use {0:theName}.", Owner)); Loc.GetString("You see no useful way to use {0:theName}.", Owner));
} }
private void NotUsefulAnymorePopup() private void NotUsefulAnymorePopup()
{ {
_bodyCache?.Owner.PopupMessage(_performerCache, BodyCache?.Owner.PopupMessage(PerformerCache,
Loc.GetString("You see no useful way to use {0:theName} anymore.", Owner)); 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);
}
} }
} }

View File

@@ -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<SurgeryToolComponent> _openSurgeryUIs = new();
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SurgeryWindowOpenMessage>(OnSurgeryWindowOpen);
SubscribeLocalEvent<SurgeryWindowCloseMessage>(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();
}
}
}
}
}