diff options
-rw-r--r-- | crawl-ref/source/abyss.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/los.cc | 28 | ||||
-rw-r--r-- | crawl-ref/source/los.h | 5 | ||||
-rw-r--r-- | crawl-ref/source/losparam.cc | 25 | ||||
-rw-r--r-- | crawl-ref/source/losparam.h | 15 | ||||
-rw-r--r-- | crawl-ref/source/luadgn.cc | 7 | ||||
-rw-r--r-- | crawl-ref/source/monplace.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 10 | ||||
-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.lua | 2 |
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 ¢re, 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 |