]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/gamemodes/gamemode/onslaught/cl_generator.qc
Merge branch 'master' into terencehill/CA_forbidspawn
[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                 IL_PUSH(g_onsgenerators, this);
153
154         setorigin(this, this.origin);
155         setmodel(this, MDL_ONS_GEN);
156         setsize(this, GENERATOR_MIN, GENERATOR_MAX);
157
158         set_movetype(this, MOVETYPE_NOCLIP);
159         this.solid                      = SOLID_BBOX;
160         set_movetype(this, MOVETYPE_NOCLIP);
161         this.move_time          = time;
162         this.drawmask           = MASK_NORMAL;
163         this.alpha                      = 1;
164         this.draw                       = generator_draw;
165 }
166
167 .vector glowmod;
168 void generator_changeteam(entity this)
169 {
170         if(this.team)
171         {
172                 this.glowmod = Team_ColorRGB(this.team - 1);
173                 this.teamradar_color = Team_ColorRGB(this.team - 1);
174                 this.colormap = 1024 + (this.team - 1) * 17;
175         }
176         else
177         {
178                 this.colormap = 1024;
179                 this.glowmod = '1 1 0';
180                 this.teamradar_color = '1 1 0';
181         }
182 }
183
184 NET_HANDLE(ENT_CLIENT_GENERATOR, bool isnew)
185 {
186         return = true;
187         int sf = ReadByte();
188
189         if(sf & GSF_SETUP)
190         {
191                 this.origin_x = ReadCoord();
192                 this.origin_y = ReadCoord();
193                 this.origin_z = ReadCoord();
194                 setorigin(this, this.origin);
195
196                 this.health = ReadByte();
197                 this.max_health = ReadByte();
198                 this.count = ReadByte();
199                 this.team = ReadByte();
200
201                 if(!this.count)
202                         this.count = 40;
203
204                 generator_changeteam(this);
205                 generator_construct(this, isnew);
206         }
207
208         if(sf & GSF_STATUS)
209         {
210                 int _tmp;
211                 _tmp = ReadByte();
212                 if(_tmp != this.team)
213                 {
214                         this.team = _tmp;
215                         generator_changeteam(this);
216                 }
217
218                 _tmp = ReadByte();
219
220                 if(_tmp != this.health)
221                         generator_damage(this, _tmp);
222
223                 this.health = _tmp;
224         }
225 }