Index: binaries/data/mods/public/gui/loadgame/SavegameWriter.js =================================================================== --- /dev/null +++ binaries/data/mods/public/gui/loadgame/SavegameWriter.js @@ -0,0 +1,60 @@ +/** + * This class obtains the current simulation state that will be saved along the savegame. + */ +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(); + } +} + +/** + * HACK: Engine.SaveGame* expects this function to be defined on the current page. + * That's why we have to pass the data to this page even if we don't need it. + */ +function getSavedGameData() +{ + return g_SavegameWriter.getSavedGameData(); +} Index: binaries/data/mods/public/gui/loadgame/load.js =================================================================== --- binaries/data/mods/public/gui/loadgame/load.js +++ binaries/data/mods/public/gui/loadgame/load.js @@ -1,3 +1,5 @@ +var g_SavegameWriter; + var g_SavedGamesMetadata = []; /** @@ -5,7 +7,28 @@ */ 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(); + + let gameSelection = Engine.GetGUIObjectByName("gameSelection"); + if (!save && gameSelection.list.length) + gameSelection.selected = 0; + else + selectionChanged(); +} + +function updateSavegameList() { let savedGames = Engine.GetSavedGames(); @@ -17,6 +40,10 @@ 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 +114,6 @@ 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 +123,7 @@ 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) Index: binaries/data/mods/public/gui/loadgame/load.xml =================================================================== --- binaries/data/mods/public/gui/loadgame/load.xml +++ 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(); Index: binaries/data/mods/public/gui/page_savegame.xml =================================================================== --- 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 - Index: binaries/data/mods/public/gui/savegame/save.js =================================================================== --- binaries/data/mods/public/gui/savegame/save.js +++ binaries/data/mods/public/gui/savegame/save.js @@ -1,91 +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(); -} - -// HACK: Engine.SaveGame* expects this function to be defined on the current page. -// That's why we have to pass the data to this page even if we don't need it. -function getSavedGameData() -{ - return g_SavedGameData; -} Index: binaries/data/mods/public/gui/savegame/save.xml =================================================================== --- binaries/data/mods/public/gui/savegame/save.xml +++ binaries/data/mods/public/gui/savegame/save.xml @@ -1,52 +0,0 @@ - - - - -