multiplayer_create.cpp

Go to the documentation of this file.
00001 /* $Id: multiplayer_create.cpp 54070 2012-05-02 13:37:50Z j_daniel $ */
00002 /*
00003    Copyright (C) 2007 - 2012
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 /**
00017  * @file
00018  * Create a multiplayer-game: select map, players, options etc.
00019  */
00020 
00021 #include "global.hpp"
00022 
00023 #include "foreach.hpp"
00024 #include "gettext.hpp"
00025 #include "game_display.hpp"
00026 #include "game_preferences.hpp"
00027 #include "construct_dialog.hpp"
00028 #include "settings.hpp"
00029 #include "map.hpp"
00030 #include "map_exception.hpp"
00031 #include "map_create.hpp"
00032 #include "gui/dialogs/message.hpp"
00033 #include "gui/dialogs/mp_create_game_set_password.hpp"
00034 #include "gui/dialogs/transient_message.hpp"
00035 #include "minimap.hpp"
00036 #include "multiplayer_create.hpp"
00037 #include "filesystem.hpp"
00038 #include "log.hpp"
00039 #include "wml_exception.hpp"
00040 #include "wml_separators.hpp"
00041 #include "formula_string_utils.hpp"
00042 
00043 static lg::log_domain log_config("config");
00044 #define ERR_CF LOG_STREAM(err, log_config)
00045 
00046 static lg::log_domain log_mp_create("mp/create");
00047 #define DBG_MP LOG_STREAM(debug, log_mp_create)
00048 
00049 namespace {
00050 const SDL_Rect null_rect = {0, 0, 0, 0};
00051 }
00052 
00053 namespace mp {
00054 
00055 create::create(game_display& disp, const config &cfg, chat& c, config& gamelist, bool local_players_only) :
00056     ui(disp, _("Create Game"), cfg, c, gamelist),
00057 
00058     local_players_only_(local_players_only),
00059     tooltip_manager_(disp.video()),
00060     map_selection_(-1),
00061     mp_countdown_init_time_(270),
00062     mp_countdown_reservoir_time_(330),
00063     user_maps_(),
00064     map_options_(),
00065     map_index_(),
00066 
00067     maps_menu_(disp.video(), std::vector<std::string>()),
00068     turns_slider_(disp.video()),
00069     turns_label_(disp.video(), "", font::SIZE_SMALL, font::LOBBY_COLOR),
00070     countdown_game_(disp.video(), _("Time limit"), gui::button::TYPE_CHECK),
00071     countdown_init_time_slider_(disp.video()),
00072     countdown_init_time_label_(disp.video(), "", font::SIZE_SMALL, font::LOBBY_COLOR),
00073     countdown_reservoir_time_slider_(disp.video()),
00074     countdown_reservoir_time_label_(disp.video(), "", font::SIZE_SMALL, font::LOBBY_COLOR),
00075     countdown_turn_bonus_label_(disp.video(), "", font::SIZE_SMALL, font::LOBBY_COLOR),
00076     countdown_turn_bonus_slider_(disp.video()),
00077     countdown_action_bonus_label_(disp.video(), "", font::SIZE_SMALL, font::LOBBY_COLOR),
00078     countdown_action_bonus_slider_(disp.video()),
00079     village_gold_slider_(disp.video()),
00080     village_gold_label_(disp.video(), "", font::SIZE_SMALL, font::LOBBY_COLOR),
00081     village_support_slider_(disp.video()),
00082     village_support_label_(disp.video(), "", font::SIZE_SMALL, font::LOBBY_COLOR),
00083     xp_modifier_slider_(disp.video()),
00084     xp_modifier_label_(disp.video(), "", font::SIZE_SMALL, font::LOBBY_COLOR),
00085     name_entry_label_(disp.video(), _("Name of game:"), font::SIZE_PLUS, font::LOBBY_COLOR),
00086     num_players_label_(disp.video(), "", font::SIZE_SMALL, font::LOBBY_COLOR),
00087     map_size_label_(disp.video(), "", font::SIZE_SMALL, font::LOBBY_COLOR),
00088     era_label_(disp.video(), _("Era:"), font::SIZE_SMALL, font::LOBBY_COLOR),
00089     map_label_(disp.video(), _("Map to play:"), font::SIZE_SMALL, font::LOBBY_COLOR),
00090     use_map_settings_(disp.video(), _("Use map settings"), gui::button::TYPE_CHECK),
00091     random_start_time_(disp.video(), _("Random start time"), gui::button::TYPE_CHECK),
00092     fog_game_(disp.video(), _("Fog of war"), gui::button::TYPE_CHECK),
00093     shroud_game_(disp.video(), _("Shroud"), gui::button::TYPE_CHECK),
00094     observers_game_(disp.video(), _("Observers"), gui::button::TYPE_CHECK),
00095     shuffle_sides_(disp.video(), _("Shuffle sides"), gui::button::TYPE_CHECK),
00096     cancel_game_(disp.video(), _("Cancel")),
00097     launch_game_(disp.video(), _("OK")),
00098     regenerate_map_(disp.video(), _("Regenerate")),
00099     generator_settings_(disp.video(), _("Settings...")),
00100     password_button_(disp.video(), _("Set Password...")),
00101     era_combo_(disp, std::vector<std::string>()),
00102     vision_combo_(disp, std::vector<std::string>()),
00103     name_entry_(disp.video(), 32),
00104     minimap_restorer_(NULL),
00105     minimap_rect_(null_rect),
00106     generator_(NULL),
00107     num_turns_(0),
00108     parameters_()
00109 {
00110     // Build the list of scenarios to play
00111 
00112     DBG_MP << "constructing multiplayer create dialog" << std::endl;
00113 
00114     // Add the 'load game' option
00115     std::string markup_txt = "`~";
00116     std::string help_sep = " ";
00117     help_sep[0] = HELP_STRING_SEPARATOR;
00118     std::string menu_help_str = help_sep + _("Load Game");
00119     map_options_.push_back(markup_txt + _("Load Game...") + menu_help_str);
00120 
00121     // User maps
00122     get_files_in_dir(get_user_data_dir() + "/editor/maps",&user_maps_,NULL,FILE_NAME_ONLY);
00123 
00124     size_t i = 0;
00125     for(i = 0; i < user_maps_.size(); i++)
00126     {
00127         menu_help_str = help_sep + user_maps_[i];
00128         map_options_.push_back(user_maps_[i] + menu_help_str);
00129     }
00130 
00131     // Standard maps
00132     i = 0;
00133     foreach (const config &j, cfg.child_range("multiplayer"))
00134     {
00135         if (j["allow_new_game"].to_bool(true))
00136         {
00137             std::string name = j["name"];
00138             menu_help_str = help_sep + name;
00139             map_options_.push_back(name + menu_help_str);
00140             map_index_.push_back(i);
00141         }
00142         ++i;
00143     }
00144 
00145     // Create the scenarios menu
00146     maps_menu_.set_items(map_options_);
00147     if (size_t(preferences::map()) < map_options_.size())
00148         maps_menu_.move_selection(preferences::map());
00149     maps_menu_.set_numeric_keypress_selection(false);
00150 
00151     turns_slider_.set_min(settings::turns_min);
00152     turns_slider_.set_max(settings::turns_max);
00153     turns_slider_.set_increment(settings::turns_step);
00154     turns_slider_.set_value(preferences::turns());
00155     turns_slider_.set_help_string(_("The maximum number of turns the game can last"));
00156 
00157     countdown_game_.set_check(preferences::countdown());
00158     countdown_game_.set_help_string(_("Enables user time limit"));
00159 
00160     countdown_init_time_slider_.set_min(30);
00161     countdown_init_time_slider_.set_max(1500);
00162     countdown_init_time_slider_.set_increment(30);
00163     countdown_init_time_slider_.set_value(preferences::countdown_init_time());
00164     countdown_init_time_slider_.set_help_string(_("Longest time allowed for first turn (seconds)"));
00165 
00166     countdown_reservoir_time_slider_.set_min(30);
00167     countdown_reservoir_time_slider_.set_max(1500);
00168     countdown_reservoir_time_slider_.set_increment(30);
00169     countdown_reservoir_time_slider_.set_value(preferences::countdown_reservoir_time());
00170     countdown_reservoir_time_slider_.set_help_string(_("Longest time possible for any turn (seconds)"));
00171 
00172     countdown_turn_bonus_slider_.set_min(10);
00173     countdown_turn_bonus_slider_.set_max(300);
00174     countdown_turn_bonus_slider_.set_increment(5);
00175     countdown_turn_bonus_slider_.set_value(preferences::countdown_turn_bonus());
00176     countdown_turn_bonus_slider_.set_help_string(_("Time for general tasks each turn (seconds)"));
00177 
00178     countdown_action_bonus_slider_.set_min(0);
00179     countdown_action_bonus_slider_.set_max(30);
00180     countdown_action_bonus_slider_.set_increment(1);
00181     countdown_action_bonus_slider_.set_value(preferences::countdown_action_bonus());
00182     countdown_action_bonus_slider_.set_help_string(_("Time for each attack, recruit, and capture"));
00183 
00184     village_gold_slider_.set_min(1);
00185     village_gold_slider_.set_max(5);
00186     village_gold_slider_.set_value(preferences::village_gold());
00187     village_gold_slider_.set_help_string(_("The amount of income each village yields per turn"));
00188 
00189     village_support_slider_.set_min(0);
00190     village_support_slider_.set_max(4);
00191     village_support_slider_.set_value(preferences::village_support());
00192     village_support_slider_.set_help_string(_("The number of unit levels each village can support"));
00193 
00194     xp_modifier_slider_.set_min(30);
00195     xp_modifier_slider_.set_max(200);
00196     xp_modifier_slider_.set_value(preferences::xp_modifier());
00197     xp_modifier_slider_.set_increment(10);
00198     xp_modifier_slider_.set_help_string(_("The amount of experience a unit needs to advance"));
00199 
00200     use_map_settings_.set_check(preferences::use_map_settings());
00201     use_map_settings_.set_help_string(_("Use scenario specific settings"));
00202 
00203     random_start_time_.set_check(preferences::random_start_time());
00204     random_start_time_.set_help_string(_("Randomize time of day in begin"));
00205 
00206     fog_game_.set_check(preferences::fog());
00207     fog_game_.set_help_string(_("Enemy units cannot be seen unless they are in range of your units"));
00208 
00209     shroud_game_.set_check(preferences::shroud());
00210     shroud_game_.set_help_string(_("The map is unknown until your units explore it"));
00211 
00212     observers_game_.set_check(preferences::allow_observers());
00213     observers_game_.set_help_string(_("Allow users who are not playing to watch the game"));
00214 
00215     shuffle_sides_.set_check(preferences::shuffle_sides());
00216     shuffle_sides_.set_help_string(_("Assign sides to players at random"));
00217 
00218     // The possible vision settings
00219     std::vector<std::string> vision_types;
00220     vision_types.push_back(_("Share View"));
00221     vision_types.push_back(_("Share Maps"));
00222     vision_types.push_back(_("Share None"));
00223     vision_combo_.set_items(vision_types);
00224     vision_combo_.set_selected(0);
00225 
00226     // The possible eras to play
00227     std::vector<std::string> eras;
00228     foreach (const config &er, cfg.child_range("era")) {
00229         eras.push_back(er["name"]);
00230     }
00231     if(eras.empty()) {
00232         gui2::show_transient_message(disp.video(), "", _("No eras found."));
00233         throw config::error(_("No eras found"));
00234     }
00235     era_combo_.set_items(eras);
00236 
00237     if (size_t(preferences::era()) < eras.size()) {
00238         era_combo_.set_selected(preferences::era());
00239     } else {
00240         era_combo_.set_selected(0);
00241     }
00242 
00243 
00244     utils::string_map i18n_symbols;
00245     i18n_symbols["login"] = preferences::login();
00246     name_entry_.set_text(vgettext("$login|’s game", i18n_symbols));
00247 
00248     gamelist_updated();
00249 }
00250 
00251 create::~create()
00252 {
00253     // Only save the settings if the dialog was 'accepted'
00254     if(get_result() != CREATE) {
00255         DBG_MP << "destructing multiplayer create dialog - aborted game creation" << std::endl;
00256         return;
00257     }
00258     DBG_MP << "destructing multiplayer create dialog - a game will be created" << std::endl;
00259 
00260     // Retrieve values
00261     get_parameters();
00262 
00263     // Save values for next game
00264     DBG_MP << "storing parameter values in preferences" << std::endl;
00265     preferences::set_allow_observers(parameters_.allow_observers);
00266     preferences::set_shuffle_sides(parameters_.shuffle_sides);
00267     preferences::set_use_map_settings(parameters_.use_map_settings);
00268     preferences::set_countdown(parameters_.mp_countdown);
00269     preferences::set_countdown_init_time(parameters_.mp_countdown_init_time);
00270     preferences::set_countdown_turn_bonus(parameters_.mp_countdown_turn_bonus);
00271     preferences::set_countdown_reservoir_time(parameters_.mp_countdown_reservoir_time);
00272     preferences::set_countdown_action_bonus(parameters_.mp_countdown_action_bonus);
00273     preferences::set_era(era_combo_.selected()); /** @todo FIXME: may be broken if new eras are added. */
00274     preferences::set_map(map_selection_);
00275 
00276     // When using map settings, the following variables are determined by the map,
00277     // so don't store them as the new preferences.
00278     if(!parameters_.use_map_settings) {
00279         preferences::set_fog(parameters_.fog_game);
00280         preferences::set_shroud(parameters_.shroud_game);
00281         preferences::set_turns(num_turns_);
00282         preferences::set_random_start_time(parameters_.random_start_time);
00283         preferences::set_village_gold(parameters_.village_gold);
00284         preferences::set_village_support(parameters_.village_support);
00285         preferences::set_xp_modifier(parameters_.xp_modifier);
00286     }
00287 }
00288 
00289 mp_game_settings& create::get_parameters()
00290 {
00291     DBG_MP << "getting parameter values from widgets" << std::endl;
00292     num_turns_ = turns_slider_.value() < turns_slider_.max_value() ?
00293         turns_slider_.value() : -1;
00294 
00295     const int mp_countdown_turn_bonus_val = countdown_turn_bonus_slider_.value() <= countdown_turn_bonus_slider_.max_value() ?
00296         countdown_turn_bonus_slider_.value() : -1;
00297     const int mp_countdown_action_bonus_val = countdown_action_bonus_slider_.value() <= countdown_action_bonus_slider_.max_value() ?
00298         countdown_action_bonus_slider_.value() : -1;
00299     const int mp_countdown_reservoir_time_val = countdown_reservoir_time_slider_.value() <= countdown_reservoir_time_slider_.max_value() ?
00300         countdown_reservoir_time_slider_.value() : -1;
00301     int mp_countdown_init_time_val = countdown_init_time_slider_.value() <= countdown_init_time_slider_.max_value() ?
00302         countdown_init_time_slider_.value() : -1;
00303     if(mp_countdown_reservoir_time_val > 0 && mp_countdown_init_time_val > mp_countdown_reservoir_time_val)
00304         mp_countdown_init_time_val = mp_countdown_reservoir_time_val;
00305 
00306     // Updates the values in the "parameters_" member to match
00307     // the values selected by the user with the widgets:
00308     parameters_.name = name_entry_.text();
00309 
00310     config::const_child_itors era_list = game_config().child_range("era");
00311     for (int num = era_combo_.selected(); num > 0; --num) {
00312         if (era_list.first == era_list.second) {
00313             throw config::error(_("Invalid era selected"));
00314         }
00315         ++era_list.first;
00316     }
00317 
00318     parameters_.mp_era = (*era_list.first)["id"].str();
00319     // CHECK
00320     parameters_.mp_countdown_init_time = mp_countdown_init_time_val;
00321     parameters_.mp_countdown_turn_bonus = mp_countdown_turn_bonus_val;
00322     parameters_.mp_countdown_reservoir_time = mp_countdown_reservoir_time_val;
00323     parameters_.mp_countdown_action_bonus = mp_countdown_action_bonus_val;
00324     parameters_.mp_countdown = countdown_game_.checked();
00325     parameters_.village_gold = village_gold_slider_.value();
00326     parameters_.village_support = village_support_slider_.value();
00327     parameters_.xp_modifier = xp_modifier_slider_.value();
00328     parameters_.use_map_settings = use_map_settings_.checked();
00329     parameters_.random_start_time = random_start_time_.checked();
00330     parameters_.fog_game = fog_game_.checked();
00331     parameters_.shroud_game = shroud_game_.checked();
00332     parameters_.allow_observers = observers_game_.checked();
00333     parameters_.shuffle_sides = shuffle_sides_.checked();
00334     parameters_.share_view = vision_combo_.selected() == 0;
00335     parameters_.share_maps = vision_combo_.selected() == 1;
00336 
00337     return parameters_;
00338 }
00339 
00340 void create::process_event()
00341 {
00342     int mousex, mousey;
00343     SDL_GetMouseState(&mousex,&mousey);
00344     tooltips::process(mousex, mousey);
00345 
00346     if(cancel_game_.pressed()) {
00347         set_result(QUIT);
00348         return;
00349     }
00350 
00351     if(launch_game_.pressed() || maps_menu_.double_clicked()) {
00352         // check if the map is valid
00353         const std::string& map_data = parameters_.scenario_data["map_data"];
00354         util::unique_ptr<gamemap> map;
00355         try {
00356             map.reset(new gamemap(game_config(), map_data));
00357         } catch(incorrect_map_format_error&) {
00358         } catch(twml_exception&) {}
00359 
00360         if (map.get() == NULL) {
00361             gui2::show_transient_message(disp_.video(), "", _("The map is invalid."));
00362         } else if (name_entry_.text() == "") {
00363             gui2::show_transient_message(disp_.video(), "", _("You must enter a name."));
00364         } else {
00365             set_result(CREATE);
00366             return;
00367         }
00368     }
00369 
00370     if(password_button_.pressed()) {
00371         gui2::tmp_create_game_set_password::execute(
00372                   parameters_.password
00373                 , disp_.video());
00374 
00375     }
00376 
00377     // Turns per game
00378     const int cur_turns = turns_slider_.value();
00379 
00380     std::stringstream buf;
00381     if(cur_turns < 100) {
00382         buf << _("Turns: ") << cur_turns;
00383     } else {
00384         buf << _("Unlimited turns");
00385     }
00386     turns_label_.set_text(buf.str());
00387 
00388     countdown_init_time_label_.enable(countdown_game_.checked());
00389     countdown_init_time_slider_.enable(countdown_game_.checked());
00390     countdown_turn_bonus_label_.enable(countdown_game_.checked());
00391     countdown_turn_bonus_slider_.enable(countdown_game_.checked());
00392 
00393     countdown_reservoir_time_label_.enable(countdown_game_.checked());
00394     countdown_reservoir_time_slider_.enable(countdown_game_.checked());
00395     countdown_action_bonus_label_.enable(countdown_game_.checked());
00396     countdown_action_bonus_slider_.enable(countdown_game_.checked());
00397 
00398     if(mp_countdown_init_time_ != countdown_init_time_slider_.value()
00399         && countdown_init_time_slider_.value() > countdown_reservoir_time_slider_.value())
00400     {
00401         countdown_reservoir_time_slider_.set_value(countdown_init_time_slider_.value());
00402     }
00403     if(mp_countdown_reservoir_time_ != countdown_reservoir_time_slider_.value()
00404         && countdown_reservoir_time_slider_.value() < countdown_init_time_slider_.value())
00405     {
00406         countdown_init_time_slider_.set_value(countdown_reservoir_time_slider_.value());
00407     }
00408     mp_countdown_init_time_ = countdown_init_time_slider_.value();
00409     mp_countdown_reservoir_time_ = countdown_reservoir_time_slider_.value();
00410 
00411     buf.str("");
00412     buf <<  _("Init. limit: ") << mp_countdown_init_time_; // << _(" sec.");
00413     countdown_init_time_label_.set_text(buf.str());
00414 
00415     const int mp_countdown_turn_bonus_val = countdown_turn_bonus_slider_.value();
00416     buf.str("");
00417     buf <<  _("Turn bonus: ") << mp_countdown_turn_bonus_val; // << _(" sec.");
00418     countdown_turn_bonus_label_.set_text(buf.str());
00419 
00420     buf.str("");
00421     buf <<  _("Reservoir: ") << mp_countdown_reservoir_time_; // << _(" sec.");
00422     countdown_reservoir_time_label_.set_text(buf.str());
00423 
00424     const int mp_countdown_action_bonus_val = countdown_action_bonus_slider_.value();
00425     buf.str("");
00426     buf <<  _("Action bonus: ") << mp_countdown_action_bonus_val; // << _(" sec.");
00427     countdown_action_bonus_label_.set_text(buf.str());
00428 
00429 
00430     // Villages can produce between 1 and 5 gold a turn
00431     const int village_gold = village_gold_slider_.value();
00432     buf.str("");
00433     buf << _("Village gold: ") << village_gold;
00434     village_gold_label_.set_text(buf.str());
00435 
00436     // Unit levels supported per village
00437     const int village_support = village_support_slider_.value();
00438     buf.str("");
00439     buf << _("Village Support: ") << village_support;
00440     village_support_label_.set_text(buf.str());
00441 
00442     // Experience modifier
00443     const int xpmod = xp_modifier_slider_.value();
00444     buf.str("");
00445     buf << _("Experience modifier: ") << xpmod << "%";
00446 
00447     xp_modifier_label_.set_text(buf.str());
00448 
00449     bool map_changed = map_selection_ != maps_menu_.selection();
00450     map_selection_ = maps_menu_.selection();
00451 
00452     if(map_changed) {
00453         generator_.assign(NULL);
00454 
00455         tooltips::clear_tooltips(minimap_rect_);
00456 
00457         const size_t select = size_t(maps_menu_.selection());
00458 
00459         if(select > 0 && select <= user_maps_.size()) {
00460             parameters_.saved_game = false;
00461             if (const config &generic_multiplayer = game_config().child("generic_multiplayer")) {
00462                 parameters_.scenario_data = generic_multiplayer;
00463                 parameters_.scenario_data["map_data"] = read_map(user_maps_[select-1]);
00464             }
00465 
00466         } else if(select > user_maps_.size() && select <= maps_menu_.number_of_items()-1) {
00467             parameters_.saved_game = false;
00468             size_t index = select - user_maps_.size() - 1;
00469             assert(index < map_index_.size());
00470             index = map_index_[index];
00471 
00472             config::const_child_itors levels = game_config().child_range("multiplayer");
00473             for (; index > 0; --index) {
00474                 if (levels.first == levels.second) break;
00475                 ++levels.first;
00476             }
00477 
00478             if (levels.first != levels.second)
00479             {
00480                 const config &level = *levels.first;
00481                 parameters_.scenario_data = level;
00482                 std::string map_data = level["map_data"];
00483 
00484                 if (map_data.empty() && !level["map"].empty()) {
00485                     map_data = read_map(level["map"]);
00486                 }
00487 
00488                 // If the map should be randomly generated.
00489                 if (!level["map_generation"].empty()) {
00490                     generator_.assign(create_map_generator(level["map_generation"], level.child("generator")));
00491                 }
00492 
00493                 if (!level["description"].empty()) {
00494                     tooltips::add_tooltip(minimap_rect_, level["description"], "", false);
00495                 }
00496             }
00497         } else {
00498             parameters_.scenario_data.clear();
00499             parameters_.saved_game = true;
00500 
00501             if (minimap_restorer_ != NULL)
00502                 minimap_restorer_->restore();
00503         }
00504     }
00505 
00506     if(generator_ != NULL && generator_->allow_user_config() && generator_settings_.pressed()) {
00507         generator_->user_config(disp_);
00508         map_changed = true;
00509     }
00510 
00511     if(generator_ != NULL && (map_changed || regenerate_map_.pressed())) {
00512         const cursor::setter cursor_setter(cursor::WAIT);
00513 
00514         // Generate the random map
00515         cursor::setter cur(cursor::WAIT);
00516         parameters_.scenario_data = generator_->create_scenario(std::vector<std::string>());
00517         map_changed = true;
00518 
00519         if (!parameters_.scenario_data["error_message"].empty())
00520             gui2::show_message(disp().video(), "map generation error", parameters_.scenario_data["error_message"]);
00521 
00522         // Set the scenario to have placing of sides
00523         // based on the terrain they prefer
00524         parameters_.scenario_data["modify_placing"] = "true";
00525     }
00526 
00527     if(map_changed) {
00528         generator_settings_.hide(generator_ == NULL);
00529         regenerate_map_.hide(generator_ == NULL);
00530 
00531         const std::string& map_data = parameters_.scenario_data["map_data"];
00532         parameters_.hash = parameters_.scenario_data.hash();
00533         util::unique_ptr<gamemap> map;
00534         try {
00535             map.reset(new gamemap(game_config(), map_data));
00536         } catch(incorrect_map_format_error& e) {
00537             ERR_CF << "map could not be loaded: " << e.message << "\n";
00538 
00539             tooltips::clear_tooltips(minimap_rect_);
00540             tooltips::add_tooltip(minimap_rect_,e.message);
00541         } catch(twml_exception& e) {
00542             ERR_CF <<  "map could not be loaded: " << e.dev_message << '\n';
00543         }
00544 
00545         launch_game_.enable(map.get() != NULL);
00546 
00547         // If there are less sides in the configuration than there are
00548         // starting positions, then generate the additional sides
00549         const int map_positions = map.get() != NULL ? map->num_valid_starting_positions() : 0;
00550 
00551         for (int pos = parameters_.scenario_data.child_count("side"); pos < map_positions; ++pos) {
00552             config& side = parameters_.scenario_data.add_child("side");
00553             side["side"] = pos + 1;
00554             side["team_name"] = pos + 1;
00555             side["canrecruit"] = true;
00556             side["controller"] = "human";
00557         }
00558 
00559         if(map.get() != NULL) {
00560             const surface mini(image::getMinimap(minimap_rect_.w,minimap_rect_.h,*map,0));
00561             SDL_Color back_color = {0,0,0,255};
00562             draw_centered_on_background(mini, minimap_rect_, back_color, video().getSurface());
00563         }
00564 
00565         int nsides = 0;
00566         foreach (const config &k, parameters_.scenario_data.child_range("side")) {
00567             if (k["allow_player"].to_bool(true)) ++nsides;
00568         }
00569 
00570         std::stringstream players;
00571         std::stringstream map_size;
00572         if(map.get() != NULL) {
00573             players << _("Players: ") << nsides;
00574             map_size << _("Size: ") << map.get()->w() << utils::unicode_multiplication_sign << map.get()->h();
00575         } else {
00576             players << _("Error");
00577             map_size << "";
00578         }
00579         num_players_label_.set_text(players.str());
00580         map_size_label_.set_text(map_size.str());
00581     }
00582 
00583     if(map_changed || use_map_settings_.pressed()) {
00584         const bool map_settings = use_map_settings_.checked();
00585 
00586         // If the map settings are wanted use them,
00587         // if not properly defined fall back to the default settings
00588         turns_slider_.set_value(map_settings ?
00589             settings::get_turns(parameters_.scenario_data["turns"]) :
00590             preferences::turns());
00591 
00592         xp_modifier_slider_.set_value(map_settings ?
00593             settings::get_xp_modifier(parameters_.scenario_data["experience_modifier"]) :
00594             preferences::xp_modifier());
00595 
00596         random_start_time_.set_check(map_settings ?
00597             parameters_.scenario_data["random_start_time"].to_bool(true) :
00598             preferences::random_start_time());
00599 
00600         // These are per player, always show values of player 1.
00601         /**
00602          * @todo This might not be 100% correct, but at the moment
00603          * it is not possible to show the fog and shroud per player.
00604          * This might change in the future.
00605          * NOTE when 'load game' is selected there are no sides.
00606          */
00607         config::const_child_itors sides = parameters_.scenario_data.child_range("side");
00608         if (sides.first != sides.second)
00609         {
00610             const config &cfg = *sides.first;
00611 
00612             village_gold_slider_.set_value(map_settings ?
00613                 settings::get_village_gold(cfg["village_gold"]) :
00614                 preferences::village_gold());
00615 
00616             village_support_slider_.set_value(map_settings ?
00617                 settings::get_village_support(cfg["village_support"]) :
00618                 preferences::village_support());
00619 
00620             fog_game_.set_check(map_settings ?
00621                 cfg["fog"].to_bool(true) :
00622                 preferences::fog());
00623 
00624             shroud_game_.set_check(map_settings ?
00625                 cfg["shroud"].to_bool(false) :
00626                 preferences::shroud());
00627         }
00628 
00629         // Set the widget states
00630         turns_slider_.enable(!map_settings);
00631         village_gold_slider_.enable(!map_settings);
00632         village_support_slider_.enable(!map_settings);
00633         xp_modifier_slider_.enable(!map_settings);
00634         random_start_time_.enable(!map_settings);
00635         fog_game_.enable(!map_settings);
00636         shroud_game_.enable(!map_settings);
00637     }
00638 }
00639 
00640 void create::hide_children(bool hide)
00641 {
00642     DBG_MP << (hide ? "hiding" : "showing" ) << " children widgets" << std::endl;
00643 
00644     ui::hide_children(hide);
00645 
00646     maps_menu_.hide(hide);
00647     turns_slider_.hide(hide);
00648     turns_label_.hide(hide);
00649 
00650     countdown_init_time_slider_.hide(hide);
00651     countdown_init_time_label_.hide(hide);
00652     countdown_turn_bonus_slider_.hide(hide);
00653     countdown_turn_bonus_label_.hide(hide);
00654     countdown_reservoir_time_slider_.hide(hide);
00655     countdown_reservoir_time_label_.hide(hide);
00656     countdown_action_bonus_slider_.hide(hide);
00657     countdown_action_bonus_label_.hide(hide);
00658     countdown_game_.hide(hide);
00659 
00660     village_gold_slider_.hide(hide);
00661     village_gold_label_.hide(hide);
00662     village_support_slider_.hide(hide);
00663     village_support_label_.hide(hide);
00664     xp_modifier_slider_.hide(hide);
00665     xp_modifier_label_.hide(hide);
00666 
00667     name_entry_label_.hide(hide);
00668     num_players_label_.hide(hide);
00669     map_size_label_.hide(hide);
00670     era_label_.hide(hide);
00671     map_label_.hide(hide);
00672 
00673     use_map_settings_.hide(hide);
00674     random_start_time_.hide(hide);
00675     fog_game_.hide(hide);
00676     shroud_game_.hide(hide);
00677     observers_game_.hide(hide);
00678     shuffle_sides_.hide(hide);
00679     cancel_game_.hide(hide);
00680     launch_game_.hide(hide);
00681     regenerate_map_.hide(hide || generator_ == NULL);
00682     generator_settings_.hide(hide || generator_ == NULL);
00683 
00684     era_combo_.hide(hide);
00685     vision_combo_.hide(hide);
00686     name_entry_.hide(hide);
00687 
00688     if (hide) {
00689         minimap_restorer_.assign(NULL);
00690     } else {
00691         minimap_restorer_.assign(new surface_restorer(&video(), minimap_rect_));
00692 
00693         const std::string& map_data = parameters_.scenario_data["map_data"];
00694 
00695         try {
00696             gamemap map(game_config(), map_data);
00697 
00698             const surface mini(image::getMinimap(minimap_rect_.w,minimap_rect_.h,map,0));
00699             SDL_Color back_color = {0,0,0,255};
00700             draw_centered_on_background(mini, minimap_rect_, back_color, video().getSurface());
00701         } catch(incorrect_map_format_error& e) {
00702             ERR_CF << "map could not be loaded: " << e.message << "\n";
00703         } catch(twml_exception& e) {
00704             ERR_CF <<  "map could not be loaded: " << e.dev_message << '\n';
00705         }
00706 
00707     }
00708 }
00709 
00710 void create::layout_children(const SDL_Rect& rect)
00711 {
00712     DBG_MP << "laying out the children" << std::endl;
00713 
00714     ui::layout_children(rect);
00715     SDL_Rect ca = client_area();
00716 
00717     const int border_size = 6;
00718     const int column_border_size = 10;
00719 
00720     int xpos = ca.x;
00721     int ypos = ca.y;
00722 
00723     // Dialog title
00724     ypos += title().height() + border_size;
00725 
00726     // Name Entry
00727     name_entry_label_.set_location(xpos, ypos);
00728     name_entry_.set_location(xpos + name_entry_label_.width() + border_size, ypos);
00729     name_entry_.set_width(ca.w - name_entry_label_.width() - border_size);
00730     ypos += std::max<int>(name_entry_.height(), name_entry_label_.height()) + border_size;
00731 
00732     // Save ypos here (column top)
00733     int ypos_columntop = ypos;
00734 
00735     // First column: minimap & random map options
00736     std::pair<int,int> resolution = preferences::resolution();
00737 
00738     const int resolution_for_small_minimap = 880;
00739 
00740     const int minimap_width = resolution.first > resolution_for_small_minimap ? 200 : 130;
00741 
00742     minimap_rect_ = create_rect(xpos, ypos, minimap_width, minimap_width);
00743     ypos += minimap_width + border_size;
00744 
00745     num_players_label_.set_location(xpos, ypos);
00746     ypos += num_players_label_.height() + border_size;
00747 
00748     map_size_label_.set_location(xpos, ypos);
00749     ypos += map_size_label_.height() + 2 * border_size;
00750 
00751     regenerate_map_.set_location(xpos, ypos);
00752     ypos += regenerate_map_.height() + border_size;
00753     generator_settings_.set_location(xpos, ypos);
00754     ypos += generator_settings_.height() + 2 * border_size;
00755 
00756     era_label_.set_location(xpos, ypos);
00757     ypos += era_label_.height() + border_size;
00758     era_combo_.set_location(xpos, ypos);
00759     ypos += era_combo_.height() + border_size;
00760     if(!local_players_only_) {
00761         password_button_.set_location(xpos, ypos);
00762         ypos += password_button_.height() + border_size;
00763     } else {
00764         password_button_.hide(true);
00765     }
00766 
00767 #ifdef MP_VISION_OPTIONAL
00768     vision_combo_.set_location(xpos, ypos);
00769     ypos += vision_combo_.height() + border_size;
00770 #endif
00771 
00772     // Second column: map menu
00773     ypos = ypos_columntop;
00774     xpos += minimap_width + column_border_size;
00775     map_label_.set_location(xpos, ypos);
00776     ypos += map_label_.height() + border_size;
00777 
00778     maps_menu_.set_max_width(200);
00779     maps_menu_.set_max_height(ca.h + ca.y - ypos);
00780     maps_menu_.set_location(xpos, ypos);
00781     // Menu dimensions are only updated when items are set. So do this now.
00782     int mapsel_save = maps_menu_.selection();
00783     maps_menu_.set_items(map_options_);
00784     maps_menu_.move_selection(mapsel_save);
00785 
00786     // Third column: big bunch of options
00787     ypos = ypos_columntop;
00788     xpos += 200 + column_border_size;
00789 
00790     turns_label_.set_location(xpos, ypos);
00791     ypos += turns_label_.height() + border_size;
00792     turns_slider_.set_width(ca.w - xpos);
00793     turns_slider_.set_location(xpos, ypos);
00794     ypos += turns_slider_.height() + border_size;
00795 
00796     village_gold_label_.set_location(xpos, ypos);
00797     ypos += village_gold_label_.height() + border_size;
00798     village_gold_slider_.set_width(ca.w - xpos);
00799     village_gold_slider_.set_location(xpos, ypos);
00800     ypos += village_gold_slider_.height() + border_size;
00801 
00802     village_support_label_.set_location(xpos, ypos);
00803     ypos += village_support_label_.height() + border_size;
00804     village_support_slider_.set_width(ca.w - xpos);
00805     village_support_slider_.set_location(xpos, ypos);
00806     ypos += village_support_slider_.height() + border_size;
00807 
00808     xp_modifier_label_.set_location(xpos, ypos);
00809     ypos += xp_modifier_label_.height() + border_size;
00810     xp_modifier_slider_.set_width(ca.w - xpos);
00811     xp_modifier_slider_.set_location(xpos, ypos);
00812     ypos += xp_modifier_slider_.height() + border_size;
00813 
00814     use_map_settings_.set_location(xpos, ypos);
00815     fog_game_.set_location(xpos + (ca.w - xpos)/2 + 5, ypos);
00816     ypos += use_map_settings_.height() + border_size;
00817 
00818     observers_game_.set_location(xpos, ypos);
00819     shroud_game_.set_location(xpos + (ca.w - xpos)/2 + 5, ypos);
00820     ypos += observers_game_.height() + border_size;
00821 
00822     shuffle_sides_.set_location(xpos, ypos);
00823     random_start_time_.set_location(xpos + (ca.w - xpos)/2 + 5, ypos);
00824     ypos += shuffle_sides_.height() + border_size;
00825 
00826     countdown_game_.set_location(xpos, ypos);
00827     ypos += countdown_game_.height() + border_size;
00828 
00829     countdown_init_time_label_.set_location(xpos, ypos);
00830     countdown_turn_bonus_label_.set_location(xpos + (ca.w - xpos)/2 + 5, ypos);
00831     ypos += countdown_init_time_label_.height() + border_size;
00832     countdown_init_time_slider_.set_width(((ca.w - xpos)/2)-5);
00833     countdown_turn_bonus_slider_.set_width(((ca.w - xpos)/2)-5);
00834     countdown_init_time_slider_.set_location(xpos, ypos);
00835     countdown_turn_bonus_slider_.set_location(xpos + (ca.w - xpos)/2 + 5, ypos);
00836     ypos += countdown_init_time_slider_.height() + border_size;
00837 
00838     countdown_reservoir_time_label_.set_location(xpos, ypos);
00839     countdown_action_bonus_label_.set_location(xpos + (ca.w - xpos)/2 + 5, ypos);
00840     ypos += countdown_reservoir_time_label_.height() + border_size;
00841     countdown_reservoir_time_slider_.set_width(((ca.w - xpos)/2)-5);
00842     countdown_action_bonus_slider_.set_width(((ca.w - xpos)/2)-5);
00843     countdown_reservoir_time_slider_.set_location(xpos, ypos);
00844     countdown_action_bonus_slider_.set_location(xpos + (ca.w - xpos)/2 + 5, ypos);
00845     ypos += countdown_reservoir_time_slider_.height() + border_size;
00846 
00847     // OK / Cancel buttons
00848     gui::button* left_button = &launch_game_;
00849     gui::button* right_button = &cancel_game_;
00850 
00851 #ifdef OK_BUTTON_ON_RIGHT
00852     std::swap(left_button,right_button);
00853 #endif
00854 
00855     // Buttons
00856     right_button->set_location(ca.x + ca.w - right_button->width(),
00857                                ca.y + ca.h - right_button->height());
00858     left_button->set_location(right_button->location().x - left_button->width() -
00859                               gui::ButtonHPadding, ca.y + ca.h - left_button->height());
00860 }
00861 
00862 } // namespace mp
00863 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

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