From 2933f030d9f3ae0f6b0116e86cc0e563a32bf83a Mon Sep 17 00:00:00 2001
From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>
Date: Sun, 8 Jan 2023 22:42:31 -0500
Subject: [PATCH] emitter visuals update (#13382)
---
.../Singularity/Systems/EmitterSystem.cs | 59 +++++++
.../Visualizers/EmitterVisualizer.cs | 55 -------
.../Components/EmitterComponent.cs | 113 -------------
.../EntitySystems/EmitterSystem.cs | 4 +-
.../Components/SharedEmitterComponent.cs | 155 ++++++++++++++++--
.../EntitySystems/SharedEmitterSystem.cs | 6 +
.../Power/Generation/Singularity/emitter.yml | 4 +-
7 files changed, 210 insertions(+), 186 deletions(-)
create mode 100644 Content.Client/Singularity/Systems/EmitterSystem.cs
delete mode 100644 Content.Client/Singularity/Visualizers/EmitterVisualizer.cs
delete mode 100644 Content.Server/Singularity/Components/EmitterComponent.cs
create mode 100644 Content.Shared/Singularity/EntitySystems/SharedEmitterSystem.cs
diff --git a/Content.Client/Singularity/Systems/EmitterSystem.cs b/Content.Client/Singularity/Systems/EmitterSystem.cs
new file mode 100644
index 0000000000..599b133326
--- /dev/null
+++ b/Content.Client/Singularity/Systems/EmitterSystem.cs
@@ -0,0 +1,59 @@
+using Content.Client.Storage.Visualizers;
+using Content.Shared.Singularity.Components;
+using Content.Shared.Singularity.EntitySystems;
+using Content.Shared.Storage;
+using Robust.Client.GameObjects;
+
+namespace Content.Client.Singularity.Systems;
+
+public sealed class EmitterSystem : SharedEmitterSystem
+{
+ [Dependency] private readonly AppearanceSystem _appearance = default!;
+
+ ///
+ public override void Initialize()
+ {
+ SubscribeLocalEvent(OnAppearanceChange);
+ }
+
+ private void OnAppearanceChange(EntityUid uid, EmitterComponent component, ref AppearanceChangeEvent args)
+ {
+ if (args.Sprite == null)
+ return;
+
+ if (args.Sprite.LayerMapTryGet(StorageVisualLayers.Lock, out var lockLayer))
+ {
+ if (!_appearance.TryGetData(uid, StorageVisuals.Locked, out bool locked, args.Component))
+ locked = false;
+
+ args.Sprite.LayerSetVisible(lockLayer, locked);
+ }
+
+ if (!_appearance.TryGetData(uid, EmitterVisuals.VisualState, out EmitterVisualState state, args.Component))
+ state = EmitterVisualState.Off;
+
+ if (!args.Sprite.LayerMapTryGet(EmitterVisualLayers.Lights, out var layer))
+ return;
+
+ switch (state)
+ {
+ case EmitterVisualState.On:
+ if (component.OnState == null)
+ break;
+ args.Sprite.LayerSetVisible(layer, true);
+ args.Sprite.LayerSetState(layer, component.OnState);
+ break;
+ case EmitterVisualState.Underpowered:
+ if (component.UnderpoweredState == null)
+ break;
+ args.Sprite.LayerSetVisible(layer, true);
+ args.Sprite.LayerSetState(layer, component.UnderpoweredState);
+ break;
+ case EmitterVisualState.Off:
+ args.Sprite.LayerSetVisible(layer, false);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+}
diff --git a/Content.Client/Singularity/Visualizers/EmitterVisualizer.cs b/Content.Client/Singularity/Visualizers/EmitterVisualizer.cs
deleted file mode 100644
index f9c094641d..0000000000
--- a/Content.Client/Singularity/Visualizers/EmitterVisualizer.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-using System;
-using Content.Shared.Singularity.Components;
-using Content.Shared.Storage;
-using JetBrains.Annotations;
-using Robust.Client.GameObjects;
-using Robust.Shared.GameObjects;
-using Robust.Shared.IoC;
-
-namespace Content.Client.Singularity.Visualizers
-{
- [UsedImplicitly]
- public sealed class EmitterVisualizer : AppearanceVisualizer
- {
- private const string OverlayBeam = "beam";
- private const string OverlayUnderPowered = "underpowered";
-
- [Obsolete("Subscribe to AppearanceChangeEvent instead.")]
- public override void OnChangeData(AppearanceComponent component)
- {
- base.OnChangeData(component);
-
- var entities = IoCManager.Resolve();
- if (!entities.TryGetComponent(component.Owner, out ISpriteComponent? sprite))
- {
- return;
- }
-
- if (!component.TryGetData(StorageVisuals.Locked, out bool locked))
- locked = false;
-
-
- if (!component.TryGetData(EmitterVisuals.VisualState, out EmitterVisualState state))
- state = EmitterVisualState.Off;
-
- switch (state)
- {
- case EmitterVisualState.On:
- sprite.LayerSetVisible(1, true);
- sprite.LayerSetState(1, OverlayBeam);
- break;
- case EmitterVisualState.Underpowered:
- sprite.LayerSetVisible(1, true);
- sprite.LayerSetState(1, OverlayUnderPowered);
- break;
- case EmitterVisualState.Off:
- sprite.LayerSetVisible(1, false);
- break;
- default:
- throw new ArgumentOutOfRangeException();
- }
-
- sprite.LayerSetVisible(2, locked);
- }
- }
-}
diff --git a/Content.Server/Singularity/Components/EmitterComponent.cs b/Content.Server/Singularity/Components/EmitterComponent.cs
deleted file mode 100644
index 817725e5ec..0000000000
--- a/Content.Server/Singularity/Components/EmitterComponent.cs
+++ /dev/null
@@ -1,113 +0,0 @@
-using System.Threading;
-using Content.Shared.Construction.Prototypes;
-using Robust.Shared.Audio;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
-
-namespace Content.Server.Singularity.Components
-{
- [RegisterComponent]
- public sealed class EmitterComponent : Component
- {
- public CancellationTokenSource? TimerCancel;
-
- // whether the power switch is in "on"
- [ViewVariables] public bool IsOn;
- // Whether the power switch is on AND the machine has enough power (so is actively firing)
- [ViewVariables] public bool IsPowered;
-
- ///
- /// counts the number of consecutive shots fired.
- ///
- [ViewVariables]
- public int FireShotCounter;
-
- ///
- /// The entity that is spawned when the emitter fires.
- ///
- [DataField("boltType")]
- public string BoltType = "EmitterBolt";
-
- ///
- /// The current amount of power being used.
- ///
- [DataField("powerUseActive")]
- public int PowerUseActive = 600;
-
- ///
- /// The base amount of power that is consumed.
- /// Used in machine part rating calculations.
- ///
- [DataField("basePowerUseActive"), ViewVariables(VVAccess.ReadWrite)]
- public int BasePowerUseActive = 600;
-
- ///
- /// Multiplier that is applied to the basePowerUseActive
- /// to get the actual power use.
- ///
- [DataField("powerUseMultiplier")]
- public float PowerUseMultiplier = 0.75f;
-
- ///
- /// The machine part used to reduce the power use of the machine.
- ///
- [DataField("machinePartPowerUse", customTypeSerializer: typeof(PrototypeIdSerializer))]
- public string MachinePartPowerUse = "Capacitor";
-
- ///
- /// The amount of shots that are fired in a single "burst"
- ///
- [DataField("fireBurstSize")]
- public int FireBurstSize = 3;
-
- ///
- /// The time between each shot during a burst.
- ///
- [DataField("fireInterval")]
- public TimeSpan FireInterval = TimeSpan.FromSeconds(2);
-
- ///
- /// The base amount of time between each shot during a burst.
- ///
- [DataField("baseFireInterval"), ViewVariables(VVAccess.ReadWrite)]
- public TimeSpan BaseFireInterval = TimeSpan.FromSeconds(2);
-
- ///
- /// The current minimum delay between bursts.
- ///
- [DataField("fireBurstDelayMin")]
- public TimeSpan FireBurstDelayMin = TimeSpan.FromSeconds(4);
-
- ///
- /// The current maximum delay between bursts.
- ///
- [DataField("fireBurstDelayMax")]
- public TimeSpan FireBurstDelayMax = TimeSpan.FromSeconds(10);
-
- ///
- /// The base minimum delay between shot bursts.
- /// Used for machine part rating calculations.
- ///
- [DataField("baseFireBurstDelayMin")]
- public TimeSpan BaseFireBurstDelayMin = TimeSpan.FromSeconds(4);
-
- ///
- /// The base maximum delay between shot bursts.
- /// Used for machine part rating calculations.
- ///
- [DataField("baseFireBurstDelayMax")]
- public TimeSpan BaseFireBurstDelayMax = TimeSpan.FromSeconds(10);
-
- ///
- /// The multiplier for the base delay between shot bursts as well as
- /// the fire interval
- ///
- [DataField("fireRateMultiplier"), ViewVariables(VVAccess.ReadWrite)]
- public float FireRateMultiplier = 0.8f;
-
- ///
- /// The machine part that affects burst delay.
- ///
- [DataField("machinePartFireRate", customTypeSerializer: typeof(PrototypeIdSerializer))]
- public string MachinePartFireRate = "Laser";
- }
-}
diff --git a/Content.Server/Singularity/EntitySystems/EmitterSystem.cs b/Content.Server/Singularity/EntitySystems/EmitterSystem.cs
index 862c31f987..44986ab518 100644
--- a/Content.Server/Singularity/EntitySystems/EmitterSystem.cs
+++ b/Content.Server/Singularity/EntitySystems/EmitterSystem.cs
@@ -4,7 +4,6 @@ using Content.Server.Construction;
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Server.Projectiles;
-using Content.Server.Singularity.Components;
using Content.Server.Storage.Components;
using Content.Server.Weapons.Ranged.Systems;
using Content.Shared.Database;
@@ -12,6 +11,7 @@ using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.Projectiles;
using Content.Shared.Singularity.Components;
+using Content.Shared.Singularity.EntitySystems;
using Content.Shared.Weapons.Ranged.Components;
using JetBrains.Annotations;
using Robust.Shared.Map;
@@ -24,7 +24,7 @@ using Timer = Robust.Shared.Timing.Timer;
namespace Content.Server.Singularity.EntitySystems
{
[UsedImplicitly]
- public sealed class EmitterSystem : EntitySystem
+ public sealed class EmitterSystem : SharedEmitterSystem
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
diff --git a/Content.Shared/Singularity/Components/SharedEmitterComponent.cs b/Content.Shared/Singularity/Components/SharedEmitterComponent.cs
index 2fca9d4d0a..f2362cae85 100644
--- a/Content.Shared/Singularity/Components/SharedEmitterComponent.cs
+++ b/Content.Shared/Singularity/Components/SharedEmitterComponent.cs
@@ -1,18 +1,145 @@
-using Robust.Shared.Serialization;
+using System.Threading;
+using Content.Shared.Construction.Prototypes;
+using Robust.Shared.GameStates;
+using Robust.Shared.Serialization;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
-namespace Content.Shared.Singularity.Components
+namespace Content.Shared.Singularity.Components;
+
+[RegisterComponent, NetworkedComponent]
+public sealed class EmitterComponent : Component
{
- [NetSerializable, Serializable]
- public enum EmitterVisuals
- {
- VisualState
- }
+ public CancellationTokenSource? TimerCancel;
- [NetSerializable, Serializable]
- public enum EmitterVisualState
- {
- On,
- Underpowered,
- Off
- }
+ // whether the power switch is in "on"
+ [ViewVariables] public bool IsOn;
+ // Whether the power switch is on AND the machine has enough power (so is actively firing)
+ [ViewVariables] public bool IsPowered;
+
+ ///
+ /// counts the number of consecutive shots fired.
+ ///
+ [ViewVariables]
+ public int FireShotCounter;
+
+ ///
+ /// The entity that is spawned when the emitter fires.
+ ///
+ [DataField("boltType")]
+ public string BoltType = "EmitterBolt";
+
+ ///
+ /// The current amount of power being used.
+ ///
+ [DataField("powerUseActive")]
+ public int PowerUseActive = 600;
+
+ ///
+ /// The base amount of power that is consumed.
+ /// Used in machine part rating calculations.
+ ///
+ [DataField("basePowerUseActive"), ViewVariables(VVAccess.ReadWrite)]
+ public int BasePowerUseActive = 600;
+
+ ///
+ /// Multiplier that is applied to the basePowerUseActive
+ /// to get the actual power use.
+ ///
+ [DataField("powerUseMultiplier")]
+ public float PowerUseMultiplier = 0.75f;
+
+ ///
+ /// The machine part used to reduce the power use of the machine.
+ ///
+ [DataField("machinePartPowerUse", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string MachinePartPowerUse = "Capacitor";
+
+ ///
+ /// The amount of shots that are fired in a single "burst"
+ ///
+ [DataField("fireBurstSize")]
+ public int FireBurstSize = 3;
+
+ ///
+ /// The time between each shot during a burst.
+ ///
+ [DataField("fireInterval")]
+ public TimeSpan FireInterval = TimeSpan.FromSeconds(2);
+
+ ///
+ /// The base amount of time between each shot during a burst.
+ ///
+ [DataField("baseFireInterval"), ViewVariables(VVAccess.ReadWrite)]
+ public TimeSpan BaseFireInterval = TimeSpan.FromSeconds(2);
+
+ ///
+ /// The current minimum delay between bursts.
+ ///
+ [DataField("fireBurstDelayMin")]
+ public TimeSpan FireBurstDelayMin = TimeSpan.FromSeconds(4);
+
+ ///
+ /// The current maximum delay between bursts.
+ ///
+ [DataField("fireBurstDelayMax")]
+ public TimeSpan FireBurstDelayMax = TimeSpan.FromSeconds(10);
+
+ ///
+ /// The base minimum delay between shot bursts.
+ /// Used for machine part rating calculations.
+ ///
+ [DataField("baseFireBurstDelayMin")]
+ public TimeSpan BaseFireBurstDelayMin = TimeSpan.FromSeconds(4);
+
+ ///
+ /// The base maximum delay between shot bursts.
+ /// Used for machine part rating calculations.
+ ///
+ [DataField("baseFireBurstDelayMax")]
+ public TimeSpan BaseFireBurstDelayMax = TimeSpan.FromSeconds(10);
+
+ ///
+ /// The multiplier for the base delay between shot bursts as well as
+ /// the fire interval
+ ///
+ [DataField("fireRateMultiplier"), ViewVariables(VVAccess.ReadWrite)]
+ public float FireRateMultiplier = 0.8f;
+
+ ///
+ /// The machine part that affects burst delay.
+ ///
+ [DataField("machinePartFireRate", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string MachinePartFireRate = "Laser";
+
+ ///
+ /// The visual state that is set when the emitter is turned on
+ ///
+ [DataField("onState")]
+ public string? OnState = "beam";
+
+ ///
+ /// The visual state that is set when the emitter doesn't have enough power.
+ ///
+ [DataField("underpoweredState")]
+ public string? UnderpoweredState = "underpowered";
+}
+
+[NetSerializable, Serializable]
+public enum EmitterVisuals : byte
+{
+ VisualState
+}
+
+[Serializable, NetSerializable]
+public enum EmitterVisualLayers : byte
+{
+ Lights
+}
+
+[NetSerializable, Serializable]
+public enum EmitterVisualState
+{
+ On,
+ Underpowered,
+ Off
}
diff --git a/Content.Shared/Singularity/EntitySystems/SharedEmitterSystem.cs b/Content.Shared/Singularity/EntitySystems/SharedEmitterSystem.cs
new file mode 100644
index 0000000000..bba6629988
--- /dev/null
+++ b/Content.Shared/Singularity/EntitySystems/SharedEmitterSystem.cs
@@ -0,0 +1,6 @@
+namespace Content.Shared.Singularity.EntitySystems;
+
+public abstract class SharedEmitterSystem : EntitySystem
+{
+
+}
diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml
index 2838bc8eaa..0a7bffc42a 100644
--- a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml
+++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml
@@ -30,9 +30,11 @@
- state: beam
shader: unshaded
visible: false
+ map: ["enum.EmitterVisualLayers.Lights"]
- state: lock
shader: unshaded
visible: false
+ map: ["enum.StorageVisualLayers.Lock"]
- type: Emitter
- type: Gun
fireRate: 10 #just has to be fast enough to keep up with upgrades
@@ -72,8 +74,6 @@
- type: Pullable
- type: Rotatable
- type: Appearance
- visuals:
- - type: EmitterVisualizer
- type: Lock
locked: false
- type: AccessReader