Merge branch 'cheats-menu-commands' into 'master'

Put some console commands on the cheats menu

See merge request KartKrew/Kart!1435
This commit is contained in:
toaster 2023-09-01 21:30:30 +00:00
commit aa42de92e1
13 changed files with 192 additions and 97 deletions

View file

@ -332,14 +332,7 @@ void COM_ImmedExecute(const char *ptext)
// COMMAND EXECUTION
// =========================================================================
typedef struct xcommand_s
{
const char *name;
struct xcommand_s *next;
com_func_t function;
} xcommand_t;
static xcommand_t *com_commands = NULL; // current commands
xcommand_t *com_commands = NULL; // current commands
#define MAX_ARGS 80
static size_t com_argc;
@ -371,7 +364,7 @@ void COM_Init(void)
COM_AddCommand("cechoduration", COM_CEchoDuration_f);
COM_AddCommand("exec", COM_Exec_f);
COM_AddCommand("wait", COM_Wait_f);
COM_AddCommand("help", COM_Help_f);
COM_AddDebugCommand("help", COM_Help_f);
COM_AddCommand("toggle", COM_Toggle_f);
COM_AddCommand("add", COM_Add_f);
COM_AddCommand("choose", COM_Choose_f);
@ -517,7 +510,7 @@ static void COM_TokenizeString(char *ptext)
* \param name Name of the command.
* \param func Function called when the command is run.
*/
void COM_AddCommand(const char *name, com_func_t func)
xcommand_t *COM_AddCommand(const char *name, com_func_t func)
{
xcommand_t *cmd;
@ -525,7 +518,7 @@ void COM_AddCommand(const char *name, com_func_t func)
if (CV_StringValue(name)[0] != '\0')
{
I_Error("%s is a variable name\n", name);
return;
return NULL;
}
// fail if the command already exists
@ -540,15 +533,25 @@ void COM_AddCommand(const char *name, com_func_t func)
if (cmd->function != COM_Lua_f)
I_Error("Command %s already exists\n", name);
return;
return NULL;
}
}
cmd = ZZ_Alloc(sizeof *cmd);
cmd->name = name;
cmd->function = func;
cmd->debug = false;
cmd->next = com_commands;
com_commands = cmd;
return cmd;
}
void COM_AddDebugCommand(const char *name, com_func_t func)
{
xcommand_t *cmd = COM_AddCommand(name, func);
cmd->debug = true;
}
/** Adds a console command for Lua.
@ -579,6 +582,7 @@ int COM_AddLuaCommand(const char *name)
cmd = ZZ_Alloc(sizeof *cmd);
cmd->name = name;
cmd->function = COM_Lua_f;
cmd->debug = false;
cmd->next = com_commands;
com_commands = cmd;
return 0;

View file

@ -44,7 +44,18 @@ enum
typedef void (*com_func_t)(void);
void COM_AddCommand(const char *name, com_func_t func);
struct xcommand_t
{
const char *name;
xcommand_t *next;
com_func_t function;
boolean debug;
};
extern xcommand_t *com_commands; // current commands
xcommand_t *COM_AddCommand(const char *name, com_func_t func);
void COM_AddDebugCommand(const char *name, com_func_t func);
int COM_AddLuaCommand(const char *name);
size_t COM_Argc(void);
@ -129,6 +140,7 @@ typedef enum
// used on menus
CV_CHEAT = 2048, // Don't let this be used in multiplayer unless cheats are on.
CV_NOLUA = 4096,/* don't let this be called from Lua */
CV_ADDEDBYLUA = 8192,
} cvflags_t;
struct CV_PossibleValue_t

View file

