Shared faction selection algorithm between host and clients.

(Fix for bug #17407.)
This commit is contained in:
Guillaume Melquiond 2010-12-30 11:18:53 +00:00
parent eba2f27676
commit e5779c6a68
4 changed files with 62 additions and 45 deletions

View File

@ -273,47 +273,8 @@ connect::side::side(connect& parent, const config& cfg, int index) :
// Try to pick a faction for the sake of appearance
// and for filling in the blanks
if(faction_ == 0) {
std::vector<std::string> find;
std::string search_field;
if (cfg.has_attribute("faction")) {
// Choose based on faction
find.push_back(cfg["faction"]);
search_field = "id";
} else if (cfg["faction_from_recruit"].to_bool() && cfg.has_attribute("recruit")) {
// 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";
}
// Pick the first faction with the greater amount of data matching the criteria
int faction_index = 0;
int best_score = 0;
std::vector<const config*>::const_iterator faction = parent.era_sides_.begin();
while(faction != parent.era_sides_.end()) {
int faction_score = 0;
const config& side = (**faction);
std::vector<std::string> recruit;
recruit = utils::split(side[search_field]);
std::vector<std::string>::const_iterator search = find.begin();
while(search != find.end()) {
for(itor = recruit.begin(); itor != recruit.end(); ++itor) {
if(*itor == *search) {
faction_score++;
break;
}
}
++search;
}
if(faction_score > best_score) {
best_score = faction_score;
faction_ = faction_index;
}
++faction;
faction_index++;
}
faction_ = find_suitable_faction(parent.era_sides_, cfg);
if (faction_ < 0) faction_ = 0;
if (faction_) {
llm_.update_leader_list(faction_);
llm_.update_gender_list(llm_.get_leader());

View File

@ -837,5 +837,46 @@ const gui::label& ui::title() const
return title_;
}
int find_suitable_faction(faction_list const &fl, const config &cfg)
{
std::vector<std::string> find;
std::string search_field;
if (const config::attribute_value *f = cfg.get("faction")) {
// Choose based on faction.
find.push_back(f->str());
search_field = "id";
} else if (cfg["faction_from_recruit"].to_bool()) {
// Choose based on recruit.
find = utils::split(cfg["recruit"]);
search_field = "recruit";
} else if (const config::attribute_value *l = cfg.get("leader")) {
// Choose based on leader.
find.push_back(*l);
search_field = "leader";
} else {
return -1;
}
int res = -1, index = 0, best_score = 0;
foreach (const config *faction, fl)
{
int faction_score = 0;
std::vector<std::string> recruit = utils::split((*faction)[search_field]);
foreach (const std::string &search, find) {
foreach (const std::string &r, recruit) {
if (r == search) {
++faction_score;
break;
}
}
}
if (faction_score > best_score) {
best_score = faction_score;
res = index;
}
++index;
}
return res;
}
}// namespace mp

View File

@ -272,6 +272,10 @@ private:
};
};
typedef std::vector<const config *> faction_list;
/** Picks the first faction with the greater amount of data matching the criteria. */
int find_suitable_faction(faction_list const &fl, const config &side);
}
#endif

View File

@ -274,13 +274,24 @@ void wait::join_game(bool observe)
if (!color_str.empty())
color = game_config::color_info(color_str).index() - 1;
std::vector<std::string> choices;
std::vector<const config *> leader_sides;
foreach (const config &side, possible_sides)
foreach (const config &side, possible_sides) {
leader_sides.push_back(&side);
}
int forced_faction = find_suitable_faction(leader_sides, *side_choice);
if (forced_faction >= 0) {
const config *f = leader_sides[forced_faction];
leader_sides.clear();
leader_sides.push_back(f);
}
std::vector<std::string> choices;
foreach (const config *s, leader_sides)
{
const config &side = *s;
const std::string &name = side["name"];
const std::string &icon = side["image"];
leader_sides.push_back(&side);
if (!icon.empty()) {
std::string rgb = side["flag_rgb"];
@ -313,7 +324,7 @@ void wait::join_game(bool observe)
config faction;
config& change = faction.add_child("change_faction");
change["name"] = preferences::login();
change["faction"] = faction_choice;
change["faction"] = forced_faction >= 0 ? forced_faction : faction_choice;
change["leader"] = leader_choice;
change["gender"] = gender_choice;
network::send_data(faction, 0);