Skip to content

Commit

Permalink
Fix quickloading (#60587)
Browse files Browse the repository at this point in the history
* restore quickload

* Removed unused variables from first attempt at restoring quickload

* Fixed keybinding

* fix ub
  • Loading branch information
angleKH authored Sep 1, 2022
1 parent 2aaf897 commit 72e6972
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 55 deletions.
8 changes: 8 additions & 0 deletions src/debug_menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ std::string enum_to_string<debug_menu::debug_menu_index>( debug_menu::debug_menu
case debug_menu::debug_menu_index::PRINT_FACTION_INFO: return "PRINT_FACTION_INFO";
case debug_menu::debug_menu_index::PRINT_NPC_MAGIC: return "PRINT_NPC_MAGIC";
case debug_menu::debug_menu_index::QUIT_NOSAVE: return "QUIT_NOSAVE";
case debug_menu::debug_menu_index::QUICKLOAD: return "QUICKLOAD";
case debug_menu::debug_menu_index::TEST_WEATHER: return "TEST_WEATHER";
case debug_menu::debug_menu_index::WRITE_GLOBAL_EOCS: return "WRITE_GLOBAL_EOCS";
case debug_menu::debug_menu_index::WRITE_GLOBAL_VARS: return "WRITE_GLOBAL_VARS";
Expand Down Expand Up @@ -345,6 +346,7 @@ static int game_uilist()
{ uilist_entry( debug_menu_index::CRASH_GAME, true, 'C', _( "Crash game (test crash handling)" ) ) },
{ uilist_entry( debug_menu_index::ACTIVATE_EOC, true, 'E', _( "Activate EOC" ) ) },
{ uilist_entry( debug_menu_index::QUIT_NOSAVE, true, 'Q', _( "Quit to main menu" ) ) },
{ uilist_entry( debug_menu_index::QUICKLOAD, true, 'q', _( "Quickload" ) ) },
};

return uilist( _( "Game…" ), uilist_initializer );
Expand Down Expand Up @@ -3009,6 +3011,12 @@ void debug()
g->uquit = QUIT_NOSAVED;
}
break;
case debug_menu_index::QUICKLOAD:
if( query_yn(
_( "Quickload without saving? This may cause issues such as duplicated or missing items and vehicles!" ) ) ) {
g->quickload();
}
break;
case debug_menu_index::TEST_WEATHER: {
get_weather().get_cur_weather_gen().test_weather( g->get_seed() );
}
Expand Down
1 change: 1 addition & 0 deletions src/debug_menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ enum class debug_menu_index : int {
EDIT_GLOBAL_VARS,
ACTIVATE_EOC,
WRITE_TIMED_EVENTS,
QUICKLOAD,
last
};

Expand Down
31 changes: 17 additions & 14 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
#include "line.h"
#include "live_view.h"
#include "loading_ui.h"
#include "main_menu.h"
#include "magic.h"
#include "make_static.h"
#include "map.h"
Expand Down Expand Up @@ -2424,9 +2425,7 @@ input_context get_default_mode_input_context()
ctxt.register_action( "workout" );
ctxt.register_action( "save" );
ctxt.register_action( "quicksave" );
#if !defined(RELEASE)
ctxt.register_action( "quickload" );
#endif
ctxt.register_action( "SUICIDE" );
ctxt.register_action( "player_data" );
ctxt.register_action( "map" );
Expand Down Expand Up @@ -12035,7 +12034,7 @@ void game::display_reachability_zones()
void game::init_autosave()
{
moves_since_last_save = 0;
last_save_timestamp = time( nullptr );
last_save_timestamp = std::time( nullptr );
}

void game::quicksave()
Expand All @@ -12051,7 +12050,7 @@ void game::quicksave()
ui_manager::redraw();
refresh_display();

time_t now = time( nullptr ); //timestamp for start of saving procedure
time_t now = std::time( nullptr ); //timestamp for start of saving procedure

//perform save
save();
Expand All @@ -12066,18 +12065,22 @@ void game::quickload()
if( active_world == nullptr ) {
return;
}
std::string const world_name = active_world->world_name;
std::string const &save_id = u.get_save_id();

