static void _LaserImpact( trace_t *trace, vec3_t dir ) { if( !trace || trace->ent < 0 ) return; if( cg_particles->integer && laserOwner ) { #define TRAILTIME ( (int)( 1000.0f / 20.0f ) ) // density as quantity per second if( laserOwner->localEffects[LOCALEFFECT_LASERBEAM_SMOKE_TRAIL] + TRAILTIME < cg.time ) { laserOwner->localEffects[LOCALEFFECT_LASERBEAM_SMOKE_TRAIL] = cg.time; CG_ImpactSmokePuff( trace->endpos, trace->plane.normal, 3, 1.0f, 8, 12 ); } #undef TRAILTIME } // it's a brush model if( trace->ent == 0 || !( cg_entities[trace->ent].current.effects & EF_TAKEDAMAGE ) ) { CG_AddLightToScene( trace->endpos, 100, 0.75f, 0.75f, 0.375f, NULL ); // TODO: add impact model return; } // it's a player // TODO: add player-impact model }
/* * CG_BulletExplosion */ void CG_BulletExplosion( vec3_t pos, vec_t *dir, trace_t *trace ) { lentity_t *le; vec3_t angles; vec3_t local_dir, end; trace_t local_trace, *tr; assert( dir || trace ); if( dir ) { // find what are we hitting tr = &local_trace; VectorMA( pos, -1.0, dir, end ); CG_Trace( tr, pos, vec3_origin, vec3_origin, end, cg.view.POVent, MASK_SHOT ); if( tr->fraction == 1.0 ) return; } else { tr = trace; dir = local_dir; VectorCopy( tr->plane.normal, dir ); } VecToAngles( dir, angles ); if( tr->surfFlags & SURF_FLESH || ( tr->ent > 0 && cg_entities[tr->ent].current.type == ET_PLAYER ) || ( tr->ent > 0 && cg_entities[tr->ent].current.type == ET_CORPSE ) ) { le = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 3, //3 frames for weak 1, 0, 0, 1, //full white no inducted alpha 0, 0, 0, 0, //dlight CG_MediaModel( cgs.media.modBulletExplode ), NULL ); le->ent.rotation = rand() % 360; le->ent.scale = 1.0f; if( ISVIEWERENTITY( tr->ent ) ) le->ent.renderfx |= RF_VIEWERMODEL; } else if( tr->surfFlags & SURF_DUST ) { // throw particles on dust CG_ImpactSmokePuff( tr->endpos, tr->plane.normal, 4, 0.6f, 6, 8 ); } else { le = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 3, //3 frames for weak 1, 1, 1, 1, //full white no inducted alpha 0, 0, 0, 0, //dlight CG_MediaModel( cgs.media.modBulletExplode ), NULL ); le->ent.rotation = rand() % 360; le->ent.scale = 1.0f; CG_ImpactSmokePuff( tr->endpos, tr->plane.normal, 2, 0.6f, 6, 8 ); if( !( tr->surfFlags & SURF_NOMARKS ) ) CG_SpawnDecal( pos, dir, random()*360, 8, 1, 1, 1, 1, 10, 1, qfalse, CG_MediaShader( cgs.media.shaderBulletMark ) ); } }