\#dotypeinv ('I') - show title for inventory subset

When asking for an inventory subset for one of the meta-classes that
can generate output which spans object classes (so B,U,C,X, and P),
insert a title at the start of the resulting inventory list.  (Iu and
Ix produce alternate output that already includes a title.)

Also, stop handling '$' differently for menustyles traditional and
combination from full and partial.  'I$' was running the '$' command
for the first two styles but just showing the inventory entry for
gold for the last two.  Change to the latter for all styles.
This commit is contained in:
PatR
2022-04-10 06:52:39 -07:00
parent 24d3c96c1d
commit 58bc545cc6
4 changed files with 82 additions and 48 deletions

View File

@@ -957,6 +957,7 @@ struct instance_globals {
winid cached_pickinv_win;
/* query objlist callback: return TRUE if obj type matches "this_type" */
int this_type;
const char *this_title; /* title for inventory list of specific type */
/* query objlist callback: return TRUE if obj is at given location */
coord only;

View File

@@ -432,8 +432,9 @@ const struct instance_globals g_init = {
NULL, /* invbuf */
0, /* inbufsize */
WIN_ERR, /* cached_pickinv_win */
UNDEFINED_VALUE,
UNDEFINED_VALUES,
0, /* this_type */
NULL, /* this_title */
UNDEFINED_VALUES, /* only (coord) */
/* light.c */
NULL, /* light_source */

View File

@@ -3503,20 +3503,25 @@ this_type_only(struct obj *obj)
int
dotypeinv(void)
{
static const char
prompt[] = "What type of object do you want an inventory of?";
char c = '\0';
int n, i = 0;
char *extra_types, types[BUFSZ];
char *extra_types, types[BUFSZ], title[QBUFSZ];
const char *before = "", *after = "";
int class_count, oclass, unpaid_count, itemcount;
int bcnt, ccnt, ucnt, xcnt, ocnt, jcnt;
boolean billx = *u.ushops && doinvbill(0);
menu_item *pick_list;
boolean traditional = TRUE;
const char *prompt = "What type of object do you want an inventory of?";
g.this_type = 0;
g.this_title = NULL;
if (!g.invent && !billx) {
You("aren't carrying anything.");
return ECMD_OK;
goto doI_done;
}
title[0] = '\0';
unpaid_count = count_unpaid(g.invent);
tally_BUCX(g.invent, FALSE, &bcnt, &ucnt, &ccnt, &xcnt, &ocnt, &jcnt);
@@ -3540,7 +3545,7 @@ dotypeinv(void)
i |= INCLUDE_VENOM;
n = query_category(prompt, g.invent, i, &pick_list, PICK_ONE);
if (!n)
return ECMD_OK;
goto doI_done;
g.this_type = c = pick_list[0].item.a_int;
free((genericptr_t) pick_list);
}
@@ -3551,7 +3556,7 @@ dotypeinv(void)
class_count = collect_obj_classes(types, g.invent, FALSE,
(boolean (*)(OBJ_P)) 0,
&itemcount);
if (unpaid_count || billx || (bcnt + ccnt + ucnt + xcnt) != 0)
if (unpaid_count || billx || (bcnt + ccnt + ucnt + xcnt) != 0 || jcnt)
types[class_count++] = ' ';
if (unpaid_count)
types[class_count++] = 'u';
@@ -3597,7 +3602,7 @@ dotypeinv(void)
savech(c);
if (c == '\0') {
clear_nhwindow(WIN_MESSAGE);
return ECMD_OK;
goto doI_done;
}
} else {
/* only one thing to itemize */
@@ -3615,63 +3620,84 @@ dotypeinv(void)
else
pline("No used-up objects%s.",
unpaid_count ? " on your shopping bill" : "");
return ECMD_OK;
goto doI_done;
}
if (c == 'u' || (c == 'U' && unpaid_count && !ucnt)) {
if (unpaid_count)
dounpaid();
else
You("are not carrying any unpaid objects.");
return ECMD_OK;
goto doI_done;
}
if (index("BUCXP", c))
oclass = c; /* not a class but understood by this_type_only() */
else
oclass = def_char_to_objclass(c); /* change to object class */
#if 0
/* this used to be done for the 'if traditional' case but not for the
menu case; also unlike '$', 'I$' explicitly asks about inventory,
so we no longer handle coin class differently from other classes */
if (oclass == COIN_CLASS) {
return doprgold();
}
#endif
/* these are used for traditional when not applicable and also for
constructing a title to be used by query_objlist() */
switch (c) {
case 'B':
before = "known to be blessed ";
break;
case 'U':
before = "known to be uncursed ";
break;
case 'C':
before = "known to be cursed ";
break;
case 'X':
after = " whose blessed/uncursed/cursed status is unknown";
break; /* better phrasing is desirable */
case 'P':
after = " that were just picked up";
break;
default:
/* 'c' is an object class, because we've already handled
all the non-class letters which were put into 'types[]';
could/should move object class names[] array from below
to somewhere above so that we can access it here (via
lcase(strcpy(classnamebuf, names[(int) c]))), but the
game-play value of doing so is low... */
before = "such ";
break;
}
if (traditional) {
if (index("BUCXP", c))
oclass = c; /* not a class but understood by this_type_only() */
else
oclass = def_char_to_objclass(c); /* change to object class */
if (oclass == COIN_CLASS)
return doprgold();
if (index(types, c) > index(types, '\033')) {
/* '> ESC' => hidden choice, something known not to be carried */
const char *before = "", *after = "";
switch (c) {
case 'B':
before = "known to be blessed ";
break;
case 'U':
before = "known to be uncursed ";
break;
case 'C':
before = "known to be cursed ";
break;
case 'X':
after = " whose blessed/uncursed/cursed status is unknown";
break; /* better phrasing is desirable */
case 'P':
after = " that were just picked up";
break;
default:
/* 'c' is an object class, because we've already handled
all the non-class letters which were put into 'types[]';
could/should move object class names[] array from below
to somewhere above so that we can access it here (via
lcase(strcpy(classnamebuf, names[(int) c]))), but the
game-play value of doing so is low... */
before = "such ";
break;
}
You("have no %sobjects%s.", before, after);
return ECMD_OK;
goto doI_done;
}
g.this_type = oclass;
g.this_type = oclass; /* extra input for this_type_only() */
}
if (index("BUCXP", c)) {
/* the before and after phrases for "you have no..." can both be
treated as mutually-exclusive suffices when creating a title */
Sprintf(title, "Items %s", (before && *before) ? before : after);
/* get rid of trailing space from 'before' and double-space from
'after's leading space */
(void) mungspaces(title);
Strcat(title, ":"); /* after removing unwanted trailing space */
g.this_title = title;
}
if (query_objlist((char *) 0, &g.invent,
((flags.invlet_constant ? USE_INVLET : 0)
| INVORDER_SORT | INCLUDE_VENOM),
&pick_list, PICK_NONE, this_type_only) > 0)
free((genericptr_t) pick_list);
doI_done:
g.this_type = 0;
g.this_title = NULL;
return ECMD_OK;
}

View File

@@ -985,6 +985,12 @@ query_objlist(const char *qstr, /* query string */
win = create_nhwindow(NHW_MENU);
start_menu(win, MENU_BEHAVE_STANDARD);
any = cg.zeroany;
if (g.this_title) {
/* dotypeinv() supplies g.this_title to display as initial header;
intentionally avoid the menu_headings highlight attribute here */
add_menu(win, &nul_glyphinfo, &any, 0, 0, ATR_NONE,
g.this_title, MENU_ITEMFLAGS_NONE);
}
/*
* Run through the list and add the objects to the menu. If
* INVORDER_SORT is set, we'll run through the list once for