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;
for(;;)
{
- if((pos - v1) * dir >= (v2 - v1) * dir)
+ if(pos * dir >= v2 * dir)
{
// went too far
trace_fraction = 1;
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;
}
}
-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);
}
/*
}
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)
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;
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);
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;