X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=cl_particles.c;h=54f73efbfa433b54503afb5f646aedc20a3c2db2;hb=8367a30715017e7a497f6baf65dbaff5f72d6cf3;hp=e6d404e223516eb9aa19e8cf8a61b58775d69119;hpb=2e0f64a4030953216fc8a2ddb8edde7964446258;p=xonotic%2Fdarkplaces.git diff --git a/cl_particles.c b/cl_particles.c index e6d404e2..54f73efb 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -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 { @@ -314,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; @@ -371,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")) { @@ -758,7 +772,7 @@ particle_t *CL_NewParticle(const vec3_t sortorigin, unsigned short ptypeindex, i part->typeindex = pt_spark; part->bounce = 0; VectorMA(part->org, lifetime, part->vel, endvec); - trace = CL_TraceLine(part->org, endvec, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_LIQUIDSMASK, true, false, NULL, false, false); + trace = CL_TraceLine(part->org, endvec, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_LIQUIDSMASK, collision_extendmovelength.value, true, false, NULL, false, false); part->die = cl.time + lifetime * trace.fraction; part2 = CL_NewParticle(endvec, pt_raindecal, pcolor1, pcolor2, tex_rainsplash, part->size, part->size * 20, part->alpha, part->alpha / 0.4, 0, 0, trace.endpos[0] + trace.plane.normal[0], trace.endpos[1] + trace.plane.normal[1], trace.endpos[2] + trace.plane.normal[2], trace.plane.normal[0], trace.plane.normal[1], trace.plane.normal[2], 0, 0, 0, 0, pqualityreduction, 0, 1, PBLEND_ADD, PARTICLE_ORIENTED_DOUBLESIDED, -1, -1, -1, 1, 1, 0, 0, NULL); if (part2) @@ -899,7 +913,7 @@ void CL_SpawnDecalParticleForPoint(const vec3_t org, float maxdist, float size, { VectorRandom(org2); VectorMA(org, maxdist, org2, org2); - trace = CL_TraceLine(org, org2, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, true, false, &hitent, false, true); + trace = CL_TraceLine(org, org2, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, &hitent, false, true); // take the closest trace result that doesn't end up hitting a NOMARKS // surface (sky for example) if (bestfrac > trace.fraction && !(trace.hitq3surfaceflags & Q3SURFACEFLAG_NOMARKS)) @@ -916,7 +930,8 @@ 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; @@ -930,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; @@ -945,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) @@ -955,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 { @@ -975,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 { @@ -996,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 { @@ -1016,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 { @@ -1035,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; @@ -1067,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); @@ -1084,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); @@ -1233,7 +1248,7 @@ static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const v { vec3_t dir, pos; float len, dec, qd; - int smoke, blood, bubbles, r, color; + int smoke, blood, bubbles, r, color, count; if (spawndlight && r_refdef.scene.numlights < MAX_DLIGHTS) { @@ -1269,6 +1284,7 @@ static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const v VectorSubtract(originmaxs, originmins, dir); len = VectorNormalizeLength(dir); + if (ent) { dec = -ent->persistent.trail_time; @@ -1290,8 +1306,9 @@ static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const v blood = cl_particles.integer && cl_particles_blood.integer; bubbles = cl_particles.integer && cl_particles_bubbles.integer && !cl_particles_quake.integer && (CL_PointSuperContents(pos) & (SUPERCONTENTS_WATER | SUPERCONTENTS_SLIME)); qd = 1.0f / cl_particles_quality.value; + count = 0; - while (len >= 0) + while (len >= 0 && ++count <= 16384) { dec = 3; if (blood) @@ -1442,8 +1459,6 @@ 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 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; @@ -1491,7 +1506,7 @@ static void CL_NewParticlesFromEffectinfo(int effectnameindex, float pcount, con } 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; @@ -1610,15 +1625,20 @@ static void CL_NewParticlesFromEffectinfo(int effectnameindex, float pcount, con { VectorCopy(originmins, trailpos); trailstep = traillen / cnt; - AnglesFromVectors(angles, traildir, NULL, false); } else { VectorCopy(center, trailpos); trailstep = 0; + } + + if (trailstep == 0) + { VectorMAM(0.5f, velocitymins, 0.5f, velocitymaxs, velocity); AnglesFromVectors(angles, velocity, NULL, false); } + 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); @@ -1657,7 +1677,7 @@ static void CL_NewParticlesFromEffectinfo(int effectnameindex, float pcount, con } } 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) @@ -1670,6 +1690,7 @@ void CL_ParticleBox(int effectnameindex, float pcount, const vec3_t originmins, 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_ParticleBox(effectnameindex, pcount, originmins, originmaxs, velocitymins, velocitymaxs, ent, palettecolor, true, true, NULL, NULL, 1); @@ -1766,6 +1787,11 @@ void CL_ReadPointFile_f (void) VectorCopy(leakorg, vecorg); Con_Printf("%i points read (%i particles spawned)\nLeak at %f %f %f\n", c, s, leakorg[0], leakorg[1], leakorg[2]); + if (c == 0) + { + return; + } + CL_NewParticle(vecorg, pt_beam, 0xFF0000, 0xFF0000, tex_beam, 64, 0, 255, 0, 0, 0, org[0] - 4096, org[1], org[2], org[0] + 4096, org[1], org[2], 0, 0, 0, 0, false, 1<<30, 1, PBLEND_ADD, PARTICLE_HBEAM, -1, -1, -1, 1, 1, 0, 0, NULL); CL_NewParticle(vecorg, pt_beam, 0x00FF00, 0x00FF00, tex_beam, 64, 0, 255, 0, 0, 0, org[0], org[1] - 4096, org[2], org[0], org[1] + 4096, org[2], 0, 0, 0, 0, false, 1<<30, 1, PBLEND_ADD, PARTICLE_HBEAM, -1, -1, -1, 1, 1, 0, 0, NULL); CL_NewParticle(vecorg, pt_beam, 0x0000FF, 0x0000FF, tex_beam, 64, 0, 255, 0, 0, 0, org[0], org[1], org[2] - 4096, org[0], org[1], org[2] + 4096, 0, 0, 0, 0, false, 1<<30, 1, PBLEND_ADD, PARTICLE_HBEAM, -1, -1, -1, 1, 1, 0, 0, NULL); @@ -1851,7 +1877,7 @@ void CL_ParticleExplosion (const vec3_t org) { VectorRandom(v2); VectorMA(org, 128, v2, v); - trace = CL_TraceLine(org, v, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false, false); + trace = CL_TraceLine(org, v, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, collision_extendmovelength.value, true, false, NULL, false, false); } while (k < 16 && trace.fraction < 0.1f); VectorSubtract(trace.endpos, org, v2); @@ -2547,7 +2573,7 @@ void R_DrawDecals (void) float frametime; float decalfade; float drawdist2; - int killsequence = cl.decalsequence - max(0, cl_decals_max.integer); + unsigned int killsequence = cl.decalsequence - bound(0, (unsigned int) cl_decals_max.integer, cl.decalsequence); frametime = bound(0, cl.time - cl.decals_updatetime, 1); cl.decals_updatetime = bound(cl.time - 1, cl.decals_updatetime + frametime, cl.time + 1); @@ -2565,7 +2591,7 @@ void R_DrawDecals (void) if (!decal->typeindex) continue; - if (killsequence - decal->decalsequence > 0) + if (killsequence > decal->decalsequence) goto killdecal; if (cl.time > decal->time2 + cl_decals_time.value) @@ -2960,7 +2986,7 @@ void R_DrawParticles (void) // if (p->bounce && cl.time >= p->delayedcollisions) if (p->bounce && cl_particles_collisions.integer && VectorLength(p->vel)) { - trace = CL_TraceLine(oldorg, p->org, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | ((p->typeindex == pt_rain || p->typeindex == pt_snow) ? SUPERCONTENTS_LIQUIDSMASK : 0), true, false, &hitent, false, false); + trace = CL_TraceLine(oldorg, p->org, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | ((p->typeindex == pt_rain || p->typeindex == pt_snow) ? SUPERCONTENTS_LIQUIDSMASK : 0), collision_extendmovelength.value, true, false, &hitent, false, false); // if the trace started in or hit something of SUPERCONTENTS_NODROP // or if the trace hit something flagged as NOIMPACT // then remove the particle