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 @@
/* 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