Quake II RTX doxygen  1.0 dev
g_phys.c File Reference
#include "g_local.h"

Go to the source code of this file.

Classes

struct  pushed_t
 

Macros

#define STOP_EPSILON   0.1
 
#define MAX_CLIP_PLANES   5
 
#define sv_stopspeed   100
 
#define sv_friction   6
 
#define sv_waterfriction   1
 

Functions

edict_t * SV_TestEntityPosition (edict_t *ent)
 
void SV_CheckVelocity (edict_t *ent)
 
qboolean SV_RunThink (edict_t *ent)
 
void SV_Impact (edict_t *e1, trace_t *trace)
 
int ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce)
 
int SV_FlyMove (edict_t *ent, float time, int mask)
 
void SV_AddGravity (edict_t *ent)
 
trace_t SV_PushEntity (edict_t *ent, vec3_t push)
 
qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
 
void SV_Physics_Pusher (edict_t *ent)
 
void SV_Physics_None (edict_t *ent)
 
void SV_Physics_Noclip (edict_t *ent)
 
void SV_Physics_Toss (edict_t *ent)
 
void SV_AddRotationalFriction (edict_t *ent)
 
void SV_Physics_Step (edict_t *ent)
 
void G_RunEntity (edict_t *ent)
 

Variables

pushed_t pushed [MAX_EDICTS]
 
pushed_tpushed_p
 
edict_t * obstacle
 

Macro Definition Documentation

◆ MAX_CLIP_PLANES

#define MAX_CLIP_PLANES   5

Definition at line 178 of file g_phys.c.

◆ STOP_EPSILON

#define STOP_EPSILON   0.1

Definition at line 140 of file g_phys.c.

◆ sv_friction

#define sv_friction   6

Definition at line 771 of file g_phys.c.

◆ sv_stopspeed

#define sv_stopspeed   100

Definition at line 770 of file g_phys.c.

◆ sv_waterfriction

#define sv_waterfriction   1

Definition at line 772 of file g_phys.c.

Function Documentation

◆ ClipVelocity()

int ClipVelocity ( vec3_t  in,
vec3_t  normal,
vec3_t  out,
float  overbounce 
)

Definition at line 142 of file g_phys.c.

143 {
144  float backoff;
145  float change;
146  int i, blocked;
147 
148  blocked = 0;
149  if (normal[2] > 0)
150  blocked |= 1; // floor
151  if (!normal[2])
152  blocked |= 2; // step
153 
154  backoff = DotProduct(in, normal) * overbounce;
155 
156  for (i = 0 ; i < 3 ; i++) {
157  change = normal[i] * backoff;
158  out[i] = in[i] - change;
159  if (out[i] > -STOP_EPSILON && out[i] < STOP_EPSILON)
160  out[i] = 0;
161  }
162 
163  return blocked;
164 }

Referenced by SV_FlyMove(), and SV_Physics_Toss().

◆ G_RunEntity()

void G_RunEntity ( edict_t *  ent)

Definition at line 905 of file g_phys.c.

906 {
907  if (ent->prethink)
908  ent->prethink(ent);
909 
910  switch ((int)ent->movetype) {
911  case MOVETYPE_PUSH:
912  case MOVETYPE_STOP:
913  SV_Physics_Pusher(ent);
914  break;
915  case MOVETYPE_NONE:
916  SV_Physics_None(ent);
917  break;
918  case MOVETYPE_NOCLIP:
919  SV_Physics_Noclip(ent);
920  break;
921  case MOVETYPE_STEP:
922  SV_Physics_Step(ent);
923  break;
924  case MOVETYPE_TOSS:
925  case MOVETYPE_BOUNCE:
926  case MOVETYPE_FLY:
927  case MOVETYPE_FLYMISSILE:
928  SV_Physics_Toss(ent);
929  break;
930  default:
931  gi.error("SV_Physics: bad movetype %i", (int)ent->movetype);
932  }
933 }

Referenced by G_RunFrame().

◆ SV_AddGravity()

void SV_AddGravity ( edict_t *  ent)

Definition at line 309 of file g_phys.c.

310 {
311  ent->velocity[2] -= ent->gravity * sv_gravity->value * FRAMETIME;
312 }

Referenced by SV_Physics_Step(), and SV_Physics_Toss().

◆ SV_AddRotationalFriction()

