Fix wesnoth.find_reach failing for private lua proxy units.

Modified pathfind::paths to take a unit as argument instead of its
location; updated all callers.

As observed by mattsc, the function did in its callstack
re-query the unit at the location of a passed private proxy unit,
calculating the reach for the unit in the unit_map at that
location instead of the private one.

The other pathfind bindings already work for private proxy
units. Private lua proxy units were introduced after the pathfinder
functions were already exposed in the lua API.
This commit is contained in:
Anonymissimus 2012-03-18 00:19:09 +00:00
parent 8bb8b1d27f
commit fba24f7ca0
11 changed files with 23 additions and 28 deletions

View file

@ -2334,7 +2334,7 @@ namespace {
return false;
}
pathfind::paths p(*resources::game_map, *resources::units, loc, *resources::teams, true, false, tm, 0, false, true);
pathfind::paths p(*resources::game_map, *resources::units, *u, *resources::teams, true, false, tm, 0, false, true);
foreach (const pathfind::paths::step &dest, p.destinations) {
clear_shroud_loc(tm, dest.curr, &cleared_locations);
}

View file

@ -349,7 +349,7 @@ void readonly_context_impl::calculate_moves(const unit_map& units, std::map<map_
}
res.insert(std::pair<map_location,pathfind::paths>(
un_it->get_location(), pathfind::paths(*resources::game_map,
units, un_it->get_location(), *resources::teams, false,
units, *un_it, *resources::teams, false,
true, current_team(), 0, see_all)));
}
@ -919,7 +919,7 @@ bool readonly_context_impl::leader_can_reach_keep() const
// Find where the leader can move
const pathfind::paths leader_paths(*resources::game_map, *resources::units,
leader->get_location(), *resources::teams, false, true, current_team());
*leader, *resources::teams, false, true, current_team());
return leader_paths.destinations.contains(start_pos);
}

View file

