Ticket #2030: saveAsv2.patch

File saveAsv2.patch, 12.1 KB (added by Crynux, 11 years ago)

updated patch

  • binaries/data/mods/public/gui/savedgames/load.js

    diff --git a/binaries/data/mods/public/gui/savedgames/load.js b/binaries/data/mods/public/gui/savedgames/load.js
    index de1150c..cd74478 100644
    a b function generateLabel(metadata)  
    1414
    1515    var date = t.getFullYear()+"-"+twoDigits(1+t.getMonth())+"-"+twoDigits(t.getDate());
    1616    var time = twoDigits(t.getHours())+":"+twoDigits(t.getMinutes())+":"+twoDigits(t.getSeconds());
    17     return "["+date+" "+time+"] "+metadata.initAttributes.map;
     17    return "["+date+" "+time+"] "+metadata.initAttributes.map+"\n"+(metadata.description?metadata.description:"");
    1818}
    1919
    2020function init()
  • binaries/data/mods/public/gui/savedgames/load.xml

    diff --git a/binaries/data/mods/public/gui/savedgames/load.xml b/binaries/data/mods/public/gui/savedgames/load.xml
    index e3ed2e8..ef63dce 100644
    a b  
    88    <!-- Add a translucent black background to fade out the menu page -->
    99    <object type="image" z="0" sprite="BackgroundTranslucent"/>
    1010
    11     <object type="image" style="StoneDialog" size="50%-190 50%-200 50%+190 50%+200">
     11    <object type="image" style="StoneDialog" size="50%-300 50%-200 50%+300 50%+200">
    1212
    1313        <object type="text" style="TitleText" size="50%-128 0%-16 50%+128 16">
    1414            Load Game
  • binaries/data/mods/public/gui/session/menu.js

    diff --git a/binaries/data/mods/public/gui/session/menu.js b/binaries/data/mods/public/gui/session/menu.js
    index ae3b5b6..464638b 100644
    a b function openDeleteDialog(selection)  
    167167// Menu functions
    168168// =============================================================================
    169169
     170function openSave(pause)
     171{
     172    getGUIObjectByName("saveGamePanel").hidden = false;
     173    savePanelInit();
     174    if (pause)
     175        pauseGame();
     176}
     177
     178function closeSave(resume)
     179{
     180    getGUIObjectByName("saveGamePanel").hidden = true;
     181    if (resume)
     182        resumeGame();
     183}
     184
    170185function openSettings(pause)
    171186{
    172187    getGUIObjectByName("settingsDialogPanel").hidden = false;
    function formatTributeTooltip(player, resource, amount)  
    434449    return "Tribute " + amount + " " + resource + " to [color=\"" + playerColor + "\"]" + player.name +
    435450        "[/color]. Shift-click to tribute " + (amount < 500 ? 500 : amount + 500) + ".";
    436451}
     452
     453var descriptions;
     454
     455function sortDecreasingDate(a, b)
     456{
     457    return b.metadata.time - a.metadata.time;
     458}
     459
     460function twoDigits(n)
     461{
     462    return n < 10 ? "0" + n : n;
     463}
     464
     465function generateLabel(metadata)
     466{
     467    var t = new Date(metadata.time*1000);
     468
     469    var date = t.getFullYear()+"-"+twoDigits(1+t.getMonth())+"-"+twoDigits(t.getDate());
     470    var time = twoDigits(t.getHours())+":"+twoDigits(t.getMinutes())+":"+twoDigits(t.getSeconds());
     471    return "["+date+" "+time+"] "+metadata.initAttributes.map+"\n"+(metadata.description?metadata.description:"");
     472}
     473
     474function selectDescription()
     475{
     476    var gameSelection = getGUIObjectByName("gameSelection");
     477    if(gameSelection.selected != -1)
     478    {
     479       
     480        getGUIObjectByName("deleteGameButton").enabled = true;
     481        var gameID = gameSelection.list_data[gameSelection.selected];
     482        getGUIObjectByName("saveGameDesc").caption = descriptions[gameID];
     483    }
     484}
     485
     486function savePanelInit()
     487{
     488    var savedGames = Engine.GetSavedGames();
     489
     490    var gameSelection = getGUIObjectByName("gameSelection");
     491
     492    getGUIObjectByName("deleteGameButton").enabled = false;
     493   
     494    if (savedGames.length == 0)
     495    {
     496        gameSelection.list = [ "No saved games found" ];
     497        gameSelection.selected = -1;
     498        return;
     499    }
     500
     501    savedGames.sort(sortDecreasingDate);
     502
     503    var gameListIDs = [ game.id for each (game in savedGames) ];
     504    var gameListLabels = [ generateLabel(game.metadata) for each (game in savedGames) ];
     505   
     506    descriptions = new Array();
     507    [ descriptions[game.id] = (game.metadata.description?game.metadata.description:"none") for each (game in savedGames) ];
     508   
     509    gameSelection.list = gameListLabels;
     510    gameSelection.list_data = gameListIDs;
     511    gameSelection.selected = -1;
     512}
     513
     514function saveGame()
     515{
     516    var gameSelection = getGUIObjectByName("gameSelection");
     517    var gameID = gameSelection.list_data[gameSelection.selected];
     518    var desc = getGUIObjectByName("saveGameDesc").caption;
     519    Engine.SaveGame(gameID?gameID:"savegame",desc,gameSelection.selected != -1);
     520    savePanelInit();
     521}
     522
     523function deleteGame()
     524{
     525    var gameSelection = getGUIObjectByName("gameSelection");
     526    var gameLabel = gameSelection.list[gameSelection.selected];
     527    var gameID = gameSelection.list_data[gameSelection.selected];
     528
     529    // Ask for confirmation
     530    var btCaptions = ["Yes", "No"];
     531    var btCode = [function(){ reallyDeleteGame(gameID); }, null];
     532    messageBox(500, 200, "\""+gameLabel+"\"\nSaved game will be permanently deleted, are you sure?", "DELETE", 0, btCaptions, btCode);
     533}
     534
     535function reallyDeleteGame(gameID)
     536{
     537    if (!Engine.DeleteSavedGame(gameID))
     538    {
     539        error("Could not delete saved game '"+gameID+"'");
     540    }
     541
     542    // Run init again to refresh saved game list
     543    savePanelInit();
     544}
  • binaries/data/mods/public/gui/session/session.xml

    diff --git a/binaries/data/mods/public/gui/session/session.xml b/binaries/data/mods/public/gui/session/session.xml
    index 38d2e5b..d82724d 100644
    a b  
    1717    <script file="gui/session/messages.js"/>
    1818    <script file="gui/session/utility_functions.js"/>
    1919
     20
     21
    2022    <object name="sn" hotkey="session.gui.toggle">
    2123    <action on="Tick">
    2224        onTick();
     
    427429    </object>
    428430
    429431    <!-- ================================  ================================ -->
     432    <!-- Save Window -->
     433    <!-- ================================  ================================ -->
     434    <object name="saveGamePanel" type="image" style="StoneDialog" size="50%-300 50%-200 50%+300 50%+200" hidden="true">
     435        <object type="image" z="0" sprite="BackgroundTranslucent"/>
     436        <object type="text" style="TitleText" size="50%-128 0%-16 50%+128 16">
     437            Save Game
     438        </object>
     439
     440        <object name="gameSelection"
     441            style="StoneList"
     442            type="list"
     443           
     444            size="24 24 100%-24 100%-124">
     445            <action on="selectionchange">
     446                selectDescription();
     447            </action>
     448        </object>
     449
     450       
     451        <object size="24 100%-124 100%-24 100%-100" name="descLabel" type="text" style="LeftLabelText">Description:</object>
     452
     453        <object name="saveGameDesc" size="24 100%-96 100%-24 100%-72" type="input" style="StoneInput" max_length="80">
     454            quick save
     455        </object>
     456       
     457        <object name="saveButton" type="button" size="0%+25 100%-60 33%+10 100%-32" style="StoneButton">
     458            Save
     459            <action on="Press">saveGame();closeSave(true);</action>
     460        </object>
     461
     462        <object name="deleteGameButton" type="button" size="33%+20 100%-60 66%-15 100%-32" style="StoneButton">
     463            Delete
     464            <action on="Press">deleteGame();</action>
     465        </object>
     466
     467        <object type="button" style="StoneButton" size="66%-5 100%-60 100%-25 100%-32">
     468            Cancel
     469            <action on="Press">closeSave(true);</action>
     470        </object>
     471
     472    </object>
     473
     474    <!-- ================================  ================================ -->
    430475    <!-- Settings Window -->
    431476    <!-- ================================  ================================ -->
    432477        <object name="settingsDialogPanel"
     
    702747        >
    703748            Save
    704749            <action on="Press">
    705             Engine.SaveGame();
    706750            closeMenu();
     751            openSave(true);
    707752            </action>
    708753        </object>
    709754
  • source/gui/scripting/ScriptFunctions.cpp

    diff --git a/source/gui/scripting/ScriptFunctions.cpp b/source/gui/scripting/ScriptFunctions.cpp
    index dd530cb..4e1cfc5 100644
    a b CScriptVal StartSavedGame(void* cbdata, std::wstring name)  
    258258    return metadata.get();
    259259}
    260260
    261 void SaveGame(void* cbdata)
     261void SaveGame(void* cbdata, std::wstring givenname, std::wstring description, bool overwrite)
    262262{
    263263    CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
    264264
    265     if (SavedGames::Save(L"quicksave", *g_Game->GetSimulation2(), guiManager, g_Game->GetPlayerID()) < 0)
     265    if (SavedGames::Save(givenname, description, overwrite, *g_Game->GetSimulation2(), guiManager, g_Game->GetPlayerID()) < 0)
    266266        LOGERROR(L"Failed to save game");
    267267}
    268268
    void GuiScriptingInit(ScriptInterface& scriptInterface)  
    669669    scriptInterface.RegisterFunction<CScriptVal, std::wstring, &StartSavedGame>("StartSavedGame");
    670670    scriptInterface.RegisterFunction<std::vector<CScriptValRooted>, &GetSavedGames>("GetSavedGames");
    671671    scriptInterface.RegisterFunction<bool, std::wstring, &DeleteSavedGame>("DeleteSavedGame");
    672     scriptInterface.RegisterFunction<void, &SaveGame>("SaveGame");
     672    scriptInterface.RegisterFunction<void, std::wstring, std::wstring, bool, &SaveGame>("SaveGame");
    673673    scriptInterface.RegisterFunction<void, &QuickSave>("QuickSave");
    674674    scriptInterface.RegisterFunction<void, &QuickLoad>("QuickLoad");
    675675
  • source/ps/SavedGame.cpp

    diff --git a/source/ps/SavedGame.cpp b/source/ps/SavedGame.cpp
    index 20bb944..0c86abd 100644
    a b static const int SAVED_GAME_VERSION_MAJOR = 1; // increment on incompatible chan  
    3131static const int SAVED_GAME_VERSION_MINOR = 0; // increment on compatible changes to the format
    3232// TODO: we ought to check version numbers when loading files
    3333
    34 Status SavedGames::Save(const std::wstring& prefix, CSimulation2& simulation, CGUIManager* gui, int playerID)
     34Status SavedGames::Save(const std::wstring& givenname, const std::wstring& description, bool overwrite, CSimulation2& simulation, CGUIManager* gui, int playerID)
    3535{
    3636    // Determine the filename to save under
    37     const VfsPath basenameFormat(L"saves/" + prefix + L"-%04d");
     37    const VfsPath basenameFormat(L"saves/" + givenname + (overwrite?L"":L"-%04d"));
    3838    const VfsPath filenameFormat = basenameFormat.ChangeExtension(L".0adsave");
    3939    VfsPath filename;
    4040
    41     // Don't make this a static global like NextNumberedFilename expects, because
    42     // that wouldn't work when 'prefix' changes, and because it's not thread-safe
    43     size_t nextSaveNumber = 0;
    44     vfs::NextNumberedFilename(g_VFS, filenameFormat, nextSaveNumber, filename);
    45 
     41    if(!overwrite)
     42    {
     43        // Don't make this a static global like NextNumberedFilename expects, because
     44        // that wouldn't work when 'prefix' changes, and because it's not thread-safe
     45        size_t nextSaveNumber = 0;
     46        vfs::NextNumberedFilename(g_VFS, filenameFormat, nextSaveNumber, filename);
     47    }
     48    else
     49    {
     50        filename = filenameFormat.string().c_str();
     51    }
    4652    // ArchiveWriter_Zip can only write to OsPaths, not VfsPaths,
    4753    // but we'd like to handle saved games via VFS.
    4854    // To avoid potential confusion from writing with non-VFS then
    Status SavedGames::Save(const std::wstring& prefix, CSimulation2& simulation, CG  
    7480        CScriptVal guiMetadata = simulation.GetScriptInterface().CloneValueFromOtherContext(gui->GetScriptInterface(), gui->GetSavedGameData().get());
    7581        simulation.GetScriptInterface().SetProperty(metadata.get(), "gui", guiMetadata);
    7682    }
     83    simulation.GetScriptInterface().SetProperty(metadata.get(), "description", description);
    7784   
    7885    std::string metadataString = simulation.GetScriptInterface().StringifyJSON(metadata.get(), true);
    7986   
  • source/ps/SavedGame.h

    diff --git a/source/ps/SavedGame.h b/source/ps/SavedGame.h
    index 019f31b..77b2e22 100644
    a b namespace SavedGames  
    4141/**
    4242 * Create new saved game archive with given prefix and simulation data
    4343 *
    44  * @param prefix Create new numbered file starting with this prefix
     44 * @param givenname Name to save the game with; can be used as a prefix depending
     45 *  on the overwrite bool.
     46 * @param description A user-given description of the save
     47 * @param overwrite if true, overwrite given filename, otherwise consider
     48 *  filename a prefix
    4549 * @param simulation
    4650 * @param gui if not NULL, store some UI-related data with the saved game
    4751 * @param playerID ID of the player who saved this file
    4852 * @return INFO::OK if successfully saved, else an error Status
    4953 */
    50 Status Save(const std::wstring& prefix, CSimulation2& simulation, CGUIManager* gui, int playerID);
     54Status Save(const std::wstring& givenname, const std::wstring& description, bool overwrite, CSimulation2& simulation, CGUIManager* gui, int playerID);
    5155
    5256/**
    5357 * Load saved game archive with the given name