void SV_AddRotationalFriction ( edict_t *  ent)

Definition at line 774 of file g_phys.c.

775 {
776  int n;
777  float adjustment;
778 
779  VectorMA(ent->s.angles, FRAMETIME, ent->avelocity, ent->s.angles);
780  adjustment = FRAMETIME * sv_stopspeed * sv_friction;
781  for (n = 0; n < 3; n++) {
782  if (ent->avelocity[n] > 0) {
783  ent->avelocity[n] -= adjustment;
784  if (ent->avelocity[n] < 0)
785  ent->avelocity[n] = 0;
786  } else {
787  ent->avelocity[n] += adjustment;
788  if (ent->avelocity[n] > 0)
789  ent->avelocity[n] = 0;
790  }
791  }
792 }

Referenced by SV_Physics_Step().

◆ SV_CheckVelocity()

void SV_CheckVelocity ( edict_t *  ent)

Definition at line 70 of file g_phys.c.

71 {
72  int i;
73 
74 //
75 // bound velocity
76 //
77  for (i = 0 ; i < 3 ; i++) {
78  if (ent->velocity[i] > sv_maxvelocity->value)
79  ent->velocity[i] = sv_maxvelocity->value;
80  else if (ent->velocity[i] < -sv_maxvelocity->value)
81  ent->velocity[i] = -sv_maxvelocity->value;
82  }
83 }

Referenced by SV_Physics_Step(), and SV_Physics_Toss().

◆ SV_FlyMove()

int SV_FlyMove ( edict_t *  ent,
float  time,
int  mask 
)

Definition at line 179 of file g_phys.c.

180 {
181  edict_t *hit;
182  int bumpcount, numbumps;
183  vec3_t dir;
184  float d;
185  int numplanes;
186  vec3_t planes[MAX_CLIP_PLANES];
187  vec3_t primal_velocity, original_velocity, new_velocity;
188  int i, j;
189  trace_t trace;
190  vec3_t end;
191  float time_left;
192  int blocked;
193 
194  numbumps = 4;
195 
196  blocked = 0;
197  VectorCopy(ent->velocity, original_velocity);
198  VectorCopy(ent->velocity, primal_velocity);
199  numplanes = 0;
200 
201  time_left = time;
202 
203  ent->groundentity = NULL;
204  for (bumpcount = 0 ; bumpcount < numbumps ; bumpcount++) {
205  for (i = 0 ; i < 3 ; i++)
206  end[i] = ent->s.origin[i] + time_left * ent->velocity[i];
207 
208  trace = gi.trace(ent->s.origin, ent->mins, ent->maxs, end, ent, mask);
209 
210  if (trace.allsolid) {
211  // entity is trapped in another solid
212  VectorCopy(vec3_origin, ent->velocity);
213  return 3;
214  }
215 
216  if (trace.fraction > 0) {
217  // actually covered some distance
218  VectorCopy(trace.endpos, ent->s.origin);
219  VectorCopy(ent->velocity, original_velocity);
220  numplanes = 0;
221  }
222 
223  if (trace.fraction == 1)
224  break; // moved the entire distance
225 
226  hit = trace.ent;
227 
228  if (trace.plane.normal[2] > 0.7) {
229  blocked |= 1; // floor
230  if (hit->solid == SOLID_BSP) {
231  ent->groundentity = hit;
232  ent->groundentity_linkcount = hit->linkcount;
233  }
234  }
235  if (!trace.plane.normal[2]) {
236  blocked |= 2; // step
237  }
238 
239 //
240 // run the impact function
241 //
242  SV_Impact(ent, &trace);
243  if (!ent->inuse)
244  break; // removed by the impact function
245 
246 
247  time_left -= time_left * trace.fraction;
248 
249  // cliped to another plane
250  if (numplanes >= MAX_CLIP_PLANES) {
251  // this shouldn't really happen
252  VectorCopy(vec3_origin, ent->velocity);
253  return 3;
254  }
255 
256  VectorCopy(trace.plane.normal, planes[numplanes]);
257  numplanes++;
258 
259 //
260 // modify original_velocity so it parallels all of the clip planes
261 //
262  for (i = 0 ; i < numplanes ; i++) {
263  ClipVelocity(original_velocity, planes[i], new_velocity, 1);
264 
265  for (j = 0 ; j < numplanes ; j++)
266  if ((j != i) && !VectorCompare(planes[i], planes[j])) {
267  if (DotProduct(new_velocity, planes[j]) < 0)
268  break; // not ok
269  }
270  if (j == numplanes)
271  break;
272  }
273 
274  if (i != numplanes) {
275  // go along this plane
276  VectorCopy(new_velocity, ent->velocity);
277  } else {
278  // go along the crease
279  if (numplanes != 2) {
280 // gi.dprintf ("clip velocity, numplanes == %i\n",numplanes);
281  VectorCopy(vec3_origin, ent->velocity);
282  return 7;
283  }
284  CrossProduct(planes[0], planes[1], dir);
285  d = DotProduct(dir, ent->velocity);
286  VectorScale(dir, d, ent->velocity);
287  }
288 
289 //
290 // if original velocity is against the original velocity, stop dead
291 // to avoid tiny occilations in sloping corners
292 //
293  if (DotProduct(ent->velocity, primal_velocity) <= 0) {
294  VectorCopy(vec3_origin, ent->velocity);
295  return blocked;
296  }
297  }
298 
299  return blocked;
300 }

