Quake II RTX doxygen  1.0 dev
pmove.c File Reference
#include "shared/shared.h"
#include "common/pmove.h"

Go to the source code of this file.

Classes

struct  pml_t
 

Macros

#define STEPSIZE   18
 
#define STOP_EPSILON   0.1
 
#define MIN_STEP_NORMAL   0.7
 
#define MAX_CLIP_PLANES   5
 

Functions

static void PM_ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce)
 
static void PM_StepSlideMove_ (void)
 
static void PM_StepSlideMove (void)
 
static void PM_Friction (void)
 
static void PM_Accelerate (vec3_t wishdir, float wishspeed, float accel)
 
static void PM_AirAccelerate (vec3_t wishdir, float wishspeed, float accel)
 
static void PM_AddCurrents (vec3_t wishvel)
 
static void PM_WaterMove (void)
 
static void PM_AirMove (void)
 
static void PM_CategorizePosition (void)
 
static void PM_CheckJump (void)
 
static void PM_CheckSpecialMovement (void)
 
static void PM_FlyMove (void)
 
static void PM_CheckDuck (void)
 
static void PM_DeadMove (void)
 
static qboolean PM_GoodPosition (void)
 
static void PM_SnapPosition (void)
 
static void PM_InitialSnapPosition (void)
 
static void PM_ClampAngles (void)
 
void Pmove (pmove_t *pmove, pmoveParams_t *params)
 
void PmoveInit (pmoveParams_t *pmp)
 
void PmoveEnableQW (pmoveParams_t *pmp)
 

Variables

static pmove_t * pm
 
static pml_t pml
 
static pmoveParams_t * pmp
 
static const float pm_stopspeed = 100
 
static const float pm_duckspeed = 100
 
static const float pm_accelerate = 10
 
static const float pm_wateraccelerate = 10
 
static const float pm_waterspeed = 400
 

Macro Definition Documentation

◆ MAX_CLIP_PLANES

#define MAX_CLIP_PLANES   5

Definition at line 104 of file pmove.c.

◆ MIN_STEP_NORMAL

#define MIN_STEP_NORMAL   0.7

Definition at line 103 of file pmove.c.

◆ STEPSIZE

#define STEPSIZE   18

Definition at line 22 of file pmove.c.

◆ STOP_EPSILON

#define STOP_EPSILON   0.1

Definition at line 71 of file pmove.c.

Function Documentation

◆ PM_Accelerate()

static void PM_Accelerate ( vec3_t  wishdir,
float  wishspeed,
float  accel 
)
static

Definition at line 326 of file pmove.c.

327 {
328  int i;
329  float addspeed, accelspeed, currentspeed;
330 
331  currentspeed = DotProduct(pml.velocity, wishdir);
332  addspeed = wishspeed - currentspeed;
333  if (addspeed <= 0)
334  return;
335  accelspeed = accel * pml.frametime * wishspeed;
336  if (accelspeed > addspeed)
337  accelspeed = addspeed;
338 
339  for (i = 0; i < 3; i++)
340  pml.velocity[i] += accelspeed * wishdir[i];
341 }

Referenced by PM_AirMove(), and PM_WaterMove().

◆ PM_AddCurrents()

static void PM_AddCurrents ( vec3_t  wishvel)
static

Definition at line 367 of file pmove.c.

368 {
369  vec3_t v;
370  float s;
371 
372  //
373  // account for ladders
374  //
375 
376  if (pml.ladder && fabs(pml.velocity[2]) <= 200) {
377  if ((pm->viewangles[PITCH] <= -15) && (pm->cmd.forwardmove > 0))
378  wishvel[2] = 200;
379  else if ((pm->viewangles[PITCH] >= 15) && (pm->cmd.forwardmove > 0))
380  wishvel[2] = -200;
381  else if (pm->cmd.upmove > 0)
382  wishvel[2] = 200;
383  else if (pm->cmd.upmove < 0)
384  wishvel[2] = -200;
385  else
386  wishvel[2] = 0;
387 
388  // limit horizontal speed when on a ladder
389  if (wishvel[0] < -25)
390  wishvel[0] = -25;
391  else if (wishvel[0] > 25)
392  wishvel[0] = 25;
393 
394  if (wishvel[1] < -25)
395  wishvel[1] = -25;
396  else if (wishvel[1] > 25)
397  wishvel[1] = 25;
398  }
399 
400 
401  //
402  // add water currents
403  //
404 
405  if (pm->watertype & MASK_CURRENT) {
406  VectorClear(v);
407 
408  if (pm->watertype & CONTENTS_CURRENT_0)
409  v[0] += 1;
410  if (pm->watertype & CONTENTS_CURRENT_90)
411  v[1] += 1;
412  if (pm->watertype & CONTENTS_CURRENT_180)
413  v[0] -= 1;
414  if (pm->watertype & CONTENTS_CURRENT_270)
415  v[1] -= 1;
416  if (pm->watertype & CONTENTS_CURRENT_UP)
417  v[2] += 1;
418  if (pm->watertype & CONTENTS_CURRENT_DOWN)
419  v[2] -= 1;
420 
421  s = pm_waterspeed;
422  if ((pm->waterlevel == 1) && (pm->groundentity))
423  s /= 2;
424 
425  VectorMA(wishvel, s, v, wishvel);
426  }
427 
428  //
429  // add conveyor belt velocities
430  //
431 
432  if (pm->groundentity) {
433  VectorClear(v);
434 
435  if (pml.groundcontents & CONTENTS_CURRENT_0)
436  v[0] += 1;
437  if (pml.groundcontents & CONTENTS_CURRENT_90)
438  v[1] += 1;
439  if (pml.groundcontents & CONTENTS_CURRENT_180)
440  v[0] -= 1;
441  if (pml.groundcontents & CONTENTS_CURRENT_270)
442  v[1] -= 1;
443  if (pml.groundcontents & CONTENTS_CURRENT_UP)
444  v[2] += 1;
445  if (pml.groundcontents & CONTENTS_CURRENT_DOWN)
446  v[2] -= 1;
447 
448  VectorMA(wishvel, 100 /* pm->groundentity->speed */, v, wishvel);
449  }
450 }

