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;
}
}