X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=qcsrc%2Fclient%2Fhud%2Fpanel%2Fstrafehud.qc;h=41059c5271089d3749c67509097c0fa27f0adec1;hb=a3563a1ec60a460f7181e68091a6ea1695c9cdad;hp=ba1acb5e7c641be1f7ee474976bd075a97e3d5dd;hpb=f2d9bf21e6975a88883a287236427f9e485bea34;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/client/hud/panel/strafehud.qc b/qcsrc/client/hud/panel/strafehud.qc index ba1acb5e7..41059c527 100644 --- a/qcsrc/client/hud/panel/strafehud.qc +++ b/qcsrc/client/hud/panel/strafehud.qc @@ -4,13 +4,13 @@ #include #include -#include #include #include #include #include #include #include +#include #include // StrafeHUD (#25) @@ -22,26 +22,6 @@ void HUD_StrafeHUD_Export(int fh) float hidden_width; int direction; -float demo_angle = -37; -float demo_direction = 1; -float demo_time = 0; -bool state_onground = false; -float state_onground_time = 0; -bool state_strafekeys = false; -float state_strafekeys_time = 0; -bool turn = false; -float turnangle; -float turnspeed; -float turnaccel; -bool fwd = true; -float starttime = 0; -float startspeed = -1; -float jumptime = 0; -float jumpheight = -1; -float jumpheight_persistent = -1; -float jumpheight_prev = 0; -float jumpspeed_prev = 0; -bool jumprestart = true; // provide basic panel cvars to old clients // TODO remove them after a future release (0.8.2+) @@ -101,6 +81,24 @@ void HUD_StrafeHUD() // draw strafehud if(csqcplayer && strafeplayer) { + // presistent + 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 bool turn = false; + static float turnangle; + static float turnspeed; + static float turnaccel; + static bool fwd = true; + static float strafe_dt_time = 0; + static int strafe_dt_count = 0; + static float strafe_dt_sum = 0; + static float strafe_dt_avg = 0; + // physics bool onground = islocal ? IS_ONGROUND(strafeplayer) : !(strafeplayer.anim_implicit_state & ANIMIMPLICITSTATE_INAIR); bool strafekeys; @@ -112,8 +110,10 @@ void HUD_StrafeHUD() float maxspeed_phys = onground ? PHYS_MAXSPEED(strafeplayer) : PHYS_MAXAIRSPEED(strafeplayer); float maxspeed = !autocvar__hud_configure ? maxspeed_phys * crouch_mod * water_mod : 320; float movespeed; + float bestspeed; float maxaccel_phys = onground ? PHYS_ACCELERATE(strafeplayer) : PHYS_AIRACCELERATE(strafeplayer); float maxaccel = !autocvar__hud_configure ? maxaccel_phys * crouch_mod * water_mod : 1; + float frametime_phys; float vel_angle = vectoangles(strafeplayer.velocity).y - (vectoangles(strafeplayer.velocity).y > 180 ? 360 : 0); // change the range from 0° - 360° to -180° - 180° to match how view_angle represents angles float view_angle = PHYS_INPUT_ANGLES(strafeplayer).y; float angle; @@ -166,6 +166,27 @@ void HUD_StrafeHUD() if(!autocvar_hud_panel_strafehud_uncapped) arrow_size = max(arrow_size, 1); + // determine frametime + if((csqcplayer_status == CSQCPLAYERSTATUS_PREDICTED) && (input_timelength > 0)) + frametime_phys = input_timelength; + else + frametime_phys = ticrate; + + if(frametime_phys > .05) // server splits frames longer than 50 ms into two moves + frametime_phys /= 2; + + // calculate average frametime + strafe_dt_sum += frametime_phys; + ++strafe_dt_count; + + if(((time - strafe_dt_time) > autocvar_hud_panel_strafehud_fps_update) || (strafe_dt_time == 0)) + { + strafe_dt_avg = strafe_dt_sum / strafe_dt_count; + + strafe_dt_time = time; + strafe_dt_count = strafe_dt_sum = 0; + } + // determine whether the player is pressing forwards or backwards keys if(islocal) // if entity is local player { @@ -373,7 +394,9 @@ void HUD_StrafeHUD() } } - minspeed = autocvar_hud_panel_strafehud_switch_minspeed < 0 ? (movespeed - maxaccel) + antiflicker_speed : autocvar_hud_panel_strafehud_switch_minspeed; + maxaccel *= strafe_dt_avg * movespeed; + bestspeed = max(movespeed - maxaccel, 0); + minspeed = autocvar_hud_panel_strafehud_switch_minspeed < 0 ? bestspeed : autocvar_hud_panel_strafehud_switch_minspeed; // get current strafing angle ranging from -180° to +180° if(!autocvar__hud_configure) @@ -475,8 +498,8 @@ void HUD_StrafeHUD() } // best angle to strafe at - bestangle = (speed > (movespeed - maxaccel) ? acos((movespeed - maxaccel) / speed) : 0) * RAD2DEG * (direction < 0 ? -1 : 1); - prebestangle = (speed > movespeed ? acos(movespeed / speed) : 0) * RAD2DEG * (direction < 0 ? -1 : 1); + bestangle = (speed > bestspeed ? acos(bestspeed / speed) * RAD2DEG * (direction < 0 ? -1 : 1) : 0); + prebestangle = (speed > movespeed ? acos(movespeed / speed) * RAD2DEG * (direction < 0 ? -1 : 1) : 0); odd_bestangle = -bestangle - wishangle; bestangle -= wishangle; prebestangle -= wishangle; @@ -702,7 +725,7 @@ void HUD_StrafeHUD() drawfill(panel_pos + eX * (indicator_direction ? 0 : panel_size.x - direction_size_horizontal.x) + eY * panel_size.y, direction_size_horizontal, autocvar_hud_panel_strafehud_direction_color, autocvar_hud_panel_strafehud_direction_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); } - if(speed < ((movespeed - maxaccel) + antiflicker_speed) && !immobile) + if(speed <= bestspeed && !immobile) { bestangle_anywhere = true; // moving forward should suffice to gain speed } @@ -818,7 +841,8 @@ void HUD_StrafeHUD() // show speed when crossing the start trigger if(autocvar_hud_panel_strafehud_startspeed_fade > 0) { - float text_alpha = 0; + static float startspeed = 0, starttime = 0; // displayed value and timestamp for fade out + if((race_nextcheckpoint == 1) || (race_checkpoint == 254 && race_nextcheckpoint == 255)) // check if the start trigger was hit (will also trigger if the finish trigger was hit if those have the same ID) { if(starttime != race_checkpointtime) @@ -827,16 +851,10 @@ void HUD_StrafeHUD() startspeed = speed; } } - if(startspeed >= 0) - { - text_alpha = cos(((time - starttime) / autocvar_hud_panel_strafehud_startspeed_fade) * 90 * DEG2RAD); // fade non-linear like the physics panel does - if((time - starttime) > autocvar_hud_panel_strafehud_startspeed_fade) - { - startspeed = -1; - } - } - if(startspeed >= 0 && text_alpha > 0 && autocvar_hud_panel_strafehud_startspeed_size > 0) + + if((starttime > 0) && ((time - starttime) <= autocvar_hud_panel_strafehud_startspeed_fade) && autocvar_hud_panel_strafehud_startspeed_size > 0) { + float text_alpha = cos(((time - starttime) / autocvar_hud_panel_strafehud_startspeed_fade) * 90 * DEG2RAD); // fade non-linear like the physics panel does vector startspeed_size = panel_size; startspeed_size.y = autocvar_hud_panel_strafehud_startspeed_size; if(!autocvar_hud_panel_strafehud_uncapped) @@ -859,53 +877,35 @@ void HUD_StrafeHUD() drawstring_aspect(panel_pos + eY * (panel_size.y + text_offset), strcat(ftos_decimals(startspeed * speed_conversion_factor, 2), autocvar_hud_panel_strafehud_unit_show ? speed_unit : ""), startspeed_size, autocvar_hud_panel_strafehud_startspeed_color, text_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); } } - else - { - starttime = 0; - startspeed = -1; - } - // experimental: show height achieved by a single jump (doesn't work in low gravity and may not be 100% accurate) - if(autocvar_hud_panel_strafehud_jumpheight_fade > 0) + // show height achieved by a single jump + // FIXME: checking z position differences is unreliable (warpzones, teleporter, kill, etc) but using velocity to calculate jump height would be + // inaccurate in hud code (possibly different tick rate, doesn't run when hud isn't drawn, rounding errors) + if(autocvar_hud_panel_strafehud_jumpheight_fade > 0 && autocvar_hud_panel_strafehud_jumpheight_size > 0) { - float text_alpha = 0; - float jumpheight_min = max(autocvar_hud_panel_strafehud_jumpheight_min, 0); - float jumpheight_current = strafeplayer.origin.z; - float jumpspeed_current = strafeplayer.velocity.z; - if(jumpspeed_prev <= jumpspeed_current || jumpheight_prev > jumpheight_current || onground || swimming || IS_DEAD(strafeplayer) || spectating) + static float height_min = 0, height_max = 0; // ground and peak of jump z coordinates + 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) { - // tries to catch kill and spectate but those are not reliable, should just hook to kill/spectate/teleport and reset jump height there - jumprestart = true; + height_min = height_max = strafeplayer.origin.z; } - else + else if(strafeplayer.origin.z > height_max) { - if(jumpheight < 0 || jumprestart) - { - jumprestart = false; - jumpheight = 0; - } - else - { - jumpheight += jumpheight_current - jumpheight_prev; - } - if((jumpheight * length_conversion_factor) > jumpheight_min && jumpheight > jumpheight_persistent) + height_max = strafeplayer.origin.z; + float jumpheight_new = (height_max - height_min) * length_conversion_factor; + + if(jumpheight_new > max(autocvar_hud_panel_strafehud_jumpheight_min, 0)) { + jumpheight = jumpheight_new; jumptime = time; - jumpheight_persistent = jumpheight; } } - jumpheight_prev = jumpheight_current; - jumpspeed_prev = jumpspeed_current; - if(jumpheight_persistent > 0) - { - text_alpha = cos(((time - jumptime) / autocvar_hud_panel_strafehud_jumpheight_fade) * 90 * DEG2RAD); // fade non-linear like the physics panel does - if((time - jumptime) > autocvar_hud_panel_strafehud_jumpheight_fade) - { - jumpheight_persistent = -1; - } - } - if(jumpheight_persistent > 0 && text_alpha > 0 && autocvar_hud_panel_strafehud_jumpheight_size > 0) + + if((jumptime > 0) && (time - jumptime) <= autocvar_hud_panel_strafehud_jumpheight_fade) { + float text_alpha = cos(((time - jumptime) / autocvar_hud_panel_strafehud_jumpheight_fade) * 90 * DEG2RAD); // fade non-linear like the physics panel does vector jumpheight_size = panel_size; jumpheight_size.y = autocvar_hud_panel_strafehud_jumpheight_size; if(!autocvar_hud_panel_strafehud_uncapped) @@ -925,14 +925,9 @@ void HUD_StrafeHUD() } string length_unit = GetLengthUnit(autocvar_hud_panel_strafehud_unit); - drawstring_aspect(panel_pos - eY * (jumpheight_size.y + text_offset), strcat(ftos_decimals(jumpheight_persistent * length_conversion_factor, length_decimals), autocvar_hud_panel_strafehud_unit_show ? length_unit : ""), jumpheight_size, autocvar_hud_panel_strafehud_jumpheight_color, text_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); + drawstring_aspect(panel_pos - eY * (jumpheight_size.y + text_offset), strcat(ftos_decimals(jumpheight, length_decimals), autocvar_hud_panel_strafehud_unit_show ? length_unit : ""), jumpheight_size, autocvar_hud_panel_strafehud_jumpheight_color, text_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); } } - else - { - jumpheight_prev = jumpspeed_prev = 0; - jumpheight = jumpheight_persistent = -1; - } draw_endBoldFont(); } }