Skip to content

Commit

Permalink
fix SC343-9, bones handling for corpse/statue of unique monster (trun…
Browse files Browse the repository at this point in the history
…k 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.
  • Loading branch information
nethack.rankin committed Oct 8, 2005
1 parent 8c56042 commit 8f8538e
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 14 deletions.
1 change: 1 addition & 0 deletions doc/fixes35.0
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 12 additions & 2 deletions src/bones.c
Original file line number Diff line number Diff line change
@@ -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. */

Expand Down Expand Up @@ -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;
Expand Down
36 changes: 24 additions & 12 deletions src/read.c
Original file line number Diff line number Diff line change
@@ -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. */

Expand Down Expand Up @@ -1893,26 +1893,26 @@ 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)
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;
Expand All @@ -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;
Expand Down Expand Up @@ -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++) {
Expand All @@ -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;
Expand Down

0 comments on commit 8f8538e

Please sign in to comment.