A Razor UI panel for game settings. It displays audio sliders (master, music, sfx), toggles for mute, auto-sell and impact effects, a reset-progress danger action, and persists changes to a PumpSettings singleton.
@using System
@using Sandbox
@using Sandbox.UI
@namespace DesertPump
@inherits Panel
<root class="settingspanel">
<div class="scrim" onclick="@Close"></div>
<div class="sheet">
<div class="head">
<div class="title"><i>settings</i> SETTINGS</div>
<div class="closebtn" onclick="@Close"><i>close</i></div>
</div>
<div class="group">
<div class="grouptitle">AUDIO</div>
<div class="row">
<div class="label">Master volume</div>
<SliderControl class="simple" Value:bind=@Master Min="@(0f)" Max="@(1f)" Step="@(0.05f)"></SliderControl>
<div class="value">@Percent( Master )</div>
</div>
<div class="row">
<div class="label">Music</div>
<SliderControl class="simple" Value:bind=@Music Min="@(0f)" Max="@(1f)" Step="@(0.05f)"></SliderControl>
<div class="value">@Percent( Music )</div>
</div>
<div class="row">
<div class="label">Sound effects</div>
<SliderControl class="simple" Value:bind=@Sfx Min="@(0f)" Max="@(1f)" Step="@(0.05f)"></SliderControl>
<div class="value">@Percent( Sfx )</div>
</div>
<div class="row toggle @( Settings.Muted ? "on" : "" )" onclick="@ToggleMute">
<div class="label">Mute everything</div>
<div class="switch"><div class="knob"></div></div>
</div>
</div>
<div class="group">
<div class="grouptitle">GAME</div>
<div class="row toggle @( Settings.AutoSell ? "on" : "" )" onclick="@ToggleAutoSell">
<div class="label">
Auto-sell when the tank fills
<span class="sub">Hands off, but you'll miss the coin sound</span>
</div>
<div class="switch"><div class="knob"></div></div>
</div>
<div class="row toggle @( Settings.ShowFloatingNumbers ? "on" : "" )" onclick="@ToggleFloaters">
@* Still stored as ShowFloatingNumbers so old saves keep working, but it
governs the whole per-action effects layer now, and the label has to
say so or turning it off looks like it broke half the screen. *@
<div class="label">
Impact effects
<span class="sub">Floating numbers, water, coins, rings and screen shake</span>
</div>
<div class="switch"><div class="knob"></div></div>
</div>
</div>
<div class="group danger">
<div class="grouptitle">DANGER</div>
<div class="row">
<div class="label">
Reset progress
<span class="sub">Every pump, upgrade and coin. Settings are kept.</span>
</div>
@if ( confirmingReset )
{
<div class="resetrow">
<div class="resetbtn confirm" onclick="@DoReset">Yes, wipe it</div>
<div class="resetbtn" onclick="@( () => confirmingReset = false )">Cancel</div>
</div>
}
else
{
<div class="resetbtn" onclick="@( () => confirmingReset = true )">Reset</div>
}
</div>
</div>
<div class="done" onclick="@Close">DONE</div>
</div>
</root>
@code
{
/// <summary>Raised when the player dismisses the settings.</summary>
public Action OnClose { get; set; }
static PumpSettings Settings => PumpSettings.Current;
bool confirmingReset;
// Slider bindings. Each setter persists, so a change survives even if the game
// is killed rather than closed.
float Master
{
get => Settings.MasterVolume;
set => Apply( () => Settings.MasterVolume = value, Settings.MasterVolume == value );
}
float Music
{
get => Settings.MusicVolume;
set => Apply( () => Settings.MusicVolume = value, Settings.MusicVolume == value );
}
float Sfx
{
get => Settings.SfxVolume;
set => Apply( () => Settings.SfxVolume = value, Settings.SfxVolume == value );
}
void Apply( Action change, bool unchanged )
{
if ( unchanged ) return;
change();
Settings.Save();
StateHasChanged();
}
void ToggleMute()
{
Settings.Muted = !Settings.Muted;
Settings.Save();
StateHasChanged();
}
void ToggleAutoSell()
{
Settings.AutoSell = !Settings.AutoSell;
Settings.Save();
StateHasChanged();
}
void ToggleFloaters()
{
Settings.ShowFloatingNumbers = !Settings.ShowFloatingNumbers;
Settings.Save();
StateHasChanged();
}
void DoReset()
{
DesertPumpGame.Current?.ResetProgress();
confirmingReset = false;
StateHasChanged();
}
void Close()
{
confirmingReset = false;
OnClose?.Invoke();
}
static string Percent( float value ) => $"{value * 100f:0}%";
protected override int BuildHash() => HashCode.Combine(
Settings.MasterVolume, Settings.MusicVolume, Settings.SfxVolume,
Settings.Muted, Settings.AutoSell, Settings.ShowFloatingNumbers, confirmingReset );
}