diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 9867cd7d6..3ca48f1af 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.227 $ $NHDT-Date: 1590879610 2020/05/30 23:00:10 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.228 $ $NHDT-Date: 1591017415 2020/06/01 13:16:55 $ General Fixes and Modified Features ----------------------------------- @@ -190,6 +190,8 @@ when hold_another_object fails while hero is swallowed, drop the item into change mkclass() to usually honor (always honor for L class) the hell-only and never-in-hell monster creation flags; no more achi-lich in the Castle (nor master lich there unless demilich gets a potion of gain level) +thieving monster could be killed while hero was removing armor, triggering + warning "stealarm(): dead monster stealing" when taking-off finished Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/decl.h b/include/decl.h index 150122c76..c131b3735 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 decl.h $NHDT-Date: 1589326665 2020/05/12 23:37:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.236 $ */ +/* NetHack 3.6 decl.h $NHDT-Date: 1591017415 2020/06/01 13:16:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.237 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1142,6 +1142,10 @@ struct instance_globals { int spl_sortmode; /* index into spl_sortchoices[] */ int *spl_orderindx; /* array of g.spl_book[] indices */ + /* steal.c */ + unsigned int stealoid; /* object to be stolen */ + unsigned int stealmid; /* monster doing the stealing */ + /* teleport.c */ struct obj *telescroll; /* non-null when teleporting via this scroll */ diff --git a/include/extern.h b/include/extern.h index 22f7a44a4..3a7cdcf52 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1590904081 2020/05/31 05:48:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.847 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1591017416 2020/06/01 13:16:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.848 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2536,9 +2536,11 @@ E void FDECL(initialspell, (struct obj *)); #ifdef USE_TRAMPOLI E int NDECL(stealarm); +E void NDECL(unstolenarm); #endif E long FDECL(somegold, (long)); E void FDECL(stealgold, (struct monst *)); +E void NDECL(thiefdead); E void FDECL(remove_worn_item, (struct obj *, BOOLEAN_P)); E int FDECL(steal, (struct monst *, char *)); E int FDECL(mpickobj, (struct monst *, struct obj *)); diff --git a/src/decl.c b/src/decl.c index 70e5ac1f0..3264d7282 100644 --- a/src/decl.c +++ b/src/decl.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 decl.c $NHDT-Date: 1589326673 2020/05/12 23:37:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.212 $ */ +/* NetHack 3.6 decl.c $NHDT-Date: 1591017417 2020/06/01 13:16:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.213 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -647,6 +647,10 @@ const struct instance_globals g_init = { 0, /* spl_sortmode */ NULL, /* spl_orderindx */ + /* steal.c */ + 0, /* stealoid */ + 0, /* stealmid */ + /* teleport.c */ NULL, /* telescroll */ diff --git a/src/mon.c b/src/mon.c index 8e7e5ddce..f9b5fd6d4 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mon.c $NHDT-Date: 1586091449 2020/04/05 12:57:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.333 $ */ +/* NetHack 3.6 mon.c $NHDT-Date: 1591017419 2020/06/01 13:16:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.337 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1977,6 +1977,8 @@ struct permonst *mptr; /* reflects mtmp->data _prior_ to mtmp's death */ /* to prevent an infinite relobj-flooreffects-hmon-killed loop */ mtmp->mtrapped = 0; mtmp->mhp = 0; /* simplify some tests: force mhp to 0 */ + if (mtmp->m_id == g.stealmid) + thiefdead(); relobj(mtmp, 0, FALSE); if (onmap || mtmp == g.level.monsters[0][0]) { if (mtmp->wormno) diff --git a/src/steal.c b/src/steal.c index e170cc50d..36f2a5a90 100644 --- a/src/steal.c +++ b/src/steal.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 steal.c $NHDT-Date: 1570566382 2019/10/08 20:26:22 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.75 $ */ +/* NetHack 3.6 steal.c $NHDT-Date: 1591017420 2020/06/01 13:17:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.82 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -6,26 +6,20 @@ #include "hack.h" static int NDECL(stealarm); - +static int NDECL(unstolenarm); static const char *FDECL(equipname, (struct obj *)); static const char * equipname(otmp) register struct obj *otmp; { - return ((otmp == uarmu) - ? "shirt" - : (otmp == uarmf) - ? "boots" - : (otmp == uarms) - ? "shield" - : (otmp == uarmg) - ? "gloves" - : (otmp == uarmc) - ? cloak_simple_name(otmp) - : (otmp == uarmh) - ? helm_simple_name(otmp) - : suit_simple_name(otmp)); + return ((otmp == uarmu) ? shirt_simple_name(otmp) + : (otmp == uarmf) ? boots_simple_name(otmp) + : (otmp == uarms) ? shield_simple_name(otmp) + : (otmp == uarmg) ? gloves_simple_name(otmp) + : (otmp == uarmc) ? cloak_simple_name(otmp) + : (otmp == uarmh) ? helm_simple_name(otmp) + : suit_simple_name(otmp)); } /* proportional subset of gold; return value actually fits in an int */ @@ -139,9 +133,35 @@ register struct monst *mtmp; } } -/* steal armor after you finish taking it off */ -unsigned int stealoid; /* object to be stolen */ -unsigned int stealmid; /* monster doing the stealing */ +/* monster who was stealing from hero has just died */ +void +thiefdead() +{ + /* hero is busy taking off an item of armor which takes multiple turns */ + g.stealmid = 0; + if (g.afternmv == stealarm) + g.afternmv = unstolenarm; +} + +/* called via (*g.afternmv)() when hero finishes taking off armor that + was slated to be stolen but the thief died in the interim */ +static int +unstolenarm(VOID_ARGS) +{ + struct obj *obj; + + /* find the object before clearing stealoid; it has already become + not-worn and is still in hero's inventory */ + for (obj = g.invent; obj; obj = obj->nobj) + if (obj->o_id == g.stealoid) + break; + g.stealoid = 0; + if (obj) { + g.nomovemsg = (char *) 0; + You("finish taking off your %s.", equipname(obj)); + } + return 0; +} static int stealarm(VOID_ARGS) @@ -149,10 +169,13 @@ stealarm(VOID_ARGS) register struct monst *mtmp; register struct obj *otmp; + if (!g.stealoid || !g.stealmid) + goto botm; + for (otmp = g.invent; otmp; otmp = otmp->nobj) { - if (otmp->o_id == stealoid) { + if (otmp->o_id == g.stealoid) { for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (mtmp->m_id == stealmid) { + if (mtmp->m_id == g.stealmid) { if (DEADMONSTER(mtmp)) impossible("stealarm(): dead monster stealing"); if (!dmgtype(mtmp->data, AD_SITM)) /* polymorphed */ @@ -174,7 +197,7 @@ stealarm(VOID_ARGS) } } botm: - stealoid = 0; + g.stealoid = g.stealmid = 0; /* in case only one has been reset so far */ return 0; } @@ -236,10 +259,10 @@ boolean unchain_ball; /* whether to unpunish or just unwield */ } } -/* Returns 1 when something was stolen (or at least, when N should flee now) - * Returns -1 if the monster died in the attempt - * Avoid stealing the object stealoid - * Nymphs and monkeys won't steal coins +/* Returns 1 when something was stolen (or at least, when N should flee now), + * returns -1 if the monster died in the attempt. + * Avoid stealing the object 'stealoid'. + * Nymphs and monkeys won't steal coins. */ int steal(mtmp, objnambuf) @@ -326,7 +349,7 @@ char *objnambuf; otmp = uarm; gotobj: - if (otmp->o_id == stealoid) + if (otmp->o_id == g.stealoid) return 0; if (otmp->otyp == BOULDER && !throws_rocks(mtmp->data)) { @@ -434,12 +457,8 @@ char *objnambuf; remove_worn_item(otmp, TRUE); otmp->cursed = curssv; if (g.multi < 0) { - /* - multi = 0; - afternmv = 0; - */ - stealoid = otmp->o_id; - stealmid = mtmp->m_id; + g.stealoid = otmp->o_id; + g.stealmid = mtmp->m_id; g.afternmv = stealarm; return 0; } diff --git a/src/uhitm.c b/src/uhitm.c index 74a48641b..0f7f2eba8 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -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