Referenced by PM_AirMove(), and PM_WaterMove().

◆ PM_AirAccelerate()

static void PM_AirAccelerate ( vec3_t  wishdir,
float  wishspeed,
float  accel 
)
static

Definition at line 343 of file pmove.c.

344 {
345  int i;
346  float addspeed, accelspeed, currentspeed, wishspd = wishspeed;
347 
348  if (wishspd > 30)
349  wishspd = 30;
350  currentspeed = DotProduct(pml.velocity, wishdir);
351  addspeed = wishspd - currentspeed;
352  if (addspeed <= 0)
353  return;
354  accelspeed = accel * wishspeed * pml.frametime;
355  if (accelspeed > addspeed)
356  accelspeed = addspeed;
357 
358  for (i = 0; i < 3; i++)
359  pml.velocity[i] += accelspeed * wishdir[i];
360 }

Referenced by PM_AirMove().

◆ PM_AirMove()

static void PM_AirMove ( void  )
static

!!!! pitch should be 1/3 so this isn't needed??!

!! this is before the accel

Definition at line 500 of file pmove.c.

501 {
502  int i;
503  vec3_t wishvel;
504  float fmove, smove;
505  vec3_t wishdir;
506  float wishspeed;
507  float maxspeed;
508 
509  fmove = pm->cmd.forwardmove;
510  smove = pm->cmd.sidemove;
511 
513 #if 0
514  pml.forward[2] = 0;
515  pml.right[2] = 0;
518 #endif
519 
520  for (i = 0; i < 2; i++)
521  wishvel[i] = pml.forward[i] * fmove + pml.right[i] * smove;
522  wishvel[2] = 0;
523 
524  PM_AddCurrents(wishvel);
525 
526  VectorCopy(wishvel, wishdir);
527  wishspeed = VectorNormalize(wishdir);
528 
529 //
530 // clamp to server defined max speed
531 //
532  maxspeed = (pm->s.pm_flags & PMF_DUCKED) ? pm_duckspeed : pmp->maxspeed;
533 
534  if (wishspeed > maxspeed) {
535  VectorScale(wishvel, maxspeed / wishspeed, wishvel);
536  wishspeed = maxspeed;
537  }
538 
539  if (pml.ladder) {
540  PM_Accelerate(wishdir, wishspeed, pm_accelerate);
541  if (!wishvel[2]) {
542  if (pml.velocity[2] > 0) {
543  pml.velocity[2] -= pm->s.gravity * pml.frametime;
544  if (pml.velocity[2] < 0)
545  pml.velocity[2] = 0;
546  } else {
547  pml.velocity[2] += pm->s.gravity * pml.frametime;
548  if (pml.velocity[2] > 0)
549  pml.velocity[2] = 0;
550  }
551  }
553  } else if (pm->groundentity) {
554  // walking on ground
555  pml.velocity[2] = 0;
556  PM_Accelerate(wishdir, wishspeed, pm_accelerate);
557 
558 
559 // PGM -- fix for negative trigger_gravity fields
560 // pml.velocity[2] = 0;
561  if (pm->s.gravity > 0)
562  pml.velocity[2] = 0;
563  else
564  pml.velocity[2] -= pm->s.gravity * pml.frametime;
565 // PGM
566 
567  if (!pml.velocity[0] && !pml.velocity[1])
568  return;
570  } else {
571  // not on ground, so little effect on velocity
572  if (pmp->airaccelerate)
573  PM_AirAccelerate(wishdir, wishspeed, pm_accelerate);
574  else
575  PM_Accelerate(wishdir, wishspeed, 1);
576  // add gravity
577  pml.velocity[2] -= pm->s.gravity * pml.frametime;
579  }
580 }

Referenced by Pmove().

◆ PM_CategorizePosition()

static void PM_CategorizePosition ( void  )
static

!ZOID changed from 100 to 180 (ramp accel)

Definition at line 589 of file pmove.c.

