From: nethack.rankin Date: Sat, 8 Oct 2005 04:19:31 +0000 (+0000) Subject: fix SC343-9, bones handling for corpse/statue of unique monster (trunk only) X-Git-Tag: MOVE2GIT~1225 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8f8538e527c334c2cf7901087fddb06600510da0;p=nethack 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. --- diff --git a/doc/fixes35.0 b/doc/fixes35.0 index ea35c7216..45db2795a 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -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 diff --git a/src/bones.c b/src/bones.c index 0d2d82628..561740ccb 100644 --- a/src/bones.c +++ b/src/bones.c @@ -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; diff --git a/src/read.c b/src/read.c index 9576e9f4c..f30957dd2 100644 --- a/src/read.c +++ b/src/read.c @@ -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;