diff --git a/src/app/app.cpp b/src/app/app.cpp index 2d253aa3..bd37396b 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -246,6 +246,7 @@ ParseArgsStatus CApplication::ParseArguments(int argc, char *argv[]) OPT_DEBUG, OPT_RUNSCENE, OPT_SCENETEST, + OPT_LOADGAME, OPT_LOGLEVEL, OPT_LANGDIR, OPT_DATADIR, @@ -264,6 +265,7 @@ ParseArgsStatus CApplication::ParseArguments(int argc, char *argv[]) { "debug", required_argument, nullptr, OPT_DEBUG }, { "runscene", required_argument, nullptr, OPT_RUNSCENE }, { "scenetest", no_argument, nullptr, OPT_SCENETEST }, + { "loadgame", required_argument, nullptr, OPT_LOADGAME }, { "loglevel", required_argument, nullptr, OPT_LOGLEVEL }, { "langdir", required_argument, nullptr, OPT_LANGDIR }, { "datadir", required_argument, nullptr, OPT_DATADIR }, @@ -309,6 +311,7 @@ ParseArgsStatus CApplication::ParseArguments(int argc, char *argv[]) GetLogger()->Message(" -debug modes enable debug modes (more info printed in logs; see code for reference of modes)\n"); GetLogger()->Message(" -runscene sceneNNN run given scene on start\n"); GetLogger()->Message(" -scenetest win every mission right after it's loaded\n"); + GetLogger()->Message(" -loadgame path load given game on start (path is /\n"); GetLogger()->Message(" -loglevel level set log level to level (one of: trace, debug, info, warn, error, none)\n"); GetLogger()->Message(" -langdir path set custom language directory path\n"); GetLogger()->Message(" environment variable: COLOBOT_LANG_DIR\n"); @@ -366,6 +369,22 @@ ParseArgsStatus CApplication::ParseArguments(int argc, char *argv[]) m_sceneTest = true; break; } + case OPT_LOADGAME: + { + std::string playerAndPath = optarg; + size_t pos = playerAndPath.find_first_of("/"); + if (pos != std::string::npos && pos > 0 && pos+1 < playerAndPath.length()) // Split player name from path + { + m_loadGamePlayerName = playerAndPath.substr(0, pos); + m_loadGameDirName = playerAndPath.substr(pos+1, playerAndPath.length()-pos-1); + } + else + { + GetLogger()->Error("Invalid path: '%s'\n", optarg); + return PARSE_ARGS_FAIL; + } + break; + } case OPT_LOGLEVEL: { LogLevel logLevel; @@ -698,8 +717,15 @@ bool CApplication::Create() StartLoadingMusic(); - if (m_runSceneCategory == LevelCategory::Max) + if (!m_loadGameDirName.empty()) + { + m_controller->GetRobotMain()->SelectPlayer(m_loadGamePlayerName); + m_controller->GetRobotMain()->LoadGameFromDirName(m_loadGameDirName); + } + else if (m_runSceneCategory == LevelCategory::Max) + { m_controller->StartApp(); + } else { m_controller->GetRobotMain()->UpdateCustomLevelList(); // To load the userlevels diff --git a/src/app/app.h b/src/app/app.h index 45e41464..2efe34a1 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -405,6 +405,10 @@ protected: int m_runSceneRank; //@} + //! Game to load on startup + std::string m_loadGamePlayerName; + std::string m_loadGameDirName; + //! Scene test mode bool m_sceneTest; diff --git a/src/level/robotmain.cpp b/src/level/robotmain.cpp index 68ecee4f..a5cc4fdb 100644 --- a/src/level/robotmain.cpp +++ b/src/level/robotmain.cpp @@ -5839,6 +5839,17 @@ void CRobotMain::QuickLoad() m_playerProfile->LoadScene(dir); } +void CRobotMain::LoadGameFromDirName(const std::string& gameDir) +{ + std::string dir = m_playerProfile->GetSaveFile(gameDir); + if(!CResourceManager::Exists(dir)) + { + GetLogger()->Error("Save slot not found\n"); + return; + } + m_playerProfile->LoadScene(dir); +} + void CRobotMain::SetExitAfterMission(bool exit) { m_exitAfterMission = exit; diff --git a/src/level/robotmain.h b/src/level/robotmain.h index ceddcb78..a7f0206b 100644 --- a/src/level/robotmain.h +++ b/src/level/robotmain.h @@ -368,6 +368,9 @@ public: //! Enable mode where completing mission closes the game void SetExitAfterMission(bool exit); + //! Load saved game (used by command line argument) + void LoadGameFromDirName(const std::string& gameDir); + //! Returns true if player can interact with things manually bool CanPlayerInteract();