summaryrefslogtreecommitdiff
path: root/src/cgame
diff options
context:
space:
mode:
authorTony J. White <tjw@tjw.org>2009-10-03 11:44:02 +0000
committerTim Angus <tim@ngus.net>2013-01-03 00:15:17 +0000
commit122de31ac2834809fb15088eda6f5278d4525fb1 (patch)
treedcb4c460a2cae6df5195bd4eb21c32a7ee309ba1 /src/cgame
parent82ef46c4c099fbfed24fa326ee6f501ad5535a30 (diff)
* voice chat stuff (no, not like TeamSpeak)
Diffstat (limited to 'src/cgame')
-rw-r--r--src/cgame/cg_local.h11
-rw-r--r--src/cgame/cg_main.c13
-rw-r--r--src/cgame/cg_players.c11
-rw-r--r--src/cgame/cg_servercmds.c193
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" ) )
{