]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into terencehill/scoreboard_item_stats 663/head
authorMario <mario.mario@y7mail.com>
Tue, 26 Jan 2021 11:58:13 +0000 (21:58 +1000)
committerMario <mario.mario@y7mail.com>
Tue, 26 Jan 2021 11:58:13 +0000 (21:58 +1000)
1  2 
_hud_common.cfg
_hud_descriptions.cfg
hud_luma.cfg
hud_luminos.cfg
hud_luminos_minimal.cfg
hud_luminos_minimal_xhair.cfg
hud_luminos_old.cfg
hud_nexuiz.cfg
qcsrc/client/hud/panel/scoreboard.qc
qcsrc/common/state.qc

diff --combined _hud_common.cfg
index 29c41803f11dcd69647dc4f036ce5eb70ff68604,4973ef0bc008d88d2dc1e1f6dda768c30c451961..9719c9dbee806e29f7979b4adad73549d7d19cda
@@@ -45,9 -45,8 +45,9 @@@ seta hud_panel_centerprint      1 "enab
  seta hud_panel_itemstime        2 "enable this panel, 1 = show when spectating, 2 = even playing in warmup stage"
  //seta hud_panel_quickmenu        1 "enable this panel"
  //seta hud_panel_scoreboard       1 "enable this panel"
 -seta hud_panel_scoreboard_accuracy 1 "show weapon accuracy stats panel on scoreboard; colors can be configured with accuracy_color* cvars"
 +seta hud_panel_scoreboard_accuracy 1 "show weapon accuracy stats panel in the scoreboard; colors can be configured with accuracy_color* cvars"
  seta hud_panel_scoreboard_ctf_leaderboard 1 "show a capture time rankings leaderboard in the scoreboard if allowed by the server"
 +seta hud_panel_scoreboard_itemstats 1 "show item stats panel in the scoreboard"
  seta hud_panel_strafehud        3 "enable this panel, 1 = show if not observing, 2 = show always, 3 = show only in race/cts if not observing"
  
  seta hud_panel_weapons_dynamichud          1 "apply the dynamic hud effects to this panel"
@@@ -84,6 -83,7 +84,7 @@@ seta hud_panel_ammo_hide_ondeath 0 "hid
  
  seta hud_panel_powerups_hide_ondeath 0 "hide this panel when dead"
  
+ seta hud_panel_healtharmor_oxygenbar_startalpha "0.2" "start alpha of the oxygen bar"
  seta hud_panel_healtharmor_maxhealth "200" "when you have this much health, the health status bar is full"
  seta hud_panel_healtharmor_maxarmor "200" "when you have this much armor, the armor status bar is full"
  seta hud_panel_healtharmor_progressbar_gfx_damage 5 "show damage effect when damaged at least by this amount; 0 disables the effect"
@@@ -120,14 -120,13 +121,17 @@@ seta hud_panel_scoreboard_others_showsc
  seta hud_panel_scoreboard_spectators_showping 1 "show ping of spectators"
  seta hud_panel_scoreboard_spectators_aligned 0 "align spectators in columns"
  seta hud_panel_scoreboard_minwidth 0.6 "minimum width of the scoreboard"
 +seta hud_panel_scoreboard_team_size_position 0 "where to show the team size (0 = do not show, 1 = left of scoreboard, 2 = right of scoreboard), will move team scores to the other side if necessary"
+ seta hud_panel_scoreboard_playerid 0 "show player id (server entity number) next to player's name"
+ seta hud_panel_scoreboard_playerid_prefix "#" "player id prefix"
+ seta hud_panel_scoreboard_playerid_suffix " " "player id suffix"
  
  seta hud_panel_scoreboard_accuracy_showdelay 2 "how long to delay displaying accuracy below the scoreboard if it's too far down"
  seta hud_panel_scoreboard_accuracy_showdelay_minpos 0.75 "delay displaying the accuracy panel only if its position is lower than this percentage of the screen height from the top"
 -seta hud_panel_scoreboard_team_size_position 0 "where to show the team size (0 = do not show, 1 = left of scoreboard, 2 = right of scoreboard), will move team scores to the other side if necessary"
 +
 +seta hud_panel_scoreboard_itemstats_filter 1 "filter out less interesting items (ammo and smaller health/armor)"
 +seta hud_panel_scoreboard_itemstats_showdelay 2.2 "how long to delay displaying item stats below the scoreboard if it's too far down"
 +seta hud_panel_scoreboard_itemstats_showdelay_minpos 0.75 "delay displaying the item stats panel only if its position is lower than this percentage of the screen height from the top"
  
  seta _hud_panel_strafehud_demo "0" "strafehud changes angle during configure"
  seta hud_panel_strafehud_mode "0" "strafehud mode which controls whether the strafehud is centered at \"0\" = view angle, \"1\" = velocity angle"
