]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Resolve PoweredLightVisualizer is Obsolete (#13891)
authorTemporalOroboros <TemporalOroboros@gmail.com>
Thu, 16 Feb 2023 04:10:41 +0000 (20:10 -0800)
committerGitHub <noreply@github.com>
Thu, 16 Feb 2023 04:10:41 +0000 (00:10 -0400)
Content.Client/Light/Visualizers/PoweredLightVisualizer.cs [deleted file]
Content.Client/Light/Visualizers/PoweredLightVisualizerSystem.cs [new file with mode: 0644]
Content.Client/Light/Visualizers/PoweredLightVisualsComponent.cs [new file with mode: 0644]
Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml
Resources/Prototypes/Entities/Structures/Lighting/ground_lighting.yml

diff --git a/Content.Client/Light/Visualizers/PoweredLightVisualizer.cs b/Content.Client/Light/Visualizers/PoweredLightVisualizer.cs
deleted file mode 100644 (file)
index cc40dd2..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-using Content.Shared.Light;
-using JetBrains.Annotations;
-using Robust.Client.Animations;
-using Robust.Client.GameObjects;
-using Robust.Shared.Animations;
-using Robust.Shared.Audio;
-using Robust.Shared.Random;
-
-namespace Content.Client.Light.Visualizers
-{
-    [UsedImplicitly]
-    public sealed class PoweredLightVisualizer : AppearanceVisualizer
-    {
-        [DataField("minBlinkingTime")] private float _minBlinkingTime = 0.5f;
-        [DataField("maxBlinkingTime")] private float _maxBlinkingTime = 2;
-        [DataField("blinkingSound")] private SoundSpecifier? _blinkingSound = default;
-
-        private bool _wasBlinking;
-
-        private Action<string>? _blinkingCallback;
-
-        [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;
-            if (!component.TryGetData(PoweredLightVisuals.BulbState, out PoweredLightState state)) return;
-
-            switch (state)
-            {
-                case PoweredLightState.Empty:
-                    sprite.LayerSetState(PoweredLightLayers.Base, "empty");
-                    ToggleBlinkingAnimation(component, false);
-                    break;
-                case PoweredLightState.Off:
-                    sprite.LayerSetState(PoweredLightLayers.Base, "off");
-                    ToggleBlinkingAnimation(component, false);
-                    break;
-                case PoweredLightState.On:
-                    if (component.TryGetData(PoweredLightVisuals.Blinking, out bool isBlinking))
-                        ToggleBlinkingAnimation(component, isBlinking);
-                    if (!isBlinking)
-                    {
-                        sprite.LayerSetState(PoweredLightLayers.Base, "on");
-                    }
-                    break;
-                case PoweredLightState.Broken:
-                    sprite.LayerSetState(PoweredLightLayers.Base, "broken");
-                    ToggleBlinkingAnimation(component, false);
-                    break;
-                case PoweredLightState.Burned:
-                    sprite.LayerSetState(PoweredLightLayers.Base, "burn");
-                    ToggleBlinkingAnimation(component, false);
-                    break;
-            }
-        }
-
-
-        private void ToggleBlinkingAnimation(AppearanceComponent component, bool isBlinking)
-        {
-            if (isBlinking == _wasBlinking)
-                return;
-            _wasBlinking = isBlinking;
-
-            component.Owner.EnsureComponent(out AnimationPlayerComponent animationPlayer);
-
-            if (isBlinking)
-            {
-                _blinkingCallback = (animName) => animationPlayer.Play(BlinkingAnimation(), "blinking");
-                animationPlayer.AnimationCompleted += _blinkingCallback;
-                animationPlayer.Play(BlinkingAnimation(), "blinking");
-            }
-            else if (animationPlayer.HasRunningAnimation("blinking"))
-            {
-                if (_blinkingCallback != null)
-                    animationPlayer.AnimationCompleted -= _blinkingCallback;
-                animationPlayer.Stop("blinking");
-            }
-        }
-
-        private Animation BlinkingAnimation()
-        {
-            var random = IoCManager.Resolve<IRobustRandom>();
-            var randomTime = random.NextFloat() *
-                (_maxBlinkingTime - _minBlinkingTime) + _minBlinkingTime;
-
-            var blinkingAnim = new Animation()
-            {
-                Length = TimeSpan.FromSeconds(randomTime),
-                AnimationTracks =
-                {
-                    new AnimationTrackComponentProperty
-                    {
-                        ComponentType = typeof(PointLightComponent),
-                        InterpolationMode = AnimationInterpolationMode.Nearest,
-                        Property = nameof(PointLightComponent.Enabled),
-                        KeyFrames =
-                        {
-                            new AnimationTrackProperty.KeyFrame(false, 0),
-                            new AnimationTrackProperty.KeyFrame(true, 1)
-                        }
-                    },
-                    new AnimationTrackSpriteFlick()
-                    {
-                        LayerKey = PoweredLightLayers.Base,
-                        KeyFrames =
-                        {
-                            new AnimationTrackSpriteFlick.KeyFrame("off", 0),
-                            new AnimationTrackSpriteFlick.KeyFrame("on", 0.5f)
-                        }
-                    }
-                }
-            };
-
-            if (_blinkingSound != null)
-            {
-                blinkingAnim.AnimationTracks.Add(new AnimationTrackPlaySound()
-                {
-                    KeyFrames =
-                {
-                    new AnimationTrackPlaySound.KeyFrame(_blinkingSound.GetSound(), 0.5f)
-                }
-                });
-            }
-
-            return blinkingAnim;
-        }
-    }
-}
diff --git a/Content.Client/Light/Visualizers/PoweredLightVisualizerSystem.cs b/Content.Client/Light/Visualizers/PoweredLightVisualizerSystem.cs
new file mode 100644 (file)
index 0000000..62af358
--- /dev/null
@@ -0,0 +1,125 @@
+using Content.Shared.Light;
+using Robust.Client.Animations;
+using Robust.Client.GameObjects;
+using Robust.Shared.Animations;
+using Robust.Shared.Random;
+
+namespace Content.Client.Light.Visualizers;
+
+public sealed class PoweredLightVisualizerSystem : VisualizerSystem<PoweredLightVisualsComponent>
+{
+    [Dependency] private readonly IRobustRandom _random = default!;
+    [Dependency] private readonly SharedAudioSystem _audio = default!;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+        SubscribeLocalEvent<PoweredLightVisualsComponent, AnimationCompletedEvent>(OnAnimationCompleted);
+    }
+
+    protected override void OnAppearanceChange(EntityUid uid, PoweredLightVisualsComponent comp, ref AppearanceChangeEvent args)
+    {
+        if (args.Sprite == null)
+            return;
+
+        if (!AppearanceSystem.TryGetData<PoweredLightState>(uid, PoweredLightVisuals.BulbState, out var state, args.Component))
+            return;
+
+        if (comp.SpriteStateMap.TryGetValue(state, out var spriteState))
+            args.Sprite.LayerSetState(PoweredLightLayers.Base, spriteState);
+
+        SetBlinkingAnimation(
+            uid,
+            state == PoweredLightState.On
+            && (AppearanceSystem.TryGetData<bool>(uid, PoweredLightVisuals.Blinking, out var isBlinking, args.Component) && isBlinking),
+            comp
+        );
+    }
+
+    /// <summary>
+    /// Loops the blinking animation until the light should stop blinking.
+    /// </summary>
+    private void OnAnimationCompleted(EntityUid uid, PoweredLightVisualsComponent comp, AnimationCompletedEvent args)
+    {
+        if (args.Key != PoweredLightVisualsComponent.BlinkingAnimationKey)
+            return;
+
+        if(!comp.IsBlinking)
+            return;
+
+        AnimationSystem.Play(uid, Comp<AnimationPlayerComponent>(uid), BlinkingAnimation(comp), PoweredLightVisualsComponent.BlinkingAnimationKey);
+    }
+
+    /// <summary>
+    /// Sets whether or not the given light should be blinking.
+    /// Triggers or clears the blinking animation of the state changes.
+    /// </summary>
+    private void SetBlinkingAnimation(EntityUid uid, bool shouldBeBlinking, PoweredLightVisualsComponent comp)
+    {
+        if (shouldBeBlinking == comp.IsBlinking)
+            return;
+
+        comp.IsBlinking = shouldBeBlinking;
+
+        var animationPlayer = EnsureComp<AnimationPlayerComponent>(uid);
+        if (shouldBeBlinking)
+        {
+            AnimationSystem.Play(uid, animationPlayer, BlinkingAnimation(comp), PoweredLightVisualsComponent.BlinkingAnimationKey);
+        }
+        else if (AnimationSystem.HasRunningAnimation(uid, animationPlayer, PoweredLightVisualsComponent.BlinkingAnimationKey))
+        {
+            AnimationSystem.Stop(uid, animationPlayer, PoweredLightVisualsComponent.BlinkingAnimationKey);
+        }
+    }
+
+    /// <summary>
+    /// Generates a blinking animation.
+    /// Essentially just flashes the light off and on over a random time interval.
+    /// The resulting animation is looped indefinitely until the comp is set to stop blinking.
+    /// </summary>
+    private Animation BlinkingAnimation(PoweredLightVisualsComponent comp)
+    {
+        var randomTime = MathHelper.Lerp(comp.MinBlinkingAnimationCycleTime, comp.MaxBlinkingAnimationCycleTime, _random.NextFloat());
+        var blinkingAnim = new Animation()
+        {
+            Length = TimeSpan.FromSeconds(randomTime),
+            AnimationTracks =
+            {
+                new AnimationTrackComponentProperty
+                {
+                    ComponentType = typeof(PointLightComponent),
+                    InterpolationMode = AnimationInterpolationMode.Nearest,
+                    Property = nameof(PointLightComponent.Enabled),
+                    KeyFrames =
+                    {
+                        new AnimationTrackProperty.KeyFrame(false, 0),
+                        new AnimationTrackProperty.KeyFrame(true, 1)
+                    }
+                },
+                new AnimationTrackSpriteFlick()
+                {
+                    LayerKey = PoweredLightLayers.Base,
+                    KeyFrames =
+                    {
+                        new AnimationTrackSpriteFlick.KeyFrame(comp.SpriteStateMap[PoweredLightState.Off], 0),
+                        new AnimationTrackSpriteFlick.KeyFrame(comp.SpriteStateMap[PoweredLightState.On], 0.5f)
+                    }
+                }
+            }
+        };
+
+        if (comp.BlinkingSound != null)
+        {
+            var sound = _audio.GetSound(comp.BlinkingSound);
+            blinkingAnim.AnimationTracks.Add(new AnimationTrackPlaySound()
+            {
+                KeyFrames =
+                {
+                    new AnimationTrackPlaySound.KeyFrame(sound, 0.5f)
+                }
+            });
+        }
+
+        return blinkingAnim;
+    }
+}
diff --git a/Content.Client/Light/Visualizers/PoweredLightVisualsComponent.cs b/Content.Client/Light/Visualizers/PoweredLightVisualsComponent.cs
new file mode 100644 (file)
index 0000000..6a1b4d7
--- /dev/null
@@ -0,0 +1,60 @@
+using Content.Shared.Light;
+using Robust.Shared.Audio;
+
+namespace Content.Client.Light.Visualizers;
+
+[RegisterComponent]
+[Access(typeof(PoweredLightVisualizerSystem))]
+public sealed class PoweredLightVisualsComponent : Component
+{
+    /// <summary>
+    /// A map of the sprite states used by this visualizer indexed by the light state they correspond to.
+    /// </summary>
+    [DataField("spriteStateMap")]
+    [ViewVariables(VVAccess.ReadOnly)]
+    public readonly Dictionary<PoweredLightState, string> SpriteStateMap = new()
+    {
+        [PoweredLightState.Empty] = "empty",
+        [PoweredLightState.Off] = "off",
+        [PoweredLightState.On] = "on",
+        [PoweredLightState.Broken] = "broken",
+        [PoweredLightState.Burned] = "burn",
+    };
+
+    #region Blinking
+
+    /// <summary>
+    /// The id used to track the blinking animation for lights.
+    /// </summary>
+    [ViewVariables(VVAccess.ReadOnly)]
+    public const string BlinkingAnimationKey = "poweredlight_blinking";
+
+    /// <summary>
+    /// The minimum length of the base blinking animation (one on-off-on cycle) in seconds.
+    /// </summary>
+    [DataField("minBlinkingTime")]
+    [ViewVariables(VVAccess.ReadWrite)]
+    public float MinBlinkingAnimationCycleTime = 0.5f;
+
+    /// <summary>
+    /// The maximum length of the base blinking animation (one on-off-on cycle) in seconds.
+    /// </summary>
+    [DataField("maxBlinkingTime")]
+    [ViewVariables(VVAccess.ReadWrite)]
+    public float MaxBlinkingAnimationCycleTime = 2;
+
+    /// <summary>
+    /// The sound that plays when the blinking animation cycles.
+    /// </summary>
+    [DataField("blinkingSound")]
+    [ViewVariables(VVAccess.ReadWrite)]
+    public SoundSpecifier? BlinkingSound = default;
+
+    /// <summary>
+    /// Whether or not this light is currently blinking.
+    /// </summary>
+    [ViewVariables(VVAccess.ReadWrite)]
+    public bool IsBlinking;
+
+    #endregion Blinking
+}
index baa2d7362a65dea04d5e99062066c9766b9136bc..6d5c0388116c8d82c53dc594be2fb452c2203f51 100644 (file)
     receiveFrequencyId: SmartLight
   - type: ApcNetworkConnection
   - type: Appearance
-    visuals:
-    - type: PoweredLightVisualizer
-      blinkingSound:
-        path: "/Audio/Machines/light_tube_on.ogg"
+  - type: PoweredLightVisuals
+    blinkingSound:
+      path: "/Audio/Machines/light_tube_on.ogg"
   - type: SignalReceiver
     inputs:
       On: []
     receiveFrequencyId: SmartLight
   - type: ApcNetworkConnection
   - type: Appearance
-    visuals:
-    - type: PoweredLightVisualizer
+  - type: PoweredLightVisuals
   - type: SignalReceiver
     inputs:
       On: []
index 3f8bbc0f994eedd3d070a27562177f8208105b68..5c506cc80227ed7abe91e03364cca139ebff685e 100644 (file)
     graph: LightFixture
     node: groundLight
   - type: Appearance
-    visuals:
-    - type: PoweredLightVisualizer
-      blinkingSound:
-        path: "/Audio/Machines/light_tube_on.ogg"
+  - type: PoweredLightVisuals
+    blinkingSound:
+      path: "/Audio/Machines/light_tube_on.ogg"
   - type: SignalReceiver
     inputs:
       On: []