28 #define LOG_MP LOG_STREAM(info, log_mp_connect_engine)
29 #define ERR_MP LOG_STREAM(err, log_mp_connect_engine)
35 const config& side,
const bool lock_settings,
const bool use_map_settings,
const bool saved_game)
36 : era_factions_(era_factions)
37 , side_num_(side[
"side"].to_int())
38 , faction_from_recruit_(side[
"faction_from_recruit"].to_bool())
39 , original_type_(get_default_faction(side)[
"type"].str())
40 , original_gender_(get_default_faction(side)[
"gender"].str())
42 , original_faction_(get_default_faction(side)[
"faction"].str())
43 , original_recruit_(
utils::
split(get_default_faction(side)[
"recruit"].str()))
44 , choose_faction_by_leader_(side[
"leader"].str())
46 , has_no_recruits_(original_recruit_.empty() && side[
"previous_recruits"].empty())
47 , faction_lock_(side[
"faction_lock"].to_bool(lock_settings))
48 , leader_lock_(side[
"leader_lock"].to_bool(lock_settings))
49 , available_factions_()
50 , available_leaders_()
51 , available_genders_()
52 , choosable_factions_()
53 , choosable_leaders_()
54 , choosable_genders_()
55 , current_faction_(nullptr)
56 , current_leader_(
"null")
57 , current_gender_(
"null")
58 , default_leader_type_(side[
"type"])
59 , default_leader_gender_(side[
"gender"])
60 , default_leader_cfg_(nullptr)
62 const std::string& leader_id = side[
"id"];
63 if(!leader_id.empty()) {
75 if(side_unit[
"canrecruit"].to_bool()) {
97 if(
current_leader_ == side_unit[
"type"] && side_unit[
"canrecruit"].to_bool()) {
122 if((*faction)[
"id"] ==
id) {
129 ERR_MP <<
"Faction '" <<
id <<
"' is not available for side " <<
side_num_ <<
" Ignoring";
160 std::vector<std::string> faction_choices, faction_excepts;
163 if(faction_choices.size() == 1 && faction_choices.front().empty()) {
164 faction_choices.clear();
168 if(faction_excepts.size() == 1 && faction_excepts.front().empty()) {
169 faction_excepts.clear();
173 std::vector<int> nonrandom_sides;
174 std::vector<int> fallback_nonrandom_sides;
178 if(faction[
"random_faction"].to_bool()) {
182 const std::string& faction_id = faction[
"id"];
184 if(!faction_choices.empty() && std::find(faction_choices.begin(), faction_choices.end(),
185 faction_id) == faction_choices.end()) {
189 if(!faction_excepts.empty() && std::find(faction_excepts.begin(), faction_excepts.end(),
190 faction_id) != faction_excepts.end()) {
195 fallback_nonrandom_sides.push_back(
i);
197 if(!avoid.empty() && std::find(avoid.begin(), avoid.end(),
198 faction_id) != avoid.end()) {
203 nonrandom_sides.push_back(
i);
206 if(nonrandom_sides.empty()) {
208 nonrandom_sides = fallback_nonrandom_sides;
211 if(nonrandom_sides.empty()) {
224 if(nonrandom_leaders.empty()) {
226 if(leader !=
"random") {
227 nonrandom_leaders.push_back(leader);
232 if(nonrandom_leaders.empty()) {
234 "Unable to find a leader type for faction $faction", {{
"faction", (*current_faction_)[
"name"].str()}}));
247 std::vector<std::string> nonrandom_genders;
249 if(gender !=
"random") {
250 nonrandom_genders.push_back(gender);
264 const config* custom_faction =
nullptr;
268 if((*faction)[
"id"] ==
"Custom" && !show_custom_faction) {
273 custom_faction = faction;
311 if((*
f)[
"id"] !=
"Random") {
320 std::set<std::string> seen;
322 [&seen](
const std::string&
s) { return !seen.insert(s).second; }
419 if(default_gender.empty()) {
434 [&default_faction](
const config* faction) {
435 return (*faction)[
"id"] == default_faction;
447 std::vector<std::string> find;
448 std::string search_field;
457 search_field =
"recruit";
461 search_field =
"leader";
463 find.push_back(
"Custom");
467 int res = -1,
index = 0, best_score = 0;
469 int faction_score = 0;
470 for(
const std::string& search : find) {
471 for(
const std::string& r :
utils::split((*faction)[search_field])) {
479 if(faction_score > best_score) {
480 best_score = faction_score;
499 std::vector<std::string> leaders_to_append =
utils::split((*faction)[
"leader"]);
502 leaders_to_append.end());
531 ERR_MP <<
"Leader '" << leader <<
"' is not available for side " <<
side_num_ <<
" Ignoring";
541 ERR_MP <<
"Gender '" << gender <<
"' is not available for side " <<
side_num_ <<
" Ignoring";
A config object defines a single node in a WML file, with access to child nodes.
optional_config_impl< config > find_child(config_key_type key, const std::string &name, const std::string &value)
Returns the first child of tag key with a name attribute containing value.
child_itors child_range(config_key_type key)
optional_config_impl< config > optional_child(config_key_type key, int n=0)
Equivalent to mandatory_child, but returns an empty optional if the nth child was not found.
void update_available_factions()
const bool faction_from_recruit_
void update_choosable_leaders()
void update_choosable_factions()
std::string default_leader_type_
void update_available_leaders()
const std::vector< std::string > original_recruit_
std::string current_leader_
const bool has_no_recruits_
void update_available_genders()
void set_current_faction(const unsigned index)
void select_default_faction()
void resolve_random(randomness::mt_rng &rng, const std::vector< std::string > &avoid)
std::vector< std::string > choosable_leaders_
std::vector< std::string > choosable_genders_
std::vector< std::string > available_genders_
void update_choosable_genders()
const config * current_faction_
int faction_index(const config &faction) const
const std::string choose_faction_by_leader_
const std::string original_faction_
void set_current_leader(const unsigned index)
int leader_index(const std::string &leader) const
returns -1 if no leader with that name was found
int gender_index(const std::string &gender) const
returns -1 if no gender with that name was found
int current_faction_index() const
static const config & get_default_faction(const config &cfg)
std::string default_leader_gender_
std::vector< const config * > available_factions_
std::vector< const config * > choosable_factions_
flg_manager(const std::vector< const config * > &era_factions, const config &side, bool lock_settings, bool use_map_settings, bool saved_game)
void set_current_gender(const unsigned index)
std::string savegame_gender_
void append_leaders_from_faction(const config *faction)
const config * default_leader_cfg_
const std::vector< const config * > & era_factions_
std::string current_gender_
int find_suitable_faction() const
std::vector< std::string > available_leaders_
uint32_t get_next_random()
Get a new random number.
static const std::string s_female
Standard string id (not translatable) for FEMALE.
static const std::string s_male
Standard string id (not translatable) for MALE.
const unit_type * find(const std::string &key, unit_type::BUILD_STATUS status=unit_type::FULL) const
Finds a unit_type by its id() and makes sure it is built to the specified level.
A single unit type that the player may recruit.
This class represents a single unit of a specific type.
Definitions for the interface to Wesnoth Markup Language (WML).
static lg::log_domain log_mp_connect_engine("mp/connect/engine")
static std::string _(const char *str)
Standard logging facilities (interface).
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
std::vector< std::string > split(const config_attribute_value &val)
static map_location::DIRECTION s
unit_type_data unit_types