]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/tturrets/units/unit_tessla.qc
Merge remote-tracking branch 'origin/master' into samual/update_effects_tab
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / tturrets / units / unit_tessla.qc
1 void spawnfunc_turret_tesla();
2 void turret_tesla_dinit();
3 void turret_tesla_fire();
4
5 entity toast(entity from, float range, float damage)
6 {
7     entity e;
8     entity etarget = world;
9     float d,dd;
10     float r;
11
12     dd = range + 1;
13
14     e = findradius(from.origin,range);
15     while (e)
16     {
17         if ((e.railgunhit != 1) && (e != from))
18         {
19             r = turret_validate_target(self,e,self.target_validate_flags);
20             if (r > 0)
21             {
22                 traceline(from.origin,0.5 * (e.absmin + e.absmax),MOVE_WORLDONLY,from);
23                 if (trace_fraction == 1.0)
24                 {
25                     d = vlen(e.origin - from.origin);
26                     if (d < dd)
27                     {
28                         dd = d;
29                         etarget = e;
30                     }
31                 }
32             }
33         }
34         e = e.chain;
35     }
36
37     if (etarget)
38     {        
39         te_csqc_lightningarc(from.origin,etarget.origin);
40         Damage(etarget, self, self, damage, DEATH_TURRET_TESLA, etarget.origin, '0 0 0');
41         etarget.railgunhit = 1;
42     }
43
44     return etarget;
45 }
46
47 float turret_tesla_firecheck()
48 {
49     // g_turrets_targetscan_maxdelay forces a target re-scan at least this often
50     float do_target_scan = 0;
51     
52     if((self.target_select_time + autocvar_g_turrets_targetscan_maxdelay) < time)
53         do_target_scan = 1;
54
55     // Old target (if any) invalid?
56     if(self.target_validate_time < time)
57     if (turret_validate_target(self, self.enemy, self.target_validate_flags) <= 0)
58     {
59         self.enemy = world;
60         self.target_validate_time = time + 0.5;
61         do_target_scan = 1;
62     }
63
64     // But never more often then g_turrets_targetscan_mindelay!
65     if (self.target_select_time + autocvar_g_turrets_targetscan_mindelay > time)
66         do_target_scan = 0;
67
68     if(do_target_scan)
69     {
70         self.enemy = turret_select_target();
71         self.target_select_time = time;
72     }
73
74     if not (turret_stdproc_firecheck())
75         return 0;
76
77     if(self.enemy)
78         return 1;
79
80     return 0;
81 }
82
83
84 void turret_tesla_fire()
85 {
86     entity e, t;
87     float d, r, i;
88
89     d = self.shot_dmg;
90     r = self.target_range;
91     e = spawn();
92     setorigin(e,self.tur_shotorg);
93
94     self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
95
96     t = toast(e,r,d);
97     remove(e);
98
99     if (t == world) return;
100
101     self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_TEAMCHECK;
102
103     self.attack_finished_single = time + self.shot_refire;
104     for (i = 0; i < 10; ++i)
105     {
106         d *= 0.75;
107         r *= 0.85;
108         t = toast(t, r, d);
109         if (t == world) break;
110
111     }
112
113     e = findchainfloat(railgunhit, 1);
114     while (e)
115     {
116         e.railgunhit = 0;
117         e = e.chain;
118     }
119 }
120
121 void turret_tesla_postthink()
122 {
123     if not (self.active)
124     {
125         self.tur_head.avelocity = '0 0 0';
126         return;
127     }
128
129     if(self.ammo < self.shot_dmg)
130     {
131         self.tur_head.avelocity = '0 45 0' * (self.ammo / self.shot_dmg);
132     }
133     else
134     {
135         self.tur_head.avelocity = '0 180 0' * (self.ammo / self.shot_dmg);
136
137         if(self.attack_finished_single > time)
138             return;
139
140         float f;
141         f = (self.ammo / self.ammo_max);
142         f = f * f;
143         if(f > random())
144             if(random() < 0.1)
145                 te_csqc_lightningarc(self.tur_shotorg,self.tur_shotorg + (randomvec() * 350));
146     }
147 }
148
149
150 void turret_tesla_dinit()
151 {
152     if (self.netname == "")      self.netname     = "Tesla Coil";
153
154     self.turrcaps_flags      = TFL_TURRCAPS_HITSCAN | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MISSILEKILL;
155
156     self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
157                                TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
158
159     self.firecheck_flags     = TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_OWM_AMMO;
160     self.shoot_flags         = TFL_SHOOT_CUSTOM;
161     self.ammo_flags          = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
162     self.aim_flags           = TFL_AIM_NO;
163     self.track_flags         = TFL_TRACK_NO;
164
165     if (turret_stdproc_init("tesla_std", "models/turrets/tesla_base.md3", "models/turrets/tesla_head.md3", TID_TESLA) == 0)
166     {
167         remove(self);
168         return;
169     }
170     setsize(self,'-60 -60 0','60 60 128');
171
172     self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
173                                  TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
174
175     self.turret_firefunc      = turret_tesla_fire;
176     self.turret_postthink     = turret_tesla_postthink;
177     self.turret_firecheckfunc = turret_tesla_firecheck;
178 }
179
180 /*QUAKED turret_tesla (0 .5 .8) ?
181 */
182 void spawnfunc_turret_tesla()
183 {
184     precache_model ("models/turrets/tesla_head.md3");
185     precache_model ("models/turrets/tesla_base.md3");
186
187
188     self.think = turret_tesla_dinit;
189     self.nextthink = time + 0.5;
190 }
191