Inventory system is mostly working and I can pick up everything and use it.

main
Zed A. Shaw 5 days ago
parent aaa6d9f9f3
commit 14b3ea7676
  1. 6
      assets/items.json
  2. 30
      gui.cpp
  3. 1
      gui.hpp
  4. 34
      inventory.cpp
  5. 8
      inventory.hpp
  6. 10
      main.cpp
  7. 4
      systems.cpp
  8. 10
      tests/inventory.cpp

@ -4,7 +4,7 @@
"name": "Crappy Torch", "name": "Crappy Torch",
"foreground": [24, 205, 189], "foreground": [24, 205, 189],
"background": [230, 20, 120], "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" "display": "\u0f08"
}, },
"SWORD_RUSTY": { "SWORD_RUSTY": {
@ -12,7 +12,7 @@
"name": "Rusty Junk Sword", "name": "Rusty Junk Sword",
"foreground": [24, 205, 189], "foreground": [24, 205, 189],
"background": [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" "display":"\u1e37"
}, },
"CHEST_SMALL": { "CHEST_SMALL": {
@ -21,7 +21,7 @@
"foreground": [24, 205, 189], "foreground": [24, 205, 189],
"background": [24, 205, 189], "background": [24, 205, 189],
"display":"\uaaea", "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": { "WALL_TORCH": {
"id": "WALL_TORCH", "id": "WALL_TORCH",

@ -31,14 +31,14 @@ using namespace ftxui;
using namespace components; using namespace components;
void InventoryUI::create_render() { 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<Player>(); auto &player = $world.get_the<Player>();
auto &inventory = $world.get<Inventory>(player.entity); auto &inventory = $world.get<Inventory>(player.entity);
update_menu_list(inventory); update_menu_list(inventory);
MenuOption option;
$inventory_box = Menu(&$menu_list, &$selected, option);
return hbox({ return hbox({
$inventory_box->Render() | frame | size(WIDTH, EQUAL, 35) | yflex_grow, $inventory_box->Render() | frame | size(WIDTH, EQUAL, 35) | yflex_grow,
separator() | yflex_grow, separator() | yflex_grow,
@ -48,26 +48,22 @@ void InventoryUI::create_render() {
}) | border | flex; }) | border | flex;
}); });
set_renderer(inventory_render); set_renderer($inventory_render);
add($inventory_box);
} }
void InventoryUI::update_menu_list(Inventory& inventory) { 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(); $menu_list.clear();
int i = 0; // SOOOOO BADDDDD for(size_t i = 0; i < inventory.count(); i++) {
for(auto& [key, val] : inventory.items) { auto& item = inventory.get(i);
$menu_list.push_back(fmt::format("{} {} ({})", $menu_list.push_back(fmt::format("{} {} ({})",
string(val.data["display"]), string(item.data["display"]),
string(val.data["name"]), string(item.data["name"]),
val.count)); item.count));
// GARBAGE HOT if($selected == int(i)) {
if($selected == i) { $item_text = item.data["description"];
$item_text = val.data["description"];
} }
i++;
} }
} }

@ -53,6 +53,7 @@ class InventoryUI : public Panel {
int $selected = 0; int $selected = 0;
Component $inventory_box; Component $inventory_box;
Component $inventory_render;
Component $inventory_table; Component $inventory_table;
DinkyECS::World& $world; DinkyECS::World& $world;
std::vector<std::string> $menu_list; std::vector<std::string> $menu_list;

@ -2,31 +2,31 @@
namespace components { namespace components {
void Inventory::add(InventoryItem item) { void Inventory::add(InventoryItem new_item) {
std::string id = item.data["id"]; for(auto &slot : items) {
if(new_item.data["id"] == slot.data["id"]) {
if(items.contains(id)) { slot.count += new_item.count;
auto &slot = items[id]; return;
slot.count += item.count; }
} else {
items[id] = item;
} }
items.push_back(new_item);
} }
InventoryItem& Inventory::get(std::string id) { InventoryItem& Inventory::get(size_t at) {
dbc::check(items.contains(id), fmt::format("item id {} is not in inventory", id)); dbc::check(at < items.size(), fmt::format("inventory index {} too big", at));
return items[id]; return items[at];
} }
bool Inventory::decrease(std::string id, int count) { bool Inventory::decrease(size_t at, int count) {
dbc::check(items.contains(id), fmt::format("item id {} is not in inventory", id)); dbc::check(at < items.size(), fmt::format("inventory index {} too big", at));
auto &slot = items[id]; auto &slot = items[at];
slot.count -= count; slot.count -= count;
return slot.count > 0; return slot.count > 0;
} }
void Inventory::remove_all(std::string id) { void Inventory::erase_item(size_t at) {
dbc::check(items.contains(id), fmt::format("item id {} is not in inventory", id)); dbc::check(at < items.size(), fmt::format("inventory index {} too big", at));
items.erase(id); items.erase(items.begin() + at);
} }
} }

@ -16,16 +16,16 @@ namespace components {
struct Inventory { struct Inventory {
int gold; int gold;
LightSource light; LightSource light;
std::unordered_map<std::string, InventoryItem> items; std::vector<InventoryItem> items;
size_t count() { return items.size(); } size_t count() { return items.size(); }
void add(InventoryItem item); 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);
}; };
} }

