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"
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)"
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"
--- /dev/null
- if((keys & KEY_FORWARD) || (keys & KEY_BACKWARD))
+#include "util.qh"
+
+#include <lib/csqcmodel/cl_player.qh>
+#include <common/physics/player.qh>
+#include <common/physics/movetypes/movetypes.qh>
+
+// 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 | 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;
+}