]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/tturrets/system/system_misc.qc
a5e2e42e7e4df680b44c039823cffaaf82f65a15
[divverent/nexuiz.git] / data / qcsrc / server / tturrets / system / system_misc.qc
1 //--// Some supptort routines //--//\r
2 \r
3 #define anglemods(a) (a - floor(a / 360) * 360)\r
4 \r
5 float shortangle_f(float ang1,float ang2)\r
6 {\r
7     if(ang1 > ang2)\r
8     {\r
9         if(ang1 > 180)\r
10             return ang1 - 360;\r
11     }\r
12     else\r
13     {\r
14         if(ang1 < -180)\r
15             return ang1 + 360;\r
16     }\r
17 \r
18     return ang1;\r
19 }\r
20 \r
21 vector shortangle_v(vector ang1,vector ang2)\r
22 {\r
23     vector vtmp;\r
24 \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
28 \r
29     return vtmp;\r
30 }\r
31 \r
32 // Get real origin\r
33 vector real_origin(entity ent)\r
34 {\r
35     entity e;\r
36     vector v;\r
37 \r
38     e = ent.tag_entity;\r
39     while(e)\r
40     {\r
41         // v = v + e.origin;\r
42         v = v + ((e.absmin + e.absmax) * 0.5);\r
43         e = e.tag_entity;\r
44     }\r
45     //v = v + ent.origin;\r
46     v = v + ((ent.absmin + ent.absmax) * 0.5);\r
47     return v;\r
48 }\r
49 \r
50 // Plug this into wherever precache is done.\r
51 void g_turrets_common_precash()\r
52 {\r
53     precache_model ("models/turrets/c512.md3");\r
54     precache_model ("models/marker.md3");\r
55 }\r
56 \r
57 void SUB_Remove();\r
58 void marker_think()\r
59 {\r
60     if(self.cnt)\r
61     if(self.cnt < time)\r
62     {\r
63         self.think = SUB_Remove;\r
64         self.nextthink = time;\r
65         return;\r
66     }\r
67 \r
68     self.frame += 1;\r
69     if(self.frame > 29)\r
70         self.frame = 0;\r
71 \r
72     self.nextthink = time;\r
73 }\r
74 \r
75 void mark_error(vector where,float lifetime)\r
76 {\r
77     entity err;\r
78 \r
79     err = spawn();\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
86     err.skin = 0;\r
87     if(lifetime)\r
88         err.cnt = lifetime + time;\r
89 }\r
90 \r
91 void mark_info(vector where,float lifetime)\r
92 {\r
93     entity err;\r
94 \r
95     err = spawn();\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
102     err.skin = 1;\r
103     if(lifetime)\r
104         err.cnt = lifetime + time;\r
105 }\r
106 \r
107 entity mark_misc(vector where,float lifetime)\r
108 {\r
109     entity err;\r
110 \r
111     err = spawn();\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
118     err.skin = 3;\r
119     if(lifetime)\r
120         err.cnt = lifetime + time;\r
121     return err;\r
122 }\r
123 \r
124 /*\r
125 * Paint a v_color colord circle on target onwho\r
126 * that fades away over f_time\r
127 */\r
128 void paint_target(entity onwho, float f_size, vector v_color, float f_time)\r
129 {\r
130     entity e;\r
131 \r
132     e = spawn();\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
138     e.alpha = 0.15;\r
139     e.movetype = MOVETYPE_FLY;\r
140 \r
141     e.velocity = (v_color * 32); // + '0 0 1' * 64;\r
142 \r
143     e.colormod = v_color;\r
144     SUB_SetFade(e,time,f_time);\r
145 }\r
146 \r
147 void paint_target2(entity onwho, float f_size, vector v_color, float f_time)\r
148 {\r
149     entity e;\r
150 \r
151     e = spawn();\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
155 \r
156     setorigin(e,onwho.origin + '0 0 1');\r
157     e.alpha = 0.15;\r
158     e.movetype = MOVETYPE_FLY;\r
159 \r
160     e.velocity = (v_color * 32); // + '0 0 1' * 64;\r
161     e.avelocity_x = -128;\r
162 \r
163     e.colormod = v_color;\r
164     SUB_SetFade(e,time,f_time);\r
165 }\r
166 \r
167 void paint_target3(vector where, float f_size, vector v_color, float f_time)\r
168 {\r
169     entity e;\r
170     e = spawn();\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
179 }\r
180 \r
181 /*\r
182 * Return the angle between two enteties\r
183 */\r
184 vector angleofs(entity from, entity to)\r
185 {\r
186     vector v_res;\r
187 \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
192 \r
193     if (v_res_x < 0) v_res_x += 360;\r
194     if (v_res_x > 180) v_res_x -= 360;\r
195 \r
196     if (v_res_y < 0) v_res_y += 360;\r
197     if (v_res_y > 180) v_res_y -= 360;\r
198 \r
199     return v_res;\r
200 }\r
201 \r
202 vector angleofs2(entity from, vector to)\r
203 {\r
204     vector v_res;\r
205 \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
210 \r
211     if (v_res_x < 0) v_res_x += 360;\r
212     if (v_res_x > 180) v_res_x -= 360;\r
213 \r
214     if (v_res_y < 0) v_res_y += 360;\r
215     if (v_res_y > 180) v_res_y -= 360;\r
216 \r
217     return v_res;\r
218 }\r
219 \r
220 vector angleofs3(vector from,vector from_a, entity to)\r
221 {\r
222     vector v_res;\r
223 \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
228 \r
229     if (v_res_x < 0) v_res_x += 360;\r
230     if (v_res_x > 180) v_res_x -= 360;\r
231 \r
232     if (v_res_y < 0) v_res_y += 360;\r
233     if (v_res_y > 180) v_res_y -= 360;\r
234 \r
235     return v_res;\r
236 }\r
237 \r
238 float turret_tag_setup(float linked)\r
239 {\r
240     // Laters dooz\r
241     if (linked)\r
242         return 0;\r
243 \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
246 \r
247     return 1;\r
248 }\r
249 \r
250 float turret_tag_fire_update()\r
251 {\r
252     if(!self.tur_head)\r
253     {\r
254         self.tur_shotorg = '0 0 0';\r
255         return 1;\r
256     }\r
257 \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
260 \r
261     return 1;\r
262 }\r
263 \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
266 \r
267 {\r
268     local vector hitloc, force, endpoint, dir;\r
269     local entity ent;\r
270 \r
271     dir = normalize(end - start);\r
272     force = dir * bforce;\r
273 \r
274     // go a little bit into the wall because we need to hit this wall later\r
275     end = end + dir;\r
276 \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
279     while (1)\r
280     {\r
281         tracebox(start, smin, smax, end, FALSE, self);\r
282 \r
283         // if it is world we can't hurt it so stop now\r
284         if (trace_ent == world || trace_fraction == 1)\r
285             break;\r
286 \r
287         if (trace_ent.solid == SOLID_BSP)\r
288             break;\r
289 \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
294 \r
295         // stop if this is a wall\r
296 \r
297         // make the entity non-solid\r
298         trace_ent.solid = SOLID_NOT;\r
299     }\r
300 \r
301     endpoint = trace_endpos;\r
302 \r
303     // find all the entities the railgun hit and restore their solid state\r
304     ent = findfloat(world, railgunhit, TRUE);\r
305     while (ent)\r
306     {\r
307         // restore their solid type\r
308         ent.solid = ent.railgunhitsolidbackup;\r
309         ent = findfloat(ent, railgunhit, TRUE);\r
310     }\r
311 \r
312     // find all the entities the railgun hit and hurt them\r
313     ent = findfloat(world, railgunhit, TRUE);\r
314     while (ent)\r
315     {\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
321 \r
322         // apply the damage\r
323         if (ent.takedamage)\r
324         {\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
328         }\r
329 \r
330         // advance to the next entity\r
331         ent = findfloat(ent, railgunhit, TRUE);\r
332     }\r
333     trace_endpos = endpoint;\r
334 }\r
335 \r
336 void turrets_precash()\r
337 {\r
338     precache_model ("models/turrets/c512.md3");\r
339 \r
340     precache_sound ("turrets/phaser.ogg");\r
341 \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
346 \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
351 \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
369 }\r