multiplayer_create.cpp

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

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs