From f1146757393a1401730fe4d6c03a30245efb3c7b Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 18 Oct 2019 15:00:16 -0700 Subject: [PATCH] containers in shops Fix a couple of bugs I stumbled across while testing something else. The sell prompt for a container dropped in a shop had phrasing issues. This fixes a couple but there are more. The message composition assumes that contents fall into two categories: those already owned by the shop and those the shopkeeper is offering to buy from the hero. But there is a third: stuff the shopkeeper doesn't care about so won't buy. The count_contents() routine can supply total contents or shop-owned contents. Subtracting one from the other yields combined hero-owned without any way to separate out shk-cares and don't-care. --- doc/fixes36.3 | 11 ++++++++++- include/extern.h | 5 +++-- src/invent.c | 22 ++++++++++++---------- src/objnam.c | 4 ++-- src/shk.c | 27 ++++++++++++++++++++------- 5 files changed, 47 insertions(+), 22 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 756d69da9..b3c2dcead 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.141 $ $NHDT-Date: 1571363147 2019/10/18 01:45:47 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.142 $ $NHDT-Date: 1571435999 2019/10/18 21:59:59 $ 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, @@ -191,6 +191,15 @@ yellow dragons had green breath partly eaten food in a bones level shop would show a non-zero sale price while on the floor but not be placed on shop bill if picked up; sale price should have been "no charge" +when non-empty container is dropped in shop and hero is asked whether to sell, + counting the subset of contents owned by hero vs those owned by shk + could obtain wrong answer because the container had been placed on + the floor but the 'unpaid' and 'no_charge' flags of its contents + hadn't been updated yet, they were still set for when it was carried +in a shop which doesn't care about tools: You drop a containing 1 item. + offers you for your items in your . Sell them? + [plural 'items' and 'them' were including the box along with the one + item in it even though shk was only offering to buy its contents] Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index d4e255744..e2fd85dca 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1567213888 2019/08/31 01:11:28 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.728 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1571436000 2019/10/18 22:00:00 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.730 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1047,7 +1047,8 @@ E int FDECL(count_unpaid, (struct obj *)); E int FDECL(count_buc, (struct obj *, int, boolean (*)(OBJ_P))); E void FDECL(tally_BUCX, (struct obj *, BOOLEAN_P, int *, int *, int *, int *, int *)); -E long FDECL(count_contents, (struct obj *, BOOLEAN_P, BOOLEAN_P, BOOLEAN_P)); +E long FDECL(count_contents, (struct obj *, + BOOLEAN_P, BOOLEAN_P, BOOLEAN_P, BOOLEAN_P)); E void FDECL(carry_obj_effects, (struct obj *)); E const char *FDECL(currency, (long)); E void FDECL(silly_thing, (const char *, struct obj *)); diff --git a/src/invent.c b/src/invent.c index be2a24497..0e11e52f4 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 invent.c $NHDT-Date: 1570566378 2019/10/08 20:26:18 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.264 $ */ +/* NetHack 3.6 invent.c $NHDT-Date: 1571436003 2019/10/18 22:00:03 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.265 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2961,30 +2961,32 @@ int *bcp, *ucp, *ccp, *xcp, *ocp; /* count everything inside a container, or just shop-owned items inside */ long -count_contents(container, nested, quantity, everything) +count_contents(container, nested, quantity, everything, newdrop) struct obj *container; boolean nested, /* include contents of any nested containers */ quantity, /* count all vs count separate stacks */ - everything; /* all objects vs only unpaid objects */ + everything, /* all objects vs only unpaid objects */ + newdrop; /* on floor, but hero-owned items haven't been marked + * no_charge yet and shop-owned items are still marked + * unpaid -- used when asking the player whether to sell */ { struct obj *otmp, *topc; boolean shoppy = FALSE; long count = 0L; - if (!everything) { + if (!everything && !newdrop) { + xchar x, y; + for (topc = container; topc->where == OBJ_CONTAINED; topc = topc->ocontainer) continue; - if (topc->where == OBJ_FLOOR) { - xchar x, y; - - (void) get_obj_location(topc, &x, &y, CONTAINED_TOO); + if (topc->where == OBJ_FLOOR && get_obj_location(topc, &x, &y, 0)) shoppy = costly_spot(x, y); - } } for (otmp = container->cobj; otmp; otmp = otmp->nobj) { if (nested && Has_contents(otmp)) - count += count_contents(otmp, nested, quantity, everything); + count += count_contents(otmp, nested, quantity, everything, + newdrop); if (everything || otmp->unpaid || (shoppy && !otmp->no_charge)) count += quantity ? otmp->quan : 1L; } diff --git a/src/objnam.c b/src/objnam.c index 59b6397cd..5903e3b9b 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 objnam.c $NHDT-Date: 1562186589 2019/07/03 20:43:09 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.245 $ */ +/* NetHack 3.6 objnam.c $NHDT-Date: 1571436005 2019/10/18 22:00:05 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.247 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1047,7 +1047,7 @@ unsigned doname_flags; /* we count the number of separate stacks, which corresponds to the number of inventory slots needed to be able to take everything out if no merges occur */ - long itemcount = count_contents(obj, FALSE, FALSE, TRUE); + long itemcount = count_contents(obj, FALSE, FALSE, TRUE, FALSE); Sprintf(eos(bp), " containing %ld item%s", itemcount, plur(itemcount)); diff --git a/src/shk.c b/src/shk.c index 0cb7e2ab1..f111b3dcc 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 shk.c $NHDT-Date: 1571363715 2019/10/18 01:55:15 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.170 $ */ +/* NetHack 3.6 shk.c $NHDT-Date: 1571436007 2019/10/18 22:00:07 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.171 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2904,8 +2904,8 @@ boolean peaceful, silent; /* gather information for message(s) prior to manipulating bill */ was_unpaid = obj->unpaid ? TRUE : FALSE; if (Has_contents(obj)) { - c_count = count_contents(obj, TRUE, FALSE, TRUE); - u_count = count_contents(obj, TRUE, FALSE, FALSE); + c_count = count_contents(obj, TRUE, FALSE, TRUE, FALSE); + u_count = count_contents(obj, TRUE, FALSE, FALSE, FALSE); } if (!billable(&shkp, obj, roomno, FALSE)) { @@ -3209,9 +3209,9 @@ xchar x, y; if (container) { /* number of items owned by shk */ - shksc = count_contents(obj, TRUE, TRUE, FALSE); + shksc = count_contents(obj, TRUE, TRUE, FALSE, TRUE); /* number of items owned by you (total - shksc) */ - yourc = count_contents(obj, TRUE, TRUE, TRUE) - shksc; + yourc = count_contents(obj, TRUE, TRUE, TRUE, TRUE) - shksc; only_partially_your_contents = shksc && yourc; } /* @@ -3227,14 +3227,27 @@ xchar x, y; (The case where it has contents already entirely owned by the shk is treated the same was if it were empty since the hero isn't selling any of those contents.) - Your container: + Your container and shk is willing to buy it: "... your . Sell it?" "... your and its contents. Sell them?" "... your and item inside. Sell them?" "... your and items inside. Sell them?" + Your container but shk only cares about the contents: + "... your item in your . Sell it?" + "... your items in your . Sell them?" Shk's container: "... your item in the . Sell it?" "... your items in the . Sell them?" + FIXME: + "your items" should sometimes be "some of your items" + (when container has some stuff the shk is willing to buy + and other stuff he or she doesn't care about); likewise, + "your item" should sometimes be "one of your items". + That would make the prompting even more verbose so + living without it might be a good thing. + FIXME too: + when container's contents are unknown, plural "items" + should be used to not give away information. */ Sprintf(qbuf, "%s offers%s %ld gold piece%s for %s%s ", Shknam(shkp), short_funds ? " only" : "", offer, @@ -3243,7 +3256,7 @@ xchar x, y; ? ((yourc == 1L) ? "your item in " : "your items in ") : "", obj->unpaid ? "the" : "your"); - one = obj->unpaid ? (yourc == 1L) : (obj->quan == 1L && !cltmp); + one = !ltmp ? (yourc == 1L) : (obj->quan == 1L && !cltmp); Sprintf(qsfx, "%s. Sell %s?", (cltmp && ltmp) ? (only_partially_your_contents