fix: lobby music volume will be changed on options change without restart (also lobby music not looped anymore) (#25530)
* fix: lobby music volume will be changed on options change without restart (also lobby music not looped anymore) * refactor: now lobby music is part of ContentAudioSystem. Lobby playlist is used instead of single track. Client now selects next lobby soundtrack after previous finished. * refactor: incapsulated info on current lobby track in simple record * refactor: fixed inconsistent naming between song and soundtrack for lobbymusic * refactor: xml-doc for LobbyPlaylistChangedEvent * fix: inverted invalid _audio.PlayGlobal check to return only if lobby soundtrack play call failed --------- Co-authored-by: pa.pecherskij <pa.pecherskij@interfax.ru>
This commit is contained in:
@@ -1,156 +0,0 @@
|
|||||||
using Content.Client.GameTicking.Managers;
|
|
||||||
using Content.Client.Lobby;
|
|
||||||
using Content.Shared.CCVar;
|
|
||||||
using Content.Shared.GameTicking;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Robust.Client;
|
|
||||||
using Robust.Client.State;
|
|
||||||
using Robust.Shared.Audio;
|
|
||||||
using Robust.Shared.Audio.Systems;
|
|
||||||
using Robust.Shared.Configuration;
|
|
||||||
using Robust.Shared.Player;
|
|
||||||
|
|
||||||
namespace Content.Client.Audio;
|
|
||||||
|
|
||||||
[UsedImplicitly]
|
|
||||||
public sealed class BackgroundAudioSystem : EntitySystem
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* TODO: Nuke this system and merge into contentaudiosystem
|
|
||||||
*/
|
|
||||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
|
||||||
[Dependency] private readonly IBaseClient _client = default!;
|
|
||||||
[Dependency] private readonly IConfigurationManager _configManager = default!;
|
|
||||||
[Dependency] private readonly ClientGameTicker _gameTicker = default!;
|
|
||||||
[Dependency] private readonly IStateManager _stateManager = default!;
|
|
||||||
|
|
||||||
private readonly AudioParams _lobbyParams = new(-5f, 1, "Master", 0, 0, 0, true, 0f);
|
|
||||||
private readonly AudioParams _roundEndParams = new(-5f, 1, "Master", 0, 0, 0, false, 0f);
|
|
||||||
|
|
||||||
public EntityUid? LobbyMusicStream;
|
|
||||||
public EntityUid? LobbyRoundRestartAudioStream;
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
Subs.CVar(_configManager, CCVars.LobbyMusicEnabled, LobbyMusicCVarChanged);
|
|
||||||
Subs.CVar(_configManager, CCVars.LobbyMusicVolume, LobbyMusicVolumeCVarChanged);
|
|
||||||
|
|
||||||
_stateManager.OnStateChanged += StateManagerOnStateChanged;
|
|
||||||
|
|
||||||
_client.PlayerLeaveServer += OnLeave;
|
|
||||||
|
|
||||||
_gameTicker.LobbySongUpdated += LobbySongUpdated;
|
|
||||||
|
|
||||||
SubscribeNetworkEvent<RoundRestartCleanupEvent>(PlayRestartSound);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Shutdown()
|
|
||||||
{
|
|
||||||
base.Shutdown();
|
|
||||||
|
|
||||||
_stateManager.OnStateChanged -= StateManagerOnStateChanged;
|
|
||||||
|
|
||||||
_client.PlayerLeaveServer -= OnLeave;
|
|
||||||
|
|
||||||
_gameTicker.LobbySongUpdated -= LobbySongUpdated;
|
|
||||||
|
|
||||||
EndLobbyMusic();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void StateManagerOnStateChanged(StateChangedEventArgs args)
|
|
||||||
{
|
|
||||||
switch (args.NewState)
|
|
||||||
{
|
|
||||||
case LobbyState:
|
|
||||||
StartLobbyMusic();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
EndLobbyMusic();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnLeave(object? sender, PlayerEventArgs args)
|
|
||||||
{
|
|
||||||
EndLobbyMusic();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LobbyMusicVolumeCVarChanged(float volume)
|
|
||||||
{
|
|
||||||
if (_stateManager.CurrentState is LobbyState)
|
|
||||||
{
|
|
||||||
RestartLobbyMusic();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LobbyMusicCVarChanged(bool musicEnabled)
|
|
||||||
{
|
|
||||||
if (!musicEnabled)
|
|
||||||
{
|
|
||||||
EndLobbyMusic();
|
|
||||||
}
|
|
||||||
else if (_stateManager.CurrentState is LobbyState)
|
|
||||||
{
|
|
||||||
StartLobbyMusic();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EndLobbyMusic();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LobbySongUpdated()
|
|
||||||
{
|
|
||||||
RestartLobbyMusic();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RestartLobbyMusic()
|
|
||||||
{
|
|
||||||
EndLobbyMusic();
|
|
||||||
StartLobbyMusic();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StartLobbyMusic()
|
|
||||||
{
|
|
||||||
if (LobbyMusicStream != null || !_configManager.GetCVar(CCVars.LobbyMusicEnabled))
|
|
||||||
return;
|
|
||||||
|
|
||||||
var file = _gameTicker.LobbySong;
|
|
||||||
if (file == null) // We have not received the lobby song yet.
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LobbyMusicStream = _audio.PlayGlobal(
|
|
||||||
file,
|
|
||||||
Filter.Local(),
|
|
||||||
false,
|
|
||||||
_lobbyParams.WithVolume(_lobbyParams.Volume + SharedAudioSystem.GainToVolume(_configManager.GetCVar(CCVars.LobbyMusicVolume))))?.Entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EndLobbyMusic()
|
|
||||||
{
|
|
||||||
LobbyMusicStream = _audio.Stop(LobbyMusicStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PlayRestartSound(RoundRestartCleanupEvent ev)
|
|
||||||
{
|
|
||||||
if (!_configManager.GetCVar(CCVars.RestartSoundsEnabled))
|
|
||||||
return;
|
|
||||||
|
|
||||||
var file = _gameTicker.RestartSound;
|
|
||||||
if (string.IsNullOrEmpty(file))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LobbyRoundRestartAudioStream = _audio.PlayGlobal(
|
|
||||||
file,
|
|
||||||
Filter.Local(),
|
|
||||||
false,
|
|
||||||
_roundEndParams.WithVolume(_roundEndParams.Volume + SharedAudioSystem.GainToVolume(_configManager.GetCVar(CCVars.LobbyMusicVolume)))
|
|
||||||
)?.Entity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
283
Content.Client/Audio/ContentAudioSystem.LobbyMusic.cs
Normal file
283
Content.Client/Audio/ContentAudioSystem.LobbyMusic.cs
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Content.Client.GameTicking.Managers;
|
||||||
|
using Content.Client.Lobby;
|
||||||
|
using Content.Shared.Audio.Events;
|
||||||
|
using Content.Shared.CCVar;
|
||||||
|
using Content.Shared.GameTicking;
|
||||||
|
using Robust.Client;
|
||||||
|
using Robust.Client.ResourceManagement;
|
||||||
|
using Robust.Client.State;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.Audio.Systems;
|
||||||
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Client.Audio;
|
||||||
|
|
||||||
|
// Part of ContentAudioSystem that is responsible for lobby music playing/stopping and round-end sound-effect.
|
||||||
|
public sealed partial class ContentAudioSystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IBaseClient _client = default!;
|
||||||
|
[Dependency] private readonly ClientGameTicker _gameTicker = default!;
|
||||||
|
[Dependency] private readonly IStateManager _stateManager = default!;
|
||||||
|
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||||
|
|
||||||
|
private readonly AudioParams _lobbySoundtrackParams = new(-5f, 1, "Master", 0, 0, 0, false, 0f);
|
||||||
|
private readonly AudioParams _roundEndSoundEffectParams = new(-5f, 1, "Master", 0, 0, 0, false, 0f);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// EntityUid of lobby restart sound component.
|
||||||
|
/// </summary>
|
||||||
|
private EntityUid? _lobbyRoundRestartAudioStream;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Shuffled list of soundtrack file-names.
|
||||||
|
/// </summary>
|
||||||
|
private string[]? _lobbyPlaylist;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Short info about lobby soundtrack currently playing. Is null if soundtrack is not playing.
|
||||||
|
/// </summary>
|
||||||
|
private LobbySoundtrackInfo? _lobbySoundtrackInfo;
|
||||||
|
|
||||||
|
private Action<LobbySoundtrackChangedEvent>? _lobbySoundtrackChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event for subscription on lobby soundtrack changes.
|
||||||
|
/// </summary>
|
||||||
|
public event Action<LobbySoundtrackChangedEvent>? LobbySoundtrackChanged
|
||||||
|
{
|
||||||
|
add
|
||||||
|
{
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
if (_lobbySoundtrackInfo != null)
|
||||||
|
{
|
||||||
|
value(new LobbySoundtrackChangedEvent(_lobbySoundtrackInfo.Filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
_lobbySoundtrackChanged += value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
remove => _lobbySoundtrackChanged -= value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes subscriptions that are related to lobby music.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeLobbyMusic()
|
||||||
|
{
|
||||||
|
Subs.CVar(_configManager, CCVars.LobbyMusicEnabled, LobbyMusicCVarChanged);
|
||||||
|
Subs.CVar(_configManager, CCVars.LobbyMusicVolume, LobbyMusicVolumeCVarChanged);
|
||||||
|
|
||||||
|
_stateManager.OnStateChanged += StateManagerOnStateChanged;
|
||||||
|
|
||||||
|
_client.PlayerLeaveServer += OnLeave;
|
||||||
|
|
||||||
|
SubscribeNetworkEvent<LobbyMusicStopEvent>(OnLobbySongStopped);
|
||||||
|
SubscribeNetworkEvent<LobbyPlaylistChangedEvent>(OnLobbySongChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnLobbySongStopped(LobbyMusicStopEvent ev)
|
||||||
|
{
|
||||||
|
EndLobbyMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StateManagerOnStateChanged(StateChangedEventArgs args)
|
||||||
|
{
|
||||||
|
switch (args.NewState)
|
||||||
|
{
|
||||||
|
case LobbyState:
|
||||||
|
StartLobbyMusic();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
EndLobbyMusic();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnLeave(object? sender, PlayerEventArgs args)
|
||||||
|
{
|
||||||
|
EndLobbyMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LobbyMusicVolumeCVarChanged(float volume)
|
||||||
|
{
|
||||||
|
if (_lobbySoundtrackInfo != null)
|
||||||
|
{
|
||||||
|
_audio.SetVolume(
|
||||||
|
_lobbySoundtrackInfo.MusicStreamEntityUid,
|
||||||
|
_lobbySoundtrackParams.Volume + SharedAudioSystem.GainToVolume(_configManager.GetCVar(CCVars.LobbyMusicVolume))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LobbyMusicCVarChanged(bool musicEnabled)
|
||||||
|
{
|
||||||
|
if (musicEnabled && _stateManager.CurrentState is LobbyState)
|
||||||
|
{
|
||||||
|
StartLobbyMusic();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EndLobbyMusic();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnLobbySongChanged(LobbyPlaylistChangedEvent playlistChangedEvent)
|
||||||
|
{
|
||||||
|
var playlist = playlistChangedEvent.Playlist;
|
||||||
|
//playlist is already playing, no need to restart it
|
||||||
|
if (_lobbySoundtrackInfo != null
|
||||||
|
&& _lobbyPlaylist != null
|
||||||
|
&& _lobbyPlaylist.SequenceEqual(playlist)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EndLobbyMusic();
|
||||||
|
StartLobbyMusic(playlistChangedEvent.Playlist);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Re-starts playing lobby music from playlist, last sent from server. if there is currently none - does nothing.
|
||||||
|
/// </summary>
|
||||||
|
private void StartLobbyMusic()
|
||||||
|
{
|
||||||
|
if (_lobbyPlaylist == null || _lobbyPlaylist.Length == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StartLobbyMusic(_lobbyPlaylist);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts playing lobby music from playlist. If playlist is empty, or lobby music setting is turned off - does nothing.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="playlist">Array of soundtrack filenames for lobby playlist.</param>
|
||||||
|
private void StartLobbyMusic(string[] playlist)
|
||||||
|
{
|
||||||
|
if (_lobbySoundtrackInfo != null || !_configManager.GetCVar(CCVars.LobbyMusicEnabled))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_lobbyPlaylist = playlist;
|
||||||
|
if (_lobbyPlaylist.Length == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlaySoundtrack(playlist[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PlaySoundtrack(string soundtrackFilename)
|
||||||
|
{
|
||||||
|
if (!_resourceCache.TryGetResource(new ResPath(soundtrackFilename), out AudioResource? audio))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var playResult = _audio.PlayGlobal(
|
||||||
|
soundtrackFilename,
|
||||||
|
Filter.Local(),
|
||||||
|
false,
|
||||||
|
_lobbySoundtrackParams.WithVolume(_lobbySoundtrackParams.Volume + SharedAudioSystem.GainToVolume(_configManager.GetCVar(CCVars.LobbyMusicVolume)))
|
||||||
|
);
|
||||||
|
if (playResult.Value.Entity == default)
|
||||||
|
{
|
||||||
|
_sawmill.Warning(
|
||||||
|
$"Tried to play lobby soundtrack '{{Filename}}' using {nameof(SharedAudioSystem)}.{nameof(SharedAudioSystem.PlayGlobal)} but it returned default value of EntityUid!",
|
||||||
|
soundtrackFilename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var nextTrackOn = _timing.CurTime + audio.AudioStream.Length;
|
||||||
|
_lobbySoundtrackInfo = new LobbySoundtrackInfo(soundtrackFilename, nextTrackOn, playResult.Value.Entity);
|
||||||
|
|
||||||
|
var lobbySongChangedEvent = new LobbySoundtrackChangedEvent(soundtrackFilename);
|
||||||
|
_lobbySoundtrackChanged?.Invoke(lobbySongChangedEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EndLobbyMusic()
|
||||||
|
{
|
||||||
|
if (_lobbySoundtrackInfo == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_audio.Stop(_lobbySoundtrackInfo.MusicStreamEntityUid);
|
||||||
|
_lobbySoundtrackInfo = null;
|
||||||
|
var lobbySongChangedEvent = new LobbySoundtrackChangedEvent();
|
||||||
|
_lobbySoundtrackChanged?.Invoke(lobbySongChangedEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PlayRestartSound(RoundRestartCleanupEvent ev)
|
||||||
|
{
|
||||||
|
if (!_configManager.GetCVar(CCVars.RestartSoundsEnabled))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var file = _gameTicker.RestartSound;
|
||||||
|
if (string.IsNullOrEmpty(file))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_lobbyRoundRestartAudioStream = _audio.PlayGlobal(
|
||||||
|
file,
|
||||||
|
Filter.Local(),
|
||||||
|
false,
|
||||||
|
_roundEndSoundEffectParams.WithVolume(_roundEndSoundEffectParams.Volume + SharedAudioSystem.GainToVolume(_configManager.GetCVar(CCVars.LobbyMusicVolume)))
|
||||||
|
)?.Entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShutdownLobbyMusic()
|
||||||
|
{
|
||||||
|
_stateManager.OnStateChanged -= StateManagerOnStateChanged;
|
||||||
|
|
||||||
|
_client.PlayerLeaveServer -= OnLeave;
|
||||||
|
|
||||||
|
EndLobbyMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateLobbyMusic()
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
_lobbySoundtrackInfo != null
|
||||||
|
&& _timing.CurTime >= _lobbySoundtrackInfo.NextTrackOn
|
||||||
|
&& _lobbyPlaylist?.Length > 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
var nextSoundtrackFilename = GetNextSoundtrackFromPlaylist(_lobbySoundtrackInfo.Filename, _lobbyPlaylist);
|
||||||
|
PlaySoundtrack(nextSoundtrackFilename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetNextSoundtrackFromPlaylist(string currentSoundtrackFilename, string[] playlist)
|
||||||
|
{
|
||||||
|
var indexOfCurrent = Array.IndexOf(playlist, currentSoundtrackFilename);
|
||||||
|
var nextTrackIndex = indexOfCurrent + 1;
|
||||||
|
if (nextTrackIndex > playlist.Length - 1)
|
||||||
|
{
|
||||||
|
nextTrackIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return playlist[nextTrackIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Container for lobby soundtrack information. </summary>
|
||||||
|
/// <param name="Filename">Soundtrack filename.</param>
|
||||||
|
/// <param name="NextTrackOn">Time (based on <see cref="IGameTiming.CurTime"/>) when this track is going to finish playing and next track have to be started.</param>
|
||||||
|
/// <param name="MusicStreamEntityUid">
|
||||||
|
/// EntityUid of launched soundtrack (from <see cref="SharedAudioSystem.PlayGlobal(string,Robust.Shared.Player.Filter,bool,System.Nullable{Robust.Shared.Audio.AudioParams})"/>).
|
||||||
|
/// </param>
|
||||||
|
private sealed record LobbySoundtrackInfo(string Filename, TimeSpan NextTrackOn, EntityUid MusicStreamEntityUid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event of changing lobby soundtrack (or stopping lobby music - will pass null for <paramref name="SoundtrackFilename"/> in that case).
|
||||||
|
/// Is used by <see cref="ContentAudioSystem.LobbySoundtrackChanged"/> and <see cref="LobbyState.UpdateLobbySoundtrackInfo"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="SoundtrackFilename">Filename of newly set soundtrack, or null if soundtrack playback is stopped.</param>
|
||||||
|
public sealed record LobbySoundtrackChangedEvent(string? SoundtrackFilename = null);
|
||||||
@@ -29,12 +29,14 @@ public sealed partial class ContentAudioSystem : SharedContentAudioSystem
|
|||||||
public const float AmbientMusicMultiplier = 3f;
|
public const float AmbientMusicMultiplier = 3f;
|
||||||
public const float LobbyMultiplier = 3f;
|
public const float LobbyMultiplier = 3f;
|
||||||
public const float InterfaceMultiplier = 2f;
|
public const float InterfaceMultiplier = 2f;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
UpdatesOutsidePrediction = true;
|
UpdatesOutsidePrediction = true;
|
||||||
InitializeAmbientMusic();
|
InitializeAmbientMusic();
|
||||||
|
InitializeLobbyMusic();
|
||||||
SubscribeNetworkEvent<RoundRestartCleanupEvent>(OnRoundCleanup);
|
SubscribeNetworkEvent<RoundRestartCleanupEvent>(OnRoundCleanup);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,11 +45,11 @@ public sealed partial class ContentAudioSystem : SharedContentAudioSystem
|
|||||||
_fadingOut.Clear();
|
_fadingOut.Clear();
|
||||||
|
|
||||||
// Preserve lobby music but everything else should get dumped.
|
// Preserve lobby music but everything else should get dumped.
|
||||||
var lobbyMusic = EntityManager.System<BackgroundAudioSystem>().LobbyMusicStream;
|
var lobbyMusic = _lobbySoundtrackInfo?.MusicStreamEntityUid;
|
||||||
TryComp(lobbyMusic, out AudioComponent? lobbyMusicComp);
|
TryComp(lobbyMusic, out AudioComponent? lobbyMusicComp);
|
||||||
var oldMusicGain = lobbyMusicComp?.Gain;
|
var oldMusicGain = lobbyMusicComp?.Gain;
|
||||||
|
|
||||||
var restartAudio = EntityManager.System<BackgroundAudioSystem>().LobbyRoundRestartAudioStream;
|
var restartAudio = _lobbyRoundRestartAudioStream;
|
||||||
TryComp(restartAudio, out AudioComponent? restartComp);
|
TryComp(restartAudio, out AudioComponent? restartComp);
|
||||||
var oldAudioGain = restartComp?.Gain;
|
var oldAudioGain = restartComp?.Gain;
|
||||||
|
|
||||||
@@ -62,12 +64,14 @@ public sealed partial class ContentAudioSystem : SharedContentAudioSystem
|
|||||||
{
|
{
|
||||||
Audio.SetGain(restartAudio, oldAudioGain.Value, restartComp);
|
Audio.SetGain(restartAudio, oldAudioGain.Value, restartComp);
|
||||||
}
|
}
|
||||||
|
PlayRestartSound(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Shutdown()
|
public override void Shutdown()
|
||||||
{
|
{
|
||||||
base.Shutdown();
|
base.Shutdown();
|
||||||
ShutdownAmbientMusic();
|
ShutdownAmbientMusic();
|
||||||
|
ShutdownLobbyMusic();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float frameTime)
|
public override void Update(float frameTime)
|
||||||
@@ -78,6 +82,7 @@ public sealed partial class ContentAudioSystem : SharedContentAudioSystem
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
UpdateAmbientMusic();
|
UpdateAmbientMusic();
|
||||||
|
UpdateLobbyMusic();
|
||||||
UpdateFades(frameTime);
|
UpdateFades(frameTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,11 @@
|
|||||||
using Content.Client.Gameplay;
|
using Content.Client.Gameplay;
|
||||||
using Content.Client.Lobby;
|
using Content.Client.Lobby;
|
||||||
using Content.Client.RoundEnd;
|
using Content.Client.RoundEnd;
|
||||||
using Content.Shared.CCVar;
|
|
||||||
using Content.Shared.GameTicking;
|
using Content.Shared.GameTicking;
|
||||||
using Content.Shared.GameWindow;
|
using Content.Shared.GameWindow;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.State;
|
using Robust.Client.State;
|
||||||
using Robust.Shared.Audio;
|
|
||||||
using Robust.Shared.Audio.Systems;
|
|
||||||
using Robust.Shared.Configuration;
|
|
||||||
using Robust.Shared.Player;
|
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Client.GameTicking.Managers
|
namespace Content.Client.GameTicking.Managers
|
||||||
@@ -32,7 +27,6 @@ namespace Content.Client.GameTicking.Managers
|
|||||||
|
|
||||||
[ViewVariables] public bool AreWeReady { get; private set; }
|
[ViewVariables] public bool AreWeReady { get; private set; }
|
||||||
[ViewVariables] public bool IsGameStarted { get; private set; }
|
[ViewVariables] public bool IsGameStarted { get; private set; }
|
||||||
[ViewVariables] public string? LobbySong { get; private set; }
|
|
||||||
[ViewVariables] public string? RestartSound { get; private set; }
|
[ViewVariables] public string? RestartSound { get; private set; }
|
||||||
[ViewVariables] public string? LobbyBackground { get; private set; }
|
[ViewVariables] public string? LobbyBackground { get; private set; }
|
||||||
[ViewVariables] public bool DisallowedLateJoin { get; private set; }
|
[ViewVariables] public bool DisallowedLateJoin { get; private set; }
|
||||||
@@ -45,7 +39,6 @@ namespace Content.Client.GameTicking.Managers
|
|||||||
|
|
||||||
public event Action? InfoBlobUpdated;
|
public event Action? InfoBlobUpdated;
|
||||||
public event Action? LobbyStatusUpdated;
|
public event Action? LobbyStatusUpdated;
|
||||||
public event Action? LobbySongUpdated;
|
|
||||||
public event Action? LobbyLateJoinStatusUpdated;
|
public event Action? LobbyLateJoinStatusUpdated;
|
||||||
public event Action<IReadOnlyDictionary<NetEntity, Dictionary<string, uint?>>>? LobbyJobsAvailableUpdated;
|
public event Action<IReadOnlyDictionary<NetEntity, Dictionary<string, uint?>>>? LobbyJobsAvailableUpdated;
|
||||||
|
|
||||||
@@ -70,16 +63,6 @@ namespace Content.Client.GameTicking.Managers
|
|||||||
_initialized = true;
|
_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetLobbySong(string? song, bool forceUpdate = false)
|
|
||||||
{
|
|
||||||
var updated = song != LobbySong;
|
|
||||||
|
|
||||||
LobbySong = song;
|
|
||||||
|
|
||||||
if (updated || forceUpdate)
|
|
||||||
LobbySongUpdated?.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LateJoinStatus(TickerLateJoinStatusEvent message)
|
private void LateJoinStatus(TickerLateJoinStatusEvent message)
|
||||||
{
|
{
|
||||||
DisallowedLateJoin = message.Disallowed;
|
DisallowedLateJoin = message.Disallowed;
|
||||||
@@ -120,7 +103,6 @@ namespace Content.Client.GameTicking.Managers
|
|||||||
RoundStartTimeSpan = message.RoundStartTimeSpan;
|
RoundStartTimeSpan = message.RoundStartTimeSpan;
|
||||||
IsGameStarted = message.IsRoundStarted;
|
IsGameStarted = message.IsRoundStarted;
|
||||||
AreWeReady = message.YouAreReady;
|
AreWeReady = message.YouAreReady;
|
||||||
SetLobbySong(message.LobbySong);
|
|
||||||
LobbyBackground = message.LobbyBackground;
|
LobbyBackground = message.LobbyBackground;
|
||||||
Paused = message.Paused;
|
Paused = message.Paused;
|
||||||
|
|
||||||
@@ -148,7 +130,6 @@ namespace Content.Client.GameTicking.Managers
|
|||||||
private void RoundEnd(RoundEndMessageEvent message)
|
private void RoundEnd(RoundEndMessageEvent message)
|
||||||
{
|
{
|
||||||
// Force an update in the event of this song being the same as the last.
|
// Force an update in the event of this song being the same as the last.
|
||||||
SetLobbySong(message.LobbySong, true);
|
|
||||||
RestartSound = message.RestartSound;
|
RestartSound = message.RestartSound;
|
||||||
|
|
||||||
// Don't open duplicate windows (mainly for replays).
|
// Don't open duplicate windows (mainly for replays).
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Content.Client.Audio;
|
||||||
using Content.Client.GameTicking.Managers;
|
using Content.Client.GameTicking.Managers;
|
||||||
using Content.Client.LateJoin;
|
using Content.Client.LateJoin;
|
||||||
using Content.Client.Lobby.UI;
|
using Content.Client.Lobby.UI;
|
||||||
@@ -34,6 +35,7 @@ namespace Content.Client.Lobby
|
|||||||
[ViewVariables] private CharacterSetupGui? _characterSetup;
|
[ViewVariables] private CharacterSetupGui? _characterSetup;
|
||||||
|
|
||||||
private ClientGameTicker _gameTicker = default!;
|
private ClientGameTicker _gameTicker = default!;
|
||||||
|
private ContentAudioSystem _contentAudioSystem = default!;
|
||||||
|
|
||||||
protected override Type? LinkedScreenType { get; } = typeof(LobbyGui);
|
protected override Type? LinkedScreenType { get; } = typeof(LobbyGui);
|
||||||
private LobbyGui? _lobby;
|
private LobbyGui? _lobby;
|
||||||
@@ -49,6 +51,8 @@ namespace Content.Client.Lobby
|
|||||||
|
|
||||||
var chatController = _userInterfaceManager.GetUIController<ChatUIController>();
|
var chatController = _userInterfaceManager.GetUIController<ChatUIController>();
|
||||||
_gameTicker = _entityManager.System<ClientGameTicker>();
|
_gameTicker = _entityManager.System<ClientGameTicker>();
|
||||||
|
_contentAudioSystem = _entityManager.System<ContentAudioSystem>();
|
||||||
|
_contentAudioSystem.LobbySoundtrackChanged += UpdateLobbySoundtrackInfo;
|
||||||
_characterSetup = new CharacterSetupGui(_entityManager, _resourceCache, _preferencesManager,
|
_characterSetup = new CharacterSetupGui(_entityManager, _resourceCache, _preferencesManager,
|
||||||
_prototypeManager, _configurationManager);
|
_prototypeManager, _configurationManager);
|
||||||
LayoutContainer.SetAnchorPreset(_characterSetup, LayoutContainer.LayoutPreset.Wide);
|
LayoutContainer.SetAnchorPreset(_characterSetup, LayoutContainer.LayoutPreset.Wide);
|
||||||
@@ -93,6 +97,7 @@ namespace Content.Client.Lobby
|
|||||||
_gameTicker.InfoBlobUpdated -= UpdateLobbyUi;
|
_gameTicker.InfoBlobUpdated -= UpdateLobbyUi;
|
||||||
_gameTicker.LobbyStatusUpdated -= LobbyStatusUpdated;
|
_gameTicker.LobbyStatusUpdated -= LobbyStatusUpdated;
|
||||||
_gameTicker.LobbyLateJoinStatusUpdated -= LobbyLateJoinStatusUpdated;
|
_gameTicker.LobbyLateJoinStatusUpdated -= LobbyLateJoinStatusUpdated;
|
||||||
|
_contentAudioSystem.LobbySoundtrackChanged -= UpdateLobbySoundtrackInfo;
|
||||||
|
|
||||||
_voteManager.ClearPopupContainer();
|
_voteManager.ClearPopupContainer();
|
||||||
|
|
||||||
@@ -207,22 +212,28 @@ namespace Content.Client.Lobby
|
|||||||
{
|
{
|
||||||
_lobby!.ServerInfo.SetInfoBlob(_gameTicker.ServerInfoBlob);
|
_lobby!.ServerInfo.SetInfoBlob(_gameTicker.ServerInfoBlob);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_gameTicker.LobbySong == null)
|
private void UpdateLobbySoundtrackInfo(LobbySoundtrackChangedEvent ev)
|
||||||
|
{
|
||||||
|
if (ev.SoundtrackFilename == null)
|
||||||
{
|
{
|
||||||
_lobby!.LobbySong.SetMarkup(Loc.GetString("lobby-state-song-no-song-text"));
|
_lobby!.LobbySong.SetMarkup(Loc.GetString("lobby-state-song-no-song-text"));
|
||||||
}
|
}
|
||||||
else if (_resourceCache.TryGetResource<AudioResource>(_gameTicker.LobbySong, out var lobbySongResource))
|
else if (
|
||||||
|
ev.SoundtrackFilename != null
|
||||||
|
&& _resourceCache.TryGetResource<AudioResource>(ev.SoundtrackFilename, out var lobbySongResource)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
var lobbyStream = lobbySongResource.AudioStream;
|
var lobbyStream = lobbySongResource.AudioStream;
|
||||||
|
|
||||||
var title = string.IsNullOrEmpty(lobbyStream.Title) ?
|
var title = string.IsNullOrEmpty(lobbyStream.Title)
|
||||||
Loc.GetString("lobby-state-song-unknown-title") :
|
? Loc.GetString("lobby-state-song-unknown-title")
|
||||||
lobbyStream.Title;
|
: lobbyStream.Title;
|
||||||
|
|
||||||
var artist = string.IsNullOrEmpty(lobbyStream.Artist) ?
|
var artist = string.IsNullOrEmpty(lobbyStream.Artist)
|
||||||
Loc.GetString("lobby-state-song-unknown-artist") :
|
? Loc.GetString("lobby-state-song-unknown-artist")
|
||||||
lobbyStream.Artist;
|
: lobbyStream.Artist;
|
||||||
|
|
||||||
var markup = Loc.GetString("lobby-state-song-text",
|
var markup = Loc.GetString("lobby-state-song-text",
|
||||||
("songTitle", title),
|
("songTitle", title),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Client.Chat.UI;
|
using Content.Client.Chat.UI;
|
||||||
using Content.Client.Info;
|
using Content.Client.Info;
|
||||||
|
using Content.Client.Message;
|
||||||
using Content.Client.Preferences;
|
using Content.Client.Preferences;
|
||||||
using Content.Client.Preferences.UI;
|
using Content.Client.Preferences.UI;
|
||||||
using Content.Client.UserInterface.Screens;
|
using Content.Client.UserInterface.Screens;
|
||||||
@@ -33,6 +34,8 @@ namespace Content.Client.Lobby.UI
|
|||||||
SetAnchorPreset(MainContainer, LayoutPreset.Wide);
|
SetAnchorPreset(MainContainer, LayoutPreset.Wide);
|
||||||
SetAnchorPreset(Background, LayoutPreset.Wide);
|
SetAnchorPreset(Background, LayoutPreset.Wide);
|
||||||
|
|
||||||
|
LobbySong.SetMarkup(Loc.GetString("lobby-state-song-no-song-text"));
|
||||||
|
|
||||||
LeaveButton.OnPressed += _ => _consoleHost.ExecuteCommand("disconnect");
|
LeaveButton.OnPressed += _ => _consoleHost.ExecuteCommand("disconnect");
|
||||||
OptionsButton.OnPressed += _ => _userInterfaceManager.GetUIController<OptionsUIController>().ToggleWindow();
|
OptionsButton.OnPressed += _ => _userInterfaceManager.GetUIController<OptionsUIController>().ToggleWindow();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,37 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Content.Server.GameTicking;
|
||||||
using Content.Server.GameTicking.Events;
|
using Content.Server.GameTicking.Events;
|
||||||
using Content.Shared.Audio;
|
using Content.Shared.Audio;
|
||||||
|
using Content.Shared.Audio.Events;
|
||||||
using Content.Shared.GameTicking;
|
using Content.Shared.GameTicking;
|
||||||
using Robust.Server.Audio;
|
using Robust.Server.Audio;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
namespace Content.Server.Audio;
|
namespace Content.Server.Audio;
|
||||||
|
|
||||||
public sealed class ContentAudioSystem : SharedContentAudioSystem
|
public sealed class ContentAudioSystem : SharedContentAudioSystem
|
||||||
{
|
{
|
||||||
|
[ValidatePrototypeId<SoundCollectionPrototype>]
|
||||||
|
private const string LobbyMusicCollection = "LobbyMusic";
|
||||||
|
|
||||||
[Dependency] private readonly AudioSystem _serverAudio = default!;
|
[Dependency] private readonly AudioSystem _serverAudio = default!;
|
||||||
|
[Dependency] private readonly IRobustRandom _robustRandom = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
|
|
||||||
|
private SoundCollectionPrototype _lobbyMusicCollection = default!;
|
||||||
|
private string[]? _lobbyPlaylist;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
|
_lobbyMusicCollection = _prototypeManager.Index<SoundCollectionPrototype>(LobbyMusicCollection);
|
||||||
|
_lobbyPlaylist = ShuffleLobbyPlaylist();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<RoundEndMessageEvent>(OnRoundEnd);
|
||||||
|
SubscribeLocalEvent<PlayerJoinedLobbyEvent>(OnPlayerJoinedLobby);
|
||||||
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundCleanup);
|
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundCleanup);
|
||||||
SubscribeLocalEvent<RoundStartingEvent>(OnRoundStart);
|
SubscribeLocalEvent<RoundStartingEvent>(OnRoundStart);
|
||||||
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnProtoReload);
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnProtoReload);
|
||||||
@@ -36,4 +54,33 @@ public sealed class ContentAudioSystem : SharedContentAudioSystem
|
|||||||
// yeah it's whacky af.
|
// yeah it's whacky af.
|
||||||
_serverAudio.ReloadPresets();
|
_serverAudio.ReloadPresets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnPlayerJoinedLobby(PlayerJoinedLobbyEvent ev)
|
||||||
|
{
|
||||||
|
if (_lobbyPlaylist != null)
|
||||||
|
{
|
||||||
|
var session = ev.PlayerSession;
|
||||||
|
RaiseNetworkEvent(new LobbyPlaylistChangedEvent(_lobbyPlaylist), session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnRoundEnd(RoundEndMessageEvent ev)
|
||||||
|
{
|
||||||
|
// The lobby song is set here instead of in RestartRound,
|
||||||
|
// because ShowRoundEndScoreboard triggers the start of the music playing
|
||||||
|
// at the end of a round, and this needs to be set before RestartRound
|
||||||
|
// in order for the lobby song status display to be accurate.
|
||||||
|
_lobbyPlaylist = ShuffleLobbyPlaylist();
|
||||||
|
RaiseNetworkEvent(new LobbyPlaylistChangedEvent(_lobbyPlaylist));
|
||||||
|
}
|
||||||
|
|
||||||
|
private string[] ShuffleLobbyPlaylist()
|
||||||
|
{
|
||||||
|
var playlist = _lobbyMusicCollection.PickFiles
|
||||||
|
.Select(x => x.ToString())
|
||||||
|
.ToArray();
|
||||||
|
_robustRandom.Shuffle(playlist);
|
||||||
|
|
||||||
|
return playlist;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ namespace Content.Server.GameTicking
|
|||||||
private TickerLobbyStatusEvent GetStatusMsg(ICommonSession session)
|
private TickerLobbyStatusEvent GetStatusMsg(ICommonSession session)
|
||||||
{
|
{
|
||||||
_playerGameStatuses.TryGetValue(session.UserId, out var status);
|
_playerGameStatuses.TryGetValue(session.UserId, out var status);
|
||||||
return new TickerLobbyStatusEvent(RunLevel != GameRunLevel.PreRoundLobby, LobbySong, LobbyBackground, status == PlayerGameStatus.ReadyToPlay, _roundStartTime, RoundPreloadTime, RoundStartTimeSpan, Paused);
|
return new TickerLobbyStatusEvent(RunLevel != GameRunLevel.PreRoundLobby, LobbyBackground, status == PlayerGameStatus.ReadyToPlay, _roundStartTime, RoundPreloadTime, RoundStartTimeSpan, Paused);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendStatusToAll()
|
private void SendStatusToAll()
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
using Robust.Shared.Audio;
|
|
||||||
using Robust.Shared.Random;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
|
|
||||||
namespace Content.Server.GameTicking
|
|
||||||
{
|
|
||||||
public sealed partial class GameTicker
|
|
||||||
{
|
|
||||||
[ValidatePrototypeId<SoundCollectionPrototype>]
|
|
||||||
private const string LobbyMusicCollection = "LobbyMusic";
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private bool _lobbyMusicInitialized = false;
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private SoundCollectionPrototype _lobbyMusicCollection = default!;
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
public string? LobbySong { get; private set; }
|
|
||||||
|
|
||||||
private void InitializeLobbyMusic()
|
|
||||||
{
|
|
||||||
DebugTools.Assert(!_lobbyMusicInitialized);
|
|
||||||
_lobbyMusicCollection = _prototypeManager.Index<SoundCollectionPrototype>(LobbyMusicCollection);
|
|
||||||
|
|
||||||
// Now that the collection is set, the lobby music has been initialized and we can choose a random song.
|
|
||||||
_lobbyMusicInitialized = true;
|
|
||||||
|
|
||||||
ChooseRandomLobbySong();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the current lobby song, or stops it if null.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="song">The lobby song to play, or null to stop any lobby songs.</param>
|
|
||||||
public void SetLobbySong(string? song)
|
|
||||||
{
|
|
||||||
DebugTools.Assert(_lobbyMusicInitialized);
|
|
||||||
|
|
||||||
if (song == null)
|
|
||||||
{
|
|
||||||
LobbySong = null;
|
|
||||||
return;
|
|
||||||
// TODO GAMETICKER send song stop event
|
|
||||||
}
|
|
||||||
|
|
||||||
LobbySong = song;
|
|
||||||
// TODO GAMETICKER send song change event
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Plays a random song from the LobbyMusic sound collection.
|
|
||||||
/// </summary>
|
|
||||||
public void ChooseRandomLobbySong()
|
|
||||||
{
|
|
||||||
DebugTools.Assert(_lobbyMusicInitialized);
|
|
||||||
SetLobbySong(_robustRandom.Pick(_lobbyMusicCollection.PickFiles).ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Stops the current lobby song being played.
|
|
||||||
/// </summary>
|
|
||||||
public void StopLobbySong()
|
|
||||||
{
|
|
||||||
SetLobbySong(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -301,12 +301,6 @@ namespace Content.Server.GameTicking
|
|||||||
|
|
||||||
RunLevel = GameRunLevel.PostRound;
|
RunLevel = GameRunLevel.PostRound;
|
||||||
|
|
||||||
// The lobby song is set here instead of in RestartRound,
|
|
||||||
// because ShowRoundEndScoreboard triggers the start of the music playing
|
|
||||||
// at the end of a round, and this needs to be set before RestartRound
|
|
||||||
// in order for the lobby song status display to be accurate.
|
|
||||||
LobbySong = _robustRandom.Pick(_lobbyMusicCollection.PickFiles).ToString();
|
|
||||||
|
|
||||||
ShowRoundEndScoreboard(text);
|
ShowRoundEndScoreboard(text);
|
||||||
SendRoundEndDiscordMessage();
|
SendRoundEndDiscordMessage();
|
||||||
}
|
}
|
||||||
@@ -394,8 +388,17 @@ namespace Content.Server.GameTicking
|
|||||||
var listOfPlayerInfoFinal = listOfPlayerInfo.OrderBy(pi => pi.PlayerOOCName).ToArray();
|
var listOfPlayerInfoFinal = listOfPlayerInfo.OrderBy(pi => pi.PlayerOOCName).ToArray();
|
||||||
var sound = RoundEndSoundCollection == null ? null : _audio.GetSound(new SoundCollectionSpecifier(RoundEndSoundCollection));
|
var sound = RoundEndSoundCollection == null ? null : _audio.GetSound(new SoundCollectionSpecifier(RoundEndSoundCollection));
|
||||||
|
|
||||||
RaiseNetworkEvent(new RoundEndMessageEvent(gamemodeTitle, roundEndText, roundDuration, RoundId,
|
var roundEndMessageEvent = new RoundEndMessageEvent(
|
||||||
listOfPlayerInfoFinal.Length, listOfPlayerInfoFinal, LobbySong, sound));
|
gamemodeTitle,
|
||||||
|
roundEndText,
|
||||||
|
roundDuration,
|
||||||
|
RoundId,
|
||||||
|
listOfPlayerInfoFinal.Length,
|
||||||
|
listOfPlayerInfoFinal,
|
||||||
|
sound
|
||||||
|
);
|
||||||
|
RaiseNetworkEvent(roundEndMessageEvent);
|
||||||
|
RaiseLocalEvent(roundEndMessageEvent);
|
||||||
|
|
||||||
_replayRoundPlayerInfo = listOfPlayerInfoFinal;
|
_replayRoundPlayerInfo = listOfPlayerInfoFinal;
|
||||||
_replayRoundText = roundEndText;
|
_replayRoundText = roundEndText;
|
||||||
|
|||||||
@@ -93,7 +93,6 @@ namespace Content.Server.GameTicking
|
|||||||
InitializeStatusShell();
|
InitializeStatusShell();
|
||||||
InitializeCVars();
|
InitializeCVars();
|
||||||
InitializePlayer();
|
InitializePlayer();
|
||||||
InitializeLobbyMusic();
|
|
||||||
InitializeLobbyBackground();
|
InitializeLobbyBackground();
|
||||||
InitializeGamePreset();
|
InitializeGamePreset();
|
||||||
DebugTools.Assert(_prototypeManager.Index<JobPrototype>(FallbackOverflowJob).Name == FallbackOverflowJobName,
|
DebugTools.Assert(_prototypeManager.Index<JobPrototype>(FallbackOverflowJob).Name == FallbackOverflowJobName,
|
||||||
|
|||||||
29
Content.Shared/Audio/Events/LobbyPlaylistChangedEvent.cs
Normal file
29
Content.Shared/Audio/Events/LobbyPlaylistChangedEvent.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Audio.Events;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event of changing lobby music playlist (on server).
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class LobbyPlaylistChangedEvent : EntityEventArgs
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public LobbyPlaylistChangedEvent(string[] playlist)
|
||||||
|
{
|
||||||
|
Playlist = playlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List of soundtrack filenames for lobby playlist.
|
||||||
|
/// </summary>
|
||||||
|
public string[] Playlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event of stopping lobby music.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class LobbyMusicStopEvent : EntityEventArgs
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -78,7 +78,6 @@ namespace Content.Shared.GameTicking
|
|||||||
public sealed class TickerLobbyStatusEvent : EntityEventArgs
|
public sealed class TickerLobbyStatusEvent : EntityEventArgs
|
||||||
{
|
{
|
||||||
public bool IsRoundStarted { get; }
|
public bool IsRoundStarted { get; }
|
||||||
public string? LobbySong { get; }
|
|
||||||
public string? LobbyBackground { get; }
|
public string? LobbyBackground { get; }
|
||||||
public bool YouAreReady { get; }
|
public bool YouAreReady { get; }
|
||||||
// UTC.
|
// UTC.
|
||||||
@@ -86,10 +85,9 @@ namespace Content.Shared.GameTicking
|
|||||||
public TimeSpan RoundStartTimeSpan { get; }
|
public TimeSpan RoundStartTimeSpan { get; }
|
||||||
public bool Paused { get; }
|
public bool Paused { get; }
|
||||||
|
|
||||||
public TickerLobbyStatusEvent(bool isRoundStarted, string? lobbySong, string? lobbyBackground, bool youAreReady, TimeSpan startTime, TimeSpan preloadTime, TimeSpan roundStartTimeSpan, bool paused)
|
public TickerLobbyStatusEvent(bool isRoundStarted, string? lobbyBackground, bool youAreReady, TimeSpan startTime, TimeSpan preloadTime, TimeSpan roundStartTimeSpan, bool paused)
|
||||||
{
|
{
|
||||||
IsRoundStarted = isRoundStarted;
|
IsRoundStarted = isRoundStarted;
|
||||||
LobbySong = lobbySong;
|
|
||||||
LobbyBackground = lobbyBackground;
|
LobbyBackground = lobbyBackground;
|
||||||
YouAreReady = youAreReady;
|
YouAreReady = youAreReady;
|
||||||
StartTime = startTime;
|
StartTime = startTime;
|
||||||
@@ -185,7 +183,6 @@ namespace Content.Shared.GameTicking
|
|||||||
public int RoundId { get; }
|
public int RoundId { get; }
|
||||||
public int PlayerCount { get; }
|
public int PlayerCount { get; }
|
||||||
public RoundEndPlayerInfo[] AllPlayersEndInfo { get; }
|
public RoundEndPlayerInfo[] AllPlayersEndInfo { get; }
|
||||||
public string? LobbySong;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sound gets networked due to how entity lifecycle works between client / server and to avoid clipping.
|
/// Sound gets networked due to how entity lifecycle works between client / server and to avoid clipping.
|
||||||
@@ -199,7 +196,6 @@ namespace Content.Shared.GameTicking
|
|||||||
int roundId,
|
int roundId,
|
||||||
int playerCount,
|
int playerCount,
|
||||||
RoundEndPlayerInfo[] allPlayersEndInfo,
|
RoundEndPlayerInfo[] allPlayersEndInfo,
|
||||||
string? lobbySong,
|
|
||||||
string? restartSound)
|
string? restartSound)
|
||||||
{
|
{
|
||||||
GamemodeTitle = gamemodeTitle;
|
GamemodeTitle = gamemodeTitle;
|
||||||
@@ -208,7 +204,6 @@ namespace Content.Shared.GameTicking
|
|||||||
RoundId = roundId;
|
RoundId = roundId;
|
||||||
PlayerCount = playerCount;
|
PlayerCount = playerCount;
|
||||||
AllPlayersEndInfo = allPlayersEndInfo;
|
AllPlayersEndInfo = allPlayersEndInfo;
|
||||||
LobbySong = lobbySong;
|
|
||||||
RestartSound = restartSound;
|
RestartSound = restartSound;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user