mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-21 12:01:05 +00:00
Warp cheat adjustments
This commit is contained in:
parent
9e72b78a24
commit
492fe94597
12 changed files with 158 additions and 67 deletions
13
src/d_main.c
13
src/d_main.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
101
src/d_netcmd.c
101
src/d_netcmd.c
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
51
src/m_cond.c
51
src/m_cond.c
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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++;
|
||||
|
||||
|
|
Loading…
Reference in a new issue