/* ================= CL_ParseBeam ================= */ static void CL_ParseBeam (model_t *m) { int i, ent; vec3_t start, end; beam_t *b; ent = MSG_ReadShort (); start[0] = MSG_ReadCoord (); start[1] = MSG_ReadCoord (); start[2] = MSG_ReadCoord (); end[0] = MSG_ReadCoord (); end[1] = MSG_ReadCoord (); end[2] = MSG_ReadCoord (); #ifdef SUPPORTS_SOFTWARE_FTESTAIN R_AddStain(end, 80, 12); //qbism ftestain #endif // override any beam with the same entity for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) { if (b->entity == ent) { b->entity = ent; b->model = m; b->endtime = cl.time + 0.2; VectorCopy (start, b->start); VectorCopy (end, b->end); return; } } // find a free beam for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) { if (!b->model || b->endtime < cl.time) { b->entity = ent; b->model = m; b->endtime = cl.time + 0.2; VectorCopy (start, b->start); VectorCopy (end, b->end); return; } } Con_Printf ("beam list overflow!\n"); }
/* =============== 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; }
/* ================= CL_ParseTEnt ================= */ void CL_ParseTEnt (void) { int type; vec3_t pos; dlight_t *dl; int rnd; int colorStart, colorLength; type = MSG_ReadByte (); switch (type) { case TE_WIZSPIKE: // spike hitting wall pos[0] = MSG_ReadCoord (); pos[1] = MSG_ReadCoord (); pos[2] = MSG_ReadCoord (); R_RunParticleEffect (pos, vec3_origin, 20, 30); #ifdef SUPPORTS_SOFTWARE_FTESTAIN R_AddStain(pos, -20, 11); //qbism ftestain #endif S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1); break; case TE_KNIGHTSPIKE: // spike hitting wall pos[0] = MSG_ReadCoord (); pos[1] = MSG_ReadCoord (); pos[2] = MSG_ReadCoord (); R_RunParticleEffect (pos, vec3_origin, 226, 20); #ifdef SUPPORTS_SOFTWARE_FTESTAIN R_AddStain(pos, -20, 15); //qbism ftestain #endif S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1); break; case TE_SPIKE: // spike hitting wall pos[0] = MSG_ReadCoord (); pos[1] = MSG_ReadCoord (); pos[2] = MSG_ReadCoord (); R_RunParticleEffect (pos, vec3_origin, 0, 10); #ifdef SUPPORTS_SOFTWARE_FTESTAIN R_AddStain(pos, -30, 10); //qbism ftestain #endif if ( rand() % 5 ) { S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1); } else { rnd = rand() & 3; if (rnd == 1) S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1); else if (rnd == 2) S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1); else S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1); } break; case TE_SUPERSPIKE: // super spike hitting wall pos[0] = MSG_ReadCoord (); pos[1] = MSG_ReadCoord (); pos[2] = MSG_ReadCoord (); R_RunParticleEffect (pos, vec3_origin, 0, 20); #ifdef SUPPORTS_SOFTWARE_FTESTAIN R_AddStain(pos, -30, 10); //qbism ftestain #endif if ( rand() % 5 ) { S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1); } else { rnd = rand() & 3; if (rnd == 1) S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1); else if (rnd == 2) S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1); else S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1); } break; case TE_GUNSHOT: // bullet hitting wall pos[0] = MSG_ReadCoord (); pos[1] = MSG_ReadCoord (); pos[2] = MSG_ReadCoord (); #ifdef SUPPORTS_KUROK if (!kurok) #endif { R_RunParticleEffect (pos, vec3_origin, 0, 20); #ifdef SUPPORTS_SOFTWARE_FTESTAIN R_AddStain(pos, -40, 12); //qbism ftestain #endif } break; case TE_EXPLOSION: // rocket explosion pos[0] = MSG_ReadCoord (); pos[1] = MSG_ReadCoord (); pos[2] = MSG_ReadCoord (); R_ParticleExplosion (pos); dl = CL_AllocDlight (0); VectorCopy (pos, dl->origin); dl->radius = 350; dl->die = cl.time + 0.5; dl->decay = 300; #ifdef SUPPORTS_KUROK if(kurok) { dl->color[0] = MSG_ReadCoord (); dl->color[1] = MSG_ReadCoord (); dl->color[2] = MSG_ReadCoord (); } #endif #ifdef SUPPORTS_SOFTWARE_FTESTAIN R_AddStain(pos, -30, 45); //qbism ftestain #endif S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; case TE_TAREXPLOSION: // tarbaby explosion pos[0] = MSG_ReadCoord (); pos[1] = MSG_ReadCoord (); pos[2] = MSG_ReadCoord (); R_BlobExplosion (pos); #ifdef SUPPORTS_KUROK if(kurok) { dl = CL_AllocDlight (0); VectorCopy (pos, dl->origin); dl->radius = 150; dl->die = cl.time + 0.75; dl->decay = 200; dl->color[0] = MSG_ReadCoord (); dl->color[1] = MSG_ReadCoord (); dl->color[2] = MSG_ReadCoord (); } #endif #ifdef SUPPORTS_SOFTWARE_FTESTAIN R_AddStain(pos, -20, 60); //qbism ftestain #endif S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; case TE_LIGHTNING1: // lightning bolts CL_ParseBeam (Mod_ForName("progs/bolt.mdl", true)); break; case TE_LIGHTNING2: // lightning bolts CL_ParseBeam (Mod_ForName("progs/bolt2.mdl", true)); break; case TE_LIGHTNING3: // lightning bolts CL_ParseBeam (Mod_ForName("progs/bolt3.mdl", true)); break; // PGM 01/21/97 case TE_BEAM: // grappling hook beam CL_ParseBeam (Mod_ForName("progs/beam.mdl", true)); break; // PGM 01/21/97 case TE_LAVASPLASH: pos[0] = MSG_ReadCoord (); pos[1] = MSG_ReadCoord (); pos[2] = MSG_ReadCoord (); R_LavaSplash (pos); break; case TE_TELEPORT: pos[0] = MSG_ReadCoord (); pos[1] = MSG_ReadCoord (); pos[2] = MSG_ReadCoord (); R_TeleportSplash (pos); break; case TE_EXPLOSION2: // color mapped explosion pos[0] = MSG_ReadCoord (); pos[1] = MSG_ReadCoord (); pos[2] = MSG_ReadCoord (); colorStart = MSG_ReadByte (); colorLength = MSG_ReadByte (); R_ParticleExplosion2 (pos, colorStart, colorLength); dl = CL_AllocDlight (0); VectorCopy (pos, dl->origin); dl->radius = 350; dl->die = cl.time + 0.5; dl->decay = 300; #ifdef SUPPORTS_SOFTWARE_FTESTAIN R_AddStain(pos, -30, 50); //qbism ftestain #endif S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; default: Sys_Error ("CL_ParseTEnt: bad type"); } }