@@@ -202,7 -201,7 +206,7 @@@ set _hud_showbinds_reload 0        "set it to 
  
  seta hud_colorflash_alpha 0.5 "starting alpha of the color flash"
  
- seta hud_damage 0.55 "an improved version of gl_polyblend for damage, draw an image instead when hurt"
+ seta hud_damage 0.55 "draw a blood image when hurt (improved version of gl_polyblend)"
  seta hud_damage_blur 0 "Use postprocessing to blur the screen when you have taken damage. This can be paired with current hud damage or just used alone. Higher values = more blur"
  seta hud_damage_blur_alpha 0.5 "Amount of alpha to use when merging the blurred layers back into the render. Turning this up higher will remove bloom, so it's best to find a balance"
  seta hud_damage_gentle_alpha_multiplier 0.10 "how much to multiply alpha of flash when using the cl_gentle version, it's much more opaque than the non-gentle version"
diff --combined _hud_descriptions.cfg
index 8dd81c1cbce4ec8b10fc2e42e7fe4e993d92a386,4bb0582cfa6231e1605197e21056cd338bba3acb..02d2d5a0f46adb114c507ccbc327b5dc57ed39c3
@@@ -375,10 -375,10 +375,11 @@@ seta hud_panel_scoreboard_table_fg_alph
  seta hud_panel_scoreboard_table_highlight "" "enable highlighting for rows and columns in scoreboard tables"
  seta hud_panel_scoreboard_table_highlight_alpha "" "highlight alpha of a scoreboard table"
  seta hud_panel_scoreboard_table_highlight_alpha_self "" "self highlight alpha of a scoreboard table"
+ seta hud_panel_scoreboard_table_highlight_alpha_eliminated "" "eliminated highlight alpha of a scoreboard table"
  seta hud_panel_scoreboard_bg_teams_color_team "" "override panel team color in team tables"
  seta hud_panel_scoreboard_accuracy_doublerows "" "use two rows instead of one"
  seta hud_panel_scoreboard_accuracy_nocolors "" "don't use colors displaying accuracy stats"
 +seta hud_panel_scoreboard_itemstats_doublerows "" "use two rows instead of one"
  
  seta hud_panel_strafehud_pos "" "position of this base of the panel"
  seta hud_panel_strafehud_size "" "size of this panel"
diff --combined hud_luma.cfg
index 5181130b2e4e9f12c742df5bd4332aeea8d8f27c,0ae785b714b91ce2fe09c6061848e9afacc24d8f..9ad2425a7c498bf97171eff9bea3acbb18ca03a3
@@@ -376,10 -376,10 +376,11 @@@ seta hud_panel_scoreboard_table_fg_alph
  seta hud_panel_scoreboard_table_highlight "1"
  seta hud_panel_scoreboard_table_highlight_alpha "0.2"
  seta hud_panel_scoreboard_table_highlight_alpha_self "0.4"
+ seta hud_panel_scoreboard_table_highlight_alpha_eliminated "0.6"
  seta hud_panel_scoreboard_bg_teams_color_team "0"
  seta hud_panel_scoreboard_accuracy_doublerows "0"
  seta hud_panel_scoreboard_accuracy_nocolors "0"
 +seta hud_panel_scoreboard_itemstats_doublerows "0"
  
  seta hud_panel_strafehud_pos "0.320000 0.570000"
  seta hud_panel_strafehud_size "0.360000 0.020000"
diff --combined hud_luminos.cfg
index a91a289705ab4dce76470d4743545ea891447404,f34ba0e23ab5702512b8841e91f7a8a06bdcc59d..c642ac38f46121727ce1487c6a78b6cc8a8d2462
@@@ -376,10 -376,10 +376,11 @@@ seta hud_panel_scoreboard_table_fg_alph
  seta hud_panel_scoreboard_table_highlight "1"
  seta hud_panel_scoreboard_table_highlight_alpha "0.08"
  seta hud_panel_scoreboard_table_highlight_alpha_self "0.3"
