vaults (reported by Eino).
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1829 c06c8d41-db1a-0410-9941-cceddc491573
FZAQNANLZOQHX675KR5GE2ZAVNT4AWX4TWEUJXXEZMOXWQ5FDHOAC
C22455VGUQOSUX2OORA32LROFQ7NNYDMD2ZDTTUZSAQLXK4AD6QAC
ILOED4VB4I6VPAUTR75ZWX6MXDYXB5DO2EDK2UH67O3HNKWV23RQC
7J3H7JY6AUO2UHNF6DAHDZI4O33JMTUUTYTPRM3CKNPUOF2RQOGAC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
MSQI3TH6T62JAXQGLL52QZCWAMC372TGB6ZNNRDGUGMJKBNNV2VAC
KCHX2F3JFEWOZT3WMJVZAAQUU2QSZ5Q7RDCD7WUJ7VE65J52JFUQC
static bool join_the_dots(
const coord_def &from,
const coord_def &to,
unsigned mmask,
bool early_exit = false);
static bool join_the_dots(const coord_def &from, const coord_def &to,
unsigned mmask, bool early_exit = false);
static bool join_the_dots_rigorous(const coord_def &from,
const coord_def &to,
unsigned mapmask,
bool early_exit = false);
struct coord_comparator
{
coord_def target;
coord_comparator(const coord_def &t) : target(t) { }
static int dist(const coord_def &a, const coord_def &b)
{
const coord_def del = a - b;
return std::abs(del.x) * GYM + std::abs(del.y);
}
bool operator () (const coord_def &a, const coord_def &b) const
{
return dist(a, target) < dist(b, target);
}
};
typedef std::set<coord_def, coord_comparator> coord_set;
static void jtd_init_surrounds(coord_set &coords,
unsigned mapmask,
const coord_def &c)
{
for (int yi = -1; yi <= 1; ++yi)
{
for (int xi = -1; xi <= 1; ++xi)
{
if (!xi == !yi)
continue;
const coord_def cx(c.x + xi, c.y + yi);
if (!in_bounds(cx) || travel_point_distance[cx.x][cx.y]
|| !unforbidden(cx, mapmask))
{
continue;
}
coords.insert(cx);
travel_point_distance[cx.x][cx.y] = (-xi + 2) * 4 + (-yi + 2);
}
}
}
static bool join_the_dots_pathfind(coord_set &coords,
const coord_def &from,
const coord_def &to,
unsigned mapmask,
bool early_exit)
{
coord_def curr = from;
while (true)
{
int &tpd = travel_point_distance[curr.x][curr.y];
tpd = !tpd? -1000 : -tpd;
if (curr == to)
break;
jtd_init_surrounds(coords, mapmask, curr);
if (coords.empty())
break;
curr = *coords.begin();
coords.erase(coords.begin());
}
if (curr != to)
return (false);
while (curr != from)
{
if (unforbidden(curr, mapmask))
grd(curr) = DNGN_FLOOR;
const int dist = travel_point_distance[curr.x][curr.y];
ASSERT(dist < 0 && dist != -1000);
curr += coord_def(-dist / 4 - 2, (-dist % 4) - 2);
}
if (unforbidden(curr, mapmask))
grd(curr) = DNGN_FLOOR;
return (true);
}
static bool join_the_dots_rigorous(const coord_def &from,
const coord_def &to,
unsigned mapmask,
bool early_exit)
{
memset(travel_point_distance, 0, sizeof(travel_distance_grid_t));
const coord_comparator comp(to);
coord_set coords(comp);
const bool found =
join_the_dots_pathfind(coords, from, to, mapmask, early_exit);
return (found);
}