We DO need to detect double-hits, due to the weird engine tracing that
authorRudolf Polzer <divverent@xonotic.org>
Wed, 11 Dec 2013 10:12:07 +0000 (11:12 +0100)
committerRudolf Polzer <divverent@xonotic.org>
Wed, 11 Dec 2013 10:12:07 +0000 (11:12 +0100)
happens sometimes at low angles.

qcsrc/server/command/radarmap.qc
qcsrc/server/g_subs.qc
qcsrc/server/w_common.qc

index 331f5f9..f2205b6 100644 (file)
@@ -28,7 +28,7 @@ float FullTraceFraction(vector a, vector mi, vector ma, vector b)
                        c = trace_endpos;
                }
 
-               n += tracebox_inverted(c, mi, ma, b, MOVE_WORLDONLY, world, FALSE);
+               n += tracebox_inverted(c, mi, ma, b, MOVE_WORLDONLY, world, FALSE, world);
 
                white += vlen(trace_endpos - c);
                c = trace_endpos;
index 834bb47..3d6d2cf 100644 (file)
@@ -534,7 +534,7 @@ void WarpZone_tracebox_antilag (entity source, vector v1, vector mi, vector ma,
        tracebox_antilag_force_wz(source, v1, mi, ma, v2, nomonst, forent, lag, TRUE);
 }
 
-float tracebox_inverted (vector v1, vector mi, vector ma, vector v2, float nomonsters, entity forent, float stopatentity) // returns the number of traces done, for benchmarking
+float tracebox_inverted (vector v1, vector mi, vector ma, vector v2, float nomonsters, entity forent, float stopatentity, entity ignorestopatentity) // returns the number of traces done, for benchmarking
 {
        vector pos, dir, t;
        float nudge;
@@ -552,7 +552,7 @@ float tracebox_inverted (vector v1, vector mi, vector ma, vector v2, float nomon
 
        for(;;)
        {
-               if((pos - v1) * dir >= (v2 - v1) * dir)
+               if(pos * dir >= v2 * dir)
                {
                        // went too far
                        trace_fraction = 1;
@@ -587,7 +587,7 @@ float tracebox_inverted (vector v1, vector mi, vector ma, vector v2, float nomon
                                pos = t + dir * nudge;
 
                                // but if we hit an entity, stop RIGHT before it
-                               if(stopatentity && stopentity)
+                               if(stopatentity && stopentity && stopentity != ignorestopatentity)
                                {
                                        trace_ent = stopentity;
                                        trace_endpos = t;
@@ -612,9 +612,9 @@ float tracebox_inverted (vector v1, vector mi, vector ma, vector v2, float nomon
        }
 }
 
-void traceline_inverted (vector v1, vector v2, float nomonsters, entity forent, float stopatentity)
+void traceline_inverted (vector v1, vector v2, float nomonsters, entity forent, float stopatentity, entity ignorestopatentity)
 {
-       tracebox_inverted(v1, '0 0 0', '0 0 0', v2, nomonsters, forent, stopatentity);
+       tracebox_inverted(v1, '0 0 0', '0 0 0', v2, nomonsters, forent, stopatentity, ignorestopatentity);
 }
 
 /*
index 86ae886..f51db6d 100644 (file)
@@ -163,11 +163,13 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f
 }
 
 float fireBullet_trace_callback_eff;
+entity fireBullet_last_hit;
 void fireBullet_trace_callback(vector start, vector hit, vector end)
 {
        if(vlen(hit - start) > 16)
                trailparticles(world, fireBullet_trace_callback_eff, start, hit);
        WarpZone_trace_forent = world;
+       fireBullet_last_hit = world;
 }
 
 void fireBullet(vector start, vector dir, float spread, float max_solid_penetration, float damage, float force, float dtype, float tracereffects)
@@ -179,7 +181,7 @@ void fireBullet(vector start, vector dir, float spread, float max_solid_penetrat
        end = start + dir * MAX_SHOT_DISTANCE;
 
        entity pl;
-       entity last_hit = world;
+       fireBullet_last_hit = world;
        float solid_penetration_left = 1;
        float total_damage = 0;
 
@@ -241,15 +243,9 @@ void fireBullet(vector start, vector dir, float spread, float max_solid_penetrat
                if(!hit || hit.solid == SOLID_BSP || hit.solid == SOLID_SLIDEBOX)
                        Damage_DamageInfo(start, damage * solid_penetration_left, 0, 0, max(1, force) * dir * solid_penetration_left, dtype, hit.species, self);
 
-               if (hit && hit != WarpZone_trace_forent)  // Avoid self-damage (except after going through a warp).
+               if (hit && hit != WarpZone_trace_forent && hit != fireBullet_last_hit)  // Avoid self-damage (except after going through a warp); avoid hitting the same entity twice (engine bug).
                {
-                       if (hit == last_hit)
-                               if (WarpZone_trace_forent)
-                                       dprint("NOTE: a player was hit twice in a row by the same bullet. But a warpzone was involved. Please verify that this is OK.\n"); // TODO make sure this doesn't actually happen unless when it should.
-                               else
-                                       print("^4WARNING:^7 a player was hit twice in a row by the same bullet.\n");
-                       last_hit = hit;
-
+                       fireBullet_last_hit = hit;
                        yoda = 0;
                        float g = accuracy_isgooddamage(self, hit);
                        Damage(hit, self, self, damage * solid_penetration_left, dtype, start, force * dir * solid_penetration_left);
@@ -287,7 +283,8 @@ void fireBullet(vector start, vector dir, float spread, float max_solid_penetrat
                        break;
 
                // move the entity along its velocity until it's out of solid, then let it resume
-               traceline_inverted (start, start + dir * maxdist, MOVE_NORMAL, WarpZone_trace_forent, TRUE);
+               // The previously hit entity is ignored here!
+               traceline_inverted (start, start + dir * maxdist, MOVE_NORMAL, WarpZone_trace_forent, TRUE, hit);
                if(trace_fraction == 1) // 1: we never got out of solid
                        break;