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(); }