if( active_world->save_exists( save_t::from_save_id( u.get_save_id() ) ) ) {
if( active_world->save_exists( save_t::from_save_id( save_id ) ) ) {
if( moves_since_last_save != 0 ) { // See if we need to reload anything
MAPBUFFER.clear();
overmap_buffer.clear();
try {
setup();
} catch( const std::exception &err ) {
debugmsg( "Error: %s", err.what() );
}
load( save_t::from_save_id( u.get_save_id() ) );
moves_since_last_save = 0;
last_save_timestamp = std::time( nullptr );

u.moves = 0;
uquit = QUIT_NOSAVED;

main_menu::queued_world_to_load = world_name;
main_menu::queued_save_id_to_load = save_id;

}

} else {
popup_getkey( _( "No saves for current character yet." ) );
}
Expand All @@ -12086,7 +12089,7 @@ void game::quickload()
void game::autosave()
{
//Don't autosave if the min-autosave interval has not passed since the last autosave/quicksave.
if( time( nullptr ) < last_save_timestamp + 60 * get_option<int>( "AUTOSAVE_MINUTES" ) ) {
if( std::time( nullptr ) < last_save_timestamp + 60 * get_option<int>( "AUTOSAVE_MINUTES" ) ) {
return;
}
quicksave(); //Driving checks are handled by quicksave()
Expand Down
6 changes: 2 additions & 4 deletions src/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -953,12 +953,11 @@ class game
void autosave(); // automatic quicksaves - Performs some checks before calling quicksave()
public:
void quicksave(); // Saves the game without quitting
void quickload(); // Loads the previously saved game if it exists
void disp_NPCs(); // Currently for debug use. Lists global NPCs.

void list_missions(); // Listed current, completed and failed missions (mission_ui.cpp)
private:
void quickload(); // Loads the previously saved game if it exists

// Input related
// Handles box showing items under mouse
bool handle_mouseview( input_context &ctxt, std::string &action );
Expand Down Expand Up @@ -1094,7 +1093,6 @@ class game
// tracks time since last monster seen to allow automatically
// reactivating safe mode.
time_duration turnssincelastmon = 0_turns;

private:
weather_manager weather; // NOLINT(cata-serialize)

Expand Down Expand Up @@ -1122,7 +1120,7 @@ class game
// NOLINTNEXTLINE(cata-serialize)
std::chrono::time_point<std::chrono::steady_clock> time_of_last_load;
int moves_since_last_save = 0; // NOLINT(cata-serialize)
time_t last_save_timestamp = 0; // NOLINT(cata-serialize)
std::time_t last_save_timestamp = 0; // NOLINT(cata-serialize)

mutable std::array<float, OVERMAP_LAYERS> latest_lightlevels; // NOLINT(cata-serialize)
// remoteveh() cache
Expand Down
17 changes: 6 additions & 11 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,7 @@ int main( int argc, const char *argv[] )
game_ui::init_ui();

g = std::make_unique<game>();

// First load and initialize everything that does not
// depend on the mods.
try {
Expand Down Expand Up @@ -769,20 +770,14 @@ int main( int argc, const char *argv[] )
return 0;
}

main_menu::queued_world_to_load = std::move( cli.world );

get_help().load();

while( true ) {
if( !cli.world.empty() ) {
if( !g->load( cli.world ) ) {
break;
}
cli.world.clear(); // ensure quit returns to opening screen

} else {
main_menu menu;
if( !menu.opening_screen() ) {
break;
}
main_menu menu;
if( !menu.opening_screen() ) {
break;
}

shared_ptr_fast<ui_adaptor> ui = g->create_or_get_main_ui_adaptor();
Expand Down
72 changes: 46 additions & 26 deletions src/main_menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,12 @@ enum class main_menu_opts : int {
CREDITS = 7,
QUIT = 8
};

static constexpr int max_menu_opts = 8;

std::string main_menu::queued_world_to_load;
std::string main_menu::queued_save_id_to_load;

static int getopt( main_menu_opts o )
{
return static_cast<int>( o );
Expand Down Expand Up @@ -599,6 +603,17 @@ bool main_menu::opening_screen()
} );
ui.mark_resize();

if( !queued_world_to_load.empty() ) {
save_t const &save_to_load = queued_save_id_to_load.empty() ? world_generator->get_world(
queued_world_to_load )->world_saves.front() : save_t::from_save_id( queued_save_id_to_load );
start = main_menu::load_game( queued_world_to_load, save_to_load );
queued_world_to_load.clear();
queued_save_id_to_load.clear();
if( start ) {
load_game = true;
}
}

while( !start ) {
ui_manager::redraw();
std::string action = ctxt.handle_input();
Expand Down Expand Up @@ -962,6 +977,36 @@ bool main_menu::new_character_tab()
return false;
}

bool main_menu::load_game( std::string const &worldname, save_t const &savegame )
{
avatar &pc = get_avatar();
on_out_of_scope cleanup( [&pc]() {
pc = avatar();
world_generator->set_active_world( nullptr );
} );

g->gamemode = nullptr;
WORLD *world = world_generator->get_world( worldname );
world_generator->last_world_name = world->world_name;
world_generator->last_character_name = savegame.decoded_name();
world_generator->save_last_world_info();
world_generator->set_active_world( world );

try {
g->setup();
} catch( const std::exception &err ) {
debugmsg( "Error: %s", err.what() );
return false;
}

if( g->load( savegame ) ) {
cleanup.cancel();
return true;
}

return false;
}

bool main_menu::load_character_tab( const std::string &worldname )
{
savegames = world_generator->get_world( worldname )->world_saves;
Expand Down Expand Up @@ -992,32 +1037,7 @@ bool main_menu::load_character_tab( const std::string &worldname )
return false;
}

avatar &pc = get_avatar();
on_out_of_scope cleanup( [&pc]() {
pc = avatar();
world_generator->set_active_world( nullptr );
} );

g->gamemode = nullptr;
WORLD *world = world_generator->get_world( worldname );
world_generator->last_world_name = world->world_name;
world_generator->last_character_name = savegames[opt_val].decoded_name();
world_generator->save_last_world_info();
world_generator->set_active_world( world );

try {
g->setup();
} catch( const std::exception &err ) {
debugmsg( "Error: %s", err.what() );
return false;
}

if( g->load( savegames[opt_val] ) ) {
cleanup.cancel();
return true;
}

return false;
return main_menu::load_game( worldname, savegames[opt_val] );
}

void main_menu::world_tab( const std::string &worldname )
Expand Down
3 changes: 3 additions & 0 deletions src/main_menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class main_menu
// Shows the main menu and returns whether a game was started or not
bool opening_screen();

static std::string queued_world_to_load;
static std::string queued_save_id_to_load;
private:
// ASCII art that says "Cataclysm Dark Days Ahead"
std::vector<std::string> mmenu_title;
Expand Down Expand Up @@ -55,6 +57,7 @@ class main_menu

// Tab functions. They return whether a game was started or not. The ones that can never
// start a game have a void return type.
bool load_game( std::string const &worldname, save_t const &savegame );
bool new_character_tab();
bool load_character_tab( const std::string &worldname );
void world_tab( const std::string &worldname );
Expand Down

0 comments on commit 72e6972

Please sign in to comment.