LockVisualizer (#25224)
* LockVisualizer * Fix state * Clean some code * Make it component, fix tests fail * Fix for StateUnlocked Now it is possible to manually set the unlocked state and it will work! * Optimize LockVisualizer, add check for unlocked state * No todo I guess
38
Content.Client/Lock/Visualizers/LockVisualizerSystem.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using Content.Shared.Storage;
|
||||
using Content.Shared.Lock;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.Lock.Visualizers;
|
||||
|
||||
public sealed class LockVisualizerSystem : VisualizerSystem<LockVisualsComponent>
|
||||
{
|
||||
protected override void OnAppearanceChange(EntityUid uid, LockVisualsComponent comp, ref AppearanceChangeEvent args)
|
||||
{
|
||||
if (args.Sprite == null
|
||||
|| !AppearanceSystem.TryGetData<bool>(uid, LockVisuals.Locked, out _, args.Component))
|
||||
return;
|
||||
|
||||
// Lock state for the entity.
|
||||
if (!AppearanceSystem.TryGetData<bool>(uid, LockVisuals.Locked, out var locked, args.Component))
|
||||
locked = true;
|
||||
|
||||
var unlockedStateExist = args.Sprite.BaseRSI?.TryGetState(comp.StateUnlocked, out _);
|
||||
|
||||
if (AppearanceSystem.TryGetData<bool>(uid, StorageVisuals.Open, out var open, args.Component))
|
||||
{
|
||||
args.Sprite.LayerSetVisible(LockVisualLayers.Lock, !open);
|
||||
}
|
||||
else if (!(bool) unlockedStateExist!)
|
||||
args.Sprite.LayerSetVisible(LockVisualLayers.Lock, locked);
|
||||
|
||||
if (!open && (bool) unlockedStateExist!)
|
||||
{
|
||||
args.Sprite.LayerSetState(LockVisualLayers.Lock, locked ? comp.StateLocked : comp.StateUnlocked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum LockVisualLayers : byte
|
||||
{
|
||||
Lock
|
||||
}
|
||||
20
Content.Client/Lock/Visualizers/LockVisualsComponent.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
namespace Content.Client.Lock.Visualizers;
|
||||
|
||||
[RegisterComponent]
|
||||
[Access(typeof(LockVisualizerSystem))]
|
||||
public sealed partial class LockVisualsComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The RSI state used for the lock indicator while the entity is locked.
|
||||
/// </summary>
|
||||
[DataField("stateLocked")]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public string? StateLocked = "locked";
|
||||
|
||||
/// <summary>
|
||||
/// The RSI state used for the lock indicator entity is unlocked.
|
||||
/// </summary>
|
||||
[DataField("stateUnlocked")]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public string? StateUnlocked = "unlocked";
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
using Content.Client.Storage.Visualizers;
|
||||
using Content.Shared.Singularity.Components;
|
||||
using Content.Shared.Singularity.Components;
|
||||
using Content.Shared.Singularity.EntitySystems;
|
||||
using Content.Shared.Storage;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.Singularity.Systems;
|
||||
@@ -21,14 +19,6 @@ public sealed class EmitterSystem : SharedEmitterSystem
|
||||
if (args.Sprite == null)
|
||||
return;
|
||||
|
||||
if (args.Sprite.LayerMapTryGet(StorageVisualLayers.Lock, out var lockLayer))
|
||||
{
|
||||
if (!_appearance.TryGetData<bool>(uid, StorageVisuals.Locked, out var locked, args.Component))
|
||||
locked = false;
|
||||
|
||||
args.Sprite.LayerSetVisible(lockLayer, locked);
|
||||
}
|
||||
|
||||
if (!_appearance.TryGetData<EmitterVisualState>(uid, EmitterVisuals.VisualState, out var state, args.Component))
|
||||
state = EmitterVisualState.Off;
|
||||
|
||||
|
||||
@@ -70,25 +70,11 @@ public sealed class EntityStorageVisualizerSystem : VisualizerSystem<EntityStora
|
||||
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
|
||||
Door
|
||||
}
|
||||
|
||||
@@ -32,20 +32,6 @@ public sealed partial class EntityStorageVisualsComponent : Component
|
||||
[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";
|
||||
|
||||
/// <summary>
|
||||
/// The drawdepth the object has when it's open
|
||||
/// </summary>
|
||||
|
||||
@@ -17,7 +17,6 @@ using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Lock;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Player;
|
||||
@@ -54,7 +53,6 @@ public sealed class GasCanisterSystem : EntitySystem
|
||||
SubscribeLocalEvent<GasCanisterComponent, GasCanisterHoldingTankEjectMessage>(OnHoldingTankEjectMessage);
|
||||
SubscribeLocalEvent<GasCanisterComponent, GasCanisterChangeReleasePressureMessage>(OnCanisterChangeReleasePressure);
|
||||
SubscribeLocalEvent<GasCanisterComponent, GasCanisterChangeReleaseValveMessage>(OnCanisterChangeReleaseValve);
|
||||
SubscribeLocalEvent<GasCanisterComponent, LockToggledEvent>(OnLockToggled);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -78,11 +76,6 @@ public sealed class GasCanisterSystem : EntitySystem
|
||||
{
|
||||
// Ensure container
|
||||
_slots.AddItemSlot(uid, comp.ContainerName, comp.GasTankSlot);
|
||||
|
||||
if (TryComp<LockComponent>(uid, out var lockComp))
|
||||
{
|
||||
_appearance.SetData(uid, GasCanisterVisuals.Locked, lockComp.Locked);
|
||||
}
|
||||
}
|
||||
|
||||
private void DirtyUI(EntityUid uid,
|
||||
@@ -309,11 +302,6 @@ public sealed class GasCanisterSystem : EntitySystem
|
||||
args.GasMixtures = new Dictionary<string, GasMixture?> { {Name(uid), component.Air} };
|
||||
}
|
||||
|
||||
private void OnLockToggled(EntityUid uid, GasCanisterComponent component, ref LockToggledEvent args)
|
||||
{
|
||||
_appearance.SetData(uid, GasCanisterVisuals.Locked, args.Locked);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the canister is locked, playing its sound and popup if so.
|
||||
/// </summary>
|
||||
|
||||
@@ -21,8 +21,7 @@ namespace Content.Shared.Atmos.Piping.Binary.Components
|
||||
public enum GasCanisterVisuals
|
||||
{
|
||||
PressureState,
|
||||
TankInserted,
|
||||
Locked
|
||||
TankInserted
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -113,3 +113,10 @@ public sealed partial class UnlockDoAfter : DoAfterEvent
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
[NetSerializable]
|
||||
[Serializable]
|
||||
public enum LockVisuals : byte
|
||||
{
|
||||
Locked
|
||||
}
|
||||
|
||||
@@ -7,11 +7,9 @@ using Content.Shared.Hands.Components;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Storage;
|
||||
using Content.Shared.Storage.Components;
|
||||
using Content.Shared.Verbs;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -46,8 +44,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);
|
||||
_appearanceSystem.SetData(uid, LockVisuals.Locked, lockComp.Locked);
|
||||
}
|
||||
|
||||
private void OnActivated(EntityUid uid, LockComponent lockComp, ActivateInWorldEvent args)
|
||||
@@ -124,7 +121,7 @@ public sealed class LockSystem : EntitySystem
|
||||
_audio.PlayPredicted(lockComp.LockSound, uid, user);
|
||||
|
||||
lockComp.Locked = true;
|
||||
_appearanceSystem.SetData(uid, StorageVisuals.Locked, true);
|
||||
_appearanceSystem.SetData(uid, LockVisuals.Locked, true);
|
||||
Dirty(uid, lockComp);
|
||||
|
||||
var ev = new LockToggledEvent(true);
|
||||
@@ -155,7 +152,7 @@ public sealed class LockSystem : EntitySystem
|
||||
_audio.PlayPredicted(lockComp.UnlockSound, uid, user);
|
||||
|
||||
lockComp.Locked = false;
|
||||
_appearanceSystem.SetData(uid, StorageVisuals.Locked, false);
|
||||
_appearanceSystem.SetData(uid, LockVisuals.Locked, false);
|
||||
Dirty(uid, lockComp);
|
||||
|
||||
var ev = new LockToggledEvent(false);
|
||||
@@ -250,7 +247,7 @@ public sealed class LockSystem : EntitySystem
|
||||
if (!component.Locked || !component.BreakOnEmag)
|
||||
return;
|
||||
_audio.PlayPredicted(component.UnlockSound, uid, null);
|
||||
_appearanceSystem.SetData(uid, StorageVisuals.Locked, false);
|
||||
_appearanceSystem.SetData(uid, LockVisuals.Locked, false);
|
||||
RemComp<LockComponent>(uid); //Literally destroys the lock as a tell it was emagged
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Security
|
||||
{
|
||||
[Serializable, NetSerializable]
|
||||
public enum DeployableBarrierVisuals : byte
|
||||
{
|
||||
State
|
||||
}
|
||||
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum DeployableBarrierState : byte
|
||||
{
|
||||
Idle,
|
||||
Deployed
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ namespace Content.Shared.Security.Systems;
|
||||
|
||||
public sealed class DeployableBarrierSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly FixtureSystem _fixtures = default!;
|
||||
[Dependency] private readonly SharedPointLightSystem _pointLight = default!;
|
||||
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
||||
@@ -55,9 +54,6 @@ public sealed class DeployableBarrierSystem : EntitySystem
|
||||
_physics.SetHard(uid, fixture, false);
|
||||
}
|
||||
|
||||
var state = isDeployed ? DeployableBarrierState.Deployed : DeployableBarrierState.Idle;
|
||||
_appearance.SetData(uid, DeployableBarrierVisuals.State, state);
|
||||
|
||||
if (TryComp(uid, out SharedPullableComponent? pullable))
|
||||
_pulling.TryStopPull(pullable);
|
||||
|
||||
|
||||
@@ -207,8 +207,6 @@ namespace Content.Shared.Storage
|
||||
{
|
||||
Open,
|
||||
HasContents,
|
||||
CanLock,
|
||||
Locked,
|
||||
StorageUsed,
|
||||
Capacity
|
||||
}
|
||||
|
||||
@@ -10,15 +10,11 @@
|
||||
- type: Sprite
|
||||
sprite: Objects/Specific/Security/barrier.rsi
|
||||
layers:
|
||||
- state: "idle"
|
||||
map: ["deployableBarrierBase"]
|
||||
- state: idle
|
||||
- state: locked
|
||||
map: ["enum.LockVisualLayers.Lock"]
|
||||
- type: Appearance
|
||||
- type: GenericVisualizer
|
||||
visuals:
|
||||
enum.DeployableBarrierVisuals.State:
|
||||
deployableBarrierBase:
|
||||
enum.DeployableBarrierState.Idle: {state: "idle"}
|
||||
enum.DeployableBarrierState.Deployed: {state: "deployed"}
|
||||
- type: LockVisuals
|
||||
- type: InteractionOutline
|
||||
- type: Physics
|
||||
bodyType: Dynamic
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
visible: false
|
||||
map: ["enum.WeldableLayers.BaseWelded"]
|
||||
- state: locked
|
||||
map: ["enum.StorageVisualLayers.Lock"]
|
||||
map: ["enum.LockVisualLayers.Lock"]
|
||||
shader: unshaded
|
||||
- type: InteractionOutline
|
||||
- type: Physics
|
||||
@@ -73,6 +73,7 @@
|
||||
- type: EntityStorageVisuals
|
||||
stateDoorOpen: artifact_container_open
|
||||
stateDoorClosed: artifact_container_door
|
||||
- type: LockVisuals
|
||||
- type: ItemSlots
|
||||
- type: ContainerContainer
|
||||
containers:
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
- state: locked
|
||||
shader: unshaded
|
||||
visible: false
|
||||
map: ["enum.StorageVisualLayers.Lock"]
|
||||
map: ["enum.LockVisualLayers.Lock"]
|
||||
- type: Transform
|
||||
noRot: false
|
||||
- type: Fixtures
|
||||
@@ -203,6 +203,7 @@
|
||||
enum.PowerDeviceVisualLayers.Powered:
|
||||
True: { visible: true }
|
||||
False: { visible: false }
|
||||
- type: LockVisuals
|
||||
- type: DeviceNetwork
|
||||
deviceNetId: Wireless
|
||||
receiveFrequencyId: BasicDevice
|
||||
|
||||
@@ -31,10 +31,10 @@
|
||||
shader: unshaded
|
||||
visible: false
|
||||
map: ["enum.EmitterVisualLayers.Lights"]
|
||||
- state: lock
|
||||
- state: locked
|
||||
shader: unshaded
|
||||
visible: false
|
||||
map: ["enum.StorageVisualLayers.Lock"]
|
||||
map: ["enum.LockVisualLayers.Lock"]
|
||||
- type: Emitter
|
||||
- type: Gun
|
||||
showExamineText: false
|
||||
@@ -83,6 +83,7 @@
|
||||
- type: Appearance
|
||||
- type: Lock
|
||||
locked: false
|
||||
- type: LockVisuals
|
||||
- type: AccessReader
|
||||
access: [[ "Engineering" ]]
|
||||
- type: Machine
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
tankInserted:
|
||||
False: { state: can-open, visible: false }
|
||||
True: { state: can-open, visible: true }
|
||||
enum.GasCanisterVisuals.Locked:
|
||||
enum.LockVisuals.Locked:
|
||||
locked:
|
||||
False: { state: can-unlocked, shader: "unshaded" }
|
||||
True: { state: can-locked, shader: "unshaded" }
|
||||
False: { state: unlocked, shader: "unshaded" }
|
||||
True: { state: locked, shader: "unshaded" }
|
||||
enum.GasCanisterVisuals.PressureState:
|
||||
pressureLight:
|
||||
0: { state: can-o0, shader: "unshaded" }
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
components:
|
||||
- type: AccessReader
|
||||
- type: Lock
|
||||
- type: LockVisuals
|
||||
- type: Sprite
|
||||
sprite: Structures/Storage/closet.rsi
|
||||
noRot: true
|
||||
@@ -14,7 +15,7 @@
|
||||
- state: generic_door
|
||||
map: ["enum.StorageVisualLayers.Door"]
|
||||
- state: locked
|
||||
map: ["enum.StorageVisualLayers.Lock"]
|
||||
map: ["enum.LockVisualLayers.Lock"]
|
||||
shader: unshaded
|
||||
- state: welded
|
||||
visible: false
|
||||
|
||||
@@ -180,6 +180,7 @@
|
||||
components:
|
||||
- type: AccessReader
|
||||
- type: Lock
|
||||
- type: LockVisuals
|
||||
- type: Sprite
|
||||
sprite: Structures/Storage/wall_locker.rsi
|
||||
layers:
|
||||
@@ -188,7 +189,7 @@
|
||||
- state: generic_door
|
||||
map: ["enum.StorageVisualLayers.Door"]
|
||||
- state: locked
|
||||
map: ["enum.StorageVisualLayers.Lock"]
|
||||
map: ["enum.LockVisualLayers.Lock"]
|
||||
shader: unshaded
|
||||
- state: welded
|
||||
visible: false
|
||||
@@ -222,7 +223,7 @@
|
||||
visible: false
|
||||
map: ["enum.WeldableLayers.BaseWelded"]
|
||||
- state: locked
|
||||
map: ["enum.StorageVisualLayers.Lock"]
|
||||
map: ["enum.LockVisualLayers.Lock"]
|
||||
shader: unshaded
|
||||
- type: MovedByPressure
|
||||
- type: DamageOnHighSpeedImpact
|
||||
@@ -282,7 +283,6 @@
|
||||
- type: Appearance
|
||||
- type: EntityStorageVisuals
|
||||
stateBase: base
|
||||
stateLocked: locked
|
||||
stateUnlocked: unlocked
|
||||
stateDoorOpen: base
|
||||
stateDoorClosed: door
|
||||
- type: LockVisuals
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
id: CrateBaseSecure
|
||||
components:
|
||||
- type: Lock
|
||||
- type: LockVisuals
|
||||
- type: AccessReader
|
||||
- type: Icon
|
||||
sprite: Structures/Storage/Crates/secure.rsi
|
||||
@@ -101,7 +102,7 @@
|
||||
visible: false
|
||||
map: ["enum.WeldableLayers.BaseWelded"]
|
||||
- state: locked
|
||||
map: ["enum.StorageVisualLayers.Lock"]
|
||||
map: ["enum.LockVisualLayers.Lock"]
|
||||
shader: unshaded
|
||||
- type: Damageable
|
||||
damageContainer: StructuralInorganic
|
||||
|
||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
@@ -11,7 +11,7 @@
|
||||
"name": "idle"
|
||||
},
|
||||
{
|
||||
"name": "deployed",
|
||||
"name": "locked",
|
||||
"delays": [
|
||||
[
|
||||
0.1,
|
||||
|
||||
|
Before Width: | Height: | Size: 214 B After Width: | Height: | Size: 214 B |
@@ -34,7 +34,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "lock",
|
||||
"name": "locked",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
|
||||
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
@@ -23,10 +23,10 @@
|
||||
"name": "can-connector"
|
||||
},
|
||||
{
|
||||
"name": "can-locked"
|
||||
"name": "locked"
|
||||
},
|
||||
{
|
||||
"name": "can-unlocked"
|
||||
"name": "unlocked"
|
||||
},
|
||||
{
|
||||
"name": "can-o0",
|
||||
|
||||
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |