From bae540ab2fa183ea40788bed14f600b1673ea6e6 Mon Sep 17 00:00:00 2001
From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com>
Date: Sun, 31 Jul 2022 14:56:26 +1200
Subject: [PATCH] Fix gas tank and other hand-interaction bugs (#9700)
---
.../Tests/Disposal/DisposalUnitTest.cs | 2 +-
.../Atmos/Components/GasTankComponent.cs | 12 ++++++++-
.../Atmos/EntitySystems/GasTankSystem.cs | 27 ++++++++++++++-----
.../Unit/EntitySystems/DisposalUnitSystem.cs | 14 +++++-----
.../DoInsertDisposalUnitEvent.cs | 4 +--
.../Kitchen/EntitySystems/MicrowaveSystem.cs | 6 +++--
6 files changed, 46 insertions(+), 19 deletions(-)
diff --git a/Content.IntegrationTests/Tests/Disposal/DisposalUnitTest.cs b/Content.IntegrationTests/Tests/Disposal/DisposalUnitTest.cs
index aaa86ac2ed6..a4fb8ae46dd 100644
--- a/Content.IntegrationTests/Tests/Disposal/DisposalUnitTest.cs
+++ b/Content.IntegrationTests/Tests/Disposal/DisposalUnitTest.cs
@@ -45,7 +45,7 @@ private void UnitInsert(DisposalUnitComponent unit, bool result, params EntityUi
foreach (var entity in entities)
{
Assert.That(system.CanInsert(unit, entity), Is.EqualTo(result));
- system.TryInsert(unit.Owner, entity, entity);
+ system.TryInsert(unit.Owner, entity, null);
}
}
diff --git a/Content.Server/Atmos/Components/GasTankComponent.cs b/Content.Server/Atmos/Components/GasTankComponent.cs
index fd4b599d4c6..3b58794fd78 100644
--- a/Content.Server/Atmos/Components/GasTankComponent.cs
+++ b/Content.Server/Atmos/Components/GasTankComponent.cs
@@ -42,7 +42,17 @@ public sealed class GasTankComponent : Component, IGasMixtureHolder
///
/// Tank is connected to internals.
///
- [ViewVariables] public bool IsConnected { get; set; }
+ [ViewVariables] public bool IsConnected => User != null;
+
+ [ViewVariables]
+ public EntityUid? User;
+
+ ///
+ /// True if this entity was recently moved out of a container. This might have been a hand -> inventory
+ /// transfer, or it might have been the user dropping the tank. This indicates the tank needs to be checked.
+ ///
+ [ViewVariables]
+ public bool CheckUser;
///
/// Pressure at which tanks start leaking.
diff --git a/Content.Server/Atmos/EntitySystems/GasTankSystem.cs b/Content.Server/Atmos/EntitySystems/GasTankSystem.cs
index 309a508d97a..97e3bf56b48 100644
--- a/Content.Server/Atmos/EntitySystems/GasTankSystem.cs
+++ b/Content.Server/Atmos/EntitySystems/GasTankSystem.cs
@@ -41,8 +41,7 @@ public override void Initialize()
SubscribeLocalEvent(OnGetActions);
SubscribeLocalEvent(OnExamined);
SubscribeLocalEvent(OnActionToggle);
- SubscribeLocalEvent(OnDropped);
-
+ SubscribeLocalEvent(OnParentChange);
SubscribeLocalEvent(OnGasTankSetPressure);
SubscribeLocalEvent(OnGasTankToggleInternals);
}
@@ -84,9 +83,12 @@ private void BeforeUiOpen(EntityUid uid, GasTankComponent component, BeforeActiv
UpdateUserInterface(component, true);
}
- private void OnDropped(EntityUid uid, GasTankComponent component, DroppedEvent args)
+ private void OnParentChange(EntityUid uid, GasTankComponent component, ref EntParentChangedMessage args)
{
- DisconnectFromInternals(component, args.User);
+ // When an item is moved from hands -> pockets, the container removal briefly dumps the item on the floor.
+ // So this is a shitty fix, where the parent check is just delayed. But this really needs to get fixed
+ // properly at some point.
+ component.CheckUser = true;
}
private void OnGetActions(EntityUid uid, GasTankComponent component, GetItemActionsEvent args)
@@ -122,6 +124,16 @@ public override void Update(float frameTime)
foreach (var gasTank in EntityManager.EntityQuery())
{
+ if (gasTank.CheckUser)
+ {
+ gasTank.CheckUser = false;
+ if (Transform(gasTank.Owner).ParentUid != gasTank.User)
+ {
+ DisconnectFromInternals(gasTank);
+ continue;
+ }
+ }
+
_atmosphereSystem.React(gasTank.Air, gasTank);
CheckStatus(gasTank);
if (_ui.IsUiOpen(gasTank.Owner, SharedGasTankUiKey.Key))
@@ -184,7 +196,10 @@ public void ConnectToInternals(GasTankComponent component)
if (!CanConnectToInternals(component)) return;
var internals = GetInternalsComponent(component);
if (internals == null) return;
- component.IsConnected = _internals.TryConnectTank(internals, component.Owner);
+
+ if (_internals.TryConnectTank(internals, component.Owner))
+ component.User = internals.Owner;
+
_actions.SetToggled(component.ToggleAction, component.IsConnected);
// Couldn't toggle!
@@ -201,7 +216,7 @@ public void ConnectToInternals(GasTankComponent component)
public void DisconnectFromInternals(GasTankComponent component, EntityUid? owner = null)
{
if (!component.IsConnected) return;
- component.IsConnected = false;
+ component.User = null;
_actions.SetToggled(component.ToggleAction, false);
_internals.DisconnectTank(GetInternalsComponent(component, owner));
diff --git a/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs b/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs
index a5aa6a443fd..13e7580b2c2 100644
--- a/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs
+++ b/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs
@@ -181,11 +181,11 @@ private void DoInsertDisposalUnit(DoInsertDisposalUnitEvent ev)
return;
}
- if (!unit.Container.Insert(toInsert))
- {
+ if (ev.User != null && !_handsSystem.TryDropIntoContainer(ev.User.Value, ev.ToInsert, unit.Container))
return;
- }
-
+ else
+ unit.Container.Insert(toInsert);
+
AfterInsert(unit, toInsert);
}
@@ -466,7 +466,7 @@ private bool Update(DisposalUnitComponent component, float frameTime)
return state == SharedDisposalUnitComponent.PressureState.Ready && component.RecentlyEjected.Count == 0;
}
- public bool TryInsert(EntityUid unitId, EntityUid toInsertId, EntityUid userId, DisposalUnitComponent? unit = null)
+ public bool TryInsert(EntityUid unitId, EntityUid toInsertId, EntityUid? userId, DisposalUnitComponent? unit = null)
{
if (!Resolve(unitId, ref unit))
return false;
@@ -477,7 +477,7 @@ public bool TryInsert(EntityUid unitId, EntityUid toInsertId, EntityUid userId,
var delay = userId == toInsertId ? unit.EntryDelay : unit.DraggedEntryDelay;
var ev = new DoInsertDisposalUnitEvent(userId, toInsertId, unitId);
- if (delay <= 0)
+ if (delay <= 0 || userId == null)
{
DoInsertDisposalUnit(ev);
return true;
@@ -485,7 +485,7 @@ public bool TryInsert(EntityUid unitId, EntityUid toInsertId, EntityUid userId,
// Can't check if our target AND disposals moves currently so we'll just check target.
// if you really want to check if disposals moves then add a predicate.
- var doAfterArgs = new DoAfterEventArgs(userId, delay, default, toInsertId)
+ var doAfterArgs = new DoAfterEventArgs(userId.Value, delay, default, toInsertId)
{
BreakOnDamage = true,
BreakOnStun = true,
diff --git a/Content.Server/Disposal/Unit/EntitySystems/DoInsertDisposalUnitEvent.cs b/Content.Server/Disposal/Unit/EntitySystems/DoInsertDisposalUnitEvent.cs
index bb94f87a9ca..6fdfce61da6 100644
--- a/Content.Server/Disposal/Unit/EntitySystems/DoInsertDisposalUnitEvent.cs
+++ b/Content.Server/Disposal/Unit/EntitySystems/DoInsertDisposalUnitEvent.cs
@@ -1,4 +1,4 @@
-namespace Content.Server.Disposal.Unit.EntitySystems
+namespace Content.Server.Disposal.Unit.EntitySystems
{
- public record DoInsertDisposalUnitEvent(EntityUid User, EntityUid ToInsert, EntityUid Unit);
+ public record DoInsertDisposalUnitEvent(EntityUid? User, EntityUid ToInsert, EntityUid Unit);
}
diff --git a/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs b/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs
index 0d9bb0701b7..78d762d98f0 100644
--- a/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs
+++ b/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs
@@ -12,6 +12,7 @@
using Content.Shared.Body.Components;
using Content.Shared.Body.Part;
using Content.Shared.Popups;
+using Content.Server.Hands.Systems;
namespace Content.Server.Kitchen.EntitySystems
{
@@ -19,6 +20,8 @@ namespace Content.Server.Kitchen.EntitySystems
internal sealed class MicrowaveSystem : EntitySystem
{
[Dependency] private readonly PopupSystem _popupSystem = default!;
+ [Dependency] private readonly HandsSystem _handsSystem = default!;
+
public override void Initialize()
{
base.Initialize();
@@ -114,8 +117,7 @@ private void OnInteractUsing(EntityUid uid, MicrowaveComponent component, Intera
}
args.Handled = true;
-
- component.Storage.Insert(args.Used);
+ _handsSystem.TryDropIntoContainer(args.User, args.Used, component.Storage);
component.DirtyUi();
}