Separate box and trail particles. Makes Xonotic's Nex beam possible again.
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 27 Jul 2013 10:24:22 +0000 (10:24 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 27 Jul 2013 10:24:22 +0000 (10:24 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11985 d7cf8633-e32d-0410-b094-e92efae38249

cl_main.c
cl_particles.c
client.h
clvm_cmds.c
prvm_offsets.h

index 76f2716..d50d4dd 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -1218,9 +1218,9 @@ static void CL_UpdateNetworkEntityTrail(entity_t *e)
                                CL_EntityParticles(e);
                }
                if (e->render.effects & EF_FLAME)
-                       CL_ParticleTrail(EFFECT_EF_FLAME, bound(0, cl.time - cl.oldtime, 0.1), origin, origin, vec3_origin, vec3_origin, NULL, 0, false, true, NULL, NULL);
+                       CL_ParticleTrail(EFFECT_EF_FLAME, bound(0, cl.time - cl.oldtime, 0.1), origin, origin, vec3_origin, vec3_origin, NULL, 0, false, true, NULL, NULL, 1);
                if (e->render.effects & EF_STARDUST)
-                       CL_ParticleTrail(EFFECT_EF_STARDUST, bound(0, cl.time - cl.oldtime, 0.1), origin, origin, vec3_origin, vec3_origin, NULL, 0, false, true, NULL, NULL);
+                       CL_ParticleTrail(EFFECT_EF_STARDUST, bound(0, cl.time - cl.oldtime, 0.1), origin, origin, vec3_origin, vec3_origin, NULL, 0, false, true, NULL, NULL, 1);
        }
        if (e->render.internaleffects & (INTEF_FLAG1QW | INTEF_FLAG2QW))
        {
@@ -1267,7 +1267,7 @@ static void CL_UpdateNetworkEntityTrail(entity_t *e)
                        len = 1.0f / len;
                VectorScale(vel, len, vel);
                // pass time as count so that trails that are time based (such as an emitter) will emit properly as long as they don't use trailspacing
-               CL_ParticleTrail(trailtype, bound(0, cl.time - cl.oldtime, 0.1), e->persistent.trail_origin, origin, vel, vel, e, e->state_current.glowcolor, false, true, NULL, NULL);
+               CL_ParticleTrail(trailtype, bound(0, cl.time - cl.oldtime, 0.1), e->persistent.trail_origin, origin, vel, vel, e, e->state_current.glowcolor, false, true, NULL, NULL, 1);
        }
        // now that the entity has survived one trail update it is allowed to
        // leave a real trail on later frames
@@ -1472,9 +1472,9 @@ static void CL_LinkNetworkEntity(entity_t *e)
                        dlightcolor[2] += 1.50f;
                }
                if (e->render.effects & EF_FLAME)
-                       CL_ParticleTrail(EFFECT_EF_FLAME, 1, origin, origin, vec3_origin, vec3_origin, NULL, 0, true, false, NULL, NULL);
+                       CL_ParticleTrail(EFFECT_EF_FLAME, 1, origin, origin, vec3_origin, vec3_origin, NULL, 0, true, false, NULL, NULL, 1);
                if (e->render.effects & EF_STARDUST)
-                       CL_ParticleTrail(EFFECT_EF_STARDUST, 1, origin, origin, vec3_origin, vec3_origin, NULL, 0, true, false, NULL, NULL);
+                       CL_ParticleTrail(EFFECT_EF_STARDUST, 1, origin, origin, vec3_origin, vec3_origin, NULL, 0, true, false, NULL, NULL, 1);
        }
        // muzzleflash fades over time, and is offset a bit
        if (e->persistent.muzzleflash > 0 && r_refdef.scene.numlights < MAX_DLIGHTS)
@@ -1556,7 +1556,7 @@ static void CL_LinkNetworkEntity(entity_t *e)
        if (e->state_current.traileffectnum)
                trailtype = (effectnameindex_t)e->state_current.traileffectnum;
        if (trailtype)
-               CL_ParticleTrail(trailtype, 1, origin, origin, vec3_origin, vec3_origin, NULL, e->state_current.glowcolor, true, false, NULL, NULL);
+               CL_ParticleTrail(trailtype, 1, origin, origin, vec3_origin, vec3_origin, NULL, e->state_current.glowcolor, true, false, NULL, NULL, 1);
 
        // don't show entities with no modelindex (note: this still shows
        // entities which have a modelindex that resolved to a NULL model)
index 941c638..e2e9ca0 100644 (file)
@@ -1442,7 +1442,7 @@ static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const v
 // 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 istrail)
 {
        qboolean found = false;
        char vabuf[1024];
@@ -1497,11 +1497,15 @@ void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins
                                if ((info->flags & PARTICLEEFFECT_NOTUNDERWATER) && underwater)
                                        continue;
 
+                               // if trailspacing is set, only ever use this effect as trail
+                               if (info->trailspacing > 0 && !istrail)
+                                       continue;
+
                                // spawn a dlight if requested
                                if (info->lightradiusstart > 0 && spawndlight)
                                {
                                        matrix4x4_t tempmatrix;
-                                       if (info->trailspacing > 0)
+                                       if (istrail)
                                                Matrix4x4_CreateTranslate(&tempmatrix, originmaxs[0], originmaxs[1], originmaxs[2]);
                                        else
                                                Matrix4x4_CreateTranslate(&tempmatrix, center[0], center[1], center[2]);
@@ -1573,20 +1577,25 @@ void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins
                                        default: break;
                                        }
                                        VectorCopy(originmins, trailpos);
-                                       if (info->trailspacing > 0)
+                                       if (istrail)
                                        {
-                                               info->particleaccumulator += traillen / info->trailspacing * cl_particles_quality.value;
-                                               trailstep = info->trailspacing / cl_particles_quality.value;
+                                               float cnt = info->countabsolute;
+                                               cnt += (pcount * info->countmultiplier) * cl_particles_quality.value;
+                                               if (info->trailspacing > 0)
+                                                       cnt += (traillen / info->trailspacing) * cl_particles_quality.value;
+                                               cnt *= fade;
+                                               info->particleaccumulator += cnt;
+                                               trailstep = traillen / cnt;
                                                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);
                                        }
                                        else
                                        {
-                                               info->particleaccumulator += info->countabsolute + pcount * info->countmultiplier * cl_particles_quality.value;
+                                               float cnt = info->countabsolute;
+                                               cnt += (pcount * info->countmultiplier) * cl_particles_quality.value;
+                                               cnt *= fade;
+                                               info->particleaccumulator += cnt;
                                                trailstep = 0;
                                                immediatebloodstain =
                                                        ((cl_decals_newsystem_immediatebloodstain.integer >= 1) && (info->particletype == pt_blood))
@@ -1595,10 +1604,10 @@ void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins
 
                                                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);
                                        }
