fix #Q241 - swallowing Medusa (trunk only)

From a bug report, eating Medusa's corpse is fatal
but devouring her whole (purple worm or poly'd hero) was not.  Now it will
be.  Also, being killed by swallowing a cockatrice or a Rider could have
disclosed "you went without food" if you hadn't eaten anything else prior.
This fixes that too, although it might be a little silly if it happens to
a monk since he'll feel guilty (for non-vegetarian diet) right as he dies.
This commit is contained in:
nethack.rankin
2005-12-03 03:16:25 +00:00
parent c28a4aece8
commit 6955f1ab63
3 changed files with 46 additions and 33 deletions

View File

@@ -100,6 +100,8 @@ adjust feedback for gas spore explosion when hallucinating
traps detected by scroll or crystal ball overlooked carried or buried chests traps detected by scroll or crystal ball overlooked carried or buried chests
can't wish for a trapped box/chest/tin by specifying "poisoned" can't wish for a trapped box/chest/tin by specifying "poisoned"
grammar bit if killed by stealing a cockatrice corpse from a monster grammar bit if killed by stealing a cockatrice corpse from a monster
being petrified by swallowing a cockatrice violates foodless conduct
devouring Medusa whole is fatal
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)mhitm.c 3.5 2005/09/27 */ /* SCCS Id: @(#)mhitm.c 3.5 2005/12/02 */
/* 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. */
@@ -698,7 +698,9 @@ mdamagem(magr, mdef, mattk)
res = MM_MISS; res = MM_MISS;
boolean cancelled; boolean cancelled;
if (touch_petrifies(pd) && !resists_ston(magr)) { if ((touch_petrifies(pd) || /* or flesh_petrifies() */
(mattk->adtyp == AD_DGST && pd == &mons[PM_MEDUSA])) &&
!resists_ston(magr)) {
long protector = attk_protection((int)mattk->aatyp), long protector = attk_protection((int)mattk->aatyp),
wornitems = magr->misc_worn_check; wornitems = magr->misc_worn_check;
@@ -1509,4 +1511,3 @@ int aatyp;
} }
/*mhitm.c*/ /*mhitm.c*/

View File

