3 void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove;
4 void() SUB_CalcMoveDone;
5 void() SUB_CalcAngleMoveDone;
6 //void() SUB_UseTargets;
20 void SUB_Remove (void)
29 Makes client invisible or removes non-client
32 void SUB_VanishOrRemove (entity ent)
34 if (ent.flags & FL_CLIENT)
37 ent.effects = EF_NODRAW;
46 void SUB_SetFade_Think (void)
48 self.think = SUB_SetFade_Think;
49 self.nextthink = self.fade_time;
50 self.alpha = 1 - (time - self.fade_time) * self.fade_rate;
51 if (self.alpha < 0.01)
52 SUB_VanishOrRemove(self);
53 self.alpha = bound(0.01, self.alpha, 1);
60 Fade 'ent' out when time >= 'when'
63 void SUB_SetFade (entity ent, float when, float fadetime)
65 //if (ent.flags & FL_CLIENT) // && ent.deadflag != DEAD_NO)
68 ent.fade_rate = 1/fadetime;
70 ent.think = SUB_SetFade_Think;
78 calculate self.velocity and self.nextthink to reach dest from
79 self.origin traveling at speed
82 void SUB_CalcMoveDone (void)
84 // After moving, set origin to exact final destination
86 setorigin (self, self.finaldest);
87 self.velocity = '0 0 0';
93 void SUB_CalcMove (vector tdest, float tspeed, void() func)
99 objerror ("No speed is defined!");
102 self.finaldest = tdest;
103 self.think = SUB_CalcMoveDone;
105 if (tdest == self.origin)
107 self.velocity = '0 0 0';
108 self.nextthink = self.ltime + 0.1;
112 delta = tdest - self.origin;
113 traveltime = vlen (delta) / tspeed;
115 if (traveltime < 0.1)
117 self.velocity = '0 0 0';
118 self.nextthink = self.ltime + 0.1;
122 self.velocity = delta * (1/traveltime); // QuakeC doesn't allow vector/float division
124 self.nextthink = self.ltime + traveltime;
127 void SUB_CalcMoveEnt (entity ent, vector tdest, float tspeed, void() func)
134 SUB_CalcMove (tdest, tspeed, func);
143 calculate self.avelocity and self.nextthink to reach destangle from
146 The calling function should make sure self.think is valid
149 void SUB_CalcAngleMoveDone (void)
151 // After rotating, set angle to exact final angle
152 self.angles = self.finalangle;
153 self.avelocity = '0 0 0';
159 void SUB_CalcAngleMove (vector destangle, float tspeed, void() func)
165 objerror ("No speed is defined!");
167 delta = destangle = self.angles;
168 traveltime = vlen (delta) / tspeed;
170 self.avelocity = delta * (1 / traveltime);
173 self.finalangle = destangle;
175 self.think = SUB_CalcAngleMoveDone;
176 self.nextthink = self.ltime + traveltime;
179 void SUB_CalcAngleMoveEnt (entity ent, vector destangle, float tspeed, void() func)
186 SUB_CalcAngleMove (destangle, tspeed, func);
195 unused but required by the engine
209 Play a sound at the given location
212 void PointSound (vector org, string snd, float vol, float attn)
217 setorigin (speaker, org);
218 sound (speaker, CHAN_BODY, snd, vol, attn);
228 A version of traceline that must be used by SOLID_SLIDEBOX things that want to hit SOLID_CORPSE things with a trace attack
231 void traceline_hitcorpse (entity source, vector v1, vector v2, float nomonst, entity forent)
235 oldsolid = source.solid;
236 source.solid = SOLID_BBOX;
238 traceline (v1, v2, nomonst, forent);
240 source.solid = oldsolid;
247 Returns a point at least 12 units away from walls
248 (useful for explosion animations, although the blast is performed where it really happened)
252 vector findbetterlocation (vector org)
256 traceline (org, org - '12 0 0', TRUE, world);
257 if (trace_fraction < 1)
260 traceline (loc, loc + '12 0 0', TRUE, world);
261 if (trace_fraction >= 1)
262 org = loc + '12 0 0';
265 traceline (org, org - '-12 0 0', TRUE, world);
266 if (trace_fraction < 1)
269 traceline (loc, loc + '-12 0 0', TRUE, world);
270 if (trace_fraction >= 1)
271 org = loc + '-12 0 0';
274 traceline (org, org - '0 12 0' , TRUE, world);
275 if (trace_fraction < 1)
278 traceline (loc, loc + '0 12 0', TRUE, world);
279 if (trace_fraction >= 1)
280 org = loc + '0 12 0';
283 traceline (org, org - '0 -12 0', TRUE, world);
284 if (trace_fraction < 1)
287 traceline (loc, loc + '0 -12 0', TRUE, world);
288 if (trace_fraction >= 1)
289 org = loc + '0 -12 0';
292 traceline (org, org - '0 0 12' , TRUE, world);
293 if (trace_fraction < 1)
296 traceline (loc, loc + '0 0 12', TRUE, world);
297 if (trace_fraction >= 1)
298 org = loc + '0 0 12';
301 traceline (org, org - '0 0 -12', TRUE, world);
302 if (trace_fraction < 1)
305 traceline (loc, loc + '0 0 -12', TRUE, world);
306 if (trace_fraction >= 1)
307 org = loc + '0 0 -12';
317 Returns a random number between -1.0 and 1.0
322 return 2 * (random () - 0.5);
331 Plays an impact effect
335 void ImpactEffect (entity ent, float weapontype)
338 org2 = findbetterlocation (ent.origin);
341 if (weapontype == IT_ROCKET_LAUNCHER)
344 effect (org2, "models/sprites/rocketexplosion.spr32", 0, 20, 40);
345 sound (ent, CHAN_BODY, "weapons/rocket_impact.wav", 1, ATTN_NORM);
347 else if (weapontype == IT_GRENADE_LAUNCHER)
350 effect (org2, "models/sprites/grenadeexplosion.spr32", 0, 20, 30);
351 sound (ent, CHAN_BODY, "weapons/grenade_impact.wav", 1, ATTN_NORM);
353 else if (weapontype == IT_HAGAR)
355 effect (org2, "models/sprites/hagarexplosion.spr32", 0, 20, 30);
358 sound (ent, CHAN_BODY, "weapons/hagexp1.wav", 1, ATTN_NORM);
360 sound (ent, CHAN_BODY, "weapons/hagexp2.wav", 1, ATTN_NORM);
362 sound (ent, CHAN_BODY, "weapons/hagexp3.wav", 1, ATTN_NORM);
369 Angc used for animations
374 float angc (float a1, float a2)
406 if (self.movedir != '0 0 0')
407 self.movedir = normalize(self.movedir);
410 if (self.angles == '0 -1 0')
411 self.movedir = '0 0 1';
412 else if (self.angles == '0 -2 0')
413 self.movedir = '0 0 -1';
416 makevectors (self.angles);
417 self.movedir = v_forward;
421 self.angles = '0 0 0';
426 // trigger angles are used for one-way touches. An angle of 0 is assumed
427 // to mean no restrictions, so use a yaw of 360 instead.
428 if (self.movedir == '0 0 0')
429 if (self.angles != '0 0 0')
431 self.solid = SOLID_TRIGGER;
432 setmodel (self, self.model); // set size and link into world
433 self.movetype = MOVETYPE_NONE;
438 void() InitSolidBSPTrigger =
440 // trigger angles are used for one-way touches. An angle of 0 is assumed
441 // to mean no restrictions, so use a yaw of 360 instead.
442 if (self.movedir == '0 0 0')
443 if (self.angles != '0 0 0')
445 self.solid = SOLID_BSP;
446 setmodel (self, self.model); // set size and link into world
447 self.movetype = MOVETYPE_PUSH;
448 // self.modelindex = 0;