Streamline cheats

"cheats" is a proper cvar now. Enabling it allows for cheats to be used any time, even in multiplayer, and disables gamedata saving. Turning it off undoes as many cheat commands as reasonably possible. Based a little bit off of some vanilla work I also did.

Many cheat commands are still SP-only, but can reasonably be allowed in netgames now if a net command is created for them.
This commit is contained in:
Sally Coolatta 2022-02-27 10:11:55 -05:00
parent 5f86c93021
commit 36b8ab1eac
22 changed files with 303 additions and 365 deletions

View file

@ -73,6 +73,15 @@ CV_PossibleValue_t CV_YesNo[] = {{0, "No"}, {1, "Yes"}, {0, NULL}};
CV_PossibleValue_t CV_Unsigned[] = {{0, "MIN"}, {999999999, "MAX"}, {0, NULL}};
CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}};
// Cheats
#ifdef DEVELOP
#define VALUE "On"
#else
#define VALUE "Off"
#endif
consvar_t cv_cheats = CVAR_INIT ("cheats", VALUE, CV_NETVAR|CV_CALL, CV_OnOff, CV_CheatsChanged);
#undef VALUE
// SRB2kart
CV_PossibleValue_t kartspeed_cons_t[] = {
{KARTSPEED_AUTO, "Auto"},
@ -336,6 +345,9 @@ void COM_Init(void)
// allocate command buffer
VS_Alloc(&com_text, COM_BUF_SIZE);
// cheats is a special cvar, so register it ASAP
CV_RegisterVar(&cv_cheats);
// add standard commands
COM_AddCommand("alias", COM_Alias_f);
COM_AddCommand("echo", COM_Echo_f);
@ -1340,12 +1352,11 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth)
boolean override = false;
INT32 overrideval = 0;
// If we want messages informing us if cheats have been enabled or disabled,
// we need to rework the consvars a little bit. This call crashes the game
// on load because not all variables will be registered at that time.
/* boolean prevcheats = false;
if (var->flags & CV_CHEAT)
prevcheats = CV_CheatsEnabled(); */
if ((var->flags & CV_CHEAT) && CV_CheatsEnabled() == false)
{
// Enforce to default value without cheats.
valstr = var->defaultvalue;
}
if (var->PossibleValue)
{
@ -1506,17 +1517,6 @@ found:
}
finish:
// See the note above.
/* if (var->flags & CV_CHEAT)
{
boolean newcheats = CV_CheatsEnabled();
if (!prevcheats && newcheats)
CONS_Printf(M_GetText("Cheats have been enabled.\n"));
else if (prevcheats && !newcheats)
CONS_Printf(M_GetText("Cheats have been disabled.\n"));
} */
if (var->flags & CV_SHOWMODIFONETIME || var->flags & CV_SHOWMODIF)
{
CONS_Printf(M_GetText("%s set to %s\n"), var->name, var->string);
@ -1526,10 +1526,13 @@ finish:
{
DEBFILE(va("%s set to %s\n", var->name, var->string));
}
var->flags |= CV_MODIFIED;
// raise 'on change' code
LUA_CVarChanged(var); // let consolelib know what cvar this is.
if (var->flags & CV_CALL && !stealth)
if ((var->flags & CV_CALL) && !stealth)
var->func();
return;
@ -1750,14 +1753,33 @@ void CV_LoadDemoVars(UINT8 **p)
static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth);
void CV_ResetCheatNetVars(void)
void CV_CheatsChanged(void)
{
consvar_t *cvar;
if (CV_CheatsEnabled())
{
G_SetUsedCheats();
}
else
{
consvar_t *cvar;
UINT8 i;
// Stealthset everything back to default.
for (cvar = consvar_vars; cvar; cvar = cvar->next)
if (cvar->flags & CV_CHEAT)
CV_SetCVar(cvar, cvar->defaultvalue, true);
// Set everything back to default.
for (cvar = consvar_vars; cvar; cvar = cvar->next)
if (cvar->flags & CV_CHEAT)
CV_SetCVar(cvar, cvar->defaultvalue, false);
// Reset any other cheat command effects here, as well.
cv_debug = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
players[i].cheats = 0;
}
}
}
// Returns true if the variable's current value is its default value
@ -1768,16 +1790,9 @@ boolean CV_IsSetToDefault(consvar_t *v)
// If any cheats CVars are not at their default settings, return true.
// Else return false.
// This returns a UINT8 because I'm too lazy to deal with the packet structure.
// Deal with it. =P
UINT8 CV_CheatsEnabled(void)
boolean CV_CheatsEnabled(void)
{
consvar_t *cvar;
for (cvar = consvar_vars; cvar; cvar = cvar->next)
if ((cvar->flags & CV_CHEAT) && strcmp(cvar->defaultvalue, cvar->string))
return 1;
return 0;
return (boolean)cv_cheats.value;
}
/** Sets a value to a variable, performing some checks and calling the

View file

@ -122,7 +122,7 @@ typedef enum
CV_NOSHOWHELP = 512, // Don't show variable in the HELP list Tails 08-13-2002
CV_HIDEN = 1024, // variable is not part of the cvar list so cannot be accessed by the console
// can only be set when we have the pointer to it
// used on menus
// 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 */
} cvflags_t;
@ -223,10 +223,10 @@ void CV_RevertNetVars(void);
void CV_LoadDemoVars(UINT8 **p);
// reset cheat netvars after cheats is deactivated
void CV_ResetCheatNetVars(void);
void CV_CheatsChanged(void);
boolean CV_IsSetToDefault(consvar_t *v);
UINT8 CV_CheatsEnabled(void);
boolean CV_CheatsEnabled(void);
// Returns cvar by name. Exposed here for Lua.
consvar_t *CV_FindVar(const char *name);

View file

