]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/tturrets/system/system_main.qc
r5811 | div0 | 2009-02-09 15:23:31 +0100 (Mon, 09 Feb 2009) | 2 lines
[divverent/nexuiz.git] / data / qcsrc / server / tturrets / system / system_main.qc
1 #define cvar_base "g_turrets_unit_"\r
2 \r
3 //.float tur_lastscore;\r
4 .string cvar_basename;\r
5 \r
6 string cvar_gets(string s_base,string s_add)\r
7 {\r
8     return strcat(s_base,s_add);\r
9 }\r
10 \r
11 .float turret_scale_damage;\r
12 .float turret_scale_range;\r
13 .float turret_scale_refire;\r
14 .float turret_scale_ammo;\r
15 .float turret_scale_aim;\r
16 .float turret_scale_health;\r
17 .float turret_scale_respawn;\r
18 \r
19 void load_unit_settings(entity ent,string unitname,float is_reload)\r
20 {\r
21 \r
22     string sbase;\r
23 \r
24     if (ent == world)\r
25         return;\r
26 \r
27     if (!ent.turret_scale_damage)    ent.turret_scale_damage  = 1;\r
28     if (!ent.turret_scale_range)     ent.turret_scale_range   = 1;\r
29     if (!ent.turret_scale_refire)    ent.turret_scale_refire  = 1;\r
30     if (!ent.turret_scale_ammo)      ent.turret_scale_ammo    = 1;\r
31     if (!ent.turret_scale_aim)       ent.turret_scale_aim     = 1;\r
32     if (!ent.turret_scale_health)    ent.turret_scale_health  = 1;\r
33     if (!ent.turret_scale_respawn)   ent.turret_scale_respawn = 1;\r
34 \r
35     sbase = strcat(cvar_base,unitname);\r
36     if (is_reload)\r
37     {\r
38         ent.enemy = world;\r
39         ent.tur_head.avelocity = '0 0 0';\r
40         ent.tur_head.angles = ent.angles;\r
41     }\r
42     ent.health = cvar(cvar_gets(sbase,"_health")) * ent.turret_scale_health;\r
43     ent.respawntime = cvar(cvar_gets(sbase,"_respawntime")) * ent.turret_scale_respawn;\r
44 \r
45     ent.shot_dmg = cvar(cvar_gets(sbase,"_shot_dmg")) * ent.turret_scale_damage;\r
46     ent.shot_refire = cvar(cvar_gets(sbase,"_shot_refire")) * ent.turret_scale_refire;\r
47     ent.shot_radius = cvar(cvar_gets(sbase,"_shot_radius")) * ent.turret_scale_damage;\r
48     ent.shot_speed = cvar(cvar_gets(sbase,"_shot_speed"));\r
49     ent.shot_spread = cvar(cvar_gets(sbase,"_shot_spread"));\r
50     ent.shot_force = cvar(cvar_gets(sbase,"_shot_force")) * ent.turret_scale_damage;\r
51     ent.shot_volly = cvar(cvar_gets(sbase,"_shot_volly"));\r
52     ent.shot_volly_refire = cvar(cvar_gets(sbase,"_shot_volly_refire")) * ent.turret_scale_refire;\r
53 \r
54     ent.target_range = cvar(cvar_gets(sbase,"_target_range")) * ent.turret_scale_range;\r
55     ent.target_range_min = cvar(cvar_gets(sbase,"_target_range_min")) * ent.turret_scale_range;\r
56     ent.target_range_fire = cvar(cvar_gets(sbase,"_target_range_fire")) * ent.turret_scale_range;\r
57     ent.target_range_optimal = cvar(cvar_gets(sbase,"_target_range_optimal")) * ent.turret_scale_range;\r
58 \r
59     ent.target_select_rangebias = cvar(cvar_gets(sbase,"_target_select_rangebias"));\r
60     ent.target_select_samebias = cvar(cvar_gets(sbase,"_target_select_samebias"));\r
61     ent.target_select_anglebias = cvar(cvar_gets(sbase,"_target_select_anglebias"));\r
62     ent.target_select_playerbias = cvar(cvar_gets(sbase,"_target_select_playerbias"));\r
63 \r
64     ent.ammo_max = cvar(cvar_gets(sbase,"_ammo_max")) * ent.turret_scale_ammo;\r
65     //ent.ammo = cvar(cvar_gets(sbase,"_ammo"));\r
66     ent.ammo_recharge = cvar(cvar_gets(sbase,"_ammo_recharge")) * ent.turret_scale_ammo;\r
67 \r
68     ent.aim_firetolerance_dist = cvar(cvar_gets(sbase,"_aim_firetolerance_dist"));\r
69 //    ent.aim_firetolerance_angle = cvar(cvar_gets(sbase,"_aim_firetolerance_angle"));\r
70     ent.aim_speed = cvar(cvar_gets(sbase,"_aim_speed")) * ent.turret_scale_aim;\r
71     ent.aim_maxrot = cvar(cvar_gets(sbase,"_aim_maxrot"));\r
72     ent.aim_maxpitch = cvar(cvar_gets(sbase,"_aim_maxpitch"));\r
73 \r
74     ent.track_type = cvar(cvar_gets(sbase,"_track_type"));\r
75     ent.track_accel_pitch = cvar(cvar_gets(sbase,"_track_accel_pitch"));\r
76     ent.track_accel_rot = cvar(cvar_gets(sbase,"_track_accel_rot"));\r
77     ent.track_blendrate = cvar(cvar_gets(sbase,"_track_blendrate"));\r
78 }\r
79 \r
80 float turret_stdproc_true()\r
81 {\r
82     return 1;\r
83 }\r
84 \r
85 float turret_stdproc_false()\r
86 {\r
87     return 0;\r
88 }\r
89 \r
90 void turret_stdproc_nothing()\r
91 {\r
92     return;\r
93 }\r
94 \r
95 /**\r
96 ** updates enemy distances, preicted impact point/time\r
97 ** & aim<->predict impact distance.\r
98 ** Also translates shoot & aimorgs by current rotation.\r
99 **/\r
100 void turret_do_updates(entity e_turret)\r
101 {\r
102     vector enemy_pos;\r
103 \r
104     if (self.turrcaps_flags & TFL_TURRCAPS_LINKED)\r
105     {\r
106         e_turret.tur_head.angles_x = e_turret.tur_head.angles_x * -1;\r
107         e_turret.angles_x = e_turret.angles_x * -1;\r
108         makevectors(e_turret.tur_head.angles + e_turret.angles);\r
109         e_turret.tur_head.angles_x = e_turret.tur_head.angles_x * -1;\r
110         e_turret.angles_x = e_turret.angles_x * -1;\r
111     }\r
112     else\r
113     {\r
114         e_turret.tur_head.angles_x = e_turret.tur_head.angles_x * -1;\r
115         makevectors(e_turret.tur_head.angles);\r
116         e_turret.tur_head.angles_x = e_turret.tur_head.angles_x * -1;\r
117     }\r
118     enemy_pos = real_origin(e_turret.enemy);\r
119 \r
120     e_turret.tur_shotorg_updated = e_turret.origin + v_forward * e_turret.tur_shotorg_x + v_right * e_turret.tur_shotorg_y + v_up * e_turret.tur_shotorg_z;\r
121     e_turret.tur_aimorg_updated = e_turret.origin + v_forward * e_turret.tur_aimorg_x + v_right * e_turret.tur_aimorg_y + v_up * e_turret.tur_aimorg_z;\r
122     e_turret.tur_shotdir_updated = v_forward; // normalize((e_turret.tur_shotorg_updated + v_forward) - e_turret.tur_shotorg_updated);\r
123 \r
124     e_turret.tur_dist_enemy = vlen(e_turret.tur_aimorg_updated - enemy_pos);\r
125     e_turret.tur_dist_aimpos = vlen(e_turret.tur_aimorg_updated - e_turret.tur_aimpos);\r
126 \r
127     //traceline(e_turret.tur_aimorg_updated,e_turret.tur_aimorg_updated + (e_turret.tur_shotdir_updated * e_turret.tur_dist_aimpos),MOVE_NORMAL,e_turret);\r
128     tracebox(e_turret.tur_aimorg_updated, '-1 -1 -1','1 1 1',e_turret.tur_aimorg_updated + (e_turret.tur_shotdir_updated * e_turret.tur_dist_aimpos),MOVE_NORMAL,e_turret);\r
129 \r
130     //traceline(e_turret.tur_aimorg_updated,e_turret.tur_aimpos,MOVE_NORMAL,e_turret);\r
131 \r
132     e_turret.tur_impactpoint = trace_endpos;\r
133     e_turret.tur_impactent = trace_ent;\r
134     e_turret.tur_dist_impact_to_aimpos = vlen(trace_endpos - e_turret.tur_aimpos);\r
135     e_turret.tur_impacttime = vlen(e_turret.tur_aimorg_updated - trace_endpos) / e_turret.shot_speed;\r
136 \r
137 \r
138 /*\r
139 .float      tur_dist_enemy;\r
140 .float      tur_dist_aimpos;\r
141 .float      tur_dist_impact_to_aimpos;\r
142 */\r
143 \r
144 }\r
145 \r
146 /**\r
147 ** Handles head rotation according to\r
148 ** the units .track_type and .track_flags\r
149 **/\r
150 void turret_stdproc_track()\r
151 {\r
152     vector wish_angle;  // This is where we want to aim\r
153 \r
154     vector real_angle;  // This is where we can aim\r
155     float f_tmp;\r
156 \r
157 \r
158     if (self.track_flags == TFL_TRACK_NO)\r
159         return;\r
160 \r
161     if(!self.tur_active)\r
162     {\r
163         wish_angle = self.idle_aim - ('1 0 0' * self.aim_maxpitch);\r
164     }\r
165     else if (self.enemy == world)\r
166     {\r
167         if (self.turrcaps_flags & TFL_TURRCAPS_LINKED)\r
168             wish_angle = self.idle_aim + self.angles;\r
169         else\r
170             if(time > self.lip)\r
171                 wish_angle = self.idle_aim;\r
172             else\r
173                 wish_angle = self.tur_head.angles;\r
174 \r
175     }\r
176     else\r
177     {\r
178         // Find the direction\r
179         if (self.turrcaps_flags & TFL_TURRCAPS_LINKED)\r
180             wish_angle = normalize(self.tur_aimpos - self.origin);\r
181         else\r
182             wish_angle = normalize(self.tur_aimpos - self.tur_head.origin);\r
183 \r
184         wish_angle = vectoangles(wish_angle); // And make a angle\r
185     }\r
186 \r
187     // Find the diffrence between where we currently aim and where we want to aim\r
188     if (self.turrcaps_flags & TFL_TURRCAPS_LINKED)\r
189         real_angle = wish_angle - (self.angles + self.tur_head.angles);\r
190     else\r
191     {\r
192         real_angle = wish_angle - self.tur_head.angles;\r
193 \r
194     }\r
195 \r
196     if(real_angle_x > self.tur_head.angles_x)\r
197     {\r
198         if(real_angle_x >= 180)\r
199             real_angle_x -= 360;\r
200     }\r
201     else\r
202     {\r
203         if(real_angle_x <= -180)\r
204             real_angle_x += 360;\r
205     }\r
206     if(real_angle_y > self.tur_head.angles_y)\r
207     {\r
208         if(real_angle_y >= 180)\r
209             real_angle_y -= 360;\r
210     }\r
211     else\r
212     {\r
213         if(real_angle_y <= -180)\r
214             real_angle_y += 360;\r
215     }\r
216 \r
217     // Limit pitch\r
218 \r
219     if (self.track_flags & TFL_TRACK_PITCH)\r
220         real_angle_x = bound(self.aim_maxpitch * -1,real_angle_x,self.aim_maxpitch);\r
221 \r
222     // Limit rot\r
223     if (self.track_flags & TFL_TRACK_ROT)\r
224         real_angle_y = bound(self.aim_maxrot * -1,real_angle_y,self.aim_maxrot);\r
225 \r
226 \r
227     if (self.track_type == TFL_TRACKTYPE_STEPMOTOR)\r
228     {\r
229         f_tmp = self.aim_speed * self.ticrate; // dgr/sec -> dgr/tic\r
230 \r
231         // Limit turning speed\r
232         real_angle_x = bound((-1 * f_tmp),real_angle_x, f_tmp);\r
233         real_angle_y = bound((-1 * f_tmp),real_angle_y, f_tmp);\r
234 \r
235         // Limit pich and rot.\r
236         if (self.track_flags & TFL_TRACK_PITCH)\r
237             self.tur_head.angles_x = bound((-1 * self.aim_maxpitch),self.tur_head.angles_x + real_angle_x,self.aim_maxpitch);\r
238 \r
239         if (self.track_flags & TFL_TRACK_ROT)\r
240             self.tur_head.angles_y = bound((-1 * self.aim_maxrot),self.tur_head.angles_y  + real_angle_y,self.aim_maxrot);\r
241 \r
242         return;\r
243     }\r
244 \r
245     if (self.track_type == TFL_TRACKTYPE_FLUIDPRECISE)\r
246     {\r
247         if (self.track_flags & TFL_TRACK_PITCH)\r
248             self.tur_head.avelocity_x = real_angle_x;\r
249 \r
250         if (self.track_flags & TFL_TRACK_ROT)\r
251             self.tur_head.avelocity_y = real_angle_y;\r
252     }\r
253     else if (self.track_type == TFL_TRACKTYPE_FLUIDINERTIA)\r
254     {\r
255         f_tmp = self.aim_speed * self.ticrate;\r
256 \r
257         real_angle_y = bound(self.aim_speed * -1,real_angle_y * self.track_accel_rot * f_tmp,self.aim_speed);\r
258         real_angle_x = bound(self.aim_speed * -1,real_angle_x * self.track_accel_pitch * f_tmp,self.aim_speed);\r
259         real_angle = (self.tur_head.avelocity * self.track_blendrate) + (real_angle * (1 - self.track_blendrate));\r
260 \r
261         if (self.track_flags & TFL_TRACK_PITCH) self.tur_head.avelocity_x = real_angle_x;\r
262         if (self.track_flags & TFL_TRACK_ROT)   self.tur_head.avelocity_y = real_angle_y;\r
263         self.tur_head.avelocity_z = real_angle_z;\r
264         setsize(self,self.mins,self.maxs);\r
265     }\r
266 \r
267     // Limit pitch\r
268     /*\r
269     if (self.track_flags & TFL_TRACK_PITCH)\r
270     {\r
271         if (self.tur_head.angles_x > self.aim_maxpitch)\r
272         {\r
273             self.tur_head.angles_x = self.aim_maxpitch;\r
274             self.tur_head.avelocity_x = 0;\r
275         }\r
276         else if (self.tur_head.angles_x < (self.aim_maxpitch * -1))\r
277         {\r
278             self.tur_head.angles_x = (self.aim_maxpitch * -1);\r
279             self.tur_head.avelocity_x = 0;\r
280         }\r
281     }\r
282 \r
283     // Limit rot\r
284     if (self.track_flags & TFL_TRACK_ROT)\r
285     {\r
286         if (self.tur_head.angles_y > self.aim_maxrot)\r
287         {\r
288             self.tur_head.angles_y = self.aim_maxrot;\r
289             self.tur_head.avelocity_y = 0;\r
290         }\r
291         else if (self.tur_head.angles_y < (self.aim_maxrot * -1))\r
292         {\r
293             self.tur_head.angles_y = (self.aim_maxrot * -1);\r
294             self.tur_head.avelocity_y = 0;\r
295         }\r
296     }\r
297     */\r
298 \r
299 \r
300 }\r
301 \r
302 /*\r
303  + = implemented\r
304  - = not implemented\r
305 \r
306  + TFL_FIRECHECK_NO\r
307  + TFL_FIRECHECK_WORLD\r
308  + TFL_FIRECHECK_DEAD\r
309  + TFL_FIRECHECK_DISTANCES\r
310  - TFL_FIRECHECK_LOS\r
311  + TFL_FIRECHECK_AIMDIST\r
312  + TFL_FIRECHECK_REALDIST\r
313  - TFL_FIRECHECK_ANGLEDIST\r
314  - TFL_FIRECHECK_TEAMCECK\r
315  + TFL_FIRECHECK_AFF\r
316  + TFL_FIRECHECK_OWM_AMMO\r
317  + TFL_FIRECHECK_OTHER_AMMO\r
318  + TFL_FIRECHECK_REFIRE\r
319 */\r
320 \r
321 /**\r
322 ** Preforms pre-fire checks based on the uints firecheck_flags\r
323 **/\r
324 float turret_stdproc_firecheck()\r
325 {\r
326     // This one just dont care =)\r
327     if (self.firecheck_flags & TFL_FIRECHECK_NO) return 1;\r
328 \r
329     // Ready?\r
330     if (self.firecheck_flags & TFL_FIRECHECK_REFIRE)\r
331         if (self.attack_finished_single >= time) return 0;\r
332 \r
333     // Special case..\r
334     if((self.shoot_flags & TFL_SHOOT_VOLLYALWAYS) && (self.volly_counter != self.shot_volly))\r
335     {\r
336         return 1;\r
337     }\r
338 \r
339 \r
340     //\r
341     if (self.firecheck_flags & TFL_FIRECHECK_DEAD)\r
342         if (self.enemy.deadflag != DEAD_NO) return 0;\r
343 \r
344     // Plz stop killing the world!\r
345     if (self.firecheck_flags & TFL_FIRECHECK_WORLD)\r
346         if (self.enemy == world) return 0;\r
347 \r
348     // Own ammo?\r
349     if (self.firecheck_flags & TFL_FIRECHECK_OWM_AMMO)\r
350         if (self.ammo < self.shot_dmg) return 0;\r
351 \r
352     // Other's ammo? (support-supply units)\r
353     if (self.firecheck_flags & TFL_FIRECHECK_OTHER_AMMO)\r
354         if (self.enemy.ammo >= self.enemy.ammo_max) return 0;\r
355 \r
356     if (self.firecheck_flags & TFL_FIRECHECK_DISTANCES)\r
357     {\r
358         // Not close enougth?\r
359         if (self.tur_dist_aimpos > self.target_range_fire) return 0;\r
360 \r
361         // To close?\r
362         if (self.tur_dist_aimpos < self.target_range_min) return 0;\r
363     }\r
364 \r
365     // Try to avoid FF?\r
366     if (self.firecheck_flags & TFL_FIRECHECK_AFF)\r
367         if (self.tur_impactent.team == self.team) return 0;\r
368 \r
369     // aim<->predicted impact\r
370     if (self.firecheck_flags & TFL_FIRECHECK_AIMDIST)\r
371         if (self.tur_dist_impact_to_aimpos  > self.aim_firetolerance_dist) return 0;\r
372 \r
373     // Volly status\r
374     if (self.shot_volly > 1)\r
375     {\r
376         if (self.volly_counter == self.shot_volly)\r
377             if (self.ammo < (self.shot_dmg * self.shot_volly))\r
378                 return 0;\r
379     }\r
380 \r
381     //if(self.tur_enemy_adist >= self.aim_firetolerance) return 0;\r
382 \r
383 \r
384     return 1;\r
385 }\r
386 \r
387 /*\r
388  + TFL_TARGETSELECT_NO\r
389  + TFL_TARGETSELECT_LOS\r
390  + TFL_TARGETSELECT_PLAYERS\r
391  + TFL_TARGETSELECT_MISSILES\r
392  - TFL_TARGETSELECT_TRIGGERTARGET\r
393  + TFL_TARGETSELECT_ANGLELIMITS\r
394  + TFL_TARGETSELECT_RANGELIMTS\r
395  + TFL_TARGETSELECT_TEAMCHECK\r
396  - TFL_TARGETSELECT_NOBUILTIN\r
397  + TFL_TARGETSELECT_OWNTEAM\r
398 */\r
399 \r
400 /**\r
401 ** Evaluate a entity for target valitity based on validate_flags\r
402 **/\r
403 float turret_validate_target(entity e_turret,entity e_target,float validate_flags)\r
404 {\r
405     vector v_tmp;\r
406 \r
407     //if(!validate_flags & TFL_TARGETSELECT_NOBUILTIN)\r
408     //    return -0.5;\r
409 \r
410     if (!e_target)// == world)\r
411         return -1;\r
412 \r
413     if (e_target.classname == "grapplinghook")\r
414         return - 1.5;\r
415 \r
416         if(g_onslaught)\r
417                 if (substring(e_target.classname, 0, 10) == "onslaught_") // don't attack onslaught targets, that's the player's job!\r
418                         return - 1.75;\r
419 \r
420     if (validate_flags & TFL_TARGETSELECT_NO)\r
421         return -2;\r
422 \r
423     // If only this was used more..\r
424     if (e_target.flags & FL_NOTARGET)\r
425         return -3;\r
426 \r
427     // Cant touch this\r
428     if ((e_target.takedamage == DAMAGE_NO) || (e_target.health < 0))\r
429         return -4;\r
430 \r
431     // player\r
432     if (e_target.flags & FL_CLIENT)\r
433     {\r
434         if (!(validate_flags & TFL_TARGETSELECT_PLAYERS))\r
435             return -5;\r
436 \r
437         if (e_target.deadflag != DEAD_NO)\r
438             return -6;\r
439     }\r
440 \r
441         // enemy turrets\r
442         if (e_target.turret_firefunc || e_target.owner.tur_head == e_target)\r
443         {\r
444                 if (validate_flags & TFL_TARGETSELECT_NOTURRETS)\r
445                         return -5.5;\r
446         }\r
447 \r
448 \r
449     // Missile\r
450     if (e_target.flags & FL_PROJECTILE)\r
451     {\r
452         if (!(validate_flags & TFL_TARGETSELECT_MISSILES))\r
453             return -7;\r
454     }\r
455 \r
456     // Team check\r
457     if (validate_flags & TFL_TARGETSELECT_TEAMCHECK)\r
458     {\r
459         if (validate_flags & TFL_TARGETSELECT_OWNTEAM)\r
460         {\r
461             if (e_target.team != e_turret.team)\r
462                 return -8;\r
463 \r
464             if (e_turret.team != e_target.owner.team)\r
465                 return -8.5;\r
466         }\r
467         else\r
468         {\r
469             if (e_target.team == e_turret.team)\r
470                 return -9;\r
471 \r
472             if (e_turret.team == e_target.owner.team)\r
473                 return -9.5;\r
474         }\r
475     }\r
476 \r
477     // Range limits?\r
478     tvt_dist = vlen(e_turret.origin - real_origin(e_target));\r
479     if (validate_flags & TFL_TARGETSELECT_RANGELIMTS)\r
480     {\r
481         if (tvt_dist < e_turret.target_range_min)\r
482             return -13;\r
483 \r
484         if (tvt_dist > e_turret.target_range)\r
485             return -14;\r
486     }\r
487 \r
488     // Can we even aim this thing?\r
489     tvt_thadv = angleofs(e_turret.tur_head,e_target);\r
490     tvt_tadv  = angleofs(e_turret,e_target);\r
491     tvt_thadf = vlen(tvt_thadv);\r
492     tvt_tadf  = vlen(tvt_tadv);\r
493 \r
494     if (validate_flags & TFL_TARGETSELECT_ANGLELIMITS)\r
495     {\r
496         if (fabs(tvt_tadv_x) > e_turret.aim_maxpitch)\r
497             return -11;\r
498 \r
499         if (fabs(tvt_tadv_y) > e_turret.aim_maxrot)\r
500             return -12;\r
501     }\r
502 \r
503     // Line of sight?\r
504     if (validate_flags & TFL_TARGETSELECT_LOS)\r
505     {\r
506         v_tmp = real_origin(e_target) + ((e_target.mins + e_target.maxs) * 0.5);\r
507         //v_tmp = e_target.origin;\r
508         traceline(e_turret.origin + e_turret.tur_aimorg,v_tmp,0,e_turret);\r
509 \r
510         if (e_turret.aim_firetolerance_dist < vlen(v_tmp - trace_endpos))\r
511             return -10;\r
512     }\r
513 \r
514 #ifdef TURRET_DEBUG_TARGETSELECT\r
515     bprint("Target:",e_target.netname," is a valid target for ",e_turret.netname,"\n");\r
516 #endif\r
517 \r
518     return 1;\r
519 }\r
520 \r
521 entity turret_select_target()\r
522 {\r
523     entity e;        // target looper entity\r
524     float  score;    // target looper entity score\r
525     entity e_enemy;  // currently best scoreing target\r
526     float  m_score;  // currently best scoreing target's score\r
527     float f;\r
528 \r
529     m_score = 0;\r
530     if(self.enemy)\r
531     if(turret_validate_target(self,self.enemy,self.target_select_flags) > 0)\r
532     {\r
533         e_enemy = self.enemy;\r
534         m_score = self.turret_score_target(self,e_enemy) * self.target_select_samebias;\r
535     }\r
536 \r
537     e = findradius(self.origin,self.target_range);\r
538 \r
539     // Nothing to aim at?\r
540     if (!e) return world;\r
541 \r
542     while (e)\r
543     {\r
544         f = turret_validate_target(self,e,self.target_select_flags);\r
545         if (f > 0)\r
546         {\r
547             score = self.turret_score_target(self,e);\r
548             if ((score > m_score) && (score > 0))\r
549             {\r
550                 e_enemy = e;\r
551                 m_score = score;\r
552             }\r
553         }\r
554         e = e.chain;\r
555     }\r
556 \r
557     return e_enemy;\r
558 }\r
559 \r
560 void turret_think()\r
561 {\r
562     entity e;\r
563 \r
564     self.nextthink = (time + self.ticrate);\r
565 \r
566     // ONS uses somewhat backwards linking.\r
567     if (teamplay)\r
568     {\r
569         if (g_onslaught)\r
570         {\r
571 \r
572         }\r
573         else\r
574         {\r
575             if (self.target)\r
576             {\r
577                 e = find(world,targetname,self.target);\r
578                 if (e != world)\r
579                     self.team = e.team;\r
580             }\r
581         }\r
582 \r
583         if (self.team != self.tur_head.team)\r
584             turret_stdproc_respawn();\r
585     }\r
586 \r
587 \r
588     if (cvar("g_turrets_reloadcvars") == 1)\r
589     {\r
590         e = nextent(world);\r
591         while (e)\r
592         {\r
593             if (e.tur_head != world)\r
594             {\r
595 \r
596                 load_unit_settings(e,e.cvar_basename,1);\r
597                 e.turret_postthink();\r
598             }\r
599 \r
600             e = nextent(e);\r
601         }\r
602 \r
603         cvar_set("g_turrets_reloadcvars","0");\r
604     }\r
605 \r
606 #ifdef TURRET_DEBUG\r
607     if (self.tur_dbg_tmr1 < time)\r
608     {\r
609         if (self.enemy) paint_target (self.enemy,128,self.tur_dbg_rvec,0.9);\r
610         paint_target(self,256,self.tur_dbg_rvec,0.9);\r
611         self.tur_dbg_tmr1 = time + 1;\r
612     }\r
613 #endif\r
614 \r
615     //Do custom prethink, and bail if it fails.\r
616     //if (!self.turret_prethink()) return;\r
617 \r
618     // Handle ammo\r
619     if (self.ammo < self.ammo_max)\r
620         self.ammo = min(self.ammo + self.ammo_recharge,self.ammo_max);\r
621 \r
622 \r
623     // Inactive turrets needs to run the think loop too\r
624     // So they can handle animation and wake up if need be.\r
625     if(!self.tur_active)\r
626     {\r
627         turret_stdproc_track();\r
628         return;\r
629     }\r
630 \r
631     //This is just wrong :|\r
632     if(self.deadflag != DEAD_NO)\r
633     {\r
634         dprint("Warning:dead turret running the think function!\n");\r
635         //self.enemy = world;\r
636         //turret_stdproc_track();\r
637         return;\r
638     }\r
639 \r
640     // This is typicaly used for zaping every target in range\r
641     // turret_fusionreactor uses this to recharge friendlys.\r
642     if (self.shoot_flags & TFL_SHOOT_HITALLVALID)\r
643     {\r
644 \r
645         // Do a self.turret_fire for every valid target.\r
646         e = findradius(self.origin,self.target_range);\r
647 \r
648         while (e)\r
649         {\r
650             if (turret_validate_target(self,e,self.target_validate_flags))\r
651             {\r
652                 self.enemy = e;\r
653 \r
654                 turret_do_updates(self);\r
655 \r
656                 if ( self.turret_firecheckfunc() ) turret_fire();\r
657             }\r
658 \r
659             e = e.chain;\r
660         }\r
661         self.enemy = world;\r
662 \r
663     }\r
664     else\r
665     {\r
666         // Special case for volly always. if it fired once it must compleate the volly.\r
667         if((self.shoot_flags & TFL_SHOOT_VOLLYALWAYS) && (self.volly_counter != self.shot_volly))\r
668         {\r
669             // Predict or whatnot\r
670             if not((self.aim_flags & TFL_AIM_NO))\r
671                 self.tur_aimpos = turret_stdproc_aim_generic();\r
672 \r
673 \r
674             // Turn & pitch\r
675             if (!self.track_flags & TFL_TRACK_NO)\r
676                 turret_stdproc_track();\r
677 \r
678             turret_do_updates(self);\r
679 \r
680             // Fire!\r
681             if (self.turret_firecheckfunc() != 0)\r
682                 turret_fire();\r
683 \r
684             self.turret_postthink();\r
685 \r
686             return;\r
687         }\r
688 \r
689         // Check if we have a vailid enemy, and try to find one if we dont.\r
690         if ((turret_validate_target(self,self.enemy,self.target_validate_flags) <= 0) && (self.cnt < time))\r
691         {\r
692             self.enemy = turret_select_target();\r
693             self.cnt = time + cvar("g_turrets_targetscan_mindelay");\r
694         }\r
695 \r
696 \r
697         // No target, just go to idle, do any custom stuff and bail.\r
698         if (self.enemy == world)\r
699         {\r
700             // Turn & pitch\r
701             if (!self.track_flags & TFL_TRACK_NO)\r
702                 turret_stdproc_track();\r
703 \r
704             // do any per-turret stuff\r
705             self.turret_postthink();\r
706 \r
707             // And bail.\r
708             return;\r
709         }\r
710         else\r
711             self.lip = time + cvar("g_turrets_aimidle_delay"); // Keep track of the last time we had a target.\r
712 \r
713         //turret_do_updates(self);\r
714 \r
715         // Predict or whatnot\r
716         if not((self.aim_flags & TFL_AIM_NO))\r
717             self.tur_aimpos = turret_stdproc_aim_generic();\r
718 \r
719         // Fire?\r
720         //if (self.turret_firecheckfunc() != 0)\r
721         //    turret_fire();\r
722 \r
723         //turret_do_updates(self);\r
724 \r
725         // Turn & pitch\r
726         if (!self.track_flags & TFL_TRACK_NO)\r
727             turret_stdproc_track();\r
728 \r
729         turret_do_updates(self);\r
730 \r
731         // Fire?\r
732         if (self.turret_firecheckfunc() != 0)\r
733             turret_fire();\r
734     }\r
735 \r
736     // do any per-turret stuff\r
737     self.turret_postthink();\r
738 }\r
739 \r
740 void turret_fire()\r
741 {\r
742     if (cvar("g_turrets_nofire") != 0)\r
743         return;\r
744 \r
745     if ((!self.tur_active) || (self.deadflag != DEAD_NO))\r
746         return;\r
747 \r
748     self.turret_firefunc();\r
749 \r
750     self.attack_finished_single = time + self.shot_refire;\r
751     self.ammo                   = self.ammo - self.shot_dmg;\r
752     self.volly_counter          = self.volly_counter - 1;\r
753     if (self.volly_counter <= 0)\r
754     {\r
755         self.volly_counter = self.shot_volly;\r
756 \r
757         if (self.shoot_flags & TFL_SHOOT_CLEARTARGET)\r
758             self.enemy = world;\r
759 \r
760         if (self.shot_volly > 1)\r
761             self.attack_finished_single = time + self.shot_volly_refire;\r
762     }\r
763 \r
764 \r
765 #ifdef TURRET_DEBUG\r
766     if (self.enemy) paint_target3(self.tur_aimpos, 64, self.tur_dbg_rvec, self.tur_impacttime + 0.25);\r
767 #endif\r
768 }\r
769 \r
770 void turret_stdproc_fire()\r
771 {\r
772     dprint("^1Bang, ^3your dead^7 ",self.enemy.netname,"! ^1(turret with no real firefunc)\n");\r
773 }\r
774 \r
775 /*\r
776     When .used a turret switched team to activator.team.\r
777     If activator is world, the turrets goes inactive.\r
778 */\r
779 void turret_stdproc_use()\r
780 {\r
781      //bprint("Used:",self.netname, " By ",other.classname,"\n");\r
782 \r
783     self.team = activator.team;\r
784 \r
785     if(self.team == 0)\r
786         self.tur_active = 0;\r
787     else\r
788         self.tur_active = 1;\r
789 \r
790 }\r
791 \r
792 /*\r
793 * Standard turret initialization. use this!\r
794 * (unless you have a very good reason not to.)\r
795 * Any special stuff like multiple cannon models should be done\r
796 * after this is proc called.\r
797 * if the return value is 0, the turret should be removed.\r
798 */\r
799 float turret_stdproc_init (string cvar_base_name)\r
800 {\r
801         entity e;\r
802 \r
803     // Are turrets allowed atm?\r
804     if (cvar("g_turrets") == 0) return 0;\r
805 \r
806     // Better more then once then never.\r
807     // turret_gibs_precash();\r
808 \r
809     if (self.spawnflags & 2)\r
810     {\r
811         entity tb;\r
812         precache_model("models/turrets/terrainbase.md3");\r
813         tb = spawn();\r
814         setmodel(tb,"models/turrets/terrainbase.md3");\r
815         setorigin(tb,self.origin);\r
816         tb.solid = SOLID_BBOX;\r
817         makestatic(tb);\r
818     }\r
819 \r
820     self.cvar_basename = cvar_base_name;\r
821     load_unit_settings(self,self.cvar_basename,0);\r
822 \r
823     // Group all turrets into the same team if in non teamplaymode, so they dont try to kill eachother.\r
824     if (cvar("g_assult") != 0)\r
825     {\r
826         if (!self.team)\r
827             self.team = 14; // Assume turrets are on the defending side if not explicitly set otehrwize\r
828     }\r
829     else if (!teamplay)\r
830                 self.team = MAX_SHOT_DISTANCE;\r
831         else if(g_onslaught && self.targetname)\r
832         {\r
833                 e = find(world,target,self.targetname);\r
834                 if(e != world)\r
835                         self.team = e.team;\r
836         }\r
837         else if(!self.team)\r
838                 self.team = MAX_SHOT_DISTANCE;\r
839 \r
840 \r
841     /*\r
842     * Try to guess some reasonaly defaults\r
843     * for missing params and do sanety checks\r
844     * thise checks could produce some "interesting" results\r
845     * if it hits a glitch in my logic :P so try to set as mutch\r
846     * as possible beforehand.\r
847     */\r
848     if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)\r
849     {\r
850         // Support units generaly dont need to have a high speed ai-loop\r
851         if (!self.ticrate) self.ticrate = 0.25;     // Speed of this turrets AI loop\r
852     }\r
853     else\r
854     {\r
855         if (!self.ticrate) self.ticrate = 0.1;     // Speed of this turrets AI loop\r
856     }\r
857 \r
858     self.ticrate = bound(0.01,self.ticrate,60);  // keep it sane plz\r
859 \r
860 // General stuff\r
861     if (self.netname == "")  self.netname        = "turret";\r
862 \r
863     if (!self.respawntime) self.respawntime = 60;\r
864     self.respawntime = max(-1,self.respawntime);\r
865 \r
866     if (!self.health)        self.health         = 1000;\r
867     self.tur_health = max(1,self.health);\r
868 \r
869     if (!self.turrcaps_flags) self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;\r
870 \r
871     if (!self.damage_flags) self.damage_flags = TFL_DMG_YES | TFL_DMG_RETALIATE | TFL_DMG_AIMSHAKE;\r
872 \r
873 // Shot stuff.\r
874     if (!self.shot_refire) self.shot_refire     = 1;\r
875     self.shot_refire = bound(0.01,self.shot_refire,9999);\r
876 \r
877     if (!self.shot_dmg) self.shot_dmg        = self.shot_refire * 50;\r
878     self.shot_dmg = max(1,self.shot_dmg);\r
879 \r
880     if (!self.shot_radius) self.shot_radius     = self.shot_dmg * 0.5;\r
881     self.shot_radius = max(1,self.shot_radius);\r
882 \r
883     if (!self.shot_speed) self.shot_speed      = 2500;\r
884     self.shot_speed = max(1,self.shot_speed);\r
885 \r
886     if (!self.shot_spread) self.shot_spread     = 0.0125;\r
887     self.shot_spread = bound(0.0001,self.shot_spread,500);\r
888 \r
889     if (!self.shot_force) self.shot_force      = self.shot_dmg * 0.5 + self.shot_radius * 0.5;\r
890     self.shot_force = bound(0.001,self.shot_force,MAX_SHOT_DISTANCE * 0.5);\r
891 \r
892     if (!self.shot_volly) self.shot_volly = 1;\r
893     self.shot_volly = bound(1,self.shot_volly,floor(self.ammo_max / self.shot_dmg));\r
894 \r
895     if (!self.shot_volly_refire) self.shot_volly_refire = self.shot_refire * self.shot_volly;\r
896     self.shot_volly_refire = bound(self.shot_refire,self.shot_volly_refire,60);\r
897 \r
898     if (!self.firecheck_flags)\r
899         self.firecheck_flags = TFL_FIRECHECK_WORLD | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES |\r
900                                TFL_FIRECHECK_LOS | TFL_FIRECHECK_AIMDIST | TFL_FIRECHECK_TEAMCECK |\r
901                                TFL_FIRECHECK_OWM_AMMO | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_WORLD;\r
902 \r
903 // Range stuff.\r
904     if (!self.target_range) self.target_range               = self.shot_speed * 0.5;\r
905     self.target_range = bound(0,self.target_range,MAX_SHOT_DISTANCE);\r
906 \r
907     if (!self.target_range_min)          self.target_range_min           = self.shot_radius * 2;\r
908     self.target_range_min = bound(0,self.target_range_min,MAX_SHOT_DISTANCE);\r
909 \r
910     if (!self.target_range_fire)         self.target_range_fire          = self.target_range * 0.8;\r
911     self.target_range_fire = bound(0,self.target_range_fire,MAX_SHOT_DISTANCE);\r
912 \r
913     if (!self.target_range_optimal)      self.target_range_optimal       = self.target_range_fire * 0.5;\r
914     self.target_range_optimal = bound(0,self.target_range_optimal,MAX_SHOT_DISTANCE);\r
915 \r
916 \r
917 // Aim stuff.\r
918     if (!self.aim_maxrot)    self.aim_maxrot    = 45;\r
919     self.aim_maxrot = bound(0,self.aim_maxrot,361);\r
920 \r
921     if (!self.aim_maxpitch)  self.aim_maxpitch  = 20;\r
922     self.aim_maxpitch = bound(0,self.aim_maxpitch,90);\r
923 \r
924     if (!self.aim_speed)     self.aim_speed     = 36;\r
925     self.aim_speed  = bound(0.1,self.aim_speed, 1000);\r
926 \r
927     if (!self.aim_firetolerance_dist)     self.aim_firetolerance_dist  = 5 + (self.shot_radius * 2);\r
928     self.aim_firetolerance_dist = bound(0.1,self.aim_firetolerance_dist,MAX_SHOT_DISTANCE);\r
929 \r
930 //    if (!self.aim_firetolerance_angle)     self.aim_firetolerance_angle  = 10;\r
931 //    self.aim_firetolerance_angle = bound(0.1,self.aim_firetolerance_angle,360);\r
932 \r
933     if (!self.aim_flags) self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_ZEASE;\r
934 \r
935     // Sill the most tested (and aim-effective)\r
936     if (!self.track_type) self.track_type = TFL_TRACKTYPE_STEPMOTOR;\r
937 \r
938     if (self.track_type != TFL_TRACKTYPE_STEPMOTOR)\r
939     {\r
940         // Fluid / Ineria mode. Looks mutch nicer, bit experimental &\r
941         // Can inmapt aim preformance alot.\r
942         // needs a bit diffrent aimspeed\r
943         if (!self.aim_speed) self.aim_speed = 180;\r
944         self.aim_speed  = bound(0.1,self.aim_speed, 1000);\r
945 \r
946         if (!self.track_accel_pitch) self.track_accel_pitch = 0.75;\r
947         if (!self.track_accel_rot)   self.track_accel_rot   = 0.75;\r
948         if (!self.track_blendrate)   self.track_blendrate   = 0.35;\r
949     }\r
950 \r
951     if (!self.track_flags) self.track_flags = TFL_TRACK_PITCH | TFL_TRACK_ROT;\r
952 \r
953 \r
954 // Target selection stuff.\r
955     if (!self.target_select_rangebias)   self.target_select_rangebias     = 1;\r
956     self.target_select_rangebias = bound(-10,self.target_select_rangebias,10);\r
957 \r
958     if (!self.target_select_samebias)    self.target_select_samebias      = 1;\r
959     self.target_select_samebias = bound(-10,self.target_select_samebias,10);\r
960 \r
961     if (!self.target_select_anglebias)   self.target_select_anglebias     = 1;\r
962     self.target_select_anglebias = bound(-10,self.target_select_anglebias,10);\r
963 \r
964     if (!self.target_select_missilebias)   self.target_select_missilebias = -10;\r
965     self.target_select_missilebias = bound(-10,self.target_select_missilebias,10);\r
966     self.target_select_playerbias = bound(-10,self.target_select_playerbias,10);\r
967 \r
968     if (!self.target_select_flags)\r
969         if (self.turrcaps_flags & TFL_TURRCAPS_MISSILEKILL)\r
970             self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_MISSILES |\r
971                                        TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_ANGLELIMITS;\r
972         else\r
973             self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS |\r
974                                        TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_ANGLELIMITS;\r
975 \r
976     //if(!self.target_validate_flags)\r
977     self.target_validate_flags = self.target_select_flags;\r
978 \r
979 \r
980 // Ammo stuff\r
981     if (!self.ammo_max)          self.ammo_max       = self.shot_dmg * 10;\r
982     self.ammo_max = max(self.shot_dmg,self.ammo_max);\r
983 \r
984     if (!self.ammo)              self.ammo           = self.shot_dmg * 5;\r
985     self.ammo = bound(0,self.ammo,self.ammo_max);\r
986 \r
987     if (!self.ammo_recharge)     self.ammo_recharge = self.shot_dmg / 2;\r
988     self.ammo_recharge = max(0,self.ammo_recharge);\r
989 \r
990     // Convert the recharge from X per sec to X per ticrate\r
991     self.ammo_recharge = self.ammo_recharge * self.ticrate;\r
992 \r
993     if (!self.ammo_flags) self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;\r
994 \r
995 // Offsets & origins\r
996     if (!self.tur_aimorg)    self.tur_aimorg = '0 0 50';\r
997     if (!self.tur_shotorg)   self.tur_shotorg = '50 0 50';\r
998 \r
999 // End of default & sanety checks, start building the turret.\r
1000 \r
1001 // Spawn extra bits\r
1002     self.tur_head   = spawn();\r
1003 \r
1004     self.tur_head.netname = self.tur_head.classname = "turret_head";\r
1005     self.tur_head.team = self.team;\r
1006 \r
1007     // Defend mode?\r
1008     if (self.target != "")\r
1009     {\r
1010         self.tur_defend = find(world, targetname, self.target);\r
1011         if (self.tur_defend == world)\r
1012         {\r
1013             self.target = "";\r
1014             dprint("Turret has invalid defendpoint!\n");\r
1015         }\r
1016     }\r
1017 \r
1018 // Claim ownership\r
1019     self.tur_head.owner = self;\r
1020 \r
1021 // Put pices in place\r
1022 \r
1023     if (!(self.turrcaps_flags & TFL_TURRCAPS_LINKED))\r
1024         setorigin(self.tur_head,self.origin);\r
1025 \r
1026     // In target defense mode, aim on the spot to defens when idle.\r
1027     if (self.tur_defend)\r
1028         self.idle_aim  = self.tur_head.angles + angleofs(self.tur_head,self.tur_defend);\r
1029     else\r
1030         self.idle_aim  = self.angles;\r
1031 \r
1032     if (!(self.turrcaps_flags & TFL_TURRCAPS_LINKED))\r
1033         self.tur_head.angles    = self.idle_aim;\r
1034 \r
1035     if (!self.health) self.health  = 150;\r
1036         self.tur_health = self.health;\r
1037 \r
1038     self.tur_head.health = self.health;\r
1039 \r
1040     //Solid bbox for preformance reasons\r
1041     self.solid              = SOLID_BBOX;\r
1042     self.tur_head.solid     = SOLID_BBOX;\r
1043 \r
1044     self.takedamage             = DAMAGE_AIM;\r
1045     self.tur_head.takedamage    = DAMAGE_AIM;\r
1046 \r
1047     self.movetype            = MOVETYPE_NOCLIP;\r
1048     self.tur_head.movetype   = MOVETYPE_NOCLIP;\r
1049 \r
1050     // Team colouring?track\r
1051     if (self.team == COLOR_TEAM1) self.colormod = '1.4 0.8 0.8';\r
1052     if (self.team == COLOR_TEAM2) self.colormod = '0.8 0.8 1.4';\r
1053 \r
1054     // Attach stdprocs. override when and what needed\r
1055     if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)\r
1056     {\r
1057         //self.turret_prethink        = turret_stdproc_true;\r
1058         self.turret_score_target    = turret_stdproc_targetscore_support;\r
1059         //self.turret_aim             = turret_stdproc_aim_generic;\r
1060         //self.turret_track           = turret_stdproc_track;\r
1061         self.turret_firecheckfunc   = turret_stdproc_firecheck;\r
1062         self.turret_firefunc        = turret_stdproc_fire;\r
1063         self.turret_postthink       = turret_stdproc_nothing;\r
1064 \r
1065         //self.turret_damagefunc          = turret_stdproc_damage;\r
1066         //self.event_damage               = turret_stdproc_damage;\r
1067         self.tur_head.event_damage      = turret_stdproc_damage;\r
1068 \r
1069         //self.turret_diefunc             = turret_stdproc_die;\r
1070         //self.turret_spawnfunc           = turret_stdproc_respawn;\r
1071 \r
1072     }\r
1073     else\r
1074     {\r
1075 \r
1076         //self.turret_prethink        = turret_stdproc_true;\r
1077         self.turret_score_target    = turret_stdproc_targetscore_generic;\r
1078 \r
1079         //if (self.aim_flags & TFL_AIM_SIMPLE)\r
1080         //    self.turret_aim             = turret_stdproc_aim_simple;\r
1081         //else\r
1082         //    self.turret_aim             = turret_stdproc_aim_generic;\r
1083 \r
1084         //self.turret_track           = turret_stdproc_track;\r
1085         self.turret_firecheckfunc   = turret_stdproc_firecheck;\r
1086         self.turret_firefunc        = turret_stdproc_fire;\r
1087         self.turret_postthink       = turret_stdproc_nothing;\r
1088 \r
1089         //self.turret_damagefunc          = turret_stdproc_damage;\r
1090         self.event_damage               = turret_stdproc_damage;\r
1091         self.tur_head.event_damage      = turret_stdproc_damage;\r
1092 \r
1093         //self.turret_diefunc             = turret_stdproc_die;\r
1094         //self.turret_spawnfunc           = turret_stdproc_respawn;\r
1095         self.turret_addtarget           = turret_stdproc_false;\r
1096     }\r
1097 \r
1098     self.use = turret_stdproc_use;\r
1099     self.bot_attack = TRUE;\r
1100 \r
1101     // Initiate the main AI loop\r
1102     self.think     = turret_think;\r
1103     self.nextthink = time + self.ticrate;\r
1104 \r
1105     self.tur_head.team = self.team;\r
1106     self.view_ofs = '0 0 0';\r
1107 \r
1108 #ifdef TURRET_DEBUG\r
1109     self.tur_dbg_start = self.nextthink;\r
1110     while (vlen(self.tur_dbg_rvec) < 2)\r
1111         self.tur_dbg_rvec  = randomvec() * 4;\r
1112 \r
1113     self.tur_dbg_rvec_x = fabs(self.tur_dbg_rvec_x);\r
1114     self.tur_dbg_rvec_y = fabs(self.tur_dbg_rvec_y);\r
1115     self.tur_dbg_rvec_z = fabs(self.tur_dbg_rvec_z);\r
1116 #endif\r
1117 \r
1118     // Its all good.\r
1119     self.classname = "turret_main";\r
1120 \r
1121     self.tur_active = 1;\r
1122 \r
1123     //if (g_onslaught)\r
1124     //    self.use();\r
1125 \r
1126     //turret_stdproc_use();\r
1127 \r
1128     return 1;\r
1129 }\r
1130 \r
1131 \r