]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/turrets/unit/tesla.qc
Clean up turrets system a bit
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / turrets / unit / tesla.qc
1 #ifdef REGISTER_TURRET
2 REGISTER_TURRET(
3 /* TUR_##id   */ TESLA,
4 /* function   */ t_tesla,
5 /* spawnflags */ TUR_FLAG_HITSCAN | TUR_FLAG_PLAYER | TUR_FLAG_MISSILE,
6 /* mins,maxs  */ '-60 -60 0', '60 60 128',
7 /* model          */ "tesla_base.md3",
8 /* head_model */ "tesla_head.md3",
9 /* netname        */ "tesla",
10 /* fullname   */ _("Tesla Coil")
11 );
12
13 #define TESLA_SETTINGS(turret) 
14
15
16 #ifdef SVQC
17 TESLA_SETTINGS(tesla)
18 #endif // SVQC
19 #else
20 #ifdef SVQC
21
22 entity toast(entity from, float range, float damage)
23 {
24         entity e;
25         entity etarget = world;
26         float d,dd;
27         float r;
28
29         dd = range + 1;
30
31         e = findradius(from.origin,range);
32         while (e)
33         {
34                 if ((e.railgunhit != 1) && (e != from))
35                 {
36                         r = turret_validate_target(self,e,self.target_validate_flags);
37                         if (r > 0)
38                         {
39                                 traceline(from.origin,0.5 * (e.absmin + e.absmax),MOVE_WORLDONLY,from);
40                                 if (trace_fraction == 1.0)
41                                 {
42                                         d = vlen(e.origin - from.origin);
43                                         if (d < dd)
44                                         {
45                                                 dd = d;
46                                                 etarget = e;
47                                         }
48                                 }
49                         }
50                 }
51                 e = e.chain;
52         }
53
54         if (etarget)
55         {
56                 te_csqc_lightningarc(from.origin,etarget.origin);
57                 Damage(etarget, self, self, damage, DEATH_TURRET_TESLA, etarget.origin, '0 0 0');
58                 etarget.railgunhit = 1;
59         }
60
61         return etarget;
62 }
63
64 float turret_tesla_firecheck()
65 {
66         // g_turrets_targetscan_maxdelay forces a target re-scan at least this often
67         float do_target_scan = 0;
68
69         if((self.target_select_time + autocvar_g_turrets_targetscan_maxdelay) < time)
70                 do_target_scan = 1;
71
72         // Old target (if any) invalid?
73         if(self.target_validate_time < time)
74         if (turret_validate_target(self, self.enemy, self.target_validate_flags) <= 0)
75         {
76                 self.enemy = world;
77                 self.target_validate_time = time + 0.5;
78                 do_target_scan = 1;
79         }
80
81         // But never more often then g_turrets_targetscan_mindelay!
82         if (self.target_select_time + autocvar_g_turrets_targetscan_mindelay > time)
83                 do_target_scan = 0;
84
85         if(do_target_scan)
86         {
87                 self.enemy = turret_select_target();
88                 self.target_select_time = time;
89         }
90
91         if not (turret_firecheck())
92                 return 0;
93
94         if(self.enemy)
95                 return 1;
96
97         return 0;
98 }
99
100 void spawnfunc_turret_tesla() { if not(turret_initialize(TUR_TESLA)) remove(self); }
101
102 float t_tesla(float req)
103 {
104         switch(req)
105         {
106                 case TR_ATTACK:
107                 {
108                         entity e, t;
109                         float d, r, i;
110
111                         d = self.shot_dmg;
112                         r = self.target_range;
113                         e = spawn();
114                         setorigin(e,self.tur_shotorg);
115
116                         self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
117
118                         t = toast(e,r,d);
119                         remove(e);
120
121                         if (t == world) return TRUE;
122
123                         self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_TEAMCHECK;
124
125                         self.attack_finished_single = time + self.shot_refire;
126                         for (i = 0; i < 10; ++i)
127                         {
128                                 d *= 0.75;
129                                 r *= 0.85;
130                                 t = toast(t, r, d);
131                                 if (t == world) break;
132
133                         }
134
135                         e = findchainfloat(railgunhit, 1);
136                         while (e)
137                         {
138                                 e.railgunhit = 0;
139                                 e = e.chain;
140                         }
141
142                         return TRUE;
143                 }
144                 case TR_THINK:
145                 {
146                         if not (self.active)
147                         {
148                                 self.tur_head.avelocity = '0 0 0';
149                                 return TRUE;
150                         }
151
152                         if(self.ammo < self.shot_dmg)
153                         {
154                                 self.tur_head.avelocity = '0 45 0' * (self.ammo / self.shot_dmg);
155                         }
156                         else
157                         {
158                                 self.tur_head.avelocity = '0 180 0' * (self.ammo / self.shot_dmg);
159
160                                 if(self.attack_finished_single > time)
161                                         return TRUE;
162
163                                 float f;
164                                 f = (self.ammo / self.ammo_max);
165                                 f = f * f;
166                                 if(f > random())
167                                         if(random() < 0.1)
168                                                 te_csqc_lightningarc(self.tur_shotorg,self.tur_shotorg + (randomvec() * 350));
169                         }
170
171                         return TRUE;
172                 }
173                 case TR_DEATH:
174                 {
175                         return TRUE;
176                 }
177                 case TR_SETUP:
178                 {
179                         self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
180                                                                  TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
181                                                                  
182                         self.turret_firecheckfunc = turret_tesla_firecheck;
183                         self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
184                                                            TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
185
186                         self.firecheck_flags    = TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AMMO_OWN;
187                         self.shoot_flags                = TFL_SHOOT_CUSTOM;
188                         self.ammo_flags                 = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
189                         self.aim_flags                  = TFL_AIM_NO;
190                         self.track_flags                = TFL_TRACK_NO;
191
192                         return TRUE;
193                 }
194                 case TR_PRECACHE:
195                 {
196                         precache_model ("models/turrets/tesla_base.md3");
197                         precache_model ("models/turrets/tesla_head.md3");
198                         return TRUE;
199                 }
200                 case TR_CONFIG:
201                 {
202                         TUR_CONFIG_SETTINGS(TESLA_SETTINGS(tesla))
203                         return TRUE;
204                 }
205         }
206
207         return TRUE;
208 }
209
210 #endif // SVQC
211 #ifdef CSQC
212 float t_tesla(float req)
213 {
214         switch(req)
215         {
216                 case TR_SETUP:
217                 {
218                         return TRUE;
219                 }
220                 case TR_PRECACHE:
221                 {
222                         precache_model ("models/turrets/tesla_base.md3");
223                         precache_model ("models/turrets/tesla_head.md3");
224                         return TRUE;
225                 }
226         }
227
228         return TRUE;
229 }
230
231 #endif // CSQC
232 #endif // REGISTER_TURRET