summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authorRobert Vollmert <rvollmert@gmx.net>2009-10-08 22:40:29 +0200
committerRobert Vollmert <rvollmert@gmx.net>2009-10-08 22:45:29 +0200
commitd87a308f449bb959db24495e2a1dc307924bc8ae (patch)
tree0f8a71bea75914d2351e45daa08345aba547121b /crawl-ref/source
parent9cc7466db06f418c165ed79fd6bfdfe334a6a568 (diff)
downloadcrawl-ref-d87a308f449bb959db24495e2a1dc307924bc8ae.tar.gz
crawl-ref-d87a308f449bb959db24495e2a1dc307924bc8ae.zip
Split and correct grid_see_grid.
There's now cell_see_cell which tests for visibility correctly, albeit slowly. That's only used for placing features in the abyss currently, but needs to be improved if it gets used more. The second function used in monster movement was left as is, but renamed to can_go_straight. This remains unreliable but probably serves its purpose. The grid_see_grid test is adapted to cell_see_cell; the grid_see_grid lua binding is now actually useful. Also reduce the number of tests in los_csc and los_symm.
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/abyss.cc2
-rw-r--r--crawl-ref/source/los.cc28
-rw-r--r--crawl-ref/source/los.h5
-rw-r--r--crawl-ref/source/losparam.cc25
-rw-r--r--crawl-ref/source/losparam.h15
-rw-r--r--crawl-ref/source/luadgn.cc7
-rw-r--r--crawl-ref/source/monplace.cc4
-rw-r--r--crawl-ref/source/monstuff.cc10
-rw-r--r--crawl-ref/source/test/los_csc.lua (renamed from crawl-ref/source/test/los_gsg.lua)16
-rw-r--r--crawl-ref/source/test/los_symm.lua2
10 files changed, 75 insertions, 39 deletions
diff --git a/crawl-ref/source/abyss.cc b/crawl-ref/source/abyss.cc
index 9effca870f..f8c331ad00 100644
--- a/crawl-ref/source/abyss.cc
+++ b/crawl-ref/source/abyss.cc
@@ -60,7 +60,7 @@ static bool _place_feature_near(const coord_def &centre,
if (cp == centre || (cp - centre).abs() > radius2 || !in_bounds(cp))
continue;
- if (not_seen && grid_see_grid(cp, centre))
+ if (not_seen && cell_see_cell(cp, centre))
continue;
if (grd(cp) == candidate)
diff --git a/crawl-ref/source/los.cc b/crawl-ref/source/los.cc
index 6aa70e0661..f585b65d58 100644
--- a/crawl-ref/source/los.cc
+++ b/crawl-ref/source/los.cc
@@ -682,14 +682,23 @@ int num_feats_between(const coord_def& source, const coord_def& target,
return (count);
}
-// Usually calculates whether from one grid someone could see the other.
-// Depending on the viewer's habitat, 'allowed' can be set to DNGN_FLOOR,
-// DNGN_SHALLOW_WATER or DNGN_DEEP_WATER.
-// Yes, this ignores lava-loving monsters.
-// XXX: It turns out the beams are not symmetrical, i.e. switching
-// pos1 and pos2 may result in small variations.
-bool grid_see_grid(const coord_def& p1, const coord_def& p2,
- dungeon_feature_type allowed)
+// Is p2 visible from p1, disregarding clouds?
+// XXX: Horribly inefficient since we do an entire LOS calculation;
+// needs to be rewritten if it is used more.
+bool cell_see_cell(const coord_def& p1, const coord_def& p2)
+{
+ env_show_grid show;
+ losight(show, los_param_nocloud(p1));
+ return see_grid(show, p1, p2);
+}
+
+// Checks whether there is a straight path from p1 to p2 that passes
+// through features >= allowed.
+// If it exists, such a path may be missed; on the other hand, it
+// is not guaranteed that p2 is visible from p1 according to LOS rules.
+// Not symmetric.
+bool can_go_straight(const coord_def& p1, const coord_def& p2,
+ dungeon_feature_type allowed)
{
if (distance(p1, p2) > _los_radius_squared)
return (false);
@@ -698,7 +707,6 @@ bool grid_see_grid(const coord_def& p1, const coord_def& p2,
if (allowed != DNGN_UNSEEN)
max_disallowed = static_cast<dungeon_feature_type>(allowed - 1);
- // XXX: Ignoring clouds for now.
return (!num_feats_between(p1, p2, DNGN_UNSEEN, max_disallowed,
true, true));
}
@@ -756,6 +764,8 @@ void _losight_quadrant(env_show_grid& sh, const los_param& dat, int sx, int sy)
for (int x = 0; x <= LOS_MAX_RANGE_X; ++x)
for (int y = 0; y <= LOS_MAX_RANGE_Y; ++y, inptr += num_words)
{
+ if (x == 0 && y == 0)
+ continue;
coord_def p = coord_def(sx*x, sy*y);
if (!dat.map_bounds(p))
continue;
diff --git a/crawl-ref/source/los.h b/crawl-ref/source/los.h
index c28561724b..379983c095 100644
--- a/crawl-ref/source/los.h
+++ b/crawl-ref/source/los.h
@@ -27,8 +27,9 @@ int num_feats_between(const coord_def& source, const coord_def& target,
dungeon_feature_type max_feat,
bool exclude_endpoints = true,
bool just_check = false);
-bool grid_see_grid(const coord_def& p1, const coord_def& p2,
- dungeon_feature_type allowed = DNGN_UNSEEN);
+bool cell_see_cell(const coord_def& p1, const coord_def& p2);
+bool can_go_straight(const coord_def& p1, const coord_def& p2,
+ dungeon_feature_type allowed);
void clear_rays_on_exit();
void losight(env_show_grid& sh, const los_param& dat);
diff --git a/crawl-ref/source/losparam.cc b/crawl-ref/source/losparam.cc
index 85e0954499..cd746d0b58 100644
--- a/crawl-ref/source/losparam.cc
+++ b/crawl-ref/source/losparam.cc
@@ -50,23 +50,40 @@ opacity_type los_param_permissive::opacity(const coord_def& p) const
}
-/* los_param_base */
+/* los_param_nocloud */
-los_param_base::los_param_base(const coord_def& c)
+los_param_nocloud::los_param_nocloud(const coord_def& c)
: los_param_trans(c)
{
}
-dungeon_feature_type los_param_base::feature(const coord_def& p) const
+dungeon_feature_type los_param_nocloud::feature(const coord_def& p) const
{
return env.grid(trans(p));
}
-unsigned los_param_base::appearance(const coord_def& p) const
+unsigned los_param_nocloud::appearance(const coord_def& p) const
{
return grid_appearance(trans(p));
}
+opacity_type los_param_nocloud::opacity(const coord_def& p) const
+{
+ dungeon_feature_type f = feature(p);
+ if (grid_is_opaque(f))
+ return OPC_OPAQUE;
+ else
+ return OPC_CLEAR;
+}
+
+
+/* los_param_base */
+
+los_param_base::los_param_base(const coord_def& c)
+ : los_param_nocloud(c)
+{
+}
+
unsigned short los_param_base::cloud_idx(const coord_def& p) const
{
return env.cgrid(trans(p));
diff --git a/crawl-ref/source/losparam.h b/crawl-ref/source/losparam.h
index fba1506b42..1d6b579565 100644
--- a/crawl-ref/source/losparam.h
+++ b/crawl-ref/source/losparam.h
@@ -54,14 +54,21 @@ struct los_param_permissive : los_param_trans
opacity_type opacity(const coord_def& p) const;
};
-// A complete base implementation that does standard visibility
-// based on env.grid.
-struct los_param_base : los_param_trans
+// Standard visibility disregarding clouds.
+struct los_param_nocloud : los_param_trans
{
- los_param_base(const coord_def& c);
+ los_param_nocloud(const coord_def& c);
dungeon_feature_type feature(const coord_def& p) const;
unsigned appearance(const coord_def& p) const;
+ opacity_type opacity(const coord_def& p) const;
+};
+
+// Standard visibility.
+struct los_param_base : los_param_nocloud
+{
+ los_param_base(const coord_def& c);
+
unsigned short cloud_idx(const coord_def& p) const;
opacity_type opacity(const coord_def& p) const;
};
diff --git a/crawl-ref/source/luadgn.cc b/crawl-ref/source/luadgn.cc
index 8a33b2873a..f377397337 100644
--- a/crawl-ref/source/luadgn.cc
+++ b/crawl-ref/source/luadgn.cc
@@ -2980,11 +2980,11 @@ LUAFN(dgn_dbg_dump_map)
return (0);
}
-LUAFN(dgn_grid_see_grid)
+LUAFN(dgn_cell_see_cell)
{
COORDS(p, 1, 2);
COORDS(q, 3, 4);
- return grid_see_grid(p, q);
+ PLUARET(number, cell_see_cell(p, q));
}
static const struct luaL_reg dgn_lib[] =
@@ -3005,7 +3005,6 @@ static const struct luaL_reg dgn_lib[] =
{ "chance", dgn_chance },
{ "weight", dgn_weight },
{ "welcome", dgn_welcome },
- { "weight", dgn_weight },
{ "orient", dgn_orient },
{ "shuffle", dgn_shuffle },
{ "shuffle_remove", dgn_shuffle_remove },
@@ -3134,7 +3133,7 @@ static const struct luaL_reg dgn_lib[] =
{ "lev_floortile", dgn_lev_floortile },
{ "lev_rocktile", dgn_lev_rocktile },
- { "grid_see_grid", dgn_grid_see_grid },
+ { "cell_see_cell", dgn_cell_see_cell },
{ NULL, NULL }
};
diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc
index 0e4f5be852..72597b1746 100644
--- a/crawl-ref/source/monplace.cc
+++ b/crawl-ref/source/monplace.cc
@@ -3159,7 +3159,7 @@ std::vector<coord_def> monster_pathfind::backtrack()
// Reduces the path coordinates to only a couple of key waypoints needed
// to reach the target. Waypoints are chosen such that from one waypoint you
// can see (and, more importantly, reach) the next one. Note that
-// grid_see_grid() is probably rather too conservative in these estimates.
+// can_go_straight() is probably rather too conservative in these estimates.
// This is done because Crawl's pathfinding - once a target is in sight and easy
// reach - is both very robust and natural, especially if we want to flexibly
// avoid plants and other monsters in the way.
@@ -3185,7 +3185,7 @@ std::vector<coord_def> monster_pathfind::calc_waypoints()
#endif
for (unsigned int i = 1; i < path.size(); i++)
{
- if (grid_see_grid(pos, path[i], can_move))
+ if (can_go_straight(pos, path[i], can_move))
continue;
else
{
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 5aeb730834..54ae2b7805 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -3562,7 +3562,7 @@ static bool _try_pathfind(monsters *mon, const dungeon_feature_type can_move,
}
if (!potentially_blocking
- || grid_see_grid(mon->pos(), you.pos(), can_move))
+ || can_go_straight(mon->pos(), you.pos(), can_move))
{
// The player is easily reachable.
// Clear travel path and target, if necessary.
@@ -3591,7 +3591,7 @@ static bool _try_pathfind(monsters *mon, const dungeon_feature_type can_move,
const coord_def targ = mon->travel_path[len - 1];
// Current target still valid?
- if (grid_see_grid(targ, you.pos(), can_move))
+ if (can_go_straight(targ, you.pos(), can_move))
{
// Did we reach the target?
if (mon->pos() == mon->travel_path[0])
@@ -3605,7 +3605,7 @@ static bool _try_pathfind(monsters *mon, const dungeon_feature_type can_move,
return (true);
}
}
- else if (grid_see_grid(mon->pos(), mon->travel_path[0],
+ else if (can_go_straight(mon->pos(), mon->travel_path[0],
can_move))
{
mon->target = mon->travel_path[0];
@@ -3944,7 +3944,7 @@ static bool _handle_monster_travelling(monsters *mon,
}
// Can we still see our next waypoint?
- if (!grid_see_grid(mon->pos(), mon->travel_path[0], can_move))
+ if (!can_go_straight(mon->pos(), mon->travel_path[0], can_move))
{
#ifdef DEBUG_PATHFIND
mpr("Can't see waypoint grid.");
@@ -3962,7 +3962,7 @@ static bool _handle_monster_travelling(monsters *mon,
const int size = mon->travel_path.size();
for (int i = size - 1; i >= 0; --i)
{
- if (grid_see_grid(mon->pos(), mon->travel_path[i], can_move))
+ if (can_go_straight(mon->pos(), mon->travel_path[i], can_move))
{
mon->target = mon->travel_path[i];
erase = i;
diff --git a/crawl-ref/source/test/los_gsg.lua b/crawl-ref/source/test/los_csc.lua
index 69b86d1da7..499511a6c2 100644
--- a/crawl-ref/source/test/los_gsg.lua
+++ b/crawl-ref/source/test/los_csc.lua
@@ -3,11 +3,13 @@
local FAILMAP = 'losfail.map'
local checks = 0
-local function test_gridseegrid_symmetry()
+local function test_cellseecell_symmetry()
-- Clear messages to prevent them accumulating and forcing a --more--
crawl.mesclr()
-- Send the player to a random spot on the level.
you.random_teleport()
+ you.losight()
+ crawl.redraw_view()
checks = checks + 1
local you_x, you_y = you.pos()
@@ -16,8 +18,8 @@ local function test_gridseegrid_symmetry()
for x = -9, 9 do
local px, py = x + you_x, y + you_y
if (x ~= 0 or y ~= 0) and dgn.in_bounds(px, py) then
- local foreward = dgn.grid_see_grid(you_x, you_y, px, py)
- local backward = dgn.grid_see_grid(px, py, you_x, you_y)
+ local foreward = dgn.cell_see_cell(you_x, you_y, px, py)
+ local backward = dgn.cell_see_cell(px, py, you_x, you_y)
this_p = dgn.point(you_x, you_y)
other_p = dgn.point(px, py)
if not forward then
@@ -26,11 +28,11 @@ local function test_gridseegrid_symmetry()
this_p = other_p
other_p = temp
end
- if forward ~= backward then
+ if (forward and backward) or (not forward and not backward) then
dgn.grid(other_p.x, other_p.y, "floor_special")
dgn.dbg_dump_map(FAILMAP)
assert(false,
- "grid_see_grid asymmetry detected (iter #" .. checks .. "): "
+ "cell_see_cell asymmetry detected (iter #" .. checks .. "): "
.. this_p .. " sees " .. other_p .. ", but not vice versa."
.. " Map saved to " .. FAILMAP)
end
@@ -48,11 +50,11 @@ local function run_los_tests(depth, nlevels, tests_per_level)
dgn.dbg_flush_map_memory()
dgn.dbg_generate_level()
for t_i = 1, tests_per_level do
- test_gridseegrid_symmetry()
+ test_cellseecell_symmetry()
end
end
end
for depth = 1, 27 do
- run_los_tests(depth, 1, 10)
+ run_los_tests(depth, 1, 1)
end
diff --git a/crawl-ref/source/test/los_symm.lua b/crawl-ref/source/test/los_symm.lua
index beb809beee..43bce66928 100644
--- a/crawl-ref/source/test/los_symm.lua
+++ b/crawl-ref/source/test/los_symm.lua
@@ -63,5 +63,5 @@ local function run_los_tests(depth, nlevels, tests_per_level)
end
for depth = 1, 27 do
- run_los_tests(depth, 1, 10)
+ run_los_tests(depth, 1, 3)
end