Ticket #2030: saveAsv2.patch
File saveAsv2.patch, 12.1 KB (added by , 11 years ago) |
---|
-
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) 14 14 15 15 var date = t.getFullYear()+"-"+twoDigits(1+t.getMonth())+"-"+twoDigits(t.getDate()); 16 16 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:""); 18 18 } 19 19 20 20 function 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 8 8 <!-- Add a translucent black background to fade out the menu page --> 9 9 <object type="image" z="0" sprite="BackgroundTranslucent"/> 10 10 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"> 12 12 13 13 <object type="text" style="TitleText" size="50%-128 0%-16 50%+128 16"> 14 14 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) 167 167 // Menu functions 168 168 // ============================================================================= 169 169 170 function openSave(pause) 171 { 172 getGUIObjectByName("saveGamePanel").hidden = false; 173 savePanelInit(); 174 if (pause) 175 pauseGame(); 176 } 177 178 function closeSave(resume) 179 { 180 getGUIObjectByName("saveGamePanel").hidden = true; 181 if (resume) 182 resumeGame(); 183 } 184 170 185 function openSettings(pause) 171 186 { 172 187 getGUIObjectByName("settingsDialogPanel").hidden = false; … … function formatTributeTooltip(player, resource, amount) 434 449 return "Tribute " + amount + " " + resource + " to [color=\"" + playerColor + "\"]" + player.name + 435 450 "[/color]. Shift-click to tribute " + (amount < 500 ? 500 : amount + 500) + "."; 436 451 } 452 453 var descriptions; 454 455 function sortDecreasingDate(a, b) 456 { 457 return b.metadata.time - a.metadata.time; 458 } 459 460 function twoDigits(n) 461 { 462 return n < 10 ? "0" + n : n; 463 } 464 465 function 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 474 function 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 486 function 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 514 function 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 523 function 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 535 function 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 17 17 <script file="gui/session/messages.js"/> 18 18 <script file="gui/session/utility_functions.js"/> 19 19 20 21 20 22 <object name="sn" hotkey="session.gui.toggle"> 21 23 <action on="Tick"> 22 24 onTick(); … … 427 429 </object> 428 430 429 431 <!-- ================================ ================================ --> 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 <!-- ================================ ================================ --> 430 475 <!-- Settings Window --> 431 476 <!-- ================================ ================================ --> 432 477 <object name="settingsDialogPanel" … … 702 747 > 703 748 Save 704 749 <action on="Press"> 705 Engine.SaveGame();706 750 closeMenu(); 751 openSave(true); 707 752 </action> 708 753 </object> 709 754 -
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) 258 258 return metadata.get(); 259 259 } 260 260 261 void SaveGame(void* cbdata )261 void SaveGame(void* cbdata, std::wstring givenname, std::wstring description, bool overwrite) 262 262 { 263 263 CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata); 264 264 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) 266 266 LOGERROR(L"Failed to save game"); 267 267 } 268 268 … … void GuiScriptingInit(ScriptInterface& scriptInterface) 669 669 scriptInterface.RegisterFunction<CScriptVal, std::wstring, &StartSavedGame>("StartSavedGame"); 670 670 scriptInterface.RegisterFunction<std::vector<CScriptValRooted>, &GetSavedGames>("GetSavedGames"); 671 671 scriptInterface.RegisterFunction<bool, std::wstring, &DeleteSavedGame>("DeleteSavedGame"); 672 scriptInterface.RegisterFunction<void, &SaveGame>("SaveGame");672 scriptInterface.RegisterFunction<void, std::wstring, std::wstring, bool, &SaveGame>("SaveGame"); 673 673 scriptInterface.RegisterFunction<void, &QuickSave>("QuickSave"); 674 674 scriptInterface.RegisterFunction<void, &QuickLoad>("QuickLoad"); 675 675 -
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 31 31 static const int SAVED_GAME_VERSION_MINOR = 0; // increment on compatible changes to the format 32 32 // TODO: we ought to check version numbers when loading files 33 33 34 Status SavedGames::Save(const std::wstring& prefix, CSimulation2& simulation, CGUIManager* gui, int playerID)34 Status SavedGames::Save(const std::wstring& givenname, const std::wstring& description, bool overwrite, CSimulation2& simulation, CGUIManager* gui, int playerID) 35 35 { 36 36 // 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")); 38 38 const VfsPath filenameFormat = basenameFormat.ChangeExtension(L".0adsave"); 39 39 VfsPath filename; 40 40 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 } 46 52 // ArchiveWriter_Zip can only write to OsPaths, not VfsPaths, 47 53 // but we'd like to handle saved games via VFS. 48 54 // To avoid potential confusion from writing with non-VFS then … … Status SavedGames::Save(const std::wstring& prefix, CSimulation2& simulation, CG 74 80 CScriptVal guiMetadata = simulation.GetScriptInterface().CloneValueFromOtherContext(gui->GetScriptInterface(), gui->GetSavedGameData().get()); 75 81 simulation.GetScriptInterface().SetProperty(metadata.get(), "gui", guiMetadata); 76 82 } 83 simulation.GetScriptInterface().SetProperty(metadata.get(), "description", description); 77 84 78 85 std::string metadataString = simulation.GetScriptInterface().StringifyJSON(metadata.get(), true); 79 86 -
source/ps/SavedGame.h
diff --git a/source/ps/SavedGame.h b/source/ps/SavedGame.h index 019f31b..77b2e22 100644
a b namespace SavedGames 41 41 /** 42 42 * Create new saved game archive with given prefix and simulation data 43 43 * 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 45 49 * @param simulation 46 50 * @param gui if not NULL, store some UI-related data with the saved game 47 51 * @param playerID ID of the player who saved this file 48 52 * @return INFO::OK if successfully saved, else an error Status 49 53 */ 50 Status Save(const std::wstring& prefix, CSimulation2& simulation, CGUIManager* gui, int playerID);54 Status Save(const std::wstring& givenname, const std::wstring& description, bool overwrite, CSimulation2& simulation, CGUIManager* gui, int playerID); 51 55 52 56 /** 53 57 * Load saved game archive with the given name