// 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"};
+cvar_t crosshair_color_red = {CVAR_SAVE, "crosshair_color_red", "1", "customizable crosshair color"};
+cvar_t crosshair_color_green = {CVAR_SAVE, "crosshair_color_green", "0", "customizable crosshair color"};
+cvar_t crosshair_color_blue = {CVAR_SAVE, "crosshair_color_blue", "0", "customizable crosshair color"};
+cvar_t crosshair_color_alpha = {CVAR_SAVE, "crosshair_color_alpha", "1", "how opaque the crosshair should be"};
+cvar_t crosshair_size = {CVAR_SAVE, "crosshair_size", "1", "adjusts size of the crosshair on the screen"};
+
void Sbar_MiniDeathmatchOverlay (int x, int y);
void Sbar_DeathmatchOverlay (void);
void Sbar_IntermissionOverlay (void);
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);
sb_items[5] = Draw_CachePic ("gfx/sb_str", true);
+ sb_items[11] = Draw_CachePic ("gfx/sb_flag_red_taken", true);
+ sb_items[12] = Draw_CachePic ("gfx/sb_flag_red_lost", true);
+ sb_items[13] = Draw_CachePic ("gfx/sb_flag_red_carrying", true);
+ sb_items[14] = Draw_CachePic ("gfx/sb_key_carrying", true);
+ sb_items[15] = Draw_CachePic ("gfx/sb_flag_blue_taken", true);
+ sb_items[16] = Draw_CachePic ("gfx/sb_flag_blue_lost", true);
+ sb_items[17] = Draw_CachePic ("gfx/sb_flag_blue_carrying", true);
+
sb_sbar = Draw_CachePic("gfx/sbar", true);
sb_sbar_minimal = Draw_CachePic("gfx/sbar_minimal", true);
sb_sbar_overlay = Draw_CachePic("gfx/sbar_overlay", true);
void Sbar_Init (void)
{
- Cmd_AddCommand ("+showscores", Sbar_ShowScores, "show scoreboard");
- Cmd_AddCommand ("-showscores", Sbar_DontShowScores, "hide scoreboard");
- Cvar_RegisterVariable (&showfps);
- Cvar_RegisterVariable (&showtime);
- Cvar_RegisterVariable (&showtime_format);
- Cvar_RegisterVariable (&showdate);
- Cvar_RegisterVariable (&showdate_format);
- Cvar_RegisterVariable (&sbar_alpha_bg);
- Cvar_RegisterVariable (&sbar_alpha_fg);
- Cvar_RegisterVariable (&cl_deathscoreboard);
+ Cmd_AddCommand("+showscores", Sbar_ShowScores, "show scoreboard");
+ Cmd_AddCommand("-showscores", Sbar_DontShowScores, "hide scoreboard");
+ Cvar_RegisterVariable(&showfps);
+ Cvar_RegisterVariable(&showtime);
+ Cvar_RegisterVariable(&showtime_format);
+ Cvar_RegisterVariable(&showdate);
+ 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);
+ Cvar_RegisterVariable(&crosshair_color_green);
+ Cvar_RegisterVariable(&crosshair_color_blue);
+ Cvar_RegisterVariable(&crosshair_color_alpha);
+ Cvar_RegisterVariable(&crosshair_size);
R_RegisterModule("sbar", sbar_start, sbar_shutdown, sbar_newmap);
}
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);
*/
void Sbar_DrawCharacter (int x, int y, int num)
{
- DrawQ_String (sbar_x + x + 4 , sbar_y + y, va("%c", num), 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0);
+ DrawQ_String (sbar_x + x + 4 , sbar_y + y, va("%c", num), 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0, NULL, true);
}
/*
*/
void Sbar_DrawString (int x, int y, char *str)
{
- DrawQ_String (sbar_x + x, sbar_y + y, str, 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0);
+ DrawQ_String (sbar_x + x, sbar_y + y, str, 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0, NULL, false);
}
/*
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);
{
if (color != (cl.scores[fragsort[i]].colors & 15))
{
+ const char* teamname;
+
color = cl.scores[fragsort[i]].colors & 15;
teamlines++;
- if (color == 4)
- strcpy(teams[teamlines-1].name, "^1Red Team");
- else if (color == 13)
- strcpy(teams[teamlines-1].name, "^4Blue Team");
- else if (color == 9)
- strcpy(teams[teamlines-1].name, "^6Pink Team");
- else if (color == 12)
- strcpy(teams[teamlines-1].name, "^3Yellow Team");
- else
- strcpy(teams[teamlines-1].name, "Total Team Score");
+ switch (color)
+ {
+ case 4:
+ teamname = "^1Red Team";
+ break;
+ case 13:
+ teamname = "^4Blue Team";
+ break;
+ case 9:
+ teamname = "^6Pink Team";
+ break;
+ case 12:
+ teamname = "^3Yellow Team";
+ break;
+ default:
+ teamname = "Total Team Score";
+ break;
+ }
+ strlcpy(teams[teamlines-1].name, teamname, sizeof(teams[teamlines-1].name));
teams[teamlines-1].frags = 0;
teams[teamlines-1].colors = color + 16 * color;
*/
void Sbar_SoloScoreboard (void)
{
+#if 1
+ char str[80], timestr[40];
+ int max, timelen;
+ int minutes, seconds;
+ double t;
+
+ t = (cl.intermission ? cl.completed_time : cl.time);
+ minutes = (int)(t / 60);
+ seconds = (int)(t - 60*floor(t/60));
+
+ // monsters and secrets are now both on the top row
+ if (cl.stats[STAT_TOTALMONSTERS])
+ Sbar_DrawString(8, 4, va("Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]));
+ if (cl.stats[STAT_TOTALSECRETS])
+ Sbar_DrawString(8+22*8, 4, va("Secrets:%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]));
+
+ // figure out the map's filename without path or extension
+ strlcpy(str, FS_FileWithoutPath(cl.worldmodel ? cl.worldmodel->name : ""), sizeof(str));
+ if (strrchr(str, '.'))
+ *(strrchr(str, '.')) = 0;
+
+ // append a : separator and then the full title
+ strlcat(str, ":", sizeof(str));
+ strlcat(str, cl.levelname, sizeof(str));
+
+ // if there's a newline character, terminate the string there
+ if (strchr(str, '\n'))
+ *(strchr(str, '\n')) = 0;
+
+ // make the time string
+ timelen = sprintf(timestr, " %i:%02i", minutes, seconds);
+
+ // truncate the level name if necessary to make room for time
+ max = 38 - timelen;
+ if ((int)strlen(str) > max)
+ str[max] = 0;
+
+ // print the filename and message
+ Sbar_DrawString(8, 12, str);
+
+ // print the time
+ Sbar_DrawString(8 + max*8, 12, timestr);
+
+#else
char str[80];
int minutes, seconds, tens, units;
int l;
l = (int) strlen (cl.levelname);
Sbar_DrawString (232 - l*4, 12, cl.levelname);
}
+#endif
}
/*
void Sbar_DrawScoreboard (void)
{
Sbar_SoloScoreboard ();
- if (cl.gametype == GAME_DEATHMATCH)
+ // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
+ //if (cl.gametype == GAME_DEATHMATCH)
+ if (!cl.islocalgame)
Sbar_DeathmatchOverlay ();
}
// 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_ADDITIVE);
- //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);
+ 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;
- if (active)
- DrawQ_Pic(vid_conwidth.integer - (w_width + w_space) * w_scale, (w_height + w_space) * w_scale * nr + w_space, NULL, w_width * w_scale, w_height * w_scale, 0.3, 0.3, 0.3, fade * sbar_alpha_fg.value, DRAWFLAG_ADDITIVE);
+ 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);
+ }
}
/*
if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN<<i) )
{
time = cl.item_gettime[i];
- flashon = (int)((cl.time - time)*10);
+ flashon = (int)(max(0, cl.time - time)*10);
if (flashon >= 10)
{
if ( cl.stats[STAT_ACTIVEWEAPON] == (IT_SHOTGUN<<i) )
{
if (cl.stats[STAT_ITEMS] & (1<<hipweapons[i]) )
{
- time = cl.item_gettime[hipweapons[i]];
+ time = max(0, cl.item_gettime[hipweapons[i]]);
flashon = (int)((cl.time - time)*10);
if (flashon >= 10)
{
// draw background
c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
- DrawQ_Pic (sbar_x + x + 10, sbar_y - 23, NULL, 28, 4, 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);
+ DrawQ_Fill (sbar_x + x + 10, sbar_y - 23, 28, 4, 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);
c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
- DrawQ_Pic (sbar_x + x + 10, sbar_y + 4 - 23, NULL, 28, 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);
+ DrawQ_Fill (sbar_x + x + 10, sbar_y + 4 - 23, 28, 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);
// draw number
f = s->frags;
// draw background
Sbar_DrawPic (112, 0, rsb_teambord);
c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
- DrawQ_Pic (sbar_x + 113, vid_conheight.integer-SBAR_HEIGHT+3, NULL, 22, 9, 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);
+ DrawQ_Fill (sbar_x + 113, vid_conheight.integer-SBAR_HEIGHT+3, 22, 9, 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);
c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
- DrawQ_Pic (sbar_x + 113, vid_conheight.integer-SBAR_HEIGHT+12, NULL, 22, 9, 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);
+ DrawQ_Fill (sbar_x + 113, vid_conheight.integer-SBAR_HEIGHT+12, 22, 9, 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);
// draw number
f = s->frags;
static double framerate = 0;
static int framecount = 0;
double newtime;
- newtime = Sys_DoubleTime();
+ newtime = realtime;
if (newtime >= nexttime)
{
framerate = framecount / (newtime - lasttime);
if (fpsstring[0])
{
fps_x = vid_conwidth.integer - fps_scalex * strlen(fpsstring);
- DrawQ_Pic(fps_x, fps_y, NULL, fps_scalex * strlen(fpsstring), fps_scaley, 0, 0, 0, 0.5, 0);
+ DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(fpsstring), fps_scaley, 0, 0, 0, 0.5, 0);
if (red)
- DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 0, 0, 1, 0);
+ DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 0, 0, 1, 0, NULL, true);
else
- DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
+ DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true);
fps_y += fps_scaley;
}
if (timestring[0])
{
fps_x = vid_conwidth.integer - fps_scalex * strlen(timestring);
- DrawQ_Pic(fps_x, fps_y, NULL, fps_scalex * strlen(timestring), fps_scaley, 0, 0, 0, 0.5, 0);
- DrawQ_String(fps_x, fps_y, timestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
+ DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(timestring), fps_scaley, 0, 0, 0, 0.5, 0);
+ DrawQ_String(fps_x, fps_y, timestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true);
fps_y += fps_scaley;
}
if (datestring[0])
{
fps_x = vid_conwidth.integer - fps_scalex * strlen(datestring);
- DrawQ_Pic(fps_x, fps_y, NULL, fps_scalex * strlen(datestring), fps_scaley, 0, 0, 0, 0.5, 0);
- DrawQ_String(fps_x, fps_y, datestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
+ DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(datestring), fps_scaley, 0, 0, 0, 0.5, 0);
+ DrawQ_String(fps_x, fps_y, datestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true);
fps_y += fps_scaley;
}
}
*/
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;
+
if(cl.csqc_vidvars.drawenginesbar) //[515]: csqc drawsbar
{
- if (cl.intermission == 1)
+ if (sb_showscores)
+ Sbar_DrawScoreboard ();
+ else if (cl.intermission == 1)
{
+ if(gamemode == GAME_NEXUIZ) // display full scoreboard (that is, show scores + map name)
+ {
+ Sbar_DrawScoreboard();
+ return;
+ }
Sbar_IntermissionOverlay();
- return;
}
else if (cl.intermission == 2)
- {
Sbar_FinaleOverlay();
- return;
- }
-
- if (gamemode == GAME_NETHERWORLD)
+ else if (gamemode == GAME_NETHERWORLD)
{
}
else if (gamemode == GAME_SOM)
}
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;
- double time;
float fade;
+ int redflag, blueflag;
+
+ sbar_x = (vid_conwidth.integer - 640)/2;
+ sbar_y = vid_conheight.integer - 47;
- // we have a max time 2s (min time = 0)
- if ((time = cl.time - cl.weapontime) < 2)
+ // calculate intensity to draw weapons bar at
+ fade = 3 - 2 * (cl.time - cl.weapontime);
+ if (fade > 0)
{
- fade = (1.0 - 0.5 * time);
- fade *= fade;
+ fade = min(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]));
else
Sbar_DrawAlphaPic (0, 0, sb_sbar_minimal, sbar_alpha_fg.value);
- // special items
- if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
+ // flag icons
+ redflag = ((cl.stats[STAT_ITEMS]>>15) & 3);
+ blueflag = ((cl.stats[STAT_ITEMS]>>17) & 3);
+ if (redflag == 3 && blueflag == 3)
{
- // Nexuiz has no anum pics
- //Sbar_DrawNum (36, 0, 666, 3, 1);
- // Nexuiz has no disc pic
- //Sbar_DrawPic (0, 0, sb_disc);
+ // 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 (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;
- if (cl.gametype == GAME_DEATHMATCH && gamemode != GAME_TRANSFUSION)
- sbar_x = 0;
- else
- sbar_x = (vid_conwidth.integer - 320)/2;
+ // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
+ //if (cl.gametype == GAME_DEATHMATCH && gamemode != GAME_TRANSFUSION)
if (sb_lines > 24)
{
Sbar_DrawFace ();
// health
- Sbar_DrawNum (154, 0, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
+ Sbar_DrawNum (136, 0, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
// ammo icon
if (gamemode == GAME_ROGUE)
Sbar_DrawNum (248, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10);
- }
-
- if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
- {
- 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);
+ }
}
}
}
Sbar_ShowFPS();
- if(cl.csqc_vidvars.drawcrosshair)
- R_Draw2DCrosshair();
+ if (cl.csqc_vidvars.drawcrosshair && crosshair.integer >= 1 && crosshair.integer <= NUMCROSSHAIRS && !cl.intermission && !r_letterbox.value && (pic = r_crosshairs[crosshair.integer]))
+ DrawQ_Pic((vid_conwidth.integer - pic->width * crosshair_size.value) * 0.5f, (vid_conheight.integer - pic->height * crosshair_size.value) * 0.5f, pic, pic->width * crosshair_size.value, pic->height * crosshair_size.value, crosshair_color_red.value, crosshair_color_green.value, crosshair_color_blue.value, crosshair_color_alpha.value, 0);
if (cl_prydoncursor.integer)
DrawQ_Pic((cl.cmd.cursor_screen[0] + 1) * 0.5 * vid_conwidth.integer, (cl.cmd.cursor_screen[1] + 1) * 0.5 * vid_conheight.integer, Draw_CachePic(va("gfx/prydoncursor%03i", cl_prydoncursor.integer), true), 0, 0, 1, 1, 1, 1, 0);
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)
{
- minutes = (int)((cl.intermission ? cl.completed_time - s->qw_entertime : realtime - s->qw_entertime) / 60.0);
- // draw colors behind score
- c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
- DrawQ_Pic(x + 14*8, y+1, NULL, 32, 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);
- c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
- DrawQ_Pic(x + 14*8, y+4, NULL, 32, 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);
- DrawQ_ColoredString(x, y, va("%c%4i %2i %4i %4i %-4s %s", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), minutes,(int) s->frags, cl.qw_teamplay ? s->qw_team : "", s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL );
+ 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, 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, myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+ }
+ else
+ {
+ // draw colors behind score
+ c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
+ DrawQ_Fill(x + 14*8, y+1, 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);
+ 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", 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 : "", 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 : "", myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+ }
}
else
{
- // draw colors behind score
- c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
- DrawQ_Pic(x + 1*8, y+1, NULL, 32, 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);
- c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
- DrawQ_Pic(x + 1*8, y+4, NULL, 32, 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);
- DrawQ_ColoredString(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 );
+ 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), 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", myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+ }
+ else
+ {
+ // draw colors behind score
+ c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
+ DrawQ_Fill(x + 9*8, y+1, 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);
+ 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", 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, 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, myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+ }
}
return 8;
}
int i, x, y;
// request new ping times every two second
- if (cl.last_ping_request < realtime - 2)
+ if (cl.last_ping_request < realtime - 2 && cls.netcon)
{
cl.last_ping_request = realtime;
if (cls.protocol == PROTOCOL_QUAKEWORLD)
MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
MSG_WriteString(&cls.netcon->message, "pings");
}
+ else if (cls.protocol == PROTOCOL_QUAKE || cls.protocol == PROTOCOL_QUAKEDP || cls.protocol == PROTOCOL_NEHAHRAMOVIE || cls.protocol == PROTOCOL_DARKPLACES1 || cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3 || cls.protocol == PROTOCOL_DARKPLACES4 || cls.protocol == PROTOCOL_DARKPLACES5 || cls.protocol == PROTOCOL_DARKPLACES6/* || cls.protocol == PROTOCOL_DARKPLACES7*/)
+ {
+ // these servers usually lack the pings command and so a less efficient "ping" command must be sent, which on modern DP servers will also reply with a pingplreport command after the ping listing
+ static int ping_anyway_counter = 0;
+ if(cl.parsingtextexpectingpingforscores == 1)
+ {
+ Con_DPrintf("want to send ping, but still waiting for other reply\n");
+ if(++ping_anyway_counter >= 5)
+ cl.parsingtextexpectingpingforscores = 0;
+ }
+ if(cl.parsingtextexpectingpingforscores != 1)
+ {
+ ping_anyway_counter = 0;
+ cl.parsingtextexpectingpingforscores = 1; // hide the output of the next ping report
+ MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
+ MSG_WriteString(&cls.netcon->message, "ping");
+ }
+ }
+ else
+ {
+ // newer server definitely has pings command, so use it for more efficiency, avoids ping reports spamming the console if they are misparsed, and saves a little bandwidth
+ MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
+ MSG_WriteString(&cls.netcon->message, "pings");
+ }
}
DrawQ_Pic ((vid_conwidth.integer - sb_ranking->width)/2, 8, sb_ranking, 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
// scores
Sbar_SortFrags ();
// draw the text
+ y = 40;
if (cls.protocol == PROTOCOL_QUAKEWORLD)
- x = (vid_conwidth.integer - (6 + 17 + 15) * 8) / 2;
+ {
+ x = (vid_conwidth.integer - (26 + 15) * 8) / 2; // 26 characters until name, then we assume 15 character names (they can be longer but usually aren't)
+ DrawQ_String(x, y, va("ping pl%% time frags team name"), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+ }
else
- x = (vid_conwidth.integer - (6 + 15) * 8) / 2;
- y = 40;
+ {
+ x = (vid_conwidth.integer - (16 + 15) * 8) / 2; // 16 characters until name, then we assume 15 character names (they can be longer but usually aren't)
+ DrawQ_String(x, y, va("ping pl%% frags name"), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+ }
+ y += 8;
if (Sbar_IsTeammatch ())
{
/*
==================
-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
int dig;
int num;
- if (cl.gametype == GAME_DEATHMATCH)
+ // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
+ //if (cl.gametype == GAME_DEATHMATCH)
+ if (!cl.islocalgame)
{
Sbar_DeathmatchOverlay ();
return;
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]);