Referenced by SV_Physics_Step().

◆ SV_Impact()

void SV_Impact ( edict_t *  e1,
trace_t *  trace 
)

Definition at line 117 of file g_phys.c.

118 {
119  edict_t *e2;
120 // cplane_t backplane;
121 
122  e2 = trace->ent;
123 
124  if (e1->touch && e1->solid != SOLID_NOT)
125  e1->touch(e1, e2, &trace->plane, trace->surface);
126 
127  if (e2->touch && e2->solid != SOLID_NOT)
128  e2->touch(e2, e1, NULL, NULL);
129 }

Referenced by SV_FlyMove(), and SV_PushEntity().

◆ SV_Physics_Noclip()

void SV_Physics_Noclip ( edict_t *  ent)

Definition at line 626 of file g_phys.c.

627 {
628 // regular thinking
629  if (!SV_RunThink(ent))
630  return;
631  if (!ent->inuse)
632  return;
633 
634  VectorMA(ent->s.angles, FRAMETIME, ent->avelocity, ent->s.angles);
635  VectorMA(ent->s.origin, FRAMETIME, ent->velocity, ent->s.origin);
636 
637  gi.linkentity(ent);
638 }

Referenced by G_RunEntity().

◆ SV_Physics_None()

void SV_Physics_None ( edict_t *  ent)

Definition at line 613 of file g_phys.c.

614 {
615 // regular thinking
616  SV_RunThink(ent);
617 }

Referenced by G_RunEntity().

◆ SV_Physics_Pusher()

void SV_Physics_Pusher ( edict_t *  ent)

Definition at line 551 of file g_phys.c.

552 {
553  vec3_t move, amove;
554  edict_t *part, *mv;
555 
556  // if not a team captain, so movement will be handled elsewhere
557  if (ent->flags & FL_TEAMSLAVE)
558  return;
559 
560  // make sure all team slaves can move before commiting
561  // any moves or calling any think functions
562  // if the move is blocked, all moved objects will be backed out
563 //retry:
564  pushed_p = pushed;
565  for (part = ent ; part ; part = part->teamchain) {
566  if (part->velocity[0] || part->velocity[1] || part->velocity[2] ||
567  part->avelocity[0] || part->avelocity[1] || part->avelocity[2]
568  ) {
569  // object is moving
570  VectorScale(part->velocity, FRAMETIME, move);
571  VectorScale(part->avelocity, FRAMETIME, amove);
572 
573  if (!SV_Push(part, move, amove))
574  break; // move was blocked
575  }
576  }
577  if (pushed_p > &pushed[MAX_EDICTS])
578  gi.error("pushed_p > &pushed[MAX_EDICTS], memory corrupted");
579 
580  if (part) {
581  // the move failed, bump all nextthink times and back out moves
582  for (mv = ent ; mv ; mv = mv->teamchain) {
583  if (mv->nextthink > 0)
584  mv->nextthink += FRAMETIME;
585  }
586 
587  // if the pusher has a "blocked" function, call it
588  // otherwise, just stay in place until the obstacle is gone
589  if (part->blocked)
590  part->blocked(part, obstacle);
591 #if 0
592  // if the pushed entity went away and the pusher is still there
593  if (!obstacle->inuse && part->inuse)
594  goto retry;
595 #endif
596  } else {
597  // the move succeeded, so call all think functions
598  for (part = ent ; part ; part = part->teamchain) {
599  SV_RunThink(part);
600  }
601  }
602 }

