+
+ if (cl_particles_explosions_shell.integer)
+ R_NewExplosion(org);
+}
+
+/*
+===============
+CL_ParticleExplosion2
+
+===============
+*/
+void CL_ParticleExplosion2 (const vec3_t org, int colorStart, int colorLength)
+{
+ int i, k;
+ if (!cl_particles.integer) return;
+
+ for (i = 0;i < 512 * cl_particles_quality.value;i++)
+ {
+ k = particlepalette[colorStart + (i % colorLength)];
+ if (cl_particles_quake.integer)
+ CL_NewParticle(pt_alphastatic, k, k, tex_particle, 1, 0, 255, 0, 0, 0, org[0], org[1], org[2], 0, 0, 0, -4, -4, 16, 256, true, 0.3);
+ else
+ CL_NewParticle(pt_alphastatic, k, k, tex_particle, lhrandom(0.5, 1.5), 0, 255, 512, 0, 0, org[0], org[1], org[2], 0, 0, 0, lhrandom(1.5, 3), lhrandom(1.5, 3), 8, 192, true, 0);
+ }
+}
+
+static void CL_Sparks(const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, float sparkcount)
+{
+ if (cl_particles_sparks.integer)
+ {
+ sparkcount *= cl_particles_quality.value;
+ while(sparkcount-- > 0)
+ CL_NewParticle(pt_spark, particlepalette[0x68], particlepalette[0x6f], tex_particle, 0.5f, 0, lhrandom(64, 255), 512, 1, 0, lhrandom(originmins[0], originmaxs[0]), lhrandom(originmins[1], originmaxs[1]), lhrandom(originmins[2], originmaxs[2]), lhrandom(velocitymins[0], velocitymaxs[0]), lhrandom(velocitymins[1], velocitymaxs[1]), lhrandom(velocitymins[2], velocitymaxs[2]) + cl.movevars_gravity * 0.1f, 0, 0, 0, 64, true, 0);
+ }
+}
+
+static void CL_Smoke(const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, float smokecount)
+{
+ if (cl_particles_smoke.integer)
+ {
+ smokecount *= cl_particles_quality.value;
+ while(smokecount-- > 0)
+ CL_NewParticle(pt_smoke, 0x101010, 0x101010, tex_smoke[rand()&7], 2, 2, 255, 256, 0, 0, lhrandom(originmins[0], originmaxs[0]), lhrandom(originmins[1], originmaxs[1]), lhrandom(originmins[2], originmaxs[2]), lhrandom(velocitymins[0], velocitymaxs[0]), lhrandom(velocitymins[1], velocitymaxs[1]), lhrandom(velocitymins[2], velocitymaxs[2]), 0, 0, 0, smokecount > 0 ? 16 : 0, true, 0);
+ }
+}
+
+void CL_ParticleCube (const vec3_t mins, const vec3_t maxs, const vec3_t dir, int count, int colorbase, vec_t gravity, vec_t randomvel)
+{
+ int k;
+ if (!cl_particles.integer) return;
+
+ count = (int)(count * cl_particles_quality.value);
+ while (count--)
+ {
+ k = particlepalette[colorbase + (rand()&3)];
+ CL_NewParticle(pt_alphastatic, k, k, tex_particle, 2, 0, 255, 128, gravity, 0, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(mins[2], maxs[2]), dir[0], dir[1], dir[2], 0, 0, 0, randomvel, true, 0);
+ }
+}
+
+void CL_ParticleRain (const vec3_t mins, const vec3_t maxs, const vec3_t dir, int count, int colorbase, int type)
+{
+ int k;
+ float minz, maxz, lifetime = 30;
+ if (!cl_particles.integer) return;
+ if (dir[2] < 0) // falling
+ {
+ minz = maxs[2] + dir[2] * 0.1;
+ maxz = maxs[2];
+ if (cl.worldmodel)
+ lifetime = (maxz - cl.worldmodel->normalmins[2]) / max(1, -dir[2]);
+ }
+ else // rising??
+ {
+ minz = mins[2];
+ maxz = maxs[2] + dir[2] * 0.1;
+ if (cl.worldmodel)
+ lifetime = (cl.worldmodel->normalmaxs[2] - minz) / max(1, dir[2]);
+ }
+
+ count = (int)(count * cl_particles_quality.value);
+
+ switch(type)
+ {
+ case 0:
+ if (!cl_particles_rain.integer) break;
+ count *= 4; // ick, this should be in the mod or maps?
+
+ while(count--)
+ {
+ k = particlepalette[colorbase + (rand()&3)];
+ if (gamemode == GAME_GOODVSBAD2)
+ CL_NewParticle(pt_rain, k, k, tex_particle, 20, 0, lhrandom(32, 64), 0, 0, -1, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(minz, maxz), dir[0], dir[1], dir[2], 0, 0, 0, 0, true, lifetime);
+ else
+ CL_NewParticle(pt_rain, k, k, tex_particle, 0.5, 0, lhrandom(32, 64), 0, 0, -1, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(minz, maxz), dir[0], dir[1], dir[2], 0, 0, 0, 0, true, lifetime);
+ }
+ break;
+ case 1:
+ if (!cl_particles_snow.integer) break;
+ while(count--)
+ {
+ k = particlepalette[colorbase + (rand()&3)];
+ if (gamemode == GAME_GOODVSBAD2)
+ CL_NewParticle(pt_snow, k, k, tex_particle, 20, 0, lhrandom(64, 128), 0, 0, -1, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(minz, maxz), dir[0], dir[1], dir[2], 0, 0, 0, 0, true, lifetime);
+ else
+ CL_NewParticle(pt_snow, k, k, tex_particle, 1, 0, lhrandom(64, 128), 0, 0, -1, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(minz, maxz), dir[0], dir[1], dir[2], 0, 0, 0, 0, true, lifetime);
+ }
+ break;
+ default:
+ Con_Printf ("CL_ParticleRain: unknown type %i (0 = rain, 1 = snow)\n", type);
+ }