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