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:
parent
8bb8b1d27f
commit
fba24f7ca0
11 changed files with 23 additions and 28 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()));
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Reference in a new issue