1 //--// Some supptort routines //--//
\r
3 #define anglemods(a) (a - floor(a / 360) * 360)
\r
5 float shortangle_f(float ang1,float ang2)
\r
21 vector shortangle_v(vector ang1,vector ang2)
\r
25 vtmp_x = shortangle_f(ang1_x,ang2_x);
\r
26 vtmp_y = shortangle_f(ang1_y,ang2_y);
\r
27 vtmp_z = shortangle_f(ang1_z,ang2_z);
\r
33 vector real_origin(entity ent)
\r
41 // v = v + e.origin;
\r
42 v = v + ((e.absmin + e.absmax) * 0.5);
\r
45 //v = v + ent.origin;
\r
46 v = v + ((ent.absmin + ent.absmax) * 0.5);
\r
50 // Plug this into wherever precache is done.
\r
51 void g_turrets_common_precash()
\r
53 precache_model ("models/turrets/c512.md3");
\r
54 precache_model ("models/marker.md3");
\r
63 self.think = SUB_Remove;
\r
64 self.nextthink = time;
\r
72 self.nextthink = time;
\r
75 void mark_error(vector where,float lifetime)
\r
80 err.classname = "error_marker";
\r
81 setmodel(err,"models/marker.md3");
\r
82 setorigin(err,where);
\r
83 err.movetype = MOVETYPE_NONE;
\r
84 err.think = marker_think;
\r
85 err.nextthink = time;
\r
88 err.cnt = lifetime + time;
\r
91 void mark_info(vector where,float lifetime)
\r
96 err.classname = "info_marker";
\r
97 setmodel(err,"models/marker.md3");
\r
98 setorigin(err,where);
\r
99 err.movetype = MOVETYPE_NONE;
\r
100 err.think = marker_think;
\r
101 err.nextthink = time;
\r
104 err.cnt = lifetime + time;
\r
107 entity mark_misc(vector where,float lifetime)
\r
112 err.classname = "mark_misc";
\r
113 setmodel(err,"models/marker.md3");
\r
114 setorigin(err,where);
\r
115 err.movetype = MOVETYPE_NONE;
\r
116 err.think = marker_think;
\r
117 err.nextthink = time;
\r
120 err.cnt = lifetime + time;
\r
125 * Paint a v_color colord circle on target onwho
\r
126 * that fades away over f_time
\r
128 void paint_target(entity onwho, float f_size, vector v_color, float f_time)
\r
133 setmodel(e, "models/turrets/c512.md3"); // precision set above
\r
134 e.scale = (f_size/512);
\r
135 //setsize(e, '0 0 0', '0 0 0');
\r
136 //setattachment(e,onwho,"");
\r
137 setorigin(e,onwho.origin + '0 0 1');
\r
139 e.movetype = MOVETYPE_FLY;
\r
141 e.velocity = (v_color * 32); // + '0 0 1' * 64;
\r
143 e.colormod = v_color;
\r
144 SUB_SetFade(e,time,f_time);
\r
147 void paint_target2(entity onwho, float f_size, vector v_color, float f_time)
\r
152 setmodel(e, "models/turrets/c512.md3"); // precision set above
\r
153 e.scale = (f_size/512);
\r
154 setsize(e, '0 0 0', '0 0 0');
\r
156 setorigin(e,onwho.origin + '0 0 1');
\r
158 e.movetype = MOVETYPE_FLY;
\r
160 e.velocity = (v_color * 32); // + '0 0 1' * 64;
\r
161 e.avelocity_x = -128;
\r
163 e.colormod = v_color;
\r
164 SUB_SetFade(e,time,f_time);
\r
167 void paint_target3(vector where, float f_size, vector v_color, float f_time)
\r
171 setmodel(e, "models/turrets/c512.md3"); // precision set above
\r
172 e.scale = (f_size/512);
\r
173 setsize(e, '0 0 0', '0 0 0');
\r
174 setorigin(e,where+ '0 0 1');
\r
175 e.movetype = MOVETYPE_NONE;
\r
176 e.velocity = '0 0 0';
\r
177 e.colormod = v_color;
\r
178 SUB_SetFade(e,time,f_time);
\r
182 * Return the angle between two enteties
\r
184 vector angleofs(entity from, entity to)
\r
188 // makevectors(from.angles);
\r
189 v_res = normalize(to.origin - from.origin);
\r
190 v_res = vectoangles(v_res);
\r
191 v_res = v_res - from.angles;
\r
193 if (v_res_x < 0) v_res_x += 360;
\r
194 if (v_res_x > 180) v_res_x -= 360;
\r
196 if (v_res_y < 0) v_res_y += 360;
\r
197 if (v_res_y > 180) v_res_y -= 360;
\r
202 vector angleofs2(entity from, vector to)
\r
206 // makevectors(from.angles);
\r
207 v_res = normalize(to - from.origin);
\r
208 v_res = vectoangles(v_res);
\r
209 v_res = v_res - from.angles;
\r
211 if (v_res_x < 0) v_res_x += 360;
\r
212 if (v_res_x > 180) v_res_x -= 360;
\r
214 if (v_res_y < 0) v_res_y += 360;
\r
215 if (v_res_y > 180) v_res_y -= 360;
\r
220 vector angleofs3(vector from,vector from_a, entity to)
\r
224 // makevectors(from.angles);
\r
225 v_res = normalize(to.origin - from);
\r
226 v_res = vectoangles(v_res);
\r
227 v_res = v_res - from_a;
\r
229 if (v_res_x < 0) v_res_x += 360;
\r
230 if (v_res_x > 180) v_res_x -= 360;
\r
232 if (v_res_y < 0) v_res_y += 360;
\r
233 if (v_res_y > 180) v_res_y -= 360;
\r
238 float turret_tag_setup(float linked)
\r
244 setorigin(self.tur_head,gettaginfo(self,gettagindex(self,"tag_head")));
\r
245 self.tur_shotorg = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire"));
\r
250 float turret_tag_fire_update()
\r
254 self.tur_shotorg = '0 0 0';
\r
258 self.tur_shotorg = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire"));
\r
259 //dprint("update: tur_shotorg: ",vtos(self.tur_shotorg)," origin:", vtos(self.tur_head.origin), " angels: ", vtos(self.tur_head.angles),"\n");
\r
264 void FireImoBeam (vector start,vector end,vector smin,vector smax,
\r
265 float bforce,float f_dmg,float f_velfactor, float deathtype)
\r
268 local vector hitloc, force, endpoint, dir;
\r
271 dir = normalize(end - start);
\r
272 force = dir * bforce;
\r
274 // go a little bit into the wall because we need to hit this wall later
\r
277 // trace multiple times until we hit a wall, each obstacle will be made unsolid.
\r
278 // note down which entities were hit so we can damage them later
\r
281 tracebox(start, smin, smax, end, FALSE, self);
\r
283 // if it is world we can't hurt it so stop now
\r
284 if (trace_ent == world || trace_fraction == 1)
\r
287 if (trace_ent.solid == SOLID_BSP)
\r
290 // make the entity non-solid so we can hit the next one
\r
291 trace_ent.railgunhit = TRUE;
\r
292 trace_ent.railgunhitloc = end;
\r
293 trace_ent.railgunhitsolidbackup = trace_ent.solid;
\r
295 // stop if this is a wall
\r
297 // make the entity non-solid
\r
298 trace_ent.solid = SOLID_NOT;
\r
301 endpoint = trace_endpos;
\r
303 // find all the entities the railgun hit and restore their solid state
\r
304 ent = findfloat(world, railgunhit, TRUE);
\r
307 // restore their solid type
\r
308 ent.solid = ent.railgunhitsolidbackup;
\r
309 ent = findfloat(ent, railgunhit, TRUE);
\r
312 // find all the entities the railgun hit and hurt them
\r
313 ent = findfloat(world, railgunhit, TRUE);
\r
316 // get the details we need to call the damage function
\r
317 hitloc = ent.railgunhitloc;
\r
318 ent.railgunhitloc = '0 0 0';
\r
319 ent.railgunhitsolidbackup = SOLID_NOT;
\r
320 ent.railgunhit = FALSE;
\r
322 // apply the damage
\r
323 if (ent.takedamage)
\r
325 Damage (ent, self, self, f_dmg, deathtype, hitloc, force);
\r
326 ent.velocity = ent.velocity * f_velfactor;
\r
327 //ent.alpha = 0.25 + random() * 0.75;
\r
330 // advance to the next entity
\r
331 ent = findfloat(ent, railgunhit, TRUE);
\r
333 trace_endpos = endpoint;
\r
336 void turrets_precash()
\r
338 precache_model ("models/turrets/c512.md3");
\r
340 precache_sound ("turrets/phaser.ogg");
\r
342 precache_model ("models/turrets/base-gib1.md3");
\r
343 precache_model ("models/turrets/base-gib2.md3");
\r
344 precache_model ("models/turrets/base-gib3.md3");
\r
345 precache_model ("models/turrets/base-gib4.md3");
\r
347 precache_model ("models/turrets/head-gib1.md3");
\r
348 precache_model ("models/turrets/head-gib2.md3");
\r
349 precache_model ("models/turrets/head-gib3.md3");
\r
350 precache_model ("models/turrets/head-gib4.md3");
\r
352 precache_model ("models/turrets/base.md3");
\r
353 precache_model ("models/turrets/flac.md3");
\r
354 precache_model ("models/turrets/pd_proj.md3");
\r
355 precache_model ("models/turrets/reactor.md3");
\r
356 precache_model ("models/turrets/mlrs_rocket.md3");
\r
357 precache_model ("models/turrets/hellion.md3");
\r
358 precache_model ("models/turrets/hunter2.md3");
\r
359 precache_model ("models/turrets/hk.md3");
\r
360 precache_model ("models/turrets/machinegun.md3");
\r
361 precache_model ("models/turrets/rocket.md3");
\r
362 precache_model ("models/turrets/mlrs.md3");
\r
363 precache_model ("models/turrets/phaser.md3");
\r
364 precache_model ("models/turrets/phaser_beam.md3");
\r
365 precache_model ("models/turrets/plasmad.md3");
\r
366 precache_model ("models/turrets/plasma.md3");
\r
367 precache_model ("models/turrets/tesla_head.md3");
\r
368 precache_model ("models/turrets/tesla_base.md3");
\r