From 3643ce3263783da1a3a5348b1a50d44cfeb72de5 Mon Sep 17 00:00:00 2001 From: gordod3 Date: Thu, 16 Jul 2026 22:42:51 +0600 Subject: [PATCH 1/3] Dirty test --- .../Storage/AnchorableStorageVisualSystem.cs | 38 +++++++++++++++++++ .../_NF/Storage/AnchorableStorageSystem.cs | 25 ++++++++++-- .../_NF/Storage/AnchorableStorageVisuals.cs | 10 +++++ .../Clothing/Back/base_clothing_backpack.yml | 12 ++++++ 4 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 Content.Client/_NF/Storage/AnchorableStorageVisualSystem.cs create mode 100644 Content.Shared/_NF/Storage/AnchorableStorageVisuals.cs diff --git a/Content.Client/_NF/Storage/AnchorableStorageVisualSystem.cs b/Content.Client/_NF/Storage/AnchorableStorageVisualSystem.cs new file mode 100644 index 00000000000..7aaf47f0b8b --- /dev/null +++ b/Content.Client/_NF/Storage/AnchorableStorageVisualSystem.cs @@ -0,0 +1,38 @@ +using Content.Shared._NF.Storage; +using Robust.Client.GameObjects; +using DrawDepth = Content.Shared.DrawDepth.DrawDepth; + +namespace Content.Client._NF.Storage; + +/// +/// Applies anchorable storage world-sprite visibility and draw depth from appearance state. +/// +public sealed class AnchorableStorageVisualSystem : EntitySystem +{ + [Dependency] private AppearanceSystem _appearance = default!; + [Dependency] private SpriteSystem _sprite = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnAppearanceChange); + } + + private void OnAppearanceChange(Entity ent, ref AppearanceChangeEvent args) + { + if (args.Sprite == null) + return; + + UpdateVisuals(ent, args.Sprite); + } + + private void UpdateVisuals(Entity ent, SpriteComponent sprite) + { + if (!_appearance.TryGetData(ent.Owner, AnchorableStorageVisuals.Anchored, out var anchored, ent.Comp)) + return; + + _sprite.SetDrawDepth((ent.Owner, sprite), anchored ? (int) DrawDepth.ThinWire : (int) DrawDepth.Items); + _sprite.SetVisible((ent.Owner, sprite), !anchored); + } +} diff --git a/Content.Server/_NF/Storage/AnchorableStorageSystem.cs b/Content.Server/_NF/Storage/AnchorableStorageSystem.cs index 8fba12c6953..344c161208a 100644 --- a/Content.Server/_NF/Storage/AnchorableStorageSystem.cs +++ b/Content.Server/_NF/Storage/AnchorableStorageSystem.cs @@ -1,5 +1,6 @@ using System.Linq; using Content.Server.Popups; +using Content.Shared._NF.Storage; using Content.Shared.Construction.Components; using Content.Shared.Mind.Components; using Content.Shared.Nyanotrasen.Item.PseudoItem; @@ -21,27 +22,38 @@ public sealed partial class AnchorableStorageSystem : EntitySystem [Dependency] private PopupSystem _popup = default!; [Dependency] private TransformSystem _xform = default!; [Dependency] private SharedContainerSystem _container = default!; + [Dependency] private SharedAppearanceSystem _appearance = default!; /// public override void Initialize() { + base.Initialize(); + + SubscribeLocalEvent(OnComponentStartup); SubscribeLocalEvent(OnAnchorStateChanged); SubscribeLocalEvent(OnAnchorAttempt); SubscribeLocalEvent(OnInsertAttempt); } - private void OnAnchorStateChanged(Entity ent, ref AnchorStateChangedEvent args) + private void OnComponentStartup(Entity ent, ref ComponentStartup args) { - if (!args.Anchored) - return; + SetAnchoredVisuals(ent.Owner, Transform(ent.Owner).Anchored); + } - if (CheckOverlap((ent, ent.Comp, Transform(ent)))) + private void OnAnchorStateChanged(Entity ent, ref AnchorStateChangedEvent args) + { + if (args.Anchored && CheckOverlap((ent, ent.Comp, Transform(ent)))) { _popup.PopupEntity(Loc.GetString("anchored-storage-already-present"), ent); _xform.Unanchor(ent, Transform(ent)); return; } + SetAnchoredVisuals(ent.Owner, args.Anchored); + + if (!args.Anchored) + return; + // Eject any sapient creatures inside the storage. // Does not recurse down into bags in bags - player characters are the largest concern, and they'll only fit in duffelbags. if (!TryComp(ent.Owner, out StorageComponent? storage)) @@ -56,6 +68,11 @@ private void OnAnchorStateChanged(Entity ent, ref An _container.RemoveEntity(ent.Owner, removeUid); } + private void SetAnchoredVisuals(EntityUid uid, bool anchored) + { + _appearance.SetData(uid, AnchorableStorageVisuals.Anchored, anchored); + } + private void OnAnchorAttempt(Entity ent, ref AnchorAttemptEvent args) { if (args.Cancelled) diff --git a/Content.Shared/_NF/Storage/AnchorableStorageVisuals.cs b/Content.Shared/_NF/Storage/AnchorableStorageVisuals.cs new file mode 100644 index 00000000000..c94784bc3d8 --- /dev/null +++ b/Content.Shared/_NF/Storage/AnchorableStorageVisuals.cs @@ -0,0 +1,10 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared._NF.Storage; + +[Serializable, NetSerializable] +public enum AnchorableStorageVisuals : byte +{ + Anchored, + Layer, +} diff --git a/Resources/Prototypes/_NF/Entities/Clothing/Back/base_clothing_backpack.yml b/Resources/Prototypes/_NF/Entities/Clothing/Back/base_clothing_backpack.yml index 322e7bea791..f4a536f1311 100644 --- a/Resources/Prototypes/_NF/Entities/Clothing/Back/base_clothing_backpack.yml +++ b/Resources/Prototypes/_NF/Entities/Clothing/Back/base_clothing_backpack.yml @@ -3,6 +3,18 @@ abstract: true id: NFBackpackHiddenStash components: + - type: Sprite + layers: + - state: icon + map: [ "enum.AnchorableStorageVisuals.Layer" ] + - type: GenericVisualizer + visuals: + enum.AnchorableStorageVisuals.Anchored: + enum.AnchorableStorageVisuals.Layer: + True: { drawdepth: ThinWire, visible: false } + False: { drawdepth: Items, visible: true } + - type: Visibility + layer: 1 - type: Appearance - type: SubFloorHide - type: Anchorable From 60c35f0ed4a0603743b8d42456e2efb8990f346f Mon Sep 17 00:00:00 2001 From: gordod3 Date: Fri, 17 Jul 2026 00:48:31 +0600 Subject: [PATCH 2/3] Delete logic that not allow player characters being in stash bags, Added missing /// Forge-Change --- .../Storage/AnchorableStorageVisualSystem.cs | 2 + .../_NF/Storage/AnchorableStorageSystem.cs | 45 +++++++++++-------- .../_NF/Storage/AnchorableStorageVisuals.cs | 2 + 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/Content.Client/_NF/Storage/AnchorableStorageVisualSystem.cs b/Content.Client/_NF/Storage/AnchorableStorageVisualSystem.cs index 7aaf47f0b8b..8a5518c4b19 100644 --- a/Content.Client/_NF/Storage/AnchorableStorageVisualSystem.cs +++ b/Content.Client/_NF/Storage/AnchorableStorageVisualSystem.cs @@ -1,3 +1,4 @@ +/// Forge-Change-Start using Content.Shared._NF.Storage; using Robust.Client.GameObjects; using DrawDepth = Content.Shared.DrawDepth.DrawDepth; @@ -36,3 +37,4 @@ private void UpdateVisuals(Entity ent, SpriteComponent spri _sprite.SetVisible((ent.Owner, sprite), !anchored); } } +/// Forge-Change-End diff --git a/Content.Server/_NF/Storage/AnchorableStorageSystem.cs b/Content.Server/_NF/Storage/AnchorableStorageSystem.cs index 344c161208a..73c9fe207ac 100644 --- a/Content.Server/_NF/Storage/AnchorableStorageSystem.cs +++ b/Content.Server/_NF/Storage/AnchorableStorageSystem.cs @@ -1,6 +1,6 @@ using System.Linq; using Content.Server.Popups; -using Content.Shared._NF.Storage; +using Content.Shared._NF.Storage; /// Forge-Change using Content.Shared.Construction.Components; using Content.Shared.Mind.Components; using Content.Shared.Nyanotrasen.Item.PseudoItem; @@ -22,57 +22,64 @@ public sealed partial class AnchorableStorageSystem : EntitySystem [Dependency] private PopupSystem _popup = default!; [Dependency] private TransformSystem _xform = default!; [Dependency] private SharedContainerSystem _container = default!; - [Dependency] private SharedAppearanceSystem _appearance = default!; + [Dependency] private SharedAppearanceSystem _appearance = default!; /// Forge-Change /// public override void Initialize() { - base.Initialize(); + base.Initialize(); /// Forge-Change - SubscribeLocalEvent(OnComponentStartup); + SubscribeLocalEvent(OnComponentStartup); /// Forge-Change SubscribeLocalEvent(OnAnchorStateChanged); SubscribeLocalEvent(OnAnchorAttempt); SubscribeLocalEvent(OnInsertAttempt); } - + /// Forge-Change-Start private void OnComponentStartup(Entity ent, ref ComponentStartup args) { SetAnchoredVisuals(ent.Owner, Transform(ent.Owner).Anchored); } + /// Forge-Change-End private void OnAnchorStateChanged(Entity ent, ref AnchorStateChangedEvent args) { - if (args.Anchored && CheckOverlap((ent, ent.Comp, Transform(ent)))) + if (!args.Anchored) + return; + + if (CheckOverlap((ent, ent.Comp, Transform(ent)))) { _popup.PopupEntity(Loc.GetString("anchored-storage-already-present"), ent); _xform.Unanchor(ent, Transform(ent)); return; } + /// Forge-Change-Start SetAnchoredVisuals(ent.Owner, args.Anchored); if (!args.Anchored) return; - + /// Forge-Change-End // Eject any sapient creatures inside the storage. // Does not recurse down into bags in bags - player characters are the largest concern, and they'll only fit in duffelbags. - if (!TryComp(ent.Owner, out StorageComponent? storage)) - return; + // if (!TryComp(ent.Owner, out StorageComponent? storage)) /// Forge-Change-Del + // return; /// Forge-Change-Del - var entsToRemove = storage.StoredItems.Keys.Where(storedItem => - HasComp(storedItem) - || HasComp(storedItem) - ).ToList(); + // var entsToRemove = storage.StoredItems.Keys.Where(storedItem => /// Forge-Change-Del + // HasComp(storedItem) /// Forge-Change-Del + // || HasComp(storedItem) /// Forge-Change-Del + // ).ToList(); /// Forge-Change-Del - foreach (var removeUid in entsToRemove) - _container.RemoveEntity(ent.Owner, removeUid); + // foreach (var removeUid in entsToRemove) /// Forge-Change-Del + // _container.RemoveEntity(ent.Owner, removeUid); /// Forge-Change-Del } + /// Forge-Change-Start private void SetAnchoredVisuals(EntityUid uid, bool anchored) { _appearance.SetData(uid, AnchorableStorageVisuals.Anchored, anchored); } + /// Forge-Change-End private void OnAnchorAttempt(Entity ent, ref AnchorAttemptEvent args) { if (args.Cancelled) @@ -92,11 +99,11 @@ private void OnInsertAttempt(Entity ent, ref Contain return; // Check for living things, they should not insert when anchored. - if (!HasComp(args.EntityUid) && !HasComp(args.EntityUid)) - return; + // if (!HasComp(args.EntityUid) && !HasComp(args.EntityUid)) /// Forge-Change-Del + // return; /// Forge-Change-Del - if (Transform(ent.Owner).Anchored) - args.Cancel(); + // if (Transform(ent.Owner).Anchored) /// Forge-Change-Del + // args.Cancel(); /// Forge-Change-Del } [PublicAPI] diff --git a/Content.Shared/_NF/Storage/AnchorableStorageVisuals.cs b/Content.Shared/_NF/Storage/AnchorableStorageVisuals.cs index c94784bc3d8..0c1af27a149 100644 --- a/Content.Shared/_NF/Storage/AnchorableStorageVisuals.cs +++ b/Content.Shared/_NF/Storage/AnchorableStorageVisuals.cs @@ -1,3 +1,4 @@ +/// Forge-Change-Start using Robust.Shared.Serialization; namespace Content.Shared._NF.Storage; @@ -8,3 +9,4 @@ public enum AnchorableStorageVisuals : byte Anchored, Layer, } +/// Forge-Change-End From 2ba5b8b685438f126298e722ee8dfc03e49edf2a Mon Sep 17 00:00:00 2001 From: gordod3 Date: Fri, 17 Jul 2026 01:00:11 +0600 Subject: [PATCH 3/3] Added missing # Forge-Change --- .../_NF/Entities/Clothing/Back/base_clothing_backpack.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Resources/Prototypes/_NF/Entities/Clothing/Back/base_clothing_backpack.yml b/Resources/Prototypes/_NF/Entities/Clothing/Back/base_clothing_backpack.yml index f4a536f1311..7bd76e089d6 100644 --- a/Resources/Prototypes/_NF/Entities/Clothing/Back/base_clothing_backpack.yml +++ b/Resources/Prototypes/_NF/Entities/Clothing/Back/base_clothing_backpack.yml @@ -3,6 +3,7 @@ abstract: true id: NFBackpackHiddenStash components: + # Forge-Change-Start - type: Sprite layers: - state: icon @@ -15,6 +16,7 @@ False: { drawdepth: Items, visible: true } - type: Visibility layer: 1 + # Forge-Change-End - type: Appearance - type: SubFloorHide - type: Anchorable