+++ /dev/null
-using Content.Shared.Power;
-using JetBrains.Annotations;
-using Robust.Client.GameObjects;
-using Robust.Shared.GameObjects;
-using Robust.Shared.IoC;
-
-namespace Content.Client.PowerCell
-{
- [UsedImplicitly]
- public sealed class PowerChargerVisualizer : AppearanceVisualizer
- {
- [Obsolete("Subscribe to your component being initialised instead.")]
- public override void InitializeEntity(EntityUid entity)
- {
- base.InitializeEntity(entity);
-
- var sprite = IoCManager.Resolve<IEntityManager>().GetComponent<SpriteComponent>(entity);
-
- // Base item
- sprite.LayerMapSet(Layers.Base, sprite.AddLayerState("empty"));
-
- // Light
- sprite.LayerMapSet(Layers.Light, sprite.AddLayerState("light-off"));
- sprite.LayerSetShader(Layers.Light, "unshaded");
- }
-
- [Obsolete("Subscribe to AppearanceChangeEvent instead.")]
- public override void OnChangeData(AppearanceComponent component)
- {
- base.OnChangeData(component);
-
- var sprite = IoCManager.Resolve<IEntityManager>().GetComponent<SpriteComponent>(component.Owner);
-
- // Update base item
- if (component.TryGetData(CellVisual.Occupied, out bool occupied))
- {
- // TODO: don't throw if it doesn't have a full state
- sprite.LayerSetState(Layers.Base, occupied ? "full" : "empty");
- }
- else
- {
- sprite.LayerSetState(Layers.Base, "empty");
- }
-
- // Update lighting
- if (component.TryGetData(CellVisual.Light, out CellChargerStatus status))
- {
- switch (status)
- {
- case CellChargerStatus.Off:
- sprite.LayerSetState(Layers.Light, "light-off");
- break;
- case CellChargerStatus.Empty:
- sprite.LayerSetState(Layers.Light, "light-empty");
- break;
- case CellChargerStatus.Charging:
- sprite.LayerSetState(Layers.Light, "light-charging");
- break;
- case CellChargerStatus.Charged:
- sprite.LayerSetState(Layers.Light, "light-charged");
- break;
- default:
- sprite.LayerSetState(Layers.Light, "light-off");
- break;
- }
- }
- else
- {
- sprite.LayerSetState(Layers.Light, "light-off");
- }
- }
-
- enum Layers : byte
- {
- Base,
- Light,
- }
- }
-}
--- /dev/null
+using Content.Shared.Power;
+
+namespace Content.Client.PowerCell;
+
+[RegisterComponent]
+[Access(typeof(PowerChargerVisualizerSystem))]
+public sealed class PowerChargerVisualsComponent : Component
+{
+ /// <summary>
+ /// The base sprite state used if the power cell charger does not contain a power cell.
+ /// </summary>
+ [DataField("emptyState")]
+ [ViewVariables(VVAccess.ReadWrite)]
+ public string EmptyState = "empty";
+
+ /// <summary>
+ /// The base sprite state used if the power cell charger contains a power cell.
+ /// </summary>
+ [DataField("occupiedState")]
+ [ViewVariables(VVAccess.ReadWrite)]
+ public string OccupiedState = "full";
+
+ /// <summary>
+ /// A mapping of the indicator light overlays for the power cell charger.
+ /// <see cref="CellChargerStatus.Off"/> Maps to the state used when the charger is out of power/disabled.
+ /// <see cref="CellChargerStatus.Empty"/> Maps to the state used when the charger does not contain a power cell.
+ /// <see cref="CellChargerStatus.Charging"/> Maps to the state used when the charger is charging a power cell.
+ /// <see cref="CellChargerStatus.Charged"/> Maps to the state used when the charger contains a fully charged power cell.
+ /// </summary>
+ [DataField("lightStates")]
+ [ViewVariables(VVAccess.ReadWrite)]
+ public readonly Dictionary<CellChargerStatus, string> LightStates = new()
+ {
+ [CellChargerStatus.Off] = "light-off",
+ [CellChargerStatus.Empty] = "light-empty",
+ [CellChargerStatus.Charging] = "light-charging",
+ [CellChargerStatus.Charged] = "light-charged",
+ };
+}
--- /dev/null
+using Content.Shared.Power;
+using Robust.Client.GameObjects;
+
+namespace Content.Client.PowerCell;
+
+public sealed class PowerChargerVisualizerSystem : VisualizerSystem<PowerChargerVisualsComponent>
+{
+ protected override void OnAppearanceChange(EntityUid uid, PowerChargerVisualsComponent comp, ref AppearanceChangeEvent args)
+ {
+ if (args.Sprite == null)
+ return;
+
+ // Update base item
+ if (AppearanceSystem.TryGetData<bool>(uid, CellVisual.Occupied, out var occupied, args.Component) && occupied)
+ {
+ // TODO: don't throw if it doesn't have a full state
+ args.Sprite.LayerSetState(PowerChargerVisualLayers.Base, comp.OccupiedState);
+ }
+ else
+ {
+ args.Sprite.LayerSetState(PowerChargerVisualLayers.Base, comp.EmptyState);
+ }
+
+ // Update lighting
+ if (AppearanceSystem.TryGetData<CellChargerStatus>(uid, CellVisual.Light, out var status, args.Component)
+ && comp.LightStates.TryGetValue(status, out var lightState))
+ {
+ args.Sprite.LayerSetState(PowerChargerVisualLayers.Light, lightState);
+ args.Sprite.LayerSetVisible(PowerChargerVisualLayers.Light, true);
+ }
+ else
+ //
+ args.Sprite.LayerSetVisible(PowerChargerVisualLayers.Light, false);
+ }
+}
+
+enum PowerChargerVisualLayers : byte
+{
+ Base,
+ Light,
+}
sprite: Structures/Power/cell_recharger.rsi
drawdepth: SmallObjects
snapCardinals: true
+ layers:
+ - map: ["enum.PowerChargerVisualLayers.Base"]
+ state: "empty"
+ - map: ["enum.PowerChargerVisualLayers.Light"]
+ state: "light-off"
+ shader: "unshaded"
- type: Charger
slotId: charger_slot
- type: ApcPowerReceiver
- type: ExtensionCableReceiver
- type: Appearance
- visuals:
- - type: PowerChargerVisualizer
+ - type: PowerChargerVisuals
- type: Anchorable
- type: Pullable
- type: Clickable