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
20 if(self.move_moveflags & MOVEFLAG_STOPONIMPACT)
22 // don't CLIP the velocity, but stop ENTIRELY
23 self.velocity = '0 0 0';
24 self.avelocity = '0 0 0';
28 void _Movetype_LinkEdict(float touch_triggers) // SV_LinkEdict
32 float _Movetype_TestEntityPosition(vector ofs) // SV_TestEntityPosition
36 org = self.move_origin + ofs;
38 cont = self.dphitcontentsmask;
39 self.dphitcontentsmask = DPCONTENTS_SOLID;
40 tracebox(self.move_origin, self.mins, self.maxs, self.move_origin, MOVE_NOMONSTERS, self);
41 self.dphitcontentsmask = cont;
46 if(vlen(trace_endpos - self.move_origin) > 0.0001)
47 self.move_origin = trace_endpos;
51 float _Movetype_UnstickEntity() // SV_UnstickEntity
53 if(!_Movetype_TestEntityPosition('0 0 0'))
55 if(!_Movetype_TestEntityPosition('-1 0 0')) goto success;
56 if(!_Movetype_TestEntityPosition('1 0 0')) goto success;
57 if(!_Movetype_TestEntityPosition('0 -1 0')) goto success;
58 if(!_Movetype_TestEntityPosition('0 1 0')) goto success;
59 if(!_Movetype_TestEntityPosition('-1 -1 0')) goto success;
60 if(!_Movetype_TestEntityPosition('1 -1 0')) goto success;
61 if(!_Movetype_TestEntityPosition('-1 1 0')) goto success;
62 if(!_Movetype_TestEntityPosition('1 1 0')) goto success;
64 for(i = 1; i <= 17; ++i)
66 if(!_Movetype_TestEntityPosition('0 0 -1' * i)) goto success;
67 if(!_Movetype_TestEntityPosition('0 0 1' * i)) goto success;
69 dprint("Some entity is stuck\n");
72 dprint("Unstuck some entity\n");
73 _Movetype_LinkEdict(TRUE);
77 vector _Movetype_ClipVelocity(vector vel, vector norm, float f) // SV_ClipVelocity
79 vel = vel - ((vel * norm) * norm) * f;
81 if(vel_x > -0.1 && vel_x < 0.1) vel_x = 0;
82 if(vel_y > -0.1 && vel_y < 0.1) vel_y = 0;
83 if(vel_z > -0.1 && vel_z < 0.1) vel_z = 0;
88 void _Movetype_PushEntityTrace(vector push)
93 end = self.move_origin + push;
95 if(self.move_movetype == MOVETYPE_FLYMISSILE)
97 else if(self.solid == SOLID_TRIGGER || self.solid == SOLID_NOT)
98 type = MOVE_NOMONSTERS;
102 tracebox(self.move_origin, self.mins, self.maxs, end, type, self);
105 float _Movetype_PushEntity(vector push, float failonstartsolid) // SV_PushEntity
107 _Movetype_PushEntityTrace(push);
109 if(trace_startsolid && failonstartsolid)
110 return trace_fraction;
112 self.move_origin = trace_endpos;
114 if(self.solid >= SOLID_TRIGGER && trace_ent && (!(self.move_flags & FL_ONGROUND) || (self.move_groundentity != trace_ent)))
115 _Movetype_Impact(trace_ent);
117 return trace_fraction;
120 void _Movetype_Physics_Toss(float dt) // SV_Physics_Toss
122 if(self.move_flags & FL_ONGROUND)
124 if(self.velocity_z >= 1/32)
125 self.move_flags &~= FL_ONGROUND;
126 else if(!self.move_groundentity)
128 else if(self.move_suspendedinair && wasfreed(self.move_groundentity))
130 self.move_groundentity = world;
135 self.move_suspendedinair = FALSE;
137 _Movetype_CheckVelocity();
139 if(self.move_movetype == MOVETYPE_BOUNCE || self.move_movetype == MOVETYPE_TOSS)
141 self.move_didgravity = TRUE;
142 self.move_velocity_z -= dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
145 self.move_angles = self.move_angles + self.move_avelocity * dt;
148 move = self.move_velocity * dt;
150 _Movetype_PushEntity(move, TRUE);
156 _Movetype_UnstickEntity();
157 _Movetype_PushEntity(move, FALSE);
162 if(trace_fraction < 1)
164 if(self.move_movetype == MOVETYPE_BOUNCEMISSILE)
166 self.move_velocity = _Movetype_ClipVelocity(self.move_velocity, trace_plane_normal, 2.0);
167 self.move_flags &~= FL_ONGROUND;
169 else if(self.move_movetype == MOVETYPE_BOUNCE)
171 self.move_velocity = _Movetype_ClipVelocity(self.move_velocity, trace_plane_normal, 1.5);
174 d = trace_plane_normal * self.move_velocity;
175 if(trace_plane_normal_z > 0.7 && d < 60 && d > -60)
177 self.move_flags |= FL_ONGROUND;
178 self.move_groundentity = trace_ent;
179 self.move_velocity = '0 0 0';
180 self.move_avelocity = '0 0 0';
183 self.move_flags &~= FL_ONGROUND;
187 self.move_velocity = _Movetype_ClipVelocity(self.move_velocity, trace_plane_normal, 1.0);
188 if(trace_plane_normal_z > 0.7)
190 self.move_flags |= FL_ONGROUND;
191 self.move_groundentity = trace_ent;
192 if(trace_ent.solid == SOLID_BSP)
193 self.move_suspendedinair = TRUE;
194 self.move_velocity = '0 0 0';
195 self.move_avelocity = '0 0 0';
198 self.move_flags &~= FL_ONGROUND;
202 _Movetype_CheckWaterTransition();
205 void Movetype_Physics(float matchserver) // SV_Physics_Entity
207 float n, i, dt, movedt;
209 dt = time - self.move_time;
214 n = max(0, floor(dt / ticrate));
216 self.move_time += n * ticrate;
223 self.move_time = time;
226 //self.move_didgravity = ((self.move_movetype == MOVETYPE_BOUNCE || self.move_movetype == MOVETYPE_TOSS) && !(self.move_flags & FL_ONGROUND));
227 // we use the field as set by the last run of this
229 for(i = 0; i < n; ++i)
231 self.move_didgravity = FALSE;
232 switch(self.move_movetype)
235 case MOVETYPE_FAKEPUSH:
236 error("SV_Physics_Pusher not implemented");
240 case MOVETYPE_FOLLOW:
241 error("SV_Physics_Follow not implemented");
243 case MOVETYPE_NOCLIP:
244 _Movetype_CheckWater();
245 self.move_origin = self.move_origin + ticrate * self.move_velocity;
246 self.move_angles = self.move_angles + ticrate * self.move_avelocity;
247 _Movetype_LinkEdict(FALSE);
250 error("SV_Physics_Step not implemented");
253 error("SV_Physics_Walk not implemented");
256 case MOVETYPE_BOUNCE:
257 case MOVETYPE_BOUNCEMISSILE:
258 case MOVETYPE_FLYMISSILE:
260 _Movetype_Physics_Toss(movedt);
265 self.avelocity = self.move_avelocity;
267 if(dt > 0 && self.move_movetype != MOVETYPE_NONE)
269 // now continue the move from move_time to time
270 self.velocity = self.move_velocity;
271 if(self.move_didgravity)
272 self.velocity_z -= dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
274 self.angles = self.move_angles + dt * self.avelocity;
276 if(self.movetype != MOVETYPE_NOCLIP)
278 _Movetype_PushEntityTrace(dt * self.velocity);
279 if(!trace_startsolid)
280 self.origin = trace_endpos;
283 self.origin = self.move_origin + dt * self.velocity;
287 self.velocity = self.move_velocity;
288 self.angles = self.move_angles;
289 self.origin = self.move_origin;