Skip to content

Commit

Permalink
Merge pull request #477 from CelticMinstrel/movetype
Browse files Browse the repository at this point in the history
Movetype patching
  • Loading branch information
irydacea committed Sep 5, 2015
2 parents c6512ab + e6d5562 commit df087a9
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 0 deletions.
1 change: 1 addition & 0 deletions changelog
Expand Up @@ -75,6 +75,7 @@ Version 1.13.1+dev:
* apply_to=attack - add set_ versions of all existing increase_ keys
* apply_to=attack - add increase_movement_used and set_movement_used to change the
number of movement points the attack consumes
* Ability to patch movetypes to account for custom terrains or damage types
* Editor:
* Added Category field and color sliders to the Edit Label panel.
* Miscellaneous and bug fixes:
Expand Down
89 changes: 89 additions & 0 deletions src/unit_types.cpp
Expand Up @@ -31,9 +31,13 @@
#include "unit.hpp"
#include "unit_abilities.hpp"
#include "unit_animation.hpp"
#include "util.hpp"

#include "gui/auxiliary/formula.hpp"

#include <boost/foreach.hpp>
#include <boost/static_assert.hpp>
#include <boost/regex.hpp>

static lg::log_domain log_config("config");
#define ERR_CF LOG_STREAM(err, log_config)
Expand Down Expand Up @@ -997,6 +1001,24 @@ namespace { // Helpers for set_config()
// Restore the variations.
ut_cfg.splice_children(variations, "variation");
}

const boost::regex fai_identifier("[a-zA-Z_]+");

template<typename MoveT>
void patch_movetype(MoveT& mt, const std::string& new_key, const std::string& formula_str, int default_val) {
config temp_cfg, original_cfg;
gui2::tformula<int> formula(formula_str);
game_logic::map_formula_callable original;
mt.write(original_cfg);
boost::sregex_iterator m(formula_str.begin(), formula_str.end(), fai_identifier);
BOOST_FOREACH(const boost::sregex_iterator::value_type& p, std::make_pair(m, boost::sregex_iterator())) {
const std::string var_name = p.str();
variant val(original_cfg[var_name].to_int(default_val));
original.add(var_name, val);
}
temp_cfg[new_key] = formula(original);
mt.merge(temp_cfg, true);
}
}// unnamed namespace

/**
Expand All @@ -1023,6 +1045,73 @@ void unit_type_data::set_config(config &cfg)
races_.insert(std::pair<std::string,unit_race>(race.id(),race));
loadscreen::increment_progress();
}

// Movetype resistance patching
BOOST_FOREACH(const config &r, cfg.child_range("resistance_defaults"))
{
const std::string& dmg_type = r["id"];
config temp_cfg;
BOOST_FOREACH(const config::attribute &attr, r.attribute_range()) {
const std::string &mt = attr.first;
if (mt == "id" || mt == "default" || movement_types_.find(mt) == movement_types_.end()) {
continue;
}
patch_movetype(movement_types_[mt].get_resistances(), dmg_type, attr.second, 100);
}
if (r.has_attribute("default")) {
BOOST_FOREACH(movement_type_map::value_type &mt, movement_types_) {
if (r.has_attribute(mt.first)) {
continue;
}
patch_movetype(mt.second.get_resistances(), dmg_type, r["default"], 100);
}
}
}

// Movetype move/defend patching
BOOST_FOREACH(const config &terrain, cfg.child_range("terrain_defaults"))
{
const std::string& ter_type = terrain["id"];
config temp_cfg;
static const std::string terrain_info_tags[] = {"movement", "vision", "jamming", "defense"};
BOOST_FOREACH(const std::string &tag, terrain_info_tags) {
if (!terrain.has_child(tag)) {
continue;
}
const config& info = terrain.child(tag);
BOOST_FOREACH(const config::attribute &attr, info.attribute_range()) {
const std::string &mt = attr.first;
if (mt == "default" || movement_types_.find(mt) == movement_types_.end()) {
continue;
}
if (tag == "defense") {
patch_movetype(movement_types_[mt].get_defense(), ter_type, attr.second, 100);
} else if (tag == "vision") {
patch_movetype(movement_types_[mt].get_vision(), ter_type, attr.second, 99);
} else if (tag == "movement") {
patch_movetype(movement_types_[mt].get_movement(), ter_type, attr.second, 99);
} else if (tag == "jamming") {
patch_movetype(movement_types_[mt].get_jamming(), ter_type, attr.second, 99);
}
}
if (info.has_attribute("default")) {
BOOST_FOREACH(movement_type_map::value_type &mt, movement_types_) {
if (info.has_attribute(mt.first)) {
continue;
}
if (tag == "defense") {
patch_movetype(mt.second.get_defense(), ter_type, info["default"], 100);
} else if (tag == "vision") {
patch_movetype(mt.second.get_vision(), ter_type, info["default"], 99);
} else if (tag == "movement") {
patch_movetype(mt.second.get_movement(), ter_type, info["default"], 99);
} else if (tag == "jamming") {
patch_movetype(mt.second.get_jamming(), ter_type, info["default"], 99);
}
}
}
}
}

// Apply base units.
BOOST_FOREACH(config &ut, cfg.child_range("unit_type"))
Expand Down

0 comments on commit df087a9

Please sign in to comment.