Referenced by G_RunEntity().

◆ SV_Physics_Step()

void SV_Physics_Step ( edict_t *  ent)

Definition at line 794 of file g_phys.c.

795 {
796  qboolean wasonground;
797  qboolean hitsound = qfalse;
798  float *vel;
799  float speed, newspeed, control;
800  float friction;
801  edict_t *groundentity;
802  int mask;
803 
804  // airborn monsters should always check for ground
805  if (!ent->groundentity)
806  M_CheckGround(ent);
807 
808  groundentity = ent->groundentity;
809 
810  SV_CheckVelocity(ent);
811 
812  if (groundentity)
813  wasonground = qtrue;
814  else
815  wasonground = qfalse;
816 
817  if (ent->avelocity[0] || ent->avelocity[1] || ent->avelocity[2])
819 
820  // add gravity except:
821  // flying monsters
822  // swimming monsters who are in the water
823  if (! wasonground)
824  if (!(ent->flags & FL_FLY))
825  if (!((ent->flags & FL_SWIM) && (ent->waterlevel > 2))) {
826  if (ent->velocity[2] < sv_gravity->value * -0.1)
827  hitsound = qtrue;
828  if (ent->waterlevel == 0)
829  SV_AddGravity(ent);
830  }
831 
832  // friction for flying monsters that have been given vertical velocity
833  if ((ent->flags & FL_FLY) && (ent->velocity[2] != 0)) {
834  speed = fabs(ent->velocity[2]);
835  control = speed < sv_stopspeed ? sv_stopspeed : speed;
836  friction = sv_friction / 3;
837  newspeed = speed - (FRAMETIME * control * friction);
838  if (newspeed < 0)
839  newspeed = 0;
840  newspeed /= speed;
841  ent->velocity[2] *= newspeed;
842  }
843 
844  // friction for flying monsters that have been given vertical velocity
845  if ((ent->flags & FL_SWIM) && (ent->velocity[2] != 0)) {
846  speed = fabs(ent->velocity[2]);
847  control = speed < sv_stopspeed ? sv_stopspeed : speed;
848  newspeed = speed - (FRAMETIME * control * sv_waterfriction * ent->waterlevel);
849  if (newspeed < 0)
850  newspeed = 0;
851  newspeed /= speed;
852  ent->velocity[2] *= newspeed;
853  }
854 
855  if (ent->velocity[2] || ent->velocity[1] || ent->velocity[0]) {
856  // apply friction
857  // let dead monsters who aren't completely onground slide
858  if ((wasonground) || (ent->flags & (FL_SWIM | FL_FLY)))
859  if (!(ent->health <= 0.0 && !M_CheckBottom(ent))) {
860  vel = ent->velocity;
861  speed = sqrt(vel[0] * vel[0] + vel[1] * vel[1]);
862  if (speed) {
863  friction = sv_friction;
864 
865  control = speed < sv_stopspeed ? sv_stopspeed : speed;
866  newspeed = speed - FRAMETIME * control * friction;
867 
868  if (newspeed < 0)
869  newspeed = 0;
870  newspeed /= speed;
871 
872  vel[0] *= newspeed;
873  vel[1] *= newspeed;
874  }
875  }
876 
877  if (ent->svflags & SVF_MONSTER)
878  mask = MASK_MONSTERSOLID;
879  else
880  mask = MASK_SOLID;
881  SV_FlyMove(ent, FRAMETIME, mask);
882 
883  gi.linkentity(ent);
884  G_TouchTriggers(ent);
885  if (!ent->inuse)
886  return;
887 
888  if (ent->groundentity)
889  if (!wasonground)
890  if (hitsound)
891  gi.sound(ent, 0, gi.soundindex("world/land.wav"), 1, 1, 0);
892  }
893 
894 // regular thinking
895  SV_RunThink(ent);
896 }

Referenced by G_RunEntity().

◆ SV_Physics_Toss()

void SV_Physics_Toss ( edict_t *  ent)

Definition at line 655 of file g_phys.c.

