]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/generator.qc
Merge branch 'master' into Mario/ons_updates
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / generator.qc
1 float generator_precached;
2 .float count;
3 .float max_health;
4
5 vector randompos(vector m1, vector m2)
6 {
7         vector v;
8         m2 = m2 - m1;
9         v_x = m2_x * random() + m1_x;
10         v_y = m2_y * random() + m1_y;
11         v_z = m2_z * random() + m1_z;
12         return  v;
13 }
14
15 void generator_precache()
16 {
17         if(generator_precached)
18                 return; // already precached
19
20         precache_model("models/onslaught/generator.md3");
21         precache_model("models/onslaught/generator_dead.md3");
22         precache_model("models/onslaught/generator_dmg1.md3");
23         precache_model("models/onslaught/generator_dmg2.md3");
24         precache_model("models/onslaught/generator_dmg3.md3");
25         precache_model("models/onslaught/generator_dmg4.md3");
26         precache_model("models/onslaught/generator_dmg5.md3");
27         precache_model("models/onslaught/generator_dmg6.md3");
28         precache_model("models/onslaught/generator_dmg7.md3");
29         precache_model("models/onslaught/generator_dmg8.md3");
30         precache_model("models/onslaught/generator_dmg9.md3");
31         precache_model("models/onslaught/generator_dead.md3");
32
33         precache_model("models/onslaught/ons_ray.md3");
34         precache_sound("onslaught/shockwave.wav");
35         precache_sound("weapons/grenade_impact.wav");
36         precache_sound("weapons/rocket_impact.wav");
37         precache_sound("onslaught/electricity_explode.wav");
38
39         generator_precached = TRUE;
40 }
41
42 void ons_generator_ray_draw()
43 {
44         if(time < self.move_time)
45                 return;
46         
47         self.move_time = time + 0.05;
48
49         if(self.count > 10)
50         {
51                 remove(self);
52                 return;
53         }
54
55         if(self.count > 5)
56                 self.alpha -= 0.1;
57         else
58                 self.alpha += 0.1;
59
60         self.scale += 0.2;
61         self.count +=1;
62 }
63
64 void ons_generator_ray_spawn(vector org)
65 {
66         entity e;
67         e = spawn();
68         e.classname = "ons_ray";
69         setmodel(e, "models/onslaught/ons_ray.md3");
70         setorigin(e, org);
71         e.angles = randomvec() * 360;
72         e.move_origin = org;
73         e.movetype = MOVETYPE_NONE;
74         e.alpha = 0;
75         e.scale = random() * 5 + 8;
76         e.move_time = time + 0.05;
77         e.drawmask = MASK_NORMAL;
78         e.draw = ons_generator_ray_draw;
79 }
80
81 void generator_draw()
82 {
83         if(time < self.move_time)
84                 return;
85
86         if(self.health > 0)
87         {
88                 // damaged fx (less probable the more damaged is the generator)
89                 if(random() < 0.9 - self.health / self.max_health)
90                 if(random() < 0.01)
91                 {
92                         pointparticles(particleeffectnum("electro_ballexplode"), self.origin + randompos('-50 -50 -20', '50 50 50'), '0 0 0', 1);
93                         sound(self, CH_TRIGGER, "onslaught/electricity_explode.wav", VOL_BASE, ATTEN_NORM);
94                 }
95                 else
96                         pointparticles(particleeffectnum("torch_small"), self.origin + randompos('-60 -60 -20', '60 60 60'), '0 0 0', 1);
97         
98                 self.move_time = time + 0.1;
99                 
100                 return;
101         }
102
103         if(self.count <= 0)
104                 return;
105
106         vector org;
107         float i;
108
109         // White shockwave
110         if(self.count==40||self.count==20)
111         {
112                 sound(self, CH_TRIGGER, "onslaught/shockwave.wav", VOL_BASE, ATTEN_NORM);
113                 pointparticles(particleeffectnum("electro_combo"), self.origin, '0 0 0', 6);
114         }
115         
116         // rays
117         if(random() > 0.25)
118         {
119                 ons_generator_ray_spawn(self.origin);
120         }
121
122         // Spawn fire balls
123         for(i=0;i < 10;++i)
124         {
125                 org = self.origin + randompos('-30 -30 -30' * i + '0 0 -20', '30 30 30' * i + '0 0 20');
126                 pointparticles(particleeffectnum("onslaught_generator_gib_explode"), org, '0 0 0', 1);
127         }
128
129         // Short explosion sound + small explosion
130         if(random() < 0.25)
131         {
132                 te_explosion(self.origin);
133                 sound(self, CH_TRIGGER, "weapons/grenade_impact.wav", VOL_BASE, ATTEN_NORM);
134         }
135
136         // Particles
137         org = self.origin + randompos(self.mins + '8 8 8', self.maxs + '-8 -8 -8');
138         pointparticles(particleeffectnum("onslaught_generator_smallexplosion"), org, '0 0 0', 1);
139
140         // Final explosion
141         if(self.count==1)
142         {
143                 org = self.origin;
144                 te_explosion(org);
145                 pointparticles(particleeffectnum("onslaught_generator_finalexplosion"), org, '0 0 0', 1);
146                 sound(self, CH_TRIGGER, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
147         }
148
149         self.move_time = time + 0.05;
150
151         self.count -= 1;
152 }
153
154 void generator_damage(float hp)
155 {
156         if(hp <= 0)
157                 setmodel(self, "models/onslaught/generator_dead.md3");
158         else if(hp < self.max_health * 0.10)
159                 setmodel(self, "models/onslaught/generator_dmg9.md3");
160         else if(hp < self.max_health * 0.20)
161                 setmodel(self, "models/onslaught/generator_dmg8.md3");
162         else if(hp < self.max_health * 0.30)
163                 setmodel(self, "models/onslaught/generator_dmg7.md3");
164         else if(hp < self.max_health * 0.40)
165                 setmodel(self, "models/onslaught/generator_dmg6.md3");
166         else if(hp < self.max_health * 0.50)
167                 setmodel(self, "models/onslaught/generator_dmg5.md3");
168         else if(hp < self.max_health * 0.60)
169                 setmodel(self, "models/onslaught/generator_dmg4.md3");
170         else if(hp < self.max_health * 0.70)
171                 setmodel(self, "models/onslaught/generator_dmg3.md3");
172         else if(hp < self.max_health * 0.80)
173                 setmodel(self, "models/onslaught/generator_dmg2.md3");
174         else if(hp < self.max_health * 0.90)
175                 setmodel(self, "models/onslaught/generator_dmg1.md3");
176         else if(hp <= self.max_health || hp >= self.max_health)
177                 setmodel(self, "models/onslaught/generator.md3");
178
179         setsize(self, GENERATOR_MIN, GENERATOR_MAX);
180 }
181
182 void generator_construct()
183 {
184         self.netname = "Generator";
185         self.classname = "onslaught_generator";
186
187         setorigin(self, self.origin);
188         setmodel(self, "models/onslaught/generator.md3");
189         setsize(self, GENERATOR_MIN, GENERATOR_MAX);
190
191         self.move_movetype      = MOVETYPE_NOCLIP;
192         self.solid                      = SOLID_BBOX;
193         self.movetype           = MOVETYPE_NOCLIP;
194         self.move_origin        = self.origin;
195         self.move_time          = time;
196         self.drawmask           = MASK_NORMAL;
197         self.alpha                      = 1;
198         self.draw                       = generator_draw;
199 }
200
201 .vector glowmod;
202 void generator_changeteam()
203 {
204         if(self.team)
205         {
206                 self.glowmod = Team_ColorRGB(self.team - 1);
207                 self.teamradar_color = Team_ColorRGB(self.team - 1);
208                 self.colormap = 1024 + (self.team - 1) * 17;
209         }
210         else
211         {
212                 self.colormap = 1024;
213                 self.glowmod = '1 1 0';
214                 self.teamradar_color = '1 1 0';
215         }
216 }
217
218 void ent_generator()
219 {
220         float sf;
221         sf = ReadByte();
222
223         if(sf & GSF_SETUP)
224         {
225                 self.origin_x = ReadCoord();
226                 self.origin_y = ReadCoord();
227                 self.origin_z = ReadCoord();
228                 setorigin(self, self.origin);
229
230                 self.health = ReadByte();
231                 self.max_health = ReadByte();
232                 self.count = ReadByte();
233                 self.team = ReadByte();
234
235                 if(!self.count)
236                         self.count = 40;
237
238                 generator_changeteam();
239                 generator_precache();
240                 generator_construct();
241         }
242
243         if(sf & GSF_STATUS)
244         {
245                 float _tmp;
246                 _tmp = ReadByte();
247                 if(_tmp != self.team)
248                 {
249                         self.team = _tmp;
250                         generator_changeteam();
251                 }
252
253                 _tmp = ReadByte();
254
255                 if(_tmp != self.health)
256                         generator_damage(_tmp);
257
258                 self.health = _tmp;
259         }
260 }