icculus quake2 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_tSV_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_tobstacle
 

Macro Definition Documentation

◆ MAX_CLIP_PLANES

#define MAX_CLIP_PLANES   5

Definition at line 182 of file g_phys.c.

◆ STOP_EPSILON

#define STOP_EPSILON   0.1

Definition at line 143 of file g_phys.c.

◆ sv_friction

#define sv_friction   6

Definition at line 788 of file g_phys.c.

◆ sv_stopspeed

#define sv_stopspeed   100

Definition at line 787 of file g_phys.c.

◆ sv_waterfriction

#define sv_waterfriction   1

Definition at line 789 of file g_phys.c.

Function Documentation

◆ ClipVelocity()

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

Definition at line 145 of file g_phys.c.

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

Referenced by SV_FlyMove(), and SV_Physics_Toss().

◆ G_RunEntity()

void G_RunEntity ( edict_t ent)

Definition at line 932 of file g_phys.c.

933 {
934  if (ent->prethink)
935  ent->prethink (ent);
936 
937  switch ( (int)ent->movetype)
938  {
939  case MOVETYPE_PUSH:
940  case MOVETYPE_STOP:
941  SV_Physics_Pusher (ent);
942  break;
943  case MOVETYPE_NONE:
944  SV_Physics_None (ent);
945  break;
946  case MOVETYPE_NOCLIP:
947  SV_Physics_Noclip (ent);
948  break;
949  case MOVETYPE_STEP:
950  SV_Physics_Step (ent);
951  break;
952  case MOVETYPE_TOSS:
953  case MOVETYPE_BOUNCE:
954  case MOVETYPE_FLY:
955  case MOVETYPE_FLYMISSILE:
956  SV_Physics_Toss (ent);
957  break;
958  default:
959  gi.error ("SV_Physics: bad movetype %i", (int)ent->movetype);
960  }
961 }

Referenced by G_RunFrame().

◆ SV_AddGravity()

void SV_AddGravity ( edict_t ent)

Definition at line 322 of file g_phys.c.

323 {
324  ent->velocity[2] -= ent->gravity * sv_gravity->value * FRAMETIME;
325 }

Referenced by SV_Physics_Step(), and SV_Physics_Toss().

◆ SV_AddRotationalFriction()

void SV_AddRotationalFriction ( edict_t ent)

Definition at line 791 of file g_phys.c.

792 {
793  int n;
794  float adjustment;
795 
796  VectorMA (ent->s.angles, FRAMETIME, ent->avelocity, ent->s.angles);
797  adjustment = FRAMETIME * sv_stopspeed * sv_friction;
798  for (n = 0; n < 3; n++)
799  {
800  if (ent->avelocity[n] > 0)
801  {
802  ent->avelocity[n] -= adjustment;
803  if (ent->avelocity[n] < 0)
804  ent->avelocity[n] = 0;
805  }
806  else
807  {
808  ent->avelocity[n] += adjustment;
809  if (ent->avelocity[n] > 0)
810  ent->avelocity[n] = 0;
811  }
812  }
813 }

Referenced by SV_Physics_Step().

◆ SV_CheckVelocity()

void SV_CheckVelocity ( edict_t ent)

Definition at line 72 of file g_phys.c.

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

Referenced by SV_Physics_Step(), and SV_Physics_Toss().

◆ SV_FlyMove()

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

Definition at line 183 of file g_phys.c.

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

Referenced by SV_Physics_Step().

◆ SV_Impact()

void SV_Impact ( edict_t e1,
trace_t trace 
)

Definition at line 120 of file g_phys.c.

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

Referenced by SV_FlyMove(), and SV_PushEntity().

◆ SV_Physics_Noclip()

void SV_Physics_Noclip ( edict_t ent)

Definition at line 643 of file g_phys.c.

644 {
645 // regular thinking
646  if (!SV_RunThink (ent))
647  return;
648 
649  VectorMA (ent->s.angles, FRAMETIME, ent->avelocity, ent->s.angles);
650  VectorMA (ent->s.origin, FRAMETIME, ent->velocity, ent->s.origin);
651 
652  gi.linkentity (ent);
653 }

Referenced by G_RunEntity().

◆ SV_Physics_None()

void SV_Physics_None ( edict_t ent)

Definition at line 630 of file g_phys.c.

631 {
632 // regular thinking
633  SV_RunThink (ent);
634 }

Referenced by G_RunEntity().

