Use the MP "Back To .." Feature in SP too #7460

Previously the behavior was the following:
- When the  "Back to Turn" button was pressed in SP, The gamestate is
  reset to the gamestate of that turn.

- When the "Back to Turn" button is pressed in MP, The gamestate is
  reset to the gamestate of that turn and a replay is started
  replaying the game until the current gamestate (using the usual
  replay UI). This is in particular useful to replay the enemies
  moves (for example in case you were afk)

Using the MP version also in SP will not only also give
the campaign player a quick way to review the enemies turn,
but also allow the player to restart the gamestate from an
arbitiary point (instead of just the begin of the turn) by
pressing the "Continue from here" button in the the replay

Furthermore, the Autosaves can still be reloaded normally via
the usual Load game menu.

This might need some finetuning based on feedback, in particular:
- Should this be optional, via a game preference?
- Should the 'replay' start in a paused state instead of replaying
  right away like it does currently?
- Should we allows addons to disable this feature (in case that
  they know that their addon breaks replays)?
- Or when a huge majority of players dislikes this we can also of
  course easily revert it.
This commit is contained in:
gfgtdf 2023-03-20 00:36:29 +01:00
parent d0176732a4
commit 790948f623

View file

@ -309,30 +309,34 @@ bool playsingle_controller::hotkey_handler::can_execute_command(const hotkey::ho
void playsingle_controller::hotkey_handler::load_autosave(const std::string& filename)
{
if(playsingle_controller_.is_networked_mp())
{
config savegame;
std::string error_log;
savegame::read_save_file(filesystem::get_saves_dir(), filename, savegame, &error_log);
if(!error_log.empty() || savegame.child_or_empty("snapshot")["replay_pos"].to_int(-1) < 0 ) {
gui2::show_error_message(_("The file you have tried to load is corrupt: '") + error_log);
return;
auto invalid_save_file = [this, filename](std::string msg){
if(playsingle_controller_.is_networked_mp()) {
gui2::show_error_message(msg);
} else {
const int res = gui2::show_message("", msg + _("Do you want to load it anyway?"), gui2::dialogs::message::yes_no_buttons);
if(res == gui2::retval::CANCEL) {
play_controller::hotkey_handler::load_autosave(filename);
}
}
};
if(!playsingle_controller_.get_saved_game().get_replay().is_ancestor(savegame.child_or_empty("replay"))) {
gui2::show_error_message(_("The file you have tried to load is not from the current session"));
return;
}
config savegame;
std::string error_log;
savegame::read_save_file(filesystem::get_saves_dir(), filename, savegame, &error_log);
std::shared_ptr<config> res(new config(savegame.child_or_empty("snapshot")));
std::shared_ptr<config> stats(new config(savegame.child_or_empty("statistics")));
throw reset_gamestate_exception(res, stats, true);
if(!error_log.empty() || savegame.child_or_empty("snapshot")["replay_pos"].to_int(-1) < 0 ) {
invalid_save_file(_("The file you have tried to load is corrupt: '") + error_log);
return;
}
else
{
play_controller::hotkey_handler::load_autosave(filename);
if(!playsingle_controller_.get_saved_game().get_replay().is_ancestor(savegame.child_or_empty("replay"))) {
invalid_save_file(_("The file you have tried to load is not from the current session"));
return;
}
std::shared_ptr<config> res(new config(savegame.child_or_empty("snapshot")));
std::shared_ptr<config> stats(new config(savegame.child_or_empty("statistics")));
throw reset_gamestate_exception(res, stats, true);
}
void playsingle_controller::hotkey_handler::replay_exit()