fix github issue #426 - binding special commands

Binding 'repeat' (DOAGAIN, or redo) to a different key than ^A
didn't work as intended because the code that used it was
checking for DOAGAIN (a key value from config.h) instead of
g.Cmd.spkeys[NHKF_DOAGAIN] (the key currently bound to repeat).

Contrary to the github issue, re-bound prefix keys worked ok for
me if followed by a direction.  However, they behaved strangely
if followed by anything else.  If the keystroke was stolen from
some other command and that command hadn't been bound to another
key, following the prefix with a non-direction could end up
executing the command that used to own the key.  For example,
 BIND=d:nopickup
to use 'd' to move without auto-pickup would work if you used
d<direction> but if you used d<something-else> if would execute
the drop command.

The NHKF_REQMENU prefix could be bound to some key other than
'm' but it only worked as intended if the new key was a movement
prefix.

This also makes DOAGAIN be unconditional.  If it is deleted or
commented out in config.h, the default binding will be '\000' so
unusable (freeing up ^A for something), but still be available
to be bound to some key (perhaps even ^A).

This also includes an unrelated change to mdlib.c.  The comments
added to config.h will force a full rebuild.  Changing mdlib.c
now rather than separately will avoid forcing that twice.

Fixes #426
This commit is contained in:
PatR
2020-12-25 13:57:05 -08:00
parent 1a2afd21d4
commit 0ec355bdb4
5 changed files with 75 additions and 28 deletions

View File

@@ -814,7 +814,8 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) :
QSignalMapper* sm = new QSignalMapper(this);
connect(sm, SIGNAL(mapped(const QString&)),
this, SLOT(doKeys(const QString&)));
// 'donull' is a placeholder here; AddToolButton() will fix it up
// 'donull' is a placeholder here; AddToolButton() will fix it up;
// button will be omitted if DOAGAIN is bound to '\0'
AddToolButton(toolbar, sm, "Again", donull, QPixmap(again_xpm));
// this used to be called "Get" which is confusing to experienced players
AddToolButton(toolbar, sm, "Pick up", dopickup, QPixmap(pickup_xpm));
@@ -888,20 +889,29 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) :
}
}
// add a toolbar button to invoke command 'name' via function '(*func)()'
void NetHackQtMainWindow::AddToolButton(QToolBar *toolbar, QSignalMapper *sm,
const char *name, int NDECL((*func)),
QPixmap xpm)
{
QToolButton *tb = new SmallToolButton(xpm, QString(name), "Action",
sm, SLOT(map()), toolbar);
char actchar[32];
char actchar[2];
uchar key;
// the ^A command is just a keystroke, not a full blown command function
if (!strcmp(name, "Again"))
(void) strkitten(actchar, ::g.Cmd.spkeys[NHKF_DOAGAIN]);
else
Sprintf(actchar, "%c", cmd_from_func(func));
sm->setMapping(tb, actchar);
toolbar->addWidget(tb);
if (!strcmp(name, "Again")) {
key = ::g.Cmd.spkeys[NHKF_DOAGAIN];
} else
key = (uchar) cmd_from_func(func);
// if key is valid, add a button for it; otherwise omit the command
// (won't work as intended if a different command is bound to same key)
if (key) {
QToolButton *tb = new SmallToolButton(xpm, QString(name), "Action",
sm, SLOT(map()), toolbar);
actchar[0] = '\0';
sm->setMapping(tb, strkitten(actchar, (char) key));
toolbar->addWidget(tb);
}
}
void NetHackQtMainWindow::zoomMap()