1 //--// Some support routines //--//
3 #define anglemodss(a) (a - floor(a / 360) * 360)
5 float(float v) anglemods =
7 v = v - 360 * floor(v / 360);
11 float safeangle(float a)
13 if((a >= -360) && (a <= 360))
17 a -= (360 * floor(a / 360));
22 float shortangle_f(float ang1,float ang2)
38 vector shortangle_v(vector ang1,vector ang2)
42 vtmp_x = shortangle_f(ang1_x,ang2_x);
43 vtmp_y = shortangle_f(ang1_y,ang2_y);
44 vtmp_z = shortangle_f(ang1_z,ang2_z);
49 vector shortangle_vxy(vector ang1,vector ang2)
53 vtmp_x = shortangle_f(ang1_x,ang2_x);
54 vtmp_y = shortangle_f(ang1_y,ang2_y);
60 vector real_origin(entity ent)
69 v = v + ((e.absmin + e.absmax) * 0.5);
73 v = v + ((ent.absmin + ent.absmax) * 0.5);
77 // Plug this into wherever precache is done.
78 void g_turrets_common_precash()
80 precache_model ("models/turrets/c512.md3");
81 precache_model ("models/marker.md3");
90 self.think = SUB_Remove;
91 self.nextthink = time;
99 self.nextthink = time;
102 void mark_error(vector where,float lifetime)
107 err.classname = "error_marker";
108 setmodel(err,"models/marker.md3");
109 setorigin(err,where);
110 err.movetype = MOVETYPE_NONE;
111 err.think = marker_think;
112 err.nextthink = time;
115 err.cnt = lifetime + time;
118 void mark_info(vector where,float lifetime)
123 err.classname = "info_marker";
124 setmodel(err,"models/marker.md3");
125 setorigin(err,where);
126 err.movetype = MOVETYPE_NONE;
127 err.think = marker_think;
128 err.nextthink = time;
131 err.cnt = lifetime + time;
134 entity mark_misc(vector where,float lifetime)
139 err.classname = "mark_misc";
140 setmodel(err,"models/marker.md3");
141 setorigin(err,where);
142 err.movetype = MOVETYPE_NONE;
143 err.think = marker_think;
144 err.nextthink = time;
147 err.cnt = lifetime + time;
152 * Paint a v_color colord circle on target onwho
153 * that fades away over f_time
155 void paint_target(entity onwho, float f_size, vector v_color, float f_time)
160 setmodel(e, "models/turrets/c512.md3"); // precision set above
161 e.scale = (f_size/512);
162 //setsize(e, '0 0 0', '0 0 0');
163 //setattachment(e,onwho,"");
164 setorigin(e,onwho.origin + '0 0 1');
166 e.movetype = MOVETYPE_FLY;
168 e.velocity = (v_color * 32); // + '0 0 1' * 64;
170 e.colormod = v_color;
171 SUB_SetFade(e,time,f_time);
174 void paint_target2(entity onwho, float f_size, vector v_color, float f_time)
179 setmodel(e, "models/turrets/c512.md3"); // precision set above
180 e.scale = (f_size/512);
181 setsize(e, '0 0 0', '0 0 0');
183 setorigin(e,onwho.origin + '0 0 1');
185 e.movetype = MOVETYPE_FLY;
187 e.velocity = (v_color * 32); // + '0 0 1' * 64;
188 e.avelocity_x = -128;
190 e.colormod = v_color;
191 SUB_SetFade(e,time,f_time);
194 void paint_target3(vector where, float f_size, vector v_color, float f_time)
198 setmodel(e, "models/turrets/c512.md3"); // precision set above
199 e.scale = (f_size/512);
200 setsize(e, '0 0 0', '0 0 0');
201 setorigin(e,where+ '0 0 1');
202 e.movetype = MOVETYPE_NONE;
203 e.velocity = '0 0 0';
204 e.colormod = v_color;
205 SUB_SetFade(e,time,f_time);
209 * Return the angle between two enteties
211 vector angleofs(entity from, entity to)
215 // makevectors(from.angles);
216 v_res = normalize(to.origin - from.origin);
217 v_res = vectoangles(v_res);
218 v_res = v_res - from.angles;
220 if (v_res_x < 0) v_res_x += 360;
221 if (v_res_x > 180) v_res_x -= 360;
223 if (v_res_y < 0) v_res_y += 360;
224 if (v_res_y > 180) v_res_y -= 360;
229 vector angleofs2(entity from, vector to)
233 // makevectors(from.angles);
234 v_res = normalize(to - from.origin);
235 v_res = vectoangles(v_res);
236 v_res = v_res - from.angles;
238 if (v_res_x < 0) v_res_x += 360;
239 if (v_res_x > 180) v_res_x -= 360;
241 if (v_res_y < 0) v_res_y += 360;
242 if (v_res_y > 180) v_res_y -= 360;
247 vector angleofs3(vector from,vector from_a, entity to)
251 // makevectors(from.angles);
252 v_res = normalize(to.origin - from);
253 v_res = vectoangles(v_res);
254 v_res = v_res - from_a;
256 if (v_res_x < 0) v_res_x += 360;
257 if (v_res_x > 180) v_res_x -= 360;
259 if (v_res_y < 0) v_res_y += 360;
260 if (v_res_y > 180) v_res_y -= 360;
265 float turret_tag_setup()
269 dprint("Call to turret_tag_setup with self.tur_head missing!\n");
270 self.tur_shotorg = '0 0 0';
274 //if not(self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
275 // setorigin(self.tur_head,gettaginfo(self,gettagindex(self,"tag_head")));
277 self.tur_shotorg = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire"));
279 v_forward = normalize(v_forward);
284 float turret_tag_fire_update()
288 dprint("Call to turret_tag_fire_update with self.tur_head missing!\n");
289 self.tur_shotorg = '0 0 0';
293 self.tur_shotorg = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire"));
294 v_forward = normalize(v_forward);
296 //dprint("update: tur_shotorg: ",vtos(self.tur_shotorg)," origin:", vtos(self.tur_head.origin), " angels: ", vtos(self.tur_head.angles),"\n");
301 void FireImoBeam (vector start,vector end,vector smin,vector smax,
302 float bforce,float f_dmg,float f_velfactor, float deathtype)
305 local vector hitloc, force, endpoint, dir;
308 dir = normalize(end - start);
309 force = dir * bforce;
311 // go a little bit into the wall because we need to hit this wall later
314 // trace multiple times until we hit a wall, each obstacle will be made unsolid.
315 // note down which entities were hit so we can damage them later
318 tracebox(start, smin, smax, end, FALSE, self);
320 // if it is world we can't hurt it so stop now
321 if (trace_ent == world || trace_fraction == 1)
324 if (trace_ent.solid == SOLID_BSP)
327 // make the entity non-solid so we can hit the next one
328 trace_ent.railgunhit = TRUE;
329 trace_ent.railgunhitloc = end;
330 trace_ent.railgunhitsolidbackup = trace_ent.solid;
332 // stop if this is a wall
334 // make the entity non-solid
335 trace_ent.solid = SOLID_NOT;
338 endpoint = trace_endpos;
340 // find all the entities the railgun hit and restore their solid state
341 ent = findfloat(world, railgunhit, TRUE);
344 // restore their solid type
345 ent.solid = ent.railgunhitsolidbackup;
346 ent = findfloat(ent, railgunhit, TRUE);
349 // find all the entities the railgun hit and hurt them
350 ent = findfloat(world, railgunhit, TRUE);
353 // get the details we need to call the damage function
354 hitloc = ent.railgunhitloc;
355 ent.railgunhitloc = '0 0 0';
356 ent.railgunhitsolidbackup = SOLID_NOT;
357 ent.railgunhit = FALSE;
362 Damage (ent, self, self, f_dmg, deathtype, hitloc, force);
363 ent.velocity = ent.velocity * f_velfactor;
364 //ent.alpha = 0.25 + random() * 0.75;
367 // advance to the next entity
368 ent = findfloat(ent, railgunhit, TRUE);
370 trace_endpos = endpoint;
373 void turrets_precache_debug_models()
375 precache_model ("models/turrets/c512.md3");
376 precache_model ("models/pathlib/goodsquare.md3");
377 precache_model ("models/pathlib/badsquare.md3");
378 precache_model ("models/pathlib/square.md3");
379 precache_model ("models/pathlib/edge.md3");
382 void turrets_precash()
384 precache_model ("models/turrets/base-gib1.md3");
385 precache_model ("models/turrets/base-gib2.md3");
386 precache_model ("models/turrets/base-gib3.md3");
387 precache_model ("models/turrets/base-gib4.md3");
389 precache_model ("models/turrets/head-gib1.md3");
390 precache_model ("models/turrets/head-gib2.md3");
391 precache_model ("models/turrets/head-gib3.md3");
392 precache_model ("models/turrets/head-gib4.md3");
393 precache_model ("models/turrets/terrainbase.md3");
395 //precache_model ("models/turrets/base.md3");
396 //precache_model ("models/turrets/flac.md3");
397 //precache_model ("models/turrets/pd_proj.md3");
398 //precache_model ("models/turrets/reactor.md3");
399 //precache_model ("models/turrets/mlrs_rocket.md3");
400 //precache_model ("models/turrets/hellion.md3");
401 //precache_model ("models/turrets/hunter2.md3");
402 //precache_model ("models/turrets/hk.md3");
403 //precache_model ("models/turrets/machinegun.md3");
404 //precache_model ("models/turrets/rocket.md3");
405 //precache_model ("models/turrets/mlrs.md3");
406 //precache_model ("models/turrets/phaser.md3");
407 //precache_model ("models/turrets/phaser_beam.md3");
408 //precache_model ("models/turrets/plasmad.md3");
409 //precache_model ("models/turrets/plasma.md3");
410 //precache_model ("models/turrets/tesla_head.md3");
411 //precache_model ("models/turrets/tesla_base.md3");
412 //turrets_precache_debug_models();