590 {
591  vec3_t point;
592  int cont;
593  trace_t trace;
594  int sample1;
595  int sample2;
596 
597 // if the player hull point one unit down is solid, the player
598 // is on ground
599 
600 // see if standing on something solid
601  point[0] = pml.origin[0];
602  point[1] = pml.origin[1];
603  point[2] = pml.origin[2] - 0.25f;
604  if (pml.velocity[2] > 180) {
605  pm->s.pm_flags &= ~PMF_ON_GROUND;
606  pm->groundentity = NULL;
607  } else {
608  trace = pm->trace(pml.origin, pm->mins, pm->maxs, point);
609  pml.groundplane = trace.plane;
610  pml.groundsurface = trace.surface;
611  pml.groundcontents = trace.contents;
612 
613  if (!trace.ent || (trace.plane.normal[2] < 0.7 && !trace.startsolid)) {
614  pm->groundentity = NULL;
615  pm->s.pm_flags &= ~PMF_ON_GROUND;
616  } else {
617  pm->groundentity = trace.ent;
618 
619  // hitting solid ground will end a waterjump
620  if (pm->s.pm_flags & PMF_TIME_WATERJUMP) {
621  pm->s.pm_flags &= ~(PMF_TIME_WATERJUMP | PMF_TIME_LAND | PMF_TIME_TELEPORT);
622  pm->s.pm_time = 0;
623  }
624 
625  if (!(pm->s.pm_flags & PMF_ON_GROUND)) {
626  // just hit the ground
627  pm->s.pm_flags |= PMF_ON_GROUND;
628  // don't do landing time if we were just going down a slope
629  if (pml.velocity[2] < -200 && !pmp->strafehack) {
630  pm->s.pm_flags |= PMF_TIME_LAND;
631  // don't allow another jump for a little while
632  if (pml.velocity[2] < -400)
633  pm->s.pm_time = 25;
634  else
635  pm->s.pm_time = 18;
636  }
637  }
638  }
639 
640  if (pm->numtouch < MAXTOUCH && trace.ent) {
641  pm->touchents[pm->numtouch] = trace.ent;
642  pm->numtouch++;
643  }
644  }
645 
646 //
647 // get waterlevel, accounting for ducking
648 //
649  pm->waterlevel = 0;
650  pm->watertype = 0;
651 
652  sample2 = pm->viewheight - pm->mins[2];
653  sample1 = sample2 / 2;
654 
655  point[2] = pml.origin[2] + pm->mins[2] + 1;
656  cont = pm->pointcontents(point);
657 
658  if (cont & MASK_WATER) {
659  pm->watertype = cont;
660  pm->waterlevel = 1;
661  point[2] = pml.origin[2] + pm->mins[2] + sample1;
662  cont = pm->pointcontents(point);
663  if (cont & MASK_WATER) {
664  pm->waterlevel = 2;
665  point[2] = pml.origin[2] + pm->mins[2] + sample2;
666  cont = pm->pointcontents(point);
667  if (cont & MASK_WATER)
668  pm->waterlevel = 3;
669  }
670  }
671 
672 }

Referenced by Pmove().

◆ PM_CheckDuck()

static void PM_CheckDuck ( void  )
static

Definition at line 884 of file pmove.c.

885 {
886  trace_t trace;
887 
888  pm->mins[0] = -16;
889  pm->mins[1] = -16;
890 
891  pm->maxs[0] = 16;
892  pm->maxs[1] = 16;
893 
894  if (pm->s.pm_type == PM_GIB) {
895  pm->mins[2] = 0;
896  pm->maxs[2] = 16;
897  pm->viewheight = 8;
898  return;
899  }
900 
901  pm->mins[2] = -24;
902 
903  if (pm->s.pm_type == PM_DEAD) {
904  pm->s.pm_flags |= PMF_DUCKED;
905  } else if (pm->cmd.upmove < 0 && (pm->s.pm_flags & PMF_ON_GROUND)) {
906  // duck
907  pm->s.pm_flags |= PMF_DUCKED;
908  } else {
909  // stand up if possible
910  if (pm->s.pm_flags & PMF_DUCKED) {
911  // try to stand up
912  pm->maxs[2] = 32;
913  trace = pm->trace(pml.origin, pm->mins, pm->maxs, pml.origin);
914  if (!trace.allsolid)
915  pm->s.pm_flags &= ~PMF_DUCKED;
916  }
917  }
918 
919  if (pm->s.pm_flags & PMF_DUCKED) {
920  pm->maxs[2] = 4;
921  pm->viewheight = -2;
922  } else {
923  pm->maxs[2] = 32;
924  pm->viewheight = 22;
925  }
926 }

Referenced by Pmove().

◆ PM_CheckJump()

static void PM_CheckJump ( void  )
static

Definition at line 680 of file pmove.c.

681 {
682  if (pm->s.pm_flags & PMF_TIME_LAND) {
683  // hasn't been long enough since landing to jump again
684  return;
685  }
686 
687  if (pm->cmd.upmove < 10) {
688  // not holding jump
689  pm->s.pm_flags &= ~PMF_JUMP_HELD;
690  return;
691  }
692 
693  // must wait for jump to be released
694  if (pm->s.pm_flags & PMF_JUMP_HELD)
695  return;
696 
697  if (pm->s.pm_type == PM_DEAD)
698  return;
699 
700  if (pm->waterlevel >= 2) {
701  // swimming, not jumping
702  pm->groundentity = NULL;
703 
704  if (pmp->waterhack)
705  return;
706 
707  if (pml.velocity[2] <= -300)
708  return;
709 
710  // FIXME: makes velocity dependent on client FPS,
711  // even causes prediction misses
712  if (pm->watertype == CONTENTS_WATER)
713  pml.velocity[2] = 100;
714  else if (pm->watertype == CONTENTS_SLIME)
715  pml.velocity[2] = 80;
716  else
717  pml.velocity[2] = 50;
718  return;
719  }
720 
721  if (pm->groundentity == NULL)
722  return; // in air, so no effect
723 
724  pm->s.pm_flags |= PMF_JUMP_HELD;
725 
726  pm->groundentity = NULL;
727  pm->s.pm_flags &= ~PMF_ON_GROUND;
728  pml.velocity[2] += 270;
729  if (pml.velocity[2] < 270)
730  pml.velocity[2] = 270;
731 }

Referenced by Pmove().

◆ PM_CheckSpecialMovement()

static void PM_CheckSpecialMovement ( void  )
static

Definition at line 739 of file pmove.c.

