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