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) 2009 - 2016 by Bartosz Waresiak <[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 "ai/formula/ai.hpp"
16 #include "attack_prediction.hpp"
17 #include "game_board.hpp"
19 #include "resources.hpp"
20 
21 
22 namespace game_logic {
23 
25 {
26  using namespace game_logic;
27  if(key == "moves") {
28  std::vector<variant> vars;
29  for(move_map::const_iterator i = srcdst_.begin(); i != srcdst_.end(); ++i) {
30  if( i->first == i->second || units_.count(i->second) == 0) {
31  move_callable* item = new move_callable(i->first, i->second);
32  vars.push_back(variant(item));
33  }
34  }
35 
36  return variant(&vars);
37  } else if(key == "has_moves") {
38  return variant(!srcdst_.empty());
39  } else {
40  return variant();
41  }
42 }
43 
44 void move_map_callable::get_inputs(std::vector<game_logic::formula_input>* inputs) const
45 {
47  inputs->push_back(game_logic::formula_input("moves", FORMULA_READ_ONLY));
48 }
49 
50 int move_callable::do_compare(const formula_callable* callable) const
51 {
52  const move_callable* mv_callable = dynamic_cast<const move_callable*>(callable);
53  if(mv_callable == nullptr) {
54  return formula_callable::do_compare(callable);
55  }
56 
57  const map_location& other_src = mv_callable->src_;
58  const map_location& other_dst = mv_callable->dst_;
59 
60  if (int cmp = src_.do_compare(other_src)) {
61  return cmp;
62  }
63 
64  return dst_.do_compare(other_dst);
65 }
66 
68 {
69  const move_partial_callable* mv_callable = dynamic_cast<const move_partial_callable*>(callable);
70  if(mv_callable == nullptr) {
71  return formula_callable::do_compare(callable);
72  }
73 
74  const map_location& other_src = mv_callable->src_;
75  const map_location& other_dst = mv_callable->dst_;
76 
77  if (int cmp = src_.do_compare(other_src)) {
78  return cmp;
79  }
80 
81  return dst_.do_compare(other_dst);
82 }
83 
85  if(key == "chance") {
86  return variant(chance_);
87  } else {
88  return variant();
89  }
90 }
91 
92 void position_callable::get_inputs(std::vector<game_logic::formula_input>* inputs) const {
93  inputs->push_back(game_logic::formula_input("chance", game_logic::FORMULA_READ_ONLY));
94 }
95 
97  if(key == "hitpoints_left") {
98  return variant(new std::vector<variant>(hitLeft_));
99  } else if(key == "probability") {
100  return variant(new std::vector<variant>(prob_));
101  } else if(key == "possible_status") {
102  return variant(new std::vector<variant>(status_));
103  } else {
104  return variant();
105  }
106 }
107 
108 void outcome_callable::get_inputs(std::vector<game_logic::formula_input>* inputs) const {
109  inputs->push_back(game_logic::formula_input("hitpoints_left", game_logic::FORMULA_READ_ONLY));
110  inputs->push_back(game_logic::formula_input("probability", game_logic::FORMULA_READ_ONLY));
111  inputs->push_back(game_logic::formula_input("possible_status", game_logic::FORMULA_READ_ONLY));
112 }
113 
114 
116  const map_location& src, const map_location& dst, int weapon)
117  : move_from_(move_from), src_(src), dst_(dst),
118  bc_(*resources::units, src, dst, weapon, -1, 1.0, nullptr,
119  &*resources::units->find(move_from))
120 {
121  type_ = ATTACK_C;
122 }
123 
124 
126  if(key == "attack_from") {
127  return variant(new location_callable(src_));
128  } else if(key == "defender") {
129  return variant(new location_callable(dst_));
130  } else if(key == "move_from") {
131  return variant(new location_callable(move_from_));
132  } else {
133  return variant();
134  }
135 }
136 
137 void attack_callable::get_inputs(std::vector<game_logic::formula_input>* inputs) const {
138  inputs->push_back(game_logic::formula_input("attack_from", game_logic::FORMULA_READ_ONLY));
139  inputs->push_back(game_logic::formula_input("defender", game_logic::FORMULA_READ_ONLY));
140  inputs->push_back(game_logic::formula_input("move_from", game_logic::FORMULA_READ_ONLY));
141 }
142 
144  const {
145  const attack_callable* a_callable = dynamic_cast<const attack_callable*>(callable);
146  if(a_callable == nullptr) {
147  return formula_callable::do_compare(callable);
148  }
149 
150  const map_location& other_from = a_callable->move_from();
151 
152  if (int cmp = move_from_.do_compare(other_from)) {
153  return cmp;
154  }
155  const map_location& other_src = a_callable->src();
156  if (int cmp = src_.do_compare(other_src)) {
157  return cmp;
158  }
159  const map_location& other_dst = a_callable->dst();
160  if (int cmp = dst_.do_compare(other_dst)) {
161  return cmp;
162  }
163  const int other_weapon = a_callable->weapon();
164  if (int cmp = (this->weapon() - other_weapon)) {
165  return cmp;
166  }
167  const int other_def_weapon = a_callable->defender_weapon();
168  return this->defender_weapon() - other_def_weapon;
169 }
170 
171 
173  if(key == "attacks") {
174  std::vector<variant> vars;
175  for(move_map::const_iterator i = ai_.get_srcdst().begin(); i != ai_.get_srcdst().end(); ++i) {
176  /* for each possible move check all adjacent tiles for enemies */
177  if(units_.count(i->second) == 0) {
178  collect_possible_attacks(vars, i->first, i->second);
179  }
180  }
181  /* special case, when unit moved toward enemy and can only attack */
183  if (i->side() == ai_.get_side() && i->attacks_left() > 0) {
184  collect_possible_attacks(vars, i->get_location(), i->get_location());
185  }
186  }
187  return variant(&vars);
188  } else {
189  return variant();
190  }
191 }
192 
193 void attack_map_callable::get_inputs(std::vector<game_logic::formula_input>* inputs) const {
194  inputs->push_back(game_logic::formula_input("attacks", game_logic::FORMULA_READ_ONLY));
195 }
196 
197 /* add to vars all attacks on enemy units around <attack_position> tile. attacker_location is tile where unit is currently standing. It's moved to attack_position first and then performs attack.*/
198 void attack_map_callable::collect_possible_attacks(std::vector<variant>& vars, map_location attacker_location, map_location attack_position) const {
199  map_location adj[6];
200  get_adjacent_tiles(attack_position, adj);
201 
202  for(int n = 0; n != 6; ++n) {
203  /* if adjacent tile is outside the board */
204  if (! resources::gameboard->map().on_board(adj[n]))
205  continue;
207  /* if tile is empty */
208  if (unit == units_.end())
209  continue;
210  /* if tile is occupied by friendly or petrified/invisible unit */
211  if (!ai_.current_team().is_enemy(unit->side()) ||
212  unit->incapacitated() ||
213  unit->invisible(unit->get_location()))
214  continue;
215  /* add attacks with default weapon */
216  attack_callable* item = new attack_callable(attacker_location, attack_position, adj[n], -1);
217  vars.push_back(variant(item));
218  }
219 }
220 
221 
223  if( key == "id")
224  return variant(id_);
225  if( key == "loc")
226  return variant(new location_callable(loc_));
227  return variant();
228 }
229 
230 void recall_callable::get_inputs(std::vector<game_logic::formula_input>* inputs) const {
232  inputs->push_back(game_logic::formula_input("loc", game_logic::FORMULA_READ_ONLY));
233 }
234 
235 
236 
238  if( key == "unit_type")
239  return variant(type_);
240  if( key == "recruit_loc")
241  return variant(new location_callable(loc_));
242  return variant();
243 }
244 
245 void recruit_callable::get_inputs(std::vector<game_logic::formula_input>* inputs) const {
246  inputs->push_back(game_logic::formula_input("unit_type", game_logic::FORMULA_READ_ONLY));
247  inputs->push_back(game_logic::formula_input("recruit_loc", game_logic::FORMULA_READ_ONLY));
248 }
249 
250 
252  if(key == "key")
253  return variant(key_);
254 
255  if(key == "value")
256  return value_;
257 
258  return variant();
259 }
260 
261 void set_var_callable::get_inputs(std::vector<game_logic::formula_input>* inputs) const {
262  inputs->push_back(game_logic::formula_input("key", game_logic::FORMULA_READ_ONLY));
263  inputs->push_back(game_logic::formula_input("value", game_logic::FORMULA_READ_ONLY));
264 }
265 
266 
268  if(key == "loc")
269  return variant(new location_callable(loc_));
270 
271  if(key == "key")
272  return variant(key_);
273 
274  if(key == "value")
275  return value_;
276 
277  return variant();
278 }
279 
280 void set_unit_var_callable::get_inputs(std::vector<game_logic::formula_input>* inputs) const {
281  inputs->push_back(game_logic::formula_input("loc", game_logic::FORMULA_READ_ONLY));
282  inputs->push_back(game_logic::formula_input("key", game_logic::FORMULA_READ_ONLY));
283  inputs->push_back(game_logic::formula_input("value", game_logic::FORMULA_READ_ONLY));
284 }
285 
286 
288  if(key == "main")
289  return variant(main_);
290 
291  if(key == "backup")
292  return variant(backup_);
293 
294  return variant();
295 }
296 
297 void safe_call_callable::get_inputs(std::vector<game_logic::formula_input>* inputs) const {
298  inputs->push_back(game_logic::formula_input("main", game_logic::FORMULA_READ_ONLY));
299  inputs->push_back(game_logic::formula_input("backup", game_logic::FORMULA_READ_ONLY));
300 }
301 
302 
304  if(key == "status")
305  return variant(status_);
306 
307  if(key == "object") {
308  if( failed_callable_ != nullptr)
309  return variant(failed_callable_);
310  else
311  return variant();
312  }
313 
314  if(key == "current_loc" && current_unit_location_ != map_location())
316 
317  return variant();
318 }
319 
320 void safe_call_result::get_inputs(std::vector<game_logic::formula_input>* inputs) const {
321  inputs->push_back(game_logic::formula_input("status", game_logic::FORMULA_READ_ONLY));
322  inputs->push_back(game_logic::formula_input("object", game_logic::FORMULA_READ_ONLY));
324  inputs->push_back(game_logic::formula_input("current_loc", game_logic::FORMULA_READ_ONLY));
325 }
326 
327 }
Defines formula ai.
virtual side_number get_side() const
Get the side number.
Definition: contexts.hpp:480
variant get_value(const std::string &key) const
const formula_callable * failed_callable_
unit_iterator end()
Definition: map.hpp:311
variant get_value(const std::string &key) const
variant get_value(const std::string &key) const
Definition: unit.hpp:95
variant get_value(const std::string &key) const
int do_compare(const formula_callable *callable) const
size_t count(const map_location &loc) const
Definition: map.hpp:306
variant get_value(const std::string &key) const
void get_inputs(std::vector< game_logic::formula_input > *inputs) const
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
variant get_value(const std::string &key) const
bool is_enemy(int n) const
Definition: team.hpp:247
variant get_value(const std::string &key) const
attack_callable(const map_location &move_from, const map_location &src, const map_location &dst, int weapon)
GLenum src
Definition: glew.h:2392
const map_location & dst() const
void get_inputs(std::vector< game_logic::formula_input > *inputs) const
void get_inputs(std::vector< game_logic::formula_input > *inputs) const
GLenum GLenum dst
Definition: glew.h:2392
void get_inputs(std::vector< game_logic::formula_input > *inputs) const
game_board * gameboard
Definition: resources.cpp:20
void get_inputs(std::vector< game_logic::formula_input > *inputs) const
virtual const move_map & get_srcdst() const
Definition: contexts.hpp:854
void get_inputs(std::vector< game_logic::formula_input > *inputs) const
const map_location & move_from() const
std::vector< formula_input > inputs() const
Definition: callable.hpp:50
void get_inputs(std::vector< game_logic::formula_input > *inputs) const
Encapsulates the map of the game.
Definition: location.hpp:38
const map_location current_unit_location_
void collect_possible_attacks(std::vector< variant > &vars, map_location attacker_location, map_location attack_position) const
void get_inputs(std::vector< game_logic::formula_input > *inputs) const
variant get_value(const std::string &key) const
size_t i
Definition: function.cpp:1057
variant get_value(const std::string &key) const
const map_location & src() const
virtual int do_compare(const formula_callable *callable) const
Definition: callable.hpp:78
int do_compare(const formula_callable *callable) const
virtual const team & current_team() const
Definition: contexts.hpp:539
GLclampd n
Definition: glew.h:5903
void get_inputs(std::vector< game_logic::formula_input > *inputs) const
bool find(E event, F functor)
Tests whether an event handler is available.
variant get_value(const std::string &key) const
int do_compare(const map_location &a) const
three-way comparator
Definition: location.hpp:86
variant get_value(const std::string &key) const
int do_compare(const game_logic::formula_callable *callable) const
Compare two attacks in deterministic way or compare pointers (nondeterministic in consequent game run...
unit_iterator find(size_t id)
Definition: map.cpp:285
const std::string weapon
void get_inputs(std::vector< game_logic::formula_input > *inputs) const
void get_inputs(std::vector< game_logic::formula_input > *inputs) const
GLsizei const GLcharARB ** string
Definition: glew.h:4503
unit_map * units
Definition: resources.cpp:35