Improve AI behavior when using goto_x/y in WML

Makes the ai to use the best path when in WML goto_x / goto_y is used.
(This used to be a straight route)
This commit is contained in:
flix 2013-04-14 17:01:52 +03:00
parent 405a2b7195
commit fddc28738b
2 changed files with 34 additions and 14 deletions

View file

@ -3,6 +3,7 @@ Version 1.11.4+dev:
* Recruiting in Micro and Experimental AIs: allow more terrain codes for castles/keeps
* Improved/Added: Command 'lua wesnoth.debug_ai([side]).ai' will now give access to the
ai-table of [side].
* Improved AI behavior when using goto_x / goto_y in WML
* Campaigns:
* Legend of Wesmere:
* Scenario 05: Elvish Horse Archers can now carry the treasure

View file

@ -29,6 +29,7 @@
#include "../../resources.hpp"
#include "../../team.hpp"
#include "../../pathfind/pathfind.hpp"
#include "../../pathfind/teleport.hpp"
#include <boost/foreach.hpp>
@ -79,24 +80,42 @@ double goto_phase::evaluate()
continue;//@todo: only bail out if goto is on keep
}
// end of passive_leader
int closest_distance = -1;
std::pair<map_location,map_location> closest_move;
for(move_map::const_iterator i = get_dstsrc().begin(); i != get_dstsrc().end(); ++i) {
if(i->second != ui->get_location()) {
continue;
const pathfind::shortest_path_calculator calc(*ui, current_team(), *resources::teams, *resources::game_map);
const pathfind::teleport_map allowed_teleports = pathfind::get_teleport_locations(*ui, current_team());
pathfind::plain_route route;
route = pathfind::a_star_search(ui->get_location(), ui->get_goto(), 10000.0, &calc, map_.w(), map_.h(), &allowed_teleports);
if (!route.steps.empty()){
move_ = check_move_action(ui->get_location(), route.steps.back());
} else {
// there is no direct path (yet)
// go to the nearest hex instead.
// maybe a door will open later or something
int closest_distance = -1;
std::pair<map_location,map_location> closest_move;
for(move_map::const_iterator i = get_dstsrc().begin(); i != get_dstsrc().end(); ++i) {
if(i->second != ui->get_location()) {
continue;
}
int distance = distance_between(i->first,ui->get_goto());
if(closest_distance == -1 || distance < closest_distance) {
closest_distance = distance;
closest_move = *i;
}
}
int distance = distance_between(i->first,ui->get_goto());
if(closest_distance == -1 || distance < closest_distance) {
closest_distance = distance;
closest_move = *i;
if(closest_distance != -1) {
move_ = check_move_action(ui->get_location(), closest_move.first);
} else {
return BAD_SCORE;
}
}
if(closest_distance != -1) {
move_ = check_move_action(ui->get_location(), closest_move.first);
if (move_->is_ok()) {
return get_score();
}
if (move_->is_ok()) {
return get_score();
}
}