Xonotic
common.qc
Go to the documentation of this file.
1 #include "common.qh"
2 
3 #if defined(CSQC)
4  #include <client/items/items.qh>
5 #elif defined(MENUQC)
6 #elif defined(SVQC)
7  #include <common/weapons/_all.qh>
8 #endif
9 
11 {
12  acc.warpzone_transform = '0 0 0';
13  acc.warpzone_shift = '0 0 0';
14 }
16 {
17  vector tr, st;
18  tr = AnglesTransform_Multiply(t, acc.warpzone_transform);
19  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 {
29  vector tt, ss;
30  tt = AnglesTransform_Invert(t);
31  ss = AnglesTransform_PrePostShift_GetPostShift(s, tt, '0 0 0');
33  // yes, this probably can be done simpler... but this way is "obvious" :)
34 }
36 {
37  WarpZone_Accumulator_AddInverseTransform(acc, wz.warpzone_transform, wz.warpzone_shift);
38 }
39 
42 {
43  vector vf, vr, vu;
44  if(this.warpzone_fadestart)
45  if(vdist(org - this.origin - 0.5 * (this.mins + this.maxs), >, this.warpzone_fadeend + 400))
46  return org;
47  // don't transform if zone faded out (plus 400qu safety margin for typical speeds and latencies)
48  // unneeded on client, on server this helps a lot
49  vf = v_forward;
50  vr = v_right;
51  vu = v_up;
52  org = WarpZone_TransformOrigin(this, org);
53  vf = WarpZone_TransformVelocity(this, vf);
54  vr = WarpZone_TransformVelocity(this, vr);
55  vu = WarpZone_TransformVelocity(this, vu);
57  traceline(this.warpzone_targetorigin, org, MOVE_NOMONSTERS, NULL);
58  else
60  v_forward = vf;
61  v_right = vr;
62  v_up = vu;
63  return org;
64 }
65 
66 void WarpZone_SetUp(entity e, vector my_org, vector my_ang, vector other_org, vector other_ang)
67 {
68  e.warpzone_transform = AnglesTransform_RightDivide(other_ang, AnglesTransform_TurnDirectionFR(my_ang));
69  e.warpzone_shift = AnglesTransform_PrePostShift_GetPostShift(my_org, e.warpzone_transform, other_org);
70  e.warpzone_origin = my_org;
71  e.warpzone_targetorigin = other_org;
72  e.warpzone_angles = my_ang;
73  e.warpzone_targetangles = other_ang;
74  vector forward, right, up;
75  FIXED_MAKE_VECTORS(my_ang, forward, right, up);
76  e.warpzone_forward = forward;
77  FIXED_MAKE_VECTORS(other_ang, forward, right, up);
78  e.warpzone_targetforward = forward;
80 }
81 
83 {
84  // a fixed camera view
85  if(this.warpzone_fadestart)
86  if(vdist(org - this.origin - 0.5 * (this.mins + this.maxs), >, this.warpzone_fadeend + 400))
87  return org;
88  // don't transform if zone faded out (plus 400qu safety margin for typical speeds and latencies)
89  // unneeded on client, on server this helps a lot
92  return this.warpzone_origin;
93 }
94 
95 void 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
96 {
97  e.warpzone_origin = my_org;
98  e.warpzone_angles = my_ang;
100 }
101 
102 .entity enemy;
103 
109 {
110  float s;
111  entity se;
112  float f;
113 
115 #ifdef CSQC
117  {
118  LOG_TRACE("hit a network ent, cannot continue WarpZoneLib_BoxTouchesBrush");
119  // we cannot continue, as a player blocks us...
120  // so, abort
121  return 0;
122  }
123 #endif
124  if (!trace_ent)
125  return 0;
127  return 1;
128 
129  se = trace_ent;
130  s = se.solid;
131  se.solid = SOLID_NOT;
133  se.solid = s;
134 
135  return f;
136 }
137 
139 {
140  float f, s;
141 
142  if(!e.modelindex || e.warpzone_isboxy)
143  return 1;
144 
145  s = e.solid;
146  e.solid = SOLID_BSP;
152  e.solid = s;
153 
154  return f;
155 }
156 
158 {
159  // if we are near any warpzone planes - MOVE AWAY (work around nearclip)
161  return NULL;
163  {
164  return it;
165  });
166  return NULL;
167 }
168 
170 {
172  return;
173  IL_EACH(g_warpzones, true,
174  {
175  it.solid = SOLID_BSP;
176  });
177 }
178 
180 {
182  return;
183  IL_EACH(g_warpzones, true,
184  {
185  it.solid = SOLID_TRIGGER;
186  });
187 }
188 
190 {
192  {
193  WarpZone_trace_transform = new_pure(warpzone_trace_transform);
194  }
196 }
198 {
200 }
201 
202 void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end, float nomonsters, entity forent, entity zone, WarpZone_trace_callback_t cb)
203 {
204  float nomonsters_adjusted;
205  float frac, sol, i;
206  float contentshack;
207  entity wz;
208  vector vf, vr, vu;
209 
210  WarpZone_trace_forent = forent;
215  {
216  if(nomonsters == MOVE_NOTHING)
217  {
218  trace_endpos = end;
219  trace_fraction = 1;
220  if(cb)
221  cb(org, trace_endpos, end);
222  return;
223  }
224  else
225  {
226  tracebox(org, mi, ma, end, nomonsters, WarpZone_trace_forent);
227  if(cb)
228  cb(org, trace_endpos, end);
229  return;
230  }
231  }
232 
233  vf = v_forward;
234  vr = v_right;
235  vu = v_up;
236 
237  switch(nomonsters)
238  {
239  case MOVE_WORLDONLY:
240  case MOVE_NOTHING:
241  nomonsters_adjusted = MOVE_NOMONSTERS;
242  break;
243  default:
244  nomonsters_adjusted = nomonsters;
245  break;
246  }
247  if((contentshack = (WarpZone_trace_forent.dphitcontentsmask && !(WarpZone_trace_forent.dphitcontentsmask & DPCONTENTS_SOLID))))
249 
250  // if starting in warpzone, first transform
251  wz = WarpZone_Find(org + mi, org + ma);
252  if(wz)
253  {
256  if(zone && wz != zone)
257  {
258  // we are in ANOTHER warpzone. This is bad. Make a zero length trace and return.
259  sol = 1;
260  trace_fraction = 0;
261  trace_endpos = org;
262  goto fail;
263  }
265  org = WarpZone_TransformOrigin(wz, org);
266  end = WarpZone_TransformOrigin(wz, end);
267  }
269  sol = -1;
270  frac = 0;
271  i = 16;
272  for (;;)
273  {
274  if(--i < 1)
275  {
276  LOG_TRACE("Too many warpzones in sequence, aborting trace.");
277  trace_ent = NULL;
278  break;
279  }
280  tracebox(org, mi, ma, end, nomonsters_adjusted, WarpZone_trace_forent);
281  if(cb)
282  cb(org, trace_endpos, end);
283  if(sol < 0)
284  sol = trace_startsolid;
285 
286  frac = trace_fraction = frac + (1 - frac) * trace_fraction;
287  if(trace_fraction >= 1)
288  break;
289  if(trace_ent.classname != "trigger_warpzone")
290  {
291  if((nomonsters == MOVE_NOTHING) || ((nomonsters == MOVE_WORLDONLY) && trace_ent) || (contentshack && (trace_dphitcontents & WarpZone_trace_forent.dphitcontentsmask) == DPCONTENTS_SOLID))
292  {
293  // continue the trace, ignoring this hit (we only care for warpzones)
294  org = trace_endpos + normalize(end - org);
295  continue;
296  // we cannot do an inverted trace here, as we do care for further warpzones inside that "solid" to be found
297  // otherwise, players could block entrances that way
298  }
299  break;
300  }
301  /*if(trace_ent == wz)
302  {
303  // FIXME can this check be removed? Do we really need it?
304  LOG_TRACE("I transformed into the same zone again, wtf, aborting the trace");
305  trace_ent = NULL;
306  break;
307  }*/
308  wz = trace_ent;
312  if(zone && wz != zone)
313  break;
315  // we hit a warpzone... so, let's perform the trace after the warp again
317  end = WarpZone_TransformOrigin(wz, end);
318 
319  // we got warped, so let's step back a bit
320  tracebox(org, mi, ma, org + normalize(org - end) * 32, nomonsters_adjusted, WarpZone_trace_forent);
321  org = trace_endpos;
322  }
324 LABEL(fail)
325  if(contentshack)
327  trace_startsolid = sol;
328  v_forward = vf;
329  v_right = vr;
330  v_up = vu;
331 }
332 
333 void WarpZone_TraceBox(vector org, vector mi, vector ma, vector end, float nomonsters, entity forent)
334 {
335  WarpZone_TraceBox_ThroughZone(org, mi, ma, end, nomonsters, forent, NULL, WarpZone_trace_callback_t_null);
336 }
337 
338 void WarpZone_TraceLine(vector org, vector end, float nomonsters, entity forent)
339 {
340  WarpZone_TraceBox(org, '0 0 0', '0 0 0', end, nomonsters, forent);
341 }
342 
344 {
345  float g, dt, i;
346  vector vf, vr, vu, v0, o0;
347  entity wz;
348 
349  o0 = e.origin;
350  v0 = e.velocity;
351  g = cvar("sv_gravity") * e.gravity;
352 
353  WarpZone_trace_forent = forent;
359  {
360  tracetoss(e, WarpZone_trace_forent);
361  if(cb)
362  cb(e.origin, trace_endpos, trace_endpos);
363  dt = vlen(e.origin - o0) / vlen(e.velocity);
365  e.velocity_z -= dt * g;
366  WarpZone_tracetoss_velocity = e.velocity;
367  e.velocity = v0;
368  return;
369  }
370 
371  vf = v_forward;
372  vr = v_right;
373  vu = v_up;
374 
375  // if starting in warpzone, first transform
376  wz = WarpZone_Find(e.origin + e.mins, e.origin + e.maxs);
377  if(wz)
378  {
381  if(zone && wz != zone)
382  {
383  // we are in ANOTHER warpzone. This is bad. Make a zero length trace and return.
384 
386  trace_endpos = o0;
387  goto fail;
388  }
390  vector org = WarpZone_TransformOrigin(wz, e.origin);
391  setorigin(e, org);
392  e.velocity = WarpZone_TransformVelocity(wz, e.velocity);
393  }
395  i = 16;
396  for (;;)
397  {
398  if(--i < 1)
399  {
400  LOG_TRACE("Too many warpzones in sequence, aborting trace.");
401  trace_ent = NULL;
402  break;
403  }
404  tracetoss(e, WarpZone_trace_forent);
405  if(cb)
406  cb(e.origin, trace_endpos, trace_endpos);
407  dt = vlen(trace_endpos - e.origin) / vlen(e.velocity);
409  e.origin = trace_endpos;
410  e.velocity_z -= dt * g;
411  if(trace_fraction >= 1)
412  break;
413  if(trace_ent.classname != "trigger_warpzone")
414  break;
415  if(trace_ent == wz)
416  {
417  // FIXME can this check be removed? Do we really need it?
418  LOG_TRACE("I transformed into the same zone again, wtf, aborting the trace");
419  trace_ent = NULL;
420  break;
421  }
422  wz = trace_ent;
426  if(zone && wz != zone)
427  break;
429  // we hit a warpzone... so, let's perform the trace after the warp again
430  e.origin = WarpZone_TransformOrigin(wz, e.origin);
431  e.velocity = WarpZone_TransformVelocity(wz, e.velocity);
432 
433  // we got warped, so let's step back a bit
434  e.velocity = -e.velocity;
435  tracetoss(e, WarpZone_trace_forent);
436  dt = vlen(trace_endpos - e.origin) / vlen(e.velocity);
438  e.origin = trace_endpos;
439  e.velocity = -e.velocity;
440  }
442 LABEL(fail)
443  WarpZone_tracetoss_velocity = e.velocity;
444  v_forward = vf;
445  v_right = vr;
446  v_up = vu;
447  // restore old entity data (caller just uses trace_endpos, WarpZone_tracetoss_velocity and the transform)
448  e.velocity = v0;
449  e.origin = o0;
450 }
451 
453 {
455 }
456 
460 {
462 }
463 
464 void WarpZone_TrailParticles(entity own, float eff, vector org, vector end)
465 {
469 }
470 
471 #ifdef CSQC
472 float WarpZone_TrailParticles_trace_callback_f;
473 float WarpZone_TrailParticles_trace_callback_flags;
474 void WarpZone_TrailParticles_WithMultiplier_trace_callback(vector from, vector endpos, vector to)
475 {
476  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);
477 }
478 
479 void WarpZone_TrailParticles_WithMultiplier(entity own, float eff, vector org, vector end, float f, int boxflags)
480 {
483  WarpZone_TrailParticles_trace_callback_f = f;
484  WarpZone_TrailParticles_trace_callback_flags = boxflags | PARTICLES_DRAWASTRAIL;
485  WarpZone_TraceBox_ThroughZone(org, '0 0 0', '0 0 0', end, MOVE_NOMONSTERS, NULL, NULL, WarpZone_TrailParticles_WithMultiplier_trace_callback);
486 }
487 #endif
488 
490 {
491  return (v - wz.warpzone_origin) * wz.warpzone_forward;
492 }
493 
495 {
496  return (v - wz.warpzone_targetorigin) * wz.warpzone_targetforward;
497 }
498 
500 {
501  return wz.warpzone_shift + AnglesTransform_Apply(wz.warpzone_transform, v);
502 }
503 
505 {
506  return AnglesTransform_Apply(wz.warpzone_transform, v);
507 }
508 
510 {
511  return AnglesTransform_ApplyToAngles(wz.warpzone_transform, v);
512 }
513 
515 {
516 #ifdef KEEP_ROLL
517  float roll;
518  roll = ang.z;
519  ang.z = 0;
520 #endif
521 
522  ang = AnglesTransform_ApplyToVAngles(wz.warpzone_transform, ang);
523 
524 #ifdef KEEP_ROLL
525  ang = AnglesTransform_Normalize(ang, true);
526  ang = AnglesTransform_CancelRoll(ang);
527  ang.z = roll;
528 #else
529  ang = AnglesTransform_Normalize(ang, false);
530 #endif
531 
532  return ang;
533 }
534 
536 {
537  return AnglesTransform_Apply(AnglesTransform_Invert(wz.warpzone_transform), v - wz.warpzone_shift);
538 }
539 
541 {
542  return AnglesTransform_Apply(AnglesTransform_Invert(wz.warpzone_transform), v);
543 }
544 
546 {
547  return AnglesTransform_ApplyToAngles(AnglesTransform_Invert(wz.warpzone_transform), v);
548 }
549 
551 {
552  float roll;
553 
554  roll = ang.z;
555  ang.z = 0;
556 
557  ang = AnglesTransform_ApplyToVAngles(AnglesTransform_Invert(wz.warpzone_transform), ang);
558  ang = AnglesTransform_Normalize(ang, true);
559  ang = AnglesTransform_CancelRoll(ang);
560 
561  ang.z = roll;
562  return ang;
563 }
564 
566 {
567  vector nearest;
568  nearest.x = bound(mi.x, org.x, ma.x);
569  nearest.y = bound(mi.y, org.y, ma.y);
570  nearest.z = bound(mi.z, org.z, ma.z);
571  return nearest;
572 }
573 
574 // blacklist of entities that WarpZone_FindRadius doesn't care about
576 {
577  if (is_pure(e)) return true;
578  string s = e.classname;
579 
580  switch(s)
581  {
582  case "weaponentity":
583  case "exteriorweaponentity":
584  case "sprite_waypoint":
585  case "spawnfunc":
586  case "weaponchild":
587  case "chatbubbleentity":
588  case "buff_model":
589  //case "net_linked": // actually some real entities are linked without classname, fail
590  case "":
591  return true;
592  }
593 
594  if (startsWith(s, "target_")) return true;
595 
596  if (startsWith(s, "info_")) return true;
597 
598  return false;
599 }
600 
605  vector org,
606  float rad,
608  vector org0,
610  vector transform,
611  vector shift,
612  bool needlineofsight)
613 {
614  if (rad <= 0) return;
615  entity wz = NULL;
616  FOREACH_ENTITY_RADIUS(org, rad, !WarpZoneLib_BadEntity(it), {
617  vector p = WarpZoneLib_NearestPointOnBox(it.origin + it.mins, it.origin + it.maxs, org0);
618  if (needlineofsight)
619  {
620  traceline(org, p, MOVE_NOMONSTERS, it);
621  if (trace_fraction < 1) continue;
622  }
623  if (!it.WarpZone_findradius_hit || vlen2(it.WarpZone_findradius_dist) > vlen2(org0 - p))
624  {
625  it.WarpZone_findradius_nearest = p;
626  it.WarpZone_findradius_dist = org0 - p;
627  it.WarpZone_findradius_findorigin = org;
628  it.WarpZone_findradius_findradius = rad;
629  if (it.classname == "warpzone_refsys")
630  {
631  // ignore, especially: do not overwrite the refsys parameters
632  }
633  else if (it.classname == "trigger_warpzone")
634  {
635  it.WarpZone_findradius_next = wz;
636  wz = it;
637  it.WarpZone_findradius_hit = 1;
638  it.enemy.WarpZone_findradius_dist = '0 0 0'; // we don't want to go through this zone ever again
639  it.enemy.WarpZone_findradius_hit = 1;
640  }
641  else
642  {
643  it.warpzone_transform = transform;
644  it.warpzone_shift = shift;
645  it.WarpZone_findradius_hit = 1;
646  }
647  }
648  });
649  for(entity e = wz; e; e = e.WarpZone_findradius_next)
650  {
651  if (WarpZoneLib_BadEntity(e)) continue;
652 
653  vector org0_new = WarpZone_TransformOrigin(e, org);
654  traceline(e.warpzone_targetorigin, org0_new, MOVE_NOMONSTERS, e);
655  vector org_new = trace_endpos;
656 
657  vector transform_new = AnglesTransform_Multiply(e.warpzone_transform, transform);
658  vector shift_new = AnglesTransform_Multiply_GetPostShift(e.warpzone_transform, e.warpzone_shift, transform, shift);
660  org_new,
661  bound(0, rad - vlen(org_new - org0_new), rad - 8),
662  org0_new,
663  transform_new, shift_new,
664  needlineofsight);
665  e.WarpZone_findradius_hit = 0;
666  e.enemy.WarpZone_findradius_hit = 0;
667  }
668 }
669 entity WarpZone_FindRadius(vector org, float rad, bool needlineofsight)
670 {
671  // FIXME: why can't we do this? (sometimes finds nothing, breaking explosions)
672  // if (!warpzone_warpzones_exist && !needlineofsight) return findradius(org, rad);
673  WarpZone_FindRadius_Recurse(org, rad, org, '0 0 0', '0 0 0', needlineofsight);
675  FOREACH_LIST(list, chain, true, it.WarpZone_findradius_hit = 0);
676  return list_first;
677 }
678 
681 {
682  // garbage collect unused reference systems
683  this.nextthink = time + 1;
684  if(this.owner.WarpZone_refsys != this)
685  delete(this);
686 }
688 {
689  if(me.WarpZone_refsys.owner != me)
690  {
691  me.WarpZone_refsys = new(warpzone_refsys);
692  me.WarpZone_refsys.owner = me;
693  setthink(me.WarpZone_refsys, WarpZone_RefSys_GC);
694  me.WarpZone_refsys.nextthink = time + 1;
695  WarpZone_Accumulator_Clear(me.WarpZone_refsys);
696  }
697 }
699 {
700  if(me.WarpZone_refsys)
701  {
702  delete(me.WarpZone_refsys);
703  me.WarpZone_refsys = NULL;
704  }
705 }
707 {
708  if(t != '0 0 0' || s != '0 0 0')
709  {
711  WarpZone_Accumulator_AddTransform(me.WarpZone_refsys, t, s);
712  }
713 }
715 {
716  WarpZone_RefSys_AddTransform(me, wz.warpzone_transform, wz.warpzone_shift);
717 }
719 {
720  if(t != '0 0 0' || s != '0 0 0')
721  {
723  WarpZone_Accumulator_AddInverseTransform(me.WarpZone_refsys, t, s);
724  }
725 }
727 {
728  WarpZone_RefSys_AddInverseTransform(me, wz.warpzone_transform, wz.warpzone_shift);
729 }
733 {
734  //vector t, s;
735  if(me.WarpZone_refsys_incremental_transform == ref.WarpZone_refsys.warpzone_transform)
736  if(me.WarpZone_refsys_incremental_shift == ref.WarpZone_refsys.warpzone_shift)
737  return;
738  WarpZone_Accumulator_AddInverseTransform(me.WarpZone_refsys, me.WarpZone_refsys_incremental_transform, me.WarpZone_refsys_incremental_shift);
739  WarpZone_Accumulator_Add(me.WarpZone_refsys, ref.WarpZone_refsys);
740  me.WarpZone_refsys_incremental_shift = ref.WarpZone_refsys.warpzone_shift;
741  me.WarpZone_refsys_incremental_transform = ref.WarpZone_refsys.warpzone_transform;
742 }
744 {
745  me.WarpZone_refsys_incremental_shift = ref.WarpZone_refsys.warpzone_shift;
746  me.WarpZone_refsys_incremental_transform = ref.WarpZone_refsys.warpzone_transform;
747 }
749 {
750  if(from.WarpZone_refsys)
751  org = WarpZone_UnTransformOrigin(from.WarpZone_refsys, org);
752  if(to.WarpZone_refsys)
753  org = WarpZone_TransformOrigin(to.WarpZone_refsys, org);
754  return org;
755 }
757 {
758  if(from.WarpZone_refsys)
759  vel = WarpZone_UnTransformVelocity(from.WarpZone_refsys, vel);
760  if(to.WarpZone_refsys)
761  vel = WarpZone_TransformVelocity(to.WarpZone_refsys, vel);
762  return vel;
763 }
765 {
766  if(from.WarpZone_refsys)
767  ang = WarpZone_UnTransformAngles(from.WarpZone_refsys, ang);
768  if(to.WarpZone_refsys)
769  ang = WarpZone_TransformAngles(to.WarpZone_refsys, ang);
770  return ang;
771 }
773 {
774  if(from.WarpZone_refsys)
775  ang = WarpZone_UnTransformVAngles(from.WarpZone_refsys, ang);
776  if(to.WarpZone_refsys)
777  ang = WarpZone_TransformVAngles(to.WarpZone_refsys, ang);
778  return ang;
779 }
781 {
782  if(from.WarpZone_refsys)
783  {
785  me.WarpZone_refsys.warpzone_shift = from.WarpZone_refsys.warpzone_shift;
786  me.WarpZone_refsys.warpzone_transform = from.WarpZone_refsys.warpzone_transform;
787  }
788  else
790 }
792 {
793  entity e = spawn();
794  WarpZone_RefSys_Copy(e, me);
795  return e;
796 }
797 
799 {
800  vector emin = toucher.absmin, emax = toucher.absmax;
801  if(STAT(Q3COMPAT))
802  {
803  // DP's tracebox enlarges absolute bounding boxes by a single quake unit
804  // we must undo that here to allow accurate touching
805  emin += '1 1 1';
806  emax -= '1 1 1';
807  }
808  return !WarpZoneLib_BoxTouchesBrush(emin, emax, this, toucher);
809 }
810 
811 
813 {
814  const float eps = 0.0625;
815  tracebox(e.origin, e.mins - '1 1 1' * eps, e.maxs + '1 1 1' * eps, e.origin + by, MOVE_WORLDONLY, e);
816  if (trace_startsolid)
817  return;
818  if (trace_fraction < 1)
819  {
820  // hit something
821  // adjust origin in the other direction...
822  setorigin(e, e.origin - by * (1 - trace_fraction));
823  }
824 }
825 
827 {
828  vector o = e.origin;
829  traceline(o, o, MOVE_WORLDONLY, e);
830  if (trace_startsolid)
831  return false;
832 
833  tracebox(o, e.mins, e.maxs, o, MOVE_WORLDONLY, e);
834  if (!trace_startsolid)
835  return true;
836 
837  vector m0 = e.mins;
838  vector m1 = e.maxs;
839  e.mins = '0 0 0';
840  e.maxs = '0 0 0';
841  WarpZoneLib_MoveOutOfSolid_Expand(e, eX * m0.x); e.mins_x = m0.x;
842  WarpZoneLib_MoveOutOfSolid_Expand(e, eX * m1.x); e.maxs_x = m1.x;
843  WarpZoneLib_MoveOutOfSolid_Expand(e, eY * m0.y); e.mins_y = m0.y;
844  WarpZoneLib_MoveOutOfSolid_Expand(e, eY * m1.y); e.maxs_y = m1.y;
845  WarpZoneLib_MoveOutOfSolid_Expand(e, eZ * m0.z); e.mins_z = m0.z;
846  WarpZoneLib_MoveOutOfSolid_Expand(e, eZ * m1.z); e.maxs_z = m1.z;
847  setorigin(e, e.origin);
848 
849  tracebox(e.origin, e.mins, e.maxs, e.origin, MOVE_WORLDONLY, e);
850  if (trace_startsolid)
851  {
852  setorigin(e, o);
853  return false;
854  }
855 
856  return true;
857 }
entity enemy
Definition: common.qc:102
const float SOLID_NOT
Definition: csprogsdefs.qc:244
#define IL_EACH(this, cond, body)
void WarpZone_Accumulator_Clear(entity acc)
Definition: common.qc:10
vector WarpZone_UnTransformVAngles(entity wz, vector ang)
Definition: common.qc:550
const vector eY
Definition: vector.qh:45
float warpzone_fadestart
Definition: common.qh:21
#define FOREACH_LIST(list, next, cond, body)
Definition: iter.qh:21
void WarpZone_RefSys_AddInverse(entity me, entity wz)
Definition: common.qc:726
vector WarpZoneLib_NearestPointOnBox(vector mi, vector ma, vector org)
Definition: common.qc:565
#define MOVE_NOTHING
Definition: common.qh:33
bool WarpZoneLib_MoveOutOfSolid(entity e)
Definition: common.qc:826
void WarpZone_TraceBox(vector org, vector mi, vector ma, vector end, float nomonsters, entity forent)
Definition: common.qc:333
float trace_networkentity
#define setcamera_transform(e, f)
bool WarpZoneLib_ExactTrigger_Touch(entity this, entity toucher)
Definition: common.qc:798
void WarpZone_RefSys_Copy(entity me, entity from)
Definition: common.qc:780
float trace_dphitcontents
entity() spawn
vector WarpZone_TransformOrigin(entity wz, vector v)
Definition: common.qc:499
var WarpZone_trace_callback_t WarpZone_trace_callback_t_null
Definition: common.qh:36
vector WarpZoneLib_BoxTouchesBrush_maxs
Definition: common.qc:105
float WarpZone_tracetoss_time
Definition: common.qh:41
void WarpZone_MakeAllOther()
Definition: common.qc:179
void WarpZone_Trace_InitTransform()
Definition: common.qc:189
vector maxs
Definition: csprogsdefs.qc:113
void WarpZone_Accumulator_AddInverseTransform(entity acc, vector t, vector s)
Definition: common.qc:27
entity WarpZone_refsys
Definition: common.qc:679
vector warpzone_origin
Definition: common.qh:14
vector AnglesTransform_CancelRoll(vector t)
entity to
Definition: self.qh:96
origin
Definition: ent_cs.qc:114
vector WarpZoneLib_BoxTouchesBrush_mins
Definition: common.qc:104
entity WarpZone_trace_lastzone
Definition: common.qh:39
void WarpZone_RefSys_AddIncrementally(entity me, entity ref)
Definition: common.qc:732
void WarpZone_RefSys_CheckCreate(entity me)
Definition: common.qc:687
float warpzone_warpzones_exist
Definition: common.qh:9
vector WarpZone_tracetoss_velocity
Definition: common.qh:40
entity chain
Definition: csprogsdefs.qc:123
vector WarpZone_RefSys_TransformVelocity(entity from, entity to, vector vel)
Definition: common.qc:756
vector AnglesTransform_Multiply_GetPostShift(vector t0, vector st0, vector t1, vector st1)
void WarpZone_Accumulator_Add(entity acc, entity wz)
Definition: common.qc:23
entity owner
Definition: main.qh:73
float autocvar_cl_warpzone_usetrace
Definition: common.qc:40
float WarpZone_PlaneDist(entity wz, vector v)
Definition: common.qc:489
vector AnglesTransform_RightDivide(vector to_transform, vector from_transform)
void WarpZone_RefSys_AddInverseTransform(entity me, vector t, vector s)
Definition: common.qc:718
#define BITSET_ASSIGN(a, b)
Definition: common.qh:104
entity trace_ent
Definition: csprogsdefs.qc:40
vector WarpZone_UnTransformOrigin(entity wz, vector v)
Definition: common.qc:535
void WarpZone_MakeAllSolid()
Definition: common.qc:169
void WarpZone_RefSys_BeginAddingIncrementally(entity me, entity ref)
Definition: common.qc:743
float warpzone_fadeend
Definition: common.qh:22
void WarpZone_TraceToss(entity e, entity forent)
Definition: common.qc:452
vector AnglesTransform_ApplyToVAngles(vector transform, vector v)
float WarpZone_TrailParticles_trace_callback_eff
Definition: common.qc:458
entity WarpZone_findradius_next
Definition: common.qc:602
vector WarpZone_RefSys_TransformOrigin(entity from, entity to, vector org)
Definition: common.qc:748
void WarpZone_Accumulator_AddInverse(entity acc, entity wz)
Definition: common.qc:35
vector AnglesTransform_TurnDirectionFR(vector transform)
entity WarpZone_trace_forent
Definition: common.qh:34
vector AnglesTransform_PrePostShift_GetPostShift(vector sf, vector t, vector st)
#define BITCLR_ASSIGN(a, b)
Definition: common.qh:101
const float MOVE_NOMONSTERS
Definition: csprogsdefs.qc:253
vector mins
Definition: csprogsdefs.qc:113
#define vlen2(v)
Definition: vector.qh:4
vector WarpZone_UnTransformAngles(entity wz, vector v)
Definition: common.qc:545
vector WarpZone_TransformAngles(entity wz, vector v)
Definition: common.qc:509
void WarpZone_SetUp(entity e, vector my_org, vector my_ang, vector other_org, vector other_ang)
Definition: common.qc:66
void WarpZone_Accumulator_AddTransform(entity acc, vector t, vector s)
Definition: common.qc:15
entity WarpZone_trace_firstzone
Definition: common.qh:38
vector WarpZone_TransformVAngles(entity wz, vector ang)
Definition: common.qc:514
vector v_up
Definition: csprogsdefs.qc:31
entity WarpZone_Find(vector mi, vector ma)
Definition: common.qc:157
void WarpZone_RefSys_Add(entity me, entity wz)
Definition: common.qc:714
float WarpZoneLib_BoxTouchesBrush(vector mi, vector ma, entity e, entity ig)
Definition: common.qc:138
entity WarpZone_RefSys_SpawnSameRefSys(entity me)
Definition: common.qc:791
vector AnglesTransform_Multiply(vector t1, vector t2)
#define NULL
Definition: post.qh:17
bool WarpZoneLib_BadEntity(entity e)
Definition: common.qc:575
#define startsWith(haystack, needle)
Definition: string.qh:217
vector WarpZone_RefSys_TransformVAngles(entity from, entity to, vector ang)
Definition: common.qc:772
float DPCONTENTS_SOLID
void WarpZone_RefSys_GC(entity this)
Definition: common.qc:680
float WarpZone_TargetPlaneDist(entity wz, vector v)
Definition: common.qc:494
vector trace_endpos
Definition: csprogsdefs.qc:37
vector AnglesTransform_ApplyToAngles(vector transform, vector v)
vector AnglesTransform_Normalize(vector t, float minimize_roll)
void WarpZone_RefSys_Clear(entity me)
Definition: common.qc:698
#define FIXED_MAKE_VECTORS
entity WarpZone_FindRadius(vector org, float rad, bool needlineofsight)
Definition: common.qc:669
float nextthink
Definition: csprogsdefs.qc:121
void WarpZone_FindRadius_Recurse(vector org, float rad, vector org0, vector transform, vector shift, bool needlineofsight)
Definition: common.qc:603
void WarpZone_RefSys_AddTransform(entity me, vector t, vector s)
Definition: common.qc:706
vector warpzone_targetorigin
Definition: common.qh:17
entity WarpZoneLib_BoxTouchesBrush_ignore
Definition: common.qc:107
vector WarpZone_TransformVelocity(entity wz, vector v)
Definition: common.qc:504
vector(float skel, float bonenum) _skel_get_boneabs_hidden
entity WarpZone_trace_transform
Definition: common.qh:37
vector WarpZone_Camera_camera_transform(entity this, vector org, vector ang)
Definition: common.qc:82
#define is_pure(e)
Definition: oo.qh:10
void WarpZoneLib_MoveOutOfSolid_Expand(entity e, vector by)
Definition: common.qc:812
vector warpzone_angles
Definition: common.qh:15
vector v
Definition: ent_cs.qc:116
const float SOLID_BSP
Definition: csprogsdefs.qc:248
vector AnglesTransform_Invert(vector transform)
vector WarpZone_camera_transform(entity this, vector org, vector ang)
Definition: common.qc:41
void WarpZone_Camera_SetUp(entity e, vector my_org, vector my_ang)
Definition: common.qc:95
IntrusiveList g_warpzones
Definition: common.qh:6
const vector eX
Definition: vector.qh:44
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition: vector.qh:8
const vector eZ
Definition: vector.qh:46
#define LOG_TRACE(...)
Definition: log.qh:81
void WarpZone_TraceLine(vector org, vector end, float nomonsters, entity forent)
Definition: common.qc:338
float PARTICLES_DRAWASTRAIL
const float SOLID_TRIGGER
Definition: csprogsdefs.qc:245
vector v_right
Definition: csprogsdefs.qc:31
void WarpZone_TrailParticles(entity own, float eff, vector org, vector end)
Definition: common.qc:464
#define LABEL(id)
Definition: compiler.qh:36
#define new_pure(class)
purely logical entities (.origin doesn&#39;t work)
Definition: oo.qh:62
setorigin(ent, v)
#define setthink(e, f)
vector WarpZone_UnTransformVelocity(entity wz, vector v)
Definition: common.qc:540
float trace_startsolid
Definition: csprogsdefs.qc:35
float MOVE_WORLDONLY
void WarpZone_TraceToss_ThroughZone(entity e, entity forent, entity zone, WarpZone_trace_callback_t cb)
Definition: common.qc:343
vector AnglesTransform_Apply(vector transform, vector v)
void WarpZone_Trace_AddTransform(entity wz)
Definition: common.qc:197
float time
Definition: csprogsdefs.qc:16
entity WarpZoneLib_BoxTouchesBrush_ent
Definition: common.qc:106
float WarpZone_findradius_hit
Definition: common.qc:601
#define makevectors
Definition: post.qh:21
void WarpZone_TrailParticles_trace_callback(vector from, vector endpos, vector to)
Definition: common.qc:459
float trace_fraction
Definition: csprogsdefs.qc:36
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:202
vector WarpZone_RefSys_TransformAngles(entity from, entity to, vector ang)
Definition: common.qc:764
void(vector start, vector hit, vector end) WarpZone_trace_callback_t
Definition: common.qh:35
vector WarpZone_refsys_incremental_transform
Definition: common.qc:731
vector v_forward
Definition: csprogsdefs.qc:31
vector WarpZone_refsys_incremental_shift
Definition: common.qc:730
entity WarpZone_TrailParticles_trace_callback_own
Definition: common.qc:457
float WarpZoneLib_BoxTouchesBrush_Recurse()
Definition: common.qc:108