alignment of mimicked or polymorphed altars
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).
This commit is contained in:
9
src/do.c
9
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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
19
src/pager.c
19
src/pager.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user