From d94e872ef34e3f715f705150cf8107e3572cda35 Mon Sep 17 00:00:00 2001 From: Matthew Fioravante Date: Sat, 6 Apr 2019 15:38:01 -0400 Subject: [PATCH 01/14] add subcommand_path set/get methods --- src/game_interpreter.cpp | 33 +++++++++++++++++++++++++++++++++ src/game_interpreter.h | 5 +++++ 2 files changed, 38 insertions(+) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 4d411ae055..0e2e50c9f1 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -55,6 +55,11 @@ bool Game_Interpreter::to_title = false; bool Game_Interpreter::exit_game = false; + +constexpr int Game_Interpreter::loop_limit; +constexpr int Game_Interpreter::call_stack_limit; +constexpr int Game_Interpreter::subcommand_sentinel; + Game_Interpreter::Game_Interpreter(bool _main_flag) { main_flag = _main_flag; @@ -257,6 +262,34 @@ int Game_Interpreter::GetThisEventId() const { return event_id; } +uint8_t& Game_Interpreter::ReserveSubcommandIndex(int indent) { + auto* frame = GetFrame(); + assert(frame); + + auto& path = frame->subcommand_path; + if (indent >= (int)path.size()) { + // This fixes an RPG_RT bug where RPG_RT would resize + // the array with uninitialized values. + path.resize(indent + 1, subcommand_sentinel); + } + return path[indent]; +} + +void Game_Interpreter::SetSubcommandIndex(int indent, int idx) { + ReserveSubcommandIndex(indent) = idx; +} + +int Game_Interpreter::GetSubcommandIndex(int indent) const { + auto* frame = GetFrame(); + if (frame == nullptr) { + return subcommand_sentinel; + } + auto& path = frame->subcommand_path; + if ((int)path.size() <= indent) { + return subcommand_sentinel; + } + return path[indent]; +} // Update void Game_Interpreter::Update(bool reset_loop_count) { diff --git a/src/game_interpreter.h b/src/game_interpreter.h index 1132afd83d..0d70071223 100644 --- a/src/game_interpreter.h +++ b/src/game_interpreter.h @@ -107,6 +107,7 @@ class Game_Interpreter protected: static constexpr int loop_limit = 10000; static constexpr int call_stack_limit = 1000; + static constexpr int subcommand_sentinel = 255; static bool to_title; static bool exit_game; @@ -257,6 +258,10 @@ class Game_Interpreter const std::string DecodeString(std::vector::const_iterator& it); RPG::MoveCommand DecodeMove(std::vector::const_iterator& it); + void SetSubcommandIndex(int indent, int idx); + uint8_t& ReserveSubcommandIndex(int indent); + int GetSubcommandIndex(int indent) const; + FileRequestBinding request_id; enum class Keys { eDown, From 41a821512da50cdb612b3cae690bbc3920230603 Mon Sep 17 00:00:00 2001 From: Matthew Fioravante Date: Sun, 7 Apr 2019 13:46:50 -0400 Subject: [PATCH 02/14] Add SkipToNextConditional() --- src/game_interpreter.cpp | 21 +++++++++++++++++++++ src/game_interpreter.h | 12 ++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 0e2e50c9f1..a18fea9a84 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -492,6 +492,27 @@ bool Game_Interpreter::SkipTo(int code, int code2, int min_indent, int max_inden return true; } +void Game_Interpreter::SkipToNextConditional(std::initializer_list codes, int indent) { + auto* frame = GetFrame(); + assert(frame); + const auto& list = frame->commands; + auto& index = frame->current_command; + + if (index >= (int)list.size()) { + return; + } + + for (++index; index < (int)list.size(); ++index) { + const auto& com = list[index]; + if (com.indent > indent) { + continue; + } + if (std::find(codes.begin(), codes.end(), com.code) != codes.end()) { + break; + } + } +} + int Game_Interpreter::DecodeInt(std::vector::const_iterator& it) { int value = 0; diff --git a/src/game_interpreter.h b/src/game_interpreter.h index 0d70071223..655dc387b6 100644 --- a/src/game_interpreter.h +++ b/src/game_interpreter.h @@ -143,6 +143,18 @@ class Game_Interpreter Game_Character* GetCharacter(int character_id) const; bool SkipTo(int code, int code2 = -1, int min_indent = -1, int max_indent = -1, bool otherwise_end = false); + + /** + * Skips to the next option in a chain of conditional commands. + * Works by skipping until we hit the end or the next command + * with com.indent <= indent. + * The <= protects against broken game code which terminates without + * a proper conditional. + * + * @param codes which codes to check. + * @param indent the indentation level to check + */ + void SkipToNextConditional(std::initializer_list codes, int indent); void SetContinuation(ContinuationFunction func); /** From b48701e95883ac4e61be3207d234171594558bf4 Mon Sep 17 00:00:00 2001 From: Matthew Fioravante Date: Sat, 6 Apr 2019 15:46:20 -0400 Subject: [PATCH 03/14] ConditionalBranch - use subcommand_path --- src/game_interpreter.cpp | 57 +++++++++++++++++++++++++++++----------- src/game_interpreter.h | 4 +++ 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index a18fea9a84..5cfa0ec473 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -405,6 +405,7 @@ void Game_Interpreter::Update(bool reset_loop_count) { // Save the frame index before we call events. int current_frame_idx = _state.stack.size() - 1; + const int index_before_exec = frame->current_command; if (!ExecuteCommand()) { break; } @@ -419,14 +420,15 @@ void Game_Interpreter::Update(bool reset_loop_count) { continue; } - // FIXME? - // After calling SkipTo this index++ will skip execution of e.g. END. - // This causes a different timing because loop_count reaches 10000 - // faster then Player does. - // No idea if any game depends on this special case. // Note: In the case we executed a CallEvent command, be sure to // increment the old frame and not the new one we just pushed. - _state.stack[current_frame_idx].current_command++; + frame = &_state.stack[current_frame_idx]; + + // Only do auto increment if the command didn't manually + // change the index. + if (index_before_exec == frame->current_command) { + frame->current_command++; + } } // for if (loop_count > loop_limit - 1) { @@ -735,9 +737,9 @@ bool Game_Interpreter::ExecuteCommand() { case Cmd::ChangeBattleCommands: return CommandChangeBattleCommands(com); case Cmd::ElseBranch: - return SkipTo(Cmd::EndBranch); + return CommandElseBranch(com); case Cmd::EndBranch: - return true; + return CommandEndBranch(com); case Cmd::ExitGame: return CommandExitGame(com); case Cmd::ToggleFullscreen: @@ -813,6 +815,17 @@ std::vector Game_Interpreter::GetChoices() { return s_choices; } +bool Game_Interpreter::CommandOptionGeneric(RPG::EventCommand const& com, int option_sub_idx, std::initializer_list next) { + const auto sub_idx = GetSubcommandIndex(com.indent); + if (sub_idx == option_sub_idx) { + // Executes this option, so clear the subidx to skip all other options. + SetSubcommandIndex(com.indent, subcommand_sentinel); + } else { + SkipToNextConditional(next, com.indent); + } + return true; +} + bool Game_Interpreter::CommandShowMessage(RPG::EventCommand const& com) { // code 10110 auto* frame = GetFrame(); assert(frame); @@ -2897,9 +2910,10 @@ bool Game_Interpreter::CommandConditionalBranch(RPG::EventCommand const& com) { if (!actor) { Output::Warning("ConditionalBranch: Invalid actor ID %d", actor_id); - // Use Else branch - ++loop_count; - return SkipTo(Cmd::ElseBranch, Cmd::EndBranch); + // Use Else Branch + SetSubcommandIndex(com.indent, 1); + SkipToNextConditional({Cmd::ElseBranch, Cmd::EndBranch}, com.indent); + return true; } switch (com.parameters[2]) { @@ -3006,11 +3020,24 @@ bool Game_Interpreter::CommandConditionalBranch(RPG::EventCommand const& com) { Output::Warning("ConditionalBranch: Branch %d unsupported", com.parameters[0]); } - if (result) - return true; - ++loop_count; - return SkipTo(Cmd::ElseBranch, Cmd::EndBranch); + int sub_idx = subcommand_sentinel; + if (!result) { + sub_idx = 1; + SkipToNextConditional({Cmd::ElseBranch, Cmd::EndBranch}, com.indent); + } + + SetSubcommandIndex(com.indent, sub_idx); + return true; +} + + +bool Game_Interpreter::CommandElseBranch(RPG::EventCommand const& com) { //code 22010 + return CommandOptionGeneric(com, 1, {Cmd::EndBranch}); +} + +bool Game_Interpreter::CommandEndBranch(RPG::EventCommand const& com) { //code 22011 + return true; } bool Game_Interpreter::CommandJumpToLabel(RPG::EventCommand const& com) { // code 12120 diff --git a/src/game_interpreter.h b/src/game_interpreter.h index 655dc387b6..4993cf0b6a 100644 --- a/src/game_interpreter.h +++ b/src/game_interpreter.h @@ -181,6 +181,8 @@ class Game_Interpreter */ void CheckGameOver(); + bool CommandOptionGeneric(RPG::EventCommand const& com, int option_sub_idx, std::initializer_list next); + bool CommandShowMessage(RPG::EventCommand const& com); bool CommandMessageOptions(RPG::EventCommand const& com); bool CommandChangeFaceGraphic(RPG::EventCommand const& com); @@ -248,6 +250,8 @@ class Game_Interpreter bool CommandChangeSaveAccess(RPG::EventCommand const& com); bool CommandChangeMainMenuAccess(RPG::EventCommand const& com); bool CommandConditionalBranch(RPG::EventCommand const& com); + bool CommandElseBranch(RPG::EventCommand const& com); + bool CommandEndBranch(RPG::EventCommand const& com); bool CommandJumpToLabel(RPG::EventCommand const& com); bool CommandBreakLoop(RPG::EventCommand const& com); bool CommandEndLoop(RPG::EventCommand const& com); From 7fbcf8f97edfa74c7f1be077f59704aef683809c Mon Sep 17 00:00:00 2001 From: Matthew Fioravante Date: Sun, 7 Apr 2019 12:11:30 -0400 Subject: [PATCH 04/14] Branch battle - use subcommand path --- src/game_interpreter_battle.cpp | 33 +++++++++++++++++++++++++-------- src/game_interpreter_battle.h | 2 ++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/game_interpreter_battle.cpp b/src/game_interpreter_battle.cpp index eaeaa4fcd6..b5e2ca3d7a 100644 --- a/src/game_interpreter_battle.cpp +++ b/src/game_interpreter_battle.cpp @@ -70,9 +70,9 @@ bool Game_Interpreter_Battle::ExecuteCommand() { case Cmd::ConditionalBranch_B: return CommandConditionalBranchBattle(com); case Cmd::ElseBranch_B: - return SkipTo(Cmd::EndBranch_B); + return CommandElseBranchBattle(com); case Cmd::EndBranch_B: - return true; + return CommandEndBranchBattle(com); default: return Game_Interpreter::ExecuteCommand(); } @@ -357,8 +357,10 @@ bool Game_Interpreter_Battle::CommandConditionalBranchBattle(RPG::EventCommand c if (!actor) { Output::Warning("ConditionalBranchBattle: Invalid actor ID %d", com.parameters[1]); - // Use Else branch - return SkipTo(Cmd::ElseBranch_B, Cmd::EndBranch_B); + // Use Else Branch + SetSubcommandIndex(com.indent, 1); + SkipToNextConditional({Cmd::ElseBranch_B, Cmd::EndBranch_B}, com.indent); + return true; } result = actor->CanAct(); @@ -381,7 +383,9 @@ bool Game_Interpreter_Battle::CommandConditionalBranchBattle(RPG::EventCommand c if (!actor) { Output::Warning("ConditionalBranchBattle: Invalid actor ID %d", com.parameters[1]); // Use Else branch - return SkipTo(Cmd::ElseBranch_B, Cmd::EndBranch_B); + SetSubcommandIndex(com.indent, 1); + SkipToNextConditional({Cmd::ElseBranch_B, Cmd::EndBranch_B}, com.indent); + return true; } result = actor->GetLastBattleAction() == com.parameters[2]; @@ -389,8 +393,21 @@ bool Game_Interpreter_Battle::CommandConditionalBranchBattle(RPG::EventCommand c } } - if (result) - return true; + int sub_idx = subcommand_sentinel; + if (!result) { + sub_idx = 1; + SkipToNextConditional({Cmd::ElseBranch_B, Cmd::EndBranch_B}, com.indent); + } + + SetSubcommandIndex(com.indent, sub_idx); + return true; +} - return SkipTo(Cmd::ElseBranch_B, Cmd::EndBranch_B); +bool Game_Interpreter_Battle::CommandElseBranchBattle(RPG::EventCommand const& com) { //code 23310 + return CommandOptionGeneric(com, 1, {Cmd::EndBranch_B}); } + +bool Game_Interpreter_Battle::CommandEndBranchBattle(RPG::EventCommand const& com) { //code 23311 + return true; +} + diff --git a/src/game_interpreter_battle.h b/src/game_interpreter_battle.h index 8299726ef7..f1ade5e69e 100644 --- a/src/game_interpreter_battle.h +++ b/src/game_interpreter_battle.h @@ -51,6 +51,8 @@ class Game_Interpreter_Battle : public Game_Interpreter bool CommandShowBattleAnimation(RPG::EventCommand const& com); bool CommandTerminateBattle(RPG::EventCommand const& com); bool CommandConditionalBranchBattle(RPG::EventCommand const& com); + bool CommandElseBranchBattle(RPG::EventCommand const& com); + bool CommandEndBranchBattle(RPG::EventCommand const& com); }; #endif From 1f99d90340bceef4791f216b875cb90f782a383e Mon Sep 17 00:00:00 2001 From: Matthew Fioravante Date: Sat, 6 Apr 2019 16:16:14 -0400 Subject: [PATCH 05/14] CommandShowChoices - use subcommand_path --- src/game_interpreter.cpp | 49 +++++++++++++++++++++------------------- src/game_interpreter.h | 4 +++- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 5cfa0ec473..42d4b8be5b 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -584,9 +584,9 @@ bool Game_Interpreter::ExecuteCommand() { case Cmd::ShowChoice: return CommandShowChoices(com); case Cmd::ShowChoiceOption: - return SkipTo(Cmd::ShowChoiceEnd); + return CommandShowChoiceOption(com); case Cmd::ShowChoiceEnd: - return true; + return CommandShowChoiceEnd(com); case Cmd::InputNumber: return CommandInputNumber(com); case Cmd::ControlSwitches: @@ -865,7 +865,7 @@ bool Game_Interpreter::CommandShowMessage(RPG::EventCommand const& com) { // cod index++; Game_Message::choice_start = line_count; Game_Message::choice_cancel_type = list[index].parameters[0]; - SetupChoices(s_choices); + SetupChoices(s_choices, com.indent); } } else if (list[index+1].code == Cmd::InputNumber) { // If next event command is input number @@ -904,7 +904,7 @@ bool Game_Interpreter::CommandChangeFaceGraphic(RPG::EventCommand const& com) { return true; } -void Game_Interpreter::SetupChoices(const std::vector& choices) { +void Game_Interpreter::SetupChoices(const std::vector& choices, int indent) { Game_Message::choice_start = Game_Message::texts.size(); Game_Message::choice_max = choices.size(); Game_Message::choice_disabled.reset(); @@ -916,36 +916,27 @@ void Game_Interpreter::SetupChoices(const std::vector& choices) { } SetContinuation(&Game_Interpreter::ContinuationChoices); + + // save game compatibility with RPG_RT + ReserveSubcommandIndex(indent); } bool Game_Interpreter::ContinuationChoices(RPG::EventCommand const& com) { auto* frame = GetFrame(); assert(frame); - const auto& list = frame->commands; auto& index = frame->current_command; - continuation = NULL; - int indent = com.indent; - for (;;) { - if (!SkipTo(Cmd::ShowChoiceOption, Cmd::ShowChoiceEnd, indent, indent)) - return false; - auto& cmd = list[index]; - if (cmd.code == Cmd::ShowChoiceEnd) { - return false; - } - int which = cmd.parameters[0]; - index++; - if (which > Game_Message::choice_result) - return false; - if (which < Game_Message::choice_result) - continue; - break; - } + SetSubcommandIndex(com.indent, Game_Message::choice_result); + + continuation = nullptr; return true; } bool Game_Interpreter::CommandShowChoices(RPG::EventCommand const& com) { // code 10140 + auto* frame = GetFrame(); + assert(frame); + auto& index = frame->current_command; if (!Game_Message::texts.empty()) { return false; } @@ -956,11 +947,23 @@ bool Game_Interpreter::CommandShowChoices(RPG::EventCommand const& com) { // cod // Choices setup std::vector choices = GetChoices(); Game_Message::choice_cancel_type = com.parameters[0]; - SetupChoices(choices); + SetupChoices(choices, com.indent); + ++index; + return false; +} + + +bool Game_Interpreter::CommandShowChoiceOption(RPG::EventCommand const& com) { //code 20140 + const auto opt_sub_idx = com.parameters[0]; + return CommandOptionGeneric(com, opt_sub_idx, {Cmd::ShowChoiceOption, Cmd::ShowChoiceEnd}); +} + +bool Game_Interpreter::CommandShowChoiceEnd(RPG::EventCommand const& com) { //code 20141 return true; } + bool Game_Interpreter::CommandInputNumber(RPG::EventCommand const& com) { // code 10150 if (Game_Message::message_waiting) { return false; diff --git a/src/game_interpreter.h b/src/game_interpreter.h index 4993cf0b6a..c752961ce2 100644 --- a/src/game_interpreter.h +++ b/src/game_interpreter.h @@ -68,7 +68,7 @@ class Game_Interpreter void Push(Game_CommonEvent* ev); void InputButton(); - void SetupChoices(const std::vector& choices); + void SetupChoices(const std::vector& choices, int indent); virtual bool ExecuteCommand(); @@ -187,6 +187,8 @@ class Game_Interpreter bool CommandMessageOptions(RPG::EventCommand const& com); bool CommandChangeFaceGraphic(RPG::EventCommand const& com); bool CommandShowChoices(RPG::EventCommand const& com); + bool CommandShowChoiceOption(RPG::EventCommand const& com); + bool CommandShowChoiceEnd(RPG::EventCommand const& com); bool CommandInputNumber(RPG::EventCommand const& com); bool CommandControlSwitches(RPG::EventCommand const& com); bool CommandControlVariables(RPG::EventCommand const& com); From ab84877f4cadc30f6446b66c746ca823a6002dc8 Mon Sep 17 00:00:00 2001 From: Matthew Fioravante Date: Sun, 7 Apr 2019 13:21:55 -0400 Subject: [PATCH 06/14] Shop Command - use subcommand_path --- src/game_interpreter_map.cpp | 45 ++++++++++++++++++++++++------------ src/game_interpreter_map.h | 3 +++ src/game_temp.cpp | 2 -- src/game_temp.h | 1 - 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/game_interpreter_map.cpp b/src/game_interpreter_map.cpp index 0c8e66daa5..1df672f0d1 100644 --- a/src/game_interpreter_map.cpp +++ b/src/game_interpreter_map.cpp @@ -88,10 +88,11 @@ bool Game_Interpreter_Map::ExecuteCommand() { case Cmd::OpenShop: return CommandOpenShop(com); case Cmd::Transaction: + return CommandTransaction(com); case Cmd::NoTransaction: - return SkipTo(Cmd::EndShop); + return CommandNoTransaction(com); case Cmd::EndShop: - return true; + return CommandEndShop(com); case Cmd::ShowInn: return CommandShowInn(com); case Cmd::Stay: @@ -263,6 +264,10 @@ bool Game_Interpreter_Map::ContinuationEnemyEncounter(RPG::EventCommand const& c } bool Game_Interpreter_Map::CommandOpenShop(RPG::EventCommand const& com) { // code 10720 + auto* frame = GetFrame(); + assert(frame); + auto& index = frame->current_command; + if (Game_Message::visible) { return false; } @@ -285,7 +290,8 @@ bool Game_Interpreter_Map::CommandOpenShop(RPG::EventCommand const& com) { // co } Game_Temp::shop_type = com.parameters[1]; - Game_Temp::shop_handlers = com.parameters[2] != 0; + // Not used, but left here for documentation purposes + //bool has_shop_handlers = com.parameters[2] != 0; Game_Temp::shop_goods.clear(); std::vector::const_iterator it; @@ -295,28 +301,37 @@ bool Game_Interpreter_Map::CommandOpenShop(RPG::EventCommand const& com) { // co Game_Temp::shop_transaction = false; Scene::instance->SetRequestedScene(Scene::Shop); SetContinuation(static_cast(&Game_Interpreter_Map::ContinuationOpenShop)); + + // save game compatibility with RPG_RT + ReserveSubcommandIndex(com.indent); + + ++index; return false; } -bool Game_Interpreter_Map::ContinuationOpenShop(RPG::EventCommand const& /* com */) { +bool Game_Interpreter_Map::ContinuationOpenShop(RPG::EventCommand const& com) { auto* frame = GetFrame(); assert(frame); auto& index = frame->current_command; continuation = nullptr; - if (!Game_Temp::shop_handlers) { - index++; - return true; - } - if (!SkipTo(Game_Temp::shop_transaction - ? Cmd::Transaction - : Cmd::NoTransaction, - Cmd::EndShop)) { - return false; - } + int sub_idx = Game_Temp::shop_transaction ? 0 : 1; - index++; + SetSubcommandIndex(com.indent, sub_idx); + + return true; +} + +bool Game_Interpreter_Map::CommandTransaction(RPG::EventCommand const& com) { // code 20720 + return CommandOptionGeneric(com, 0, {Cmd::NoTransaction, Cmd::EndShop}); +} + +bool Game_Interpreter_Map::CommandNoTransaction(RPG::EventCommand const& com) { // code 20721 + return CommandOptionGeneric(com, 1, {Cmd::EndShop}); +} + +bool Game_Interpreter_Map::CommandEndShop(RPG::EventCommand const& com) { // code 20722 return true; } diff --git a/src/game_interpreter_map.h b/src/game_interpreter_map.h index 2e7149ea53..f6337ec8e1 100644 --- a/src/game_interpreter_map.h +++ b/src/game_interpreter_map.h @@ -57,6 +57,9 @@ class Game_Interpreter_Map : public Game_Interpreter bool CommandRecallToLocation(RPG::EventCommand const& com); bool CommandEnemyEncounter(RPG::EventCommand const& com); bool CommandOpenShop(RPG::EventCommand const& com); + bool CommandTransaction(RPG::EventCommand const& com); + bool CommandNoTransaction(RPG::EventCommand const& com); + bool CommandEndShop(RPG::EventCommand const& com); bool CommandShowInn(RPG::EventCommand const& com); bool CommandEnterHeroName(RPG::EventCommand const& com); bool CommandTeleport(RPG::EventCommand const& com); diff --git a/src/game_temp.cpp b/src/game_temp.cpp index 07d75c50b8..9d24836a5d 100644 --- a/src/game_temp.cpp +++ b/src/game_temp.cpp @@ -26,7 +26,6 @@ bool Game_Temp::transition_erase; bool Game_Temp::shop_buys; bool Game_Temp::shop_sells; int Game_Temp::shop_type; -bool Game_Temp::shop_handlers; std::vector Game_Temp::shop_goods; bool Game_Temp::shop_transaction; int Game_Temp::inn_price; @@ -51,7 +50,6 @@ void Game_Temp::Init() { shop_buys = true; shop_sells = true; shop_type = 0; - shop_handlers = false; shop_goods = {}; shop_transaction = false; inn_price = 0; diff --git a/src/game_temp.h b/src/game_temp.h index 8fc1e3f022..c87f134812 100644 --- a/src/game_temp.h +++ b/src/game_temp.h @@ -42,7 +42,6 @@ class Game_Temp { static bool shop_buys; static bool shop_sells; static int shop_type; // message set A, B, or C - static bool shop_handlers; // custom transaction/no-transaction handlers static std::vector shop_goods; static bool shop_transaction; From b1ef7e74a24359aaf0ac85e755aa93fc211c8434 Mon Sep 17 00:00:00 2001 From: Matthew Fioravante Date: Sun, 7 Apr 2019 14:31:55 -0400 Subject: [PATCH 07/14] Refactor Inn command --- src/game_interpreter_map.cpp | 38 +++++++++++++++++++++++++----------- src/game_interpreter_map.h | 3 +++ src/game_temp.cpp | 2 -- src/game_temp.h | 4 ---- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/game_interpreter_map.cpp b/src/game_interpreter_map.cpp index 1df672f0d1..18ff37f68c 100644 --- a/src/game_interpreter_map.cpp +++ b/src/game_interpreter_map.cpp @@ -96,10 +96,11 @@ bool Game_Interpreter_Map::ExecuteCommand() { case Cmd::ShowInn: return CommandShowInn(com); case Cmd::Stay: + return CommandStay(com); case Cmd::NoStay: - return SkipTo(Cmd::EndInn); + return CommandNoStay(com); case Cmd::EndInn: - return true; + return CommandEndInn(com); case Cmd::EnterHeroName: return CommandEnterHeroName(com); case Cmd::Teleport: @@ -338,7 +339,8 @@ bool Game_Interpreter_Map::CommandEndShop(RPG::EventCommand const& com) { // cod bool Game_Interpreter_Map::CommandShowInn(RPG::EventCommand const& com) { // code 10730 int inn_type = com.parameters[0]; Game_Temp::inn_price = com.parameters[1]; - Game_Temp::inn_handlers = com.parameters[2] != 0; + // Not used, but left here for documentation purposes + // bool has_inn_handlers = com.parameters[2] != 0; if (Game_Temp::inn_price == 0) { // Skip prompt. @@ -436,10 +438,14 @@ bool Game_Interpreter_Map::CommandShowInn(RPG::EventCommand const& com) { // cod Game_Message::choice_result = 4; SetContinuation(static_cast(&Game_Interpreter_Map::ContinuationShowInnStart)); + + // save game compatibility with RPG_RT + ReserveSubcommandIndex(com.indent); + return false; } -bool Game_Interpreter_Map::ContinuationShowInnStart(RPG::EventCommand const& /* com */) { +bool Game_Interpreter_Map::ContinuationShowInnStart(RPG::EventCommand const& com) { auto* frame = GetFrame(); assert(frame); auto& index = frame->current_command; @@ -451,6 +457,8 @@ bool Game_Interpreter_Map::ContinuationShowInnStart(RPG::EventCommand const& /* bool inn_stay = Game_Message::choice_result == 0; + SetSubcommandIndex(com.indent, inn_stay ? 0 : 1); + Game_Temp::inn_calling = false; if (inn_stay) { @@ -467,9 +475,7 @@ bool Game_Interpreter_Map::ContinuationShowInnStart(RPG::EventCommand const& /* return false; } - if (Game_Temp::inn_handlers) - SkipTo(Cmd::NoStay, Cmd::EndInn); - index++; + ++index; return true; } @@ -489,7 +495,7 @@ bool Game_Interpreter_Map::ContinuationShowInnContinue(RPG::EventCommand const& return false; } -bool Game_Interpreter_Map::ContinuationShowInnFinish(RPG::EventCommand const& /* com */) { +bool Game_Interpreter_Map::ContinuationShowInnFinish(RPG::EventCommand const& com) { auto* frame = GetFrame(); assert(frame); auto& index = frame->current_command; @@ -509,15 +515,25 @@ bool Game_Interpreter_Map::ContinuationShowInnFinish(RPG::EventCommand const& /* Graphics::GetTransition().Init(Transition::TransitionFadeIn, Scene::instance.get(), 36, false); Game_System::BgmPlay(Main_Data::game_data.system.before_battle_music); - if (Game_Temp::inn_handlers) - SkipTo(Cmd::Stay, Cmd::EndInn); - index++; + ++index; return false; } return false; } +bool Game_Interpreter_Map::CommandStay(RPG::EventCommand const& com) { // code 20730 + return CommandOptionGeneric(com, 0, {Cmd::NoStay, Cmd::EndInn}); +} + +bool Game_Interpreter_Map::CommandNoStay(RPG::EventCommand const& com) { // code 20731 + return CommandOptionGeneric(com, 1, {Cmd::EndInn}); +} + +bool Game_Interpreter_Map::CommandEndInn(RPG::EventCommand const& com) { // code 20732 + return true; +} + bool Game_Interpreter_Map::CommandEnterHeroName(RPG::EventCommand const& com) { // code 10740 auto* frame = GetFrame(); assert(frame); diff --git a/src/game_interpreter_map.h b/src/game_interpreter_map.h index f6337ec8e1..ebe38c302a 100644 --- a/src/game_interpreter_map.h +++ b/src/game_interpreter_map.h @@ -61,6 +61,9 @@ class Game_Interpreter_Map : public Game_Interpreter bool CommandNoTransaction(RPG::EventCommand const& com); bool CommandEndShop(RPG::EventCommand const& com); bool CommandShowInn(RPG::EventCommand const& com); + bool CommandStay(RPG::EventCommand const& com); + bool CommandNoStay(RPG::EventCommand const& com); + bool CommandEndInn(RPG::EventCommand const& com); bool CommandEnterHeroName(RPG::EventCommand const& com); bool CommandTeleport(RPG::EventCommand const& com); bool CommandEnterExitVehicle(RPG::EventCommand const& com); diff --git a/src/game_temp.cpp b/src/game_temp.cpp index 9d24836a5d..2427815b60 100644 --- a/src/game_temp.cpp +++ b/src/game_temp.cpp @@ -29,7 +29,6 @@ int Game_Temp::shop_type; std::vector Game_Temp::shop_goods; bool Game_Temp::shop_transaction; int Game_Temp::inn_price; -bool Game_Temp::inn_handlers; std::string Game_Temp::hero_name; int Game_Temp::hero_name_id; int Game_Temp::hero_name_charset; @@ -53,7 +52,6 @@ void Game_Temp::Init() { shop_goods = {}; shop_transaction = false; inn_price = 0; - inn_handlers = false; hero_name = ""; hero_name_id = 0; hero_name_charset = 0; diff --git a/src/game_temp.h b/src/game_temp.h index c87f134812..373cb15acb 100644 --- a/src/game_temp.h +++ b/src/game_temp.h @@ -44,11 +44,7 @@ class Game_Temp { static int shop_type; // message set A, B, or C static std::vector shop_goods; static bool shop_transaction; - - static int inn_type; // message set A or B static int inn_price; - static bool inn_handlers; // custom stay/no-stay handlers - static bool inn_stay; static std::string hero_name; static int hero_name_id; From 70e55c61c2b8681492bd11b76f53ac154fba934e Mon Sep 17 00:00:00 2001 From: Matthew Fioravante Date: Sun, 7 Apr 2019 14:48:44 -0400 Subject: [PATCH 08/14] Refactor CommandEnemyEncounter --- src/game_interpreter_map.cpp | 94 +++++++++++++++++++----------------- src/game_interpreter_map.h | 4 ++ 2 files changed, 53 insertions(+), 45 deletions(-) diff --git a/src/game_interpreter_map.cpp b/src/game_interpreter_map.cpp index 18ff37f68c..2933a30063 100644 --- a/src/game_interpreter_map.cpp +++ b/src/game_interpreter_map.cpp @@ -80,11 +80,13 @@ bool Game_Interpreter_Map::ExecuteCommand() { case Cmd::EnemyEncounter: return CommandEnemyEncounter(com); case Cmd::VictoryHandler: + return CommandVictoryHandler(com); case Cmd::EscapeHandler: + return CommandEscapeHandler(com); case Cmd::DefeatHandler: - return SkipTo(Cmd::EndBattle); + return CommandDefeatHandler(com); case Cmd::EndBattle: - return true; + return CommandEndBattle(com); case Cmd::OpenShop: return CommandOpenShop(com); case Cmd::Transaction: @@ -164,6 +166,10 @@ bool Game_Interpreter_Map::CommandRecallToLocation(RPG::EventCommand const& com) } bool Game_Interpreter_Map::CommandEnemyEncounter(RPG::EventCommand const& com) { // code 10710 + auto* frame = GetFrame(); + assert(frame); + auto& index = frame->current_command; + if (Game_Message::visible) { return false; } @@ -204,6 +210,11 @@ bool Game_Interpreter_Map::CommandEnemyEncounter(RPG::EventCommand const& com) { Scene::instance->SetRequestedScene(Scene::Battle); SetContinuation(static_cast(&Game_Interpreter_Map::ContinuationEnemyEncounter)); + + // save game compatibility with RPG_RT + ReserveSubcommandIndex(com.indent); + + ++index; return false; } @@ -214,54 +225,47 @@ bool Game_Interpreter_Map::ContinuationEnemyEncounter(RPG::EventCommand const& c continuation = NULL; - switch (Game_Temp::battle_result) { - case Game_Temp::BattleVictory: - if ((Game_Temp::battle_defeat_mode == 0 && Game_Temp::battle_escape_mode != 2) || !SkipTo(Cmd::VictoryHandler, Cmd::EndBattle)) { - index++; - return false; - } - index++; - return true; - case Game_Temp::BattleEscape: - switch (Game_Temp::battle_escape_mode) { - case 0: // disallowed - shouldn't happen - return true; - case 1: + int sub_idx = subcommand_sentinel; + + if (Game_Temp::battle_result == Game_Temp::BattleVictory) { + sub_idx = 0; + } + + if (Game_Temp::battle_result == Game_Temp::BattleEscape) { + sub_idx = 1; + //FIXME: subidx set before this anyway?? + if (Game_Temp::battle_escape_mode == 1) { return CommandEndEventProcessing(com); - case 2: - if (!SkipTo(Cmd::EscapeHandler, Cmd::EndBattle)) { - index++; - return false; - } - index++; - return true; - default: - return false; } - case Game_Temp::BattleDefeat: - switch (Game_Temp::battle_defeat_mode) { - case 0: + } + + if (Game_Temp::battle_result == Game_Temp::BattleDefeat) { + sub_idx = 2; + //FIXME: subidx set before this anyway?? + if (Game_Temp::battle_defeat_mode == 0) { return CommandGameOver(com); - case 1: - if (!SkipTo(Cmd::DefeatHandler, Cmd::EndBattle)) { - index++; - return false; - } - index++; - return true; - default: - return false; } - case Game_Temp::BattleAbort: - if (!SkipTo(Cmd::EndBattle)) { - index++; - return false; - } - index++; - return true; - default: - return false; } + + SetSubcommandIndex(com.indent, sub_idx); + + return true; +} + +bool Game_Interpreter_Map::CommandVictoryHandler(RPG::EventCommand const& com) { // code 20710 + return CommandOptionGeneric(com, 0, {Cmd::EscapeHandler, Cmd::DefeatHandler, Cmd::EndBattle}); +} + +bool Game_Interpreter_Map::CommandEscapeHandler(RPG::EventCommand const& com) { // code 20711 + return CommandOptionGeneric(com, 1, {Cmd::DefeatHandler, Cmd::EndBattle}); +} + +bool Game_Interpreter_Map::CommandDefeatHandler(RPG::EventCommand const& com) { // code 20712 + return CommandOptionGeneric(com, 2, {Cmd::EndBattle}); +} + +bool Game_Interpreter_Map::CommandEndBattle(RPG::EventCommand const& com) { // code 20713 + return true; } bool Game_Interpreter_Map::CommandOpenShop(RPG::EventCommand const& com) { // code 10720 diff --git a/src/game_interpreter_map.h b/src/game_interpreter_map.h index ebe38c302a..70e7fd874b 100644 --- a/src/game_interpreter_map.h +++ b/src/game_interpreter_map.h @@ -56,6 +56,10 @@ class Game_Interpreter_Map : public Game_Interpreter private: bool CommandRecallToLocation(RPG::EventCommand const& com); bool CommandEnemyEncounter(RPG::EventCommand const& com); + bool CommandVictoryHandler(RPG::EventCommand const& com); + bool CommandEscapeHandler(RPG::EventCommand const& com); + bool CommandDefeatHandler(RPG::EventCommand const& com); + bool CommandEndBattle(RPG::EventCommand const& com); bool CommandOpenShop(RPG::EventCommand const& com); bool CommandTransaction(RPG::EventCommand const& com); bool CommandNoTransaction(RPG::EventCommand const& com); From 83dd29fff2c246f42a170a5b476ccb091ea31aa1 Mon Sep 17 00:00:00 2001 From: Matthew Fioravante Date: Sun, 7 Apr 2019 14:59:38 -0400 Subject: [PATCH 09/14] Refactor BreakLoop --- src/game_interpreter.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 42d4b8be5b..b18bce2975 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -461,7 +461,6 @@ void Game_Interpreter::CheckGameOver() { } } -// Skip to command. bool Game_Interpreter::SkipTo(int code, int code2, int min_indent, int max_indent, bool otherwise_end) { auto* frame = GetFrame(); assert(frame); @@ -3064,7 +3063,24 @@ bool Game_Interpreter::CommandJumpToLabel(RPG::EventCommand const& com) { // cod } bool Game_Interpreter::CommandBreakLoop(RPG::EventCommand const& com) { // code 12220 - return SkipTo(Cmd::EndLoop, Cmd::EndLoop, 0, com.indent - 1, true); + auto* frame = GetFrame(); + assert(frame); + const auto& list = frame->commands; + auto& index = frame->current_command; + + // BreakLoop will jump to the end of the event if there is no loop. + + //FIXME: This emulates an RPG_RT bug where break loop ignores scopes and + //unconditionally jumps to the next EndLoop command. + auto pcode = list[index].code; + for (++index; index < (int)list.size(); ++index) { + if (pcode == Cmd::EndLoop) { + break; + } + pcode = list[index].code; + } + + return true; } bool Game_Interpreter::CommandEndLoop(RPG::EventCommand const& com) { // code 22210 From 35a3ea941129ffa13ff875b424a82b4d268aaa7f Mon Sep 17 00:00:00 2001 From: Matthew Fioravante Date: Sun, 7 Apr 2019 15:00:30 -0400 Subject: [PATCH 10/14] Remove unused Game_Interpreter::SkipTo() --- src/game_interpreter.cpp | 32 -------------------------------- src/game_interpreter.h | 2 -- 2 files changed, 34 deletions(-) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index b18bce2975..3f3c1e7131 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -461,38 +461,6 @@ void Game_Interpreter::CheckGameOver() { } } -bool Game_Interpreter::SkipTo(int code, int code2, int min_indent, int max_indent, bool otherwise_end) { - auto* frame = GetFrame(); - assert(frame); - const auto& list = frame->commands; - auto& index = frame->current_command; - - if (code2 < 0) - code2 = code; - if (min_indent < 0) - min_indent = list[index].indent; - if (max_indent < 0) - max_indent = list[index].indent; - - int idx; - for (idx = index; (size_t) idx < list.size(); idx++) { - if (list[idx].indent < min_indent) - return false; - if (list[idx].indent > max_indent) - continue; - if (list[idx].code != code && - list[idx].code != code2) - continue; - index = idx; - return true; - } - - if (otherwise_end) - index = idx; - - return true; -} - void Game_Interpreter::SkipToNextConditional(std::initializer_list codes, int indent) { auto* frame = GetFrame(); assert(frame); diff --git a/src/game_interpreter.h b/src/game_interpreter.h index c752961ce2..60938900f3 100644 --- a/src/game_interpreter.h +++ b/src/game_interpreter.h @@ -142,8 +142,6 @@ class Game_Interpreter int OperateValue(int operation, int operand_type, int operand); Game_Character* GetCharacter(int character_id) const; - bool SkipTo(int code, int code2 = -1, int min_indent = -1, int max_indent = -1, bool otherwise_end = false); - /** * Skips to the next option in a chain of conditional commands. * Works by skipping until we hit the end or the next command From d3817d953f69dfb773d6f37017a0084e660d407a Mon Sep 17 00:00:00 2001 From: Matthew Fioravante Date: Sat, 17 Aug 2019 10:07:43 -0400 Subject: [PATCH 11/14] CommandEndLoop: Fix index After end loop, the next command is not Loop but instead is the first command inside the loop. --- src/game_interpreter.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 3f3c1e7131..c6b203d7b3 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -3070,6 +3070,11 @@ bool Game_Interpreter::CommandEndLoop(RPG::EventCommand const& com) { // code 22 break; } + // Jump past the Cmd::Loop to the first command. + if (index < (int)frame->commands.size()) { + ++index; + } + return true; } From 8e8adc3d95c6d33c5de53f0ea6ca65c578ea6cd6 Mon Sep 17 00:00:00 2001 From: Matthew Fioravante Date: Sat, 17 Aug 2019 16:17:02 -0400 Subject: [PATCH 12/14] Continuation - don't reset event loop --- src/game_interpreter.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index c6b203d7b3..9503fbcee2 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -377,10 +377,9 @@ void Game_Interpreter::Update(bool reset_loop_count) { result = (this->*continuation)(list[index]); } - if (result) - continue; - else + if (!result) { break; + } } if (Game_Map::GetNeedRefresh()) { From 95684bae2a3b180730425074bed74da96a851505 Mon Sep 17 00:00:00 2001 From: Matthew Fioravante Date: Sun, 18 Aug 2019 10:25:57 -0400 Subject: [PATCH 13/14] Cleanup ShowMessages command - Don't loop over choices or number input - Increment index after choices and number input (broken in earlier commit) --- src/game_interpreter.cpp | 60 +++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 9503fbcee2..ffd998b0d3 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -816,37 +816,39 @@ bool Game_Interpreter::CommandShowMessage(RPG::EventCommand const& com) { // cod Game_Message::texts.push_back(com.string); line_count++; - for (; index + 1 < list.size(); index++) { - // If next event command is the following parts of the message - if (list[index+1].code == Cmd::ShowMessage_2) { - // Add second (another) line - line_count++; - Game_Message::texts.push_back(list[index+1].string); - } else { - // If next event command is show choices - if (list[index+1].code == Cmd::ShowChoice) { - std::vector s_choices = GetChoices(); - // If choices fit on screen - if (s_choices.size() <= (4 - line_count)) { - index++; - Game_Message::choice_start = line_count; - Game_Message::choice_cancel_type = list[index].parameters[0]; - SetupChoices(s_choices, com.indent); - } - } else if (list[index+1].code == Cmd::InputNumber) { - // If next event command is input number - // If input number fits on screen - if (line_count < 4) { - index++; - Game_Message::num_input_start = line_count; - Game_Message::num_input_digits_max = list[index].parameters[0]; - Game_Message::num_input_variable_id = list[index].parameters[1]; - } - } + ++index; - break; + // Check for continued lines via ShowMessage_2 + while (index < list.size() && list[index].code == Cmd::ShowMessage_2) { + // Add second (another) line + line_count++; + Game_Message::texts.push_back(list[index].string); + ++index; + } + + // Handle Choices or number + if (index < list.size()) { + // If next event command is show choices + if (list[index].code == Cmd::ShowChoice) { + std::vector s_choices = GetChoices(); + // If choices fit on screen + if (s_choices.size() <= (4 - line_count)) { + Game_Message::choice_start = line_count; + Game_Message::choice_cancel_type = list[index].parameters[0]; + SetupChoices(s_choices, com.indent); + ++index; + } + } else if (list[index].code == Cmd::InputNumber) { + // If next event command is input number + // If input number fits on screen + if (line_count < 4) { + Game_Message::num_input_start = line_count; + Game_Message::num_input_digits_max = list[index].parameters[0]; + Game_Message::num_input_variable_id = list[index].parameters[1]; + ++index; + } } - } // End for + } return true; } From 62e286b63555e227878a1225f522ad0a2d680c25 Mon Sep 17 00:00:00 2001 From: Matthew Fioravante Date: Sun, 1 Sep 2019 21:29:07 -0400 Subject: [PATCH 14/14] Use enum values for subcommand idx values --- src/game_interpreter.cpp | 7 ++++-- src/game_interpreter_battle.cpp | 8 +++++-- src/game_interpreter_map.cpp | 40 +++++++++++++++++++++++---------- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index ffd998b0d3..785cff7a61 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -55,6 +55,9 @@ bool Game_Interpreter::to_title = false; bool Game_Interpreter::exit_game = false; +enum BranchSubcommand { + eOptionBranchElse = 1 +}; constexpr int Game_Interpreter::loop_limit; constexpr int Game_Interpreter::call_stack_limit; @@ -2994,7 +2997,7 @@ bool Game_Interpreter::CommandConditionalBranch(RPG::EventCommand const& com) { int sub_idx = subcommand_sentinel; if (!result) { - sub_idx = 1; + sub_idx = eOptionBranchElse; SkipToNextConditional({Cmd::ElseBranch, Cmd::EndBranch}, com.indent); } @@ -3004,7 +3007,7 @@ bool Game_Interpreter::CommandConditionalBranch(RPG::EventCommand const& com) { bool Game_Interpreter::CommandElseBranch(RPG::EventCommand const& com) { //code 22010 - return CommandOptionGeneric(com, 1, {Cmd::EndBranch}); + return CommandOptionGeneric(com, eOptionBranchElse, {Cmd::EndBranch}); } bool Game_Interpreter::CommandEndBranch(RPG::EventCommand const& com) { //code 22011 diff --git a/src/game_interpreter_battle.cpp b/src/game_interpreter_battle.cpp index b5e2ca3d7a..5dfcf01013 100644 --- a/src/game_interpreter_battle.cpp +++ b/src/game_interpreter_battle.cpp @@ -32,6 +32,10 @@ #include "spriteset_battle.h" #include +enum BranchBattleSubcommand { + eOptionBranchBattleElse = 1 +}; + Game_Interpreter_Battle::Game_Interpreter_Battle() : Game_Interpreter(true) {} @@ -395,7 +399,7 @@ bool Game_Interpreter_Battle::CommandConditionalBranchBattle(RPG::EventCommand c int sub_idx = subcommand_sentinel; if (!result) { - sub_idx = 1; + sub_idx = eOptionBranchBattleElse; SkipToNextConditional({Cmd::ElseBranch_B, Cmd::EndBranch_B}, com.indent); } @@ -404,7 +408,7 @@ bool Game_Interpreter_Battle::CommandConditionalBranchBattle(RPG::EventCommand c } bool Game_Interpreter_Battle::CommandElseBranchBattle(RPG::EventCommand const& com) { //code 23310 - return CommandOptionGeneric(com, 1, {Cmd::EndBranch_B}); + return CommandOptionGeneric(com, eOptionBranchBattleElse, {Cmd::EndBranch_B}); } bool Game_Interpreter_Battle::CommandEndBranchBattle(RPG::EventCommand const& com) { //code 23311 diff --git a/src/game_interpreter_map.cpp b/src/game_interpreter_map.cpp index 2933a30063..40a41fc2bc 100644 --- a/src/game_interpreter_map.cpp +++ b/src/game_interpreter_map.cpp @@ -48,6 +48,22 @@ #include "game_interpreter_map.h" #include "reader_lcf.h" +enum EnemyEncounterSubcommand { + eOptionEnemyEncounterVictory = 0, + eOptionEnemyEncounterEscape = 1, + eOptionEnemyEncounterDefeat = 2, +}; + +enum ShopSubcommand { + eOptionShopTransaction = 0, + eOptionShopNoTransaction = 1, +}; + +enum InnSubcommand { + eOptionInnStay = 0, + eOptionInnNoStay = 1, +}; + void Game_Interpreter_Map::SetState(const RPG::SaveEventExecState& save) { Clear(); _state = save; @@ -228,11 +244,11 @@ bool Game_Interpreter_Map::ContinuationEnemyEncounter(RPG::EventCommand const& c int sub_idx = subcommand_sentinel; if (Game_Temp::battle_result == Game_Temp::BattleVictory) { - sub_idx = 0; + sub_idx = eOptionEnemyEncounterVictory; } if (Game_Temp::battle_result == Game_Temp::BattleEscape) { - sub_idx = 1; + sub_idx = eOptionEnemyEncounterEscape; //FIXME: subidx set before this anyway?? if (Game_Temp::battle_escape_mode == 1) { return CommandEndEventProcessing(com); @@ -240,7 +256,7 @@ bool Game_Interpreter_Map::ContinuationEnemyEncounter(RPG::EventCommand const& c } if (Game_Temp::battle_result == Game_Temp::BattleDefeat) { - sub_idx = 2; + sub_idx = eOptionEnemyEncounterDefeat; //FIXME: subidx set before this anyway?? if (Game_Temp::battle_defeat_mode == 0) { return CommandGameOver(com); @@ -253,15 +269,15 @@ bool Game_Interpreter_Map::ContinuationEnemyEncounter(RPG::EventCommand const& c } bool Game_Interpreter_Map::CommandVictoryHandler(RPG::EventCommand const& com) { // code 20710 - return CommandOptionGeneric(com, 0, {Cmd::EscapeHandler, Cmd::DefeatHandler, Cmd::EndBattle}); + return CommandOptionGeneric(com, eOptionEnemyEncounterVictory, {Cmd::EscapeHandler, Cmd::DefeatHandler, Cmd::EndBattle}); } bool Game_Interpreter_Map::CommandEscapeHandler(RPG::EventCommand const& com) { // code 20711 - return CommandOptionGeneric(com, 1, {Cmd::DefeatHandler, Cmd::EndBattle}); + return CommandOptionGeneric(com, eOptionEnemyEncounterEscape, {Cmd::DefeatHandler, Cmd::EndBattle}); } bool Game_Interpreter_Map::CommandDefeatHandler(RPG::EventCommand const& com) { // code 20712 - return CommandOptionGeneric(com, 2, {Cmd::EndBattle}); + return CommandOptionGeneric(com, eOptionEnemyEncounterDefeat, {Cmd::EndBattle}); } bool Game_Interpreter_Map::CommandEndBattle(RPG::EventCommand const& com) { // code 20713 @@ -321,7 +337,7 @@ bool Game_Interpreter_Map::ContinuationOpenShop(RPG::EventCommand const& com) { continuation = nullptr; - int sub_idx = Game_Temp::shop_transaction ? 0 : 1; + int sub_idx = Game_Temp::shop_transaction ? eOptionShopTransaction : eOptionShopNoTransaction; SetSubcommandIndex(com.indent, sub_idx); @@ -329,11 +345,11 @@ bool Game_Interpreter_Map::ContinuationOpenShop(RPG::EventCommand const& com) { } bool Game_Interpreter_Map::CommandTransaction(RPG::EventCommand const& com) { // code 20720 - return CommandOptionGeneric(com, 0, {Cmd::NoTransaction, Cmd::EndShop}); + return CommandOptionGeneric(com, eOptionShopTransaction, {Cmd::NoTransaction, Cmd::EndShop}); } bool Game_Interpreter_Map::CommandNoTransaction(RPG::EventCommand const& com) { // code 20721 - return CommandOptionGeneric(com, 1, {Cmd::EndShop}); + return CommandOptionGeneric(com, eOptionShopNoTransaction, {Cmd::EndShop}); } bool Game_Interpreter_Map::CommandEndShop(RPG::EventCommand const& com) { // code 20722 @@ -461,7 +477,7 @@ bool Game_Interpreter_Map::ContinuationShowInnStart(RPG::EventCommand const& com bool inn_stay = Game_Message::choice_result == 0; - SetSubcommandIndex(com.indent, inn_stay ? 0 : 1); + SetSubcommandIndex(com.indent, inn_stay ? eOptionInnStay : eOptionInnNoStay); Game_Temp::inn_calling = false; @@ -527,11 +543,11 @@ bool Game_Interpreter_Map::ContinuationShowInnFinish(RPG::EventCommand const& co } bool Game_Interpreter_Map::CommandStay(RPG::EventCommand const& com) { // code 20730 - return CommandOptionGeneric(com, 0, {Cmd::NoStay, Cmd::EndInn}); + return CommandOptionGeneric(com, eOptionInnStay, {Cmd::NoStay, Cmd::EndInn}); } bool Game_Interpreter_Map::CommandNoStay(RPG::EventCommand const& com) { // code 20731 - return CommandOptionGeneric(com, 1, {Cmd::EndInn}); + return CommandOptionGeneric(com, eOptionInnNoStay, {Cmd::EndInn}); } bool Game_Interpreter_Map::CommandEndInn(RPG::EventCommand const& com) { // code 20732