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