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))
{
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
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)
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)
// 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];
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]);
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))
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--)
{
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);
}
/*
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);
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 );
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);
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
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)
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)