740 {
741  vec3_t spot;
742  int cont;
743  vec3_t flatforward;
744  trace_t trace;
745 
746  if (pm->s.pm_time)
747  return;
748 
749  pml.ladder = qfalse;
750 
751  // check for ladder
752  flatforward[0] = pml.forward[0];
753  flatforward[1] = pml.forward[1];
754  flatforward[2] = 0;
755  VectorNormalize(flatforward);
756 
757  VectorMA(pml.origin, 1, flatforward, spot);
758  trace = pm->trace(pml.origin, pm->mins, pm->maxs, spot);
759  if ((trace.fraction < 1) && (trace.contents & CONTENTS_LADDER))
760  pml.ladder = qtrue;
761 
762  // check for water jump
763  if (pm->waterlevel != 2)
764  return;
765 
766  VectorMA(pml.origin, 30, flatforward, spot);
767  spot[2] += 4;
768  cont = pm->pointcontents(spot);
769  if (!(cont & CONTENTS_SOLID))
770  return;
771 
772  spot[2] += 16;
773  cont = pm->pointcontents(spot);
774  if (cont)
775  return;
776  // jump out of water
777  VectorScale(flatforward, 50, pml.velocity);
778  pml.velocity[2] = 350;
779 
780  pm->s.pm_flags |= PMF_TIME_WATERJUMP;
781  pm->s.pm_time = 255;
782 }

Referenced by Pmove().

◆ PM_ClampAngles()

static void PM_ClampAngles ( void  )
static

Definition at line 1095 of file pmove.c.

1096 {
1097  short temp;
1098  int i;
1099 
1100  if (pm->s.pm_flags & PMF_TIME_TELEPORT) {
1101  pm->viewangles[YAW] = SHORT2ANGLE(pm->cmd.angles[YAW] + pm->s.delta_angles[YAW]);
1102  pm->viewangles[PITCH] = 0;
1103  pm->viewangles[ROLL] = 0;
1104  } else {
1105  // circularly clamp the angles with deltas
1106  for (i = 0; i < 3; i++) {
1107  temp = pm->cmd.angles[i] + pm->s.delta_angles[i];
1108  pm->viewangles[i] = SHORT2ANGLE(temp);
1109  }
1110 
1111  // don't let the player look up or down more than 90 degrees
1112  if (pm->viewangles[PITCH] > 89 && pm->viewangles[PITCH] < 180)
1113  pm->viewangles[PITCH] = 89;
1114  else if (pm->viewangles[PITCH] < 271 && pm->viewangles[PITCH] >= 180)
1115  pm->viewangles[PITCH] = 271;
1116  }
1117  AngleVectors(pm->viewangles, pml.forward, pml.right, pml.up);
1118 }

Referenced by Pmove().

◆ PM_ClipVelocity()

static void PM_ClipVelocity ( vec3_t  in,
vec3_t  normal,
vec3_t  out,
float  overbounce 
)
static

Definition at line 73 of file pmove.c.

74 {
75  float backoff;
76  float change;
77  int i;
78 
79  backoff = DotProduct(in, normal) * overbounce;
80 
81  for (i = 0; i < 3; i++) {
82  change = normal[i] * backoff;
83  out[i] = in[i] - change;
84  if (out[i] > -STOP_EPSILON && out[i] < STOP_EPSILON)
85  out[i] = 0;
86  }
87 }

Referenced by PM_StepSlideMove_().

◆ PM_DeadMove()

static void PM_DeadMove ( void  )
static

Definition at line 934 of file pmove.c.

935 {
936  float forward;
937 
938  if (!pm->groundentity)
939  return;
940 
941  // extra friction
942 
943  forward = VectorLength(pml.velocity);
944  forward -= 20;
945  if (forward <= 0) {
946  VectorClear(pml.velocity);
947  } else {
949  VectorScale(pml.velocity, forward, pml.velocity);
950  }
951 }

Referenced by Pmove().

◆ PM_FlyMove()

static void PM_FlyMove ( void  )
static

Definition at line 790 of file pmove.c.

791 {
792  float speed, drop, friction, control, newspeed;
793  float currentspeed, addspeed, accelspeed;
794  int i;
795  vec3_t wishvel;
796  float fmove, smove;
797  vec3_t wishdir;
798  float wishspeed;
799 
800  pm->viewheight = 22;
801 
802  // friction
803 
804  speed = VectorLength(pml.velocity);
805  if (speed < 1) {
806  VectorCopy(vec3_origin, pml.velocity);
807  } else {
808  drop = 0;
809 
810  friction = pmp->flyfriction;
811  control = speed < pm_stopspeed ? pm_stopspeed : speed;
812  drop += control * friction * pml.frametime;
813 
814  // scale the velocity
815  newspeed = speed - drop;
816  if (newspeed < 0)
817  newspeed = 0;
818  newspeed /= speed;
819 
820  VectorScale(pml.velocity, newspeed, pml.velocity);
821  }
822 
823  // accelerate
824  fmove = pm->cmd.forwardmove;
825  smove = pm->cmd.sidemove;
826 
829 
830  for (i = 0; i < 3; i++)
831  wishvel[i] = pml.forward[i] * fmove + pml.right[i] * smove;
832  wishvel[2] += pm->cmd.upmove;
833 
834  VectorCopy(wishvel, wishdir);
835  wishspeed = VectorNormalize(wishdir);
836 
837  //
838  // clamp to server defined max speed
839  //
840  if (wishspeed > pmp->maxspeed) {
841  VectorScale(wishvel, pmp->maxspeed / wishspeed, wishvel);
842  wishspeed = pmp->maxspeed;
843  }
844 
845  currentspeed = DotProduct(pml.velocity, wishdir);
846  addspeed = wishspeed - currentspeed;
847  if (addspeed <= 0) {
848  if (!pmp->flyhack) {
849  return; // original buggy behaviour
850  }
851  } else {
852  accelspeed = pm_accelerate * pml.frametime * wishspeed;
853  if (accelspeed > addspeed)
854  accelspeed = addspeed;
855 
856  for (i = 0; i < 3; i++)
857  pml.velocity[i] += accelspeed * wishdir[i];
858  }
859 
860 #if 0
861  if (doclip) {
862  for (i = 0; i < 3; i++)
863  end[i] = pml.origin[i] + pml.frametime * pml.velocity[i];
864 
865  trace = pm->trace(pml.origin, pm->mins, pm->maxs, end);
866 
867  VectorCopy(trace.endpos, pml.origin);
868  } else
869 #endif
870  {
871  // move
872  VectorMA(pml.origin, pml.frametime, pml.velocity, pml.origin);
873  }
874 }

