Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
walk.qc
Go to the documentation of this file.
1#include "walk.qh"
2
3void _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
11
12 bool applygravity = (!_Movetype_CheckWater(this) && this.move_movetype == MOVETYPE_WALK && !(this.flags & FL_WATERJUMP));
13
14 // do a regular slide move unless it looks like you ran into a step
15 bool oldonground = IS_ONGROUND(this);
16
17 vector start_origin = this.origin;
18 vector start_velocity = this.velocity;
19
20 if(PHYS_WALLCLIP(this) && this.pm_time)
21 {
22 if(dt >= this.pm_time || (this.flags & FL_WATERJUMP))
23 this.pm_time = 0;
24 else
25 this.pm_time -= dt;
26 }
27
28 int clip = _Movetype_FlyMove(this, dt, applygravity, false, GAMEPLAYFIX_STEPMULTIPLETIMES(this) ? PHYS_STEPHEIGHT(this) : 0);
29
30 if (GAMEPLAYFIX_DOWNTRACEONGROUND(this) && !(clip & 1))
31 {
32 // only try this if there was no floor in the way in the trace (no,
33 // this check seems to be not REALLY necessary, because if clip & 1,
34 // our trace will hit that thing too)
35 vector upmove = this.origin + '0 0 1';
36 vector downmove = this.origin - '0 0 1';
37 int type;
38 if (this.move_nomonsters)
39 type = max(0, this.move_nomonsters);
40 else if (this.move_movetype == MOVETYPE_FLYMISSILE)
41 type = MOVE_MISSILE;
43 type = MOVE_WORLDONLY;
44 else if (this.solid == SOLID_TRIGGER || this.solid == SOLID_NOT)
45 type = MOVE_NOMONSTERS;
46 else
47 type = MOVE_NORMAL;
48 tracebox(upmove, this.mins, this.maxs, downmove, type, this);
50 {
51 clip |= 1; // but we HAVE found a floor
52 // set groundentity so we get carried when walking onto a mover
54 }
55 }
56
57 // if the move did not hit the ground at any point, we're not on ground
58 if (!(clip & 1))
59 UNSET_ONGROUND(this);
60 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
61 this.pm_time = 0.25;
62
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))
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
123 _Movetype_LinkEdict(this, true);
124
125 // check for stuckness, possibly due to the limited precision of floats
126 // in the clipping hulls
127 if (clip
128 && fabs(originalorigin.y - this.origin.y) < 0.03125
129 && fabs(originalorigin.x - this.origin.x) < 0.03125)
130 {
131 // Con_Printf("wall\n");
132 // stepping up didn't make any progress, revert to original move
133 this.origin = originalorigin;
134 this.velocity = originalvelocity;
135 // clip = originalmove_clip;
136 this.flags = originalflags;
137 this.groundentity = originalmove_groundentity;
138 // now try to unstick if needed
139 // clip = SV_TryUnstick (ent, oldvel);
140 return;
141 }
142
143 // Con_Printf("step - ");
144
145 // extra friction based on view angle
146 if ((clip & 2) && PHYS_WALLFRICTION(this))
148 }
149 // don't do the down move if stepdown is disabled, moving upward, not in water, or the move started offground or ended onground
150 else if (!GAMEPLAYFIX_STEPDOWN(this) || this.waterlevel >= 3 || start_velocity.z >= (1.0 / 32.0)
151 || !oldonground || IS_ONGROUND(this) || (GAMEPLAYFIX_STEPDOWN_MAXSPEED(this) && vdist(start_velocity, >=, GAMEPLAYFIX_STEPDOWN_MAXSPEED(this)) && !IS_ONSLICK(this)))
152 {
153 return;
154 }
155
156 // move down
157 vector downmove = '0 0 0';
158 downmove.z = -PHYS_STEPHEIGHT(this) + start_velocity.z * dt;
159 if(!_Movetype_PushEntity(this, downmove, true))
160 {
161 // we got teleported when downstepping... must abort the move
162 return;
163 }
164
166 {
167 // this has been disabled so that you can't jump when you are stepping
168 // up while already jumping (also known as the Quake2 double jump bug)
169 // LordHavoc: disabled this check so you can walk on monsters/players
170 //if (PRVM_serveredictfloat(ent, solid) == SOLID_BSP)
171 if(GAMEPLAYFIX_STEPDOWN(this) == 2)
172 {
173 SET_ONGROUND(this);
174 this.groundentity = trace_ent;
175 }
176 }
177 else
178 {
179 // Con_Printf("slope\n");
180 // if the push down didn't end up on good ground, use the move without
181 // the step up. This happens near wall / slope combinations, and can
182 // cause the player to hop up higher on a slope too steep to climb
183 this.origin = originalorigin;
184 this.velocity = originalvelocity;
185 this.flags = originalflags;
186 this.groundentity = originalmove_groundentity;
187 }
188
189 _Movetype_LinkEdict(this, true);
190}
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
float waterlevel
Definition player.qh:226
const int FL_WATERJUMP
Definition constants.qh:80
float flags
const float MOVE_NOMONSTERS
entity trace_ent
const float SOLID_TRIGGER
const float MOVE_NORMAL
vector mins
vector velocity
const float SOLID_NOT
vector maxs
float MOVE_WORLDONLY
vector origin
float trace_fraction
const float MOVE_MISSILE
solid
Definition ent_cs.qc:165
float fabs(float f)
float max(float f,...)
void _Movetype_CheckStuck(entity this)
Definition movetypes.qc:620
int _Movetype_FlyMove(entity this, float dt, bool applygravity, bool applystepnormal, float stepheight)
Definition movetypes.qc:120
bool _Movetype_CheckWater(entity this)
Definition movetypes.qc:334
void _Movetype_LinkEdict(entity this, bool touch_triggers)
Definition movetypes.qc:516
bool _Movetype_PushEntity(entity this, vector push, bool dolink)
Definition movetypes.qc:668
void _Movetype_WallFriction(entity this, vector stepnormal)
Definition movetypes.qc:102
const int MOVETYPE_WALK
Definition movetypes.qh:132
#define GAMEPLAYFIX_STEPDOWN(s)
Definition movetypes.qh:25
#define GAMEPLAYFIX_DOWNTRACEONGROUND(s)
Definition movetypes.qh:23
#define GAMEPLAYFIX_UNSTICKPLAYERS(s)
Definition movetypes.qh:28
#define PHYS_STEPHEIGHT(s)
Definition movetypes.qh:38
#define PHYS_WALLCLIP(s)
Definition movetypes.qh:43
float pm_time
Definition movetypes.qh:74
#define IS_ONSLICK(s)
Definition movetypes.qh:19
const int MOVETYPE_FLYMISSILE
Definition movetypes.qh:138
entity groundentity
Definition movetypes.qh:93
#define PHYS_WALLFRICTION(s)
Definition movetypes.qh:41
#define PHYS_JUMPSTEP(s)
Definition movetypes.qh:40
const int MOVETYPE_FLY_WORLDONLY
Definition movetypes.qh:143
#define SET_ONGROUND(s)
Definition movetypes.qh:17
float move_nomonsters
Definition movetypes.qh:88
vector move_stepnormal
Definition movetypes.qh:103
float move_movetype
Definition movetypes.qh:76
#define UNSET_ONGROUND(s)
Definition movetypes.qh:18
#define GAMEPLAYFIX_STEPMULTIPLETIMES(s)
Definition movetypes.qh:27
const int MOVETYPE_FLY
Definition movetypes.qh:134
#define GAMEPLAYFIX_STEPDOWN_MAXSPEED(s)
Definition movetypes.qh:26
#define PHYS_NOSTEP(s)
Definition movetypes.qh:39
#define IS_ONGROUND(s)
Definition movetypes.qh:16
vector
Definition self.qh:92
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition vector.qh:8
void _Movetype_Physics_Walk(entity this, float dt)
Definition walk.qc:3