From 05e8075c59ca5031ec4e7f04cef2404d8ab6d095 Mon Sep 17 00:00:00 2001 From: awsms <48278661+awsms@users.noreply.github.com> Date: Thu, 1 Oct 2026 07:33:59 +0200 Subject: [PATCH] Add a controller look acceleration toggle Controller aiming always ramped toward the requested turn rate, preventing players from choosing an immediate response to right-stick input. Add an Enabled/Disabled Look Acceleration control to the Controller menu and persist it through settings load/save and native menu dvars. Forward the setting to the aiming code: disabling it applies the requested angular velocity immediately, including when switching off an active ramp. Keep acceleration enabled by default for existing configurations. Preserve response curves, sensitivity scaling, ADS blending and FOV scaling. Validation: the play build and targeted formatting checks passed. Temporary probes checked immediate turning, the existing acceleration ramp, switching off mid-ramp, and ADS/FOV scaling at 30, 60 and 144 Hz. Menu inheritance and the toggle choices were also checked. Physical-controller feel has not been retested in game. --- crates/console/src/plugin/mod.rs | 1 + crates/console/src/user_settings.rs | 7 ++ crates/frame/src/settings.rs | 2 + crates/net/src/client/input.rs | 2 + crates/net/src/client/pad_aim.rs | 5 +- crates/ui/menus/controller.json | 103 ++++++++++++++++++++++++---- 6 files changed, 106 insertions(+), 14 deletions(-) diff --git a/crates/console/src/plugin/mod.rs b/crates/console/src/plugin/mod.rs index 92c5264..4411ccc 100644 --- a/crates/console/src/plugin/mod.rs +++ b/crates/console/src/plugin/mod.rs @@ -411,6 +411,7 @@ fn publish_client_action_input( out.pad_sensitivity = settings.pad_sensitivity / frame::GameSettings::PAD_SENSITIVITY_DEFAULT; out.pad_ads_sensitivity = settings.pad_ads_sensitivity; + out.pad_acceleration = settings.pad_acceleration; if let Some(pad) = pad { let sticks = crate::gamepad::sticks(pad, &settings); physical.movement_ready |= sticks.movement == Vec2::ZERO; diff --git a/crates/console/src/user_settings.rs b/crates/console/src/user_settings.rs index 83fccb8..04eb60f 100644 --- a/crates/console/src/user_settings.rs +++ b/crates/console/src/user_settings.rs @@ -358,6 +358,7 @@ fn serialize_settings(settings: &frame::GameSettings, binds: &KeyBinds) -> Strin format!("pad_ads_sensitivity={:.2}", settings.pad_ads_sensitivity), format!("pad_invert={}", settings.pad_invert), format!("pad_curve={}", settings.pad_curve), + format!("pad_acceleration={}", settings.pad_acceleration), format!("pad_aim_assist={}", settings.pad_aim_assist), format!("pad_prompts={}", settings.pad_prompts), format!("pad_vibration={}", settings.pad_vibration), @@ -451,6 +452,7 @@ fn parse_settings(source: &str, settings: &mut frame::GameSettings, binds: &mut "pad_ads_sensitivity" => parse_into(value, &mut settings.pad_ads_sensitivity), "pad_invert" => parse_into(value, &mut settings.pad_invert), "pad_curve" => parse_into(value, &mut settings.pad_curve), + "pad_acceleration" => parse_into(value, &mut settings.pad_acceleration), "pad_aim_assist" => parse_into(value, &mut settings.pad_aim_assist), "pad_prompts" => parse_into(value, &mut settings.pad_prompts), "pad_vibration" => parse_into(value, &mut settings.pad_vibration), @@ -534,6 +536,7 @@ pub(crate) fn native_menu_settings( "ui_pad_ads_sensitivity" => parse_into(value, &mut settings.pad_ads_sensitivity), "ui_pad_invert" => settings.pad_invert = value == "1", "ui_pad_curve" => parse_into(value, &mut settings.pad_curve), + "ui_pad_acceleration" => settings.pad_acceleration = value == "1", "ui_pad_aim_assist" => parse_into(value, &mut settings.pad_aim_assist), "ui_pad_prompts" => parse_into(value, &mut settings.pad_prompts), "ui_pad_test_rumble" => { @@ -576,6 +579,10 @@ pub(crate) fn native_menu_settings( ); dvars.set("ui_pad_invert", if settings.pad_invert { "1" } else { "0" }); dvars.set("ui_pad_curve", settings.pad_curve.to_string()); + dvars.set( + "ui_pad_acceleration", + if settings.pad_acceleration { "1" } else { "0" }, + ); dvars.set("ui_pad_aim_assist", settings.pad_aim_assist.to_string()); dvars.set("ui_pad_prompts", settings.pad_prompts.to_string()); dvars.set( diff --git a/crates/frame/src/settings.rs b/crates/frame/src/settings.rs index 3ef79e5..1a61f89 100644 --- a/crates/frame/src/settings.rs +++ b/crates/frame/src/settings.rs @@ -44,6 +44,7 @@ pub struct GameSettings { pub pad_ads_sensitivity: f32, pub pad_invert: bool, pub pad_curve: u8, + pub pad_acceleration: bool, pub pad_aim_assist: u8, pub pad_prompts: u8, pub pad_vibration: bool, @@ -74,6 +75,7 @@ impl Default for GameSettings { pad_ads_sensitivity: 1.0, pad_invert: false, pad_curve: 0, + pad_acceleration: true, pad_aim_assist: 0, pad_prompts: 0, pad_vibration: true, diff --git a/crates/net/src/client/input.rs b/crates/net/src/client/input.rs index 8a7bb84..52feb20 100644 --- a/crates/net/src/client/input.rs +++ b/crates/net/src/client/input.rs @@ -55,6 +55,7 @@ pub struct ClientActionInput { pub pad_look: [f32; 2], pub pad_deflection: f32, pub pad_sensitivity: f32, + pub pad_acceleration: bool, pub pad_ads_sensitivity: f32, pub pad_turn_rate: [f32; 2], /// Pitch and yaw, degrees. @@ -89,6 +90,7 @@ impl Default for ClientActionInput { pad_look: [0.0; 2], pad_deflection: 0.0, pad_sensitivity: 1.0, + pad_acceleration: true, pad_ads_sensitivity: 1.0, pad_turn_rate: [0.0; 2], pad_look_delta: [0.0; 2], diff --git a/crates/net/src/client/pad_aim.rs b/crates/net/src/client/pad_aim.rs index 3b80407..ae5acbd 100644 --- a/crates/net/src/client/pad_aim.rs +++ b/crates/net/src/client/pad_aim.rs @@ -171,8 +171,9 @@ pub fn pad_look_frame( let wanted = [-input.pad_look[1] * max_pitch, -input.pad_look[0] * max_yaw]; for (rate, goal) in input.pad_turn_rate.iter_mut().zip(wanted) { - if (goal.abs() > rate.abs() && goal.signum() == rate.signum()) - || (*rate == 0.0 && goal != 0.0) + if input.pad_acceleration + && ((goal.abs() > rate.abs() && goal.signum() == rate.signum()) + || (*rate == 0.0 && goal != 0.0)) { let step = TURN_ACCEL * zoom * dt; *rate = if goal > *rate { diff --git a/crates/ui/menus/controller.json b/crates/ui/menus/controller.json index 0dfb485..cd9f7bb 100644 --- a/crates/ui/menus/controller.json +++ b/crates/ui/menus/controller.json @@ -559,6 +559,85 @@ "name": "controller_label_11" } }, + { + "name": "video_display_mode", + "fields": { + "item_type": 12, + "static_flags": 0, + "dvar": "ui_pad_acceleration", + "choices": [ + [ + "@MENU_DISABLED", + "0" + ], + [ + "@MENU_ENABLED", + "1" + ] + ], + "vis_exp": "1", + "disabled_exp": "0", + "text_key": "", + "text_exp": "", + "text_align_mode": 10, + "text_align_x": -8, + "text_align_y": 0, + "fore_color": [ + 1, + 1, + 1, + 1 + ], + "rect": { + "x": 232, + "y": 148, + "w": 344, + "h": 20 + }, + "handlers": { + "action": [ + { + "Script": "play mouse_click;" + } + ], + "focus": [ + { + "Script": "play mouse_over; setItemColor self backcolor 0 0 0 1;" + } + ], + "leave_focus": [ + { + "Script": "setItemColor self backcolor 0 0 0 0;" + } + ] + }, + "text_scale": 0.375, + "style": 1, + "background": "menu_button_selection_bar", + "back_color": [ + 0, + 0, + 0, + 0 + ], + "name": "ui_pad_acceleration" + } + }, + { + "name": "video_display_mode_label", + "fields": { + "vis_exp": "1", + "text_key": "Look Acceleration", + "rect": { + "x": 232, + "y": 148, + "w": 344, + "h": 20 + }, + "text_scale": 0.32, + "name": "controller_acceleration_label" + } + }, { "name": "video_display_mode", "fields": { @@ -586,7 +665,7 @@ ], "rect": { "x": 232, - "y": 148, + "y": 168, "w": 344, "h": 20 }, @@ -626,7 +705,7 @@ "text_key": "Aim Assist", "rect": { "x": 232, - "y": 148, + "y": 168, "w": 344, "h": 20 }, @@ -665,7 +744,7 @@ ], "rect": { "x": 232, - "y": 168, + "y": 188, "w": 344, "h": 20 }, @@ -705,7 +784,7 @@ "text_key": "Vibration", "rect": { "x": 232, - "y": 168, + "y": 188, "w": 344, "h": 20 }, @@ -735,7 +814,7 @@ ], "rect": { "x": 420, - "y": 188, + "y": 208, "w": 112, "h": 20 }, @@ -775,7 +854,7 @@ "vis_exp": "1", "rect": { "x": 232, - "y": 188, + "y": 208, "w": 344, "h": 20 }, @@ -804,7 +883,7 @@ ], "rect": { "x": 420, - "y": 208, + "y": 228, "w": 112, "h": 20 }, @@ -844,7 +923,7 @@ "vis_exp": "1", "rect": { "x": 232, - "y": 208, + "y": 228, "w": 344, "h": 20 }, @@ -890,7 +969,7 @@ ], "rect": { "x": 232, - "y": 228, + "y": 248, "w": 344, "h": 20 }, @@ -930,7 +1009,7 @@ "text_key": "Controller Prompts", "rect": { "x": 232, - "y": 228, + "y": 248, "w": 344, "h": 20 }, @@ -960,7 +1039,7 @@ ], "rect": { "x": 232, - "y": 248, + "y": 268, "w": 344, "h": 20 }, @@ -1000,7 +1079,7 @@ "text_key": "Test Vibration", "rect": { "x": 232, - "y": 248, + "y": 268, "w": 344, "h": 20 },