Referenced by Pmove().

◆ PM_Friction()

static void PM_Friction ( void  )
static

Definition at line 277 of file pmove.c.

278 {
279  float *vel;
280  float speed, newspeed, control;
281  float friction;
282  float drop;
283 
284  vel = pml.velocity;
285 
286  speed = sqrt(vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2]);
287  if (speed < 1) {
288  vel[0] = 0;
289  vel[1] = 0;
290  return;
291  }
292 
293  drop = 0;
294 
295 // apply ground friction
296  if ((pm->groundentity && pml.groundsurface && !(pml.groundsurface->flags & SURF_SLICK)) || (pml.ladder)) {
297  friction = pmp->friction;
298  control = speed < pm_stopspeed ? pm_stopspeed : speed;
299  drop += control * friction * pml.frametime;
300  }
301 
302 // apply water friction
303  if (pm->waterlevel && !pml.ladder)
304  drop += speed * pmp->waterfriction * pm->waterlevel * pml.frametime;
305 
306 // scale the velocity
307  newspeed = speed - drop;
308  if (newspeed < 0) {
309  newspeed = 0;
310  }
311  newspeed /= speed;
312 
313  vel[0] = vel[0] * newspeed;
314  vel[1] = vel[1] * newspeed;
315  vel[2] = vel[2] * newspeed;
316 }

Referenced by Pmove().

◆ PM_GoodPosition()

static qboolean PM_GoodPosition ( void  )
static

Definition at line 954 of file pmove.c.

955 {
956  trace_t trace;
957  vec3_t origin, end;
958  int i;
959 
960  if (pm->s.pm_type == PM_SPECTATOR)
961  return qtrue;
962 
963  for (i = 0; i < 3; i++)
964  origin[i] = end[i] = pm->s.origin[i] * 0.125;
965  trace = pm->trace(origin, pm->mins, pm->maxs, end);
966 
967  return !trace.allsolid;
968 }

Referenced by PM_InitialSnapPosition(), and PM_SnapPosition().

◆ PM_InitialSnapPosition()

static void PM_InitialSnapPosition ( void  )
static

Definition at line 1063 of file pmove.c.

1064 {
1065  int x, y, z;
1066  short base[3];
1067  static const short offset[3] = { 0, -1, 1 };
1068 
1069  VectorCopy(pm->s.origin, base);
1070 
1071  for (z = 0; z < 3; z++) {
1072  pm->s.origin[2] = base[2] + offset[z];
1073  for (y = 0; y < 3; y++) {
1074  pm->s.origin[1] = base[1] + offset[y];
1075  for (x = 0; x < 3; x++) {
1076  pm->s.origin[0] = base[0] + offset[x];
1077  if (PM_GoodPosition()) {
1078  pml.origin[0] = pm->s.origin[0] * 0.125;
1079  pml.origin[1] = pm->s.origin[1] * 0.125;
1080  pml.origin[2] = pm->s.origin[2] * 0.125;
1081  VectorCopy(pm->s.origin, pml.previous_origin);
1082  return;
1083  }
1084  }
1085  }
1086  }
1087 }

Referenced by Pmove().

◆ PM_SnapPosition()

static void PM_SnapPosition ( void  )
static

Definition at line 978 of file pmove.c.

979 {
980  int sign[3];
981  int i, j, bits;
982  short base[3];
983  // try all single bits first
984  static const byte jitterbits[8] = {0, 4, 1, 2, 3, 5, 6, 7};
985 
986  // snap velocity to eigths
987  for (i = 0; i < 3; i++)
988  pm->s.velocity[i] = (int)(pml.velocity[i] * 8);
989 
990  for (i = 0; i < 3; i++) {
991  if (pml.origin[i] >= 0)
992  sign[i] = 1;
993  else
994  sign[i] = -1;
995  pm->s.origin[i] = (int)(pml.origin[i] * 8);
996  if (pm->s.origin[i] * 0.125f == pml.origin[i])
997  sign[i] = 0;
998  }
999  VectorCopy(pm->s.origin, base);
1000 
1001  // try all combinations
1002  for (j = 0; j < 8; j++) {
1003  bits = jitterbits[j];
1004  VectorCopy(base, pm->s.origin);
1005  for (i = 0; i < 3; i++)
1006  if (bits & (1 << i))
1007  pm->s.origin[i] += sign[i];
1008 
1009  if (PM_GoodPosition())
1010  return;
1011  }
1012 
1013  // go back to the last position
1014  VectorCopy(pml.previous_origin, pm->s.origin);
1015 }

Referenced by Pmove().

◆ PM_StepSlideMove()

static void PM_StepSlideMove ( void  )
static

! Special case

Definition at line 213 of file pmove.c.

