]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
BUI bugfixes / improvements (#23881)
authorPieter-Jan Briers <pieterjan.briers+git@gmail.com>
Sun, 14 Jan 2024 07:18:39 +0000 (08:18 +0100)
committerGitHub <noreply@github.com>
Sun, 14 Jan 2024 07:18:39 +0000 (18:18 +1100)
* 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

22 files changed:
Content.Server/Access/Systems/AccessOverriderSystem.cs
Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs
Content.Server/Atmos/Monitor/Systems/AirAlarmSystem.cs
Content.Server/CrewManifest/CrewManifestSystem.cs
Content.Server/CrewManifest/CrewManifestViewerComponent.cs
Content.Server/DeviceNetwork/Systems/NetworkConfiguratorSystem.cs
Content.Server/Disposal/Tube/DisposalTubeSystem.cs
Content.Server/Instruments/InstrumentSystem.cs
Content.Server/MagicMirror/MagicMirrorSystem.cs
Content.Server/Pinpointer/StationMapSystem.cs
Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.UI.cs
Content.Server/Shuttles/Systems/ShuttleConsoleSystem.Drone.cs
Content.Server/Shuttles/Systems/ShuttleConsoleSystem.cs
Content.Server/Storage/EntitySystems/StorageSystem.cs
Content.Server/SurveillanceCamera/Systems/SurveillanceCameraMonitorSystem.cs
Content.Server/UserInterface/ActivatableUISystem.Power.cs
Content.Server/UserInterface/ActivatableUISystem.cs
Content.Server/VendingMachines/VendingMachineSystem.cs
Resources/Locale/en-US/disposal/tube/components/disposal-router-component.ftl
Resources/Locale/en-US/disposal/tube/components/disposal-tagger-window.ftl
Resources/Prototypes/Entities/Objects/Devices/pda.yml
Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml

index 41bb84ab6b22223470cda583869879d9710cc6ec..2aa22575782ae0e2d8be712c8f7a0a5418bc3a8f 100644 (file)
@@ -31,14 +31,18 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem
     {
         base.Initialize();
 
-        SubscribeLocalEvent<AccessOverriderComponent, WriteToTargetAccessReaderIdMessage>(OnWriteToTargetAccessReaderIdMessage);
         SubscribeLocalEvent<AccessOverriderComponent, ComponentStartup>(UpdateUserInterface);
         SubscribeLocalEvent<AccessOverriderComponent, EntInsertedIntoContainerMessage>(UpdateUserInterface);
         SubscribeLocalEvent<AccessOverriderComponent, EntRemovedFromContainerMessage>(UpdateUserInterface);
         SubscribeLocalEvent<AccessOverriderComponent, AfterInteractEvent>(AfterInteractOn);
         SubscribeLocalEvent<AccessOverriderComponent, AccessOverriderDoAfterEvent>(OnDoAfter);
-        SubscribeLocalEvent<AccessOverriderComponent, BoundUIOpenedEvent>(UpdateUserInterface);
-        SubscribeLocalEvent<AccessOverriderComponent, BoundUIClosedEvent>(OnClose);
+
+        Subs.BuiEvents<AccessOverriderComponent>(AccessOverriderUiKey.Key, subs =>
+        {
+            subs.Event<BoundUIOpenedEvent>(UpdateUserInterface);
+            subs.Event<BoundUIClosedEvent>(OnClose);
+            subs.Event<WriteToTargetAccessReaderIdMessage>(OnWriteToTargetAccessReaderIdMessage);
+        });
     }
 
     private void AfterInteractOn(EntityUid uid, AccessOverriderComponent component, AfterInteractEvent args)
index ecc5bfd3e2c786a9360dfefd2287c35a9c33e206..a57401cbb19862263c869a4fb8d334978c776f40 100644 (file)
@@ -16,9 +16,13 @@ public sealed class BlockGameArcadeSystem : EntitySystem
 
         SubscribeLocalEvent<BlockGameArcadeComponent, ComponentInit>(OnComponentInit);
         SubscribeLocalEvent<BlockGameArcadeComponent, AfterActivatableUIOpenEvent>(OnAfterUIOpen);
-        SubscribeLocalEvent<BlockGameArcadeComponent, BoundUIClosedEvent>(OnAfterUiClose);
         SubscribeLocalEvent<BlockGameArcadeComponent, PowerChangedEvent>(OnBlockPowerChanged);
-        SubscribeLocalEvent<BlockGameArcadeComponent, BlockGameMessages.BlockGamePlayerActionMessage>(OnPlayerAction);
+
+        Subs.BuiEvents<BlockGameArcadeComponent>(BlockGameUiKey.Key, subs =>
+        {
+            subs.Event<BoundUIClosedEvent>(OnAfterUiClose);
+            subs.Event<BlockGameMessages.BlockGamePlayerActionMessage>(OnPlayerAction);
+        });
     }
 
     public override void Update(float frameTime)
