From: Rudolf Polzer Date: Wed, 11 Dec 2013 10:12:07 +0000 (+0100) Subject: We DO need to detect double-hits, due to the weird engine tracing that X-Git-Tag: xonotic-v0.8.0~152^2~223^2 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=commitdiff_plain;h=d91906e1bb6225cd68269812a6d2b4314e23fcdb;hp=3fd748dcd694797c7b905c450c3ae180cedfc956 We DO need to detect double-hits, due to the weird engine tracing that happens sometimes at low angles. --- diff --git a/qcsrc/server/command/radarmap.qc b/qcsrc/server/command/radarmap.qc index 331f5f95f4..f2205b68d5 100644 --- a/qcsrc/server/command/radarmap.qc +++ b/qcsrc/server/command/radarmap.qc @@ -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; diff --git a/qcsrc/server/g_subs.qc b/qcsrc/server/g_subs.qc index 834bb47116..3d6d2cfc21 100644 --- a/qcsrc/server/g_subs.qc +++ b/qcsrc/server/g_subs.qc @@ -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); } /* diff --git a/qcsrc/server/w_common.qc b/qcsrc/server/w_common.qc index 86ae8866ce..f51db6dd5d 100644 --- a/qcsrc/server/w_common.qc +++ b/qcsrc/server/w_common.qc @@ -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;