Cleaned everything up more so that it's using better events, but I need to rewrite the event handlers.

This commit is contained in:
Zed A. Shaw 2026-04-08 13:50:38 -04:00
parent 1179d6eb43
commit a47e004d37
6 changed files with 47 additions and 129 deletions

View file

@ -17,7 +17,7 @@
"[_]" "[_]"
], ],
"actions": { "actions": {
"Restart": 43, "Restart": 51,
"Quit": 38 "Quit": 38
} }
} }
@ -42,7 +42,7 @@
"[_]" "[_]"
], ],
"actions": { "actions": {
"Continue": 43, "Continue": 50,
"Quit": 38 "Quit": 38
} }
} }
@ -66,7 +66,6 @@
], ],
"actions": { "actions": {
"Start": 43, "Start": 43,
"About": 43,
"Quit": 38 "Quit": 38
} }
} }
@ -89,7 +88,7 @@
"[_]" "[_]"
], ],
"actions": { "actions": {
"Restart": 43, "Restart": 51,
"Quit": 38 "Quit": 38
} }
} }

View file

@ -46,5 +46,8 @@ namespace game {
UPDATE_SPRITE=__LINE__, UPDATE_SPRITE=__LINE__,
USE_ITEM=__LINE__, USE_ITEM=__LINE__,
LEVEL_UP=__LINE__, LEVEL_UP=__LINE__,
WIN=__LINE__,
NEXT_LEVEL=__LINE__,
NEW_GAME=__LINE__,
}; };
} }

View file

