From: otta8634 Date: Tue, 24 Sep 2024 13:30:09 +0000 (+0800) Subject: Move physics-state strafehud/physics hud code to ../common_physics.qc X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=ca404af93ce6f6b3d866a347fc4c655b09840267;p=xonotic%2Fxonotic-data.pk3dir.git Move physics-state strafehud/physics hud code to ../common_physics.qc 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. --- diff --git a/qcsrc/client/hud/_mod.inc b/qcsrc/client/hud/_mod.inc index e2b2c546a..b68490385 100644 --- a/qcsrc/client/hud/_mod.inc +++ b/qcsrc/client/hud/_mod.inc @@ -1,4 +1,5 @@ // generated file; do not modify +#include #include #include #include diff --git a/qcsrc/client/hud/_mod.qh b/qcsrc/client/hud/_mod.qh index eb6324b46..6551a408b 100644 --- a/qcsrc/client/hud/_mod.qh +++ b/qcsrc/client/hud/_mod.qh @@ -1,4 +1,5 @@ // generated file; do not modify +#include #include #include #include diff --git a/qcsrc/client/hud/common_physics.qc b/qcsrc/client/hud/common_physics.qc new file mode 100644 index 000000000..816703fdc --- /dev/null +++ b/qcsrc/client/hud/common_physics.qc @@ -0,0 +1,132 @@ +#include "common_physics.qh" + +#include +#include +#include + +// non-local players +#include // anim_implicit_state +#include // 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 index 000000000..37d574aae --- /dev/null +++ b/qcsrc/client/hud/common_physics.qh @@ -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; diff --git a/qcsrc/client/hud/hud.qc b/qcsrc/client/hud/hud.qc index bf1db9e38..0b9aebc51 100644 --- a/qcsrc/client/hud/hud.qc +++ b/qcsrc/client/hud/hud.qc @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -701,6 +702,7 @@ void HUD_Main() prev_myteam = myteam; } + HUD_Physics_Init(); HUD_Configure_Frame(); if(scoreboard_fade_alpha == 1) diff --git a/qcsrc/client/hud/panel/physics.qc b/qcsrc/client/hud/panel/physics.qc index 4aaf1407e..83b432b39 100644 --- a/qcsrc/client/hud/panel/physics.qc +++ b/qcsrc/client/hud/panel/physics.qc @@ -1,9 +1,7 @@ #include "physics.qh" +#include #include -#include -#include -#include // 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) diff --git a/qcsrc/client/hud/panel/physics.qh b/qcsrc/client/hud/panel/physics.qh index 500ef4a38..c05207a04 100644 --- a/qcsrc/client/hud/panel/physics.qh +++ b/qcsrc/client/hud/panel/physics.qh @@ -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 diff --git a/qcsrc/client/hud/panel/strafehud.qc b/qcsrc/client/hud/panel/strafehud.qc index 6164a4897..ad302f310 100644 --- a/qcsrc/client/hud/panel/strafehud.qc +++ b/qcsrc/client/hud/panel/strafehud.qc @@ -1,22 +1,19 @@ // Author: Juhu #include "strafehud.qh" +#include #include -#include -#include -#include // non-essential #include // for v_flipped state -// non-local players -#include // anim_implicit_state -#include // CSQCModel_server2csqc() - // start speed #include // checkpoint information (race_*) +// GeomLerp +#include + // 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; } diff --git a/qcsrc/common/_mod.inc b/qcsrc/common/_mod.inc index 4a45c1edb..c63e54d75 100644 --- a/qcsrc/common/_mod.inc +++ b/qcsrc/common/_mod.inc @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include diff --git a/qcsrc/common/_mod.qh b/qcsrc/common/_mod.qh index f8461f41e..b0303432e 100644 --- a/qcsrc/common/_mod.qh +++ b/qcsrc/common/_mod.qh @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include diff --git a/qcsrc/common/ent_cs.qh b/qcsrc/common/ent_cs.qh index 3c96661e6..2834c0e57 100644 --- a/qcsrc/common/ent_cs.qh +++ b/qcsrc/common/ent_cs.qh @@ -1,7 +1,8 @@ #pragma once #ifdef CSQC -#include + #include + #include // for playerslots #endif REGISTER_NET_LINKED(ENT_CLIENT_ENTCS) diff --git a/qcsrc/common/physics/player.qh b/qcsrc/common/physics/player.qh index 3c14bea6d..f66860f6f 100644 --- a/qcsrc/common/physics/player.qh +++ b/qcsrc/common/physics/player.qh @@ -370,3 +370,6 @@ NET_HANDLE(setpause, bool) return true; } #endif + +// used elsewhere, like in strafehud +float GeomLerp(float, float, float);