shop feedback ("gold piecess") (trunk only)

From a bug report, dropping and selling a container that had some things owned
by the hero and some already owned by the shop, you could get "You sold
some items inside <a container> for N gold piecess."  Shop handing for
containers has been changed significantly since 3.4.3, but the typo
"pieces" that then optionally gets plural "s" appended was still there.

     While testing the trivial fix, I noticed suboptional feedback in the
prompt about selling.  For a container owned by the shop, it said "items"
even when there was just one hero owned item inside.  Fortunately this
potentinal can of worns only seemed to have one tiny weeny worm in it....

     The revised version of count_buc() that I've had laying around for
a while is also included.

     The fixes entry is for "piecess", not escaped/captured/exterminated
worms, and goes into fixes34.4 despite this patch being labeled "trunk
only".  Separate patch for trunk to follow.
This commit is contained in:
nethack.rankin
2011-10-27 02:24:54 +00:00
parent 98cb2eda54
commit 3337f05af8
5 changed files with 63 additions and 41 deletions
+1
View File
@@ -412,6 +412,7 @@ temporary loss of Dex from wounded legs will become permanent if it occurs
character escape sequence handling during options processing was vulernable character escape sequence handling during options processing was vulernable
to malformed escapes and could potentially be abused to clobber the to malformed escapes and could potentially be abused to clobber the
stack and launch a buffer overrun attack stack and launch a buffer overrun attack
fix message typo, "you sold some items inside <container> for N gold piecess"
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes
+1
View File
@@ -952,6 +952,7 @@ E void NDECL(reassign);
E int NDECL(doorganize); E int NDECL(doorganize);
E int FDECL(count_unpaid, (struct obj *)); E int FDECL(count_unpaid, (struct obj *));
E int FDECL(count_buc, (struct obj *,int)); E int FDECL(count_buc, (struct obj *,int));
E long FDECL(count_contents, (struct obj *,BOOLEAN_P,BOOLEAN_P,BOOLEAN_P));
E void FDECL(carry_obj_effects, (struct obj *)); E void FDECL(carry_obj_effects, (struct obj *));
E const char *FDECL(currency, (long)); E const char *FDECL(currency, (long));
E void FDECL(silly_thing, (const char *,struct obj *)); E void FDECL(silly_thing, (const char *,struct obj *));
+34 -25
View File
@@ -2056,6 +2056,9 @@ count_unpaid(list)
/* /*
* Returns the number of items with b/u/c/unknown within the given list. * Returns the number of items with b/u/c/unknown within the given list.
* This does NOT include contained objects. * This does NOT include contained objects.
*
* Assumes that the hero sees or touches or otherwise senses the objects
* at some point: bknown is forced for priest[ess], like in xname().
*/ */
int int
count_buc(list, type) count_buc(list, type)
@@ -2064,31 +2067,37 @@ count_buc(list, type)
{ {
int count = 0; int count = 0;
while (list) { for ( ; list; list = list->nobj) {
if (Role_if(PM_PRIEST)) list->bknown = TRUE; /* coins are "none of the above" as far as BUCX filtering goes */
switch(type) { if (list->oclass == COIN_CLASS) continue;
case BUC_BLESSED: /* priests always know bless/curse state */
if (list->oclass != COIN_CLASS && list->bknown && list->blessed) if (Role_if(PM_PRIEST)) list->bknown = 1;
count++;
break; /* check whether this object matches the requested type */
case BUC_CURSED: if (!list->bknown ? (type == BUC_UNKNOWN) :
if (list->oclass != COIN_CLASS && list->bknown && list->cursed) list->blessed ? (type == BUC_BLESSED) :
count++; list->cursed ? (type == BUC_CURSED) :
break; (type == BUC_UNCURSED))
case BUC_UNCURSED: ++count;
if (list->oclass != COIN_CLASS && }
list->bknown && !list->blessed && !list->cursed) return count;
count++; }
break;
case BUC_UNKNOWN: long
if (list->oclass != COIN_CLASS && !list->bknown) count_contents(container, nested, quantity, everything)
count++; struct obj *container;
break; boolean nested, /* include contents of any nested containers */
default: quantity, /* count all vs count separate stacks */
impossible("need count of curse status %d?", type); everything; /* all objects vs only unpaid objects */
return 0; {
} struct obj *otmp;
list = list->nobj; long count = 0L;
for (otmp = container->cobj; otmp; otmp = otmp->nobj) {
if (nested && Has_contents(otmp))
count += count_contents(otmp, nested, quantity, everything);
if (everything || otmp->unpaid)
count += quantity ? otmp->quan : 1L;
} }
return count; return count;
} }
+7 -6
View File
@@ -736,14 +736,15 @@ register struct obj *obj;
if (obj->greased) Strcat(prefix, "greased "); if (obj->greased) Strcat(prefix, "greased ");
if (cknown && Has_contents(obj)) { if (cknown && Has_contents(obj)) {
struct obj *curr; /* we count all objects (obj->quantity); perhaps we should
long itemcount = 0L; count seperate stacks instead (or even introduce a user
preference option to choose between the two alternatives)
since it's somewhat odd so see "containing 1002 items"
when there are 2 scrolls plus 1000 gold pieces */
long itemcount = count_contents(obj, FALSE, TRUE, TRUE);
/* Count the number of contained objects */
for (curr = obj->cobj; curr; curr = curr->nobj)
itemcount += curr->quan;
Sprintf(eos(bp), " containing %ld item%s", Sprintf(eos(bp), " containing %ld item%s",
itemcount, plur(itemcount)); itemcount, plur(itemcount));
} }
switch(obj->oclass) { switch(obj->oclass) {
+20 -10
View File
@@ -2876,9 +2876,15 @@ xchar x, y;
if (short_funds) offer = shkmoney; if (short_funds) offer = shkmoney;
if (!sell_response) { if (!sell_response) {
only_partially_your_contents = (container && long yourc = 0L, shksc;
contained_cost(obj, shkp, 0L, FALSE, FALSE) !=
contained_cost(obj, shkp, 0L, FALSE, TRUE)); if (container) {
/* number of items owned by shk */
shksc = count_contents(obj, TRUE, TRUE, FALSE);
/* number of items owned by you (total - shksc) */
yourc = count_contents(obj, TRUE, TRUE, TRUE) - shksc;
only_partially_your_contents = shksc && yourc;
}
/* /*
"<shk> offers * for ..." query formatting. "<shk> offers * for ..." query formatting.
Normal item(s): Normal item(s):
@@ -2895,22 +2901,26 @@ xchar x, y;
Your container: Your container:
"... your <empty bag>. Sell it?" "... your <empty bag>. Sell it?"
"... your <bag> and its contents. Sell them?" "... your <bag> and its contents. Sell them?"
"... your <bag> and item inside. Sell them?"
"... your <bag> and items inside. Sell them?" "... your <bag> and items inside. Sell them?"
Shk's container: Shk's container:
(empty case won't happen--nothing to sell) "... your item in the <bag>. Sell it?"
"... the contents of the <bag>. Sell them?"
"... your items in the <bag>. Sell them?" "... your items in the <bag>. Sell them?"
*/ */
Sprintf(qbuf, "%s offers%s %ld gold piece%s for %s%s ", Sprintf(qbuf, "%s offers%s %ld gold piece%s for %s%s ",
shkname(shkp), short_funds ? " only" : "", shkname(shkp), short_funds ? " only" : "",
offer, plur(offer), offer, plur(offer),
(cltmp && !ltmp) ? (only_partially_your_contents ? (cltmp && !ltmp) ?
"your items in " : the_contents_of) : "", ((yourc == 1L) ? "your item in " :
"your items in ") : "",
obj->unpaid ? "the" : "your"); obj->unpaid ? "the" : "your");
one = (obj->quan == 1L && !cltmp); one = obj->unpaid ? (yourc == 1L) :
(obj->quan == 1L && !cltmp);
Sprintf(qsfx, "%s. Sell %s?", Sprintf(qsfx, "%s. Sell %s?",
(cltmp && ltmp) ? (only_partially_your_contents ? (cltmp && ltmp) ? (only_partially_your_contents ?
" and items inside" : and_its_contents) : "", ((yourc == 1L) ? " and item inside" :
" and items inside") :
and_its_contents) : "",
one ? "it" : "them"); one ? "it" : "them");
(void)safe_qbuf(qbuf, qbuf, qsfx, (void)safe_qbuf(qbuf, qbuf, qsfx,
obj, xname, simpleonames, obj, xname, simpleonames,
@@ -2932,7 +2942,7 @@ xchar x, y;
pay(-offer, shkp); pay(-offer, shkp);
shk_names_obj(shkp, obj, (sell_how != SELL_NORMAL) ? shk_names_obj(shkp, obj, (sell_how != SELL_NORMAL) ?
(!ltmp && cltmp && only_partially_your_contents) ? (!ltmp && cltmp && only_partially_your_contents) ?
"sold some items inside %s for %ld gold pieces%s.%s" : "sold some items inside %s for %ld gold piece%s.%s" :
"sold %s for %ld gold piece%s.%s" : "sold %s for %ld gold piece%s.%s" :
"relinquish %s and receive %ld gold piece%s in compensation.%s", "relinquish %s and receive %ld gold piece%s in compensation.%s",
offer, ""); offer, "");