]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/movetypes/walk.qc
Merge branch 'master' into Mario/qc_physics_prehax
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / movetypes / walk.qc
1 void _Movetype_Physics_Walk(float dt)  // SV_WalkMove
2 {
3         vector stepnormal = '0 0 0';
4
5         // if frametime is 0 (due to client sending the same timestamp twice), don't move
6         if (dt <= 0)
7                 return;
8
9         if (GAMEPLAYFIX_UNSTICKPLAYERS)
10                 _Movetype_UnstickEntity();
11
12         bool applygravity = (!_Movetype_CheckWater(self) && self.move_movetype == MOVETYPE_WALK && !(self.move_flags & FL_WATERJUMP));
13
14         _Movetype_CheckVelocity();
15
16         // do a regular slide move unless it looks like you ran into a step
17         bool oldonground = (self.move_flags & FL_ONGROUND);
18
19         vector start_origin = self.move_origin;
20         vector start_velocity = self.move_velocity;
21
22         int clip = _Movetype_FlyMove(dt, applygravity, stepnormal, GAMEPLAYFIX_STEPMULTIPLETIMES ? PHYS_STEPHEIGHT : 0);
23
24         if (GAMEPLAYFIX_DOWNTRACEONGROUND && !(clip & 1))
25         {
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';
31                 int type;
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
40         }
41
42         // if the move did not hit the ground at any point, we're not on ground
43         if (!(clip & 1))
44                 self.move_flags &= ~FL_ONGROUND;
45
46         _Movetype_CheckVelocity();
47         _Movetype_LinkEdict(true);
48
49         if (clip & 8)  // teleport
50                 return;
51
52         if (self.move_flags & FL_WATERJUMP)
53                 return;
54
55         if (PHYS_NOSTEP)
56                 return;
57
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;
63
64         // if move didn't block on a step, return
65         if (clip & 2)
66         {
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)
69                         return;
70
71                 if (self.move_movetype != MOVETYPE_FLY)
72                 {
73                         // return if gibbed by a trigger
74                         if (self.move_movetype != MOVETYPE_WALK)
75                                 return;
76
77                         // return if attempting to jump while airborn (unless sv_jumpstep)
78                         if (!PHYS_JUMPSTEP)
79                                 if (!oldonground && self.move_waterlevel == 0)
80                                         return;
81                 }
82
83                 // try moving up and forward to go up a step
84                 // back to start pos
85                 self.move_origin = start_origin;
86                 self.move_velocity = start_velocity;
87
88                 // move up
89                 vector upmove = '0 0 1' * PHYS_STEPHEIGHT;
90                 if (!_Movetype_PushEntity(upmove, true))
91                 {
92                         // we got teleported when upstepping... must abort the move
93                         return;
94                 }
95
96                 // move forward
97                 self.move_velocity_z = 0;
98                 clip = _Movetype_FlyMove(dt, applygravity, stepnormal, 0);
99                 self.move_velocity_z += start_velocity.z;
100                 if (clip & 8)
101                 {
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
104                         return;
105                 }
106
107                 _Movetype_CheckVelocity();
108                 _Movetype_LinkEdict(true);
109
110                 // check for stuckness, possibly due to the limited precision of floats
111                 // in the clipping hulls
112                 if (clip
113                     && fabs(originalmove_origin.y - self.move_origin.y) < 0.03125
114                     && fabs(originalmove_origin.x - self.move_origin.x) < 0.03125)
115                 {
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);
125                         return;
126                 }
127
128                 // Con_Printf("step - ");
129
130                 // extra friction based on view angle
131                 if (clip & 2 && PHYS_WALLFRICTION)
132                         _Movetype_WallFriction(stepnormal);
133         }
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))
136         {
137                 return;
138         }
139
140         // move down
141         vector downmove = '0 0 1' * (-PHYS_STEPHEIGHT + start_velocity.z * dt);
142         if (!_Movetype_PushEntity(downmove, true))
143         {
144                 // we got teleported when downstepping... must abort the move
145                 return;
146         }
147
148         if (trace_fraction < 1 && trace_plane_normal.z > 0.7)
149         {
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)
152         }
153         else
154         {
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;
163         }
164
165         _Movetype_CheckVelocity();
166         _Movetype_LinkEdict(true);
167 }