From 82ee8f68f775d25429fe6c7fe1380332a139beb5 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Fri, 13 Jun 2025 00:57:45 -0400 Subject: [PATCH] Created a separate FSM for the DND functionality that compiles but need to wire it in to work. --- events.hpp | 2 +- gui/dnd_loot.cpp | 160 +++++++++++++++++++++++++++++++++++++++++++++++ gui/dnd_loot.hpp | 39 ++++++++++++ gui/fsm.cpp | 141 +++++------------------------------------ gui/fsm.hpp | 14 ++--- main.cpp | 3 +- meson.build | 1 + 7 files changed, 221 insertions(+), 139 deletions(-) create mode 100644 gui/dnd_loot.cpp create mode 100644 gui/dnd_loot.hpp diff --git a/events.hpp b/events.hpp index 4e224c3..88f3ab3 100644 --- a/events.hpp +++ b/events.hpp @@ -4,7 +4,7 @@ namespace Events { enum GUI { START, COMBAT, DEATH, STAIRS_UP, STAIRS_DOWN, TRAP, COMBAT_START, NO_NEIGHBORS, HP_STATUS, - ATTACK, BLOCK, EVADE, NEW_RITUAL, + ATTACK, NEW_RITUAL, UPDATE_SPRITE, ENEMY_SPAWN, NOOP, LOOT_ITEM, LOOT_CONTAINER, LOOT_CLOSE, LOOT_SELECT, INV_SELECT, AIM_CLICK diff --git a/gui/dnd_loot.cpp b/gui/dnd_loot.cpp new file mode 100644 index 0000000..3a22963 --- /dev/null +++ b/gui/dnd_loot.cpp @@ -0,0 +1,160 @@ +#define FSM_DEBUG 1 +#include "gui/guecstra.hpp" +#include "gui/dnd_loot.hpp" +#include "gui/uisystems.hpp" + +namespace gui { + + DNDLoot::DNDLoot(StatusUI status_ui, LootUI loot_ui, sf::RenderWindow &window, routing::Router& router) : + $status_ui(status_ui), + $loot_ui(loot_ui), + $window(window), + $router(router) + { + } + + bool DNDLoot::event(Event ev, std::any data) { + switch($state) { + FSM_STATE(DNDState, START, ev); + FSM_STATE(DNDState, LOOTING, ev, data); + FSM_STATE(DNDState, LOOT_GRAB, ev, data); + FSM_STATE(DNDState, INV_GRAB, ev, data); + FSM_STATE(DNDState, END, ev); + default: + dbc::log(fmt::format("event received with data but state={} is not handled", int($state))); + } + + return in_state(DNDState::END); + } + + void DNDLoot::START(Event ev) { + dbc::check(ev == Event::STARTED, "START not given a STARTED event."); + state(DNDState::LOOTING); + } + + void DNDLoot::LOOTING(Event ev, std::any data) { + using enum Event; + + switch(ev) { + case LOOT_OPEN: + $loot_ui.active = false; + state(DNDState::END); + break; + case LOOT_SELECT: + $grab_source = UISystem::loot_grab($loot_ui.$gui, data); + if($grab_source) state(DNDState::LOOT_GRAB); + break; + case INV_SELECT: + $grab_source = UISystem::loot_grab($status_ui.$gui, data); + if($grab_source) state(DNDState::INV_GRAB); + break; + case MOUSE_DRAG_START: + case MOUSE_CLICK: + mouse_action(false); + break; + default: + state(DNDState::LOOTING); + } + } + + void DNDLoot::LOOT_GRAB(Event ev, std::any data) { + using enum Event; + + switch(ev) { + case LOOT_OPEN: + $loot_ui.active = false; + state(DNDState::END); + break; + case LOOT_SELECT: + $grab_source = UISystem::loot_grab($loot_ui.$gui, data); + if($grab_source) state(DNDState::LOOTING); + break; + case INV_SELECT: + if(UISystem::loot_drop($loot_ui.$gui, + $status_ui.$gui, $grab_source, data)) + { + state(DNDState::LOOTING); + } + break; + case MOUSE_CLICK: + mouse_action(false); + break; + case MOUSE_DRAG: + case MOUSE_MOVE: { + if($grab_source) { + auto& source = $loot_ui.$gui.get(*$grab_source); + source.move($window.mapPixelToCoords($router.position)); + } + mouse_action(true); + } break; + case MOUSE_DRAG_START: + mouse_action(false); + break; + case MOUSE_DROP: + mouse_action(false); + break; + case TICK: + // do nothing + break; + default: + state(DNDState::LOOT_GRAB); + } + } + + void DNDLoot::INV_GRAB(Event ev, std::any data) { + using enum Event; + + switch(ev) { + case LOOT_OPEN: + $loot_ui.active = false; + state(DNDState::END); + break; + case LOOT_SELECT: + if(UISystem::loot_drop($status_ui.$gui, + $loot_ui.$gui, $grab_source, data)) + { + state(DNDState::LOOTING); + } + break; + case INV_SELECT: + $grab_source = UISystem::loot_grab($status_ui.$gui, data); + state(DNDState::LOOTING); + break; + case MOUSE_CLICK: + mouse_action(false); + break; + case MOUSE_DRAG: + case MOUSE_MOVE: { + if($grab_source) { + auto& source = $status_ui.$gui.get(*$grab_source); + source.move($window.mapPixelToCoords($router.position)); + } + mouse_action(true); + } break; + case MOUSE_DRAG_START: { + mouse_action(false); + } break; + case MOUSE_DROP: + mouse_action(false); + break; + default: + state(DNDState::INV_GRAB); + } + } + + void DNDLoot::END(Event ev) { + dbc::check(ev == Event::STARTED, "END not given a STARTED event."); + $grab_source = std::nullopt; + state(DNDState::LOOTING); + } + + sf::Vector2f DNDLoot::mouse_position() { + return $window.mapPixelToCoords($router.position); + } + + void DNDLoot::mouse_action(bool hover) { + sf::Vector2f pos = mouse_position(); + $status_ui.mouse(pos.x, pos.y, hover); + if($loot_ui.active) $loot_ui.mouse(pos.x, pos.y, hover); + } +} diff --git a/gui/dnd_loot.hpp b/gui/dnd_loot.hpp new file mode 100644 index 0000000..11ab269 --- /dev/null +++ b/gui/dnd_loot.hpp @@ -0,0 +1,39 @@ +#pragma once +#include "simplefsm.hpp" +#include +#include "gui/status_ui.hpp" +#include "gui/loot_ui.hpp" +#include "gui/event_router.hpp" + +namespace gui { + enum class DNDState { + START=0, + LOOTING=1, + LOOT_GRAB=2, + INV_GRAB=3, + END=4 + }; + + class DNDLoot : public DeadSimpleFSM { + public: + std::optional $grab_source = std::nullopt; + StatusUI& $status_ui; + LootUI& $loot_ui; + sf::RenderWindow& $window; + routing::Router& $router; + + DNDLoot(StatusUI status_ui, + LootUI loot_ui, sf::RenderWindow& window, + routing::Router& router); + + bool event(Event ev, std::any data={}); + + void START(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 mouse_action(bool hover); + sf::Vector2f mouse_position(); + }; +} diff --git a/gui/fsm.cpp b/gui/fsm.cpp index ed2adb8..34b6962 100644 --- a/gui/fsm.cpp +++ b/gui/fsm.cpp @@ -1,3 +1,4 @@ +#define FSM_DEBUG 1 #include "gui/fsm.hpp" #include #include @@ -26,12 +27,13 @@ namespace gui { $map_ui($level), $mini_map($level), $loot_ui($level), - $font{FONT_FILE_NAME} + $font{FONT_FILE_NAME}, + $dnd_loot($status_ui, $loot_ui, $window, $router) { $window.setPosition({0,0}); } - void FSM::event(Event ev) { + void FSM::event(Event ev, std::any data) { switch($state) { FSM_STATE(State, START, ev); FSM_STATE(State, MOVING, ev); @@ -42,20 +44,7 @@ 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(-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 received with data but state={} is not handled", int($state))); } } @@ -125,113 +114,11 @@ namespace gui { } } - void FSM::LOOT_GRAB(Event ev, std::any data) { - using enum Event; - - switch(ev) { - case LOOT_OPEN: - $loot_ui.active = false; - state(State::IDLE); - break; - case LOOT_SELECT: - $grab_source = UISystem::loot_grab($loot_ui.$gui, data); - if($grab_source) state(State::LOOTING); - break; - case INV_SELECT: - if(UISystem::loot_drop($loot_ui.$gui, - $status_ui.$gui, $grab_source, data)) - { - state(State::LOOTING); - } - break; - case MOUSE_CLICK: - mouse_action(false); - break; - case MOUSE_DRAG: - case MOUSE_MOVE: { - if($grab_source) { - auto& source = $loot_ui.$gui.get(*$grab_source); - source.move($window.mapPixelToCoords($router.position)); - } - mouse_action(true); - } break; - case MOUSE_DRAG_START: - mouse_action(false); - 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; - - switch(ev) { - case LOOT_OPEN: - $loot_ui.active = false; - state(State::IDLE); - break; - case LOOT_SELECT: - if(UISystem::loot_drop($status_ui.$gui, - $loot_ui.$gui, $grab_source, data)) - { - state(State::LOOTING); - } - break; - case INV_SELECT: - $grab_source = UISystem::loot_grab($status_ui.$gui, data); - state(State::LOOTING); - break; - case MOUSE_CLICK: - mouse_action(false); - break; - case MOUSE_DRAG: - case MOUSE_MOVE: { - if($grab_source) { - auto& source = $status_ui.$gui.get(*$grab_source); - source.move($window.mapPixelToCoords($router.position)); - } - mouse_action(true); - } break; - case MOUSE_DRAG_START: { - mouse_action(false); - } break; - case MOUSE_DROP: - mouse_action(false); - break; - 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: - $grab_source = UISystem::loot_grab($loot_ui.$gui, data); - if($grab_source) state(State::LOOT_GRAB); - break; - case INV_SELECT: - $grab_source = UISystem::loot_grab($status_ui.$gui, data); - if($grab_source) state(State::INV_GRAB); - break; - case MOUSE_DRAG_START: - case MOUSE_CLICK: - mouse_action(false); - break; - default: - state(State::LOOTING); + if(!$dnd_loot.event(ev, data)) { + state(State::IDLE); + } else { + dbc::log("!!!!!!!!! LOOTING ENDED!"); } } @@ -283,6 +170,7 @@ namespace gui { state(State::NEXT_LEVEL); break; case LOOT_OPEN: + $dnd_loot.event(Event::STARTED); $loot_ui.active = true; state(State::LOOTING); break; @@ -386,8 +274,11 @@ namespace gui { if($debug_ui.active) $debug_ui.mouse(pos.x, pos.y, hover); $combat_ui.mouse(pos.x, pos.y, hover); $status_ui.mouse(pos.x, pos.y, hover); - $main_ui.mouse(pos.x, pos.y, hover); - if($loot_ui.active) $loot_ui.mouse(pos.x, pos.y, hover); + if($loot_ui.active) { + $loot_ui.mouse(pos.x, pos.y, hover); + } else { + $main_ui.mouse(pos.x, pos.y, hover); + } } void FSM::handle_keyboard_mouse() { @@ -582,10 +473,6 @@ namespace gui { case eGUI::NEW_RITUAL: $combat_ui.init(); break; - case eGUI::EVADE: - case eGUI::BLOCK: - dbc::log("YOU NEED TO IMPLEMENT THIS!!!!!"); - break; case eGUI::ATTACK: $temp_attack_id = std::any_cast(data); event(Event::ATTACK); diff --git a/gui/fsm.hpp b/gui/fsm.hpp index 5351477..f3e9182 100644 --- a/gui/fsm.hpp +++ b/gui/fsm.hpp @@ -13,6 +13,7 @@ #include "gui/mini_map.hpp" #include "events.hpp" #include "gui/event_router.hpp" +#include "gui/dnd_loot.hpp" namespace gui { enum class State { @@ -24,10 +25,8 @@ namespace gui { ROTATING=5, NEXT_LEVEL=6, LOOTING=7, - LOOT_GRAB=8, - INV_GRAB=9, - IDLE=10, - END=11 + IDLE=8, + END=9 }; class FSM : public DeadSimpleFSM { @@ -49,12 +48,11 @@ namespace gui { LootUI $loot_ui; sf::Font $font; gui::routing::Router $router; - std::optional $grab_source; + DNDLoot $dnd_loot; FSM(); - void event(Event ev); - void event(Event ev, std::any data); + void event(Event ev, std::any data={}); void autowalk(); void start_autowalk(double rot_speed); @@ -68,8 +66,6 @@ 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/main.cpp b/main.cpp index 60d513a..9ba9bfc 100644 --- a/main.cpp +++ b/main.cpp @@ -35,8 +35,6 @@ 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) { @@ -45,6 +43,7 @@ int main(int argc, char* argv[]) { main.handle_keyboard_mouse(); } } else{ + dbc::log("NOT IN STATE"); main.event(gui::Event::TICK); } diff --git a/meson.build b/meson.build index 83503cf..647c36d 100644 --- a/meson.build +++ b/meson.build @@ -95,6 +95,7 @@ sources = [ 'gui/boss_fight_ui.cpp', 'gui/combat_ui.cpp', 'gui/debug_ui.cpp', + 'gui/dnd_loot.cpp', 'gui/event_router.cpp', 'gui/fsm.cpp', 'gui/guecstra.cpp',