View Single Post
Old 09-20-2006, 04:12 PM   #137
ensiform
The Stig
 
ensiform's Avatar
 
Join Date: Nov 2004
Location: Sawtooth Cauldron
Posts: 1,241
Current Game: Borderlands 2
Replacement for DeathmatchScoreboardMessage that comes from Enemy Territory with some enhancements and such so that it will not go over 1022 limit.

Note: if you use unlagged change the ping part to use pers.realPing instead of ps.ping.

Code:
// G_SendScore_Add
// 
// Add score with clientNum at index i of level.sortedClients[]
// to the string buf.
// 
// returns qtrue if the score was appended to buf, qfalse otherwise.
qboolean G_SendScore_Add(gentity_t *ent, int i, char *buf, int bufsize) 
{
	gclient_t *cl;
	int ping, scoreFlags=0, accuracy, perfect;
	char entry[256];

	entry[0] = '\0';

	cl = &level.clients[level.sortedClients[i]];

	if ( cl->pers.connected == CON_CONNECTING ) {
		ping = -1;
	} else {
		ping = cl->ps.ping < 999 ? cl->ps.ping : 999;
	}

	if( cl->accuracy_shots ) {
		accuracy = cl->accuracy_hits * 100 / cl->accuracy_shots;
	} else {
		accuracy = 0;
	}
	perfect = ( cl->ps.persistant[PERS_RANK] == 0 && cl->ps.persistant[PERS_KILLED] == 0 ) ? 1 : 0;

	Com_sprintf (entry, sizeof(entry),
		" %i %i %i %i %i %i %i %i %i %i %i %i %i %i ", 
		level.sortedClients[i],
		cl->ps.persistant[PERS_SCORE], 
		ping, 
		(level.time - cl->pers.enterTime)/60000,
		scoreFlags,
		g_entities[level.sortedClients[i]].s.powerups, 
		accuracy, 
		cl->ps.persistant[PERS_IMPRESSIVE_COUNT],
		cl->ps.persistant[PERS_EXCELLENT_COUNT],
		cl->ps.persistant[PERS_GAUNTLET_FRAG_COUNT], 
		cl->ps.persistant[PERS_DEFEND_COUNT], 
		cl->ps.persistant[PERS_ASSIST_COUNT], 
		perfect,
		cl->ps.persistant[PERS_CAPTURES]);

	if((strlen(buf) + strlen(entry) + 1) > bufsize) {
		return qfalse;
	}
	Q_strcat(buf, bufsize, entry);
	return qtrue;
}

/*
==================
G_SendScore

==================
*/
void G_SendScore( gentity_t *ent ) {
	int i;
	int numSorted;
	int count;
	// tjw: commands over 1022 will crash the client so they're
	//      pruned in trap_SendServerCommand()
	//      1022 -32 for the startbuffer
	char		buffer[990];
	char		startbuffer[32];

	numSorted = level.numConnectedClients;
	
	if (numSorted > MAX_CLIENTS)
	{
		numSorted = MAX_CLIENTS;
	}

	count = 0;
	*buffer = '\0';
	*startbuffer = '\0';

	Q_strncpyz(startbuffer, va(
		"scores %i %i %i",
		level.numConnectedClients,
		level.teamScores[TEAM_RED],
		level.teamScores[TEAM_BLUE]),
		sizeof(startbuffer));

	// tjw: keep adding scores to the scores command until we fill 
	//      up the buffer.  
	for(i=0 ; i < numSorted ; i++) {
		// tjw: the old version of SendScore() did this.  I removed it
		//      originally because it seemed like an unneccessary hack.
		//      perhaps it is necessary for compat with CG_Argv()?
		if(!G_SendScore_Add(ent, i, buffer, sizeof(buffer))) {
			break;
		}
		count++;
	}
	if(!count) {
		return;
	}
	trap_SendServerCommand(ent-g_entities, va(
		"%s%s", startbuffer, buffer));
}
Now just replace all instances of DeathmatchScoreboardMessage with G_SendScore.

Client-Side fix to allow actually up to MAX_CLIENTS instead of only 20 clients to draw on scoreboard:

cg_servercmds.c:

Code:
/*
=================
CG_ParseScores

=================
*/
static void CG_ParseScores( void ) {
	int		i, powerups;

	cg.numScores = atoi( CG_Argv( 1 ) );
	if ( cg.numScores > MAX_CLIENTS ) {
		cg.numScores = MAX_CLIENTS;
	}

	cg.teamScores[0] = atoi( CG_Argv( 2 ) );
	cg.teamScores[1] = atoi( CG_Argv( 3 ) );

	memset( cg.scores, 0, sizeof( cg.scores ) );
	for ( i = 0 ; i < cg.numScores ; i++ ) {
		//
		cg.scores[i].client = atoi( CG_Argv( i * 14 + 4 ) );
		cg.scores[i].score = atoi( CG_Argv( i * 14 + 5 ) );
		cg.scores[i].ping = atoi( CG_Argv( i * 14 + 6 ) );
		cg.scores[i].time = atoi( CG_Argv( i * 14 + 7 ) );
		cg.scores[i].scoreFlags = atoi( CG_Argv( i * 14 + 8 ) );
		powerups = atoi( CG_Argv( i * 14 + 9 ) );
		cg.scores[i].accuracy = atoi(CG_Argv(i * 14 + 10));
		cg.scores[i].impressiveCount = atoi(CG_Argv(i * 14 + 11));
		cg.scores[i].excellentCount = atoi(CG_Argv(i * 14 + 12));
		cg.scores[i].guantletCount = atoi(CG_Argv(i * 14 + 13));
		cg.scores[i].defendCount = atoi(CG_Argv(i * 14 + 14));
		cg.scores[i].assistCount = atoi(CG_Argv(i * 14 + 15));
		cg.scores[i].perfect = atoi(CG_Argv(i * 14 + 16));
		cg.scores[i].captures = atoi(CG_Argv(i * 14 + 17));

		if ( cg.scores[i].client < 0 || cg.scores[i].client >= MAX_CLIENTS ) {
			cg.scores[i].client = 0;
		}
		cgs.clientinfo[ cg.scores[i].client ].score = cg.scores[i].score;
		cgs.clientinfo[ cg.scores[i].client ].powerups = powerups;

		cg.scores[i].team = cgs.clientinfo[cg.scores[i].client].team;
	}
}


iojamp project lead / coder

Last edited by ensiform; 09-20-2006 at 04:40 PM.
ensiform is offline   you may: quote & reply,