@ -901,7 +901,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[gametype],
sizeof netbuffer->u.serverinfo.gametypename);
netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame;
netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled();
netbuffer->u.serverinfo.cheatsenabled = (UINT8)CV_CheatsEnabled();
netbuffer->u.serverinfo.kartvars = (UINT8) (
(gamespeed & SV_SPEEDMASK) |

View file

@ -1548,6 +1548,12 @@ void D_SRB2Main(void)
if (M_CheckParm("-noupload"))
COM_BufAddText("downloading 0\n");
if (M_CheckParm("-gamedata") && M_IsNextParm())
{
// Moved from G_LoadGameData itself, as it would cause some crazy
// confusion issues when loading mods.
strlcpy(gamedatafilename, M_GetNextParm(), sizeof gamedatafilename);
}
G_LoadGameData();
wipegamestate = gamestate;
@ -1631,7 +1637,7 @@ void D_SRB2Main(void)
{
if (!M_CheckParm("-server"))
{
G_SetGameModified(true, true);
G_SetUsedCheats();
// Start up a "minor" grand prix session
memset(&grandprixinfo, 0, sizeof(struct grandprixinfo));
@ -1842,15 +1848,16 @@ void D_SRB2Main(void)
{
// Prevent warping to nonexistent levels
if (W_CheckNumForName(G_BuildMapName(pstartmap)) == LUMPERROR)
{
I_Error("Could not warp to %s (map not found)\n", G_BuildMapName(pstartmap));
// Prevent warping to locked levels
// ... unless you're in a dedicated server. Yes, technically this means you can view any level by
// running a dedicated server and joining it yourself, but that's better than making dedicated server's
// lives hell.
else if (!dedicated && M_MapLocked(pstartmap))
I_Error("You need to unlock this level before you can warp to it!\n");
}
else
{
if (M_MapLocked(pstartmap))
{
G_SetUsedCheats();
}
D_MapChange(pstartmap, gametype, (cv_kartencore.value == 1), true, 0, false, false);
}
}

View file

@ -62,12 +62,6 @@
#include "doomstat.h"
#include "deh_tables.h"
#ifdef NETGAME_DEVMODE
#define CV_RESTRICT CV_NETVAR
#else
#define CV_RESTRICT 0
#endif
#ifdef HAVE_DISCORDRPC
#include "discord.h"
#endif
@ -148,10 +142,6 @@ static void KartEncore_OnChange(void);
static void KartComeback_OnChange(void);
static void KartEliminateLast_OnChange(void);
#ifdef NETGAME_DEVMODE
static void Fishcake_OnChange(void);
#endif
static void Command_Playdemo_f(void);
static void Command_Timedemo_f(void);
static void Command_Stopdemo_f(void);
@ -213,7 +203,6 @@ static void Command_ShowScores_f(void);
static void Command_ShowTime_f(void);
static void Command_Isgamemodified_f(void);
static void Command_Cheats_f(void);
#ifdef _DEBUG
static void Command_Togglemodified_f(void);
static void Command_Archivetest_f(void);
@ -245,9 +234,6 @@ static CV_PossibleValue_t pause_cons_t[] = {{0, "Server"}, {1, "All"}, {0, NULL}
consvar_t cv_showinputjoy = CVAR_INIT ("showinputjoy", "Off", 0, CV_OnOff, NULL);
#ifdef NETGAME_DEVMODE
static consvar_t cv_fishcake = CVAR_INIT ("fishcake", "Off", CV_CALL|CV_NOSHOWHELP|CV_RESTRICT, CV_OnOff, Fishcake_OnChange);
#endif
static consvar_t cv_dummyconsvar = CVAR_INIT ("dummyconsvar", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, DummyConsvar_OnChange);
consvar_t cv_restrictskinchange = CVAR_INIT ("restrictskinchange", "No", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL);
@ -341,35 +327,35 @@ consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS] = { //Alam: Dummy for save
#endif
// SRB2kart
consvar_t cv_superring = CVAR_INIT ("superring", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_sneaker = CVAR_INIT ("sneaker", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_rocketsneaker = CVAR_INIT ("rocketsneaker", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_invincibility = CVAR_INIT ("invincibility", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_banana = CVAR_INIT ("banana", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_eggmanmonitor = CVAR_INIT ("eggmanmonitor", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_orbinaut = CVAR_INIT ("orbinaut", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_jawz = CVAR_INIT ("jawz", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_mine = CVAR_INIT ("mine", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_landmine = CVAR_INIT ("landmine", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_droptarget = CVAR_INIT ("droptarget", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_ballhog = CVAR_INIT ("ballhog", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_selfpropelledbomb = CVAR_INIT ("selfpropelledbomb", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_grow = CVAR_INIT ("grow", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_shrink = CVAR_INIT ("shrink", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_lightningshield = CVAR_INIT ("lightningshield", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_bubbleshield = CVAR_INIT ("bubbleshield", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_flameshield = CVAR_INIT ("flameshield", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_hyudoro = CVAR_INIT ("hyudoro", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_pogospring = CVAR_INIT ("pogospring", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_kitchensink = CVAR_INIT ("kitchensink", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_superring = CVAR_INIT ("superring", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_sneaker = CVAR_INIT ("sneaker", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_rocketsneaker = CVAR_INIT ("rocketsneaker", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_invincibility = CVAR_INIT ("invincibility", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_banana = CVAR_INIT ("banana", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_eggmanmonitor = CVAR_INIT ("eggmanmonitor", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_orbinaut = CVAR_INIT ("orbinaut", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_jawz = CVAR_INIT ("jawz", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_mine = CVAR_INIT ("mine", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_landmine = CVAR_INIT ("landmine", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_droptarget = CVAR_INIT ("droptarget", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_ballhog = CVAR_INIT ("ballhog", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_selfpropelledbomb = CVAR_INIT ("selfpropelledbomb", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_grow = CVAR_INIT ("grow", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_shrink = CVAR_INIT ("shrink", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_lightningshield = CVAR_INIT ("lightningshield", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_bubbleshield = CVAR_INIT ("bubbleshield", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_flameshield = CVAR_INIT ("flameshield", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_hyudoro = CVAR_INIT ("hyudoro", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_pogospring = CVAR_INIT ("pogospring", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_kitchensink = CVAR_INIT ("kitchensink", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_dualsneaker = CVAR_INIT ("dualsneaker", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_triplesneaker = CVAR_INIT ("triplesneaker", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_triplebanana = CVAR_INIT ("triplebanana", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_decabanana = CVAR_INIT ("decabanana", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_tripleorbinaut = CVAR_INIT ("tripleorbinaut", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_quadorbinaut = CVAR_INIT ("quadorbinaut", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_dualjawz = CVAR_INIT ("dualjawz", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_dualsneaker = CVAR_INIT ("dualsneaker", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_triplesneaker = CVAR_INIT ("triplesneaker", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_triplebanana = CVAR_INIT ("triplebanana", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_decabanana = CVAR_INIT ("decabanana", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_tripleorbinaut = CVAR_INIT ("tripleorbinaut", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_quadorbinaut = CVAR_INIT ("quadorbinaut", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_dualjawz = CVAR_INIT ("dualjawz", "On", CV_NETVAR, CV_OnOff, NULL);
static CV_PossibleValue_t kartminimap_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}};
consvar_t cv_kartminimap = CVAR_INIT ("kartminimap", "4", CV_SAVE, kartminimap_cons_t, NULL);
@ -378,9 +364,9 @@ static CV_PossibleValue_t kartinvinsfx_cons_t[] = {{0, "Music"}, {1, "SFX"}, {0,
consvar_t cv_kartinvinsfx = CVAR_INIT ("kartinvinsfx", "SFX", CV_SAVE, kartinvinsfx_cons_t, NULL);
consvar_t cv_kartspeed = CVAR_INIT ("kartspeed", "Auto", CV_NETVAR|CV_CALL|CV_NOINIT, kartspeed_cons_t, KartSpeed_OnChange);
static CV_PossibleValue_t kartbumpers_cons_t[] = {{1, "MIN"}, {12, "MAX"}, {0, NULL}};
consvar_t cv_kartbumpers = CVAR_INIT ("kartbumpers", "3", CV_NETVAR|CV_CHEAT, kartbumpers_cons_t, NULL);
consvar_t cv_kartfrantic = CVAR_INIT ("kartfrantic", "Off", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartFrantic_OnChange);
consvar_t cv_kartcomeback = CVAR_INIT ("kartcomeback", "On", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartComeback_OnChange);
consvar_t cv_kartbumpers = CVAR_INIT ("kartbumpers", "3", CV_NETVAR, kartbumpers_cons_t, NULL);
consvar_t cv_kartfrantic = CVAR_INIT ("kartfrantic", "Off", CV_NETVAR|CV_CALL|CV_NOINIT, CV_OnOff, KartFrantic_OnChange);
consvar_t cv_kartcomeback = CVAR_INIT ("kartcomeback", "On", CV_NETVAR|CV_CALL|CV_NOINIT, CV_OnOff, KartComeback_OnChange);
static CV_PossibleValue_t kartencore_cons_t[] = {{-1, "Auto"}, {0, "Off"}, {1, "On"}, {0, NULL}};
consvar_t cv_kartencore = CVAR_INIT ("kartencore", "Auto", CV_NETVAR|CV_CALL|CV_NOINIT, kartencore_cons_t, KartEncore_OnChange);
static CV_PossibleValue_t kartvoterulechanges_cons_t[] = {{0, "Never"}, {1, "Sometimes"}, {2, "Frequent"}, {3, "Always"}, {0, NULL}};
@ -409,9 +395,9 @@ static CV_PossibleValue_t kartbot_cons_t[] = {
};
consvar_t cv_kartbot = CVAR_INIT ("kartbot", "0", CV_NETVAR, kartbot_cons_t, NULL);
consvar_t cv_karteliminatelast = CVAR_INIT ("karteliminatelast", "Yes", CV_NETVAR|CV_CHEAT|CV_CALL, CV_YesNo, KartEliminateLast_OnChange);
consvar_t cv_karteliminatelast = CVAR_INIT ("karteliminatelast", "Yes", CV_NETVAR|CV_CALL, CV_YesNo, KartEliminateLast_OnChange);
consvar_t cv_kartusepwrlv = CVAR_INIT ("kartusepwrlv", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL);
consvar_t cv_kartusepwrlv = CVAR_INIT ("kartusepwrlv", "Yes", CV_NETVAR, CV_YesNo, NULL);
static CV_PossibleValue_t kartdebugitem_cons_t[] =
{
@ -420,37 +406,30 @@ static CV_PossibleValue_t kartdebugitem_cons_t[] =
#undef FOREACH
{0}
};
consvar_t cv_kartdebugitem = CVAR_INIT ("kartdebugitem", "0", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugitem_cons_t, NULL);
consvar_t cv_kartdebugitem = CVAR_INIT ("kartdebugitem", "0", CV_NETVAR|CV_CHEAT, kartdebugitem_cons_t, NULL);
static CV_PossibleValue_t kartdebugamount_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}};
consvar_t cv_kartdebugamount = CVAR_INIT ("kartdebugamount", "1", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugamount_cons_t, NULL);
#ifdef DEVELOP
#define VALUE "Yes"
#else
#define VALUE "No"
#endif
consvar_t cv_kartallowgiveitem = CVAR_INIT ("kartallowgiveitem", VALUE, CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_YesNo, NULL);
#undef VALUE
consvar_t cv_kartdebugamount = CVAR_INIT ("kartdebugamount", "1", CV_NETVAR|CV_CHEAT, kartdebugamount_cons_t, NULL);
consvar_t cv_kartdebugdistribution = CVAR_INIT ("kartdebugdistribution", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
consvar_t cv_kartdebughuddrop = CVAR_INIT ("kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
consvar_t cv_kartdebugdistribution = CVAR_INIT ("kartdebugdistribution", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_kartdebughuddrop = CVAR_INIT ("kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
static CV_PossibleValue_t kartdebugwaypoint_cons_t[] = {{0, "Off"}, {1, "Forwards"}, {2, "Backwards"}, {0, NULL}};
consvar_t cv_kartdebugwaypoints = CVAR_INIT ("kartdebugwaypoints", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugwaypoint_cons_t, NULL);
consvar_t cv_kartdebugbotpredict = CVAR_INIT ("kartdebugbotpredict", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
consvar_t cv_kartdebugwaypoints = CVAR_INIT ("kartdebugwaypoints", "Off", CV_NETVAR|CV_CHEAT, kartdebugwaypoint_cons_t, NULL);
consvar_t cv_kartdebugbotpredict = CVAR_INIT ("kartdebugbotpredict", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_kartdebugcheckpoint = CVAR_INIT ("kartdebugcheckpoint", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
consvar_t cv_kartdebugnodes = CVAR_INIT ("kartdebugnodes", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
consvar_t cv_kartdebugcolorize = CVAR_INIT ("kartdebugcolorize", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
consvar_t cv_kartdebugdirector = CVAR_INIT ("kartdebugdirector", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
consvar_t cv_kartdebugcheckpoint = CVAR_INIT ("kartdebugcheckpoint", "Off", CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_kartdebugnodes = CVAR_INIT ("kartdebugnodes", "Off", CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_kartdebugcolorize = CVAR_INIT ("kartdebugcolorize", "Off", CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_kartdebugdirector = CVAR_INIT ("kartdebugdirector", "Off", CV_CHEAT, CV_OnOff, NULL);
static CV_PossibleValue_t votetime_cons_t[] = {{10, "MIN"}, {3600, "MAX"}, {0, NULL}};
consvar_t cv_votetime = CVAR_INIT ("votetime", "20", CV_NETVAR, votetime_cons_t, NULL);
consvar_t cv_gravity = CVAR_INIT ("gravity", "0.8", CV_RESTRICT|CV_FLOAT|CV_CALL, NULL, Gravity_OnChange); // change DEFAULT_GRAVITY if you change this
consvar_t cv_gravity = CVAR_INIT ("gravity", "0.8", CV_CHEAT|CV_FLOAT|CV_CALL, NULL, Gravity_OnChange); // change DEFAULT_GRAVITY if you change this
consvar_t cv_soundtest = CVAR_INIT ("soundtest", "0", CV_CALL, NULL, SoundTest_OnChange);
static CV_PossibleValue_t minitimelimit_cons_t[] = {{15, "MIN"}, {9999, "MAX"}, {0, NULL}};
consvar_t cv_countdowntime = CVAR_INIT ("countdowntime", "30", CV_NETVAR|CV_CHEAT, minitimelimit_cons_t, NULL);
consvar_t cv_countdowntime = CVAR_INIT ("countdowntime", "30", CV_NETVAR, minitimelimit_cons_t, NULL);
consvar_t cv_autobalance = CVAR_INIT ("autobalance", "Off", CV_SAVE|CV_NETVAR|CV_CALL, CV_OnOff, AutoBalance_OnChange);
consvar_t cv_teamscramble = CVAR_INIT ("teamscramble", "Off", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, teamscramble_cons_t, TeamScramble_OnChange);
@ -459,7 +438,7 @@ consvar_t cv_scrambleonchange = CVAR_INIT ("scrambleonchange", "Off", CV_SAVE|CV
consvar_t cv_itemfinder = CVAR_INIT ("itemfinder", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, ItemFinder_OnChange);
// Scoring type options
consvar_t cv_overtime = CVAR_INIT ("overtime", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL);
consvar_t cv_overtime = CVAR_INIT ("overtime", "Yes", CV_NETVAR, CV_YesNo, NULL);
consvar_t cv_rollingdemos = CVAR_INIT ("rollingdemos", "On", CV_SAVE, CV_OnOff, NULL);
@ -470,7 +449,7 @@ consvar_t cv_timelimit = CVAR_INIT ("timelimit", "None", CV_SAVE|CV_NETVAR|CV_CA
static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}};
consvar_t cv_numlaps = CVAR_INIT ("numlaps", "3", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t, NumLaps_OnChange);
static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, "Map default"}, {0, NULL}};
consvar_t cv_basenumlaps = CVAR_INIT ("basenumlaps", "Map default", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange);
consvar_t cv_basenumlaps = CVAR_INIT ("basenumlaps", "Map default", CV_SAVE|CV_NETVAR|CV_CALL, basenumlaps_cons_t, BaseNumLaps_OnChange);
// Point and time limits for every gametype
INT32 pointlimits[NUMGAMETYPES];
@ -671,7 +650,6 @@ void D_RegisterServerCommands(void)
COM_AddCommand("isgamemodified", Command_Isgamemodified_f); // test
COM_AddCommand("showscores", Command_ShowScores_f);
COM_AddCommand("showtime", Command_ShowTime_f);
COM_AddCommand("cheats", Command_Cheats_f); // test
#ifdef _DEBUG
COM_AddCommand("togglemodified", Command_Togglemodified_f);
COM_AddCommand("archivetest", Command_Archivetest_f);
@ -883,10 +861,6 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_netstat);
CV_RegisterVar(&cv_netticbuffer);
#ifdef NETGAME_DEVMODE
CV_RegisterVar(&cv_fishcake);
#endif
// HUD
CV_RegisterVar(&cv_itemfinder);
CV_RegisterVar(&cv_showinputjoy);
@ -2577,7 +2551,8 @@ static void Command_Map_f(void)
const char *gametypename;
boolean newresetplayers;
boolean mustmodifygame;
boolean usingcheats;
boolean ischeating;
INT32 newmapnum;
@ -2601,20 +2576,8 @@ static void Command_Map_f(void)
option_skill = COM_CheckPartialParm("-s");
newresetplayers = ! COM_CheckParm("-noresetplayers");
mustmodifygame = !(netgame || multiplayer) && !majormods;
if (mustmodifygame && !option_force)
{
/* May want to be more descriptive? */
CONS_Printf(M_GetText("Sorry, level change disabled in single player.\n"));
return;
}
if (!newresetplayers && !cv_debug)
{
CONS_Printf(M_GetText("DEVMODE must be enabled.\n"));
return;
}
usingcheats = CV_CheatsEnabled();
ischeating = (!(netgame || multiplayer)) || (!newresetplayers);
if (option_gametype)
{
@ -2657,9 +2620,15 @@ static void Command_Map_f(void)
return;
}
if (mustmodifygame && option_force)
if (M_MapLocked(newmapnum))
{
G_SetGameModified(multiplayer, true);
ischeating = true;
}
if (ischeating && !usingcheats)
{
CONS_Printf(M_GetText("Cheats must be enabled.\n"));
return;
}
// new gametype value
@ -2716,7 +2685,7 @@ static void Command_Map_f(void)
{
newencoremode = !newencoremode;
if (!M_SecretUnlocked(SECRET_ENCORE) && newencoremode == true && !option_force)
if (!M_SecretUnlocked(SECRET_ENCORE) && newencoremode == true && !usingcheats)
{
CONS_Alert(CONS_NOTICE, M_GetText("You haven't unlocked Encore Mode yet!\n"));
return;
@ -2728,10 +2697,12 @@ static void Command_Map_f(void)
// don't use a gametype the map doesn't support
if (cv_debug || option_force || cv_skipmapcheck.value)
{
fromlevelselect = false; // The player wants us to trek on anyway. Do so.
// G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer
}
else
{
// G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer
if (!(
mapheaderinfo[newmapnum-1] &&
mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype)
@ -2829,18 +2800,6 @@ static void Command_Map_f(void)
}
}
// Prevent warping to locked levels
// ... unless you're in a dedicated server. Yes, technically this means you can view any level by
// running a dedicated server and joining it yourself, but that's better than making dedicated server's
// lives hell.
if (!dedicated && M_MapLocked(newmapnum))
{
CONS_Alert(CONS_NOTICE, M_GetText("You need to unlock this level before you can warp to it!\n"));
Z_Free(realmapname);
Z_Free(mapname);
return;
}
if (tutorialmode && tutorialgcs)
{
G_CopyControls(gamecontrol[0], gamecontroldefault[0][gcs_custom], gcl_full, num_gcl_full); // using gcs_custom as temp storage
@ -4625,23 +4584,12 @@ void D_GameTypeChanged(INT32 lastgametype)
static void Gravity_OnChange(void)
{
if (!M_SecretUnlocked(SECRET_PANDORA) && !netgame && !cv_debug
&& strcmp(cv_gravity.string, cv_gravity.defaultvalue))
if (netgame)
{
CONS_Printf(M_GetText("You haven't earned this yet.\n"));
CV_StealthSet(&cv_gravity, cv_gravity.defaultvalue);
// TODO: multiplayer support
return;
}
#ifndef NETGAME_GRAVITY
if(netgame)
{
CV_StealthSet(&cv_gravity, cv_gravity.defaultvalue);
return;
}
#endif
if (!CV_IsSetToDefault(&cv_gravity))
G_SetGameModified(multiplayer, true);
gravity = cv_gravity.value;
}
@ -4860,7 +4808,7 @@ static void Command_Mapmd5_f(void)
static void Command_ExitLevel_f(void)
{
if (!(netgame || multiplayer) && !cv_debug)
if (!(netgame || multiplayer) && !CV_CheatsEnabled())
CONS_Printf(M_GetText("This only works in a netgame.\n"));
else if (!(server || (IsPlayerAdmin(consoleplayer))))
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
@ -4953,7 +4901,7 @@ static void Got_GiveItemcmd(UINT8 **cp, INT32 playernum)
amt = READUINT8 (*cp);
if (
( netgame && ! cv_kartallowgiveitem.value ) ||
( !CV_CheatsEnabled() ) ||
( item < KITEM_SAD || item >= NUMKARTITEMS )
)
{
@ -5052,23 +5000,6 @@ void Command_Retry_f(void)
}
}
#ifdef NETGAME_DEVMODE
// Allow the use of devmode in netgames.
static void Fishcake_OnChange(void)
{
cv_debug = cv_fishcake.value;
// consvar_t's get changed to default when registered
// so don't make modifiedgame always on!
if (cv_debug)
{
G_SetGameModified(multiplayer, true);
}
else if (cv_debug != cv_fishcake.value)
CV_SetValue(&cv_fishcake, cv_debug);
}
#endif
/** Reports to the console whether or not the game has been modified.
*
* \todo Make it obvious, so a console command won't be necessary.
@ -5087,27 +5018,6 @@ static void Command_Isgamemodified_f(void)
CONS_Printf("The game has not been modified. You can play Record Attack, earn medals and unlock extras.\n");
}
static void Command_Cheats_f(void)
{
if (COM_CheckParm("off"))
{
if (!(server || (IsPlayerAdmin(consoleplayer))))
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
else
CV_ResetCheatNetVars();
return;
}
if (CV_CheatsEnabled())
{
CONS_Printf(M_GetText("At least one CHEAT-marked variable has been changed -- Cheats are enabled.\n"));
if (server || (IsPlayerAdmin(consoleplayer)))
CONS_Printf(M_GetText("Type CHEATS OFF to reset all cheat variables to default.\n"));
}
else
CONS_Printf(M_GetText("No CHEAT-marked variables are changed -- Cheats are disabled.\n"));
}
#ifdef _DEBUG
static void Command_Togglemodified_f(void)
{
@ -5160,8 +5070,6 @@ static void Command_Archivetest_f(void)
#endif
/** Give yourself an, optional quantity or one of, an item.
*
* \sa cv_kartallowgiveitem
*/
static void Command_KartGiveItem_f(void)
{
@ -5175,8 +5083,7 @@ static void Command_KartGiveItem_f(void)
int i;
/* Allow always in local games. */
if (! netgame || cv_kartallowgiveitem.value)
if (CV_CheatsEnabled())
{
ac = COM_Argc();
if (ac < 2)
@ -5516,7 +5423,7 @@ static void Skin_OnChange(void)
if (!Playing())
return; // do whatever you want
if (!(cv_debug || devparm) && !(multiplayer || netgame) // In single player.
if (!CV_CheatsEnabled() && !(multiplayer || netgame) // In single player.
&& (gamestate != GS_WAITINGPLAYERS)) // allows command line -warp x +skin y
{
CV_StealthSet(&cv_skin[0], skins[players[consoleplayer].skin].name);
@ -5592,7 +5499,7 @@ static void Color_OnChange(void)
}
else
{
if (!(cv_debug || devparm) && !(multiplayer || netgame)) // In single player.
if (!CV_CheatsEnabled() && !(multiplayer || netgame)) // In single player.
{
CV_StealthSet(&cv_skin[0], skins[players[consoleplayer].skin].name);
return;

View file

@ -86,7 +86,7 @@ extern consvar_t cv_kartusepwrlv;
extern consvar_t cv_votetime;
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartallowgiveitem, cv_kartdebugdistribution, cv_kartdebughuddrop;
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugdistribution, cv_kartdebughuddrop;
extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes, cv_kartdebugcolorize, cv_kartdebugdirector;
extern consvar_t cv_kartdebugwaypoints, cv_kartdebugbotpredict;

View file

@ -66,8 +66,8 @@ typedef enum
// Accessibility and cheats
PF_KICKSTARTACCEL = 1<<4, // Is accelerate in kickstart mode?
PF_GODMODE = 1<<5,
PF_NOCLIP = 1<<6,
// 1<<5 free
// 1<<6 free
PF_WANTSTOJOIN = 1<<7, // Spectator that wants to join
@ -105,6 +105,13 @@ typedef enum
// up to 1<<31 is free
} pflags_t;
typedef enum
{
PC_GODMODE = 1,
PC_NOCLIP = 1<<1,
// up to 1<<31 is free
} pcheats_t;
typedef enum
{
// Are animation frames playing?
@ -350,6 +357,7 @@ typedef struct player_s
// Bit flags.
// See pflags_t, above.
pflags_t pflags;
pcheats_t cheats;
// playing animation.
panim_t panim;

View file

@ -122,7 +122,7 @@ extern char logfilename[1024];
#endif
/* A mod name to further distinguish versions. */
#define SRB2APPLICATION "SRB2Kart"
#define SRB2APPLICATION "RingRacers"
//#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3
#ifdef DEVELOP
@ -146,7 +146,7 @@ extern char logfilename[1024];
#define VERSIONSTRINGW WSTRING (VERSIONSTRING)
/* A custom URL protocol for server links. */
#define SERVER_URL_PROTOCOL "srb2kart://"
#define SERVER_URL_PROTOCOL "ringracers://"
// Does this version require an added patch file?
// Comment or uncomment this as necessary.
@ -619,12 +619,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
// None of these that are disabled in the normal build are guaranteed to work perfectly
// Compile them at your own risk!
/// Allows the use of devmode in multiplayer. AKA "fishcake"
//#define NETGAME_DEVMODE
/// Allows gravity changes in netgames, no questions asked.
//#define NETGAME_GRAVITY
/// Dumps the contents of a network save game upon consistency failure for debugging.
//#define DUMPCONSISTENCY

View file

@ -95,6 +95,7 @@ extern boolean modifiedgame;
extern boolean majormods;
extern UINT16 mainwads;
extern boolean savemoddata; // This mod saves time/emblem data.
extern boolean usedCheats;
extern boolean imcontinuing; // Temporary flag while continuing
extern boolean metalrecording;
@ -685,8 +686,6 @@ extern INT16 scrambleteams[MAXPLAYERS]; //for CTF team scramble
extern INT16 scrambletotal; //for CTF team scramble
extern INT16 scramblecount; //for CTF team scramble
extern INT32 cheats;
// SRB2kart
extern UINT8 gamespeed;
extern boolean franticitems;

View file

@ -1035,7 +1035,7 @@ void F_GameEvaluationDrawer(void)
{
V_DrawString(8, 16, V_YELLOWMAP, "Unlocked:");
if (!(netgame) && (!modifiedgame || savemoddata))
if (!usedCheats)
{
INT32 startcoord = 32;
@ -1050,10 +1050,8 @@ void F_GameEvaluationDrawer(void)
}
}
}
else if (netgame)
V_DrawString(8, 96, V_YELLOWMAP, "Multiplayer games\ncan't unlock\nextras!");
else
V_DrawString(8, 96, V_YELLOWMAP, "Modified games\ncan't unlock\nextras!");
V_DrawString(8, 96, V_YELLOWMAP, "Cheated games\ncan't unlock\nextras!");
}
#endif
@ -1107,14 +1105,7 @@ void F_GameEvaluationTicker(void)
if (finalecount == 5*TICRATE)
{
if (netgame || multiplayer) // modify this when we finally allow unlocking stuff in 2P
{
HU_SetCEchoFlags(V_YELLOWMAP);
HU_SetCEchoDuration(6);
HU_DoCEcho("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Multiplayer games can't unlock extras!");
S_StartSound(NULL, sfx_s3k68);
}
else if (!modifiedgame || savemoddata)
if (!usedCheats)
{
++timesBeaten;
@ -1127,7 +1118,7 @@ void F_GameEvaluationTicker(void)
{
HU_SetCEchoFlags(V_YELLOWMAP);
HU_SetCEchoDuration(6);
HU_DoCEcho("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Modified games can't unlock extras!");
HU_DoCEcho("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Cheated games can't unlock extras!");
S_StartSound(NULL, sfx_s3k68);
}
}

View file

@ -122,6 +122,7 @@ UINT16 mainwads = 0;
boolean modifiedgame = false; // Set if homebrew PWAD stuff has been added.
boolean majormods = false; // Set if Lua/Gameplay SOC/replacement map has been added.
boolean savemoddata = false;
boolean usedCheats = false; // Set when a "cheats on" is ever used.
UINT8 paused;
UINT8 modeattacking = ATTACKING_NONE;
boolean imcontinuing = false;
@ -297,8 +298,6 @@ INT16 scrambleteams[MAXPLAYERS]; //for CTF team scramble
INT16 scrambletotal; //for CTF team scramble
INT16 scramblecount; //for CTF team scramble
INT32 cheats; //for multiplayer cheat commands
// SRB2Kart
// Cvars that we don't want changed mid-game
UINT8 gamespeed; // Game's current speed (or difficulty, or cc, or etc); 0 for easy, 1 for normal, 2 for hard
@ -658,6 +657,22 @@ void G_SetGameModified(boolean silent, boolean major)
Command_ExitGame_f();
}
// for consistency among messages: this sets cheats as used.
void G_SetUsedCheats(void)
{
if (usedCheats)
return;
usedCheats = true;
CONS_Alert(CONS_NOTICE, M_GetText("Cheats activated -- game must be restarted to save progress.\n"));
// If in record attack recording, cancel it.
if (modeattacking)
M_EndModeAttackRun();
else if (marathonmode)
Command_ExitGame_f();
}
/** Builds an original game map name from a map number.
* The complexity is due to MAPA0-MAPZZ.
*
@ -2188,6 +2203,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
UINT32 followitem;
INT32 pflags;
INT32 cheats;
UINT8 ctfteam;
@ -2266,6 +2282,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
botrival = players[player].botvars.rival;
pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE));
cheats = 0;
// SRB2kart
if (betweenmaps || leveltime < introtime)
@ -2339,7 +2356,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
// As long as we're not in multiplayer, carry over cheatcodes from map to map
if (!(netgame || multiplayer))
pflags |= (players[player].pflags & (PF_GODMODE|PF_NOCLIP));
cheats = players[player].cheats;
if (!betweenmaps)
{
@ -2356,6 +2373,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->roundscore = roundscore;
p->lives = lives;
p->pflags = pflags;
p->cheats = cheats;
p->ctfteam = ctfteam;
p->jointime = jointime;
p->splitscreenindex = splitscreenindex;
@ -3407,7 +3425,7 @@ tryagain:
if ((mapheaderinfo[ix]->typeoflevel & tolflags) != tolflags
|| ix == pprevmap
|| (!dedicated && M_MapLocked(ix+1))
|| M_MapLocked(ix+1)
|| (usehellmaps != (mapheaderinfo[ix]->menuflags & LF2_HIDEINMENU))) // this is bad
continue; //isokmap = false;
@ -3528,11 +3546,8 @@ void G_AddMapToBuffer(INT16 map)
//
static void G_UpdateVisited(void)
{
boolean spec = G_IsSpecialStage(gamemap);
// Update visitation flags?
if ((!modifiedgame || savemoddata) // Not modified
&& !multiplayer && !demo.playback // SP/RA/NiGHTS mode
&& !(spec && stagefailed)) // Not failed the special stage
if (!demo.playback) // Not watching a demo
{
UINT8 earnedEmblems;
@ -3575,14 +3590,16 @@ static void G_HandleSaveLevel(void)
remove(liveeventbackup);
cursaveslot = 0;
}
else if ((!modifiedgame || savemoddata) && !(netgame || multiplayer || ultimatemode || demo.recording || metalrecording || modeattacking))
else if (!usedCheats && !(netgame || multiplayer || ultimatemode || demo.recording || metalrecording || modeattacking))
G_SaveGame((UINT32)cursaveslot, spstage_start);
}
}
// and doing THIS here means you don't lose your progress if you close the game mid-intermission
else if (!(ultimatemode || netgame || multiplayer || demo.playback || demo.recording || metalrecording || modeattacking)
&& (!modifiedgame || savemoddata) && cursaveslot > 0 && CanSaveLevel(lastmap+1))
else if (!(ultimatemode || demo.playback || demo.recording || metalrecording || modeattacking)
&& cursaveslot > 0 && CanSaveLevel(lastmap+1))
{
G_SaveGame((UINT32)cursaveslot, lastmap+1); // not nextmap+1 to route around special stages
}
}
//
@ -3943,7 +3960,7 @@ static void G_DoContinued(void)
tokenlist = 0;
token = 0;
if (!(netgame || multiplayer || demo.playback || demo.recording || metalrecording || modeattacking) && (!modifiedgame || savemoddata) && cursaveslot > 0)
if (!(netgame || multiplayer || demo.playback || demo.recording || metalrecording || modeattacking) && !usedCheats && cursaveslot > 0)
G_SaveGameOver((UINT32)cursaveslot, true);
// Reset # of lives
@ -4012,19 +4029,25 @@ void G_LoadGameSettings(void)
S_InitRuntimeSounds();
}
#define GAMEDATA_ID 0x61688195 // Change every major version, as usual
// G_LoadGameData
// Loads the main data file, which stores information such as emblems found, etc.
void G_LoadGameData(void)
{
size_t length;
INT32 i, j;
UINT8 modded = false;
UINT32 versionID;
UINT8 rtemp;
//For records
tic_t rectime;
tic_t reclap;
// Stop saving, until we successfully load it again.
gamedataloaded = false;
// Clear things so previously read gamedata doesn't transfer
// to new gamedata
G_ClearRecords(); // main and nights records
@ -4037,27 +4060,31 @@ void G_LoadGameData(void)
vspowerlevel[i] = PWRLVRECORD_START;
if (M_CheckParm("-nodata"))
return; // Don't load.
// Allow saving of gamedata beyond this point
gamedataloaded = true;
if (M_CheckParm("-gamedata") && M_IsNextParm())
{
strlcpy(gamedatafilename, M_GetNextParm(), sizeof gamedatafilename);
// Don't load at all.
return;
}
if (M_CheckParm("-resetdata"))
return; // Don't load (essentially, reset).
{
// Don't load, but do save. (essentially, reset)
gamedataloaded = true;
return;
}
length = FIL_ReadFile(va(pandf, srb2home, gamedatafilename), &savebuffer);
if (!length) // Aw, no game data. Their loss!
if (!length)
{
// No gamedata. We can save a new one.
gamedataloaded = true;
return;
}
save_p = savebuffer;
// Version check
if (READUINT32(save_p) != 0xFCAFE211)
versionID = READUINT32(save_p);
if (versionID != GAMEDATA_ID)
{
const char *gdfolder = "the Ring Racers folder";
if (strcmp(srb2home,"."))
@ -4065,7 +4092,7 @@ void G_LoadGameData(void)
Z_Free(savebuffer);
save_p = NULL;
I_Error("Game data is from another version of SRB2.\nDelete %s(maybe in %s) and try again.", gamedatafilename, gdfolder);
I_Error("Game data is not for Ring Racers v2.0.\nDelete %s(maybe in %s) and try again.", gamedatafilename, gdfolder);
}
totalplaytime = READUINT32(save_p);
@ -4078,13 +4105,17 @@ void G_LoadGameData(void)
goto datacorrupt;
}
modded = READUINT8(save_p);
{
// Quick & dirty hash for what mod this save file is for.
UINT32 modID = READUINT32(save_p);
UINT32 expectedID = quickncasehash(timeattackfolder, 64);
// Aha! Someone's been screwing with the save file!
if ((modded && !savemoddata))
goto datacorrupt;
else if (modded != true && modded != false)
goto datacorrupt;
if (modID != expectedID)
{
// Aha! Someone's been screwing with the save file!
goto datacorrupt;
}
}
// TODO put another cipher on these things? meh, I don't care...
for (i = 0; i < NUMMAPS; i++)
@ -4141,6 +4172,12 @@ void G_LoadGameData(void)
Z_Free(savebuffer);
save_p = NULL;
// Don't consider loaded until it's a success!
// It used to do this much earlier, but this would cause the gamedata to
// save over itself when it I_Errors from the corruption landing point below,
// which can accidentally delete players' legitimate data if the code ever has any tiny mistakes!
gamedataloaded = true;
// Silent update unlockables in case they're out of sync with conditions
M_SilentUpdateUnlockablesAndEmblems();
@ -4178,18 +4215,15 @@ void G_SaveGameData(void)
return;
}
#if 0
// SRB2Kart: Let players unlock stuff with addons.
if (modifiedgame && !savemoddata)
if (usedCheats)
{
free(savebuffer);
save_p = savebuffer = NULL;
return;
}
#endif
// Version test
WRITEUINT32(save_p, 0xFCAFE211);
WRITEUINT32(save_p, GAMEDATA_ID);
WRITEUINT32(save_p, totalplaytime);
WRITEUINT32(save_p, matchesplayed);
@ -4197,7 +4231,7 @@ void G_SaveGameData(void)
for (i = 0; i < PWRLV_NUMTYPES; i++)
WRITEUINT16(save_p, vspowerlevel[i]);
WRITEUINT8(save_p, (UINT8)savemoddata);
WRITEUINT32(save_p, quickncasehash(timeattackfolder, 64));
// TODO put another cipher on these things? meh, I don't care...
for (i = 0; i < NUMMAPS; i++)
@ -4605,7 +4639,7 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool
memset(&players[i].respawn, 0, sizeof (players[i].respawn));
// Clear cheatcodes too, just in case.
players[i].pflags &= ~(PF_GODMODE|PF_NOCLIP);
players[i].cheats = 0;
players[i].roundscore = 0;

View file

@ -243,6 +243,7 @@ void G_LoadGameData(void);
void G_LoadGameSettings(void);
void G_SetGameModified(boolean silent, boolean major);
void G_SetUsedCheats(void);
void G_SetGamestate(gamestate_t newstate);

View file

@ -257,7 +257,6 @@ void K_RegisterKartStuff(void)
CV_RegisterVar(&cv_kartdebugitem);
CV_RegisterVar(&cv_kartdebugamount);
CV_RegisterVar(&cv_kartallowgiveitem);
CV_RegisterVar(&cv_kartdebugdistribution);
CV_RegisterVar(&cv_kartdebughuddrop);
CV_RegisterVar(&cv_kartdebugwaypoints);

View file

@ -97,7 +97,7 @@ static UINT8 cheatf_warp(void)
if (success)
{
G_SaveGameData(); //G_SetGameModified(false);
G_SaveGameData(); //G_SetUsedCheats();
S_StartSound(0, sfx_kc42);
}
@ -121,7 +121,7 @@ static UINT8 cheatf_devmode(void)
S_StartSound(0, sfx_itemup);
// Just unlock all the things and turn on -debug and console devmode.
G_SetGameModified(false, false); // might need to revist the latter later
G_SetUsedCheats();
for (i = 0; i < MAXUNLOCKABLES; i++)
unlockables[i].unlocked = true;
devparm = true;
@ -264,11 +264,8 @@ boolean cht_Responder(event_t *ev)
}
// Console cheat commands rely on these a lot...
#define REQUIRE_PANDORA if (!M_SecretUnlocked(SECRET_PANDORA) && !cv_debug)\
{ CONS_Printf(M_GetText("You haven't earned this yet.\n")); return; }
#define REQUIRE_DEVMODE if (!cv_debug)\
{ CONS_Printf(M_GetText("DEVMODE must be enabled.\n")); return; }
#define REQUIRE_CHEATS if (!CV_CheatsEnabled())\
{ CONS_Printf(M_GetText("Cheats must be enabled.\n")); return; }
#define REQUIRE_OBJECTPLACE if (!objectplacing)\
{ CONS_Printf(M_GetText("OBJECTPLACE must be enabled.\n")); return; }
@ -284,37 +281,35 @@ void Command_CheatNoClip_f(void)
{
player_t *plyr;
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER;
REQUIRE_SINGLEPLAYER; // TODO: make netplay compatible
plyr = &players[consoleplayer];
if (!plyr->mo || P_MobjWasRemoved(plyr->mo))
return;
plyr->pflags ^= PF_NOCLIP;
CONS_Printf(M_GetText("No Clipping %s\n"), plyr->pflags & PF_NOCLIP ? M_GetText("On") : M_GetText("Off"));
plyr->cheats ^= PC_NOCLIP;
CONS_Printf(M_GetText("No Clipping %s\n"), plyr->cheats & PC_NOCLIP ? M_GetText("On") : M_GetText("Off"));
if (plyr->pflags & PF_NOCLIP)
if (plyr->cheats & PC_NOCLIP)
plyr->mo->flags |= MF_NOCLIP;
else
plyr->mo->flags &= ~MF_NOCLIP;
G_SetGameModified(multiplayer, true);
}
void Command_CheatGod_f(void)
{
player_t *plyr;
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER;
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
plyr = &players[consoleplayer];
plyr->pflags ^= PF_GODMODE;
CONS_Printf(M_GetText("Cheese Mode %s\n"), plyr->pflags & PF_GODMODE ? M_GetText("On") : M_GetText("Off"));
G_SetGameModified(multiplayer, true);
plyr->cheats ^= PC_GODMODE;
CONS_Printf(M_GetText("Cheese Mode %s\n"), plyr->cheats & PC_GODMODE ? M_GetText("On") : M_GetText("Off"));
}
void Command_Scale_f(void)
@ -322,9 +317,9 @@ void Command_Scale_f(void)
const double scaled = atof(COM_Argv(1));
fixed_t scale = FLOAT_TO_FIXED(scaled);
REQUIRE_DEVMODE;
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER;
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
if (scale < FRACUNIT/100 || scale > 100*FRACUNIT) //COM_Argv(1) will return a null string if they did not give a paramater, so...
{
@ -342,9 +337,9 @@ void Command_Scale_f(void)
void Command_Gravflip_f(void)
{
REQUIRE_DEVMODE;
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER;
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
if (players[consoleplayer].mo)
players[consoleplayer].mo->flags2 ^= MF2_OBJECTFLIP;
@ -352,9 +347,9 @@ void Command_Gravflip_f(void)
void Command_Hurtme_f(void)
{
REQUIRE_DEVMODE;
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER;
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
if (COM_Argc() < 2)
{
@ -372,9 +367,9 @@ void Command_RTeleport_f(void)
player_t *p = &players[consoleplayer];
subsector_t *ss;
REQUIRE_DEVMODE;
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER;
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
if (COM_Argc() < 3 || COM_Argc() > 7)
{
@ -434,9 +429,9 @@ void Command_Teleport_f(void)
player_t *p = &players[consoleplayer];
subsector_t *ss;
REQUIRE_DEVMODE;
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER;
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
if (COM_Argc() < 3 || COM_Argc() > 11)
{
@ -650,9 +645,9 @@ void Command_Teleport_f(void)
void Command_Skynum_f(void)
{
REQUIRE_DEVMODE;
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER;
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
if (COM_Argc() != 2)
{
@ -668,9 +663,9 @@ void Command_Skynum_f(void)
void Command_Weather_f(void)
{
REQUIRE_DEVMODE;
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER;
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
if (COM_Argc() != 2)
{
@ -688,9 +683,9 @@ void Command_Toggletwod_f(void)
{
player_t *p = &players[consoleplayer];
REQUIRE_DEVMODE;
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER;
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
if (p->mo)
p->mo->flags2 ^= MF2_TWOD;
@ -703,6 +698,9 @@ void Command_Toggletwod_f(void)
// Don't enable this for normal builds...
void Command_CauseCfail_f(void)
{
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
if (consoleplayer == serverplayer)
{
CONS_Printf(M_GetText("Only remote players can use this command.\n"));
@ -745,9 +743,9 @@ void Command_Dumplua_f(void)
void Command_Savecheckpoint_f(void)
{
REQUIRE_DEVMODE;
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER;
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
players[consoleplayer].respawn.pointx = players[consoleplayer].mo->x;
players[consoleplayer].respawn.pointy = players[consoleplayer].mo->y;
@ -760,8 +758,8 @@ void Command_Savecheckpoint_f(void)
/*
void Command_Getallemeralds_f(void)
{
REQUIRE_CHEATS;
REQUIRE_SINGLEPLAYER;
REQUIRE_PANDORA;
emeralds = EMERALD_ALL;
@ -770,6 +768,7 @@ void Command_Getallemeralds_f(void)
void Command_Resetemeralds_f(void)
{
REQUIRE_CHEATS;
REQUIRE_SINGLEPLAYER;
emeralds = 0;
@ -780,9 +779,8 @@ void Command_Resetemeralds_f(void)
void Command_Devmode_f(void)
{
#ifndef _DEBUG
REQUIRE_SINGLEPLAYER;
#endif
REQUIRE_CHEATS;
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
if (COM_Argc() > 1)
{
@ -799,15 +797,12 @@ void Command_Devmode_f(void)
CONS_Printf(M_GetText("devmode <flags>: enable debugging tools and info, prepend with 0x to use hexadecimal\n"));
return;
}
G_SetGameModified(multiplayer, true);
}
void Command_Setrings_f(void)
{
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER;
REQUIRE_PANDORA;
if (COM_Argc() > 1)
{
@ -815,16 +810,13 @@ void Command_Setrings_f(void)
players[consoleplayer].rings = 0;
P_GivePlayerRings(&players[consoleplayer], atoi(COM_Argv(1)));
players[consoleplayer].totalring -= atoi(COM_Argv(1)); //undo totalring addition done in P_GivePlayerRings
G_SetGameModified(multiplayer, true);
}
}
void Command_Setlives_f(void)
{
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER;
REQUIRE_PANDORA;
if (COM_Argc() > 1)
{
@ -839,8 +831,6 @@ void Command_Setlives_f(void)
players[consoleplayer].lives = 0;
P_GivePlayerLives(&players[consoleplayer], atoi(COM_Argv(1)));
}
G_SetGameModified(multiplayer, true);
}
}
@ -1149,7 +1139,6 @@ void OP_ObjectplaceMovement(player_t *player)
void Command_Writethings_f(void)
{
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER;
REQUIRE_OBJECTPLACE;
P_WriteThings();
@ -1161,9 +1150,8 @@ void Command_ObjectPlace_f(void)
size_t silent;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER;
G_SetGameModified(multiplayer, true);
REQUIRE_CHEATS;
REQUIRE_SINGLEPLAYER; // this one will very likely never be multiplayer compatible...
silent = COM_CheckParm("-silent");

View file

@ -382,17 +382,23 @@ UINT8 M_SecretUnlocked(INT32 type)
UINT8 M_MapLocked(INT32 mapnum)
{
#ifdef DEVELOP
if (1)
(void)mapnum;
return false;
#else
// Don't lock maps in dedicated servers.
// That just makes hosts' lives hell.
if (dedicated)
return false;
#endif
if (!mapheaderinfo[mapnum-1] || mapheaderinfo[mapnum-1]->unlockrequired < 0)
return false;
if (!unlockables[mapheaderinfo[mapnum-1]->unlockrequired].unlocked)
return true;
return false;
#endif
}
INT32 M_CountEmblems(void)

View file

@ -6376,7 +6376,7 @@ static void M_GetAllEmeralds(INT32 choice)
emeralds = EMERALD_ALL;
M_StartMessage(M_GetText("You now have all 7 emeralds.\nUse them wisely.\nWith great power comes great ring drain.\n"),NULL,MM_NOTHING);
G_SetGameModified(multiplayer, true);
G_SetUsedCheats();
}
static void M_DestroyRobotsResponse(INT32 ch)
@ -6387,7 +6387,7 @@ static void M_DestroyRobotsResponse(INT32 ch)
// Destroy all robots
P_DestroyRobots();
G_SetGameModified(multiplayer, true);
G_SetUsedCheats();
}
static void M_DestroyRobots(INT32 choice)

View file

@ -1893,7 +1893,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (player) // Player is the target
{
if (player->pflags & PF_GODMODE)
if (player->cheats & PC_GODMODE)
return false;
if (!force)

View file

@ -2239,7 +2239,7 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
fixed_t tryy = thiscam->y;
#ifndef NOCLIPCAM
if ((players[displayplayers[i]].pflags & PF_NOCLIP) || (leveltime < introtime)) // Noclipping player camera noclips too!!
if ((players[displayplayers[i]].cheats & PC_NOCLIP) || (leveltime < introtime)) // Noclipping player camera noclips too!!
#else
if (!(players[displayplayers[i]].pflags & PF_NOCONTEST)) // Time Over should not clip through walls
#endif

View file

@ -2040,7 +2040,7 @@ boolean P_CheckDeathPitCollide(mobj_t *mo)
I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo));
if (mo->player && mo->player->pflags & PF_GODMODE)
if (mo->player && mo->player->cheats & PC_GODMODE)
return false;
if (((mo->z <= mo->subsector->sector->floorheight
@ -3531,7 +3531,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
player->karthud[khud_timeovercam] = (2*TICRATE)+1;
}
if (!resetcalled && !(player->pflags & PF_NOCLIP || leveltime < introtime) && !P_CheckSight(&dummy, player->mo)) // TODO: "P_CheckCameraSight" instead.
if (!resetcalled && !(player->cheats & PC_NOCLIP || leveltime < introtime) && !P_CheckSight(&dummy, player->mo)) // TODO: "P_CheckCameraSight" instead.
{
P_ResetCamera(player, thiscam);
}
@ -10583,7 +10583,7 @@ void P_RemoveSavegameMobj(mobj_t *mobj)
static CV_PossibleValue_t respawnitemtime_cons_t[] = {{1, "MIN"}, {300, "MAX"}, {0, NULL}};
consvar_t cv_itemrespawntime = CVAR_INIT ("respawnitemtime", "2", CV_NETVAR|CV_CHEAT, respawnitemtime_cons_t, NULL);
consvar_t cv_itemrespawn = CVAR_INIT ("respawnitem", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_itemrespawn = CVAR_INIT ("respawnitem", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
void P_SpawnPrecipitation(void)
{
@ -11417,31 +11417,23 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i)
switch (i)
{
case MT_EMBLEM:
if (netgame || multiplayer)
return false; // Single player only
case MT_ITEMCAPSULE:
{
boolean isRingCapsule = (mthing->angle < 1 || mthing->angle == KITEM_SUPERRING || mthing->angle >= NUMKARTITEMS);
if (modifiedgame && !savemoddata)
return false; // No cheating!!
// don't spawn ring capsules in GTR_SPHERES gametypes
if (isRingCapsule && (gametyperules & GTR_SPHERES))
return false;
break;
case MT_ITEMCAPSULE:
{
boolean isRingCapsule = (mthing->angle < 1 || mthing->angle == KITEM_SUPERRING || mthing->angle >= NUMKARTITEMS);
// don't spawn ring capsules in GTR_SPHERES gametypes
if (isRingCapsule && (gametyperules & GTR_SPHERES))
return false;
// in record attack, only spawn ring capsules
// (behavior can be inverted with the Extra flag, i.e. item capsule spawns and ring capsule does not)
if (modeattacking
&& (!(mthing->options & MTF_EXTRA) == !isRingCapsule))
return false;
}
break;
default:
break;
// in record attack, only spawn ring capsules
// (behavior can be inverted with the Extra flag, i.e. item capsule spawns and ring capsule does not)
if (modeattacking
&& (!(mthing->options & MTF_EXTRA) == !isRingCapsule))
return false;
}
break;
default:
break;
}
// No bosses outside of a combat situation.

View file

@ -4133,9 +4133,6 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
// Initialize sector node list.
P_Initsecnode();
if (netgame || multiplayer)
cv_debug = 0;
if (metalplayback)
G_StopMetalDemo();
@ -4476,7 +4473,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
{
// I'd love to do this in the menu code instead of here, but everything's a mess and I can't guarantee saving proper player struct info before the first act's started. You could probably refactor it, but it'd be a lot of effort. Easier to just work off known good code. ~toast 22/06/2020
if (!(ultimatemode || netgame || multiplayer || demo.playback || demo.recording || metalrecording || modeattacking || marathonmode)
&& (!modifiedgame || savemoddata) && cursaveslot > 0)
&& !usedCheats && cursaveslot > 0)
G_SaveGame((UINT32)cursaveslot, gamemap);
// If you're looking for saving sp file progression (distinct from G_SaveGameOver), check G_DoCompleted.
}

View file

@ -3084,7 +3084,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
}
#ifndef NOCLIPCAM
cameranoclip = ((player->pflags & PF_NOCLIP)
cameranoclip = ((player->cheats & PC_NOCLIP)
|| (mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)) // Noclipping player camera noclips too!!
|| (leveltime < introtime)); // Kart intro cam
#endif

View file

@ -298,7 +298,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
player->kartweight = skin->kartweight;
#if 0
if (!(cv_debug || devparm) && !(netgame || multiplayer || demo.playback))
if (!CV_CheatsEnabled() && !(netgame || multiplayer || demo.playback))
{
for (i = 0; i <= r_splitscreen; i++)
{