]> granicus.if.org Git - nethack/commitdiff
fix github issue #285 - spellcasting monster
authorPatR <rankin@nethack.org>
Sun, 2 Feb 2020 08:55:26 +0000 (00:55 -0800)
committerPatR <rankin@nethack.org>
Sun, 2 Feb 2020 08:55:26 +0000 (00:55 -0800)
After casting a spell, a monster got a chance to make a regular attack
despite the apparent attempt to set up a return value indicating that
it wouldn't move.

When looking over the return value situation, I noticed 'wormhitu()'
for the first time.  It gives worms additional attacks when the hero
is adjacent to some of the tail, that only works if the head is within
reach of a melee attack.  The hidden tail segment at head's location
always met that criterium so gave an extra attack that didn't make
sense; change wormhitu() to skip that segment.

Do some formatting in mcastu.c; no change in actual code there.

Fixes #285

doc/fixes37.0
include/extern.h
src/mcastu.c
src/monmove.c
src/worm.c

index 686cd7b84e382a950d27f863b2a6954e3499542b..58e243ac98be37a3012143f94280bf16e903513c 100644 (file)
@@ -1,4 +1,4 @@
-$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.85 $ $NHDT-Date: 1580608377 2020/02/02 01:52:57 $
+$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.87 $ $NHDT-Date: 1580633720 2020/02/02 08:55:20 $
 
 General Fixes and Modified Features
 -----------------------------------
@@ -50,6 +50,7 @@ revamp achievement tracking for exploring Mine's End and Sokoban (by acquiring
 throttle long worm growth rate and HP accumulation
 poly'd hero was able to zap wands, apply tools, and #rub objects without
        having any hands
+spellcasting monster got an extra move after casting
 
 
 Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
index ef9f648389b289a93553d4dcc34d105458859aac..b43df085eb3b8ad4816a72a35997935ee97ebdc2 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 extern.h        $NHDT-Date: 1580044333 2020/01/26 13:12:13 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.786 $ */
+/* NetHack 3.6 extern.h        $NHDT-Date: 1580633720 2020/02/02 08:55:20 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.787 $ */
 /* Copyright (c) Steve Creps, 1988.                              */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -3014,7 +3014,7 @@ E void FDECL(initworm, (struct monst *, int));
 E void FDECL(worm_move, (struct monst *));
 E void FDECL(worm_nomove, (struct monst *));
 E void FDECL(wormgone, (struct monst *));
-E void FDECL(wormhitu, (struct monst *));
+E int FDECL(wormhitu, (struct monst *));
 E void FDECL(cutworm, (struct monst *, XCHAR_P, XCHAR_P, BOOLEAN_P));
 E void FDECL(see_wsegs, (struct monst *));
 E void FDECL(detect_wsegs, (struct monst *, BOOLEAN_P));
index ad00be3615b980da268c3f1d3753a6e097a02faf..baeb2d5fa48b644bb228e0dfc882a588bfe8552e 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 mcastu.c        $NHDT-Date: 1567418129 2019/09/02 09:55:29 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.55 $ */
+/* NetHack 3.6 mcastu.c        $NHDT-Date: 1580633721 2020/02/02 08:55:21 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.64 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2011. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -82,8 +82,7 @@ static int
 choose_magic_spell(spellval)
 int spellval;
 {
-    /* for 3.4.3 and earlier, val greater than 22 selected the default spell
-     */
+    /* for 3.4.3 and earlier, val greater than 22 selected default spell */
     while (spellval > 24 && rn2(25))
         spellval = rn2(spellval);
 
@@ -232,7 +231,7 @@ boolean foundyou;
     /* monster unable to cast spells? */
     if (mtmp->mcan || mtmp->mspec_used || !ml) {
         cursetxt(mtmp, is_undirected_spell(mattk->adtyp, spellnum));
-        return (0);
+        return 0;
     }
 
     if (mattk->adtyp == AD_SPEL || mattk->adtyp == AD_CLRC) {
@@ -250,14 +249,14 @@ boolean foundyou;
               canseemon(mtmp) ? Monnam(mtmp) : "Something",
               levl[mtmp->mux][mtmp->muy].typ == WATER ? "empty water"
                                                       : "thin air");
-        return (0);
+        return 0;
     }
 
     nomul(0);
     if (rn2(ml * 10) < (mtmp->mconf ? 100 : 20)) { /* fumbled attack */
         if (canseemon(mtmp) && !Deaf)
             pline_The("air crackles around %s.", mon_nam(mtmp));
-        return (0);
+        return 0;
     }
     if (canspotmon(mtmp) || !is_undirected_spell(mattk->adtyp, spellnum)) {
         pline("%s casts a spell%s!",
@@ -283,7 +282,7 @@ boolean foundyou;
             impossible(
               "%s casting non-hand-to-hand version of hand-to-hand spell %d?",
                        Monnam(mtmp), mattk->adtyp);
-            return (0);
+            return 0;
         }
     } else if (mattk->damd)
         dmg = d((int) ((ml / 2) + mattk->damn), (int) mattk->damd);
@@ -293,7 +292,6 @@ boolean foundyou;
         dmg = (dmg + 1) / 2;
 
     ret = 1;
-
     switch (mattk->adtyp) {
     case AD_FIRE:
         pline("You're enveloped in flames.");
@@ -334,7 +332,7 @@ boolean foundyou;
     }
     if (dmg)
         mdamageu(mtmp, dmg);
