Push [and],[or],[not] tags from event weapon filters to all weapon filters.
This commit is contained in:
parent
9a8140ca34
commit
b45a6fa04f
3 changed files with 44 additions and 42 deletions
|
@ -33,6 +33,8 @@ Version 1.11.0+svn:
|
|||
delayed shroud updates (which is still a major caveat).
|
||||
* Added [effect] apply_to=overlay
|
||||
* Added [terrain_type] max_light= and min_light=.
|
||||
* Standardize weapon filters, supporting special=, [and], [or], and [not]
|
||||
wherever weapons can be filtered.
|
||||
* Miscellaneous and bug fixes:
|
||||
* Fix invalid memory access crash resulting from deleting all saved games
|
||||
in the Load Game dialog
|
||||
|
|
|
@ -3365,34 +3365,7 @@ namespace game_events {
|
|||
return false;
|
||||
}
|
||||
const attack_type attack(cfg);
|
||||
bool matches = attack.matches_filter(filter.get_parsed_config());
|
||||
|
||||
// Handle [and], [or], and [not] with in-order precedence
|
||||
vconfig::all_children_iterator cond_i = filter.ordered_begin();
|
||||
vconfig::all_children_iterator cond_end = filter.ordered_end();
|
||||
while(cond_i != cond_end)
|
||||
{
|
||||
const std::string& cond_name = cond_i.get_key();
|
||||
const vconfig& cond_filter = cond_i.get_child();
|
||||
|
||||
// Handle [and]
|
||||
if(cond_name == "and")
|
||||
{
|
||||
matches = matches && matches_special_filter(cfg, cond_filter);
|
||||
}
|
||||
// Handle [or]
|
||||
else if(cond_name == "or")
|
||||
{
|
||||
matches = matches || matches_special_filter(cfg, cond_filter);
|
||||
}
|
||||
// Handle [not]
|
||||
else if(cond_name == "not")
|
||||
{
|
||||
matches = matches && !matches_special_filter(cfg, cond_filter);
|
||||
}
|
||||
++cond_i;
|
||||
}
|
||||
return matches;
|
||||
return attack.matches_filter(filter.get_parsed_config());
|
||||
}
|
||||
|
||||
bool unit_matches_filter(const unit &u, const vconfig& filter)
|
||||
|
|
|
@ -91,11 +91,10 @@ std::string attack_type::accuracy_parry_description() const
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not *this matches the given @a filter.
|
||||
* If @a ignore_special is set to true, then the special= attribute of the
|
||||
* filter is ignored.
|
||||
* Returns whether or not *this matches the given @a filter, ignoring the
|
||||
* complexities introduced by [and], [or], and [not].
|
||||
*/
|
||||
bool attack_type::matches_filter(const config& filter) const
|
||||
static bool matches_simple_filter(const attack_type & attack, const config & filter)
|
||||
{
|
||||
const std::vector<std::string>& filter_range = utils::split(filter["range"]);
|
||||
const std::string& filter_damage = filter["damage"];
|
||||
|
@ -103,25 +102,53 @@ bool attack_type::matches_filter(const config& filter) const
|
|||
const std::vector<std::string> filter_type = utils::split(filter["type"]);
|
||||
const std::string filter_special = filter["special"];
|
||||
|
||||
if(filter_range.empty() == false && std::find(filter_range.begin(),filter_range.end(),range()) == filter_range.end())
|
||||
return false;
|
||||
|
||||
if(filter_damage.empty() == false && !in_ranges(damage(), utils::parse_ranges(filter_damage))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(filter_name.empty() == false && std::find(filter_name.begin(),filter_name.end(),id()) == filter_name.end())
|
||||
if ( !filter_range.empty() && std::find(filter_range.begin(), filter_range.end(), attack.range()) == filter_range.end() )
|
||||
return false;
|
||||
|
||||
if(filter_type.empty() == false && std::find(filter_type.begin(),filter_type.end(),type()) == filter_type.end())
|
||||
if ( !filter_damage.empty() && !in_ranges(attack.damage(), utils::parse_ranges(filter_damage)) )
|
||||
return false;
|
||||
|
||||
if ( !filter_special.empty() && !get_special_bool(filter_special, true) )
|
||||
if ( !filter_name.empty() && std::find(filter_name.begin(), filter_name.end(), attack.id()) == filter_name.end() )
|
||||
return false;
|
||||
|
||||
if ( !filter_type.empty() && std::find(filter_type.begin(), filter_type.end(), attack.type()) == filter_type.end() )
|
||||
return false;
|
||||
|
||||
if ( !filter_special.empty() && !attack.get_special_bool(filter_special, true) )
|
||||
return false;
|
||||
|
||||
// Passed all tests.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not *this matches the given @a filter.
|
||||
*/
|
||||
bool attack_type::matches_filter(const config& filter) const
|
||||
{
|
||||
// Handle the basic filter.
|
||||
bool matches = matches_simple_filter(*this, filter);
|
||||
|
||||
// Handle [and], [or], and [not] with in-order precedence
|
||||
BOOST_FOREACH( const config::any_child &condition, filter.all_children_range() )
|
||||
{
|
||||
// Handle [and]
|
||||
if ( condition.key == "and" )
|
||||
matches = matches && matches_filter(condition.cfg);
|
||||
|
||||
// Handle [or]
|
||||
else if ( condition.key == "or" )
|
||||
matches = matches || matches_filter(condition.cfg);
|
||||
|
||||
// Handle [not]
|
||||
else if ( condition.key == "not" )
|
||||
matches = matches && !matches_filter(condition.cfg);
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Modifies *this using the specifications in @a cfg, but only if *this matches
|
||||
* @a cfg viewed as a filter.
|
||||
|
|
Loading…
Add table
Reference in a new issue