\#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:
@@ -957,6 +957,7 @@ struct instance_globals {
|
|||||||
winid cached_pickinv_win;
|
winid cached_pickinv_win;
|
||||||
/* query objlist callback: return TRUE if obj type matches "this_type" */
|
/* query objlist callback: return TRUE if obj type matches "this_type" */
|
||||||
int 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 */
|
/* query objlist callback: return TRUE if obj is at given location */
|
||||||
coord only;
|
coord only;
|
||||||
|
|
||||||
|
|||||||
@@ -432,8 +432,9 @@ const struct instance_globals g_init = {
|
|||||||
NULL, /* invbuf */
|
NULL, /* invbuf */
|
||||||
0, /* inbufsize */
|
0, /* inbufsize */
|
||||||
WIN_ERR, /* cached_pickinv_win */
|
WIN_ERR, /* cached_pickinv_win */
|
||||||
UNDEFINED_VALUE,
|
0, /* this_type */
|
||||||
UNDEFINED_VALUES,
|
NULL, /* this_title */
|
||||||
|
UNDEFINED_VALUES, /* only (coord) */
|
||||||
|
|
||||||
/* light.c */
|
/* light.c */
|
||||||
NULL, /* light_source */
|
NULL, /* light_source */
|
||||||
|
|||||||
118
src/invent.c
118
src/invent.c
@@ -3503,20 +3503,25 @@ this_type_only(struct obj *obj)
|
|||||||
int
|
int
|
||||||
dotypeinv(void)
|
dotypeinv(void)
|
||||||
{
|
{
|
||||||
|
static const char
|
||||||
|
prompt[] = "What type of object do you want an inventory of?";
|
||||||
char c = '\0';
|
char c = '\0';
|
||||||
int n, i = 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 class_count, oclass, unpaid_count, itemcount;
|
||||||
int bcnt, ccnt, ucnt, xcnt, ocnt, jcnt;
|
int bcnt, ccnt, ucnt, xcnt, ocnt, jcnt;
|
||||||
boolean billx = *u.ushops && doinvbill(0);
|
boolean billx = *u.ushops && doinvbill(0);
|
||||||
menu_item *pick_list;
|
menu_item *pick_list;
|
||||||
boolean traditional = TRUE;
|
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) {
|
if (!g.invent && !billx) {
|
||||||
You("aren't carrying anything.");
|
You("aren't carrying anything.");
|
||||||
return ECMD_OK;
|
goto doI_done;
|
||||||
}
|
}
|
||||||
|
title[0] = '\0';
|
||||||
unpaid_count = count_unpaid(g.invent);
|
unpaid_count = count_unpaid(g.invent);
|
||||||
tally_BUCX(g.invent, FALSE, &bcnt, &ucnt, &ccnt, &xcnt, &ocnt, &jcnt);
|
tally_BUCX(g.invent, FALSE, &bcnt, &ucnt, &ccnt, &xcnt, &ocnt, &jcnt);
|
||||||
|
|
||||||
@@ -3540,7 +3545,7 @@ dotypeinv(void)
|
|||||||
i |= INCLUDE_VENOM;
|
i |= INCLUDE_VENOM;
|
||||||
n = query_category(prompt, g.invent, i, &pick_list, PICK_ONE);
|
n = query_category(prompt, g.invent, i, &pick_list, PICK_ONE);
|
||||||
if (!n)
|
if (!n)
|
||||||
return ECMD_OK;
|
goto doI_done;
|
||||||
g.this_type = c = pick_list[0].item.a_int;
|
g.this_type = c = pick_list[0].item.a_int;
|
||||||
free((genericptr_t) pick_list);
|
free((genericptr_t) pick_list);
|
||||||
}
|
}
|
||||||
@@ -3551,7 +3556,7 @@ dotypeinv(void)
|
|||||||
class_count = collect_obj_classes(types, g.invent, FALSE,
|
class_count = collect_obj_classes(types, g.invent, FALSE,
|
||||||
(boolean (*)(OBJ_P)) 0,
|
(boolean (*)(OBJ_P)) 0,
|
||||||
&itemcount);
|
&itemcount);
|
||||||
if (unpaid_count || billx || (bcnt + ccnt + ucnt + xcnt) != 0)
|
if (unpaid_count || billx || (bcnt + ccnt + ucnt + xcnt) != 0 || jcnt)
|
||||||
types[class_count++] = ' ';
|
types[class_count++] = ' ';
|
||||||
if (unpaid_count)
|
if (unpaid_count)
|
||||||
types[class_count++] = 'u';
|
types[class_count++] = 'u';
|
||||||
@@ -3597,7 +3602,7 @@ dotypeinv(void)
|
|||||||
savech(c);
|
savech(c);
|
||||||
if (c == '\0') {
|
if (c == '\0') {
|
||||||
clear_nhwindow(WIN_MESSAGE);
|
clear_nhwindow(WIN_MESSAGE);
|
||||||
return ECMD_OK;
|
goto doI_done;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* only one thing to itemize */
|
/* only one thing to itemize */
|
||||||
@@ -3615,63 +3620,84 @@ dotypeinv(void)
|
|||||||
else
|
else
|
||||||
pline("No used-up objects%s.",
|
pline("No used-up objects%s.",
|
||||||
unpaid_count ? " on your shopping bill" : "");
|
unpaid_count ? " on your shopping bill" : "");
|
||||||
return ECMD_OK;
|
goto doI_done;
|
||||||
}
|
}
|
||||||
if (c == 'u' || (c == 'U' && unpaid_count && !ucnt)) {
|
if (c == 'u' || (c == 'U' && unpaid_count && !ucnt)) {
|
||||||
if (unpaid_count)
|
if (unpaid_count)
|
||||||
dounpaid();
|
dounpaid();
|
||||||
else
|
else
|
||||||
You("are not carrying any unpaid objects.");
|
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 (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')) {
|
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);
|
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,
|
if (query_objlist((char *) 0, &g.invent,
|
||||||
((flags.invlet_constant ? USE_INVLET : 0)
|
((flags.invlet_constant ? USE_INVLET : 0)
|
||||||
| INVORDER_SORT | INCLUDE_VENOM),
|
| INVORDER_SORT | INCLUDE_VENOM),
|
||||||
&pick_list, PICK_NONE, this_type_only) > 0)
|
&pick_list, PICK_NONE, this_type_only) > 0)
|
||||||
free((genericptr_t) pick_list);
|
free((genericptr_t) pick_list);
|
||||||
|
|
||||||
|
doI_done:
|
||||||
|
g.this_type = 0;
|
||||||
|
g.this_title = NULL;
|
||||||
return ECMD_OK;
|
return ECMD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -985,6 +985,12 @@ query_objlist(const char *qstr, /* query string */
|
|||||||
win = create_nhwindow(NHW_MENU);
|
win = create_nhwindow(NHW_MENU);
|
||||||
start_menu(win, MENU_BEHAVE_STANDARD);
|
start_menu(win, MENU_BEHAVE_STANDARD);
|
||||||
any = cg.zeroany;
|
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
|
* Run through the list and add the objects to the menu. If
|
||||||
* INVORDER_SORT is set, we'll run through the list once for
|
* INVORDER_SORT is set, we'll run through the list once for
|
||||||
|
|||||||
Reference in New Issue
Block a user