attack_result_ptr readwrite_context_impl::execute_attack_action(const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon){ unit_map::iterator i = resources::units->find(attacker_loc); double m_aggression = i.valid() && i->can_recruit() ? get_leader_aggression() : get_aggression(); return actions::execute_attack_action(get_side(),true,attacker_loc,defender_loc,attacker_weapon, m_aggression); }
void protect_goal::add_targets(std::back_insert_iterator< std::vector< target >> target_list) { std::string goal_type; if (protect_unit_) { goal_type = "protect_unit"; } else { goal_type ="protect_location"; } if (!(this)->active()) { LOG_AI_GOAL << "skipping " << goal_type << " goal - not active" << std::endl; return; } const config &criteria = cfg_.child("criteria"); if (!criteria) { LOG_AI_GOAL << "skipping " << goal_type << " goal - no criteria given" << std::endl; return; } else { DBG_AI_GOAL << "side " << get_side() << ": "<< goal_type << " goal with criteria" << std::endl << cfg_.child("criteria") << std::endl; } unit_map &units = resources::gameboard->units(); std::set<map_location> items; if (protect_unit_) { const unit_filter ufilt{ vconfig(criteria) }; for (const unit &u : units) { // 'protect_unit' can be set to any unit of any side -> exclude hidden units // unless they are visible to the AI side (e.g. allies with shared vision). // As is done in other parts of the AI, units under fog/shroud count as visible to the AI. if (ufilt(u) && (!u.invisible(u.get_location()) || u.is_visible_to_team(current_team(), false))) { DBG_AI_GOAL << "side " << get_side() << ": in " << goal_type << ": " << u.get_location() << " should be protected\n"; items.insert(u.get_location()); } } } else { filter_ptr_->get_locations(items); } DBG_AI_GOAL << "side " << get_side() << ": searching for threats in "+goal_type+" goal" << std::endl; // Look for directions to protect a specific location or specific unit. for (const map_location &loc : items) { for (const unit &u : units) { int distance = distance_between(u.get_location(), loc); if (current_team().is_enemy(u.side()) && distance < radius_ && !u.invisible(u.get_location())) { DBG_AI_GOAL << "side " << get_side() << ": in " << goal_type << ": found threat target. " << u.get_location() << " is a threat to "<< loc << '\n'; *target_list = target(u.get_location(), value_ * static_cast<double>(radius_ - distance) / radius_, target::TYPE::THREAT); } } } }
recall_result_ptr readonly_context_impl::check_recall_action(const std::string& id, const map_location &where){ return actions::execute_recall_action(get_side(),false,id,where); }
stopunit_result_ptr readonly_context_impl::check_stopunit_action(const map_location& unit_location, bool remove_movement, bool remove_attacks){ return actions::execute_stopunit_action(get_side(),false,unit_location,remove_movement,remove_attacks); }
void stage::on_create() { LOG_AI_STAGE << "side "<< get_side() << " : "<<" created stage with name=["<<cfg_["name"]<<"]"<<std::endl; }
move_result_ptr readonly_context_impl::check_move_action(const map_location& from, const map_location& to, bool remove_movement){ return actions::execute_move_action(get_side(),false,from,to,remove_movement); }
attack_result_ptr readonly_context_impl::check_attack_action(const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon){ unit_map::iterator i = resources::units->find(attacker_loc); double m_aggression = i.valid() && i->can_recruit() ? get_leader_aggression() : get_aggression(); const unit_advancements_aspect& m_advancements = get_advancements(); return actions::execute_attack_action(get_side(),false,attacker_loc,defender_loc,attacker_weapon, m_aggression, m_advancements); }
void protect_goal::add_targets(std::back_insert_iterator< std::vector< target > > target_list) { std::string goal_type; if (protect_unit_) { if (protect_only_own_unit_) { goal_type = "protect_my_unit"; } else { goal_type = "protect_unit"; } } else { goal_type ="protect_location"; } if (!(this)->active()) { LOG_AI_GOAL << "skipping " << goal_type << " goal - not active" << std::endl; return; } const config &criteria = cfg_.child("criteria"); if (!criteria) { LOG_AI_GOAL << "skipping " << goal_type << " goal - no criteria given" << std::endl; return; } else { DBG_AI_GOAL << goal_type << " goal with criteria" << std::endl << cfg_.child("criteria") << std::endl; } unit_map &units = get_info().units; std::vector<team> &teams = get_info().teams; std::set<map_location> items; if (protect_unit_) { for(unit_map::const_iterator u = units.begin(); u != units.end(); ++u) { if (protect_only_own_unit_ && u->second.side()!=get_side()) { continue; } //TODO: we will protect hidden units, by not testing for invisibility to current side if (u->second.matches_filter(vconfig(criteria),u->first)) { DBG_AI_GOAL << "in "<<goal_type<< ": " << u->first << " should be protected " << std::endl; items.insert(u->first); } } } else { filter_ptr_->get_locations(items); } DBG_AI_GOAL << "seaching for threats in "+goal_type+" goal" << std::endl; // Look for directions to protect a specific location or specific unit. foreach (const map_location &loc, items) { for(unit_map::const_iterator u = units.begin(); u != units.end(); ++u) { const int distance = distance_between(u->first,loc); if(current_team().is_enemy(u->second.side()) && distance < radius_ && !u->second.invisible(u->first, units, teams)) { DBG_AI_GOAL << "in "<<goal_type<<": found threat target. " << u->first << " is a threat to "<< loc << std::endl; *target_list = target(u->first, value_ * double(radius_-distance) / double(radius_),target::THREAT); } } } }
recruit_result_ptr readwrite_context_impl::execute_recruit_action(const std::string& unit_name, const map_location &where, const map_location &from){ return actions::execute_recruit_action(get_side(),true,unit_name,where,from); }
team& readwrite_context_impl::current_team_w() { return (*resources::teams)[get_side()-1]; }
move_result_ptr readwrite_context_impl::execute_move_action(const map_location& from, const map_location& to, bool remove_movement){ return actions::execute_move_action(get_side(),true,from,to,remove_movement); }
bool ai_default_recruitment_stage::recruit_usage(const std::string& usage) { raise_user_interact(); analyze_all(); const int min_gold = 0; log_scope2(log_ai, "recruiting troops"); LOG_AI << "recruiting '" << usage << "'\n"; //make sure id, usage and cost are known for the coming evaluation of unit types unit_types.build_all(unit_type::HELP_INDEX); std::vector<std::string> options; bool found = false; // Find an available unit that can be recruited, // matches the desired usage type, and comes in under budget. BOOST_FOREACH(const std::string &name, current_team().recruits()) { const unit_type *ut = unit_types.find(name); if (!ut) continue; // If usage is empty consider any unit. if (usage.empty() || ut->usage() == usage) { LOG_AI << name << " considered for " << usage << " recruitment\n"; found = true; if (current_team().gold() - ut->cost() < min_gold) { LOG_AI << name << " rejected, cost too high (cost: " << ut->cost() << ", current gold: " << current_team().gold() <<", min_gold: " << min_gold << ")\n"; continue; } if (not_recommended_units_.count(name)) { LOG_AI << name << " rejected, bad terrain or combat\n"; continue; } std::map<std::string,int>::iterator imc = maximum_counts_.find(name); if (imc != maximum_counts_.end()) { int count_active = 0; for (unit_map::const_iterator u = resources::units->begin(); u != resources::units->end(); ++u) { if (u->side() == get_side() && !u->incapacitated() && u->type().base_id() == name) { ++count_active; } } if (count_active >= imc->second) { LOG_AI << name << " rejected, too many in the field\n"; continue; } } LOG_AI << "recommending '" << name << "'\n"; options.push_back(name); } } // From the available options, choose one at random if(options.empty() == false) { const int option = rand()%options.size(); recruit_result_ptr recruit_res = check_recruit_action(options[option]); if (recruit_res->is_ok()) { recruit_res->execute(); if (!recruit_res->is_ok()) { ERR_AI << "recruitment failed "<< std::endl; } } return recruit_res->is_gamestate_changed(); } if (found) { LOG_AI << "No available units to recruit that come under the price.\n"; } else if (usage != "") { //FIXME: This message should be suppressed when WML author //chooses the default recruitment pattern. const std::string warning = "At difficulty level " + resources::gamedata->difficulty() + ", trying to recruit a:" + usage + " but no unit of that type (usage=) is" " available. Check the recruit and [ai]" " recruitment_pattern keys for team '" + current_team().name() + "' (" + lexical_cast<std::string>(get_side()) + ")" " against the usage key of the" " units in question! Removing invalid" " recruitment_pattern entry and continuing...\n"; WRN_AI << warning; // Uncommented until the recruitment limiting macro can be fixed to not trigger this warning. //lg::wml_error << warning; //@fixme //return current_team_w().remove_recruitment_pattern_entry(usage); return false; } return false; }
bool Plane::intersects(const BoundingBox& b) const { return get_side(b) == INTERSECT; }
void goal::on_create() { LOG_AI_GOAL << "side " << get_side() << " : " << " created goal with name=[" << cfg_["name"] << "]" << std::endl; }
bool G_Map::init() { auto tab_info = the_app->script()->read_table("the_map_info"); if (tab_info->is_nil()) { return false; } for (unsigned i = 1; ; ++i) { auto tab_item = tab_info->read_table(i); if (tab_item->is_nil()) { break; } int id = tab_item->read_integer("id", -1); if (id < 0) { continue; } G_MapCity *city = probe_city(id); city->_coin = tab_item->read_integer("tongqian"); unsigned side_id = tab_item->read_integer("mbelong"); side_id--; if (side_id > G_SIDE_UNKNOWN) { log_error("unknown side id '%d'.", side_id + 1); return false; } city->_origin = city->_side = get_side(side_id); city->_side->_coin += city->_coin; auto joins = tab_item->read_table("xiangling"); if (joins->is_nil()) { log_error("city '%d' is solo.", id); return false; } for (unsigned j = 1; ; ++j) { int join_item = joins->read_integer(j, -1); if (join_item < 0) { break; } city->_joins[join_item] = probe_city(join_item); } } if (!init_side()) { return false; } for (G_MapCity *city : _city_list) { if (!city->_origin) { log_error("city %d bad.", city->_id); continue; } city->init(); } object<G_GraphicMatrix> path(_city_list.size()); G_GraphicMatrix mat(_city_list.size()); for (unsigned i = 0; i < _city_list.size(); ++i) { for (unsigned j = 0; j < _city_list.size(); ++j) { if (i == j) { mat.elem(i, j) = 0; } else { G_MapCity *city = _city_list[i]; G_MapCity *city2 = _city_list[j]; if (city->_joins.find(city2->_id) == city->_joins.end()) { mat.elem(i, j) = UINT32_MAX; } else { mat.elem(i, j) = 1; } } } } for (unsigned i = 0; i < _city_list.size(); ++i) { for (unsigned j = 0; j < _city_list.size(); ++j) { path->elem(i, j) = UINT32_MAX; } } for(unsigned k = 0; k < _city_list.size(); k++) { for(unsigned i = 0; i < _city_list.size(); i++) { for(unsigned j = 0; j < _city_list.size(); j++) { if((mat.elem(i, k) && mat.elem(k, j) && mat.elem(i, k) < UINT32_MAX && mat.elem(k, j) < UINT32_MAX) && (mat.elem(i, k) + mat.elem(k, j) < mat.elem(i, j))) { mat.elem(i, j) = mat.elem(i, k) + mat.elem(k, j); path->elem(i, j) = path->elem(k, j); } } } } _path = path; return true; }
void goal::unrecognized() { ERR_AI_GOAL << "side " << get_side() << " : " << " tried to create goal with name=[" << cfg_["name"] << "], but the [" << cfg_["engine"] << "] engine did not recognize that type of goal. " << std::endl; ok_ = false; }
game_info& action_result::get_info() const { return manager::get_active_ai_info_for_side(get_side()); }
bool idle_stage::do_play_stage(){ LOG_AI_STAGE << "Turn " << resources::tod_manager->turn() << ": playing idle stage for side: "<< get_side() << std::endl; return false; }
void attack_result::do_check_before() { LOG_AI_ACTIONS << " check_before " << *this << std::endl; const unit_map::const_iterator attacker = resources::units->find(attacker_loc_); const unit_map::const_iterator defender = resources::units->find(defender_loc_); if(attacker==resources::units->end()) { LOG_AI_ACTIONS << "attempt to attack without attacker\n"; set_error(E_EMPTY_ATTACKER); return; } if (defender==resources::units->end()) { LOG_AI_ACTIONS << "attempt to attack without defender\n"; set_error(E_EMPTY_DEFENDER); return; } if(attacker->incapacitated()) { LOG_AI_ACTIONS << "attempt to attack with unit that is petrified\n"; set_error(E_INCAPACITATED_ATTACKER); return; } if(defender->incapacitated()) { LOG_AI_ACTIONS << "attempt to attack unit that is petrified\n"; set_error(E_INCAPACITATED_DEFENDER); return; } if(!attacker->attacks_left()) { LOG_AI_ACTIONS << "attempt to attack with no attacks left\n"; set_error(E_NO_ATTACKS_LEFT); return; } if(attacker->side()!=get_side()) { LOG_AI_ACTIONS << "attempt to attack with not own unit\n"; set_error(E_NOT_OWN_ATTACKER); return; } if(!get_my_team().is_enemy(defender->side())) { LOG_AI_ACTIONS << "attempt to attack unit that is not enemy\n"; set_error(E_NOT_ENEMY_DEFENDER); return; } if (attacker_weapon_!=-1) { if ((attacker_weapon_<0)||(attacker_weapon_ >= static_cast<int>(attacker->attacks().size()))) { LOG_AI_ACTIONS << "invalid weapon selection for the attacker\n"; set_error(E_WRONG_ATTACKER_WEAPON); return; } } if (!tiles_adjacent(attacker_loc_,defender_loc_)) { LOG_AI_ACTIONS << "attacker and defender not adjacent\n"; set_error(E_ATTACKER_AND_DEFENDER_NOT_ADJACENT); return; } }
OSL::ShaderGlobals& ShadingPoint::get_osl_shader_globals() const { assert(hit()); if (!(m_members & HasOSLShaderGlobals)) { const ShadingRay& ray(get_ray()); m_shader_globals.P = Vector3f(get_point()); m_shader_globals.dPdx = OSL::Vec3(0, 0, 0); m_shader_globals.dPdy = OSL::Vec3(0, 0, 0); m_shader_globals.dPdz = OSL::Vec3(0, 0, 0); m_shader_globals.I = Vector3f(normalize(ray.m_dir)); m_shader_globals.dIdx = OSL::Vec3(0, 0, 0); m_shader_globals.dIdy = OSL::Vec3(0, 0, 0); m_shader_globals.N = Vector3f(get_shading_normal()); m_shader_globals.Ng = Vector3f(get_geometric_normal()); m_shader_globals.u = get_uv(0).x; m_shader_globals.dudx = 0; m_shader_globals.dudy = 0; m_shader_globals.v = get_uv(0).y; m_shader_globals.dvdx = 0; m_shader_globals.dvdy = 0; m_shader_globals.dPdu = Vector3f(get_dpdu(0)); m_shader_globals.dPdv = Vector3f(get_dpdv(0)); m_shader_globals.time = ray.m_time; m_shader_globals.dtime = 0; m_shader_globals.dPdtime = OSL::Vec3(0, 0, 0); m_shader_globals.Ps = OSL::Vec3(0, 0, 0); m_shader_globals.dPsdx = OSL::Vec3(0, 0, 0); m_shader_globals.dPsdy = OSL::Vec3(0, 0, 0); m_shader_globals.renderstate = 0; m_shader_globals.tracedata = 0; m_shader_globals.objdata = 0; m_obj_transform_info.m_assembly_instance_transform = &get_assembly_instance().cumulated_transform_sequence(); m_obj_transform_info.m_object_instance_transform = &get_object_instance().get_transform(); m_shader_globals.object2common = reinterpret_cast<OSL::TransformationPtr>(&m_obj_transform_info); m_shader_globals.shader2common = 0; m_shader_globals.surfacearea = 0; m_shader_globals.raytype = static_cast<int>(ray.m_type); m_shader_globals.flipHandedness = 0; m_shader_globals.backfacing = get_side() == ObjectInstance::FrontSide ? 0 : 1; m_shader_globals.context = 0; m_shader_globals.Ci = 0; m_members |= HasOSLShaderGlobals; } else { // Update always the raytype, as it might have changed from the previous run. m_shader_globals.raytype = static_cast<int>(get_ray().m_type); } return m_shader_globals; }
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::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::units); move_spectator.set_unit(resources::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*/ NULL, /*bool continue_move*/ true, ///@todo 1.9 set to false after implemeting interrupt awareness /*bool show_move*/ preferences::show_ai_moves(), /*bool* interrupted*/ NULL, /*::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. This may cause bugs! " << std::endl; } //Demotes to DBG "unchecked result" warning throw; } } }
recall_result_ptr readwrite_context_impl::execute_recall_action(const std::string& id, const map_location &where){ return actions::execute_recall_action(get_side(),true,id,where); }
bool stage_unit_formulas::do_play_stage() { //execute units formulas first game_logic::unit_formula_set units_with_formulas; unit_map &units_ = *resources::units; for(unit_map::unit_iterator i = units_.begin() ; i != units_.end() ; ++i) { if (i->side() == get_side()) { if (i->has_formula() || i->has_loop_formula()) { int priority = 0; if (i->has_priority_formula()) { try { game_logic::const_formula_ptr priority_formula(fai_.create_optional_formula(i->get_priority_formula())); if (priority_formula) { game_logic::map_formula_callable callable(&fai_); callable.add_ref(); callable.add("me", variant(new unit_callable(*i))); priority = (game_logic::formula::evaluate(priority_formula, callable)).as_int(); } else { WRN_AI << "priority formula skipped, maybe it's empty or incorrect"<< std::endl; } } catch(game_logic::formula_error& e) { if(e.filename == "formula") e.line = 0; fai_.handle_exception( e, "Unit priority formula error for unit: '" + i->type_id() + "' standing at (" + str_cast(i->get_location().x + 1) + "," + str_cast(i->get_location().y + 1) + ")"); priority = 0; } catch(type_error& e) { priority = 0; ERR_AI << "formula type error while evaluating unit priority formula " << e.message << "\n"; } } units_with_formulas.insert( game_logic::unit_formula_pair( i, priority ) ); } } } for(game_logic::unit_formula_set::iterator pair_it = units_with_formulas.begin() ; pair_it != units_with_formulas.end() ; ++pair_it) { unit_map::iterator i = pair_it->first; if( i.valid() ) { if (i->has_formula()) { try { game_logic::const_formula_ptr formula(fai_.create_optional_formula(i->get_formula())); if (formula) { game_logic::map_formula_callable callable(&fai_); callable.add_ref(); callable.add("me", variant(new unit_callable(*i))); fai_.make_action(formula, callable); } else { WRN_AI << "unit formula skipped, maybe it's empty or incorrect" << std::endl; } } catch(game_logic::formula_error& e) { if(e.filename == "formula") { e.line = 0; } fai_.handle_exception( e, "Unit formula error for unit: '" + i->type_id() + "' standing at (" + str_cast(i->get_location().x + 1) + "," + str_cast(i->get_location().y + 1) + ")"); } } } if( i.valid() ) { if (i->has_loop_formula()) { try { game_logic::const_formula_ptr loop_formula(fai_.create_optional_formula(i->get_loop_formula())); if (loop_formula) { game_logic::map_formula_callable callable(&fai_); callable.add_ref(); callable.add("me", variant(new unit_callable(*i))); while ( !fai_.make_action(loop_formula, callable).is_empty() && i.valid() ) { } } else { WRN_AI << "Loop formula skipped, maybe it's empty or incorrect" << std::endl; } } catch(game_logic::formula_error& e) { if (e.filename == "formula") { e.line = 0; } fai_.handle_exception( e, "Unit loop formula error for unit: '" + i->type_id() + "' standing at (" + str_cast(i->get_location().x + 1) + "," + str_cast(i->get_location().y + 1) + ")"); } } } } return false; }
recruit_result_ptr readonly_context_impl::check_recruit_action(const std::string& unit_name, const map_location &where){ return actions::execute_recruit_action(get_side(),false,unit_name,where); }
std::vector<target> default_ai_context_impl::find_targets(const move_map& enemy_dstsrc) { log_scope2(log_ai, "finding targets..."); unit_map &units_ = *resources::units; unit_map::iterator leader = units_.find_leader(get_side()); gamemap &map_ = *resources::game_map; std::vector<team> teams_ = *resources::teams; const bool has_leader = leader != units_.end(); std::vector<target> targets; //=== start getting targets //if enemy units are in range of the leader, then we target the enemies who are in range. if(has_leader) { double threat = power_projection(leader->get_location(), enemy_dstsrc); if(threat > 0.0) { //find the location of enemy threats std::set<map_location> threats; map_location adj[6]; get_adjacent_tiles(leader->get_location(), adj); for(size_t n = 0; n != 6; ++n) { std::pair<move_map::const_iterator,move_map::const_iterator> itors = enemy_dstsrc.equal_range(adj[n]); while(itors.first != itors.second) { if(units_.count(itors.first->second)) { threats.insert(itors.first->second); } ++itors.first; } } assert(threats.empty() == false); #ifdef SUOKKO //FIXME: suokko's revision 29531 included this change. Correct? const double value = threat*get_protect_leader()/leader->second.hitpoints(); #else const double value = threat/double(threats.size()); #endif for(std::set<map_location>::const_iterator i = threats.begin(); i != threats.end(); ++i) { LOG_AI << "found threat target... " << *i << " with value: " << value << "\n"; targets.push_back(target(*i,value,target::THREAT)); } } } double corner_distance = distance_between(map_location(0,0), map_location(map_.w(),map_.h())); double village_value = get_village_value(); if(has_leader && village_value > 0.0) { std::map<map_location,pathfind::paths> friends_possible_moves; move_map friends_srcdst, friends_dstsrc; calculate_possible_moves(friends_possible_moves, friends_srcdst, friends_dstsrc, false, true); const std::vector<map_location>& villages = map_.villages(); for(std::vector<map_location>::const_iterator t = villages.begin(); t != villages.end(); ++t) { assert(map_.on_board(*t)); bool ally_village = false; for (size_t i = 0; i != teams_.size(); ++i) { if (!current_team().is_enemy(i + 1) && teams_[i].owns_village(*t)) { ally_village = true; break; } } if (ally_village) { //Support seems to cause the AI to just 'sit around' a lot, so //only turn it on if it's explicitly enabled. if(get_support_villages()) { double enemy = power_projection(*t, enemy_dstsrc); if (enemy > 0) { enemy *= 1.7; double our = power_projection(*t, friends_dstsrc); double value = village_value * our / enemy; add_target(target(*t, value, target::SUPPORT)); } } } else { double leader_distance = distance_between(*t, leader->get_location()); double value = village_value * (1.0 - leader_distance / corner_distance); LOG_AI << "found village target... " << *t << " with value: " << value << " distance: " << leader_distance << '\n'; targets.push_back(target(*t,value,target::VILLAGE)); } } } std::vector<goal_ptr>& goals = get_goals(); //find the enemy leaders and explicit targets unit_map::const_iterator u; if (get_leader_value()>0.0) { for(u = units_.begin(); u != units_.end(); ++u) { //is a visible enemy leader if (u->can_recruit() && current_team().is_enemy(u->side()) && !u->invisible(u->get_location())) { assert(map_.on_board(u->get_location())); LOG_AI << "found enemy leader (side: " << u->side() << ") target... " << u->get_location() << " with value: " << get_leader_value() << "\n"; targets.push_back(target(u->get_location(), get_leader_value(), target::LEADER)); } } } //explicit targets for this team for(std::vector<goal_ptr>::iterator j = goals.begin(); j != goals.end(); ++j) { if (!(*j)->active()) { continue; } (*j)->add_targets(std::back_inserter(targets)); } //=== end getting targets std::vector<double> new_values; for(std::vector<target>::iterator i = targets.begin(); i != targets.end(); ++i) { new_values.push_back(i->value); for(std::vector<target>::const_iterator j = targets.begin(); j != targets.end(); ++j) { if(i->loc == j->loc) { continue; } const double distance = abs(j->loc.x - i->loc.x) + abs(j->loc.y - i->loc.y); new_values.back() += j->value/(distance*distance); } } assert(new_values.size() == targets.size()); for(size_t n = 0; n != new_values.size(); ++n) { LOG_AI << "target value: " << targets[n].value << " -> " << new_values[n] << "\n"; targets[n].value = new_values[n]; } return targets; }
attack_result_ptr readonly_context_impl::check_attack_action(const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon){ return actions::execute_attack_action(get_side(),false,attacker_loc,defender_loc,attacker_weapon, get_aggression()); }
synced_command_result_ptr readonly_context_impl::check_synced_command_action(const std::string& lua_code, const map_location& location){ return actions::execute_synced_command_action(get_side(),false,lua_code,location); }