00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "goal.hpp"
00022 #include "../lua/core.hpp"
00023 #include "../manager.hpp"
00024 #include "../../log.hpp"
00025 #include "../lua/lua_object.hpp"
00026 #include "../../gamestatus.hpp"
00027 #include "../../foreach.hpp"
00028 #include "../../resources.hpp"
00029 #include "../../scripting/lua.hpp"
00030 #include "../../terrain_filter.hpp"
00031 #include "../../unit.hpp"
00032 #include "../../unit_map.hpp"
00033 #include "../../team.hpp"
00034 #include "../../variable.hpp"
00035
00036 #include <boost/lexical_cast.hpp>
00037
00038 namespace ai {
00039
00040 static lg::log_domain log_ai_goal("ai/goal");
00041 #define DBG_AI_GOAL LOG_STREAM(debug, log_ai_goal)
00042 #define LOG_AI_GOAL LOG_STREAM(info, log_ai_goal)
00043 #define ERR_AI_GOAL LOG_STREAM(err, log_ai_goal)
00044
00045 goal::goal(readonly_context &context, const config &cfg)
00046 : readonly_context_proxy(), cfg_(cfg)
00047 {
00048 init_readonly_context_proxy(context);
00049 }
00050
00051
00052
00053 void goal::on_create()
00054 {
00055 }
00056
00057 void goal::on_create(boost::shared_ptr<ai::lua_ai_context>)
00058 {
00059 }
00060
00061
00062 goal::~goal()
00063 {
00064 }
00065
00066
00067 void goal::add_targets(std::back_insert_iterator< std::vector< target > > )
00068 {
00069 }
00070
00071
00072
00073 config goal::to_config() const
00074 {
00075 return cfg_;
00076 }
00077
00078 std::string goal::get_id() const
00079 {
00080 return cfg_["id"];
00081 }
00082
00083 std::string goal::get_name() const
00084 {
00085 return cfg_["id"];
00086 }
00087
00088 std::string goal::get_engine() const
00089 {
00090 return cfg_["engine"];
00091 }
00092
00093
00094 bool goal::redeploy(const config &cfg)
00095 {
00096 cfg_ = cfg;
00097 on_create();
00098 return true;
00099 }
00100
00101
00102 bool goal::active() const
00103 {
00104 return is_active(cfg_["time_of_day"],cfg_["turns"]);
00105 }
00106
00107
00108 void target_unit_goal::on_create()
00109 {
00110 goal::on_create();
00111 if (const config::attribute_value *v = cfg_.get("value")) {
00112 try {
00113 value_ = boost::lexical_cast<double>(*v);
00114 } catch (boost::bad_lexical_cast){
00115 ERR_AI_GOAL << "bad value of goal"<<std::endl;
00116 value_ = 0;
00117 }
00118 }
00119 }
00120
00121 void target_unit_goal::add_targets(std::back_insert_iterator< std::vector< target > > target_list)
00122 {
00123 if (!(this)->active()) {
00124 return;
00125 }
00126
00127 const config &criteria = cfg_.child("criteria");
00128 if (!criteria) return;
00129
00130
00131 foreach (const unit &u, *resources::units) {
00132 if (u.matches_filter(vconfig(criteria), u.get_location())) {
00133 LOG_AI_GOAL << "found explicit target unit at ... " << u.get_location() << " with value: " << value() << "\n";
00134 *target_list = target(u.get_location(), value(), target::EXPLICIT);
00135 }
00136 }
00137
00138
00139 }
00140
00141
00142 target_unit_goal::target_unit_goal(readonly_context &context, const config &cfg)
00143 : goal(context,cfg)
00144 , value_(0.0)
00145 {
00146 }
00147
00148
00149 void target_location_goal::on_create()
00150 {
00151 goal::on_create();
00152 if (cfg_.has_attribute("value")) {
00153 try {
00154 value_ = boost::lexical_cast<double>(cfg_["value"]);
00155 } catch (boost::bad_lexical_cast){
00156 ERR_AI_GOAL << "bad value of goal"<<std::endl;
00157 value_ = 0;
00158 }
00159 }
00160 const config &criteria = cfg_.child("criteria");
00161 if (criteria) {
00162 filter_ptr_ = boost::shared_ptr<terrain_filter>(new terrain_filter(vconfig(criteria),*resources::units));
00163 }
00164 }
00165
00166 void target_location_goal::add_targets(std::back_insert_iterator< std::vector< target > > target_list)
00167 {
00168 if (!(this)->active()) {
00169 return;
00170 }
00171
00172 if (!filter_ptr_) return;
00173
00174 std::set<map_location> items;
00175 filter_ptr_->get_locations(items);
00176 foreach (const map_location &loc, items)
00177 {
00178 LOG_AI_GOAL << "found explicit target location ... " << loc << " with value: " << value() << std::endl;
00179 *target_list = target(loc, value(), target::EXPLICIT);
00180 }
00181
00182 }
00183
00184 target_location_goal::target_location_goal(readonly_context &context, const config &cfg)
00185 : goal(context,cfg)
00186 , filter_ptr_()
00187 , value_(0.0)
00188 {
00189 }
00190
00191
00192
00193 void protect_goal::on_create()
00194 {
00195 goal::on_create();
00196 if (const config::attribute_value *v = cfg_.get("value")) {
00197 try {
00198 value_ = boost::lexical_cast<double>(*v);
00199 } catch (boost::bad_lexical_cast){
00200 ERR_AI_GOAL << "bad value of protect_goal"<<std::endl;
00201 value_ = 0;
00202 }
00203 }
00204 if (const config::attribute_value *v = cfg_.get("protect_radius")) {
00205 try {
00206 radius_ = boost::lexical_cast<int>(*v);
00207 } catch (boost::bad_lexical_cast){
00208 ERR_AI_GOAL << "bad protection radius of protect_goal"<<std::endl;
00209 radius_ = 1;
00210 }
00211 }
00212
00213 if (radius_<1) {
00214 radius_=20;
00215 }
00216 const config &criteria = cfg_.child("criteria");
00217 if (criteria) {
00218 filter_ptr_ = boost::shared_ptr<terrain_filter>(new terrain_filter(vconfig(criteria),*resources::units));
00219 }
00220
00221
00222 }
00223
00224
00225 void protect_goal::add_targets(std::back_insert_iterator< std::vector< target > > target_list)
00226 {
00227 std::string goal_type;
00228 if (protect_unit_) {
00229 if (protect_only_own_unit_) {
00230 goal_type = "protect_my_unit";
00231 } else {
00232 goal_type = "protect_unit";
00233 }
00234 } else {
00235 goal_type ="protect_location";
00236 }
00237
00238 if (!(this)->active()) {
00239 LOG_AI_GOAL << "skipping " << goal_type << " goal - not active" << std::endl;
00240 return;
00241 }
00242
00243 const config &criteria = cfg_.child("criteria");
00244 if (!criteria) {
00245 LOG_AI_GOAL << "skipping " << goal_type << " goal - no criteria given" << std::endl;
00246 return;
00247 } else {
00248 DBG_AI_GOAL << "side " << get_side() << ": "<< goal_type << " goal with criteria" << std::endl << cfg_.child("criteria") << std::endl;
00249 }
00250
00251 unit_map &units = *resources::units;
00252
00253 std::set<map_location> items;
00254 if (protect_unit_) {
00255 foreach (const unit &u, units)
00256 {
00257 if (protect_only_own_unit_ && u.side() != get_side()) {
00258 continue;
00259 }
00260
00261 if (u.matches_filter(vconfig(criteria), u.get_location())) {
00262 DBG_AI_GOAL << "side " << get_side() << ": in " << goal_type << ": " << u.get_location() << " should be protected\n";
00263 items.insert(u.get_location());
00264 }
00265 }
00266 } else {
00267 filter_ptr_->get_locations(items);
00268 }
00269 DBG_AI_GOAL << "side " << get_side() << ": seaching for threats in "+goal_type+" goal" << std::endl;
00270
00271 foreach (const map_location &loc, items)
00272 {
00273 foreach (const unit &u, units)
00274 {
00275 int distance = distance_between(u.get_location(), loc);
00276 if (current_team().is_enemy(u.side()) && distance < radius_ &&
00277 !u.invisible(u.get_location()))
00278 {
00279 DBG_AI_GOAL << "side " << get_side() << ": in " << goal_type << ": found threat target. " << u.get_location() << " is a threat to "<< loc << '\n';
00280 *target_list = target(u.get_location(),
00281 value_ * double(radius_ - distance) /
00282 radius_, target::THREAT);
00283 }
00284 }
00285 }
00286
00287
00288 }
00289
00290
00291 protect_goal::protect_goal(readonly_context &context, const config &cfg, bool protect_only_own_unit, bool protect_unit)
00292 : goal(context,cfg)
00293 , filter_ptr_()
00294 , protect_only_own_unit_(protect_only_own_unit)
00295 , protect_unit_(protect_unit)
00296 , radius_(20)
00297 , value_(1.0)
00298 {
00299 }
00300
00301 lua_goal::lua_goal(readonly_context &context, const config &cfg)
00302 : goal(context, cfg)
00303 , code_()
00304 , handler_()
00305 {
00306 if (cfg.has_attribute("code")) {
00307 code_ = cfg["code"].str();
00308 }
00309 else
00310 {
00311
00312 }
00313 }
00314
00315 void lua_goal::on_create(boost::shared_ptr<ai::lua_ai_context> l_ctx)
00316 {
00317 handler_ = boost::shared_ptr<lua_ai_action_handler>(resources::lua_kernel->create_lua_ai_action_handler(code_.c_str(), *l_ctx));
00318 }
00319
00320 void lua_goal::add_targets(std::back_insert_iterator< std::vector< target > > target_list)
00321 {
00322 boost::shared_ptr< lua_object< std::vector < target > > > l_obj
00323 = boost::shared_ptr< lua_object< std::vector < target > > >(new lua_object< std::vector < target > >());
00324 config c = config();
00325 handler_->handle(c, true, l_obj);
00326 std::vector < target > targets = *(l_obj->get());
00327
00328 foreach (target tg, targets)
00329 {
00330 *target_list = tg;
00331 }
00332
00333 }
00334
00335
00336
00337 }