656 {
657  trace_t trace;
658  vec3_t move;
659  float backoff;
660  edict_t *slave;
661  qboolean wasinwater;
662  qboolean isinwater;
663  vec3_t old_origin;
664 
665 // regular thinking
666  SV_RunThink(ent);
667  if (!ent->inuse)
668  return;
669 
670  // if not a team captain, so movement will be handled elsewhere
671  if (ent->flags & FL_TEAMSLAVE)
672  return;
673 
674  if (ent->velocity[2] > 0)
675  ent->groundentity = NULL;
676 
677 // check for the groundentity going away
678  if (ent->groundentity)
679  if (!ent->groundentity->inuse)
680  ent->groundentity = NULL;
681 
682 // if onground, return without moving
683  if (ent->groundentity)
684  return;
685 
686  VectorCopy(ent->s.origin, old_origin);
687 
688  SV_CheckVelocity(ent);
689 
690 // add gravity
691  if (ent->movetype != MOVETYPE_FLY
692  && ent->movetype != MOVETYPE_FLYMISSILE)
693  SV_AddGravity(ent);
694 
695 // move angles
696  VectorMA(ent->s.angles, FRAMETIME, ent->avelocity, ent->s.angles);
697 
698 // move origin
699  VectorScale(ent->velocity, FRAMETIME, move);
700  trace = SV_PushEntity(ent, move);
701  if (!ent->inuse)
702  return;
703 
704  if (trace.fraction < 1) {
705  if (ent->movetype == MOVETYPE_BOUNCE)
706  backoff = 1.5;
707  else
708  backoff = 1;
709 
710  ClipVelocity(ent->velocity, trace.plane.normal, ent->velocity, backoff);
711 
712  // stop if on ground
713  if (trace.plane.normal[2] > 0.7) {
714  if (ent->velocity[2] < 60 || ent->movetype != MOVETYPE_BOUNCE) {
715  ent->groundentity = trace.ent;
716  ent->groundentity_linkcount = trace.ent->linkcount;
717  VectorCopy(vec3_origin, ent->velocity);
718  VectorCopy(vec3_origin, ent->avelocity);
719  }
720  }
721 
722 // if (ent->touch)
723 // ent->touch (ent, trace.ent, &trace.plane, trace.surface);
724  }
725 
726 // check for water transition
727  wasinwater = (ent->watertype & MASK_WATER);
728  ent->watertype = gi.pointcontents(ent->s.origin);
729  isinwater = ent->watertype & MASK_WATER;
730 
731  if (isinwater)
732  ent->waterlevel = 1;
733  else
734  ent->waterlevel = 0;
735 
736  if (!wasinwater && isinwater)
737  gi.positioned_sound(old_origin, g_edicts, CHAN_AUTO, gi.soundindex("misc/h2ohit1.wav"), 1, 1, 0);
738  else if (wasinwater && !isinwater)
739  gi.positioned_sound(ent->s.origin, g_edicts, CHAN_AUTO, gi.soundindex("misc/h2ohit1.wav"), 1, 1, 0);
740 
741 // move teamslaves
742  for (slave = ent->teamchain; slave; slave = slave->teamchain) {
743  VectorCopy(ent->s.origin, slave->s.origin);
744  gi.linkentity(slave);
745  }
746 }

Referenced by G_RunEntity().

◆ SV_Push()

qboolean SV_Push ( edict_t *  pusher,
vec3_t  move,
vec3_t  amove 
)

Definition at line 389 of file g_phys.c.

