00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "cg_local.h"
00025
00026
00027 #define SCOREBOARD_X (0)
00028
00029 #define SB_HEADER 86
00030 #define SB_TOP (SB_HEADER+32)
00031
00032
00033 #define SB_STATUSBAR 420
00034
00035 #define SB_NORMAL_HEIGHT 40
00036 #define SB_INTER_HEIGHT 16 // interleaved height
00037
00038 #define SB_MAXCLIENTS_NORMAL ((SB_STATUSBAR - SB_TOP) / SB_NORMAL_HEIGHT)
00039 #define SB_MAXCLIENTS_INTER ((SB_STATUSBAR - SB_TOP) / SB_INTER_HEIGHT - 1)
00040
00041
00042
00043
00044
00045 #define SB_LEFT_BOTICON_X (SCOREBOARD_X+0)
00046 #define SB_LEFT_HEAD_X (SCOREBOARD_X+32)
00047 #define SB_RIGHT_BOTICON_X (SCOREBOARD_X+64)
00048 #define SB_RIGHT_HEAD_X (SCOREBOARD_X+96)
00049
00050 #define SB_BOTICON_X (SCOREBOARD_X+32)
00051 #define SB_HEAD_X (SCOREBOARD_X+64)
00052
00053 #define SB_SCORELINE_X 112
00054
00055 #define SB_RATING_WIDTH (6 * BIGCHAR_WIDTH) // width 6
00056 #define SB_SCORE_X (SB_SCORELINE_X + BIGCHAR_WIDTH) // width 6
00057 #define SB_RATING_X (SB_SCORELINE_X + 6 * BIGCHAR_WIDTH) // width 6
00058 #define SB_PING_X (SB_SCORELINE_X + 12 * BIGCHAR_WIDTH + 8) // width 5
00059 #define SB_TIME_X (SB_SCORELINE_X + 17 * BIGCHAR_WIDTH + 8) // width 5
00060 #define SB_NAME_X (SB_SCORELINE_X + 22 * BIGCHAR_WIDTH) // width 15
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 static qboolean localClient;
00074
00075
00076
00077
00078
00079
00080
00081 static void CG_DrawClientScore( int y, score_t *score, float *color, float fade, qboolean largeFormat ) {
00082 char string[1024];
00083 vec3_t headAngles;
00084 clientInfo_t *ci;
00085 int iconx, headx;
00086
00087 if ( score->client < 0 || score->client >= cgs.maxclients ) {
00088 Com_Printf( "Bad score->client: %i\n", score->client );
00089 return;
00090 }
00091
00092 ci = &cgs.clientinfo[score->client];
00093
00094 iconx = SB_BOTICON_X + (SB_RATING_WIDTH / 2);
00095 headx = SB_HEAD_X + (SB_RATING_WIDTH / 2);
00096
00097
00098 if ( ci->powerups & ( 1 << PW_NEUTRALFLAG ) ) {
00099 if( largeFormat ) {
00100 CG_DrawFlagModel( iconx, y - ( 32 - BIGCHAR_HEIGHT ) / 2, 32, 32, TEAM_FREE, qfalse );
00101 }
00102 else {
00103 CG_DrawFlagModel( iconx, y, 16, 16, TEAM_FREE, qfalse );
00104 }
00105 } else if ( ci->powerups & ( 1 << PW_REDFLAG ) ) {
00106 if( largeFormat ) {
00107 CG_DrawFlagModel( iconx, y - ( 32 - BIGCHAR_HEIGHT ) / 2, 32, 32, TEAM_RED, qfalse );
00108 }
00109 else {
00110 CG_DrawFlagModel( iconx, y, 16, 16, TEAM_RED, qfalse );
00111 }
00112 } else if ( ci->powerups & ( 1 << PW_BLUEFLAG ) ) {
00113 if( largeFormat ) {
00114 CG_DrawFlagModel( iconx, y - ( 32 - BIGCHAR_HEIGHT ) / 2, 32, 32, TEAM_BLUE, qfalse );
00115 }
00116 else {
00117 CG_DrawFlagModel( iconx, y, 16, 16, TEAM_BLUE, qfalse );
00118 }
00119 } else {
00120 if ( ci->botSkill > 0 && ci->botSkill <= 5 ) {
00121 if ( cg_drawIcons.integer ) {
00122 if( largeFormat ) {
00123 CG_DrawPic( iconx, y - ( 32 - BIGCHAR_HEIGHT ) / 2, 32, 32, cgs.media.botSkillShaders[ ci->botSkill - 1 ] );
00124 }
00125 else {
00126 CG_DrawPic( iconx, y, 16, 16, cgs.media.botSkillShaders[ ci->botSkill - 1 ] );
00127 }
00128 }
00129 } else if ( ci->handicap < 100 ) {
00130 Com_sprintf( string, sizeof( string ), "%i", ci->handicap );
00131 if ( cgs.gametype == GT_TOURNAMENT )
00132 CG_DrawSmallStringColor( iconx, y - SMALLCHAR_HEIGHT/2, string, color );
00133 else
00134 CG_DrawSmallStringColor( iconx, y, string, color );
00135 }
00136
00137
00138 if ( cgs.gametype == GT_TOURNAMENT ) {
00139 Com_sprintf( string, sizeof( string ), "%i/%i", ci->wins, ci->losses );
00140 if( ci->handicap < 100 && !ci->botSkill ) {
00141 CG_DrawSmallStringColor( iconx, y + SMALLCHAR_HEIGHT/2, string, color );
00142 }
00143 else {
00144 CG_DrawSmallStringColor( iconx, y, string, color );
00145 }
00146 }
00147 }
00148
00149
00150 VectorClear( headAngles );
00151 headAngles[YAW] = 180;
00152 if( largeFormat ) {
00153 CG_DrawHead( headx, y - ( ICON_SIZE - BIGCHAR_HEIGHT ) / 2, ICON_SIZE, ICON_SIZE,
00154 score->client, headAngles );
00155 }
00156 else {
00157 CG_DrawHead( headx, y, 16, 16, score->client, headAngles );
00158 }
00159
00160 #ifdef MISSIONPACK
00161
00162 if ( ci->teamTask != TEAMTASK_NONE ) {
00163 if ( ci->teamTask == TEAMTASK_OFFENSE ) {
00164 CG_DrawPic( headx + 48, y, 16, 16, cgs.media.assaultShader );
00165 }
00166 else if ( ci->teamTask == TEAMTASK_DEFENSE ) {
00167 CG_DrawPic( headx + 48, y, 16, 16, cgs.media.defendShader );
00168 }
00169 }
00170 #endif
00171
00172 if ( score->ping == -1 ) {
00173 Com_sprintf(string, sizeof(string),
00174 " connecting %s", ci->name);
00175 } else if ( ci->team == TEAM_SPECTATOR ) {
00176 Com_sprintf(string, sizeof(string),
00177 " SPECT %3i %4i %s", score->ping, score->time, ci->name);
00178 } else {
00179 Com_sprintf(string, sizeof(string),
00180 "%5i %4i %4i %s", score->score, score->ping, score->time, ci->name);
00181 }
00182
00183
00184 if ( score->client == cg.snap->ps.clientNum ) {
00185 float hcolor[4];
00186 int rank;
00187
00188 localClient = qtrue;
00189
00190 if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR
00191 || cgs.gametype >= GT_TEAM ) {
00192 rank = -1;
00193 } else {
00194 rank = cg.snap->ps.persistant[PERS_RANK] & ~RANK_TIED_FLAG;
00195 }
00196 if ( rank == 0 ) {
00197 hcolor[0] = 0;
00198 hcolor[1] = 0;
00199 hcolor[2] = 0.7f;
00200 } else if ( rank == 1 ) {
00201 hcolor[0] = 0.7f;
00202 hcolor[1] = 0;
00203 hcolor[2] = 0;
00204 } else if ( rank == 2 ) {
00205 hcolor[0] = 0.7f;
00206 hcolor[1] = 0.7f;
00207 hcolor[2] = 0;
00208 } else {
00209 hcolor[0] = 0.7f;
00210 hcolor[1] = 0.7f;
00211 hcolor[2] = 0.7f;
00212 }
00213
00214 hcolor[3] = fade * 0.7;
00215 CG_FillRect( SB_SCORELINE_X + BIGCHAR_WIDTH + (SB_RATING_WIDTH / 2), y,
00216 640 - SB_SCORELINE_X - BIGCHAR_WIDTH, BIGCHAR_HEIGHT+1, hcolor );
00217 }
00218
00219 CG_DrawBigString( SB_SCORELINE_X + (SB_RATING_WIDTH / 2), y, string, fade );
00220
00221
00222 if ( cg.snap->ps.stats[ STAT_CLIENTS_READY ] & ( 1 << score->client ) ) {
00223 CG_DrawBigStringColor( iconx, y, "READY", color );
00224 }
00225 }
00226
00227
00228
00229
00230
00231
00232 static int CG_TeamScoreboard( int y, team_t team, float fade, int maxClients, int lineHeight ) {
00233 int i;
00234 score_t *score;
00235 float color[4];
00236 int count;
00237 clientInfo_t *ci;
00238
00239 color[0] = color[1] = color[2] = 1.0;
00240 color[3] = fade;
00241
00242 count = 0;
00243 for ( i = 0 ; i < cg.numScores && count < maxClients ; i++ ) {
00244 score = &cg.scores[i];
00245 ci = &cgs.clientinfo[ score->client ];
00246
00247 if ( team != ci->team ) {
00248 continue;
00249 }
00250
00251 CG_DrawClientScore( y + lineHeight * count, score, color, fade, lineHeight == SB_NORMAL_HEIGHT );
00252
00253 count++;
00254 }
00255
00256 return count;
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266 qboolean CG_DrawOldScoreboard( void ) {
00267 int x, y, w, i, n1, n2;
00268 float fade;
00269 float *fadeColor;
00270 char *s;
00271 int maxClients;
00272 int lineHeight;
00273 int topBorderSize, bottomBorderSize;
00274
00275
00276 if ( cg_paused.integer ) {
00277 cg.deferredPlayerLoading = 0;
00278 return qfalse;
00279 }
00280
00281 if ( cgs.gametype == GT_SINGLE_PLAYER && cg.predictedPlayerState.pm_type == PM_INTERMISSION ) {
00282 cg.deferredPlayerLoading = 0;
00283 return qfalse;
00284 }
00285
00286
00287 if ( cg.warmup && !cg.showScores ) {
00288 return qfalse;
00289 }
00290
00291 if ( cg.showScores || cg.predictedPlayerState.pm_type == PM_DEAD ||
00292 cg.predictedPlayerState.pm_type == PM_INTERMISSION ) {
00293 fade = 1.0;
00294 fadeColor = colorWhite;
00295 } else {
00296 fadeColor = CG_FadeColor( cg.scoreFadeTime, FADE_TIME );
00297
00298 if ( !fadeColor ) {
00299
00300 cg.deferredPlayerLoading = 0;
00301 cg.killerName[0] = 0;
00302 return qfalse;
00303 }
00304 fade = *fadeColor;
00305 }
00306
00307
00308
00309 if ( cg.killerName[0] ) {
00310 s = va("Fragged by %s", cg.killerName );
00311 w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
00312 x = ( SCREEN_WIDTH - w ) / 2;
00313 y = 40;
00314 CG_DrawBigString( x, y, s, fade );
00315 }
00316
00317
00318 if ( cgs.gametype < GT_TEAM) {
00319 if (cg.snap->ps.persistant[PERS_TEAM] != TEAM_SPECTATOR ) {
00320 s = va("%s place with %i",
00321 CG_PlaceString( cg.snap->ps.persistant[PERS_RANK] + 1 ),
00322 cg.snap->ps.persistant[PERS_SCORE] );
00323 w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
00324 x = ( SCREEN_WIDTH - w ) / 2;
00325 y = 60;
00326 CG_DrawBigString( x, y, s, fade );
00327 }
00328 } else {
00329 if ( cg.teamScores[0] == cg.teamScores[1] ) {
00330 s = va("Teams are tied at %i", cg.teamScores[0] );
00331 } else if ( cg.teamScores[0] >= cg.teamScores[1] ) {
00332 s = va("Red leads %i to %i",cg.teamScores[0], cg.teamScores[1] );
00333 } else {
00334 s = va("Blue leads %i to %i",cg.teamScores[1], cg.teamScores[0] );
00335 }
00336
00337 w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
00338 x = ( SCREEN_WIDTH - w ) / 2;
00339 y = 60;
00340 CG_DrawBigString( x, y, s, fade );
00341 }
00342
00343
00344 y = SB_HEADER;
00345
00346 CG_DrawPic( SB_SCORE_X + (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardScore );
00347 CG_DrawPic( SB_PING_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardPing );
00348 CG_DrawPic( SB_TIME_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardTime );
00349 CG_DrawPic( SB_NAME_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardName );
00350
00351 y = SB_TOP;
00352
00353
00354 if ( cg.numScores > SB_MAXCLIENTS_NORMAL ) {
00355 maxClients = SB_MAXCLIENTS_INTER;
00356 lineHeight = SB_INTER_HEIGHT;
00357 topBorderSize = 8;
00358 bottomBorderSize = 16;
00359 } else {
00360 maxClients = SB_MAXCLIENTS_NORMAL;
00361 lineHeight = SB_NORMAL_HEIGHT;
00362 topBorderSize = 16;
00363 bottomBorderSize = 16;
00364 }
00365
00366 localClient = qfalse;
00367
00368 if ( cgs.gametype >= GT_TEAM ) {
00369
00370
00371
00372 y += lineHeight/2;
00373
00374 if ( cg.teamScores[0] >= cg.teamScores[1] ) {
00375 n1 = CG_TeamScoreboard( y, TEAM_RED, fade, maxClients, lineHeight );
00376 CG_DrawTeamBackground( 0, y - topBorderSize, 640, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED );
00377 y += (n1 * lineHeight) + BIGCHAR_HEIGHT;
00378 maxClients -= n1;
00379 n2 = CG_TeamScoreboard( y, TEAM_BLUE, fade, maxClients, lineHeight );
00380 CG_DrawTeamBackground( 0, y - topBorderSize, 640, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE );
00381 y += (n2 * lineHeight) + BIGCHAR_HEIGHT;
00382 maxClients -= n2;
00383 } else {
00384 n1 = CG_TeamScoreboard( y, TEAM_BLUE, fade, maxClients, lineHeight );
00385 CG_DrawTeamBackground( 0, y - topBorderSize, 640, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE );
00386 y += (n1 * lineHeight) + BIGCHAR_HEIGHT;
00387 maxClients -= n1;
00388 n2 = CG_TeamScoreboard( y, TEAM_RED, fade, maxClients, lineHeight );
00389 CG_DrawTeamBackground( 0, y - topBorderSize, 640, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED );
00390 y += (n2 * lineHeight) + BIGCHAR_HEIGHT;
00391 maxClients -= n2;
00392 }
00393 n1 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients, lineHeight );
00394 y += (n1 * lineHeight) + BIGCHAR_HEIGHT;
00395
00396 } else {
00397
00398
00399
00400 n1 = CG_TeamScoreboard( y, TEAM_FREE, fade, maxClients, lineHeight );
00401 y += (n1 * lineHeight) + BIGCHAR_HEIGHT;
00402 n2 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients - n1, lineHeight );
00403 y += (n2 * lineHeight) + BIGCHAR_HEIGHT;
00404 }
00405
00406 if (!localClient) {
00407
00408 for ( i = 0 ; i < cg.numScores ; i++ ) {
00409 if ( cg.scores[i].client == cg.snap->ps.clientNum ) {
00410 CG_DrawClientScore( y, &cg.scores[i], fadeColor, fade, lineHeight == SB_NORMAL_HEIGHT );
00411 break;
00412 }
00413 }
00414 }
00415
00416
00417 if ( ++cg.deferredPlayerLoading > 10 ) {
00418 CG_LoadDeferredPlayers();
00419 }
00420
00421 return qtrue;
00422 }
00423
00424
00425
00426
00427
00428
00429
00430
00431 static void CG_CenterGiantLine( float y, const char *string ) {
00432 float x;
00433 vec4_t color;
00434
00435 color[0] = 1;
00436 color[1] = 1;
00437 color[2] = 1;
00438 color[3] = 1;
00439
00440 x = 0.5 * ( 640 - GIANT_WIDTH * CG_DrawStrlen( string ) );
00441
00442 CG_DrawStringExt( x, y, string, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 );
00443 }
00444
00445
00446
00447
00448
00449
00450
00451
00452 void CG_DrawOldTourneyScoreboard( void ) {
00453 const char *s;
00454 vec4_t color;
00455 int min, tens, ones;
00456 clientInfo_t *ci;
00457 int y;
00458 int i;
00459
00460
00461 if ( cg.scoresRequestTime + 2000 < cg.time ) {
00462 cg.scoresRequestTime = cg.time;
00463 trap_SendClientCommand( "score" );
00464 }
00465
00466 color[0] = 1;
00467 color[1] = 1;
00468 color[2] = 1;
00469 color[3] = 1;
00470
00471
00472 color[0] = color[1] = color[2] = 0;
00473 color[3] = 1;
00474 CG_FillRect( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, color );
00475
00476
00477 s = CG_ConfigString( CS_MOTD );
00478 if ( !s[0] ) {
00479 s = "Scoreboard";
00480 }
00481
00482
00483 CG_CenterGiantLine( 8, s );
00484
00485
00486 ones = cg.time / 1000;
00487 min = ones / 60;
00488 ones %= 60;
00489 tens = ones / 10;
00490 ones %= 10;
00491 s = va("%i:%i%i", min, tens, ones );
00492
00493 CG_CenterGiantLine( 64, s );
00494
00495
00496
00497
00498 y = 160;
00499 if ( cgs.gametype >= GT_TEAM ) {
00500
00501
00502
00503 CG_DrawStringExt( 8, y, "Red Team", color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 );
00504 s = va("%i", cg.teamScores[0] );
00505 CG_DrawStringExt( 632 - GIANT_WIDTH * strlen(s), y, s, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 );
00506
00507 y += 64;
00508
00509 CG_DrawStringExt( 8, y, "Blue Team", color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 );
00510 s = va("%i", cg.teamScores[1] );
00511 CG_DrawStringExt( 632 - GIANT_WIDTH * strlen(s), y, s, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 );
00512 } else {
00513
00514
00515
00516 for ( i = 0 ; i < MAX_CLIENTS ; i++ ) {
00517 ci = &cgs.clientinfo[i];
00518 if ( !ci->infoValid ) {
00519 continue;
00520 }
00521 if ( ci->team != TEAM_FREE ) {
00522 continue;
00523 }
00524
00525 CG_DrawStringExt( 8, y, ci->name, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 );
00526 s = va("%i", ci->score );
00527 CG_DrawStringExt( 632 - GIANT_WIDTH * strlen(s), y, s, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 );
00528 y += 64;
00529 }
00530 }
00531
00532
00533 }
00534