1
0

JukeboxSystem.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. using Content.Server.Power.Components;
  2. using Content.Server.Power.EntitySystems;
  3. using Content.Shared.Audio.Jukebox;
  4. using Content.Shared.Power;
  5. using Robust.Server.GameObjects;
  6. using Robust.Shared.Audio;
  7. using Robust.Shared.Audio.Components;
  8. using Robust.Shared.Audio.Systems;
  9. using Robust.Shared.Player;
  10. using Robust.Shared.Prototypes;
  11. using JukeboxComponent = Content.Shared.Audio.Jukebox.JukeboxComponent;
  12. namespace Content.Server.Audio.Jukebox;
  13. public sealed class JukeboxSystem : SharedJukeboxSystem
  14. {
  15. [Dependency] private readonly IPrototypeManager _protoManager = default!;
  16. [Dependency] private readonly AppearanceSystem _appearanceSystem = default!;
  17. public override void Initialize()
  18. {
  19. base.Initialize();
  20. SubscribeLocalEvent<JukeboxComponent, JukeboxSelectedMessage>(OnJukeboxSelected);
  21. SubscribeLocalEvent<JukeboxComponent, JukeboxPlayingMessage>(OnJukeboxPlay);
  22. SubscribeLocalEvent<JukeboxComponent, JukeboxPauseMessage>(OnJukeboxPause);
  23. SubscribeLocalEvent<JukeboxComponent, JukeboxStopMessage>(OnJukeboxStop);
  24. SubscribeLocalEvent<JukeboxComponent, JukeboxSetTimeMessage>(OnJukeboxSetTime);
  25. SubscribeLocalEvent<JukeboxComponent, ComponentInit>(OnComponentInit);
  26. SubscribeLocalEvent<JukeboxComponent, ComponentShutdown>(OnComponentShutdown);
  27. SubscribeLocalEvent<JukeboxComponent, PowerChangedEvent>(OnPowerChanged);
  28. }
  29. private void OnComponentInit(EntityUid uid, JukeboxComponent component, ComponentInit args)
  30. {
  31. if (HasComp<ApcPowerReceiverComponent>(uid))
  32. {
  33. TryUpdateVisualState(uid, component);
  34. }
  35. }
  36. private void OnJukeboxPlay(EntityUid uid, JukeboxComponent component, ref JukeboxPlayingMessage args)
  37. {
  38. if (Exists(component.AudioStream))
  39. {
  40. Audio.SetState(component.AudioStream, AudioState.Playing);
  41. }
  42. else
  43. {
  44. component.AudioStream = Audio.Stop(component.AudioStream);
  45. if (string.IsNullOrEmpty(component.SelectedSongId) ||
  46. !_protoManager.TryIndex(component.SelectedSongId, out var jukeboxProto))
  47. {
  48. return;
  49. }
  50. component.AudioStream = Audio.PlayPvs(jukeboxProto.Path, uid, AudioParams.Default.WithMaxDistance(10f))?.Entity;
  51. Dirty(uid, component);
  52. }
  53. }
  54. private void OnJukeboxPause(Entity<JukeboxComponent> ent, ref JukeboxPauseMessage args)
  55. {
  56. Audio.SetState(ent.Comp.AudioStream, AudioState.Paused);
  57. }
  58. private void OnJukeboxSetTime(EntityUid uid, JukeboxComponent component, JukeboxSetTimeMessage args)
  59. {
  60. if (TryComp(args.Actor, out ActorComponent? actorComp))
  61. {
  62. var offset = actorComp.PlayerSession.Channel.Ping * 1.5f / 1000f;
  63. Audio.SetPlaybackPosition(component.AudioStream, args.SongTime + offset);
  64. }
  65. }
  66. private void OnPowerChanged(Entity<JukeboxComponent> entity, ref PowerChangedEvent args)
  67. {
  68. TryUpdateVisualState(entity);
  69. if (!this.IsPowered(entity.Owner, EntityManager))
  70. {
  71. Stop(entity);
  72. }
  73. }
  74. private void OnJukeboxStop(Entity<JukeboxComponent> entity, ref JukeboxStopMessage args)
  75. {
  76. Stop(entity);
  77. }
  78. private void Stop(Entity<JukeboxComponent> entity)
  79. {
  80. Audio.SetState(entity.Comp.AudioStream, AudioState.Stopped);
  81. Dirty(entity);
  82. }
  83. private void OnJukeboxSelected(EntityUid uid, JukeboxComponent component, JukeboxSelectedMessage args)
  84. {
  85. if (!Audio.IsPlaying(component.AudioStream))
  86. {
  87. component.SelectedSongId = args.SongId;
  88. DirectSetVisualState(uid, JukeboxVisualState.Select);
  89. component.Selecting = true;
  90. component.AudioStream = Audio.Stop(component.AudioStream);
  91. }
  92. Dirty(uid, component);
  93. }
  94. public override void Update(float frameTime)
  95. {
  96. base.Update(frameTime);
  97. var query = EntityQueryEnumerator<JukeboxComponent>();
  98. while (query.MoveNext(out var uid, out var comp))
  99. {
  100. if (comp.Selecting)
  101. {
  102. comp.SelectAccumulator += frameTime;
  103. if (comp.SelectAccumulator >= 0.5f)
  104. {
  105. comp.SelectAccumulator = 0f;
  106. comp.Selecting = false;
  107. TryUpdateVisualState(uid, comp);
  108. }
  109. }
  110. }
  111. }
  112. private void OnComponentShutdown(EntityUid uid, JukeboxComponent component, ComponentShutdown args)
  113. {
  114. component.AudioStream = Audio.Stop(component.AudioStream);
  115. }
  116. private void DirectSetVisualState(EntityUid uid, JukeboxVisualState state)
  117. {
  118. _appearanceSystem.SetData(uid, JukeboxVisuals.VisualState, state);
  119. }
  120. private void TryUpdateVisualState(EntityUid uid, JukeboxComponent? jukeboxComponent = null)
  121. {
  122. if (!Resolve(uid, ref jukeboxComponent))
  123. return;
  124. var finalState = JukeboxVisualState.On;
  125. if (!this.IsPowered(uid, EntityManager))
  126. {
  127. finalState = JukeboxVisualState.Off;
  128. }
  129. _appearanceSystem.SetData(uid, JukeboxVisuals.VisualState, finalState);
  130. }
  131. }