◆ SV_Physics_Pusher()

void SV_Physics_Pusher ( edict_t ent)

Definition at line 562 of file g_phys.c.

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

Referenced by G_RunEntity().

◆ SV_Physics_Step()

void SV_Physics_Step ( edict_t ent)

Definition at line 815 of file g_phys.c.

816 {
817  qboolean wasonground;
818  qboolean hitsound = false;
819  float *vel;
820  float speed, newspeed, control;
821  float friction;
822  edict_t *groundentity;
823  int mask;
824 
825  // airborn monsters should always check for ground
826  if (!ent->groundentity)
827  M_CheckGround (ent);
828 
829  groundentity = ent->groundentity;
830 
831  SV_CheckVelocity (ent);
832 
833  if (groundentity)
834  wasonground = true;
835  else
836  wasonground = false;
837 
838  if (ent->avelocity[0] || ent->avelocity[1] || ent->avelocity[2])
840 
841  // add gravity except:
842  // flying monsters
843  // swimming monsters who are in the water
844  if (! wasonground)
845  if (!(ent->flags & FL_FLY))
846  if (!((ent->flags & FL_SWIM) && (ent->waterlevel > 2)))
847  {
848  if (ent->velocity[2] < sv_gravity->value*-0.1)
849  hitsound = true;
850  if (ent->waterlevel == 0)
851  SV_AddGravity (ent);
852  }
853 
854  // friction for flying monsters that have been given vertical velocity
855  if ((ent->flags & FL_FLY) && (ent->velocity[2] != 0))
856  {
857  speed = fabs(ent->velocity[2]);
858  control = speed < sv_stopspeed ? sv_stopspeed : speed;
859  friction = sv_friction/3;
860  newspeed = speed - (FRAMETIME * control * friction);
861  if (newspeed < 0)
862  newspeed = 0;
863  newspeed /= speed;
864  ent->velocity[2] *= newspeed;
865  }
866 
867  // friction for flying monsters that have been given vertical velocity
868  if ((ent->flags & FL_SWIM) && (ent->velocity[2] != 0))
869  {
870  speed = fabs(ent->velocity[2]);
871  control = speed < sv_stopspeed ? sv_stopspeed : speed;
872  newspeed = speed - (FRAMETIME * control * sv_waterfriction * ent->waterlevel);
873  if (newspeed < 0)
874  newspeed = 0;
875  newspeed /= speed;
876  ent->velocity[2] *= newspeed;
877  }
878 
879  if (ent->velocity[2] || ent->velocity[1] || ent->velocity[0])
880  {
881  // apply friction
882  // let dead monsters who aren't completely onground slide
883  if ((wasonground) || (ent->flags & (FL_SWIM|FL_FLY)))
884  if (!(ent->health <= 0.0 && !M_CheckBottom(ent)))
885  {
886  vel = ent->velocity;
887  speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1]);
888  if (speed)
889  {
890  friction = sv_friction;
891 
892  control = speed < sv_stopspeed ? sv_stopspeed : speed;
893  newspeed = speed - FRAMETIME*control*friction;
894 
895  if (newspeed < 0)
896  newspeed = 0;
897  newspeed /= speed;
898 
899  vel[0] *= newspeed;
900  vel[1] *= newspeed;
901  }
902  }
903 
904  if (ent->svflags & SVF_MONSTER)
906  else
907  mask = MASK_SOLID;
908  SV_FlyMove (ent, FRAMETIME, mask);
909 
910  gi.linkentity (ent);
911  G_TouchTriggers (ent);
912  if (!ent->inuse)
913  return;
914 
915  if (ent->groundentity)
916  if (!wasonground)
917  if (hitsound)
918  gi.sound (ent, 0, gi.soundindex("world/land.wav"), 1, 1, 0);
919  }
920 
921 // regular thinking
922  SV_RunThink (ent);
923 }

Referenced by G_RunEntity().

◆ SV_Physics_Toss()

void SV_Physics_Toss ( edict_t ent)

Definition at line 670 of file g_phys.c.

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

Referenced by G_RunEntity().

◆ SV_Push()

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

Definition at line 403 of file g_phys.c.

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

Referenced by SV_Physics_Pusher().

◆ SV_PushEntity()

trace_t SV_PushEntity ( edict_t ent,
vec3_t  push 
)

Definition at line 342 of file g_phys.c.