@ -667,10 +667,11 @@ private:
variant execute(const formula_callable& variables, formula_debugger *fdb) const {
const map_location loc = convert_variant<location_callable>(args()[0]->evaluate(variables,add_debug_info(fdb,0,"suitable_keep:location")))->loc();
const unit_map& units = *resources::units;
if (units.find(loc) == units.end()){
const unit_map::const_iterator u = units.find(loc);
if (u == units.end()){
return variant();
}
const pathfind::paths unit_paths(*resources::game_map, units, loc ,*resources::teams, false, true, ai_.current_team());
const pathfind::paths unit_paths(*resources::game_map, units, *u ,*resources::teams, false, true, ai_.current_team());
return variant(new location_callable(ai_.suitable_keep(loc,unit_paths)));
}

View file

@ -153,7 +153,7 @@ static int cfun_ai_get_suitable_keep(lua_State *L)
}
else return luaL_typerror(L, 1, "unit");
const map_location loc = leader->get_location();
const pathfind::paths leader_paths(*resources::game_map, *resources::units, loc,
const pathfind::paths leader_paths(*resources::game_map, *resources::units, *leader,
*resources::teams, false, true, context.current_team());
const map_location &res = context.suitable_keep(loc,leader_paths);
if (!res.valid()) {

View file

@ -679,7 +679,7 @@ double move_leader_to_goals_phase::evaluate()
return BAD_SCORE;
}
const pathfind::paths leader_paths(*resources::game_map, *resources::units, leader->get_location(),
const pathfind::paths leader_paths(*resources::game_map, *resources::units, *leader,
*resources::teams, false, true, current_team());
std::map<map_location,pathfind::paths> possible_moves;
@ -753,7 +753,7 @@ double move_leader_to_keep_phase::evaluate()
}
// Find where the leader can move
const pathfind::paths leader_paths(*resources::game_map, units_, leader->get_location(),
const pathfind::paths leader_paths(*resources::game_map, units_, *leader,
*resources::teams, false, true, current_team());
const map_location& keep = suitable_keep(leader->get_location(), leader_paths);
if (keep == map_location::null_location) {

View file

@ -1354,7 +1354,7 @@ void menu_handler::show_enemy_moves(bool ignore_units, int side_num)
{
const unit_movement_resetter move_reset(*u);
const pathfind::paths& path = pathfind::paths(map_,units_,
u->get_location(), teams_, false, true,
*u, teams_, false, true,
teams_[gui_->viewing_team()], 0, false, ignore_units);
gui_->highlight_another_reach(path);

View file

@ -267,7 +267,7 @@ void mouse_handler::mouse_motion(int x, int y, const bool browse, bool update, m
{ // start planned unit map scope
wb::future_map_if_active raii;
current_paths_ = pathfind::paths(map_,units_,new_hex,teams_,
current_paths_ = pathfind::paths(map_,units_,*un,teams_,
false,true,viewing_team(),path_turns_);
} // end planned unit map scope
@ -624,7 +624,7 @@ void mouse_handler::select_hex(const map_location& hex, const bool browse, const
next_unit_ = u->get_location();
{
current_paths_ = pathfind::paths(map_, units_, hex, teams_,
current_paths_ = pathfind::paths(map_, units_, *u, teams_,
false, true, viewing_team(), path_turns_);
}
if(highlight) {

View file

@ -170,13 +170,14 @@ struct comp {
}
static void find_routes(const gamemap& map, const unit_map& /*units*/,
const unit& u, const map_location& loc,
const unit& u,
int move_left, pathfind::paths::dest_vect &destinations,
std::vector<team> const &teams,
bool force_ignore_zocs, bool allow_teleport, int turns_left,
const team &viewing_team,
bool see_all, bool ignore_units)
{
const map_location loc = u.get_location();
const team& current_team = teams[u.side() - 1];
pathfind::teleport_map teleports;
if (allow_teleport) {
@ -347,23 +348,17 @@ bool pathfind::paths::dest_vect::contains(const map_location &loc) const
}
pathfind::paths::paths(gamemap const &map, unit_map const &units,
map_location const &loc, std::vector<team> const &teams,
const unit& u, std::vector<team> const &teams,
bool force_ignore_zoc, bool allow_teleport, const team &viewing_team,
int additional_turns, bool see_all, bool ignore_units)
: destinations()
{
const unit_map::const_iterator i = units.find(loc);
if(i == units.end()) {
ERR_PF << "paths::paths() -- unit not found\n";
if (u.side() < 1 || u.side() > int(teams.size())) {
return;
}
if (i->side() < 1 || i->side() > int(teams.size())) {
return;
}
find_routes(map, units, *i, loc,
i->movement_left(), destinations, teams, force_ignore_zoc,
find_routes(map, units, u,
u.movement_left(), destinations, teams, force_ignore_zoc,
allow_teleport,additional_turns,viewing_team,
see_all, ignore_units);
}

View file

@ -86,7 +86,7 @@ struct paths
// viewing_team is usually current team, except for Show Enemy Moves etc.
paths(gamemap const &map,
unit_map const &units,
map_location const &loc, std::vector<team> const &teams,
const unit& u, std::vector<team> const &teams,
bool force_ignore_zocs, bool allow_teleport,
const team &viewing_team, int additional_turns = 0,
bool see_all = false, bool ignore_units = false);

View file

@ -1061,7 +1061,7 @@ void play_controller::process_keyup_event(const SDL_Event& event) {
// if it's not the unit's turn, we reset its moves
unit_movement_resetter move_reset(*u, u->side() != player_number_);
mouse_handler_.set_current_paths(pathfind::paths(map_, units_, u->get_location(),
mouse_handler_.set_current_paths(pathfind::paths(map_, units_, *u,
teams_,false,true, teams_[gui_->viewing_team()],
mouse_handler_.get_path_turns()));

View file

@ -1502,7 +1502,7 @@ static int intf_highlight_hex(lua_State *L)
unit_map::const_unit_iterator i = resources::units->find(loc);
if(i != resources::units->end()) {
resources::screen->highlight_reach(pathfind::paths(
*resources::game_map, *resources::units, loc, *resources::teams, false,
*resources::game_map, *resources::units, *i, *resources::teams, false,
(*i).get_ability_bool("teleport"), resources::teams->front()));
}
@ -2157,18 +2157,17 @@ static int intf_find_path(lua_State *L)
static int intf_find_reach(lua_State *L)
{
int arg = 1;
map_location src;
unit_map &units = *resources::units;
const unit *u = NULL;
if (lua_isuserdata(L, arg))
{
u = luaW_checkunit(L, 1);
src = u->get_location();
++arg;
}
else
{
map_location src;
src.x = luaL_checkinteger(L, arg) - 1;
++arg;
src.y = luaL_checkinteger(L, arg) - 1;
@ -2213,7 +2212,7 @@ static int intf_find_reach(lua_State *L)
}
team &viewing_team = teams[(viewing_side ? viewing_side : u->side()) - 1];
pathfind::paths res(map, units, src, teams, ignore_units, !ignore_teleport,
pathfind::paths res(map, units, *u, teams, ignore_units, !ignore_teleport,
viewing_team, additional_turns, see_all, ignore_units);
int nb = res.destinations.size();