diff --git a/binaries/data/mods/public/gui/savedgames/load.js b/binaries/data/mods/public/gui/savedgames/load.js index 7fc94dcb14..7b88add85c 100644 --- a/binaries/data/mods/public/gui/savedgames/load.js +++ b/binaries/data/mods/public/gui/savedgames/load.js @@ -26,6 +26,7 @@ function init() if (savedGames.length == 0) { gameSelection.list = [ "No saved games found" ]; + gameSelection.selected = 0; getGUIObjectByName("loadGameButton").enabled = false; getGUIObjectByName("deleteGameButton").enabled = false; return; @@ -47,12 +48,21 @@ function loadGame() var gameID = gameSelection.list_data[gameSelection.selected]; var metadata = Engine.StartSavedGame(gameID); - - Engine.SwitchGuiPage("page_loading.xml", { - "attribs": metadata.initAttributes, - "isNetworked" : false, - "playerAssignments": metadata.gui.playerAssignments - }); + if (!metadata) + { + // Probably the file wasn't found + // Show error and refresh saved game list + error("Could not load saved game '"+gameID+"'"); + init(); + } + else + { + Engine.SwitchGuiPage("page_loading.xml", { + "attribs": metadata.initAttributes, + "isNetworked" : false, + "playerAssignments": metadata.gui.playerAssignments + }); + } } function deleteGame() @@ -71,7 +81,7 @@ function reallyDeleteGame(gameID) { if (!Engine.DeleteSavedGame(gameID)) { - warn("Could not delete saved game '"+gameID+"'"); + error("Could not delete saved game '"+gameID+"'"); } // Run init again to refresh saved game list diff --git a/source/gui/scripting/ScriptFunctions.cpp b/source/gui/scripting/ScriptFunctions.cpp index 9c28e70a01..4fad858096 100644 --- a/source/gui/scripting/ScriptFunctions.cpp +++ b/source/gui/scripting/ScriptFunctions.cpp @@ -213,7 +213,6 @@ CScriptVal StartSavedGame(void* cbdata, std::wstring name) CScriptValRooted metadata; std::string savedState; Status err = SavedGames::Load(name, guiManager->GetScriptInterface(), metadata, savedState); - WARN_IF_ERR(err); if (err < 0) return CScriptVal(); diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index ea37f1fc54..7bc37366e1 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -454,7 +454,7 @@ static void InitVfs(const CmdLineArgs& args) g_VFS = CreateVfs(cacheSize); g_VFS->Mount(L"screenshots/", paths.Data()/"screenshots"/""); - g_VFS->Mount(L"saves/", paths.Data()/"saves"/""); + g_VFS->Mount(L"saves/", paths.Data()/"saves"/"", VFS_MOUNT_WATCH); const OsPath readonlyConfig = paths.RData()/"config"/""; g_VFS->Mount(L"config/", readonlyConfig); if(readonlyConfig != paths.Config()) diff --git a/source/ps/SavedGame.cpp b/source/ps/SavedGame.cpp index b860617fe1..20bb944e07 100644 --- a/source/ps/SavedGame.cpp +++ b/source/ps/SavedGame.cpp @@ -144,6 +144,10 @@ Status SavedGames::Load(const std::wstring& name, ScriptInterface& scriptInterfa const VfsPath basename(L"saves/" + name); const VfsPath filename = basename.ChangeExtension(L".0adsave"); + // Don't crash just because file isn't found, this can happen if the file is deleted from the OS + if (!VfsFileExists(filename)) + return ERR::FILE_NOT_FOUND; + OsPath realPath; WARN_RETURN_STATUS_IF_ERR(g_VFS->GetRealPath(filename, realPath)); diff --git a/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp index 01a6e1b18d..456756429e 100644 --- a/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp @@ -478,10 +478,17 @@ QUERYHANDLER(PickSimilarObjects) { CmpPtr cmpTemplateManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY); ENSURE(cmpTemplateManager); - std::string templateName = cmpTemplateManager->GetCurrentTemplateName((entity_id_t)msg->id); - // Since owner selections are meaningless in Atlas, use INVALID_PLAYER - msg->ids = EntitySelection::PickSimilarEntities(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), templateName, INVALID_PLAYER, false, true, true); + entity_id_t ent = msg->id; + std::string templateName = cmpTemplateManager->GetCurrentTemplateName(ent); + + // If unit has ownership, only pick units from the same player + player_id_t owner = INVALID_PLAYER; + CmpPtr cmpOwnership(*g_Game->GetSimulation2(), ent); + if (cmpOwnership) + owner = cmpOwnership->GetOwner(); + + msg->ids = EntitySelection::PickSimilarEntities(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), templateName, owner, false, true, true); }