-NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.615 $ $NHDT-Date: 1627951429 2021/08/03 00:43:49 $
+NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.629 $ $NHDT-Date: 1629817676 2021/08/24 15:07:56 $
General Fixes and Modified Features
-----------------------------------
normal play because role monsters are invalid polymorph targets there]
revise a 3.6.1 fix: if a spellbook which is being read becomes cursed, always
stop reading: "The <book> slams shut!" and set book->bknown
+concealed mimic could trigger sanity check warning "mimic concealed as an
+ object despite Prot-from-shape-changers" if hidden as "strange object"
+cancelled shape changer would become uncancelled if saved and restored (even
+ just leaving its level and then returning)
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
-/* NetHack 3.7 mon.c $NHDT-Date: 1627413528 2021/07/27 19:18:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.382 $ */
+/* NetHack 3.7 mon.c $NHDT-Date: 1629817677 2021/08/24 15:07:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.384 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */
newsym(mtmp->mx, mtmp->my);
}
-/* force all chameleons to become normal */
+/* [taken out of rescham() in order to be shared by restore_cham()] */
+void
+normal_shape(struct monst *mon)
+{
+ int mcham = (int) mon->cham;
+
+ if (mcham >= LOW_PM) {
+ unsigned mcan = mon->mcan;
+
+ (void) newcham(mon, &mons[mcham], FALSE, FALSE);
+ mon->cham = NON_PM;
+ /* newcham() may uncancel a polymorphing monster; override that */
+ if (mcan)
+ mon->mcan = 1;
+ newsym(mon->mx, mon->my);
+ }
+ if (is_were(mon->data) && mon->data->mlet != S_HUMAN) {
+ new_were(mon);
+ }
+ if (M_AP_TYPE(mon) != M_AP_NOTHING) {
+ /* this used to include a cansee() check but Protection_from_
+ _shape_changers shouldn't be trumped by being unseen */
+ if (!mon->meating) {
+ /* make revealed mimic fall asleep in lieu of shape change */
+ if (M_AP_TYPE(mon) != M_AP_MONSTER)
+ mon->msleeping = 1;
+ seemimic(mon);
+ } else {
+ /* quickmimic: pet is midst of eating a mimic corpse;
+ this terminates the meal early */
+ finish_meating(mon);
+ }
+ }
+}
+
+/* force all chameleons and mimics to become themselves and werecreatures
+ to revert to human form; called when Protection_from_shape_changers gets
+ activated via wearing or eating ring */
void
rescham(void)
{
register struct monst *mtmp;
- int mcham;
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp))
continue;
- mcham = (int) mtmp->cham;
- if (mcham >= LOW_PM) {
- (void) newcham(mtmp, &mons[mcham], FALSE, FALSE);
- mtmp->cham = NON_PM;
- }
- if (is_were(mtmp->data) && mtmp->data->mlet != S_HUMAN)
- new_were(mtmp);
- if (M_AP_TYPE(mtmp) != M_AP_NOTHING) {
- /* this used to include a cansee() check but Protection_from_
- _shape_changers shouldn't be trumped by being unseen */
- if (!mtmp->meating) {
- /* make revealed mimic fall asleep in lieu of shape change */
- if (M_AP_TYPE(mtmp) != M_AP_MONSTER)
- mtmp->msleeping = 1;
- seemimic(mtmp);
- } else {
- /* quickmimic: pet is midst of eating a mimic corpse;
- this terminates the meal early */
- finish_meating(mtmp);
- }
- }
+ normal_shape(mtmp);
}
}
-/* Let the chameleons change again -dgk */
+/* let chameleons change and mimics hide again; called when taking off
+ ring of protection from shape changers */
void
restartcham(void)
{
continue;
if (!mtmp->mcan)
mtmp->cham = pm_to_cham(monsndx(mtmp->data));
- if (mtmp->data->mlet == S_MIMIC && mtmp->msleeping
- && cansee(mtmp->mx, mtmp->my)) {
+ if (mtmp->data->mlet == S_MIMIC && mtmp->msleeping) {
set_mimic_sym(mtmp);
newsym(mtmp->mx, mtmp->my);
}
against shape-changing might be different now than it was at the
time the level was saved. */
void
-restore_cham(struct monst* mon)
+restore_cham(struct monst *mon)
{
- int mcham;
-
- if (Protection_from_shape_changers) {
- mcham = (int) mon->cham;
- if (mcham >= LOW_PM) {
- mon->cham = NON_PM;
- (void) newcham(mon, &mons[mcham], FALSE, FALSE);
- } else if (is_were(mon->data) && !is_human(mon->data)) {
- new_were(mon);
- }
+ if (Protection_from_shape_changers || mon->mcan) {
+ /* force chameleon or mimic to revert to its natural shape */
+ normal_shape(mon);
} else if (mon->cham == NON_PM) {
+ /* chameleon doesn't change shape here, just gets allowed to do so */
mon->cham = pm_to_cham(monsndx(mon->data));
}
}
/* unwatched hiders may hide again; if so, returns True */
static boolean
-restrap(struct monst* mtmp)
+restrap(struct monst *mtmp)
{
struct trap *t;
-/* NetHack 3.7 zap.c $NHDT-Date: 1626390628 2021/07/15 23:10:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.369 $ */
+/* NetHack 3.7 zap.c $NHDT-Date: 1629817679 2021/08/24 15:07:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.372 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
}
} else {
mdef->mcan = 1;
- /* force shapeshifter into its base form */
- if (M_AP_TYPE(mdef) != M_AP_NOTHING)
- seemimic(mdef);
- /* [not 'else if'; chameleon might have been hiding as a mimic] */
- if (mdef->cham >= LOW_PM) {
- /* note: newcham() uncancels shapechangers (resets m->mcan
- to 0), but only for shapechangers whose m->cham is already
- NON_PM and we just verified that it's LOW_PM or higher */
- newcham(mdef, &mons[mdef->cham], FALSE, FALSE);
- mdef->cham = NON_PM; /* cancelled shapeshifter can't shift */
- }
- if (is_were(mdef->data) && !is_human(mdef->data))
- were_change(mdef);
+ /* force shapeshifter into its base form or mimic to unhide */
+ normal_shape(mdef);
if (mdef->data == &mons[PM_CLAY_GOLEM]) {
if (canseemon(mdef))