diff --git a/data/test/scenarios/filter_vision.cfg b/data/test/scenarios/filter_vision.cfg new file mode 100644 index 000000000000..49acb0f0d8c4 --- /dev/null +++ b/data/test/scenarios/filter_vision.cfg @@ -0,0 +1,157 @@ +# This test scenario checks unit filter [filter_vision], +# and terrain_filter [filter_vision]. It tests what happens +# when there is a single, there are multiple, or there are +# no matches to the standard side filter contained. + +#define TEST_FILTER_VISION_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=yes + team_name=West + [/side] + [side] + side=2 + controller=human + name = "Bob" + type = Orcish Grunt + id=bob + fog=yes + team_name=East + [/side] + [side] + side=3 + controller=human + name = "Dave" + type = Dwarvish Fighter + id=dave + fog=yes + team_name=East + [/side] + [side] + side=4 + controller=human + name = "Charlie" + type = Chocobone + id=charlie + fog=yes + team_name=West + [/side] + + {EVENTS} + [/test] +#enddef + +#define chat_if X +{VARIABLE_OP chat_ctr add 1} + +[if] + {X} + [then] + [chat] + message="$chat_ctr" ": yes" + [/chat] + [/then] + [else] + [chat] + message="$chat_ctr" ": no" + [/chat] + [/else] +[/if] +#enddef + +#define test_vision_chat X Y +{chat_if ([have_unit] + {X} + [filter_vision] + {Y} + [/filter_vision] + [/have_unit] + )} +{chat_if ([have_unit] + {X} + [filter_location] + [filter_vision] + {Y} + [/filter_vision] + [/filter_location] + [/have_unit] + )} +[delay] + time=500 +[/delay] +#enddef + +#define assert_test_true X Y +{ASSERT ([have_unit] + {X} + [filter_vision] + {Y} + [/filter_vision] + [/have_unit] + )} +{ASSERT ([have_unit] + {X} + [filter_location] + [filter_vision] + {Y} + [/filter_vision] + [/filter_location] + [/have_unit] + )} +#enddef + +#define assert_test_false X Y +{ASSERT ([not] + [have_unit] + {X} + [filter_vision] + {Y} + [/filter_vision] + [/have_unit] + [/not] + )} +{ASSERT ([not] + [have_unit] + {X} + [filter_location] + [filter_vision] + {Y} + [/filter_vision] + [/filter_location] + [/have_unit] + [/not] + )} +#enddef + +{TEST_FILTER_VISION_SCEN "filter_vision" ( + [event] + name=start + {VARIABLE chat_ctr 0} + + {assert_test_true () (side=1,2,3,4)} + {assert_test_true (side=2) (side=1,2,3,4)} + {assert_test_true (side=4) (side=1,2,3,4)} + {assert_test_true (side=1) (side=4)} + {assert_test_true (side=2) (side=4)} + {assert_test_true (side=3) (side=4)} + {assert_test_true (side=4) (side=1)} + {assert_test_true (side=4) (side=3)} + {assert_test_false (side=4) (side=2)} + {assert_test_false () (side=5)} + + {RETURN ([true][/true])} + [/event] +)} diff --git a/src/terrain_filter.cpp b/src/terrain_filter.cpp index 4fca2af732ff..216c9b651da0 100644 --- a/src/terrain_filter.cpp +++ b/src/terrain_filter.cpp @@ -183,13 +183,16 @@ bool terrain_filter::match_internal(const map_location& loc, const bool ignore_x side_filter ssf(*i, fc_); std::vector sides = ssf.get_teams(); + bool found = false; BOOST_FOREACH(const int side, sides) { const team &viewing_team = fc_->get_disp_context().teams().at(side - 1); bool viewer_sees = respect_fog ? !viewing_team.fogged(loc) : !viewing_team.shrouded(loc); - if (visible != viewer_sees) { - return false; + if (visible == viewer_sees) { + found = true; + break; } } + if (!found) {return false;} } } diff --git a/src/unit_filter.cpp b/src/unit_filter.cpp index 28ad001fcc59..98e46b1e9588 100644 --- a/src/unit_filter.cpp +++ b/src/unit_filter.cpp @@ -531,16 +531,18 @@ bool basic_unit_filter_impl::internal_matches_filter(const unit & u, const map_l assert(vision_filters_viewers_lists_.size() == vision_filters_visible_attr_.size()); for (size_t i = 0; i < vision_filters_viewers_lists_.size(); i++) { const std::set & viewers = vision_filters_viewers_lists_[i]; - if (viewers.empty()) { - return false; - } - std::set::const_iterator viewer, viewer_end = viewers.end(); - for (viewer = viewers.begin(); viewer != viewer_end; ++viewer) { - bool fogged = fc_.get_disp_context().teams()[*viewer - 1].fogged(loc); + + bool found = false; + BOOST_FOREACH (const int viewer, viewers) { + bool fogged = fc_.get_disp_context().teams()[viewer - 1].fogged(loc); bool hiding = u.invisible(loc/*, false(?) */); bool unit_hidden = fogged || hiding; - if (vision_filters_visible_attr_[i] == unit_hidden) return false; + if (vision_filters_visible_attr_[i] != unit_hidden) { + found = true; + break; + } } + if (!found) {return false;} } assert(filter_adj_filters_.size() == filter_adj_is_enemy_.size()); diff --git a/wml_test_schedule b/wml_test_schedule index 4676a25fd16f..d277aa2ac3cb 100644 --- a/wml_test_schedule +++ b/wml_test_schedule @@ -79,6 +79,7 @@ 0 event_handlers_in_events_6 0 event_handlers_in_events_7 0 event_handlers_in_events_8 +0 filter_vision # # Pathfinding #