From eb1c06e7f4e2e15ec1806bc302ffaf6e67ef2916 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Thu, 20 Oct 2016 15:16:42 -0400 Subject: [PATCH] Improve handling of map generator errors --- src/game_launcher.cpp | 2 + src/play_controller.cpp | 162 +++++++++++++++++++++------------------- 2 files changed, 87 insertions(+), 77 deletions(-) diff --git a/src/game_launcher.cpp b/src/game_launcher.cpp index 86c45369ae1e7..3457f760c2153 100644 --- a/src/game_launcher.cpp +++ b/src/game_launcher.cpp @@ -967,6 +967,8 @@ void game_launcher::launch_game(RELOAD_GAME_DATA reload) //this will make it so next time through the title screen loop, this game is loaded } catch(twml_exception& e) { e.show(video()); + } catch(mapgen_exception& e) { + gui2::show_error_message(video(), _("Map generator error: ") + e.message); } } diff --git a/src/play_controller.cpp b/src/play_controller.cpp index ca6bc97a5fe96..272002a2297ff 100644 --- a/src/play_controller.cpp +++ b/src/play_controller.cpp @@ -214,92 +214,100 @@ struct throw_end_level void play_controller::init(CVideo& video, const config& level) { + bool failed = true; + gui2::tloadscreen::display(video, [this, &video, &level, &failed]() { + try { + gui2::tloadscreen::progress("load level"); + + LOG_NG << "initializing game_state..." << (SDL_GetTicks() - ticks()) << std::endl; + gamestate_.reset(new game_state(level, *this, tdata_)); + + resources::gameboard = &gamestate().board_; + resources::gamedata = &gamestate().gamedata_; + resources::tod_manager = &gamestate().tod_manager_; + resources::units = &gamestate().board_.units_; + resources::filter_con = &gamestate(); + resources::undo_stack = &undo_stack(); + resources::game_events = gamestate().events_manager_.get(); + resources::lua_kernel = gamestate().lua_kernel_.get(); + + gamestate_->init(level, *this); + resources::tunnels = gamestate().pathfind_manager_.get(); + + LOG_NG << "initializing whiteboard..." << (SDL_GetTicks() - ticks()) << std::endl; + gui2::tloadscreen::progress("init whiteboard"); + whiteboard_manager_.reset(new wb::manager()); + resources::whiteboard = whiteboard_manager_; + + LOG_NG << "loading units..." << (SDL_GetTicks() - ticks()) << std::endl; + gui2::tloadscreen::progress("load units"); + preferences::encounter_all_content(gamestate().board_); + + LOG_NG << "initializing theme... " << (SDL_GetTicks() - ticks()) << std::endl; + gui2::tloadscreen::progress("init theme"); + const config& theme_cfg = controller_base::get_theme(game_config_, level["theme"]); + + LOG_NG << "building terrain rules... " << (SDL_GetTicks() - ticks()) << std::endl; + gui2::tloadscreen::progress("build terrain"); + gui_.reset(new game_display(gamestate().board_, video, whiteboard_manager_, *gamestate().reports_, gamestate().tod_manager_, theme_cfg, level)); + if (!gui_->video().faked()) { + if (saved_game_.mp_settings().mp_countdown) + gui_->get_theme().modify_label("time-icon", _ ("time left for current turn")); + else + gui_->get_theme().modify_label("time-icon", _ ("current local time")); + } - gui2::tloadscreen::display(video, [this, &video, &level]() { - gui2::tloadscreen::progress("load level"); - - LOG_NG << "initializing game_state..." << (SDL_GetTicks() - ticks()) << std::endl; - gamestate_.reset(new game_state(level, *this, tdata_)); - - resources::gameboard = &gamestate().board_; - resources::gamedata = &gamestate().gamedata_; - resources::tod_manager = &gamestate().tod_manager_; - resources::units = &gamestate().board_.units_; - resources::filter_con = &gamestate(); - resources::undo_stack = &undo_stack(); - resources::game_events = gamestate().events_manager_.get(); - resources::lua_kernel = gamestate().lua_kernel_.get(); - - gamestate_->init(level, *this); - resources::tunnels = gamestate().pathfind_manager_.get(); - - LOG_NG << "initializing whiteboard..." << (SDL_GetTicks() - ticks()) << std::endl; - gui2::tloadscreen::progress("init whiteboard"); - whiteboard_manager_.reset(new wb::manager()); - resources::whiteboard = whiteboard_manager_; - - LOG_NG << "loading units..." << (SDL_GetTicks() - ticks()) << std::endl; - gui2::tloadscreen::progress("load units"); - preferences::encounter_all_content(gamestate().board_); - - LOG_NG << "initializing theme... " << (SDL_GetTicks() - ticks()) << std::endl; - gui2::tloadscreen::progress("init theme"); - const config& theme_cfg = controller_base::get_theme(game_config_, level["theme"]); - - LOG_NG << "building terrain rules... " << (SDL_GetTicks() - ticks()) << std::endl; - gui2::tloadscreen::progress("build terrain"); - gui_.reset(new game_display(gamestate().board_, video, whiteboard_manager_, *gamestate().reports_, gamestate().tod_manager_, theme_cfg, level)); - if (!gui_->video().faked()) { - if (saved_game_.mp_settings().mp_countdown) - gui_->get_theme().modify_label("time-icon", _ ("time left for current turn")); - else - gui_->get_theme().modify_label("time-icon", _ ("current local time")); - } - - gui2::tloadscreen::progress("init display"); - mouse_handler_.set_gui(gui_.get()); - menu_handler_.set_gui(gui_.get()); - resources::screen = gui_.get(); + gui2::tloadscreen::progress("init display"); + mouse_handler_.set_gui(gui_.get()); + menu_handler_.set_gui(gui_.get()); + resources::screen = gui_.get(); - LOG_NG << "done initializing display... " << (SDL_GetTicks() - ticks()) << std::endl; + LOG_NG << "done initializing display... " << (SDL_GetTicks() - ticks()) << std::endl; - LOG_NG << "building gamestate to gui and whiteboard... " << (SDL_GetTicks() - ticks()) << std::endl; - // This *needs* to be created before the show_intro and show_map_scene - // as that functions use the manager state_of_game - // Has to be done before registering any events! - gamestate().set_game_display(gui_.get()); - gui2::tloadscreen::progress("init lua"); + LOG_NG << "building gamestate to gui and whiteboard... " << (SDL_GetTicks() - ticks()) << std::endl; + // This *needs* to be created before the show_intro and show_map_scene + // as that functions use the manager state_of_game + // Has to be done before registering any events! + gamestate().set_game_display(gui_.get()); + gui2::tloadscreen::progress("init lua"); - if(gamestate().first_human_team_ != -1) { - gui_->set_team(gamestate().first_human_team_); - } - else if(is_observer()) { - // Find first team that is allowed to be observed. - // If not set here observer would be without fog until - // the first turn of observable side - size_t i; - for (i=0;i < gamestate().board_.teams().size();++i) - { - if (!gamestate().board_.teams()[i].get_disallow_observers()) + if(gamestate().first_human_team_ != -1) { + gui_->set_team(gamestate().first_human_team_); + } + else if(is_observer()) { + // Find first team that is allowed to be observed. + // If not set here observer would be without fog until + // the first turn of observable side + size_t i; + for (i=0;i < gamestate().board_.teams().size();++i) { - gui_->set_team(i); + if (!gamestate().board_.teams()[i].get_disallow_observers()) + { + gui_->set_team(i); + } } } - } - init_managers(); - gui2::tloadscreen::progress("start game"); - //loadscreen_manager->reset(); - gamestate().gamedata_.set_phase(game_data::PRELOAD); - gamestate().lua_kernel_->load_game(level); - - plugins_context_.reset(new plugins_context("Game")); - plugins_context_->set_callback("save_game", [this](const config& cfg) { save_game_auto(cfg["filename"]); }, true); - plugins_context_->set_callback("save_replay", [this](const config& cfg) { save_replay_auto(cfg["filename"]); }, true); - plugins_context_->set_callback("quit", throw_end_level(), false); - plugins_context_->set_accessor_string("scenario_name", [this](config) { return get_scenario_name(); }); + init_managers(); + gui2::tloadscreen::progress("start game"); + //loadscreen_manager->reset(); + gamestate().gamedata_.set_phase(game_data::PRELOAD); + gamestate().lua_kernel_->load_game(level); + + plugins_context_.reset(new plugins_context("Game")); + plugins_context_->set_callback("save_game", [this](const config& cfg) { save_game_auto(cfg["filename"]); }, true); + plugins_context_->set_callback("save_replay", [this](const config& cfg) { save_replay_auto(cfg["filename"]); }, true); + plugins_context_->set_callback("quit", throw_end_level(), false); + plugins_context_->set_accessor_string("scenario_name", [this](config) { return get_scenario_name(); }); + failed = false; + } catch(twml_exception& e) { + e.show(video); + } }); - //Do this after the loadingscreen, so that ita happens in the main thread. + if(failed) { + throw_quit_game_exception(); + } + //Do this after the loadingscreen, so that it happens in the main thread. gui_->join(); }