From 6452470d4a7afa324e665d11214690b059c17ab8 Mon Sep 17 00:00:00 2001 From: Mauro Junior <45118493+jetrotal@users.noreply.github.com> Date: Thu, 22 Jun 2023 00:01:39 -0300 Subject: [PATCH] Call Movement Action + Wait for Single Movement( can Detect fail cases) Call Movement Action: `@raw 2050, "SetMoveSpeed", 0, 10001, 1, 3` @2050("typeOfAction",[targetIsVar,target, parameterIsvar, parameter]) ```js @raw 2051, "", 0, 10001 //Wait for Single Movement @raw 20140, "Fails to move x times", 8 // start fail branch @raw 10 //empty space for more cmds @raw 20141 // end of fail branch ``` ------------------------------- old commits comments: Update Feature - Support Detecting when Move Route Fails Thanks @MackValentine Mack for solving some Core Issues --- src/game_character.cpp | 17 ++++++++ src/game_character.h | 3 ++ src/game_interpreter.cpp | 85 ++++++++++++++++++++++++++++++++++++++++ src/game_interpreter.h | 2 + 4 files changed, 107 insertions(+) diff --git a/src/game_character.cpp b/src/game_character.cpp index 4e71fd57df3..2942b9295f7 100644 --- a/src/game_character.cpp +++ b/src/game_character.cpp @@ -782,6 +782,23 @@ void Game_Character::CancelMoveRoute() { SetMoveRouteFinished(false); } +bool Game_Character::isStuck(int i) { + if(i == 0 ) i =1; + int currentPose = 500; + if (GetMoveRouteIndex() < GetMoveRoute().move_commands.size()) { + if (IsStopping() && GetMoveRoute().move_commands[GetMoveRouteIndex()].command_id < 12) { + failsMove++; + } else { + failsMove = 0; + } + } else { + failsMove = 0; + } + + //Output::Warning("stuck? - {} {} {} -- {}", failsMove, IsPaused(), i, GetMaxStopCount()); + return failsMove > i && (GetStopCount() == 0 || GetStopCount() > GetMaxStopCount()); +} + int Game_Character::GetSpriteX() const { int x = GetX() * SCREEN_TILE_SIZE; diff --git a/src/game_character.h b/src/game_character.h index 8d451fe9709..938bbe5ec27 100644 --- a/src/game_character.h +++ b/src/game_character.h @@ -861,6 +861,9 @@ class Game_Character { static constexpr int GetDxFromDirection(int dir); static constexpr int GetDyFromDirection(int dir); + int failsMove = 0; + bool isStuck(int i); + protected: explicit Game_Character(Type type, lcf::rpg::SaveMapEventBase* d); /** Check for and fix incorrect data after loading save game */ diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 353d66fa9fa..6fab24e2d5f 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -821,6 +821,10 @@ bool Game_Interpreter::ExecuteCommand(lcf::rpg::EventCommand const& com) { return CommandManiacSetGameOption(com); case Cmd::Maniac_CallCommand: return CommandManiacCallCommand(com); + case static_cast(2050): //Cmd::EasyRpg_CallMovement + return CommandCallMovement(com); + case static_cast(2051): //Cmd::EasyRpg_WaitForMovement + return CommandWaitForMovement(com); default: return true; } @@ -4643,6 +4647,87 @@ bool Game_Interpreter::CommandManiacCallCommand(lcf::rpg::EventCommand const&) { return true; } +bool Game_Interpreter::CommandCallMovement(lcf::rpg::EventCommand const& com) { + // CommandSetMovement("moveCommand",[useVarID, ID, useVarOutput, output]) + + int eventID = ValueOrVariable(com.parameters[0], com.parameters[1]); + int outputParam = ValueOrVariable(com.parameters[2], com.parameters[3]); + + Game_Character* event = GetCharacter(eventID); + Game_Character* target; + + std::string moveCommand = ToString(com.string); + std::string outputString = event->GetSpriteName(); + + std::size_t pos = moveCommand.find('/'); + + if (pos != std::string::npos) { + outputString = moveCommand.substr(pos + 1); + moveCommand = moveCommand.substr(0, pos); + } + + if (moveCommand == "SetMoveSpeed")event->SetMoveSpeed(outputParam); + if (moveCommand == "SetMoveFrequency")event->SetMoveFrequency(outputParam); + if (moveCommand == "SetTransparency")event->SetTransparency(outputParam); + + if (moveCommand == "Event2Event") { + target = GetCharacter(outputParam); + event->SetFacing(target->GetFacing()); + event->SetDirection(target->GetDirection()); + event->SetX(target->GetX()); + event->SetY(target->GetY()); + } + + if (moveCommand == "SetFacingLocked")event->SetFacingLocked(outputParam); + if (moveCommand == "SetLayer")event->SetLayer(outputParam); + if (moveCommand == "SetFlying")event->SetFlying(outputParam); //FIXME: I wish any event could imitate an airship, lacks more work. + if (moveCommand == "ChangeCharset")event->SetSpriteGraphic(outputString,outputParam); // syntax ChangeCharset/actor1 + + if (moveCommand == "StopMovement")event->CancelMoveRoute(); + + return true; +} + +bool Game_Interpreter::CommandWaitForMovement(lcf::rpg::EventCommand const& com) { + // CommandWaitForMovement(useVarID, ID) + + // Needed for ShowChoice + auto* frame = GetFramePtr(); + const auto& list = frame->commands; + auto& index = frame->current_command; + + // Retrieve event ID + int eventID = ValueOrVariable(com.parameters[0], com.parameters[1]); + if (eventID == 0) + eventID = GetCurrentEventId(); + + // Get the character associated with the event ID + Game_Character* ev = GetCharacter(eventID); + + // Check if movement exists and if it's currently running + bool movementExists = !ev->GetMoveRoute().move_commands.empty(); + bool movementIsRunning = movementExists && (ev->IsMoveRouteOverwritten() && !ev->IsMoveRouteFinished()); + + int i = frame->current_command + 1; + + // Check the next command for a specific condition + const auto& cmd = list[i]; + const int32_t failBranch = static_cast(Cmd::ShowChoiceOption); + + // If the next command is "Fails to move x times" and the character is stuck, cancel movement + if (cmd.code == failBranch && cmd.string == "Fails to move x times") + if (ev->isStuck(cmd.parameters[0])) { + ev->failsMove = 0; + ev->CancelMoveRoute(); + frame->current_command = i + 1; + return true; + } + + // Return false if movement is still in progress + if(!movementIsRunning) ev->failsMove = 0; + return !movementIsRunning; +} + Game_Interpreter& Game_Interpreter::GetForegroundInterpreter() { return Game_Battle::IsBattleRunning() ? Game_Battle::GetInterpreter() diff --git a/src/game_interpreter.h b/src/game_interpreter.h index a436cbfaed1..4154239c334 100644 --- a/src/game_interpreter.h +++ b/src/game_interpreter.h @@ -284,6 +284,8 @@ class Game_Interpreter bool CommandManiacChangePictureId(lcf::rpg::EventCommand const& com); bool CommandManiacSetGameOption(lcf::rpg::EventCommand const& com); bool CommandManiacCallCommand(lcf::rpg::EventCommand const& com); + bool CommandCallMovement(lcf::rpg::EventCommand const& com); + bool CommandWaitForMovement(lcf::rpg::EventCommand const& com); int DecodeInt(lcf::DBArray::const_iterator& it); const std::string DecodeString(lcf::DBArray::const_iterator& it);