diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 22532246b..52aa675e4 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.83 $ $NHDT-Date: 1562114348 2019/07/03 00:39:08 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.84 $ $NHDT-Date: 1562203850 2019/07/04 01:30:50 $ This fixes36.3 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.2 in May 2019. Please note, however, @@ -94,6 +94,10 @@ saving bones with 'perm_invent' On could result in "Bad fruit #N" warnings update persistent inventory window immediately if 'sortpack' option is toggled grammar bit for wizard mode final disclosure; attribute section could show "You had N experience points, 1 more were needed to attain level X+1." +if an engulfer has any worn items, hero could pick them up from inside and + they wouldn't be unworn properly, eventually triggering warnings or + worse (Juiblex will wear an amulet if created with one; a shapechanger + might wear one and then turn into an engulfer) Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/src/invent.c b/src/invent.c index 03dea621e..c9d5019f0 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 invent.c $NHDT-Date: 1561751391 2019/06/28 19:49:51 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.260 $ */ +/* NetHack 3.6 invent.c $NHDT-Date: 1562203850 2019/07/04 01:30:50 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.261 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3360,6 +3360,21 @@ boolean picked_some; if (u.uswallow && u.ustuck) { struct monst *mtmp = u.ustuck; + /* + * FIXME? + * Engulfer's inventory can include worn items (specific case is + * Juiblex being created with an amulet as random defensive item) + * which will be flagged as "(being worn)". This code includes + * such a worn item under the header "Contents of 's stomach", + * a nifty trick for how/where to wear stuff. The situation is + * rare enough to turn a blind eye. + * + * 3.6.3: Pickup has been changed to decline to pick up a worn + * item from inside an engulfer, but if player tries, it just + * says "you can't" without giving a reason why (which would be + * something along the lines of "because it's worn on the outside + * so is unreachable from in here..."). + */ Sprintf(fbuf, "Contents of %s %s", s_suffix(mon_nam(mtmp)), mbodypart(mtmp, STOMACH)); /* Skip "Contents of " by using fbuf index 12 */ diff --git a/src/pickup.c b/src/pickup.c index 123fb7065..1af0c51e8 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pickup.c $NHDT-Date: 1559675617 2019/06/04 19:13:37 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.228 $ */ +/* NetHack 3.6 pickup.c $NHDT-Date: 1562203851 2019/07/04 01:30:51 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.229 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -828,7 +828,8 @@ boolean FDECL((*allow), (OBJ_P)); /* allow function */ anything any; boolean printed_type_name, first, sorted = (qflags & INVORDER_SORT) != 0, - engulfer = (qflags & INCLUDE_HERO) != 0; + engulfer = (qflags & INCLUDE_HERO) != 0, + engulfer_minvent; unsigned sortflags; Loot *sortedolist, *srtoli; @@ -842,6 +843,13 @@ boolean FDECL((*allow), (OBJ_P)); /* allow function */ last = curr; n++; } + /* can't depend upon 'engulfer' because that's used to indicate whether + hero should be shown as an extra, fake item */ + engulfer_minvent = (olist && olist->where == OBJ_MINVENT + && u.uswallow && olist->ocarry == u.ustuck); + if (engulfer_minvent && n == 1 && olist->owornmask != 0L) { + qflags &= ~AUTOSELECT_SINGLE; + } if (engulfer) { ++n; /* don't autoselect swallowed hero if it's the only choice */ @@ -945,10 +953,20 @@ boolean FDECL((*allow), (OBJ_P)); /* allow function */ /* fix up counts: -1 means no count used => pick all; if fake_hero_object was picked, discard that choice */ for (i = k = 0, mi = *pick_list; i < n; i++, mi++) { - if (mi->item.a_obj == &fake_hero_object) + curr = mi->item.a_obj; + if (curr == &fake_hero_object) { + /* this isn't actually possible; fake item representing + hero is only included for look here (':'), not pickup, + and that's PICK_NONE so we can't get here from there */ + You_cant("pick yourself up!"); continue; - if (mi->count == -1L || mi->count > mi->item.a_obj->quan) - mi->count = mi->item.a_obj->quan; + } + if (engulfer_minvent && curr->owornmask != 0L) { + You_cant("pick %s up.", ysimple_name(curr)); + continue; + } + if (mi->count == -1L || mi->count > curr->quan) + mi->count = curr->quan; if (k < i) (*pick_list)[k] = *mi; ++k; @@ -959,10 +977,14 @@ boolean FDECL((*allow), (OBJ_P)); /* allow function */ *pick_list = 0; n = 0; } else if (k < n) { - /* other stuff plus fake_hero; last slot is now unused */ - (*pick_list)[k].item = cg.zeroany; - (*pick_list)[k].count = 0L; - n = k; + /* other stuff plus fake_hero; last slot is now unused + (could be more than one if player tried to pick items + worn by engulfer) */ + while (n > k) { + --n; + (*pick_list)[n].item = cg.zeroany; + (*pick_list)[n].count = 0L; + } } } else if (n < 0) { /* -1 is used for SIGNAL_NOMENU, so callers don't expect it @@ -1462,6 +1484,10 @@ boolean telekinesis; /* not picking it up directly by hand */ if (obj == uchain) { /* do not pick up attached chain */ return 0; + } else if (obj->where == OBJ_MINVENT && obj->owornmask != 0L + && u.uswallow && obj->ocarry == u.ustuck) { + You_cant("pick %s up.", ysimple_name(obj)); + return 0; } else if (obj->oartifact && !touch_artifact(obj, &g.youmonst)) { return 0; } else if (obj->otyp == CORPSE) {