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)
49 void SUB_SetFade_Think (void)
51 self.think = SUB_SetFade_Think;
52 self.nextthink = self.fade_time;
53 self.alpha = 1 - (time - self.fade_time) * self.fade_rate;
54 if (self.alpha < 0.01)
55 SUB_VanishOrRemove(self);
56 self.alpha = bound(0.01, self.alpha, 1);
63 Fade 'ent' out when time >= 'when'
66 void SUB_SetFade (entity ent, float when, float fadetime)
68 //if (ent.flags & FL_CLIENT) // && ent.deadflag != DEAD_NO)
71 ent.fade_rate = 1/fadetime;
73 ent.think = SUB_SetFade_Think;
81 calculate self.velocity and self.nextthink to reach dest from
82 self.origin traveling at speed
85 void SUB_CalcMoveDone (void)
87 // After moving, set origin to exact final destination
89 setorigin (self, self.finaldest);
90 self.velocity = '0 0 0';
96 void SUB_CalcMove (vector tdest, float tspeed, void() func)
102 objerror ("No speed is defined!");
105 self.finaldest = tdest;
106 self.think = SUB_CalcMoveDone;
108 if (tdest == self.origin)
110 self.velocity = '0 0 0';
111 self.nextthink = self.ltime + 0.1;
115 delta = tdest - self.origin;
116 traveltime = vlen (delta) / tspeed;
118 if (traveltime < 0.1)
120 self.velocity = '0 0 0';
121 self.nextthink = self.ltime + 0.1;
125 self.velocity = delta * (1/traveltime); // QuakeC doesn't allow vector/float division
127 self.nextthink = self.ltime + traveltime;
130 void SUB_CalcMoveEnt (entity ent, vector tdest, float tspeed, void() func)
137 SUB_CalcMove (tdest, tspeed, func);
146 calculate self.avelocity and self.nextthink to reach destangle from
149 The calling function should make sure self.think is valid
152 void SUB_CalcAngleMoveDone (void)
154 // After rotating, set angle to exact final angle
155 self.angles = self.finalangle;
156 self.avelocity = '0 0 0';
162 void SUB_CalcAngleMove (vector destangle, float tspeed, void() func)
168 objerror ("No speed is defined!");
170 delta = destangle - self.angles;
171 traveltime = vlen (delta) / tspeed;
173 self.avelocity = delta * (1 / traveltime);
176 self.finalangle = destangle;
178 self.think = SUB_CalcAngleMoveDone;
179 self.nextthink = self.ltime + traveltime;
182 void SUB_CalcAngleMoveEnt (entity ent, vector destangle, float tspeed, void() func)
189 SUB_CalcAngleMove (destangle, tspeed, func);
198 unused but required by the engine
212 Play a sound at the given location
215 void PointSound (vector org, string snd, float vol, float attn)
220 setorigin (speaker, org);
221 sound (speaker, CHAN_BODY, snd, vol, attn);
231 A version of traceline that must be used by SOLID_SLIDEBOX things that want to hit SOLID_CORPSE things with a trace attack
232 Additionally it moves players back into the past before the trace and restores them afterward.
235 void traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag)
238 local float oldsolid;
240 // check whether antilagged traces are enabled
243 if (clienttype(forent) != CLIENTTYPE_REAL)
244 lag = 0; // only antilag for clients
246 if (cvar("g_antilag") != 2)
249 // change shooter to SOLID_BBOX so the shot can hit corpses
250 oldsolid = source.solid;
251 source.solid = SOLID_BBOX;
255 // take players back into the past
256 player = player_list;
259 antilag_takeback(player, time - lag);
260 player = player.nextplayer;
265 traceline (v1, v2, nomonst, forent);
267 // restore players to current positions
270 player = player_list;
273 antilag_restore(player);
274 player = player.nextplayer;
278 // restore shooter solid type
279 source.solid = oldsolid;
286 Returns a point at least 12 units away from walls
287 (useful for explosion animations, although the blast is performed where it really happened)
291 vector findbetterlocation (vector org, float mindist)
297 vec = mindist * '1 0 0';
301 traceline (org, org + vec, TRUE, world);
303 if (trace_fraction < 1)
306 traceline (loc, loc + vec, TRUE, world);
307 if (trace_fraction >= 1)
326 Returns a random number between -1.0 and 1.0
331 return 2 * (random () - 0.5);
336 Angc used for animations
341 float angc (float a1, float a2)
373 if (self.movedir != '0 0 0')
374 self.movedir = normalize(self.movedir);
377 if (self.angles == '0 -1 0')
378 self.movedir = '0 0 1';
379 else if (self.angles == '0 -2 0')
380 self.movedir = '0 0 -1';
383 makevectors (self.angles);
384 self.movedir = v_forward;
388 self.angles = '0 0 0';
393 // trigger angles are used for one-way touches. An angle of 0 is assumed
394 // to mean no restrictions, so use a yaw of 360 instead.
395 if (self.movedir == '0 0 0')
396 if (self.angles != '0 0 0')
398 self.solid = SOLID_TRIGGER;
399 setmodel (self, self.model); // set size and link into world, no precision needed
400 self.movetype = MOVETYPE_NONE;
405 void() InitSolidBSPTrigger =
407 // trigger angles are used for one-way touches. An angle of 0 is assumed
408 // to mean no restrictions, so use a yaw of 360 instead.
409 if (self.movedir == '0 0 0')
410 if (self.angles != '0 0 0')
412 self.solid = SOLID_BSP;
413 setmodel (self, self.model); // set size and link into world, no precision needed
414 self.movetype = MOVETYPE_PUSH;
415 // self.modelindex = 0;