diff --git a/src/game_end_exceptions.cpp b/src/game_end_exceptions.cpp index 877c4e548927..bf35ef13edff 100644 --- a/src/game_end_exceptions.cpp +++ b/src/game_end_exceptions.cpp @@ -24,6 +24,7 @@ transient_end_level::transient_end_level() , custom_endlevel_music() , reveal_map(true) , disabled(false) + , proceed_to_next_level(false) {} end_level_data::end_level_data() diff --git a/src/game_end_exceptions.hpp b/src/game_end_exceptions.hpp index cab1e19b3761..f2421c7ac9df 100644 --- a/src/game_end_exceptions.hpp +++ b/src/game_end_exceptions.hpp @@ -91,6 +91,7 @@ struct transient_end_level{ std::string custom_endlevel_music; /**< Custom short music played at the end. */ bool reveal_map; /**< Should we reveal map when game is ended? (Multiplayer only) */ bool disabled; /**< Limits execution of tag [endlevel] to a single time > */ + bool proceed_to_next_level; /**< whether to proceed to the next scenario, equals (res == VICTORY) in sp. > */ }; /** diff --git a/src/play_controller.cpp b/src/play_controller.cpp index b47a23256467..6c2034889766 100644 --- a/src/play_controller.cpp +++ b/src/play_controller.cpp @@ -1486,6 +1486,8 @@ void play_controller::check_victory() } DBG_NG << "throwing end level exception..." << std::endl; + //Also proceed to the next scenario when another player survived. + end_level_data_.transient.proceed_to_next_level = found_player || found_network_player; throw end_level_exception(found_player ? VICTORY : DEFEAT); } diff --git a/src/playcampaign.cpp b/src/playcampaign.cpp index a47a9989b3d2..b9f9634fa90d 100644 --- a/src/playcampaign.cpp +++ b/src/playcampaign.cpp @@ -97,10 +97,10 @@ static void clear_carryover_WML (game_state & gamestate) { } } -static void store_carryover(game_state& gamestate, playsingle_controller& playcontroller, display& disp, const end_level_data& end_level){ +static void store_carryover(game_state& gamestate, playsingle_controller& playcontroller, display& disp, const end_level_data& end_level, const LEVEL_RESULT res){ bool has_next_scenario = !resources::gamedata->next_scenario().empty() && resources::gamedata->next_scenario() != "null"; - + //explain me: when could this be the case?? if(resources::teams->size() < 1){ gamestate.carryover_sides_start["next_scenario"] = resources::gamedata->next_scenario(); return; @@ -117,9 +117,12 @@ static void store_carryover(game_state& gamestate, playsingle_controller& playco if (obs) { title = _("Scenario Report"); - } else { + } else if (res == VICTORY) { title = _("Victory"); report << "" << _("You have emerged victorious!") << "\n\n"; + } else { + title = _("Defeat"); + report << _("You have been defeated!") << "\n"; } std::vector teams = playcontroller.get_teams_const(); @@ -130,7 +133,7 @@ static void store_carryover(game_state& gamestate, playsingle_controller& playco } } - if (persistent_teams > 0 && (has_next_scenario || + if (persistent_teams > 0 && ((has_next_scenario && end_level.transient.proceed_to_next_level)|| gamestate.classification().campaign_type == game_classification::TEST)) { gamemap map = playcontroller.get_map_const(); @@ -296,25 +299,17 @@ static LEVEL_RESULT playsingle_scenario(const config& game_config, config& cfg_end_level = state_of_game.carryover_sides.child_or_add("end_level_data"); end_level.write(cfg_end_level); - if (res == DEFEAT) { - if (resources::persist != NULL) - resources::persist->end_transaction(); - gui2::show_transient_message(disp.video(), - _("Defeat"), - _("You have been defeated!") - ); - } - else if(res == VICTORY){ - store_carryover(state_of_game, playcontroller, disp, end_level); - } - - if (!disp.video().faked() && res != QUIT) + if (res != QUIT) { - try { - playcontroller.maybe_linger(); - } catch(end_level_exception& e) { - if (e.result == QUIT) { - return QUIT; + store_carryover(state_of_game, playcontroller, disp, end_level, res); + if(!disp.video().faked()) + { + try { + playcontroller.maybe_linger(); + } catch(end_level_exception& e) { + if (e.result == QUIT) { + return QUIT; + } } } } @@ -347,27 +342,26 @@ static LEVEL_RESULT playmp_scenario(const config& game_config, if (io_type == IO_CLIENT && playcontroller.is_host()) io_type = IO_SERVER; - if (res == DEFEAT) { - if (resources::persist != NULL) - resources::persist->end_transaction(); - gui2::show_transient_message(disp.video(), - _("Defeat"), - _("You have been defeated!") - ); - } - else if(res == VICTORY){ - store_carryover(state_of_game, playcontroller, disp, end_level); - } - else if(res == OBSERVER_END){ - state_of_game.carryover_sides_start["next_scenario"] = resources::gamedata->next_scenario(); - } - - if (!disp.video().faked() && res != QUIT) { - try { - playcontroller.maybe_linger(); - } catch(end_level_exception& e) { - if (e.result == QUIT) { - return QUIT; + if (res != QUIT) + { + if(res != OBSERVER_END) + { + //We need to call this before linger because it also prints the defeated/victory message. + //(we want to see that message before entering the linger mode) + store_carryover(state_of_game, playcontroller, disp, end_level, res); + } + else + { + state_of_game.carryover_sides_start["next_scenario"] = resources::gamedata->next_scenario(); + } + if(!disp.video().faked()) + { + try { + playcontroller.maybe_linger(); + } catch(end_level_exception& e) { + if (e.result == QUIT) { + return QUIT; + } } } } @@ -535,13 +529,16 @@ LEVEL_RESULT play_game(game_display& disp, game_state& gamestate, gamestate.replay_start().clear(); // On DEFEAT, QUIT, or OBSERVER_END, we're done now - if (res != VICTORY) + //if(res == QUIT || ((res != VICTORY) && gamestate.carryover_sides_start["next_scenario"].empty())) + + //If there is no next scenario we're done now. + if(res == QUIT || !end_level.transient.proceed_to_next_level || gamestate.carryover_sides_start["next_scenario"].empty()) + { + gamestate.snapshot = config(); + return res; + } + else if(res == OBSERVER_END) { - if (res != OBSERVER_END || gamestate.carryover_sides_start["next_scenario"].empty()) { - gamestate.snapshot = config(); - return res; - } - const int dlg_res = gui2::show_message(disp.video(), _("Game Over"), _("This scenario has ended. Do you want to continue the campaign?"), gui2::tmessage::yes_no_buttons); diff --git a/src/playsingle_controller.cpp b/src/playsingle_controller.cpp index 598b0f900d47..10acc669604b 100644 --- a/src/playsingle_controller.cpp +++ b/src/playsingle_controller.cpp @@ -164,6 +164,7 @@ void playsingle_controller::check_end_level() } return; } + get_end_level_data().transient.proceed_to_next_level = (level_result_ == VICTORY); throw end_level_exception(level_result_); } @@ -522,6 +523,7 @@ LEVEL_RESULT playsingle_controller::play_scenario( if(defeat_music.empty() != true) sound::play_music_once(defeat_music); + persist_.end_transaction(); return DEFEAT; } else { return QUIT; @@ -989,6 +991,8 @@ void playsingle_controller::check_time_over(){ } check_victory(); + + get_end_level_data().transient.proceed_to_next_level = false; throw end_level_exception(DEFEAT); } }