From 94385b195ded0280c5b101b576ea7f175a00db88 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Sat, 7 Jun 2025 00:11:29 -0400 Subject: [PATCH] Mostly worked out how to do looting but now need how to take out of inventory and put into loot. --- events.hpp | 4 +- gui/fsm.cpp | 145 +++++++++++++++++++++++++++++++++++----------- gui/fsm.hpp | 25 ++++---- gui/loot_ui.cpp | 12 ++-- gui/loot_ui.hpp | 1 + gui/status_ui.cpp | 2 +- main.cpp | 2 + 7 files changed, 138 insertions(+), 53 deletions(-) diff --git a/events.hpp b/events.hpp index 6eb1484..892a8c5 100644 --- a/events.hpp +++ b/events.hpp @@ -6,7 +6,7 @@ namespace Events { COMBAT_START, NO_NEIGHBORS, HP_STATUS, ATTACK, BLOCK, EVADE, NEW_RITUAL, UPDATE_SPRITE, ENEMY_SPAWN, NOOP, - LOOT_CLOSE, LOOT_SELECT, LOOT_PLACE + LOOT_CLOSE, LOOT_SELECT, INV_SELECT }; struct Combat { @@ -33,7 +33,7 @@ namespace gui { STAIRS_DOWN = 13, LOOT_OPEN=14, LOOT_SELECT=15, - LOOT_PLACE=16, + INV_SELECT=16, QUIT = 17, MOUSE_CLICK=18, MOUSE_MOVE=19, diff --git a/gui/fsm.cpp b/gui/fsm.cpp index 0221a67..189cb58 100644 --- a/gui/fsm.cpp +++ b/gui/fsm.cpp @@ -39,15 +39,20 @@ namespace gui { FSM_STATE(State, COMBAT_ROTATE, ev); FSM_STATE(State, NEXT_LEVEL, ev); FSM_STATE(State, END, ev); - FSM_STATE(State, LOOTING, ev, std::make_any(true)); + FSM_STATE(State, LOOTING, ev, std::make_any(-1)); + FSM_STATE(State, LOOT_GRAB, ev, std::make_any(-1)); + FSM_STATE(State, INV_GRAB, ev, std::make_any(-1)); } } void FSM::event(Event ev, std::any data) { switch($state) { FSM_STATE(State, LOOTING, ev, data); + FSM_STATE(State, LOOT_GRAB, ev, data); + FSM_STATE(State, INV_GRAB, ev, data); + FSM_STATE(State, IDLE, ev); default: - dbc::log(fmt::format("event given with data but event={} is not handled", int(ev))); + dbc::log(fmt::format("event received with data but state={} is not handled", int($state))); } } @@ -118,7 +123,7 @@ namespace gui { } } - void FSM::LOOTING(Event ev, std::any data) { + void FSM::LOOT_GRAB(Event ev, std::any data) { using enum Event; switch(ev) { @@ -127,39 +132,117 @@ namespace gui { state(State::IDLE); break; case LOOT_SELECT: { - fmt::println("loot is selected"); int slot_id = std::any_cast(data); - if(auto entity = $loot_ui.select_slot(slot_id)) { - fmt::println("LOOT SELECT slot={} has entity={}", slot_id, entity.value()); - $status_ui.select_slot(slot_id, entity.value()); + $status_ui.select_slot(slot_id, *entity); + $dumb_sprite = $loot_ui.grab_sprite(slot_id); + + $window.setMouseCursorVisible(false); + $dumb_sprite->setOrigin({128, 128}); + $dumb_sprite->setPosition({ + float($router.position.x), + float($router.position.y) + }); } } break; - case LOOT_PLACE: { + case INV_SELECT: { std::string slot_name = std::any_cast(data); int slot_id = $status_ui.place_slot(slot_name); - // BUG: fix this bullshit if(slot_id != -1) { $loot_ui.remove_slot(slot_id); } + $window.setMouseCursorVisible(true); + $dumb_sprite = nullptr; + state(State::LOOTING); } break; case MOUSE_CLICK: mouse_action(false); break; - case MOUSE_MOVE: + case MOUSE_MOVE: { + if($dumb_sprite) { + $dumb_sprite->setPosition({ + float($router.position.x), + float($router.position.y) + }); + } + mouse_action(true); + } break; + case MOUSE_DRAG_START: { + mouse_action(false); + } break; + case MOUSE_DRAG: { + if($dumb_sprite) { + $dumb_sprite->setPosition({ + float($router.position.x), + float($router.position.y) + }); + } mouse_action(true); + } break; + case MOUSE_DROP: + mouse_action(false); + break; + case TICK: + // do nothing + break; + default: + state(State::LOOT_GRAB); + } + } + + void FSM::INV_GRAB(Event ev, std::any data) { + using enum Event; + (void)data; + + switch(ev) { + case LOOT_OPEN: + $loot_ui.active = false; + state(State::IDLE); break; - case MOUSE_DRAG_START: + case LOOT_SELECT: { + state(State::IDLE); + } break; + case INV_SELECT: { + state(State::IDLE); + } break; + case MOUSE_CLICK: mouse_action(false); break; - case MOUSE_DRAG: + case MOUSE_MOVE: { mouse_action(true); - break; + } break; + case MOUSE_DRAG_START: { + mouse_action(false); + } break; + case MOUSE_DRAG: { + mouse_action(true); + } break; case MOUSE_DROP: mouse_action(false); break; - case TICK: - // do nothing + default: + state(State::INV_GRAB); + } + } + + void FSM::LOOTING(Event ev, std::any data) { + using enum Event; + + switch(ev) { + case LOOT_OPEN: + $loot_ui.active = false; + state(State::IDLE); + break; + case LOOT_SELECT: + LOOT_GRAB(ev, data); + state(State::LOOT_GRAB); + break; + case INV_SELECT: + state(State::INV_GRAB); + INV_GRAB(ev, data); + break; + case MOUSE_CLICK: + mouse_action(false); break; default: state(State::LOOTING); @@ -213,39 +296,31 @@ namespace gui { sound::stop("ambient"); state(State::NEXT_LEVEL); break; - case STOP_COMBAT: - case TICK: - // do nothing - break; case LOOT_OPEN: { - dbc::log("IDLE LOOT OPEN!"); Config items("assets/items.json"); auto& data = items["TORCH_BAD"]; - auto torch = $level.world->entity(); - components::configure_entity(*$level.world, torch, data["components"]); - $loot_ui.contents.push_back(torch); + + for(int i = 0; $loot_ui.contents.size() < 10; i++) { + auto torch = $level.world->entity(); + components::configure_entity(*$level.world, torch, data["components"]); + $loot_ui.contents.push_back(torch); + } + $loot_ui.update(); $loot_ui.active = true; - state(State::LOOTING); - } break; - case LOOT_PLACE: - // ignored + case INV_SELECT: + state(State::INV_GRAB); break; - case MOUSE_CLICK: mouse_action(false); break; case MOUSE_MOVE: mouse_action(true); break; - case MOUSE_DRAG: // ignored - case MOUSE_DRAG_START: // ignored - case MOUSE_DROP: // ignored - break; default: - dbc::sentinel("unhandled event in IDLE"); + break; // ignore everything else } } @@ -498,8 +573,8 @@ namespace gui { case eGUI::LOOT_SELECT: event(Event::LOOT_SELECT, data); break; - case eGUI::LOOT_PLACE: - event(Event::LOOT_PLACE, data); + case eGUI::INV_SELECT: + event(Event::INV_SELECT, data); break; case eGUI::LOOT: { $map_ui.log(L"You picked up an item."); diff --git a/gui/fsm.hpp b/gui/fsm.hpp index 0905e76..d31b801 100644 --- a/gui/fsm.hpp +++ b/gui/fsm.hpp @@ -1,4 +1,5 @@ #pragma once + #include "constants.hpp" #include "levelmanager.hpp" #include "simplefsm.hpp" @@ -15,16 +16,18 @@ namespace gui { enum class State { - START, - MOVING, - IN_COMBAT, - COMBAT_ROTATE, - ATTACKING, - ROTATING, - NEXT_LEVEL, - LOOTING, - IDLE, - END + START=0, + MOVING=1, + IN_COMBAT=2, + COMBAT_ROTATE=3, + ATTACKING=4, + ROTATING=5, + NEXT_LEVEL=6, + LOOTING=7, + LOOT_GRAB=8, + INV_GRAB=9, + IDLE=10, + END=11 }; class FSM : public DeadSimpleFSM { @@ -65,6 +68,8 @@ namespace gui { void COMBAT_ROTATE(Event ev); void NEXT_LEVEL(Event ev); void LOOTING(Event ev, std::any data); + void LOOT_GRAB(Event ev, std::any data); + void INV_GRAB(Event ev, std::any data); void END(Event ev); void try_move(int dir, bool strafe); diff --git a/gui/loot_ui.cpp b/gui/loot_ui.cpp index 6498191..6fffe3c 100644 --- a/gui/loot_ui.cpp +++ b/gui/loot_ui.cpp @@ -48,13 +48,19 @@ namespace gui { } std::optional LootUI::select_slot(int slot_id) { - if(size_t(slot_id) < contents.size()) { + if(slot_id >= 0 && size_t(slot_id) < contents.size()) { return contents.at(slot_id); } else { return std::nullopt; } } + shared_ptr LootUI::grab_sprite(int slot_id) { + auto id = $gui.entity("item_", slot_id); + auto& sprite = $gui.get(id); + return sprite.sprite; + } + void LootUI::remove_slot(int slot_id) { dbc::check(size_t(slot_id) < contents.size(), fmt::format("invalid slot id {} give, contents.size={}", @@ -70,12 +76,8 @@ namespace gui { for(size_t i = 0; i < INV_SLOTS; i++) { auto id = $gui.entity("item_", int(i)); - fmt::println("checking for sprite at {}", id); if($gui.has(id)) { - fmt::println("REMOVING SPRITE {}", id); $gui.remove(id); - } else { - fmt::println("nothing at {}", id); } if(i < contents.size()) { diff --git a/gui/loot_ui.hpp b/gui/loot_ui.hpp index e329277..66fea97 100644 --- a/gui/loot_ui.hpp +++ b/gui/loot_ui.hpp @@ -22,5 +22,6 @@ namespace gui { bool mouse(float x, float y, bool hover); std::optional select_slot(int slot); void remove_slot(int slot_id); + shared_ptr grab_sprite(int slot_id); }; } diff --git a/gui/status_ui.cpp b/gui/status_ui.cpp index 5fee91b..cd36a8d 100644 --- a/gui/status_ui.cpp +++ b/gui/status_ui.cpp @@ -43,7 +43,7 @@ namespace gui { } else { $gui.set(button, {guecs::to_wstring(name)}); $gui.set(button, { - guecs::make_action(*$level.world, Events::GUI::LOOT_PLACE, {name}) + guecs::make_action(*$level.world, Events::GUI::INV_SELECT, {name}) }); } } diff --git a/main.cpp b/main.cpp index 559a8e1..60d513a 100644 --- a/main.cpp +++ b/main.cpp @@ -35,6 +35,8 @@ int main(int argc, char* argv[]) { if(main.in_state(gui::State::IDLE) || main.in_state(gui::State::NEXT_LEVEL) || main.in_state(gui::State::LOOTING) + || main.in_state(gui::State::LOOT_GRAB) + || main.in_state(gui::State::INV_GRAB) || main.in_state(gui::State::IN_COMBAT)) { if(main.autowalking) {