/* * CG_PlasmaExplosion */ void CG_PlasmaExplosion( vec3_t pos, vec3_t dir, int fire_mode, float radius ) { lentity_t *le; vec3_t angles; float model_radius = PLASMA_EXPLOSION_MODEL_RADIUS; VecToAngles( dir, angles ); if( fire_mode == FIRE_MODE_STRONG ) { le = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 4, 1, 1, 1, 1, 150, 0, 0.75, 0, CG_MediaModel( cgs.media.modPlasmaExplosion ), NULL ); le->ent.scale = radius/model_radius; } else { le = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 4, 1, 1, 1, 1, 80, 0, 0.75, 0, CG_MediaModel( cgs.media.modPlasmaExplosion ), NULL ); le->ent.scale = radius/model_radius; } le->ent.rotation = rand() % 360; CG_SpawnDecal( pos, dir, 90, 16, 1, 1, 1, 1, 4, 1, qtrue, CG_MediaShader( cgs.media.shaderPlasmaMark ) ); }
/* * CG_GunBladeBlastImpact */ void CG_GunBladeBlastImpact( vec3_t pos, vec3_t dir, float radius ) { lentity_t *le; lentity_t *le_explo; vec3_t angles; float model_radius = GUNBLADEBLAST_EXPLOSION_MODEL_RADIUS; VecToAngles( dir, angles ); le = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 2, //3 frames 1, 1, 1, 1, //full white no inducted alpha 0, 0, 0, 0, //dlight CG_MediaModel( cgs.media.modBladeWallHit ), //"models/weapon_hits/gunblade/hit_blast.md3" NULL ); le->ent.rotation = rand() % 360; le->ent.scale = 1.0f; // this is the small bullet impact le_explo = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 2 + ( radius/16.1f ), 1, 1, 1, 1, //full white no inducted alpha 0, 0, 0, 0, //dlight CG_MediaModel( cgs.media.modBladeWallExplo ), NULL ); le_explo->ent.rotation = rand() % 360; le_explo->ent.scale = radius/model_radius; CG_SpawnDecal( pos, dir, random()*360, 3+( radius*0.5f ), 1, 1, 1, 1, 10, 1, qfalse, CG_MediaShader( cgs.media.shaderExplosionMark ) ); }
/* * CG_BladeImpact */ void CG_BladeImpact( const vec3_t pos, const vec3_t dir ) { lentity_t *le; vec3_t angles; vec3_t end; vec3_t local_pos, local_dir; trace_t trace; //find what are we hitting VectorCopy( pos, local_pos ); VectorNormalize2( dir, local_dir ); VectorMA( pos, -1.0, local_dir, end ); CG_Trace( &trace, local_pos, vec3_origin, vec3_origin, end, cg.view.POVent, MASK_SHOT ); if( trace.fraction == 1.0 ) return; VecToAngles( local_dir, angles ); if( trace.surfFlags & SURF_FLESH || ( trace.ent > 0 && cg_entities[trace.ent].current.type == ET_PLAYER ) || ( trace.ent > 0 && cg_entities[trace.ent].current.type == ET_CORPSE ) ) { 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.modBladeWallHit ), NULL ); le->ent.rotation = rand() % 360; le->ent.scale = 1.0f; trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxBladeFleshHit[(int)( random()*3 )] ), pos, CHAN_AUTO, cg_volume_effects->value, ATTN_NORM ); } else if( trace.surfFlags & SURF_DUST ) { // throw particles on dust CG_ParticleEffect( trace.endpos, trace.plane.normal, 0.30f, 0.30f, 0.25f, 30 ); //fixme? would need a dust sound trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxBladeWallHit[(int)( random()*2 )] ), pos, CHAN_AUTO, cg_volume_effects->value, ATTN_NORM ); } 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.modBladeWallHit ), NULL ); le->ent.rotation = rand() % 360; le->ent.scale = 1.0f; CG_ParticleEffect( trace.endpos, trace.plane.normal, 0.30f, 0.30f, 0.25f, 15 ); trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxBladeWallHit[(int)( random()*2 )] ), pos, CHAN_AUTO, cg_volume_effects->value, ATTN_NORM ); if( !( trace.surfFlags & SURF_NOMARKS ) ) CG_SpawnDecal( pos, dir, random()*10, 8, 1, 1, 1, 1, 10, 1, false, CG_MediaShader( cgs.media.shaderBladeMark ) ); } }
/* * CG_InstaExplosionMode */ void CG_InstaExplosionMode( vec3_t pos, vec3_t dir, int fire_mode ) { lentity_t *le; vec3_t angles; VecToAngles( dir, angles ); le = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 6, // 6 is time 1, 1, 1, 1, //full white no inducted alpha 250, 0.65, 0.65, 0.65, //white dlight CG_MediaModel( cgs.media.modInstagunWallHit ), NULL ); le->ent.rotation = rand() % 360; if( fire_mode == FIRE_MODE_STRONG ) { le->ent.scale = 1.5f; // add white energy particles on the impact CG_ImpactPuffParticles( pos, dir, 12, 1.25f, 1, 1, 1, 1, CG_MediaShader( cgs.media.shaderAdditiveParticleShine ) ); } else { le->ent.scale = 1.0f; CG_ImpactPuffParticles( pos, dir, 12, 1.0f, 1, 1, 1, 1, NULL ); } CG_SpawnDecal( pos, dir, random()*360, 8, 1, 1, 1, 1, 10, 1, qtrue, CG_MediaShader( cgs.media.shaderInstagunMark ) ); }
void CG_Dash( entity_state_t *state ) { lentity_t *le; vec3_t pos, dvect, angle = { 0, 0, 0 }; if( !(cg_cartoonEffects->integer & 4) ) return; // KoFFiE: Calculate angle based on relative position of the previous origin state of the player entity VectorSubtract( state->origin, cg_entities[state->number].prev.origin, dvect ); // ugly inline define -> Ignore when difference between 2 positions was less than this value. #define IGNORE_DASH 6.0 if( ( dvect[0] > -IGNORE_DASH ) && ( dvect[0] < IGNORE_DASH ) && ( dvect[1] > -IGNORE_DASH ) && ( dvect[1] < IGNORE_DASH ) ) return; VecToAngles( dvect, angle ); VectorCopy( state->origin, pos ); angle[1] += 270; // Adjust angle pos[2] -= 24; // Adjust the position to ground height if( CG_PointContents( pos ) & MASK_WATER ) return; // no smoke under water :) le = CG_AllocModel( LE_DASH_SCALE, pos, angle, 7, //5 1.0, 1.0, 1.0, 1.0, 0, 0, 0, 0, CG_MediaModel( cgs.media.modDash ), NULL ); le->ent.scale = 0.01f; le->ent.axis[2][2] *= 2.0f; }
/* * CG_BoltExplosionMode */ void CG_BoltExplosionMode( const vec3_t pos, const vec3_t dir, int fire_mode, int surfFlags ) { lentity_t *le; vec3_t angles; if( !CG_SpawnDecal( pos, dir, random()*360, 12, 1, 1, 1, 1, 10, 1, true, CG_MediaShader( cgs.media.shaderElectroboltMark ) ) ) { if( surfFlags & (SURF_SKY|SURF_NOMARKS|SURF_NOIMPACT) ) { return; } } VecToAngles( dir, angles ); le = CG_AllocModel( LE_INVERSESCALE_ALPHA_FADE, pos, angles, 6, // 6 is time 1, 1, 1, 1, //full white no inducted alpha 250, 0.75, 0.75, 0.75, //white dlight CG_MediaModel( cgs.media.modElectroBoltWallHit ), NULL ); le->ent.rotation = rand() % 360; le->ent.scale = ( fire_mode == FIRE_MODE_STRONG ) ? 1.5f : 1.0f; // add white energy particles on the impact CG_ImpactPuffParticles( pos, dir, 15, 0.75f, 1, 1, 1, 1, NULL ); trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxElectroboltHit ), pos, CHAN_AUTO, cg_volume_effects->value, ATTN_STATIC ); }
/* * CG_PModel_SpawnTeleportEffect */ void CG_PModel_SpawnTeleportEffect( centity_t *cent ) { int j; cgs_skeleton_t *skel; lentity_t *le; vec3_t teleportOrigin; vec3_t rgb; skel = CG_SkeletonForModel( cent->ent.model ); if( !skel || !cent->ent.boneposes ) return; for( j = LOCALEFFECT_EV_PLAYER_TELEPORT_IN; j <= LOCALEFFECT_EV_PLAYER_TELEPORT_OUT; j++ ) { if( cent->localEffects[j] ) { cent->localEffects[j] = 0; VectorSet( rgb, 0.5, 0.5, 0.5 ); if( j == LOCALEFFECT_EV_PLAYER_TELEPORT_OUT ) { VectorCopy( cent->teleportedFrom, teleportOrigin ); } else { VectorCopy( cent->teleportedTo, teleportOrigin ); if( ISVIEWERENTITY( cent->current.number ) ) { VectorSet( rgb, 0.1, 0.1, 0.1 ); } } // spawn a dummy model le = CG_AllocModel( LE_RGB_FADE, teleportOrigin, vec3_origin, 10, rgb[0], rgb[1], rgb[2], 1, 0, 0, 0, 0, cent->ent.model, CG_MediaShader( cgs.media.shaderTeleportShellGfx ) ); if( cent->skel ) { // use static bone pose, no animation le->skel = cent->skel; le->static_boneposes = ( bonepose_t * )CG_Malloc( sizeof( bonepose_t ) * le->skel->numBones ); memcpy( le->static_boneposes, cent->ent.boneposes, sizeof( bonepose_t ) * le->skel->numBones ); le->ent.boneposes = le->static_boneposes; le->ent.oldboneposes = le->ent.boneposes; } le->ent.frame = cent->ent.frame; le->ent.oldframe = cent->ent.oldframe; le->ent.backlerp = 1.0f; Matrix3_Copy( cent->ent.axis, le->ent.axis ); } } }
void CG_SmallPileOfGibs( vec3_t origin, int damage, const vec3_t initialVelocity ) { lentity_t *le; int i, count; float mass; vec3_t angles, velocity; int time; float baseangle = random() * 2 * M_PI; float radialspeed = 5.0f * damage; if( !cg_gibs->integer ) return; clamp( radialspeed, 50.0f, 100.0f ); time = 15; mass = 120; count = cg_gibs->integer; clamp( count, 10, 128 ); VectorCopy( initialVelocity, velocity ); // clip gib velocity clamp( velocity[0], -100, 100 ); clamp( velocity[1], -100, 100 ); clamp( velocity[2], 100, 500 ); // always some upwards for( i = 0; i < count; i++ ) { le = CG_AllocModel( LE_NO_FADE, origin, vec3_origin, time + time * random(), 1, 1, 1, 1, 0, 0, 0, 0, CG_MediaModel( cgs.media.modTechyGibs[MAX_BIG_TECHY_GIBS + (((int)brandom( 0, MAX_SMALL_TECHY_GIBS )) % MAX_SMALL_TECHY_GIBS)] ), NULL ); VectorSet( angles, crandom() * 360, crandom() * 360, crandom() * 360 ); AnglesToAxis( angles, le->ent.axis ); le->ent.scale = 1.0 + ( random() * 0.5f ); le->ent.renderfx = RF_FULLBRIGHT|RF_NOSHADOW; le->velocity[0] = velocity[0] + ( cos( baseangle + M_PI * 2 * (float)(i) / (float)(count) ) * radialspeed ) + crandom() * radialspeed * 0.5f; le->velocity[1] = velocity[1] + ( sin( baseangle + M_PI * 2 * (float)(i) / (float)(count) ) * radialspeed ) + crandom() * radialspeed * 0.5f; le->velocity[2] = velocity[2] + 125 + crandom() * radialspeed; VectorSet( le->accel, -0.2f, -0.2f, -900 ); le->bounce = 35; } CG_ImpactPuffParticles( origin, vec3_origin, 16, 2.5f, 1, 0.5, 0, 1, NULL ); }
/* * CG_InstaExplosionMode */ void CG_InstaExplosionMode( const vec3_t pos, const vec3_t dir, int fire_mode, int surfFlags, int owner ) { int team = -1; vec4_t tcolor = { 0.65f, 0.0f, 0.26f, 1.0f }; lentity_t *le; vec3_t angles; if( cg_teamColoredInstaBeams->integer && owner && ( owner < gs.maxclients + 1 ) ) team = cg_entities[owner].current.team; if( ( team == TEAM_ALPHA ) || ( team == TEAM_BETA ) ) { CG_TeamColor( team, tcolor ); tcolor[0] *= 0.65f; tcolor[1] *= 0.65f; tcolor[2] *= 0.65f; } if( !CG_SpawnDecal( pos, dir, random()*360, 12, tcolor[0], tcolor[1], tcolor[2], 1.0f, 10, 1, true, CG_MediaShader( cgs.media.shaderInstagunMark ) ) ) { if( surfFlags & (SURF_SKY|SURF_NOMARKS|SURF_NOIMPACT) ) { return; } } VecToAngles( dir, angles ); le = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 6, // 6 is time tcolor[0], tcolor[1], tcolor[2], 1, 250, 0.65, 0.65, 0.65, //white dlight CG_MediaModel( cgs.media.modInstagunWallHit ), NULL ); le->ent.rotation = rand() % 360; le->ent.scale = ( fire_mode == FIRE_MODE_STRONG ) ? 1.5f : 1.0f; // add white energy particles on the impact CG_ImpactPuffParticles( pos, dir, 15, 0.75f, 1, 1, 1, 1, NULL ); trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxElectroboltHit ), pos, CHAN_AUTO, cg_volume_effects->value, ATTN_STATIC ); }
/* * 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 ) ); } }
void CG_SmallPileOfGibs( const vec3_t origin, int damage, const vec3_t initialVelocity, int team ) { lentity_t *le; int i, j, count; vec3_t angles, velocity; int time; if( !cg_gibs->integer ) return; time = 50; count = 14 + cg_gibs->integer; // 15 models minimum clamp( count, 15, 128 ); for( i = 0; i < count; i++ ) { vec4_t color; // coloring switch ( rand( ) % 3 ) { case 0: // orange Vector4Set( color, 1, 0.5, 0, 1 ); break; case 1: // purple Vector4Set( color, 1, 0, 1, 1 ); break; case 2: default: if( ( team == TEAM_ALPHA ) || ( team == TEAM_BETA ) ) { // team CG_TeamColor( team, color ); for( j = 0; j < 3; j++ ) { color[j] = bound( 60.0f / 255.0f, color[j], 1.0f ); } } else { // grey Vector4Set( color, 60.0f / 255.0f, 60.0f / 255.0f, 60.0f / 255.0f, 1.0f ); } break; } le = CG_AllocModel( LE_ALPHA_FADE, origin, vec3_origin, time + time * random( ), color[0], color[1], color[2], color[3], 0, 0, 0, 0, CG_MediaModel( cgs.media.modIlluminatiGibs ), NULL ); // random rotation and scale variations VectorSet( angles, crandom() * 360, crandom() * 360, crandom() * 360 ); AnglesToAxis( angles, le->ent.axis ); le->ent.scale = 0.8f - ( random() * 0.25 ); le->ent.renderfx = RF_FULLBRIGHT|RF_NOSHADOW; velocity[0] = crandom() * 0.5; velocity[1] = crandom() * 0.5; velocity[2] = 0.5 + random() * 0.5; // always have upwards VectorNormalize( velocity ); VectorScale( velocity, min( damage * 10, 300 ), velocity ); velocity[0] += crandom() * bound( 0, damage, 150 ); velocity[1] += crandom() * bound( 0, damage, 150 ); velocity[2] += random() * bound( 0, damage, 250 ); VectorAdd( initialVelocity, velocity, le->velocity ); le->avelocity[0] = random() * 1200; le->avelocity[1] = random() * 1200; le->avelocity[2] = random() * 1200; //friction and gravity VectorSet( le->accel, -0.2f, -0.2f, -900 ); le->bounce = 75; } }