]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Move physics-state strafehud/physics hud code to ../common_physics.qc
authorotta8634 <k9wolf@pm.me>
Tue, 24 Sep 2024 13:30:09 +0000 (21:30 +0800)
committerotta8634 <k9wolf@pm.me>
Tue, 24 Sep 2024 13:37:28 +0000 (21:37 +0800)
The physics hud and strafehud require similar calculations/variables (e.g. vel,
onslick, speed, immobile, onground, jumpheld (& keys), swimming, alive_player).
Moved all associated code to client/hud/common_physics.qc which runs before the
HUDs are drawn. This prevents duplicate code.
Consequently, includes for these huds could be cleaned up.
Updated strafehud and physics hud code accordingly.
Added GeomLerp to common/physics/player.qh for strafehud.

12 files changed:
qcsrc/client/hud/_mod.inc
qcsrc/client/hud/_mod.qh
qcsrc/client/hud/common_physics.qc [new file with mode: 0644]
qcsrc/client/hud/common_physics.qh [new file with mode: 0644]
qcsrc/client/hud/hud.qc
qcsrc/client/hud/panel/physics.qc
qcsrc/client/hud/panel/physics.qh
qcsrc/client/hud/panel/strafehud.qc
qcsrc/common/_mod.inc
qcsrc/common/_mod.qh
qcsrc/common/ent_cs.qh
qcsrc/common/physics/player.qh

index e2b2c546a18b0c5a37e70b92023e99221b364d7c..b6849038524e036db62e8f57b366dcdc357b0768 100644 (file)
@@ -1,4 +1,5 @@
 // generated file; do not modify
+#include <client/hud/common_physics.qc>
 #include <client/hud/crosshair.qc>
 #include <client/hud/hud.qc>
 #include <client/hud/hud_config.qc>
index eb6324b46954a2efc7289a802bade4f600ad4324..6551a408b16526099c9050d20ff8e0413891a164 100644 (file)
@@ -1,4 +1,5 @@
 // generated file; do not modify
+#include <client/hud/common_physics.qh>
 #include <client/hud/crosshair.qh>
 #include <client/hud/hud.qh>
 #include <client/hud/hud_config.qh>
