]> granicus.if.org Git - nethack/commitdiff
web spinning tweak for Sokoban
authorPatR <rankin@nethack.org>
Sun, 27 Jun 2021 00:06:37 +0000 (17:06 -0700)
committerPatR <rankin@nethack.org>
Sun, 27 Jun 2021 00:06:37 +0000 (17:06 -0700)
When spiders try to spin webs, don't let them do so in Sokoban
unless the level has already been solved or the spider can see the
stairs up (which was the simplest way I could achieve something
close to "is in the same room as the stairs up") where it can't
interfere with solving the level.

doc/fixes37.0
src/monmove.c

index 9d712daf4fa62a6b9322b35d5d8e3d6b96275219..c470dd77266aee6a8883e49147d6632934b790e3 100644 (file)
@@ -724,6 +724,7 @@ corpse of monster with gender specific names (king vs queen and so forth)
 prevent obj_pmname() from calling mon_pmname(monst) when monst->data is null
        to prevent a null pointer dereference
 correct the pluralization of monarch to monarchs, rather than monarches
+don't allow web spun by spider to interfere with solving Soloban
 
 curses: 'msg_window' option wasn't functional for curses unless the binary
        also included tty support
index 43c43689c5b9f7a236c9b9115ccf860360f9547e..a28a4288be6c3c47df63dafbf2ced7359ba83c6b 100644 (file)
@@ -14,6 +14,7 @@ static void distfleeck(struct monst *, int *, int *, int *);
 static int m_arrival(struct monst *);
 static boolean holds_up_web(xchar, xchar);
 static int count_webbing_walls(xchar, xchar);
+static boolean soko_allow_web(struct monst *);
 static boolean m_balks_at_approaching(struct monst *);
 static boolean stuff_prevents_passage(struct monst *);
 static int vamp_shift(struct monst *, struct permonst *, boolean);
@@ -866,10 +867,8 @@ holds_up_web(xchar x, xchar y)
 
     if (!isok(x, y)
         || IS_ROCK(levl[x][y].typ)
-        || ((levl[x][y].typ == STAIRS
-             || levl[x][y].typ == LADDER)
-            && (sway = stairway_at(x,y)) != 0
-            && sway->up)
+        || ((levl[x][y].typ == STAIRS || levl[x][y].typ == LADDER)
+            && (sway = stairway_at(x, y)) != 0 && sway->up)
         || levl[x][y].typ == IRONBARS)
         return TRUE;
 
@@ -885,16 +884,34 @@ count_webbing_walls(xchar x, xchar y)
             + holds_up_web(x, y + 1) + holds_up_web(x - 1, y));
 }
 
+/* reject webs which interfere with solving Sokoban */
+static boolean
+soko_allow_web(struct monst *mon)
+{
+    stairway *stway;
+
+    /* for a non-Sokoban level or a solved Sokoban level, no restriction */
+    if (!Sokoban)
+        return TRUE;
+    /* not-yet-solved Sokoban level:  allow web only when spinner can see
+       the stairs up [we really want 'is in same chamber as stairs up'] */
+    stway = stairway_find_dir(TRUE); /* stairs up */
+    if (stway && m_cansee(mon, stway->sx, stway->sy))
+        return TRUE;
+    return FALSE;
+}
+
 /* monster might spin a web */
 static void
 maybe_spin_web(struct monst *mtmp)
 {
-    if (webmaker(mtmp->data) && !mtmp->mspec_used
-        && !t_at(mtmp->mx, mtmp->my)) {
+    if (webmaker(mtmp->data)
+        && mtmp->mcanmove && !mtmp->msleeping && !mtmp->mspec_used
+        && !t_at(mtmp->mx, mtmp->my) && soko_allow_web(mtmp)) {
         struct trap *trap;
-        int prob = (((mtmp->data == &mons[PM_GIANT_SPIDER]) ? 15 : 5)
-            * (count_webbing_walls(mtmp->mx, mtmp->my) + 1))
-            - (3 * count_traps(WEB));
+        int prob = ((((mtmp->data == &mons[PM_GIANT_SPIDER]) ? 15 : 5)
+                     * (count_webbing_walls(mtmp->mx, mtmp->my) + 1))
+                    - (3 * count_traps(WEB)));
 
         if (rn2(1000) < prob
             && (trap = maketrap(mtmp->mx, mtmp->my, WEB)) != 0) {
@@ -902,8 +919,7 @@ maybe_spin_web(struct monst *mtmp)
             if (cansee(mtmp->mx, mtmp->my)) {
                 char mbuf[BUFSZ];
 
-                Strcpy(mbuf,
-                       canspotmon(mtmp) ? y_monnam(mtmp) : something);
+                Strcpy(mbuf, canspotmon(mtmp) ? y_monnam(mtmp) : something);
                 pline("%s spins a web.", upstart(mbuf));
                 trap->tseen = 1;
             }