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:
@@ -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
|
losing a level while polymorphed affects hero's current monster HP as well as
|
||||||
underlying normal HP
|
underlying normal HP
|
||||||
mind flayer brain eating is subject to certain fatal targets and to cannibalism
|
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
|
Platform- and/or Interface-Specific Fixes
|
||||||
|
|||||||
+12
-2
@@ -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. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985,1993. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -127,8 +127,18 @@ boolean restore;
|
|||||||
vault guards in order to prevent corpse
|
vault guards in order to prevent corpse
|
||||||
revival or statue reanimation. */
|
revival or statue reanimation. */
|
||||||
if (otmp->oattached == OATTACHED_MONST &&
|
if (otmp->oattached == OATTACHED_MONST &&
|
||||||
cant_revive(&mnum, FALSE, (struct obj *)0))
|
cant_revive(&mnum, FALSE, (struct obj *)0)) {
|
||||||
otmp->oattached = OATTACHED_NOTHING;
|
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) {
|
} else if (otmp->otyp == AMULET_OF_YENDOR) {
|
||||||
/* no longer the real Amulet */
|
/* no longer the real Amulet */
|
||||||
otmp->otyp = FAKE_AMULET_OF_YENDOR;
|
otmp->otyp = FAKE_AMULET_OF_YENDOR;
|
||||||
|
|||||||
+24
-12
@@ -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. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* 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
|
/* 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
|
* normal locations -- if the player tries to create one elsewhere, or to
|
||||||
* one, the disoriented creature becomes a zombie
|
* revive one, the disoriented creature becomes a zombie
|
||||||
*/
|
*/
|
||||||
boolean
|
boolean
|
||||||
cant_revive(mtype, revival, from_obj)
|
cant_revive(mtype, revival, from_obj)
|
||||||
@@ -1902,17 +1902,17 @@ int *mtype;
|
|||||||
boolean revival;
|
boolean revival;
|
||||||
struct obj *from_obj;
|
struct obj *from_obj;
|
||||||
{
|
{
|
||||||
|
|
||||||
/* SHOPKEEPERS can be revived now */
|
/* SHOPKEEPERS can be revived now */
|
||||||
if (*mtype==PM_GUARD || (*mtype==PM_SHOPKEEPER && !revival)
|
if (*mtype == PM_GUARD || (*mtype == PM_SHOPKEEPER && !revival) ||
|
||||||
|| *mtype==PM_ALIGNED_PRIEST || *mtype==PM_ANGEL) {
|
*mtype == PM_HIGH_PRIEST || *mtype == PM_ALIGNED_PRIEST ||
|
||||||
|
*mtype == PM_ANGEL) {
|
||||||
*mtype = PM_HUMAN_ZOMBIE;
|
*mtype = PM_HUMAN_ZOMBIE;
|
||||||
return TRUE;
|
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;
|
*mtype = PM_LONG_WORM;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} else if (from_obj && unique_corpstat(&mons[*mtype]) &&
|
} else if (unique_corpstat(&mons[*mtype]) &&
|
||||||
from_obj->oattached != OATTACHED_MONST) {
|
(!from_obj || from_obj->oattached != OATTACHED_MONST)) {
|
||||||
/* unique corpses (from bones or wizard mode wish) or
|
/* unique corpses (from bones or wizard mode wish) or
|
||||||
statues (bones or any wish) end up as shapechangers */
|
statues (bones or any wish) end up as shapechangers */
|
||||||
*mtype = PM_DOPPELGANGER;
|
*mtype = PM_DOPPELGANGER;
|
||||||
@@ -1933,7 +1933,7 @@ boolean
|
|||||||
create_particular()
|
create_particular()
|
||||||
{
|
{
|
||||||
char buf[BUFSZ], *bufp, monclass = MAXMCLASSES;
|
char buf[BUFSZ], *bufp, monclass = MAXMCLASSES;
|
||||||
int which, tries, i;
|
int which, tries, i, firstchoice = NON_PM;
|
||||||
struct permonst *whichpm;
|
struct permonst *whichpm;
|
||||||
struct monst *mtmp;
|
struct monst *mtmp;
|
||||||
boolean madeany = FALSE;
|
boolean madeany = FALSE;
|
||||||
@@ -1981,7 +1981,15 @@ create_particular()
|
|||||||
pline(thats_enough_tries);
|
pline(thats_enough_tries);
|
||||||
} else {
|
} else {
|
||||||
if (!randmonst) {
|
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];
|
whichpm = &mons[which];
|
||||||
}
|
}
|
||||||
for (i = 0; i <= multi; i++) {
|
for (i = 0; i <= multi; i++) {
|
||||||
@@ -2004,7 +2012,11 @@ create_particular()
|
|||||||
set_malign(mtmp);
|
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;
|
return madeany;
|
||||||
|
|||||||
Reference in New Issue
Block a user