From 123a4147dea2945f6c60fe9e4e0a3aa2da75e1dc Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Sun, 14 Jan 2024 08:18:39 +0100 Subject: [PATCH] BUI bugfixes / improvements (#23881) * Fix ActivatableUIRequiresPowerCellComponent stopping power draw when one of two people closes the UI. Also fixes it to check UiKey properly. * Remove unnecessary CrewManifestViewer on PDAs This is for a pop-up crew manifest UI, which the PDA doesn't use. * Fix BoundUIClosedEvents that didn't check UI key/not correctly at least. Uses the new helper method in engine. * Fix drone (cargo shuttle) pilot console UI breaking if two people open it and one person closes it. * Fixes for disposal router/tagger UI. Code was badly copy pasted without changing identifiers, never worked. Also cleaned up some of the logic (text trimming, sounds). Also removed the "refuse to work if you have something in your active hand" check like why. * Avoid running most ActivatableUIComponent logic when closing a UI via toggle Activating the UI while it's already open closes it via toggle. Except it still ran 99% of the "attempting to open" logic which makes no sense. This probably fixes a bug or some other dumb behavior somewhere. * Bitch --- .../Access/Systems/AccessOverriderSystem.cs | 10 ++- .../Arcade/BlockGame/BlockGameArcadeSystem.cs | 8 +- .../Atmos/Monitor/Systems/AirAlarmSystem.cs | 20 +++-- .../CrewManifest/CrewManifestSystem.cs | 17 +++- .../CrewManifestViewerComponent.cs | 10 ++- .../Systems/NetworkConfiguratorSystem.cs | 7 ++ .../Disposal/Tube/DisposalTubeSystem.cs | 80 +++++++------------ .../Instruments/InstrumentSystem.cs | 15 ++-- .../MagicMirror/MagicMirrorSystem.cs | 14 ++-- Content.Server/Pinpointer/StationMapSystem.cs | 8 +- .../SensorMonitoringConsoleSystem.UI.cs | 5 +- .../Systems/ShuttleConsoleSystem.Drone.cs | 4 +- .../Shuttles/Systems/ShuttleConsoleSystem.cs | 12 ++- .../Storage/EntitySystems/StorageSystem.cs | 5 +- .../SurveillanceCameraMonitorSystem.cs | 15 ++-- .../ActivatableUISystem.Power.cs | 14 +++- .../UserInterface/ActivatableUISystem.cs | 28 ++++--- .../VendingMachines/VendingMachineSystem.cs | 16 ++-- .../components/disposal-router-component.ftl | 1 - .../components/disposal-tagger-window.ftl | 1 - .../Entities/Objects/Devices/pda.yml | 2 - .../Machines/Computers/computers.yml | 7 +- 22 files changed, 174 insertions(+), 125 deletions(-) diff --git a/Content.Server/Access/Systems/AccessOverriderSystem.cs b/Content.Server/Access/Systems/AccessOverriderSystem.cs index 41bb84ab6b2..2aa22575782 100644 --- a/Content.Server/Access/Systems/AccessOverriderSystem.cs +++ b/Content.Server/Access/Systems/AccessOverriderSystem.cs @@ -31,14 +31,18 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem { base.Initialize(); - SubscribeLocalEvent(OnWriteToTargetAccessReaderIdMessage); SubscribeLocalEvent(UpdateUserInterface); SubscribeLocalEvent(UpdateUserInterface); SubscribeLocalEvent(UpdateUserInterface); SubscribeLocalEvent(AfterInteractOn); SubscribeLocalEvent(OnDoAfter); - SubscribeLocalEvent(UpdateUserInterface); - SubscribeLocalEvent(OnClose); + + Subs.BuiEvents(AccessOverriderUiKey.Key, subs => + { + subs.Event(UpdateUserInterface); + subs.Event(OnClose); + subs.Event(OnWriteToTargetAccessReaderIdMessage); + }); } private void AfterInteractOn(EntityUid uid, AccessOverriderComponent component, AfterInteractEvent args) diff --git a/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs b/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs index ecc5bfd3e2c..a57401cbb19 100644 --- a/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs +++ b/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs @@ -16,9 +16,13 @@ public sealed class BlockGameArcadeSystem : EntitySystem SubscribeLocalEvent(OnComponentInit); SubscribeLocalEvent(OnAfterUIOpen); - SubscribeLocalEvent(OnAfterUiClose); SubscribeLocalEvent(OnBlockPowerChanged); - SubscribeLocalEvent(OnPlayerAction); + + Subs.BuiEvents(BlockGameUiKey.Key, subs => + { + subs.Event(OnAfterUiClose); + subs.Event(OnPlayerAction); + }); } public override void Update(float frameTime) diff --git a/Content.Server/Atmos/Monitor/Systems/AirAlarmSystem.cs b/Content.Server/Atmos/Monitor/Systems/AirAlarmSystem.cs index b65d8556809..b346fd63b0d 100644 --- a/Content.Server/Atmos/Monitor/Systems/AirAlarmSystem.cs +++ b/Content.Server/Atmos/Monitor/Systems/AirAlarmSystem.cs @@ -157,19 +157,23 @@ public sealed class AirAlarmSystem : EntitySystem SubscribeLocalEvent(OnAtmosUpdate); SubscribeLocalEvent(OnAtmosAlarm); SubscribeLocalEvent(OnPowerChanged); - SubscribeLocalEvent(OnResyncAll); - SubscribeLocalEvent(OnUpdateAlarmMode); - SubscribeLocalEvent(OnUpdateAutoMode); - SubscribeLocalEvent(OnUpdateThreshold); - SubscribeLocalEvent(OnUpdateDeviceData); - SubscribeLocalEvent(OnCopyDeviceData); - SubscribeLocalEvent(OnTabChange); SubscribeLocalEvent(OnDeviceListUpdate); - SubscribeLocalEvent(OnClose); SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnShutdown); SubscribeLocalEvent(OnActivate); + + Subs.BuiEvents(SharedAirAlarmInterfaceKey.Key, subs => + { + subs.Event(OnClose); + subs.Event(OnResyncAll); + subs.Event(OnUpdateAlarmMode); + subs.Event(OnUpdateAutoMode); + subs.Event(OnUpdateThreshold); + subs.Event(OnUpdateDeviceData); + subs.Event(OnCopyDeviceData); + subs.Event(OnTabChange); + }); } private void OnDeviceListUpdate(EntityUid uid, AirAlarmComponent component, DeviceListUpdateEvent args) diff --git a/Content.Server/CrewManifest/CrewManifestSystem.cs b/Content.Server/CrewManifest/CrewManifestSystem.cs index 4c4f17f61d4..12b6984b5ae 100644 --- a/Content.Server/CrewManifest/CrewManifestSystem.cs +++ b/Content.Server/CrewManifest/CrewManifestSystem.cs @@ -13,6 +13,7 @@ using Content.Shared.StationRecords; using Robust.Shared.Configuration; using Robust.Shared.Console; using Robust.Shared.Player; +using Robust.Shared.Utility; namespace Content.Server.CrewManifest; @@ -37,10 +38,11 @@ public sealed class CrewManifestSystem : EntitySystem SubscribeLocalEvent(AfterGeneralRecordCreated); SubscribeLocalEvent(OnRecordModified); SubscribeLocalEvent(OnRecordRemoved); - SubscribeLocalEvent(OnBoundUiClose); - SubscribeLocalEvent(OpenEuiFromBui); SubscribeLocalEvent(OnRoundRestart); SubscribeNetworkEvent(OnRequestCrewManifest); + + SubscribeLocalEvent(OnBoundUiClose); + SubscribeLocalEvent(OpenEuiFromBui); } private void OnRoundRestart(RoundRestartCleanupEvent ev) @@ -91,6 +93,9 @@ public sealed class CrewManifestSystem : EntitySystem private void OnBoundUiClose(EntityUid uid, CrewManifestViewerComponent component, BoundUIClosedEvent ev) { + if (!Equals(ev.UiKey, component.OwnerKey)) + return; + var owningStation = _stationSystem.GetOwningStation(uid); if (owningStation == null || ev.Session is not { } session) { @@ -124,6 +129,14 @@ public sealed class CrewManifestSystem : EntitySystem private void OpenEuiFromBui(EntityUid uid, CrewManifestViewerComponent component, CrewManifestOpenUiMessage msg) { + if (!msg.UiKey.Equals(component.OwnerKey)) + { + Log.Error( + "{User} tried to open crew manifest from wrong UI: {Key}. Correct owned is {ExpectedKey}", + msg.Session, msg.UiKey, component.OwnerKey); + return; + } + var owningStation = _stationSystem.GetOwningStation(uid); if (owningStation == null || msg.Session is not { } session) { diff --git a/Content.Server/CrewManifest/CrewManifestViewerComponent.cs b/Content.Server/CrewManifest/CrewManifestViewerComponent.cs index f66bc4c1afb..25d73abf92e 100644 --- a/Content.Server/CrewManifest/CrewManifestViewerComponent.cs +++ b/Content.Server/CrewManifest/CrewManifestViewerComponent.cs @@ -1,3 +1,5 @@ +using Content.Shared.CCVar; + namespace Content.Server.CrewManifest; [RegisterComponent] @@ -5,8 +7,14 @@ public sealed partial class CrewManifestViewerComponent : Component { /// /// If this manifest viewer is unsecure or not. If it is, - /// CCVars.CrewManifestUnsecure being false will + /// being false will /// not allow this entity to be processed by CrewManifestSystem. /// [DataField("unsecure")] public bool Unsecure; + + /// + /// The owner interface of this crew manifest viewer. When it closes, so too will an opened crew manifest. + /// + [DataField(required: true)] + public Enum OwnerKey { get; private set; } = default!; } diff --git a/Content.Server/DeviceNetwork/Systems/NetworkConfiguratorSystem.cs b/Content.Server/DeviceNetwork/Systems/NetworkConfiguratorSystem.cs index e610907d257..c8faa930d11 100644 --- a/Content.Server/DeviceNetwork/Systems/NetworkConfiguratorSystem.cs +++ b/Content.Server/DeviceNetwork/Systems/NetworkConfiguratorSystem.cs @@ -532,6 +532,13 @@ public sealed class NetworkConfiguratorSystem : SharedNetworkConfiguratorSystem /// private void OnUiClosed(EntityUid uid, NetworkConfiguratorComponent component, BoundUIClosedEvent args) { + if (!args.UiKey.Equals(NetworkConfiguratorUiKey.Configure) + && !args.UiKey.Equals(NetworkConfiguratorUiKey.Link) + && !args.UiKey.Equals(NetworkConfiguratorUiKey.List)) + { + return; + } + if (TryComp(component.ActiveDeviceList, out DeviceListComponent? list)) { list.Configurators.Remove(uid); diff --git a/Content.Server/Disposal/Tube/DisposalTubeSystem.cs b/Content.Server/Disposal/Tube/DisposalTubeSystem.cs index 2bf00c5008c..b7d8455d85e 100644 --- a/Content.Server/Disposal/Tube/DisposalTubeSystem.cs +++ b/Content.Server/Disposal/Tube/DisposalTubeSystem.cs @@ -58,22 +58,26 @@ namespace Content.Server.Disposal.Tube SubscribeLocalEvent(OnGetJunctionConnectableDirections); SubscribeLocalEvent(OnGetJunctionNextDirection); - SubscribeLocalEvent(OnComponentRemove); SubscribeLocalEvent(OnGetRouterConnectableDirections); SubscribeLocalEvent(OnGetRouterNextDirection); SubscribeLocalEvent(OnGetTransitConnectableDirections); SubscribeLocalEvent(OnGetTransitNextDirection); - SubscribeLocalEvent(OnComponentRemove); SubscribeLocalEvent(OnGetTaggerConnectableDirections); SubscribeLocalEvent(OnGetTaggerNextDirection); - SubscribeLocalEvent(OnOpenRouterUIAttempt); - SubscribeLocalEvent(OnOpenTaggerUIAttempt); + Subs.BuiEvents(DisposalRouterUiKey.Key, subs => + { + subs.Event(OnOpenRouterUI); + subs.Event(OnUiAction); + }); - SubscribeLocalEvent(OnUiAction); - SubscribeLocalEvent(OnUiAction); + Subs.BuiEvents(DisposalTaggerUiKey.Key, subs => + { + subs.Event(OnOpenTaggerUI); + subs.Event(OnUiAction); + }); } @@ -84,15 +88,13 @@ namespace Content.Server.Disposal.Tube /// A user interface message from the client. private void OnUiAction(EntityUid uid, DisposalTaggerComponent tagger, SharedDisposalTaggerComponent.UiActionMessage msg) { - if (!DisposalTaggerUiKey.Key.Equals(msg.UiKey)) - return; if (TryComp(uid, out var physBody) && physBody.BodyType != BodyType.Static) return; //Check for correct message and ignore maleformed strings if (msg.Action == SharedDisposalTaggerComponent.UiAction.Ok && SharedDisposalTaggerComponent.TagRegex.IsMatch(msg.Tag)) { - tagger.Tag = msg.Tag; + tagger.Tag = msg.Tag.Trim(); _audioSystem.PlayPvs(tagger.ClickSound, uid, AudioParams.Default.WithVolume(-2f)); } } @@ -105,8 +107,6 @@ namespace Content.Server.Disposal.Tube /// A user interface message from the client. private void OnUiAction(EntityUid uid, DisposalRouterComponent router, SharedDisposalRouterComponent.UiActionMessage msg) { - if (!DisposalRouterUiKey.Key.Equals(msg.UiKey)) - return; if (!EntityManager.EntityExists(msg.Session.AttachedEntity)) return; if (TryComp(uid, out var physBody) && physBody.BodyType != BodyType.Static) @@ -118,9 +118,14 @@ namespace Content.Server.Disposal.Tube router.Tags.Clear(); foreach (var tag in msg.Tags.Split(',', StringSplitOptions.RemoveEmptyEntries)) { + var trimmed = tag.Trim(); + if (trimmed == "") + continue; + router.Tags.Add(tag.Trim()); - _audioSystem.PlayPvs(router.ClickSound, uid, AudioParams.Default.WithVolume(-2f)); } + + _audioSystem.PlayPvs(router.ClickSound, uid, AudioParams.Default.WithVolume(-2f)); } } @@ -134,16 +139,6 @@ namespace Content.Server.Disposal.Tube DisconnectTube(uid, tube); } - private void OnComponentRemove(EntityUid uid, DisposalTaggerComponent tagger, ComponentRemove args) - { - _uiSystem.TryCloseAll(uid, DisposalTaggerUiKey.Key); - } - - private void OnComponentRemove(EntityUid uid, DisposalRouterComponent tagger, ComponentRemove args) - { - _uiSystem.TryCloseAll(uid, DisposalRouterUiKey.Key); - } - private void OnGetBendConnectableDirections(EntityUid uid, DisposalBendComponent component, ref GetDisposalsConnectableDirectionsEvent args) { var direction = Transform(uid).LocalRotation; @@ -283,40 +278,18 @@ namespace Content.Server.Disposal.Tube DisconnectTube(uid, component); } - private void OnOpenRouterUIAttempt(EntityUid uid, DisposalRouterComponent router, ActivatableUIOpenAttemptEvent args) + private void OnOpenRouterUI(EntityUid uid, DisposalRouterComponent router, BoundUIOpenedEvent args) { - if (!TryComp(args.User, out var hands)) - { - _popups.PopupClient(Loc.GetString("disposal-router-window-tag-input-activate-no-hands"), uid, args.User); - return; - } - - var activeHandEntity = hands.ActiveHandEntity; - if (activeHandEntity != null) - { - args.Cancel(); - } - UpdateRouterUserInterface(uid, router); } - private void OnOpenTaggerUIAttempt(EntityUid uid, DisposalTaggerComponent tagger, ActivatableUIOpenAttemptEvent args) + private void OnOpenTaggerUI(EntityUid uid, DisposalTaggerComponent tagger, BoundUIOpenedEvent args) { - if (!TryComp(args.User, out var hands)) - { - _popups.PopupClient(Loc.GetString("disposal-tagger-window-activate-no-hands"), uid, args.User); - return; - } - - var activeHandEntity = hands.ActiveHandEntity; - if (activeHandEntity != null) - { - args.Cancel(); - } - if (_uiSystem.TryGetUi(uid, DisposalTaggerUiKey.Key, out var bui)) + { _uiSystem.SetUiState(bui, new DisposalTaggerUserInterfaceState(tagger.Tag)); + } } /// @@ -325,11 +298,13 @@ namespace Content.Server.Disposal.Tube /// Returns a private void UpdateRouterUserInterface(EntityUid uid, DisposalRouterComponent router) { - var bui = _uiSystem.GetUiOrNull(uid, DisposalTaggerUiKey.Key); + var bui = _uiSystem.GetUiOrNull(uid, DisposalRouterUiKey.Key); + if (bui == null) + return; + if (router.Tags.Count <= 0) { - if (bui is not null) - _uiSystem.SetUiState(bui, new DisposalTaggerUserInterfaceState("")); + _uiSystem.SetUiState(bui, new DisposalRouterUserInterfaceState("")); return; } @@ -343,8 +318,7 @@ namespace Content.Server.Disposal.Tube taglist.Remove(taglist.Length - 2, 2); - if (bui is not null) - _uiSystem.SetUiState(bui, new DisposalTaggerUserInterfaceState(taglist.ToString())); + _uiSystem.SetUiState(bui, new DisposalRouterUserInterfaceState(taglist.ToString())); } private void OnAnchorChange(EntityUid uid, DisposalTubeComponent component, ref AnchorStateChangedEvent args) diff --git a/Content.Server/Instruments/InstrumentSystem.cs b/Content.Server/Instruments/InstrumentSystem.cs index 6f8369182cb..17899b72328 100644 --- a/Content.Server/Instruments/InstrumentSystem.cs +++ b/Content.Server/Instruments/InstrumentSystem.cs @@ -50,9 +50,12 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem SubscribeNetworkEvent(OnMidiSetMaster); SubscribeNetworkEvent(OnMidiSetFilteredChannel); - SubscribeLocalEvent(OnBoundUIClosed); - SubscribeLocalEvent(OnBoundUIOpened); - SubscribeLocalEvent(OnBoundUIRequestBands); + Subs.BuiEvents(InstrumentUiKey.Key, subs => + { + subs.Event(OnBoundUIClosed); + subs.Event(OnBoundUIOpened); + subs.Event(OnBoundUIRequestBands); + }); SubscribeLocalEvent(OnStrumentGetState); @@ -197,9 +200,6 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem private void OnBoundUIClosed(EntityUid uid, InstrumentComponent component, BoundUIClosedEvent args) { - if (args.UiKey is not InstrumentUiKey) - return; - if (HasComp(uid) && _bui.TryGetUi(uid, args.UiKey, out var bui) && bui.SubscribedSessions.Count == 0) @@ -212,9 +212,6 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem private void OnBoundUIOpened(EntityUid uid, InstrumentComponent component, BoundUIOpenedEvent args) { - if (args.UiKey is not InstrumentUiKey) - return; - EnsureComp(uid); Clean(uid, component); } diff --git a/Content.Server/MagicMirror/MagicMirrorSystem.cs b/Content.Server/MagicMirror/MagicMirrorSystem.cs index c2d6f0fda25..f6858e10a05 100644 --- a/Content.Server/MagicMirror/MagicMirrorSystem.cs +++ b/Content.Server/MagicMirror/MagicMirrorSystem.cs @@ -29,11 +29,15 @@ public sealed class MagicMirrorSystem : EntitySystem { base.Initialize(); SubscribeLocalEvent(OnOpenUIAttempt); - SubscribeLocalEvent(OnUIClosed); - SubscribeLocalEvent(OnMagicMirrorSelect); - SubscribeLocalEvent(OnTryMagicMirrorChangeColor); - SubscribeLocalEvent(OnTryMagicMirrorAddSlot); - SubscribeLocalEvent(OnTryMagicMirrorRemoveSlot); + + Subs.BuiEvents(MagicMirrorUiKey.Key, subs => + { + subs.Event(OnUIClosed); + subs.Event(OnMagicMirrorSelect); + subs.Event(OnTryMagicMirrorChangeColor); + subs.Event(OnTryMagicMirrorAddSlot); + subs.Event(OnTryMagicMirrorRemoveSlot); + }); SubscribeLocalEvent(OnMagicMirrorInteract); diff --git a/Content.Server/Pinpointer/StationMapSystem.cs b/Content.Server/Pinpointer/StationMapSystem.cs index 0460f08f138..c9db560fef0 100644 --- a/Content.Server/Pinpointer/StationMapSystem.cs +++ b/Content.Server/Pinpointer/StationMapSystem.cs @@ -14,8 +14,12 @@ public sealed class StationMapSystem : EntitySystem { base.Initialize(); SubscribeLocalEvent(OnUserParentChanged); - SubscribeLocalEvent(OnStationMapOpened); - SubscribeLocalEvent(OnStationMapClosed); + + Subs.BuiEvents(StationMapUiKey.Key, subs => + { + subs.Event(OnStationMapOpened); + subs.Event(OnStationMapClosed); + }); } private void OnStationMapClosed(EntityUid uid, StationMapComponent component, BoundUIClosedEvent args) diff --git a/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.UI.cs b/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.UI.cs index 6c0dddeb266..26c6b178313 100644 --- a/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.UI.cs +++ b/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.UI.cs @@ -10,7 +10,10 @@ public sealed partial class SensorMonitoringConsoleSystem { private void InitUI() { - SubscribeLocalEvent(ConsoleUIClosed); + Subs.BuiEvents(SensorMonitoringConsoleUiKey.Key, subs => + { + subs.Event(ConsoleUIClosed); + }); } private void UpdateConsoleUI(EntityUid uid, SensorMonitoringConsoleComponent comp) diff --git a/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.Drone.cs b/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.Drone.cs index 864a2fbaef2..cef4faa13b2 100644 --- a/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.Drone.cs +++ b/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.Drone.cs @@ -27,7 +27,9 @@ public sealed partial class ShuttleConsoleSystem private void OnDronePilotConsoleClose(EntityUid uid, DroneConsoleComponent component, BoundUIClosedEvent args) { - component.Entity = null; + // Only if last person closed UI. + if (!_ui.IsUiOpen(uid, args.UiKey)) + component.Entity = null; } private void OnCargoGetConsole(EntityUid uid, DroneConsoleComponent component, ref ConsoleShuttleEvent args) diff --git a/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.cs b/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.cs index 21c7ecc0500..afe9d78a25c 100644 --- a/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.cs +++ b/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.cs @@ -43,12 +43,18 @@ public sealed partial class ShuttleConsoleSystem : SharedShuttleConsoleSystem SubscribeLocalEvent(OnConsolePowerChange); SubscribeLocalEvent(OnConsoleAnchorChange); SubscribeLocalEvent(OnConsoleUIOpenAttempt); - SubscribeLocalEvent(OnDestinationMessage); - SubscribeLocalEvent(OnConsoleUIClose); + Subs.BuiEvents(ShuttleConsoleUiKey.Key, subs => + { + subs.Event(OnDestinationMessage); + subs.Event(OnConsoleUIClose); + }); SubscribeLocalEvent(OnCargoGetConsole); SubscribeLocalEvent(OnDronePilotConsoleOpen); - SubscribeLocalEvent(OnDronePilotConsoleClose); + Subs.BuiEvents(ShuttleConsoleUiKey.Key, subs => + { + subs.Event(OnDronePilotConsoleClose); + }); SubscribeLocalEvent(OnDock); SubscribeLocalEvent(OnUndock); diff --git a/Content.Server/Storage/EntitySystems/StorageSystem.cs b/Content.Server/Storage/EntitySystems/StorageSystem.cs index b1da3cf30e4..035ca5f399a 100644 --- a/Content.Server/Storage/EntitySystems/StorageSystem.cs +++ b/Content.Server/Storage/EntitySystems/StorageSystem.cs @@ -34,7 +34,10 @@ public sealed partial class StorageSystem : SharedStorageSystem { base.Initialize(); SubscribeLocalEvent>(AddUiVerb); - SubscribeLocalEvent(OnBoundUIClosed); + Subs.BuiEvents(StorageComponent.StorageUiKey.Key, subs => + { + subs.Event(OnBoundUIClosed); + }); SubscribeLocalEvent(OnExploded); SubscribeLocalEvent(OnStorageFillMapInit); diff --git a/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraMonitorSystem.cs b/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraMonitorSystem.cs index 7b1dff0b6bc..39dcb1a9e0f 100644 --- a/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraMonitorSystem.cs +++ b/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraMonitorSystem.cs @@ -18,16 +18,19 @@ public sealed class SurveillanceCameraMonitorSystem : EntitySystem public override void Initialize() { SubscribeLocalEvent(OnSurveillanceCameraDeactivate); - SubscribeLocalEvent(OnBoundUiClose); SubscribeLocalEvent(OnPowerChanged); - SubscribeLocalEvent(OnSwitchMessage); SubscribeLocalEvent(OnPacketReceived); - SubscribeLocalEvent(OnSubnetRequest); SubscribeLocalEvent(OnComponentStartup); SubscribeLocalEvent(OnToggleInterface); - SubscribeLocalEvent(OnRefreshCamerasMessage); - SubscribeLocalEvent(OnRefreshSubnetsMessage); - SubscribeLocalEvent(OnDisconnectMessage); + Subs.BuiEvents(SurveillanceCameraMonitorUiKey.Key, subs => + { + subs.Event(OnRefreshCamerasMessage); + subs.Event(OnRefreshSubnetsMessage); + subs.Event(OnDisconnectMessage); + subs.Event(OnSubnetRequest); + subs.Event(OnSwitchMessage); + subs.Event(OnBoundUiClose); + }); } private const float _maxHeartbeatTime = 300f; diff --git a/Content.Server/UserInterface/ActivatableUISystem.Power.cs b/Content.Server/UserInterface/ActivatableUISystem.Power.cs index 918be614b87..7c687aa3cd4 100644 --- a/Content.Server/UserInterface/ActivatableUISystem.Power.cs +++ b/Content.Server/UserInterface/ActivatableUISystem.Power.cs @@ -31,12 +31,24 @@ public sealed partial class ActivatableUISystem private void OnBatteryOpened(EntityUid uid, ActivatableUIRequiresPowerCellComponent component, BoundUIOpenedEvent args) { + var activatable = Comp(uid); + + if (!args.UiKey.Equals(activatable.Key)) + return; + _cell.SetPowerCellDrawEnabled(uid, true); } private void OnBatteryClosed(EntityUid uid, ActivatableUIRequiresPowerCellComponent component, BoundUIClosedEvent args) { - _cell.SetPowerCellDrawEnabled(uid, false); + var activatable = Comp(uid); + + if (!args.UiKey.Equals(activatable.Key)) + return; + + // Stop drawing power if this was the last person with the UI open. + if (!_uiSystem.IsUiOpen(uid, activatable.Key)) + _cell.SetPowerCellDrawEnabled(uid, false); } /// diff --git a/Content.Server/UserInterface/ActivatableUISystem.cs b/Content.Server/UserInterface/ActivatableUISystem.cs index 459a704911f..e3dad633586 100644 --- a/Content.Server/UserInterface/ActivatableUISystem.cs +++ b/Content.Server/UserInterface/ActivatableUISystem.cs @@ -124,16 +124,7 @@ public sealed partial class ActivatableUISystem : EntitySystem private bool InteractUI(EntityUid user, EntityUid uiEntity, ActivatableUIComponent aui) { - if (!_blockerSystem.CanInteract(user, uiEntity) && (!aui.AllowSpectator || !HasComp(user))) - return false; - - if (aui.RequireHands && !HasComp(user)) - return false; - - if (!EntityManager.TryGetComponent(user, out ActorComponent? actor)) - return false; - - if (aui.AdminOnly && !_adminManager.IsAdmin(actor.PlayerSession)) + if (!TryComp(user, out ActorComponent? actor)) return false; if (aui.Key == null) @@ -142,6 +133,21 @@ public sealed partial class ActivatableUISystem : EntitySystem if (!_uiSystem.TryGetUi(uiEntity, aui.Key, out var ui)) return false; + if (ui.SubscribedSessions.Contains(actor.PlayerSession)) + { + _uiSystem.CloseUi(ui, actor.PlayerSession); + return true; + } + + if (!_blockerSystem.CanInteract(user, uiEntity) && (!aui.AllowSpectator || !HasComp(user))) + return false; + + if (aui.RequireHands && !HasComp(user)) + return false; + + if (aui.AdminOnly && !_adminManager.IsAdmin(actor.PlayerSession)) + return false; + if (aui.SingleUser && (aui.CurrentSingleUser != null) && (actor.PlayerSession != aui.CurrentSingleUser)) { string message = Loc.GetString("machine-already-in-use", ("machine", uiEntity)); @@ -169,7 +175,7 @@ public sealed partial class ActivatableUISystem : EntitySystem RaiseLocalEvent(uiEntity, bae); SetCurrentSingleUser(uiEntity, actor.PlayerSession, aui); - _uiSystem.ToggleUi(ui, actor.PlayerSession); + _uiSystem.OpenUi(ui, actor.PlayerSession); //Let the component know a user opened it so it can do whatever it needs to do var aae = new AfterActivatableUIOpenEvent(user, actor.PlayerSession); diff --git a/Content.Server/VendingMachines/VendingMachineSystem.cs b/Content.Server/VendingMachines/VendingMachineSystem.cs index e4d4e931e35..da024888a50 100644 --- a/Content.Server/VendingMachines/VendingMachineSystem.cs +++ b/Content.Server/VendingMachines/VendingMachineSystem.cs @@ -56,9 +56,13 @@ namespace Content.Server.VendingMachines SubscribeLocalEvent(OnEmpPulse); SubscribeLocalEvent(OnActivatableUIOpenAttempt); - SubscribeLocalEvent(OnBoundUIOpened); - SubscribeLocalEvent(OnBoundUIClosed); - SubscribeLocalEvent(OnInventoryEjectMessage); + + Subs.BuiEvents(VendingMachineUiKey.Key, subs => + { + subs.Event(OnBoundUIOpened); + subs.Event(OnBoundUIClosed); + subs.Event(OnInventoryEjectMessage); + }); SubscribeLocalEvent(OnSelfDispense); @@ -114,12 +118,6 @@ namespace Content.Server.VendingMachines private void OnBoundUIClosed(EntityUid uid, VendingMachineComponent component, BoundUIClosedEvent args) { - if (args.UiKey is not VendingMachineUiKey) - return; - - if ((VendingMachineUiKey) args.UiKey != VendingMachineUiKey.Key) - return; - // Only vendors that advertise will send message after dispensing if (component.ShouldSayThankYou && TryComp(uid, out var advertise)) { diff --git a/Resources/Locale/en-US/disposal/tube/components/disposal-router-component.ftl b/Resources/Locale/en-US/disposal/tube/components/disposal-router-component.ftl index 2975607fd7f..64fbfdf66f3 100644 --- a/Resources/Locale/en-US/disposal/tube/components/disposal-router-component.ftl +++ b/Resources/Locale/en-US/disposal/tube/components/disposal-router-component.ftl @@ -4,7 +4,6 @@ disposal-router-window-title = Disposal Router disposal-router-window-tags-label = Tags: disposal-router-window-tag-input-tooltip = A comma separated list of tags disposal-router-window-tag-input-confirm-button = Confirm -disposal-router-window-tag-input-activate-no-hands = You have no hands ## ConfigureVerb diff --git a/Resources/Locale/en-US/disposal/tube/components/disposal-tagger-window.ftl b/Resources/Locale/en-US/disposal/tube/components/disposal-tagger-window.ftl index 24091a05334..dc4b40fc7f8 100644 --- a/Resources/Locale/en-US/disposal/tube/components/disposal-tagger-window.ftl +++ b/Resources/Locale/en-US/disposal/tube/components/disposal-tagger-window.ftl @@ -1,7 +1,6 @@ disposal-tagger-window-title = Disposal Tagger disposal-tagger-window-tag-input-label = Tag: disposal-tagger-window-tag-confirm-button = Confirm -disposal-tagger-window-activate-no-hands = You have no hands. ## ConfigureVerb configure-verb-get-data-text = Open Configuration diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml index 8a0c6dea94f..133ae8eb2c2 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml @@ -99,8 +99,6 @@ type: InstrumentBoundUserInterface - key: enum.HealthAnalyzerUiKey.Key type: HealthAnalyzerBoundUserInterface - - type: CrewManifestViewer - unsecure: true - type: Tag tags: - DoorBumpOpener diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml index d42127b1328..c0c91d57c69 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml @@ -139,7 +139,7 @@ energy: 1.6 color: "#c94242" - type: Computer - board: CargoShuttleConsoleCircuitboard + board: CargoShuttleConsoleCircuitboard - type: StealTarget stealGroup: CargoShuttleConsoleCircuitboard @@ -172,7 +172,7 @@ board: SalvageShuttleConsoleCircuitboard - type: StealTarget stealGroup: SalvageShuttleConsoleCircuitboard - + - type: entity parent: BaseComputer id: ComputerIFF @@ -486,6 +486,7 @@ - key: enum.IdCardConsoleUiKey.Key type: IdCardConsoleBoundUserInterface - type: CrewManifestViewer + ownerKey: enum.IdCardConsoleUiKey.Key - type: Sprite layers: - map: ["computerLayerBody"] @@ -862,7 +863,7 @@ access: [["Salvage"]] - type: StealTarget stealGroup: SalvageExpeditionsComputerCircuitboard - + - type: entity parent: BaseComputer id: ComputerSurveillanceCameraMonitor