diff --git a/src/async_op.h b/src/async_op.h index 6ee72bbc5ee..f39f85c7383 100644 --- a/src/async_op.h +++ b/src/async_op.h @@ -34,6 +34,7 @@ class AsyncOp { eNone, eShowScreen, eEraseScreen, + eCallInn, eToTitle, eExitGame }; @@ -46,6 +47,9 @@ class AsyncOp { /** @return an EraseScreen async operation */ static AsyncOp MakeEraseScreen(int transition_type); + /** @return an CallInn async operation */ + static AsyncOp MakeCallInn(); + /** @return a ToTitle async operation */ static AsyncOp MakeToTitle(); @@ -99,6 +103,10 @@ inline AsyncOp AsyncOp::MakeEraseScreen(int transition_type) { return AsyncOp(eEraseScreen, transition_type); } +inline AsyncOp AsyncOp::MakeCallInn() { + return AsyncOp(eCallInn); +} + inline AsyncOp AsyncOp::MakeToTitle() { return AsyncOp(eToTitle); } diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 331c9c7e2a1..72b4afef5e3 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -383,6 +383,11 @@ void Game_Interpreter::Update(bool reset_loop_count) { } } + // continuation triggered an async operation. + if (IsAsyncPending()) { + break; + } + if (Game_Map::GetNeedRefresh()) { Game_Map::Refresh(); } @@ -3333,6 +3338,5 @@ bool Game_Interpreter::DefaultContinuation(RPG::EventCommand const& /* com */) { bool Game_Interpreter::ContinuationOpenShop(RPG::EventCommand const& /* com */) { return true; } bool Game_Interpreter::ContinuationShowInnStart(RPG::EventCommand const& /* com */) { return true; } -bool Game_Interpreter::ContinuationShowInnFinish(RPG::EventCommand const& /* com */) { return true; } bool Game_Interpreter::ContinuationEnemyEncounter(RPG::EventCommand const& /* com */) { return true; } diff --git a/src/game_interpreter.h b/src/game_interpreter.h index 70215b43369..80cd8c507bd 100644 --- a/src/game_interpreter.h +++ b/src/game_interpreter.h @@ -252,7 +252,6 @@ class Game_Interpreter virtual bool ContinuationChoices(RPG::EventCommand const& com); virtual bool ContinuationOpenShop(RPG::EventCommand const& com); virtual bool ContinuationShowInnStart(RPG::EventCommand const& com); - virtual bool ContinuationShowInnFinish(RPG::EventCommand const& com); virtual bool ContinuationEnemyEncounter(RPG::EventCommand const& com); int DecodeInt(std::vector::const_iterator& it); diff --git a/src/game_interpreter_map.cpp b/src/game_interpreter_map.cpp index 9c09fa8c3e0..5697e3d6886 100644 --- a/src/game_interpreter_map.cpp +++ b/src/game_interpreter_map.cpp @@ -365,8 +365,7 @@ bool Game_Interpreter_Map::CommandShowInn(RPG::EventCommand const& com) { // cod if (Game_Temp::inn_price == 0) { // Skip prompt. Game_Message::choice_result = 0; - SetContinuation(static_cast(&Game_Interpreter_Map::ContinuationShowInnStart)); - return false; + return ContinuationShowInnStart(com); } Game_Message::message_waiting = true; @@ -462,7 +461,7 @@ bool Game_Interpreter_Map::CommandShowInn(RPG::EventCommand const& com) { // cod // save game compatibility with RPG_RT ReserveSubcommandIndex(com.indent); - return false; + return true; } bool Game_Interpreter_Map::ContinuationShowInnStart(RPG::EventCommand const& com) { @@ -484,64 +483,13 @@ bool Game_Interpreter_Map::ContinuationShowInnStart(RPG::EventCommand const& com if (inn_stay) { Main_Data::game_party->GainGold(-Game_Temp::inn_price); - // Full heal - std::vector actors = Main_Data::game_party->GetActors(); - for (Game_Actor* actor : actors) { - actor->FullHeal(); - } - Graphics::GetTransition().Init(Transition::TransitionFadeOut, Scene::instance.get(), 36, true); - Game_System::BgmFade(800); - SetContinuation(static_cast(&Game_Interpreter_Map::ContinuationShowInnContinue)); - return false; + _async_op = AsyncOp::MakeCallInn(); + return true; } - ++index; return true; } -bool Game_Interpreter_Map::ContinuationShowInnContinue(RPG::EventCommand const& /* com */) { - if (Graphics::IsTransitionPending()) - return false; - - const RPG::Music& bgm_inn = Game_System::GetSystemBGM(Game_System::BGM_Inn); - // FIXME: Abusing before_battle_music (Which is unused when calling an Inn) - // Is there also before_inn_music in the savegame? - Main_Data::game_data.system.before_battle_music = Game_System::GetCurrentBGM(); - - Game_System::BgmPlay(bgm_inn); - - SetContinuation(static_cast(&Game_Interpreter_Map::ContinuationShowInnFinish)); - - return false; -} - -bool Game_Interpreter_Map::ContinuationShowInnFinish(RPG::EventCommand const& com) { - auto* frame = GetFrame(); - assert(frame); - auto& index = frame->current_command; - - if (Graphics::IsTransitionPending()) - return false; - - const RPG::Music& bgm_inn = Game_System::GetSystemBGM(Game_System::BGM_Inn); - if (bgm_inn.name.empty() || - bgm_inn.name == "(OFF)" || - bgm_inn.name == "(Brak)" || - !Audio().BGM_IsPlaying() || - Audio().BGM_PlayedOnce()) { - - Game_System::BgmStop(); - continuation = NULL; - Graphics::GetTransition().Init(Transition::TransitionFadeIn, Scene::instance.get(), 36, false); - Game_System::BgmPlay(Main_Data::game_data.system.before_battle_music); - - ++index; - return false; - } - - return false; -} - bool Game_Interpreter_Map::CommandStay(RPG::EventCommand const& com) { // code 20730 return CommandOptionGeneric(com, eOptionInnStay, {Cmd::NoStay, Cmd::EndInn}); } diff --git a/src/game_interpreter_map.h b/src/game_interpreter_map.h index 70e7fd874b1..49ca33f2f65 100644 --- a/src/game_interpreter_map.h +++ b/src/game_interpreter_map.h @@ -84,8 +84,6 @@ class Game_Interpreter_Map : public Game_Interpreter bool ContinuationOpenShop(RPG::EventCommand const& com) override; bool ContinuationShowInnStart(RPG::EventCommand const& com) override; - bool ContinuationShowInnContinue(RPG::EventCommand const& com); - bool ContinuationShowInnFinish(RPG::EventCommand const& com) override; bool ContinuationEnemyEncounter(RPG::EventCommand const& com) override; static std::vector pending; diff --git a/src/scene_map.cpp b/src/scene_map.cpp index e2b9c3b8b3c..056f12b4d73 100644 --- a/src/scene_map.cpp +++ b/src/scene_map.cpp @@ -172,6 +172,10 @@ void Scene_Map::PreUpdate(MapUpdateAsyncContext& actx) { } void Scene_Map::Update() { + if (activate_inn) { + UpdateInn(); + return; + } MapUpdateAsyncContext actx; UpdateStage1(actx); } @@ -391,6 +395,55 @@ void Scene_Map::OnAsyncSuspend(F&& f, AsyncOp aop, bool is_preupdate) { Graphics::GetTransition().Init(tt, this, 32, false); } + if (aop.GetType() == AsyncOp::eCallInn) { + activate_inn = true; + music_before_inn = Game_System::GetCurrentBGM(); + inn_continuation = std::forward(f); + + Game_System::BgmFade(800); + + // FIXME: Is 36 correct here? + Graphics::GetTransition().Init(Transition::TransitionFadeOut, Scene::instance.get(), 36, true); + + AsyncNext([=]() { StartInn(); }); + return; + } + AsyncNext(std::forward(f)); } +void Scene_Map::StartInn() { + const RPG::Music& bgm_inn = Game_System::GetSystemBGM(Game_System::BGM_Inn); + if (bgm_inn.name.empty() || + bgm_inn.name == "(OFF)" || + bgm_inn.name == "(Brak)") { + FinishInn(); + return; + } + + Game_System::BgmStop(); + Game_System::BgmPlay(bgm_inn); +} + +void Scene_Map::FinishInn() { + // FIXME: Is 36 correct here? + Graphics::GetTransition().Init(Transition::TransitionFadeIn, Scene::instance.get(), 36, false); + // FIXME: Does this play before or after transition? + Game_System::BgmPlay(music_before_inn); + + // Full heal + std::vector actors = Main_Data::game_party->GetActors(); + for (Game_Actor* actor : actors) { + actor->FullHeal(); + } + + activate_inn = false; + AsyncNext(std::move(inn_continuation)); +} + +void Scene_Map::UpdateInn() { + if (!Audio().BGM_IsPlaying() || Audio().BGM_PlayedOnce()) { + Game_System::BgmStop(); + FinishInn(); + } +} diff --git a/src/scene_map.h b/src/scene_map.h index c42fdedf13f..636f3d58457 100644 --- a/src/scene_map.h +++ b/src/scene_map.h @@ -78,6 +78,10 @@ class Scene_Map: public Scene { void UpdateSceneCalling(); + void StartInn(); + void UpdateInn(); + void FinishInn(); + template void AsyncNext(F&& f); template void OnAsyncSuspend(F&& f, AsyncOp aop, bool is_preupdate); @@ -86,6 +90,10 @@ class Scene_Map: public Scene { int debug_menuoverwrite_counter = 0; bool from_save; bool screen_erased_by_event = false; + + RPG::Music music_before_inn = {}; + AsyncContinuation inn_continuation = {}; + bool activate_inn = false; }; #endif