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,19 +1,37 @@
|
||||
using System.Linq;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.GameTicking.Events;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.Audio.Events;
|
||||
using Content.Shared.GameTicking;
|
||||
using Robust.Server.Audio;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.Audio;
|
||||
|
||||
public sealed class ContentAudioSystem : SharedContentAudioSystem
|
||||
{
|
||||
[ValidatePrototypeId<SoundCollectionPrototype>]
|
||||
private const string LobbyMusicCollection = "LobbyMusic";
|
||||
|
||||
[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()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
_lobbyMusicCollection = _prototypeManager.Index<SoundCollectionPrototype>(LobbyMusicCollection);
|
||||
_lobbyPlaylist = ShuffleLobbyPlaylist();
|
||||
|
||||
SubscribeLocalEvent<RoundEndMessageEvent>(OnRoundEnd);
|
||||
SubscribeLocalEvent<PlayerJoinedLobbyEvent>(OnPlayerJoinedLobby);
|
||||
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundCleanup);
|
||||
SubscribeLocalEvent<RoundStartingEvent>(OnRoundStart);
|
||||
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnProtoReload);
|
||||
@@ -36,4 +54,33 @@ public sealed class ContentAudioSystem : SharedContentAudioSystem
|
||||
// yeah it's whacky af.
|
||||
_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)
|
||||
{
|
||||
_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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
// 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);
|
||||
SendRoundEndDiscordMessage();
|
||||
}
|
||||
@@ -394,8 +388,17 @@ namespace Content.Server.GameTicking
|
||||
var listOfPlayerInfoFinal = listOfPlayerInfo.OrderBy(pi => pi.PlayerOOCName).ToArray();
|
||||
var sound = RoundEndSoundCollection == null ? null : _audio.GetSound(new SoundCollectionSpecifier(RoundEndSoundCollection));
|
||||
|
||||
RaiseNetworkEvent(new RoundEndMessageEvent(gamemodeTitle, roundEndText, roundDuration, RoundId,
|
||||
listOfPlayerInfoFinal.Length, listOfPlayerInfoFinal, LobbySong, sound));
|
||||
var roundEndMessageEvent = new RoundEndMessageEvent(
|
||||
gamemodeTitle,
|
||||
roundEndText,
|
||||
roundDuration,
|
||||
RoundId,
|
||||
listOfPlayerInfoFinal.Length,
|
||||
listOfPlayerInfoFinal,
|
||||
sound
|
||||
);
|
||||
RaiseNetworkEvent(roundEndMessageEvent);
|
||||
RaiseLocalEvent(roundEndMessageEvent);
|
||||
|
||||
_replayRoundPlayerInfo = listOfPlayerInfoFinal;
|
||||
_replayRoundText = roundEndText;
|
||||
|
||||
@@ -93,7 +93,6 @@ namespace Content.Server.GameTicking
|
||||
InitializeStatusShell();
|
||||
InitializeCVars();
|
||||
InitializePlayer();
|
||||
InitializeLobbyMusic();
|
||||
InitializeLobbyBackground();
|
||||
InitializeGamePreset();
|
||||
DebugTools.Assert(_prototypeManager.Index<JobPrototype>(FallbackOverflowJob).Name == FallbackOverflowJobName,
|
||||
|
||||
Reference in New Issue
Block a user