Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix quickloading #60587

Merged
merged 4 commits into from
Sep 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -12039,7 +12038,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 @@ -12055,7 +12054,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 @@ -12070,18 +12069,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 @@ -12090,7 +12093,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