]> granicus.if.org Git - nethack/commitdiff
fix #K2154 - monster wearing alchemy smock
authorPatR <rankin@nethack.org>
Wed, 28 Jul 2021 20:45:56 +0000 (13:45 -0700)
committerPatR <rankin@nethack.org>
Wed, 28 Jul 2021 20:45:56 +0000 (13:45 -0700)
For the hero, a worn alchemy smock confers both poison resistance
and acid resistance.  For monsters, it was only conferring poison
resistance.  Change ut to add acid resistance too.

doc/fixes37.0
src/worn.c

index b535ea9c16db39b26790b0c0fb07c0085b2666fd..b40f69fb0164cf7c094cbe47d1a5cdee36d0ed5a 100644 (file)
@@ -1,4 +1,4 @@
-NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.609 $ $NHDT-Date: 1627414178 2021/07/27 19:29:38 $
+NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.610 $ $NHDT-Date: 1627505147 2021/07/28 20:45:47 $
 
 General Fixes and Modified Features
 -----------------------------------
@@ -576,6 +576,8 @@ some monsters should not have been scared of bugle playing
 monsters that drowned would never leave a corpse (holdover from decades ago
        when it wasn't possible to recover anything from a water location)
 give alternate message if hero is blind when throne gives "your vision clears"
+monster wearing an alchemy smock was only getting poison resistance from it,
+       not acid resistance; give both properties, just like for hero
 
 
 Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
index 050d20c911c39d7fc748d7747bc56509f0e8144a..1a04fb066e74c7bc5010f4fa5a18ade345787c6b 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 worn.c  $NHDT-Date: 1606919259 2020/12/02 14:27:39 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ */
+/* NetHack 3.7 worn.c  $NHDT-Date: 1627505148 2021/07/28 20:45:48 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.77 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2013. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -333,6 +333,16 @@ mon_adjust_speed(struct monst *mon,
     }
 }
 
+/* alchemy smock confers two properites, poison and acid resistance
+   but objects[ALCHEMY_SMOCK].oc_oprop can only describe one of them;
+   if it is poison resistance, alternate property is acid resistance;
+   if someone changes it to acid resistance, alt becomes posion resist;
+   if someone changes it to hallucination resistance, all bets are off */
+#define altprop(o) \
+    (((o)->otyp == ALCHEMY_SMOCK)                               \
+     ? (POISON_RES + ACID_RES - objects[(o)->otyp].oc_oprop)    \
+     : 0)
+
 /* armor put on or taken off; might be magical variety
    [TODO: rename to 'update_mon_extrinsics()' and change all callers...] */
 void
@@ -342,12 +352,14 @@ update_mon_intrinsics(struct monst *mon, struct obj *obj, boolean on,
     int unseen;
     uchar mask;
     struct obj *otmp;
-    int which = (int) objects[obj->otyp].oc_oprop;
+    int which = (int) objects[obj->otyp].oc_oprop,
+        altwhich = altprop(obj);
 
     unseen = !canseemon(mon);
     if (!which)
         goto maybe_blocks;
 
+ again:
     if (on) {
         switch (which) {
         case INVIS:
@@ -409,14 +421,30 @@ update_mon_intrinsics(struct monst *mon, struct obj *obj, boolean on,
         case POISON_RES:
         case ACID_RES:
         case STONE_RES:
+            /*
+             * Update monster's extrinsics (for worn objects only;
+             * 'obj' itself might still be worn or already unworn).
+             *
+             * If an alchemy smock is being taken off, this code will
+             * be run twice (via 'goto again') and other worn gear
+             * gets tested for conferring poison resistance on the
+             * first pass and acid resistance on the second.
+             *
+             * If some other item is being taken off, there will be
+             * only one pass but a worn alchemy smock will be an
+             * alternate source for either of those two resistances.
+             */
             mask = (uchar) (1 << (which - 1));
-            /* update monster's extrinsics (for worn objects only;
-               'obj' itself might still be worn or already unworn) */
-            for (otmp = mon->minvent; otmp; otmp = otmp->nobj)
-                if (otmp != obj
-                    && otmp->owornmask
-                    && (int) objects[otmp->otyp].oc_oprop == which)
+            for (otmp = mon->minvent; otmp; otmp = otmp->nobj) {
+                if (otmp == obj || !otmp->owornmask)
+                    continue;
+                if ((int) objects[otmp->otyp].oc_oprop == which)
                     break;
+                /* check whether 'otmp' confers target property as an extra
+                   one rather than as the one specified for it in objects[] */
+                if (altprop(otmp) == which)
+                    break;
+            }
             if (!otmp)
                 mon->mextrinsics &= ~((unsigned short) mask);
             break;
@@ -425,6 +453,13 @@ update_mon_intrinsics(struct monst *mon, struct obj *obj, boolean on,
         }
     }
 
+    /* worn alchemy smock/apron confers both poison resistance and acid
+       resistance to the hero so do likewise for monster who wears one */
+    if (altwhich && which != altwhich) {
+        which = altwhich;
+        goto again;
+    }
+
  maybe_blocks:
     /* obj->owornmask has been cleared by this point, so we can't use it.
        However, since monsters don't wield armor, we don't have to guard
@@ -446,6 +481,8 @@ update_mon_intrinsics(struct monst *mon, struct obj *obj, boolean on,
         newsym(mon->mx, mon->my);
 }
 
+#undef altprop
+
 int
 find_mac(struct monst *mon)
 {