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);
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;
+ 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) {
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;
}