diff options
Diffstat (limited to 'crawl-ref/source')
-rw-r--r-- | crawl-ref/source/beam.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/directn.cc | 29 | ||||
-rw-r--r-- | crawl-ref/source/los.cc | 42 | ||||
-rw-r--r-- | crawl-ref/source/los.h | 9 | ||||
-rw-r--r-- | crawl-ref/source/spells4.cc | 3 |
5 files changed, 56 insertions, 30 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index fc7c8d2d98..e0c7dc5f99 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -2852,8 +2852,7 @@ bool check_line_of_sight(const coord_def& source, const coord_def& target) // Note that we are guaranteed to be within the player LOS range, // so fallback is unnecessary. - ray_def ray; - return find_ray(source, target, ray); + return exists_ray(source, target); } // When a mimic is hit by a ranged attack, it teleports away (the slow diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc index 15d3ebd572..45aaacbdcb 100644 --- a/crawl-ref/source/directn.cc +++ b/crawl-ref/source/directn.cc @@ -960,26 +960,17 @@ bool _dist_ok(const dist& moves, int range, targ_mode_type mode, return (true); } -// XXX: fold this into generalized find_ray. +// Assuming the target is in view, is line-of-fire +// blocked, and by what? static bool _blocked_ray(const coord_def &where, dungeon_feature_type* feat = NULL) { - ray_def ray; - if (!find_ray(you.pos(), where, ray)) - fallback_ray(you.pos(), where, ray); - ray.advance_through(where); - - while (ray.pos() != where) - { - if (grd(ray.pos()) <= DNGN_MINMOVE) - { - if (feat != NULL) - *feat = grd(ray.pos()); - return (true); - } - ray.advance_through(where); - } - return (false); + if (exists_ray(you.pos(), where)) + return (false); + if (feat == NULL) + return (true); + *feat = ray_blocker(you.pos(), where); + return (true); } void direction(dist& moves, targetting_type restricts, @@ -1316,7 +1307,8 @@ void direction(dist& moves, targetting_type restricts, #ifdef WIZARD case CMD_TARGET_CYCLE_BEAM: show_beam = true; - have_beam = find_ray(you.pos(), moves.target, ray, show_beam); + have_beam = find_ray(you.pos(), moves.target, ray, + opc_solid, bds_default, show_beam); need_beam_redraw = true; break; #endif @@ -3353,6 +3345,7 @@ std::string get_monster_equipment_desc(const monsters *mon, bool full_desc, return desc; } +// Describe a cell, guaranteed to be in view. static void _describe_cell(const coord_def& where, bool in_range) { bool mimic_item = false; diff --git a/crawl-ref/source/los.cc b/crawl-ref/source/los.cc index c7b8ddef74..38de458419 100644 --- a/crawl-ref/source/los.cc +++ b/crawl-ref/source/los.cc @@ -581,8 +581,8 @@ void cellray::calc_params() // opc has been translated for this quadrant. // XXX: Allow finding ray of minimum opacity. bool _find_ray_se(const coord_def& target, ray_def& ray, - bool cycle, const opacity_func& opc, - const bounds_func& bds) + const opacity_func& opc, const bounds_func& bds, + bool cycle) { ASSERT(target.x >= 0 && target.y >= 0 && !target.origin()); if (!bds(target)) @@ -653,8 +653,8 @@ struct opacity_trans : opacity_func // assume that ray is appropriately filled in, and look for the next // ray. We only ever use ray.cycle_idx. bool find_ray(const coord_def& source, const coord_def& target, - ray_def& ray, bool cycle, - const opacity_func& opc, const bounds_func &bds) + ray_def& ray, const opacity_func& opc, const bounds_func &bds, + bool cycle) { if (target == source || !map_bounds(source) || !map_bounds(target)) return false; @@ -666,7 +666,7 @@ bool find_ray(const coord_def& source, const coord_def& target, const coord_def abs = coord_def(absx, absy); opacity_trans opc_trans = opacity_trans(opc, source, signx, signy); - if (!_find_ray_se(abs, ray, cycle, opc_trans, bds)) + if (!_find_ray_se(abs, ray, opc_trans, bds, cycle)) return (false); if (signx < 0) @@ -682,6 +682,38 @@ bool find_ray(const coord_def& source, const coord_def& target, return (true); } +bool exists_ray(const coord_def& source, const coord_def& target, + const opacity_func& opc, const bounds_func &bds) +{ + ray_def ray; + return (find_ray(source, target, ray, opc, bds)); +} + +// Assuming that target is in view of source, but line of +// fire is blocked, what is it blocked by? +dungeon_feature_type ray_blocker(const coord_def& source, + const coord_def& target) +{ + ray_def ray; + if (!find_ray(source, target, ray, opc_default)) + { + ASSERT (false); + return (NUM_REAL_FEATURES); + } + + ray.advance(false); // Must not cut corners! + int blocked = 0; + while (ray.pos() != target) + { + blocked += opc_solid(ray.pos()); + if (blocked >= OPC_OPAQUE) + return (env.grid(ray.pos())); + ray.advance(false); + } + ASSERT (false); + return (NUM_REAL_FEATURES); +} + // Returns a straight ray from source to target. void fallback_ray(const coord_def& source, const coord_def& target, ray_def& ray) diff --git a/crawl-ref/source/los.h b/crawl-ref/source/los.h index 7041c2af0d..92d00090e0 100644 --- a/crawl-ref/source/los.h +++ b/crawl-ref/source/los.h @@ -19,9 +19,12 @@ int get_los_radius_squared(); // XXX struct ray_def; bool find_ray(const coord_def& source, const coord_def& target, - ray_def& ray, bool cycle = false, - const opacity_func &opc = opc_solid, - const bounds_func &bds = bds_default); + ray_def& ray, const opacity_func &opc = opc_solid, + const bounds_func &bds = bds_default, bool cycle = false); +bool exists_ray(const coord_def& source, const coord_def& target, + const opacity_func &opc = opc_solid, + const bounds_func &bds = bds_default); +dungeon_feature_type ray_blocker(const coord_def& source, const coord_def& target); void fallback_ray(const coord_def& source, const coord_def& target, ray_def& ray); diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc index 5fe91b53bd..0339e79934 100644 --- a/crawl-ref/source/spells4.cc +++ b/crawl-ref/source/spells4.cc @@ -1371,8 +1371,7 @@ bool cast_fragmentation(int pow, const dist& spd) bool hole = true; const char *what = NULL; - ray_def ray; - if (!find_ray(you.pos(), spd.target, ray)) + if (!exists_ray(you.pos(), spd.target)) { mpr("There's a wall in the way!"); return (false); |