]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/generator.qc
Merge branch 'master' into terencehill/hud_cleanups
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / generator.qc
1 #include "generator.qh"
2
3 #include "teamradar.qh"
4 #include "../common/movetypes/movetypes.qh"
5
6 .float alpha;
7 .float scale;
8 .int count;
9 .float max_health;
10
11 void ons_generator_ray_draw(entity this)
12 {
13         if(time < self.move_time)
14                 return;
15
16         self.move_time = time + 0.05;
17
18         if(self.count > 10)
19         {
20                 remove(self);
21                 return;
22         }
23
24         if(self.count > 5)
25                 self.alpha -= 0.1;
26         else
27                 self.alpha += 0.1;
28
29         self.scale += 0.2;
30         self.count +=1;
31 }
32
33 void ons_generator_ray_spawn(vector org)
34 {
35         entity e;
36         e = spawn();
37         e.classname = "ons_ray";
38         setmodel(e, MDL_ONS_RAY);
39         setorigin(e, org);
40         e.angles = randomvec() * 360;
41         e.move_origin = org;
42         e.movetype = MOVETYPE_NONE;
43         e.alpha = 0;
44         e.scale = random() * 5 + 8;
45         e.move_time = time + 0.05;
46         e.drawmask = MASK_NORMAL;
47         e.draw = ons_generator_ray_draw;
48 }
49
50 void generator_draw(entity this)
51 {
52         if(time < self.move_time)
53                 return;
54
55         if(self.health > 0)
56         {
57                 // damaged fx (less probable the more damaged is the generator)
58                 if(random() < 0.9 - self.health / self.max_health)
59                 if(random() < 0.01)
60                 {
61                         pointparticles(particleeffectnum(EFFECT_ELECTRO_BALLEXPLODE), self.origin + randompos('-50 -50 -20', '50 50 50'), '0 0 0', 1);
62                         sound(self, CH_TRIGGER, SND_ONS_ELECTRICITY_EXPLODE, VOL_BASE, ATTEN_NORM);
63                 }
64                 else
65                         pointparticles(particleeffectnum(EFFECT_ONS_GENERATOR_DAMAGED), self.origin + randompos('-60 -60 -20', '60 60 60'), '0 0 0', 1);
66
67                 self.move_time = time + 0.1;
68
69                 return;
70         }
71
72         if(self.count <= 0)
73                 return;
74
75         vector org;
76         int i;
77
78         // White shockwave
79         if(self.count==40||self.count==20)
80         {
81                 sound(self, CH_TRIGGER, SND_ONS_SHOCKWAVE, VOL_BASE, ATTEN_NORM);
82                 pointparticles(particleeffectnum(EFFECT_ELECTRO_COMBO), self.origin, '0 0 0', 6);
83         }
84
85         // rays
86         if(random() > 0.25)
87         {
88                 ons_generator_ray_spawn(self.origin);
89         }
90
91         // Spawn fire balls
92         for(i=0;i < 10;++i)
93         {
94                 org = self.origin + randompos('-30 -30 -30' * i + '0 0 -20', '30 30 30' * i + '0 0 20');
95                 pointparticles(particleeffectnum(EFFECT_ONS_GENERATOR_GIB), org, '0 0 0', 1);
96         }
97
98         // Short explosion sound + small explosion
99         if(random() < 0.25)
100         {
101                 te_explosion(self.origin);
102                 sound(self, CH_TRIGGER, SND_GRENADE_IMPACT, VOL_BASE, ATTEN_NORM);
103         }
104
105         // Particles
106         org = self.origin + randompos(self.mins + '8 8 8', self.maxs + '-8 -8 -8');
107         pointparticles(particleeffectnum(EFFECT_ONS_GENERATOR_EXPLODE), org, '0 0 0', 1);
108
109         // Final explosion
110         if(self.count==1)
111         {
112                 org = self.origin;
113                 te_explosion(org);
114                 pointparticles(particleeffectnum(EFFECT_ONS_GENERATOR_EXPLODE2), org, '0 0 0', 1);
115                 sound(self, CH_TRIGGER, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
116         }
117
118         self.move_time = time + 0.05;
119
120         self.count -= 1;
121 }
122
123 void generator_damage(float hp)
124 {SELFPARAM();
125         if(hp <= 0)
126                 setmodel(self, MDL_ONS_GEN_DEAD);
127         else if(hp < self.max_health * 0.10)
128                 setmodel(self, MDL_ONS_GEN9);
129         else if(hp < self.max_health * 0.20)
130                 setmodel(self, MDL_ONS_GEN8);
131         else if(hp < self.max_health * 0.30)
132                 setmodel(self, MDL_ONS_GEN7);
133         else if(hp < self.max_health * 0.40)
134                 setmodel(self, MDL_ONS_GEN6);
135         else if(hp < self.max_health * 0.50)
136                 setmodel(self, MDL_ONS_GEN5);
137         else if(hp < self.max_health * 0.60)
138                 setmodel(self, MDL_ONS_GEN4);
139         else if(hp < self.max_health * 0.70)
140                 setmodel(self, MDL_ONS_GEN3);
141         else if(hp < self.max_health * 0.80)
142                 setmodel(self, MDL_ONS_GEN2);
143         else if(hp < self.max_health * 0.90)
144                 setmodel(self, MDL_ONS_GEN1);
145         else if(hp <= self.max_health || hp >= self.max_health)
146                 setmodel(self, MDL_ONS_GEN);
147
148         setsize(self, GENERATOR_MIN, GENERATOR_MAX);
149 }
150
151 void generator_construct()
152 {SELFPARAM();
153         self.netname = "Generator";
154         self.classname = "onslaught_generator";
155
156         setorigin(self, self.origin);
157         setmodel(self, MDL_ONS_GEN);
158         setsize(self, GENERATOR_MIN, GENERATOR_MAX);
159
160         self.move_movetype      = MOVETYPE_NOCLIP;
161         self.solid                      = SOLID_BBOX;
162         self.movetype           = MOVETYPE_NOCLIP;
163         self.move_origin        = self.origin;
164         self.move_time          = time;
165         self.drawmask           = MASK_NORMAL;
166         self.alpha                      = 1;
167         self.draw                       = generator_draw;
168 }
169
170 .vector glowmod;
171 void generator_changeteam()
172 {SELFPARAM();
173         if(self.team)
174         {
175                 self.glowmod = Team_ColorRGB(self.team - 1);
176                 self.teamradar_color = Team_ColorRGB(self.team - 1);
177                 self.colormap = 1024 + (self.team - 1) * 17;
178         }
179         else
180         {
181                 self.colormap = 1024;
182                 self.glowmod = '1 1 0';
183                 self.teamradar_color = '1 1 0';
184         }
185 }
186
187 void ent_generator()
188 {SELFPARAM();
189         int sf = ReadByte();
190
191         if(sf & GSF_SETUP)
192         {
193                 self.origin_x = ReadCoord();
194                 self.origin_y = ReadCoord();
195                 self.origin_z = ReadCoord();
196                 setorigin(self, self.origin);
197
198                 self.health = ReadByte();
199                 self.max_health = ReadByte();
200                 self.count = ReadByte();
201                 self.team = ReadByte();
202
203                 if(!self.count)
204                         self.count = 40;
205
206                 generator_changeteam();
207                 generator_construct();
208         }
209
210         if(sf & GSF_STATUS)
211         {
212                 int _tmp;
213                 _tmp = ReadByte();
214                 if(_tmp != self.team)
215                 {
216                         self.team = _tmp;
217                         generator_changeteam();
218                 }
219
220                 _tmp = ReadByte();
221
222                 if(_tmp != self.health)
223                         generator_damage(_tmp);
224
225                 self.health = _tmp;
226         }
227 }