1 void WarpZone_SetUp(entity e, vector my_org, vector my_ang, vector other_org, vector other_ang)
3 e.warpzone_transform = AnglesTransform_Divide(other_ang, AnglesTransform_TurnDirectionFR(my_ang));
4 e.warpzone_origin = my_org;
5 e.warpzone_targetorigin = other_org;
6 e.warpzone_angles = my_ang;
7 e.warpzone_targetangles = other_ang;
8 fixedmakevectors(my_ang); e.warpzone_forward = v_forward;
9 fixedmakevectors(other_ang); e.warpzone_targetforward = v_forward;
14 vector WarpZoneLib_BoxTouchesBrush_mins;
15 vector WarpZoneLib_BoxTouchesBrush_maxs;
16 entity WarpZoneLib_BoxTouchesBrush_ent;
17 entity WarpZoneLib_BoxTouchesBrush_ignore;
18 float WarpZoneLib_BoxTouchesBrush_Recurse()
24 tracebox('0 0 0', WarpZoneLib_BoxTouchesBrush_mins, WarpZoneLib_BoxTouchesBrush_maxs, '0 0 0', MOVE_NOMONSTERS, WarpZoneLib_BoxTouchesBrush_ignore);
26 if (trace_networkentity)
28 dprint("hit a network ent, cannot continue WarpZoneLib_BoxTouchesBrush\n");
29 // we cannot continue, as a player blocks us...
36 if (trace_ent == WarpZoneLib_BoxTouchesBrush_ent)
44 f = WarpZoneLib_BoxTouchesBrush_Recurse();
50 float WarpZoneLib_BoxTouchesBrush(vector mi, vector ma, entity e, entity ig)
59 WarpZoneLib_BoxTouchesBrush_mins = mi;
60 WarpZoneLib_BoxTouchesBrush_maxs = ma;
61 WarpZoneLib_BoxTouchesBrush_ent = e;
62 WarpZoneLib_BoxTouchesBrush_ignore = ig;
63 f = WarpZoneLib_BoxTouchesBrush_Recurse();
69 entity WarpZone_Find(vector mi, vector ma)
71 // if we are near any warpzone planes - MOVE AWAY (work around nearclip)
73 for(e = world; (e = find(e, classname, "trigger_warpzone")); )
74 if(WarpZoneLib_BoxTouchesBrush(mi, ma, e, world))
79 void WarpZone_MakeAllSolid()
82 for(e = world; (e = find(e, classname, "trigger_warpzone")); )
86 void WarpZone_MakeAllOther()
89 for(e = world; (e = find(e, classname, "trigger_warpzone")); )
90 e.solid = SOLID_TRIGGER;
93 void WarpZone_TraceBox(vector org, vector mi, vector ma, vector end, float nomonsters, entity forent)
102 WarpZone_MakeAllSolid();
110 tracebox(org, mi, ma, end, nomonsters, forent);
111 if(WarpZone_trace_callback)
112 WarpZone_trace_callback();
114 sol = trace_startsolid;
115 if(trace_fraction >= 1)
117 frac = trace_fraction = frac + (1 - frac) * trace_fraction;
118 if(trace_ent.classname != "trigger_warpzone")
120 // we hit a warpzone... so, let's perform the trace after the warp again
121 org = WarpZone_TransformOrigin(trace_ent, trace_endpos);
122 end = WarpZone_TransformOrigin(trace_ent, end);
123 WarpZone_trace_velocity = WarpZone_TransformVelocity(trace_ent, WarpZone_trace_velocity);
124 WarpZone_trace_angles = WarpZone_TransformAngles(trace_ent, WarpZone_trace_angles);
125 WarpZone_trace_v_angle = WarpZone_TransformVAngles(trace_ent, WarpZone_trace_v_angle);
128 dprint("I transformed into the same zone again, wtf, aborting the trace\n");
133 WarpZone_MakeAllOther();
134 trace_startsolid = sol;
135 WarpZone_trace_endpos = o0 + (e0 - o0) * trace_fraction;
141 void WarpZone_TraceLine(vector org, vector end, float nomonsters, entity forent)
143 WarpZone_TraceBox(org, '0 0 0', '0 0 0', end, nomonsters, forent);
146 void WarpZone_TraceToss(entity e, entity forent)
149 vector vf, vr, vu, v0, o0;
153 WarpZone_MakeAllSolid();
154 g = cvar("sv_gravity") * e.gravity;
155 WarpZone_tracetoss_time = 0;
160 tracetoss(e, forent);
161 if(WarpZone_trace_callback)
162 WarpZone_trace_callback();
163 e.origin = trace_endpos;
164 dt = vlen(e.origin - o0) / vlen(e.velocity);
165 WarpZone_tracetoss_time += dt;
166 e.velocity_z -= WarpZone_tracetoss_time * g;
167 if(trace_fraction >= 1)
169 if(trace_ent.classname != "trigger_warpzone")
171 // we hit a warpzone... so, let's perform the trace after the warp again
172 e.origin = WarpZone_TransformOrigin(trace_ent, e.origin);
173 e.velocity = WarpZone_TransformVelocity(trace_ent, e.velocity);
175 WarpZone_MakeAllOther();
179 WarpZone_tracetoss_velocity = e.velocity;
182 WarpZone_trace_endpos = e.origin + e.velocity * WarpZone_tracetoss_time;
183 WarpZone_trace_endpos_z -= 0.5 * g * WarpZone_tracetoss_time * WarpZone_tracetoss_time;
186 void WarpZone_TrailParticles(entity own, float eff, vector org, vector end)
193 WarpZone_MakeAllSolid();
197 traceline(org, end, MOVE_NOMONSTERS, world);
198 //print(vtos(org), " to ", vtos(trace_endpos), "\n");
199 trailparticles(own, eff, org, trace_endpos);
200 if(trace_fraction >= 1)
202 if(trace_ent.classname != "trigger_warpzone")
204 // we hit a warpzone... so, let's perform the trace after the warp again
205 org = WarpZone_TransformOrigin(trace_ent, trace_endpos);
206 end = WarpZone_TransformOrigin(trace_ent, end);
208 WarpZone_MakeAllOther();
214 float WarpZone_PlaneDist(entity wz, vector v)
216 return (v - wz.warpzone_origin) * wz.warpzone_forward;
219 float WarpZone_TargetPlaneDist(entity wz, vector v)
221 return (v - wz.warpzone_targetorigin) * wz.warpzone_targetforward;
224 vector WarpZone_TransformOrigin(entity wz, vector v)
226 return wz.warpzone_targetorigin + AnglesTransform_Apply(wz.warpzone_transform, v - wz.warpzone_origin);
229 vector WarpZone_TransformVelocity(entity wz, vector v)
231 return AnglesTransform_Apply(wz.warpzone_transform, v);
234 vector WarpZone_TransformAngles(entity wz, vector v)
236 return AnglesTransform_ApplyToAngles(wz.warpzone_transform, v);
239 vector WarpZone_TransformVAngles(entity wz, vector ang)
246 ang = AnglesTransform_ApplyToVAngles(wz.warpzone_transform, ang);
247 ang = AnglesTransform_Normalize(ang, TRUE);
248 ang = AnglesTransform_CancelRoll(ang);
254 vector WarpZone_UnTransformOrigin(entity wz, vector v)
256 return wz.warpzone_origin + AnglesTransform_Apply(AnglesTransform_Invert(wz.warpzone_transform), v - wz.warpzone_targetorigin);
259 vector WarpZone_UnTransformVelocity(entity wz, vector v)
261 return AnglesTransform_Apply(AnglesTransform_Invert(wz.warpzone_transform), v);
264 vector WarpZone_UnTransformAngles(entity wz, vector v)
266 return AnglesTransform_ApplyToAngles(AnglesTransform_Invert(wz.warpzone_transform), v);
269 vector WarpZone_UnTransformVAngles(entity wz, vector ang)
276 ang = AnglesTransform_ApplyToVAngles(AnglesTransform_Invert(wz.warpzone_transform), ang);
277 ang = AnglesTransform_Normalize(ang, TRUE);
278 ang = AnglesTransform_CancelRoll(ang);
284 vector WarpZoneLib_NearestPointOnBox(vector mi, vector ma, vector org)
287 nearest_x = bound(mi_x, org_x, ma_x);
288 nearest_y = bound(mi_y, org_y, ma_y);
289 nearest_z = bound(mi_z, org_z, ma_z);
293 .float WarpZone_findradius_hit;
294 .entity WarpZone_findradius_next;
295 void WarpZone_FindRadius_Recurse(vector org, float rad, vector org0, vector shift0, vector transform, vector shift1, float needlineofsight)
296 // blast origin of current search original blast origin how to untransform (victim to blast system)
300 vector shift0_new, transform_new, shift1_new;
306 e0 = findradius(org, rad);
309 for(e = e0; e; e = e.chain)
311 p = WarpZoneLib_NearestPointOnBox(e.origin + e.mins, e.origin + e.maxs, org0);
314 traceline(org, p, MOVE_NOMONSTERS, e);
315 if(trace_fraction < 1)
318 if(!e.WarpZone_findradius_hit || vlen(e.WarpZone_findradius_dist) > vlen(org0 - p))
320 e.WarpZone_findradius_nearest = p;
321 e.WarpZone_findradius_dist = org0 - p;
322 e.WarpZone_findradius_findorigin = org;
323 e.WarpZone_findradius_findradius = rad;
324 if(e.classname == "trigger_warpzone")
326 e.WarpZone_findradius_next = wz;
329 e.WarpZone_findradius_hit = 1;
330 e.enemy.WarpZone_findradius_dist = '0 0 0'; // we don't want to go through this zone ever again
331 e.enemy.WarpZone_findradius_hit = 1;
335 e.warpzone_transform = transform;
336 e.warpzone_origin = shift0;
337 e.warpzone_targetorigin = shift1;
339 e.WarpZone_findradius_hit = 1;
343 for(e = wz; e; e = e.WarpZone_findradius_next)
345 org0_new = WarpZone_TransformOrigin(e, org);
346 traceline(e.warpzone_targetorigin, org0_new, MOVE_NOMONSTERS, e);
347 org_new = trace_endpos;
348 transform_new = AnglesTransform_Multiply(transform, AnglesTransform_Invert(e.warpzone_transform));
349 shift0_new = e.warpzone_targetorigin;
350 shift1_new = AnglesTransform_Apply(transform, e.warpzone_origin - shift0) + shift1;
351 WarpZone_FindRadius_Recurse(
353 bound(0, rad - vlen(org_new - org0_new), rad - 8),
355 shift0_new, transform_new, shift1_new,
357 e.WarpZone_findradius_hit = 0;
358 e.enemy.WarpZone_findradius_hit = 0;
361 entity WarpZone_FindRadius(vector org, float rad, float needlineofsight)
364 WarpZone_FindRadius_Recurse(org, rad, org, '0 0 0', '0 0 0', '0 0 0', needlineofsight);
365 e0 = findchainfloat(WarpZone_findradius_hit, 1);
366 for(e = e0; e; e = e.chain)
367 e.WarpZone_findradius_hit = 0;