]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/tturrets.qc
Move turrets death and gib to client (now zero network use for those events)
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / tturrets.qc
1 void turrets_precache()
2 {
3     precache_model ("models/turrets/ewheel-base2.md3");
4     precache_model ("models/turrets/ewheel-gun1.md3");
5     precache_model ("models/turrets/base.md3");
6     precache_model ("models/turrets/flac.md3");
7     precache_model ("models/turrets/reactor.md3");
8     precache_model ("models/turrets/hellion.md3");
9     precache_model ("models/turrets/hk.md3");
10     precache_model ("models/turrets/machinegun.md3");
11     precache_model ("models/turrets/mlrs.md3");
12     precache_model ("models/turrets/phaser.md3");
13     precache_model ("models/turrets/phaser_beam.md3");
14     precache_model ("models/turrets/plasma.md3");
15     precache_model ("models/turrets/plasmad.md3");
16     precache_model ("models/turrets/tesla_head.md3");
17     precache_model ("models/turrets/tesla_base.md3");
18     precache_model ("models/turrets/walker_head_minigun.md3");
19     precache_model ("models/turrets/walker_body.md3");
20     precache_model ("models/turrets/walker_props.md3");
21     precache_model ("models/turrets/walker_spawn.md3");
22     precache_model ("models/turrets/rocket.md3");
23     
24     precache_sound ("turrets/phaser.wav");
25     precache_sound ("weapons/rocket_impact.wav");
26     precache_sound ("weapons/uzi_fire.wav");
27 }
28
29 void turret_remove()
30 {
31     dprint("Removing turret type ", ftos(self.turret_type), "\n");
32     
33     remove(self.tur_head);
34     self.tur_head = world;    
35 }
36
37 void turret_changeteam()
38 {
39         self.colormod = '0 0 0';
40         switch(self.team)
41         {
42         case COLOR_TEAM1: // Red
43             self.colormod = '2 0.5 0.5';
44             break;
45
46         case COLOR_TEAM2: // Blue
47             self.colormod = '0.5 0.5 2';
48             break;
49
50         case COLOR_TEAM3: // Yellow
51             self.colormod = '1.4 1.4 0.6';
52             break;
53
54         case COLOR_TEAM4: // Pink
55             self.colormod = '1.4 0.6 1.4';
56             break;
57         }
58         
59         self.tur_head.colormod = self.colormod;    
60 }
61
62 void turret_head_draw()
63 {    
64     float dt;
65     dt = time - self.move_time;
66     self.move_time = time;
67     if(dt <= 0)
68         return;
69     
70     self.angles += dt * self.move_avelocity;    
71     self.drawmask = MASK_NORMAL;
72 }
73
74 void turret_draw()
75 {        
76     if (self.health < 127)
77     if(random() < 0.25)
78         te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
79     
80     self.drawmask = MASK_NORMAL;
81 }
82
83 string tid2info_base;
84 string tid2info_head;
85 vector  tid2info_min;
86 vector  tid2info_max;
87 void turret_tid2info(float _tid)
88 {
89     tid2info_base = "models/turrets/base.md3";
90     tid2info_min = '-32 -32 0';
91     tid2info_max = '32 32 64';
92
93     switch(_tid)
94     {
95         case TID_EWHEEL:
96             tid2info_base = "models/turrets/ewheel-base2.md3";
97             tid2info_head = "models/turrets/ewheel-gun1.md3";
98             break;
99         case TID_FLAC:
100             tid2info_head = "models/turrets/flac.md3";
101             break;
102         case TID_FUSION:
103             tid2info_head = "models/turrets/reactor.md3";
104             tid2info_min = '-34 -34 0';
105             tid2info_max = '34 34 90';
106             break;
107         case TID_HELLION:
108             tid2info_head = "models/turrets/hellion.md3";
109             break;
110         case TID_HK:
111             tid2info_head = "models/turrets/hk.md3";
112             break;
113         case TID_MACHINEGUN:
114             tid2info_head = "models/turrets/machinegun.md3";
115             break;
116         case TID_MLRS:
117             tid2info_head = "models/turrets/mlrs.md3";
118             break;
119         case TID_PHASER:
120             tid2info_head = "models/turrets/phaser.md3";
121             break;
122         case TID_PLASMA:
123             tid2info_head = "models/turrets/plasma.md3";
124             break;
125         case TID_PLASMA_DUAL:
126             tid2info_head = "models/turrets/plasmad.md3";
127             break;
128         case TID_TESLA:
129             tid2info_base = "models/turrets/tesla_base.md3";
130             tid2info_head = "models/turrets/tesla_head.md3";
131             tid2info_min = '-60 -60 0';
132             tid2info_max  ='60 60 128';
133             break;
134         case TID_WALKER:
135             tid2info_base = "models/turrets/walker_body.md3";
136             tid2info_head = "models/turrets/walker_head_minigun.md3";
137             tid2info_min = '-70 -70 0';
138             tid2info_max = '70 70 95';
139             break;
140     }    
141 }
142
143 //void(entity e, entity tagentity, string tagname) setattachment = #443;
144 void turret_construct()
145 {    
146     if(self.tur_head == world)
147         self.tur_head = spawn();
148     
149     turret_tid2info(self.turret_type);
150     
151     setorigin(self, self.origin);
152     
153     self.tur_head.classname = "turret_head";
154     self.tur_head.owner   = self;
155
156     setmodel(self, tid2info_base);
157     setmodel(self.tur_head, tid2info_head);
158     
159     self.tur_head.move_movetype = MOVETYPE_NOCLIP;
160     self.move_movetype = MOVETYPE_NOCLIP;
161     self.tur_head.angles = self.angles;
162     
163     setsize(self, tid2info_min, tid2info_max);
164     setsize(self.tur_head, '0 0 0', '0 0 0');
165     
166     setorigin(self.tur_head, gettaginfo(self, gettagindex(self, "tag_head")));
167     self.health             = 255;
168     self.solid              = SOLID_BBOX;
169     self.tur_head.solid     = SOLID_NOT;
170     self.movetype           = MOVETYPE_NOCLIP;
171     self.tur_head.movetype  = MOVETYPE_NOCLIP;    
172     self.draw               = turret_draw;
173     self.tur_head.draw      = turret_head_draw;
174     self.entremove          = turret_remove;
175 }
176
177 entity turret_gibtoss(string _model, vector _from, vector _to, vector _cmod, float _explode);
178 void turret_gibboom();
179
180 void turret_gib_draw()
181 {
182     Movetype_Physics_MatchTicrate(autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy);
183     self.drawmask = MASK_NORMAL;
184         
185         if(self.cnt)
186         {
187             if(time >= self.nextthink)
188             {
189             turret_gibboom();
190             remove(self);
191             }
192         }
193         else
194         {
195         self.alpha = bound(0, self.nextthink - time, 1);
196         if(self.alpha < ALPHA_MIN_VISIBLE)
197             remove(self);           
198         }
199 }
200
201 void turret_gibboom()
202 {
203     float i;
204     sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
205     pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
206
207     for (i = 1; i < 5; i = i +1)
208         turret_gibtoss(strcat("models/turrets/head-gib", ftos(i), ".md3"), self.origin, self.velocity + randomvec() * 700, '0 0 0', FALSE);
209 }
210
211 entity turret_gibtoss(string _model, vector _from, vector _to, vector _cmod, float _explode)
212 {
213     entity gib;
214
215     gib = spawn();
216     setorigin(gib, _from);
217     setmodel(gib, _model);
218     gib.colormod = _cmod;
219         gib.solid = SOLID_CORPSE;
220     gib.draw = turret_gib_draw;    
221     gib.cnt = _explode;
222     
223     if(_explode)
224     {
225         gib.nextthink = time + 0.2 * (autocvar_cl_gibs_lifetime * (1 + prandom() * 0.15));
226         gib.effects = EF_FLAME;
227     }        
228     else
229         gib.nextthink = time + autocvar_cl_gibs_lifetime * (1 + prandom() * 0.15);
230     
231     gib.gravity = 1;
232         gib.move_movetype = MOVETYPE_BOUNCE;
233         gib.move_origin = gib.origin = _from;
234         gib.move_velocity = _to;        
235         gib.move_avelocity = prandomvec() * 32;
236         gib.move_time = time;
237         gib.damageforcescale = 1;
238         
239         return gib;
240 }
241
242 void turret_die()
243 {    
244     entity headgib;
245     
246     setmodel(self, "");
247     setmodel(self.tur_head, "");
248     sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
249     pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
250     turret_tid2info(self.turret_type);
251
252     // Base
253     if(self.turret_type == TID_EWHEEL)
254         turret_gibtoss(tid2info_base, self.origin, self.velocity, '-1 -1 -1', FALSE);
255     else if (self.turret_type == TID_WALKER)
256         turret_gibtoss(tid2info_base, self.origin, self.velocity, '-1 -1 -1', FALSE);
257     else if (self.turret_type == TID_TESLA)
258         turret_gibtoss(tid2info_base, self.origin, self.velocity, '-1 -1 -1', FALSE);
259     else
260     {        
261         if (random() > 0.5)
262         {
263             turret_gibtoss("models/turrets/base-gib2.md3", self.origin + '0 0 2', '0 0 50' + randomvec() * 150, '0 0 0', FALSE);
264             turret_gibtoss("models/turrets/base-gib3.md3", self.origin + '0 0 2', '0 0 50' + randomvec() * 150, '0 0 0', FALSE);
265             turret_gibtoss("models/turrets/base-gib4.md3", self.origin + '0 0 2', '0 0 50' + randomvec() * 150, '0 0 0', FALSE);
266         }
267         else
268             turret_gibtoss("models/turrets/base-gib1.md3", self.origin, '0 0 0', '0 0 0', TRUE);
269     }
270     
271     headgib = turret_gibtoss(tid2info_head, self.origin + '0 0 32', '0 0 200' + randomvec() * 200, '-1 -1 -1', TRUE);
272     headgib.angles = headgib.move_angles = self.tur_head.angles;
273     headgib.avelocity = headgib.move_avelocity = self.tur_head.move_avelocity + randomvec() * 45;
274     headgib.avelocity_y = headgib.move_avelocity_y = headgib.move_avelocity_y * 5;
275     headgib.gravity = 0.5;
276 }
277
278 void ent_turret()
279 {
280     float sf;
281     sf = ReadByte();
282
283         if(sf & TNSF_SETUP)
284         {           
285             self.turret_type = ReadByte();
286             dprint("Constructing turret type ", ftos(self.turret_type), "\n");
287                     
288             self.origin_x = ReadCoord();
289             self.origin_y = ReadCoord();
290             self.origin_z = ReadCoord();
291             
292             self.angles_x = ReadAngle();
293             self.angles_y = ReadAngle();
294             
295             turret_construct();
296     }
297     
298     if(sf & TNSF_ANG)
299     {
300         self.tur_head.move_angles_x = ReadShort();
301         self.tur_head.move_angles_y = ReadShort();
302         self.tur_head.angles = self.angles + self.tur_head.move_angles;
303     }
304     
305     if(sf & TNSF_AVEL)
306     {
307         self.tur_head.move_avelocity_x = ReadShort();
308         self.tur_head.move_avelocity_y = ReadShort();            
309     }
310     
311     if(sf & TNSF_STATUS)
312     {        
313         float _team;
314         _team = ReadByte();
315         _team -= 1; // /&)=(%&#)&%)/#&)=½!!!½!!". thanks.
316         self.health = ReadByte();
317         if(_team != self.team)
318         {
319             self.team = _team;
320             turret_changeteam();        
321         }
322     } 
323     
324     if(sf == TNSF_DIE)
325         turret_die();
326 }