using System.Numerics;
using Content.Shared.Camera;
+using Content.Shared.CCVar;
+using Robust.Shared.Configuration;
namespace Content.Client.Camera;
public sealed class CameraRecoilSystem : SharedCameraRecoilSystem
{
+ [Dependency] private readonly IConfigurationManager _configManager = default!;
+
+ protected float Intensity;
+
public override void Initialize()
{
base.Initialize();
SubscribeNetworkEvent<CameraKickEvent>(OnCameraKick);
+
+ _configManager.OnValueChanged(CCVars.ScreenShakeIntensity, OnCvarChanged, true);
+ }
+
+ public override void Shutdown()
+ {
+ base.Shutdown();
+
+ _configManager.UnsubValueChanged(CCVars.ScreenShakeIntensity, OnCvarChanged);
+ }
+
+ private void OnCvarChanged(float value)
+ {
+ Intensity = value;
}
private void OnCameraKick(CameraKickEvent ev)
public override void KickCamera(EntityUid uid, Vector2 recoil, CameraRecoilComponent? component = null)
{
+ if (Intensity == 0)
+ return;
+
if (!Resolve(uid, ref component, false))
return;
+ recoil *= Intensity;
+
// Use really bad math to "dampen" kicks when we're already kicked.
var existing = component.CurrentKick.Length();
var dampen = existing / KickMagnitudeMax;
FontColorOverride="{xNamespace:Static s:StyleNano.NanoGold}"
StyleClasses="LabelKeyText"/>
<CheckBox Name="ReducedMotionCheckBox" Text="{Loc 'ui-options-reduced-motion'}" />
+ <BoxContainer Orientation="Horizontal">
+ <Label Text="{Loc 'ui-options-screen-shake-intensity'}" Margin="8 0" />
+ <Slider Name="ScreenShakeIntensitySlider"
+ MinValue="0"
+ MaxValue="100"
+ Rounded="True"
+ MinWidth="200" />
+ <Label Name="ScreenShakeIntensityLabel" Margin="8 0" />
+ </BoxContainer>
<Label Text="{Loc 'ui-options-general-discord'}"
FontColorOverride="{xNamespace:Static s:StyleNano.NanoGold}"
StyleClasses="LabelKeyText"/>
using Robust.Shared;
using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
+using Range = Robust.Client.UserInterface.Controls.Range;
namespace Content.Client.Options.UI.Tabs
{
FancySpeechBubblesCheckBox.OnToggled += OnCheckBoxToggled;
FancyNameBackgroundsCheckBox.OnToggled += OnCheckBoxToggled;
ReducedMotionCheckBox.OnToggled += OnCheckBoxToggled;
+ ScreenShakeIntensitySlider.OnValueChanged += OnScreenShakeIntensitySliderChanged;
// ToggleWalk.OnToggled += OnCheckBoxToggled;
StaticStorageUI.OnToggled += OnCheckBoxToggled;
OpaqueStorageWindowCheckBox.Pressed = _cfg.GetCVar(CCVars.OpaqueStorageWindow);
FancySpeechBubblesCheckBox.Pressed = _cfg.GetCVar(CCVars.ChatEnableFancyBubbles);
FancyNameBackgroundsCheckBox.Pressed = _cfg.GetCVar(CCVars.ChatFancyNameBackground);
+ ReducedMotionCheckBox.Pressed = _cfg.GetCVar(CCVars.ReducedMotion);
+ ScreenShakeIntensitySlider.Value = _cfg.GetCVar(CCVars.ScreenShakeIntensity) * 100f;
// ToggleWalk.Pressed = _cfg.GetCVar(CCVars.ToggleWalk);
StaticStorageUI.Pressed = _cfg.GetCVar(CCVars.StaticStorageUI);
UpdateApplyButton();
}
+ private void OnScreenShakeIntensitySliderChanged(Range obj)
+ {
+ ScreenShakeIntensityLabel.Text = Loc.GetString("ui-options-screen-shake-percent", ("intensity", ScreenShakeIntensitySlider.Value / 100f));
+ UpdateApplyButton();
+ }
+
private void OnApplyButtonPressed(BaseButton.ButtonEventArgs args)
{
foreach (var theme in _prototypeManager.EnumeratePrototypes<HudThemePrototype>())
_cfg.SetCVar(CCVars.ChatEnableFancyBubbles, FancySpeechBubblesCheckBox.Pressed);
_cfg.SetCVar(CCVars.ChatFancyNameBackground, FancyNameBackgroundsCheckBox.Pressed);
_cfg.SetCVar(CCVars.ReducedMotion, ReducedMotionCheckBox.Pressed);
+ _cfg.SetCVar(CCVars.ScreenShakeIntensity, ScreenShakeIntensitySlider.Value / 100f);
// _cfg.SetCVar(CCVars.ToggleWalk, ToggleWalk.Pressed);
_cfg.SetCVar(CCVars.StaticStorageUI, StaticStorageUI.Pressed);
var isFancyChatSame = FancySpeechBubblesCheckBox.Pressed == _cfg.GetCVar(CCVars.ChatEnableFancyBubbles);
var isFancyBackgroundSame = FancyNameBackgroundsCheckBox.Pressed == _cfg.GetCVar(CCVars.ChatFancyNameBackground);
var isReducedMotionSame = ReducedMotionCheckBox.Pressed == _cfg.GetCVar(CCVars.ReducedMotion);
+ var isScreenShakeIntensitySame = Math.Abs(ScreenShakeIntensitySlider.Value / 100f - _cfg.GetCVar(CCVars.ScreenShakeIntensity)) < 0.01f;
// var isToggleWalkSame = ToggleWalk.Pressed == _cfg.GetCVar(CCVars.ToggleWalk);
var isStaticStorageUISame = StaticStorageUI.Pressed == _cfg.GetCVar(CCVars.StaticStorageUI);
isFancyChatSame &&
isFancyBackgroundSame &&
isReducedMotionSame &&
+ isScreenShakeIntensitySame &&
// isToggleWalkSame &&
isStaticStorageUISame;
}
public static readonly CVarDef<bool> ReducedMotion =
CVarDef.Create("accessibility.reduced_motion", false, CVar.CLIENTONLY | CVar.ARCHIVE);
+ /// <summary>
+ /// Screen shake intensity slider, controlling the intensity of the CameraRecoilSystem.
+ /// Goes from 0 (no recoil at all) to 1 (regular amounts of recoil)
+ /// </summary>
+ public static readonly CVarDef<float> ScreenShakeIntensity =
+ CVarDef.Create("accessibility.screen_shake_intensity", 1f, CVar.CLIENTONLY | CVar.ARCHIVE);
+
/*
* CHAT
*/
ui-options-fancy-speech = Show names in speech bubbles
ui-options-fancy-name-background = Add background to speech bubble names
ui-options-reduced-motion = Reduce motion of visual effects
+ui-options-screen-shake-intensity = Screen shake intensity
+ui-options-screen-shake-percent = { TOSTRING($intensity, "P0") }
ui-options-vsync = VSync
ui-options-fullscreen = Fullscreen
ui-options-lighting-label = Lighting Quality: