03e81f4bdea092deee9f965d104cf4f3d4c8f2af
[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                 remove(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         e.move_origin = org;
37         e.movetype = MOVETYPE_NONE;
38         e.alpha = 0;
39         e.scale = random() * 5 + 8;
40         e.move_time = time + 0.05;
41         e.drawmask = MASK_NORMAL;
42         e.draw = ons_generator_ray_draw;
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)
147 {
148         this.netname = "Generator";
149         this.classname = "onslaught_generator";
150
151         setorigin(this, this.origin);
152         setmodel(this, MDL_ONS_GEN);
153         setsize(this, GENERATOR_MIN, GENERATOR_MAX);
154
155         this.move_movetype      = MOVETYPE_NOCLIP;
156         this.solid                      = SOLID_BBOX;
157         this.movetype           = MOVETYPE_NOCLIP;
158         this.move_origin        = this.origin;
159         this.move_time          = time;
160         this.drawmask           = MASK_NORMAL;
161         this.alpha                      = 1;
162         this.draw                       = generator_draw;
163 }
164
165 .vector glowmod;
166 void generator_changeteam(entity this)
167 {
168         if(this.team)
169         {
170                 this.glowmod = Team_ColorRGB(this.team - 1);
171                 this.teamradar_color = Team_ColorRGB(this.team - 1);
172                 this.colormap = 1024 + (this.team - 1) * 17;
173         }
174         else
175         {
176                 this.colormap = 1024;
177                 this.glowmod = '1 1 0';
178                 this.teamradar_color = '1 1 0';
179         }
180 }
181
182 NET_HANDLE(ENT_CLIENT_GENERATOR, bool isnew)
183 {
184         return = true;
185         int sf = ReadByte();
186
187         if(sf & GSF_SETUP)
188         {
189                 this.origin_x = ReadCoord();
190                 this.origin_y = ReadCoord();
191                 this.origin_z = ReadCoord();
192                 setorigin(this, this.origin);
193
194                 this.health = ReadByte();
195                 this.max_health = ReadByte();
196                 this.count = ReadByte();
197                 this.team = ReadByte();
198
199                 if(!this.count)
200                         this.count = 40;
201
202                 generator_changeteam(this);
203                 generator_construct(this);
204         }
205
206         if(sf & GSF_STATUS)
207         {
208                 int _tmp;
209                 _tmp = ReadByte();
210                 if(_tmp != this.team)
211                 {
212                         this.team = _tmp;
213                         generator_changeteam(this);
214                 }
215
216                 _tmp = ReadByte();
217
218                 if(_tmp != this.health)
219                         generator_damage(this, _tmp);
220
221                 this.health = _tmp;
222         }
223 }