Do autosaves

This commit is contained in:
2025-03-02 12:03:52 -06:00
committed by Celtic Minstrel
parent 53de92c932
commit 5bc1643be7
7 changed files with 63 additions and 3 deletions

View File

@@ -35,6 +35,7 @@ std::vector<std::pair<fs::path, std::time_t>> sorted_file_mtimes(fs::path dir, s
bool load_party(fs::path file_to_load, cUniverse& univ);
bool save_party(cUniverse& univ, bool save_as = false);
bool save_party_force(cUniverse& univ, fs::path file);
void init_directories(const char* exec_path);

View File

@@ -444,9 +444,12 @@ bool load_party_v2(fs::path file_to_load, cUniverse& real_univ){
return true;
}
static bool save_party_const(const cUniverse& univ, bool save_as) {
static bool save_party_const(const cUniverse& univ, bool save_as, fs::path dest_file = "") {
// Make sure it has the proper file extension
fs::path dest_file = univ.file;
if(dest_file.empty()){
dest_file = univ.file;
}
if(dest_file.extension() != ".exg"){
dest_file += ".exg";
}
@@ -555,6 +558,10 @@ bool save_party(cUniverse& univ, bool save_as) {
return save_party_const(univ, save_as);
}
bool save_party_force(cUniverse& univ, fs::path file) {
return save_party_const(univ, false, file);
}
static bool compare_mtime(std::pair<fs::path, std::time_t> a, std::pair<fs::path, std::time_t> b) {
return std::difftime(a.second, b.second) > 0;
}

View File

@@ -483,6 +483,7 @@ void handle_rest(bool& need_redraw, bool& need_reprint) {
if(i == 50) {
do_rest(1200, get_ran(5,1,10), 50);
add_string_to_buf(" Rest successful.");
try_auto_save("RestComplete");
put_pc_screen();
pause(25);
}
@@ -1138,6 +1139,9 @@ static void handle_town_wait(bool& need_redraw, bool& need_reprint) {
redraw_screen(REFRESH_NONE);
}
put_pc_screen();
if(!party_sees_a_monst()){
try_auto_save("TownWaitComplete");
}
}
void handle_wait(bool& did_something, bool& need_redraw, bool& need_reprint) {
@@ -3196,6 +3200,7 @@ void increase_age() {
else {
play_sound(6);
add_string_to_buf("You eat.");
try_auto_save("Eat");
}
}

View File

@@ -6,6 +6,7 @@
#include "universe/universe.hpp"
#include "boe.monster.hpp"
#include "boe.graphics.hpp"
#include "boe.fileio.hpp"
#include "boe.locutils.hpp"
#include "boe.newgraph.hpp"
#include "boe.infodlg.hpp"
@@ -4681,8 +4682,10 @@ bool hit_end_c_button() {
}
}
if(end_ok)
if(end_ok){
end_combat();
if(which_combat_type == 0) try_auto_save("EndOutdoorCombat");
}
return end_ok;
}

View File

@@ -480,3 +480,37 @@ bool load_scenario_header(fs::path file,scen_header_type& scen_head){
return true;
}
const int MAX_AUTOSAVE_DEFAULT = 5;
void try_auto_save(std::string reason) {
if(!get_bool_pref("Autosave", true)) return;
if(!get_bool_pref("Autosave_" + reason, true)) return;
if(univ.file.empty()){
ASB("Autosave: Make a manual save first.");
print_buf();
return;
}
fs::path auto_folder = univ.file;
auto_folder.replace_extension(".auto");
fs::create_directories(auto_folder);
std::vector<std::pair<fs::path, std::time_t>> auto_mtimes = sorted_file_mtimes(auto_folder);
int max_autosaves = get_int_pref("Autosave_Max", MAX_AUTOSAVE_DEFAULT);
fs::path target_path;
if(auto_mtimes.size() < max_autosaves){
target_path = auto_folder / std::to_string(auto_mtimes.size() + 1);
target_path += ".exg";
}
// Save file buffer is full, so overwrite the oldest autosave
else{
target_path = auto_mtimes.back().first;
}
if(save_party_force(univ, target_path)){
ASB("Autosave: Game saved");
}else{
ASB("Autosave: Save not completed");
}
print_buf();
}

View File

@@ -30,4 +30,8 @@ fs::path locate_scenario(std::string scen_name);
void alter_rect(rectangle *r);
// The player can configure autosaves on/off globally, or individually
// for a variety of different trigger reasons
void try_auto_save(std::string reason);
#endif

View File

@@ -507,6 +507,8 @@ void start_town_mode(short which_town, short entry_dir) {
// TODO: One problem with this - it paints the terrain after the town entry dialog is dismissed
// ... except it actually doesn't, because the town enter special is only queued, not run immediately.
draw_terrain(1);
try_auto_save("EnterTown");
}
@@ -629,6 +631,10 @@ location end_town_mode(bool switching_level,location destination, bool debug_lea
univ.party.town_num = 200; // should be harmless...
if(!switching_level){
try_auto_save("ExitTown");
}
return to_return;
}