OrbitVisualsSystem.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. using System.Numerics;
  2. using Content.Shared.Follower.Components;
  3. using Robust.Client.Animations;
  4. using Robust.Client.GameObjects;
  5. using Robust.Shared.Animations;
  6. using Robust.Shared.Random;
  7. using Robust.Shared.Timing;
  8. namespace Content.Client.Orbit;
  9. public sealed class OrbitVisualsSystem : EntitySystem
  10. {
  11. [Dependency] private readonly IRobustRandom _robustRandom = default!;
  12. [Dependency] private readonly AnimationPlayerSystem _animations = default!;
  13. [Dependency] private readonly IGameTiming _timing = default!;
  14. private readonly string _orbitStopKey = "orbiting_stop";
  15. public override void Initialize()
  16. {
  17. base.Initialize();
  18. SubscribeLocalEvent<OrbitVisualsComponent, ComponentInit>(OnComponentInit);
  19. SubscribeLocalEvent<OrbitVisualsComponent, ComponentRemove>(OnComponentRemove);
  20. }
  21. private void OnComponentInit(EntityUid uid, OrbitVisualsComponent component, ComponentInit args)
  22. {
  23. _robustRandom.SetSeed((int)_timing.CurTime.TotalMilliseconds);
  24. component.OrbitDistance =
  25. _robustRandom.NextFloat(0.75f * component.OrbitDistance, 1.25f * component.OrbitDistance);
  26. component.OrbitLength = _robustRandom.NextFloat(0.5f * component.OrbitLength, 1.5f * component.OrbitLength);
  27. if (TryComp<SpriteComponent>(uid, out var sprite))
  28. {
  29. sprite.EnableDirectionOverride = true;
  30. sprite.DirectionOverride = Direction.South;
  31. }
  32. var animationPlayer = EnsureComp<AnimationPlayerComponent>(uid);
  33. if (_animations.HasRunningAnimation(uid, animationPlayer, _orbitStopKey))
  34. {
  35. _animations.Stop((uid, animationPlayer), _orbitStopKey);
  36. }
  37. }
  38. private void OnComponentRemove(EntityUid uid, OrbitVisualsComponent component, ComponentRemove args)
  39. {
  40. if (!TryComp<SpriteComponent>(uid, out var sprite))
  41. return;
  42. sprite.EnableDirectionOverride = false;
  43. var animationPlayer = EnsureComp<AnimationPlayerComponent>(uid);
  44. if (!_animations.HasRunningAnimation(uid, animationPlayer, _orbitStopKey))
  45. {
  46. _animations.Play((uid, animationPlayer), GetStopAnimation(component, sprite), _orbitStopKey);
  47. }
  48. }
  49. public override void FrameUpdate(float frameTime)
  50. {
  51. base.FrameUpdate(frameTime);
  52. foreach (var (orbit, sprite) in EntityManager.EntityQuery<OrbitVisualsComponent, SpriteComponent>())
  53. {
  54. var progress = (float)(_timing.CurTime.TotalSeconds / orbit.OrbitLength) % 1;
  55. var angle = new Angle(Math.PI * 2 * progress);
  56. var vec = angle.RotateVec(new Vector2(orbit.OrbitDistance, 0));
  57. sprite.Rotation = angle;
  58. sprite.Offset = vec;
  59. }
  60. }
  61. private Animation GetStopAnimation(OrbitVisualsComponent component, SpriteComponent sprite)
  62. {
  63. var length = component.OrbitStopLength;
  64. return new Animation()
  65. {
  66. Length = TimeSpan.FromSeconds(length),
  67. AnimationTracks =
  68. {
  69. new AnimationTrackComponentProperty()
  70. {
  71. ComponentType = typeof(SpriteComponent),
  72. Property = nameof(SpriteComponent.Offset),
  73. KeyFrames =
  74. {
  75. new AnimationTrackProperty.KeyFrame(sprite.Offset, 0f),
  76. new AnimationTrackProperty.KeyFrame(Vector2.Zero, length),
  77. },
  78. InterpolationMode = AnimationInterpolationMode.Linear
  79. },
  80. new AnimationTrackComponentProperty()
  81. {
  82. ComponentType = typeof(SpriteComponent),
  83. Property = nameof(SpriteComponent.Rotation),
  84. KeyFrames =
  85. {
  86. new AnimationTrackProperty.KeyFrame(sprite.Rotation.Reduced(), 0f),
  87. new AnimationTrackProperty.KeyFrame(Angle.Zero, length),
  88. },
  89. InterpolationMode = AnimationInterpolationMode.Linear
  90. }
  91. }
  92. };
  93. }
  94. }