@ -436,7 +436,7 @@ void CON_Init(void)
extern struct CVarList *cvlist_console;
CV_RegisterList(cvlist_console);
}
COM_AddCommand("bind", CONS_Bind_f);
COM_AddDebugCommand("bind", CONS_Bind_f);
}
else
{

View file

@ -1445,9 +1445,9 @@ void D_SRB2Main(void)
// Do this up here so that WADs loaded through the command line can use ExecCfg
COM_Init();
COM_AddCommand("assert", Command_assert);
COM_AddDebugCommand("assert", Command_assert);
#ifdef DEVELOP
COM_AddCommand("crash", Command_crash);
COM_AddDebugCommand("crash", Command_crash);
#endif
#ifndef TESTERS

View file

@ -379,27 +379,27 @@ void D_RegisterServerCommands(void)
COM_AddCommand("serverchangeteam", Command_ServerTeamChange_f);
RegisterNetXCmd(XD_CLEARSCORES, Got_Clearscores);
COM_AddCommand("clearscores", Command_Clearscores_f);
COM_AddDebugCommand("clearscores", Command_Clearscores_f);
COM_AddCommand("map", Command_Map_f);
COM_AddCommand("randommap", Command_RandomMap);
COM_AddDebugCommand("randommap", Command_RandomMap);
COM_AddCommand("restartlevel", Command_RestartLevel);
COM_AddCommand("queuemap", Command_QueueMap_f);
COM_AddCommand("exitgame", Command_ExitGame_f);
COM_AddCommand("retry", Command_Retry_f);
COM_AddCommand("exitlevel", Command_ExitLevel_f);
COM_AddCommand("showmap", Command_Showmap_f);
COM_AddDebugCommand("showmap", Command_Showmap_f);
COM_AddCommand("mapmd5", Command_Mapmd5_f);
COM_AddCommand("addfile", Command_Addfile);
COM_AddCommand("listwad", Command_ListWADS_f);
COM_AddCommand("listmapthings", Command_ListDoomednums_f);
COM_AddDebugCommand("listwad", Command_ListWADS_f);
COM_AddDebugCommand("listmapthings", Command_ListDoomednums_f);
COM_AddCommand("runsoc", Command_RunSOC);
COM_AddCommand("pause", Command_Pause);
COM_AddCommand("gametype", Command_ShowGametype_f);
COM_AddCommand("version", Command_Version_f);
COM_AddDebugCommand("gametype", Command_ShowGametype_f);
COM_AddDebugCommand("version", Command_Version_f);
#ifdef UPDATE_ALERT
COM_AddCommand("mod_details", Command_ModDetails_f);
#endif
@ -408,17 +408,17 @@ void D_RegisterServerCommands(void)
COM_AddCommand("saveconfig", Command_SaveConfig_f);
COM_AddCommand("loadconfig", Command_LoadConfig_f);
COM_AddCommand("changeconfig", Command_ChangeConfig_f);
COM_AddCommand("isgamemodified", Command_Isgamemodified_f); // test
COM_AddCommand("showscores", Command_ShowScores_f);
COM_AddCommand("showtime", Command_ShowTime_f);
COM_AddDebugCommand("isgamemodified", Command_Isgamemodified_f); // test
COM_AddDebugCommand("showscores", Command_ShowScores_f);
COM_AddDebugCommand("showtime", Command_ShowTime_f);
#ifdef _DEBUG
COM_AddCommand("togglemodified", Command_Togglemodified_f);
COM_AddCommand("archivetest", Command_Archivetest_f);
COM_AddDebugCommand("togglemodified", Command_Togglemodified_f);
COM_AddDebugCommand("archivetest", Command_Archivetest_f);
#endif
COM_AddCommand("downloads", Command_Downloads_f);
COM_AddDebugCommand("downloads", Command_Downloads_f);
COM_AddCommand("give", Command_KartGiveItem_f);
COM_AddDebugCommand("give", Command_KartGiveItem_f);
COM_AddCommand("schedule_add", Command_Schedule_Add);
COM_AddCommand("schedule_clear", Command_Schedule_Clear);
@ -426,7 +426,7 @@ void D_RegisterServerCommands(void)
COM_AddCommand("automate_set", Command_Automate_Set);
COM_AddCommand("eval", Command_Eval);
COM_AddDebugCommand("eval", Command_Eval);
COM_AddCommand("writetextmap", Command_WriteTextmap);
@ -437,15 +437,15 @@ void D_RegisterServerCommands(void)
// d_clisrv
COM_AddCommand("ping", Command_Ping_f);
COM_AddDebugCommand("ping", Command_Ping_f);
RegisterNetXCmd(XD_DISCORD, Got_DiscordInfo);
COM_AddCommand("numthinkers", Command_Numthinkers_f);
COM_AddCommand("countmobjs", Command_CountMobjs_f);
COM_AddDebugCommand("numthinkers", Command_Numthinkers_f);
COM_AddDebugCommand("countmobjs", Command_CountMobjs_f);
#ifdef _DEBUG
COM_AddCommand("causecfail", Command_CauseCfail_f);
COM_AddDebugCommand("causecfail", Command_CauseCfail_f);
#endif
#ifdef LUA_ALLOW_BYTECODE
COM_AddCommand("dumplua", Command_Dumplua_f);
@ -496,9 +496,9 @@ void D_RegisterClientCommands(void)
COM_AddCommand("stopdemo", Command_Stopdemo_f);
COM_AddCommand("playintro", Command_Playintro_f);
COM_AddCommand("resetcamera", Command_ResetCamera_f);
COM_AddDebugCommand("resetcamera", Command_ResetCamera_f);
COM_AddCommand("view", Command_View_f);
COM_AddDebugCommand("view", Command_View_f);
COM_AddCommand("view2", Command_View_f);
COM_AddCommand("view3", Command_View_f);
COM_AddCommand("view4", Command_View_f);
@ -514,43 +514,43 @@ void D_RegisterClientCommands(void)
COM_AddCommand("startmovie", Command_StartMovie_f);
COM_AddCommand("startlossless", Command_StartLossless_f);
COM_AddCommand("stopmovie", Command_StopMovie_f);
COM_AddCommand("minigen", M_MinimapGenerate);
COM_AddDebugCommand("minigen", M_MinimapGenerate);
#ifdef SRB2_CONFIG_ENABLE_WEBM_MOVIES
M_AVRecorder_AddCommands();
#endif
COM_AddCommand("displayplayer", Command_Displayplayer_f);
COM_AddDebugCommand("displayplayer", Command_Displayplayer_f);
// k_menu.c
//CV_RegisterVar(&cv_compactscoreboard);
// ingame object placing
COM_AddCommand("objectplace", Command_ObjectPlace_f);
COM_AddDebugCommand("objectplace", Command_ObjectPlace_f);
//COM_AddCommand("writethings", Command_Writethings_f);
// CV_RegisterVar(&cv_grid);
// CV_RegisterVar(&cv_snapto);
// add cheats
COM_AddCommand("noclip", Command_CheatNoClip_f);
COM_AddCommand("god", Command_CheatGod_f);
COM_AddCommand("setrings", Command_Setrings_f);
COM_AddCommand("setspheres", Command_Setspheres_f);
COM_AddCommand("setlives", Command_Setlives_f);
COM_AddCommand("setscore", Command_Setscore_f);
COM_AddCommand("devmode", Command_Devmode_f);
COM_AddCommand("savecheckpoint", Command_Savecheckpoint_f);
COM_AddCommand("scale", Command_Scale_f);
COM_AddCommand("gravflip", Command_Gravflip_f);
COM_AddCommand("hurtme", Command_Hurtme_f);
COM_AddCommand("teleport", Command_Teleport_f);
COM_AddCommand("rteleport", Command_RTeleport_f);
COM_AddCommand("skynum", Command_Skynum_f);
COM_AddCommand("weather", Command_Weather_f);
COM_AddCommand("grayscale", Command_Grayscale_f);
COM_AddCommand("goto", Command_Goto_f);
COM_AddCommand("angle", Command_Angle_f);
COM_AddCommand("respawnat", Command_RespawnAt_f);
COM_AddDebugCommand("noclip", Command_CheatNoClip_f);
COM_AddDebugCommand("god", Command_CheatGod_f);
COM_AddDebugCommand("setrings", Command_Setrings_f);
COM_AddDebugCommand("setspheres", Command_Setspheres_f);
COM_AddDebugCommand("setlives", Command_Setlives_f);
COM_AddDebugCommand("setscore", Command_Setscore_f);
COM_AddDebugCommand("devmode", Command_Devmode_f);
COM_AddDebugCommand("savecheckpoint", Command_Savecheckpoint_f);
COM_AddDebugCommand("scale", Command_Scale_f);
COM_AddDebugCommand("gravflip", Command_Gravflip_f);
COM_AddDebugCommand("hurtme", Command_Hurtme_f);
COM_AddDebugCommand("teleport", Command_Teleport_f);
COM_AddDebugCommand("rteleport", Command_RTeleport_f);
COM_AddDebugCommand("skynum", Command_Skynum_f);
COM_AddDebugCommand("weather", Command_Weather_f);
COM_AddDebugCommand("grayscale", Command_Grayscale_f);
COM_AddDebugCommand("goto", Command_Goto_f);
COM_AddDebugCommand("angle", Command_Angle_f);
COM_AddDebugCommand("respawnat", Command_RespawnAt_f);
{
extern struct CVarList *cvlist_player;

View file

@ -6845,6 +6845,7 @@ struct int_const_s const INT_CONST[] = {
{"CV_HIDDEN",CV_HIDDEN},
{"CV_CHEAT",CV_CHEAT},
{"CV_NOLUA",CV_NOLUA},
{"CV_ADDEDBYLUA",CV_ADDEDBYLUA},
// v_video flags
{"V_NOSCALEPATCH",V_NOSCALEPATCH},

View file

@ -411,7 +411,7 @@ static int lib_cvRegisterVar(lua_State *L)
return luaL_error(L, M_GetText("Variable %s has CV_CALL without a function\n"), cvar->name);
// actually time to register it to the console now! Finally!
cvar->flags |= CV_MODIFIED;
cvar->flags |= CV_MODIFIED | CV_ADDEDBYLUA;
CV_RegisterVar(cvar);
if (cvar->flags & CV_MODIFIED)
return luaL_error(L, "failed to register cvar (probable conflict with internal variable/command names)");

View file

@ -19,22 +19,86 @@
#include "../../command.h"
#include "../../doomtype.h"
#include "../../k_hud.h"
#include "../../k_menu.h"
#include "../../screen.h"
extern "C" void COM_Lua_f(void);
using srb2::Draw;
namespace
{
enum Mode
{
kCvars,
kCommands,
kNumModes
};
const char* mode_strings[kNumModes] = {
"Options",
"Commands",
};
std::vector<menuitem_t> g_menu;
std::vector<INT32> g_menu_offsets;
int g_menu_cursors[kNumModes];
void sort_menu()
int menu_mode()
{
std::sort(g_menu.begin(), g_menu.end(),
[](menuitem_t& a, menuitem_t& b) { return std::strcmp(a.text, b.text) < 0; });
return PAUSE_CheatsDef.extra1;
}
void menu_mode(int mode)
{
g_menu_cursors[menu_mode()] = itemOn;
PAUSE_CheatsDef.extra1 = mode;
itemOn = g_menu_cursors[menu_mode()];
}
void list_cvars()
{
for (consvar_t* var = consvar_vars; var; var = var->next)
{
if (!(var->flags & (CV_CHEAT | CV_ADDEDBYLUA)))
{
continue;
}
UINT16 status = IT_STRING | IT_CVAR;
INT32 height = 8;
if (!var->PossibleValue && !(var->flags & CV_FLOAT))
{
status |= IT_CV_STRING;
height += 16;
}
g_menu.push_back(menuitem_t {status, var->name, var->description, nullptr, {.cvar = var}, 0, height});
}
}
void list_commands()
{
static const auto call = [](INT32 idx) { COM_ImmedExecute(currentMenu->menuitems[idx].text); };
for (xcommand_t* cmd = com_commands; cmd; cmd = cmd->next)
{
if (!(cmd->debug || cmd->function == COM_Lua_f))
{
continue;
}
g_menu.push_back(menuitem_t {IT_STRING | IT_CALL, cmd->name, nullptr, nullptr, {.routine = call}, 0, 8});
}
}
void group_menu()
{
int old_key = '\0';
// Can't use range-for because iterators are invalidated
@ -73,26 +137,21 @@ void menu_open()
g_menu = {};
g_menu_offsets = {};
for (consvar_t* var = consvar_vars; var; var = var->next)
switch (menu_mode())
{
if (!(var->flags & CV_CHEAT))
{
continue;
}
case kCvars:
list_cvars();
break;
UINT16 status = IT_STRING | IT_CVAR;
INT32 height = 8;
if (!var->PossibleValue && !(var->flags & CV_FLOAT))
{
status |= IT_CV_STRING;
height += 16;
}
g_menu.push_back(menuitem_t {status, var->name, nullptr, nullptr, {.cvar = var}, 0, height});
case kCommands:
list_commands();
break;
}
sort_menu();
std::sort(g_menu.begin(), g_menu.end(),
[](menuitem_t& a, menuitem_t& b) { return std::strcmp(a.text, b.text) < 0; });
group_menu();
INT32 y = 0;
@ -117,26 +176,43 @@ boolean menu_close()
return true;
}
boolean menu_input(INT32)
{
// C button: cycle through modes
if (M_MenuButtonPressed(0, MBT_Y))
{
menu_mode((menu_mode() + 1) % kNumModes);
// reload menu
menu_open();
}
return false;
}
void draw_menu()
{
auto tooltip = Draw(0, 0);
constexpr int kMargin = 4;
tooltip.patch("MENUHINT");
Draw draw = Draw(0, 0).align(Draw::Align::kCenter);
draw.patch("MENUHINT");
const menuitem_t& item = currentMenu->menuitems[itemOn];
if (const consvar_t* cvar = item.itemaction.cvar; cvar && cvar->description)
if (item.tooltip)
{
tooltip.xy(BASEVIDWIDTH/2, 12).font(Draw::Font::kThin).align(Draw::Align::kCenter).text(cvar->description);
draw.xy(BASEVIDWIDTH/2, 12).font(Draw::Font::kThin).text(item.tooltip);
}
draw = draw.y(27 + kMargin);
constexpr int kTooltipHeight = 27;
constexpr int kPad = 4;
int y = tooltip.y() + kTooltipHeight + kPad;
draw.x(BASEVIDWIDTH/2).font(Draw::Font::kGamemode).text(mode_strings[menu_mode()]);
K_drawButton((draw.x() + 8) * FRACUNIT, (draw.y() + 8) * FRACUNIT, 0, kp_button_y[0], M_MenuButtonHeld(0, MBT_Y));
draw = draw.y(32 + kMargin);
currentMenu->y = std::min(y, (BASEVIDHEIGHT/2) - g_menu_offsets[itemOn]);
currentMenu->y = std::min(static_cast<int>(draw.y()), (BASEVIDHEIGHT/2) - g_menu_offsets[itemOn]);
V_SetClipRect(0, y * FRACUNIT, BASEVIDWIDTH * FRACUNIT, (BASEVIDHEIGHT - y - kPad) * FRACUNIT, 0);
V_SetClipRect(0, draw.y() * FRACUNIT, BASEVIDWIDTH * FRACUNIT, (BASEVIDHEIGHT - draw.y() - kMargin) * FRACUNIT, 0);
M_DrawGenericMenu();
V_ClearClipRect();
}
@ -149,7 +225,7 @@ menu_t PAUSE_CheatsDef = {
0,
nullptr,
48, 0,
0, 0,
kCvars, 0,
MBF_SOUNDLESS,
nullptr,
0, 0,
@ -157,5 +233,5 @@ menu_t PAUSE_CheatsDef = {
nullptr,
menu_open,
menu_close,
nullptr,
menu_input,
};

View file

@ -1643,5 +1643,5 @@ void R_RegisterEngineStuff(void)
// debugging
COM_AddCommand("debugrender_highlight", Command_Debugrender_highlight);
COM_AddDebugCommand("debugrender_highlight", Command_Debugrender_highlight);
}

View file

@ -190,11 +190,11 @@ void S_RegisterSoundStuff(void)
return;
}
COM_AddCommand("tunes", Command_Tunes_f);
COM_AddCommand("restartaudio", Command_RestartAudio_f);
COM_AddCommand("playsound", Command_PlaySound);
COM_AddDebugCommand("tunes", Command_Tunes_f);
COM_AddDebugCommand("restartaudio", Command_RestartAudio_f);
COM_AddDebugCommand("playsound", Command_PlaySound);
RegisterNetXCmd(XD_PLAYSOUND, Got_PlaySound);
COM_AddCommand("musicdef", Command_MusicDef_f);
COM_AddDebugCommand("musicdef", Command_MusicDef_f);
}
void SetChannelsNum(void);

View file

@ -32,6 +32,7 @@ TYPEDEF (minigen_t);
TYPEDEF (vsbuf_t);
TYPEDEF (CV_PossibleValue_t);
TYPEDEF (consvar_t);
TYPEDEF (xcommand_t);
// d_netcmd.h
TYPEDEF (changeteam_packet_t);

View file

@ -148,6 +148,7 @@ public:
constexpr Chain() {}
explicit Chain(float x, float y) : x_(x), y_(y) {}
Chain(const Chain&) = default;
Chain& operator=(const Chain&) = default;
struct Clipper
{

View file

@ -108,8 +108,8 @@ void Z_Init(void)
CONS_Printf("System memory: %uMB - Free: %uMB\n", total>>20, memfree);
// Note: This allocates memory. Watch out.
COM_AddCommand("memfree", Command_Memfree_f);
COM_AddCommand("memdump", Command_Memdump_f);
COM_AddDebugCommand("memfree", Command_Memfree_f);
COM_AddDebugCommand("memdump", Command_Memdump_f);
}