fix github issue #148 - life-save while swallowed

Life-saving was setting u.uswldtim to 0, presumably intending that
to stop the hero from being digested, but it actually resulted in
being totally digested on the swallower's next turn if the death
being short-circuited wasn't digestion.  Change life-saving to make
swallower or grabber release the hero instead of tinkering with
u.uswldtim.  In addition to rescuing the hero from digestion, it
prevents an eel which has just drowned the hero (who has survived
drowning via life-saving) from pulling him/her back into the water
on its next turn.  It will need to make another successful grab to
do that now.

While testing, I noticed that if I was polymorphed and wearing an
amulet of unchanging, life-saving didn't restore my HP-as-a-monster
and due to the recent change to force that to 0 when the hero dies,
I died again immediately after my life was saved.  So this bug was
latent in the past and became noticeable in the last couple of days.
This commit is contained in:
PatR
2018-10-28 16:03:42 -07:00
parent 747ebf0ead
commit 858e9ce00d
3 changed files with 37 additions and 11 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 end.c $NHDT-Date: 1539804880 2018/10/17 19:34:40 $ $NHDT-Branch: keni-makedefsm $:$NHDT-Revision: 1.146 $ */
/* NetHack 3.6 end.c $NHDT-Date: 1540767809 2018/10/28 23:03:29 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.148 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -851,7 +851,8 @@ int how;
if (u.uhpmax < uhpmin)
u.uhpmax = uhpmin;
u.uhp = u.uhpmax;
u.uswldtim = 0;
if (Upolyd) /* Unchanging, or death which bypasses losing hit points */
u.mh = u.mhmax;
if (u.uhunger < 500) {
u.uhunger = 500;
newuhs(FALSE);
@@ -877,6 +878,16 @@ int how;
curs_on_u();
if (!context.mon_moving)
endmultishot(FALSE);
if (u.uswallow) {
/* might drop hero onto a trap that kills her all over again */
expels(u.ustuck, u.ustuck->data, TRUE);
} else if (u.ustuck) {
if (Upolyd && sticks(youmonst.data))
You("release %s.", mon_nam(u.ustuck));
else
pline("%s releases you.", Monnam(u.ustuck));
unstuck(u.ustuck);
}
}
/*
@@ -1006,13 +1017,16 @@ void
done(how)
int how;
{
boolean survive = FALSE;
if (how == TRICKED) {
if (killer.name[0]) {
paniclog("trickery", killer.name);
killer.name[0] = 0;
killer.name[0] = '\0';
}
if (wizard) {
You("are a very tricky wizard, it seems.");
killer.format = KILLED_BY_AN; /* reset to 0 */
return;
}
}
@@ -1064,20 +1078,24 @@ int how;
if (how == GENOCIDED) {
pline("Unfortunately you are still genocided...");
} else {
killer.name[0] = 0;
killer.format = 0;
return;
survive = TRUE;
}
}
if ((wizard || discover) && (how <= GENOCIDED)
/* explore and wizard modes offer player the option to keep playing */
if (!survive && (wizard || discover) && how <= GENOCIDED
&& !paranoid_query(ParanoidDie, "Die?")) {
pline("OK, so you don't %s.", (how == CHOKING) ? "choke" : "die");
savelife(how);
killer.name[0] = 0;
killer.format = 0;
survive = TRUE;
}
if (survive) {
killer.name[0] = '\0';
killer.format = KILLED_BY_AN; /* reset to 0 */
return;
}
really_done(how);
/*NOTREACHED*/
}
/* separated from done() in order to specify the __noreturn__ attribute */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mhitu.c $NHDT-Date: 1513297347 2017/12/15 00:22:27 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.149 $ */
/* NetHack 3.6 mhitu.c $NHDT-Date: 1540767817 2018/10/28 23:03:37 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.159 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1956,11 +1956,17 @@ struct attack *mattk;
if (tmp)
stop_occupation();
if (touch_petrifies(youmonst.data) && !resists_ston(mtmp)) {
if (!u.uswallow) {
; /* life-saving has already expelled swallowed hero */
} else if (touch_petrifies(youmonst.data) && !resists_ston(mtmp)) {
pline("%s very hurriedly %s you!", Monnam(mtmp),
is_animal(mtmp->data) ? "regurgitates" : "expels");
expels(mtmp, mtmp->data, FALSE);
} else if (!u.uswldtim || youmonst.data->msize >= MZ_HUGE) {
/* 3.6.2: u.uswldtim used to be set to 0 by life-saving but it
expels now so the !u.uswldtim case is no longer possible;
however, polymorphing into a huge form while already
swallowed is still possible */
You("get %s!", is_animal(mtmp->data) ? "regurgitated" : "expelled");
if (flags.verbose
&& (is_animal(mtmp->data)