]> granicus.if.org Git - nethack/commitdiff
alignment of mimicked or polymorphed altars
authorPatR <rankin@nethack.org>
Mon, 25 Nov 2019 23:01:40 +0000 (15:01 -0800)
committerPatR <rankin@nethack.org>
Mon, 25 Nov 2019 23:01:40 +0000 (15:01 -0800)
A reddit thread about an unaligned altar in an aligned temple was
a tipoff that mimics posing as altars didn't have any particular
alignment.  The look-at code was misusing an operloaded field of the
underlying terrain.  Pick an alignment at random when taking on the
appearance of an altar, store it in the mimic's mon->mextra->mcorpsenm
field, and have look-at use that.

Also, dropping a ring of polymorph into a sink can transform it, and
one possible outcome is an altar.  In this case, the alignment is
part of the location's topology, but code setting that up was using
Align2amask(rn2(foo)).  That's a macro which evaluates its argument
more than once.  The first evaluation was effectively a no-op.  If
the second evaluation picked lawful then the result was lawful as
intended.  But if the second picked non-lawful and the third picked
lawful, the result would end up as none-of-the-above (a value of 3
when it needs to be a single-bit mask of 1, 2, or 4).

doc/fixes36.3
include/mextra.h
src/do.c
src/makemon.c
src/pager.c

index f522e20b5355003b66e66abaad199398d2b6daa9..238f156cabfd4df4287c6825ed731d6a61f17ba3 100644 (file)
@@ -1,4 +1,4 @@
-$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.190 $ $NHDT-Date: 1574638389 2019/11/24 23:33:09 $
+$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.191 $ $NHDT-Date: 1574722861 2019/11/25 23:01:01 $
 
 This fixes36.3 file is here to capture information about updates in the 3.6.x
 lineage following the release of 3.6.2 in May 2019. Please note, however,
@@ -302,7 +302,11 @@ when Riders use their bargethrough capability, don't let them swap places with
        there'd be no corpse so no auto-revive)
 putting on levitation boots while on sink would crash when attempting to set
        the enchantment known flag on Null 'uarmf' pointer
-unix: Fix double DLB definition in linux hints file
+look-at of mimics mimicking altars got an arbitary alignment from misuse of
+       underlying terrain
+polymorph_sink creating an altar passed a call to rn2() as an argument to a
+       macro which evaluates its parameter more than once
+unix: fix double DLB definition in linux hints file
 windows: fix --showpaths output for the data file which relies on being
        constructed programmatically to incorporate the version suffix
 
index 6879a16ace8e6abf8a2bcfe123a8b174eff38e4d..2fd27472a94f50342dd27f02ad250f83526f5e40 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 mextra.h        $NHDT-Date: 1571531885 2019/10/20 00:38:05 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.23 $ */
+/* NetHack 3.6 mextra.h        $NHDT-Date: 1574722861 2019/11/25 23:01:01 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.24 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Michael Allison, 2006. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -179,8 +179,9 @@ struct mextra {
     struct eshk *eshk;
     struct emin *emin;
     struct edog *edog;
-    int mcorpsenm; /* obj->corpsenm for mimic posing as statue or corpse, or
-                    * obj->spe (fruit index) for one posing as a slime mold */
+    int mcorpsenm; /* obj->corpsenm for mimic posing as statue or corpse,
+                    * obj->spe (fruit index) for one posing as a slime mold,
+                    * or an alignment mask for one posing as an altar */
 };
 
 #define MNAME(mon) ((mon)->mextra->mname)
index 035fd3a8ec1a5584331bdf9b6bf6f34c1c2a5ad7..72b31564071e6ebd84c89f76e3f120bf127f804a 100644 (file)
--- a/src/do.c
+++ b/src/do.c
@@ -1,4 +1,4 @@
-/* NetHack 3.6 do.c    $NHDT-Date: 1559670603 2019/06/04 17:50:03 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.192 $ */
+/* NetHack 3.6 do.c    $NHDT-Date: 1574722862 2019/11/25 23:01:02 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.193 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Derek S. Ray, 2015. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -309,6 +309,7 @@ polymorph_sink()
 {
     uchar sym = S_sink;
     boolean sinklooted;
+    int algn;
 
     if (levl[u.ux][u.uy].typ != SINK)
         return;
@@ -335,7 +336,11 @@ polymorph_sink()
     case 2:
         sym = S_altar;
         levl[u.ux][u.uy].typ = ALTAR;
-        levl[u.ux][u.uy].altarmask = Align2amask(rn2((int) A_LAWFUL + 2) - 1);
+        /* 3.6.3: this used to pass 'rn2(A_LAWFUL + 2) - 1' to
+           Align2mask() but it evaluates its argument more than once */
+        algn = rn2(3) - 1; /* -1 (A_Cha) or 0 (A_Neu) or +1 (A_Law) */
+        levl[u.ux][u.uy].altarmask = ((Inhell && rn2(3)) ? AM_NONE
+                                      : Align2amask(algn));
         break;
     case 3:
         sym = S_room;
