fix github issue #354 - stealarm() impossible

A thieving monster could be killed while the hero was busy taking
off armor which needs multiple turns (normally a suit) and if that
happened on the same turn as the take-off finished, the warning
"stealarm(): dead monster stealing" was issued.  Cited case was
having the thief be killed by a stinking cloud but it could happen
if the death was caused by a pet or by some other monster trying
to attack the hero.  If the thief died sooner, the situation was
silently ignored.  So this could have been fixed by just getting
rid of the impossible() feedback.

'stealmid' and 'stealoid' should have been static in steal.c rather
than global and as such should have been moved into 'struct g'.
This moves them there and then takes advantage of having access to
'stealmid' outside of steal.c.  That's just a minor optimization
since m_detach() could call new thiefdead() unconditionally and the
latter could check whether the dead monster matches 'stealmid'.

Fixes #354
This commit is contained in:
PatR
2020-06-01 06:17:07 -07:00
parent ac364b3e20
commit 503df6823d
7 changed files with 80 additions and 47 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 uhitm.c $NHDT-Date: 1586807928 2020/04/13 19:58:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.230 $ */
/* NetHack 3.6 uhitm.c $NHDT-Date: 1591017421 2020/06/01 13:17:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.236 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1522,7 +1522,7 @@ steal_it(mdef, mattk)
struct monst *mdef;
struct attack *mattk;
{
struct obj *otmp, *gold = 0, *stealoid, **minvent_ptr;
struct obj *otmp, *gold = 0, *ustealo, **minvent_ptr;
long unwornmask;
otmp = mdef->minvent;
@@ -1530,25 +1530,25 @@ struct attack *mattk;
return; /* nothing to take */
/* look for worn body armor */
stealoid = (struct obj *) 0;
ustealo = (struct obj *) 0;
if (could_seduce(&g.youmonst, mdef, mattk)) {
/* find armor, and move it to end of inventory in the process */
minvent_ptr = &mdef->minvent;
while ((otmp = *minvent_ptr) != 0)
if (otmp->owornmask & W_ARM) {
if (stealoid)
if (ustealo)
panic("steal_it: multiple worn suits");
*minvent_ptr = otmp->nobj; /* take armor out of minvent */
stealoid = otmp;
stealoid->nobj = (struct obj *) 0;
ustealo = otmp;
ustealo->nobj = (struct obj *) 0;
} else {
minvent_ptr = &otmp->nobj;
}
*minvent_ptr = stealoid; /* put armor back into minvent */
*minvent_ptr = ustealo; /* put armor back into minvent */
}
gold = findgold(mdef->minvent);
if (stealoid) { /* we will be taking everything */
if (ustealo) { /* we will be taking everything */
char heshe[20];
/* 3.7: this uses hero's base gender rather than nymph feminimity
@@ -1590,7 +1590,7 @@ struct attack *mattk;
move instead of waiting until it picks something up */
mdef->misc_worn_check |= I_SPECIAL;
if (otmp == stealoid) /* special message for final item */
if (otmp == ustealo) /* special message for final item */
pline("%s finishes taking off %s suit.", Monnam(mdef),
mhis(mdef));
}
@@ -1611,7 +1611,7 @@ struct attack *mattk;
break; /* can't continue stealing */
}
if (!stealoid)
if (!ustealo)
break; /* only taking one item */
/* take gold out of minvent before making next selection; if it