index b65d8556809eb2f2a41e56a32bad9c23a662c52f..b346fd63b0da61d27dc876713f7ae4f800de6beb 100644 (file)
@@ -157,19 +157,23 @@ public sealed class AirAlarmSystem : EntitySystem
         SubscribeLocalEvent<AirAlarmComponent, AtmosDeviceUpdateEvent>(OnAtmosUpdate);
         SubscribeLocalEvent<AirAlarmComponent, AtmosAlarmEvent>(OnAtmosAlarm);
         SubscribeLocalEvent<AirAlarmComponent, PowerChangedEvent>(OnPowerChanged);
-        SubscribeLocalEvent<AirAlarmComponent, AirAlarmResyncAllDevicesMessage>(OnResyncAll);
-        SubscribeLocalEvent<AirAlarmComponent, AirAlarmUpdateAlarmModeMessage>(OnUpdateAlarmMode);
-        SubscribeLocalEvent<AirAlarmComponent, AirAlarmUpdateAutoModeMessage>(OnUpdateAutoMode);
-        SubscribeLocalEvent<AirAlarmComponent, AirAlarmUpdateAlarmThresholdMessage>(OnUpdateThreshold);
-        SubscribeLocalEvent<AirAlarmComponent, AirAlarmUpdateDeviceDataMessage>(OnUpdateDeviceData);
-        SubscribeLocalEvent<AirAlarmComponent, AirAlarmCopyDeviceDataMessage>(OnCopyDeviceData);
-        SubscribeLocalEvent<AirAlarmComponent, AirAlarmTabSetMessage>(OnTabChange);
         SubscribeLocalEvent<AirAlarmComponent, DeviceListUpdateEvent>(OnDeviceListUpdate);
-        SubscribeLocalEvent<AirAlarmComponent, BoundUIClosedEvent>(OnClose);
         SubscribeLocalEvent<AirAlarmComponent, ComponentInit>(OnInit);
         SubscribeLocalEvent<AirAlarmComponent, MapInitEvent>(OnMapInit);
         SubscribeLocalEvent<AirAlarmComponent, ComponentShutdown>(OnShutdown);
         SubscribeLocalEvent<AirAlarmComponent, ActivateInWorldEvent>(OnActivate);
+
+        Subs.BuiEvents<AirAlarmComponent>(SharedAirAlarmInterfaceKey.Key, subs =>
+        {
+            subs.Event<BoundUIClosedEvent>(OnClose);
+            subs.Event<AirAlarmResyncAllDevicesMessage>(OnResyncAll);
+            subs.Event<AirAlarmUpdateAlarmModeMessage>(OnUpdateAlarmMode);
+            subs.Event<AirAlarmUpdateAutoModeMessage>(OnUpdateAutoMode);
+            subs.Event<AirAlarmUpdateAlarmThresholdMessage>(OnUpdateThreshold);
+            subs.Event<AirAlarmUpdateDeviceDataMessage>(OnUpdateDeviceData);
+            subs.Event<AirAlarmCopyDeviceDataMessage>(OnCopyDeviceData);
+            subs.Event<AirAlarmTabSetMessage>(OnTabChange);
+        });
     }
 
     private void OnDeviceListUpdate(EntityUid uid, AirAlarmComponent component, DeviceListUpdateEvent args)
