Exemplo n.º 1
0
// Explicit server command to remove a view from the client's snapshot
void CG_mvDelete_f(void)
{
	if (cg.demoPlayback)
	{
		return;
	}
	else
	{
		int pID = -1;

		if (trap_Argc() > 1)
		{
			char aName[64];

			trap_Args(aName, sizeof(aName));
			pID = CG_findClientNum(aName);
		}
		else
		{
			cg_window_t *w = cg.mvCurrentActive;

			if (w != NULL)
			{
				pID = (w->mvInfo & MV_PID);
			}
		}

		if (pID >= 0 && CG_mvMergedClientLocate(pID))
		{
			trap_SendClientCommand(va("mvdel %d\n", pID));
		}
	}
}
Exemplo n.º 2
0
// Explicit server command to add a view to the client's snapshot
void CG_mvNew_f(void)
{
    if(cg.demoPlayback || trap_Argc() < 2) return;
    else {
        int pID;
        char aName[64];

        trap_Args(aName, sizeof(aName));
        pID = CG_findClientNum(aName);

        if(pID >= 0 && !CG_mvMergedClientLocate(pID)) {
            trap_SendClientCommand(va("mvadd %d\n", pID));
        }
    }
}
Exemplo n.º 3
0
/*
===================
CG_TransitionSnapshot

The transition point from snap to nextSnap has passed
===================
*/
static void CG_TransitionSnapshot( void ) {
	centity_t			*cent;
	snapshot_t			*oldFrame;
	int					i, id;

	if ( !cg.snap ) {
		CG_Error( "CG_TransitionSnapshot: NULL cg.snap" );
	}
	if ( !cg.nextSnap ) {
		CG_Error( "CG_TransitionSnapshot: NULL cg.nextSnap" );
	}

	// execute any server string commands before transitioning entities
	CG_ExecuteNewServerCommands( cg.nextSnap->serverCommandSequence );

	// if we had a map_restart, set everthing with initial
	
	if ( !(cg.snap) || !(cg.nextSnap) ) {
		return;
	}

	// rain - I hate doing things like this for enums.  Oh well.
	memset(&oldValid, 0, sizeof(oldValid));

	// clear the currentValid flag for all entities in the existing snapshot
	for ( i = 0 ; i < cg.snap->numEntities ; i++ ) {
		cent = &cg_entities[ cg.snap->entities[ i ].number ];
		cent->currentValid = qfalse;
		oldValid[cg.snap->entities[i].number] = qtrue;
	}

	// OSP -- check for MV updates from new snapshot info
#ifdef MV_SUPPORT
	if(cg.snap->ps.powerups[PW_MVCLIENTLIST] != cg.mvClientList) {
		CG_mvProcessClientList();
	}
#endif

	// move nextSnap to snap and do the transitions
	oldFrame = cg.snap;
	cg.snap = cg.nextSnap;

	if( cg.snap->ps.clientNum == cg.clientNum ) {
		if( cg.xp < cg.snap->ps.stats[STAT_XP] ) {
			cg.xpChangeTime = cg.time;
		}
		cg.xp = cg.snap->ps.stats[STAT_XP];
	}

	BG_PlayerStateToEntityState( &cg.snap->ps, &cg_entities[ cg.snap->ps.clientNum ].currentState, qfalse );
	cg_entities[ cg.snap->ps.clientNum ].interpolate = qfalse;

	for ( i = 0 ; i < cg.snap->numEntities ; i++ ) {
		id = cg.snap->entities[ i ].number;
		CG_TransitionEntity( &cg_entities[ id ] );

		// rain - #374 - ent doesn't exist in this frame, reset it.
		// this is to fix the silent landmines bug, which is caused
		// by a stale miscTime in the cent
		if (cg_entities[id].currentValid == qfalse && oldValid[id] == qtrue) {
			CG_ResetEntity(&cg_entities[id]);
		}

		if(cg.mvTotalClients > 0 && CG_mvMergedClientLocate(id)) {
			CG_mvUpdateClientInfo(id);
		}
	}

	if(cg.mvTotalClients > 0) {
		CG_mvTransitionPlayerState(&cg.snap->ps);
	}

	cg.nextSnap = NULL;

	// check for playerstate transition events
	if ( oldFrame ) {
		playerState_t	*ops, *ps;

		ops = &oldFrame->ps;
		ps = &cg.snap->ps;
		// teleporting checks are irrespective of prediction
		if ( ( ps->eFlags ^ ops->eFlags ) & EF_TELEPORT_BIT ) {
			cg.thisFrameTeleport = qtrue;	// will be cleared by prediction code
		}

		// if we are not doing client side movement prediction for any
		// reason, then the client events and view changes will be issued now
		if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW)
			|| cg_nopredict.integer 
#ifdef ALLOW_GSYNC
			|| cg_synchronousClients.integer 
#endif // ALLOW_GSYNC
		) {
			CG_TransitionPlayerState( ps, ops );
		}
	}

}
Exemplo n.º 4
0
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;
	}
}
Exemplo n.º 5
0
static void WM_DrawClientScore(int x, int y, score_t * score, float *color, float fade)
{
	int             maxchars, offset;
	int             i, j;
	float           tempx;
	vec4_t          hcolor;
	clientInfo_t   *ci;
	char            buf[64];

	// CHRUKER: b0?? - Was using the wrong char height for this calculation
	if(y + SMALLCHAR_HEIGHT >= 470)
	{
		return;
	}

	ci = &cgs.clientinfo[score->client];

	if(score->client == cg.snap->ps.clientNum)
	{
		hcolor[3] = fade * 0.3;
		VectorSet(hcolor, .5f, .5f, .2f);	// DARK-RED

		// CHRUKER: b077 - Player highlighting was split into columns
		CG_FillRect( x-5, y, (INFO_PLAYER_WIDTH + INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH + 5), SMALLCHAR_HEIGHT - 1, hcolor );
	}

	tempx = x;

	// DHM - Nerve
	VectorSet(hcolor, 1, 1, 1);
	hcolor[3] = fade;

	maxchars = 16;
	offset = 0;

	if(ci->team != TEAM_SPECTATOR)
	{
		if(ci->powerups & ((1 << PW_REDFLAG) | (1 << PW_BLUEFLAG)))
		{
			// CHRUKER: b078 - Medic, death and objective icons on the scoreboard are drawn too big
			CG_DrawPic( tempx - 3, y + 1, 14, 14, cgs.media.objectiveShader );
			offset += 14;	// CHRUKER: b072 - Need to match tempx or else the other text gets offset
			tempx += 14;
			maxchars -= 2;
		}

		// draw the skull icon if out of lives
		if(score->respawnsLeft == -2 ||
		   (cgs.clientinfo[cg.clientNum].team != TEAM_SPECTATOR && ci->team == cgs.clientinfo[cg.clientNum].team &&
			cgs.clientinfo[score->client].health == -1))
		{
			// CHRUKER: b078 - Medic, death and objective icons on the scoreboard are drawn too big
			CG_DrawPic( tempx - 3, y + 1, 14, 14, cgs.media.scoreEliminatedShader );
			offset += 14;
			tempx += 14;
			maxchars -= 2;
		}
		else if(cgs.clientinfo[cg.clientNum].team != TEAM_SPECTATOR && ci->team == cgs.clientinfo[cg.clientNum].team &&
				cgs.clientinfo[score->client].health == 0)
		{
			// CHRUKER: b078 - Medic, death and objective icons on the scoreboard are drawn too big
			CG_DrawPic( tempx - 3, y + 1, 14, 14, cgs.media.medicIcon );
			offset += 14;
			tempx += 14;
			maxchars -= 2;
		}
	}

	// draw name
	CG_DrawStringExt(tempx, y, ci->name, hcolor, qfalse, qfalse, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, maxchars);
	maxchars -= CG_DrawStrlen(ci->name);

	// draw medals
	buf[0] = '\0';
	for(i = 0; i < SK_NUM_SKILLS; i++)
	{
		for(j = 0; j < ci->medals[i]; j++)
			Q_strcat(buf, sizeof(buf), va("^%c%c", COLOR_RED + i, skillNames[i][0]));
	}
	maxchars--;

	// CHRUKER: b032 - Medals clipped wrong in scoreboard when you're dead, because CG_DrawStringExt will draw
	//                 everything if maxchars <= 0
	if (maxchars > 0)
	{
		CG_DrawStringExt(tempx + (BG_drawStrlen(ci->name) * SMALLCHAR_WIDTH + SMALLCHAR_WIDTH), y, buf, hcolor, qfalse, qfalse,
						 SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, maxchars);
	}

	tempx += INFO_PLAYER_WIDTH - offset;

	if(ci->team == TEAM_SPECTATOR)
	{
		const char     *s;
		int             w, totalwidth;

		totalwidth = INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH - 8;

		// CHRUKER: b031 -  Show connecting people as connecting
		if (score->ping == -1)
		{
			s = CG_TranslateString( "^1CONNECTING" );
		}
		else
		{
			s = CG_TranslateString( "^3SPECTATOR" );
		}
		w = CG_DrawStrlen(s) * SMALLCHAR_WIDTH;

		CG_DrawSmallString(tempx + totalwidth - w, y, s, fade);
		return;
	}
	// OSP - allow MV clients see the class of its merged client's on the scoreboard
	else if(cg.snap->ps.persistant[PERS_TEAM] == ci->team || CG_mvMergedClientLocate(score->client))
	{
		CG_DrawSmallString(tempx, y, CG_TranslateString(BG_ShortClassnameForNumber(score->playerClass)), fade);
	}
	tempx += INFO_CLASS_WIDTH;

	CG_DrawSmallString(tempx, y, va("%3i", score->score), fade);
	if(cg_gameType.integer == GT_WOLF_LMS)
	{
		tempx += INFO_SCORE_WIDTH;
	}
	else
	{
		tempx += INFO_XP_WIDTH;
	}

	CG_DrawSmallString(tempx, y, va("%4i", score->ping), fade);
	tempx += INFO_LATENCY_WIDTH;

	if(cg_gameType.integer != GT_WOLF_LMS)
	{
		if(score->respawnsLeft >= 0)
		{
			CG_DrawSmallString(tempx, y, va("%2i", score->respawnsLeft), fade);
		}
		else
		{
			CG_DrawSmallString(tempx, y, " -", fade);
		}
		tempx += INFO_LIVES_WIDTH;
	}
}
Exemplo n.º 6
0
static void WM_DrawClientScore(int x, int y, score_t *score, float *color, float fade, qboolean livesleft)
{
	int          maxchars = 16, offset = 0;
	int          i, j;
	float        tempx;
	vec4_t       hcolor;
	clientInfo_t *ci;
	char         buf[64];

	if (y + 16 >= 470)
	{
		return;
	}

	ci = &cgs.clientinfo[score->client];

	if (score->client == cg.snap->ps.clientNum)
	{
		hcolor[3] = fade * 0.3;
		VectorSet(hcolor, .5f, .5f, .2f);           // DARK-RED

		CG_FillRect(x - 5, y, (INFO_TOTAL_WIDTH + 5), 15, hcolor);
	}

	tempx = x;

	VectorSet(hcolor, 1, 1, 1);
	hcolor[3] = fade;

	y += 12;

	// add some extra space when not showing lives in non-LMS
	if (cg_gameType.integer != GT_WOLF_LMS && !livesleft)
	{
		maxchars += 2;
	}

	// draw GeoIP flag
	if (score->ping != -1 && score->ping != 999 && cg_countryflags.integer)
	{
		if (CG_DrawFlag(tempx - 3, y - 11, fade, ci->clientNum))
		{
			offset   += 15;
			tempx    += 15;
			maxchars -= 2;
		}
	}

	if (ci->team != TEAM_SPECTATOR)
	{
		// draw ready icon if client is ready..
		if ((score->scoreflags & 1) && cgs.gamestate != GS_PLAYING)
		{
			CG_DrawPic(tempx - 1, y - 10, 10, 10, cgs.media.readyShader);
			offset   += 12;
			tempx    += 12;
			maxchars -= 2;
		}

		if (ci->powerups & ((1 << PW_REDFLAG) | (1 << PW_BLUEFLAG)))
		{
			CG_DrawPic(tempx - 1, y - 10, 10, 10, cgs.media.objectiveShader);
			offset   += 12;
			tempx    += 12;
			maxchars -= 2;
		}
		else if (cgs.clientinfo[cg.clientNum].team != TEAM_SPECTATOR && ci->team == cgs.clientinfo[cg.clientNum].team && (ci->powerups & (1 << PW_OPS_DISGUISED)))
		{
			CG_DrawPic(tempx - 1, y - 10, 10, 10, ci->team == TEAM_AXIS ? cgs.media.alliedUniformShader : cgs.media.axisUniformShader);
			offset   += 12;
			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 - 1, y - 10, 10, 10, cgs.media.scoreEliminatedShader);
			offset   += 12;
			tempx    += 12;
			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 - 10, 10, 10, cgs.media.medicIcon);
			offset   += 12;
			tempx    += 12;
			maxchars -= 2;
		}
	}

	// draw name
	CG_Text_Paint_Ext(tempx, y, 0.24, 0.28, colorWhite, ci->name, 0, maxchars, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2_lo);
	maxchars -= CG_Text_Width_Ext(ci->name, 0.24, 0, &cgs.media.limboFont2_lo);

	// 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_Text_Paint_Ext will draw everything if maxchars <= 0
	if (maxchars > 0)
	{
		CG_Text_Paint_Ext(tempx + (CG_drawStrlen(ci->name) * 8 + 8), y, 0.24, 0.28, colorWhite, buf, 0, maxchars, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2_lo);
	}

	tempx += INFO_PLAYER_WIDTH - offset;

	// add the extra room here
	if (cg_gameType.integer != GT_WOLF_LMS && !livesleft && ci->team != TEAM_SPECTATOR)
	{
		tempx += INFO_LIVES_WIDTH;
	}

	if (ci->team == TEAM_SPECTATOR)
	{
		const char *s;
		int        w, totalwidth = INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH - 8;

		// Show connecting people as CONNECTING
		if (score->ping == -1)
		{
			s = CG_TranslateString("^3CONNECTING");
		}
		else
		{
			s = CG_TranslateString("^3SPECTATOR");
		}
		w = CG_Text_Width_Ext(s, 0.24, 0, &cgs.media.limboFont2_lo);
		CG_Text_Paint_Ext(tempx + totalwidth - w, y, 0.24, 0.28, colorYellow, s, 0, 0, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2_lo);
		return;
	}
	// allow MV clients see the class of its merged client's on the scoreboard
	else if (cg.snap->ps.persistant[PERS_TEAM] == ci->team || cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR || cg.snap->ps.pm_type == PM_INTERMISSION
#if FEATURE_MULTIVIEW
	         || CG_mvMergedClientLocate(score->client)
#endif
	         )
	{
		CG_DrawPic(tempx - 3, y - 12, 14, 14, cgs.media.skillPics[SkillNumForClass(ci->cls)]);

		if (cgs.clientinfo[ci->clientNum].rank > 0)
		{
			CG_DrawPic(tempx + 13, y - 12, 16, 16, rankicons[cgs.clientinfo[ci->clientNum].rank][cgs.clientinfo[ci->clientNum].team == TEAM_AXIS ? 1 : 0][0].shader);
		}
	}

	tempx += INFO_CLASS_WIDTH;

	CG_Text_Paint_Ext(tempx, y, 0.24, 0.28, colorWhite, va("^7%3i", score->score), 0, 0, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2_lo);
	if (cg_gameType.integer == GT_WOLF_LMS)
	{
		tempx += INFO_SCORE_WIDTH;
	}
	else
	{
		tempx += INFO_XP_WIDTH;
	}

	if (score->ping == -1)
	{
		CG_Text_Paint_Ext(tempx, y, 0.24, 0.28, colorRed, "^1CONN^7", 0, 0, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2_lo);
	}
	else if (score->scoreflags & 2)
	{
		CG_Text_Paint_Ext(tempx, y, 0.24, 0.28, colorWhite, " BOT", 0, 0, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2_lo);
	}
	else
	{
		CG_Text_Paint_Ext(tempx, y, 0.24, 0.28, colorWhite, va("%4i", score->ping), 0, 0, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2_lo);
	}
	tempx += INFO_LATENCY_WIDTH;

	if (cg_gameType.integer != GT_WOLF_LMS && livesleft)
	{
		if (score->respawnsLeft >= 0)
		{
			CG_Text_Paint_Ext(tempx, y, 0.24, 0.28, colorWhite, va("%2i", score->respawnsLeft), 0, 0, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2_lo);
		}
		else
		{
			CG_Text_Paint_Ext(tempx, y, 0.24, 0.28, colorWhite, " -", 0, 0, ITEM_TEXTSTYLE_SHADOWED, &cgs.media.limboFont2_lo);
		}
	}
}
Exemplo n.º 7
0
static void WM_DrawClientScore(int x, int y, score_t *score, float *color, float fade)
{
	int          maxchars, offset;
	int          i, j;
	float        tempx;
	vec4_t       hcolor;
	clientInfo_t *ci;
	char         buf[64];

	if (y + SMALLCHAR_HEIGHT >= 470)
	{
		return;
	}

	ci = &cgs.clientinfo[score->client];

	if (score->client == cg.snap->ps.clientNum)
	{
		hcolor[3] = fade * 0.3;
		VectorSet(hcolor, .5f, .5f, .2f);           // DARK-RED

		CG_FillRect(x - 5, y, (INFO_TOTAL_WIDTH + 5), SMALLCHAR_HEIGHT - 1, hcolor);
	}

	tempx = x;

	VectorSet(hcolor, 1, 1, 1);
	hcolor[3] = fade;

	maxchars = 16;
	offset   = 0;

	if (ci->team != TEAM_SPECTATOR)
	{
		/* FIXME: adjust x,y coordinates ...
		// draw ready icon if client is ready..
		if (score->scoreflags & 1 && cgs.gamestate != GS_PLAYING)
		{
		    CG_DrawPic(tempx - 3, y + 1, 14, 14, cgs.media.readyIcon);
		    offset += 14;
		    tempx += 14;
		    maxchars -= 2;
		}
		*/

		if (ci->powerups & ((1 << PW_REDFLAG) | (1 << PW_BLUEFLAG)))
		{
			CG_DrawPic(tempx - 1, y + 1, 10, 10, cgs.media.objectiveShader);
			offset   += 10;
			tempx    += 10;
			maxchars -= 2;
		}

		// draw the skull icon if out of lives
		if (score->respawnsLeft == -2 || (cgs.clientinfo[cg.clientNum].team != TEAM_SPECTATOR && ci->team == cgs.clientinfo[cg.clientNum].team && cgs.clientinfo[score->client].health == -1))
		{
			CG_DrawPic(tempx - 1, y + 1, 10, 10, cgs.media.scoreEliminatedShader);
			offset   += 10;
			tempx    += 10;
			maxchars -= 2;
		}
		else if (cgs.clientinfo[cg.clientNum].team != TEAM_SPECTATOR && ci->team == cgs.clientinfo[cg.clientNum].team && cgs.clientinfo[score->client].health == 0)
		{
			CG_DrawPic(tempx - 1, y + 1, 10, 10, cgs.media.medicIcon);
			offset   += 10;
			tempx    += 10;
			maxchars -= 2;
		}
	}

	// GeoIP - draw flag before name
	if (score->ping != -1 && score->ping != 999 && cg_countryflags.integer)
	{
		if (cf_draw(tempx - 11, y - 8, fade, ci->clientNum))
		{
			offset   += 14;
			tempx    += 14;
			maxchars -= 2;
		}
	}

	// draw name
	CG_DrawStringExt(tempx, y, ci->name, hcolor, qfalse, qfalse, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, maxchars);
	maxchars -= CG_DrawStrlen(ci->name);

	// draw medals
	buf[0] = '\0';
	for (i = 0; i < SK_NUM_SKILLS; i++)
	{
		for (j = 0; j < ci->medals[i]; j++)
		{
			Q_strcat(buf, sizeof(buf), va("^%c%c", COLOR_RED + i, skillNames[i][0]));
		}
	}
	maxchars--;

	// CG_DrawStringExt will draw everything if maxchars <= 0
	if (maxchars > 0)
	{
		CG_DrawStringExt(tempx + (BG_drawStrlen(ci->name) * SMALLCHAR_WIDTH + SMALLCHAR_WIDTH),
		                 y, buf, hcolor, qfalse, qfalse, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, maxchars);
	}

	tempx += INFO_PLAYER_WIDTH - offset;

	if (ci->team == TEAM_SPECTATOR)
	{
		const char *s;
		int        w, totalwidth = INFO_CLASS_WIDTH + INFO_SCORE_WIDTH + INFO_LATENCY_WIDTH - 8;

		// Show connecting people as CONNECTING
		if (score->ping == -1)
		{
			s = CG_TranslateString("^3CONNECTING");
		}
		else
		{
			s = CG_TranslateString("^3SPECTATOR");
		}
		w = CG_DrawStrlen(s) * SMALLCHAR_WIDTH;
		CG_DrawSmallString(tempx + totalwidth - w, y, s, fade);
		return;
	}
	// allow MV clients see the class of its merged client's on the scoreboard
	else if (cg.snap->ps.persistant[PERS_TEAM] == ci->team || cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR
#if FEATURE_MULTIVIEW
	         || CG_mvMergedClientLocate(score->client)
#endif
	         )
	{
		CG_DrawPic(tempx - 3, y + 1, 14, 14, cgs.media.skillPics[SkillNumForClass(ci->cls)]);
	}
	tempx += INFO_CLASS_WIDTH;

	CG_DrawSmallString(tempx, y, va("%3i", score->score), fade);
	if (cg_gameType.integer == GT_WOLF_LMS)
	{
		tempx += INFO_SCORE_WIDTH;
	}
	else
	{
		tempx += INFO_XP_WIDTH;
	}

	if (score->ping == -1)
	{
		CG_DrawSmallString(tempx, y, "^1CONN^7", fade);
	}
	else if (score->scoreflags & 2)
	{
		CG_DrawSmallString(tempx, y, " BOT", fade);
	}
	else
	{
		CG_DrawSmallString(tempx, y, va("%4i", score->ping), fade);
	}
	tempx += INFO_LATENCY_WIDTH;

	if (cg_gameType.integer != GT_WOLF_LMS)
	{
		if (score->respawnsLeft >= 0)
		{
			CG_DrawSmallString(tempx, y, va("%2i", score->respawnsLeft), fade);
		}
		else
		{
			CG_DrawSmallString(tempx, y, " -", fade);
		}
	}
}