]> granicus.if.org Git - nethack/commitdiff
prayer vs blocked by boulder
authorPatR <rankin@nethack.org>
Mon, 12 Nov 2018 00:04:45 +0000 (16:04 -0800)
committerPatR <rankin@nethack.org>
Mon, 12 Nov 2018 00:04:45 +0000 (16:04 -0800)
Salvaged from an old, unfinished patch.  When checking whether the
hero is trapped by walls and solid rock, adjacent boulders are
evaluated on whether they can be pushed out of the way.  Extend that
evaluation:  (1) two boulders on a spot are pushable if there is a
pool beyond that spot, and (2) boulders can't be pushed diagonally
in Sokoban.

src/pray.c

index 7ad09455a81f038a56d216156c45877aaa045fdd..5569c33f0bb02588f02eabf2b8db309ab6990bf7 100644 (file)
@@ -2181,6 +2181,7 @@ blocked_boulder(dx, dy)
 int dx, dy;
 {
     register struct obj *otmp;
+    int nx, ny;
     long count = 0L;
 
     for (otmp = level.objects[u.ux + dx][u.uy + dy]; otmp;
@@ -2189,6 +2190,7 @@ int dx, dy;
             count += otmp->quan;
     }
 
+    nx = u.ux + 2 * dx, ny = u.uy + 2 * dy; /* next spot beyond boulder(s) */
     switch (count) {
     case 0:
         /* no boulders--not blocked */
@@ -2196,17 +2198,24 @@ int dx, dy;
     case 1:
         /* possibly blocked depending on if it's pushable */
         break;
+    case 2:
+        /* this is only approximate since multiple boulders might sink */
+        if (is_pool_or_lava(nx, ny)) /* does its own isok() check */
+            break; /* still need Sokoban check below */
+        /*FALLTHRU*/
     default:
         /* more than one boulder--blocked after they push the top one;
            don't force them to push it first to find out */
         return TRUE;
     }
 
-    if (!isok(u.ux + 2 * dx, u.uy + 2 * dy))
+    if (dx && dy && Sokoban) /* can't push boulder diagonally in Sokoban */
+        return TRUE;
+    if (!isok(nx, ny))
         return TRUE;
-    if (IS_ROCK(levl[u.ux + 2 * dx][u.uy + 2 * dy].typ))
+    if (IS_ROCK(levl[nx][ny].typ))
         return TRUE;
-    if (sobj_at(BOULDER, u.ux + 2 * dx, u.uy + 2 * dy))
+    if (sobj_at(BOULDER, nx, ny))
         return TRUE;
 
     return FALSE;