]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/client/hud/panel/scoreboard.qc
Merge branch 'master' into terencehill/scoreboard_update
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / hud / panel / scoreboard.qc
index f82c7345ca0c7d3afdc84102cd5a728afa54c6ed..7d14e9a95f448ab9224ef318ac184e00cf130dcd 100644 (file)
@@ -19,6 +19,7 @@ int sbt_num_fields;
 
 string autocvar_hud_fontsize;
 string hud_fontsize_str;
+float max_namesize;
 
 float sbt_bg_alpha;
 float sbt_fg_alpha;
@@ -49,6 +50,7 @@ bool autocvar_hud_panel_scoreboard_table_highlight = true;
 float autocvar_hud_panel_scoreboard_table_highlight_alpha = 0.2;
 float autocvar_hud_panel_scoreboard_table_highlight_alpha_self = 0.4;
 float autocvar_hud_panel_scoreboard_bg_teams_color_team = 0;
+float autocvar_hud_panel_scoreboard_namesize = 15;
 
 bool autocvar_hud_panel_scoreboard_accuracy = true;
 bool autocvar_hud_panel_scoreboard_accuracy_doublerows = false;
@@ -56,6 +58,12 @@ bool autocvar_hud_panel_scoreboard_accuracy_nocolors = false;
 
 bool autocvar_hud_panel_scoreboard_dynamichud = false;
 
+bool autocvar_hud_panel_scoreboard_maxrows = true;
+int autocvar_hud_panel_scoreboard_maxrows_players = 20;
+int autocvar_hud_panel_scoreboard_maxrows_teamplayers = 9;
+bool autocvar_hud_panel_scoreboard_others_showscore = true;
+bool autocvar_hud_panel_scoreboard_spectators_showping = true;
+
 
 void drawstringright(vector, string, vector, vector, float, float);
 void drawstringcenter(vector, string, vector, vector, float, float);
@@ -723,18 +731,20 @@ string Scoreboard_FixColumnWidth(int i, string str)
        if(sbt_field[i] == SP_NAME) // name gets all remaining space
        {
                int j;
-               float namesize;
-               namesize = panel_size.x;
+               float remaining_space = 0;
                for(j = 0; j < sbt_num_fields; ++j)
                        if(j != i)
                                if (sbt_field[i] != SP_SEPARATOR)
-                                       namesize -= sbt_field_size[j] + hud_fontsize.x;
-               sbt_field_size[i] = namesize;
+                                       remaining_space += sbt_field_size[j] + hud_fontsize.x;
+               sbt_field_size[i] = panel_size.x - remaining_space;
 
                if (sbt_fixcolumnwidth_iconlen != 0)
-                       namesize -= sbt_fixcolumnwidth_marginlen + sbt_fixcolumnwidth_iconlen * hud_fontsize.x;
+                       remaining_space += sbt_fixcolumnwidth_marginlen + sbt_fixcolumnwidth_iconlen * hud_fontsize.x;
+               float namesize = panel_size.x - remaining_space;
                str = textShortenToWidth(str, namesize, hud_fontsize, stringwidth_colors);
                sbt_fixcolumnwidth_len = stringwidth(str, true, hud_fontsize);
+
+               max_namesize = vid_conwidth - remaining_space;
        }
        else
                sbt_fixcolumnwidth_len = stringwidth(str, false, hud_fontsize);
@@ -749,13 +759,15 @@ string Scoreboard_FixColumnWidth(int i, string str)
 void Scoreboard_initFieldSizes()
 {
        for(int i = 0; i < sbt_num_fields; ++i)
-               sbt_field_size[i] = stringwidth(sbt_field_title[i], false, hud_fontsize);
+               Scoreboard_FixColumnWidth(i, "");
 }
 
