diff --git a/Content.Client/Inventory/StrippableBoundUserInterface.cs b/Content.Client/Inventory/StrippableBoundUserInterface.cs index 2ce07758c9..af7815935d 100644 --- a/Content.Client/Inventory/StrippableBoundUserInterface.cs +++ b/Content.Client/Inventory/StrippableBoundUserInterface.cs @@ -17,6 +17,7 @@ using Content.Shared.Inventory.VirtualItem; using Content.Shared.Strip.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.Player; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Input; @@ -29,10 +30,13 @@ namespace Content.Client.Inventory [UsedImplicitly] public sealed class StrippableBoundUserInterface : BoundUserInterface { + [Dependency] private readonly IPlayerManager _player = default!; [Dependency] private readonly IUserInterfaceManager _ui = default!; + private readonly ExamineSystem _examine; private readonly InventorySystem _inv; private readonly SharedCuffableSystem _cuffable; + private readonly StrippableSystem _strippable; [ViewVariables] private const int ButtonSeparation = 4; @@ -51,6 +55,8 @@ namespace Content.Client.Inventory _examine = EntMan.System(); _inv = EntMan.System(); _cuffable = EntMan.System(); + _strippable = EntMan.System(); + _virtualHiddenEntity = EntMan.SpawnEntity(HiddenPocketEntityId, MapCoordinates.Nullspace); } @@ -198,7 +204,8 @@ namespace Content.Client.Inventory var entity = container.ContainedEntity; // If this is a full pocket, obscure the real entity - if (entity != null && slotDef.StripHidden) + // this does not work for modified clients because they are still sent the real entity + if (entity != null && _strippable.IsStripHidden(slotDef, _player.LocalEntity)) entity = _virtualHiddenEntity; var button = new SlotButton(new SlotData(slotDef, container)); diff --git a/Content.Shared/Interaction/SharedInteractionSystem.cs b/Content.Shared/Interaction/SharedInteractionSystem.cs index 7f2ecb50f8..2926e1d1b3 100644 --- a/Content.Shared/Interaction/SharedInteractionSystem.cs +++ b/Content.Shared/Interaction/SharedInteractionSystem.cs @@ -21,6 +21,7 @@ using Content.Shared.Physics; using Content.Shared.Players.RateLimiting; using Content.Shared.Popups; using Content.Shared.Storage; +using Content.Shared.Strip; using Content.Shared.Tag; using Content.Shared.Timing; using Content.Shared.UserInterface; @@ -67,6 +68,7 @@ namespace Content.Shared.Interaction [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly TagSystem _tagSystem = default!; [Dependency] private readonly SharedUserInterfaceSystem _ui = default!; + [Dependency] private readonly SharedStrippableSystem _strippable = default!; [Dependency] private readonly SharedPlayerRateLimitManager _rateLimit = default!; [Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] private readonly ISharedChatManager _chat = default!; @@ -1321,7 +1323,7 @@ namespace Content.Shared.Interaction if (wearer == user) return true; - if (slotDef.StripHidden) + if (_strippable.IsStripHidden(slotDef, user)) return false; return InRangeUnobstructed(user, wearer) && _containerSystem.IsInSameOrParentContainer(user, wearer); diff --git a/Content.Shared/Inventory/InventorySystem.Equip.cs b/Content.Shared/Inventory/InventorySystem.Equip.cs index f089dfaf23..8158b8c2f6 100644 --- a/Content.Shared/Inventory/InventorySystem.Equip.cs +++ b/Content.Shared/Inventory/InventorySystem.Equip.cs @@ -10,6 +10,7 @@ using Content.Shared.Inventory.Events; using Content.Shared.Item; using Content.Shared.Movement.Systems; using Content.Shared.Popups; +using Content.Shared.Strip; using Content.Shared.Strip.Components; using Content.Shared.Whitelist; using Robust.Shared.Audio.Systems; @@ -32,6 +33,7 @@ public abstract partial class InventorySystem [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; + [Dependency] private readonly SharedStrippableSystem _strippable = default!; [ValidatePrototypeId] private const string PocketableItemSize = "Small"; diff --git a/Content.Shared/Inventory/InventorySystem.Relay.cs b/Content.Shared/Inventory/InventorySystem.Relay.cs index 9573f9b43d..d431195a81 100644 --- a/Content.Shared/Inventory/InventorySystem.Relay.cs +++ b/Content.Shared/Inventory/InventorySystem.Relay.cs @@ -114,7 +114,7 @@ public partial class InventorySystem var enumerator = new InventorySlotEnumerator(component); while (enumerator.NextItem(out var item, out var slotDef)) { - if (!slotDef.StripHidden || args.User == uid) + if (!_strippable.IsStripHidden(slotDef, args.User) || args.User == uid) RaiseLocalEvent(item, ev); } } diff --git a/Content.Shared/Inventory/InventoryTemplatePrototype.cs b/Content.Shared/Inventory/InventoryTemplatePrototype.cs index a4d77767e3..91accec8c9 100644 --- a/Content.Shared/Inventory/InventoryTemplatePrototype.cs +++ b/Content.Shared/Inventory/InventoryTemplatePrototype.cs @@ -1,4 +1,5 @@ using System.Numerics; +using Content.Shared.Strip; using Content.Shared.Whitelist; using Robust.Shared.Prototypes; @@ -39,6 +40,10 @@ public sealed partial class SlotDefinition [DataField("displayName", required: true)] public string DisplayName { get; private set; } = string.Empty; + /// + /// Whether or not this slot will have its item hidden in the strip menu, and block interactions. + /// + /// [DataField("stripHidden")] public bool StripHidden { get; private set; } /// diff --git a/Content.Shared/Strip/SharedStrippableSystem.cs b/Content.Shared/Strip/SharedStrippableSystem.cs index 7afe503275..e4b31debc6 100644 --- a/Content.Shared/Strip/SharedStrippableSystem.cs +++ b/Content.Shared/Strip/SharedStrippableSystem.cs @@ -10,6 +10,7 @@ using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.IdentityManagement; using Content.Shared.Interaction; +using Content.Shared.Interaction.Components; using Content.Shared.Interaction.Events; using Content.Shared.Inventory; using Content.Shared.Inventory.VirtualItem; @@ -294,7 +295,7 @@ public abstract class SharedStrippableSystem : EntitySystem if (!stealth) { - if (slotDef.StripHidden) + if (IsStripHidden(slotDef, user)) _popupSystem.PopupEntity(Loc.GetString("strippable-component-alert-owner-hidden", ("slot", slot)), target, target, PopupType.Large); else _popupSystem.PopupEntity(Loc.GetString("strippable-component-alert-owner", ("user", Identity.Entity(user, EntityManager)), ("item", item)), target, target, PopupType.Large); @@ -660,4 +661,15 @@ public abstract class SharedStrippableSystem : EntitySystem if (args.CanDrop) args.Handled = true; } + + public bool IsStripHidden(SlotDefinition definition, EntityUid? viewer) + { + if (!definition.StripHidden) + return false; + + if (viewer == null) + return true; + + return !HasComp(viewer); + } }