fix mdig_tunnel impossibility

Reported by the keymasher:  "stone at (48,8) is undiggable".  Bigroom 4
has a tree at that spot and the whole level is flagged as undiggable.
Undiggable trees were supported on arboreal levels (where their terrain
type is STONE rather than TREE), but not elsewhere.  Monster movement
uses IS_ROCK(), which is true for TREEs, but may_dig() uses IS_STWALL(),
which is false for TREEs so doesn't consider the location as being of
interest and fails to disallow digging.  But mdig_tunnel() bypasses
may_dig() and tests the NONDIGGABLE bit directly, disallowing digging.
(If this sounds confusing, it's a stroll in the park compared to the
code itself.  Apologies for the mixed metaphore.)

Digging away a secret corridor could leave rocks, which doesn't make
a whole lot of sense.  Now a monster's dig attempt will reveal the
location as a corridor instead.

This also moves an assignment out of a macro invocation where it was
inviting trouble if that macro gets modified.  And reorganizes an 'if'
to put cheaper tests sooner.
This commit is contained in:
PatR
2015-05-13 17:54:26 -07:00
parent beaab1b974
commit dd62a6831f
4 changed files with 26 additions and 15 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 dig.c $NHDT-Date: 1431192766 2015/05/09 17:32:46 $ $NHDT-Branch: master $:$NHDT-Revision: 1.90 $ */
/* NetHack 3.6 dig.c $NHDT-Date: 1431563241 2015/05/14 00:27:21 $ $NHDT-Branch: master $:$NHDT-Revision: 1.91 $ */
/* NetHack 3.6 dig.c $Date: 2012/02/16 03:01:37 $ $Revision: 1.67 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1272,14 +1272,21 @@ register struct monst *mtmp;
}
newsym(mtmp->mx, mtmp->my);
return FALSE;
} else if (here->typ == SCORR) {
here->typ = CORR;
unblock_point(mtmp->mx, mtmp->my);
newsym(mtmp->mx, mtmp->my);
You_feel("a draft.");
return FALSE;
} else if (!IS_ROCK(here->typ) && !IS_TREE(here->typ)) /* no dig */
return FALSE;
/* Only rock, trees, and walls fall through to this point. */
if ((here->wall_info & W_NONDIGGABLE) != 0) {
impossible("mdig_tunnel: %s at (%d,%d) is undiggable",
(IS_WALL(here->typ) ? "wall" : "stone"), (int) mtmp->mx,
(int) mtmp->my);
(IS_WALL(here->typ) ? "wall"
: IS_TREE(here->typ) ? "tree" : "stone"),
(int) mtmp->mx, (int) mtmp->my);
return FALSE; /* still alive */
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 hack.c $NHDT-Date: 1431192758 2015/05/09 17:32:38 $ $NHDT-Branch: master $:$NHDT-Revision: 1.148 $ */
/* NetHack 3.6 hack.c $NHDT-Date: 1431563243 2015/05/14 00:27:23 $ $NHDT-Branch: master $:$NHDT-Revision: 1.149 $ */
/* NetHack 3.6 hack.c $Date: 2013/10/26 21:33:47 $ $Revision: 1.120 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -580,13 +580,15 @@ dosinkfall()
float_vs_flight();
}
/* intended to be called only on ROCKs or TREEs */
boolean
may_dig(x, y)
register xchar x, y;
/* intended to be called only on ROCKs */
{
return (boolean)(!(IS_STWALL(levl[x][y].typ)
&& (levl[x][y].wall_info & W_NONDIGGABLE)));
struct rm *lev = &levl[x][y];
return (boolean)(!((IS_STWALL(lev->typ) || IS_TREE(lev->typ))
&& (lev->wall_info & W_NONDIGGABLE)));
}
boolean

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mon.c $NHDT-Date: 1431192769 2015/05/09 17:32:49 $ $NHDT-Branch: master $:$NHDT-Revision: 1.174 $ */
/* NetHack 3.6 mon.c $NHDT-Date: 1431563243 2015/05/14 00:27:23 $ $NHDT-Branch: master $:$NHDT-Revision: 1.175 $ */
/* NetHack 3.6 mon.c $Date: 2012/05/16 02:15:10 $ $Revision: 1.126 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1114,11 +1114,12 @@ long flag;
treeok = (m_carrying(mon, AXE) || (m_carrying(mon, BATTLE_AXE)
&& !which_armor(mon, W_ARMS)));
}
thrudoor |= rockok || treeok;
if (rockok || treeok)
thrudoor = TRUE;
}
nexttry: /* eels prefer the water, but if there is no water nearby,
they will crawl over land */
they will crawl over land */
if (mon->mconf) {
flag |= ALLOW_ALL;
flag &= ~NOTONL;
@@ -1131,7 +1132,8 @@ nexttry: /* eels prefer the water, but if there is no water nearby,
for (ny = max(0, y - 1); ny <= maxy; ny++) {
if (nx == x && ny == y)
continue;
if (IS_ROCK(ntyp = levl[nx][ny].typ)
ntyp = levl[nx][ny].typ;
if (IS_ROCK(ntyp)
&& !((flag & ALLOW_WALL) && may_passwall(nx, ny))
&& !((IS_TREE(ntyp) ? treeok : rockok) && may_dig(nx, ny)))
continue;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 monmove.c $NHDT-Date: 1431195533 2015/05/09 18:18:53 $ $NHDT-Branch: master $:$NHDT-Revision: 1.69 $ */
/* NetHack 3.6 monmove.c $NHDT-Date: 1431563244 2015/05/14 00:27:24 $ $NHDT-Branch: master $:$NHDT-Revision: 1.70 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1100,9 +1100,9 @@ not_special:
if (mmoved == 1 && (u.ux != nix || u.uy != niy) && itsstuck(mtmp))
return (3);
if (((IS_ROCK(levl[nix][niy].typ) && may_dig(nix, niy))
|| closed_door(nix, niy)) && mmoved == 1
&& can_tunnel && needspick(ptr)) {
if (mmoved == 1 && can_tunnel && needspick(ptr)
&& ((IS_ROCK(levl[nix][niy].typ) && may_dig(nix, niy))
|| closed_door(nix, niy))) {
if (closed_door(nix, niy)) {
if (!(mw_tmp = MON_WEP(mtmp)) || !is_pick(mw_tmp)
|| !is_axe(mw_tmp))