Some changes to ability formulas implementation

- Detect a formula by parentheses, as in GUI2 and movetype patching
- Use "self" and "other" instead of "sender" and "receiver"

Closes #1802
This commit is contained in:
Celtic Minstrel 2017-06-24 20:17:23 -04:00
parent 424ceab053
commit d2067e4768
3 changed files with 14 additions and 14 deletions

View file

@ -62,6 +62,7 @@ Version 1.13.8+dev:
* New vision_cost and jamming_cost keys in SUF
* Integer SUF keys (eg level) now accept a list of ranges
* Fix $other_unit variable in SUF not being available in nested [and] [or] [not]
* Unit ability values can now be specified with WFL
Version 1.13.8:
* Campaigns:

View file

@ -426,9 +426,8 @@ public:
T operator()(t_string const &) const { return def_; }
T operator()(const std::string& s) const
{
utils::string_view formula_prefix("formula:");
if (boost::starts_with(s, formula_prefix)) {
return formula_handler_(s.substr(formula_prefix.size()));
if(s.size() >= 2 && s[0] == '(') {
return formula_handler_(s);
}
return lexical_cast_default<T>(s, def_);
}
@ -448,16 +447,16 @@ T get_single_ability_value(const config::attribute_value& v, T def, const map_lo
return v.apply_visitor(make_get_ability_value_visitor(def, [&](const std::string& s) {
try {
wfl::map_formula_callable callable;
assert(resources::units);
auto u_itor = resources::units->find(sender_loc);
if(u_itor != resources::units->end()) {
callable.add("sender", wfl::variant(std::make_shared<wfl::unit_callable>(*u_itor)));
if(u_itor == resources::units->end()) {
return def;
}
wfl::map_formula_callable callable(std::make_shared<wfl::unit_callable>(*u_itor));
u_itor = resources::units->find(receiver_loc);
if(u_itor != resources::units->end()) {
callable.add("receiver", wfl::variant(std::make_shared<wfl::unit_callable>(*u_itor)));
callable.add("other", wfl::variant(std::make_shared<wfl::unit_callable>(*u_itor)));
}
return formula_handler(wfl::formula(s), callable);
} catch(wfl::formula_error& e) {
@ -469,7 +468,7 @@ T get_single_ability_value(const config::attribute_value& v, T def, const map_lo
}
template<typename TComp>
std::pair<int,map_location> unit_ability_list::highest_impl(const std::string& key, int def, const TComp& comp) const
std::pair<int,map_location> unit_ability_list::get_extremum(const std::string& key, int def, const TComp& comp) const
{
if ( cfgs_.empty() ) {
return std::make_pair(def, map_location());
@ -503,8 +502,8 @@ std::pair<int,map_location> unit_ability_list::highest_impl(const std::string& k
return std::make_pair(flat + stack, best_loc);
}
template std::pair<int, map_location> unit_ability_list::highest_impl<std::less<int>>(const std::string& key, int def, const std::less<int>& comp) const;
template std::pair<int, map_location> unit_ability_list::highest_impl<std::greater<int>>(const std::string& key, int def, const std::greater<int>& comp) const;
template std::pair<int, map_location> unit_ability_list::get_extremum<std::less<int>>(const std::string& key, int def, const std::less<int>& comp) const;
template std::pair<int, map_location> unit_ability_list::get_extremum<std::greater<int>>(const std::string& key, int def, const std::greater<int>& comp) const;
/*
*

View file

@ -59,15 +59,15 @@ public:
// Implemented in unit_abilities.cpp
std::pair<int, map_location> highest(const std::string& key, int def=0) const
{
return highest_impl(key, def, std::less<int>());
return get_extremum(key, def, std::less<int>());
}
std::pair<int, map_location> lowest(const std::string& key, int def=0) const
{
return highest_impl(key, def, std::greater<int>());
return get_extremum(key, def, std::greater<int>());
}
template<typename TComp>
std::pair<int, map_location> highest_impl(const std::string& key, int def, const TComp& comp) const;
std::pair<int, map_location> get_extremum(const std::string& key, int def, const TComp& comp) const;
// The following make this class usable with standard library algorithms and such
typedef std::vector<unit_ability>::iterator iterator;