game_controller.cpp

Go to the documentation of this file.
00001 /* $Id: game_controller.cpp 53010 2012-02-14 18:17:09Z shadowmaster $ */
00002 /*
00003    Copyright (C) 2003 - 2012 by David White <dave@whitevine.net>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 #include "game_controller.hpp"
00017 
00018 #include "about.hpp"
00019 #include "addon/manager.hpp"
00020 #include "ai/configuration.hpp"
00021 #include "builder.hpp"
00022 #include "construct_dialog.hpp"
00023 #include "gettext.hpp"
00024 #include "gui/dialogs/addon_connect.hpp"
00025 #include "gui/dialogs/campaign_difficulty.hpp"
00026 #include "gui/dialogs/campaign_selection.hpp"
00027 #include "gui/dialogs/language_selection.hpp"
00028 #include "gui/dialogs/message.hpp"
00029 #include "gui/dialogs/mp_method_selection.hpp"
00030 #include "gui/dialogs/title_screen.hpp"
00031 #include "gui/dialogs/transient_message.hpp"
00032 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
00033 #include "gui/widgets/debug.hpp"
00034 #endif
00035 #include "gui/auxiliary/event/handler.hpp"
00036 #include "gui/widgets/settings.hpp"
00037 #include "gui/widgets/window.hpp"
00038 #include "intro.hpp"
00039 #include "language.hpp"
00040 #include "loadscreen.hpp"
00041 #include "log.hpp"
00042 #include "map_exception.hpp"
00043 #include "multiplayer.hpp"
00044 #include "network.hpp"
00045 #include "playcampaign.hpp"
00046 #include "preferences_display.hpp"
00047 #include "replay.hpp"
00048 #include "savegame.hpp"
00049 #include "scripting/lua.hpp"
00050 #include "statistics.hpp"
00051 #include "wml_exception.hpp"
00052 #include "gui/dialogs/mp_host_game_prompt.hpp"
00053 
00054 static lg::log_domain log_config("config");
00055 #define ERR_CONFIG LOG_STREAM(err, log_config)
00056 #define WRN_CONFIG LOG_STREAM(warn, log_config)
00057 #define LOG_CONFIG LOG_STREAM(info, log_config)
00058 
00059 #define LOG_GENERAL LOG_STREAM(info, lg::general)
00060 #define WRN_GENERAL LOG_STREAM(warn, lg::general)
00061 #define DBG_GENERAL LOG_STREAM(debug, lg::general)
00062 
00063 static lg::log_domain log_network("network");
00064 #define ERR_NET LOG_STREAM(err, log_network)
00065 
00066 static bool less_campaigns_rank(const config &a, const config &b) {
00067     return a["rank"].to_int(1000) < b["rank"].to_int(1000);
00068 }
00069 
00070 game_controller::game_controller(const commandline_options& cmdline_opts, const char *appname) :
00071     game_controller_abstract(cmdline_opts),
00072     thread_manager(),
00073     font_manager_(),
00074     prefs_manager_(),
00075     image_manager_(),
00076     main_event_context_(),
00077     hotkey_manager_(),
00078     music_thinker_(),
00079     resize_monitor_(),
00080     paths_manager_(),
00081     test_scenario_("test"),
00082     screenshot_map_(),
00083     screenshot_filename_(),
00084     game_config_(),
00085     old_defines_map_(),
00086     state_(),
00087     multiplayer_server_(),
00088     jump_to_multiplayer_(false),
00089     jump_to_campaign_(false, -1, "", ""),
00090     jump_to_editor_(false),
00091     cache_(game_config::config_cache::instance())
00092 {
00093     bool no_music = false;
00094     bool no_sound = false;
00095 
00096     // The path can be hardcoded and it might be a relative path.
00097     if(!game_config::path.empty() &&
00098 #ifdef _WIN32
00099         // use c_str to ensure that index 1 points to valid element since c_str() returns null-terminated string
00100         game_config::path.c_str()[1] != ':'
00101 #else
00102         game_config::path[0] != '/'
00103 #endif
00104     )
00105     {
00106         game_config::path = get_cwd() + '/' + game_config::path;
00107         font_manager_.update_font_path();
00108     }
00109 
00110     const std::string app_basename = file_name(appname);
00111     jump_to_editor_ = app_basename.find("editor") != std::string::npos;
00112 
00113     if (cmdline_opts_.campaign) {
00114         jump_to_campaign_.jump_ = true;
00115         jump_to_campaign_.campaign_id_ = *cmdline_opts_.campaign;
00116         std::cerr << "selected campaign id: [" << jump_to_campaign_.campaign_id_ << "]\n";
00117 
00118         if (cmdline_opts_.campaign_difficulty) {
00119             jump_to_campaign_.difficulty_ = *cmdline_opts_.campaign_difficulty;
00120             std::cerr << "selected difficulty: [" << jump_to_campaign_.difficulty_ << "]\n";
00121         }
00122         else
00123             jump_to_campaign_.difficulty_ = -1; // let the user choose the difficulty
00124 
00125         if (cmdline_opts_.campaign_scenario) {
00126             jump_to_campaign_.scenario_id_ = *cmdline_opts_.campaign_scenario;
00127             std::cerr << "selected scenario id: [" << jump_to_campaign_.scenario_id_ << "]\n";
00128         }
00129     }
00130     if (cmdline_opts_.clock)
00131         gui2::show_debug_clock_button = true;
00132     if (cmdline_opts_.debug) {
00133         game_config::debug = true;
00134         game_config::mp_debug = true;
00135     }
00136 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
00137     if (cmdline_opts_.debug_dot_domain)
00138         gui2::tdebug_layout_graph::set_domain (*cmdline_opts_.debug_dot_domain);
00139     if (cmdline_opts_.debug_dot_level)
00140         gui2::tdebug_layout_graph::set_level (*cmdline_opts_.debug_dot_level);
00141 #endif
00142     if (cmdline_opts_.editor)
00143     {
00144         jump_to_editor_ = true;
00145         if(!cmdline_opts_.editor->empty())
00146             game::load_game_exception::game = *cmdline_opts_.editor;
00147     }
00148     if (cmdline_opts_.fps)
00149         preferences::set_show_fps(true);
00150     if (cmdline_opts_.fullscreen)
00151         preferences::set_fullscreen(true);
00152     if (cmdline_opts_.load)
00153         game::load_game_exception::game = *cmdline_opts_.load;
00154     if (cmdline_opts_.max_fps) {
00155         int fps;
00156         //FIXME: remove the next line once the weird util.cpp specialized template lexical_cast_default() linking issue is solved
00157         fps = lexical_cast_default<int>("", 50);
00158         fps = *cmdline_opts_.max_fps;
00159         fps = std::min<int>(fps, 1000);
00160         fps = std::max<int>(fps, 1);
00161         fps = 1000 / fps;
00162         // increase the delay to avoid going above the maximum
00163         if(1000 % fps != 0) {
00164             ++fps;
00165         }
00166         preferences::set_draw_delay(fps);
00167     }
00168     if (cmdline_opts_.nogui) {
00169         no_sound = true;
00170         preferences::disable_preferences_save();
00171     }
00172     if (cmdline_opts_.new_storyscreens)
00173         // This is a hidden option to help testing
00174         // the work-in-progress new storyscreen code.
00175         // Don't document.
00176         set_new_storyscreen(true);
00177     if (cmdline_opts_.new_widgets)
00178         gui2::new_widgets = true;
00179     if (cmdline_opts_.nocache)
00180         cache_.set_use_cache(false);
00181     if (cmdline_opts_.nodelay)
00182         game_config::no_delay = true;
00183     if (cmdline_opts_.nomusic)
00184         no_music = true;
00185     if (cmdline_opts_.nosound)
00186         no_sound = true;
00187     //These commented lines should be used to implement support of connection
00188     //through a proxy via command line options.
00189     //The ANA network module should implement these methods (while the SDL_net won't.)
00190     if (cmdline_opts_.proxy)
00191         network::enable_connection_through_proxy();
00192     if (cmdline_opts_.proxy_address)
00193     {
00194         network::enable_connection_through_proxy();
00195         network::set_proxy_address(*cmdline_opts_.proxy_address);
00196     }
00197     if (cmdline_opts_.proxy_password)
00198     {
00199         network::enable_connection_through_proxy();
00200         network::set_proxy_password(*cmdline_opts_.proxy_password);
00201     }
00202     if (cmdline_opts_.proxy_port)
00203     {
00204         network::enable_connection_through_proxy();
00205         network::set_proxy_port(*cmdline_opts_.proxy_port);
00206     }
00207     if (cmdline_opts_.proxy_user)
00208     {
00209         network::enable_connection_through_proxy();
00210         network::set_proxy_user(*cmdline_opts_.proxy_user);
00211     }
00212     if (cmdline_opts_.resolution) {
00213         const int xres = cmdline_opts_.resolution->get<0>();
00214         const int yres = cmdline_opts_.resolution->get<1>();
00215         if(xres > 0 && yres > 0) {
00216             const std::pair<int,int> resolution(xres,yres);
00217             preferences::set_resolution(resolution);
00218         }
00219     }
00220     if (cmdline_opts_.screenshot) {
00221         //TODO it could be simplified to use cmdline_opts_ directly if there is no other way to enter screenshot mode
00222         screenshot_map_ = *cmdline_opts_.screenshot_map_file;
00223         screenshot_filename_ = *cmdline_opts_.screenshot_output_file;
00224         no_sound = true;
00225         preferences::disable_preferences_save();
00226     }
00227     if (cmdline_opts_.server){
00228         jump_to_multiplayer_ = true;
00229         //Do we have any server specified ?
00230         if (!cmdline_opts_.server->empty())
00231             multiplayer_server_ = *cmdline_opts_.server;
00232         else //Pick the first server in config
00233         {
00234             if (game_config::server_list.size() > 0)
00235                 multiplayer_server_ = preferences::network_host();
00236             else
00237                 multiplayer_server_ = "";
00238         }
00239     }
00240     if (cmdline_opts_.username) {
00241         preferences::disable_preferences_save();
00242         preferences::set_login(*cmdline_opts_.username);
00243     }
00244     if (cmdline_opts_.password) {
00245         preferences::disable_preferences_save();
00246         preferences::set_password(*cmdline_opts_.password);
00247     }
00248     if (cmdline_opts_.smallgui)
00249         game_config::small_gui = true;
00250     if (cmdline_opts_.test)
00251     {
00252         if (!cmdline_opts_.test->empty())
00253             test_scenario_ = *cmdline_opts_.test;
00254     }
00255     if (cmdline_opts_.validcache)
00256         cache_.set_force_valid_cache(true);
00257     if (cmdline_opts_.windowed)
00258         preferences::set_fullscreen(false);
00259     if (cmdline_opts_.with_replay)
00260         game::load_game_exception::show_replay = true;
00261 
00262     std::cerr << '\n';
00263     std::cerr << "Data directory: " << game_config::path
00264         << "\nUser configuration directory: " << get_user_config_dir()
00265         << "\nUser data directory: " << get_user_data_dir()
00266         << "\nCache directory: " << get_cache_dir()
00267         << '\n';
00268 
00269     // disable sound in nosound mode, or when sound engine failed to initialize
00270     if (no_sound || ((preferences::sound_on() || preferences::music_on() ||
00271                       preferences::turn_bell() || preferences::UI_sound_on()) &&
00272                      !sound::init_sound())) {
00273         preferences::set_sound(false);
00274         preferences::set_music(false);
00275         preferences::set_turn_bell(false);
00276         preferences::set_UI_sound(false);
00277     }
00278     else if (no_music) { // else disable the music in nomusic mode
00279         preferences::set_music(false);
00280     }
00281 }
00282 
00283 bool game_controller::init_config(const bool force)
00284 {
00285     cache_.clear_defines();
00286 
00287     // make sure that multiplayer mode is set if command line parameter is selected
00288     if (cmdline_opts_.multiplayer)
00289         cache_.add_define("MULTIPLAYER");
00290 
00291     if (cmdline_opts_.test)
00292         cache_.add_define("TEST");
00293 
00294     if (jump_to_editor_)
00295         cache_.add_define("EDITOR");
00296 
00297     if (!cmdline_opts_.multiplayer && !cmdline_opts_.test && !jump_to_editor_)
00298         cache_.add_define("TITLE_SCREEN");
00299 
00300     load_game_cfg(force);
00301 
00302     game_config::load_config(game_config_.child("game_config"));
00303 
00304     hotkey::deactivate_all_scopes();
00305     hotkey::set_scope_active(hotkey::SCOPE_GENERAL);
00306     hotkey::set_scope_active(hotkey::SCOPE_GAME);
00307 
00308     hotkey::load_hotkeys(game_config(), true);
00309     paths_manager_.set_paths(game_config());
00310 	::init_textdomains(game_config());
00311     about::set_about(game_config());
00312     ai::configuration::init(game_config());
00313 
00314     return true;
00315 }
00316 
00317 bool game_controller::play_test()
00318 {
00319     static bool first_time = true;
00320 
00321     if(!cmdline_opts_.test) {
00322         return true;
00323     }
00324     if(!first_time)
00325         return false;
00326 
00327     first_time = false;
00328 
00329     state_.classification().campaign_type = "test";
00330     state_.classification().scenario = test_scenario_;
00331     state_.classification().campaign_define = "TEST";
00332     cache_.add_define("TEST");
00333 
00334     load_game_cfg();
00335 
00336     paths_manager_.set_paths(game_config());
00337 
00338     try {
00339         play_game(disp(),state_,game_config());
00340     } catch (game::load_game_exception &) {
00341         return true;
00342     }
00343 
00344     return false;
00345 }
00346 
00347 bool game_controller::play_screenshot_mode()
00348 {
00349     if(!cmdline_opts_.screenshot) {
00350         return true;
00351     }
00352 
00353     cache_.clear_defines();
00354     cache_.add_define("EDITOR");
00355     load_game_cfg();
00356     const binary_paths_manager bin_paths_manager(game_config());
00357 	::init_textdomains(game_config());
00358 
00359     editor::start(game_config(), video_, screenshot_map_, true, screenshot_filename_);
00360     return false;
00361 }
00362 
00363 bool game_controller::play_multiplayer_mode()
00364 {
00365     state_ = game_state();
00366 
00367     if(!cmdline_opts_.multiplayer) {
00368         return true;
00369     }
00370 
00371     std::string era = "era_default";
00372     std::string scenario = "multiplayer_The_Freelands";
00373     std::map<int,std::string> side_types, side_controllers, side_algorithms, side_ai_configs;
00374     std::map<int,utils::string_map> side_parameters;
00375     std::string turns = "50";
00376     std::string label = "";
00377 
00378     size_t sides_counted = 0;
00379 
00380     if (cmdline_opts_.multiplayer_ai_config)
00381     {
00382         for(std::vector<boost::tuple<unsigned int, std::string> >::const_iterator it=cmdline_opts_.multiplayer_ai_config->begin(); it!=cmdline_opts_.multiplayer_ai_config->end(); ++it)
00383         {
00384             const unsigned int side = it->get<0>();
00385             const std::string ai_cfg_name = it->get<1>();
00386             if (side > sides_counted)
00387             {
00388                 std::cerr << "counted sides: " << side << "\n";
00389                 sides_counted = side;
00390             }
00391             side_ai_configs[side] = ai_cfg_name;
00392         }
00393     }
00394     if (cmdline_opts_.multiplayer_algorithm)
00395     {
00396         for(std::vector<boost::tuple<unsigned int, std::string> >::const_iterator it=cmdline_opts_.multiplayer_algorithm->begin(); it!=cmdline_opts_.multiplayer_algorithm->end(); ++it)
00397         {
00398             const unsigned int side = it->get<0>();
00399             const std::string algorithm_id = it->get<1>();
00400             if (side > sides_counted)
00401             {
00402                 std::cerr << "counted sides: " << side << "\n";
00403                 sides_counted = side;
00404             }
00405             side_algorithms[side] = algorithm_id;
00406         }
00407     }
00408     if (cmdline_opts_.multiplayer_controller)
00409     {
00410         for(std::vector<boost::tuple<unsigned int, std::string> >::const_iterator it=cmdline_opts_.multiplayer_controller->begin(); it!=cmdline_opts_.multiplayer_controller->end(); ++it)
00411         {
00412             const unsigned int side = it->get<0>();
00413             const std::string controller_id = it->get<1>();
00414             if (side > sides_counted)
00415             {
00416                 std::cerr << "counted sides: " << side << "\n";
00417                 sides_counted = side;
00418             }
00419             side_controllers[side] = controller_id;
00420         }
00421     }
00422     if (cmdline_opts_.multiplayer_era)
00423         era = *cmdline_opts_.multiplayer_era;
00424     if (cmdline_opts_.multiplayer_exit_at_end)
00425         game_config::exit_at_end = true;
00426     if (cmdline_opts_.multiplayer_label)
00427         label = *cmdline_opts_.multiplayer_label;
00428     if (cmdline_opts_.multiplayer_parm)
00429     {
00430         for(std::vector<boost::tuple<unsigned int, std::string, std::string> >::const_iterator it=cmdline_opts_.multiplayer_parm->begin(); it!=cmdline_opts_.multiplayer_parm->end(); ++it)
00431         {
00432             const unsigned int side = it->get<0>();
00433             const std::string param_name = it->get<1>();
00434             const std::string param_value = it->get<2>();
00435             side_parameters[side][param_name] = param_value;
00436         }
00437     }
00438     if (cmdline_opts_.multiplayer_scenario)
00439         scenario = *cmdline_opts_.multiplayer_scenario;
00440     if (cmdline_opts_.multiplayer_side)
00441     {
00442         for(std::vector<boost::tuple<unsigned int, std::string> >::const_iterator it=cmdline_opts_.multiplayer_side->begin(); it!=cmdline_opts_.multiplayer_side->end(); ++it)
00443         {
00444             const unsigned int side = it->get<0>();
00445             const std::string faction_id = it->get<1>();
00446             if (side > sides_counted)
00447             {
00448                 std::cerr << "counted sides: " << side << "\n";
00449                 sides_counted = side;
00450             }
00451             side_types[side] = faction_id;
00452         }
00453     }
00454     if (cmdline_opts_.multiplayer_turns)
00455         turns = *cmdline_opts_.multiplayer_turns;
00456 
00457     const config &lvl = game_config().find_child("multiplayer", "id", scenario);
00458     if (!lvl) {
00459         std::cerr << "Could not find scenario '" << scenario << "'\n";
00460         return false;
00461     }
00462 
00463     state_.classification().campaign_type = "multiplayer";
00464     state_.classification().scenario = "";
00465     state_.snapshot = config();
00466 
00467     config level = lvl;
00468 
00469     const config &era_cfg = game_config().find_child("era","id",era);
00470     if (!era_cfg) {
00471         std::cerr << "Could not find era '" << era << "'\n";
00472         return false;
00473     }
00474 
00475     level["turns"] = turns;
00476 
00477     const config &side = era_cfg.child("multiplayer_side");
00478     if (!side) {
00479         std::cerr << "Could not find multiplayer side\n";
00480         return false;
00481     }
00482 
00483     while (level.child_count("side") < sides_counted) {
00484         std::cerr << "now adding side...\n";
00485         level.add_child("side");
00486     }
00487 
00488     int side_num = 1;
00489     foreach (config &s, level.child_range("side"))
00490     {
00491         std::map<int,std::string>::const_iterator type = side_types.find(side_num),
00492                                                   controller = side_controllers.find(side_num),
00493                                                   algorithm = side_algorithms.find(side_num),
00494                               ai_config = side_ai_configs.find(side_num);
00495 
00496         const config* side = type == side_types.end() ?
00497             &era_cfg.find_child("multiplayer_side", "random_faction", "yes") :
00498             &era_cfg.find_child("multiplayer_side", "id", type->second);
00499 
00500         if (!*side) {
00501             std::string side_name = (type == side_types.end() ? "default" : type->second);
00502             std::cerr << "Could not find side '" << side_name << "' for side " << side_num << "\n";
00503             return false;
00504         }
00505 
00506         if ((*side)["random_faction"].to_bool())
00507         {
00508             std::vector<std::string> faction_choices, faction_excepts;
00509             faction_choices = utils::split((*side)["choices"]);
00510             if(faction_choices.size() == 1 && faction_choices.front() == "") {
00511                 faction_choices.clear();
00512             }
00513             faction_excepts = utils::split((*side)["except"]);;
00514             if(faction_excepts.size() == 1 && faction_excepts.front() == "") {
00515                 faction_excepts.clear();
00516             }
00517             unsigned j = 0;
00518             foreach (const config &faction, era_cfg.child_range("multiplayer_side"))
00519             {
00520                 if (faction["random_faction"].to_bool()) continue;
00521                 const std::string &faction_id = faction["id"];
00522                 if (!faction_choices.empty() &&
00523                     std::find(faction_choices.begin(), faction_choices.end(), faction_id) == faction_choices.end())
00524                     continue;
00525                 if (!faction_excepts.empty() &&
00526                     std::find(faction_excepts.begin(), faction_excepts.end(), faction_id) != faction_excepts.end())
00527                     continue;
00528                 if (rand() % ++j == 0)
00529                     side = &faction;
00530             }
00531             if ((*side)["random_faction"].to_bool()) {
00532                 std::cerr << "Could not find any non-random faction for side " << side_num << "\n";
00533                 return false;
00534             }
00535             std::cerr << " Faction " << (*side)["name"] <<
00536                 " selected for side " << side_num << ".\n";
00537         }
00538 
00539         s["side"] = side_num;
00540         s["canrecruit"] = true;
00541 
00542         s.append(*side);
00543 
00544         if(controller != side_controllers.end()) {
00545             s["controller"] = controller->second;
00546         }
00547 
00548         if(algorithm != side_algorithms.end()) {
00549             s["ai_algorithm"] = algorithm->second;
00550         }
00551 
00552         if(ai_config != side_ai_configs.end()) {
00553             s["ai_config"] = ai_config->second;
00554         }
00555 
00556         config& ai_params = s.add_child("ai");
00557 
00558         //now add in any arbitrary parameters given to the side
00559         for(utils::string_map::const_iterator j = side_parameters[side_num].begin(); j != side_parameters[side_num].end(); ++j) {
00560             s[j->first] = j->second;
00561             ai_params[j->first] = j->second;
00562         }
00563         ++side_num;
00564     }
00565     level.add_child("era", era_cfg);
00566 
00567     try {
00568         recorder.add_log_data("ai_log","ai_label",label);
00569         state_.snapshot = level;
00570         play_game(disp(), state_, game_config());
00571     } catch (game::load_game_exception &) {
00572         //the user's trying to load a game, so go into the normal title screen loop and load one
00573         return true;
00574     } catch(twml_exception& e) {
00575         e.show(disp());
00576         return false;
00577     } catch(std::exception& e) {
00578         std::cerr << "caught exception: " << e.what() << "\n";
00579     } catch(...) {
00580         std::cerr << "caught unknown error playing level...\n";
00581     }
00582 
00583     return false;
00584 }
00585 
00586 bool game_controller::is_loading() const
00587 {
00588     return !game::load_game_exception::game.empty();
00589 }
00590 
00591 bool game_controller::load_game()
00592 {
00593     savegame::loadgame load(disp(), game_config(), state_);
00594 
00595     try {
00596         load.load_game(game::load_game_exception::game, game::load_game_exception::show_replay, game::load_game_exception::cancel_orders, game::load_game_exception::select_difficulty, game::load_game_exception::difficulty);
00597 
00598         cache_.clear_defines();
00599         game_config::scoped_preproc_define dificulty_def(state_.classification().difficulty);
00600 
00601         game_config::scoped_preproc_define campaign_define_def(state_.classification().campaign_define, !state_.classification().campaign_define.empty());
00602 
00603         game_config::scoped_preproc_define campaign_type_def("MULTIPLAYER", state_.classification().campaign_define.empty() && (state_.classification().campaign_type == "multiplayer"));
00604 
00605         typedef boost::shared_ptr<game_config::scoped_preproc_define> define_ptr;
00606         std::deque<define_ptr> extra_defines;
00607         for(std::vector<std::string>::const_iterator i = state_.classification().campaign_xtra_defines.begin(); i != state_.classification().campaign_xtra_defines.end(); ++i) {
00608             define_ptr newdefine(new game_config::scoped_preproc_define(*i));
00609             extra_defines.push_back(newdefine);
00610         }
00611 
00612         try {
00613             load_game_cfg();
00614         } catch(config::error&) {
00615             cache_.clear_defines();
00616             load_game_cfg();
00617             return false;
00618         }
00619 
00620         paths_manager_.set_paths(game_config());
00621         load.set_gamestate();
00622 
00623     } catch(load_game_cancelled_exception&) {
00624         clear_loaded_game();
00625         return false;
00626     } catch(config::error& e) {
00627         if(e.message.empty()) {
00628             gui2::show_error_message(disp().video(), _("The file you have tried to load is corrupt"));
00629         }
00630         else {
00631             gui2::show_error_message(disp().video(), _("The file you have tried to load is corrupt: '") + e.message + '\'');
00632         }
00633         return false;
00634     } catch(twml_exception& e) {
00635         e.show(disp());
00636         return false;
00637     } catch(io_exception& e) {
00638         if(e.message.empty()) {
00639             gui2::show_error_message(disp().video(), _("File I/O Error while reading the game"));
00640         } else {
00641             gui2::show_error_message(disp().video(), _("File I/O Error while reading the game: '") + e.message + '\'');
00642         }
00643         return false;
00644     } catch(game::error& e) {
00645         if(e.message.empty()) {
00646             gui2::show_error_message(disp().video(), _("The file you have tried to load is corrupt"));
00647         }
00648         else {
00649             gui2::show_error_message(disp().video(), _("The file you have tried to load is corrupt: '") + e.message + '\'');
00650         }
00651         return false;
00652     }
00653     recorder = replay(state_.replay_data);
00654     recorder.start_replay();
00655     recorder.set_skip(false);
00656 
00657     LOG_CONFIG << "has snapshot: " << (state_.snapshot.child("side") ? "yes" : "no") << "\n";
00658 
00659     if (!state_.snapshot.child("side")) {
00660         // No snapshot; this is a start-of-scenario
00661         if (load.show_replay()) {
00662             // There won't be any turns to replay, but the
00663             // user gets to watch the intro sequence again ...
00664             LOG_CONFIG << "replaying (start of scenario)\n";
00665         } else {
00666             LOG_CONFIG << "skipping...\n";
00667             recorder.set_skip(false);
00668         }
00669     } else {
00670         // We have a snapshot. But does the user want to see a replay?
00671         if(load.show_replay()) {
00672             statistics::clear_current_scenario();
00673             LOG_CONFIG << "replaying (snapshot)\n";
00674         } else {
00675             LOG_CONFIG << "setting replay to end...\n";
00676             recorder.set_to_end();
00677             if(!recorder.at_end()) {
00678                 WRN_CONFIG << "recorder is not at the end!!!\n";
00679             }
00680         }
00681     }
00682 
00683     if(state_.classification().campaign_type == "multiplayer") {
00684         foreach (config &side, state_.snapshot.child_range("side"))
00685         {
00686             if (side["controller"] == "network")
00687                 side["controller"] = "human";
00688             if (side["controller"] == "network_ai")
00689                 side["controller"] = "human_ai";
00690         }
00691     }
00692 
00693     if (load.cancel_orders()) {
00694         foreach (config &side, state_.snapshot.child_range("side"))
00695         {
00696             if (side["controller"] != "human") continue;
00697             foreach (config &unit, side.child_range("unit"))
00698             {
00699                 unit["goto_x"] = -999;
00700                 unit["goto_y"] = -999;
00701             }
00702         }
00703     }
00704 
00705     return true;
00706 }
00707 
00708 void game_controller::set_tutorial()
00709 {
00710     state_ = game_state();
00711     state_.classification().campaign_type = "tutorial";
00712     state_.classification().scenario = "tutorial";
00713     state_.classification().campaign_define = "TUTORIAL";
00714     cache_.clear_defines();
00715     cache_.add_define("TUTORIAL");
00716 
00717 }
00718 
00719 void game_controller::mark_completed_campaigns(std::vector<config> &campaigns)
00720 {
00721     foreach (config &campaign, campaigns) {
00722         campaign["completed"] = preferences::is_campaign_completed(campaign["id"]);
00723     }
00724 }
00725 
00726 bool game_controller::new_campaign()
00727 {
00728     state_ = game_state();
00729     state_.classification().campaign_type = "scenario";
00730 
00731     const config::const_child_itors &ci = game_config().child_range("campaign");
00732     std::vector<config> campaigns(ci.first, ci.second);
00733     mark_completed_campaigns(campaigns);
00734     std::stable_sort(campaigns.begin(),campaigns.end(),less_campaigns_rank);
00735 
00736     if(campaigns.begin() == campaigns.end()) {
00737       gui2::show_error_message(disp().video(),
00738                   _("No campaigns are available.\n"));
00739         return false;
00740     }
00741 
00742     int campaign_num = -1;
00743     // No campaign selected from command line
00744     if (jump_to_campaign_.campaign_id_.empty() == true)
00745     {
00746         gui2::tcampaign_selection dlg(campaigns);
00747 
00748         try {
00749             dlg.show(disp().video());
00750         } catch(twml_exception& e) {
00751             e.show(disp());
00752             return false;
00753         }
00754 
00755         if(dlg.get_retval() != gui2::twindow::OK) {
00756             return false;
00757         }
00758 
00759         campaign_num = dlg.get_choice();
00760     }
00761     else
00762     {
00763         // don't reset the campaign_id_ so we can know
00764         // if we should quit the game or return to the main menu
00765 
00766         // checking for valid campaign name
00767         for(size_t i = 0; i < campaigns.size(); ++i)
00768         {
00769             if (campaigns[i]["id"] == jump_to_campaign_.campaign_id_)
00770             {
00771                 campaign_num = i;
00772                 break;
00773             }
00774         }
00775 
00776         // didn't found any campaign with that id
00777         if (campaign_num == -1)
00778         {
00779             std::cerr<<"No such campaign id to jump to: ["<<jump_to_campaign_.campaign_id_<<"]\n";
00780             return false;
00781         }
00782     }
00783 
00784     const config &campaign = campaigns[campaign_num];
00785     state_.classification().campaign = campaign["id"].str();
00786     state_.classification().abbrev = campaign["abbrev"].str();
00787 
00788     // we didn't specify in the command line the scenario to be started
00789     if (jump_to_campaign_.scenario_id_.empty())
00790         state_.classification().scenario = campaign["first_scenario"].str();
00791     else
00792         state_.classification().scenario = jump_to_campaign_.scenario_id_;
00793 
00794     state_.classification().end_text = campaign["end_text"].str();
00795     state_.classification().end_text_duration = campaign["end_text_duration"];
00796 
00797     const std::string difficulty_descriptions = campaign["difficulty_descriptions"];
00798     std::vector<std::string> difficulty_options = utils::split(difficulty_descriptions, ';');
00799 
00800     const std::vector<std::string> difficulties = utils::split(campaign["difficulties"]);
00801 
00802     if(difficulties.empty() == false) {
00803         int difficulty = 0;
00804         if (jump_to_campaign_.difficulty_ == -1){
00805             if(difficulty_options.size() != difficulties.size()) {
00806                 difficulty_options.resize(difficulties.size());
00807                 std::copy(difficulties.begin(),difficulties.end(),difficulty_options.begin());
00808             }
00809 
00810             gui2::tcampaign_difficulty dlg(difficulty_options);
00811             dlg.show(disp().video());
00812 
00813             if(dlg.selected_index() == -1) {
00814                 if (jump_to_campaign_.campaign_id_.empty() == false)
00815                 {
00816                     jump_to_campaign_.campaign_id_ = "";
00817                 }
00818                 // canceled difficulty dialog, relaunch the campaign selection dialog
00819                 return new_campaign();
00820             }
00821             difficulty = dlg.selected_index();
00822         }
00823         else
00824         {
00825             if (jump_to_campaign_.difficulty_
00826                     > static_cast<int>(difficulties.size()))
00827             {
00828                 std::cerr << "incorrect difficulty number: [" <<
00829                     jump_to_campaign_.difficulty_ << "]. maximum is [" <<
00830                     difficulties.size() << "].\n";
00831                 return false;
00832             }
00833             else
00834             {
00835                 difficulty = jump_to_campaign_.difficulty_ - 1;
00836             }
00837         }
00838 
00839         state_.classification().difficulty = difficulties[difficulty];
00840         cache_.clear_defines();
00841         cache_.add_define(difficulties[difficulty]);
00842     } else {
00843         //clear even when there is no difficulty
00844         cache_.clear_defines();
00845     }
00846 
00847     state_.classification().campaign_define = campaign["define"].str();
00848     state_.classification().campaign_xtra_defines = utils::split(campaign["extra_defines"]);
00849 
00850     return true;
00851 }
00852 
00853 std::string game_controller::jump_to_campaign_id() const
00854 {
00855     return jump_to_campaign_.campaign_id_;
00856 }
00857 
00858 bool game_controller::goto_campaign()
00859 {
00860     if(jump_to_campaign_.jump_){
00861         if(new_campaign()) {
00862             jump_to_campaign_.jump_ = false;
00863             launch_game(game_controller::RELOAD_DATA);
00864         }else{
00865             jump_to_campaign_.jump_ = false;
00866             return false;
00867         }
00868     }
00869     return true;
00870 }
00871 
00872 bool game_controller::goto_multiplayer()
00873 {
00874     if(jump_to_multiplayer_){
00875         jump_to_multiplayer_ = false;
00876         if(play_multiplayer()){
00877             ;
00878         }else{
00879             return false;
00880         }
00881     }
00882     return true;
00883 }
00884 
00885 bool game_controller::goto_editor()
00886 {
00887     if(jump_to_editor_){
00888         jump_to_editor_ = false;
00889         if (start_editor(normalize_path(game::load_game_exception::game)) ==
00890             editor::EXIT_QUIT_TO_DESKTOP)
00891         {
00892             return false;
00893         }
00894         clear_loaded_game();
00895     }
00896     return true;
00897 }
00898 
00899 void game_controller::reload_changed_game_config()
00900 {
00901     // rebuild addon version info cache
00902     refresh_addon_version_info_cache();
00903 
00904     //force a reload of configuration information
00905     cache_.recheck_filetree_checksum();
00906     old_defines_map_.clear();
00907     clear_binary_paths_cache();
00908     init_config(true);
00909 }
00910 
00911 void game_controller::start_wesnothd()
00912 {
00913     const std::string wesnothd_program =
00914         preferences::get_mp_server_program_name().empty() ?
00915         get_program_invocation("wesnothd") : preferences::get_mp_server_program_name();
00916 
00917     std::string config = get_user_config_dir() + "/lan_server.cfg";
00918     if (!file_exists(config)) {
00919         // copy file if it isn't created yet
00920         write_file(config, read_file(get_wml_location("lan_server.cfg")));
00921     }
00922 
00923 #ifndef _WIN32
00924     std::string command = "\"" + wesnothd_program +"\" -c \"" + config + "\" -d -t 2 -T 5";
00925 #else
00926     // start wesnoth as background job
00927     std::string command = "cmd /C start \"wesnoth server\" /B \"" + wesnothd_program + "\" -c \"" + config + "\" -t 2 -T 5";
00928 #endif
00929     LOG_GENERAL << "Starting wesnothd: "<< command << "\n";
00930     if (std::system(command.c_str()) == 0) {
00931         // Give server a moment to start up
00932         SDL_Delay(50);
00933         return;
00934     }
00935     preferences::set_mp_server_program_name("");
00936 
00937     // Couldn't start server so throw error
00938     WRN_GENERAL << "Failed to run server start script\n";
00939     throw game::mp_server_error("Starting MP server failed!");
00940 }
00941 
00942 bool game_controller::play_multiplayer()
00943 {
00944     int res;
00945 
00946     state_ = game_state();
00947     state_.classification().campaign_type = "multiplayer";
00948     state_.classification().campaign_define = "MULTIPLAYER";
00949 
00950     //Print Gui only if the user hasn't specified any server
00951     if( multiplayer_server_.empty() ){
00952 
00953         int start_server;
00954         do {
00955             start_server = 0;
00956 
00957             gui2::tmp_method_selection dlg;
00958 
00959             dlg.show(disp().video());
00960 
00961             if(dlg.get_retval() == gui2::twindow::OK) {
00962                 res = dlg.get_choice();
00963             } else {
00964                 return false;
00965 
00966             }
00967 
00968             if (res == 2 && preferences::mp_server_warning_disabled() < 2) {
00969                 start_server = !gui2::tmp_host_game_prompt::execute(disp().video());
00970             }
00971         } while (start_server);
00972         if (res < 0) {
00973             return false;
00974         }
00975 
00976     }else{
00977         res = 4;
00978     }
00979 
00980     try {
00981         if (res == 2)
00982         {
00983             try {
00984                 start_wesnothd();
00985             } catch(game::mp_server_error&)
00986             {
00987                 std::string path = preferences::show_wesnothd_server_search(disp());
00988 
00989                 if (!path.empty())
00990                 {
00991                     preferences::set_mp_server_program_name(path);
00992                     start_wesnothd();
00993                 }
00994                 else
00995                 {
00996                     return false;
00997                 }
00998             }
00999 
01000 
01001         }
01002 
01003         /* do */ {
01004             cache_.clear_defines();
01005             game_config::scoped_preproc_define multiplayer(state_.classification().campaign_define);
01006             load_game_cfg();
01007             events::discard(INPUT_MASK); // prevent the "keylogger" effect
01008             cursor::set(cursor::NORMAL);
01009             // update binary paths
01010             paths_manager_.set_paths(game_config());
01011             clear_binary_paths_cache();
01012         }
01013 
01014         if(res == 3) {
01015             std::vector<std::string> chat;
01016             config game_data;
01017 
01018             const mp::controller cntr = mp::CNTR_LOCAL;
01019 
01020             mp::start_local_game(disp(), game_config(), cntr);
01021 
01022         } else if((res >= 0 && res <= 2) || res == 4) {
01023             std::string host;
01024             if(res == 0) {
01025                 host = preferences::server_list().front().address;
01026             }else if(res == 2) {
01027                 host = "localhost";
01028             }else if(res == 4){
01029                 host = multiplayer_server_;
01030                 multiplayer_server_ = "";
01031             }
01032             mp::start_client(disp(), game_config(), host);
01033         }
01034 
01035     } catch(game::mp_server_error& e) {
01036         gui2::show_error_message(disp().video(), _("Error while starting server: ") + e.message);
01037     } catch(game::load_game_failed& e) {
01038         gui2::show_error_message(disp().video(), _("The game could not be loaded: ") + e.message);
01039     } catch(game::game_error& e) {
01040         gui2::show_error_message(disp().video(), _("Error while playing the game: ") + e.message);
01041     } catch(network::error& e) {
01042         if(e.message != "") {
01043             ERR_NET << "caught network::error: " << e.message << "\n";
01044             gui2::show_transient_message(disp().video()
01045                     , ""
01046                     , gettext(e.message.c_str()));
01047         } else {
01048             ERR_NET << "caught network::error\n";
01049         }
01050     } catch(config::error& e) {
01051         if(e.message != "") {
01052             ERR_CONFIG << "caught config::error: " << e.message << "\n";
01053             gui2::show_transient_message(disp().video(), "", e.message);
01054         } else {
01055             ERR_CONFIG << "caught config::error\n";
01056         }
01057     } catch(incorrect_map_format_error& e) {
01058         gui2::show_error_message(disp().video(), std::string(_("The game map could not be loaded: ")) + e.message);
01059     } catch (game::load_game_exception &) {
01060         //this will make it so next time through the title screen loop, this game is loaded
01061     } catch(twml_exception& e) {
01062         e.show(disp());
01063     }
01064 
01065     return false;
01066 }
01067 
01068 bool game_controller::change_language()
01069 {
01070     gui2::tlanguage_selection dlg;
01071     dlg.show(disp().video());
01072     if (dlg.get_retval() != gui2::twindow::OK) return false;
01073 
01074     if (!cmdline_opts_.nogui) {
01075         std::string wm_title_string = _("The Battle for Wesnoth");
01076         wm_title_string += " - " + game_config::revision;
01077         SDL_WM_SetCaption(wm_title_string.c_str(), NULL);
01078     }
01079 
01080     return true;
01081 }
01082 
01083 void game_controller::show_preferences()
01084 {
01085     const preferences::display_manager disp_manager(&disp());
01086     preferences::show_preferences_dialog(disp(),game_config());
01087 
01088     disp().redraw_everything();
01089 }
01090 
01091 void game_controller::set_unit_data()
01092 {
01093     loadscreen::start_stage("load unit types");
01094     if (config &units = game_config_.child("units")) {
01095         unit_types.set_config(units);
01096     }
01097 }
01098 
01099 void game_controller::load_game_cfg(const bool force)
01100 {
01101     // make sure that 'debug mode' symbol is set if command line parameter is selected
01102     // also if we're in multiplayer and actual debug mode is disabled
01103     if (game_config::debug || game_config::mp_debug) {
01104         cache_.add_define("DEBUG_MODE");
01105     }
01106 
01107     if (!game_config_.empty() && !force
01108             && old_defines_map_ == cache_.get_preproc_map())
01109         return; // game_config already holds requested config in memory
01110     old_defines_map_ = cache_.get_preproc_map();
01111     loadscreen::global_loadscreen_manager loadscreen_manager(disp().video());
01112     cursor::setter cur(cursor::WAIT);
01113     // The loadscreen will erase the titlescreen
01114     // NOTE: even without loadscreen, needed after MP lobby
01115     try {
01116         /**
01117          * Read all game configs
01118          * First we should load data/
01119          * Then handle terrains so that they are last loaded from data/
01120          * 2nd everything in userdata
01121          **/
01122         loadscreen::start_stage("verify cache");
01123         data_tree_checksum();
01124         loadscreen::start_stage("create cache");
01125 
01126         // start transaction so macros are shared
01127         game_config::config_cache_transaction main_transaction;
01128 
01129         cache_.get_config(game_config::path +"/data", game_config_);
01130 
01131         main_transaction.lock();
01132 
01133         /* Put the gfx rules aside so that we can prepend the add-on
01134            rules to them. */
01135         config core_terrain_rules;
01136         core_terrain_rules.splice_children(game_config_, "terrain_graphics");
01137 
01138         // load usermade add-ons
01139         const std::string user_campaign_dir = get_addon_campaigns_dir();
01140         std::vector< std::string > error_addons;
01141         // Scan addon directories
01142         std::vector<std::string> user_dirs;
01143         // Scan for standalone files
01144         std::vector<std::string> user_files;
01145 
01146         // The addons that we'll actually load
01147         std::vector<std::string> addons_to_load;
01148 
01149         get_files_in_dir(user_campaign_dir,&user_files,&user_dirs,ENTIRE_FILE_PATH);
01150         std::string user_error_log;
01151 
01152         // Append the $user_campaign_dir/*.cfg files to addons_to_load.
01153         for(std::vector<std::string>::const_iterator uc = user_files.begin(); uc != user_files.end(); ++uc) {
01154             const std::string file = *uc;
01155             int size_minus_extension = file.size() - 4;
01156             if(file.substr(size_minus_extension, file.size()) == ".cfg") {
01157                 // Allowing it if the dir doesn't exist, for the single-file add-on.
01158                 // Turn this into an error later, possibly in 1.11.0
01159                 if(file_exists(file.substr(0, size_minus_extension)))
01160                     lg::wml_error << '\'' << file << "' is deprecated, use '" << file.substr(0, size_minus_extension) << "/_main.cfg' instead.\n";
01161                 addons_to_load.push_back(file);
01162             }
01163         }
01164 
01165         // Append the $user_campaign_dir/*/_main.cfg files to addons_to_load.
01166         for(std::vector<std::string>::const_iterator uc = user_dirs.begin(); uc != user_dirs.end(); ++uc){
01167             const std::string main_cfg = *uc + "/_main.cfg";
01168             if (file_exists(main_cfg))
01169                 addons_to_load.push_back(main_cfg);
01170         }
01171 
01172         // Load the addons
01173         for(std::vector<std::string>::const_iterator uc = addons_to_load.begin(); uc != addons_to_load.end(); ++uc) {
01174             const std::string toplevel = *uc;
01175             try {
01176                 config umc_cfg;
01177                 cache_.get_config(toplevel, umc_cfg);
01178 
01179                 game_config_.append(umc_cfg);
01180             } catch(config::error& err) {
01181                 ERR_CONFIG << "error reading usermade add-on '" << *uc << "'\n";
01182                 error_addons.push_back(*uc);
01183                 user_error_log += err.message + "\n";
01184             } catch(preproc_config::error& err) {
01185                 ERR_CONFIG << "error reading usermade add-on '" << *uc << "'\n";
01186                 error_addons.push_back(*uc);
01187                 user_error_log += err.message + "\n";
01188             } catch(io_exception&) {
01189                 ERR_CONFIG << "error reading usermade add-on '" << *uc << "'\n";
01190                 error_addons.push_back(*uc);
01191             }
01192             if(error_addons.empty() == false) {
01193                 std::stringstream msg;
01194                 msg << _n("The following add-on had errors and could not be loaded:",
01195                         "The following add-ons had errors and could not be loaded:",
01196                         error_addons.size());
01197                 for(std::vector<std::string>::const_iterator i = error_addons.begin(); i != error_addons.end(); ++i) {
01198                     msg << "\n" << *i;
01199                 }
01200 
01201                 msg << '\n' << _("ERROR DETAILS:") << '\n' << user_error_log;
01202 
01203                 gui2::show_error_message(disp().video(),msg.str());
01204             }
01205         }
01206 
01207         // Extract the Lua scripts at toplevel.
01208         extract_preload_scripts(game_config_);
01209         game_config_.clear_children("lua");
01210 
01211         config colorsys_info;
01212         colorsys_info.splice_children(game_config_, "color_range");
01213         colorsys_info.splice_children(game_config_, "color_palette");
01214 
01215         game_config_.merge_children("units");
01216         game_config_.splice_children(core_terrain_rules, "terrain_graphics");
01217 
01218         config& hashes = game_config_.add_child("multiplayer_hashes");
01219         foreach (const config &ch, game_config_.child_range("multiplayer")) {
01220             hashes[ch["id"]] = ch.hash();
01221         }
01222 
01223         game_config::add_color_info(colorsys_info);
01224 
01225         set_unit_data();
01226 
01227         terrain_builder::set_terrain_rules_cfg(game_config());
01228 
01229 		::init_strings(game_config());
01230 
01231         theme::set_known_themes(&game_config());
01232 
01233     } catch(game::error& e) {
01234         ERR_CONFIG << "Error loading game configuration files\n";
01235         gui2::show_error_message(disp().video(), _("Error loading game configuration files: '") +
01236             e.message + _("' (The game will now exit)"));
01237         throw;
01238     }
01239 }
01240 
01241 void game_controller::launch_game(RELOAD_GAME_DATA reload)
01242 {
01243     loadscreen::global_loadscreen_manager loadscreen_manager(disp().video());
01244     loadscreen::start_stage("load data");
01245     if(reload == RELOAD_DATA) {
01246         game_config::scoped_preproc_define campaign_define(state_.classification().campaign_define, state_.classification().campaign_define.empty() == false);
01247 
01248         typedef boost::shared_ptr<game_config::scoped_preproc_define> define_ptr;
01249         std::deque<define_ptr> extra_defines;
01250         for(std::vector<std::string>::const_iterator i = state_.classification().campaign_xtra_defines.begin(); i != state_.classification().campaign_xtra_defines.end(); ++i) {
01251             define_ptr newdefine(new game_config::scoped_preproc_define(*i));
01252             extra_defines.push_back(newdefine);
01253         }
01254         try {
01255             load_game_cfg();
01256         } catch(config::error&) {
01257             cache_.clear_defines();
01258             load_game_cfg();
01259             return;
01260         }
01261     }
01262 
01263     const binary_paths_manager bin_paths_manager(game_config());
01264 
01265     try {
01266         const LEVEL_RESULT result = play_game(disp(),state_,game_config());
01267         // don't show The End for multiplayer scenario
01268         // change this if MP campaigns are implemented
01269         if(result == VICTORY && (state_.classification().campaign_type.empty() || state_.classification().campaign_type != "multiplayer")) {
01270             preferences::add_completed_campaign(state_.classification().campaign);
01271             the_end(disp(), state_.classification().end_text, state_.classification().end_text_duration);
01272             if(state_.classification().end_credits) {
01273                 about::show_about(disp(),state_.classification().campaign);
01274             }
01275         }
01276 
01277         clear_loaded_game();
01278     } catch (game::load_game_exception &) {
01279         //this will make it so next time through the title screen loop, this game is loaded
01280     } catch(twml_exception& e) {
01281         e.show(disp());
01282     }
01283 }
01284 
01285 void game_controller::play_replay()
01286 {
01287     const binary_paths_manager bin_paths_manager(game_config());
01288 
01289     try {
01290 		::play_replay(disp(),state_,game_config(),video_);
01291 
01292         clear_loaded_game();
01293     } catch (game::load_game_exception &) {
01294         //this will make it so next time through the title screen loop, this game is loaded
01295     } catch(twml_exception& e) {
01296         e.show(disp());
01297     }
01298 }
01299 
01300 editor::EXIT_STATUS game_controller::start_editor(const std::string& filename)
01301 {
01302     while(true){
01303         cache_.clear_defines();
01304         cache_.add_define("EDITOR");
01305         load_game_cfg();
01306         const binary_paths_manager bin_paths_manager(game_config());
01307 		::init_textdomains(game_config());
01308 
01309         editor::EXIT_STATUS res = editor::start(game_config(), video_, filename);
01310 
01311         if(res != editor::EXIT_RELOAD_DATA)
01312             return res;
01313 
01314         reload_changed_game_config();
01315         image::flush_cache();
01316     }
01317     return editor::EXIT_ERROR; // not supposed to happen
01318 }
01319 
01320 game_controller::~game_controller()
01321 {
01322     delete gui::empty_menu;
01323     sound::close_sound();
01324 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:02:52 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs