fix #H2642 - escaping from drowning by moving diagonally

From a bug report, you could crawl
out of water to avoid drowning by moving diagonally into an intact doorway
even though regular movement won't allow that.  (Second version of Medusa's
level has a door adjacent to water.)  You could also escape diagonally when
polymorphed into a grid bug.
This commit is contained in:
nethack.rankin
2012-04-30 21:25:05 +00:00
parent 2dc1a2e21e
commit ebf42e6746
4 changed files with 28 additions and 4 deletions

View File

@@ -832,6 +832,7 @@ adjust turning-to-stone or -slime messages when you have no limbs
wizard mode ^F on Plane of Water marked portal as seen but didn't display it
magic mapping now displays furniture in preference to known or remembered traps
or objects and known traps in preference to remembered objects
restrictions on diagonal movement were ignored when crawling out of water
Platform- and/or Interface-Specific Fixes

View File

@@ -810,6 +810,7 @@ E boolean FDECL(in_town, (int,int));
E void FDECL(check_special_room, (BOOLEAN_P));
E int NDECL(dopickup);
E void NDECL(lookaround);
E boolean FDECL(crawl_destination, (int,int));
E int NDECL(monster_nearby);
E void FDECL(nomul, (int));
E void FDECL(unmul, (const char *));

View File

@@ -2390,6 +2390,28 @@ int x, y;
return !(lev_p->doormask & ~(D_NODOOR|D_BROKEN));
}
/* used by drown() to check whether hero can crawl from water to <x,y> */
boolean
crawl_destination(x, y)
int x, y;
{
/* is location ok in general? */
if (!goodpos(x, y, &youmonst, 0)) return FALSE;
/* orthogonal movement is unrestricted when destination is ok */
if (x == u.ux || y == u.uy) return TRUE;
/* diagonal movement has some restrictions */
if (NODIAG(u.umonnum)) return FALSE; /* poly'd into a grid bug... */
if (Passes_walls) return TRUE; /* or a xorn... */
/* pool could be next to a door, conceivably even inside a shop */
if (IS_DOOR(levl[x][y].typ) && (!doorless_door(x, y) || block_door(x, y)))
return FALSE;
/* finally, are we trying to squeeze through a too-narrow gap? */
return !(bad_rock(youmonst.data, u.ux, y) &&
bad_rock(youmonst.data, x, u.uy));
}
/* something like lookaround, but we are not running */
/* react only to monsters that might hit us */
int

View File

@@ -8,8 +8,8 @@ extern const char * const destroy_strings[][3]; /* from zap.c */
STATIC_DCL void FDECL(dofiretrap, (struct obj *));
STATIC_DCL void NDECL(domagictrap);
STATIC_DCL boolean FDECL(emergency_disrobe,(boolean *));
STATIC_DCL int FDECL(untrap_prob, (struct trap *ttmp));
STATIC_DCL boolean FDECL(emergency_disrobe, (boolean *));
STATIC_DCL int FDECL(untrap_prob, (struct trap *));
STATIC_DCL void FDECL(move_into_trap, (struct trap *));
STATIC_DCL int FDECL(try_disarm, (struct trap *,BOOLEAN_P));
STATIC_DCL void FDECL(reward_untrap, (struct trap *, struct monst *));
@@ -3376,7 +3376,7 @@ drown()
for (i = 0; i < 100; i++) {
x = rn1(3,u.ux - 1);
y = rn1(3,u.uy - 1);
if (goodpos(x, y, &youmonst, 0)) {
if (crawl_destination(x, y)) {
crawl_ok = TRUE;
goto crawl;
}
@@ -3384,7 +3384,7 @@ drown()
/* one more scan */
for (x = u.ux - 1; x <= u.ux + 1; x++)
for (y = u.uy - 1; y <= u.uy + 1; y++)
if (goodpos(x, y, &youmonst, 0)) {
if (crawl_destination(x, y)) {
crawl_ok = TRUE;
goto crawl;
}