item actions for '* ) [ = " (' commands
Make the various item-in-use commands put up a menu--which allows
choosing an item for context-sensitive item action--if/when preceded
by the 'm' prefix. Some of them do that even without the prefix ('*',
'[', or '=' when more than one ring is worn). By default '(' shows
primary weapon, then secondary one if dual-wielding. 'm (' shows a
menu of primary, alternate whether dual-wielding it or not, and quiver.
This commit is contained in:
@@ -46,7 +46,7 @@
|
||||
.ds f0 \*(vr
|
||||
.ds f1 \" empty
|
||||
.\"DO NOT REMOVE NH_DATESUB .ds f2 DATE(%B %-d, %Y)
|
||||
.ds f2 "November 13, 2023
|
||||
.ds f2 "November 17, 2023
|
||||
.
|
||||
.\" A note on some special characters:
|
||||
.\" \(lq = left double quote
|
||||
@@ -1576,21 +1576,44 @@ Default key is \(oqs\(cq.
|
||||
.lp "#seeall "
|
||||
Show all equipment in use.
|
||||
Default key is \(oq*\(cq.
|
||||
.lp ""
|
||||
Will display in-use items in a menu even when there is only one.
|
||||
.lp #seeamulet
|
||||
Show the amulet currently worn.
|
||||
Default key is \(oq\(dq\(cq. \" double quote
|
||||
.lp ""
|
||||
Using the \(oq\f(CRm\fP\(cq prefix will force the display of a worn
|
||||
amulet in a menu rather than with just a message.
|
||||
.lp #seearmor
|
||||
Show the armor currently worn.
|
||||
Default key is \(oq[\(cq.
|
||||
.lp ""
|
||||
Will display worn armor in a menu even when there is only thing worn.
|
||||
.lp #seerings
|
||||
Show the ring(s) currently worn.
|
||||
Default key is \(oq=\(cq.
|
||||
.lp ""
|
||||
Will display worn rings in a menu if there are two (or there is
|
||||
just one and is a meat ring rather than a \(lqreal\(rq ring).
|
||||
Use the \(oq\f(CRm\fP\(cq prefix to force a menu for one ring.
|
||||
.lp #seetools
|
||||
Show the tools currently in use.
|
||||
Default key is \(oq(\(cq.
|
||||
.lp ""
|
||||
Will display the result in a message if there is one tool in use (worn
|
||||
blindfold or towel or lenses, lit lamp(s) and/or candle(s), leashes
|
||||
attached to pets).
|
||||
Will display a menu if there are more than one or if the command is
|
||||
preceded by the \(oq\f(CRm\fP\(cq prefix.
|
||||
.lp #seeweapon
|
||||
Show the weapon currently wielded.
|
||||
Default key is \(oq)\(cq.
|
||||
.lp ""
|
||||
If dual-wielding, a separate message about the secondary weapon will be
|
||||
given.
|
||||
Using the \(oq\f(CRm\fP\(cq prefix will force a menu and it will include
|
||||
primary weapon, alternate weapon even when not dual-wielding, and also
|
||||
whatever is currently assigned to the quiver slot.
|
||||
.lp "#shell "
|
||||
Do a shell escape, switching from NetHack to a subprocess.
|
||||
Can be disabled at the time the program is built.
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
\author{Original version - Eric S. Raymond\\
|
||||
(Edited and expanded for 3.7.0 by Mike Stephenson and others)}
|
||||
%DO NOT REMOVE NH_DATESUB \date{DATE(%B %-d, %Y)}
|
||||
\date{November 13, 2023}
|
||||
\date{November 27, 2023}
|
||||
|
||||
\maketitle
|
||||
|
||||
@@ -1697,21 +1697,47 @@ Search for traps and secret doors around you. Default key is `{\tt s}'.
|
||||
%.lp
|
||||
\item[\tb{\#seeall}]
|
||||
Show all equipment in use. Default key is `{\tt *}'.
|
||||
%.lp ""
|
||||
\\
|
||||
Will display in-use items in a menu even when there is only one.
|
||||
%.lp
|
||||
\item[\tb{\#seeamulet}]
|
||||
Show the amulet currently worn. Default key is `{\tt "}'.
|
||||
%.lp ""
|
||||
\\
|
||||
Using the `{\tt m}' prefix will force the display of a worn
|
||||
amulet in a menu rather than with just a message.
|
||||
%.lp
|
||||
\item[\tb{\#seearmor}]
|
||||
Show the armor currently worn. Default key is `{\tt [}'.
|
||||
%.lp ""
|
||||
\\
|
||||
Will display worn armor in a menu even when there is only thing worn.
|
||||
%.lp
|
||||
\item[\tb{\#seerings}]
|
||||
Show the ring(s) currently worn. Default key is `{\tt =}'.
|
||||
%.lp ""
|
||||
Will display worn rings in a menu if there are two (or there is
|
||||
just one and is a meat ring rather than a ``real'' ring).
|
||||
Use the `{\tt m}' prefix to force a menu for one ring.
|
||||
%.lp
|
||||
\item[\tb{\#seetools}]
|
||||
Show the tools currently in use. Default key is `{\tt (}'.
|
||||
%.lp ""
|
||||
Will display the result in a message if there is one tool in use (worn
|
||||
blindfold or towel or lenses, lit lamp(s) and/or candle(s), leashes
|
||||
attached to pets).
|
||||
Will display a menu if there are more than one or if the command is
|
||||
preceded by the `{\tt m}' prefix.
|
||||
%.lp
|
||||
\item[\tb{\#seeweapon}]
|
||||
Show the weapon currently wielded. Default key is `{\tt )}'.
|
||||
%.lp ""
|
||||
If dual-wielding, a separate message about the secondary weapon will be
|
||||
given.
|
||||
Using the `{\tt m}' prefix will force a menu and it will include
|
||||
primary weapon, alternate weapon even when not dual-wielding, and also
|
||||
whatever is currently assigned to the quiver slot.
|
||||
%.lp
|
||||
\item[\tb{\#shell}]
|
||||
Do a shell escape, switching from NetHack to a subprocess.
|
||||
|
||||
@@ -2351,6 +2351,10 @@ the '*' command (list inventory items in use) now shows items in a specific
|
||||
gloves, boots, shirt, lit lamps and candles, leashes attached to pets
|
||||
instead of by object class (sortpack) or inventory letter (!sortpack);
|
||||
new perm_invent+perminv_mode==inuse does the same
|
||||
allow the ')', '[', '(', '=', '"', and '*' commands to be preceded by the 'm'
|
||||
prefix to force a menu where the player can pick an item and choose
|
||||
a context-sensitive item action for it; some give a menu even without
|
||||
the prefix and for those, same item selection and action can be used
|
||||
|
||||
|
||||
Platform- and/or Interface-Specific New Features
|
||||
|
||||
14
src/cmd.c
14
src/cmd.c
@@ -2698,17 +2698,17 @@ struct ext_func_tab extcmdlist[] = {
|
||||
{ 's', "search", "search for traps and secret doors",
|
||||
dosearch, IFBURIED | CMD_M_PREFIX, "searching" },
|
||||
{ '*', "seeall", "show all equipment in use",
|
||||
doprinuse, IFBURIED, NULL },
|
||||
doprinuse, IFBURIED | CMD_M_PREFIX, NULL },
|
||||
{ AMULET_SYM, "seeamulet", "show the amulet currently worn",
|
||||
dopramulet, IFBURIED, NULL },
|
||||
dopramulet, IFBURIED | CMD_M_PREFIX, NULL },
|
||||
{ ARMOR_SYM, "seearmor", "show the armor currently worn",
|
||||
doprarm, IFBURIED, NULL },
|
||||
doprarm, IFBURIED | CMD_M_PREFIX, NULL },
|
||||
{ RING_SYM, "seerings", "show the ring(s) currently worn",
|
||||
doprring, IFBURIED, NULL },
|
||||
doprring, IFBURIED | CMD_M_PREFIX, NULL },
|
||||
{ TOOL_SYM, "seetools", "show the tools currently in use",
|
||||
doprtool, IFBURIED, NULL },
|
||||
doprtool, IFBURIED | CMD_M_PREFIX, NULL },
|
||||
{ WEAPON_SYM, "seeweapon", "show the weapon currently wielded",
|
||||
doprwep, IFBURIED, NULL },
|
||||
doprwep, IFBURIED | CMD_M_PREFIX, NULL },
|
||||
{ '!', "shell", "leave game to enter a sub-shell ('exit' to come back)",
|
||||
dosh_core, (IFBURIED | GENERALCMD | NOFUZZERCMD
|
||||
#ifndef SHELL
|
||||
@@ -2717,7 +2717,7 @@ struct ext_func_tab extcmdlist[] = {
|
||||
), NULL },
|
||||
/* $ is like ),=,&c but is not included with *, so not called "seegold" */
|
||||
{ GOLD_SYM, "showgold", "show gold, possibly shop credit or debt",
|
||||
doprgold, IFBURIED, NULL },
|
||||
doprgold, IFBURIED | CMD_M_PREFIX, NULL },
|
||||
{ SPBOOK_SYM, "showspells", "list and reorder known spells",
|
||||
dovspell, IFBURIED, NULL },
|
||||
{ '^', "showtrap", "describe an adjacent, discovered trap",
|
||||
|
||||
176
src/invent.c
176
src/invent.c
@@ -24,6 +24,7 @@ static char *cinv_ansimpleoname(struct obj *);
|
||||
static boolean only_here(struct obj *);
|
||||
static void compactify(char *);
|
||||
static boolean taking_off(const char *);
|
||||
static void mime_action(const char *);
|
||||
static int ckvalidcat(struct obj *);
|
||||
static int ckunpaid(struct obj *);
|
||||
static char *safeq_xprname(struct obj *);
|
||||
@@ -44,7 +45,8 @@ static boolean item_naming_classification(struct obj *, char *, char *);
|
||||
static int item_reading_classification(struct obj *, char *);
|
||||
static void ia_addmenu(winid, int, char, const char *);
|
||||
static void itemactions_pushkeys(struct obj *, int);
|
||||
static void mime_action(const char *);
|
||||
static int itemactions(struct obj *);
|
||||
static int dispinv_with_action(char *, boolean, const char *);
|
||||
|
||||
/* enum and structs are defined in wintype.h */
|
||||
static win_request_info wri_info;
|
||||
@@ -62,8 +64,10 @@ static boolean in_perm_invent_toggled;
|
||||
*/
|
||||
static const char venom_inv[] = { VENOM_CLASS, 0 }; /* (constant) */
|
||||
|
||||
/* menu heading lines used instead of object classes when sorting by in-use */
|
||||
static const char *const inuse_headers[] = { /* [4] shown first, [1] last */
|
||||
/* menu heading lines used instead of object classes when sorting by in-use;
|
||||
pointers aren't const because dispinv_with_action() might temporarily
|
||||
change "Accessories" to "Rings" or "Amulet", then back again */
|
||||
static const char *inuse_headers[] = { /* [4] shown first, [1] last */
|
||||
"", "Miscellaneous", "Worn Armor",
|
||||
"Wielded/Readied Weapons", "Accessories",
|
||||
};
|
||||
@@ -3362,13 +3366,40 @@ itemactions(struct obj *otmp)
|
||||
return ECMD_OK;
|
||||
}
|
||||
|
||||
|
||||
/* the #inventory command */
|
||||
int
|
||||
ddoinv(void)
|
||||
/* show some or all of inventory while allowing the picking of an item in
|
||||
order to preform context-sensitive item action on it; always returns 'ok';
|
||||
invent subsets specified by the ')', '[', '(', '=', '"', or '*' commands
|
||||
when they're invoked with the 'm' prefix (or without it for '*') */
|
||||
static int
|
||||
dispinv_with_action(
|
||||
char *lets, /* list of invlet values to include */
|
||||
boolean use_inuse_ordering, /* affects sortloot() and header labels */
|
||||
const char *alt_label) /* alternate value for in-use "Accessories" */
|
||||
{
|
||||
struct obj *otmp;
|
||||
char c = display_inventory((char *) 0, TRUE);
|
||||
const char *save_accessories = 0;
|
||||
char c, save_sortloot = 0;
|
||||
unsigned len = lets ? (unsigned) strlen(lets) : 0U;
|
||||
boolean menumode = (len != 1 || iflags.menu_requested) ? TRUE : FALSE,
|
||||
save_force_invmenu = iflags.force_invmenu;
|
||||
|
||||
if (use_inuse_ordering) {
|
||||
save_accessories = inuse_headers[4];
|
||||
save_sortloot = flags.sortloot;
|
||||
|
||||
flags.sortloot = 'i'; /* checked by display_pickinv() */
|
||||
if (alt_label)
|
||||
inuse_headers[4] = alt_label;
|
||||
}
|
||||
iflags.force_invmenu = FALSE;
|
||||
|
||||
c = display_inventory(lets, menumode);
|
||||
|
||||
if (use_inuse_ordering) {
|
||||
flags.sortloot = save_sortloot;
|
||||
inuse_headers[4] = save_accessories;
|
||||
}
|
||||
iflags.force_invmenu = save_force_invmenu;
|
||||
|
||||
if (c && c != '\033') {
|
||||
for (otmp = gi.invent; otmp; otmp = otmp->nobj)
|
||||
@@ -3378,6 +3409,13 @@ ddoinv(void)
|
||||
return ECMD_OK;
|
||||
}
|
||||
|
||||
/* the #inventory command (not much left...) */
|
||||
int
|
||||
ddoinv(void)
|
||||
{
|
||||
return dispinv_with_action((char *) 0, FALSE, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* find_unpaid()
|
||||
*
|
||||
@@ -3515,7 +3553,7 @@ display_pickinv(
|
||||
if (!flags.invlet_constant)
|
||||
reassign();
|
||||
|
||||
if (n == 1 && !iflags.force_invmenu) {
|
||||
if (n == 1 && !iflags.force_invmenu && !iflags.menu_requested) {
|
||||
/* when only one item of interest, use pline instead of menus;
|
||||
we actually use a fake message-line menu in order to allow
|
||||
the user to perform selection at the --More-- prompt for tty */
|
||||
@@ -4860,6 +4898,14 @@ doprgold(void)
|
||||
You("have no money.");
|
||||
}
|
||||
shopper_financial_report();
|
||||
|
||||
if (umoney && iflags.menu_requested) {
|
||||
char dollarsign[] = "$";
|
||||
|
||||
/* mustn't use TRUE or gold wouldn't show up unless it was quivered */
|
||||
(void) dispinv_with_action(dollarsign, FALSE, NULL);
|
||||
}
|
||||
|
||||
return ECMD_OK;
|
||||
}
|
||||
|
||||
@@ -4869,10 +4915,24 @@ doprwep(void)
|
||||
{
|
||||
if (!uwep) {
|
||||
You("are %s.", empty_handed());
|
||||
} else {
|
||||
} else if (!iflags.menu_requested) {
|
||||
prinv((char *) 0, uwep, 0L);
|
||||
if (u.twoweap)
|
||||
prinv((char *) 0, uswapwep, 0L);
|
||||
} else {
|
||||
char lets[4]; /* 4: uwep, uswapwep, uquiver, terminator */
|
||||
int ct = 0;
|
||||
|
||||
/* obj_to_let() will assign letters to all of invent if necessary
|
||||
(for '!fixinv') so doesn't need to be repeated once called here */
|
||||
lets[ct++] = obj_to_let(uwep);
|
||||
if (uswapwep)
|
||||
lets[ct++] = uswapwep->invlet;
|
||||
if (uquiver)
|
||||
lets[ct++] = uquiver->invlet;
|
||||
lets[ct] = '\0';
|
||||
|
||||
(void) dispinv_with_action(lets, TRUE, NULL);
|
||||
}
|
||||
return ECMD_OK;
|
||||
}
|
||||
@@ -4904,8 +4964,6 @@ noarmor(boolean report_uskin)
|
||||
int
|
||||
doprarm(void)
|
||||
{
|
||||
char lets[8];
|
||||
int ct = 0;
|
||||
/*
|
||||
* Note: players sometimes get here by pressing a function key which
|
||||
* transmits ''ESC [ <something>'' rather than by pressing '[';
|
||||
@@ -4915,22 +4973,30 @@ doprarm(void)
|
||||
if (!wearing_armor()) {
|
||||
noarmor(TRUE);
|
||||
} else {
|
||||
if (uarmu)
|
||||
lets[ct++] = obj_to_let(uarmu);
|
||||
char lets[8]; /* 8: up to 7 pieces of armor plus terminator */
|
||||
int ct = 0;
|
||||
|
||||
/* obj_to_let() will assign letters to all of invent if necessary
|
||||
(for '!fixinv') so doesn't need to be repeated once called, but
|
||||
each armor slot doesn't know whether any that precede have made
|
||||
that call so just do it for each one; use SORTPACK_INUSE order */
|
||||
if (uarm)
|
||||
lets[ct++] = obj_to_let(uarm);
|
||||
if (uarmc)
|
||||
lets[ct++] = obj_to_let(uarmc);
|
||||
if (uarmh)
|
||||
lets[ct++] = obj_to_let(uarmh);
|
||||
if (uarms)
|
||||
lets[ct++] = obj_to_let(uarms);
|
||||
if (uarmh)
|
||||
lets[ct++] = obj_to_let(uarmh);
|
||||
if (uarmg)
|
||||
lets[ct++] = obj_to_let(uarmg);
|
||||
if (uarmf)
|
||||
lets[ct++] = obj_to_let(uarmf);
|
||||
if (uarmu)
|
||||
lets[ct++] = obj_to_let(uarmu);
|
||||
lets[ct] = 0;
|
||||
(void) display_inventory(lets, FALSE);
|
||||
|
||||
(void) dispinv_with_action(lets, TRUE, NULL);
|
||||
}
|
||||
return ECMD_OK;
|
||||
}
|
||||
@@ -4942,15 +5008,32 @@ doprring(void)
|
||||
if (!uleft && !uright) {
|
||||
You("are not wearing any rings.");
|
||||
} else {
|
||||
char lets[3];
|
||||
char lets[3]; /* 3: uright, uleft, terminator */
|
||||
boolean use_inuse_mode = FALSE;
|
||||
int ct = 0;
|
||||
|
||||
if (uleft)
|
||||
lets[ct++] = obj_to_let(uleft);
|
||||
if (uright)
|
||||
/* if either ring is a meat ring, switch to use_inuse_mode in order
|
||||
to label it/them as "Rings" rather than "Comestibles" */
|
||||
if (uright) {
|
||||
lets[ct++] = obj_to_let(uright);
|
||||
lets[ct] = 0;
|
||||
(void) display_inventory(lets, FALSE);
|
||||
if (uright->oclass != RING_CLASS)
|
||||
use_inuse_mode = TRUE;
|
||||
}
|
||||
if (uleft) {
|
||||
lets[ct++] = obj_to_let(uleft);
|
||||
if (uleft->oclass != RING_CLASS)
|
||||
use_inuse_mode = TRUE;
|
||||
}
|
||||
lets[ct] = '\0';
|
||||
/* also switch to use_inuse_mode if there are two rings or player
|
||||
used the 'm' prefix */
|
||||
if (ct > 1 || iflags.menu_requested)
|
||||
use_inuse_mode = TRUE;
|
||||
|
||||
(void) dispinv_with_action(lets, use_inuse_mode,
|
||||
/* note; alternate label will be ignored
|
||||
if 'use_inuse_mode' is False */
|
||||
(ct == 1) ? "Ring" : "Rings");
|
||||
}
|
||||
return ECMD_OK;
|
||||
}
|
||||
@@ -4959,10 +5042,18 @@ doprring(void)
|
||||
int
|
||||
dopramulet(void)
|
||||
{
|
||||
if (!uamul)
|
||||
if (!uamul) {
|
||||
You("are not wearing an amulet.");
|
||||
else
|
||||
prinv((char *) 0, uamul, 0L);
|
||||
} else {
|
||||
char lets[2];
|
||||
|
||||
/* using display_inventory() instead of prinv() allows player
|
||||
to use 'm "' to force and menu and be able to choose amulet
|
||||
in order to perform a context-sensitve item action */
|
||||
lets[0] = obj_to_let(uamul), lets[1] = '\0';
|
||||
|
||||
(void) dispinv_with_action(lets, TRUE, "Amulet");
|
||||
}
|
||||
return ECMD_OK;
|
||||
}
|
||||
|
||||
@@ -5003,7 +5094,7 @@ doprtool(void)
|
||||
if (!ct)
|
||||
You("are not using any tools.");
|
||||
else
|
||||
(void) display_inventory(lets, FALSE);
|
||||
(void) dispinv_with_action(lets, TRUE, NULL);
|
||||
return ECMD_OK;
|
||||
}
|
||||
|
||||
@@ -5014,41 +5105,18 @@ doprinuse(void)
|
||||
{
|
||||
struct obj *otmp;
|
||||
int ct = 0;
|
||||
#if 0 /* old doprinuse() */
|
||||
char lets[52 + 1];
|
||||
|
||||
for (otmp = gi.invent; otmp; otmp = otmp->nobj)
|
||||
if (is_inuse(otmp)) {
|
||||
/* we could be carrying more than 52 items; theoretically they
|
||||
might all be lit candles so avoid potential lets[] overflow */
|
||||
if (ct >= (int) sizeof lets - 1)
|
||||
break;
|
||||
lets[ct++] = obj_to_let(otmp);
|
||||
}
|
||||
lets[ct] = '\0';
|
||||
if (ct)
|
||||
(void) display_inventory(lets, FALSE);
|
||||
#else /* new */
|
||||
/* no longer need to collect letters; sortloot() takes care of it, but
|
||||
still need to count far enough to know whether anything is in use */
|
||||
still want to count far enough to know whether anything is in use */
|
||||
for (otmp = gi.invent; otmp; otmp = otmp->nobj)
|
||||
if (is_inuse(otmp)) {
|
||||
++ct;
|
||||
break;
|
||||
}
|
||||
if (ct) {
|
||||
char save_sortloot = flags.sortloot;
|
||||
|
||||
flags.sortloot = 'i';
|
||||
/* bypass display_inventory() and go straight to display_pickinv() */
|
||||
(void) display_pickinv((char *) 0, (char *) 0, (char *) 0,
|
||||
/* 'want_reply' forces window other than WIN_INVENT */
|
||||
TRUE, (long *) 0);
|
||||
flags.sortloot = save_sortloot;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
if (!ct)
|
||||
You("are not wearing or wielding anything.");
|
||||
else
|
||||
(void) dispinv_with_action((char *) 0, TRUE, NULL);
|
||||
return ECMD_OK;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user