214 {
215  vec3_t start_o, start_v;
216  vec3_t down_o, down_v;
217  trace_t trace;
218  float down_dist, up_dist;
219 // vec3_t delta;
220  vec3_t up, down;
221 
222  VectorCopy(pml.origin, start_o);
223  VectorCopy(pml.velocity, start_v);
224 
226 
227  VectorCopy(pml.origin, down_o);
228  VectorCopy(pml.velocity, down_v);
229 
230  VectorCopy(start_o, up);
231  up[2] += STEPSIZE;
232 
233  trace = pm->trace(up, pm->mins, pm->maxs, up);
234  if (trace.allsolid)
235  return; // can't step up
236 
237  // try sliding above
238  VectorCopy(up, pml.origin);
239  VectorCopy(start_v, pml.velocity);
240 
242 
243  // push down the final amount
244  VectorCopy(pml.origin, down);
245  down[2] -= STEPSIZE;
246  trace = pm->trace(pml.origin, pm->mins, pm->maxs, down);
247  if (!trace.allsolid) {
248  VectorCopy(trace.endpos, pml.origin);
249  }
250 
251  VectorCopy(pml.origin, up);
252 
253  // decide which one went farther
254  down_dist = (down_o[0] - start_o[0]) * (down_o[0] - start_o[0])
255  + (down_o[1] - start_o[1]) * (down_o[1] - start_o[1]);
256  up_dist = (up[0] - start_o[0]) * (up[0] - start_o[0])
257  + (up[1] - start_o[1]) * (up[1] - start_o[1]);
258 
259  if (down_dist > up_dist || trace.plane.normal[2] < MIN_STEP_NORMAL) {
260  VectorCopy(down_o, pml.origin);
261  VectorCopy(down_v, pml.velocity);
262  return;
263  }
265  // if we were walking along a plane, then we need to copy the Z over
266  pml.velocity[2] = down_v[2];
267 }

Referenced by PM_AirMove(), PM_WaterMove(), and Pmove().

◆ PM_StepSlideMove_()

static void PM_StepSlideMove_ ( void  )
static

Definition at line 105 of file pmove.c.

106 {
107  int bumpcount, numbumps;
108  vec3_t dir;
109  float d;
110  int numplanes;
111  vec3_t planes[MAX_CLIP_PLANES];
112  vec3_t primal_velocity;
113  int i, j;
114  trace_t trace;
115  vec3_t end;
116  float time_left;
117 
118  numbumps = 4;
119 
120  VectorCopy(pml.velocity, primal_velocity);
121  numplanes = 0;
122 
123  time_left = pml.frametime;
124 
125  for (bumpcount = 0; bumpcount < numbumps; bumpcount++) {
126  for (i = 0; i < 3; i++)
127  end[i] = pml.origin[i] + time_left * pml.velocity[i];
128 
129  trace = pm->trace(pml.origin, pm->mins, pm->maxs, end);
130 
131  if (trace.allsolid) {
132  // entity is trapped in another solid
133  pml.velocity[2] = 0; // don't build up falling damage
134  return;
135  }
136 
137  if (trace.fraction > 0) {
138  // actually covered some distance
139  VectorCopy(trace.endpos, pml.origin);
140  numplanes = 0;
141  }
142 
143  if (trace.fraction == 1)
144  break; // moved the entire distance
145 
146  // save entity for contact
147  if (pm->numtouch < MAXTOUCH && trace.ent) {
148  pm->touchents[pm->numtouch] = trace.ent;
149  pm->numtouch++;
150  }
151 
152  time_left -= time_left * trace.fraction;
153 
154  // slide along this plane
155  if (numplanes >= MAX_CLIP_PLANES) {
156  // this shouldn't really happen
157  VectorCopy(vec3_origin, pml.velocity);
158  break;
159  }
160 
161  VectorCopy(trace.plane.normal, planes[numplanes]);
162  numplanes++;
163 
164 //
165 // modify original_velocity so it parallels all of the clip planes
166 //
167  for (i = 0; i < numplanes; i++) {
168  PM_ClipVelocity(pml.velocity, planes[i], pml.velocity, 1.01);
169  for (j = 0; j < numplanes; j++)
170  if (j != i) {
171  if (DotProduct(pml.velocity, planes[j]) < 0)
172  break; // not ok
173  }
174  if (j == numplanes)
175  break;
176  }
177 
178  if (i != numplanes) {
179  // go along this plane
180  } else {
181  // go along the crease
182  if (numplanes != 2) {
183 // Con_Printf ("clip velocity, numplanes == %i\n",numplanes);
184  VectorCopy(vec3_origin, pml.velocity);
185  break;
186  }
187  CrossProduct(planes[0], planes[1], dir);
188  d = DotProduct(dir, pml.velocity);
189  VectorScale(dir, d, pml.velocity);
190  }
191 
192  //
193  // if velocity is against the original velocity, stop dead
194  // to avoid tiny occilations in sloping corners
195  //
196  if (DotProduct(pml.velocity, primal_velocity) <= 0) {
197  VectorCopy(vec3_origin, pml.velocity);
198  break;
199  }
200  }
201 
202  if (pm->s.pm_time) {
203  VectorCopy(primal_velocity, pml.velocity);
204  }
205 }

Referenced by PM_StepSlideMove().

◆ PM_WaterMove()

static void PM_WaterMove ( void  )
static

Definition at line 459 of file pmove.c.

460 {
461  int i;
462  vec3_t wishvel;
463  float wishspeed;
464  vec3_t wishdir;
465 
466 //
467 // user intentions
468 //
469  for (i = 0; i < 3; i++)
470  wishvel[i] = pml.forward[i] * pm->cmd.forwardmove + pml.right[i] * pm->cmd.sidemove;
471 
472  if (!pm->cmd.forwardmove && !pm->cmd.sidemove && !pm->cmd.upmove)
473  wishvel[2] -= 60; // drift towards bottom
474  else
475  wishvel[2] += pm->cmd.upmove;
476 
477  PM_AddCurrents(wishvel);
478 
479  VectorCopy(wishvel, wishdir);
480  wishspeed = VectorNormalize(wishdir);
481 
482  if (wishspeed > pmp->maxspeed) {
483  VectorScale(wishvel, pmp->maxspeed / wishspeed, wishvel);
484  wishspeed = pmp->maxspeed;
485  }
486  wishspeed *= pmp->watermult;
487 
488  PM_Accelerate(wishdir, wishspeed, pm_wateraccelerate);
489 
491 }

Referenced by Pmove().

◆ Pmove()

void Pmove ( pmove_t *  pmove,
pmoveParams_t *  params 
)

Definition at line 1127 of file pmove.c.

1128 {
1129  pm = pmove;
1130  pmp = params;
1131 
1132  // clear results
1133  pm->numtouch = 0;
1134  VectorClear(pm->viewangles);
1135  pm->viewheight = 0;
1136  pm->groundentity = NULL;
1137  pm->watertype = 0;
1138  pm->waterlevel = 0;
1139 
1140  // clear all pmove local vars
1141  memset(&pml, 0, sizeof(pml));
1142 
1143  // convert origin and velocity to float values
1144  VectorScale(pm->s.origin, 0.125f, pml.origin);
1145  VectorScale(pm->s.velocity, 0.125f, pml.velocity);
1146 
1147  // save old org in case we get stuck
1148  VectorCopy(pm->s.origin, pml.previous_origin);
1149 
1150  PM_ClampAngles();
1151 
1152  if (pm->s.pm_type == PM_SPECTATOR) {
1153  pml.frametime = pmp->speedmult * pm->cmd.msec * 0.001f;
1154  PM_FlyMove();
1155  PM_SnapPosition();
1156  return;
1157  }
1158 
1159  pml.frametime = pm->cmd.msec * 0.001f;
1160 
1161  if (pm->s.pm_type >= PM_DEAD) {
1162  pm->cmd.forwardmove = 0;
1163  pm->cmd.sidemove = 0;
1164  pm->cmd.upmove = 0;
1165  }
1166 
1167  if (pm->s.pm_type == PM_FREEZE)
1168  return; // no movement at all
1169 
1170  // set mins, maxs, and viewheight
1171  PM_CheckDuck();
1172 
1173  if (pm->snapinitial)
1175 
1176  // set groundentity, watertype, and waterlevel
1178 
1179  if (pm->s.pm_type == PM_DEAD)
1180  PM_DeadMove();
1181 
1183 
1184  // drop timing counter
1185  if (pm->s.pm_time) {
1186  int msec;
1187 
1188  msec = pm->cmd.msec >> 3;
1189  if (!msec)
1190  msec = 1;
1191  if (msec >= pm->s.pm_time) {
1192  pm->s.pm_flags &= ~(PMF_TIME_WATERJUMP | PMF_TIME_LAND | PMF_TIME_TELEPORT);
1193  pm->s.pm_time = 0;
1194  } else
1195  pm->s.pm_time -= msec;
1196  }
1197 
1198  if (pm->s.pm_flags & PMF_TIME_TELEPORT) {
1199  // teleport pause stays exactly in place
1200  } else if (pm->s.pm_flags & PMF_TIME_WATERJUMP) {
1201  // waterjump has no control, but falls
1202  pml.velocity[2] -= pm->s.gravity * pml.frametime;
1203  if (pml.velocity[2] < 0) {
1204  // cancel as soon as we are falling down again
1205  pm->s.pm_flags &= ~(PMF_TIME_WATERJUMP | PMF_TIME_LAND | PMF_TIME_TELEPORT);
1206  pm->s.pm_time = 0;
1207  }
1208 
1209  PM_StepSlideMove();
1210  } else {
1211  PM_CheckJump();
1212 
1213  PM_Friction();
1214 
1215  if (pm->waterlevel >= 2)
1216  PM_WaterMove();
1217  else {
1218  vec3_t angles;
1219 
1220  VectorCopy(pm->viewangles, angles);
1221  if (angles[PITCH] > 180)
1222  angles[PITCH] = angles[PITCH] - 360;
1223  angles[PITCH] /= 3;
1224 
1225  AngleVectors(angles, pml.forward, pml.right, pml.up);
1226 
1227  PM_AirMove();
1228  }
1229  }
1230 
1231  // set groundentity, watertype, and waterlevel for final spot
1233 
1234  PM_SnapPosition();
1235 }

Referenced by CL_PredictMovement(), and PF_Pmove().

◆ PmoveEnableQW()

void PmoveEnableQW ( pmoveParams_t *  pmp)

Definition at line 1250 of file pmove.c.

1251 {
1252  pmp->qwmode = qtrue;
1253  pmp->watermult = 0.7f;
1254  pmp->maxspeed = 320;
1255  //pmp->upspeed = (sv_qwmod->integer > 1) ? 310 : 350;
1256  pmp->friction = 4;
1257  pmp->waterfriction = 4;
1258  pmp->airaccelerate = qtrue;
1259 }

Referenced by CL_ParseServerData(), and init_pmove_and_es_flags().

◆ PmoveInit()

void PmoveInit ( pmoveParams_t *  pmp)

Definition at line 1237 of file pmove.c.

