float trace_dphitcontents;
-.float dphitcontents;
+.float dphitcontentsmask;
void WarpZone_Accumulator_Clear(entity acc)
{
vector WarpZone_camera_transform(vector org, vector ang)
{
vector vf, vr, vu;
+ if(self.warpzone_fadestart)
+ if(vlen(org - self.origin - 0.5 * (self.mins + self.maxs)) > self.warpzone_fadeend + 400)
+ return org;
+ // don't transform if zone faded out (plus 400qu safety margin for typical speeds and latencies)
+ // unneeded on client, on server this helps a lot
vf = v_forward;
vr = v_right;
vu = v_up;
void WarpZone_SetUp(entity e, vector my_org, vector my_ang, vector other_org, vector other_ang)
{
- e.warpzone_transform = AnglesTransform_Divide(other_ang, AnglesTransform_TurnDirectionFR(my_ang));
+ e.warpzone_transform = AnglesTransform_RightDivide(other_ang, AnglesTransform_TurnDirectionFR(my_ang));
e.warpzone_shift = AnglesTransform_PrePostShift_GetPostShift(my_org, e.warpzone_transform, other_org);
e.warpzone_origin = my_org;
e.warpzone_targetorigin = other_org;
vector WarpZone_Camera_camera_transform(vector org, vector ang)
{
// a fixed camera view
+ if(self.warpzone_fadestart)
+ if(vlen(org - self.origin - 0.5 * (self.mins + self.maxs)) > self.warpzone_fadeend + 400)
+ return org;
+ // don't transform if zone faded out (plus 400qu safety margin for typical speeds and latencies)
+ // unneeded on client, on server this helps a lot
trace_endpos = self.warpzone_origin;
makevectors(self.warpzone_angles);
return self.warpzone_origin;
entity wz;
vector vf, vr, vu;
+ WarpZone_trace_firstzone = world;
+ WarpZone_trace_lastzone = world;
WarpZone_Trace_InitTransform();
if(!warpzone_warpzones_exist)
{
break;
}
if((contentshack = (forent.dphitcontentsmask && !(forent.dphitcontentsmask & DPCONTENTS_SOLID))))
- forent.dphitcontentsmask |= DPCONTENTS_SOLID;
+ BITSET_ASSIGN(forent.dphitcontentsmask, DPCONTENTS_SOLID);
// if starting in warpzone, first transform
wz = WarpZone_Find(org + mi, org + ma);
if(wz)
{
+ WarpZone_trace_firstzone = wz;
+ WarpZone_trace_lastzone = wz;
if(zone && wz != zone)
{
// we are in ANOTHER warpzone. This is bad. Make a zero length trace and return.
}
if(trace_ent == wz)
{
+ // FIXME can this check be removed? Do we really need it?
dprint("I transformed into the same zone again, wtf, aborting the trace\n");
trace_ent = world;
break;
}
wz = trace_ent;
+ if(!WarpZone_trace_firstzone)
+ WarpZone_trace_firstzone = wz;
+ WarpZone_trace_lastzone = wz;
if(zone && wz != zone)
break;
WarpZone_Trace_AddTransform(wz);
WarpZone_MakeAllOther();
:fail
if(contentshack)
- forent.dphitcontentsmask &~= DPCONTENTS_SOLID;
+ BITCLR_ASSIGN(forent.dphitcontentsmask, DPCONTENTS_SOLID);
trace_startsolid = sol;
v_forward = vf;
v_right = vr;
o0 = e.origin;
v0 = e.velocity;
+ WarpZone_trace_firstzone = world;
+ WarpZone_trace_lastzone = world;
WarpZone_Trace_InitTransform();
WarpZone_tracetoss_time = 0;
if(!warpzone_warpzones_exist)
wz = WarpZone_Find(e.origin + e.mins, e.origin + e.maxs);
if(wz)
{
+ WarpZone_trace_firstzone = wz;
+ WarpZone_trace_lastzone = wz;
if(zone && wz != zone)
{
// we are in ANOTHER warpzone. This is bad. Make a zero length trace and return.
break;
if(trace_ent == wz)
{
+ // FIXME can this check be removed? Do we really need it?
dprint("I transformed into the same zone again, wtf, aborting the trace\n");
trace_ent = world;
break;
}
wz = trace_ent;
+ if(!WarpZone_trace_firstzone)
+ WarpZone_trace_firstzone = wz;
+ WarpZone_trace_lastzone = wz;
if(zone && wz != zone)
break;
WarpZone_Trace_AddTransform(wz);
WarpZone_TraceBox_ThroughZone(org, '0 0 0', '0 0 0', end, MOVE_NOMONSTERS, world, world, WarpZone_TrailParticles_trace_callback);
}
+#ifdef CSQC
+float WarpZone_TrailParticles_trace_callback_f;
+float WarpZone_TrailParticles_trace_callback_flags;
+void WarpZone_TrailParticles_WithMultiplier_trace_callback(vector from, vector endpos, vector to)
+{
+ boxparticles(WarpZone_TrailParticles_trace_callback_eff, WarpZone_TrailParticles_trace_callback_own, from, endpos, WarpZone_TrailParticles_trace_callback_own.velocity, WarpZone_TrailParticles_trace_callback_own.velocity, WarpZone_TrailParticles_trace_callback_f, WarpZone_TrailParticles_trace_callback_flags);
+}
+
+void WarpZone_TrailParticles_WithMultiplier(entity own, float eff, vector org, vector end, float f, float boxflags)
+{
+ WarpZone_TrailParticles_trace_callback_own = own;
+ WarpZone_TrailParticles_trace_callback_eff = eff;
+ WarpZone_TrailParticles_trace_callback_f = f;
+ WarpZone_TrailParticles_trace_callback_flags = boxflags;
+ WarpZone_TraceBox_ThroughZone(org, '0 0 0', '0 0 0', end, MOVE_NOMONSTERS, world, world, WarpZone_TrailParticles_WithMultiplier_trace_callback);
+}
+#endif
+
float WarpZone_PlaneDist(entity wz, vector v)
{
return (v - wz.warpzone_origin) * wz.warpzone_forward;