1 .entity move_groundentity;
2 .float move_suspendedinair;
3 .float move_didgravity;
5 void _Movetype_CheckVelocity() // SV_CheckVelocity
9 float _Movetype_CheckWater() // SV_CheckWater
14 void _Movetype_CheckWaterTransition() // SV_CheckWaterTransition
18 void _Movetype_Impact(entity oth) // SV_Impact
22 void _Movetype_LinkEdict(float touch_triggers) // SV_LinkEdict
26 float _Movetype_TestEntityPosition(vector ofs) // SV_TestEntityPosition
30 org = self.move_origin + ofs;
32 cont = self.dphitcontentsmask;
33 self.dphitcontentsmask = DPCONTENTS_SOLID;
34 tracebox(self.move_origin, self.mins, self.maxs, self.move_origin, MOVE_NOMONSTERS, self);
35 self.dphitcontentsmask = cont;
40 if(vlen(trace_endpos - self.move_origin) > 0.0001)
41 self.move_origin = trace_endpos;
45 float _Movetype_UnstickEntity() // SV_UnstickEntity
47 if(!_Movetype_TestEntityPosition('0 0 0'))
49 if(!_Movetype_TestEntityPosition('-1 0 0')) goto success;
50 if(!_Movetype_TestEntityPosition('1 0 0')) goto success;
51 if(!_Movetype_TestEntityPosition('0 -1 0')) goto success;
52 if(!_Movetype_TestEntityPosition('0 1 0')) goto success;
53 if(!_Movetype_TestEntityPosition('-1 -1 0')) goto success;
54 if(!_Movetype_TestEntityPosition('1 -1 0')) goto success;
55 if(!_Movetype_TestEntityPosition('-1 1 0')) goto success;
56 if(!_Movetype_TestEntityPosition('1 1 0')) goto success;
58 for(i = 1; i <= 17; ++i)
60 if(!_Movetype_TestEntityPosition('0 0 -1' * i)) goto success;
61 if(!_Movetype_TestEntityPosition('0 0 1' * i)) goto success;
63 dprint("Some entity is stuck\n");
66 dprint("Unstuck some entity\n");
67 _Movetype_LinkEdict(TRUE);
71 vector _Movetype_ClipVelocity(vector vel, vector norm, float f) // SV_ClipVelocity
73 vel = vel - ((vel * norm) * norm) * f;
75 if(vel_x > -0.1 && vel_x < 0.1) vel_x = 0;
76 if(vel_y > -0.1 && vel_y < 0.1) vel_y = 0;
77 if(vel_z > -0.1 && vel_z < 0.1) vel_z = 0;
82 void _Movetype_PushEntityTrace(vector push)
87 end = self.move_origin + push;
89 if(self.move_movetype == MOVETYPE_FLYMISSILE)
91 else if(self.solid == SOLID_TRIGGER || self.solid == SOLID_NOT)
92 type = MOVE_NOMONSTERS;
96 tracebox(self.move_origin, self.mins, self.maxs, end, type, self);
99 float _Movetype_PushEntity(vector push, float failonstartsolid) // SV_PushEntity
101 _Movetype_PushEntityTrace(push);
103 if(trace_startsolid && failonstartsolid)
104 return trace_fraction;
106 self.move_origin = trace_endpos;
108 if(self.solid >= SOLID_TRIGGER && trace_ent && (!(self.move_flags & FL_ONGROUND) || (self.move_groundentity != trace_ent)))
109 _Movetype_Impact(trace_ent);
111 return trace_fraction;
114 void _Movetype_Physics_Toss(float dt) // SV_Physics_Toss
116 if(self.move_flags & FL_ONGROUND)
118 if(self.velocity_z >= 1/32)
119 self.move_flags &~= FL_ONGROUND;
120 else if(!self.move_groundentity)
122 else if(self.move_suspendedinair && wasfreed(self.move_groundentity))
124 self.move_groundentity = world;
129 self.move_suspendedinair = FALSE;
131 _Movetype_CheckVelocity();
133 if(self.move_movetype == MOVETYPE_BOUNCE || self.move_movetype == MOVETYPE_TOSS)
135 self.move_didgravity = TRUE;
136 self.move_velocity_z -= dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
139 self.move_angles = self.move_angles + self.move_avelocity * dt;
142 move = self.move_velocity * dt;
144 _Movetype_PushEntity(move, TRUE);
150 _Movetype_UnstickEntity();
151 _Movetype_PushEntity(move, FALSE);
156 if(trace_fraction < 1)
158 if(self.move_movetype == MOVETYPE_BOUNCEMISSILE)
160 self.move_velocity = _Movetype_ClipVelocity(self.move_velocity, trace_plane_normal, 2.0);
161 self.move_flags &~= FL_ONGROUND;
163 else if(self.move_movetype == MOVETYPE_BOUNCE)
165 self.move_velocity = _Movetype_ClipVelocity(self.move_velocity, trace_plane_normal, 1.5);
168 d = trace_plane_normal * self.move_velocity;
169 if(trace_plane_normal_z > 0.7 && d < 60 && d > -60)
171 self.move_flags |= FL_ONGROUND;
172 self.move_groundentity = trace_ent;
173 self.move_velocity = '0 0 0';
174 self.move_avelocity = '0 0 0';
177 self.move_flags &~= FL_ONGROUND;
181 self.move_velocity = _Movetype_ClipVelocity(self.move_velocity, trace_plane_normal, 1.0);
182 if(trace_plane_normal_z > 0.7)
184 self.move_flags |= FL_ONGROUND;
185 self.move_groundentity = trace_ent;
186 if(trace_ent.solid == SOLID_BSP)
187 self.move_suspendedinair = TRUE;
188 self.move_velocity = '0 0 0';
189 self.move_avelocity = '0 0 0';
192 self.move_flags &~= FL_ONGROUND;
196 _Movetype_CheckWaterTransition();
199 void Movetype_Physics(float matchserver) // SV_Physics_Entity
201 float n, i, dt, movedt;
203 dt = time - self.move_time;
208 n = max(0, floor(dt / ticrate));
210 self.move_time += n * ticrate;
217 self.move_time = time;
220 //self.move_didgravity = ((self.move_movetype == MOVETYPE_BOUNCE || self.move_movetype == MOVETYPE_TOSS) && !(self.move_flags & FL_ONGROUND));
221 // we use the field as set by the last run of this
223 for(i = 0; i < n; ++i)
225 self.move_didgravity = FALSE;
226 switch(self.move_movetype)
229 case MOVETYPE_FAKEPUSH:
230 error("SV_Physics_Pusher not implemented");
234 case MOVETYPE_FOLLOW:
235 error("SV_Physics_Follow not implemented");
237 case MOVETYPE_NOCLIP:
238 _Movetype_CheckWater();
239 self.move_origin = self.move_origin + ticrate * self.move_velocity;
240 self.move_angles = self.move_angles + ticrate * self.move_avelocity;
241 _Movetype_LinkEdict(FALSE);
244 error("SV_Physics_Step not implemented");
247 error("SV_Physics_Walk not implemented");
250 case MOVETYPE_BOUNCE:
251 case MOVETYPE_BOUNCEMISSILE:
252 case MOVETYPE_FLYMISSILE:
254 _Movetype_Physics_Toss(movedt);
259 self.avelocity = self.move_avelocity;
263 // now continue the move from move_time to time
264 self.velocity = self.move_velocity;
265 if(self.move_didgravity)
266 self.velocity_z -= dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
268 self.angles = self.move_angles + dt * self.avelocity;
270 if(self.movetype != MOVETYPE_NOCLIP)
272 _Movetype_PushEntityTrace(dt * self.velocity);
273 if(!trace_startsolid)
274 self.origin = trace_endpos;
277 self.origin = self.move_origin + dt * self.velocity;
281 self.velocity = self.move_velocity;
282 self.angles = self.move_angles;
283 self.origin = self.move_origin;