@ -1,3 +1,4 @@
#define FSM_DEBUG 1
#include "gui/fsm.hpp" #include "gui/fsm.hpp"
#include <iostream> #include <iostream>
#include <chrono> #include <chrono>
@ -29,18 +30,14 @@ namespace gui {
switch($state) { switch($state) {
FSM_STATE(State, START, ev); FSM_STATE(State, START, ev);
FSM_STATE(State, INTRO, ev); FSM_STATE(State, INTRO, ev);
FSM_STATE(State, START_SCENE, ev); FSM_STATE(State, SHOW_SCREEN, ev);
FSM_STATE(State, DEATH_SCENE, ev);
FSM_STATE(State, WIN_SCENE, ev);
FSM_STATE(State, NEXT_LEVEL_SCENE, ev);
FSM_STATE(State, MOVING, ev); FSM_STATE(State, MOVING, ev);
FSM_STATE(State, ATTACKING, ev, data); FSM_STATE(State, ATTACKING, ev, data);
FSM_STATE(State, ROTATING, ev); FSM_STATE(State, ROTATING, ev);
FSM_STATE(State, IDLE, ev, data); FSM_STATE(State, IDLE, ev, data);
FSM_STATE(State, LOOTING, ev, data); FSM_STATE(State, LOOTING, ev, data);
FSM_STATE(State, END_QUIT, ev); FSM_STATE(State, END_QUIT, ev);
FSM_STATE(State, END_PLAY_AGAIN, ev); FSM_STATE(State, END_NEW_GAME, ev);
FSM_STATE(State, END_PLAYER_DIED, ev);
} }
} }
@ -60,7 +57,6 @@ namespace gui {
run_systems(); run_systems();
show_scene("STARTING"); show_scene("STARTING");
state(State::START_SCENE);
} }
void FSM::INTRO(Event ev) { void FSM::INTRO(Event ev) {
@ -76,7 +72,7 @@ namespace gui {
} }
} }
void FSM::START_SCENE(Event ev) { void FSM::SHOW_SCREEN(Event ev) {
using enum Event; using enum Event;
switch(ev) { switch(ev) {
@ -84,7 +80,7 @@ namespace gui {
mouse_action(guecs::NO_MODS); mouse_action(guecs::NO_MODS);
break; break;
case MOUSE_MOVE: { case MOUSE_MOVE: {
mouse_action({1 << guecs::ModBit::hover}); mouse_action({1 << guecs::ModBit::hover});
} break; } break;
case START: case START:
close_scene(); close_scene();
@ -92,6 +88,15 @@ namespace gui {
$story->init(); $story->init();
state(State::INTRO); state(State::INTRO);
break; break;
case NEW_GAME:
close_scene();
state(State::END_NEW_GAME);
break;
case NEXT_LEVEL:
next_level();
close_scene();
state(State::IDLE);
break;
case QUIT: case QUIT:
FSM::IDLE(ev, {}); FSM::IDLE(ev, {});
break; break;
@ -103,73 +108,6 @@ namespace gui {
} }
} }
void FSM::DEATH_SCENE(Event ev) {
using enum Event;
switch(ev) {
case MOUSE_CLICK:
mouse_action(guecs::NO_MODS);
break;
case MOUSE_MOVE: {
mouse_action({1 << guecs::ModBit::hover});
} break;
case START:
close_scene();
state(State::END_PLAYER_DIED);
break;
case QUIT:
FSM::IDLE(ev, {});
break;
default:
break;
}
}
void FSM::WIN_SCENE(Event ev) {
using enum Event;
switch(ev) {
case MOUSE_CLICK:
mouse_action(guecs::NO_MODS);
break;
case MOUSE_MOVE: {
mouse_action({1 << guecs::ModBit::hover});
} break;
case START:
close_scene();
state(State::END_PLAY_AGAIN);
break;
case QUIT:
FSM::IDLE(ev, {});
break;
default:
break;
}
}
void FSM::NEXT_LEVEL_SCENE(Event ev) {
using enum Event;
switch(ev) {
case MOUSE_CLICK:
mouse_action(guecs::NO_MODS);
break;
case MOUSE_MOVE: {
mouse_action({1 << guecs::ModBit::hover});
} break;
case START:
next_level();
close_scene();
state(State::IDLE);
break;
case QUIT:
FSM::IDLE(ev, {});
break;
default:
break;
}
}
void FSM::MOVING(Event ) { void FSM::MOVING(Event ) {
// this should be an optional that returns a point // this should be an optional that returns a point
if(auto move_to = $main_ui.play_move()) { if(auto move_to = $main_ui.play_move()) {
@ -311,14 +249,10 @@ namespace gui {
dbc::log($F("END_QUIT: received event after done: {}", int(ev))); dbc::log($F("END_QUIT: received event after done: {}", int(ev)));
} }
void FSM::END_PLAYER_DIED(Event ev) { void FSM::END_NEW_GAME(Event ev) {
dbc::log($F("END_PLAYER_DIED: received event after done: {}", int(ev))); dbc::log($F("END_PLAYER_DIED: received event after done: {}", int(ev)));
} }
void FSM::END_PLAY_AGAIN(Event ev) {
dbc::log($F("END_PLAY_AGAIN: received event after done: {}", int(ev)));
}
sf::Vector2f FSM::mouse_position() { sf::Vector2f FSM::mouse_position() {
return $window.mapPixelToCoords($router.position); return $window.mapPixelToCoords($router.position);
} }
@ -454,8 +388,7 @@ namespace gui {
bool FSM::active() { bool FSM::active() {
return !(in_state(State::END_QUIT) return !(in_state(State::END_QUIT)
|| in_state(State::END_PLAY_AGAIN) || in_state(State::END_NEW_GAME));
|| in_state(State::END_PLAYER_DIED));
} }
void FSM::handle_world_events() { void FSM::handle_world_events() {
@ -473,9 +406,6 @@ namespace gui {
auto &damage = std::any_cast<components::CombatResult&>(data); auto &damage = std::any_cast<components::CombatResult&>(data);
} }
break; break;
case eGUI::COMBAT_START:
event(Event::COMBAT_START);
break;
case eGUI::ENTITY_SPAWN: { case eGUI::ENTITY_SPAWN: {
auto& sprite = world->get<components::Sprite>(entity); auto& sprite = world->get<components::Sprite>(entity);
$main_ui.$rayview->update_sprite(entity, sprite); $main_ui.$rayview->update_sprite(entity, sprite);
@ -489,9 +419,6 @@ namespace gui {
// BUG: need to resolve GUI events vs. FSM events better // BUG: need to resolve GUI events vs. FSM events better
event(Event::LOOT_OPEN); event(Event::LOOT_OPEN);
break; break;
case eGUI::LOOT_SELECT:
event(Event::LOOT_SELECT, data);
break;
case eGUI::INV_SELECT: { case eGUI::INV_SELECT: {
if($router.left_button) { if($router.left_button) {
event(Event::INV_SELECT, data); event(Event::INV_SELECT, data);
@ -499,9 +426,6 @@ namespace gui {
event(Event::USE_ITEM, data); event(Event::USE_ITEM, data);
} }
} break; } break;
case eGUI::AIM_CLICK:
event(Event::AIM_CLICK);
break;
case eGUI::LOOT_ITEM: { case eGUI::LOOT_ITEM: {
dbc::check(world->has<components::InventoryItem>(entity), dbc::check(world->has<components::InventoryItem>(entity),
"INVALID LOOT_ITEM, that entity has no InventoryItem"); "INVALID LOOT_ITEM, that entity has no InventoryItem");
@ -513,15 +437,26 @@ namespace gui {
$loot_ui.update(); $loot_ui.update();
event(Event::LOOT_OPEN); event(Event::LOOT_OPEN);
} break; } break;
case eGUI::ATTACK:
event(Event::ATTACK, data);
break;
case eGUI::STAIRS_DOWN: case eGUI::STAIRS_DOWN:
check_player_wins(); check_player_wins();
break; break;
case eGUI::START:
event(Event::START, data); case eGUI::COMBAT_START:
case eGUI::AIM_CLICK:
event(game::Event(evt));
break; break;
case eGUI::LOOT_SELECT:
case eGUI::ATTACK:
case eGUI::QUIT:
case eGUI::WIN:
case eGUI::START:
case eGUI::NEXT_LEVEL:
case eGUI::NEW_GAME:
event(game::Event(evt), data);
break;
case eGUI::DEATH: { case eGUI::DEATH: {
$status_ui.update(); $status_ui.update();
@ -531,11 +466,6 @@ namespace gui {
player_died(); player_died();
} }
} break; } break;
case eGUI::NOOP: {
if(data.type() == typeid(std::string)) {
auto name = std::any_cast<std::string>(data);
}
} break;
default: default:
dbc::log($F("Unhandled event: evt={}; enemy={}; data={}", dbc::log($F("Unhandled event: evt={}; enemy={}; data={}",
evt, entity, data.type().name())); evt, entity, data.type().name()));
@ -566,6 +496,7 @@ namespace gui {
void FSM::show_scene(const std::string& name) { void FSM::show_scene(const std::string& name) {
$screens.set_active(name); $screens.set_active(name);
$screens.set_visible(true); $screens.set_visible(true);
state(State::SHOW_SCREEN);
} }
void FSM::close_scene() { void FSM::close_scene() {
@ -574,7 +505,6 @@ namespace gui {
void FSM::player_died() { void FSM::player_died() {
show_scene("DEATH"); show_scene("DEATH");
state(State::DEATH_SCENE);
} }
void FSM::check_player_wins() { void FSM::check_player_wins() {
@ -585,10 +515,8 @@ namespace gui {
if(level.index < levels_to_win) { if(level.index < levels_to_win) {
show_scene("NEXT_LEVEL"); show_scene("NEXT_LEVEL");
$screens.active_ui()->set_text(fmt::format("ENTERING\nLEVEL\n{}", level.index+2)); $screens.active_ui()->set_text(fmt::format("ENTERING\nLEVEL\n{}", level.index+2));
state(State::NEXT_LEVEL_SCENE);
} else { } else {
show_scene("WIN"); show_scene("WIN");
state(State::WIN_SCENE);
} }
} }

View file

@ -19,18 +19,14 @@ namespace gui {
enum class State { enum class State {
START=__LINE__, START=__LINE__,
INTRO=__LINE__, INTRO=__LINE__,
START_SCENE=__LINE__, SHOW_SCREEN=__LINE__,
DEATH_SCENE=__LINE__,
WIN_SCENE=__LINE__,
NEXT_LEVEL_SCENE=__LINE__,
MOVING=__LINE__, MOVING=__LINE__,
ATTACKING=__LINE__, ATTACKING=__LINE__,
ROTATING=__LINE__, ROTATING=__LINE__,
LOOTING=__LINE__, LOOTING=__LINE__,
IDLE=__LINE__, IDLE=__LINE__,
END_QUIT=__LINE__, END_QUIT=__LINE__,
END_PLAYER_DIED=__LINE__, END_NEW_GAME=__LINE__,
END_PLAY_AGAIN=__LINE__,
}; };
class FSM : public DeadSimpleFSM<State, game::Event> { class FSM : public DeadSimpleFSM<State, game::Event> {
@ -61,10 +57,7 @@ namespace gui {
void START(game::Event ev); void START(game::Event ev);
void INTRO(game::Event ev); void INTRO(game::Event ev);
void START_SCENE(game::Event ev); void SHOW_SCREEN(game::Event ev);
void WIN_SCENE(game::Event ev);
void DEATH_SCENE(game::Event ev);
void NEXT_LEVEL_SCENE(game::Event ev);
void IDLE(game::Event ev, std::any data); void IDLE(game::Event ev, std::any data);
void MOVING(game::Event ev); void MOVING(game::Event ev);
void ATTACKING(game::Event ev, std::any data); void ATTACKING(game::Event ev, std::any data);
@ -72,8 +65,7 @@ namespace gui {
void ROTATING(game::Event ev); void ROTATING(game::Event ev);
void LOOTING(game::Event ev, std::any data); void LOOTING(game::Event ev, std::any data);
void END_QUIT(game::Event ev); void END_QUIT(game::Event ev);
void END_PLAYER_DIED(game::Event ev); void END_NEW_GAME(game::Event ev);
void END_PLAY_AGAIN(game::Event ev);
void try_move(int dir, bool strafe); void try_move(int dir, bool strafe);
sf::Vector2f mouse_position(); sf::Vector2f mouse_position();

View file

@ -6,6 +6,7 @@ namespace guecs {
Clickable make_action(guecs::Entity gui_id, game::Event event) { Clickable make_action(guecs::Entity gui_id, game::Event event) {
return {[&, gui_id, event](auto){ return {[&, gui_id, event](auto){
auto world = GameDB::current_world(); auto world = GameDB::current_world();
fmt::println("!!!!! SENDING EVENT: {}", int(event));
world->send<game::Event>(event, gui_id, {}); world->send<game::Event>(event, gui_id, {});
}}; }};
} }
@ -13,6 +14,7 @@ namespace guecs {
Clickable make_action(guecs::Entity gui_id, game::Event event, std::any data) { Clickable make_action(guecs::Entity gui_id, game::Event event, std::any data) {
return {[&, event, data](auto){ return {[&, event, data](auto){
auto world = GameDB::current_world(); auto world = GameDB::current_world();
fmt::println("!!!!! SENDING EVENT with data: {}", int(event));
world->send<game::Event>(event, gui_id, data); world->send<game::Event>(event, gui_id, data);
}}; }};
} }

View file

@ -20,11 +20,8 @@ void play_game(std::shared_ptr<gui::FSM> main) {
// BUG: need to sort out how to deal with this in the FSM // BUG: need to sort out how to deal with this in the FSM
if(main->in_state(gui::State::IDLE) if(main->in_state(gui::State::IDLE)
|| main->in_state(gui::State::START_SCENE) || main->in_state(gui::State::SHOW_SCREEN)
|| main->in_state(gui::State::INTRO) || main->in_state(gui::State::INTRO)
|| main->in_state(gui::State::WIN_SCENE)
|| main->in_state(gui::State::DEATH_SCENE)
|| main->in_state(gui::State::NEXT_LEVEL_SCENE)
|| main->in_state(gui::State::LOOTING)) || main->in_state(gui::State::LOOTING))
{ {
main->handle_keyboard_mouse(); main->handle_keyboard_mouse();
@ -60,10 +57,7 @@ int main(int argc, char* argv[]) {
if(main->in_state(gui::State::END_QUIT)) { if(main->in_state(gui::State::END_QUIT)) {
return 0; return 0;
} else if(main->in_state(gui::State::END_PLAYER_DIED)) { } else if(main->in_state(gui::State::END_NEW_GAME)) {
System::restart();
main = std::make_shared<gui::FSM>(window);
} else if(main->in_state(gui::State::END_PLAY_AGAIN)) {
System::restart(); System::restart();
main = std::make_shared<gui::FSM>(window); main = std::make_shared<gui::FSM>(window);
} else { } else {