390 {
391  int i, e;
392  edict_t *check, *block;
393  vec3_t mins, maxs;
394  pushed_t *p;
395  vec3_t org, org2, move2, forward, right, up;
396 
397  // clamp the move to 1/8 units, so the position will
398  // be accurate for client side prediction
399  for (i = 0 ; i < 3 ; i++) {
400  float temp;
401  temp = move[i] * 8.0;
402  if (temp > 0.0)
403  temp += 0.5;
404  else
405  temp -= 0.5;
406  move[i] = 0.125 * (int)temp;
407  }
408 
409  // find the bounding box
410  for (i = 0 ; i < 3 ; i++) {
411  mins[i] = pusher->absmin[i] + move[i];
412  maxs[i] = pusher->absmax[i] + move[i];
413  }
414 
415 // we need this for pushing things later
416  VectorSubtract(vec3_origin, amove, org);
417  AngleVectors(org, forward, right, up);
418 
419 // save the pusher's original position
420  pushed_p->ent = pusher;
421  VectorCopy(pusher->s.origin, pushed_p->origin);
422  VectorCopy(pusher->s.angles, pushed_p->angles);
423 #if USE_SMOOTH_DELTA_ANGLES
424  if (pusher->client)
425  pushed_p->deltayaw = pusher->client->ps.pmove.delta_angles[YAW];
426 #endif
427  pushed_p++;
428 
429 // move the pusher to it's final position
430  VectorAdd(pusher->s.origin, move, pusher->s.origin);
431  VectorAdd(pusher->s.angles, amove, pusher->s.angles);
432  gi.linkentity(pusher);
433 
434 // see if any solid entities are inside the final position
435  check = g_edicts + 1;
436  for (e = 1; e < globals.num_edicts; e++, check++) {
437  if (!check->inuse)
438  continue;
439  if (check->movetype == MOVETYPE_PUSH
440  || check->movetype == MOVETYPE_STOP
441  || check->movetype == MOVETYPE_NONE
442  || check->movetype == MOVETYPE_NOCLIP)
443  continue;
444 
445  if (!check->area.prev)
446  continue; // not linked in anywhere
447 
448  // if the entity is standing on the pusher, it will definitely be moved
449  if (check->groundentity != pusher) {
450  // see if the ent needs to be tested
451  if (check->absmin[0] >= maxs[0]
452  || check->absmin[1] >= maxs[1]
453  || check->absmin[2] >= maxs[2]
454  || check->absmax[0] <= mins[0]
455  || check->absmax[1] <= mins[1]
456  || check->absmax[2] <= mins[2])
457  continue;
458 
459  // see if the ent's bbox is inside the pusher's final position
460  if (!SV_TestEntityPosition(check))
461  continue;
462  }
463 
464  if ((pusher->movetype == MOVETYPE_PUSH) || (check->groundentity == pusher)) {
465  // move this entity
466  pushed_p->ent = check;
467  VectorCopy(check->s.origin, pushed_p->origin);
468  VectorCopy(check->s.angles, pushed_p->angles);
469 #if USE_SMOOTH_DELTA_ANGLES
470  if (check->client)
471  pushed_p->deltayaw = check->client->ps.pmove.delta_angles[YAW];
472 #endif
473  pushed_p++;
474 
475  // try moving the contacted entity
476  VectorAdd(check->s.origin, move, check->s.origin);
477 #if USE_SMOOTH_DELTA_ANGLES
478  if (check->client) {
479  // FIXME: doesn't rotate monsters?
480  // FIXME: skuller: needs client side interpolation
481  check->client->ps.pmove.delta_angles[YAW] += ANGLE2SHORT(amove[YAW]);
482  }
483 #endif
484 
485  // figure movement due to the pusher's amove
486  VectorSubtract(check->s.origin, pusher->s.origin, org);
487  org2[0] = DotProduct(org, forward);
488  org2[1] = -DotProduct(org, right);
489  org2[2] = DotProduct(org, up);
490  VectorSubtract(org2, org, move2);
491  VectorAdd(check->s.origin, move2, check->s.origin);
492 
493  // may have pushed them off an edge
494  if (check->groundentity != pusher)
495  check->groundentity = NULL;
496 
497  block = SV_TestEntityPosition(check);
498  if (!block) {
499  // pushed ok
500  gi.linkentity(check);
501  // impact?
502  continue;
503  }
504 
505  // if it is ok to leave in the old position, do it
506  // this is only relevent for riding entities, not pushed
507  // FIXME: this doesn't acount for rotation
508  VectorSubtract(check->s.origin, move, check->s.origin);
509  block = SV_TestEntityPosition(check);
510  if (!block) {
511  pushed_p--;
512  continue;
513  }
514  }
515 
516  // save off the obstacle so we can call the block function
517  obstacle = check;
518 
519  // move back any entities we already moved
520  // go backwards, so if the same entity was pushed
521  // twice, it goes back to the original position
522  for (p = pushed_p - 1 ; p >= pushed ; p--) {
523  VectorCopy(p->origin, p->ent->s.origin);
524  VectorCopy(p->angles, p->ent->s.angles);
525 #if USE_SMOOTH_DELTA_ANGLES
526  if (p->ent->client) {
527  p->ent->client->ps.pmove.delta_angles[YAW] = p->deltayaw;
528  }
529 #endif
530  gi.linkentity(p->ent);
531  }
532  return qfalse;
533  }
534 
535 //FIXME: is there a better way to handle this?
536  // see if anything we moved has touched a trigger
537  for (p = pushed_p - 1 ; p >= pushed ; p--)
538  G_TouchTriggers(p->ent);
539 
540  return qtrue;
541 }

