FSM now working better with animations spawning again. Still need to resolve enemies that run away jumping around, which is caused by run_systems() too much.

This commit is contained in:
Zed A. Shaw 2026-08-10 14:30:05 -04:00
parent 2b68696328
commit adcfbb883e
4 changed files with 59 additions and 23 deletions

View file

@ -37,7 +37,7 @@ tracy_build:
meson compile -j 10 -C builddir meson compile -j 10 -C builddir
test: build test: build
./builddir/fuc2it -d yes ./builddir/fuc2it yes
run: build test run: build test
ifeq '$(OS)' 'Windows_NT' ifeq '$(OS)' 'Windows_NT'

View file

@ -190,7 +190,7 @@ void System::distribute_loot(Position target_pos) {
} }
set_position(world, *level.collision, loot_entity, target_pos); set_position(world, *level.collision, loot_entity, target_pos);
level.world->send<game::Event>(game::Event::ENTITY_SPAWN, loot_entity, {}); level.world->send<game::Event>(game::Event::ENTITY_SPAWN, loot_entity, {loot_entity});
} }
void System::death() { void System::death() {
@ -209,8 +209,9 @@ void System::death() {
// we won't change out the player's components later // we won't change out the player's components later
dead_things.push_back(ent); dead_things.push_back(ent);
} }
// we need to send this event for everything that dies // we need to send this event for everything that dies
world.send<game::Event>(game::Event::DEATH, ent, {}); world.send<game::Event>(game::Event::DEATH, ent, {ent});
} else if(combat.almost_dead()) { } else if(combat.almost_dead()) {
// if enemies are below 50% health they are marked with bad health // if enemies are below 50% health they are marked with bad health
if(world.has<ai::EntityAI>(ent)) { if(world.has<ai::EntityAI>(ent)) {
@ -473,7 +474,7 @@ void System::drop_item(Entity item) {
set_position(world, *level.collision, item, drop_spot); set_position(world, *level.collision, item, drop_spot);
level.world->not_constant(item); level.world->not_constant(item);
level.world->send<game::Event>(game::Event::ENTITY_SPAWN, item, {}); level.world->send<game::Event>(game::Event::ENTITY_SPAWN, item, {item});
} }
// NOTE: I think pickup and this need to be different // NOTE: I think pickup and this need to be different

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>
@ -75,12 +76,30 @@ namespace gui {
} }
void FSM::ATTACKING(Event ev, std::any data) { void FSM::ATTACKING(Event ev, std::any data) {
// BUG: the way this locks animations is weird using enum Event;
switch(ev) {
case ENTITY_SPAWN:
entity_spawned(std::any_cast<DinkyECS::Entity>(data));
break;
case COMBAT:
break;
case COMBAT_START:
break;
case DEATH:
something_died(std::any_cast<DinkyECS::Entity>(data));
break;
case TICK:
run_systems();
if(!$main_ui.hands_playing()) { if(!$main_ui.hands_playing()) {
// run combat one more time // run combat one more time
$systems.runCombat(0);
state(State::IDLE); state(State::IDLE);
} }
break;
default:
dbc::log($F("Unhandled attacking event: {}", magic_enum::enum_name(ev)));
}
} }
void FSM::ROTATING(Event ev, std::any data) { void FSM::ROTATING(Event ev, std::any data) {
@ -142,7 +161,6 @@ namespace gui {
case ATTACK: case ATTACK:
$main_ui.play_hands(); $main_ui.play_hands();
$main_ui.dirty(); $main_ui.dirty();
sound::play("sword_hit_1");
$systems.runCombat(0); $systems.runCombat(0);
run_systems(); run_systems();
$status_ui.update(); $status_ui.update();
@ -204,22 +222,36 @@ namespace gui {
case NEW_RITUAL: case NEW_RITUAL:
$combat_ui.init(COMBAT_UI_X, COMBAT_UI_Y, COMBAT_UI_WIDTH, COMBAT_UI_HEIGHT); $combat_ui.init(COMBAT_UI_X, COMBAT_UI_Y, COMBAT_UI_WIDTH, COMBAT_UI_HEIGHT);
break; break;
case DEATH: { case DEATH:
// BUG: this is hot dogshit something_died(std::any_cast<DinkyECS::Entity>(data));
break;
case ENTITY_SPAWN:
entity_spawned(std::any_cast<DinkyECS::Entity>(data));
break;
default:
break; // ignore everything else
}
}
void FSM::entity_spawned(DinkyECS::Entity entity) {
auto world = GameDB::current_world();
auto& sprite = world->get<components::Sprite>(entity);
$main_ui.$rayview->update_sprite(entity, sprite);
$main_ui.dirty();
run_systems();
}
void FSM::something_died(DinkyECS::Entity entity) {
auto world = GameDB::current_world(); auto world = GameDB::current_world();
auto player = world->get_the<Player>(); auto player = world->get_the<Player>();
auto entity = std::any_cast<DinkyECS::Entity>(data);
$status_ui.update(); $status_ui.update();
if(entity != player.entity) { if(entity != player.entity) {
$main_ui.dead_entity(entity); $main_ui.dead_entity(entity);
} else { } else {
dbc::log("NEED TO HANDLE PLAYER DYING."); dbc::log("NEED TO HANDLE PLAYER DYING.");
} }
} break;
default:
break; // ignore everything else
}
} }
void FSM::CUT_SCENE_PLAYING(Event ev, std::any data) { void FSM::CUT_SCENE_PLAYING(Event ev, std::any data) {
@ -241,6 +273,7 @@ namespace gui {
void FSM::try_move(int dir, bool strafe) { void FSM::try_move(int dir, bool strafe) {
auto& level = GameDB::current_level(); auto& level = GameDB::current_level();
using enum State; using enum State;
// prevent moving into occupied space // prevent moving into occupied space
Point move_to = $main_ui.plan_move(dir, strafe); Point move_to = $main_ui.plan_move(dir, strafe);

View file

@ -80,5 +80,7 @@ namespace gui {
void next_level(bool bossfight); void next_level(bool bossfight);
void debug_render(); void debug_render();
void take_screenshot(); void take_screenshot();
void something_died(DinkyECS::Entity entity);
void entity_spawned(DinkyECS::Entity entity);
}; };
} }