Exemple #1
0
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);
}
Exemple #2
0
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);
}
Exemple #7
0
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);
			}
		}
	}


}
Exemple #9
0
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);
}
Exemple #10
0
team& readwrite_context_impl::current_team_w()
{
	return (*resources::teams)[get_side()-1];
}
Exemple #11
0
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);
}
Exemple #12
0
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;
}
Exemple #13
0
	bool Plane::intersects(const BoundingBox& b) const {
		return get_side(b) == INTERSECT;
	}
Exemple #14
0
void goal::on_create()
{
	LOG_AI_GOAL << "side " << get_side() << " : " << " created goal with name=[" << cfg_["name"] << "]" << std::endl;
}
Exemple #15
0
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;
}
Exemple #16
0
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;
}
Exemple #17
0
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;
}
Exemple #19
0
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;
	}
}
Exemple #20
0
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;
}
Exemple #21
0
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);
}
Exemple #25
0
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());
}
Exemple #27
0
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);
}