void CG_EntityEvent( centity_t *cent, vec3_t position ) { entityState_t *es; int event; vec3_t dir; const char *s; int clientNum; clientInfo_t *ci; es = ¢->currentState; event = es->event & ~EV_EVENT_BITS; if ( cg_debugEvents.integer ) { CG_Printf( "ent:%3i event:%3i ", es->number, event ); } if ( !event ) { DEBUGNAME("ZEROEVENT"); return; } clientNum = es->clientNum; if ( clientNum < 0 || clientNum >= MAX_CLIENTS ) { clientNum = 0; } ci = &cgs.clientinfo[ clientNum ]; switch ( event ) { // // movement generated events // case EV_FOOTSTEP: DEBUGNAME("EV_FOOTSTEP"); if (cg_footsteps.integer) { trap_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ ci->footsteps ][rand()&3] ); } break; case EV_FOOTSTEP_METAL: DEBUGNAME("EV_FOOTSTEP_METAL"); if (cg_footsteps.integer) { trap_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_METAL ][rand()&3] ); } break; case EV_FOOTSPLASH: DEBUGNAME("EV_FOOTSPLASH"); if (cg_footsteps.integer) { trap_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3] ); } break; case EV_FOOTWADE: DEBUGNAME("EV_FOOTWADE"); if (cg_footsteps.integer) { trap_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3] ); } break; case EV_SWIM: DEBUGNAME("EV_SWIM"); if (cg_footsteps.integer) { trap_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3] ); } break; case EV_FALL_SHORT: DEBUGNAME("EV_FALL_SHORT"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.landSound ); if ( clientNum == cg.predictedPlayerState.clientNum ) { // smooth landing z changes cg.landChange = -8; cg.landTime = cg.time; } break; case EV_FALL_MEDIUM: DEBUGNAME("EV_FALL_MEDIUM"); // use normal pain sound trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*pain100_1.wav" ) ); if ( clientNum == cg.predictedPlayerState.clientNum ) { // smooth landing z changes cg.landChange = -16; cg.landTime = cg.time; } break; case EV_FALL_FAR: DEBUGNAME("EV_FALL_FAR"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*fall1.wav" ) ); cent->pe.painTime = cg.time; // don't play a pain sound right after this if ( clientNum == cg.predictedPlayerState.clientNum ) { // smooth landing z changes cg.landChange = -24; cg.landTime = cg.time; } break; case EV_STEP_4: case EV_STEP_8: case EV_STEP_12: case EV_STEP_16: // smooth out step up transitions DEBUGNAME("EV_STEP"); { float oldStep; int delta; int step; if ( clientNum != cg.predictedPlayerState.clientNum ) { break; } // if we are interpolating, we don't need to smooth steps if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) || cg_nopredict.integer || cg_synchronousClients.integer ) { break; } // check for stepping up before a previous step is completed delta = cg.time - cg.stepTime; if (delta < STEP_TIME) { oldStep = cg.stepChange * (STEP_TIME - delta) / STEP_TIME; } else { oldStep = 0; } // add this amount step = 4 * (event - EV_STEP_4 + 1 ); cg.stepChange = oldStep + step; if ( cg.stepChange > MAX_STEP_CHANGE ) { cg.stepChange = MAX_STEP_CHANGE; } cg.stepTime = cg.time; break; } case EV_JUMP_PAD: DEBUGNAME("EV_JUMP_PAD"); // CG_Printf( "EV_JUMP_PAD w/effect #%i\n", es->eventParm ); { localEntity_t *smoke; vec3_t up = {0, 0, 1}; smoke = CG_SmokePuff( cent->lerpOrigin, up, 32, 1, 1, 1, 0.33f, 1000, cg.time, 0, LEF_PUFF_DONT_SCALE, cgs.media.smokePuffShader ); } // boing sound at origin, jump sound on player trap_S_StartSound ( cent->lerpOrigin, -1, CHAN_VOICE, cgs.media.jumpPadSound ); trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) ); break; case EV_JUMP: DEBUGNAME("EV_JUMP"); trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) ); break; case EV_TAUNT: DEBUGNAME("EV_TAUNT"); trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*taunt.wav" ) ); break; #ifdef MISSIONPACK case EV_TAUNT_YES: DEBUGNAME("EV_TAUNT_YES"); CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_YES); break; case EV_TAUNT_NO: DEBUGNAME("EV_TAUNT_NO"); CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_NO); break; case EV_TAUNT_FOLLOWME: DEBUGNAME("EV_TAUNT_FOLLOWME"); CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_FOLLOWME); break; case EV_TAUNT_GETFLAG: DEBUGNAME("EV_TAUNT_GETFLAG"); CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONGETFLAG); break; case EV_TAUNT_GUARDBASE: DEBUGNAME("EV_TAUNT_GUARDBASE"); CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONDEFENSE); break; case EV_TAUNT_PATROL: DEBUGNAME("EV_TAUNT_PATROL"); CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONPATROL); break; #endif case EV_WATER_TOUCH: DEBUGNAME("EV_WATER_TOUCH"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrInSound ); break; case EV_WATER_LEAVE: DEBUGNAME("EV_WATER_LEAVE"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrOutSound ); break; case EV_WATER_UNDER: DEBUGNAME("EV_WATER_UNDER"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrUnSound ); break; case EV_WATER_CLEAR: DEBUGNAME("EV_WATER_CLEAR"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*gasp.wav" ) ); break; case EV_ITEM_PICKUP: DEBUGNAME("EV_ITEM_PICKUP"); { gitem_t *item; int index; index = es->eventParm; // player predicted if ( index < 1 || index >= bg_numItems ) { break; } item = &bg_itemlist[ index ]; // powerups and team items will have a separate global sound, this one // will be played at prediction time if ( item->giType == IT_POWERUP || item->giType == IT_TEAM) { trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.n_healthSound ); } else if (item->giType == IT_PERSISTANT_POWERUP) { #ifdef MISSIONPACK switch (item->giTag ) { case PW_SCOUT: trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.scoutSound ); break; case PW_GUARD: trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.guardSound ); break; case PW_DOUBLER: trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.doublerSound ); break; case PW_AMMOREGEN: trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.ammoregenSound ); break; } #endif } else { trap_S_StartSound (NULL, es->number, CHAN_AUTO, trap_S_RegisterSound( item->pickup_sound, qfalse ) ); } // show icon and name on status bar if ( es->number == cg.snap->ps.clientNum ) { CG_ItemPickup( index ); } } break; case EV_GLOBAL_ITEM_PICKUP: DEBUGNAME("EV_GLOBAL_ITEM_PICKUP"); { gitem_t *item; int index; index = es->eventParm; // player predicted if ( index < 1 || index >= bg_numItems ) { break; } item = &bg_itemlist[ index ]; // powerup pickups are global if( item->pickup_sound ) { trap_S_StartSound (NULL, cg.snap->ps.clientNum, CHAN_AUTO, trap_S_RegisterSound( item->pickup_sound, qfalse ) ); } // show icon and name on status bar if ( es->number == cg.snap->ps.clientNum ) { CG_ItemPickup( index ); } } break; // // weapon events // case EV_NOAMMO: DEBUGNAME("EV_NOAMMO"); // trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.noAmmoSound ); if ( es->number == cg.snap->ps.clientNum ) { CG_OutOfAmmoChange(); } break; case EV_CHANGE_WEAPON: DEBUGNAME("EV_CHANGE_WEAPON"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.selectSound ); break; case EV_FIRE_WEAPON: DEBUGNAME("EV_FIRE_WEAPON"); CG_FireWeapon( cent ); break; case EV_USE_ITEM0: DEBUGNAME("EV_USE_ITEM0"); CG_UseItem( cent ); break; case EV_USE_ITEM1: DEBUGNAME("EV_USE_ITEM1"); CG_UseItem( cent ); break; case EV_USE_ITEM2: DEBUGNAME("EV_USE_ITEM2"); CG_UseItem( cent ); break; case EV_USE_ITEM3: DEBUGNAME("EV_USE_ITEM3"); CG_UseItem( cent ); break; case EV_USE_ITEM4: DEBUGNAME("EV_USE_ITEM4"); CG_UseItem( cent ); break; case EV_USE_ITEM5: DEBUGNAME("EV_USE_ITEM5"); CG_UseItem( cent ); break; case EV_USE_ITEM6: DEBUGNAME("EV_USE_ITEM6"); CG_UseItem( cent ); break; case EV_USE_ITEM7: DEBUGNAME("EV_USE_ITEM7"); CG_UseItem( cent ); break; case EV_USE_ITEM8: DEBUGNAME("EV_USE_ITEM8"); CG_UseItem( cent ); break; case EV_USE_ITEM9: DEBUGNAME("EV_USE_ITEM9"); CG_UseItem( cent ); break; case EV_USE_ITEM10: DEBUGNAME("EV_USE_ITEM10"); CG_UseItem( cent ); break; case EV_USE_ITEM11: DEBUGNAME("EV_USE_ITEM11"); CG_UseItem( cent ); break; case EV_USE_ITEM12: DEBUGNAME("EV_USE_ITEM12"); CG_UseItem( cent ); break; case EV_USE_ITEM13: DEBUGNAME("EV_USE_ITEM13"); CG_UseItem( cent ); break; case EV_USE_ITEM14: DEBUGNAME("EV_USE_ITEM14"); CG_UseItem( cent ); break; //================================================================= // // other events // case EV_PLAYER_TELEPORT_IN: DEBUGNAME("EV_PLAYER_TELEPORT_IN"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.teleInSound ); CG_SpawnEffect( position); break; case EV_PLAYER_TELEPORT_OUT: DEBUGNAME("EV_PLAYER_TELEPORT_OUT"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.teleOutSound ); CG_SpawnEffect( position); break; case EV_ITEM_POP: DEBUGNAME("EV_ITEM_POP"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.respawnSound ); break; case EV_ITEM_RESPAWN: DEBUGNAME("EV_ITEM_RESPAWN"); cent->miscTime = cg.time; // scale up from this trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.respawnSound ); break; case EV_GRENADE_BOUNCE: DEBUGNAME("EV_GRENADE_BOUNCE"); if ( rand() & 1 ) { trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.hgrenb1aSound ); } else { trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.hgrenb2aSound ); } break; case EV_PROXIMITY_MINE_STICK: DEBUGNAME("EV_PROXIMITY_MINE_STICK"); if( es->eventParm & SURF_FLESH ) { trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimplSound ); } else if( es->eventParm & SURF_METALSTEPS ) { trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimpmSound ); } else { trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimpdSound ); } break; case EV_PROXIMITY_MINE_TRIGGER: DEBUGNAME("EV_PROXIMITY_MINE_TRIGGER"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbactvSound ); break; case EV_KAMIKAZE: DEBUGNAME("EV_KAMIKAZE"); CG_KamikazeEffect( cent->lerpOrigin ); break; case EV_OBELISKEXPLODE: DEBUGNAME("EV_OBELISKEXPLODE"); CG_ObeliskExplode( cent->lerpOrigin, es->eventParm ); break; case EV_OBELISKPAIN: DEBUGNAME("EV_OBELISKPAIN"); CG_ObeliskPain( cent->lerpOrigin ); break; case EV_INVUL_IMPACT: DEBUGNAME("EV_INVUL_IMPACT"); CG_InvulnerabilityImpact( cent->lerpOrigin, cent->currentState.angles ); break; case EV_JUICED: DEBUGNAME("EV_JUICED"); CG_InvulnerabilityJuiced( cent->lerpOrigin ); break; case EV_LIGHTNINGBOLT: DEBUGNAME("EV_LIGHTNINGBOLT"); CG_LightningBoltBeam(es->origin2, es->pos.trBase); break; case EV_SCOREPLUM: DEBUGNAME("EV_SCOREPLUM"); CG_ScorePlum( cent->currentState.otherEntityNum, cent->lerpOrigin, cent->currentState.time ); break; // // missile impacts // case EV_MISSILE_HIT: DEBUGNAME("EV_MISSILE_HIT"); ByteToDir( es->eventParm, dir ); CG_MissileHitPlayer( es->weapon, position, dir, es->otherEntityNum ); break; case EV_MISSILE_MISS: DEBUGNAME("EV_MISSILE_MISS"); ByteToDir( es->eventParm, dir ); CG_MissileHitWall( es->weapon, 0, position, dir, IMPACTSOUND_DEFAULT ); break; case EV_MISSILE_MISS_METAL: DEBUGNAME("EV_MISSILE_MISS_METAL"); ByteToDir( es->eventParm, dir ); CG_MissileHitWall( es->weapon, 0, position, dir, IMPACTSOUND_METAL ); break; case EV_RAILTRAIL: DEBUGNAME("EV_RAILTRAIL"); cent->currentState.weapon = WP_RAILGUN; //unlagged - attack prediction #2 // if the client is us, unlagged is on server-side, and we've got it client-side if ( es->clientNum == cg.predictedPlayerState.clientNum && cgs.delagHitscan && (cg_delag.integer & 1 || cg_delag.integer & 16) ) { // do nothing, because it was already predicted //Com_Printf("Ignoring rail trail event\n"); } else { if(es->clientNum == cg.snap->ps.clientNum && !cg.renderingThirdPerson) { if(cg_drawGun.integer == 2) VectorMA(es->origin2, 8, cg.refdef.viewaxis[1], es->origin2); else if(cg_drawGun.integer == 3) VectorMA(es->origin2, 4, cg.refdef.viewaxis[1], es->origin2); } // draw a rail trail, because it wasn't predicted CG_RailTrail( ci, es->origin2, es->pos.trBase ); // if the end was on a nomark surface, don't make an explosion if ( es->eventParm != 255 ) { ByteToDir( es->eventParm, dir ); CG_MissileHitWall( es->weapon, es->clientNum, position, dir, IMPACTSOUND_DEFAULT ); } //Com_Printf("Non-predicted rail trail\n"); } //unlagged - attack prediction #2 break; case EV_BULLET_HIT_WALL: DEBUGNAME("EV_BULLET_HIT_WALL"); //unlagged - attack prediction #2 // if the client is us, unlagged is on server-side, and we've got it client-side if ( es->clientNum == cg.predictedPlayerState.clientNum && cgs.delagHitscan && (cg_delag.integer & 1 || cg_delag.integer & 2) ) { // do nothing, because it was already predicted //Com_Printf("Ignoring bullet event\n"); } else { // do the bullet, because it wasn't predicted ByteToDir( es->eventParm, dir ); CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD ); //Com_Printf("Non-predicted bullet\n"); } //unlagged - attack prediction #2 break; case EV_BULLET_HIT_FLESH: DEBUGNAME("EV_BULLET_HIT_FLESH"); //unlagged - attack prediction #2 // if the client is us, unlagged is on server-side, and we've got it client-side if ( es->clientNum == cg.predictedPlayerState.clientNum && cgs.delagHitscan && (cg_delag.integer & 1 || cg_delag.integer & 2) ) { // do nothing, because it was already predicted //Com_Printf("Ignoring bullet event\n"); } else { // do the bullet, because it wasn't predicted CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qtrue, es->eventParm ); //Com_Printf("Non-predicted bullet\n"); } //unlagged - attack prediction #2 break; case EV_SHOTGUN: DEBUGNAME("EV_SHOTGUN"); //unlagged - attack prediction #2 // if the client is us, unlagged is on server-side, and we've got it client-side if ( es->otherEntityNum == cg.predictedPlayerState.clientNum && cgs.delagHitscan && (cg_delag.integer & 1 || cg_delag.integer & 4) ) { // do nothing, because it was already predicted //Com_Printf("Ignoring shotgun event\n"); } else { // do the shotgun pattern, because it wasn't predicted CG_ShotgunFire( es ); //Com_Printf("Non-predicted shotgun pattern\n"); } //unlagged - attack prediction #2 break; case EV_GENERAL_SOUND: DEBUGNAME("EV_GENERAL_SOUND"); if ( cgs.gameSounds[ es->eventParm ] ) { trap_S_StartSound (NULL, es->number, CHAN_VOICE, cgs.gameSounds[ es->eventParm ] ); } else { s = CG_ConfigString( CS_SOUNDS + es->eventParm ); trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, s ) ); } break; case EV_GLOBAL_SOUND: // play from the player's head so it never diminishes DEBUGNAME("EV_GLOBAL_SOUND"); if ( cgs.gameSounds[ es->eventParm ] ) { trap_S_StartSound (NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.gameSounds[ es->eventParm ] ); } else { s = CG_ConfigString( CS_SOUNDS + es->eventParm ); trap_S_StartSound (NULL, cg.snap->ps.clientNum, CHAN_AUTO, CG_CustomSound( es->number, s ) ); } break; case EV_GLOBAL_TEAM_SOUND: // play from the player's head so it never diminishes { DEBUGNAME("EV_GLOBAL_TEAM_SOUND"); switch( es->eventParm ) { case GTS_RED_CAPTURE: // CTF: red team captured the blue flag, 1FCTF: red team captured the neutral flag if ( cgs.clientinfo[cg.clientNum].team == TEAM_RED ) CG_AddBufferedSound( cgs.media.captureYourTeamSound ); else CG_AddBufferedSound( cgs.media.captureOpponentSound ); break; case GTS_BLUE_CAPTURE: // CTF: blue team captured the red flag, 1FCTF: blue team captured the neutral flag if ( cgs.clientinfo[cg.clientNum].team == TEAM_BLUE ) CG_AddBufferedSound( cgs.media.captureYourTeamSound ); else CG_AddBufferedSound( cgs.media.captureOpponentSound ); break; case GTS_RED_RETURN: // CTF: blue flag returned, 1FCTF: never used if ( cgs.clientinfo[cg.clientNum].team == TEAM_RED ) CG_AddBufferedSound( cgs.media.returnYourTeamSound ); else CG_AddBufferedSound( cgs.media.returnOpponentSound ); // CG_AddBufferedSound( cgs.media.blueFlagReturnedSound ); break; case GTS_BLUE_RETURN: // CTF red flag returned, 1FCTF: neutral flag returned if ( cgs.clientinfo[cg.clientNum].team == TEAM_BLUE ) CG_AddBufferedSound( cgs.media.returnYourTeamSound ); else CG_AddBufferedSound( cgs.media.returnOpponentSound ); // CG_AddBufferedSound( cgs.media.redFlagReturnedSound ); break; case GTS_RED_TAKEN: // CTF: red team took blue flag, 1FCTF: blue team took the neutral flag // if this player picked up the flag then a sound is played in CG_CheckLocalSounds if (cg.snap->ps.powerups[PW_BLUEFLAG] || cg.snap->ps.powerups[PW_NEUTRALFLAG]) { } else { if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) { //#ifdef MISSIONPACK if (cgs.gametype == GT_1FCTF) CG_AddBufferedSound( cgs.media.yourTeamTookTheFlagSound ); else //#endif CG_AddBufferedSound( cgs.media.enemyTookYourFlagSound ); } else if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) { //#ifdef MISSIONPACK if (cgs.gametype == GT_1FCTF) CG_AddBufferedSound( cgs.media.enemyTookTheFlagSound ); else //#endif CG_AddBufferedSound( cgs.media.yourTeamTookEnemyFlagSound ); } } break; case GTS_BLUE_TAKEN: // CTF: blue team took the red flag, 1FCTF red team took the neutral flag // if this player picked up the flag then a sound is played in CG_CheckLocalSounds if (cg.snap->ps.powerups[PW_REDFLAG] || cg.snap->ps.powerups[PW_NEUTRALFLAG]) { } else { if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) { //#ifdef MISSIONPACK if (cgs.gametype == GT_1FCTF) CG_AddBufferedSound( cgs.media.yourTeamTookTheFlagSound ); else //#endif CG_AddBufferedSound( cgs.media.enemyTookYourFlagSound ); } else if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) { //#ifdef MISSIONPACK if (cgs.gametype == GT_1FCTF) CG_AddBufferedSound( cgs.media.enemyTookTheFlagSound ); else //#endif CG_AddBufferedSound( cgs.media.yourTeamTookEnemyFlagSound ); } } break; case GTS_REDOBELISK_ATTACKED: // Overload: red obelisk is being attacked if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) { CG_AddBufferedSound( cgs.media.yourBaseIsUnderAttackSound ); } break; case GTS_BLUEOBELISK_ATTACKED: // Overload: blue obelisk is being attacked if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) { CG_AddBufferedSound( cgs.media.yourBaseIsUnderAttackSound ); } break; case GTS_REDTEAM_SCORED: CG_AddBufferedSound(cgs.media.redScoredSound); break; case GTS_BLUETEAM_SCORED: CG_AddBufferedSound(cgs.media.blueScoredSound); break; case GTS_REDTEAM_TOOK_LEAD: CG_AddBufferedSound(cgs.media.redLeadsSound); break; case GTS_BLUETEAM_TOOK_LEAD: CG_AddBufferedSound(cgs.media.blueLeadsSound); break; case GTS_TEAMS_ARE_TIED: CG_AddBufferedSound( cgs.media.teamsTiedSound ); break; case GTS_KAMIKAZE: trap_S_StartLocalSound(cgs.media.kamikazeFarSound, CHAN_ANNOUNCER); break; default: break; } break; } case EV_PAIN: // local player sounds are triggered in CG_CheckLocalSounds, // so ignore events on the player DEBUGNAME("EV_PAIN"); if ( cent->currentState.number != cg.snap->ps.clientNum ) { CG_PainEvent( cent, es->eventParm ); } break; case EV_DEATH1: case EV_DEATH2: case EV_DEATH3: DEBUGNAME("EV_DEATHx"); if (CG_WaterLevel(cent) >= 1) { trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, "*drown.wav")); } else { trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, va("*death%i.wav", event - EV_DEATH1 + 1))); } break; case EV_OBITUARY: DEBUGNAME("EV_OBITUARY"); CG_Obituary( es ); break; // // powerup events // case EV_POWERUP_QUAD: DEBUGNAME("EV_POWERUP_QUAD"); if ( es->number == cg.snap->ps.clientNum ) { cg.powerupActive = PW_QUAD; cg.powerupTime = cg.time; } trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.quadSound ); break; case EV_POWERUP_BATTLESUIT: DEBUGNAME("EV_POWERUP_BATTLESUIT"); if ( es->number == cg.snap->ps.clientNum ) { cg.powerupActive = PW_BATTLESUIT; cg.powerupTime = cg.time; } trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.protectSound ); break; case EV_POWERUP_REGEN: DEBUGNAME("EV_POWERUP_REGEN"); if ( es->number == cg.snap->ps.clientNum ) { cg.powerupActive = PW_REGEN; cg.powerupTime = cg.time; } trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.regenSound ); break; case EV_GIB_PLAYER: DEBUGNAME("EV_GIB_PLAYER"); // don't play gib sound when using the kamikaze because it interferes // with the kamikaze sound, downside is that the gib sound will also // not be played when someone is gibbed while just carrying the kamikaze if ( !(es->eFlags & EF_KAMIKAZE) ) { trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.gibSound ); } CG_GibPlayer( cent->lerpOrigin ); break; case EV_STOPLOOPINGSOUND: DEBUGNAME("EV_STOPLOOPINGSOUND"); trap_S_StopLoopingSound( es->number ); es->loopSound = 0; break; case EV_DEBUG_LINE: DEBUGNAME("EV_DEBUG_LINE"); CG_Beam( cent ); break; default: DEBUGNAME("UNKNOWN"); CG_Error( "Unknown event: %i", event ); break; } }
void CG_EntityEvent( centity_t *cent, vec3_t position ) { entityState_t *es; int event; vec3_t dir; const char *s; int playerNum; playerInfo_t *pi; int i; es = ¢->currentState; event = es->event & ~EV_EVENT_BITS; if ( cg_debugEvents.integer ) { CG_Printf( "ent:%3i event:%3i ", es->number, event ); } if ( !event ) { DEBUGNAME("ZEROEVENT"); return; } playerNum = es->playerNum; if ( playerNum < 0 || playerNum >= MAX_CLIENTS ) { playerNum = 0; } pi = &cgs.playerinfo[ playerNum ]; switch ( event ) { // // movement generated events // case EV_FOOTSTEP: DEBUGNAME("EV_FOOTSTEP"); if (cg_footsteps.integer) { trap_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ pi->footsteps ][rand()&3] ); } break; case EV_FOOTSTEP_METAL: DEBUGNAME("EV_FOOTSTEP_METAL"); if (cg_footsteps.integer) { trap_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_METAL ][rand()&3] ); } break; case EV_FOOTSPLASH: DEBUGNAME("EV_FOOTSPLASH"); if (cg_footsteps.integer) { trap_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3] ); } break; case EV_FOOTWADE: DEBUGNAME("EV_FOOTWADE"); if (cg_footsteps.integer) { trap_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3] ); } break; case EV_SWIM: DEBUGNAME("EV_SWIM"); if (cg_footsteps.integer) { trap_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3] ); } break; case EV_FALL_SHORT: DEBUGNAME("EV_FALL_SHORT"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.landSound ); for (i = 0; i < CG_MaxSplitView(); i++) { if ( playerNum == cg.snap->pss[i].playerNum ) { // smooth landing z changes cg.localPlayers[i].landChange = -8; cg.localPlayers[i].landTime = cg.time; } } break; case EV_FALL_MEDIUM: DEBUGNAME("EV_FALL_MEDIUM"); // use normal pain sound if (cgs.fallDamage) { trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*pain100_1.wav" ) ); } else { trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.landSound ); } for (i = 0; i < CG_MaxSplitView(); i++) { if ( playerNum == cg.snap->pss[i].playerNum ) { // smooth landing z changes cg.localPlayers[i].landChange = -16; cg.localPlayers[i].landTime = cg.time; } } break; case EV_FALL_FAR: DEBUGNAME("EV_FALL_FAR"); if (cgs.fallDamage) { trap_S_StartSound (NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*fall1.wav" ) ); } else { trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.landSound ); } cent->pe.painTime = cg.time; // don't play a pain sound right after this for (i = 0; i < CG_MaxSplitView(); i++) { if ( playerNum == cg.snap->pss[i].playerNum ) { // smooth landing z changes cg.localPlayers[i].landChange = -24; cg.localPlayers[i].landTime = cg.time; } } break; case EV_STEP_4: case EV_STEP_8: case EV_STEP_12: case EV_STEP_16: // smooth out step up transitions DEBUGNAME("EV_STEP"); { float oldStep; int delta; int step; localPlayer_t *player; playerState_t *ps; for (i = 0; i < CG_MaxSplitView(); i++) { player = &cg.localPlayers[i]; ps = &cg.snap->pss[i]; if ( playerNum != ps->playerNum ) { continue; } // if we are interpolating, we don't need to smooth steps if ( cg.demoPlayback || (ps->pm_flags & PMF_FOLLOW) || cg_nopredict.integer || cg_synchronousClients.integer ) { continue; } // check for stepping up before a previous step is completed delta = cg.time - player->stepTime; if (delta < STEP_TIME) { oldStep = player->stepChange * (STEP_TIME - delta) / STEP_TIME; } else { oldStep = 0; } // add this amount step = 4 * (event - EV_STEP_4 + 1 ); player->stepChange = oldStep + step; if ( player->stepChange > MAX_STEP_CHANGE ) { player->stepChange = MAX_STEP_CHANGE; } player->stepTime = cg.time; } break; } case EV_JUMP_PAD: DEBUGNAME("EV_JUMP_PAD"); // CG_Printf( "EV_JUMP_PAD w/effect #%i\n", es->eventParm ); { vec3_t up = {0, 0, 1}; CG_SmokePuff( cent->lerpOrigin, up, 32, 1, 1, 1, 0.33f, 1000, cg.time, 0, LEF_PUFF_DONT_SCALE, cgs.media.smokePuffShader ); } // boing sound at origin, jump sound on player trap_S_StartSound ( cent->lerpOrigin, -1, CHAN_VOICE, cgs.media.jumpPadSound ); trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) ); break; case EV_JUMP: DEBUGNAME("EV_JUMP"); trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) ); break; case EV_TAUNT: DEBUGNAME("EV_TAUNT"); trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*taunt.wav" ) ); break; #ifdef MISSIONPACK case EV_TAUNT_YES: DEBUGNAME("EV_TAUNT_YES"); CG_VoiceChatLocal(~0, SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_YES); break; case EV_TAUNT_NO: DEBUGNAME("EV_TAUNT_NO"); CG_VoiceChatLocal(~0, SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_NO); break; case EV_TAUNT_FOLLOWME: DEBUGNAME("EV_TAUNT_FOLLOWME"); CG_VoiceChatLocal(~0, SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_FOLLOWME); break; case EV_TAUNT_GETFLAG: DEBUGNAME("EV_TAUNT_GETFLAG"); CG_VoiceChatLocal(~0, SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONGETFLAG); break; case EV_TAUNT_GUARDBASE: DEBUGNAME("EV_TAUNT_GUARDBASE"); CG_VoiceChatLocal(~0, SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONDEFENSE); break; case EV_TAUNT_PATROL: DEBUGNAME("EV_TAUNT_PATROL"); CG_VoiceChatLocal(~0, SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONPATROL); break; #endif case EV_WATER_TOUCH: DEBUGNAME("EV_WATER_TOUCH"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrInSound ); break; case EV_WATER_LEAVE: DEBUGNAME("EV_WATER_LEAVE"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrOutSound ); break; case EV_WATER_UNDER: DEBUGNAME("EV_WATER_UNDER"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrUnSound ); break; case EV_WATER_CLEAR: DEBUGNAME("EV_WATER_CLEAR"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*gasp.wav" ) ); break; case EV_ITEM_PICKUP: DEBUGNAME("EV_ITEM_PICKUP"); { gitem_t *item; int index; index = es->eventParm; // player predicted if ( index < 1 || index >= BG_NumItems() ) { break; } item = BG_ItemForItemNum( index ); // powerups and team items will have a separate global sound, this one // will be played at prediction time if ( item->giType == IT_POWERUP || item->giType == IT_TEAM) { trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.n_healthSound ); } else if (item->giType == IT_PERSISTANT_POWERUP) { #ifdef MISSIONPACK switch (item->giTag ) { case PW_SCOUT: trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.scoutSound ); break; case PW_GUARD: trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.guardSound ); break; case PW_DOUBLER: trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.doublerSound ); break; case PW_AMMOREGEN: trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.ammoregenSound ); break; } #endif } else { trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.itemPickupSounds[ index ] ); } // show icon and name on status bar for (i = 0; i < CG_MaxSplitView(); i++) { if ( es->number == cg.snap->pss[i].playerNum ) { CG_ItemPickup( i, index ); } } } break; case EV_GLOBAL_ITEM_PICKUP: DEBUGNAME("EV_GLOBAL_ITEM_PICKUP"); { int index; index = es->eventParm; // player predicted if ( index < 1 || index >= BG_NumItems() ) { break; } // powerup pickups are global trap_S_StartLocalSound( cgs.media.itemPickupSounds[ index ], CHAN_AUTO ); // show icon and name on status bar for (i = 0; i < CG_MaxSplitView(); i++) { if ( es->number == cg.snap->pss[i].playerNum ) { CG_ItemPickup( i, index ); } } } break; // // weapon events // case EV_NOAMMO: DEBUGNAME("EV_NOAMMO"); // trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.noAmmoSound ); for (i = 0; i < CG_MaxSplitView(); i++) { if ( es->number == cg.snap->pss[i].playerNum ) { CG_OutOfAmmoChange(i); } } break; case EV_CHANGE_WEAPON: DEBUGNAME("EV_CHANGE_WEAPON"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.selectSound ); break; case EV_FIRE_WEAPON: DEBUGNAME("EV_FIRE_WEAPON"); CG_FireWeapon( cent ); break; case EV_USE_ITEM0: case EV_USE_ITEM1: case EV_USE_ITEM2: case EV_USE_ITEM3: case EV_USE_ITEM4: case EV_USE_ITEM5: case EV_USE_ITEM6: case EV_USE_ITEM7: case EV_USE_ITEM8: case EV_USE_ITEM9: case EV_USE_ITEM10: case EV_USE_ITEM11: case EV_USE_ITEM12: case EV_USE_ITEM13: case EV_USE_ITEM14: case EV_USE_ITEM15: DEBUGNAME2("EV_USE_ITEM%d", event - EV_USE_ITEM0); CG_UseItem( cent ); break; //================================================================= // // other events // case EV_PLAYER_TELEPORT_IN: DEBUGNAME("EV_PLAYER_TELEPORT_IN"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.teleInSound ); CG_SpawnEffect( position); break; case EV_PLAYER_TELEPORT_OUT: DEBUGNAME("EV_PLAYER_TELEPORT_OUT"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.teleOutSound ); CG_SpawnEffect( position); break; case EV_ITEM_POP: DEBUGNAME("EV_ITEM_POP"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.respawnSound ); break; case EV_ITEM_RESPAWN: DEBUGNAME("EV_ITEM_RESPAWN"); cent->miscTime = cg.time; // scale up from this trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.respawnSound ); break; case EV_GRENADE_BOUNCE: DEBUGNAME("EV_GRENADE_BOUNCE"); if ( rand() & 1 ) { trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.hgrenb1aSound ); } else { trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.hgrenb2aSound ); } break; #ifdef MISSIONPACK case EV_PROXIMITY_MINE_STICK: DEBUGNAME("EV_PROXIMITY_MINE_STICK"); if( es->eventParm & SURF_FLESH ) { trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimplSound ); } else if( es->eventParm & SURF_METALSTEPS ) { trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimpmSound ); } else { trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimpdSound ); } break; case EV_PROXIMITY_MINE_TRIGGER: DEBUGNAME("EV_PROXIMITY_MINE_TRIGGER"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbactvSound ); break; case EV_KAMIKAZE: DEBUGNAME("EV_KAMIKAZE"); CG_KamikazeEffect( cent->lerpOrigin ); break; case EV_OBELISKEXPLODE: DEBUGNAME("EV_OBELISKEXPLODE"); CG_ObeliskExplode( cent->lerpOrigin, es->eventParm ); break; case EV_OBELISKPAIN: DEBUGNAME("EV_OBELISKPAIN"); CG_ObeliskPain( cent->lerpOrigin ); break; case EV_INVUL_IMPACT: DEBUGNAME("EV_INVUL_IMPACT"); CG_InvulnerabilityImpact( cent->lerpOrigin, cent->currentState.angles ); break; case EV_JUICED: DEBUGNAME("EV_JUICED"); CG_InvulnerabilityJuiced( cent->lerpOrigin ); break; case EV_LIGHTNINGBOLT: DEBUGNAME("EV_LIGHTNINGBOLT"); CG_LightningBoltBeam(es->origin2, es->pos.trBase); break; #endif case EV_SCOREPLUM: DEBUGNAME("EV_SCOREPLUM"); CG_ScorePlum( cent->currentState.otherEntityNum, cent->lerpOrigin, cent->currentState.time ); break; // // missile impacts // case EV_MISSILE_HIT: DEBUGNAME("EV_MISSILE_HIT"); ByteToDir( es->eventParm, dir ); CG_MissileHitPlayer( es->weapon, position, dir, es->otherEntityNum ); break; case EV_MISSILE_MISS: DEBUGNAME("EV_MISSILE_MISS"); ByteToDir( es->eventParm, dir ); CG_MissileHitWall( es->weapon, 0, position, dir, IMPACTSOUND_DEFAULT ); break; case EV_MISSILE_MISS_METAL: DEBUGNAME("EV_MISSILE_MISS_METAL"); ByteToDir( es->eventParm, dir ); CG_MissileHitWall( es->weapon, 0, position, dir, IMPACTSOUND_METAL ); break; case EV_RAILTRAIL: DEBUGNAME("EV_RAILTRAIL"); cent->currentState.weapon = WP_RAILGUN; if ( es->playerNum >= 0 && es->playerNum < MAX_CLIENTS ) { for (i = 0; i < CG_MaxSplitView(); i++) { if ( es->playerNum == cg.snap->pss[i].playerNum && !cg.localPlayers[i].renderingThirdPerson) { if(cg_drawGun[i].integer == 2) VectorMA(es->origin2, 8, cg.refdef.viewaxis[1], es->origin2); else if(cg_drawGun[i].integer == 3) VectorMA(es->origin2, 4, cg.refdef.viewaxis[1], es->origin2); break; } } } CG_RailTrail(pi, es->origin2, es->pos.trBase); // if the end was on a nomark surface, don't make an explosion if ( es->eventParm != 255 ) { ByteToDir( es->eventParm, dir ); CG_MissileHitWall( es->weapon, es->playerNum, position, dir, IMPACTSOUND_DEFAULT ); } break; case EV_BULLET_HIT_WALL: DEBUGNAME("EV_BULLET_HIT_WALL"); ByteToDir( es->eventParm, dir ); CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD ); break; case EV_BULLET_HIT_FLESH: DEBUGNAME("EV_BULLET_HIT_FLESH"); CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qtrue, es->eventParm ); break; case EV_SHOTGUN: DEBUGNAME("EV_SHOTGUN"); CG_ShotgunFire( es ); break; case EV_GENERAL_SOUND: DEBUGNAME("EV_GENERAL_SOUND"); if ( cgs.gameSounds[ es->eventParm ] ) { trap_S_StartSound (NULL, es->number, CHAN_VOICE, cgs.gameSounds[ es->eventParm ] ); } else { s = CG_ConfigString( CS_SOUNDS + es->eventParm ); trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, s ) ); } break; case EV_GLOBAL_SOUND: // play as a local sound so it never diminishes DEBUGNAME("EV_GLOBAL_SOUND"); if ( cgs.gameSounds[ es->eventParm ] ) { trap_S_StartLocalSound( cgs.gameSounds[ es->eventParm ], CHAN_AUTO ); } else { s = CG_ConfigString( CS_SOUNDS + es->eventParm ); trap_S_StartLocalSound( CG_CustomSound( es->number, s ), CHAN_AUTO ); } break; case EV_GLOBAL_TEAM_SOUND: // play as a local sound so it never diminishes DEBUGNAME("EV_GLOBAL_TEAM_SOUND"); { qboolean blueTeam = qfalse; qboolean redTeam = qfalse; qboolean localHasBlue = qfalse; qboolean localHasRed = qfalse; qboolean localHasNeutral = qfalse; // Check if any local player is on blue/red team or has flags. for (i = 0; i < CG_MaxSplitView(); i++) { if (cg.snap->playerNums[i] == -1) { continue; } if (cg.snap->pss[i].persistant[PERS_TEAM] == TEAM_BLUE) { blueTeam = qtrue; } if (cg.snap->pss[i].persistant[PERS_TEAM] == TEAM_RED) { redTeam = qtrue; } if (cg.snap->pss[i].powerups[PW_BLUEFLAG]) { localHasBlue = qtrue; } if (cg.snap->pss[i].powerups[PW_REDFLAG]) { localHasRed = qtrue; } if (cg.snap->pss[i].powerups[PW_NEUTRALFLAG]) { localHasNeutral = qtrue; } } // ZTM: NOTE: Some of these sounds don't really work with local player on different teams. // New games might want to replace you/enemy sounds with red/blue. // See http://github.com/zturtleman/spearmint/wiki/New-Sounds switch( es->eventParm ) { case GTS_RED_CAPTURE: // CTF: red team captured the blue flag, 1FCTF: red team captured the neutral flag if ( redTeam ) CG_AddBufferedSound( cgs.media.captureYourTeamSound ); else CG_AddBufferedSound( cgs.media.captureOpponentSound ); break; case GTS_BLUE_CAPTURE: // CTF: blue team captured the red flag, 1FCTF: blue team captured the neutral flag if ( blueTeam ) CG_AddBufferedSound( cgs.media.captureYourTeamSound ); else CG_AddBufferedSound( cgs.media.captureOpponentSound ); break; case GTS_RED_RETURN: // CTF: blue flag returned, 1FCTF: never used if ( redTeam ) CG_AddBufferedSound( cgs.media.returnYourTeamSound ); else CG_AddBufferedSound( cgs.media.returnOpponentSound ); // CG_AddBufferedSound( cgs.media.blueFlagReturnedSound ); break; case GTS_BLUE_RETURN: // CTF red flag returned, 1FCTF: neutral flag returned if ( blueTeam ) CG_AddBufferedSound( cgs.media.returnYourTeamSound ); else CG_AddBufferedSound( cgs.media.returnOpponentSound ); // CG_AddBufferedSound( cgs.media.redFlagReturnedSound ); break; case GTS_RED_TAKEN: // CTF: red team took blue flag, 1FCTF: blue team took the neutral flag // if this player picked up the flag then a sound is played in CG_CheckLocalSounds if (localHasBlue || localHasNeutral) { } else if (!(redTeam && blueTeam)) { if (blueTeam) { #ifdef MISSIONPACK if (cgs.gametype == GT_1FCTF) CG_AddBufferedSound( cgs.media.yourTeamTookTheFlagSound ); else #endif CG_AddBufferedSound( cgs.media.enemyTookYourFlagSound ); } else if (redTeam) { #ifdef MISSIONPACK if (cgs.gametype == GT_1FCTF) CG_AddBufferedSound( cgs.media.enemyTookTheFlagSound ); else #endif CG_AddBufferedSound( cgs.media.yourTeamTookEnemyFlagSound ); } } else { // ZTM: NOTE: There are local players on both teams, so have no correct sound to play. New games should fix this. } break; case GTS_BLUE_TAKEN: // CTF: blue team took the red flag, 1FCTF red team took the neutral flag // if this player picked up the flag then a sound is played in CG_CheckLocalSounds if (localHasRed || localHasNeutral) { } else if (!(redTeam && blueTeam)) { if (redTeam) { #ifdef MISSIONPACK if (cgs.gametype == GT_1FCTF) CG_AddBufferedSound( cgs.media.yourTeamTookTheFlagSound ); else #endif CG_AddBufferedSound( cgs.media.enemyTookYourFlagSound ); } else if (blueTeam) { #ifdef MISSIONPACK if (cgs.gametype == GT_1FCTF) CG_AddBufferedSound( cgs.media.enemyTookTheFlagSound ); else #endif CG_AddBufferedSound( cgs.media.yourTeamTookEnemyFlagSound ); } } else { // ZTM: NOTE: There are local players on both teams, so have no correct sound to play. New games should fix this. } break; #ifdef MISSIONPACK // ZTM: NOTE: These are confusing when there are players on both teams (players don't know which base is attacked). New games should fix this. case GTS_REDOBELISK_ATTACKED: // Overload: red obelisk is being attacked if (redTeam) { CG_AddBufferedSound( cgs.media.yourBaseIsUnderAttackSound ); } break; case GTS_BLUEOBELISK_ATTACKED: // Overload: blue obelisk is being attacked if (blueTeam) { CG_AddBufferedSound( cgs.media.yourBaseIsUnderAttackSound ); } break; #endif case GTS_REDTEAM_SCORED: CG_AddBufferedSound(cgs.media.redScoredSound); break; case GTS_BLUETEAM_SCORED: CG_AddBufferedSound(cgs.media.blueScoredSound); break; case GTS_REDTEAM_TOOK_LEAD: if ( cgs.gametype != GT_TEAM || cg_teamDmLeadAnnouncements.integer ) { CG_AddBufferedSound(cgs.media.redLeadsSound); } break; case GTS_BLUETEAM_TOOK_LEAD: if ( cgs.gametype != GT_TEAM || cg_teamDmLeadAnnouncements.integer ) { CG_AddBufferedSound(cgs.media.blueLeadsSound); } break; case GTS_TEAMS_ARE_TIED: if ( cgs.gametype != GT_TEAM || cg_teamDmLeadAnnouncements.integer ) { CG_AddBufferedSound( cgs.media.teamsTiedSound ); } break; #ifdef MISSIONPACK case GTS_KAMIKAZE: trap_S_StartLocalSound(cgs.media.kamikazeFarSound, CHAN_ANNOUNCER); break; #endif default: break; } break; } case EV_PAIN: // local player sounds are triggered in CG_CheckLocalSounds, // so ignore events on the player DEBUGNAME("EV_PAIN"); if ( !CG_LocalPlayerState( es->number ) ) { CG_PainEvent( cent, es->eventParm ); } break; case EV_DEATH1: case EV_DEATH2: case EV_DEATH3: DEBUGNAME2("EV_DEATH%d", event - EV_DEATH1 + 1); // check if gibbed // eventParm 1 = living player gibbed // eventParm 2 = corpse gibbed // eventParm 3 = living person gib headshot if ( es->eventParm >= 1 ) { CG_GibPlayer( cent->lerpOrigin, (es->eventParm == 3) ? qtrue : qfalse ); if ( cg_blood.integer && cg_gibs.integer ) { // don't play gib sound when using the kamikaze because it interferes // with the kamikaze sound, downside is that the gib sound will also // not be played when someone is gibbed while just carrying the kamikaze if ( !(es->eFlags & EF_KAMIKAZE) ) { trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.gibSound ); } // don't play death sound break; } // don't play death sound if already dead if ( es->eventParm == 2 ) { break; } } if (CG_WaterLevel(cent) >= 1) { trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, "*drown.wav")); } else { trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, va("*death%i.wav", event - EV_DEATH1 + 1))); } break; case EV_OBITUARY: DEBUGNAME("EV_OBITUARY"); CG_ParseObituary( es ); break; // // powerup events // case EV_POWERUP_QUAD: DEBUGNAME("EV_POWERUP_QUAD"); for (i = 0; i < CG_MaxSplitView(); i++) { if ( es->number == cg.snap->pss[i].playerNum ) { cg.localPlayers[i].powerupActive = PW_QUAD; cg.localPlayers[i].powerupTime = cg.time; } } trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.quadSound ); break; case EV_POWERUP_BATTLESUIT: DEBUGNAME("EV_POWERUP_BATTLESUIT"); for (i = 0; i < CG_MaxSplitView(); i++) { if ( es->number == cg.snap->pss[i].playerNum ) { cg.localPlayers[i].powerupActive = PW_BATTLESUIT; cg.localPlayers[i].powerupTime = cg.time; } } trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.protectSound ); break; case EV_POWERUP_REGEN: DEBUGNAME("EV_POWERUP_REGEN"); for (i = 0; i < CG_MaxSplitView(); i++) { if ( es->number == cg.snap->pss[i].playerNum ) { cg.localPlayers[i].powerupActive = PW_REGEN; cg.localPlayers[i].powerupTime = cg.time; } } trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.regenSound ); break; case EV_STOPLOOPINGSOUND: DEBUGNAME("EV_STOPLOOPINGSOUND"); trap_S_StopLoopingSound( es->number ); es->loopSound = 0; break; case EV_DEBUG_LINE: DEBUGNAME("EV_DEBUG_LINE"); CG_Beam( cent ); break; default: DEBUGNAME("UNKNOWN"); CG_Error( "Unknown event: %i", event ); break; } }
void CG_EntityEvent( centity_t *cent, vec3_t position ) { entityState_t *es; int event; vec3_t dir; const char *s; int clientNum; clientInfo_t *ci; es = ¢->currentState; event = es->event & ~EV_EVENT_BITS; if ( cg_debugEvents.integer ) { CG_Printf( "ent:%3i event:%3i ", es->number, event ); } if ( !event ) { DEBUGNAME("ZEROEVENT"); return; } clientNum = es->clientNum; if ( clientNum < 0 || clientNum >= MAX_CLIENTS ) { clientNum = 0; } ci = &cgs.clientinfo[ clientNum ]; switch ( event ) { // // movement generated events // case EV_WATER_TOUCH: DEBUGNAME("EV_WATER_TOUCH"); S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrInSound ); break; case EV_WATER_LEAVE: DEBUGNAME("EV_WATER_LEAVE"); S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrOutSound ); break; case EV_WATER_UNDER: DEBUGNAME("EV_WATER_UNDER"); S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrUnSound ); break; case EV_WATER_CLEAR: DEBUGNAME("EV_WATER_CLEAR"); S_StartSound (NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*gasp.wav" ) ); break; case EV_ITEM_PICKUP: DEBUGNAME("EV_ITEM_PICKUP"); { gitem_t *item; int index; index = es->eventParm; // player predicted if ( index < 1 || index >= bg_numItems ) { break; } item = &bg_itemlist[ index ]; // powerups and team items will have a separate global sound, this one // will be played at prediction time if ( item->giType == IT_TEAM) { S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.n_healthSound ); } else { S_StartSound (NULL, es->number, CHAN_AUTO, S_RegisterSound( item->pickup_sound, false ) ); } // show icon and name on status bar if ( es->number == cg.snap->ps.clientNum ) { CG_ItemPickup( index ); } } break; case EV_GLOBAL_ITEM_PICKUP: DEBUGNAME("EV_GLOBAL_ITEM_PICKUP"); { gitem_t *item; int index; index = es->eventParm; // player predicted if ( index < 1 || index >= bg_numItems ) { break; } item = &bg_itemlist[ index ]; // powerup pickups are global if( item->pickup_sound ) { S_StartSound (NULL, cg.snap->ps.clientNum, CHAN_AUTO, S_RegisterSound( item->pickup_sound, false ) ); } // show icon and name on status bar if ( es->number == cg.snap->ps.clientNum ) { CG_ItemPickup( index ); } } break; // // weapon events // case EV_FIRE_MG: DEBUGNAME("EV_FIRE_WEAPON"); CG_FireMachinegun( cent, false ); break; case EV_FIRE_WEAPON: DEBUGNAME("EV_FIRE_WEAPON"); CG_FireWeapon( cent ); break; case EV_FIRE_FLARE: DEBUGNAME("EV_FIRE_FLARE"); break; case EV_NUKE: DEBUGNAME("EV_NUKE"); CG_NukeEffect( cent, es ); break; case EV_FLAK: DEBUGNAME("EV_FLAK"); CG_FlakEffect( cent, es ); break; //================================================================= // // other events // case EV_ITEM_POP: DEBUGNAME("EV_ITEM_POP"); S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.respawnSound ); break; case EV_ITEM_RESPAWN: DEBUGNAME("EV_ITEM_RESPAWN"); cent->miscTime = cg.time; // scale up from this S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.respawnSound ); break; // // missile impacts // case EV_MISSILE_HIT: DEBUGNAME("EV_MISSILE_HIT"); ByteToDir( es->eventParm, dir ); CG_MissileHitWall( es->weaponIndex, 0, position, dir, IMPACTSOUND_DEFAULT ); break; case EV_MISSILE_MISS: DEBUGNAME("EV_MISSILE_MISS"); ByteToDir( es->eventParm, dir ); CG_MissileHitWall( es->weaponIndex, 0, position, dir, IMPACTSOUND_DEFAULT ); break; case EV_MISSILE_MISS_METAL: DEBUGNAME("EV_MISSILE_MISS_METAL"); ByteToDir( es->eventParm, dir ); CG_MissileHitWall( es->weaponIndex, 0, position, dir, IMPACTSOUND_METAL ); break; // MFQ3 events case EV_VEHICLE_HIT: DEBUGNAME("EV_VEHICLE_HIT"); CG_VehicleHit( position, es->eventParm ); break; case EV_VEHICLE_DIE: DEBUGNAME("EV_VEHICLE_DIE"); CG_GenericExplosion( position, EXPLODE_VEHICLE_DIE ); break; case EV_VEHICLE_GIB: DEBUGNAME("EV_VEHICLE_GIB"); if(availableVehicles[cgs.clientinfo[ cent->currentState.clientNum ].vehicle].cat & CAT_LQM) CG_GibPlayer(position); else CG_GenericExplosion( position, EXPLODE_VEHICLE_GIB ); break; case EV_BUILDING_EXPLODE: DEBUGNAME("EV_BUILDING_EXPLODE"); CG_GenericExplosion( position, EXPLODE_BUILDING ); break; case EV_GEAR_UP_FULL: DEBUGNAME("EV_GEAR_UP_FULL"); cent->gearAnimStartTime = 0; cent->gearAnim = GEAR_ANIM_STOP; cent->gearAnimFrame = GEAR_UP; break; case EV_GEAR_UP: DEBUGNAME("EV_GEAR_UP"); cent->gearAnimStartTime = cg.time; cent->gearAnim = GEAR_ANIM_UP; break; case EV_GEAR_STOP: DEBUGNAME("EV_GEAR_STOP"); cent->gearAnimStartTime = 0; cent->gearAnim = GEAR_ANIM_STOP; break; case EV_GEAR_DOWN: DEBUGNAME("EV_GEAR_DOWN"); cent->gearAnimStartTime = cg.time; cent->gearAnim = GEAR_ANIM_DOWN; break; case EV_GEAR_DOWN_FULL: DEBUGNAME("EV_GEAR_DOWN_FULL"); cent->gearAnimStartTime = 0; cent->gearAnim = GEAR_ANIM_STOP; { // old version /* if( cent->currentState.eType == ET_VEHICLE ) { clientInfo_t *ci; int clientNum; clientNum = cent->currentState.clientNum; if ( clientNum < 0 || clientNum >= MAX_CLIENTS ) { Com_Error( ERR_DROP, "Bad clientNum on player entity (EV_GEAR_DOWN_FULL)"); } ci = &cgs.clientinfo[ clientNum ]; cent->gearAnimFrame = availableVehicles[ci->vehicle].maxGearFrame; } else if( cent->currentState.eType == ET_MISC_VEHICLE ) { cent->gearAnimFrame = availableVehicles[cent->currentState.modelindex].maxGearFrame; } */ // New version clientInfo_t *ci; int clientNum; clientNum = cent->currentState.clientNum; if( clientNum < 0 || clientNum >= MAX_CLIENTS ) { cent->gearAnimFrame = availableVehicles[cent->currentState.modelindex].maxGearFrame; } else { ci = &cgs.clientinfo[ clientNum ]; cent->gearAnimFrame = availableVehicles[ci->vehicle].maxGearFrame; } } break; case EV_BAY_UP_FULL: DEBUGNAME("EV_BAY_UP_FULL"); cent->bayAnimStartTime = 0; cent->bayAnim = BAY_ANIM_STOP; cent->bayAnimFrame = BAY_UP; break; case EV_BAY_UP: DEBUGNAME("EV_BAY_UP"); cent->bayAnimStartTime = cg.time; cent->bayAnim = BAY_ANIM_UP; break; case EV_BAY_STOP: DEBUGNAME("EV_BAY_STOP"); cent->bayAnimStartTime = 0; cent->bayAnim = BAY_ANIM_STOP; break; case EV_BAY_DOWN: DEBUGNAME("EV_BAY_DOWN"); cent->bayAnimStartTime = cg.time; cent->bayAnim = BAY_ANIM_DOWN; break; case EV_BAY_DOWN_FULL: DEBUGNAME("EV_BAY_DOWN_FULL"); cent->bayAnimStartTime = 0; cent->bayAnim = BAY_ANIM_STOP; break; case EV_GENERAL_SOUND: DEBUGNAME("EV_GENERAL_SOUND"); if ( cgs.gameSounds[ es->eventParm ] ) { S_StartSound (NULL, es->number, CHAN_VOICE, cgs.gameSounds[ es->eventParm ] ); } else { s = CG_ConfigString( CS_SOUNDS + es->eventParm ); S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, s ) ); } break; case EV_GLOBAL_SOUND: // play from the player's head so it never diminishes DEBUGNAME("EV_GLOBAL_SOUND"); if ( cgs.gameSounds[ es->eventParm ] ) { S_StartSound (NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.gameSounds[ es->eventParm ] ); } else { s = CG_ConfigString( CS_SOUNDS + es->eventParm ); S_StartSound (NULL, cg.snap->ps.clientNum, CHAN_AUTO, CG_CustomSound( es->number, s ) ); } break; case EV_GLOBAL_TEAM_SOUND: // play from the player's head so it never diminishes { DEBUGNAME("EV_GLOBAL_TEAM_SOUND"); switch( es->eventParm ) { case GTS_RED_CAPTURE: // CTF: red team captured the blue flag, 1FCTF: red team captured the neutral flag if ( cgs.clientinfo[cg.clientNum].team == ClientBase::TEAM_RED ) CG_AddBufferedSound( cgs.media.captureYourTeamSound ); else CG_AddBufferedSound( cgs.media.captureOpponentSound ); break; case GTS_BLUE_CAPTURE: // CTF: blue team captured the red flag, 1FCTF: blue team captured the neutral flag if ( cgs.clientinfo[cg.clientNum].team == ClientBase::TEAM_BLUE ) CG_AddBufferedSound( cgs.media.captureYourTeamSound ); else CG_AddBufferedSound( cgs.media.captureOpponentSound ); break; case GTS_RED_RETURN: // CTF: blue flag returned, 1FCTF: never used if ( cgs.clientinfo[cg.clientNum].team == ClientBase::TEAM_RED ) CG_AddBufferedSound( cgs.media.returnYourTeamSound ); else CG_AddBufferedSound( cgs.media.returnOpponentSound ); // CG_AddBufferedSound( cgs.media.blueFlagReturnedSound ); break; case GTS_BLUE_RETURN: // CTF red flag returned, 1FCTF: neutral flag returned if ( cgs.clientinfo[cg.clientNum].team == ClientBase::TEAM_BLUE ) CG_AddBufferedSound( cgs.media.returnYourTeamSound ); else CG_AddBufferedSound( cgs.media.returnOpponentSound ); // CG_AddBufferedSound( cgs.media.redFlagReturnedSound ); break; case GTS_RED_TAKEN: // CTF: red team took blue flag, 1FCTF: blue team took the neutral flag // if this player picked up the flag then a sound is played in CG_CheckLocalSounds if (cg.snap->ps.objectives & OB_BLUEFLAG ) { } else { if (cgs.clientinfo[cg.clientNum].team == ClientBase::TEAM_BLUE) { CG_AddBufferedSound( cgs.media.enemyTookYourFlagSound ); } else if (cgs.clientinfo[cg.clientNum].team == ClientBase::TEAM_RED) { CG_AddBufferedSound( cgs.media.yourTeamTookEnemyFlagSound ); } } break; case GTS_BLUE_TAKEN: // CTF: blue team took the red flag, 1FCTF red team took the neutral flag // if this player picked up the flag then a sound is played in CG_CheckLocalSounds if (cg.snap->ps.objectives & OB_REDFLAG ) { } else { if (cgs.clientinfo[cg.clientNum].team == ClientBase::TEAM_RED) { CG_AddBufferedSound( cgs.media.enemyTookYourFlagSound ); } else if (cgs.clientinfo[cg.clientNum].team == ClientBase::TEAM_BLUE) { CG_AddBufferedSound( cgs.media.yourTeamTookEnemyFlagSound ); } } break; case GTS_REDTEAM_SCORED: CG_AddBufferedSound(cgs.media.redScoredSound); break; case GTS_BLUETEAM_SCORED: CG_AddBufferedSound(cgs.media.blueScoredSound); break; case GTS_REDTEAM_TOOK_LEAD: CG_AddBufferedSound(cgs.media.redLeadsSound); break; case GTS_BLUETEAM_TOOK_LEAD: CG_AddBufferedSound(cgs.media.blueLeadsSound); break; case GTS_TEAMS_ARE_TIED: CG_AddBufferedSound( cgs.media.teamsTiedSound ); break; // MFQ3 case GTS_NUKE: S_StartLocalSound(cgs.media.nukeFarSound, CHAN_ANNOUNCER); break; default: break; } break; } case EV_PAIN: // local player sounds are triggered in CG_CheckLocalSounds, // so ignore events on the player DEBUGNAME("EV_PAIN"); if ( cent->currentState.number != cg.snap->ps.clientNum ) { CG_PainEvent( cent, es->eventParm ); } break; case EV_DEATH1: case EV_DEATH2: case EV_DEATH3: DEBUGNAME("EV_DEATHx"); S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, va("*death%i.wav", event - EV_DEATH1 + 1) ) ); break; case EV_OBITUARY: DEBUGNAME("EV_OBITUARY"); CG_VehicleObituary( es ); break; case EV_DEBUG_LINE: DEBUGNAME("EV_DEBUG_LINE"); CG_Beam( cent ); break; default: DEBUGNAME("UNKNOWN"); Com_Error( ERR_DROP, "Unknown event: %i", event ); break; } }
void CG_EntityEvent(centity_t *cent, vec3_t position) { entityState_t *es; int event; vec3_t dir; const char *s; int clientNum; clientInfo_t *ci; es = ¢->currentState; event = es->event & ~EV_EVENT_BITS; if (cg_debugEvents.integer) { CG_Printf("ent:%3i event:%3i ", es->number, event); } if (!event) { DEBUGNAME("ZEROEVENT"); return; } clientNum = es->clientNum; if (clientNum < 0 || clientNum >= MAX_CLIENTS) { clientNum = 0; } ci = &cgs.clientinfo[ clientNum ]; switch (event) { // // movement generated events // case EV_BANDAGE: DEBUGNAME("EV_BANDAGE"); if (clientNum == cg.predictedPlayerState.clientNum) { CG_ZoomReset_f(); } trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.bandageSound); break; case EV_FOOTSTEP: DEBUGNAME("EV_FOOTSTEP"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[ ci->footsteps ][rand()&3]); } break; case EV_FOOTSTEP_METAL: DEBUGNAME("EV_FOOTSTEP_METAL"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_METAL ][rand()&3]); } break; case EV_FOOTSPLASH: DEBUGNAME("EV_FOOTSPLASH"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3]); } break; case EV_FOOTWADE: DEBUGNAME("EV_FOOTWADE"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3]); } break; case EV_SWIM: DEBUGNAME("EV_SWIM"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3]); } break; case EV_FOOTSTEP_LADDER: //Xamis DEBUGNAME("EV_FOOTSTEP_LADDER"); { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.ladderSound[rand()&3]); } break; case EV_LEDGEGRAB: //Xamis DEBUGNAME("EV_LEDGEGRAB"); { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.ledgeSound); } break; case EV_FALL_SHORT: DEBUGNAME("EV_FALL_SHORT"); trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.landSound); if (clientNum == cg.predictedPlayerState.clientNum) { // smooth landing z changes cg.landChange = -8; cg.landTime = cg.time; } break; case EV_FALL_MEDIUM: DEBUGNAME("EV_FALL_MEDIUM"); // use normal pain sound trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, "*pain100_1.wav")); if (clientNum == cg.predictedPlayerState.clientNum) { // smooth landing z changes cg.landChange = -16; cg.landTime = cg.time; } break; case EV_FALL_FAR: DEBUGNAME("EV_FALL_FAR"); trap_S_StartSound(NULL, es->number, CHAN_AUTO, CG_CustomSound(es->number, "*fall1.wav")); cent->pe.painTime = cg.time; // don't play a pain sound right after this if (clientNum == cg.predictedPlayerState.clientNum) { // smooth landing z changes cg.landChange = -32; cg.landTime = cg.time; } break; case EV_CURBSTOMP: DEBUGNAME("EV_CURBSTOMP"); trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.stompSound); break; case EV_STEP_4: case EV_STEP_8: case EV_STEP_12: case EV_STEP_16: // smooth out step up transitions DEBUGNAME("EV_STEP"); { float oldStep; int delta; int step; if (clientNum != cg.predictedPlayerState.clientNum) { break; } // if we are interpolating, we don't need to smooth steps if (cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) || cg_nopredict.integer || cg_synchronousClients.integer) { break; } // check for stepping up before a previous step is completed delta = cg.time - cg.stepTime; if (delta < STEP_TIME) { oldStep = cg.stepChange * (STEP_TIME - delta) / STEP_TIME; } else { oldStep = 0; } // add this amount step = 4 * (event - EV_STEP_4 + 1); cg.stepChange = oldStep + step; if (cg.stepChange > MAX_STEP_CHANGE) { cg.stepChange = MAX_STEP_CHANGE; } cg.stepTime = cg.time; break; } case EV_JUMP_PAD: DEBUGNAME("EV_JUMP_PAD"); // CG_Printf( "EV_JUMP_PAD w/effect #%i\n", es->eventParm ); { localEntity_t *smoke; vec3_t up = {0, 0, 1}; smoke = CG_SmokePuff(cent->lerpOrigin, up, 32, 1, 1, 1, 0.33f, 1000, cg.time, 0, LEF_PUFF_DONT_SCALE, cgs.media.smokePuffShader); } // boing sound at origin, jump sound on player trap_S_StartSound(cent->lerpOrigin, -1, CHAN_VOICE, cgs.media.jumpPadSound); trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, "*jump1.wav")); break; case EV_JUMP: DEBUGNAME("EV_JUMP"); //trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) ); //Xamis { vec3_t surfNormal, refNormal = {0.0f, 0.0f, 1.0f}; vec3_t rotAxis; if (clientNum != cg.predictedPlayerState.clientNum) break; //set surfNormal VectorCopy(cg.predictedPlayerState.grapplePoint, surfNormal); //if we are moving from one surface to another smooth the transition if (!VectorCompare(surfNormal, cg.lastNormal) && surfNormal[ 2 ] != 1.0f) { CrossProduct(refNormal, surfNormal, rotAxis); VectorNormalize(rotAxis); //add the op CG_addSmoothOp(rotAxis, 15.0f, 1.0f); } //copy the current normal to the lastNormal VectorCopy(surfNormal, cg.lastNormal); } break; case EV_BLEED: DEBUGNAME("EV_BLEED"); CG_CreateBleeder(es->pos.trBase, 10, cent->currentState.clientNum); // CG_PlayerBleed(cent->currentState.clientNum, 10, es->pos.trBase, dir ); break; case EV_WALLJUMP: DEBUGNAME("EV_WALLJUMP") break; case EV_TAUNT: DEBUGNAME("EV_TAUNT"); trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, "*taunt.wav")); break; #ifdef MISSIONPACK case EV_TAUNT_YES: DEBUGNAME("EV_TAUNT_YES"); CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_YES); break; case EV_TAUNT_NO: DEBUGNAME("EV_TAUNT_NO"); CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_NO); break; case EV_TAUNT_FOLLOWME: DEBUGNAME("EV_TAUNT_FOLLOWME"); CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_FOLLOWME); break; case EV_TAUNT_GETFLAG: DEBUGNAME("EV_TAUNT_GETFLAG"); CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONGETFLAG); break; case EV_TAUNT_GUARDBASE: DEBUGNAME("EV_TAUNT_GUARDBASE"); CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONDEFENSE); break; case EV_TAUNT_PATROL: DEBUGNAME("EV_TAUNT_PATROL"); CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONPATROL); break; #endif case EV_WATER_TOUCH: DEBUGNAME("EV_WATER_TOUCH"); trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.watrInSound); break; case EV_WATER_LEAVE: DEBUGNAME("EV_WATER_LEAVE"); trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.watrOutSound); break; case EV_WATER_UNDER: DEBUGNAME("EV_WATER_UNDER"); trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.watrUnSound); break; case EV_WATER_CLEAR: DEBUGNAME("EV_WATER_CLEAR"); trap_S_StartSound(NULL, es->number, CHAN_AUTO, CG_CustomSound(es->number, "*gasp.wav")); break; case EV_ITEM_PICKUP: DEBUGNAME("EV_ITEM_PICKUP"); { gitem_t *item; int index; index = es->eventParm; // player predicted if (index < 1 || index >= bg_numItems) { break; } item = &bg_itemlist[ index ]; // trap_S_StartSound (NULL, es->number, CHAN_AUTO, trap_S_RegisterSound( item->pickup_sound, qfalse ) ); //Disable sounds for powerup -- Xamis // powerups and team items will have a separate global sound, this one // will be played at prediction time if (item->giType == IT_POWERUP || item->giType == IT_TEAM) { //trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.n_healthSound ); } else { trap_S_StartSound(NULL, es->number, CHAN_AUTO, trap_S_RegisterSound(item->pickup_sound, qfalse)); } // show icon and name on status bar if (es->number == cg.snap->ps.clientNum) { CG_ItemPickup(index); } } break; case EV_GLOBAL_ITEM_PICKUP: DEBUGNAME("EV_GLOBAL_ITEM_PICKUP"); { gitem_t *item; int index; index = es->eventParm; // player predicted if (index < 1 || index >= bg_numItems) { break; } item = &bg_itemlist[ index ]; // powerup pickups are global if (item->pickup_sound) { trap_S_StartSound(NULL, cg.snap->ps.clientNum, CHAN_AUTO, trap_S_RegisterSound(item->pickup_sound, qfalse)); } // show icon and name on status bar if (es->number == cg.snap->ps.clientNum) { CG_ItemPickup(index); } } break; // // weapon events // case EV_NOAMMO: DEBUGNAME("EV_NOAMMO"); // trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.noAmmoSound ); if (es->number == cg.snap->ps.clientNum) { trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.noammoSound); } break; case EV_NONADES: DEBUGNAME("EV_NONADES"); if (clientNum == cg.predictedPlayerState.clientNum) { CG_WeaponSort(); } break; case EV_POWERSLIDE: CG_HasteTrail(cent); break; case EV_CHANGE_WEAPON: DEBUGNAME("EV_CHANGE_WEAPON"); trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.selectSound); break; case EV_WEAPON_DROPPED: DEBUGNAME("EV_WEAPON_DROPPED"); if (clientNum == cg.predictedPlayerState.clientNum) { //CG_Printf("EV_WEAPON_DROPPED\n"); CG_WeaponSort(); } break; case EV_FIRE_WEAPON: DEBUGNAME("EV_FIRE_WEAPON"); CG_FireWeapon(cent); break; case EV_ZOOM_RESET: if (clientNum == cg.predictedPlayerState.clientNum) { CG_ZoomReset_f(); } break; case EV_EJECT_CASING: { entityState_t *ent; weaponInfo_t *weap; ent = ¢->currentState; weap = &cg_weapons[ ent->weapon ]; weap->ejectBrassFunc(cent); break; } case EV_USE_ITEM0: DEBUGNAME("EV_USE_ITEM0"); CG_UseItem(cent); break; case EV_USE_ITEM1: DEBUGNAME("EV_USE_ITEM1"); CG_UseItem(cent); break; case EV_USE_ITEM2: DEBUGNAME("EV_USE_ITEM2"); CG_UseItem(cent); break; case EV_USE_ITEM3: DEBUGNAME("EV_USE_ITEM3"); CG_UseItem(cent); break; case EV_USE_ITEM4: DEBUGNAME("EV_USE_ITEM4"); CG_UseItem(cent); break; case EV_USE_ITEM5: DEBUGNAME("EV_USE_ITEM5"); CG_UseItem(cent); break; case EV_USE_ITEM6: DEBUGNAME("EV_USE_ITEM6"); CG_UseItem(cent); break; case EV_USE_ITEM7: DEBUGNAME("EV_USE_ITEM7"); CG_UseItem(cent); break; case EV_USE_ITEM8: DEBUGNAME("EV_USE_ITEM8"); CG_UseItem(cent); break; case EV_USE_ITEM9: DEBUGNAME("EV_USE_ITEM9"); CG_UseItem(cent); break; case EV_USE_ITEM10: DEBUGNAME("EV_USE_ITEM10"); CG_UseItem(cent); break; case EV_USE_ITEM11: DEBUGNAME("EV_USE_ITEM11"); CG_UseItem(cent); break; case EV_USE_ITEM12: DEBUGNAME("EV_USE_ITEM12"); CG_UseItem(cent); break; case EV_USE_ITEM13: DEBUGNAME("EV_USE_ITEM13"); CG_UseItem(cent); break; case EV_USE_ITEM14: DEBUGNAME("EV_USE_ITEM14"); CG_UseItem(cent); break; //================================================================= // // other events // case EV_PLAYER_TELEPORT_IN: DEBUGNAME("EV_PLAYER_TELEPORT_IN"); //trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.teleInSound ); //disable sound --Xamis CG_SpawnEffect(position); break; case EV_PLAYER_TELEPORT_OUT: DEBUGNAME("EV_PLAYER_TELEPORT_OUT"); //trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.teleOutSound );//disable sound --Xamis CG_SpawnEffect(position); break; case EV_ITEM_POP: DEBUGNAME("EV_ITEM_POP"); //trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.respawnSound ); break; case EV_ITEM_RESPAWN: DEBUGNAME("EV_ITEM_RESPAWN"); cent->miscTime = cg.time; // scale up from this //trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.respawnSound ); break; case EV_GRENADE_BOUNCE: DEBUGNAME("EV_GRENADE_BOUNCE"); if (rand() & 1) { trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.hgrenb1aSound); } else { trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.hgrenb2aSound); } break; #ifdef MISSIONPACK case EV_PROXIMITY_MINE_STICK: DEBUGNAME("EV_PROXIMITY_MINE_STICK"); if (es->eventParm & SURF_FLESH) { trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.wstbimplSound); } else if (es->eventParm & SURF_METALSTEPS) { trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.wstbimpmSound); } else { trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.wstbimpdSound); } break; case EV_PROXIMITY_MINE_TRIGGER: DEBUGNAME("EV_PROXIMITY_MINE_TRIGGER"); trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.wstbactvSound); break; case EV_KAMIKAZE: DEBUGNAME("EV_KAMIKAZE"); CG_KamikazeEffect(cent->lerpOrigin); break; case EV_OBELISKEXPLODE: DEBUGNAME("EV_OBELISKEXPLODE"); CG_ObeliskExplode(cent->lerpOrigin, es->eventParm); break; case EV_OBELISKPAIN: DEBUGNAME("EV_OBELISKPAIN"); CG_ObeliskPain(cent->lerpOrigin); break; case EV_INVUL_IMPACT: DEBUGNAME("EV_INVUL_IMPACT"); CG_InvulnerabilityImpact(cent->lerpOrigin, cent->currentState.angles); break; case EV_JUICED: DEBUGNAME("EV_JUICED"); CG_InvulnerabilityJuiced(cent->lerpOrigin); break; case EV_LIGHTNINGBOLT: DEBUGNAME("EV_LIGHTNINGBOLT"); CG_LightningBoltBeam(es->origin2, es->pos.trBase); break; #endif case EV_SCOREPLUM: DEBUGNAME("EV_SCOREPLUM"); CG_ScorePlum(cent->currentState.otherEntityNum, cent->lerpOrigin, cent->currentState.time); break; // // missile impacts // case EV_MISSILE_HIT: DEBUGNAME("EV_MISSILE_HIT"); ByteToDir(es->eventParm, dir); CG_MissileHitPlayer(es->weapon, position, dir, es->otherEntityNum); break; case EV_MISSILE_MISS: DEBUGNAME("EV_MISSILE_MISS"); ByteToDir(es->eventParm, dir); CG_MissileHitWall(es->weapon, 0, position, dir, IMPACTSOUND_DEFAULT); break; case EV_MISSILE_MISS_METAL: DEBUGNAME("EV_MISSILE_MISS_METAL"); ByteToDir(es->eventParm, dir); CG_MissileHitWall(es->weapon, 0, position, dir, IMPACTSOUND_METAL); break; case EV_BULLET_HIT_WALL: DEBUGNAME("EV_BULLET_HIT_WALL"); ByteToDir(es->eventParm, dir); CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD); break; case EV_BULLET_HIT_FLESH: DEBUGNAME("EV_BULLET_HIT_FLESH"); CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qtrue, es->eventParm); break; case EV_SHOTGUN: DEBUGNAME("EV_SHOTGUN"); CG_ShotgunFire(es); break; case EV_GAMESTATE: trap_Cvar_Set("ui_gamestate", va("%i", es->eventParm)); break; case EV_GENERAL_SOUND: DEBUGNAME("EV_GENERAL_SOUND"); if (cgs.gameSounds[ es->eventParm ]) { trap_S_StartSound(NULL, es->number, CHAN_VOICE, cgs.gameSounds[ es->eventParm ]); } else { s = CG_ConfigString(CS_SOUNDS + es->eventParm); trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, s)); } break; case EV_GLOBAL_SOUND: // play from the player's head so it never diminishes DEBUGNAME("EV_GLOBAL_SOUND"); if (cgs.gameSounds[ es->eventParm ]) { trap_S_StartSound(NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.gameSounds[ es->eventParm ]); } else { s = CG_ConfigString(CS_SOUNDS + es->eventParm); trap_S_StartSound(NULL, cg.snap->ps.clientNum, CHAN_AUTO, CG_CustomSound(es->number, s)); } break; case EV_GLOBAL_TEAM_SOUND: // play from the player's head so it never diminishes { DEBUGNAME("EV_GLOBAL_TEAM_SOUND"); switch (es->eventParm) { case GTS_DRAW_ROUND: CG_AddBufferedSound(cgs.media.roundDrawSound); break; case GTS_RED_CAPTURE: // CTF: red team captured the blue flag, 1FCTF: red team captured the neutral flag if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) CG_AddBufferedSound(cgs.media.captureYourTeamSound); else CG_AddBufferedSound(cgs.media.captureOpponentSound); break; case GTS_BLUE_CAPTURE: // CTF: blue team captured the red flag, 1FCTF: blue team captured the neutral flag if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) CG_AddBufferedSound(cgs.media.captureYourTeamSound); else CG_AddBufferedSound(cgs.media.captureOpponentSound); break; case GTS_RED_RETURN: // CTF: blue flag returned, 1FCTF: never used if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) CG_AddBufferedSound(cgs.media.returnYourTeamSound); else CG_AddBufferedSound(cgs.media.returnOpponentSound); // CG_AddBufferedSound(cgs.media.blueFlagReturnedSound); break; case GTS_BLUE_RETURN: // CTF red flag returned, 1FCTF: neutral flag returned if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) CG_AddBufferedSound(cgs.media.returnYourTeamSound); else CG_AddBufferedSound(cgs.media.returnOpponentSound); // CG_AddBufferedSound(cgs.media.redFlagReturnedSound); break; case GTS_RED_TAKEN: // CTF: red team took blue flag, 1FCTF: blue team took the neutral flag // if this player picked up the flag then a sound is played in CG_CheckLocalSounds if (cg.snap->ps.powerups[PW_BLUEFLAG] || cg.snap->ps.powerups[PW_NEUTRALFLAG]) { } else { if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) { #ifdef MISSIONPACK if (cgs.gametype == GT_BOMB) CG_AddBufferedSound(cgs.media.yourTeamTookTheFlagSound); else #endif CG_AddBufferedSound(cgs.media.enemyTookYourFlagSound); } else if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) { #ifdef MISSIONPACK if (cgs.gametype == GT_BOMB) CG_AddBufferedSound(cgs.media.enemyTookTheFlagSound); else #endif CG_AddBufferedSound(cgs.media.yourTeamTookEnemyFlagSound); } } break; case GTS_BLUE_TAKEN: // CTF: blue team took the red flag, 1FCTF red team took the neutral flag // if this player picked up the flag then a sound is played in CG_CheckLocalSounds if (cg.snap->ps.powerups[PW_REDFLAG] || cg.snap->ps.powerups[PW_NEUTRALFLAG]) { } else { if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) { #ifdef MISSIONPACK if (cgs.gametype == GT_BOMB) CG_AddBufferedSound(cgs.media.yourTeamTookTheFlagSound); else #endif CG_AddBufferedSound(cgs.media.enemyTookYourFlagSound); } else if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) { #ifdef MISSIONPACK if (cgs.gametype == GT_BOMB) CG_AddBufferedSound(cgs.media.enemyTookTheFlagSound); else #endif CG_AddBufferedSound(cgs.media.yourTeamTookEnemyFlagSound); } } break; case GTS_REDOBELISK_ATTACKED: // Overload: red obelisk is being attacked if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) { CG_AddBufferedSound(cgs.media.yourBaseIsUnderAttackSound); } break; case GTS_BLUEOBELISK_ATTACKED: // Overload: blue obelisk is being attacked if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) { CG_AddBufferedSound(cgs.media.yourBaseIsUnderAttackSound); } break; case GTS_REDTEAM_SCORED: CG_AddBufferedSound(cgs.media.redScoredSound); break; case GTS_BLUETEAM_SCORED: CG_AddBufferedSound(cgs.media.blueScoredSound); break; case GTS_REDTEAM_TOOK_LEAD: CG_AddBufferedSound(cgs.media.redLeadsSound); break; case GTS_BLUETEAM_TOOK_LEAD: CG_AddBufferedSound(cgs.media.blueLeadsSound); break; case GTS_TEAMS_ARE_TIED: CG_AddBufferedSound(cgs.media.teamsTiedSound); break; #ifdef MISSIONPACK case GTS_KAMIKAZE: trap_S_StartLocalSound(cgs.media.kamikazeFarSound, CHAN_ANNOUNCER); break; #endif default: break; } break; } case EV_PAIN: // local player sounds are triggered in CG_CheckLocalSounds, // so ignore events on the player DEBUGNAME("EV_PAIN"); if (cent->currentState.number != cg.snap->ps.clientNum) { CG_PainEvent(cent, es->eventParm); } break; case EV_DEATH1: case EV_DEATH2: case EV_DEATH3: DEBUGNAME("EV_DEATHx"); if (clientNum == cg.predictedPlayerState.clientNum) { CG_ZoomReset_f(); } trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, va("*death%i.wav", event - EV_DEATH1 + 1))); break; case EV_OBITUARY: DEBUGNAME("EV_OBITUARY"); CG_Obituary(es); break; // // powerup events // case EV_GIB_PLAYER: DEBUGNAME("EV_GIB_PLAYER"); // don't play gib sound when using the kamikaze because it interferes // with the kamikaze sound, downside is that the gib sound will also // not be played when someone is gibbed while just carrying the kamikaze if (!(es->eFlags & EF_KAMIKAZE)) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.gibSound); } CG_GibPlayer(cent->lerpOrigin); break; //Xamis case EV_BREAK_GLASS: DEBUGNAME("EV_BREAK_GLASS"); trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.glassSound); CG_BreakGlass(cent->lerpOrigin); break; case EV_STOPLOOPINGSOUND: DEBUGNAME("EV_STOPLOOPINGSOUND"); trap_S_StopLoopingSound(es->number); es->loopSound = 0; break; case EV_DEBUG_LINE: DEBUGNAME("EV_DEBUG_LINE"); CG_Beam(cent); break; default: DEBUGNAME("UNKNOWN"); CG_Error("Unknown event: %i", event); break; } }
void CG_EntityEvent( centity_t *cent, vec3_t position ) { entityState_t *es; int event; vec3_t axis[3]; const char *s, *s2; int clientNum; //clientInfo_t *ci; es = ¢->currentState; event = es->event & ~EV_EVENT_BITS; if ( cg_debugEvents.integer ) { CG_Printf( "ent:%3i event:%3i ", es->number, event ); } if ( !event ) { DEBUGNAME("ZEROEVENT"); return; } if ( !cent->gent )//|| !cent->gent->client ) { return; } //ci = ¢->gent->client->clientInfo; clientNum = cent->gent->s.number; switch ( event ) { // // movement generated events // /* case EV_FOOTSTEP: DEBUGNAME("EV_FOOTSTEP"); if (cg_footsteps.integer) { if ( cent->gent && cent->gent->s.number == 0 && !cg.renderingThirdPerson )//!cg_thirdPerson.integer ) {//Everyone else has keyframed footsteps in animevents.cfg #ifdef _IMMERSION int index = rand()&3; cgi_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_NORMAL ][index] ); cgi_FF_Start( cgs.media.footstepForces[ FOOTSTEP_NORMAL ][ index ], es->number ); #else cgi_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_NORMAL ][rand()&3] ); #endif // _IMMERSION } } break; case EV_FOOTSTEP_METAL: DEBUGNAME("EV_FOOTSTEP_METAL"); if (cg_footsteps.integer) { if ( cent->gent && cent->gent->s.number == 0 && !cg.renderingThirdPerson ) {//Everyone else has keyframed footsteps in animevents.cfg #ifdef _IMMERSION int index = rand()&3; cgi_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_METAL ][index] ); cgi_FF_Start( cgs.media.footstepForces[ FOOTSTEP_METAL ][ index ], es->number ); #else cgi_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_METAL ][rand()&3] ); #endif // _IMMERSION } } break; */ case EV_FOOTSPLASH: DEBUGNAME("EV_FOOTSPLASH"); if (cg_footsteps.integer) { #ifdef _IMMERSION int index = rand()&3; cgi_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_SPLASH ][index] ); cgi_FF_Start( cgs.media.footstepForces[ FOOTSTEP_SPLASH ][ index ], es->number ); #else cgi_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3] ); #endif // _IMMERSION } break; case EV_FOOTWADE: DEBUGNAME("EV_FOOTWADE"); if (cg_footsteps.integer) { #ifdef _IMMERSION int index = rand()&3; cgi_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_WADE ][index] ); cgi_FF_Start( cgs.media.footstepForces[ FOOTSTEP_WADE ][ index ], es->number ); #else cgi_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_WADE ][rand()&3] ); #endif // _IMMERSION } break; case EV_SWIM: DEBUGNAME("EV_SWIM"); if (cg_footsteps.integer) { #ifdef _IMMERSION int index = rand()&3; cgi_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_SWIM ][index] ); cgi_FF_Start( cgs.media.footstepForces[ FOOTSTEP_SWIM ][ index ], es->number ); #else cgi_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_SWIM ][rand()&3] ); #endif // _IMMERSION } break; case EV_FALL_SHORT: DEBUGNAME("EV_FALL_SHORT"); cgi_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.landSound ); #ifdef _IMMERSION cgi_FF_Start( cgs.media.landForce, es->number ); #endif // _IMMERSION if ( clientNum == cg.predicted_player_state.clientNum ) { // smooth landing z changes cg.landChange = -8; cg.landTime = cg.time; } //FIXME: maybe kick up some dust? break; case EV_FALL_MEDIUM: DEBUGNAME("EV_FALL_MEDIUM"); // use normal pain sound - if ( g_entities[es->number].health <= 0 ) {//dead cgi_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.landSound ); #ifdef _IMMERSION cgi_FF_Start( cgs.media.landForce, es->number ); #endif // _IMMERSION } else if ( g_entities[es->number].s.weapon == WP_SABER || (g_entities[es->number].client && (g_entities[es->number].client->ps.forcePowersKnown&(1<<FP_LEVITATION))) ) {//jedi or someone who has force jump (so probably took no damage) CG_TryPlayCustomSound( NULL, es->number, CHAN_BODY, "*land1.wav", CS_BASIC ); } else {//still alive CG_TryPlayCustomSound( NULL, es->number, CHAN_BODY, "*pain100.wav", CS_BASIC ); } if ( clientNum == cg.predicted_player_state.clientNum ) { // smooth landing z changes cg.landChange = -16; cg.landTime = cg.time; } #ifdef _XBOX cgi_FF_StartFX( fffx_FallingMedium ); #endif //FIXME: maybe kick up some dust? break; case EV_FALL_FAR: DEBUGNAME("EV_FALL_FAR"); CG_TryPlayCustomSound( NULL, es->number, CHAN_BODY, "*land1.wav", CS_BASIC ); cgi_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.landSound ); cent->pe.painTime = cg.time; // don't play a pain sound right after this if ( clientNum == cg.predicted_player_state.clientNum ) { // smooth landing z changes cg.landChange = -24; cg.landTime = cg.time; } #ifdef _XBOX cgi_FF_StartFX( fffx_FallingFar ); #endif //FIXME: maybe kick up some dust? break; case EV_STEP_4: case EV_STEP_8: case EV_STEP_12: case EV_STEP_16: // smooth out step up transitions DEBUGNAME("EV_STEP"); { float oldStep; int delta; int step; if ( clientNum != cg.predicted_player_state.clientNum ) { break; } // if we are interpolating, we don't need to smooth steps if ( cg_timescale.value >= 1.0f ) { break; } // check for stepping up before a previous step is completed delta = cg.time - cg.stepTime; if (delta < STEP_TIME) { oldStep = cg.stepChange * (STEP_TIME - delta) / STEP_TIME; } else { oldStep = 0; } // add this amount step = 4 * (event - EV_STEP_4 + 1 ); cg.stepChange = oldStep + step; if ( cg.stepChange > MAX_STEP_CHANGE ) { cg.stepChange = MAX_STEP_CHANGE; } cg.stepTime = cg.time; break; } case EV_JUMP: DEBUGNAME("EV_JUMP"); CG_TryPlayCustomSound(NULL, es->number, CHAN_AUTO, "*jump1.wav", CS_BASIC );//CHAN_VOICE break; case EV_ROLL: DEBUGNAME("EV_ROLL"); CG_TryPlayCustomSound(NULL, es->number, CHAN_AUTO, "*jump1.wav", CS_BASIC );//CHAN_VOICE cgi_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.rollSound );//CHAN_AUTO //FIXME: need some sort of body impact on ground sound and maybe kick up some dust? break; case EV_LAVA_TOUCH: DEBUGNAME("EV_LAVA_TOUCH"); cgi_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.lavaInSound ); #ifdef _IMMERSION cgi_FF_Start( cgs.media.watrInSound, es->number ); #endif // _IMMERSION break; case EV_LAVA_LEAVE: DEBUGNAME("EV_LAVA_LEAVE"); cgi_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.lavaOutSound ); #ifdef _IMMERSION cgi_FF_Start( cgs.media.watrOutSound, es->number ); #endif // _IMMERSION break; case EV_LAVA_UNDER: DEBUGNAME("EV_LAVA_UNDER"); cgi_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.lavaUnSound ); #ifdef _IMMERSION cgi_FF_Start( cgs.media.watrUnSound, es->number ); #endif // _IMMERSION break; case EV_WATER_TOUCH: DEBUGNAME("EV_WATER_TOUCH"); cgi_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrInSound ); #ifdef _IMMERSION cgi_FF_Start( cgs.media.watrInSound, es->number ); #endif // _IMMERSION break; case EV_WATER_LEAVE: DEBUGNAME("EV_WATER_LEAVE"); cgi_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrOutSound ); #ifdef _IMMERSION cgi_FF_Start( cgs.media.watrOutSound, es->number ); #endif // _IMMERSION break; case EV_WATER_UNDER: DEBUGNAME("EV_WATER_UNDER"); cgi_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrUnSound ); #ifdef _IMMERSION cgi_FF_Start( cgs.media.watrUnSound, es->number ); #endif // _IMMERSION break; case EV_WATER_CLEAR: DEBUGNAME("EV_WATER_CLEAR"); CG_TryPlayCustomSound(NULL, es->number, CHAN_AUTO, "*gasp.wav", CS_BASIC ); break; case EV_WATER_GURP1: case EV_WATER_GURP2: DEBUGNAME("EV_WATER_GURPx"); CG_TryPlayCustomSound(NULL, es->number, CHAN_AUTO, va("*gurp%d.wav",event-EV_WATER_GURP1+1), CS_BASIC ); break; case EV_WATER_DROWN: DEBUGNAME("EV_WATER_DROWN"); CG_TryPlayCustomSound(NULL, es->number, CHAN_AUTO, "*drown.wav", CS_BASIC ); break; case EV_ITEM_PICKUP: DEBUGNAME("EV_ITEM_PICKUP"); { gitem_t *item; int index; qboolean bHadItem = qfalse; index = es->eventParm; // player predicted if ( (char)index < 0 ) { index = -(char)index; bHadItem = qtrue; } if ( index >= bg_numItems ) { break; } item = &bg_itemlist[ index ]; cgi_S_StartSound (NULL, es->number, CHAN_AUTO, cgi_S_RegisterSound( item->pickup_sound ) ); #ifdef _IMMERSION cgi_FF_Start( cgi_FF_Register( item->pickup_force, FF_CHANNEL_TOUCH ), es->number ); #endif // _IMMERSION // show icon and name on status bar if ( es->number == cg.snap->ps.clientNum ) { CG_ItemPickup( index, bHadItem ); } } break; // // weapon events // case EV_NOAMMO: DEBUGNAME("EV_NOAMMO"); //cgi_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.noAmmoSound ); if ( es->number == cg.snap->ps.clientNum ) { CG_OutOfAmmoChange(); } break; case EV_CHANGE_WEAPON: DEBUGNAME("EV_CHANGE_WEAPON"); if ( es->weapon == WP_SABER ) { /* if ( !cent->gent || !cent->gent->client || (cent->currentState.saberInFlight == qfalse && cent->currentState.saberActive == qtrue) ) { cgi_S_StartSound (NULL, es->number, CHAN_AUTO, cgi_S_RegisterSound( "sound/weapons/saber/saberoffquick.wav" ) ); } */ if ( cent->gent && cent->gent->client ) { //if ( cent->gent->client->ps.saberInFlight ) {//if it's not in flight or lying around, turn it off! cent->currentState.saberActive = qfalse; } } } // FIXME: if it happens that you don't want the saber to play the switch sounds, feel free to modify this bit. if ( weaponData[cg.weaponSelect].selectSnd[0] ) { // custom select sound cgi_S_StartSound (NULL, es->number, CHAN_AUTO, cgi_S_RegisterSound( weaponData[cg.weaponSelect].selectSnd )); #ifdef _IMMERSION cgi_FF_Start( cgi_FF_Register( weaponData[cg.weaponSelect].selectFrc, FF_CHANNEL_WEAPON ), es->number ); #endif // _IMMERSION } else { // generic sound cgi_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.selectSound ); #ifdef _IMMERSION cgi_FF_Start( cgs.media.selectForce, es->number ); #endif // _IMMERSION } break; case EV_FIRE_WEAPON: DEBUGNAME("EV_FIRE_WEAPON"); CG_FireWeapon( cent, qfalse ); break; case EV_ALT_FIRE: DEBUGNAME("EV_ALT_FIRE"); CG_FireWeapon( cent, qtrue ); break; case EV_DISRUPTOR_MAIN_SHOT: DEBUGNAME("EV_DISRUPTOR_MAIN_SHOT"); FX_DisruptorMainShot( cent->currentState.origin2, cent->lerpOrigin ); break; case EV_DISRUPTOR_SNIPER_SHOT: DEBUGNAME("EV_DISRUPTOR_SNIPER_SHOT"); FX_DisruptorAltShot( cent->currentState.origin2, cent->lerpOrigin, cent->gent->alt_fire ); break; case EV_DISRUPTOR_SNIPER_MISS: DEBUGNAME("EV_DISRUPTOR_SNIPER_MISS"); FX_DisruptorAltMiss( cent->lerpOrigin, cent->gent->pos1 ); break; case EV_DEMP2_ALT_IMPACT: FX_DEMP2_AltDetonate( cent->lerpOrigin, es->eventParm ); break; case EV_CONC_ALT_SHOT: DEBUGNAME("EV_CONC_ALT_SHOT"); FX_ConcAltShot( cent->currentState.origin2, cent->lerpOrigin ); break; case EV_CONC_ALT_MISS: DEBUGNAME("EV_CONC_ALT_MISS"); FX_ConcAltMiss( cent->lerpOrigin, cent->gent->pos1 ); break; // case EV_POWERUP_SEEKER_FIRE: // DEBUGNAME("EV_POWERUP_SEEKER_FIRE"); // CG_FireSeeker( cent ); // break; case EV_POWERUP_BATTLESUIT: DEBUGNAME("EV_POWERUP_BATTLESUIT"); if ( es->number == cg.snap->ps.clientNum ) { cg.powerupActive = PW_BATTLESUIT; cg.powerupTime = cg.time; } //cgi_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.invulnoProtectSound ); break; case EV_KOTHOS_BEAM: DEBUGNAME("EV_KOTHOS_BEAM"); if ( Q_irand( 0, 1 ) ) { FX_KothosBeam( cg_entities[cent->currentState.otherEntityNum].gent->client->renderInfo.handRPoint, cg_entities[cent->currentState.otherEntityNum2].lerpOrigin ); } else { FX_KothosBeam( cg_entities[cent->currentState.otherEntityNum].gent->client->renderInfo.handLPoint, cg_entities[cent->currentState.otherEntityNum2].lerpOrigin ); } break; //================================================================= // // other events // case EV_REPLICATOR: DEBUGNAME("EV_REPLICATOR"); // FX_Replicator( cent, position ); break; case EV_BATTERIES_CHARGED: cg.batteryChargeTime = cg.time + 3000; cgi_S_StartSound( vec3_origin, es->number, CHAN_AUTO, cgs.media.batteryChargeSound ); break; case EV_DISINTEGRATION: { DEBUGNAME("EV_DISINTEGRATION"); qboolean makeNotSolid = qfalse; int disintPW = es->eventParm; int disintEffect = 0; int disintLength = 0; qhandle_t disintSound1 = NULL; qhandle_t disintSound2 = NULL; qhandle_t disintSound3 = NULL; switch( disintPW ) { case PW_DISRUPTION:// sniper rifle disintEffect = EF_DISINTEGRATION;//ef_ disintSound1 = cgs.media.disintegrateSound;//with scream disintSound2 = cgs.media.disintegrate2Sound;//no scream disintSound3 = cgs.media.disintegrate3Sound;//with inhuman scream disintLength = 2000; makeNotSolid = qtrue; break; /* case PW_SHOCKED:// arc welder disintEffect = EF_DISINT_1;//ef_ disintSound1 = NULL;//with scream disintSound2 = NULL;//no scream disintSound3 = NULL;//with inhuman scream disintLength = 4000; break; */ default: return; break; } if ( cent->gent->owner ) { cent->gent->owner->fx_time = cg.time; if ( cent->gent->owner->client ) { if ( disintSound1 && disintSound2 ) {//play an extra sound /* if ( cent->gent->owner->client->playerTeam == TEAM_STARFLEET || cent->gent->owner->client->playerTeam == TEAM_SCAVENGERS || cent->gent->owner->client->playerTeam == TEAM_MALON || cent->gent->owner->client->playerTeam == TEAM_IMPERIAL || cent->gent->owner->client->playerTeam == TEAM_HIROGEN || cent->gent->owner->client->playerTeam == TEAM_DISGUISE || cent->gent->owner->client->playerTeam == TEAM_KLINGON ) */ // listed all the non-humanoids, because there's a lot more humanoids class_t npc_class = cent->gent->owner->client->NPC_class; if( npc_class != CLASS_ATST && npc_class != CLASS_GONK && npc_class != CLASS_INTERROGATOR && npc_class != CLASS_MARK1 && npc_class != CLASS_MARK2 && npc_class != CLASS_MOUSE && npc_class != CLASS_PROBE && npc_class != CLASS_PROTOCOL && npc_class != CLASS_R2D2 && npc_class != CLASS_R5D2 && npc_class != CLASS_SEEKER && npc_class != CLASS_SENTRY) {//Only the humanoids scream cgi_S_StartSound ( NULL, cent->gent->owner->s.number, CHAN_VOICE, disintSound1 ); } // no more forge or 8472 // else if ( cent->gent->owner->client->playerTeam == TEAM_FORGE || // cent->gent->owner->client->playerTeam == TEAM_8472 ) // { // cgi_S_StartSound ( NULL, cent->gent->s.number, CHAN_VOICE, disintSound3 ); // } else { cgi_S_StartSound ( NULL, cent->gent->s.number, CHAN_AUTO, disintSound2 ); } } cent->gent->owner->s.powerups |= ( 1 << disintPW ); cent->gent->owner->client->ps.powerups[disintPW] = cg.time + disintLength; // Things that are being disintegrated should probably not be solid... if ( makeNotSolid && cent->gent->owner->client->playerTeam != TEAM_NEUTRAL ) { cent->gent->contents = CONTENTS_NONE; } } else { cent->gent->owner->s.eFlags = disintEffect;//FIXME: |= ? cent->gent->owner->delay = cg.time + disintLength; } } } break; // This does not necessarily have to be from a grenade... case EV_GRENADE_BOUNCE: DEBUGNAME("EV_GRENADE_BOUNCE"); CG_BounceEffect( cent, es->weapon, position, cent->gent->pos1 ); break; // // missile impacts // case EV_MISSILE_STICK: DEBUGNAME("EV_MISSILE_STICK"); CG_MissileStick( cent, es->weapon, position ); break; case EV_MISSILE_HIT: DEBUGNAME("EV_MISSILE_HIT"); CG_MissileHitPlayer( cent, es->weapon, position, cent->gent->pos1, cent->gent->alt_fire ); break; case EV_MISSILE_MISS: DEBUGNAME("EV_MISSILE_MISS"); CG_MissileHitWall( cent, es->weapon, position, cent->gent->pos1, cent->gent->alt_fire ); break; case EV_BMODEL_SOUND: DEBUGNAME("EV_BMODEL_SOUND"); cgi_S_StartSound( NULL, es->number, CHAN_AUTO, es->eventParm ); break; case EV_GENERAL_SOUND: DEBUGNAME("EV_GENERAL_SOUND"); if ( cgs.sound_precache[ es->eventParm ] ) { cgi_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.sound_precache[ es->eventParm ] ); } else { s = CG_ConfigString( CS_SOUNDS + es->eventParm ); CG_TryPlayCustomSound(NULL, es->number, CHAN_AUTO, s, CS_BASIC ); } break; case EV_GLOBAL_SOUND: // play from the player's head so it never diminishes DEBUGNAME("EV_GLOBAL_SOUND"); if ( cgs.sound_precache[ es->eventParm ] ) { cgi_S_StartSound (NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.sound_precache[ es->eventParm ] ); } else { s = CG_ConfigString( CS_SOUNDS + es->eventParm ); CG_TryPlayCustomSound( NULL, cg.snap->ps.clientNum, CHAN_AUTO, s, CS_BASIC ); } break; #ifdef _IMMERSION case EV_ENTITY_FORCE: // Plays force on entity DEBUGNAME("EV_ENTITY_FORCE"); if ( !cgs.force_precache[ es->eventParm ] ) { const char *name; int channel; if ( CG_ConfigForce( es->eventParm, name, channel ) ) { cgs.force_precache[ es->eventParm ] = cgi_FF_Register( name, channel ); } } cgi_FF_Start( cgs.force_precache[ es->eventParm ], es->number ); break; case EV_GLOBAL_FORCE: case EV_AREA_FORCE: DEBUGNAME("EV_AREA_FORCE"); // Plays force for anyone if ( !cgs.force_precache[ es->eventParm ] ) { const char *name; int channel; if ( CG_ConfigForce( es->eventParm, name, channel ) ) { cgs.force_precache[ es->eventParm ] = cgi_FF_Register( name, channel ); } } cgi_FF_Start( cgs.force_precache[ es->eventParm ], es->number ); break; case EV_FORCE_STOP: DEBUGNAME("EV_FORCE_STOP"); if ( es->eventParm < 0 ) { cgi_FF_StopAll( ); } else if ( es->eventParm < MAX_FORCES && cgs.force_precache[ es->eventParm ] ) { cgi_FF_Stop( cgs.force_precache[ es->eventParm ], es->number ); } break; #endif // _IMMERSION case EV_DRUGGED: DEBUGNAME("EV_DRUGGED"); if ( cent->gent && cent->gent->owner && cent->gent->owner->s.number == 0 ) { // Only allow setting up the wonky vision on the player..do it for 10 seconds...must be synchronized with calcs done in cg_view. Just search for cg.wonkyTime to find 'em. cg.wonkyTime = cg.time + 10000; } break; case EV_PAIN: { char *snd; const int health = es->eventParm; if ( cent->gent && cent->gent->NPC && (cent->gent->NPC->aiFlags & NPCAI_DIE_ON_IMPACT) ) { return; } //FIXME: don't do this if we're falling to our deaths... DEBUGNAME("EV_PAIN"); // don't do more than two pain sounds a second if ( cg.time - cent->pe.painTime < 500 ) { return; } if ( health < 25 ) { snd = "*pain100.wav"; } else if ( health < 50 ) { snd = "*pain75.wav"; } else if ( health < 75 ) { snd = "*pain50.wav"; } else { snd = "*pain25.wav"; } CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, snd, CS_BASIC ); // save pain time for programitic twitch animation cent->pe.painTime = cg.time; cent->pe.painDirection ^= 1; } break; case EV_DEATH1: case EV_DEATH2: case EV_DEATH3: DEBUGNAME("EV_DEATHx"); /* if ( cent->gent && cent->gent->NPC && (cent->gent->NPC->aiFlags & NPCAI_DIE_ON_IMPACT) ) { return; } */ CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*death%i.wav", event - EV_DEATH1 + 1), CS_BASIC ); break; // Called by the FxRunner entity...usually for Environmental FX Events case EV_PLAY_EFFECT: DEBUGNAME("EV_PLAY_EFFECT"); { const bool portalEnt = !!es->isPortalEnt; //the fxrunner spawning this effect is within a skyportal, so only render this effect within that portal. s = CG_ConfigString( CS_EFFECTS + es->eventParm ); // Ghoul2 Insert Start if (es->boltInfo != 0) { const bool isRelative = !!es->weapon; theFxScheduler.PlayEffect( s, cent->lerpOrigin, axis, es->boltInfo, -1, portalEnt, es->loopSound, isRelative ); //loopSound 0 = not looping, 1 for infinite, else duration } else { VectorCopy( cent->gent->pos3, axis[0] ); VectorCopy( cent->gent->pos4, axis[1] ); CrossProduct( axis[0], axis[1], axis[2] ); // the entNum the effect may be attached to #ifdef _IMMERSION if ( es->saberActive ) { theFxScheduler.PlayEffect( s, cent->lerpOrigin, axis, -1, FF_CLIENT( es->otherEntityNum ), portalEnt ); } else #endif // _IMMERSION if ( es->otherEntityNum ) { theFxScheduler.PlayEffect( s, cent->lerpOrigin, axis, -1, es->otherEntityNum, portalEnt ); } else { theFxScheduler.PlayEffect( s, cent->lerpOrigin, axis, -1, -1, portalEnt ); } } } // Ghoul2 Insert End break; // play an effect bolted onto a muzzle case EV_PLAY_MUZZLE_EFFECT: DEBUGNAME("EV_PLAY_MUZZLE_EFFECT"); s = CG_ConfigString( CS_EFFECTS + es->eventParm ); theFxScheduler.PlayEffect( s, es->otherEntityNum ); break; case EV_STOP_EFFECT: DEBUGNAME("EV_STOP_EFFECT"); { bool portalEnt = false; if ( es->isPortalEnt ) { //the fxrunner spawning this effect is within a skyportal, so only render this effect within that portal. portalEnt = true; } s = CG_ConfigString( CS_EFFECTS + es->eventParm ); if ( es->boltInfo != 0 ) { theFxScheduler.StopEffect( s, es->boltInfo, portalEnt ); } } break; case EV_TARGET_BEAM_DRAW: DEBUGNAME("EV_TARGET_BEAM_DRAW"); if ( cent->gent ) { s = CG_ConfigString( CS_EFFECTS + es->eventParm ); if ( s && s[0] ) { if ( cent->gent->delay ) { s2 = CG_ConfigString( CS_EFFECTS + cent->gent->delay ); } else { s2 = NULL; } CG_DrawTargetBeam( cent->lerpOrigin, cent->gent->s.origin2, cent->gent->pos1, s, s2 ); } /* else { int gack = 0; // this is bad if it get's here } */ } break; case EV_ANGER1: //Say when acquire an enemy when didn't have one before case EV_ANGER2: case EV_ANGER3: DEBUGNAME("EV_ANGERx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*anger%i.wav", event - EV_ANGER1 + 1), CS_COMBAT ); break; case EV_VICTORY1: //Say when killed an enemy case EV_VICTORY2: case EV_VICTORY3: DEBUGNAME("EV_VICTORYx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*victory%i.wav", event - EV_VICTORY1 + 1), CS_COMBAT ); break; case EV_CONFUSE1: //Say when confused case EV_CONFUSE2: case EV_CONFUSE3: DEBUGNAME("EV_CONFUSEDx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*confuse%i.wav", event - EV_CONFUSE1 + 1), CS_COMBAT ); break; case EV_PUSHED1: //Say when pushed case EV_PUSHED2: case EV_PUSHED3: DEBUGNAME("EV_PUSHEDx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*pushed%i.wav", event - EV_PUSHED1 + 1), CS_COMBAT ); break; case EV_CHOKE1: //Say when choking case EV_CHOKE2: case EV_CHOKE3: DEBUGNAME("EV_CHOKEx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*choke%i.wav", event - EV_CHOKE1 + 1), CS_COMBAT ); break; case EV_FFWARN: //Warn ally to stop shooting you DEBUGNAME("EV_FFWARN"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, "*ffwarn.wav", CS_COMBAT ); break; case EV_FFTURN: //Turn on ally after being shot by them DEBUGNAME("EV_FFTURN"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, "*ffturn.wav", CS_COMBAT ); break; //extra sounds for ST case EV_CHASE1: case EV_CHASE2: case EV_CHASE3: DEBUGNAME("EV_CHASEx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*chase%i.wav", event - EV_CHASE1 + 1), CS_EXTRA ); break; case EV_COVER1: case EV_COVER2: case EV_COVER3: case EV_COVER4: case EV_COVER5: DEBUGNAME("EV_COVERx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*cover%i.wav", event - EV_COVER1 + 1), CS_EXTRA ); break; case EV_DETECTED1: case EV_DETECTED2: case EV_DETECTED3: case EV_DETECTED4: case EV_DETECTED5: DEBUGNAME("EV_DETECTEDx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*detected%i.wav", event - EV_DETECTED1 + 1), CS_EXTRA ); break; case EV_GIVEUP1: case EV_GIVEUP2: case EV_GIVEUP3: case EV_GIVEUP4: DEBUGNAME("EV_GIVEUPx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*giveup%i.wav", event - EV_GIVEUP1 + 1), CS_EXTRA ); break; case EV_LOOK1: case EV_LOOK2: DEBUGNAME("EV_LOOKx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*look%i.wav", event - EV_LOOK1 + 1), CS_EXTRA ); break; case EV_LOST1: DEBUGNAME("EV_LOST1"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, "*lost1.wav", CS_EXTRA ); break; case EV_OUTFLANK1: case EV_OUTFLANK2: DEBUGNAME("EV_OUTFLANKx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*outflank%i.wav", event - EV_OUTFLANK1 + 1), CS_EXTRA ); break; case EV_ESCAPING1: case EV_ESCAPING2: case EV_ESCAPING3: DEBUGNAME("EV_ESCAPINGx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*escaping%i.wav", event - EV_ESCAPING1 + 1), CS_EXTRA ); break; case EV_SIGHT1: case EV_SIGHT2: case EV_SIGHT3: DEBUGNAME("EV_SIGHTx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*sight%i.wav", event - EV_SIGHT1 + 1), CS_EXTRA ); break; case EV_SOUND1: case EV_SOUND2: case EV_SOUND3: DEBUGNAME("EV_SOUNDx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*sound%i.wav", event - EV_SOUND1 + 1), CS_EXTRA ); break; case EV_SUSPICIOUS1: case EV_SUSPICIOUS2: case EV_SUSPICIOUS3: case EV_SUSPICIOUS4: case EV_SUSPICIOUS5: DEBUGNAME("EV_SUSPICIOUSx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*suspicious%i.wav", event - EV_SUSPICIOUS1 + 1), CS_EXTRA ); break; //extra sounds for Jedi case EV_COMBAT1: case EV_COMBAT2: case EV_COMBAT3: DEBUGNAME("EV_COMBATx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*combat%i.wav", event - EV_COMBAT1 + 1), CS_JEDI ); break; case EV_JDETECTED1: case EV_JDETECTED2: case EV_JDETECTED3: DEBUGNAME("EV_JDETECTEDx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*jdetected%i.wav", event - EV_JDETECTED1 + 1), CS_JEDI ); break; case EV_TAUNT1: case EV_TAUNT2: case EV_TAUNT3: DEBUGNAME("EV_TAUNTx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*taunt%i.wav", event - EV_TAUNT1 + 1), CS_JEDI ); break; case EV_JCHASE1: case EV_JCHASE2: case EV_JCHASE3: DEBUGNAME("EV_JCHASEx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*jchase%i.wav", event - EV_JCHASE1 + 1), CS_JEDI ); break; case EV_JLOST1: case EV_JLOST2: case EV_JLOST3: DEBUGNAME("EV_JLOSTx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*jlost%i.wav", event - EV_JLOST1 + 1), CS_JEDI ); break; case EV_DEFLECT1: case EV_DEFLECT2: case EV_DEFLECT3: DEBUGNAME("EV_DEFLECTx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*deflect%i.wav", event - EV_DEFLECT1 + 1), CS_JEDI ); break; case EV_GLOAT1: case EV_GLOAT2: case EV_GLOAT3: DEBUGNAME("EV_GLOATx"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*gloat%i.wav", event - EV_GLOAT1 + 1), CS_JEDI ); break; case EV_PUSHFAIL: DEBUGNAME("EV_PUSHFAIL"); CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, "*pushfail.wav", CS_JEDI ); break; case EV_USE_FORCE: DEBUGNAME("EV_USE_FORCEITEM"); CG_UseForce( cent ); break; case EV_USE_ITEM: DEBUGNAME("EV_USE_ITEM"); CG_UseItem( cent ); break; case EV_USE_INV_BINOCULARS: DEBUGNAME("EV_USE_INV_BINOCULARS"); UseItem(INV_ELECTROBINOCULARS ); break; case EV_USE_INV_BACTA: DEBUGNAME("EV_USE_INV_BACTA"); UseItem(INV_BACTA_CANISTER ); break; case EV_USE_INV_SEEKER: DEBUGNAME("EV_USE_INV_SEEKER"); UseItem(INV_SEEKER ); break; case EV_USE_INV_LIGHTAMP_GOGGLES: DEBUGNAME("EV_USE_INV_LIGHTAMP_GOGGLES"); UseItem(INV_LIGHTAMP_GOGGLES ); break; case EV_USE_INV_SENTRY: DEBUGNAME("EV_USE_INV_SENTRY"); UseItem(INV_SENTRY ); break; case EV_DEBUG_LINE: DEBUGNAME("EV_DEBUG_LINE"); CG_TestLine(position, es->origin2, es->time, (unsigned int)(es->time2), es->weapon); break; default: DEBUGNAME("UNKNOWN"); CG_Error( "Unknown event: %i", event ); break; } }
void CG_EntityEvent( centity_t *cent, vec3_t position ) { entityState_t *es; int event; vec3_t dir; const char *s; int clientNum; clientInfo_t *ci; int steptime; if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) steptime = 200; else steptime = BG_FindSteptimeForClass( cg.snap->ps.stats[ STAT_PCLASS ] ); es = ¢->currentState; event = es->event & ~EV_EVENT_BITS; if( cg_debugEvents.integer ) CG_Printf( "ent:%3i event:%3i ", es->number, event ); if( !event ) { DEBUGNAME("ZEROEVENT"); return; } clientNum = es->clientNum; if( clientNum < 0 || clientNum >= MAX_CLIENTS ) clientNum = 0; ci = &cgs.clientinfo[ clientNum ]; switch( event ) { // // movement generated events // case EV_FOOTSTEP: DEBUGNAME( "EV_FOOTSTEP" ); if( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE ) { if( ci->footsteps == FOOTSTEP_CUSTOM ) trap_S_StartSound( NULL, es->number, CHAN_BODY, ci->customFootsteps[ rand( ) & 3 ] ); else trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.footsteps[ ci->footsteps ][ rand( ) & 3 ] ); } break; case EV_FOOTSTEP_METAL: DEBUGNAME( "EV_FOOTSTEP_METAL" ); if( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE ) { if( ci->footsteps == FOOTSTEP_CUSTOM ) trap_S_StartSound( NULL, es->number, CHAN_BODY, ci->customMetalFootsteps[ rand( ) & 3 ] ); else trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_METAL ][ rand( ) & 3 ] ); } break; case EV_FOOTSTEP_SQUELCH: DEBUGNAME( "EV_FOOTSTEP_SQUELCH" ); if( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE ) { trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_FLESH ][ rand( ) & 3 ] ); } break; case EV_FOOTSPLASH: DEBUGNAME( "EV_FOOTSPLASH" ); if( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE ) { trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_SPLASH ][ rand( ) & 3 ] ); } break; case EV_FOOTWADE: DEBUGNAME( "EV_FOOTWADE" ); if( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE ) { trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_SPLASH ][ rand( ) & 3 ] ); } break; case EV_SWIM: DEBUGNAME( "EV_SWIM" ); if( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE ) { trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_SPLASH ][ rand( ) & 3 ] ); } break; case EV_FALL_SHORT: DEBUGNAME( "EV_FALL_SHORT" ); trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.landSound ); if( clientNum == cg.predictedPlayerState.clientNum ) { // smooth landing z changes cg.landChange = -8; cg.landTime = cg.time; } break; case EV_FALL_MEDIUM: DEBUGNAME( "EV_FALL_MEDIUM" ); // use normal pain sound trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*pain100_1.wav" ) ); if( clientNum == cg.predictedPlayerState.clientNum ) { // smooth landing z changes cg.landChange = -16; cg.landTime = cg.time; } break; case EV_FALL_FAR: DEBUGNAME( "EV_FALL_FAR" ); trap_S_StartSound (NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*fall1.wav" ) ); cent->pe.painTime = cg.time; // don't play a pain sound right after this if( clientNum == cg.predictedPlayerState.clientNum ) { // smooth landing z changes cg.landChange = -24; cg.landTime = cg.time; } break; case EV_FALLING: DEBUGNAME( "EV_FALLING" ); trap_S_StartSound( NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*falling1.wav" ) ); break; case EV_STEP_4: case EV_STEP_8: case EV_STEP_12: case EV_STEP_16: // smooth out step up transitions case EV_STEPDN_4: case EV_STEPDN_8: case EV_STEPDN_12: case EV_STEPDN_16: // smooth out step down transitions DEBUGNAME( "EV_STEP" ); { float oldStep; int delta; int step; if( clientNum != cg.predictedPlayerState.clientNum ) break; // if we are interpolating, we don't need to smooth steps if( cg.demoPlayback || ( cg.snap->ps.pm_flags & PMF_FOLLOW ) || cg_nopredict.integer || cg_synchronousClients.integer ) break; // check for stepping up before a previous step is completed delta = cg.time - cg.stepTime; if( delta < steptime ) oldStep = cg.stepChange * ( steptime - delta ) / steptime; else oldStep = 0; // add this amount if( event >= EV_STEPDN_4 ) { step = 4 * ( event - EV_STEPDN_4 + 1 ); cg.stepChange = oldStep - step; } else { step = 4 * ( event - EV_STEP_4 + 1 ); cg.stepChange = oldStep + step; } if( cg.stepChange > MAX_STEP_CHANGE ) cg.stepChange = MAX_STEP_CHANGE; else if( cg.stepChange < -MAX_STEP_CHANGE ) cg.stepChange = -MAX_STEP_CHANGE; cg.stepTime = cg.time; break; } case EV_JUMP: DEBUGNAME( "EV_JUMP" ); trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) ); if( BG_ClassHasAbility( cg.predictedPlayerState.stats[ STAT_PCLASS ], SCA_WALLJUMPER ) ) { vec3_t surfNormal, refNormal = { 0.0f, 0.0f, 1.0f }; vec3_t rotAxis; if( clientNum != cg.predictedPlayerState.clientNum ) break; //set surfNormal VectorCopy( cg.predictedPlayerState.grapplePoint, surfNormal ); //if we are moving from one surface to another smooth the transition if( !VectorCompare( surfNormal, cg.lastNormal ) && surfNormal[ 2 ] != 1.0f ) { CrossProduct( refNormal, surfNormal, rotAxis ); VectorNormalize( rotAxis ); //add the op CG_addSmoothOp( rotAxis, 15.0f, 1.0f ); } //copy the current normal to the lastNormal VectorCopy( surfNormal, cg.lastNormal ); } break; case EV_LEV1_GRAB: DEBUGNAME( "EV_LEV1_GRAB" ); trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.media.alienL1Grab ); break; case EV_LEV4_CHARGE_PREPARE: DEBUGNAME( "EV_LEV4_CHARGE_PREPARE" ); trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.media.alienL4ChargePrepare ); break; case EV_LEV4_CHARGE_START: DEBUGNAME( "EV_LEV4_CHARGE_START" ); //FIXME: stop cgs.media.alienL4ChargePrepare playing here trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.media.alienL4ChargeStart ); break; case EV_TAUNT: DEBUGNAME( "EV_TAUNT" ); trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*taunt.wav" ) ); break; case EV_WATER_TOUCH: DEBUGNAME( "EV_WATER_TOUCH" ); trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.watrInSound ); break; case EV_WATER_LEAVE: DEBUGNAME( "EV_WATER_LEAVE" ); trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.watrOutSound ); break; case EV_WATER_UNDER: DEBUGNAME( "EV_WATER_UNDER" ); trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.watrUnSound ); break; case EV_WATER_CLEAR: DEBUGNAME( "EV_WATER_CLEAR" ); trap_S_StartSound( NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*gasp.wav" ) ); break; // // weapon events // case EV_NOAMMO: DEBUGNAME( "EV_NOAMMO" ); { } break; case EV_CHANGE_WEAPON: DEBUGNAME( "EV_CHANGE_WEAPON" ); trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.selectSound ); break; case EV_FIRE_WEAPON: DEBUGNAME( "EV_FIRE_WEAPON" ); CG_FireWeapon( cent, WPM_PRIMARY ); break; case EV_FIRE_WEAPON2: DEBUGNAME( "EV_FIRE_WEAPON2" ); CG_FireWeapon( cent, WPM_SECONDARY ); break; case EV_FIRE_WEAPON3: DEBUGNAME( "EV_FIRE_WEAPON3" ); CG_FireWeapon( cent, WPM_TERTIARY ); break; //================================================================= // // other events // case EV_PLAYER_TELEPORT_IN: DEBUGNAME( "EV_PLAYER_TELEPORT_IN" ); //deprecated break; case EV_PLAYER_TELEPORT_OUT: DEBUGNAME( "EV_PLAYER_TELEPORT_OUT" ); CG_PlayerDisconnect( position ); break; case EV_BUILD_CONSTRUCT: DEBUGNAME( "EV_BUILD_CONSTRUCT" ); //do something useful here break; case EV_BUILD_DESTROY: DEBUGNAME( "EV_BUILD_DESTROY" ); //do something useful here break; case EV_RPTUSE_SOUND: DEBUGNAME( "EV_RPTUSE_SOUND" ); trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.repeaterUseSound ); break; case EV_GRENADE_BOUNCE: DEBUGNAME( "EV_GRENADE_BOUNCE" ); if( rand( ) & 1 ) trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.hardBounceSound1 ); else trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.hardBounceSound2 ); break; // // missile impacts // case EV_MISSILE_HIT: DEBUGNAME( "EV_MISSILE_HIT" ); ByteToDir( es->eventParm, dir ); CG_MissileHitPlayer( (weapon_t)es->weapon, (weaponMode_t)es->generic1, position, dir, es->otherEntityNum ); break; case EV_MISSILE_MISS: DEBUGNAME( "EV_MISSILE_MISS" ); ByteToDir( es->eventParm, dir ); CG_MissileHitWall( (weapon_t)es->weapon, (weaponMode_t)es->generic1, 0, position, dir, IMPACTSOUND_DEFAULT ); break; case EV_MISSILE_MISS_METAL: DEBUGNAME( "EV_MISSILE_MISS_METAL" ); ByteToDir( es->eventParm, dir ); CG_MissileHitWall( (weapon_t)es->weapon, (weaponMode_t)es->generic1, 0, position, dir, IMPACTSOUND_METAL ); break; case EV_HUMAN_BUILDABLE_EXPLOSION: DEBUGNAME( "EV_HUMAN_BUILDABLE_EXPLOSION" ); ByteToDir( es->eventParm, dir ); CG_HumanBuildableExplosion( position, dir ); break; case EV_ALIEN_BUILDABLE_EXPLOSION: DEBUGNAME( "EV_ALIEN_BUILDABLE_EXPLOSION" ); ByteToDir( es->eventParm, dir ); CG_AlienBuildableExplosion( position, dir ); break; case EV_TESLATRAIL: DEBUGNAME( "EV_TESLATRAIL" ); cent->currentState.weapon = WP_TESLAGEN; { centity_t *source = &cg_entities[ es->generic1 ]; centity_t *target = &cg_entities[ es->clientNum ]; vec3_t sourceOffset = { 0.0f, 0.0f, 28.0f }; if( !CG_IsTrailSystemValid( &source->muzzleTS ) ) { source->muzzleTS = CG_SpawnNewTrailSystem( cgs.media.teslaZapTS ); if( CG_IsTrailSystemValid( &source->muzzleTS ) ) { CG_SetAttachmentCent( &source->muzzleTS->frontAttachment, source ); CG_SetAttachmentCent( &source->muzzleTS->backAttachment, target ); CG_AttachToCent( &source->muzzleTS->frontAttachment ); CG_AttachToCent( &source->muzzleTS->backAttachment ); CG_SetAttachmentOffset( &source->muzzleTS->frontAttachment, sourceOffset ); source->muzzleTSDeathTime = cg.time + cg_teslaTrailTime.integer; } } } break; case EV_BULLET_HIT_WALL: DEBUGNAME( "EV_BULLET_HIT_WALL" ); ByteToDir( es->eventParm, dir ); CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, false, ENTITYNUM_WORLD ); break; case EV_BULLET_HIT_FLESH: DEBUGNAME( "EV_BULLET_HIT_FLESH" ); CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, true, es->eventParm ); break; case EV_SHOTGUN: DEBUGNAME( "EV_SHOTGUN" ); CG_ShotgunFire( es ); break; case EV_GENERAL_SOUND: DEBUGNAME( "EV_GENERAL_SOUND" ); if( cgs.gameSounds[ es->eventParm ] ) trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.gameSounds[ es->eventParm ] ); else { s = CG_ConfigString( CS_SOUNDS + es->eventParm ); trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, s ) ); } break; case EV_GLOBAL_SOUND: // play from the player's head so it never diminishes DEBUGNAME( "EV_GLOBAL_SOUND" ); if( cgs.gameSounds[ es->eventParm ] ) trap_S_StartSound( NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.gameSounds[ es->eventParm ] ); else { s = CG_ConfigString( CS_SOUNDS + es->eventParm ); trap_S_StartSound( NULL, cg.snap->ps.clientNum, CHAN_AUTO, CG_CustomSound( es->number, s ) ); } break; case EV_PAIN: // local player sounds are triggered in CG_CheckLocalSounds, // so ignore events on the player DEBUGNAME( "EV_PAIN" ); if( cent->currentState.number != cg.snap->ps.clientNum ) CG_PainEvent( cent, es->eventParm ); break; case EV_DEATH1: case EV_DEATH2: case EV_DEATH3: DEBUGNAME( "EV_DEATHx" ); trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, va( "*death%i.wav", event - EV_DEATH1 + 1 ) ) ); break; case EV_OBITUARY: DEBUGNAME( "EV_OBITUARY" ); CG_Obituary( es ); break; case EV_GIB_PLAYER: DEBUGNAME( "EV_GIB_PLAYER" ); // no gibbing break; case EV_STOPLOOPINGSOUND: DEBUGNAME( "EV_STOPLOOPINGSOUND" ); trap_S_StopLoopingSound( es->number ); es->loopSound = 0; break; case EV_DEBUG_LINE: DEBUGNAME( "EV_DEBUG_LINE" ); CG_Beam( cent ); break; case EV_BUILD_DELAY: DEBUGNAME( "EV_BUILD_DELAY" ); if( clientNum == cg.predictedPlayerState.clientNum ) { trap_S_StartLocalSound( cgs.media.buildableRepairedSound, CHAN_LOCAL_SOUND ); cg.lastBuildAttempt = cg.time; } break; case EV_BUILD_REPAIR: DEBUGNAME( "EV_BUILD_REPAIR" ); trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.buildableRepairSound ); break; case EV_BUILD_REPAIRED: DEBUGNAME( "EV_BUILD_REPAIRED" ); trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.buildableRepairedSound ); break; case EV_OVERMIND_ATTACK: DEBUGNAME( "EV_OVERMIND_ATTACK" ); if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_ALIENS ) { trap_S_StartLocalSound( cgs.media.alienOvermindAttack, CHAN_ANNOUNCER ); CG_CenterPrint( "The Overmind is under attack!", 200, GIANTCHAR_WIDTH * 4 ); } break; case EV_OVERMIND_DYING: DEBUGNAME( "EV_OVERMIND_DYING" ); if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_ALIENS ) { trap_S_StartLocalSound( cgs.media.alienOvermindDying, CHAN_ANNOUNCER ); CG_CenterPrint( "The Overmind is dying!", 200, GIANTCHAR_WIDTH * 4 ); } break; case EV_DCC_ATTACK: DEBUGNAME( "EV_DCC_ATTACK" ); if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_HUMANS ) { //trap_S_StartLocalSound( cgs.media.humanDCCAttack, CHAN_ANNOUNCER ); CG_CenterPrint( "Our base is under attack!", 200, GIANTCHAR_WIDTH * 4 ); } break; case EV_OVERMIND_SPAWNS: DEBUGNAME( "EV_OVERMIND_SPAWNS" ); if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_ALIENS ) { trap_S_StartLocalSound( cgs.media.alienOvermindSpawns, CHAN_ANNOUNCER ); CG_CenterPrint( "The Overmind needs spawns!", 200, GIANTCHAR_WIDTH * 4 ); } break; case EV_ALIEN_EVOLVE: DEBUGNAME( "EV_ALIEN_EVOLVE" ); trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.alienEvolveSound ); { particleSystem_t *ps = CG_SpawnNewParticleSystem( cgs.media.alienEvolvePS ); if( CG_IsParticleSystemValid( &ps ) ) { CG_SetAttachmentCent( &ps->attachment, cent ); CG_AttachToCent( &ps->attachment ); } } if( es->number == cg.clientNum ) { CG_ResetPainBlend( ); cg.spawnTime = cg.time; } break; case EV_ALIEN_EVOLVE_FAILED: DEBUGNAME( "EV_ALIEN_EVOLVE_FAILED" ); if( clientNum == cg.predictedPlayerState.clientNum ) { //FIXME: change to "negative" sound trap_S_StartLocalSound( cgs.media.buildableRepairedSound, CHAN_LOCAL_SOUND ); cg.lastEvolveAttempt = cg.time; } break; case EV_ALIEN_ACIDTUBE: DEBUGNAME( "EV_ALIEN_ACIDTUBE" ); { particleSystem_t *ps = CG_SpawnNewParticleSystem( cgs.media.alienAcidTubePS ); if( CG_IsParticleSystemValid( &ps ) ) { CG_SetAttachmentCent( &ps->attachment, cent ); ByteToDir( es->eventParm, dir ); CG_SetParticleSystemNormal( ps, dir ); CG_AttachToCent( &ps->attachment ); } } break; case EV_MEDKIT_USED: DEBUGNAME( "EV_MEDKIT_USED" ); trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.medkitUseSound ); break; case EV_PLAYER_RESPAWN: DEBUGNAME( "EV_PLAYER_RESPAWN" ); if( es->number == cg.clientNum ) cg.spawnTime = cg.time; break; default: DEBUGNAME( "UNKNOWN" ); CG_Error( "Unknown event: %i", event ); break; } }
void CG_EntityEvent( centity_t *cent, vec3_t position ) { entityState_t *es; int event; vec3_t dir; const char *s; int clientNum; clientInfo_t *ci; playerEntity_t *pe; fxParent_t fxParent; es = ¢->currentState; pe = ¢->pe; event = es->event & ~EV_EVENT_BITS; if ( cg_debugEvents.integer ) { CG_Printf( "ent:%3i event:%3i ", es->number, event ); } if ( !event ) { DEBUGNAME("ZEROEVENT"); return; } CG_DemoEntityEvent( cent ); clientNum = es->clientNum; if ( clientNum < 0 || clientNum >= MAX_CLIENTS ) { clientNum = 0; } ci = &cgs.clientinfo[ clientNum ]; switch ( es->eType ) { case ET_PLAYER: case ET_INVISIBLE: if ( ci->hide || !ci->infoValid ) return; case ET_MISSILE: if ( cg.defrag.detected && ( ci->hide || !ci->infoValid)) return; } if (cg.defrag.detected) { switch ( event ) { case EV_PLAYER_TELEPORT_IN: case EV_PLAYER_TELEPORT_OUT: case EV_MISSILE_HIT: case EV_MISSILE_MISS: case EV_MISSILE_MISS_METAL: case EV_RAILTRAIL: case EV_BULLET: case EV_BULLET_HIT_FLESH: case EV_BULLET_HIT_WALL: case EV_SHOTGUN: if ( ci->hide || !ci->infoValid ) return; } } switch ( event ) { // // movement generated events // case EV_FOOTSTEP: DEBUGNAME("EV_FOOTSTEP"); if (cg_footsteps.integer) { trap_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ ci->footsteps ][rand()&3] ); } break; case EV_FOOTSTEP_METAL: DEBUGNAME("EV_FOOTSTEP_METAL"); if (cg_footsteps.integer) { trap_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_METAL ][rand()&3] ); } break; case EV_FOOTSPLASH: DEBUGNAME("EV_FOOTSPLASH"); if (cg_footsteps.integer) { trap_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3] ); } break; case EV_FOOTWADE: DEBUGNAME("EV_FOOTWADE"); if (cg_footsteps.integer) { trap_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3] ); } break; case EV_SWIM: DEBUGNAME("EV_SWIM"); if (cg_footsteps.integer) { trap_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3] ); } break; case EV_FALL_SHORT: DEBUGNAME("EV_FALL_SHORT"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.landSound ); // smooth landing z changes pe->landChange = -8; pe->landTime = cg.time; break; case EV_FALL_MEDIUM: DEBUGNAME("EV_FALL_MEDIUM"); // use normal pain sound trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*pain100_1.wav" ) ); pe->landChange = -16; pe->landTime = cg.time; break; case EV_FALL_FAR: DEBUGNAME("EV_FALL_FAR"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*fall1.wav" ) ); cent->pe.painTime = cg.time; // don't play a pain sound right after this pe->landChange = -24; pe->landTime = cg.time; break; case EV_STEP_4: case EV_STEP_8: case EV_STEP_12: case EV_STEP_16: // smooth out step up transitions DEBUGNAME("EV_STEP"); { float oldStep; int delta; int step; // if we are interpolating, we don't need to smooth steps if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) || cg_nopredict.integer || cg_synchronousClients.integer ) { break; } // check for stepping up before a previous step is completed delta = cg.time - pe->stepTime; if (delta < STEP_TIME) { oldStep = pe->stepChange * (STEP_TIME - delta) / STEP_TIME; } else { oldStep = 0; } // add this amount step = 4 * (event - EV_STEP_4 + 1 ); pe->stepChange = oldStep + step; if ( pe->stepChange > MAX_STEP_CHANGE ) { pe->stepChange = MAX_STEP_CHANGE; } pe->stepTime = cg.time; break; } case EV_JUMP_PAD: DEBUGNAME("EV_JUMP_PAD"); // CG_Printf( "EV_JUMP_PAD w/effect #%i\n", es->eventParm ); { localEntity_t *smoke; vec3_t up = {0, 0, 1}; smoke = CG_SmokePuff( cent->lerpOrigin, up, 32, 1, 1, 1, 0.33f, 1000, cg.time, 0, LEF_PUFF_DONT_SCALE, cgs.media.smokePuffShader ); } // boing sound at origin, jump sound on player trap_S_StartSound ( cent->lerpOrigin, -1, CHAN_VOICE, cgs.media.jumpPadSound ); trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) ); break; case EV_JUMP: DEBUGNAME("EV_JUMP"); trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) ); break; case EV_TAUNT: DEBUGNAME("EV_TAUNT"); trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*taunt.wav" ) ); break; case EV_WATER_TOUCH: DEBUGNAME("EV_WATER_TOUCH"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrInSound ); break; case EV_WATER_LEAVE: DEBUGNAME("EV_WATER_LEAVE"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrOutSound ); break; case EV_WATER_UNDER: DEBUGNAME("EV_WATER_UNDER"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrUnSound ); break; case EV_WATER_CLEAR: DEBUGNAME("EV_WATER_CLEAR"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*gasp.wav" ) ); break; case EV_ITEM_PICKUP: DEBUGNAME("EV_ITEM_PICKUP"); { gitem_t *item; int index; index = es->eventParm; // player predicted if ( index < 1 || index >= bg_numItems ) { break; } item = &bg_itemlist[ index ]; // powerups and team items will have a separate global sound, this one // will be played at prediction time if ( item->giType == IT_POWERUP || item->giType == IT_TEAM) { trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.n_healthSound ); } else if (item->giType == IT_PERSISTANT_POWERUP) { } else { trap_S_StartSound (NULL, es->number, CHAN_AUTO, trap_S_RegisterSound( item->pickup_sound, qfalse ) ); } // show icon and name on status bar if ( cg.playerCent && es->number == cg.playerCent->currentState.number ) { CG_ItemPickup( index ); } } break; case EV_GLOBAL_ITEM_PICKUP: DEBUGNAME("EV_GLOBAL_ITEM_PICKUP"); { gitem_t *item; int index; index = es->eventParm; // player predicted if ( index < 1 || index >= bg_numItems ) { break; } item = &bg_itemlist[ index ]; // powerup pickups are global if( item->pickup_sound ) { if( cg.playerCent ) trap_S_StartSound (NULL, cg.playerCent->currentState.number, CHAN_AUTO, trap_S_RegisterSound( item->pickup_sound, qfalse ) ); else trap_S_StartSound (NULL, ENTITYNUM_NONE, CHAN_AUTO, trap_S_RegisterSound( item->pickup_sound, qfalse ) ); } // show icon and name on status bar if ( cg.playerCent && es->number == cg.playerCent->currentState.number ) { CG_ItemPickup( index ); } } break; // // weapon events // case EV_NOAMMO: DEBUGNAME("EV_NOAMMO"); // trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.noAmmoSound ); if ( es->number == cg.snap->ps.clientNum ) { CG_OutOfAmmoChange(); } break; case EV_CHANGE_WEAPON: DEBUGNAME("EV_CHANGE_WEAPON"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.selectSound ); break; case EV_FIRE_WEAPON: DEBUGNAME("EV_FIRE_WEAPON"); CG_FireWeapon( cent ); break; case EV_USE_ITEM0: DEBUGNAME("EV_USE_ITEM0"); CG_UseItem( cent ); break; case EV_USE_ITEM1: DEBUGNAME("EV_USE_ITEM1"); CG_UseItem( cent ); break; case EV_USE_ITEM2: DEBUGNAME("EV_USE_ITEM2"); CG_UseItem( cent ); break; case EV_USE_ITEM3: DEBUGNAME("EV_USE_ITEM3"); CG_UseItem( cent ); break; case EV_USE_ITEM4: DEBUGNAME("EV_USE_ITEM4"); CG_UseItem( cent ); break; case EV_USE_ITEM5: DEBUGNAME("EV_USE_ITEM5"); CG_UseItem( cent ); break; case EV_USE_ITEM6: DEBUGNAME("EV_USE_ITEM6"); CG_UseItem( cent ); break; case EV_USE_ITEM7: DEBUGNAME("EV_USE_ITEM7"); CG_UseItem( cent ); break; case EV_USE_ITEM8: DEBUGNAME("EV_USE_ITEM8"); CG_UseItem( cent ); break; case EV_USE_ITEM9: DEBUGNAME("EV_USE_ITEM9"); CG_UseItem( cent ); break; case EV_USE_ITEM10: DEBUGNAME("EV_USE_ITEM10"); CG_UseItem( cent ); break; case EV_USE_ITEM11: DEBUGNAME("EV_USE_ITEM11"); CG_UseItem( cent ); break; case EV_USE_ITEM12: DEBUGNAME("EV_USE_ITEM12"); CG_UseItem( cent ); break; case EV_USE_ITEM13: DEBUGNAME("EV_USE_ITEM13"); CG_UseItem( cent ); break; case EV_USE_ITEM14: DEBUGNAME("EV_USE_ITEM14"); CG_UseItem( cent ); break; //================================================================= // // other events // case EV_PLAYER_TELEPORT_IN: DEBUGNAME("EV_PLAYER_TELEPORT_IN"); VectorCopy( position, fxParent.origin ); fxParent.origin[2] -= 24; fxParent.flags = FXP_ORIGIN; trap_FX_Run( cgs.fx.player.teleportIn, &fxParent, cent ); break; trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.teleInSound ); CG_SpawnEffect( position); break; case EV_PLAYER_TELEPORT_OUT: DEBUGNAME("EV_PLAYER_TELEPORT_OUT"); VectorCopy( position, fxParent.origin ); fxParent.origin[2] -= 24; fxParent.flags = FXP_ORIGIN; trap_FX_Run( cgs.fx.player.teleportOut, &fxParent, cent ); break; trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.teleOutSound ); CG_SpawnEffect( position); break; case EV_ITEM_POP: DEBUGNAME("EV_ITEM_POP"); trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.respawnSound ); break; case EV_ITEM_RESPAWN: DEBUGNAME("EV_ITEM_RESPAWN"); cent->miscTime = cg.time; // scale up from this trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.respawnSound ); break; case EV_GRENADE_BOUNCE: DEBUGNAME("EV_GRENADE_BOUNCE"); if ( rand() & 1 ) { trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.hgrenb1aSound ); } else { trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.hgrenb2aSound ); } break; case EV_SCOREPLUM: DEBUGNAME("EV_SCOREPLUM"); CG_ScorePlum( cent->currentState.otherEntityNum, cent->lerpOrigin, cent->currentState.time ); break; // // missile impacts // case EV_MISSILE_HIT: DEBUGNAME("EV_MISSILE_HIT"); ByteToDir( es->eventParm, dir ); CG_MissileHitPlayer( es->weapon, position, dir, es->otherEntityNum ); break; case EV_MISSILE_MISS: DEBUGNAME("EV_MISSILE_MISS"); ByteToDir( es->eventParm, dir ); CG_MissileHitWall( es->weapon, 0, position, dir, IMPACTSOUND_DEFAULT ); break; case EV_MISSILE_MISS_METAL: DEBUGNAME("EV_MISSILE_MISS_METAL"); ByteToDir( es->eventParm, dir ); CG_MissileHitWall( es->weapon, 0, position, dir, IMPACTSOUND_METAL ); break; case EV_RAILTRAIL: DEBUGNAME("EV_RAILTRAIL"); cent->currentState.weapon = WP_RAILGUN; // if the end was on a nomark surface, don't make an explosion CG_RailTrail( ci, es->origin2, es->pos.trBase ); if ( es->eventParm != 255 ) { ByteToDir( es->eventParm, dir ); CG_MissileHitWall( es->weapon, es->clientNum, position, dir, IMPACTSOUND_DEFAULT ); } break; case EV_BULLET_HIT_WALL: DEBUGNAME("EV_BULLET_HIT_WALL"); ByteToDir( es->eventParm, dir ); CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD ); break; case EV_BULLET_HIT_FLESH: DEBUGNAME("EV_BULLET_HIT_FLESH"); CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qtrue, es->eventParm ); break; case EV_SHOTGUN: DEBUGNAME("EV_SHOTGUN"); CG_ShotgunFire( es ); break; case EV_GENERAL_SOUND: DEBUGNAME("EV_GENERAL_SOUND"); if ( cgs.gameSounds[ es->eventParm ] ) { trap_S_StartSound (NULL, es->number, CHAN_VOICE, cgs.gameSounds[ es->eventParm ] ); } else { s = CG_ConfigString( CS_SOUNDS + es->eventParm ); trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, s ) ); } break; case EV_GLOBAL_SOUND: // play from the player's head so it never diminishes DEBUGNAME("EV_GLOBAL_SOUND"); if ( cgs.gameSounds[ es->eventParm ] ) { trap_S_StartSound (NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.gameSounds[ es->eventParm ] ); } else { s = CG_ConfigString( CS_SOUNDS + es->eventParm ); trap_S_StartSound (NULL, cg.snap->ps.clientNum, CHAN_AUTO, CG_CustomSound( es->number, s ) ); } break; case EV_GLOBAL_TEAM_SOUND: // play from the player's head so it never diminishes { DEBUGNAME("EV_GLOBAL_TEAM_SOUND"); switch( es->eventParm ) { case GTS_RED_CAPTURE: // CTF: red team captured the blue flag, 1FCTF: red team captured the neutral flag if ( cgs.clientinfo[cg.clientNum].team == TEAM_RED ) CG_AddBufferedSound( cgs.media.captureYourTeamSound ); else CG_AddBufferedSound( cgs.media.captureOpponentSound ); break; case GTS_BLUE_CAPTURE: // CTF: blue team captured the red flag, 1FCTF: blue team captured the neutral flag if ( cgs.clientinfo[cg.clientNum].team == TEAM_BLUE ) CG_AddBufferedSound( cgs.media.captureYourTeamSound ); else CG_AddBufferedSound( cgs.media.captureOpponentSound ); break; case GTS_RED_RETURN: // CTF: blue flag returned, 1FCTF: never used if ( cgs.clientinfo[cg.clientNum].team == TEAM_RED ) CG_AddBufferedSound( cgs.media.returnYourTeamSound ); else CG_AddBufferedSound( cgs.media.returnOpponentSound ); // CG_AddBufferedSound( cgs.media.blueFlagReturnedSound ); break; case GTS_BLUE_RETURN: // CTF red flag returned, 1FCTF: neutral flag returned if ( cgs.clientinfo[cg.clientNum].team == TEAM_BLUE ) CG_AddBufferedSound( cgs.media.returnYourTeamSound ); else CG_AddBufferedSound( cgs.media.returnOpponentSound ); // CG_AddBufferedSound( cgs.media.redFlagReturnedSound ); break; case GTS_RED_TAKEN: // CTF: red team took blue flag, 1FCTF: blue team took the neutral flag // if this player picked up the flag then a sound is played in CG_CheckLocalSounds if (cg.snap->ps.powerups[PW_BLUEFLAG] || cg.snap->ps.powerups[PW_NEUTRALFLAG]) { } else { if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) { CG_AddBufferedSound( cgs.media.enemyTookYourFlagSound ); } else if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) { CG_AddBufferedSound( cgs.media.yourTeamTookEnemyFlagSound ); } } break; case GTS_BLUE_TAKEN: // CTF: blue team took the red flag, 1FCTF red team took the neutral flag // if this player picked up the flag then a sound is played in CG_CheckLocalSounds if (cg.snap->ps.powerups[PW_REDFLAG] || cg.snap->ps.powerups[PW_NEUTRALFLAG]) { } else { if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) { CG_AddBufferedSound( cgs.media.enemyTookYourFlagSound ); } else if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) { CG_AddBufferedSound( cgs.media.yourTeamTookEnemyFlagSound ); } } break; case GTS_REDOBELISK_ATTACKED: // Overload: red obelisk is being attacked if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) { CG_AddBufferedSound( cgs.media.yourBaseIsUnderAttackSound ); } break; case GTS_BLUEOBELISK_ATTACKED: // Overload: blue obelisk is being attacked if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) { CG_AddBufferedSound( cgs.media.yourBaseIsUnderAttackSound ); } break; case GTS_REDTEAM_SCORED: CG_AddBufferedSound(cgs.media.redScoredSound); break; case GTS_BLUETEAM_SCORED: CG_AddBufferedSound(cgs.media.blueScoredSound); break; case GTS_REDTEAM_TOOK_LEAD: CG_AddBufferedSound(cgs.media.redLeadsSound); break; case GTS_BLUETEAM_TOOK_LEAD: CG_AddBufferedSound(cgs.media.blueLeadsSound); break; case GTS_TEAMS_ARE_TIED: CG_AddBufferedSound( cgs.media.teamsTiedSound ); break; default: break; } break; } case EV_PAIN: // local player sounds are triggered in CG_CheckLocalSounds, // so ignore events on the player DEBUGNAME("EV_PAIN"); if ( cent->currentState.number != cg.snap->ps.clientNum ) { CG_PainEvent( cent, es->eventParm ); } break; case EV_DEATH1: case EV_DEATH2: case EV_DEATH3: DEBUGNAME("EV_DEATHx"); trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, va("*death%i.wav", event - EV_DEATH1 + 1) ) ); break; case EV_OBITUARY: DEBUGNAME("EV_OBITUARY"); CG_Obituary( es ); break; // // powerup events // case EV_POWERUP_QUAD: DEBUGNAME("EV_POWERUP_QUAD"); if ( es->number == cg.snap->ps.clientNum ) { cg.powerupActive = PW_QUAD; cg.powerupTime = cg.time; } trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.quadSound ); break; case EV_POWERUP_BATTLESUIT: DEBUGNAME("EV_POWERUP_BATTLESUIT"); if ( es->number == cg.snap->ps.clientNum ) { cg.powerupActive = PW_BATTLESUIT; cg.powerupTime = cg.time; } trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.protectSound ); break; case EV_POWERUP_REGEN: DEBUGNAME("EV_POWERUP_REGEN"); if ( es->number == cg.snap->ps.clientNum ) { cg.powerupActive = PW_REGEN; cg.powerupTime = cg.time; } trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.regenSound ); break; case EV_GIB_PLAYER: DEBUGNAME("EV_GIB_PLAYER"); // don't play gib sound when using the kamikaze because it interferes // with the kamikaze sound, downside is that the gib sound will also // not be played when someone is gibbed while just carrying the kamikaze if ( !(es->eFlags & EF_KAMIKAZE) ) { trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.gibSound ); } if (cg_gibDirectional.integer == 1) { float speed; VectorCopy( cent->currentState.pos.trDelta, dir ); speed = VectorNormalize( dir ); if ( speed > 500 ) { VectorScale( dir, 500, dir ); CG_GibPlayer( cent->lerpOrigin, dir ); } else { CG_GibPlayer( cent->lerpOrigin, cent->currentState.pos.trDelta ); } } else if (cg_gibDirectional.integer == 2 && es->eventParm >= 0 && es->eventParm < MAX_CLIENTS && (cg_entities[es->eventParm].currentValid || cg.snap->ps.clientNum == es->eventParm)) { if ( cg.snap->ps.clientNum == es->eventParm) { VectorSubtract( cent->lerpOrigin, cg.predictedPlayerState.origin, dir ); } else { VectorSubtract( cent->lerpOrigin, cg_entities[es->eventParm].lerpOrigin, dir ); } VectorNormalize( dir ); VectorScale( dir, 300, dir ); CG_GibPlayer( cent->lerpOrigin, dir ); } else { CG_GibPlayer( cent->lerpOrigin, vec3_origin ); } break; case EV_STOPLOOPINGSOUND: DEBUGNAME("EV_STOPLOOPINGSOUND"); trap_S_StopLoopingSound( es->number ); es->loopSound = 0; break; case EV_DEBUG_LINE: DEBUGNAME("EV_DEBUG_LINE"); CG_Beam( cent ); break; default: DEBUGNAME("UNKNOWN"); if (mov_debug.integer) CG_Printf( "Unknown event: %i\n", event ); break; } }