The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
callable_objects.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 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 #include "formula/callable_objects.hpp"
16 #include "formula/function.hpp"
17 #include "units/unit.hpp"
19 #include "config.hpp"
20 
21 template <typename T, typename K>
22 variant convert_map( const std::map<T, K>& input_map ) {
23  std::map<variant,variant> tmp;
24 
25  for(typename std::map< T, K>::const_iterator i = input_map.begin(); i != input_map.end(); ++i) {
26  tmp[ variant(i->first) ] = variant( i->second );
27  }
28 
29  return variant( &tmp );
30 }
31 
32 
33 template <typename T>
34 variant convert_vector( const std::vector<T>& input_vector )
35 {
36  std::vector<variant> tmp;
37 
38  for(typename std::vector<T>::const_iterator i = input_vector.begin(); i != input_vector.end(); ++i) {
39  tmp.push_back( variant( *i ) );
40  }
41 
42  return variant( &tmp );
43 }
44 
45 
47 {
48  if(key == "x") {
49  return variant(loc_.x+1);
50  } else if(key == "y") {
51  return variant(loc_.y+1);
52  } else {
53  return variant();
54  }
55 }
56 
57 void location_callable::get_inputs(std::vector<game_logic::formula_input>* inputs) const
58 {
60  inputs->push_back(game_logic::formula_input("x", FORMULA_READ_ONLY));
61  inputs->push_back(game_logic::formula_input("y", FORMULA_READ_ONLY));
62 }
63 
65 {
66  const location_callable* loc_callable = dynamic_cast<const location_callable*>(callable);
67  if(loc_callable == nullptr) {
68  return formula_callable::do_compare(callable);
69  }
70 
71  const map_location& other_loc = loc_callable->loc();
72  return loc_.do_compare(other_loc);
73 }
74 
76 {
77  std::ostringstream s;
78  s << "loc(" << (loc_.x+1) << "," << (loc_.y+1) << ")";
79  str += s.str();
80 }
81 
82 
84 {
85  if(key == "id" || key == "name") {
86  return variant(att_.id());
87  } else if(key == "description") {
88  return variant(att_.name());
89  } else if(key == "type") {
90  return variant(att_.type());
91  } else if(key == "icon") {
92  return variant(att_.icon());
93  } else if(key == "range") {
94  return variant(att_.range());
95  } else if(key == "damage") {
96  return variant(att_.damage());
97  } else if(key == "number_of_attacks" || key == "number" || key == "num_attacks" || key == "attacks") {
98  return variant(att_.num_attacks());
99  } else if(key == "attack_weight") {
101  } else if(key == "defense_weight") {
103  } else if(key == "accuracy") {
104  return variant(att_.accuracy());
105  } else if(key == "parry") {
106  return variant(att_.parry());
107  } else if(key == "movement_used") {
108  return variant(att_.movement_used());
109  } else if(key == "specials" || key == "special") {
110  const config specials = att_.specials();
111  std::vector<variant> res;
112 
113  for(const auto& special : specials.all_children_range()) {
114  if(!special.cfg["id"].empty()) {
115  res.push_back(variant(special.cfg["id"].str()));
116  }
117  }
118  return variant(&res);
119  }
120 
121  return variant();
122 }
123 
124 void attack_type_callable::get_inputs(std::vector<game_logic::formula_input>* inputs) const
125 {
127  inputs->push_back(game_logic::formula_input("name", FORMULA_READ_ONLY));
128  inputs->push_back(game_logic::formula_input("type", FORMULA_READ_ONLY));
129  inputs->push_back(game_logic::formula_input("description", FORMULA_READ_ONLY));
130  inputs->push_back(game_logic::formula_input("icon", FORMULA_READ_ONLY));
131  inputs->push_back(game_logic::formula_input("range", FORMULA_READ_ONLY));
132  inputs->push_back(game_logic::formula_input("damage", FORMULA_READ_ONLY));
133  inputs->push_back(game_logic::formula_input("number", FORMULA_READ_ONLY));
134  inputs->push_back(game_logic::formula_input("accuracy", FORMULA_READ_ONLY));
135  inputs->push_back(game_logic::formula_input("parry", FORMULA_READ_ONLY));
136  inputs->push_back(game_logic::formula_input("movement_used", FORMULA_READ_ONLY));
137  inputs->push_back(game_logic::formula_input("attack_weight", FORMULA_READ_ONLY));
138  inputs->push_back(game_logic::formula_input("defense_weight", FORMULA_READ_ONLY));
139  inputs->push_back(game_logic::formula_input("specials", FORMULA_READ_ONLY));
140 }
141 
142 int attack_type_callable::do_compare(const formula_callable* callable) const
143 {
144  const attack_type_callable* att_callable = dynamic_cast<const attack_type_callable*>(callable);
145  if(att_callable == nullptr) {
146  return formula_callable::do_compare(callable);
147  }
148 
149  if (att_.damage() != att_callable->att_.damage() )
150  return att_.damage() - att_callable->att_.damage();
151 
152  if (att_.num_attacks() != att_callable->att_.num_attacks() )
153  return att_.num_attacks() - att_callable->att_.num_attacks();
154 
155  if ( att_.id() != att_callable->att_.id() )
156  return att_.id().compare(att_callable->att_.id());
157 
158  if ( att_.type() != att_callable->att_.type() )
159  return att_.type().compare(att_callable->att_.type());
160 
161  if ( att_.range() != att_callable->att_.range() )
162  return att_.range().compare(att_callable->att_.range());
163 
164  return att_.weapon_specials().compare(att_callable->att_.weapon_specials());
165 }
166 
168 {
169  if(key == "x") {
171  return variant();
172  } else {
173  return variant(loc_.x+1);
174  }
175  } else if(key == "y") {
177  return variant();
178  } else {
179  return variant(loc_.y+1);
180  }
181  } else if(key == "loc") {
183  return variant();
184  } else {
185  return variant(new location_callable(loc_));
186  }
187  } else if(key == "id") {
188  return variant(u_.id());
189  } else if(key == "type") {
190  return variant(u_.type_id());
191  } else if(key == "name") {
192  return variant(u_.name());
193  } else if(key == "usage") {
194  return variant(u_.usage());
195  } else if(key == "leader" || key == "canrecruit") {
196  return variant(u_.can_recruit());
197  } else if(key == "undead") {
198  return variant(u_.get_state("not_living") ? 1 : 0);
199  } else if(key == "attacks") {
200  const std::vector<attack_type>& att = u_.attacks();
201  std::vector<variant> res;
202 
203  for( std::vector<attack_type>::const_iterator i = att.begin(); i != att.end(); ++i)
204  res.push_back(variant(new attack_type_callable(*i)));
205  return variant(&res);
206  } else if(key == "abilities") {
207  std::vector<std::string> abilities = u_.get_ability_list();
208  std::vector<variant> res;
209 
210  if (abilities.empty())
211  return variant( &res );
212 
213  for (std::vector<std::string>::iterator it = abilities.begin(); it != abilities.end(); ++it)
214  {
215  res.push_back( variant(*it) );
216  }
217  return variant( &res );
218  } else if(key == "hitpoints") {
219  return variant(u_.hitpoints());
220  } else if(key == "max_hitpoints") {
221  return variant(u_.max_hitpoints());
222  } else if(key == "experience") {
223  return variant(u_.experience());
224  } else if(key == "max_experience") {
225  return variant(u_.max_experience());
226  } else if(key == "level" || key == "full") {
227  // This allows writing "upkeep == full"
228  return variant(u_.level());
229  } else if(key == "total_movement" || key == "max_moves") {
230  return variant(u_.total_movement());
231  } else if(key == "movement_left" || key == "moves") {
232  return variant(u_.movement_left());
233  } else if(key == "attacks_left") {
234  return variant(u_.attacks_left());
235  } else if(key == "max_attacks") {
236  return variant(u_.max_attacks());
237  } else if(key == "traits") {
238  const std::vector<std::string> traits = u_.get_traits_list();
239  std::vector<variant> res;
240 
241  if(traits.empty())
242  return variant( &res );
243 
244  for (std::vector<std::string>::const_iterator it = traits.begin(); it != traits.end(); ++it)
245  {
246  res.push_back( variant(*it) );
247  }
248  return variant( &res );
249  } else if(key == "extra_recruit") {
250  const std::vector<std::string> recruits = u_.recruits();
251  std::vector<variant> res;
252 
253  if(recruits.empty())
254  return variant( &res );
255 
256  for (std::vector<std::string>::const_iterator it = recruits.begin(); it != recruits.end(); ++it)
257  {
258  res.push_back( variant(*it) );
259  }
260  return variant( &res );
261  } else if(key == "advances_to") {
262  const std::vector<std::string> advances = u_.advances_to();
263  std::vector<variant> res;
264 
265  if(advances.empty())
266  return variant( &res );
267 
268  for (std::vector<std::string>::const_iterator it = advances.begin(); it != advances.end(); ++it)
269  {
270  res.push_back( variant(*it) );
271  }
272  return variant( &res );
273  } else if(key == "states" || key == "status") {
274  const std::map<std::string, std::string>& states_map = u_.get_states();
275 
276  return convert_map( states_map );
277  } else if(key == "side") {
278  return variant(u_.side()-1);
279  } else if(key == "cost") {
280  return variant(u_.cost());
281  } else if(key == "upkeep") {
282  return variant(u_.upkeep());
283  } else if(key == "loyal") {
284  // So we can write "upkeep == loyal"
285  return variant(0);
286  } else if(key == "hidden") {
287  return variant(u_.get_hidden());
288  } else if(key == "petrified") {
289  return variant(u_.incapacitated());
290  } else if(key == "resting") {
291  return variant(u_.resting());
292  } else if(key == "role") {
293  return variant(u_.get_role());
294  } else if(key == "race") {
295  return variant(u_.race()->id());
296  } else if(key == "gender") {
297  return variant(gender_string(u_.gender()));
298  } else if(key == "variation") {
299  return variant(u_.variation());
300  } else if(key == "zoc") {
301  return variant(u_.get_emit_zoc());
302  } else if(key == "alignment") {
303  return variant(u_.alignment().to_string());
304  } else if(key == "facing") {
306  } else if(key == "vars") {
308  return variant(u_.formula_manager().formula_vars().get());
309  } else {
310  return variant();
311  }
312  } else if(key == "wml_vars") {
313  return variant(new config_callable(u_.variables()));
314  } else if(key == "n" || key == "s" || key == "ne" || key == "se" || key == "nw" || key == "sw" || key == "lawful" || key == "neutral" || key == "chaotic" || key == "liminal" || key == "male" || key == "female") {
315  return variant(key);
316  } else {
317  return variant();
318  }
319 }
320 
321 void unit_callable::get_inputs(std::vector<game_logic::formula_input>* inputs) const
322 {
324  inputs->push_back(game_logic::formula_input("x", FORMULA_READ_ONLY));
325  inputs->push_back(game_logic::formula_input("y", FORMULA_READ_ONLY));
326  inputs->push_back(game_logic::formula_input("loc", FORMULA_READ_ONLY));
327  inputs->push_back(game_logic::formula_input("id", FORMULA_READ_ONLY));
328  inputs->push_back(game_logic::formula_input("type", FORMULA_READ_ONLY));
329  inputs->push_back(game_logic::formula_input("name", FORMULA_READ_ONLY));
330  inputs->push_back(game_logic::formula_input("canrecruit", FORMULA_READ_ONLY));
331  inputs->push_back(game_logic::formula_input("undead", FORMULA_READ_ONLY));
332  inputs->push_back(game_logic::formula_input("traits", FORMULA_READ_ONLY));
333  inputs->push_back(game_logic::formula_input("attacks", FORMULA_READ_ONLY));
334  inputs->push_back(game_logic::formula_input("abilities", FORMULA_READ_ONLY));
335  inputs->push_back(game_logic::formula_input("hitpoints", FORMULA_READ_ONLY));
336  inputs->push_back(game_logic::formula_input("max_hitpoints", FORMULA_READ_ONLY));
337  inputs->push_back(game_logic::formula_input("experience", FORMULA_READ_ONLY));
338  inputs->push_back(game_logic::formula_input("max_experience", FORMULA_READ_ONLY));
339  inputs->push_back(game_logic::formula_input("level", FORMULA_READ_ONLY));
340  inputs->push_back(game_logic::formula_input("moves", FORMULA_READ_ONLY));
341  inputs->push_back(game_logic::formula_input("max_moves", FORMULA_READ_ONLY));
342  inputs->push_back(game_logic::formula_input("attacks_left", FORMULA_READ_ONLY));
343  inputs->push_back(game_logic::formula_input("max_attacks", FORMULA_READ_ONLY));
344  inputs->push_back(game_logic::formula_input("side", FORMULA_READ_ONLY));
345  inputs->push_back(game_logic::formula_input("extra_recruit", FORMULA_READ_ONLY));
346  inputs->push_back(game_logic::formula_input("advances_to", FORMULA_READ_ONLY));
347  inputs->push_back(game_logic::formula_input("status", FORMULA_READ_ONLY));
348  inputs->push_back(game_logic::formula_input("cost", FORMULA_READ_ONLY));
349  inputs->push_back(game_logic::formula_input("usage", FORMULA_READ_ONLY));
350  inputs->push_back(game_logic::formula_input("upkeep", FORMULA_READ_ONLY));
351  inputs->push_back(game_logic::formula_input("hidden", FORMULA_READ_ONLY));
352  inputs->push_back(game_logic::formula_input("petrified", FORMULA_READ_ONLY));
353  inputs->push_back(game_logic::formula_input("resting", FORMULA_READ_ONLY));
354  inputs->push_back(game_logic::formula_input("role", FORMULA_READ_ONLY));
355  inputs->push_back(game_logic::formula_input("race", FORMULA_READ_ONLY));
356  inputs->push_back(game_logic::formula_input("gender", FORMULA_READ_ONLY));
357  inputs->push_back(game_logic::formula_input("variation", FORMULA_READ_ONLY));
358  inputs->push_back(game_logic::formula_input("zoc", FORMULA_READ_ONLY));
359  inputs->push_back(game_logic::formula_input("alignment", FORMULA_READ_ONLY));
360  inputs->push_back(game_logic::formula_input("facing", FORMULA_READ_ONLY));
361  inputs->push_back(game_logic::formula_input("vars", FORMULA_READ_ONLY));
362  inputs->push_back(game_logic::formula_input("wml_vars", FORMULA_READ_ONLY));
363 }
364 
365 int unit_callable::do_compare(const formula_callable* callable) const
366 {
367  const unit_callable* u_callable = dynamic_cast<const unit_callable*>(callable);
368  if(u_callable == nullptr) {
369  return formula_callable::do_compare(callable);
370  }
371 
372  return u_.underlying_id() - u_callable->u_.underlying_id();
373 }
374 
376 {
377  if(key == "id") {
378  return variant(u_.id());
379  } else if(key == "type") {
380  return variant(u_.type_name());
381  } else if(key == "alignment") {
382  return variant(u_.alignment().to_string());
383  } else if(key == "race") {
384  return variant(u_.race_id());
385  } else if(key == "abilities") {
386  std::vector<std::string> abilities = u_.get_ability_list();
387  std::vector<variant> res;
388 
389  if (abilities.empty())
390  return variant( &res );
391 
392  for (std::vector<std::string>::iterator it = abilities.begin(); it != abilities.end(); ++it)
393  {
394  res.push_back( variant(*it) );
395  }
396  return variant( &res );
397  } else if(key == "traits") {
398  std::vector<variant> res;
399 
400  for(const auto& config : u_.possible_traits())
401  {
402  res.push_back(variant(config["id"].str()));
403  }
404  return variant(&res);
405  } else if(key == "attacks") {
406  std::vector<attack_type> att = u_.attacks();
407  std::vector<variant> res;
408 
409  for( std::vector<attack_type>::iterator i = att.begin(); i != att.end(); ++i)
410  res.push_back(variant(new attack_type_callable(*i)));
411  return variant(&res);
412  } else if(key == "hitpoints" || key == "max_hitpoints") {
413  return variant(u_.hitpoints());
414  } else if(key == "experience" || key == "max_experience") {
415  return variant(u_.experience_needed(true));
416  } else if(key == "level") {
417  return variant(u_.level());
418  } else if(key == "total_movement" || key == "max_moves" || key == "moves") {
419  return variant(u_.movement());
420  } else if(key == "unpoisonable") {
421  return variant(u_.musthave_status("unpoisonable"));
422  } else if(key == "undrainable") {
423  return variant(u_.musthave_status("undrainable"));
424  } else if(key == "unplagueable") {
425  return variant(u_.musthave_status("unplagueable"));
426  } else if(key == "cost") {
427  return variant(u_.cost());
428  } else if(key == "recall_cost") {
429  return variant(u_.recall_cost());
430  } else if(key == "usage") {
431  return variant(u_.usage());
432  } else {
433  return variant();
434  }
435 }
436 
437 void unit_type_callable::get_inputs(std::vector<game_logic::formula_input>* inputs) const
438 {
440  inputs->push_back(game_logic::formula_input("id", FORMULA_READ_ONLY));
441  inputs->push_back(game_logic::formula_input("type", FORMULA_READ_ONLY));
442  inputs->push_back(game_logic::formula_input("race", FORMULA_READ_ONLY));
443  inputs->push_back(game_logic::formula_input("alignment", FORMULA_READ_ONLY));
444  inputs->push_back(game_logic::formula_input("abilities", FORMULA_READ_ONLY));
445  inputs->push_back(game_logic::formula_input("traits", FORMULA_READ_ONLY));
446  inputs->push_back(game_logic::formula_input("attacks", FORMULA_READ_ONLY));
447  inputs->push_back(game_logic::formula_input("hitpoints", FORMULA_READ_ONLY));
448  inputs->push_back(game_logic::formula_input("experience", FORMULA_READ_ONLY));
449  inputs->push_back(game_logic::formula_input("level", FORMULA_READ_ONLY));
450  inputs->push_back(game_logic::formula_input("total_movement", FORMULA_READ_ONLY));
451  inputs->push_back(game_logic::formula_input("undead", FORMULA_READ_ONLY));
452  inputs->push_back(game_logic::formula_input("cost", FORMULA_READ_ONLY));
453  inputs->push_back(game_logic::formula_input("recall_cost", FORMULA_READ_ONLY));
454  inputs->push_back(game_logic::formula_input("usage", FORMULA_READ_ONLY));
455 }
456 
457 int unit_type_callable::do_compare(const formula_callable* callable) const
458 {
459  const unit_type_callable* u_callable = dynamic_cast<const unit_type_callable*>(callable);
460  if(u_callable == nullptr) {
461  return formula_callable::do_compare(callable);
462  }
463 
464  return u_.id().compare(u_callable->u_.id());
465 }
466 
467 class fai_variant_visitor : public boost::static_visitor<variant> {
468 public:
469  variant operator()(bool b) const {return variant(b ? 1 : 0);}
470  variant operator()(int i) const {return variant(i);}
471  variant operator()(unsigned long long i) const {return variant(i);}
472  variant operator()(double i) const {return variant(i * 1000, variant::DECIMAL_VARIANT);}
473  variant operator()(const std::string& s) const {return variant(s);} // TODO: Should comma-separated lists of stuff be returned as a list? The challenge is to distinguish them from ordinary strings that happen to contain a comma (or should we assume that such strings will be translatable?)
474  variant operator()(const t_string& s) const {return variant(s.str());}
475  variant operator()(boost::blank) const {return variant();}
476 };
477 
479 {
480  if(cfg_.has_attribute(key)) {
481  return cfg_[key].apply_visitor(fai_variant_visitor());
482  } else if(cfg_.has_child(key)) {
483  std::vector<variant> result;
484  for(const auto& child : cfg_.child_range(key)) {
485  result.push_back(variant(new config_callable(child)));
486  }
487  return variant(&result);
488  } else if(key == "__all_children") {
489  std::vector<variant> result;
490  for(const auto& child : cfg_.all_children_range()) {
491  const variant cfg_child(new config_callable(child.cfg));
492  const variant kv(new game_logic::key_value_pair(variant(child.key), cfg_child));
493  result.push_back(kv);
494  }
495  return variant(&result);
496  } else if(key == "__children") {
497  std::map<std::string, std::vector<variant> > build;
498  for(const auto& child : cfg_.all_children_range()) {
499  const variant cfg_child(new config_callable(child.cfg));
500  build[child.key].push_back(cfg_child);
501  }
502  std::map<variant,variant> result;
503  for(auto& p : build) {
504  result[variant(p.first)] = variant(&p.second);
505  }
506  return variant(&result);
507  } else if(key == "__attributes") {
508  std::map<variant,variant> result;
509  for(const auto& val : cfg_.attribute_range()) {
510  result[variant(val.first)] = val.second.apply_visitor(fai_variant_visitor());
511  }
512  return variant(&result);
513  } else return variant();
514 }
515 
516 void config_callable::get_inputs(std::vector<game_logic::formula_input>* inputs) const
517 {
518  inputs->push_back(game_logic::formula_input("__all_children", game_logic::FORMULA_READ_ONLY));
519  inputs->push_back(game_logic::formula_input("__children", game_logic::FORMULA_READ_ONLY));
520  inputs->push_back(game_logic::formula_input("__attributes", game_logic::FORMULA_READ_ONLY));
521  for(const auto& val : cfg_.attribute_range()) {
522  if(val.first.find_first_not_of(game_logic::formula::id_chars) != std::string::npos) {
524  }
525  }
526 }
527 
529 {
530  const config_callable* cfg_callable = dynamic_cast<const config_callable*>(callable);
531  if(cfg_callable == nullptr) {
532  return formula_callable::do_compare(callable);
533  }
534 
535  if(cfg_ == cfg_callable->get_config()) {
536  return 0;
537  }
538  return cfg_.hash().compare(cfg_callable->get_config().hash());
539 }
540 
542 {
543  if(key == "x") {
544  return variant(loc_.x+1);
545  } else if(key == "y") {
546  return variant(loc_.y+1);
547  } else if(key == "loc") {
548  return variant(new location_callable(loc_));
549  } else if(key == "id") {
550  return variant(std::string(t_.id()));
551  } else if(key == "name") {
552  return variant(t_.name());
553  } else if(key == "editor_name") {
554  return variant(t_.editor_name());
555  } else if(key == "description") {
556  return variant(t_.description());
557  } else if(key == "icon") {
558  return variant(t_.icon_image());
559  } else if(key == "light") {
560  return variant(t_.light_bonus(0));
561  } else if(key == "village") {
562  return variant(t_.is_village());
563  } else if(key == "castle") {
564  return variant(t_.is_castle());
565  } else if(key == "keep") {
566  return variant(t_.is_keep());
567  } else if(key == "healing") {
568  return variant(t_.gives_healing());
569  } else
570  return variant();
571 }
572 
573 void terrain_callable::get_inputs(std::vector<game_logic::formula_input>* inputs) const
574 {
576  inputs->push_back(game_logic::formula_input("x", FORMULA_READ_ONLY));
577  inputs->push_back(game_logic::formula_input("y", FORMULA_READ_ONLY));
578  inputs->push_back(game_logic::formula_input("loc", FORMULA_READ_ONLY));
579  inputs->push_back(game_logic::formula_input("id", FORMULA_READ_ONLY));
580  inputs->push_back(game_logic::formula_input("name", FORMULA_READ_ONLY));
581  inputs->push_back(game_logic::formula_input("editor_name", FORMULA_READ_ONLY));
582  inputs->push_back(game_logic::formula_input("description", FORMULA_READ_ONLY));
583  inputs->push_back(game_logic::formula_input("icon", FORMULA_READ_ONLY));
584  inputs->push_back(game_logic::formula_input("light", FORMULA_READ_ONLY));
585  inputs->push_back(game_logic::formula_input("village", FORMULA_READ_ONLY));
586  inputs->push_back(game_logic::formula_input("castle", FORMULA_READ_ONLY));
587  inputs->push_back(game_logic::formula_input("keep", FORMULA_READ_ONLY));
588  inputs->push_back(game_logic::formula_input("healing", FORMULA_READ_ONLY));
589 }
590 
591 int terrain_callable::do_compare(const formula_callable* callable) const
592 {
593  const terrain_callable* terr_callable = dynamic_cast<const terrain_callable*>(callable);
594  if(terr_callable == nullptr) {
595  return formula_callable::do_compare(callable);
596  }
597 
598  const map_location& other_loc = terr_callable->loc_;
599 
600  return loc_.do_compare(other_loc);
601 }
602 
603 
604 
const t_string & name() const
Definition: attack_type.hpp:35
variant get_value(const std::string &key) const
child_itors child_range(const std::string &key)
Definition: config.cpp:613
int total_movement() const
Definition: unit.hpp:218
void get_inputs(std::vector< game_logic::formula_input > *inputs) const
const std::string & id() const
Definition: unit.hpp:148
std::string const & gender_string(unit_race::GENDER gender)
Definition: race.cpp:151
const attack_type att_
const t_string & type_name() const
The name of the unit in the current language setting.
Definition: types.hpp:112
int max_hitpoints() const
Definition: unit.hpp:169
bool get_state(const std::string &state) const
Definition: unit.cpp:1289
size_t underlying_id() const
The unique internal ID of the unit.
Definition: unit.hpp:150
int movement() const
Definition: types.hpp:128
const t_string & name() const
The unit name for display.
Definition: unit.hpp:158
int experience() const
Definition: unit.hpp:171
twindow * build(CVideo &video, const twindow_builder::tresolution *definition)
Builds a window.
double attack_weight() const
Definition: attack_type.hpp:47
void get_inputs(std::vector< game_logic::formula_input > *inputs) const
variant get_value(const std::string &key) const
int do_compare(const formula_callable *callable) const
bool musthave_status(const std::string &status) const
Definition: types.cpp:669
int hitpoints() const
Definition: unit.hpp:168
variant operator()(unsigned long long i) const
int upkeep() const
Definition: unit.cpp:1498
variant get_value(const std::string &key) const
int do_compare(const formula_callable *callable) const
int movement_used() const
Definition: attack_type.hpp:90
std::string usage() const
Definition: unit.hpp:360
void get_inputs(std::vector< game_logic::formula_input > *inputs) const
variant operator()(const t_string &s) const
std::vector< std::string > get_ability_list() const
Definition: types.cpp:545
const std::string & id() const
Definition: race.hpp:33
const map_location & loc() const
GLuint const GLfloat * val
Definition: glew.h:2614
const t_string & name() const
Definition: terrain.hpp:33
const std::string & id() const
Definition: terrain.hpp:37
variant get_value(const std::string &key) const
int side() const
Definition: unit.hpp:201
int light_bonus(int base) const
Returns the light (lawful) bonus for this terrain when the time of day gives a base bonus...
Definition: terrain.hpp:55
int max_attacks() const
Definition: unit.hpp:231
int do_compare(const game_logic::formula_callable *callable) const
std::string weapon_specials(bool only_active=false, bool is_backstab=false) const
Returns a comma-separated string of active names for the specials of *this.
Definition: abilities.cpp:649
int level() const
Definition: types.hpp:126
int parry() const
Definition: attack_type.hpp:44
const game_logic::map_formula_callable_ptr & formula_vars() const
int accuracy() const
Definition: attack_type.hpp:43
const std::string & icon() const
Definition: attack_type.hpp:38
Definitions for the interface to Wesnoth Markup Language (WML).
const t_string & editor_name() const
Definition: terrain.hpp:34
bool get_hidden() const
Definition: unit.hpp:304
void serialize_to_string(std::string &str) const
int num_attacks() const
Definition: attack_type.hpp:46
const std::vector< std::string > & recruits() const
Definition: unit.hpp:209
GLdouble GLdouble GLdouble b
Definition: glew.h:6966
void get_inputs(std::vector< game_logic::formula_input > *inputs) const
bool has_child(const std::string &key) const
Determine whether a config has a child or not.
Definition: config.cpp:651
const std::string & type_id() const
The id of the type of the unit.
Definition: unit.hpp:142
bool incapacitated() const
Definition: unit.hpp:215
config_callable(const config &c)
GLuint64EXT * result
Definition: glew.h:10727
static const char *const id_chars
Definition: formula.hpp:65
int gives_healing() const
Definition: terrain.hpp:61
unit_type::ALIGNMENT alignment() const
Definition: unit.hpp:368
const unit_type & u_
all_children_itors all_children_range() const
In-order iteration over all children.
Definition: config.cpp:1127
variant operator()(const std::string &s) const
variant get_value(const std::string &key) const
bool can_recruit() const
Definition: unit.hpp:207
unit_race::GENDER gender() const
Definition: unit.hpp:203
variant operator()(int i) const
const terrain_type & t_
variant get_value(const std::string &key) const
static const map_location & null_location()
Definition: location.hpp:195
GLfloat GLfloat p
Definition: glew.h:12766
const config specials() const
Definition: attack_type.hpp:49
int movement_left() const
Returns how far a unit can move this turn (zero if incapacitated).
Definition: unit.hpp:220
bool is_village() const
Definition: terrain.hpp:62
variant convert_vector(const std::vector< T > &input_vector)
variant operator()(boost::blank) const
const std::string & id() const
Definition: attack_type.hpp:36
const std::string & type() const
Definition: attack_type.hpp:37
const std::vector< attack_type > & attacks() const
Definition: unit.hpp:271
std::string race_id() const
Returns the ID of this type's race without the need to build the type.
Definition: types.hpp:215
int cost() const
Definition: types.hpp:134
Encapsulates the map of the game.
Definition: location.hpp:38
const std::string & usage() const
Definition: types.hpp:137
GLuint res
Definition: glew.h:9258
const config & get_config() const
const std::vector< std::string > & advances_to() const
Definition: unit.hpp:133
map_location::DIRECTION facing() const
Definition: unit.hpp:278
bool is_keep() const
Definition: terrain.hpp:64
config & variables()
Definition: unit.hpp:366
const std::map< std::string, std::string > get_states() const
Definition: unit.cpp:1267
config::const_child_itors possible_traits() const
Definition: types.hpp:182
const_attr_itors attribute_range() const
Definition: config.cpp:984
int attacks_left() const
Definition: unit.hpp:230
const std::string & range() const
Definition: attack_type.hpp:39
bool resting() const
Definition: unit.hpp:242
size_t i
Definition: function.cpp:1057
const std::string & variation() const
Definition: unit.hpp:155
int do_compare(const formula_callable *callable) const
int level() const
Definition: unit.hpp:175
int hitpoints() const
Definition: types.hpp:123
int experience_needed(bool with_acceleration=true) const
Definition: types.cpp:514
int damage() const
Definition: attack_type.hpp:45
std::string hash() const
Definition: config.cpp:1468
variant operator()(double i) const
const location & loc_
unit_formula_manager & formula_manager() const
Definition: unit.hpp:393
bool has_attribute(const std::string &key) const
Definition: config.cpp:514
int max_experience() const
Definition: unit.hpp:172
int cost() const
Definition: unit.hpp:284
std::vector< attack_type > attacks() const
Definition: types.cpp:484
int do_compare(const map_location &a) const
three-way comparator
Definition: location.hpp:86
double defense_weight() const
Definition: attack_type.hpp:48
const config & cfg_
void get_inputs(std::vector< game_logic::formula_input > *inputs) const
int do_compare(const formula_callable *callable) const
int recall_cost() const
Definition: types.hpp:127
const std::string & str() const
Definition: tstring.hpp:170
variant operator()(bool b) const
const std::string & get_role() const
Definition: unit.hpp:265
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
bool get_emit_zoc() const
Definition: unit.hpp:268
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
bool is_castle() const
Definition: terrain.hpp:63
void get_inputs(std::vector< game_logic::formula_input > *inputs) const
GLdouble s
Definition: glew.h:1358
const t_string & description() const
Definition: terrain.hpp:35
variant convert_map(const std::map< T, K > &input_map)
const unit_race * race() const
Never returns nullptr, but may point to the null race.
Definition: unit.hpp:371
static std::string write_direction(DIRECTION dir)
Definition: location.cpp:144
std::vector< std::string > get_ability_list() const
Definition: abilities.cpp:210
GLsizei const GLcharARB ** string
Definition: glew.h:4503
const std::string & icon_image() const
Definition: terrain.hpp:29
const location loc_
const std::string & id() const
The id for this unit_type.
Definition: types.hpp:115
int do_compare(const formula_callable *callable) const
std::vector< std::string > get_traits_list() const
Definition: unit.cpp:883