1 #include "particles.qh"
3 #include "../common/util.qh"
4 #include "autocvars.qh"
5 #include "bgmscript.qh"
7 #include "../common/stats.qh"
8 #include "../warpzonelib/common.qh"
10 void Draw_PointParticles()
17 sz = self.maxs - self.mins;
19 if(self.absolute == 2)
22 n = self.just_toggled ? self.impulse : 0;
24 n = self.impulse * drawframetime;
28 n *= self.impulse * drawframetime;
36 for(i = random(); i <= n && fail <= 64*n; ++i)
39 p.x += random() * sz.x;
40 p.y += random() * sz.y;
41 p.z += random() * sz.z;
42 if(WarpZoneLib_BoxTouchesBrush(p, p, self, world))
44 if(self.movedir != '0 0 0')
46 traceline(p, p + normalize(self.movedir) * 4096, 0, world);
48 pointparticles(self.cnt, p, trace_plane_normal * vlen(self.movedir) + self.velocity + randomvec() * self.waterlevel, self.count);
52 pointparticles(self.cnt, p, self.velocity + randomvec() * self.waterlevel, self.count);
57 sound(self, CH_AMBIENT, self.noise, VOL_BASE * self.volume, self.atten);
59 self.just_toggled = 0;
61 else if(self.absolute)
70 void Ent_PointParticles_Remove()
73 strunzone(self.noise);
74 self.noise = string_null;
76 strunzone(self.bgmscript);
77 self.bgmscript = string_null;
80 void Ent_PointParticles()
87 i = ReadCoord(); // density (<0: point, >0: volume)
88 if(i && !self.impulse && self.cnt) // self.cnt check is so it only happens if the ent already existed
89 self.just_toggled = 1;
94 self.origin_x = ReadCoord();
95 self.origin_y = ReadCoord();
96 self.origin_z = ReadCoord();
100 self.modelindex = ReadShort();
105 self.mins_x = ReadCoord();
106 self.mins_y = ReadCoord();
107 self.mins_z = ReadCoord();
108 self.maxs_x = ReadCoord();
109 self.maxs_y = ReadCoord();
110 self.maxs_z = ReadCoord();
115 self.maxs_x = ReadCoord();
116 self.maxs_y = ReadCoord();
117 self.maxs_z = ReadCoord();
122 self.mins = self.maxs = '0 0 0';
125 self.cnt = ReadShort(); // effect number
129 self.velocity = decompressShortVector(ReadShort());
130 self.movedir = decompressShortVector(ReadShort());
134 self.velocity = self.movedir = '0 0 0';
138 self.waterlevel = ReadShort() / 16.0;
139 self.count = ReadByte() / 16.0;
147 strunzone(self.noise);
149 strunzone(self.bgmscript);
150 self.noise = strzone(ReadString());
153 self.atten = ReadByte() / 64.0;
154 self.volume = ReadByte() / 255.0;
156 self.bgmscript = strzone(ReadString());
157 if(self.bgmscript != "")
159 self.bgmscriptattack = ReadByte() / 64.0;
160 self.bgmscriptdecay = ReadByte() / 64.0;
161 self.bgmscriptsustain = ReadByte() / 255.0;
162 self.bgmscriptrelease = ReadByte() / 64.0;
164 BGMScript_InitEntity(self);
169 self.absolute = (self.impulse >= 0);
172 v = self.maxs - self.mins;
173 self.impulse *= -v.x * v.y * v.z / 262144; // relative: particles per 64^3 cube
180 setorigin(self, self.origin);
181 setsize(self, self.mins, self.maxs);
182 self.solid = SOLID_NOT;
183 self.draw = Draw_PointParticles;
184 self.entremove = Ent_PointParticles_Remove;
189 te_particlerain(self.origin + self.mins, self.origin + self.maxs, self.velocity, floor(self.count * drawframetime + random()), self.glow_color);
194 te_particlesnow(self.origin + self.mins, self.origin + self.maxs, self.velocity, floor(self.count * drawframetime + random()), self.glow_color);
197 void Ent_RainOrSnow()
199 self.impulse = ReadByte(); // Rain, Snow, or Whatever
200 self.origin_x = ReadCoord();
201 self.origin_y = ReadCoord();
202 self.origin_z = ReadCoord();
203 self.maxs_x = ReadCoord();
204 self.maxs_y = ReadCoord();
205 self.maxs_z = ReadCoord();
206 self.velocity = decompressShortVector(ReadShort());
207 self.count = ReadShort() * 10;
208 self.glow_color = ReadByte(); // color
210 self.mins = -0.5 * self.maxs;
211 self.maxs = 0.5 * self.maxs;
212 self.origin = self.origin - self.mins;
214 setorigin(self, self.origin);
215 setsize(self, self.mins, self.maxs);
216 self.solid = SOLID_NOT;
218 self.draw = Draw_Rain;
220 self.draw = Draw_Snow;
223 void Net_ReadVortexBeamParticle()
225 vector shotorg, endpos;
227 shotorg.x = ReadCoord(); shotorg.y = ReadCoord(); shotorg.z = ReadCoord();
228 endpos.x = ReadCoord(); endpos.y = ReadCoord(); endpos.z = ReadCoord();
229 charge = ReadByte() / 255.0;
231 pointparticles(particleeffectnum("nex_muzzleflash"), shotorg, normalize(endpos - shotorg) * 1000, 1);
233 //draw either the old v2.3 beam or the new beam
234 charge = sqrt(charge); // divide evenly among trail spacing and alpha
235 particles_alphamin = particles_alphamax = particles_fade = charge;
237 if (autocvar_cl_particles_oldvortexbeam && (getstati(STAT_ALLOW_OLDVORTEXBEAM) || isdemo()))
238 WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum("TE_TEI_G3"), shotorg, endpos, 1, PARTICLES_USEALPHA | PARTICLES_USEFADE);
240 WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum("nex_beam"), shotorg, endpos, 1, PARTICLES_USEALPHA | PARTICLES_USEFADE);