diff --git a/qcsrc/client/hud/common_physics.qc b/qcsrc/client/hud/common_physics.qc
new file mode 100644 (file)
index 0000000..816703f
--- /dev/null
@@ -0,0 +1,132 @@
+#include "common_physics.qh"
+
+#include <lib/csqcmodel/cl_player.qh>
+#include <common/physics/player.qh>
+#include <common/physics/movetypes/movetypes.qh>
+
+// non-local players
+#include <common/animdecide.qh> // anim_implicit_state
+#include <common/ent_cs.qh> // CSQCModel_server2csqc()
+
+void HUD_Physics_Init()
+{
+       // find out whether the local csqcmodel entity is valid
+       if(spectatee_status > 0 || isdemo())
+       {
+               islocal = false;
+               strafeplayer = CSQCModel_server2csqc(player_localentnum - 1);
+       }
+       else
+       {
+               islocal = true;
+               strafeplayer = csqcplayer;
+       }
+
+       if(csqcplayer && strafeplayer)
+               csqc_and_strafe_player = true;
+       else
+       {
+               csqc_and_strafe_player = false;
+               // Since both huds return (essentially) when this is false, no variables beyond this point need to be computed
+               return;
+       }
+
+       predicted = csqcplayer_status == CSQCPLAYERSTATUS_PREDICTED;
+
+       // check the player waterlevel without affecting the player entity, this way we can fetch waterlevel even if client prediction is disabled
+       {
+               // store old values
+               void old_contentstransition(int, int) = strafeplayer.contentstransition;
+               float old_watertype = strafeplayer.watertype;
+               float old_waterlevel = strafeplayer.waterlevel;
+
+               strafeplayer.contentstransition = func_null; // unset the contentstransition function if present
+               _Movetype_CheckWater(strafeplayer);
+               strafe_waterlevel = strafeplayer.waterlevel; // store the player waterlevel
+
+               // restore old values
+               strafeplayer.contentstransition = old_contentstransition;
+               strafeplayer.watertype = old_watertype;
+               strafeplayer.waterlevel = old_waterlevel;
+       }
+
+       movement_phys = PHYS_INPUT_MOVEVALUES(strafeplayer);
+       keys = STAT(PRESSED_KEYS);
+       // try to ignore if track_canjump is enabled, doesn't work in spectator mode if spectated player uses +jetpack or cl_movement_track_canjump
+       jumpheld = false;
+       if(islocal)
+       {
+               if((PHYS_INPUT_BUTTON_JUMP(strafeplayer) || PHYS_INPUT_BUTTON_JETPACK(strafeplayer)) && !PHYS_CL_TRACK_CANJUMP(strafeplayer))
+                       jumpheld = true;
+       }
+       else
+       {
+               if((keys & KEY_JUMP) && !PHYS_TRACK_CANJUMP(strafeplayer))
+                       jumpheld = true;
+       }
+
+       // doesn't get changed by ground timeout and isn't affected by jump input
+       real_onground                 = islocal ? IS_ONGROUND(strafeplayer) : !(strafeplayer.anim_implicit_state & ANIMIMPLICITSTATE_INAIR);
+       // doesn't get changed by ground timeout
+       real_onslick                  = false;
+       // if jump is held assume we are in air, avoids flickering of the hud when hitting the ground
+       onground                      = (real_onground && !jumpheld);
+       onslick                       = real_onslick;
+       // the hud will not work well while swimming
+       swimming                      = strafe_waterlevel >= WATERLEVEL_SWIMMING;
+       // use local csqcmodel entity for this even when spectating, flickers too much otherwise
+       vel_phys                      = csqcplayer.velocity;
+       speed_phys                    = vlen(vec2(vel_phys));
+       speed3d_phys                  = vlen(vel_phys);
+       immobile                      = speed_phys <= 0;
+
+       maxspeed_ground               = PHYS_MAXSPEED(strafeplayer);
+       maxspeed_air                  = PHYS_MAXAIRSPEED(strafeplayer);
+       maxspeed_airstrafe            = PHYS_MAXAIRSTRAFESPEED(strafeplayer);
+       maxaccel_ground               = PHYS_ACCELERATE(strafeplayer);
+       maxaccel_air                  = PHYS_AIRACCELERATE(strafeplayer);
+       maxaccel_airstrafe            = PHYS_AIRSTRAFEACCELERATE(strafeplayer);
+       // only the local csqcplayer entity contains this information even when spectating
+       maxspeed_mod                  = IS_DUCKED(csqcplayer) ? .5 : 1;
+       maxspeed_phys                 = onground ? maxspeed_ground : maxspeed_air;
+       maxspeed                      = maxspeed_phys * maxspeed_mod;
+       maxaccel_phys                 = onground ? maxaccel_ground : maxaccel_air;
+       maxaccel                      = maxaccel_phys;
+       stopspeed                     = PHYS_STOPSPEED(strafeplayer);
+       airstopaccel                  = PHYS_AIRSTOPACCELERATE(strafeplayer);
+       aircontrol                    = PHYS_AIRCONTROL(strafeplayer);
+       aircontrol_backwards          = PHYS_AIRCONTROL_BACKWARDS(strafeplayer) == 1;
+       aircontrol_power              = PHYS_AIRCONTROL_POWER(strafeplayer);
+       aircontrol_penalty            = PHYS_AIRCONTROL_PENALTY(strafeplayer);
+       airaccel_qw                   = PHYS_AIRACCEL_QW(strafeplayer) == 1;
+       friction_phys                 = PHYS_FRICTION(strafeplayer);
+
+       // change the range from 0° - 360° to -180° - 180° to match how view_angle represents angles
+       vel_angle                     = vectoangles(strafeplayer.velocity).y - (vectoangles(strafeplayer.velocity).y > 180 ? 360 : 0);
+       view_angle                    = PHYS_INPUT_ANGLES(strafeplayer).y;
+
+       if(onground)
+       {
+               if(friction_phys == 0)
+               {
+                       onslick = true;
+               }
+               else // don't use IS_ONSLICK(), it only works for the local player and only if client prediction is enabled
+               {
+                       trace_dphitq3surfaceflags = 0;
+                       tracebox(strafeplayer.origin, strafeplayer.mins, strafeplayer.maxs, strafeplayer.origin - '0 0 1', MOVE_NOMONSTERS, strafeplayer);
+                       onslick = trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK;
+               }
+               real_onslick = onslick;
+
+               onground_lasttime = time;
+               onslick_last = onslick;
+       }
+       else if(jumpheld || swimming)
+       {
+               onground_lasttime = 0;
+       }
+
+       strafefriction = onslick ? PHYS_FRICTION_SLICK(strafeplayer) : friction_phys;
+       alive_player   = (!IS_DEAD(strafeplayer) && IS_PLAYER(strafeplayer));
+}
diff --git a/qcsrc/client/hud/common_physics.qh b/qcsrc/client/hud/common_physics.qh
new file mode 100644 (file)
index 0000000..37d574a
--- /dev/null
@@ -0,0 +1,51 @@
+#pragma once
+
+// Shared by panel/strafehud.qc and panel/physics.qc, since hud some elements require the same variables/calculations
+// All PHYS_* macro calls are localised here
+// All csqcplayer related calls are also localised here
+
+void HUD_Physics_Init();
+
+entity strafeplayer;
+bool   islocal;
+bool   csqc_and_strafe_player;
+bool   predicted;
+
+float  strafe_waterlevel;
+vector movement_phys;
+int    keys;
+bool   jumpheld;
+bool   real_onground;
+bool   real_onslick;
+bool   onground;
+bool   onslick;
+bool   swimming;
+vector vel_phys; // NOTE: physics hud previously did this: vector vel = (csqcplayer ? csqcplayer.velocity : pmove_vel);
+float  speed_phys;
+float  speed3d_phys;
+bool   immobile;
+float  maxspeed_ground;
+float  maxspeed_air;
+float  maxspeed_airstrafe;
+float  maxaccel_ground;
+float  maxaccel_air;
+float  maxaccel_airstrafe;
+float  maxspeed_mod;
+float  maxspeed_phys;
+float  maxspeed;
+float  maxaccel_phys;
+float  maxaccel;
+float  stopspeed;
+float  airstopaccel;
+float  aircontrol;
+bool   aircontrol_backwards;
+float  aircontrol_power;
+float  aircontrol_penalty;
+bool   airaccel_qw;
+float  friction_phys;
+float  vel_angle;
+float  view_angle;
+float  onground_lasttime = 0;
+bool   onslick_last      = false;
+float  strafefriction;
+bool   alive_player;
index bf1db9e38fde5ab5586070beb7a4639907219190..0b9aebc51e8e34e5776f5f732637b32f06125db0 100644 (file)
@@ -4,6 +4,7 @@
 #include <client/hud/hud_config.qh>
 #include <client/hud/panel/chat.qh>
 #include <client/hud/panel/scoreboard.qh>
