/* ================= CG_HumanBuildableExplosion Called for human buildables as they are destroyed ================= */ void CG_HumanBuildableExplosion( vec3_t origin, vec3_t dir ) { particleSystem_t *ps; trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.humanBuildableExplosion ); //particle system ps = CG_SpawnNewParticleSystem( cgs.media.humanBuildableDestroyedPS ); if( CG_IsParticleSystemValid( &ps ) ) { CG_SetAttachmentPoint( &ps->attachment, origin ); CG_SetParticleSystemNormal( ps, dir ); CG_AttachToPoint( &ps->attachment ); } }
/* ================= CG_Bleed This is the spurt of blood when a character gets hit ================= */ void CG_Bleed( vec3_t origin, vec3_t normal, int entityNum ) { team_t team; qhandle_t bleedPS; particleSystem_t *ps; if( !cg_blood.integer ) return; if( cg_entities[ entityNum ].currentState.eType == ET_PLAYER ) { team = cgs.clientinfo[ entityNum ].team; if( team == TEAM_ALIENS ) bleedPS = cgs.media.alienBleedPS; else if( team == TEAM_HUMANS ) bleedPS = cgs.media.humanBleedPS; else return; } else if( cg_entities[ entityNum ].currentState.eType == ET_BUILDABLE ) { //ew team = BG_Buildable( cg_entities[ entityNum ].currentState.modelindex, NULL )->team; if( team == TEAM_ALIENS ) bleedPS = cgs.media.alienBuildableBleedPS; else if( team == TEAM_HUMANS ) bleedPS = cgs.media.humanBuildableBleedPS; else return; } else return; ps = CG_SpawnNewParticleSystem( bleedPS ); if( CG_IsParticleSystemValid( &ps ) ) { CG_SetAttachmentPoint( &ps->attachment, origin ); CG_SetAttachmentCent( &ps->attachment, &cg_entities[ entityNum ] ); CG_AttachToPoint( &ps->attachment ); CG_SetParticleSystemNormal( ps, normal ); } }
/* =============== CG_DestroyTrailSystem Destroy a trail system =============== */ void CG_DestroyTrailSystem( trailSystem_t **ts ) { ( *ts )->destroyTime = cg.time; if ( CG_Attached( & ( *ts )->frontAttachment ) && !CG_Attached( & ( *ts )->backAttachment ) ) { vec3_t v; // attach the trail head to a static point CG_AttachmentPoint( & ( *ts )->frontAttachment, v ); CG_SetAttachmentPoint( & ( *ts )->frontAttachment, v ); CG_AttachToPoint( & ( *ts )->frontAttachment ); ( *ts )->frontAttachment.centValid = false; // a bit naughty } ts = nullptr; }
/* ============== CG_AddViewWeapon Add the weapon, and flash for the player's view ============== */ void CG_AddViewWeapon( playerState_t *ps ) { refEntity_t hand; centity_t *cent; clientInfo_t *ci; float fovOffset; vec3_t angles; weaponInfo_t *wi; weapon_t weapon = ps->weapon; weaponMode_t weaponMode = ps->generic1; if( weaponMode <= WPM_NONE || weaponMode >= WPM_NUM_WEAPONMODES ) weaponMode = WPM_PRIMARY; CG_RegisterWeapon( weapon ); wi = &cg_weapons[ weapon ]; cent = &cg.predictedPlayerEntity; // &cg_entities[cg.snap->ps.clientNum]; if( ( ps->persistant[PERS_TEAM] == TEAM_SPECTATOR ) || ( ps->stats[ STAT_STATE ] & SS_INFESTING ) || ( ps->stats[ STAT_STATE ] & SS_HOVELING ) ) return; //TA: no weapon carried - can't draw it if( weapon == WP_NONE ) return; if( ps->pm_type == PM_INTERMISSION ) return; //TA: draw a prospective buildable infront of the player if( ( ps->stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT ) > BA_NONE ) CG_GhostBuildable( ps->stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT ); if( weapon == WP_LUCIFER_CANNON && ps->stats[ STAT_MISC ] > 0 ) { if( ps->stats[ STAT_MISC ] > ( LCANNON_TOTAL_CHARGE - ( LCANNON_TOTAL_CHARGE / 3 ) ) ) trap_S_AddLoopingSound( ps->clientNum, ps->origin, vec3_origin, cgs.media.lCannonWarningSound ); } // no gun if in third person view if( cg.renderingThirdPerson ) return; // allow the gun to be completely removed if( !cg_drawGun.integer ) { vec3_t origin; VectorCopy( cg.refdef.vieworg, origin ); VectorMA( origin, -8, cg.refdef.viewaxis[ 2 ], origin ); if( cent->muzzlePS ) CG_SetAttachmentPoint( ¢->muzzlePS->attachment, origin ); //check for particle systems if( wi->wim[ weaponMode ].muzzleParticleSystem && cent->muzzlePsTrigger ) { cent->muzzlePS = CG_SpawnNewParticleSystem( wi->wim[ weaponMode ].muzzleParticleSystem ); if( CG_IsParticleSystemValid( ¢->muzzlePS ) ) { CG_SetAttachmentPoint( ¢->muzzlePS->attachment, origin ); CG_SetAttachmentCent( ¢->muzzlePS->attachment, cent ); CG_AttachToPoint( ¢->muzzlePS->attachment ); } cent->muzzlePsTrigger = qfalse; } return; } // don't draw if testing a gun model if( cg.testGun ) return; // drop gun lower at higher fov //if ( cg_fov.integer > 90 ) { //TA: the client side variable isn't used ( shouldn't iD have done this anyway? ) if( cg.refdef.fov_y > 90 ) fovOffset = -0.4 * ( cg.refdef.fov_y - 90 ); else fovOffset = 0; memset( &hand, 0, sizeof( hand ) ); // set up gun position CG_CalculateWeaponPosition( hand.origin, angles ); VectorMA( hand.origin, cg_gun_x.value, cg.refdef.viewaxis[ 0 ], hand.origin ); VectorMA( hand.origin, cg_gun_y.value, cg.refdef.viewaxis[ 1 ], hand.origin ); VectorMA( hand.origin, ( cg_gun_z.value + fovOffset ), cg.refdef.viewaxis[ 2 ], hand.origin ); if( weapon == WP_LUCIFER_CANNON && ps->stats[ STAT_MISC ] > 0 ) { float fraction = (float)ps->stats[ STAT_MISC ] / (float)LCANNON_TOTAL_CHARGE; VectorMA( hand.origin, random( ) * fraction, cg.refdef.viewaxis[ 0 ], hand.origin ); VectorMA( hand.origin, random( ) * fraction, cg.refdef.viewaxis[ 1 ], hand.origin ); } AnglesToAxis( angles, hand.axis ); // map torso animations to weapon animations if( cg_gun_frame.integer ) { // development tool hand.frame = hand.oldframe = cg_gun_frame.integer; hand.backlerp = 0; } else { // get clientinfo for animation map ci = &cgs.clientinfo[ cent->currentState.clientNum ]; hand.frame = CG_MapTorsoToWeaponFrame( ci, cent->pe.torso.frame ); hand.oldframe = CG_MapTorsoToWeaponFrame( ci, cent->pe.torso.oldFrame ); hand.backlerp = cent->pe.torso.backlerp; } hand.hModel = wi->handsModel; hand.renderfx = RF_DEPTHHACK | RF_FIRST_PERSON | RF_MINLIGHT; // add everything onto the hand CG_AddPlayerWeapon( &hand, ps, &cg.predictedPlayerEntity ); }
/* ================= CG_MissileHitWall Caused by an EV_MISSILE_MISS event, or directly by local bullet tracing ================= */ void CG_MissileHitWall( weapon_t weaponNum, weaponMode_t weaponMode, int clientNum, vec3_t origin, vec3_t dir, impactSound_t soundType ) { qhandle_t mark = 0; qhandle_t ps = 0; int c; float radius = 1.0f; weaponInfo_t *weapon = &cg_weapons[ weaponNum ]; if( weaponMode <= WPM_NONE || weaponMode >= WPM_NUM_WEAPONMODES ) weaponMode = WPM_PRIMARY; mark = weapon->wim[ weaponMode ].impactMark; radius = weapon->wim[ weaponMode ].impactMarkSize; ps = weapon->wim[ weaponMode ].impactParticleSystem; if( soundType == IMPACTSOUND_FLESH ) { //flesh sound for( c = 0; c < 4; c++ ) { if( !weapon->wim[ weaponMode ].impactFleshSound[ c ] ) break; } if( c > 0 ) { c = rand( ) % c; if( weapon->wim[ weaponMode ].impactFleshSound[ c ] ) trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weapon->wim[ weaponMode ].impactFleshSound[ c ] ); } } else { //normal sound for( c = 0; c < 4; c++ ) { if( !weapon->wim[ weaponMode ].impactSound[ c ] ) break; } if( c > 0 ) { c = rand( ) % c; if( weapon->wim[ weaponMode ].impactSound[ c ] ) trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weapon->wim[ weaponMode ].impactSound[ c ] ); } } //create impact particle system if( ps ) { particleSystem_t *partSystem = CG_SpawnNewParticleSystem( ps ); if( CG_IsParticleSystemValid( &partSystem ) ) { CG_SetAttachmentPoint( &partSystem->attachment, origin ); CG_SetParticleSystemNormal( partSystem, dir ); CG_AttachToPoint( &partSystem->attachment ); } } // // impact mark // if( radius > 0.0f ) CG_ImpactMark( mark, origin, dir, random( ) * 360, 1, 1, 1, 1, qfalse, radius, qfalse ); }
void CG_AddViewWeapon( playerState_t *ps ) { refEntity_t hand; centity_t *cent; clientInfo_t *ci; float fovOffset; vec3_t angles; weaponInfo_t *wi; weapon_t weapon = ps->weapon; weaponMode_t weaponMode = ps->generic1; vec3_t cuboidSize; // no weapon carried - can't draw it if( weapon == WP_NONE ) return; if( weaponMode <= WPM_NONE || weaponMode >= WPM_NUM_WEAPONMODES ) weaponMode = WPM_PRIMARY; wi = &cg_weapons[ weapon ]; if( !wi->registered ) { Com_Printf( S_COLOR_YELLOW "WARNING: CG_AddViewWeapon: weapon %d (%s) " "is not registered\n", weapon, BG_Weapon( weapon )->name ); return; } cent = &cg.predictedPlayerEntity; // &cg_entities[cg.snap->ps.clientNum]; if( ps->persistant[PERS_SPECSTATE] != SPECTATOR_NOT ) return; if( ps->pm_type == PM_INTERMISSION ) return; // draw a prospective buildable infront of the player if( ( ps->stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT ) > BA_NONE ) CG_GhostBuildable( ps->stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT, cg.cuboidSelection ); // no gun if in third person view if( cg.renderingThirdPerson ) return; // allow the gun to be completely removed if( !cg_drawGun.integer ) { vec3_t origin; VectorCopy( cg.refdef.vieworg, origin ); VectorMA( origin, -8, cg.refdef.viewaxis[ 2 ], origin ); if( cent->muzzlePS ) CG_SetAttachmentPoint( ¢->muzzlePS->attachment, origin ); //check for particle systems if( wi->wim[ weaponMode ].muzzleParticleSystem && cent->muzzlePsTrigger ) { cent->muzzlePS = CG_SpawnNewParticleSystem( wi->wim[ weaponMode ].muzzleParticleSystem ); if( CG_IsParticleSystemValid( ¢->muzzlePS ) ) { CG_SetAttachmentPoint( ¢->muzzlePS->attachment, origin ); CG_SetAttachmentCent( ¢->muzzlePS->attachment, cent ); CG_AttachToPoint( ¢->muzzlePS->attachment ); } cent->muzzlePsTrigger = qfalse; } return; } // don't draw if testing a gun model if( cg.testGun ) return; // drop gun lower at higher fov if( cg.refdef.fov_y > 90 ) fovOffset = -0.4 * ( cg.refdef.fov_y - 90 ); else fovOffset = 0; Com_Memset( &hand, 0, sizeof( hand ) ); // set up gun position CG_CalculateWeaponPosition( hand.origin, angles ); VectorMA( hand.origin, cg_gun_x.value, cg.refdef.viewaxis[ 0 ], hand.origin ); VectorMA( hand.origin, cg_gun_y.value, cg.refdef.viewaxis[ 1 ], hand.origin ); VectorMA( hand.origin, ( cg_gun_z.value + fovOffset ), cg.refdef.viewaxis[ 2 ], hand.origin ); // Lucifer Cannon vibration effect if( weapon == WP_LUCIFER_CANNON && ps->stats[ STAT_MISC ] > 0 ) { float fraction; fraction = (float)ps->stats[ STAT_MISC ] / LCANNON_CHARGE_TIME_MAX; VectorMA( hand.origin, random( ) * fraction, cg.refdef.viewaxis[ 0 ], hand.origin ); VectorMA( hand.origin, random( ) * fraction, cg.refdef.viewaxis[ 1 ], hand.origin ); } AnglesToAxis( angles, hand.axis ); // map torso animations to weapon animations if( cg_gun_frame.integer ) { // development tool hand.frame = hand.oldframe = cg_gun_frame.integer; hand.backlerp = 0; } else { // get clientinfo for animation map ci = &cgs.clientinfo[ cent->currentState.clientNum ]; hand.frame = CG_MapTorsoToWeaponFrame( ci, cent->pe.torso.frame ); hand.oldframe = CG_MapTorsoToWeaponFrame( ci, cent->pe.torso.oldFrame ); hand.backlerp = cent->pe.torso.backlerp; } hand.hModel = wi->handsModel; hand.renderfx = RF_DEPTHHACK | RF_FIRST_PERSON | RF_MINLIGHT; // add everything onto the hand CG_AddPlayerWeapon( &hand, ps, &cg.predictedPlayerEntity ); }