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_arrow "1" "set the angle indicator's arrow style: 0 = none, 1 = top, 2 = bottom, 3 = both"
-seta hud_panel_strafehud_angle_arrow_height "0.5" "height of the arrow (relative to the panel height)"
-seta hud_panel_strafehud_angle_arrow_width "0.03" "width of the arrow (relative to the panel width)"
+seta hud_panel_strafehud_angle_arrow_size "0.5" "size of the arrow (relative to the panel height)"
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 (set to -1 for dynamic minspeed)"
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"
if(autocvar_hud_panel_strafehud_angle_arrow > 0)
{
- vector arrow_size = currentangle_size;
- arrow_size.x = panel_size.x * autocvar_hud_panel_strafehud_angle_arrow_width;
- arrow_size.y = panel_size.y * min(autocvar_hud_panel_strafehud_angle_arrow_height, 10);
- vector arrow_fragment = '0 0.2 0';
-
- if(arrow_size.x > 0 && arrow_size.y > 0)
+ float arrow_size = panel_size.y * min(autocvar_hud_panel_strafehud_angle_arrow_size, 10); // there's only one size cvar, arrows always have a 45° angle to ensure proper rendering without antialiasing
+ if(arrow_size > 0)
{
- // find a suitable fragment size to draw all the parts evenly
- float fragment_divisor1 = arrow_size.y / arrow_fragment.y;
- float fragment_divisor2 = fragment_divisor1 - floor(fragment_divisor1);
- fragment_divisor1 = floor(fragment_divisor1);
- if(fragment_divisor1 >= 1)
- {
- if(fragment_divisor2 < 0.5)
- arrow_fragment.y += arrow_fragment.y * fragment_divisor2 / fragment_divisor1;
- else
- arrow_fragment.y -= arrow_fragment.y * (1 - fragment_divisor2) / (fragment_divisor1 + 1);
- }
- else
- {
- arrow_fragment.y = arrow_size.y;
- }
-
- for(float i = arrow_size.y; i > 0; i -= arrow_fragment.y)
- {
- arrow_fragment.x = arrow_size.x * (i/arrow_size.y);
- if(autocvar_hud_panel_strafehud_angle_arrow == 1 || autocvar_hud_panel_strafehud_angle_arrow >= 3)
- drawfill(panel_pos - eY * ((currentangle_size.y - panel_size.y) / 2 + i) + eX * (currentangle_offset - arrow_fragment.x/2), arrow_fragment, currentangle_color, autocvar_hud_panel_strafehud_angle_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
- if(autocvar_hud_panel_strafehud_angle_arrow >= 2)
- drawfill(panel_pos + eY * (-(currentangle_size.y - panel_size.y) / 2 + currentangle_size.y + i - arrow_fragment.y) + eX * (currentangle_offset - arrow_fragment.x/2), arrow_fragment, currentangle_color, autocvar_hud_panel_strafehud_angle_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
- }
+ if(autocvar_hud_panel_strafehud_angle_arrow == 1 || autocvar_hud_panel_strafehud_angle_arrow >= 3)
+ StrafeHUD_drawStrafeArrow(panel_pos + eY * ((panel_size.y - currentangle_size.y) / 2) + eX * currentangle_offset, arrow_size, currentangle_color, autocvar_hud_panel_strafehud_angle_alpha * panel_fg_alpha, true);
+ if(autocvar_hud_panel_strafehud_angle_arrow >= 2)
+ StrafeHUD_drawStrafeArrow(panel_pos + eY * ((panel_size.y - currentangle_size.y) / 2 + currentangle_size.y) + eX * currentangle_offset, arrow_size, currentangle_color, autocvar_hud_panel_strafehud_angle_alpha * panel_fg_alpha, false);
}
}
}
}
}
+// 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)
+{
+ if(flipped) origin -= size*eY;
+ R_BeginPolygon("", DRAWFLAG_NORMAL, true);
+ R_PolygonVertex(origin + (flipped ? size*eY : '0 0 0') , '0 0 0', color, alpha);
+ R_PolygonVertex(origin + (flipped ? '0 0 0' : size*eY) - size*eX, '0 0 0', color, alpha);
+ R_PolygonVertex(origin + (flipped ? '0 0 0' : size*eY) + size*eX, '0 0 0', color, alpha);
+ R_EndPolygon();
+}
+
// length unit conversion (km and miles are only included to match the GetSpeedUnit* functions)
float GetLengthUnitFactor(int length_unit)
{
AUTOCVAR_SAVE(hud_panel_strafehud_angle_accel_color, vector, '0 1 1', "color of the indicator showing the player's current angle if it is within the acceleration zone");
AUTOCVAR_SAVE(hud_panel_strafehud_angle_overturn_color, vector, '1 0 1', "color of the indicator showing the player's current angle if it is within the overturn zone");
AUTOCVAR_SAVE(hud_panel_strafehud_angle_arrow, int, 1, "set the angle indicator's arrow style: 0 = none, 1 = top, 2 = bottom, 3 = both");
-AUTOCVAR_SAVE(hud_panel_strafehud_angle_arrow_height, float, 0.5, "height of the arrow (relative to the panel height)");
-AUTOCVAR_SAVE(hud_panel_strafehud_angle_arrow_width, float, 0.03, "width of the arrow (relative to the panel width)");
+AUTOCVAR_SAVE(hud_panel_strafehud_angle_arrow_size, float, 0.5, "size of the arrow (relative to the panel height)");
AUTOCVAR_SAVE(hud_panel_strafehud_switch_minspeed, float, -1, "minimum speed in qu/s at which switch indicator(s) which are used to aid changing strafe direction will be shown (set to -1 for dynamic minspeed)");
AUTOCVAR_SAVE(hud_panel_strafehud_switch_color, vector, '1 1 0', "color of the switch indicator");
AUTOCVAR_SAVE(hud_panel_strafehud_switch_alpha, float, 1, "opacity of the switch indicator");
void StrafeHUD_drawGradient(vector, vector, vector, float, float, float, float, int);
float GetLengthUnitFactor(int);
string GetLengthUnit(int);
+void StrafeHUD_drawStrafeArrow(vector, float, vector, float, bool);