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