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