62 #define DBG_AI_ACTIONS LOG_STREAM(debug, log_ai_actions) 63 #define LOG_AI_ACTIONS LOG_STREAM(info, log_ai_actions) 64 #define WRN_AI_ACTIONS LOG_STREAM(warn, log_ai_actions) 65 #define ERR_AI_ACTIONS LOG_STREAM(err, log_ai_actions) 71 : return_value_checked_(true),side_(side),status_(AI_ACTION_SUCCESS),is_execution_(false),is_gamestate_changed_(false)
78 DBG_AI_ACTIONS <<
"Return value of AI ACTION was not checked." << std::endl;
101 if (!
is_ok()) {
DBG_AI_ACTIONS <<
"Return value of AI ACTION was not checked." << std::endl; }
176 :
action_result(side), attacker_loc_(attacker_loc), defender_loc_(defender_loc), attacker_weapon_(attacker_weapon), aggression_(aggression)
200 if(attacker->incapacitated()) {
201 LOG_AI_ACTIONS <<
"attempt to attack with unit that is petrified\n";
206 if(defender->incapacitated()) {
212 if(!attacker->attacks_left()) {
252 s <<
"attack by side ";
274 if(attacker_weapon < 0) {
319 if (!
is_ok()) {
DBG_AI_ACTIONS <<
"Return value of AI ACTION was not checked." << std::endl; }
331 const map_location& to,
bool remove_movement,
bool unreach_is_ok)
335 , remove_movement_(remove_movement)
337 , unit_location_(from)
338 , unreach_is_ok_(unreach_is_ok)
339 , has_ambusher_(false)
340 , has_interrupted_teleport_(false)
351 const unit *u = &*un;
391 if (
route_->steps.empty()) {
436 s <<
"full move by side ";
438 s <<
"partial move by side ";
441 s <<
" from location "<<
from_;
442 s <<
" to location "<<
to_;
453 bool gamestate_changed =
false;
455 int step =
route_->steps.size();
483 if ( num_steps > 0 ) {
499 if (!stopunit_res->is_ok()) {
502 if (stopunit_res->is_gamestate_changed()) {
517 if (!
is_ok()) {
DBG_AI_ACTIONS <<
"Return value of AI ACTION was not checked." << std::endl; }
534 , recall_location_(where)
536 , location_checked_(false)
591 if(location_specified) {
622 s <<
"recall by side ";
626 s <<
"] on location "<<
where_;
628 s <<
"] on any suitable location";
636 LOG_AI_ACTIONS <<
"start of execution of: " << *
this << std::endl;
667 if (!
is_ok()) {
DBG_AI_ACTIONS <<
"Return value of AI ACTION was not checked." << std::endl; }
681 , unit_name_(unit_name)
683 , recruit_location_(where)
684 , recruit_from_(from)
741 if(location_specified) {
772 s <<
"recruitment by side ";
776 s <<
"] on location "<<
where_;
778 s <<
"] on any suitable location";
786 LOG_AI_ACTIONS <<
"start of execution of: " << *
this << std::endl;
811 if (!
is_ok()) {
DBG_AI_ACTIONS <<
"Return value of AI ACTION was not checked." << std::endl; }
823 :
action_result(side), unit_location_(unit_location), remove_movement_(remove_movement), remove_attacks_(remove_attacks)
834 const unit *u = &*un;
875 s <<
" stopunit by side ";
878 s <<
" : remove movement ";
884 s <<
" remove attacks ";
893 LOG_AI_ACTIONS <<
"start of execution of: " << *
this << std::endl;
909 un->remove_movement_ai();
914 un->remove_attacks_ai();
919 if (!
is_ok()) {
DBG_AI_ACTIONS <<
"Return value of AI ACTION was not checked." << std::endl; }
931 :
action_result(side), lua_code_(lua_code), location_(location)
947 s <<
" synced_command by side ";
963 LOG_AI_ACTIONS <<
"start of execution of: " << *
this << std::endl;
976 if (!
is_ok()) {
DBG_AI_ACTIONS <<
"Return value of AI ACTION was not checked." << std::endl; }
1003 int attacker_weapon,
1015 bool remove_movement,
1025 const std::string& unit_id,
1048 bool remove_movement,
1049 bool remove_attacks)
1058 const std::string& lua_code,
1068 if (error_names_.empty()){
1110 if (i==error_names_.end()){
1111 ERR_AI_ACTIONS <<
"error name not available for error #"<<error_code << std::endl;
1112 i = error_names_.find(-1);
1113 assert(i != error_names_.end());
1121 if(gamestate_changed){
map_location recruit_location_
map_location recruit_from_
virtual void do_init_for_execution()
virtual void do_check_after()
bool simulated_synced_command()
::tod_manager * tod_manager
int h() const
Effective map height, in hexes.
virtual void do_execute()
const unit_type * find(const std::string &key, unit_type::BUILD_STATUS status=unit_type::FULL) const
Finds a unit_type by its id() and makes sure it is built to the specified level.
game_info & get_info() const
map_location recall_from_
std::shared_ptr< stopunit_result > stopunit_result_ptr
unit_const_ptr get_recall_unit(const team &my_team)
virtual const unit_map & units() const override
virtual void do_check_before()
This class represents a single unit of a specific type.
const battle_context_unit_stats & get_defender_stats() const
This method returns the statistics of the defender.
static std::map< int, std::string > error_names_
static manager & get_singleton()
virtual void do_execute()=0
void raise_gamestate_changed()
Notifies all observers of 'ai_gamestate_changed' event.
map_location unit_location_
const unit_map::const_iterator & get_unit() const
get new location of moved unit
virtual void do_init_for_execution()
Various functions that implement attacks and attack calculations.
static config get_recall(const std::string &unit_id, const map_location &loc, const map_location &from)
Exception used to escape form the ai or ui code to playsingle_controller::play_side.
const combatant & get_attacker_combatant(const combatant *prev_def=nullptr)
Get the simulation results.
virtual void do_check_after()
bool test_route(const unit &un)
Managing the AI-Game interaction - AI actions and their results.
map_location recall_location_
game_info & get_active_ai_info_for_side(side_number side)
Gets AI info for active AI of the given side.
virtual void do_init_for_execution()
const map_location & where_
const std::string & unit_id_
double average_hp(unsigned int healing=0) const
What's the average hp (weighted average of hp_dist).
const unit_type * get_unit_type_known(const std::string &recruit)
virtual std::string do_describe() const
std::shared_ptr< move_result > move_result_ptr
virtual void do_init_for_execution()
virtual const gamemap & map() const override
virtual std::string do_describe() const
virtual void do_check_before()
unit_type_data unit_types
Recruitment OK, but not at the specified location.
std::size_t move_unit_and_record(const std::vector< map_location > &steps, undo_list *undo_stack, bool continued_move, bool show_move, bool *interrupted, move_unit_spectator *move_spectator)
Moves a unit across the board.
virtual void do_execute()
std::shared_ptr< recruit_result > recruit_result_ptr
virtual const map_location & get_unit_location() const
static config unit_name(const unit *u)
action_result(side_number side)
bool simulated_attack(const map_location &attacker_loc, const map_location &defender_loc, double attacker_hp, double defender_hp)
virtual void do_check_after()=0
const std::string & lua_code_
std::shared_ptr< attack_result > attack_result_ptr
virtual std::string do_describe() const
void init_for_execution()
const unit_map::const_iterator & get_failed_teleport() const
get the location of a failed teleport
bool has_interrupted_teleport_
std::shared_ptr< pathfind::plain_route > route_
std::ostream & operator<<(std::ostream &s, const ai::candidate_action &ca)
const unit_map::const_iterator & get_ambusher() const
get the location of an ambusher
A single unit type that the player may recruit.
const combatant & get_defender_combatant(const combatant *prev_def=nullptr)
std::shared_ptr< const unit > unit_const_ptr
This class stores all the data for a single 'side' (in game nomenclature).
A small explanation about what's going on here: Each action has access to two game_info objects First...
virtual void do_init_for_execution()
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.
bool simulated_recall(int side, const std::string &unit_id, const map_location &recall_location)
std::shared_ptr< recall_result > recall_result_ptr
unit_ptr find_if_matches_id(const std::string &unit_id)
Find a unit by id.
static lg::log_domain log_ai_actions("ai/actions")
virtual void do_check_after()
attack_result(side_number side, const map_location &attacker_loc, const map_location &defender_loc, int attacker_weapon, double aggression)
Structure which holds a single route between one location and another.
bool return_value_checked_
const time_of_day & get_time_of_day(int for_turn=0) const
Returns global time of day for the passed turn.
virtual void do_check_after()
virtual std::string do_describe() const
virtual void do_execute()
bool test_enough_gold(const team &my_team, const unit_type &type)
Computes the statistics of a battle between an attacker and a defender unit.
synced_command_result(side_number side, const std::string &lua_code, const map_location &location)
const std::string & id() const
The id for this unit_type.
Managing the AIs lifecycle - headers TODO: Refactor history handling and internal commands...
int attack_num
Index into unit->attacks() or -1 for none.
virtual void do_check_after()
virtual void do_execute()
const bool remove_movement_
friend void sim_gamestate_changed(action_result *result, bool gamestate_changed)
No vacant castle tiles around a leader on a keep.
virtual void do_check_before()=0
virtual void do_init_for_execution()=0
const std::string & unit_name_
std::shared_ptr< synced_command_result > synced_command_result_ptr
static config get_attack(const map_location &a, const map_location &b, int att_weapon, int def_weapon, const std::string &attacker_type_id, const std::string &defender_type_id, int attacker_lvl, int defender_lvl, const std::size_t turn, const time_of_day &t)
virtual void do_check_before()
Encapsulates the map of the game.
const bool remove_attacks_
virtual void do_check_before()
unit_iterator find(std::size_t id)
virtual std::string do_describe() const
Various functions related to the creation of units (recruits, recalls, and placed units)...
bool tiles_adjacent(const map_location &a, const map_location &b)
Function which tells if two locations are adjacent.
const map_location & defender_loc_
int w() const
Effective map width, in hexes.
RECRUIT_CHECK check_recall_location(const int side, map_location &recall_location, map_location &recall_from, const unit &unit_recall)
Checks if there is a location on which to recall unit_recall.
No able leaders are on a keep.
void attack_unit_and_advance(const map_location &attacker, const map_location &defender, int attack_with, int defend_with, bool update_display)
Performs an attack, and advanced the units afterwards.
bool simulated_stopunit(const map_location &unit_location, bool remove_movement, bool remove_attacks)
static map_location::DIRECTION s
bool test_enough_gold(const team &my_team)
std::set< map_location > recent_attacks
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...
void set_gamestate_changed()
virtual void do_check_before()
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.
stopunit_result(side_number side, const map_location &unit_location, bool remove_movement, bool remove_attacks)
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.
bool is_gamestate_changed_
RECRUIT_CHECK check_recruit_location(const int side, map_location &recruit_location, map_location &recruited_from, const std::string &unit_type)
Checks if there is a location on which to place a recruited unit.
virtual void do_check_before()
static void ignore_error_function(const std::string &message)
A function to be passed to run_in_synced_context to ignore the error.
const map_location & unit_location_
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.
void set_error(int error_code, bool log_as_error=true)
void set_unit(const unit_map::const_iterator &u)
set the iterator to moved unit
static bool run_and_throw(const std::string &commandname, const config &data, bool use_undo=true, bool show=true, synced_command::error_handler_function error_handler=default_error_function)
team & get_my_team() const
static bool run_in_synced_context_if_not_already(const std::string &commandname, const config &data, bool use_undo=true, bool show=true, synced_command::error_handler_function error_handler=default_error_function)
Checks whether we are currently running in a synced context, and if not we enters it...
static void execute_or_check(action_result &action, bool execute)
bool is_execution() const
bool simulated_move(int side, const map_location &from, const map_location &to, int steps, map_location &unit_location)
bool is_gamestate_changed() const
const map_location & get_location() const
The current map location this unit is at.
bool simulated_recruit(int side, const unit_type *u, const map_location &recruit_location)
Standard logging facilities (interface).
const teleport_map get_teleport_locations(const unit &u, const team &viewing_team, bool see_all, bool ignore_units, bool check_vision)
recall_list_manager & recall_list()
static const map_location & null_location()
virtual void do_execute()
virtual std::string do_describe() const =0
bool incapacitated() const
Check if the unit has been petrified.
static config get_recruit(const std::string &type_id, const map_location &loc, const map_location &from)
int side() const
The side this unit belongs to.
virtual std::string do_describe() const
recall_result(side_number side, const std::string &unit_id, const map_location &where, const map_location &from)
const map_location where_
plain_route a_star_search(const map_location &src, const map_location &dst, double stop_at, const cost_calculator &calc, const std::size_t width, const std::size_t height, const teleport_map *teleports, bool border)
const map_location & attacker_loc_
move_result(side_number side, const map_location &from, const map_location &to, bool remove_movement, bool unreach_is_ok)
virtual void do_check_after()
const battle_context_unit_stats & get_attacker_stats() const
This method returns the statistics of the attacker.
std::string::const_iterator iterator
int movement_left() const
Gets how far a unit can move, considering the incapacitated flag.
recruit_result(side_number side, const std::string &unit_name, const map_location &where, const map_location &from)
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...
virtual void do_init_for_execution()
No leaders able to recall/recruit the given unit/type.
static const std::string & get_error_name(int error_code)
get human-readable name of the error by code.
const std::vector< map_location > & route_
const map_location & location_
virtual void do_execute()
Implement simulated actions.