The Battle for Wesnoth  1.15.0-dev
actions.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2018 by Yurii Chernyi <terraninfo@terraninfo.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 /**
16  * Managing the AI-Game interaction - AI actions and their results
17  * @file
18  * */
19 
20 #pragma once
21 
22 #include "actions/move.hpp"
23 #include "ai/game_info.hpp"
25 #include "units/ptr.hpp"
26 
27 namespace pathfind
28 {
29 struct plain_route;
30 } // of namespace pathfind
31 
32 class unit;
33 class unit_type;
34 class team;
35 
36 namespace ai
37 {
39 {
40  // Manage gamestate changed in simulated actions.
41  friend void sim_gamestate_changed(action_result* result, bool gamestate_changed);
42 
43 public:
44  enum result {
45  AI_ACTION_SUCCESS = 0,
46  AI_ACTION_STARTED = 1,
47  AI_ACTION_FAILURE = -1
48  };
49 
50  virtual ~action_result();
51 
52  /* check as must as possible without executing anything */
53  void check_before();
54 
55  /* execute the action */
56  void execute();
57 
58  /* has the game state changed during execution ? */
59  bool is_gamestate_changed() const;
60 
61  /* check the return value of the action. mandatory to call. */
62  bool is_ok();
63 
64  /* get the return value of the action */
65  int get_status() const;
66 
67  /* describe the action */
68  virtual std::string do_describe() const = 0;
69 
70 protected:
72 
73  /* do check before execution or just check. setting status_ via set_error to != cancels the execution.*/
74  virtual void do_check_before() = 0;
75 
76  /* do some additional checks after execution. */
77  virtual void do_check_after() = 0;
78 
79  /* execute. assert(is_success()) */
80  virtual void do_execute() = 0;
81 
82  /* runs before cheching before execution */
83  virtual void do_init_for_execution() = 0;
84 
85  /* are we going to execute the action now ? */
86  bool is_execution() const;
87 
88  /* return the side number */
89  int get_side() const
90  {
91  return side_;
92  }
93 
94  /* return real information about the game state */
95  game_info& get_info() const;
96 
97  team& get_my_team() const;
98 
99  /* set error code */
100  void set_error(int error_code, bool log_as_error = true);
101 
102  /* is error code equal to 0 (no errors)? */
103  bool is_success() const;
104 
105  /* note that the game state has been changed */
106  void set_gamestate_changed();
107 
108 private:
109  /* Check after the execution */
110  void check_after();
111 
112  /* Initialization before execution */
113  void init_for_execution();
114 
115  /* set the flag that the return value had been checked */
116  void set_ok_checked();
117 
118  /* was the return value checked ? */
120 
121  /* current side number */
122  int side_;
123 
124  /* execution status. if 0, all is ok. if !=0, then there were some problems. */
125  int status_;
126 
127  /* are we going to execute the action now ? */
129 
131 };
132 
134 {
135 public:
137  const map_location& attacker_loc,
138  const map_location& defender_loc,
139  int attacker_weapon,
140  double aggression,
141  const unit_advancements_aspect& advancements = unit_advancements_aspect());
142 
143  enum result {
144  E_EMPTY_ATTACKER = 1001,
145  E_EMPTY_DEFENDER = 1002,
146  E_INCAPACITATED_ATTACKER = 1003,
147  E_INCAPACITATED_DEFENDER = 1004,
148  E_NOT_OWN_ATTACKER = 1005,
149  E_NOT_ENEMY_DEFENDER = 1006,
150  E_NO_ATTACKS_LEFT = 1007,
151  E_WRONG_ATTACKER_WEAPON = 1008,
152  E_UNABLE_TO_CHOOSE_ATTACKER_WEAPON = 1009,
153  E_ATTACKER_AND_DEFENDER_NOT_ADJACENT = 1010
154  };
155 
156  virtual std::string do_describe() const;
157 
158 protected:
159  virtual void do_check_before();
160  virtual void do_check_after();
161  virtual void do_execute();
162  virtual void do_init_for_execution();
163 
164 private:
168  double aggression_;
170 };
171 
173 {
174 public:
176  const map_location& from,
177  const map_location& to,
178  bool remove_movement,
179  bool unreach_is_ok);
180 
181  enum result {
182  E_EMPTY_MOVE = 2001,
183  E_NO_UNIT = 2002,
184  E_NOT_OWN_UNIT = 2003,
185  E_INCAPACITATED_UNIT = 2004,
186  E_AMBUSHED = 2005,
187  E_FAILED_TELEPORT = 2006,
188  E_NOT_REACHED_DESTINATION = 2007,
189  E_NO_ROUTE = 2008
190  };
191 
192  virtual std::string do_describe() const;
193  virtual const map_location& get_unit_location() const;
194 
195 protected:
196  virtual void do_check_before();
197  virtual void do_check_after();
198  virtual void do_execute();
199  virtual void do_init_for_execution();
200 
201 private:
202  const unit* get_unit();
203  bool test_route(const unit& un);
207  std::shared_ptr<pathfind::plain_route> route_;
212 };
213 
215 {
216 public:
217  recall_result(side_number side, const std::string& unit_id, const map_location& where, const map_location& from);
218 
219  enum result {
220  E_NOT_AVAILABLE_FOR_RECALLING = 6001,
221  E_NO_GOLD = 6003,
222  E_NO_LEADER = 6004,
223  E_LEADER_NOT_ON_KEEP = 6005,
224  E_BAD_RECALL_LOCATION = 6006
225  };
226 
227  virtual std::string do_describe() const;
228 
229 protected:
230  virtual void do_check_before();
231  virtual void do_check_after();
232  virtual void do_execute();
233  virtual void do_init_for_execution();
234 
235 private:
236  unit_const_ptr get_recall_unit(const team& my_team);
237  bool test_enough_gold(const team& my_team);
238 
239  const std::string& unit_id_;
244 };
245 
247 {
248 public:
249  recruit_result(side_number side, const std::string& unit_name, const map_location& where, const map_location& from);
250 
251  enum result {
252  E_NOT_AVAILABLE_FOR_RECRUITING = 3001,
253  E_UNKNOWN_OR_DUMMY_UNIT_TYPE = 3002,
254  E_NO_GOLD = 3003,
255  E_NO_LEADER = 3004,
256  E_LEADER_NOT_ON_KEEP = 3005,
257  E_BAD_RECRUIT_LOCATION = 3006
258  };
259 
260  virtual std::string do_describe() const;
261 
262 protected:
263  virtual void do_check_before();
264  virtual void do_check_after();
265  virtual void do_execute();
266  virtual void do_init_for_execution();
267 
268 private:
269  const unit_type* get_unit_type_known(const std::string& recruit);
270  bool test_enough_gold(const team& my_team, const unit_type& type);
271 
272  const std::string& unit_name_;
277 };
278 
280 {
281 public:
282  stopunit_result(side_number side, const map_location& unit_location, bool remove_movement, bool remove_attacks);
283 
284  enum result {
285  E_NO_UNIT = 4002,
286  E_NOT_OWN_UNIT = 4003,
287  E_INCAPACITATED_UNIT = 4004
288  };
289 
290  virtual std::string do_describe() const;
291 
292 protected:
293  virtual void do_check_before();
294  virtual void do_check_after();
295  virtual void do_execute();
296  virtual void do_init_for_execution();
297 
298 private:
299  const unit* get_unit();
301  const bool remove_movement_;
302  const bool remove_attacks_;
303 };
304 
306 {
307 public:
308  synced_command_result(side_number side, const std::string& lua_code, const map_location& location);
309 
310  virtual std::string do_describe() const;
311 
312 protected:
313  virtual void do_check_before();
314  virtual void do_check_after();
315  virtual void do_execute();
316  virtual void do_init_for_execution();
317 
318 private:
319  const std::string& lua_code_;
321 };
322 
323 class actions
324 {
325 public:
326  // =======================================================================
327  // Stateless interface to actions
328  // =======================================================================
329 
330  /**
331  * Ask the game to attack an enemy defender using our unit attacker from attackers current location,
332  * @param side the side which tries to execute the move
333  * @param execute should move be actually executed or not
334  * @param attacker_loc location of attacker
335  * @param defender_loc location of defender
336  * @param attacker_weapon weapon of attacker
337  * @param aggression aggression of attacker, is used to determine attacker's weapon if it is not specified
338  * @retval possible result: ok
339  * @retval possible result: something wrong
340  * @retval possible result: attacker and/or defender are invalid
341  * @retval possible result: attacker doesn't have the specified weapon
342  */
343  static attack_result_ptr execute_attack_action(side_number side,
344  bool execute,
345  const map_location& attacker_loc,
346  const map_location& defender_loc,
347  int attacker_weapon,
348  double aggression,
349  const unit_advancements_aspect& advancements = unit_advancements_aspect());
350 
351  /**
352  * Ask the game to move our unit from location 'from' to location 'to', optionally - doing a partial move
353  * @param side the side which tries to execute the move
354  * @param execute should move be actually executed or not
355  * @param from location of our unit
356  * @param to where to move
357  * @param remove_movement set unit movement to 0 in case of successful move
358  * @retval possible result: ok
359  * @retval possible result: something wrong
360  * @retval possible result: move is interrupted
361  * @retval possible result: move is impossible
362  */
363  static move_result_ptr execute_move_action(side_number side,
364  bool execute,
365  const map_location& from,
366  const map_location& to,
367  bool remove_movement,
368  bool unreach_is_ok = false);
369 
370  /**
371  * Ask the game to recall a unit for us on specified location
372  * @param side the side which tries to execute the move
373  * @param execute should move be actually executed or not
374  * @param unit_id the id of the unit to be recalled.
375  * @param where location where the unit is to be recalled.
376  * @retval possible result: ok
377  * @retval possible_result: something wrong
378  * @retval possible_result: leader not on keep
379  * @retval possible_result: no free space on keep
380  * @retval possible_result: not enough gold
381  */
382  static recall_result_ptr execute_recall_action(side_number side,
383  bool execute,
384  const std::string& unit_id,
385  const map_location& where,
386  const map_location& from);
387 
388  /**
389  * Ask the game to recruit a unit for us on specified location
390  * @param side the side which tries to execute the move
391  * @param execute should move be actually executed or not
392  * @param unit_name the name of the unit to be recruited.
393  * @param where location where the unit is to be recruited.
394  * @retval possible result: ok
395  * @retval possible_result: something wrong
396  * @retval possible_result: leader not on keep
397  * @retval possible_result: no free space on keep
398  * @retval possible_result: not enough gold
399  */
400  static recruit_result_ptr execute_recruit_action(side_number side,
401  bool execute,
402  const std::string& unit_name,
403  const map_location& where,
404  const map_location& from);
405 
406  /**
407  * Ask the game to remove unit movements and/or attack
408  * @param side the side which tries to execute the move
409  * @param execute should move be actually executed or not
410  * @param unit_location the location of our unit
411  * @param remove_movement set remaining movements to 0
412  * @param remove_attacks set remaining attacks to 0
413  * @retval possible result: ok
414  * @retval possible_result: something wrong
415  * @retval possible_result: nothing to do
416  */
417  static stopunit_result_ptr execute_stopunit_action(side_number side,
418  bool execute,
419  const map_location& unit_location,
420  bool remove_movement,
421  bool remove_attacks);
422 
423  /**
424  * Ask the game to run Lua code
425  * @param side the side which tries to execute the move
426  * @param execute should move be actually executed or not
427  * @param lua_code the code to be run
428  * @param location location to be passed to the code as x1/y1
429  * @retval possible result: ok
430  * @retval possible_result: something wrong
431  * @retval possible_result: nothing to do
432  */
433  static synced_command_result_ptr execute_synced_command_action(
434  side_number side, bool execute, const std::string& lua_code, const map_location& location);
435 
436  /**
437  * get human-readable name of the error by code.
438  * @param error_code error code.
439  * @retval result the name of the error.
440  */
441  const static std::string& get_error_name(int error_code);
442 
443 private:
444  static std::map<int, std::string> error_names_;
445 };
446 
447 ///@todo 1.7.11 important! Add an ai action (and fai function) to set a goto on a unit
448 ///@todo 1.7.11 important! Add an ai action (and fai function) to send a chat message to a player
449 
450 } // end of namespace ai
451 
452 std::ostream& operator<<(std::ostream& s, const ai::attack_result& r);
453 std::ostream& operator<<(std::ostream& s, const ai::move_result& r);
454 std::ostream& operator<<(std::ostream& s, const ai::recall_result& r);
455 std::ostream& operator<<(std::ostream& s, const ai::recruit_result& r);
456 std::ostream& operator<<(std::ostream& s, const ai::stopunit_result& r);
457 std::ostream& operator<<(std::ostream& s, const ai::synced_command_result& r);
bool unreach_is_ok_
Definition: actions.hpp:209
map_location recruit_location_
Definition: actions.hpp:274
boost::intrusive_ptr< const unit > unit_const_ptr
Definition: ptr.hpp:30
map_location recruit_from_
Definition: actions.hpp:275
bool has_ambusher_
Definition: actions.hpp:210
bool remove_movement_
Definition: actions.hpp:206
map_location recall_from_
Definition: actions.hpp:242
This class represents a single unit of a specific type.
Definition: unit.hpp:99
static std::map< int, std::string > error_names_
Definition: actions.hpp:444
map_location unit_location_
Definition: actions.hpp:208
map_location recall_location_
Definition: actions.hpp:241
const map_location & where_
Definition: actions.hpp:273
const std::string & unit_id_
Definition: actions.hpp:239
const unit_advancements_aspect & advancements_
Definition: actions.hpp:169
int get_side() const
Definition: actions.hpp:89
const map_location from_
Definition: actions.hpp:204
static config unit_name(const unit *u)
Definition: reports.cpp:129
const std::string & lua_code_
Definition: actions.hpp:319
bool has_interrupted_teleport_
Definition: actions.hpp:211
std::shared_ptr< pathfind::plain_route > route_
Definition: actions.hpp:207
A single unit type that the player may recruit.
Definition: types.hpp:42
This class stores all the data for a single &#39;side&#39; (in game nomenclature).
Definition: team.hpp:44
A small explanation about what&#39;s going on here: Each action has access to two game_info objects First...
Definition: actions.cpp:58
Structure which holds a single route between one location and another.
Definition: pathfind.hpp:131
bool return_value_checked_
Definition: actions.hpp:119
bool location_checked_
Definition: actions.hpp:243
std::unique_ptr< recruit_result > recruit_result_ptr
Definition: game_info.hpp:83
std::unique_ptr< recall_result > recall_result_ptr
Definition: game_info.hpp:82
double aggression_
Definition: actions.hpp:168
const bool remove_movement_
Definition: actions.hpp:301
const std::string & unit_name_
Definition: actions.hpp:272
void sim_gamestate_changed(action_result *result, bool gamestate_changed)
Definition: actions.cpp:1202
Encapsulates the map of the game.
Definition: location.hpp:42
Various functions related to moving units.
const bool remove_attacks_
Definition: actions.hpp:302
const map_location & defender_loc_
Definition: actions.hpp:166
Game information for the AI.
std::unique_ptr< synced_command_result > synced_command_result_ptr
Definition: game_info.hpp:87
std::unique_ptr< attack_result > attack_result_ptr
Definition: game_info.hpp:81
static map_location::DIRECTION s
std::unique_ptr< stopunit_result > stopunit_result_ptr
Definition: game_info.hpp:86
bool is_gamestate_changed_
Definition: actions.hpp:130
const map_location & unit_location_
Definition: actions.hpp:300
std::ostream & operator<<(std::ostream &s, const ai::attack_result &r)
Definition: actions.cpp:1212
const map_location to_
Definition: actions.hpp:205
std::unique_ptr< move_result > move_result_ptr
Definition: game_info.hpp:84
int side_number
Definition: game_info.hpp:39
const map_location where_
Definition: actions.hpp:240
const map_location & attacker_loc_
Definition: actions.hpp:165
const map_location & location_
Definition: actions.hpp:320