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:37 +02:00
parent 0ef2f15f51
commit 1ceb9d2d91
4 changed files with 73 additions and 7 deletions

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 [master] mind flayer, the Wizard, and the riders to bright magenta
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

View File

@@ -113,6 +113,7 @@ struct epri {
struct bill_x {
unsigned bo_id;
boolean useup;
boolean queuedpay;
long price; /* price per unit */
long bquan; /* amount used up */
};

View File

@@ -17,7 +17,7 @@
* Incrementing EDITLEVEL can be used to force invalidation of old bones
* and save files.
*/
#define EDITLEVEL 93
#define EDITLEVEL 94
/*
* Development status possibilities.

View File

@@ -45,6 +45,7 @@ static long set_cost(struct obj *, struct monst *);
static const char *shk_embellish(struct obj *, long);
static long cost_per_charge(struct monst *, struct obj *, boolean);
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,
boolean);
static long stolen_container(struct obj *, struct monst *, long, boolean);
@@ -1382,6 +1383,56 @@ cheapest_item(struct monst *shkp)
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 */
int
dopay(void)
@@ -1635,6 +1686,7 @@ dopay(void)
/* now check items on bill */
if (eshkp->billct) {
register boolean itemize;
boolean queuedpay = FALSE;
int iprompt;
umoney = money_cnt(gi.invent);
@@ -1651,12 +1703,19 @@ dopay(void)
return ECMD_OK;
}
/* 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;
if (flags.menu_style != MENU_TRADITIONAL && eshkp->billct > 1) {
if (!menu_pick_pay_items(shkp))
return ECMD_OK;
queuedpay = TRUE;
itemize = FALSE;
} 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++) {
tmp = 0;
@@ -1664,6 +1723,11 @@ dopay(void)
struct obj *otmp;
register struct bill_x *bp = &(eshkp->bill_p[tmp]);
if (queuedpay && !bp->queuedpay) {
tmp++;
continue;
}
/* find the object on one of the lists */
if ((otmp = bp_to_obj(bp)) != 0) {
/* if completely used up, object quantity is stale;