purple worms

Compiler complained about 'ptr' possibly being used unitinialized
in meatcorpse() and in this case it was right.  meatcorpse() was
cloned from meatobj() but the necessary initialization was missing.

Purple worm would devore an entire stack of corpses in one bite.
Split one off and have it eat that instead.

I'm not sure whether attempting to revive a Rider corpse can force
a monster off the level to make room.  If so, meatobj() and
meatcorpse() weren't prepared to handle that, nor was their caller.
It appears that the monster (either g.cube or purple worm) will
only eat as it moves so can't revive a Rider on a completely full
level since it won't be able to move in that situation.  I fixed
the caller to be prepared to handle a result of 3 (no further
action allowed) instead of just dealing with 2 (died), but I didn't
fix either of the meatfoo() routines to return 3 since bumping the
eating monster off the level seems to not be possible.

Don't let purple worms eat lichen corpses, regardless of whether
they'll swallow live ones.
This commit is contained in:
PatR
2020-04-05 05:57:37 -07:00
parent 30ad8eed84
commit 995a6bf4fe
2 changed files with 49 additions and 24 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 monmove.c $NHDT-Date: 1585361053 2020/03/28 02:04:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.133 $ */
/* NetHack 3.6 monmove.c $NHDT-Date: 1586091452 2020/04/05 12:57:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.137 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2006. */
/* NetHack may be freely redistributed. See license for details. */
@@ -838,7 +838,7 @@ m_move(mtmp, after)
register struct monst *mtmp;
register int after;
{
register int appr;
int appr, etmp;
xchar gx, gy, nix, niy, chcnt;
int chi; /* could be schar except for stupid Sun-2 compiler */
boolean likegold = 0, likegems = 0, likeobjs = 0, likemagic = 0,
@@ -1008,8 +1008,8 @@ register int after;
if ((!mtmp->mpeaceful || !rn2(10)) && (!Is_rogue_level(&u.uz))) {
boolean in_line = (lined_up(mtmp)
&& (distmin(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy)
<= (throws_rocks(g.youmonst.data) ? 20 : ACURRSTR / 2 + 1)));
&& (distmin(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy)
<= (throws_rocks(g.youmonst.data) ? 20 : ACURRSTR / 2 + 1)));
if (appr != 1 || !in_line) {
/* Monsters in combat won't pick stuff up, avoiding the
@@ -1530,15 +1530,14 @@ register int after;
/* Maybe a cube ate just about anything */
if (ptr == &mons[PM_GELATINOUS_CUBE]) {
if (meatobj(mtmp) == 2)
return 2; /* it died */
if ((etmp = meatobj(mtmp)) >= 2)
return etmp; /* it died or got forced off the level */
}
/* Maybe a purple worm ate a corpse */
if (ptr == &mons[PM_PURPLE_WORM]
|| ptr == &mons[PM_BABY_PURPLE_WORM]) {
if (meatcorpse(mtmp) == 2)
return 2; /* it died */
if ((etmp = meatcorpse(mtmp)) >= 2)
return etmp; /* it died or got forced off the level */
}
if (!*in_rooms(mtmp->mx, mtmp->my, SHOPBASE) || !rn2(25)) {