From: TimePath Date: Wed, 13 May 2015 05:46:07 +0000 (+1000) Subject: Inventory system X-Git-Tag: xonotic-v0.8.1~53^2~4 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=98a754f2f897954b3a664c2d751d1a12a1688e42;p=xonotic%2Fxonotic-data.pk3dir.git Inventory system Counts collected items and sends them with delta compression --- diff --git a/qcsrc/client/main.qc b/qcsrc/client/main.qc index ad727bf41..0cedf8fd7 100644 --- a/qcsrc/client/main.qc +++ b/qcsrc/client/main.qc @@ -859,6 +859,7 @@ void CSQC_Ent_Update(float bIsNewEntity) case ENT_CLIENT_WARPZONE_TELEPORTED: WarpZone_Teleported_Read(bIsNewEntity); break; case ENT_CLIENT_TRIGGER_MUSIC: Ent_ReadTriggerMusic(); break; case ENT_CLIENT_HOOK: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_HOOK); break; + case ENT_CLIENT_INVENTORY: Inventory_Read(self); break; case ENT_CLIENT_ARC_BEAM: Ent_ReadArcBeam(bIsNewEntity); break; case ENT_CLIENT_ACCURACY: Ent_ReadAccuracy(); break; case ENT_CLIENT_AUXILIARYXHAIR: Net_AuXair2(bIsNewEntity); break; diff --git a/qcsrc/common/constants.qh b/qcsrc/common/constants.qh index 45a65abbe..8c7cb6b3a 100644 --- a/qcsrc/common/constants.qh +++ b/qcsrc/common/constants.qh @@ -64,6 +64,7 @@ const int ENT_CLIENT_WARPZONE = 24; const int ENT_CLIENT_WARPZONE_CAMERA = 25; const int ENT_CLIENT_TRIGGER_MUSIC = 26; const int ENT_CLIENT_HOOK = 27; +const int ENT_CLIENT_INVENTORY = 28; const int ENT_CLIENT_ARC_BEAM = 29; // WEAPONTODO: fix numbers const int ENT_CLIENT_ACCURACY = 30; const int ENT_CLIENT_SHOWNAMES = 31; diff --git a/qcsrc/common/items/all.inc b/qcsrc/common/items/all.inc index f009bbe00..2c4f1dea4 100644 --- a/qcsrc/common/items/all.inc +++ b/qcsrc/common/items/all.inc @@ -3,4 +3,5 @@ #include "item/buff.qc" #include "item/health.qc" #include "item/jetpack.qc" +#include "item/pickup.qc" #include "item/powerup.qc" diff --git a/qcsrc/common/items/all.qh b/qcsrc/common/items/all.qh index 7290b95a9..1786b4261 100644 --- a/qcsrc/common/items/all.qh +++ b/qcsrc/common/items/all.qh @@ -1,12 +1,12 @@ #ifndef ALL_H #define ALL_H -const int MAX_ITEMS = 23; +const int MAX_ITEMS = 24; entity ITEMS[MAX_ITEMS]; #define ITEMS_FOREACH(pred, body) do { \ for (int i = 0; i < ITEM_COUNT; i++) { \ - const entity it = ITEMS[i]; \ + const noref entity it = ITEMS[i]; \ if (pred) { body } \ } \ } while(0) @@ -14,25 +14,6 @@ entity ITEMS[MAX_ITEMS]; void RegisterItems(); void Dump_Items(); -#ifdef CSQC -void ReadItems() -{ -/* - const int flags = read(); - for (int i = 0; i < MAX_ITEMS; i++) { - if (flags & BIT(i)) { - self.items[i] = read(); - } - } -*/ -} #endif -#ifdef SVQC -void WriteItems() -{ - -} -#endif - -#endif +#include "inventory.qh" diff --git a/qcsrc/common/items/inventory.qh b/qcsrc/common/items/inventory.qh new file mode 100644 index 000000000..9b277bf67 --- /dev/null +++ b/qcsrc/common/items/inventory.qh @@ -0,0 +1,64 @@ +#ifndef INVENTORY_H +#define INVENTORY_H + +#include "all.qh" +#include "item/pickup.qh" + +entityclass(Inventory); +/** Stores counts of items, the id being the index */ +class(Inventory) .int inv_items[MAX_ITEMS]; + +/** Player inventory; Inventories also have one inventory for storing the previous state */ +.Inventory inventory; + +#ifdef CSQC +void Inventory_Read(Inventory data) +{ + const int bits = ReadInt24_t(); + ITEMS_FOREACH(bits & BIT(i), LAMBDA({ + int prev = data.inv_items[i]; + int next = data.inv_items[i] = ReadByte(); + dprintf("%s: %.0f -> %.0f\n", ITEMS[i].m_name, prev, next); + })); +} +#endif + +#ifdef SVQC +void Inventory_Write(Inventory data) +{ + int bits = 0; + ITEMS_FOREACH(true, LAMBDA({ + .int idx = inv_items[i]; + bits = BITSET(bits, BIT(i), data.inventory.(idx) != (data.inventory.(idx) = data.(idx))); + })); + WriteInt24_t(MSG_ENTITY, bits); + ITEMS_FOREACH(bits & BIT(i), LAMBDA({ + WriteByte(MSG_ENTITY, data.inv_items[i]); + })); +} +#endif + +#ifdef SVQC +bool Inventory_Send(entity to, int sf) +{ + WriteByte(MSG_ENTITY, ENT_CLIENT_INVENTORY); + entity e = self.owner; + if (IS_SPEC(e)) e = e.enemy; + Inventory data = e.inventory; + Inventory_Write(data); + return true; +} + +void Inventory_new(entity e) +{ + Inventory inv = new(Inventory), bak = new(Inventory); + inv.classname = "inventory", bak.classname = "inventory"; + inv.inventory = bak; + inv.drawonlytoclient = e; + Net_LinkEntity((inv.owner = e).inventory = inv, false, 0, Inventory_Send); +} +void Inventory_delete(entity e) { remove(e.inventory.inventory); remove(e.inventory); } +void Inventory_update(entity e) { e.inventory.SendFlags = 0xFFFFFF; } +#endif + +#endif diff --git a/qcsrc/common/items/item.qh b/qcsrc/common/items/item.qh index 6ca131418..da4e7a453 100644 --- a/qcsrc/common/items/item.qh +++ b/qcsrc/common/items/item.qh @@ -3,6 +3,7 @@ #include "../oo.qh" #define ITEM_HANDLE(signal, ...) __Item_Send_##signal(__VA_ARGS__) CLASS(GameItem, Object) + ATTRIB(GameItem, m_id, int, 0) METHOD(GameItem, show, void(entity this)) void GameItem_show(entity this) { print("A game item\n"); } void ITEM_HANDLE(Show, entity this) { this.show(this); } @@ -15,6 +16,7 @@ int ITEM_COUNT; void RegisterItems_##id() { \ const entity this = NEW(class); \ ITEM_##id = this; \ + this.m_id = ITEM_COUNT; \ ITEMS[ITEM_COUNT++] = this; \ body \ } \ diff --git a/qcsrc/common/items/item/pickup.qc b/qcsrc/common/items/item/pickup.qc new file mode 100644 index 000000000..35aac2bff --- /dev/null +++ b/qcsrc/common/items/item/pickup.qc @@ -0,0 +1,13 @@ +#include "pickup.qh" + +#ifdef SVQC +bool ITEM_HANDLE(Pickup, entity this, entity item, entity player) { + bool b = this.giveTo(this, item, player); + if (b) { + dprintf("entity %i picked up %s\n", player, this.m_name); + player.inventory.inv_items[this.m_id]++; + Inventory_update(player); + } + return b; +} +#endif diff --git a/qcsrc/common/items/item/pickup.qh b/qcsrc/common/items/item/pickup.qh index 47788f3aa..1875517f1 100644 --- a/qcsrc/common/items/item/pickup.qh +++ b/qcsrc/common/items/item/pickup.qh @@ -16,7 +16,7 @@ CLASS(Pickup, GameItem) ATTRIB(Pickup, m_respawntimejitter, float(), func_null) METHOD(Pickup, giveTo, bool(entity this, entity item, entity player)) bool Pickup_giveTo(entity this, entity item, entity player) { return Item_GiveTo(item, player); } - bool ITEM_HANDLE(Pickup, entity this, entity item, entity player) { printf("%s picked up %s\n", etos(player), this.m_name); return this.giveTo(this, item, player); } + bool ITEM_HANDLE(Pickup, entity this, entity item, entity player); #endif ENDCLASS(Pickup) diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index 259b7e260..b73eebbf4 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -35,6 +35,8 @@ #include "../common/net_notice.qh" +#include "../common/items/inventory.qh" + #include "../common/monsters/sv_monsters.qh" #include "../warpzonelib/server.qh" @@ -1096,6 +1098,7 @@ void ClientConnect (void) PlayerScore_Attach(self); ClientData_Attach(); accuracy_init(self); + Inventory_new(self); bot_clientconnect(); @@ -1338,6 +1341,7 @@ void ClientDisconnect (void) bot_relinkplayerlist(); accuracy_free(self); + Inventory_delete(self); ClientData_Detach(); PlayerScore_Detach(self); diff --git a/qcsrc/server/miscfunctions.qc b/qcsrc/server/miscfunctions.qc index 41f388ed5..5f663ccdc 100644 --- a/qcsrc/server/miscfunctions.qc +++ b/qcsrc/server/miscfunctions.qc @@ -1270,7 +1270,7 @@ void SetCustomizer(entity e, float(void) customizer, void(void) uncustomizer) } -void Net_LinkEntity(entity e, float docull, float dt, bool(entity, int) sendfunc) +void Net_LinkEntity(entity e, bool docull, float dt, bool(entity, int) sendfunc) { vector mi, ma; diff --git a/qcsrc/server/miscfunctions.qh b/qcsrc/server/miscfunctions.qh index a8a9117d5..3acc88360 100644 --- a/qcsrc/server/miscfunctions.qh +++ b/qcsrc/server/miscfunctions.qh @@ -468,6 +468,6 @@ entity initialize_entity_first; float sound_allowed(float dest, entity e); void InitializeEntity(entity e, void(void) func, float order); void SetCustomizer(entity e, float(void) customizer, void(void) uncustomizer); -void Net_LinkEntity(entity e, float docull, float dt, float(entity, float) sendfunc); +void Net_LinkEntity(entity e, bool docull, float dt, bool(entity, int) sendfunc); #endif