bool simulated_attack(const map_location& attacker_loc, const map_location& defender_loc, double attacker_hp, double defender_hp){ LOG_AI_SIM_ACTIONS << "Simulated attack" << std::endl; unit_map::iterator attack_unit = resources::gameboard->units().find(attacker_loc); unit_map::iterator defend_unit = resources::gameboard->units().find(defender_loc); LOG_AI_SIM_ACTIONS << attack_unit->type_name() << " at " << attacker_loc << " attack " << defend_unit->type_name() << " at " << defender_loc << std::endl; LOG_AI_SIM_ACTIONS << "attacker's hp before attack: " << attack_unit->hitpoints() << std::endl; LOG_AI_SIM_ACTIONS << "defender's hp before attack: " << defend_unit->hitpoints() << std::endl; attack_unit->set_hitpoints(static_cast<int>(attacker_hp)); defend_unit->set_hitpoints(static_cast<int>(defender_hp)); LOG_AI_SIM_ACTIONS << "attacker's hp after attack: " << attack_unit->hitpoints() << std::endl; LOG_AI_SIM_ACTIONS << "defender's hp after attack: " << defend_unit->hitpoints() << std::endl; int attacker_xp = game_config::combat_xp(defend_unit->level()); int defender_xp = game_config::combat_xp(attack_unit->level()); bool attacker_died = false; bool defender_died = false; if(attack_unit->hitpoints() <= 0){ attacker_xp = 0; defender_xp = game_config::kill_xp(attack_unit->level()); (resources::gameboard->units()).erase(attacker_loc); attacker_died = true; } if(defend_unit->hitpoints() <= 0){ defender_xp = 0; attacker_xp = game_config::kill_xp(defend_unit->level()); (resources::gameboard->units()).erase(defender_loc); defender_died = true; } if(!attacker_died){ attack_unit->set_experience(attack_unit->experience()+attacker_xp); helper_advance_unit(attacker_loc); simulated_stopunit(attacker_loc, true, true); } if(!defender_died){ defend_unit->set_experience(defend_unit->experience()+defender_xp); helper_advance_unit(defender_loc); simulated_stopunit(defender_loc, true, true); } return true; }
void stopunit_result::do_execute() { LOG_AI_ACTIONS << "start of execution of: " << *this << std::endl; assert(is_success()); unit_map::iterator un = resources::gameboard->units().find(unit_location_); if(resources::simulation_){ bool gamestate_changed = simulated_stopunit(unit_location_, remove_movement_, remove_attacks_); sim_gamestate_changed(this, gamestate_changed); return; } try { if (remove_movement_){ un->remove_movement_ai(); set_gamestate_changed(); manager::raise_gamestate_changed(); } if (remove_attacks_){ un->remove_attacks_ai(); set_gamestate_changed(); manager::raise_gamestate_changed();//to be on the safe side } } catch (...) { if (!is_ok()) { DBG_AI_ACTIONS << "Return value of AI ACTION was not checked." << std::endl; } //Demotes to DBG "unchecked result" warning throw; } }
void move_result::do_execute() { LOG_AI_ACTIONS << "start of execution of: "<< *this << std::endl; assert(is_success()); if(resources::simulation_){ bool gamestate_changed = false; if(from_ != to_){ int step = route_->steps.size(); gamestate_changed = simulated_move(get_side(), from_, to_, step, unit_location_); } else { assert(remove_movement_); } unit_map::const_iterator un = resources::gameboard->units().find(unit_location_); if(remove_movement_ && un->movement_left() > 0 && unit_location_ == to_){ gamestate_changed = simulated_stopunit(unit_location_, true, false); } sim_gamestate_changed(this, gamestate_changed); return; } ::actions::move_unit_spectator move_spectator(resources::gameboard->units()); move_spectator.set_unit(resources::gameboard->units().find(from_)); if (from_ != to_) { size_t num_steps = ::actions::move_unit_and_record( /*std::vector<map_location> steps*/ route_->steps, /*::actions::undo_list* undo_stack*/ nullptr, /*bool continue_move*/ true, ///@todo 1.9 set to false after implemeting interrupt awareness /*bool show_move*/ !preferences::skip_ai_moves(), /*bool* interrupted*/ nullptr, /*::actions::move_unit_spectator* move_spectator*/ &move_spectator); if ( num_steps > 0 ) { set_gamestate_changed(); } else if ( move_spectator.get_ambusher().valid() ) { // Unlikely, but some types of strange WML (or bad pathfinding) // could cause an ambusher to be found without moving. set_gamestate_changed(); } } else { assert(remove_movement_); } if (move_spectator.get_unit().valid()){ unit_location_ = move_spectator.get_unit()->get_location(); if (remove_movement_ && move_spectator.get_unit()->movement_left() > 0 && unit_location_ == to_) { stopunit_result_ptr stopunit_res = actions::execute_stopunit_action(get_side(),true,unit_location_,true,false); if (!stopunit_res->is_ok()) { set_error(stopunit_res->get_status()); } if (stopunit_res->is_gamestate_changed()) { set_gamestate_changed(); } } } else { unit_location_ = map_location(); } has_ambusher_ = move_spectator.get_ambusher().valid(); has_interrupted_teleport_ = move_spectator.get_failed_teleport().valid(); if (is_gamestate_changed()) { try { manager::raise_gamestate_changed(); } catch (...) { if (!is_ok()) { DBG_AI_ACTIONS << "Return value of AI ACTION was not checked." << std::endl; } //Demotes to DBG "unchecked result" warning throw; } } }