]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/movetypes/walk.qc
Merge branch 'master' into Mario/vaporizer_damage
[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)
33                         type = MOVE_MISSILE;
34                 else if (self.move_movetype == MOVETYPE_FLY_WORLDONLY)
35                         type = MOVE_WORLDONLY;
36                 else if (self.solid == SOLID_TRIGGER || self.solid == SOLID_NOT)
37                         type = MOVE_NOMONSTERS;
38                 else type = MOVE_NORMAL;
39                 tracebox(upmove, self.mins, self.maxs, downmove, type, self);
40                 if (trace_fraction < 1 && trace_plane_normal.z > 0.7)
41                         clip |= 1;  // but we HAVE found a floor
42         }
43
44         // if the move did not hit the ground at any point, we're not on ground
45         if (!(clip & 1))
46                 self.move_flags &= ~FL_ONGROUND;
47
48         _Movetype_CheckVelocity();
49         _Movetype_LinkEdict(true);
50
51         if (clip & 8)  // teleport
52                 return;
53
54         if (self.move_flags & FL_WATERJUMP)
55                 return;
56
57         if (PHYS_NOSTEP)
58                 return;
59
60         vector originalmove_origin = self.move_origin;
61         vector originalmove_velocity = self.move_velocity;
62         // originalmove_clip = clip;
63         int originalmove_flags = self.move_flags;
64         entity originalmove_groundentity = self.move_groundentity;
65
66         // if move didn't block on a step, return
67         if (clip & 2)
68         {
69                 // if move was not trying to move into the step, return
70                 if (fabs(start_velocity.x) < 0.03125 && fabs(start_velocity.y) < 0.03125)
71                         return;
72
73                 if (self.move_movetype != MOVETYPE_FLY)
74                 {
75                         // return if gibbed by a trigger
76                         if (self.move_movetype != MOVETYPE_WALK)
77                                 return;
78
79                         // return if attempting to jump while airborn (unless sv_jumpstep)
80                         if (!PHYS_JUMPSTEP)
81                                 if (!oldonground && self.move_waterlevel == 0)
82                                         return;
83                 }
84
85                 // try moving up and forward to go up a step
86                 // back to start pos
87                 self.move_origin = start_origin;
88                 self.move_velocity = start_velocity;
89
90                 // move up
91                 vector upmove = '0 0 1' * PHYS_STEPHEIGHT;
92                 if (!_Movetype_PushEntity(upmove, true))
93                 {
94                         // we got teleported when upstepping... must abort the move
95                         return;
96                 }
97
98                 // move forward
99                 self.move_velocity_z = 0;
100                 clip = _Movetype_FlyMove(dt, applygravity, stepnormal, 0);
101                 self.move_velocity_z += start_velocity.z;
102                 if (clip & 8)
103                 {
104                         // we got teleported when upstepping... must abort the move
105                         // note that z velocity handling may not be what QC expects here, but we cannot help it
106                         return;
107                 }
108
109                 _Movetype_CheckVelocity();
110                 _Movetype_LinkEdict(true);
111
112                 // check for stuckness, possibly due to the limited precision of floats
113                 // in the clipping hulls
114                 if (clip
115                     && fabs(originalmove_origin.y - self.move_origin.y) < 0.03125
116                     && fabs(originalmove_origin.x - self.move_origin.x) < 0.03125)
117                 {
118                         // Con_Printf("wall\n");
119                         // stepping up didn't make any progress, revert to original move
120                         self.move_origin = originalmove_origin;
121                         self.move_velocity = originalmove_velocity;
122                         // clip = originalmove_clip;
123                         self.move_flags = originalmove_flags;
124                         self.move_groundentity = originalmove_groundentity;
125                         // now try to unstick if needed
126                         // clip = SV_TryUnstick (ent, oldvel);
127                         return;
128                 }
129
130                 // Con_Printf("step - ");
131
132                 // extra friction based on view angle
133                 if (clip & 2 && PHYS_WALLFRICTION)
134                         _Movetype_WallFriction(stepnormal);
135         }
136         // don't do the down move if stepdown is disabled, moving upward, not in water, or the move started offground or ended onground
137         else if (!GAMEPLAYFIX_STEPDOWN || self.move_waterlevel >= 3 || start_velocity.z >= (1.0 / 32.0) || !oldonground || (self.move_flags & FL_ONGROUND))
138         {
139                 return;
140         }
141
142         // move down
143         vector downmove = '0 0 1' * (-PHYS_STEPHEIGHT + start_velocity.z * dt);
144         if (!_Movetype_PushEntity(downmove, true))
145         {
146                 // we got teleported when downstepping... must abort the move
147                 return;
148         }
149
150         if (trace_fraction < 1 && trace_plane_normal.z > 0.7)
151         {
152                 // this has been disabled so that you can't jump when you are stepping
153                 // up while already jumping (also known as the Quake2 double jump bug)
154         }
155         else
156         {
157                 // Con_Printf("slope\n");
158                 // if the push down didn't end up on good ground, use the move without
159                 // the step up.  This happens near wall / slope combinations, and can
160                 // cause the player to hop up higher on a slope too steep to climb
161                 self.move_origin = originalmove_origin;
162                 self.move_velocity = originalmove_velocity;
163                 self.move_flags = originalmove_flags;
164                 self.move_groundentity = originalmove_groundentity;
165         }
166
167         _Movetype_CheckVelocity();
168         _Movetype_LinkEdict(true);
169 }