From 0e3a1d56d9b6d4382cc4c709b9ef9059a7170daf Mon Sep 17 00:00:00 2001 From: Juhu <5894800-Juhu_@users.noreply.gitlab.com> Date: Wed, 14 Sep 2022 10:07:21 +0200 Subject: [PATCH] strafehud: detect zero friction frame on landing, remove ground timeout which became useless due to that, rename air timeout to ground timeout and refactor all timeout code --- _hud_common.cfg | 3 +- qcsrc/client/hud/panel/strafehud.qc | 99 ++++++++++++----------------- qcsrc/client/hud/panel/strafehud.qh | 3 +- 3 files changed, 43 insertions(+), 62 deletions(-) diff --git a/_hud_common.cfg b/_hud_common.cfg index 00977a49d..c236229f2 100644 --- a/_hud_common.cfg +++ b/_hud_common.cfg @@ -196,8 +196,7 @@ seta hud_panel_strafehud_jumpheight_fade "0" "fade time (in seconds) of the jump seta hud_panel_strafehud_jumpheight_min "50" "minimum jump height to display in the selected unit" seta hud_panel_strafehud_jumpheight_color "0 1 0.75" "color of the jump height text" seta hud_panel_strafehud_jumpheight_size "1.5" "size of the jump height text (relative to the panel height)" -seta hud_panel_strafehud_timeout_air "0.1" "time (in seconds) after take off before changing to air strafe physics when not jumping (visually more consistent hud while on slick downwards ramps)" -seta hud_panel_strafehud_timeout_ground "0.03333333" "time (in seconds) after landing before changing to non-air strafe physics (visually more consistent hud while strafe turning when touching the floor after every hop)" +seta hud_panel_strafehud_timeout_ground "0.1" "time (in seconds) after take off before changing to air strafe physics when not jumping (visually more consistent hud while on slick downwards ramps)" seta hud_panel_strafehud_timeout_turn "0.1" "time (in seconds) after releasing the strafe keys before changing mode (visually more consistent hud while switching between left/right strafe turning)" seta hud_panel_strafehud_antiflicker_angle "0.01" "how many degrees from 0° to 180° the hud ignores if it could cause visual disturbances otherwise (and to counter rounding errors)" seta hud_panel_strafehud_fps_update "0.5" "update interval (in seconds) of the frametime to calculate the optimal angle, smaller values may cause flickering" diff --git a/qcsrc/client/hud/panel/strafehud.qc b/qcsrc/client/hud/panel/strafehud.qc index 3fc1355d5..49a627185 100644 --- a/qcsrc/client/hud/panel/strafehud.qc +++ b/qcsrc/client/hud/panel/strafehud.qc @@ -95,10 +95,8 @@ void HUD_StrafeHUD() static float demo_angle = -37; static float demo_direction = 1; static float demo_time = 0; - static bool state_onground = false; - static float state_onground_time = 0; - static bool state_strafekeys = false; - static float state_strafekeys_time = 0; + static float onground_lasttime = 0; + static float turn_lasttime = 0; static bool turn = false; static float turnangle; static float turnspeed; @@ -110,7 +108,10 @@ void HUD_StrafeHUD() static float dt = 0; // physics - bool onground = islocal ? IS_ONGROUND(strafeplayer) : !(strafeplayer.anim_implicit_state & ANIMIMPLICITSTATE_INAIR); + int keys = STAT(PRESSED_KEYS); + bool jumpheld = islocal ? (PHYS_INPUT_BUTTON_JUMP(strafeplayer) || PHYS_INPUT_BUTTON_JETPACK(strafeplayer)) : (keys & KEY_JUMP); // doesn't work in spectator mode if spectated player uses +jetpack + bool onground = (islocal ? IS_ONGROUND(strafeplayer) : !(strafeplayer.anim_implicit_state & ANIMIMPLICITSTATE_INAIR)) && !jumpheld; // if jump is held assume we are in air + bool onground_expired; bool strafekeys; bool swimming = strafe_waterlevel >= WATERLEVEL_SWIMMING; // the hud will not work well while swimming bool spectating = entcs_GetSpecState(strafeplayer.sv_entnum) == ENTCS_SPEC_PURE; @@ -126,7 +127,6 @@ void HUD_StrafeHUD() float view_angle = PHYS_INPUT_ANGLES(strafeplayer).y; float angle; vector movement = PHYS_INPUT_MOVEVALUES(strafeplayer); - int keys = STAT(PRESSED_KEYS); int keys_fwd; float wishangle = 0; @@ -170,6 +170,25 @@ void HUD_StrafeHUD() float range_minangle; float arrow_size = max(panel_size.y * min(autocvar_hud_panel_strafehud_angle_arrow_size, 10), 0); // there's only one size cvar for the arrows, they will always have a 45° angle to ensure proper rendering without antialiasing + if(onground) onground_lasttime = time; + else if(jumpheld) onground_lasttime = 0; + + if(onground_lasttime == 0) + onground_expired = true; + else + onground_expired = (time - onground_lasttime) >= autocvar_hud_panel_strafehud_timeout_ground; + + if(!onground && !onground_expired) // if ground timeout hasn't expired yet use ground physics + { + onground = true; + if(!autocvar__hud_configure) + maxaccel = PHYS_ACCELERATE(strafeplayer); + } + + movespeed = vlen(vec2(movement)); + if(movespeed == 0) movespeed = maxspeed; + else movespeed = min(movespeed, maxspeed); + if(!autocvar_hud_panel_strafehud_uncapped) arrow_size = max(arrow_size, 1); @@ -192,7 +211,7 @@ void HUD_StrafeHUD() dt_time = dt_sum = 0; } } - else + else // when spectating other players server ticrate will be used, this may not be accurate but there is no way to find other player's frametime { dt = ticrate; dt_update = dt_time = dt_sum = 0; @@ -315,36 +334,20 @@ void HUD_StrafeHUD() } // detect air strafe turning - if(onground != state_onground) - { - state_onground_time = time; - } - state_onground = onground; - - if(strafekeys != state_strafekeys) - { - state_strafekeys_time = time; - } - state_strafekeys = strafekeys; - - if((!strafekeys && vlen(vec2(movement)) > 0) || autocvar__hud_configure) + if((!strafekeys && vlen(vec2(movement)) > 0) || onground || autocvar__hud_configure) { turn = false; } - else if(onground) - { - if((time - state_onground_time) >= autocvar_hud_panel_strafehud_timeout_ground) // timeout for strafe jumping in general - { - turn = false; - } - } else // air strafe only { + bool turn_expired = (time - turn_lasttime) >= autocvar_hud_panel_strafehud_timeout_turn; + if(strafekeys) { - if(((time - state_onground_time) >= autocvar_hud_panel_strafehud_timeout_air) || (keys & KEY_JUMP)) // timeout for slick ramps + if(onground_expired) // timeout for slick ramps { turn = true; // CPMA turning + turn_lasttime = time; turnangle = wishangle; // calculate the maximum air strafe speed and acceleration @@ -352,12 +355,9 @@ void HUD_StrafeHUD() if(PHYS_MAXAIRSTRAFESPEED(strafeplayer) != 0) { - maxspeed = GeomLerp(PHYS_MAXAIRSPEED(strafeplayer), strafity, PHYS_MAXAIRSTRAFESPEED(strafeplayer)); - maxspeed = min(maxspeed, PHYS_MAXAIRSPEED(strafeplayer) * maxspeed_mod); + maxspeed = min(maxspeed, GeomLerp(PHYS_MAXAIRSPEED(strafeplayer), strafity, PHYS_MAXAIRSTRAFESPEED(strafeplayer))); } - turnspeed = vlen(vec2(movement)); - if(turnspeed == 0) turnspeed = maxspeed; - else turnspeed = min(turnspeed, maxspeed); + turnspeed = movespeed = min(movespeed, maxspeed); if(PHYS_AIRSTRAFEACCELERATE(strafeplayer) != 0) { @@ -366,34 +366,17 @@ void HUD_StrafeHUD() turnaccel = maxaccel; } } - else if((time - state_strafekeys_time) >= autocvar_hud_panel_strafehud_timeout_turn) // timeout for jumping with strafe keys only + else if(turn) { - turn = false; - } - } - if(turn && (onground || !strafekeys)) // retain last state until strafe turning times out - { - wishangle = turnangle; - movespeed = turnspeed; - maxaccel = turnaccel; - } - else{ - movespeed = vlen(vec2(movement)); - if(movespeed == 0) movespeed = maxspeed; - else movespeed = min(movespeed, maxspeed); - - if(onground) - { - if((keys & KEY_JUMP) && ((time - state_onground_time) < autocvar_hud_panel_strafehud_timeout_ground)) // if ground timeout hasn't expired yet use air accelerate + if(!turn_expired) // retain last state until strafe turning times out { - maxaccel = !autocvar__hud_configure ? PHYS_AIRACCELERATE(strafeplayer) : 1; + wishangle = turnangle; + movespeed = turnspeed; + maxaccel = turnaccel; } - } - else - { - if(!(keys & KEY_JUMP) && ((time - state_onground_time) < autocvar_hud_panel_strafehud_timeout_air)) // if air timeout hasn't expired yet use ground accelerate + else // timeout for jumping with strafe keys only { - maxaccel = !autocvar__hud_configure ? PHYS_ACCELERATE(strafeplayer) : 1; + turn = false; } } } @@ -909,7 +892,7 @@ void HUD_StrafeHUD() static float jumpheight = 0, jumptime = 0; // displayed value and timestamp for fade out // tries to catch kill and spectate but those are not reliable - if((strafeplayer.velocity.z <= 0) || onground || swimming || IS_DEAD(strafeplayer) || spectating) + if((strafeplayer.velocity.z <= 0) || IS_ONGROUND(strafeplayer) || swimming || IS_DEAD(strafeplayer) || spectating) { height_min = height_max = strafeplayer.origin.z; } diff --git a/qcsrc/client/hud/panel/strafehud.qh b/qcsrc/client/hud/panel/strafehud.qh index 4d896b226..19365f8a1 100644 --- a/qcsrc/client/hud/panel/strafehud.qh +++ b/qcsrc/client/hud/panel/strafehud.qh @@ -51,8 +51,7 @@ float autocvar_hud_panel_strafehud_jumpheight_fade = 0; float autocvar_hud_panel_strafehud_jumpheight_min = 50; vector autocvar_hud_panel_strafehud_jumpheight_color = '0 1 0.75'; float autocvar_hud_panel_strafehud_jumpheight_size = 1.5; -float autocvar_hud_panel_strafehud_timeout_air = 0.1; -float autocvar_hud_panel_strafehud_timeout_ground = 0.03333333; +float autocvar_hud_panel_strafehud_timeout_ground = 0.1; float autocvar_hud_panel_strafehud_timeout_turn = 0.1; float autocvar_hud_panel_strafehud_antiflicker_angle = 0.01; float autocvar_hud_panel_strafehud_fps_update = 0.5; -- 2.39.2