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