add [has_ally],[has_enemy] tags for standard side filter

Unlike [allied_with] and [enemy_of], these will match if only if
there is *any* ally or enemy matching the filter. The other versions
of the tag match only if all sides matching the filter are
allied / opposed.

This commit also adds a unit test that checks that it works as
expected.
This commit is contained in:
Chris Beck 2014-07-06 23:48:13 -04:00
parent d4235f0589
commit 5a64d43fae
4 changed files with 152 additions and 0 deletions

View file

@ -0,0 +1,116 @@
# This test checks that the [has_ally] tag is working as expected.
#define TEST_HAS_ALLY_SCEN ID EVENTS
[test]
name = "Unit Test {ID}"
map_data = "{test/maps/move_skip_sighted.map}"
turns = 3
id = {ID}
random_start_time = no
{DAWN}
[side]
side=1
controller=human
name = "Alice"
type = Elvish Archer
id=alice
fog=no
team_name=West
[/side]
[side]
side=2
controller=human
name = "Bob"
type = Orcish Grunt
id=bob
fog=no
team_name=East
[/side]
[side]
side=3
controller=human
name = "Dave"
type = Dwarvish Fighter
id=dave
fog=no
team_name=East
[/side]
[side]
side=4
controller=human
name= "Charlie"
type = Chocobone
id=charlie
fog=no
team_name=West
[/side]
{EVENTS}
[/test]
#enddef
{TEST_HAS_ALLY_SCEN "has_ally" (
[event]
name=start
{ASSERT ([have_unit]
id=dave
[filter_side]
[has_ally]
[has_unit]
id=bob
[/has_unit]
[/has_ally]
[/filter_side]
[/have_unit]
)}
{ASSERT ([have_unit]
id=dave
[filter_side]
[has_enemy]
[has_unit]
id=alice
[/has_unit]
[/has_enemy]
[/filter_side]
[/have_unit]
)}
{ASSERT ([have_unit]
id=dave
[filter_side]
[not]
[has_ally]
[has_unit]
id=steve
[/has_unit]
[/has_ally]
[/not]
[/filter_side]
[/have_unit]
)}
{ASSERT ([have_unit]
id=dave
[filter_side]
[has_enemy]
side=1,4
[/has_enemy]
[/filter_side]
[/have_unit]
)}
{ASSERT ([not]
[have_unit]
id=dave
[filter_side]
[has_ally]
[has_unit]
id=charlie
[/has_unit]
[/has_ally]
[/filter_side]
[/have_unit]
[/not]
)}
{RETURN ([true][/true])}
[/event]
)}

View file

@ -188,6 +188,39 @@ bool side_filter::match_internal(const team &t) const
}
}
const vconfig& has_enemy = cfg_.child("has_enemy");
if(!has_enemy.null()) {
if (!has_enemy_filter_)
has_enemy_filter_.reset(new side_filter(has_enemy, fc_));
const std::vector<int>& teams = has_enemy_filter_->get_teams();
bool found = false;
BOOST_FOREACH(const int side, teams) {
if((fc_->get_disp_context().teams())[side - 1].is_enemy(t.side()))
{
found = true;
break;
}
}
if (!found) return false;
}
const vconfig& has_ally = cfg_.child("has_ally");
if(!has_ally.null()) {
if (!has_ally_filter_)
has_ally_filter_.reset(new side_filter(has_ally, fc_));
const std::vector<int>& teams = has_ally_filter_->get_teams();
bool found = false;
BOOST_FOREACH(const int side, teams) {
if(!(fc_->get_disp_context().teams())[side - 1].is_enemy(t.side()))
{
found = true;
break;
}
}
if (!found) return false;
}
const config::attribute_value cfg_controller = cfg_["controller"];
if (!cfg_controller.blank())
{

View file

@ -65,6 +65,8 @@ private:
mutable boost::scoped_ptr<unit_filter> ufilter_;
mutable boost::scoped_ptr<side_filter> allied_filter_;
mutable boost::scoped_ptr<side_filter> enemy_filter_;
mutable boost::scoped_ptr<side_filter> has_ally_filter_;
mutable boost::scoped_ptr<side_filter> has_enemy_filter_;
};
#endif

View file

@ -79,6 +79,7 @@
0 event_handlers_in_events_6
0 event_handlers_in_events_7
0 event_handlers_in_events_8
0 has_ally
#
# Pathfinding
#