diff --git a/Content.Client/Audio/BackgroundAudioSystem.cs b/Content.Client/Audio/BackgroundAudioSystem.cs index 7a308de4a9..46e7d03211 100644 --- a/Content.Client/Audio/BackgroundAudioSystem.cs +++ b/Content.Client/Audio/BackgroundAudioSystem.cs @@ -1,19 +1,24 @@ +using System.Threading; using Content.Client.GameTicking.Managers; using Content.Client.Lobby; using Content.Client.Viewport; using Content.Shared; using Content.Shared.Audio; using Content.Shared.CCVar; +using Content.Shared.Maps; using JetBrains.Annotations; using Robust.Client; +using Robust.Client.Player; using Robust.Client.State; using Robust.Shared.Audio; using Robust.Shared.Configuration; using Robust.Shared.GameObjects; using Robust.Shared.IoC; +using Robust.Shared.Map; using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; +using Timer = Robust.Shared.Timing.Timer; namespace Content.Client.Audio { @@ -26,8 +31,9 @@ namespace Content.Client.Audio [Dependency] private readonly IStateManager _stateManager = default!; [Dependency] private readonly IBaseClient _client = default!; [Dependency] private readonly ClientGameTicker _gameTicker = default!; - - private SoundCollectionPrototype _ambientCollection = default!; + [Dependency] private readonly IMapManager _mapManager = default!; + [Dependency] private readonly ITileDefinitionManager _tileDefMan = default!; + [Dependency] private readonly IPlayerManager _playMan = default!; private readonly AudioParams _ambientParams = new(-10f, 1, "Master", 0, 0, 0, true, 0f); private readonly AudioParams _lobbyParams = new(-5f, 1, "Master", 0, 0, 0, true, 0f); @@ -35,14 +41,26 @@ namespace Content.Client.Audio private IPlayingAudioStream? _ambientStream; private IPlayingAudioStream? _lobbyStream; + private SoundCollectionPrototype _currentCollection = default!; + private CancellationTokenSource _timerCancelTokenSource = new(); + + private SoundCollectionPrototype _spaceAmbience = default!; + private SoundCollectionPrototype _stationAmbience = default!; + public override void Initialize() { base.Initialize(); - _ambientCollection = _prototypeManager.Index("AmbienceBase"); + _stationAmbience = _prototypeManager.Index("StationAmbienceBase"); + _spaceAmbience = _prototypeManager.Index("SpaceAmbienceBase"); + _currentCollection = _stationAmbience; _configManager.OnValueChanged(CCVars.AmbienceVolume, AmbienceCVarChanged); _configManager.OnValueChanged(CCVars.LobbyMusicEnabled, LobbyMusicCVarChanged); + _configManager.OnValueChanged(CCVars.StationAmbienceEnabled, StationAmbienceCVarChanged); + _configManager.OnValueChanged(CCVars.SpaceAmbienceEnabled, SpaceAmbienceCVarChanged); + + SubscribeLocalEvent(EntParentChanged); _stateManager.OnStateChanged += StateManagerOnStateChanged; @@ -67,6 +85,36 @@ namespace Content.Client.Audio EndLobbyMusic(); } + private void EntParentChanged(ref EntParentChangedMessage message) + { + if(_playMan.LocalPlayer is null || _playMan.LocalPlayer.ControlledEntity != message.Entity) return; + if (!TryComp(message.Entity, out var xform) || + !_mapManager.TryGetGrid(xform.GridID, out var grid)) return; + + var tileDef = (ContentTileDefinition) _tileDefMan[grid.GetTileRef(xform.Coordinates).Tile.TypeId]; + + if(_currentCollection.ID == _spaceAmbience.ID) + { + if (!tileDef.Sturdy) return; + ChangeAmbience(_stationAmbience); + + } + else // currently station + { + if (tileDef.Sturdy) return; + ChangeAmbience(_spaceAmbience); + } + } + + private void ChangeAmbience(SoundCollectionPrototype newAmbience) + { + EndAmbience(); + _currentCollection = newAmbience; + _timerCancelTokenSource.Cancel(); + _timerCancelTokenSource = new(); + Timer.Spawn(1500, StartAmbience, _timerCancelTokenSource.Token); + } + private void StateManagerOnStateChanged(StateChangedEventArgs args) { EndAmbience(); @@ -122,7 +170,8 @@ namespace Content.Client.Audio private void StartAmbience() { EndAmbience(); - var file = _robustRandom.Pick(_ambientCollection.PickFiles).ToString(); + if (!CanPlayCollection(_currentCollection)) return; + var file = _robustRandom.Pick(_currentCollection.PickFiles).ToString(); _ambientStream = SoundSystem.Play(Filter.Local(), file, _ambientParams.WithVolume(_ambientParams.Volume + _configManager.GetCVar(CCVars.AmbienceVolume))); } @@ -132,6 +181,40 @@ namespace Content.Client.Audio _ambientStream = null; } + private bool CanPlayCollection(SoundCollectionPrototype collection) + { + if (collection.ID == _spaceAmbience.ID) + return _configManager.GetCVar(CCVars.SpaceAmbienceEnabled); + if (collection.ID == _stationAmbience.ID) + return _configManager.GetCVar(CCVars.StationAmbienceEnabled); + + return true; + } + + private void StationAmbienceCVarChanged(bool enabled) + { + if (enabled && _stateManager.CurrentState is GameScreen && _currentCollection.ID == _stationAmbience.ID) + { + StartAmbience(); + } + else if(_currentCollection.ID == _stationAmbience.ID) + { + EndAmbience(); + } + } + + private void SpaceAmbienceCVarChanged(bool enabled) + { + if (enabled && _stateManager.CurrentState is GameScreen && _currentCollection.ID == _spaceAmbience.ID) + { + StartAmbience(); + } + else if(_currentCollection.ID == _spaceAmbience.ID) + { + EndAmbience(); + } + } + private void LobbyMusicCVarChanged(bool musicEnabled) { if (!musicEnabled) diff --git a/Content.Client/EscapeMenu/UI/Tabs/AudioTab.xaml b/Content.Client/EscapeMenu/UI/Tabs/AudioTab.xaml index b6f235ab2b..ddeff7f2f6 100644 --- a/Content.Client/EscapeMenu/UI/Tabs/AudioTab.xaml +++ b/Content.Client/EscapeMenu/UI/Tabs/AudioTab.xaml @@ -63,6 +63,8 @@ + + diff --git a/Content.Client/EscapeMenu/UI/Tabs/AudioTab.xaml.cs b/Content.Client/EscapeMenu/UI/Tabs/AudioTab.xaml.cs index 84100ef33d..696c8bf083 100644 --- a/Content.Client/EscapeMenu/UI/Tabs/AudioTab.xaml.cs +++ b/Content.Client/EscapeMenu/UI/Tabs/AudioTab.xaml.cs @@ -22,6 +22,8 @@ namespace Content.Client.EscapeMenu.UI.Tabs IoCManager.InjectDependencies(this); LobbyMusicCheckBox.Pressed = _cfg.GetCVar(CCVars.LobbyMusicEnabled); + StationAmbienceCheckBox.Pressed = _cfg.GetCVar(CCVars.StationAmbienceEnabled); + SpaceAmbienceCheckBox.Pressed = _cfg.GetCVar(CCVars.SpaceAmbienceEnabled); ApplyButton.OnPressed += OnApplyButtonPressed; ResetButton.OnPressed += OnResetButtonPressed; @@ -30,6 +32,8 @@ namespace Content.Client.EscapeMenu.UI.Tabs AmbienceVolumeSlider.OnValueChanged += OnAmbienceVolumeSliderChanged; AmbienceSoundsSlider.OnValueChanged += OnAmbienceSoundsSliderChanged; LobbyMusicCheckBox.OnToggled += OnLobbyMusicCheckToggled; + StationAmbienceCheckBox.OnToggled += OnStationAmbienceCheckToggled; + SpaceAmbienceCheckBox.OnToggled += OnSpaceAmbienceCheckToggled; AmbienceSoundsSlider.MinValue = _cfg.GetCVar(CCVars.MinMaxAmbientSourcesConfigured); AmbienceSoundsSlider.MaxValue = _cfg.GetCVar(CCVars.MaxMaxAmbientSourcesConfigured); @@ -73,6 +77,16 @@ namespace Content.Client.EscapeMenu.UI.Tabs UpdateChanges(); } + private void OnStationAmbienceCheckToggled(BaseButton.ButtonEventArgs args) + { + UpdateChanges(); + } + + private void OnSpaceAmbienceCheckToggled(BaseButton.ButtonEventArgs args) + { + UpdateChanges(); + } + private void OnApplyButtonPressed(BaseButton.ButtonEventArgs args) { _cfg.SetCVar(CVars.AudioMasterVolume, MasterVolumeSlider.Value / 100); @@ -80,6 +94,8 @@ namespace Content.Client.EscapeMenu.UI.Tabs _cfg.SetCVar(CCVars.AmbienceVolume, LV100ToDB(AmbienceVolumeSlider.Value)); _cfg.SetCVar(CCVars.MaxAmbientSources, (int)AmbienceSoundsSlider.Value); _cfg.SetCVar(CCVars.LobbyMusicEnabled, LobbyMusicCheckBox.Pressed); + _cfg.SetCVar(CCVars.StationAmbienceEnabled, StationAmbienceCheckBox.Pressed); + _cfg.SetCVar(CCVars.SpaceAmbienceEnabled, SpaceAmbienceCheckBox.Pressed); _cfg.SaveToFile(); UpdateChanges(); } @@ -96,6 +112,8 @@ namespace Content.Client.EscapeMenu.UI.Tabs AmbienceVolumeSlider.Value = DBToLV100(_cfg.GetCVar(CCVars.AmbienceVolume)); AmbienceSoundsSlider.Value = _cfg.GetCVar(CCVars.MaxAmbientSources); LobbyMusicCheckBox.Pressed = _cfg.GetCVar(CCVars.LobbyMusicEnabled); + StationAmbienceCheckBox.Pressed = _cfg.GetCVar(CCVars.StationAmbienceEnabled); + SpaceAmbienceCheckBox.Pressed = _cfg.GetCVar(CCVars.SpaceAmbienceEnabled); UpdateChanges(); } @@ -122,7 +140,9 @@ namespace Content.Client.EscapeMenu.UI.Tabs Math.Abs(AmbienceVolumeSlider.Value - DBToLV100(_cfg.GetCVar(CCVars.AmbienceVolume))) < 0.01f; var isAmbientSoundsSame = (int)AmbienceSoundsSlider.Value == _cfg.GetCVar(CCVars.MaxAmbientSources); var isLobbySame = LobbyMusicCheckBox.Pressed == _cfg.GetCVar(CCVars.LobbyMusicEnabled); - var isEverythingSame = isMasterVolumeSame && isMidiVolumeSame && isAmbientVolumeSame && isAmbientSoundsSame && isLobbySame; + var isStationAmbienceSame = StationAmbienceCheckBox.Pressed == _cfg.GetCVar(CCVars.StationAmbienceEnabled); + var isSpaceAmbienceSame = SpaceAmbienceCheckBox.Pressed == _cfg.GetCVar(CCVars.SpaceAmbienceEnabled); + var isEverythingSame = isMasterVolumeSame && isMidiVolumeSame && isAmbientVolumeSame && isAmbientSoundsSame && isLobbySame && isStationAmbienceSame && isSpaceAmbienceSame; ApplyButton.Disabled = isEverythingSame; ResetButton.Disabled = isEverythingSame; MasterVolumeLabel.Text = diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index 923058e1bb..40a91cdc8e 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -56,6 +56,19 @@ namespace Content.Shared.CCVar /// public static readonly CVarDef AmbienceVolume = CVarDef.Create("ambience.volume", 0.0f, CVar.ARCHIVE | CVar.CLIENTONLY); + + /// + /// Whether to play the station ambience (humming) sound + /// + public static readonly CVarDef StationAmbienceEnabled = + CVarDef.Create("ambience.station_ambience", true, CVar.ARCHIVE | CVar.CLIENTONLY); + + /// + /// Whether to play the space ambience + /// + public static readonly CVarDef SpaceAmbienceEnabled = + CVarDef.Create("ambience.space_ambience", true, CVar.ARCHIVE | CVar.CLIENTONLY); + /* * Status */ diff --git a/Resources/Audio/Ambience/constellations.ogg b/Resources/Audio/Ambience/constellations.ogg new file mode 100644 index 0000000000..75e9c0d3cc Binary files /dev/null and b/Resources/Audio/Ambience/constellations.ogg differ diff --git a/Resources/Audio/Ambience/license.txt b/Resources/Audio/Ambience/license.txt index 671b6ca79c..27f8a93909 100644 --- a/Resources/Audio/Ambience/license.txt +++ b/Resources/Audio/Ambience/license.txt @@ -1 +1,3 @@ shipambience.ogg from /tg/station (commit https://github.com/tgstation/tgstation/blob/66a625e6df15eaa97e599248a2281c74238ce26e/sound/ambience/shipambience.ogg), which took it from CEV Eris (commit https://github.com/discordia-space/CEV-Eris/blob/e4e40d38424afe88c8a81cf0e3857d8af4ef077f/sound/ambience/shipambience.ogg). Licensed under CC-BY-SA. +starlight.ogg by qwertyquerty from https://www.youtube.com/watch?v=XTfPEFfmhrA. Licensed under CC-BY-SA-3.0. +constellations.ogg by qwertyquerty from https://www.youtube.com/watch?v=ufwRj1LI3aw. Licensed under CC-BY-SA-3.0. \ No newline at end of file diff --git a/Resources/Audio/Ambience/starlight.ogg b/Resources/Audio/Ambience/starlight.ogg new file mode 100644 index 0000000000..67cd1bbb59 Binary files /dev/null and b/Resources/Audio/Ambience/starlight.ogg differ 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 79884ac1ae..7fbcd4066d 100644 --- a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl +++ b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl @@ -16,6 +16,8 @@ ui-options-midi-volume = MIDI (Instrument) Volume: ui-options-ambience-volume = Ambience volume: ui-options-ambience-max-sounds = Ambience simultaneous sounds: ui-options-lobby-music = Lobby Music +ui-options-station-ambience = Station Ambience +ui-options-space-ambience = Space Ambience ui-options-volume-label = Volume ui-options-volume-percent = { TOSTRING($volume, "P0") } diff --git a/Resources/Prototypes/SoundCollections/ambience.yml b/Resources/Prototypes/SoundCollections/ambience.yml index cccce8d1e2..66fc68c1b5 100644 --- a/Resources/Prototypes/SoundCollections/ambience.yml +++ b/Resources/Prototypes/SoundCollections/ambience.yml @@ -1,4 +1,10 @@ - type: soundCollection - id: AmbienceBase + id: StationAmbienceBase files: - /Audio/Ambience/shipambience.ogg + +- type: soundCollection + id: SpaceAmbienceBase + files: + - /Audio/Ambience/starlight.ogg + - /Audio/Ambience/constellations.ogg