From 40df69ebe55755e3c7a792e91d79334ca5bd6f55 Mon Sep 17 00:00:00 2001 From: Juhu <5894800-Juhu_@users.noreply.gitlab.com> Date: Mon, 19 Aug 2024 20:07:58 +0200 Subject: [PATCH] strafehud: improved comments to better document slick detector behavior --- qcsrc/client/hud/panel/strafehud.qc | 33 +++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/qcsrc/client/hud/panel/strafehud.qc b/qcsrc/client/hud/panel/strafehud.qc index 66fd55bf0..dff499d00 100644 --- a/qcsrc/client/hud/panel/strafehud.qc +++ b/qcsrc/client/hud/panel/strafehud.qc @@ -21,6 +21,11 @@ #include // for IS_PLAYER() macro #include // IS_DEAD() macro +// epsilon value for the slick detector steps to avoid +// an infinite loop due to floating point rounding errors +// (works with current limits as long as uncapped mode is not used) +#define SLICKDETECT_STEPS_EPSILON 0.00001 + // StrafeHUD (#25) void HUD_StrafeHUD_Export(int fh) @@ -782,35 +787,49 @@ void HUD_StrafeHUD() panel_size.x > 0) { float slicksteps = max(autocvar_hud_panel_strafehud_slickdetector_granularity, 0); + bool allslick = PHYS_FRICTION(strafeplayer) == 0; bool slickdetected = false; if(!autocvar_hud_panel_strafehud_uncapped) slicksteps = min(slicksteps, 4); slicksteps = 90 * DEG2RAD / 2 ** slicksteps; - slickdetected = real_onslick; // don't need to traceline if already touching slick + // don't need to traceline if already touching slick + slickdetected = real_onslick; + + // coordinates at the bottom center of the player bbox + vector traceorigin = strafeplayer.origin + eZ * strafeplayer.mins.z; // traceline into every direction trace_dphitq3surfaceflags = 0; - vector traceorigin = strafeplayer.origin + eZ * strafeplayer.mins.z; - for(float i = 0; i < 90 * DEG2RAD - 0.00001 && !slickdetected; i += slicksteps) + for(float i = 0; i < 90 * DEG2RAD - SLICKDETECT_STEPS_EPSILON && !slickdetected; i += slicksteps) { vector slickoffset; float slickrotate; + + // creates a vector angled 'i' degrees relative to the Z vector + // negative cosine value to face downwards slickoffset.z = -cos(i) * autocvar_hud_panel_strafehud_slickdetector_range; slickrotate = sin(i) * autocvar_hud_panel_strafehud_slickdetector_range; - for(float j = 0; j < 360 * DEG2RAD - 0.00001 && !slickdetected; j += slicksteps) + for(float j = 0; j < 360 * DEG2RAD - SLICKDETECT_STEPS_EPSILON && !slickdetected; j += slicksteps) { + // adjusts the vector so that it rotates 'j' degrees around the Z vector slickoffset.x = sin(j) * slickrotate; slickoffset.y = cos(j) * slickrotate; + // trace a line, we hit slick if: + // - it hits something and surface friction is disabled + // - the slick surface flag got set + // note: it is not guaranteed that the detected surface is actually + // a zero friction surface if PHYS_FRICTION_SLICK() does not equal zero traceline(traceorigin, traceorigin + slickoffset, MOVE_NOMONSTERS, strafeplayer); - if((PHYS_FRICTION(strafeplayer) == 0 && trace_fraction < 1) + if((allslick && trace_fraction < 1) || (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK)) slickdetected = true; - if(i == 0) - break; + + // rotation does nothing when we are perpendicular to the ground, hence only one iteration + if(i == 0) break; } } -- 2.39.2