From 8b4a4026418a5abf745c39c8ae57f760ecce797d Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Fri, 16 Aug 2024 22:14:29 -0700 Subject: [PATCH] allow playing multiple announcement sounds at once --- .../Announcements/Systems/AnnouncerSystem.cs | 53 +++++-- Content.Client/Options/UI/Tabs/AudioTab.xaml | 3 + .../Options/UI/Tabs/AudioTab.xaml.cs | 150 +++++++++--------- Content.Shared/CCVar/CCVars.cs | 10 +- .../en-US/escape-menu/ui/options-menu.ftl | 2 + 5 files changed, 128 insertions(+), 90 deletions(-) diff --git a/Content.Client/Announcements/Systems/AnnouncerSystem.cs b/Content.Client/Announcements/Systems/AnnouncerSystem.cs index de76396f705..2ce419b7881 100644 --- a/Content.Client/Announcements/Systems/AnnouncerSystem.cs +++ b/Content.Client/Announcements/Systems/AnnouncerSystem.cs @@ -1,3 +1,4 @@ +using System.Linq; using Content.Client.Audio; using Content.Shared.Announcements.Events; using Content.Shared.Announcements.Systems; @@ -18,8 +19,8 @@ public sealed class AnnouncerSystem : SharedAnnouncerSystem [Dependency] private readonly IResourceCache _cache = default!; [Dependency] private readonly IAudioManager _audioManager = default!; - private IAudioSource? AnnouncerSource { get; set; } - private float AnnouncerVolume { get; set; } + public List AnnouncerSources { get; } = new(); + public float AnnouncerVolume { get; private set; } public override void Initialize() @@ -28,8 +29,10 @@ public override void Initialize() AnnouncerVolume = _config.GetCVar(CCVars.AnnouncerVolume) * 100f / ContentAudioSystem.AnnouncerMultiplier; - SubscribeNetworkEvent(OnAnnouncementReceived); _config.OnValueChanged(CCVars.AnnouncerVolume, OnAnnouncerVolumeChanged); + _config.OnValueChanged(CCVars.AnnouncerDisableMultipleSounds, OnAnnouncerDisableMultipleSounds); + + SubscribeNetworkEvent(OnAnnouncementReceived); } public override void Shutdown() @@ -37,6 +40,7 @@ public override void Shutdown() base.Shutdown(); _config.UnsubValueChanged(CCVars.AnnouncerVolume, OnAnnouncerVolumeChanged); + _config.UnsubValueChanged(CCVars.AnnouncerDisableMultipleSounds, OnAnnouncerDisableMultipleSounds); } @@ -44,10 +48,23 @@ private void OnAnnouncerVolumeChanged(float value) { AnnouncerVolume = value; - if (AnnouncerSource != null) - AnnouncerSource.Gain = AnnouncerVolume; + foreach (var source in AnnouncerSources) + source.Gain = AnnouncerVolume; } + private void OnAnnouncerDisableMultipleSounds(bool value) + { + if (!value) + return; + + foreach (var audioSource in AnnouncerSources.ToList()) + { + audioSource.Dispose(); + AnnouncerSources.Remove(audioSource); + } + } + + private void OnAnnouncementReceived(AnnouncementSendEvent ev) { if (!ev.Recipients.Contains(_player.LocalSession!.UserId) @@ -56,14 +73,28 @@ private void OnAnnouncementReceived(AnnouncementSendEvent ev) return; var source = _audioManager.CreateAudioSource(resource); - if (source != null) + if (source == null) + return; + + source.Gain = AnnouncerVolume * SharedAudioSystem.VolumeToGain(ev.AudioParams.Volume); + source.Global = true; + + if (_config.GetCVar(CCVars.AnnouncerDisableMultipleSounds)) + { + foreach (var audioSource in AnnouncerSources.ToList()) + { + audioSource.Dispose(); + AnnouncerSources.Remove(audioSource); + } + } + + foreach (var audioSource in AnnouncerSources.ToList().Where(audioSource => !audioSource.Playing)) { - source.Gain = AnnouncerVolume * SharedAudioSystem.VolumeToGain(ev.AudioParams.Volume); - source.Global = true; + audioSource.Dispose(); + AnnouncerSources.Remove(audioSource); } - AnnouncerSource?.Dispose(); - AnnouncerSource = source; - AnnouncerSource?.StartPlaying(); + AnnouncerSources.Add(source); + source.StartPlaying(); } } diff --git a/Content.Client/Options/UI/Tabs/AudioTab.xaml b/Content.Client/Options/UI/Tabs/AudioTab.xaml index 8dd723d446d..78b0e82629e 100644 --- a/Content.Client/Options/UI/Tabs/AudioTab.xaml +++ b/Content.Client/Options/UI/Tabs/AudioTab.xaml @@ -117,6 +117,9 @@ + diff --git a/Content.Client/Options/UI/Tabs/AudioTab.xaml.cs b/Content.Client/Options/UI/Tabs/AudioTab.xaml.cs index 0207ed5c471..7da80d774bd 100644 --- a/Content.Client/Options/UI/Tabs/AudioTab.xaml.cs +++ b/Content.Client/Options/UI/Tabs/AudioTab.xaml.cs @@ -30,97 +30,89 @@ public AudioTab() ApplyButton.OnPressed += OnApplyButtonPressed; ResetButton.OnPressed += OnResetButtonPressed; - MasterVolumeSlider.OnValueChanged += OnMasterVolumeSliderChanged; - MidiVolumeSlider.OnValueChanged += OnMidiVolumeSliderChanged; - AmbientMusicVolumeSlider.OnValueChanged += OnAmbientMusicVolumeSliderChanged; - AmbienceVolumeSlider.OnValueChanged += OnAmbienceVolumeSliderChanged; - AmbienceSoundsSlider.OnValueChanged += OnAmbienceSoundsSliderChanged; - LobbyVolumeSlider.OnValueChanged += OnLobbyVolumeSliderChanged; - InterfaceVolumeSlider.OnValueChanged += OnInterfaceVolumeSliderChanged; - AnnouncerVolumeSlider.OnValueChanged += OnAnnouncerVolumeSliderChanged; - LobbyMusicCheckBox.OnToggled += OnLobbyMusicCheckToggled; - RestartSoundsCheckBox.OnToggled += OnRestartSoundsCheckToggled; - EventMusicCheckBox.OnToggled += OnEventMusicCheckToggled; - AdminSoundsCheckBox.OnToggled += OnAdminSoundsCheckToggled; + + AttachUpdateChangesHandler( + MasterVolumeSlider, + MidiVolumeSlider, + AmbientMusicVolumeSlider, + AmbienceVolumeSlider, + AmbienceSoundsSlider, + LobbyVolumeSlider, + InterfaceVolumeSlider, + AnnouncerVolumeSlider, + + LobbyMusicCheckBox, + RestartSoundsCheckBox, + EventMusicCheckBox, + AnnouncerDisableMultipleSoundsCheckBox, + AdminSoundsCheckBox + ); AmbienceSoundsSlider.MinValue = _cfg.GetCVar(CCVars.MinMaxAmbientSourcesConfigured); AmbienceSoundsSlider.MaxValue = _cfg.GetCVar(CCVars.MaxMaxAmbientSourcesConfigured); Reset(); + return; + + void AttachUpdateChangesHandler(params Control[] controls) + { + foreach (var control in controls) + { + switch (control) + { + case Slider slider: + slider.OnValueChanged += _ => UpdateChanges(); + break; + case CheckBox checkBox: + checkBox.OnToggled += _ => UpdateChanges(); + break; + } + } + } } protected override void Dispose(bool disposing) { ApplyButton.OnPressed -= OnApplyButtonPressed; ResetButton.OnPressed -= OnResetButtonPressed; - MasterVolumeSlider.OnValueChanged -= OnMasterVolumeSliderChanged; - MidiVolumeSlider.OnValueChanged -= OnMidiVolumeSliderChanged; - AmbientMusicVolumeSlider.OnValueChanged -= OnAmbientMusicVolumeSliderChanged; - AmbienceVolumeSlider.OnValueChanged -= OnAmbienceVolumeSliderChanged; - LobbyVolumeSlider.OnValueChanged -= OnLobbyVolumeSliderChanged; - InterfaceVolumeSlider.OnValueChanged -= OnInterfaceVolumeSliderChanged; - AnnouncerVolumeSlider.OnValueChanged -= OnAnnouncerVolumeSliderChanged; - base.Dispose(disposing); - } - - private void OnLobbyVolumeSliderChanged(Range obj) - { - UpdateChanges(); - } - - private void OnInterfaceVolumeSliderChanged(Range obj) - { - UpdateChanges(); - } - - private void OnAmbientMusicVolumeSliderChanged(Range obj) - { - UpdateChanges(); - } - - private void OnAmbienceVolumeSliderChanged(Range obj) - { - UpdateChanges(); - } - - private void OnAmbienceSoundsSliderChanged(Range obj) - { - UpdateChanges(); - } - private void OnMasterVolumeSliderChanged(Range range) - { - _audio.SetMasterGain(MasterVolumeSlider.Value / 100f * ContentAudioSystem.MasterVolumeMultiplier); - UpdateChanges(); - } - - private void OnMidiVolumeSliderChanged(Range range) - { - UpdateChanges(); - } - - private void OnAnnouncerVolumeSliderChanged(Range range) - { - UpdateChanges(); - } + DetachUpdateChangesHandler( + MasterVolumeSlider, + MidiVolumeSlider, + AmbientMusicVolumeSlider, + AmbienceVolumeSlider, + AmbienceSoundsSlider, + LobbyVolumeSlider, + InterfaceVolumeSlider, + AnnouncerVolumeSlider, + + LobbyMusicCheckBox, + RestartSoundsCheckBox, + EventMusicCheckBox, + AnnouncerDisableMultipleSoundsCheckBox, + AdminSoundsCheckBox + ); - private void OnLobbyMusicCheckToggled(BaseButton.ButtonEventArgs args) - { - UpdateChanges(); - } - private void OnRestartSoundsCheckToggled(BaseButton.ButtonEventArgs args) - { - UpdateChanges(); - } - private void OnEventMusicCheckToggled(BaseButton.ButtonEventArgs args) - { - UpdateChanges(); + base.Dispose(disposing); + return; + + void DetachUpdateChangesHandler(params Control[] controls) + { + foreach (var control in controls) + { + switch (control) + { + case Slider slider: + slider.OnValueChanged -= _ => UpdateChanges(); + break; + case CheckBox checkBox: + checkBox.OnToggled -= _ => UpdateChanges(); + break; + } + } + } } - private void OnAdminSoundsCheckToggled(BaseButton.ButtonEventArgs args) - { - UpdateChanges(); - } private void OnApplyButtonPressed(BaseButton.ButtonEventArgs args) { @@ -139,6 +131,7 @@ private void OnApplyButtonPressed(BaseButton.ButtonEventArgs args) _cfg.SetCVar(CCVars.LobbyMusicEnabled, LobbyMusicCheckBox.Pressed); _cfg.SetCVar(CCVars.RestartSoundsEnabled, RestartSoundsCheckBox.Pressed); _cfg.SetCVar(CCVars.EventMusicEnabled, EventMusicCheckBox.Pressed); + _cfg.SetCVar(CCVars.AnnouncerDisableMultipleSounds, AnnouncerDisableMultipleSoundsCheckBox.Pressed); _cfg.SetCVar(CCVars.AdminSoundsEnabled, AdminSoundsCheckBox.Pressed); _cfg.SaveToFile(); UpdateChanges(); @@ -164,6 +157,7 @@ private void Reset() LobbyMusicCheckBox.Pressed = _cfg.GetCVar(CCVars.LobbyMusicEnabled); RestartSoundsCheckBox.Pressed = _cfg.GetCVar(CCVars.RestartSoundsEnabled); EventMusicCheckBox.Pressed = _cfg.GetCVar(CCVars.EventMusicEnabled); + AnnouncerDisableMultipleSoundsCheckBox.Pressed = _cfg.GetCVar(CCVars.AnnouncerDisableMultipleSounds); AdminSoundsCheckBox.Pressed = _cfg.GetCVar(CCVars.AdminSoundsEnabled); UpdateChanges(); } @@ -190,10 +184,12 @@ private void UpdateChanges() var isLobbySame = LobbyMusicCheckBox.Pressed == _cfg.GetCVar(CCVars.LobbyMusicEnabled); var isRestartSoundsSame = RestartSoundsCheckBox.Pressed == _cfg.GetCVar(CCVars.RestartSoundsEnabled); var isEventSame = EventMusicCheckBox.Pressed == _cfg.GetCVar(CCVars.EventMusicEnabled); + var isAnnouncerDisableMultipleSoundsSame = AnnouncerDisableMultipleSoundsCheckBox.Pressed == _cfg.GetCVar(CCVars.AnnouncerDisableMultipleSounds); var isAdminSoundsSame = AdminSoundsCheckBox.Pressed == _cfg.GetCVar(CCVars.AdminSoundsEnabled); var isEverythingSame = isMasterVolumeSame && isMidiVolumeSame && isAmbientVolumeSame && isAmbientMusicVolumeSame && isAmbientSoundsSame && isLobbySame && isRestartSoundsSame && isEventSame - && isAdminSoundsSame && isLobbyVolumeSame && isInterfaceVolumeSame && isAnnouncerVolumeSame; + && isAnnouncerDisableMultipleSoundsSame && isAdminSoundsSame && isLobbyVolumeSame + && isInterfaceVolumeSame && isAnnouncerVolumeSame; ApplyButton.Disabled = isEverythingSame; ResetButton.Disabled = isEverythingSame; MasterVolumeLabel.Text = diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index ff2a915b1ba..d61b51cec10 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -466,6 +466,12 @@ public static readonly CVarDef public static readonly CVarDef AnnouncerVolume = CVarDef.Create("announcer.volume", 0.5f, CVar.ARCHIVE | CVar.CLIENTONLY); + /// + /// Disables multiple announcement sounds from playing at once + /// + public static readonly CVarDef AnnouncerDisableMultipleSounds = + CVarDef.Create("announcer.disable_multiple_sounds", false, CVar.ARCHIVE | CVar.CLIENTONLY); + /* * Queue @@ -2291,7 +2297,7 @@ public static readonly CVarDef /// public static readonly CVarDef StationGoalsChance = CVarDef.Create("game.station_goals_chance", 0.1f, CVar.SERVERONLY); - + #region CPR System /// @@ -2338,7 +2344,7 @@ public static readonly CVarDef /// public static readonly CVarDef CPRAirlossReductionMultiplier = CVarDef.Create("cpr.airloss_reduction_multiplier", 1f, CVar.REPLICATED | CVar.SERVER); - + #endregion #region Contests System diff --git a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl index 7b25b616b24..2eab749c35a 100644 --- a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl +++ b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl @@ -34,6 +34,8 @@ ui-options-announcer-volume = Announcer volume: ui-options-lobby-music = Lobby & Round-end Music ui-options-restart-sounds = Round Restart Sounds ui-options-event-music = Event Music +ui-options-announcer-disable-multiple-sounds = Disable Overlapping Announcer Sounds +ui-options-announcer-disable-multiple-sounds-tooltip = Some announcements will not sound right, this setting isn't recommended ui-options-admin-sounds = Play Admin Sounds ui-options-volume-label = Volume ui-options-volume-percent = { TOSTRING($volume, "P0") }