]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_particles.c
Fix sv_jumpstep cvar, whose behavior was completely inverted (jump stepping worked...
[xonotic/darkplaces.git] / cl_particles.c
index 853c25e20afd58315ff0f97815ae20e02c11d798..83639adedf9c760405f56d974c666768cbba48d1 100644 (file)
@@ -44,6 +44,7 @@ particletype_t particletype[pt_total] =
 
 #define PARTICLEEFFECT_UNDERWATER 1
 #define PARTICLEEFFECT_NOTUNDERWATER 2
+#define PARTICLEEFFECT_DEFINED 2147483648U
 
 typedef struct particleeffectinfo_s
 {
@@ -296,6 +297,7 @@ cvar_t cl_particles_sparks = {CVAR_SAVE, "cl_particles_sparks", "1", "enables sp
 cvar_t cl_particles_bubbles = {CVAR_SAVE, "cl_particles_bubbles", "1", "enables bubbles (used by multiple effects)"};
 cvar_t cl_particles_visculling = {CVAR_SAVE, "cl_particles_visculling", "0", "perform a costly check if each particle is visible before drawing"};
 cvar_t cl_particles_collisions = {CVAR_SAVE, "cl_particles_collisions", "1", "allow costly collision detection on particles (sparks that bounce, particles not going through walls, blood hitting surfaces, etc)"};
+cvar_t cl_particles_forcetraileffects = {0, "cl_particles_forcetraileffects", "0", "force trails to be displayed even if a non-trail draw primitive was used (debug/compat feature)"};
 cvar_t cl_decals = {CVAR_SAVE, "cl_decals", "1", "enables decals (bullet holes, blood, etc)"};
 cvar_t cl_decals_visculling = {CVAR_SAVE, "cl_decals_visculling", "1", "perform a very cheap check if each decal is visible before drawing"};
 cvar_t cl_decals_time = {CVAR_SAVE, "cl_decals_time", "20", "how long before decals start to fade away"};
@@ -313,6 +315,7 @@ static void CL_Particles_ParseEffectInfo(const char *textstart, const char *text
 {
        int arrayindex;
        int argc;
+       int i;
        int linenumber;
        particleeffectinfo_t *info = NULL;
        const char *text = textstart;
@@ -370,17 +373,29 @@ static void CL_Particles_ParseEffectInfo(const char *textstart, const char *text
                                Con_Printf("%s:%i: too many effects!\n", filename, linenumber);
                                break;
                        }
+                       for(i = 0; i < numparticleeffectinfo; ++i)
+                       {
+                               info = particleeffectinfo + i;
+                               if(!(info->flags & PARTICLEEFFECT_DEFINED))
+                                       if(info->effectnameindex == effectnameindex)
+                                               break;
+                       }
+                       if(i < numparticleeffectinfo)
+                               continue;
                        info = particleeffectinfo + numparticleeffectinfo++;
                        // copy entire info from baseline, then fix up the nameindex
                        *info = baselineparticleeffectinfo;
                        info->effectnameindex = effectnameindex;
+                       continue;
                }
                else if (info == NULL)
                {
                        Con_Printf("%s:%i: command %s encountered before effect\n", filename, linenumber, argv[0]);
                        break;
                }
-               else if (!strcmp(argv[0], "countabsolute")) {readfloat(info->countabsolute);}
+
+               info->flags |= PARTICLEEFFECT_DEFINED;
+               if (!strcmp(argv[0], "countabsolute")) {readfloat(info->countabsolute);}
                else if (!strcmp(argv[0], "count")) {readfloat(info->countmultiplier);}
                else if (!strcmp(argv[0], "type"))
                {
@@ -595,6 +610,7 @@ void CL_Particles_Init (void)
        Cvar_RegisterVariable (&cl_particles_bubbles);
        Cvar_RegisterVariable (&cl_particles_visculling);
        Cvar_RegisterVariable (&cl_particles_collisions);
+       Cvar_RegisterVariable (&cl_particles_forcetraileffects);
        Cvar_RegisterVariable (&cl_decals);
        Cvar_RegisterVariable (&cl_decals_visculling);
        Cvar_RegisterVariable (&cl_decals_time);
@@ -914,11 +930,13 @@ void CL_SpawnDecalParticleForPoint(const vec3_t org, float maxdist, float size,
 
 static void CL_Sparks(const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, float sparkcount);
 static void CL_Smoke(const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, float smokecount);
-static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qboolean spawndlight, qboolean spawnparticles)
+static void CL_NewParticlesFromEffectinfo(int effectnameindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qboolean spawndlight, qboolean spawnparticles, float tintmins[4], float tintmaxs[4], float fade, qboolean wanttrail);
+static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qboolean spawndlight, qboolean spawnparticles, qboolean wanttrail)
 {
        vec3_t center;
        matrix4x4_t tempmatrix;
        particle_t *part;
+
        VectorLerp(originmins, 0.5, originmaxs, center);
        Matrix4x4_CreateTranslate(&tempmatrix, center[0], center[1], center[2]);
        if (effectnameindex == EFFECT_SVC_PARTICLE)
@@ -927,9 +945,9 @@ static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const v
                {
                        // bloodhack checks if this effect's color matches regular or lightning blood and if so spawns a blood effect instead
                        if (count == 1024)
-                               CL_ParticleEffect(EFFECT_TE_EXPLOSION, 1, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0);
+                               CL_NewParticlesFromEffectinfo(EFFECT_TE_EXPLOSION, 1, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
                        else if (cl_particles_blood_bloodhack.integer && !cl_particles_quake.integer && (palettecolor == 73 || palettecolor == 225))
-                               CL_ParticleEffect(EFFECT_TE_BLOOD, count / 2.0f, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0);
+                               CL_NewParticlesFromEffectinfo(EFFECT_TE_BLOOD, count / 2.0f, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
                        else
                        {
                                count *= cl_particles_quality.value;
@@ -942,9 +960,9 @@ static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const v
                }
        }
        else if (effectnameindex == EFFECT_TE_WIZSPIKE)
-               CL_ParticleEffect(EFFECT_SVC_PARTICLE, 30*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 20);
+               CL_NewParticlesFromEffectinfo(EFFECT_SVC_PARTICLE, 30*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 20, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
        else if (effectnameindex == EFFECT_TE_KNIGHTSPIKE)
-               CL_ParticleEffect(EFFECT_SVC_PARTICLE, 20*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 226);
+               CL_NewParticlesFromEffectinfo(EFFECT_SVC_PARTICLE, 20*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 226, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
        else if (effectnameindex == EFFECT_TE_SPIKE)
        {
                if (cl_particles_bulletimpacts.integer)
@@ -952,7 +970,7 @@ static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const v
                        if (cl_particles_quake.integer)
                        {
                                if (cl_particles_smoke.integer)
-                                       CL_ParticleEffect(EFFECT_SVC_PARTICLE, 10*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0);
+                                       CL_NewParticlesFromEffectinfo(EFFECT_SVC_PARTICLE, 10*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
                        }
                        else
                        {
@@ -972,7 +990,7 @@ static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const v
                        if (cl_particles_quake.integer)
                        {
                                if (cl_particles_smoke.integer)
-                                       CL_ParticleEffect(EFFECT_SVC_PARTICLE, 10*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0);
+                                       CL_NewParticlesFromEffectinfo(EFFECT_SVC_PARTICLE, 10*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
                        }
                        else
                        {
@@ -993,7 +1011,7 @@ static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const v
                        if (cl_particles_quake.integer)
                        {
                                if (cl_particles_smoke.integer)
-                                       CL_ParticleEffect(EFFECT_SVC_PARTICLE, 20*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0);
+                                       CL_NewParticlesFromEffectinfo(EFFECT_SVC_PARTICLE, 20*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
                        }
                        else
                        {
@@ -1013,7 +1031,7 @@ static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const v
                        if (cl_particles_quake.integer)
                        {
                                if (cl_particles_smoke.integer)
-                                       CL_ParticleEffect(EFFECT_SVC_PARTICLE, 20*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0);
+                                       CL_NewParticlesFromEffectinfo(EFFECT_SVC_PARTICLE, 20*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
                        }
                        else
                        {
@@ -1032,7 +1050,7 @@ static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const v
                if (!cl_particles_blood.integer)
                        return;
                if (cl_particles_quake.integer)
-                       CL_ParticleEffect(EFFECT_SVC_PARTICLE, 2*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 73);
+                       CL_NewParticlesFromEffectinfo(EFFECT_SVC_PARTICLE, 2*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 73, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
                else
                {
                        static double bloodaccumulator = 0;
@@ -1064,7 +1082,7 @@ static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const v
                if (cl_particles_bulletimpacts.integer)
                {
                        if (cl_particles_quake.integer)
-                               CL_ParticleEffect(EFFECT_SVC_PARTICLE, 20*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0);
+                               CL_NewParticlesFromEffectinfo(EFFECT_SVC_PARTICLE, 20*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
                        else
                        {
                                CL_Smoke(originmins, originmaxs, velocitymins, velocitymaxs, 4*count);
@@ -1081,7 +1099,7 @@ static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const v
                if (cl_particles_bulletimpacts.integer)
                {
                        if (cl_particles_quake.integer)
-                               CL_ParticleEffect(EFFECT_SVC_PARTICLE, 20*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0);
+                               CL_NewParticlesFromEffectinfo(EFFECT_SVC_PARTICLE, 20*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
                        else
                        {
                                CL_Smoke(originmins, originmaxs, velocitymins, velocitymaxs, 4*count);
@@ -1210,6 +1228,8 @@ static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const v
        }
        else if (effectnameindex == EFFECT_EF_FLAME)
        {
+               if (!spawnparticles)
+                       count = 0;
                count *= 300 * cl_particles_quality.value;
                while (count-- > 0)
                        CL_NewParticle(center, pt_smoke, 0x6f0f00, 0xe3974f, tex_particle, 4, 0, lhrandom(64, 128), 384, -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]), 1, 4, 16, 128, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
@@ -1217,6 +1237,8 @@ static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const v
        }
        else if (effectnameindex == EFFECT_EF_STARDUST)
        {
+               if (!spawnparticles)
+                       count = 0;
                count *= 200 * cl_particles_quality.value;
                while (count-- > 0)
                        CL_NewParticle(center, pt_static, 0x903010, 0xFFD030, tex_particle, 4, 0, lhrandom(64, 128), 128, 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]), 0.2, 0.8, 16, 128, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
@@ -1435,9 +1457,7 @@ static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const v
 
 // this is also called on point effects with spawndlight = true and
 // spawnparticles = true
-// it is called CL_ParticleTrail because most code does not want to supply
-// these parameters, only trail handling does
-void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qboolean spawndlight, qboolean spawnparticles, float tintmins[4], float tintmaxs[4])
+static void CL_NewParticlesFromEffectinfo(int effectnameindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qboolean spawndlight, qboolean spawnparticles, float tintmins[4], float tintmaxs[4], float fade, qboolean wanttrail)
 {
        qboolean found = false;
        char vabuf[1024];
@@ -1484,8 +1504,14 @@ void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins
                }
                for (effectinfoindex = 0, info = particleeffectinfo;effectinfoindex < MAX_PARTICLEEFFECTINFO && info->effectnameindex;effectinfoindex++, info++)
                {
-                       if (info->effectnameindex == effectnameindex)
+                       if ((info->effectnameindex == effectnameindex) && (info->flags & PARTICLEEFFECT_DEFINED))
                        {
+                               qboolean definedastrail = info->trailspacing > 0;
+
+                               qboolean drawastrail = wanttrail;
+                               if (cl_particles_forcetraileffects.integer)
+                                       drawastrail = drawastrail || definedastrail;
+
                                found = true;
                                if ((info->flags & PARTICLEEFFECT_UNDERWATER) && !underwater)
                                        continue;
@@ -1496,7 +1522,7 @@ void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins
                                if (info->lightradiusstart > 0 && spawndlight)
                                {
                                        matrix4x4_t tempmatrix;
-                                       if (info->trailspacing > 0)
+                                       if (drawastrail)
                                                Matrix4x4_CreateTranslate(&tempmatrix, originmaxs[0], originmaxs[1], originmaxs[2]);
                                        else
                                                Matrix4x4_CreateTranslate(&tempmatrix, center[0], center[1], center[2]);
@@ -1547,6 +1573,9 @@ void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins
                                }
                                else if (info->orientation == PARTICLE_HBEAM)
                                {
+                                       if (!drawastrail)
+                                               continue;
+
                                        AnglesFromVectors(angles, traildir, NULL, false);
                                        AngleVectors(angles, forward, right, up);
                                        VectorMAMAM(info->relativeoriginoffset[0], forward, info->relativeoriginoffset[1], right, info->relativeoriginoffset[2], up, trailpos);
@@ -1555,6 +1584,7 @@ void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins
                                }
                                else
                                {
+                                       float cnt;
                                        if (!cl_particles.integer)
                                                continue;
                                        switch (info->particletype)
@@ -1567,33 +1597,50 @@ void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins
                                        case pt_snow: if (!cl_particles_snow.integer) continue;break;
                                        default: break;
                                        }
-                                       VectorCopy(originmins, trailpos);
-                                       if (info->trailspacing > 0)
-                                       {
-                                               info->particleaccumulator += traillen / info->trailspacing * cl_particles_quality.value;
-                                               trailstep = info->trailspacing / cl_particles_quality.value;
-                                               immediatebloodstain = false;
 
-                                               AnglesFromVectors(angles, traildir, NULL, false);
-                                               AngleVectors(angles, forward, right, up);
-                                               VectorMAMAMAM(1.0f, trailpos, info->relativeoriginoffset[0], forward, info->relativeoriginoffset[1], right, info->relativeoriginoffset[2], up, trailpos);
-                                               VectorMAMAM(info->relativevelocityoffset[0], forward, info->relativevelocityoffset[1], right, info->relativevelocityoffset[2], up, velocity);
-                                       }
+                                       cnt = info->countabsolute;
+                                       cnt += (pcount * info->countmultiplier) * cl_particles_quality.value;
+                                       // if drawastrail is not set, we will
+                                       // use the regular cnt-based random
+                                       // particle spawning at the center; so
+                                       // do NOT apply trailspacing then!
+                                       if (drawastrail && definedastrail)
+                                               cnt += (traillen / info->trailspacing) * cl_particles_quality.value;
+                                       cnt *= fade;
+                                       if (cnt == 0)
+                                               continue;  // nothing to draw
+                                       info->particleaccumulator += cnt;
+
+                                       if (drawastrail || definedastrail)
+                                               immediatebloodstain = false;
                                        else
-                                       {
-                                               info->particleaccumulator += info->countabsolute + pcount * info->countmultiplier * cl_particles_quality.value;
-                                               trailstep = 0;
                                                immediatebloodstain =
                                                        ((cl_decals_newsystem_immediatebloodstain.integer >= 1) && (info->particletype == pt_blood))
                                                        ||
                                                        ((cl_decals_newsystem_immediatebloodstain.integer >= 2) && staintex);
 
+                                       if (drawastrail)
+                                       {
+                                               VectorCopy(originmins, trailpos);
+                                               trailstep = traillen / cnt;
+                                       }
+                                       else
+                                       {
+                                               VectorCopy(center, trailpos);
+                                               trailstep = 0;
+                                       }
+
+                                       if (trailstep == 0)
+                                       {
                                                VectorMAM(0.5f, velocitymins, 0.5f, velocitymaxs, velocity);
                                                AnglesFromVectors(angles, velocity, NULL, false);
-                                               AngleVectors(angles, forward, right, up);
-                                               VectorMAMAMAM(1.0f, trailpos, info->relativeoriginoffset[0], traildir, info->relativeoriginoffset[1], right, info->relativeoriginoffset[2], up, trailpos);
-                                               VectorMAMAM(info->relativevelocityoffset[0], traildir, info->relativevelocityoffset[1], right, info->relativevelocityoffset[2], up, velocity);
                                        }
+                                       else
+                                               AnglesFromVectors(angles, traildir, NULL, false);
+
+                                       AngleVectors(angles, forward, right, up);
+                                       VectorMAMAMAM(1.0f, trailpos, info->relativeoriginoffset[0], forward, info->relativeoriginoffset[1], right, info->relativeoriginoffset[2], up, trailpos);
+                                       VectorMAMAM(info->relativevelocityoffset[0], forward, info->relativevelocityoffset[1], right, info->relativevelocityoffset[2], up, velocity);
                                        info->particleaccumulator = bound(0, info->particleaccumulator, 16384);
                                        for (;info->particleaccumulator >= 1;info->particleaccumulator--)
                                        {
@@ -1602,7 +1649,7 @@ void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins
                                                        tex = (int)lhrandom(info->tex[0], info->tex[1]);
                                                        tex = min(tex, info->tex[1] - 1);
                                                }
-                                               if (!trailstep)
+                                               if (!(drawastrail || definedastrail))
                                                {
                                                        trailpos[0] = lhrandom(originmins[0], originmaxs[0]);
                                                        trailpos[1] = lhrandom(originmins[1], originmaxs[1]);
@@ -1628,12 +1675,23 @@ void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins
                }
        }
        if (!found)
-               CL_ParticleEffect_Fallback(effectnameindex, pcount, originmins, originmaxs, velocitymins, velocitymaxs, ent, palettecolor, spawndlight, spawnparticles);
+               CL_ParticleEffect_Fallback(effectnameindex, pcount, originmins, originmaxs, velocitymins, velocitymaxs, ent, palettecolor, spawndlight, spawnparticles, wanttrail);
+}
+
+void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qboolean spawndlight, qboolean spawnparticles, float tintmins[4], float tintmaxs[4], float fade)
+{
+       CL_NewParticlesFromEffectinfo(effectnameindex, pcount, originmins, originmaxs, velocitymins, velocitymaxs, ent, palettecolor, spawndlight, spawnparticles, tintmins, tintmaxs, fade, true);
 }
 
+void CL_ParticleBox(int effectnameindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qboolean spawndlight, qboolean spawnparticles, float tintmins[4], float tintmaxs[4], float fade)
+{
+       CL_NewParticlesFromEffectinfo(effectnameindex, pcount, originmins, originmaxs, velocitymins, velocitymaxs, ent, palettecolor, spawndlight, spawnparticles, tintmins, tintmaxs, fade, false);
+}
+
+// note: this one ONLY does boxes!
 void CL_ParticleEffect(int effectnameindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor)
 {
-       CL_ParticleTrail(effectnameindex, pcount, originmins, originmaxs, velocitymins, velocitymaxs, ent, palettecolor, true, true, NULL, NULL);
+       CL_ParticleBox(effectnameindex, pcount, originmins, originmaxs, velocitymins, velocitymaxs, ent, palettecolor, true, true, NULL, NULL, 1);
 }
 
 /*
@@ -1643,7 +1701,7 @@ CL_EntityParticles
 */
 void CL_EntityParticles (const entity_t *ent)
 {
-       int i;
+       int i, j;
        vec_t pitch, yaw, dist = 64, beamlength = 16;
        vec3_t org, v;
        static vec3_t avelocities[NUMVERTEXNORMALS];
@@ -1653,8 +1711,9 @@ void CL_EntityParticles (const entity_t *ent)
        Matrix4x4_OriginFromMatrix(&ent->render.matrix, org);
 
        if (!avelocities[0][0])
-               for (i = 0;i < NUMVERTEXNORMALS * 3;i++)
-                       avelocities[0][i] = lhrandom(0, 2.55);
+               for (i = 0;i < NUMVERTEXNORMALS;i++)
+                       for (j = 0;j < 3;j++)
+                               avelocities[i][j] = lhrandom(0, 2.55);
 
        for (i = 0;i < NUMVERTEXNORMALS;i++)
        {