@ -34,7 +34,7 @@ void configure_world(DinkyECS::World &world, Map &game_map) {
world.set<Motion>(player.entity, {0, 0}); world.set<Motion>(player.entity, {0, 0});
world.set<Combat>(player.entity, {100, 10}); world.set<Combat>(player.entity, {100, 10});
world.set<Tile>(player.entity, {config.enemies["PLAYER_TILE"]["display"]}); world.set<Tile>(player.entity, {config.enemies["PLAYER_TILE"]["display"]});
world.set<LightSource>(player.entity, {70,1.0}); world.set<LightSource>(player.entity, {50,1.0});
world.set<Inventory>(player.entity, {5}); world.set<Inventory>(player.entity, {5});
auto sword = world.entity(); auto sword = world.entity();
@ -44,6 +44,13 @@ void configure_world(DinkyECS::World &world, Map &game_map) {
world.set<InventoryItem>(sword, {1, config.items["SWORD_RUSTY"]}); world.set<InventoryItem>(sword, {1, config.items["SWORD_RUSTY"]});
world.set<Weapon>(sword, {20}); world.set<Weapon>(sword, {20});
auto torch = world.entity();
pos = game_map.place_entity(2);
world.set<Position>(torch, {pos.x+1, pos.y+1});
world.set<Tile>(torch, {config.items["TORCH_BAD"]["display"]});
world.set<InventoryItem>(torch, {1, config.items["TORCH_BAD"]});
world.set<LightSource>(torch, {70,2.0f});
auto enemy = world.entity(); auto enemy = world.entity();
world.set<Position>(enemy, {game_map.place_entity(1)}); world.set<Position>(enemy, {game_map.place_entity(1)});
world.set<Motion>(enemy, {0,0}); world.set<Motion>(enemy, {0,0});
@ -61,6 +68,7 @@ void configure_world(DinkyECS::World &world, Map &game_map) {
world.set<Position>(gold, {game_map.place_entity(3)}); world.set<Position>(gold, {game_map.place_entity(3)});
world.set<Loot>(gold, {100}); world.set<Loot>(gold, {100});
world.set<Tile>(gold, {config.items["CHEST_SMALL"]["display"]}); world.set<Tile>(gold, {config.items["CHEST_SMALL"]["display"]});
world.set<InventoryItem>(gold, {1, config.items["CHEST_SMALL"]});
auto wall_torch = world.entity(); auto wall_torch = world.entity();
world.set<Position>(wall_torch, {game_map.place_entity(4)}); world.set<Position>(wall_torch, {game_map.place_entity(4)});

@ -150,6 +150,10 @@ void System::collision(DinkyECS::World &world, Player &player) {
auto &weapon = world.get<Weapon>(entity); auto &weapon = world.get<Weapon>(entity);
player_combat.damage = weapon.damage; player_combat.damage = weapon.damage;
world.remove<Weapon>(entity); world.remove<Weapon>(entity);
} else if(world.has<Loot>(entity)) {
auto &loot = world.get<Loot>(entity);
inventory.gold += loot.amount;
world.remove<Loot>(entity);
} }
collider.remove(item_pos.location); collider.remove(item_pos.location);

@ -37,7 +37,7 @@ TEST_CASE("basic inventory test", "[inventory]") {
System::pickup(world, player, sword); System::pickup(world, player, sword);
REQUIRE(inventory.count() == 1); REQUIRE(inventory.count() == 1);
// get the item and confirm there is 1 // get the item and confirm there is 1
auto &item1 = inventory.get("SWORD_RUSTY"); auto &item1 = inventory.get(0);
REQUIRE(item1.count == 1); REQUIRE(item1.count == 1);
System::pickup(world, player, sword); System::pickup(world, player, sword);
@ -46,16 +46,16 @@ TEST_CASE("basic inventory test", "[inventory]") {
REQUIRE(inventory.count() == 1); REQUIRE(inventory.count() == 1);
REQUIRE(item1.count == 4); REQUIRE(item1.count == 4);
inventory.decrease("SWORD_RUSTY", 1); inventory.decrease(0, 1);
REQUIRE(item1.count == 3); REQUIRE(item1.count == 3);
inventory.decrease("SWORD_RUSTY", 2); inventory.decrease(0, 2);
REQUIRE(item1.count == 1); REQUIRE(item1.count == 1);
bool active = inventory.decrease("SWORD_RUSTY", 1); bool active = inventory.decrease(0, 1);
REQUIRE(item1.count == 0); REQUIRE(item1.count == 0);
REQUIRE(active == false); REQUIRE(active == false);
inventory.remove_all("SWORD_RUSTY"); inventory.erase_item(0);
REQUIRE(inventory.count() == 0); REQUIRE(inventory.count() == 0);
} }

Loading…
Cancel
Save