The Battle for Wesnoth  1.19.7+dev
actions.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2024
3  by Yurii Chernyi <terraninfo@terraninfo.net>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 /**
17  * Managing the AI-Game interaction - AI actions and their results
18  * @file
19  * */
20 
21 #pragma once
22 
23 #include "ai/game_info.hpp"
24 
25 #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 {
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 */
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 
137  enum result {
148  };
149 
150  virtual std::string do_describe() const;
151 protected:
152  virtual void do_check_before();
153  virtual void do_check_after();
154  virtual void do_execute();
155  virtual void do_init_for_execution();
156 private:
160  double aggression_;
161 };
162 
163 class move_result : public action_result {
164 public:
165  move_result( side_number side,
166  const map_location& from,
167  const map_location& to,
168  bool remove_movement,
169  bool unreach_is_ok);
170 
171  enum result {
172  E_EMPTY_MOVE = 2001,
173  E_NO_UNIT = 2002,
176  E_AMBUSHED = 2005,
178  E_OFF_MAP = 2007,
179  E_NO_ROUTE = 2008
180  };
181 
182  virtual std::string do_describe() const;
183  virtual const map_location& get_unit_location() const;
184 protected:
185  virtual void do_check_before();
186  virtual void do_check_after();
187  virtual void do_execute();
188  virtual void do_init_for_execution();
189 private:
190  const unit *get_unit();
191  bool test_route(const unit &un);
195  std::shared_ptr<pathfind::plain_route> route_;
200 };
201 
202 
203 class recall_result : public action_result {
204 public:
205  recall_result (side_number side, const std::string &unit_id, const map_location& where, const map_location& from);
206 
207  enum result {
209  E_NO_GOLD = 6003,
210  E_NO_LEADER = 6004,
212  E_BAD_RECALL_LOCATION = 6006
213  };
214 
215  virtual std::string do_describe() const;
216 protected:
217  virtual void do_check_before();
218  virtual void do_check_after();
219  virtual void do_execute();
220  virtual void do_init_for_execution();
221 private:
223  const team& my_team);
224  bool test_enough_gold(
225  const team& my_team);
226 
227  const std::string& unit_id_;
232 };
233 
235 public:
236  recruit_result( side_number side, const std::string& unit_name, const map_location& where, const map_location& from);
237 
238  enum result {
241  E_NO_GOLD = 3003,
242  E_NO_LEADER = 3004,
245  };
246 
247  virtual std::string do_describe() const;
248 protected:
249  virtual void do_check_before();
250  virtual void do_check_after();
251  virtual void do_execute();
252  virtual void do_init_for_execution();
253 private:
255  const std::string &recruit);
256  bool test_enough_gold(
257  const team& my_team,
258  const unit_type &type );
259 
260  const std::string& unit_name_;
265 };
266 
268 public:
270  const map_location& unit_location,
271  bool remove_movement,
272  bool remove_attacks );
273 
274  enum result {
275  E_NO_UNIT = 4002,
277  E_INCAPACITATED_UNIT = 4004
278  };
279 
280  virtual std::string do_describe() const;
281 protected:
282  virtual void do_check_before();
283  virtual void do_check_after();
284  virtual void do_execute();
285  virtual void do_init_for_execution();
286 private:
287  const unit *get_unit();
289  const bool remove_movement_;
290  const bool remove_attacks_;
291 };
292 
294 public:
296  const std::string& lua_code,
297  const map_location& location );
298 
299  virtual std::string do_describe() const;
300 protected:
301  virtual void do_check_before();
302  virtual void do_check_after();
303  virtual void do_execute();
304  virtual void do_init_for_execution();
305 private:
306  const std::string& lua_code_;
308 };
309 
310 
311 class actions {
312 
313 public:
314 // =======================================================================
315 // Stateless interface to actions
316 // =======================================================================
317 
318 
319 /**
320  * Ask the game to attack an enemy defender using our unit attacker from attackers current location,
321  * @param side the side which tries to execute the move
322  * @param execute should move be actually executed or not
323  * @param attacker_loc location of attacker
324  * @param defender_loc location of defender
325  * @param attacker_weapon weapon of attacker
326  * @param aggression aggression of attacker, is used to determine attacker's weapon if it is not specified
327  * @retval possible results: ok, something wrong, attacker and/or defender are invalid, or attacker doesn't have the specified weapon
328  */
330  bool execute,
331  const map_location& attacker_loc,
332  const map_location& defender_loc,
333  int attacker_weapon,
334  double aggression);
335 
336 
337 /**
338  * Ask the game to move our unit from location 'from' to location 'to', optionally - doing a partial move
339  * @param side the side which tries to execute the move
340  * @param execute should move be actually executed or not
341  * @param from location of our unit
342  * @param to where to move
343  * @param remove_movement set unit movement to 0 in case of successful move
344  * @param unreach_is_ok whether it's okay for a destination to be unreachable
345  * @retval possible results: ok, something wrong, move is interrupted, or move is impossible
346  */
348  bool execute,
349  const map_location& from,
350  const map_location& to,
351  bool remove_movement,
352  bool unreach_is_ok = false);
353 
354 
355 
356 /**
357  * Ask the game to recall a unit for us on specified location
358  * @param side the side which tries to execute the move
359  * @param execute should move be actually executed or not
360  * @param unit_id the id of the unit to be recalled.
361  * @param where location where the unit is to be recalled.
362  * @param from the location where the unit was recruited from.
363  * @retval possible results: ok, something wrong, leader not on keep, no free space on keep, or not enough gold
364  */
366  bool execute,
367  const std::string& unit_id,
368  const map_location& where,
369  const map_location& from);
370 
371 
372 
373 /**
374  * Ask the game to recruit a unit for us on specified location
375  * @param side the side which tries to execute the move
376  * @param execute should move be actually executed or not
377  * @param unit_name the name of the unit to be recruited.
378  * @param where location where the unit is to be recruited.
379  * @param from the location where the unit was recruited from.
380  * @retval possible results: ok, something wrong, leader not on keep, no free space on keep, or not enough gold
381  */
383  bool execute,
384  const std::string& unit_name,
385  const map_location& where,
386  const map_location& from);
387 
388 
389 /**
390  * Ask the game to remove unit movements and/or attack
391  * @param side the side which tries to execute the move
392  * @param execute should move be actually executed or not
393  * @param unit_location the location of our unit
394  * @param remove_movement set remaining movements to 0
395  * @param remove_attacks set remaining attacks to 0
396  * @retval possible results: ok, something wrong, or nothing to do
397  */
399  bool execute,
400  const map_location& unit_location,
401  bool remove_movement,
402  bool remove_attacks );
403 
404 
405 /**
406  * Ask the game to run Lua code
407  * @param side the side which tries to execute the move
408  * @param execute should move be actually executed or not
409  * @param lua_code the code to be run
410  * @param location location to be passed to the code as x1/y1
411  * @retval possible results: ok, something wrong, or nothing to do
412  */
414  bool execute,
415  const std::string& lua_code,
416  const map_location& location );
417 
418 
419 /**
420  * get human-readable name of the error by code.
421  * @param error_code error code.
422  * @retval result the name of the error.
423  */
424 const static std::string& get_error_name(int error_code);
425 
426 private:
427 
428 static const std::map<int, std::string> error_names_;
429 
430 };
431 
432 
433 } //end of namespace ai
434 
435 std::ostream &operator<<(std::ostream &s, const ai::attack_result& r);
436 std::ostream &operator<<(std::ostream &s, const ai::move_result& r);
437 std::ostream &operator<<(std::ostream &s, const ai::recall_result& r);
438 std::ostream &operator<<(std::ostream &s, const ai::recruit_result& r);
439 std::ostream &operator<<(std::ostream &s, const ai::stopunit_result& r);
440 std::ostream &operator<<(std::ostream &s, const ai::synced_command_result& r);
Various functions related to moving units.
std::ostream & operator<<(std::ostream &s, const ai::attack_result &r)
Definition: actions.cpp:1118
virtual void do_check_before()=0
void init_for_execution()
Definition: actions.cpp:111
virtual ~action_result()
Definition: actions.cpp:75
int get_status() const
Definition: actions.cpp:148
virtual void do_execute()=0
void check_before()
Definition: actions.cpp:87
bool return_value_checked_
Definition: actions.hpp:114
void set_gamestate_changed()
Definition: actions.cpp:143
game_info & get_info() const
Definition: actions.cpp:163
virtual void do_init_for_execution()=0
void check_after()
Definition: actions.cpp:82
action_result(side_number side)
Definition: actions.cpp:70
bool is_gamestate_changed() const
Definition: actions.cpp:119
friend void sim_gamestate_changed(action_result *result, bool gamestate_changed)
Definition: actions.cpp:1108
int get_side() const
Definition: actions.hpp:87
virtual void do_check_after()=0
bool is_success() const
Definition: actions.cpp:153
bool is_gamestate_changed_
Definition: actions.hpp:125
team & get_my_team() const
Definition: actions.cpp:168
virtual std::string do_describe() const =0
bool is_execution() const
Definition: actions.cpp:158
void set_error(int error_code, bool log_as_error=true)
Definition: actions.cpp:130
static recall_result_ptr execute_recall_action(side_number side, bool execute, const std::string &unit_id, const map_location &where, const map_location &from)
Ask the game to recall a unit for us on specified location.
Definition: actions.cpp:1054
static const std::map< int, std::string > error_names_
Definition: actions.hpp:428
static synced_command_result_ptr execute_synced_command_action(side_number side, bool execute, const std::string &lua_code, const map_location &location)
Ask the game to run Lua code.
Definition: actions.cpp:1087
static const std::string & get_error_name(int error_code)
get human-readable name of the error by code.
Definition: actions.cpp:1097
static attack_result_ptr execute_attack_action(side_number side, bool execute, const map_location &attacker_loc, const map_location &defender_loc, int attacker_weapon, double aggression)
Ask the game to attack an enemy defender using our unit attacker from attackers current location,...
Definition: actions.cpp:1030
static move_result_ptr execute_move_action(side_number side, bool execute, const map_location &from, const map_location &to, bool remove_movement, bool unreach_is_ok=false)
Ask the game to move our unit from location 'from' to location 'to', optionally - doing a partial mov...
Definition: actions.cpp:1042
static recruit_result_ptr execute_recruit_action(side_number side, bool execute, const std::string &unit_name, const map_location &where, const map_location &from)
Ask the game to recruit a unit for us on specified location.
Definition: actions.cpp:1065
static stopunit_result_ptr execute_stopunit_action(side_number side, bool execute, const map_location &unit_location, bool remove_movement, bool remove_attacks)
Ask the game to remove unit movements and/or attack.
Definition: actions.cpp:1076
double aggression_
Definition: actions.hpp:160
virtual void do_execute()
Definition: actions.cpp:262
attack_result(side_number side, const map_location &attacker_loc, const map_location &defender_loc, int attacker_weapon, double aggression)
Definition: actions.cpp:175
virtual std::string do_describe() const
Definition: actions.cpp:249
virtual void do_check_before()
Definition: actions.cpp:180
const map_location & attacker_loc_
Definition: actions.hpp:157
const map_location & defender_loc_
Definition: actions.hpp:158
virtual void do_init_for_execution()
Definition: actions.cpp:317
@ E_UNABLE_TO_CHOOSE_ATTACKER_WEAPON
Definition: actions.hpp:146
@ E_ATTACKER_AND_DEFENDER_NOT_ADJACENT
Definition: actions.hpp:147
virtual void do_check_after()
Definition: actions.cpp:245
virtual const map_location & get_unit_location() const
Definition: actions.cpp:403
bool has_interrupted_teleport_
Definition: actions.hpp:199
bool test_route(const unit &un)
Definition: actions.cpp:356
const map_location to_
Definition: actions.hpp:193
const map_location from_
Definition: actions.hpp:192
virtual void do_check_after()
Definition: actions.cpp:408
virtual void do_execute()
Definition: actions.cpp:440
virtual void do_check_before()
Definition: actions.cpp:391
std::shared_ptr< pathfind::plain_route > route_
Definition: actions.hpp:195
const unit * get_unit()
Definition: actions.cpp:337
move_result(side_number side, const map_location &from, const map_location &to, bool remove_movement, bool unreach_is_ok)
Definition: actions.cpp:323
bool remove_movement_
Definition: actions.hpp:194
virtual void do_init_for_execution()
Definition: actions.cpp:514
bool has_ambusher_
Definition: actions.hpp:198
map_location unit_location_
Definition: actions.hpp:196
virtual std::string do_describe() const
Definition: actions.cpp:425
bool unreach_is_ok_
Definition: actions.hpp:197
recall_result(side_number side, const std::string &unit_id, const map_location &where, const map_location &from)
Definition: actions.cpp:520
virtual std::string do_describe() const
Definition: actions.cpp:610
virtual void do_init_for_execution()
Definition: actions.cpp:659
map_location recall_location_
Definition: actions.hpp:229
const std::string & unit_id_
Definition: actions.hpp:227
virtual void do_check_after()
Definition: actions.cpp:592
bool test_enough_gold(const team &my_team)
Definition: actions.cpp:540
@ E_NOT_AVAILABLE_FOR_RECALLING
Definition: actions.hpp:208
unit_const_ptr get_recall_unit(const team &my_team)
Definition: actions.cpp:531
bool location_checked_
Definition: actions.hpp:231
virtual void do_check_before()
Definition: actions.cpp:549
map_location recall_from_
Definition: actions.hpp:230
virtual void do_execute()
Definition: actions.cpp:625
const map_location where_
Definition: actions.hpp:228
virtual void do_check_before()
Definition: actions.cpp:695
virtual void do_execute()
Definition: actions.cpp:771
map_location recruit_from_
Definition: actions.hpp:263
const unit_type * get_unit_type_known(const std::string &recruit)
Definition: actions.cpp:676
map_location recruit_location_
Definition: actions.hpp:262
virtual std::string do_describe() const
Definition: actions.cpp:756
bool test_enough_gold(const team &my_team, const unit_type &type)
Definition: actions.cpp:686
const map_location & where_
Definition: actions.hpp:261
virtual void do_check_after()
Definition: actions.cpp:738
@ E_NOT_AVAILABLE_FOR_RECRUITING
Definition: actions.hpp:239
@ E_UNKNOWN_OR_DUMMY_UNIT_TYPE
Definition: actions.hpp:240
recruit_result(side_number side, const std::string &unit_name, const map_location &where, const map_location &from)
Definition: actions.cpp:665
virtual void do_init_for_execution()
Definition: actions.cpp:804
const std::string & unit_name_
Definition: actions.hpp:260
virtual void do_init_for_execution()
Definition: actions.cpp:912
virtual void do_execute()
Definition: actions.cpp:879
virtual void do_check_before()
Definition: actions.cpp:834
virtual std::string do_describe() const
Definition: actions.cpp:860
const bool remove_movement_
Definition: actions.hpp:289
const bool remove_attacks_
Definition: actions.hpp:290
const unit * get_unit()
Definition: actions.cpp:815
stopunit_result(side_number side, const map_location &unit_location, bool remove_movement, bool remove_attacks)
Definition: actions.cpp:810
const map_location & unit_location_
Definition: actions.hpp:288
virtual void do_check_after()
Definition: actions.cpp:843
virtual std::string do_describe() const
Definition: actions.cpp:932
virtual void do_check_after()
Definition: actions.cpp:928
const map_location & location_
Definition: actions.hpp:307
virtual void do_init_for_execution()
Definition: actions.cpp:969
synced_command_result(side_number side, const std::string &lua_code, const map_location &location)
Definition: actions.cpp:918
virtual void do_check_before()
Definition: actions.cpp:923
const std::string & lua_code_
Definition: actions.hpp:306
virtual void do_execute()
Definition: actions.cpp:941
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:75
A single unit type that the player may recruit.
Definition: types.hpp:43
This class represents a single unit of a specific type.
Definition: unit.hpp:133
Game information for the AI.
A small explanation about what's going on here: Each action has access to two game_info objects First...
Definition: actions.cpp:59
std::shared_ptr< recruit_result > recruit_result_ptr
Definition: game_info.hpp:84
std::shared_ptr< attack_result > attack_result_ptr
Definition: game_info.hpp:82
std::shared_ptr< stopunit_result > stopunit_result_ptr
Definition: game_info.hpp:87
std::shared_ptr< synced_command_result > synced_command_result_ptr
Definition: game_info.hpp:88
int side_number
Definition: game_info.hpp:40
std::shared_ptr< move_result > move_result_ptr
Definition: game_info.hpp:85
std::shared_ptr< recall_result > recall_result_ptr
Definition: game_info.hpp:83
std::shared_ptr< const unit > unit_const_ptr
Definition: ptr.hpp:27
static config unit_name(const unit *u)
Definition: reports.cpp:161
Encapsulates the map of the game.
Definition: location.hpp:45
Structure which holds a single route between one location and another.
Definition: pathfind.hpp:133
static map_location::direction s