diff --git a/changelog b/changelog index 218eb212e27..528278fd00e 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,7 @@ +Version 1.1.9+svn: + * multiplayer + * scenarios can set faction, recruit, leader, and some other initial settings previously ignored in multiplayer + Version 1.1.9: * campaigns * Heir to the Throne diff --git a/src/config.cpp b/src/config.cpp index 0acfca49de6..9724d573872 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -570,6 +570,23 @@ config config::merge_with(const config& c) const return n; } +void config::prune() { + string_map::iterator val = values.begin(); + while(val != values.end()) { + if(val->second.empty()) { + values.erase(val++); + } else { + ++val; + } + } + + for(child_map::const_iterator list = children.begin(); list != children.end(); ++list) { + for(child_list::const_iterator child = list->second.begin(); child != list->second.end(); ++child) { + (*child)->prune(); + } + } +} + void config::reset_translation() const { for(string_map::const_iterator val = values.begin(); val != values.end(); ++val) { diff --git a/src/config.hpp b/src/config.hpp index b712910b7fb..9a543f293c6 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -125,6 +125,9 @@ public: config merge_with(const config& c) const; + //removes keys with empty values + void prune(); + //append data from another config object to this one. attributes in the //latter config object will clobber attributes in this one. void append(const config& cfg); diff --git a/src/leader_list.cpp b/src/leader_list.cpp index 29d7e4aedc3..a655d80b52b 100644 --- a/src/leader_list.cpp +++ b/src/leader_list.cpp @@ -30,10 +30,15 @@ leader_list_manager::leader_list_manager(const config::child_list& side_list, void leader_list_manager::set_combo(gui::combo* combo) { + int selected = combo_ != NULL ? combo_->selected() : 0; combo_ = combo; - if (combo_ != NULL) { - update_leader_list(0); + if(combo_ != NULL) { + if(leaders_.empty()) { + update_leader_list(0); + } else { + populate_combo(selected); + } } } @@ -77,8 +82,13 @@ void leader_list_manager::update_leader_list(int side_index) leaders_.push_back(default_leader); } - std::vector leader_strings; + leaders_.push_back("random"); + populate_combo(default_index); +} +void leader_list_manager::populate_combo(int selected_index) { + std::vector::const_iterator itor; + std::vector leader_strings; for(itor = leaders_.begin(); itor != leaders_.end(); ++itor) { const game_data::unit_type_map& utypes = data_->unit_types; @@ -90,17 +100,17 @@ void leader_list_manager::update_leader_list(int side_index) leader_strings.push_back(IMAGE_PREFIX + image + std::string("~TC(1," + utypes.find(*itor)->second.flag_rgb() + ")") + COLUMN_SEPARATOR + name); } else { - leader_strings.push_back("?"); + if(*itor == "random") { + leader_strings.push_back(IMAGE_PREFIX + random_enemy_picture + COLUMN_SEPARATOR + _("Random")); + } else { + leader_strings.push_back("?"); + } } } - leaders_.push_back("random"); - leader_strings.push_back(IMAGE_PREFIX + random_enemy_picture + - COLUMN_SEPARATOR + _("Random")); - if(combo_ != NULL) { combo_->set_items(leader_strings); - combo_->set_selected(default_index); + combo_->set_selected(selected_index); } } @@ -112,8 +122,10 @@ void leader_list_manager::set_leader(const std::string& leader) int leader_index = 0; for(std::vector::const_iterator itor = leaders_.begin(); itor != leaders_.end(); ++itor) { - if (leader == *itor) + if(leader == *itor) { combo_->set_selected(leader_index); + return; + } ++leader_index; } } diff --git a/src/leader_list.hpp b/src/leader_list.hpp index caa3e8a7316..ed96a286c09 100644 --- a/src/leader_list.hpp +++ b/src/leader_list.hpp @@ -35,6 +35,8 @@ public: bool is_leader_ok(std::string leader); private: + void populate_combo(int selected_index); + std::vector leaders_; config::child_list side_list_; const game_data* data_; diff --git a/src/multiplayer_connect.cpp b/src/multiplayer_connect.cpp index 03d35355a2c..8be7266f0f7 100644 --- a/src/multiplayer_connect.cpp +++ b/src/multiplayer_connect.cpp @@ -149,6 +149,78 @@ connect::side::side(connect& parent, const config& cfg, int index) : } combo_leader_.set_items(leader_name_pseudolist); combo_leader_.set_selected(0); + } else if(parent_->params_.use_map_settings) { + //lock gold and income sliders if those are set by the scenario + if(!cfg_["gold"].empty()) + slider_gold_.enable(false); + if(!cfg_["income"].empty()) + slider_income_.enable(false); + if(!cfg_["team_name"].empty()) + combo_team_.enable(false); + if(!cfg_["colour"].empty()) + combo_colour_.enable(false); + + //set the leader + leader_ = cfg_["type"]; + if(!leader_.empty()) { + combo_leader_.enable(false); + llm_.set_combo(NULL); + std::vector leader_name_pseudolist; + game_data::unit_type_map::const_iterator leader_name = parent_->game_data_.unit_types.find(leader_); + if(leader_name == parent_->game_data_.unit_types.end()) { + leader_name_pseudolist.push_back("?"); + } else { + leader_name_pseudolist.push_back(leader_name->second.language_name()); + } + combo_leader_.set_items(leader_name_pseudolist); + combo_leader_.set_selected(0); + } + + //try to pick a faction for the sake of appearance and for filling in the blanks + if(faction_ == 0) { + std::vector find; + std::string search_field; + if(!cfg_["faction"].empty()) { + //choose based on faction + find.push_back(cfg_["faction"]); + search_field = "id"; + } else if(!cfg_["recruit"].empty()) { + //choose based on recruit + find = utils::split(cfg_["recruit"]); + search_field = "recruit"; + } else if(!leader_.empty()) { + //choose based on leader + find.push_back(leader_); + search_field = "leader"; + } + + std::vector::const_iterator search = find.begin(); + while(search != find.end()) { + int faction_index = 0; + std::vector::const_iterator faction = parent.era_sides_.begin(); + while(faction_ == 0 && faction != parent.era_sides_.end()) { + const config& side = (**faction); + std::vector recruit; + recruit = utils::split(side[search_field]); + for(itor = recruit.begin(); itor != recruit.end(); ++itor) { + if(*itor == *search) { + faction_ = faction_index; + llm_.update_leader_list(faction_); + combo_faction_.enable(false); + } + } + ++faction; + faction_index++; + } + //exit outmost loop if we've found a faction + if(!combo_faction_.enabled()) { + break; + } + ++search; + } + } else { + combo_faction_.enable(false); + } } update_ui(); @@ -170,7 +242,7 @@ connect::side::side(const side& a) : label_gold_(a.label_gold_), label_income_(a.label_income_), enabled_(a.enabled_), changed_(a.changed_), llm_(a.llm_) { - llm_.set_combo(enabled_ ? &combo_leader_ : NULL); + llm_.set_combo((enabled_ && leader_.empty()) ? &combo_leader_ : NULL); } void connect::side::add_widgets_to_scrollpane(gui::scrollpane& pane, int pos) @@ -369,7 +441,7 @@ void connect::side::update_ui() config connect::side::get_config() const { - config res = cfg_; + config res(cfg_); // If the user is allowed to change type, faction, leader etc, then // import their new values in the config. @@ -481,6 +553,17 @@ config connect::side::get_config() const res["allow_changes"] = "no"; } + if(parent_->params_.use_map_settings && enabled_) { + config trimmed = cfg_; + trimmed["controller"] = ""; + trimmed["side"] = ""; + if(controller_ != CNTR_COMPUTER) { + //only override names for computer controlled players + trimmed["user_description"] = ""; + } + trimmed.prune(); + return res.merge_with(trimmed); + } return res; } @@ -545,12 +628,16 @@ void connect::side::import_network_user(const config& data) id_ = data["name"]; controller_ = CNTR_NETWORK; - if (enabled_ && !parent_->era_sides_.empty()) { - faction_ = lexical_cast_default(data["faction"], 0); - if (faction_ > int(parent_->era_sides_.size())) - faction_ = 0; - llm_.update_leader_list(faction_); - llm_.set_leader(data["leader"]); + if(enabled_ && !parent_->era_sides_.empty()) { + if(combo_faction_.enabled()) { + faction_ = lexical_cast_default(data["faction"], 0); + if(faction_ > int(parent_->era_sides_.size())) + faction_ = 0; + llm_.update_leader_list(faction_); + } + if(combo_leader_.enabled()) { + llm_.set_leader(data["leader"]); + } } update_ui(); @@ -562,8 +649,10 @@ void connect::side::reset(mp::controller controller) controller_ = controller; if(enabled_ && !parent_->era_sides_.empty()) { - faction_ = 0; - llm_.update_leader_list(0); + if(combo_faction_.enabled()) + faction_ = 0; + if(combo_leader_.enabled()) + llm_.update_leader_list(0); } update_ui(); @@ -1300,5 +1389,3 @@ void connect::kick_player(const std::string& name) } } - -