diff --git a/src/ai/composite/goal.cpp b/src/ai/composite/goal.cpp index b5b6b2702c5b..329f5efa28a5 100644 --- a/src/ai/composite/goal.cpp +++ b/src/ai/composite/goal.cpp @@ -157,7 +157,7 @@ void target_unit_goal::add_targets(std::back_insert_iterator< std::vector< targe BOOST_FOREACH(const unit &u, *resources::units) { if (ufilt( u )) { LOG_AI_GOAL << "found explicit target unit at ... " << u.get_location() << " with value: " << value() << "\n"; - *target_list = target(u.get_location(), value(), target::EXPLICIT); + *target_list = target(u.get_location(), value(), target::TYPE::EXPLICIT); } } @@ -207,7 +207,7 @@ void target_location_goal::add_targets(std::back_insert_iterator< std::vector< t BOOST_FOREACH(const map_location &loc, items) { LOG_AI_GOAL << "found explicit target location ... " << loc << " with value: " << value() << std::endl; - *target_list = target(loc, value(), target::EXPLICIT); + *target_list = target(loc, value(), target::TYPE::EXPLICIT); } } @@ -316,7 +316,7 @@ void protect_goal::add_targets(std::back_insert_iterator< std::vector< target > 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_ * double(radius_ - distance) / - radius_, target::THREAT); + radius_, target::TYPE::THREAT); } } } @@ -363,12 +363,16 @@ void lua_goal::add_targets(std::back_insert_iterator< std::vector< target > > ta = boost::shared_ptr< lua_object< std::vector < target > > >(new lua_object< std::vector < target > >()); config c = config(); handler_->handle(c, true, l_obj); - std::vector < target > targets = *(l_obj->get()); + try { + std::vector < target > targets = *(l_obj->get()); - BOOST_FOREACH(target tg, targets) - { - *target_list = tg; - } + BOOST_FOREACH(target tg, targets) + { + *target_list = tg; + } + } catch(bad_enum_cast& e) { + ERR_AI_GOAL << "A Lua goal returned a target of an unknown type (\"" << e.value() << "\"; unfortunately, the engine cannot recover from this error. As a result, all targets returned by the goal have been lost.\n"; + } } diff --git a/src/ai/default/contexts.cpp b/src/ai/default/contexts.cpp index 6605805481de..0c23d3588ec4 100644 --- a/src/ai/default/contexts.cpp +++ b/src/ai/default/contexts.cpp @@ -172,7 +172,7 @@ std::vector default_ai_context_impl::find_targets(const move_map& enemy_ #endif for(std::set::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)); + targets.push_back(target(*i,value,target::TYPE::THREAT)); } } } @@ -209,7 +209,7 @@ std::vector default_ai_context_impl::find_targets(const move_map& enemy_ enemy *= 1.7; double our = power_projection(*t, friends_dstsrc); double value = village_value * our / enemy; - add_target(target(*t, value, target::SUPPORT)); + add_target(target(*t, value, target::TYPE::SUPPORT)); } } } @@ -220,7 +220,7 @@ std::vector default_ai_context_impl::find_targets(const move_map& enemy_ LOG_AI << "found village target... " << *t << " with value: " << value << " distance: " << leader_distance << '\n'; - targets.push_back(target(*t,value,target::VILLAGE)); + targets.push_back(target(*t,value,target::TYPE::VILLAGE)); } } } @@ -236,7 +236,7 @@ std::vector default_ai_context_impl::find_targets(const move_map& enemy_ && !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)); + targets.push_back(target(u->get_location(), get_leader_value(), target::TYPE::LEADER)); } } diff --git a/src/ai/default/contexts.hpp b/src/ai/default/contexts.hpp index 77979f4cc48a..1ecda91396a0 100644 --- a/src/ai/default/contexts.hpp +++ b/src/ai/default/contexts.hpp @@ -22,6 +22,7 @@ #include "ai/contexts.hpp" #include "formula/callable.hpp" +#include "utils/make_enum.hpp" #ifdef _MSC_VER #if _MSC_VER < 1600 @@ -38,9 +39,17 @@ namespace ai { struct target { - enum TYPE { VILLAGE, LEADER, EXPLICIT, THREAT, BATTLE_AID, MASS, SUPPORT }; - - target(const map_location& pos, double val, TYPE target_type=VILLAGE) : loc(pos), value(val), type(target_type) + MAKE_ENUM(TYPE, + (VILLAGE, "village") + (LEADER, "leader") + (EXPLICIT, "explicit") + (THREAT, "threat") + (BATTLE_AID, "battle aid") + (MASS, "mass") + (SUPPORT, "support") + ); + + target(const map_location& pos, double val, TYPE target_type=TYPE::VILLAGE) : loc(pos), value(val), type(target_type) {} map_location loc; double value; diff --git a/src/ai/lua/core.cpp b/src/ai/lua/core.cpp index 1c7afd280dbe..3503bcf96376 100644 --- a/src/ai/lua/core.cpp +++ b/src/ai/lua/core.cpp @@ -382,7 +382,7 @@ static int cfun_ai_get_targets(lua_State *L) lua_pushstring(L, "type"); - lua_pushnumber(L, it->type); + lua_pushstring(L, it->type.to_string().c_str()); lua_rawset(L, -3); lua_pushstring(L, "loc"); diff --git a/src/ai/lua/lua_object.hpp b/src/ai/lua/lua_object.hpp index 17762ee6e41f..c32b894561eb 100644 --- a/src/ai/lua/lua_object.hpp +++ b/src/ai/lua/lua_object.hpp @@ -170,7 +170,12 @@ inline boost::shared_ptr > lua_object< std::vector > lua_pushstring(L, "type"); // st n + 2 lua_rawget(L, -2); // st n + 2 - target::TYPE type = static_cast(lua_tointeger(L, -1)); // st n + 2 + target::TYPE type = target::TYPE::EXPLICIT; + if(lua_isnumber(L, -1)) { + type = target::TYPE::from_int(lua_tointeger(L, -1)); // st n + 2 + } else if(lua_isstring(L, -1)) { + type = target::TYPE::string_to_enum(lua_tostring(L, -1)); // st n + 2 + } lua_pop(L, 1); // st n + 1 diff --git a/src/ai/testing/ca_testing_move_to_targets.cpp b/src/ai/testing/ca_testing_move_to_targets.cpp index bf4a4c39f352..762f6af2ddd4 100644 --- a/src/ai/testing/ca_testing_move_to_targets.cpp +++ b/src/ai/testing/ca_testing_move_to_targets.cpp @@ -233,7 +233,7 @@ double testing_move_to_targets_phase::rate_target(const target& tg, const unit_m //for 'support' targets, they are rated much higher if we can get there within two turns, //otherwise they are worthless to go for at all. - if(tg.type == target::SUPPORT) { + if(tg.type == target::TYPE::SUPPORT) { if (move_cost <= u->movement_left() * 2) { rating *= 10.0; } else { @@ -245,7 +245,7 @@ double testing_move_to_targets_phase::rate_target(const target& tg, const unit_m //scouts do not like encountering enemies on their paths if (u->usage() == "scout") { //scouts get a bonus for going after villages - if(tg.type == target::VILLAGE) { + if(tg.type == target::TYPE::VILLAGE) { rating *= get_scout_village_targeting(); } @@ -428,7 +428,7 @@ std::pair testing_move_to_targets_phase::choose_move( //if our target is a position to support, then we //see if we can move to a position in support of this target - if(best_target->type == target::SUPPORT) { + if(best_target->type == target::TYPE::SUPPORT) { LOG_AI << "support...\n"; std::vector locs; @@ -554,7 +554,7 @@ std::pair testing_move_to_targets_phase::choose_move( for(std::set::const_iterator j = mass_locations.begin(); j != mass_locations.end(); ++j) { if(*j != best_loc && distance_between(*j,best_loc) < 3) { LOG_AI << "found mass-to-attack target... " << *j << " with value: " << value*4.0 << "\n"; - targets.push_back(target(*j,value*4.0,target::MASS)); + targets.push_back(target(*j,value*4.0,target::TYPE::MASS)); best_target = targets.end() - 1; } } @@ -578,12 +578,12 @@ std::pair testing_move_to_targets_phase::choose_move( get_caution())) { double value = best_target->value - best->cost() / 20.0; - if(value > 0.0 && best_target->type != target::MASS) { + if(value > 0.0 && best_target->type != target::TYPE::MASS) { //there are enemies ahead. Rally troops around us to //try to take the target if(is_dangerous) { LOG_AI << "found reinforcement target... " << its.first->first << " with value: " << value*2.0 << "\n"; - targets.push_back(target(its.first->first,value*2.0,target::BATTLE_AID)); + targets.push_back(target(its.first->first,value*2.0,target::TYPE::BATTLE_AID)); } best_target->value = value;