Referenced by SV_Physics_Pusher().

◆ SV_PushEntity()

trace_t SV_PushEntity ( edict_t *  ent,
vec3_t  push 
)

Definition at line 329 of file g_phys.c.

330 {
331  trace_t trace;
332  vec3_t start;
333  vec3_t end;
334  int mask;
335 
336  VectorCopy(ent->s.origin, start);
337  VectorAdd(start, push, end);
338 
339 retry:
340  if (ent->clipmask)
341  mask = ent->clipmask;
342  else
343  mask = MASK_SOLID;
344 
345  trace = gi.trace(start, ent->mins, ent->maxs, end, ent, mask);
346 
347  VectorCopy(trace.endpos, ent->s.origin);
348  gi.linkentity(ent);
349 
350  if (trace.fraction != 1.0) {
351  SV_Impact(ent, &trace);
352 
353  // if the pushed entity went away and the pusher is still there
354  if (!trace.ent->inuse && ent->inuse) {
355  // move the pusher back and try again
356  VectorCopy(start, ent->s.origin);
357  gi.linkentity(ent);
358  goto retry;
359  }
360  }
361 
362  if (ent->inuse)
363  G_TouchTriggers(ent);
364 
365  return trace;
366 }

Referenced by SV_Physics_Toss().

◆ SV_RunThink()

qboolean SV_RunThink ( edict_t *  ent)

Definition at line 92 of file g_phys.c.

93 {
94  float thinktime;
95 
96  thinktime = ent->nextthink;
97  if (thinktime <= 0)
98  return qtrue;
99  if (thinktime > level.time + 0.001)
100  return qtrue;
101 
102  ent->nextthink = 0;
103  if (!ent->think)
104  gi.error("NULL ent->think");
105  ent->think(ent);
106 
107  return qfalse;
108 }

Referenced by SV_Physics_Noclip(), SV_Physics_None(), SV_Physics_Pusher(), SV_Physics_Step(), and SV_Physics_Toss().

◆ SV_TestEntityPosition()

edict_t* SV_TestEntityPosition ( edict_t *  ent)

Definition at line 47 of file g_phys.c.

48 {
49  trace_t trace;
50  int mask;
51 
52  if (ent->clipmask)
53  mask = ent->clipmask;
54  else
55  mask = MASK_SOLID;
56  trace = gi.trace(ent->s.origin, ent->mins, ent->maxs, ent->s.origin, ent, mask);
57 
58  if (trace.startsolid)
59  return g_edicts;
60 
61  return NULL;
62 }

Referenced by SV_Push().

Variable Documentation

◆ obstacle

edict_t* obstacle

Definition at line 379 of file g_phys.c.

Referenced by SV_Physics_Pusher(), and SV_Push().

◆ pushed

pushed_t pushed[MAX_EDICTS]

Definition at line 377 of file g_phys.c.

Referenced by SV_Physics_Pusher(), and SV_Push().

◆ pushed_p

pushed_t * pushed_p

Definition at line 377 of file g_phys.c.

Referenced by SV_Physics_Pusher(), and SV_Push().

