add [unit_type_fix] in [scenario], [era] etc
fixes #1451 Currently advancements can be changed in two ways: 1) Via [advancefrom], this causes OOS in multiplayer 2) Via certain campaign etra defines, this has other disadvantages see The new [unit_type_fix] that is accepted in [scenario], [multiplayer], [era], [modification] , [campaign] and [ressource] changes the advancement of a unit type only for one game and has non of the disadvantages of the other two methods. We should also deprecate the other two methods.
This commit is contained in:
parent
3c172f7303
commit
e4c4ca7572
4 changed files with 68 additions and 0 deletions
|
@ -97,6 +97,7 @@ static void copy_persistent(const config& src, config& dst)
|
|||
|
||||
static const std::set<std::string> tags {
|
||||
"terrain_graphics",
|
||||
"unit_type_fix",
|
||||
"lua"};
|
||||
|
||||
for (const std::string& attr : attrs)
|
||||
|
@ -167,6 +168,9 @@ play_controller::play_controller(const config& level, saved_game& state_of_game,
|
|||
{
|
||||
copy_persistent(level, level_);
|
||||
|
||||
for(const config& unit_type_fix : level_.child_range("unit_type_fix")) {
|
||||
unit_types.apply_scenario_fix(unit_type_fix);
|
||||
}
|
||||
resources::controller = this;
|
||||
resources::persist = &persist_;
|
||||
resources::recorder = replay_.get();
|
||||
|
@ -188,6 +192,7 @@ play_controller::play_controller(const config& level, saved_game& state_of_game,
|
|||
|
||||
play_controller::~play_controller()
|
||||
{
|
||||
unit_types.remove_scenario_fixes();
|
||||
hotkey::delete_all_wml_hotkeys();
|
||||
clear_resources();
|
||||
}
|
||||
|
|
|
@ -331,6 +331,11 @@ void saved_game::load_mod(const std::string& type, const std::string& id, size_t
|
|||
for(const config& modlua : cfg.child_range("lua")) {
|
||||
this->starting_point_.add_child_at_total("lua", modlua, pos++);
|
||||
}
|
||||
|
||||
// Copy unit_type_fix
|
||||
for(const config& modlua : cfg.child_range("unit_type_fix")) {
|
||||
this->starting_point_.add_child_at_total("unit_type_fix", modlua, pos++);
|
||||
}
|
||||
|
||||
// Copy load_resource
|
||||
for(const config& load_resource : cfg.child_range("load_resource")) {
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "gui/dialogs/loading_screen.hpp"
|
||||
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/range/algorithm_ext/erase.hpp>
|
||||
|
||||
#include <locale>
|
||||
|
||||
|
@ -1423,6 +1424,59 @@ const unit_race* unit_type_data::find_race(const std::string& key) const
|
|||
return i != races_.end() ? &i->second : nullptr;
|
||||
}
|
||||
|
||||
void unit_type::apply_scenario_fix(const config& cfg)
|
||||
{
|
||||
if(auto p_setxp = cfg.get("set_experience")) {
|
||||
experience_needed_ = p_setxp->to_int();
|
||||
}
|
||||
if(auto attr = cfg.get("set_advances_to")) {
|
||||
advances_to_ = utils::split(attr->str());
|
||||
}
|
||||
if(auto attr = cfg.get("set_cost")) {
|
||||
cost_ = attr->to_int(1);
|
||||
}
|
||||
if(auto attr = cfg.get("add_advancement")) {
|
||||
for(const auto& str : utils::split(attr->str())) {
|
||||
advances_to_.push_back(str);
|
||||
}
|
||||
}
|
||||
if(auto attr = cfg.get("remove_advancement")) {
|
||||
for(const auto& str : utils::split(attr->str())) {
|
||||
boost::remove_erase(advances_to_, str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void unit_type_data::apply_scenario_fix(const config& cfg)
|
||||
{
|
||||
unit_type_map::iterator itor = types_.find(cfg["type"].str());
|
||||
// This might happen if units of another era are requested (for example for savegames)
|
||||
if(itor != types_.end()) {
|
||||
itor->second.apply_scenario_fix(cfg);
|
||||
}
|
||||
else {
|
||||
// should we give an error message?
|
||||
}
|
||||
}
|
||||
|
||||
void unit_type::remove_scenario_fixes()
|
||||
{
|
||||
advances_to_.clear();
|
||||
const std::string& advances_to_val = cfg_["advances_to"];
|
||||
if(advances_to_val != "null" && !advances_to_val.empty()) {
|
||||
advances_to_ = utils::split(advances_to_val);
|
||||
}
|
||||
experience_needed_ = cfg_["experience"].to_int(500);
|
||||
cost_ = cfg_["cost"].to_int(1);
|
||||
}
|
||||
|
||||
void unit_type_data::remove_scenario_fixes()
|
||||
{
|
||||
for(auto& pair : types_) {
|
||||
pair.second.remove_scenario_fixes();
|
||||
}
|
||||
}
|
||||
|
||||
void unit_type::check_id(std::string& id)
|
||||
{
|
||||
assert(!id.empty());
|
||||
|
|
|
@ -275,6 +275,8 @@ public:
|
|||
/// Attention: Filters in resistance-abilities will be ignored.
|
||||
int resistance_against(const std::string& damage_name, bool attacker) const;
|
||||
|
||||
void apply_scenario_fix(const config& cfg);
|
||||
void remove_scenario_fixes();
|
||||
private:
|
||||
/// Generates (and returns) a trimmed config suitable for use with units.
|
||||
const config & build_unit_cfg() const;
|
||||
|
@ -375,6 +377,8 @@ public:
|
|||
/** Checks if the [hide_help] tag contains these IDs. */
|
||||
bool hide_help(const std::string &type_id, const std::string &race_id) const;
|
||||
|
||||
void apply_scenario_fix(const config& cfg);
|
||||
void remove_scenario_fixes();
|
||||
private:
|
||||
/** Parses the [hide_help] tag. */
|
||||
void read_hide_help(const config &cfg);
|
||||
|
|
Loading…
Add table
Reference in a new issue