index 4c4f17f61d4934b4f8c114b1e7a27bbc739734e5..12b6984b5aeab19fe243c7e21a66662f76d752d8 100644 (file)
@@ -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<AfterGeneralRecordCreatedEvent>(AfterGeneralRecordCreated);
         SubscribeLocalEvent<RecordModifiedEvent>(OnRecordModified);
         SubscribeLocalEvent<RecordRemovedEvent>(OnRecordRemoved);
-        SubscribeLocalEvent<CrewManifestViewerComponent, BoundUIClosedEvent>(OnBoundUiClose);
-        SubscribeLocalEvent<CrewManifestViewerComponent, CrewManifestOpenUiMessage>(OpenEuiFromBui);
         SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundRestart);
         SubscribeNetworkEvent<RequestCrewManifestMessage>(OnRequestCrewManifest);
+
+        SubscribeLocalEvent<CrewManifestViewerComponent, BoundUIClosedEvent>(OnBoundUiClose);
+        SubscribeLocalEvent<CrewManifestViewerComponent, CrewManifestOpenUiMessage>(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)
         {
index f66bc4c1afb965c847c54ee44bcb7493069e080e..25d73abf92ec3b084e2e97e10ecc60551e5d76c4 100644 (file)
@@ -1,3 +1,5 @@
+using Content.Shared.CCVar;
+
 namespace Content.Server.CrewManifest;
 
 [RegisterComponent]
@@ -5,8 +7,14 @@ public sealed partial class CrewManifestViewerComponent : Component
 {
     /// <summary>
     ///     If this manifest viewer is unsecure or not. If it is,
-    ///     CCVars.CrewManifestUnsecure being false will
+    ///     <see cref="CCVars.CrewManifestUnsecure"/> being false will
     ///     not allow this entity to be processed by CrewManifestSystem.
     /// </summary>
     [DataField("unsecure")] public bool Unsecure;
+
+    /// <summary>
+    /// The owner interface of this crew manifest viewer. When it closes, so too will an opened crew manifest.
+    /// </summary>
+    [DataField(required: true)]
+    public Enum OwnerKey { get; private set; } = default!;
 }
index e610907d2575e7952111ec83f414d285dfea2475..c8faa930d1126eb55ea4d72b9e4c51a6bbaa4132 100644 (file)
@@ -532,6 +532,13 @@ public sealed class NetworkConfiguratorSystem : SharedNetworkConfiguratorSystem
     /// </summary>
     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);
index 2bf00c5008c5473380e158c48ac32552f239019d..b7d8455d85e07bb4075ed205294bfd53969b93fb 100644 (file)
@@ -58,22 +58,26 @@ namespace Content.Server.Disposal.Tube
             SubscribeLocalEvent<DisposalJunctionComponent, GetDisposalsConnectableDirectionsEvent>(OnGetJunctionConnectableDirections);
             SubscribeLocalEvent<DisposalJunctionComponent, GetDisposalsNextDirectionEvent>(OnGetJunctionNextDirection);
 
-            SubscribeLocalEvent<DisposalRouterComponent, ComponentRemove>(OnComponentRemove);
             SubscribeLocalEvent<DisposalRouterComponent, GetDisposalsConnectableDirectionsEvent>(OnGetRouterConnectableDirections);
             SubscribeLocalEvent<DisposalRouterComponent, GetDisposalsNextDirectionEvent>(OnGetRouterNextDirection);
 
             SubscribeLocalEvent<DisposalTransitComponent, GetDisposalsConnectableDirectionsEvent>(OnGetTransitConnectableDirections);
             SubscribeLocalEvent<DisposalTransitComponent, GetDisposalsNextDirectionEvent>(OnGetTransitNextDirection);
 
