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 Play a sound at the given location
217 void PointSound (vector org, string snd, float vol, float attn)
222 setorigin (speaker, org);
223 sound (speaker, CHAN_BODY, snd, vol, attn);
233 A version of traceline that must be used by SOLID_SLIDEBOX things that want to hit SOLID_CORPSE things with a trace attack
234 Additionally it moves players back into the past before the trace and restores them afterward.
237 void traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag)
240 local float oldsolid;
242 // check whether antilagged traces are enabled
245 if (clienttype(forent) != CLIENTTYPE_REAL)
246 lag = 0; // only antilag for clients
248 if (cvar("g_antilag") != 2)
251 // change shooter to SOLID_BBOX so the shot can hit corpses
252 oldsolid = source.solid;
253 source.solid = SOLID_BBOX;
257 // take players back into the past
258 player = player_list;
261 antilag_takeback(player, time - lag);
262 player = player.nextplayer;
267 traceline (v1, v2, nomonst, forent);
269 // restore players to current positions
272 player = player_list;
275 antilag_restore(player);
276 player = player.nextplayer;
280 // restore shooter solid type
281 source.solid = oldsolid;
288 Returns a point at least 12 units away from walls
289 (useful for explosion animations, although the blast is performed where it really happened)
293 vector findbetterlocation (vector org, float mindist)
299 vec = mindist * '1 0 0';
303 traceline (org, org + vec, TRUE, world);
305 if (trace_fraction < 1)
308 traceline (loc, loc + vec, TRUE, world);
309 if (trace_fraction >= 1)
328 Returns a random number between -1.0 and 1.0
333 return 2 * (random () - 0.5);
338 Angc used for animations
343 float angc (float a1, float a2)
375 if (self.movedir != '0 0 0')
376 self.movedir = normalize(self.movedir);
379 if (self.angles == '0 -1 0')
380 self.movedir = '0 0 1';
381 else if (self.angles == '0 -2 0')
382 self.movedir = '0 0 -1';
385 makevectors (self.angles);
386 self.movedir = v_forward;
390 self.angles = '0 0 0';
395 // trigger angles are used for one-way touches. An angle of 0 is assumed
396 // to mean no restrictions, so use a yaw of 360 instead.
397 if (self.movedir == '0 0 0')
398 if (self.angles != '0 0 0')
400 self.solid = SOLID_TRIGGER;
401 setmodel (self, self.model); // set size and link into world, no precision needed
402 self.movetype = MOVETYPE_NONE;
407 void InitSolidBSPTrigger()
409 // trigger angles are used for one-way touches. An angle of 0 is assumed
410 // to mean no restrictions, so use a yaw of 360 instead.
411 if (self.movedir == '0 0 0')
412 if (self.angles != '0 0 0')
414 self.solid = SOLID_BSP;
415 setmodel (self, self.model); // set size and link into world, no precision needed
416 self.movetype = MOVETYPE_PUSH;
417 // self.modelindex = 0;