OSDN Git Service

update year to 2020
[jnethack/source.git] / src / worm.c
index f39a0a7..4a4f2a1 100644 (file)
@@ -1,11 +1,11 @@
-/* NetHack 3.6 worm.c  $NHDT-Date: 1456528599 2016/02/26 23:16:39 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.20 $ */
+/* NetHack 3.6 worm.c  $NHDT-Date: 1561340880 2019/06/24 01:48:00 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.30 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2009. */
 /* NetHack may be freely redistributed.  See license for details. */
 
 /* JNetHack Copyright */
 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
-/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016            */
+/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2020            */
 /* JNetHack may be freely redistributed.  See license for details. */
 
 #include "hack.h"
@@ -306,7 +306,8 @@ register struct monst *worm;
      */
     for (seg = wtails[wnum]; seg; seg = seg->nseg)
         if (distu(seg->wx, seg->wy) < 3)
-            (void) mattacku(worm);
+            if (mattacku(worm))
+                return; /* your passive ability killed the worm */
 }
 
 /*  cutworm()
@@ -318,10 +319,10 @@ register struct monst *worm;
  *  that both halves will survive.
  */
 void
-cutworm(worm, x, y, weap)
+cutworm(worm, x, y, cuttier)
 struct monst *worm;
 xchar x, y;
-struct obj *weap;
+boolean cuttier; /* hit is by wielded blade or axe or by thrown axe */
 {
     register struct wseg *curr, *new_tail;
     register struct monst *new_worm;
@@ -334,12 +335,10 @@ struct obj *weap;
     if (x == worm->mx && y == worm->my)
         return; /* hit on head */
 
-    /* cutting goes best with a bladed weapon */
-    cut_chance = rnd(20); /* Normally  1-16 does not cut */
-    /* Normally 17-20 does */
-
-    if (weap && is_blade(weap)) /* With a blade 1- 6 does not cut */
-        cut_chance += 10;       /*              7-20 does         */
+    /* cutting goes best with a cuttier weapon */
+    cut_chance = rnd(20); /* Normally     1-16 does not cut, 17-20 does, */
+    if (cuttier)
+        cut_chance += 10; /* with a blade 1- 6 does not cut,  7-20 does. */
 
     if (cut_chance < 17)
         return; /* not good enough */
@@ -387,9 +386,10 @@ struct obj *weap;
 
     /* Sometimes the tail end dies. */
     if (!new_worm) {
+        place_worm_seg(worm, x, y); /* place the "head" segment back */
         if (context.mon_moving) {
             if (canspotmon(worm))
-#if 0 /*JP*/
+#if 0 /*JP:T*/
                 pline("Part of %s tail has been cut off.",
                       s_suffix(mon_nam(worm)));
 #else
@@ -427,7 +427,7 @@ struct obj *weap;
     wgrowtime[new_wnum] = 0L;    /* trying to call initworm().       */
 
     /* Place the new monster at all the segment locations. */
-    place_wsegs(new_worm);
+    place_wsegs(new_worm, worm);
 
     if (context.mon_moving)
 /*JP
@@ -476,13 +476,14 @@ boolean use_detection_glyph;
     struct wseg *curr = wtails[worm->wormno];
 
     /*  if (!mtmp->wormno) return;  bullet proofing */
+    int what_tail = what_mon(PM_LONG_WORM_TAIL, newsym_rn2);
 
     while (curr != wheads[worm->wormno]) {
         num = use_detection_glyph
-            ? detected_monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL))
+            ? detected_monnum_to_glyph(what_tail)
             : (worm->mtame
-               ? petnum_to_glyph(what_mon(PM_LONG_WORM_TAIL))
-               : monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL)));
+               ? petnum_to_glyph(what_tail)
+               : monnum_to_glyph(what_tail));
         show_glyph(curr->wx, curr->wy, num);
         curr = curr->nseg;
     }
@@ -574,17 +575,28 @@ int fd;
  *  place_wsegs()
  *
  *  Place the segments of the given worm.  Called from restore.c
+ *  If oldworm is not NULL, assumes the oldworm segments are on map
+ *  in the same location as worm segments
  */
 void
