Show menu when paying items

... and have more than 1 billed item, and using non-traditional
menustyle.

I opted to add an extra field to the bill struct, because
that made the code cleaner.

Breaks saves and bones.
This commit is contained in:
Pasi Kallinen
2023-12-09 12:43:41 +02:00
parent 0ef2f15f51
commit 1ceb9d2d91
4 changed files with 73 additions and 7 deletions
+1
View File
@@ -1321,6 +1321,7 @@ change vrock and hezrou from red to green, adjust vrock tile to have green
change wolf and werewolf to grey, warg to black change wolf and werewolf to grey, warg to black
change [master] mind flayer, the Wizard, and the riders to bright magenta change [master] mind flayer, the Wizard, and the riders to bright magenta
walking into a shopkeeper tries to pay the bill walking into a shopkeeper tries to pay the bill
show billed items in a menu when paying with non-traditional menustyle
Fixes to 3.7.0-x General Problems Exposed Via git Repository Fixes to 3.7.0-x General Problems Exposed Via git Repository
+1
View File
@@ -113,6 +113,7 @@ struct epri {
struct bill_x { struct bill_x {
unsigned bo_id; unsigned bo_id;
boolean useup; boolean useup;
boolean queuedpay;
long price; /* price per unit */ long price; /* price per unit */
long bquan; /* amount used up */ long bquan; /* amount used up */
}; };
+1 -1
View File
@@ -17,7 +17,7 @@
* Incrementing EDITLEVEL can be used to force invalidation of old bones * Incrementing EDITLEVEL can be used to force invalidation of old bones
* and save files. * and save files.
*/ */
#define EDITLEVEL 93 #define EDITLEVEL 94
/* /*
* Development status possibilities. * Development status possibilities.
+70 -6
View File
@@ -45,6 +45,7 @@ static long set_cost(struct obj *, struct monst *);
static const char *shk_embellish(struct obj *, long); static const char *shk_embellish(struct obj *, long);
static long cost_per_charge(struct monst *, struct obj *, boolean); static long cost_per_charge(struct monst *, struct obj *, boolean);
static long cheapest_item(struct monst *); static long cheapest_item(struct monst *);
static int menu_pick_pay_items(struct monst *);
static int dopayobj(struct monst *, struct bill_x *, struct obj **, int, static int dopayobj(struct monst *, struct bill_x *, struct obj **, int,
boolean); boolean);
static long stolen_container(struct obj *, struct monst *, long, boolean); static long stolen_container(struct obj *, struct monst *, long, boolean);
@@ -1382,6 +1383,56 @@ cheapest_item(struct monst *shkp)
return gmin; return gmin;
} }
/* show items on your bill in a menu, and ask which to pay.
returns the number of entries selected. */
static int
menu_pick_pay_items(struct monst *shkp)
{
struct eshk *eshkp = ESHK(shkp);
winid win;
anything any;
menu_item *pick_list = (menu_item *) 0;
int i, j, n, clr = NO_COLOR;
char buf[BUFSZ];
any = cg.zeroany;
win = create_nhwindow(NHW_MENU);
start_menu(win, MENU_BEHAVE_STANDARD);
for (n = 0; n < eshkp->billct; n++) {
struct obj *otmp;
register struct bill_x *bp = &(eshkp->bill_p[n]);
bp->queuedpay = FALSE;
/* find the object on one of the lists */
if ((otmp = bp_to_obj(bp)) != 0) {
/* if completely used up, object quantity is stale;
restoring it to its original value here avoids
making the partly-used-up code more complicated */
if (bp->useup)
otmp->quan = bp->bquan;
Sprintf(buf, "%s%s",
bp->useup ? "(used up) " : "",
doname(otmp));
any.a_int = n + 1; /* +1: avoid 0 */
add_menu(win, &nul_glyphinfo, &any, 0, 0, ATR_NONE, clr, buf,
MENU_ITEMFLAGS_NONE);
}
}
end_menu(win, "Pay which items?");
n = select_menu(win, PICK_ANY, &pick_list);
destroy_nhwindow(win);
for (j = 0; j < n; ++j) {
i = pick_list[j].item.a_int - 1; /* -1: reverse +1 above */
eshkp->bill_p[i].queuedpay = TRUE;
}
free(pick_list);
return n;
}
/* the #pay command */ /* the #pay command */
int int
dopay(void) dopay(void)
@@ -1635,6 +1686,7 @@ dopay(void)
/* now check items on bill */ /* now check items on bill */
if (eshkp->billct) { if (eshkp->billct) {
register boolean itemize; register boolean itemize;
boolean queuedpay = FALSE;
int iprompt; int iprompt;
umoney = money_cnt(gi.invent); umoney = money_cnt(gi.invent);
@@ -1651,12 +1703,19 @@ dopay(void)
return ECMD_OK; return ECMD_OK;
} }
/* this isn't quite right; it itemizes without asking if the if (flags.menu_style != MENU_TRADITIONAL && eshkp->billct > 1) {
* single item on the bill is partly used up and partly unpaid */ if (!menu_pick_pay_items(shkp))
iprompt = (eshkp->billct > 1 ? ynq("Itemized billing?") : 'y'); return ECMD_OK;
itemize = (iprompt == 'y'); queuedpay = TRUE;
if (iprompt == 'q') itemize = FALSE;
goto thanks; } else {
/* this isn't quite right; it itemizes without asking if the
* single item on the bill is partly used up and partly unpaid */
iprompt = (eshkp->billct > 1 ? ynq("Itemized billing?") : 'y');
itemize = (iprompt == 'y');
if (iprompt == 'q')
goto thanks;
}
for (pass = 0; pass <= 1; pass++) { for (pass = 0; pass <= 1; pass++) {
tmp = 0; tmp = 0;
@@ -1664,6 +1723,11 @@ dopay(void)
struct obj *otmp; struct obj *otmp;
register struct bill_x *bp = &(eshkp->bill_p[tmp]); register struct bill_x *bp = &(eshkp->bill_p[tmp]);
if (queuedpay && !bp->queuedpay) {
tmp++;
continue;
}
/* find the object on one of the lists */ /* find the object on one of the lists */
if ((otmp = bp_to_obj(bp)) != 0) { if ((otmp = bp_to_obj(bp)) != 0) {
/* if completely used up, object quantity is stale; /* if completely used up, object quantity is stale;