fix #H5462 - failed F-attack gives misleading msg
Report was for 'F' followed by '.' reporting "cmdassist: Invalid
direction key!" and then by a direction grid (which happened to
include '.' for self). That behavior applied for all the movement
prefix keys ('m', 'G', &c). When 'cmdassist' was off, "F." would
yield "Unknown command 'F.'." instead.
Now you'll get "You can't fight yourself.", either instead of the
"invalid direction key" part of cmdassist feedback (followed by a
direction grid which excludes up, down, and self since they aren't
applicable for prefix keys) or of the "unknown command" result.
Likewise, "You can't run upward." or "You can't rush downward."
for "G<" and "g>", respectively.
This commit is contained in:
@@ -380,6 +380,8 @@ levitation vs encumbrance message sequencing issues: putting on boots of
|
|||||||
of encumbrance until player took another action
|
of encumbrance until player took another action
|
||||||
removing a blindfold with 'A' took two turns, with 'R' (and 'T') only one,
|
removing a blindfold with 'A' took two turns, with 'R' (and 'T') only one,
|
||||||
and could result in a panic if the blindfold was stolen during removal
|
and could result in a panic if the blindfold was stolen during removal
|
||||||
|
cmdassist help for movement prefix followed by invalid direction was strange
|
||||||
|
when the direction was up, down, or self disallowed for that prefix
|
||||||
|
|
||||||
|
|
||||||
Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository
|
Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository
|
||||||
|
|||||||
182
src/cmd.c
182
src/cmd.c
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.6 cmd.c $NHDT-Date: 1494034344 2017/05/06 01:32:24 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.256 $ */
|
/* NetHack 3.6 cmd.c $NHDT-Date: 1494976933 2017/05/16 23:22:13 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.257 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -184,8 +184,8 @@ static const char *readchar_queue = "";
|
|||||||
static coord clicklook_cc;
|
static coord clicklook_cc;
|
||||||
|
|
||||||
STATIC_DCL char *NDECL(parse);
|
STATIC_DCL char *NDECL(parse);
|
||||||
STATIC_DCL void FDECL(show_direction_keys, (winid, BOOLEAN_P));
|
STATIC_DCL void FDECL(show_direction_keys, (winid, CHAR_P, BOOLEAN_P));
|
||||||
STATIC_DCL boolean FDECL(help_dir, (CHAR_P, const char *));
|
STATIC_DCL boolean FDECL(help_dir, (CHAR_P, int, const char *));
|
||||||
|
|
||||||
STATIC_PTR int
|
STATIC_PTR int
|
||||||
doprev_message(VOID_ARGS)
|
doprev_message(VOID_ARGS)
|
||||||
@@ -3073,7 +3073,11 @@ dokeylist(VOID_ARGS)
|
|||||||
boolean keys_used[256] = {0};
|
boolean keys_used[256] = {0};
|
||||||
winid datawin;
|
winid datawin;
|
||||||
int i;
|
int i;
|
||||||
const struct {
|
static const char
|
||||||
|
run_desc[] = "Prefix: run until something very interesting is seen",
|
||||||
|
forcefight_desc[] =
|
||||||
|
"Prefix: force fight even if you don't see a monster";
|
||||||
|
static const struct {
|
||||||
int nhkf;
|
int nhkf;
|
||||||
const char *desc;
|
const char *desc;
|
||||||
boolean numpad;
|
boolean numpad;
|
||||||
@@ -3081,22 +3085,18 @@ dokeylist(VOID_ARGS)
|
|||||||
{ NHKF_ESC, "escape from the current query/action", FALSE },
|
{ NHKF_ESC, "escape from the current query/action", FALSE },
|
||||||
{ NHKF_RUSH,
|
{ NHKF_RUSH,
|
||||||
"Prefix: rush until something interesting is seen", FALSE },
|
"Prefix: rush until something interesting is seen", FALSE },
|
||||||
{ NHKF_RUN,
|
{ NHKF_RUN, run_desc, FALSE },
|
||||||
"Prefix: run until something extremely interesting is seen", FALSE },
|
{ NHKF_RUN2, run_desc, TRUE },
|
||||||
{ NHKF_RUN2,
|
{ NHKF_FIGHT, forcefight_desc, FALSE },
|
||||||
"Prefix: run until something extremely interesting is seen", TRUE },
|
{ NHKF_FIGHT2, forcefight_desc, TRUE } ,
|
||||||
{ NHKF_FIGHT,
|
|
||||||
"Prefix: force fight even if you don't see a monster", FALSE },
|
|
||||||
{ NHKF_FIGHT2,
|
|
||||||
"Prefix: force fight even if you don't see a monster", TRUE },
|
|
||||||
{ NHKF_NOPICKUP,
|
{ NHKF_NOPICKUP,
|
||||||
"Prefix: move without picking up objects/fighting", FALSE },
|
"Prefix: move without picking up objects/fighting", FALSE },
|
||||||
{ NHKF_RUN_NOPICKUP,
|
{ NHKF_RUN_NOPICKUP,
|
||||||
"Prefix: run without picking up objects/fighting", FALSE },
|
"Prefix: run without picking up objects/fighting", FALSE },
|
||||||
{ NHKF_DOINV, "inventory (same as #inventory)", TRUE },
|
{ NHKF_DOINV, "view inventory", TRUE },
|
||||||
{ NHKF_REQMENU, "Prefix: request a menu", FALSE },
|
{ NHKF_REQMENU, "Prefix: request a menu", FALSE },
|
||||||
#ifdef REDO
|
#ifdef REDO
|
||||||
{ NHKF_DOAGAIN , "redo the previous command", FALSE },
|
{ NHKF_DOAGAIN , "re-do: perform the previous command again", FALSE },
|
||||||
#endif
|
#endif
|
||||||
{ 0, (const char *) 0, FALSE }
|
{ 0, (const char *) 0, FALSE }
|
||||||
};
|
};
|
||||||
@@ -3108,7 +3108,7 @@ dokeylist(VOID_ARGS)
|
|||||||
/* directional keys */
|
/* directional keys */
|
||||||
putstr(datawin, 0, "");
|
putstr(datawin, 0, "");
|
||||||
putstr(datawin, 0, "Directional keys:");
|
putstr(datawin, 0, "Directional keys:");
|
||||||
show_direction_keys(datawin, FALSE);
|
show_direction_keys(datawin, '.', FALSE); /* '.'==self in direction grid */
|
||||||
|
|
||||||
keys_used[(uchar) Cmd.move_NW] = keys_used[(uchar) Cmd.move_N]
|
keys_used[(uchar) Cmd.move_NW] = keys_used[(uchar) Cmd.move_N]
|
||||||
= keys_used[(uchar) Cmd.move_NE] = keys_used[(uchar) Cmd.move_W]
|
= keys_used[(uchar) Cmd.move_NE] = keys_used[(uchar) Cmd.move_W]
|
||||||
@@ -3942,11 +3942,12 @@ int NDECL((*cmd_func));
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ch2spkeys(c, start,end)
|
ch2spkeys(c, start, end)
|
||||||
char c;
|
char c;
|
||||||
int start,end;
|
int start,end;
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = start; i <= end; i++)
|
for (i = start; i <= end; i++)
|
||||||
if (Cmd.spkeys[i] == c)
|
if (Cmd.spkeys[i] == c)
|
||||||
return i;
|
return i;
|
||||||
@@ -3957,6 +3958,7 @@ void
|
|||||||
rhack(cmd)
|
rhack(cmd)
|
||||||
register char *cmd;
|
register char *cmd;
|
||||||
{
|
{
|
||||||
|
int spkey;
|
||||||
boolean do_walk, do_rush, prefix_seen, bad_command,
|
boolean do_walk, do_rush, prefix_seen, bad_command,
|
||||||
firsttime = (cmd == 0);
|
firsttime = (cmd == 0);
|
||||||
|
|
||||||
@@ -3990,7 +3992,9 @@ register char *cmd;
|
|||||||
/* handle most movement commands */
|
/* handle most movement commands */
|
||||||
do_walk = do_rush = prefix_seen = FALSE;
|
do_walk = do_rush = prefix_seen = FALSE;
|
||||||
context.travel = context.travel1 = 0;
|
context.travel = context.travel1 = 0;
|
||||||
switch (ch2spkeys(*cmd, NHKF_RUN,NHKF_CLICKLOOK)) {
|
spkey = ch2spkeys(*cmd, NHKF_RUN, NHKF_CLICKLOOK);
|
||||||
|
|
||||||
|
switch (spkey) {
|
||||||
case NHKF_RUSH:
|
case NHKF_RUSH:
|
||||||
if (movecmd(cmd[1])) {
|
if (movecmd(cmd[1])) {
|
||||||
context.run = 2;
|
context.run = 2;
|
||||||
@@ -4161,14 +4165,13 @@ register char *cmd;
|
|||||||
|
|
||||||
if (bad_command) {
|
if (bad_command) {
|
||||||
char expcmd[20]; /* we expect 'cmd' to point to 1 or 2 chars */
|
char expcmd[20]; /* we expect 'cmd' to point to 1 or 2 chars */
|
||||||
register char c;
|
char c, c1 = cmd[1];
|
||||||
|
|
||||||
expcmd[0] = '\0';
|
expcmd[0] = '\0';
|
||||||
while ((c = *cmd++) != '\0')
|
while ((c = *cmd++) != '\0')
|
||||||
Strcat(expcmd, visctrl(c)); /* add 1..4 chars plus terminator */
|
Strcat(expcmd, visctrl(c)); /* add 1..4 chars plus terminator */
|
||||||
|
|
||||||
if (!prefix_seen || !iflags.cmdassist
|
if (!prefix_seen || !help_dir(c1, spkey, "Invalid direction key!"))
|
||||||
|| !help_dir(0, "Invalid direction key!"))
|
|
||||||
Norep("Unknown command '%s'.", expcmd);
|
Norep("Unknown command '%s'.", expcmd);
|
||||||
}
|
}
|
||||||
/* didn't move */
|
/* didn't move */
|
||||||
@@ -4319,7 +4322,8 @@ retry:
|
|||||||
if (!index(quitchars, dirsym)) {
|
if (!index(quitchars, dirsym)) {
|
||||||
help_requested = (dirsym == Cmd.spkeys[NHKF_GETDIR_HELP]);
|
help_requested = (dirsym == Cmd.spkeys[NHKF_GETDIR_HELP]);
|
||||||
if (help_requested || iflags.cmdassist) {
|
if (help_requested || iflags.cmdassist) {
|
||||||
did_help = help_dir((s && *s == '^') ? dirsym : 0,
|
did_help = help_dir((s && *s == '^') ? dirsym : '\0',
|
||||||
|
NHKF_ESC,
|
||||||
help_requested ? (const char *) 0
|
help_requested ? (const char *) 0
|
||||||
: "Invalid direction key!");
|
: "Invalid direction key!");
|
||||||
if (help_requested)
|
if (help_requested)
|
||||||
@@ -4339,61 +4343,141 @@ retry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
STATIC_OVL void
|
STATIC_OVL void
|
||||||
show_direction_keys(win, nodiag)
|
show_direction_keys(win, centerchar, nodiag)
|
||||||
winid win;
|
winid win; /* should specify a window which is using a fixed-width font... */
|
||||||
|
char centerchar; /* '.' or '@' or ' ' */
|
||||||
boolean nodiag;
|
boolean nodiag;
|
||||||
{
|
{
|
||||||
char buf[BUFSZ];
|
char buf[BUFSZ];
|
||||||
|
|
||||||
|
if (!centerchar)
|
||||||
|
centerchar = ' ';
|
||||||
|
|
||||||
if (nodiag) {
|
if (nodiag) {
|
||||||
Sprintf(buf, " %c ", Cmd.move_N);
|
Sprintf(buf, " %c ", Cmd.move_N);
|
||||||
putstr(win, 0, buf);
|
putstr(win, 0, buf);
|
||||||
putstr(win, 0, " | ");
|
putstr(win, 0, " | ");
|
||||||
Sprintf(buf, " %c- . -%c", Cmd.move_W, Cmd.move_E);
|
Sprintf(buf, " %c- %c -%c",
|
||||||
|
Cmd.move_W, centerchar, Cmd.move_E);
|
||||||
putstr(win, 0, buf);
|
putstr(win, 0, buf);
|
||||||
putstr(win, 0, " | ");
|
putstr(win, 0, " | ");
|
||||||
Sprintf(buf, " %c ", Cmd.move_S);
|
Sprintf(buf, " %c ", Cmd.move_S);
|
||||||
putstr(win, 0, buf);
|
putstr(win, 0, buf);
|
||||||
} else {
|
} else {
|
||||||
Sprintf(buf, " %c %c %c", Cmd.move_NW, Cmd.move_N,
|
Sprintf(buf, " %c %c %c",
|
||||||
Cmd.move_NE);
|
Cmd.move_NW, Cmd.move_N, Cmd.move_NE);
|
||||||
putstr(win, 0, buf);
|
putstr(win, 0, buf);
|
||||||
putstr(win, 0, " \\ | / ");
|
putstr(win, 0, " \\ | / ");
|
||||||
Sprintf(buf, " %c- . -%c", Cmd.move_W, Cmd.move_E);
|
Sprintf(buf, " %c- %c -%c",
|
||||||
|
Cmd.move_W, centerchar, Cmd.move_E);
|
||||||
putstr(win, 0, buf);
|
putstr(win, 0, buf);
|
||||||
putstr(win, 0, " / | \\ ");
|
putstr(win, 0, " / | \\ ");
|
||||||
Sprintf(buf, " %c %c %c", Cmd.move_SW, Cmd.move_S,
|
Sprintf(buf, " %c %c %c",
|
||||||
Cmd.move_SE);
|
Cmd.move_SW, Cmd.move_S, Cmd.move_SE);
|
||||||
putstr(win, 0, buf);
|
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
|
STATIC_OVL boolean
|
||||||
help_dir(sym, msg)
|
help_dir(sym, spkey, msg)
|
||||||
char sym;
|
char sym;
|
||||||
|
int spkey; /* NHKF_ code for prefix key, if one was used, or for ESC */
|
||||||
const char *msg;
|
const char *msg;
|
||||||
{
|
{
|
||||||
static const char wiz_only_list[] = "EFGIVW";
|
static const char wiz_only_list[] = "EFGIVW";
|
||||||
char ctrl;
|
char ctrl;
|
||||||
winid win;
|
winid win;
|
||||||
char buf[BUFSZ], buf2[BUFSZ], *explain;
|
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; /* else FALLTHRU */
|
||||||
|
case NHKF_RUN:
|
||||||
|
case NHKF_RUN_NOPICKUP:
|
||||||
|
dothat = "run";
|
||||||
|
break;
|
||||||
|
case NHKF_FIGHT2:
|
||||||
|
if (!Cmd.num_pad)
|
||||||
|
break; /* else 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 (*buf) {
|
||||||
|
pline("%s", buf);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
/* when 'cmdassist' is off and caller doesn't insist, do nothing */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
win = create_nhwindow(NHW_TEXT);
|
win = create_nhwindow(NHW_TEXT);
|
||||||
if (!win)
|
if (!win)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (msg) {
|
|
||||||
|
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);
|
Sprintf(buf, "cmdassist: %s", msg);
|
||||||
putstr(win, 0, buf);
|
putstr(win, 0, buf);
|
||||||
putstr(win, 0, "");
|
putstr(win, 0, "");
|
||||||
}
|
}
|
||||||
if (letter(sym) || sym == '[') { /* 'dat/cmdhelp' shows ESC as ^[ */
|
|
||||||
|
if (!prefixhandling && (letter(sym) || sym == '[')) {
|
||||||
|
/* '[': old 'cmdhelp' showed ESC as ^[ */
|
||||||
sym = highc(sym); /* @A-Z[ (note: letter() accepts '@') */
|
sym = highc(sym); /* @A-Z[ (note: letter() accepts '@') */
|
||||||
ctrl = (sym - 'A') + 1; /* 0-27 (note: 28-31 aren't applicable) */
|
ctrl = (sym - 'A') + 1; /* 0-27 (note: 28-31 aren't applicable) */
|
||||||
if ((explain = dowhatdoes_core(ctrl, buf2)) != 0
|
if ((explain = dowhatdoes_core(ctrl, buf2)) != 0
|
||||||
&& (!index(wiz_only_list, sym) || wizard)) {
|
&& (!index(wiz_only_list, sym) || wizard)) {
|
||||||
Sprintf(buf, "Are you trying to use ^%c%s?", sym,
|
Sprintf(buf, "Are you trying to use ^%c%s?", sym,
|
||||||
index(wiz_only_list, sym)
|
index(wiz_only_list, sym) ? ""
|
||||||
? ""
|
|
||||||
: " as specified in the Guidebook");
|
: " as specified in the Guidebook");
|
||||||
putstr(win, 0, buf);
|
putstr(win, 0, buf);
|
||||||
putstr(win, 0, "");
|
putstr(win, 0, "");
|
||||||
@@ -4407,17 +4491,29 @@ const char *msg;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Sprintf(buf, "Valid direction keys %sare:",
|
Sprintf(buf, "Valid direction keys%s%s%s are:",
|
||||||
NODIAG(u.umonnum) ? "in your current form " : "");
|
prefixhandling ? " to " : "", prefixhandling ? dothat : "",
|
||||||
|
NODIAG(u.umonnum) ? " in your current form" : "");
|
||||||
putstr(win, 0, buf);
|
putstr(win, 0, buf);
|
||||||
show_direction_keys(win, NODIAG(u.umonnum));
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
putstr(win, 0, "");
|
|
||||||
putstr(win, 0, " < up");
|
|
||||||
putstr(win, 0, " > down");
|
|
||||||
Sprintf(buf, " %4s direct at yourself",
|
|
||||||
visctrl(Cmd.spkeys[NHKF_GETDIR_SELF]));
|
|
||||||
putstr(win, 0, buf);
|
|
||||||
if (msg) {
|
if (msg) {
|
||||||
/* non-null msg means that this wasn't an explicit user request */
|
/* non-null msg means that this wasn't an explicit user request */
|
||||||
putstr(win, 0, "");
|
putstr(win, 0, "");
|
||||||
|
|||||||
Reference in New Issue
Block a user