Warp cheat adjustments

This commit is contained in:
Sal 2023-08-07 18:35:20 +00:00
parent 9e72b78a24
commit 492fe94597
12 changed files with 158 additions and 67 deletions

View file

@ -1737,14 +1737,15 @@ void D_SRB2Main(void)
// Prevent warping to nonexistent levels // Prevent warping to nonexistent levels
if (W_CheckNumForName(G_BuildMapName(pstartmap)) == LUMPERROR) if (W_CheckNumForName(G_BuildMapName(pstartmap)) == LUMPERROR)
I_Error("Could not warp to %s (map not found)\n", G_BuildMapName(pstartmap)); 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, serverGamedata))
I_Error("You need to unlock this level before you can warp to it!\n");
else else
{ {
if (M_CampaignWarpIsCheat(gametype, pstartmap, serverGamedata))
{
// If you're warping via command line, you know what you're doing.
// No need to I_Error over this.
G_SetUsedCheats(false);
}
D_MapChange(pstartmap, gametype, ultimatemode, true, 0, false, false); D_MapChange(pstartmap, gametype, ultimatemode, true, 0, false, false);
} }
} }

View file

@ -1902,8 +1902,8 @@ static void Command_Map_f(void)
size_t option_gametype; size_t option_gametype;
const char *gametypename; const char *gametypename;
boolean newresetplayers; boolean newresetplayers;
boolean prevent_cheat;
boolean wouldSetCheats; boolean set_cheated;
INT32 newmapnum; INT32 newmapnum;
@ -1924,21 +1924,33 @@ static void Command_Map_f(void)
option_gametype = COM_CheckPartialParm("-g"); option_gametype = COM_CheckPartialParm("-g");
newresetplayers = ! COM_CheckParm("-noresetplayers"); newresetplayers = ! COM_CheckParm("-noresetplayers");
wouldSetCheats = prevent_cheat = !( usedCheats ) && !( option_force || cv_debug );
!( netgame || multiplayer ) &&
!( usedCheats );
if (wouldSetCheats && !option_force) if (!( netgame || multiplayer ))
{ {
/* May want to be more descriptive? */ if (prevent_cheat)
CONS_Printf(M_GetText("Sorry, level change disabled in single player.\n")); {
return; /* May want to be more descriptive? */
CONS_Printf(M_GetText("Cheats must be enabled to level change in single player.\n"));
return;
}
else
{
set_cheated = true;
}
} }
if (!newresetplayers && !cv_debug) if (!newresetplayers)
{ {
CONS_Printf(M_GetText("DEVMODE must be enabled.\n")); if (prevent_cheat)
return; {
CONS_Printf(M_GetText("Cheats must be enabled to use -noresetplayers.\n"));
return;
}
else
{
set_cheated = true;
}
} }
if (option_gametype) if (option_gametype)
@ -1946,7 +1958,7 @@ static void Command_Map_f(void)
if (!multiplayer) if (!multiplayer)
{ {
CONS_Printf(M_GetText( CONS_Printf(M_GetText(
"You can't switch gametypes in single player!\n")); "You can't switch gametypes in single player!\n"));
return; return;
} }
else if (COM_Argc() < option_gametype + 2)/* no argument after? */ else if (COM_Argc() < option_gametype + 2)/* no argument after? */
@ -1959,7 +1971,9 @@ static void Command_Map_f(void)
} }
if (!( first_option = COM_FirstOption() )) if (!( first_option = COM_FirstOption() ))
{
first_option = COM_Argc(); first_option = COM_Argc();
}
if (first_option < 2) if (first_option < 2)
{ {
@ -1982,11 +1996,6 @@ static void Command_Map_f(void)
return; return;
} }
if (wouldSetCheats && option_force)
{
G_SetUsedCheats(false);
}
// new gametype value // new gametype value
// use current one by default // use current one by default
if (option_gametype) if (option_gametype)
@ -2028,15 +2037,13 @@ static void Command_Map_f(void)
} }
// don't use a gametype the map doesn't support // 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 // G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer
else if (!(
mapheaderinfo[newmapnum-1] &&
mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype)
))
{ {
if (!( if (prevent_cheat && !cv_skipmapcheck.value)
mapheaderinfo[newmapnum-1] &&
mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype)
))
{ {
CONS_Alert(CONS_WARNING, M_GetText("%s (%s) doesn't support %s mode!\n(Use -force to override)\n"), realmapname, G_BuildMapName(newmapnum), CONS_Alert(CONS_WARNING, M_GetText("%s (%s) doesn't support %s mode!\n(Use -force to override)\n"), realmapname, G_BuildMapName(newmapnum),
(multiplayer ? gametype_cons_t[newgametype].strvalue : "Single Player")); (multiplayer ? gametype_cons_t[newgametype].strvalue : "Single Player"));
@ -2046,23 +2053,33 @@ static void Command_Map_f(void)
} }
else else
{ {
fromlevelselect = // The player wants us to trek on anyway. Do so.
( netgame || multiplayer ) && fromlevelselect = false;
newgametype == gametype && set_cheated = ((gametypedefaultrules[newgametype] & GTR_CAMPAIGN) == GTR_CAMPAIGN);
gametypedefaultrules[newgametype] & GTR_CAMPAIGN;
} }
} }
else
{
fromlevelselect =
( netgame || multiplayer ) &&
newgametype == gametype &&
(gametypedefaultrules[newgametype] & GTR_CAMPAIGN);
}
// Prevent warping to locked levels // Prevent warping to locked levels
// ... unless you're in a dedicated server. Yes, technically this means you can view any level by if (M_CampaignWarpIsCheat(newgametype, newmapnum, serverGamedata))
// running a dedicated server and joining it yourself, but that's better than making dedicated server's
// lives hell.
if (!dedicated && M_MapLocked(newmapnum, serverGamedata))
{ {
CONS_Alert(CONS_NOTICE, M_GetText("You need to unlock this level before you can warp to it!\n")); if (prevent_cheat)
Z_Free(realmapname); {
Z_Free(mapname); CONS_Alert(CONS_NOTICE, M_GetText("Cheats must be enabled to warp to a locked level!\n"));
return; Z_Free(realmapname);
Z_Free(mapname);
return;
}
else
{
set_cheated = true;
}
} }
// Ultimate Mode only in SP via menu // Ultimate Mode only in SP via menu
@ -2079,6 +2096,11 @@ static void Command_Map_f(void)
} }
tutorialmode = false; // warping takes us out of tutorial mode tutorialmode = false; // warping takes us out of tutorial mode
if (set_cheated && !usedCheats)
{
G_SetUsedCheats(false);
}
D_MapChange(newmapnum, newgametype, false, newresetplayers, 0, false, fromlevelselect); D_MapChange(newmapnum, newgametype, false, newresetplayers, 0, false, fromlevelselect);
Z_Free(realmapname); Z_Free(realmapname);
@ -4555,25 +4577,37 @@ static void Command_Mapmd5_f(void)
CONS_Printf(M_GetText("You must be in a level to use this.\n")); CONS_Printf(M_GetText("You must be in a level to use this.\n"));
} }
void D_SendExitLevel(boolean cheat)
{
UINT8 buf[8];
UINT8 *buf_p = buf;
WRITEUINT8(buf_p, cheat);
SendNetXCmd(XD_EXITLEVEL, &buf, buf_p - buf);
}
static void Command_ExitLevel_f(void) static void Command_ExitLevel_f(void)
{ {
if (!(netgame || (multiplayer && gametype != GT_COOP)) && !cv_debug) if (!(server || (IsPlayerAdmin(consoleplayer))))
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")); CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
else if (( gamestate != GS_LEVEL && gamestate != GS_CREDITS ) || demoplayback) else if (( gamestate != GS_LEVEL && gamestate != GS_CREDITS ) || demoplayback)
CONS_Printf(M_GetText("You must be in a level to use this.\n")); CONS_Printf(M_GetText("You must be in a level to use this.\n"));
else else
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(true);
} }
static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum) static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum)
{ {
(void)cp; boolean cheat = false;
cheat = (boolean)READUINT8(*cp);
// Ignore duplicate XD_EXITLEVEL commands. // Ignore duplicate XD_EXITLEVEL commands.
if (gameaction == ga_completed) if (gameaction == ga_completed)
{
return; return;
}
if (playernum != serverplayer && !IsPlayerAdmin(playernum)) if (playernum != serverplayer && !IsPlayerAdmin(playernum))
{ {
@ -4583,6 +4617,11 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum)
return; return;
} }
if (G_CoopGametype() && cheat)
{
G_SetUsedCheats(false);
}
G_ExitLevel(); G_ExitLevel();
} }