@@ -1774,9 +1774,17 @@ gulpum(mdef,mattk)
register struct monst *mdef; register struct monst *mdef;
register struct attack *mattk; register struct attack *mattk;
{ {
#ifdef LINT /* static char msgbuf[BUFSZ]; */
char msgbuf[BUFSZ];
#else
static char msgbuf[BUFSZ]; /* for nomovemsg */
#endif
register int tmp; register int tmp;
register int dam = d((int)mattk->damn, (int)mattk->damd); register int dam = d((int)mattk->damn, (int)mattk->damd);
boolean fatal_gulp;
struct obj *otmp; struct obj *otmp;
struct permonst *pd = mdef->data;
/* Not totally the same as for real monsters. Specifically, these /* Not totally the same as for real monsters. Specifically, these
* don't take multiple moves. (It's just too hard, for too little * don't take multiple moves. (It's just too hard, for too little
* result, to program monsters which attack from inside you, which * result, to program monsters which attack from inside you, which
@@ -1785,27 +1793,44 @@ register struct attack *mattk;
* after exactly 1 round of attack otherwise. -KAA * after exactly 1 round of attack otherwise. -KAA
*/ */
if(mdef->data->msize >= MZ_HUGE) return 0; if (pd->msize >= MZ_HUGE) return 0;
if(u.uhunger < 1500 && !u.uswallow) { if(u.uhunger < 1500 && !u.uswallow) {
for (otmp = mdef->minvent; otmp; otmp = otmp->nobj) for (otmp = mdef->minvent; otmp; otmp = otmp->nobj)
(void) snuff_lit(otmp); (void) snuff_lit(otmp);
if(!touch_petrifies(mdef->data) || Stone_resistance) { /* engulfing a cockatrice or digesting a Rider or Medusa */
#ifdef LINT /* static char msgbuf[BUFSZ]; */ fatal_gulp = (touch_petrifies(pd) && !Stone_resistance) ||
char msgbuf[BUFSZ]; (mattk->adtyp == AD_DGST && (is_rider(pd) ||
#else (pd == &mons[PM_MEDUSA]) && !Stone_resistance));
static char msgbuf[BUFSZ];
#endif if ((mattk->adtyp == AD_DGST && !Slow_digestion) || fatal_gulp) {
/* KMH, conduct */
u.uconduct.food++;
if (!vegan(pd))
u.uconduct.unvegan++;
if (!vegetarian(pd))
violated_vegetarian();
}
if (fatal_gulp && !is_rider(pd)) { /* petrification */
char kbuf[BUFSZ];
const char *mname = pd->mname;
if (!type_is_pname(pd)) mname = an(mname);
You("bite into %s.", mon_nam(mdef));
Sprintf(kbuf, "swallowing %s whole", mname);
instapetrify(kbuf);
} else {
start_engulf(mdef); start_engulf(mdef);
switch(mattk->adtyp) { switch(mattk->adtyp) {
case AD_DGST: case AD_DGST:
/* eating a Rider or its corpse is fatal */ /* eating a Rider or its corpse is fatal */
if (is_rider(mdef->data)) { if (is_rider(pd)) {
pline("Unfortunately, digesting any of it is fatal."); pline("Unfortunately, digesting any of it is fatal.");
end_engulf(); end_engulf();
Sprintf(killer.name, "unwisely tried to eat %s", Sprintf(killer.name, "unwisely tried to eat %s",
mdef->data->mname); pd->mname);
killer.format = NO_KILLER_PREFIX; killer.format = NO_KILLER_PREFIX;
done(DIED); done(DIED);
return 0; /* lifesaved */ return 0; /* lifesaved */
@@ -1816,13 +1841,6 @@ register struct attack *mattk;
break; break;
} }
/* KMH, conduct */
u.uconduct.food++;
if (!vegan(mdef->data))
u.uconduct.unvegan++;
if (!vegetarian(mdef->data))
violated_vegetarian();
/* Use up amulet of life saving */ /* Use up amulet of life saving */
if (!!(otmp = mlifesaver(mdef))) m_useup(mdef, otmp); if (!!(otmp = mlifesaver(mdef))) m_useup(mdef, otmp);
@@ -1832,12 +1850,11 @@ register struct attack *mattk;
You("hurriedly regurgitate the sizzling in your %s.", You("hurriedly regurgitate the sizzling in your %s.",
body_part(STOMACH)); body_part(STOMACH));
} else { } else {
tmp = 1 + (mdef->data->cwt >> 8); tmp = 1 + (pd->cwt >> 8);
if (corpse_chance(mdef, &youmonst, TRUE) && if (corpse_chance(mdef, &youmonst, TRUE) &&
!(mvitals[monsndx(mdef->data)].mvflags & !(mvitals[monsndx(pd)].mvflags & G_NOCORPSE)) {
G_NOCORPSE)) {
/* nutrition only if there can be a corpse */ /* nutrition only if there can be a corpse */
u.uhunger += (mdef->data->cnutrit+1) / 2; u.uhunger += (pd->cnutrit + 1) / 2;
} else tmp = 0; } else tmp = 0;
Sprintf(msgbuf, "You totally digest %s.", Sprintf(msgbuf, "You totally digest %s.",
mon_nam(mdef)); mon_nam(mdef));
@@ -1852,9 +1869,9 @@ register struct attack *mattk;
nomul(-tmp); nomul(-tmp);
nomovemsg = msgbuf; nomovemsg = msgbuf;
} else pline("%s", msgbuf); } else pline("%s", msgbuf);
if (mdef->data == &mons[PM_GREEN_SLIME]) { if (pd == &mons[PM_GREEN_SLIME]) {
Sprintf(msgbuf, "%s isn't sitting well with you.", Sprintf(msgbuf, "%s isn't sitting well with you.",
The(mdef->data->mname)); The(pd->mname));
if (!Unchanging) { if (!Unchanging) {
make_slimed(5L, (char*) 0); make_slimed(5L, (char*) 0);
} }
@@ -1867,8 +1884,7 @@ register struct attack *mattk;
if (youmonst.data == &mons[PM_FOG_CLOUD]) { if (youmonst.data == &mons[PM_FOG_CLOUD]) {
pline("%s is laden with your moisture.", pline("%s is laden with your moisture.",
Monnam(mdef)); Monnam(mdef));
if (amphibious(mdef->data) && if (amphibious(pd) && !flaming(pd)) {
!flaming(mdef->data)) {
dam = 0; dam = 0;
pline("%s seems unharmed.", Monnam(mdef)); pline("%s seems unharmed.", Monnam(mdef));
} }
@@ -1937,12 +1953,6 @@ register struct attack *mattk;
pline("Obviously, you didn't like %s taste.", pline("Obviously, you didn't like %s taste.",
s_suffix(mon_nam(mdef))); s_suffix(mon_nam(mdef)));
} }
} else {
char kbuf[BUFSZ];
You("bite into %s.", mon_nam(mdef));
Sprintf(kbuf, "swallowing %s whole", an(mdef->data->mname));
instapetrify(kbuf);
} }
} }
return(0); return(0);