summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref')
-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