diff --git a/binaries/data/mods/public/gui/loadgame/SavegameWriter.js b/binaries/data/mods/public/gui/loadgame/SavegameWriter.js new file mode 100644 index 0000000000..bc78942d24 --- /dev/null +++ b/binaries/data/mods/public/gui/loadgame/SavegameWriter.js @@ -0,0 +1,52 @@ +/** + * This class obtains the current simulation state to be saved along the savegame, + * asks the user whether to overwrite a savegame and performs the saving. + */ +class SavegameWriter +{ + constructor(data) + { + this.savedGameData = data && data.savedGameData || {}; + let simulationState = Engine.GuiInterfaceCall("GetSimulationState"); + this.savedGameData.timeElapsed = simulationState.timeElapsed; + this.savedGameData.states = simulationState.players.map(pState => pState.state); + } + + getSavedGameData() + { + return this.savedGameData; + } + + saveGame() + { + let gameSelection = Engine.GetGUIObjectByName("gameSelection"); + let gameLabel = gameSelection.list[gameSelection.selected]; + let gameID = gameSelection.list_data[gameSelection.selected]; + let desc = Engine.GetGUIObjectByName("saveGameDesc").caption; + let name = gameID || "savegame"; + + if (!gameID) + { + this.reallySaveGame(name, desc, true); + return; + } + + messageBox( + 500, 200, + sprintf(translate("\"%(label)s\""), { "label": gameLabel }) + "\n" + + translate("Saved game will be permanently overwritten, are you sure?"), + translate("OVERWRITE SAVE"), + [translate("No"), translate("Yes")], + [null, () => { this.reallySaveGame(name, desc, false); }]); + } + + reallySaveGame(name, desc, nameIsPrefix) + { + if (nameIsPrefix) + Engine.SaveGamePrefix(name, desc, this.savedGameData); + else + Engine.SaveGame(name, desc, this.savedGameData); + + Engine.PopGuiPage(); + } +} diff --git a/binaries/data/mods/public/gui/common/functions_utility_loadsave.js b/binaries/data/mods/public/gui/loadgame/functions_utility_loadsave.js similarity index 97% rename from binaries/data/mods/public/gui/common/functions_utility_loadsave.js rename to binaries/data/mods/public/gui/loadgame/functions_utility_loadsave.js index 7605d46662..f74522d715 100644 --- a/binaries/data/mods/public/gui/common/functions_utility_loadsave.js +++ b/binaries/data/mods/public/gui/loadgame/functions_utility_loadsave.js @@ -64,8 +64,7 @@ function reallyDeleteGame(gameID) if (!Engine.DeleteSavedGame(gameID)) error("Could not delete saved game: " + gameID); - // Run init again to refresh saved game list - init(); + updateSavegameList(); } function deleteTooltip() diff --git a/binaries/data/mods/public/gui/loadgame/load.js b/binaries/data/mods/public/gui/loadgame/load.js index e617705d53..1fae1a8eed 100644 --- a/binaries/data/mods/public/gui/loadgame/load.js +++ b/binaries/data/mods/public/gui/loadgame/load.js @@ -1,3 +1,5 @@ +var g_SavegameWriter; + var g_SavedGamesMetadata = []; /** @@ -5,7 +7,29 @@ var g_SavedGamesMetadata = []; */ const g_CivData = loadCivData(false, false); -function init() +function init(data) +{ + let save = Engine.IsGameStarted(); + if (save) + g_SavegameWriter = new SavegameWriter(data); + + let confirmButton = Engine.GetGUIObjectByName("confirmButton"); + confirmButton.caption = save ? translate("Save") : translate("Load"); + confirmButton.onPress = save ? () => { g_SavegameWriter.saveGame(); } : loadGame; + Engine.GetGUIObjectByName("title").caption = save ? translate("Save Game") : translate("Load Game") + Engine.GetGUIObjectByName("saveGameDesc").hidden = !save; + + updateSavegameList(); + + // Select the most recent savegame to be loaded, or no savegame to be overwritten + let gameSelection = Engine.GetGUIObjectByName("gameSelection"); + if (!save && gameSelection.list.length) + gameSelection.selected = 0; + else + selectionChanged(); +} + +function updateSavegameList() { let savedGames = Engine.GetSavedGames(); @@ -17,6 +41,10 @@ function init() let gameSelection = Engine.GetGUIObjectByName("gameSelection"); gameSelection.enabled = !!savedGames.length; + gameSelection.onSelectionChange = selectionChanged; + gameSelection.onSelectionColumnChange = updateSavegameList; + gameSelection.onMouseLeftDoubleClickItem = loadGame; + Engine.GetGUIObjectByName("gameSelectionFeedback").hidden = !!savedGames.length; let selectedGameId = gameSelection.list_data[gameSelection.selected]; @@ -87,9 +115,6 @@ function init() gameSelection.selected = selectedGameIndex; else if (gameSelection.selected >= g_SavedGamesMetadata.length) // happens when deleting the last saved game gameSelection.selected = g_SavedGamesMetadata.length - 1; - else if (gameSelection.selected == -1 && g_SavedGamesMetadata.length) - gameSelection.selected = 0; - selectionChanged(); Engine.GetGUIObjectByName("deleteGameButton").tooltip = deleteTooltip(); } @@ -99,7 +124,7 @@ function selectionChanged() let metadata = g_SavedGamesMetadata[Engine.GetGUIObjectByName("gameSelection").selected]; Engine.GetGUIObjectByName("invalidGame").hidden = !!metadata; Engine.GetGUIObjectByName("validGame").hidden = !metadata; - Engine.GetGUIObjectByName("loadGameButton").enabled = !!metadata; + Engine.GetGUIObjectByName("confirmButton").enabled = !!metadata || Engine.IsGameStarted(); Engine.GetGUIObjectByName("deleteGameButton").enabled = !!metadata; if (!metadata) @@ -170,8 +195,7 @@ function loadGame() message, translate("Warning"), [translate("No"), translate("Yes")], - [init, function(){ reallyLoadGame(gameId); }] - ); + [undefined, () => { reallyLoadGame(gameId); }]); } function reallyLoadGame(gameId) @@ -179,10 +203,7 @@ function reallyLoadGame(gameId) let metadata = Engine.StartSavedGame(gameId); if (!metadata) { - // Probably the file wasn't found - // Show error and refresh saved game list error("Could not load saved game: " + gameId); - init(); return; } diff --git a/binaries/data/mods/public/gui/loadgame/load.xml b/binaries/data/mods/public/gui/loadgame/load.xml index 33c6472c90..468672221c 100644 --- a/binaries/data/mods/public/gui/loadgame/load.xml +++ b/binaries/data/mods/public/gui/loadgame/load.xml @@ -10,9 +10,7 @@ - - Load Game - + - selectionChanged(); - init(); - loadGame(); - Date / Time @@ -49,6 +43,10 @@ No saved games found. + + saveGame(); + + Cancel Engine.PopGuiPage(); @@ -59,16 +57,12 @@ deleteGame(); - - Load - loadGame(); - - + - init(); + updateSavegameList(); @@ -79,7 +73,7 @@ - + Players: diff --git a/binaries/data/mods/public/gui/page_savegame.xml b/binaries/data/mods/public/gui/page_savegame.xml deleted file mode 100644 index 05d2e57236..0000000000 --- a/binaries/data/mods/public/gui/page_savegame.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - common/modern/setup.xml - common/modern/styles.xml - common/modern/sprites.xml - - common/setup.xml - common/sprites.xml - common/styles.xml - - savegame/save.xml - diff --git a/binaries/data/mods/public/gui/savegame/save.js b/binaries/data/mods/public/gui/savegame/save.js deleted file mode 100644 index 4814034e1d..0000000000 --- a/binaries/data/mods/public/gui/savegame/save.js +++ /dev/null @@ -1,84 +0,0 @@ -var g_Descriptions; -var g_SavedGameData; - -function selectDescription() -{ - let gameSelection = Engine.GetGUIObjectByName("gameSelection"); - let gameID = gameSelection.list_data[gameSelection.selected]; - Engine.GetGUIObjectByName("deleteGameButton").enabled = !!gameID; - - if (!gameID) - return; - - Engine.GetGUIObjectByName("saveGameDesc").caption = g_Descriptions[gameID]; -} - -function init(data) -{ - g_SavedGameData = data && data.savedGameData || {}; - let simulationState = Engine.GuiInterfaceCall("GetSimulationState"); - g_SavedGameData.timeElapsed = simulationState.timeElapsed; - g_SavedGameData.states = simulationState.players.map(pState => pState.state); - - let savedGames = Engine.GetSavedGames().sort(sortDecreasingDate); - - let gameSelection = Engine.GetGUIObjectByName("gameSelection"); - gameSelection.enabled = savedGames.length != 0; - - if (!savedGames.length) - { - gameSelection.list = [translate("No saved games found")]; - gameSelection.selected = -1; - return; - } - - g_Descriptions = {}; - for (let game of savedGames) - g_Descriptions[game.id] = game.metadata.description || ""; - - let engineInfo = Engine.GetEngineInfo(); - gameSelection.list = savedGames.map(game => generateSavegameLabel(game.metadata, engineInfo)); - gameSelection.list_data = savedGames.map(game => game.id); - gameSelection.selected = Math.min(gameSelection.selected, gameSelection.list.length - 1); - - Engine.GetGUIObjectByName("deleteGameButton").tooltip = deleteTooltip(); -} - -function saveGame() -{ - let gameSelection = Engine.GetGUIObjectByName("gameSelection"); - let gameLabel = gameSelection.list[gameSelection.selected]; - let gameID = gameSelection.list_data[gameSelection.selected]; - let desc = Engine.GetGUIObjectByName("saveGameDesc").caption; - let name = gameID || "savegame"; - - if (!gameID) - { - reallySaveGame(name, desc, true); - return; - } - - messageBox( - 500, 200, - sprintf(translate("\"%(label)s\""), { "label": gameLabel }) + "\n" + - translate("Saved game will be permanently overwritten, are you sure?"), - translate("OVERWRITE SAVE"), - [translate("No"), translate("Yes")], - [null, function(){ reallySaveGame(name, desc, false); }] - ); -} - -function reallySaveGame(name, desc, nameIsPrefix) -{ - if (nameIsPrefix) - Engine.SaveGamePrefix(name, desc, g_SavedGameData); - else - Engine.SaveGame(name, desc, g_SavedGameData); - - closeSave(); -} - -function closeSave() -{ - Engine.PopGuiPage(); -} diff --git a/binaries/data/mods/public/gui/savegame/save.xml b/binaries/data/mods/public/gui/savegame/save.xml deleted file mode 100644 index 8a973c2f5c..0000000000 --- a/binaries/data/mods/public/gui/savegame/save.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - -