]> granicus.if.org Git - nethack/commitdiff
giant carrying boulder dies while trapped in a pit (trunk only)
authornethack.allison <nethack.allison>
Sun, 11 Apr 2004 18:39:14 +0000 (18:39 +0000)
committernethack.allison <nethack.allison>
Sun, 11 Apr 2004 18:39:14 +0000 (18:39 +0000)
<Someone> wrote:
> "You kill the invisible storm giant.  The boulder fills a pit."
> [...] why did I find the corpse *lying on* and not *buried in* the
> former pit?

Ensure that the corpse ends up buried in that case.

doc/fixes35.0
include/extern.h
include/hack.h
src/dog.c
src/mklev.c
src/mkmaze.c
src/mkobj.c
src/mon.c
src/trap.c

index dd8235f787063636fd7d28a7b93cf9107d1de660..4e5255888f442de98bf06346fbfec9cae3567104 100644 (file)
@@ -62,6 +62,8 @@ tripping over a cockatrice corpse didn't petrify, even when not wearing boots
 do not call swamps on the Juiblex level "moat" when freezing
 keep score from wrapping around and becoming negative by capping it
 kicked objects do not slide when on the air or water levels
+when a giant carrying a boulder dies in a pit, ensure that the corpse is
+       buried under the filled pit
 
 
 Platform- and/or Interface-Specific Fixes
index ff09d477b7b320f2c6853fd6f37db722f0ae621b..8b77c0becd9d09b4b8cbbd4dbf54552c2656f93a 100644 (file)
@@ -1088,7 +1088,7 @@ E int FDECL(bcsign, (struct obj *));
 E int FDECL(weight, (struct obj *));
 E struct obj *FDECL(mkgold, (long,int,int));
 E struct obj *FDECL(mkcorpstat,
-               (int,struct monst *,struct permonst *,int,int,BOOLEAN_P));
+               (int,struct monst *,struct permonst *,int,int,unsigned));
 E int FDECL(corpse_revive_type, (struct obj *));
 E struct obj *FDECL(obj_attach_mid, (struct obj *, unsigned));
 E struct monst *FDECL(get_mtraits, (struct obj *, BOOLEAN_P));
index b1677b1f508f6e902cb92b13d30d858ad322e353..26cde3aae008e58f56aa5072bf1c1574f8e3e6d6 100644 (file)
@@ -143,6 +143,11 @@ NEARDATA extern coord bhitpos;     /* place where throw or zap hits or stops */
 #define MM_IGNOREWATER   0x80  /* ignore water when positioning */
 #define MM_ADJACENTOK    0x100 /* it is acceptable to use adjacent coordinates */
 
+/* flags for make_corpse() and mkcorpstat() */
+#define CORPSTAT_NONE    0x00
+#define CORPSTAT_INIT    0x01  /* pass init flag to mkcorpstat */
+#define CORPSTAT_BURIED          0x02  /* bury the corpse or statue */
+
 /* special mhpmax value when loading bones monster to flag as extinct or genocided */
 #define DEFUNCT_MONSTER        (-100)
 
