diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 4c3bd945e..5ea4594cc 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.121 $ $NHDT-Date: 1570142734 2019/10/03 22:45:34 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.124 $ $NHDT-Date: 1570232224 2019/10/04 23:37:04 $ 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, @@ -163,6 +163,16 @@ query_category() and whatdoes_help() had early returns which could each leave the query one couldn't happen unless there is a coding error for object classes somewhere and the help one couldn't happen unless the installed data files left 'keyhelp' missing] +ball and chain could end up too far from punished hero (triggering b&c warning + for wizard mode with sanity checking active) when crawling out of + water failed because dropping stuff left hero overly encumbered and + hero was life saved--or player declined to die--if the hero got + teleported one step further from ball and chain's current location +avoid 'object lost' panic when polymorph causes loss of levitation boots or + water walking boots which dumps hero into water where emergency + disrobing/dropping in order to crawl out chooses to drop those boots +'sortloot's attempt to group musical instruments separately from other tools + didn't work as intended due to missing 'break' in sortloot_classify() Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository @@ -170,7 +180,7 @@ Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository elemental_clog() loop needed to guard against obliteration of the monster that was trying to be placed using ^G to create "hidden mimic" shouldn't have marked it as undetected since - mimics 'hide' be appearing to be something else; honor "hidden" for + mimics 'hide' by appearing to be something else; honor "hidden" for 'hides_under' creatures if/when created at location with object(s), also for eels and other fish if/when created at water location for wizard mode 'wizweight' option, glob weight wasn't shown unless glob had diff --git a/src/invent.c b/src/invent.c index 13132536e..e66929a49 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 invent.c $NHDT-Date: 1567213892 2019/08/31 01:11:32 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.262 $ */ +/* NetHack 3.6 invent.c $NHDT-Date: 1570232224 2019/10/04 23:37:04 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.263 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -139,8 +139,10 @@ struct obj *obj; case DRUM_OF_EARTHQUAKE: case HORN_OF_PLENTY: /* not a musical instrument */ k = 3; /* instrument or unknown horn of plenty */ + break; default: k = 4; /* 'other' tool */ + break; } break; case FOOD_CLASS: diff --git a/src/polyself.c b/src/polyself.c index 8517307d8..9b8869892 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 polyself.c $NHDT-Date: 1559664952 2019/06/04 16:15:52 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.133 $ */ +/* NetHack 3.6 polyself.c $NHDT-Date: 1570230710 2019/10/04 23:11:50 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.134 $ */ /* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ @@ -23,6 +23,7 @@ static void FDECL(check_strangling, (BOOLEAN_P)); static void FDECL(polyman, (const char *, const char *)); +static void FDECL(dropp, (struct obj *)); static void NDECL(break_armor); static void FDECL(drop_weapon, (int)); static int FDECL(armor_to_dragon, (int)); @@ -876,6 +877,33 @@ int mntmp; return 1; } +/* dropx() jacket for break_armor() */ +static void +dropp(obj) +struct obj *obj; +{ + struct obj *otmp; + + /* + * Dropping worn armor while polymorphing might put hero into water + * (loss of levitation boots or water walking boots that the new + * form can't wear), where emergency_disrobe() could remove it from + * inventory. Without this, dropx() could trigger an 'object lost' + * panic. Right now, boots are the only armor which might encounter + * this situation, but handle it for all armor. + * + * Hypothetically, 'obj' could have merged with something (not + * applicable for armor) and no longer be a valid pointer, so scan + * inventory for it instead of trusting obj->where. + */ + for (otmp = g.invent; otmp; otmp = otmp->nobj) { + if (otmp == obj) { + dropx(obj); + break; + } + } +} + static void break_armor() { @@ -894,7 +922,7 @@ break_armor() if (otmp->oartifact) { Your("%s falls off!", cloak_simple_name(otmp)); (void) Cloak_off(); - dropx(otmp); + dropp(otmp); } else { Your("%s tears apart!", cloak_simple_name(otmp)); (void) Cloak_off(); @@ -911,7 +939,7 @@ break_armor() cancel_don(); Your("armor falls around you!"); (void) Armor_gone(); - dropx(otmp); + dropp(otmp); } if ((otmp = uarmc) != 0) { if (is_whirly(g.youmonst.data)) @@ -919,7 +947,7 @@ break_armor() else You("shrink out of your %s!", cloak_simple_name(otmp)); (void) Cloak_off(); - dropx(otmp); + dropp(otmp); } if ((otmp = uarmu) != 0) { if (is_whirly(g.youmonst.data)) @@ -927,7 +955,7 @@ break_armor() else You("become much too small for your shirt!"); setworn((struct obj *) 0, otmp->owornmask & W_ARMU); - dropx(otmp); + dropp(otmp); } } if (has_horns(g.youmonst.data)) { @@ -945,7 +973,7 @@ break_armor() Your("%s falls to the %s!", helm_simple_name(otmp), surface(u.ux, u.uy)); (void) Helmet_off(); - dropx(otmp); + dropp(otmp); } } } @@ -957,12 +985,12 @@ break_armor() You("drop your gloves%s!", uwep ? " and weapon" : ""); drop_weapon(0); (void) Gloves_off(); - dropx(otmp); + dropp(otmp); } if ((otmp = uarms) != 0) { You("can no longer hold your shield!"); (void) Shield_off(); - dropx(otmp); + dropp(otmp); } if ((otmp = uarmh) != 0) { if (donning(otmp)) @@ -970,7 +998,7 @@ break_armor() Your("%s falls to the %s!", helm_simple_name(otmp), surface(u.ux, u.uy)); (void) Helmet_off(); - dropx(otmp); + dropp(otmp); } } if (nohands(g.youmonst.data) || verysmall(g.youmonst.data) @@ -984,7 +1012,7 @@ break_armor() Your("boots %s off your feet!", verysmall(g.youmonst.data) ? "slide" : "are pushed"); (void) Boots_off(); - dropx(otmp); + dropp(otmp); } } } @@ -1037,6 +1065,10 @@ int alone; updateinv = FALSE; else if (candropwep) dropx(otmp); + /* [note: dropp vs dropx -- if heart of ahriman is wielded, we + might be losing levitation by dropping it; but that won't + happen until the drop, unlike Boots_off() dumping hero into + water and triggering emergency_disrobe() before dropx()] */ if (updateinv) update_inventory(); diff --git a/src/potion.c b/src/potion.c index c2a6c88df..b114ec82b 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 potion.c $NHDT-Date: 1560850774 2019/06/18 09:39:34 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.162 $ */ +/* NetHack 3.6 potion.c $NHDT-Date: 1570235292 2019/10/05 00:28:12 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.163 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1766,41 +1766,33 @@ static short mixtype(o1, o2) register struct obj *o1, *o2; { + int o1typ = o1->otyp, o2typ = o2->otyp; + /* cut down on the number of cases below */ if (o1->oclass == POTION_CLASS - && (o2->otyp == POT_GAIN_LEVEL || o2->otyp == POT_GAIN_ENERGY - || o2->otyp == POT_HEALING || o2->otyp == POT_EXTRA_HEALING - || o2->otyp == POT_FULL_HEALING || o2->otyp == POT_ENLIGHTENMENT - || o2->otyp == POT_FRUIT_JUICE)) { - struct obj *swp; - - swp = o1; - o1 = o2; - o2 = swp; + && (o2typ == POT_GAIN_LEVEL || o2typ == POT_GAIN_ENERGY + || o2typ == POT_HEALING || o2typ == POT_EXTRA_HEALING + || o2typ == POT_FULL_HEALING || o2typ == POT_ENLIGHTENMENT + || o2typ == POT_FRUIT_JUICE)) { + /* swap o1 and o2 */ + o1typ = o2->otyp; + o2typ = o1->otyp; } - switch (o1->otyp) { + switch (o1typ) { case POT_HEALING: - switch (o2->otyp) { - case POT_SPEED: - case POT_GAIN_LEVEL: - case POT_GAIN_ENERGY: + if (o2typ == POT_SPEED) return POT_EXTRA_HEALING; - } + /*FALLTHRU*/ case POT_EXTRA_HEALING: - switch (o2->otyp) { - case POT_GAIN_LEVEL: - case POT_GAIN_ENERGY: - return POT_FULL_HEALING; - } case POT_FULL_HEALING: - switch (o2->otyp) { - case POT_GAIN_LEVEL: - case POT_GAIN_ENERGY: - return POT_GAIN_ABILITY; - } + if (o2typ == POT_GAIN_LEVEL || o2typ == POT_GAIN_ENERGY) + return (o1typ == POT_HEALING) ? POT_EXTRA_HEALING + : (o1typ == POT_EXTRA_HEALING) ? POT_FULL_HEALING + : POT_GAIN_ABILITY; + /*FALLTHRU*/ case UNICORN_HORN: - switch (o2->otyp) { + switch (o2typ) { case POT_SICKNESS: return POT_FRUIT_JUICE; case POT_HALLUCINATION: @@ -1810,12 +1802,12 @@ register struct obj *o1, *o2; } break; case AMETHYST: /* "a-methyst" == "not intoxicated" */ - if (o2->otyp == POT_BOOZE) + if (o2typ == POT_BOOZE) return POT_FRUIT_JUICE; break; case POT_GAIN_LEVEL: case POT_GAIN_ENERGY: - switch (o2->otyp) { + switch (o2typ) { case POT_CONFUSION: return (rn2(3) ? POT_BOOZE : POT_ENLIGHTENMENT); case POT_HEALING: @@ -1831,7 +1823,7 @@ register struct obj *o1, *o2; } break; case POT_FRUIT_JUICE: - switch (o2->otyp) { + switch (o2typ) { case POT_SICKNESS: return POT_SICKNESS; case POT_ENLIGHTENMENT: @@ -1843,7 +1835,7 @@ register struct obj *o1, *o2; } break; case POT_ENLIGHTENMENT: - switch (o2->otyp) { + switch (o2typ) { case POT_LEVITATION: if (rn2(3)) return POT_GAIN_LEVEL; diff --git a/src/shk.c b/src/shk.c index 33e84fb64..bc7f23cea 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 shk.c $NHDT-Date: 1558124088 2019/05/17 20:14:48 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.163 $ */ +/* NetHack 3.6 shk.c $NHDT-Date: 1570236762 2019/10/05 00:52:42 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.168 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2029,11 +2029,11 @@ struct obj *obj; if (obj->globby) { /* globs must be sold by weight not by volume */ - int unit_weight = (int) objects[obj->otyp].oc_weight, - wt = (obj->owt > 0) ? obj->owt : weight(obj); + long unit_weight = (long) objects[obj->otyp].oc_weight, + wt = (obj->owt > 0) ? (long) obj->owt : (long) weight(obj); if (unit_weight) - units = wt / unit_weight; + units = (wt + unit_weight - 1L) / unit_weight; } return units; } diff --git a/src/teleport.c b/src/teleport.c index febb6221b..0c8847149 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 teleport.c $NHDT-Date: 1564771880 2019/08/02 18:51:20 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.92 $ */ +/* NetHack 3.6 teleport.c $NHDT-Date: 1570227405 2019/10/04 22:16:45 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.93 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -302,9 +302,9 @@ boolean allow_drag; * rock in the way), in which case it teleports the ball on its own. */ if (ball_active) { - if (!carried(uball) && distmin(nux, nuy, uball->ox, uball->oy) <= 2) + if (!carried(uball) && distmin(nux, nuy, uball->ox, uball->oy) <= 2) { ball_still_in_range = TRUE; /* don't have to move the ball */ - else { + } else { /* have to move the ball */ if (!allow_drag || distmin(u.ux, u.uy, nux, nuy) > 1) { /* we should not have dist > 1 and allow_drag at the same @@ -341,8 +341,13 @@ boolean allow_drag; boolean cause_delay; if (drag_ball(nux, nuy, &bc_control, &ballx, &bally, &chainx, - &chainy, &cause_delay, allow_drag)) + &chainy, &cause_delay, allow_drag)) { move_bc(0, bc_control, ballx, bally, chainx, chainy); + } else { + /* dragging fails if hero is encumbered beyond 'burdened' */ + allow_drag = FALSE; /* teleport b&c to hero's new spot */ + unplacebc(); /* to match placebc() below */ + } } } /* must set u.ux, u.uy after drag_ball(), which may need to know