diff options
author | Tony J. White <tjw@tjw.org> | 2009-10-03 11:44:02 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2013-01-03 00:15:17 +0000 |
commit | 122de31ac2834809fb15088eda6f5278d4525fb1 (patch) | |
tree | dcb4c460a2cae6df5195bd4eb21c32a7ee309ba1 /src/cgame | |
parent | 82ef46c4c099fbfed24fa326ee6f501ad5535a30 (diff) |
* voice chat stuff (no, not like TeamSpeak)
Diffstat (limited to 'src/cgame')
-rw-r--r-- | src/cgame/cg_local.h | 11 | ||||
-rw-r--r-- | src/cgame/cg_main.c | 13 | ||||
-rw-r--r-- | src/cgame/cg_players.c | 11 | ||||
-rw-r--r-- | src/cgame/cg_servercmds.c | 193 |
4 files changed, 226 insertions, 2 deletions
diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h index 2aeaf95f..de97e48b 100644 --- a/src/cgame/cg_local.h +++ b/src/cgame/cg_local.h @@ -771,6 +771,9 @@ typedef struct sfxHandle_t customFootsteps[ 4 ]; sfxHandle_t customMetalFootsteps[ 4 ]; + + char voice[ MAX_VOICE_NAME_LEN ]; + int voiceTime; } clientInfo_t; @@ -1037,7 +1040,6 @@ typedef struct // attacking player int attackerTime; - int voiceTime; // reward medals int rewardStack; @@ -1404,6 +1406,9 @@ typedef struct // media cgMedia_t media; + + voice_t *voices; + clientList_t ignoreList; } cgs_t; //============================================================================== @@ -1540,6 +1545,8 @@ extern vmCvar_t cg_painBlendZoom; extern vmCvar_t cg_stickySpec; extern vmCvar_t cg_alwaysSprint; +extern vmCvar_t cg_debugVoices; + extern vmCvar_t ui_currentClass; extern vmCvar_t ui_carriage; extern vmCvar_t ui_stages; @@ -1553,6 +1560,8 @@ extern vmCvar_t cg_debugRandom; extern vmCvar_t cg_optimizePrediction; extern vmCvar_t cg_projectileNudge; +extern vmCvar_t cg_voice; + // // cg_main.c // diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c index 9dd1a953..c36c447d 100644 --- a/src/cgame/cg_main.c +++ b/src/cgame/cg_main.c @@ -230,6 +230,8 @@ vmCvar_t cg_painBlendZoom; vmCvar_t cg_stickySpec; vmCvar_t cg_alwaysSprint; +vmCvar_t cg_debugVoices; + vmCvar_t ui_currentClass; vmCvar_t ui_carriage; vmCvar_t ui_stages; @@ -243,6 +245,8 @@ vmCvar_t cg_debugRandom; vmCvar_t cg_optimizePrediction; vmCvar_t cg_projectileNudge; +vmCvar_t cg_voice; + typedef struct { @@ -352,6 +356,8 @@ static cvarTable_t cvarTable[ ] = { &cg_painBlendMax, "cg_painBlendMax", "0.7", 0 }, { &cg_painBlendScale, "cg_painBlendScale", "7.0", 0 }, { &cg_painBlendZoom, "cg_painBlendZoom", "0.65", 0 }, + + { &cg_debugVoices, "cg_debugVoices", "0", 0 }, { &ui_currentClass, "ui_currentClass", "0", 0 }, { &ui_carriage, "ui_carriage", "", 0 }, @@ -390,7 +396,9 @@ static cvarTable_t cvarTable[ ] = { &cg_oldRail, "cg_oldRail", "1", CVAR_ARCHIVE}, { &cg_oldRocket, "cg_oldRocket", "1", CVAR_ARCHIVE}, { &cg_oldPlasma, "cg_oldPlasma", "1", CVAR_ARCHIVE}, - { &cg_trueLightning, "cg_trueLightning", "0.0", CVAR_ARCHIVE} + { &cg_trueLightning, "cg_trueLightning", "0.0", CVAR_ARCHIVE}, + + { &cg_voice, "voice", "default", CVAR_USERINFO|CVAR_ARCHIVE} }; static int cvarTableSize = sizeof( cvarTable ) / sizeof( cvarTable[0] ); @@ -1850,6 +1858,9 @@ void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum ) CG_UpdateMediaFraction( 1.0f ); CG_InitBuildables( ); + + cgs.voices = BG_VoiceInit( ); + BG_PrintVoices( cgs.voices, cg_debugVoices.integer ); CG_RegisterClients( ); // if low on memory, some clients will be deferred diff --git a/src/cgame/cg_players.c b/src/cgame/cg_players.c index dcbe86db..1cebf451 100644 --- a/src/cgame/cg_players.c +++ b/src/cgame/cg_players.c @@ -746,6 +746,13 @@ void CG_NewClientInfo( int clientNum ) // the old value memset( &newInfo, 0, sizeof( newInfo ) ); + + // grab our own ignoreList + if( clientNum == cg.predictedPlayerState.clientNum ) + { + v = Info_ValueForKey( configstring, "ig" ); + BG_ClientListParse( &cgs.ignoreList, v ); + } // isolate the player's name v = Info_ValueForKey( configstring, "n" ); @@ -784,6 +791,10 @@ void CG_NewClientInfo( int clientNum ) *slash = 0; } + // voice + v = Info_ValueForKey( configstring, "v" ); + Q_strncpyz( newInfo.voice, v, sizeof( newInfo.voice ) ); + // replace whatever was there with the new one newInfo.infoValid = qtrue; *ci = newInfo; diff --git a/src/cgame/cg_servercmds.c b/src/cgame/cg_servercmds.c index 6c45fcb1..4742eabe 100644 --- a/src/cgame/cg_servercmds.c +++ b/src/cgame/cg_servercmds.c @@ -903,6 +903,193 @@ void CG_Menu( int menu, int arg ) /* ================= +CG_Say +================= +*/ +static void CG_Say( int clientNum, char *text ) +{ + clientInfo_t *ci; + char sayText[ MAX_SAY_TEXT ] = {""}; + + if( clientNum < 0 || clientNum >= MAX_CLIENTS ) + return; + + ci = &cgs.clientinfo[ clientNum ]; + Com_sprintf( sayText, sizeof( sayText ), + "%s: " S_COLOR_WHITE S_COLOR_GREEN "%s" S_COLOR_WHITE "\n", + ci->name, text ); + + CG_RemoveChatEscapeChar( sayText ); + if( BG_ClientListTest( &cgs.ignoreList, clientNum ) ) + CG_Printf( "[skipnotify]%s", sayText ); + else + CG_Printf( "%s", sayText ); +} + +/* +================= +CG_SayTeam +================= +*/ +static void CG_SayTeam( int clientNum, char *text ) +{ + clientInfo_t *ci; + char sayText[ MAX_SAY_TEXT ] = {""}; + + if( clientNum < 0 || clientNum >= MAX_CLIENTS ) + return; + + + ci = &cgs.clientinfo[ clientNum ]; + Com_sprintf( sayText, sizeof( sayText ), + "%s: " S_COLOR_WHITE S_COLOR_CYAN "%s" S_COLOR_WHITE "\n", + ci->name, text ); + + CG_RemoveChatEscapeChar( sayText ); + if( BG_ClientListTest( &cgs.ignoreList, clientNum ) ) + CG_Printf( "[skipnotify]%s", sayText ); + else + CG_Printf( "%s", sayText ); +} + +/* +================= +CG_VoiceTrack + +return the voice indexed voice track or print errors quietly to console +in case someone is on an unpure server and wants to know which voice pak +is missing or incomplete +================= +*/ +static voiceTrack_t *CG_VoiceTrack( char *voice, int cmd, int track ) +{ + voice_t *v; + voiceCmd_t *c; + voiceTrack_t *t; + + v = BG_VoiceByName( cgs.voices, voice ); + if( !v ) + { + CG_Printf( "[skipnotify]WARNING: could not find voice \"%s\"\n", voice ); + return NULL; + } + c = BG_VoiceCmdByNum( v->cmds, cmd ); + if( !c ) + { + CG_Printf( "[skipnotify]WARNING: could not find command %d " + "in voice \"%s\"\n", cmd, voice ); + return NULL; + } + t = BG_VoiceTrackByNum( c->tracks, track ); + if( !t ) + { + CG_Printf( "[skipnotify]WARNING: could not find track %d for command %d in " + "voice \"%s\"\n", track, cmd, voice ); + return NULL; + } + return t; +} + +/* +================= +CG_ParseVoice + +voice clientNum vChan cmdNum trackNum [sayText] +================= +*/ +static void CG_ParseVoice( void ) +{ + int clientNum; + voiceChannel_t vChan; + char sayText[ MAX_SAY_TEXT] = {""}; + voiceTrack_t *track; + clientInfo_t *ci; + + if( trap_Argc() < 5 || trap_Argc() > 6 ) + return; + + if( trap_Argc() == 6 ) + Q_strncpyz( sayText, CG_Argv( 5 ), sizeof( sayText ) ); + + clientNum = atoi( CG_Argv( 1 ) ); + if( clientNum < 0 || clientNum >= MAX_CLIENTS ) + return; + + vChan = atoi( CG_Argv( 2 ) ); + if( vChan < 0 || vChan >= VOICE_CHAN_NUM_CHANS ) + return; + + if( cg_teamChatsOnly.integer && vChan != VOICE_CHAN_TEAM ) + return; + + ci = &cgs.clientinfo[ clientNum ]; + + // this joker is still talking + if( ci->voiceTime > cg.time ) + return; + + track = CG_VoiceTrack( ci->voice, atoi( CG_Argv( 3 ) ), atoi( CG_Argv( 4 ) ) ); + + // keep track of how long the player will be speaking + // assume it takes 3s to say "*unintelligible gibberish*" + if( track ) + ci->voiceTime = cg.time + track->duration; + else + ci->voiceTime = cg.time + 3000; + + if( !sayText[ 0 ] ) + { + if( track ) + Q_strncpyz( sayText, track->text, sizeof( sayText ) ); + else + Q_strncpyz( sayText, "*unintelligible gibberish*", sizeof( sayText ) ); + } + + if( !cg_noVoiceText.integer ) + { + switch( vChan ) + { + case VOICE_CHAN_ALL: + CG_Say( clientNum, sayText ); + break; + case VOICE_CHAN_TEAM: + CG_SayTeam( clientNum, sayText ); + break; + default: + break; + } + } + + // playing voice audio tracks disabled + if( cg_noVoiceChats.integer ) + return; + + // no audio track to play + if( !track ) + return; + + // don't play audio track for lamers + if( BG_ClientListTest( &cgs.ignoreList, clientNum ) ) + return; + + switch( vChan ) + { + case VOICE_CHAN_ALL: + trap_S_StartLocalSound( track->track, CHAN_VOICE ); + break; + case VOICE_CHAN_TEAM: + trap_S_StartLocalSound( track->track, CHAN_VOICE ); + break; + case VOICE_CHAN_LOCAL: + trap_S_StartSound( NULL, clientNum, CHAN_VOICE, track->track ); + break; + default: + break; + } +} + +/* +================= CG_ServerCommand The string has been tokenized and can be retrieved with @@ -970,6 +1157,12 @@ static void CG_ServerCommand( void ) CG_Printf( "%s\n", text ); return; } + + if( !strcmp( cmd, "voice" ) ) + { + CG_ParseVoice( ); + return; + } if( !strcmp( cmd, "scores" ) ) { |