index 0c99ff7689040f9cfbf58e671df2afa820750894..98301e8f76502a563bf4c24d0787aa124c2387f5 100644 (file)
--- a/src/dog.c
+++ b/src/dog.c
@@ -379,7 +379,7 @@ boolean with_you;
                    }
                }
                corpse = mkcorpstat(CORPSE, (struct monst *)0, mtmp->data,
-                               xlocale, ylocale, FALSE);
+                               xlocale, ylocale, CORPSTAT_NONE);
 #ifndef GOLDOBJ
                if (mtmp->mgold) {
                    if (xlocale == 0 && ylocale == 0 && corpse) {
index c1fb7cc2c0ccf7333848246e2b85ca4cab65ff6d..60d954924b9fbbb4d871d32f0578e97ed2d60513 100644 (file)
@@ -791,7 +791,7 @@ skip0:
                if(!rn2(20))
                    (void) mkcorpstat(STATUE, (struct monst *)0,
                                      (struct permonst *)0,
-                                     somex(croom), somey(croom), TRUE);
+                                     somex(croom), somey(croom), CORPSTAT_INIT);
                /* put box/chest inside;
                 *  40% chance for at least 1 box, regardless of number
                 *  of rooms; about 5 - 7.5% for 2 boxes, least likely
index 12aaee69946d2f309b0e4483ba18134bb1677f7a..0a810067cb458a70d5ddb1abb116f2128141a6aa 100644 (file)
@@ -431,7 +431,7 @@ fixup_special()
            otmp = mk_tt_object(STATUE, somex(croom), somey(croom));
        else /* Medusa statues don't contain books */
            otmp = mkcorpstat(STATUE, (struct monst *)0, (struct permonst *)0,
-                             somex(croom), somey(croom), FALSE);
+                             somex(croom), somey(croom), CORPSTAT_NONE);
        if (otmp) {
            while (pm_resistance(&mons[otmp->corpsenm],MR_STONE)
                   || poly_when_stoned(&mons[otmp->corpsenm])) {
index f34c8e3da4dd31b6ce3fc5677234abe06572b5c0..d067deb0a3de8d22d210d6bf3d394aaa4db87a5a 100644 (file)
@@ -884,14 +884,15 @@ int x, y;
  * resurrection.
  */
 struct obj *
-mkcorpstat(objtype, mtmp, ptr, x, y, init)
+mkcorpstat(objtype, mtmp, ptr, x, y, corpstatflags)
 int objtype;   /* CORPSE or STATUE */
 struct monst *mtmp;
 struct permonst *ptr;
 int x, y;
-boolean init;
+unsigned corpstatflags;
 {
        register struct obj *otmp;
+       boolean init = ((corpstatflags & CORPSTAT_INIT) != 0);
 
        if (objtype != CORPSE && objtype != STATUE)
            impossible("making corpstat type %d", objtype);
@@ -1058,9 +1059,11 @@ int x, y;
 const char *nm;
 {
        struct obj *otmp;
+       unsigned corpstatflags = (objtype != STATUE) ?
+                                CORPSTAT_INIT : CORPSTAT_NONE;
 
        otmp = mkcorpstat(objtype, (struct monst *)0, ptr,
-                               x, y, (boolean)(objtype != STATUE));
+                               x, y, corpstatflags);
        if (nm)
                otmp = oname(otmp, nm);
        return(otmp);
index 2eea44bab9bd73fdf85b67fcff56519e2739caf0..6312e612268a6268e722fc7682d00c0ddd1f060e 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -30,7 +30,6 @@ STATIC_DCL void FDECL(kill_eggs, (struct obj *));
           (level.flags.graveyard && is_undead(mdat) && rn2(3))
 #endif
 
-
 #if 0
 /* part of the original warning code which was replaced in 3.3.1 */
 #define warnDelay 10
@@ -44,7 +43,7 @@ const char *warnings[] = {
 STATIC_DCL void NDECL(warn_effects);
 #endif /* 0 */
 
-STATIC_DCL struct obj *FDECL(make_corpse,(struct monst *));
+STATIC_DCL struct obj *FDECL(make_corpse,(struct monst *, unsigned));
 STATIC_DCL void FDECL(m_detach, (struct monst *, struct permonst *));
 STATIC_DCL void FDECL(lifesaved_monster, (struct monst *));
 
@@ -162,14 +161,17 @@ STATIC_VAR short cham_to_pm[] = {
  * etc....
  */
 STATIC_OVL struct obj *
-make_corpse(mtmp)
+make_corpse(mtmp,corpseflags)
 register struct monst *mtmp;
+unsigned corpseflags;
 {
        register struct permonst *mdat = mtmp->data;
        int num;
        struct obj *obj = (struct obj *)0;
        int x = mtmp->mx, y = mtmp->my;
        int mndx = monsndx(mdat);
+       unsigned corpstatflags = corpseflags;
+       boolean burythem = ((corpstatflags & CORPSTAT_BURIED) != 0);
 
        switch(mndx) {
            case PM_GRAY_DRAGON:
@@ -211,7 +213,8 @@ register struct monst *mtmp;
            case PM_VAMPIRE_LORD:
                /* include mtmp in the mkcorpstat() call */
                num = undead_to_corpse(mndx);
-               obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, TRUE);
+               corpstatflags |= CORPSTAT_INIT;
+               obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, corpstatflags);
                obj->age -= 100;                /* this is an *OLD* corpse */
                break;
            case PM_KOBOLD_MUMMY:
@@ -231,7 +234,8 @@ register struct monst *mtmp;
            case PM_GIANT_ZOMBIE:
            case PM_ETTIN_ZOMBIE:
                num = undead_to_corpse(mndx);
-               obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, TRUE);
+               corpstatflags |= CORPSTAT_INIT;
+               obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, corpstatflags);
                obj->age -= 100;                /* this is an *OLD* corpse */
                break;
            case PM_IRON_GOLEM:
@@ -253,8 +257,9 @@ register struct monst *mtmp;
                mtmp->mnamelth = 0;
                break;
            case PM_STONE_GOLEM:
+               corpstatflags &= ~CORPSTAT_INIT;
                obj = mkcorpstat(STATUE, (struct monst *)0,
-                       mdat, x, y, FALSE);
+                       mdat, x, y, corpstatflags);
                break;
            case PM_WOOD_GOLEM:
                num = d(2,4);
@@ -284,9 +289,17 @@ register struct monst *mtmp;
            default:
                if (mvitals[mndx].mvflags & G_NOCORPSE)
                    return (struct obj *)0;
-               else    /* preserve the unique traits of some creatures */
+               else {
+                   corpstatflags |= CORPSTAT_INIT;
+                   /* preserve the unique traits of some creatures */
                    obj = mkcorpstat(CORPSE, KEEPTRAITS(mtmp) ? mtmp : 0,
-                                    mdat, x, y, TRUE);
+                                    mdat, x, y, corpstatflags);
+                   if (burythem) {
+                       (void) bury_an_obj(obj);
+                       newsym(x, y);
+                       return obj;
+                   }
+               }
                break;
        }
        /* All special cases should precede the G_NOCORPSE check */
