X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fwarpzonelib%2Fcommon.qc;h=25a67a1731eaa9e3118dc69ae77674defbd28a35;hb=5e621953ca00e202f8c9a3ab0f35e6a6f7f9e695;hp=360652d6f24eafa9b4d2b708f8dcf1543e47cf67;hpb=febfec579435117da1469a14456badb58ce2e177;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/warpzonelib/common.qc b/qcsrc/warpzonelib/common.qc index 360652d6f..25a67a173 100644 --- a/qcsrc/warpzonelib/common.qc +++ b/qcsrc/warpzonelib/common.qc @@ -1,5 +1,5 @@ float trace_dphitcontents; -.float dphitcontents; +.float dphitcontentsmask; void WarpZone_Accumulator_Clear(entity acc) { @@ -28,6 +28,11 @@ var float autocvar_cl_warpzone_usetrace = 1; 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; @@ -47,7 +52,7 @@ vector WarpZone_camera_transform(vector org, vector ang) 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; @@ -61,6 +66,11 @@ void WarpZone_SetUp(entity e, vector my_org, vector my_ang, vector other_org, ve 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; @@ -132,6 +142,8 @@ entity WarpZone_Find(vector mi, vector ma) { // if we are near any warpzone planes - MOVE AWAY (work around nearclip) entity e; + if(!warpzone_warpzones_exist) + return world; for(e = world; (e = find(e, classname, "trigger_warpzone")); ) if(WarpZoneLib_BoxTouchesBrush(mi, ma, e, world)) return e; @@ -141,6 +153,8 @@ entity WarpZone_Find(vector mi, vector ma) void WarpZone_MakeAllSolid() { entity e; + if(!warpzone_warpzones_exist) + return; for(e = world; (e = find(e, classname, "trigger_warpzone")); ) e.solid = SOLID_BSP; } @@ -148,6 +162,8 @@ void WarpZone_MakeAllSolid() void WarpZone_MakeAllOther() { entity e; + if(!warpzone_warpzones_exist) + return; for(e = world; (e = find(e, classname, "trigger_warpzone")); ) e.solid = SOLID_TRIGGER; } @@ -175,6 +191,8 @@ void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end, entity wz; vector vf, vr, vu; + WarpZone_trace_firstzone = world; + WarpZone_trace_lastzone = world; WarpZone_Trace_InitTransform(); if(!warpzone_warpzones_exist) { @@ -212,12 +230,14 @@ void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end, 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. @@ -227,7 +247,7 @@ void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end, goto fail; } WarpZone_Trace_AddTransform(wz); - org = WarpZone_TransformOrigin(wz, trace_endpos); + org = WarpZone_TransformOrigin(wz, org); end = WarpZone_TransformOrigin(wz, end); } WarpZone_MakeAllSolid(); @@ -265,11 +285,15 @@ void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end, } 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); @@ -280,7 +304,7 @@ void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end, WarpZone_MakeAllOther(); :fail if(contentshack) - forent.dphitcontentsmask &~= DPCONTENTS_SOLID; + BITCLR_ASSIGN(forent.dphitcontentsmask, DPCONTENTS_SOLID); trace_startsolid = sol; v_forward = vf; v_right = vr; @@ -303,6 +327,11 @@ void WarpZone_TraceToss_ThroughZone(entity e, entity forent, entity zone, WarpZo vector vf, vr, vu, v0, o0; entity wz; + 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) @@ -312,19 +341,22 @@ void WarpZone_TraceToss_ThroughZone(entity e, entity forent, entity zone, WarpZo cb(e.origin, trace_endpos, trace_endpos); dt = vlen(e.origin - o0) / vlen(e.velocity); WarpZone_tracetoss_time += dt; + e.velocity_z -= dt * g; + WarpZone_tracetoss_velocity = e.velocity; + e.velocity = v0; return; } vf = v_forward; vr = v_right; vu = v_up; - o0 = e.origin; - v0 = e.velocity; // if starting in warpzone, first transform 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. @@ -354,18 +386,22 @@ void WarpZone_TraceToss_ThroughZone(entity e, entity forent, entity zone, WarpZo e.origin = trace_endpos; dt = vlen(e.origin - o0) / vlen(e.velocity); WarpZone_tracetoss_time += dt; - e.velocity_z -= WarpZone_tracetoss_time * g; + e.velocity_z -= dt * g; if(trace_fraction >= 1) break; if(trace_ent.classname != "trigger_warpzone") 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); @@ -403,6 +439,24 @@ void WarpZone_TrailParticles(entity own, float eff, vector org, vector end) 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; @@ -609,7 +663,7 @@ void WarpZone_RefSys_AddIncrementally(entity me, entity ref) t = AnglesTransform_Invert(me.WarpZone_refsys_incremental_transform); s = AnglesTransform_PrePostShift_GetPostShift(me.WarpZone_refsys_incremental_shift, t, '0 0 0'); WarpZone_Accumulator_AddTransform(me.WarpZone_refsys, t, s); - WarpZone_Accumulator_Add(me.WarpZone_refsys, ref); + WarpZone_Accumulator_Add(me.WarpZone_refsys, ref.WarpZone_refsys); me.WarpZone_refsys_incremental_shift = ref.WarpZone_refsys.warpzone_shift; me.WarpZone_refsys_incremental_transform = ref.WarpZone_refsys.warpzone_transform; }