Finally have inventory not crashing for most edge cases. This solves many bugs but mostly closes #58.
This commit is contained in:
parent
601f3331ed
commit
f64b202ee7
9 changed files with 90 additions and 43 deletions
|
@ -61,11 +61,13 @@ namespace gui {
|
|||
case LOOT_OPEN:
|
||||
END(CLOSE);
|
||||
break;
|
||||
case LOOT_SELECT:
|
||||
if(commit_move($loot_ui.$gui, $grab_source, data)) {
|
||||
case LOOT_SELECT: {
|
||||
auto drop_id = std::any_cast<guecs::Entity>(data);
|
||||
|
||||
if(move_or_swap($loot_ui, drop_id)) {
|
||||
state(DNDState::LOOTING);
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case INV_SELECT:
|
||||
if(commit_drop($loot_ui.$gui,
|
||||
$status_ui.$gui, $grab_source, data))
|
||||
|
@ -92,11 +94,12 @@ namespace gui {
|
|||
state(DNDState::LOOTING);
|
||||
}
|
||||
break;
|
||||
case INV_SELECT:
|
||||
if(commit_move($status_ui.$gui, $grab_source, data)) {
|
||||
case INV_SELECT: {
|
||||
auto drop_id = std::any_cast<guecs::Entity>(data);
|
||||
if(move_or_swap($status_ui, drop_id)) {
|
||||
state(DNDState::LOOTING);
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
default:
|
||||
handle_mouse(ev, $status_ui.$gui);
|
||||
}
|
||||
|
@ -114,15 +117,10 @@ namespace gui {
|
|||
} break;
|
||||
case INV_SELECT: {
|
||||
auto drop_id = std::any_cast<guecs::Entity>(data);
|
||||
|
||||
if($status_ui.occupied(drop_id)) {
|
||||
$status_ui.swap(*$grab_source, drop_id);
|
||||
END(CLOSE);
|
||||
} else if(commit_move($status_ui.$gui, $grab_source, data)) {
|
||||
if(move_or_swap($status_ui, drop_id)) {
|
||||
END(CLOSE);
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
default:
|
||||
handle_mouse(ev, $status_ui.$gui);
|
||||
}
|
||||
|
@ -252,13 +250,12 @@ namespace gui {
|
|||
}
|
||||
}
|
||||
|
||||
bool DNDLoot::commit_move(guecs::UI& gui, std::optional<guecs::Entity> source_id, std::any data) {
|
||||
bool DNDLoot::commit_move(guecs::UI& gui, std::optional<guecs::Entity> source_id, guecs::Entity drop_id) {
|
||||
dbc::check(source_id != std::nullopt, "source_id must exist");
|
||||
|
||||
auto& grab = gui.get<guecs::GrabSource>(*source_id);
|
||||
grab.commit();
|
||||
|
||||
auto drop_id = std::any_cast<guecs::Entity>(data);
|
||||
auto& drop = gui.get<guecs::DropTarget>(drop_id);
|
||||
|
||||
if(drop.commit(grab.world_entity)) {
|
||||
|
@ -307,4 +304,30 @@ namespace gui {
|
|||
clear_grab();
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* If I refactored everything to use a levelmanager module then
|
||||
* this and many other things could go away. Access to $level is
|
||||
* making this too complicated. Do this for now, but fix bug #59.
|
||||
*/
|
||||
bool DNDLoot::move_or_swap(StatusUI& ui, guecs::Entity drop_id) {
|
||||
if(ui.occupied(drop_id)) {
|
||||
ui.swap(*$grab_source, drop_id);
|
||||
clear_grab();
|
||||
return true;
|
||||
} else {
|
||||
return commit_move(ui.$gui, $grab_source, drop_id);
|
||||
}
|
||||
}
|
||||
|
||||
bool DNDLoot::move_or_swap(LootUI& ui, guecs::Entity drop_id) {
|
||||
if(ui.occupied(drop_id)) {
|
||||
ui.swap(*$grab_source, drop_id);
|
||||
clear_grab();
|
||||
return true;
|
||||
} else {
|
||||
return commit_move(ui.$gui, $grab_source, drop_id);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -50,13 +50,16 @@ namespace gui {
|
|||
std::optional<guecs::Entity> source_id, std::any data);
|
||||
|
||||
bool commit_move(guecs::UI& gui,
|
||||
std::optional<guecs::Entity> source_id, std::any data);
|
||||
std::optional<guecs::Entity> source_id, guecs::Entity drop_id);
|
||||
|
||||
bool hold_item(guecs::UI& gui, guecs::Entity gui_id);
|
||||
bool throw_on_floor(guecs::UI& gui, bool from_status);
|
||||
|
||||
void clear_grab();
|
||||
|
||||
bool move_or_swap(StatusUI& status_ui, guecs::Entity drop_id);
|
||||
bool move_or_swap(LootUI& ui, guecs::Entity drop_id);
|
||||
|
||||
sf::Vector2f mouse_position();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -47,7 +47,6 @@ namespace gui {
|
|||
for(int i = 0; i < INV_SLOTS; i++) {
|
||||
auto name = fmt::format("item_{}", i);
|
||||
auto id = $gui.entity(name);
|
||||
$slot_to_name.insert_or_assign(id, name);
|
||||
|
||||
$gui.set<guecs::Rectangle>(id, {THEME.PADDING,
|
||||
THEME.TRANSPARENT, THEME.LIGHT_MID });
|
||||
|
@ -69,7 +68,7 @@ namespace gui {
|
|||
|
||||
for(size_t i = 0; i < INV_SLOTS; i++) {
|
||||
auto id = $gui.entity("item_", int(i));
|
||||
auto& slot_name = $slot_to_name.at(id);
|
||||
auto& slot_name = $gui.name_for(id);
|
||||
|
||||
if(contents.has(slot_name)) {
|
||||
auto item = contents.get(slot_name);
|
||||
|
@ -97,7 +96,7 @@ namespace gui {
|
|||
}
|
||||
|
||||
void LootUI::remove_slot(guecs::Entity slot_id) {
|
||||
auto& name = $slot_to_name.at(slot_id);
|
||||
auto& name = $gui.name_for(slot_id);
|
||||
fmt::println("LootUI remove slot inv::Model id={} slot={}", $target, name);
|
||||
System::remove_from_container(*$level.world, $target, name);
|
||||
update();
|
||||
|
@ -106,7 +105,8 @@ namespace gui {
|
|||
bool LootUI::place_slot(guecs::Entity id, DinkyECS::Entity world_entity) {
|
||||
fmt::println("LootUI target={} placing world entity {} in slot id {}",
|
||||
$target, id, world_entity);
|
||||
auto& name = $slot_to_name.at(id);
|
||||
auto& name = $gui.name_for(id);
|
||||
|
||||
bool worked = System::place_in_container(*$level.world, $target, name, world_entity);
|
||||
if(worked) update();
|
||||
return worked;
|
||||
|
@ -136,4 +136,18 @@ namespace gui {
|
|||
bool LootUI::mouse(float x, float y, bool hover) {
|
||||
return $gui.mouse(x, y, hover);
|
||||
}
|
||||
|
||||
bool LootUI::occupied(guecs::Entity slot) {
|
||||
return System::inventory_occupied($level, $target, $gui.name_for(slot));
|
||||
}
|
||||
|
||||
void LootUI::swap(guecs::Entity gui_a, guecs::Entity gui_b) {
|
||||
if(gui_a != gui_b) {
|
||||
auto& a_name = $gui.name_for(gui_a);
|
||||
auto& b_name = $gui.name_for(gui_b);
|
||||
System::inventory_swap($level, $target, a_name, b_name);
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ namespace gui {
|
|||
bool active = false;
|
||||
guecs::UI $gui;
|
||||
GameLevel $level;
|
||||
std::unordered_map<guecs::Entity, std::string> $slot_to_name;
|
||||
DinkyECS::Entity $temp_loot;
|
||||
DinkyECS::Entity $target;
|
||||
|
||||
|
@ -34,5 +33,7 @@ namespace gui {
|
|||
bool place_slot(guecs::Entity gui_id, DinkyECS::Entity world_entity);
|
||||
void add_loose_item(DinkyECS::Entity entity);
|
||||
bool drop_item(DinkyECS::Entity item_id);
|
||||
bool occupied(guecs::Entity gui_id);
|
||||
void swap(guecs::Entity gui_a, guecs::Entity gui_b);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ namespace gui {
|
|||
|
||||
for(auto& [name, cell] : $gui.cells()) {
|
||||
auto gui_id = $gui.entity(name);
|
||||
$slot_to_name.insert_or_assign(gui_id, name);
|
||||
|
||||
if(name == "character_view") {
|
||||
$gui.set<Rectangle>(gui_id, {});
|
||||
|
@ -102,7 +101,7 @@ namespace gui {
|
|||
}
|
||||
|
||||
bool StatusUI::place_slot(guecs::Entity gui_id, DinkyECS::Entity world_entity) {
|
||||
auto& slot_name = $slot_to_name.at(gui_id);
|
||||
auto& slot_name = $gui.name_for(gui_id);
|
||||
auto player = $level.world->get_the<components::Player>();
|
||||
auto& inventory = $level.world->get<inventory::Model>(player.entity);
|
||||
|
||||
|
@ -128,8 +127,7 @@ namespace gui {
|
|||
// ground or moving from one container or another, so when loot_ui
|
||||
// moves to use an ECS id to a container I can have the System
|
||||
// do it.
|
||||
dbc::log(fmt::format("removing slot: {}", slot_id));
|
||||
auto& slot_name = $slot_to_name.at(slot_id);
|
||||
auto& slot_name = $gui.name_for(slot_id);
|
||||
|
||||
auto player = $level.world->get_the<components::Player>();
|
||||
auto& inventory = $level.world->get<inventory::Model>(player.entity);
|
||||
|
@ -143,25 +141,17 @@ namespace gui {
|
|||
|
||||
void StatusUI::swap(guecs::Entity gui_a, guecs::Entity gui_b) {
|
||||
if(gui_a != gui_b) {
|
||||
auto& a_name = $gui.name_for(gui_a);
|
||||
auto& b_name = $gui.name_for(gui_b);
|
||||
auto player = $level.world->get_the<components::Player>();
|
||||
auto& inventory = $level.world->get<inventory::Model>(player.entity);
|
||||
|
||||
auto& a_name = $slot_to_name.at(gui_a);
|
||||
auto& b_name = $slot_to_name.at(gui_b);
|
||||
auto a_ent = inventory.get(a_name);
|
||||
auto b_ent = inventory.get(b_name);
|
||||
inventory.swap(a_ent, b_ent);
|
||||
System::inventory_swap($level, player.entity, a_name, b_name);
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
bool StatusUI::occupied(guecs::Entity slot) {
|
||||
dbc::check($slot_to_name.contains(slot), "jank ass slot to name thing isn't loaded right you idiot.");
|
||||
|
||||
auto player = $level.world->get_the<components::Player>();
|
||||
auto& inventory = $level.world->get<inventory::Model>(player.entity);
|
||||
auto& slot_name = $slot_to_name.at(slot);
|
||||
return inventory.has(slot_name);
|
||||
return System::inventory_occupied($level, player.entity, $gui.name_for(slot));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ namespace gui {
|
|||
public:
|
||||
guecs::UI $gui;
|
||||
GameLevel $level;
|
||||
std::unordered_map<guecs::Entity, std::string> $slot_to_name;
|
||||
ritual::UI $ritual_ui;
|
||||
|
||||
explicit StatusUI(GameLevel level);
|
||||
|
|
15
systems.cpp
15
systems.cpp
|
@ -562,3 +562,18 @@ Position& System::player_position(GameLevel& level) {
|
|||
auto& player = level.world->get_the<components::Player>();
|
||||
return level.world->get<components::Position>(player.entity);
|
||||
}
|
||||
|
||||
void System::inventory_swap(GameLevel &level, Entity container_id, const std::string& a_name, const std::string &b_name) {
|
||||
dbc::check(a_name != b_name, "Attempt to inventory swap the same slot, you should check this and avoid calling me.");
|
||||
|
||||
auto& inventory = level.world->get<inventory::Model>(container_id);
|
||||
|
||||
auto a_ent = inventory.get(a_name);
|
||||
auto b_ent = inventory.get(b_name);
|
||||
inventory.swap(a_ent, b_ent);
|
||||
}
|
||||
|
||||
bool System::inventory_occupied(GameLevel& level, Entity container_id, const std::string& name) {
|
||||
auto& inventory = level.world->get<inventory::Model>(container_id);
|
||||
return inventory.has(name);
|
||||
}
|
||||
|
|
|
@ -37,4 +37,6 @@ namespace System {
|
|||
void remove_from_container(World& world, Entity cont_id, const std::string& name);
|
||||
void remove_from_world(GameLevel &level, Entity entity);
|
||||
Position& player_position(GameLevel& level);
|
||||
void inventory_swap(GameLevel &level, Entity container_id, const std::string& a_name, const std::string &b_name);
|
||||
bool inventory_occupied(GameLevel& level, Entity container_id, const std::string& name);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[wrap-git]
|
||||
directory=lel-guecs-0.2.0
|
||||
directory=lel-guecs-0.3.0
|
||||
url=https://git.learnjsthehardway.com/learn-code-the-hard-way/lel-guecs.git
|
||||
revision=HEAD
|
||||
depth=1
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue