Make it possible to overwrite a default leader by mp::connect selection.

Default leader is found by checking for "id" in [side] tag. If id was
found, it will check if leader was carried over and is now in [unit]
tag. If leader was still not found, it will try to pick a first unit
which can recruit.

If "Use map settings" are off or no leader was specified, mp::connect
will allow to select a leader from a faction. If default leader was in
carryover and the new leader was selected, the old leader attributes
will be cleared, keeping only an "id" and a newly set "type" and
"gender" attributes.
This commit is contained in:
Andrius Silinskas 2013-08-29 16:33:35 +01:00
parent 879849ed42
commit 311d101fe5
4 changed files with 67 additions and 47 deletions

View file

@ -55,8 +55,37 @@ flg_manager::flg_manager(const std::vector<const config*>& era_factions,
choosable_genders_(),
current_faction_(NULL),
current_leader_("null"),
current_gender_("null")
current_gender_("null"),
default_leader_type_(side_["type"]),
default_leader_cfg_(NULL)
{
const std::string& leader_id = side_["id"];
if (!leader_id.empty()) {
// Check if leader was carried over and now is in [unit] tag.
default_leader_cfg_ = &side_.find_child("unit", "id", leader_id);
if (*default_leader_cfg_) {
default_leader_type_ = (*default_leader_cfg_)["type"].str();
} else {
default_leader_cfg_ = NULL;
}
} else if (default_leader_type_.empty()) {
// Find a unit which can recruit.
BOOST_FOREACH(const config& side_unit, side_.child_range("unit")) {
if (side_unit["canrecruit"].to_bool()) {
default_leader_type_ = side_unit["type"].str();
default_leader_cfg_ = &side_unit;
break;
}
}
}
if (!default_leader_type_.empty()) {
const unit_type* unit = unit_types.find(default_leader_type_);
if (unit == NULL) {
default_leader_type_.clear();
default_leader_cfg_ = NULL;
}
}
update_available_factions();
set_current_faction((unsigned) 0);
@ -288,9 +317,8 @@ void flg_manager::update_available_leaders()
available_leaders_.clear();
// Add a default leader if there is one.
const std::string& leader= leader_type();
if (!leader.empty()) {
available_leaders_.push_back(leader);
if (!default_leader_type_.empty()) {
available_leaders_.push_back(default_leader_type_);
}
if (!saved_game_) {
@ -398,13 +426,12 @@ void flg_manager::update_choosable_leaders()
{
choosable_leaders_ = available_leaders_;
const std::string& leader = leader_type();
if (!leader.empty() && map_settings_) {
if (!default_leader_type_.empty() && map_settings_) {
if (std::find(available_leaders_.begin(), available_leaders_.end(),
leader) != available_leaders_.end()) {
default_leader_type_) != available_leaders_.end()) {
choosable_leaders_.clear();
choosable_leaders_.push_back(leader);
choosable_leaders_.push_back(default_leader_type_);
}
}
}
@ -483,36 +510,6 @@ void flg_manager::append_leaders_from_faction(const config* faction)
leaders_to_append.end());
}
std::string flg_manager::leader_type() const
{
const std::string& leader_id = side_["id"];
std::string leader_type = side_["type"];
if (!leader_id.empty()) {
// Check if leader was carried over and now is in [unit] tag.
const config& leader_unit = side_.find_child("unit", "id", leader_id);
if (leader_unit) {
leader_type = leader_unit["type"].str();
}
} else if (leader_type.empty()) {
// Find a unit which can recruit.
BOOST_FOREACH(const config& side_unit, side_.child_range("unit")) {
if (side_unit["canrecruit"].to_bool()) {
leader_type = side_unit["type"].str();
break;
}
}
}
if (!leader_type.empty()) {
const unit_type *unit = unit_types.find(leader_type);
if (unit) {
return leader_type;
}
}
return "";
}
int flg_manager::faction_index(const config* faction) const
{
std::vector<const config*>::const_iterator it = std::find(

View file

@ -72,6 +72,9 @@ public:
const std::string& current_gender() const
{ return current_gender_; }
const config* default_leader_cfg() const
{ return default_leader_cfg_; }
int current_faction_index() const
{ return faction_index(current_faction_); }
@ -90,8 +93,6 @@ private:
// to a choosable factions.
void append_leaders_from_faction(const config* faction);
std::string leader_type() const;
int faction_index(const config* faction) const;
int leader_index(const std::string& leader) const;
int gender_index(const std::string& gender) const;
@ -123,6 +124,9 @@ private:
const config* current_faction_;
std::string current_leader_;
std::string current_gender_;
std::string default_leader_type_;
const config* default_leader_cfg_;
};
} // end namespace mp

View file

@ -53,7 +53,6 @@ const std::string attributes_to_trim[] = {
"extra_recruit",
"previous_recruits",
"controller",
"id",
"team_name",
"user_team_name",
"color",
@ -796,7 +795,6 @@ side_engine::side_engine(const config& cfg, connect_engine& parent_engine,
allow_player_(cfg["controller"] == "ai" && cfg["allow_player"].empty() ?
false : cfg["allow_player"].to_bool(true)),
allow_changes_(cfg["allow_changes"].to_bool(true)),
leader_id_(cfg["id"]),
index_(index),
team_(0),
color_(index),
@ -872,7 +870,9 @@ config side_engine::new_config() const
// then import their new values in the config.
if (!parent_.params_.saved_game) {
// Merge the faction data to res.
res.append(flg_.current_faction());
config faction = flg_.current_faction();
faction.remove_attribute("id");
res.append(faction);
res["faction_name"] = res["name"];
}
@ -882,7 +882,6 @@ config side_engine::new_config() const
res["current_player"] = player_id_.empty() ? current_player_ : player_id_;
res["controller"] = (res["current_player"] == preferences::login()) ?
"human" : controller_names[controller_];
res["id"] = leader_id_;
if (player_id_.empty()) {
std::string description;
@ -958,8 +957,29 @@ config side_engine::new_config() const
res["allow_changes"] = !parent_.params_.saved_game && allow_changes_;
if (!parent_.params_.saved_game) {
res["type"] = flg_.current_leader();
res["gender"] = flg_.current_gender();
// Find a config where a default leader is and set a new type
// and gender values for it.
config* leader = &res;
if (flg_.default_leader_cfg() != NULL) {
BOOST_FOREACH(config& side_unit, res.child_range("unit")) {
if (*flg_.default_leader_cfg() == side_unit) {
leader = &side_unit;
if (flg_.current_leader() != (*leader)["type"]) {
// If a new leader type was selected from carryover,
// make sure that we reset the leader.
std::string leader_id = (*leader)["id"];
leader->clear();
if (!leader_id.empty()) {
(*leader)["id"] = leader_id;
}
}
break;
}
}
}
(*leader)["type"] = flg_.current_leader();
(*leader)["gender"] = flg_.current_gender();
res["team_name"] = parent_.team_names_[team_];
res["user_team_name"] = parent_.user_team_names_[team_];

View file

@ -203,7 +203,6 @@ private:
const bool allow_player_;
const bool allow_changes_;
const std::string leader_id_;
int index_;
int team_;