Merge branch 'cheats-menu' into 'cvar-reorganization'

Cheats menu on the pause menu

See merge request KartKrew/Kart!1424
This commit is contained in:
Oni 2023-08-26 02:34:42 +00:00
commit d2021560e5
8 changed files with 231 additions and 33 deletions

View file

@ -66,7 +66,7 @@ static boolean CV_Command(void);
consvar_t *CV_FindVar(const char *name);
static const char *CV_StringValue(const char *var_name);
static consvar_t *consvar_vars; // list of registered console variables
consvar_t *consvar_vars; // list of registered console variables
static UINT16 consvar_number_of_netids = 0;
static char com_token[1024];

View file

@ -144,6 +144,7 @@ struct consvar_t //NULL, NULL, 0, NULL, NULL |, 0, NULL, NULL, 0, 0, NULL
INT32 flags; // flags see cvflags_t above
CV_PossibleValue_t *PossibleValue; // table of possible values
void (*func)(void); // called on change, if CV_CALL set
const char *description;
INT32 value; // for INT32 and fixed_t
const char *string; // value in string
char *zstring; // Either NULL or same as string.
@ -204,9 +205,11 @@ struct CVarList;
#define CVAR_INIT consvar_t
#else
#define CVAR_INIT( ... ) \
{ __VA_ARGS__, 0, NULL, NULL, {0, {NULL}}, 0U, (char)0, NULL }
{ __VA_ARGS__, NULL, 0, NULL, NULL, {0, {NULL}}, 0U, (char)0, NULL }
#endif
extern consvar_t *consvar_vars; // list of registered console variables
extern CV_PossibleValue_t CV_OnOff[];
extern CV_PossibleValue_t CV_YesNo[];
extern CV_PossibleValue_t CV_Unsigned[];

View file

