The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
filter.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2016 by David White <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #define GETTEXT_DOMAIN "wesnoth-lib"
16 
17 #include "global.hpp"
18 
19 #include "config.hpp"
20 #include "display_context.hpp"
21 #include "filter_context.hpp"
22 #include "game_board.hpp"
23 #include "game_data.hpp"
24 #include "log.hpp"
25 #include "map/map.hpp"
26 #include "side_filter.hpp"
27 #include "team.hpp"
28 #include "terrain/filter.hpp"
29 #include "tod_manager.hpp"
30 #include "units/unit.hpp"
31 #include "units/filter.hpp"
32 #include "variable.hpp"
33 #include "formula/callable_objects.hpp"
34 #include "formula/formula.hpp"
36 
37 #include <boost/range/adaptor/transformed.hpp>
38 
39 static lg::log_domain log_engine("engine");
40 #define ERR_NG LOG_STREAM(err, log_engine)
41 #define WRN_NG LOG_STREAM(warn, log_engine)
42 
44 {
45 }
46 
47 #ifdef _MSC_VER
48 // This is a workaround for a VC bug; this constructor is never called
49 // and so we don't care about the warnings this quick fix generates
50 #pragma warning(push)
51 #pragma warning(disable:4413)
53  cfg_(vconfig::unconstructed_vconfig()),
54  fc_(nullptr),
55  cache_(),
56  max_loop_(),
57  flat_()
58 {
59  assert(false);
60 }
61 #pragma warning(pop)
62 #endif
63 
64 
66  const bool flat_tod, const size_t max_loop) :
67  cfg_(cfg),
68  fc_(fc),
69  cache_(),
70  max_loop_(max_loop),
71  flat_(flat_tod)
72 {
73 }
74 
76  cfg_(cfg),
77  fc_(original.fc_),
78  cache_(),
79  max_loop_(original.max_loop_),
80  flat_(original.flat_)
81 {
82 }
83 
85  xy_pred(), // We should construct this too, since it has no datamembers
86  // use the default constructor.
87  cfg_(other.cfg_),
88  fc_(other.fc_),
89  cache_(),
90  max_loop_(other.max_loop_),
91  flat_(other.flat_)
92 {
93 }
94 
96 {
97  // Use copy constructor to make sure we are coherent
98  if (this != &other) {
99  this->~terrain_filter();
100  new (this) terrain_filter(other) ;
101  }
102  return *this ;
103 }
104 
106  parsed_terrain(nullptr),
107  adjacent_matches(nullptr),
108  adjacent_match_cache(),
109  ufilter_()
110 {}
111 
112 namespace {
113  struct cfg_isor {
114  bool operator() (std::pair<const std::string,const vconfig> val) {
115  return val.first == "or";
116  }
117  };
118 } //end anonymous namespace
119 
120 bool terrain_filter::match_internal(const map_location& loc, const bool ignore_xy) const
121 {
122  std::string lua_function = cfg_["lua_function"];
123  if (!lua_function.empty() && fc_->get_lua_kernel()) {
124  if (!fc_->get_lua_kernel()->run_filter(lua_function.c_str(), loc)) {
125  return false;
126  }
127  }
128 
129  //Filter Areas
130  if (cfg_.has_attribute("area") &&
131  fc_->get_tod_man().get_area_by_id(cfg_["area"]).count(loc) == 0)
132  return false;
133 
134  if(cfg_.has_attribute("terrain")) {
135  if(cache_.parsed_terrain == nullptr) {
137  }
141  return false;
142  }
143  }
144  }
145 
146  //Allow filtering on location ranges
147  if (!ignore_xy) {
148  if (!loc.matches_range(cfg_["x"], cfg_["y"])) {
149  return false;
150  }
151  //allow filtering by searching a stored variable of locations
152  if (cfg_.has_attribute("find_in")) {
153  if (const game_data * gd = fc_->get_game_data()) {
154  try
155  {
156  variable_access_const vi = gd->get_variable_access_read(cfg_["find_in"]);
157 
158  bool found = false;
159  for (const config &cfg : vi.as_array()) {
160  if (map_location(cfg, nullptr) == loc) {
161  found = true;
162  break;
163  }
164  }
165  if (!found) return false;
166  }
167  catch (const invalid_variablename_exception&)
168  {
169  return false;
170  }
171  }
172  }
173  if (cfg_.has_attribute("location_id")) {
174  if (loc != fc_->get_disp_context().map().special_location(cfg_["location_id"])) {
175  return false;
176  }
177  }
178  }
179  //Allow filtering on unit
180  if(cfg_.has_child("filter")) {
182  if (!u.valid())
183  return false;
184  if (!cache_.ufilter_)
185  cache_.ufilter_.reset(new unit_filter(vconfig(cfg_.child("filter")), fc_, flat_));
186  if (!cache_.ufilter_->matches(*u, loc))
187  return false;
188  }
189 
190  // Allow filtering on visibility to a side
191  if (cfg_.has_child("filter_vision")) {
192  const vconfig::child_list& vis_filt = cfg_.get_children("filter_vision");
193  vconfig::child_list::const_iterator i, i_end = vis_filt.end();
194  for (i = vis_filt.begin(); i != i_end; ++i) {
195  bool visible = (*i)["visible"].to_bool(true);
196  bool respect_fog = (*i)["respect_fog"].to_bool(true);
197 
198  side_filter ssf(*i, fc_);
199  std::vector<int> sides = ssf.get_teams();
200 
201  bool found = false;
202  for (const int side : sides) {
203  const team &viewing_team = fc_->get_disp_context().teams().at(side - 1);
204  bool viewer_sees = respect_fog ? !viewing_team.fogged(loc) : !viewing_team.shrouded(loc);
205  if (visible == viewer_sees) {
206  found = true;
207  break;
208  }
209  }
210  if (!found) {return false;}
211  }
212  }
213 
214  //Allow filtering on adjacent locations
215  if(cfg_.has_child("filter_adjacent_location")) {
216  map_location adjacent[6];
217  get_adjacent_tiles(loc, adjacent);
218  const vconfig::child_list& adj_cfgs = cfg_.get_children("filter_adjacent_location");
219  vconfig::child_list::const_iterator i, i_end, i_begin = adj_cfgs.begin();
220  for (i = i_begin, i_end = adj_cfgs.end(); i != i_end; ++i) {
221  int match_count = 0;
222  vconfig::child_list::difference_type index = i - i_begin;
223  std::vector<map_location::DIRECTION> dirs = (*i).has_attribute("adjacent")
225  std::vector<map_location::DIRECTION>::const_iterator j, j_end = dirs.end();
226  for (j = dirs.begin(); j != j_end; ++j) {
227  map_location &adj = adjacent[*j];
228  if (fc_->get_disp_context().map().on_board(adj)) {
229  if(cache_.adjacent_matches == nullptr) {
230  while(index >= std::distance(cache_.adjacent_match_cache.begin(), cache_.adjacent_match_cache.end())) {
231  const vconfig& adj_cfg = adj_cfgs[cache_.adjacent_match_cache.size()];
232  std::pair<terrain_filter, std::map<map_location,bool> > amc_pair(
233  terrain_filter(adj_cfg, *this),
234  std::map<map_location,bool>());
235  cache_.adjacent_match_cache.push_back(amc_pair);
236  }
237  terrain_filter &amc_filter = cache_.adjacent_match_cache[index].first;
238  std::map<map_location,bool> &amc = cache_.adjacent_match_cache[index].second;
239  std::map<map_location,bool>::iterator lookup = amc.find(adj);
240  if(lookup == amc.end()) {
241  if(amc_filter(adj)) {
242  amc[adj] = true;
243  ++match_count;
244  } else {
245  amc[adj] = false;
246  }
247  } else if(lookup->second) {
248  ++match_count;
249  }
250  } else {
251  assert(index < std::distance(cache_.adjacent_matches->begin(), cache_.adjacent_matches->end()));
252  std::set<map_location> &amc = (*cache_.adjacent_matches)[index];
253  if(amc.find(adj) != amc.end()) {
254  ++match_count;
255  }
256  }
257  }
258  }
259  static std::vector<std::pair<int,int> > default_counts = utils::parse_ranges("1-6");
260  std::vector<std::pair<int,int> > counts = (*i).has_attribute("count")
261  ? utils::parse_ranges((*i)["count"]) : default_counts;
262  if(!in_ranges(match_count, counts)) {
263  return false;
264  }
265  }
266  }
267 
268  const t_string& t_tod_type = cfg_["time_of_day"];
269  const t_string& t_tod_id = cfg_["time_of_day_id"];
270  const std::string& tod_type = t_tod_type;
271  const std::string& tod_id = t_tod_id;
272  if(!tod_type.empty() || !tod_id.empty()) {
273  // creating a time_of_day is expensive, only do it if we will use it
274  time_of_day tod;
275 
276  if(flat_) {
277  tod = fc_->get_tod_man().get_time_of_day(loc);
278  } else {
280  }
281 
282  if(!tod_type.empty()) {
283  const std::vector<std::string>& vals = utils::split(tod_type);
284  if(tod.lawful_bonus<0) {
285  if(std::find(vals.begin(),vals.end(),unit_type::ALIGNMENT::enum_to_string(unit_type::ALIGNMENT::CHAOTIC)) == vals.end()) {
286  return false;
287  }
288  } else if(tod.lawful_bonus>0) {
289  if(std::find(vals.begin(),vals.end(),unit_type::ALIGNMENT::enum_to_string(unit_type::ALIGNMENT::LAWFUL)) == vals.end()) {
290  return false;
291  }
292  } else if(std::find(vals.begin(),vals.end(),unit_type::ALIGNMENT::enum_to_string(unit_type::ALIGNMENT::NEUTRAL)) == vals.end()) {
293  return false;
294  }
295  }
296 
297  if(!tod_id.empty()) {
298  if(tod_id != tod.id) {
299  if(std::find(tod_id.begin(),tod_id.end(),',') != tod_id.end() &&
300  std::search(tod_id.begin(),tod_id.end(),
301  tod.id.begin(),tod.id.end()) != tod_id.end()) {
302  const std::vector<std::string>& vals = utils::split(tod_id);
303  if(std::find(vals.begin(),vals.end(),tod.id) == vals.end()) {
304  return false;
305  }
306  } else {
307  return false;
308  }
309  }
310  }
311  }
312 
313  //allow filtering on owner (for villages)
314  const config::attribute_value &owner_side = cfg_["owner_side"];
315  const vconfig& filter_owner = cfg_.child("filter_owner");
316  if(!filter_owner.null()) {
317  if(!owner_side.empty()) {
318  WRN_NG << "duplicate side information in a SLF, ignoring inline owner_side=" << std::endl;
319  }
320  if(!fc_->get_disp_context().map().is_village(loc))
321  return false;
322  side_filter ssf(filter_owner, fc_);
323  const std::vector<int>& sides = ssf.get_teams();
324  bool found = false;
325  if(sides.empty() && fc_->get_disp_context().village_owner(loc) == -1)
326  found = true;
327  for(const int side : sides) {
328  if(fc_->get_disp_context().teams().at(side - 1).owns_village(loc)) {
329  found = true;
330  break;
331  }
332  }
333  if(!found)
334  return false;
335  }
336  else if(!owner_side.empty()) {
337  const int side_index = owner_side.to_int(0) - 1;
338  if(fc_->get_disp_context().village_owner(loc) != side_index) {
339  return false;
340  }
341  }
342 
343  if(cfg_.has_attribute("formula")) {
344  try {
345  const gamemap& map = fc_->get_disp_context().map();
347  const terrain_type& ter = map.tdata()->get_terrain_info(t);
348  const terrain_callable callable(ter,loc);
349  const game_logic::formula form(cfg_["formula"]);
350  if(!form.evaluate(callable).as_bool()) {
351  return false;
352  }
353  return true;
354  } catch(game_logic::formula_error& e) {
355  lg::wml_error() << "Formula error in location filter: " << e.type << " at " << e.filename << ':' << e.line << ")\n";
356  // Formulae with syntax errors match nothing
357  return false;
358  }
359  }
360 
361  return true;
362 }
363 
364 bool terrain_filter::match(const map_location& loc) const
365 {
366  if(cfg_["x"] == "recall" && cfg_["y"] == "recall") {
367  return !fc_->get_disp_context().map().on_board(loc);
368  }
369  std::set<map_location> hexes;
370  std::vector<map_location> loc_vec(1, loc);
371 
372  //handle radius
373  size_t radius = cfg_["radius"].to_size_t(0);
374  if(radius > max_loop_) {
375  ERR_NG << "terrain_filter: radius greater than " << max_loop_
376  << ", restricting\n";
377  radius = max_loop_;
378  }
379  if ( radius == 0 )
380  hexes.insert(loc_vec.begin(), loc_vec.end());
381  else if ( cfg_.has_child("filter_radius") ) {
382  terrain_filter r_filter(cfg_.child("filter_radius"), *this);
383  get_tiles_radius(fc_->get_disp_context().map(), loc_vec, radius, hexes, false, r_filter);
384  } else {
385  get_tiles_radius(fc_->get_disp_context().map(), loc_vec, radius, hexes);
386  }
387 
388  size_t loop_count = 0;
389  std::set<map_location>::const_iterator i;
390  for(i = hexes.begin(); i != hexes.end(); ++i) {
391  bool matches = match_internal(*i, false);
392 
393  //handle [and], [or], and [not] with in-order precedence
396  while(cond != cond_end)
397  {
398  const std::string& cond_name = cond.get_key();
399  const vconfig& cond_cfg = cond.get_child();
400 
401  //handle [and]
402  if(cond_name == "and")
403  {
404  matches = matches && terrain_filter(cond_cfg, *this)(*i);
405  }
406  //handle [or]
407  else if(cond_name == "or")
408  {
409  matches = matches || terrain_filter(cond_cfg, *this)(*i);
410  }
411  //handle [not]
412  else if(cond_name == "not")
413  {
414  matches = matches && !terrain_filter(cond_cfg, *this)(*i);
415  }
416  ++cond;
417  }
418  if(matches) {
419  return true;
420  }
421  if(++loop_count > max_loop_) {
422  std::set<map_location>::const_iterator temp = i;
423  if(++temp != hexes.end()) {
424  ERR_NG << "terrain_filter: loop count greater than " << max_loop_
425  << ", aborting\n";
426  break;
427  }
428  }
429  }
430  return false;
431 }
432 //using a class to be able to firen it in terrain_filter
434 {
435 public:
436  using location_set = std::set<map_location>;
437  struct tno_start_set_yet {};
438  struct tno_filter
439  {
440  bool operator()(const map_location&) const { return true; }
441  };
442 
443  template<typename T, typename F1, typename F2, typename F3>
444  static void filter_final(T&& src, location_set& dest, const terrain_filter&, const F1& f1, const F2& f2, const F3& f3)
445  {
446  for (const map_location &loc : src) {
447  if (f1(loc) && f2(loc) && f3(loc)) {
448  dest.insert(loc);
449  }
450  }
451  }
452 
453  template<typename T, typename F1, typename F2>
454  static void filter_special_loc(T&& src, location_set& dest, const terrain_filter& filter, const F1& f1, const F2& f2)
455  {
456  if (filter.cfg_.has_attribute("location_id")) {
457  map_location loc2 = filter.fc_->get_disp_context().map().special_location(filter.cfg_["location_id"]);
458  filter_final(src, dest, filter, f1, f2, [loc2](const map_location& loc) { return loc == loc2; });
459  }
460  else {
461  filter_final(src, dest, filter, f1, f2, tno_filter());
462  }
463  }
464 
465  template<typename T, typename F1>
466  static void filter_area(T&& src, location_set& dest, const terrain_filter& filter, const F1& f1)
467  {
468  if (filter.cfg_.has_attribute("area")) {
469  const std::set<map_location>& area = filter.fc_->get_tod_man().get_area_by_id(filter.cfg_["area"]);
470  filter_special_loc(src, dest, filter, f1, [&area](const map_location& loc) { return area.find(loc) != area.end(); });
471  }
472  else {
473  filter_special_loc(src, dest, filter, f1, tno_filter());
474  }
475  }
476 
477  template<typename T>
478  static void filter_xy(T&& src, location_set& dest, const terrain_filter& filter, bool with_border)
479  {
480  if (filter.cfg_.has_attribute("x") || filter.cfg_.has_attribute("y")) {
481  std::vector<map_location> xy_vector = filter.fc_->get_disp_context().map().parse_location_range(filter.cfg_["x"], filter.cfg_["y"], with_border);
482  filter_area(src, dest, filter, [&xy_vector](const map_location& loc) { return std::find(xy_vector.begin(), xy_vector.end(), loc) != xy_vector.end(); });
483  }
484  else {
485  filter_area(src, dest, filter, tno_filter());
486  }
487  }
488 };
489 //using lambdas with boost transformed gives compile erros on gcc (it works on clang and msvc)
491 {
492  map_location operator()(const config& cfg) const { return map_location(cfg, nullptr); }
494 };
495 void terrain_filter::get_locations(std::set<map_location>& locs, bool with_border) const
496 {
497  std::set<map_location> match_set;
498 
499  // See if the caller provided an override to with_border
500  with_border = cfg_["include_borders"].to_bool(with_border);
501 
502  if (cfg_.has_attribute("find_in")) {
503 
504  if (const game_data * gd = fc_->get_game_data()) {
505  try
506  {
507  auto ar = gd->get_variable_access_read(cfg_["find_in"]).as_array();
508  terrain_filterimpl::filter_xy(ar | boost::adaptors::transformed(cfg_to_loc()), match_set, *this, with_border);
509  }
510  catch (const invalid_variablename_exception&)
511  {
512  //Do nothing
513  }
514  }
515  }
516  else if (cfg_.has_attribute("x") || cfg_.has_attribute("y")) {
517  std::vector<map_location> xy_vector = fc_->get_disp_context().map().parse_location_range(cfg_["x"], cfg_["y"], with_border);
518  terrain_filterimpl::filter_area(xy_vector, match_set, *this, terrain_filterimpl::tno_filter());
519  }
520  else if (cfg_.has_attribute("area")) {
521  const std::set<map_location>& area = fc_->get_tod_man().get_area_by_id(cfg_["area"]);
523  }
524  else if (cfg_.has_attribute("location_id")) {
525  map_location loc2 = fc_->get_disp_context().map().special_location(cfg_["location_id"]);
526  if (loc2.valid()) {
527  match_set.insert(loc2);
528  }
529  }
530  else {
531  //consider all locations on the map
532  int bs = fc_->get_disp_context().map().border_size();
533  int w = with_border ? fc_->get_disp_context().map().w() + bs : fc_->get_disp_context().map().w();
534  int h = with_border ? fc_->get_disp_context().map().h() + bs : fc_->get_disp_context().map().h();
535  for (int x = with_border ? 0 - bs : 0; x < w; ++x) {
536  for (int y = with_border ? 0 - bs : 0; y < h; ++y) {
537  match_set.insert(map_location(x, y));
538  }
539  }
540  }
541 
542  //handle location filter
543  if(cfg_.has_child("filter_adjacent_location")) {
544  if(cache_.adjacent_matches == nullptr) {
545  cache_.adjacent_matches = new std::vector<std::set<map_location> >();
546  }
547  const vconfig::child_list& adj_cfgs = cfg_.get_children("filter_adjacent_location");
548  for (unsigned i = 0; i < adj_cfgs.size(); ++i) {
549  std::set<map_location> adj_set;
550  /* GCC-3.3 doesn't like operator[] so use at(), which has the same result */
551  terrain_filter(adj_cfgs.at(i), *this).get_locations(adj_set, with_border);
552  cache_.adjacent_matches->push_back(adj_set);
553  if(i >= max_loop_ && i+1 < adj_cfgs.size()) {
554  ERR_NG << "terrain_filter: loop count greater than " << max_loop_
555  << ", aborting\n";
556  break;
557  }
558  }
559  }
560  std::set<map_location>::iterator loc_itor = match_set.begin();
561  while(loc_itor != match_set.end()) {
562  if(match_internal(*loc_itor, true)) {
563  ++loc_itor;
564  } else {
565  match_set.erase(loc_itor++);
566  }
567  }
568 
569  //handle [and], [or], and [not] with in-order precedence
572  int ors_left = std::count_if(cond, cond_end, cfg_isor());
573  while(cond != cond_end)
574  {
575  //if there are no locations or [or] conditions left, go ahead and return empty
576  if(match_set.empty() && ors_left <= 0) {
577  return;
578  }
579 
580  const std::string& cond_name = cond.get_key();
581  const vconfig& cond_cfg = cond.get_child();
582 
583  //handle [and]
584  if(cond_name == "and") {
585  std::set<map_location> intersect_hexes;
586  terrain_filter(cond_cfg, *this).get_locations(intersect_hexes, with_border);
587  std::set<map_location>::iterator intersect_itor = match_set.begin();
588  while(intersect_itor != match_set.end()) {
589  if(intersect_hexes.find(*intersect_itor) == intersect_hexes.end()) {
590  match_set.erase(*intersect_itor++);
591  } else {
592  ++intersect_itor;
593  }
594  }
595  }
596  //handle [or]
597  else if(cond_name == "or") {
598  std::set<map_location> union_hexes;
599  terrain_filter(cond_cfg, *this).get_locations(union_hexes, with_border);
600  //match_set.insert(union_hexes.begin(), union_hexes.end()); //doesn't compile on MSVC
601  std::set<map_location>::iterator insert_itor = union_hexes.begin();
602  while(insert_itor != union_hexes.end()) {
603  match_set.insert(*insert_itor++);
604  }
605  --ors_left;
606  }
607  //handle [not]
608  else if(cond_name == "not") {
609  std::set<map_location> removal_hexes;
610  terrain_filter(cond_cfg, *this).get_locations(removal_hexes, with_border);
611  std::set<map_location>::iterator erase_itor = removal_hexes.begin();
612  while(erase_itor != removal_hexes.end()) {
613  match_set.erase(*erase_itor++);
614  }
615  }
616  ++cond;
617  }
618  if(match_set.empty()) {
619  return;
620  }
621 
622  //handle radius
623  size_t radius = cfg_["radius"].to_size_t(0);
624  if(radius > max_loop_) {
625  ERR_NG << "terrain_filter: radius greater than " << max_loop_
626  << ", restricting\n";
627  radius = max_loop_;
628  }
629  if(radius > 0) {
630  std::vector<map_location> xy_vector (match_set.begin(), match_set.end());
631  if(cfg_.has_child("filter_radius")) {
632  terrain_filter r_filter(cfg_.child("filter_radius"), *this);
633  get_tiles_radius(fc_->get_disp_context().map(), xy_vector, radius, locs, with_border, r_filter);
634  } else {
635  get_tiles_radius(fc_->get_disp_context().map(), xy_vector, radius, locs, with_border);
636  }
637  } else {
638  locs.insert(match_set.begin(), match_set.end());
639  }
640 }
641 
643 {
644  return cfg_.get_config();
645 }
646 
648  delete parsed_terrain;
649  delete adjacent_matches;
650 }
std::vector< int > get_teams() const
Definition: side_filter.cpp:72
std::function< int(lua_State *)> lua_function
virtual const display_context & get_disp_context() const =0
bool matches_range(const std::string &xloc, const std::string &yloc) const
Definition: location.cpp:311
variable_info_detail::maybe_const< vit, config::child_itors >::type as_array() const
might throw invalid_variablename_exception
bool shrouded(const map_location &loc) const
Definition: team.cpp:567
map_location operator()(const config &cfg) const
Definition: filter.cpp:492
vconfig get_child() const
Definition: variable.cpp:374
vconfig child(const std::string &key) const
Returns a child of *this whose key is key.
Definition: variable.cpp:243
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
Definition: location.hpp:274
const time_of_day & get_time_of_day(int for_turn=0) const
Returns global time of day for the passed turn.
Definition: tod_manager.hpp:56
static void filter_final(T &&src, location_set &dest, const terrain_filter &, const F1 &f1, const F2 &f2, const F3 &f3)
Definition: filter.cpp:444
all_children_iterator ordered_end() const
Definition: variable.cpp:403
bool is_village(const map_location &loc) const
Definition: map.cpp:68
virtual bool operator()(const map_location &loc) const
Definition: filter.hpp:54
std::string id
Definition: time_of_day.hpp:77
int lawful_bonus
The % bonus lawful units receive.
Definition: time_of_day.hpp:70
GLuint const GLfloat * val
Definition: glew.h:2614
int village_owner(const map_location &loc) const
Given the location of a village, will return the 0-based index of the team that currently owns it...
#define h
static void filter_special_loc(T &&src, location_set &dest, const terrain_filter &filter, const F1 &f1, const F2 &f2)
Definition: filter.cpp:454
std::vector< std::set< map_location > > * adjacent_matches
Definition: filter.hpp:85
terrain_filter_cache cache_
Definition: filter.hpp:93
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1220
#define WRN_NG
Definition: filter.cpp:41
GLenum src
Definition: glew.h:2392
bool as_bool() const
Definition: variant.cpp:580
static std::vector< DIRECTION > parse_directions(const std::string &str)
Parse_directions takes a comma-separated list, and filters out any invalid directions.
Definition: location.cpp:128
const vconfig cfg_
Definition: filter.hpp:73
-file sdl_utils.hpp
bool empty() const
Tests for an attribute that either was never set or was set to "".
Definition: config.cpp:375
GLdouble GLdouble t
Definition: glew.h:1366
Definitions for the interface to Wesnoth Markup Language (WML).
virtual const gamemap & map() const =0
Variant for storing WML attributes.
Definition: config.hpp:223
bool match(const map_location &loc) const
Definition: filter.cpp:364
const tdata_cache & tdata() const
Definition: map.hpp:70
const filter_context * fc_
Definition: filter.hpp:74
t_translation::t_match * parsed_terrain
Definition: filter.hpp:82
Object which defines a time of day with associated bonuses, image, sounds etc.
Definition: time_of_day.hpp:48
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:50
bool null() const
Definition: variable.hpp:66
bool valid() const
Definition: location.hpp:69
child_list get_children(const std::string &key) const
Definition: variable.cpp:181
This structure can be used for matching terrain strings.
Definition: translation.hpp:83
static text_list cache_
Definition: font.cpp:772
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1858
int w() const
Effective map width.
Definition: map.hpp:105
t_translation::t_terrain number() const
Definition: terrain.hpp:43
bool has_child(const std::string &key) const
Returns whether or not *this has a child whose key is key.
Definition: variable.cpp:270
const size_t max_loop
The maximum number of hexes on a map and items in an array and also used as maximum in wml loops...
Encapsulates the map of the game.
Definition: map.hpp:37
static const std::vector< DIRECTION > & default_dirs()
Default list of directions.
Definition: location.cpp:55
int border_size() const
Size of the map border.
Definition: map.hpp:111
bool operator()(const map_location &) const
Definition: filter.cpp:440
virtual const unit_map & units() const =0
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Definition: translation.hpp:47
~terrain_filter()
Default implementation, but defined out-of-line for efficiency reasons.
Definition: filter.cpp:43
Encapsulates the map of the game.
Definition: location.hpp:38
const terrain_type & get_terrain_info(const t_translation::t_terrain &terrain) const
Definition: map.cpp:100
std::vector< map_location > parse_location_range(const std::string &xvals, const std::string &yvals, bool with_border=false) const
Parses ranges of locations into a vector of locations, using this map's dimensions as bounds...
Definition: map.cpp:537
map_location special_location(const std::string &id) const
Definition: map.cpp:409
static variant evaluate(const const_formula_ptr &f, const formula_callable &variables, formula_debugger *fdb=nullptr, variant default_res=variant(0))
Definition: formula.hpp:31
void get_locations(std::set< map_location > &locs, bool with_border=false) const
Definition: filter.cpp:495
size_t max_loop_
Definition: filter.hpp:94
virtual const std::vector< team > & teams() const =0
config to_config() const
Definition: filter.cpp:642
std::stringstream & wml_error()
Use this logger to send errors due to deprecated WML.
Definition: log.cpp:262
int h() const
Effective map height.
Definition: map.hpp:108
std::vector< std::pair< int, int > > parse_ranges(std::string const &str)
const config & get_config() const
Definition: variable.hpp:68
terrain_filter & operator=(const terrain_filter &other)
Definition: filter.cpp:95
GLuint index
Definition: glew.h:1782
Information on a WML variable.
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:5910
size_t i
Definition: function.cpp:1057
bool terrain_matches(const t_terrain &src, const t_terrain &dest)
Tests whether a specific terrain matches an expression, for matching rules see above.
map_location result_type
Definition: filter.cpp:493
GLint GLint GLint GLint GLint x
Definition: glew.h:1220
bool run_filter(char const *name, unit const &u)
Runs a script from a unit filter.
bool fogged(const map_location &loc) const
Definition: team.cpp:575
void get_tiles_radius(const map_location &center, size_t radius, std::set< map_location > &result)
Function that will add to result all locations within radius tiles of center (including center itself...
Definition: pathutils.cpp:70
virtual const tod_manager & get_tod_man() const =0
const std::set< map_location > & get_area_by_id(const std::string &id) const
t_translation::t_terrain get_terrain(const map_location &loc) const
Looks up terrain at a particular location.
Definition: map.cpp:341
bool on_board(const map_location &loc) const
Tell if a location is on the map.
Definition: map.cpp:467
const time_of_day get_illuminated_time_of_day(const unit_map &units, const gamemap &map, const map_location &loc, int for_turn=0) const
Returns time of day object for the passed turn at a location.
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glew.h:3448
bool find(E event, F functor)
Tests whether an event handler is available.
virtual const game_data * get_game_data() const =0
static int cond(LexState *ls)
Definition: lparser.cpp:1168
A variable-expanding proxy for the config class.
Definition: variable.hpp:36
static lg::log_domain log_engine("engine")
Standard logging facilities (interface).
virtual game_lua_kernel * get_lua_kernel() const =0
boost::scoped_ptr< unit_filter > ufilter_
Definition: filter.hpp:90
std::vector< std::pair< terrain_filter, std::map< map_location, bool > > > adjacent_match_cache
Definition: filter.hpp:88
int to_int(int def=0) const
Definition: config.cpp:308
std::vector< std::string > split(std::string const &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
#define e
terrain_filter(const vconfig &cfg, const filter_context *fc, const bool flat_tod=false, const size_t max_loop=game_config::max_loop)
Definition: filter.cpp:65
unit_iterator find(size_t id)
Definition: map.cpp:285
bool valid() const
Definition: map.hpp:229
static void filter_area(T &&src, location_set &dest, const terrain_filter &filter, const F1 &f1)
Definition: filter.cpp:466
std::vector< vconfig > child_list
Definition: variable.hpp:71
bool match_internal(const map_location &loc, const bool ignore_xy) const
Definition: filter.cpp:120
#define ERR_NG
Definition: filter.cpp:40
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
static void filter_xy(T &&src, location_set &dest, const terrain_filter &filter, bool with_border)
Definition: filter.cpp:478
GLsizei const GLcharARB ** string
Definition: glew.h:4503
std::string get_key() const
Definition: variable.cpp:365
bool has_attribute(const std::string &key) const
< Synonym for operator[]
Definition: variable.hpp:92
all_children_iterator ordered_begin() const
In-order iteration over all children.
Definition: variable.cpp:398
bool in_ranges(const Cmp c, const std::vector< std::pair< Cmp, Cmp > > &ranges)
Definition: util.hpp:195
std::set< map_location > location_set
Definition: filter.cpp:436