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