343 {
344  trace_t trace;
345  vec3_t start;
346  vec3_t end;
347  int mask;
348 
349  VectorCopy (ent->s.origin, start);
350  VectorAdd (start, push, end);
351 
352 retry:
353  if (ent->clipmask)
354  mask = ent->clipmask;
355  else
356  mask = MASK_SOLID;
357 
358  trace = gi.trace (start, ent->mins, ent->maxs, end, ent, mask);
359 
360  VectorCopy (trace.endpos, ent->s.origin);
361  gi.linkentity (ent);
362 
363  if (trace.fraction != 1.0)
364  {
365  SV_Impact (ent, &trace);
366 
367  // if the pushed entity went away and the pusher is still there
368  if (!trace.ent->inuse && ent->inuse)
369  {
370  // move the pusher back and try again
371  VectorCopy (start, ent->s.origin);
372  gi.linkentity (ent);
373  goto retry;
374  }
375  }
376 
377  if (ent->inuse)
378  G_TouchTriggers (ent);
379 
380  return trace;
381 }

Referenced by SV_Physics_Toss().

◆ SV_RunThink()

qboolean SV_RunThink ( edict_t ent)

Definition at line 95 of file g_phys.c.

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

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 49 of file g_phys.c.

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

Referenced by SV_Push().

Variable Documentation

◆ obstacle

edict_t* obstacle

Definition at line 393 of file g_phys.c.

Referenced by SV_Physics_Pusher(), and SV_Push().

◆ pushed

Definition at line 391 of file g_phys.c.

Referenced by SV_Physics_Pusher(), and SV_Push().

◆ pushed_p

pushed_t * pushed_p

Definition at line 391 of file g_phys.c.

Referenced by SV_Physics_Pusher(), and SV_Push().

