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

This commit is contained in:
Zed A. Shaw 2025-01-04 13:32:26 -05:00
parent aaa6d9f9f3
commit 14b3ea7676
8 changed files with 56 additions and 47 deletions

View file

@ -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",

30
gui.cpp
View file

@ -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<Player>();
auto &inventory = $world.get<Inventory>(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++;
}
}

View file

@ -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<std::string> $menu_list;

View file

@ -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;
}
}
InventoryItem& Inventory::get(std::string id) {
dbc::check(items.contains(id), fmt::format("item id {} is not in inventory", id));
return items[id];
items.push_back(new_item);
}
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];
InventoryItem& Inventory::get(size_t at) {
dbc::check(at < items.size(), fmt::format("inventory index {} too big", at));
return items[at];
}
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);
}
}

View file

@ -16,16 +16,16 @@ namespace components {
struct Inventory {
int gold;
LightSource light;
std::unordered_map<std::string, InventoryItem> items;
std::vector<InventoryItem> 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);
};
}

View file

@ -34,7 +34,7 @@ void configure_world(DinkyECS::World &world, Map &game_map) {
world.set<Motion>(player.entity, {0, 0});
world.set<Combat>(player.entity, {100, 10});
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});
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<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();
world.set<Position>(enemy, {game_map.place_entity(1)});
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<Loot>(gold, {100});
world.set<Tile>(gold, {config.items["CHEST_SMALL"]["display"]});
world.set<InventoryItem>(gold, {1, config.items["CHEST_SMALL"]});
auto wall_torch = world.entity();
world.set<Position>(wall_torch, {game_map.place_entity(4)});

View file

@ -150,6 +150,10 @@ void System::collision(DinkyECS::World &world, Player &player) {
auto &weapon = world.get<Weapon>(entity);
player_combat.damage = weapon.damage;
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);

View file

@ -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);
}