From af249c0a681eec410f343cd2a18c8d4d569ecf2a Mon Sep 17 00:00:00 2001 From: div0 Date: Sun, 28 Feb 2010 19:44:16 +0000 Subject: [PATCH] fix multi-zone impacts git-svn-id: svn://svn.icculus.org/nexuiz/trunk@8710 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/qcsrc/warpzonelib/common.qc | 60 ++++++++++++++++++++++++++++++-- data/qcsrc/warpzonelib/common.qh | 1 + data/qcsrc/warpzonelib/server.qc | 3 +- 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/data/qcsrc/warpzonelib/common.qc b/data/qcsrc/warpzonelib/common.qc index 89599ea8f..f71041b5d 100644 --- a/data/qcsrc/warpzonelib/common.qc +++ b/data/qcsrc/warpzonelib/common.qc @@ -138,6 +138,56 @@ void WarpZone_TraceBox(vector org, vector mi, vector ma, vector end, float nomon v_up = vu; } +void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end, float nomonsters, entity forent, entity zone) +{ + float frac, sol; + vector o0, e0; + entity e; + vector vf, vr, vu; + vf = v_forward; + vr = v_right; + vu = v_up; + WarpZone_MakeAllSolid(); + o0 = org; + e0 = end; + sol = -1; + frac = 0; + e = world; + for(;;) + { + tracebox(org, mi, ma, end, nomonsters, forent); + if(WarpZone_trace_callback) + WarpZone_trace_callback(); + if(sol < 0) + sol = trace_startsolid; + if(trace_fraction >= 1) + break; + frac = trace_fraction = frac + (1 - frac) * trace_fraction; + if(trace_ent.classname != "trigger_warpzone") + break; + if(trace_ent != zone) + break; + // we hit a warpzone... so, let's perform the trace after the warp again + org = WarpZone_TransformOrigin(trace_ent, trace_endpos); + end = WarpZone_TransformOrigin(trace_ent, end); + WarpZone_trace_velocity = WarpZone_TransformVelocity(trace_ent, WarpZone_trace_velocity); + WarpZone_trace_angles = WarpZone_TransformAngles(trace_ent, WarpZone_trace_angles); + WarpZone_trace_v_angle = WarpZone_TransformVAngles(trace_ent, WarpZone_trace_v_angle); + if(trace_ent == e) + { + dprint("I transformed into the same zone again, wtf, aborting the trace\n"); + break; + } + e = trace_ent; + } + WarpZone_MakeAllOther(); + trace_startsolid = sol; + WarpZone_trace_endpos = o0 + (e0 - o0) * trace_fraction; + v_forward = vf; + v_right = vr; + v_up = vu; +} + void WarpZone_TraceLine(vector org, vector end, float nomonsters, entity forent) { WarpZone_TraceBox(org, '0 0 0', '0 0 0', end, nomonsters, forent); @@ -185,13 +235,13 @@ void WarpZone_TraceToss(entity e, entity forent) void WarpZone_TrailParticles(entity own, float eff, vector org, vector end) { - float frac; vector vf, vr, vu; + entity e; vf = v_forward; vr = v_right; vu = v_up; WarpZone_MakeAllSolid(); - frac = 0; + e = world; for(;;) { traceline(org, end, MOVE_NOMONSTERS, world); @@ -204,6 +254,12 @@ void WarpZone_TrailParticles(entity own, float eff, vector org, vector end) // we hit a warpzone... so, let's perform the trace after the warp again org = WarpZone_TransformOrigin(trace_ent, trace_endpos); end = WarpZone_TransformOrigin(trace_ent, end); + if(trace_ent == e) + { + dprint("I transformed into the same zone again, wtf, aborting the trace\n"); + break; + } + e = trace_ent; } WarpZone_MakeAllOther(); v_forward = vf; diff --git a/data/qcsrc/warpzonelib/common.qh b/data/qcsrc/warpzonelib/common.qh index 622bab927..a637d6329 100644 --- a/data/qcsrc/warpzonelib/common.qh +++ b/data/qcsrc/warpzonelib/common.qh @@ -24,6 +24,7 @@ vector WarpZone_trace_endpos; // UNtransformed endpos vector WarpZone_tracetoss_velocity; // ending velocity of a tracetoss (post-transform) float WarpZone_tracetoss_time; // duration of toss (approximate) void WarpZone_TraceBox(vector org, vector min, vector max, vector end, float nomonsters, entity forent); +void WarpZone_TraceBox_ThroughZone(vector org, vector min, vector max, vector end, float nomonsters, entity forent, entity zone); void WarpZone_TraceLine(vector org, vector end, float nomonsters, entity forent); void WarpZone_TraceToss(entity e, entity forent); void WarpZone_TrailParticles(entity own, float eff, vector org, vector end); diff --git a/data/qcsrc/warpzonelib/server.qc b/data/qcsrc/warpzonelib/server.qc index 2bab197d8..d5b989260 100644 --- a/data/qcsrc/warpzonelib/server.qc +++ b/data/qcsrc/warpzonelib/server.qc @@ -238,14 +238,13 @@ float WarpZone_CheckProjectileImpact() v0 = self.velocity; a0 = self.angles; - // FIXME this code assumes the trace goes through just one warpzone. // this approach transports the projectile at its full speed, but does // not properly retain the projectile trail (but we can't retain it // easily anyway without delaying the projectile by two frames, so who // cares) WarpZone_trace_angles = self.angles; WarpZone_trace_velocity = self.velocity; - WarpZone_TraceBox(self.warpzone_oldorigin, self.mins, self.maxs, self.warpzone_oldorigin + self.warpzone_oldvelocity * frametime, MOVE_NORMAL, self); // this will get us through the warpzone + WarpZone_TraceBox_ThroughZone(self.warpzone_oldorigin, self.mins, self.maxs, self.warpzone_oldorigin + self.warpzone_oldvelocity * frametime, MOVE_NORMAL, self, wz); // this will get us through the warpzone setorigin(self, trace_endpos); self.angles = WarpZone_trace_angles; self.velocity = WarpZone_trace_velocity; -- 2.39.2