mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 05:51:20 +00:00
Externalized default key bindings
This commit is contained in:
parent
62d036a63e
commit
c36222d2ef
9 changed files with 191 additions and 226 deletions
200
src/c_bind.cpp
200
src/c_bind.cpp
|
@ -43,158 +43,11 @@
|
||||||
#include "configfile.h"
|
#include "configfile.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "d_event.h"
|
#include "d_event.h"
|
||||||
|
#include "w_wad.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
/* Default keybindings for Doom (and all other games)
|
|
||||||
*/
|
|
||||||
static const FBinding DefBindings[] =
|
|
||||||
{
|
|
||||||
{ "`", "toggleconsole" },
|
|
||||||
{ "1", "slot 1" },
|
|
||||||
{ "2", "slot 2" },
|
|
||||||
{ "3", "slot 3" },
|
|
||||||
{ "4", "slot 4" },
|
|
||||||
{ "5", "slot 5" },
|
|
||||||
{ "6", "slot 6" },
|
|
||||||
{ "7", "slot 7" },
|
|
||||||
{ "8", "slot 8" },
|
|
||||||
{ "9", "slot 9" },
|
|
||||||
{ "0", "slot 0" },
|
|
||||||
{ "[", "invprev" },
|
|
||||||
{ "]", "invnext" },
|
|
||||||
{ "mwheelleft", "invprev" },
|
|
||||||
{ "mwheelright", "invnext" },
|
|
||||||
{ "enter", "invuse" },
|
|
||||||
{ "-", "sizedown" },
|
|
||||||
{ "=", "sizeup" },
|
|
||||||
{ "ctrl", "+attack" },
|
|
||||||
{ "alt", "+strafe" },
|
|
||||||
{ "shift", "+speed" },
|
|
||||||
{ "space", "+use" },
|
|
||||||
{ "rightarrow", "+right" },
|
|
||||||
{ "leftarrow", "+left" },
|
|
||||||
{ "uparrow", "+forward" },
|
|
||||||
{ "downarrow", "+back" },
|
|
||||||
{ ",", "+moveleft" },
|
|
||||||
{ ".", "+moveright" },
|
|
||||||
{ "mouse1", "+attack" },
|
|
||||||
{ "mouse2", "+strafe" },
|
|
||||||
{ "mouse3", "+forward" },
|
|
||||||
{ "mouse4", "+speed" },
|
|
||||||
{ "capslock", "toggle cl_run" },
|
|
||||||
{ "f1", "menu_help" },
|
|
||||||
{ "f2", "menu_save" },
|
|
||||||
{ "f3", "menu_load" },
|
|
||||||
{ "f4", "menu_options" },
|
|
||||||
{ "f5", "menu_display" },
|
|
||||||
{ "f6", "quicksave" },
|
|
||||||
{ "f7", "menu_endgame" },
|
|
||||||
{ "f8", "togglemessages" },
|
|
||||||
{ "f9", "quickload" },
|
|
||||||
{ "f11", "bumpgamma" },
|
|
||||||
{ "f10", "menu_quit" },
|
|
||||||
{ "tab", "togglemap" },
|
|
||||||
{ "pause", "pause" },
|
|
||||||
{ "sysrq", "screenshot" },
|
|
||||||
{ "t", "messagemode" },
|
|
||||||
{ "\\", "+showscores" },
|
|
||||||
{ "f12", "spynext" },
|
|
||||||
{ "mwheeldown", "weapnext" },
|
|
||||||
{ "mwheelup", "weapprev" },
|
|
||||||
|
|
||||||
// Generic joystick buttons
|
|
||||||
{ "joy1", "+attack" },
|
|
||||||
{ "joy2", "+strafe" },
|
|
||||||
{ "joy3", "+speed" },
|
|
||||||
{ "joy4", "+use" },
|
|
||||||
|
|
||||||
// Xbox 360 / PS2 controllers
|
|
||||||
{ "pad_a", "+use" },
|
|
||||||
{ "pad_y", "+jump" },
|
|
||||||
{ "rtrigger", "+attack" },
|
|
||||||
{ "ltrigger", "+altattack" },
|
|
||||||
{ "lshoulder", "weapprev" },
|
|
||||||
{ "rshoulder", "weapnext" },
|
|
||||||
{ "dpadleft", "invprev" },
|
|
||||||
{ "dpadright", "invnext" },
|
|
||||||
{ "dpaddown", "invuse" },
|
|
||||||
{ "dpadup", "togglemap" },
|
|
||||||
{ "pad_start", "pause" },
|
|
||||||
{ "pad_back", "menu_main" },
|
|
||||||
{ "lthumb", "crouch" },
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const FBinding DefRavenBindings[] =
|
|
||||||
{
|
|
||||||
{ "pgup", "+moveup" },
|
|
||||||
{ "ins", "+movedown" },
|
|
||||||
{ "home", "land" },
|
|
||||||
{ "pgdn", "+lookup" },
|
|
||||||
{ "del", "+lookdown" },
|
|
||||||
{ "end", "centerview" },
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const FBinding DefHereticBindings[] =
|
|
||||||
{
|
|
||||||
{ "backspace", "use ArtiTomeOfPower" },
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const FBinding DefHexenBindings[] =
|
|
||||||
{
|
|
||||||
{ "/", "+jump" },
|
|
||||||
{ "backspace", "invuseall" },
|
|
||||||
{ "\\", "use ArtiHealth" },
|
|
||||||
{ "0", "useflechette" },
|
|
||||||
{ "9", "use ArtiBlastRadius" },
|
|
||||||
{ "8", "use ArtiTeleport" },
|
|
||||||
{ "7", "use ArtiTeleportOther" },
|
|
||||||
{ "6", "use ArtiPork" },
|
|
||||||
{ "5", "use ArtiInvulnerability2" },
|
|
||||||
{ "scroll", "+showscores" },
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const FBinding DefStrifeBindings[] =
|
|
||||||
{
|
|
||||||
{ "a", "+jump" },
|
|
||||||
{ "w", "showpop 1" },
|
|
||||||
{ "backspace", "invdrop" },
|
|
||||||
{ "z", "showpop 3" },
|
|
||||||
{ "k", "showpop 2" },
|
|
||||||
{ "q", "invquery" },
|
|
||||||
{ NULL, NULL }
|
|
||||||
// not done
|
|
||||||
// h - use health
|
|
||||||
};
|
|
||||||
|
|
||||||
static const FBinding DefAutomapBindings[] =
|
|
||||||
{
|
|
||||||
{ "f", "am_togglefollow" },
|
|
||||||
{ "g", "am_togglegrid" },
|
|
||||||
{ "p", "am_toggletexture" },
|
|
||||||
{ "m", "am_setmark" },
|
|
||||||
{ "c", "am_clearmarks" },
|
|
||||||
{ "0", "am_gobig" },
|
|
||||||
{ "rightarrow", "+am_panright" },
|
|
||||||
{ "leftarrow", "+am_panleft" },
|
|
||||||
{ "uparrow", "+am_panup" },
|
|
||||||
{ "downarrow", "+am_pandown" },
|
|
||||||
{ "-", "+am_zoomout" },
|
|
||||||
{ "=", "+am_zoomin" },
|
|
||||||
{ "kp-", "+am_zoomout" },
|
|
||||||
{ "kp+", "+am_zoomin" },
|
|
||||||
{ "mwheelup", "am_zoom 1.2" },
|
|
||||||
{ "mwheeldown", "am_zoom -1.2" },
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *KeyNames[NUM_KEYS] =
|
const char *KeyNames[NUM_KEYS] =
|
||||||
{
|
{
|
||||||
// This array is dependant on the particular keyboard input
|
// This array is dependant on the particular keyboard input
|
||||||
|
@ -452,21 +305,6 @@ void FKeyBindings::DoBind (const char *key, const char *bind)
|
||||||
//
|
//
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
void FKeyBindings::SetBinds(const FBinding *binds)
|
|
||||||
{
|
|
||||||
while (binds->Key)
|
|
||||||
{
|
|
||||||
DoBind (binds->Key, binds->Bind);
|
|
||||||
binds++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//=============================================================================
|
|
||||||
|
|
||||||
void FKeyBindings::UnbindAll ()
|
void FKeyBindings::UnbindAll ()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NUM_KEYS; ++i)
|
for (int i = 0; i < NUM_KEYS; ++i)
|
||||||
|
@ -785,29 +623,37 @@ CCMD (rebind)
|
||||||
|
|
||||||
void C_BindDefaults ()
|
void C_BindDefaults ()
|
||||||
{
|
{
|
||||||
Bindings.SetBinds (DefBindings);
|
int lump, lastlump = 0;
|
||||||
|
|
||||||
if (gameinfo.gametype & (GAME_Raven|GAME_Strife))
|
while ((lump = Wads.FindLump("DEFBINDS", &lastlump)) != -1)
|
||||||
{
|
{
|
||||||
Bindings.SetBinds (DefRavenBindings);
|
FScanner sc(lump);
|
||||||
}
|
|
||||||
|
|
||||||
if (gameinfo.gametype == GAME_Heretic)
|
while (sc.GetString())
|
||||||
{
|
{
|
||||||
Bindings.SetBinds (DefHereticBindings);
|
FKeyBindings *dest = &Bindings;
|
||||||
}
|
int key;
|
||||||
|
|
||||||
if (gameinfo.gametype == GAME_Hexen)
|
// bind destination is optional and is the same as the console command
|
||||||
|
if (sc.Compare("bind"))
|
||||||
{
|
{
|
||||||
Bindings.SetBinds (DefHexenBindings);
|
sc.MustGetString();
|
||||||
}
|
}
|
||||||
|
else if (sc.Compare("doublebind"))
|
||||||
if (gameinfo.gametype == GAME_Strife)
|
|
||||||
{
|
{
|
||||||
Bindings.SetBinds (DefStrifeBindings);
|
dest = &DoubleBindings;
|
||||||
|
sc.MustGetString();
|
||||||
|
}
|
||||||
|
else if (sc.Compare("mapbind"))
|
||||||
|
{
|
||||||
|
dest = &AutomapBindings;
|
||||||
|
sc.MustGetString();
|
||||||
|
}
|
||||||
|
key = GetConfigKeyFromName(sc.String);
|
||||||
|
sc.MustGetString();
|
||||||
|
dest->SetBind(key, sc.String);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AutomapBindings.SetBinds(DefAutomapBindings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CCMD(binddefaults)
|
CCMD(binddefaults)
|
||||||
|
|
|
@ -42,19 +42,12 @@ class FCommandLine;
|
||||||
|
|
||||||
void C_NameKeys (char *str, int first, int second);
|
void C_NameKeys (char *str, int first, int second);
|
||||||
|
|
||||||
struct FBinding
|
|
||||||
{
|
|
||||||
const char *Key;
|
|
||||||
const char *Bind;
|
|
||||||
};
|
|
||||||
|
|
||||||
class FKeyBindings
|
class FKeyBindings
|
||||||
{
|
{
|
||||||
FString Binds[NUM_KEYS];
|
FString Binds[NUM_KEYS];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void PerformBind(FCommandLine &argv, const char *msg);
|
void PerformBind(FCommandLine &argv, const char *msg);
|
||||||
void SetBinds(const FBinding *binds);
|
|
||||||
bool DoKey(event_t *ev);
|
bool DoKey(event_t *ev);
|
||||||
void ArchiveBindings(FConfigFile *F, const char *matchcmd = NULL);
|
void ArchiveBindings(FConfigFile *F, const char *matchcmd = NULL);
|
||||||
int GetKeysForCommand (const char *cmd, int *first, int *second);
|
int GetKeysForCommand (const char *cmd, int *first, int *second);
|
||||||
|
|
|
@ -2324,6 +2324,8 @@ void D_DoomMain (void)
|
||||||
allwads.ShrinkToFit();
|
allwads.ShrinkToFit();
|
||||||
SetMapxxFlag();
|
SetMapxxFlag();
|
||||||
|
|
||||||
|
GameConfig->DoKeySetup(gameinfo.ConfigName);
|
||||||
|
|
||||||
// Now that wads are loaded, define mod-specific cvars.
|
// Now that wads are loaded, define mod-specific cvars.
|
||||||
ParseCVarInfo();
|
ParseCVarInfo();
|
||||||
|
|
||||||
|
|
|
@ -244,9 +244,6 @@ void FGameConfigFile::MigrateStub (const char *pathname, FConfigFile *config, vo
|
||||||
|
|
||||||
void FGameConfigFile::MigrateOldConfig ()
|
void FGameConfigFile::MigrateOldConfig ()
|
||||||
{
|
{
|
||||||
// Set default key bindings. These will be overridden
|
|
||||||
// by the bindings in the config file if it exists.
|
|
||||||
C_SetDefaultBindings ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGameConfigFile::DoGlobalSetup ()
|
void FGameConfigFile::DoGlobalSetup ()
|
||||||
|
@ -400,41 +397,6 @@ void FGameConfigFile::DoGameSetup (const char *gamename)
|
||||||
ReadCVars (0);
|
ReadCVars (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bMigrating)
|
|
||||||
{
|
|
||||||
C_SetDefaultBindings ();
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy (subsection, "Bindings", sublen);
|
|
||||||
if (SetSection (section))
|
|
||||||
{
|
|
||||||
Bindings.UnbindAll();
|
|
||||||
while (NextInSection (key, value))
|
|
||||||
{
|
|
||||||
Bindings.DoBind (key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy (subsection, "DoubleBindings", sublen);
|
|
||||||
if (SetSection (section))
|
|
||||||
{
|
|
||||||
DoubleBindings.UnbindAll();
|
|
||||||
while (NextInSection (key, value))
|
|
||||||
{
|
|
||||||
DoubleBindings.DoBind (key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy (subsection, "AutomapBindings", sublen);
|
|
||||||
if (SetSection (section))
|
|
||||||
{
|
|
||||||
AutomapBindings.UnbindAll();
|
|
||||||
while (NextInSection (key, value))
|
|
||||||
{
|
|
||||||
AutomapBindings.DoBind (key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy (subsection, "ConsoleAliases", sublen);
|
strncpy (subsection, "ConsoleAliases", sublen);
|
||||||
if (SetSection (section))
|
if (SetSection (section))
|
||||||
{
|
{
|
||||||
|
@ -455,6 +417,38 @@ void FGameConfigFile::DoGameSetup (const char *gamename)
|
||||||
OkayToWrite = true;
|
OkayToWrite = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Moved from DoGameSetup so that it can happen after wads are loaded
|
||||||
|
void FGameConfigFile::DoKeySetup(const char *gamename)
|
||||||
|
{
|
||||||
|
static const struct { const char *label; FKeyBindings *bindings; } binders[] =
|
||||||
|
{
|
||||||
|
{ "Bindings", &Bindings },
|
||||||
|
{ "DoubleBindings", &DoubleBindings },
|
||||||
|
{ "AutomapBindings", &AutomapBindings },
|
||||||
|
};
|
||||||
|
const char *key, *value;
|
||||||
|
|
||||||
|
sublen = countof(section) - 1 - mysnprintf(section, countof(section), "%s.", gamename);
|
||||||
|
subsection = section + countof(section) - sublen - 1;
|
||||||
|
section[countof(section) - 1] = '\0';
|
||||||
|
|
||||||
|
C_SetDefaultBindings ();
|
||||||
|
|
||||||
|
for (int i = 0; i < countof(binders); ++i)
|
||||||
|
{
|
||||||
|
strncpy(subsection, binders[i].label, sublen);
|
||||||
|
if (SetSection(section))
|
||||||
|
{
|
||||||
|
FKeyBindings *bindings = binders[i].bindings;
|
||||||
|
bindings->UnbindAll();
|
||||||
|
while (NextInSection(key, value))
|
||||||
|
{
|
||||||
|
bindings->DoBind(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Like DoGameSetup(), but for mod-specific cvars.
|
// Like DoGameSetup(), but for mod-specific cvars.
|
||||||
// Called after CVARINFO has been parsed.
|
// Called after CVARINFO has been parsed.
|
||||||
void FGameConfigFile::DoModSetup(const char *gamename)
|
void FGameConfigFile::DoModSetup(const char *gamename)
|
||||||
|
|
|
@ -47,6 +47,7 @@ public:
|
||||||
|
|
||||||
void DoGlobalSetup ();
|
void DoGlobalSetup ();
|
||||||
void DoGameSetup (const char *gamename);
|
void DoGameSetup (const char *gamename);
|
||||||
|
void DoKeySetup (const char *gamename);
|
||||||
void DoModSetup (const char *gamename);
|
void DoModSetup (const char *gamename);
|
||||||
void ArchiveGlobalData ();
|
void ArchiveGlobalData ();
|
||||||
void ArchiveGameData (const char *gamename);
|
void ArchiveGameData (const char *gamename);
|
||||||
|
|
103
wadsrc/static/defbinds.txt
Normal file
103
wadsrc/static/defbinds.txt
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
/* Default keybindings for all games */
|
||||||
|
|
||||||
|
` toggleconsole
|
||||||
|
1 "slot 1"
|
||||||
|
2 "slot 2"
|
||||||
|
3 "slot 3"
|
||||||
|
4 "slot 4"
|
||||||
|
5 "slot 5"
|
||||||
|
6 "slot 6"
|
||||||
|
7 "slot 7"
|
||||||
|
8 "slot 8"
|
||||||
|
9 "slot 9"
|
||||||
|
0 "slot 0"
|
||||||
|
[ invprev
|
||||||
|
] invnext
|
||||||
|
mwheelleft invprev
|
||||||
|
mwheelright invnext
|
||||||
|
enter invuse
|
||||||
|
- sizedown
|
||||||
|
= sizeup
|
||||||
|
ctrl +attack
|
||||||
|
alt +strafe
|
||||||
|
shift +speed
|
||||||
|
space +use
|
||||||
|
rightarrow +right
|
||||||
|
leftarrow +left
|
||||||
|
uparrow +forward
|
||||||
|
downarrow +back
|
||||||
|
, +moveleft
|
||||||
|
. +moveright
|
||||||
|
mouse1 +attack
|
||||||
|
mouse2 +strafe
|
||||||
|
mouse3 +forward
|
||||||
|
mouse4 +speed
|
||||||
|
capslock "toggle cl_run"
|
||||||
|
f1 menu_help
|
||||||
|
f2 menu_save
|
||||||
|
f3 menu_load
|
||||||
|
f4 menu_options
|
||||||
|
f5 menu_display
|
||||||
|
f6 quicksave
|
||||||
|
f7 menu_endgame
|
||||||
|
f8 togglemessages
|
||||||
|
f9 quickload
|
||||||
|
f11 bumpgamma
|
||||||
|
f10 menu_quit
|
||||||
|
tab togglemap
|
||||||
|
pause pause
|
||||||
|
sysrq screenshot
|
||||||
|
t messagemode
|
||||||
|
\ +showscores
|
||||||
|
f12 spynext
|
||||||
|
mwheeldown weapnext
|
||||||
|
mwheelup weapprev
|
||||||
|
|
||||||
|
// Originally just for Heretic, Hexen, and Strife.
|
||||||
|
// I can't see why they shouldn't be for Doom or Chex either.
|
||||||
|
pgup +moveup
|
||||||
|
ins +movedown
|
||||||
|
home land
|
||||||
|
pgdn +lookup
|
||||||
|
del +lookdown
|
||||||
|
end centerview
|
||||||
|
|
||||||
|
// Generic joystick buttons
|
||||||
|
joy1 +attack
|
||||||
|
joy2 +strafe
|
||||||
|
joy3 +speed
|
||||||
|
joy4 +use
|
||||||
|
|
||||||
|
// Xbox 360 / PS2 controllers
|
||||||
|
pad_a +use
|
||||||
|
pad_y +jump
|
||||||
|
rtrigger +attack
|
||||||
|
ltrigger +altattack
|
||||||
|
lshoulder weapprev
|
||||||
|
rshoulder weapnext
|
||||||
|
dpadleft invprev
|
||||||
|
dpadright invnext
|
||||||
|
dpaddown invuse
|
||||||
|
dpadup togglemap
|
||||||
|
pad_start pause
|
||||||
|
pad_back menu_main
|
||||||
|
lthumb crouch
|
||||||
|
|
||||||
|
|
||||||
|
/* Default automap bindings */
|
||||||
|
mapbind f am_togglefollow
|
||||||
|
mapbind g am_togglegrid
|
||||||
|
mapbind p am_toggletexture
|
||||||
|
mapbind m am_setmark
|
||||||
|
mapbind c am_clearmarks
|
||||||
|
mapbind 0 am_gobig
|
||||||
|
mapbind rightarrow +am_panright
|
||||||
|
mapbind leftarrow +am_panleft
|
||||||
|
mapbind uparrow +am_panup
|
||||||
|
mapbind downarrow +am_pandown
|
||||||
|
mapbind - +am_zoomout
|
||||||
|
mapbind = +am_zoomin
|
||||||
|
mapbind kp- +am_zoomout
|
||||||
|
mapbind kp+ +am_zoomin
|
||||||
|
mapbind mwheelup "am_zoom 1.2"
|
||||||
|
mapbind mwheeldown "am_zoom -1.2"
|
3
wadsrc/static/filter/game-heretic/defbinds.txt
Normal file
3
wadsrc/static/filter/game-heretic/defbinds.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
/* Default keybindings for Heretic */
|
||||||
|
|
||||||
|
backspace "use ArtiTomeOfPower"
|
12
wadsrc/static/filter/game-hexen/defbinds.txt
Normal file
12
wadsrc/static/filter/game-hexen/defbinds.txt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/* Default keybindings for Hexen */
|
||||||
|
|
||||||
|
/ +jump
|
||||||
|
backspace invuseall
|
||||||
|
\ "use ArtiHealth"
|
||||||
|
0 useflechette
|
||||||
|
9 "use ArtiBlastRadius"
|
||||||
|
8 "use ArtiTeleport"
|
||||||
|
7 "use ArtiTeleportOther"
|
||||||
|
6 "use ArtiPork"
|
||||||
|
5 "use ArtiInvulnerability2"
|
||||||
|
scroll +showscores
|
11
wadsrc/static/filter/game-strife/defbinds.txt
Normal file
11
wadsrc/static/filter/game-strife/defbinds.txt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
/* Default keybindings for Strife */
|
||||||
|
|
||||||
|
a +jump
|
||||||
|
w "showpop 1"
|
||||||
|
backspace invdrop
|
||||||
|
z "showpop 3"
|
||||||
|
k "showpop 2"
|
||||||
|
q invquery
|
||||||
|
|
||||||
|
; not done
|
||||||
|
; h - use health
|
Loading…
Reference in a new issue