* Added Jukebox, along with music for jukebox * Fixed Jukebox meta.json copyright * Removed songs I couldn't find a license for. * Renamed files to solve check failures from spaces * Added missing attributions.yml * Fixed lack of description in Jukebox * Jukebox is now constructable. * Change Jukebox menu to FancyWindow * Moved Jukebox messages out of jukebox component * Removed Jukebox OnValueChanged. * JukeboxComp now uses AutoGenerateComponentState * Removed state code, since it's auto generated * Fixed various Jukebox code to match conventions. * Updated Standard.yml to match changed song list. * fixes * Jukebox workin * Fix * Polishing * Finalising * Revert * bad * jukey * Reviews * name * Update submodule to 218.2.0 --------- Co-authored-by: iNVERTED <alextjorgensen@gmail.com>
154 lines
5.0 KiB
C#
154 lines
5.0 KiB
C#
using Content.Shared.Audio.Jukebox;
|
|
using Robust.Client.Animations;
|
|
using Robust.Client.GameObjects;
|
|
using Robust.Shared.Prototypes;
|
|
|
|
namespace Content.Client.Audio.Jukebox;
|
|
|
|
|
|
public sealed class JukeboxSystem : SharedJukeboxSystem
|
|
{
|
|
[Dependency] private readonly IPrototypeManager _protoManager = default!;
|
|
[Dependency] private readonly AnimationPlayerSystem _animationPlayer = default!;
|
|
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
SubscribeLocalEvent<JukeboxComponent, AppearanceChangeEvent>(OnAppearanceChange);
|
|
SubscribeLocalEvent<JukeboxComponent, AnimationCompletedEvent>(OnAnimationCompleted);
|
|
SubscribeLocalEvent<JukeboxComponent, AfterAutoHandleStateEvent>(OnJukeboxAfterState);
|
|
|
|
_protoManager.PrototypesReloaded += OnProtoReload;
|
|
}
|
|
|
|
public override void Shutdown()
|
|
{
|
|
base.Shutdown();
|
|
_protoManager.PrototypesReloaded -= OnProtoReload;
|
|
}
|
|
|
|
private void OnProtoReload(PrototypesReloadedEventArgs obj)
|
|
{
|
|
if (!obj.WasModified<JukeboxPrototype>())
|
|
return;
|
|
|
|
var query = AllEntityQuery<JukeboxComponent, UserInterfaceComponent>();
|
|
|
|
while (query.MoveNext(out _, out var ui))
|
|
{
|
|
if (!ui.OpenInterfaces.TryGetValue(JukeboxUiKey.Key, out var baseBui) ||
|
|
baseBui is not JukeboxBoundUserInterface bui)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
bui.PopulateMusic();
|
|
}
|
|
}
|
|
|
|
private void OnJukeboxAfterState(Entity<JukeboxComponent> ent, ref AfterAutoHandleStateEvent args)
|
|
{
|
|
if (!TryComp(ent, out UserInterfaceComponent? ui))
|
|
return;
|
|
|
|
if (!ui.OpenInterfaces.TryGetValue(JukeboxUiKey.Key, out var baseBui) ||
|
|
baseBui is not JukeboxBoundUserInterface bui)
|
|
{
|
|
return;
|
|
}
|
|
|
|
bui.Reload();
|
|
}
|
|
|
|
private void OnAnimationCompleted(EntityUid uid, JukeboxComponent component, AnimationCompletedEvent args)
|
|
{
|
|
if (!TryComp<SpriteComponent>(uid, out var sprite))
|
|
return;
|
|
|
|
if (!TryComp<AppearanceComponent>(uid, out var appearance) ||
|
|
!_appearanceSystem.TryGetData<JukeboxVisualState>(uid, JukeboxVisuals.VisualState, out var visualState, appearance))
|
|
{
|
|
visualState = JukeboxVisualState.On;
|
|
}
|
|
|
|
UpdateAppearance(uid, visualState, component, sprite);
|
|
}
|
|
|
|
private void OnAppearanceChange(EntityUid uid, JukeboxComponent component, ref AppearanceChangeEvent args)
|
|
{
|
|
if (args.Sprite == null)
|
|
return;
|
|
|
|
if (!args.AppearanceData.TryGetValue(JukeboxVisuals.VisualState, out var visualStateObject) ||
|
|
visualStateObject is not JukeboxVisualState visualState)
|
|
{
|
|
visualState = JukeboxVisualState.On;
|
|
}
|
|
|
|
UpdateAppearance(uid, visualState, component, args.Sprite);
|
|
}
|
|
|
|
private void UpdateAppearance(EntityUid uid, JukeboxVisualState visualState, JukeboxComponent component, SpriteComponent sprite)
|
|
{
|
|
SetLayerState(JukeboxVisualLayers.Base, component.OffState, sprite);
|
|
|
|
switch (visualState)
|
|
{
|
|
case JukeboxVisualState.On:
|
|
SetLayerState(JukeboxVisualLayers.Base, component.OnState, sprite);
|
|
break;
|
|
|
|
case JukeboxVisualState.Off:
|
|
SetLayerState(JukeboxVisualLayers.Base, component.OffState, sprite);
|
|
break;
|
|
|
|
case JukeboxVisualState.Select:
|
|
PlayAnimation(uid, JukeboxVisualLayers.Base, component.SelectState, 1.0f, sprite);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void PlayAnimation(EntityUid uid, JukeboxVisualLayers layer, string? state, float animationTime, SpriteComponent sprite)
|
|
{
|
|
if (string.IsNullOrEmpty(state))
|
|
return;
|
|
|
|
if (!_animationPlayer.HasRunningAnimation(uid, state))
|
|
{
|
|
var animation = GetAnimation(layer, state, animationTime);
|
|
sprite.LayerSetVisible(layer, true);
|
|
_animationPlayer.Play(uid, animation, state);
|
|
}
|
|
}
|
|
|
|
private static Animation GetAnimation(JukeboxVisualLayers layer, string state, float animationTime)
|
|
{
|
|
return new Animation
|
|
{
|
|
Length = TimeSpan.FromSeconds(animationTime),
|
|
AnimationTracks =
|
|
{
|
|
new AnimationTrackSpriteFlick
|
|
{
|
|
LayerKey = layer,
|
|
KeyFrames =
|
|
{
|
|
new AnimationTrackSpriteFlick.KeyFrame(state, 0f)
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
private void SetLayerState(JukeboxVisualLayers layer, string? state, SpriteComponent sprite)
|
|
{
|
|
if (string.IsNullOrEmpty(state))
|
|
return;
|
|
|
|
sprite.LayerSetVisible(layer, true);
|
|
sprite.LayerSetAutoAnimated(layer, true);
|
|
sprite.LayerSetState(layer, state);
|
|
}
|
|
}
|