-    return (ret);
+    return ret;
 }
 
 static int
@@ -845,11 +843,11 @@ register struct attack *mattk;
     /* don't print constant stream of curse messages for 'normal'
        spellcasting monsters at range */
     if (mattk->adtyp > AD_SPC2)
-        return (0);
+        return 0;
 
     if (mtmp->mcan) {
         cursetxt(mtmp, FALSE);
-        return (0);
+        return 0;
     }
     if (lined_up(mtmp) && rn2(3)) {
         nomul(0);
@@ -862,7 +860,7 @@ register struct attack *mattk;
         } else
             impossible("Monster spell %d cast", mattk->adtyp - 1);
     }
-    return (1);
+    return 1;
 }
 
 /*mcastu.c*/
index 324eaeb05c6ef5137d854e790dabc7329b607c8d..4d18d2850451e42709c75ba6c19b0442f63ee1f2 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 monmove.c       $NHDT-Date: 1579616424 2020/01/21 14:20:24 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.128 $ */
+/* NetHack 3.6 monmove.c       $NHDT-Date: 1580633722 2020/02/02 08:55:22 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.129 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Michael Allison, 2006. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -631,22 +631,23 @@ register struct monst *mtmp;
         /* arbitrary distance restriction to keep monster far away
            from you from having cast dozens of sticks-to-snakes
            or similar spells by the time you reach it */
-        if (dist2(mtmp->mx, mtmp->my, u.ux, u.uy) <= 49
-            && !mtmp->mspec_used) {
+        if (!mtmp->mspec_used
+            && dist2(mtmp->mx, mtmp->my, u.ux, u.uy) <= 49) {
             struct attack *a;
 
             for (a = &mdat->mattk[0]; a < &mdat->mattk[NATTK]; a++) {
                 if (a->aatyp == AT_MAGC
                     && (a->adtyp == AD_SPEL || a->adtyp == AD_CLRC)) {
                     if (castmu(mtmp, a, FALSE, FALSE)) {
-                        tmp = 3;
+                        tmp = 3; /* bypass m_move() */
                         break;
                     }
                 }
             }
         }
 
-        tmp = m_move(mtmp, 0);
+        if (!tmp)
+            tmp = m_move(mtmp, 0);
         if (tmp != 2)
             distfleeck(mtmp, &inrange, &nearby, &scared); /* recalc */
 
@@ -690,14 +691,18 @@ register struct monst *mtmp;
     /*  Now, attack the player if possible - one attack set per monst
      */
 
-    if (!mtmp->mpeaceful || (Conflict && !resist(mtmp, RING_CLASS, 0, 0))) {
-        if (inrange && !noattacks(mdat)
-            && (Upolyd ? u.mh : u.uhp) > 0 && !scared && tmp != 3)
+    if (tmp != 3 && (!mtmp->mpeaceful
+                     || (Conflict && !resist(mtmp, RING_CLASS, 0, 0)))) {
+        if (inrange && !scared && !noattacks(mdat)
+            /* [is this hp check really needed?] */
+            && (Upolyd ? u.mh : u.uhp) > 0) {
             if (mattacku(mtmp))
                 return 1; /* monster died (e.g. exploded) */
-
-        if (mtmp->wormno)
-            wormhitu(mtmp);
+        }
+        if (mtmp->wormno) {
+            if (wormhitu(mtmp))
+                return 1; /* worm died (poly'd hero passive counter-attack) */
+        }
     }
     /* special speeches for quest monsters */
     if (!mtmp->msleeping && mtmp->mcanmove && nearby)
@@ -707,6 +712,7 @@ register struct monst *mtmp;
         && couldsee(mtmp->mx, mtmp->my) && !mtmp->minvis && !rn2(5))
         cuss(mtmp);
 
+    /* note: can't get here when tmp==2 so this always returns 0 */
     return (tmp == 2);
 }
 
index 920a2766f357fc0abb45117750ebbc576ddb091b..28f47542d6f213fe664e6f27d134cd089f883726 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 worm.c  $NHDT-Date: 1580043421 2020/01/26 12:57:01 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.42 $ */
+/* NetHack 3.6 worm.c  $NHDT-Date: 1580633722 2020/02/02 08:55:22 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.43 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2009. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -329,8 +329,10 @@ struct monst *worm;
  *  Check for mon->wormno before calling this function!
  *
  *  If the hero is near any part of the worm, the worm will try to attack.
+ *  Returns 1 if the worm dies (poly'd hero with passive counter-attack)
+ *  or 0 if it doesn't.
  */
-void
+int
 wormhitu(worm)
 struct monst *worm;
 {
@@ -341,11 +343,15 @@ struct monst *worm;
      *  is out of range of the player.  We might try to kludge, and bring
      *  the head within range for a tiny moment, but this needs a bit more
      *  looking at before we decide to do this.
+     *
+     *  Head has already had a chance to attack, so the dummy tail segment
+     *  sharing its location should be skipped.
      */
-    for (seg = wtails[wnum]; seg; seg = seg->nseg)
+    for (seg = wtails[wnum]; seg != wheads[wnum]; seg = seg->nseg)
         if (distu(seg->wx, seg->wy) < 3)
             if (mattacku(worm))
-                return; /* your passive ability killed the worm */
+                return 1; /* your passive ability killed the worm */
+    return 0;
 }
 
 /*  cutworm()