index 2ec04698c5b2ed1a9a9e3eee6c0bdccf5b237267..3145ad6dea3ad4c3199ad3d76dded0abd774b4bf 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 makemon.c       $NHDT-Date: 1571531888 2019/10/20 00:38:08 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.141 $ */
+/* NetHack 3.6 makemon.c       $NHDT-Date: 1574722863 2019/11/25 23:01:03 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.142 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2012. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -2194,10 +2194,12 @@ register struct monst *mtmp;
     } else if (rt == TEMPLE) {
         ap_type = M_AP_FURNITURE;
         appear = S_altar;
-        /*
-         * We won't bother with beehives, morgues, barracks, throne rooms
-         * since they shouldn't contain too many mimics anyway...
-         */
+
+    /*
+     * We won't bother with beehives, morgues, barracks, throne rooms
+     * since they shouldn't contain too many mimics anyway...
+     */
+
     } else if (rt >= SHOPBASE) {
         s_sym = get_shop_item(rt - SHOPBASE);
         if (s_sym < 0) {
@@ -2254,6 +2256,11 @@ register struct monst *mtmp;
            current_fruit is equivalent to creating an instance of that
            fruit (no-op if a fruit of this type has actually been made) */
         flags.made_fruit = TRUE;
+    } else if (ap_type == M_AP_FURNITURE && appear == S_altar) {
+        int algn = rn2(3) - 1; /* -1 (A_Cha) or 0 (A_Neu) or +1 (A_Law) */
+
+        newmcorpsenm(mtmp);
+        MCORPSENM(mtmp) = (Inhell && rn2(3)) ? AM_NONE : Align2amask(algn);
     } else if (has_mcorpsenm(mtmp)) {
         /* don't retain stale value from a previously mimicked shape */
         MCORPSENM(mtmp) = NON_PM;
index 77cff068b440abcad7e27251e599f1f3385bb33b..7f14b0ffb9468a26693d929666f2fbdf9a8e8caf 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 pager.c $NHDT-Date: 1574011494 2019/11/17 17:24:54 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.161 $ */
+/* NetHack 3.6 pager.c $NHDT-Date: 1574722864 2019/11/25 23:01:04 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.162 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2018. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -477,17 +477,24 @@ char *buf, *monbuf;
         Strcpy(buf, def_warnsyms[warnindx].explanation);
     } else if (!glyph_is_cmap(glyph)) {
         Strcpy(buf, "unexplored area");
-    } else
+    } else {
+        int amsk;
+        aligntyp algn;
+
         switch (glyph_to_cmap(glyph)) {
         case S_altar:
+            amsk = ((mtmp = m_at(x, y)) != 0 && has_mcorpsenm(mtmp)
+                    && M_AP_TYPE(mtmp) == M_AP_FURNITURE
+                    && mtmp->mappearance == S_altar) ? MCORPSENM(mtmp)
+                   : levl[x][y].altarmask;
+            algn = Amask2align(amsk & ~AM_SHRINE);
             Sprintf(buf, "%s %saltar",
                     /* like endgame high priests, endgame high altars
                        are only recognizable when immediately adjacent */
                     (Is_astralevel(&u.uz) && distu(x, y) > 2)
                         ? "aligned"
-                        : align_str(
-                              Amask2align(levl[x][y].altarmask & ~AM_SHRINE)),
-                    ((levl[x][y].altarmask & AM_SHRINE)
+                        : align_str(algn),
+                    ((amsk & AM_SHRINE) != 0
                      && (Is_astralevel(&u.uz) || Is_sanctum(&u.uz)))
                         ? "high "
                         : "");
@@ -522,7 +529,7 @@ char *buf, *monbuf;
             Strcpy(buf, defsyms[glyph_to_cmap(glyph)].explanation);
             break;
         }
-
+    }
     return (pm && !Hallucination) ? pm : (struct permonst *) 0;
 }