+ seta hud_panel_scoreboard_table_highlight_alpha_eliminated "0.5"
  seta hud_panel_scoreboard_bg_teams_color_team "0"
  seta hud_panel_scoreboard_accuracy_doublerows "1"
  seta hud_panel_scoreboard_accuracy_nocolors "0"
 +seta hud_panel_scoreboard_itemstats_doublerows "0"
  
  seta hud_panel_strafehud_pos "0.330000 0.570000"
  seta hud_panel_strafehud_size "0.340000 0.020000"
diff --combined hud_luminos_minimal.cfg
index 31a798f050dd7c71592593b214cfdc09114ed292,0756e25399b45a254aff48e699e0228f518dad48..d15dd868ac2c37c074f2a17da73137ebb99774a6
@@@ -376,10 -376,10 +376,11 @@@ seta hud_panel_scoreboard_table_fg_alph
  seta hud_panel_scoreboard_table_highlight "1"
  seta hud_panel_scoreboard_table_highlight_alpha "0.08"
  seta hud_panel_scoreboard_table_highlight_alpha_self "0.3"
+ seta hud_panel_scoreboard_table_highlight_alpha_eliminated "0.5"
  seta hud_panel_scoreboard_bg_teams_color_team "0.7"
  seta hud_panel_scoreboard_accuracy_doublerows "1"
  seta hud_panel_scoreboard_accuracy_nocolors "0"
 +seta hud_panel_scoreboard_itemstats_doublerows "0"
  
  seta hud_panel_strafehud_pos "0.380000 0.550000"
  seta hud_panel_strafehud_size "0.240000 0.025000"
index 9e6538520a45ac6dc65016012abf80413ff937b9,53287c16fa33229c7b6c09d2a9865bff2bcdd887..11c57ee484bdc0344e34c507f5408a9d35d41a1a
@@@ -376,10 -376,10 +376,11 @@@ seta hud_panel_scoreboard_table_fg_alph
  seta hud_panel_scoreboard_table_highlight "1"
  seta hud_panel_scoreboard_table_highlight_alpha "0.08"
  seta hud_panel_scoreboard_table_highlight_alpha_self "0.3"
+ seta hud_panel_scoreboard_table_highlight_alpha_eliminated "0.5"
  seta hud_panel_scoreboard_bg_teams_color_team "0.7"
  seta hud_panel_scoreboard_accuracy_doublerows "1"
  seta hud_panel_scoreboard_accuracy_nocolors "0"
 +seta hud_panel_scoreboard_itemstats_doublerows "0"
  
  seta hud_panel_strafehud_pos "0.330000 0.700000"
  seta hud_panel_strafehud_size "0.340000 0.015000"
diff --combined hud_luminos_old.cfg
index eac63c6bbcb3295e1f1bbed1b74b44b8dff8923f,f30c21064512a4513d4429fd4974f60feaee5bfb..42a79015cdc43267e21a93505aa7a287987c133a
@@@ -376,10 -376,10 +376,11 @@@ seta hud_panel_scoreboard_table_fg_alph
  seta hud_panel_scoreboard_table_highlight "1"
  seta hud_panel_scoreboard_table_highlight_alpha "0.08"
  seta hud_panel_scoreboard_table_highlight_alpha_self "0.3"
+ seta hud_panel_scoreboard_table_highlight_alpha_eliminated "0.5"
  seta hud_panel_scoreboard_bg_teams_color_team "0.7"
  seta hud_panel_scoreboard_accuracy_doublerows "1"
  seta hud_panel_scoreboard_accuracy_nocolors "0"
 +seta hud_panel_scoreboard_itemstats_doublerows "0"
  
  seta hud_panel_strafehud_pos "0.320000 0.540000"
  seta hud_panel_strafehud_size "0.360000 0.025000"
diff --combined hud_nexuiz.cfg
index f2a56cc080e42f7f377e26de2edc25623f971b09,fc87b820123de396577d43921c2b556140396528..9200283c3d3c1aeaed050a7933f4f9e675039ca7
@@@ -376,10 -376,10 +376,11 @@@ seta hud_panel_scoreboard_table_fg_alph
  seta hud_panel_scoreboard_table_highlight "1"
  seta hud_panel_scoreboard_table_highlight_alpha "0.1"
  seta hud_panel_scoreboard_table_highlight_alpha_self "0.25"
