diff --git a/doc/fixes34.4 b/doc/fixes34.4 index 69031f814..533169d52 100644 --- a/doc/fixes34.4 +++ b/doc/fixes34.4 @@ -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 diff --git a/include/extern.h b/include/extern.h index 0ba835021..2ec40316e 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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); diff --git a/src/hack.c b/src/hack.c index 1486590c1..33a66cf35 100644 --- a/src/hack.c +++ b/src/hack.c @@ -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. diff --git a/src/mon.c b/src/mon.c index 635ca9078..b064c34ae 100644 --- 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