]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/tturrets/system/system_misc.qc
preliminary declaration of jointtype, and make misc_follow behave as a joint if joint...
[divverent/nexuiz.git] / data / qcsrc / server / tturrets / system / system_misc.qc
1 //--// Some support routines //--//
2
3 #define anglemodss(a) (a - floor(a / 360) * 360)
4 float(float v) anglemods =
5 {
6         v = v - 360 * floor(v / 360);
7         return v;
8 };
9 float safeangle(float a)
10 {
11     if((a > -361) && (a < 361))
12         return a;
13
14     a -= (360 * floor(a / 360));
15
16     return a;
17 }
18
19 float shortangle_f(float ang1,float ang2)
20 {
21     if(ang1 > ang2)
22     {
23         if(ang1 > 180)
24             return ang1 - 360;
25     }
26     else
27     {
28         if(ang1 < -180)
29             return ang1 + 360;
30     }
31
32     return ang1;
33 }
34
35 vector shortangle_v(vector ang1,vector ang2)
36 {
37     vector vtmp;
38
39     vtmp_x = shortangle_f(ang1_x,ang2_x);
40     vtmp_y = shortangle_f(ang1_y,ang2_y);
41     vtmp_z = shortangle_f(ang1_z,ang2_z);
42
43     return vtmp;
44 }
45
46 vector shortangle_vxy(vector ang1,vector ang2)
47 {
48     vector vtmp;
49
50     vtmp_x = shortangle_f(ang1_x,ang2_x);
51     vtmp_y = shortangle_f(ang1_y,ang2_y);
52
53     return vtmp;
54 }
55
56 // Get real origin
57 vector real_origin(entity ent)
58 {
59     entity e;
60     vector v;
61
62     e = ent.tag_entity;
63     while(e)
64     {
65         // v = v + e.origin;
66         v = v + ((e.absmin + e.absmax) * 0.5);
67         e = e.tag_entity;
68     }
69     //v = v + ent.origin;
70     v = v + ((ent.absmin + ent.absmax) * 0.5);
71     return v;
72 }
73
74 // Plug this into wherever precache is done.
75 void g_turrets_common_precash()
76 {
77     precache_model ("models/turrets/c512.md3");
78     precache_model ("models/marker.md3");
79 }
80
81 void SUB_Remove();
82 void marker_think()
83 {
84     if(self.cnt)
85     if(self.cnt < time)
86     {
87         self.think = SUB_Remove;
88         self.nextthink = time;
89         return;
90     }
91
92     self.frame += 1;
93     if(self.frame > 29)
94         self.frame = 0;
95
96     self.nextthink = time;
97 }
98
99 void mark_error(vector where,float lifetime)
100 {
101     entity err;
102
103     err = spawn();
104     err.classname = "error_marker";
105     setmodel(err,"models/marker.md3");
106     setorigin(err,where);
107     err.movetype = MOVETYPE_NONE;
108     err.think = marker_think;
109     err.nextthink = time;
110     err.skin = 0;
111     if(lifetime)
112         err.cnt = lifetime + time;
113 }
114
115 void mark_info(vector where,float lifetime)
116 {
117     entity err;
118
119     err = spawn();
120     err.classname = "info_marker";
121     setmodel(err,"models/marker.md3");
122     setorigin(err,where);
123     err.movetype = MOVETYPE_NONE;
124     err.think = marker_think;
125     err.nextthink = time;
126     err.skin = 1;
127     if(lifetime)
128         err.cnt = lifetime + time;
129 }
130
131 entity mark_misc(vector where,float lifetime)
132 {
133     entity err;
134
135     err = spawn();
136     err.classname = "mark_misc";
137     setmodel(err,"models/marker.md3");
138     setorigin(err,where);
139     err.movetype = MOVETYPE_NONE;
140     err.think = marker_think;
141     err.nextthink = time;
142     err.skin = 3;
143     if(lifetime)
144         err.cnt = lifetime + time;
145     return err;
146 }
147
148 /*
149 * Paint a v_color colord circle on target onwho
150 * that fades away over f_time
151 */
152 void paint_target(entity onwho, float f_size, vector v_color, float f_time)
153 {
154     entity e;
155
156     e = spawn();
157     setmodel(e, "models/turrets/c512.md3"); // precision set above
158     e.scale = (f_size/512);
159     //setsize(e, '0 0 0', '0 0 0');
160     //setattachment(e,onwho,"");
161     setorigin(e,onwho.origin + '0 0 1');
162     e.alpha = 0.15;
163     e.movetype = MOVETYPE_FLY;
164
165     e.velocity = (v_color * 32); // + '0 0 1' * 64;
166
167     e.colormod = v_color;
168     SUB_SetFade(e,time,f_time);
169 }
170
171 void paint_target2(entity onwho, float f_size, vector v_color, float f_time)
172 {
173     entity e;
174
175     e = spawn();
176     setmodel(e, "models/turrets/c512.md3"); // precision set above
177     e.scale = (f_size/512);
178     setsize(e, '0 0 0', '0 0 0');
179
180     setorigin(e,onwho.origin + '0 0 1');
181     e.alpha = 0.15;
182     e.movetype = MOVETYPE_FLY;
183
184     e.velocity = (v_color * 32); // + '0 0 1' * 64;
185     e.avelocity_x = -128;
186
187     e.colormod = v_color;
188     SUB_SetFade(e,time,f_time);
189 }
190
191 void paint_target3(vector where, float f_size, vector v_color, float f_time)
192 {
193     entity e;
194     e = spawn();
195     setmodel(e, "models/turrets/c512.md3"); // precision set above
196     e.scale = (f_size/512);
197     setsize(e, '0 0 0', '0 0 0');
198     setorigin(e,where+ '0 0 1');
199     e.movetype = MOVETYPE_NONE;
200     e.velocity = '0 0 0';
201     e.colormod = v_color;
202     SUB_SetFade(e,time,f_time);
203 }
204
205 /*
206 * Return the angle between two enteties
207 */
208 vector angleofs(entity from, entity to)
209 {
210     vector v_res;
211
212     // makevectors(from.angles);
213     v_res = normalize(to.origin - from.origin);
214     v_res = vectoangles(v_res);
215     v_res = v_res - from.angles;
216
217     if (v_res_x < 0) v_res_x += 360;
218     if (v_res_x > 180) v_res_x -= 360;
219
220     if (v_res_y < 0) v_res_y += 360;
221     if (v_res_y > 180) v_res_y -= 360;
222
223     return v_res;
224 }
225
226 vector angleofs2(entity from, vector to)
227 {
228     vector v_res;
229
230     // makevectors(from.angles);
231     v_res = normalize(to - from.origin);
232     v_res = vectoangles(v_res);
233     v_res = v_res - from.angles;
234
235     if (v_res_x < 0) v_res_x += 360;
236     if (v_res_x > 180) v_res_x -= 360;
237
238     if (v_res_y < 0) v_res_y += 360;
239     if (v_res_y > 180) v_res_y -= 360;
240
241     return v_res;
242 }
243
244 vector angleofs3(vector from,vector from_a, entity to)
245 {
246     vector v_res;
247
248     // makevectors(from.angles);
249     v_res = normalize(to.origin - from);
250     v_res = vectoangles(v_res);
251     v_res = v_res - from_a;
252
253     if (v_res_x < 0) v_res_x += 360;
254     if (v_res_x > 180) v_res_x -= 360;
255
256     if (v_res_y < 0) v_res_y += 360;
257     if (v_res_y > 180) v_res_y -= 360;
258
259     return v_res;
260 }
261
262 float turret_tag_setup()
263 {
264     if(!self.tur_head)
265     {
266         dprint("Call to turret_tag_setup with self.tur_head missing!\n");
267         self.tur_shotorg = '0 0 0';
268         return 0;
269     }
270
271     setorigin(self.tur_head,gettaginfo(self,gettagindex(self,"tag_head")));
272     self.tur_shotorg = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire"));
273
274     v_forward = normalize(v_forward);
275
276     return 1;
277 }
278
279 float turret_tag_fire_update()
280 {
281     if(!self.tur_head)
282     {
283         dprint("Call to turret_tag_fire_update with self.tur_head missing!\n");
284         self.tur_shotorg = '0 0 0';
285         return 0;
286     }
287
288     self.tur_shotorg = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire"));
289     v_forward = normalize(v_forward);
290
291     //dprint("update: tur_shotorg: ",vtos(self.tur_shotorg)," origin:", vtos(self.tur_head.origin), " angels: ", vtos(self.tur_head.angles),"\n");
292
293     return 1;
294 }
295
296 void FireImoBeam (vector start,vector end,vector smin,vector smax,
297                   float bforce,float f_dmg,float f_velfactor, float deathtype)
298
299 {
300     local vector hitloc, force, endpoint, dir;
301     local entity ent;
302
303     dir = normalize(end - start);
304     force = dir * bforce;
305
306     // go a little bit into the wall because we need to hit this wall later
307     end = end + dir;
308
309     // trace multiple times until we hit a wall, each obstacle will be made unsolid.
310     // note down which entities were hit so we can damage them later
311     while (1)
312     {
313         tracebox(start, smin, smax, end, FALSE, self);
314
315         // if it is world we can't hurt it so stop now
316         if (trace_ent == world || trace_fraction == 1)
317             break;
318
319         if (trace_ent.solid == SOLID_BSP)
320             break;
321
322         // make the entity non-solid so we can hit the next one
323         trace_ent.railgunhit = TRUE;
324         trace_ent.railgunhitloc = end;
325         trace_ent.railgunhitsolidbackup = trace_ent.solid;
326
327         // stop if this is a wall
328
329         // make the entity non-solid
330         trace_ent.solid = SOLID_NOT;
331     }
332
333     endpoint = trace_endpos;
334
335     // find all the entities the railgun hit and restore their solid state
336     ent = findfloat(world, railgunhit, TRUE);
337     while (ent)
338     {
339         // restore their solid type
340         ent.solid = ent.railgunhitsolidbackup;
341         ent = findfloat(ent, railgunhit, TRUE);
342     }
343
344     // find all the entities the railgun hit and hurt them
345     ent = findfloat(world, railgunhit, TRUE);
346     while (ent)
347     {
348         // get the details we need to call the damage function
349         hitloc = ent.railgunhitloc;
350         ent.railgunhitloc = '0 0 0';
351         ent.railgunhitsolidbackup = SOLID_NOT;
352         ent.railgunhit = FALSE;
353
354         // apply the damage
355         if (ent.takedamage)
356         {
357             Damage (ent, self, self, f_dmg, deathtype, hitloc, force);
358             ent.velocity = ent.velocity * f_velfactor;
359             //ent.alpha = 0.25 + random() * 0.75;
360         }
361
362         // advance to the next entity
363         ent = findfloat(ent, railgunhit, TRUE);
364     }
365     trace_endpos = endpoint;
366 }
367
368 void turrets_precache_debug_models()
369 {
370     precache_model ("models/turrets/c512.md3");
371     precache_model ("models/pathlib/goodsquare.md3");
372     precache_model ("models/pathlib/badsquare.md3");
373     precache_model ("models/pathlib/square.md3");
374     precache_model ("models/pathlib/edge.md3");
375 }
376
377 void turrets_precash()
378 {
379     precache_model ("models/turrets/base-gib1.md3");
380     precache_model ("models/turrets/base-gib2.md3");
381     precache_model ("models/turrets/base-gib3.md3");
382     precache_model ("models/turrets/base-gib4.md3");
383
384     precache_model ("models/turrets/head-gib1.md3");
385     precache_model ("models/turrets/head-gib2.md3");
386     precache_model ("models/turrets/head-gib3.md3");
387     precache_model ("models/turrets/head-gib4.md3");
388     precache_model ("models/turrets/terrainbase.md3");
389
390     //precache_model ("models/turrets/base.md3");
391     //precache_model ("models/turrets/flac.md3");
392     //precache_model ("models/turrets/pd_proj.md3");
393     //precache_model ("models/turrets/reactor.md3");
394     //precache_model ("models/turrets/mlrs_rocket.md3");
395     //precache_model ("models/turrets/hellion.md3");
396     //precache_model ("models/turrets/hunter2.md3");
397     //precache_model ("models/turrets/hk.md3");
398     //precache_model ("models/turrets/machinegun.md3");
399     //precache_model ("models/turrets/rocket.md3");
400     //precache_model ("models/turrets/mlrs.md3");
401     //precache_model ("models/turrets/phaser.md3");
402     //precache_model ("models/turrets/phaser_beam.md3");
403     //precache_model ("models/turrets/plasmad.md3");
404     //precache_model ("models/turrets/plasma.md3");
405     //precache_model ("models/turrets/tesla_head.md3");
406     //precache_model ("models/turrets/tesla_base.md3");
407         //turrets_precache_debug_models();
408 }