]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/physics/movetypes/walk.qc
579a1cbafe471103b07a5cd5ddabc02871e8a77b
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / physics / movetypes / walk.qc
1 #include "walk.qh"
2
3 void _Movetype_Physics_Walk(entity this, float dt)  // SV_WalkMove
4 {
5         vector stepnormal = '0 0 0';
6
7         // if frametime is 0 (due to client sending the same timestamp twice), don't move
8         if (dt <= 0)
9                 return;
10
11         if (GAMEPLAYFIX_UNSTICKPLAYERS(this))
12                 _Movetype_UnstickEntity(this);
13
14         bool applygravity = (!_Movetype_CheckWater(this) && this.move_movetype == MOVETYPE_WALK && !(this.move_flags & FL_WATERJUMP));
15
16         _Movetype_CheckVelocity(this);
17
18         // do a regular slide move unless it looks like you ran into a step
19         bool oldonground = (this.move_flags & FL_ONGROUND);
20
21         vector start_origin = this.move_origin;
22         vector start_velocity = this.move_velocity;
23
24         int clip = _Movetype_FlyMove(this, dt, applygravity, stepnormal, GAMEPLAYFIX_STEPMULTIPLETIMES(this) ? PHYS_STEPHEIGHT(this) : 0);
25
26         if (GAMEPLAYFIX_DOWNTRACEONGROUND(this) && !(clip & 1))
27         {
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';
33                 int type;
34                 if (this.move_movetype == MOVETYPE_FLYMISSILE)
35                         type = MOVE_MISSILE;
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
44         }
45
46         // if the move did not hit the ground at any point, we're not on ground
47         if (!(clip & 1))
48                 this.move_flags &= ~FL_ONGROUND;
49
50         _Movetype_CheckVelocity(this);
51         _Movetype_LinkEdict(this, true);
52
53         if (clip & 8)  // teleport
54                 return;
55
56         if (this.move_flags & FL_WATERJUMP)
57                 return;
58
59         if (PHYS_NOSTEP(this))
60                 return;
61
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;
67
68         // if move didn't block on a step, return
69         if (clip & 2)
70         {
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)
73                         return;
74
75                 if (this.move_movetype != MOVETYPE_FLY)
76                 {
77                         // return if gibbed by a trigger
78                         if (this.move_movetype != MOVETYPE_WALK)
79                                 return;
80
81                         // return if attempting to jump while airborn (unless sv_jumpstep)
82                         if (!PHYS_JUMPSTEP(this))
83                                 if (!oldonground && this.move_waterlevel == 0)
84                                         return;
85                 }
86
87                 // try moving up and forward to go up a step
88                 // back to start pos
89                 this.move_origin = start_origin;
90                 this.move_velocity = start_velocity;
91
92                 // move up
93                 vector upmove = '0 0 1' * PHYS_STEPHEIGHT(this);
94                 _Movetype_PushEntity(this, upmove, true);
95                 if(wasfreed(this))
96                         return;
97                 if(trace_startsolid)
98                 {
99                         // we got teleported when upstepping... must abort the move
100                         return;
101                 }
102
103                 // move forward
104                 this.move_velocity_z = 0;
105                 clip = _Movetype_FlyMove(this, dt, applygravity, stepnormal, 0);
106                 this.move_velocity_z += start_velocity.z;
107                 if (clip & 8)
108                 {
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
111                         return;
112                 }
113
114                 _Movetype_CheckVelocity(this);
115                 _Movetype_LinkEdict(this, true);
116
117                 // check for stuckness, possibly due to the limited precision of floats
118                 // in the clipping hulls
119                 if (clip
120                     && fabs(originalmove_origin.y - this.move_origin.y) < 0.03125
121                     && fabs(originalmove_origin.x - this.move_origin.x) < 0.03125)
122                 {
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);
132                         return;
133                 }
134
135                 // Con_Printf("step - ");
136
137                 // extra friction based on view angle
138                 if ((clip & 2) && PHYS_WALLFRICTION(this))
139                         _Movetype_WallFriction(this, stepnormal);
140         }
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))
143         {
144                 return;
145         }
146
147         // move down
148         vector downmove = '0 0 1' * (-PHYS_STEPHEIGHT(this) + start_velocity.z * dt);
149         _Movetype_PushEntity(this, downmove, true);
150         if(wasfreed(this))
151                 return;
152
153         if(trace_startsolid)
154         {
155                 // we got teleported when downstepping... must abort the move
156                 return;
157         }
158
159         if (trace_fraction < 1 && trace_plane_normal.z > 0.7)
160         {
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)
163         }
164         else
165         {
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;
174         }
175
176         _Movetype_CheckVelocity(this);
177         _Movetype_LinkEdict(this, true);
178 }