+#include <client/hud/common_physics.qh>
 #include <client/items/items.qh>
 #include <client/mapvoting.qh>
 #include <client/teamradar.qh>
@@ -701,6 +702,7 @@ void HUD_Main()
                prev_myteam = myteam;
        }
 
+       HUD_Physics_Init();
        HUD_Configure_Frame();
 
        if(scoreboard_fade_alpha == 1)
index 4aaf1407e22287dd07159c4153123aee2fe8a1e9..83b432b39433eb8885ecb77e564ec8062aef3d28 100644 (file)
@@ -1,9 +1,7 @@
 #include "physics.qh"
+#include <client/hud/common_physics.qh>
 
 #include <client/draw.qh>
-#include <lib/csqcmodel/cl_player.qh>
-#include <common/physics/player.qh>
-#include <common/physics/movetypes/movetypes.qh>
 
 // Physics (#15)
 
@@ -30,7 +28,7 @@ void HUD_Physics_Export(int fh)
        HUD_Write_Cvar("hud_panel_physics_text_scale");
 }
 
-vector acc_prevspeed;
+vector acc_prev_vel;
 float acc_prevtime, acc_avg, top_speed, top_speed_time, jump_speed, jump_speed_time, prev_vel_z = 0;
 float physics_update_time, discrete_speed, discrete_acceleration;
 void HUD_Physics()
@@ -55,20 +53,10 @@ void HUD_Physics()
                panel_size -= '2 2 0' * panel_bg_padding;
        }
 
-       draw_beginBoldFont();
+       if(!csqc_and_strafe_player)
+               return;
 
-       bool onslick = false;
-       if(IS_ONGROUND(csqcplayer))
-       {
-               if(PHYS_FRICTION(csqcplayer) == 0)
-                       onslick = true;
-               else // don't use IS_ONSLICK(), it only works for the local player and only if client prediction is enabled
-               {
-                       trace_dphitq3surfaceflags = 0;
-                       tracebox(csqcplayer.origin, csqcplayer.mins, csqcplayer.maxs, csqcplayer.origin - '0 0 1', MOVE_NOMONSTERS, csqcplayer);
-                       onslick = trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK;
-               }
-       }
+       draw_beginBoldFont();
 
        float acceleration_progressbar_scale = 0;
        if(autocvar_hud_panel_physics_progressbar && autocvar_hud_panel_physics_acceleration_progressbar_scale > 1)
@@ -82,15 +70,16 @@ void HUD_Physics()
 
        //compute speed
        float speed, conversion_factor = GetSpeedUnitFactor(autocvar_hud_speed_unit);
-       vector vel = (csqcplayer ? csqcplayer.velocity : pmove_vel);
-
        float max_speed = floor( autocvar_hud_panel_physics_speed_max * conversion_factor + 0.5 );
        if (autocvar__hud_configure)
+       {
                speed = floor( max_speed * 0.65 + 0.5 );
+               immobile = speed <= 0;
+       }
        else if(autocvar_hud_panel_physics_speed_vertical)
