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