--- /dev/null
+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
+}
--- /dev/null
+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";
+}
+++ /dev/null
-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
- }
-}
}
}
- 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);
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)
/// <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);
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)
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
sprite: Objects/Specific/Medical/Morgue/bodybags.rsi
layers:
- state: bag
- map: ["unfoldedLayer"]
+ map: ["unfoldedLayer", "enum.StorageVisualLayers.Base"]
- state: bag_folded
map: ["foldedLayer"]
visible: false
components:
- Paper
- type: Appearance
- visuals:
- - type: StorageVisualizer
- state_open: open_overlay
+ - type: EntityStorageVisuals
+ stateDoorOpen: open_overlay
- type: GenericVisualizer
visuals:
enum.PaperLabelVisuals.HasLabel:
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:
snapCardinals: true
layers:
- state: fat
+ map: ["enum.StorageVisualLayers.Base"]
- state: fat_door_off
map: ["enum.StorageVisualLayers.Door"]
- state: fat_red
noRot: true
layers:
- state: generic
+ map: ["enum.StorageVisualLayers.Base"]
- state: generic_door
map: ["enum.StorageVisualLayers.Door"]
- state: locked
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
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
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
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
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
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
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
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
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: