special level mimics

The special level loader would allow the level description to specify
an alternate monster appearance for any type of monster, and if one
was specified for a mimic then that mimic would be polymorphed into
the appearance instead of masquerading as it.  This changes it to
only use an appearance for mimics, the Wizard, vampires, and general
shapeshifters (chameleons, doppelgangers, sandestins).  The mimic
case doesn't work as expected:  map display shows the symbol for the
specified shape but farlook describes it as a mimic.  The Wizard case
hasn't been tested.  The chameleon and vampshifter cases seem to work.

It also allowed shapechangers (including vampires) to be given an
object or furniture appearance.  I didn't try things out to find out
what what their behavior would be if/when that happened.

I'm not sure whether the farlook issue for mimics-as-monsters is with
the pager code or the monster name formatting code.  (Possibly the
mimic just needs to be flagged has 'hidden' as well has having an
alternate appearance.)  I'm not going to worry about it since none of
our special levels attempt to give mimics a monster shape.  Mimicking
a monster is a feature for clones of the Wizard, not for mimics,
although it might be nice if the latter worked correctly someday.
This commit is contained in:
PatR
2017-12-31 17:19:38 -08:00
parent 46da4b5e90
commit bb9738ff0e
3 changed files with 34 additions and 9 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 extern.h $NHDT-Date: 1513130012 2017/12/13 01:53:32 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.621 $ */
/* NetHack 3.6 extern.h $NHDT-Date: 1514769568 2018/01/01 01:19:28 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.622 $ */
/* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1397,6 +1397,7 @@ E void FDECL(restore_cham, (struct monst *));
E boolean FDECL(hideunder, (struct monst *));
E void FDECL(hide_monst, (struct monst *));
E void FDECL(mon_animal_list, (BOOLEAN_P));
E boolean FDECL(validvamp, (struct monst *, int *, int));
E int FDECL(select_newcham_form, (struct monst *));
E void FDECL(mgender_from_permonst, (struct monst *, struct permonst *));
E int FDECL(newcham,

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mon.c $NHDT-Date: 1505266804 2017/09/13 01:40:04 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.244 $ */
/* NetHack 3.6 mon.c $NHDT-Date: 1514769571 2018/01/01 01:19:31 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.246 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -23,7 +23,6 @@ STATIC_DCL void FDECL(kill_eggs, (struct obj *));
STATIC_DCL int FDECL(pickvampshape, (struct monst *));
STATIC_DCL boolean FDECL(isspecmon, (struct monst *));
STATIC_DCL boolean FDECL(validspecmon, (struct monst *, int));
STATIC_DCL boolean FDECL(validvamp, (struct monst *, int *, int));
STATIC_DCL struct permonst *FDECL(accept_newcham_form, (int));
STATIC_DCL struct obj *FDECL(make_corpse, (struct monst *, unsigned));
STATIC_DCL void FDECL(m_detach, (struct monst *, struct permonst *));
@@ -3162,7 +3161,7 @@ int mndx;
}
/* prevent wizard mode user from specifying invalid vampshifter shape */
STATIC_OVL boolean
boolean
validvamp(mon, mndx_p, monclass)
struct monst *mon;
int *mndx_p, monclass;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 sp_lev.c $NHDT-Date: 1514720301 2017/12/31 11:38:21 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.94 $ */
/* NetHack 3.6 sp_lev.c $NHDT-Date: 1514769572 2018/01/01 01:19:32 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.95 $ */
/* Copyright (c) 1989 by Jean-Christophe Collet */
/* NetHack may be freely redistributed. See license for details. */
@@ -1589,11 +1589,14 @@ struct mkroom *croom;
mtmp = christen_monst(mtmp, m->name.str);
/*
* This is currently hardwired for mimics only. It should
* eventually be expanded.
* This doesn't complain if an attempt is made to give a
* non-mimic/non-shapechanger an appearance or to give a
* shapechanger a non-monster shape, it just refuses to comply.
*/
if (m->appear_as.str
&& ((mtmp->data->mlet == S_MIMIC) || mtmp->cham >= LOW_PM)
&& ((mtmp->data->mlet == S_MIMIC)
/* shapechanger (chameleons, et al, and vampires) */
|| (mtmp->cham >= LOW_PM && m->appear == M_AP_MONSTER))
&& !Protection_from_shape_changers) {
int i;
@@ -1658,7 +1661,29 @@ struct mkroom *croom;
mndx = select_newcham_form(mtmp);
else
mndx = name_to_mon(m->appear_as.str);
if ((mndx != NON_PM) && (&mons[mndx] != mtmp->data)) {
if (mndx == NON_PM || (is_vampshifter(mtmp)
&& !validvamp(mtmp, &mndx, S_HUMAN))) {
impossible("create_monster: invalid %s (\"%s\")",
(mtmp->data->mlet == S_MIMIC)
? "mimic appearance"
: (mtmp->data == &mons[PM_WIZARD_OF_YENDOR])
? "Wizard appearance"
: is_vampshifter(mtmp)
? "vampire shape"
: "chameleon shape",
m->appear_as.str);
} else if (&mons[mndx] == mtmp->data) {
/* explicitly forcing a mimic to appear as itself */
mtmp->m_ap_type = M_AP_NOTHING;
mtmp->mappearance = 0;
} else if (mtmp->data->mlet == S_MIMIC
|| mtmp->data == &mons[PM_WIZARD_OF_YENDOR]) {
/* this is ordinarily only used for Wizard clones
and hasn't been exhaustively tested for mimics */
mtmp->m_ap_type = M_AP_MONSTER;
mtmp->mappearance = mndx;
} else { /* chameleon or vampire */
struct permonst *mdat = &mons[mndx];
struct permonst *olddata = mtmp->data;