/* ================= CG_DrawScoreboard ================= */ static void CG_DrawClientScore( int y, score_t *score, vector4 *color, float fade, qboolean largeFormat ) { //vector3 headAngles; clientInfo_t *ci; int iconx = SB_SCORELINE_X - 5;//SB_BOTICON_X + (SB_RATING_WIDTH / 2); float scale = largeFormat ? 1.0f : 0.75f, iconSize = largeFormat ? SB_NORMAL_HEIGHT : SB_INTER_HEIGHT; iconx -= iconSize; if ( score->client < 0 || score->client >= cgs.maxclients ) { Com_Printf( "Bad score->client: %i\n", score->client ); return; } ci = &cgs.clientinfo[score->client]; // draw the handicap or bot skill marker (unless player has flag) if ( ci->powerups & (1<<PW_NEUTRALFLAG) ) { if ( largeFormat ) CG_DrawFlagModel( iconx, y - (32 - BIGCHAR_HEIGHT) / 2, iconSize, iconSize, TEAM_FREE, qfalse ); else CG_DrawFlagModel( iconx, y, iconSize, iconSize, TEAM_FREE, qfalse ); } else if ( ci->powerups & ( 1 << PW_REDFLAG ) ) CG_DrawFlagModel( iconx, y, iconSize, iconSize, TEAM_RED, qfalse ); else if ( ci->powerups & ( 1 << PW_BLUEFLAG ) ) CG_DrawFlagModel( iconx, y, iconSize, iconSize, TEAM_BLUE, qfalse ); else if ( cgs.gametype == GT_POWERDUEL && (ci->duelTeam == DUELTEAM_LONE || ci->duelTeam == DUELTEAM_DOUBLE) ) { CG_DrawPic( iconx, y, iconSize, iconSize, trap->R_RegisterShaderNoMip( (ci->duelTeam == DUELTEAM_LONE) ? "gfx/mp/pduel_icon_lone" : "gfx/mp/pduel_icon_double" ) ); } else if (cgs.gametype == GT_SIEGE) { //try to draw the shader for this class on the scoreboard if (ci->siegeIndex != -1) { siegeClass_t *scl = &bgSiegeClasses[ci->siegeIndex]; if (scl->classShader) { CG_DrawPic (iconx, y, largeFormat?24:12, largeFormat?24:12, scl->classShader); } } } else if ( ci->modelIcon && cg_scoreboardSkinIcons.integer ) CG_DrawPic( iconx, y, iconSize, iconSize, ci->modelIcon ); // highlight your position if ( score->client == cg.snap->ps.clientNum ) { vector4 hcolor; int rank; localClient = qtrue; if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR || cgs.gametype >= GT_TEAM ) { rank = -1; } else { rank = cg.snap->ps.persistant[PERS_RANK] & ~RANK_TIED_FLAG; } if ( rank == 0 ) { hcolor.r = 0; hcolor.g = 0; hcolor.b = 0.7f; } else if ( rank == 1 ) { hcolor.r = 0.7f; hcolor.g = 0; hcolor.b = 0; } else if ( rank == 2 ) { hcolor.r = 0.7f; hcolor.g = 0.7f; hcolor.b = 0; } else { hcolor.r = 0.7f; hcolor.g = 0.7f; hcolor.b = 0.7f; } hcolor.a = fade * 0.7; CG_FillRect( SB_SCORELINE_X - 5, y /*+ 2*/, SB_SCORELINE_WIDTH /*- SB_SCORELINE_X * 2 + 10*/, largeFormat?SB_NORMAL_HEIGHT:SB_INTER_HEIGHT, &hcolor ); } CG_Text_Paint (SB_NAME_X, y, 0.9f * scale, &colorWhite, ci->name,0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM ); if ( score->ping != -1 ) { if ( ci->team != TEAM_SPECTATOR || cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL ) { if (cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL) { CG_Text_Paint (SB_SCORE_X, y, 1.0f * scale, &colorWhite, va("%i/%i", ci->wins, ci->losses),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL ); } else { if ( Server_Supports( SSF_SCOREBOARD_KD ) ) CG_Text_Paint (SB_SCORE_X, y, 1.0f * scale, &colorWhite, va("%i/%i", score->score, score->deaths),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL ); else CG_Text_Paint (SB_SCORE_X, y, 1.0f * scale, &colorWhite, va("%i", score->score),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL ); } } CG_Text_Paint (SB_PING_X, y, 1.0f * scale, &colorWhite, va("%i", score->ping),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL ); CG_Text_Paint (SB_TIME_X, y, 1.0f * scale, &colorWhite, va("%i", score->time),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL ); } else { CG_Text_Paint (SB_SCORE_X, y, 1.0f * scale, &colorWhite, "-",0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL ); CG_Text_Paint (SB_PING_X, y, 1.0f * scale, &colorWhite, "-",0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL ); CG_Text_Paint (SB_TIME_X, y, 1.0f * scale, &colorWhite, "-",0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL ); } // add the "ready" marker for intermission exiting if ( cg.snap->ps.stats[STAT_CLIENTS_READY] & ( 1 << score->client ) ) { CG_Text_Paint( cg_scoreboardSkinIcons.integer ? 4 : SB_NAME_X - 48, y + 2, 0.7f * scale, &colorWhite, CG_GetStringEdString("MP_INGAME", "READY"), 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM ); } else if ( cgs.clientinfo[score->client].botSkill != -1 ) CG_Text_Paint( cg_scoreboardSkinIcons.integer ? 4 : SB_NAME_X - 48, y + 2, 0.7f * scale, &colorWhite, "BOT", 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM ); else if ( score->team == TEAM_SPECTATOR ) CG_Text_Paint( cg_scoreboardSkinIcons.integer ? 4 : SB_NAME_X - 48, y + 2, 0.7f * scale, &colorWhite, "SPEC", 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM ); }
void CG_SpecHelpDraw() { if(cg.spechelpWindow == SHOW_OFF) { return; } else { const helpType_t help[] = { //{ "+zoom", "hold for pointer" }, { "MOUSE1", "window move/resize" }, { "SHIFT/CTRL/MOUSE4", "hold to resize" }, { "MWHEELDOWN/INS/KPPGUP", "window on" }, { "MWHEELUP/DEL/KPPGDN", "window off" }, { "MOUSE2", "swap w/main view" }, { NULL, NULL }, //{ "weapalt", "swingcam toggle" }, { "BACKSPACE", "help on/off" }, { "M/ESC", "End Multiview" }, }; int i, x, y = 480, w, h; int len, maxlen = 0; char format[MAX_STRING_TOKENS]/*, buf[MAX_STRING_TOKENS]*/; char *lines[16]; vec4_t bgColor = COLOR_BG; // window vec4_t borderColor = COLOR_BORDER; // window vec4_t bgColorTitle = COLOR_BG_TITLE; // titlebar vec4_t borderColorTitle = COLOR_BORDER_TITLE; // titlebar // Main header int hStyle = ITEM_TEXTSTYLE_SHADOWED; float hScale = 0.16f; float hScaleY = 0.21f; fontInfo_t *hFont = FONT_HEADER; vec4_t hdrColor2 = COLOR_HDR2; // text // Text settings int tStyle = ITEM_TEXTSTYLE_SHADOWED; int tSpacing = 9; // Should derive from CG_Text_Height_Ext float tScale = 0.19f; fontInfo_t *tFont = FONT_TEXT; vec4_t tColor = COLOR_TEXT; // text float diff = cg.fadeTime - trap_Milliseconds(); // FIXME: Should compute all this stuff beforehand // Compute required width for(i=0; i<sizeof(help)/sizeof(helpType_t); i++) { if(help[i].cmd != NULL) { //len = strlen(CG_getBindKeyName(help[i].cmd, buf, sizeof(buf))); len = strlen(help[i].cmd); if(len > maxlen) { maxlen = len; } } } Q_strncpyz(format, va("^2%%%ds ^N%%s", maxlen), sizeof(format)); for(i=0, maxlen=0; i<sizeof(help)/sizeof(helpType_t); i++) { if(help[i].cmd != NULL) { //lines[i] = va(format, CG_getBindKeyName(help[i].cmd, buf, sizeof(buf)), help[i].info); lines[i] = va(format, help[i].cmd, help[i].info); len = CG_Text_Width_Ext(lines[i], tScale, 0, FONT_TEXT); if(len > maxlen) { maxlen = len; } } else { lines[i] = NULL; } } w = maxlen + 8; x = SH_X; y = SH_Y; h = 2 + tSpacing + 2 + // Header 2 + 1 + tSpacing * (sizeof(help) / sizeof(helpType_t)) + 2; // Fade-in effects if(diff > 0.0f) { float scale = (diff / STATS_FADE_TIME); if(cg.spechelpWindow == SHOW_ON) { scale = 1.0f - scale; } bgColor[3] *= scale; bgColorTitle[3] *= scale; borderColor[3] *= scale; borderColorTitle[3] *= scale; hdrColor2[3] *= scale; tColor[3] *= scale; x -= w * (1.0f - scale); } else if(cg.spechelpWindow == SHOW_SHUTDOWN) { cg.spechelpWindow = SHOW_OFF; return; } CG_DrawRect(x, y, w, h, 1, borderColor); CG_FillRect(x, y, w, h, bgColor); // Header CG_FillRect(x, y, w, tSpacing + 4, bgColorTitle); CG_DrawRect(x, y, w, tSpacing + 4, 1, borderColorTitle); x += 4; y += 1; y += tSpacing; CG_Text_Paint_Ext(x, y, hScale, hScaleY, hdrColor2, "SPECTATOR CONTROLS", 0.0f, 0, hStyle, hFont); y += 3; // Control info for(i=0; i<sizeof(help)/sizeof(helpType_t); i++) { y += tSpacing; if(lines[i] != NULL) { CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, lines[i], 0.0f, 0, tStyle, tFont); } } } }
void CG_TopShotsDraw() { if(cgs.topshots.show == SHOW_OFF) { return; } else { int i, x = 640 + TS_X - TS_W, y = 480, h; topshotStats_t *ts = &cgs.topshots; vec4_t bgColor = COLOR_BG; // window vec4_t borderColor = COLOR_BORDER; // window vec4_t bgColorTitle = COLOR_BG_TITLE; // titlebar vec4_t borderColorTitle = COLOR_BORDER_TITLE; // titlebar // Main header int hStyle = ITEM_TEXTSTYLE_SHADOWED; float hScale = 0.16f; float hScaleY = 0.21f; fontInfo_t *hFont = FONT_HEADER; // Sub header int hStyle2 = 0; float hScale2 = 0.16f; float hScaleY2 = 0.20f; fontInfo_t *hFont2 = FONT_SUBHEADER; vec4_t hdrColor = COLOR_HDR; // text vec4_t hdrColor2 = COLOR_HDR2; // text // Text settings int tStyle = ITEM_TEXTSTYLE_SHADOWED; int tSpacing = 9; // Should derive from CG_Text_Height_Ext float tScale = 0.19f; fontInfo_t *tFont = FONT_TEXT; vec4_t tColor = COLOR_TEXT; // text float diff = cgs.topshots.fadeTime - cg.time; // FIXME: Should compute this beforehand h = 2 + tSpacing + 2 + // Header 2 + 2 + tSpacing + 2 + // Stats columns 1 + // Stats + extra tSpacing * ((ts->cWeapons > 0) ? ts->cWeapons : 1) + 1; // Fade-in effects if(diff > 0.0f) { float scale = (diff / STATS_FADE_TIME); if(cgs.topshots.show == SHOW_ON) { scale = 1.0f - scale; } bgColor[3] *= scale; bgColorTitle[3] *= scale; borderColor[3] *= scale; borderColorTitle[3] *= scale; hdrColor[3] *= scale; hdrColor2[3] *= scale; tColor[3] *= scale; y += (TS_Y - h) * scale; } else if(cgs.topshots.show == SHOW_SHUTDOWN) { cgs.topshots.show = SHOW_OFF; return; } else { y += TS_Y - h; } CG_DrawRect(x, y, TS_W, h, 1, borderColor); CG_FillRect(x, y, TS_W, h, bgColor); // Header CG_FillRect(x, y, TS_W, tSpacing+4, bgColorTitle); CG_DrawRect(x, y, TS_W, tSpacing+4, 1, borderColorTitle); y += 1; y += tSpacing; CG_Text_Paint_Ext(x + 4, y, hScale, hScaleY, hdrColor, "\"TOPSHOT\" ACCURACIES", 0.0f, 0, hStyle, hFont); y += 4; // Weapon stats y += 2; CG_FillRect(x, y, TS_W, tSpacing + 3, bgColorTitle); CG_DrawRect(x, y, TS_W, tSpacing + 3, 1, borderColorTitle); x += 4; y += 1 + tSpacing; CG_Text_Paint_Ext(x, y, hScale2, hScaleY2, hdrColor, "Weapon", 0.0f, 0, hStyle2, hFont2); x += 60; CG_Text_Paint_Ext(x, y, hScale2, hScaleY2, hdrColor, "Accuracy", 0.0f, 0, hStyle2, hFont2); x += 53; CG_Text_Paint_Ext(x, y, hScale2, hScaleY2, hdrColor, "Hits / Shots", 0.0f, 0, hStyle2, hFont2); x += 62; CG_Text_Paint_Ext(x, y, hScale2, hScaleY2, hdrColor, "Kills", 0.0f, 0, hStyle2, hFont2); x += 32; CG_Text_Paint_Ext(x, y, hScale2, hScaleY2, hdrColor, "Player", 0.0f, 0, hStyle2, hFont2); x = 640 + TS_X - TS_W + 4; y += 1; if(ts->cWeapons == 0) { y += tSpacing; CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, "No qualifying weapon info available.", 0.0f, 0, tStyle, tFont); } else { for(i=0; i<ts->cWeapons; i++) { y += tSpacing; CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, ts->strWS[i], 0.0f, 0, tStyle, tFont); } } } }
static void CG_DrawClientScore( int y, const score_t *score, const float *color, float fade, qboolean largeFormat ) { char string[1024]; vec3_t headAngles; const clientInfo_t *ci; int iconx, headx; #if 0 Com_Printf("---- CG_DrawClientScore() ------\n"); Com_Printf(" client: %d\n", score->client); Com_Printf(" score: %d\n", score->score); Com_Printf(" ping: %d\n", score->ping); Com_Printf(" time: %d\n", score->time); Com_Printf(" scoreFlags: %d\n", score->scoreFlags); Com_Printf(" powerUps: %d\n", score->powerUps); Com_Printf(" accuracy: %d\n", score->accuracy); // Com_Printf(" ...\n"); Com_Printf(" impressiveCount: %d\n", score->impressiveCount); Com_Printf(" excellentCount: %d\n", score->excellentCount); Com_Printf(" gauntletCount: %d\n", score->gauntletCount); Com_Printf(" defendCount: %d\n", score->defendCount); Com_Printf(" assistCount: %d\n", score->assistCount); Com_Printf(" perfect: %d\n", score->perfect); Com_Printf(" team: %d\n", score->team); #endif if ( score->client < 0 || score->client >= cgs.maxclients ) { Com_Printf( "Bad score->client: %i\n", score->client ); return; } ci = &cgs.clientinfo[score->client]; iconx = SB_BOTICON_X + (SB_RATING_WIDTH / 2); headx = SB_HEAD_X + (SB_RATING_WIDTH / 2); // draw the handicap or bot skill marker (unless player has flag) if ( ci->powerups & ( 1 << PW_NEUTRALFLAG ) ) { if( largeFormat ) { CG_DrawFlagModel( iconx, y - ( 32 - BIGCHAR_HEIGHT ) / 2, 32, 32, TEAM_FREE, qfalse ); } else { CG_DrawFlagModel( iconx, y, 16, 16, TEAM_FREE, qfalse ); } } else if ( ci->powerups & ( 1 << PW_REDFLAG ) ) { if( largeFormat ) { CG_DrawFlagModel( iconx, y - ( 32 - BIGCHAR_HEIGHT ) / 2, 32, 32, TEAM_RED, qfalse ); } else { CG_DrawFlagModel( iconx, y, 16, 16, TEAM_RED, qfalse ); } } else if ( ci->powerups & ( 1 << PW_BLUEFLAG ) ) { if( largeFormat ) { CG_DrawFlagModel( iconx, y - ( 32 - BIGCHAR_HEIGHT ) / 2, 32, 32, TEAM_BLUE, qfalse ); } else { CG_DrawFlagModel( iconx, y, 16, 16, TEAM_BLUE, qfalse ); } } else { if ( ci->botSkill > 0 && ci->botSkill <= 5 ) { if ( cg_drawIcons.integer ) { if( largeFormat ) { CG_DrawPic( iconx, y - ( 32 - BIGCHAR_HEIGHT ) / 2, 32, 32, cgs.media.botSkillShaders[ ci->botSkill - 1 ] ); } else { CG_DrawPic( iconx, y, 16, 16, cgs.media.botSkillShaders[ ci->botSkill - 1 ] ); } } } else if ( ci->handicap < 100 ) { Com_sprintf( string, sizeof( string ), "%i", ci->handicap ); if ( CG_IsDuelGame(cgs.gametype) ) CG_DrawSmallStringColor( iconx, y - SMALLCHAR_HEIGHT/2, string, color ); else CG_DrawSmallStringColor( iconx, y, string, color ); } // draw the wins / losses if ( CG_IsDuelGame(cgs.gametype) ) { Com_sprintf( string, sizeof( string ), "%i/%i", ci->wins, ci->losses ); if( ci->handicap < 100 && !ci->botSkill ) { CG_DrawSmallStringColor( iconx, y + SMALLCHAR_HEIGHT/2, string, color ); } else { CG_DrawSmallStringColor( iconx, y, string, color ); } } } // draw the face VectorClear( headAngles ); headAngles[YAW] = 180; if( largeFormat ) { CG_DrawHead( headx, y - ( ICON_SIZE - BIGCHAR_HEIGHT ) / 2, ICON_SIZE, ICON_SIZE, score->client, headAngles, qtrue ); } else { CG_DrawHead( headx, y, 16, 16, score->client, headAngles, qtrue ); } #ifdef MISSIONPACK // draw the team task if ( ci->teamTask != TEAMTASK_NONE ) { if ( ci->teamTask == TEAMTASK_OFFENSE ) { CG_DrawPic( headx + 48, y, 16, 16, cgs.media.assaultShader ); } else if ( ci->teamTask == TEAMTASK_DEFENSE ) { CG_DrawPic( headx + 48, y, 16, 16, cgs.media.defendShader ); } } #endif // draw the score line if ( score->ping == -1 ) { Com_sprintf(string, sizeof(string), " connecting %s", ci->name); //} else if ( ci->team == TEAM_SPECTATOR && cg.numScores > 0) { } else if ( score->team == TEAM_SPECTATOR && cg.numScores > 0) { Com_sprintf(string, sizeof(string), "^3%5i %4i %4i ^7%s", score->score, score->ping, score->time, ci->name); } else if (cg.numScores > 0) { #if 1 Com_sprintf(string, sizeof(string), "%5i %4i %4i %s", score->score, score->ping, score->time, ci->name); #endif #if 0 Com_sprintf(string, sizeof(string), "%5i %4i %4i %i %i %i %i %s %s", score->score, score->ping, score->time, score->alive, score->frags, score->deaths, score->accuracy, weapNames[score->bestWeapon], ci->name); #endif #if 0 Com_sprintf(string, sizeof(string), "%5i %4i %4i %d %s %s", score->score, score->ping, score->time, score->accuracy, weapNames[score->bestWeapon], ci->name); #endif } else if (cg.demoPlayback) { Com_sprintf(string, sizeof(string), " %s", ci->name); } //FIXME wolfcam // highlight your position if ( score->client == cg.snap->ps.clientNum ) { float hcolor[4]; int rank; localClient = qtrue; if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR || cgs.gametype >= GT_TEAM ) { rank = -1; } else { rank = cg.snap->ps.persistant[PERS_RANK] & ~RANK_TIED_FLAG; } if ( rank == 0 ) { hcolor[0] = 0; hcolor[1] = 0; hcolor[2] = 0.7f; } else if ( rank == 1 ) { hcolor[0] = 0.7f; hcolor[1] = 0; hcolor[2] = 0; } else if ( rank == 2 ) { hcolor[0] = 0.7f; hcolor[1] = 0.7f; hcolor[2] = 0; } else { hcolor[0] = 0.7f; hcolor[1] = 0.7f; hcolor[2] = 0.7f; } hcolor[3] = fade * 0.7; CG_FillRect( SB_SCORELINE_X + BIGCHAR_WIDTH + (SB_RATING_WIDTH / 2), y, 640 - SB_SCORELINE_X - BIGCHAR_WIDTH, BIGCHAR_HEIGHT+1, hcolor ); } CG_DrawBigString( SB_SCORELINE_X + (SB_RATING_WIDTH / 2), y, string, fade ); // add the "ready" marker for intermission exiting if ( cg.snap->ps.stats[ STAT_CLIENTS_READY ] & ( 1 << score->client ) ) { CG_DrawBigStringColor( iconx, y, "READY", color ); } }
/* ================= Slider_Draw ================= */ static void Slider_Draw( menuslider_s *s ) { float *color; int style; int i; int x; int y; qboolean focus; x = s->generic.x; y = s->generic.y; focus = (s->generic.parent->cursor == s->generic.menuPosition); style = UI_SMALLFONT; if ( s->generic.flags & QMF_GRAYED ) { color = text_color_disabled; } else if (focus) { color = text_color_highlight; style |= UI_PULSE; } else { color = text_color_normal; } if ( focus ) { // draw cursor CG_FillRect( s->generic.left, s->generic.top, s->generic.right-s->generic.left+1, s->generic.bottom-s->generic.top+1, listbar_color ); UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|UI_SMALLFONT, color); } // draw label UI_DrawString( x - SMALLCHAR_WIDTH, y, s->generic.name, UI_RIGHT|style, color ); // draw slider UI_DrawChar( x + SMALLCHAR_WIDTH, y, 128, UI_LEFT|style, color); for ( i = 0; i < SLIDER_RANGE; i++ ) UI_DrawChar( x + (i+2)*SMALLCHAR_WIDTH, y, 129, UI_LEFT|style, color); UI_DrawChar( x + (i+2)*SMALLCHAR_WIDTH, y, 130, UI_LEFT|style, color); // clamp thumb if (s->maxvalue > s->minvalue) { s->range = ( s->curvalue - s->minvalue ) / ( float ) ( s->maxvalue - s->minvalue ); if ( s->range < 0) s->range = 0; else if ( s->range > 1) s->range = 1; } else s->range = 0; // draw thumb if (style & UI_PULSE) { style &= ~UI_PULSE; style |= UI_BLINK; } UI_DrawChar( (int)( x + 2*SMALLCHAR_WIDTH + (SLIDER_RANGE-1)*SMALLCHAR_WIDTH* s->range ), y, 131, UI_LEFT|style, color); }
void CG_DrawFireTeamOverlay( rectDef_t* rect ) { int x = rect->x; int y = rect->y + 1; // +1, jitter it into place in 1024 :) float h; clientInfo_t* ci = NULL; char buffer[64]; fireteamData_t* f = NULL; int i; vec4_t clr1 = { .16f, .2f, .17f, .8f }; vec4_t clr2 = { 0.f, 0.f, 0.f, .2f }; vec4_t clr3 = { 0.25f, 0.f, 0.f, 153 / 255.f }; vec4_t tclr = { 0.6f, 0.6f, 0.6f, 1.0f }; vec4_t bgColor = { 0.0f, 0.0f, 0.0f, 0.6f }; // window vec4_t borderColor = { 0.5f, 0.5f, 0.5f, 0.5f }; // window if ( !( f = CG_IsOnFireteam( cg.clientNum ) ) ) { return; } h = 12 + 2 + 2; for ( i = 0; i < 6; i++ ) { ci = CG_SortedFireTeamPlayerForPosition( i, 6 ); if ( !ci ) { break;; } h += FT_BAR_HEIGHT + FT_BAR_YSPACING; } CG_DrawRect( x, y, 204, h, 1, borderColor ); CG_FillRect( x + 1, y + 1, 204 - 2, h - 2, bgColor ); x += 2; y += 2; CG_FillRect( x, y, 204 - 4, 12, clr1 ); sprintf( buffer, "Fireteam: %s", bg_fireteamNames[f->ident] ); Q_strupr( buffer ); CG_Text_Paint_Ext( x + 3, y + FT_BAR_HEIGHT, .19f, .19f, tclr, buffer, 0, 0, 0, &cgs.media.limboFont1 ); x += 2; //y += 2; for ( i = 0; i < 6; i++ ) { y += FT_BAR_HEIGHT + FT_BAR_YSPACING; x = rect->x + 2; ci = CG_SortedFireTeamPlayerForPosition( i, 6 ); if ( !ci ) { break;; } if ( ci->selected ) { CG_FillRect( x, y + FT_BAR_YSPACING, 204 - 4, FT_BAR_HEIGHT, clr3 ); } else { CG_FillRect( x, y + FT_BAR_YSPACING, 204 - 4, FT_BAR_HEIGHT, clr2 ); } x += 4; CG_Text_Paint_Ext( x, y + FT_BAR_HEIGHT, .2f, .2f, tclr, BG_ClassLetterForNumber( ci->cls ), 0, 0, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2 ); x += 10; CG_Text_Paint_Ext( x, y + FT_BAR_HEIGHT, .2f, .2f, tclr, ci->team == TEAM_AXIS ? miniRankNames_Axis[ci->rank] : miniRankNames_Allies[ci->rank], 0, 0, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2 ); x += 22; CG_Text_Paint_Ext( x, y + FT_BAR_HEIGHT, .2f, .2f, tclr, ci->name, 0, 17, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2 ); x += 90; /* CG_DrawPic(x + 2, y + 2, FT_BAR_HEIGHT - 4, FT_BAR_HEIGHT - 4, cgs.media.movementAutonomyIcons[0]); x += FT_BAR_HEIGHT; CG_DrawPic(x + 2, y + 2, FT_BAR_HEIGHT - 4, FT_BAR_HEIGHT - 4, cgs.media.weaponAutonomyIcons[0]); x += FT_BAR_HEIGHT; x += 4;*/ /* if( isLeader ) { CG_Text_Paint_Ext(x, y + FT_BAR_HEIGHT, .2f, .2f, tclr, va("%i", i+4), 0, 0, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2 ); }*/ x += 20; if ( ci->health > 80 ) { CG_Text_Paint_Ext( x, y + FT_BAR_HEIGHT, .2f, .2f, tclr, va( "%i", ci->health < 0 ? 0 : ci->health ), 0, 0, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2 ); } else if ( ci->health > 0 ) { CG_Text_Paint_Ext( x, y + FT_BAR_HEIGHT, .2f, .2f, colorYellow, va( "%i", ci->health < 0 ? 0 : ci->health ), 0, 0, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2 ); } else { CG_Text_Paint_Ext( x, y + FT_BAR_HEIGHT, .2f, .2f, colorRed, va( "%i", ci->health < 0 ? 0 : ci->health ), 0, 0, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2 ); } //x += 20; { vec2_t loc; char *s; loc[0] = ci->location[0]; loc[1] = ci->location[1]; s = va( "^3(%s)", BG_GetLocationString( loc ) ); x = rect->x + ( 204 - 4 - CG_Text_Width_Ext( s, .2f, 0, &cgs.media.limboFont2 ) ); CG_Text_Paint_Ext( x, y + FT_BAR_HEIGHT, .2f, .2f, tclr, va( "^3(%s)", BG_GetLocationString( loc ) ), 0, 0, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2 ); } } }
/* New ETrun draw spectators function * * @author Nico */ static void WM_ETrun_DrawSpectators(int *x, int *y, fontInfo_t *font, s_timerunScores *orderedScores, int numScores) { char *s; int tempx = 0; float fontsize = 0.16f; int i = 0; int mil, min, sec; // Draw "Spectators" s = "Spectators"; tempx = *x + INFO_SPEC_TOTAL_WIDTH / 2 - CG_Text_Width_Ext(s, 0.25f, 0, &cgs.media.limboFont1) / 2; WM_ETrun_print(s, font, 0.25f, tempx, *y, qtrue, 0); WM_ETrun_newlines(1, y, SMALLCHAR_HEIGHT); // Draw player info headings background CG_FillRect(*x, *y, INFO_SPEC_TOTAL_WIDTH, INFO_LINE_HEIGHT, clrUiBack); CG_DrawRect_FixedBorder(*x, *y, INFO_SPEC_TOTAL_WIDTH, INFO_LINE_HEIGHT, 1, colorBlack); *y += INFO_LINE_HEIGHT - 2; // Draw spec info headings tempx = *x; WM_ETrun_print("Name", font, fontsize, tempx, *y, qtrue, 0); tempx += INFO_SPEC_PLAYER_WIDTH; WM_ETrun_print("Following", font, fontsize, tempx, *y, qtrue, 0); tempx += INFO_SPEC_FOLLOWED_PLAYER_WIDTH; WM_ETrun_print("Time", font, fontsize, tempx, *y, qtrue, 0); tempx += INFO_SPEC_SCORE_WIDTH; WM_ETrun_print("Speed", font, fontsize, tempx, *y, qtrue, 0); tempx += INFO_SPEC_SPEED_WIDTH; WM_ETrun_print("Ping", font, fontsize, tempx, *y, qtrue, 0); tempx += INFO_SPEC_LATENCY_WIDTH; for (i = 0; i < numScores; ++i) { qboolean drawFlag = qfalse; // Ignore non-spectators if (orderedScores[i].team != TEAM_SPECTATOR) { continue; } tempx = *x; *y += 4; // Draw background (highlight your line) CG_FillRect(*x, *y, INFO_SPEC_TOTAL_WIDTH, INFO_LINE_HEIGHT, orderedScores[i].clientNum == cg.clientNum ? clrUiYou : clrUiBack); CG_DrawRect_FixedBorder(*x, *y, INFO_SPEC_TOTAL_WIDTH, INFO_LINE_HEIGHT, 1, colorBlack); *y += INFO_LINE_HEIGHT - 2; // Nico, draw country flag if (cg_countryFlags.integer) { if (WM_ETrun_drawCountryFlag(tempx, *y, orderedScores[i].countryCode)) { tempx += 16; drawFlag = qtrue; } } // Nico, draw player name WM_ETrun_print(orderedScores[i].name, font, fontsize, tempx, *y, qtrue, drawFlag == qfalse ? NAME_MAX_LENGHT : NAME_MAX_LENGHT - 3); tempx += drawFlag == qfalse ? INFO_PLAYER_WIDTH : INFO_PLAYER_WIDTH - 16; // Nico, draw followed client name if (orderedScores[i].clientNum != orderedScores[i].followedClient) { s = orderedScores[i].followedClientName; } else { s = "-"; } WM_ETrun_print(s, font, fontsize, tempx, *y, qtrue, NAME_MAX_LENGHT); tempx += INFO_SPEC_FOLLOWED_PLAYER_WIDTH; // Nico, show best time if (orderedScores[i].timerunBestTime) { mil = orderedScores[i].timerunBestTime; min = mil / 60000; mil -= min * 60000; sec = mil / 1000; mil -= sec * 1000; s = va("^7%02d:%02d.%03d", min, sec, mil); } else { s = "-"; } WM_ETrun_print(s, font, fontsize, tempx, *y, qtrue, 0); tempx += INFO_SPEC_SCORE_WIDTH; // Nico, draw best speed WM_ETrun_print(va("%d", orderedScores[i].timerunBestSpeed), font, fontsize, tempx, *y, qtrue, 0); tempx += INFO_SPEC_SPEED_WIDTH; // Nico, draw ping WM_ETrun_print(WM_ETrun_coloredPing(orderedScores[i].ping), font, fontsize, tempx, *y, qtrue, 0); tempx += INFO_SPEC_LATENCY_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; }
/* ================= CG_DrawScoreboard ================= */ static void CG_DrawClientScore( int y, score_t *score, float *color, float fade, qboolean largeFormat ) { //vec3_t headAngles; clientInfo_t *ci; int iconx, headx; float scale; if ( largeFormat ) { scale = 1.0f; } else { scale = 0.75f; } if ( score->client < 0 || score->client >= cgs.maxclients ) { Com_Printf( "Bad score->client: %i\n", score->client ); return; } ci = &cgs.clientinfo[score->client]; iconx = SB_BOTICON_X + (SB_RATING_WIDTH / 2); headx = SB_HEAD_X + (SB_RATING_WIDTH / 2); // draw the handicap or bot skill marker (unless player has flag) if ( ci->powerups & ( 1 << PW_REDFLAG ) ) { CG_DrawFlagModel( iconx*cgs.screenXScale, y*cgs.screenYScale, 32*cgs.screenXScale, 32*cgs.screenYScale, TEAM_RED, qfalse ); } else if ( ci->powerups & ( 1 << PW_BLUEFLAG ) ) { CG_DrawFlagModel( iconx*cgs.screenXScale, y*cgs.screenYScale, 32*cgs.screenXScale, 32*cgs.screenYScale, TEAM_BLUE, qfalse ); } else if (cgs.gametype == GT_POWERDUEL && (ci->duelTeam == DUELTEAM_LONE || ci->duelTeam == DUELTEAM_DOUBLE)) { if (ci->duelTeam == DUELTEAM_LONE) { CG_DrawPic ( iconx, y, 32, 32, trap_R_RegisterShaderNoMip ( "gfx/mp/pduel_icon_lone" ) ); } else { CG_DrawPic ( iconx, y, 32, 32, trap_R_RegisterShaderNoMip ( "gfx/mp/pduel_icon_double" ) ); } } else { // draw the wins / losses /* if ( cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL ) { CG_DrawSmallStringColor( iconx, y + SMALLCHAR_HEIGHT/2, va("%i/%i", ci->wins, ci->losses ), color ); } */ //rww - in duel, we now show wins/losses in place of "frags". This is because duel now defaults to 1 kill per round. } // highlight your position if ( score->client == cg.snap->ps.clientNum ) { float hcolor[4]; int rank; localClient = qtrue; if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR || cgs.gametype >= GT_TEAM ) { rank = -1; } else { rank = cg.snap->ps.persistant[PERS_RANK] & ~RANK_TIED_FLAG; } if ( rank == 0 ) { hcolor[0] = 0; hcolor[1] = 0; hcolor[2] = 0.7f; } else if ( rank == 1 ) { hcolor[0] = 0.7f; hcolor[1] = 0; hcolor[2] = 0; } else if ( rank == 2 ) { hcolor[0] = 0.7f; hcolor[1] = 0.7f; hcolor[2] = 0; } else { hcolor[0] = 0.7f; hcolor[1] = 0.7f; hcolor[2] = 0.7f; } hcolor[3] = fade * 0.7; CG_FillRect( SB_SCORELINE_X - 5, y + 2, 640 - SB_SCORELINE_X * 2 + 10, largeFormat?SB_NORMAL_HEIGHT:SB_INTER_HEIGHT, hcolor ); } CG_Text_Paint (SB_NAME_X, y, 0.9f * scale, colorWhite, ci->name,0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM ); if ( score->ping != -1 ) { if ( ci->team != TEAM_SPECTATOR || cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL ) { if (cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL) { CG_Text_Paint (SB_SCORE_X, y, 1.0f * scale, colorWhite, va("%i/%i", ci->wins, ci->losses),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL ); } else { CG_Text_Paint (SB_SCORE_X, y, 1.0f * scale, colorWhite, va("%i", score->score),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL ); } } CG_Text_Paint (SB_PING_X, y, 1.0f * scale, colorWhite, va("%i", score->ping),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL ); CG_Text_Paint (SB_TIME_X, y, 1.0f * scale, colorWhite, va("%i", score->time),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL ); } else { CG_Text_Paint (SB_SCORE_X, y, 1.0f * scale, colorWhite, "-",0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL ); CG_Text_Paint (SB_PING_X, y, 1.0f * scale, colorWhite, "-",0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL ); CG_Text_Paint (SB_TIME_X, y, 1.0f * scale, colorWhite, "-",0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL ); } // add the "ready" marker for intermission exiting if ( cg.snap->ps.stats[ STAT_CLIENTS_READY ] & ( 1 << score->client ) ) { CG_Text_Paint (SB_NAME_X - 64, y + 2, 0.7f * scale, colorWhite, CG_GetStringEdString("MP_INGAME", "READY"),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM ); } }
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; }
/* ================= CG_DrawScoreboard ================= */ static void CG_DrawClientScore( int x, int y, score_t *score, float *color, float fade ) { char string[1024]; vec3_t headAngles; clientInfo_t *ci; if ( score->client < 0 || score->client >= cgs.maxclients ) { Com_Printf( "Bad score->client: %i\n", score->client ); return; } ci = &cgs.clientinfo[score->client]; // draw the handicap or bot skill marker if ( ci->botSkill > 0 && ci->botSkill <= 5 ) { CG_DrawPic( 0, y - 8, 32, 32, cgs.media.botSkillShaders[ ci->botSkill - 1 ] ); } else if ( ci->handicap < 100 ) { Com_sprintf( string, sizeof( string ), "%i", ci->handicap ); CG_DrawSmallStringColor( 8, y, string, color ); } // draw the wins / losses if ( cgs.gametype == GT_TOURNAMENT ) { Com_sprintf( string, sizeof( string ), "%i/%i", ci->wins, ci->losses ); CG_DrawSmallStringColor( x + SCOREBOARD_WIDTH + 2, y, string, color ); } // draw the face VectorClear( headAngles ); headAngles[YAW] = 180; CG_DrawHead( x - ICON_SIZE, y - ( ICON_SIZE - BIGCHAR_HEIGHT ) / 2, ICON_SIZE, ICON_SIZE, score->client, headAngles ); if ( ci->powerups & ( 1 << PW_REDFLAG ) ) { CG_DrawFlagModel( x - ICON_SIZE - ICON_SIZE / 2, y - ( ICON_SIZE - BIGCHAR_HEIGHT ) / 2, ICON_SIZE, ICON_SIZE, TEAM_RED ); } else if ( ci->powerups & ( 1 << PW_BLUEFLAG ) ) { CG_DrawFlagModel( x - ICON_SIZE - ICON_SIZE / 2, y - ( ICON_SIZE - BIGCHAR_HEIGHT ) / 2, ICON_SIZE, ICON_SIZE, TEAM_BLUE ); } // draw the score line if ( score->ping == -1 ) { Com_sprintf( string, sizeof( string ), "connecting %s", ci->name ); } else if ( ci->team == TEAM_SPECTATOR ) { Com_sprintf( string, sizeof( string ), "SPECT %4i %4i %s", score->ping, score->time, ci->name ); } else { Com_sprintf( string, sizeof( string ), "%5i %4i %4i %s", score->score, score->ping, score->time, ci->name ); } // highlight your position if ( score->client == cg.snap->ps.clientNum ) { float hcolor[4]; int rank; if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR || cgs.gametype >= GT_TEAM ) { rank = -1; } else { rank = cg.snap->ps.persistant[PERS_RANK] & ~RANK_TIED_FLAG; } if ( rank == 0 ) { hcolor[0] = 0; hcolor[1] = 0; hcolor[2] = 0.7; } else if ( rank == 1 ) { hcolor[0] = 0.7; hcolor[1] = 0; hcolor[2] = 0; } else if ( rank == 2 ) { hcolor[0] = 0.7; hcolor[1] = 0.7; hcolor[2] = 0; } else { hcolor[0] = 0.7; hcolor[1] = 0.7; hcolor[2] = 0.7; } hcolor[3] = fade * 0.7; CG_FillRect( x - 2, y, SCOREBOARD_WIDTH, BIGCHAR_HEIGHT + 1, hcolor ); } CG_DrawBigString( x, y, string, fade ); // add the "ready" marker for intermission exiting if ( cg.snap->ps.stats[ STAT_CLIENTS_READY ] & ( 1 << score->client ) ) { CG_DrawBigStringColor( 0, y, "READY", color ); } }
int WM_DrawObjectives( int x, int y, int width, float fade ) { const char *s, *buf, *str; char teamstr[32]; int i, num, strwidth, status; int height, tempy, rows; vec4_t hcolor; int msec, mins, seconds, tens; // JPW NERVE 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 *s, *buf, *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 ); } } 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 ); } } 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 { 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 - ( 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( "%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 ) ) { num = atoi( buf ); 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; }
// Main window-drawing handler void CG_windowDraw(void) { int h, x, y, i, j, milli, t_offset, tmp; cg_window_t *w; qboolean fCleanup = qfalse; // Gordon: FIXME, the limbomenu var no longer exists vec4_t *bg; vec4_t textColor, borderColor, bgColor; if (cg.winHandler.numActiveWindows == 0) { // Draw these for demoplayback no matter what CG_demoAviFPSDraw(); CG_demoTimescaleDraw(); return; } milli = trap_Milliseconds(); memcpy(textColor, colorWhite, sizeof (vec4_t)); // Mouse cursor position for MV highlighting (offset for cursor pointer position) // Also allow for swingcam toggling for (i = 0; i < cg.winHandler.numActiveWindows; ++i) { w = &cg.winHandler.window[cg.winHandler.activeWindows[i]]; if (!w->inuse || w->state == WSTATE_OFF) { fCleanup = qtrue; continue; } if (w->effects & WFX_TEXTSIZING) { CG_windowNormalizeOnText(w); w->effects &= ~WFX_TEXTSIZING; } bg = ((w->effects & WFX_FLASH) && (milli % w->flashPeriod) > w->flashMidpoint) ? &w->colorBackground2 : &w->colorBackground; h = w->h; x = w->x; y = w->y; t_offset = milli - w->time; textColor[3] = 1.0f; memcpy(&borderColor, w->colorBorder, sizeof (vec4_t)); memcpy(&bgColor, bg, sizeof (vec4_t)); // TODO: Add in support for ALL scrolling effects if (w->state == WSTATE_START) { tmp = w->targetTime - t_offset; if (w->effects & WFX_SCROLLUP) { if (tmp > 0) { y += (480 - y) * tmp / w->targetTime; } else { w->state = WSTATE_COMPLETE; } w->curY = y; } if (w->effects & WFX_FADEIN) { if (tmp > 0) { textColor[3] = (float)((float)t_offset / (float)w->targetTime); } else { w->state = WSTATE_COMPLETE; } } } else if (w->state == WSTATE_SHUTDOWN) { tmp = w->targetTime - t_offset; if (w->effects & WFX_SCROLLUP) { if (tmp > 0) { y = w->curY + (480 - w->y) * t_offset / w->targetTime; } if (tmp < 0 || y >= 480) { w->state = WSTATE_OFF; fCleanup = qtrue; continue; } } if (w->effects & WFX_FADEIN) { if (tmp > 0) { textColor[3] -= (float)((float)t_offset / (float)w->targetTime); } else { textColor[3] = 0.0f; w->state = WSTATE_OFF; } } } borderColor[3] *= textColor[3]; bgColor[3] *= textColor[3]; CG_FillRect(x, y, w->w, h, bgColor); CG_DrawRect(x, y, w->w, h, 1, borderColor); x += 5; y -= (w->effects & WFX_TRUETYPE) ? 3 : 0; for (j = w->lineCount - 1; j >= 0; --j) { if (w->effects & WFX_TRUETYPE) { CG_Text_Paint_Ext(x, y + h, w->fontScaleX, w->fontScaleY, textColor, (char *)w->lineText[j], 0.0f, 0, 0, &cgs.media.limboFont2); } h -= (w->lineHeight[j] + 3); if (!(w->effects & WFX_TRUETYPE)) { CG_DrawStringExt2(x, y + h, (char *)w->lineText[j], textColor, qfalse, qtrue, w->fontWidth, w->fontHeight, 0); } } } // Extra rate info CG_demoAviFPSDraw(); CG_demoTimescaleDraw(); if (fCleanup) { CG_windowCleanup(); } }
/* * CG_DrawScoreboard */ static void CG_DrawClientScore(int y, Score *score, float *color, float fade, qbool largeFormat) { char string[1024]; Vec3 headAngles; Clientinfo *ci; int iconx, headx; if(score->client < 0 || score->client >= cgs.maxclients){ comprintf("Bad score->client: %i\n", score->client); return; } ci = &cgs.clientinfo[score->client]; iconx = SB_BOTICON_X + (SB_RATING_WIDTH / 2); headx = SB_HEAD_X + (SB_RATING_WIDTH / 2); /* draw the handicap or bot skill marker (unless player has flag) */ if(ci->powerups & (1 << PW_NEUTRALFLAG)){ if(largeFormat) CG_DrawFlagModel(iconx, y - (32 - BIGCHAR_HEIGHT) / 2, 32, 32, TEAM_FREE, qfalse); else CG_DrawFlagModel(iconx, y, 16, 16, TEAM_FREE, qfalse); }else if(ci->powerups & (1 << PW_REDFLAG)){ if(largeFormat) CG_DrawFlagModel(iconx, y - (32 - BIGCHAR_HEIGHT) / 2, 32, 32, TEAM_RED, qfalse); else CG_DrawFlagModel(iconx, y, 16, 16, TEAM_RED, qfalse); }else if(ci->powerups & (1 << PW_BLUEFLAG)){ if(largeFormat) CG_DrawFlagModel(iconx, y - (32 - BIGCHAR_HEIGHT) / 2, 32, 32, TEAM_BLUE, qfalse); else CG_DrawFlagModel(iconx, y, 16, 16, TEAM_BLUE, qfalse); }else{ if(ci->botSkill > 0 && ci->botSkill <= 5){ if(cg_drawIcons.integer){ if(largeFormat) CG_DrawPic( iconx, y - (32 - BIGCHAR_HEIGHT) / 2, 32, 32, cgs.media.botSkillShaders[ ci-> botSkill - 1 ]); else CG_DrawPic( iconx, y, 16, 16, cgs.media.botSkillShaders[ ci-> botSkill - 1 ]); } }else if(ci->handicap < Maxhealth){ Q_sprintf(string, sizeof(string), "%i", ci->handicap); if(cgs.gametype == GT_TOURNAMENT) CG_DrawSmallStringColor(iconx, y - SMALLCHAR_HEIGHT/2, string, color); else CG_DrawSmallStringColor(iconx, y, string, color); } /* draw the wins / losses */ if(cgs.gametype == GT_TOURNAMENT){ Q_sprintf(string, sizeof(string), "%i/%i", ci->wins, ci->losses); if(ci->handicap < Maxhealth && !ci->botSkill) CG_DrawSmallStringColor(iconx, y + SMALLCHAR_HEIGHT/2, string, color); else CG_DrawSmallStringColor(iconx, y, string, color); } } /* draw the face */ clearv3(headAngles); headAngles[YAW] = 180; if(largeFormat) CG_DrawHead(headx, y - (ICON_SIZE - BIGCHAR_HEIGHT) / 2, ICON_SIZE, ICON_SIZE, score->client, headAngles); else CG_DrawHead(headx, y, 16, 16, score->client, headAngles); #ifdef MISSIONPACK /* draw the team task */ if(ci->teamTask != TEAMTASK_NONE){ if(ci->teamTask == TEAMTASK_OFFENSE) CG_DrawPic(headx + 48, y, 16, 16, cgs.media.assaultShader); else if(ci->teamTask == TEAMTASK_DEFENSE) CG_DrawPic(headx + 48, y, 16, 16, cgs.media.defendShader); } #endif /* draw the score line */ if(score->ping == -1) Q_sprintf(string, sizeof(string), " connecting %s", ci->name); else if(ci->team == TEAM_SPECTATOR) Q_sprintf(string, sizeof(string), " SPECT %3i %4i %s", score->ping, score->time, ci->name); else Q_sprintf(string, sizeof(string), "%5i %4i %4i %s", score->score, score->ping, score->time, ci->name); /* highlight your position */ if(score->client == cg.snap->ps.clientNum){ float hcolor[4]; int rank; localClient = qtrue; if(cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR || cgs.gametype >= GT_TEAM) rank = -1; else rank = cg.snap->ps.persistant[PERS_RANK] & ~RANK_TIED_FLAG; if(rank == 0){ hcolor[0] = 0; hcolor[1] = 0; hcolor[2] = 0.7f; }else if(rank == 1){ hcolor[0] = 0.7f; hcolor[1] = 0; hcolor[2] = 0; }else if(rank == 2){ hcolor[0] = 0.7f; hcolor[1] = 0.7f; hcolor[2] = 0; }else{ hcolor[0] = 0.7f; hcolor[1] = 0.7f; hcolor[2] = 0.7f; } hcolor[3] = fade * 0.7; CG_FillRect( SB_SCORELINE_X + BIGCHAR_WIDTH + (SB_RATING_WIDTH / 2), y, 640 - SB_SCORELINE_X - BIGCHAR_WIDTH, BIGCHAR_HEIGHT+1, hcolor); } CG_DrawBigString(SB_SCORELINE_X + (SB_RATING_WIDTH / 2), y, string, fade); /* add the "ready" marker for intermission exiting */ if(cg.snap->ps.stats[ STAT_CLIENTS_READY ] & (1 << score->client)) CG_DrawBigStringColor(iconx, y, "READY", color); }
static int WM_TeamScoreboard(int x, int y, team_t team, float fade, int maxrows, int absmaxrows) { vec4_t hcolor; float tempx, tempy; int i; int count = 0; int width = INFO_TOTAL_WIDTH; qboolean use_mini_chars = qfalse; 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; 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; } y += SMALLCHAR_HEIGHT + 2; cg.teamPlayers[team] = 0; for (i = 0; i < cg.numScores; i++) { if (team != cgs.clientinfo[cg.scores[i].client].team) { continue; } cg.teamPlayers[team]++; } 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) { 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 { 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; for (i = 0; i < cg.numScores && count < maxrows; i++) { if (team != cgs.clientinfo[cg.scores[i].client].team) { continue; } 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 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; } 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; }
static void CG_DrawStatsDebug(void) { int textWidth = 0; int i, x, y, w, h; if (!cg_debugSkills.integer) { return; } for (i = 0; i < 6; i++) { if (statsDebugTime[i] + 9000 > cg.time) { if (statsDebugTextWidth[i] > textWidth) { textWidth = statsDebugTextWidth[i]; } } } w = textWidth + 6; h = 9; x = 640 - w; y = (480 - 5 * (12 + 2) + 6 - 4) - 6 - h; // don't ask i = statsDebugPos; do { vec4_t colour; if (statsDebugTime[i] + 9000 <= cg.time) { break; } colour[0] = colour[1] = colour[2] = .5f; if (cg.time - statsDebugTime[i] > 5000) { colour[3] = .5f - .5f * ((cg.time - statsDebugTime[i] - 5000) / 4000.f); } else { colour[3] = .5f ; } CG_FillRect(x, y, w, h, colour); colour[0] = colour[1] = colour[2] = 1.f; if (cg.time - statsDebugTime[i] > 5000) { colour[3] = 1.f - ((cg.time - statsDebugTime[i] - 5000) / 4000.f); } else { colour[3] = 1.f ; } CG_Text_Paint_Ext(640.f - 3 - statsDebugTextWidth[i], y + h - 2, .15f, .15f, colour, statsDebugStrings[i], 0, 0, ITEM_TEXTSTYLE_NORMAL, &cgs.media.limboFont2); y -= h; i--; if (i < 0) { i = 6 - 1; } } while (i != statsDebugPos); }
int WM_DrawObjectives(int x, int y, int width, float fade) { const char *s; int rows; if (cg.snap->ps.pm_type == PM_INTERMISSION) { const char *s, *buf, *shader = NULL, *flagshader = NULL, *nameshader = NULL; rows = 8; y += SMALLCHAR_HEIGHT * (rows - 1); s = CG_ConfigString(CS_MULTI_MAPWINNER); buf = Info_ValueForKey(s, "winner"); if (atoi(buf) == -1) { // "ITS A TIE!"; } else if (atoi(buf)) { // "ALLIES"; flagshader = "ui/assets/portraits/allies_win_flag.tga"; nameshader = "ui/assets/portraits/text_allies.tga"; } else { // "AXIS"; flagshader = "ui/assets/portraits/axis_win_flag.tga"; nameshader = "ui/assets/portraits/text_axis.tga"; } y += SMALLCHAR_HEIGHT * ((rows - 2) / 2); if (flagshader) { CG_DrawPic(100 + cgs.wideXoffset, 10, 210, 136, trap_R_RegisterShaderNoMip(flagshader)); CG_DrawPic(325 + cgs.wideXoffset, 10, 210, 136, trap_R_RegisterShaderNoMip(flagshader)); } if (shader) { CG_DrawPic(229 + cgs.wideXoffset, 10, 182, 136, trap_R_RegisterShaderNoMip(shader)); } if (nameshader) { CG_DrawPic(140 + cgs.wideXoffset, 50, 127, 64, trap_R_RegisterShaderNoMip(nameshader)); CG_DrawPic(365 + cgs.wideXoffset, 50, 127, 64, trap_R_RegisterShaderNoMip("ui/assets/portraits/text_win.tga")); } return y; } // mission time & reinforce time else { int msec, mins, seconds, tens; rows = 1; CG_FillRect(x - 5, y - 2, width + 5, 21, clrUiBack); CG_FillRect(x - 5, y - 2, width + 5, 21, clrUiBar); CG_DrawRect_FixedBorder(x - 5, y - 2, width + 5, 21, 1, colorBlack); y += SMALLCHAR_HEIGHT * (rows - 1); if (cgs.timelimit > 0.0f) { 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; } else { msec = mins = tens = seconds = 0; } if (cgs.gamestate != GS_PLAYING) { s = va("%s %s", CG_TranslateString("MISSION TIME:"), CG_TranslateString("WARMUP")); } else if (msec < 0 && cgs.timelimit > 0.0f) { if (cgs.gamestate == GS_WAITING_FOR_PLAYERS) { s = va("%s %s", CG_TranslateString("MISSION TIME:"), CG_TranslateString("GAME STOPPED")); } else { 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_Text_Paint_Ext(x, y + 13, 0.25f, 0.25f, tclr, s, 0, 0, 0, &cgs.media.limboFont1); // FIXME: do a switch for gametype if (cgs.gametype != GT_WOLF_LMS) { if (cgs.clientinfo[cg.snap->ps.clientNum].team == TEAM_AXIS || cgs.clientinfo[cg.snap->ps.clientNum].team == TEAM_ALLIES) { msec = CG_CalculateReinfTime(qfalse) * 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_Text_Paint_Ext(640 - 20 - CG_Text_Width_Ext(s, 0.25f, 0, &cgs.media.limboFont1) + cgs.wideXoffset, y + 13, 0.25f, 0.25f, tclr, s, 0, 0, 0, &cgs.media.limboFont1); } } if (cgs.gametype == GT_WOLF_STOPWATCH) { int w; s = va("%s %i", CG_TranslateString("STOPWATCH ROUND"), cgs.currentRound + 1); w = CG_Text_Width_Ext(s, 0.25f, 0, &cgs.media.limboFont1); CG_Text_Paint_Ext(x + 300 - w * 0.5f, y + 13, 0.25f, 0.25f, tclr, s, 0, 0, 0, &cgs.media.limboFont1); } else if (cgs.gametype == GT_WOLF_LMS) { int w; s = va("%s %i %s %i-%i", CG_TranslateString("ROUND"), cgs.currentRound + 1, CG_TranslateString("SCORE"), cg.teamWonRounds[1], cg.teamWonRounds[0]); w = CG_Text_Width_Ext(s, 0.25f, 0, &cgs.media.limboFont1); CG_Text_Paint_Ext(x + 300 - w * 0.5f, y + 13, 0.25f, 0.25f, tclr, s, 0, 0, 0, &cgs.media.limboFont1); } else if (cgs.gametype == GT_WOLF_CAMPAIGN) { int w; s = va("MAP %i of %i", cgs.currentCampaignMap + 1, cgs.campaignData.mapCount); w = CG_Text_Width_Ext(s, 0.25f, 0, &cgs.media.limboFont1); CG_Text_Paint_Ext(x + 300 - w * 0.5f, y + 13, 0.25f, 0.25f, tclr, s, 0, 0, 0, &cgs.media.limboFont1); } // MAPVOTE else if (cgs.gametype == GT_WOLF_MAPVOTE) { int w; s = (cgs.mapVoteMapY ? va("MAP %i of %i", cgs.mapVoteMapX + 1, cgs.mapVoteMapY) : ""); w = CG_Text_Width_Ext(s, 0.25f, 0, &cgs.media.limboFont1); CG_Text_Paint_Ext(x + 300 - w * 0.5f, y + 13, 0.25f, 0.25f, tclr, s, 0, 0, 0, &cgs.media.limboFont1); } y += SMALLCHAR_HEIGHT * 2; } return y; }
static float CG_DrawFPS(float y) { static int previousTimes[MAX_FPS_FRAMES]; static int previous; static int index; static int oldSamples; char *s; int t = trap_Milliseconds(); // don't use serverTime, because that will be drifting to correct for internet lag changes, timescales, timedemos, etc int frameTime = t - previous; int x, w, w2; int samples = cg_drawFPS.integer; previous = t; if (samples < 4) { samples = 4; } if (samples > MAX_FPS_FRAMES) { samples = MAX_FPS_FRAMES; } if (samples != oldSamples) { index = 0; } oldSamples = samples; previousTimes[index % samples] = frameTime; index++; if (index > samples) { int i, fps; // average multiple frames together to smooth changes out a bit int total = 0; for (i = 0 ; i < samples ; ++i) { total += previousTimes[i]; } total = total ? total : 1; fps = 1000 * samples / total; s = va("%i FPS", fps); } else { s = "estimating"; } w = CG_Text_Width_Ext(s, 0.19f, 0, &cgs.media.limboFont1); w2 = (UPPERRIGHT_W > w) ? UPPERRIGHT_W : w; x = (int)(Ccg_WideX(UPPERRIGHT_X)) - w2 - 2; CG_FillRect(x, y, w2 + 5, 12 + 2, HUD_Background); CG_DrawRect_FixedBorder(x, y, w2 + 5, 12 + 2, 1, HUD_Border); CG_Text_Paint_Ext(x + ((w2 - w) / 2) + 2, y + 11, 0.19f, 0.19f, HUD_Text, s, 0, 0, 0, &cgs.media.limboFont1); return y + 12 + 4; }
/* New ETrun draw players function * * @author Nico */ static void WM_ETrun_DrawPlayers(int *x, int *y, fontInfo_t *font, s_timerunScores *orderedScores, int numScores) { char *s; int tempx = 0; float fontsize = 0.16f; int i = 0; int mil, min, sec; char status[MAX_QPATH] = { 0 }; // Draw "Players" s = "Players"; tempx = *x + INFO_TOTAL_WIDTH / 2 - CG_Text_Width_Ext(s, 0.25f, 0, &cgs.media.limboFont1) / 2; WM_ETrun_print(s, font, 0.25f, tempx, *y, qtrue, 0); WM_ETrun_newlines(1, y, SMALLCHAR_HEIGHT); // Draw player info headings background CG_FillRect(*x, *y, INFO_TOTAL_WIDTH, INFO_LINE_HEIGHT, clrUiBack); CG_DrawRect_FixedBorder(*x, *y, INFO_TOTAL_WIDTH, INFO_LINE_HEIGHT, 1, colorBlack); *y += INFO_LINE_HEIGHT - 2; // Draw player info headings tempx = *x; WM_ETrun_print("Name", font, fontsize, tempx, *y, qtrue, 0); tempx += INFO_PLAYER_WIDTH; WM_ETrun_print("Team", font, fontsize, tempx, *y, qtrue, 0); tempx += INFO_TEAM_WIDTH; WM_ETrun_print("Time", font, fontsize, tempx, *y, qtrue, 0); tempx += INFO_SCORE_WIDTH; WM_ETrun_print("Speed", font, fontsize, tempx, *y, qtrue, 0); tempx += INFO_SPEED_WIDTH; WM_ETrun_print("Ping", font, fontsize, tempx, *y, qtrue, 0); tempx += INFO_LATENCY_WIDTH; WM_ETrun_print("Status", font, fontsize, tempx, *y, qtrue, 0); tempx += INFO_STATE_WIDTH; for (i = 0; i < numScores; ++i) { qboolean drawFlag = qfalse; // Ignore spectators if (orderedScores[i].team == TEAM_SPECTATOR) { continue; } tempx = *x; *y += 4; // Draw background (highlight your line) CG_FillRect(*x, *y, INFO_TOTAL_WIDTH, INFO_LINE_HEIGHT, orderedScores[i].clientNum == cg.clientNum ? clrUiYou : clrUiBack); CG_DrawRect_FixedBorder(*x, *y, INFO_TOTAL_WIDTH, INFO_LINE_HEIGHT, 1, colorBlack); *y += INFO_LINE_HEIGHT - 2; // Nico, draw country flag if (cg_countryFlags.integer) { if (WM_ETrun_drawCountryFlag(tempx, *y, orderedScores[i].countryCode)) { tempx += 16; drawFlag = qtrue; } } // Nico, draw player name WM_ETrun_print(orderedScores[i].name, font, fontsize, tempx, *y, qtrue, drawFlag == qfalse ? NAME_MAX_LENGHT : NAME_MAX_LENGHT - 3); tempx += drawFlag == qfalse ? INFO_PLAYER_WIDTH : INFO_PLAYER_WIDTH - 16; // Nico, draw team if (orderedScores[i].team == TEAM_AXIS) { s = "^1Axis"; } else { s = "^4Allies"; } WM_ETrun_print(s, font, fontsize, tempx, *y, qtrue, 0); tempx += INFO_TEAM_WIDTH; // Nico, show best time if (orderedScores[i].timerunBestTime) { mil = orderedScores[i].timerunBestTime; min = mil / 60000; mil -= min * 60000; sec = mil / 1000; mil -= sec * 1000; s = va("^7%02d:%02d.%03d", min, sec, mil); } else { s = "-"; } WM_ETrun_print(s, font, fontsize, tempx, *y, qtrue, 0); tempx += INFO_SCORE_WIDTH; // Nico, draw best speed WM_ETrun_print(va("%d", orderedScores[i].timerunBestSpeed), font, fontsize, tempx, *y, qtrue, 0); tempx += INFO_SPEED_WIDTH; // Nico, draw ping WM_ETrun_print(WM_ETrun_coloredPing(orderedScores[i].ping), font, fontsize, tempx, *y, qtrue, 0); tempx += INFO_LATENCY_WIDTH; // Nico, reset status memset(status, 0, sizeof (status)); // Nico, draw status if (orderedScores[i].timerunStatus == 1) { Q_strcat(status, sizeof (status), "^2R "); } if (orderedScores[i].clientLogged == 1) { Q_strcat(status, sizeof (status), "^7L "); } if (orderedScores[i].clientCGaz == 1) { Q_strcat(status, sizeof (status), "^8C "); } if (orderedScores[i].clientHidden == 1) { Q_strcat(status, sizeof (status), "^9H "); } if (orderedScores[i].speclocked == 1) { Q_strcat(status, sizeof (status), "^bS "); } if (status[0] == '\0') { Q_strncpyz(status, "-", sizeof (status)); } WM_ETrun_print(status, font, fontsize, tempx, *y, qtrue, 0); tempx += INFO_STATE_WIDTH; } WM_ETrun_newlines(2, 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]; 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, 14, 14, cgs.media.objectiveShader); offset += 14; tempx += 14; maxchars -= 2; } if (cgs.gametype == GT_WOLF_GOLDY && ci->team == cgs.clientinfo[cg.clientNum].team && ci->gold > 0 && ci->health != -1) { CG_DrawPic(tempx - 1, y + 1, 14, 14, cgs.media.goldIcon); 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 - 1, 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) { CG_DrawPic(tempx - 1, y + 1, 14, 14, cgs.media.medicIcon); offset += 14; tempx += 14; 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 || cg.snap->ps.pm_type == PM_INTERMISSION #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("^7%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); } } }
// Main window-drawing handler void CG_windowDraw(void) { int h, x, y, i, j, milli, t_offset, tmp; cg_window_t *w; qboolean fCleanup = qfalse; #if FEATURE_MULTIVIEW qboolean fAllowMV = (cg.snap != NULL && cg.snap->ps.pm_type != PM_INTERMISSION); #endif vec4_t *bg; vec4_t textColor, borderColor, bgColor; if (cg.winHandler.numActiveWindows == 0) { // Draw these for demoplayback no matter what CG_demoAviFPSDraw(); CG_demoTimescaleDraw(); return; } milli = trap_Milliseconds(); memcpy(textColor, colorWhite, sizeof(vec4_t)); #if FEATURE_MULTIVIEW // Mouse cursor position for MV highlighting (offset for cursor pointer position) // Also allow for swingcam toggling if (cg.mvTotalClients > 0 && fAllowMV) { CG_cursorUpdate(); } #endif for (i = 0; i < cg.winHandler.numActiveWindows; i++) { w = &cg.winHandler.window[cg.winHandler.activeWindows[i]]; if (!w->inuse || w->state == WSTATE_OFF) { fCleanup = qtrue; continue; } #if FEATURE_MULTIVIEW // Multiview rendering has its own handling if (w->effects & WFX_MULTIVIEW) { if (w != cg.mvCurrentMainview && fAllowMV) { CG_mvDraw(w); } continue; } #endif if (w->effects & WFX_TEXTSIZING) { CG_windowNormalizeOnText(w); w->effects &= ~WFX_TEXTSIZING; } bg = ((w->effects & WFX_FLASH) && (milli % w->flashPeriod) > w->flashMidpoint) ? &w->colorBackground2 : &w->colorBackground; h = w->h; x = w->x; y = w->y; t_offset = milli - w->time; textColor[3] = 1.0f; memcpy(&borderColor, w->colorBorder, sizeof(vec4_t)); memcpy(&bgColor, bg, sizeof(vec4_t)); // TODO: Add in support for ALL scrolling effects if (w->state == WSTATE_START) { tmp = w->targetTime - t_offset; if (w->effects & WFX_SCROLLUP) { if (tmp > 0) { y += (SCREEN_HEIGHT - y) * tmp / w->targetTime; //(100 * tmp / w->targetTime) / 100; } else { w->state = WSTATE_COMPLETE; } w->curY = y; } if (w->effects & WFX_FADEIN) { if (tmp > 0) { textColor[3] = ((float)t_offset / (float)w->targetTime); } else { w->state = WSTATE_COMPLETE; } } } else if (w->state == WSTATE_SHUTDOWN) { tmp = w->targetTime - t_offset; if (w->effects & WFX_SCROLLUP) { if (tmp > 0) { y = w->curY + (SCREEN_HEIGHT - w->y) * t_offset / w->targetTime; //(100 * t_offset / w->targetTime) / 100; } if (tmp < 0 || y >= SCREEN_HEIGHT) { w->state = WSTATE_OFF; fCleanup = qtrue; continue; } } if (w->effects & WFX_FADEIN) { if (tmp > 0) { textColor[3] -= ((float)t_offset / (float)w->targetTime); } else { textColor[3] = 0.0f; w->state = WSTATE_OFF; } } } borderColor[3] *= textColor[3]; bgColor[3] *= textColor[3]; CG_FillRect(x, y, w->w, h, bgColor); CG_DrawRect(x, y, w->w, h, 1, borderColor); x += 5; y -= (w->effects & WFX_TRUETYPE) ? 3 : 0; for (j = w->lineCount - 1; j >= 0; j--) { if (w->effects & WFX_TRUETYPE) { CG_Text_Paint_Ext(x, y + h, w->fontScaleX, w->fontScaleY, textColor, w->lineText[j], 0.0f, 0, 0, &cgs.media.limboFont2); } h -= (w->lineHeight[j] + 3); if (!(w->effects & WFX_TRUETYPE)) { CG_Text_Paint_Ext(x, y + h, cg_fontScaleSP.value, cg_fontScaleSP.value, textColor, w->lineText[j], 0, 0, 0, &cgs.media.limboFont2); } } } #if FEATURE_MULTIVIEW // Wedge in MV info overlay if (cg.mvTotalClients > 0 && fAllowMV) { CG_mvOverlayDisplay(); } #endif // Extra rate info CG_demoAviFPSDraw(); CG_demoTimescaleDraw(); #if FEATURE_MULTIVIEW // Mouse cursor lays on top of everything if (cg.mvTotalClients > 0 && cg.time < cgs.cursorUpdate && fAllowMV) { CG_DrawPic(cgDC.cursorx, cgDC.cursory, 32, 32, cgs.media.cursorIcon); } #endif if (fCleanup) { CG_windowCleanup(); } }
void UI_DisplayContextCG::fillRect( float x, float y, float w, float h, const vec4_t color ) { CG_FillRect( x, y, w, h, color ); }
/* ================= CG_DrawTourneyScoreboard Draw the oversize scoreboard for tournements ================= */ void CG_DrawTourneyScoreboard( void ) { const char *s; vec4_t color; int min, tens, ones; const clientInfo_t *ci; int y; int i; // request more scores regularly if ( cg.scoresRequestTime + 2000 < cg.time ) { cg.scoresRequestTime = cg.time; trap_SendClientCommand( "score" ); } // draw the dialog background color[0] = color[1] = color[2] = 0; color[3] = 1; CG_FillRect( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, color ); color[0] = 1; color[1] = 1; color[2] = 1; color[3] = 1; // print the mesage of the day s = CG_ConfigString( CS_MOTD ); if ( !s[0] ) { s = "Scoreboard"; } // print optional title CG_CenterGiantLine( 8, s ); // print server time ones = cg.time / 1000; min = ones / 60; ones %= 60; tens = ones / 10; ones %= 10; s = va("%i:%i%i", min, tens, ones ); CG_CenterGiantLine( 64, s ); // print the two scores y = 160; if ( cgs.gametype >= GT_TEAM ) { // // teamplay scoreboard // CG_DrawStringExt( 8, y, "Red Team", color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0, &cgs.media.giantchar ); s = va("%i", cg.teamScores[0] ); CG_DrawStringExt( 632 - GIANT_WIDTH * strlen(s), y, s, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0, &cgs.media.giantchar ); y += 64; CG_DrawStringExt( 8, y, "Blue Team", color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0, &cgs.media.giantchar ); s = va("%i", cg.teamScores[1] ); CG_DrawStringExt( 632 - GIANT_WIDTH * strlen(s), y, s, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0, &cgs.media.giantchar ); } else { // // free for all scoreboard // for ( i = 0 ; i < MAX_CLIENTS ; i++ ) { ci = &cgs.clientinfo[i]; if ( !ci->infoValid ) { continue; } if ( ci->team != TEAM_FREE ) { continue; } CG_DrawStringExt( 8, y, ci->name, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0, &cgs.media.giantchar ); s = va("%i", ci->score ); CG_DrawStringExt( 632 - GIANT_WIDTH * strlen(s), y, s, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0, &cgs.media.giantchar ); y += 64; } } }
void CG_FilledBar( float x, float y, float w, float h, float *startColor, float *endColor, const float *bgColor, float frac, int flags ) { vec4_t backgroundcolor = {1, 1, 1, 0.25f}, colorAtPos; // colorAtPos is the lerped color if necessary if ( ( flags & BAR_BG ) && bgColor ) { // BAR_BG set, and color specified, use specified bg color Vector4Copy( bgColor, backgroundcolor ); } // hud alpha if ( !( flags & BAR_NOHUDALPHA ) ) { startColor[3] *= cg_hudAlpha.value; if ( endColor ) { endColor[3] *= cg_hudAlpha.value; } if ( backgroundcolor ) { backgroundcolor[3] *= cg_hudAlpha.value; } } if ( flags & BAR_LERP_COLOR ) { Vector4Average( startColor, endColor, frac, colorAtPos ); } // background if ( ( flags & BAR_BG ) ) { int indent = BAR_BORDERSIZE; // draw background at full size and shrink the remaining box to fit inside with a border. (alternate border may be specified by a BAR_BGSPACING_xx) CG_FillRect( x, y, w, h, backgroundcolor ); if ( flags & BAR_BGSPACING_X0Y0 ) { // fill the whole box (no border) } else if ( flags & BAR_BGSPACING_X0Y5 ) { // spacing created for weapon heat indent *= 3; y += indent; h -= ( 2 * indent ); } else { // default spacing of 2 units on each side x += indent; y += indent; w -= ( 2 * indent ); h -= ( 2 * indent ); } } // adjust for horiz/vertical and draw the fractional box if ( flags & BAR_VERT ) { if ( flags & BAR_LEFT ) { // TODO: remember to swap colors on the ends here y += ( h * ( 1 - frac ) ); } else if ( flags & BAR_CENTER ) { y += ( h * ( 1 - frac ) / 2 ); } if ( flags & BAR_LERP_COLOR ) { CG_FillRect( x, y, w, h * frac, colorAtPos ); } else { CG_FillRect( x, y, w, h * frac, startColor ); } } else { if ( flags & BAR_LEFT ) { // TODO: remember to swap colors on the ends here x += ( w * ( 1 - frac ) ); } else if ( flags & BAR_CENTER ) { x += ( w * ( 1 - frac ) / 2 ); } if ( flags & BAR_LERP_COLOR ) { CG_FillRect( x, y, w * frac, h, colorAtPos ); } else { CG_FillRect( x, y, w * frac, h, startColor ); } } }
void CG_DemoHelpDraw() { if(cg.demohelpWindow == SHOW_OFF) { return; } else { const char *help[] = { "^nTAB ^mscores", "^nF1-F5 ^mavidemo record", "^nF11-F12 ^mscreenshot", NULL, "^nKP_DOWN ^mslow down (--)", "^nKP_LEFT ^mslow down (-)", "^nKP_UP ^mspeed up (++)", "^nKP_RIGHT ^mspeed up (+)", "^nSPACE ^mnormal speed", NULL, "^nENTER ^mExternal view", "^nLFT/RGHT ^mChange angle", "^nUP/DOWN ^mMove in/out" }; const char *mvhelp[] = { NULL, "^nMOUSE1 ^mSelect/move view", "^nMOUSE2 ^mSwap w/main view", "^nMOUSE3 ^mToggle on/off", "^nSHIFT ^mHold to resize", "^nKP_PGUP ^mEnable a view", "^nKP_PGDN ^mClose a view" }; int i, x, y = 480, w, h; vec4_t bgColor = COLOR_BG; // window vec4_t borderColor = COLOR_BORDER; // window vec4_t bgColorTitle = COLOR_BG_TITLE; // titlebar vec4_t borderColorTitle = COLOR_BORDER_TITLE; // titlebar // Main header int hStyle = ITEM_TEXTSTYLE_SHADOWED; float hScale = 0.16f; float hScaleY = 0.21f; fontInfo_t *hFont = FONT_HEADER; vec4_t hdrColor2 = COLOR_HDR2; // text // Text settings int tStyle = ITEM_TEXTSTYLE_SHADOWED; int tSpacing = 9; // Should derive from CG_Text_Height_Ext float tScale = 0.19f; fontInfo_t *tFont = FONT_TEXT; vec4_t tColor = COLOR_TEXT; // text float diff = cg.fadeTime - trap_Milliseconds(); // FIXME: Should compute this beforehand w = DH_W + ((cg.mvTotalClients > 1) ? 12 : 0); x = 640 + DH_X - w; h = 2 + tSpacing + 2 + // Header 2 + 1 + tSpacing * (2 + (sizeof(help) + ((cg.mvTotalClients > 1) ? sizeof(mvhelp) : 0)) / sizeof(char *)) + 2; // Fade-in effects if(diff > 0.0f) { float scale = (diff / STATS_FADE_TIME); if(cg.demohelpWindow == SHOW_ON) { scale = 1.0f - scale; } bgColor[3] *= scale; bgColorTitle[3] *= scale; borderColor[3] *= scale; borderColorTitle[3] *= scale; hdrColor2[3] *= scale; tColor[3] *= scale; y += (DH_Y - h) * scale; } else if(cg.demohelpWindow == SHOW_SHUTDOWN) { cg.demohelpWindow = SHOW_OFF; return; } else { y += DH_Y - h; } CG_DrawRect(x, y, w, h, 1, borderColor); CG_FillRect(x, y, w, h, bgColor); // Header CG_FillRect(x, y, w, tSpacing + 4, bgColorTitle); CG_DrawRect(x, y, w, tSpacing + 4, 1, borderColorTitle); x += 4; y += 1; y += tSpacing; CG_Text_Paint_Ext(x, y, hScale, hScaleY, hdrColor2, "DEMO CONTROLS", 0.0f, 0, hStyle, hFont); y += 3; // Control info for(i=0; i<sizeof(help)/sizeof(char *); i++) { y += tSpacing; if(help[i] != NULL) { CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, (char*)help[i], 0.0f, 0, tStyle, tFont); } } if(cg.mvTotalClients > 1) { for(i=0; i<sizeof(mvhelp)/sizeof(char *); i++) { y += tSpacing; if(mvhelp[i] != NULL) { CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, (char*)mvhelp[i], 0.0f, 0, tStyle, tFont); } } } y += tSpacing * 2; CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, "^nBACKSPACE ^mhelp on/off", 0.0f, 0, tStyle, tFont); } }
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; int i, j; // To draw medals char buf[64]; // To draw medals 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 CG_FillRect(x - 5, y, (INFO_TOTAL_WIDTH + 5), MINICHAR_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_WARMUP || cgs.gamestate == GS_INTERMISSION ) ) { CG_DrawPic( tempx-2 + 1, 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 += 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; } } // GeoIP - draw flag before name if (score->ping != -1 && score->ping != 999 && cg_countryflags.integer) { if (cf_draw(tempx - 11, y - 10, fade, ci->clientNum)) { offset += 14; tempx += 14; maxchars -= 2; } } // draw name CG_DrawStringExt(tempx, y, ci->name, hcolor, qfalse, qfalse, MINICHAR_WIDTH, MINICHAR_HEIGHT, maxchars); // 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); } 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) * MINICHAR_WIDTH; 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.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR) { CG_DrawPic(tempx, y - 2, 12, 12, cgs.media.skillPics[SkillNumForClass(ci->cls)]); } 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; } if (score->ping == -1) { CG_DrawStringExt(tempx, y, "^1CONN", hcolor, qfalse, qfalse, MINICHAR_WIDTH, MINICHAR_HEIGHT, 0); } else if (score->scoreflags & 2) { CG_DrawStringExt(tempx, y, " ^4BOT", hcolor, qfalse, qfalse, MINICHAR_WIDTH, MINICHAR_HEIGHT, 0); } else { 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; } }
void CG_GameStatsDraw() { if(cgs.gamestats.show == SHOW_OFF) { return; } else { int i, x = GS_X + 4, y = GS_Y, h; gameStats_t *gs = &cgs.gamestats; vec4_t bgColor = COLOR_BG; // window vec4_t borderColor = COLOR_BORDER; // window vec4_t bgColorTitle = COLOR_BG_TITLE; // titlebar vec4_t borderColorTitle = COLOR_BORDER_TITLE; // titlebar // Main header int hStyle = ITEM_TEXTSTYLE_SHADOWED; float hScale = 0.16f; float hScaleY = 0.21f; fontInfo_t *hFont = FONT_HEADER; // Sub header int hStyle2 = 0; float hScale2 = 0.16f; float hScaleY2 = 0.20f; fontInfo_t *hFont2 = FONT_SUBHEADER; vec4_t hdrColor = COLOR_HDR; // text // vec4_t hdrColor2 = COLOR_HDR2; // text // Text settings int tStyle = ITEM_TEXTSTYLE_SHADOWED; int tSpacing = 9; // Should derive from CG_Text_Height_Ext float tScale = 0.19f; fontInfo_t *tFont = FONT_TEXT; vec4_t tColor = COLOR_TEXT; // text float diff = cgs.gamestats.fadeTime - cg.time; // FIXME: Should compute this beforehand h = 2 + tSpacing + 2 + // Header 2 + 2 + tSpacing + 2 + // Stats columns 1 + // Stats + extra tSpacing * ((gs->cWeapons > 0) ? gs->cWeapons : 1) + tSpacing * ((gs->fHasStats) ? 3 : 0) + ((cgs.gametype == GT_WOLF_LMS) ? 0 : ( 4 + 2 * tSpacing + // Rank/XP 1 + tSpacing + 4 + 2 * tSpacing + // Skill columns 1 + // Skillz tSpacing * ((gs->cSkills > 0) ? gs->cSkills : 1) ) ) + 2; // Fade-in effects if(diff > 0.0f) { float scale = (diff / STATS_FADE_TIME); if(cgs.gamestats.show == SHOW_ON) { scale = 1.0f - scale; } bgColor[3] *= scale; bgColorTitle[3] *= scale; borderColor[3] *= scale; borderColorTitle[3] *= scale; hdrColor[3] *= scale; tColor[3] *= scale; y -= h * (1.0f - scale); } else if(cgs.gamestats.show == SHOW_SHUTDOWN) { cgs.gamestats.show = SHOW_OFF; return; } CG_DrawRect(GS_X, y, GS_W, h, 1, borderColor); CG_FillRect(GS_X, y, GS_W, h, bgColor); // Header CG_FillRect(GS_X, y, GS_W, tSpacing+4, bgColorTitle); CG_DrawRect(GS_X, y, GS_W, tSpacing+4, 1, borderColorTitle); y += 1; y += tSpacing; CG_Text_Paint_Ext(x, y, hScale, hScaleY, hdrColor, "PLAYER STATS", 0.0f, 0, hStyle, hFont); y += 3; y += 2; // Weapon stats y += 2; CG_FillRect(GS_X, y, GS_W, tSpacing + 3, bgColorTitle); CG_DrawRect(GS_X, y, GS_W, tSpacing + 3, 1, borderColorTitle); y += 1 + tSpacing; CG_Text_Paint_Ext(x, y, hScale2, hScaleY2, hdrColor, "Weapon", 0.0f, 0, hStyle2, hFont2); x += 66; CG_Text_Paint_Ext(x, y, hScale2, hScaleY2, hdrColor, "Accuracy", 0.0f, 0, hStyle2, hFont2); x += 53; CG_Text_Paint_Ext(x, y, hScale2, hScaleY2, hdrColor, "Hits / Shots", 0.0f, 0, hStyle2, hFont2); x += 62; CG_Text_Paint_Ext(x, y, hScale2, hScaleY2, hdrColor, "Kills", 0.0f, 0, hStyle2, hFont2); x += 29; CG_Text_Paint_Ext(x, y, hScale2, hScaleY2, hdrColor, "Deaths", 0.0f, 0, hStyle2, hFont2); x += 40; CG_Text_Paint_Ext(x, y, hScale2, hScaleY2, hdrColor, "Headshots", 0.0f, 0, hStyle2, hFont2); x = GS_X + 4; y += 2; y += 1; if(gs->cWeapons == 0) { y += tSpacing; CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, "No weapon info available.", 0.0f, 0, tStyle, tFont); } else { for(i=0; i<gs->cWeapons; i++) { y += tSpacing; CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, gs->strWS[i], 0.0f, 0, tStyle, tFont); } if(gs->fHasStats) { y += tSpacing; for(i=0; i<2; i++) { y += tSpacing; CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, gs->strExtra[i], 0.0f, 0, tStyle, tFont); } } } // No rank/xp/skill info for LMS if(cgs.gametype == GT_WOLF_LMS) { return; } // Rank/XP info y += tSpacing; y += 2; CG_FillRect(GS_X, y, GS_W, tSpacing + 3, bgColorTitle); CG_DrawRect(GS_X, y, GS_W, tSpacing + 3, 1, borderColorTitle); y += 1 + tSpacing; CG_Text_Paint_Ext(x, y, hScale2, hScaleY2, hdrColor, "Rank", 0.0f, 0, hStyle2, hFont2); x += 82; CG_Text_Paint_Ext(x, y, hScale2, hScaleY2, hdrColor, "XP", 0.0f, 0, hStyle2, hFont2); x = GS_X + 4; y += 1; y += tSpacing; CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, gs->strRank, 0.0f, 0, tStyle, tFont); // Skill info y += tSpacing; y += 2; CG_FillRect(GS_X, y, GS_W, tSpacing + 3, bgColorTitle); CG_DrawRect(GS_X, y, GS_W, tSpacing + 3, 1, borderColorTitle); y += 1 + tSpacing; CG_Text_Paint_Ext(x, y, hScale2, hScaleY2, hdrColor, "Skills", 0.0f, 0, hStyle2, hFont2); x += 84; CG_Text_Paint_Ext(x, y, hScale2, hScaleY2, hdrColor, "Level", 0.0f, 0, hStyle2, hFont2); x += 40; CG_Text_Paint_Ext(x, y, hScale2, hScaleY2, hdrColor, "XP / Next Level", 0.0f, 0, hStyle2, hFont2); if(cgs.gametype == GT_WOLF_CAMPAIGN) { x += 86; CG_Text_Paint_Ext(x, y, hScale2, hScaleY2, hdrColor, "Medals", 0.0f, 0, hStyle2, hFont2); } x = GS_X + 4; y += 1; if(gs->cSkills == 0) { y += tSpacing; CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, "No skills acquired!", 0.0f, 0, tStyle, tFont); } else { for(i=0; i<gs->cSkills; i++) { y += tSpacing; CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, gs->strSkillz[i], 0.0f, 0, tStyle, tFont); } } } }
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 = 360; 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 SUCCESSFULLY BEAT THE CLOCK!"; // FIXME: translations } else { s = "ALLIES COULDN'T BEAT THE CLOCK!"; } } else { if (winner != defender) { s = "AXIS SUCCESSFULLY BEAT THE CLOCK!"; } else { s = "AXIS COULDN'T BEAT THE CLOCK!"; } } s = CG_TranslateString(s); } CG_FillRect(320 - w / 2, y, w, 20, clrUiBar); CG_DrawRect_FixedBorder(320 - w / 2, y, w, 20, 1, colorBlack); w = CG_Text_Width_Ext(s, 0.25f, 0, &cgs.media.limboFont1); CG_Text_Paint_Ext(320 - w * 0.5f, y + 15, 0.25f, 0.25f, tclr, s, 0, 0, 0, &cgs.media.limboFont1); return y + INFO_LINE_HEIGHT + 6; }
// Dens: objective display popup void CG_ObjectivesDraw() { const char* cs; char color[3]; int status; if(cgs.objectives.show == SHOW_OFF) { return; } else { int i, x = 640 + OBJ_X - OBJ_W, y = 480, h; int lines = 0, count = 0; char temp[1024], *s, *p; vec4_t bgColor = COLOR_BG; // window vec4_t borderColor = COLOR_BORDER; // window vec4_t bgColorTitle = COLOR_BG_TITLE; // titlebar vec4_t borderColorTitle = COLOR_BORDER_TITLE; // titlebar // Main header int hStyle = ITEM_TEXTSTYLE_SHADOWED; float hScale = 0.16f; float hScaleY = 0.21f; fontInfo_t *hFont = FONT_HEADER; vec4_t hdrColor = COLOR_HDR; // text vec4_t hdrColor2 = COLOR_HDR2; // text // Text settings int tStyle = ITEM_TEXTSTYLE_SHADOWED; int tSpacing = 9; // Should derive from CG_Text_Height_Ext float tScale = 0.19f; fontInfo_t *tFont = FONT_TEXT; vec4_t tColor = COLOR_TEXT; // text float diff = cgs.objectives.fadeTime - cg.time; if(cgs.clientinfo[cg.snap->ps.clientNum].team == TEAM_SPECTATOR){ Q_strncpyz(temp, cg.objMapDescription_Neutral ,sizeof(temp)); while ((s = strchr(temp, '*'))) { *s = '\n'; } CG_FitTextToWidth_Ext( temp, tScale, OBJ_W, sizeof(temp), FONT_TEXT ); p = temp; while(*p) { if(*p == '\n') { *p++ = '\0'; lines++; }else{ p++; } } if(temp[0]){ count++; } Q_strncpyz(temp, cg.objMapDescription_Allied,sizeof(temp)); while ((s = strchr(temp, '*'))) { *s = '\n'; } CG_FitTextToWidth_Ext( temp, tScale, OBJ_W, sizeof(temp), FONT_TEXT ); p = temp; while(*p) { if(*p == '\n') { *p++ = '\0'; lines++; }else{ p++; } } if(temp[0]){ lines += 1; // Allied count++; } Q_strncpyz(temp, cg.objMapDescription_Axis ,sizeof(temp)); while ((s = strchr(temp, '*'))) { *s = '\n'; } CG_FitTextToWidth_Ext( temp, tScale, OBJ_W, sizeof(temp), FONT_TEXT ); p = temp; while(*p) { if(*p == '\n') { *p++ = '\0'; lines++; }else{ p++; } } if(temp[0]){ lines += 1; // Axis count++; } }else if(cgs.clientinfo[cg.snap->ps.clientNum].team == TEAM_ALLIES){ for(i=0; i<MAX_OBJECTIVES && cg.objDescription_Allied[i][0] ;i++){ Q_strncpyz(temp, cg.objDescription_Allied[i] ,sizeof(temp)); // Dens: no double newlines... make the pop up look really bad while ((s = strstr(temp, "**"))) { *s = ' '; } while ((s = strchr(temp, '*'))) { *s = '\n'; } CG_FitTextToWidth_Ext( temp, tScale, OBJ_W, sizeof(temp), FONT_TEXT ); p = temp; while(*p) { if(*p == '\n') { *p++ = '\0'; lines++; }else{ p++; } } if(temp[0]){ count++; } } }else if(cgs.clientinfo[cg.snap->ps.clientNum].team == TEAM_AXIS){ for(i=0; i<MAX_OBJECTIVES && cg.objDescription_Axis[i][0] ;i++){ Q_strncpyz(temp, cg.objDescription_Axis[i] ,sizeof(temp)); while ((s = strstr(temp, "**"))) { *s = ' '; } while ((s = strchr(temp, '*'))) { *s = '\n'; } CG_FitTextToWidth_Ext( temp, tScale, OBJ_W, sizeof(temp), FONT_TEXT ); p = temp; while(*p) { if(*p == '\n') { *p++ = '\0'; lines++; }else{ p++; } } if(temp[0]){ count++; } } } // FIXME: Should compute this beforehand h = 2 + tSpacing + 2 + // Header 1 + tSpacing * (((lines + count - 1) > 0) ? (lines + count - 1) : 1) + 1 + 2; // Fade-in effects if(diff > 0.0f) { float scale = (diff / STATS_FADE_TIME); if(cgs.objectives.show == SHOW_ON) { scale = 1.0f - scale; } bgColor[3] *= scale; bgColorTitle[3] *= scale; borderColor[3] *= scale; borderColorTitle[3] *= scale; hdrColor[3] *= scale; hdrColor2[3] *= scale; tColor[3] *= scale; y += (TS_Y - h) * scale; } else if(cgs.objectives.show == SHOW_SHUTDOWN) { cgs.objectives.show = SHOW_OFF; return; } else { y += TS_Y - h; } CG_DrawRect(x, y, OBJ_W, h, 1, borderColor); CG_FillRect(x, y, OBJ_W, h, bgColor); // Header CG_FillRect(x, y, OBJ_W, tSpacing+4, bgColorTitle); CG_DrawRect(x, y, OBJ_W, tSpacing+4, 1, borderColorTitle); y += 1; y += tSpacing; CG_Text_Paint_Ext(x + 4, y, hScale, hScaleY, hdrColor, "OBJECTIVES", 0.0f, 0, hStyle, hFont); y += 4; if(!count){ y += tSpacing; CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, "Unable to load objectives", 0.0f, 0, tStyle, tFont); return; } cs = CG_ConfigString( CS_MULTI_OBJECTIVE ); if(cgs.clientinfo[cg.snap->ps.clientNum].team == TEAM_SPECTATOR){ Q_strncpyz(temp, cg.objMapDescription_Neutral ,sizeof(temp)); while ((s = strchr(temp, '*'))) { *s = '\n'; } CG_FitTextToWidth_Ext( temp, tScale, OBJ_W, sizeof(temp), FONT_TEXT ); s = p = temp; while(*p) { if(*p == '\n') { *p++ = '\0'; y += tSpacing; CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, s, 0.0f, 0, tStyle, tFont); s = p; } else { p++; } } if(temp[0] && count > 0){ count--; y += tSpacing; } Q_strncpyz(temp, cg.objMapDescription_Allied ,sizeof(temp)); while ((s = strchr(temp, '*'))) { *s = '\n'; } CG_FitTextToWidth_Ext( temp, tScale, OBJ_W, sizeof(temp), FONT_TEXT ); y += tSpacing; CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, "^4Allies", 0.0f, 0, tStyle, tFont); s = p = temp; while(*p) { if(*p == '\n') { *p++ = '\0'; y += tSpacing; CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, s, 0.0f, 0, tStyle, tFont); s = p; } else { p++; } } if(temp[0] && count > 0){ count--; y += tSpacing; } Q_strncpyz(temp, cg.objMapDescription_Axis ,sizeof(temp)); while ((s = strchr(temp, '*'))) { *s = '\n'; } CG_FitTextToWidth_Ext( temp, tScale, OBJ_W, sizeof(temp), FONT_TEXT ); y += tSpacing; CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, "^1Axis", 0.0f, 0, tStyle, tFont); s = p = temp; while(*p) { if(*p == '\n') { *p++ = '\0'; y += tSpacing; CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, s, 0.0f, 0, tStyle, tFont); s = p; } else { p++; } } if(temp[0] && count > 0){ count--; y += tSpacing; } }else if(cgs.clientinfo[cg.snap->ps.clientNum].team == TEAM_ALLIES){ for(i=0; i<MAX_OBJECTIVES && cg.objDescription_Allied[i][0] ;i++){ Q_strncpyz(temp, cg.objDescription_Allied[i] ,sizeof(temp)); while ((s = strstr(temp, "**"))) { *s = ' '; } while ((s = strchr(temp, '*'))) { *s = '\n'; } CG_FitTextToWidth_Ext( temp, tScale, OBJ_W, sizeof(temp), FONT_TEXT ); status = 0; color[0] = '\0'; status = atoi(Info_ValueForKey( cs, va( "a%i", i+1 ))); if(status == 1){ Q_strncpyz(color, "^2" ,sizeof(color)); }else if(status == 2){ Q_strncpyz(color, "^1" ,sizeof(color)); } s = p = temp; while(*p) { if(*p == '\n') { *p++ = '\0'; y += tSpacing; CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, va("%s%s",color[0] ? color : "", s), 0.0f, 0, tStyle, tFont); s = p; }else{ p++; } } if(temp[0] && count > 0){ count--; y += tSpacing; } } }else if(cgs.clientinfo[cg.snap->ps.clientNum].team == TEAM_AXIS){ for(i=0; i<MAX_OBJECTIVES && cg.objDescription_Axis[i][0] ;i++){ Q_strncpyz(temp, cg.objDescription_Axis[i] ,sizeof(temp)); while ((s = strstr(temp, "**"))) { *s = ' '; } while ((s = strchr(temp, '*'))) { *s = '\n'; } CG_FitTextToWidth_Ext( temp, tScale, OBJ_W, sizeof(temp), FONT_TEXT ); status = 0; color[0] = '\0'; status = atoi(Info_ValueForKey( cs, va( "x%i", i+1 ))); if(status == 1){ Q_strncpyz(color, "^2" ,sizeof(color)); }else if(status == 2){ Q_strncpyz(color, "^1" ,sizeof(color)); } s = p = temp; while(*p) { if(*p == '\n') { *p++ = '\0'; y += tSpacing; CG_Text_Paint_Ext(x, y, tScale, tScale, tColor, va("%s%s",color[0] ? color : "", s), 0.0f, 0, tStyle, tFont); s = p; }else{ p++; } } if(temp[0] && count > 0){ count--; y += tSpacing; } } } } }
/* ================= CG_DrawScoreboard ================= */ static void CG_DrawClientScore( int y, score_t *score, float *color, float fade, qboolean largeFormat ) { char string[1024]; vec3_t headAngles; clientInfo_t *ci; int iconx, headx; float scale = 0.35; int h = CG_Text_Height( "Tj", scale, 0 ); //int ty; if ( score->client < 0 || score->client >= cgs.maxclients ) { Com_Printf( "Bad score->client: %i\n", score->client ); return; } color[3] = fade; ci = &cgs.clientinfo[score->client]; iconx = SB_BOTICON_X + (SB_RATING_WIDTH / 2); headx = SB_HEAD_X + (SB_RATING_WIDTH / 2); // draw the handicap or bot skill marker (unless player has flag) if ( ci->powerups & ( 1 << PW_NEUTRALFLAG ) ) { if( largeFormat ) { CG_DrawFlagModel( iconx, y - SB_LARGE_SPACER, SB_LARGE_ICON, SB_LARGE_ICON, TEAM_FREE, qfalse, SCR_CENTER ); } else { CG_DrawFlagModel( iconx, y - SB_SMALL_SPACER, SB_SMALL_ICON, SB_SMALL_ICON, TEAM_FREE, qfalse, SCR_CENTER ); } } else if ( ci->powerups & ( 1 << PW_REDFLAG ) ) { if( largeFormat ) { CG_DrawFlagModel( iconx, y - SB_LARGE_SPACER, SB_LARGE_ICON, SB_LARGE_ICON, TEAM_RED, qfalse, SCR_CENTER ); } else { CG_DrawFlagModel( iconx, y - SB_SMALL_SPACER, SB_SMALL_ICON, SB_SMALL_ICON, TEAM_RED, qfalse, SCR_CENTER ); } } else if ( ci->powerups & ( 1 << PW_BLUEFLAG ) ) { if( largeFormat ) { CG_DrawFlagModel( iconx, y - SB_LARGE_SPACER, SB_LARGE_ICON, SB_LARGE_ICON, TEAM_BLUE, qfalse, SCR_CENTER ); } else { CG_DrawFlagModel( iconx, y - SB_SMALL_SPACER, SB_SMALL_ICON, SB_SMALL_ICON, TEAM_BLUE, qfalse, SCR_CENTER ); } } else { if ( ci->botSkill > 0 && ci->botSkill <= 5 ) { if ( cg_drawIcons.integer ) { if( largeFormat ) { CG_DrawColorPic( iconx, y - SB_LARGE_SPACER, SB_LARGE_ICON, SB_LARGE_ICON, cgs.media.botSkillShaders[ci->botSkill - 1], SCR_CENTER, color ); } else { CG_DrawColorPic( iconx, y - SB_SMALL_SPACER, SB_SMALL_ICON, SB_SMALL_ICON, cgs.media.botSkillShaders[ci->botSkill - 1], SCR_CENTER, color ); } } } else if ( ci->handicap < 100 ) { Com_sprintf( string, sizeof( string ), "%i", ci->handicap ); if ( gt[cgs.gametype].duel ) { if ( cg_highResFonts.integer ) { CG_Text_Paint( iconx, y + h + ((float)h/2), scale, color, string, 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER ); } else { CG_DrawSmallStringColor( iconx, y - SMALLCHAR_HEIGHT/2, string, color, SCR_CENTER ); } } else { if ( cg_highResFonts.integer ) { //w = CG_Text_Width(s, scale, 0); h = CG_Text_Height(string, scale, 0); CG_Text_Paint( iconx, y + h, scale, color, string, 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER ); } else { CG_DrawSmallStringColor( iconx, y, string, color, SCR_CENTER ); } } } // draw the wins / losses if ( gt[cgs.gametype].duel ) { Com_sprintf( string, sizeof( string ), "%i/%i", ci->wins, ci->losses ); if ( ci->handicap < 100 && !ci->botSkill ) { if ( cg_highResFonts.integer ) { CG_Text_Paint( iconx, y + h + ((float)h/2), scale, color, string, 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER ); } else { CG_DrawSmallStringColor( iconx, y + SMALLCHAR_HEIGHT/2, string, color, SCR_CENTER ); } } else { if ( cg_highResFonts.integer ) { CG_Text_Paint( iconx, y + h, scale, color, string, 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER ); } else { CG_DrawSmallStringColor( iconx, y, string, color, SCR_CENTER ); } } } } // draw the face VectorClear( headAngles ); headAngles[YAW] = 180; if ( largeFormat ) { CG_DrawHead( headx, y - SB_LARGE_SPACER*2, ICON_SIZE, ICON_SIZE, score->client, headAngles, SCR_CENTER, color ); } else { CG_DrawHead( headx, y + SB_SMALL_SPACER, SB_SMALL_ICON, SB_SMALL_ICON, score->client, headAngles, SCR_CENTER, color ); } // draw the score line // highlight your position if ( score->client == cg.snap->ps.clientNum ) { float hcolor[4]; int rank; localClient = qtrue; if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR ) { rank = -1; } else { rank = cg.snap->ps.persistant[PERS_RANK] & ~RANK_TIED_FLAG; } if ( rank == 0 ) { hcolor[0] = 0; hcolor[1] = 0; hcolor[2] = 0.7f; } else if ( rank == 1 ) { hcolor[0] = 0.7f; hcolor[1] = 0; hcolor[2] = 0; } else if ( rank == 2 ) { hcolor[0] = 0.7f; hcolor[1] = 0.7f; hcolor[2] = 0; } else { hcolor[0] = 0.4f; hcolor[1] = 0.4f; hcolor[2] = 0.4f; } hcolor[3] = fade * 0.7; /* CG_DrawTeamBackground( SB_SCORELINE_X + BIGCHAR_WIDTH + (SB_RATING_WIDTH / 2), y, SCREEN_WIDTH - SB_SCORELINE_X - BIGCHAR_WIDTH, BIGCHAR_HEIGHT+1, 1, gt[cgs.gametype].teams ? cg.snap->ps.persistant[PERS_TEAM] : hcolor, SCR_CENTER ); */ CG_FillRect( SB_SCORELINE_X + BIGCHAR_WIDTH + (SB_RATING_WIDTH / 2), y, SCREEN_WIDTH - SB_SCORELINE_X - BIGCHAR_WIDTH, BIGCHAR_HEIGHT+2, gt[cgs.gametype].teams ? CG_TeamColorDark(cg.snap->ps.persistant[PERS_TEAM], fade) : hcolor, SCR_CENTER ); } // draw client score strings if ( cg_highResFonts.integer ) { qboolean spec = ci->team == TEAM_SPECTATOR; int w; char *s; // score s = (score->ping == -1) ? "CONN" : spec ? "SPEC" : cg.warmup ? "-" : va("%i", score->score); w = CG_Text_Width( s, scale, 0 ); CG_Text_Paint( SB_SCORE_X + (SB_RATING_WIDTH / 2) + 64-w, y + h, scale, color, s, 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER ); // ping s = va( "%i", score->ping ); w = CG_Text_Width( s, scale, 0 ); CG_Text_Paint( SB_PING_X - (SB_RATING_WIDTH + BIGCHAR_WIDTH )/2 + 64-w, y + h, scale, color, s, 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER ); // time s = va( "%i", score->time ); //CG_IntToTime( score->time*1000, qtrue, qfalse ); w = CG_Text_Width( s, scale, 0 ); CG_Text_Paint( SB_TIME_X - (SB_RATING_WIDTH + BIGCHAR_WIDTH )/2 + 64-w, y + h, scale, color, s, 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER ); // name CG_Text_Paint( SB_NAME_X - (SB_RATING_WIDTH / 2), y + h, scale, color, ci->name, 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER ); } else { if ( score->ping == -1 ) { Com_sprintf(string, sizeof(string), " connecting %s", ci->name); } else if ( ci->team == TEAM_SPECTATOR ) { Com_sprintf(string, sizeof(string), " SPECT %3i %4i %s", score->ping, score->time, ci->name); } else { Com_sprintf(string, sizeof(string), "%5i %4i %4i %s", score->score, score->ping, score->time, ci->name); } CG_DrawBigString( SB_SCORELINE_X + (SB_RATING_WIDTH / 2), y, string, fade, SCR_CENTER ); } // add the "ready" marker for intermission exiting if ( cg.snap->ps.stats[STAT_CLIENTS_READY] & ( 1 << score->client ) ) { if ( cg_highResFonts.integer ) { CG_Text_Paint( iconx, y + h, scale, color, "READY", 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER ); } else { CG_DrawBigStringColor( iconx, y, "READY", color, SCR_CENTER ); } } }