3 void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove;
4 void() SUB_CalcMoveDone;
5 void() SUB_CalcAngleMoveDone;
6 //void() SUB_UseTargets;
9 void spawnfunc_info_null (void)
12 // if anything breaks, tell the mapper to fix his map! info_null is meant to remove itself immediately.
22 void SUB_Remove (void)
31 Makes client invisible or removes non-client
34 void SUB_VanishOrRemove (entity ent)
36 if (ent.flags & FL_CLIENT)
51 void SUB_SetFade_Think (void)
53 self.think = SUB_SetFade_Think;
54 self.nextthink = self.fade_time;
55 self.alpha = 1 - (time - self.fade_time) * self.fade_rate;
56 if (self.alpha < 0.01)
57 SUB_VanishOrRemove(self);
58 self.alpha = bound(0.01, self.alpha, 1);
65 Fade 'ent' out when time >= 'when'
68 void SUB_SetFade (entity ent, float when, float fadetime)
70 //if (ent.flags & FL_CLIENT) // && ent.deadflag != DEAD_NO)
73 ent.fade_rate = 1/fadetime;
75 ent.think = SUB_SetFade_Think;
83 calculate self.velocity and self.nextthink to reach dest from
84 self.origin traveling at speed
87 void SUB_CalcMoveDone (void)
89 // After moving, set origin to exact final destination
91 setorigin (self, self.finaldest);
92 self.velocity = '0 0 0';
98 void SUB_CalcMove (vector tdest, float tspeed, void() func)
104 objerror ("No speed is defined!");
107 self.finaldest = tdest;
108 self.think = SUB_CalcMoveDone;
110 if (tdest == self.origin)
112 self.velocity = '0 0 0';
113 self.nextthink = self.ltime + 0.1;
117 delta = tdest - self.origin;
118 traveltime = vlen (delta) / tspeed;
120 if (traveltime < 0.1)
122 self.velocity = '0 0 0';
123 self.nextthink = self.ltime + 0.1;
127 self.velocity = delta * (1/traveltime); // QuakeC doesn't allow vector/float division
129 self.nextthink = self.ltime + traveltime;
132 void SUB_CalcMoveEnt (entity ent, vector tdest, float tspeed, void() func)
139 SUB_CalcMove (tdest, tspeed, func);
148 calculate self.avelocity and self.nextthink to reach destangle from
151 The calling function should make sure self.think is valid
154 void SUB_CalcAngleMoveDone (void)
156 // After rotating, set angle to exact final angle
157 self.angles = self.finalangle;
158 self.avelocity = '0 0 0';
164 void SUB_CalcAngleMove (vector destangle, float tspeed, void() func)
170 objerror ("No speed is defined!");
172 delta = destangle - self.angles;
173 traveltime = vlen (delta) / tspeed;
175 self.avelocity = delta * (1 / traveltime);
178 self.finalangle = destangle;
180 self.think = SUB_CalcAngleMoveDone;
181 self.nextthink = self.ltime + traveltime;
184 void SUB_CalcAngleMoveEnt (entity ent, vector destangle, float tspeed, void() func)
191 SUB_CalcAngleMove (destangle, tspeed, func);
200 unused but required by the engine
214 A version of traceline that must be used by SOLID_SLIDEBOX things that want to hit SOLID_CORPSE things with a trace attack
215 Additionally it moves players back into the past before the trace and restores them afterward.
218 void traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag)
221 local float oldsolid;
223 // check whether antilagged traces are enabled
226 if (clienttype(forent) != CLIENTTYPE_REAL)
227 lag = 0; // only antilag for clients
229 if (cvar("g_antilag") != 2)
232 // change shooter to SOLID_BBOX so the shot can hit corpses
233 oldsolid = source.solid;
234 source.solid = SOLID_BBOX;
238 // take players back into the past
239 player = player_list;
242 antilag_takeback(player, time - lag);
243 player = player.nextplayer;
248 traceline (v1, v2, nomonst, forent);
250 // restore players to current positions
253 player = player_list;
256 antilag_restore(player);
257 player = player.nextplayer;
261 // restore shooter solid type
262 source.solid = oldsolid;
269 Returns a point at least 12 units away from walls
270 (useful for explosion animations, although the blast is performed where it really happened)
274 vector findbetterlocation (vector org, float mindist)
280 vec = mindist * '1 0 0';
284 traceline (org, org + vec, TRUE, world);
286 if (trace_fraction < 1)
289 traceline (loc, loc + vec, TRUE, world);
290 if (trace_fraction >= 1)
309 Returns a random number between -1.0 and 1.0
314 return 2 * (random () - 0.5);
319 Angc used for animations
324 float angc (float a1, float a2)
347 void SetBrushEntityModel()
351 precache_model(self.model);
352 setmodel(self, self.model); // no precision needed
354 setorigin(self, self.origin);
355 setsize(self, self.mins, self.maxs);
366 if (self.movedir != '0 0 0')
367 self.movedir = normalize(self.movedir);
370 if (self.angles == '0 -1 0')
371 self.movedir = '0 0 1';
372 else if (self.angles == '0 -2 0')
373 self.movedir = '0 0 -1';
376 makevectors (self.angles);
377 self.movedir = v_forward;
381 self.angles = '0 0 0';
386 // trigger angles are used for one-way touches. An angle of 0 is assumed
387 // to mean no restrictions, so use a yaw of 360 instead.
388 if (self.movedir == '0 0 0')
389 if (self.angles != '0 0 0')
391 self.solid = SOLID_TRIGGER;
392 SetBrushEntityModel();
393 self.movetype = MOVETYPE_NONE;
398 void InitSolidBSPTrigger()
400 // trigger angles are used for one-way touches. An angle of 0 is assumed
401 // to mean no restrictions, so use a yaw of 360 instead.
402 if (self.movedir == '0 0 0')
403 if (self.angles != '0 0 0')
405 self.solid = SOLID_BSP;
406 SetBrushEntityModel();
407 self.movetype = MOVETYPE_PUSH;
408 // self.modelindex = 0;
412 void InitMovingBrushTrigger()
414 // trigger angles are used for one-way touches. An angle of 0 is assumed
415 // to mean no restrictions, so use a yaw of 360 instead.
416 self.solid = SOLID_BSP;
417 SetBrushEntityModel();
418 self.movetype = MOVETYPE_PUSH;