/* ============== 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); } }
// FIXME: add more options to shorten this box void CG_DrawFireTeamOverlay(rectDef_t *rect) { int x = rect->x; int y = rect->y + 1; // +1, jitter it into place in 1024 :) 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]; vec3_t origin; int curWeap; // assign fireteam data, and early out if not on one if (!(f = CG_IsOnFireteam(cg.clientNum))) { return; } 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) { origin[0] = ci->location[0]; origin[1] = ci->location[1]; locStr[i] = CG_BuildLocationString(ci->clientNum, origin, LOC_FTEAM); if (!locStr[i][1] || !*locStr[i]) { locStr[i] = ""; } locwidth = CG_Text_Width_Ext(locStr[i], 0.2f, 0, &cgs.media.limboFont2); } else { locwidth = 0; } namewidth = CG_Text_Width_Ext(ci->name, 0.2f, 0, &cgs.media.limboFont2); 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)) { float realw = Ccg_WideX(640); x = x - ((x + boxWidth) - realw) - MIN_BORDER_DISTANCE; } else if (x < MIN_BORDER_DISTANCE) { x = MIN_BORDER_DISTANCE; } CG_DrawRect(x, y, boxWidth, h, 1, borderColor); CG_FillRect(x + 1, y + 1, boxWidth - 2, h - 2, bgColor); x += 2; y += 2; CG_FillRect(x, y, boxWidth - 4, 12, clr1); 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 + 3, y + FT_BAR_HEIGHT, .19f, .19f, tclr, buffer, 0, 0, 0, &cgs.media.limboFont1); x += 2; lineX = 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 - 6, FT_BAR_HEIGHT, clr3); } else { CG_FillRect(x, y + FT_BAR_YSPACING, boxWidth - 6, FT_BAR_HEIGHT, clr2); } x += 4; // draw class icon in fireteam overlay CG_DrawPic(x, y, 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, tclr, "^3->", 0, 0, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2); x += 14; // draw latched class icon in fireteam overlay CG_DrawPic(x, y, 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, 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, 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, &cgs.media.limboFont2); // add space x += 14 + bestNameWidth - puwidth; // draw the player's weapon icon if (cg.predictedPlayerEntity.currentState.eFlags & EF_MOUNTEDTANK) { if (cg_entities[cg_entities[cg_entities[cg.snap->ps.clientNum].tagParent].tankparent].currentState.density & 8) { curWeap = WP_MOBILE_BROWNING; } else { curWeap = WP_MOBILE_MG42; } } else if (cg.predictedPlayerEntity.currentState.eFlags & EF_MG42_ACTIVE) { curWeap = WP_MOBILE_MG42; } else { curWeap = cg_entities[ci->clientNum].currentState.weapon; } if (cg_weapons[curWeap].weaponIcon[0]) // do not try to draw nothing { CG_DrawPic(x, y, CG_WeaponIconScale(curWeap) * 10, 10, cg_weapons[curWeap].weaponIcon[0]); } else if (cg_weapons[curWeap].weaponIcon[1]) { CG_DrawPic(x, y, CG_WeaponIconScale(curWeap) * 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, &cgs.media.limboFont2); 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, &cgs.media.limboFont2); 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, &cgs.media.limboFont2); } 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, &cgs.media.limboFont2); 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, &cgs.media.limboFont2); } else { x += 12; CG_Text_Paint_Ext(x, y + FT_BAR_HEIGHT, .2f, .2f, colorRed, "0", 0, 0, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2); } // set hard limit on width x += 12; if (cg_locations.integer & LOC_FTEAM) { CG_Text_Paint_Ext(x, y + FT_BAR_HEIGHT, .2f, .2f, tclr, locStr[i], 0, 0, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2); } } }