void CL_AddParticles(void) { cparticle_t *p, *next; float alpha; float time, time2; vec3_t org; int color; cparticle_t *active, *tail; active = NULL; tail = NULL; for (p = active_particles; p; p = next) { next = p->next; if (p->alphavel != INSTANT_PARTICLE) { time = (cl.time - p->time) * 0.001; alpha = p->alpha + time * p->alphavel; if (alpha <= 0) { /* faded out */ p->next = free_particles; free_particles = p; continue; } } else { time = 0.0f; alpha = p->alpha; } p->next = NULL; if (!tail) { active = tail = p; } else { tail->next = p; tail = p; } if (alpha > 1.0f) { alpha = 1; } color = p->color; time2 = time * time; org[0] = p->org[0] + p->vel[0] * time + p->accel[0] * time2; org[1] = p->org[1] + p->vel[1] * time + p->accel[1] * time2; org[2] = p->org[2] + p->vel[2] * time + p->accel[2] * time2; V_AddParticle(org, color, alpha); if (p->alphavel == INSTANT_PARTICLE) { p->alphavel = 0.0; p->alpha = 0.0; } } active_particles = active; }
/* =============== CL_AddParticles =============== */ void CL_AddParticles (void) { cparticle_t *p, *next; float alpha; float time, time2; vec3_t org; int color; cparticle_t *active, *tail; int contents; float grav; active = NULL; tail = NULL; if (!cl_drawParticles->integer) return; // allow gravity tweaks by the server grav = Cvar_VariableValue("sv_gravity"); if (!grav) grav = 1; else grav /= 800; for (p = active_particles; p; p = next) { next = p->next; // set alpha // PMM - added INSTANT_PARTICLE handling if (p->alphavel != INSTANT_PARTICLE) { time = (cl.time - p->time) * 0.001; alpha = p->alpha + time * p->alphavel; if (alpha <= 0) { // faded out CL_FreeParticle (p); continue; } else if (alpha <= 0.3f && p->color == 240) // this is HACK central... { // do blood decals if (rand() & 4) { trace_t tr; time2 = time * time; org[0] = p->org[0] + p->vel[0] * time + p->accel[0] * time2; org[1] = p->org[1] + p->vel[1] * time + p->accel[1] * time2; org[2] = p->org[2] + p->vel[2] * time + p->accel[2] * time2; tr = CL_Trace(p->org, org, 0, MASK_SOLID); if (tr.fraction != 1.0f) { if (!VectorCompare(tr.plane.normal, vec3_origin) && !(CM_PointContents(p->org, 0) & MASK_WATER)) // no blood splatters underwater... { vec4_t color; Vector4Set(color, 1.0, 0.0, 0.0, 1.0f); RE_AddDecal(tr.endpos, tr.plane.normal, color, 16 + ((rand() % 21 * 0.05f) - 0.5f), DECAL_BLOOD + (rand() & 4), 0, frand() * 360); } } } } } else { alpha = p->alpha; } if (alpha > 1.0) alpha = 1; // set color color = p->color; // backup old position VectorCopy (p->org, p->oldOrg); // calculate new position time2 = time * time; org[0] = p->org[0] + p->vel[0] * time + p->accel[0] * time2; org[1] = p->org[1] + p->vel[1] * time + p->accel[1] * time2; org[2] = p->org[2] + p->vel[2] * time + p->accel[2] * time2; // gravity modulation //if (!p->ignoreGrav) // org[2] += time2 * -PARTICLE_GRAVITY; // collision test if (cl_particleCollision->integer) { if (p->bounceFactor) { trace_t trace; vec3_t vel; int hitTime; float time; trace = CL_Trace(p->oldOrg, org, 0, CONTENTS_SOLID); if (trace.fraction > 0 && trace.fraction < 1) { // reflect the velocity on the trace plane hitTime = cl.time - cls.rframetime + cls.rframetime * trace.fraction; time = ((float)hitTime - p->time) * 0.001; Vector3Set (vel, p->vel[0], p->vel[1], p->vel[2] + p->accel[2] * time * grav); VectorReflect (vel, trace.plane.normal, p->vel); VectorScale (p->vel, p->bounceFactor, p->vel); // check for stop, making sure that even on low FPS systems it doesn't bobble if (trace.allsolid || (trace.plane.normal[2] > 0 && (p->vel[2] < 40 || p->vel[2] < -cls.rframetime * p->vel[2]))) { VectorClear(p->vel); VectorClear(p->accel); p->bounceFactor = 0.0f; } VectorCopy (trace.endpos, org); // reset particle p->time = cl.time; VectorCopy (org, p->org); } } } // kill all particles in solid contents = CM_PointContents (org, 0); if (contents & MASK_SOLID) { CL_FreeParticle (p); continue; } // have this always below CL_FreeParticle(p); ! p->next = NULL; if (!tail) { active = tail = p; } else { tail->next = p; tail = p; } // add to scene V_AddParticle (org, color, alpha); // PMM if (p->alphavel == INSTANT_PARTICLE) { p->alphavel = 0.0; p->alpha = 0.0; } } active_particles = active; }
/* =============== CL_AddParticles =============== */ void CL_AddParticles (void) { cparticle_t *p, *next; //float alpha; float cltime; float time = 0, time2 = 0; cparticle_t *active = NULL, *tail = NULL; particle_t part; cltime = (float)cl.time; for (p=active_particles ; p ; p=next) { next = p->next; // PMM - added INSTANT_PARTICLE handling for heat beam if (p->alphavel != INSTANT_PARTICLE) { time = (cltime - p->time)*0.001f; part.alpha = p->alpha + time*p->alphavel; if (part.alpha <= 0.0f) { // faded out p->next = free_particles; free_particles = p; continue; } else if(part.alpha <= 0.3f && p->color == 0xe8) { #if 0 if(rand() & 4) { trace_t tr; time2 = time*time; part.origin[0] = p->org[0] + p->vel[0]*time + p->accel[0]*time2; part.origin[1] = p->org[1] + p->vel[1]*time + p->accel[1]*time2; part.origin[2] = p->org[2] + p->vel[2]*time + p->accel[2]*time2; tr = CM_BoxTrace(p->org, part.origin, vec3_origin, vec3_origin, 0, MASK_SOLID); if (tr.fraction != 1.0f) { R_AddDecal(tr.endpos, tr.plane.normal, 0, 0, 0, 1.0f, 2 + ((rand()%21*0.05) - 0.5), 1, 0, rand()%361); } } #endif R_AddStain(p->org, 0, 18); } } else { part.alpha = p->alpha; p->alphavel = p->alpha = 0.0f; } p->next = NULL; if (!tail) { active = tail = p; } else { tail->next = p; tail = p; } if (part.alpha > 1.0f) part.alpha = 1.0f; time2 = time*time; part.origin[0] = p->org[0] + p->vel[0]*time + p->accel[0]*time2; part.origin[1] = p->org[1] + p->vel[1]*time + p->accel[1]*time2; part.origin[2] = p->org[2] + p->vel[2]*time + p->accel[2]*time2; part.color = p->color; V_AddParticle (&part); // PMM //if (p->alphavel == INSTANT_PARTICLE) // p->alphavel = p->alpha = 0.0; } active_particles = active; }