summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/view.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/view.cc')
-rw-r--r--crawl-ref/source/view.cc92
1 files changed, 88 insertions, 4 deletions
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index 852bb65699..9d53d930d0 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -2064,7 +2064,7 @@ static bool superior_ray(int shortest, int imbalance,
bool find_ray( int sourcex, int sourcey, int targetx, int targety,
bool allow_fallback, ray_def& ray, int cycle_dir,
- bool find_shortest )
+ bool find_shortest, bool ignore_solid )
{
int cellray, inray;
const int signx = ((targetx - sourcex >= 0) ? 1 : -1);
@@ -2106,7 +2106,7 @@ bool find_ray( int sourcex, int sourcey, int targetx, int targety,
{
const int xi = signx * ray_coord_x[inray + cur_offset];
const int yi = signy * ray_coord_y[inray + cur_offset];
- if (inray < cellray
+ if (inray < cellray && !ignore_solid
&& grid_is_solid(grd[sourcex + xi][sourcey + yi]))
{
blocked = true;
@@ -2224,6 +2224,48 @@ bool find_ray( int sourcex, int sourcey, int targetx, int targety,
return false;
}
+// Count the number of matching features between two points along
+// a beam-like path; the path will pass through solid features.
+// By default, it exludes enpoints from the count.
+int num_feats_between(int sourcex, int sourcey, int targetx, int targety,
+ dungeon_feature_type min_feat,
+ dungeon_feature_type max_feat,
+ bool exclude_endpoints)
+{
+ ray_def ray;
+ int count = 0;
+ int max_dist = grid_distance(sourcex, sourcey, targetx, targety);
+
+ ray.fullray_idx = -1; // to quiet valgrind
+ find_ray( sourcex, sourcey, targetx, targety, true, ray, 0, true, true );
+
+ if (exclude_endpoints && ray.x() == sourcex && ray.y() == sourcey)
+ {
+ ray.advance(true);
+ max_dist--;
+ }
+
+ int dist = 0;
+ while (dist++ <= max_dist)
+ {
+ dungeon_feature_type feat = grd[ray.x()][ray.y()];
+
+ if (feat >= min_feat && feat <= max_feat)
+ count++;
+
+ if (ray.x() == targetx && ray.y() == targety)
+ {
+ if (exclude_endpoints && feat >= min_feat && feat <= max_feat)
+ count--;
+
+ break;
+ }
+ ray.advance(true);
+ }
+
+ return count;
+}
+
// The rule behind LOS is:
// Two cells can see each other if there is any line from some point
// of the first to some point of the second ("generous" LOS.)
@@ -2262,7 +2304,8 @@ bool find_ray( int sourcex, int sourcey, int targetx, int targety,
// Smoke will now only block LOS after two cells of smoke. This is
// done by updating with a second array.
void losight(FixedArray < unsigned int, 19, 19 > &sh,
- FixedArray < dungeon_feature_type, 80, 70 > &gr, int x_p, int y_p)
+ FixedArray < dungeon_feature_type, 80, 70 > &gr, int x_p, int y_p,
+ bool clear_walls_block)
{
raycast();
// go quadrant by quadrant
@@ -2299,7 +2342,8 @@ void losight(FixedArray < unsigned int, 19, 19 > &sh,
continue;
// if this cell is opaque...
- if ( grid_is_opaque(gr[realx][realy]) )
+ if ( grid_is_opaque(gr[realx][realy])
+ || (clear_walls_block && grid_is_wall(gr[realx][realy])))
{
// then block the appropriate rays
for ( unsigned int i = 0; i < num_words; ++i )
@@ -3341,6 +3385,33 @@ bool see_grid( int grx, int gry )
return (false);
} // end see_grid()
+// answers the question: "Would a grid be within character's line of sight,
+// even if all translucent/clear walls were made opaque?"
+bool see_grid_no_trans( int grx, int gry )
+{
+ // rare case: can player see self? (of course!)
+ if (grx == you.x_pos && gry == you.y_pos)
+ return (true);
+
+ // check no_trans_show array
+ if (grid_distance( grx, gry, you.x_pos, you.y_pos ) < 9)
+ {
+ const int ex = grx - you.x_pos + 9;
+ const int ey = gry - you.y_pos + 9;
+
+ if (env.no_trans_show[ex][ey])
+ return (true);
+ }
+
+ return (false);
+}
+
+// Is the grid visible, but a translucent wall is in the way?
+bool trans_wall_blocking( int grx, int gry )
+{
+ return see_grid(grx, gry) && !see_grid_no_trans(grx, gry);
+}
+
static const unsigned table[ NUM_CSET ][ NUM_DCHAR_TYPES ] =
{
// CSET_ASCII
@@ -3464,6 +3535,15 @@ void init_feature_table( void )
Feature[i].magic_symbol = Options.char_table[ DCHAR_WALL_MAGIC ];
break;
+ case DNGN_CLEAR_ROCK_WALL:
+ case DNGN_CLEAR_STONE_WALL:
+ case DNGN_CLEAR_PERMAROCK_WALL:
+ Feature[i].symbol = Options.char_table[ DCHAR_WALL ];
+ Feature[i].magic_symbol = Options.char_table[ DCHAR_WALL_MAGIC ];
+ Feature[i].colour = LIGHTCYAN;
+ break;
+
+
case DNGN_OPEN_DOOR:
Feature[i].symbol = Options.char_table[ DCHAR_DOOR_OPEN ];
Feature[i].colour = LIGHTGREY;
@@ -4217,6 +4297,10 @@ void viewwindow(bool draw_it, bool do_updates)
losight( env.show, grd, you.x_pos, you.y_pos ); // must be done first
+ // What would be visible, if all of the translucent walls were
+ // made opaque.
+ losight( env.no_trans_show, grd, you.x_pos, you.y_pos, true );
+
env.show_col.init(LIGHTGREY);
Show_Backup.init(0);