Skip to content

Commit

Permalink
fix github issue #148 - life-save while swallowed
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
PatR committed Oct 28, 2018
1 parent 747ebf0 commit 858e9ce
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 11 deletions.
2 changes: 2 additions & 0 deletions doc/fixes36.2
Expand Up @@ -191,6 +191,7 @@ make long extended commands list be more navigable
simplify #wizidentify; don't rely on having bold menu entries
ensure tmp_at() structures are initialized for all code paths when swallowed
trapped-vs-levitation/flying change broke Sting releasing hero from web
life-saving while poly'd and Unchanging wasn't restoring u.mh (HP as monster)
tty: turn off an optimization that is the suspected cause of Windows reported
partial status lines following level changes
tty: ensure that current status fields are always copied to prior status
Expand Down Expand Up @@ -274,6 +275,7 @@ make mine town "orctown" variation a multiple level feature of the mines
replace #monpolycontrol command with monpolycontrol boolean option
replace #wizdebug_traveldisplay command with travel_debug boolean option
rename #wizdebug_bury command to #wizbury
life-saving now makes swallower or grabber release hero


Code Cleanup and Reorganization
Expand Down
36 changes: 27 additions & 9 deletions src/end.c
@@ -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. */
Expand Down Expand Up @@ -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);
Expand All @@ -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);
}
}

/*
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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 */
Expand Down
10 changes: 8 additions & 2 deletions src/mhitu.c
@@ -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. */
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 858e9ce

Please sign in to comment.