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
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, serverGamedata))
I_Error("You need to unlock this level before you can warp to it!\n");
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);
}
}

View file

@ -1902,8 +1902,8 @@ static void Command_Map_f(void)
size_t option_gametype;
const char *gametypename;
boolean newresetplayers;
boolean wouldSetCheats;
boolean prevent_cheat;
boolean set_cheated;
INT32 newmapnum;
@ -1924,22 +1924,34 @@ static void Command_Map_f(void)
option_gametype = COM_CheckPartialParm("-g");
newresetplayers = ! COM_CheckParm("-noresetplayers");
wouldSetCheats =
!( netgame || multiplayer ) &&
!( usedCheats );
prevent_cheat = !( usedCheats ) && !( option_force || cv_debug );
if (wouldSetCheats && !option_force)
if (!( netgame || multiplayer ))
{
if (prevent_cheat)
{
/* May want to be more descriptive? */
CONS_Printf(M_GetText("Sorry, level change disabled in single player.\n"));
CONS_Printf(M_GetText("Cheats must be enabled to level change in single player.\n"));
return;
}
if (!newresetplayers && !cv_debug)
else
{
CONS_Printf(M_GetText("DEVMODE must be enabled.\n"));
set_cheated = true;
}
}
if (!newresetplayers)
{
if (prevent_cheat)
{
CONS_Printf(M_GetText("Cheats must be enabled to use -noresetplayers.\n"));
return;
}
else
{
set_cheated = true;
}
}
if (option_gametype)
{
@ -1959,7 +1971,9 @@ static void Command_Map_f(void)
}
if (!( first_option = COM_FirstOption() ))
{
first_option = COM_Argc();
}
if (first_option < 2)
{
@ -1982,11 +1996,6 @@ static void Command_Map_f(void)
return;
}
if (wouldSetCheats && option_force)
{
G_SetUsedCheats(false);
}
// new gametype value
// use current one by default
if (option_gametype)
@ -2028,15 +2037,13 @@ 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
{
if (!(
mapheaderinfo[newmapnum-1] &&
mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype)
))
{
if (prevent_cheat && !cv_skipmapcheck.value)
{
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"));
@ -2045,25 +2052,35 @@ static void Command_Map_f(void)
return;
}
else
{
// The player wants us to trek on anyway. Do so.
fromlevelselect = false;
set_cheated = ((gametypedefaultrules[newgametype] & GTR_CAMPAIGN) == GTR_CAMPAIGN);
}
}
else
{
fromlevelselect =
( netgame || multiplayer ) &&
newgametype == gametype &&
gametypedefaultrules[newgametype] & GTR_CAMPAIGN;
}
(gametypedefaultrules[newgametype] & GTR_CAMPAIGN);
}
// 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, serverGamedata))
if (M_CampaignWarpIsCheat(newgametype, newmapnum, serverGamedata))
{
CONS_Alert(CONS_NOTICE, M_GetText("You need to unlock this level before you can warp to it!\n"));
if (prevent_cheat)
{
CONS_Alert(CONS_NOTICE, M_GetText("Cheats must be enabled to warp to a locked level!\n"));
Z_Free(realmapname);
Z_Free(mapname);
return;
}
else
{
set_cheated = true;
}
}
// Ultimate Mode only in SP via menu
if (netgame || multiplayer)
@ -2079,6 +2096,11 @@ static void Command_Map_f(void)
}
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);
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"));
}
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)
{
if (!(netgame || (multiplayer && gametype != GT_COOP)) && !cv_debug)
CONS_Printf(M_GetText("This only works in a netgame.\n"));
else if (!(server || (IsPlayerAdmin(consoleplayer))))
if (!(server || (IsPlayerAdmin(consoleplayer))))
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
else if (( gamestate != GS_LEVEL && gamestate != GS_CREDITS ) || demoplayback)
CONS_Printf(M_GetText("You must be in a level to use this.\n"));
else
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
D_SendExitLevel(true);
}
static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum)
{
(void)cp;
boolean cheat = false;
cheat = (boolean)READUINT8(*cp);
// Ignore duplicate XD_EXITLEVEL commands.
if (gameaction == ga_completed)
{
return;
}
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
{
@ -4583,6 +4617,11 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum)
return;
}
if (G_CoopGametype() && cheat)
{
G_SetUsedCheats(false);
}
G_ExitLevel();
}

View file

@ -201,6 +201,7 @@ void D_SendPlayerConfig(void);
void Command_ExitGame_f(void);
void Command_Retry_f(void);
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);
boolean IsPlayerAdmin(INT32 playernum);
void SetAdminPlayer(INT32 playernum);

View file

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

View file

@ -2137,7 +2137,7 @@ boolean G_Responder(event_t *ev)
if (! netgame)
F_StartGameEvaluation();
else if (server || IsPlayerAdmin(consoleplayer))
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
D_SendExitLevel(false);
return true;
}
}
@ -3861,7 +3861,7 @@ static INT16 RandMap(UINT32 tolflags, INT16 pprevmap)
for (ix = 0; ix < NUMMAPS; ix++)
if (mapheaderinfo[ix] && (mapheaderinfo[ix]->typeoflevel & tolflags) == tolflags
&& 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;

View file

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

View file

@ -467,6 +467,15 @@ UINT8 M_SecretUnlocked(INT32 type, 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)
{
return false;
@ -480,6 +489,48 @@ UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data)
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 found = 0, i;

View file

@ -252,6 +252,7 @@ void M_SilentUpdateSkinAvailabilites(void);
UINT8 M_AnySecretUnlocked(gamedata_t *data);
UINT8 M_SecretUnlocked(INT32 type, 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);
// Emblem shit

View file

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

View file

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

View file

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