So far most of the bugs are solved but there's still some edge cases in the inventory dance.
This commit is contained in:
parent
e0588847fa
commit
3c5021e4c9
6 changed files with 40 additions and 25 deletions
|
@ -126,7 +126,7 @@ namespace gui {
|
||||||
|
|
||||||
switch(ev) {
|
switch(ev) {
|
||||||
case INV_SELECT:
|
case INV_SELECT:
|
||||||
commit_drop($loot_ui.$gui, $status_ui.$gui, $grab_source, data);
|
if(commit_drop($loot_ui.$gui, $status_ui.$gui, $grab_source, data))
|
||||||
{
|
{
|
||||||
END(Event::CLOSE);
|
END(Event::CLOSE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,18 +103,16 @@ namespace gui {
|
||||||
auto& slot_name = $slot_to_name.at(gui_id);
|
auto& slot_name = $slot_to_name.at(gui_id);
|
||||||
auto& inventory = $level.world->get_the<inventory::Model>();
|
auto& inventory = $level.world->get_the<inventory::Model>();
|
||||||
|
|
||||||
for(auto [ent, slot] : inventory.by_entity) {
|
inventory.dump();
|
||||||
fmt::println("BY_ENTITY: ent={}, slot={}", ent, slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(auto [slot, ent] : inventory.by_slot) {
|
if(inventory.add(slot_name, world_entity)) {
|
||||||
fmt::println("BY_SLOT: ent={}, slot={}", ent, slot);
|
$level.world->make_constant(world_entity);
|
||||||
|
update();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
dbc::log("there's something there already");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$level.world->make_constant(world_entity);
|
|
||||||
inventory.add(slot_name, world_entity);
|
|
||||||
update();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StatusUI::drop_item(DinkyECS::Entity item_id) {
|
bool StatusUI::drop_item(DinkyECS::Entity item_id) {
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
#include "inventory.hpp"
|
#include "inventory.hpp"
|
||||||
|
|
||||||
namespace inventory {
|
namespace inventory {
|
||||||
void Model::add(const Slot &in_slot, DinkyECS::Entity ent) {
|
bool Model::add(const Slot &in_slot, DinkyECS::Entity ent) {
|
||||||
if(by_entity.contains(ent)) {
|
invariant();
|
||||||
// doing it this way so we can get the offending entity, otherwise it
|
|
||||||
// crashes on the by_entity.at when this test _passes_
|
if(by_slot.contains(in_slot)) return false;
|
||||||
dbc::sentinel(fmt::format("failed to add item to inventory, entity {} is already in the inventory slot {}", ent, by_entity.at(ent)));
|
|
||||||
}
|
|
||||||
|
|
||||||
by_entity.insert_or_assign(ent, in_slot);
|
by_entity.insert_or_assign(ent, in_slot);
|
||||||
by_slot.insert_or_assign(in_slot, ent);
|
by_slot.insert_or_assign(in_slot, ent);
|
||||||
|
|
||||||
invariant();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Slot& Model::get(DinkyECS::Entity ent) {
|
Slot& Model::get(DinkyECS::Entity ent) {
|
||||||
|
@ -49,9 +47,6 @@ namespace inventory {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::invariant() {
|
void Model::invariant() {
|
||||||
dbc::check(by_slot.size() == by_entity.size(), "by_slot and by_entity have differing sizes");
|
|
||||||
// std::unordered_map<DinkyECS::Entity, Slot> find_dupes;
|
|
||||||
|
|
||||||
for(auto& [slot, ent] : by_slot) {
|
for(auto& [slot, ent] : by_slot) {
|
||||||
dbc::check(by_entity.at(ent) == slot,
|
dbc::check(by_entity.at(ent) == slot,
|
||||||
fmt::format("mismatched slot {} in by_slot doesn't match entity {}", slot, ent));
|
fmt::format("mismatched slot {} in by_slot doesn't match entity {}", slot, ent));
|
||||||
|
@ -61,5 +56,18 @@ namespace inventory {
|
||||||
dbc::check(by_slot.at(slot) == ent,
|
dbc::check(by_slot.at(slot) == ent,
|
||||||
fmt::format("mismatched entity {} in by_entity doesn't match entity {}", ent, slot));
|
fmt::format("mismatched entity {} in by_entity doesn't match entity {}", ent, slot));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dbc::check(by_slot.size() == by_entity.size(), "by_slot and by_entity have differing sizes");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Model::dump() {
|
||||||
|
invariant();
|
||||||
|
fmt::println("INVENTORY has {} slots, sizes equal? {}, contents:",
|
||||||
|
by_entity.size(), by_entity.size() == by_slot.size());
|
||||||
|
|
||||||
|
for(auto [slot, ent] : by_slot) {
|
||||||
|
fmt::println("slot={}, ent={}, both={}, equal={}",
|
||||||
|
slot, ent, by_entity.contains(ent), by_entity.at(ent) == slot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace inventory {
|
||||||
std::unordered_map<Slot, DinkyECS::Entity> by_slot;
|
std::unordered_map<Slot, DinkyECS::Entity> by_slot;
|
||||||
std::unordered_map<DinkyECS::Entity, Slot> by_entity;
|
std::unordered_map<DinkyECS::Entity, Slot> by_entity;
|
||||||
|
|
||||||
void add(const Slot &in_slot, DinkyECS::Entity ent);
|
bool add(const Slot &in_slot, DinkyECS::Entity ent);
|
||||||
Slot& get(DinkyECS::Entity ent);
|
Slot& get(DinkyECS::Entity ent);
|
||||||
DinkyECS::Entity get(const Slot& slot);
|
DinkyECS::Entity get(const Slot& slot);
|
||||||
bool has(DinkyECS::Entity ent);
|
bool has(DinkyECS::Entity ent);
|
||||||
|
@ -17,5 +17,6 @@ namespace inventory {
|
||||||
void remove(DinkyECS::Entity ent);
|
void remove(DinkyECS::Entity ent);
|
||||||
void remove(const Slot& slot);
|
void remove(const Slot& slot);
|
||||||
void invariant();
|
void invariant();
|
||||||
|
void dump();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,17 @@ TEST_CASE("base test", "[inventory]") {
|
||||||
inventory::Model inv;
|
inventory::Model inv;
|
||||||
DinkyECS::Entity test_ent = 1;
|
DinkyECS::Entity test_ent = 1;
|
||||||
|
|
||||||
inv.add("hand_l", test_ent);
|
bool good = inv.add("hand_l", test_ent);
|
||||||
inv.invariant();
|
inv.invariant();
|
||||||
|
REQUIRE(good);
|
||||||
|
|
||||||
auto& slot = inv.get(test_ent);
|
auto& slot = inv.get(test_ent);
|
||||||
REQUIRE(slot == "hand_l");
|
REQUIRE(slot == "hand_l");
|
||||||
|
|
||||||
|
// confirm that we get false when trying to do it again
|
||||||
|
good = inv.add("hand_l", test_ent);
|
||||||
|
REQUIRE(!good);
|
||||||
|
|
||||||
auto ent = inv.get(slot);
|
auto ent = inv.get(slot);
|
||||||
REQUIRE(ent == test_ent);
|
REQUIRE(ent == test_ent);
|
||||||
|
|
||||||
|
@ -27,7 +32,8 @@ TEST_CASE("base test", "[inventory]") {
|
||||||
REQUIRE(!inv.has(ent));
|
REQUIRE(!inv.has(ent));
|
||||||
|
|
||||||
// test remove just by slot
|
// test remove just by slot
|
||||||
inv.add("hand_r", test_ent);
|
good = inv.add("hand_r", test_ent);
|
||||||
|
REQUIRE(good);
|
||||||
REQUIRE(inv.has("hand_r"));
|
REQUIRE(inv.has("hand_r"));
|
||||||
REQUIRE(inv.has(test_ent));
|
REQUIRE(inv.has(test_ent));
|
||||||
inv.invariant();
|
inv.invariant();
|
||||||
|
@ -37,7 +43,8 @@ TEST_CASE("base test", "[inventory]") {
|
||||||
REQUIRE(!inv.has(test_ent));
|
REQUIRE(!inv.has(test_ent));
|
||||||
|
|
||||||
// test remove just by entity
|
// test remove just by entity
|
||||||
inv.add("pocket_l", test_ent);
|
good = inv.add("pocket_l", test_ent);
|
||||||
|
REQUIRE(good);
|
||||||
REQUIRE(inv.has("pocket_l"));
|
REQUIRE(inv.has("pocket_l"));
|
||||||
REQUIRE(inv.has(test_ent));
|
REQUIRE(inv.has(test_ent));
|
||||||
inv.invariant();
|
inv.invariant();
|
||||||
|
|
|
@ -179,6 +179,7 @@ void WorldBuilder::configure_starting_items(DinkyECS::World &world) {
|
||||||
|
|
||||||
auto &inventory = world.get_the<inventory::Model>();
|
auto &inventory = world.get_the<inventory::Model>();
|
||||||
inventory.add("hand_r", torch_id);
|
inventory.add("hand_r", torch_id);
|
||||||
|
world.make_constant(torch_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldBuilder::place_entities(DinkyECS::World &world) {
|
void WorldBuilder::place_entities(DinkyECS::World &world) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue