fix SC343-9, bones handling for corpse/statue of unique monster (trunk only)

The logic in cant_revive() was a little off, so reviving a unique
corpse or statue on a bones level would recreate that unique monster instead
of making a doppelganger who's imitating it.  Fixing that was simple but had
the unintended side-effect of making it impossible to deliberately create
unique monsters with ^G in wizard mode.  So create_particular() has been
modified to let the user override the zombie or doppelganger conversion.
And then when not overriding, shapechangers took on random appearance, so
this also changes create_particular() to override shape changing.  And that
has the side-effect of making chameleons or vampires start out as themselves
instead of as random critters or bats/fog clouds.  [Better stop now! :-]

    resetobjs() also needed to have extra corpse handling when saving bones
because the fix for revival wouldn't prevent you from turning to stone by
eating apparent-Medusa's corpse.  Statues of uniques and corpses of special
humans like vault guards and shopkeepers didn't need anything extra; they
can retain original form until an attempt at revival is tried.

    I'm not going to try to adapt this for 3.4.4.
This commit is contained in:
nethack.rankin
2005-10-08 04:19:31 +00:00
parent 8c56042a0c
commit 8f8538e527
3 changed files with 37 additions and 14 deletions

View File

@@ -89,6 +89,7 @@ prevent polymorphing into "new man" at low level from magnifying HP and Pw
losing a level while polymorphed affects hero's current monster HP as well as
underlying normal HP
mind flayer brain eating is subject to certain fatal targets and to cannibalism
corpses of unique monsters in bones behaved incorrectly if revived or eaten
Platform- and/or Interface-Specific Fixes

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)bones.c 3.5 2004/12/17 */
/* SCCS Id: @(#)bones.c 3.5 2005/10/07 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985,1993. */
/* NetHack may be freely redistributed. See license for details. */
@@ -127,8 +127,18 @@ boolean restore;
vault guards in order to prevent corpse
revival or statue reanimation. */
if (otmp->oattached == OATTACHED_MONST &&
cant_revive(&mnum, FALSE, (struct obj *)0))
cant_revive(&mnum, FALSE, (struct obj *)0)) {
otmp->oattached = OATTACHED_NOTHING;
/* mnum is now either human_zombie or
doppelganger; for corpses of uniques,
we need to force the transformation
now rather than wait until a revival
attempt, otherwise eating this corpse
would behave as if it remains unique */
if (mnum == PM_DOPPELGANGER &&
otmp->otyp == CORPSE)
otmp->corpsenm = mnum;
}
} else if (otmp->otyp == AMULET_OF_YENDOR) {
/* no longer the real Amulet */
otmp->otyp = FAKE_AMULET_OF_YENDOR;

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)read.c 3.5 2005/04/14 */
/* SCCS Id: @(#)read.c 3.5 2005/10/07 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1893,8 +1893,8 @@ unpunish()
}
/* some creatures have special data structures that only make sense in their
* normal locations -- if the player tries to create one elsewhere, or to revive
* one, the disoriented creature becomes a zombie
* normal locations -- if the player tries to create one elsewhere, or to
* revive one, the disoriented creature becomes a zombie
*/
boolean
cant_revive(mtype, revival, from_obj)
@@ -1902,17 +1902,17 @@ int *mtype;
boolean revival;
struct obj *from_obj;
{
/* SHOPKEEPERS can be revived now */
if (*mtype==PM_GUARD || (*mtype==PM_SHOPKEEPER && !revival)
|| *mtype==PM_ALIGNED_PRIEST || *mtype==PM_ANGEL) {
if (*mtype == PM_GUARD || (*mtype == PM_SHOPKEEPER && !revival) ||
*mtype == PM_HIGH_PRIEST || *mtype == PM_ALIGNED_PRIEST ||
*mtype == PM_ANGEL) {
*mtype = PM_HUMAN_ZOMBIE;
return TRUE;
} else if (*mtype==PM_LONG_WORM_TAIL) { /* for create_particular() */
} else if (*mtype == PM_LONG_WORM_TAIL) { /* for create_particular() */
*mtype = PM_LONG_WORM;
return TRUE;
} else if (from_obj && unique_corpstat(&mons[*mtype]) &&
from_obj->oattached != OATTACHED_MONST) {
} else if (unique_corpstat(&mons[*mtype]) &&
(!from_obj || from_obj->oattached != OATTACHED_MONST)) {
/* unique corpses (from bones or wizard mode wish) or
statues (bones or any wish) end up as shapechangers */
*mtype = PM_DOPPELGANGER;
@@ -1933,7 +1933,7 @@ boolean
create_particular()
{
char buf[BUFSZ], *bufp, monclass = MAXMCLASSES;
int which, tries, i;
int which, tries, i, firstchoice = NON_PM;
struct permonst *whichpm;
struct monst *mtmp;
boolean madeany = FALSE;
@@ -1981,7 +1981,15 @@ create_particular()
pline(thats_enough_tries);
} else {
if (!randmonst) {
(void) cant_revive(&which, FALSE, (struct obj *)0);
firstchoice = which;
if (cant_revive(&which, FALSE, (struct obj *)0)) {
#ifdef WIZARD /* intentionally redundant... */
/* wizard mode can override handling of special monsters */
Sprintf(buf, "Creating %s instead; force %s?",
mons[which].mname, mons[firstchoice].mname);
if (yn(buf) == 'y') which = firstchoice;
#endif
}
whichpm = &mons[which];
}
for (i = 0; i <= multi; i++) {
@@ -2004,7 +2012,11 @@ create_particular()
set_malign(mtmp);
}
}
if (mtmp) madeany = TRUE;
if (mtmp) {
madeany = TRUE;
if (mtmp->cham && firstchoice != NON_PM)
(void)newcham(mtmp, &mons[firstchoice], FALSE, FALSE);
}
}
}
return madeany;