-            SubscribeLocalEvent<DisposalTaggerComponent, ComponentRemove>(OnComponentRemove);
             SubscribeLocalEvent<DisposalTaggerComponent, GetDisposalsConnectableDirectionsEvent>(OnGetTaggerConnectableDirections);
             SubscribeLocalEvent<DisposalTaggerComponent, GetDisposalsNextDirectionEvent>(OnGetTaggerNextDirection);
 
-            SubscribeLocalEvent<DisposalRouterComponent, ActivatableUIOpenAttemptEvent>(OnOpenRouterUIAttempt);
-            SubscribeLocalEvent<DisposalTaggerComponent, ActivatableUIOpenAttemptEvent>(OnOpenTaggerUIAttempt);
+            Subs.BuiEvents<DisposalRouterComponent>(DisposalRouterUiKey.Key, subs =>
+            {
+                subs.Event<BoundUIOpenedEvent>(OnOpenRouterUI);
+                subs.Event<SharedDisposalRouterComponent.UiActionMessage>(OnUiAction);
+            });
 
-            SubscribeLocalEvent<DisposalRouterComponent, SharedDisposalRouterComponent.UiActionMessage>(OnUiAction);
-            SubscribeLocalEvent<DisposalTaggerComponent, SharedDisposalTaggerComponent.UiActionMessage>(OnUiAction);
+            Subs.BuiEvents<DisposalTaggerComponent>(DisposalTaggerUiKey.Key, subs =>
+            {
+                subs.Event<BoundUIOpenedEvent>(OnOpenTaggerUI);
+                subs.Event<SharedDisposalTaggerComponent.UiActionMessage>(OnUiAction);
+            });
         }
 
 
