3 void _Movetype_Physics_Walk(entity this, float dt) // SV_WalkMove
5 // if frametime is 0 (due to client sending the same timestamp twice), don't move
9 if (GAMEPLAYFIX_UNSTICKPLAYERS(this))
10 _Movetype_CheckStuck(this);
12 bool applygravity = (!_Movetype_CheckWater(this) && this.move_movetype == MOVETYPE_WALK && !(this.flags & FL_WATERJUMP));
14 _Movetype_CheckVelocity(this);
16 // do a regular slide move unless it looks like you ran into a step
17 bool oldonground = IS_ONGROUND(this);
19 vector start_origin = this.origin;
20 vector start_velocity = this.velocity;
22 if(PHYS_WALLCLIP(this) && this.pm_time)
24 if(dt >= this.pm_time || (this.flags & FL_WATERJUMP))
30 int clip = _Movetype_FlyMove(this, dt, applygravity, false, GAMEPLAYFIX_STEPMULTIPLETIMES(this) ? PHYS_STEPHEIGHT(this) : 0);
32 if (GAMEPLAYFIX_DOWNTRACEONGROUND(this) && !(clip & 1))
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';
40 if (this.move_nomonsters)
41 type = max(0, this.move_nomonsters);
42 else if (this.move_movetype == MOVETYPE_FLYMISSILE)
44 else if (this.move_movetype == MOVETYPE_FLY_WORLDONLY)
45 type = MOVE_WORLDONLY;
46 else if (this.solid == SOLID_TRIGGER || this.solid == SOLID_NOT)
47 type = MOVE_NOMONSTERS;
50 tracebox(upmove, this.mins, this.maxs, downmove, type, this);
51 if (trace_fraction < 1 && trace_plane_normal.z > 0.7)
53 clip |= 1; // but we HAVE found a floor
54 // set groundentity so we get carried when walking onto a mover
55 this.groundentity = trace_ent;
59 // if the move did not hit the ground at any point, we're not on ground
62 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
65 _Movetype_CheckVelocity(this);
66 _Movetype_LinkEdict(this, true);
68 if (clip & 8) // teleport
71 if (this.flags & FL_WATERJUMP)
74 if (PHYS_NOSTEP(this))
77 vector originalorigin = this.origin;
78 vector originalvelocity = this.velocity;
79 // originalmove_clip = clip;
80 int originalflags = this.flags;
81 entity originalmove_groundentity = this.groundentity;
83 // if move didn't block on a step, return
86 // if move was not trying to move into the step, return
87 if (fabs(start_velocity.x) < 0.03125 && fabs(start_velocity.y) < 0.03125)
90 if (this.move_movetype != MOVETYPE_FLY)
92 // return if gibbed by a trigger
93 if (this.move_movetype != MOVETYPE_WALK)
96 // return if attempting to jump while airborn (unless sv_jumpstep)
97 if (!PHYS_JUMPSTEP(this))
98 if (!oldonground && this.waterlevel == 0)
102 // try moving up and forward to go up a step
104 this.origin = start_origin;
105 this.velocity = start_velocity;
108 vector upmove = '0 0 1' * PHYS_STEPHEIGHT(this);
109 if(!_Movetype_PushEntity(this, upmove, true))
111 // we got teleported when upstepping... must abort the move
117 clip = _Movetype_FlyMove(this, dt, applygravity, true, 0);
118 this.velocity_z += start_velocity.z;
121 // we got teleported when upstepping... must abort the move
122 // note that z velocity handling may not be what QC expects here, but we cannot help it
126 _Movetype_CheckVelocity(this);
127 _Movetype_LinkEdict(this, true);
129 // check for stuckness, possibly due to the limited precision of floats
130 // in the clipping hulls
132 && fabs(originalorigin.y - this.origin.y) < 0.03125
133 && fabs(originalorigin.x - this.origin.x) < 0.03125)
135 // Con_Printf("wall\n");
136 // stepping up didn't make any progress, revert to original move
137 this.origin = originalorigin;
138 this.velocity = originalvelocity;
139 // clip = originalmove_clip;
140 this.flags = originalflags;
141 this.groundentity = originalmove_groundentity;
142 // now try to unstick if needed
143 // clip = SV_TryUnstick (ent, oldvel);
147 // Con_Printf("step - ");
149 // extra friction based on view angle
150 if ((clip & 2) && PHYS_WALLFRICTION(this))
151 _Movetype_WallFriction(this, move_stepnormal);
153 // don't do the down move if stepdown is disabled, moving upward, not in water, or the move started offground or ended onground
154 else if (!GAMEPLAYFIX_STEPDOWN(this) || this.waterlevel >= 3 || start_velocity.z >= (1.0 / 32.0)
155 || !oldonground || IS_ONGROUND(this) || (GAMEPLAYFIX_STEPDOWN_MAXSPEED(this) && vdist(start_velocity, >=, GAMEPLAYFIX_STEPDOWN_MAXSPEED(this)) && !IS_ONSLICK(this)))
161 vector downmove = '0 0 0';
162 downmove.z = -PHYS_STEPHEIGHT(this) + start_velocity.z * dt;
163 if(!_Movetype_PushEntity(this, downmove, true))
165 // we got teleported when downstepping... must abort the move
169 if (trace_fraction < 1 && trace_plane_normal.z > 0.7)
171 // this has been disabled so that you can't jump when you are stepping
172 // up while already jumping (also known as the Quake2 double jump bug)
173 // LordHavoc: disabled this check so you can walk on monsters/players
174 //if (PRVM_serveredictfloat(ent, solid) == SOLID_BSP)
175 if(GAMEPLAYFIX_STEPDOWN(this) == 2)
178 this.groundentity = trace_ent;
183 // Con_Printf("slope\n");
184 // if the push down didn't end up on good ground, use the move without
185 // the step up. This happens near wall / slope combinations, and can
186 // cause the player to hop up higher on a slope too steep to climb
187 this.origin = originalorigin;
188 this.velocity = originalvelocity;
189 this.flags = originalflags;
190 this.groundentity = originalmove_groundentity;
193 _Movetype_CheckVelocity(this);
194 _Movetype_LinkEdict(this, true);