in src/cmd.c [5102:5409]
help_requested ? (const char *) 0
: "Invalid direction key!");
if (help_requested)
goto retry;
}
if (!did_help)
pline("What a strange direction!");
}
return 0;
} else if (is_mov && !dxdy_moveok()) {
You_cant("orient yourself that direction.");
return 0;
}
if (!u.dz && (Stunned || (Confusion && !rn2(5))))
confdir();
return 1;
}
STATIC_OVL void
show_direction_keys(win, centerchar, nodiag)
winid win; /* should specify a window which is using a fixed-width font... */
char centerchar; /* '.' or '@' or ' ' */
boolean nodiag;
{
char buf[BUFSZ];
if (!centerchar)
centerchar = ' ';
if (nodiag) {
Sprintf(buf, " %c ", Cmd.move_N);
putstr(win, 0, buf);
putstr(win, 0, " | ");
Sprintf(buf, " %c- %c -%c",
Cmd.move_W, centerchar, Cmd.move_E);
putstr(win, 0, buf);
putstr(win, 0, " | ");
Sprintf(buf, " %c ", Cmd.move_S);
putstr(win, 0, buf);
} else {
Sprintf(buf, " %c %c %c",
Cmd.move_NW, Cmd.move_N, Cmd.move_NE);
putstr(win, 0, buf);
putstr(win, 0, " \\ | / ");
Sprintf(buf, " %c- %c -%c",
Cmd.move_W, centerchar, Cmd.move_E);
putstr(win, 0, buf);
putstr(win, 0, " / | \\ ");
Sprintf(buf, " %c %c %c",
Cmd.move_SW, Cmd.move_S, Cmd.move_SE);
putstr(win, 0, buf);
};
}
/* explain choices if player has asked for getdir() help or has given
an invalid direction after a prefix key ('F', 'g', 'm', &c), which
might be bogus but could be up, down, or self when not applicable */
STATIC_OVL boolean
help_dir(sym, spkey, msg)
char sym;
int spkey; /* NHKF_ code for prefix key, if one was used, or for ESC */
const char *msg;
{
static const char wiz_only_list[] = "EFGIVW";
char ctrl;
winid win;
char buf[BUFSZ], buf2[BUFSZ], *explain;
const char *dothat, *how;
boolean prefixhandling, viawindow;
/* NHKF_ESC indicates that player asked for help at getdir prompt */
viawindow = (spkey == NHKF_ESC || iflags.cmdassist);
prefixhandling = (spkey != NHKF_ESC);
/*
* Handling for prefix keys that don't want special directions.
* Delivered via pline if 'cmdassist' is off, or instead of the
* general message if it's on.
*/
dothat = "do that";
how = " at"; /* for "<action> at yourself"; not used for up/down */
switch (spkey) {
case NHKF_NOPICKUP:
dothat = "move";
break;
case NHKF_RUSH:
dothat = "rush";
break;
case NHKF_RUN2:
if (!Cmd.num_pad)
break;
/*FALLTHRU*/
case NHKF_RUN:
case NHKF_RUN_NOPICKUP:
dothat = "run";
break;
case NHKF_FIGHT2:
if (!Cmd.num_pad)
break;
/*FALLTHRU*/
case NHKF_FIGHT:
dothat = "fight";
how = ""; /* avoid "fight at yourself" */
break;
default:
prefixhandling = FALSE;
break;
}
buf[0] = '\0';
/* for movement prefix followed by '.' or (numpad && 's') to mean 'self';
note: '-' for hands (inventory form of 'self') is not handled here */
if (prefixhandling
&& (sym == Cmd.spkeys[NHKF_GETDIR_SELF]
|| (Cmd.num_pad && sym == Cmd.spkeys[NHKF_GETDIR_SELF2]))) {
Sprintf(buf, "You can't %s%s yourself.", dothat, how);
/* for movement prefix followed by up or down */
} else if (prefixhandling && (sym == '<' || sym == '>')) {
Sprintf(buf, "You can't %s %s.", dothat,
/* was "upwards" and "downwards", but they're considered
to be variants of canonical "upward" and "downward" */
(sym == '<') ? "upward" : "downward");
}
/* if '!cmdassist', display via pline() and we're done (note: asking
for help at getdir() prompt forces cmdassist for this operation) */
if (!viawindow) {
if (prefixhandling) {
if (!*buf)
Sprintf(buf, "Invalid direction for '%s' prefix.",
visctrl(Cmd.spkeys[spkey]));
pline("%s", buf);
return TRUE;
}
/* when 'cmdassist' is off and caller doesn't insist, do nothing */
return FALSE;
}
win = create_nhwindow(NHW_TEXT);
if (!win)
return FALSE;
if (*buf) {
/* show bad-prefix message instead of general invalid-direction one */
putstr(win, 0, buf);
putstr(win, 0, "");
} else if (msg) {
Sprintf(buf, "cmdassist: %s", msg);
putstr(win, 0, buf);
putstr(win, 0, "");
}
if (!prefixhandling && (letter(sym) || sym == '[')) {
/* '[': old 'cmdhelp' showed ESC as ^[ */
sym = highc(sym); /* @A-Z[ (note: letter() accepts '@') */
ctrl = (sym - 'A') + 1; /* 0-27 (note: 28-31 aren't applicable) */
if ((explain = dowhatdoes_core(ctrl, buf2)) != 0
&& (!index(wiz_only_list, sym) || wizard)) {
Sprintf(buf, "Are you trying to use ^%c%s?", sym,
index(wiz_only_list, sym) ? ""
: " as specified in the Guidebook");
putstr(win, 0, buf);
putstr(win, 0, "");
putstr(win, 0, explain);
putstr(win, 0, "");
putstr(win, 0,
"To use that command, hold down the <Ctrl> key as a shift");
Sprintf(buf, "and press the <%c> key.", sym);
putstr(win, 0, buf);
putstr(win, 0, "");
}
}
Sprintf(buf, "Valid direction keys%s%s%s are:",
prefixhandling ? " to " : "", prefixhandling ? dothat : "",
NODIAG(u.umonnum) ? " in your current form" : "");
putstr(win, 0, buf);
show_direction_keys(win, !prefixhandling ? '.' : ' ', NODIAG(u.umonnum));
if (!prefixhandling || spkey == NHKF_NOPICKUP) {
/* NOPICKUP: unlike the other prefix keys, 'm' allows up/down for
stair traversal; we won't get here when "m<" or "m>" has been
given but we include up and down for 'm'+invalid_direction;
self is excluded as a viable direction for every prefix */
putstr(win, 0, "");
putstr(win, 0, " < up");
putstr(win, 0, " > down");
if (!prefixhandling) {
int selfi = Cmd.num_pad ? NHKF_GETDIR_SELF2 : NHKF_GETDIR_SELF;
Sprintf(buf, " %4s direct at yourself",
visctrl(Cmd.spkeys[selfi]));
putstr(win, 0, buf);
}
}
if (msg) {
/* non-null msg means that this wasn't an explicit user request */
putstr(win, 0, "");
putstr(win, 0,
"(Suppress this message with !cmdassist in config file.)");
}
display_nhwindow(win, FALSE);
destroy_nhwindow(win);
return TRUE;
}
void
confdir()
{
register int x = NODIAG(u.umonnum) ? 2 * rn2(4) : rn2(8);
u.dx = xdir[x];
u.dy = ydir[x];
return;
}
const char *
directionname(dir)
int dir;
{
static NEARDATA const char *const dirnames[] = {
"west", "northwest", "north", "northeast", "east",
"southeast", "south", "southwest", "down", "up",
};
if (dir < 0 || dir >= SIZE(dirnames))
return "invalid";
return dirnames[dir];
}
int
isok(x, y)
register int x, y;
{
/* x corresponds to curx, so x==1 is the first column. Ach. %% */
return x >= 1 && x <= COLNO - 1 && y >= 0 && y <= ROWNO - 1;
}
/* #herecmdmenu command */
STATIC_PTR int
doherecmdmenu(VOID_ARGS)
{
char ch = here_cmd_menu(TRUE);
return ch ? 1 : 0;
}
/* #therecmdmenu command, a way to test there_cmd_menu without mouse */
STATIC_PTR int
dotherecmdmenu(VOID_ARGS)
{
char ch;
if (!getdir((const char *) 0) || !isok(u.ux + u.dx, u.uy + u.dy))
return 0;
if (u.dx || u.dy)
ch = there_cmd_menu(TRUE, u.ux + u.dx, u.uy + u.dy);
else
ch = here_cmd_menu(TRUE);
return ch ? 1 : 0;
}
STATIC_OVL void
add_herecmd_menuitem(win, func, text)
winid win;
int NDECL((*func));
const char *text;
{
char ch;
anything any;
if ((ch = cmd_from_func(func)) != '\0') {
any = zeroany;
any.a_nfunc = func;
add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, text, MENU_UNSELECTED);
}
}
STATIC_OVL char
there_cmd_menu(doit, x, y)
boolean doit;
int x, y;
{
winid win;
char ch;
char buf[BUFSZ];
schar typ = levl[x][y].typ;
int npick, K = 0;
menu_item *picks = (menu_item *) 0;
struct trap *ttmp;
struct monst *mtmp;
win = create_nhwindow(NHW_MENU);
start_menu(win);
if (IS_DOOR(typ)) {
boolean key_or_pick, card;
int dm = levl[x][y].doormask;
if ((dm & (D_CLOSED | D_LOCKED))) {
add_herecmd_menuitem(win, doopen, "Open the door"), ++K;
/* unfortunately there's no lknown flag for doors to
remember the locked/unlocked state */
key_or_pick = (carrying(SKELETON_KEY) || carrying(LOCK_PICK));
card = (carrying(CREDIT_CARD) != 0);
if (key_or_pick || card) {