Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
common.qc
Go to the documentation of this file.
1#include "common.qh"
2
4
5#ifdef CSQC
6 #include <client/items/items.qh>
7#elifdef SVQC
9#endif
10
12{
13 acc.warpzone_transform = '0 0 0';
14 acc.warpzone_shift = '0 0 0';
15}
17{
18 vector tr = AnglesTransform_Multiply(t, acc.warpzone_transform);
19 vector st = AnglesTransform_Multiply_GetPostShift(t, s, acc.warpzone_transform, acc.warpzone_shift);
20 acc.warpzone_transform = tr;
21 acc.warpzone_shift = st;
22}
24{
25 WarpZone_Accumulator_AddTransform(acc, wz.warpzone_transform, wz.warpzone_shift);
26}
28{
32 // yes, this probably can be done simpler... but this way is "obvious" :)
33}
35{
36 WarpZone_Accumulator_AddInverseTransform(acc, wz.warpzone_transform, wz.warpzone_shift);
37}
38
40{
41 if (this.warpzone_fadestart)
42 if (vdist(org - this.origin - 0.5 * (this.mins + this.maxs), >, this.warpzone_fadeend + 400))
43 return org;
44 // don't transform if zone faded out (plus 400qu safety margin for typical speeds and latencies)
45 // unneeded on client, on server this helps a lot
46 vector vf = v_forward;
47 vector vr = v_right;
48 vector vu = v_up;
50 vf = WarpZone_TransformVelocity(this, vf);
51 vr = WarpZone_TransformVelocity(this, vr);
52 vu = WarpZone_TransformVelocity(this, vu);
54 v_forward = vf;
55 v_right = vr;
56 v_up = vu;
57 return org;
58}
59
60void WarpZone_SetUp(entity e, vector my_org, vector my_ang, vector other_org, vector other_ang)
61{
62 e.warpzone_transform = AnglesTransform_RightDivide(other_ang, AnglesTransform_TurnDirectionFR(my_ang));
63 e.warpzone_shift = AnglesTransform_PrePostShift_GetPostShift(my_org, e.warpzone_transform, other_org);
64 e.warpzone_origin = my_org;
65 e.warpzone_targetorigin = other_org;
66 e.warpzone_angles = my_ang;
67 e.warpzone_targetangles = other_ang;
68 vector forward, right, up;
69 FIXED_MAKE_VECTORS(my_ang, forward, right, up);
70 e.warpzone_forward = forward;
71 FIXED_MAKE_VECTORS(other_ang, forward, right, up);
72 e.warpzone_targetforward = forward;
74}
75
77{
78 // a fixed camera view
79 if (this.warpzone_fadestart)
80 if (vdist(org - this.origin - 0.5 * (this.mins + this.maxs), >, this.warpzone_fadeend + 400))
81 return org;
82 // don't transform if zone faded out (plus 400qu safety margin for typical speeds and latencies)
83 // unneeded on client, on server this helps a lot
86 return this.warpzone_origin;
87}
88
89void WarpZone_Camera_SetUp(entity e, vector my_org, vector my_ang) // we assume that e.oldorigin and e.avelocity point to view origin and direction
90{
91 e.warpzone_origin = my_org;
92 e.warpzone_angles = my_ang;
94}
95
96.entity enemy;
97
99{
100 tracebox('0 0 0', mi, ma, '0 0 0', MOVE_NOMONSTERS, ig);
101#ifdef CSQC
103 {
104 LOG_TRACE("hit a network ent, cannot continue WarpZoneLib_BoxTouchesBrush");
105 // we cannot continue, as a player blocks us...
106 // so, abort
107 return 0;
108 }
109#endif
110 if (!trace_ent)
111 return 0;
112 if (trace_ent == e)
113 return 1;
114
115 entity se = trace_ent;
116 float s = se.solid;
117 se.solid = SOLID_NOT;
118 setorigin(se, se.origin); // unlink
119 float f = WarpZoneLib_BoxTouchesBrush_Recurse(mi, ma, e, ig);
120 se.solid = s;
121 setorigin(se, se.origin); // relink
122
123 return f;
124}
125
127{
128 // bones_was_here: TODO: when findbox_OrFallback() is available, use it to
129 // optimise this into a single non-recursive function that only calls tracebox once
130
131 if (!e.modelindex || e.warpzone_isboxy)
132 return 1;
133
134 // work around trigger_hurt on geit3ctf1 not being detected by tracebox
135 // bones_was_here: FIXME: WHY do these triggers only have supercontents == 128 ?!
136 if (Q3COMPAT_COMMON && ig != world)
137 ig.dphitcontentsmask |= 128;
138
139 float s = e.solid;
140 if (e.solid != SOLID_BSP)
141 {
142 e.solid = SOLID_BSP;
143 setorigin(e, e.origin); // update linking
144 }
145 float f = WarpZoneLib_BoxTouchesBrush_Recurse(mi, ma, e, ig);
146 if (e.solid != s) // if we needed to change .solid temporarily
147 {
148 e.solid = s; // restore it
149 setorigin(e, e.origin); // update linking
150 }
151
152 if (Q3COMPAT_COMMON && ig != world)
153 ig.dphitcontentsmask &= ~128;
154
155 return f;
156}
157
159{
160 // if we are near any warpzone planes - MOVE AWAY (work around nearclip)
162 return NULL;
163 IL_EACH(g_warpzones, WarpZoneLib_BoxTouchesBrush(mi, ma, it, NULL), return it);
164 return NULL;
165}
166
168{
170 return;
171 IL_EACH(g_warpzones, true, it.solid = SOLID_BSP);
172}
173
175{
177 return;
178 IL_EACH(g_warpzones, true, it.solid = SOLID_TRIGGER);
179}
180
191
193{
194 float nomonsters_adjusted;
195 float frac, sol, i;
196 float contentshack;
197
198 WarpZone_trace_forent = forent;
203 {
204 if (nomonsters == MOVE_NOTHING)
205 {
206 trace_endpos = end;
207 trace_fraction = 1;
208 if (cb)
209 cb(org, trace_endpos, end);
210 return;
211 }
212 else
213 {
214 tracebox(org, mi, ma, end, nomonsters, WarpZone_trace_forent);
215 if (cb)
216 cb(org, trace_endpos, end);
217 return;
218 }
219 }
220
221 vector vf = v_forward;
222 vector vr = v_right;
223 vector vu = v_up;
224
225 switch (nomonsters)
226 {
227 case MOVE_WORLDONLY:
228 case MOVE_NOTHING:
229 nomonsters_adjusted = MOVE_NOMONSTERS;
230 break;
231 default:
232 nomonsters_adjusted = nomonsters;
233 break;
234 }
235 if ((contentshack = (WarpZone_trace_forent.dphitcontentsmask && !(WarpZone_trace_forent.dphitcontentsmask & DPCONTENTS_SOLID))))
237
238 // if starting in warpzone, first transform
239 entity wz = WarpZone_Find(org + mi, org + ma);
240 if (wz)
241 {
244 if (zone && wz != zone)
245 {
246 // we are in ANOTHER warpzone. This is bad. Make a zero length trace and return.
247 sol = 1;
248 trace_fraction = 0;
250 goto fail;
251 }
254 end = WarpZone_TransformOrigin(wz, end);
255 }
257 sol = -1;
258 frac = 0;
259 i = 16;
260 for (;;)
261 {
262 if (--i < 1)
263 {
264 LOG_TRACE("Too many warpzones in sequence, aborting trace.");
265 trace_ent = NULL;
266 break;
267 }
268 tracebox(org, mi, ma, end, nomonsters_adjusted, WarpZone_trace_forent);
269 if (cb)
270 cb(org, trace_endpos, end);
271 if (sol < 0)
272 sol = trace_startsolid;
273
274 frac = trace_fraction = frac + (1 - frac) * trace_fraction;
275 if (trace_fraction >= 1)
276 break;
277 if (trace_ent.classname != "trigger_warpzone")
278 {
279 if (nomonsters == MOVE_NOTHING
280 || (nomonsters == MOVE_WORLDONLY && trace_ent)
281 || (contentshack && (trace_dphitcontents & WarpZone_trace_forent.dphitcontentsmask) == DPCONTENTS_SOLID))
282 {
283 // continue the trace, ignoring this hit (we only care for warpzones)
284 org = trace_endpos + normalize(end - org);
285 continue;
286 // we cannot do an inverted trace here, as we do care for further warpzones inside that "solid" to be found
287 // otherwise, players could block entrances that way
288 }
289 break;
290 }
291 /*if (trace_ent == wz)
292 {
293 // FIXME can this check be removed? Do we really need it?
294 LOG_TRACE("I transformed into the same zone again, wtf, aborting the trace");
295 trace_ent = NULL;
296 break;
297 }*/
298 wz = trace_ent;
302 if (zone && wz != zone)
303 break;
305 // we hit a warpzone... so, let's perform the trace after the warp again
307 end = WarpZone_TransformOrigin(wz, end);
308
309 // we got warped, so let's step back a bit
310 tracebox(org, mi, ma, org + normalize(org - end) * 32, nomonsters_adjusted, WarpZone_trace_forent);
312 }
314LABEL(fail)
315 if (contentshack)
317 trace_startsolid = sol;
318 v_forward = vf;
319 v_right = vr;
320 v_up = vu;
321}
322
323void WarpZone_TraceBox(vector org, vector mi, vector ma, vector end, float nomonsters, entity forent)
324{
325 WarpZone_TraceBox_ThroughZone(org, mi, ma, end, nomonsters, forent, NULL, WarpZone_trace_callback_t_null);
326}
327
328void WarpZone_TraceLine(vector org, vector end, float nomonsters, entity forent)
329{
330 WarpZone_TraceBox(org, '0 0 0', '0 0 0', end, nomonsters, forent);
331}
332
334{
335 vector o0 = e.origin;
336 vector v0 = e.velocity;
337 float g = PHYS_GRAVITY(NULL) * e.gravity;
338 float dt, i;
339
340 WarpZone_trace_forent = forent;
346 {
347 tracetoss(e, WarpZone_trace_forent);
348 if (cb)
349 cb(e.origin, trace_endpos, trace_endpos);
350 dt = vlen(e.origin - o0) / vlen(e.velocity);
352 e.velocity_z -= dt * g;
353 WarpZone_tracetoss_velocity = e.velocity;
354 e.velocity = v0;
355 return;
356 }
357
358 vector vf = v_forward;
359 vector vr = v_right;
360 vector vu = v_up;
361
362 // if starting in warpzone, first transform
363 entity wz = WarpZone_Find(e.origin + e.mins, e.origin + e.maxs);
364 if (wz)
365 {
368 if (zone && wz != zone)
369 {
370 // we are in ANOTHER warpzone. This is bad. Make a zero length trace and return.
371
373 trace_endpos = o0;
374 goto fail;
375 }
377 vector org = WarpZone_TransformOrigin(wz, e.origin);
378 setorigin(e, org);
379 e.velocity = WarpZone_TransformVelocity(wz, e.velocity);
380 }
382 i = 16;
383 for (;;)
384 {
385 if (--i < 1)
386 {
387 LOG_TRACE("Too many warpzones in sequence, aborting trace.");
388 trace_ent = NULL;
389 break;
390 }
391 tracetoss(e, WarpZone_trace_forent);
392 if (cb)
393 cb(e.origin, trace_endpos, trace_endpos);
394 dt = vlen(trace_endpos - e.origin) / vlen(e.velocity);
396 e.origin = trace_endpos;
397 e.velocity_z -= dt * g;
398 if (trace_fraction >= 1)
399 break;
400 if (trace_ent.classname != "trigger_warpzone")
401 break;
402 if (trace_ent == wz)
403 {
404 // FIXME can this check be removed? Do we really need it?
405 LOG_TRACE("I transformed into the same zone again, wtf, aborting the trace");
406 trace_ent = NULL;
407 break;
408 }
409 wz = trace_ent;
413 if (zone && wz != zone)
414 break;
416 // we hit a warpzone... so, let's perform the trace after the warp again
417 e.origin = WarpZone_TransformOrigin(wz, e.origin);
418 e.velocity = WarpZone_TransformVelocity(wz, e.velocity);
419
420 // we got warped, so let's step back a bit
421 e.velocity = -e.velocity;
422 tracetoss(e, WarpZone_trace_forent);
423 dt = vlen(trace_endpos - e.origin) / vlen(e.velocity);
425 e.origin = trace_endpos;
426 e.velocity = -e.velocity;
427 }
429LABEL(fail)
430 WarpZone_tracetoss_velocity = e.velocity;
431 v_forward = vf;
432 v_right = vr;
433 v_up = vu;
434 // restore old entity data (caller just uses trace_endpos, WarpZone_tracetoss_velocity and the transform)
435 e.velocity = v0;
436 e.origin = o0;
437}
438
443
450
457
458#ifdef CSQC
465
474#endif
475
477{
478 return (v - wz.warpzone_origin) * wz.warpzone_forward;
479}
480
482{
483 return (v - wz.warpzone_targetorigin) * wz.warpzone_targetforward;
484}
485
487{
488 return wz.warpzone_shift + AnglesTransform_Apply(wz.warpzone_transform, v);
489}
490
492{
493 return AnglesTransform_Apply(wz.warpzone_transform, v);
494}
495
497{
498 return AnglesTransform_ApplyToAngles(wz.warpzone_transform, v);
499}
500
502{
503#ifdef KEEP_ROLL
504 float roll = ang.z;
505 ang.z = 0;
506#endif
507
508 ang = AnglesTransform_ApplyToVAngles(wz.warpzone_transform, ang);
509#ifdef KEEP_ROLL
512 ang.z = roll;
513#else
515#endif
516 return ang;
517}
518
520{
521 return AnglesTransform_Apply(AnglesTransform_Invert(wz.warpzone_transform), v - wz.warpzone_shift);
522}
523
525{
526 return AnglesTransform_Apply(AnglesTransform_Invert(wz.warpzone_transform), v);
527}
528
533
535{
536#ifdef KEEP_ROLL
537 float roll = ang.z;
538 ang.z = 0;
539#endif
540
542#ifdef KEEP_ROLL
545 ang.z = roll;
546#else
548#endif
549 return ang;
550}
551
552// blacklist of entities that WarpZone_FindRadius doesn't care about
554{
555 if (is_pure(e))
556 return true;
557 string s = e.classname;
558
559 switch (s)
560 {
561 case "weaponentity":
562 case "exteriorweaponentity":
563 case "sprite_waypoint":
564 case "waypoint":
565 case "spawnfunc":
566 case "weaponchild":
567 case "chatbubbleentity":
568 case "buff_model":
569 //case "net_linked": // actually some real entities are linked without classname, fail
570 case "":
571 return true;
572 }
573
574 if (startsWith(s, "target_"))
575 return true;
576 if (startsWith(s, "info_"))
577 return true;
578 return false;
579}
580
585 vector org,
586 float rad,
588 vector org0,
590 vector transform,
591 vector shift,
592 bool needlineofsight)
593{
594 if (rad <= 0)
595 return;
596 entity wz = NULL;
598 {
599 vector p = NearestPointOnBoundingBox(it.origin + it.mins, it.origin + it.maxs, org0);
600 if (needlineofsight)
601 {
602 traceline(org, p, MOVE_NOMONSTERS, it);
603 if (trace_fraction < 1)
604 continue;
605 }
606 if (!it.WarpZone_findradius_hit || vlen2(it.WarpZone_findradius_dist) > vlen2(org0 - p))
607 {
608 it.WarpZone_findradius_nearest = p;
609 it.WarpZone_findradius_dist = org0 - p;
610 it.WarpZone_findradius_findorigin = org;
611 it.WarpZone_findradius_findradius = rad;
612 if (it.classname == "warpzone_refsys")
613 ; // ignore, especially: do not overwrite the refsys parameters
614 else if (it.classname == "trigger_warpzone")
615 {
616 it.WarpZone_findradius_next = wz;
617 wz = it;
618 it.WarpZone_findradius_hit = 1;
619 it.enemy.WarpZone_findradius_dist = '0 0 0'; // we don't want to go through this zone ever again
620 it.enemy.WarpZone_findradius_hit = 1;
621 }
622 else
623 {
624 it.warpzone_transform = transform;
625 it.warpzone_shift = shift;
626 it.WarpZone_findradius_hit = 1;
627 }
628 }
629 });
630 for (entity e = wz; e; e = e.WarpZone_findradius_next)
631 {
633 continue;
634
635 vector org0_new = WarpZone_TransformOrigin(e, org);
636 traceline(e.warpzone_targetorigin, org0_new, MOVE_NOMONSTERS, e);
637 vector org_new = trace_endpos;
638
639 vector transform_new = AnglesTransform_Multiply(e.warpzone_transform, transform);
640 vector shift_new = AnglesTransform_Multiply_GetPostShift(e.warpzone_transform, e.warpzone_shift, transform, shift);
642 org_new,
643 bound(0, rad - vlen(org_new - org0_new), rad - 8),
644 org0_new,
645 transform_new, shift_new,
646 needlineofsight);
647 e.WarpZone_findradius_hit = 0;
648 e.enemy.WarpZone_findradius_hit = 0;
649 }
650}
651entity WarpZone_FindRadius(vector org, float rad, bool needlineofsight)
652{
653 bool simple_findradius = true;
654 // use simple findradius if no warpzone is touching the box of side 2 * rad and center org
655 // which includes the sphere of radius rad and center org
657 {
658 vector boxmin = vec3(org.x - rad, org.y - rad, org.z - rad);
659 vector boxmax = vec3(org.x + rad, org.y + rad, org.z + rad);
660 IL_EACH(g_warpzones, boxesoverlap(it.absmin, it.absmax, boxmin, boxmax),
661 {
662 simple_findradius = false;
663 break;
664 });
665 }
666
667 if (simple_findradius)
668 {
669 entity prev_good_ent = NULL;
670 entity list_first = findradius(org, rad);
671 FOREACH_LIST(list, chain, true,
672 {
673 // remove bad elements from this list while iterating
674 if (WarpZoneLib_BadEntity(it) || it.classname == "warpzone_refsys")
675 {
676 if (!prev_good_ent)
677 list_first = list_first.chain;
678 else
679 prev_good_ent.chain = it.chain;
680 continue;
681 }
682
683 vector p = NearestPointOnBoundingBox(it.origin + it.mins, it.origin + it.maxs, org);
684 if (needlineofsight)
685 {
686 traceline(org, p, MOVE_NOMONSTERS, it);
687 if (trace_fraction < 1)
688 {
689 if (!prev_good_ent)
690 list_first = list_first.chain;
691 else
692 prev_good_ent.chain = it.chain;
693 continue;
694 }
695 }
696
697 it.WarpZone_findradius_nearest = p;
698 it.WarpZone_findradius_dist = org - p;
699 WarpZone_Accumulator_Clear(it); // reset .warpzone_transform and .warpzone_shift
700
701 prev_good_ent = it;
702 });
703 return list_first;
704 }
705
706 WarpZone_FindRadius_Recurse(org, rad, org, '0 0 0', '0 0 0', needlineofsight);
708 FOREACH_LIST(list, chain, true, it.WarpZone_findradius_hit = 0);
709 return list_first;
710}
711
714{
715 // garbage collect unused reference systems
716 this.nextthink = time + 1;
717 if (this.owner.WarpZone_refsys != this)
718 delete(this);
719}
721{
722 if (me.WarpZone_refsys.owner != me)
723 {
724 me.WarpZone_refsys = new(warpzone_refsys);
725 me.WarpZone_refsys.owner = me;
726 setthink(me.WarpZone_refsys, WarpZone_RefSys_GC);
727 me.WarpZone_refsys.nextthink = time + 1;
728 WarpZone_Accumulator_Clear(me.WarpZone_refsys);
729 }
730}
732{
733 if (me.WarpZone_refsys)
734 {
735 delete(me.WarpZone_refsys);
736 me.WarpZone_refsys = NULL;
737 }
738}
740{
741 if (t != '0 0 0' || s != '0 0 0')
742 {
744 WarpZone_Accumulator_AddTransform(me.WarpZone_refsys, t, s);
745 }
746}
748{
749 WarpZone_RefSys_AddTransform(me, wz.warpzone_transform, wz.warpzone_shift);
750}
752{
753 if (t != '0 0 0' || s != '0 0 0')
754 {
756 WarpZone_Accumulator_AddInverseTransform(me.WarpZone_refsys, t, s);
757 }
758}
760{
761 WarpZone_RefSys_AddInverseTransform(me, wz.warpzone_transform, wz.warpzone_shift);
762}
766{
767 //vector t, s;
768 if (me.WarpZone_refsys_incremental_transform == ref.WarpZone_refsys.warpzone_transform)
769 if (me.WarpZone_refsys_incremental_shift == ref.WarpZone_refsys.warpzone_shift)
770 return;
771 WarpZone_Accumulator_AddInverseTransform(me.WarpZone_refsys, me.WarpZone_refsys_incremental_transform, me.WarpZone_refsys_incremental_shift);
772 WarpZone_Accumulator_Add(me.WarpZone_refsys, ref.WarpZone_refsys);
773 me.WarpZone_refsys_incremental_shift = ref.WarpZone_refsys.warpzone_shift;
774 me.WarpZone_refsys_incremental_transform = ref.WarpZone_refsys.warpzone_transform;
775}
777{
778 me.WarpZone_refsys_incremental_shift = ref.WarpZone_refsys.warpzone_shift;
779 me.WarpZone_refsys_incremental_transform = ref.WarpZone_refsys.warpzone_transform;
780}
782{
783 if (from.WarpZone_refsys)
784 org = WarpZone_UnTransformOrigin(from.WarpZone_refsys, org);
785 if (to.WarpZone_refsys)
786 org = WarpZone_TransformOrigin(to.WarpZone_refsys, org);
787 return org;
788}
790{
791 if (from.WarpZone_refsys)
792 vel = WarpZone_UnTransformVelocity(from.WarpZone_refsys, vel);
793 if (to.WarpZone_refsys)
794 vel = WarpZone_TransformVelocity(to.WarpZone_refsys, vel);
795 return vel;
796}
798{
799 if (from.WarpZone_refsys)
800 ang = WarpZone_UnTransformAngles(from.WarpZone_refsys, ang);
801 if (to.WarpZone_refsys)
802 ang = WarpZone_TransformAngles(to.WarpZone_refsys, ang);
803 return ang;
804}
806{
807 if (from.WarpZone_refsys)
808 ang = WarpZone_UnTransformVAngles(from.WarpZone_refsys, ang);
809 if (to.WarpZone_refsys)
810 ang = WarpZone_TransformVAngles(to.WarpZone_refsys, ang);
811 return ang;
812}
814{
815 if (from.WarpZone_refsys)
816 {
818 me.WarpZone_refsys.warpzone_shift = from.WarpZone_refsys.warpzone_shift;
819 me.WarpZone_refsys.warpzone_transform = from.WarpZone_refsys.warpzone_transform;
820 }
821 else
823}
825{
826 entity e = spawn();
828 return e;
829}
830
832{
833 vector emin = toucher.absmin, emax = toucher.absmax;
834 if (!Q3COMPAT_COMMON)
835 {
836 // Xonotic and Nexuiz maps assume triggers will be activated by adjacent players
837 // prior to sv_legacy_bbox_expand 0 DP always did this for SVQC and never for CSQC
838 emin -= '1 1 1';
839 emax += '1 1 1';
840 }
841
842 // if called from a touch func, we can assume the boxes do overlap
843 if (!touchfunc && !boxesoverlap(emin, emax, this.absmin, this.absmax)) // quick
844 return false;
845
846 return WarpZoneLib_BoxTouchesBrush(emin, emax, this, toucher); // accurate
847}
848
849
851{
852 const float eps = 0.0625;
853 tracebox(e.origin, e.mins - '1 1 1' * eps, e.maxs + '1 1 1' * eps, e.origin + by, MOVE_WORLDONLY, e);
855 return;
856 if (trace_fraction < 1)
857 {
858 // hit something
859 // adjust origin in the other direction...
860 setorigin(e, e.origin - by * (1 - trace_fraction));
861 }
862}
863
865{
866 vector o = e.origin;
867 traceline(o, o, MOVE_WORLDONLY, e);
869 return 0; // too stuck, giving up
870
871 tracebox(o, e.mins, e.maxs, o, MOVE_WORLDONLY, e);
872 if (!trace_startsolid)
873 return -1; // wasn't stuck
874
875 vector m0 = e.mins;
876 vector m1 = e.maxs;
877 e.mins = '0 0 0';
878 e.maxs = '0 0 0';
879 WarpZoneLib_MoveOutOfSolid_Expand(e, eX * m0.x); e.mins_x = m0.x;
880 WarpZoneLib_MoveOutOfSolid_Expand(e, eX * m1.x); e.maxs_x = m1.x;
881 WarpZoneLib_MoveOutOfSolid_Expand(e, eY * m0.y); e.mins_y = m0.y;
882 WarpZoneLib_MoveOutOfSolid_Expand(e, eY * m1.y); e.maxs_y = m1.y;
883 WarpZoneLib_MoveOutOfSolid_Expand(e, eZ * m0.z); e.mins_z = m0.z;
884 WarpZoneLib_MoveOutOfSolid_Expand(e, eZ * m1.z); e.maxs_z = m1.z;
885 setorigin(e, e.origin);
886
887 tracebox(e.origin, e.mins, e.maxs, e.origin, MOVE_WORLDONLY, e);
889 {
890 setorigin(e, o);
891 return 0; // can't fix
892 }
893
894 return 1; // was stuck but is fixed now
895}
vector AnglesTransform_ApplyToVAngles(vector transform, vector v)
vector AnglesTransform_Multiply_GetPostShift(vector t0, vector st0, vector t1, vector st1)
vector AnglesTransform_CancelRoll(vector t)
vector AnglesTransform_TurnDirectionFR(vector transform)
vector AnglesTransform_Apply(vector transform, vector v)
angles transforms angles in fixedmakevectors/fixedvectoangles space
vector AnglesTransform_Normalize(vector t, float minimize_roll)
vector AnglesTransform_Invert(vector transform)
vector AnglesTransform_RightDivide(vector to_transform, vector from_transform)
vector AnglesTransform_PrePostShift_GetPostShift(vector sf, vector t, vector st)
vector AnglesTransform_Multiply(vector t1, vector t2)
vector AnglesTransform_ApplyToAngles(vector transform, vector v)
#define FIXED_MAKE_VECTORS(angles, forward, right, up)
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
entity owner
Definition main.qh:87
#define Q3COMPAT_COMMON
Definition stats.qh:370
#define LABEL(id)
Definition compiler.qh:34
vector v_up
const float MOVE_NOMONSTERS
float trace_dphitcontents
entity trace_ent
const float SOLID_TRIGGER
float DPCONTENTS_SOLID
vector mins
entity chain
const float SOLID_NOT
float time
vector v_right
float trace_networkentity
vector trace_endpos
float trace_startsolid
vector maxs
float nextthink
float MOVE_WORLDONLY
vector absmax
vector v_forward
vector origin
float trace_fraction
vector absmin
const float SOLID_BSP
float PARTICLES_DRAWASTRAIL
#define spawn
#define IL_EACH(this, cond, body)
#define FOREACH_LIST(list, next, cond, body)
Definition iter.qh:21
#define FOREACH_ENTITY_RADIUS(org, dist, cond, body)
Definition iter.qh:160
void WarpZone_RefSys_AddInverseTransform(entity me, vector t, vector s)
Definition common.qc:751
vector WarpZone_UnTransformVelocity(entity wz, vector v)
Definition common.qc:524
void WarpZone_SetUp(entity e, vector my_org, vector my_ang, vector other_org, vector other_ang)
Definition common.qc:60
vector WarpZone_Camera_camera_transform(entity this, vector org, vector ang)
Definition common.qc:76
void WarpZone_RefSys_Add(entity me, entity wz)
Definition common.qc:747
entity WarpZone_findradius_next
Definition common.qc:582
void WarpZone_TraceToss_ThroughZone(entity e, entity forent, entity zone, WarpZone_trace_callback_t cb)
Definition common.qc:333
void WarpZone_RefSys_Clear(entity me)
Definition common.qc:731
vector WarpZone_RefSys_TransformVelocity(entity from, entity to, vector vel)
Definition common.qc:789
void WarpZone_TraceToss(entity e, entity forent)
Definition common.qc:439
void WarpZone_FindRadius_Recurse(vector org, float rad, vector org0, vector transform, vector shift, bool needlineofsight)
Definition common.qc:583
entity WarpZone_Find(vector mi, vector ma)
Definition common.qc:158
float WarpZoneLib_BoxTouchesBrush(vector mi, vector ma, entity e, entity ig)
Definition common.qc:126
vector WarpZone_UnTransformVAngles(entity wz, vector ang)
Definition common.qc:534
float WarpZoneLib_BoxTouchesBrush_Recurse(vector mi, vector ma, entity e, entity ig)
Definition common.qc:98
bool WarpZoneLib_ExactTrigger_Touch(entity this, entity toucher, bool touchfunc)
Definition common.qc:831
void WarpZone_Accumulator_Clear(entity acc)
Definition common.qc:11
float WarpZone_PlaneDist(entity wz, vector v)
Definition common.qc:476
void WarpZone_Trace_InitTransform()
Definition common.qc:181
void WarpZone_Camera_SetUp(entity e, vector my_org, vector my_ang)
Definition common.qc:89
void WarpZone_Accumulator_AddTransform(entity acc, vector t, vector s)
Definition common.qc:16
float WarpZone_findradius_hit
Definition common.qc:581
entity WarpZone_FindRadius(vector org, float rad, bool needlineofsight)
Definition common.qc:651
vector WarpZone_refsys_incremental_transform
Definition common.qc:764
void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end, float nomonsters, entity forent, entity zone, WarpZone_trace_callback_t cb)
Definition common.qc:192
void WarpZone_TraceLine(vector org, vector end, float nomonsters, entity forent)
Definition common.qc:328
vector WarpZone_TransformVAngles(entity wz, vector ang)
Definition common.qc:501
vector WarpZone_TransformVelocity(entity wz, vector v)
Definition common.qc:491
void WarpZone_RefSys_GC(entity this)
Definition common.qc:713
void WarpZone_TrailParticles_WithMultiplier(entity own, float eff, vector org, vector end, float f, int boxflags)
Definition common.qc:466
void WarpZone_RefSys_CheckCreate(entity me)
Definition common.qc:720
void WarpZone_RefSys_BeginAddingIncrementally(entity me, entity ref)
Definition common.qc:776
bool WarpZoneLib_BadEntity(entity e)
Definition common.qc:553
float WarpZone_TrailParticles_trace_callback_flags
Definition common.qc:460
vector WarpZone_TransformAngles(entity wz, vector v)
Definition common.qc:496
void WarpZone_TrailParticles(entity own, float eff, vector org, vector end)
Definition common.qc:451
void WarpZone_MakeAllOther()
Definition common.qc:174
vector WarpZone_UnTransformOrigin(entity wz, vector v)
Definition common.qc:519
entity WarpZone_TrailParticles_trace_callback_own
Definition common.qc:444
entity WarpZone_refsys
Definition common.qc:712
void WarpZone_RefSys_AddIncrementally(entity me, entity ref)
Definition common.qc:765
vector WarpZone_TransformOrigin(entity wz, vector v)
Definition common.qc:486
entity WarpZone_RefSys_SpawnSameRefSys(entity me)
Definition common.qc:824
vector WarpZone_refsys_incremental_shift
Definition common.qc:763
void WarpZone_RefSys_AddTransform(entity me, vector t, vector s)
Definition common.qc:739
void WarpZone_TraceBox(vector org, vector mi, vector ma, vector end, float nomonsters, entity forent)
Definition common.qc:323
float WarpZone_TargetPlaneDist(entity wz, vector v)
Definition common.qc:481
void WarpZone_MakeAllSolid()
Definition common.qc:167
vector WarpZone_camera_transform(entity this, vector org, vector ang)
Definition common.qc:39
void WarpZone_TrailParticles_WithMultiplier_trace_callback(vector from, vector endpos, vector to)
Definition common.qc:461
void WarpZone_Accumulator_AddInverse(entity acc, entity wz)
Definition common.qc:34
void WarpZone_RefSys_AddInverse(entity me, entity wz)
Definition common.qc:759
vector WarpZone_RefSys_TransformOrigin(entity from, entity to, vector org)
Definition common.qc:781
float WarpZone_TrailParticles_trace_callback_f
Definition common.qc:459
void WarpZone_RefSys_Copy(entity me, entity from)
Definition common.qc:813
vector WarpZone_UnTransformAngles(entity wz, vector v)
Definition common.qc:529
void WarpZone_Accumulator_AddInverseTransform(entity acc, vector t, vector s)
Definition common.qc:27
void WarpZone_TrailParticles_trace_callback(vector from, vector endpos, vector to)
Definition common.qc:446
void WarpZone_Trace_AddTransform(entity wz)
Definition common.qc:187
void WarpZoneLib_MoveOutOfSolid_Expand(entity e, vector by)
Definition common.qc:850
float WarpZone_TrailParticles_trace_callback_eff
Definition common.qc:445
vector WarpZone_RefSys_TransformVAngles(entity from, entity to, vector ang)
Definition common.qc:805
vector WarpZone_RefSys_TransformAngles(entity from, entity to, vector ang)
Definition common.qc:797
void WarpZone_Accumulator_Add(entity acc, entity wz)
Definition common.qc:23
int WarpZoneLib_MoveOutOfSolid(entity e)
Definition common.qc:864
var WarpZone_trace_callback_t WarpZone_trace_callback_t_null
Definition common.qh:38
entity WarpZone_trace_firstzone
Definition common.qh:40
#define BITSET_ASSIGN(a, b)
Definition common.qh:106
float warpzone_fadestart
Definition common.qh:24
vector warpzone_targetorigin
Definition common.qh:20
void(vector start, vector hit, vector end) WarpZone_trace_callback_t
Definition common.qh:37
float warpzone_fadeend
Definition common.qh:25
#define BITCLR_ASSIGN(a, b)
Definition common.qh:103
entity WarpZone_trace_lastzone
Definition common.qh:41
vector warpzone_origin
Definition common.qh:17
vector WarpZone_tracetoss_velocity
Definition common.qh:42
entity WarpZone_trace_transform
Definition common.qh:39
#define MOVE_NOTHING
Definition common.qh:35
IntrusiveList g_warpzones
Definition common.qh:6
float warpzone_warpzones_exist
Definition common.qh:12
vector warpzone_angles
Definition common.qh:18
float WarpZone_tracetoss_time
Definition common.qh:43
entity WarpZone_trace_forent
Definition common.qh:36
#define LOG_TRACE(...)
Definition log.qh:74
entity findchainfloat(.float field, float match)
float bound(float min, float value, float max)
float vlen(vector v)
vector normalize(vector v)
#define PHYS_GRAVITY(s)
Definition movetypes.qh:54
#define is_pure(e)
Definition oo.qh:16
#define new_pure(class)
purely logical entities (not linked to the area grid)
Definition oo.qh:66
#define NULL
Definition post.qh:14
#define world
Definition post.qh:15
#define makevectors
Definition post.qh:21
#define setthink(e, f)
#define setcamera_transform(e, f)
Definition self.qh:97
vector
Definition self.qh:96
vector org
Definition self.qh:96
entity entity toucher
Definition self.qh:76
vector vector ang
Definition self.qh:96
#define startsWith(haystack, needle)
Definition string.qh:234
entity enemy
Definition sv_ctf.qh:152
#define vlen2(v)
Definition vector.qh:4
const vector eY
Definition vector.qh:44
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt().
Definition vector.qh:8
const vector eZ
Definition vector.qh:45
ERASEABLE vector NearestPointOnBoundingBox(vector mi, vector ma, vector org)
Definition vector.qh:200
ERASEABLE float boxesoverlap(vector m1, vector m2, vector m3, vector m4)
Requires that m2>m1 in all coordinates, and that m4>m3.
Definition vector.qh:72
const vector eX
Definition vector.qh:43
#define vec3(_x, _y, _z)
Definition vector.qh:100