View file

@ -201,6 +201,7 @@ void D_SendPlayerConfig(void);
void Command_ExitGame_f(void); void Command_ExitGame_f(void);
void Command_Retry_f(void); void Command_Retry_f(void);
void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore
void D_SendExitLevel(boolean cheat);
void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect); void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect);
boolean IsPlayerAdmin(INT32 playernum); boolean IsPlayerAdmin(INT32 playernum);
void SetAdminPlayer(INT32 playernum); void SetAdminPlayer(INT32 playernum);

View file

@ -1644,7 +1644,7 @@ void F_GameEvaluationTicker(void)
sparklloop = 0; sparklloop = 0;
} }
if (finalecount == 5*TICRATE) if (G_CoopGametype() && !stagefailed && finalecount == 5*TICRATE)
{ {
serverGamedata->timesBeaten++; serverGamedata->timesBeaten++;
clientGamedata->timesBeaten++; clientGamedata->timesBeaten++;

View file

@ -2137,7 +2137,7 @@ boolean G_Responder(event_t *ev)
if (! netgame) if (! netgame)
F_StartGameEvaluation(); F_StartGameEvaluation();
else if (server || IsPlayerAdmin(consoleplayer)) else if (server || IsPlayerAdmin(consoleplayer))
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
return true; return true;
} }
} }
@ -3861,7 +3861,7 @@ static INT16 RandMap(UINT32 tolflags, INT16 pprevmap)
for (ix = 0; ix < NUMMAPS; ix++) for (ix = 0; ix < NUMMAPS; ix++)
if (mapheaderinfo[ix] && (mapheaderinfo[ix]->typeoflevel & tolflags) == tolflags if (mapheaderinfo[ix] && (mapheaderinfo[ix]->typeoflevel & tolflags) == tolflags
&& ix != pprevmap // Don't pick the same map. && ix != pprevmap // Don't pick the same map.
&& (dedicated || !M_MapLocked(ix+1, serverGamedata)) // Don't pick locked maps. && (!M_MapLocked(ix+1, serverGamedata)) // Don't pick locked maps.
) )
okmaps[numokmaps++] = ix; okmaps[numokmaps++] = ix;

