Esempio n. 1
0
void G_PlayerAward( edict_t *ent, const char *awardMsg )
{
	edict_t *other;
	char cmd[MAX_STRING_CHARS];
	gameaward_t *ga;
	int i, size;
	score_stats_t *stats;

	if( !awardMsg || !awardMsg[0] || !ent->r.client )
		return;

	Q_snprintfz( cmd, sizeof( cmd ), "aw \"%s\"", awardMsg );
	trap_GameCmd( ent, cmd );

	if( dedicated->integer )
		G_Printf( "%s", COM_RemoveColorTokens( va( "%s receives a '%s' award.\n", ent->r.client->netname, awardMsg ) ) );

	ent->r.client->level.stats.awards++;
	teamlist[ent->s.team].stats.awards++;
	G_Gametype_ScoreEvent( ent->r.client, "award", awardMsg );

	stats = &ent->r.client->level.stats;
	if( !stats->awardAllocator )
		stats->awardAllocator = LinearAllocator( sizeof( gameaward_t ), 0, _G_LevelMalloc, _G_LevelFree );

	// ch : this doesnt work for race right?
	if( GS_MatchState() == MATCH_STATE_PLAYTIME || GS_MatchState() == MATCH_STATE_POSTMATCH )
	{
		// ch : we store this locally to send to MM
		// first check if we already have this one on the clients list
		size = LA_Size( stats->awardAllocator );
		ga = NULL;
		for( i = 0; i < size; i++ )
		{
			ga = ( gameaward_t * )LA_Pointer( stats->awardAllocator, i );
			if( !strncmp( ga->name, awardMsg, sizeof(ga->name)-1 ) )
				break;
		}

		if( i >= size )
		{
			ga = ( gameaward_t * )LA_Alloc( stats->awardAllocator );
			memset( ga, 0, sizeof(*ga) );
			ga->name = G_RegisterLevelString( awardMsg );
		}

		if( ga )
			ga->count++;
	}

	// add it to every player who's chasing this player
	for( other = game.edicts + 1; PLAYERNUM( other ) < gs.maxclients; other++ )
	{
		if( !other->r.client || !other->r.inuse || !other->r.client->resp.chase.active )
			continue;

		if( other->r.client->resp.chase.target == ENTNUM( ent ) )
			trap_GameCmd( other, cmd );
	}
}
Esempio n. 2
0
/*
* Cmd_ShowStats_f
*/
static void Cmd_ShowStats_f( edict_t *ent )
{
	edict_t *target;

	if( trap_Cmd_Argc() > 2 )
	{
		G_PrintMsg( ent, "Usage: stats [player]\n" );
		return;
	}

	if( trap_Cmd_Argc() == 2 )
	{
		target = G_PlayerForText( trap_Cmd_Argv( 1 ) );
		if( target == NULL )
		{
			G_PrintMsg( ent, "No such player\n" );
			return;
		}
	}
	else
	{
		if( ent->r.client->resp.chase.active && game.edicts[ent->r.client->resp.chase.target].r.client )
			target = &game.edicts[ent->r.client->resp.chase.target];
		else
			target = ent;
	}

	if( target->s.team == TEAM_SPECTATOR )
	{
		G_PrintMsg( ent, "No stats for spectators\n" );
		return;
	}

	trap_GameCmd( ent, va( "plstats 1 \"%s\"", G_StatsMessage( target ) ) );
}
Esempio n. 3
0
/*
* G_Match_Autorecord_Stats
*/
void G_Match_Autorecord_Stats( void )
{
	edict_t *ent;

	for( ent = game.edicts + 1; PLAYERNUM( ent ) < gs.maxclients; ent++ )
	{
		if( !ent->r.inuse || ent->s.team == TEAM_SPECTATOR || ( ent->r.svflags & SVF_FAKECLIENT ) )
			continue;
		trap_GameCmd( ent, va( "plstats 2 \"%s\"", G_StatsMessage( ent ) ) );
	}
}
Esempio n. 4
0
void G_PlayerAward( edict_t *ent, const char *awardMsg )
{
	edict_t *other, *third;

	if( !awardMsg || !awardMsg[0] || !ent->r.client )
		return;

	trap_GameCmd( ent, va( "aw \"%s\"", awardMsg ) );

	if( dedicated->integer )
		G_Printf( "%s", COM_RemoveColorTokens( va( "%s receives a '%s' award.\n", ent->r.client->netname, awardMsg ) ) );

	ent->r.client->level.stats.awards++;
	teamlist[ent->s.team].stats.awards++;
	G_Gametype_ScoreEvent( ent->r.client, "award", awardMsg );

	// add it to every player who's chasing this player
	for( other = game.edicts + 1; PLAYERNUM( other ) < gs.maxclients; other++ )
	{
		if( !other->r.client || !other->r.inuse || !other->r.client->resp.chase.active )
			continue;

		if( other->r.client->resp.chase.target == ent->s.number )
		{
			trap_GameCmd( other, va( "aw \"%s\"", awardMsg ) );
			
			// someone could also be chase-caming the guy in the chasecam
			for( third = game.edicts + 1; PLAYERNUM( third ) < gs.maxclients; third++ )
			{
				if( !third->r.client || !third->r.inuse || !third->r.client->resp.chase.active )
					continue;

				if( third->r.client->resp.chase.target == other->s.number )
					trap_GameCmd( third, va( "aw \"%s\"", awardMsg ) );
			}
		}
	}
}
Esempio n. 5
0
/*
* G_Teams_TDM_UpdateTeamInfoMessages
*/
void G_Teams_UpdateTeamInfoMessages( void )
{
	static int nexttime = 0;
	static char teammessage[MAX_STRING_CHARS];
	edict_t	*ent, *e;
	size_t len;
	int i, j, team;
	char entry[MAX_TOKEN_CHARS];
	int locationTag;

	nexttime -= game.snapFrameTime;
	if( nexttime > 0 )
		return;

	while( nexttime <= 0 )
		nexttime += 2000;

	// time for a new update

	for( team = TEAM_ALPHA; team < GS_MAX_TEAMS; team++ )
	{
		*teammessage = 0;
		Q_snprintfz( teammessage, sizeof( teammessage ), "ti \"" );
		len = strlen( teammessage );

		// add our team info to the string
		for( i = 0; i < teamlist[team].numplayers; i++ )
		{
			ent = game.edicts + teamlist[team].playerIndices[i];

			if( G_IsDead( ent ) )  // don't show dead players
				continue;

			if( ent->r.client->teamstate.is_coach )  // don't show coachs
				continue;

			// get location name
			locationTag = G_MapLocationTAGForOrigin( ent->s.origin );
			if( locationTag == -1 )
				continue;

			*entry = 0;

			Q_snprintfz( entry, sizeof( entry ), "%i %i %i %i ", PLAYERNUM( ent ), locationTag, HEALTH_TO_INT( ent->health ), ARMOR_TO_INT( ent->r.client->resp.armor ) );

			if( MAX_STRING_CHARS - len > strlen( entry ) )
			{
				Q_strncatz( teammessage, entry, sizeof( teammessage ) );
				len = strlen( teammessage );
			}
		}

		// add closing quote
		*entry = 0;
		Q_snprintfz( entry, sizeof( entry ), "\"" );
		if( MAX_STRING_CHARS - len > strlen( entry ) )
		{
			Q_strncatz( teammessage, entry, sizeof( teammessage ) );
			len = strlen( teammessage );
		}

		for( i = 0; i < teamlist[team].numplayers; i++ )
		{
			ent = game.edicts + teamlist[team].playerIndices[i];

			if( !ent->r.inuse || !ent->r.client )
				continue;

			trap_GameCmd( ent, teammessage );

			// see if there are spectators chasing this player and send them the layout too
			for( j = 0; j < teamlist[TEAM_SPECTATOR].numplayers; j++ )
			{
				e = game.edicts + teamlist[TEAM_SPECTATOR].playerIndices[j];

				if( !e->r.inuse || !e->r.client )
					continue;

				if( e->r.client->resp.chase.active && e->r.client->resp.chase.target == ENTNUM( ent ) )
					trap_GameCmd( e, teammessage );
			}
		}
	}
}
Esempio n. 6
0
/*
* G_MoveClientToTV
*
* Sends cmd to connect to a non-full TV server with round robin balancing
*/
void G_MoveClientToTV( edict_t *ent )
{
	int i;
	gclient_t *client, *best;
	static int last_tv = 0;
	bool isIPv6;
	char ip[MAX_INFO_VALUE];
	int port;
	const char *p;

	if( !ent->r.client ) {
		return;
	}
	if( ent->r.svflags & SVF_FAKECLIENT ) {
		return;
	}
	if( ent->r.client->isTV ) {
		return;
	}

	best = NULL;
	for( i = 0; i < gs.maxclients; i++ ) {
		client = &game.clients[(last_tv + 1 + i) % gs.maxclients];
		if( !client->isTV || client->connecting ) {
			// not a TV or not ready yet
			continue;
		}
		if( client->tv.numclients == client->tv.maxclients ) {
			// full
			continue;
		}
		if( !client->tv.channel ) {
			// invalid userinfo/channel number
			continue;
		}
		best = client;
		break;
	}

	if( !best ) {
		G_PrintMsg( ent, "Could not find a free TV server\n" );
		return;
	}

	Q_strncpyz( ip, best->ip, sizeof( ip ) );

	// check IP type
	p = strstr( ip, "::" );
	isIPv6 = p != NULL;

	// strip port number from address string
	p = strrchr( ip, ':' );
	if( p != NULL ) {
		ip[p - ip] = '\0';
	}

	port = isIPv6 ? best->tv.port6 : best->tv.port;

	last_tv = best - game.clients;
	trap_GameCmd( ent, va( "memo tv_moveto \"%s\" %s:%hu#%i", COM_RemoveColorTokens( best->netname ), ip, port, best->tv.channel ) );
}
Esempio n. 7
0
/*
* Cmd_Upstate_f
*
* Update client on the state of things
*/
static void Cmd_Upstate_f( edict_t *ent )
{
	G_UpdatePlayerMatchMsg( ent, true );
	G_SetPlayerHelpMessage( ent, ent->r.client->level.helpmessage, true );
	trap_GameCmd( ent, va( "qm %s", ent->r.client->level.quickMenuItems ) );
}
Esempio n. 8
0
/*
* G_ClientUpdateScoreBoardMessage
* 
* Show the scoreboard messages if the scoreboards are active
*/
void G_UpdateScoreBoardMessages( void )
{
	static int nexttime = 0;
	int i;
	edict_t	*ent;
	gclient_t *client;
	bool forcedUpdate = false;
	char command[MAX_STRING_CHARS];
	size_t maxlen, staticlen;

	// fixme : mess of copying
	maxlen = MAX_STRING_CHARS - ( strlen( "scb \"\"" + 4 ) );

	if( game.asEngine != NULL )
		GT_asCallScoreboardMessage( maxlen );
	else
		G_Gametype_GENERIC_ScoreboardMessage();

	G_ScoreboardMessage_AddSpectators();

	staticlen = strlen( scoreboardString );

update:
	// send to players who have scoreboard visible
	for( i = 0; i < gs.maxclients; i++ )
	{
		ent = game.edicts + 1 + i;
		if( !ent->r.inuse || !ent->r.client )
			continue;

		client = ent->r.client;

		if( game.realtime <= client->level.scoreboard_time + scoreboardInterval )
			continue;

		if( forcedUpdate || ( client->ps.stats[STAT_LAYOUTS] & STAT_LAYOUT_SCOREBOARD ) )
		{
			scoreboardString[staticlen] = '\0';
			if( client->resp.chase.active )
				G_ScoreboardMessage_AddChasers( client->resp.chase.target, ENTNUM( ent ) );
			else
				G_ScoreboardMessage_AddChasers( ENTNUM( ent ), ENTNUM( ent ) );
			Q_snprintfz( command, sizeof( command ), "scb \"%s\"", scoreboardString );

			client->level.scoreboard_time = game.realtime + scoreboardInterval - ( game.realtime%scoreboardInterval );
			trap_GameCmd( ent, command );
			trap_GameCmd( ent, G_PlayerStatsMessage( ent ) );
		}
	}

	if( !forcedUpdate )
	{
		// every 10 seconds, send everyone the scoreboard
		nexttime -= game.snapFrameTime;
		if( nexttime > 0 )
			return;

		do
		{
			nexttime += 10000;
		}
		while( nexttime <= 0 );

		forcedUpdate = true;
		goto update;
	}
}
Esempio n. 9
0
/*
* G_ClientUpdateScoreBoardMessage
* 
* Show the scoreboard messages if the scoreboards are active
*/
void G_UpdateScoreBoardMessages( void )
{
	static int nexttime = 0;
	int i;
	edict_t	*ent;
	gclient_t *client;
	char *scoreBoardMessage = "";
	qboolean forcedUpdate = qfalse;
	char string[MAX_STRING_CHARS];
	size_t maxlen;

	// fixme : mess of copying
	maxlen = MAX_STRING_CHARS - ( strlen( "scb \"\"" + 4 ) );

	if( level.gametype.asEngineHandle >= 0 )
		scoreBoardMessage = G_asCallScoreboardMessage( maxlen );
	else
		scoreBoardMessage = G_Gametype_GENERIC_ScoreboardMessage();

	G_ScoreboardMessage_AddSpectators();

	Q_strncpyz( string, scoreBoardMessage ? scoreBoardMessage : "", maxlen );
	Q_snprintfz( scoreboardString, sizeof( scoreboardString ), "scb \"%s\"", string );
	scoreBoardMessage = scoreboardString;

update:
	// send to players who have scoreboard visible
	for( i = 0; i < gs.maxclients; i++ )
	{
		ent = game.edicts + 1 + i;
		if( !ent->r.inuse || !ent->r.client )
			continue;

		client = ent->r.client;

		if( game.realtime <= client->level.scoreboard_time + scoreboardInterval )
			continue;

		if( forcedUpdate || ( client->ps.stats[STAT_LAYOUTS] & STAT_LAYOUT_SCOREBOARD ) )
		{
			client->level.scoreboard_time = game.realtime + scoreboardInterval - ( game.realtime%scoreboardInterval );
			trap_GameCmd( ent, scoreBoardMessage );
			trap_GameCmd( ent, G_PlayerStatsMessage( ent ) );
		}
	}

	if( !forcedUpdate )
	{
		// every 10 seconds, send everyone the scoreboard
		nexttime -= game.snapFrameTime;
		if( nexttime > 0 )
			return;

		do
		{
			nexttime += 10000;
		}
		while( nexttime <= 0 );

		forcedUpdate = qtrue;
		goto update;
	}
}