X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fwarpzonelib%2Fcommon.qc;h=e76bc0eb96761c5efa52f02a07400b51fa28cdaa;hb=ee1b8d51f50d3f8c6948e81441ac03ae0f52781d;hp=af530814e0b23d84f559297f511b46136d652416;hpb=1216175333a1129260067a4f3ef26e9b43336ded;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/warpzonelib/common.qc b/qcsrc/warpzonelib/common.qc index af530814e..e76bc0eb9 100644 --- a/qcsrc/warpzonelib/common.qc +++ b/qcsrc/warpzonelib/common.qc @@ -1,3 +1,6 @@ +float trace_dphitcontents; +.float dphitcontentsmask; + void WarpZone_Accumulator_Clear(entity acc) { acc.warpzone_transform = '0 0 0'; @@ -25,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; @@ -58,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; @@ -110,7 +123,7 @@ float WarpZoneLib_BoxTouchesBrush(vector mi, vector ma, entity e, entity ig) { float f, s; - if not(e.modelindex) + if(!e.modelindex || e.warpzone_isboxy) return 1; s = e.solid; @@ -129,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; @@ -138,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; } @@ -145,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; } @@ -167,9 +186,31 @@ void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end, { float nomonsters_adjusted; float frac, sol, i; + float contentshack; vector o0, e0; entity wz; vector vf, vr, vu; + + WarpZone_Trace_InitTransform(); + if(!warpzone_warpzones_exist) + { + if(nomonsters == MOVE_NOTHING) + { + trace_endpos = end; + trace_fraction = 1; + if(cb) + cb(org, trace_endpos, end); + return; + } + else + { + tracebox(org, mi, ma, end, nomonsters, forent); + if(cb) + cb(org, trace_endpos, end); + return; + } + } + vf = v_forward; vr = v_right; vu = v_up; @@ -186,8 +227,9 @@ void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end, nomonsters_adjusted = nomonsters; break; } + if((contentshack = (forent.dphitcontentsmask && !(forent.dphitcontentsmask & DPCONTENTS_SOLID)))) + forent.dphitcontentsmask |= DPCONTENTS_SOLID; - WarpZone_Trace_InitTransform(); // if starting in warpzone, first transform wz = WarpZone_Find(org + mi, org + ma); if(wz) @@ -201,7 +243,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(); @@ -227,7 +269,7 @@ void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end, break; if(trace_ent.classname != "trigger_warpzone") { - if((nomonsters == MOVE_NOTHING) || ((nomonsters == MOVE_WORLDONLY) && trace_ent)) + if((nomonsters == MOVE_NOTHING) || ((nomonsters == MOVE_WORLDONLY) && trace_ent) || (contentshack && (trace_dphitcontents & forent.dphitcontentsmask) == DPCONTENTS_SOLID)) { // continue the trace, ignoring this hit (we only care for warpzones) org = trace_endpos + normalize(end - org); @@ -253,6 +295,8 @@ void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end, } WarpZone_MakeAllOther(); :fail + if(contentshack) + forent.dphitcontentsmask &~= DPCONTENTS_SOLID; trace_startsolid = sol; v_forward = vf; v_right = vr; @@ -275,13 +319,28 @@ void WarpZone_TraceToss_ThroughZone(entity e, entity forent, entity zone, WarpZo vector vf, vr, vu, v0, o0; entity wz; - vf = v_forward; - vr = v_right; - vu = v_up; o0 = e.origin; v0 = e.velocity; WarpZone_Trace_InitTransform(); + WarpZone_tracetoss_time = 0; + if(!warpzone_warpzones_exist) + { + tracetoss(e, forent); + if(cb) + 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; + // if starting in warpzone, first transform wz = WarpZone_Find(e.origin + e.mins, e.origin + e.maxs); if(wz) @@ -300,7 +359,6 @@ void WarpZone_TraceToss_ThroughZone(entity e, entity forent, entity zone, WarpZo } WarpZone_MakeAllSolid(); g = cvar("sv_gravity") * e.gravity; - WarpZone_tracetoss_time = 0; i = 16; for(;;) { @@ -314,9 +372,9 @@ void WarpZone_TraceToss_ThroughZone(entity e, entity forent, entity zone, WarpZo if(cb) cb(e.origin, trace_endpos, trace_endpos); e.origin = trace_endpos; - e.velocity_z -= WarpZone_tracetoss_time * g; dt = vlen(e.origin - o0) / vlen(e.velocity); WarpZone_tracetoss_time += dt; + e.velocity_z -= dt * g; if(trace_fraction >= 1) break; if(trace_ent.classname != "trigger_warpzone") @@ -365,6 +423,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;