/* ================== MenuField_Init ================== */ void MenuField_Init( menufield_s* m ) { int l; int w; int h; int style; MField_Clear( &m->field ); if (m->generic.flags & QMF_SMALLFONT) { w = SMALLCHAR_WIDTH; h = SMALLCHAR_HEIGHT; style = UI_SMALLFONT; } else { w = BIGCHAR_WIDTH; h = BIGCHAR_HEIGHT; style = UI_BIGFONT; } l = CG_DrawStrlen( m->generic.name, style ) + w; m->generic.left = m->generic.x - l; m->generic.top = m->generic.y; m->generic.right = m->generic.x + w + m->field.widthInChars*w; m->generic.bottom = m->generic.y + h; }
void CG_demoTimescaleDraw( void ) { if ( cg.demoPlayback && cgs.timescaleUpdate > cg.time && demo_drawTimeScale.integer != 0 ) { char *s = va( "^3TimeScale: ^7%.1f", cg_timescale.value ); int w = CG_DrawStrlen( s ) * SMALLCHAR_WIDTH; CG_FillRect( 42 - 2, 400, w + 5, SMALLCHAR_HEIGHT + 3, colorDkGreen ); CG_DrawRect( 42 - 2, 400, w + 5, SMALLCHAR_HEIGHT + 3, 1, colorMdYellow ); CG_DrawStringExt( 42, 400, s, colorWhite, qfalse, qtrue, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, 0 ); } }
/* ================= Slider_Init ================= */ static void Slider_Init( menuslider_s *s ) { int len; // calculate bounds len = CG_DrawStrlen( s->generic.name, UI_SMALLFONT ); s->generic.left = s->generic.x - len - SMALLCHAR_WIDTH; s->generic.right = s->generic.x + (SLIDER_RANGE+2+1)*SMALLCHAR_WIDTH; s->generic.top = s->generic.y; s->generic.bottom = s->generic.y + SMALLCHAR_HEIGHT; }
/* ================= RadioButton_Init ================= */ static void RadioButton_Init( menuradiobutton_s *rb ) { int len; // calculate bounds len = CG_DrawStrlen( rb->generic.name, UI_SMALLFONT ); rb->generic.left = rb->generic.x - len - SMALLCHAR_WIDTH; rb->generic.right = rb->generic.x + 6*SMALLCHAR_WIDTH; rb->generic.top = rb->generic.y; rb->generic.bottom = rb->generic.y + SMALLCHAR_HEIGHT; }
/* ================= SpinControl_Init ================= */ static void SpinControl_Init( menulist_s *s ) { int len; int l; const char* str; #ifdef IOQ3ZTM qboolean foundItem = qfalse; #endif len = CG_DrawStrlen( s->generic.name, UI_SMALLFONT ); #ifdef IOQ3ZTM if (s->generic.flags & QMF_LEFT_JUSTIFY) { s->generic.left = s->generic.x; s->generic.x += len + SMALLCHAR_WIDTH; } else #endif s->generic.left = s->generic.x - SMALLCHAR_WIDTH - len; len = s->numitems = 0; while ( (str = s->itemnames[s->numitems]) != 0 ) { l = CG_DrawStrlen( str, UI_SMALLFONT ); if (l > len) len = l; #ifdef IOQ3ZTM // Use first non-empty item. if (!foundItem && strlen(s->itemnames[s->numitems]) > 0) { s->curvalue = s->numitems; foundItem = qtrue; } #endif s->numitems++; } s->generic.top = s->generic.y; s->generic.right = s->generic.x + len + SMALLCHAR_WIDTH; s->generic.bottom = s->generic.y + SMALLCHAR_HEIGHT; }
/* ================ CG_CenterGiantLine ================ */ static void CG_CenterGiantLine( float y, const char *string ) { float x; /* vec4_t color; color[0] = 1; color[1] = 1; color[2] = 1; color[3] = 1; */ x = ( SCREEN_WIDTH - GIANT_WIDTH * CG_DrawStrlen(string) )/2; CG_DrawStringExt( x, y, string, colorWhite, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0, SCR_CENTER ); }
/* ================ CG_CenterGiantLine ================ */ static void CG_CenterGiantLine( gfixed y, const char *string ) { gfixed x; vec4_t color; color[0] = GFIXED_1; color[1] = GFIXED_1; color[2] = GFIXED_1; color[3] = GFIXED_1; x = GFIXED(0,5) * MAKE_GFIXED( 640 - GIANT_WIDTH * CG_DrawStrlen( string ) ); CG_DrawStringExt( FIXED_TO_INT(x), FIXED_TO_INT(y), string, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 ); }
/* ======================================================================================================================================= CG_CenterGiantLine ======================================================================================================================================= */ static void CG_CenterGiantLine(float y, const char *string) { float x; vec4_t color; color[0] = 1; color[1] = 1; color[2] = 1; color[3] = 1; x = 0.5 * (640 - GIANT_WIDTH * CG_DrawStrlen(string)); CG_DrawStringExt(x, y, string, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0); }
/* ================= Action_Init ================= */ static void Action_Init( menuaction_s *a ) { int len; // calculate bounds len = CG_DrawStrlen( a->generic.name, UI_BIGFONT ); // left justify text a->generic.left = a->generic.x; a->generic.right = a->generic.x + len; a->generic.top = a->generic.y; a->generic.bottom = a->generic.y + BIGCHAR_HEIGHT; }
/* ================= SpinControl_Init ================= */ static void SpinControl_Init( menulist_s *s ) { int len; int l; const char* str; len = CG_DrawStrlen( s->generic.name, UI_SMALLFONT ); s->generic.left = s->generic.x - SMALLCHAR_WIDTH - len; len = s->numitems = 0; while ( (str = s->itemnames[s->numitems]) != 0 ) { l = CG_DrawStrlen( str, UI_SMALLFONT ); if (l > len) len = l; s->numitems++; } s->generic.top = s->generic.y; s->generic.right = s->generic.x + len + SMALLCHAR_WIDTH; s->generic.bottom = s->generic.y + SMALLCHAR_HEIGHT; }
// Set the window width and height based on the windows text/font parameters void CG_windowNormalizeOnText( cg_window_t *w ) { int i, tmp; if ( w == NULL ) { return; } w->w = 0; w->h = 0; if ( !( w->effects & WFX_TRUETYPE ) ) { w->fontWidth = w->fontScaleX * WINDOW_FONTWIDTH; w->fontHeight = w->fontScaleY * WINDOW_FONTHEIGHT; } for ( i = 0; i < w->lineCount; i++ ) { if ( w->effects & WFX_TRUETYPE ) { tmp = CG_Text_Width_Ext( (char*)w->lineText[i], w->fontScaleX, 0, &cgs.media.limboFont2 ); } else { tmp = CG_DrawStrlen( (char*)w->lineText[i] ) * w->fontWidth; } if ( tmp > w->w ) { w->w = tmp; } } for ( i = 0; i < w->lineCount; i++ ) { if ( w->effects & WFX_TRUETYPE ) { w->lineHeight[i] = CG_Text_Height_Ext( (char*)w->lineText[i], w->fontScaleY, 0, &cgs.media.limboFont2 ); } else { w->lineHeight[i] = w->fontHeight; } w->h += w->lineHeight[i] + 3; } // Border + margins w->w += 10; w->h += 3; // Set up bottom alignment if ( w->x < 0 ) { w->x += 640 - w->w; } if ( w->y < 0 ) { w->y += 480 - w->h; } }
float UI_UtilsCG::drawTimer( float y ) { char *s; int dx = 0, dy = 0, w = 0; int mins, seconds, tens; int msec; // calc milliseconds msec = cg.time - cgs.levelStartTime; // convert msec to time components seconds = msec / 1000; mins = seconds / 60; seconds -= mins * 60; tens = seconds / 10; seconds -= tens * 10; s = va( "%i:%i%i", mins, tens, seconds ); w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH; // alter the draw position? if( CG_NewHUDActive() ) { // fit around the New HUD (draw bottom middle-right) dx = 480; dy = 460; } else { // draw top right dx = 604; dy = y + 8; } // draw the timer background (TODO: possibly replace this with HUD when near/in the HUD) dc_->fillRect( dx-(k_TIMER_WIDTH/2), dy-4, k_TIMER_WIDTH, k_TIMER_HEIGHT, *createColourVector( 0,0.5f,0,0.75f,NULL ) ); dc_->drawRect( dx-(k_TIMER_WIDTH/2), dy-4, k_TIMER_WIDTH, k_TIMER_HEIGHT, 1, *createColourVector( 0,0,0,1.0f,NULL ) ); // draw timer string drawStringNew( dx, dy, 0.35f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_SHADOWED, CENTRE_JUSTIFY ); return y + k_TIMER_HEIGHT + 4; }
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; }
/* ================= RadioButton_Init ================= */ static void RadioButton_Init( menuradiobutton_s *rb ) { int len; // calculate bounds len = CG_DrawStrlen( rb->generic.name, UI_SMALLFONT ); #ifdef IOQ3ZTM if (rb->generic.flags & QMF_LEFT_JUSTIFY) { rb->generic.left = rb->generic.x; rb->generic.x += len + SMALLCHAR_WIDTH; } else #endif { rb->generic.left = rb->generic.x - len - SMALLCHAR_WIDTH; } rb->generic.right = rb->generic.x + 6*SMALLCHAR_WIDTH; rb->generic.top = rb->generic.y; rb->generic.bottom = rb->generic.y + SMALLCHAR_HEIGHT; }
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 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_Small(int x, int y, score_t * score, float *color, float fade) { int maxchars, offset; float tempx; vec4_t hcolor; clientInfo_t *ci; // CHRUKER: b033 - Added to draw medals int i, j; char buf[64]; if(y + MINICHAR_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), MINICHAR_HEIGHT - 1, hcolor ); } tempx = x; // DHM - Nerve VectorSet(hcolor, 1, 1, 1); hcolor[3] = fade; // CHRUKER: b033 - Corrected to draw medals maxchars = 16; offset = 0; if(ci->team != TEAM_SPECTATOR) { if(ci->powerups & ((1 << PW_REDFLAG) | (1 << PW_BLUEFLAG))) { // CHRUKER: b071 - Objective carrier icon missing on compact scoreboard // CHRUKER: b078 - Medic, death and objective icons on the scoreboard are drawn too big 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)) { // CHRUKER: b078 - Medic, death and objective icons on the scoreboard are drawn too big 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) { // CHRUKER: b078 - Medic, death and objective icons on the scoreboard are drawn too big CG_DrawPic( tempx - 1, y + 1, 10, 10, cgs.media.medicIcon ); offset += 10; tempx += 10; maxchars -= 2; } } // draw name CG_DrawStringExt(tempx, y, ci->name, hcolor, qfalse, qfalse, MINICHAR_WIDTH, MINICHAR_HEIGHT, maxchars); // CHRUKER: b033 - Added to draw medals maxchars -= CG_DrawStrlen( ci->name ); 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--; if (maxchars > 0) CG_DrawStringExt( tempx + (BG_drawStrlen(ci->name) * MINICHAR_WIDTH + MINICHAR_WIDTH), y, buf, hcolor, qfalse, qfalse, MINICHAR_WIDTH, MINICHAR_HEIGHT, maxchars ); // b033 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; // CHRUKER: b031 - Show connecting people as connecting if (score->ping == -1) { s = CG_TranslateString( "^1CONNECTING" ); } else { s = CG_TranslateString( "^3SPECTATOR" ); } w = CG_DrawStrlen(s) * MINICHAR_WIDTH; // CHRUKER: b034 - Using the mini char height CG_DrawStringExt( tempx + totalwidth - w, y, s, hcolor, qfalse, qfalse, MINICHAR_WIDTH, MINICHAR_HEIGHT, 0 ); 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, " -", hcolor, qfalse, qfalse, MINICHAR_WIDTH, MINICHAR_HEIGHT, 0); } tempx += INFO_LIVES_WIDTH; } }
/* ================= CG_DrawScoreboard Draw the normal in-game scoreboard ================= */ qboolean CG_DrawOldScoreboard( void ) { int x, y, w, i, n1, n2; float fade; float *fadeColor; char *s; int maxClients; int lineHeight; int topBorderSize, bottomBorderSize; // don't draw amuthing if the menu or console is up if ( cg_paused.integer ) { cg.deferredPlayerLoading = 0; return qfalse; } // don't draw scoreboard during death while warmup up if ( cg.warmup && !cg.showScores ) { return qfalse; } if ( cg.showScores || cg.predictedPlayerState.pm_type == PM_DEAD || cg.predictedPlayerState.pm_type == PM_INTERMISSION ) { fade = 1.0; fadeColor = colorWhite; } else { fadeColor = CG_FadeColor( cg.scoreFadeTime, FADE_TIME ); if ( !fadeColor ) { // next time scoreboard comes up, don't print killer cg.deferredPlayerLoading = 0; cg.killerName[0] = 0; return qfalse; } fade = *fadeColor; } // fragged by ... line // or if in intermission and duel, prints the winner of the duel round if (cgs.gametype == GT_TOURNAMENT && cgs.duelWinner != -1 && cg.predictedPlayerState.pm_type == PM_INTERMISSION) { s = va("%s %s", cgs.clientinfo[cgs.duelWinner].name, CG_GetStripEdString("INGAMETEXT", "DUEL_WINS") ); /*w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH; x = ( SCREEN_WIDTH - w ) / 2; y = 40; CG_DrawBigString( x, y, s, fade ); */ x = ( SCREEN_WIDTH ) / 2; y = 40; CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM ); } else if (cgs.gametype == GT_TOURNAMENT && cgs.duelist1 != -1 && cgs.duelist2 != -1 && cg.predictedPlayerState.pm_type == PM_INTERMISSION) { s = va("%s %s %s", cgs.clientinfo[cgs.duelist1].name, CG_GetStripEdString("INGAMETEXT", "SPECHUD_VERSUS"), cgs.clientinfo[cgs.duelist2].name ); /*w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH; x = ( SCREEN_WIDTH - w ) / 2; y = 40; CG_DrawBigString( x, y, s, fade ); */ x = ( SCREEN_WIDTH ) / 2; y = 40; CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM ); } else if ( cg.killerName[0] ) { s = va("%s %s", CG_GetStripEdString("INGAMETEXT", "KILLEDBY"), cg.killerName ); /*w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH; x = ( SCREEN_WIDTH - w ) / 2; y = 40; CG_DrawBigString( x, y, s, fade ); */ x = ( SCREEN_WIDTH ) / 2; y = 40; CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM ); } // current rank if ( !GT_Team(cgs.gametype)) { if (cg.snap->ps.persistant[PERS_TEAM] != TEAM_SPECTATOR ) { char sPlace[256]; char sOf[256]; char sWith[256]; trap_SP_GetStringTextString("INGAMETEXT_PLACE", sPlace, sizeof(sPlace)); trap_SP_GetStringTextString("INGAMETEXT_OF", sOf, sizeof(sOf)); trap_SP_GetStringTextString("INGAMETEXT_WITH", sWith, sizeof(sWith)); s = va("%s %s (%s %i) %s %i", CG_PlaceString( cg.snap->ps.persistant[PERS_RANK] + 1 ), sPlace, sOf, cg.numScores, sWith, cg.snap->ps.persistant[PERS_SCORE] ); w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH; x = ( SCREEN_WIDTH ) / 2; y = 60; //CG_DrawBigString( x, y, s, fade ); UI_DrawProportionalString(x, y, s, UI_CENTER|UI_DROPSHADOW, colorTable[CT_WHITE]); } } else { if ( cg.teamScores[0] == cg.teamScores[1] ) { s = va("Teams are tied at %i", cg.teamScores[0] ); } else if ( cg.teamScores[0] >= cg.teamScores[1] ) { s = va("Red leads %i to %i",cg.teamScores[0], cg.teamScores[1] ); } else { s = va("Blue leads %i to %i",cg.teamScores[1], cg.teamScores[0] ); } x = ( SCREEN_WIDTH ) / 2; y = 60; CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM ); } // scoreboard y = SB_HEADER; CG_DrawPic ( SB_SCORELINE_X - 40, y - 5, SB_SCORELINE_WIDTH + 80, 40, trap_R_RegisterShaderNoMip ( "gfx/menus/menu_buttonback.tga" ) ); // "NAME", "SCORE", "PING", "TIME" weren't localised, GODDAMMIT!!!!!!!! // // Unfortunately, since it's so sodding late now and post release I can't enable the localisation code (REM'd) since some of // the localised strings don't fit - since no-one's ever seen them to notice this. Smegging brilliant. Thanks people. // CG_Text_Paint ( SB_NAME_X, y, 1.0f, colorWhite, /*CG_GetStripEdString("MENUS3", "NAME")*/"Name",0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM ); if (cgs.gametype == GT_TOURNAMENT) { char sWL[100]; trap_SP_GetStringTextString("INGAMETEXT_W_L", sWL, sizeof(sWL)); CG_Text_Paint ( SB_SCORE_X, y, 1.0f, colorWhite, sWL, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM ); } else { CG_Text_Paint ( SB_SCORE_X, y, 1.0f, colorWhite, /*CG_GetStripEdString("MENUS3", "SCORE")*/"Score", 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM ); } CG_Text_Paint ( SB_PING_X, y, 1.0f, colorWhite, /*CG_GetStripEdString("MENUS0", "PING")*/"Ping", 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM ); CG_Text_Paint ( SB_TIME_X, y, 1.0f, colorWhite, /*CG_GetStripEdString("MENUS3", "TIME")*/"Time", 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM ); y = SB_TOP; // If there are more than SB_MAXCLIENTS_NORMAL, use the interleaved scores if ( cg.numScores > SB_MAXCLIENTS_NORMAL ) { maxClients = SB_MAXCLIENTS_INTER; lineHeight = SB_INTER_HEIGHT; topBorderSize = 8; bottomBorderSize = 16; } else { maxClients = SB_MAXCLIENTS_NORMAL; lineHeight = SB_NORMAL_HEIGHT; topBorderSize = 8; bottomBorderSize = 8; } localClient = qfalse; //I guess this should end up being able to display 19 clients at once. //In a team game, if there are 9 or more clients on the team not in the lead, //we only want to show 10 of the clients on the team in the lead, so that we //have room to display the clients in the lead on the losing team. //I guess this can be accomplished simply by printing the first teams score with a maxClients //value passed in related to how many players are on both teams. if ( GT_Team(cgs.gametype) ) { // // teamplay scoreboard // y += lineHeight/2; if ( cg.teamScores[0] >= cg.teamScores[1] ) { int team1MaxCl = CG_GetTeamCount(TEAM_RED, maxClients); int team2MaxCl = CG_GetTeamCount(TEAM_BLUE, maxClients); if (team1MaxCl > 10 && (team1MaxCl+team2MaxCl) > maxClients) { team1MaxCl -= team2MaxCl; //subtract as many as you have to down to 10, once we get there //we just set it to 10 if (team1MaxCl < 10) { team1MaxCl = 10; } } team2MaxCl = (maxClients-team1MaxCl); //team2 can display however many is left over after team1's display n1 = CG_TeamScoreboard( y, TEAM_RED, fade, team1MaxCl, lineHeight, qtrue ); CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED ); CG_TeamScoreboard( y, TEAM_RED, fade, team1MaxCl, lineHeight, qfalse ); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; //maxClients -= n1; n2 = CG_TeamScoreboard( y, TEAM_BLUE, fade, team2MaxCl, lineHeight, qtrue ); CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE ); CG_TeamScoreboard( y, TEAM_BLUE, fade, team2MaxCl, lineHeight, qfalse ); y += (n2 * lineHeight) + BIGCHAR_HEIGHT; //maxClients -= n2; maxClients -= (team1MaxCl+team2MaxCl); } else { int team1MaxCl = CG_GetTeamCount(TEAM_BLUE, maxClients); int team2MaxCl = CG_GetTeamCount(TEAM_RED, maxClients); if (team1MaxCl > 10 && (team1MaxCl+team2MaxCl) > maxClients) { team1MaxCl -= team2MaxCl; //subtract as many as you have to down to 10, once we get there //we just set it to 10 if (team1MaxCl < 10) { team1MaxCl = 10; } } team2MaxCl = (maxClients-team1MaxCl); //team2 can display however many is left over after team1's display n1 = CG_TeamScoreboard( y, TEAM_BLUE, fade, team1MaxCl, lineHeight, qtrue ); CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE ); CG_TeamScoreboard( y, TEAM_BLUE, fade, team1MaxCl, lineHeight, qfalse ); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; //maxClients -= n1; n2 = CG_TeamScoreboard( y, TEAM_RED, fade, team2MaxCl, lineHeight, qtrue ); CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED ); CG_TeamScoreboard( y, TEAM_RED, fade, team2MaxCl, lineHeight, qfalse ); y += (n2 * lineHeight) + BIGCHAR_HEIGHT; //maxClients -= n2; maxClients -= (team1MaxCl+team2MaxCl); } n1 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients, lineHeight, qfalse ); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; } else { // // free for all scoreboard // n1 = CG_TeamScoreboard( y, TEAM_FREE, fade, maxClients, lineHeight, qfalse ); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; n2 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients - n1, lineHeight, qfalse ); y += (n2 * lineHeight) + BIGCHAR_HEIGHT; } if (!localClient) { // draw local client at the bottom for ( i = 0 ; i < cg.numScores ; i++ ) { if ( cg.scores[i].client == cg.snap->ps.clientNum ) { CG_DrawClientScore( y, &cg.scores[i], fadeColor, fade, lineHeight == SB_NORMAL_HEIGHT ); break; } } } // load any models that have been deferred if ( ++cg.deferredPlayerLoading > 10 ) { CG_LoadDeferredPlayers(); } return qtrue; }
float UI_UtilsCG::drawCountdownTimer( float y ) { char *s; int dx = 0, dy = 0, w = 0; int mins, seconds, tens; int msec; bool flash = false; // no need for the countdown timer? if( cgs.timelimit == 0 ) { return y; } // calc milliseconds msec = (cgs.timelimit * 60 * 1000) - (cg.time - cgs.levelStartTime) + 1000; // the +1000 is just a correction offset // rubbish msec value? (i.e. negative) if( msec < 0 ) msec = 0; // convert msec to time components seconds = msec / 1000; mins = seconds / 60; seconds -= mins * 60; tens = seconds / 10; seconds -= tens * 10; // flashing countdown? (within last minute of play) if( msec <= (60*1000) && (msec & 0x100) ) { flash = true; } s = va( "%i:%i%i", mins, tens, seconds ); w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH; // alter the draw position? if( CG_NewHUDActive() ) { // fit around the New HUD (draw bottom middle-left) dx = 160; dy = 460; } else { // draw top right dx = 604; dy = y + 8; } // draw the timer background (TODO: possibly replace this with HUD when near/in the HUD) dc_->fillRect( dx-(k_TIMER_WIDTH/2), dy-4, k_TIMER_WIDTH, k_TIMER_HEIGHT, *createColourVector( 0.7f,0,0,0.75f,NULL ) ); dc_->drawRect( dx-(k_TIMER_WIDTH/2), dy-4, k_TIMER_WIDTH, k_TIMER_HEIGHT, 1, *createColourVector( 0,0,0,1.0f,NULL ) ); // draw timer string if( !flash ) { drawStringNew( dx, dy, 0.35f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_SHADOWED, CENTRE_JUSTIFY ); } return y + k_TIMER_HEIGHT + 4; }
/* ======================================================================================================================================= CG_DrawOldScoreboard Draw the normal in-game scoreboard. ======================================================================================================================================= */ qboolean CG_DrawOldScoreboard(void) { int x, y, w, i, n1, n2; float fade; float *fadeColor; char *s; int maxClients; int lineHeight; int topBorderSize, bottomBorderSize; // don't draw amuthing if the menu or console is up if (cg_paused.integer) { cg.deferredPlayerLoading = 0; return qfalse; } if (cgs.gametype == GT_SINGLE_PLAYER && cg.predictedPlayerState.pm_type == PM_INTERMISSION) { cg.deferredPlayerLoading = 0; return qfalse; } // don't draw scoreboard during death while warmup up if (cg.warmup && !cg.showScores) { return qfalse; } if (cg.showScores || cg.predictedPlayerState.pm_type == PM_DEAD || cg.predictedPlayerState.pm_type == PM_INTERMISSION) { fade = 1.0; fadeColor = colorWhite; } else { fadeColor = CG_FadeColor(cg.scoreFadeTime, FADE_TIME); if (!fadeColor) { // next time scoreboard comes up, don't print killer cg.deferredPlayerLoading = 0; cg.killerName[0] = 0; return qfalse; } fade = *fadeColor; } // fragged by ... line if (cg.killerName[0]) { s = va("Fragged by %s", cg.killerName); w = CG_DrawStrlen(s) * BIGCHAR_WIDTH; x = (SCREEN_WIDTH - w) / 2; y = 40; CG_DrawBigString(x, y, s, fade); } // current rank if (cgs.gametype < GT_TEAM) { if (cg.snap->ps.persistant[PERS_TEAM] != TEAM_SPECTATOR) { s = va("%s place with %i", CG_PlaceString(cg.snap->ps.persistant[PERS_RANK] + 1), cg.snap->ps.persistant[PERS_SCORE]); w = CG_DrawStrlen(s) * BIGCHAR_WIDTH; x = (SCREEN_WIDTH - w) / 2; y = 60; CG_DrawBigString(x, y, s, fade); } } else { if (cg.teamScores[0] == cg.teamScores[1]) { s = va("Teams are tied at %i", cg.teamScores[0]); } else if (cg.teamScores[0] >= cg.teamScores[1]) { s = va("Red leads %i to %i", cg.teamScores[0], cg.teamScores[1]); } else { s = va("Blue leads %i to %i", cg.teamScores[1], cg.teamScores[0]); } w = CG_DrawStrlen(s) * BIGCHAR_WIDTH; x = (SCREEN_WIDTH - w) / 2; y = 60; CG_DrawBigString(x, y, s, fade); } // scoreboard y = SB_HEADER; CG_DrawPic(SB_SCORE_X + (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardScore); CG_DrawPic(SB_PING_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardPing); CG_DrawPic(SB_TIME_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardTime); CG_DrawPic(SB_NAME_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardName); y = SB_TOP; // If there are more than SB_MAXCLIENTS_NORMAL, use the interleaved scores if (cg.numScores > SB_MAXCLIENTS_NORMAL) { maxClients = SB_MAXCLIENTS_INTER; lineHeight = SB_INTER_HEIGHT; topBorderSize = 8; bottomBorderSize = 16; } else { maxClients = SB_MAXCLIENTS_NORMAL; lineHeight = SB_NORMAL_HEIGHT; topBorderSize = 16; bottomBorderSize = 16; } localClient = qfalse; if (cgs.gametype >= GT_TEAM) { // teamplay scoreboard y += lineHeight / 2; if (cg.teamScores[0] >= cg.teamScores[1]) { n1 = CG_TeamScoreboard(y, TEAM_RED, fade, maxClients, lineHeight); CG_DrawTeamBackground(0, y - topBorderSize, 640, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; maxClients -= n1; n2 = CG_TeamScoreboard(y, TEAM_BLUE, fade, maxClients, lineHeight); CG_DrawTeamBackground(0, y - topBorderSize, 640, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE); y += (n2 * lineHeight) + BIGCHAR_HEIGHT; maxClients -= n2; } else { n1 = CG_TeamScoreboard(y, TEAM_BLUE, fade, maxClients, lineHeight); CG_DrawTeamBackground(0, y - topBorderSize, 640, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; maxClients -= n1; n2 = CG_TeamScoreboard(y, TEAM_RED, fade, maxClients, lineHeight); CG_DrawTeamBackground(0, y - topBorderSize, 640, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED); y += (n2 * lineHeight) + BIGCHAR_HEIGHT; maxClients -= n2; } n1 = CG_TeamScoreboard(y, TEAM_SPECTATOR, fade, maxClients, lineHeight); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; } else { // free for all scoreboard n1 = CG_TeamScoreboard(y, TEAM_FREE, fade, maxClients, lineHeight); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; n2 = CG_TeamScoreboard(y, TEAM_SPECTATOR, fade, maxClients - n1, lineHeight); y += (n2 * lineHeight) + BIGCHAR_HEIGHT; } if (!localClient) { // draw local client at the bottom for (i = 0; i < cg.numScores; i++) { if (cg.scores[i].client == cg.snap->ps.clientNum) { CG_DrawClientScore(y, &cg.scores[i], fadeColor, fade, lineHeight == SB_NORMAL_HEIGHT); break; } } } // load any models that have been deferred if (++cg.deferredPlayerLoading > 10) { CG_LoadDeferredPlayers(); } return qtrue; }
/* ================ 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 ); }
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_ConsolePrint ================ */ void CG_ConsolePrint( const char *p ) { int lineDrawLen, wordDrawLen, charDrawLen; int wordLen; int i; while ( *p != '\0' ) { if ( *p == '\r' ) { con.x = 0; p++; continue; } else if ( *p == '\n' ) { Con_LineFeed( qfalse ); p++; continue; } lineDrawLen = CG_DrawStrlen( con.lines[con.current % CON_MAXLINES] ) * SMALLCHAR_WIDTH; wordDrawLen = charDrawLen = 0; for ( i = 0; i < CON_LINELENGTH; i++ ) { if ( Q_IsColorString( &p[i] ) ) { continue; } if ( p[i] == '\0' || p[i] == '\r' || p[i] == '\n' || p[i] == ' ' ) { break; } // break string at slashes, but don't leave them trailing at end of line (stick to beginning of next word) if ( i > 0 && ( p[i] == '/' || p[i] == '\\' ) ) { break; } charDrawLen = CG_DrawStrlenEx( &p[i], 1 ) * SMALLCHAR_WIDTH; // make sure the word will fit on screen, even if it needs a whole line to do so. if ( wordDrawLen + charDrawLen > con.screenFakeWidth - ( con.sideMargin * 2 ) ) { break; } wordDrawLen += charDrawLen; } // if *p is a word separator or word is too long, just copy one char at a time if ( i == 0 || i == CON_LINELENGTH ) { wordLen = 1; } else { wordLen = i; } if ( con.x + wordLen > CON_LINELENGTH ) { Con_LineFeed( qtrue ); } else if ( lineDrawLen + wordDrawLen > con.screenFakeWidth - ( con.sideMargin * 2 ) ) { Con_LineFeed( qtrue ); } Q_strncpyz( &con.lines[con.current % CON_MAXLINES][con.x], p, wordLen+1 ); con.x += wordLen; p += wordLen; } }
/* ================= CG_DrawScoreboard Draw the normal in-game scoreboard ================= */ qboolean CG_DrawScoreboard( void ) { int x = 0, y = 0; float fade; float *fadeColor; char *s; // don't draw amuthing if the menu or console is up if ( cg_paused.integer ) { cg.deferredPlayerLoading = 0; return qfalse; } // don't draw scoreboard during death while warmup up if ( cg.warmup && !cg.showScores ) { return qfalse; } // NERVE - SMF - added mp wolf check if ( cg.showScores || ( cg.predictedPlayerState.pm_type == PM_DEAD && cgs.gametype < GT_WOLF ) || cg.predictedPlayerState.pm_type == PM_INTERMISSION ) { fade = 1.0; fadeColor = colorWhite; } else { fadeColor = CG_FadeColor( cg.scoreFadeTime, FADE_TIME ); if ( !fadeColor ) { // next time scoreboard comes up, don't print killer cg.deferredPlayerLoading = 0; cg.killerName[0] = 0; return qfalse; } fade = *fadeColor; } // fragged by ... line if ( cg.killerName[0] ) { int w; s = va( "Killed by %s", cg.killerName ); w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH; x = ( SCREEN_WIDTH - w ) / 2; y = 40; CG_DrawBigString( x, y, s, fade ); } // current rank // NERVE - SMF if ( cgs.gametype >= GT_WOLF ) { INFO_PLAYER_WIDTH = 140; INFO_SCORE_WIDTH = 50; INFO_CLASS_WIDTH = 50; INFO_LATENCY_WIDTH = 40; INFO_TEAM_HEIGHT = 24; INFO_BORDER = 2; INFO_TOTAL_WIDTH = INFO_PLAYER_WIDTH + INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH; x = 20; y = 10; WM_DrawObjectives( x, y, 595, fade ); if ( cgs.gametype == GT_WOLF_STOPWATCH && ( cg.snap->ps.pm_type == PM_INTERMISSION ) ) { y = WM_DrawInfoLine( x, 155, fade ); WM_TeamScoreboard( x, y, TEAM_RED, fade, 18 ); x = 335; WM_TeamScoreboard( x, y, TEAM_BLUE, fade, 18 ); } else { y = 155; WM_TeamScoreboard( x, y, TEAM_RED, fade, 20 ); x = 335; WM_TeamScoreboard( x, y, TEAM_BLUE, fade, 20 ); } } // -NERVE - SMF else if ( cgs.gametype >= GT_TEAM ) { // // teamplay scoreboard // if ( cg.teamScores[0] >= cg.teamScores[1] ) { y = CG_TeamScoreboard( x, y, TEAM_RED, fade ); y = CG_TeamScoreboard( x, y, TEAM_BLUE, fade ); } else { y = CG_TeamScoreboard( x, y, TEAM_BLUE, fade ); y = CG_TeamScoreboard( x, y, TEAM_RED, fade ); } y = CG_TeamScoreboard( x, y, TEAM_SPECTATOR, fade ); } else { //----(SA) modified // // free for all scoreboard // y = CG_TeamScoreboard( x, y, TEAM_FREE, fade ); y = CG_TeamScoreboard( x, y, TEAM_SPECTATOR, fade ); } // load any models that have been deferred if ( ++cg.deferredPlayerLoading > 1 ) { CG_LoadDeferredPlayers(); } return qtrue; }
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; }
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; } }
/* ================= CG_DrawOldScoreboard Draw the normal in-game scoreboard ================= */ qboolean CG_DrawOldScoreboard( void ) { int x, y, w, i, n1, n2; float fade; const float *fadeColor; const char *s; int maxClients; int lineHeight; int topBorderSize, bottomBorderSize; QLWideScreen = WIDESCREEN_CENTER; // don't draw amuthing if the menu or console is up if ( cg_paused.integer ) { cg.deferredPlayerLoading = 0; return qfalse; } if ( cgs.gametype == GT_SINGLE_PLAYER && cg.predictedPlayerState.pm_type == PM_INTERMISSION ) { cg.deferredPlayerLoading = 0; return qfalse; } // don't draw scoreboard during death while warmup up if ( cg.warmup && !cg.showScores ) { return qfalse; } if ( cg.showScores || cg.predictedPlayerState.pm_type == PM_DEAD || cg.predictedPlayerState.pm_type == PM_INTERMISSION ) { fade = 1.0; fadeColor = colorWhite; } else { fadeColor = CG_FadeColor( cg.scoreFadeTime, FADE_TIME ); if ( !fadeColor ) { // next time scoreboard comes up, don't print killer cg.deferredPlayerLoading = 0; cg.killerName[0] = 0; return qfalse; } fade = *fadeColor; } // fragged by ... line if ( cg.killerName[0] ) { s = va("Fragged by %s", cg.killerName ); w = CG_DrawStrlen( s, &cgs.media.bigchar ); x = ( SCREEN_WIDTH - w ) / 2; y = 40; CG_DrawBigString( x, y, s, fade ); } // current rank if (!CG_IsTeamGame(cgs.gametype)) { if (!wolfcam_following || (wolfcam_following && wcg.clientNum == cg.snap->ps.clientNum)) { if (cg.snap->ps.persistant[PERS_TEAM] != TEAM_SPECTATOR ) { s = va("%s place with %i", CG_PlaceString( cg.snap->ps.persistant[PERS_RANK] + 1 ), cg.snap->ps.persistant[PERS_SCORE] ); w = CG_DrawStrlen( s, &cgs.media.bigchar ); x = ( SCREEN_WIDTH - w ) / 2; y = 60; CG_DrawBigString( x, y, s, fade ); } } else { // wolfcam_following if (cgs.clientinfo[wcg.clientNum].team != TEAM_SPECTATOR) { if (CG_IsCpmaMvd()) { int rank; int i; rank = 1; for (i = 0; i < MAX_CLIENTS; i++) { if (!cgs.clientinfo[i].infoValid) { continue; } if (cgs.clientinfo[i].team == TEAM_SPECTATOR) { continue; } if (cgs.clientinfo[i].score > cgs.clientinfo[wcg.clientNum].score) { rank++; } } s = va("%s ^7place with %i", CG_PlaceString(rank), cgs.clientinfo[wcg.clientNum].score); w = CG_DrawStrlen( s, &cgs.media.bigchar ); x = ( SCREEN_WIDTH - w ) / 2; y = 60; CG_DrawBigString( x, y, s, fade ); } else { // not cpma mvd // following someone who is ingame but not the main demo view if (CG_IsDuelGame(cgs.gametype)) { // we are following the other dueler if (cgs.scores1 == cgs.scores2) { s = va("%s ^7place with %i", CG_PlaceString(1), cgs.scores1); } else { if (cg.snap->ps.persistant[PERS_RANK] == 0) { // we are second s = va("%s ^7place with %i", CG_PlaceString(2), cgs.scores2); } else { // we are first s = va("%s ^7place with %i", CG_PlaceString(1), cgs.scores1); } } w = CG_DrawStrlen( s, &cgs.media.bigchar ); x = ( SCREEN_WIDTH - w ) / 2; y = 60; CG_DrawBigString( x, y, s, fade ); } else { // we don't have enough information // pass, don't draw ranking } } } } } else { if ( cg.teamScores[0] == cg.teamScores[1] ) { s = va("Teams are tied at %i", cg.teamScores[0] ); } else if ( cg.teamScores[0] >= cg.teamScores[1] ) { s = va("Red leads %i to %i",cg.teamScores[0], cg.teamScores[1] ); } else { s = va("Blue leads %i to %i",cg.teamScores[1], cg.teamScores[0] ); } w = CG_DrawStrlen( s, &cgs.media.bigchar ); x = ( SCREEN_WIDTH - w ) / 2; y = 60; CG_DrawBigString( x, y, s, fade ); } // scoreboard y = SB_HEADER; CG_DrawPic( SB_SCORE_X + (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardScore ); CG_DrawPic( SB_PING_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardPing ); CG_DrawPic( SB_TIME_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardTime ); CG_DrawPic( SB_NAME_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardName ); y = SB_TOP; // If there are more than SB_MAXCLIENTS_NORMAL, use the interleaved scores if (1) { //( cg.numScores > SB_MAXCLIENTS_NORMAL ) { maxClients = SB_MAXCLIENTS_INTER; lineHeight = SB_INTER_HEIGHT; topBorderSize = 8; bottomBorderSize = 16; } else { maxClients = SB_MAXCLIENTS_NORMAL; lineHeight = SB_NORMAL_HEIGHT; topBorderSize = 16; bottomBorderSize = 16; } localClient = qfalse; if ( cgs.gametype >= GT_TEAM ) { // // teamplay scoreboard // y += lineHeight/2; if ( cg.teamScores[0] >= cg.teamScores[1] ) { n1 = CG_TeamScoreboard( y, TEAM_RED, fade, maxClients, lineHeight ); CG_DrawTeamBackground( 0, y - topBorderSize, 640, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED ); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; maxClients -= n1; n2 = CG_TeamScoreboard( y, TEAM_BLUE, fade, maxClients, lineHeight ); CG_DrawTeamBackground( 0, y - topBorderSize, 640, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE ); y += (n2 * lineHeight) + BIGCHAR_HEIGHT; maxClients -= n2; } else { n1 = CG_TeamScoreboard( y, TEAM_BLUE, fade, maxClients, lineHeight ); CG_DrawTeamBackground( 0, y - topBorderSize, 640, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE ); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; maxClients -= n1; n2 = CG_TeamScoreboard( y, TEAM_RED, fade, maxClients, lineHeight ); CG_DrawTeamBackground( 0, y - topBorderSize, 640, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED ); y += (n2 * lineHeight) + BIGCHAR_HEIGHT; maxClients -= n2; } n1 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients, lineHeight ); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; } else { // // free for all scoreboard // n1 = CG_TeamScoreboard( y, TEAM_FREE, fade, maxClients, lineHeight ); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; n2 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients - n1, lineHeight ); y += (n2 * lineHeight) + BIGCHAR_HEIGHT; } if (!localClient) { // draw local client at the bottom for ( i = 0 ; i < cg.numScores ; i++ ) { if ( cg.scores[i].client == cg.snap->ps.clientNum ) { CG_DrawClientScore( y, &cg.scores[i], fadeColor, fade, lineHeight == SB_NORMAL_HEIGHT ); break; } } } // load any models that have been deferred if ( ++cg.deferredPlayerLoading > 10 ) { CG_LoadDeferredPlayers(); } return qtrue; }
/* ======================================================================================================================================= CG_DrawScoreboard Draw the normal in-game scoreboard. ======================================================================================================================================= */ qboolean CG_DrawScoreboard(void) { int x = 0, y = 0, w; // TTimo init float fade; float *fadeColor; char *s; if (cg_fixedAspect.integer) { CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER); } // don't draw anything if the menu or console is up if (cg_paused.integer) { cg.deferredPlayerLoading = 0; return qfalse; } // still need to see 'mission failed' message in SP if (cgs.gametype == GT_SINGLE_PLAYER && cg.predictedPlayerState.pm_type == PM_DEAD) { return qfalse; } if (cgs.gametype == GT_SINGLE_PLAYER && cg.predictedPlayerState.pm_type == PM_INTERMISSION) { cg.deferredPlayerLoading = 0; return qfalse; } // don't draw scoreboard during death while warmup up if (cg.warmup && !cg.showScores) { return qfalse; } if (cg.showScores || cg.predictedPlayerState.pm_type == PM_DEAD || cg.predictedPlayerState.pm_type == PM_INTERMISSION) { fade = 1.0; } else { fadeColor = CG_FadeColor(cg.scoreFadeTime, FADE_TIME); if (!fadeColor) { // next time scoreboard comes up, don't print killer cg.deferredPlayerLoading = 0; cg.killerName[0] = 0; return qfalse; } fade = *fadeColor; } // fragged by ... line if (cg.killerName[0]) { s = va("Killed by %s", cg.killerName); w = CG_DrawStrlen(s) * BIGCHAR_WIDTH; x = (SCREEN_WIDTH - w) / 2; y = 40; CG_DrawBigString(x, y, s, fade); } // current rank // ---- (SA) enclosed this so it doesn't draw for SP if (cgs.gametype != GT_SINGLE_PLAYER && cgs.gametype != GT_WOLF) { // added wolf multiplayer check if (cg.snap->ps.persistant[PERS_TEAM] != TEAM_SPECTATOR) { if (cgs.gametype < GT_TEAM) { s = va("%s place with %i", CG_PlaceString(cg.snap->ps.persistant[PERS_RANK] + 1), cg.snap->ps.persistant[PERS_SCORE]); w = CG_DrawStrlen(s) * BIGCHAR_WIDTH; x = (SCREEN_WIDTH - w) / 2; y = 60; CG_DrawBigString(x, y, s, fade); } else { if (cg.teamScores[0] == cg.teamScores[1]) { s = va("Teams are tied at %i", cg.teamScores[0]); } else if (cg.teamScores[0] >= cg.teamScores[1]) { s = va("Red leads %i to %i", cg.teamScores[0], cg.teamScores[1]); } else { s = va("Blue leads %i to %i", cg.teamScores[1], cg.teamScores[0]); } w = CG_DrawStrlen(s) * BIGCHAR_WIDTH; x = (SCREEN_WIDTH - w) / 2; y = 60; CG_DrawBigString(x, y, s, fade); } } // scoreboard x = 320 - SCOREBOARD_WIDTH / 2; y = 86; #if 0 CG_DrawBigStringColor(x, y, "SCORE PING TIME NAME", fadeColor); CG_DrawBigStringColor(x, y + 12, "---- - ---- ---- -------------- - ", fadeColor); #endif CG_DrawPic(x + 1 * 16, y, 64, 32, cgs.media.scoreboardScore); CG_DrawPic(x + 6 * 16 + 8, y, 64, 32, cgs.media.scoreboardPing); CG_DrawPic(x + 11 * 16 + 8, y, 64, 32, cgs.media.scoreboardTime); CG_DrawPic(x + 16 * 16, y, 64, 32, cgs.media.scoreboardName); y += 32; } // NERVE - SMF if (cgs.gametype == GT_WOLF) { // teamplay scoreboard x = 320 - SCOREBOARD_WIDTH / 2 + 20 + 20; y = 40; y = WM_ScoreboardOverlay(x, y, fade); if (cg.teamScores[0] >= cg.teamScores[1]) { y = WM_TeamScoreboard(x, y, TEAM_RED, fade); y = WM_TeamScoreboard(x, y, TEAM_BLUE, fade); } else { y = WM_TeamScoreboard(x, y, TEAM_BLUE, fade); y = WM_TeamScoreboard(x, y, TEAM_RED, fade); } WM_TeamScoreboard(x, y, TEAM_SPECTATOR, fade); } // - NERVE - SMF } else if (cgs.gametype >= GT_TEAM) {
/* ================= CG_DrawScoreboard Draw the normal in-game scoreboard ================= */ qboolean CG_DrawScoreboard( void ) { int x = 0, y = 0, w, x_right; float fade; float *fadeColor; char *s; x = 20; y = 10; x_right = 640 - x - (INFO_TOTAL_WIDTH - 5); // don't draw anything if the menu or console is up if ( cg_paused.integer ) { return qfalse; } // don't draw scoreboard during death while warmup up // OSP - also for pesky scoreboards in demos if((cg.warmup || (cg.demoPlayback && cg.snap->ps.pm_type != PM_INTERMISSION)) && !cg.showScores) { return qfalse; } // don't draw if in cameramode if( cg.cameraMode ) { return qtrue; } if( cg.showScores || cg.predictedPlayerState.pm_type == PM_INTERMISSION ) { fade = 1.0; fadeColor = colorWhite; } else { fadeColor = CG_FadeColor( cg.scoreFadeTime, FADE_TIME ); if( !fadeColor ) { // next time scoreboard comes up, don't print killer *cg.killerName = 0; return qfalse; } fade = fadeColor[3]; } // fragged by ... line if( *cg.killerName ) { s = va("Killed by %s", cg.killerName ); w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH; CG_DrawBigString( ( SCREEN_WIDTH - w ) / 2, 40, s, fade ); } y = WM_DrawObjectives( x, y, 640 - 2*x + 5, fade ); if ( cgs.gametype == GT_WOLF_STOPWATCH && ( cg.snap->ps.pm_type == PM_INTERMISSION ) ) { y = WM_DrawInfoLine( x, 155, fade ); WM_TeamScoreboard( x, y, TEAM_AXIS, fade, 8 ); x = x_right; WM_TeamScoreboard( x, y, TEAM_ALLIES, fade, 8 ); } else { if(cg.snap->ps.pm_type == PM_INTERMISSION) { WM_TeamScoreboard( x, y, TEAM_AXIS, fade, 9 ); x = x_right; WM_TeamScoreboard( x, y, TEAM_ALLIES, fade, 9 ); } else { WM_TeamScoreboard( x, y, TEAM_AXIS, fade, 25 ); x = x_right; WM_TeamScoreboard( x, y, TEAM_ALLIES, fade, 25 ); } } /* if(!CG_IsSinglePlayer()) { qtime_t ct; G_showWindowMessages(); trap_RealTime(&ct); s = va("^3%02d:%02d:%02d - %02d %s %d", ct.tm_hour, ct.tm_min, ct.tm_sec, ct.tm_mday, aMonths[ct.tm_mon], 1900 + ct.tm_year); CG_DrawStringExt(444, 12, s, colorWhite, qfalse, qtrue, 8, 8, 0); } */ return qtrue; }