static void WM_DrawClientScore(int x, int y, score_t *score, float *color, float fade) { float tempx; vec4_t hcolor; clientInfo_t *ci; if (y + SMALLCHAR_HEIGHT >= 440) { return; } if (score->client == cg.snap->ps.clientNum) { tempx = x; hcolor[3] = fade * 0.3; VectorSet(hcolor, 0.4452, 0.1172, 0.0782); // DARK - RED CG_FillRect(tempx, y + 1, INFO_PLAYER_WIDTH - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor); tempx += INFO_PLAYER_WIDTH; CG_FillRect(tempx, y + 1, INFO_SCORE_WIDTH - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor); tempx += INFO_SCORE_WIDTH; CG_FillRect(tempx, y + 1, INFO_LATENCY_WIDTH - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor); } tempx = x; ci = &cgs.clientinfo[score->client]; CG_DrawSmallString(tempx, y, ci->name, fade); tempx += INFO_PLAYER_WIDTH; CG_DrawSmallString(tempx, y, va("%4i", score->score), fade); tempx += INFO_SCORE_WIDTH; CG_DrawSmallString(tempx, y, va("%4i", score->ping), fade); }
static int WM_DrawInfoLine( int x, int y, float fade ) { int w, defender, winner; const char *s; if ( cg.snap->ps.pm_type != PM_INTERMISSION ) { return y; } w = 300; CG_DrawPic( 320 - w / 2, y, w, INFO_LINE_HEIGHT, trap_R_RegisterShaderNoMip( "ui_mp/assets/mp_line_strip.tga" ) ); s = CG_ConfigString( CS_MULTI_INFO ); defender = atoi( Info_ValueForKey( s, "defender" ) ); s = CG_ConfigString( CS_MULTI_MAPWINNER ); winner = atoi( Info_ValueForKey( s, "winner" ) ); if ( cgs.currentRound ) { // first round s = va( CG_TranslateString( "Clock is now set to %s!" ), WM_TimeToString( cgs.nextTimeLimit * 60.f * 1000.f ) ); } else { // second round if ( !defender ) { if ( winner != defender ) { s = "Allies sucessfully beat the clock!"; } else { s = "Allies couldn't beat the clock!"; } } else { if ( winner != defender ) { s = "Axis sucessfully beat the clock!"; } else { s = "Axis couldn't beat the clock!"; } } s = CG_TranslateString( s ); } w = CG_DrawStrlen( s ) * SMALLCHAR_WIDTH; CG_DrawSmallString( 320 - w / 2, ( y + INFO_LINE_HEIGHT / 2 ) - SMALLCHAR_HEIGHT / 2, s, fade ); return y + INFO_LINE_HEIGHT + 10; }
/* ======================================================================================================================================= WM_DrawObjectives ======================================================================================================================================= */ int WM_DrawObjectives(int x, int y, int width, float fade) { const char *s, *buf, *str; char teamstr[32]; int i, num, strwidth, status; y += 32; // determine character's team if (cg.snap->ps.persistant[PERS_TEAM] == TEAM_RED) { strcpy(teamstr, "axis_desc"); } else { strcpy(teamstr, "allied_desc"); } s = CG_ConfigString(CS_MULTI_INFO); buf = Info_ValueForKey(s, "numobjectives"); if (buf && atoi(buf)) { num = atoi(buf); for (i = 0; i < num; i++) { s = CG_ConfigString(CS_MULTI_OBJECTIVE1 + i); buf = Info_ValueForKey(s, teamstr); // draw text str = va("%s", buf); strwidth = CG_DrawStrlen(str) * SMALLCHAR_WIDTH; CG_DrawSmallString(x + width / 2 - strwidth / 2 - 12, y, str, fade); // draw status flags status = atoi(Info_ValueForKey(s, "status")); if (status == 0) { CG_DrawPic(x + width / 2 - strwidth / 2 - 16 - 24, y, 24, 16, trap_R_RegisterShaderNoMip("ui/assets/ger_flag.tga")); CG_DrawPic(x + width / 2 + strwidth / 2 - 12 + 4, y, 24, 16, trap_R_RegisterShaderNoMip("ui/assets/ger_flag.tga")); } else if (status == 1) { CG_DrawPic(x + width / 2 - strwidth / 2 - 16 - 24, y, 24, 16, trap_R_RegisterShaderNoMip("ui/assets/usa_flag.tga")); CG_DrawPic(x + width / 2 + strwidth / 2 - 12 + 4, y, 24, 16, trap_R_RegisterShaderNoMip("ui/assets/usa_flag.tga")); } y += 16; } } return y; }
static void WM_DrawClientScore_Small( int x, int y, score_t *score, float *color, float fade ) { int maxchars, offset; float tempx; vec4_t hcolor; clientInfo_t *ci; if ( y + SMALLCHAR_HEIGHT >= 470 ) return; ci = &cgs.clientinfo[score->client]; if ( score->client == cg.snap->ps.clientNum ) { tempx = x; hcolor[3] = fade * 0.3; VectorSet( hcolor, .5f, .5f, .2f ); // DARK-RED CG_FillRect( tempx, y + 1, INFO_PLAYER_WIDTH - INFO_BORDER, MINICHAR_HEIGHT - 1, hcolor ); tempx += INFO_PLAYER_WIDTH; if ( ci->team == TEAM_SPECTATOR ) { int width; width = INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH; CG_FillRect( tempx, y + 1, width - INFO_BORDER, MINICHAR_HEIGHT - 1, hcolor ); tempx += width; } else { CG_FillRect( tempx, y + 1, INFO_CLASS_WIDTH - INFO_BORDER, MINICHAR_HEIGHT - 1, hcolor ); tempx += INFO_CLASS_WIDTH; if( cg_gameType.integer == GT_WOLF_LMS ) { CG_FillRect( tempx, y + 1, INFO_SCORE_WIDTH - INFO_BORDER, MINICHAR_HEIGHT - 1, hcolor ); tempx += INFO_SCORE_WIDTH; } else { CG_FillRect( tempx, y + 1, INFO_XP_WIDTH - INFO_BORDER, MINICHAR_HEIGHT - 1, hcolor ); tempx += INFO_XP_WIDTH; } CG_FillRect( tempx, y + 1, INFO_LATENCY_WIDTH - INFO_BORDER, MINICHAR_HEIGHT - 1, hcolor ); tempx += INFO_LATENCY_WIDTH; if( cg_gameType.integer != GT_WOLF_LMS ) { CG_FillRect( tempx, y + 1, INFO_LIVES_WIDTH - INFO_BORDER, MINICHAR_HEIGHT - 1, hcolor ); tempx += INFO_LIVES_WIDTH; } } } tempx = x; // DHM - Nerve VectorSet( hcolor, 1, 1, 1 ); hcolor[3] = fade; maxchars = 17; offset = 0; if ( ci->team != TEAM_SPECTATOR ) { if ( ci->powerups & ( (1 << PW_REDFLAG) | (1 << PW_BLUEFLAG) ) ) { CG_DrawPic( tempx-2, y-4, 20, 20, trap_R_RegisterShader( "models/multiplayer/treasure/treasure" ) ); offset += 14; tempx += 14; maxchars -= 2; } // draw the skull icon if out of lives if ( score->respawnsLeft == -2 || ( cgs.clientinfo[cg.clientNum].team != TEAM_SPECTATOR && ci->team == cgs.clientinfo[cg.clientNum].team && cgs.clientinfo[score->client].health == -1 ) ) { CG_DrawPic( tempx, y, 12, 12, cgs.media.scoreEliminatedShader ); offset += 14; tempx += 14; maxchars -= 2; } else if( cgs.clientinfo[cg.clientNum].team != TEAM_SPECTATOR && ci->team == cgs.clientinfo[cg.clientNum].team && cgs.clientinfo[score->client].health == 0 ) { CG_DrawPic( tempx + 1, y + 1, 10, 10, cgs.media.medicIcon ); offset += 14; tempx += 14; maxchars -= 2; } } // draw name CG_DrawStringExt( tempx, y, ci->name, hcolor, qfalse, qfalse, MINICHAR_WIDTH, MINICHAR_HEIGHT, maxchars ); tempx += INFO_PLAYER_WIDTH - offset; // dhm - nerve if ( ci->team == TEAM_SPECTATOR ) { const char *s; int w, totalwidth; totalwidth = INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH - 8; s = CG_TranslateString( "^3SPECTATOR" ); w = CG_DrawStrlen( s ) * MINICHAR_WIDTH; CG_DrawSmallString( tempx + totalwidth - w, y, s, fade ); return; } else if ( cg.snap->ps.persistant[PERS_TEAM] == ci->team ) { CG_DrawStringExt( tempx, y, CG_TranslateString( BG_ShortClassnameForNumber( score->playerClass ) ), hcolor, qfalse, qfalse, MINICHAR_WIDTH, MINICHAR_HEIGHT, 0 ); // CG_DrawSmallString( tempx, y, CG_TranslateString( s ), fade ); } tempx += INFO_CLASS_WIDTH; CG_DrawStringExt( tempx, y, va( "%3i", score->score ), hcolor, qfalse, qfalse, MINICHAR_WIDTH, MINICHAR_HEIGHT, 0 ); if( cg_gameType.integer == GT_WOLF_LMS ) { tempx += INFO_SCORE_WIDTH; } else { tempx += INFO_XP_WIDTH; } CG_DrawStringExt( tempx, y, va( "%4i", score->ping ), hcolor, qfalse, qfalse, MINICHAR_WIDTH, MINICHAR_HEIGHT, 0 ); tempx += INFO_LATENCY_WIDTH; if( cg_gameType.integer != GT_WOLF_LMS ) { if( score->respawnsLeft >= 0 ) { CG_DrawStringExt( tempx, y, va( "%2i", score->respawnsLeft ), hcolor, qfalse, qfalse, MINICHAR_WIDTH, MINICHAR_HEIGHT, 0 ); } else { CG_DrawStringExt( tempx, y, va( " -", score->respawnsLeft ), hcolor, qfalse, qfalse, MINICHAR_WIDTH, MINICHAR_HEIGHT, 0 ); } tempx += INFO_LIVES_WIDTH; } }
static void WM_DrawClientScore( int x, int y, score_t *score, float *color, float fade ) { int maxchars, offset; int i, j; float tempx; vec4_t hcolor; clientInfo_t *ci; char buf[64]; if ( y + SMALLCHAR_HEIGHT >= 470 ) return; ci = &cgs.clientinfo[score->client]; if ( score->client == cg.snap->ps.clientNum ) { tempx = x; hcolor[3] = fade * 0.3; VectorSet( hcolor, .5f, .5f, .2f ); // DARK-RED CG_FillRect( tempx, y + 1, INFO_PLAYER_WIDTH - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor ); tempx += INFO_PLAYER_WIDTH; if ( ci->team == TEAM_SPECTATOR ) { int width; width = INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH; CG_FillRect( tempx, y + 1, width - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor ); tempx += width; } else { CG_FillRect( tempx, y + 1, INFO_CLASS_WIDTH - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor ); tempx += INFO_CLASS_WIDTH; if( cg_gameType.integer == GT_WOLF_LMS ) { CG_FillRect( tempx, y + 1, INFO_SCORE_WIDTH - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor ); tempx += INFO_SCORE_WIDTH; } else { CG_FillRect( tempx, y + 1, INFO_XP_WIDTH - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor ); tempx += INFO_XP_WIDTH; } CG_FillRect( tempx, y + 1, INFO_LATENCY_WIDTH - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor ); tempx += INFO_LATENCY_WIDTH; if( cg_gameType.integer != GT_WOLF_LMS ) { CG_FillRect( tempx, y + 1, INFO_LIVES_WIDTH - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor ); tempx += INFO_LIVES_WIDTH; } } } tempx = x; // DHM - Nerve VectorSet( hcolor, 1, 1, 1 ); hcolor[3] = fade; maxchars = 16; offset = 0; if ( ci->team != TEAM_SPECTATOR ) { if ( ci->powerups & ( (1 << PW_REDFLAG) | (1 << PW_BLUEFLAG) ) ) { CG_DrawPic( tempx-4, y, 16, 16, cgs.media.objectiveShader ); offset += 8; tempx += 12; maxchars -= 2; } // draw the skull icon if out of lives if( score->respawnsLeft == -2 || (cgs.clientinfo[cg.clientNum].team != TEAM_SPECTATOR && ci->team == cgs.clientinfo[cg.clientNum].team && cgs.clientinfo[score->client].health == -1 ) ) { CG_DrawPic( tempx, y, 18, 18, cgs.media.scoreEliminatedShader ); offset += 18; tempx += 18; maxchars -= 2; } else if( cgs.clientinfo[cg.clientNum].team != TEAM_SPECTATOR && ci->team == cgs.clientinfo[cg.clientNum].team && cgs.clientinfo[score->client].health == 0 ) { CG_DrawPic( tempx + 1, y + 1, 16, 16, cgs.media.medicIcon ); offset += 18; tempx += 18; maxchars -= 2; } } // draw name CG_DrawStringExt( tempx, y, ci->name, hcolor, qfalse, qfalse, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, maxchars ); maxchars -= CG_DrawStrlen( ci->name ); // draw medals buf[0] = '\0'; for( i = 0; i < SK_NUM_SKILLS; i++ ) { for( j = 0; j < ci->medals[i]; j++ ) Q_strcat( buf, sizeof(buf), va( "^%c%c", COLOR_RED + i, skillNames[i][0] ) ); } maxchars--; CG_DrawStringExt( tempx + (BG_drawStrlen(ci->name) * SMALLCHAR_WIDTH + SMALLCHAR_WIDTH), y, buf, hcolor, qfalse, qfalse, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, maxchars ); tempx += INFO_PLAYER_WIDTH - offset; if ( ci->team == TEAM_SPECTATOR ) { const char *s; int w, totalwidth; totalwidth = INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH - 8; s = CG_TranslateString( "^3SPECTATOR" ); w = CG_DrawStrlen( s ) * SMALLCHAR_WIDTH; CG_DrawSmallString( tempx + totalwidth - w, y, s, fade ); return; } // OSP - allow MV clients see the class of its merged client's on the scoreboard else if ( cg.snap->ps.persistant[PERS_TEAM] == ci->team || CG_mvMergedClientLocate(score->client) ) { CG_DrawSmallString( tempx, y, CG_TranslateString( BG_ShortClassnameForNumber( score->playerClass ) ), fade ); } tempx += INFO_CLASS_WIDTH; CG_DrawSmallString( tempx, y, va( "%3i", score->score ), fade ); if( cg_gameType.integer == GT_WOLF_LMS ) { tempx += INFO_SCORE_WIDTH; } else { tempx += INFO_XP_WIDTH; } CG_DrawSmallString( tempx, y, va( "%4i", score->ping ), fade ); tempx += INFO_LATENCY_WIDTH; if( cg_gameType.integer != GT_WOLF_LMS ) { if( score->respawnsLeft >= 0 ) { CG_DrawSmallString( tempx, y, va( "%2i", score->respawnsLeft ), fade ); } else { CG_DrawSmallString( tempx, y, va( " -", score->respawnsLeft ), fade ); } tempx += INFO_LIVES_WIDTH; } }
/* ======================================================================================================================================= WM_ScoreboardOverlay ======================================================================================================================================= */ int WM_ScoreboardOverlay(int x, int y, float fade) { vec4_t hcolor; int width; char *s; // JPW NERVE int msec, mins, seconds, tens; // JPW NERVE width = INFO_PLAYER_WIDTH + INFO_LATENCY_WIDTH + INFO_SCORE_WIDTH + 25; VectorSet(hcolor, 0, 0, 0); hcolor[3] = 0.7 * fade; // draw background CG_FillRect(x - 12, y, width, 400, hcolor); // draw title frame VectorSet(hcolor, 0.0039, 0.0039, 0.2461); hcolor[3] = 1 * fade; CG_FillRect(x - 12, y, width, 30, hcolor); CG_DrawRect(x - 12, y, width, 400, 2, hcolor); if (cg.snap->ps.pm_type == PM_INTERMISSION) { const char *s, *buf; s = CG_ConfigString(CS_MULTI_INFO); buf = Info_ValueForKey(s, "winner"); if (atoi(buf)) { CG_DrawSmallString(x - 12 + 5, y, "ALLIES WIN!", fade); } else { CG_DrawSmallString(x - 12 + 5, y, "AXIS WIN!", fade); } } // mission time & reinforce time else { msec = (cgs.timelimit * 60.f * 1000.f) - (cg.time - cgs.levelStartTime); seconds = msec / 1000; mins = seconds / 60; seconds -= mins * 60; tens = seconds / 10; seconds -= tens * 10; s = va("Mission time: %2.0f:%i%i", (float)mins, tens, seconds); // float cast to line up with reinforce time CG_DrawSmallString(x - 7, y, s, fade); if (cgs.clientinfo[cg.snap->ps.clientNum].team == TEAM_RED) { msec = cg_redlimbotime.integer - (cg.time % cg_redlimbotime.integer); } else if (cgs.clientinfo[cg.snap->ps.clientNum].team == TEAM_BLUE) { msec = cg_bluelimbotime.integer - (cg.time % cg_bluelimbotime.integer); } else { // no team(spectator mode) msec = 0; } if (msec) { seconds = msec / 1000; mins = seconds / 60; seconds -= mins * 60; tens = seconds / 10; seconds -= tens * 10; s = va("Reinforce time: %2.0f:%i%i", (float)mins, tens, seconds); CG_DrawSmallString(x - 7, y + 16, s, fade); } } // CG_DrawSmallString(x - 12 + 5, y, "Wolfenstein Multiplayer", fade); // old one y = WM_DrawObjectives(x, y, width, fade); y += 5; // draw field names CG_DrawSmallString(x, y, "Players", fade); x += INFO_PLAYER_WIDTH; CG_DrawSmallString(x, y, "Score", fade); x += INFO_SCORE_WIDTH; CG_DrawSmallString(x, y, "Latency", fade); y += 20; return y; }
/* ======================================================================================================================================= WM_TeamScoreboard ======================================================================================================================================= */ static int WM_TeamScoreboard(int x, int y, team_t team, float fade) { vec4_t hcolor; float tempx; int i; hcolor[3] = fade; if (team == TEAM_RED) { VectorSet(hcolor, 0.4452, 0.1172, 0.0782); // LIGHT - RED } else if (team == TEAM_BLUE) { VectorSet(hcolor, 0.1836, 0.2422, 0.1680); // LIGHT - GREEN } else { VectorSet(hcolor, 0.2, 0.2, 0.2); // DARK - GREY } // dont draw spectator if there are none for (i = 0; i < cg.numScores; i++) { if (team == cgs.clientinfo[cg.scores[i].client].team) { break; } } if (team == TEAM_SPECTATOR && i == cg.numScores) { return y; } // draw team header if (y + SMALLCHAR_HEIGHT >= 440) { return y; } tempx = x; CG_FillRect(tempx, y, INFO_PLAYER_WIDTH - INFO_BORDER, INFO_TEAM_HEIGHT, hcolor); if (team == TEAM_RED) { CG_DrawSmallString(tempx, y, "Axis", fade); } else if (team == TEAM_BLUE) { CG_DrawSmallString(tempx, y, "Allies", fade); } else { CG_DrawSmallString(tempx, y, "Spectators", fade); } tempx += INFO_PLAYER_WIDTH; CG_FillRect(tempx, y, INFO_SCORE_WIDTH - INFO_BORDER, INFO_TEAM_HEIGHT, hcolor); tempx += INFO_SCORE_WIDTH; CG_FillRect(tempx, y, INFO_LATENCY_WIDTH - INFO_BORDER, INFO_TEAM_HEIGHT, hcolor); // draw player info VectorSet(hcolor, 1, 1, 1); hcolor[3] = fade; y += INFO_TEAM_HEIGHT + INFO_BORDER; for (i = 0; i < cg.numScores; i++) { if (team != cgs.clientinfo[cg.scores[i].client].team) { continue; } WM_DrawClientScore(x, y, &cg.scores[i], hcolor, fade); y += SMALLCHAR_HEIGHT; } y += 4; return y; }
/* ================ CG_DrawRadarSymbols ================ */ static void CG_DrawRadarSymbols_AIR( int vehicle ) { unsigned int i; centity_t *self = &cg.predictedPlayerEntity; vec3_t pos, pos1, pos2; vec3_t dir; float dist; float range = availableVehicles[vehicle].radarRange; float scale; float hdg = self->currentState.angles[1]; float angle; vec3_t angles; int otherveh; vec3_t otherpos; int icon; int drawnTargets = 0; trace_t res; // radar screen and mode CG_DrawPic( 440, 280, 200, 200, cgs.media.HUDradar ); CG_DrawSmallString( 615, 340, "AIR", 1.0f); // current range if( cg.RADARRangeSetting ) { range /= (2 * cg.RADARRangeSetting); } // adjust for radar screen size scale = range/64; // tell range CG_DrawSmallString( 595, 320, va("%.0f", range), 1.0f); // ground vehicle adjustment for angle if( (availableVehicles[vehicle].cat & CAT_GROUND) || (availableVehicles[vehicle].cat & CAT_BOAT) ) { hdg += self->currentState.angles2[ROLL]; if( hdg > 360 ) hdg -= 360; else if( hdg < 0 ) hdg += 360; } // pos VectorCopy( self->currentState.pos.trBase, pos ); // walk through list of targets for( i = 0; i < cg.radarTargets; i++ ) { // dont show self if( cg.radarEnts[i] == &cg.predictedPlayerEntity ) continue; // dont show dead ones if( cg.radarEnts[i]->currentState.eFlags & EF_DEAD ) continue; // get other vehicle if( cg.radarEnts[i]->currentState.eType == ET_MISC_VEHICLE ) { otherveh = cg.radarEnts[i]->currentState.modelindex; } else { otherveh = cgs.clientinfo[cg.radarEnts[i]->currentState.clientNum].vehicle; } VectorCopy( cg.radarEnts[i]->currentState.pos.trBase, otherpos ); // get dir and dist VectorSet( pos1, otherpos[0], otherpos[1], 0 ); VectorSet( pos2, pos[0], pos[1], 0 ); VectorSubtract( pos1, pos2, dir ); dist = VectorNormalize(dir); // check out of range if( dist > range ) continue; // scale dist to radar screen dist /= scale; // get screen dir vectoangles( dir, angles ); angle = angles[1]-hdg; if( angle > 360 ) angle -= 360; else if( angle < 0 ) angle += 360; if( angle >= 90 && angle <= 270 ) { if( !(cg.radarEnts[i]->currentState.ONOFF & OO_RADAR) ) continue; } angles[1] -= hdg - 90; if( angles[1] > 360 ) angles[1] -= 360; else if( angles[1] < 0 ) angles[1] += 360; angles[0] = angles[2] = 0; AngleVectors( angles, dir, 0, 0 ); VectorScale( dir, dist, dir ); // check LOS and/or RADAR on if( !(cg.radarEnts[i]->currentState.ONOFF & OO_RADAR) ) { CG_Trace( &res, pos, NULL, NULL, otherpos, cg.snap->ps.clientNum, MASK_SOLID ); if( res.fraction < 1.0f ) continue; } // which icon (if at all, dont show lqms) if( (availableVehicles[otherveh].cat & CAT_PLANE) || (availableVehicles[otherveh].cat & CAT_HELO) ) { float alt = otherpos[2] - pos[2]; icon = RD_AIR_SAME_ENEMY; if( alt > 1000 ) icon += 3; else if( alt < -1000 ) icon += 6; } else { continue; } // friend or foe if( cgs.gametype >= GT_TEAM ) { if( cgs.clientinfo[cg.radarEnts[i]->currentState.clientNum].team == cgs.clientinfo[self->currentState.clientNum].team ) icon++; } // draw CG_DrawPic( 558 + dir[0], 386 - dir[1], 8, 8, cgs.media.radarIcons[icon] ); // check if we should draw any more targets drawnTargets++; if( drawnTargets >= cg_radarTargets.integer ) break; } cg.radarTargets = 0; }
static void WM_DrawClientScore(int x, int y, score_t * score, float *color, float fade) { int maxchars, offset; int i, j; float tempx; vec4_t hcolor; clientInfo_t *ci; char buf[64]; // CHRUKER: b0?? - Was using the wrong char height for this calculation if(y + SMALLCHAR_HEIGHT >= 470) { return; } ci = &cgs.clientinfo[score->client]; if(score->client == cg.snap->ps.clientNum) { hcolor[3] = fade * 0.3; VectorSet(hcolor, .5f, .5f, .2f); // DARK-RED // CHRUKER: b077 - Player highlighting was split into columns CG_FillRect( x-5, y, (INFO_PLAYER_WIDTH + INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH + 5), SMALLCHAR_HEIGHT - 1, hcolor ); } tempx = x; // DHM - Nerve VectorSet(hcolor, 1, 1, 1); hcolor[3] = fade; maxchars = 16; offset = 0; if(ci->team != TEAM_SPECTATOR) { if(ci->powerups & ((1 << PW_REDFLAG) | (1 << PW_BLUEFLAG))) { // CHRUKER: b078 - Medic, death and objective icons on the scoreboard are drawn too big CG_DrawPic( tempx - 3, y + 1, 14, 14, cgs.media.objectiveShader ); offset += 14; // CHRUKER: b072 - Need to match tempx or else the other text gets offset tempx += 14; maxchars -= 2; } // draw the skull icon if out of lives if(score->respawnsLeft == -2 || (cgs.clientinfo[cg.clientNum].team != TEAM_SPECTATOR && ci->team == cgs.clientinfo[cg.clientNum].team && cgs.clientinfo[score->client].health == -1)) { // CHRUKER: b078 - Medic, death and objective icons on the scoreboard are drawn too big CG_DrawPic( tempx - 3, y + 1, 14, 14, cgs.media.scoreEliminatedShader ); offset += 14; tempx += 14; maxchars -= 2; } else if(cgs.clientinfo[cg.clientNum].team != TEAM_SPECTATOR && ci->team == cgs.clientinfo[cg.clientNum].team && cgs.clientinfo[score->client].health == 0) { // CHRUKER: b078 - Medic, death and objective icons on the scoreboard are drawn too big CG_DrawPic( tempx - 3, y + 1, 14, 14, cgs.media.medicIcon ); offset += 14; tempx += 14; maxchars -= 2; } } // draw name CG_DrawStringExt(tempx, y, ci->name, hcolor, qfalse, qfalse, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, maxchars); maxchars -= CG_DrawStrlen(ci->name); // draw medals buf[0] = '\0'; for(i = 0; i < SK_NUM_SKILLS; i++) { for(j = 0; j < ci->medals[i]; j++) Q_strcat(buf, sizeof(buf), va("^%c%c", COLOR_RED + i, skillNames[i][0])); } maxchars--; // CHRUKER: b032 - Medals clipped wrong in scoreboard when you're dead, because CG_DrawStringExt will draw // everything if maxchars <= 0 if (maxchars > 0) { CG_DrawStringExt(tempx + (BG_drawStrlen(ci->name) * SMALLCHAR_WIDTH + SMALLCHAR_WIDTH), y, buf, hcolor, qfalse, qfalse, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, maxchars); } tempx += INFO_PLAYER_WIDTH - offset; if(ci->team == TEAM_SPECTATOR) { const char *s; int w, totalwidth; totalwidth = INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH - 8; // CHRUKER: b031 - Show connecting people as connecting if (score->ping == -1) { s = CG_TranslateString( "^1CONNECTING" ); } else { s = CG_TranslateString( "^3SPECTATOR" ); } w = CG_DrawStrlen(s) * SMALLCHAR_WIDTH; CG_DrawSmallString(tempx + totalwidth - w, y, s, fade); return; } // OSP - allow MV clients see the class of its merged client's on the scoreboard else if(cg.snap->ps.persistant[PERS_TEAM] == ci->team || CG_mvMergedClientLocate(score->client)) { CG_DrawSmallString(tempx, y, CG_TranslateString(BG_ShortClassnameForNumber(score->playerClass)), fade); } tempx += INFO_CLASS_WIDTH; CG_DrawSmallString(tempx, y, va("%3i", score->score), fade); if(cg_gameType.integer == GT_WOLF_LMS) { tempx += INFO_SCORE_WIDTH; } else { tempx += INFO_XP_WIDTH; } CG_DrawSmallString(tempx, y, va("%4i", score->ping), fade); tempx += INFO_LATENCY_WIDTH; if(cg_gameType.integer != GT_WOLF_LMS) { if(score->respawnsLeft >= 0) { CG_DrawSmallString(tempx, y, va("%2i", score->respawnsLeft), fade); } else { CG_DrawSmallString(tempx, y, " -", fade); } tempx += INFO_LIVES_WIDTH; } }
static int WM_TeamScoreboard( int x, int y, team_t team, float fade, int maxrows ) { vec4_t hcolor; float tempx, tempy; int height, width; int i, rows; height = SMALLCHAR_HEIGHT * maxrows; width = INFO_PLAYER_WIDTH + INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH; rows = height / SMALLCHAR_HEIGHT - 2; hcolor[0] = hcolor[1] = hcolor[2] = 1; hcolor[3] = 1.f; trap_R_SetColor( hcolor ); CG_DrawPic( x - 15, y - 4, width + 30, height + 1, trap_R_RegisterShaderNoMip( "ui_mp/assets/mp_score_team.tga" ) ); trap_R_SetColor( NULL ); if ( team == TEAM_RED ) { VectorSet( hcolor, ( 68.f / 255.f ), ( 0.f / 255.f ), ( 0.f / 255.f ) ); } else if ( team == TEAM_BLUE ) { VectorSet( hcolor, ( 0.f / 255.f ), ( 45.f / 255.f ), ( 68.f / 255.f ) ); } hcolor[3] = 1 * fade; // draw header if ( team == TEAM_RED ) { CG_DrawSmallString( x, y, va( "%s [%d] (%d %s)", CG_TranslateString( "Axis" ), cg.teamScores[0], cg.teamPlayers[team], CG_TranslateString( "players" ) ), fade ); } else if ( team == TEAM_BLUE ) { CG_DrawSmallString( x, y, va( "%s [%d] (%d %s)", CG_TranslateString( "Allies" ), cg.teamScores[1], cg.teamPlayers[team], CG_TranslateString( "players" ) ), fade ); } y += SMALLCHAR_HEIGHT + 4; // save off y val tempy = y; // draw color bands for ( i = 0; i < rows; i++ ) { hcolor[3] = fade * 0.3; if ( i % 2 == 0 ) { VectorSet( hcolor, ( 0.f / 255.f ), ( 163.f / 255.f ), ( 113.f / 255.f ) ); // LIGHT BLUE } else { VectorSet( hcolor, ( 0.f / 255.f ), ( 133.f / 255.f ), ( 92.f / 255.f ) ); // DARK BLUE } hcolor[3] = 0; CG_FillRect( x, y, width, SMALLCHAR_HEIGHT, hcolor ); y += SMALLCHAR_HEIGHT; } hcolor[3] = 1; y = tempy; tempx = x; // draw player info headings CG_DrawSmallString( tempx, y, CG_TranslateString( "Name" ), fade ); tempx += INFO_PLAYER_WIDTH; CG_DrawSmallString( tempx, y, CG_TranslateString( "Class" ), fade ); tempx += INFO_CLASS_WIDTH; CG_DrawSmallString( tempx, y, CG_TranslateString( "Score" ), fade ); tempx += INFO_SCORE_WIDTH; CG_DrawSmallString( tempx, y, CG_TranslateString( "Ping" ), fade ); tempx += INFO_LATENCY_WIDTH; y += SMALLCHAR_HEIGHT; // draw player info VectorSet( hcolor, 1, 1, 1 ); hcolor[3] = fade; cg.teamPlayers[team] = 0; // JPW NERVE for ( i = 0; i < cg.numScores; i++ ) { if ( team != cgs.clientinfo[ cg.scores[i].client ].team ) { continue; } cg.teamPlayers[team]++; // JPW NERVE // one frame latency, but who cares? WM_DrawClientScore( x, y, &cg.scores[i], hcolor, fade ); y += SMALLCHAR_HEIGHT; } // draw spectators y += SMALLCHAR_HEIGHT; for ( i = 0; i < cg.numScores; i++ ) { if ( cgs.clientinfo[ cg.scores[i].client ].team != TEAM_SPECTATOR ) { continue; } if ( team == TEAM_RED && ( i % 2 ) ) { continue; } if ( team == TEAM_BLUE && ( ( i + 1 ) % 2 ) ) { continue; } WM_DrawClientScore( x, y, &cg.scores[i], hcolor, fade ); y += SMALLCHAR_HEIGHT; } return y; }
static void WM_DrawClientScore( int x, int y, score_t *score, float *color, float fade ) { int maxchars, offset; float tempx; vec4_t hcolor; clientInfo_t *ci; if ( y + SMALLCHAR_HEIGHT >= 470 ) { return; } ci = &cgs.clientinfo[score->client]; if ( score->client == cg.snap->ps.clientNum ) { tempx = x; hcolor[3] = fade * 0.3; VectorSet( hcolor, 0.4452, 0.1172, 0.0782 ); // DARK-RED CG_FillRect( tempx, y + 1, INFO_PLAYER_WIDTH - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor ); tempx += INFO_PLAYER_WIDTH; if ( ci->team == TEAM_SPECTATOR ) { int width; width = INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH; CG_FillRect( tempx, y + 1, width - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor ); tempx += width; } else { CG_FillRect( tempx, y + 1, INFO_CLASS_WIDTH - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor ); tempx += INFO_CLASS_WIDTH; CG_FillRect( tempx, y + 1, INFO_SCORE_WIDTH - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor ); tempx += INFO_SCORE_WIDTH; CG_FillRect( tempx, y + 1, INFO_LATENCY_WIDTH - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor ); tempx += INFO_LATENCY_WIDTH; } } tempx = x; // DHM - Nerve VectorSet( hcolor, 1, 1, 1 ); hcolor[3] = fade; maxchars = 17; offset = 0; if ( ci->team != TEAM_SPECTATOR ) { if ( ci->powerups & ( ( 1 << PW_REDFLAG ) | ( 1 << PW_BLUEFLAG ) ) ) { CG_DrawPic( tempx - 4, y - 4, 24, 24, trap_R_RegisterShader( "models/multiplayer/treasure/treasure" ) ); offset += 16; tempx += 16; maxchars -= 2; } // draw the skull icon if out of lives if ( score->respawnsLeft == -2 ) { CG_DrawPic( tempx, y, 18, 18, cgs.media.scoreEliminatedShader ); offset += 18; tempx += 18; maxchars -= 2; } } // draw name CG_DrawStringExt( tempx, y, ci->name, hcolor, qfalse, qfalse, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, maxchars ); tempx += INFO_PLAYER_WIDTH - offset; // dhm - nerve if ( ci->team == TEAM_SPECTATOR ) { const char *s; int w, totalwidth; totalwidth = INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH - 8; s = CG_TranslateString( "^3SPECTATOR" ); w = CG_DrawStrlen( s ) * SMALLCHAR_WIDTH; CG_DrawSmallString( tempx + totalwidth - w, y, s, fade ); return; } else if ( cg.snap->ps.persistant[PERS_TEAM] == ci->team ) { int val = score->playerClass; // cg_entities[ ci->clientNum ].currentState.teamNum; const char *s; if ( val == 0 ) { s = "Soldr"; } else if ( val == 1 ) { s = "Medic"; } else if ( val == 2 ) { s = "Engr"; } else if ( val == 3 ) { s = "Lieut"; } else { s = ""; } CG_DrawSmallString( tempx, y, CG_TranslateString( s ), fade ); } tempx += INFO_CLASS_WIDTH; CG_DrawSmallString( tempx, y, va( "%4i", score->score ), fade ); tempx += INFO_SCORE_WIDTH; CG_DrawSmallString( tempx, y, va( "%4i", score->ping ), fade ); tempx += INFO_LATENCY_WIDTH; }
int WM_DrawObjectives( int x, int y, int width, float fade ) { const char *s, *buf, *str; char teamstr[32]; int i, height, tempy, rows; vec4_t hcolor; rows = 7; height = SMALLCHAR_HEIGHT * rows; hcolor[0] = hcolor[1] = hcolor[2] = 1; hcolor[3] = 1.f; trap_R_SetColor( hcolor ); if ( cg.snap->ps.pm_type != PM_INTERMISSION ) { CG_DrawPic( x - 10, y, width + 20, height + SMALLCHAR_HEIGHT + 10 + 1, trap_R_RegisterShaderNoMip( "ui_mp/assets/mp_score_objectives" ) ); } VectorSet( hcolor, 1, 1, 1 ); trap_R_SetColor( NULL ); VectorSet( hcolor, ( 68.f / 255.f ), ( 0.f / 255.f ), ( 0.f / 255.f ) ); hcolor[3] = 1 * fade; // draw header if ( cg.snap->ps.pm_type != PM_INTERMISSION ) { CG_DrawSmallString( x, y, CG_TranslateString( "Goals" ), fade ); } y += SMALLCHAR_HEIGHT + 3; // draw color bands tempy = y; if ( cg.snap->ps.pm_type != PM_INTERMISSION ) { for ( i = 0; i < rows; i++ ) { hcolor[3] = fade * 0.3; if ( i % 2 == 0 ) { VectorSet( hcolor, ( 0.f / 255.f ), ( 113.f / 255.f ), ( 163.f / 255.f ) ); // LIGHT BLUE } else { VectorSet( hcolor, ( 0.f / 255.f ), ( 92.f / 255.f ), ( 133.f / 255.f ) ); // DARK BLUE } hcolor[3] = 0; CG_FillRect( x, y, width, SMALLCHAR_HEIGHT, hcolor ); y += SMALLCHAR_HEIGHT; } } hcolor[3] = 1; y = tempy; if ( cg.snap->ps.pm_type == PM_INTERMISSION ) { const char *shader = NULL, *flagshader = NULL, *nameshader = NULL; s = CG_ConfigString( CS_MULTI_MAPWINNER ); buf = Info_ValueForKey( s, "winner" ); if ( atoi( buf ) == -1 ) { str = "ITS A TIE!"; } else if ( atoi( buf ) ) { str = "ALLIES"; shader = "ui_mp/assets/portraits/allies_win"; flagshader = "ui_mp/assets/portraits/allies_win_flag.tga"; nameshader = "ui_mp/assets/portraits/text_allies.tga"; if ( !cg.latchVictorySound ) { cg.latchVictorySound = qtrue; trap_S_StartLocalSound( trap_S_RegisterSound( "sound/multiplayer/music/l_complete_2.wav" ), CHAN_LOCAL_SOUND ); if ( cg_announcer.integer ) { trap_S_StartLocalSound( cgs.media.winAllies, CHAN_ANNOUNCER ); } } } else { str = "AXIS"; shader = "ui_mp/assets/portraits/axis_win"; flagshader = "ui_mp/assets/portraits/axis_win_flag.tga"; nameshader = "ui_mp/assets/portraits/text_axis.tga"; if ( !cg.latchVictorySound ) { cg.latchVictorySound = qtrue; trap_S_StartLocalSound( trap_S_RegisterSound( "sound/multiplayer/music/s_stinglow.wav" ), CHAN_LOCAL_SOUND ); if ( cg_announcer.integer ) { trap_S_StartLocalSound( cgs.media.winAxis, CHAN_ANNOUNCER ); } } } y += SMALLCHAR_HEIGHT * ( ( rows - 2 ) / 2 ); if ( flagshader ) { CG_DrawPic( 10, 10, 210, 136, trap_R_RegisterShaderNoMip( flagshader ) ); CG_DrawPic( 415, 10, 210, 136, trap_R_RegisterShaderNoMip( flagshader ) ); } if ( shader ) { CG_DrawPic( 229, 10, 182, 136, trap_R_RegisterShaderNoMip( shader ) ); } if ( nameshader ) { CG_DrawPic( 50, 50, 127, 64, trap_R_RegisterShaderNoMip( nameshader ) ); CG_DrawPic( 455, 50, 127, 64, trap_R_RegisterShaderNoMip( "ui_mp/assets/portraits/text_win.tga" ) ); } return y; } // JPW NERVE -- mission time & reinforce time else { int msec, mins, seconds, tens; tempy = y; y += SMALLCHAR_HEIGHT * ( rows - 1 ); msec = ( cgs.timelimit * 60.f * 1000.f ) - ( cg.time - cgs.levelStartTime ); seconds = msec / 1000; mins = seconds / 60; seconds -= mins * 60; tens = seconds / 10; seconds -= tens * 10; if ( msec < 0 ) { s = va( "%s %s", CG_TranslateString( "Mission time:" ), CG_TranslateString( "Sudden Death" ) ); } else { s = va( "%s %2.0f:%i%i", CG_TranslateString( "Mission time:" ), (float)mins, tens, seconds ); // float cast to line up with reinforce time } CG_DrawSmallString( x,y,s,fade ); if ( cgs.clientinfo[cg.snap->ps.clientNum].team == TEAM_RED ) { msec = cg_redlimbotime.integer - ( ( cgs.aReinfOffset[TEAM_RED] + cg.time - cgs.levelStartTime ) % cg_redlimbotime.integer ) + 1000; } else if ( cgs.clientinfo[cg.snap->ps.clientNum].team == TEAM_BLUE ) { msec = cg_bluelimbotime.integer - ( ( cgs.aReinfOffset[TEAM_BLUE] + cg.time - cgs.levelStartTime ) % cg_bluelimbotime.integer ) + 1000; } else { // no team (spectator mode) msec = 0; } if ( msec ) { seconds = msec / 1000; mins = seconds / 60; seconds -= mins * 60; tens = seconds / 10; seconds -= tens * 10; s = va( "%s %2.0f:%i%i", CG_TranslateString( "Reinforce time:" ), (float)mins, tens, seconds ); CG_DrawSmallString( x + 425,y,s,fade ); } // NERVE - SMF if ( cgs.gametype == GT_WOLF_STOPWATCH ) { int w; s = va( "%s %i", CG_TranslateString( "Stopwatch Round" ), cgs.currentRound + 1 ); w = CG_DrawStrlen( s ) * SMALLCHAR_WIDTH; CG_DrawSmallString( x + 300 - w / 2,y,s,fade ); } // -NERVE - SMF y = tempy; } // jpw // determine character's team if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_RED ) { strcpy( teamstr, "short_axis_desc" ); } else { strcpy( teamstr, "short_allied_desc" ); } s = CG_ConfigString( CS_MULTI_INFO ); buf = Info_ValueForKey( s, "numobjectives" ); if ( buf && atoi( buf ) ) { int num = atoi( buf ); int strwidth, status; for ( i = 0; i < num; i++ ) { s = CG_ConfigString( CS_MULTI_OBJECTIVE1 + i ); buf = Info_ValueForKey( s, teamstr ); if ( !buf || !strlen( buf ) ) { str = va( "%s %i", CG_TranslateString( "Objective" ), i + 1 ); } else { str = va( "%s", CG_TranslateString( buf ) ); } // draw text strwidth = CG_DrawStrlen( str ) * SMALLCHAR_WIDTH; CG_DrawSmallString( x + width / 2 - strwidth / 2 - 12, y, str, fade ); // draw status flags s = CG_ConfigString( CS_MULTI_OBJ1_STATUS + i ); status = atoi( Info_ValueForKey( s, "status" ) ); if ( status == 0 ) { CG_DrawPic( x, y + 1, 24, 14, trap_R_RegisterShaderNoMip( "ui_mp/assets/ger_flag.tga" ) ); } else if ( status == 1 ) { CG_DrawPic( x, y + 1, 24, 14, trap_R_RegisterShaderNoMip( "ui_mp/assets/usa_flag.tga" ) ); } y += SMALLCHAR_HEIGHT; } } return y; }
/* ================ CG_DrawStatusBar_MFQ3 ================ */ void CG_DrawStatusBar_MFQ3( void ) { int color; centity_t *cent; playerState_t *ps; int value; int vehicle = cgs.clientinfo[cg.predictedPlayerState.clientNum].vehicle; int w; static vec4_t colors[] = { // { 0.2, 1.0, 0.2, 1.0 } , { 1.0, 0.2, 0.2, 1.0 }, {0.5, 0.5, 0.5, 1} }; { 1.0f, 0.89f, 0.0f, 1.0f } , // normal, yellow { 1.0f, 0.0f, 0.0f, 1.0f }, // low health, red {0.5f, 0.5f, 0.5f, 1.0f}, // weapon firing, grey { 1.0f, 1.0f, 1.0f, 1.0f }, // health > 100, white { 0.3f, 1.0f, 0.3f, 1.0f } // green }; if ( cg_drawStatus.integer == 0 ) { return; } cent = &cg_entities[cg.snap->ps.clientNum]; ps = &cg.snap->ps; // aiming/targetting reticles CG_Draw_Reticles(); // main background CG_DrawPic( 0, 430, 640, 50, cgs.media.HUDmain ); // // flag // if( cg.predictedPlayerState.objectives & OB_REDFLAG ) { CG_DrawStatusBarFlag( 640 - ICON_SIZE, ClientBase::TEAM_RED ); } else if( cg.predictedPlayerState.objectives & OB_BLUEFLAG ) { CG_DrawStatusBarFlag( 640 - ICON_SIZE, ClientBase::TEAM_BLUE ); } // // RADAR // if( cent->currentState.ONOFF & OO_RADAR_AIR ) { CG_DrawRadarSymbols_AIR(vehicle); } else if( cent->currentState.ONOFF & OO_RADAR_GROUND ) { CG_DrawRadarSymbols_GROUND(vehicle); } else if( availableVehicles[vehicle].radarRange || availableVehicles[vehicle].radarRange2 ) { CG_DrawPic( 440, 280, 200, 200, cgs.media.HUDradar ); CG_DrawSmallString( 595, 320, "OFF", 1.0f); } // // GPS // if( cg.GPS ) { trace_t tr; vec3_t start, end; // main CG_DrawPic( -14, 380, 512, 102, cgs.media.HUDgps ); // heading value = 360 - (int)ps->vehicleAngles[1]; CG_DrawSmallString( 234, 420, va("%i",value), 1.0f ); // altitude VectorCopy( ps->origin, start ); start[2] += availableVehicles[vehicle].mins[2]; VectorCopy( start, end ); end[2] -= 2000; CG_Trace( &tr, start, vec3_origin, vec3_origin, end, cg.snap->ps.clientNum, MASK_SOLID|MASK_WATER ); value = (int)(tr.fraction * 2000); if( value > 100 ) color = 3; else if( value > 50 ) color = 4; else if( value > 25 ) color = 0; else color = 1; if( value < 2000 ) { CG_DrawSmallStringColor( 374, 420, va("%i",value), colors[color] ); } else { CG_DrawSmallStringColor( 374, 420, "XXXX", colors[color] ); } // x coord value = (int)ps->origin[0]; CG_DrawSmallString( 264, 423, va("%i",value), 0.7f ); // y coord value = (int)ps->origin[1]; CG_DrawSmallString( 320, 423, va("%i",value), 0.7f ); } // // INFO // if( !cg.INFO ) { // bit dirty to have NOT but oh well... // main CG_DrawPic( 0, 330, 150, 150, cgs.media.HUDext ); if( availableVehicles[vehicle].caps & HC_GEAR ) { if( cent->currentState.ONOFF & OO_GEAR ) { CG_DrawSmallStringColor( 2, 390, "Gear", colors[4] ); } else { CG_DrawSmallString( 2, 390, "Gear", 1.0f ); } } if( availableVehicles[vehicle].caps & HC_SPEEDBRAKE ) { if( cent->currentState.ONOFF & OO_SPEEDBRAKE ) { CG_DrawSmallStringColor( 2, 410, "Speedbrakes", colors[4] ); } else { CG_DrawSmallString( 2, 410, "Speedbrakes", 1.0f ); } } else { if( cent->currentState.ONOFF & OO_SPEEDBRAKE ) { CG_DrawSmallStringColor( 2, 410, "Brakes", colors[4] ); } else { CG_DrawSmallString( 2, 410, "Brakes", 1.0f ); } } value = ps->stats[STAT_FUEL]; if ( value > 10 ) { color = 3; // white } else if (value > 5) { color = 0; // yellow } else { color = 1; // red } if( (availableVehicles[vehicle].cat & CAT_PLANE) || (availableVehicles[vehicle].cat & CAT_HELO) || (availableVehicles[vehicle].cat & CAT_BOAT) ) { value *= 100; } CG_DrawSmallStringColor( 2, 430, va("Fuel %i", value), colors[color]); } // // FLARES // if( ps->ammo[WP_FLARE+8] > 0 ) { CG_DrawBigString( 600, 462, va("%i", ps->ammo[WP_FLARE]), 1.0f ); } // // speed and throttle // value = ps->speed/10; if ( value > availableVehicles[vehicle].stallspeed * SPEED_GREEN_ARC ) { color = 3; // white } else if (value > availableVehicles[vehicle].stallspeed * SPEED_YELLOW_ARC ) { color = 4; // green } else if (value >= availableVehicles[vehicle].stallspeed) { color = 0; // yellow } else { color = 1; // red } w = CG_DrawStrlen(va("%i",value)) * BIGCHAR_WIDTH; CG_DrawBigStringColor(285-w, 460, va("%i",value), colors[color]); if( ps->throttle > availableVehicles[vehicle].maxthrottle ) { value = ps->throttle - availableVehicles[vehicle].maxthrottle; } else { value = ps->throttle; } CG_DrawPic(295, 443, 50, 37, cgs.media.throttle[value]); // // health // value = (100*ps->stats[STAT_HEALTH]/ps->stats[STAT_MAX_HEALTH]); if( value > 100 ) value = 100; if ( value < 10 ) { color = 1; } else if (value < 25) { color = 0; } else { color = 3; } w = CG_DrawStrlen(va("%i",value)) * BIGCHAR_WIDTH; CG_DrawBigStringColor( 398-w, 460, va("%i",value), colors[color]); // // ammo // if( cent->currentState.weaponNum >= 0 ) { value = ps->ammo[cent->currentState.weaponNum]; w = CG_DrawStrlen(va("%i",value)) * BIGCHAR_WIDTH; CG_DrawBigString (500-w, 460, va("%i",value),1.0f); CG_DrawPic( 416, 440, 24, 45, availableWeapons[availableVehicles[vehicle].weapons[cent->currentState.weaponNum]].iconHandle ); } // // ammo mg // if( ps->ammo[WP_MACHINEGUN+8] > 0 ) { if( cent->currentState.weaponNum >= 0 ) { value = ps->ammo[0]; w = CG_DrawStrlen(va("%i",value)) * BIGCHAR_WIDTH; CG_DrawBigString (180-w, 460, va("%i",value),1.0f); CG_DrawPic( 200, 440, 24, 45, availableWeapons[availableVehicles[vehicle].weapons[0]].iconHandle ); } } }
static int WM_TeamScoreboard( int x, int y, team_t team, float fade, int maxrows ) { vec4_t hcolor; float tempx, tempy; int height, width; int i; int count = 0; vec4_t tclr = { 0.6f, 0.6f, 0.6f, 1.0f }; height = SMALLCHAR_HEIGHT * maxrows; width = INFO_PLAYER_WIDTH + INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH; CG_FillRect( x-5, y-2, width+5, 21, clrUiBack ); CG_FillRect( x-5, y-2, width+5, 21, clrUiBar ); Vector4Set( hcolor, 0, 0, 0, fade ); CG_DrawRect_FixedBorder( x-5, y-2, width+5, 21, 1, colorBlack ); // draw header if( cg_gameType.integer == GT_WOLF_LMS ) { char *s; if ( team == TEAM_AXIS ) { s = va( "%s [%d] (%d %s)", CG_TranslateString( "AXIS" ), cg.teamScores[0], cg.teamPlayers[team], CG_TranslateString("PLAYERS") ); s = va( "%s ^3%s", s, cg.teamFirstBlood == TEAM_AXIS ? CG_TranslateString("FIRST BLOOD") : "" ); CG_Text_Paint_Ext( x, y + 13, 0.25f, 0.25f, tclr, s, 0, 0, 0, &cgs.media.limboFont1 ); } else if ( team == TEAM_ALLIES ) { s = va( "%s [%d] (%d %s)", CG_TranslateString( "ALLIES" ), cg.teamScores[1], cg.teamPlayers[team], CG_TranslateString("PLAYERS") ); s = va( "%s ^3%s", s, cg.teamFirstBlood == TEAM_ALLIES ? CG_TranslateString("FIRST BLOOD") : "" ); CG_Text_Paint_Ext( x, y + 13, 0.25f, 0.25f, tclr, s, 0, 0, 0, &cgs.media.limboFont1 ); } } else { if ( team == TEAM_AXIS ) { CG_Text_Paint_Ext( x, y + 13, 0.25f, 0.25f, tclr, va( "%s [%d] (%d %s)", CG_TranslateString( "AXIS" ), cg.teamScores[0], cg.teamPlayers[team], CG_TranslateString("PLAYERS") ), 0, 0, 0, &cgs.media.limboFont1 ); } else if ( team == TEAM_ALLIES ) { CG_Text_Paint_Ext( x, y + 13, 0.25f, 0.25f, tclr, va( "%s [%d] (%d %s)", CG_TranslateString( "ALLIES" ), cg.teamScores[1], cg.teamPlayers[team], CG_TranslateString("PLAYERS") ), 0, 0, 0, &cgs.media.limboFont1 ); } } y += SMALLCHAR_HEIGHT + 3; // save off y val tempy = y; // draw color bands for ( i = 0; i <= maxrows; i++ ) { if ( i % 2 == 0 ) VectorSet( hcolor, (80.f/255.f), (80.f/255.f), (80.f/255.f) ); // LIGHT BLUE else VectorSet( hcolor, (0.f/255.f), (0.f/255.f), (0.f/255.f) ); // DARK BLUE hcolor[3] = fade * 0.3; CG_FillRect( x-5, y, width+5, SMALLCHAR_HEIGHT+1, hcolor ); trap_R_SetColor( colorBlack ); CG_DrawTopBottom( x-5, y, width+5, SMALLCHAR_HEIGHT+1, 1 ); trap_R_SetColor( NULL ); y += SMALLCHAR_HEIGHT; } hcolor[3] = 1; y = tempy; tempx = x; CG_FillRect( x-5, y-1, width+5, 18, clrUiBack ); //CG_FillRect( x-5, y-1, width+5, 18, clrUiBar ); trap_R_SetColor( colorBlack ); CG_DrawTopBottom( x-5, y-1, width+5, 18, 1 ); trap_R_SetColor( NULL ); // draw player info headings CG_DrawSmallString( tempx, y, CG_TranslateString( "Name" ), fade ); tempx += INFO_PLAYER_WIDTH; CG_DrawSmallString( tempx, y, CG_TranslateString( "Class" ), fade ); tempx += INFO_CLASS_WIDTH; if( cgs.gametype == GT_WOLF_LMS ) { CG_DrawSmallString( tempx, y, CG_TranslateString( "Score" ), fade ); tempx += INFO_SCORE_WIDTH; } else { CG_DrawSmallString( tempx + 1 * SMALLCHAR_WIDTH, y, CG_TranslateString( "XP" ), fade ); tempx += INFO_XP_WIDTH; } CG_DrawSmallString( tempx, y, CG_TranslateString( "Ping" ), fade ); tempx += INFO_LATENCY_WIDTH; if( cgs.gametype != GT_WOLF_LMS ) { CG_DrawPicST( tempx + 2, y, INFO_LIVES_WIDTH - 4, 16, 0.f, 0.f, 0.5f, 1.f, team == TEAM_ALLIES ? cgs.media.hudAlliedHelmet : cgs.media.hudAxisHelmet ); tempx += INFO_LIVES_WIDTH; } y += SMALLCHAR_HEIGHT; // draw player info VectorSet( hcolor, 1, 1, 1 ); hcolor[3] = fade; cg.teamPlayers[team] = 0; // JPW NERVE for ( i = 0; i < cg.numScores; i++ ) { if ( team != cgs.clientinfo[ cg.scores[i].client ].team ) continue; cg.teamPlayers[team]++; } count = 0; for( i = 0; i < cg.numScores && count < maxrows; i++ ) { if( team != cgs.clientinfo[ cg.scores[i].client ].team ) { continue; } if( cg.teamPlayers[team] > maxrows ) { WM_DrawClientScore_Small( x, y, &cg.scores[i], hcolor, fade ); y += MINICHAR_HEIGHT; } else { WM_DrawClientScore( x, y, &cg.scores[i], hcolor, fade ); y += SMALLCHAR_HEIGHT; } count++; } // draw spectators y += SMALLCHAR_HEIGHT; for ( i = 0; i < cg.numScores; i++ ) { if ( cgs.clientinfo[ cg.scores[i].client ].team != TEAM_SPECTATOR ) continue; if ( team == TEAM_AXIS && ( i % 2 ) ) continue; if ( team == TEAM_ALLIES && ( ( i + 1 ) % 2 ) ) continue; WM_DrawClientScore( x, y, &cg.scores[i], hcolor, fade ); y += SMALLCHAR_HEIGHT; } return y; }
// CHRUKER: b035 - Added absolute maximum rows static int WM_TeamScoreboard(int x, int y, team_t team, float fade, int maxrows, int absmaxrows) { vec4_t hcolor; float tempx, tempy; int height, width; int i; int count = 0; qboolean use_mini_chars = qfalse; // CHRUKER: b035 - Needed to check if using mini chars vec4_t tclr = { 0.6f, 0.6f, 0.6f, 1.0f }; height = SMALLCHAR_HEIGHT * maxrows; width = INFO_PLAYER_WIDTH + INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH; CG_FillRect(x - 5, y - 2, width + 5, 21, clrUiBack); CG_FillRect(x - 5, y - 2, width + 5, 21, clrUiBar); Vector4Set(hcolor, 0, 0, 0, fade); CG_DrawRect_FixedBorder(x - 5, y - 2, width + 5, 21, 1, colorBlack); // draw header if(cg_gameType.integer == GT_WOLF_LMS) { char *s; if(team == TEAM_AXIS) { s = va("%s [%d] (%d %s)", CG_TranslateString("AXIS"), cg.teamScores[0], cg.teamPlayers[team], CG_TranslateString("PLAYERS")); s = va("%s ^3%s", s, cg.teamFirstBlood == TEAM_AXIS ? CG_TranslateString("FIRST BLOOD") : ""); CG_Text_Paint_Ext(x, y + 13, 0.25f, 0.25f, tclr, s, 0, 0, 0, &cgs.media.limboFont1); } else if(team == TEAM_ALLIES) { s = va("%s [%d] (%d %s)", CG_TranslateString("ALLIES"), cg.teamScores[1], cg.teamPlayers[team], CG_TranslateString("PLAYERS")); s = va("%s ^3%s", s, cg.teamFirstBlood == TEAM_ALLIES ? CG_TranslateString("FIRST BLOOD") : ""); CG_Text_Paint_Ext(x, y + 13, 0.25f, 0.25f, tclr, s, 0, 0, 0, &cgs.media.limboFont1); } } else { if(team == TEAM_AXIS) { CG_Text_Paint_Ext(x, y + 13, 0.25f, 0.25f, tclr, va("%s [%d] (%d %s)", CG_TranslateString("AXIS"), cg.teamScores[0], cg.teamPlayers[team], CG_TranslateString("PLAYERS")), 0, 0, 0, &cgs.media.limboFont1); } else if(team == TEAM_ALLIES) { CG_Text_Paint_Ext(x, y + 13, 0.25f, 0.25f, tclr, va("%s [%d] (%d %s)", CG_TranslateString("ALLIES"), cg.teamScores[1], cg.teamPlayers[team], CG_TranslateString("PLAYERS")), 0, 0, 0, &cgs.media.limboFont1); } } y += SMALLCHAR_HEIGHT + 3; tempx = x; // CHRUKER: b076 - Adjusted y coordinate, and changed to use DrawBottom instead of DrawTopBottom CG_FillRect(x - 5, y, width + 5, 18, clrUiBack); trap_R_SetColor(colorBlack); CG_DrawBottom_NoScale(x - 5, y, width + 5, 18, 1); trap_R_SetColor(NULL); // draw player info headings CG_DrawSmallString(tempx, y, CG_TranslateString("Name"), fade); tempx += INFO_PLAYER_WIDTH; CG_DrawSmallString(tempx, y, CG_TranslateString("Class"), fade); tempx += INFO_CLASS_WIDTH; if(cgs.gametype == GT_WOLF_LMS) { CG_DrawSmallString(tempx, y, CG_TranslateString("Score"), fade); tempx += INFO_SCORE_WIDTH; } else { CG_DrawSmallString(tempx + 1 * SMALLCHAR_WIDTH, y, CG_TranslateString("XP"), fade); tempx += INFO_XP_WIDTH; } CG_DrawSmallString(tempx, y, CG_TranslateString("Ping"), fade); tempx += INFO_LATENCY_WIDTH; if(cgs.gametype != GT_WOLF_LMS) { CG_DrawPicST(tempx + 2, y, INFO_LIVES_WIDTH - 4, 16, 0.f, 0.f, 0.5f, 1.f, team == TEAM_ALLIES ? cgs.media.hudAlliedHelmet : cgs.media.hudAxisHelmet); tempx += INFO_LIVES_WIDTH; } // CHRUKER: b076 - The math says char height + 2 * border width (1 pixel) y += SMALLCHAR_HEIGHT + 2; cg.teamPlayers[team] = 0; // JPW NERVE for(i = 0; i < cg.numScores; i++) { if(team != cgs.clientinfo[cg.scores[i].client].team) { continue; } cg.teamPlayers[team]++; } // CHRUKER: b035 - Adjust maxrows if ( cg.teamPlayers[team] > maxrows ) { maxrows = absmaxrows; use_mini_chars = qtrue; } // save off y val tempy = y; // draw color bands for ( i = 0; i < maxrows; i++ ) { if ( i % 2 == 0 ) { VectorSet( hcolor, (80.f/255.f), (80.f/255.f), (80.f/255.f) ); // LIGHT BLUE } else { VectorSet( hcolor, (0.f/255.f), (0.f/255.f), (0.f/255.f) ); // DARK BLUE } hcolor[3] = fade * 0.3; if (use_mini_chars) { // CHRUKER: b076 - Adjusted y height, and changed to DrawBottom instead of DrawTopBottom CG_FillRect( x-5, y, width+5, MINICHAR_HEIGHT, hcolor ); trap_R_SetColor( colorBlack ); CG_DrawBottom_NoScale( x-5, y, width+5, MINICHAR_HEIGHT, 1 ); trap_R_SetColor( NULL ); y += MINICHAR_HEIGHT; } else { // CHRUKER: b076 - Adjusted y height, and changed to DrawBottom instead of DrawTopBottom CG_FillRect( x-5, y, width+5, SMALLCHAR_HEIGHT, hcolor ); trap_R_SetColor( colorBlack ); CG_DrawBottom_NoScale( x-5, y, width+5, SMALLCHAR_HEIGHT, 1 ); trap_R_SetColor( NULL ); y += SMALLCHAR_HEIGHT; } } hcolor[3] = 1; y = tempy; // draw player info VectorSet( hcolor, 1, 1, 1 ); hcolor[3] = fade; count = 0; for(i = 0; i < cg.numScores && count < maxrows; i++) { if(team != cgs.clientinfo[cg.scores[i].client].team) { continue; } // CHRUKER: b035 - Using the flag instead if(use_mini_chars) { WM_DrawClientScore_Small(x, y, &cg.scores[i], hcolor, fade); y += MINICHAR_HEIGHT; } else { WM_DrawClientScore(x, y, &cg.scores[i], hcolor, fade); y += SMALLCHAR_HEIGHT; } count++; } // draw spectators // CHRUKER: b035 - Missing support for mini char height scoreboard background if (use_mini_chars) { y += MINICHAR_HEIGHT; } else { y += SMALLCHAR_HEIGHT; } for(i = 0; i < cg.numScores; i++) { if(cgs.clientinfo[cg.scores[i].client].team != TEAM_SPECTATOR) { continue; } if(team == TEAM_AXIS && (i % 2)) { continue; } if(team == TEAM_ALLIES && ((i + 1) % 2)) { continue; } // CHRUKER: b034 - Missing support for minichars; b035 - Using the flag instead if(use_mini_chars) { WM_DrawClientScore_Small( x, y, &cg.scores[i], hcolor, fade ); y += MINICHAR_HEIGHT; } else { WM_DrawClientScore( x, y, &cg.scores[i], hcolor, fade ); y += SMALLCHAR_HEIGHT; } } return y; }
/* ================ Con_DrawSolidConsole Draws the console with the solid background ================ */ void Con_DrawSolidConsole( connstate_t state, float frac ) { int i; int x, y; int rows; char *text; int row; int lines; vec4_t color; if ( frac > 1 ) frac = 1; lines = cgs.glconfig.vidHeight * frac / cgs.screenYScale; if (lines <= 0) return; CG_SetScreenPlacement( PLACE_STRETCH, PLACE_STRETCH ); // draw the background y = frac * SCREEN_HEIGHT; if ( y < 1 ) { y = 0; } else { CG_DrawPic( 0, 0, SCREEN_WIDTH, y, cgs.media.consoleShader ); } color[0] = 1; color[1] = 0; color[2] = 0; color[3] = 1; CG_FillRect( 0, y, SCREEN_WIDTH, 2, color ); CG_SetScreenPlacement( PLACE_RIGHT, PLACE_TOP ); // draw the version number CG_DrawSmallStringColor( SCREEN_WIDTH - CG_DrawStrlen( con.version ) * SMALLCHAR_WIDTH, lines - SMALLCHAR_HEIGHT, con.version, color ); CG_SetScreenPlacement( PLACE_LEFT, PLACE_TOP ); // draw the text rows = (lines-SMALLCHAR_HEIGHT)/SMALLCHAR_HEIGHT; // rows of text to draw y = lines - (SMALLCHAR_HEIGHT*3); // draw from the bottom up if (con.display != con.current) { int linewidth = con.screenFakeWidth / SMALLCHAR_WIDTH; // draw arrows to show the buffer is backscrolled trap_R_SetColor( color ); for (x=0 ; x<linewidth ; x+=4) CG_DrawChar( (x+1)*SMALLCHAR_WIDTH, y, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, '^' ); y -= SMALLCHAR_HEIGHT; rows--; trap_R_SetColor( NULL ); } row = con.display; if ( con.x == 0 ) { row--; } for (i=0 ; i<rows ; i++, y -= SMALLCHAR_HEIGHT, row--) { if (row < 0) break; if (con.current - row >= CON_MAXLINES) { // past scrollback wrap point continue; } text = con.lines[row % CON_MAXLINES]; CG_DrawSmallString( con.sideMargin, y, text, 1.0f ); } // draw the input prompt, user text, and cursor if desired Con_DrawInput ( state, lines ); }
static void WM_DrawClientScore(int x, int y, score_t *score, float *color, float fade) { int maxchars, offset; int i, j; float tempx; vec4_t hcolor; clientInfo_t *ci; char buf[64]; if (y + SMALLCHAR_HEIGHT >= 470) { return; } ci = &cgs.clientinfo[score->client]; if (score->client == cg.snap->ps.clientNum) { hcolor[3] = fade * 0.3; VectorSet(hcolor, .5f, .5f, .2f); // DARK-RED CG_FillRect(x - 5, y, (INFO_TOTAL_WIDTH + 5), SMALLCHAR_HEIGHT - 1, hcolor); } tempx = x; VectorSet(hcolor, 1, 1, 1); hcolor[3] = fade; maxchars = 16; offset = 0; if (ci->team != TEAM_SPECTATOR) { /* FIXME: adjust x,y coordinates ... // draw ready icon if client is ready.. if (score->scoreflags & 1 && cgs.gamestate != GS_PLAYING) { CG_DrawPic(tempx - 3, y + 1, 14, 14, cgs.media.readyIcon); offset += 14; tempx += 14; maxchars -= 2; } */ if (ci->powerups & ((1 << PW_REDFLAG) | (1 << PW_BLUEFLAG))) { CG_DrawPic(tempx - 1, y + 1, 10, 10, cgs.media.objectiveShader); offset += 10; tempx += 10; maxchars -= 2; } // draw the skull icon if out of lives if (score->respawnsLeft == -2 || (cgs.clientinfo[cg.clientNum].team != TEAM_SPECTATOR && ci->team == cgs.clientinfo[cg.clientNum].team && cgs.clientinfo[score->client].health == -1)) { CG_DrawPic(tempx - 1, y + 1, 10, 10, cgs.media.scoreEliminatedShader); offset += 10; tempx += 10; maxchars -= 2; } else if (cgs.clientinfo[cg.clientNum].team != TEAM_SPECTATOR && ci->team == cgs.clientinfo[cg.clientNum].team && cgs.clientinfo[score->client].health == 0) { CG_DrawPic(tempx - 1, y + 1, 10, 10, cgs.media.medicIcon); offset += 10; tempx += 10; maxchars -= 2; } } // GeoIP - draw flag before name if (score->ping != -1 && score->ping != 999 && cg_countryflags.integer) { if (cf_draw(tempx - 11, y - 8, fade, ci->clientNum)) { offset += 14; tempx += 14; maxchars -= 2; } } // draw name CG_DrawStringExt(tempx, y, ci->name, hcolor, qfalse, qfalse, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, maxchars); maxchars -= CG_DrawStrlen(ci->name); // draw medals buf[0] = '\0'; for (i = 0; i < SK_NUM_SKILLS; i++) { for (j = 0; j < ci->medals[i]; j++) { Q_strcat(buf, sizeof(buf), va("^%c%c", COLOR_RED + i, skillNames[i][0])); } } maxchars--; // CG_DrawStringExt will draw everything if maxchars <= 0 if (maxchars > 0) { CG_DrawStringExt(tempx + (BG_drawStrlen(ci->name) * SMALLCHAR_WIDTH + SMALLCHAR_WIDTH), y, buf, hcolor, qfalse, qfalse, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, maxchars); } tempx += INFO_PLAYER_WIDTH - offset; if (ci->team == TEAM_SPECTATOR) { const char *s; int w, totalwidth = INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH - 8; // Show connecting people as CONNECTING if (score->ping == -1) { s = CG_TranslateString("^3CONNECTING"); } else { s = CG_TranslateString("^3SPECTATOR"); } w = CG_DrawStrlen(s) * SMALLCHAR_WIDTH; CG_DrawSmallString(tempx + totalwidth - w, y, s, fade); return; } // allow MV clients see the class of its merged client's on the scoreboard else if (cg.snap->ps.persistant[PERS_TEAM] == ci->team || cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR #if FEATURE_MULTIVIEW || CG_mvMergedClientLocate(score->client) #endif ) { CG_DrawPic(tempx - 3, y + 1, 14, 14, cgs.media.skillPics[SkillNumForClass(ci->cls)]); } tempx += INFO_CLASS_WIDTH; CG_DrawSmallString(tempx, y, va("%3i", score->score), fade); if (cg_gameType.integer == GT_WOLF_LMS) { tempx += INFO_SCORE_WIDTH; } else { tempx += INFO_XP_WIDTH; } if (score->ping == -1) { CG_DrawSmallString(tempx, y, "^1CONN^7", fade); } else if (score->scoreflags & 2) { CG_DrawSmallString(tempx, y, " BOT", fade); } else { CG_DrawSmallString(tempx, y, va("%4i", score->ping), fade); } tempx += INFO_LATENCY_WIDTH; if (cg_gameType.integer != GT_WOLF_LMS) { if (score->respawnsLeft >= 0) { CG_DrawSmallString(tempx, y, va("%2i", score->respawnsLeft), fade); } else { CG_DrawSmallString(tempx, y, " -", fade); } } }