void CG_DrawWeaponSelect( void ) { int i, bits, count, smallIconSize, bigIconSize, holdX, x, y, pad, sideLeftIconCnt, sideRightIconCnt, sideMax, holdCount, iconCnt, yOffset = 0; qboolean drewConc = qfalse; // can't cycle when on a weapon if ( cg.predictedPlayerState.emplacedIndex ) cg.weaponSelectTime = 0; // Time is up for the HUD to display if ( (cg.weaponSelectTime + WEAPON_SELECT_TIME) < cg.time ) return; // don't display if dead if ( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 ) return; // showing weapon select clears pickup item display, but not the blend blob cg.itemPickupTime = 0; bits = cg.predictedPlayerState.stats[STAT_WEAPONS]; // count the number of weapons owned count = 0; // display this weapon that we don't actually "have" as unhighlighted until it's deselected // since it's selected we must increase the count to display the proper number of valid selectable weapons if ( !CG_WeaponSelectable( cg.weaponSelect ) && (cg.weaponSelect == WP_THERMAL || cg.weaponSelect == WP_TRIP_MINE) ) count++; for ( i = 1; i < WP_NUM_WEAPONS; i++ ) { if ( bits & (1 << i) ) { if ( CG_WeaponSelectable( i ) || (i != WP_THERMAL && i != WP_TRIP_MINE) ) count++; } } if ( !count ) // If no weapons, don't display return; sideMax = 3; // Max number of icons on the side // Calculate how many icons will appear to either side of the center one holdCount = count - 1; // -1 for the center icon if ( holdCount == 0 ) { // No icons to either side sideLeftIconCnt = 0; sideRightIconCnt = 0; } else if ( count > (2 * sideMax) ) { // Go to the max on each side sideLeftIconCnt = sideMax; sideRightIconCnt = sideMax; } else { // Less than max, so do the calc sideLeftIconCnt = holdCount / 2; sideRightIconCnt = holdCount - sideLeftIconCnt; } if ( cg.weaponSelect == WP_CONCUSSION ) i = WP_FLECHETTE; else i = cg.weaponSelect - 1; if ( i < 1 ) i = LAST_USEABLE_WEAPON; smallIconSize = 40; bigIconSize = 80; pad = 12; x = (SCREEN_WIDTH / 2); y = 410; // Left side ICONS trap->R_SetColor( &colorTable[CT_WHITE] ); // Work backwards from current icon holdX = x - ((bigIconSize / 2) + pad + smallIconSize) * cgs.widthRatioCoef; drewConc = qfalse; for ( iconCnt = 1; iconCnt < (sideLeftIconCnt + 1); i-- ) { if ( i == WP_CONCUSSION ) i--; else if ( i == WP_FLECHETTE && !drewConc && cg.weaponSelect != WP_CONCUSSION ) i = WP_CONCUSSION; if ( i < 1 ) i = LAST_USEABLE_WEAPON; // Does he have this weapon? if ( !(bits & (1 << i)) ) { if ( i == WP_CONCUSSION ) { drewConc = qtrue; i = WP_ROCKET_LAUNCHER; } continue; } // Don't show thermal and tripmine when out of them if ( !CG_WeaponSelectable( i ) && (i == WP_THERMAL || i == WP_TRIP_MINE) ) continue; ++iconCnt; // Good icon if ( media.gfx.interface.weaponIcons[i] ) { CG_RegisterWeapon( i ); trap->R_SetColor( &colorTable[CT_WHITE] ); if ( !CG_WeaponCheck( i ) ) CG_DrawPic(holdX, y + 10 + yOffset, smallIconSize * cgs.widthRatioCoef, smallIconSize, media.gfx.interface.weaponIconsInactive[i]); else CG_DrawPic(holdX, y + 10 + yOffset, smallIconSize * cgs.widthRatioCoef, smallIconSize, media.gfx.interface.weaponIcons[i]); holdX -= (smallIconSize + pad) * cgs.widthRatioCoef; } if ( i == WP_CONCUSSION ) { drewConc = qtrue; i = WP_ROCKET_LAUNCHER; } } // Current Center Icon if ( media.gfx.interface.weaponIcons[cg.weaponSelect] ) { CG_RegisterWeapon( cg.weaponSelect ); trap->R_SetColor( &colorTable[CT_WHITE] ); if ( !CG_WeaponCheck( cg.weaponSelect ) ) CG_DrawPic(x - (bigIconSize / 2 * cgs.widthRatioCoef), (y - ((bigIconSize - smallIconSize) / 2)) + 10 + yOffset, bigIconSize * cgs.widthRatioCoef, bigIconSize, media.gfx.interface.weaponIconsInactive[cg.weaponSelect]); else CG_DrawPic(x - (bigIconSize / 2 * cgs.widthRatioCoef), (y - ((bigIconSize - smallIconSize) / 2)) + 10 + yOffset, bigIconSize * cgs.widthRatioCoef, bigIconSize, media.gfx.interface.weaponIcons[cg.weaponSelect]); } if ( cg.weaponSelect == WP_CONCUSSION ) i = WP_ROCKET_LAUNCHER; else i = cg.weaponSelect + 1; if ( i > LAST_USEABLE_WEAPON ) i = 1; // Right side ICONS // Work forwards from current icon holdX = x + ((bigIconSize / 2) + pad) * cgs.widthRatioCoef; for ( iconCnt = 1; iconCnt<(sideRightIconCnt + 1); i++ ) { if ( i == WP_CONCUSSION ) i++; else if ( i == WP_ROCKET_LAUNCHER && !drewConc && cg.weaponSelect != WP_CONCUSSION ) i = WP_CONCUSSION; if ( i > LAST_USEABLE_WEAPON ) i = 1; if ( !(bits & (1 << i)) ) { if ( i == WP_CONCUSSION ) { drewConc = qtrue; i = WP_FLECHETTE; } continue; } // Don't show thermal and tripmine when out of them if ( !CG_WeaponSelectable( i ) && (i == WP_THERMAL || i == WP_TRIP_MINE) ) continue; ++iconCnt; // Good icon if ( media.gfx.interface.weaponIcons[i] ) { CG_RegisterWeapon( i ); // No ammo for this weapon? trap->R_SetColor( &colorTable[CT_WHITE] ); if ( !CG_WeaponCheck( i ) ) CG_DrawPic(holdX, y + 10 + yOffset, smallIconSize * cgs.widthRatioCoef, smallIconSize, media.gfx.interface.weaponIconsInactive[i]); else CG_DrawPic(holdX, y + 10 + yOffset, smallIconSize * cgs.widthRatioCoef, smallIconSize, media.gfx.interface.weaponIcons[i]); holdX += (smallIconSize + pad); } if ( i == WP_CONCUSSION ) { drewConc = qtrue; i = WP_FLECHETTE; } } // draw the selected name if ( cg_weapons[cg.weaponSelect].item ) { vector4 textColor = { .875f, .718f, .121f, 1.0f }; char upperKey[1024]; Com_sprintf( upperKey, sizeof(upperKey), "SP_INGAME_%s", cg_weapons[cg.weaponSelect].item->classname ); Q_strupr( upperKey ); const char *s = nullptr; char text[1024]; if ( trap->SE_GetStringTextString( upperKey, text, sizeof(text) ) ) { s = text; } else { s = cg_weapons[cg.weaponSelect].item->classname; } const Font font( FONT_SMALL, 1.0f, false ); const float width = font.Width( s ); font.Paint( (SCREEN_WIDTH / 2) - (width / 2.0f), y + 45 + yOffset, s, &textColor, ITEM_TEXTSTYLE_SHADOWED ); } trap->R_SetColor( NULL ); }
/* ======================================================================================================================================= CG_DrawOldScoreboard Draw the normal in-game scoreboard. ======================================================================================================================================= */ qboolean CG_DrawOldScoreboard(void) { int x, y, w, i, n1, n2; float fade; float *fadeColor; char *s; int maxClients; int lineHeight; int topBorderSize, bottomBorderSize; // don't draw amuthing if the menu or console is up if (cg_paused.integer) { cg.deferredPlayerLoading = 0; return qfalse; } if (cgs.gametype == GT_SINGLE_PLAYER && cg.predictedPlayerState.pm_type == PM_INTERMISSION) { cg.deferredPlayerLoading = 0; return qfalse; } // don't draw scoreboard during death while warmup up if (cg.warmup && !cg.showScores) { return qfalse; } if (cg.showScores || cg.predictedPlayerState.pm_type == PM_DEAD || cg.predictedPlayerState.pm_type == PM_INTERMISSION) { fade = 1.0; fadeColor = colorWhite; } else { fadeColor = CG_FadeColor(cg.scoreFadeTime, FADE_TIME); if (!fadeColor) { // next time scoreboard comes up, don't print killer cg.deferredPlayerLoading = 0; cg.killerName[0] = 0; return qfalse; } fade = *fadeColor; } // fragged by ... line if (cg.killerName[0]) { s = va("Fragged by %s", cg.killerName); w = CG_DrawStrlen(s) * BIGCHAR_WIDTH; x = (SCREEN_WIDTH - w) / 2; y = 40; CG_DrawBigString(x, y, s, fade); } // current rank if (cgs.gametype < GT_TEAM) { if (cg.snap->ps.persistant[PERS_TEAM] != TEAM_SPECTATOR) { s = va("%s place with %i", CG_PlaceString(cg.snap->ps.persistant[PERS_RANK] + 1), cg.snap->ps.persistant[PERS_SCORE]); w = CG_DrawStrlen(s) * BIGCHAR_WIDTH; x = (SCREEN_WIDTH - w) / 2; y = 60; CG_DrawBigString(x, y, s, fade); } } else { if (cg.teamScores[0] == cg.teamScores[1]) { s = va("Teams are tied at %i", cg.teamScores[0]); } else if (cg.teamScores[0] >= cg.teamScores[1]) { s = va("Red leads %i to %i", cg.teamScores[0], cg.teamScores[1]); } else { s = va("Blue leads %i to %i", cg.teamScores[1], cg.teamScores[0]); } w = CG_DrawStrlen(s) * BIGCHAR_WIDTH; x = (SCREEN_WIDTH - w) / 2; y = 60; CG_DrawBigString(x, y, s, fade); } // scoreboard y = SB_HEADER; CG_DrawPic(SB_SCORE_X + (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardScore); CG_DrawPic(SB_PING_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardPing); CG_DrawPic(SB_TIME_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardTime); CG_DrawPic(SB_NAME_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardName); y = SB_TOP; // If there are more than SB_MAXCLIENTS_NORMAL, use the interleaved scores if (cg.numScores > SB_MAXCLIENTS_NORMAL) { maxClients = SB_MAXCLIENTS_INTER; lineHeight = SB_INTER_HEIGHT; topBorderSize = 8; bottomBorderSize = 16; } else { maxClients = SB_MAXCLIENTS_NORMAL; lineHeight = SB_NORMAL_HEIGHT; topBorderSize = 16; bottomBorderSize = 16; } localClient = qfalse; if (cgs.gametype >= GT_TEAM) { // teamplay scoreboard y += lineHeight / 2; if (cg.teamScores[0] >= cg.teamScores[1]) { n1 = CG_TeamScoreboard(y, TEAM_RED, fade, maxClients, lineHeight); CG_DrawTeamBackground(0, y - topBorderSize, 640, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; maxClients -= n1; n2 = CG_TeamScoreboard(y, TEAM_BLUE, fade, maxClients, lineHeight); CG_DrawTeamBackground(0, y - topBorderSize, 640, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE); y += (n2 * lineHeight) + BIGCHAR_HEIGHT; maxClients -= n2; } else { n1 = CG_TeamScoreboard(y, TEAM_BLUE, fade, maxClients, lineHeight); CG_DrawTeamBackground(0, y - topBorderSize, 640, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; maxClients -= n1; n2 = CG_TeamScoreboard(y, TEAM_RED, fade, maxClients, lineHeight); CG_DrawTeamBackground(0, y - topBorderSize, 640, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED); y += (n2 * lineHeight) + BIGCHAR_HEIGHT; maxClients -= n2; } n1 = CG_TeamScoreboard(y, TEAM_SPECTATOR, fade, maxClients, lineHeight); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; } else { // free for all scoreboard n1 = CG_TeamScoreboard(y, TEAM_FREE, fade, maxClients, lineHeight); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; n2 = CG_TeamScoreboard(y, TEAM_SPECTATOR, fade, maxClients - n1, lineHeight); y += (n2 * lineHeight) + BIGCHAR_HEIGHT; } if (!localClient) { // draw local client at the bottom for (i = 0; i < cg.numScores; i++) { if (cg.scores[i].client == cg.snap->ps.clientNum) { CG_DrawClientScore(y, &cg.scores[i], fadeColor, fade, lineHeight == SB_NORMAL_HEIGHT); break; } } } // load any models that have been deferred if (++cg.deferredPlayerLoading > 10) { CG_LoadDeferredPlayers(); } return qtrue; }
void CG_DrawConnectScreen(qboolean interactive, qboolean forcerefresh) { static qboolean inside = qfalse; char buffer[1024]; if (!DC) { return; } if (inside) { return; } inside = qtrue; if (!bg_loadscreeninited) { trap_Cvar_Set("ui_connecting", "0"); RegisterFont("ariblk", 27, &cgs.media.bg_loadscreenfont1); RegisterFont("courbd", 30, &cgs.media.bg_loadscreenfont2); bg_axispin = DC->registerShaderNoMip("gfx/loading/pin_axis"); bg_alliedpin = DC->registerShaderNoMip("gfx/loading/pin_allied"); bg_neutralpin = DC->registerShaderNoMip("gfx/loading/pin_neutral"); bg_pin = DC->registerShaderNoMip("gfx/loading/pin_shot"); bg_filter_bo = DC->registerShaderNoMip("ui/assets/filter_bots"); bg_filter_ff = DC->registerShaderNoMip("ui/assets/filter_ff"); bg_filter_hw = DC->registerShaderNoMip("ui/assets/filter_weap"); bg_filter_lv = DC->registerShaderNoMip("ui/assets/filter_lives"); bg_filter_al = DC->registerShaderNoMip("ui/assets/filter_antilag"); bg_filter_bt = DC->registerShaderNoMip("ui/assets/filter_balance"); bg_mappic = 0; BG_PanelButtonsSetup(loadpanelButtons); C_PanelButtonsSetup(loadpanelButtons, cgs.wideXoffset); bg_loadscreeninited = qtrue; } BG_PanelButtonsRender(loadpanelButtons); if (interactive) { DC->drawHandlePic(DC->cursorx, DC->cursory, 32, 32, DC->Assets.cursor); } DC->getConfigString(CS_SERVERINFO, buffer, sizeof(buffer)); if (*buffer) { const char *str; float x = 540.0f + cgs.wideXoffset; float y = 322; int i; qboolean enabled = qfalse; CG_Text_Paint_Centred_Ext(x, y, 0.22f, 0.22f, clr3, ("^1" LEGACY_MOD " ^0" ETLEGACY_VERSION), 0, 0, 0, &cgs.media.bg_loadscreenfont1); y = 340; str = Info_ValueForKey(buffer, "sv_hostname"); CG_Text_Paint_Centred_Ext(x, y, 0.2f, 0.2f, colorWhite, str && *str ? str : "ETHost", 0, 26, 0, &cgs.media.bg_loadscreenfont2); y += 14; for (i = 0; i < MAX_MOTDLINES; i++) { str = CG_ConfigString(CS_CUSTMOTD + i); if (!str || !*str) { break; } CG_Text_Paint_Centred_Ext(x, y, 0.2f, 0.2f, colorWhite, str, 0, 26, 0, &cgs.media.bg_loadscreenfont2); y += 10; } y = 417; str = Info_ValueForKey(buffer, "g_friendlyfire"); if (str && *str && atoi(str)) { x = 461 + cgs.wideXoffset; CG_DrawPic(x, y, 16, 16, bg_filter_ff); } if (atoi(Info_ValueForKey(buffer, "g_gametype")) != GT_WOLF_LMS) { str = Info_ValueForKey(buffer, "g_maxlives"); if (str && *str && atoi(str)) { enabled = qtrue; } if (!enabled) { str = Info_ValueForKey(buffer, "g_alliedmaxlives"); if (str && *str && atoi(str)) { enabled = qtrue; } } if (!enabled) { str = Info_ValueForKey(buffer, "g_axismaxlives"); if (str && *str && atoi(str)) { enabled = qtrue; } } } if (enabled) { x = 489 + cgs.wideXoffset; CG_DrawPic(x, y, 16, 16, bg_filter_lv); } str = Info_ValueForKey(buffer, "omnibot_playing"); if (str && *str && atoi(str)) { x = 518 + cgs.wideXoffset; CG_DrawPic(x, y, 16, 16, bg_filter_bo); } str = Info_ValueForKey(buffer, "g_heavyWeaponRestriction"); if (str && *str && atoi(str) != 100) { x = 546 + cgs.wideXoffset; CG_DrawPic(x, y, 16, 16, bg_filter_hw); } str = Info_ValueForKey(buffer, "g_antilag"); if (str && *str && atoi(str)) { x = 575 + cgs.wideXoffset; CG_DrawPic(x, y, 16, 16, bg_filter_al); } str = Info_ValueForKey(buffer, "g_balancedteams"); if (str && *str && atoi(str)) { x = 604 + cgs.wideXoffset; CG_DrawPic(x, y, 16, 16, bg_filter_bt); } } if (*cgs.rawmapname) { float x = 16 + cgs.wideXoffset + 1; if (!bg_mappic) { bg_mappic = DC->registerShaderNoMip(va("levelshots/%s", cgs.rawmapname)); if (!bg_mappic) { bg_mappic = DC->registerShaderNoMip("levelshots/unknownmap"); } } trap_R_SetColor(colorBlack); CG_DrawPic(x, 2 + 1, 192, 144, bg_mappic); trap_R_SetColor(NULL); x = 16 + cgs.wideXoffset; CG_DrawPic(x, 2, 192, 144, bg_mappic); x = 16 + cgs.wideXoffset + 80; CG_DrawPic(x, 2 + 6, 20, 20, bg_pin); } if (forcerefresh) { DC->updateScreen(); } inside = qfalse; }
/* ============== CG_DrawCursorHints cg_cursorHints.integer == 0: no hints 1: sin size pulse 2: one way size pulse 3: alpha pulse 4+: static image ============== */ void CG_DrawCursorhint(rectDef_t *rect) { float *color; qhandle_t icon, icon2 = 0; float scale, halfscale; float middle = rect->x + cgs.wideXoffset; if (!cg_cursorHints.integer) { return; } CG_CheckForCursorHints(); switch (cg.cursorHintIcon) { case HINT_NONE: case HINT_FORCENONE: icon = 0; break; case HINT_DOOR: icon = cgs.media.doorHintShader; break; case HINT_DOOR_ROTATING: icon = cgs.media.doorRotateHintShader; break; case HINT_DOOR_LOCKED: icon = cgs.media.doorLockHintShader; break; case HINT_DOOR_ROTATING_LOCKED: icon = cgs.media.doorRotateLockHintShader; break; case HINT_MG42: icon = cgs.media.mg42HintShader; break; case HINT_BREAKABLE: icon = cgs.media.breakableHintShader; break; case HINT_BREAKABLE_DYNAMITE: icon = cgs.media.dynamiteHintShader; break; case HINT_TANK: icon = cgs.media.tankHintShader; break; case HINT_SATCHELCHARGE: icon = cgs.media.satchelchargeHintShader; break; case HINT_CONSTRUCTIBLE: icon = cgs.media.buildHintShader; break; case HINT_UNIFORM: icon = cgs.media.uniformHintShader; break; case HINT_LANDMINE: icon = cgs.media.landmineHintShader; break; case HINT_CHAIR: icon = cgs.media.notUsableHintShader; break; case HINT_ALARM: icon = cgs.media.alarmHintShader; break; case HINT_HEALTH: icon = cgs.media.healthHintShader; break; case HINT_TREASURE: icon = cgs.media.treasureHintShader; break; case HINT_KNIFE: icon = cgs.media.knifeHintShader; break; case HINT_LADDER: icon = cgs.media.ladderHintShader; break; case HINT_BUTTON: icon = cgs.media.buttonHintShader; break; case HINT_WATER: icon = cgs.media.waterHintShader; break; case HINT_CAUTION: icon = cgs.media.cautionHintShader; break; case HINT_DANGER: icon = cgs.media.dangerHintShader; break; case HINT_SECRET: icon = cgs.media.secretHintShader; break; case HINT_QUESTION: icon = cgs.media.qeustionHintShader; break; case HINT_EXCLAMATION: icon = cgs.media.exclamationHintShader; break; case HINT_CLIPBOARD: icon = cgs.media.clipboardHintShader; break; case HINT_WEAPON: icon = cgs.media.weaponHintShader; break; case HINT_AMMO: icon = cgs.media.ammoHintShader; break; case HINT_ARMOR: icon = cgs.media.armorHintShader; break; case HINT_POWERUP: icon = cgs.media.powerupHintShader; break; case HINT_HOLDABLE: icon = cgs.media.holdableHintShader; break; case HINT_INVENTORY: icon = cgs.media.inventoryHintShader; break; case HINT_PLYR_FRIEND: case HINT_PLYR_NEUTRAL: case HINT_PLYR_ENEMY: case HINT_PLYR_UNKNOWN: return; // multiplayer hints case HINT_BUILD: icon = cgs.media.buildHintShader; break; case HINT_DISARM: icon = cgs.media.disarmHintShader; break; case HINT_REVIVE: icon = cgs.media.reviveHintShader; break; case HINT_DYNAMITE: icon = cgs.media.dynamiteHintShader; break; case HINT_ACTIVATE: case HINT_PLAYER: default: icon = cgs.media.usableHintShader; break; } if (!icon) { return; } // color color = CG_FadeColor(cg.cursorHintTime, cg.cursorHintFade); if (!color) { trap_R_SetColor(NULL); return; } if (cg_cursorHints.integer == 3) { color[3] *= 0.5 + 0.5 * sin((float)cg.time / 150.0); } // size if (cg_cursorHints.integer >= 3) // no size pulsing { scale = halfscale = 0; } else { if (cg_cursorHints.integer == 2) { scale = (float)((cg.cursorHintTime) % 1000) / 100.0f; // one way size pulse } else { scale = CURSORHINT_SCALE * (0.5 + 0.5 * sin((float)cg.time / 150.0)); // sin pulse } halfscale = scale * 0.5f; } // set color and draw the hint trap_R_SetColor(color); CG_DrawPic(middle - halfscale, rect->y - halfscale, rect->w + scale, rect->h + scale, icon); if (icon2) { CG_DrawPic(middle - halfscale, rect->y - halfscale, rect->w + scale, rect->h + scale, icon2); } trap_R_SetColor(NULL); // draw status bar under the cursor hint if (cg.cursorHintValue) { vec4_t backG = { 1, 1, 1, 0.3f }; float curValue = (float)cg.cursorHintValue / 255.0f; if (curValue > 0.01f) { CG_FilledBar(middle, rect->y + rect->h + 4, rect->w, 8, colorRed, colorGreen, backG, curValue, BAR_BORDER_SMALL | BAR_LERP_COLOR); } } }
/* ============= CG_Scanner ============= */ void CG_Scanner( rectDef_t *rect, qhandle_t shader, vec4_t color ) { int i; vec3_t origin; vec3_t relOrigin; vec4_t hIabove; vec4_t hIbelow; vec4_t aIabove = { 1.0f, 0.0f, 0.0f, 0.75f }; vec4_t aIbelow = { 1.0f, 0.0f, 0.0f, 0.5f }; Vector4Copy( color, hIabove ); hIabove[ 3 ] *= 1.5f; Vector4Copy( color, hIbelow ); VectorCopy( entityPositions.origin, origin ); //draw human buildables below scanner plane for( i = 0; i < entityPositions.numHumanBuildables; i++ ) { VectorClear( relOrigin ); VectorSubtract( entityPositions.humanBuildablePos[ i ], origin, relOrigin ); if( VectorLength( relOrigin ) < SCANNER_RANGE && ( relOrigin[ 2 ] < 0 ) ) CG_DrawBlips( rect, relOrigin, hIbelow ); } //draw alien buildables below scanner plane for( i = 0; i < entityPositions.numAlienBuildables; i++ ) { VectorClear( relOrigin ); VectorSubtract( entityPositions.alienBuildablePos[ i ], origin, relOrigin ); if( VectorLength( relOrigin ) < SCANNER_RANGE && ( relOrigin[ 2 ] < 0 ) ) CG_DrawBlips( rect, relOrigin, aIbelow ); } //draw human clients below scanner plane for( i = 0; i < entityPositions.numHumanClients; i++ ) { VectorClear( relOrigin ); VectorSubtract( entityPositions.humanClientPos[ i ], origin, relOrigin ); if( VectorLength( relOrigin ) < SCANNER_RANGE && ( relOrigin[ 2 ] < 0 ) ) CG_DrawBlips( rect, relOrigin, hIbelow ); } //draw alien buildables below scanner plane for( i = 0; i < entityPositions.numAlienClients; i++ ) { VectorClear( relOrigin ); VectorSubtract( entityPositions.alienClientPos[ i ], origin, relOrigin ); if( VectorLength( relOrigin ) < SCANNER_RANGE && ( relOrigin[ 2 ] < 0 ) ) CG_DrawBlips( rect, relOrigin, aIbelow ); } if( !cg_disableScannerPlane.integer ) { trap_R_SetColor( color ); CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); trap_R_SetColor( NULL ); } //draw human buildables above scanner plane for( i = 0; i < entityPositions.numHumanBuildables; i++ ) { VectorClear( relOrigin ); VectorSubtract( entityPositions.humanBuildablePos[ i ], origin, relOrigin ); if( VectorLength( relOrigin ) < SCANNER_RANGE && ( relOrigin[ 2 ] > 0 ) ) CG_DrawBlips( rect, relOrigin, hIabove ); } //draw alien buildables above scanner plane for( i = 0; i < entityPositions.numAlienBuildables; i++ ) { VectorClear( relOrigin ); VectorSubtract( entityPositions.alienBuildablePos[ i ], origin, relOrigin ); if( VectorLength( relOrigin ) < SCANNER_RANGE && ( relOrigin[ 2 ] > 0 ) ) CG_DrawBlips( rect, relOrigin, aIabove ); } //draw human clients above scanner plane for( i = 0; i < entityPositions.numHumanClients; i++ ) { VectorClear( relOrigin ); VectorSubtract( entityPositions.humanClientPos[ i ], origin, relOrigin ); if( VectorLength( relOrigin ) < SCANNER_RANGE && ( relOrigin[ 2 ] > 0 ) ) CG_DrawBlips( rect, relOrigin, hIabove ); } //draw alien clients above scanner plane for( i = 0; i < entityPositions.numAlienClients; i++ ) { VectorClear( relOrigin ); VectorSubtract( entityPositions.alienClientPos[ i ], origin, relOrigin ); if( VectorLength( relOrigin ) < SCANNER_RANGE && ( relOrigin[ 2 ] > 0 ) ) CG_DrawBlips( rect, relOrigin, aIabove ); } }
void CG_LimboPanel_WeaponPanel(panel_button_t *button) { weapon_t weap = CG_LimboPanel_GetSelectedWeapon(); int cnt = CG_LimboPanel_WeaponCount(); if (cgs.ccSelectedWeapon2 >= CG_LimboPanel_WeaponCount_ForSlot(0)) { cgs.ccSelectedWeapon2 = CG_LimboPanel_WeaponCount_ForSlot(0) - 1; } if (CG_LimboPanel_GetTeam() == TEAM_SPECTATOR) { vec4_t clr = { 0.f, 0.f, 0.f, 0.4f }; CG_DrawPic(button->rect.x, button->rect.y, button->rect.w, button->rect.h, cgs.media.limboWeaponCard); trap_R_SetColor(clr); CG_DrawPic(button->rect.x, button->rect.y, button->rect.w, button->rect.h, cgs.media.limboWeaponBlendThingy); trap_R_SetColor(NULL); CG_Text_Paint_Ext(button->rect.x + 4, button->rect.y + 12, weaponPanelNameFont.scalex, weaponPanelNameFont.scaley, weaponPanelNameFont.colour, "SPECTATOR", 0, 0, weaponPanelNameFont.style, weaponPanelNameFont.font); return; } if (BG_PanelButtons_GetFocusButton() == button && cnt > 1) { int i, x; rectDef_t rect; memcpy(&rect, &button->rect, sizeof (rect)); CG_LimboPanel_WeaponPanel_DrawWeapon(&rect, weap, qtrue, va("%iof%i", CG_LimboPanel_GetSelectedWeaponNum() + 1, cnt), CG_LimboPanel_RealWeaponIsDisabled(weap)); if (BG_CursorInRect(&rect) && button->data[7] != 0) { SOUND_FOCUS; button->data[7] = 0; } rect.y -= rect.h; // render in expanded mode ^ for (i = 0, x = 1; i < cnt; ++i) { weapon_t cycleWeap = CG_LimboPanel_GetWeaponForNumber(i, cgs.ccSelectedWeaponNumber, qtrue); if (cycleWeap != weap) { CG_LimboPanel_WeaponPanel_DrawWeapon(&rect, cycleWeap, qtrue, va("%iof%i", i + 1, cnt), CG_LimboPanel_RealWeaponIsDisabled(cycleWeap)); if (BG_CursorInRect(&rect) && button->data[7] != x) { SOUND_FOCUS; button->data[7] = x; } rect.y -= rect.h; x++; } } CG_DrawBorder(button->rect.x, button->rect.y - ((cnt - 1) * button->rect.h), button->rect.w, button->rect.h * cnt, qfalse, qfalse); } else { vec4_t clr = { 0.f, 0.f, 0.f, 0.4f }; // render in normal mode CG_LimboPanel_WeaponPanel_DrawWeapon(&button->rect, weap, cnt > 1 ? qtrue : qfalse, va("%iof%i", CG_LimboPanel_GetSelectedWeaponNum() + 1, cnt), CG_LimboPanel_RealWeaponIsDisabled(weap)); if (cnt <= 1 || !BG_CursorInRect(&button->rect)) { vec4_t clr2 = { 1.f, 1.f, 1.f, 0.4f }; trap_R_SetColor(clr2); } CG_DrawPic(button->rect.x + button->rect.w - 20, button->rect.y + 4, 16, 12, cgs.media.limboWeaponCardArrow); trap_R_SetColor(clr); CG_DrawPic(button->rect.x, button->rect.y, button->rect.w, button->rect.h, cgs.media.limboWeaponBlendThingy); trap_R_SetColor(NULL); } }
// 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 qboolean fAllowMV = ( cg.snap != NULL && cg.snap->ps.pm_type != PM_INTERMISSION /*&& !cg.limboMenu*/ ); 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 if ( cg.mvTotalClients > 0 && fAllowMV ) { CG_cursorUpdate(); } 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; } // Multiview rendering has its own handling if ( w->effects & WFX_MULTIVIEW ) { if ( w != cg.mvCurrentMainview && fAllowMV ) { CG_mvDraw( w ); } 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; //(100 * tmp / w->targetTime) / 100; } 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; //(100 * t_offset / w->targetTime) / 100; } 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(x, y + h, w->fontScale, textColor, (char*)w->lineText[j], 0.0f, 0, 0); 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 ); } } } // Wedge in MV info overlay if ( cg.mvTotalClients > 0 && fAllowMV ) { CG_mvOverlayDisplay(); } // Extra rate info CG_demoAviFPSDraw(); CG_demoTimescaleDraw(); // Mouse cursor lays on top of everything if ( cg.mvTotalClients > 0 && cg.time < cgs.cursorUpdate && fAllowMV ) { //CG_DrawPic(cgs.cursorX - CURSOR_OFFSETX, cgs.cursorY - CURSOR_OFFSETY, 32, 32, cgs.media.cursor); CG_DrawPic( cgDC.cursorx, cgDC.cursory, 32, 32, cgs.media.cursorIcon ); } if ( fCleanup ) { CG_windowCleanup(); } }
/* ================ CG_DrawAmmo ================ */ static void CG_DrawAmmo( centity_t *cent,menuDef_t *menuHUD) { playerState_t *ps; int ammo; itemDef_t *focusItem; float width; const char *text; vec4_t opacity; const weaponInfo_t *weaponInfo; if( cg.jkg_WHUDOpacity < 1.0f ) { MAKERGBA(opacity, 1,1,1, cg.jkg_WHUDOpacity); } else { MAKERGBA(opacity, 1,1,1, cg.jkg_HUDOpacity); } ps = &cg.snap->ps; // Can we find the menu? if (!menuHUD) { return; } if (!cent->currentState.weapon ) // We don't have a weapon right now { return; } #ifndef NO_SP_STYLE_AMMO // Figure out whether or not we want to do the thing where we highlight the text whenever we consume ammo or change firing mode (or, change weapon) if (cg.lastAmmo != cg.predictedPlayerState.stats[STAT_AMMO] || cg.lastAmmoGun != cg.predictedPlayerState.weaponId) { cg.lastAmmo = cg.predictedPlayerState.stats[STAT_AMMO]; cg.lastAmmoTime = cg.time + 200; // matches SP 1:1 cg.lastAmmoGun = cg.predictedPlayerState.weaponId; } if(cg.lastAmmoTime > cg.time) { vec4_t colorCopy = { 0.2, 0.72, 0.86, 1 }; Q_RGBCopy(&opacity, colorCopy); } #endif weaponInfo = CG_WeaponInfo (cent->currentState.weapon, cent->currentState.weaponVariation); if ( GetWeaponData( cent->currentState.weapon, cent->currentState.weaponVariation )->firemodes[0].cost == 0 && GetWeaponData( cent->currentState.weapon, cent->currentState.weaponVariation )->firemodes[1].cost == 0) { //just draw "infinite" text = "Ammo: Infinite"; } else { if ( GetWeaponAmmoClip( cent->currentState.weapon, cent->currentState.weaponVariation )) { ammo = ps->stats[STAT_AMMO]; } else { ammo = ps->ammo; } if ( GetWeaponAmmoClip( cent->currentState.weapon, cent->currentState.weaponVariation )) { // Display the amount of clips too float temp; temp = ceil(( float ) ps->ammo / ( float ) GetWeaponAmmoClip( cent->currentState.weapon, cent->currentState.weaponVariation )); text = va( "Ammo: %i (%i)", ammo, ( int ) temp ); } else { text = va( "Ammo: %i", ammo ); } } // Now then, lets render this text ^_^ width = (float)trap_R_Font_StrLenPixels(text, cgDC.Assets.qhSmallFont, 1) * 0.6f; focusItem = Menu_FindItemByName(menuHUD, "infobar"); if (focusItem) { trap_R_Font_DrawString(focusItem->window.rect.x + ((focusItem->window.rect.w/2) - (width/2)), focusItem->window.rect.y, text, opacity, cgDC.Assets.qhSmall3Font, -1, 0.5f); } focusItem = Menu_FindItemByName(menuHUD, "weapicon"); if (focusItem) { trap_R_SetColor( opacity ); CG_DrawPic( focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w, focusItem->window.rect.h, weaponInfo->hudIcon ); } }
/* ================ CG_DrawSaberStyle If the weapon is a light saber (which needs no ammo) then draw a graphic showing the saber style (fast, medium, strong) ================ */ static void CG_DrawSaberStyle( centity_t *cent, menuDef_t *menuHUD) { const weaponInfo_t *weaponInfo; itemDef_t *focusItem; const char *text; float width; if (!cent->currentState.weapon ) // We don't have a weapon right now { return; } if ( cent->currentState.weapon != WP_SABER ) { return; } // Can we find the menu? if (!menuHUD) { return; } weaponInfo = CG_WeaponInfo (WP_SABER, 0); // draw the current saber style in this window // TODO: cvar plz if(jkg_simpleHUD.integer) { text = va( "Style: %s", SaberStances[cg.predictedPlayerState.fd.saberDrawAnimLevel].saberName_simple ); } else { text = va( "Stance: %s", SaberStances[cg.predictedPlayerState.fd.saberDrawAnimLevel].saberName_technical ); } /*switch ( cg.predictedPlayerState.fd.saberDrawAnimLevel ) { case 1: //FORCE_LEVEL_1: Fast text = "Style: Fast"; break; case 2: //FORCE_LEVEL_2: Medium text = "Style: Medium"; break; case 3: //FORCE_LEVEL_3: Strong text = "Style: Strong"; break; case 4: //FORCE_LEVEL_4://Desann text = "Style: Desann"; break; case 5: //FORCE_LEVEL_5://Tavion text = "Style: Tavion"; break; case 6: //SS_DUAL text = "Style: Dual"; break; case 7: //SS_STAFF text = "Style: Staff"; break; default: // ??? Should never happen text = "Style: Unknown"; break; }*/ // Now then, lets render this text ^_^ width = (float)trap_R_Font_StrLenPixels(text, cgDC.Assets.qhSmall3Font, 1) * 0.6f; focusItem = Menu_FindItemByName(menuHUD, "infobar"); if (focusItem) { trap_R_Font_DrawString(focusItem->window.rect.x + ((focusItem->window.rect.w/2) - (width/2)), focusItem->window.rect.y, text, colorWhite, cgDC.Assets.qhSmall3Font, -1, 0.6f); } focusItem = Menu_FindItemByName(menuHUD, "weapicon"); if (focusItem) { trap_R_SetColor( NULL ); CG_DrawPic( focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w, focusItem->window.rect.h, weaponInfo->hudIcon ); } }
/* ============== CG_DrawCursorHints cg_cursorHints.integer == 0: no hints 1: sin size pulse 2: one way size pulse 3: alpha pulse 4+: static image ============== */ void CG_DrawCursorhint( rectDef_t *rect ) { float *color; qhandle_t icon, icon2 = 0; float scale, halfscale; //bool redbar = false; bool yellowbar = false; if ( !cg_cursorHints.integer ) { return; } CG_CheckForCursorHints(); switch ( cg.cursorHintIcon ) { case HINT_NONE: case HINT_FORCENONE: icon = 0; break; case HINT_DOOR: icon = cgs.media.doorHintShader; break; case HINT_DOOR_ROTATING: icon = cgs.media.doorRotateHintShader; break; case HINT_DOOR_LOCKED: icon = cgs.media.doorLockHintShader; break; case HINT_DOOR_ROTATING_LOCKED: icon = cgs.media.doorRotateLockHintShader; break; case HINT_MG42: icon = cgs.media.mg42HintShader; break; case HINT_BREAKABLE: icon = cgs.media.breakableHintShader; break; case HINT_BREAKABLE_DYNAMITE: icon = cgs.media.dynamiteHintShader; break; case HINT_TANK: icon = cgs.media.tankHintShader; break; case HINT_SATCHELCHARGE: icon = cgs.media.satchelchargeHintShader; break; case HINT_CONSTRUCTIBLE: icon = cgs.media.buildHintShader; break; case HINT_UNIFORM: icon = cgs.media.uniformHintShader; break; case HINT_LANDMINE: icon = cgs.media.landmineHintShader; break; case HINT_CHAIR: icon = cgs.media.notUsableHintShader; // only show 'pickupable' if you're not armed, or are armed with a single handed weapon // rain - WEAPS_ONE_HANDED isn't valid anymore, because // WP_SILENCED_COLT uses a bit >31 (and, therefore, is too large // to be shifted in the way WEAPS_ONE_HANDED does on a 32-bit // system.) If you want to use HINT_CHAIR, you'll need to fix // this. #if 0 if ( !( cg.predictedPlayerState.weapon ) || WEAPS_ONE_HANDED & ( 1 << ( cg.predictedPlayerState.weapon ) ) ) { icon = cgs.media.chairHintShader; } #endif break; case HINT_ALARM: icon = cgs.media.alarmHintShader; break; case HINT_HEALTH: icon = cgs.media.healthHintShader; break; case HINT_TREASURE: icon = cgs.media.treasureHintShader; break; case HINT_KNIFE: icon = cgs.media.knifeHintShader; break; case HINT_LADDER: icon = cgs.media.ladderHintShader; break; case HINT_BUTTON: icon = cgs.media.buttonHintShader; break; case HINT_WATER: icon = cgs.media.waterHintShader; break; case HINT_CAUTION: icon = cgs.media.cautionHintShader; break; case HINT_DANGER: icon = cgs.media.dangerHintShader; break; case HINT_SECRET: icon = cgs.media.secretHintShader; break; case HINT_QUESTION: icon = cgs.media.qeustionHintShader; break; case HINT_EXCLAMATION: icon = cgs.media.exclamationHintShader; break; case HINT_CLIPBOARD: icon = cgs.media.clipboardHintShader; break; case HINT_WEAPON: icon = cgs.media.weaponHintShader; break; case HINT_AMMO: icon = cgs.media.ammoHintShader; break; case HINT_ARMOR: icon = cgs.media.armorHintShader; break; case HINT_POWERUP: icon = cgs.media.powerupHintShader; break; case HINT_HOLDABLE: icon = cgs.media.holdableHintShader; break; case HINT_INVENTORY: icon = cgs.media.inventoryHintShader; break; case HINT_PLYR_FRIEND: icon = cgs.media.hintPlrFriendShader; break; case HINT_PLYR_NEUTRAL: icon = cgs.media.hintPlrNeutralShader; break; case HINT_PLYR_ENEMY: icon = cgs.media.hintPlrEnemyShader; break; case HINT_PLYR_UNKNOWN: icon = cgs.media.hintPlrUnknownShader; break; // DHM - Nerve :: multiplayer hints case HINT_BUILD: icon = cgs.media.buildHintShader; break; case HINT_DISARM: icon = cgs.media.disarmHintShader; break; case HINT_REVIVE: icon = cgs.media.reviveHintShader; break; case HINT_DYNAMITE: icon = cgs.media.dynamiteHintShader; break; // dhm - end // Mad Doc - TDF case HINT_LOCKPICK: icon = cgs.media.doorLockHintShader; // TAT 1/30/2003 - use the locked door hint cursor yellowbar = true; // draw the status bar in yellow so it shows up better break; case HINT_ACTIVATE: case HINT_PLAYER: default: icon = cgs.media.usableHintShader; break; } if ( !icon ) { return; } // color color = CG_FadeColor( cg.cursorHintTime, cg.cursorHintFade ); if ( !color ) { trap_R_SetColor( NULL ); return; } if ( cg_cursorHints.integer == 3 ) { color[3] *= 0.5 + 0.5 * sin( (float)cg.time / 150.0 ); } // size if ( cg_cursorHints.integer >= 3 ) { // no size pulsing scale = halfscale = 0; } else { if ( cg_cursorHints.integer == 2 ) { scale = (float)( ( cg.cursorHintTime ) % 1000 ) / 100.0f; // one way size pulse } else { scale = CURSORHINT_SCALE * ( 0.5 + 0.5 * sin( (float)cg.time / 150.0 ) ); // sin pulse } halfscale = scale * 0.5f; } // set color and draw the hint trap_R_SetColor( color ); CG_DrawPic( rect->x - halfscale, rect->y - halfscale, rect->w + scale, rect->h + scale, icon ); if ( icon2 ) { CG_DrawPic( rect->x - halfscale, rect->y - halfscale, rect->w + scale, rect->h + scale, icon2 ); } trap_R_SetColor( NULL ); // draw status bar under the cursor hint if ( cg.cursorHintValue ) { if ( yellowbar ) { Vector4Set( color, 1, 1, 0, 1.0f ); } else { Vector4Set( color, 0, 0, 1, 0.5f ); } CG_FilledBar( rect->x, rect->y + rect->h + 4, rect->w, 8, color, NULL, NULL, (float)cg.cursorHintValue / 255.0f, 0 ); } }
static void CG_DrawHotkeyBar ( menuDef_t *menuHUD, vec4_t opacity ) { itemDef_t *focusItem; int i; if (!menuHUD) { return; } focusItem = Menu_FindItemByName(menuHUD, "frame"); if (focusItem) { trap_R_SetColor(opacity); CG_DrawPic( focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w, focusItem->window.rect.h, focusItem->window.background ); } // Print background of the bars for (i=0; i<11; i++) { focusItem = Menu_FindItemByName(menuHUD, va("slot%i", i)); if (focusItem) { vec4_t col = {0.11f, 0.11f, 0.11f, 1.0f}; qhandle_t shader = cgs.media.whiteShader; //dummy col[3] *= cg.jkg_HUDOpacity; if ( i < MAX_ACI_SLOTS && cg.playerACI[i] >= 0 && cg.playerInventory[cg.playerACI[i]].id && cg.playerInventory[cg.playerACI[i]].id->itemID ) { int weapon, variation; if(cg.playerInventory[cg.playerACI[i]].id->itemType == ITEM_WEAPON) { if ( BG_GetWeaponByIndex (cg.playerInventory[cg.playerACI[i]].id->varID, &weapon, &variation) ) { const weaponInfo_t *weaponInfo = CG_WeaponInfo (weapon, variation); shader = weaponInfo->hudIcon; col[0] = 1.0f; col[1] = 1.0f; col[2] = 1.0f; /*trap_R_SetColor (colorTable[CT_MDGREY]); trap_R_DrawStretchPic(focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w, focusItem->window.rect.h, 0, 0, 1, 1, cgs.media.whiteShader);*/ if(i == cg.weaponSelect) { trap_R_SetColor (opacity); //TODO: precache me! trap_R_DrawStretchPic(focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w, focusItem->window.rect.h, 0, 0, 1, 1, trap_R_RegisterShaderNoMip("gfx/jkghud/aciselect")); } } } else { col[0] = 1.0f; col[1] = 1.0f; col[2] = 1.0f; shader = trap_R_RegisterShaderNoMip(cg.playerInventory[cg.playerACI[i]].id->itemIcon); } } if(shader != cgs.media.whiteShader) { trap_R_SetColor( col ); trap_R_DrawStretchPic(focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w, focusItem->window.rect.h, 0, 0, 1, 1, shader); } //CG_DrawRect(focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w, focusItem->window.rect.h, 1, colorWhite); } focusItem = Menu_FindItemByName(menuHUD, va("slotl%i", i)); if (focusItem) { trap_R_Font_DrawString(focusItem->window.rect.x, focusItem->window.rect.y, va("%i", i), opacity, cgDC.Assets.qhSmallFont, -1, 0.4f); } } focusItem = Menu_FindItemByName(menuHUD, "frame_overlay"); if(focusItem) { trap_R_SetColor(opacity); CG_DrawPic( focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w, focusItem->window.rect.h, focusItem->window.background ); } }
/* ======================================================================================================================================= CG_DrawScoreboard Draw the normal in-game scoreboard. ======================================================================================================================================= */ qboolean CG_DrawScoreboard(void) { int x = 0, y = 0, w; // TTimo init float fade; float *fadeColor; char *s; if (cg_fixedAspect.integer) { CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER); } // don't draw anything if the menu or console is up if (cg_paused.integer) { cg.deferredPlayerLoading = 0; return qfalse; } // still need to see 'mission failed' message in SP if (cgs.gametype == GT_SINGLE_PLAYER && cg.predictedPlayerState.pm_type == PM_DEAD) { return qfalse; } if (cgs.gametype == GT_SINGLE_PLAYER && cg.predictedPlayerState.pm_type == PM_INTERMISSION) { cg.deferredPlayerLoading = 0; return qfalse; } // don't draw scoreboard during death while warmup up if (cg.warmup && !cg.showScores) { return qfalse; } if (cg.showScores || cg.predictedPlayerState.pm_type == PM_DEAD || cg.predictedPlayerState.pm_type == PM_INTERMISSION) { fade = 1.0; } else { fadeColor = CG_FadeColor(cg.scoreFadeTime, FADE_TIME); if (!fadeColor) { // next time scoreboard comes up, don't print killer cg.deferredPlayerLoading = 0; cg.killerName[0] = 0; return qfalse; } fade = *fadeColor; } // fragged by ... line if (cg.killerName[0]) { s = va("Killed by %s", cg.killerName); w = CG_DrawStrlen(s) * BIGCHAR_WIDTH; x = (SCREEN_WIDTH - w) / 2; y = 40; CG_DrawBigString(x, y, s, fade); } // current rank // ---- (SA) enclosed this so it doesn't draw for SP if (cgs.gametype != GT_SINGLE_PLAYER && cgs.gametype != GT_WOLF) { // added wolf multiplayer check if (cg.snap->ps.persistant[PERS_TEAM] != TEAM_SPECTATOR) { if (cgs.gametype < GT_TEAM) { s = va("%s place with %i", CG_PlaceString(cg.snap->ps.persistant[PERS_RANK] + 1), cg.snap->ps.persistant[PERS_SCORE]); w = CG_DrawStrlen(s) * BIGCHAR_WIDTH; x = (SCREEN_WIDTH - w) / 2; y = 60; CG_DrawBigString(x, y, s, fade); } else { if (cg.teamScores[0] == cg.teamScores[1]) { s = va("Teams are tied at %i", cg.teamScores[0]); } else if (cg.teamScores[0] >= cg.teamScores[1]) { s = va("Red leads %i to %i", cg.teamScores[0], cg.teamScores[1]); } else { s = va("Blue leads %i to %i", cg.teamScores[1], cg.teamScores[0]); } w = CG_DrawStrlen(s) * BIGCHAR_WIDTH; x = (SCREEN_WIDTH - w) / 2; y = 60; CG_DrawBigString(x, y, s, fade); } } // scoreboard x = 320 - SCOREBOARD_WIDTH / 2; y = 86; #if 0 CG_DrawBigStringColor(x, y, "SCORE PING TIME NAME", fadeColor); CG_DrawBigStringColor(x, y + 12, "---- - ---- ---- -------------- - ", fadeColor); #endif CG_DrawPic(x + 1 * 16, y, 64, 32, cgs.media.scoreboardScore); CG_DrawPic(x + 6 * 16 + 8, y, 64, 32, cgs.media.scoreboardPing); CG_DrawPic(x + 11 * 16 + 8, y, 64, 32, cgs.media.scoreboardTime); CG_DrawPic(x + 16 * 16, y, 64, 32, cgs.media.scoreboardName); y += 32; } // NERVE - SMF if (cgs.gametype == GT_WOLF) { // teamplay scoreboard x = 320 - SCOREBOARD_WIDTH / 2 + 20 + 20; y = 40; y = WM_ScoreboardOverlay(x, y, fade); if (cg.teamScores[0] >= cg.teamScores[1]) { y = WM_TeamScoreboard(x, y, TEAM_RED, fade); y = WM_TeamScoreboard(x, y, TEAM_BLUE, fade); } else { y = WM_TeamScoreboard(x, y, TEAM_BLUE, fade); y = WM_TeamScoreboard(x, y, TEAM_RED, fade); } WM_TeamScoreboard(x, y, TEAM_SPECTATOR, fade); } // - NERVE - SMF } else if (cgs.gametype >= GT_TEAM) {
/* ======================================================================================================================================= CG_DrawScoreboard ======================================================================================================================================= */ 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); } }
void CG_DrawHandlePicDc (float x, float y, float w, float h, qhandle_t asset, int widescreen, rectDef_t menuRect) { wsset(); CG_DrawPic(x, y, w, h, asset); wsoff(); }
/* ============== CG_DrawNumField Take x,y positions as if 640 x 480 and scales them to the proper resolution ============== */ void CG_DrawNumField (int x, int y, int width, int value,int charWidth,int charHeight,int style,qboolean zeroFill) { char num[16], *ptr; int l; int frame; int xWidth; if (width < 1) { return; } // draw number string if (width > 5) { width = 5; } switch ( width ) { case 1: value = value > 9 ? 9 : value; value = value < 0 ? 0 : value; break; case 2: value = value > 99 ? 99 : value; value = value < -9 ? -9 : value; break; case 3: value = value > 999 ? 999 : value; value = value < -99 ? -99 : value; break; case 4: value = value > 9999 ? 9999 : value; value = value < -999 ? -999 : value; break; } Com_sprintf (num, sizeof(num), "%i", value); l = strlen(num); if (l > width) l = width; // FIXME: Might need to do something different for the chunky font?? switch(style) { case NUM_FONT_SMALL: xWidth = charWidth; break; case NUM_FONT_CHUNKY: xWidth = (charWidth/1.2f) + 2; break; default: case NUM_FONT_BIG: xWidth = (charWidth/2) + 7;//(charWidth/6); break; } if ( zeroFill ) { for (int i = 0; i < (width - l); i++ ) { switch(style) { case NUM_FONT_SMALL: CG_DrawPic( x,y, charWidth, charHeight, cgs.media.smallnumberShaders[0] ); break; case NUM_FONT_CHUNKY: CG_DrawPic( x,y, charWidth, charHeight, cgs.media.chunkyNumberShaders[0] ); break; default: case NUM_FONT_BIG: CG_DrawPic( x,y, charWidth, charHeight, cgs.media.numberShaders[0] ); break; } x += 2 + (xWidth); } } else { x += 2 + (xWidth)*(width - l); } ptr = num; while (*ptr && l) { if (*ptr == '-') frame = STAT_MINUS; else frame = *ptr -'0'; switch(style) { case NUM_FONT_SMALL: CG_DrawPic( x,y, charWidth, charHeight, cgs.media.smallnumberShaders[frame] ); x++; // For a one line gap break; case NUM_FONT_CHUNKY: CG_DrawPic( x,y, charWidth, charHeight, cgs.media.chunkyNumberShaders[frame] ); break; default: case NUM_FONT_BIG: CG_DrawPic( x,y, charWidth, charHeight, cgs.media.numberShaders[frame] ); break; } x += (xWidth); ptr++; l--; } }
static void CG_DrawTopLeftHUD ( menuDef_t *menuHUD, vec4_t opacity ) { itemDef_t *focusItem; if (!menuHUD) { return; } // Print background of the bars /*focusItem = Menu_FindItemByName(menuHUD, "barsbackground"); if (focusItem) { trap_R_SetColor(opacity); CG_DrawPic( focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w, focusItem->window.rect.h, focusItem->window.background ); }*/ if (cg.predictedPlayerState.pm_type != PM_SPECTATOR) { CG_DrawArmor(menuHUD); CG_DrawHealth(menuHUD); CG_DrawForcePower(menuHUD); JKG_DrawFiringMode(menuHUD); focusItem = Menu_FindItemByName(menuHUD, "frame"); if (focusItem) { trap_R_SetColor(opacity); CG_DrawPic( focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w, focusItem->window.rect.h, focusItem->window.background ); } focusItem = Menu_FindItemByName(menuHUD, "hudicon_shield"); if (focusItem) { trap_R_SetColor(opacity); CG_DrawPic( focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w, focusItem->window.rect.h, focusItem->window.background ); } focusItem = Menu_FindItemByName(menuHUD, "hudicon_health"); if (focusItem) { trap_R_SetColor(opacity); CG_DrawPic( focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w, focusItem->window.rect.h, focusItem->window.background ); } focusItem = Menu_FindItemByName(menuHUD, "hudicon_stamina"); if (focusItem) { trap_R_SetColor(opacity); CG_DrawPic( focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w, focusItem->window.rect.h, focusItem->window.background ); } } // Put in the avatar before we put on the frame /*focusItem = Menu_FindItemByName(menuHUD, "avatar"); if (focusItem) { trap_R_SetColor(opacity); CG_DrawPic( focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w, focusItem->window.rect.h, cgs.media.avatar_placeholder ); } */ // Print frame // Print level /*focusItem = Menu_FindItemByName(menuHUD, "leveltext"); if (focusItem) { const char *temp = va("%i", 0); int x = ((focusItem->window.rect.w/2) - (trap_R_Font_StrLenPixels(temp, MenuFontToHandle(1), 0.6f) / 2)) + focusItem->window.rect.x; //CG_DrawRect(focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w, focusItem->window.rect.h, 1, colorWhite); trap_R_Font_DrawString( x, focusItem->window.rect.y, temp, opacity,//colorWhite, MenuFontToHandle(1), -1, 0.6f); }*/ /*focusItem = Menu_FindItemByName(menuHUD, "nametext"); if (focusItem) { const char *temp = va("%s", Info_ValueForKey(CG_ConfigString(CS_PLAYERS + cg.snap->ps.clientNum), "n")); //CG_DrawRect(focusItem->window.rect.x,focusItem->window.rect.y,focusItem->window.rect.w,focusItem->window.rect.h,1,colorWhite); // To avoid rounding errors, we get the length at scale 1, then adjust it int x = ((focusItem->window.rect.w/2) - (((float)trap_R_Font_StrLenPixels(temp, MenuFontToHandle(1), 1) * 0.5f) / 2)) + focusItem->window.rect.x; //CG_DrawRect(focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w, focusItem->window.rect.h, 1, colorWhite); ChatBox_SetPaletteAlpha(opacity[3]); trap_R_Font_DrawString( x, focusItem->window.rect.y, temp, opacity,//colorWhite, MenuFontToHandle(1), -1, 0.5f); ChatBox_SetPaletteAlpha(1); }*/ }
// Gordon: this function is mental, i love it :) void CG_LimboPanel_RenderCounter(panel_button_t *button) { float x, w; float count[MAX_ROLLERS]; int i, j; qhandle_t shaderBack; qhandle_t shaderRoll; int numimages; float counter_rolltime = CG_LimboPanel_RenderCounter_RollTimeForButton(button); int num = CG_LimboPanel_RenderCounter_NumRollers(button); int value = CG_LimboPanel_RenderCounter_ValueForButton(button); if (num > MAX_ROLLERS) { num = MAX_ROLLERS; } CG_LimboPanel_RenderCounter_GetShaders(button, &shaderBack, &shaderRoll, &numimages); if (COUNTER_ROLLTOTAL < counter_rolltime) { // we're rolling float frac = COUNTER_ROLLTOTAL / counter_rolltime; for (i = 0, j = 1; i < num; ++i, j *= numimages) { int valueOld = (button->data[3] / j) % numimages; int valueNew = (button->data[5] / j) % numimages; if (valueNew == valueOld) { count[i] = valueOld; } else if ((valueNew > valueOld) != (button->data[5] > button->data[3])) { // we're flipping around so.... if (button->data[5] > button->data[3]) { count[i] = valueOld + frac; } else { count[i] = valueOld - frac; } } else { // normal flip count[i] = valueOld + ((valueNew - valueOld) * frac); } } } else { if (button->data[3] != button->data[5]) { button->data[3] = button->data[5]; } else if (value != button->data[3]) { int maxchange = abs(value - button->data[3]); if (maxchange > CG_LimboPanel_RenderCounter_MaxChangeForButton(button)) { maxchange = CG_LimboPanel_RenderCounter_MaxChangeForButton(button); } if (value > button->data[3]) { if (CG_LimboPanel_RenderCounter_CountsUp(button)) { button->data[5] = button->data[3] + maxchange; } else { button->data[5] = value; } } else { if (CG_LimboPanel_RenderCounter_CountsDown(button)) { button->data[5] = button->data[3] - maxchange; } else { button->data[5] = value; } } button->data[4] = cg.time; } for (i = 0, j = 1; i < num; ++i, j *= numimages) { count[i] = (int)(button->data[3] / j); } } x = button->rect.x; w = (num > 1) ? (button->rect.w / (float)num) : button->rect.w; if (CG_LimboPanel_RenderCounter_IsReversed(button)) { for (i = 0; i < num; ++i) { CG_LimboPanel_RenderCounterNumber(x, button->rect.y, w, button->rect.h, count[i], shaderBack, shaderRoll, numimages); x += w + button->data[6]; } } else { for (i = num - 1; i >= 0; --i) { CG_LimboPanel_RenderCounterNumber(x, button->rect.y, w, button->rect.h, count[i], shaderBack, shaderRoll, numimages); x += w + button->data[6]; } } if (button->data[0] == 0 || button->data[0] == 1) { CG_DrawPic(button->rect.x - 2, button->rect.y - 2, button->rect.w * 1.4f, button->rect.h + 7, cgs.media.limboCounterBorder); } }
static void CG_DrawMiniMap ( menuDef_t *menuHUD, vec4_t opacity ) { itemDef_t *focusItem; if (!menuHUD) { return; } // Render the minimap // Use a default fixed radius of 500 units for now MiniMap_Render(menuHUD, 1500.0f); focusItem = Menu_FindItemByName(menuHUD, "frame"); if (focusItem) { trap_R_SetColor(opacity); CG_DrawPic( focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w, focusItem->window.rect.h, focusItem->window.background ); } //Render the credit display focusItem = Menu_FindItemByName(menuHUD, "credits"); if (focusItem) { trap_R_SetColor(opacity); trap_R_Font_DrawString(focusItem->window.rect.x, focusItem->window.rect.y, va("Credits: %i", cg.predictedPlayerState.persistant[PERS_CREDITS]), opacity, cgDC.Assets.qhSmall3Font, -1, focusItem->textscale); } focusItem = Menu_FindItemByName(menuHUD, "smalltext"); if(focusItem) { char buffer[1024]; int mins, sec, msec; int numberItems = 0; buffer[0] = '\0'; trap_R_SetColor(opacity); if(cg_drawTimer.integer == 1 || cg_drawTimer.integer == 3) { //Draw server time msec = cg.time - cgs.levelStartTime; sec = msec/1000; //Convert to mm:ss format mins = floor((float)sec/60); sec -= (mins * 60); strcat(buffer, va("Timer: %.2i:%.2i ", mins, sec)); numberItems++; } if(cg_drawTimer.integer == 2 || cg_drawTimer.integer == 3) { //Add a slash if(numberItems > 0) { strcat(buffer, "/ "); numberItems++; } if(T_meridiem()) { strcat(buffer, va("Clock: %.2i:%.2i PM ", T_hour(qfalse), T_minute())); } else { strcat(buffer, va("Clock: %.2i:%.2i AM ", T_hour(qfalse), T_minute())); } } //TODO: Add more s***e //strcat(buffer, '\0'); trap_R_Font_DrawString(focusItem->window.rect.x, focusItem->window.rect.y, buffer, opacity, cgDC.Assets.qhSmall3Font, -1, focusItem->textscale); } if(cg_drawFPS.integer > 0) { focusItem = Menu_FindItemByName(menuHUD, "fps"); if(focusItem) { CG_DrawFPS(focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w, focusItem->window.rect.h, focusItem->iMenuFont, focusItem->textscale); } } }
/* ================ Con_DrawSolidConsole Draws the console with the solid background ================ */ void Con_DrawSolidConsole( connstate_t state, float frac ) { int i; int x, y; int rows; char *text; int row; int lines; vec4_t color; if ( frac > 1 ) frac = 1; lines = cgs.glconfig.vidHeight * frac / cgs.screenYScale; if (lines <= 0) return; CG_SetScreenPlacement( PLACE_STRETCH, PLACE_STRETCH ); // draw the background y = frac * SCREEN_HEIGHT; if ( y < 1 ) { y = 0; } else { CG_DrawPic( 0, 0, SCREEN_WIDTH, y, cgs.media.consoleShader ); } color[0] = 1; color[1] = 0; color[2] = 0; color[3] = 1; CG_FillRect( 0, y, SCREEN_WIDTH, 2, color ); CG_SetScreenPlacement( PLACE_RIGHT, PLACE_TOP ); // draw the version number CG_DrawSmallStringColor( SCREEN_WIDTH - CG_DrawStrlen( con.version ) * SMALLCHAR_WIDTH, lines - SMALLCHAR_HEIGHT, con.version, color ); CG_SetScreenPlacement( PLACE_LEFT, PLACE_TOP ); // draw the text rows = (lines-SMALLCHAR_HEIGHT)/SMALLCHAR_HEIGHT; // rows of text to draw y = lines - (SMALLCHAR_HEIGHT*3); // draw from the bottom up if (con.display != con.current) { int linewidth = con.screenFakeWidth / SMALLCHAR_WIDTH; // draw arrows to show the buffer is backscrolled trap_R_SetColor( color ); for (x=0 ; x<linewidth ; x+=4) CG_DrawChar( (x+1)*SMALLCHAR_WIDTH, y, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, '^' ); y -= SMALLCHAR_HEIGHT; rows--; trap_R_SetColor( NULL ); } row = con.display; if ( con.x == 0 ) { row--; } for (i=0 ; i<rows ; i++, y -= SMALLCHAR_HEIGHT, row--) { if (row < 0) break; if (con.current - row >= CON_MAXLINES) { // past scrollback wrap point continue; } text = con.lines[row % CON_MAXLINES]; CG_DrawSmallString( con.sideMargin, y, text, 1.0f ); } // draw the input prompt, user text, and cursor if desired Con_DrawInput ( state, lines ); }
/* ================ CG_DrawStatusBar ================ */ static void CG_DrawStatusBar( void ) { int color; centity_t *cent; playerState_t *ps; int value; vec4_t hcolor; vec3_t angles; vec3_t origin; static float colors[4][4] = { // { 0.2, 1.0, 0.2, 1.0 } , { 1.0, 0.2, 0.2, 1.0 }, {0.5, 0.5, 0.5, 1} }; { 1.0f, 0.69f, 0.0f, 1.0f }, // normal { 1.0f, 0.2f, 0.2f, 1.0f }, // low health { 0.5f, 0.5f, 0.5f, 1.0f }, // weapon firing { 1.0f, 1.0f, 1.0f, 1.0f } }; // health > 100 if ( cg_drawStatus.integer == 0 ) { return; } // draw the team background CG_DrawTeamBackground( 0, 420, 640, 60, 0.33f, cg.snap->ps.persistant[PERS_TEAM] ); cent = &cg_entities[cg.snap->ps.clientNum]; ps = &cg.snap->ps; VectorClear( angles ); // draw any 3D icons first, so the changes back to 2D are minimized if ( cent->currentState.weapon && cg_weapons[ cent->currentState.weapon ].ammoModel ) { origin[0] = 70; origin[1] = 0; origin[2] = 0; angles[YAW] = 90 + 20 * sin( (cg.time / 1000.0) + cg.timeFraction / 1000.0 ); CG_Draw3DModel( (CHAR_WIDTH*3 + TEXT_ICON_SPACE)*cgs.widthRatioCoef, 432, ICON_SIZE*cgs.widthRatioCoef, ICON_SIZE, cg_weapons[ cent->currentState.weapon ].ammoModel, 0, origin, angles ); } CG_DrawStatusBarHead( 185 + (CHAR_WIDTH*3 + TEXT_ICON_SPACE)*cgs.widthRatioCoef ); if( cg.predictedPlayerState.powerups[PW_REDFLAG] ) { CG_DrawStatusBarFlag( 185 + CHAR_WIDTH*3 + TEXT_ICON_SPACE + ICON_SIZE, TEAM_RED ); } else if( cg.predictedPlayerState.powerups[PW_BLUEFLAG] ) { CG_DrawStatusBarFlag( 185 + CHAR_WIDTH*3 + TEXT_ICON_SPACE + ICON_SIZE, TEAM_BLUE ); } else if( cg.predictedPlayerState.powerups[PW_NEUTRALFLAG] ) { CG_DrawStatusBarFlag( 185 + CHAR_WIDTH*3 + TEXT_ICON_SPACE + ICON_SIZE, TEAM_FREE ); } if ( ps->stats[ STAT_ARMOR ] ) { origin[0] = 90; origin[1] = 0; origin[2] = -10; angles[YAW] = ( (cg.time & 2047) + cg.timeFraction ) * 360 / 2048.0; CG_Draw3DModel( 370 + (CHAR_WIDTH*3 + TEXT_ICON_SPACE)*cgs.widthRatioCoef, 432, ICON_SIZE*cgs.widthRatioCoef, ICON_SIZE, cgs.media.armorModel, 0, origin, angles ); } // // ammo // if ( cent->currentState.weapon ) { value = ps->ammo[cent->currentState.weapon]; if ( value > -1 ) { if ( cg.predictedPlayerState.weaponstate == WEAPON_FIRING && cg.predictedPlayerState.weaponTime > 100 ) { // draw as dark grey when reloading color = 2; // dark grey } else { if ( value >= 0 ) { color = 0; // green } else { color = 1; // red } } trap_R_SetColor( colors[color] ); CG_DrawField (0, 432, 3, value); trap_R_SetColor( NULL ); // if we didn't draw a 3D icon, draw a 2D icon for ammo if ( !cg_draw3dIcons.integer && cg_drawIcons.integer ) { qhandle_t icon; icon = cg_weapons[ cg.predictedPlayerState.weapon ].ammoIcon; if ( icon ) { CG_DrawPic( (CHAR_WIDTH*3 + TEXT_ICON_SPACE)*cgs.widthRatioCoef, 432, ICON_SIZE*cgs.widthRatioCoef, ICON_SIZE, icon ); } } } } // // health // value = ps->stats[STAT_HEALTH]; if ( value > 100 ) { trap_R_SetColor( colors[3] ); // white } else if (value > 25) { trap_R_SetColor( colors[0] ); // green } else if (value > 0) { color = (cg.time >> 8) & 1; // flash trap_R_SetColor( colors[color] ); } else {
/* ============== CG_DrawPlayerWeaponIcon ============== */ void CG_DrawPlayerWeaponIcon(rectDef_t *rect, qboolean drawHighlighted, int align, vec4_t *refcolor) { int size; int realweap; qhandle_t icon; float scale, halfScale; vec4_t hcolor; VectorCopy(*refcolor, hcolor); hcolor[3] = 1.f; if ((cg.predictedPlayerEntity.currentState.eFlags & EF_MG42_ACTIVE) || (cg.predictedPlayerEntity.currentState.eFlags & EF_MOUNTEDTANK)) { if (cg_entities[cg_entities[cg_entities[cg.snap->ps.clientNum].tagParent].tankparent].currentState.density & 8) { realweap = WP_MOBILE_BROWNING; } else { realweap = WP_MOBILE_MG42; } } else { realweap = cg.predictedPlayerState.weapon; } size = CG_WeaponIconScale(realweap); if (!size) { return; } if (drawHighlighted) { // we don't have icon[0]; icon = cg_weapons[realweap].weaponIcon[1]; } else { icon = cg_weapons[realweap].weaponIcon[1]; } // pulsing grenade icon to help the player 'count' in their head if (cg.predictedPlayerState.grenadeTimeLeft) // grenades and dynamite set this { // these time differently if (realweap == WP_DYNAMITE) { if (((cg.grenLastTime) % 1000) > ((cg.predictedPlayerState.grenadeTimeLeft) % 1000)) { trap_S_StartLocalSound(cgs.media.grenadePulseSound4, CHAN_LOCAL_SOUND); } } else { if (((cg.grenLastTime) % 1000) < ((cg.predictedPlayerState.grenadeTimeLeft) % 1000)) { switch (cg.predictedPlayerState.grenadeTimeLeft / 1000) { case 3: trap_S_StartLocalSound(cgs.media.grenadePulseSound4, CHAN_LOCAL_SOUND); break; case 2: trap_S_StartLocalSound(cgs.media.grenadePulseSound3, CHAN_LOCAL_SOUND); break; case 1: trap_S_StartLocalSound(cgs.media.grenadePulseSound2, CHAN_LOCAL_SOUND); break; case 0: trap_S_StartLocalSound(cgs.media.grenadePulseSound1, CHAN_LOCAL_SOUND); break; } } } scale = (float)((cg.predictedPlayerState.grenadeTimeLeft) % 1000) / 100.0f; halfScale = scale * 0.5f; cg.grenLastTime = cg.predictedPlayerState.grenadeTimeLeft; } else { scale = halfScale = 0; } if (icon) { float x, y, w, h; if (size == 1) // draw half width to match the icon asset { // start at left x = rect->x - halfScale; y = rect->y - halfScale; w = rect->w / 2 + scale; h = rect->h + scale; switch (align) { case ITEM_ALIGN_CENTER: x += rect->w / 4; break; case ITEM_ALIGN_RIGHT: x += rect->w / 2; break; case ITEM_ALIGN_LEFT: default: break; } } else { x = rect->x - halfScale; y = rect->y - halfScale; w = rect->w + scale; h = rect->h + scale; } trap_R_SetColor(hcolor); CG_DrawPic(x, y, w, h, icon); } }
void CG_PanelButtonsRender_Img( panel_button_t* button ) { CG_DrawPic( button->rect.x, button->rect.y, button->rect.w, button->rect.h, button->hShaderNormal ); }
/* ==================== CG_DrawInformation Draw all the status / pacifier stuff during level loading ==================== */ void CG_DrawInformation( void ) { const char *s; const char *info; const char *sysInfo; int y; int value; qhandle_t levelshot = 0; // TTimo: init // qhandle_t detail; char buf[1024]; static int lastDraw = 0; // Ridah, so we don't draw the screen more often than we need to int ms; static int callCount = 0; float percentDone; int expectedHunk; char hunkBuf[MAX_QPATH]; vec4_t color; if ( cg.snap && ( strlen( cg_missionStats.string ) <= 1 ) ) { return; // we are in the world, no need to draw information } if ( callCount ) { // reject recursive calls return; } ms = trap_Milliseconds(); if ( ( lastDraw <= ms ) && ( lastDraw > ms - 100 ) ) { return; } lastDraw = ms; callCount++; info = CG_ConfigString( CS_SERVERINFO ); sysInfo = CG_ConfigString( CS_SYSTEMINFO ); trap_Cvar_VariableStringBuffer( "com_expectedhunkusage", hunkBuf, MAX_QPATH ); expectedHunk = atoi( hunkBuf ); s = Info_ValueForKey( info, "mapname" ); if ( s && s[0] != 0 ) { // there is often no 's' if ( strlen( cg_missionStats.string ) > 1 && cg_missionStats.string[0] == 's' ) { levelshot = trap_R_RegisterShaderNoMip( va( "levelshots/pre_%s_stats.tga", s ) ); } else { // show briefing screen if ( s && s[0] != 0 ) { // there is often no 's' levelshot = trap_R_RegisterShaderNoMip( va( "levelshots/%s.tga", s ) ); } } } if ( !levelshot ) { levelshot = trap_R_RegisterShaderNoMip( "menu/art/unknownmap" ); } trap_R_SetColor( NULL ); CG_DrawPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, levelshot ); // blend a detail texture over it //detail = trap_R_RegisterShader( "levelShotDetail" ); //trap_R_DrawStretchPic( 0, 0, cgs.glconfig.vidWidth, cgs.glconfig.vidHeight, 0, 0, 2.5, 2, detail ); // (SA) commented out for Drew // UI_DrawProportionalString( 320, 16, va( "Loading %s", Info_ValueForKey( info, "mapname" ) ), UI_SMALLFONT|UI_CENTER|UI_DROPSHADOW, colorWhite ); // show the loading progress VectorSet( color, 0.8, 0.8, 0.8 ); color[3] = 0.8; if ( strlen( cg_missionStats.string ) > 1 && cg_missionStats.string[0] == 's' ) { vec2_t xy = { 190, 470 }; vec2_t wh = { 260, 10 }; // draw the mission stats while loading if ( !Q_strncmp( cg_missionStats.string, "s=", 2 ) ) { CG_DrawStats( cg_missionStats.string + 2 ); } if ( cg_waitForFire.integer == 1 ) { // waiting for server to finish loading the map UI_DrawProportionalString( 320, xy[1] + wh[1] - 10, "press fire to continue", UI_CENTER | UI_EXSMALLFONT | UI_DROPSHADOW, color ); } else if ( expectedHunk > 0 ) { percentDone = (float)( cg_hunkUsed.integer + cg_soundAdjust.integer ) / (float)( expectedHunk ); if ( percentDone > 0.97 ) { // never actually show 100%, since we are not in the game yet percentDone = 0.97; } CG_HorizontalPercentBar( xy[0] + 10, xy[1] + wh[1] - 10, wh[0] - 20, 10, percentDone ); } else if ( expectedHunk == -2 ) { // we're ready, press a key to start playing if ( ( ms % 1000 ) < 700 ) { // flashing to get our attention UI_DrawProportionalString( 320, xy[1] + wh[1] - 10, "press fire to begin", UI_CENTER | UI_EXSMALLFONT | UI_DROPSHADOW, color ); } } else { UI_DrawProportionalString( 320, xy[1] + wh[1] - 10, "please wait", UI_CENTER | UI_EXSMALLFONT | UI_DROPSHADOW, color ); } trap_UpdateScreen(); callCount--; return; } // Ridah, in single player, cheats disabled, don't show unnecessary information // DHM - Nerve :: maybe temp, but we want to display the same as single player right now if ( cgs.gametype == GT_SINGLE_PLAYER || cgs.gametype >= GT_WOLF ) { vec2_t xy = { 200, 468 }; vec2_t wh = { 240, 10 }; // show the server motd CG_DrawMotd(); // show the percent complete bar if ( expectedHunk > 0 ) { percentDone = (float)( cg_hunkUsed.integer + cg_soundAdjust.integer ) / (float)( expectedHunk ); if ( percentDone > 0.97 ) { percentDone = 0.97; } CG_HorizontalPercentBar( xy[0], xy[1], wh[0], wh[1], percentDone ); } else if ( expectedHunk == -2 ) { // we're ready, press a key to start playing if ( ( ms % 1000 ) < 700 ) { // flashing to get our attention UI_DrawProportionalString( 320, xy[1] - 2, "press fire to begin", UI_CENTER | UI_EXSMALLFONT | UI_DROPSHADOW, color ); } } trap_UpdateScreen(); callCount--; return; } // done. // draw the icons of thiings as they are loaded CG_DrawLoadingIcons(); // the first 150 rows are reserved for the client connection // screen to write into if ( cg.infoScreenText[0] ) { UI_DrawProportionalString( 320, 128, va( "Loading... %s", cg.infoScreenText ), UI_CENTER | UI_SMALLFONT | UI_DROPSHADOW, colorWhite ); } else { UI_DrawProportionalString( 320, 128, "Awaiting snapshot...", UI_CENTER | UI_SMALLFONT | UI_DROPSHADOW, colorWhite ); } // draw info string information y = 180; // don't print server lines if playing a local game trap_Cvar_VariableStringBuffer( "sv_running", buf, sizeof( buf ) ); if ( !atoi( buf ) ) { // server hostname s = Info_ValueForKey( info, "sv_hostname" ); UI_DrawProportionalString( 320, y, s, UI_CENTER | UI_SMALLFONT | UI_DROPSHADOW, colorWhite ); y += PROP_HEIGHT; // server-specific message of the day s = CG_ConfigString( CS_MOTD ); if ( s[0] ) { UI_DrawProportionalString( 320, y, s, UI_CENTER | UI_SMALLFONT | UI_DROPSHADOW, colorWhite ); y += PROP_HEIGHT; } // some extra space after hostname and motd y += 10; } // map-specific message (long map name) s = CG_ConfigString( CS_MESSAGE ); if ( s[0] ) { UI_DrawProportionalString( 320, y, s, UI_CENTER | UI_SMALLFONT | UI_DROPSHADOW, colorWhite ); y += PROP_HEIGHT; } // cheats warning s = Info_ValueForKey( sysInfo, "sv_cheats" ); if ( s[0] == '1' ) { UI_DrawProportionalString( 320, y, "CHEATS ARE ENABLED", UI_CENTER | UI_SMALLFONT | UI_DROPSHADOW, colorWhite ); y += PROP_HEIGHT; } // game type switch ( cgs.gametype ) { case GT_FFA: s = "Free For All"; break; case GT_SINGLE_PLAYER: s = "Single Player"; break; case GT_TOURNAMENT: s = "Tournament"; break; case GT_TEAM: s = "Team Deathmatch"; break; case GT_CTF: s = "Capture The Flag"; break; // JPW NERVE case GT_WOLF: s = "Wolfenstein Multiplayer"; break; // jpw // NERVE - SMF case GT_WOLF_STOPWATCH: s = "WolfMP Stopwatch"; break; case GT_WOLF_CP: s = "WolfMP Checkpoint"; break; // -NERVE - SMF // JPW NERVE case GT_WOLF_CPH: s = "WolfMP Capture & Hold"; break; // jpw default: s = "Unknown Gametype"; break; } UI_DrawProportionalString( 320, y, s, UI_CENTER | UI_SMALLFONT | UI_DROPSHADOW, colorWhite ); y += PROP_HEIGHT; value = atoi( Info_ValueForKey( info, "timelimit" ) ); if ( value ) { UI_DrawProportionalString( 320, y, va( "timelimit %i", value ), UI_CENTER | UI_SMALLFONT | UI_DROPSHADOW, colorWhite ); y += PROP_HEIGHT; } if ( cgs.gametype != GT_CTF && cgs.gametype != GT_SINGLE_PLAYER ) { value = atoi( Info_ValueForKey( info, "fraglimit" ) ); if ( value ) { UI_DrawProportionalString( 320, y, va( "fraglimit %i", value ), UI_CENTER | UI_SMALLFONT | UI_DROPSHADOW, colorWhite ); y += PROP_HEIGHT; } } if ( cgs.gametype == GT_CTF ) { value = atoi( Info_ValueForKey( info, "capturelimit" ) ); if ( value ) { UI_DrawProportionalString( 320, y, va( "capturelimit %i", value ), UI_CENTER | UI_SMALLFONT | UI_DROPSHADOW, colorWhite ); y += PROP_HEIGHT; } } callCount--; }
static void WM_DrawClientScore( int x, int y, score_t *score, float *color, float fade ) { int maxchars, offset; int i, j; float tempx; vec4_t hcolor; clientInfo_t *ci; char buf[64]; if ( y + SMALLCHAR_HEIGHT >= 470 ) return; ci = &cgs.clientinfo[score->client]; if ( score->client == cg.snap->ps.clientNum ) { tempx = x; hcolor[3] = fade * 0.3; VectorSet( hcolor, .5f, .5f, .2f ); // DARK-RED CG_FillRect( tempx, y + 1, INFO_PLAYER_WIDTH - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor ); tempx += INFO_PLAYER_WIDTH; if ( ci->team == TEAM_SPECTATOR ) { int width; width = INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH; CG_FillRect( tempx, y + 1, width - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor ); tempx += width; } else { CG_FillRect( tempx, y + 1, INFO_CLASS_WIDTH - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor ); tempx += INFO_CLASS_WIDTH; if( cg_gameType.integer == GT_WOLF_LMS ) { CG_FillRect( tempx, y + 1, INFO_SCORE_WIDTH - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor ); tempx += INFO_SCORE_WIDTH; } else { CG_FillRect( tempx, y + 1, INFO_XP_WIDTH - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor ); tempx += INFO_XP_WIDTH; } CG_FillRect( tempx, y + 1, INFO_LATENCY_WIDTH - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor ); tempx += INFO_LATENCY_WIDTH; if( cg_gameType.integer != GT_WOLF_LMS ) { CG_FillRect( tempx, y + 1, INFO_LIVES_WIDTH - INFO_BORDER, SMALLCHAR_HEIGHT - 1, hcolor ); tempx += INFO_LIVES_WIDTH; } } } tempx = x; // DHM - Nerve VectorSet( hcolor, 1, 1, 1 ); hcolor[3] = fade; maxchars = 16; offset = 0; if ( ci->team != TEAM_SPECTATOR ) { if ( ci->powerups & ( (1 << PW_REDFLAG) | (1 << PW_BLUEFLAG) ) ) { CG_DrawPic( tempx-4, y, 16, 16, cgs.media.objectiveShader ); offset += 8; tempx += 12; maxchars -= 2; } // draw the skull icon if out of lives if( score->respawnsLeft == -2 || (cgs.clientinfo[cg.clientNum].team != TEAM_SPECTATOR && ci->team == cgs.clientinfo[cg.clientNum].team && cgs.clientinfo[score->client].health == -1 ) ) { CG_DrawPic( tempx, y, 18, 18, cgs.media.scoreEliminatedShader ); offset += 18; tempx += 18; maxchars -= 2; } else if( cgs.clientinfo[cg.clientNum].team != TEAM_SPECTATOR && ci->team == cgs.clientinfo[cg.clientNum].team && cgs.clientinfo[score->client].health == 0 ) { CG_DrawPic( tempx + 1, y + 1, 16, 16, cgs.media.medicIcon ); offset += 18; tempx += 18; maxchars -= 2; } } // draw name CG_DrawStringExt( tempx, y, ci->name, hcolor, qfalse, qfalse, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, maxchars ); maxchars -= CG_DrawStrlen( ci->name ); // draw medals buf[0] = '\0'; for( i = 0; i < SK_NUM_SKILLS; i++ ) { for( j = 0; j < ci->medals[i]; j++ ) Q_strcat( buf, sizeof(buf), va( "^%c%c", COLOR_RED + i, skillNames[i][0] ) ); } maxchars--; CG_DrawStringExt( tempx + (BG_drawStrlen(ci->name) * SMALLCHAR_WIDTH + SMALLCHAR_WIDTH), y, buf, hcolor, qfalse, qfalse, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, maxchars ); tempx += INFO_PLAYER_WIDTH - offset; if ( ci->team == TEAM_SPECTATOR ) { const char *s; int w, totalwidth; totalwidth = INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH - 8; s = CG_TranslateString( "^3SPECTATOR" ); w = CG_DrawStrlen( s ) * SMALLCHAR_WIDTH; CG_DrawSmallString( tempx + totalwidth - w, y, s, fade ); return; } // OSP - allow MV clients see the class of its merged client's on the scoreboard else if ( cg.snap->ps.persistant[PERS_TEAM] == ci->team || CG_mvMergedClientLocate(score->client) ) { CG_DrawSmallString( tempx, y, CG_TranslateString( BG_ShortClassnameForNumber( score->playerClass ) ), fade ); } tempx += INFO_CLASS_WIDTH; CG_DrawSmallString( tempx, y, va( "%3i", score->score ), fade ); if( cg_gameType.integer == GT_WOLF_LMS ) { tempx += INFO_SCORE_WIDTH; } else { tempx += INFO_XP_WIDTH; } CG_DrawSmallString( tempx, y, va( "%4i", score->ping ), fade ); tempx += INFO_LATENCY_WIDTH; if( cg_gameType.integer != GT_WOLF_LMS ) { if( score->respawnsLeft >= 0 ) { CG_DrawSmallString( tempx, y, va( "%2i", score->respawnsLeft ), fade ); } else { CG_DrawSmallString( tempx, y, va( " -", score->respawnsLeft ), fade ); } tempx += INFO_LIVES_WIDTH; } }
/** * @brief CG_DrawPMItems * @param[in] rect * @param[in] style */ void CG_DrawPMItems(rectDef_t rect, int style) { vec4_t colour = { 0.f, 0.f, 0.f, 1.f }; vec4_t colourText = { 1.f, 1.f, 1.f, 1.f }; float t; int i, j, size, w, sizew; pmListItem_t *listItem = cg_pmOldList; float y = rect.y; //360; float fontScale = cg_fontScaleSP.value; if (cg_drawSmallPopupIcons.integer) { size = PM_ICON_SIZE_SMALL; y += 4; } else { size = PM_ICON_SIZE_NORMAL; } if (cg.snap->ps.persistant[PERS_RESPAWNS_LEFT] >= 0) { y -= 20; } if (!cg_pmWaitingList) { return; } t = cg_pmWaitingList->time + cg_popupStayTime.integer; if (cg.time > t) { colourText[3] = colour[3] = 1 - ((cg.time - t) / (float)cg_popupFadeTime.integer); } if (cg_pmWaitingList->shader > 0) { // colorize for (j = 0; j < 3; j++) { colourText[j] = cg_pmWaitingList->color[j]; } trap_R_SetColor(colourText); CG_DrawPic(4, ICON_Y_OFFSET(y), size, size, cg_pmWaitingList->shader); // decolorize for (j = 0; j < 3; j++) { colourText[j] = 1.f; } trap_R_SetColor(NULL); } else { size = -2; } CG_Text_Paint_Ext(size + 6, y + 12, fontScale, fontScale, colourText, cg_pmWaitingList->message, 0, 0, style, &cgs.media.limboFont2); // 4 + size + 2 w = CG_Text_Width_Ext(cg_pmWaitingList->message, fontScale, 0, &cgs.media.limboFont2); sizew = (cg_drawSmallPopupIcons.integer) ? PM_ICON_SIZE_SMALL : PM_ICON_SIZE_NORMAL; if (cg_pmWaitingList->weaponShader > 0) { for (i = 0; i < 3; i++) { colourText[i] = cg_pmWaitingList->color[i]; } trap_R_SetColor(colourText); CG_DrawPic(size + w + 12, ICON_Y_OFFSET(y), sizew * cg_pmWaitingList->scaleShader, sizew, cg_pmWaitingList->weaponShader); // 4 + size + 2 + w + 6 for (i = 0; i < 3; i++) { colourText[i] = 1.f; } trap_R_SetColor(NULL); } else { size = (cg_drawSmallPopupIcons.integer) ? 2 : 8; sizew = 0; } if (cg_pmWaitingList->message2[0]) { CG_Text_Paint_Ext(size + w + sizew * cg_pmWaitingList->scaleShader + 16, y + 12, fontScale, fontScale, colourText, cg_pmWaitingList->message2, 0, 0, style, &cgs.media.limboFont2); // 4 + size + 2 + w + 6 + sizew*... + 4 } for (i = 0; i < 6 && listItem; i++, listItem = listItem->next) { size = (cg_drawSmallPopupIcons.integer) ? PM_ICON_SIZE_SMALL : PM_ICON_SIZE_NORMAL; y -= size + 2; t = listItem->time + cg_popupStayTime.integer; if (cg.time > t) { colourText[3] = colour[3] = 1 - ((cg.time - t) / (float)cg_popupFadeTime.integer); } else { colourText[3] = colour[3] = 1.f; } if (listItem->shader > 0) { // colorize for (j = 0; j < 3; j++) { colourText[j] = listItem->color[j]; } trap_R_SetColor(colourText); CG_DrawPic(4, ICON_Y_OFFSET(y), size, size, listItem->shader); // decolorize for (j = 0; j < 3; j++) { colourText[j] = 1.f; } trap_R_SetColor(NULL); } else { size = -2; } CG_Text_Paint_Ext(rect.x + size + 2, y + 12, fontScale, fontScale, colourText, listItem->message, 0, 0, style, &cgs.media.limboFont2); w = CG_Text_Width_Ext(listItem->message, fontScale, 0, &cgs.media.limboFont2); sizew = (cg_drawSmallPopupIcons.integer) ? PM_ICON_SIZE_SMALL : PM_ICON_SIZE_NORMAL; if (listItem->weaponShader > 0) { for (i = 0; i < 3; i++) { colourText[i] = listItem->color[i]; } trap_R_SetColor(colourText); CG_DrawPic(size + w + 12, ICON_Y_OFFSET(y), sizew * listItem->scaleShader, sizew, listItem->weaponShader); for (i = 0; i < 3; i++) { colourText[i] = 1.f; } trap_R_SetColor(NULL); } else { size = (cg_drawSmallPopupIcons.integer) ? 2 : 8; sizew = 0; } if (listItem->message2[0]) { //size + w + sizew * listItem->scaleShader + 16 CG_Text_Paint_Ext(size + w + sizew * listItem->scaleShader + 16, y + 12, fontScale, fontScale, colourText, listItem->message2, 0, 0, style, &cgs.media.limboFont2); } } }
int WM_DrawObjectives( int x, int y, int width, float fade ) { const char *s, *str; int tempy, rows; int msec, mins, seconds, tens; // JPW NERVE vec4_t tclr = { 0.6f, 0.6f, 0.6f, 1.0f }; if ( cg.snap->ps.pm_type == PM_INTERMISSION ) { const char *s, *buf, *shader = NULL, *flagshader = NULL, *nameshader = NULL; // Moved to CG_DrawIntermission /* static int doScreenshot = 0, doDemostop = 0; // OSP - End-of-level autoactions if(!cg.demoPlayback) { if(!cg.latchVictorySound) { if(cg_autoAction.integer & AA_SCREENSHOT) { doScreenshot = cg.time + 1000; } if(cg_autoAction.integer & AA_STATSDUMP) { CG_dumpStats_f(); } if((cg_autoAction.integer & AA_DEMORECORD) && (cgs.gametype == GT_WOLF_STOPWATCH && cgs.currentRound != 1)) { doDemostop = cg.time + 5000; // stats should show up within 5 seconds } } if(doScreenshot > 0 && doScreenshot < cg.time) { CG_autoScreenShot_f(); doScreenshot = 0; } if(doDemostop > 0 && doDemostop < cg.time) { trap_SendConsoleCommand("stoprecord\n"); doDemostop = 0; } } */ rows = 8; y += SMALLCHAR_HEIGHT * ( rows - 1 ); 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/assets/portraits/allies_win"; flagshader = "ui/assets/portraits/allies_win_flag.tga"; nameshader = "ui/assets/portraits/text_allies.tga"; /* if ( !cg.latchVictorySound ) { cg.latchVictorySound = qtrue; trap_S_StartLocalSound( trap_S_RegisterSound( "sound/music/allies_win.wav", qtrue ), CHAN_LOCAL_SOUND ); // FIXME: stream }*/ } else { str = "AXIS"; // shader = "ui/assets/portraits/axis_win"; flagshader = "ui/assets/portraits/axis_win_flag.tga"; nameshader = "ui/assets/portraits/text_axis.tga"; /* if ( !cg.latchVictorySound ) { cg.latchVictorySound = qtrue; trap_S_StartLocalSound( trap_S_RegisterSound( "sound/music/axis_win.wav", qtrue ), CHAN_LOCAL_SOUND ); // FIXME: stream }*/ } y += SMALLCHAR_HEIGHT * ( ( rows - 2 ) / 2 ); if ( flagshader ) { CG_DrawPic( 100, 10, 210, 136, trap_R_RegisterShaderNoMip( flagshader ) ); CG_DrawPic( 325, 10, 210, 136, trap_R_RegisterShaderNoMip( flagshader ) ); } if ( shader ) CG_DrawPic( 229, 10, 182, 136, trap_R_RegisterShaderNoMip( shader ) ); if ( nameshader ) { CG_DrawPic( 140, 50, 127, 64, trap_R_RegisterShaderNoMip( nameshader ) ); CG_DrawPic( 365, 50, 127, 64, trap_R_RegisterShaderNoMip( "ui/assets/portraits/text_win.tga" ) ); } return y; } // JPW NERVE -- mission time & reinforce time else { tempy = y; 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 { 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 ); 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 ), y + 13, 0.25f, 0.25f, tclr, s, 0, 0, 0, &cgs.media.limboFont1 ); } } // NERVE - SMF 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 ); } y += SMALLCHAR_HEIGHT * 2; } // jpw return y; }
/* ======================================================================================================================================= CG_DrawClientScore ======================================================================================================================================= */ 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; 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 (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) { 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); } 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) { 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); } // 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 void WM_DrawClientScore_Small( int x, int y, score_t *score, float *color, float fade ) { int maxchars, offset; float tempx; vec4_t hcolor; clientInfo_t *ci; if ( y + SMALLCHAR_HEIGHT >= 470 ) return; ci = &cgs.clientinfo[score->client]; if ( score->client == cg.snap->ps.clientNum ) { tempx = x; hcolor[3] = fade * 0.3; VectorSet( hcolor, .5f, .5f, .2f ); // DARK-RED CG_FillRect( tempx, y + 1, INFO_PLAYER_WIDTH - INFO_BORDER, MINICHAR_HEIGHT - 1, hcolor ); tempx += INFO_PLAYER_WIDTH; if ( ci->team == TEAM_SPECTATOR ) { int width; width = INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH; CG_FillRect( tempx, y + 1, width - INFO_BORDER, MINICHAR_HEIGHT - 1, hcolor ); tempx += width; } else { CG_FillRect( tempx, y + 1, INFO_CLASS_WIDTH - INFO_BORDER, MINICHAR_HEIGHT - 1, hcolor ); tempx += INFO_CLASS_WIDTH; if( cg_gameType.integer == GT_WOLF_LMS ) { CG_FillRect( tempx, y + 1, INFO_SCORE_WIDTH - INFO_BORDER, MINICHAR_HEIGHT - 1, hcolor ); tempx += INFO_SCORE_WIDTH; } else { CG_FillRect( tempx, y + 1, INFO_XP_WIDTH - INFO_BORDER, MINICHAR_HEIGHT - 1, hcolor ); tempx += INFO_XP_WIDTH; } CG_FillRect( tempx, y + 1, INFO_LATENCY_WIDTH - INFO_BORDER, MINICHAR_HEIGHT - 1, hcolor ); tempx += INFO_LATENCY_WIDTH; if( cg_gameType.integer != GT_WOLF_LMS ) { CG_FillRect( tempx, y + 1, INFO_LIVES_WIDTH - INFO_BORDER, MINICHAR_HEIGHT - 1, hcolor ); tempx += INFO_LIVES_WIDTH; } } } tempx = x; // DHM - Nerve VectorSet( hcolor, 1, 1, 1 ); hcolor[3] = fade; maxchars = 17; offset = 0; if ( ci->team != TEAM_SPECTATOR ) { if ( ci->powerups & ( (1 << PW_REDFLAG) | (1 << PW_BLUEFLAG) ) ) { CG_DrawPic( tempx-2, y-4, 20, 20, trap_R_RegisterShader( "models/multiplayer/treasure/treasure" ) ); offset += 14; tempx += 14; maxchars -= 2; } // draw the skull icon if out of lives if ( score->respawnsLeft == -2 || ( cgs.clientinfo[cg.clientNum].team != TEAM_SPECTATOR && ci->team == cgs.clientinfo[cg.clientNum].team && cgs.clientinfo[score->client].health == -1 ) ) { CG_DrawPic( tempx, y, 12, 12, cgs.media.scoreEliminatedShader ); offset += 14; tempx += 14; maxchars -= 2; } else if( cgs.clientinfo[cg.clientNum].team != TEAM_SPECTATOR && ci->team == cgs.clientinfo[cg.clientNum].team && cgs.clientinfo[score->client].health == 0 ) { CG_DrawPic( tempx + 1, y + 1, 10, 10, cgs.media.medicIcon ); offset += 14; tempx += 14; maxchars -= 2; } } // draw name CG_DrawStringExt( tempx, y, ci->name, hcolor, qfalse, qfalse, MINICHAR_WIDTH, MINICHAR_HEIGHT, maxchars ); tempx += INFO_PLAYER_WIDTH - offset; // dhm - nerve if ( ci->team == TEAM_SPECTATOR ) { const char *s; int w, totalwidth; totalwidth = INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH - 8; s = CG_TranslateString( "^3SPECTATOR" ); w = CG_DrawStrlen( s ) * MINICHAR_WIDTH; CG_DrawSmallString( tempx + totalwidth - w, y, s, fade ); return; } else if ( cg.snap->ps.persistant[PERS_TEAM] == ci->team ) { CG_DrawStringExt( tempx, y, CG_TranslateString( BG_ShortClassnameForNumber( score->playerClass ) ), hcolor, qfalse, qfalse, MINICHAR_WIDTH, MINICHAR_HEIGHT, 0 ); // CG_DrawSmallString( tempx, y, CG_TranslateString( s ), fade ); } tempx += INFO_CLASS_WIDTH; CG_DrawStringExt( tempx, y, va( "%3i", score->score ), hcolor, qfalse, qfalse, MINICHAR_WIDTH, MINICHAR_HEIGHT, 0 ); if( cg_gameType.integer == GT_WOLF_LMS ) { tempx += INFO_SCORE_WIDTH; } else { tempx += INFO_XP_WIDTH; } CG_DrawStringExt( tempx, y, va( "%4i", score->ping ), hcolor, qfalse, qfalse, MINICHAR_WIDTH, MINICHAR_HEIGHT, 0 ); tempx += INFO_LATENCY_WIDTH; if( cg_gameType.integer != GT_WOLF_LMS ) { if( score->respawnsLeft >= 0 ) { CG_DrawStringExt( tempx, y, va( "%2i", score->respawnsLeft ), hcolor, qfalse, qfalse, MINICHAR_WIDTH, MINICHAR_HEIGHT, 0 ); } else { CG_DrawStringExt( tempx, y, va( " -", score->respawnsLeft ), hcolor, qfalse, qfalse, MINICHAR_WIDTH, MINICHAR_HEIGHT, 0 ); } tempx += INFO_LIVES_WIDTH; } }
/** * @brief Draw FireTeam overlay * @param[in] rect */ void CG_DrawFireTeamOverlay(rectDef_t *rect) { float x = rect->x; float y = rect->y + 1; // +1, jitter it into place int i, locwidth, namewidth, puwidth, lineX; int boxWidth = 90; int bestNameWidth = -1; int bestLocWidth = -1; char buffer[64]; float h = 16; // 12 + 2 + 2 clientInfo_t *ci = NULL; fireteamData_t *f = NULL; char *locStr[MAX_FIRETEAM_MEMBERS]; int curWeap; // assign fireteam data, and early out if not on one if (!(f = CG_IsOnFireteam(cg.clientNum))) { return; } Com_Memset(locStr, 0, sizeof(char *) * MAX_FIRETEAM_MEMBERS); // First get name and location width, also store location names for (i = 0; i < MAX_FIRETEAM_MEMBERS; i++) { ci = CG_SortedFireTeamPlayerForPosition(i); // Make sure it's valid if (!ci) { break; } if (cg_locations.integer & LOC_FTEAM) { locStr[i] = CG_BuildLocationString(ci->clientNum, ci->location, LOC_FTEAM); if (!locStr[i][1] || !*locStr[i]) { locStr[i] = 0; } locwidth = CG_Text_Width_Ext(locStr[i], 0.2f, 0, FONT_TEXT); } else { locwidth = 0; } namewidth = CG_Text_Width_Ext(ci->name, 0.2f, 0, FONT_TEXT); if (ci->powerups & ((1 << PW_REDFLAG) | (1 << PW_BLUEFLAG) | (1 << PW_OPS_DISGUISED))) { namewidth += 14; } if (namewidth > bestNameWidth) { bestNameWidth = namewidth; } if (locwidth > bestLocWidth) { bestLocWidth = locwidth; } h += 12.f; } boxWidth += bestLocWidth + bestNameWidth; if (cg_fireteamLatchedClass.integer) { boxWidth += 28; } if ((Ccg_WideX(640) - MIN_BORDER_DISTANCE) < (x + boxWidth)) { x = x - ((x + boxWidth) - Ccg_WideX(640)) - MIN_BORDER_DISTANCE; } else if (x < MIN_BORDER_DISTANCE) { x = MIN_BORDER_DISTANCE; } CG_FillRect(x, y, boxWidth, h, FT_bg2); CG_DrawRect(x, y, boxWidth, h, 1, FT_border); x += 1; y += 1; CG_FillRect(x, y, boxWidth - 2, 12, FT_bg); if (f->priv) { Com_sprintf(buffer, 64, CG_TranslateString("Private Fireteam: %s"), bg_fireteamNames[f->ident]); } else { Com_sprintf(buffer, 64, CG_TranslateString("Fireteam: %s"), bg_fireteamNames[f->ident]); } Q_strupr(buffer); CG_Text_Paint_Ext(x + 4, y + FT_BAR_HEIGHT, .19f, .19f, FT_text, buffer, 0, 0, 0, FONT_HEADER); lineX = (int)x; for (i = 0; i < MAX_FIRETEAM_MEMBERS; i++) { x = lineX; y += FT_BAR_HEIGHT + FT_BAR_YSPACING; // grab a pointer to the current player ci = CG_SortedFireTeamPlayerForPosition(i); // make sure it's valid if (!ci) { break; } // hilight selected players if (ci->selected) { CG_FillRect(x, y + FT_BAR_YSPACING, boxWidth - 2, FT_BAR_HEIGHT, FT_select); } else { CG_FillRect(x, y + FT_BAR_YSPACING, boxWidth - 2, FT_BAR_HEIGHT, FT_noselect); } x += 4; // draw class icon in fireteam overlay CG_DrawPic(x, y + 2, 12, 12, cgs.media.skillPics[SkillNumForClass(ci->cls)]); x += 14; if (cg_fireteamLatchedClass.integer && ci->cls != ci->latchedcls) { // draw the yellow arrow CG_Text_Paint_Ext(x, y + FT_BAR_HEIGHT, .2f, .2f, FT_text, "^3->", 0, 0, ITEM_TEXTSTYLE_SHADOWED, FONT_TEXT); x += 14; // draw latched class icon in fireteam overlay CG_DrawPic(x, y + 2, 12, 12, cgs.media.skillPics[SkillNumForClass(ci->latchedcls)]); x += 14; } else if (cg_fireteamLatchedClass.integer) { x += 28; } // draw the mute-icon in the fireteam overlay.. //if ( ci->muted ) { // CG_DrawPic( x, y, 12, 12, cgs.media.muteIcon ); // x += 14; //} else if // draw objective icon (if they are carrying one) in fireteam overlay if (ci->powerups & ((1 << PW_REDFLAG) | (1 << PW_BLUEFLAG))) { CG_DrawPic(x, y + 2, 12, 12, cgs.media.objectiveShader); x += 14; puwidth = 14; } // or else draw the disguised icon in fireteam overlay else if (ci->powerups & (1 << PW_OPS_DISGUISED)) { CG_DrawPic(x, y + 2, 12, 12, ci->team == TEAM_AXIS ? cgs.media.alliedUniformShader : cgs.media.axisUniformShader); x += 14; puwidth = 14; } // otherwise draw rank icon in fireteam overlay else { //if (ci->rank > 0) CG_DrawPic( x, y, 12, 12, rankicons[ ci->rank ][ ci->team == TEAM_AXIS ? 1 : 0 ][0].shader ); //x += 14; puwidth = 0; } // draw the player's name CG_Text_Paint_Ext(x, y + FT_BAR_HEIGHT, .2f, .2f, colorWhite, ci->name, 0, 0, ITEM_TEXTSTYLE_SHADOWED, FONT_TEXT); // add space x += 14 + bestNameWidth - puwidth; // draw the player's weapon icon if (cg.predictedPlayerEntity.currentState.eFlags & EF_MOUNTEDTANK) { if (IS_MOUNTED_TANK_BROWNING(cg.snap->ps.clientNum)) { curWeap = WP_MOBILE_BROWNING; } else { curWeap = WP_MOBILE_MG42; } } else if ((cg.predictedPlayerEntity.currentState.eFlags & EF_MG42_ACTIVE) || (cg.predictedPlayerEntity.currentState.eFlags & EF_AAGUN_ACTIVE)) { curWeap = WP_MOBILE_MG42; } else { curWeap = cg_entities[ci->clientNum].currentState.weapon; } // note: WP_NONE is excluded if (IS_VALID_WEAPON(curWeap) && cg_weapons[curWeap].weaponIcon[0]) // do not try to draw nothing { CG_DrawPic(x, y + 2, cg_weapons[curWeap].weaponIconScale * 10, 10, cg_weapons[curWeap].weaponIcon[0]); } else if (IS_VALID_WEAPON(curWeap) && cg_weapons[curWeap].weaponIcon[1]) { CG_DrawPic(x, y + 2, cg_weapons[curWeap].weaponIconScale * 10, 10, cg_weapons[curWeap].weaponIcon[1]); } x += 24; if (ci->health >= 100) { CG_Text_Paint_Ext(x, y + FT_BAR_HEIGHT, .2f, .2f, colorGreen, va("%i", ci->health < 0 ? 0 : ci->health), 0, 0, ITEM_TEXTSTYLE_SHADOWED, FONT_TEXT); x += 12; } else if (ci->health >= 10) { x += 6; CG_Text_Paint_Ext(x, y + FT_BAR_HEIGHT, .2f, .2f, ci->health > 80 ? colorGreen : colorYellow, va("%i", ci->health < 0 ? 0 : ci->health), 0, 0, ITEM_TEXTSTYLE_SHADOWED, FONT_TEXT); x += 6; } else if (ci->health > 0) { x += 12; 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, FONT_TEXT); } else if (ci->health == 0) { x += 6; CG_Text_Paint_Ext(x, y + FT_BAR_HEIGHT, .2f, .2f, ((cg.time % 500) > 250) ? colorWhite : colorRed, "*", 0, 0, ITEM_TEXTSTYLE_SHADOWED, FONT_TEXT); x += 6; CG_Text_Paint_Ext(x, y + FT_BAR_HEIGHT, .2f, .2f, ((cg.time % 500) > 250) ? colorRed : colorWhite, "0", 0, 0, ITEM_TEXTSTYLE_SHADOWED, FONT_TEXT); } else { x += 12; CG_Text_Paint_Ext(x, y + FT_BAR_HEIGHT, .2f, .2f, colorRed, "0", 0, 0, ITEM_TEXTSTYLE_SHADOWED, FONT_TEXT); } // set hard limit on width x += 12; if (cg_locations.integer & LOC_FTEAM) { CG_Text_Paint_Ext(x, y + FT_BAR_HEIGHT, .2f, .2f, FT_text, locStr[i], 0, 0, ITEM_TEXTSTYLE_SHADOWED, FONT_TEXT); } } }
void CG_DrawConnectScreen(qboolean interactive, qboolean forcerefresh) { static qboolean inside = qfalse; char buffer[1024]; bg_loadscreeninteractive = interactive; if (!DC) { return; } if (inside) { return; } inside = qtrue; if (!bg_loadscreeninited) { trap_Cvar_Set("ui_connecting", "0"); DC->registerFont("ariblk", 27, &bg_loadscreenfont1); DC->registerFont("courbd", 30, &bg_loadscreenfont2); bg_axispin = DC->registerShaderNoMip("gfx/loading/pin_axis"); bg_alliedpin = DC->registerShaderNoMip("gfx/loading/pin_allied"); bg_neutralpin = DC->registerShaderNoMip("gfx/loading/pin_neutral"); bg_pin = DC->registerShaderNoMip("gfx/loading/pin_shot"); bg_filter_pb = DC->registerShaderNoMip("ui/assets/filter_pb"); bg_filter_ff = DC->registerShaderNoMip("ui/assets/filter_ff"); bg_filter_hw = DC->registerShaderNoMip("ui/assets/filter_weap"); bg_filter_lv = DC->registerShaderNoMip("ui/assets/filter_lives"); bg_filter_al = DC->registerShaderNoMip("ui/assets/filter_antilag"); bg_filter_bt = DC->registerShaderNoMip("ui/assets/filter_balance"); bg_mappic = 0; BG_PanelButtonsSetup(loadpanelButtons); bg_loadscreeninited = qtrue; } BG_PanelButtonsRender(loadpanelButtons); if (interactive) { DC->drawHandlePic(DC->cursorx, DC->cursory, 32, 32, DC->Assets.cursor); } DC->getConfigString(CS_SERVERINFO, buffer, sizeof(buffer)); if (*buffer) { const char *str; qboolean enabled = qfalse; float x, y; int i; // vec4_t clr1 = { 41/255.f, 51/255.f, 43/255.f, 204/255.f }; // vec4_t clr2 = { 0.f, 0.f, 0.f, 225/255.f }; vec4_t clr3 = { 1.f, 1.f, 1.f, .6f }; /* CG_FillRect( 8, 8, 230, 16, clr1 ); CG_DrawRect_FixedBorder( 8, 8, 230, 16, 1, colorMdGrey ); CG_FillRect( 8, 23, 230, 210, clr2 ); CG_DrawRect_FixedBorder( 8, 23, 230, 216, 1, colorMdGrey );*/ y = 322; CG_Text_Paint_Centred_Ext(540, y, 0.22f, 0.22f, clr3, "SERVER INFO", 0, 0, 0, &bg_loadscreenfont1); y = 340; str = Info_ValueForKey(buffer, "sv_hostname"); CG_Text_Paint_Centred_Ext(540, y, 0.2f, 0.2f, colorWhite, str && *str ? str : "ETHost", 0, 26, 0, &bg_loadscreenfont2); y += 14; for (i = 0; i < MAX_MOTDLINES; i++) { str = CG_ConfigString(CS_CUSTMOTD + i); if (!str || !*str) { break; } CG_Text_Paint_Centred_Ext(540, y, 0.2f, 0.2f, colorWhite, str, 0, 26, 0, &bg_loadscreenfont2); y += 10; } y = 417; str = Info_ValueForKey(buffer, "g_friendlyfire"); if (str && *str && atoi(str)) { x = 461; CG_DrawPic(x, y, 16, 16, bg_filter_ff); } if (atoi(Info_ValueForKey(buffer, "g_gametype")) != GT_WOLF_LMS) { str = Info_ValueForKey(buffer, "g_alliedmaxlives"); if (str && *str && atoi(str)) { enabled = qtrue; } else { str = Info_ValueForKey(buffer, "g_axismaxlives"); if (str && *str && atoi(str)) { enabled = qtrue; } else { str = Info_ValueForKey(buffer, "g_maxlives"); if (str && *str && atoi(str)) { enabled = qtrue; } } } } if (enabled) { x = 489; CG_DrawPic(x, y, 16, 16, bg_filter_lv); } str = Info_ValueForKey(buffer, "sv_punkbuster"); if (str && *str && atoi(str)) { x = 518; CG_DrawPic(x, y, 16, 16, bg_filter_pb); } str = Info_ValueForKey(buffer, "g_heavyWeaponRestriction"); if (str && *str && atoi(str) != 100) { x = 546; CG_DrawPic(x, y, 16, 16, bg_filter_hw); } str = Info_ValueForKey(buffer, "g_antilag"); if (str && *str && atoi(str)) { x = 575; CG_DrawPic(x, y, 16, 16, bg_filter_al); } str = Info_ValueForKey(buffer, "g_balancedteams"); if (str && *str && atoi(str)) { x = 604; CG_DrawPic(x, y, 16, 16, bg_filter_bt); } } if (*cgs.rawmapname) { if (!bg_mappic) { bg_mappic = DC->registerShaderNoMip(va("levelshots/%s", cgs.rawmapname)); if (!bg_mappic) { bg_mappic = DC->registerShaderNoMip("levelshots/unknownmap"); } } trap_R_SetColor(colorBlack); CG_DrawPic(16 + 1, 2 + 1, 192, 144, bg_mappic); trap_R_SetColor(NULL); CG_DrawPic(16, 2, 192, 144, bg_mappic); CG_DrawPic(16 + 80, 2 + 6, 20, 20, bg_pin); } if (forcerefresh) { DC->updateScreen(); } inside = qfalse; }