gi
game_import_t gi
Definition: g_main.c:25
cplane_s::normal
vec3_t normal
Definition: q_shared.h:411
edict_s::s
entity_state_t s
Definition: g_local.h:964
edict_s::groundentity
edict_t * groundentity
Definition: g_local.h:1073
sv_waterfriction
#define sv_waterfriction
Definition: g_phys.c:789
YAW
#define YAW
Definition: q_shared.h:66
MASK_MONSTERSOLID
#define MASK_MONSTERSOLID
Definition: q_shared.h:394
pushed_t::ent
edict_t * ent
Definition: g_phys.c:386
game_import_t::trace
trace_t(* trace)(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passent, int contentmask)
Definition: game.h:128
trace_t::fraction
float fraction
Definition: q_shared.h:453
int
CONST PIXELFORMATDESCRIPTOR int
Definition: qgl_win.c:35
VectorSubtract
#define VectorSubtract(a, b, c)
Definition: q_shared.h:156
edict_s::absmax
vec3_t absmax
Definition: g_local.h:985
trace_t::plane
cplane_t plane
Definition: q_shared.h:455
FRAMETIME
#define FRAMETIME
Definition: g_local.h:73
obstacle
edict_t * obstacle
Definition: g_phys.c:393
pushed_t::deltayaw
float deltayaw
Definition: g_phys.c:389
MOVETYPE_NOCLIP
@ MOVETYPE_NOCLIP
Definition: g_local.h:189
MOVETYPE_STOP
@ MOVETYPE_STOP
Definition: g_local.h:191
numplanes
int numplanes
Definition: cmodel.c:71
entity_state_s::origin
vec3_t origin
Definition: q_shared.h:1173
edict_s::linkcount
int linkcount
Definition: g_local.h:971
SV_CheckVelocity
void SV_CheckVelocity(edict_t *ent)
Definition: g_phys.c:72
sv_friction
#define sv_friction
Definition: g_phys.c:788
MASK_WATER
#define MASK_WATER
Definition: q_shared.h:395
VectorScale
void VectorScale(vec3_t in, vec_t scale, vec3_t out)
Definition: q_shared.c:782
pushed_t::origin
vec3_t origin
Definition: g_phys.c:387
qboolean
qboolean
Definition: q_shared.h:56
edict_s::inuse
qboolean inuse
Definition: g_local.h:970
SV_Physics_Noclip
void SV_Physics_Noclip(edict_t *ent)
Definition: g_phys.c:643
trace_t
Definition: q_shared.h:449
i
int i
Definition: q_shared.c:305
G_TouchTriggers
void G_TouchTriggers(edict_t *ent)
Definition: g_utils.c:475
MOVETYPE_PUSH
@ MOVETYPE_PUSH
Definition: g_local.h:190
MOVETYPE_FLYMISSILE
@ MOVETYPE_FLYMISSILE
Definition: g_local.h:197
pushed_p
pushed_t * pushed_p
Definition: g_phys.c:391
SV_Impact
void SV_Impact(edict_t *e1, trace_t *trace)
Definition: g_phys.c:120
edict_s::client
struct gclient_s * client
Definition: g_local.h:965
game_import_t::sound
void(* sound)(edict_t *ent, int channel, int soundindex, float volume, float attenuation, float timeofs)
Definition: game.h:109
edict_s::blocked
void(* blocked)(edict_t *self, edict_t *other)
Definition: g_local.h:1039
SV_Physics_Pusher
void SV_Physics_Pusher(edict_t *ent)
Definition: g_phys.c:562
edict_s::mins
vec3_t mins
Definition: g_local.h:984
edict_s::prethink
void(* prethink)(edict_t *ent)
Definition: g_local.h:1037
SV_AddGravity
void SV_AddGravity(edict_t *ent)
Definition: g_phys.c:322
g_edicts
edict_t * g_edicts
Definition: g_main.c:33
edict_s::groundentity_linkcount
int groundentity_linkcount
Definition: g_local.h:1074
edict_s::movetype
int movetype
Definition: g_local.h:995
MOVETYPE_STEP
@ MOVETYPE_STEP
Definition: g_local.h:194
FL_SWIM
#define FL_SWIM
Definition: g_local.h:58
j
GLint j
Definition: qgl_win.c:150
MASK_SOLID
#define MASK_SOLID
Definition: q_shared.h:391
AngleVectors
void AngleVectors(vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
Definition: q_shared.c:93
CHAN_AUTO
#define CHAN_AUTO
Definition: q_shared.h:1007
ClipVelocity
int ClipVelocity(vec3_t in, vec3_t normal, vec3_t out, float overbounce)
Definition: g_phys.c:145
trace_t::allsolid
qboolean allsolid
Definition: q_shared.h:451
edict_s::svflags
int svflags
Definition: g_local.h:983
CrossProduct
void CrossProduct(vec3_t v1, vec3_t v2, vec3_t cross)
Definition: q_shared.c:753
edict_s
Definition: g_local.h:962
SV_AddRotationalFriction
void SV_AddRotationalFriction(edict_t *ent)
Definition: g_phys.c:791
MOVETYPE_NONE
@ MOVETYPE_NONE
Definition: g_local.h:188
SV_Physics_None
void SV_Physics_None(edict_t *ent)
Definition: g_phys.c:630
game_import_t::soundindex
int(* soundindex)(char *name)
Definition: game.h:122
forward
static vec3_t forward
Definition: p_view.c:29
edict_s::clipmask
int clipmask
Definition: g_local.h:987
player_state_t::pmove
pmove_state_t pmove
Definition: q_shared.h:1200
game_import_t::pointcontents
int(* pointcontents)(vec3_t point)
Definition: game.h:129
DotProduct
#define DotProduct(x, y)
Definition: q_shared.h:155
game_import_t::positioned_sound
void(* positioned_sound)(vec3_t origin, edict_t *ent, int channel, int soundinedex, float volume, float attenuation, float timeofs)
Definition: game.h:110
edict_s::nextthink
float nextthink
Definition: g_local.h:1036
cvar_s::value
float value
Definition: q_shared.h:324
edict_s::think
void(* think)(edict_t *self)
Definition: g_local.h:1038
STOP_EPSILON
#define STOP_EPSILON
Definition: g_phys.c:143
pmove_state_t::delta_angles
short delta_angles[3]
Definition: q_shared.h:499
M_CheckBottom
qboolean M_CheckBottom(edict_t *ent)
Definition: m_move.c:37
gclient_s::ps
player_state_t ps
Definition: g_local.h:880
edict_s::watertype
int watertype
Definition: g_local.h:1093
NULL
#define NULL
Definition: q_shared.h:60
globals
game_export_t globals
Definition: g_main.c:26
edict_s::solid
solid_t solid
Definition: g_local.h:986
SOLID_NOT
@ SOLID_NOT
Definition: game.h:35
MAX_EDICTS
#define MAX_EDICTS
Definition: q_shared.h:80
edict_s::velocity
vec3_t velocity
Definition: g_local.h:1024
ERR_FATAL
#define ERR_FATAL
Definition: qcommon.h:735
SV_PushEntity
trace_t SV_PushEntity(edict_t *ent, vec3_t push)
Definition: g_phys.c:342
VectorAdd
#define VectorAdd(a, b, c)
Definition: q_shared.h:157
M_CheckGround
void M_CheckGround(edict_t *ent)
Definition: g_monster.c:141
SV_FlyMove
int SV_FlyMove(edict_t *ent, float time, int mask)
Definition: g_phys.c:183
game_import_t::error
void(* error)(char *fmt,...)
Definition: game.h:118
VectorCopy
#define VectorCopy(a, b)
Definition: q_shared.h:158
MAX_CLIP_PLANES
#define MAX_CLIP_PLANES
Definition: g_phys.c:182
trace_t::endpos
vec3_t endpos
Definition: q_shared.h:454
vec3_origin
vec3_t vec3_origin
Definition: q_shared.c:24
up
static vec3_t up
Definition: p_view.c:29
pushed_t
Definition: g_phys.c:384
level
GLint level
Definition: qgl_win.c:116
SV_Push
qboolean SV_Push(edict_t *pusher, vec3_t move, vec3_t amove)
Definition: g_phys.c:403
edict_s::flags
int flags
Definition: g_local.h:996
FL_TEAMSLAVE
#define FL_TEAMSLAVE
Definition: g_local.h:67
pushed_t::angles
vec3_t angles
Definition: g_phys.c:388
sqrt
double sqrt(double x)
VectorMA
void VectorMA(vec3_t veca, float scale, vec3_t vecb, vec3_t vecc)
Definition: q_shared.c:719
SOLID_BSP
@ SOLID_BSP
Definition: game.h:38
edict_s::maxs
vec3_t maxs
Definition: g_local.h:984
edict_s::avelocity
vec3_t avelocity
Definition: g_local.h:1025
trace_t::startsolid
qboolean startsolid
Definition: q_shared.h:452
edict_s::gravity
float gravity
Definition: g_local.h:1028
trace_t::ent
struct edict_s * ent
Definition: q_shared.h:458
FL_FLY
#define FL_FLY
Definition: g_local.h:57
SVF_MONSTER
#define SVF_MONSTER
Definition: game.h:29
edict_s::touch
void(* touch)(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
Definition: g_local.h:1040
SV_TestEntityPosition
edict_t * SV_TestEntityPosition(edict_t *ent)
Definition: g_phys.c:49
MOVETYPE_BOUNCE
@ MOVETYPE_BOUNCE
Definition: g_local.h:198
trace_t::surface
csurface_t * surface
Definition: q_shared.h:456
sv_gravity
cvar_t * sv_gravity
Definition: g_main.c:53
SV_Physics_Toss
void SV_Physics_Toss(edict_t *ent)
Definition: g_phys.c:670
MOVETYPE_TOSS
@ MOVETYPE_TOSS
Definition: g_local.h:196
right
GLdouble right
Definition: qgl_win.c:159
pushed
pushed_t pushed[MAX_EDICTS]
Definition: g_phys.c:391
sv_maxvelocity
cvar_t * sv_maxvelocity
Definition: g_main.c:52
edict_s::waterlevel
int waterlevel
Definition: g_local.h:1094
edict_s::area
link_t area
Definition: g_local.h:974
VectorCompare
int VectorCompare(vec3_t v1, vec3_t v2)
Definition: q_shared.c:672
mask
GLint GLuint mask
Definition: qgl_win.c:317
edict_s::teamchain
edict_t * teamchain
Definition: g_local.h:1075
game_import_t::linkentity
void(* linkentity)(edict_t *ent)
Definition: game.h:138
entity_state_s::angles
vec3_t angles
Definition: q_shared.h:1174
sv_stopspeed
#define sv_stopspeed
Definition: g_phys.c:787
SV_Physics_Step
void SV_Physics_Step(edict_t *ent)
Definition: g_phys.c:815
vec3_t
vec_t vec3_t[3]
Definition: q_shared.h:127
edict_s::absmin
vec3_t absmin
Definition: g_local.h:985
MOVETYPE_FLY
@ MOVETYPE_FLY
Definition: g_local.h:195
game_export_t::num_edicts
int num_edicts
Definition: game.h:231
SV_RunThink
qboolean SV_RunThink(edict_t *ent)
Definition: g_phys.c:95
edict_s::health
int health
Definition: g_local.h:1051