diff --git a/animation.cpp b/animation.cpp index e98382c..9089b96 100644 --- a/animation.cpp +++ b/animation.cpp @@ -113,6 +113,8 @@ namespace components { current = 0; subframe = 0.0f; } + + if(end_cb) end_cb(); } void Animation::step(sf::Vector2f& scale_out, sf::Vector2f& pos_out, sf::IntRect& rect_out) { diff --git a/boss/fight.cpp b/boss/fight.cpp index 7504f7f..94f6f3c 100644 --- a/boss/fight.cpp +++ b/boss/fight.cpp @@ -1,3 +1,4 @@ +#define FSM_DEBUG 1 #include "boss/fight.hpp" #include "boss/system.hpp" #include "animation.hpp" @@ -31,6 +32,7 @@ namespace boss { FSM_STATE(State, START, ev, data); FSM_STATE(State, PLAYER_REQUESTS, ev, data); FSM_STATE(State, EXEC_PLAN, ev, data); + FSM_STATE(State, ANIMATE, ev, data); FSM_STATE(State, END, ev, data); } } @@ -88,28 +90,47 @@ namespace boss { state(State::END); break; case COMBAT_START: - $ui.status(L"X TURN", L"STEP"); + $ui.status(L"EXEC PLAN", L"ANIMATE"); next_combat(); break; case COMBAT: do_combat(data); + state(State::ANIMATE); break; default: break; } } + void Fight::ANIMATE(game::Event ev, std::any data) { + using enum game::Event; + + switch(ev) { + case ANIMATION_END: + $ui.status(L"ANIMATE END", L"NEXT"); + next_combat(); + break; + default: + // ignored + break; + } + } + void Fight::END(game::Event ev, std::any) { fmt::println("BOSS_FIGHT:END event {}", (int)ev); } void Fight::next_combat() { if(auto action = $battle.next()) { + fmt::println("next combat has action"); System::combat(*action, $world, $boss_id, 0); + state(State::EXEC_PLAN); } else if(player_dead()) { + fmt::println("player died"); $ui.status(L"YOU DIED", L"DEAD"); state(State::END); } else { + fmt::println("end combat next turn"); $ui.status(L"PLAYER REQUESTS", L"COMMIT"); $ui.reset_camera(); $battle.ap_refresh(); @@ -131,17 +152,29 @@ namespace boss { case BattleHostState::disagree: { std::string player_move = Random::uniform(0, 1) == 0 ? "player1" : "player3"; $ui.move_actor("player", player_move); - if(result.player_did > 0) $ui.animate_actor("player"); + if(result.player_did > 0) { + $ui.animate_actor("player"); + } else { + // NO need a no animation event + $ui.animate_actor("player"); + } $ui.damage("player", "boss", result.player_did); } break; case BattleHostState::not_host: { std::string boss_move = Random::uniform(0, 1) == 0 ? "boss5" : "boss6"; $ui.move_actor("boss", boss_move); - if(result.enemy_did > 0) $ui.animate_actor("boss"); + if(result.enemy_did > 0) { + $ui.animate_actor("boss"); + } else { + // NO need a no animation event + $ui.animate_actor("boss"); + } $ui.damage("boss", "player", result.enemy_did); } break; case BattleHostState::out_of_ap: + // NO need an out of AP animation + $ui.animate_actor("player"); break; } diff --git a/boss/fight.hpp b/boss/fight.hpp index 753404a..6485db3 100644 --- a/boss/fight.hpp +++ b/boss/fight.hpp @@ -16,6 +16,7 @@ namespace boss { START=__LINE__, PLAYER_REQUESTS=__LINE__, EXEC_PLAN=__LINE__, + ANIMATE=__LINE__, END=__LINE__ }; @@ -42,6 +43,7 @@ namespace boss { void START(game::Event ev, std::any data); void PLAYER_REQUESTS(game::Event ev, std::any data); void EXEC_PLAN(game::Event ev, std::any data); + void ANIMATE(game::Event ev, std::any data); void END(game::Event ev, std::any data); void render(sf::RenderWindow& window); diff --git a/boss/ui.cpp b/boss/ui.cpp index 130ed3f..77fc8c0 100644 --- a/boss/ui.cpp +++ b/boss/ui.cpp @@ -21,6 +21,10 @@ namespace boss { $view_texture({BOSS_VIEW_WIDTH, BOSS_VIEW_HEIGHT}), $view_sprite($view_texture.getTexture()) { + $arena.set_end_cb([&]() { + $world->send(game::Event::ANIMATION_END, DinkyECS::NONE, {}); + }); + $view_sprite.setPosition({BOSS_VIEW_X, BOSS_VIEW_Y}); } diff --git a/components.hpp b/components.hpp index 5f85c61..422eea0 100644 --- a/components.hpp +++ b/components.hpp @@ -156,6 +156,7 @@ namespace components { bool toggled = false; bool looped = false; bool flipped = false; + std::function end_cb = nullptr; int current = 0; bool playing = false; diff --git a/events.hpp b/events.hpp index ecb6a0c..55efbb3 100644 --- a/events.hpp +++ b/events.hpp @@ -3,6 +3,8 @@ namespace game { enum Event { AIM_CLICK=__LINE__, + ANIMATION_END=__LINE__, + ANIMATION_START=__LINE__, ATTACK=__LINE__, BOSS_END=__LINE__, BOSS_START=__LINE__, diff --git a/scene.cpp b/scene.cpp index 8474b94..4d0e6d9 100644 --- a/scene.cpp +++ b/scene.cpp @@ -177,6 +177,12 @@ namespace scene { zoom(mid_x, mid_y, style, scale); } + void Engine::set_end_cb(std::function cb) { + for(auto& actor : $actors) { + actor.anim.end_cb = cb; + } + } + void Engine::reset(sf::RenderTexture& view) { $camera.reset(view); } diff --git a/scene.hpp b/scene.hpp index a18b55e..ea793c8 100644 --- a/scene.hpp +++ b/scene.hpp @@ -7,6 +7,7 @@ #include #include #include "camera.hpp" +#include namespace scene { using std::shared_ptr; @@ -56,5 +57,6 @@ namespace scene { void zoom(const std::string& actor, const std::string& style, float scale=0.9f); void zoom(float mid_x, float mid_y, const std::string& style, float scale); void reset(sf::RenderTexture& view); + void set_end_cb(std::function cb); }; } diff --git a/simplefsm.hpp b/simplefsm.hpp index 8729dd8..b2378cc 100644 --- a/simplefsm.hpp +++ b/simplefsm.hpp @@ -5,7 +5,8 @@ #ifndef FSM_DEBUG #define FSM_STATE(C, S, E, ...) case C::S: S(E, ##__VA_ARGS__); break #else -#define FSM_STATE(C, S, E, ...) case C::S: fmt::println(">> " #C " " #S " event={}, state={}", int(E), int($state)); S(E, ##__VA_ARGS__); fmt::println("<< " #C " state={}", int($state)); break +int last_event=-1; +#define FSM_STATE(C, S, E, ...) case C::S: if(last_event != int(E)) { last_event = int(E); fmt::println(">> " #C " " #S " event={}, state={}", int(E), int($state));}; S(E, ##__VA_ARGS__); break #endif template @@ -19,6 +20,9 @@ public: void event(E event, Types... args); void state(S next_state) { +#ifdef FSM_DEBUG + fmt::println("<< STATE: {} -> {}", int($state), int(next_state)); +#endif $state = next_state; }