@ -86,6 +86,12 @@ struct consvar_t::Builder
return builder;
}
Builder& description(const char* description)
{
var_.description = description;
return *this;
}
Builder& save()
{
var_.flags |= CV_SAVE;
@ -757,43 +763,43 @@ consvar_t cv_votetime = UnsavedNetVar("votetime", "20").min_max(10, 3600);
// Cheats don't save...
//
consvar_t cv_battletest = OnlineCheat("battletest", "Off").on_off();
consvar_t cv_battletest = OnlineCheat("battletest", "Off").on_off().description("Free Play goes to Battle instead of Prisons");
#ifdef DEVELOP
consvar_t cv_botcontrol = OnlineCheat("botcontrol", "On").on_off();
consvar_t cv_botcontrol = OnlineCheat("botcontrol", "On").on_off().description("Toggle bot AI movement");
#endif
extern CV_PossibleValue_t capsuletest_cons_t[];
void CapsuleTest_OnChange(void);
consvar_t cv_capsuletest = OnlineCheat("capsuletest", "Off").values(capsuletest_cons_t).onchange(CapsuleTest_OnChange);
consvar_t cv_capsuletest = OnlineCheat("capsuletest", "Off").values(capsuletest_cons_t).onchange(CapsuleTest_OnChange).description("Force item capsule spawning rules");
consvar_t cv_debugencorevote = OnlineCheat("debugencorevote", "Off").on_off();
consvar_t cv_debugencorevote = OnlineCheat("debugencorevote", "Off").on_off().description("Force encore choice to appear on vote screen");
void ForceSkin_OnChange(void);
consvar_t cv_forceskin = OnlineCheat("forcecharacter", "None").onchange(ForceSkin_OnChange);
consvar_t cv_forceskin = OnlineCheat("forcecharacter", "None").onchange(ForceSkin_OnChange).description("Force all players to use one character");
consvar_t cv_kartdebugamount = OnlineCheat("debugitemamount", "1").min_max(1, 255);
consvar_t cv_kartdebugbots = OnlineCheat("debugbots", "Off").on_off();
consvar_t cv_kartdebugdistribution = OnlineCheat("debugitemodds", "Off").on_off();
consvar_t cv_kartdebughuddrop = OnlineCheat("debugitemdrop", "Off").on_off();
consvar_t cv_kartdebugamount = OnlineCheat("debugitemamount", "1").min_max(1, 255).description("If debugitem, give multiple copies of an item");
consvar_t cv_kartdebugbots = OnlineCheat("debugbots", "Off").on_off().description("Bot AI debugger");
consvar_t cv_kartdebugdistribution = OnlineCheat("debugitemodds", "Off").on_off().description("Show items that the roulette can roll");
consvar_t cv_kartdebughuddrop = OnlineCheat("debugitemdrop", "Off").on_off().description("Players drop paper items when damaged in any way");
extern CV_PossibleValue_t kartdebugitem_cons_t[];
consvar_t cv_kartdebugitem = OnlineCheat("debugitem", "None").values(kartdebugitem_cons_t);
consvar_t cv_kartdebugitem = OnlineCheat("debugitem", "None").values(kartdebugitem_cons_t).description("Force item boxes to only roll one kind of item");
consvar_t cv_kartdebugstart = OnlineCheat("debugstart", "Off").on_off();
consvar_t cv_kartdebugwaypoints = OnlineCheat("debugwaypoints", "Off").values({{0, "Off"}, {1, "Forwards"}, {2, "Backwards"}});
consvar_t cv_kartdebugstart = OnlineCheat("debugstart", "Off").on_off().description("Skip POSITION");
consvar_t cv_kartdebugwaypoints = OnlineCheat("debugwaypoints", "Off").values({{0, "Off"}, {1, "Forwards"}, {2, "Backwards"}}).description("Make waypoints visible");
#ifdef DEVELOP
consvar_t cv_kartencoremap = OnlineCheat("encoremap", "On").on_off();
consvar_t cv_kartencoremap = OnlineCheat("encoremap", "On").on_off().description("Toggle Encore colormap");
#endif
extern CV_PossibleValue_t numlaps_cons_t[];
void NumLaps_OnChange(void);
consvar_t cv_numlaps = OnlineCheat("numlaps", "Map default").values(numlaps_cons_t).onchange(NumLaps_OnChange).save();
consvar_t cv_numlaps = OnlineCheat("numlaps", "Map default").values(numlaps_cons_t).onchange(NumLaps_OnChange).save().description("Race maps always have the same number of laps");
consvar_t cv_restrictskinchange = OnlineCheat("restrictskinchange", "Yes").yes_no();
consvar_t cv_spbtest = OnlineCheat("spbtest", "Off").on_off();
consvar_t cv_timescale = OnlineCheat(cvlist_timer)("timescale", "1.0").floating_point().min_max(FRACUNIT/20, 20*FRACUNIT);
consvar_t cv_restrictskinchange = OnlineCheat("restrictskinchange", "Yes").yes_no().description("Don't let players change their skin in the middle of gameplay");
consvar_t cv_spbtest = OnlineCheat("spbtest", "Off").on_off().description("SPB can never target a player");
consvar_t cv_timescale = OnlineCheat(cvlist_timer)("timescale", "1.0").floating_point().min_max(FRACUNIT/20, 20*FRACUNIT).description("Overclock or slow down the game");
//
@ -802,14 +808,14 @@ consvar_t cv_timescale = OnlineCheat(cvlist_timer)("timescale", "1.0").floating_
//
consvar_t cv_botscanvote = ServerCheat("botscanvote", "No").yes_no();
consvar_t cv_debugrank = ServerCheat("debugrank", "Off").on_off();
consvar_t cv_debugrank = ServerCheat("debugrank", "Off").on_off().description("Show GP rank state on the HUD");
void Gravity_OnChange(void);
consvar_t cv_gravity = ServerCheat("gravity", "0.8").floating_point().onchange(Gravity_OnChange); // change DEFAULT_GRAVITY if you change this
consvar_t cv_gravity = ServerCheat("gravity", "0.8").floating_point().onchange(Gravity_OnChange).description("Change the default gravity"); // change DEFAULT_GRAVITY if you change this
consvar_t cv_kartdebugcolorize = ServerCheat("debugcolorize", "Off").on_off();
consvar_t cv_kartdebugdirector = ServerCheat("debugdirector", "Off").on_off();
consvar_t cv_kartdebugnodes = ServerCheat("debugnodes", "Off").on_off();
consvar_t cv_kartdebugcolorize = ServerCheat("debugcolorize", "Off").on_off().description("Show all colorized options on the HUD");
consvar_t cv_kartdebugdirector = ServerCheat("debugdirector", "Off").on_off().description("Show director AI on the HUD");
consvar_t cv_kartdebugnodes = ServerCheat("debugnodes", "Off").on_off().description("Show player node and latency on the HUD");
//
@ -818,19 +824,19 @@ consvar_t cv_kartdebugnodes = ServerCheat("debugnodes", "Off").on_off();
// Not saved...
//
consvar_t cv_debugfinishline = PlayerCheat("debugfinishline", "Off").on_off();
consvar_t cv_debugrender_contrast = PlayerCheat("debugrender_contrast", "0.0").floating_point().min_max(-FRACUNIT, FRACUNIT);
consvar_t cv_debugrender_portal = PlayerCheat("debugrender_portal", "Off").on_off();
consvar_t cv_debugrender_spriteclip = PlayerCheat("debugrender_spriteclip", "Off").on_off();
consvar_t cv_devmode_screen = PlayerCheat("devmode_screen", "1").min_max(1, 4);
consvar_t cv_drawpickups = PlayerCheat("drawpickups", "Yes").yes_no();
consvar_t cv_debugfinishline = PlayerCheat("debugfinishline", "Off").on_off().description("Highlight finish lines and respawn lines with high contrast colors");
consvar_t cv_debugrender_contrast = PlayerCheat("debugrender_contrast", "0.0").floating_point().min_max(-FRACUNIT, FRACUNIT).description("Change level lighting");
consvar_t cv_debugrender_portal = PlayerCheat("debugrender_portal", "Off").on_off().description("Highlight visual portals in red");
consvar_t cv_debugrender_spriteclip = PlayerCheat("debugrender_spriteclip", "Off").on_off().description("Let sprites draw through walls");
consvar_t cv_devmode_screen = PlayerCheat("devmode_screen", "1").min_max(1, 4).description("Choose which splitscreen player devmode applies to");
consvar_t cv_drawpickups = PlayerCheat("drawpickups", "Yes").yes_no().description("Hide rings, spheres, item capsules, prison capsules (visual only)");
void CV_palette_OnChange(void);
consvar_t cv_palette = PlayerCheat("palette", "").onchange_noinit(CV_palette_OnChange);
consvar_t cv_palettenum = PlayerCheat("palettenum", "0").values(CV_Unsigned).onchange_noinit(CV_palette_OnChange);
consvar_t cv_palette = PlayerCheat("palette", "").onchange_noinit(CV_palette_OnChange).description("Force palette to a different lump");
consvar_t cv_palettenum = PlayerCheat("palettenum", "0").values(CV_Unsigned).onchange_noinit(CV_palette_OnChange).description("Use a different sub-palette by default");
extern CV_PossibleValue_t renderhitbox_cons_t[];
consvar_t cv_renderhitbox = PlayerCheat("renderhitbox", "Off").values(renderhitbox_cons_t);
consvar_t cv_renderhitbox = PlayerCheat("renderhitbox", "Off").values(renderhitbox_cons_t).description("Show hitboxes around objects");
//

View file

@ -462,6 +462,7 @@ typedef enum
mpause_canceljoin,
mpause_spectatemenu,
mpause_psetup,
mpause_cheats,
mpause_options,
mpause_title,

View file

@ -11,4 +11,5 @@ target_sources(SRB2SDL2 PRIVATE
pause-kick.c
pause-replay.c
virtual-keyboard.c
pause-cheats.cpp
)

View file

@ -0,0 +1,161 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2023 by James Robert Roman
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file menus/transient/pause-cheats.c
/// \brief Cheats directory, for developers
#include <algorithm>
#include <cstddef>
#include <cstring>
#include <vector>
#include "../../v_draw.hpp"
#include "../../v_video.h"
#include "../../command.h"
#include "../../doomtype.h"
#include "../../k_menu.h"
#include "../../screen.h"
using srb2::Draw;
namespace
{
std::vector<menuitem_t> g_menu;
std::vector<INT32> g_menu_offsets;
void sort_menu()
{
std::sort(g_menu.begin(), g_menu.end(),
[](menuitem_t& a, menuitem_t& b) { return std::strcmp(a.text, b.text) < 0; });
int old_key = '\0';
// Can't use range-for because iterators are invalidated
// by std::vector::insert.
for (std::size_t i = 0; i < g_menu.size(); ++i)
{
int new_key = g_menu[i].text[0];
if (new_key == old_key)
{
// Group cvars starting with the same letter
// together.
continue;
}
old_key = new_key;
if (i == 0)
{
continue;
}
constexpr int spacer = 8;
g_menu.insert(
g_menu.begin() + i,
menuitem_t {IT_SPACE | IT_DYLITLSPACE, nullptr, nullptr, nullptr, {}, spacer, spacer}
);
i++; // skip the inserted element
}
}
void menu_open()
{
g_menu = {};
g_menu_offsets = {};
for (consvar_t* var = consvar_vars; var; var = var->next)
{
if (!(var->flags & CV_CHEAT))
{
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, nullptr, nullptr, {.cvar = var}, 0, height});
}
sort_menu();
INT32 y = 0;
for (menuitem_t& item : g_menu)
{
g_menu_offsets.push_back(y);
y += item.mvar2;
}
PAUSE_CheatsDef.menuitems = g_menu.data();
PAUSE_CheatsDef.numitems = g_menu.size();
}
boolean menu_close()
{
PAUSE_CheatsDef.menuitems = nullptr;
PAUSE_CheatsDef.numitems = 0;
g_menu = {};
g_menu_offsets = {};
return true;
}
void draw_menu()
{
auto tooltip = Draw(0, 0);
tooltip.patch("MENUHINT");
const menuitem_t& item = currentMenu->menuitems[itemOn];
if (const consvar_t* cvar = item.itemaction.cvar; cvar && cvar->description)
{
tooltip.xy(BASEVIDWIDTH/2, 12).font(Draw::Font::kThin).align(Draw::Align::kCenter).text(cvar->description);
}
constexpr int kTooltipHeight = 27;
constexpr int kPad = 4;
int y = tooltip.y() + kTooltipHeight + kPad;
currentMenu->y = std::min(y, (BASEVIDHEIGHT/2) - g_menu_offsets[itemOn]);
V_SetClipRect(0, y * FRACUNIT, BASEVIDWIDTH * FRACUNIT, (BASEVIDHEIGHT - y - kPad) * FRACUNIT, 0);
M_DrawGenericMenu();
V_ClearClipRect();
}
}; // namespace
menu_t PAUSE_CheatsDef = {
0,
&PAUSE_MainDef,
0,
nullptr,
48, 0,
0, 0,
MBF_SOUNDLESS,
nullptr,
0, 0,
draw_menu,
nullptr,
menu_open,
menu_close,
nullptr,
};

