diff --git a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.cs b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.cs
index b72a7c4eb3..fd732009e9 100644
--- a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.cs
+++ b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.cs
@@ -87,7 +87,6 @@ public abstract partial class SharedHandsSystem
///
///
///
-
public void RemoveHands(EntityUid uid, HandsComponent? handsComp = null)
{
if (!Resolve(uid, ref handsComp))
@@ -137,6 +136,43 @@ public abstract partial class SharedHandsSystem
return false;
}
+ public bool TryGetActiveHand(Entity entity, [NotNullWhen(true)] out Hand? hand)
+ {
+ if (!Resolve(entity, ref entity.Comp, false))
+ {
+ hand = null;
+ return false;
+ }
+
+ hand = entity.Comp.ActiveHand;
+ return hand != null;
+ }
+
+ public bool TryGetActiveItem(Entity entity, [NotNullWhen(true)] out EntityUid? item)
+ {
+ if (!TryGetActiveHand(entity, out var hand))
+ {
+ item = null;
+ return false;
+ }
+
+ item = hand.HeldEntity;
+ return item != null;
+ }
+
+ public Hand? GetActiveHand(Entity entity)
+ {
+ if (!Resolve(entity, ref entity.Comp))
+ return null;
+
+ return entity.Comp.ActiveHand;
+ }
+
+ public EntityUid? GetActiveItem(Entity entity)
+ {
+ return GetActiveHand(entity)?.HeldEntity;
+ }
+
///
/// Enumerate over hands, starting with the currently active hand.
///
@@ -227,9 +263,17 @@ public abstract partial class SharedHandsSystem
return true;
}
- public bool IsHolding(EntityUid uid, EntityUid? entity, [NotNullWhen(true)] out Hand? inHand, HandsComponent? handsComp = null)
+ public bool IsHolding(Entity entity, [NotNullWhen(true)] EntityUid? item)
+ {
+ return IsHolding(entity, item, out _, entity);
+ }
+
+ public bool IsHolding(EntityUid uid, [NotNullWhen(true)] EntityUid? entity, [NotNullWhen(true)] out Hand? inHand, HandsComponent? handsComp = null)
{
inHand = null;
+ if (entity == null)
+ return false;
+
if (!Resolve(uid, ref handsComp, false))
return false;
diff --git a/Content.Shared/UserInterface/ActivatableUIComponent.cs b/Content.Shared/UserInterface/ActivatableUIComponent.cs
index 136a1f82cf..3f83816b7d 100644
--- a/Content.Shared/UserInterface/ActivatableUIComponent.cs
+++ b/Content.Shared/UserInterface/ActivatableUIComponent.cs
@@ -4,22 +4,26 @@ using Robust.Shared.Serialization.TypeSerializers.Implementations;
namespace Content.Shared.UserInterface
{
- [RegisterComponent, NetworkedComponent]
+ [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class ActivatableUIComponent : Component
{
[DataField(required: true, customTypeSerializer: typeof(EnumSerializer))]
- public Enum? Key { get; set; } = default!;
+ public Enum? Key;
+
+ ///
+ /// Whether the item must be held in one of the user's hands to work.
+ /// This is ignored unless is true.
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField]
+ public bool InHandsOnly;
+
+ [DataField]
+ public bool SingleUser;
[ViewVariables(VVAccess.ReadWrite)]
[DataField]
- public bool InHandsOnly { get; set; } = false;
-
- [DataField]
- public bool SingleUser { get; set; } = false;
-
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField]
- public bool AdminOnly { get; set; } = false;
+ public bool AdminOnly;
[DataField]
public LocId VerbText = "ui-verb-toggle-open";
@@ -38,16 +42,15 @@ namespace Content.Shared.UserInterface
///
/// Entities that are required to open this UI.
///
- [DataField("allowedItems")]
- [ViewVariables(VVAccess.ReadWrite)]
- public EntityWhitelist? AllowedItems = null;
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public EntityWhitelist? RequiredItems;
///
- /// Whether you can activate this ui with activateinhand or not
+ /// If true, then this UI can only be opened via verbs. I.e., normal interactions/activations will not open
+ /// the UI.
///
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField]
- public bool RightClickOnly;
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public bool VerbOnly;
///
/// Whether spectators (non-admin ghosts) should be allowed to view this UI.
@@ -57,17 +60,18 @@ namespace Content.Shared.UserInterface
public bool AllowSpectator = true;
///
- /// Whether the UI should close when the item is deselected due to a hand swap or drop
+ /// Whether the item must be in the user's currently selected/active hand.
+ /// This is ignored unless is true.
///
[ViewVariables(VVAccess.ReadWrite)]
[DataField]
- public bool CloseOnHandDeselect = true;
+ public bool RequireActiveHand = true;
///
/// The client channel currently using the object, or null if there's none/not single user.
/// NOTE: DO NOT DIRECTLY SET, USE ActivatableUISystem.SetCurrentSingleUser
///
- [ViewVariables]
+ [DataField, AutoNetworkedField]
public EntityUid? CurrentSingleUser;
}
}
diff --git a/Content.Shared/UserInterface/ActivatableUISystem.Power.cs b/Content.Shared/UserInterface/ActivatableUISystem.Power.cs
index 64099c9573..b8a815c7a8 100644
--- a/Content.Shared/UserInterface/ActivatableUISystem.Power.cs
+++ b/Content.Shared/UserInterface/ActivatableUISystem.Power.cs
@@ -20,12 +20,19 @@ public sealed partial class ActivatableUISystem
{
_cell.SetPowerCellDrawEnabled(uid, false);
- if (HasComp(uid) &&
- TryComp(uid, out var activatable) &&
- activatable.Key != null)
+ if (!HasComp(uid) ||
+ !TryComp(uid, out ActivatableUIComponent? activatable))
{
- _uiSystem.CloseUi(uid, activatable.Key);
+ return;
}
+
+ if (activatable.Key == null)
+ {
+ Log.Error($"Encountered null key in activatable ui on entity {ToPrettyString(uid)}");
+ return;
+ }
+
+ _uiSystem.CloseUi(uid, activatable.Key);
}
private void OnBatteryOpened(EntityUid uid, ActivatableUIRequiresPowerCellComponent component, BoundUIOpenedEvent args)
@@ -55,9 +62,15 @@ public sealed partial class ActivatableUISystem
///
public void CheckUsage(EntityUid uid, ActivatableUIComponent? active = null, ActivatableUIRequiresPowerCellComponent? component = null, PowerCellDrawComponent? draw = null)
{
- if (!Resolve(uid, ref component, ref draw, ref active, false) || active.Key == null)
+ if (!Resolve(uid, ref component, ref draw, ref active, false))
return;
+ if (active.Key == null)
+ {
+ Log.Error($"Encountered null key in activatable ui on entity {ToPrettyString(uid)}");
+ return;
+ }
+
if (_cell.HasActivatableCharge(uid))
return;
diff --git a/Content.Shared/UserInterface/ActivatableUISystem.cs b/Content.Shared/UserInterface/ActivatableUISystem.cs
index 94271cc681..5d408012bd 100644
--- a/Content.Shared/UserInterface/ActivatableUISystem.cs
+++ b/Content.Shared/UserInterface/ActivatableUISystem.cs
@@ -3,11 +3,11 @@ using Content.Shared.Administration.Managers;
using Content.Shared.Ghost;
using Content.Shared.Hands;
using Content.Shared.Hands.Components;
+using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction;
-using Content.Shared.Interaction.Events;
using Content.Shared.Popups;
using Content.Shared.Verbs;
-using Robust.Shared.Player;
+using Robust.Shared.Containers;
namespace Content.Shared.UserInterface;
@@ -17,23 +17,31 @@ public sealed partial class ActivatableUISystem : EntitySystem
[Dependency] private readonly ActionBlockerSystem _blockerSystem = default!;
[Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!;
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
+ [Dependency] private readonly SharedHandsSystem _hands = default!;
+ [Dependency] private readonly SharedContainerSystem _container = default!;
+ [Dependency] private readonly SharedInteractionSystem _interaction = default!;
+
+ private readonly List _toClose = new();
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent(OnActivate);
- SubscribeLocalEvent(OnUseInHand);
SubscribeLocalEvent(OnInteractUsing);
SubscribeLocalEvent(OnHandDeselected);
- SubscribeLocalEvent((uid, aui, _) => CloseAll(uid, aui));
- // *THIS IS A BLATANT WORKAROUND!* RATIONALE: Microwaves need it
- SubscribeLocalEvent(OnParentChanged);
+ SubscribeLocalEvent(OnHandUnequipped);
SubscribeLocalEvent(OnUIClose);
+ SubscribeLocalEvent>(GetActivationVerb);
+ SubscribeLocalEvent>(GetVerb);
+
+ // TODO ActivatableUI
+ // Add UI-user component, and listen for user container changes.
+ // I.e., should lose a computer UI if a player gets shut into a locker.
+ SubscribeLocalEvent(OnGotInserted);
+ SubscribeLocalEvent(OnGotRemoved);
+
SubscribeLocalEvent(OnBoundInterfaceInteractAttempt);
-
- SubscribeLocalEvent>(AddOpenUiVerb);
-
SubscribeLocalEvent(OnActionPerform);
InitializePower();
@@ -59,25 +67,54 @@ public sealed partial class ActivatableUISystem : EntitySystem
args.Handled = _uiSystem.TryToggleUi(uid, args.Key, args.Performer);
}
- private void AddOpenUiVerb(EntityUid uid, ActivatableUIComponent component, GetVerbsEvent args)
+
+ private void GetActivationVerb(EntityUid uid, ActivatableUIComponent component, GetVerbsEvent args)
+ {
+ if (component.VerbOnly || !ShouldAddVerb(uid, component, args))
+ return;
+
+ args.Verbs.Add(new ActivationVerb
+ {
+ // TODO VERBS add "open UI" icon
+ Act = () => InteractUI(args.User, uid, component),
+ Text = Loc.GetString(component.VerbText)
+ });
+ }
+
+ private void GetVerb(EntityUid uid, ActivatableUIComponent component, GetVerbsEvent args)
+ {
+ if (!component.VerbOnly || !ShouldAddVerb(uid, component, args))
+ return;
+
+ args.Verbs.Add(new Verb
+ {
+ // TODO VERBS add "open UI" icon
+ Act = () => InteractUI(args.User, uid, component),
+ Text = Loc.GetString(component.VerbText)
+ });
+ }
+
+ private bool ShouldAddVerb(EntityUid uid, ActivatableUIComponent component, GetVerbsEvent args) where T : Verb
{
if (!args.CanAccess)
- return;
+ return false;
- if (component.RequireHands && args.Hands == null)
- return;
+ if (component.RequireHands)
+ {
+ if (args.Hands == null)
+ return false;
- if (component.InHandsOnly && args.Using != uid)
- return;
+ if (component.InHandsOnly)
+ {
+ if (!_hands.IsHolding(args.User, uid, out var hand, args.Hands))
+ return false;
- if (!args.CanInteract && (!component.AllowSpectator || !HasComp(args.User)))
- return;
+ if (component.RequireActiveHand && args.Hands.ActiveHand != hand)
+ return false;
+ }
+ }
- ActivationVerb verb = new();
- verb.Act = () => InteractUI(args.User, uid, component);
- verb.Text = Loc.GetString(component.VerbText);
- // TODO VERBS add "open UI" icon?
- args.Verbs.Add(verb);
+ return args.CanInteract || component.AllowSpectator && HasComp(args.User);
}
private void OnActivate(EntityUid uid, ActivatableUIComponent component, ActivateInWorldEvent args)
@@ -85,24 +122,10 @@ public sealed partial class ActivatableUISystem : EntitySystem
if (args.Handled)
return;
- if (component.InHandsOnly)
+ if (component.VerbOnly)
return;
- if (component.AllowedItems != null)
- return;
-
- args.Handled = InteractUI(args.User, uid, component);
- }
-
- private void OnUseInHand(EntityUid uid, ActivatableUIComponent component, UseInHandEvent args)
- {
- if (args.Handled)
- return;
-
- if (component.RightClickOnly)
- return;
-
- if (component.AllowedItems != null)
+ if (component.RequiredItems != null)
return;
args.Handled = InteractUI(args.User, uid, component);
@@ -110,15 +133,19 @@ public sealed partial class ActivatableUISystem : EntitySystem
private void OnInteractUsing(EntityUid uid, ActivatableUIComponent component, InteractUsingEvent args)
{
- if (args.Handled) return;
- if (component.AllowedItems == null) return;
- if (!component.AllowedItems.IsValid(args.Used, EntityManager)) return;
- args.Handled = InteractUI(args.User, uid, component);
- }
+ if (args.Handled)
+ return;
- private void OnParentChanged(EntityUid uid, ActivatableUIComponent aui, ref EntParentChangedMessage args)
- {
- CloseAll(uid, aui);
+ if (component.VerbOnly)
+ return;
+
+ if (component.RequiredItems == null)
+ return;
+
+ if (!component.RequiredItems.IsValid(args.Used, EntityManager))
+ return;
+
+ args.Handled = InteractUI(args.User, uid, component);
}
private void OnUIClose(EntityUid uid, ActivatableUIComponent component, BoundUIClosedEvent args)
@@ -148,22 +175,33 @@ public sealed partial class ActivatableUISystem : EntitySystem
if (!_blockerSystem.CanInteract(user, uiEntity) && (!aui.AllowSpectator || !HasComp(user)))
return false;
- if (aui.RequireHands && !HasComp(user))
- return false;
+ if (aui.RequireHands)
+ {
+ if (!TryComp(user, out HandsComponent? hands))
+ return false;
+
+ if (aui.InHandsOnly)
+ {
+ if (!_hands.IsHolding(user, uiEntity, out var hand, hands))
+ return false;
+
+ if (aui.RequireActiveHand && hands.ActiveHand != hand)
+ return false;
+ }
+ }
if (aui.AdminOnly && !_adminManager.IsAdmin(user))
return false;
if (aui.SingleUser && aui.CurrentSingleUser != null && user != aui.CurrentSingleUser)
{
- string message = Loc.GetString("machine-already-in-use", ("machine", uiEntity));
+ var message = Loc.GetString("machine-already-in-use", ("machine", uiEntity));
_popupSystem.PopupEntity(message, uiEntity, user);
- // If we get here, supposedly, the object is in use.
- // Check with BUI that it's ACTUALLY in use just in case.
- // Since this could brick the object if it goes wrong.
if (_uiSystem.IsUiOpen(uiEntity, aui.Key))
- return false;
+ return true;
+
+ Log.Error($"Activatable UI has user without being opened? Entity: {ToPrettyString(uiEntity)}. User: {aui.CurrentSingleUser}, Key: {aui.Key}");
}
// If we've gotten this far, fire a cancellable event that indicates someone is about to activate this.
@@ -199,26 +237,77 @@ public sealed partial class ActivatableUISystem : EntitySystem
return;
aui.CurrentSingleUser = user;
+ Dirty(uid, aui);
RaiseLocalEvent(uid, new ActivatableUIPlayerChangedEvent());
}
public void CloseAll(EntityUid uid, ActivatableUIComponent? aui = null)
{
- if (!Resolve(uid, ref aui, false) || aui.Key == null)
+ if (!Resolve(uid, ref aui, false))
return;
+ if (aui.Key == null)
+ {
+ Log.Error($"Encountered null key in activatable ui on entity {ToPrettyString(uid)}");
+ return;
+ }
+
_uiSystem.CloseUi(uid, aui.Key);
}
- private void OnHandDeselected(EntityUid uid, ActivatableUIComponent? aui, HandDeselectedEvent args)
+ private void OnHandDeselected(Entity ent, ref HandDeselectedEvent args)
{
- if (!Resolve(uid, ref aui, false))
+ if (ent.Comp.RequireHands && ent.Comp.InHandsOnly && ent.Comp.RequireActiveHand)
+ CloseAll(ent, ent);
+ }
+
+ private void OnHandUnequipped(Entity ent, ref GotUnequippedHandEvent args)
+ {
+ if (ent.Comp.RequireHands && ent.Comp.InHandsOnly)
+ CloseAll(ent, ent);
+ }
+
+ private void OnGotInserted(Entity ent, ref EntGotInsertedIntoContainerMessage args)
+ {
+ CheckAccess((ent, ent));
+ }
+
+ private void OnGotRemoved(Entity ent, ref EntGotRemovedFromContainerMessage args)
+ {
+ CheckAccess((ent, ent));
+ }
+
+ public void CheckAccess(Entity ent)
+ {
+ if (!Resolve(ent, ref ent.Comp))
return;
- if (!aui.CloseOnHandDeselect)
+ if (ent.Comp.Key == null)
+ {
+ Log.Error($"Encountered null key in activatable ui on entity {ToPrettyString(ent)}");
return;
+ }
- CloseAll(uid, aui);
+ foreach (var user in _uiSystem.GetActors(ent.Owner, ent.Comp.Key))
+ {
+ if (!_container.IsInSameOrParentContainer(user, ent)
+ && !_interaction.CanAccessViaStorage(user, ent))
+ {
+ _toClose.Add(user);
+ continue;
+
+ }
+
+ if (!_interaction.InRangeUnobstructed(user, ent))
+ _toClose.Add(user);
+ }
+
+ foreach (var user in _toClose)
+ {
+ _uiSystem.CloseUi(ent.Owner, ent.Comp.Key, user);
+ }
+
+ _toClose.Clear();
}
}
diff --git a/Resources/Prototypes/Entities/Clothing/Hands/gloves.yml b/Resources/Prototypes/Entities/Clothing/Hands/gloves.yml
index 02ec58bd67..0c2ded620e 100644
--- a/Resources/Prototypes/Entities/Clothing/Hands/gloves.yml
+++ b/Resources/Prototypes/Entities/Clothing/Hands/gloves.yml
@@ -372,8 +372,7 @@
- type: MeleeSpeech
- type: ActivatableUI
key: enum.MeleeSpeechUiKey.Key
- closeOnHandDeselect: false
- rightClickOnly: true
+ verbOnly: true
- type: Actions
- type: UserInterface
interfaces:
diff --git a/Resources/Prototypes/Entities/Objects/Devices/Electronics/door.yml b/Resources/Prototypes/Entities/Objects/Devices/Electronics/door.yml
index ada46c5d02..a832bea741 100644
--- a/Resources/Prototypes/Entities/Objects/Devices/Electronics/door.yml
+++ b/Resources/Prototypes/Entities/Objects/Devices/Electronics/door.yml
@@ -16,7 +16,7 @@
- type: AccessReader
- type: ActivatableUI
key: enum.DoorElectronicsConfigurationUiKey.Key
- allowedItems:
+ requiredItems:
tags:
- DoorElectronicsConfigurator
- type: UserInterface
diff --git a/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/war_declarator.yml b/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/war_declarator.yml
index c0ce4cba18..78009f1042 100644
--- a/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/war_declarator.yml
+++ b/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/war_declarator.yml
@@ -14,7 +14,7 @@
- type: ActivatableUI
inHandsOnly: true
singleUser: true
- closeOnHandDeselect: false
+ requireActiveHand: false
key: enum.WarDeclaratorUiKey.Key
- type: UserInterface
interfaces:
diff --git a/Resources/Prototypes/Entities/Objects/Devices/forensic_scanner.yml b/Resources/Prototypes/Entities/Objects/Devices/forensic_scanner.yml
index e7c0b14beb..170751766b 100644
--- a/Resources/Prototypes/Entities/Objects/Devices/forensic_scanner.yml
+++ b/Resources/Prototypes/Entities/Objects/Devices/forensic_scanner.yml
@@ -17,7 +17,7 @@
- type: ActivatableUI
key: enum.ForensicScannerUiKey.Key
inHandsOnly: true
- closeOnHandDeselect: false
+ requireActiveHand: false
- type: UserInterface
interfaces:
enum.ForensicScannerUiKey.Key:
diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml
index e1efc03993..472d0ecbe1 100644
--- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml
+++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml
@@ -86,7 +86,6 @@
- type: ActivatableUI
key: enum.PdaUiKey.Key
singleUser: true
- closeOnHandDeselect: false
- type: UserInterface
interfaces:
enum.PdaUiKey.Key:
diff --git a/Resources/Prototypes/Entities/Objects/Misc/books.yml b/Resources/Prototypes/Entities/Objects/Misc/books.yml
index e44e981a6c..25e6bb9f94 100644
--- a/Resources/Prototypes/Entities/Objects/Misc/books.yml
+++ b/Resources/Prototypes/Entities/Objects/Misc/books.yml
@@ -22,7 +22,6 @@
contentSize: 12000
- type: ActivatableUI
key: enum.PaperUiKey.Key
- closeOnHandDeselect: false
- type: UserInterface
interfaces:
enum.PaperUiKey.Key:
diff --git a/Resources/Prototypes/Entities/Objects/Misc/paper.yml b/Resources/Prototypes/Entities/Objects/Misc/paper.yml
index 0c87459164..5fa341c976 100644
--- a/Resources/Prototypes/Entities/Objects/Misc/paper.yml
+++ b/Resources/Prototypes/Entities/Objects/Misc/paper.yml
@@ -18,7 +18,6 @@
- type: PaperLabelType
- type: ActivatableUI
key: enum.PaperUiKey.Key
- closeOnHandDeselect: false
requireHands: false
- type: UserInterface
interfaces:
diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/handheld_crew_monitor.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/handheld_crew_monitor.yml
index f30e1cf633..19a0b36ee9 100644
--- a/Resources/Prototypes/Entities/Objects/Specific/Medical/handheld_crew_monitor.yml
+++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/handheld_crew_monitor.yml
@@ -17,7 +17,6 @@
- type: ActivatableUIRequiresPowerCell
- type: ActivatableUI
key: enum.CrewMonitoringUIKey.Key
- closeOnHandDeselect: false
- type: UserInterface
interfaces:
enum.CrewMonitoringUIKey.Key:
diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/healthanalyzer.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/healthanalyzer.yml
index 4f8b6f2936..c01aaa84a9 100644
--- a/Resources/Prototypes/Entities/Objects/Specific/Medical/healthanalyzer.yml
+++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/healthanalyzer.yml
@@ -17,7 +17,6 @@
storedRotation: -90
- type: ActivatableUI
key: enum.HealthAnalyzerUiKey.Key
- closeOnHandDeselect: false
- type: UserInterface
interfaces:
enum.HealthAnalyzerUiKey.Key:
diff --git a/Resources/Prototypes/Entities/Objects/Specific/Research/anomaly.yml b/Resources/Prototypes/Entities/Objects/Specific/Research/anomaly.yml
index 4250d9ccdd..bf0a3be4e5 100644
--- a/Resources/Prototypes/Entities/Objects/Specific/Research/anomaly.yml
+++ b/Resources/Prototypes/Entities/Objects/Specific/Research/anomaly.yml
@@ -9,7 +9,7 @@
state: icon
- type: ActivatableUI
key: enum.AnomalyScannerUiKey.Key
- closeOnHandDeselect: false
+ requireActiveHand: false
inHandsOnly: true
- type: UserInterface
interfaces:
diff --git a/Resources/Prototypes/Entities/Objects/Specific/Service/barber.yml b/Resources/Prototypes/Entities/Objects/Specific/Service/barber.yml
index d7b0a566e1..251331919e 100644
--- a/Resources/Prototypes/Entities/Objects/Specific/Service/barber.yml
+++ b/Resources/Prototypes/Entities/Objects/Specific/Service/barber.yml
@@ -10,7 +10,8 @@
- type: MagicMirror
- type: ActivatableUI
key: enum.MagicMirrorUiKey.Key
- closeOnHandDeselect: true
+ inHandsOnly: true
+ requireActiveHand: true
- type: UserInterface
interfaces:
enum.MagicMirrorUiKey.Key:
diff --git a/Resources/Prototypes/Entities/Objects/Specific/atmos.yml b/Resources/Prototypes/Entities/Objects/Specific/atmos.yml
index acf5f6f240..c67e7ff8c3 100644
--- a/Resources/Prototypes/Entities/Objects/Specific/atmos.yml
+++ b/Resources/Prototypes/Entities/Objects/Specific/atmos.yml
@@ -13,7 +13,7 @@
- type: ActivatableUI
inHandsOnly: true
singleUser: true
- closeOnHandDeselect: false
+ requireActiveHand: false
key: enum.GasAnalyzerUiKey.Key
- type: UserInterface
interfaces:
diff --git a/Resources/Prototypes/Entities/Objects/Tools/access_configurator.yml b/Resources/Prototypes/Entities/Objects/Tools/access_configurator.yml
index b6c7c49855..d63e1f0aa9 100644
--- a/Resources/Prototypes/Entities/Objects/Tools/access_configurator.yml
+++ b/Resources/Prototypes/Entities/Objects/Tools/access_configurator.yml
@@ -67,7 +67,7 @@
- type: ActivatableUI
key: enum.AccessOverriderUiKey.Key
requireHands: true
- closeOnHandDeselect: false
+ requireActiveHand: false
singleUser: true
- type: ItemSlots
- type: ContainerContainer