mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-04 17:51:17 +00:00
Shared faction selection algorithm between host and clients.
(Fix for bug #17407.)
This commit is contained in:
parent
eba2f27676
commit
e5779c6a68
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user