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)
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";
206 if(defender->incapacitated()) {
212 if(!attacker->attacks_left()) {
252 s <<
"attack by side ";
274 if(attacker_weapon < 0) {
324 const map_location& to,
bool remove_movement,
bool unreach_is_ok)
328 , remove_movement_(remove_movement)
330 , unit_location_(from)
331 , unreach_is_ok_(unreach_is_ok)
332 , has_ambusher_(false)
333 , has_interrupted_teleport_(false)
344 const unit *u = &*un;
384 if (
route_->steps.empty()) {
429 s <<
"full move by side ";
431 s <<
"partial move by side ";
434 s <<
" from location "<<
from_;
435 s <<
" to location "<<
to_;
446 bool gamestate_changed =
false;
448 int step =
route_->steps.size();
490 if (!stopunit_res->is_ok()) {
493 if (stopunit_res->is_gamestate_changed()) {
525 , recall_location_(where)
527 , location_checked_(false)
582 if(location_specified) {
613 s <<
"recall by side ";
619 s <<
"] on any suitable location";
670 , recruit_location_(where)
671 , recruit_from_(from)
672 , location_checked_(false)
728 if(location_specified) {
759 s <<
"recruitment by side ";
765 s <<
"] on any suitable location";
811 :
action_result(side), unit_location_(unit_location), remove_movement_(remove_movement), remove_attacks_(remove_attacks)
822 const unit *u = &*un;
863 s <<
" stopunit by side ";
866 s <<
" : remove movement ";
872 s <<
" remove attacks ";
897 un->remove_movement_ai();
902 un->remove_attacks_ai();
919 :
action_result(side), lua_code_(lua_code), location_(location)
935 s <<
" synced_command by side ";
1034 int attacker_weapon,
1037 auto action = std::make_shared<attack_result>(side, attacker_loc, defender_loc, attacker_weapon, aggression);
1046 bool remove_movement,
1049 auto action = std::make_shared<move_result>(side, from, to, remove_movement, unreach_is_ok);
1056 const std::string& unit_id,
1060 auto action = std::make_shared<recall_result>(side, unit_id, where, from);
1071 auto action = std::make_shared<recruit_result>(side,
unit_name, where, from);
1079 bool remove_movement,
1080 bool remove_attacks)
1082 auto action = std::make_shared<stopunit_result>(side, unit_location, remove_movement, remove_attacks);
1089 const std::string& lua_code,
1092 auto action = std::make_shared<synced_command_result>(side, lua_code, location);
1101 ERR_AI_ACTIONS <<
"error name not available for error #"<<error_code;
1109 if(gamestate_changed){
1110 result->set_gamestate_changed();
Various functions that implement attacks and attack calculations.
const std::vector< map_location > & route_
std::ostream & operator<<(std::ostream &s, const ai::attack_result &r)
Managing the AI-Game interaction - AI actions and their results.
Managing the AIs lifecycle - headers TODO: Refactor history handling and internal commands.
const unit_map::const_iterator & get_ambusher() const
get the location of an ambusher
const unit_map::const_iterator & get_unit() const
get new location of moved unit
std::size_t get_tiles_entered() const
void set_unit(const unit_map::const_iterator &u)
set the iterator to moved unit
void set_ai_move(bool ai_move=true)
const unit_map::const_iterator & get_failed_teleport() const
get the location of a failed teleport
void clear()
Clears the stack of undoable (and redoable) actions.
virtual void do_check_before()=0
void init_for_execution()
virtual void do_execute()=0
bool return_value_checked_
void set_gamestate_changed()
game_info & get_info() const
virtual void do_init_for_execution()=0
action_result(side_number side)
bool is_gamestate_changed() const
friend void sim_gamestate_changed(action_result *result, bool gamestate_changed)
virtual void do_check_after()=0
bool is_gamestate_changed_
team & get_my_team() const
virtual std::string do_describe() const =0
bool is_execution() const
void set_error(int error_code, bool log_as_error=true)
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.
static const std::map< int, std::string > error_names_
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.
static const std::string & get_error_name(int error_code)
get human-readable name of the error by code.
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,...
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...
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.
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.
virtual void do_execute()
attack_result(side_number side, const map_location &attacker_loc, const map_location &defender_loc, int attacker_weapon, double aggression)
virtual std::string do_describe() const
virtual void do_check_before()
const map_location & attacker_loc_
const map_location & defender_loc_
virtual void do_init_for_execution()
@ E_UNABLE_TO_CHOOSE_ATTACKER_WEAPON
@ E_ATTACKER_AND_DEFENDER_NOT_ADJACENT
@ E_INCAPACITATED_ATTACKER
@ E_WRONG_ATTACKER_WEAPON
@ E_INCAPACITATED_DEFENDER
virtual void do_check_after()
std::set< map_location > recent_attacks
void raise_gamestate_changed()
Notifies all observers of 'ai_gamestate_changed' event.
game_info & get_active_ai_info_for_side(side_number side)
Gets AI info for active AI of the given side.
static manager & get_singleton()
virtual const map_location & get_unit_location() const
bool has_interrupted_teleport_
bool test_route(const unit &un)
virtual void do_check_after()
virtual void do_execute()
virtual void do_check_before()
std::shared_ptr< pathfind::plain_route > route_
move_result(side_number side, const map_location &from, const map_location &to, bool remove_movement, bool unreach_is_ok)
virtual void do_init_for_execution()
map_location unit_location_
virtual std::string do_describe() const
recall_result(side_number side, const std::string &unit_id, const map_location &where, const map_location &from)
virtual std::string do_describe() const
virtual void do_init_for_execution()
map_location recall_location_
const std::string & unit_id_
virtual void do_check_after()
bool test_enough_gold(const team &my_team)
@ E_NOT_AVAILABLE_FOR_RECALLING
unit_const_ptr get_recall_unit(const team &my_team)
virtual void do_check_before()
map_location recall_from_
virtual void do_execute()
const map_location where_
virtual void do_check_before()
virtual void do_execute()
map_location recruit_from_
const unit_type * get_unit_type_known(const std::string &recruit)
map_location recruit_location_
virtual std::string do_describe() const
bool test_enough_gold(const team &my_team, const unit_type &type)
const map_location & where_
virtual void do_check_after()
@ E_NOT_AVAILABLE_FOR_RECRUITING
@ E_UNKNOWN_OR_DUMMY_UNIT_TYPE
recruit_result(side_number side, const std::string &unit_name, const map_location &where, const map_location &from)
virtual void do_init_for_execution()
const std::string & unit_name_
virtual void do_init_for_execution()
virtual void do_execute()
virtual void do_check_before()
virtual std::string do_describe() const
const bool remove_movement_
const bool remove_attacks_
stopunit_result(side_number side, const map_location &unit_location, bool remove_movement, bool remove_attacks)
const map_location & unit_location_
virtual void do_check_after()
virtual std::string do_describe() const
virtual void do_check_after()
const map_location & location_
virtual void do_init_for_execution()
synced_command_result(side_number side, const std::string &lua_code, const map_location &location)
virtual void do_check_before()
const std::string & lua_code_
virtual void do_execute()
Computes the statistics of a battle between an attacker and a defender unit.
const battle_context_unit_stats & get_defender_stats() const
This method returns the statistics of the defender.
const combatant & get_attacker_combatant(const combatant *prev_def=nullptr)
Get the simulation results.
const battle_context_unit_stats & get_attacker_stats() const
This method returns the statistics of the attacker.
const combatant & get_defender_combatant(const combatant *prev_def=nullptr)
virtual const unit_map & units() const override
virtual const gamemap & map() const override
int w() const
Effective map width.
int h() const
Effective map height.
bool on_board(const map_location &loc) const
Tell if a location is on the map.
unit_ptr find_if_matches_id(const std::string &unit_id)
Find a unit by id.
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)
static config get_recall(const std::string &unit_id, const map_location &loc, const map_location &from)
static config get_recruit(const std::string &type_id, const map_location &loc, const map_location &from)
Exception used to escape form the ai or ui code to playsingle_controller::play_side.
static bool run_in_synced_context_if_not_already(const std::string &commandname, const config &data, action_spectator &spectator=get_default_spectator())
Checks whether we are currently running in a synced context, and if not we enters it.
This class stores all the data for a single 'side' (in game nomenclature).
recall_list_manager & recall_list()
const time_of_day & get_time_of_day(int for_turn=0) const
Returns global time of day for the passed turn.
unit_iterator find(std::size_t id)
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.
A single unit type that the player may recruit.
const std::string & id() const
The id for this unit_type.
This class represents a single unit of a specific type.
Various functions related to the creation of units (recruits, recalls, and placed units).
bool incapacitated() const
Check if the unit has been petrified.
int side() const
The side this unit belongs to.
const map_location & get_location() const
The current map location this unit is at.
int movement_left() const
Gets how far a unit can move, considering the incapacitated flag.
bool tiles_adjacent(const map_location &a, const map_location &b)
Function which tells if two locations are adjacent.
Standard logging facilities (interface).
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.
@ RECRUIT_OK
Recruitment OK, but not at the specified location.
@ RECRUIT_NO_VACANCY
No able leaders are on a keep.
@ RECRUIT_NO_ABLE_LEADER
No leaders exist.
@ RECRUIT_ALTERNATE_LOCATION
No vacant castle tiles around a leader on a keep.
@ RECRUIT_NO_KEEP_LEADER
No leaders able to recall/recruit the given unit/type.
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.
std::size_t move_unit_and_record(const std::vector< map_location > &steps, bool continued_move, bool *interrupted)
Wrapper around the other overload.
A small explanation about what's going on here: Each action has access to two game_info objects First...
bool simulated_attack(const map_location &attacker_loc, const map_location &defender_loc, double attacker_hp, double defender_hp)
bool simulated_stopunit(const map_location &unit_location, bool remove_movement, bool remove_attacks)
std::shared_ptr< recruit_result > recruit_result_ptr
bool simulated_move(int side, const map_location &from, const map_location &to, int steps, map_location &unit_location)
bool simulated_recruit(int side, const unit_type *u, const map_location &recruit_location)
void sim_gamestate_changed(action_result *result, bool gamestate_changed)
bool simulated_synced_command()
static lg::log_domain log_ai_actions("ai/actions")
std::shared_ptr< attack_result > attack_result_ptr
std::shared_ptr< stopunit_result > stopunit_result_ptr
std::shared_ptr< synced_command_result > synced_command_result_ptr
std::shared_ptr< move_result > move_result_ptr
std::shared_ptr< recall_result > recall_result_ptr
bool simulated_recall(int side, const std::string &unit_id, const map_location &recall_location)
static void execute_or_check(action_result &action, bool execute)
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 teleport_map get_teleport_locations(const unit &u, const team &viewing_team, bool see_all, bool ignore_units, bool check_vision)
::tod_manager * tod_manager
actions::undo_list * undo_stack
std::shared_ptr< const unit > unit_const_ptr
static config unit_name(const unit *u)
Implement simulated actions.
int attack_num
Index into unit->attacks() or -1 for none.
double average_hp(unsigned int healing=0) const
What's the average hp (weighted average of hp_dist).
Encapsulates the map of the game.
static const map_location & null_location()
Structure which holds a single route between one location and another.
static map_location::direction s
unit_type_data unit_types
Various functions that implement the undoing (and redoing) of in-game commands.