Port [protect_leader], [protect_unit], [protect_location]...

...to new-style ai config. The form is
[goal]name=protect[criteria]SLF[/criteria][/goal], and old syntax is
converted automatically on load. This allows RCA AI to use these types
of goals.
This commit is contained in:
Iurii Chernyi 2010-01-29 20:27:42 +00:00
parent cd69d0c7ad
commit 256faf3c17
6 changed files with 205 additions and 25 deletions

View File

@ -1,4 +1,7 @@
1.7.12+svn:
* AI:
* Port [protect_leader], [protect_unit], [protect_location] to new-style ai
config, which is a goal with name=protect, which accepts a SLF [criteria].
* Engine:
* Fix bug #15146: made kill event with animate="yes" recheck the presence of
unit before animating, fixing the assertion failure (in case the unit is

View File

@ -150,4 +150,84 @@ target_unit_goal::target_unit_goal(readonly_context &context, const config &cfg)
}
void protect_goal::on_create()
{
goal::on_create();
if (cfg_.has_attribute("value")) {
try {
value_ = boost::lexical_cast<double>(cfg_["value"]);
} catch (boost::bad_lexical_cast){
ERR_AI_COMPOSITE_GOAL << "bad value of protect_goal"<<std::endl;
value_ = 0;
}
}
if (cfg_.has_attribute("protect_radius")) {
try {
radius_ = boost::lexical_cast<int>(cfg_["protect_radius"]);
} catch (boost::bad_lexical_cast){
ERR_AI_COMPOSITE_GOAL << "bad protection radius of protect_goal"<<std::endl;
radius_ = 1;
}
}
if (radius_<1) {
radius_=20;
}
const config &criteria = cfg_.child("criteria");
if (criteria) {
filter_ptr_ = boost::shared_ptr<terrain_filter>(new terrain_filter(vconfig(criteria),get_info().units));
}
}
void protect_goal::add_targets(std::back_insert_iterator< std::vector< target > > target_list)
{
if (!(this)->active()) {
LOG_AI_COMPOSITE_GOAL << "skipping protect_goal - not active" << std::endl;
return;
}
if (!filter_ptr_) {
LOG_AI_COMPOSITE_GOAL << "skipping protect_goal - no criteria given" << std::endl;
return;
} else {
DBG_AI_COMPOSITE_GOAL << "protect_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;
filter_ptr_->get_locations(items);
DBG_AI_COMPOSITE_GOAL << "seaching for threats in protect_goal" << std::endl;
// Look for directions to protect a specific location.
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_COMPOSITE_GOAL << "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);
}
}
}
}
protect_goal::protect_goal(readonly_context &context, const config &cfg)
: goal(context,cfg)
, filter_ptr_()
, radius_(20)
, value_(1.0) //these defaults are taken from old code
{
}
} //end of namespace ai

View File

@ -31,6 +31,7 @@
#include "../contexts.hpp"
#include "../game_info.hpp"
#include "../../terrain_filter.hpp"
//included for 'target' markers
#include "../default/contexts.hpp"
@ -55,10 +56,10 @@ public:
virtual void add_targets(std::back_insert_iterator< std::vector< target > > target_list);
config to_config() const;
virtual config to_config() const;
void on_create();
virtual void on_create();
bool active() const;
@ -105,6 +106,29 @@ private:
class protect_goal : public goal {
public:
protect_goal(readonly_context &context, const config &cfg);
virtual void add_targets(std::back_insert_iterator< std::vector< target > > target_list);
virtual void on_create();
private:
double value()
{
return value_;
}
boost::shared_ptr<terrain_filter> filter_ptr_;
int radius_;
double value_;
};
class goal_factory{
public:
typedef boost::shared_ptr< goal_factory > factory_ptr;

View File

@ -310,17 +310,11 @@ bool configuration::upgrade_side_config_from_1_07_02_to_1_07_03(side_number side
aiparam.clear_children(wka.name_);
}
}
fallback_stage_cfg_ai.append(aiparam);
}
foreach (const config &aitarget, aiparam.child_range("target")) {
config aigoal;
if (aiparam.has_attribute("turns")) {
aigoal["turns"] = aiparam["turns"];
}
if (aiparam.has_attribute("time_of_day")) {
aigoal["time_of_day"] = aiparam["time_of_day"];
}
if (aitarget.has_attribute("value")) {
aigoal["value"] = aitarget["value"];
} else {
@ -333,6 +327,35 @@ bool configuration::upgrade_side_config_from_1_07_02_to_1_07_03(side_number side
parsed_cfg.add_child("goal",aigoal);
}
aiparam.clear_children("target");
foreach (const config &ai_protect_unit, aiparam.child_range("protect_unit")) {
upgrade_protect_goal_config_from_1_07_02_to_1_07_03(side,ai_protect_unit,parsed_cfg,true);
}
aiparam.clear_children("protect_unit");
foreach (const config &ai_protect_location, aiparam.child_range("protect_location")) {
upgrade_protect_goal_config_from_1_07_02_to_1_07_03(side,ai_protect_location,parsed_cfg,false);
}
aiparam.clear_children("protect_location");
if (aiparam.has_attribute("protect_leader")) {
config c;
c["value"] = aiparam["protect_leader"];
c["can_recruit"] = "yes";
c["side_number"] = str_cast(side);
if (aiparam.has_attribute("protect_leader_radius")) {
c["radius"] = aiparam["protect_leader_radius"];
}
upgrade_protect_goal_config_from_1_07_02_to_1_07_03(side,c,parsed_cfg,true);
}
fallback_stage_cfg_ai.append(aiparam);
}
}
fallback_stage_cfg_ai.clear_children("aspect");
@ -342,7 +365,7 @@ bool configuration::upgrade_side_config_from_1_07_02_to_1_07_03(side_number side
}
fallback_stage_cfg_ai.clear_children("stage");
//move [goal] to root of the config
//move [goal]s to root of the config
foreach (const config &aigoal, fallback_stage_cfg_ai.child_range("goal")) {
parsed_cfg.add_child("goal",aigoal);
}
@ -374,10 +397,47 @@ void configuration::upgrade_aspect_configs_from_1_07_02_to_1_07_03(side_number s
cfg.add_child("ai",aiparam);
}
DBG_AI_CONFIGURATION << "side "<< side <<": upgrading aspects from syntax of 1.7.2. to 1.7.3, old-style config is:" << std::endl << cfg << std::endl;
DBG_AI_CONFIGURATION << "side "<< side <<": upgrading aspects from syntax of 1.7.2 to 1.7.3, old-style config is:" << std::endl << cfg << std::endl;
foreach (const well_known_aspect &wka, well_known_aspects) {
upgrade_aspect_config_from_1_07_02_to_1_07_03(side, cfg,parsed_cfg,wka.name_,wka.was_an_attribute_);
}
}
void configuration::upgrade_protect_goal_config_from_1_07_02_to_1_07_03(side_number side, const config &protect_cfg, config &parsed_cfg, bool add_filter)
{
config aigoal;
aigoal["name"] = "protect";
if (protect_cfg.has_attribute("value")) {
aigoal["value"] = protect_cfg["value"];
} else {
aigoal["value"] = "1";//old default value
}
//note: 'radius' attribute is renamed to avoid confusion with SLF's radius
if (protect_cfg.has_attribute("radius")) {
aigoal["protect_radius"] = protect_cfg["radius"];
} else {
aigoal["protect_radius"] = "20";//old default value
}
DBG_AI_CONFIGURATION << "side "<< side <<": upgrading protect goal from syntax of 1.7.2 to 1.7.3, old-style config is:" << std::endl << protect_cfg << std::endl;
if (add_filter) {
config &aigoal_criteria = aigoal.add_child("criteria",config());
config &aigoal_criteria_filter = aigoal_criteria.add_child("filter",protect_cfg);
aigoal_criteria_filter.remove_attribute("value");
aigoal_criteria_filter.remove_attribute("radius");
} else {
config &aigoal_criteria = aigoal.add_child("criteria",protect_cfg);
aigoal_criteria.remove_attribute("value");
aigoal_criteria.remove_attribute("radius");
}
parsed_cfg.add_child("goal",aigoal);
DBG_AI_CONFIGURATION << "side "<< side <<": after upgrade of protect goal from syntax of 1.7.2 to 1.7.3, new-style config is:" << std::endl << aigoal << std::endl;
}
} //end of namespace ai

View File

@ -135,6 +135,15 @@ private:
static bool upgrade_aspect_config_from_1_07_02_to_1_07_03(side_number side, const config& cfg, config& parsed_cfg, const std::string &id, bool aspect_was_attribute = true);
/**
* Upgrade protect goal config from version 1.7.2 to version 1.7.3
* @param side side number
* @param[in] protect_cfg the config to be read
* @param[out] parsed_cfg parsed config, to which a new goal is to be added
* @param[in] add_filter should [filter] be added to criteria or not
*/
static void upgrade_protect_goal_config_from_1_07_02_to_1_07_03(side_number side, const config &protect_cfg, config &parsed_cfg, bool add_filter);
/**
* Upgrade side config from version 1.7.2 to version 1.7.3
* @param[in] cfg the config to be read

View File

@ -126,6 +126,10 @@ static register_candidate_action_factory<testing_ai_default::leader_control_phas
static register_goal_factory<target_unit_goal>
goal_factory("");
static register_goal_factory<protect_goal>
goal_factory_protect("protect");
// =======================================================================
// Aspects
// =======================================================================