1 void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove;
2 void() SUB_CalcMoveDone;
3 void() SUB_CalcAngleMoveDone;
5 //void() SUB_UseTargets;
32 void SUB_Remove (void)
41 Makes ent invisible or removes it if ent.norespawn
44 void SUB_VanishOrRemove (entity ent)
54 ent.effects = EF_NODRAW;
58 void SUB_SetFade_Think (void)
60 self.think = SUB_SetFade_Think;
61 self.nextthink = self.fade_time;
62 self.alpha = 1 - (time - self.fade_time) * 0.5;
65 if (self.alpha < 0.01) // don't let it reach 0, lest it become fully visible again
66 SUB_VanishOrRemove(self);
67 //if (self.flags & FL_CLIENT && self.deadflag == DEAD_NO) objerror("Fading on non-corpse client!\n");
74 Fade 'ent' out when time >= 'when'
77 void SUB_SetFade (entity ent, float when)
81 ent.think = SUB_SetFade_Think;
89 calculate self.velocity and self.nextthink to reach dest from
90 self.origin traveling at speed
93 void SUB_CalcMoveDone (void)
95 // After moving, set origin to exact final destination
97 setorigin (self, self.finaldest);
98 self.velocity = '0 0 0';
104 void SUB_CalcMove (vector tdest, float tspeed, void() func)
110 objerror ("No speed is defined!");
113 self.finaldest = tdest;
114 self.think = SUB_CalcMoveDone;
116 if (tdest == self.origin)
118 self.velocity = '0 0 0';
119 self.nextthink = self.ltime + 0.1;
123 delta = tdest - self.origin;
124 traveltime = vlen (delta) / tspeed;
126 if (traveltime < 0.1)
128 self.velocity = '0 0 0';
129 self.nextthink = self.ltime + 0.1;
133 self.velocity = delta * (1/traveltime); // QuakeC doesn't allow vector/float division
135 self.nextthink = self.ltime + traveltime;
138 void SUB_CalcMoveEnt (entity ent, vector tdest, float tspeed, void() func)
145 SUB_CalcMove (tdest, tspeed, func);
154 calculate self.avelocity and self.nextthink to reach destangle from
157 The calling function should make sure self.think is valid
160 void SUB_CalcAngleMoveDone (void)
162 // After rotating, set angle to exact final angle
163 self.angles = self.finalangle;
164 self.avelocity = '0 0 0';
170 void SUB_CalcAngleMove (vector destangle, float tspeed, void() func)
176 objerror ("No speed is defined!");
178 delta = destangle = self.angles;
179 traveltime = vlen (delta) / tspeed;
181 self.avelocity = delta * (1 / traveltime);
184 self.finalangle = destangle;
186 self.think = SUB_CalcAngleMoveDone;
187 self.nextthink = self.ltime + traveltime;
190 void SUB_CalcAngleMoveEnt (entity ent, vector destangle, float tspeed, void() func)
197 SUB_CalcAngleMove (destangle, tspeed, func);
206 unused but required by the engine
220 Play a sound at the given location
223 void PointSound (vector org, string snd, float vol, float attn)
228 setorigin (speaker, org);
229 sound (speaker, CHAN_BODY, snd, vol, attn);
239 A version of traceline that must be used by SOLID_SLIDEBOX things that want to hit SOLID_CORPSE things with a trace attack
242 void traceline_hitcorpse (entity source, vector v1, vector v2, float nomonst, entity forent)
246 oldsolid = source.solid;
247 source.solid = SOLID_BBOX;
249 traceline (v1, v2, nomonst, forent);
251 source.solid = oldsolid;
258 Returns a point at least 12 units away from walls
259 (useful for explosion animations, although the blast is performed where it really happened)
263 vector findbetterlocation (vector org)
267 traceline (org, org - '12 0 0', TRUE, world);
268 if (trace_fraction < 1)
271 traceline (loc, loc + '12 0 0', TRUE, world);
272 if (trace_fraction >= 1)
273 org = loc + '12 0 0';
276 traceline (org, org - '-12 0 0', TRUE, world);
277 if (trace_fraction < 1)
280 traceline (loc, loc + '-12 0 0', TRUE, world);
281 if (trace_fraction >= 1)
282 org = loc + '-12 0 0';
285 traceline (org, org - '0 12 0' , TRUE, world);
286 if (trace_fraction < 1)
289 traceline (loc, loc + '0 12 0', TRUE, world);
290 if (trace_fraction >= 1)
291 org = loc + '0 12 0';
294 traceline (org, org - '0 -12 0', TRUE, world);
295 if (trace_fraction < 1)
298 traceline (loc, loc + '0 -12 0', TRUE, world);
299 if (trace_fraction >= 1)
300 org = loc + '0 -12 0';
303 traceline (org, org - '0 0 12' , TRUE, world);
304 if (trace_fraction < 1)
307 traceline (loc, loc + '0 0 12', TRUE, world);
308 if (trace_fraction >= 1)
309 org = loc + '0 0 12';
312 traceline (org, org - '0 0 -12', TRUE, world);
313 if (trace_fraction < 1)
316 traceline (loc, loc + '0 0 -12', TRUE, world);
317 if (trace_fraction >= 1)
318 org = loc + '0 0 -12';
328 Returns a random number between -1.0 and 1.0
333 return 2 * (random () - 0.5);
342 Plays an impact effect
346 void ImpactEffect (entity ent, float weapontype)
349 org2 = findbetterlocation (ent.origin);
352 if (weapontype == IT_ROCKET_LAUNCHER)
355 effect (org2, "models/sprites/dpexplosion1.spr32", 0, 20, 40);
356 sound (ent, CHAN_BODY, "weapons/rocket_impact.wav", 1, ATTN_NORM);
358 else if (weapontype == IT_GRENADE_LAUNCHER)
361 effect (org2, "models/sprites/dpexplosion1.spr32", 0, 20, 30);
362 sound (ent, CHAN_BODY, "weapons/grenade_impact.wav", 1, ATTN_NORM);
364 else if (weapontype == IT_HAGAR)
366 effect (org2, "models/sprites/dpexplosion2.spr32", 0, 20, 30);
369 sound (ent, CHAN_BODY, "weapons/hagexp1.wav", 1, ATTN_NORM);
371 sound (ent, CHAN_BODY, "weapons/hagexp2.wav", 1, ATTN_NORM);
373 sound (ent, CHAN_BODY, "weapons/hagexp3.wav", 1, ATTN_NORM);
375 else if (weapontype == IT_ELECTRO) // Secondary fire
377 effect (org2, "models/sprites/plasmahitwall.spr32", 0, 20, 50);
378 sound (ent, CHAN_BODY, "weapons/plasma_hit.wav", 1, ATTN_NORM);
385 Angc used for animations
390 float angc (float a1, float a2)
422 if (self.movedir != '0 0 0')
423 self.movedir = normalize(self.movedir);
426 if (self.angles == '0 -1 0')
427 self.movedir = '0 0 1';
428 else if (self.angles == '0 -2 0')
429 self.movedir = '0 0 -1';
432 makevectors (self.angles);
433 self.movedir = v_forward;
437 self.angles = '0 0 0';
442 // trigger angles are used for one-way touches. An angle of 0 is assumed
443 // to mean no restrictions, so use a yaw of 360 instead.
444 if (self.movedir == '0 0 0')
445 if (self.angles != '0 0 0')
447 self.solid = SOLID_TRIGGER;
448 setmodel (self, self.model); // set size and link into world
449 self.movetype = MOVETYPE_NONE;
454 void() InitSolidBSPTrigger =
456 // trigger angles are used for one-way touches. An angle of 0 is assumed
457 // to mean no restrictions, so use a yaw of 360 instead.
458 if (self.movedir == '0 0 0')
459 if (self.angles != '0 0 0')
461 self.solid = SOLID_BSP;
462 setmodel (self, self.model); // set size and link into world
463 self.movetype = MOVETYPE_PUSH;
464 // self.modelindex = 0;