]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/triggers/func/pointparticles.qc
Merge master into qc_physics_prehax (blame TimePath if it's completely broken)
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / triggers / func / pointparticles.qc
index 896bd796bb168ec7ccd52599c1861c9da0bd1395..9b32371dbeaa5af43a94e922bc179216d6f267c7 100644 (file)
@@ -1,3 +1,7 @@
+#ifdef CSQC
+       #include "../../../client/particles.qh"
+#endif
+
 #ifdef SVQC
 // NOTE: also contains func_sparks
 
@@ -177,4 +181,182 @@ void spawnfunc_func_sparks()
 
        spawnfunc_func_pointparticles();
 }
+#elif defined(CSQC)
+
+void Draw_PointParticles()
+{
+       float n, i, fail;
+       vector p;
+       vector sz;
+       vector o;
+       o = self.origin;
+       sz = self.maxs - self.mins;
+       n = doBGMScript(self);
+       if(self.absolute == 2)
+       {
+               if(n >= 0)
+                       n = self.just_toggled ? self.impulse : 0;
+               else
+                       n = self.impulse * drawframetime;
+       }
+       else
+       {
+               n *= self.impulse * drawframetime;
+               if(self.just_toggled)
+                       if(n < 1)
+                               n = 1;
+       }
+       if(n == 0)
+               return;
+       fail = 0;
+       for(i = random(); i <= n && fail <= 64*n; ++i)
+       {
+               p = o + self.mins;
+               p.x += random() * sz.x;
+               p.y += random() * sz.y;
+               p.z += random() * sz.z;
+               if(WarpZoneLib_BoxTouchesBrush(p, p, self, world))
+               {
+                       if(self.movedir != '0 0 0')
+                       {
+                               traceline(p, p + normalize(self.movedir) * 4096, 0, world);
+                               p = trace_endpos;
+                               pointparticles(self.cnt, p, trace_plane_normal * vlen(self.movedir) + self.velocity + randomvec() * self.waterlevel, self.count);
+                       }
+                       else
+                       {
+                               pointparticles(self.cnt, p, self.velocity + randomvec() * self.waterlevel, self.count);
+                       }
+                       if(self.noise != "")
+                       {
+                               setorigin(self, p);
+                               sound(self, CH_AMBIENT, self.noise, VOL_BASE * self.volume, self.atten);
+                       }
+                       self.just_toggled = 0;
+               }
+               else if(self.absolute)
+               {
+                       ++fail;
+                       --i;
+               }
+       }
+       setorigin(self, o);
+}
+
+void Ent_PointParticles_Remove()
+{
+       if(self.noise)
+               strunzone(self.noise);
+       self.noise = string_null;
+       if(self.bgmscript)
+               strunzone(self.bgmscript);
+       self.bgmscript = string_null;
+}
+
+void Ent_PointParticles()
+{
+       float i;
+       vector v;
+       int f = ReadByte();
+       if(f & 2)
+       {
+               i = ReadCoord(); // density (<0: point, >0: volume)
+               if(i && !self.impulse && self.cnt) // self.cnt check is so it only happens if the ent already existed
+                       self.just_toggled = 1;
+               self.impulse = i;
+       }
+       if(f & 4)
+       {
+               self.origin_x = ReadCoord();
+               self.origin_y = ReadCoord();
+               self.origin_z = ReadCoord();
+       }
+       if(f & 1)
+       {
+               self.modelindex = ReadShort();
+               if(f & 0x80)
+               {
+                       if(self.modelindex)
+                       {
+                               self.mins_x = ReadCoord();
+                               self.mins_y = ReadCoord();
+                               self.mins_z = ReadCoord();
+                               self.maxs_x = ReadCoord();
+                               self.maxs_y = ReadCoord();
+                               self.maxs_z = ReadCoord();
+                       }
+                       else
+                       {
+                               self.mins    = '0 0 0';
+                               self.maxs_x = ReadCoord();
+                               self.maxs_y = ReadCoord();
+                               self.maxs_z = ReadCoord();
+                       }
+               }
+               else
+               {
+                       self.mins = self.maxs = '0 0 0';
+               }
+
+               self.cnt = ReadShort(); // effect number
+
+               if(f & 0x20)
+               {
+                       self.velocity = decompressShortVector(ReadShort());
+                       self.movedir = decompressShortVector(ReadShort());
+               }
+               else
+               {
+                       self.velocity = self.movedir = '0 0 0';
+               }
+               if(f & 0x40)
+               {
+                       self.waterlevel = ReadShort() / 16.0;
+                       self.count = ReadByte() / 16.0;
+               }
+               else
+               {
+                       self.waterlevel = 0;
+                       self.count = 1;
+               }
+               if(self.noise)
+                       strunzone(self.noise);
+               if(self.bgmscript)
+                       strunzone(self.bgmscript);
+               self.noise = strzone(ReadString());
+               if(self.noise != "")
+               {
+                       self.atten = ReadByte() / 64.0;
+                       self.volume = ReadByte() / 255.0;
+               }
+               self.bgmscript = strzone(ReadString());
+               if(self.bgmscript != "")
+               {
+                       self.bgmscriptattack = ReadByte() / 64.0;
+                       self.bgmscriptdecay = ReadByte() / 64.0;
+                       self.bgmscriptsustain = ReadByte() / 255.0;
+                       self.bgmscriptrelease = ReadByte() / 64.0;
+               }
+               BGMScript_InitEntity(self);
+       }
+
+       if(f & 2)
+       {
+               self.absolute = (self.impulse >= 0);
+               if(!self.absolute)
+               {
+                       v = self.maxs - self.mins;
+                       self.impulse *= -v.x * v.y * v.z / 262144; // relative: particles per 64^3 cube
+               }
+       }
+
+       if(f & 0x10)
+               self.absolute = 2;
+
+       setorigin(self, self.origin);
+       setsize(self, self.mins, self.maxs);
+       self.solid = SOLID_NOT;
+       self.draw = Draw_PointParticles;
+       self.entremove = Ent_PointParticles_Remove;
+}
 #endif