Example #1
0
//// HOST_SAY
// String comes in as
// say blah blah blah
// or as
// blah blah blah
//
void Host_Say( edict_t *pEdict, const CCommand &args, MessageMode_t messageMode )
{
	CBasePlayer *client;
	int		j;
	char	*p;
	char    szTemp[256];
	char	text[256];
	const char *cpSay = "say";
	const char *cpSayTeam = "say_team";
	const char *cpSaySpec = "say_spec";
	const char *pcmd = args[0];
	bool bSenderDead = false;

	// We can get a raw string now, without the "say " prepended
	if ( args.ArgC() == 0 )
		return;

	if ( !stricmp( pcmd, cpSay) || !stricmp( pcmd, cpSayTeam ) || !stricmp( pcmd, cpSaySpec ) )
	{
		if ( args.ArgC() >= 2 )
		{
			p = (char *)args.ArgS();
		}
		else
		{
			// say with a blank message, nothing to do
			return;
		}
	}
	else  // Raw text, need to prepend argv[0]
	{
		if ( args.ArgC() >= 2 )
		{
			Q_snprintf( szTemp,sizeof(szTemp), "%s %s", ( char * )pcmd, (char *)args.ArgS() );
		}
		else
		{
			// Just a one word command, use the first word...sigh
			Q_snprintf( szTemp,sizeof(szTemp), "%s", ( char * )pcmd );
		}
		p = szTemp;
	}

	CBasePlayer *pPlayer = NULL;
	if ( pEdict )
	{
		pPlayer = ((CBasePlayer *)CBaseEntity::Instance( pEdict ));
		Assert( pPlayer );

		// make sure the text has valid content
		p = CheckChatText( pPlayer, p );
	}

	if ( !p )
		return;

	if ( pEdict )
	{
		if ( !pPlayer->CanSpeak(messageMode) )
			return;

		// See if the player wants to modify of check the text
		pPlayer->CheckChatText( p, 127 );	// though the buffer szTemp that p points to is 256, 
											// chat text is capped to 127 in CheckChatText above

		Assert( strlen( pPlayer->GetPlayerName() ) > 0 );

		bSenderDead = ( pPlayer->m_lifeState != LIFE_ALIVE );
	}
	else
	{
		bSenderDead = false;
	}

	const char *pszFormat = NULL;
	const char *pszPrefix = NULL;
	char pszLocation[8];

	if ( g_pGameRules )
	{
		pszFormat = g_pGameRules->GetChatFormat( messageMode, pPlayer );
		pszPrefix = g_pGameRules->GetChatPrefix( messageMode, pPlayer );	

		if (pPlayer && pPlayer->GetTeam() && pPlayer->GetTeam()->GetCaptain() == pPlayer)
			Q_snprintf(pszLocation, sizeof(pszLocation), "(%s)", g_pGameRules->GetChatLocation( messageMode, pPlayer ));
		else
			Q_snprintf(pszLocation, sizeof(pszLocation), "%s", g_pGameRules->GetChatLocation( messageMode, pPlayer ));
	}

	const char *pszPlayerName = pPlayer ? pPlayer->GetPlayerName() : "Stadium Announcer";
 
	// loop through all players
	// Start with the first player.
	// This may return the world in single player if the client types something between levels or during spawn
	// so check it, or it will infinite loop

	client = NULL;
	for ( int i = 1; i <= gpGlobals->maxClients; i++ )
	{
		client = ToBaseMultiplayerPlayer( UTIL_PlayerByIndex( i ) );
		if ( !client || !client->edict() )
			continue;
		
		if ( client->edict() == pEdict )
			continue;

		if ( !(client->IsNetClient()) )	// Not a client ? (should never be true)
			continue;

		if ( messageMode != MM_SAY && !g_pGameRules->PlayerCanHearChat( client, pPlayer, messageMode ) )
			continue;

		if ( pPlayer && !client->CanHearAndReadChatFrom( pPlayer ) )
			continue;

		if ( pPlayer && GetVoiceGameMgr() && GetVoiceGameMgr()->IsPlayerIgnoringPlayer( pPlayer->entindex(), i ) )
			continue;

		CSingleUserRecipientFilter user( client );
		user.MakeReliable();

		UTIL_SayText2Filter( user, pPlayer, true, pszFormat, pszPlayerName, p, pszLocation, pszPrefix );
	}

	if ( pPlayer )
	{
		// print to the sending client
		CSingleUserRecipientFilter user( pPlayer );
		user.MakeReliable();

		UTIL_SayText2Filter( user, pPlayer, true, pszFormat, pszPlayerName, p, pszLocation, pszPrefix );
	}

	// echo to server console
	// Adrian: Only do this if we're running a dedicated server since we already print to console on the client.
	if ( engine->IsDedicatedServer() )
	{
		Q_snprintf( text, sizeof(text), "%s: ", pszPlayerName );

		j = sizeof(text) - 2 - strlen(text);  // -2 for /n and null terminator
		if ( (int)strlen(p) > j )
			p[j] = 0;

		Q_strncat( text, p, sizeof( text ), COPY_ALL_CHARACTERS );
		Q_strncat( text, "\n", sizeof( text ), COPY_ALL_CHARACTERS );

		Msg( "%s", text );
	}

	Assert( p );

	int userid = 0;
	const char *networkID = "Console";
	const char *playerName = "Console";
	const char *playerTeam = "Console";
	if ( pPlayer )
	{
		userid = pPlayer->GetUserID();
		networkID = pPlayer->GetNetworkIDString();
		playerName = pPlayer->GetPlayerName();
		CTeam *team = pPlayer->GetTeam();
		if ( team )
		{
			playerTeam = team->GetKitName();
		}
	}
		
	if ( messageMode == MM_SAY_TEAM )
		UTIL_LogPrintf( "\"%s<%i><%s><%s>\" say_team \"%s\"\n", playerName, userid, networkID, playerTeam, p );
	else if ( messageMode == MM_SAY_SPEC )
		UTIL_LogPrintf( "\"%s<%i><%s><%s>\" say_spec \"%s\"\n", playerName, userid, networkID, playerTeam, p );
	else
		UTIL_LogPrintf( "\"%s<%i><%s><%s>\" say \"%s\"\n", playerName, userid, networkID, playerTeam, p );

	IGameEvent * event = gameeventmanager->CreateEvent( "player_say" );

	if ( event )	// will be null if there are no listeners!
	{
		event->SetInt("userid", userid );
		event->SetString("text", p );
		event->SetInt("priority", 1 );	// HLTV event priority, not transmitted
		gameeventmanager->FireEvent( event );
	}
}