gi
game_import_t gi
Definition: g_main.c:23
push
push
Definition: god_rays_shared.h:6
sv_waterfriction
#define sv_waterfriction
Definition: g_phys.c:772
pushed_t::ent
edict_t * ent
Definition: g_phys.c:370
FRAMETIME
#define FRAMETIME
Definition: g_local.h:75
obstacle
edict_t * obstacle
Definition: g_phys.c:379
MOVETYPE_NOCLIP
@ MOVETYPE_NOCLIP
Definition: g_local.h:187
MOVETYPE_STOP
@ MOVETYPE_STOP
Definition: g_local.h:189
SV_CheckVelocity
void SV_CheckVelocity(edict_t *ent)
Definition: g_phys.c:70
sv_friction
#define sv_friction
Definition: g_phys.c:771
pushed_t::origin
vec3_t origin
Definition: g_phys.c:371
SV_Physics_Noclip
void SV_Physics_Noclip(edict_t *ent)
Definition: g_phys.c:626
G_TouchTriggers
void G_TouchTriggers(edict_t *ent)
Definition: g_utils.c:443
MOVETYPE_PUSH
@ MOVETYPE_PUSH
Definition: g_local.h:188
MOVETYPE_FLYMISSILE
@ MOVETYPE_FLYMISSILE
Definition: g_local.h:195
pushed_p
pushed_t * pushed_p
Definition: g_phys.c:377
SV_Impact
void SV_Impact(edict_t *e1, trace_t *trace)
Definition: g_phys.c:117
SV_Physics_Pusher
void SV_Physics_Pusher(edict_t *ent)
Definition: g_phys.c:551
SV_AddGravity
void SV_AddGravity(edict_t *ent)
Definition: g_phys.c:309
g_edicts
edict_t * g_edicts
Definition: g_main.c:31
MOVETYPE_STEP
@ MOVETYPE_STEP
Definition: g_local.h:192
FL_SWIM
#define FL_SWIM
Definition: g_local.h:60
ClipVelocity
int ClipVelocity(vec3_t in, vec3_t normal, vec3_t out, float overbounce)
Definition: g_phys.c:142
vec3_origin
vec3_t vec3_origin
Definition: shared.c:21
SV_AddRotationalFriction
void SV_AddRotationalFriction(edict_t *ent)
Definition: g_phys.c:774
MOVETYPE_NONE
@ MOVETYPE_NONE
Definition: g_local.h:186
SV_Physics_None
void SV_Physics_None(edict_t *ent)
Definition: g_phys.c:613
forward
static vec3_t forward
Definition: p_view.c:27
STOP_EPSILON
#define STOP_EPSILON
Definition: g_phys.c:140
AngleVectors
void AngleVectors(vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
Definition: shared.c:23
M_CheckBottom
qboolean M_CheckBottom(edict_t *ent)
Definition: m_move.c:35
globals
game_export_t globals
Definition: g_main.c:24
SV_PushEntity
trace_t SV_PushEntity(edict_t *ent, vec3_t push)
Definition: g_phys.c:329
M_CheckGround
void M_CheckGround(edict_t *ent)
Definition: g_monster.c:139
SV_FlyMove
int SV_FlyMove(edict_t *ent, float time, int mask)
Definition: g_phys.c:179
level_locals_t::time
float time
Definition: g_local.h:299
MAX_CLIP_PLANES
#define MAX_CLIP_PLANES
Definition: g_phys.c:178
up
static vec3_t up
Definition: p_view.c:27
pushed_t
Definition: g_phys.c:369
right
static vec3_t right
Definition: p_view.c:27
SV_Push
qboolean SV_Push(edict_t *pusher, vec3_t move, vec3_t amove)
Definition: g_phys.c:389
FL_TEAMSLAVE
#define FL_TEAMSLAVE
Definition: g_local.h:69
pushed_t::angles
vec3_t angles
Definition: g_phys.c:372
level
level_locals_t level
Definition: g_main.c:22
FL_FLY
#define FL_FLY
Definition: g_local.h:59
SV_TestEntityPosition
edict_t * SV_TestEntityPosition(edict_t *ent)
Definition: g_phys.c:47
MOVETYPE_BOUNCE
@ MOVETYPE_BOUNCE
Definition: g_local.h:196
sv_gravity
cvar_t * sv_gravity
Definition: g_main.c:52
SV_Physics_Toss
void SV_Physics_Toss(edict_t *ent)
Definition: g_phys.c:655
MOVETYPE_TOSS
@ MOVETYPE_TOSS
Definition: g_local.h:194
pushed
pushed_t pushed[MAX_EDICTS]
Definition: g_phys.c:377
sv_maxvelocity
cvar_t * sv_maxvelocity
Definition: g_main.c:51
int
CONST PIXELFORMATDESCRIPTOR int
Definition: wgl.c:26
sv_stopspeed
#define sv_stopspeed
Definition: g_phys.c:770
SV_Physics_Step
void SV_Physics_Step(edict_t *ent)
Definition: g_phys.c:794
MOVETYPE_FLY
@ MOVETYPE_FLY
Definition: g_local.h:193
SV_RunThink
qboolean SV_RunThink(edict_t *ent)
Definition: g_phys.c:92