]> granicus.if.org Git - nethack/commitdiff
Allow spiders to spin webs
authorPasi Kallinen <paxed@alt.org>
Wed, 23 Jun 2021 19:42:29 +0000 (22:42 +0300)
committerPasi Kallinen <paxed@alt.org>
Wed, 23 Jun 2021 19:50:57 +0000 (22:50 +0300)
Revisited this feature, and the chance of a spider spinning a web
depends now on the number of webs already present on the level.

For a giant spider to spin a web in the middle of a room with no
supports, the limit of existing webs is 4, next to one support 9,
next to two supports 14, and so on. Cave spider limits are much lower.

doc/fixes37.0
include/extern.h
src/monmove.c
src/trap.c

index 233ef8426f6a75d3daedf46b468b22a4e1b1b795..c00799c406656a4c72b2e235562b33be58ae912c 100644 (file)
@@ -1049,6 +1049,7 @@ monsters can see and remember hero resistances
 monsters can gain resistances by eating corpses
 menu for what-is command supports /^ and /" to view a list of nearby or whole
        level visible and remembered traps
+spiders will occasionally spin webs when moving around
 
 
 Platform- and/or Interface-Specific New Features
index 4c9e3138f4d25d419bc181b4e388c210dc700578..43ba4d2a13b35061422e53101110166f5f8aee1a 100644 (file)
@@ -2641,6 +2641,7 @@ extern boolean chest_trap(struct obj *, int, boolean);
 extern void deltrap(struct trap *);
 extern boolean delfloortrap(struct trap *);
 extern struct trap *t_at(int, int);
+extern int count_traps(int);
 extern void b_trapped(const char *, int);
 extern boolean unconscious(void);
 extern void blow_up_landmine(struct trap *);
index 7c9069820ba2cb35a0f0b2b74ca3b576b0764b5f..f7cf941ad9b4f84bc117c666eacc00fbe3e94935 100644 (file)
@@ -12,6 +12,8 @@ static int disturb(struct monst *);
 static void release_hero(struct monst *);
 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 m_balks_at_approaching(struct monst *);
 static boolean stuff_prevents_passage(struct monst *);
 static int vamp_shift(struct monst *, struct permonst *, boolean);
@@ -857,6 +859,58 @@ m_balks_at_approaching(struct monst* mtmp)
     return FALSE;
 }
 
+static boolean
+holds_up_web(xchar x, xchar y)
+{
+    stairway *sway;
+
+    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 == IRONBARS)
+        return TRUE;
+
+    return FALSE;
+}
+
+/* returns the number of walls in the four cardinal directions that could
+   hold up a web */
+static int
+count_webbing_walls(xchar x, xchar y)
+{
+    return (holds_up_web(x, y - 1) + holds_up_web(x + 1, y)
+            + holds_up_web(x, y + 1) + holds_up_web(x - 1, y));
+}
+
+/* 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)) {
+        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));
+
+        if (rn2(1000) < prob
+            && (trap = maketrap(mtmp->mx, mtmp->my, WEB)) != 0) {
+            mtmp->mspec_used = d(4, 4); /* 4..16 */
+            if (cansee(mtmp->mx, mtmp->my)) {
+                char mbuf[BUFSZ];
+
+                Strcpy(mbuf,
+                       canspotmon(mtmp) ? y_monnam(mtmp) : something);
+                pline("%s spins a web.", upstart(mbuf));
+                trap->tseen = 1;
+            }
+        }
+    }
+}
+
 /* Return values:
  * 0: did not move, but can still attack and do other stuff.
  * 1: moved, possibly can attack.
@@ -1553,6 +1607,8 @@ m_move(register struct monst* mtmp, register int after)
             }
         }
 
+        maybe_spin_web(mtmp);
+
         if (hides_under(ptr) || ptr->mlet == S_EEL) {
             /* Always set--or reset--mundetected if it's already hidden
                (just in case the object it was hiding under went away);
index c4e56225df4584d26d2cb35c6859bd497a9c4cd9..236092d2d6d4655af4c5c66508eedddf11571072 100644 (file)
@@ -5399,6 +5399,22 @@ t_at(register int x, register int y)
     return (struct trap *) 0;
 }
 
+/* return number of traps of type ttyp on this level */
+int
+count_traps(int ttyp)
+{
+    int ret = 0;
+    struct trap *trap = g.ftrap;
+
+    while (trap) {
+        if (trap->ttyp == ttyp)
+            ret++;
+        trap = trap->ntrap;
+    }
+
+    return ret;
+}
+
 void
 deltrap(register struct trap* trap)
 {