diff --git a/Content.Client/Audio/ClientGlobalSoundSystem.cs b/Content.Client/Audio/ClientGlobalSoundSystem.cs index 50c3971d95..882ab1be6d 100644 --- a/Content.Client/Audio/ClientGlobalSoundSystem.cs +++ b/Content.Client/Audio/ClientGlobalSoundSystem.cs @@ -66,7 +66,7 @@ public sealed class ClientGlobalSoundSystem : SharedGlobalSoundSystem { if(!_adminAudioEnabled) return; - var stream = _audio.PlayGlobal(soundEvent.Filename, Filter.Local(), false, soundEvent.AudioParams); + var stream = _audio.PlayGlobal(soundEvent.Specifier, Filter.Local(), false, soundEvent.AudioParams); _adminAudio.Add(stream?.Entity); } @@ -75,13 +75,13 @@ public sealed class ClientGlobalSoundSystem : SharedGlobalSoundSystem // Either the cvar is disabled or it's already playing if(!_eventAudioEnabled || _eventAudio.ContainsKey(soundEvent.Type)) return; - var stream = _audio.PlayGlobal(soundEvent.Filename, Filter.Local(), false, soundEvent.AudioParams); + var stream = _audio.PlayGlobal(soundEvent.Specifier, Filter.Local(), false, soundEvent.AudioParams); _eventAudio.Add(soundEvent.Type, stream?.Entity); } private void PlayGameSound(GameGlobalSoundEvent soundEvent) { - _audio.PlayGlobal(soundEvent.Filename, Filter.Local(), false, soundEvent.AudioParams); + _audio.PlayGlobal(soundEvent.Specifier, Filter.Local(), false, soundEvent.AudioParams); } private void StopStationEventMusic(StopStationEventMusic soundEvent) diff --git a/Content.Client/Audio/ContentAudioSystem.LobbyMusic.cs b/Content.Client/Audio/ContentAudioSystem.LobbyMusic.cs index 7d7d77f51a..fda2c0062c 100644 --- a/Content.Client/Audio/ContentAudioSystem.LobbyMusic.cs +++ b/Content.Client/Audio/ContentAudioSystem.LobbyMusic.cs @@ -218,7 +218,7 @@ public sealed partial class ContentAudioSystem return; var file = _gameTicker.RestartSound; - if (string.IsNullOrEmpty(file)) + if (ResolvedSoundSpecifier.IsNullOrEmpty(file)) { return; } diff --git a/Content.Client/Disposal/Systems/DisposalUnitSystem.cs b/Content.Client/Disposal/Systems/DisposalUnitSystem.cs index 2fe56fcce9..da548c1e54 100644 --- a/Content.Client/Disposal/Systems/DisposalUnitSystem.cs +++ b/Content.Client/Disposal/Systems/DisposalUnitSystem.cs @@ -144,7 +144,7 @@ public sealed class DisposalUnitSystem : SharedDisposalUnitSystem { KeyFrames = { - new AnimationTrackPlaySound.KeyFrame(_audioSystem.GetSound(unit.FlushSound), 0) + new AnimationTrackPlaySound.KeyFrame(_audioSystem.ResolveSound(unit.FlushSound), 0) } }); } diff --git a/Content.Client/GameTicking/Managers/ClientGameTicker.cs b/Content.Client/GameTicking/Managers/ClientGameTicker.cs index 3d5775a3c5..170b24c02a 100644 --- a/Content.Client/GameTicking/Managers/ClientGameTicker.cs +++ b/Content.Client/GameTicking/Managers/ClientGameTicker.cs @@ -10,6 +10,7 @@ using Robust.Client.Graphics; using Robust.Client.State; using Robust.Client.UserInterface; using Robust.Shared.Prototypes; +using Robust.Shared.Audio; namespace Content.Client.GameTicking.Managers { @@ -26,7 +27,7 @@ namespace Content.Client.GameTicking.Managers [ViewVariables] public bool AreWeReady { get; private set; } [ViewVariables] public bool IsGameStarted { get; private set; } - [ViewVariables] public string? RestartSound { get; private set; } + [ViewVariables] public ResolvedSoundSpecifier? RestartSound { get; private set; } [ViewVariables] public string? LobbyBackground { get; private set; } [ViewVariables] public bool DisallowedLateJoin { get; private set; } [ViewVariables] public string? ServerInfoBlob { get; private set; } diff --git a/Content.Client/Light/Visualizers/PoweredLightVisualizerSystem.cs b/Content.Client/Light/Visualizers/PoweredLightVisualizerSystem.cs index 2dc7f5a822..ee81641d26 100644 --- a/Content.Client/Light/Visualizers/PoweredLightVisualizerSystem.cs +++ b/Content.Client/Light/Visualizers/PoweredLightVisualizerSystem.cs @@ -122,7 +122,7 @@ public sealed class PoweredLightVisualizerSystem : VisualizerSystem pi.PlayerOOCName).ToArray(); - var sound = RoundEndSoundCollection == null ? null : _audio.GetSound(new SoundCollectionSpecifier(RoundEndSoundCollection)); + var sound = RoundEndSoundCollection == null ? null : _audio.ResolveSound(new SoundCollectionSpecifier(RoundEndSoundCollection)); var roundEndMessageEvent = new RoundEndMessageEvent( gamemodeTitle, diff --git a/Content.Server/Light/EntitySystems/HandheldLightSystem.cs b/Content.Server/Light/EntitySystems/HandheldLightSystem.cs index a1977d5a46..2c8d18539f 100644 --- a/Content.Server/Light/EntitySystems/HandheldLightSystem.cs +++ b/Content.Server/Light/EntitySystems/HandheldLightSystem.cs @@ -202,7 +202,7 @@ namespace Content.Server.Light.EntitySystems if (!_powerCell.TryGetBatteryFromSlot(uid, out var battery) && !TryComp(uid, out battery)) { - _audio.PlayPvs(_audio.GetSound(component.TurnOnFailSound), uid); + _audio.PlayPvs(_audio.ResolveSound(component.TurnOnFailSound), uid); _popup.PopupEntity(Loc.GetString("handheld-light-component-cell-missing-message"), uid, user); return false; } @@ -212,7 +212,7 @@ namespace Content.Server.Light.EntitySystems // Simple enough. if (component.Wattage > battery.CurrentCharge) { - _audio.PlayPvs(_audio.GetSound(component.TurnOnFailSound), uid); + _audio.PlayPvs(_audio.ResolveSound(component.TurnOnFailSound), uid); _popup.PopupEntity(Loc.GetString("handheld-light-component-cell-dead-message"), uid, user); return false; } diff --git a/Content.Server/Nuke/NukeSystem.cs b/Content.Server/Nuke/NukeSystem.cs index 84118931b1..aa1fe32401 100644 --- a/Content.Server/Nuke/NukeSystem.cs +++ b/Content.Server/Nuke/NukeSystem.cs @@ -49,7 +49,7 @@ public sealed class NukeSystem : EntitySystem /// Used to calculate when the nuke song should start playing for maximum kino with the nuke sfx /// private float _nukeSongLength; - private string _selectedNukeSong = String.Empty; + private ResolvedSoundSpecifier _selectedNukeSong = String.Empty; /// /// Time to leave between the nuke song and the nuke alarm playing. @@ -302,7 +302,7 @@ public sealed class NukeSystem : EntitySystem // Start playing the nuke event song so that it ends a couple seconds before the alert sound // should play - if (nuke.RemainingTime <= _nukeSongLength + nuke.AlertSoundTime + NukeSongBuffer && !nuke.PlayedNukeSong && !string.IsNullOrEmpty(_selectedNukeSong)) + if (nuke.RemainingTime <= _nukeSongLength + nuke.AlertSoundTime + NukeSongBuffer && !nuke.PlayedNukeSong && !ResolvedSoundSpecifier.IsNullOrEmpty(_selectedNukeSong)) { _sound.DispatchStationEventMusic(uid, _selectedNukeSong, StationEventMusicType.Nuke); nuke.PlayedNukeSong = true; @@ -311,7 +311,7 @@ public sealed class NukeSystem : EntitySystem // play alert sound if time is running out if (nuke.RemainingTime <= nuke.AlertSoundTime && !nuke.PlayedAlertSound) { - _sound.PlayGlobalOnStation(uid, _audio.GetSound(nuke.AlertSound), new AudioParams{Volume = -5f}); + _sound.PlayGlobalOnStation(uid, _audio.ResolveSound(nuke.AlertSound), new AudioParams{Volume = -5f}); _sound.StopStationEventMusic(uid, StationEventMusicType.Nuke); nuke.PlayedAlertSound = true; UpdateAppearance(uid, nuke); @@ -469,7 +469,7 @@ public sealed class NukeSystem : EntitySystem var posText = $"({x}, {y})"; // We are collapsing the randomness here, otherwise we would get separate random song picks for checking duration and when actually playing the song afterwards - _selectedNukeSong = _audio.GetSound(component.ArmMusic); + _selectedNukeSong = _audio.ResolveSound(component.ArmMusic); // warn a crew var announcement = Loc.GetString("nuke-component-announcement-armed", @@ -478,7 +478,7 @@ public sealed class NukeSystem : EntitySystem var sender = Loc.GetString("nuke-component-announcement-sender"); _chatSystem.DispatchStationAnnouncement(stationUid ?? uid, announcement, sender, false, null, Color.Red); - _sound.PlayGlobalOnStation(uid, _audio.GetSound(component.ArmSound)); + _sound.PlayGlobalOnStation(uid, _audio.ResolveSound(component.ArmSound)); _nukeSongLength = (float) _audio.GetAudioLength(_selectedNukeSong).TotalSeconds; // turn on the spinny light @@ -519,7 +519,7 @@ public sealed class NukeSystem : EntitySystem _chatSystem.DispatchStationAnnouncement(uid, announcement, sender, false); component.PlayedNukeSong = false; - _sound.PlayGlobalOnStation(uid, _audio.GetSound(component.DisarmSound)); + _sound.PlayGlobalOnStation(uid, _audio.ResolveSound(component.DisarmSound)); _sound.StopStationEventMusic(uid, StationEventMusicType.Nuke); // reset nuke remaining time to either itself or the minimum time, whichever is higher diff --git a/Content.Server/Nutrition/EntitySystems/CreamPieSystem.cs b/Content.Server/Nutrition/EntitySystems/CreamPieSystem.cs index b107e47c79..cdcfcc1f21 100644 --- a/Content.Server/Nutrition/EntitySystems/CreamPieSystem.cs +++ b/Content.Server/Nutrition/EntitySystems/CreamPieSystem.cs @@ -43,7 +43,7 @@ namespace Content.Server.Nutrition.EntitySystems { // The entity is deleted, so play the sound at its position rather than parenting var coordinates = Transform(uid).Coordinates; - _audio.PlayPvs(_audio.GetSound(creamPie.Sound), coordinates, AudioParams.Default.WithVariation(0.125f)); + _audio.PlayPvs(_audio.ResolveSound(creamPie.Sound), coordinates, AudioParams.Default.WithVariation(0.125f)); if (EntityManager.TryGetComponent(uid, out FoodComponent? foodComp)) { diff --git a/Content.Server/Radiation/Systems/GeigerSystem.cs b/Content.Server/Radiation/Systems/GeigerSystem.cs index a0bc5dd739..9b6ed31781 100644 --- a/Content.Server/Radiation/Systems/GeigerSystem.cs +++ b/Content.Server/Radiation/Systems/GeigerSystem.cs @@ -161,7 +161,7 @@ public sealed class GeigerSystem : SharedGeigerSystem if (!_player.TryGetSessionByEntity(component.User.Value, out var session)) return; - var sound = _audio.GetSound(sounds); + var sound = _audio.ResolveSound(sounds); var param = sounds.Params.WithLoop(true).WithVolume(-4f); component.Stream = _audio.PlayGlobal(sound, session, param)?.Entity; diff --git a/Content.Server/Salvage/Expeditions/SalvageExpeditionComponent.cs b/Content.Server/Salvage/Expeditions/SalvageExpeditionComponent.cs index ff3c8176fd..2fa54fd11f 100644 --- a/Content.Server/Salvage/Expeditions/SalvageExpeditionComponent.cs +++ b/Content.Server/Salvage/Expeditions/SalvageExpeditionComponent.cs @@ -56,5 +56,5 @@ public sealed partial class SalvageExpeditionComponent : SharedSalvageExpedition /// Song selected on MapInit so we can predict the audio countdown properly. /// [DataField] - public SoundPathSpecifier SelectedSong; + public ResolvedSoundSpecifier SelectedSong; } diff --git a/Content.Server/Salvage/SalvageSystem.Expeditions.cs b/Content.Server/Salvage/SalvageSystem.Expeditions.cs index 923880169d..65583b38f5 100644 --- a/Content.Server/Salvage/SalvageSystem.Expeditions.cs +++ b/Content.Server/Salvage/SalvageSystem.Expeditions.cs @@ -69,8 +69,7 @@ public sealed partial class SalvageSystem private void OnExpeditionMapInit(EntityUid uid, SalvageExpeditionComponent component, MapInitEvent args) { - var selectedFile = _audio.GetSound(component.Sound); - component.SelectedSong = new SoundPathSpecifier(selectedFile, component.Sound.Params); + component.SelectedSong = _audio.ResolveSound(component.Sound); } private void OnExpeditionShutdown(EntityUid uid, SalvageExpeditionComponent component, ComponentShutdown args) diff --git a/Content.Server/Salvage/SalvageSystem.Runner.cs b/Content.Server/Salvage/SalvageSystem.Runner.cs index 921d966709..98cff49f99 100644 --- a/Content.Server/Salvage/SalvageSystem.Runner.cs +++ b/Content.Server/Salvage/SalvageSystem.Runner.cs @@ -144,7 +144,7 @@ public sealed partial class SalvageSystem while (query.MoveNext(out var uid, out var comp)) { var remaining = comp.EndTime - _timing.CurTime; - var audioLength = _audio.GetAudioLength(comp.SelectedSong.Path.ToString()); + var audioLength = _audio.GetAudioLength(comp.SelectedSong); if (comp.Stage < ExpeditionStage.FinalCountdown && remaining < TimeSpan.FromSeconds(45)) { diff --git a/Content.Shared/Audio/SharedGlobalSoundSystem.cs b/Content.Shared/Audio/SharedGlobalSoundSystem.cs index 7ad07c21aa..b2ed5dc90d 100644 --- a/Content.Shared/Audio/SharedGlobalSoundSystem.cs +++ b/Content.Shared/Audio/SharedGlobalSoundSystem.cs @@ -14,11 +14,11 @@ public abstract class SharedGlobalSoundSystem : EntitySystem [Serializable, NetSerializable] public class GlobalSoundEvent : EntityEventArgs { - public string Filename; + public ResolvedSoundSpecifier Specifier; public AudioParams? AudioParams; - public GlobalSoundEvent(string filename, AudioParams? audioParams = null) + public GlobalSoundEvent(ResolvedSoundSpecifier specifier, AudioParams? audioParams = null) { - Filename = filename; + Specifier = specifier; AudioParams = audioParams; } } @@ -29,7 +29,7 @@ public class GlobalSoundEvent : EntityEventArgs [Serializable, NetSerializable] public sealed class AdminSoundEvent : GlobalSoundEvent { - public AdminSoundEvent(string filename, AudioParams? audioParams = null) : base(filename, audioParams){} + public AdminSoundEvent(ResolvedSoundSpecifier specifier, AudioParams? audioParams = null) : base(specifier, audioParams){} } /// @@ -38,7 +38,7 @@ public sealed class AdminSoundEvent : GlobalSoundEvent [Serializable, NetSerializable] public sealed class GameGlobalSoundEvent : GlobalSoundEvent { - public GameGlobalSoundEvent(string filename, AudioParams? audioParams = null) : base(filename, audioParams){} + public GameGlobalSoundEvent(ResolvedSoundSpecifier specifier, AudioParams? audioParams = null) : base(specifier, audioParams){} } public enum StationEventMusicType : byte @@ -54,8 +54,8 @@ public sealed class StationEventMusicEvent : GlobalSoundEvent { public StationEventMusicType Type; - public StationEventMusicEvent(string filename, StationEventMusicType type, AudioParams? audioParams = null) : base( - filename, audioParams) + public StationEventMusicEvent(ResolvedSoundSpecifier specifier, StationEventMusicType type, AudioParams? audioParams = null) : base( + specifier, audioParams) { Type = type; } diff --git a/Content.Shared/GameTicking/SharedGameTicker.cs b/Content.Shared/GameTicking/SharedGameTicker.cs index 015889b152..050d4826cb 100644 --- a/Content.Shared/GameTicking/SharedGameTicker.cs +++ b/Content.Shared/GameTicking/SharedGameTicker.cs @@ -6,6 +6,7 @@ using Robust.Shared.Serialization; using Robust.Shared.Serialization.Markdown.Mapping; using Robust.Shared.Serialization.Markdown.Value; using Robust.Shared.Timing; +using Robust.Shared.Audio; namespace Content.Shared.GameTicking { @@ -196,7 +197,7 @@ namespace Content.Shared.GameTicking /// /// Sound gets networked due to how entity lifecycle works between client / server and to avoid clipping. /// - public string? RestartSound; + public ResolvedSoundSpecifier? RestartSound; public RoundEndMessageEvent( string gamemodeTitle, @@ -205,7 +206,7 @@ namespace Content.Shared.GameTicking int roundId, int playerCount, RoundEndPlayerInfo[] allPlayersEndInfo, - string? restartSound) + ResolvedSoundSpecifier? restartSound) { GamemodeTitle = gamemodeTitle; RoundEndText = roundEndText; diff --git a/Content.Shared/Sound/SharedEmitSoundSystem.cs b/Content.Shared/Sound/SharedEmitSoundSystem.cs index 30744b6864..67aabbb74d 100644 --- a/Content.Shared/Sound/SharedEmitSoundSystem.cs +++ b/Content.Shared/Sound/SharedEmitSoundSystem.cs @@ -187,7 +187,7 @@ public abstract class SharedEmitSoundSystem : EntitySystem if (_netMan.IsServer && sound != null) { - _audioSystem.PlayPvs(_audioSystem.GetSound(sound), uid, AudioParams.Default.WithVolume(volume)); + _audioSystem.PlayPvs(_audioSystem.ResolveSound(sound), uid, AudioParams.Default.WithVolume(volume)); } }