From 8907a5df9c90bfe17b51a7bcae2e19c29a7a800b Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 30 Oct 2020 17:46:21 -0700 Subject: [PATCH] more alignment conversion The overview code could reveal the true alignment of an altar if hero saw a mimic pretending to be an altar on that spot, or reveal junk for the alignment when mimicking at altar on some other spot. Avoid passing macros that might evaluate their arguments more than once to other macros which might also do that. The hidden code expansion can easily get out of hand (although in this case it was modest). Also, get rid of the unused MSA_foo alignment values since two of them had the values swapped. Lastly, make Amask2align() more robust in case a value with the shrine bit set gets passed to it. --- include/align.h | 37 ++++++++++++++++++++----------------- src/dungeon.c | 13 ++++++++++--- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/include/align.h b/include/align.h index f6539ceed..055fb13ed 100644 --- a/include/align.h +++ b/include/align.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 align.h $NHDT-Date: 1596498525 2020/08/03 23:48:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 3.7 align.h $NHDT-Date: 1604105154 2020/10/31 00:45:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) Mike Stephenson, Izchak Miller 1991. */ /* NetHack may be freely redistributed. See license for details. */ @@ -30,27 +30,30 @@ typedef struct align { /* alignment & record */ #define AM_LAWFUL 4 #define AM_MASK 7 -/* Some altars are considered as shrines, so we need a flag. */ +/* Some altars are considered as shrines, so we need a flag for that + for the altarmask field of struct rm. */ #define AM_SHRINE 8 -#define AM_SPLEV_CO 3 -#define AM_SPLEV_NONCO 7 +/* special level flags, gone by the time the level has been loaded */ +#define AM_SPLEV_CO 3 /* co-aligned: force alignment to match hero's */ +#define AM_SPLEV_NONCO 7 /* non-co-aligned: force alignment to not match */ #define AM_SPLEV_RANDOM 8 -#define Amask2align(x) \ - ((aligntyp)((!(x)) ? A_NONE : ((x) == AM_LAWFUL) ? A_LAWFUL \ - : ((int) x) - 2)) +#define Amask2align(x) \ + ((aligntyp) ((((x) & AM_MASK) == 0) ? A_NONE \ + : (((x) & AM_MASK) == AM_LAWFUL) ? A_LAWFUL \ + : ((int) (x) - 2))) /* 2 => 0, 1 => -1 */ #define Align2amask(x) \ - (((x) == A_NONE) ? AM_NONE : ((x) == A_LAWFUL) ? AM_LAWFUL : (x) + 2) - -/* Because clearly Nethack needs more ways to specify alignment. - The Amask2msa AM_LAWFUL check needs to mask with AM_MASK to - strip off possible AM_SHRINE bit */ -#define Amask2msa(x) (((x) & AM_MASK) == 4 ? 3 : (x) & AM_MASK) -#define Msa2amask(x) ((x) == 3 ? 4 : (x)) + ((unsigned) (((x) == A_NONE) ? AM_NONE \ + : ((x) == A_LAWFUL) ? AM_LAWFUL \ + : ((x) + 2))) /* -1 => 1, 0 => 2 */ + +/* Because clearly Nethack needs more ways to specify alignment... + Amask2msa(): 1, 2, 4 converted to 1, 2, 3 to fit within a width 2 bitfield; + Msa2amask(): 1, 2, 3 converted back to 1, 2, 4; + For Amask2msa(), 'x' might have the shrine bit set so strip that off. */ +#define Amask2msa(x) ((((x) & AM_MASK) == 4) ? 3 : (x) & AM_MASK) +#define Msa2amask(x) (((x) == 3) ? 4 : (x)) #define MSA_NONE 0 /* unaligned or multiple alignments */ -#define MSA_LAWFUL 1 -#define MSA_NEUTRAL 2 -#define MSA_CHAOTIC 3 #endif /* ALIGN_H */ diff --git a/src/dungeon.c b/src/dungeon.c index 17a5ba3f1..e116073b9 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dungeon.c $NHDT-Date: 1596498164 2020/08/03 23:42:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.133 $ */ +/* NetHack 3.7 dungeon.c $NHDT-Date: 1604105163 2020/10/31 00:46:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.135 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2842,10 +2842,13 @@ recalc_mapseen() mptr->feat.ngrave = count; break; case ALTAR: + /* get the altarmask for this location; might be a mimic */ + atmp = altarmask_at(x, y); + /* convert to index: 0..3 */ atmp = (Is_astralevel(&u.uz) && (levl[x][y].seenv & SVALL) != SVALL) ? MSA_NONE - : Amask2msa(levl[x][y].altarmask); + : Amask2msa(atmp); if (!mptr->feat.naltar) mptr->feat.msalign = atmp; else if (mptr->feat.msalign != atmp) @@ -3297,6 +3300,8 @@ boolean printdun; an(shop_string(mptr->feat.shoptype))); } if (mptr->feat.naltar > 0) { + unsigned atmp; + /* Temples + non-temple altars get munged into just "altars" */ if (mptr->feat.ntemple != mptr->feat.naltar) ADDNTOBUF("altar", mptr->feat.naltar); @@ -3304,7 +3309,9 @@ boolean printdun; ADDNTOBUF("temple", mptr->feat.ntemple); /* only print out altar's god if they are all to your god */ - if (Amask2align(Msa2amask(mptr->feat.msalign)) == u.ualign.type) + atmp = mptr->feat.msalign; /* 0, 1, 2, 3 */ + atmp = Msa2amask(atmp); /* 0, 1, 2, 4 */ + if (Amask2align(atmp) == u.ualign.type) /* -127, -1, 0, +1 */ Sprintf(eos(buf), " to %s", align_gname(u.ualign.type)); } ADDNTOBUF("throne", mptr->feat.nthrone); -- 2.50.1