29 #define LOG_MP LOG_STREAM(info, log_mp_connect_engine)
30 #define ERR_MP LOG_STREAM(err, log_mp_connect_engine)
40 const config& side,
const bool lock_settings,
const bool use_map_settings,
const bool saved_game)
42 , era_factions_(era_factions)
43 , side_num_(side[
"side"].to_int())
44 , faction_from_recruit_(side[
"faction_from_recruit"].to_bool())
45 , original_faction_(get_default_faction(side)[
"faction"].str())
46 , original_recruit_(
utils::
split(get_default_faction(side)[
"recruit"].str()))
48 , has_no_recruits_(original_recruit_.empty() && side[
"previous_recruits"].empty())
49 , faction_lock_(side[
"faction_lock"].to_bool(lock_settings))
50 , leader_lock_(side[
"leader_lock"].to_bool(lock_settings))
51 , available_factions_()
52 , available_leaders_()
53 , available_genders_()
54 , choosable_factions_()
55 , choosable_leaders_()
56 , choosable_genders_()
57 , current_faction_(nullptr)
58 , current_leader_(
"null")
59 , current_gender_(
"null")
60 , default_leader_type_(
"")
61 , default_leader_gender_(
"")
63 std::string leader_id = side[
"id"];
69 auto set_leader = [&](
const config&
cfg) {
71 leader_id =
cfg[
"id"];
87 if(!leader_id.empty()) {
90 if(
auto p_cfg = side.
find_child(
"unit",
"id", leader_id)) {
98 if(
auto p_cfg = side.
find_child(
"unit",
"canrecruit",
"yes")) {
131 if((*faction)[
"id"] ==
id) {
138 ERR_MP <<
"Faction '" <<
id <<
"' is not available for side " <<
side_num_ <<
" Ignoring";
169 std::vector<std::string> faction_choices, faction_excepts;
172 if(faction_choices.size() == 1 && faction_choices.front().empty()) {
173 faction_choices.clear();
177 if(faction_excepts.size() == 1 && faction_excepts.front().empty()) {
178 faction_excepts.clear();
182 std::vector<int> nonrandom_sides;
183 std::vector<int> fallback_nonrandom_sides;
187 if(faction[
"random_faction"].to_bool()) {
191 const std::string& faction_id = faction[
"id"];
193 if(!faction_choices.empty() &&
std::find(faction_choices.begin(), faction_choices.end(),
194 faction_id) == faction_choices.end()) {
198 if(!faction_excepts.empty() &&
std::find(faction_excepts.begin(), faction_excepts.end(),
199 faction_id) != faction_excepts.end()) {
204 fallback_nonrandom_sides.push_back(
i);
206 if(!avoid.empty() &&
std::find(avoid.begin(), avoid.end(),
207 faction_id) != avoid.end()) {
212 nonrandom_sides.push_back(
i);
215 if(nonrandom_sides.empty()) {
217 nonrandom_sides = fallback_nonrandom_sides;
220 if(nonrandom_sides.empty()) {
233 if(nonrandom_leaders.empty()) {
235 if(leader !=
"random") {
236 nonrandom_leaders.push_back(leader);
241 if(nonrandom_leaders.empty()) {
243 "Unable to find a leader type for faction $faction", {{
"faction", (*current_faction_)[
"name"].str()}}));
256 std::vector<std::string> nonrandom_genders;
258 if(gender !=
"random") {
259 nonrandom_genders.push_back(gender);
273 const config* custom_faction =
nullptr;
277 if((*faction)[
"id"] ==
"Custom" && !show_custom_faction) {
282 custom_faction = faction;
320 if((*
f)[
"id"] !=
"Random") {
329 std::set<std::string> seen;
424 if(default_gender.empty()) {
439 [&default_faction](
const config* faction) {
440 return (*faction)[
"id"] == default_faction;
452 std::vector<std::string>
find;
453 std::string search_field;
462 search_field =
"recruit";
464 find.push_back(
"Custom");
468 int res = -1,
index = 0, best_score = 0;
470 int faction_score = 0;
471 for(
const std::string& search :
find) {
472 for(
const std::string& r :
utils::split((*faction)[search_field])) {
480 if(faction_score > best_score) {
481 best_score = faction_score;
500 std::vector<std::string> leaders_to_append =
utils::split((*faction)[
"leader"]);
503 leaders_to_append.end());
532 ERR_MP <<
"Leader '" << leader <<
"' is not available for side " <<
side_num_ <<
" Ignoring";
542 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.
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()
flg_manager(const era_metadata &era_info, const std::vector< const config * > &era_factions, const config &side, bool lock_settings, bool use_map_settings, bool saved_game)
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 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_
void set_current_gender(const unsigned index)
void append_leaders_from_faction(const config *faction)
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(std::string_view 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)
auto * find(Container &container, const Value &value)
Convenience wrapper for using find on a container without needing to comare to end()
The base template for associating string values with enum values.
static map_location::direction s
unit_type_data unit_types