]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
strafehud: detect zero friction frame on landing, remove ground timeout which became...
authorJuhu <5894800-Juhu_@users.noreply.gitlab.com>
Wed, 14 Sep 2022 08:07:21 +0000 (10:07 +0200)
committerJuhu <5894800-Juhu_@users.noreply.gitlab.com>
Wed, 14 Sep 2022 08:09:26 +0000 (10:09 +0200)
_hud_common.cfg
qcsrc/client/hud/panel/strafehud.qc
qcsrc/client/hud/panel/strafehud.qh

index 00977a49de7f4b05dbdf019f79ebdcaf67c22411..c236229f27ee72733723149060a4100506d4158a 100644 (file)
@@ -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"
index 3fc1355d51f408ddece64701fa0a05a2edcd6109..49a627185ab4fe4de42573331ab03ebe62d1c9b7 100644 (file)
@@ -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;
             }
index 4d896b226ce03c2e16ed29d43338328b387a8e65..19365f8a123fe39b82e6857b3b56900267a968fc 100644 (file)
@@ -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;