fix #H7136 - iron bars vs non-diggable walls
Iron bars can be destroyed in some circumstances (hit by yellow dragon breath or thrown potion of acid, being eaten by rust monser or black pudding, or by poly'd hero in those forms) and should act like walls for diggable/non-diggable purposes. But they aren't walls, so the non-diggable flag was not being set for them by the special level loader. Even once that was changed, they weren't being handled consistently. Some places checked for non-diggable directly (zap_over_floor of acid breath, potion of acid hitting bars) and started working as intended, others used may_dig() to check non-diggable (poly'd hero attempting to eat iron bars) but it doesn't handle iron bars, and still others didn't check at all (bars-eating monster who moved onto bars location in expectation of eating those next).
This commit is contained in:
@@ -142,6 +142,8 @@ known bear trap was being forgotten about by a player polymorphed into a
|
||||
no leash-related message is given when a leashed pet yellow light explodes
|
||||
shop messages refer to shk by name even when shk is not visible but some
|
||||
used pronoun "it" or "its" in same sentence; ditto for vault guards
|
||||
poly'd hero and monsters could eat through iron bars in areas where walls
|
||||
were flagged as non-diggable
|
||||
|
||||
|
||||
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
|
||||
|
||||
@@ -381,7 +381,7 @@ extern struct symsetentry symset[NUM_GRAPHICS]; /* from drawing.c */
|
||||
#define DB_UNDER 28 /* mask for underneath */
|
||||
|
||||
/*
|
||||
* Wall information.
|
||||
* Wall information. Nondiggable also applies to iron bars.
|
||||
*/
|
||||
#define WM_MASK 0x07 /* wall mode (bottom three bits) */
|
||||
#define W_NONDIGGABLE 0x08
|
||||
|
||||
@@ -364,8 +364,8 @@ moverock()
|
||||
/*
|
||||
* still_chewing()
|
||||
*
|
||||
* Chew on a wall, door, or boulder. Returns TRUE if still eating, FALSE
|
||||
* when done.
|
||||
* Chew on a wall, door, or boulder. [What about statues?]
|
||||
* Returns TRUE if still eating, FALSE when done.
|
||||
*/
|
||||
STATIC_OVL int
|
||||
still_chewing(x, y)
|
||||
@@ -379,7 +379,10 @@ xchar x, y;
|
||||
(void) memset((genericptr_t) &context.digging, 0,
|
||||
sizeof (struct dig_info));
|
||||
|
||||
if (!boulder && IS_ROCK(lev->typ) && !may_dig(x, y)) {
|
||||
if (!boulder
|
||||
&& ((IS_ROCK(lev->typ) && !may_dig(x, y))
|
||||
/* may_dig() checks W_NONDIGGABLE but doesn't handle iron bars */
|
||||
|| (lev->typ == IRONBARS && (lev->wall_info & W_NONDIGGABLE)))) {
|
||||
You("hurt your teeth on the %s.",
|
||||
(lev->typ == IRONBARS)
|
||||
? "bars"
|
||||
|
||||
@@ -1320,7 +1320,11 @@ nexttry: /* eels prefer the water, but if there is no water nearby,
|
||||
&& !((IS_TREE(ntyp) ? treeok : rockok) && may_dig(nx, ny)))
|
||||
continue;
|
||||
/* KMH -- Added iron bars */
|
||||
if (ntyp == IRONBARS && !(flag & ALLOW_BARS))
|
||||
if (ntyp == IRONBARS
|
||||
&& (!(flag & ALLOW_BARS)
|
||||
|| ((levl[nx][ny].wall_info & W_NONDIGGABLE)
|
||||
&& (dmgtype(mdat, AD_RUST)
|
||||
|| dmgtype(mdat, AD_CORR)))))
|
||||
continue;
|
||||
if (IS_DOOR(ntyp) && !(amorphous(mdat) || can_fog(mon))
|
||||
&& (((levl[nx][ny].doormask & D_CLOSED) && !(flag & OPENDOOR))
|
||||
|
||||
@@ -1388,7 +1388,8 @@ postmov:
|
||||
add_damage(mtmp->mx, mtmp->my, 0L);
|
||||
}
|
||||
} else if (levl[mtmp->mx][mtmp->my].typ == IRONBARS) {
|
||||
if (may_dig(mtmp->mx, mtmp->my)
|
||||
/* 3.6.2: was using may_dig() but it doesn't handle bars */
|
||||
if (!(levl[mtmp->mx][mtmp->my].wall_info & W_NONDIGGABLE)
|
||||
&& (dmgtype(ptr, AD_RUST) || dmgtype(ptr, AD_CORR))) {
|
||||
if (canseemon(mtmp))
|
||||
pline("%s eats through the iron bars.", Monnam(mtmp));
|
||||
|
||||
19
src/sp_lev.c
19
src/sp_lev.c
@@ -621,6 +621,7 @@ schar filling;
|
||||
schar lit;
|
||||
{
|
||||
int x, y;
|
||||
|
||||
for (x = 2; x <= x_maze_max; x++)
|
||||
for (y = 0; y <= y_maze_max; y++) {
|
||||
SET_TYPLIT(x, y, filling, lit);
|
||||
@@ -636,11 +637,21 @@ xchar x1, y1, x2, y2;
|
||||
int prop;
|
||||
{
|
||||
register xchar x, y;
|
||||
struct rm *lev;
|
||||
|
||||
for (y = max(y1, 0); y <= min(y2, ROWNO - 1); y++)
|
||||
for (x = max(x1, 0); x <= min(x2, COLNO - 1); x++)
|
||||
if (IS_STWALL(levl[x][y].typ) || IS_TREE(levl[x][y].typ))
|
||||
levl[x][y].wall_info |= prop;
|
||||
x1 = max(x1, 1);
|
||||
x2 = min(x2, COLNO - 1);
|
||||
y1 = max(y1, 0);
|
||||
y2 = min(y2, ROWNO - 1);
|
||||
for (y = y1; y <= y2; y++)
|
||||
for (x = x1; x <= x2; x++) {
|
||||
lev = &levl[x][y];
|
||||
if (IS_STWALL(lev->typ) || IS_TREE(lev->typ)
|
||||
/* 3.6.2: made iron bars eligible to be flagged nondiggable
|
||||
(checked by chewing(hack.c) and zap_over_floor(zap.c)) */
|
||||
|| lev->typ == IRONBARS)
|
||||
lev->wall_info |= prop;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
|
||||
Reference in New Issue
Block a user