1 void() SUB_Null = {};
\r
3 void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove;
\r
4 void() SUB_CalcMoveDone;
\r
5 void() SUB_CalcAngleMoveDone;
\r
6 //void() SUB_UseTargets;
\r
9 void info_null (void)
\r
20 void SUB_Remove (void)
\r
29 Makes client invisible or removes non-client
\r
32 void SUB_VanishOrRemove (entity ent)
\r
34 if (ent.flags & FL_CLIENT)
\r
37 ent.effects = EF_NODRAW;
\r
46 void ExtinguishFlame(entity targ);
\r
48 void SUB_SetFade_Think (void)
\r
51 ExtinguishFlame(self);
\r
52 self.think = SUB_SetFade_Think;
\r
53 self.nextthink = self.fade_time;
\r
54 self.alpha = 1 - (time - self.fade_time) * self.fade_rate;
\r
55 if (self.alpha < 0.01)
\r
56 SUB_VanishOrRemove(self);
\r
57 self.alpha = bound(0.01, self.alpha, 1);
\r
64 Fade 'ent' out when time >= 'when'
\r
67 void SUB_SetFade (entity ent, float when, float fadetime)
\r
69 //if (ent.flags & FL_CLIENT) // && ent.deadflag != DEAD_NO)
\r
72 ent.fade_rate = 1/fadetime;
\r
73 ent.fade_time = when;
\r
74 ent.think = SUB_SetFade_Think;
\r
75 ent.nextthink = when;
\r
82 calculate self.velocity and self.nextthink to reach dest from
\r
83 self.origin traveling at speed
\r
87 void SUB_CalcMoveDone (void)
\r
89 // After moving, set origin to exact final destination
\r
91 setorigin (self, self.finaldest);
\r
92 self.velocity = '0 0 0';
\r
93 self.nextthink = -1;
\r
98 /*void SUB_CalcMove (vector tdest, float tspeed, void() func)
\r
104 objerror ("No speed is defined!");
\r
106 self.think1 = func;
\r
107 self.finaldest = tdest;
\r
108 self.think = SUB_CalcMoveDone;
\r
110 if (tdest == self.origin)
\r
112 self.velocity = '0 0 0';
\r
113 self.nextthink = self.ltime + 0.1;
\r
117 delta = tdest - self.origin;
\r
118 traveltime = vlen (delta) / tspeed;
\r
120 if (traveltime < 0.1)
\r
122 self.velocity = '0 0 0';
\r
123 self.nextthink = self.ltime + 0.1;
\r
127 self.velocity = delta * (1/traveltime); // QuakeC doesn't allow vector/float division
\r
129 self.nextthink = self.ltime + traveltime;
\r
132 void () SUB_CalcMoveDone =
\r
134 setorigin (self, self.finaldest);
\r
135 self.velocity = '0 0 0';
\r
136 self.nextthink = -1;
\r
143 void (vector tdest, float tspeed, void() func) SUB_CalcMove =
\r
145 local vector vdestdelta;
\r
147 local float traveltime;
\r
151 objerror ("No speed is defined!");
\r
153 self.think1 = func;
\r
154 self.finaldest = tdest;
\r
155 self.think = SUB_CalcMoveDone;
\r
156 if ((tdest == self.origin))
\r
158 self.velocity = '0 0 0';
\r
159 self.nextthink = (self.ltime + 0.1);
\r
162 vdestdelta = (tdest - self.origin);
\r
163 len = vlen (vdestdelta);
\r
164 traveltime = (len / tspeed);
\r
165 if ((traveltime < 0.1))
\r
167 self.velocity = '0 0 0';
\r
168 self.nextthink = (self.ltime + 0.1);
\r
171 self.nextthink = (self.ltime + traveltime);
\r
172 self.velocity = (vdestdelta * (1 / traveltime));
\r
175 void SUB_CalcMoveEnt (entity ent, vector tdest, float tspeed, void() func)
\r
182 SUB_CalcMove (tdest, tspeed, func);
\r
191 calculate self.avelocity and self.nextthink to reach destangle from
\r
192 self.angles rotating
\r
194 The calling function should make sure self.think is valid
\r
197 void SUB_CalcAngleMoveDone (void)
\r
199 // After rotating, set angle to exact final angle
\r
200 self.angles = self.finalangle;
\r
201 self.avelocity = '0 0 0';
\r
202 self.nextthink = -1;
\r
207 void SUB_CalcAngleMove (vector destangle, float tspeed, void() func)
\r
213 objerror ("No speed is defined!");
\r
215 delta = destangle = self.angles;
\r
216 traveltime = vlen (delta) / tspeed;
\r
218 self.avelocity = delta * (1 / traveltime);
\r
220 self.think1 = func;
\r
221 self.finalangle = destangle;
\r
223 self.think = SUB_CalcAngleMoveDone;
\r
224 self.nextthink = self.ltime + traveltime;
\r
227 void SUB_CalcAngleMoveEnt (entity ent, vector destangle, float tspeed, void() func)
\r
234 SUB_CalcAngleMove (destangle, tspeed, func);
\r
243 unused but required by the engine
\r
257 Play a sound at the given location
\r
260 void PointSound (vector org, string snd, float vol, float attn)
\r
264 speaker = spawn ();
\r
265 setorigin (speaker, org);
\r
266 sound (speaker, CHAN_BODY, snd, vol, attn);
\r
274 traceline_hitcorpse
\r
276 A version of traceline that must be used by SOLID_SLIDEBOX things that want to hit SOLID_CORPSE things with a trace attack
\r
279 void traceline_hitcorpse (entity source, vector v1, vector v2, float nomonst, entity forent)
\r
283 oldsolid = source.solid;
\r
284 source.solid = SOLID_BBOX;
\r
286 traceline (v1, v2, nomonst, forent);
\r
288 source.solid = oldsolid;
\r
295 Returns a point at least 12 units away from walls
\r
296 (useful for explosion animations, although the blast is performed where it really happened)
\r
300 vector findbetterlocation (vector org)
\r
304 traceline (org, org - '12 0 0', TRUE, world);
\r
305 if (trace_fraction < 1)
\r
307 loc = trace_endpos;
\r
308 traceline (loc, loc + '12 0 0', TRUE, world);
\r
309 if (trace_fraction >= 1)
\r
310 org = loc + '12 0 0';
\r
313 traceline (org, org - '-12 0 0', TRUE, world);
\r
314 if (trace_fraction < 1)
\r
316 loc = trace_endpos;
\r
317 traceline (loc, loc + '-12 0 0', TRUE, world);
\r
318 if (trace_fraction >= 1)
\r
319 org = loc + '-12 0 0';
\r
322 traceline (org, org - '0 12 0' , TRUE, world);
\r
323 if (trace_fraction < 1)
\r
325 loc = trace_endpos;
\r
326 traceline (loc, loc + '0 12 0', TRUE, world);
\r
327 if (trace_fraction >= 1)
\r
328 org = loc + '0 12 0';
\r
331 traceline (org, org - '0 -12 0', TRUE, world);
\r
332 if (trace_fraction < 1)
\r
334 loc = trace_endpos;
\r
335 traceline (loc, loc + '0 -12 0', TRUE, world);
\r
336 if (trace_fraction >= 1)
\r
337 org = loc + '0 -12 0';
\r
340 traceline (org, org - '0 0 12' , TRUE, world);
\r
341 if (trace_fraction < 1)
\r
343 loc = trace_endpos;
\r
344 traceline (loc, loc + '0 0 12', TRUE, world);
\r
345 if (trace_fraction >= 1)
\r
346 org = loc + '0 0 12';
\r
349 traceline (org, org - '0 0 -12', TRUE, world);
\r
350 if (trace_fraction < 1)
\r
352 loc = trace_endpos;
\r
353 traceline (loc, loc + '0 0 -12', TRUE, world);
\r
354 if (trace_fraction >= 1)
\r
355 org = loc + '0 0 -12';
\r
365 Returns a random number between -1.0 and 1.0
\r
368 float crandom (void)
\r
370 return 2 * (random () - 0.5);
\r
375 Angc used for animations
\r
380 float angc (float a1, float a2)
\r
410 void() SetMovedir =
\r
412 if (self.movedir != '0 0 0')
\r
413 self.movedir = normalize(self.movedir);
\r
416 if (self.angles == '0 -1 0')
\r
417 self.movedir = '0 0 1';
\r
418 else if (self.angles == '0 -2 0')
\r
419 self.movedir = '0 0 -1';
\r
422 makevectors (self.angles);
\r
423 self.movedir = v_forward;
\r
427 self.angles = '0 0 0';
\r
430 void() InitTrigger =
\r
432 // trigger angles are used for one-way touches. An angle of 0 is assumed
\r
433 // to mean no restrictions, so use a yaw of 360 instead.
\r
434 if (self.movedir == '0 0 0')
\r
435 if (self.angles != '0 0 0')
\r
437 self.solid = SOLID_TRIGGER;
\r
438 setmodel (self, self.model); // set size and link into world
\r
439 self.movetype = MOVETYPE_NONE;
\r
440 self.modelindex = 0;
\r
444 void() InitSolidBSPTrigger =
\r
446 // trigger angles are used for one-way touches. An angle of 0 is assumed
\r
447 // to mean no restrictions, so use a yaw of 360 instead.
\r
448 if (self.movedir == '0 0 0')
\r
449 if (self.angles != '0 0 0')
\r
451 self.solid = SOLID_BSP;
\r
452 setmodel (self, self.model); // set size and link into world
\r
453 self.movetype = MOVETYPE_PUSH;
\r
454 // self.modelindex = 0;
\r