29 #define LOG_MP LOG_STREAM(info, log_mp_connect_engine)
30 #define ERR_MP LOG_STREAM(err, log_mp_connect_engine)
36 const config& side,
const bool lock_settings,
const bool use_map_settings,
const bool saved_game)
37 : era_factions_(era_factions)
38 , side_num_(side[
"side"].to_int())
39 , faction_from_recruit_(side[
"faction_from_recruit"].to_bool())
40 , original_type_(get_default_faction(side)[
"type"].str())
41 , original_gender_(get_default_faction(side)[
"gender"].str())
43 , original_faction_(get_default_faction(side)[
"faction"].str())
44 , original_recruit_(
utils::
split(get_default_faction(side)[
"recruit"].str()))
45 , choose_faction_by_leader_(side[
"leader"].str())
47 , has_no_recruits_(original_recruit_.empty() && side[
"previous_recruits"].empty())
48 , faction_lock_(side[
"faction_lock"].to_bool(lock_settings))
49 , leader_lock_(side[
"leader_lock"].to_bool(lock_settings))
50 , available_factions_()
51 , available_leaders_()
52 , available_genders_()
53 , choosable_factions_()
54 , choosable_leaders_()
55 , choosable_genders_()
56 , current_faction_(nullptr)
57 , current_leader_(
"null")
58 , current_gender_(
"null")
59 , default_leader_type_(side[
"type"])
60 , default_leader_gender_(side[
"gender"])
61 , default_leader_cfg_(nullptr)
63 const std::string& leader_id = side[
"id"];
64 if(!leader_id.empty()) {
76 if(side_unit[
"canrecruit"].to_bool()) {
98 if(
current_leader_ == side_unit[
"type"] && side_unit[
"canrecruit"].to_bool()) {
123 if((*faction)[
"id"] ==
id) {
130 ERR_MP <<
"Faction '" <<
id <<
"' is not available for side " <<
side_num_ <<
" Ignoring";
161 std::vector<std::string> faction_choices, faction_excepts;
164 if(faction_choices.size() == 1 && faction_choices.front().empty()) {
165 faction_choices.clear();
169 if(faction_excepts.size() == 1 && faction_excepts.front().empty()) {
170 faction_excepts.clear();
174 std::vector<int> nonrandom_sides;
175 std::vector<int> fallback_nonrandom_sides;
179 if(faction[
"random_faction"].to_bool()) {
183 const std::string& faction_id = faction[
"id"];
185 if(!faction_choices.empty() && std::find(faction_choices.begin(), faction_choices.end(),
186 faction_id) == faction_choices.end()) {
190 if(!faction_excepts.empty() && std::find(faction_excepts.begin(), faction_excepts.end(),
191 faction_id) != faction_excepts.end()) {
196 fallback_nonrandom_sides.push_back(
i);
198 if(!avoid.empty() && std::find(avoid.begin(), avoid.end(),
199 faction_id) != avoid.end()) {
204 nonrandom_sides.push_back(
i);
207 if(nonrandom_sides.empty()) {
209 nonrandom_sides = fallback_nonrandom_sides;
212 if(nonrandom_sides.empty()) {
225 if(nonrandom_leaders.empty()) {
227 if(leader !=
"random") {
228 nonrandom_leaders.push_back(leader);
233 if(nonrandom_leaders.empty()) {
235 "Unable to find a leader type for faction $faction", {{
"faction", (*current_faction_)[
"name"].str()}}));
248 std::vector<std::string> nonrandom_genders;
250 if(gender !=
"random") {
251 nonrandom_genders.push_back(gender);
265 const config* custom_faction =
nullptr;
269 if((*faction)[
"id"] ==
"Custom" && !show_custom_faction) {
274 custom_faction = faction;
312 if((*
f)[
"id"] !=
"Random") {
321 std::set<std::string> seen;
416 if(default_gender.empty()) {
431 [&default_faction](
const config* faction) {
432 return (*faction)[
"id"] == default_faction;
444 std::vector<std::string> find;
445 std::string search_field;
454 search_field =
"recruit";
458 search_field =
"leader";
460 find.push_back(
"Custom");
464 int res = -1,
index = 0, best_score = 0;
466 int faction_score = 0;
467 for(
const std::string& search : find) {
468 for(
const std::string& r :
utils::split((*faction)[search_field])) {
476 if(faction_score > best_score) {
477 best_score = faction_score;
496 std::vector<std::string> leaders_to_append =
utils::split((*faction)[
"leader"]);
499 leaders_to_append.end());
528 ERR_MP <<
"Leader '" << leader <<
"' is not available for side " <<
side_num_ <<
" Ignoring";
538 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.
void erase_if(Container &container, const Predicate &predicate)
Convenience wrapper for using std::remove_if on a container.
std::vector< std::string > split(const config_attribute_value &val)
static map_location::direction s
unit_type_data unit_types