diagonal blockage exceptions

From a bug report, amorphous creatures can fit underneath
closed doors but could still be considered too big to fit through diagonal
gaps.  Let them and several other shapeless or flexibly shaped critters
squeeze through provided that they pass the not-carrying-too-much check.
This commit is contained in:
nethack.rankin
2005-12-23 04:35:24 +00:00
parent a43a3ac988
commit b4cc1427d9
4 changed files with 43 additions and 16 deletions

View File

@@ -171,6 +171,8 @@ prevent "object lost" panic caused by accessing freed memory after worn
non-fireproof water walking boots are destroyed by lava
stop multi-turn running, searching, or resting early if levitation ends
Call command could be used to remotely identify which high priest is which
large amorphous, whirly, noncorporeal, or slithy creatures can fit through
tight diagonal gaps despite their size
Platform- and/or Interface-Specific Fixes

View File

@@ -724,6 +724,7 @@ E void FDECL(movobj, (struct obj *,XCHAR_P,XCHAR_P));
E boolean FDECL(may_dig, (XCHAR_P,XCHAR_P));
E boolean FDECL(may_passwall, (XCHAR_P,XCHAR_P));
E boolean FDECL(bad_rock, (struct permonst *,XCHAR_P,XCHAR_P));
E int FDECL(cant_squeeze_thru, (struct monst *));
E boolean FDECL(invocation_pos, (XCHAR_P,XCHAR_P));
E boolean FDECL(test_move, (int, int, int, int, int));
E void NDECL(domove);

View File

@@ -526,6 +526,33 @@ register xchar x,y;
&& !(passes_walls(mdat) && may_passwall(x,y)))));
}
/* caller has already decided that it's a tight diagonal; check whether a
monster--who might be the hero--can fit through, and if not then return
the reason why: 1: can't fit, 2: possessions won't fit, 3: sokoban */
int /* returns 0 if we can squeeze through */
cant_squeeze_thru(mon)
struct monst *mon;
{
int amt;
struct permonst *ptr = mon->data;
/* too big? */
if (bigmonst(ptr) &&
!(amorphous(ptr) || is_whirly(ptr) ||
noncorporeal(ptr) || slithy(ptr) || can_fog(mon))) return 1;
/* lugging too much junk? */
amt = (mon == &youmonst) ? inv_weight() + weight_cap() :
curr_mon_load(mon);
if (amt > 600) return 2;
/* Sokoban restriction applies to hero only */
if (mon == &youmonst && In_sokoban(&u.uz)) return 3;
/* can squeeze through */
return 0;
}
boolean
invocation_pos(x, y)
xchar x, y;
@@ -623,20 +650,18 @@ int mode;
if (dx && dy
&& bad_rock(youmonst.data,ux,y) && bad_rock(youmonst.data,x,uy)) {
/* Move at a diagonal. */
if (In_sokoban(&u.uz)) {
if (mode == DO_MOVE)
You("cannot pass that way.");
switch (cant_squeeze_thru(&youmonst)) {
case 3:
if (mode == DO_MOVE) You("cannot pass that way.");
return FALSE;
}
if (bigmonst(youmonst.data)) {
if (mode == DO_MOVE)
Your("body is too large to fit through.");
case 2:
if (mode == DO_MOVE) You("are carrying too much to get through.");
return FALSE;
}
if (invent && (inv_weight() + weight_cap() > 600)) {
if (mode == DO_MOVE)
You("are carrying too much to get through.");
case 1:
if (mode == DO_MOVE) Your("body is too large to fit through.");
return FALSE;
default:
break; /* can squeeze through */
}
}
/* Pick travel path that does not require crossing a trap.

View File

@@ -1051,8 +1051,7 @@ 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)) continue;
if(IS_DOOR(ntyp) &&
!(amorphous(mdat) || (!amorphous(mdat) && can_fog(mon))) &&
if(IS_DOOR(ntyp) && !(amorphous(mdat) || can_fog(mon)) &&
((levl[nx][ny].doormask & D_CLOSED && !(flag & OPENDOOR)) ||
(levl[nx][ny].doormask & D_LOCKED && !(flag & UNLOCKDOOR))) &&
!thrudoor) continue;
@@ -1151,9 +1150,9 @@ nexttry: /* eels prefer the water, but if there is no water nearby,
if(flag & NOTONL) continue;
info[cnt] |= NOTONL;
}
if (nx != x && ny != y && bad_rock(mdat, x, ny)
&& bad_rock(mdat, nx, y)
&& (bigmonst(mdat) || (curr_mon_load(mon) > 600)))
/* check for diagonal tight squeeze */
if (nx != x && ny != y && bad_rock(mdat, x, ny) &&
bad_rock(mdat, nx, y) && cant_squeeze_thru(mon))
continue;
/* The monster avoids a particular type of trap if it's familiar
* with the trap type. Pets get ALLOW_TRAPS and checking is