+ else if (effectnameindex == EFFECT_EF_FLAME)
+ {
+ count *= 300 * cl_particles_quality.value;
+ while (count-- > 0)
+ particle(particletype + 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);
+ CL_AllocDlight(NULL, &tempmatrix, 200, 2.0f, 1.5f, 0.5f, 0, 0, 0, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
+ }
+ else if (effectnameindex == EFFECT_EF_STARDUST)
+ {
+ count *= 200 * cl_particles_quality.value;
+ while (count-- > 0)
+ particle(particletype + 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);
+ CL_AllocDlight(NULL, &tempmatrix, 200, 1.0f, 0.7f, 0.3f, 0, 0, 0, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
+ }
+ else if (!strncmp(particleeffectname[effectnameindex], "TR_", 3))
+ {
+ vec3_t dir, pos;
+ float len, dec, qd;
+ int smoke, blood, bubbles, r, color;
+
+ if (effectnameindex == EFFECT_TR_ROCKET)
+ CL_AllocDlight(&ent->render, &ent->render.matrix, 200, 3.0f, 1.5f, 0.5f, 0, 0, 0, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
+ else if (effectnameindex == EFFECT_TR_VORESPIKE)
+ {
+ if (gamemode == GAME_PRYDON && !cl_particles_quake.integer)
+ CL_AllocDlight(&ent->render, &ent->render.matrix, 100, 0.3f, 0.6f, 1.2f, 0, 0, 0, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
+ else
+ CL_AllocDlight(&ent->render, &ent->render.matrix, 200, 1.2f, 0.5f, 1.0f, 0, 0, 0, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
+ }
+ else if (effectnameindex == EFFECT_TR_NEXUIZPLASMA)
+ CL_AllocDlight(&ent->render, &ent->render.matrix, 200, 0.75f, 1.5f, 3.0f, 0, 0, 0, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
+
+ if (originmaxs[0] == originmins[0] && originmaxs[1] == originmins[1] && originmaxs[2] == originmins[2])
+ return;
+
+ VectorSubtract(originmaxs, originmins, dir);
+ len = VectorNormalizeLength(dir);
+ dec = -ent->persistent.trail_time;
+ ent->persistent.trail_time += len;
+ if (ent->persistent.trail_time < 0.01f)
+ return;
+
+ // if we skip out, leave it reset
+ ent->persistent.trail_time = 0.0f;
+
+ // advance into this frame to reach the first puff location
+ VectorMA(originmins, dec, dir, pos);
+ len -= dec;
+
+ smoke = cl_particles.integer && cl_particles_smoke.integer;
+ 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;
+
+ while (len >= 0)
+ {
+ dec = 3;
+ if (blood)
+ {
+ if (effectnameindex == EFFECT_TR_BLOOD)
+ {
+ if (cl_particles_quake.integer)
+ {
+ color = particlepalette[67 + (rand()&3)];
+ particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 0, 255, 128, 0, -0.05, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 3, 0);
+ }
+ else
+ {
+ dec = 16;
+ particle(particletype + pt_blood, 0xFFFFFF, 0xFFFFFF, tex_bloodparticle[rand()&7], 8, 0, qd * cl_particles_blood_alpha.value * 768.0f, qd * cl_particles_blood_alpha.value * 384.0f, 0, -1, pos[0], pos[1], pos[2], lhrandom(velocitymins[0], velocitymaxs[0]), lhrandom(velocitymins[1], velocitymaxs[1]), lhrandom(velocitymins[2], velocitymaxs[2]), 1, 4, 0, 64);
+ }
+ }
+ else if (effectnameindex == EFFECT_TR_SLIGHTBLOOD)
+ {
+ if (cl_particles_quake.integer)
+ {
+ dec = 6;
+ color = particlepalette[67 + (rand()&3)];
+ particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 0, 255, 128, 0, -0.05, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 3, 0);
+ }
+ else
+ {
+ dec = 32;
+ particle(particletype + pt_blood, 0xFFFFFF, 0xFFFFFF, tex_bloodparticle[rand()&7], 8, 0, qd * cl_particles_blood_alpha.value * 768.0f, qd * cl_particles_blood_alpha.value * 384.0f, 0, -1, pos[0], pos[1], pos[2], lhrandom(velocitymins[0], velocitymaxs[0]), lhrandom(velocitymins[1], velocitymaxs[1]), lhrandom(velocitymins[2], velocitymaxs[2]), 1, 4, 0, 64);
+ }
+ }
+ }
+ if (smoke)
+ {
+ if (effectnameindex == EFFECT_TR_ROCKET)
+ {
+ if (cl_particles_quake.integer)
+ {
+ r = rand()&3;
+ color = particlepalette[ramp3[r]];
+ particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 0, 42*(6-r), 306, 0, -0.05, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 3, 0);
+ }
+ else
+ {
+ particle(particletype + pt_smoke, 0x303030, 0x606060, tex_smoke[rand()&7], 3, 0, cl_particles_smoke_alpha.value*62, cl_particles_smoke_alphafade.value*62, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0);
+ particle(particletype + pt_static, 0x801010, 0xFFA020, tex_smoke[rand()&7], 3, 0, cl_particles_smoke_alpha.value*288, cl_particles_smoke_alphafade.value*1400, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 20);
+ }
+ }
+ else if (effectnameindex == EFFECT_TR_GRENADE)
+ {
+ if (cl_particles_quake.integer)
+ {
+ r = 2 + (rand()%5);
+ color = particlepalette[ramp3[r]];
+ particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 0, 42*(6-r), 306, 0, -0.05, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 3, 0);
+ }
+ else
+ {
+ particle(particletype + pt_smoke, 0x303030, 0x606060, tex_smoke[rand()&7], 3, 0, cl_particles_smoke_alpha.value*50, cl_particles_smoke_alphafade.value*50, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0);
+ }
+ }
+ else if (effectnameindex == EFFECT_TR_WIZSPIKE)
+ {
+ if (cl_particles_quake.integer)
+ {
+ dec = 6;
+ color = particlepalette[52 + (rand()&7)];
+ particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 0, 255, 512, 0, 0, pos[0], pos[1], pos[2], 30*dir[1], 30*-dir[0], 0, 0, 0, 0, 0);
+ particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 0, 255, 512, 0, 0, pos[0], pos[1], pos[2], 30*-dir[1], 30*dir[0], 0, 0, 0, 0, 0);
+ }
+ else if (gamemode == GAME_GOODVSBAD2)
+ {
+ dec = 6;
+ particle(particletype + pt_static, 0x00002E, 0x000030, tex_particle, 6, 0, 128, 384, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0);
+ }
+ else
+ {
+ color = particlepalette[20 + (rand()&7)];
+ particle(particletype + pt_static, color, color, tex_particle, 2, 0, 64, 192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0);
+ }
+ }
+ else if (effectnameindex == EFFECT_TR_KNIGHTSPIKE)
+ {
+ if (cl_particles_quake.integer)
+ {
+ dec = 6;
+ color = particlepalette[230 + (rand()&7)];
+ particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 0, 255, 512, 0, 0, pos[0], pos[1], pos[2], 30*dir[1], 30*-dir[0], 0, 0, 0, 0, 0);
+ particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 0, 255, 512, 0, 0, pos[0], pos[1], pos[2], 30*-dir[1], 30*dir[0], 0, 0, 0, 0, 0);
+ }
+ else
+ {
+ color = particlepalette[226 + (rand()&7)];
+ particle(particletype + pt_static, color, color, tex_particle, 2, 0, 64, 192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0);
+ }
+ }
+ else if (effectnameindex == EFFECT_TR_VORESPIKE)
+ {
+ if (cl_particles_quake.integer)
+ {
+ color = particlepalette[152 + (rand()&3)];
+ particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 0, 255, 850, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 8, 0);
+ }
+ else if (gamemode == GAME_GOODVSBAD2)
+ {
+ dec = 6;
+ particle(particletype + pt_alphastatic, particlepalette[0 + (rand()&255)], particlepalette[0 + (rand()&255)], tex_particle, 6, 0, 255, 384, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0);
+ }
+ else if (gamemode == GAME_PRYDON)
+ {
+ dec = 6;
+ particle(particletype + pt_static, 0x103040, 0x204050, tex_particle, 6, 0, 64, 192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0);
+ }
+ else
+ particle(particletype + pt_static, 0x502030, 0x502030, tex_particle, 3, 0, 64, 192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0);
+ }
+ else if (effectnameindex == EFFECT_TR_NEHAHRASMOKE)
+ {
+ dec = 7;
+ particle(particletype + pt_alphastatic, 0x303030, 0x606060, tex_smoke[rand()&7], 7, 0, 64, 320, 0, 0, pos[0], pos[1], pos[2], 0, 0, lhrandom(4, 12), 0, 0, 0, 4);
+ }
+ else if (effectnameindex == EFFECT_TR_NEXUIZPLASMA)
+ {
+ dec = 4;
+ particle(particletype + pt_static, 0x283880, 0x283880, tex_particle, 4, 0, 255, 1024, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 16);
+ }
+ else if (effectnameindex == EFFECT_TR_GLOWTRAIL)
+ particle(particletype + pt_alphastatic, particlepalette[palettecolor], particlepalette[palettecolor], tex_particle, 5, 0, 128, 320, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0);
+ }
+ if (bubbles)
+ {
+ if (effectnameindex == EFFECT_TR_ROCKET)
+ particle(particletype + pt_bubble, 0x404040, 0x808080, tex_bubble, 2, 0, lhrandom(64, 255), 256, -0.25, 1.5, pos[0], pos[1], pos[2], 0, 0, 0, 0.0625, 0.25, 0, 16);
+ else if (effectnameindex == EFFECT_TR_GRENADE)
+ particle(particletype + pt_bubble, 0x404040, 0x808080, tex_bubble, 2, 0, lhrandom(64, 255), 256, -0.25, 1.5, pos[0], pos[1], pos[2], 0, 0, 0, 0.0625, 0.25, 0, 16);
+ }
+ // advance to next time and position
+ dec *= qd;
+ len -= dec;
+ VectorMA (pos, dec, dir, pos);
+ }
+ ent->persistent.trail_time = len;
+ }
+ else if (developer.integer >= 1)
+ Con_Printf("CL_ParticleEffect_Fallback: no fallback found for effect %s\n", particleeffectname[effectnameindex]);