]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Resolves StorageVisualizer is Obsolete (#13910)
authorTemporalOroboros <TemporalOroboros@gmail.com>
Thu, 18 May 2023 18:03:20 +0000 (11:03 -0700)
committerGitHub <noreply@github.com>
Thu, 18 May 2023 18:03:20 +0000 (14:03 -0400)
20 files changed:
Content.Client/Storage/Visualizers/EntityStorageVisualizerSystem.cs [new file with mode: 0644]
Content.Client/Storage/Visualizers/EntityStorageVisualsComponent.cs [new file with mode: 0644]
Content.Client/Storage/Visualizers/StorageVisualizer.cs [deleted file]
Content.Server/Storage/EntitySystems/EntityStorageSystem.cs
Content.Shared/Lock/LockSystem.cs
Content.Shared/Storage/EntitySystems/SharedEntityStorageSystem.cs
Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/box.yml
Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml
Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifact_equipment.yml
Resources/Prototypes/Entities/Structures/Machines/fatextractor.yml
Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/base_structurelockers.yml
Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml
Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml
Resources/Prototypes/Entities/Structures/Storage/Closets/big_boxes.yml
Resources/Prototypes/Entities/Structures/Storage/Closets/closets.yml
Resources/Prototypes/Entities/Structures/Storage/Closets/wall_lockers.yml
Resources/Prototypes/Entities/Structures/Storage/Closets/wardrobe.yml
Resources/Prototypes/Entities/Structures/Storage/Crates/base_structurecrates.yml
Resources/Prototypes/Entities/Structures/Storage/Crates/crates.yml
Resources/Prototypes/Entities/Structures/Storage/morgue.yml

diff --git a/Content.Client/Storage/Visualizers/EntityStorageVisualizerSystem.cs b/Content.Client/Storage/Visualizers/EntityStorageVisualizerSystem.cs
new file mode 100644 (file)
index 0000000..39a8f3d
--- /dev/null
@@ -0,0 +1,82 @@
+using Content.Shared.Storage;
+using Robust.Client.GameObjects;
+
+namespace Content.Client.Storage.Visualizers;
+
+public sealed class EntityStorageVisualizerSystem : VisualizerSystem<EntityStorageVisualsComponent>
+{
+    public override void Initialize()
+    {
+        base.Initialize();
+        SubscribeLocalEvent<EntityStorageVisualsComponent, ComponentInit>(OnComponentInit);
+    }
+
+    /// <summary>
+    /// Sets the base sprite to this layer. Exists to make the inheritance tree less boilerplate-y.
+    /// </summary>
+    private void OnComponentInit(EntityUid uid, EntityStorageVisualsComponent comp, ComponentInit args)
+    {
+        if (comp.StateBaseClosed == null)
+            return;
+
+        comp.StateBaseOpen ??= comp.StateBaseClosed;
+        if (!TryComp<SpriteComponent>(uid, out var sprite))
+            return;
+
+        sprite.LayerSetState(StorageVisualLayers.Base, comp.StateBaseClosed);
+    }
+
+    protected override void OnAppearanceChange(EntityUid uid, EntityStorageVisualsComponent comp, ref AppearanceChangeEvent args)
+    {
+        if (args.Sprite == null
+        || !AppearanceSystem.TryGetData<bool>(uid, StorageVisuals.Open, out var open, args.Component))
+            return;
+
+        // Open/Closed state for the storage entity.
+        if (args.Sprite.LayerMapTryGet(StorageVisualLayers.Door, out _))
+        {
+            if (open)
+            {
+                args.Sprite.LayerSetVisible(StorageVisualLayers.Door, true);
+                if (comp.StateDoorOpen != null)
+                    args.Sprite.LayerSetState(StorageVisualLayers.Door, comp.StateDoorOpen);
+
+                if (comp.StateBaseOpen != null)
+                    args.Sprite.LayerSetState(StorageVisualLayers.Base, comp.StateBaseOpen);
+            }
+            else
+            {
+                if (comp.StateDoorClosed != null)
+                {
+                    args.Sprite.LayerSetState(StorageVisualLayers.Door, comp.StateDoorClosed);
+                    args.Sprite.LayerSetVisible(StorageVisualLayers.Door, true);
+                }
+                else
+                    args.Sprite.LayerSetVisible(StorageVisualLayers.Door, false);
+
+                if (comp.StateBaseClosed != null)
+                    args.Sprite.LayerSetState(StorageVisualLayers.Base, comp.StateBaseClosed);
+            }
+        }
+
+        // Lock state for the storage entity. TODO: Split into its own visualizer.
+        if (AppearanceSystem.TryGetData<bool>(uid, StorageVisuals.CanLock, out var canLock, args.Component) && canLock)
+        {
+            if (!AppearanceSystem.TryGetData<bool>(uid, StorageVisuals.Locked, out var locked, args.Component))
+                locked = true;
+
+            args.Sprite.LayerSetVisible(StorageVisualLayers.Lock, !open);
+            if (!open)
+            {
+                args.Sprite.LayerSetState(StorageVisualLayers.Lock, locked ? comp.StateLocked : comp.StateUnlocked);
+            }
+        }
+    }
+}
+
+public enum StorageVisualLayers : byte
+{
+    Base,
+    Door,
+    Lock
+}
diff --git a/Content.Client/Storage/Visualizers/EntityStorageVisualsComponent.cs b/Content.Client/Storage/Visualizers/EntityStorageVisualsComponent.cs
new file mode 100644 (file)
index 0000000..c3e8e5d
--- /dev/null
@@ -0,0 +1,48 @@
+namespace Content.Client.Storage.Visualizers;
+
+[RegisterComponent]
+[Access(typeof(EntityStorageVisualizerSystem))]
+public sealed class EntityStorageVisualsComponent : Component
+{
+    /// <summary>
+    /// The RSI state used for the base layer of the storage entity sprite while the storage is closed.
+    /// </summary>
+    [DataField("stateBaseClosed")]
+    [ViewVariables(VVAccess.ReadWrite)]
+    public string? StateBaseClosed;
+
+    /// <summary>
+    /// The RSI state used for the base layer of the storage entity sprite while the storage is open.
+    /// </summary>
+    [DataField("stateBaseOpen")]
+    [ViewVariables(VVAccess.ReadWrite)]
+    public string? StateBaseOpen;
+
+    /// <summary>
+    /// The RSI state used for the door/lid while the storage is open.
+    /// </summary>
+    [DataField("stateDoorOpen")]
+    [ViewVariables(VVAccess.ReadWrite)]
+    public string? StateDoorOpen;
+
+    /// <summary>
+    /// The RSI state used for the door/lid while the storage is closed.
+    /// </summary>
+    [DataField("stateDoorClosed")]
+    [ViewVariables(VVAccess.ReadWrite)]
+    public string? StateDoorClosed;
+
+    /// <summary>
+    /// The RSI state used for the lock indicator while the storage is locked.
+    /// </summary>
+    [DataField("stateLocked")]
+    [ViewVariables(VVAccess.ReadWrite)]
+    public string? StateLocked = "locked";
+
+    /// <summary>
+    /// The RSI state used for the lock indicator while the storage is unlocked.
+    /// </summary>
+    [DataField("stateUnlocked")]
+    [ViewVariables(VVAccess.ReadWrite)]
+    public string? StateUnlocked = "unlocked";
+}
diff --git a/Content.Client/Storage/Visualizers/StorageVisualizer.cs b/Content.Client/Storage/Visualizers/StorageVisualizer.cs
deleted file mode 100644 (file)
index 44fe352..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-using Content.Shared.Storage;
-using JetBrains.Annotations;
-using Robust.Client.GameObjects;
-using Robust.Shared.GameObjects;
-using Robust.Shared.IoC;
-using Robust.Shared.Serialization.Manager.Attributes;
-
-namespace Content.Client.Storage.Visualizers
-{
-    [UsedImplicitly]
-    public sealed class StorageVisualizer : AppearanceVisualizer
-    {
-        /// <summary>
-        /// Sets the base sprite to this layer. Exists to make the inheritance tree less boilerplate-y.
-        /// </summary>
-        [DataField("state")]
-        private string? _stateBase;
-        [DataField("state_alt")]
-        private string? _stateBaseAlt;
-        [DataField("state_open")]
-        private string? _stateOpen;
-        [DataField("state_closed")]
-        private string? _stateClosed;
-
-        [Obsolete("Subscribe to your component being initialised instead.")]
-        public override void InitializeEntity(EntityUid entity)
-        {
-            if (!IoCManager.Resolve<IEntityManager>().TryGetComponent(entity, out SpriteComponent? sprite))
-            {
-                return;
-            }
-
-            if (_stateBase != null)
-            {
-                sprite.LayerSetState(0, _stateBase);
-            }
-
-            if (_stateBaseAlt == null)
-            {
-                _stateBaseAlt = _stateBase;
-            }
-        }
-
-        [Obsolete("Subscribe to AppearanceChangeEvent instead.")]
-        public override void OnChangeData(AppearanceComponent component)
-        {
-            base.OnChangeData(component);
-
-            var entities = IoCManager.Resolve<IEntityManager>();
-            if (!entities.TryGetComponent(component.Owner, out SpriteComponent? sprite))
-            {
-                return;
-            }
-
-            component.TryGetData(StorageVisuals.Open, out bool open);
-
-            if (sprite.LayerMapTryGet(StorageVisualLayers.Door, out _))
-            {
-                sprite.LayerSetVisible(StorageVisualLayers.Door, true);
-
-                if (open)
-                {
-                    if (_stateOpen != null)
-                    {
-                        sprite.LayerSetState(StorageVisualLayers.Door, _stateOpen);
-                        sprite.LayerSetVisible(StorageVisualLayers.Door, true);
-                    }
-
-                    if (_stateBaseAlt != null)
-                        sprite.LayerSetState(0, _stateBaseAlt);
-                }
-                else if (!open)
-                {
-                    if (_stateClosed != null)
-                        sprite.LayerSetState(StorageVisualLayers.Door, _stateClosed);
-                    else
-                    {
-                        sprite.LayerSetVisible(StorageVisualLayers.Door, false);
-                    }
-
-                    if (_stateBase != null)
-                        sprite.LayerSetState(0, _stateBase);
-                }
-                else
-                {
-                    sprite.LayerSetVisible(StorageVisualLayers.Door, false);
-                }
-            }
-
-            if (component.TryGetData(StorageVisuals.CanLock, out bool canLock) && canLock)
-            {
-                if (!component.TryGetData(StorageVisuals.Locked, out bool locked))
-                {
-                    locked = true;
-                }
-
-                sprite.LayerSetVisible(StorageVisualLayers.Lock, !open);
-                if (!open)
-                {
-                    sprite.LayerSetState(StorageVisualLayers.Lock, locked ? "locked" : "unlocked");
-                }
-            }
-        }
-    }
-
-    public enum StorageVisualLayers : byte
-    {
-        Door,
-        Lock
-    }
-}
index 509dec8a3d1026cd59323e26789c5abf98702dc9..a9866e73a2af4af78e4111d5d7066c4d26aae803 100644 (file)
@@ -41,9 +41,9 @@ public sealed class EntityStorageSystem : SharedEntityStorageSystem
         }
     }
 
