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
AUXVWXWIFSTWFA6VZXN2FMG7FQEKRZVV6MD32VQQ7J2RKCXHAVGAC
T5XERKCC6UL2UI2HKE34BTKNINTOXOSDCBYGC3A3JY7XMKIQW4GQC
4PKN27E55QIIHAAGJ3G7XSIYYELDO3HQUPVLVWCFGCUBYDSKL3DQC
DH3D44HGNRXTSZLL5HTHKOPKCO4VZQZVBEMFOAPRJGQMLGN2BFQAC
E7DV36ZR6TOGBD75BHGARCMIQQS6MSV7V3A7M7V4LOFHEC5NF6CQC
SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC
ILOED4VB4I6VPAUTR75ZWX6MXDYXB5DO2EDK2UH67O3HNKWV23RQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
GVCGKTH5IJ4VSQEIN4CRC7ZFVZW26JPIYNCPTO7GY66CSZZEW3ZQC
V4WGXVERZ34B7CEINV4D3ZYEKKT2TUIUYTOX5FSOX6B26U3DPVLQC
TZ643KHSE5CUPXFSQ7VYVOCM5MTQ7F4SENEYQX2RNFHGHLQVS3RQC
77H4BWWPPGLM3PLZH4QTAJRXIZTSDVNCOKZE223I437FN2UJ34RQC
WG6O475IOLZFMUQSLVR2KHM7XTBF5HH276L2KDGF7UOSESDOAILQC
GT7BSR54BVJKHUCLEBTELGBMNBFFDQW52EVC4XKVEMUVG2UGZMDAC
B4X67DGLW77QLGPTMORE2EJ5K5VA3TWIU23HFUF4TZDODXQSFLRQC
EOMCPVNQLX3IMLC46EAO67DPBH5KEG2FQTPBLGU62HIRWA3UQ7XQC
I2B33Z7NZGC33AMDSSK446AZZYWKPHWLAGULVHKKZU4MVB4BNJOAC
YHSVOROKPYS33Y4RYZRVZTE3G5LXOFX52HEDNLV6HIXOJYNOKH3QC
W7KGGF2VUXLD6YH55EPIRQ5SF5VKVKT33P6RNKCFCVQ4QXOLQE7AC
IVVTHLTTLOP5TSULXJWUSSXHOKYWVU3OWKYVK45A7RIB6V34MYQAC
AUXHSGS4EFOPZ6TVZYWNVOUDO7NYKUKE3HBKGQQWTALSVFOE3HAAC
GQL5SIGBHLU3FMCE54XVGLRY5AZHRM6DUEB722REA2DPLGJSN6EQC
UH3CJQMQ3NPICXD34NTCTUZJWOCEF4P5XEGXFLLNDDFLZK7QPUBQC
OYTCBRC7LE44EUVRZVYTOOVKQWJ6P6YE3FXTOGUTNKEMLNWPHKSQC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
MBBPLL4SZUB3JUUYQYLZW7S5OXRCEGJX3WWADOQXGHWQ7BIKCY5QC
I7QLYOTE6DLQZM7YWUWYLKHRJRB2A3STQ42ALSRGQICEWKD2QTEQC
7Y5HSDFKA5TPLS2TWTRFMQVX6UXUDHXU5MUMXQSDFAIY4THQ3BIQC
R6XS2HO5QX2FJUGL5UQQRNETKCMYWTUFPHPPS5SYWK3OQA4UDUQQC
}
// 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;
// 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);
}
|| (pow >= 60 && grid == DNGN_STONE_WALL && one_chance_in(10))))
|| (pow >= 40 && grid == DNGN_CLEAR_ROCK_WALL
&& one_chance_in(3))
|| (pow >= 60 && grid == DNGN_STONE_WALL && one_chance_in(10))
|| (pow >= 60 && grid == DNGN_CLEAR_STONE_WALL &&
one_chance_in(10)) ))
// find a space near our target...
if ( !random_near_space(ox, oy, tx, ty) )
// find a space near our target... First try to find a random
// square not adjacent to the player, then one adjacent if
// that fails.
if ( !random_near_space(ox, oy, tx, ty) &&
!random_near_space(ox, oy, tx, ty, true))
int blink(int pow, bool high_level_controlled_blink)
// If wizard_blink is set, all restriction are ignored (except for
// a monster being at the target spot), and the player gains no
// contamination.
int blink(int pow, bool high_level_controlled_blink, bool wizard_blink)
else if (!random_near_space(you.x_pos, you.y_pos, tx, ty))
// First try to find a random square not adjacent to the player,
// then one adjacent if that fails.
else if (!random_near_space(you.x_pos, you.y_pos, tx, ty)
&& !random_near_space(you.x_pos, you.y_pos, tx, ty, true))
int tries = 0;
// 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;
tries++;
// 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);
if (tries > 149)
break;
// 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));
//
// * Any: edit dungeon.cc and add a symbol to map_feature() and
// vault_grid() for the feature, if you want vault maps to
// be able to use it. If you do, also update
// docs/level-design.txt with the new symbol.
// * Any: edit luadgn.cc and add the feature's name to the dngn_feature_names
// array, if you want vault map Lua code to be able to use the
// feature, and/or you want to be able to create the feature
// using the "create feature by name" wizard command.
###########################################################################
# Small areas with translucent rock (glass) columns which you can duck
# behind, but still see the monster you're ducking from (and they can
# still see you
NAME: glass_columns_a
DEPTH:
MAP
.....
.m.m.
.....
.m.m.
.....
ENDMAP
NAME: glass_columns_b
DEPTH:
MAP
.......
.m.m.m.
.......
.m.m.m.
.......
.m.m.m.
.......
ENDMAP
NAME: glass_columns_c
DEPTH:
MAP
.........
.m.m.m.m.
.........
.m.m.m.m.
.........
.m.m.m.m.
.........
.m.m.m.m.
.........
ENDMAP
##########################################################
# A feature encased in glass, for flavour.
NAME: feat_on_display
DEPTH:
SUBST: ? = TUl
TAGS: no_monster_gen no_item_gen
MAP
.....
.mmm.
.m?m.
.mmm.
.....
ENDMAP
#######################################################################
# An item encased in glass. If the player wants it, it can be dug out.
NAME: item_on_display_a
DEPTH:
TAGS: no_monster_gen no_item_gen
MAP
.....
.mmm.
.m%m.
.mmm.
.....
ENDMAP
#####################################################################
# A good item encased in *permanet* glass. If the player wants it,
# teleport control will be needed.
NAME: item_on_display_b
DEPTH:
TAGS: no_monster_gen no_item_gen
MAP
.....
.ooo.
.o*o.
.ooo.
.....
ENDMAP
#####################################################################
# An average monster in a cage of glass; can get out if it has the
# ability to dig or blink like a blink-frog. Also, the player can
# dig it out.
NAME: caged_monster_a
DEPTH: D, Elf, Snake, Vault
MAP
.....
.mmm.
.m0m.
.mmm.
.....
ENDMAP
############################################################################
# Entry vaults using translucent (glass) walls
# A spiral made entirely of glass
NAME: glass_entry_001
TAGS: entry
ORIENT: float
SHUFFLE: {[(<
SUBST: < = .
MAP
mmmmmmmmmmmmmmmmmm
m................m
m.mmmmmmmmmmmmmm.m
m.m............m.m
m.m.mmmmmmmmmm.m.m
m.m.m........m.m.m
m.m.m.mmmmmm.m.m.m
m.m.m.m....m.m.m.m
m.m.m.m.mm.m.m.m.m
m.m.m.m{[m.m.m.m.m
m.m.m.m(<m.m.m.m.m
m.m.m.mmmm.m.m.m.m
m.m.m......m.m.m.m
m.m.mmmmmmmm.m.m.m
m.m..........m.m.m
m.mmmmmmmmmmmm.m.m
m..............m.m
mmmmmmmmmmmmmmmm@m
ENDMAP
# A spiral made of rock, with lots of "windows".
NAME: glass_entry_002
TAGS: entry
ORIENT: float
SHUFFLE: {[(<
SUBST: < = .
MAP
mxmxmxmxmxmxxmxxmx
x................m
m.xmxmxmxmxmxmxm.x
x.m............x.m
m.x.mxmxmxmxmx.m.x
x.m.x........m.x.m
m.x.m.xmxmxx.x.m.x
x.m.x.m....x.m.x.m
m.x.m.x.mx.m.x.m.x
x.m.x.m{[m.x.m.x.m
m.x.m.x(<x.m.x.m.x
x.m.x.xmxx.x.m.x.m
m.x.m......m.x.m.x
x.m.xxmxmxmx.m.x.m
m.x..........x.m.x
x.xmxmxmxmxmxm.x.m
m..............m.x
xxmxmxmxmxmxmxmx@m
ENDMAP
A harder obstacle than rock walls. Only the mightiest magic can shatter stone walls.
A harder obstacle than rock walls. Only the mightiest magic can shatter stone walls.
%%%%
A translucent rock wall
%%%%
A translucent stone wall
A harder obstacle than rock walls. Only the mightiest magic can shatter stone walls. It has been imbued with arcane magics which render it translucent.
if ((targ_grid == DNGN_ROCK_WALL || targ_grid == DNGN_WAX_WALL)
&& !(x <= 6 || y <= 6 || x >= (GXM - 6) || y >= (GYM - 6)))
if ((targ_grid == DNGN_ROCK_WALL || targ_grid == DNGN_WAX_WALL
|| targ_grid == DNGN_CLEAR_ROCK_WALL)
&& !(x <= 6 || y <= 6 || x >= (GXM - 6) || y >= (GYM - 6)))