PoweredLightVisualizerSystem.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. using Content.Shared.Light;
  2. using Robust.Client.Animations;
  3. using Robust.Client.GameObjects;
  4. using Robust.Shared.Animations;
  5. using Robust.Shared.Audio;
  6. using Robust.Shared.Audio.Systems;
  7. using Robust.Shared.Random;
  8. namespace Content.Client.Light.Visualizers;
  9. public sealed class PoweredLightVisualizerSystem : VisualizerSystem<PoweredLightVisualsComponent>
  10. {
  11. [Dependency] private readonly IRobustRandom _random = default!;
  12. [Dependency] private readonly SharedAudioSystem _audio = default!;
  13. public override void Initialize()
  14. {
  15. base.Initialize();
  16. SubscribeLocalEvent<PoweredLightVisualsComponent, AnimationCompletedEvent>(OnAnimationCompleted);
  17. }
  18. protected override void OnAppearanceChange(EntityUid uid, PoweredLightVisualsComponent comp, ref AppearanceChangeEvent args)
  19. {
  20. if (args.Sprite == null)
  21. return;
  22. if (!AppearanceSystem.TryGetData<PoweredLightState>(uid, PoweredLightVisuals.BulbState, out var state, args.Component))
  23. return;
  24. if (comp.SpriteStateMap.TryGetValue(state, out var spriteState))
  25. args.Sprite.LayerSetState(PoweredLightLayers.Base, spriteState);
  26. if (args.Sprite.LayerExists(PoweredLightLayers.Glow))
  27. {
  28. if (TryComp<PointLightComponent>(uid, out var light))
  29. {
  30. args.Sprite.LayerSetColor(PoweredLightLayers.Glow, light.Color);
  31. }
  32. args.Sprite.LayerSetVisible(PoweredLightLayers.Glow, state == PoweredLightState.On);
  33. }
  34. SetBlinkingAnimation(
  35. uid,
  36. state == PoweredLightState.On
  37. && (AppearanceSystem.TryGetData<bool>(uid, PoweredLightVisuals.Blinking, out var isBlinking, args.Component) && isBlinking),
  38. comp
  39. );
  40. }
  41. /// <summary>
  42. /// Loops the blinking animation until the light should stop blinking.
  43. /// </summary>
  44. private void OnAnimationCompleted(EntityUid uid, PoweredLightVisualsComponent comp, AnimationCompletedEvent args)
  45. {
  46. if (args.Key != PoweredLightVisualsComponent.BlinkingAnimationKey)
  47. return;
  48. if(!comp.IsBlinking)
  49. return;
  50. AnimationSystem.Play(uid, Comp<AnimationPlayerComponent>(uid), BlinkingAnimation(comp), PoweredLightVisualsComponent.BlinkingAnimationKey);
  51. }
  52. /// <summary>
  53. /// Sets whether or not the given light should be blinking.
  54. /// Triggers or clears the blinking animation of the state changes.
  55. /// </summary>
  56. private void SetBlinkingAnimation(EntityUid uid, bool shouldBeBlinking, PoweredLightVisualsComponent comp)
  57. {
  58. if (shouldBeBlinking == comp.IsBlinking)
  59. return;
  60. comp.IsBlinking = shouldBeBlinking;
  61. var animationPlayer = EnsureComp<AnimationPlayerComponent>(uid);
  62. if (shouldBeBlinking)
  63. {
  64. AnimationSystem.Play(uid, animationPlayer, BlinkingAnimation(comp), PoweredLightVisualsComponent.BlinkingAnimationKey);
  65. }
  66. else if (AnimationSystem.HasRunningAnimation(uid, animationPlayer, PoweredLightVisualsComponent.BlinkingAnimationKey))
  67. {
  68. AnimationSystem.Stop(uid, animationPlayer, PoweredLightVisualsComponent.BlinkingAnimationKey);
  69. }
  70. }
  71. /// <summary>
  72. /// Generates a blinking animation.
  73. /// Essentially just flashes the light off and on over a random time interval.
  74. /// The resulting animation is looped indefinitely until the comp is set to stop blinking.
  75. /// </summary>
  76. private Animation BlinkingAnimation(PoweredLightVisualsComponent comp)
  77. {
  78. var randomTime = MathHelper.Lerp(comp.MinBlinkingAnimationCycleTime, comp.MaxBlinkingAnimationCycleTime, _random.NextFloat());
  79. var blinkingAnim = new Animation()
  80. {
  81. Length = TimeSpan.FromSeconds(randomTime),
  82. AnimationTracks =
  83. {
  84. new AnimationTrackComponentProperty
  85. {
  86. ComponentType = typeof(PointLightComponent),
  87. InterpolationMode = AnimationInterpolationMode.Nearest,
  88. Property = nameof(PointLightComponent.AnimatedEnable),
  89. KeyFrames =
  90. {
  91. new AnimationTrackProperty.KeyFrame(false, 0),
  92. new AnimationTrackProperty.KeyFrame(true, 1)
  93. }
  94. },
  95. new AnimationTrackSpriteFlick()
  96. {
  97. LayerKey = PoweredLightLayers.Base,
  98. KeyFrames =
  99. {
  100. new AnimationTrackSpriteFlick.KeyFrame(comp.SpriteStateMap[PoweredLightState.Off], 0),
  101. new AnimationTrackSpriteFlick.KeyFrame(comp.SpriteStateMap[PoweredLightState.On], 0.5f)
  102. }
  103. }
  104. }
  105. };
  106. if (comp.BlinkingSound != null)
  107. {
  108. var sound = _audio.ResolveSound(comp.BlinkingSound);
  109. blinkingAnim.AnimationTracks.Add(new AnimationTrackPlaySound()
  110. {
  111. KeyFrames =
  112. {
  113. new AnimationTrackPlaySound.KeyFrame(sound, 0.5f)
  114. }
  115. });
  116. }
  117. return blinkingAnim;
  118. }
  119. }