-vector Scoreboard_DrawHeader(vector pos, vector rgb)
+vector Scoreboard_DrawHeader(vector pos, vector rgb, bool other_players)
 {
        int i;
        vector column_dim = eY * panel_size.y;
+       if(other_players)
+               column_dim.y -= 1.25 * hud_fontsize.y;
        vector text_offset = eY * (1.25 - 1) / 2 * hud_fontsize.y;
        pos.x += hud_fontsize.x * 0.5;
        for(i = 0; i < sbt_num_fields; ++i)
@@ -891,12 +903,92 @@ void Scoreboard_DrawItem(vector item_pos, vector rgb, entity pl, bool is_self, i
                drawfill(h_pos, h_size, '0 0 0', 0.5 * panel_fg_alpha, DRAWFLAG_NORMAL);
 }
 
+vector Scoreboard_DrawOthers(vector item_pos, vector rgb, int this_team, entity ignored_pl, entity pl, int pl_number)
+{
+       int i = 0;
+       vector h_pos = item_pos;
+       vector h_size = eX * panel_size.x + eY * hud_fontsize.y * 1.25;
+
+       bool complete = (this_team == NUM_SPECTATOR);
+
+       if(!complete)
+       if((sbt_highlight) && (!(pl_number % 2)))
+               drawfill(h_pos, h_size, rgb, sbt_highlight_alpha, DRAWFLAG_NORMAL);
+
+       vector pos = item_pos;
+       pos.x += hud_fontsize.x * 0.5;
+       pos.y += (1.25 - 1) / 2 * hud_fontsize.y; // center text vertically
+
+       float width_limit = item_pos.x + panel_size.x - hud_fontsize.x;
+       if(!complete)
+               width_limit -= stringwidth("...", false, hud_fontsize);
+       float namesize = autocvar_hud_panel_scoreboard_namesize * hud_fontsize.x;
+       float ping_padding = 0;
+       float min_pingsize = stringwidth("999", false, hud_fontsize);
+       for(i = 0; pl; pl = pl.sort_next)
+       {
+               if(pl.team != this_team)
+                       continue;
+               if(pl == ignored_pl)
+                       continue;
+
+               ping_padding = 0;
+               string str = textShortenToWidth(entcs_GetName(pl.sv_entnum), namesize, hud_fontsize, stringwidth_colors);
+               if(this_team == NUM_SPECTATOR)
+               {
+                       if(autocvar_hud_panel_scoreboard_spectators_showping)
+                       {
+                               string ping = Scoreboard_GetField(pl, SP_PING);
+                               float pingsize = stringwidth(ping, false, hud_fontsize);
+                               if(min_pingsize > pingsize)
+                                       ping_padding = min_pingsize - pingsize;
+                               string col = rgb_to_hexcolor(sbt_field_rgb);
+                               str = sprintf("%s ^7[%s%s^7]", str, col, ping);
+                       }
+               }
+               else if(autocvar_hud_panel_scoreboard_others_showscore)
+                       str = sprintf("%s ^7(^3%s^7)", str, ftos(pl.(scores(ps_primary))));
+               float str_width = stringwidth(str, true, hud_fontsize);
+               if(pos.x + str_width > width_limit)
+               {
+                       ++i;
+                       if(!complete)
+                       {
+                               drawstring(pos, "...", hud_fontsize, '1 1 1', sbt_fg_alpha, DRAWFLAG_NORMAL);
+                               break;
+                       }
+                       else
+                       {
+                               pos.x = item_pos.x + hud_fontsize.x * 0.5;
+                               pos.y = item_pos.y + i * (hud_fontsize.y * 1.25);
+                       }
+               }
+               drawcolorcodedstring(pos, str, hud_fontsize, sbt_fg_alpha, DRAWFLAG_NORMAL);
+               pos.x += str_width + hud_fontsize.x * 0.5;
+               pos.x += ping_padding;
+       }
+       return eX * item_pos.x + eY * (item_pos.y + i * hud_fontsize.y * 1.25);
+}
+
 vector Scoreboard_MakeTable(vector pos, entity tm, vector rgb, vector bg_size)
 {
-       entity pl;
+       int max_players = 999;
+       if(autocvar_hud_panel_scoreboard_maxrows)
+       {
+               if(teamplay)
+                       max_players = autocvar_hud_panel_scoreboard_maxrows_teamplayers;
+               else
+                       max_players = autocvar_hud_panel_scoreboard_maxrows_players;
+               if(max_players <= 1)
+                       max_players = 1;
+               if(max_players == tm.team_size)
+                       max_players = 999;
+       }
 
+       entity pl;
+       entity me = playerslots[current_player];
        panel_pos = pos;
-       panel_size.y = 1.25 * hud_fontsize.y * (1 + max(1, tm.team_size));
+       panel_size.y = 1.25 * hud_fontsize.y * (1 + bound(1, tm.team_size, max_players));
        panel_size.y += panel_bg_padding * 2;
        HUD_Panel_DrawBg();
 
@@ -926,28 +1018,38 @@ vector Scoreboard_MakeTable(vector pos, entity tm, vector rgb, vector bg_size)
 
 
        // print header row and highlight columns
-       pos = Scoreboard_DrawHeader(panel_pos, rgb);
+       pos = Scoreboard_DrawHeader(panel_pos, rgb, (max_players < tm.team_size));
 
        // fill the table and draw the rows
+       bool is_self = false;
+       bool self_shown = false;
        int i = 0;
-       if (teamplay)
-               for(pl = players.sort_next; pl; pl = pl.sort_next)
+       for(pl = players.sort_next; pl; pl = pl.sort_next)
+       {
+               if(pl.team != tm.team)
+                       continue;
+               if(i == max_players - 2 && pl != me)
                {
-                       if(pl.team != tm.team)
-                               continue;
-                       Scoreboard_DrawItem(pos, rgb, pl, (pl.sv_entnum == player_localnum), i);
-                       pos.y += 1.25 * hud_fontsize.y;
-                       ++i;
+                       if(!self_shown && me.team == tm.team)
+                       {
+                               Scoreboard_DrawItem(pos, rgb, me, true, i);
+                               self_shown = true;
+                               pos.y += 1.25 * hud_fontsize.y;
+                               ++i;
+                       }
                }
-       else
-               for(pl = players.sort_next; pl; pl = pl.sort_next)
+               if(i >= max_players - 1)
                {
-                       if(pl.team == NUM_SPECTATOR)
-                               continue;
-                       Scoreboard_DrawItem(pos, rgb, pl, (pl.sv_entnum == player_localnum), i);
-                       pos.y += 1.25 * hud_fontsize.y;
-                       ++i;
+                       pos = Scoreboard_DrawOthers(pos, rgb, tm.team, (self_shown ? me : NULL), pl, i);
+                       break;
                }
+               is_self = (pl.sv_entnum == current_player);
+               Scoreboard_DrawItem(pos, rgb, pl, is_self, i);
+               if(is_self)
+                       self_shown = true;
+               pos.y += 1.25 * hud_fontsize.y;
+               ++i;
+       }
 
        panel_size.x += panel_bg_padding * 2; // restore initial width
        return end_pos;
@@ -1309,15 +1411,17 @@ void Scoreboard_Draw()
        if(!autocvar__hud_configure)
                panel_pos.y = max((autocvar_con_notify * autocvar_con_notifysize), panel_pos.y);
 
+       float excess = max(0, max_namesize - autocvar_hud_panel_scoreboard_namesize * hud_fontsize.x);
+       float fixed_scoreboard_width = bound(vid_conwidth * 0.4, vid_conwidth - excess, vid_conwidth * 0.93);
+       panel_pos.x = 0.5 * (vid_conwidth - fixed_scoreboard_width);
+       panel_size.x = fixed_scoreboard_width;
+
        Scoreboard_UpdatePlayerTeams();
 
-       vector pos, tmp;
+       vector pos = panel_pos;
        entity pl, tm;
        string str;
 
-       // Initializes position
-       pos = panel_pos;
-
        // Heading
        vector sb_heading_fontsize;
        sb_heading_fontsize = hud_fontsize * 2;
@@ -1372,12 +1476,10 @@ void Scoreboard_Draw()
        else
        {
                for(tm = teams.sort_next; tm; tm = tm.sort_next)
-               {
-                       if(tm.team == NUM_SPECTATOR)
-                               continue;
-
-                       pos = Scoreboard_MakeTable(pos, tm, panel_bg_color, bg_size);
-               }
+                       if(tm.team != NUM_SPECTATOR)
+                               break;
+               // display it anyway
+               pos = Scoreboard_MakeTable(pos, tm, panel_bg_color, bg_size);
        }
 
        if(gametype == MAPINFO_TYPE_CTS || gametype == MAPINFO_TYPE_RACE) {
@@ -1397,23 +1499,20 @@ void Scoreboard_Draw()
        pos = Scoreboard_MapStats_Draw(pos, panel_bg_color, bg_size);
 
        // List spectators
-       float specs = 0;
-       tmp = pos;
        for(pl = players.sort_next; pl; pl = pl.sort_next)
        {
-               if(pl.team != NUM_SPECTATOR)
-                       continue;
-               pos.y += 1.25 * hud_fontsize.y;
-               Scoreboard_DrawItem(pos, '0 0 0', pl, (pl.sv_entnum == player_localnum), specs);
-               ++specs;
-       }
+               if(pl.team == NUM_SPECTATOR)
+               {
+                       draw_beginBoldFont();
+                       drawstring(pos, _("Spectators"), hud_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+                       draw_endBoldFont();
+                       pos.y += 1.25 * hud_fontsize.y;
 
-       if(specs)
-       {
-               draw_beginBoldFont();
-               drawstring(tmp, _("Spectators"), hud_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
-               draw_endBoldFont();
-               pos.y += 1.25 * hud_fontsize.y;
+                       pos = Scoreboard_DrawOthers(pos, '0 0 0', pl.team, NULL, pl, 0);
+                       pos.y += 1.25 * hud_fontsize.y;
+
+                       break;
+               }
        }
 
        // Print info string