@@ -1578,7 +1591,7 @@ register struct monst *mdef;
 
        if (corpse_chance(mdef, (struct monst *)0, FALSE) &&
            (accessible(mdef->mx, mdef->my) || is_pool(mdef->mx, mdef->my)))
-               (void) make_corpse(mdef);
+               (void) make_corpse(mdef,CORPSTAT_NONE);
 }
 
 /* monster disappears, not dies */
@@ -1650,7 +1663,7 @@ register struct monst *mdef;
                /* defer statue creation until after inventory removal
                   so that saved monster traits won't retain any stale
                   item-conferred attributes */
-               otmp = mkcorpstat(STATUE, mdef, mdef->data, x, y, FALSE);
+               otmp = mkcorpstat(STATUE, mdef, mdef->data, x, y, CORPSTAT_NONE);
                if (mdef->mnamelth) otmp = oname(otmp, NAME(mdef));
                while ((obj = oldminvent) != 0) {
                    oldminvent = obj->nobj;
@@ -1760,7 +1773,7 @@ xkilled(mtmp, dest)
        register struct trap *t;
        boolean redisp = FALSE;
        boolean wasinside = u.uswallow && (u.ustuck == mtmp);
-
+       boolean burycorpse = FALSE;
 
        /* KMH, conduct */
        u.uconduct.killer++;
@@ -1782,14 +1795,18 @@ xkilled(mtmp, dest)
        }
 
        if (mtmp->mtrapped && (t = t_at(x, y)) != 0 &&
-               (t->ttyp == PIT || t->ttyp == SPIKED_PIT) &&
-               sobj_at(BOULDER, x, y))
-           dest |= 2;     /*
+               (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) {
+
+               if (sobj_at(BOULDER, x, y))
+                       dest |= 2;     /*
                            * Prevent corpses/treasure being created "on top"
                            * of the boulder that is about to fall in. This is
                            * out of order, but cannot be helped unless this
                            * whole routine is rearranged.
                            */
+               if (m_carrying(mtmp, BOULDER))
+                       burycorpse = TRUE;
+       }
 
        /* your pet knows who just killed it...watch out */
        if (mtmp->mtame && !mtmp->isminion) EDOG(mtmp)->killed_by_u = 1;
@@ -1857,8 +1874,16 @@ xkilled(mtmp, dest)
                 * different from whether or not the corpse is "special";
                 * if we want both, we have to specify it explicitly.
                 */
-               if (corpse_chance(mtmp, (struct monst *)0, FALSE))
-                       (void) make_corpse(mtmp);
+               if (corpse_chance(mtmp, (struct monst *)0, FALSE)) {
+                       struct obj *cadaver = make_corpse(mtmp, burycorpse ?
+                                             CORPSTAT_BURIED : CORPSTAT_NONE);
+                       if (burycorpse && cadaver && cansee(x,y) &&
+                           !mtmp->minvis &&
+                           cadaver->where == OBJ_BURIED && (dest & 1)) {
+                               pline("%s corpse ends up buried.",
+                                       s_suffix(Monnam(mtmp)));
+                       }
+               }
        }
        if(redisp) newsym(x,y);
 cleanup:
index 8d0c0b4ac4929656c3b6cc483ed67d03ea0f5d81..abe053714cc9a142b55e563bd873a933fe0e70d6 100644 (file)
@@ -245,7 +245,7 @@ register int x, y, typ;
                struct obj *otmp, *statue;
 
                statue = mkcorpstat(STATUE, (struct monst *)0,
-                                       &mons[rndmonnum()], x, y, FALSE);
+                                       &mons[rndmonnum()], x, y, CORPSTAT_NONE);
                mtmp = makemon(&mons[statue->corpsenm], 0, 0, NO_MM_FLAGS);
                if (!mtmp) break; /* should never happen */
                while(mtmp->minvent) {