]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into terencehill/scoreboard_item_stats
authorMario <mario.mario@y7mail.com>
Sun, 18 Oct 2020 23:55:38 +0000 (09:55 +1000)
committerMario <mario.mario@y7mail.com>
Sun, 18 Oct 2020 23:55:38 +0000 (09:55 +1000)
qcsrc/client/hud/panel/scoreboard.qc
qcsrc/common/items/inventory.qh

index 7f3c8e5c28a3596d424a39d074d93eff89a96333..c474ad33b8c0b2cb4f8dc574e479bab745bac3e1 100644 (file)
@@ -13,6 +13,7 @@
 #include <common/scores.qh>
 #include <common/stats.qh>
 #include <common/teams.qh>
+#include <common/items/inventory.qh>
 
 // Scoreboard (#24)
 
@@ -1312,6 +1313,107 @@ vector Scoreboard_AccuracyStats_Draw(vector pos, vector rgb, vector bg_size)
        return initial_pos + (end_pos - initial_pos) * scoreboard_acc_fade_alpha;
 }
 
+vector Scoreboard_ItemStats_Draw(vector pos, vector rgb, vector bg_size)
+{
+       float scoreboard_acc_fade_alpha_save = scoreboard_acc_fade_alpha; // debug
+       scoreboard_acc_fade_alpha = 1; // debug: make Item Stats always visible
+
+       float initial_posx = pos.x;
+       int disownedcnt = 0;
+       FOREACH(Items, true, {
+               int q = g_inventory.inv_items[it.m_id];
+               //q = 1; // debug: display all items
+               if (!q) ++disownedcnt;
+       });
+
+       int n = Items_COUNT - disownedcnt;
+       if (n <= 0) return pos;
+
+       int rows = (autocvar_hud_panel_scoreboard_accuracy_doublerows && n >= floor(Items_COUNT / 2)) ? 2 : 1;
+       int columnns = ceil(n / rows);
+
+       float height = 40;
+       float fontsize = height * 1/3;
+       float item_height = height * 2/3;
+
+       drawstring(pos, _("Item stats"), hud_fontsize, '1 1 1', panel_fg_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_acc_fade_alpha;
+       HUD_Panel_DrawBg();
+       panel_bg_alpha = panel_bg_alpha_save;
+
+       vector end_pos = panel_pos + eY * (panel_size.y + 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_acc_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', panel_bg_alpha * 0.2, 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, '1 1 1', sbt_highlight_alpha, DRAWFLAG_NORMAL);
+       }
+
+       if (rows == 2)
+               pos.x += item_width / 2;
+
+       float oldposx = pos.x;
+       vector tmpos = pos;
+
+       int column = 0;
+       FOREACH(Items, true, {
+               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, 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, 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;
+       });
+       pos.y += height;
+       pos.y += 1.25 * hud_fontsize.y;
+       pos.x = initial_posx;
+
+       panel_size.x += panel_bg_padding * 2; // restore initial width
+
+       scoreboard_acc_fade_alpha = scoreboard_acc_fade_alpha_save; // debug
+       return pos;
+}
+
 vector MapStats_DrawKeyValue(vector pos, string key, string value) {
        float px = pos.x;
        pos.x += hud_fontsize.x * 0.25;
@@ -1815,6 +1917,7 @@ void Scoreboard_Draw()
 
        if (Scoreboard_AccuracyStats_WouldDraw(pos.y))
                pos = Scoreboard_AccuracyStats_Draw(pos, panel_bg_color, bg_size);
+       pos = Scoreboard_ItemStats_Draw(pos, panel_bg_color, bg_size);
 
        if(MUTATOR_CALLHOOK(ShowRankings)) {
                string ranktitle = M_ARGV(0, string);
index c47be669978bb90b00afa5724297fc7d21c48544..cc17571ecc91bee3d94f401d7fec2a12457a29aa 100644 (file)
@@ -5,7 +5,7 @@
 #ifdef GAMEQC
 CLASS(Inventory, Object)
     /** Stores counts of items, the id being the index */
-    ATTRIBARRAY(Inventory, inv_items, int, REGISTRY_MAX(Items));
+    ATTRIBARRAY(Inventory, inv_items, int, Items_MAX);
 ENDCLASS(Inventory)
 
 /** Player inventory */
@@ -15,23 +15,9 @@ ENDCLASS(Inventory)
 
 REGISTER_NET_LINKED(ENT_CLIENT_INVENTORY)
 
-const int Inventory_groups_minor = 8; // must be a multiple of 8 (one byte) to optimize bandwidth usage
-const int Inventory_groups_major = 4; // must be >= ceil(REGISTRY_COUNT(Items) / Inventory_groups_minor)
-#endif
+const int Inventory_groups_major = 16;
+const int Inventory_groups_minor = 8; // ceil(Items_MAX / Inventory_groups_major)
 
-// no need to perform these checks on both server and client
-#ifdef CSQC
-STATIC_INIT(Inventory)
-{
-       if (Inventory_groups_minor / 8 != floor(Inventory_groups_minor / 8))
-               error("Inventory_groups_minor is not a multiple of 8.");
-       int min_major_value = ceil(REGISTRY_COUNT(Items) / Inventory_groups_minor);
-       if (Inventory_groups_major < min_major_value)
-               error(sprintf("Inventory_groups_major can not be < %d.", min_major_value));
-}
-#endif
-
-#ifdef SVQC
 #define G_MAJOR(id) (floor((id) / Inventory_groups_minor))
 #define G_MINOR(id) ((id) % Inventory_groups_minor)
 #endif
@@ -42,21 +28,21 @@ NET_HANDLE(ENT_CLIENT_INVENTORY, bool isnew)
 {
     make_pure(this);
     g_inventory = this;
-    const int majorBits = Readbits(Inventory_groups_major);
+    const int majorBits = ReadShort();
     for (int i = 0; i < Inventory_groups_major; ++i) {
         if (!(majorBits & BIT(i))) {
             continue;
         }
-        const int minorBits = Readbits(Inventory_groups_minor);
+        const int minorBits = ReadByte();
         for (int j = 0; j < Inventory_groups_minor; ++j) {
             if (!(minorBits & BIT(j))) {
                 continue;
             }
-            const GameItem it = REGISTRY_GET(Items, Inventory_groups_minor * i + j);
+            const GameItem it = Items_from(Inventory_groups_minor * i + j);
             .int fld = inv_items[it.m_id];
             int prev = this.(fld);
             int next = this.(fld) = ReadByte();
-            LOG_DEBUGF("%s: %.0f -> %.0f", it.m_name, prev, next);
+            LOG_TRACEF("%s: %.0f -> %.0f", it.m_name, prev, next);
         }
     }
     return true;
@@ -87,21 +73,21 @@ void Inventory_Write(Inventory data, Inventory store)
                        minorBitsArr[maj] = BITSET(minorBitsArr[maj], BIT(G_MINOR(it.m_id)), true);
         }
     });
+    WriteShort(MSG_ENTITY, majorBits);
 
-       Writebits(MSG_ENTITY, majorBits, Inventory_groups_major);
        for (int i = 0; i < Inventory_groups_major; ++i)
        {
                if (!(majorBits & BIT(i)))
                        continue;
 
                const int minorBits = minorBitsArr[i];
-               Writebits(MSG_ENTITY, minorBits, Inventory_groups_minor);
+               WriteByte(MSG_ENTITY, minorBits);
                for (int j = 0; j < Inventory_groups_minor; ++j)
                {
                        if (!(minorBits & BIT(j)))
                                continue;
 
-                       const entity it = REGISTRY_GET(Items, Inventory_groups_minor * i + j);
+                       const entity it = Items_from(Inventory_groups_minor * i + j);
                        WriteByte(MSG_ENTITY, data.inv_items[it.m_id]);
                }
        }
@@ -133,7 +119,7 @@ void Inventory_new(PlayerState this)
     setcefc(inv, Inventory_customize);
     Net_LinkEntity((inv.owner = this).inventory = inv, false, 0, Inventory_Send);
 }
-void Inventory_delete(entity e) { delete(e.inventory.inventory); delete(e.inventory); }
+void Inventory_delete(entity e) { delete(e.inventory); }
 void Inventory_update(entity e) { e.inventory.SendFlags = 0xFFFFFF; }
 
 void InventoryStorage_attach(entity e) { e.inventory_store = NEW(Inventory); e.inventory_store.drawonlytoclient = e; }