-place_wsegs(worm)
-struct monst *worm;
+place_wsegs(worm, oldworm)
+struct monst *worm, *oldworm;
 {
     struct wseg *curr = wtails[worm->wormno];
 
     /*  if (!mtmp->wormno) return;  bullet proofing */
 
     while (curr != wheads[worm->wormno]) {
-        place_worm_seg(worm, curr->wx, curr->wy);
+        xchar x = curr->wx;
+        xchar y = curr->wy;
+
+        if (oldworm) {
+            if (m_at(x,y) == oldworm)
+                remove_monster(x, y);
+            else
+                impossible("placing worm seg <%i,%i> over another mon", x, y);
+        }
+        place_worm_seg(worm, x, y);
         curr = curr->nseg;
     }
 }
@@ -603,10 +615,12 @@ struct monst *worm;
     curr = wtails[worm->wormno];
 
     while (curr != wheads[worm->wormno]) {
-        if (!isok(curr->wx, curr->wy))
-            panic("worm seg not isok");
-        if (level.monsters[curr->wx][curr->wy] != worm)
-            panic("worm not at seg location");
+        if (curr->wx) {
+            if (!isok(curr->wx, curr->wy))
+                panic("worm seg not isok");
+            if (level.monsters[curr->wx][curr->wy] != worm)
+                panic("worm not at seg location");
+        }
         curr = curr->nseg;
     }
 }
@@ -628,8 +642,11 @@ register struct monst *worm;
     /*  if (!mtmp->wormno) return;  bullet proofing */
 
     while (curr) {
-        remove_monster(curr->wx, curr->wy);
-        newsym(curr->wx, curr->wy);
+        if (curr->wx) {
+            remove_monster(curr->wx, curr->wy);
+            newsym(curr->wx, curr->wy);
+            curr->wx = 0;
+        }
         curr = curr->nseg;
     }
 }
@@ -671,7 +688,6 @@ xchar x, y;
         char tryct = 0;
 
         /* pick a random direction from x, y and search for goodpos() */
-
         do {
             random_dir(ox, oy, &nx, &ny);
         } while (!goodpos(nx, ny, worm, 0) && (tryct++ < 50));
@@ -702,21 +718,26 @@ xchar x, y;
 STATIC_OVL
 void
 random_dir(x, y, nx, ny)
-register xchar x, y;
-register xchar *nx, *ny;
+xchar x, y;
+xchar *nx, *ny;
 {
-    *nx = x;
-    *ny = y;
-
-    *nx += (x > 1                     /* extreme left ? */
-              ? (x < COLNO            /* extreme right ? */
-                   ? (rn2(3) - 1)     /* neither so +1, 0, or -1 */
-                   : -rn2(2))         /* 0, or -1 */
-              : rn2(2));              /* 0, or 1 */
-
-    *ny += (*nx == x                  /* same kind of thing with y */
-              ? (y > 1 ? (y < ROWNO ? (rn2(2) ? 1 : -1) : -1) : 1)
-              : (y > 1 ? (y < ROWNO ? (rn2(3) - 1) : -rn2(2)) : rn2(2)));
+    *nx = x + (x > 1                /* extreme left ? */
+               ? (x < COLNO - 1     /* extreme right ? */
+                  ? (rn2(3) - 1)    /* neither so +1, 0, or -1 */
+                  : -rn2(2))        /* right edge, use -1 or 0 */
+               : rn2(2));           /* left edge, use 0 or 1 */
+    if (*nx != x) /* if x has changed, do same thing with y */
+        *ny = y + (y > 0             /* y==0 is ok (x==0 is not) */
+                   ? (y < ROWNO - 1
+                      ? (rn2(3) - 1)
+                      : -rn2(2))
+                   : rn2(2));
+    else /* when x has remained the same, force y to change */
+        *ny = y + (y > 0
+                   ? (y < ROWNO - 1
+                      ? (rn2(2) ? 1 : -1)   /* not at edge, so +1 or -1 */
+                      : -1)                 /* bottom, use -1 */
+                   : 1);                    /* top, use +1 */
 }
 
 /* for size_monst(cmd.c) to support #stats */