diff --git a/Content.Server/SimpleStation14/Jukebox/JukeboxSystem.cs b/Content.Server/SimpleStation14/Jukebox/JukeboxSystem.cs
index b3d6ce620b..66b74c6f52 100644
--- a/Content.Server/SimpleStation14/Jukebox/JukeboxSystem.cs
+++ b/Content.Server/SimpleStation14/Jukebox/JukeboxSystem.cs
@@ -12,6 +12,8 @@
using Content.Server.DeviceLinking.Events;
using Content.Server.DeviceLinking.Systems;
using Robust.Shared.Random;
+using Content.Shared.Power;
+using System.Linq;
namespace Content.Server.SimpleStation14.Jukebox;
@@ -22,6 +24,7 @@ public sealed partial class JukeboxSystem : EntitySystem
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly UserInterfaceSystem _ui = default!;
[Dependency] private readonly DeviceLinkSystem _link = default!;
+ [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
public const string PortSongPlayed = "Start";
public const string PortSongStopped = "Timer";
@@ -94,7 +97,7 @@ public void TrySkipSong(EntityUid jukebox, JukeboxComponent? jukeboxComp = null)
if (!jukeboxComp.CanPlay)
return;
- End(jukebox, jukeboxComp);
+ EndTrack(jukebox, jukeboxComp);
if (jukeboxComp.NextUp.Count > 0)
{
@@ -113,7 +116,7 @@ public void TrySkipSong(EntityUid jukebox, JukeboxComponent? jukeboxComp = null)
/// Pauses the currently playing song and sets the Jukebox to a paused state.
///
///
- /// See to stop the Jukebox instead.
+ /// See to stop the Jukebox instead.
/// Pausing a Jukebox will allow it to remember its paused state, even if it gets stopped later.
///
public void DoPauseSong(EntityUid jukebox, JukeboxComponent? jukeboxComp = null)
@@ -126,7 +129,7 @@ public void DoPauseSong(EntityUid jukebox, JukeboxComponent? jukeboxComp = null)
jukeboxComp.Paused = true;
- Stop(jukebox, jukeboxComp);
+ StopSong(jukebox, jukeboxComp);
}
///
@@ -167,7 +170,7 @@ public void TryPlayRandomSong(EntityUid jukebox, JukeboxComponent? jukeboxComp =
if (!Resolve(jukebox, ref jukeboxComp))
return;
- var potentialSongs = jukeboxComp.Songs;
+ var potentialSongs = jukeboxComp.Songs.ToList();
if (jukeboxComp.Emagged)
potentialSongs.AddRange(jukeboxComp.EmaggedSongs);
@@ -264,31 +267,32 @@ private void CheckCanPlay(EntityUid uid, JukeboxComponent component)
if (canPlay)
TryRestart(uid, component);
else
- Stop(uid, component);
+ StopSong(uid, component);
}
///
/// Stops the currently playing song and sets the Jukebox to a stopped state.
///
///
+ /// This stops the song, but does not indicate that the user wants the song paused.
+ /// For instance, a power outage may stop the song from playing, but the user would want it to continue automatically when power comes back.
+ /// If the user pauses the song manually, they do not want a power outage to restart it.
/// See to pause the Jukebox instead.
///
- private void Stop(EntityUid jukeBox, JukeboxComponent jukeboxComp)
+ private void StopSong(EntityUid jukeBox, JukeboxComponent jukeboxComp)
{
if (!jukeboxComp.Playing)
return;
- jukeboxComp.Playing = false;
-
jukeboxComp.StoppedTime = _timing.CurTime;
Clean(jukeBox, jukeboxComp);
}
///
- /// Ends the currently playing song in the Jukebox.
+ /// Removes the track data from the Jukebox, and stops the song from playing.
///
- private void End(EntityUid jukeBox, JukeboxComponent jukeboxComp)
+ private void EndTrack(EntityUid jukeBox, JukeboxComponent jukeboxComp)
{
jukeboxComp.CurrentlyPlayingTrack = null;
@@ -304,7 +308,11 @@ private void End(EntityUid jukeBox, JukeboxComponent jukeboxComp)
///
/// Cleans up the active elements of a playing song.
///
- private void Clean(EntityUid jukeBox, JukeboxComponent jukeboxComp)
+ ///
+ /// Called either when a song is stopped, or when a song ends.
+ /// This does not modify the Jukebox's state, and should be called after the state has been updated.
+ ///
+ private void Clean(EntityUid jukebox, JukeboxComponent jukeboxComp)
{
if (jukeboxComp.CurrentlyPlayingStream != null)
{
@@ -312,7 +320,9 @@ private void Clean(EntityUid jukeBox, JukeboxComponent jukeboxComp)
jukeboxComp.CurrentlyPlayingStream = null;
}
- UpdateState(jukeBox, jukeboxComp);
+ jukeboxComp.Playing = false;
+
+ UpdateState(jukebox, jukeboxComp);
}
///
@@ -327,13 +337,8 @@ private void TryRestart(EntityUid jukeBox, JukeboxComponent jukeboxComp)
if (jukeboxComp.Paused || !jukeboxComp.CanPlay)
return;
- jukeboxComp.Playing = true;
-
if (jukeboxComp.CurrentlyPlayingTrack == null || jukeboxComp.FinishPlayingTime == null || jukeboxComp.StoppedTime == null)
- {
- UpdateState(jukeBox, jukeboxComp);
return;
- }
var timeLeftBeforeFinished = (TimeSpan) (jukeboxComp.CurrentlyPlayingTrack.Duration - (jukeboxComp.FinishPlayingTime - jukeboxComp.StoppedTime));
@@ -348,19 +353,21 @@ private void TryRestart(EntityUid jukeBox, JukeboxComponent jukeboxComp)
/// Updates the Jukebox's state and ui.
///
/// Whether or not to populate the song list in the ui.
- private void UpdateState(EntityUid jukeBox, JukeboxComponent jukeboxComp, bool populateSongs = false)
+ private void UpdateState(EntityUid jukebox, JukeboxComponent jukeboxComp, bool populateSongs = false)
{
Dirty(jukeboxComp);
- _ui.TrySendUiMessage(jukeBox, JukeboxUiKey.Key, new JukeboxUpdateStateMessage(populateSongs));
+ _appearance.SetData(jukebox, PowerDeviceVisuals.VisualState, jukeboxComp.Playing); // Set the Jukebox's playing animation if valid.
+
+ _ui.TrySendUiMessage(jukebox, JukeboxUiKey.Key, new JukeboxUpdateStateMessage(populateSongs));
}
///
/// Event handler for the song in the Jukebox reaching its end.
///
- private void OnSongEnd(EntityUid jukeBox, JukeboxComponent jukeboxComp)
+ private void OnSongEnd(EntityUid jukebox, JukeboxComponent jukeboxComp)
{
- TrySkipSong(jukeBox, jukeboxComp);
+ TrySkipSong(jukebox, jukeboxComp);
}
#endregion Private functions
diff --git a/Content.Server/SimpleStation14/Jukebox/JukeboxSystems.Interactions.cs b/Content.Server/SimpleStation14/Jukebox/JukeboxSystems.Interactions.cs
index b972db1d97..f8aedbf120 100644
--- a/Content.Server/SimpleStation14/Jukebox/JukeboxSystems.Interactions.cs
+++ b/Content.Server/SimpleStation14/Jukebox/JukeboxSystems.Interactions.cs
@@ -56,7 +56,7 @@ private void OnEmagged(EntityUid jukeBox, JukeboxComponent jukeboxComp, ref GotE
///
private void OnPaused(EntityUid jukeBox, JukeboxComponent jukeboxComp, ref EntityPausedEvent args)
{
- Stop(jukeBox, jukeboxComp);
+ StopSong(jukeBox, jukeboxComp);
}
///
diff --git a/Content.Shared/SimpleStation14/Jukebox/JukeboxComponent.cs b/Content.Shared/SimpleStation14/Jukebox/JukeboxComponent.cs
index 41acc78c77..1bb372bab3 100644
--- a/Content.Shared/SimpleStation14/Jukebox/JukeboxComponent.cs
+++ b/Content.Shared/SimpleStation14/Jukebox/JukeboxComponent.cs
@@ -118,7 +118,7 @@ public sealed partial class JukeboxComponent : Component
///
[AutoNetworkedField]
[ViewVariables(VVAccess.ReadOnly)]
- public bool Playing { get; set; } = true;
+ public bool Playing { get; set; } = false;
///
/// Whether or not the Jukebox is currently paused.
diff --git a/Content.Shared/SimpleStation14/Jukebox/JukeboxSystem.cs b/Content.Shared/SimpleStation14/Jukebox/JukeboxSystem.cs
index 652b0cc0ed..c5f6c28954 100644
--- a/Content.Shared/SimpleStation14/Jukebox/JukeboxSystem.cs
+++ b/Content.Shared/SimpleStation14/Jukebox/JukeboxSystem.cs
@@ -54,3 +54,11 @@ public JukeboxSongSelectedMessage(string song)
Song = song;
}
}
+
+[Serializable, NetSerializable]
+public enum JukeboxVisualLayers
+{
+ Lit,
+ UnLit,
+ Player,
+}
diff --git a/Resources/Prototypes/SimpleStation14/Entities/Structures/Machines/Fun/jukebox.yml b/Resources/Prototypes/SimpleStation14/Entities/Structures/Machines/Fun/jukebox.yml
index a28095536c..9b55f49253 100644
--- a/Resources/Prototypes/SimpleStation14/Entities/Structures/Machines/Fun/jukebox.yml
+++ b/Resources/Prototypes/SimpleStation14/Entities/Structures/Machines/Fun/jukebox.yml
@@ -1,5 +1,6 @@
- type: entity
parent: [ BaseMachinePowered, ConstructibleMachine ]
+ abstract: true
id: JukeboxBase
name: jukebox
description: A jukebox, capable of playing music.
@@ -15,9 +16,6 @@
sprite: SimpleStation14/Structures/Machines/jukebox.rsi
layers:
- state: base
- - state: powered
- - state: powered_unlit
- shader: unshaded
- type: ApcPowerReceiver
powerLoad: 350
- type: Jukebox
@@ -46,6 +44,31 @@
decorativeUi: true
- type: Machine
board: JukeboxMachineCircuitboard
+ - type: Appearance
+ - type: Sprite
+ sprite: SimpleStation14/Structures/Machines/jukebox.rsi
+ layers:
+ - state: base
+ - state: powered
+ map: ["enum.JukeboxVisualLayers.UnLit"]
+ - state: powered_unlit
+ shader: unshaded
+ map: ["enum.JukeboxVisualLayers.Lit"]
+ - state: active
+ map: ["enum.JukeboxVisualLayers.Player"]
+ - type: GenericVisualizer
+ visuals:
+ enum.PowerDeviceVisuals.VisualState:
+ enum.JukeboxVisualLayers.Player:
+ True: { visible: true}
+ False: { visible: false }
+ enum.PowerDeviceVisuals.Powered:
+ enum.JukeboxVisualLayers.Lit:
+ True: { visible: true }
+ False: { visible: false }
+ enum.JukeboxVisualLayers.UnLit:
+ True: { visible: true }
+ False: { visible: false }
# This and the Zune are just goofy testing items, but proper versions of them should probably be made.
- type: entity