-               speed = floor( vlen(vel) * conversion_factor + 0.5 );
+               speed = floor( speed3d_phys * conversion_factor + 0.5 );
        else
-               speed = floor( vlen(vel - vel.z * '0 0 1') * conversion_factor + 0.5 );
+               speed = floor( speed_phys * conversion_factor + 0.5 );
 
        //compute acceleration
        float acceleration, f;
@@ -98,16 +87,15 @@ void HUD_Physics()
                acceleration = 0.45; //use a hardcoded value so that the hud responds to hud_panel_physics_acceleration_max changing
        else
        {
-               // 1 m/s = 0.0254 qu/s; 1 g = 9.80665 m/s^2
                f = time - acc_prevtime;
                if(autocvar_hud_panel_physics_acceleration_vertical)
-                       acceleration = (vlen(vel) - vlen(acc_prevspeed));
+                       acceleration = (speed3d_phys - vlen(acc_prev_vel));
                else
-                       acceleration = (vlen(vel - '0 0 1' * vel.z) - vlen(acc_prevspeed - '0 0 1' * acc_prevspeed.z));
+                       acceleration = (speed_phys - vlen(vec2(acc_prev_vel)));
 
-               acceleration = acceleration * (1 / max(0.0001, f)) * (0.0254 / 9.80665);
+               acceleration = acceleration * (1 / max(0.0001, f)) * ACCEL2GRAV;
 
-               acc_prevspeed = vel;
+               acc_prev_vel = vel_phys;
                acc_prevtime = time;
 
                if(autocvar_hud_panel_physics_acceleration_movingaverage)
@@ -177,22 +165,22 @@ void HUD_Physics()
        {
                if (autocvar__hud_configure)
                {
-                       top_speed = floor( max_speed * speed_size * 0.9 + 0.5 ); // slightly less than top speed text
+                       top_speed = floor( max_speed * speed_size * 0.9 + 0.5 ); //slightly less than top speed text
                        f = 1;
                }
                else
                {
-                       if(vel.z > prev_vel_z && !IS_DEAD(csqcplayer) && IS_PLAYER(csqcplayer))
+                       if(vel_phys.z > prev_vel_z && jumpheld && !onground && !swimming && alive_player)
                        {
-                               // FIXME: this includes some situations where the player doesn't explicitly jump (e.g. bouncing on ramp, jumppad)
-                               // maybe these can be left in?
+                               //NOTE: this includes some situations where the player doesn't explicitly jump (e.g. jumppad, weapon kb)
+                               //excluding them would be difficult. maybe they can be left in?
                                jump_speed = speed;
                                jump_speed_time = time;
                        }               
                        f = max(1, autocvar_hud_panel_physics_jumpspeed_time);
                        // divide by f to make it start from 1
                        f = cos( ((time - jump_speed_time) / f) * PI/2 );
-                       prev_vel_z = vel.z;
+                       prev_vel_z = vel_phys.z;
                }
                if (f > 0)
                {
@@ -210,7 +198,7 @@ void HUD_Physics()
        }
 
        //draw speed
-       if(speed)
+       if(!immobile)
        if(autocvar_hud_panel_physics_progressbar == 1 || autocvar_hud_panel_physics_progressbar == 2)
                HUD_Panel_DrawProgressBar(panel_pos + speed_offset, panel_size, "progressbar", speed/max_speed, 0, speed_baralign, autocvar_hud_progressbar_speed_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
        if (autocvar_hud_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 2)
index 500ef4a38ffc5e4e94e717e4197bd25818e4c2a7..c05207a04a554fc1e5969fd8ed53315253d3d43c 100644 (file)
@@ -27,3 +27,7 @@ float autocvar_hud_panel_physics_jumpspeed_time = 1;
 vector autocvar_hud_progressbar_acceleration_color;
 vector autocvar_hud_progressbar_acceleration_neg_color;
 vector autocvar_hud_progressbar_speed_color;
+
+// 1 m/s^2 = 0.0254 qu/s^2; 1 g = 9.80665 m/s^2
+const float ACCEL2GRAV = 0.00259007918096393775; // converts qu/s^2 acceleration to m/s^2, relative to real-world gravity
+// equivalent to 0.0254 / 9.80665
index 6164a48970986d4d1b43cbe621455874e9f786fc..ad302f310fd25a341546c857fafeac47fef2d7e4 100644 (file)
@@ -1,22 +1,19 @@
 // Author: Juhu
 
 #include "strafehud.qh"
+#include <client/hud/common_physics.qh>
 
 #include <client/draw.qh>
-#include <lib/csqcmodel/cl_player.qh>
-#include <common/physics/player.qh>
-#include <common/physics/movetypes/movetypes.qh>
 
 // non-essential
 #include <client/view.qh> // for v_flipped state
 
-// non-local players
-#include <common/animdecide.qh> // anim_implicit_state
-#include <common/ent_cs.qh> // CSQCModel_server2csqc()
-
 // start speed
 #include <client/hud/panel/racetimer.qh> // checkpoint information (race_*)
 
+// GeomLerp
+#include <common/physics/player.qh>
+
 // StrafeHUD (#25)
 
 void HUD_StrafeHUD_Export(int fh)
@@ -24,13 +21,9 @@ void HUD_StrafeHUD_Export(int fh)
        // allow saving cvars that aesthetically change the panel into hud skin files
 }
 
-float GeomLerp(float a, float _lerp, float b); // declare GeomLerp here since there's no header file for it
-
 void HUD_StrafeHUD()
 {
        static float hud_lasttime = 0;
-       entity strafeplayer;
-       bool islocal;
 
        // generic hud routines
        if(!autocvar__hud_configure)
@@ -55,134 +48,73 @@ void HUD_StrafeHUD()
                panel_size -= '2 2 0' * panel_bg_padding;
        }
 
-       // find out whether the local csqcmodel entity is valid
-       if(spectatee_status > 0 || isdemo())
-       {
-               islocal = false;
-               strafeplayer = CSQCModel_server2csqc(player_localentnum - 1);
-       }
-       else
-       {
-               islocal = true;
-               strafeplayer = csqcplayer;
-       }
-
        // draw strafehud
-       if(csqcplayer && strafeplayer)
+       if(csqc_and_strafe_player)
        {
-               float strafe_waterlevel;
-
-               // check the player waterlevel without affecting the player entity, this way we can fetch waterlevel even if client prediction is disabled
-               {
-                       // store old values
-                       void old_contentstransition(int, int) = strafeplayer.contentstransition;
-                       float old_watertype = strafeplayer.watertype;
-                       float old_waterlevel = strafeplayer.waterlevel;
-
-                       strafeplayer.contentstransition = func_null; // unset the contentstransition function if present
-                       _Movetype_CheckWater(strafeplayer);
-                       strafe_waterlevel = strafeplayer.waterlevel; // store the player waterlevel
-
-                       // restore old values
-                       strafeplayer.contentstransition = old_contentstransition;
-                       strafeplayer.watertype = old_watertype;
-                       strafeplayer.waterlevel = old_waterlevel;
-               }
+               float friction  = friction_phys;
+               float speed     = speed_phys;
+               vector movement = movement_phys;
 
-               int keys = STAT(PRESSED_KEYS);
-               // try to ignore if track_canjump is enabled, doesn't work in spectator mode if spectated player uses +jetpack or cl_movement_track_canjump
-               bool jumpheld = false;
-               if(islocal)
+               if(autocvar__hud_configure)
                {
-                       if((PHYS_INPUT_BUTTON_JUMP(strafeplayer) || PHYS_INPUT_BUTTON_JETPACK(strafeplayer)) && !PHYS_CL_TRACK_CANJUMP(strafeplayer))
-                               jumpheld = true;
-               }
-               else
-               {
-                       if((keys & KEY_JUMP) && !PHYS_TRACK_CANJUMP(strafeplayer))
-                               jumpheld = true;
+                       speed    = 1337;
+                       immobile = false;
+                       maxspeed = 320;
+                       maxaccel = 1;
                }
 
                // persistent
-               static float onground_lasttime       = 0;
-               static bool  onslick_last            = false;
-               static float turn_lasttime           = 0;
-               static bool  turn                    = false;
+               static float turn_lasttime          = 0;
+               static bool  turn                   = false;
                static float turnangle;
-               static float dt_update               = 0;
-               static int   dt_time                 = 0;
-               static float dt_sum                  = 0;
-               static float dt                      = 0;
+               static float dt_update              = 0;
+               static int   dt_time                = 0;
+               static float dt_sum                 = 0;
+               static float dt                     = 0;
 
                // physics
-               // doesn't get changed by ground timeout and isn't affected by jump input
-               bool   real_onground                 = islocal ? IS_ONGROUND(strafeplayer) : !(strafeplayer.anim_implicit_state & ANIMIMPLICITSTATE_INAIR);
-               // doesn't get changed by ground timeout
-               bool   real_onslick                  = false;
-               // if jump is held assume we are in air, avoids flickering of the hud when hitting the ground
-               bool   onground                      = real_onground && !jumpheld;
-               bool   onslick                       = real_onslick;
                bool   onground_expired;
                bool   strafekeys;
-               // the hud will not work well while swimming
-               bool   swimming                      = strafe_waterlevel >= WATERLEVEL_SWIMMING;
-               // use local csqcmodel entity for this even when spectating, flickers too much otherwise
-               float  speed                         = !autocvar__hud_configure ? vlen(vec2(csqcplayer.velocity)) : 1337;
-               // only the local csqcplayer entity contains this information even when spectating
-               float  maxspeed_mod                  = IS_DUCKED(csqcplayer) ? .5 : 1;
-               float  maxspeed_phys                 = onground ? PHYS_MAXSPEED(strafeplayer) : PHYS_MAXAIRSPEED(strafeplayer);
-               float  maxspeed                      = !autocvar__hud_configure ? maxspeed_phys * maxspeed_mod : 320;
                float  movespeed;
                float  bestspeed;
-               float  maxaccel_phys                 = onground ? PHYS_ACCELERATE(strafeplayer) : PHYS_AIRACCELERATE(strafeplayer);
-               float  maxaccel                      = !autocvar__hud_configure ? maxaccel_phys : 1;
-               float  airstopaccel                  = PHYS_AIRSTOPACCELERATE(strafeplayer);
-               float  aircontrol                    = PHYS_AIRCONTROL(strafeplayer);
-               bool   aircontrol_backwards          = PHYS_AIRCONTROL_BACKWARDS(strafeplayer) == 1;
-               bool   airaccel_qw                   = PHYS_AIRACCEL_QW(strafeplayer) == 1;
-               // change the range from 0° - 360° to -180° - 180° to match how view_angle represents angles
-               float  vel_angle                     = vectoangles(strafeplayer.velocity).y - (vectoangles(strafeplayer.velocity).y > 180 ? 360 : 0);
-               float  view_angle                    = PHYS_INPUT_ANGLES(strafeplayer).y;
                float  angle;
-               vector movement                      = PHYS_INPUT_MOVEVALUES(strafeplayer);
                bool   fwd; // left & right variables are flipped when !fwd
                int    keys_fwd;
                float  wishangle;
                int    direction;
-               float  strafity                      = 0;
+               float  strafity                     = 0;
 
                // HUD
                int    mode;
-               float  speed_conversion_factor       = GetSpeedUnitFactor(autocvar_hud_speed_unit);
-               float  length_conversion_factor      = GetLengthUnitFactor(autocvar_hud_speed_unit);
+               float  speed_conversion_factor      = GetSpeedUnitFactor(autocvar_hud_speed_unit);
+               float  length_conversion_factor     = GetLengthUnitFactor(autocvar_hud_speed_unit);
                // use more decimals when displaying km or miles
-               int    length_decimals               = autocvar_hud_speed_unit >= 3 && autocvar_hud_speed_unit <= 5 ? 6 : 2;
-               float  antiflicker_angle             = bound(0, autocvar_hud_panel_strafehud_antiflicker_angle, 180);
+               int    length_decimals              = autocvar_hud_speed_unit >= 3 && autocvar_hud_speed_unit <= 5 ? 6 : 2;
+               float  antiflicker_angle            = bound(0, autocvar_hud_panel_strafehud_antiflicker_angle, 180);
                float  minspeed;
-               float  shift_offset                  = 0;
-               bool   straight_overturn             = false;
-               bool   immobile                      = speed <= 0;
+               float  shift_offset                 = 0;
+               bool   straight_overturn            = false;
                float  hudangle;
                float  hidden_width;
                float  neutral_offset;
                float  neutral_width;
-               vector currentangle_color            = autocvar_hud_panel_strafehud_angle_neutral_color;
+               vector currentangle_color           = autocvar_hud_panel_strafehud_angle_neutral_color;
                float  currentangle_offset;
                vector currentangle_size;
                float  bestangle;
                float  prebestangle;
                float  overturn_angle;
                float  odd_bestangle;
-               float  bestangle_offset              = 0;
-               float  switch_bestangle_offset       = 0;
-               bool   odd_angles                    = false;
-               float  odd_bestangle_offset          = 0;
-               float  switch_odd_bestangle_offset   = 0;
-               float  switch_bestangle_width        = 0;
-               float  wturn_bestangle               = 0;
-               float  wturn_left_bestangle_offset   = 0;
-               float  wturn_right_bestangle_offset  = 0;
-               float  wturn_bestangle_width         = 0;
+               float  bestangle_offset             = 0;
+               float  switch_bestangle_offset      = 0;
+               bool   odd_angles                   = false;
+               float  odd_bestangle_offset         = 0;
+               float  switch_odd_bestangle_offset  = 0;
+               float  switch_bestangle_width       = 0;
+               float  wturn_bestangle              = 0;
+               float  wturn_left_bestangle_offset  = 0;
+               float  wturn_right_bestangle_offset = 0;
+               float  wturn_bestangle_width        = 0;
                float  accelzone_left_offset;
                float  accelzone_right_offset;
                float  accelzone_width;
@@ -192,17 +124,17 @@ void HUD_StrafeHUD()
                float  overturn_offset;
                float  overturn_width;
                float  slickdetector_height;
-               vector direction_size_vertical       = '0 0 0';
-               vector direction_size_horizontal     = '0 0 0';
+               vector direction_size_vertical      = '0 0 0';
+               vector direction_size_horizontal    = '0 0 0';
                float  range_minangle;
-               float  text_offset_top               = 0;
-               float  text_offset_bottom            = 0;
+               float  text_offset_top              = 0;
+               float  text_offset_bottom           = 0;
 
                // real_* variables which are always positive with no wishangle offset
                float  real_bestangle;
                float  real_prebestangle;
                float  real_overturn_angle;
-               float  real_wturn_bestangle          = 0;
+               float  real_wturn_bestangle         = 0;
 
                if(autocvar_hud_panel_strafehud_mode >= 0 && autocvar_hud_panel_strafehud_mode <= 1)
                        mode = autocvar_hud_panel_strafehud_mode;
@@ -212,28 +144,6 @@ void HUD_StrafeHUD()
                // there's only one size cvar for the arrows, they will always have a 45° angle to ensure proper rendering without antialiasing
                float arrow_size = max(panel_size.y * min(autocvar_hud_panel_strafehud_angle_arrow_size, 10), 0);
 
-               if(onground)
-               {
-                       if(PHYS_FRICTION(strafeplayer) == 0)
-                       {
-                               onslick = true;
-                       }
-                       else // don't use IS_ONSLICK(), it only works for the local player and only if client prediction is enabled
-                       {
-                               trace_dphitq3surfaceflags = 0;
-                               tracebox(strafeplayer.origin, strafeplayer.mins, strafeplayer.maxs, strafeplayer.origin - '0 0 1', MOVE_NOMONSTERS, strafeplayer);
-                               onslick = trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK;
-                       }
-                       real_onslick = onslick;
-
-                       onground_lasttime = time;
-                       onslick_last = onslick;
-               }
-               else if(jumpheld || swimming)
-               {
-                       onground_lasttime = 0;
-               }
-
                if(onground_lasttime == 0)
                        onground_expired = true;
                else
@@ -246,8 +156,8 @@ void HUD_StrafeHUD()
 
                        if(!autocvar__hud_configure)
                        {
-                               maxspeed = PHYS_MAXSPEED(strafeplayer) * maxspeed_mod;
-                               maxaccel = PHYS_ACCELERATE(strafeplayer);
+                               maxspeed = maxspeed_ground * maxspeed_mod;
+                               maxaccel = maxaccel_ground;
                        }
                }
 
@@ -261,7 +171,7 @@ void HUD_StrafeHUD()
                        arrow_size = max(arrow_size, 1);
 
                // determine frametime
-               if((csqcplayer_status == CSQCPLAYERSTATUS_PREDICTED) && (input_timelength > 0))
+               if(predicted && (input_timelength > 0))
                {
                        float dt_client = input_timelength;
 
@@ -383,13 +293,13 @@ void HUD_StrafeHUD()
                                // calculate the maximum air strafe speed and acceleration
                                strafity = 1 - (90 - fabs(wishangle)) / 45;
 
-                               if(PHYS_MAXAIRSTRAFESPEED(strafeplayer) != 0)
-                                       maxspeed = min(maxspeed, GeomLerp(PHYS_MAXAIRSPEED(strafeplayer), strafity, PHYS_MAXAIRSTRAFESPEED(strafeplayer)));
+                               if(maxspeed_airstrafe != 0)
+                                       maxspeed = min(maxspeed, GeomLerp(maxspeed_air, strafity, maxspeed_airstrafe));
 
                                movespeed = min(movespeed, maxspeed);
 
-                               if(PHYS_AIRSTRAFEACCELERATE(strafeplayer) != 0)
-                                       maxaccel = GeomLerp(PHYS_AIRACCELERATE(strafeplayer), strafity, PHYS_AIRSTRAFEACCELERATE(strafeplayer));
+                               if(maxaccel_airstrafe != 0)
+                                       maxaccel = GeomLerp(maxaccel_air, strafity, maxaccel_airstrafe);
                        }
                }
 
@@ -401,9 +311,7 @@ void HUD_StrafeHUD()
 
                if((speed > 0) && onground)
                {
-                       float strafefriction = onslick ? PHYS_FRICTION_SLICK(strafeplayer) : PHYS_FRICTION(strafeplayer);
-
-                       frictionspeed = speed * dt * strafefriction * max(PHYS_STOPSPEED(strafeplayer) / speed, 1);
+                       frictionspeed = speed * dt * strafefriction * max(stopspeed / speed, 1);
                        strafespeed = max(speed - frictionspeed, 0);
                }
                else
@@ -633,11 +541,11 @@ void HUD_StrafeHUD()
                 * this doesn't have support for sv_aircontrol_sideways == 1
                 */
                bool wturning    = !onground && wishangle == 0 && (keys_fwd == STRAFEHUD_KEYS_FORWARD || (aircontrol_backwards && keys_fwd == STRAFEHUD_KEYS_BACKWARD));
-               bool wturn_valid = aircontrol && PHYS_AIRCONTROL_PENALTY(strafeplayer) == 0 && (airaccel_qw || autocvar_hud_panel_strafehud_wturn_unrestricted == 1);
+               bool wturn_valid = aircontrol && aircontrol_penalty == 0 && (airaccel_qw || autocvar_hud_panel_strafehud_wturn_unrestricted == 1);
                bool wturn_check = autocvar_hud_panel_strafehud_wturn && !immobile && wturn_valid;
                if(wturn_check)
                {
-                       float wturn_power = PHYS_AIRCONTROL_POWER(strafeplayer);
+                       float wturn_power = aircontrol_power;
                        if(wturn_power == 2)
                        {
                                float wturn_a = 32 * aircontrol * dt;
@@ -672,9 +580,9 @@ void HUD_StrafeHUD()
                if(draw_normal)
                {
                        // recalculate bestangle as if strafing normally
-                       float n_maxspeed  = PHYS_MAXAIRSPEED(strafeplayer) * maxspeed_mod;
+                       float n_maxspeed  = maxspeed_air * maxspeed_mod;
                        float n_movespeed = n_maxspeed;
-                       float n_maxaccel  = PHYS_AIRACCELERATE(strafeplayer) * dt * n_movespeed;
+                       float n_maxaccel  = maxaccel_air * dt * n_movespeed;
                        float n_bestspeed = max(n_movespeed - n_maxaccel, 0);
                        n_bestangle = speed > n_bestspeed
                                ? acos(n_bestspeed / speed) * RAD2DEG - 45
@@ -1004,7 +912,7 @@ void HUD_StrafeHUD()
                                        slickoffset.y = cos(j) * slickrotate;
 
                                        traceline(traceorigin, traceorigin + slickoffset, MOVE_NOMONSTERS, strafeplayer);
-                                       if((PHYS_FRICTION(strafeplayer) == 0 && trace_fraction < 1)
+                                       if((friction == 0 && trace_fraction < 1)
                                        || (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK))
                                                slickdetected = true;
                                        if(i == 0)
@@ -1271,7 +1179,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) || real_onground || swimming || IS_DEAD(strafeplayer) || !IS_PLAYER(strafeplayer))
+                       if((strafeplayer.velocity.z <= 0) || real_onground || swimming || !alive_player)
                        {
                                height_min = height_max = strafeplayer.origin.z;
                        }
index 4a45c1edb0123b87fa606dbf2d1d916a62df9717..c63e54d75ce19d9edbb71f406dce56a70efb03f2 100644 (file)
@@ -3,6 +3,7 @@
 #include <common/animdecide.qc>
 #include <common/campaign_file.qc>
 #include <common/campaign_setup.qc>
+#include <common/checkextension.qc>
 #include <common/ent_cs.qc>
 #include <common/mapinfo.qc>
 #include <common/net_notice.qc>
index f8461f41e2d2148b4ed5f856cbc8360332ca68f0..b0303432e9a9a42f7bc6a54395dd7ebf7d6b8ba2 100644 (file)
@@ -3,6 +3,7 @@
 #include <common/animdecide.qh>
 #include <common/campaign_file.qh>
 #include <common/campaign_setup.qh>
+#include <common/checkextension.qh>
 #include <common/ent_cs.qh>
 #include <common/mapinfo.qh>
 #include <common/net_notice.qh>
index 3c96661e60b678c5cd2db85ef57d7d200d11bbe1..2834c0e57907988d4ab94aaa43a0ad48810d8cf9 100644 (file)
@@ -1,7 +1,8 @@
 #pragma once
 
 #ifdef CSQC
-#include <client/csqcmodel_hooks.qh>
+       #include <client/csqcmodel_hooks.qh>
+       #include <client/main.qh> // for playerslots
 #endif
 
 REGISTER_NET_LINKED(ENT_CLIENT_ENTCS)
index 3c14bea6dc0d0793f3962340d53867c5cfb4a8a9..f66860f6fcf0c26f772c50a4d4b1b6880562700b 100644 (file)
@@ -370,3 +370,6 @@ NET_HANDLE(setpause, bool)
        return true;
 }
 #endif
+
+// used elsewhere, like in strafehud
+float GeomLerp(float, float, float);