1 void _Movetype_Physics_Walk(float dt) // SV_WalkMove
3 vector stepnormal = '0 0 0';
5 // if frametime is 0 (due to client sending the same timestamp twice), don't move
9 if (GAMEPLAYFIX_UNSTICKPLAYERS)
10 _Movetype_UnstickEntity();
12 bool applygravity = (!_Movetype_CheckWater(self) && self.move_movetype == MOVETYPE_WALK && !(self.move_flags & FL_WATERJUMP));
14 _Movetype_CheckVelocity();
16 // do a regular slide move unless it looks like you ran into a step
17 bool oldonground = (self.move_flags & FL_ONGROUND);
19 vector start_origin = self.move_origin;
20 vector start_velocity = self.move_velocity;
22 int clip = _Movetype_FlyMove(dt, applygravity, stepnormal, GAMEPLAYFIX_STEPMULTIPLETIMES ? PHYS_STEPHEIGHT : 0);
24 if (GAMEPLAYFIX_DOWNTRACEONGROUND && !(clip & 1))
26 // only try this if there was no floor in the way in the trace (no,
27 // this check seems to be not REALLY necessary, because if clip & 1,
28 // our trace will hit that thing too)
29 vector upmove = self.move_origin + '0 0 1';
30 vector downmove = self.move_origin - '0 0 1';
32 if (self.move_movetype == MOVETYPE_FLYMISSILE) type = MOVE_MISSILE; else if (self.move_movetype == MOVETYPE_FLY_WORLDONLY)
33 type = MOVE_WORLDONLY;
34 else if (self.solid == SOLID_TRIGGER || self.solid == SOLID_NOT)
35 type = MOVE_NOMONSTERS;
36 else type = MOVE_NORMAL;
37 tracebox(upmove, self.mins, self.maxs, downmove, type, self);
38 if (trace_fraction < 1 && trace_plane_normal.z > 0.7)
39 clip |= 1; // but we HAVE found a floor
42 // if the move did not hit the ground at any point, we're not on ground
44 self.move_flags &= ~FL_ONGROUND;
46 _Movetype_CheckVelocity();
47 _Movetype_LinkEdict(true);
49 if (clip & 8) // teleport
52 if (self.move_flags & FL_WATERJUMP)
58 vector originalmove_origin = self.move_origin;
59 vector originalmove_velocity = self.move_velocity;
60 // originalmove_clip = clip;
61 int originalmove_flags = self.move_flags;
62 entity originalmove_groundentity = self.move_groundentity;
64 // if move didn't block on a step, return
67 // if move was not trying to move into the step, return
68 if (fabs(start_velocity.x) < 0.03125 && fabs(start_velocity.y) < 0.03125)
71 if (self.move_movetype != MOVETYPE_FLY)
73 // return if gibbed by a trigger
74 if (self.move_movetype != MOVETYPE_WALK)
77 // return if attempting to jump while airborn (unless sv_jumpstep)
79 if (!oldonground && self.move_waterlevel == 0)
83 // try moving up and forward to go up a step
85 self.move_origin = start_origin;
86 self.move_velocity = start_velocity;
89 vector upmove = '0 0 1' * PHYS_STEPHEIGHT;
90 if (!_Movetype_PushEntity(upmove, true))
92 // we got teleported when upstepping... must abort the move
97 self.move_velocity_z = 0;
98 clip = _Movetype_FlyMove(dt, applygravity, stepnormal, 0);
99 self.move_velocity_z += start_velocity.z;
102 // we got teleported when upstepping... must abort the move
103 // note that z velocity handling may not be what QC expects here, but we cannot help it
107 _Movetype_CheckVelocity();
108 _Movetype_LinkEdict(true);
110 // check for stuckness, possibly due to the limited precision of floats
111 // in the clipping hulls
113 && fabs(originalmove_origin.y - self.move_origin.y) < 0.03125
114 && fabs(originalmove_origin.x - self.move_origin.x) < 0.03125)
116 // Con_Printf("wall\n");
117 // stepping up didn't make any progress, revert to original move
118 self.move_origin = originalmove_origin;
119 self.move_velocity = originalmove_velocity;
120 // clip = originalmove_clip;
121 self.move_flags = originalmove_flags;
122 self.move_groundentity = originalmove_groundentity;
123 // now try to unstick if needed
124 // clip = SV_TryUnstick (ent, oldvel);
128 // Con_Printf("step - ");
130 // extra friction based on view angle
131 if (clip & 2 && PHYS_WALLFRICTION)
132 _Movetype_WallFriction(stepnormal);
134 // don't do the down move if stepdown is disabled, moving upward, not in water, or the move started offground or ended onground
135 else if (!GAMEPLAYFIX_STEPDOWN || self.move_waterlevel >= 3 || start_velocity.z >= (1.0 / 32.0) || !oldonground || (self.move_flags & FL_ONGROUND))
141 vector downmove = '0 0 1' * (-PHYS_STEPHEIGHT + start_velocity.z * dt);
142 if (!_Movetype_PushEntity(downmove, true))
144 // we got teleported when downstepping... must abort the move
148 if (trace_fraction < 1 && trace_plane_normal.z > 0.7)
150 // this has been disabled so that you can't jump when you are stepping
151 // up while already jumping (also known as the Quake2 double jump bug)
155 // Con_Printf("slope\n");
156 // if the push down didn't end up on good ground, use the move without
157 // the step up. This happens near wall / slope combinations, and can
158 // cause the player to hop up higher on a slope too steep to climb
159 self.move_origin = originalmove_origin;
160 self.move_velocity = originalmove_velocity;
161 self.move_flags = originalmove_flags;
162 self.move_groundentity = originalmove_groundentity;
165 _Movetype_CheckVelocity();
166 _Movetype_LinkEdict(true);