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_faction_(get_default_faction(side)[
"faction"].str())
41 , original_recruit_(
utils::
split(get_default_faction(side)[
"recruit"].str()))
43 , has_no_recruits_(original_recruit_.empty() && side[
"previous_recruits"].empty())
44 , faction_lock_(side[
"faction_lock"].to_bool(lock_settings))
45 , leader_lock_(side[
"leader_lock"].to_bool(lock_settings))
46 , available_factions_()
47 , available_leaders_()
48 , available_genders_()
49 , choosable_factions_()
50 , choosable_leaders_()
51 , choosable_genders_()
52 , current_faction_(nullptr)
53 , current_leader_(
"null")
54 , current_gender_(
"null")
55 , default_leader_type_(
"")
56 , default_leader_gender_(
"")
58 std::string leader_id = side[
"id"];
64 auto set_leader = [&](
const config& cfg) {
66 leader_id = cfg[
"id"];
82 if(!leader_id.empty()) {
85 if(
auto p_cfg = side.
find_child(
"unit",
"id", leader_id)) {
93 if(
auto p_cfg = side.
find_child(
"unit",
"canrecruit",
"yes")) {
126 if((*faction)[
"id"] ==
id) {
133 ERR_MP <<
"Faction '" <<
id <<
"' is not available for side " <<
side_num_ <<
" Ignoring";
164 std::vector<std::string> faction_choices, faction_excepts;
167 if(faction_choices.size() == 1 && faction_choices.front().empty()) {
168 faction_choices.clear();
172 if(faction_excepts.size() == 1 && faction_excepts.front().empty()) {
173 faction_excepts.clear();
177 std::vector<int> nonrandom_sides;
178 std::vector<int> fallback_nonrandom_sides;
182 if(faction[
"random_faction"].to_bool()) {
186 const std::string& faction_id = faction[
"id"];
188 if(!faction_choices.empty() &&
std::find(faction_choices.begin(), faction_choices.end(),
189 faction_id) == faction_choices.end()) {
193 if(!faction_excepts.empty() &&
std::find(faction_excepts.begin(), faction_excepts.end(),
194 faction_id) != faction_excepts.end()) {
199 fallback_nonrandom_sides.push_back(
i);
201 if(!avoid.empty() &&
std::find(avoid.begin(), avoid.end(),
202 faction_id) != avoid.end()) {
207 nonrandom_sides.push_back(
i);
210 if(nonrandom_sides.empty()) {
212 nonrandom_sides = fallback_nonrandom_sides;
215 if(nonrandom_sides.empty()) {
228 if(nonrandom_leaders.empty()) {
230 if(leader !=
"random") {
231 nonrandom_leaders.push_back(leader);
236 if(nonrandom_leaders.empty()) {
238 "Unable to find a leader type for faction $faction", {{
"faction", (*current_faction_)[
"name"].str()}}));
251 std::vector<std::string> nonrandom_genders;
253 if(gender !=
"random") {
254 nonrandom_genders.push_back(gender);
268 const config* custom_faction =
nullptr;
272 if((*faction)[
"id"] ==
"Custom" && !show_custom_faction) {
277 custom_faction = faction;
315 if((*
f)[
"id"] !=
"Random") {
324 std::set<std::string> seen;
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";
459 find.push_back(
"Custom");
463 int res = -1,
index = 0, best_score = 0;
465 int faction_score = 0;
466 for(
const std::string& search :
find) {
467 for(
const std::string& r :
utils::split((*faction)[search_field])) {
475 if(faction_score > best_score) {
476 best_score = faction_score;
495 std::vector<std::string> leaders_to_append =
utils::split((*faction)[
"leader"]);
498 leaders_to_append.end());
527 ERR_MP <<
"Leader '" << leader <<
"' is not available for side " <<
side_num_ <<
" Ignoring";
537 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()
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_
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)
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()
static map_location::direction s
unit_type_data unit_types