#ifdef GAMEQC
CLASS(Inventory, Object)
/** Stores counts of items, the id being the index */
- ATTRIBARRAY(Inventory, inv_items, int, Items_MAX);
+ ATTRIBARRAY(Inventory, inv_items, int, REGISTRY_MAX(Items));
ENDCLASS(Inventory)
/** Player inventory */
REGISTER_NET_LINKED(ENT_CLIENT_INVENTORY)
-const int Inventory_groups_major = 16;
-const int Inventory_groups_minor = 8; // ceil(Items_MAX / Inventory_groups_major)
+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
+// 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
{
make_pure(this);
g_inventory = this;
- const int majorBits = ReadShort();
+ const int majorBits = Readbits(Inventory_groups_major);
for (int i = 0; i < Inventory_groups_major; ++i) {
if (!(majorBits & BIT(i))) {
continue;
}
- const int minorBits = ReadByte();
+ const int minorBits = Readbits(Inventory_groups_minor);
for (int j = 0; j < Inventory_groups_minor; ++j) {
if (!(minorBits & BIT(j))) {
continue;
}
- const GameItem it = Items_from(Inventory_groups_minor * i + j);
+ const GameItem it = REGISTRY_GET(Items, Inventory_groups_minor * i + j);
.int fld = inv_items[it.m_id];
int prev = this.(fld);
int next = this.(fld) = ReadByte();
- LOG_TRACEF("%s: %.0f -> %.0f", it.m_name, prev, next);
+ LOG_DEBUGF("%s: %.0f -> %.0f", it.m_name, prev, next);
}
}
return true;
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];
- WriteByte(MSG_ENTITY, minorBits);
+ Writebits(MSG_ENTITY, minorBits, Inventory_groups_minor);
for (int j = 0; j < Inventory_groups_minor; ++j)
{
if (!(minorBits & BIT(j)))
continue;
- const entity it = Items_from(Inventory_groups_minor * i + j);
+ const entity it = REGISTRY_GET(Items, Inventory_groups_minor * i + j);
WriteByte(MSG_ENTITY, data.inv_items[it.m_id]);
}
}
setcefc(inv, Inventory_customize);
Net_LinkEntity((inv.owner = this).inventory = inv, false, 0, Inventory_Send);
}
-void Inventory_delete(entity e) { delete(e.inventory); }
+void Inventory_delete(entity e) { delete(e.inventory.inventory); 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; }