]> granicus.if.org Git - nethack/commitdiff
fix SC343-9, bones handling for corpse/statue of unique monster (trunk only)
authornethack.rankin <nethack.rankin>
Sat, 8 Oct 2005 04:19:31 +0000 (04:19 +0000)
committernethack.rankin <nethack.rankin>
Sat, 8 Oct 2005 04:19:31 +0000 (04:19 +0000)
     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.

doc/fixes35.0
src/bones.c
src/read.c

index ea35c721680661548a7d0fb57d782cd9df365d2c..45db2795a6b0f7f4a7996dc1db630991a10b6068 100644 (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
index 0d2d826283b7515597684fbd14fb0e65311ec215..561740ccb4ea1b24fcf678e8650147395540d4f4 100644 (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;
index 9576e9f4cbfed243715f4a8476cf5ec14dcdbfa1..f30957dd2f92cb0e50e1e8f95ad65b4683949752 100644 (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;