View file

@ -64,6 +64,9 @@ menuitem_t PAUSE_Main[] =
{IT_STRING | IT_CALL, "PLAYER SETUP", "M_ICOCHR",
NULL, {.routine = M_CharacterSelect}, 0, 0},
{IT_STRING | IT_SUBMENU, "CHEATS", "M_ICOCHT",
NULL, {.submenu = &PAUSE_CheatsDef}, 0, 0},
{IT_STRING | IT_CALL, "OPTIONS", "M_ICOOPT",
NULL, {.routine = M_InitOptions}, 0, 0},
@ -135,6 +138,7 @@ void M_OpenPauseMenu(void)
PAUSE_Main[mpause_canceljoin].status = IT_DISABLED;
PAUSE_Main[mpause_spectatemenu].status = IT_DISABLED;
PAUSE_Main[mpause_psetup].status = IT_DISABLED;
PAUSE_Main[mpause_cheats].status = IT_DISABLED;
Dummymenuplayer_OnChange(); // Make sure the consvar is within bounds of the amount of splitscreen players we have.
@ -217,6 +221,11 @@ void M_OpenPauseMenu(void)
}
}
if (CV_CheatsEnabled())
{
PAUSE_Main[mpause_cheats].status = IT_STRING | IT_SUBMENU;
}
G_ResetAllDeviceRumbles();
}

View file

@ -990,6 +990,8 @@ void V_DrawBlock(INT32 x, INT32 y, INT32 scrn, INT32 width, INT32 height, const
//
void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
{
const cliprect_t *clip = V_GetClipRect();
if (rendermode == render_none)
return;
@ -1051,6 +1053,21 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
UINT8 g = (color.rgba & 0xFF00) >> 8;
UINT8 b = (color.rgba & 0xFF0000) >> 16;
if (clip && clip->enabled)
{
int x2 = std::min(x + w, clip->right);
int y2 = std::min(y + h, clip->bottom);
if (x < clip->left)
x = clip->left;
if (y < clip->top)
y = clip->top;
w = std::max(0, x2 - x);
h = std::max(0, y2 - y);
}
g_2d.begin_quad()
.patch(nullptr)
.color(r / 255.f, g / 255.f, b / 255.f, 1.f)