From: Juhu <5894800-Juhu_@users.noreply.gitlab.com> Date: Sun, 12 Jan 2025 02:48:35 +0000 (+0100) Subject: Merge branch 'master' into Juhu/strafehud-next X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=ae16a18b36c8cdac4603ffaf2f1ead056c83107c;p=xonotic%2Fxonotic-data.pk3dir.git Merge branch 'master' into Juhu/strafehud-next Fixed merge conflicts caused by CVAR description and strafehud logic changes --- ae16a18b36c8cdac4603ffaf2f1ead056c83107c diff --cc _hud_common.cfg index 385e302b5,4266918ce..c651fdac4 --- a/_hud_common.cfg +++ b/_hud_common.cfg @@@ -164,15 -164,16 +164,15 @@@ seta hud_panel_scoreboard_itemstats_fil seta hud_panel_scoreboard_itemstats_showdelay 2.2 "how long to delay displaying item stats below the scoreboard if it's too far down" seta hud_panel_scoreboard_itemstats_showdelay_minpos 0.75 "delay displaying the item stats panel only if its position is lower than this percentage of the screen height from the top" - seta _hud_panel_strafehud_demo "0" "strafehud changes angle during configure" - seta hud_panel_strafehud_mode "0" "strafehud mode which controls whether the strafehud is centered at 0 = view angle, 1 = velocity angle" - seta hud_panel_strafehud_range "90" "the angle range up to 360 degrees displayed on the strafehud, -1 = current fov, 0 = dynamic (chooses the minimum range required to still see the whole area needed for accelerating)" - seta hud_panel_strafehud_range_sidestrafe "-2" "the angle range up to 360 degrees displayed on the strafehud when side strafing, 0 = dynamic (chooses the minimum range required to still see the whole area needed for accelerating), -1 = current fov, -2 = same as the normal range" - seta hud_panel_strafehud_style "2" "0 = no styling, 1 = progress bar style for the strafe bar, 2 = accelerated gradient for the strafe bar (no non-linear projection for gradient color/opacity), 3 = software gradient for the strafe bar (slow)" + seta _hud_panel_strafehud_demo "0" "StrafeHUD changes angle during configure" + seta hud_panel_strafehud_mode "0" "StrafeHUD mode which controls whether the StrafeHUD is centered at \"0\" = view angle, \"1\" = velocity angle" -seta hud_panel_strafehud_range "90" "the angle range up to 360 degrees displayed on the StrafeHUD, \"0\" = dynamic (chooses the minimum range required to still see the whole area needed for accelerating)" -seta hud_panel_strafehud_range_sidestrafe "-1" "the angle range up to 360 degrees displayed on the StrafeHUD when side strafing, \"0\" = dynamic (chooses the minimum range required to still see the whole area needed for accelerating), \"-1\" = same as the normal range" -seta hud_panel_strafehud_style "2" "\"0\" = no styling, \"1\" = progress bar style for the strafe bar, \"2\" = gradient for the strafe bar" ++seta hud_panel_strafehud_range "90" "the angle range up to 360 degrees displayed on the StrafeHUD, \"-1\" = current fov, \"0\" = dynamic (chooses the minimum range required to still see the whole area needed for accelerating)" ++seta hud_panel_strafehud_range_sidestrafe "-2" "the angle range up to 360 degrees displayed on the StrafeHUD when side strafing, \"0\" = dynamic (chooses the minimum range required to still see the whole area needed for accelerating), \"-1\" = current fov, \"-2\" = same as the normal range" ++seta hud_panel_strafehud_style "2" "\"0\" = no styling, \"1\" = progress bar style for the strafe bar, \"2\" = accelerated gradient for the strafe bar (no non-linear projection for gradient color/opacity), \"3\" = software gradient for the strafe bar (slow)" seta hud_panel_strafehud_unit_show "1" "show units" - seta hud_panel_strafehud_onground_mode "2" "handling of landing at speeds where friction is higher than optimal acceleration, 0 = fill the whole hud with overturn, 1 = show zones regardless, 2 = show the zones as if airborne (useful for quake2 and quake3 physics)" - seta hud_panel_strafehud_onground_friction "1" "set to 1 to account for friction in calculations" - seta hud_panel_strafehud_bar_preaccel "1" "set to 1 to extend the acceleration zone by the strafe meter zone before full acceleration can be achieved" -seta hud_panel_strafehud_uncapped "0" "remove some safety restrictions, useful to set thinner indicator lines down to 1px or for trying out higher values for some performance degrading operations (WARNING: elements may turn invisible if too thin, other configurations may crash your game or look horribly ugly)" + seta hud_panel_strafehud_onground_mode "2" "handling of landing at speeds where friction is higher than optimal acceleration; \"0\" = fill the whole HUD with overturn, \"1\" = show zones regardless, \"2\" = show the zones as if airborne (useful for quake2 and quake3 physics)" + seta hud_panel_strafehud_onground_friction "1" "account for friction in calculations" + seta hud_panel_strafehud_bar_preaccel "1" "extend the acceleration zone by the strafe meter zone before full acceleration can be achieved" seta hud_panel_strafehud_bar_preaccel_color "0 1 0" "color of the strafe meter pre-acceleration zone" seta hud_panel_strafehud_bar_preaccel_alpha "0.5" "opacity of the strafe meter pre-acceleration zone" seta hud_panel_strafehud_bar_neutral_color "1 1 1" "color of the strafe meter neutral zone" @@@ -186,39 -191,23 +186,39 @@@ seta hud_panel_strafehud_angle_preaccel seta hud_panel_strafehud_angle_neutral_color "1 1 0" "color of the indicator showing the player's current angle if it is within the neutral zone" seta hud_panel_strafehud_angle_accel_color "0 1 1" "color of the indicator showing the player's current angle if it is within the acceleration zone" seta hud_panel_strafehud_angle_overturn_color "1 0 1" "color of the indicator showing the player's current angle if it is within the overturn zone" - seta hud_panel_strafehud_angle_line "0" "defines the number of dashes of the indicator line showing the player's current angle (set to 0 to disable or 1 for a solid line)" -seta hud_panel_strafehud_angle_arrow "1" "set the angle indicator's arrow style; \"0\" = none, \"1\" = top, \"2\" = bottom, \"3\" = both" -seta hud_panel_strafehud_angle_arrow_size "0.5" "size of the arrow (relative to the panel height)" ++seta hud_panel_strafehud_angle_line "0" "defines the number of dashes of the indicator line showing the player's current angle; \"0\" = no line , \"1\" = solid line" +seta hud_panel_strafehud_angle_line_width "0.001" "width of the indicator line showing the player's current angle (relative to the panel width)" +seta hud_panel_strafehud_angle_line_height "1" "height of the indicator line showing the player's current angle (relative to the panel height)" - seta hud_panel_strafehud_angle_arrow "1" "arrow style of the angle indicator showing the player's current angle (0 = none, 1 = top, 2 = bottom, 3 = both)" ++seta hud_panel_strafehud_angle_arrow "1" "arrow style of the angle indicator showing the player's current angle; \"0\" = none, \"1\" = top, \"2\" = bottom, \"3\" = both" +seta hud_panel_strafehud_angle_arrow_size "0.5" "arrow size of the indicator showing the player's current angle (relative to the panel height)" - seta hud_panel_strafehud_bestangle "1" "set to 1 to enable a ghost angle indicator showing the best angle to gain maximum acceleration, 2 = only when side strafing" + seta hud_panel_strafehud_bestangle "1" "\"1\" = enable a ghost angle indicator showing the best angle to gain maximum acceleration, \"2\" = only when side strafing" seta hud_panel_strafehud_bestangle_color "1 1 1" "color of the indicator showing the best angle to gain maximum acceleration" seta hud_panel_strafehud_bestangle_alpha "0.5" "opacity of the indicator showing the best angle to gain maximum acceleration" - seta hud_panel_strafehud_bestangle_line "0" "defines the number of dashes of the best angle indicator line (set to 0 to disable or 1 for a solid line)" -seta hud_panel_strafehud_switch "1" "\"1\" = enable the switch indicator showing the angle to move to when switching sides, \"2\" = show the normal switch indicators when W-turning, \"3\" = also while side strafing" -seta hud_panel_strafehud_switch_minspeed "-1" "minimum speed in qu/s at which switch indicator(s) which are used to aid changing strafe direction will be shown; \"-1\" = dynamic" -seta hud_panel_strafehud_switch_color "1 1 0" "color of the switch indicator" -seta hud_panel_strafehud_switch_alpha "1" "opacity of the switch indicator" -seta hud_panel_strafehud_switch_width "0.003" "width of the strafe angle indicator(s) (relative to the strafe bar width)" ++seta hud_panel_strafehud_bestangle_line "0" "defines the number of dashes of the best angle indicator line; \"0\" = no line , \"1\" = solid line" +seta hud_panel_strafehud_bestangle_line_width "0.001" "width of the best angle indicator line (relative to the panel width)" +seta hud_panel_strafehud_bestangle_line_height "1" "height of the best angle indicator line (relative to the panel height)" - seta hud_panel_strafehud_bestangle_arrow "1" "arrow style of the best angle indicator (0 = none, 1 = top, 2 = bottom, 3 = both)" ++seta hud_panel_strafehud_bestangle_arrow "1" "arrow style of the best angle indicator; \"0\" = none, \"1\" = top, \"2\" = bottom, \"3\" = both" +seta hud_panel_strafehud_bestangle_arrow_size "0.5" "arrow size of the best angle indicator (relative to the panel height)" - seta hud_panel_strafehud_switch "1" "set to 1 to enable the strafe angle indicator showing the angle to move to when changing side, 2 = show the normal switch indicators when W-turning, 3 = also while side strafing" - seta hud_panel_strafehud_switch_minspeed "-1" "minimum speed in qu/s at which angle indicator(s) which are used to aid changing strafe direction will be shown (set to -1 for dynamic minspeed)" ++seta hud_panel_strafehud_switch "1" "\"1\" = enable the strafe angle indicator showing the angle to move to when changing side, \"2\" = show the normal switch indicators when W-turning, \"3\" = also while side strafing" ++seta hud_panel_strafehud_switch_minspeed "-1" "minimum speed in qu/s at which angle indicator(s) which are used to aid changing strafe direction will be shown; \"-1\" = dynamic" +seta hud_panel_strafehud_switch_color "1 1 0" "color of the strafe angle indicators for changing strafe direction" +seta hud_panel_strafehud_switch_alpha "0.5" "opacity of the strafe angle indicators for changing strafe direction" - seta hud_panel_strafehud_switch_line "0" "defines the number of dashes of the change angle indicator line (set to 0 to disable or 1 for a solid line)" ++seta hud_panel_strafehud_switch_line "0" "defines the number of dashes of the change angle indicator line; \"0\" = no line , \"1\" = solid line" +seta hud_panel_strafehud_switch_line_width "0.001" "width of the change angle indicator line (relative to the panel width)" +seta hud_panel_strafehud_switch_line_height "1" "height of the change angle indicator line (relative to the panel height)" - seta hud_panel_strafehud_switch_arrow "1" "arrow style of the change angle indicator (0 = none, 1 = top, 2 = bottom, 3 = both)" ++seta hud_panel_strafehud_switch_arrow "1" "arrow style of the change angle indicator; \"0\" = none, \"1\" = top, \"2\" = bottom, \"3\" = both" +seta hud_panel_strafehud_switch_arrow_size "0.5" "arrow size of the change angle indicator (relative to the panel height)" - seta hud_panel_strafehud_wturn "1" "enable the W-turn indicators showing the angle to rotate your velocity as fast as possible, 1 = only if W-turning, 2 = also while strafing normally, 3 = also while side strafing" + seta hud_panel_strafehud_wturn "1" "enable W-turn indicators showing the angle to rotate your velocity as fast as possible; \"1\" = only if W-turning, \"2\" = also while strafing normally, \"3\" = also while side strafing" -seta hud_panel_strafehud_wturn_color "0 1 1" "color of the W-turn indicators" -seta hud_panel_strafehud_wturn_alpha "1" "opacity of the W-turn indicators" -seta hud_panel_strafehud_wturn_width "0.003" "width of the W-turn indicators (relative to the strafe bar width)" +seta hud_panel_strafehud_wturn_color "0 0 1" "color of the W-turn indicators" +seta hud_panel_strafehud_wturn_alpha "0.5" "opacity of the W-turn indicators" - seta hud_panel_strafehud_wturn_proper "0" "use the proper formula to calculate W-turn indicators (warning: loses accuracy at high speeds)" - seta hud_panel_strafehud_wturn_unrestricted "0" "set to 1 to enable the W-turn indicators even when W-turning gives acceleration (warning: not completely accurate)" - seta hud_panel_strafehud_wturn_line "0" "defines the number of dashes of the W-turn angle indicator line (set to 0 to disable or 1 for a solid line)" + seta hud_panel_strafehud_wturn_proper "0" "use the proper formula to calculate W-turn indicators (WARNING: loses accuracy at high speeds)" + seta hud_panel_strafehud_wturn_unrestricted "0" "enable W-turn indicators even when W-turning gives acceleration (WARNING: not completely accurate)" ++seta hud_panel_strafehud_wturn_line "0" "defines the number of dashes of the W-turn angle indicator line; \"0\" = no line , \"1\" = solid line" +seta hud_panel_strafehud_wturn_line_width "0.001" "width of the W-turn angle indicator line (relative to the panel width)" +seta hud_panel_strafehud_wturn_line_height "1" "height of the W-turn angle indicator line (relative to the panel height)" - seta hud_panel_strafehud_wturn_arrow "1" "arrow style of the W-turn angle indicator (0 = none, 1 = top, 2 = bottom, 3 = both)" ++seta hud_panel_strafehud_wturn_arrow "1" "arrow style of the W-turn angle indicator; \"0\" = none, \"1\" = top, \"2\" = bottom, \"3\" = both" +seta hud_panel_strafehud_wturn_arrow_size "0.5" "arrow size of the W-turn angle indicator (relative to the panel height)" - seta hud_panel_strafehud_direction "0" "set to 1 to enable the direction caps to see in which direction you are currently strafing" + seta hud_panel_strafehud_direction "0" "enable direction caps to see in which direction you are currently strafing" seta hud_panel_strafehud_direction_color "0 0.5 1" "color of the direction caps which indicate the direction the player is currently strafing towards" seta hud_panel_strafehud_direction_alpha "1" "opacity of the direction caps which indicate the direction the player is currently strafing towards" seta hud_panel_strafehud_direction_width "0.25" "stroke width of the direction caps which indicate the direction the player is currently strafing towards (relative to the panel height)" @@@ -229,43 -218,21 +229,43 @@@ seta hud_panel_strafehud_slickdetector_ seta hud_panel_strafehud_slickdetector_color "0 1 1" "color of the slick detector indicator" seta hud_panel_strafehud_slickdetector_alpha "0.5" "opacity of the slick detector indicator" seta hud_panel_strafehud_slickdetector_height "0.125" "height of the slick detector indicator (relative to the panel height)" - seta hud_panel_strafehud_startspeed "1" "set to 1 to enable the start speed indicator which shows you the speed you had while passing the start trigger of a race map" + seta hud_panel_strafehud_startspeed "1" "enable the start speed indicator which shows you the speed you had while passing the start trigger of a race map" seta hud_panel_strafehud_startspeed_fade "4" "fade time (in seconds) of the start speed text" seta hud_panel_strafehud_startspeed_color "1 0.75 0" "color of the start speed text" - seta hud_panel_strafehud_startspeed_pos "0 -1" "position of the start speed text (relative to the panel), the Y coordinate must be <= -1 (below) or >= 1 (above) the panel" ++seta hud_panel_strafehud_startspeed_pos "0 -1" "position of the start speed text (relative to the panel), the Y coordinate must be <= \"-1\" (below) or >= \"1\" (above) the panel" seta hud_panel_strafehud_startspeed_size "1.5" "size of the start speed text (relative to the panel height)" - seta hud_panel_strafehud_jumpheight "0" "set to 1 to enable the jump height indicator which tells you how high you jumped" + seta hud_panel_strafehud_jumpheight "0" "enable the jump height indicator which tells you how high you jumped" seta hud_panel_strafehud_jumpheight_fade "4" "fade time (in seconds) of the jump height text" seta hud_panel_strafehud_jumpheight_min "50" "minimum jump height to display in the selected unit" seta hud_panel_strafehud_jumpheight_color "0 1 0.75" "color of the jump height text" - seta hud_panel_strafehud_jumpheight_pos "0 -2" "position of the jump height text (relative to the panel), the Y coordinate must be <= -1 (below) or >= 1 (above) the panel" ++seta hud_panel_strafehud_jumpheight_pos "0 -2" "position of the jump height text (relative to the panel), the Y coordinate must be <= \"-1\" (below) or >= \"1\" (above) the panel" seta hud_panel_strafehud_jumpheight_size "1.5" "size of the jump height text (relative to the panel height)" - seta hud_panel_strafehud_timeout_ground "0.1" "time (in seconds) after take off before changing to air strafe physics when not jumping (visually more consistent hud while on slick downwards ramps)" - seta hud_panel_strafehud_timeout_turn "0.1" "time (in seconds) after releasing the strafe keys before changing mode (visually more consistent hud while switching between left/right strafe turning)" - seta hud_panel_strafehud_antiflicker_angle "0.01" "how many degrees from 0° to 180° the hud ignores if it could cause visual disturbances otherwise (and to counter rounding errors)" + seta hud_panel_strafehud_timeout_ground "0.1" "time (in seconds) after take off before changing to air strafe physics when not jumping (visually more consistent HUD while on downwards slick ramps)" + seta hud_panel_strafehud_timeout_turn "0.1" "time (in seconds) after releasing the strafe keys before changing mode (visually more consistent HUD while switching between left/right strafe turning)" + seta hud_panel_strafehud_antiflicker_angle "0.01" "how many degrees from 0° to 180° the HUD ignores if it could cause visual disturbances otherwise (and to counter rounding errors)" seta hud_panel_strafehud_fps_update "0.5" "update interval (in seconds) of the frametime to calculate the optimal angle, smaller values may cause flickering" - seta hud_panel_strafehud_sonar "0" "set to 1 to enable the strafe sonar" ++seta hud_panel_strafehud_sonar "0" "\"1\" = enable the strafe sonar" +seta hud_panel_strafehud_sonar_audio "misc/talk" "audio to play for sonar" +seta hud_panel_strafehud_sonar_start "0.5" "how optimal from 0 to 1 your strafing angle has to be for the strafe sonar to activate" +seta hud_panel_strafehud_sonar_interval_start "0.333333" "strafe sonar sound interval in seconds" +seta hud_panel_strafehud_sonar_interval_range "-0.222222" "dynamic sound interval range in seconds of the strafe sonar as you approach the optimal angle" +seta hud_panel_strafehud_sonar_interval_exponent "1" "exponent of the dynamic sound interval range of the strafe sonar" +seta hud_panel_strafehud_sonar_volume_start "0.333333" "sound volume of the strafe sonar" +seta hud_panel_strafehud_sonar_volume_range "0.666666" "dynamic volume range of the strafe sonar as you approach the optimal angle" +seta hud_panel_strafehud_sonar_volume_exponent "1" "exponent of the dynamic volume range of the strafe sonar" +seta hud_panel_strafehud_sonar_pitch_start "0.9" "playback speed of the strafe sonar" +seta hud_panel_strafehud_sonar_pitch_range "0.1" "dynamic playback speed range of the strafe sonar as you approach the optimal angle" +seta hud_panel_strafehud_sonar_pitch_exponent "1" "exponent of the dynamic playback speed range of the strafe sonar" - seta hud_panel_strafehud_vangle "0" "set to 1 to enable the vertical angle indicator" ++seta hud_panel_strafehud_vangle "0" "\"1\" = enable the vertical angle indicator" +seta hud_panel_strafehud_vangle_color "0.75 0.75 0.75" "color of the vertical angle text" - seta hud_panel_strafehud_vangle_pos "-0.25 1" "position of the vertical angle text (relative to the panel), the Y coordinate must be <= -1 (below) or >= 1 (above) the panel" ++seta hud_panel_strafehud_vangle_pos "-0.25 1" "position of the vertical angle text (relative to the panel), the Y coordinate must be <= \"-1\" (below) or >= \"1\" (above) the panel" +seta hud_panel_strafehud_vangle_size "1" "size of the vertical angle text (relative to the panel height)" - seta hud_panel_strafehud_strafeefficiency "0" "set to 1 to enable the strafe efficiency indicator" - seta hud_panel_strafehud_strafeefficiency_pos "0.25 1" "position of the strafe efficiency text (relative to the panel), the Y coordinate must be <= -1 (below) or >= 1 (above) the panel" ++seta hud_panel_strafehud_strafeefficiency "0" "\"1\" = enable the strafe efficiency indicator" ++seta hud_panel_strafehud_strafeefficiency_pos "0.25 1" "position of the strafe efficiency text (relative to the panel), the Y coordinate must be <= \"-1\" (below) or >= \"1\" (above) the panel" +seta hud_panel_strafehud_strafeefficiency_size "1" "size of the strafe efficiency text (relative to the panel height)" - seta hud_panel_strafehud_projection "0" "strafehud projection mode, 0 = linear, 1 = perspective, 2 = panoramic" ++seta hud_panel_strafehud_projection "0" "StrafeHUD projection mode; \"0\" = linear, \"1\" = perspective, \"2\" = panoramic" - // hud panel aliases + // HUD panel aliases alias quickmenu "cl_cmd hud quickmenu ${* ?}" alias hud_panel_radar_rotate "toggle hud_panel_radar_rotation 0 1 2 3 4" diff --cc qcsrc/client/hud/panel/strafehud/util.qc index 1181628ea,000000000..dd7c4eb35 mode 100644,000000..100644 --- a/qcsrc/client/hud/panel/strafehud/util.qc +++ b/qcsrc/client/hud/panel/strafehud/util.qc @@@ -1,343 -1,0 +1,343 @@@ +#include "util.qh" + +#include +#include +#include + +// convert a strafe angle into a HUD width value +float StrafeHUD_AngleToWidth(float angle, float range) +{ + return angle / range * panel_size.x; +} + +// convert a strafe angle into a centered HUD offset value +float StrafeHUD_AngleToOffset(float angle, float range) +{ + return StrafeHUD_AngleToWidth(angle, range) + panel_size.x / 2; +} + +// turn a ratio into a projected ratio based on the total angular distance +float StrafeHUD_Project(float ratio, float range, bool reverse) +{ + range *= DEG2RAD / 2; + switch(autocvar_hud_panel_strafehud_projection) + { + default: + case STRAFEHUD_PROJECTION_LINEAR: + return ratio; + case STRAFEHUD_PROJECTION_PERSPECTIVE: + if(!reverse) + { + ratio *= range; + ratio = tan(ratio) / tan(range); + } + else + { + ratio = atan(ratio * tan(range)); + ratio /= range; + } + break; + case STRAFEHUD_PROJECTION_PANORAMIC: + if(!reverse) + { + ratio *= range; + ratio = tan(ratio / 2) / tan(range / 2); + } + else + { + ratio = atan(ratio * tan(range / 2)) * 2; + ratio /= range; + } + break; + } + return ratio; +} + +// project a centered HUD offset value +float StrafeHUD_ProjectOffset(float offset, float range, bool reverse) +{ + if(autocvar_hud_panel_strafehud_projection == STRAFEHUD_PROJECTION_LINEAR) + return offset; + + float ratio = (offset - (panel_size.x / 2)) / (panel_size.x / 2); + ratio = StrafeHUD_Project(ratio, range, reverse); + offset = ratio * (panel_size.x / 2) + (panel_size.x / 2); + return offset; +} + +// project a HUD width value +float StrafeHUD_ProjectWidth(float offset, float width, float range) +{ + if(autocvar_hud_panel_strafehud_projection == STRAFEHUD_PROJECTION_LINEAR) + return width; + + return StrafeHUD_ProjectOffset(offset + width, range, false) - StrafeHUD_ProjectOffset(offset, range, false); +} + +// length unit conversion (km and miles are only included to match the GetSpeedUnit* functions) +float StrafeHUD_GetLengthUnitFactor(int length_unit) +{ + switch(length_unit) + { + default: + case 1: return 1.0; + case 2: return 0.0254; + case 3: return 0.0254 * 0.001; + case 4: return 0.0254 * 0.001 * 0.6213711922; + case 5: return 0.0254 * 0.001 * 0.5399568035; + } +} + +string StrafeHUD_GetLengthUnit(int length_unit) +{ + switch(length_unit) + { + // translator-friendly strings without the initial space + default: + case 1: return strcat(" ", _("qu")); + case 2: return strcat(" ", _("m")); + case 3: return strcat(" ", _("km")); + case 4: return strcat(" ", _("mi")); + case 5: return strcat(" ", _("nmi")); + } +} + +// check the player waterlevel without affecting the player entity, this way we can fetch waterlevel even if client prediction is disabled +float StrafeHUD_DetermineWaterLevel(entity e) +{ + // store old values + void old_contentstransition(int, int) = e.contentstransition; + float old_watertype = e.watertype; + float old_waterlevel = e.waterlevel; + + e.contentstransition = func_null; // unset the contentstransition function if present + _Movetype_CheckWater(e); + float new_waterlevel = e.waterlevel; // store the player waterlevel + + // restore old values + e.contentstransition = old_contentstransition; + e.watertype = old_watertype; + e.waterlevel = old_waterlevel; + + return new_waterlevel; +} + +// determine frametime, to avoid jitter, average the frametime in case client prediction is used +float StrafeHUD_DetermineFrameTime() +{ + static float dt_update = 0; + static int dt_time = 0; + static float dt_sum = 0; + static float dt = 0; + if((csqcplayer_status == CSQCPLAYERSTATUS_PREDICTED) && (input_timelength > 0)) + { + float dt_client = input_timelength; + + 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 + dt_sum += dt_client * dt_client; // weighted sum of all frametimes (mean numerator) + dt_time += dt_client; // time spent averaging (mean denominator) + + if(((time - dt_update) > autocvar_hud_panel_strafehud_fps_update) || (dt_update == 0)) + { + dt = dt_sum / dt_time; + dt_update = time; + dt_time = dt_sum = 0; + } + } + else // when spectating other players server ticrate will be used, this may not be accurate but there is no way to find other player's frametime + { + dt = ticrate; + dt_update = dt_time = dt_sum = 0; + } + + return dt; +} + +// determine player wishdir, non-local player movement is limited to 45 degree steps +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; + } + 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) + { + if(wishangle < 0) + wishangle += 180; + else + wishangle -= 180; + + wishangle *= -1; + } + } + } + } + else // alternatively calculate wishdir by querying pressed keys + { - if((keys & KEY_FORWARD) || (keys & KEY_BACKWARD)) ++ if(keys & (KEY_FORWARD | KEY_BACKWARD)) + wishangle = 45; + else + wishangle = 90; + if(keys & KEY_LEFT) + wishangle *= -1; + else if(!(keys & KEY_RIGHT)) + wishangle = 0; // wraps at 180° + } + + return wishangle; +} + +// determine whether the player is pressing forwards or backwards keys +int StrafeHUD_DetermineForwardKeys(vector movement, int keys, bool is_local) +{ + if(is_local) // if entity is local player + { + if(movement.x > 0) + return STRAFEHUD_KEYS_FORWARD; + else if(movement.x < 0) + return STRAFEHUD_KEYS_BACKWARD; + else + return STRAFEHUD_KEYS_NONE; + } + else // alternatively determine direction by querying pressed keys + { + if((keys & KEY_FORWARD) && !(keys & KEY_BACKWARD)) + return STRAFEHUD_KEYS_FORWARD; + else if(!(keys & KEY_FORWARD) && (keys & KEY_BACKWARD)) + return STRAFEHUD_KEYS_BACKWARD; + else + return STRAFEHUD_KEYS_NONE; + } +} + +float StrafeHUD_DetermineHudAngle(float absolute_wishangle, float absolute_overturnangle, float strafity) +{ + + // determine the minimal required HUD angle to contain the full strafing angle range + // this is useful for the velocity centered mode where the zones do not follow the strafing angle + // how it works: + // the angle where the most acceleration occurs moves relative to the player velocity + // from 0 - wishangle to absolute_overturnangle - wishangle + // the angle farther away from the center is the maximum the optimal strafing angle can + // diverge from the direction of velocity + // this angle has to be multiplied by two since the HUD extends in both directions which + // halves the amount it extends in a single direction + float range_minangle = max(absolute_wishangle, absolute_overturnangle - absolute_wishangle) * 2; + + float range_normal = autocvar_hud_panel_strafehud_range; + float range_side = autocvar_hud_panel_strafehud_range_sidestrafe; + float range_used; + + float hfov = getproperty(VF_FOVX); + if(isnan(range_normal) || isnan(range_side) || isnan(hfov)) return 360; + + // negative values enable different behaviour + // no exact matching so that all negative values are caught + if(range_normal == 0) // range = 0, use minimum angle required if dynamically setting hud angle + range_normal = autocvar__hud_configure ? 90 : range_minangle; + else if(range_normal < 0) // range = -1, use the current field of view + range_normal = hfov; + + if(range_side < -1) // range = -2, use the normal range + range_used = range_normal; + else + { + if(range_side == 0) // range = 0, use minimum angle required if dynamically setting hud angle + range_side = autocvar__hud_configure ? 90 : range_minangle; + else if(range_side < 0) // range = -1, use the current field of view + range_side = hfov; + + range_used = GeomLerp(range_normal, strafity, range_side); + } + float hudangle = bound(0, fabs(range_used), 360); // limit HUD range to 360 degrees, higher values don't make sense + + // limit strafe-meter angle to values suitable for the current projection mode + switch(autocvar_hud_panel_strafehud_projection) + { + // those limits are a little less than the maximal FOV the game allows + // however, they suffice for all realistic use cases + case STRAFEHUD_PROJECTION_PERSPECTIVE: + hudangle = min(hudangle, 170); + break; + case STRAFEHUD_PROJECTION_PANORAMIC: + hudangle = min(hudangle, 350); + break; + } + + return hudangle; +} + +// determine whether the player is strafing left or right +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)) + return STRAFEHUD_DIRECTION_RIGHT; + else if(angle < -antiflicker_angle && angle > (-180 + antiflicker_angle)) + return STRAFEHUD_DIRECTION_LEFT; + else + return STRAFEHUD_DIRECTION_NONE; + } +} + +// determine whether the player holds the jump key +// try to ignore if track_canjump is enabled +// does not work in spectator mode if the spectated player uses +jetpack or cl_movement_track_canjump +bool StrafeHUD_DetermineJumpHeld(entity e, int keys, bool is_local) +{ + if(is_local) + { + if((PHYS_INPUT_BUTTON_JUMP(e) || PHYS_INPUT_BUTTON_JETPACK(e)) && !PHYS_CL_TRACK_CANJUMP(e)) + return true; + } + else + { + if((keys & KEY_JUMP) && !PHYS_TRACK_CANJUMP(e)) + return true; + } + + return false; +} + +// mix two colors based on a ratio +vector StrafeHUD_MixColors(vector color1, vector color2, float ratio) +{ + if(ratio <= 0) return color1; + if(ratio >= 1) return color2; + return color1 + (color2 - color1) * ratio; +}