]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - sbar.c
added DP_QC_STRFTIME extension
[xonotic/darkplaces.git] / sbar.c
diff --git a/sbar.c b/sbar.c
index 2dc35e04027ceb2053e382217ce9638038ec7baf..95fb089d8c98271c1cfa418034d2d009058f4578 100644 (file)
--- a/sbar.c
+++ b/sbar.c
@@ -96,6 +96,12 @@ cvar_t sbar_alpha_fg = {CVAR_SAVE, "sbar_alpha_fg", "1", "opacity value of the s
 
 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);
@@ -167,6 +173,13 @@ void sbar_start(void)
                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[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);
@@ -337,16 +350,22 @@ void sbar_newmap(void)
 
 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(&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);
 }
@@ -541,19 +560,30 @@ void Sbar_SortFrags (void)
                {
                        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;
@@ -592,6 +622,45 @@ Sbar_SoloScoreboard
 */
 void Sbar_SoloScoreboard (void)
 {
+#if 1
+       char    str[80], timestr[40];
+       int             i, max;
+       int             minutes, seconds;
+
+       minutes = (int)(cl.time / 60);
+       seconds = (int)(cl.time - 60*floor(cl.time/60));
+
+       // monsters and secrets are now both on the top row
+       if (gamemode != GAME_NEXUIZ)
+               Sbar_DrawString(8, 4, va("Monsters:%3i /%3i    Secrets :%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS], 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));
+
+       // make the time string
+       max = 38 - sprintf(timestr, " %i:%02i", minutes, seconds);
+
+       // if there's a newline character, terminate the string there
+       if (strchr(str, '\n'))
+               *(strchr(str, '\n')) = 0;
+
+       // pad with spaces to fill the allotted space and append the time
+       i = bound(0, (int)strlen(str), max);
+       while (i < max)
+               str[i++] = ' ';
+       str[i] = 0;
+       strlcat(str, timestr, sizeof(str));
+
+       // print the line of text
+       Sbar_DrawString(8, 12, str);
+
+#else
        char    str[80];
        int             minutes, seconds, tens, units;
        int             l;
@@ -620,6 +689,7 @@ void Sbar_SoloScoreboard (void)
                l = (int) strlen (cl.levelname);
                Sbar_DrawString (232 - l*4, 12, cl.levelname);
        }
+#endif
 }
 
 /*
@@ -630,7 +700,9 @@ Sbar_DrawScoreboard
 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 ();
 }
 
@@ -678,7 +750,7 @@ void Sbar_DrawInventory (void)
                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)  )
@@ -702,7 +774,7 @@ void Sbar_DrawInventory (void)
                {
                        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)
                                {
@@ -1014,6 +1086,8 @@ extern float v_dmg_time, v_dmg_roll, v_dmg_pitch;
 extern cvar_t v_kicktime;
 void Sbar_Draw (void)
 {
+       cachepic_t *pic;
+
        if(cl.csqc_vidvars.drawenginesbar)      //[515]: csqc drawsbar
        {
                if (cl.intermission == 1)
@@ -1085,9 +1159,10 @@ void Sbar_Draw (void)
                                int i;
                                double time;
                                float fade;
+                               int redflag, blueflag;
 
                                // we have a max time 2s (min time = 0)
-                               if ((time = cl.time - cl.weapontime) < 2)
+                               if ((time = max(0, cl.time - cl.weapontime)) < 2)
                                {
                                        fade = (1.0 - 0.5 * time);
                                        fade *= fade;
@@ -1107,14 +1182,13 @@ void Sbar_Draw (void)
                                else
                                        Sbar_DrawAlphaPic (0, 0, sb_sbar_minimal, sbar_alpha_fg.value);
 
-                               // special items
-                               if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
-                               {
-                                       // Nexuiz has no anum pics
-                                       //Sbar_DrawNum (36, 0, 666, 3, 1);
-                                       // Nexuiz has no disc pic
-                                       //Sbar_DrawPic (0, 0, sb_disc);
-                               }
+                               // flag icons
+                               redflag = ((cl.stats[STAT_ITEMS]>>15) & 3);
+                               if (redflag)
+                                       Sbar_DrawPic (10, -85, sb_items[redflag+10]);
+                               blueflag = ((cl.stats[STAT_ITEMS]>>17) & 3);
+                               if (blueflag)
+                                       Sbar_DrawPic (10, -145, sb_items[blueflag+14]);
 
                                // armor
                                Sbar_DrawXNum ((340-3*24), 12, cl.stats[STAT_ARMOR], 3, 24, 0.6,0.7,0.8,1,0);
@@ -1220,7 +1294,9 @@ void Sbar_Draw (void)
                else // Quake and others
                {
                        sbar_y = vid_conheight.integer - SBAR_HEIGHT;
-                       if (cl.gametype == GAME_DEATHMATCH && gamemode != GAME_TRANSFUSION)
+                       // 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;
@@ -1289,7 +1365,7 @@ void Sbar_Draw (void)
                                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)
@@ -1325,7 +1401,9 @@ void Sbar_Draw (void)
 
                        }
 
-                       if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
+                       // 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);
@@ -1337,8 +1415,8 @@ void Sbar_Draw (void)
 
        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);
@@ -1356,28 +1434,54 @@ float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
 {
        int minutes;
        unsigned char *c;
+       minutes = (int)((cl.intermission ? cl.completed_time - s->qw_entertime : cl.time - s->qw_entertime) / 60.0);
        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_ColoredString(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 );
+                       else
+                               DrawQ_ColoredString(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 );
+               }
+               else
+               {
+                       // draw colors behind score
+                       c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
+                       DrawQ_Pic(x + 14*8, y+1, NULL, 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_Pic(x + 14*8, y+4, NULL, 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);
+                       if (s->qw_ping || s->qw_packetloss)
+                               DrawQ_ColoredString(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 );
+                       else
+                               DrawQ_ColoredString(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 );
+               }
        }
        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_ColoredString(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 );
+                       else
+                               DrawQ_ColoredString(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 );
+               }
+               else
+               {
+                       // draw colors behind score
+                       c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
+                       DrawQ_Pic(x + 9*8, y+1, NULL, 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_Pic(x + 9*8, y+4, NULL, 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);
+                       if (s->qw_ping || s->qw_packetloss)
+                               DrawQ_ColoredString(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 );
+                       else
+                               DrawQ_ColoredString(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 );
+               }
        }
        return 8;
 }
@@ -1387,7 +1491,7 @@ void Sbar_DeathmatchOverlay (void)
        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)
@@ -1395,6 +1499,30 @@ void Sbar_DeathmatchOverlay (void)
                        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
+                       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);
@@ -1402,11 +1530,18 @@ void Sbar_DeathmatchOverlay (void)
        // 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_ColoredString(x, y, va("ping pl%% time frags team  name"), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL );
+       }
        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_ColoredString(x, y, va("ping pl%% frags  name"), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL );
+       }
+       y += 8;
 
        if (Sbar_IsTeammatch ())
        {
@@ -1476,7 +1611,9 @@ void Sbar_IntermissionOverlay (void)
        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;