+ seta hud_panel_scoreboard_table_highlight_alpha_eliminated "0.5"
  seta hud_panel_scoreboard_bg_teams_color_team "0.7"
  seta hud_panel_scoreboard_accuracy_doublerows "1"
  seta hud_panel_scoreboard_accuracy_nocolors "0"
 +seta hud_panel_scoreboard_itemstats_doublerows "0"
  
  seta hud_panel_strafehud_pos "0.360000 0.570000"
  seta hud_panel_strafehud_size "0.280000 0.025000"
index 3f0db5526235c9bc7ddc980bad18d86b69c5e58f,9965d58fb4ed257d341596517b046a33be301e48..82f96d02d55e60dbd89a603a551d2f4002addb9a
@@@ -13,7 -13,6 +13,7 @@@
  #include <common/scores.qh>
  #include <common/stats.qh>
  #include <common/teams.qh>
 +#include <common/items/inventory.qh>
  
  // Scoreboard (#24)
  
@@@ -30,6 -29,7 +30,7 @@@ void Scoreboard_Draw_Export(int fh
        HUD_Write_Cvar("hud_panel_scoreboard_table_highlight");
        HUD_Write_Cvar("hud_panel_scoreboard_table_highlight_alpha");
        HUD_Write_Cvar("hud_panel_scoreboard_table_highlight_alpha_self");
+       HUD_Write_Cvar("hud_panel_scoreboard_table_highlight_alpha_eliminated");
        HUD_Write_Cvar("hud_panel_scoreboard_bg_teams_color_team");
        HUD_Write_Cvar("hud_panel_scoreboard_accuracy_doublerows");
        HUD_Write_Cvar("hud_panel_scoreboard_accuracy_nocolors");
@@@ -52,6 -52,7 +53,7 @@@ float sbt_fg_alpha_self
  bool sbt_highlight;
  float sbt_highlight_alpha;
  float sbt_highlight_alpha_self;
+ float sbt_highlight_alpha_eliminated;
  
  // provide basic panel cvars to old clients
  // TODO remove them after a future release (0.8.2+)
@@@ -74,6 -75,7 +76,7 @@@ float autocvar_hud_panel_scoreboard_tab
  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_table_highlight_alpha_eliminated = 0.6;
  float autocvar_hud_panel_scoreboard_bg_teams_color_team = 0;
  float autocvar_hud_panel_scoreboard_namesize = 15;
  float autocvar_hud_panel_scoreboard_team_size_position = 0;
@@@ -84,12 -86,6 +87,12 @@@ bool autocvar_hud_panel_scoreboard_accu
  float autocvar_hud_panel_scoreboard_accuracy_showdelay = 2;
  float autocvar_hud_panel_scoreboard_accuracy_showdelay_minpos = 0.75;
  
 +bool autocvar_hud_panel_scoreboard_itemstats = true;
 +bool autocvar_hud_panel_scoreboard_itemstats_doublerows = false;
 +bool autocvar_hud_panel_scoreboard_itemstats_filter = true;
 +float autocvar_hud_panel_scoreboard_itemstats_showdelay = 2.2; // slightly more delayed than accuracy
 +float autocvar_hud_panel_scoreboard_itemstats_showdelay_minpos = 0.75;
 +
  bool autocvar_hud_panel_scoreboard_dynamichud = false;
  
  float autocvar_hud_panel_scoreboard_maxheight = 0.6;
@@@ -97,6 -93,9 +100,9 @@@ bool autocvar_hud_panel_scoreboard_othe
  bool autocvar_hud_panel_scoreboard_spectators_showping = true;
  bool autocvar_hud_panel_scoreboard_spectators_aligned = false;
  float autocvar_hud_panel_scoreboard_minwidth = 0.4;
+ bool autocvar_hud_panel_scoreboard_playerid = false;
+ string autocvar_hud_panel_scoreboard_playerid_prefix = "#";
+ string autocvar_hud_panel_scoreboard_playerid_suffix = " ";
  
  // mode 0: returns translated label
  // mode 1: prints name and description of all the labels
@@@ -575,6 -574,13 +581,13 @@@ LABEL(found
        sbt_field[sbt_num_fields] = SP_END;
  }
  
+ string Scoreboard_AddPlayerId(string pl_name, entity pl)
+ {
+       string pref = autocvar_hud_panel_scoreboard_playerid_prefix;
+       string suf = autocvar_hud_panel_scoreboard_playerid_suffix;
+       return strcat(pref, itos(pl.sv_entnum + 1), suf, pl_name);
+ }
  // MOVEUP::
  vector sbt_field_rgb;
  string sbt_field_icon0;
@@@ -643,7 -649,10 +656,10 @@@ string Scoreboard_GetField(entity pl, P
                        return str;
  
                case SP_NAME:
-                       return Scoreboard_GetName(pl);
+                       str = Scoreboard_GetName(pl);
+                       if (autocvar_hud_panel_scoreboard_playerid)
+                               str = Scoreboard_AddPlayerId(str, pl);
+                       return str;
  
                case SP_FRAGS:
                        f = pl.(scores(SP_KILLS));
@@@ -940,7 -949,7 +956,7 @@@ void Scoreboard_DrawItem(vector item_po
        }
  
        if(pl.eliminated)
-               drawfill(h_pos, h_size, '0 0 0', 0.5 * panel_fg_alpha, DRAWFLAG_NORMAL);
+               drawfill(h_pos, h_size, '0 0 0', sbt_highlight_alpha_eliminated, DRAWFLAG_NORMAL);
  }
  
  vector Scoreboard_DrawOthers(vector item_pos, vector rgb, int this_team, entity ignored_pl, entity pl, int pl_number)
                else if(autocvar_hud_panel_scoreboard_others_showscore)
                        field = Scoreboard_GetField(pl, SP_SCORE);
  
-               string str = textShortenToWidth(entcs_GetName(pl.sv_entnum), namesize, hud_fontsize, stringwidth_colors);
+               string str = entcs_GetName(pl.sv_entnum);
+               if (autocvar_hud_panel_scoreboard_playerid)
+                       str = Scoreboard_AddPlayerId(str, pl);
+               str = textShortenToWidth(str, namesize, hud_fontsize, stringwidth_colors);
                float column_width = stringwidth(str, true, hud_fontsize);
                if((this_team == NUM_SPECTATOR) && autocvar_hud_panel_scoreboard_spectators_aligned)
                {
                {
                        h_size.x = column_width + hud_fontsize.x * 0.25;
                        h_size.y = hud_fontsize.y;
-                       drawfill(pos - hud_fontsize.x * 0.25 * eX, h_size, '0 0 0', 0.5 * panel_fg_alpha, DRAWFLAG_NORMAL);
+                       drawfill(pos - hud_fontsize.x * 0.25 * eX, h_size, '0 0 0', sbt_highlight_alpha_eliminated, DRAWFLAG_NORMAL);
                }
                pos.x += column_width;
                pos.x += hud_fontsize.x;
@@@ -1076,7 -1088,7 +1095,7 @@@ vector Scoreboard_MakeTable(vector pos
        panel_size.y += panel_bg_padding * 2;
        HUD_Panel_DrawBg();
  
 -      vector end_pos = panel_pos + eY * (panel_size.y + 0.5* hud_fontsize.y);
 +      vector end_pos = panel_pos + eY * (panel_size.y + 0.5 * hud_fontsize.y);
        if(panel.current_panel_bg != "0")
                end_pos.y += panel_bg_border * 2;
  
@@@ -1166,7 -1178,14 +1185,7 @@@ bool Scoreboard_WouldDraw(
  float average_accuracy;
  vector Scoreboard_AccuracyStats_Draw(vector pos, vector rgb, vector bg_size)
  {
 -      if (frametime)
 -      {
 -              if (scoreboard_fade_alpha == 1)
 -                      scoreboard_acc_fade_alpha = min(1, scoreboard_acc_fade_alpha + frametime * 10);
 -              else
 -                      scoreboard_acc_fade_alpha = 1; // sync fading with the scoreboard
 -      }
 -      vector initial_pos = pos;
 +      scoreboard_acc_fade_alpha = min(scoreboard_fade_alpha, scoreboard_acc_fade_alpha + frametime * 10);
  
        WepSet weapons_stat = WepSet_GetFromStat();
        WepSet weapons_inmap = WepSet_GetFromStat_InMap();
        HUD_Panel_DrawBg();
        panel_bg_alpha = panel_bg_alpha_save;
  
 -      vector end_pos = panel_pos + eY * (panel_size.y + hud_fontsize.y);
 +      vector end_pos = panel_pos + eY * (panel_size.y + 0.5 * hud_fontsize.y);
        if(panel.current_panel_bg != "0")
                end_pos.y += panel_bg_border * 2;
  
  
        panel_size.x += panel_bg_padding * 2; // restore initial width
  
 -      if (scoreboard_acc_fade_alpha == 1)
 -              return end_pos;
 -      return initial_pos + (end_pos - initial_pos) * scoreboard_acc_fade_alpha;
 +      return end_pos;
 +}
 +
 +.bool uninteresting;
 +STATIC_INIT(default_order_items_label)
 +{
 +      IL_EACH(default_order_items, true, {
 +              if(!(it.instanceOfPowerup
 +                      || it == ITEM_HealthMega || it == ITEM_HealthBig
 +                      || it == ITEM_ArmorMega || it == ITEM_ArmorBig
 +                      ))
 +              {
 +                      it.uninteresting = true;
 +              }
 +      });
 +}
 +
 +vector Scoreboard_ItemStats_Draw(vector pos, vector rgb, vector bg_size)
 +{
 +      scoreboard_itemstats_fade_alpha = min(scoreboard_fade_alpha, scoreboard_itemstats_fade_alpha + frametime * 10);
 +
 +      int disowned_cnt = 0;
 +      int uninteresting_cnt = 0;
 +      IL_EACH(default_order_items, true, {
 +              int q = g_inventory.inv_items[it.m_id];
 +              //q = 1; // debug: display all items
 +              if (autocvar_hud_panel_scoreboard_itemstats_filter && it.uninteresting)
 +                      ++uninteresting_cnt;
 +              else if (!q)
 +                      ++disowned_cnt;
 +      });
 +      int items_cnt = REGISTRY_COUNT(Items) - uninteresting_cnt;
 +      int n = items_cnt - disowned_cnt;
 +      if (n <= 0) return pos;
 +
 +      int rows = (autocvar_hud_panel_scoreboard_itemstats_doublerows && n >= floor(REGISTRY_COUNT(Items) / 2)) ? 2 : 1;
 +      int columnns = max(6, ceil(n / rows));
 +
 +      float height = 40;
 +      float fontsize = height * 1/3;
 +      float item_height = height * 2/3;
 +
 +      drawstring(pos + eX * panel_bg_padding, _("Item stats"), hud_fontsize, '1 1 1', panel_fg_alpha * scoreboard_itemstats_fade_alpha, DRAWFLAG_NORMAL);
 +      pos.y += 1.25 * hud_fontsize.y;
 +      if(panel.current_panel_bg != "0")
 +              pos.y += panel_bg_border;
 +
 +      panel_pos = pos;
 +      panel_size.y = height * rows;
 +      panel_size.y += panel_bg_padding * 2;
 +
 +      float panel_bg_alpha_save = panel_bg_alpha;
 +      panel_bg_alpha *= scoreboard_itemstats_fade_alpha;
 +      HUD_Panel_DrawBg();
 +      panel_bg_alpha = panel_bg_alpha_save;
 +
 +      vector end_pos = panel_pos + eY * (panel_size.y + 0.5 * hud_fontsize.y);
 +      if(panel.current_panel_bg != "0")
 +              end_pos.y += panel_bg_border * 2;
 +
 +      if(panel_bg_padding)
 +      {
 +              panel_pos += '1 1 0' * panel_bg_padding;
 +              panel_size -= '2 2 0' * panel_bg_padding;
 +      }
 +
 +      pos = panel_pos;
 +      vector tmp = panel_size;
 +
 +      float item_width = tmp.x / columnns / rows;
 +
 +      if (sbt_bg_alpha)
 +              drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb, sbt_bg_alpha * scoreboard_itemstats_fade_alpha, DRAWFLAG_NORMAL);
 +
 +      if(sbt_highlight)
 +      {
 +              // column highlighting
 +              for (int i = 0; i < columnns; ++i)
 +                      if ((i % 2) == 0)
 +                              drawfill(pos + '1 0 0' * item_width * rows * i, '0 1 0' * height * rows + '1 0 0' * item_width * rows, '0 0 0', sbt_highlight_alpha * scoreboard_itemstats_fade_alpha, DRAWFLAG_NORMAL);
 +
 +              // row highlighting
 +              for (int i = 0; i < rows; ++i)
 +                      drawfill(pos + '0 1 0' * item_height + '0 1 0' * height * i, '1 0 0' * panel_size.x + '0 1 0' * fontsize, rgb, sbt_highlight_alpha * scoreboard_itemstats_fade_alpha, DRAWFLAG_NORMAL);
 +      }
 +
 +      if (rows == 2)
 +              pos.x += item_width / 2;
 +
 +      float oldposx = pos.x;
 +      vector tmpos = pos;
 +
 +      int column = 0;
 +      IL_EACH(default_order_items, !(autocvar_hud_panel_scoreboard_itemstats_filter && it.uninteresting), {
 +              int n = g_inventory.inv_items[it.m_id];
 +              //n = 1 + floor(i * 3 + 4.8) % 7; // debug: display a value for each item
 +              if (n <= 0) continue;
 +              drawpic_aspect_skin(tmpos, it.m_icon, '1 0 0' * item_width + '0 1 0' * item_height, '1 1 1', panel_fg_alpha * scoreboard_itemstats_fade_alpha, DRAWFLAG_NORMAL);
 +              string s = ftos(n);
 +              float padding = (item_width - stringwidth(s, false, '1 0 0' * fontsize)) / 2; // center
 +              drawstring(tmpos + '1 0 0' * padding + '0 1 0' * item_height, s, '1 1 0' * fontsize, '1 1 1', panel_fg_alpha * scoreboard_itemstats_fade_alpha, DRAWFLAG_NORMAL);
 +              tmpos.x += item_width * rows;
 +              pos.x += item_width * rows;
 +              if (rows == 2 && column == columnns - 1) {
 +                      tmpos.x = oldposx;
 +                      tmpos.y += height;
 +                      pos.y += height;
 +              }
 +              ++column;
 +      });
 +
 +      panel_size.x += panel_bg_padding * 2; // restore initial width
 +
 +      return end_pos;
  }
  
  vector MapStats_DrawKeyValue(vector pos, string key, string value) {
@@@ -1470,7 -1378,7 +1489,7 @@@ vector Scoreboard_MapStats_Draw(vector 
        panel_size.y += panel_bg_padding * 2;
        HUD_Panel_DrawBg();
  
 -      vector end_pos = panel_pos + eY * (panel_size.y + hud_fontsize.y);
 +      vector end_pos = panel_pos + eY * (panel_size.y + 0.5 * hud_fontsize.y);
        if(panel.current_panel_bg != "0")
                end_pos.y += panel_bg_border * 2;
  
@@@ -1556,7 -1464,7 +1575,7 @@@ vector Scoreboard_Rankings_Draw(vector 
  
        HUD_Panel_DrawBg();
  
 -      vector end_pos = panel_pos + eY * (panel_size.y + hud_fontsize.y);
 +      vector end_pos = panel_pos + eY * (panel_size.y + 0.5 * hud_fontsize.y);
        if(panel.current_panel_bg != "0")
                end_pos.y += panel_bg_border * 2;
  
@@@ -1644,42 -1552,6 +1663,42 @@@ bool Scoreboard_AccuracyStats_WouldDraw
        return true;
  }
  
 +bool have_item_stats;
 +bool Scoreboard_ItemStats_WouldDraw(float ypos)
 +{
 +      if (MUTATOR_CALLHOOK(DrawScoreboardItemStats))
 +              return false;
 +      if (!autocvar_hud_panel_scoreboard_itemstats || !g_inventory || warmup_stage || ypos > 0.91 * vid_conheight)
 +              return false;
 +
 +      if (time < scoreboard_time + autocvar_hud_panel_scoreboard_itemstats_showdelay
 +              && ypos > autocvar_hud_panel_scoreboard_itemstats_showdelay_minpos * vid_conheight
 +              && !intermission)
 +      {
 +              return false;
 +      }
 +
 +      if (!have_item_stats)
 +      {
 +              IL_EACH(default_order_items, true, {
 +                      if (!(autocvar_hud_panel_scoreboard_itemstats_filter && it.uninteresting))
 +                      {
 +                              int q = g_inventory.inv_items[it.m_id];
 +                              //q = 1; // debug: display all items
 +                              if (q)
 +                              {
 +                                      have_item_stats = true;
 +                                      break;
 +                              }
 +                      }
 +              });
 +              if (!have_item_stats)
 +                      return false;
 +      }
 +
 +      return true;
 +}
 +
  void Scoreboard_Draw()
  {
        if(!autocvar__hud_configure)
  
                // frametime checks allow to toggle the scoreboard even when the game is paused
                if(scoreboard_active) {
 -                      if (scoreboard_fade_alpha < 1)
 +                      if (scoreboard_fade_alpha == 0)
                                scoreboard_time = time;
                        if(hud_configure_menu_open == 1)
                                scoreboard_fade_alpha = 1;
                if (!scoreboard_fade_alpha)
                {
                        scoreboard_acc_fade_alpha = 0;
 +                      scoreboard_itemstats_fade_alpha = 0;
                        return;
                }
        }
        sbt_highlight = autocvar_hud_panel_scoreboard_table_highlight;
        sbt_highlight_alpha = autocvar_hud_panel_scoreboard_table_highlight_alpha * panel_fg_alpha;
        sbt_highlight_alpha_self = autocvar_hud_panel_scoreboard_table_highlight_alpha_self * panel_fg_alpha;
+       sbt_highlight_alpha_eliminated = autocvar_hud_panel_scoreboard_table_highlight_alpha_eliminated * panel_fg_alpha;
        sbt_fg_alpha = autocvar_hud_panel_scoreboard_table_fg_alpha * panel_fg_alpha;
        sbt_fg_alpha_self = autocvar_hud_panel_scoreboard_table_fg_alpha_self * panel_fg_alpha;
  
  
        Scoreboard_UpdatePlayerTeams();
  
 +      float initial_pos_y = panel_pos.y;
        vector pos = panel_pos;
        entity pl, tm;
        string str;
  
        if (Scoreboard_AccuracyStats_WouldDraw(pos.y))
                pos = Scoreboard_AccuracyStats_Draw(pos, panel_bg_color, bg_size);
 +      if (Scoreboard_ItemStats_WouldDraw(pos.y))
 +              pos = Scoreboard_ItemStats_Draw(pos, panel_bg_color, bg_size);
  
        if(MUTATOR_CALLHOOK(ShowRankings)) {
                string ranktitle = M_ARGV(0, string);
                drawcolorcodedstring(pos + '0.5 0 0' * (panel_size.x - stringwidth(str, true, hud_fontsize)), str, hud_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
        }
  
 -      scoreboard_bottom = pos.y + 2 * hud_fontsize.y;
 +      pos.y += 2 * hud_fontsize.y;
 +      if (scoreboard_fade_alpha < 1)
 +              scoreboard_bottom = initial_pos_y + (pos.y - initial_pos_y) * scoreboard_fade_alpha;
 +      else if (pos.y != scoreboard_bottom)
 +      {
 +              if (pos.y > scoreboard_bottom)
 +                      scoreboard_bottom = min(pos.y, scoreboard_bottom + frametime * 10 * (pos.y - initial_pos_y));
 +              else
 +                      scoreboard_bottom = max(pos.y, scoreboard_bottom - frametime * 10 * (pos.y - initial_pos_y));
 +      }
  }
diff --combined qcsrc/common/state.qc
index 3060a51aa5f40e29c5af984bad43d96b92bf702b,651a86f917f5a83ead5c6517070b05bd6be1cd4c..018f626e0318bcf02dee8807f08260afd1262158
@@@ -4,9 -4,8 +4,9 @@@
  
  void Inventory_new(PlayerState this);
  void Inventory_delete(entity this);
 +void Inventory_clear(PlayerState this);
  void InventoryStorage_attach(PlayerState this);
 -void InventoryStorage_detach(PlayerState this);
 +void InventoryStorage_delete(PlayerState this);
  
  void PlayerState_attach(entity this)
  {
@@@ -23,7 -22,6 +23,7 @@@ void PlayerState_detach(entity this
      PlayerState ps = PS(this);
        if (!ps) return;  // initial connect
        PS(this) = NULL;
 +    Inventory_clear(this.inventory_store); // no need to network updates, as there is no inventory attached
  
        if (ps.m_client != this) return;  // don't own state, spectator
        ps.ps_push(ps, this);
@@@ -70,13 -68,13 +70,13 @@@ void PlayerScore_Detach(entity this)
  
  void ClientState_detach(entity this)
  {
-     GetCvars(this, CS(this), -1);  // free cvars TODO: is this still needed now that it's stored on the clientstate entity?
+     GetCvars(this, CS_CVAR(this), -1);  // free cvars TODO: is this still needed now that it's stored on the clientstate entity?
      accuracy_free(this); // TODO: needs to be before CS() is deleted!
      PlayerScore_Detach(this); // what ^they^ said
      W_HitPlotClose(this);
      ClientData_Detach(this);
      entcs_detach(this);
 -    InventoryStorage_detach(this);
 +    InventoryStorage_delete(this);
        delete(CS(this));
        this._cs = NULL;