diff options
author | zelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573> | 2007-09-19 06:42:50 +0000 |
---|---|---|
committer | zelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573> | 2007-09-19 06:42:50 +0000 |
commit | 4958b84b497fe729eaf14bc90b8d01874722c33d (patch) | |
tree | 12bce6e34f779166f7cdcefee95255b53d9ba8b3 /crawl-ref/source/monstuff.cc | |
parent | 63318a4b57b03ffc4686e4a3b78d64b73f50b6b9 (diff) | |
download | crawl-ref-4958b84b497fe729eaf14bc90b8d01874722c33d.tar.gz crawl-ref-4958b84b497fe729eaf14bc90b8d01874722c33d.zip |
Introduces three new wall types, translucent versions of the normal
rock wall, stone wall and permanent rock wall. These are for use in
vaults, and are never randomly generated. Magically translucent
versions of the normal wall types are used, rather than glass, so we
don't have to figure out how glass would react to things like digging
and Shatter, but can re-use the code for the normal wall types.
I've tried to fix all the places where the old code assumes that any
square which is visible to the player has no walls between it and the
player, but I've probably missed lots; this will require a lot of play
testing before its ready for non-developers.
viewwindow() now has two calls to losight(), the second one
determining what squares would be visible if all translucent walls
were made transparent, so that there's a quick way to see if there's
any translucent walls between the player and a square. This second
call to losight() doesn't cause any noticeable slowdown for me, but it
might on an older system.
Other than viewwindow() making a second call to losight(), there
shouldn't be any changes to game-play or game-logic if there aren't any
translucent walls around.
The wizard blinking command (&b) has been changed so that it ignores
all normal restrictions except for needing to see the target square and
not landing on monsters; if the player lands on a wall square it's
changed to floor. Wizard blinking also doesn't increase magical
contamination.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2145 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/monstuff.cc')
-rw-r--r-- | crawl-ref/source/monstuff.cc | 97 |
1 files changed, 81 insertions, 16 deletions
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 47ecdc7e8d..ef499b6f53 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -1245,31 +1245,93 @@ bool monster_blink(monsters *monster) // allow_adjacent: allow target to be adjacent to origin // restrict_LOS: restict target to be within PLAYER line of sight bool random_near_space(int ox, int oy, int &tx, int &ty, bool allow_adjacent, - bool restrict_LOS) + bool restrict_LOS) { - int tries = 0; - do + // This might involve ray tracing (via num_feats_between()), so + // cache results to avoid duplicating ray traces. + FixedArray<bool, 14, 14> tried; + tried.init(false); + + // Is the monster on the other side of a tranparent wall? + bool trans_wall_block = trans_wall_blocking(ox, oy); + bool origin_is_player = (you.pos() == coord_def(ox, oy)); + int min_walls_between = 0; + + // Skip ray tracing if possible. + if (trans_wall_block) + min_walls_between = num_feats_between(ox, oy, you.x_pos, you.y_pos, + DNGN_CLEAR_ROCK_WALL, + DNGN_CLEAR_PERMAROCK_WALL); + int tries = 0; + while (tries++ < 150) { - tx = ox - 6 + random2(14); - ty = oy - 6 + random2(14); + int dx = random2(14); + int dy = random2(14); + + tx = ox - 6 + dx; + ty = oy - 6 + dy; // origin is not 'near' if (tx == ox && ty == oy) continue; - tries++; + if (tried[dx][dy]) + continue; - if (tries > 149) - break; + tried[dx][dy] = true; + + if ((!see_grid(tx, ty) && restrict_LOS) + || grd[tx][ty] < DNGN_SHALLOW_WATER + || mgrd[tx][ty] != NON_MONSTER + || (tx == you.x_pos && ty == you.y_pos) + || (!allow_adjacent && distance(ox, oy, tx, ty) <= 2)) + continue; + + if (!trans_wall_block && !origin_is_player) + return (true); + + // If the monster is on a visible square which is on the other + // side of one or more translucent from the player, then it + // can only blink through translucent walls if the end point + // is either not visible to the player, or there are at least + // as many translucent walls between the player and the end + // point as between the player and the start point. However, + // monsters can still blink through translucent walls to get + // away from the player, since in the absence of tranlucent + // walls monsters can blink to places which are not in either + // the monster's nor the player's LOS. + if (!see_grid(tx, ty) && !origin_is_player) + return (true); + + // Player can't randomly pass through translucent walls. + if (origin_is_player) + { + if (see_grid_no_trans(tx, ty)) + return (true); + + continue; + } + + int walls_passed = num_feats_between(tx, ty, ox, oy, + DNGN_CLEAR_ROCK_WALL, + DNGN_CLEAR_PERMAROCK_WALL); + if (walls_passed == 0) + return (true); + + // Player can't randomly pass through translucent walls. + if (origin_is_player) + continue; + + int walls_between = num_feats_between(tx, ty, you.x_pos, you.y_pos, + DNGN_CLEAR_ROCK_WALL, + DNGN_CLEAR_PERMAROCK_WALL); + + if (walls_between >= min_walls_between) + return (true); } - while ((!see_grid(tx, ty) && restrict_LOS) - || grd[tx][ty] < DNGN_SHALLOW_WATER - || mgrd[tx][ty] != NON_MONSTER - || (tx == you.x_pos && ty == you.y_pos) - || (!allow_adjacent && distance(ox, oy, tx, ty) <= 2)); - return (tries < 150); + return (false); } // end random_near_space() static bool habitat_okay( const monsters *monster, int targ ) @@ -4597,7 +4659,8 @@ static void monster_move(monsters *monster) deep_water_available = true; if (monster->type == MONS_BORING_BEETLE - && target_grid == DNGN_ROCK_WALL) + && (target_grid == DNGN_ROCK_WALL + || target_grid == DNGN_CLEAR_ROCK_WALL)) { // don't burrow out of bounds if (targ_x <= 7 || targ_x >= (GXM - 8) @@ -4948,7 +5011,9 @@ forget_it: // take care of beetle burrowing if (monster->type == MONS_BORING_BEETLE) { - if (grd[monster->x + mmov_x][monster->y + mmov_y] == DNGN_ROCK_WALL + dungeon_feature_type feat = + grd[monster->x + mmov_x][monster->y + mmov_y]; + if ((feat == DNGN_ROCK_WALL || feat == DNGN_ROCK_WALL) && good_move[mmov_x + 1][mmov_y + 1] == true) { grd[monster->x + mmov_x][monster->y + mmov_y] = DNGN_FLOOR; |