The Battle for Wesnoth  1.13.10+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 - 2017 by David White <dave@whitevine.net>
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 
17 #include "config.hpp"
18 #include "formula/function.hpp"
19 #include "map/map.hpp"
20 #include "display_context.hpp"
21 #include "team.hpp"
23 #include "log.hpp"
24 
25 static lg::log_domain log_scripting_formula("scripting/formula");
26 #define LOG_SF LOG_STREAM(info, log_scripting_formula)
27 #define ERR_SF LOG_STREAM(err, log_scripting_formula)
28 
29 namespace wfl
30 {
31 
33 {
34  if(key == "x") {
35  return variant(loc_.wml_x());
36  } else if(key == "y") {
37  return variant(loc_.wml_y());
38  }
39 
40  return variant();
41 }
42 
44 {
45  add_input(inputs, "x");
46  add_input(inputs, "y");
47 }
48 
50 {
51  const location_callable* loc_callable = dynamic_cast<const location_callable*>(callable);
52  if(loc_callable == nullptr) {
53  return formula_callable::do_compare(callable);
54  }
55 
56  const map_location& other_loc = loc_callable->loc();
57  return loc_.do_compare(other_loc);
58 }
59 
61 {
62  std::ostringstream s;
63  s << "loc(" << (loc_.wml_x()) << "," << (loc_.wml_y()) << ")";
64  str += s.str();
65 }
66 
68 {
69  if(key == "id" || key == "name") {
70  return variant(att_->id());
71  } else if(key == "description") {
72  return variant(att_->name());
73  } else if(key == "type") {
74  return variant(att_->type());
75  } else if(key == "icon") {
76  return variant(att_->icon());
77  } else if(key == "range") {
78  return variant(att_->range());
79  } else if(key == "damage") {
80  return variant(att_->damage());
81  } else if(key == "number_of_attacks" || key == "number" || key == "num_attacks" || key == "attacks") {
82  return variant(att_->num_attacks());
83  } else if(key == "attack_weight") {
84  return variant(att_->attack_weight(), variant::DECIMAL_VARIANT);
85  } else if(key == "defense_weight") {
86  return variant(att_->defense_weight(), variant::DECIMAL_VARIANT);
87  } else if(key == "accuracy") {
88  return variant(att_->accuracy());
89  } else if(key == "parry") {
90  return variant(att_->parry());
91  } else if(key == "movement_used") {
92  return variant(att_->movement_used());
93  } else if(key == "specials" || key == "special") {
94  std::vector<variant> res;
95 
96  for(const auto& special : att_->specials().all_children_range()) {
97  if(!special.cfg["id"].empty()) {
98  res.emplace_back(special.cfg["id"].str());
99  }
100  }
101  return variant(res);
102  }
103 
104  return variant();
105 }
106 
108 {
109  add_input(inputs, "name");
110  add_input(inputs, "type");
111  add_input(inputs, "description");
112  add_input(inputs, "icon");
113  add_input(inputs, "range");
114  add_input(inputs, "damage");
115  add_input(inputs, "number");
116  add_input(inputs, "accuracy");
117  add_input(inputs, "parry");
118  add_input(inputs, "movement_used");
119  add_input(inputs, "attack_weight");
120  add_input(inputs, "defense_weight");
121  add_input(inputs, "specials");
122 }
123 
125 {
126  const attack_type_callable* att_callable = dynamic_cast<const attack_type_callable*>(callable);
127  if(att_callable == nullptr) {
128  return formula_callable::do_compare(callable);
129  }
130 
131  if(att_->damage() != att_callable->att_->damage()) {
132  return att_->damage() - att_callable->att_->damage();
133  }
134 
135  if(att_->num_attacks() != att_callable->att_->num_attacks()) {
136  return att_->num_attacks() - att_callable->att_->num_attacks();
137  }
138 
139  if(att_->id() != att_callable->att_->id()) {
140  return att_->id().compare(att_callable->att_->id());
141  }
142 
143  if(att_->type() != att_callable->att_->type()) {
144  return att_->type().compare(att_callable->att_->type());
145  }
146 
147  if(att_->range() != att_callable->att_->range()) {
148  return att_->range().compare(att_callable->att_->range());
149  }
150 
151  return att_->weapon_specials().compare(att_callable->att_->weapon_specials());
152 }
153 
155 {
156  if(key == "x") {
158  return variant();
159  }
160 
161  return variant(loc_.wml_x());
162  } else if(key == "y") {
164  return variant();
165  }
166 
167  return variant(loc_.wml_y());
168  } else if(key == "loc") {
170  return variant();
171  }
172 
173  return variant(std::make_shared<location_callable>(loc_));
174  } else if(key == "id") {
175  return variant(u_.id());
176  } else if(key == "type") {
177  return variant(u_.type_id());
178  } else if(key == "name") {
179  return variant(u_.name());
180  } else if(key == "usage") {
181  return variant(u_.usage());
182  } else if(key == "leader" || key == "canrecruit") {
183  return variant(u_.can_recruit());
184  } else if(key == "undead") {
185  return variant(u_.get_state("not_living") ? 1 : 0);
186  } else if(key == "attacks") {
187  std::vector<variant> res;
188  for(const attack_type& att : u_.attacks()) {
189  res.emplace_back(std::make_shared<attack_type_callable>(att));
190  }
191 
192  return variant(res);
193  } else if(key == "abilities") {
195  } else if(key == "hitpoints") {
196  return variant(u_.hitpoints());
197  } else if(key == "max_hitpoints") {
198  return variant(u_.max_hitpoints());
199  } else if(key == "experience") {
200  return variant(u_.experience());
201  } else if(key == "max_experience") {
202  return variant(u_.max_experience());
203  } else if(key == "level" || key == "full") {
204  // This allows writing "upkeep == full"
205  return variant(u_.level());
206  } else if(key == "total_movement" || key == "max_moves") {
207  return variant(u_.total_movement());
208  } else if(key == "movement_left" || key == "moves") {
209  return variant(u_.movement_left());
210  } else if(key == "attacks_left") {
211  return variant(u_.attacks_left());
212  } else if(key == "max_attacks") {
213  return variant(u_.max_attacks());
214  } else if(key == "traits") {
216  } else if(key == "extra_recruit") {
218  } else if(key == "advances_to") {
220  } else if(key == "states" || key == "status") {
222  } else if(key == "side") {
223  return variant(u_.side()-1);
224  } else if(key == "cost") {
225  return variant(u_.cost());
226  } else if(key == "upkeep") {
227  return variant(u_.upkeep());
228  } else if(key == "loyal") {
229  // So we can write "upkeep == loyal"
230  return variant(0);
231  } else if(key == "hidden") {
232  return variant(u_.get_hidden());
233  } else if(key == "petrified") {
234  return variant(u_.incapacitated());
235  } else if(key == "resting") {
236  return variant(u_.resting());
237  } else if(key == "role") {
238  return variant(u_.get_role());
239  } else if(key == "race") {
240  return variant(u_.race()->id());
241  } else if(key == "gender") {
242  return variant(gender_string(u_.gender()));
243  } else if(key == "variation") {
244  return variant(u_.variation());
245  } else if(key == "zoc") {
246  return variant(u_.get_emit_zoc());
247  } else if(key == "alignment") {
248  return variant(u_.alignment().to_string());
249  } else if(key == "facing") {
251  } else if(key == "vars") {
254  }
255 
256  return variant();
257  } else if(key == "wml_vars") {
258  return variant(std::make_shared<config_callable>(u_.variables()));
259  } else if(key == "n" || key == "s" || key == "ne" || key == "se" || key == "nw" || key == "sw" ||
260  key == "lawful" || key == "neutral" || key == "chaotic" || key == "liminal" ||
261  key == "male" || key == "female")
262  {
263  return variant(key);
264  }
265 
266  return variant();
267 }
268 
270 {
271  add_input(inputs, "x");
272  add_input(inputs, "y");
273  add_input(inputs, "loc");
274  add_input(inputs, "id");
275  add_input(inputs, "type");
276  add_input(inputs, "name");
277  add_input(inputs, "canrecruit");
278  add_input(inputs, "undead");
279  add_input(inputs, "traits");
280  add_input(inputs, "attacks");
281  add_input(inputs, "abilities");
282  add_input(inputs, "hitpoints");
283  add_input(inputs, "max_hitpoints");
284  add_input(inputs, "experience");
285  add_input(inputs, "max_experience");
286  add_input(inputs, "level");
287  add_input(inputs, "moves");
288  add_input(inputs, "max_moves");
289  add_input(inputs, "attacks_left");
290  add_input(inputs, "max_attacks");
291  add_input(inputs, "side");
292  add_input(inputs, "extra_recruit");
293  add_input(inputs, "advances_to");
294  add_input(inputs, "status");
295  add_input(inputs, "cost");
296  add_input(inputs, "usage");
297  add_input(inputs, "upkeep");
298  add_input(inputs, "hidden");
299  add_input(inputs, "petrified");
300  add_input(inputs, "resting");
301  add_input(inputs, "role");
302  add_input(inputs, "race");
303  add_input(inputs, "gender");
304  add_input(inputs, "variation");
305  add_input(inputs, "zoc");
306  add_input(inputs, "alignment");
307  add_input(inputs, "facing");
308  add_input(inputs, "vars");
309  add_input(inputs, "wml_vars");
310 }
311 
312 int unit_callable::do_compare(const formula_callable* callable) const
313 {
314  const unit_callable* u_callable = dynamic_cast<const unit_callable*>(callable);
315  if(u_callable == nullptr) {
316  return formula_callable::do_compare(callable);
317  }
318 
319  return u_.underlying_id() - u_callable->u_.underlying_id();
320 }
321 
323 {
324  if(key == "id") {
325  return variant(u_.id());
326  } else if(key == "type") {
327  return variant(u_.type_name());
328  } else if(key == "alignment") {
329  return variant(u_.alignment().to_string());
330  } else if(key == "race") {
331  return variant(u_.race_id());
332  } else if(key == "abilities") {
334  } else if(key == "traits") {
335  std::vector<variant> res;
336  for(const auto& config : u_.possible_traits()) {
337  res.emplace_back(config["id"].str());
338  }
339 
340  return variant(res);
341  } else if(key == "attacks") {
342  std::vector<variant> res;
343  for(const attack_type& att : u_.attacks()) {
344  res.emplace_back(std::make_shared<attack_type_callable>(att));
345  }
346 
347  return variant(res);
348  } else if(key == "hitpoints" || key == "max_hitpoints") {
349  return variant(u_.hitpoints());
350  } else if(key == "experience" || key == "max_experience") {
351  return variant(u_.experience_needed(true));
352  } else if(key == "level") {
353  return variant(u_.level());
354  } else if(key == "total_movement" || key == "max_moves" || key == "moves") {
355  return variant(u_.movement());
356  } else if(key == "unpoisonable") {
357  return variant(u_.musthave_status("unpoisonable"));
358  } else if(key == "undrainable") {
359  return variant(u_.musthave_status("undrainable"));
360  } else if(key == "unplagueable") {
361  return variant(u_.musthave_status("unplagueable"));
362  } else if(key == "cost") {
363  return variant(u_.cost());
364  } else if(key == "recall_cost") {
365  return variant(u_.recall_cost());
366  } else if(key == "usage") {
367  return variant(u_.usage());
368  }
369 
370  return variant();
371 }
372 
374 {
375  add_input(inputs, "id");
376  add_input(inputs, "type");
377  add_input(inputs, "race");
378  add_input(inputs, "alignment");
379  add_input(inputs, "abilities");
380  add_input(inputs, "traits");
381  add_input(inputs, "attacks");
382  add_input(inputs, "hitpoints");
383  add_input(inputs, "experience");
384  add_input(inputs, "level");
385  add_input(inputs, "total_movement");
386  add_input(inputs, "undead");
387  add_input(inputs, "cost");
388  add_input(inputs, "recall_cost");
389  add_input(inputs, "usage");
390 }
391 
393 {
394  const unit_type_callable* u_callable = dynamic_cast<const unit_type_callable*>(callable);
395  if(u_callable == nullptr) {
396  return formula_callable::do_compare(callable);
397  }
398 
399  return u_.id().compare(u_callable->u_.id());
400 }
401 
402 struct fai_variant_visitor : public boost::static_visitor<variant>
403 {
404  variant operator()(bool b) const { return variant(b ? 1 : 0); }
405  variant operator()(int i) const { return variant(i); }
406  variant operator()(unsigned long long i) const { return variant(i); }
407  variant operator()(double i) const { return variant(i * 1000, variant::DECIMAL_VARIANT); }
408  // TODO: Should comma-separated lists of stuff be returned as a list?
409  // The challenge is to distinguish them from ordinary strings that happen to contain a comma
410  // (or should we assume that such strings will be translatable?).
411  variant operator()(const std::string& s) const { return variant(s); }
412  variant operator()(const t_string& s) const { return variant(s.str()); }
413  variant operator()(boost::blank) const { return variant(); }
414 };
415 
417 {
418  if(cfg_.has_attribute(key)) {
419  return cfg_[key].apply_visitor(fai_variant_visitor());
420  } else if(cfg_.has_child(key)) {
421  std::vector<variant> result;
422  for(const auto& child : cfg_.child_range(key)) {
423  result.emplace_back(std::make_shared<config_callable>(child));
424  }
425 
426  return variant(result);
427  } else if(key == "__all_children") {
428  std::vector<variant> result;
429  for(const auto& child : cfg_.all_children_range()) {
430  const variant cfg_child(std::make_shared<config_callable>(child.cfg));
431  const variant kv(std::make_shared<key_value_pair>(variant(child.key), cfg_child));
432  result.push_back(kv);
433  }
434 
435  return variant(result);
436  } else if(key == "__children") {
437  std::map<std::string, std::vector<variant> > build;
438  for(const auto& child : cfg_.all_children_range()) {
439  const variant cfg_child(std::make_shared<config_callable>(child.cfg));
440  build[child.key].push_back(cfg_child);
441  }
442 
443  std::map<variant,variant> result;
444  for(auto& p : build) {
445  result[variant(p.first)] = variant(p.second);
446  }
447 
448  return variant(result);
449  } else if(key == "__attributes") {
450  std::map<variant,variant> result;
451  for(const auto& val : cfg_.attribute_range()) {
452  result[variant(val.first)] = val.second.apply_visitor(fai_variant_visitor());
453  }
454 
455  return variant(result);
456  }
457 
458  return variant();
459 }
460 
462 {
463  add_input(inputs, "__all_children");
464  add_input(inputs, "__children");
465  add_input(inputs, "__attributes");
466 
467  for(const auto& val : cfg_.attribute_range()) {
468  if(val.first.find_first_not_of(formula::id_chars) != std::string::npos) {
469  add_input(inputs, val.first);
470  }
471  }
472 }
473 
475 {
476  const config_callable* cfg_callable = dynamic_cast<const config_callable*>(callable);
477  if(cfg_callable == nullptr) {
478  return formula_callable::do_compare(callable);
479  }
480 
481  if(cfg_ == cfg_callable->get_config()) {
482  return 0;
483  }
484 
485  return cfg_.hash().compare(cfg_callable->get_config().hash());
486 }
487 
488 terrain_callable::terrain_callable(const display_context& dc, const map_location& loc) : loc_(loc), t_(dc.map().get_terrain_info(loc)), owner_(dc.village_owner(loc))
489 {
490  type_ = TERRAIN_C;
491 }
492 
494 {
495  if(key == "x") {
496  return variant(loc_.wml_x());
497  } else if(key == "y") {
498  return variant(loc_.wml_y());
499  } else if(key == "loc") {
500  return variant(std::make_shared<location_callable>(loc_));
501  } else if(key == "id") {
502  return variant(std::string(t_.id()));
503  } else if(key == "name") {
504  return variant(t_.name());
505  } else if(key == "editor_name") {
506  return variant(t_.editor_name());
507  } else if(key == "description") {
508  return variant(t_.description());
509  } else if(key == "icon") {
510  return variant(t_.icon_image());
511  } else if(key == "light") {
512  return variant(t_.light_bonus(0));
513  } else if(key == "village") {
514  return variant(t_.is_village());
515  } else if(key == "castle") {
516  return variant(t_.is_castle());
517  } else if(key == "keep") {
518  return variant(t_.is_keep());
519  } else if(key == "healing") {
520  return variant(t_.gives_healing());
521  } else if(key == "owner") {
522  return variant(owner_);
523  }
524 
525  return variant();
526 }
527 
529 {
530  add_input(inputs, "x");
531  add_input(inputs, "y");
532  add_input(inputs, "loc");
533  add_input(inputs, "id");
534  add_input(inputs, "name");
535  add_input(inputs, "editor_name");
536  add_input(inputs, "description");
537  add_input(inputs, "icon");
538  add_input(inputs, "light");
539  add_input(inputs, "village");
540  add_input(inputs, "castle");
541  add_input(inputs, "keep");
542  add_input(inputs, "healing");
543  add_input(inputs, "owner");
544 }
545 
547 {
548  const terrain_callable* terr_callable = dynamic_cast<const terrain_callable*>(callable);
549  if(terr_callable == nullptr) {
550  return formula_callable::do_compare(callable);
551  }
552 
553  const map_location& other_loc = terr_callable->loc_;
554  return loc_.do_compare(other_loc);
555 }
556 
558  return board_.map();
559 }
560 
562 {
563  add_input(inputs, "gamemap");
564  add_input(inputs, "terrain");
565  add_input(inputs, "w");
566  add_input(inputs, "h");
567 }
568 
570 {
571  if(key == "terrain") {
572  int w = get_gamemap().w();
573  int h = get_gamemap().h();
574 
575  std::vector<variant> vars;
576  for(int i = 0; i < w; i++) {
577  for(int j = 0; j < h; j++) {
578  const map_location loc(i, j);
579  vars.emplace_back(std::make_shared<terrain_callable>(board_, loc));
580  }
581  }
582 
583  return variant(vars);
584  } else if(key == "w") {
585  return variant(get_gamemap().w());
586  } else if(key == "h") {
587  return variant(get_gamemap().h());
588  } else {
589  return variant();
590  }
591 }
592 
594 {
595  add_input(inputs, "side");
596  add_input(inputs, "id");
597  add_input(inputs, "gold");
598  add_input(inputs, "start_gold");
599  add_input(inputs, "base_income");
600  add_input(inputs, "total_income");
601  add_input(inputs, "village_gold");
602  add_input(inputs, "village_support");
603  add_input(inputs, "recall_cost");
604  add_input(inputs, "name");
605  add_input(inputs, "is_human");
606  add_input(inputs, "is_ai");
607  add_input(inputs, "is_network");
608  add_input(inputs, "fog");
609  add_input(inputs, "shroud");
610  add_input(inputs, "hidden");
611  add_input(inputs, "flag");
612  add_input(inputs, "flag_icon");
613  add_input(inputs, "team_name");
614  add_input(inputs, "faction");
615  add_input(inputs, "faction_name");
616  add_input(inputs, "color");
617  add_input(inputs, "share_vision");
618  add_input(inputs, "carryover_bonus");
619  add_input(inputs, "carryover_percentage");
620  add_input(inputs, "carryover_add");
621  add_input(inputs, "recruit");
622  add_input(inputs, "wml_vars");
623 }
624 
626 {
627  if(key == "side") {
628  return variant(team_.side());
629  } else if(key == "id") {
630  return variant(team_.save_id());
631  } else if(key == "save_id") {
632  return variant(team_.save_id());
633  } else if(key == "gold") {
634  return variant(team_.gold());
635  } else if(key == "start_gold") {
636  return variant(team_.start_gold());
637  } else if(key == "base_income") {
638  return variant(team_.base_income());
639  } else if(key == "total_income") {
640  return variant(team_.total_income());
641  } else if(key == "village_gold") {
642  return variant(team_.village_gold());
643  } else if(key == "village_support") {
644  return variant(team_.village_support());
645  } else if(key == "recall_cost") {
646  return variant(team_.recall_cost());
647  } else if(key == "is_human") {
648  return variant(team_.is_local_human());
649  } else if(key == "is_ai") {
650  return variant(team_.is_local_ai());
651  } else if(key == "is_network") {
652  return variant(team_.is_network());
653  } else if(key == "fog") {
654  return variant(team_.uses_fog());
655  } else if(key == "shroud") {
656  return variant(team_.uses_shroud());
657  } else if(key == "hidden") {
658  return variant(team_.hidden());
659  } else if(key == "flag") {
660  return variant(team_.flag());
661  } else if(key == "flag_icon") {
662  return variant(team_.flag_icon());
663  } else if(key == "team_name") {
664  return variant(team_.team_name());
665  } else if(key == "color") {
666  return variant(team_.color());
667  } else if(key == "share_vision") {
668  return variant(team_.share_vision().to_string());
669  } else if(key == "carryover_bonus") {
670  return variant(team_.carryover_bonus());
671  } else if(key == "carryover_percentage") {
673  } else if(key == "carryover_add") {
674  return variant(team_.carryover_add());
675  } else if(key == "recruit") {
676  std::vector<variant> result;
677  for(const auto& recruit : team_.recruits()) {
678  result.emplace_back(recruit);
679  }
680 
681  return variant(result);
682  } else if(key == "wml_vars") {
683  return variant(std::make_shared<config_callable>(team_.variables()));
684  }
685 
686  return variant();
687 }
688 
690 {
691  if(key == "key") {
692  return variant(key_);
693  } else if(key == "value") {
694  return value_;
695  }
696 
697  return variant();
698 }
699 
701 {
702  add_input(inputs, "key");
703  add_input(inputs, "value");
704 }
705 
707 {
708  //if(infinite_loop_guardian_.set_var_check()) {
709  if(auto obj = ctxt.try_convert<formula_callable>()) {
710  LOG_SF << "Setting variable: " << key_ << " -> " << value_.to_debug_string() << "\n";
711  obj->mutate_value(key_, value_);
712  return variant(true);
713  }
714  //}
715  //too many calls in a row - possible infinite loop
716  ERR_SF << "ERROR #" << 5001 << " while executing 'set_var' formula function" << std::endl;
717 
718  return variant(std::make_shared<safe_call_result>(fake_ptr(), 5001));
719 }
720 
722 {
723  if(key == "main") {
724  return variant(main_);
725  } else if(key == "backup") {
726  return variant(backup_);
727  }
728 
729  return variant();
730 }
731 
733 {
734  add_input(inputs, "main");
735  add_input(inputs, "backup");
736 }
737 
739 {
740  variant res;
741  if(auto action = main_.try_convert<action_callable>()) {
742  res = action->execute_self(ctxt);
743  }
744 
745  if(res.try_convert<safe_call_result>()) {
746  /* If we have safe_call formula and either an error occurred, or the current action
747  * was not recognized, then evaluate backup formula from safe_call and execute it
748  * during the next loop
749  */
750 
751  map_formula_callable callable(ctxt.as_callable());
752  callable.add("error", res);
753 
754  /* Store the result in safe_call_callable in case we would like to display it to the user,
755  * for example if this formula was executed from the commandline.
756  */
757  backup_ = get_backup()->evaluate(callable);
758  ctxt.execute_variant(backup_);
759  }
760  return variant(true);
761 }
762 
764 {
765  if(key == "status") {
766  return variant(status_);
767  } else if(key == "object") {
768  if(failed_callable_) {
769  return variant(failed_callable_);
770  }
771 
772  return variant();
773  } else if(key == "current_loc" && current_unit_location_ != map_location()) {
774  return variant(std::make_shared<location_callable>(current_unit_location_));
775  }
776 
777  return variant();
778 }
779 
781 {
782  add_input(inputs, "status");
783  add_input(inputs, "object");
784 
786  add_input(inputs, "current_loc");
787  }
788 }
789 
790 } // namespace wfl
variant execute_variant(const variant &to_exec)
Definition: variant.cpp:659
variant get_value(const std::string &key) const override
bool uses_shroud() const
Definition: team.hpp:312
bool is_local_ai() const
Definition: team.hpp:265
bool is_network() const
Definition: team.hpp:259
const std::string & flag() const
Definition: team.hpp:298
const_formula_callable_ptr as_callable() const
Definition: variant.hpp:79
const std::string & get_role() const
Gets this unit's role.
Definition: unit.hpp:532
int total_movement() const
The maximum moves this unit has.
Definition: unit.hpp:1058
std::string usage() const
Gets this unit's usage.
Definition: unit.hpp:549
std::vector< char_t > string
bool incapacitated() const
Check if the unit has been petrified.
Definition: unit.hpp:764
int start_gold() const
Definition: team.hpp:189
void get_inputs(formula_input_vector &inputs) const override
const std::string & color() const
Definition: team.hpp:254
const t_string & type_name() const
The name of the unit in the current language setting.
Definition: types.hpp:137
void get_inputs(formula_input_vector &inputs) const override
variant get_value(const std::string &key) const override
int movement() const
Definition: types.hpp:153
const gamemap & get_gamemap() const
const std::string & variation() const
The ID of the variation of this unit's type.
Definition: unit.hpp:454
const std::set< std::string > & recruits() const
Definition: team.hpp:222
bool musthave_status(const std::string &status) const
Definition: types.cpp:694
variant get_value(const std::string &key) const override
const display_context & board_
bool hidden() const
Definition: team.hpp:341
int upkeep() const
Gets the amount of gold this unit costs a side per turn.
Definition: unit.cpp:1520
bool get_emit_zoc() const
Gets the raw zone-of-control flag, disregarding incapacitated.
Definition: unit.hpp:1130
int movement_left() const
Gets how far a unit can move, considering the incapacitated flag.
Definition: unit.hpp:1068
bool get_hidden() const
Gets whether this unit is currently hidden on the map.
Definition: unit.hpp:581
const_attack_itors attacks() const
Definition: types.cpp:492
double carryover_bonus() const
Definition: team.hpp:353
child_itors child_range(config_key_type key)
Definition: config.cpp:295
config & variables()
Gets any user-defined variables this unit 'owns'.
Definition: unit.hpp:566
variant operator()(const std::string &s) const
const std::vector< std::string > & advances_to() const
Gets the possible types this unit can advance to on level-up.
Definition: unit.hpp:145
variant operator()(bool b) const
std::vector< std::string > get_ability_list() const
Definition: types.cpp:565
int level() const
The current level of this unit.
Definition: unit.hpp:442
const std::string & id() const
Definition: race.hpp:32
const std::vector< std::string > & recruits() const
The type IDs of the other units this unit may recruit, if possible.
Definition: unit.hpp:494
std::vector< formula_input > formula_input_vector
const t_string & name() const
Definition: terrain.hpp:33
void get_inputs(formula_input_vector &inputs) const override
const std::string & id() const
Definition: terrain.hpp:37
int attacks_left() const
Gets the remaining number of attacks this unit can perform this turn.
Definition: unit.hpp:845
static variant convert_set(const std::set< T > &input_set)
Definition: callable.hpp:114
#define h
#define ERR_SF
int wml_y() const
Definition: location.hpp:116
map_location::DIRECTION facing() const
The current directin this unit is facing within its hex.
Definition: unit.hpp:1158
void get_inputs(formula_input_vector &inputs) const override
variant operator()(int i) const
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
void get_inputs(formula_input_vector &inputs) const override
const std::string & type_id() const
The id of this unit's type.
Definition: unit.hpp:268
-file sdl_utils.hpp
int level() const
Definition: types.hpp:151
int cost() const
How much gold is required to recruit this unit.
Definition: unit.hpp:503
Definitions for the interface to Wesnoth Markup Language (WML).
const t_string & editor_name() const
Definition: terrain.hpp:34
virtual const gamemap & map() const =0
unit_formula_manager & formula_manager() const
Get the unit formula manager.
Definition: unit.hpp:1529
static lg::log_domain log_scripting_formula("scripting/formula")
variant operator()(boost::blank) const
const unit_race * race() const
Gets this unit's race.
Definition: unit.hpp:388
SHARE_VISION share_vision() const
Definition: team.hpp:384
map_location loc_
#define b
const_formula_callable_ptr failed_callable_
int max_experience() const
The max number of experience points this unit can have.
Definition: unit.hpp:418
variant get_value(const std::string &key) const override
void get_inputs(formula_input_vector &inputs) const override
variant execute_self(variant ctxt) override
int recall_cost() const
Definition: team.hpp:192
const std::string & flag_icon() const
Definition: team.hpp:299
int do_compare(const formula_callable *callable) const override
int wml_x() const
Definition: location.hpp:115
int gives_healing() const
Definition: terrain.hpp:61
int village_support() const
Definition: team.hpp:198
config & variables()
Definition: team.hpp:356
map_formula_callable & add(const std::string &key, const variant &value)
Definition: callable.hpp:252
const std::string & id() const
Gets this unit's id.
Definition: unit.hpp:285
int hitpoints() const
The current number of hitpoints this unit has.
Definition: unit.hpp:394
int carryover_percentage() const
Definition: team.hpp:349
int base_income() const
Definition: team.hpp:190
int do_compare(const formula_callable *callable) const override
int w() const
Effective map width.
Definition: map.hpp:90
std::shared_ptr< T > try_convert() const
Definition: variant.hpp:86
size_t underlying_id() const
This unit's unique internal ID.
Definition: unit.hpp:297
const t_string & name() const
Gets this unit's translatable display name.
Definition: unit.hpp:308
unit_race::GENDER gender() const
The gender of this unit.
Definition: unit.hpp:361
Encapsulates the map of the game.
Definition: map.hpp:34
int do_compare(const formula_callable *callable) const override
const std::string & team_name() const
Definition: team.hpp:294
int max_hitpoints() const
The max number of hitpoints this unit can have.
Definition: unit.hpp:400
bool is_local_human() const
Definition: team.hpp:264
int max_attacks() const
The maximum number of attacks this unit may perform per turn, usually 1.
Definition: unit.hpp:835
const config & get_config() const
virtual int do_compare(const formula_callable *callable) const
Definition: callable.hpp:145
void serialize_to_string(std::string &str) const override
window * build(CVideo &video, const builder_window::window_resolution *definition)
Builds a window.
std::vector< std::string > get_ability_list() const
Get a list of all abilities by ID.
Definition: abilities.cpp:219
static const map_location & null_location()
Definition: location.hpp:220
int experience() const
The current number of experience points this unit has.
Definition: unit.hpp:412
bool is_village() const
Definition: terrain.hpp:62
variant get_value(const std::string &key) const override
void get_inputs(formula_input_vector &inputs) const override
const std::string & save_id() const
Definition: team.hpp:230
std::string race_id() const
Returns the ID of this type's race without the need to build the type.
Definition: types.hpp:244
const map_location & loc_
variant get_value(const std::string &key) const override
const std::string & gender_string(unit_race::GENDER gender)
Definition: race.cpp:130
void get_inputs(formula_input_vector &inputs) const override
int cost() const
Definition: types.hpp:159
#define LOG_SF
const expression_ptr & get_backup() const
bool has_child(config_key_type key) const
Determine whether a config has a child or not.
Definition: config.cpp:345
Encapsulates the map of the game.
Definition: location.hpp:40
bool has_attribute(config_key_type key) const
Definition: config.cpp:196
const std::string & usage() const
Definition: types.hpp:162
formula_callable_ptr fake_ptr()
Definition: callable.hpp:41
int h() const
Effective map height.
Definition: map.hpp:93
bool is_keep() const
Definition: terrain.hpp:64
mock_party p
config::const_child_itors possible_traits() const
Definition: types.hpp:205
int do_compare(const formula_callable *callable) const override
const wfl::map_formula_callable_ptr & formula_vars() const
const_attr_itors attribute_range() const
Definition: config.cpp:688
static map_location::DIRECTION s
void get_inputs(formula_input_vector &inputs) const override
void get_inputs(formula_input_vector &inputs) const override
bool get_state(const std::string &state) const
Check if the unit is affected by a status effect.
Definition: unit.cpp:1286
variant get_value(const std::string &key) const override
const map_location loc_
variant get_value(const std::string &key) const override
attack_itors attacks()
Gets an iterator over this unit's attacks.
Definition: unit.hpp:786
const terrain_type & t_
#define i
bool can_recruit() const
Whether this unit can recruit other units - ie, are they a leader unit.
Definition: unit.hpp:482
int w
int side() const
Definition: team.hpp:187
variant get_value(const std::string &key) const override
variant operator()(double i) const
int hitpoints() const
Definition: types.hpp:148
int experience_needed(bool with_acceleration=true) const
Definition: types.cpp:526
std::string hash() const
Definition: config.cpp:1176
static const char *const id_chars
Definition: formula.hpp:74
int gold() const
Definition: team.hpp:188
variant operator()(unsigned long long i) const
Definition: contexts.hpp:42
int do_compare(const formula_callable *callable) const override
bool uses_fog() const
Definition: team.hpp:313
const map_location & loc() const
variant get_value(const std::string &key) const override
Standard logging facilities (interface).
unit_type::ALIGNMENT alignment() const
The alignment of this unit.
Definition: unit.hpp:371
static variant convert_vector(const std::vector< T > &input_vector)
Definition: callable.hpp:125
std::string to_debug_string(bool verbose=false, formula_seen_stack *seen=nullptr) const
Definition: variant.cpp:649
const std::set< std::string > get_states() const
Get the status effects currently affecting the unit.
Definition: unit.cpp:1269
variant execute_self(variant ctxt) override
int do_compare(const map_location &a) const
three-way comparator
Definition: location.hpp:88
bool carryover_add() const
Definition: team.hpp:351
terrain_callable(const display_context &m, const map_location &loc)
int total_income() const
Definition: team.hpp:195
static void add_input(formula_input_vector &inputs, const std::string &key, FORMULA_ACCESS_TYPE access_type=FORMULA_READ_ONLY)
Definition: callable.hpp:135
int recall_cost() const
Definition: types.hpp:152
const std::string & str() const
Definition: tstring.hpp:186
void get_inputs(formula_input_vector &inputs) const override
int do_compare(const formula_callable *callable) const override
variant get_value(const std::string &key) const override
int village_gold() const
Definition: team.hpp:191
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:93
bool is_castle() const
Definition: terrain.hpp:63
bool resting() const
Checks whether this unit is 'resting'.
Definition: unit.hpp:1112
const map_location current_unit_location_
const t_string & description() const
Definition: terrain.hpp:35
static std::string write_direction(DIRECTION dir)
Definition: location.cpp:139
const_all_children_itors all_children_range() const
In-order iteration over all children.
Definition: config.cpp:787
int side() const
The side this unit belongs to.
Definition: unit.hpp:245
const std::string & icon_image() const
Definition: terrain.hpp:29
const std::string & id() const
The id for this unit_type.
Definition: types.hpp:140
std::vector< std::string > get_traits_list() const
Gets a list of the traits this unit currently has.
Definition: unit.cpp:862
variant operator()(const t_string &s) const