]> granicus.if.org Git - nethack/commitdiff
diagonal blockage exceptions
authornethack.rankin <nethack.rankin>
Fri, 23 Dec 2005 04:35:24 +0000 (04:35 +0000)
committernethack.rankin <nethack.rankin>
Fri, 23 Dec 2005 04:35:24 +0000 (04:35 +0000)
     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.

doc/fixes34.4
include/extern.h
src/hack.c
src/mon.c

index 69031f814b379edbac4970b14d0ed0050df9f49a..533169d52e31e5a6622059482d58698d132fa07e 100644 (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
index 0ba8350216db90fab0632b0cf3875f0ec45a0ba3..2ec40316e649411d7bd35d94416f39deca5d9952 100644 (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);
index 1486590c183c4a5f1e3b4870fbdcade6456e5621..33a66cf350c32b64074949bb32a5e6edf9fa4736 100644 (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.
index 635ca90783cae6dc5da9bb76d18568a60d86139a..b064c34ae3043ae7695ea8dc4a9429de609c67f6 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -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