diff --git a/src/game_character.cpp b/src/game_character.cpp index 02a2fb05bd..3474dd4233 100644 --- a/src/game_character.cpp +++ b/src/game_character.cpp @@ -793,6 +793,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 152262723f..cec65646c7 100644 --- a/src/game_character.h +++ b/src/game_character.h @@ -909,6 +909,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 98b9edef57..afceaa5bf9 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -788,9 +788,9 @@ bool Game_Interpreter::ExecuteCommand(lcf::rpg::EventCommand const& com) { return CommandManiacCallCommand(com); case Cmd::EasyRpg_SetInterpreterFlag: return CommandEasyRpgSetInterpreterFlag(com); - case static_cast(2056): //EasyRPG_CloneMapEvent + case Cmd::EasyRpg_CloneMapEvent: return CommandEasyRpgCloneMapEvent(com); - case static_cast(2057): //EasyRPG_DestroyMapEvent + case Cmd::EasyRpg_DestroyMapEvent: return CommandEasyRpgDestroyMapEvent(com); default: return true; diff --git a/src/game_interpreter.h b/src/game_interpreter.h index 7149d59ca2..2955dc3ff7 100644 --- a/src/game_interpreter.h +++ b/src/game_interpreter.h @@ -301,6 +301,9 @@ class Game_Interpreter : public Game_BaseInterpreterContext bool CommandEasyRpgCloneMapEvent(lcf::rpg::EventCommand const& com); bool CommandEasyRpgDestroyMapEvent(lcf::rpg::EventCommand const& com); + int DecodeInt(lcf::DBArray::const_iterator& it); + const std::string DecodeString(lcf::DBArray::const_iterator& it); + void SetSubcommandIndex(int indent, int idx); uint8_t& ReserveSubcommandIndex(int indent); int GetSubcommandIndex(int indent) const; diff --git a/src/game_interpreter_map.cpp b/src/game_interpreter_map.cpp index 37269f0b66..1df583c111 100644 --- a/src/game_interpreter_map.cpp +++ b/src/game_interpreter_map.cpp @@ -234,6 +234,8 @@ bool Game_Interpreter_Map::ExecuteCommand(lcf::rpg::EventCommand const& com) { return CommandToggleAtbMode(com); case Cmd::EasyRpg_TriggerEventAt: return CommandEasyRpgTriggerEventAt(com); + case Cmd::EasyRpg_CallMovementAction: + return CommandEasyRpgCallMovementAction(com); case Cmd::EasyRpg_WaitForSingleMovement: return CommandEasyRpgWaitForSingleMovement(com); default: @@ -832,6 +834,78 @@ bool Game_Interpreter_Map::CommandEasyRpgTriggerEventAt(lcf::rpg::EventCommand c return true; } + +bool Game_Interpreter_Map::CommandEasyRpgCallMovementAction(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]); + int outputParamB = ValueOrVariable(com.parameters[4], com.parameters[5]); + + 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 == "SetAnimationType")event->SetAnimationType(static_cast(outputParam)); + + + if (moveCommand == "Event2Event") { + target = GetCharacter(outputParam); + if (!target) { + return true; + } + event->SetFacing(target->GetFacing()); + event->SetDirection(target->GetDirection()); + event->SetX(target->GetX()); + event->SetY(target->GetY()); + } + + if (moveCommand == "FaceTowards"){ + if(!event->IsMoving()) { + target = GetCharacter(outputParam); + if (!target) { + return true; + } + event->TurnTowardCharacter(*target); + event->UpdateFacing(); + } + } + + if (moveCommand == "FaceAway"){ + if (!event->IsMoving()) { + target = GetCharacter(outputParam); + if (!target) { + return true; + } + event->TurnAwayFromCharacter(*target); + event->UpdateFacing(); + } + } + + 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 == "JumpTo")event->Game_Character::Jump(outputParam, outputParamB); + + if (moveCommand == "StopMovement")event->CancelMoveRoute(); + + return true; +} + bool Game_Interpreter_Map::CommandEasyRpgWaitForSingleMovement(lcf::rpg::EventCommand const& com) { if (!Player::HasEasyRpgExtensions()) { return true; diff --git a/src/game_interpreter_map.h b/src/game_interpreter_map.h index e94dd0dc96..60ea07fd3b 100644 --- a/src/game_interpreter_map.h +++ b/src/game_interpreter_map.h @@ -85,6 +85,7 @@ class Game_Interpreter_Map : public Game_Interpreter bool CommandToggleAtbMode(lcf::rpg::EventCommand const& com); bool CommandEasyRpgTriggerEventAt(lcf::rpg::EventCommand const& com); + bool CommandEasyRpgCallMovementAction(lcf::rpg::EventCommand const& com); bool CommandEasyRpgWaitForSingleMovement(lcf::rpg::EventCommand const& com); AsyncOp ContinuationShowInnStart(int indent, int choice_result, int price);