From: Juhu <5894800-Juhu_@users.noreply.gitlab.com> Date: Sun, 12 Jan 2025 12:48:28 +0000 (+0100) Subject: strafehud: applied review changes by k9er X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=88170504557665e2f112481610f22fc027f97d1b;p=xonotic%2Fxonotic-data.pk3dir.git strafehud: applied review changes by k9er --- diff --git a/qcsrc/client/hud/panel/strafehud.qc b/qcsrc/client/hud/panel/strafehud.qc index 050c4c28f..45e7bad2b 100644 --- a/qcsrc/client/hud/panel/strafehud.qc +++ b/qcsrc/client/hud/panel/strafehud.qc @@ -31,9 +31,13 @@ void HUD_StrafeHUD() // generic hud routines if(!autocvar__hud_configure) { - if(!autocvar_hud_panel_strafehud || - (spectatee_status == -1 && (autocvar_hud_panel_strafehud == 1 || autocvar_hud_panel_strafehud == 3)) || - (autocvar_hud_panel_strafehud == 3 && !MUTATOR_CALLHOOK(HUD_StrafeHUD_showoptional))) { hud_lasttime = time; return; } + if(!autocvar_hud_panel_strafehud + || (spectatee_status == -1 && (autocvar_hud_panel_strafehud == 1 || autocvar_hud_panel_strafehud == 3)) + || (autocvar_hud_panel_strafehud == 3 && !MUTATOR_CALLHOOK(HUD_StrafeHUD_showoptional))) + { + hud_lasttime = time; + return; + } } HUD_Panel_LoadCvars(); @@ -63,7 +67,11 @@ void HUD_StrafeHUD() strafeplayer = csqcplayer; } - if(!csqcplayer || !strafeplayer) { hud_lasttime = time; return; } + if(!csqcplayer || !strafeplayer) + { + hud_lasttime = time; + return; + } // draw strafehud @@ -606,7 +614,7 @@ void HUD_StrafeHUD() indicator_size.y = max(panel_size.y * min(autocvar_hud_panel_strafehud_switch_line_height, 10), 1); indicator_size.z = 0; - float num_dashes = nearbyint(autocvar_hud_panel_strafehud_switch_line); + float num_dashes = rint(autocvar_hud_panel_strafehud_switch_line); bool has_top_arrow = autocvar_hud_panel_strafehud_switch_arrow == 1 || autocvar_hud_panel_strafehud_switch_arrow >= 3; bool has_bottom_arrow = autocvar_hud_panel_strafehud_switch_arrow >= 2; @@ -651,7 +659,7 @@ void HUD_StrafeHUD() indicator_size.y = max(panel_size.y * min(autocvar_hud_panel_strafehud_bestangle_line_height, 10), 1); indicator_size.z = 0; - float num_dashes = nearbyint(autocvar_hud_panel_strafehud_bestangle_line); + float num_dashes = rint(autocvar_hud_panel_strafehud_bestangle_line); bool has_top_arrow = autocvar_hud_panel_strafehud_bestangle_arrow == 1 || autocvar_hud_panel_strafehud_bestangle_arrow >= 3; bool has_bottom_arrow = autocvar_hud_panel_strafehud_bestangle_arrow >= 2; @@ -687,7 +695,7 @@ void HUD_StrafeHUD() indicator_size.y = max(panel_size.y * min(autocvar_hud_panel_strafehud_wturn_line_height, 10), 1); indicator_size.z = 0; - float num_dashes = nearbyint(autocvar_hud_panel_strafehud_wturn_line); + float num_dashes = rint(autocvar_hud_panel_strafehud_wturn_line); bool has_top_arrow = autocvar_hud_panel_strafehud_wturn_arrow == 1 || autocvar_hud_panel_strafehud_wturn_arrow >= 3; bool has_bottom_arrow = autocvar_hud_panel_strafehud_wturn_arrow >= 2; @@ -720,7 +728,7 @@ void HUD_StrafeHUD() indicator_size.y = max(panel_size.y * min(autocvar_hud_panel_strafehud_angle_line_height, 10), 1); indicator_size.z = 0; - float num_dashes = nearbyint(autocvar_hud_panel_strafehud_angle_line); + float num_dashes = rint(autocvar_hud_panel_strafehud_angle_line); bool has_top_arrow = autocvar_hud_panel_strafehud_angle_arrow == 1 || autocvar_hud_panel_strafehud_angle_arrow >= 3; bool has_bottom_arrow = autocvar_hud_panel_strafehud_angle_arrow >= 2; diff --git a/qcsrc/client/hud/panel/strafehud.qh b/qcsrc/client/hud/panel/strafehud.qh index 7497fe275..a84d8abf5 100644 --- a/qcsrc/client/hud/panel/strafehud.qh +++ b/qcsrc/client/hud/panel/strafehud.qh @@ -1,9 +1,6 @@ #pragma once #include "../panel.qh" -#include "strafehud/util.qh" -#include "strafehud/draw.qh" -#include "strafehud/core.qh" -#include "strafehud/extra.qh" +#include int autocvar_hud_panel_strafehud = 3; bool autocvar__hud_panel_strafehud_demo = false; @@ -15,6 +12,12 @@ int autocvar_hud_panel_strafehud_style = 2; bool autocvar_hud_panel_strafehud_unit_show = true; int autocvar_hud_panel_strafehud_onground_mode = 2; bool autocvar_hud_panel_strafehud_onground_friction = true; + +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; + bool autocvar_hud_panel_strafehud_bar_preaccel = true; vector autocvar_hud_panel_strafehud_bar_preaccel_color = '0 1 0'; float autocvar_hud_panel_strafehud_bar_preaccel_alpha = 0.5; @@ -24,6 +27,7 @@ vector autocvar_hud_panel_strafehud_bar_accel_color = '0 1 0'; float autocvar_hud_panel_strafehud_bar_accel_alpha = 0.5; vector autocvar_hud_panel_strafehud_bar_overturn_color = '1 0 1'; float autocvar_hud_panel_strafehud_bar_overturn_alpha = 0.5; + float autocvar_hud_panel_strafehud_angle_alpha = 0.8; vector autocvar_hud_panel_strafehud_angle_preaccel_color = '0 1 1'; vector autocvar_hud_panel_strafehud_angle_neutral_color = '1 1 0'; @@ -61,17 +65,20 @@ float autocvar_hud_panel_strafehud_wturn_line_width = 0.001; float autocvar_hud_panel_strafehud_wturn_line_height = 1; int autocvar_hud_panel_strafehud_wturn_arrow = 1; float autocvar_hud_panel_strafehud_wturn_arrow_size = 0.5; + bool autocvar_hud_panel_strafehud_direction = false; vector autocvar_hud_panel_strafehud_direction_color = '0 0.5 1'; float autocvar_hud_panel_strafehud_direction_alpha = 1; float autocvar_hud_panel_strafehud_direction_width = 0.25; float autocvar_hud_panel_strafehud_direction_length = 0.02; + bool autocvar_hud_panel_strafehud_slickdetector = true; float autocvar_hud_panel_strafehud_slickdetector_range = 200; int autocvar_hud_panel_strafehud_slickdetector_granularity = 1; vector autocvar_hud_panel_strafehud_slickdetector_color = '0 1 1'; float autocvar_hud_panel_strafehud_slickdetector_alpha = 0.5; float autocvar_hud_panel_strafehud_slickdetector_height = 0.125; + bool autocvar_hud_panel_strafehud_startspeed = true; float autocvar_hud_panel_strafehud_startspeed_fade = 4; vector autocvar_hud_panel_strafehud_startspeed_color = '1 0.75 0'; @@ -83,10 +90,15 @@ float autocvar_hud_panel_strafehud_jumpheight_min = 50; vector autocvar_hud_panel_strafehud_jumpheight_color = '0 1 0.75'; vector autocvar_hud_panel_strafehud_jumpheight_pos = '0 -2 0'; float autocvar_hud_panel_strafehud_jumpheight_size = 1.5; -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; +bool autocvar_hud_panel_strafehud_vangle = false; +vector autocvar_hud_panel_strafehud_vangle_color = '0.75 0.75 0.75'; +vector autocvar_hud_panel_strafehud_vangle_pos = '-0.25 1 0'; +float autocvar_hud_panel_strafehud_vangle_size = 1; +bool autocvar_hud_panel_strafehud_strafeefficiency = false; +vector autocvar_hud_panel_strafehud_strafeefficiency_pos = '0.25 1 0'; +float autocvar_hud_panel_strafehud_strafeefficiency_size = 1; +int autocvar_hud_panel_strafehud_projection = 0; + bool autocvar_hud_panel_strafehud_sonar = false; string autocvar_hud_panel_strafehud_sonar_audio = "misc/talk"; float autocvar_hud_panel_strafehud_sonar_start = 0.5; @@ -99,14 +111,6 @@ float autocvar_hud_panel_strafehud_sonar_volume_exponent = 1; float autocvar_hud_panel_strafehud_sonar_pitch_start = 0.9; float autocvar_hud_panel_strafehud_sonar_pitch_range = 0.1; float autocvar_hud_panel_strafehud_sonar_pitch_exponent = 1; -bool autocvar_hud_panel_strafehud_vangle = false; -vector autocvar_hud_panel_strafehud_vangle_color = '0.75 0.75 0.75'; -vector autocvar_hud_panel_strafehud_vangle_pos = '-0.25 1 0'; -float autocvar_hud_panel_strafehud_vangle_size = 1; -bool autocvar_hud_panel_strafehud_strafeefficiency = false; -vector autocvar_hud_panel_strafehud_strafeefficiency_pos = '0.25 1 0'; -float autocvar_hud_panel_strafehud_strafeefficiency_size = 1; -int autocvar_hud_panel_strafehud_projection = 0; const int STRAFEHUD_MODE_VIEW_CENTERED = 0; const int STRAFEHUD_MODE_VELOCITY_CENTERED = 1; diff --git a/qcsrc/client/hud/panel/strafehud/_mod.inc b/qcsrc/client/hud/panel/strafehud/_mod.inc index 344b03856..56ddc7bbc 100644 --- a/qcsrc/client/hud/panel/strafehud/_mod.inc +++ b/qcsrc/client/hud/panel/strafehud/_mod.inc @@ -1,5 +1,5 @@ // genmod.sh autogenerated file; do not modify -#include #include +#include #include #include diff --git a/qcsrc/client/hud/panel/strafehud/_mod.qh b/qcsrc/client/hud/panel/strafehud/_mod.qh index f379c5966..0a656e068 100644 --- a/qcsrc/client/hud/panel/strafehud/_mod.qh +++ b/qcsrc/client/hud/panel/strafehud/_mod.qh @@ -1,5 +1,5 @@ // genmod.sh autogenerated file; do not modify -#include #include +#include #include #include diff --git a/qcsrc/client/hud/panel/strafehud/core.qc b/qcsrc/client/hud/panel/strafehud/core.qc deleted file mode 100644 index 2731552e5..000000000 --- a/qcsrc/client/hud/panel/strafehud/core.qc +++ /dev/null @@ -1,248 +0,0 @@ -#include "core.qh" - -#include - -void StrafeHUD_DrawStrafeMeter( - float shiftangle, float wishangle, float absolute_bestangle, - float absolute_prebestangle, float absolute_overturnangle, - bool moving, float hudangle) -{ - // the neutral zone fills the whole strafe bar - if(!moving) - { - // draw neutral zone - if(panel_size.x > 0 && panel_size.y > 0 && autocvar_hud_panel_strafehud_bar_neutral_alpha > 0) - { - switch(autocvar_hud_panel_strafehud_style) - { - default: - case STRAFEHUD_STYLE_DRAWFILL: - drawfill( - panel_pos, panel_size, - autocvar_hud_panel_strafehud_bar_neutral_color, - autocvar_hud_panel_strafehud_bar_neutral_alpha * panel_fg_alpha, - DRAWFLAG_NORMAL); - break; - - case STRAFEHUD_STYLE_PROGRESSBAR: - HUD_Panel_DrawProgressBar( - panel_pos, panel_size, "progressbar", 1, 0, 0, - autocvar_hud_panel_strafehud_bar_neutral_color, - autocvar_hud_panel_strafehud_bar_neutral_alpha * panel_fg_alpha, - DRAWFLAG_NORMAL); - } - } - } - else - { - // calculate various zones of the strafe-o-meter - float accelzone_left_startangle; - float accelzone_right_startangle; - float preaccelzone_left_startangle; - float preaccelzone_right_startangle; - float neutral_startangle; - float overturn_startangle; - - float accelzone_offsetangle = absolute_overturnangle - absolute_bestangle; - float preaccelzone_offsetangle = fabs(absolute_bestangle - absolute_prebestangle); - float neutral_offsetangle = 360; - float overturn_offsetangle = 360 - absolute_overturnangle * 2; - - if(!autocvar_hud_panel_strafehud_bar_preaccel) - preaccelzone_offsetangle = 0; - - // assign starting angles and shift the current offset for every element - float current_startangle = 0; - - preaccelzone_right_startangle = current_startangle; - current_startangle += preaccelzone_offsetangle; - - accelzone_right_startangle = current_startangle; - current_startangle += accelzone_offsetangle; - - overturn_startangle = current_startangle; - current_startangle += overturn_offsetangle; - - accelzone_left_startangle = current_startangle; - current_startangle += accelzone_offsetangle; - - preaccelzone_left_startangle = current_startangle; - current_startangle += preaccelzone_offsetangle; - - neutral_startangle = current_startangle; - neutral_offsetangle = 360 - current_startangle; - - // calculate how far off-center the strafe zones currently are - shiftangle += neutral_offsetangle / 2 - wishangle; - - // shift strafe zones into correct place - neutral_startangle += shiftangle; - accelzone_left_startangle += shiftangle; - accelzone_right_startangle += shiftangle; - preaccelzone_left_startangle += shiftangle; - preaccelzone_right_startangle += shiftangle; - overturn_startangle += shiftangle; - - // draw left acceleration zone - if(accelzone_offsetangle > 0) - StrafeHUD_DrawStrafeHUD( - accelzone_left_startangle, accelzone_offsetangle, - autocvar_hud_panel_strafehud_bar_accel_color, - autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, - autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_LEFT, - hudangle); - - if(autocvar_hud_panel_strafehud_bar_preaccel && preaccelzone_offsetangle > 0) - StrafeHUD_DrawStrafeHUD( - preaccelzone_left_startangle, preaccelzone_offsetangle, - autocvar_hud_panel_strafehud_bar_preaccel_color, - autocvar_hud_panel_strafehud_bar_preaccel_alpha * panel_fg_alpha, - autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_RIGHT, - hudangle); - - // draw right acceleration zone - if(accelzone_offsetangle > 0) - StrafeHUD_DrawStrafeHUD( - accelzone_right_startangle, accelzone_offsetangle, - autocvar_hud_panel_strafehud_bar_accel_color, - autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, - autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_RIGHT, - hudangle); - - if(autocvar_hud_panel_strafehud_bar_preaccel && preaccelzone_offsetangle > 0) - StrafeHUD_DrawStrafeHUD( - preaccelzone_right_startangle, preaccelzone_offsetangle, - autocvar_hud_panel_strafehud_bar_preaccel_color, - autocvar_hud_panel_strafehud_bar_preaccel_alpha * panel_fg_alpha, - autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_LEFT, - hudangle); - - // draw overturn zone - if(overturn_offsetangle > 0) - StrafeHUD_DrawStrafeHUD( - overturn_startangle, overturn_offsetangle, - autocvar_hud_panel_strafehud_bar_overturn_color, - autocvar_hud_panel_strafehud_bar_overturn_alpha * panel_fg_alpha, - autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_BOTH, - hudangle); - - // draw neutral zone - if(neutral_offsetangle > 0) - StrafeHUD_DrawStrafeHUD( - neutral_startangle, neutral_offsetangle, - autocvar_hud_panel_strafehud_bar_neutral_color, - autocvar_hud_panel_strafehud_bar_neutral_alpha * panel_fg_alpha, - autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_NONE, - hudangle); - } -} - -// draw the actual strafe angle indicator -void StrafeHUD_DrawAngleIndicator( - float angle, vector line_size, float arrow_size, int num_dashes, - bool has_top_arrow, bool has_bottom_arrow, vector color, float alpha, float hudangle) -{ - if(alpha <= 0) return; - - // bound to HUD area - angle = bound(-hudangle / 2, angle, hudangle / 2); - - float offset = StrafeHUD_AngleToOffset(angle, hudangle); - offset = StrafeHUD_ProjectOffset(offset, hudangle, false); - - StrafeHUD_DrawAngleIndicatorLine(line_size, offset, num_dashes, color, alpha); - - if(has_top_arrow) - StrafeHUD_DrawAngleIndicatorArrow(arrow_size, offset, line_size, color, alpha, true); - - if(has_bottom_arrow) - StrafeHUD_DrawAngleIndicatorArrow(arrow_size, offset, line_size, color, alpha, false); -} - -// draw the line of the angle indicator -void StrafeHUD_DrawAngleIndicatorLine(vector size, float offset, int num_dashes, vector color, float alpha) -{ - if(num_dashes <= 0 || size.x <= 0 || size.y <= 0) return; - - vector segment_size = size; - segment_size.y = size.y / (bound(1, num_dashes, size.y) * 2 - 1); - - for(float i = 0; i < size.y; i += segment_size.y * 2) - { - // check if last iteration - if(i + segment_size.y * 2 >= size.y) - segment_size.y = size.y - i; - - drawfill( - panel_pos - eY * ((size.y - panel_size.y) / 2 - i) + eX * (offset - segment_size.x / 2), - segment_size, color, alpha * panel_fg_alpha, DRAWFLAG_NORMAL); - } -} - -// draw the arrows on the angle indicator -void StrafeHUD_DrawAngleIndicatorArrow(float size, float offset, vector line_size, vector color, float alpha, bool top) -{ - if(size <= 0) return; - - if(top) - { - StrafeHUD_DrawStrafeArrow( - panel_pos + eY * ((panel_size.y - line_size.y) / 2) + eX * offset, - size, color, alpha * panel_fg_alpha, true, line_size.x); - } - else - { - StrafeHUD_DrawStrafeArrow( - panel_pos + eY * ((panel_size.y - line_size.y) / 2 + line_size.y) + eX * offset, - size, color, alpha * panel_fg_alpha, false, line_size.x); - } -} - -// direction indicator -void StrafeHUD_DrawDirectionIndicator(int direction, bool opposite_direction, bool fwd) -{ - vector direction_size_vertical; - direction_size_vertical.x = max(panel_size.y * min(autocvar_hud_panel_strafehud_direction_width, 1), 1); - direction_size_vertical.y = panel_size.y + direction_size_vertical.x * 2; - direction_size_vertical.z = 0; - - vector direction_size_horizontal; - direction_size_horizontal.x = panel_size.x * min(autocvar_hud_panel_strafehud_direction_length, .5); - direction_size_horizontal.y = direction_size_vertical.x; - direction_size_horizontal.z = 0; - - if(direction != STRAFEHUD_DIRECTION_NONE && - direction_size_vertical.x > 0 && - autocvar_hud_panel_strafehud_direction_alpha > 0) - { - bool indicator_direction = direction == STRAFEHUD_DIRECTION_LEFT; - - // invert left/right when strafing backwards or when strafing towards the opposite side indicated by the direction variable - // if both conditions are true then it's inverted twice hence not inverted at all - if(!fwd != opposite_direction) - indicator_direction = !indicator_direction; - - // draw the direction indicator caps at the sides of the hud - // vertical line - if(direction_size_vertical.y > 0) - drawfill( - panel_pos - eY * direction_size_horizontal.y + eX * (indicator_direction ? -direction_size_vertical.x : panel_size.x), - direction_size_vertical, autocvar_hud_panel_strafehud_direction_color, - autocvar_hud_panel_strafehud_direction_alpha * panel_fg_alpha, - DRAWFLAG_NORMAL); - - // top horizontal line - drawfill( - panel_pos + eX * (indicator_direction ? 0 : panel_size.x - direction_size_horizontal.x) - eY * direction_size_horizontal.y, - direction_size_horizontal, autocvar_hud_panel_strafehud_direction_color, - autocvar_hud_panel_strafehud_direction_alpha * panel_fg_alpha, - DRAWFLAG_NORMAL); - - // bottom horizontal line - 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); - } -} diff --git a/qcsrc/client/hud/panel/strafehud/core.qh b/qcsrc/client/hud/panel/strafehud/core.qh deleted file mode 100644 index 8ed5d53a9..000000000 --- a/qcsrc/client/hud/panel/strafehud/core.qh +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include "../strafehud.qh" - -void StrafeHUD_DrawStrafeMeter(float, float, float, float, float, bool, float); -void StrafeHUD_DrawAngleIndicator(float, vector, float, int, bool, bool, vector, float, float); -void StrafeHUD_DrawAngleIndicatorLine(vector, float, int, vector, float); -void StrafeHUD_DrawAngleIndicatorArrow(float, float, vector, vector, float, bool); -void StrafeHUD_DrawDirectionIndicator(int, bool, bool); diff --git a/qcsrc/client/hud/panel/strafehud/draw.qc b/qcsrc/client/hud/panel/strafehud/draw.qc index 31fa5aca2..9218b1167 100644 --- a/qcsrc/client/hud/panel/strafehud/draw.qc +++ b/qcsrc/client/hud/panel/strafehud/draw.qc @@ -4,7 +4,7 @@ // draw the strafe-o-meter bar // aligns HUD elements perfectly in the hud area -// also deals with wrapping around on edges, different HUD styles, etc +// also deals with wrapping around on edges, different HUD styles, etc. void StrafeHUD_DrawStrafeHUD(float startangle, float offsetangle, vector color, float alpha, int type, int gradient_type, float range) { float offset = StrafeHUD_AngleToOffset(startangle % 360, range); @@ -12,11 +12,17 @@ void StrafeHUD_DrawStrafeHUD(float startangle, float offsetangle, vector color, float mirror_offset; float mirror_width; - if(StrafeHUD_IsGradient(type) && gradient_type == STRAFEHUD_GRADIENT_NONE) - type = STRAFEHUD_STYLE_DRAWFILL; + if(width <= 0) return; - if(alpha <= 0 && !StrafeHUD_IsGradient(type) || width <= 0) - return; + if(StrafeHUD_IsGradient(type)) + { + if(gradient_type == STRAFEHUD_GRADIENT_NONE) + { + type = STRAFEHUD_STYLE_DRAWFILL; + if(alpha <= 0) return; + } + } + else if(alpha <= 0) return; // how much is hidden by the current hud angle float hidden_width = (360 - range) / range * panel_size.x; @@ -170,7 +176,9 @@ void StrafeHUD_DrawStrafeHUD(float startangle, float offsetangle, vector color, } // accelerated gradient, does not support non-linear projection of the color and opacity within individual segments -void StrafeHUD_DrawGradient(vector color1, vector color2, vector size, float original_width, float offset, float alpha, float gradient_offset, int gradient_type, float range) +void StrafeHUD_DrawGradient( + vector color1, vector color2, vector size, float original_width, + float offset, float alpha, float gradient_offset, int gradient_type, float range) { if(gradient_type == STRAFEHUD_GRADIENT_BOTH) { @@ -199,15 +207,15 @@ void StrafeHUD_DrawGradient(vector color1, vector color2, vector size, float ori float alpha1 = bound(0, alpha, 1); float alpha2 = bound(0, autocvar_hud_panel_strafehud_bar_neutral_alpha * panel_fg_alpha, 1); - if((alpha1 + alpha2) == 0) return; + if(alpha1 + alpha2 == 0) return; float ratio1 = gradient_offset / original_width; - if(gradient_type == STRAFEHUD_GRADIENT_LEFT) - ratio1 = 1 - ratio1; - float ratio2 = (gradient_offset + size.x) / original_width; if(gradient_type == STRAFEHUD_GRADIENT_LEFT) + { + ratio1 = 1 - ratio1; ratio2 = 1 - ratio2; + } vector origin = HUD_Shift(panel_pos); gradient_start.x = HUD_ScaleX(gradient_start.x); @@ -230,7 +238,9 @@ void StrafeHUD_DrawGradient(vector color1, vector color2, vector size, float ori } // more expensive gradient rendering which does not rely on vertex gradients (required to properly render the color/opacity of individual segments in non-linear projection modes) -void StrafeHUD_DrawSoftGradient(vector color1, vector color2, vector size, float original_width, float offset, float original_offset, float alpha, float gradient_offset, int gradient_type, float range) +void StrafeHUD_DrawSoftGradient( + vector color1, vector color2, vector size, float original_width, float offset, float original_offset, + float alpha, float gradient_offset, int gradient_type, float range) { float alpha1 = bound(0, alpha, 1); float alpha2 = bound(0, autocvar_hud_panel_strafehud_bar_neutral_alpha * panel_fg_alpha, 1); @@ -266,8 +276,10 @@ void StrafeHUD_DrawSoftGradient(vector color1, vector color2, vector size, float // draw the strafe arrows (inspired by drawspritearrow() in common/mutators/mutator/waypoints/waypointsprites.qc) void StrafeHUD_DrawStrafeArrow(vector origin, float size, vector color, float alpha, bool flipped, float connection_width) { + // alpha and size already checked + origin = HUD_Shift(origin); - float width = HUD_ScaleX(size * 2 + connection_width); + float width = HUD_ScaleX(size * 2 + connection_width); float height = HUD_ScaleY(size); if(flipped) origin.y -= size; R_BeginPolygon("", DRAWFLAG_NORMAL, true); @@ -285,26 +297,29 @@ void StrafeHUD_DrawStrafeArrow(vector origin, float size, vector color, float al R_EndPolygon(); } -// draw a fading text indicator above or below the strafe meter, return true if something was displayed -void StrafeHUD_DrawTextIndicator(string text, float height, vector color, float fadetime, float lasttime, vector pos, float offset_top, float offset_bottom) +// draw a fading text indicator above or below the strafe meter +void StrafeHUD_DrawTextIndicator( + string text, float height, vector color, float fadetime, float lasttime, + vector pos, float offset_top, float offset_bottom) { - if((height <= 0) || (lasttime <= 0) || (fadetime <= 0) || ((time - lasttime) >= fadetime)) + float time_frac = (time - lasttime) / fadetime; + if(height <= 0 || lasttime <= 0 || fadetime <= 0 || time_frac > 1) return; - float alpha = cos(((time - lasttime) / fadetime) * M_PI_2); // fade non-linear like the physics panel does + float alpha = cos(time_frac * M_PI_2); // fade non-linear like the physics panel does vector size = panel_size; size.y = height; if(pos.y >= 1) { - pos.y--; // for calculations the position should not start at +1 + --pos.y; // for calculations the position should not start at +1 pos = StrafeHUD_CalculateTextIndicatorPosition(pos); pos.y += size.y + offset_top; pos.y *= -1; // it's more intuitive for up to be positive } else if(pos.y <= -1) { - pos.y++; // for calculations the position should not start at -1 + ++pos.y; // for calculations the position should not start at -1 pos = StrafeHUD_CalculateTextIndicatorPosition(pos); pos.y *= -1; // it's more intuitive for down to be negative pos.y += panel_size.y + offset_bottom; @@ -314,15 +329,6 @@ void StrafeHUD_DrawTextIndicator(string text, float height, vector color, float drawstring_aspect(panel_pos + pos, text, size, color, alpha * panel_fg_alpha, DRAWFLAG_NORMAL); } -vector StrafeHUD_CalculateTextIndicatorPosition(vector pos) -{ - pos.x *= panel_size.x / 2; // more intuitive since we start in the middle, this turns the range from -0.5 to +0.5 into -1 to +1 - pos.y *= panel_size.y; - pos.z = 0; - - return pos; -} - bool StrafeHUD_IsGradient(int style) { return style == STRAFEHUD_STYLE_GRADIENT || style == STRAFEHUD_STYLE_SOFT_GRADIENT; diff --git a/qcsrc/client/hud/panel/strafehud/draw.qh b/qcsrc/client/hud/panel/strafehud/draw.qh index 329237edc..1bab2ea75 100644 --- a/qcsrc/client/hud/panel/strafehud/draw.qh +++ b/qcsrc/client/hud/panel/strafehud/draw.qh @@ -6,5 +6,4 @@ void StrafeHUD_DrawGradient(vector, vector, vector, float, float, float, float, void StrafeHUD_DrawSoftGradient(vector, vector, vector, float, float, float, float, float, int, float); void StrafeHUD_DrawStrafeArrow(vector, float, vector, float, bool, float); void StrafeHUD_DrawTextIndicator(string, float, vector, float, float, vector, float, float); -vector StrafeHUD_CalculateTextIndicatorPosition(vector); bool StrafeHUD_IsGradient(int); diff --git a/qcsrc/client/hud/panel/strafehud/draw_core.qc b/qcsrc/client/hud/panel/strafehud/draw_core.qc new file mode 100644 index 000000000..707f21111 --- /dev/null +++ b/qcsrc/client/hud/panel/strafehud/draw_core.qc @@ -0,0 +1,248 @@ +#include "draw_core.qh" + +#include + +void StrafeHUD_DrawStrafeMeter( + float shiftangle, float wishangle, float absolute_bestangle, + float absolute_prebestangle, float absolute_overturnangle, + bool moving, float hudangle) +{ + // the neutral zone fills the whole strafe bar + if(!moving) + { + // draw neutral zone + if(panel_size.x > 0 && panel_size.y > 0 && autocvar_hud_panel_strafehud_bar_neutral_alpha > 0) + { + switch(autocvar_hud_panel_strafehud_style) + { + default: + case STRAFEHUD_STYLE_DRAWFILL: + drawfill( + panel_pos, panel_size, + autocvar_hud_panel_strafehud_bar_neutral_color, + autocvar_hud_panel_strafehud_bar_neutral_alpha * panel_fg_alpha, + DRAWFLAG_NORMAL); + break; + + case STRAFEHUD_STYLE_PROGRESSBAR: + HUD_Panel_DrawProgressBar( + panel_pos, panel_size, "progressbar", 1, 0, 0, + autocvar_hud_panel_strafehud_bar_neutral_color, + autocvar_hud_panel_strafehud_bar_neutral_alpha * panel_fg_alpha, + DRAWFLAG_NORMAL); + } + } + } + else + { + // calculate various zones of the strafe-o-meter + float accelzone_left_startangle; + float accelzone_right_startangle; + float preaccelzone_left_startangle; + float preaccelzone_right_startangle; + float neutral_startangle; + float overturn_startangle; + + float accelzone_offsetangle = absolute_overturnangle - absolute_bestangle; + float preaccelzone_offsetangle = fabs(absolute_bestangle - absolute_prebestangle); + float neutral_offsetangle = 360; + float overturn_offsetangle = 360 - absolute_overturnangle * 2; + + if(!autocvar_hud_panel_strafehud_bar_preaccel) + preaccelzone_offsetangle = 0; + + // assign starting angles and shift the current offset for every element + float current_startangle = 0; + + preaccelzone_right_startangle = current_startangle; + current_startangle += preaccelzone_offsetangle; + + accelzone_right_startangle = current_startangle; + current_startangle += accelzone_offsetangle; + + overturn_startangle = current_startangle; + current_startangle += overturn_offsetangle; + + accelzone_left_startangle = current_startangle; + current_startangle += accelzone_offsetangle; + + preaccelzone_left_startangle = current_startangle; + current_startangle += preaccelzone_offsetangle; + + neutral_startangle = current_startangle; + neutral_offsetangle = 360 - current_startangle; + + // calculate how far off-center the strafe zones currently are + shiftangle += neutral_offsetangle / 2 - wishangle; + + // shift strafe zones into correct place + neutral_startangle += shiftangle; + accelzone_left_startangle += shiftangle; + accelzone_right_startangle += shiftangle; + preaccelzone_left_startangle += shiftangle; + preaccelzone_right_startangle += shiftangle; + overturn_startangle += shiftangle; + + // draw left acceleration zone + if(accelzone_offsetangle > 0) + StrafeHUD_DrawStrafeHUD( + accelzone_left_startangle, accelzone_offsetangle, + autocvar_hud_panel_strafehud_bar_accel_color, + autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, + autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_LEFT, + hudangle); + + if(autocvar_hud_panel_strafehud_bar_preaccel && preaccelzone_offsetangle > 0) + StrafeHUD_DrawStrafeHUD( + preaccelzone_left_startangle, preaccelzone_offsetangle, + autocvar_hud_panel_strafehud_bar_preaccel_color, + autocvar_hud_panel_strafehud_bar_preaccel_alpha * panel_fg_alpha, + autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_RIGHT, + hudangle); + + // draw right acceleration zone + if(accelzone_offsetangle > 0) + StrafeHUD_DrawStrafeHUD( + accelzone_right_startangle, accelzone_offsetangle, + autocvar_hud_panel_strafehud_bar_accel_color, + autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, + autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_RIGHT, + hudangle); + + if(autocvar_hud_panel_strafehud_bar_preaccel && preaccelzone_offsetangle > 0) + StrafeHUD_DrawStrafeHUD( + preaccelzone_right_startangle, preaccelzone_offsetangle, + autocvar_hud_panel_strafehud_bar_preaccel_color, + autocvar_hud_panel_strafehud_bar_preaccel_alpha * panel_fg_alpha, + autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_LEFT, + hudangle); + + // draw overturn zone + if(overturn_offsetangle > 0) + StrafeHUD_DrawStrafeHUD( + overturn_startangle, overturn_offsetangle, + autocvar_hud_panel_strafehud_bar_overturn_color, + autocvar_hud_panel_strafehud_bar_overturn_alpha * panel_fg_alpha, + autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_BOTH, + hudangle); + + // draw neutral zone + if(neutral_offsetangle > 0) + StrafeHUD_DrawStrafeHUD( + neutral_startangle, neutral_offsetangle, + autocvar_hud_panel_strafehud_bar_neutral_color, + autocvar_hud_panel_strafehud_bar_neutral_alpha * panel_fg_alpha, + autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_NONE, + hudangle); + } +} + +// draw the actual strafe angle indicator +void StrafeHUD_DrawAngleIndicator( + float angle, vector line_size, float arrow_size, int num_dashes, + bool has_top_arrow, bool has_bottom_arrow, vector color, float alpha, float hudangle) +{ + if(alpha <= 0) return; + + // bound to HUD area + angle = bound(-hudangle / 2, angle, hudangle / 2); + + float offset = StrafeHUD_AngleToOffset(angle, hudangle); + offset = StrafeHUD_ProjectOffset(offset, hudangle, false); + + StrafeHUD_DrawAngleIndicatorLine(line_size, offset, num_dashes, color, alpha); + + if(has_top_arrow) + StrafeHUD_DrawAngleIndicatorArrow(arrow_size, offset, line_size, color, alpha, true); + + if(has_bottom_arrow) + StrafeHUD_DrawAngleIndicatorArrow(arrow_size, offset, line_size, color, alpha, false); +} + +// draw the line of the angle indicator +void StrafeHUD_DrawAngleIndicatorLine(vector size, float offset, int num_dashes, vector color, float alpha) +{ + if(num_dashes <= 0 || size.x <= 0 || size.y <= 0) return; + + vector segment_size = size; + segment_size.y = size.y / (bound(1, num_dashes, size.y) * 2 - 1); + + for(float i = 0; i < size.y; i += segment_size.y * 2) + { + // check if last iteration + if(i + segment_size.y * 2 >= size.y) + segment_size.y = size.y - i; + + drawfill( + panel_pos - eY * ((size.y - panel_size.y) / 2 - i) + eX * (offset - segment_size.x / 2), + segment_size, color, alpha * panel_fg_alpha, DRAWFLAG_NORMAL); + } +} + +// draw the arrows on the angle indicator +void StrafeHUD_DrawAngleIndicatorArrow(float size, float offset, vector line_size, vector color, float alpha, bool top) +{ + if(size <= 0) return; + + if(top) + { + StrafeHUD_DrawStrafeArrow( + panel_pos + eY * ((panel_size.y - line_size.y) / 2) + eX * offset, + size, color, alpha * panel_fg_alpha, true, line_size.x); + } + else + { + StrafeHUD_DrawStrafeArrow( + panel_pos + eY * ((panel_size.y - line_size.y) / 2 + line_size.y) + eX * offset, + size, color, alpha * panel_fg_alpha, false, line_size.x); + } +} + +// direction indicator +void StrafeHUD_DrawDirectionIndicator(int direction, bool opposite_direction, bool fwd) +{ + vector direction_size_vertical; + direction_size_vertical.x = max(panel_size.y * min(autocvar_hud_panel_strafehud_direction_width, 1), 1); + direction_size_vertical.y = panel_size.y + direction_size_vertical.x * 2; + direction_size_vertical.z = 0; + + vector direction_size_horizontal; + direction_size_horizontal.x = panel_size.x * min(autocvar_hud_panel_strafehud_direction_length, .5); + direction_size_horizontal.y = direction_size_vertical.x; + direction_size_horizontal.z = 0; + + if(direction != STRAFEHUD_DIRECTION_NONE && + direction_size_vertical.x > 0 && + autocvar_hud_panel_strafehud_direction_alpha > 0) + { + bool indicator_direction = direction == STRAFEHUD_DIRECTION_LEFT; + + // invert left/right when strafing backwards or when strafing towards the opposite side indicated by the direction variable + // if both conditions are true then it's inverted twice hence not inverted at all + if(!fwd != opposite_direction) + indicator_direction = !indicator_direction; + + // draw the direction indicator caps at the sides of the hud + // vertical line + if(direction_size_vertical.y > 0) + drawfill( + panel_pos - eY * direction_size_horizontal.y + eX * (indicator_direction ? -direction_size_vertical.x : panel_size.x), + direction_size_vertical, autocvar_hud_panel_strafehud_direction_color, + autocvar_hud_panel_strafehud_direction_alpha * panel_fg_alpha, + DRAWFLAG_NORMAL); + + // top horizontal line + drawfill( + panel_pos + eX * (indicator_direction ? 0 : panel_size.x - direction_size_horizontal.x) - eY * direction_size_horizontal.y, + direction_size_horizontal, autocvar_hud_panel_strafehud_direction_color, + autocvar_hud_panel_strafehud_direction_alpha * panel_fg_alpha, + DRAWFLAG_NORMAL); + + // bottom horizontal line + 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); + } +} diff --git a/qcsrc/client/hud/panel/strafehud/draw_core.qh b/qcsrc/client/hud/panel/strafehud/draw_core.qh new file mode 100644 index 000000000..8ed5d53a9 --- /dev/null +++ b/qcsrc/client/hud/panel/strafehud/draw_core.qh @@ -0,0 +1,8 @@ +#pragma once +#include "../strafehud.qh" + +void StrafeHUD_DrawStrafeMeter(float, float, float, float, float, bool, float); +void StrafeHUD_DrawAngleIndicator(float, vector, float, int, bool, bool, vector, float, float); +void StrafeHUD_DrawAngleIndicatorLine(vector, float, int, vector, float); +void StrafeHUD_DrawAngleIndicatorArrow(float, float, vector, vector, float, bool); +void StrafeHUD_DrawDirectionIndicator(int, bool, bool); diff --git a/qcsrc/client/hud/panel/strafehud/extra.qc b/qcsrc/client/hud/panel/strafehud/extra.qc index 03d285ba2..356303e89 100644 --- a/qcsrc/client/hud/panel/strafehud/extra.qc +++ b/qcsrc/client/hud/panel/strafehud/extra.qc @@ -81,19 +81,18 @@ float StrafeHUD_DrawSlickDetector(entity e, bool onslick) vector slickdetector_size = panel_size; slickdetector_size.y = slickdetector_height; - // top horizontal line - drawfill( - panel_pos - eY * slickdetector_size.y, slickdetector_size, - autocvar_hud_panel_strafehud_slickdetector_color, - autocvar_hud_panel_strafehud_slickdetector_alpha * panel_fg_alpha, - DRAWFLAG_NORMAL); - - // bottom horizontal line - drawfill( - panel_pos + eY * panel_size.y, - slickdetector_size, autocvar_hud_panel_strafehud_slickdetector_color, - autocvar_hud_panel_strafehud_slickdetector_alpha * panel_fg_alpha, - DRAWFLAG_NORMAL); + // horizontal lines + for(int i = 0; i <= 1; ++i) + { + float y_offset = (i == 0) + ? -slickdetector_size.y // top + : panel_size.y; // bottom + drawfill( + panel_pos + eY * y_offset, + slickdetector_size, autocvar_hud_panel_strafehud_slickdetector_color, + autocvar_hud_panel_strafehud_slickdetector_alpha * panel_fg_alpha, + DRAWFLAG_NORMAL); + } } return slickdetector_height; @@ -105,18 +104,110 @@ float StrafeHUD_DrawSlickDetector(entity e, bool onslick) // vertical angle for weapon jumps void StrafeHUD_DrawVerticalAngle(entity e, float text_offset_top, float text_offset_bottom) { - if(autocvar_hud_panel_strafehud_vangle) + if(!autocvar_hud_panel_strafehud_vangle) return; + + float vangle = -PHYS_INPUT_ANGLES(e).x; + float vangle_height = autocvar_hud_panel_strafehud_vangle_size * panel_size.y; + string vangle_text = strcat(ftos_decimals(vangle, 2), "°"); + + StrafeHUD_DrawTextIndicator( + vangle_text, vangle_height, + autocvar_hud_panel_strafehud_vangle_color, 1, + time, autocvar_hud_panel_strafehud_vangle_pos, + text_offset_top, text_offset_bottom); +} + +// show height achieved by a single jump +// FIXME: checking z position differences is unreliable (warpzones, teleporter, kill, etc), use velocity to calculate jump height instead +// FIXME: move capturing the jump height value out of the HUD +void StrafeHUD_DrawJumpHeight(entity e, bool onground, bool swimming, float text_offset_top, float text_offset_bottom) +{ + float length_conversion_factor = StrafeHUD_GetLengthUnitFactor(autocvar_hud_speed_unit); + 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((e.velocity.z <= 0) || onground || swimming || IS_DEAD(e) || !IS_PLAYER(e)) { - float vangle = -PHYS_INPUT_ANGLES(e).x; - float vangle_height = autocvar_hud_panel_strafehud_vangle_size * panel_size.y; - string vangle_text = strcat(ftos_decimals(vangle, 2), "°"); - - StrafeHUD_DrawTextIndicator( - vangle_text, vangle_height, - autocvar_hud_panel_strafehud_vangle_color, 1, - time, autocvar_hud_panel_strafehud_vangle_pos, - text_offset_top, text_offset_bottom); + height_min = height_max = e.origin.z; } + else if(e.origin.z > height_max) + { + height_max = e.origin.z; + float jumpheight_new = height_max - height_min; + + if((jumpheight_new * length_conversion_factor) > max(autocvar_hud_panel_strafehud_jumpheight_min, 0)) + { + jumpheight = jumpheight_new; + jumptime = time; + } + } + + if(!autocvar_hud_panel_strafehud_jumpheight) return; + + // use more decimals when displaying km or miles + int length_decimals = autocvar_hud_speed_unit >= 3 && autocvar_hud_speed_unit <= 5 ? 6 : 2; + + float jumpheight_height = autocvar_hud_panel_strafehud_jumpheight_size * panel_size.y; + string jumpheight_text = ftos_decimals(jumpheight * length_conversion_factor, length_decimals); + if(autocvar_hud_panel_strafehud_unit_show) + jumpheight_text = strcat(jumpheight_text, StrafeHUD_GetLengthUnit(autocvar_hud_speed_unit)); + + StrafeHUD_DrawTextIndicator( + jumpheight_text, jumpheight_height, + autocvar_hud_panel_strafehud_jumpheight_color, + autocvar_hud_panel_strafehud_jumpheight_fade, + jumptime, autocvar_hud_panel_strafehud_jumpheight_pos, + text_offset_top, text_offset_bottom); +} + +// strafe efficiency, percentage of how far away the current angle is from the optimal angle +// the percentage changes linearly with angular distance +void StrafeHUD_DrawStrafeEfficiency(float strafe_ratio, float text_offset_top, float text_offset_bottom) +{ + if(!autocvar_hud_panel_strafehud_strafeefficiency) return; + + float strafeeff_height = autocvar_hud_panel_strafehud_strafeefficiency_size * panel_size.y; + string strafeeff_text = strcat(ftos_decimals(strafe_ratio * 100, 2), "%"); + vector strafeeff_color = StrafeHUD_MixColors('1 1 1', (strafe_ratio > 0 ? '0 1 0' : '1 0 0'), fabs(strafe_ratio)); + + StrafeHUD_DrawTextIndicator( + strafeeff_text, strafeeff_height, + strafeeff_color, 1, + time, autocvar_hud_panel_strafehud_strafeefficiency_pos, + text_offset_top, text_offset_bottom); +} + +// show speed when crossing the start trigger +// FIXME: move capturing the race start speed value out of the HUD +void StrafeHUD_DrawStartSpeed(float speed, float text_offset_top, float text_offset_bottom) +{ + static float startspeed = 0, starttime = 0; // displayed value and timestamp for fade out + + // check if the start trigger was hit (will also trigger if the finish trigger was hit if those have the same ID) + if((race_nextcheckpoint == 1) || (race_checkpoint == 254 && race_nextcheckpoint == 255)) + { + if((race_checkpointtime > 0) && (starttime != race_checkpointtime)) + { + starttime = race_checkpointtime; + startspeed = speed; + } + } + + if(!autocvar_hud_panel_strafehud_startspeed) return; + + float speed_conversion_factor = GetSpeedUnitFactor(autocvar_hud_speed_unit); + float startspeed_height = autocvar_hud_panel_strafehud_startspeed_size * panel_size.y; + string startspeed_text = ftos_decimals(startspeed * speed_conversion_factor, 2); + if(autocvar_hud_panel_strafehud_unit_show) + startspeed_text = strcat(startspeed_text, GetSpeedUnit(autocvar_hud_speed_unit)); + + StrafeHUD_DrawTextIndicator( + startspeed_text, startspeed_height, + autocvar_hud_panel_strafehud_startspeed_color, + autocvar_hud_panel_strafehud_startspeed_fade, + starttime, autocvar_hud_panel_strafehud_startspeed_pos, + text_offset_top, text_offset_bottom); } // strafe sonar for audible feedback when strafing @@ -177,99 +268,3 @@ string StrafeHUD_UpdateSonarSound() return sonarsound; } - -// show height achieved by a single jump -// FIXME: checking z position differences is unreliable (warpzones, teleporter, kill, etc), use velocity to calculate jump height instead -// FIXME: move capturing the jump height value out of the HUD -void StrafeHUD_DrawJumpHeight(entity e, bool onground, bool swimming, float text_offset_top, float text_offset_bottom) -{ - float length_conversion_factor = StrafeHUD_GetLengthUnitFactor(autocvar_hud_speed_unit); - 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((e.velocity.z <= 0) || onground || swimming || IS_DEAD(e) || !IS_PLAYER(e)) - { - height_min = height_max = e.origin.z; - } - else if(e.origin.z > height_max) - { - height_max = e.origin.z; - float jumpheight_new = height_max - height_min; - - if((jumpheight_new * length_conversion_factor) > max(autocvar_hud_panel_strafehud_jumpheight_min, 0)) - { - jumpheight = jumpheight_new; - jumptime = time; - } - } - - if(autocvar_hud_panel_strafehud_jumpheight) - { - // use more decimals when displaying km or miles - int length_decimals = autocvar_hud_speed_unit >= 3 && autocvar_hud_speed_unit <= 5 ? 6 : 2; - - float jumpheight_height = autocvar_hud_panel_strafehud_jumpheight_size * panel_size.y; - string jumpheight_text = ftos_decimals(jumpheight * length_conversion_factor, length_decimals); - if(autocvar_hud_panel_strafehud_unit_show) - jumpheight_text = strcat(jumpheight_text, StrafeHUD_GetLengthUnit(autocvar_hud_speed_unit)); - - StrafeHUD_DrawTextIndicator( - jumpheight_text, jumpheight_height, - autocvar_hud_panel_strafehud_jumpheight_color, - autocvar_hud_panel_strafehud_jumpheight_fade, - jumptime, autocvar_hud_panel_strafehud_jumpheight_pos, - text_offset_top, text_offset_bottom); - } -} - -// strafe efficiency, percentage of how far away the current angle is from the optimal angle -// the percentage changes linearly with angular distance -void StrafeHUD_DrawStrafeEfficiency(float strafe_ratio, float text_offset_top, float text_offset_bottom) -{ - if(autocvar_hud_panel_strafehud_strafeefficiency) - { - float strafeeff_height = autocvar_hud_panel_strafehud_strafeefficiency_size * panel_size.y; - string strafeeff_text = strcat(ftos_decimals(strafe_ratio * 100, 2), "%"); - vector strafeeff_color = '1 1 1' - (strafe_ratio > 0 ? '1 0 1' : '0 1 1') * fabs(strafe_ratio); - - StrafeHUD_DrawTextIndicator( - strafeeff_text, strafeeff_height, - strafeeff_color, 1, - time, autocvar_hud_panel_strafehud_strafeefficiency_pos, - text_offset_top, text_offset_bottom); - } -} - -// show speed when crossing the start trigger -// FIXME: move capturing the race start speed value out of the HUD -void StrafeHUD_DrawStartSpeed(float speed, float text_offset_top, float text_offset_bottom) -{ - static float startspeed = 0, starttime = 0; // displayed value and timestamp for fade out - - // check if the start trigger was hit (will also trigger if the finish trigger was hit if those have the same ID) - if((race_nextcheckpoint == 1) || (race_checkpoint == 254 && race_nextcheckpoint == 255)) - { - if((race_checkpointtime > 0) && (starttime != race_checkpointtime)) - { - starttime = race_checkpointtime; - startspeed = speed; - } - } - - if(autocvar_hud_panel_strafehud_startspeed) - { - float speed_conversion_factor = GetSpeedUnitFactor(autocvar_hud_speed_unit); - float startspeed_height = autocvar_hud_panel_strafehud_startspeed_size * panel_size.y; - string startspeed_text = ftos_decimals(startspeed * speed_conversion_factor, 2); - if(autocvar_hud_panel_strafehud_unit_show) - startspeed_text = strcat(startspeed_text, GetSpeedUnit(autocvar_hud_speed_unit)); - - StrafeHUD_DrawTextIndicator( - startspeed_text, startspeed_height, - autocvar_hud_panel_strafehud_startspeed_color, - autocvar_hud_panel_strafehud_startspeed_fade, - starttime, autocvar_hud_panel_strafehud_startspeed_pos, - text_offset_top, text_offset_bottom); - } -} diff --git a/qcsrc/client/hud/panel/strafehud/extra.qh b/qcsrc/client/hud/panel/strafehud/extra.qh index be6e81753..836d43d62 100644 --- a/qcsrc/client/hud/panel/strafehud/extra.qh +++ b/qcsrc/client/hud/panel/strafehud/extra.qh @@ -2,9 +2,11 @@ #include "../strafehud.qh" float StrafeHUD_DrawSlickDetector(entity, bool); + void StrafeHUD_DrawVerticalAngle(entity, float, float); -void StrafeHUD_Sonar(float, string); -string StrafeHUD_UpdateSonarSound(); void StrafeHUD_DrawJumpHeight(entity, bool, bool, float, float); void StrafeHUD_DrawStrafeEfficiency(float, float, float); void StrafeHUD_DrawStartSpeed(float, float, float); + +void StrafeHUD_Sonar(float, string); +string StrafeHUD_UpdateSonarSound(); diff --git a/qcsrc/client/hud/panel/strafehud/util.qc b/qcsrc/client/hud/panel/strafehud/util.qc index dd7c4eb35..7c18c0182 100644 --- a/qcsrc/client/hud/panel/strafehud/util.qc +++ b/qcsrc/client/hud/panel/strafehud/util.qc @@ -136,12 +136,13 @@ float StrafeHUD_DetermineFrameTime() if(dt_client > .05) // server splits frames longer than 50 ms into two moves (DarkPlaces behaviour) dt_client /= 2; // does not ensure frames are smaller than 50 ms, just splits large frames in half, matches server behaviour - // calculate average frametime - // calculated using a weighted arithmetic mean, where the weighting is equal to the frametime itself - // for example, given a 1 ms frame and a 9 ms frame we have: - // a total time of 10 ms - // a weighted sum of 1 ms * 1 ms + 9 ms * 9 ms = 82 ms^2 - // the final result is 82 ms^2 / 10 ms = 8.2 ms + /* calculate average frametime + * calculated using a weighted arithmetic mean, where the weighting is equal to the frametime itself + * for example, given a 1 ms frame and a 9 ms frame we have: + * a total time of 10 ms + * a weighted sum of 1 ms * 1 ms + 9 ms * 9 ms = 82 ms^2 + * the final result is 82 ms^2 / 10 ms = 8.2 ms + */ dt_sum += dt_client * dt_client; // weighted sum of all frametimes (mean numerator) dt_time += dt_client; // time spent averaging (mean denominator) @@ -167,34 +168,20 @@ float StrafeHUD_DetermineWishAngle(vector movement, int keys, bool is_local) float wishangle; if(is_local) // if entity is local player { - if(movement.x == 0) - { - if(movement.y < 0) - wishangle = -90; - else if(movement.y > 0) - wishangle = 90; - else - wishangle = 0; - } + if(movement.y == 0) + wishangle = 0; else { - if(movement.y == 0) - { - wishangle = 0; - } - else + wishangle = RAD2DEG * atan2(movement.y, movement.x); + // wrap the wish angle if it exceeds ±90° + if(fabs(wishangle) > 90) { - wishangle = RAD2DEG * atan2(movement.y, movement.x); - // wrap the wish angle if it exceeds ±90° - if(fabs(wishangle) > 90) - { - if(wishangle < 0) - wishangle += 180; - else - wishangle -= 180; - - wishangle *= -1; - } + if(wishangle < 0) + wishangle += 180; + else + wishangle -= 180; + + wishangle *= -1; } } } @@ -297,13 +284,9 @@ float StrafeHUD_DetermineHudAngle(float absolute_wishangle, float absolute_overt float StrafeHUD_DetermineDirection(float angle, float wishangle, float antiflicker_angle) { if(wishangle > 0) - { return STRAFEHUD_DIRECTION_RIGHT; - } else if(wishangle < 0) - { return STRAFEHUD_DIRECTION_LEFT; - } else { if(angle > antiflicker_angle && angle < (180 - antiflicker_angle)) @@ -341,3 +324,12 @@ vector StrafeHUD_MixColors(vector color1, vector color2, float ratio) if(ratio >= 1) return color2; return color1 + (color2 - color1) * ratio; } + +vector StrafeHUD_CalculateTextIndicatorPosition(vector pos) +{ + pos.x *= panel_size.x / 2; // more intuitive since we start in the middle, this turns the range from -0.5 to +0.5 into -1 to +1 + pos.y *= panel_size.y; + pos.z = 0; + + return pos; +} diff --git a/qcsrc/client/hud/panel/strafehud/util.qh b/qcsrc/client/hud/panel/strafehud/util.qh index 4aeb595e8..11d8064c0 100644 --- a/qcsrc/client/hud/panel/strafehud/util.qh +++ b/qcsrc/client/hud/panel/strafehud/util.qh @@ -6,8 +6,10 @@ float StrafeHUD_AngleToOffset(float, float); float StrafeHUD_Project(float, float, bool); float StrafeHUD_ProjectOffset(float, float, bool); float StrafeHUD_ProjectWidth(float, float, float); + float StrafeHUD_GetLengthUnitFactor(int); string StrafeHUD_GetLengthUnit(int); + float StrafeHUD_DetermineWaterLevel(entity); float StrafeHUD_DetermineFrameTime(); float StrafeHUD_DetermineWishAngle(vector, int, bool); @@ -15,4 +17,7 @@ int StrafeHUD_DetermineForwardKeys(vector, int, bool); float StrafeHUD_DetermineHudAngle(float, float, float); float StrafeHUD_DetermineDirection(float, float, float); bool StrafeHUD_DetermineJumpHeld(entity, int, bool); + vector StrafeHUD_MixColors(vector, vector, float); + +vector StrafeHUD_CalculateTextIndicatorPosition(vector);