@@ -84,15 +88,13 @@ namespace Content.Server.Disposal.Tube
         /// <param name="msg">A user interface message from the client.</param>
         private void OnUiAction(EntityUid uid, DisposalTaggerComponent tagger, SharedDisposalTaggerComponent.UiActionMessage msg)
         {
-            if (!DisposalTaggerUiKey.Key.Equals(msg.UiKey))
-                return;
             if (TryComp<PhysicsComponent>(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
         /// <param name="msg">A user interface message from the client.</param>
         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<PhysicsComponent>(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<HandsComponent>(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<HandsComponent>(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));
+            }
         }
 
         /// <summary>
@@ -325,11 +298,13 @@ namespace Content.Server.Disposal.Tube
         /// <returns>Returns a <see cref="SharedDisposalRouterComponent.DisposalRouterUserInterfaceState"/></returns>
         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)
index 6f8369182cbb8491a7044b06f91f49d7d1bcd36d..17899b723282a540004e80d32ba3d8c9e704a972 100644 (file)
@@ -50,9 +50,12 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem
         SubscribeNetworkEvent<InstrumentSetMasterEvent>(OnMidiSetMaster);
         SubscribeNetworkEvent<InstrumentSetFilteredChannelEvent>(OnMidiSetFilteredChannel);
 
-        SubscribeLocalEvent<InstrumentComponent, BoundUIClosedEvent>(OnBoundUIClosed);
-        SubscribeLocalEvent<InstrumentComponent, BoundUIOpenedEvent>(OnBoundUIOpened);
-        SubscribeLocalEvent<InstrumentComponent, InstrumentBandRequestBuiMessage>(OnBoundUIRequestBands);
+        Subs.BuiEvents<InstrumentComponent>(InstrumentUiKey.Key, subs =>
+        {
+            subs.Event<BoundUIClosedEvent>(OnBoundUIClosed);
+            subs.Event<BoundUIOpenedEvent>(OnBoundUIOpened);
+            subs.Event<InstrumentBandRequestBuiMessage>(OnBoundUIRequestBands);
+        });
 
         SubscribeLocalEvent<InstrumentComponent, ComponentGetState>(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<ActiveInstrumentComponent>(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<ActiveInstrumentComponent>(uid);
         Clean(uid, component);
     }
index c2d6f0fda25882a262e8b32892b5e5826a251841..f6858e10a05eca5fc6974768a4d0967b4d31b2da 100644 (file)
@@ -29,11 +29,15 @@ public sealed class MagicMirrorSystem : EntitySystem
     {
         base.Initialize();
         SubscribeLocalEvent<MagicMirrorComponent, ActivatableUIOpenAttemptEvent>(OnOpenUIAttempt);
-        SubscribeLocalEvent<MagicMirrorComponent, BoundUIClosedEvent>(OnUIClosed);
-        SubscribeLocalEvent<MagicMirrorComponent, MagicMirrorSelectMessage>(OnMagicMirrorSelect);
-        SubscribeLocalEvent<MagicMirrorComponent, MagicMirrorChangeColorMessage>(OnTryMagicMirrorChangeColor);
-        SubscribeLocalEvent<MagicMirrorComponent, MagicMirrorAddSlotMessage>(OnTryMagicMirrorAddSlot);
-        SubscribeLocalEvent<MagicMirrorComponent, MagicMirrorRemoveSlotMessage>(OnTryMagicMirrorRemoveSlot);
+
+        Subs.BuiEvents<MagicMirrorComponent>(MagicMirrorUiKey.Key, subs =>
+        {
+            subs.Event<BoundUIClosedEvent>(OnUIClosed);
+            subs.Event<MagicMirrorSelectMessage>(OnMagicMirrorSelect);
+            subs.Event<MagicMirrorChangeColorMessage>(OnTryMagicMirrorChangeColor);
+            subs.Event<MagicMirrorAddSlotMessage>(OnTryMagicMirrorAddSlot);
+            subs.Event<MagicMirrorRemoveSlotMessage>(OnTryMagicMirrorRemoveSlot);
+        });
 
         SubscribeLocalEvent<MagicMirrorComponent, AfterInteractEvent>(OnMagicMirrorInteract);
 
index 0460f08f13889bd80d180b6cf27f3ad537fe545d..c9db560fef06e5baad18087eb8fa6d91a3dd795a 100644 (file)
@@ -14,8 +14,12 @@ public sealed class StationMapSystem : EntitySystem
     {
         base.Initialize();
         SubscribeLocalEvent<StationMapUserComponent, EntParentChangedMessage>(OnUserParentChanged);
-        SubscribeLocalEvent<StationMapComponent, BoundUIOpenedEvent>(OnStationMapOpened);
-        SubscribeLocalEvent<StationMapComponent, BoundUIClosedEvent>(OnStationMapClosed);
+
+        Subs.BuiEvents<StationMapComponent>(StationMapUiKey.Key, subs =>
+        {
+            subs.Event<BoundUIOpenedEvent>(OnStationMapOpened);
+            subs.Event<BoundUIClosedEvent>(OnStationMapClosed);
+        });
     }
 
     private void OnStationMapClosed(EntityUid uid, StationMapComponent component, BoundUIClosedEvent args)
index 6c0dddeb266958bd1e29a11d5a6866f2a4183db5..26c6b178313ddd7b53bb508e6b6efb12d6338c8d 100644 (file)
@@ -10,7 +10,10 @@ public sealed partial class SensorMonitoringConsoleSystem
 {
     private void InitUI()
     {
-        SubscribeLocalEvent<SensorMonitoringConsoleComponent, BoundUIClosedEvent>(ConsoleUIClosed);
+        Subs.BuiEvents<SensorMonitoringConsoleComponent>(SensorMonitoringConsoleUiKey.Key, subs =>
+        {
+            subs.Event<BoundUIClosedEvent>(ConsoleUIClosed);
+        });
     }
 
     private void UpdateConsoleUI(EntityUid uid, SensorMonitoringConsoleComponent comp)
index 864a2fbaef25681db32ad89892d08933e2e8e679..cef4faa13b2afddedaa703166b20f8e629159def 100644 (file)
@@ -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)
index 21c7ecc0500806e5ea31dd718d0f5a5e2b8b5703..afe9d78a25cd5145cbfae06ffc9d48d7825403cf 100644 (file)
@@ -43,12 +43,18 @@ public sealed partial class ShuttleConsoleSystem : SharedShuttleConsoleSystem
         SubscribeLocalEvent<ShuttleConsoleComponent, PowerChangedEvent>(OnConsolePowerChange);
         SubscribeLocalEvent<ShuttleConsoleComponent, AnchorStateChangedEvent>(OnConsoleAnchorChange);
         SubscribeLocalEvent<ShuttleConsoleComponent, ActivatableUIOpenAttemptEvent>(OnConsoleUIOpenAttempt);
-        SubscribeLocalEvent<ShuttleConsoleComponent, ShuttleConsoleFTLRequestMessage>(OnDestinationMessage);
-        SubscribeLocalEvent<ShuttleConsoleComponent, BoundUIClosedEvent>(OnConsoleUIClose);
+        Subs.BuiEvents<ShuttleConsoleComponent>(ShuttleConsoleUiKey.Key, subs =>
+        {
+            subs.Event<ShuttleConsoleFTLRequestMessage>(OnDestinationMessage);
+            subs.Event<BoundUIClosedEvent>(OnConsoleUIClose);
+        });
 
         SubscribeLocalEvent<DroneConsoleComponent, ConsoleShuttleEvent>(OnCargoGetConsole);
         SubscribeLocalEvent<DroneConsoleComponent, AfterActivatableUIOpenEvent>(OnDronePilotConsoleOpen);
-        SubscribeLocalEvent<DroneConsoleComponent, BoundUIClosedEvent>(OnDronePilotConsoleClose);
+        Subs.BuiEvents<DroneConsoleComponent>(ShuttleConsoleUiKey.Key, subs =>
+        {
+            subs.Event<BoundUIClosedEvent>(OnDronePilotConsoleClose);
+        });
 
         SubscribeLocalEvent<DockEvent>(OnDock);
         SubscribeLocalEvent<UndockEvent>(OnUndock);
index b1da3cf30e4d9702499843b76496c39507b4eaef..035ca5f399a2cd2aa0ba2d9c1ecdea1890251e73 100644 (file)
@@ -34,7 +34,10 @@ public sealed partial class StorageSystem : SharedStorageSystem
     {
         base.Initialize();
         SubscribeLocalEvent<StorageComponent, GetVerbsEvent<ActivationVerb>>(AddUiVerb);
-        SubscribeLocalEvent<StorageComponent, BoundUIClosedEvent>(OnBoundUIClosed);
+        Subs.BuiEvents<StorageComponent>(StorageComponent.StorageUiKey.Key, subs =>
+        {
+            subs.Event<BoundUIClosedEvent>(OnBoundUIClosed);
+        });
         SubscribeLocalEvent<StorageComponent, BeforeExplodeEvent>(OnExploded);
 
         SubscribeLocalEvent<StorageFillComponent, MapInitEvent>(OnStorageFillMapInit);
index 7b1dff0b6bc9b6f4cd05146f7eadcfddab68ada1..39dcb1a9e0fd213802d28502cfc7955fd500c3a3 100644 (file)
@@ -18,16 +18,19 @@ public sealed class SurveillanceCameraMonitorSystem : EntitySystem
     public override void Initialize()
     {
         SubscribeLocalEvent<SurveillanceCameraMonitorComponent, SurveillanceCameraDeactivateEvent>(OnSurveillanceCameraDeactivate);
-        SubscribeLocalEvent<SurveillanceCameraMonitorComponent, BoundUIClosedEvent>(OnBoundUiClose);
         SubscribeLocalEvent<SurveillanceCameraMonitorComponent, PowerChangedEvent>(OnPowerChanged);
-        SubscribeLocalEvent<SurveillanceCameraMonitorComponent, SurveillanceCameraMonitorSwitchMessage>(OnSwitchMessage);
         SubscribeLocalEvent<SurveillanceCameraMonitorComponent, DeviceNetworkPacketEvent>(OnPacketReceived);
-        SubscribeLocalEvent<SurveillanceCameraMonitorComponent, SurveillanceCameraMonitorSubnetRequestMessage>(OnSubnetRequest);
         SubscribeLocalEvent<SurveillanceCameraMonitorComponent, ComponentStartup>(OnComponentStartup);
         SubscribeLocalEvent<SurveillanceCameraMonitorComponent, AfterActivatableUIOpenEvent>(OnToggleInterface);
-        SubscribeLocalEvent<SurveillanceCameraMonitorComponent, SurveillanceCameraRefreshCamerasMessage>(OnRefreshCamerasMessage);
-        SubscribeLocalEvent<SurveillanceCameraMonitorComponent, SurveillanceCameraRefreshSubnetsMessage>(OnRefreshSubnetsMessage);
-        SubscribeLocalEvent<SurveillanceCameraMonitorComponent, SurveillanceCameraDisconnectMessage>(OnDisconnectMessage);
+        Subs.BuiEvents<SurveillanceCameraMonitorComponent>(SurveillanceCameraMonitorUiKey.Key, subs =>
+        {
+            subs.Event<SurveillanceCameraRefreshCamerasMessage>(OnRefreshCamerasMessage);
+            subs.Event<SurveillanceCameraRefreshSubnetsMessage>(OnRefreshSubnetsMessage);
+            subs.Event<SurveillanceCameraDisconnectMessage>(OnDisconnectMessage);
+            subs.Event<SurveillanceCameraMonitorSubnetRequestMessage>(OnSubnetRequest);
+            subs.Event<SurveillanceCameraMonitorSwitchMessage>(OnSwitchMessage);
+            subs.Event<BoundUIClosedEvent>(OnBoundUiClose);
+        });
     }
 
     private const float _maxHeartbeatTime = 300f;
index 918be614b87c5110d0f726c9a814ab994dfc7802..7c687aa3cd406e4b87c4fd437f096d59efbafa11 100644 (file)
@@ -31,12 +31,24 @@ public sealed partial class ActivatableUISystem
 
     private void OnBatteryOpened(EntityUid uid, ActivatableUIRequiresPowerCellComponent component, BoundUIOpenedEvent args)
     {
+        var activatable = Comp<ActivatableUIComponent>(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<ActivatableUIComponent>(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);
     }
 
     /// <summary>
index 459a704911f688f2da25f23ce83bce4a7d688bd1..e3dad6335865bedbedbf8f1203b9180426b9eab9 100644 (file)
@@ -124,22 +124,28 @@ public sealed partial class ActivatableUISystem : EntitySystem
 
     private bool InteractUI(EntityUid user, EntityUid uiEntity, ActivatableUIComponent aui)
     {
-        if (!_blockerSystem.CanInteract(user, uiEntity) && (!aui.AllowSpectator || !HasComp<GhostComponent>(user)))
+        if (!TryComp(user, out ActorComponent? actor))
             return false;
 
-        if (aui.RequireHands && !HasComp<HandsComponent>(user))
+        if (aui.Key == null)
             return false;
 
-        if (!EntityManager.TryGetComponent(user, out ActorComponent? actor))
+        if (!_uiSystem.TryGetUi(uiEntity, aui.Key, out var ui))
             return false;
 
-        if (aui.AdminOnly && !_adminManager.IsAdmin(actor.PlayerSession))
+        if (ui.SubscribedSessions.Contains(actor.PlayerSession))
+        {
+            _uiSystem.CloseUi(ui, actor.PlayerSession);
+            return true;
+        }
+
+        if (!_blockerSystem.CanInteract(user, uiEntity) && (!aui.AllowSpectator || !HasComp<GhostComponent>(user)))
             return false;
 
-        if (aui.Key == null)
+        if (aui.RequireHands && !HasComp<HandsComponent>(user))
             return false;
 
-        if (!_uiSystem.TryGetUi(uiEntity, aui.Key, out var ui))
+        if (aui.AdminOnly && !_adminManager.IsAdmin(actor.PlayerSession))
             return false;
 
         if (aui.SingleUser && (aui.CurrentSingleUser != null) && (actor.PlayerSession != aui.CurrentSingleUser))
@@ -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);
index e4d4e931e3536bb056c584bc8d3efc100cd2cebf..da024888a50d2f1fbca7b436370db532ac1f644f 100644 (file)
@@ -56,9 +56,13 @@ namespace Content.Server.VendingMachines
             SubscribeLocalEvent<VendingMachineComponent, EmpPulseEvent>(OnEmpPulse);
 
             SubscribeLocalEvent<VendingMachineComponent, ActivatableUIOpenAttemptEvent>(OnActivatableUIOpenAttempt);
-            SubscribeLocalEvent<VendingMachineComponent, BoundUIOpenedEvent>(OnBoundUIOpened);
-            SubscribeLocalEvent<VendingMachineComponent, BoundUIClosedEvent>(OnBoundUIClosed);
-            SubscribeLocalEvent<VendingMachineComponent, VendingMachineEjectMessage>(OnInventoryEjectMessage);
+
+            Subs.BuiEvents<VendingMachineComponent>(VendingMachineUiKey.Key, subs =>
+            {
+                subs.Event<BoundUIOpenedEvent>(OnBoundUIOpened);
+                subs.Event<BoundUIClosedEvent>(OnBoundUIClosed);
+                subs.Event<VendingMachineEjectMessage>(OnInventoryEjectMessage);
+            });
 
             SubscribeLocalEvent<VendingMachineComponent, VendingMachineSelfDispenseEvent>(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<AdvertiseComponent>(uid, out var advertise))
             {
index 2975607fd7f0d6f4f6aa542a51926da02176277d..64fbfdf66f39a986f98ff20e532467eaae2c3e0d 100644 (file)
@@ -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
 
index 24091a05334cd2254ae404f59aa0e81a6ed5337d..dc4b40fc7f8339a8873a63889bbf81c70d01c3ed 100644 (file)
@@ -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
index 8a0c6dea94fb918312120945384b3fccc6c5cda6..133ae8eb2c2a17a8f706c1616e29eb94695f06a3 100644 (file)
@@ -99,8 +99,6 @@
       type: InstrumentBoundUserInterface
     - key: enum.HealthAnalyzerUiKey.Key
       type: HealthAnalyzerBoundUserInterface
-  - type: CrewManifestViewer
-    unsecure: true
   - type: Tag
     tags:
     - DoorBumpOpener
index d42127b1328e4ad8340e448f9cef27425c6bb1b9..c0c91d57c69d3711dde844c61cef7afb07bed529 100644 (file)
     energy: 1.6
     color: "#c94242"
   - type: Computer
-    board: CargoShuttleConsoleCircuitboard  
+    board: CargoShuttleConsoleCircuitboard
   - type: StealTarget
     stealGroup: CargoShuttleConsoleCircuitboard
 
       board: SalvageShuttleConsoleCircuitboard
     - type: StealTarget
       stealGroup: SalvageShuttleConsoleCircuitboard
-      
+
 - type: entity
   parent: BaseComputer
   id: ComputerIFF
     - key: enum.IdCardConsoleUiKey.Key
       type: IdCardConsoleBoundUserInterface
   - type: CrewManifestViewer
+    ownerKey: enum.IdCardConsoleUiKey.Key
   - type: Sprite
     layers:
     - map: ["computerLayerBody"]
       access: [["Salvage"]]
     - type: StealTarget
       stealGroup: SalvageExpeditionsComputerCircuitboard
-      
+
 - type: entity
   parent: BaseComputer
   id: ComputerSurveillanceCameraMonitor