-
- VectorSubtract(end, start, dir);
- VectorNormalize(dir);
-
- VectorSubtract (end, start, vec);
-#ifdef WORKINGLQUAKE
- len = VectorNormalize (vec);
- dec = 0;
- speed = 1.0f / cl.frametime;
- VectorSubtract(end, start, vel);
-#else
- len = VectorNormalizeLength (vec);
- 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;
-
- speed = ent->state_current.time - ent->state_previous.time;
- if (speed)
- speed = 1.0f / speed;
- VectorSubtract(ent->state_current.origin, ent->state_previous.origin, vel);
- color = particlepalette[color];
-#endif
- VectorScale(vel, speed, vel);
-
- // advance into this frame to reach the first puff location
- VectorMA(start, dec, vec, pos);
- len -= dec;
-
- smoke = cl_particles.integer && cl_particles_smoke.integer;
- blood = cl_particles.integer && cl_particles_blood.integer;
-#ifdef WORKINGLQUAKE
- contents = CL_PointQ1Contents(pos);
- bubbles = cl_particles.integer && cl_particles_bubbles.integer && (contents == CONTENTS_WATER || contents == CONTENTS_SLIME);
-#else
- bubbles = cl_particles.integer && cl_particles_bubbles.integer && (CL_PointSuperContents(pos) & (SUPERCONTENTS_WATER | SUPERCONTENTS_SLIME));
-#endif
- qd = 1.0f / cl_particles_quality.value;
-
- while (len >= 0)
- {
- switch (type)
- {
- case 0: // rocket trail
- if (cl_particles_quake.integer)
- {
- dec = qd*3;
- r = rand()&3;
- color = particlepalette[ramp3[r]];
- particle(particletype + pt_alphastatic, color, color, tex_particle, 1, qd*42*(6-r), qd*306, 0, -0.05, pos[0], pos[1], pos[2], 0, 0, 0, 0, 3, 0);
- }
- else
- {
- dec = qd*3;
- if (smoke)
- {
- particle(particletype + pt_smoke, 0x303030, 0x606060, tex_smoke[rand()&7], 3, qd*cl_particles_smoke_alpha.value*62, qd*cl_particles_smoke_alphafade.value*62, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0);
- particle(particletype + pt_static, 0x801010, 0xFFA020, tex_smoke[rand()&7], 3, qd*cl_particles_smoke_alpha.value*288, qd*cl_particles_smoke_alphafade.value*1400, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 20);
- }
- if (bubbles)
- particle(particletype + pt_bubble, 0x404040, 0x808080, tex_bubble, 2, qd*lhrandom(64, 255), qd*256, -0.25, 1.5, pos[0], pos[1], pos[2], 0, 0, 0, (1.0 / 16.0), 0, 16);
- }
- break;
-
- case 1: // grenade trail
- if (cl_particles_quake.integer)
- {
- dec = qd*3;
- r = 2 + (rand()%5);
- color = particlepalette[ramp3[r]];
- particle(particletype + pt_alphastatic, color, color, tex_particle, 1, qd*42*(6-r), qd*306, 0, -0.05, pos[0], pos[1], pos[2], 0, 0, 0, 0, 3, 0);
- }
- else
- {
- dec = qd*3;
- if (smoke)
- particle(particletype + pt_smoke, 0x303030, 0x606060, tex_smoke[rand()&7], 3, qd*cl_particles_smoke_alpha.value*50, qd*cl_particles_smoke_alphafade.value*50, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0);
- }
- break;
-
-
- case 2: // blood
- case 4: // slight blood
- if (cl_particles_quake.integer)
- {
- if (type == 2)
- {
- dec = qd*3;
- color = particlepalette[67 + (rand()&3)];
- particle(particletype + pt_alphastatic, color, color, tex_particle, 1, qd*255, qd*128, 0, -0.05, pos[0], pos[1], pos[2], 0, 0, 0, 0, 3, 0);
- }
- else
- {
- dec = qd*6;
- color = particlepalette[67 + (rand()&3)];
- particle(particletype + pt_alphastatic, color, color, tex_particle, 1, qd*255, qd*128, 0, -0.05, pos[0], pos[1], pos[2], 0, 0, 0, 0, 3, 0);
- }
- }
- else
- {
- dec = qd*16;
- if (blood)
- particle(particletype + pt_blood, 0xFFFFFF, 0xFFFFFF, tex_bloodparticle[rand()&7], 8, qd * cl_particles_blood_alpha.value * 768.0f, qd * cl_particles_blood_alpha.value * 384.0f, 0, -1, pos[0], pos[1], pos[2], vel[0] * 0.5f, vel[1] * 0.5f, vel[2] * 0.5f, 1, 0, 64);
- }
- break;
-
- case 3: // green tracer
- if (cl_particles_quake.integer)
- {
- dec = qd*6;
- color = particlepalette[52 + (rand()&7)];
- particle(particletype + pt_alphastatic, color, color, tex_particle, 1, qd*255, qd*512, 0, 0, pos[0], pos[1], pos[2], 30*vec[1], 30*-vec[0], 0, 0, 0, 0);
- particle(particletype + pt_alphastatic, color, color, tex_particle, 1, qd*255, qd*512, 0, 0, pos[0], pos[1], pos[2], 30*-vec[1], 30*vec[0], 0, 0, 0, 0);
- }
- else
- {
- dec = qd*16;
- if (smoke)
- {
- if (gamemode == GAME_GOODVSBAD2)
- {
- dec = qd*6;
- particle(particletype + pt_static, 0x00002E, 0x000030, tex_particle, 6, qd*128, qd*384, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0);
- }
- else
- {
- dec = qd*3;
- color = particlepalette[20 + (rand()&7)];
- particle(particletype + pt_static, color, color, tex_particle, 2, qd*64, qd*192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0);
- }
- }
- }
- break;
-
- case 5: // flame tracer
- if (cl_particles_quake.integer)
- {
- dec = qd*6;
- color = particlepalette[230 + (rand()&7)];
- particle(particletype + pt_alphastatic, color, color, tex_particle, 1, qd*255, qd*512, 0, 0, pos[0], pos[1], pos[2], 30*vec[1], 30*-vec[0], 0, 0, 0, 0);
- particle(particletype + pt_alphastatic, color, color, tex_particle, 1, qd*255, qd*512, 0, 0, pos[0], pos[1], pos[2], 30*-vec[1], 30*vec[0], 0, 0, 0, 0);
- }
- else
- {
- dec = qd*3;
- if (smoke)
- {
- color = particlepalette[226 + (rand()&7)];
- particle(particletype + pt_static, color, color, tex_particle, 2, qd*64, qd*192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0);
- }
- }
- break;
-
- case 6: // voor trail
- if (cl_particles_quake.integer)
- {
- dec = qd*3;
- color = particlepalette[152 + (rand()&3)];
- particle(particletype + pt_alphastatic, color, color, tex_particle, 1, qd*255, qd*850, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 8, 0);
- }
- else
- {
- dec = qd*16;
- if (smoke)
- {
- if (gamemode == GAME_GOODVSBAD2)
- {
- dec = qd*6;
- particle(particletype + pt_alphastatic, particlepalette[0 + (rand()&255)], particlepalette[0 + (rand()&255)], tex_particle, 6, qd*255, qd*384, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0);
- }
- else if (gamemode == GAME_PRYDON)
- {
- dec = qd*6;
- particle(particletype + pt_static, 0x103040, 0x204050, tex_particle, 6, qd*64, qd*192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0);
- }
- else
- {
- dec = qd*3;
- particle(particletype + pt_static, 0x502030, 0x502030, tex_particle, 3, qd*64, qd*192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0);
- }
- }
- }
- break;
-#ifndef WORKINGLQUAKE
- case 7: // Nehahra smoke tracer
- dec = qd*7;
- if (smoke)
- particle(particletype + pt_alphastatic, 0x303030, 0x606060, tex_smoke[rand()&7], 7, qd*64, qd*320, 0, 0, pos[0], pos[1], pos[2], 0, 0, lhrandom(4, 12), 0, 0, 4);
- break;
- case 8: // Nexuiz plasma trail
- dec = qd*4;
- if (smoke)
- particle(particletype + pt_static, 0x283880, 0x283880, tex_particle, 4, qd*255, qd*1024, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 16);
- break;
- case 9: // glow trail
- dec = qd*3;
- if (smoke)
- particle(particletype + pt_alphastatic, color, color, tex_particle, 5, qd*128, qd*320, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0);
- break;
-#endif
- default:
- Sys_Error("CL_RocketTrail: unknown trail type %i", type);
- }
-
- // advance to next time and position
- len -= dec;
- VectorMA (pos, dec, vec, pos);