+                                       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--)
                                        {
@@ -1636,9 +1645,19 @@ void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins
                CL_ParticleEffect_Fallback(effectnameindex, pcount, originmins, originmaxs, velocitymins, velocitymaxs, ent, palettecolor, spawndlight, spawnparticles);
 }
 
+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);
+}
+
 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);
 }
 
 /*
index 83b171c..f830c2e 100644 (file)
--- a/client.h
+++ b/client.h
@@ -1720,7 +1720,8 @@ effectnameindex_t;
 int CL_ParticleEffectIndexForName(const char *name);
 const char *CL_ParticleEffectNameForIndex(int i);
 void CL_ParticleEffect(int effectindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor);
-void CL_ParticleTrail(int effectindex, 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]);
+void CL_ParticleTrail(int effectindex, 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);
+void CL_ParticleBox(int effectindex, 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);
 void CL_ParseParticleEffect (void);
 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);
 void CL_ParticleRain (const vec3_t mins, const vec3_t maxs, const vec3_t dir, int count, int colorbase, int type);
index 6ca2749..c0cad22 100644 (file)
@@ -1364,10 +1364,13 @@ static void VM_CL_boxparticles (prvm_prog_t *prog)
        vec3_t origin_from, origin_to, dir_from, dir_to;
        float count;
        int flags;
-       float tintmins[4], tintmaxs[4];
+       qboolean istrail;
+       float tintmins[4], tintmaxs[4], fade;
        VM_SAFEPARMCOUNTRANGE(7, 8, VM_CL_boxparticles);
 
        effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
+       if (effectnum < 0)
+               return;
        // own = PRVM_G_EDICT(OFS_PARM1); // TODO find use for this
        VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin_from);
        VectorCopy(PRVM_G_VECTOR(OFS_PARM3), origin_to  );
@@ -1378,8 +1381,12 @@ static void VM_CL_boxparticles (prvm_prog_t *prog)
                flags = PRVM_G_FLOAT(OFS_PARM7);
        else
                flags = 0;
+
        Vector4Set(tintmins, 1, 1, 1, 1);
        Vector4Set(tintmaxs, 1, 1, 1, 1);
+       fade = 1;
+       istrail = false;
+
        if(flags & 1) // read alpha
        {
                tintmins[3] = PRVM_clientglobalfloat(particles_alphamin);
@@ -1390,9 +1397,19 @@ static void VM_CL_boxparticles (prvm_prog_t *prog)
                VectorCopy(PRVM_clientglobalvector(particles_colormin), tintmins);
                VectorCopy(PRVM_clientglobalvector(particles_colormax), tintmaxs);
        }
-       if (effectnum < 0)
-               return;
-       CL_ParticleTrail(effectnum, count, origin_from, origin_to, dir_from, dir_to, NULL, 0, true, true, tintmins, tintmaxs);
+       if(flags & 4) // read fade
+       {
+               fade = PRVM_clientglobalfloat(particles_fade);
+       }
+       if(flags & 128) // draw as trail
+       {
+               istrail = true;
+       }
+
+       if (istrail)
+               CL_ParticleTrail(effectnum, count, origin_from, origin_to, dir_from, dir_to, NULL, 0, true, true, tintmins, tintmaxs, fade);
+       else
+               CL_ParticleBox(effectnum, count, origin_from, origin_to, dir_from, dir_to, NULL, 0, true, true, tintmins, tintmaxs, fade);
 }
 
 //#531 void(float pause) setpause
index 440b3e4..c02bc07 100644 (file)
@@ -150,6 +150,7 @@ PRVM_DECLARE_clientglobalfloat(particle_type)
 PRVM_DECLARE_clientglobalfloat(particle_velocityjitter)
 PRVM_DECLARE_clientglobalfloat(particles_alphamax)
 PRVM_DECLARE_clientglobalfloat(particles_alphamin)
+PRVM_DECLARE_clientglobalfloat(particles_fade)
 PRVM_DECLARE_clientglobalfloat(player_localentnum)
 PRVM_DECLARE_clientglobalfloat(player_localnum)
 PRVM_DECLARE_clientglobalfloat(require_spawnfunc_prefix)
@@ -527,6 +528,7 @@ PRVM_DECLARE_global(particle_type)
 PRVM_DECLARE_global(particle_velocityjitter)
 PRVM_DECLARE_global(particles_alphamax)
 PRVM_DECLARE_global(particles_alphamin)
+PRVM_DECLARE_global(particles_fade)
 PRVM_DECLARE_global(particles_colormax)
 PRVM_DECLARE_global(particles_colormin)
 PRVM_DECLARE_global(player_localentnum)