3 void _Movetype_Physics_Walk(entity this, float dt) // SV_WalkMove
5 vector stepnormal = '0 0 0';
7 // if frametime is 0 (due to client sending the same timestamp twice), don't move
11 if (GAMEPLAYFIX_UNSTICKPLAYERS(this))
12 _Movetype_UnstickEntity(this);
14 bool applygravity = (!_Movetype_CheckWater(this) && this.move_movetype == MOVETYPE_WALK && !(this.move_flags & FL_WATERJUMP));
16 _Movetype_CheckVelocity(this);
18 // do a regular slide move unless it looks like you ran into a step
19 bool oldonground = (this.move_flags & FL_ONGROUND);
21 vector start_origin = this.move_origin;
22 vector start_velocity = this.move_velocity;
24 int clip = _Movetype_FlyMove(this, dt, applygravity, stepnormal, GAMEPLAYFIX_STEPMULTIPLETIMES(this) ? PHYS_STEPHEIGHT(this) : 0);
26 if (GAMEPLAYFIX_DOWNTRACEONGROUND(this) && !(clip & 1))
28 // only try this if there was no floor in the way in the trace (no,
29 // this check seems to be not REALLY necessary, because if clip & 1,
30 // our trace will hit that thing too)
31 vector upmove = this.move_origin + '0 0 1';
32 vector downmove = this.move_origin - '0 0 1';
34 if (this.move_movetype == MOVETYPE_FLYMISSILE)
36 else if (this.move_movetype == MOVETYPE_FLY_WORLDONLY)
37 type = MOVE_WORLDONLY;
38 else if (this.solid == SOLID_TRIGGER || this.solid == SOLID_NOT)
39 type = MOVE_NOMONSTERS;
40 else type = MOVE_NORMAL;
41 tracebox(upmove, this.mins, this.maxs, downmove, type, this);
42 if (trace_fraction < 1 && trace_plane_normal.z > 0.7)
43 clip |= 1; // but we HAVE found a floor
46 // if the move did not hit the ground at any point, we're not on ground
48 this.move_flags &= ~FL_ONGROUND;
50 _Movetype_CheckVelocity(this);
51 _Movetype_LinkEdict(this, true);
53 if (clip & 8) // teleport
56 if (this.move_flags & FL_WATERJUMP)
59 if (PHYS_NOSTEP(this))
62 vector originalmove_origin = this.move_origin;
63 vector originalmove_velocity = this.move_velocity;
64 // originalmove_clip = clip;
65 int originalmove_flags = this.move_flags;
66 entity originalmove_groundentity = this.move_groundentity;
68 // if move didn't block on a step, return
71 // if move was not trying to move into the step, return
72 if (fabs(start_velocity.x) < 0.03125 && fabs(start_velocity.y) < 0.03125)
75 if (this.move_movetype != MOVETYPE_FLY)
77 // return if gibbed by a trigger
78 if (this.move_movetype != MOVETYPE_WALK)
81 // return if attempting to jump while airborn (unless sv_jumpstep)
82 if (!PHYS_JUMPSTEP(this))
83 if (!oldonground && this.move_waterlevel == 0)
87 // try moving up and forward to go up a step
89 this.move_origin = start_origin;
90 this.move_velocity = start_velocity;
93 vector upmove = '0 0 1' * PHYS_STEPHEIGHT(this);
94 _Movetype_PushEntity(this, upmove, true);
99 // we got teleported when upstepping... must abort the move
104 this.move_velocity_z = 0;
105 clip = _Movetype_FlyMove(this, dt, applygravity, stepnormal, 0);
106 this.move_velocity_z += start_velocity.z;
109 // we got teleported when upstepping... must abort the move
110 // note that z velocity handling may not be what QC expects here, but we cannot help it
114 _Movetype_CheckVelocity(this);
115 _Movetype_LinkEdict(this, true);
117 // check for stuckness, possibly due to the limited precision of floats
118 // in the clipping hulls
120 && fabs(originalmove_origin.y - this.move_origin.y) < 0.03125
121 && fabs(originalmove_origin.x - this.move_origin.x) < 0.03125)
123 // Con_Printf("wall\n");
124 // stepping up didn't make any progress, revert to original move
125 this.move_origin = originalmove_origin;
126 this.move_velocity = originalmove_velocity;
127 // clip = originalmove_clip;
128 this.move_flags = originalmove_flags;
129 this.move_groundentity = originalmove_groundentity;
130 // now try to unstick if needed
131 // clip = SV_TryUnstick (ent, oldvel);
135 // Con_Printf("step - ");
137 // extra friction based on view angle
138 if ((clip & 2) && PHYS_WALLFRICTION(this))
139 _Movetype_WallFriction(this, stepnormal);
141 // don't do the down move if stepdown is disabled, moving upward, not in water, or the move started offground or ended onground
142 else if (!GAMEPLAYFIX_STEPDOWN(this) || this.move_waterlevel >= 3 || start_velocity.z >= (1.0 / 32.0) || !oldonground || (this.move_flags & FL_ONGROUND))
148 vector downmove = '0 0 1' * (-PHYS_STEPHEIGHT(this) + start_velocity.z * dt);
149 _Movetype_PushEntity(this, downmove, true);
155 // we got teleported when downstepping... must abort the move
159 if (trace_fraction < 1 && trace_plane_normal.z > 0.7)
161 // this has been disabled so that you can't jump when you are stepping
162 // up while already jumping (also known as the Quake2 double jump bug)
166 // Con_Printf("slope\n");
167 // if the push down didn't end up on good ground, use the move without
168 // the step up. This happens near wall / slope combinations, and can
169 // cause the player to hop up higher on a slope too steep to climb
170 this.move_origin = originalmove_origin;
171 this.move_velocity = originalmove_velocity;
172 this.move_flags = originalmove_flags;
173 this.move_groundentity = originalmove_groundentity;
176 _Movetype_CheckVelocity(this);
177 _Movetype_LinkEdict(this, true);