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.
This commit is contained in:
PatR
2019-10-18 15:00:16 -07:00
parent 30101a80f1
commit f114675739
5 changed files with 47 additions and 22 deletions

View File

@@ -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 <box> containing 1 item.
<Shk> offers you <gold> for your items in your <box>. 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

View File

@@ -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 *));

View File

@@ -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;
}

View File

@@ -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));

View File

@@ -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 <empty bag>. Sell it?"
"... your <bag> and its contents. Sell them?"
"... your <bag> and item inside. Sell them?"
"... your <bag> and items inside. Sell them?"
Your container but shk only cares about the contents:
"... your item in your <bag>. Sell it?"
"... your items in your <bag>. Sell them?"
Shk's container:
"... your item in the <bag>. Sell it?"
"... your items in the <bag>. 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