void CG_DrawLivesLeft(hudComponent_t comp) { if (cg_gameType.integer == GT_WOLF_LMS) { return; } if (cg.snap->ps.persistant[PERS_RESPAWNS_LEFT] < 0) { return; } CG_DrawPic(4, 360, 48, 24, cg.snap->ps.persistant[PERS_TEAM] == TEAM_ALLIES ? cgs.media.hudAlliedHelmet : cgs.media.hudAxisHelmet); CG_DrawField(44, 360, 3, cg.snap->ps.persistant[PERS_RESPAWNS_LEFT], 14, 20, qtrue, qtrue); }
/* ================== CG_BuildableStatusDisplay ================== */ static void CG_BuildableStatusDisplay( centity_t *cent ) { entityState_t *es = ¢->currentState; vec3_t origin; float healthScale; int health; float x, y; vec4_t color; qboolean powered, marked; trace_t tr; float d; buildStat_t *bs; int i, j; int entNum; vec3_t trOrigin; vec3_t right; qboolean visible = qfalse; vec3_t mins, maxs; entityState_t *hit; if( BG_FindTeamForBuildable( es->modelindex ) == BIT_ALIENS ) bs = &cgs.alienBuildStat; else bs = &cgs.humanBuildStat; if( !bs->loaded ) return; d = Distance( cent->lerpOrigin, cg.refdef.vieworg ); if( d > STATUS_MAX_VIEW_DIST ) return; Vector4Copy( bs->foreColor, color ); // trace for center point BG_FindBBoxForBuildable( es->modelindex, mins, maxs ); VectorCopy( cent->lerpOrigin, origin ); // center point origin[ 2 ] += mins[ 2 ]; origin[ 2 ] += ( abs( mins[ 2 ] ) + abs( maxs[ 2 ] ) ) / 2; entNum = cg.predictedPlayerState.clientNum; // if first try fails, step left, step right for( j = 0; j < 3; j++ ) { VectorCopy( cg.refdef.vieworg, trOrigin ); switch( j ) { case 1: // step right AngleVectors( cg.refdefViewAngles, NULL, right, NULL ); VectorMA( trOrigin, STATUS_PEEK_DIST, right, trOrigin ); break; case 2: // step left AngleVectors( cg.refdefViewAngles, NULL, right, NULL ); VectorMA( trOrigin, -STATUS_PEEK_DIST, right, trOrigin ); break; default: break; } // look through up to 3 players and/or transparent buildables for( i = 0; i < 3; i++ ) { CG_Trace( &tr, trOrigin, NULL, NULL, origin, entNum, MASK_SHOT ); if( tr.entityNum == cent->currentState.number ) { visible = qtrue; break; } if( tr.entityNum == ENTITYNUM_WORLD ) break; hit = &cg_entities[ tr.entityNum ].currentState; if( tr.entityNum < MAX_CLIENTS || ( hit->eType == ET_BUILDABLE && ( !( es->generic1 & B_SPAWNED_TOGGLEBIT ) || BG_FindTransparentTestForBuildable( hit->modelindex ) ) ) ) { entNum = tr.entityNum; VectorCopy( tr.endpos, trOrigin ); } else break; } } // hack to make the kit obscure view if( cg_drawGun.integer && visible && cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_HUMANS && CG_WorldToScreen( origin, &x, &y ) ) { if( x > 450 && y > 290 ) visible = qfalse; } if( !visible && cent->buildableStatus.visible ) { cent->buildableStatus.visible = qfalse; cent->buildableStatus.lastTime = cg.time; } else if( visible && !cent->buildableStatus.visible ) { cent->buildableStatus.visible = qtrue; cent->buildableStatus.lastTime = cg.time; } // Fade up if( cent->buildableStatus.visible ) { if( cent->buildableStatus.lastTime + STATUS_FADE_TIME > cg.time ) color[ 3 ] = (float)( cg.time - cent->buildableStatus.lastTime ) / STATUS_FADE_TIME; } // Fade down if( !cent->buildableStatus.visible ) { if( cent->buildableStatus.lastTime + STATUS_FADE_TIME > cg.time ) color[ 3 ] = 1.0f - (float)( cg.time - cent->buildableStatus.lastTime ) / STATUS_FADE_TIME; else return; } health = es->generic1 & B_HEALTH_MASK; healthScale = (float)health / B_HEALTH_MASK; if( health > 0 && healthScale < 0.01f ) healthScale = 0.01f; else if( healthScale < 0.0f ) healthScale = 0.0f; else if( healthScale > 1.0f ) healthScale = 1.0f; if( CG_WorldToScreen( origin, &x, &y ) ) { float picH = bs->frameHeight; float picW = bs->frameWidth; float picX = x; float picY = y; float scale; float subH, subY; vec4_t frameColor; // this is fudged to get the width/height in the cfg to be more realistic scale = ( picH / d ) * 3; powered = es->generic1 & B_POWERED_TOGGLEBIT; marked = es->generic1 & B_MARKED_TOGGLEBIT; picH *= scale; picW *= scale; picX -= ( picW * 0.5f ); picY -= ( picH * 0.5f ); // sub-elements such as icons and number subH = picH - ( picH * bs->verticalMargin ); subY = picY + ( picH * 0.5f ) - ( subH * 0.5f ); if( bs->frameShader ) { Vector4Copy( bs->backColor, frameColor ); frameColor[ 3 ] = color[ 3 ]; trap_R_SetColor( frameColor ); CG_DrawPic( picX, picY, picW, picH, bs->frameShader ); trap_R_SetColor( NULL ); } if( health > 0 ) { float hX, hY, hW, hH; vec4_t healthColor; hX = picX + ( bs->healthPadding * scale ); hY = picY + ( bs->healthPadding * scale ); hH = picH - ( bs->healthPadding * 2.0f * scale ); hW = picW * healthScale - ( bs->healthPadding * 2.0f * scale ); if( healthScale == 1.0f ) Vector4Copy( bs->healthLowColor, healthColor ); else if( healthScale >= 0.75f ) Vector4Copy( bs->healthGuardedColor, healthColor ); else if( healthScale >= 0.50f ) Vector4Copy( bs->healthElevatedColor, healthColor ); else if( healthScale >= 0.25f ) Vector4Copy( bs->healthHighColor, healthColor ); else Vector4Copy( bs->healthSevereColor, healthColor ); healthColor[ 3 ] = color[ 3 ]; trap_R_SetColor( healthColor ); CG_DrawPic( hX, hY, hW, hH, cgs.media.whiteShader ); trap_R_SetColor( NULL ); } if( bs->overlayShader ) { float oW = bs->overlayWidth; float oH = bs->overlayHeight; float oX = x; float oY = y; oH *= scale; oW *= scale; oX -= ( oW * 0.5f ); oY -= ( oH * 0.5f ); trap_R_SetColor( frameColor ); CG_DrawPic( oX, oY, oW, oH, bs->overlayShader ); trap_R_SetColor( NULL ); } trap_R_SetColor( color ); if( !powered ) { float pX; pX = picX + ( subH * bs->horizontalMargin ); CG_DrawPic( pX, subY, subH, subH, bs->noPowerShader ); } if( marked ) { float mX; mX = picX + picW - ( subH * bs->horizontalMargin ) - subH; CG_DrawPic( mX, subY, subH, subH, bs->markedShader ); } { float nX; int healthMax; int healthPoints; healthMax = BG_FindHealthForBuildable( es->modelindex ); healthPoints = (int)( healthScale * healthMax ); if( health > 0 && healthPoints < 1 ) healthPoints = 1; nX = picX + ( picW * 0.5f ) - 2.0f - ( ( subH * 4 ) * 0.5f ); if( healthPoints > 999 ) nX -= 0.0f; else if( healthPoints > 99 ) nX -= subH * 0.5f; else if( healthPoints > 9 ) nX -= subH * 1.0f; else nX -= subH * 1.5f; CG_DrawField( nX, subY, 4, subH, subH, healthPoints ); } trap_R_SetColor( NULL ); } }
/* ================ 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 {