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