From: nethack.rankin Date: Fri, 23 Dec 2005 04:35:24 +0000 (+0000) Subject: diagonal blockage exceptions X-Git-Tag: MOVE2GIT~1176 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b4cc1427d9cf0ffcdf69729ca401af637a345299;p=nethack 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. --- 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