]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
strafehud: improved comments to better document slick detector behavior Juhu/slick_detect_stuff
authorJuhu <5894800-Juhu_@users.noreply.gitlab.com>
Mon, 19 Aug 2024 18:07:58 +0000 (20:07 +0200)
committerJuhu <5894800-Juhu_@users.noreply.gitlab.com>
Mon, 19 Aug 2024 18:07:58 +0000 (20:07 +0200)
qcsrc/client/hud/panel/strafehud.qc

index 66fd55bf093383ee69a402560856f6a3239dab57..dff499d00896ba493f9598a279c35b2a6508e5d8 100644 (file)
 #include <lib/csqcmodel/common.qh> // for IS_PLAYER() macro
 #include <common/resources/cl_resources.qh> // 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;
                                }
                        }