-    protected override void OnInit(EntityUid uid, SharedEntityStorageComponent component, ComponentInit args)
+    protected override void OnComponentInit(EntityUid uid, SharedEntityStorageComponent component, ComponentInit args)
     {
-        base.OnInit(uid, component, args);
+        base.OnComponentInit(uid, component, args);
 
         if (TryComp<ConstructionComponent>(uid, out var construction))
             _construction.AddContainer(uid, ContainerName, construction);
index 79a0e26fbdee83491470a82e9d97ccadcc49fb55..3c0f6560da58325497738e253ac2579d5f9b8d12 100644 (file)
@@ -62,6 +62,7 @@ public sealed class LockSystem : EntitySystem
     private void OnStartup(EntityUid uid, LockComponent lockComp, ComponentStartup args)
     {
         _appearanceSystem.SetData(uid, StorageVisuals.CanLock, true);
+        _appearanceSystem.SetData(uid, StorageVisuals.Locked, lockComp.Locked);
     }
 
     private void OnActivated(EntityUid uid, LockComponent lockComp, ActivateInWorldEvent args)
index 7b17cf4b7eb9670072bd395ada307331912dd142..abcaec6cb6529227d727be81868a68bee5c5ad67 100644 (file)
@@ -43,8 +43,9 @@ public abstract class SharedEntityStorageSystem : EntitySystem
     /// <inheritdoc/>
     public override void Initialize()
     {
-        SubscribeLocalEvent<SharedEntityStorageComponent, ComponentInit>(OnInit);
-        SubscribeLocalEvent<SharedEntityStorageComponent, ActivateInWorldEvent>(OnInteract, after: new[]{typeof(LockSystem)});
+        SubscribeLocalEvent<SharedEntityStorageComponent, ComponentInit>(OnComponentInit);
+        SubscribeLocalEvent<SharedEntityStorageComponent, ComponentStartup>(OnComponentStartup);
+        SubscribeLocalEvent<SharedEntityStorageComponent, ActivateInWorldEvent>(OnInteract, after: new[] { typeof(LockSystem) });
         SubscribeLocalEvent<SharedEntityStorageComponent, LockToggleAttemptEvent>(OnLockToggleAttempt);
         SubscribeLocalEvent<SharedEntityStorageComponent, DestructionEventArgs>(OnDestruction);
         SubscribeLocalEvent<SharedEntityStorageComponent, GetVerbsEvent<InteractionVerb>>(AddToggleOpenVerb);
@@ -76,13 +77,18 @@ public abstract class SharedEntityStorageSystem : EntitySystem
         component.IsWeldedShut = state.IsWeldedShut;
     }
 
-    protected virtual void OnInit(EntityUid uid, SharedEntityStorageComponent component, ComponentInit args)
+    protected virtual void OnComponentInit(EntityUid uid, SharedEntityStorageComponent component, ComponentInit args)
     {
         component.Contents = _container.EnsureContainer<Container>(uid, ContainerName);
         component.Contents.ShowContents = component.ShowContents;
         component.Contents.OccludesLight = component.OccludesLight;
     }
 
+    protected virtual void OnComponentStartup(EntityUid uid, SharedEntityStorageComponent component, ComponentStartup args)
+    {
+        _appearance.SetData(uid, StorageVisuals.Open, component.Open);
+    }
+
     private void OnInteract(EntityUid uid, SharedEntityStorageComponent component, ActivateInWorldEvent args)
     {
         if (args.Handled)
index 2a52127b3bebbc73dbdd6d47c9701746108aad55..4982eb8e2d53e96d53511e720f3dcf6630e122fe 100644 (file)
     drawdepth: SmallObjects
     layers:
     - state: box
+      map: ["enum.StorageVisualLayers.Base"]
     - state: box-open
       map: ["enum.StorageVisualLayers.Door"]
     netsync: false
     sprite: Objects/Consumable/Food/Baked/pizza.rsi
     heldPrefix: box
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state_open: box-open
-      state_closed: box
+  - type: EntityStorageVisuals
+    stateDoorOpen: box-open
+    stateDoorClosed: box
   - type: StaticPrice
     price: 0
 
index a4b6ea99295250feffb1b47551e22d41e061046d..74d53e078f467eb72364ddf27191da84aecbd24f 100644 (file)
@@ -12,7 +12,7 @@
     sprite: Objects/Specific/Medical/Morgue/bodybags.rsi
     layers:
     - state: bag
-      map: ["unfoldedLayer"]
+      map: ["unfoldedLayer", "enum.StorageVisualLayers.Base"]
     - state: bag_folded
       map: ["foldedLayer"]
       visible: false
@@ -58,9 +58,8 @@
         components:
         - Paper
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state_open: open_overlay
+  - type: EntityStorageVisuals
+    stateDoorOpen: open_overlay
   - type: GenericVisualizer
     visuals:
       enum.PaperLabelVisuals.HasLabel:
index 6b06a0be90aa47900fa53c8366f3993e1ace4466..0b0e4e265cf7f5f57ee2166f92cbd78f45fd01aa 100644 (file)
       drawdepth: Objects
       sprite: Structures/Storage/Crates/artifact.rsi
       layers:
-        - state: artifact_container
-        - state: artifact_container_door
-          map: ["enum.StorageVisualLayers.Door"]
-        - state: welded
-          visible: false
-          map: ["enum.WeldableLayers.BaseWelded"]
-        - state: locked
-          map: ["enum.StorageVisualLayers.Lock"]
-          shader: unshaded
+      - state: artifact_container
+        map: ["enum.StorageVisualLayers.Base"]
+      - state: artifact_container_door
+        map: ["enum.StorageVisualLayers.Door"]
+      - state: welded
+        visible: false
+        map: ["enum.WeldableLayers.BaseWelded"]
+      - state: locked
+        map: ["enum.StorageVisualLayers.Lock"]
+        shader: unshaded
     - type: InteractionOutline
     - type: Physics
     - type: Fixtures
           components:
             - Paper
     - type: Appearance
-      visuals:
-        - type: StorageVisualizer
-          state_open: artifact_container_open
-          state_closed: artifact_container_door
+    - type: EntityStorageVisuals
+      stateDoorOpen: artifact_container_open
+      stateDoorClosed: artifact_container_door
     - type: ItemSlots
     - type: ContainerContainer
       containers:
index 3914f5e5e26264d69da55cdc7802565955648422..aeaedb0f6b92cbfde20066ec535fbdf5c3ce539a 100644 (file)
@@ -16,6 +16,7 @@
     snapCardinals: true
     layers:
     - state: fat
+      map: ["enum.StorageVisualLayers.Base"]
     - state: fat_door_off
       map: ["enum.StorageVisualLayers.Door"]
     - state: fat_red
index 5266cc8ae00f3693f563a5ec54fbba87101329b3..145a587208cebdbe36e41e5639a5b4011761a208 100644 (file)
@@ -11,6 +11,7 @@
     noRot: true
     layers:
     - state: generic
+      map: ["enum.StorageVisualLayers.Base"]
     - state: generic_door
       map: ["enum.StorageVisualLayers.Door"]
     - state: locked
index bc6e056e25892490b004abf1831dbfef38e3ee57..0a9037499a69580853f4e47106e3fd4eebe7e0dc 100644 (file)
@@ -5,11 +5,10 @@
   description: This is where the bartender keeps the booze.
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: cabinet
-      state_open: cabinet_open
-      state_closed: cabinet_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: cabinet
+    stateDoorOpen: cabinet_open
+    stateDoorClosed: cabinet_door
 
   - type: AccessReader
     access: [["Bar"]]
   name: quartermaster's locker
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: qm
-      state_open: qm_open
-      state_closed: qm_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: qm
+    stateDoorOpen: qm_open
+    stateDoorClosed: qm_door
   - type: AccessReader
     access: [["Quartermaster"]]
 
   description: Nevermind the pickaxe.
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: mining
-      state_open: mining_open
-      state_closed: mining_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: mining
+    stateDoorOpen: mining_open
+    stateDoorClosed: mining_door
   - type: AccessReader
     access: [["Salvage"]]
 
   name: captain's locker
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: cap
-      state_open: cap_open
-      state_closed: cap_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: cap
+    stateDoorOpen: cap_open
+    stateDoorClosed: cap_door
   - type: AccessReader
     access: [["Captain"]]
 
   name: head of personnel's locker
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: hop
-      state_open: hop_open
-      state_closed: hop_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: hop
+    stateDoorOpen: hop_open
+    stateDoorClosed: hop_door
   - type: AccessReader
     access: [["HeadOfPersonnel"]]
 
   name: chief engineer's locker
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: ce
-      state_open: ce_open
-      state_closed: ce_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: ce
+    stateDoorOpen: ce_open
+    stateDoorClosed: ce_door
   - type: AccessReader
     access: [ [ "ChiefEngineer" ] ]
 
   name: electrical supplies locker
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: eng
-      state_open: eng_open
-      state_closed: eng_elec_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: eng
+    stateDoorOpen: eng_open
+    stateDoorClosed: eng_elec_door
   - type: AccessReader
     access: [ [ "Engineering" ] ]
 
   name: welding supplies locker
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: eng
-      state_open: eng_open
-      state_closed: eng_weld_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: eng
+    stateDoorOpen: eng_open
+    stateDoorClosed: eng_weld_door
   - type: AccessReader
     access: [ [ "Engineering" ] ]
 
   name: atmospheric technician's locker
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: atmos
-      state_open: atmos_open
-      state_closed: atmos_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: atmos
+    stateDoorOpen: atmos_open
+    stateDoorClosed: atmos_door
   - type: AccessReader
     access: [ [ "Atmospherics" ] ]
 
   name: engineer's locker
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: eng_secure
-      state_open: eng_secure_open
-      state_closed: eng_secure_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: eng_secure
+    stateDoorOpen: eng_secure_open
+    stateDoorClosed: eng_secure_door
   - type: AccessReader
     access: [ [ "Engineering" ] ]
 
   name: freezer
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: freezer
-      state_open: freezer_open
-      state_closed: freezer_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: freezer
+    stateDoorOpen: freezer_open
+    stateDoorClosed: freezer_door
   - type: AccessReader
     access: [ [ "Kitchen" ] ]
   - type: ExplosionResistance
   name: botanist's locker
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: hydro
-      state_open: hydro_open
-      state_closed: hydro_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: hydro
+    stateDoorOpen: hydro_open
+    stateDoorClosed: hydro_door
   - type: AccessReader
     access: [ [ "Hydroponics" ] ]
 
   description: Filled to the brim with medical junk.
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: med
-      state_open: med_open
-      state_closed: med_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: med
+    stateDoorOpen: med_open
+    stateDoorClosed: med_door
   - type: AccessReader
     access: [ [ "Medical" ] ]
 
   name: medical doctor's locker
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: med_secure
-      state_open: med_secure_open
-      state_closed: med_secure_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: med_secure
+    stateDoorOpen: med_secure_open
+    stateDoorClosed: med_secure_door
   - type: AccessReader
     access: [ [ "Medical" ] ]
 
   name: paramedic's locker
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: paramed
-      state_open: paramed_open
-      state_closed: paramed_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: paramed
+    stateDoorOpen: paramed_open
+    stateDoorClosed: paramed_door
   - type: AccessReader
     access: [ [ "Medical" ] ]
 
   name: chemical locker
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: med
-      state_open: med_open
-      state_closed: chemical_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: med
+    stateDoorOpen: med_open
+    stateDoorClosed: chemical_door
   - type: AccessReader
     access: [ [ "Chemistry" ] ]
 
   name: chief medical officer's locker
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: cmo
-      state_open: cmo_open
-      state_closed: cmo_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: cmo
+    stateDoorOpen: cmo_open
+    stateDoorClosed: cmo_door
   - type: AccessReader
     access: [ [ "ChiefMedicalOfficer" ] ]
 
   name: research director's locker
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: rd
-      state_open: rd_open
-      state_closed: rd_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: rd
+    stateDoorOpen: rd_open
+    stateDoorClosed: rd_door
   - type: AccessReader
     access: [ [ "ResearchDirector" ] ]
 
   parent: LockerBase
   name: scientist's locker
   components:
-    - type: Appearance
-      visuals:
-        - type: StorageVisualizer
-          state: science
-          state_open: science_open
-          state_closed: science_door
-    - type: AccessReader
-      access: [ [ "Research" ] ]
+  - type: Appearance
+  - type: EntityStorageVisuals
+    stateBaseClosed: science
+    stateDoorOpen: science_open
+    stateDoorClosed: science_door
+  - type: AccessReader
+    access: [ [ "Research" ] ]
 
 # HoS
 - type: entity
   name: head of security's locker
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: hos
-      state_open: hos_open
-      state_closed: hos_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: hos
+    stateDoorOpen: hos_open
+    stateDoorClosed: hos_door
   - type: AccessReader
     access: [["HeadOfSecurity"]]
 
   name: warden's locker
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: warden
-      state_open: warden_open
-      state_closed: warden_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: warden
+    stateDoorOpen: warden_open
+    stateDoorClosed: warden_door
   - type: AccessReader
     access: [["Armory"]]
 
   name: brigmedic locker
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: brigmedic
-      state_open: armory_open
-      state_closed: brigmedic_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: brigmedic
+    stateDoorOpen: armory_open
+    stateDoorClosed: brigmedic_door
   - type: AccessReader
     access: [["Medical"]]
 
   name: security officer's locker
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: sec
-      state_open: sec_open
-      state_closed: sec_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: sec
+    stateDoorOpen: sec_open
+    stateDoorClosed: sec_door
   - type: AccessReader
     access: [["Security"]]
 
   name: gun safe
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: shotguncase
-      state_open: shotguncase_open
-      state_closed: shotguncase_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: shotguncase
+    stateDoorOpen: shotguncase_open
+    stateDoorClosed: shotguncase_door
   - type: AccessReader
     access: [["Armory"]]
 
   description: It's a personal storage unit for operative gear.
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: syndicate
-      state_open: syndicate_open
-      state_closed: syndicate_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: syndicate
+    stateDoorOpen: syndicate_open
+    stateDoorClosed: syndicate_door
 
 # Bluespace
 - type: entity
index 326572a3afe44bf25d62482b0f8c1b514026aa2e..3ed6aa27dcb5dd39f3a0d5e2966d8261fa3ed457 100644 (file)
@@ -13,6 +13,7 @@
     sprite: Structures/Storage/closet.rsi
     layers:
     - state: generic
+      map: ["enum.StorageVisualLayers.Base"]
     - state: generic_door
       map: ["enum.StorageVisualLayers.Door"]
     - state: welded
             min: 1
             max: 1
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: generic_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: generic_door
 
 #Wall Closet
 - type: entity
     sprite: Structures/Storage/wall_locker.rsi
     layers:
     - state: generic
+      map: ["enum.StorageVisualLayers.Base"]
     - state: generic_door
       map: ["enum.StorageVisualLayers.Door"]
     - state: welded
     sprite: Structures/Storage/wall_locker.rsi
     layers:
     - state: generic
+      map: ["enum.StorageVisualLayers.Base"]
     - state: generic_door
       map: ["enum.StorageVisualLayers.Door"]
     - state: locked
             min: 1
             max: 1
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: base
-      state_open: base 
-      state_closed: closed
+  - type: EntityStorageVisuals
+    stateBase: base
+    stateDoorOpen: base 
+    stateDoorClosed: closed
index 25d7b946e0224614bce7abc4f78795ddbcdee88c..b22288627ebe5abde1e46bb36504b84a280995b0 100644 (file)
       sprite: Structures/Storage/closet.rsi
       layers:
       - state: cardboard
+        map: ["enum.StorageVisualLayers.Base"]
       - state: cardboard_open
         map: ["enum.StorageVisualLayers.Door"]
     - type: Appearance
-      visuals:
-      - type: StorageVisualizer
-        state: cardboard
-        state_open: cardboard_open
+    - type: EntityStorageVisuals
+      stateBaseClosed: cardboard
+      stateDoorOpen: cardboard_open
     - type: Tag
       tags:
         - DoorBumpOpener
       noRot: true
       netsync: false
       layers:
-        - state: "cardboard_special"
+      - state: "cardboard_special"
     - type: TimedDespawn
       lifetime: 1
     - type: Tag
index 18b2a1ed3a18d40f79c3c3564f33fe99e4d9e6a2..c8136546eed5132397e11ebf51a7fad80bf61437 100644 (file)
@@ -6,11 +6,10 @@
   description: It's a storage unit for tools.
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: eng
-      state_open: eng_open
-      state_closed: eng_tool_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: eng
+    stateDoorOpen: eng_open
+    stateDoorClosed: eng_tool_door
 
 # Radiation suit closet
 - type: entity
   description: "More comfortable than radiation poisioning."
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: eng
-      state_open: eng_open
-      state_closed: eng_rad_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: eng
+    stateDoorOpen: eng_open
+    stateDoorClosed: eng_rad_door
 
 # Emergency closet
 - type: entity
   description: It's a storage unit for emergency breath masks and O2 tanks.
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: emergency
-      state_open: emergency_open
-      state_closed: emergency_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: emergency
+    stateDoorOpen: emergency_open
+    stateDoorClosed: emergency_door
 
 # Fire safety closet
 - type: entity
   description: It's a storage unit for fire-fighting supplies.
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: fire
-      state_open: fire_open
-      state_closed: fire_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: fire
+    stateDoorOpen: fire_open
+    stateDoorClosed: fire_door
 
 # EOD closet
 - type: entity
   description: It's a storage unit for explosion-protective suits.
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: bomb
-      state_open: bomb_open
-      state_closed: bomb_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: bomb
+    stateDoorOpen: bomb_open
+    stateDoorClosed: bomb_door
 
 # Biohazard
 
   description: It's a storage unit for level 3 biohazard gear.
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: bio
-      state_open: bio_open
-      state_closed: bio_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: bio
+    stateDoorOpen: bio_open
+    stateDoorClosed: bio_door
 
 # Virology variant
 - type: entity
   parent: ClosetL3
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: bio_viro
-      state_open: bio_viro_open
-      state_closed: bio_viro_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: bio_viro
+    stateDoorOpen: bio_viro_open
+    stateDoorClosed: bio_viro_door
 
 # Security variant
 - type: entity
   parent: ClosetL3
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: bio_sec
-      state_open: bio_sec_open
-      state_closed: bio_sec_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: bio_sec
+    stateDoorOpen: bio_sec_open
+    stateDoorClosed: bio_sec_door
 
 # Janitor variant
 - type: entity
   parent: ClosetL3
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: bio_jan
-      state_open: bio_jan_open
-      state_closed: bio_jan_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: bio_jan
+    stateDoorOpen: bio_jan_open
+    stateDoorClosed: bio_jan_door
 
 # Maintenance closet
 - type: entity
   parent: ClosetBase
   description: It's a storage unit.
   components:
-    - type: Appearance
-      visuals:
-        - type: StorageVisualizer
-          state_open: generic_open
-          state_closed: generic_door
+  - type: Appearance
+  - type: EntityStorageVisuals
+    stateDoorOpen: generic_open
+    stateDoorClosed: generic_door
 
 # Bluespace closet
 - type: entity
index 4000430b5e320d75d952daf9d16f04023b08bd4e..4280b960b4c38e2d647c9b639aafa95c29256dcb 100644 (file)
@@ -5,11 +5,10 @@
   description: It's a storage unit.
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: generic_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: generic_door
 
 - type: entity
   id: ClosetWallEmergency
   description: It's a storage unit for emergency breath masks and O2 tanks.
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: emergency
-      state_open: emergency_open
-      state_closed: emergency_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: emergency
+    stateDoorOpen: emergency_open
+    stateDoorClosed: emergency_door
 
 - type: entity
   id: ClosetWallFire
   description: It's a storage unit for fire-fighting supplies.
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: fire
-      state_open: fire_open
-      state_closed: fire_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: fire
+    stateDoorOpen: fire_open
+    stateDoorClosed: fire_door
 
 - type: entity
   id: ClosetWallBlue
   description: "A wardrobe packed with stylish blue clothing."
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: blue_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: blue_door
 
 - type: entity
   id: ClosetWallPink
   description: "A wardrobe packed with fabulous pink clothing."
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: pink_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: pink_door
 
 - type: entity
   id: ClosetWallBlack
   description: "A wardrobe packed with stylish black clothing."
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: black_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: black_door
 
 - type: entity
   id: ClosetWallGreen
   description: "A wardrobe packed with stylish green clothing."
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: green_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: green_door
 
 - type: entity
   id: ClosetWallOrange
   name: prison wall closet
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: orange_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: orange_door
 
 - type: entity
   id: ClosetWallYellow
   description: "A wardrobe packed with stylish yellow clothing."
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: yellow_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: yellow_door
 
 - type: entity
   id: ClosetWallWhite
   description: "A wardrobe packed with stylish white clothing."
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: white_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: white_door
 
 - type: entity
   id: ClosetWallGrey
   description: "A wardrobe packed with a tide of grey clothing."
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: gray_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: gray_door
 
 - type: entity
   id: ClosetWallMixed
   description: "A wardrobe packed with a mix of colorful clothing."
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: mixed_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: mixed_door
 
 - type: entity
   id: ClosetWallAtmospherics
   name: atmospherics wall closet
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: atmos_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: atmos_door
 
 - type: entity
   id: LockerWallMedical
   name: medical wall locker
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: med
-      state_open: med_open
-      state_closed: med_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: med
+    stateDoorOpen: med_open
+    stateDoorClosed: med_door
   - type: AccessReader
     access: [["Medical"]]
\ No newline at end of file
index e58d55547d1384d3366cce8012bb903849d7b956..01e8749d9f938fcaf809b5a98b6b803a62cc7143 100644 (file)
   description: "A wardrobe packed with stylish blue clothing."
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: blue_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: blue_door
 
 # Pink wardrobe
 - type: entity
   description: "A wardrobe packed with fabulous pink clothing."
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: pink_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: pink_door
 
 # Black wardrobe
 - type: entity
   description: "A wardrobe packed with stylish black clothing."
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: black_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: black_door
 
 # Green wardrobe
 - type: entity
   description: "A wardrobe packed with stylish green clothing."
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: green_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: green_door
 
 # Prison wardrobe
 - type: entity
   name: prison wardrobe
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: orange_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: orange_door
 
 # Yellow wardrobe
 - type: entity
   description: "A wardrobe packed with stylish yellow clothing."
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: yellow_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: yellow_door
 
 # White wardrobe
 - type: entity
   description: "A wardrobe packed with stylish white clothing."
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: white_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: white_door
 
 # Grey wardrobe
 - type: entity
   description: "A wardrobe packed with a tide of grey clothing."
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: grey_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: grey_door
 
 # Mixed wardrobe
 - type: entity
   description: "A wardrobe packed with a mix of colorful clothing."
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: mixed_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: mixed_door
 
 # Jobs
 
   name: security wardrobe
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: red_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: red_door
 
 - type: entity
   id: WardrobeAtmospherics
   name: atmospherics wardrobe
   components:
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: generic
-      state_open: generic_open
-      state_closed: atmos_wardrobe_door
+  - type: EntityStorageVisuals
+    stateBaseClosed: generic
+    stateDoorOpen: generic_open
+    stateDoorClosed: atmos_wardrobe_door
 
 - type: entity
   id: ClosetJanitor
index 1f253fe6f13a9395658867ecd16309be2ca6c3d7..e943b7e219dd588347f4fa5e620ca7bf1e63f025 100644 (file)
@@ -16,6 +16,7 @@
     sprite: Structures/Storage/Crates/generic.rsi
     layers:
     - state: base
+      map: ["enum.StorageVisualLayers.Base"]
     - state: closed
       map: ["enum.StorageVisualLayers.Door"]
     - state: welded
       - !type:DoActsBehavior
         acts: ["Destruction"]
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state_open: open
-      state_closed: closed
+  - type: EntityStorageVisuals
+    stateDoorOpen: open
+    stateDoorClosed: closed
   - type: PaperLabel
     labelSlot:
       insertVerbText: Attach Label
index 671ca28ee30d74c0becd73392468891ad10e1f46..e2065ee23fd62e00ada832d5bf2dd3c930f34cd8 100644 (file)
     sprite: Structures/Storage/Crates/piratechest.rsi
     layers:
     - state: crate
+      map: ["enum.StorageVisualLayers.Base"]
     - state: crate_door
       map: ["enum.StorageVisualLayers.Door"]
     - state: welded
     sprite: Structures/Storage/Crates/piratechest.rsi
     state: crate_icon
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state_open: crate_open
-      state_closed: crate_door
+  - type: EntityStorageVisuals
+    stateDoorOpen: crate_open
+    stateDoorClosed: crate_door
index f082615106f51574a796678a05ec215fd7b9a303..7052ffa815b417975832953eaa016791014f4c3d 100644 (file)
@@ -85,7 +85,7 @@
     sprite: Structures/Storage/morgue.rsi
     layers:
     - state: crema_closed
-      map: ["enum.CrematoriumVisualLayers.Base"]
+      map: ["enum.CrematoriumVisualLayers.Base", "enum.StorageVisualLayers.Base"]
     - state: crema_tray
       offset: 0, -1
       map: ["enum.StorageVisualLayers.Door"]
     containers:
       entity_storage: !type:Container
   - type: Appearance
-    visuals:
-    - type: StorageVisualizer
-      state: crema_closed
-      state_alt: crema_open
-      state_open: crema_tray
+  - type: EntityStorageVisuals
+    stateBaseClosed: crema_closed
+    stateBaseOpen: crema_open
+    stateDoorOpen: crema_tray
   - type: GenericVisualizer
     visuals:
       enum.CrematoriumVisuals.Burning: