Xonotic
walk.qc
Go to the documentation of this file.
1 #include "walk.qh"
2 
3 void _Movetype_Physics_Walk(entity this, float dt) // SV_WalkMove
4 {
5  // if frametime is 0 (due to client sending the same timestamp twice), don't move
6  if (dt <= 0)
7  return;
8 
9  if (GAMEPLAYFIX_UNSTICKPLAYERS(this) == 1)
11 
12  bool applygravity = (!_Movetype_CheckWater(this) && this.move_movetype == MOVETYPE_WALK && !(this.flags & FL_WATERJUMP));
13 
15 
16  // do a regular slide move unless it looks like you ran into a step
17  bool oldonground = IS_ONGROUND(this);
18 
19  vector start_origin = this.origin;
20  vector start_velocity = this.velocity;
21 
22  if(PHYS_WALLCLIP(this) && this.pm_time)
23  {
24  if(dt >= this.pm_time || (this.flags & FL_WATERJUMP))
25  this.pm_time = 0;
26  else
27  this.pm_time -= dt;
28  }
29 
30  int clip = _Movetype_FlyMove(this, dt, applygravity, false, GAMEPLAYFIX_STEPMULTIPLETIMES(this) ? PHYS_STEPHEIGHT(this) : 0);
31 
32  if (GAMEPLAYFIX_DOWNTRACEONGROUND(this) && !(clip & 1))
33  {
34  // only try this if there was no floor in the way in the trace (no,
35  // this check seems to be not REALLY necessary, because if clip & 1,
36  // our trace will hit that thing too)
37  vector upmove = this.origin + '0 0 1';
38  vector downmove = this.origin - '0 0 1';
39  int type;
41  type = MOVE_MISSILE;
42  else if (this.move_movetype == MOVETYPE_FLY_WORLDONLY)
43  type = MOVE_WORLDONLY;
44  else if (this.solid == SOLID_TRIGGER || this.solid == SOLID_NOT)
45  type = MOVE_NOMONSTERS;
46  else type = MOVE_NORMAL;
47  tracebox(upmove, this.mins, this.maxs, downmove, type, this);
48  if (trace_fraction < 1 && trace_plane_normal.z > 0.7)
49  {
50  clip |= 1; // but we HAVE found a floor
51  // set groundentity so we get carried when walking onto a mover
52  this.groundentity = trace_ent;
53  }
54  }
55 
56  // if the move did not hit the ground at any point, we're not on ground
57  if (!(clip & 1))
58  UNSET_ONGROUND(this);
59  else if(PHYS_WALLCLIP(this) && !this.groundentity && (PHYS_WALLCLIP(this) == 2 || start_velocity.z < -200)) // don't do landing time if we were just going down a slope
60  this.pm_time = 0.25;
61 
63  _Movetype_LinkEdict(this, true);
64 
65  if (clip & 8) // teleport
66  return;
67 
68  if (this.flags & FL_WATERJUMP)
69  return;
70 
71  if (PHYS_NOSTEP(this))
72  return;
73 
74  vector originalorigin = this.origin;
75  vector originalvelocity = this.velocity;
76  // originalmove_clip = clip;
77  int originalflags = this.flags;
78  entity originalmove_groundentity = this.groundentity;
79 
80  // if move didn't block on a step, return
81  if (clip & 2)
82  {
83  // if move was not trying to move into the step, return
84  if (fabs(start_velocity.x) < 0.03125 && fabs(start_velocity.y) < 0.03125)
85  return;
86 
87  if (this.move_movetype != MOVETYPE_FLY)
88  {
89  // return if gibbed by a trigger
90  if (this.move_movetype != MOVETYPE_WALK)
91  return;
92 
93  // return if attempting to jump while airborn (unless sv_jumpstep)
94  if (!PHYS_JUMPSTEP(this))
95  if (!oldonground && this.waterlevel == 0)
96  return;
97  }
98 
99  // try moving up and forward to go up a step
100  // back to start pos
101  this.origin = start_origin;
102  this.velocity = start_velocity;
103 
104  // move up
105  vector upmove = '0 0 1' * PHYS_STEPHEIGHT(this);
106  if(!_Movetype_PushEntity(this, upmove, true, true))
107  {
108  // we got teleported when upstepping... must abort the move
109  return;
110  }
111 
112  // move forward
113  this.velocity_z = 0;
114  clip = _Movetype_FlyMove(this, dt, applygravity, true, 0);
115  this.velocity_z += start_velocity.z;
116  if (clip & 8)
117  {
118  // we got teleported when upstepping... must abort the move
119  // note that z velocity handling may not be what QC expects here, but we cannot help it
120  return;
121  }
122 
124  _Movetype_LinkEdict(this, true);
125 
126  // check for stuckness, possibly due to the limited precision of floats
127  // in the clipping hulls
128  if (clip
129  && fabs(originalorigin.y - this.origin.y) < 0.03125
130  && fabs(originalorigin.x - this.origin.x) < 0.03125)
131  {
132  // Con_Printf("wall\n");
133  // stepping up didn't make any progress, revert to original move
134  this.origin = originalorigin;
135  this.velocity = originalvelocity;
136  // clip = originalmove_clip;
137  this.flags = originalflags;
138  this.groundentity = originalmove_groundentity;
139  // now try to unstick if needed
140  // clip = SV_TryUnstick (ent, oldvel);
141  return;
142  }
143 
144  // Con_Printf("step - ");
145 
146  // extra friction based on view angle
147  if ((clip & 2) && PHYS_WALLFRICTION(this))
149  }
150  // don't do the down move if stepdown is disabled, moving upward, not in water, or the move started offground or ended onground
151  else if (!GAMEPLAYFIX_STEPDOWN(this) || this.waterlevel >= 3 || start_velocity.z >= (1.0 / 32.0)
152  || !oldonground || IS_ONGROUND(this) || (GAMEPLAYFIX_STEPDOWN_MAXSPEED(this) && vdist(start_velocity, >=, GAMEPLAYFIX_STEPDOWN_MAXSPEED(this)) && !IS_ONSLICK(this)))
153  {
154  return;
155  }
156 
157  // move down
158  vector downmove = '0 0 0';
159  downmove.z = -PHYS_STEPHEIGHT(this) + start_velocity.z * dt;
160  if(!_Movetype_PushEntity(this, downmove, true, true))
161  {
162  // we got teleported when downstepping... must abort the move
163  return;
164  }
165 
166  if (trace_fraction < 1 && trace_plane_normal.z > 0.7)
167  {
168  // this has been disabled so that you can't jump when you are stepping
169  // up while already jumping (also known as the Quake2 double jump bug)
170  // LordHavoc: disabled this check so you can walk on monsters/players
171  //if (PRVM_serveredictfloat(ent, solid) == SOLID_BSP)
172  if(GAMEPLAYFIX_STEPDOWN(this) == 2)
173  {
174  SET_ONGROUND(this);
175  this.groundentity = trace_ent;
176  }
177  }
178  else
179  {
180  // Con_Printf("slope\n");
181  // if the push down didn't end up on good ground, use the move without
182  // the step up. This happens near wall / slope combinations, and can
183  // cause the player to hop up higher on a slope too steep to climb
184  this.origin = originalorigin;
185  this.velocity = originalvelocity;
186  this.flags = originalflags;
187  this.groundentity = originalmove_groundentity;
188  }
189 
191  _Movetype_LinkEdict(this, true);
192 }
const float SOLID_NOT
Definition: csprogsdefs.qc:244
#define PHYS_WALLCLIP(s)
Definition: movetypes.qh:43
#define GAMEPLAYFIX_DOWNTRACEONGROUND(s)
Definition: movetypes.qh:23
float MOVETYPE_WALK
Definition: progsdefs.qc:249
#define GAMEPLAYFIX_STEPMULTIPLETIMES(s)
Definition: movetypes.qh:27
float waterlevel
Definition: progsdefs.qc:181
bool _Movetype_CheckWater(entity this)
Definition: movetypes.qc:345
entity() spawn
vector move_stepnormal
Definition: movetypes.qh:103
const float MOVE_NORMAL
Definition: csprogsdefs.qc:252
#define IS_ONGROUND(s)
Definition: movetypes.qh:16
vector maxs
Definition: csprogsdefs.qc:113
#define GAMEPLAYFIX_UNSTICKPLAYERS(s)
Definition: movetypes.qh:28
#define PHYS_JUMPSTEP(s)
Definition: movetypes.qh:40
origin
Definition: ent_cs.qc:114
void _Movetype_CheckStuck(entity this)
Definition: movetypes.qc:649
#define UNSET_ONGROUND(s)
Definition: movetypes.qh:18
float move_movetype
Definition: movetypes.qh:76
entity trace_ent
Definition: csprogsdefs.qc:40
float pm_time
Definition: movetypes.qh:74
entity groundentity
Definition: movetypes.qh:93
const float MOVE_MISSILE
Definition: csprogsdefs.qc:254
const float MOVE_NOMONSTERS
Definition: csprogsdefs.qc:253
vector mins
Definition: csprogsdefs.qc:113
float MOVETYPE_FLY_WORLDONLY
void _Movetype_LinkEdict(entity this, bool touch_triggers)
Definition: movetypes.qc:512
void _Movetype_Physics_Walk(entity this, float dt)
Definition: walk.qc:3
#define IS_ONSLICK(s)
Definition: movetypes.qh:19
int _Movetype_FlyMove(entity this, float dt, bool applygravity, bool applystepnormal, float stepheight)
Definition: movetypes.qc:124
#define GAMEPLAYFIX_STEPDOWN(s)
Definition: movetypes.qh:25
vector(float skel, float bonenum) _skel_get_boneabs_hidden
float MOVETYPE_FLYMISSILE
Definition: progsdefs.qc:255
float flags
Definition: csprogsdefs.qc:129
#define SET_ONGROUND(s)
Definition: movetypes.qh:17
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition: vector.qh:8
const float SOLID_TRIGGER
Definition: csprogsdefs.qc:245
float MOVE_WORLDONLY
#define PHYS_WALLFRICTION(s)
Definition: movetypes.qh:41
bool _Movetype_PushEntity(entity this, vector push, bool failonstartsolid, bool dolink)
Definition: movetypes.qc:697
#define PHYS_STEPHEIGHT(s)
Definition: movetypes.qh:38
void _Movetype_CheckVelocity(entity this)
Definition: movetypes.qc:339
vector velocity
Definition: csprogsdefs.qc:103
void _Movetype_WallFriction(entity this, vector stepnormal)
Definition: movetypes.qc:106
#define GAMEPLAYFIX_STEPDOWN_MAXSPEED(s)
Definition: movetypes.qh:26
float MOVETYPE_FLY
Definition: progsdefs.qc:251
#define PHYS_NOSTEP(s)
Definition: movetypes.qh:39
float FL_WATERJUMP
Definition: progsdefs.qc:242
float solid
Definition: csprogsdefs.qc:99