reaction/code/cgame/cg_scoreboard.c
2013-01-04 13:27:22 +00:00

1451 lines
47 KiB
C

//-----------------------------------------------------------------------------
//
// $Id$
//
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.51 2003/03/29 18:53:41 jbravo
// Fixed ammo bug when dropping bandolier. Added color to more errormessages
//
// Revision 1.50 2002/10/21 21:17:16 niceass
// bleh
//
// Revision 1.49 2002/10/21 21:04:33 niceass
// ref fix
//
// Revision 1.48 2002/10/21 21:01:49 niceass
// ref ready code
//
// Revision 1.47 2002/08/29 04:45:25 niceass
// color changes for new outlined font
//
// Revision 1.46 2002/08/27 05:08:22 niceass
// fix for ref
//
// Revision 1.45 2002/08/24 07:59:48 niceass
// new ref system
//
// Revision 1.44 2002/08/07 04:44:23 niceass
// ctb changes
//
// Revision 1.43 2002/07/22 01:27:38 niceass
// spectator coloring fix
//
// Revision 1.42 2002/07/19 04:40:56 jbravo
// Added 2 new radio sets and ctb radio sound support
//
// Revision 1.41 2002/07/09 05:42:51 niceass
// flag scoreboard changes
//
// Revision 1.40 2002/07/08 04:27:32 niceass
// moved some code to game. Changed from head models to icons
//
// Revision 1.39 2002/07/02 07:38:55 niceass
// Added total players/subs & fixed ping bug
//
// Revision 1.38 2002/07/02 07:21:41 niceass
// untested matchmode ping determination
//
// Revision 1.37 2002/06/21 21:05:00 niceass
// tinkering
//
// Revision 1.36 2002/06/20 02:27:30 jbravo
// Now the scoreboard doesnt show whos alive and whos not when you are alive
//
// Revision 1.35 2002/06/19 05:21:20 niceass
// scoreboard stuff
//
// Revision 1.34 2002/06/16 20:06:13 jbravo
// Reindented all the source files with "indent -kr -ut -i8 -l120 -lc120 -sob -bad -bap"
//
// Revision 1.33 2002/06/10 13:20:03 slicer
// RefID is now passed trought scoreboard, no more lca cvar, only cg.lca
//
// Revision 1.32 2002/06/05 23:39:23 niceass
// small change in wording
//
// Revision 1.31 2002/06/05 04:58:43 niceass
// Scoreboard changes
//
// Revision 1.30 2002/06/03 19:20:18 niceass
// referee change
//
// Revision 1.29 2002/06/03 00:47:18 niceass
// match scoreboard changes
//
// Revision 1.28 2002/05/27 17:47:19 jbravo
// Fixes and cleanups
//
// Revision 1.27 2002/05/27 07:00:09 niceass
// misc changes
//
// Revision 1.26 2002/05/12 02:21:06 niceass
// Matchmode scoreboard features
//
// Revision 1.25 2002/05/07 13:35:45 jbravo
// Fixed the double lights for spectators and made the use cmd use rq3_cmd
// and made scoreboard not revieal whos alive or dead to live players.
//
// Revision 1.24 2002/04/29 06:15:30 niceass
// ref shown as green. more mm stuff soon to come
//
// Revision 1.23 2002/04/23 06:05:52 niceass
// scoreboard stuff (btw, green is ugly)
//
// Revision 1.22 2002/04/18 16:13:23 jbravo
// Scoreboard now shows green for live players and white for dead.
// Time should not get reset on deaths any more.
//
// Revision 1.21 2002/03/31 03:31:24 jbravo
// Compiler warning cleanups
//
// Revision 1.20 2002/03/31 02:01:32 niceass
// fixes and changes
//
// Revision 1.19 2002/03/30 23:20:10 jbravo
// Added damage in scoreboard.
//
// Revision 1.18 2002/03/30 02:54:24 jbravo
// MOre spec tweaks and a scoreboard fix
//
// Revision 1.17 2002/03/24 22:57:27 niceass
// VERY big scoreboard changes
//
// Revision 1.14 2002/03/17 21:32:23 jbravo
// Fixed the dynamic teamnames system up a bit to reduce traffic
//
// Revision 1.13 2002/03/17 00:40:23 jbravo
// Adding variable team names. g_RQ3_team1name and g_RQ3_team2name. Fixed
// Slicers fraglimit check.
//
// Revision 1.12 2002/03/10 23:27:26 blaze
// fixed net for the wstats
//
// Revision 1.11 2002/03/03 23:12:18 blaze
// weapon stats - fixed a formating bug.
//
// Revision 1.10 2002/03/03 21:44:01 blaze
// weapon stats, done, beta test for bugs
//
// Revision 1.9 2002/03/02 01:16:30 blaze
// weapons stats- reordered where the mp5 was to make it more consistant with the weapon selection page
//
// Revision 1.8 2002/02/28 06:09:23 blaze
// weapons stats on server side - spelling fixed, and forgot ssg3000 and kicks
//
// Revision 1.7 2002/02/28 05:41:54 blaze
// weapons stats on client side
//
// Revision 1.6 2002/02/10 08:17:08 niceass
// many changes to scoreboard (deaths/second mode)
//
// Revision 1.5 2002/02/04 00:23:05 niceass
// New TP scoreboard
//
// Revision 1.4 2002/01/11 19:48:29 jbravo
// Formatted the source in non DOS format.
//
// Revision 1.3 2001/12/31 16:28:41 jbravo
// I made a Booboo with the Log tag.
//
//
//-----------------------------------------------------------------------------
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_scoreboard -- draw the scoreboard on top of the game screen
#include "cg_local.h"
//static qboolean localClient; // true if local client has been displayed
void CG_DrawScoreBoardHead(float x, float y, float w, float h,
qhandle_t headModel, qhandle_t headSkin, vec3_t headAngles);
void CG_ScoreBoardHead(team_t team, float x, float y, float w, float h);
#define SB_WIDTH 330
#define SB_FONTSIZEW 7
#define SB_FONTSIZEH (SB_FONTSIZEW * 2)
#define SB_PADDING 1
int TeamAveragePing(team_t team)
{
int i;
int Players = 0, AvgPing = 0;
int MaxPing1 = -1; // Ping value
int MaxPing1I = -1, MaxPing2I = -1; // Index value
score_t *Score;
clientInfo_t *ci;
// Find out how many are on the team
// and the two highest pingers
for (i = 0; i < cg.numScores; i++) {
Score = &cg.scores[i];
ci = &cgs.clientinfo[Score->client];
if (Score->sub == TEAM_RED || Score->sub == TEAM_BLUE)
continue;
if (ci->team != team)
continue;
Players++;
if (Score->ping >= MaxPing1) {
MaxPing2I = MaxPing1I;
MaxPing1 = Score->ping;
MaxPing1I = i;
}
}
if (!Players)
return 0;
for (i = 0; i < cg.numScores; i++) {
Score = &cg.scores[i];
ci = &cgs.clientinfo[Score->client];
if (Score->sub == TEAM_RED || Score->sub == TEAM_BLUE)
continue;
if (ci->team != team)
continue;
// 4+ players, ignore highest pinger on team
if (Players > 3 && i == MaxPing1I)
continue;
// 7+ players, ignore second highest pinger on team also
if (Players > 6 && i == MaxPing2I)
continue;
AvgPing += Score->ping;
}
// One player ignored
if (Players > 3)
Players--;
// A Second player ignored
if (Players > 6)
Players--;
return AvgPing / Players;
}
void DrawStrip(int y, int Height, qboolean Fill, qboolean Top, qboolean Bottom, float *FillC, float *BoarderC)
{
if (Fill) {
CG_FillRect((SCREEN_WIDTH - SB_WIDTH) / 2, y, SB_WIDTH, Height + SB_PADDING * 2, FillC);
}
if (Top)
CG_DrawCleanLine((SCREEN_WIDTH - SB_WIDTH) / 2, y, SB_WIDTH, 1, BoarderC);
if (Bottom)
CG_DrawCleanLine((SCREEN_WIDTH - SB_WIDTH) / 2, y + Height + SB_PADDING * 2, SB_WIDTH, 1, BoarderC);
CG_DrawCleanSides((SCREEN_WIDTH - SB_WIDTH) / 2, y, SB_WIDTH, Height + SB_PADDING * 2, 1, BoarderC);
}
void DrawLeftStripText(int y, int Height, char *Text, int maxChars, float *Color)
{
CG_DrawStringExt((SCREEN_WIDTH - SB_WIDTH) / 2 + 2, y + (Height + SB_PADDING * 2 - SB_FONTSIZEH) / 2, Text, Color, qtrue,
qfalse, // Shadow?
SB_FONTSIZEW, // charWidth
SB_FONTSIZEH, // charHeight
maxChars); // MaxChars
}
void DrawStripText(int y, int x, int Height, char *Text, int maxChars, float *Color)
{
CG_DrawStringExt((SCREEN_WIDTH - SB_WIDTH) / 2 + x, y + (Height + SB_PADDING * 2 - SB_FONTSIZEH) / 2, Text, Color, qfalse,
qfalse, // Shadow?
SB_FONTSIZEW, // charWidth
SB_FONTSIZEH, // charHeight
maxChars); // MaxChars
}
void DrawRightStripText(int y, int Height, char *Text, int maxChars, float *Color)
{
int Len;
Len = CG_DrawStrlen(Text);
CG_DrawStringExt(((SCREEN_WIDTH + SB_WIDTH) / 2) - (Len * SB_FONTSIZEW) - 2, y + (Height + SB_PADDING * 2 - SB_FONTSIZEH) / 2, Text, Color, qtrue,
qfalse, // Shadow?
SB_FONTSIZEW, // charWidth
SB_FONTSIZEH, // charHeight
maxChars); // MaxChars
}
void DrawCenterStripText(int y, int Height, char *Text, int maxChars, float *Color)
{
int Len;
Len = CG_DrawStrlen(Text);
CG_DrawStringExt((SCREEN_WIDTH - Len * SB_FONTSIZEW) / 2, y + (Height + SB_PADDING * 2 - SB_FONTSIZEH) / 2, Text, Color, qtrue, // Force color?
qfalse, // Shadow?
SB_FONTSIZEW, // charWidth
SB_FONTSIZEH, // charHeight
maxChars); // MaxChars
}
static void CG_DrawTeamplayClientScore(int y, score_t * score, float *Fill, float *Boarder, float *Color)
{
char Tmp[128], MMstr[128];
clientInfo_t *ci;
float FillColor[4], TextColor[4];
int l;
if (score->client < 0 || score->client >= cgs.maxclients) {
Com_Printf("^1Bad score->client: %i\n", score->client);
return;
}
ci = &cgs.clientinfo[score->client];
for (l = 0; l < 4; l++) {
FillColor[l] = Fill[l];
TextColor[l] = Color[l];
}
if (score->client == cg.clientNum)
FillColor[3] += 0.2f;
if (FillColor[3] > 1)
FillColor[3] = 1;
// Dead?
if (!score->alive) {
TextColor[0] *= 0.5f;
TextColor[1] *= 0.5f;
TextColor[2] *= 0.5f;
}
DrawStrip(y, SB_FONTSIZEH, qtrue, qfalse, qfalse, FillColor, Boarder);
Com_sprintf(Tmp, 128, "%5i %s", score->score, ci->name);
DrawLeftStripText(y, SB_FONTSIZEH, Tmp, 27, TextColor);
if (score->ping != -1) {
Com_sprintf(Tmp, 128, "%4i %4i %6i", score->time, score->ping, score->damage);
DrawRightStripText(y, SB_FONTSIZEH, Tmp, 100, TextColor);
} else {
DrawRightStripText(y, SB_FONTSIZEH, "CONNECTING ", 100, TextColor);
}
memset(MMstr, 0, sizeof(MMstr));
if (score->referee)
strcat(MMstr, "^3[REF]^7");
if (score->captain)
strcat(MMstr, "[CAPTAIN]");
if (score->sub)
strcat(MMstr, "[SUB]");
if ( CG_DrawStrlen(MMstr) )
DrawStripText(y, -(SB_FONTSIZEW * ((signed)CG_DrawStrlen(MMstr) + 1)), SB_FONTSIZEH, MMstr, 100, colorWhite);
if (ci->powerups & ( 1 << PW_REDFLAG ) )
CG_DrawFlagModel( (SCREEN_WIDTH + SB_WIDTH) / 2 + 2, y, SB_FONTSIZEH + SB_PADDING * 2,
SB_FONTSIZEH + SB_PADDING * 2, TEAM_RED, qfalse );
else if (ci->powerups & ( 1 << PW_BLUEFLAG ) )
CG_DrawFlagModel( (SCREEN_WIDTH + SB_WIDTH) / 2 + 2, y, SB_FONTSIZEH + SB_PADDING * 2,
SB_FONTSIZEH + SB_PADDING * 2, TEAM_BLUE, qfalse );
}
/*
=================
CG_TeamScoreboard
- By NiceAss
=================
*/
static int CG_TeamplayScoreboard(void)
{
clientInfo_t *ci;
int i;
int Reds, Blues, Spectators;
int RedSubs, BlueSubs;
float Alpha;
score_t *Score;
int y;
int Alternate, First;
int Ping, Frags, Damage; // Averages and totals
char Tmp[128];
// Colors
vec4_t RedL, BlueL, GreyL, BlackL;
vec4_t RedD, BlueD, GreyD;
// Sine wave fading
if (cg.time > cg.scoreStartTime + 300) {
Alpha = cos((cg.time - cg.scoreStartTime) / 400.0f) * 0.15f + 0.85f;
} else {
// Fade in
Alpha = (float) (cg.time - cg.scoreStartTime) / (float) 300;
if (Alpha > 1.0f)
Alpha = 1.0f;
}
// NiceAss: Update scoreboard while open every 2 seconds
if (cg.scoresRequestTime + 2000 < cg.time) {
cg.scoresRequestTime = cg.time;
trap_SendClientCommand("score");
}
MAKERGBA(BlackL, 0.0f, 0.0f, 0.0f, 0.8f * Alpha);
CG_TeamColor(TEAM_RED, RedD);
RedD[0] *= 0.8f;
RedD[1] *= 0.8f;
RedD[2] *= 0.8f;
RedD[3] *= (0.8f * Alpha);
CG_TeamColor(TEAM_BLUE, BlueD);
BlueD[0] *= 0.8f;
BlueD[1] *= 0.8f;
BlueD[2] *= 0.8f;
BlueD[3] *= (0.8f * Alpha);
MAKERGBA(GreyD, 0.3f, 0.3f, 0.3f, 0.84f * Alpha);
CG_TeamColor(TEAM_RED, RedL);
RedL[0] *= 0.8f;
RedL[1] *= 0.8f;
RedL[2] *= 0.8f;
RedL[3] *= (0.8f * Alpha);
CG_TeamColor(TEAM_BLUE, BlueL);
BlueL[0] *= 0.8f;
BlueL[1] *= 0.8f;
BlueL[2] *= 0.8f;
BlueL[3] *= (0.8f * Alpha);
MAKERGBA(GreyL, 0.3f, 0.3f, 0.3f, 0.4f * Alpha);
Reds = Blues = Spectators = RedSubs = BlueSubs = 0;
// Get totals for red/blue/spectators and subs
for (i = 0; i < cg.numScores; i++) {
Score = &cg.scores[i];
ci = &cgs.clientinfo[Score->client];
if (Score->sub == TEAM_RED)
RedSubs++;
else if (Score->sub == TEAM_BLUE)
BlueSubs++;
else if (ci->team == TEAM_RED)
Reds++;
else if (ci->team == TEAM_BLUE)
Blues++;
else if (ci->team == TEAM_SPECTATOR)
Spectators++;
}
y = 20; // Starting height.
// NiceAss: The matchmode match time
if (cg_RQ3_matchmode.integer) {
int mins, secs;
char Time[16];
char *pingFair;
mins = (int) floor(cg.matchTime / 60.0f);
secs = cg.matchTime - (mins * 60);
Com_sprintf(Time, 16, "%d:%02d", mins, secs);
if (abs(TeamAveragePing(TEAM_RED) - TeamAveragePing(TEAM_BLUE)) <= 40)
pingFair = "PINGS FAIR";
else
pingFair = "PINGS UNFAIR";
DrawRightStripText(y, SB_FONTSIZEH, va("%s - Matchtime: %s", pingFair, Time), 100, colorWhite);
y += SB_FONTSIZEH + SB_PADDING * 2 + 2;
}
// NiceAss: Deathmatch scoreboard:
if (cg.scoreTPMode == 1 || cgs.gametype < GT_TEAM) {
// vec3_t headAngles;
DrawStrip(y, SB_FONTSIZEH, qtrue, qtrue, qtrue, BlackL, colorWhite);
DrawLeftStripText(y, SB_FONTSIZEH, "Frags Name", 100, colorWhite);
DrawRightStripText(y, SB_FONTSIZEH, "Time Ping Damage", 100, colorWhite);
y += SB_FONTSIZEH + SB_PADDING * 2 + 2;
// VectorSet(headAngles, 0, sin(cg.time * 0.002f) * 20.0f + 180.0f, 0);
First = 0;
for (i = 0; i < cg.numScores; i++) {
Score = &cg.scores[i];
ci = &cgs.clientinfo[Score->client];
CG_DrawTeamplayClientScore(y, Score, GreyL, colorWhite, colorWhite);
if (First == 0)
DrawStrip(y, SB_FONTSIZEH, qfalse, qtrue, qfalse, GreyL, colorWhite);
y += SB_FONTSIZEH + SB_PADDING * 2;
First = 1;
}
DrawStrip(y - (SB_FONTSIZEH + SB_PADDING * 2), SB_FONTSIZEH, qfalse, qfalse, qtrue, GreyL, colorWhite);
return Reds + Blues + ceil(Spectators / 2);
}
// *************** RED TEAM ***************
DrawStrip(y, SB_FONTSIZEH, qtrue, qtrue, qtrue, RedD, colorBlack);
DrawLeftStripText(y, SB_FONTSIZEH, cg_RQ3_team1name.string, 100, colorWhite);
if (cg_RQ3_matchmode.integer)
DrawRightStripText(y, SB_FONTSIZEH, va("%d/%d - %s - Wins: %d", Reds, RedSubs,
cg.team1ready ? "Ready" : "Not Ready", cg.teamScores[0]),
100, colorWhite);
else
DrawRightStripText(y, SB_FONTSIZEH, va("%d/%d - Wins: %d", Reds, RedSubs, cg.teamScores[0]), 100, colorWhite);
CG_ScoreBoardHead (TEAM_RED, (SCREEN_WIDTH - SB_WIDTH) / 2 - 36, y, 34, 34);
y += SB_FONTSIZEH + SB_PADDING * 2 + 2;
DrawStrip(y, SB_FONTSIZEH, qtrue, qtrue, qtrue, GreyL, colorBlack);
DrawLeftStripText(y, SB_FONTSIZEH, "Frags Name", 100, colorWhite);
DrawRightStripText(y, SB_FONTSIZEH, "Time Ping Damage", 100, colorWhite);
y += SB_FONTSIZEH + SB_PADDING * 2;
Ping = Frags = Damage = 0;
if (Reds || RedSubs) {
if (Reds) {
y += 2;
First = 0;
for (i = 0; i < cg.numScores; i++) {
Score = &cg.scores[i];
ci = &cgs.clientinfo[Score->client];
if (ci->team == TEAM_RED && Score->sub == 0) {
CG_DrawTeamplayClientScore(y, Score, RedL, colorBlack, colorWhite);
if (First == 0)
DrawStrip(y, SB_FONTSIZEH, qfalse, qtrue, qfalse, RedL, colorBlack);
y += SB_FONTSIZEH + SB_PADDING * 2;
Ping += Score->ping;
Frags += Score->score;
Damage += Score->damage;
First = 1;
}
}
Ping /= Reds;
DrawStrip(y - (SB_FONTSIZEH + SB_PADDING * 2), SB_FONTSIZEH, qfalse, qfalse, qtrue, RedL,
colorBlack);
}
// SUBS
if (RedSubs) {
y += 2;
First = 0;
for (i = 0; i < cg.numScores; i++) {
Score = &cg.scores[i];
ci = &cgs.clientinfo[Score->client];
if (ci->team == TEAM_RED && Score->sub) {
CG_DrawTeamplayClientScore(y, Score, RedL, colorBlack, colorWhite);
if (First == 0)
DrawStrip(y, SB_FONTSIZEH, qfalse, qtrue, qfalse, RedL, colorBlack);
y += SB_FONTSIZEH + SB_PADDING * 2;
Ping += Score->ping;
Frags += Score->score;
Damage += Score->damage;
First = 1;
}
}
DrawStrip(y - (SB_FONTSIZEH + SB_PADDING * 2), SB_FONTSIZEH, qfalse, qfalse, qtrue, RedL,
colorBlack);
}
y += 2;
if (cg_RQ3_matchmode.integer)
Ping = TeamAveragePing(TEAM_RED);
Com_sprintf(Tmp, 128, "%5d", Frags);
DrawStrip(y, SB_FONTSIZEH, qtrue, qtrue, qtrue, GreyL, colorBlack);
DrawLeftStripText(y, SB_FONTSIZEH, Tmp, 100, colorWhite);
Com_sprintf(Tmp, 128, "%4d %6d", Ping, Damage);
DrawRightStripText(y, SB_FONTSIZEH, Tmp, 100, colorWhite);
DrawCenterStripText(y, SB_FONTSIZEH, "Totals", 20, colorWhite);
} else {
y += 2;
DrawStrip(y, SB_FONTSIZEH, qtrue, qtrue, qtrue, RedL, colorBlack);
DrawCenterStripText(y, SB_FONTSIZEH, "No team members", 100, colorWhite);
}
// *************** BLUE TEAM ************
y += SB_FONTSIZEH * 2;
DrawStrip(y, SB_FONTSIZEH, qtrue, qtrue, qtrue, BlueD, colorBlack);
DrawLeftStripText(y, SB_FONTSIZEH, cg_RQ3_team2name.string, 100, colorWhite);
if (cg_RQ3_matchmode.integer)
DrawRightStripText(y, SB_FONTSIZEH, va("%d/%d - %s - Wins: %d", Blues, BlueSubs,
cg.team2ready ? "Ready" : "Not Ready", cg.teamScores[1]),
100, colorWhite);
else
DrawRightStripText(y, SB_FONTSIZEH, va("%d/%d - Wins: %d", Blues, BlueSubs, cg.teamScores[1]), 100, colorWhite);
CG_ScoreBoardHead (TEAM_BLUE, (SCREEN_WIDTH - SB_WIDTH) / 2 - 36, y, 34, 34);
y += SB_FONTSIZEH + SB_PADDING * 2 + 2;
DrawStrip(y, SB_FONTSIZEH, qtrue, qtrue, qtrue, GreyL, colorBlack);
DrawLeftStripText(y, SB_FONTSIZEH, "Frags Name", 100, colorWhite);
DrawRightStripText(y, SB_FONTSIZEH, "Time Ping Damage", 100, colorWhite);
y += SB_FONTSIZEH + SB_PADDING * 2;
Ping = Frags = Damage = 0;
if (Blues || BlueSubs) {
if (Blues) {
y += 2;
First = 0;
for (i = 0; i < cg.numScores; i++) {
Score = &cg.scores[i];
ci = &cgs.clientinfo[Score->client];
if (ci->team == TEAM_BLUE && Score->sub == 0) {
CG_DrawTeamplayClientScore(y, Score, BlueL, colorBlack, colorWhite);
if (First == 0)
DrawStrip(y, SB_FONTSIZEH, qfalse, qtrue, qfalse, BlueL, colorBlack);
y += SB_FONTSIZEH + SB_PADDING * 2;
Ping += Score->ping;
Frags += Score->score;
Damage += Score->damage;
First = 1;
}
}
Ping /= Blues;
DrawStrip(y - (SB_FONTSIZEH + SB_PADDING * 2), SB_FONTSIZEH, qfalse, qfalse, qtrue, BlueL,
colorBlack);
}
// SUBS:
if (BlueSubs) {
y += 2;
First = 0;
for (i = 0; i < cg.numScores; i++) {
Score = &cg.scores[i];
ci = &cgs.clientinfo[Score->client];
if (ci->team == TEAM_BLUE && Score->sub) {
CG_DrawTeamplayClientScore(y, Score, BlueL, colorBlack, colorWhite);
if (First == 0)
DrawStrip(y, SB_FONTSIZEH, qfalse, qtrue, qfalse, BlueL, colorBlack);
y += SB_FONTSIZEH + SB_PADDING * 2;
Ping += Score->ping;
Frags += Score->score;
Damage += Score->damage;
First = 1;
}
}
DrawStrip(y - (SB_FONTSIZEH + SB_PADDING * 2), SB_FONTSIZEH, qfalse, qfalse, qtrue, BlueL,
colorBlack);
}
y += 2;
if (cg_RQ3_matchmode.integer)
Ping = TeamAveragePing(TEAM_BLUE);
Com_sprintf(Tmp, 128, "%5d", Frags);
DrawStrip(y, SB_FONTSIZEH, qtrue, qtrue, qtrue, GreyL, colorBlack);
DrawLeftStripText(y, SB_FONTSIZEH, Tmp, 100, colorWhite);
Com_sprintf(Tmp, 128, "%4d %6d", Ping, Damage);
DrawRightStripText(y, SB_FONTSIZEH, Tmp, 100, colorWhite);
DrawCenterStripText(y, SB_FONTSIZEH, "Totals", 20, colorWhite);
} else {
y += 2;
DrawStrip(y, SB_FONTSIZEH, qtrue, qtrue, qtrue, BlueL, colorBlack);
DrawCenterStripText(y, SB_FONTSIZEH, "No team members", 100, colorWhite);
}
if ( cg_RQ3_matchmode.integer && cg.refready != -1 ) {
y += SB_FONTSIZEH * 2;
DrawStrip(y, SB_FONTSIZEH, qtrue, qtrue, qtrue, BlackL, colorWhite);
DrawRightStripText(y, SB_FONTSIZEH,
cg.refready ? "Referee Ready" : "Referee Not Ready", 100, colorWhite);
}
// *************** SPECTATORS ************
if (Spectators) {
Alternate = 1;
First = 0;
y += SB_FONTSIZEH * 2;
DrawStrip(y, SB_FONTSIZEH, qtrue, qtrue, qtrue, GreyD, colorBlack);
DrawLeftStripText(y, SB_FONTSIZEH, "Spectators", 100, colorWhite);
y += SB_FONTSIZEH + SB_PADDING * 2 + 2;
for (i = 0; i < cg.numScores; i++) {
Score = &cg.scores[i];
ci = &cgs.clientinfo[Score->client];
if (ci->team != TEAM_SPECTATOR)
continue;
if (First == 0)
DrawStrip(y, SB_FONTSIZEH, qfalse, qtrue, qfalse, GreyL, colorBlack);
else
DrawStrip(y, SB_FONTSIZEH, qtrue, qfalse, qfalse, GreyL, colorBlack);
if (Score->referee) {
if (Alternate == 1)
DrawStripText(y, -(SB_FONTSIZEW * 6), SB_FONTSIZEH, "^3[REF]^7", 100, colorWhite);
else
DrawStripText(y, SB_WIDTH + SB_FONTSIZEW, SB_FONTSIZEH, "^3[REF]^7", 100, colorWhite);
}
if (Alternate == 1) {
DrawLeftStripText(y, SB_FONTSIZEH, ci->name, 20, colorWhite);
} else {
DrawRightStripText(y, SB_FONTSIZEH, ci->name, 20, colorWhite);
y += SB_FONTSIZEH + SB_PADDING * 2;
}
Alternate = -Alternate;
First = 1;
}
if (Alternate == 1)
DrawStrip(y - (SB_FONTSIZEH + SB_PADDING * 2), SB_FONTSIZEH, qfalse, qfalse, qtrue, GreyL,
colorBlack);
else
DrawStrip(y, SB_FONTSIZEH, qfalse, qfalse, qtrue, GreyL, colorBlack);
}
return Reds + Blues + ceil(Spectators / 2);
}
/*
=================
CG_DrawScoreboard
Draw the normal in-game scoreboard
=================
*/
qboolean CG_DrawOldScoreboard(void)
{
// 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;
}
if (!cg.showScores)
return qfalse;
// don't draw scoreboard during death while warmup up
if (cg.warmup) {
return qfalse;
}
CG_TeamplayScoreboard();
// load any models that have been deferred
if (++cg.deferredPlayerLoading > 10) {
CG_LoadDeferredPlayers();
}
return qtrue;
}
//================================================================================
/*
================
CG_CenterGiantLine
================
*/
static void CG_CenterGiantLine(float y, const char *string)
{
float x;
vec4_t color;
color[0] = 1;
color[1] = 1;
color[2] = 1;
color[3] = 1;
x = 0.5 * (640 - GIANT_WIDTH * CG_DrawStrlen(string));
CG_DrawStringExt(x, y, string, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0);
}
/*
=================
CG_DrawTourneyScoreboard
Draw the oversize scoreboard for tournements
=================
*/
void CG_DrawOldTourneyScoreboard(void)
{
const char *s;
vec4_t color;
int min, tens, ones;
clientInfo_t *ci;
int y;
int i;
// request more scores regularly
if (cg.scoresRequestTime + 2000 < cg.time) {
cg.scoresRequestTime = cg.time;
trap_SendClientCommand("score");
}
// draw the dialog background
color[0] = color[1] = color[2] = 0;
color[3] = 1;
CG_FillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, color);
color[0] = 1;
color[1] = 1;
color[2] = 1;
color[3] = 1;
// print the mesage of the day
s = CG_ConfigString(CS_MOTD);
if (!s[0]) {
s = "Scoreboard";
}
// print optional title
CG_CenterGiantLine(8, s);
// print server time
ones = cg.time / 1000;
min = ones / 60;
ones %= 60;
tens = ones / 10;
ones %= 10;
s = va("%i:%i%i", min, tens, ones);
CG_CenterGiantLine(64, s);
// print the two scores
y = 160;
if (cgs.gametype >= GT_TEAM) {
//
// teamplay scoreboard
//
CG_DrawStringExt(8, y, "Red Team", color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0);
s = va("%i", cg.teamScores[0]);
CG_DrawStringExt(632 - GIANT_WIDTH * strlen(s), y, s, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT,
0);
y += 64;
CG_DrawStringExt(8, y, "Blue Team", color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0);
s = va("%i", cg.teamScores[1]);
CG_DrawStringExt(632 - GIANT_WIDTH * strlen(s), y, s, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT,
0);
} else {
//
// free for all scoreboard
//
for (i = 0; i < MAX_CLIENTS; i++) {
ci = &cgs.clientinfo[i];
if (!ci->infoValid) {
continue;
}
if (ci->team != TEAM_FREE) {
continue;
}
CG_DrawStringExt(8, y, ci->name, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0);
s = va("%i", ci->score);
CG_DrawStringExt(632 - GIANT_WIDTH * strlen(s), y, s, color, qtrue, qtrue, GIANT_WIDTH,
GIANT_HEIGHT, 0);
y += 64;
}
}
}
//Blaze: Added the weapons stats "scoreboard" to this file because it's a scoreboard in a way.
/*
==============================
CG_DrawWeaponStats
Draws the stats of the player
==============================
*/
#define WS_LEFTSIDE 20
#define WS_TOP 200
#define WS_WIDTH 640 - WS_LEFTSIDE * 10
#define WS_LINE_WIDTH 1
#define WS_PADDING (WS_LINE_WIDTH+2)
void CG_DrawWeaponStats(void)
{
int i, offset;
float color[4], Alpha; // Alpha2;
int size;
char String[80];
if (cg.time > cg.wstatsStartTime + 300) {
Alpha = (cos((cg.time - cg.wstatsStartTime) / 400.0f) + 1.0f) * 0.25f + 0.5f;
// Alpha2 = (cos((cg.time - cg.wstatsStartTime) / 400.0f) + 1.0f) * 0.5f;
} else {
Alpha = (float) (cg.time - cg.wstatsStartTime) / (float) 300;
if (Alpha > 1.0f)
Alpha = 1.0f;
}
//make room for 8 weapon stats
size = (10 * 20) + WS_PADDING;
// Score bar - Red:
MAKERGBA(color, 1.0f, 0.5f, 0.5f, 0.7f * Alpha);
CG_FillRect(WS_LEFTSIDE, WS_TOP, WS_WIDTH, SMALLCHAR_HEIGHT + (WS_PADDING * 2), color);
//Box for scores, etc
MAKERGBA(color, 0.55f, 0.55f, 0.55f, 0.7f * Alpha);
CG_FillRect(WS_LEFTSIDE, WS_TOP + SMALLCHAR_HEIGHT + (WS_PADDING * 2),
WS_WIDTH, SMALLCHAR_HEIGHT + (WS_PADDING * 2), color);
//Box for weapon stuff
MAKERGBA(color, 0.6f, 0.5f, 0.5f, 0.5f * Alpha);
CG_FillRect(WS_LEFTSIDE, WS_TOP + (SMALLCHAR_HEIGHT + (WS_PADDING * 2)) * 2, WS_WIDTH, size, color);
//box for weapon stuff
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 0.8f);
CG_DrawCleanRect(WS_LEFTSIDE, WS_TOP,
WS_WIDTH, (SMALLCHAR_HEIGHT + WS_PADDING * 2) * 2 + size, WS_LINE_WIDTH, color);
//box for score stuff
CG_DrawCleanRect(WS_LEFTSIDE, WS_TOP + SMALLCHAR_HEIGHT + (WS_PADDING * 2),
WS_WIDTH, (SMALLCHAR_HEIGHT + WS_PADDING * 2), WS_LINE_WIDTH, color);
//Red box for Weapon stats
MAKERGBA(color, 1.0f, 0.5f, 0.5f, 0.7f * Alpha);
CG_FillRect(WS_LEFTSIDE, WS_TOP + (SMALLCHAR_HEIGHT + (WS_PADDING * 2)) * 2, WS_WIDTH, SMALLCHAR_HEIGHT, color);
//White box for the weapon names, etc
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 0.8f);
CG_DrawCleanRect(WS_LEFTSIDE, WS_TOP - 1 + (SMALLCHAR_HEIGHT + (WS_PADDING * 2)) * 2,
WS_WIDTH, SMALLCHAR_HEIGHT + 1, WS_LINE_WIDTH, color);
//Fill in the top bar
offset = 7;
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6, WS_TOP + WS_PADDING, "Score", color);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * 7, WS_TOP + WS_PADDING, "Net", color);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * 7 * 2, WS_TOP + WS_PADDING, "K/D/S", color);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * 7 * 3, WS_TOP + WS_PADDING, "TK's", color);
// MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
// CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * 7 * 4, WS_TOP + WS_PADDING,
// "Efficiency", color);
Com_sprintf(String, sizeof(String), "%4i", cg.snap->ps.persistant[PERS_SCORE]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH, WS_TOP + WS_PADDING * 3 + SMALLCHAR_HEIGHT,
String, color);
Com_sprintf(String, sizeof(String), "%3i",
cg.snap->ps.persistant[PERS_SCORE] - cg.snap->ps.persistant[PERS_KILLED]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * 7 - 1, WS_TOP + WS_PADDING * 3 + SMALLCHAR_HEIGHT,
String, color);
Com_sprintf(String, sizeof(String), "%i/%i/%i", cg.records[REC_KILLS], cg.snap->ps.persistant[PERS_KILLED],
cg.records[REC_SUICIDES]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * 7 * 2, WS_TOP + WS_PADDING * 3 + SMALLCHAR_HEIGHT,
String, color);
Com_sprintf(String, sizeof(String), "%4i", cg.records[REC_TEAMKILLS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * 7 * 3, WS_TOP + WS_PADDING * 3 + SMALLCHAR_HEIGHT,
String, color);
i = 2;
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH, WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++,
"Weapon Stats", color);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH, WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++,
"Knife(slash)", color);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH, WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++,
"Knife(throw)", color);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH, WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++,
"MK23", color);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH, WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++,
"MP5", color);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH, WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++,
"M3", color);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH, WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++,
"M4", color);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH, WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++,
"HC", color);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH, WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++,
"SSG3000", color);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH, WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++,
"Akimbo", color);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH, WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++,
"Grenade", color);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH, WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++,
"Kicks", color);
//Accuracy
i = 2;
offset = 15;
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, "Accuracy", color);
Com_sprintf(String, sizeof(String), "%.1f%%",
100 * (float) cg.records[REC_KNIFESLASHHITS] /
(cg.records[REC_KNIFESLASHSHOTS] ? cg.records[REC_KNIFESLASHSHOTS] : 1));
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%.1f%%",
100 * (float) cg.records[REC_KNIFETHROWHITS] /
(cg.records[REC_KNIFETHROWSHOTS] ? cg.records[REC_KNIFETHROWSHOTS] : 1));
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%.1f%%",
100 * (float) cg.records[REC_MK23HITS] /
(cg.records[REC_MK23SHOTS] ? cg.records[REC_MK23SHOTS] : 1));
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%.1f%%",
100 * (float) cg.records[REC_MP5HITS] / (cg.records[REC_MP5SHOTS] ? cg.records[REC_MP5SHOTS] : 1));
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%.1f%%",
100 * (float) cg.records[REC_M3HITS] / (cg.records[REC_M3SHOTS] ? cg.records[REC_M3SHOTS] : 1));
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%.1f%%",
100 * (float) cg.records[REC_M4HITS] / (cg.records[REC_M4SHOTS] ? cg.records[REC_M4SHOTS] : 1));
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%.1f%%",
100 * (float) cg.records[REC_HANDCANNONHITS] /
(cg.records[REC_HANDCANNONSHOTS] ? cg.records[REC_HANDCANNONSHOTS] : 1));
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%.1f%%",
100 * (float) cg.records[REC_SSG3000HITS] /
(cg.records[REC_SSG3000SHOTS] ? cg.records[REC_SSG3000SHOTS] : 1));
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%.1f%%",
100 * (float) cg.records[REC_AKIMBOHITS] /
(cg.records[REC_AKIMBOSHOTS] ? cg.records[REC_AKIMBOSHOTS] : 1));
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%.1f%%",
100 * (float) cg.records[REC_GRENADEHITS] /
(cg.records[REC_GRENADESHOTS] ? cg.records[REC_GRENADESHOTS] : 1));
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
//Hits
i = 2;
offset = 25;
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, "Hits", color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_KNIFESLASHHITS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_KNIFETHROWHITS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_MK23HITS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_MP5HITS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_M3HITS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_M4HITS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_HANDCANNONHITS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_SSG3000HITS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_AKIMBOHITS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_GRENADEHITS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_KICKHITS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
//Shots
i = 2;
offset = 32;
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * (offset - 1),
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, "Shots", color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_KNIFESLASHSHOTS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_KNIFETHROWSHOTS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_MK23SHOTS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_MP5SHOTS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_M3SHOTS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_M4SHOTS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_HANDCANNONSHOTS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_SSG3000SHOTS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_AKIMBOSHOTS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_GRENADESHOTS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
//Kills
i = 2;
offset = 39;
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * (offset - 1),
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, "Kills", color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_KNIFESLASHKILLS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_KNIFETHROWKILLS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_MK23KILLS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_MP5KILLS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_M3KILLS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_M4KILLS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_HANDCANNONKILLS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_SSG3000KILLS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_AKIMBOKILLS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_GRENADEKILLS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_KICKKILLS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
//Deaths
i = 2;
offset = 47;
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * (offset - 2),
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, "Deaths", color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_KNIFESLASHDEATHS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_KNIFETHROWDEATHS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_MK23DEATHS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_MP5DEATHS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_M3DEATHS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_M4DEATHS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_HANDCANNONDEATHS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_SSG3000DEATHS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_AKIMBODEATHS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_GRENADEDEATHS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
Com_sprintf(String, sizeof(String), "%4d", cg.records[REC_KICKDEATHS]);
MAKERGBA(color, 1.0f, 1.0f, 1.0f, 1.0f);
CG_DrawSmallStringColor(WS_LEFTSIDE + 6 + SMALLCHAR_WIDTH * offset,
WS_TOP + WS_PADDING * 4 + SMALLCHAR_HEIGHT * i++, String, color);
if (cg.wstatsRequestTime + 3000 < cg.time) {
// the scores are more than two seconds out of data,
// so request new ones
cg.wstatsRequestTime = cg.time;
trap_SendClientCommand("wstats");
}
return;
}
/*
CG_FindHead By NiceAss
Used to parse the model cvars and register the model and skin. It
then displays it.
*/
void CG_ScoreBoardHead(team_t team, float x, float y, float w, float h) {
char modelskin[128], filename[128];
char *model = NULL, *skin = NULL;
qhandle_t headIcon; //headModel, headSkin;
//vec3_t Angles;
if (team == TEAM_RED)
strcpy(modelskin, cg_RQ3_team1model.string);
else
strcpy(modelskin, cg_RQ3_team2model.string);
skin = strchr(modelskin, '/');
if (!skin)
return;
*skin = '\0';
skin++;
model = modelskin;
//********************** LOAD HEAD ***************************
/*
Com_sprintf(filename, 128, "models/players/%s/head.md3", model);
headModel = trap_R_RegisterModel( filename );
if (!headModel)
return;
Com_sprintf(filename, 128, "models/players/%s/head_%s.skin", model, skin);
headSkin = trap_R_RegisterSkin( filename );
if (!headSkin)
return;
VectorClear( Angles );
Angles[1] = sin(cg.time * 0.0025f) * 20.0f + 180.0f;
Angles[0] = cos(cg.time * 0.002f) * 8.0f;
CG_DrawScoreBoardHead(x, y, w, h, headModel, headSkin, Angles);
*/
Com_sprintf(filename, 128, "models/players/%s/icon_%s.md3", model, skin);
headIcon = trap_R_RegisterShaderNoMip( filename );
if (!headIcon)
return;
CG_DrawPic(x, y, w, h, headIcon);
}
/*
CG_DrawScoreBoardHead By NiceAss
Displays the player model. This is just an altered CG_DrawHead.
*/
/*
void CG_DrawScoreBoardHead(float x, float y, float w, float h,
qhandle_t headModel, qhandle_t headSkin,
vec3_t headAngles)
{
float len;
vec3_t origin;
vec3_t mins, maxs;
if (!headModel)
return;
// offset the origin y and z to center the head
trap_R_ModelBounds(headModel, mins, maxs);
origin[2] = -0.5 * (mins[2] + maxs[2]);
origin[1] = 0.5 * (mins[1] + maxs[1]);
// calculate distance so the head nearly fills the box
// assume heads are taller than wide
len = 0.7 * (maxs[2] - mins[2]);
origin[0] = len / 0.268; // len / tan( fov/2 )
CG_Draw3DModel(x, y, w, h, headModel, headSkin, origin, headAngles);
}
*/