View file

@ -1487,7 +1487,6 @@ void LUA_SetHudHook(int hook, huddrawlist_h list)
break; break;
case HUD_HOOK(intermission): case HUD_HOOK(intermission):
lua_pushboolean(gL, intertype == int_spec && lua_pushboolean(gL, stagefailed);
stagefailed);
} }
} }

View file

@ -467,6 +467,15 @@ UINT8 M_SecretUnlocked(INT32 type, gamedata_t *data)
UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data) UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data)
{ {
if (dedicated)
{
// If you're in a dedicated server, every level is unlocked.
// 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.
return false;
}
if (!mapheaderinfo[mapnum-1] || mapheaderinfo[mapnum-1]->unlockrequired < 0) if (!mapheaderinfo[mapnum-1] || mapheaderinfo[mapnum-1]->unlockrequired < 0)
{ {
return false; return false;
@ -480,6 +489,48 @@ UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data)
return false; return false;
} }
UINT8 M_CampaignWarpIsCheat(INT32 gt, INT32 mapnum, gamedata_t *data)
{
if (M_MapLocked(mapnum, data) == true)
{
// Warping to locked maps is definitely always a cheat
return true;
}
if ((gametypedefaultrules[gt] & GTR_CAMPAIGN) == 0)
{
// Not a campaign, do whatever you want.
return false;
}
if (G_IsSpecialStage(mapnum))
{
// Warping to special stages is a cheat
return true;
}
if (mapheaderinfo[mapnum-1]->menuflags & LF2_HIDEINMENU)
{
// You're never allowed to warp to this level.
return true;
}
if (mapheaderinfo[mapnum-1]->menuflags & LF2_NOVISITNEEDED)
{
// You're always allowed to warp to this level.
return false;
}
if (mapnum == spstage_start)
{
// Warping to the first level is never a cheat
return false;
}
// It's only a cheat if you've never been there.
return (!(data->mapvisited[mapnum]));
}
INT32 M_CountEmblems(gamedata_t *data) INT32 M_CountEmblems(gamedata_t *data)
{ {
INT32 found = 0, i; INT32 found = 0, i;

View file

@ -252,6 +252,7 @@ void M_SilentUpdateSkinAvailabilites(void);
UINT8 M_AnySecretUnlocked(gamedata_t *data); UINT8 M_AnySecretUnlocked(gamedata_t *data);
UINT8 M_SecretUnlocked(INT32 type, gamedata_t *data); UINT8 M_SecretUnlocked(INT32 type, gamedata_t *data);
UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data); UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data);
UINT8 M_CampaignWarpIsCheat(INT32 gt, INT32 mapnum, gamedata_t *data);
INT32 M_CountEmblems(gamedata_t *data); INT32 M_CountEmblems(gamedata_t *data);
// Emblem shit // Emblem shit

View file

@ -2235,7 +2235,7 @@ void P_CheckTimeLimit(void)
} }
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
} }
//Optional tie-breaker for Match/CTF //Optional tie-breaker for Match/CTF
@ -2298,11 +2298,11 @@ void P_CheckTimeLimit(void)
} }
} }
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
} }
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
} }
/** Checks if a player's score is over the pointlimit and the round should end. /** Checks if a player's score is over the pointlimit and the round should end.
@ -2331,7 +2331,7 @@ void P_CheckPointLimit(void)
if ((UINT32)cv_pointlimit.value <= redscore || (UINT32)cv_pointlimit.value <= bluescore) if ((UINT32)cv_pointlimit.value <= redscore || (UINT32)cv_pointlimit.value <= bluescore)
{ {
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
} }
} }
else else
@ -2344,7 +2344,7 @@ void P_CheckPointLimit(void)
if ((UINT32)cv_pointlimit.value <= players[i].score) if ((UINT32)cv_pointlimit.value <= players[i].score)
{ {
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
return; return;
} }
} }
@ -2388,7 +2388,7 @@ void P_CheckSurvivors(void)
{ {
CONS_Printf(M_GetText("The IT player has left the game.\n")); CONS_Printf(M_GetText("The IT player has left the game.\n"));
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
return; return;
} }
@ -2408,7 +2408,7 @@ void P_CheckSurvivors(void)
{ {
CONS_Printf(M_GetText("All players have been tagged!\n")); CONS_Printf(M_GetText("All players have been tagged!\n"));
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
} }
return; return;
@ -2420,7 +2420,7 @@ void P_CheckSurvivors(void)
{ {
CONS_Printf(M_GetText("There are no players able to become IT.\n")); CONS_Printf(M_GetText("There are no players able to become IT.\n"));
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
} }
return; return;
@ -2432,7 +2432,7 @@ void P_CheckSurvivors(void)
{ {
CONS_Printf(M_GetText("All players have been tagged!\n")); CONS_Printf(M_GetText("All players have been tagged!\n"));
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
} }
} }

View file

@ -8238,7 +8238,7 @@ static boolean P_LoadAddon(UINT16 numlumps)
{ {
CONS_Printf(M_GetText("Current map %d replaced by added file, ending the level to ensure consistency.\n"), gamemap); CONS_Printf(M_GetText("Current map %d replaced by added file, ending the level to ensure consistency.\n"), gamemap);
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
} }
return true; return true;

View file

@ -11758,7 +11758,7 @@ void P_PlayerThink(player_t *player)
if (!total || ((4*exiting)/total) >= numneeded) if (!total || ((4*exiting)/total) >= numneeded)
{ {
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
} }
else else
player->exiting = 3; player->exiting = 3;
@ -11766,7 +11766,7 @@ void P_PlayerThink(player_t *player)
else else
{ {
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
} }
} }

View file

@ -998,8 +998,7 @@ void Y_Ticker(void)
if (paused || P_AutoPause()) if (paused || P_AutoPause())
return; return;
LUA_HookBool(intertype == int_spec && stagefailed, LUA_HookBool(stagefailed, HOOK(IntermissionThinker));
HOOK(IntermissionThinker));
intertic++; intertic++;