// 0-4 are based on health (in 20 increments)
// 0 is static, 1 is temporary animation
cachepic_t *sb_faces[5][2];
+cachepic_t *sb_health; // GAME_NEXUIZ
cachepic_t *sb_face_invis;
cachepic_t *sb_face_quad;
cvar_t showdate_format = {CVAR_SAVE, "showdate_format", "%Y-%m-%d", "format string for date"};
cvar_t sbar_alpha_bg = {CVAR_SAVE, "sbar_alpha_bg", "0.4", "opacity value of the statusbar background image"};
cvar_t sbar_alpha_fg = {CVAR_SAVE, "sbar_alpha_fg", "1", "opacity value of the statusbar weapon/item icons and numbers"};
+cvar_t sbar_hudselector = {CVAR_SAVE, "sbar_hudselector", "0", "selects which of the builtin hud layouts to use (meaning is somewhat dependent on gamemode, so nexuiz has a very different set of hud layouts than quake for example)"};
+cvar_t sbar_miniscoreboard_size = {CVAR_SAVE, "sbar_miniscoreboard_size", "-1", "sets the size of the mini deathmatch overlay in items, or disables it when set to 0, or sets it to a sane default when set to -1"};
cvar_t cl_deathscoreboard = {0, "cl_deathscoreboard", "1", "shows scoreboard (+showscores) while dead"};
for (i = 0;i < 10;i++)
sb_nums[0][i] = Draw_CachePic (va("gfx/num_%i",i), true);
sb_nums[0][10] = Draw_CachePic ("gfx/num_minus", true);
+ sb_colon = Draw_CachePic ("gfx/num_colon", true);
sb_ammo[0] = Draw_CachePic ("gfx/sb_shells", true);
sb_ammo[1] = Draw_CachePic ("gfx/sb_bullets", true);
sb_ammo[2] = Draw_CachePic ("gfx/sb_rocket", true);
sb_ammo[3] = Draw_CachePic ("gfx/sb_cells", true);
+ sb_armor[0] = Draw_CachePic ("gfx/sb_armor", true);
+ sb_armor[1] = NULL;
+ sb_armor[2] = NULL;
+
+ sb_health = Draw_CachePic ("gfx/sb_health", true);
+
sb_items[2] = Draw_CachePic ("gfx/sb_slowmo", true);
sb_items[3] = Draw_CachePic ("gfx/sb_invinc", true);
sb_items[4] = Draw_CachePic ("gfx/sb_energy", true);
Cvar_RegisterVariable(&showdate_format);
Cvar_RegisterVariable(&sbar_alpha_bg);
Cvar_RegisterVariable(&sbar_alpha_fg);
+ Cvar_RegisterVariable(&sbar_hudselector);
+ Cvar_RegisterVariable(&sbar_miniscoreboard_size);
Cvar_RegisterVariable(&cl_deathscoreboard);
Cvar_RegisterVariable(&crosshair_color_red);
Sbar_DrawPic
=============
*/
+void Sbar_DrawStretchPic (int x, int y, cachepic_t *pic, float alpha, float overridewidth, float overrideheight)
+{
+ DrawQ_Pic (sbar_x + x, sbar_y + y, pic, overridewidth, overrideheight, 1, 1, 1, alpha, 0);
+}
+
void Sbar_DrawPic (int x, int y, cachepic_t *pic)
{
DrawQ_Pic (sbar_x + x, sbar_y + y, pic, 0, 0, 1, 1, 1, sbar_alpha_fg.value, 0);
char str[32], *ptr;
int l, frame;
- l = sprintf(str, "%i", num);
+ if (digits < 0)
+ {
+ digits = -digits;
+ l = sprintf(str, "%0*i", digits, num);
+ }
+ else
+ l = sprintf(str, "%i", num);
ptr = str;
if (l > digits)
ptr += (l-digits);
// AK to make DrawInventory smaller
static void Sbar_DrawWeapon(int nr, float fade, int active)
{
- // width = 300, height = 100
- const int w_width = 300, w_height = 100, w_space = 10;
- const float w_scale = 0.4;
+ if (sbar_hudselector.integer == 1)
+ {
+ // width = 300, height = 100
+ const int w_width = 32, w_height = 12, w_space = 2, font_size = 8;
- DrawQ_Pic(vid_conwidth.integer - (w_width + w_space) * w_scale, (w_height + w_space) * w_scale * nr + w_space, sb_weapons[0][nr], w_width * w_scale, w_height * w_scale, (active) ? 1 : 0.6, active ? 1 : 0.6, active ? 1 : 1, fade * sbar_alpha_fg.value, DRAWFLAG_NORMAL);
- //DrawQ_String(vid_conwidth.integer - (w_space + font_size ), (w_height + w_space) * w_scale * nr + w_space, va("%i",nr+1), 0, font_size, font_size, 1, 0, 0, fade, 0, NULL, true);
+ DrawQ_Pic((vid_conwidth.integer - w_width * 9) * 0.5 + w_width * nr, vid_conheight.integer - w_height, sb_weapons[0][nr], w_width, w_height, (active) ? 1 : 0.6, active ? 1 : 0.6, active ? 1 : 0.6, (active ? 1 : 0.6) * fade * sbar_alpha_fg.value, DRAWFLAG_NORMAL);
+ DrawQ_String((vid_conwidth.integer - w_width * 9) * 0.5 + w_width * nr + w_space, vid_conheight.integer - w_height + w_space, va("%i",nr+1), 0, font_size, font_size, 1, 1, 0, sbar_alpha_fg.value, 0, NULL, true);
+ }
+ else
+ {
+ // width = 300, height = 100
+ const int w_width = 300, w_height = 100, w_space = 10;
+ const float w_scale = 0.4;
+
+ DrawQ_Pic(vid_conwidth.integer - (w_width + w_space) * w_scale, (w_height + w_space) * w_scale * nr + w_space, sb_weapons[0][nr], w_width * w_scale, w_height * w_scale, (active) ? 1 : 0.6, active ? 1 : 0.6, active ? 1 : 1, fade * sbar_alpha_fg.value, DRAWFLAG_NORMAL);
+ //DrawQ_String(vid_conwidth.integer - (w_space + font_size ), (w_height + w_space) * w_scale * nr + w_space, va("%i",nr+1), 0, font_size, font_size, 1, 0, 0, fade, 0, NULL, true);
+ }
}
/*
*/
extern float v_dmg_time, v_dmg_roll, v_dmg_pitch;
extern cvar_t v_kicktime;
+void Sbar_Score (int margin);
void Sbar_Draw (void)
{
cachepic_t *pic;
}
else if (gamemode == GAME_NEXUIZ)
{
- sbar_y = vid_conheight.integer - 47;
- sbar_x = (vid_conwidth.integer - 640)/2;
-
if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
{
+ sbar_x = (vid_conwidth.integer - 640)/2;
+ sbar_y = vid_conheight.integer - 47;
Sbar_DrawAlphaPic (0, 0, sb_scorebar, sbar_alpha_bg.value);
Sbar_DrawScoreboard ();
}
+ else if (sb_lines && sbar_hudselector.integer == 1)
+ {
+ int i;
+ float fade;
+ int redflag, blueflag;
+
+ sbar_x = (vid_conwidth.integer - 320)/2;
+ sbar_y = vid_conheight.integer - 24 - 16;
+
+ // calculate intensity to draw weapons bar at
+ fade = 3.2 - 2 * (cl.time - cl.weapontime);
+ fade = bound(0.7, fade, 1);
+ for (i = 0; i < 8;i++)
+ if (cl.stats[STAT_ITEMS] & (1 << i))
+ Sbar_DrawWeapon(i + 1, fade, (i + 2 == cl.stats[STAT_ACTIVEWEAPON]));
+ if((cl.stats[STAT_ITEMS] & (1<<12)))
+ Sbar_DrawWeapon(0, fade, (cl.stats[STAT_ACTIVEWEAPON] == 1));
+
+ // flag icons
+ redflag = ((cl.stats[STAT_ITEMS]>>15) & 3);
+ blueflag = ((cl.stats[STAT_ITEMS]>>17) & 3);
+ if (redflag == 3 && blueflag == 3)
+ {
+ // The Impossible Combination[tm]
+ // Can only happen in Key Hunt mode...
+ Sbar_DrawPic (10 - sbar_x, -179, sb_items[14]);
+ }
+ else
+ {
+ if (redflag)
+ Sbar_DrawPic (10 - sbar_x, -117, sb_items[redflag+10]);
+ if (blueflag)
+ Sbar_DrawPic (10 - sbar_x, -177, sb_items[blueflag+14]);
+ }
+
+ // armor
+ if (cl.stats[STAT_ARMOR] > 0)
+ {
+ Sbar_DrawStretchPic (0, 0, sb_armor[0], sbar_alpha_fg.value, 24, 24);
+ if(cl.stats[STAT_ARMOR] > 100)
+ Sbar_DrawXNum(24,0,cl.stats[STAT_ARMOR],3,24,1,1,0,1,0);
+ else if(cl.stats[STAT_ARMOR] > 25)
+ Sbar_DrawXNum(24,0,cl.stats[STAT_ARMOR],3,24,0.6,0.7,0.8,1,0);
+ else
+ Sbar_DrawXNum(24,0,cl.stats[STAT_ARMOR],3,24,0.7,0,0,1,0);
+ }
+
+ // health
+ if (cl.stats[STAT_HEALTH] != 0)
+ {
+ Sbar_DrawStretchPic (112, 0, sb_health, sbar_alpha_fg.value, 24, 24);
+ if(cl.stats[STAT_HEALTH] > 100)
+ Sbar_DrawXNum(136,0,cl.stats[STAT_HEALTH],3,24,1,1,0,1,0);
+ else if(cl.stats[STAT_HEALTH] > 25)
+ Sbar_DrawXNum(136,0,cl.stats[STAT_HEALTH],3,24,0.6,0.7,0.8,1,0);
+ else
+ Sbar_DrawXNum(136,0,cl.stats[STAT_HEALTH],3,24,0.7,0,0,1,0);
+ }
+
+ // ammo
+ if ((cl.stats[STAT_ITEMS] & (NEX_IT_SHELLS | NEX_IT_BULLETS | NEX_IT_ROCKETS | NEX_IT_CELLS)) || cl.stats[STAT_AMMO] != 0)
+ {
+ if (cl.stats[STAT_ITEMS] & NEX_IT_SHELLS)
+ Sbar_DrawStretchPic (224, 0, sb_ammo[0], sbar_alpha_fg.value, 24, 24);
+ else if (cl.stats[STAT_ITEMS] & NEX_IT_BULLETS)
+ Sbar_DrawStretchPic (224, 0, sb_ammo[1], sbar_alpha_fg.value, 24, 24);
+ else if (cl.stats[STAT_ITEMS] & NEX_IT_ROCKETS)
+ Sbar_DrawStretchPic (224, 0, sb_ammo[2], sbar_alpha_fg.value, 24, 24);
+ else if (cl.stats[STAT_ITEMS] & NEX_IT_CELLS)
+ Sbar_DrawStretchPic (224, 0, sb_ammo[3], sbar_alpha_fg.value, 24, 24);
+ if(cl.stats[STAT_AMMO] > 10)
+ Sbar_DrawXNum(248, 0, cl.stats[STAT_AMMO], 3, 24, 0.6,0.7,0.8,1,0);
+ else
+ Sbar_DrawXNum(248, 0, cl.stats[STAT_AMMO], 3, 24, 0.7,0,0,1,0);
+ }
+
+ if (sbar_x + 320 + 160 <= vid_conwidth.integer)
+ Sbar_MiniDeathmatchOverlay (sbar_x + 320, sbar_y);
+ if (sbar_x > 0)
+ Sbar_Score(16);
+ // The margin can be at most 8 to support 640x480 console size:
+ // 320 + 2 * (144 + 16) = 640
+ }
else if (sb_lines)
{
int i;
float fade;
int redflag, blueflag;
+ sbar_x = (vid_conwidth.integer - 640)/2;
+ sbar_y = vid_conheight.integer - 47;
+
// calculate intensity to draw weapons bar at
fade = 3 - 2 * (cl.time - cl.weapontime);
if (fade > 0)
else
{
if (redflag)
- Sbar_DrawPic (10 - sbar_x, -109, sb_items[redflag+10]);
+ Sbar_DrawPic (10 - sbar_x, -117, sb_items[redflag+10]);
if (blueflag)
- Sbar_DrawPic (10 - sbar_x, -169, sb_items[blueflag+14]);
+ Sbar_DrawPic (10 - sbar_x, -177, sb_items[blueflag+14]);
}
// armor
if (sb_lines > 24)
DrawQ_Pic(sbar_x,sbar_y,sb_sbar_overlay,0,0,1,1,1,1,DRAWFLAG_MODULATE);
- }
- //if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
- // Sbar_MiniDeathmatchOverlay (0, 17);
+ if (sbar_x + 600 + 160 <= vid_conwidth.integer)
+ Sbar_MiniDeathmatchOverlay (sbar_x + 600, sbar_y);
+
+ if (sbar_x > 0)
+ Sbar_Score(-16);
+ // Because:
+ // Mini scoreboard uses 12*4 per other team, that is, 144
+ // pixels when there are four teams...
+ // Nexuiz by default sets vid_conwidth to 800... makes
+ // sbar_x == 80...
+ // so we need to shift it by 64 pixels to the right to fit
+ // BUT: then it overlaps with the image that gets drawn
+ // for viewsize 100! Therefore, just account for 3 teams,
+ // that is, 96 pixels mini scoreboard size, needing 16 pixels
+ // to the right!
+ }
}
else if (gamemode == GAME_ZYMOTIC)
{
}
else // Quake and others
{
+ sbar_x = (vid_conwidth.integer - 320)/2;
sbar_y = vid_conheight.integer - SBAR_HEIGHT;
// LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
//if (cl.gametype == GAME_DEATHMATCH && gamemode != GAME_TRANSFUSION)
- if (!cl.islocalgame && gamemode != GAME_TRANSFUSION)
- sbar_x = 0;
- else
- sbar_x = (vid_conwidth.integer - 320)/2;
if (sb_lines > 24)
{
Sbar_DrawNum (248, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10);
- }
-
- // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
- //if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
- if (!cl.islocalgame && vid_conwidth.integer > 320)
- {
- if (gamemode == GAME_TRANSFUSION)
- Sbar_MiniDeathmatchOverlay (0, 0);
- else
- Sbar_MiniDeathmatchOverlay (324, vid_conheight.integer - sb_lines);
+ // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
+ if ((!cl.islocalgame || cl.gametype != GAME_COOP))
+ {
+ if (gamemode == GAME_TRANSFUSION)
+ Sbar_MiniDeathmatchOverlay (0, 0);
+ else
+ Sbar_MiniDeathmatchOverlay (sbar_x + 324, vid_conheight.integer - 8*8);
+ Sbar_Score(24);
+ }
}
}
}
float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
{
int minutes;
+ qboolean myself = false;
unsigned char *c;
minutes = (int)((cl.intermission ? cl.completed_time - s->qw_entertime : cl.time - s->qw_entertime) / 60.0);
+
+ if((s - cl.scores) == cl.playerentity - 1)
+ myself = true;
+ if((s - teams) >= 0 && (s - teams) < MAX_SCOREBOARD)
+ if((s->colors & 15) == (cl.scores[cl.playerentity - 1].colors & 15))
+ myself = true;
+
if (cls.protocol == PROTOCOL_QUAKEWORLD)
{
if (s->qw_spectator)
{
if (s->qw_ping || s->qw_packetloss)
- DrawQ_String(x, y, va("%4i %3i %4i spectator %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), minutes, (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+ DrawQ_String(x, y, va("%4i %3i %4i spectator %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), minutes, myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
else
- DrawQ_String(x, y, va(" %4i spectator %c%s", minutes, (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+ DrawQ_String(x, y, va(" %4i spectator %c%s", minutes, myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
}
else
{
c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
DrawQ_Fill(x + 14*8, y+4, 40, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
// print the text
- //DrawQ_String(x, y, va("%c%4i %s", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, true);
+ //DrawQ_String(x, y, va("%c%4i %s", myself ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, true);
if (s->qw_ping || s->qw_packetloss)
- DrawQ_String(x, y, va("%4i %3i %4i %5i %-4s %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), minutes,(int) s->frags, cl.qw_teamplay ? s->qw_team : "", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+ DrawQ_String(x, y, va("%4i %3i %4i %5i %-4s %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), minutes,(int) s->frags, cl.qw_teamplay ? s->qw_team : "", myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
else
- DrawQ_String(x, y, va(" %4i %5i %-4s %c%s", minutes,(int) s->frags, cl.qw_teamplay ? s->qw_team : "", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+ DrawQ_String(x, y, va(" %4i %5i %-4s %c%s", minutes,(int) s->frags, cl.qw_teamplay ? s->qw_team : "", myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
}
}
else
if (s->qw_spectator)
{
if (s->qw_ping || s->qw_packetloss)
- DrawQ_String(x, y, va("%4i %3i spect %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+ DrawQ_String(x, y, va("%4i %3i spect %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
else
- DrawQ_String(x, y, va(" spect %c%s", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+ DrawQ_String(x, y, va(" spect %c%s", myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
}
else
{
c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
DrawQ_Fill(x + 9*8, y+4, 40, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
// print the text
- //DrawQ_String(x, y, va("%c%4i %s", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, true);
+ //DrawQ_String(x, y, va("%c%4i %s", myself ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, true);
if (s->qw_ping || s->qw_packetloss)
- DrawQ_String(x, y, va("%4i %3i %5i %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), (int) s->frags, (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+ DrawQ_String(x, y, va("%4i %3i %5i %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), (int) s->frags, myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
else
- DrawQ_String(x, y, va(" %5i %c%s", (int) s->frags, (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+ DrawQ_String(x, y, va(" %5i %c%s", (int) s->frags, myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
}
}
return 8;
/*
==================
-Sbar_DeathmatchOverlay
+Sbar_MiniDeathmatchOverlay
==================
*/
void Sbar_MiniDeathmatchOverlay (int x, int y)
{
- int i, numlines;
+ int i, j, numlines, range_begin, range_end, myteam, teamsep;
+
+ // do not draw this if sbar_miniscoreboard_size is zero
+ if(sbar_miniscoreboard_size.value == 0)
+ return;
+ // adjust the given y if sbar_miniscoreboard_size doesn't indicate default (< 0)
+ if(sbar_miniscoreboard_size.value > 0)
+ y = vid_conheight.integer - sbar_miniscoreboard_size.value * 8;
+
+ // scores
+ Sbar_SortFrags ();
// decide where to print
if (gamemode == GAME_TRANSFUSION)
if (x >= vid_conwidth.integer || y >= vid_conheight.integer || numlines < 1)
return;
- // scores
- Sbar_SortFrags ();
-
//find us
for (i = 0; i < scoreboardlines; i++)
if (fragsort[i] == cl.playerentity - 1)
break;
+ range_begin = 0;
+ range_end = scoreboardlines;
+ teamsep = 0;
+
+ if (gamemode != GAME_TRANSFUSION)
+ if (Sbar_IsTeammatch ())
+ {
+ // reserve space for the team scores
+ numlines -= teamlines;
+
+ // find first and last player of my team (only draw the team totals and my own team)
+ range_begin = range_end = i;
+ myteam = cl.scores[fragsort[i]].colors & 15;
+ while(range_begin > 0 && (cl.scores[fragsort[range_begin-1]].colors & 15) == myteam)
+ --range_begin;
+ while(range_end < scoreboardlines && (cl.scores[fragsort[range_end]].colors & 15) == myteam)
+ ++range_end;
+
+ // looks better than two players
+ if(numlines == 2)
+ {
+ teamsep = 8;
+ numlines = 1;
+ }
+ }
+
// figure out start
i -= numlines/2;
- i = min(i, scoreboardlines - numlines);
- i = max(i, 0);
+ i = min(i, range_end - numlines);
+ i = max(i, range_begin);
if (gamemode == GAME_TRANSFUSION)
{
- for (;i < scoreboardlines && x < vid_conwidth.integer;i++)
+ for (;i < range_end && x < vid_conwidth.integer;i++)
x += 128 + (int)Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
}
else
{
- for (;i < scoreboardlines && y < vid_conheight.integer;i++)
+ if(range_end - i < numlines) // won't draw to bottom?
+ y += 8 * (numlines - (range_end - i)); // bottom align
+ // show team scores first
+ for (j = 0;j < teamlines && y < vid_conheight.integer;j++)
+ y += (int)Sbar_PrintScoreboardItem((teams + teamsort[j]), x, y);
+ y += teamsep;
+ for (;i < range_end && y < vid_conheight.integer;i++)
y += (int)Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
}
}
+int Sbar_TeamColorCompare(const void *t1_, const void *t2_)
+{
+ static int const sortorder[16] =
+ {
+ 1001,
+ 1002,
+ 1003,
+ 1004,
+ 1, // red
+ 1005,
+ 1006,
+ 1007,
+ 1008,
+ 4, // pink
+ 1009,
+ 1010,
+ 3, // yellow
+ 2, // blue
+ 1011,
+ 1012
+ };
+ const scoreboard_t *t1 = *(scoreboard_t **) t1_;
+ const scoreboard_t *t2 = *(scoreboard_t **) t2_;
+ int tc1 = sortorder[t1->colors & 15];
+ int tc2 = sortorder[t2->colors & 15];
+ return tc1 - tc2;
+}
+
+void Sbar_Score (int margin)
+{
+ int i, me, score, otherleader, place, distribution, minutes, seconds;
+ double timeleft;
+ int sbar_x_save = sbar_x;
+ int sbar_y_save = sbar_y;
+
+ sbar_y = vid_conheight.value - (32+12);
+ sbar_x -= margin;
+
+ me = cl.playerentity - 1;
+ if (me >= 0 && me < cl.maxclients)
+ {
+ if(Sbar_IsTeammatch())
+ {
+ // Layout:
+ //
+ // team1 team3 team4
+ //
+ // TEAM2
+
+ scoreboard_t *teamcolorsort[16];
+
+ Sbar_SortFrags();
+ for(i = 0; i < teamlines; ++i)
+ teamcolorsort[i] = &(teams[i]);
+
+ // Now sort them by color
+ qsort(teamcolorsort, teamlines, sizeof(*teamcolorsort), Sbar_TeamColorCompare);
+
+ // : margin
+ // -12*4: four digits space
+ place = (teamlines - 1) * (-12 * 4);
+
+ for(i = 0; i < teamlines; ++i)
+ {
+ int cindex = teamcolorsort[i]->colors & 15;
+ unsigned char *c = (unsigned char *)&palette_complete[(cindex << 4) + 8];
+ float cm = max(max(c[0], c[1]), c[2]);
+ float cr = c[0] / cm;
+ float cg = c[1] / cm;
+ float cb = c[2] / cm;
+ if(cindex == (cl.scores[cl.playerentity - 1].colors & 15)) // my team
+ {
+ Sbar_DrawXNum(-32*4, 0, teamcolorsort[i]->frags, 4, 32, cr, cg, cb, 1, 0);
+ }
+ else // other team
+ {
+ Sbar_DrawXNum(place, -12, teamcolorsort[i]->frags, 4, 12, cr, cg, cb, 1, 0);
+ place += 4 * 12;
+ }
+ }
+ }
+ else
+ {
+ // Layout:
+ //
+ // leading place
+ //
+ // FRAGS
+ //
+ // find leading score other than ourselves, to calculate distribution
+ // find our place in the scoreboard
+ score = cl.scores[me].frags;
+ for (i = 0, otherleader = -1, place = 1;i < cl.maxclients;i++)
+ {
+ if (cl.scores[i].name[0] && i != me)
+ {
+ if (otherleader == -1 || cl.scores[i].frags > cl.scores[otherleader].frags)
+ otherleader = i;
+ if (score < cl.scores[i].frags || (score == cl.scores[i].frags && i < me))
+ place++;
+ }
+ }
+ distribution = otherleader >= 0 ? score - cl.scores[otherleader].frags : 0;
+ if (place == 1)
+ Sbar_DrawXNum(-3*12, -12, place, 3, 12, 1, 1, 1, 1, 0);
+ else if (place == 2)
+ Sbar_DrawXNum(-3*12, -12, place, 3, 12, 1, 1, 0, 1, 0);
+ else
+ Sbar_DrawXNum(-3*12, -12, place, 3, 12, 1, 0, 0, 1, 0);
+ if (otherleader < 0)
+ Sbar_DrawXNum(-32*4, 0, score, 4, 32, 1, 1, 1, 1, 0);
+ if (distribution >= 0)
+ {
+ Sbar_DrawXNum(-7*12, -12, distribution, 4, 12, 1, 1, 1, 1, 0);
+ Sbar_DrawXNum(-32*4, 0, score, 4, 32, 1, 1, 1, 1, 0);
+ }
+ else if (distribution >= -5)
+ {
+ Sbar_DrawXNum(-7*12, -12, distribution, 4, 12, 1, 1, 0, 1, 0);
+ Sbar_DrawXNum(-32*4, 0, score, 4, 32, 1, 1, 0, 1, 0);
+ }
+ else
+ {
+ Sbar_DrawXNum(-7*12, -12, distribution, 4, 12, 1, 0, 0, 1, 0);
+ Sbar_DrawXNum(-32*4, 0, score, 4, 32, 1, 0, 0, 1, 0);
+ }
+ }
+ }
+
+ if (cl.statsf[STAT_TIMELIMIT])
+ {
+ timeleft = max(0, cl.statsf[STAT_TIMELIMIT] * 60 - cl.time);
+ minutes = (int)floor(timeleft / 60);
+ seconds = (int)(floor(timeleft) - minutes * 60);
+ if (minutes >= 5)
+ {
+ Sbar_DrawXNum(-12*6, 32, minutes, 3, 12, 1, 1, 1, 1, 0);
+ if(sb_colon && sb_colon->tex != r_texture_notexture)
+ DrawQ_Pic(sbar_x + -12*3, sbar_y + 32, sb_colon, 12, 12, 1, 1, 1, sbar_alpha_fg.value, 0);
+ Sbar_DrawXNum(-12*2, 32, seconds, -2, 12, 1, 1, 1, 1, 0);
+ }
+ else if (minutes >= 1)
+ {
+ Sbar_DrawXNum(-12*6, 32, minutes, 3, 12, 1, 1, 0, 1, 0);
+ if(sb_colon && sb_colon->tex != r_texture_notexture)
+ DrawQ_Pic(sbar_x + -12*3, sbar_y + 32, sb_colon, 12, 12, 1, 1, 0, sbar_alpha_fg.value, 0);
+ Sbar_DrawXNum(-12*2, 32, seconds, -2, 12, 1, 1, 0, 1, 0);
+ }
+ else if ((int)(timeleft * 4) & 1)
+ Sbar_DrawXNum(-12*2, 32, seconds, -2, 12, 1, 1, 1, 1, 0);
+ else
+ Sbar_DrawXNum(-12*2, 32, seconds, -2, 12, 1, 0, 0, 1, 0);
+ }
+ else
+ {
+ minutes = (int)floor(cl.time / 60);
+ seconds = (int)(floor(cl.time) - minutes * 60);
+ Sbar_DrawXNum(-12*6, 32, minutes, 3, 12, 1, 1, 1, 1, 0);
+ if(sb_colon && sb_colon->tex != r_texture_notexture)
+ DrawQ_Pic(sbar_x + -12*3, sbar_y + 32, sb_colon, 12, 12, 1, 1, 1, sbar_alpha_fg.value, 0);
+ Sbar_DrawXNum(-12*2, 32, seconds, -2, 12, 1, 1, 1, 1, 0);
+ }
+
+ sbar_x = sbar_x_save;
+ sbar_y = sbar_y_save;
+}
+
/*
==================
Sbar_IntermissionOverlay
dig = (int)cl.completed_time / 60;
Sbar_DrawNum (160, 64, dig, 3, 0);
num = (int)cl.completed_time - dig*60;
- if (gamemode != GAME_NEXUIZ)
- Sbar_DrawPic (234,64,sb_colon);
+ Sbar_DrawPic (234,64,sb_colon);
Sbar_DrawPic (246,64,sb_nums[0][num/10]);
Sbar_DrawPic (266,64,sb_nums[0][num%10]);