diff --git a/Content.Client/Options/UI/OptionsMenu.xaml b/Content.Client/Options/UI/OptionsMenu.xaml
index ab3b88ca4e..d72d587168 100644
--- a/Content.Client/Options/UI/OptionsMenu.xaml
+++ b/Content.Client/Options/UI/OptionsMenu.xaml
@@ -8,5 +8,6 @@
+
diff --git a/Content.Client/Options/UI/OptionsMenu.xaml.cs b/Content.Client/Options/UI/OptionsMenu.xaml.cs
index c3a8e66470..f174764de6 100644
--- a/Content.Client/Options/UI/OptionsMenu.xaml.cs
+++ b/Content.Client/Options/UI/OptionsMenu.xaml.cs
@@ -1,15 +1,17 @@
+using Content.Client.Administration.Managers;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
-using Robust.Shared.IoC;
using Content.Client.Options.UI.Tabs;
-
+using Robust.Shared.Timing;
namespace Content.Client.Options.UI
{
[GenerateTypedNameReferences]
public sealed partial class OptionsMenu : DefaultWindow
{
+ [Dependency] private readonly IClientAdminManager _clientAdminManager = default!;
+
public OptionsMenu()
{
RobustXamlLoader.Load(this);
@@ -20,6 +22,7 @@ namespace Content.Client.Options.UI
Tabs.SetTabTitle(2, Loc.GetString("ui-options-tab-controls"));
Tabs.SetTabTitle(3, Loc.GetString("ui-options-tab-audio"));
Tabs.SetTabTitle(4, Loc.GetString("ui-options-tab-network"));
+ Tabs.SetTabTitle(5, "Админ");
UpdateTabs();
}
@@ -28,5 +31,11 @@ namespace Content.Client.Options.UI
{
GraphicsTab.UpdateProperties();
}
+
+ protected override void FrameUpdate(FrameEventArgs args)
+ {
+ Tabs.SetTabVisible(5, _clientAdminManager.IsActive());
+ base.FrameUpdate(args);
+ }
}
}
diff --git a/Content.Client/Options/UI/Tabs/AdminSettingsTab.xaml b/Content.Client/Options/UI/Tabs/AdminSettingsTab.xaml
new file mode 100644
index 0000000000..b1c8c928bb
--- /dev/null
+++ b/Content.Client/Options/UI/Tabs/AdminSettingsTab.xaml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content.Client/Options/UI/Tabs/AdminSettingsTab.xaml.cs b/Content.Client/Options/UI/Tabs/AdminSettingsTab.xaml.cs
new file mode 100644
index 0000000000..c91ef4a625
--- /dev/null
+++ b/Content.Client/Options/UI/Tabs/AdminSettingsTab.xaml.cs
@@ -0,0 +1,50 @@
+using Content.Shared.CCVar;
+using Content.Shared.White;
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.XAML;
+using Robust.Shared.Configuration;
+using Range = Robust.Client.UserInterface.Controls.Range;
+
+namespace Content.Client.Options.UI.Tabs;
+
+[GenerateTypedNameReferences]
+public sealed partial class AdminSettingsTab : Control
+{
+ [Dependency] private readonly IConfigurationManager _cfg = default!;
+
+ public AdminSettingsTab()
+ {
+ RobustXamlLoader.Load(this);
+ IoCManager.InjectDependencies(this);
+
+ LoadData();
+
+ AhelpSoundVolume.OnValueChanged += OnAhelpVolumeChanged;
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ AhelpSoundVolume.OnValueChanged -= OnAhelpVolumeChanged;
+ base.Dispose(disposing);
+ }
+
+ private void LoadData()
+ {
+ var bwoinkVolume = _cfg.GetCVar(WhiteCVars.BwoinkVolume);
+ AhelpSoundVolume.Value = bwoinkVolume;
+ AhelpSoundVolumeLabel.Text = ((int) bwoinkVolume).ToString();
+ }
+
+ private void OnAhelpVolumeChanged(Range newValue)
+ {
+ _cfg.SetCVar(WhiteCVars.BwoinkVolume, LV100ToDB(newValue.Value));
+ AhelpSoundVolumeLabel.Text = ((int)newValue.Value).ToString();
+ }
+
+ private float LV100ToDB(float lv100)
+ {
+ // Saving negative infinity doesn't work, so use -10000000 instead (MidiManager does it)
+ return MathF.Max(-10000000, MathF.Log(lv100 / 100, 10) * 10);
+ }
+}
diff --git a/Content.Client/UserInterface/Systems/Bwoink/AHelpUIController.cs b/Content.Client/UserInterface/Systems/Bwoink/AHelpUIController.cs
index a8c4a2b1b4..35447230fe 100644
--- a/Content.Client/UserInterface/Systems/Bwoink/AHelpUIController.cs
+++ b/Content.Client/UserInterface/Systems/Bwoink/AHelpUIController.cs
@@ -13,6 +13,7 @@ using Content.Client.UserInterface.Systems.MenuBar.Widgets;
using Content.Shared.Administration;
using Content.Shared.CCVar;
using Content.Shared.Input;
+using Content.Shared.White;
using JetBrains.Annotations;
using Robust.Client.Audio;
using Robust.Client.Graphics;
@@ -21,6 +22,7 @@ using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controllers;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
+using Robust.Shared.Audio;
using Robust.Shared.Configuration;
using Robust.Shared.Input.Binding;
using Robust.Shared.Network;
@@ -38,6 +40,8 @@ public sealed class AHelpUIController: UIController, IOnSystemChanged UIManager.GetActiveUIWidgetOrNull()?.AHelpButton;
@@ -47,12 +51,17 @@ public sealed class AHelpUIController: UIController, IOnSystemChanged(DiscordRelayUpdated);
SubscribeNetworkEvent(PeopleTypingUpdated);
+ defaultBwoinkVolume = WhiteCVars.BwoinkVolume.DefaultValue;
+ _cfg.OnValueChanged(WhiteCVars.BwoinkVolume, volume => adminBwoinkVolume = volume);
_adminManager.AdminStatusUpdated += OnAdminStatusUpdated;
_config.OnValueChanged(CCVars.AHelpSound, v => _aHelpSound = v, true);
@@ -133,10 +142,20 @@ public sealed class AHelpUIController: UIController, IOnSystemChanged GhostRespawnMaxPlayers =
CVarDef.Create("ghost.respawn_max_players", 40, CVar.SERVERONLY);
+
+ /*
+ * Bwoink
+ */
+
+ public static readonly CVarDef BwoinkVolume =
+ CVarDef.Create("white.admin.bwoinkVolume", 0f, CVar.CLIENTONLY | CVar.ARCHIVE);
}