From 14b3ea76760886aaaf080ca9d68ca67fa9ed52d7 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Sat, 4 Jan 2025 13:32:26 -0500 Subject: [PATCH] Inventory system is mostly working and I can pick up everything and use it. --- assets/items.json | 6 +++--- gui.cpp | 30 +++++++++++++----------------- gui.hpp | 1 + inventory.cpp | 34 +++++++++++++++++----------------- inventory.hpp | 8 ++++---- main.cpp | 10 +++++++++- systems.cpp | 4 ++++ tests/inventory.cpp | 10 +++++----- 8 files changed, 56 insertions(+), 47 deletions(-) diff --git a/assets/items.json b/assets/items.json index bd1585b..04d5137 100644 --- a/assets/items.json +++ b/assets/items.json @@ -4,7 +4,7 @@ "name": "Crappy Torch", "foreground": [24, 205, 189], "background": [230, 20, 120], - "description": "Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. Summus brains sit​​, morbo vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris. Hi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium.", + "description": "A torch that barely lights the way. You wonder if it'd be better to not see the person who murders you.", "display": "\u0f08" }, "SWORD_RUSTY": { @@ -12,7 +12,7 @@ "name": "Rusty Junk Sword", "foreground": [24, 205, 189], "background": [24, 205, 189], - "description": "Shoreditch pickled readymade tousled tumeric. Chicharrones same jawn irony woke echo park jianbing artisan ethical praxis grailed portland. Banjo solarpunk yes plz, offal Brooklyn beard bushwick letterpress celiac sartorial.", + "description": "A sword left to rot in a deep hole where it acquired a patina of dirt and tetanus. You aren't sure if it's more deadly for you to hold it or for the people you stab with it.", "display":"\u1e37" }, "CHEST_SMALL": { @@ -21,7 +21,7 @@ "foreground": [24, 205, 189], "background": [24, 205, 189], "display":"\uaaea", - "description": "Tote bag sustainable crucifix gentrify kombucha. Try-hard single-origin coffee meh pork belly cliche aesthetic scenester disrupt banjo af." + "description": "A small chest of gold. You wonder who would leave something like this around." }, "WALL_TORCH": { "id": "WALL_TORCH", diff --git a/gui.cpp b/gui.cpp index 314e466..2d7057b 100644 --- a/gui.cpp +++ b/gui.cpp @@ -31,14 +31,14 @@ using namespace ftxui; using namespace components; void InventoryUI::create_render() { - auto inventory_render = Renderer([&] { + MenuOption option; + $inventory_box = Menu(&$menu_list, &$selected, option); + + $inventory_render = Renderer([&] { auto &player = $world.get_the(); auto &inventory = $world.get(player.entity); update_menu_list(inventory); - MenuOption option; - $inventory_box = Menu(&$menu_list, &$selected, option); - return hbox({ $inventory_box->Render() | frame | size(WIDTH, EQUAL, 35) | yflex_grow, separator() | yflex_grow, @@ -48,26 +48,22 @@ void InventoryUI::create_render() { }) | border | flex; }); - set_renderer(inventory_render); + set_renderer($inventory_render); + add($inventory_box); } void InventoryUI::update_menu_list(Inventory& inventory) { - // BUG: probably need to have a dirty marker on inventory - // so we don't update this all the damn time $menu_list.clear(); - int i = 0; // SOOOOO BADDDDD - for(auto& [key, val] : inventory.items) { + for(size_t i = 0; i < inventory.count(); i++) { + auto& item = inventory.get(i); $menu_list.push_back(fmt::format("{} {} ({})", - string(val.data["display"]), - string(val.data["name"]), - val.count)); + string(item.data["display"]), + string(item.data["name"]), + item.count)); - // GARBAGE HOT - if($selected == i) { - $item_text = val.data["description"]; + if($selected == int(i)) { + $item_text = item.data["description"]; } - - i++; } } diff --git a/gui.hpp b/gui.hpp index 317bb13..9a727fd 100644 --- a/gui.hpp +++ b/gui.hpp @@ -53,6 +53,7 @@ class InventoryUI : public Panel { int $selected = 0; Component $inventory_box; + Component $inventory_render; Component $inventory_table; DinkyECS::World& $world; std::vector $menu_list; diff --git a/inventory.cpp b/inventory.cpp index 7b2fb4e..da5655d 100644 --- a/inventory.cpp +++ b/inventory.cpp @@ -2,31 +2,31 @@ namespace components { - void Inventory::add(InventoryItem item) { - std::string id = item.data["id"]; - - if(items.contains(id)) { - auto &slot = items[id]; - slot.count += item.count; - } else { - items[id] = item; + void Inventory::add(InventoryItem new_item) { + for(auto &slot : items) { + if(new_item.data["id"] == slot.data["id"]) { + slot.count += new_item.count; + return; + } } + + items.push_back(new_item); } - InventoryItem& Inventory::get(std::string id) { - dbc::check(items.contains(id), fmt::format("item id {} is not in inventory", id)); - return items[id]; + InventoryItem& Inventory::get(size_t at) { + dbc::check(at < items.size(), fmt::format("inventory index {} too big", at)); + return items[at]; } - bool Inventory::decrease(std::string id, int count) { - dbc::check(items.contains(id), fmt::format("item id {} is not in inventory", id)); - auto &slot = items[id]; + bool Inventory::decrease(size_t at, int count) { + dbc::check(at < items.size(), fmt::format("inventory index {} too big", at)); + auto &slot = items[at]; slot.count -= count; return slot.count > 0; } - void Inventory::remove_all(std::string id) { - dbc::check(items.contains(id), fmt::format("item id {} is not in inventory", id)); - items.erase(id); + void Inventory::erase_item(size_t at) { + dbc::check(at < items.size(), fmt::format("inventory index {} too big", at)); + items.erase(items.begin() + at); } } diff --git a/inventory.hpp b/inventory.hpp index 4d90fd3..9a0acae 100644 --- a/inventory.hpp +++ b/inventory.hpp @@ -16,16 +16,16 @@ namespace components { struct Inventory { int gold; LightSource light; - std::unordered_map items; + std::vector items; size_t count() { return items.size(); } void add(InventoryItem item); - bool decrease(std::string id, int count); + bool decrease(size_t at, int count); - InventoryItem& get(std::string id); + InventoryItem& get(size_t at); - void remove_all(std::string id); + void erase_item(size_t at); }; } diff --git a/main.cpp b/main.cpp index 000aa58..b1f8681 100644 --- a/main.cpp +++ b/main.cpp @@ -34,7 +34,7 @@ void configure_world(DinkyECS::World &world, Map &game_map) { world.set(player.entity, {0, 0}); world.set(player.entity, {100, 10}); world.set(player.entity, {config.enemies["PLAYER_TILE"]["display"]}); - world.set(player.entity, {70,1.0}); + world.set(player.entity, {50,1.0}); world.set(player.entity, {5}); auto sword = world.entity(); @@ -44,6 +44,13 @@ void configure_world(DinkyECS::World &world, Map &game_map) { world.set(sword, {1, config.items["SWORD_RUSTY"]}); world.set(sword, {20}); + auto torch = world.entity(); + pos = game_map.place_entity(2); + world.set(torch, {pos.x+1, pos.y+1}); + world.set(torch, {config.items["TORCH_BAD"]["display"]}); + world.set(torch, {1, config.items["TORCH_BAD"]}); + world.set(torch, {70,2.0f}); + auto enemy = world.entity(); world.set(enemy, {game_map.place_entity(1)}); world.set(enemy, {0,0}); @@ -61,6 +68,7 @@ void configure_world(DinkyECS::World &world, Map &game_map) { world.set(gold, {game_map.place_entity(3)}); world.set(gold, {100}); world.set(gold, {config.items["CHEST_SMALL"]["display"]}); + world.set(gold, {1, config.items["CHEST_SMALL"]}); auto wall_torch = world.entity(); world.set(wall_torch, {game_map.place_entity(4)}); diff --git a/systems.cpp b/systems.cpp index 309800a..3a76702 100644 --- a/systems.cpp +++ b/systems.cpp @@ -150,6 +150,10 @@ void System::collision(DinkyECS::World &world, Player &player) { auto &weapon = world.get(entity); player_combat.damage = weapon.damage; world.remove(entity); + } else if(world.has(entity)) { + auto &loot = world.get(entity); + inventory.gold += loot.amount; + world.remove(entity); } collider.remove(item_pos.location); diff --git a/tests/inventory.cpp b/tests/inventory.cpp index 2bd2c1f..68718bf 100644 --- a/tests/inventory.cpp +++ b/tests/inventory.cpp @@ -37,7 +37,7 @@ TEST_CASE("basic inventory test", "[inventory]") { System::pickup(world, player, sword); REQUIRE(inventory.count() == 1); // get the item and confirm there is 1 - auto &item1 = inventory.get("SWORD_RUSTY"); + auto &item1 = inventory.get(0); REQUIRE(item1.count == 1); System::pickup(world, player, sword); @@ -46,16 +46,16 @@ TEST_CASE("basic inventory test", "[inventory]") { REQUIRE(inventory.count() == 1); REQUIRE(item1.count == 4); - inventory.decrease("SWORD_RUSTY", 1); + inventory.decrease(0, 1); REQUIRE(item1.count == 3); - inventory.decrease("SWORD_RUSTY", 2); + inventory.decrease(0, 2); REQUIRE(item1.count == 1); - bool active = inventory.decrease("SWORD_RUSTY", 1); + bool active = inventory.decrease(0, 1); REQUIRE(item1.count == 0); REQUIRE(active == false); - inventory.remove_all("SWORD_RUSTY"); + inventory.erase_item(0); REQUIRE(inventory.count() == 0); }