Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
physics.qc
Go to the documentation of this file.
1#include "physics.qh"
2
4
5void sys_phys_simulate(entity this, float dt);
6void sys_phys_simulate_simple(entity this, float dt);
7
9
10void sys_phys_update(entity this, float dt)
11{
12 if (!IS_CLIENT(this))
13 {
15 return;
16 }
17
18 sys_phys_fix(this, dt);
19 if (sys_phys_override(this, dt))
20 return;
21
22 sys_phys_monitor(this, dt);
23
24 PHYS_CS(this).movement_old = PHYS_CS(this).movement;
25 PHYS_CS(this).v_angle_old = this.v_angle;
26 PHYS_CS(this).buttons_old = PHYS_INPUT_BUTTON_MASK(this);
27
28 sys_phys_ai(this);
29
31
32 if (IS_SVQC)
33 {
34 if (this.move_movetype == MOVETYPE_NONE)
35 return;
36 // when we get here, disableclientprediction cannot be 2
37 if(this.move_movetype == MOVETYPE_FOLLOW) // not compatible with prediction
39 else if(this.move_qcphysics)
41 else
43 }
44
46
47 PM_check_frozen(this);
48
49 PM_check_blocked(this);
50
51 float maxspeed_mod = 1;
52
53 // conveyors: first fix velocity
54 if (this.conveyor.active)
55 this.velocity -= this.conveyor.movedir;
56 MUTATOR_CALLHOOK(PlayerPhysics, this, dt);
57
58 if (!IS_PLAYER(this))
59 {
61 maxspeed_mod = STAT(SPECTATORSPEED, this);
62 }
63 sys_phys_fixspeed(this, maxspeed_mod);
64
65 if (IS_DEAD(this))
66 {
67 // handle water here
68 vector midpoint = ((this.absmin + this.absmax) * 0.5);
69 int cont = pointcontents(midpoint);
70 if (cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME)
71 {
72 this.velocity = this.velocity * 0.5;
73
74 // do we want this?
75 // if(pointcontents(midpoint + '0 0 2') == CONTENT_WATER)
76 // { this.velocity_z = 70; }
77 }
79 return;
80 }
81
82 PM_check_slick(this);
83
84 if (IS_SVQC && !PHYS_FIXANGLE(this))
85 this.angles = eY * this.v_angle.y;
86 if (IS_PLAYER(this))
87 {
88 if (IS_ONGROUND(this))
89 {
91 PM_Footsteps(this);
92 }
93 else if (IsFlying(this))
94 this.wasFlying = true;
95 CheckPlayerJump(this);
96 }
97
98 if (this.flags & FL_WATERJUMP)
99 {
100 this.velocity_x = this.movedir.x;
101 this.velocity_y = this.movedir.y;
102 if (time > this.teleport_time || this.waterlevel == WATERLEVEL_NONE)
103 {
104 this.flags &= ~FL_WATERJUMP;
105 this.teleport_time = 0;
106 }
107 }
108 else if (MUTATOR_CALLHOOK(PM_Physics, this, maxspeed_mod, dt))
109 { /* handled */ }
110 else if (this.move_movetype == MOVETYPE_NOCLIP
111 || this.move_movetype == MOVETYPE_FLY
113 || MUTATOR_CALLHOOK(IsFlying, this))
114 {
115 this.com_phys_friction = PHYS_FRICTION(this);
116 this.com_phys_vel_max = PHYS_MAXSPEED(this) * maxspeed_mod;
117 this.com_phys_acc_rate = PHYS_ACCELERATE(this) * maxspeed_mod;
118 this.com_phys_friction_air = true;
119 sys_phys_simulate(this, dt);
120 this.com_phys_friction_air = false;
121 }
122 else if (this.waterlevel >= WATERLEVEL_SWIMMING)
123 {
124 this.com_phys_vel_max = PHYS_MAXSPEED(this) * maxspeed_mod;
125 this.com_phys_acc_rate = PHYS_ACCELERATE(this) * maxspeed_mod;
126 this.com_phys_water = true;
127 sys_phys_simulate(this, dt);
128 this.com_phys_water = false;
129 this.jumppadcount = 0;
130 }
131 else if (this.ladder_entity)
132 {
133 this.com_phys_friction = PHYS_FRICTION(this);
134 this.com_phys_vel_max = PHYS_MAXSPEED(this) * maxspeed_mod;
135 this.com_phys_acc_rate = PHYS_ACCELERATE(this) * maxspeed_mod;
136 this.com_phys_gravity = -PHYS_GRAVITY(this) * dt;
137 if (PHYS_ENTGRAVITY(this))
138 this.com_phys_gravity *= PHYS_ENTGRAVITY(this);
139 this.com_phys_ladder = true;
140 this.com_phys_friction_air = true;
141 sys_phys_simulate(this, dt);
142 this.com_phys_friction_air = false;
143 this.com_phys_ladder = false;
144 this.com_phys_gravity = 0;
145 }
146 else if (ITEMS_STAT(this) & IT_USING_JETPACK)
147 PM_jetpack(this, maxspeed_mod, dt);
148 else if (IS_ONGROUND(this) && (!IS_ONSLICK(this) || !PHYS_SLICK_APPLYGRAVITY(this)))
149 {
150 if (!WAS_ONGROUND(this))
151 {
152 emit(phys_land, this);
153 if (this.lastground < time - 0.3)
154 this.velocity *= (1 - PHYS_FRICTION_ONLAND(this));
155 }
156 this.com_phys_vel_max = PHYS_MAXSPEED(this) * maxspeed_mod;
157 this.com_phys_gravity = -PHYS_GRAVITY(this) * dt;
158 if (PHYS_ENTGRAVITY(this))
159 this.com_phys_gravity *= PHYS_ENTGRAVITY(this);
160 this.com_phys_ground = true;
161 this.com_phys_vel_2d = true;
162 sys_phys_simulate(this, dt);
163 this.com_phys_vel_2d = false;
164 this.com_phys_ground = false;
165 this.com_phys_gravity = 0;
166 }
167 else
168 {
169 this.com_phys_acc_rate_air = PHYS_AIRACCELERATE(this) * min(maxspeed_mod, 1);
170 this.com_phys_acc_rate_air_stop = PHYS_AIRSTOPACCELERATE(this) * maxspeed_mod;
171 this.com_phys_acc_rate_air_strafe = PHYS_AIRSTRAFEACCELERATE(this) * maxspeed_mod;
172 this.com_phys_vel_max_air_strafe = PHYS_MAXAIRSTRAFESPEED(this) * maxspeed_mod;
173 this.com_phys_vel_max_air = PHYS_MAXAIRSPEED(this) * maxspeed_mod;
174 this.com_phys_vel_max = PHYS_MAXAIRSPEED(this) * min(maxspeed_mod, 1);
175 this.com_phys_air = true;
176 this.com_phys_vel_2d = true;
177 sys_phys_simulate(this, dt);
178 this.com_phys_vel_2d = false;
179 this.com_phys_air = false;
180 }
181
183}
184
186{
187 if (IS_ONGROUND(this))
188 this.lastground = time;
189 // conveyors: then break velocity again
190 if (this.conveyor.active)
191 this.velocity += this.conveyor.movedir;
192 this.lastflags = this.flags;
193
194 this.lastclassname = this.classname;
195}
196
198void sys_phys_simulate(entity this, float dt)
199{
200 if (!this.com_phys_ground && !this.com_phys_air)
201 {
202 // noclipping
203 // flying
204 // on a spawnfunc_func_ladder
205 // swimming in spawnfunc_func_water
206 // swimming
207 UNSET_ONGROUND(this);
208
209 if (this.com_phys_friction_air > 0)
210 {
211 const float grav = -this.com_phys_gravity;
212 this.velocity_z += grav / 2;
213 this.velocity = this.velocity * (1 - dt * this.com_phys_friction);
214 this.velocity_z += grav / 2;
215 }
216 }
217
218 if (this.com_phys_water)
219 {
220 // water jump only in certain situations
221 // this mimics quakeworld code
222 if (PHYS_INPUT_BUTTON_JUMP(this)
224 && this.velocity_z >= -180
225 && !this.viewloc
226 && !PHYS_FROZEN(this))
227 {
228 vector yawangles = eY * this.v_angle.y;
229 vector forward, right, up;
230 MAKE_VECTORS(yawangles, forward, right, up);
231 vector spot = this.origin + 24 * forward;
232 spot_z += 8;
233 traceline(spot, spot, MOVE_NOMONSTERS, this);
235 {
236 spot_z += 24;
237 traceline(spot, spot, MOVE_NOMONSTERS, this);
238 if (!trace_startsolid)
239 {
240 this.velocity = forward * 50;
241 this.velocity_z = 310;
242 UNSET_ONGROUND(this);
243 SET_JUMP_HELD(this);
244 }
245 }
246 }
247 }
248
249 vector forward, right, up;
250 vector v_tmp = (this.com_phys_vel_2d ? vec3(0, this.v_angle.y, 0) : this.v_angle);
251 MAKE_VECTORS(v_tmp, forward, right, up);
252 // wishvel = forward * PHYS_CS(this).movement.x + right * PHYS_CS(this).movement.y + up * PHYS_CS(this).movement.z;
253 vector wishvel = forward * PHYS_CS(this).movement.x
254 + right * PHYS_CS(this).movement.y
255 + eZ * (this.com_phys_vel_2d ? 0 : PHYS_CS(this).movement.z);
256 if (this.com_phys_water)
257 {
258 if (PHYS_FROZEN(this))
259 {
260 if(this.waterlevel >= WATERLEVEL_SUBMERGED && this.velocity.z >= -70) // don't change the speed too abruptally
261 wishvel = '0 0 160'; // resurface
262 else if(this.waterlevel >= WATERLEVEL_SWIMMING && this.velocity.z > 0)
263 wishvel = eZ * (1.3 * min(this.velocity.z, 160)); // resurface a bit more above the surface
264 }
265 else
266 {
267 if (PHYS_INPUT_BUTTON_CROUCH(this))
268 wishvel.z = -PHYS_MAXSPEED(this);
269 if (this.viewloc)
270 wishvel.z = -160; // drift anyway
271 else if (wishvel == '0 0 0')
272 wishvel.z = -60; // drift towards bottom
273 }
274 }
275 if (this.com_phys_ladder)
276 {
277 if (this.viewloc)
278 wishvel.z = PHYS_CS(this).movement_old.x;
279
280 if (this.ladder_entity.classname == "func_water")
281 {
282 float f = vlen(wishvel);
283 if (f > this.ladder_entity.speed)
284 wishvel *= (this.ladder_entity.speed / f);
285
286 this.watertype = this.ladder_entity.skin;
287 f = this.ladder_entity.origin_z + this.ladder_entity.maxs_z;
288 if ((this.origin_z + this.view_ofs_z) < f)
290 else if ((this.origin_z + (this.mins_z + this.maxs_z) * 0.5) < f)
292 else if ((this.origin_z + this.mins_z + 1) < f)
294 else
295 {
298 }
299 }
300 }
301
302 // acceleration
303 float wishspeed = vlen(wishvel);
304 // Mathematically equivalent to normalize(wishvel) but more closely matches Q3
305 // which uses the same single-precision optimisation to save one sqrt()
306 const vector wishdir = wishspeed ? wishvel * (1 / wishspeed) : '0 0 0';
307 wishspeed = min(wishspeed, this.com_phys_vel_max);
308
309 if (this.com_phys_air)
310 {
311 // apply air speed limit
312 float airaccelqw = PHYS_AIRACCEL_QW(this);
313 float wishspeed0 = wishspeed;
314 const float maxairspd = this.com_phys_vel_max;
315 wishspeed = min(wishspeed, maxairspd);
316 if (IS_DUCKED(this))
317 wishspeed *= 0.5;
318
319 float airaccel = this.com_phys_acc_rate_air;
320
321 float accelerating = (this.velocity * wishdir > 0);
322 float wishspeed2 = wishspeed;
323
324 // CPM: air control
325 if (PHYS_AIRSTOPACCELERATE(this))
326 {
327 const float dot = normalize(vec2(this.velocity)) * wishdir;
328 if (dot < 0)
329 {
331 airaccel = this.com_phys_acc_rate_air_stop; // full slow-down
332 else
333 airaccel += (airaccel - this.com_phys_acc_rate_air_stop) * dot; // sinusoidal slow-down
334 }
335 }
336 // note that for straight forward jumping:
337 // step = accel * dt * wishspeed0;
338 // accel = bound(0, wishspeed - vel_xy_current, step) * accelqw + step * (1 - accelqw);
339 // -->
340 // dv/dt = accel * maxspeed (when slow)
341 // dv/dt = accel * maxspeed * (1 - accelqw) (when fast)
342 // log dv/dt = logaccel + logmaxspeed (when slow)
343 // log dv/dt = logaccel + logmaxspeed + log(1 - accelqw) (when fast)
344 float strafity = IsMoveInDirection(PHYS_CS(this).movement, -90) + IsMoveInDirection(PHYS_CS(this).movement, +90); // if one is nonzero, other is always zero
345 if (PHYS_MAXAIRSTRAFESPEED(this))
346 wishspeed = min(wishspeed, GeomLerp(this.com_phys_vel_max_air,
347 strafity,
349
350 if (PHYS_AIRSTRAFEACCELERATE(this))
351 airaccel = GeomLerp(airaccel, strafity, this.com_phys_acc_rate_air_strafe);
352
353 if (PHYS_AIRSTRAFEACCEL_QW(this))
354 airaccelqw =
355 (((strafity > 0.5 ? PHYS_AIRSTRAFEACCEL_QW(this) : PHYS_AIRACCEL_QW(this)) >= 0) ? +1 : -1)
356 *
357 (1 - GeomLerp(1 - fabs(PHYS_AIRACCEL_QW(this)), strafity, 1 - fabs(PHYS_AIRSTRAFEACCEL_QW(this))));
358 // !CPM
359
360 if (PHYS_WARSOWBUNNY_TURNACCEL(this) && accelerating && PHYS_CS(this).movement.y == 0 && PHYS_CS(this).movement.x != 0)
361 PM_AirAccelerate(this, dt, wishdir, wishspeed2);
362 else
363 {
364 float sidefric = maxairspd ? (PHYS_AIRACCEL_SIDEWAYS_FRICTION(this) / maxairspd) : 0;
365 PM_Accelerate(this, dt, wishdir, wishspeed, wishspeed0, airaccel, airaccelqw,
367 }
368
369 if (PHYS_AIRCONTROL(this))
370 CPM_PM_Aircontrol(this, dt, wishdir, wishspeed2);
371 }
372 else
373 {
374 if (this.com_phys_ground && IS_DUCKED(this))
375 wishspeed *= 0.5;
376
377 if (this.com_phys_water)
378 {
379 wishspeed *= 0.7;
380
381 // if (!(this.flags & FL_WATERJUMP)) // TODO: use
382 {
383 // water friction
384 float f = 1 - dt * PHYS_FRICTION(this);
385 this.velocity *= bound(0, f, 1);
386
387 f = wishspeed - this.velocity * wishdir;
388 if (f > 0)
389 {
390 float accelspeed = min(PHYS_ACCELERATE(this) * dt * wishspeed, f);
391 this.velocity += accelspeed * wishdir;
392 }
393
394 // holding jump button swims upward slowly
395 if (PHYS_INPUT_BUTTON_JUMP(this) && !this.viewloc && !PHYS_FROZEN(this))
396 {
397 // was:
398 // lava: 50
399 // slime: 80
400 // water: 100
401 // idea: double those
403 this.velocity_z = PHYS_MAXSPEED(this) * 0.7;
404 else
405 this.velocity_z = 200;
406 }
407 }
408 if (this.viewloc)
409 {
410 const float addspeed = wishspeed - this.velocity * wishdir;
411 if (addspeed > 0)
412 {
413 const float accelspeed = min(PHYS_ACCELERATE(this) * dt * wishspeed, addspeed);
414 this.velocity += accelspeed * wishdir;
415 }
416 }
417 else
418 {
419 // water acceleration
420 PM_Accelerate(this, dt, wishdir, wishspeed, wishspeed, this.com_phys_acc_rate, 1, 0, 0, 0);
421 }
422 return;
423 }
424 if (this.com_phys_ground)
425 {
426 // apply edge friction
427 const float f2 = vlen2(vec2(this.velocity));
428 const int realfriction = (IS_ONSLICK(this))
429 ? PHYS_FRICTION_SLICK(this)
430 : PHYS_FRICTION(this);
431 if (f2 > 0 && realfriction > 0)
432 {
433 // TODO: apply edge friction
434 // apply ground friction
435
436 float f = sqrt(f2);
437 const float S = PHYS_STOPSPEED(this);
438 //f = 1 - dt * realfriction * ((f < S) ? (S / f) : 1);
439 // k9er: documentation here https://gitlab.com/otta8634/xonotic-physics
440 const float dt_r = PHYS_FRICTION_REPLICA_DT;
441 // minor optimization, but it's only useful if friction > 1/dt_r
442 //if (realfriction * dt_r >= 1)
443 // f = 0;
444 //else
445 {
446 const float independent_geometric = (1 - realfriction * dt_r) ** (dt / dt_r);
447 // NOTE: first condition ensures subframe accuracy in the geometric -> linear transition, may be not worth the hassle
448 if (S < f && f < S / independent_geometric)
449 {
450 this.velocity = normalize(this.velocity);
451 f = S - S * realfriction * (dt - (dt_r * log(S / f)) / log(1 - realfriction * dt_r));
452 }
453 else if (f >= S)
454 f = independent_geometric;
455 else
456 f = 1 - realfriction * dt * S / f;
457 f = max(0, f);
458 }
459 this.velocity *= f;
460 }
461 const float addspeed = wishspeed - this.velocity * wishdir;
462 if (addspeed > 0)
463 {
464 const float accel = (IS_ONSLICK(this))
466 : PHYS_ACCELERATE(this);
467 const float accelspeed = min(accel * dt * wishspeed, addspeed);
468 this.velocity += accelspeed * wishdir;
469 }
470 return;
471 }
472
473 // MOVETYPE_NOCLIP, MOVETYPE_FLY, and ladders
474 PM_Accelerate(this, dt, wishdir, wishspeed, wishspeed, this.com_phys_acc_rate, 1, 0, 0, 0);
475 }
476}
477
481{
482 vector mn = this.mins;
483 vector mx = this.maxs;
484
485 vector g = '0 0 0';
486 if (this.com_phys_gravity_factor && !g)
487 g = '0 0 -1' * PHYS_GRAVITY(NULL);
488
489 vector vel = this.com_phys_vel;
490 vector pos = this.com_phys_pos;
491
492 // SV_Physics_Toss
493
494 vel += g * dt;
495
496 this.angles += dt * this.avelocity;
497 float movetime = dt;
498 for (int i = 0; i < MAX_CLIP_PLANES && movetime > 0; ++i)
499 {
500 vector push = vel * movetime;
501 vector p0 = pos;
502 vector p1 = p0 + push;
503 // SV_PushEntity
504 tracebox(p0, mn, mx, p1, MOVE_NORMAL, this);
505 if (!trace_startsolid)
506 {
507 bool hit = trace_fraction < 1;
508 pos = trace_endpos;
509 entity ent = trace_ent;
510 // SV_LinkEdict_TouchAreaGrid
511 if (this.solid != SOLID_NOT)
512 {
513 FOREACH_ENTITY_RADIUS_ORDERED(0.5 * (this.absmin + this.absmax), 0.5 * vlen(this.absmax - this.absmin), true,
514 {
515 if (it.solid != SOLID_TRIGGER || it == this)
516 continue;
517 if (gettouch(it) && boxesoverlap(it.absmin, it.absmax, this.absmin, this.absmax))
518 {
519 // SV_LinkEdict_TouchAreaGrid_Call
520 trace_allsolid = false;
521 trace_startsolid = false;
522 trace_fraction = 1;
523 trace_inwater = false;
524 trace_inopen = true;
525 trace_endpos = it.origin;
526 trace_plane_normal = '0 0 1';
528 trace_ent = this;
533 gettouch(it)(this, it);
534 vel = this.velocity;
535 }
536 });
537 }
538 if (hit && this.solid >= SOLID_TRIGGER && (!IS_ONGROUND(this) || this.groundentity != ent))
539 {
540 // SV_Impact (ent, trace);
541 tracebox(p0, mn, mx, p1, MOVE_NORMAL, this);
542 void(entity, entity) touched = gettouch(this);
543 if (touched && this.solid != SOLID_NOT)
544 touched(ent, this);
545
546 void(entity, entity) touched2 = gettouch(ent);
547 if (this && ent && touched2 && ent.solid != SOLID_NOT)
548 {
549 trace_endpos = ent.origin;
550 trace_plane_normal *= -1;
551 trace_plane_dist *= -1;
552 trace_ent = this;
557 touched2(this, ent);
558 }
559 }
560 }
561 // end SV_PushEntity
562 if (wasfreed(this))
563 return;
564 tracebox(p0, mn, mx, p1, MOVE_NORMAL, this);
565 if (trace_fraction == 1)
566 break;
567 movetime *= 1 - min(1, trace_fraction);
568 ClipVelocity(vel, trace_plane_normal, vel, 1);
569 }
570
571 this.com_phys_vel = vel;
572 this.com_phys_pos = pos;
573 setorigin(this, this.com_phys_pos);
574}
575
#define MUTATOR_CALLHOOK(id,...)
Definition base.qh:143
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
bool sys_phys_override(entity this, float dt)
Definition cl_physics.qc:13
void sys_phys_monitor(entity this, float dt)
Definition cl_physics.qc:19
void sys_phys_ai(entity this)
Definition cl_physics.qc:21
void sys_phys_spectator_control(entity this)
Definition cl_physics.qc:25
void sys_phys_pregame_hold(entity this)
Definition cl_physics.qc:23
void sys_phys_fixspeed(entity this, float maxspeed_mod)
Definition cl_physics.qc:27
void sys_phys_fix(entity this, float dt)
Definition cl_physics.qc:3
const int IT_USING_JETPACK
Definition item.qh:27
void PM_check_hitground(entity this)
Definition player.qc:656
void PM_jetpack(entity this, float maxspd_mod, float dt)
Definition player.qc:727
void PM_check_blocked(entity this)
Definition player.qc:715
void PM_check_frozen(entity this)
Definition player.qc:641
void CPM_PM_Aircontrol(entity this, float dt, vector wishdir, float wishspeed)
Definition player.qc:225
void CheckPlayerJump(entity this)
Definition player.qc:526
float GeomLerp(float a, float _lerp, float b)
Definition player.qc:154
void PM_check_slick(entity this)
Definition player.qc:702
float IsMoveInDirection(vector mv, float ang)
Definition player.qc:145
bool IsFlying(entity this)
Definition player.qc:836
void PM_Accelerate(entity this, float dt, vector wishdir, float wishspeed, float wishspeed0, float accel, float accelqw, float stretchfactor, float sidefric, float speedlimit)
Definition player.qc:271
void PM_AirAccelerate(entity this, float dt, vector wishdir, float wishspeed)
Definition player.qc:335
void PM_Footsteps(entity this)
Definition player.qc:681
#define PHYS_INPUT_BUTTON_CROUCH(s)
Definition player.qh:154
#define PHYS_AIRSTRAFEACCEL_QW(s)
Definition player.qh:108
#define PHYS_FRICTION_SLICK(s)
Definition player.qh:116
vector movement
Definition player.qh:229
string lastclassname
Definition player.qh:70
#define PHYS_CS(s)
Definition player.qh:258
#define IS_CLIENT(s)
Definition player.qh:242
#define IS_DEAD(s)
Definition player.qh:245
#define PHYS_MAXAIRSTRAFESPEED(s)
Definition player.qh:135
int lastflags
Definition player.qh:63
#define PHYS_INPUT_BUTTON_JUMP(s)
Definition player.qh:151
vector v_angle
Definition player.qh:237
#define PHYS_AIRACCELERATE(s)
Definition player.qh:95
#define WAS_ONGROUND(s)
Definition player.qh:207
float teleport_time
Definition player.qh:216
#define PHYS_STOPSPEED(s)
Definition player.qh:138
#define PHYS_FRICTION(s)
Definition player.qh:114
float watertype
Definition player.qh:225
float waterlevel
Definition player.qh:226
#define ITEMS_STAT(s)
Definition player.qh:214
#define PHYS_MAXAIRSPEED(s)
Definition player.qh:134
#define PHYS_AIRACCEL_QW(s)
Definition player.qh:97
#define PHYS_AIRSPEEDLIMIT_NONQW(s)
Definition player.qh:104
#define PHYS_AIRSTRAFEACCELERATE(s)
Definition player.qh:107
bool wasFlying
Definition player.qh:65
#define PHYS_SLICKACCELERATE(s)
Definition player.qh:96
#define PHYS_FIXANGLE(s)
Definition player.qh:220
#define PHYS_FROZEN(s)
Definition player.qh:118
#define PHYS_ACCELERATE(s)
Definition player.qh:94
#define IS_DUCKED(s)
Definition player.qh:210
#define PHYS_AIRACCEL_SIDEWAYS_FRICTION(s)
Definition player.qh:99
float lastground
Definition player.qh:64
#define PHYS_MAXSPEED(s)
Definition player.qh:136
#define PHYS_AIRSTOPACCELERATE_FULL(s)
Definition player.qh:106
#define PHYS_AIRACCEL_QW_STRETCHFACTOR(s)
Definition player.qh:98
#define IS_PLAYER(s)
Definition player.qh:243
#define PHYS_FRICTION_REPLICA_DT
Definition player.qh:342
#define PHYS_AIRSTOPACCELERATE(s)
Definition player.qh:105
#define PHYS_WARSOWBUNNY_TURNACCEL(s)
Definition player.qh:146
#define PHYS_FRICTION_ONLAND(s)
Definition player.qh:115
entity conveyor
Definition player.qh:57
#define SET_JUMP_HELD(s)
Definition player.qh:204
#define PHYS_AIRCONTROL(s)
Definition player.qh:100
#define PHYS_SLICK_APPLYGRAVITY(s)
Definition player.qh:148
#define PHYS_INPUT_BUTTON_MASK(s)
Definition player.qh:189
const int FL_WATERJUMP
Definition constants.qh:80
string classname
float flags
const float MOVE_NOMONSTERS
float trace_dphitcontents
entity trace_ent
const float SOLID_TRIGGER
vector avelocity
float frametime
const float MOVE_NORMAL
vector mins
float trace_dpstartcontents
vector velocity
const float CONTENT_WATER
const float SOLID_NOT
string trace_dphittexturename
float time
vector trace_endpos
float trace_startsolid
vector maxs
float log(float f)
float trace_inopen
float trace_dphitq3surfaceflags
vector absmax
vector origin
float trace_fraction
vector absmin
const float CONTENT_LAVA
float trace_allsolid
const float CONTENT_EMPTY
vector trace_plane_normal
float trace_plane_dist
float trace_inwater
const float CONTENT_SLIME
#define MAKE_VECTORS(angles, forward, right, up)
Same as the makevectors builtin but uses the provided locals instead of the v_* globals.
float disableclientprediction
float com_phys_acc_rate_air_strafe
Definition physics.qh:12
float com_phys_acc_rate_air
Definition physics.qh:11
float com_phys_gravity
Definition physics.qh:16
float com_phys_acc_rate
Definition physics.qh:10
float com_phys_vel_max
Definition physics.qh:7
bool com_phys_vel_2d
Definition physics.qh:22
bool com_phys_air
Definition physics.qh:20
bool com_phys_water
Definition physics.qh:23
float com_phys_gravity_factor
Definition physics.qh:17
bool move_qcphysics
Definition physics.qh:25
bool com_phys_ladder
Definition physics.qh:21
vector com_phys_vel
Definition physics.qh:6
vector com_phys_pos
Definition physics.qh:4
float com_phys_friction
Definition physics.qh:14
float com_phys_vel_max_air
Definition physics.qh:8
bool com_phys_ground
Definition physics.qh:19
float com_phys_vel_max_air_strafe
Definition physics.qh:9
float com_phys_acc_rate_air_stop
Definition physics.qh:13
bool com_phys_friction_air
Definition physics.qh:24
void sys_phys_update(entity this, float dt)
Definition physics.qc:10
void sys_phys_update_single(entity this)
Definition physics.qc:576
void sys_phys_simulate(entity this, float dt)
for players
Definition physics.qc:198
void sys_phys_simulate_simple(entity this, float dt)
for other entities
Definition physics.qc:480
void sys_phys_postupdate(entity this)
Definition physics.qc:185
ent angles
Definition ent_cs.qc:121
solid
Definition ent_cs.qc:165
#define FOREACH_ENTITY_RADIUS_ORDERED(org, dist, cond, body)
Definition iter.qh:164
float jumppadcount
Definition jumppads.qh:28
entity ladder_entity
Definition ladder.qh:11
#define IS_SVQC
Definition _all.inc:12
#define STAT(...)
Definition stats.qh:82
#define emit(T,...)
Definition lib.qh:17
vector movedir
Definition viewloc.qh:18
entity viewloc
Definition viewloc.qh:13
float bound(float min, float value, float max)
float vlen(vector v)
float sqrt(float f)
float min(float f,...)
vector normalize(vector v)
float fabs(float f)
float max(float f,...)
const int MOVETYPE_NONE
Definition movetypes.qh:129
const int WATERLEVEL_SWIMMING
Definition movetypes.qh:13
const int WATERLEVEL_WETFEET
Definition movetypes.qh:12
const int WATERLEVEL_SUBMERGED
Definition movetypes.qh:14
const int MOVETYPE_FOLLOW
Definition movetypes.qh:141
const int WATERLEVEL_NONE
Definition movetypes.qh:11
#define PHYS_GRAVITY(s)
Definition movetypes.qh:53
#define IS_ONSLICK(s)
Definition movetypes.qh:19
entity groundentity
Definition movetypes.qh:93
const int MOVETYPE_FLY_WORLDONLY
Definition movetypes.qh:143
float move_movetype
Definition movetypes.qh:76
#define UNSET_ONGROUND(s)
Definition movetypes.qh:18
const int MOVETYPE_NOCLIP
Definition movetypes.qh:137
const int MOVETYPE_FLY
Definition movetypes.qh:134
#define PHYS_ENTGRAVITY(s)
Definition movetypes.qh:55
#define IS_ONGROUND(s)
Definition movetypes.qh:16
string string_null
Definition nil.qh:9
spree_inf s1 s2 s3loc s2 spree_inf s1 s2 s3loc s2 spree_inf s1 s2 s3loc s2 s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2 f1points f2
Definition all.inc:364
#define NULL
Definition post.qh:14
#define gettouch(e)
Definition self.qh:74
vector
Definition self.qh:92
void
Definition self.qh:72
#define vlen2(v)
Definition vector.qh:4
const vector eY
Definition vector.qh:45
const vector eZ
Definition vector.qh:46
#define ClipVelocity(in, normal, out, overbounce)
Definition vector.qh:156
ERASEABLE float boxesoverlap(vector m1, vector m2, vector m3, vector m4)
requires that m2>m1 in all coordinates, and that m4>m3
Definition vector.qh:73
#define vec2(...)
Definition vector.qh:90
#define vec3(_x, _y, _z)
Definition vector.qh:95
void viewloc_PlayerPhysics(entity this)
Definition viewloc.qc:13