1238 {
1239  // set up default pmove parameters
1240  memset(pmp, 0, sizeof(*pmp));
1241 
1242  pmp->speedmult = 1;
1243  pmp->watermult = 0.5f;
1244  pmp->maxspeed = 300;
1245  pmp->friction = 6;
1246  pmp->waterfriction = 1;
1247  pmp->flyfriction = 9;
1248 }

Referenced by CL_ParseServerData(), and SV_Init().

Variable Documentation

◆ pm

◆ pm_accelerate

const float pm_accelerate = 10
static

Definition at line 52 of file pmove.c.

Referenced by PM_AirMove(), and PM_FlyMove().

◆ pm_duckspeed

const float pm_duckspeed = 100
static

Definition at line 51 of file pmove.c.

Referenced by PM_AirMove().

◆ pm_stopspeed

const float pm_stopspeed = 100
static

Definition at line 50 of file pmove.c.

Referenced by PM_FlyMove(), and PM_Friction().

◆ pm_wateraccelerate

const float pm_wateraccelerate = 10
static

Definition at line 53 of file pmove.c.

Referenced by PM_WaterMove().

◆ pm_waterspeed

const float pm_waterspeed = 400
static

Definition at line 54 of file pmove.c.

Referenced by PM_AddCurrents().

◆ pml

◆ pmp

pmoveParams_t* pmp
static
PM_AddCurrents
static void PM_AddCurrents(vec3_t wishvel)
Definition: pmove.c:367
pm
static pmove_t * pm
Definition: pmove.c:44
PM_AirMove
static void PM_AirMove(void)
Definition: pmove.c:500
PM_SnapPosition
static void PM_SnapPosition(void)
Definition: pmove.c:978
PM_ClampAngles
static void PM_ClampAngles(void)
Definition: pmove.c:1095
PM_CheckJump
static void PM_CheckJump(void)
Definition: pmove.c:680
pml
static pml_t pml
Definition: pmove.c:45
pml_t::groundsurface
csurface_t * groundsurface
Definition: pmove.c:36
pml_t::frametime
float frametime
Definition: pmove.c:33
PM_StepSlideMove
static void PM_StepSlideMove(void)
Definition: pmove.c:213
pml_t::ladder
qboolean ladder
Definition: pmove.c:41
PM_AirAccelerate
static void PM_AirAccelerate(vec3_t wishdir, float wishspeed, float accel)
Definition: pmove.c:343
vec3_origin
vec3_t vec3_origin
Definition: shared.c:21
PM_DeadMove
static void PM_DeadMove(void)
Definition: pmove.c:934
pml_t::velocity
vec3_t velocity
Definition: pmove.c:30
PM_StepSlideMove_
static void PM_StepSlideMove_(void)
Definition: pmove.c:105
STEPSIZE
#define STEPSIZE
Definition: pmove.c:22
forward
static vec3_t forward
Definition: p_view.c:27
pml_t::origin
vec3_t origin
Definition: pmove.c:29
pml_t::right
vec3_t right
Definition: pmove.c:32
PM_Accelerate
static void PM_Accelerate(vec3_t wishdir, float wishspeed, float accel)
Definition: pmove.c:326
PM_FlyMove
static void PM_FlyMove(void)
Definition: pmove.c:790
pm_stopspeed
static const float pm_stopspeed
Definition: pmove.c:50
pml_t::forward
vec3_t forward
Definition: pmove.c:32
pm_waterspeed
static const float pm_waterspeed
Definition: pmove.c:54
PM_GoodPosition
static qboolean PM_GoodPosition(void)
Definition: pmove.c:954
PM_CategorizePosition
static void PM_CategorizePosition(void)
Definition: pmove.c:589
origin
static vec3_t origin
Definition: mesh.c:27
AngleVectors
void AngleVectors(vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
Definition: shared.c:23
PM_CheckSpecialMovement
static void PM_CheckSpecialMovement(void)
Definition: pmove.c:739
pm_accelerate
static const float pm_accelerate
Definition: pmove.c:52
PM_Friction
static void PM_Friction(void)
Definition: pmove.c:277
pml_t::groundplane
cplane_t groundplane
Definition: pmove.c:37
PM_WaterMove
static void PM_WaterMove(void)
Definition: pmove.c:459
PM_ClipVelocity
static void PM_ClipVelocity(vec3_t in, vec3_t normal, vec3_t out, float overbounce)
Definition: pmove.c:73
pm_wateraccelerate
static const float pm_wateraccelerate
Definition: pmove.c:53
pml_t::up
vec3_t up
Definition: pmove.c:32
MIN_STEP_NORMAL
#define MIN_STEP_NORMAL
Definition: pmove.c:103
up
static vec3_t up
Definition: p_view.c:27
PM_InitialSnapPosition
static void PM_InitialSnapPosition(void)
Definition: pmove.c:1063
STOP_EPSILON
#define STOP_EPSILON
Definition: pmove.c:71
int
CONST PIXELFORMATDESCRIPTOR int
Definition: wgl.c:26
MAX_CLIP_PLANES
#define MAX_CLIP_PLANES
Definition: pmove.c:104
PM_CheckDuck
static void PM_CheckDuck(void)
Definition: pmove.c:884
VectorNormalize
vec_t VectorNormalize(vec3_t v)
Definition: shared.c:55
pml_t::groundcontents
int groundcontents
Definition: pmove.c:38
pm_duckspeed
static const float pm_duckspeed
Definition: pmove.c:51
pmp
static pmoveParams_t * pmp
Definition: pmove.c:47
pml_t::previous_origin
vec3_t previous_origin
Definition: pmove.c:40