--- /dev/null
+using Content.Shared.CCVar;
+using Robust.Client.Audio;
+using Robust.Client.ResourceManagement;
+using Robust.Client.UserInterface.Controllers;
+using Robust.Shared.Audio.Sources;
+using Robust.Shared.Configuration;
+
+namespace Content.Client.Audio;
+
+public sealed class AudioUIController : UIController
+{
+ [Dependency] private readonly IAudioManager _audioManager = default!;
+ [Dependency] private readonly IConfigurationManager _configManager = default!;
+ [Dependency] private readonly IResourceCache _cache = default!;
+
+ private float _interfaceGain;
+ private IAudioSource? _clickSource;
+ private IAudioSource? _hoverSource;
+
+ private const float ClickGain = 0.25f;
+ private const float HoverGain = 0.05f;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ /*
+ * This exists to load UI sounds outside of the game sim.
+ */
+
+ // No unsub coz never shuts down until program exit.
+ _configManager.OnValueChanged(CCVars.UIClickSound, SetClickSound, true);
+ _configManager.OnValueChanged(CCVars.UIHoverSound, SetHoverSound, true);
+
+ _configManager.OnValueChanged(CCVars.InterfaceVolume, SetInterfaceVolume, true);
+ }
+
+ private void SetInterfaceVolume(float obj)
+ {
+ _interfaceGain = obj;
+
+ if (_clickSource != null)
+ {
+ _clickSource.Gain = ClickGain * _interfaceGain;
+ }
+
+ if (_hoverSource != null)
+ {
+ _hoverSource.Gain = HoverGain * _interfaceGain;
+ }
+ }
+
+ private void SetClickSound(string value)
+ {
+ if (!string.IsNullOrEmpty(value))
+ {
+ var resource = _cache.GetResource<AudioResource>(value);
+ var source =
+ _audioManager.CreateAudioSource(resource);
+
+ if (source != null)
+ {
+ source.Gain = ClickGain * _interfaceGain;
+ source.Global = true;
+ }
+
+ _clickSource = source;
+ UIManager.SetClickSound(source);
+ }
+ else
+ {
+ UIManager.SetClickSound(null);
+ }
+ }
+
+ private void SetHoverSound(string value)
+ {
+ if (!string.IsNullOrEmpty(value))
+ {
+ var hoverResource = _cache.GetResource<AudioResource>(value);
+ var hoverSource =
+ _audioManager.CreateAudioSource(hoverResource);
+
+ if (hoverSource != null)
+ {
+ hoverSource.Gain = HoverGain * _interfaceGain;
+ hoverSource.Global = true;
+ }
+
+ _hoverSource = hoverSource;
+ UIManager.SetHoverSound(hoverSource);
+ }
+ else
+ {
+ UIManager.SetHoverSound(null);
+ }
+ }
+}
using Content.Shared.Audio;
-using Content.Shared.CCVar;
using Content.Shared.GameTicking;
-using Robust.Client.GameObjects;
-using Robust.Shared;
-using Robust.Shared.Audio;
+using Robust.Client.Audio;
+using Robust.Client.ResourceManagement;
+using Robust.Client.UserInterface;
using AudioComponent = Robust.Shared.Audio.Components.AudioComponent;
namespace Content.Client.Audio;
public sealed partial class ContentAudioSystem : SharedContentAudioSystem
{
+ [Dependency] private readonly IAudioManager _audioManager = default!;
+ [Dependency] private readonly IResourceCache _cache = default!;
+ [Dependency] private readonly IUserInterfaceManager _uiManager = default!;
+
// Need how much volume to change per tick and just remove it when it drops below "0"
private readonly Dictionary<EntityUid, float> _fadingOut = new();
public const float AmbienceMultiplier = 3f;
public const float AmbientMusicMultiplier = 3f;
public const float LobbyMultiplier = 3f;
+ public const float InterfaceMultiplier = 2f;
public override void Initialize()
{
if (IsAtFront)
{
WindowOpen = false;
- _uiManager.GetActiveUIWidget<GameTopMenuBar>().CraftingButton.Pressed = false; // This does not call CraftingButtonToggled
+ _uiManager.GetActiveUIWidget<GameTopMenuBar>().CraftingButton.SetClickPressed(false); // This does not call CraftingButtonToggled
}
else
_constructionView.MoveToFront();
else
{
WindowOpen = true;
- _uiManager.GetActiveUIWidget<GameTopMenuBar>().CraftingButton.Pressed = true; // This does not call CraftingButtonToggled
+ _uiManager.GetActiveUIWidget<GameTopMenuBar>().CraftingButton.SetClickPressed(true); // This does not call CraftingButtonToggled
}
}
<Label Name="LobbyVolumeLabel" MinSize="48 0" Align="Right" />
<Control MinSize="4 0"/>
</BoxContainer>
+ <BoxContainer Orientation="Horizontal" Margin="5 0 0 0">
+ <Label Text="{Loc 'ui-options-interface-volume'}" HorizontalExpand="True" />
+ <Control MinSize="8 0" />
+ <Slider Name="InterfaceVolumeSlider"
+ MinValue="0"
+ MaxValue="100"
+ HorizontalExpand="True"
+ MinSize="80 0"
+ Rounded="True" />
+ <Control MinSize="8 0" />
+ <Label Name="InterfaceVolumeLabel" MinSize="48 0" Align="Right" />
+ <Control MinSize="4 0"/>
+ </BoxContainer>
<BoxContainer Orientation="Horizontal" Margin="5 0 0 0">
<Label Text="{Loc 'ui-options-ambience-max-sounds'}" HorizontalExpand="True" />
<Control MinSize="8 0" />
using Content.Shared.CCVar;
using Robust.Client.Audio;
using Robust.Client.AutoGenerated;
-using Robust.Client.GameObjects;
-using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared;
-using Robust.Shared.Audio.Systems;
using Robust.Shared.Configuration;
using Range = Robust.Client.UserInterface.Controls.Range;
AmbienceVolumeSlider.OnValueChanged += OnAmbienceVolumeSliderChanged;
AmbienceSoundsSlider.OnValueChanged += OnAmbienceSoundsSliderChanged;
LobbyVolumeSlider.OnValueChanged += OnLobbyVolumeSliderChanged;
+ InterfaceVolumeSlider.OnValueChanged += OnInterfaceVolumeSliderChanged;
LobbyMusicCheckBox.OnToggled += OnLobbyMusicCheckToggled;
RestartSoundsCheckBox.OnToggled += OnRestartSoundsCheckToggled;
EventMusicCheckBox.OnToggled += OnEventMusicCheckToggled;
AmbientMusicVolumeSlider.OnValueChanged -= OnAmbientMusicVolumeSliderChanged;
AmbienceVolumeSlider.OnValueChanged -= OnAmbienceVolumeSliderChanged;
LobbyVolumeSlider.OnValueChanged -= OnLobbyVolumeSliderChanged;
+ InterfaceVolumeSlider.OnValueChanged -= OnInterfaceVolumeSliderChanged;
base.Dispose(disposing);
}
UpdateChanges();
}
+ private void OnInterfaceVolumeSliderChanged(Range obj)
+ {
+ UpdateChanges();
+ }
+
private void OnAmbientMusicVolumeSliderChanged(Range obj)
{
UpdateChanges();
_cfg.SetCVar(CCVars.AmbienceVolume, AmbienceVolumeSlider.Value / 100f * ContentAudioSystem.AmbienceMultiplier);
_cfg.SetCVar(CCVars.AmbientMusicVolume, AmbientMusicVolumeSlider.Value / 100f * ContentAudioSystem.AmbientMusicMultiplier);
_cfg.SetCVar(CCVars.LobbyMusicVolume, LobbyVolumeSlider.Value / 100f * ContentAudioSystem.LobbyMultiplier);
+ _cfg.SetCVar(CCVars.InterfaceVolume, InterfaceVolumeSlider.Value / 100f * ContentAudioSystem.InterfaceMultiplier);
_cfg.SetCVar(CCVars.MaxAmbientSources, (int)AmbienceSoundsSlider.Value);
AmbienceVolumeSlider.Value = _cfg.GetCVar(CCVars.AmbienceVolume) * 100f / ContentAudioSystem.AmbienceMultiplier;
AmbientMusicVolumeSlider.Value = _cfg.GetCVar(CCVars.AmbientMusicVolume) * 100f / ContentAudioSystem.AmbientMusicMultiplier;
LobbyVolumeSlider.Value = _cfg.GetCVar(CCVars.LobbyMusicVolume) * 100f / ContentAudioSystem.LobbyMultiplier;
+ InterfaceVolumeSlider.Value = _cfg.GetCVar(CCVars.InterfaceVolume) * 100f / ContentAudioSystem.InterfaceMultiplier;
AmbienceSoundsSlider.Value = _cfg.GetCVar(CCVars.MaxAmbientSources);
Math.Abs(AmbientMusicVolumeSlider.Value - _cfg.GetCVar(CCVars.AmbientMusicVolume) * 100f / ContentAudioSystem.AmbientMusicMultiplier) < 0.01f;
var isLobbyVolumeSame =
Math.Abs(LobbyVolumeSlider.Value - _cfg.GetCVar(CCVars.LobbyMusicVolume) * 100f / ContentAudioSystem.LobbyMultiplier) < 0.01f;
+ var isInterfaceVolumeSame =
+ Math.Abs(InterfaceVolumeSlider.Value - _cfg.GetCVar(CCVars.InterfaceVolume) * 100f / ContentAudioSystem.InterfaceMultiplier) < 0.01f;
var isAmbientSoundsSame = (int)AmbienceSoundsSlider.Value == _cfg.GetCVar(CCVars.MaxAmbientSources);
var isLobbySame = LobbyMusicCheckBox.Pressed == _cfg.GetCVar(CCVars.LobbyMusicEnabled);
var isEventSame = EventMusicCheckBox.Pressed == _cfg.GetCVar(CCVars.EventMusicEnabled);
var isAdminSoundsSame = AdminSoundsCheckBox.Pressed == _cfg.GetCVar(CCVars.AdminSoundsEnabled);
var isEverythingSame = isMasterVolumeSame && isMidiVolumeSame && isAmbientVolumeSame && isAmbientMusicVolumeSame && isAmbientSoundsSame && isLobbySame && isRestartSoundsSame && isEventSame
- && isAdminSoundsSame && isLobbyVolumeSame;
+ && isAdminSoundsSame && isLobbyVolumeSame && isInterfaceVolumeSame;
ApplyButton.Disabled = isEverythingSame;
ResetButton.Disabled = isEverythingSame;
MasterVolumeLabel.Text =
Loc.GetString("ui-options-volume-percent", ("volume", AmbienceVolumeSlider.Value / 100));
LobbyVolumeLabel.Text =
Loc.GetString("ui-options-volume-percent", ("volume", LobbyVolumeSlider.Value / 100));
+ InterfaceVolumeLabel.Text =
+ Loc.GetString("ui-options-volume-percent", ("volume", InterfaceVolumeSlider.Value / 100));
AmbienceSoundsLabel.Text = ((int)AmbienceSoundsSlider.Value).ToString();
}
}
private void OnWindowOpened()
{
if (ActionButton != null)
- ActionButton.Pressed = true;
+ ActionButton.SetClickPressed(true);
SearchAndDisplay();
}
private void OnWindowClosed()
{
if (ActionButton != null)
- ActionButton.Pressed = false;
+ ActionButton.SetClickPressed(false);
}
public void OnStateExited(GameplayState state)
{
base.MouseEntered();
+ UserInterfaceManager.HoverSound();
_beingHovered = true;
DrawModeChanged();
}
private void OnWindowOpen()
{
- if (AdminButton != null)
- AdminButton.Pressed = true;
+ AdminButton?.SetClickPressed(true);
}
private void OnWindowClosed()
{
- if (AdminButton != null)
- AdminButton.Pressed = false;
+ AdminButton?.SetClickPressed(false);
}
private void OnWindowDisposed()
LobbyAHelpButton.Pressed = pressed;
}
+ UIManager.ClickSound();
UnreadAHelpRead();
}
if (CharacterButton != null)
{
- CharacterButton.Pressed = !_window.IsOpen;
+ CharacterButton.SetClickPressed(!_window.IsOpen);
}
if (_window.IsOpen)
EscapeButton.OnPressed += EscapeButtonOnOnPressed;
}
- private void ActivateButton() => EscapeButton!.Pressed = true;
- private void DeactivateButton() => EscapeButton!.Pressed = false;
+ private void ActivateButton() => EscapeButton!.SetClickPressed(true);
+ private void DeactivateButton() => EscapeButton!.SetClickPressed(false);
public void OnStateEntered(GameplayState state)
{
if (_guideWindow.IsOpen)
{
+ UIManager.ClickSound();
_guideWindow.Close();
return;
}
if (GuidebookButton != null)
- GuidebookButton.Pressed = !_guideWindow.IsOpen;
+ GuidebookButton.SetClickPressed(!_guideWindow.IsOpen);
if (guides == null)
{
}
UpdateInventoryHotbar(_playerInventory);
- _inventoryHotbar.Visible = !_inventoryHotbar.Visible;
+ var shouldBeVisible = !_inventoryHotbar.Visible;
+ _inventoryHotbar.Visible = shouldBeVisible;
+
}
// Neuron Activation
return;
if (_sandbox.SandboxAllowed && _window.IsOpen != true)
{
+ UIManager.ClickSound();
_window.OpenCentered();
}
else
{
+ UIManager.ClickSound();
_window.Close();
}
}
public static readonly CVarDef<float> LobbyMusicVolume =
CVarDef.Create("ambience.lobby_music_volume", 0.50f, CVar.ARCHIVE | CVar.CLIENTONLY);
+ /// <summary>
+ /// UI volume.
+ /// </summary>
+ public static readonly CVarDef<float> InterfaceVolume =
+ CVarDef.Create("audio.interface_volume", 0.50f, CVar.ARCHIVE | CVar.CLIENTONLY);
+
/*
* Status
*/
public static readonly CVarDef<bool> DatabaseSynchronous =
CVarDef.Create("database.sync", false, CVar.SERVERONLY);
+ /*
+ * Interface
+ */
+
+ public static readonly CVarDef<string> UIClickSound =
+ CVarDef.Create("interface.click_sound", "/Audio/UserInterface/click.ogg", CVar.REPLICATED);
+
+ public static readonly CVarDef<string> UIHoverSound =
+ CVarDef.Create("interface.hover_sound", "/Audio/UserInterface/hover.ogg", CVar.REPLICATED);
+
/*
* Outline
*/
--- /dev/null
+- files:
+ - click.ogg
+ license: "CC0-1.0"
+ copyright: "Made by el_boss, edited by mirrorcult"
+ source: "https://freesound.org/people/el_boss/sounds/677861/"
+
+- files:
+ - hover.ogg
+ license: "CC0-1.0"
+ copyright: "Made by MATRIXXX_, edited by metalgearsloth"
+ source: "https://freesound.org/people/MATRIXXX_/sounds/703884/"
\ No newline at end of file
ui-options-ambient-music-volume = Ambient music volume:
ui-options-ambience-volume = Ambience volume:
ui-options-lobby-volume = Lobby & Round-end volume:
+ui-options-interface-volume = Interface volume:
ui-options-ambience-max-sounds = Ambience simultaneous sounds:
ui-options-lobby-music = Lobby & Round-end Music
ui-options-restart-sounds = Round Restart Sounds