Let some cheat commands work online

noclip
god
scale
gravflip
hurtme
This commit is contained in:
James R 2022-09-29 02:24:55 -07:00
parent 0444e70413
commit 6426358377
5 changed files with 152 additions and 29 deletions

View file

@ -37,6 +37,7 @@
#include "r_data.h" // Color_cons_t
#include "r_skins.h"
#include "m_random.h"
#include "p_local.h" // P_ResetPlayerCheats
//========
// protos.

View file

@ -96,6 +96,7 @@ static void Got_DiscordInfo(UINT8 **cp, INT32 playernum);
static void Got_ScheduleTaskcmd(UINT8 **cp, INT32 playernum);
static void Got_ScheduleClearcmd(UINT8 **cp, INT32 playernum);
static void Got_Automatecmd(UINT8 **cp, INT32 playernum);
static void Got_Cheat(UINT8 **cp, INT32 playernum);
static void PointLimit_OnChange(void);
static void TimeLimit_OnChange(void);
@ -625,7 +626,8 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
"PLAYSOUND", // XD_PLAYSOUND
"SCHEDULETASK", // XD_SCHEDULETASK
"SCHEDULECLEAR", // XD_SCHEDULECLEAR
"AUTOMATE" // XD_AUTOMATE
"AUTOMATE", // XD_AUTOMATE
"CHEAT", // XD_CHEAT
};
// =========================================================================
@ -678,6 +680,8 @@ void D_RegisterServerCommands(void)
RegisterNetXCmd(XD_SCHEDULECLEAR, Got_ScheduleClearcmd);
RegisterNetXCmd(XD_AUTOMATE, Got_Automatecmd);
RegisterNetXCmd(XD_CHEAT, Got_Cheat);
// Remote Administration
COM_AddCommand("password", Command_Changepassword_f);
COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin
@ -1970,6 +1974,42 @@ void D_SendPlayerConfig(UINT8 n)
SendNetXCmdForPlayer(n, XD_POWERLEVEL, buf, p-buf);
}
void D_Cheat(INT32 playernum, INT32 cheat, ...)
{
va_list ap;
UINT8 buf[64];
UINT8 *p = buf;
if (!CV_CheatsEnabled())
{
CONS_Printf("This cannot be used without cheats enabled.\n");
return;
}
WRITEUINT8(p, playernum);
WRITEUINT8(p, cheat);
va_start(ap, cheat);
#define COPY(writemacro, type) writemacro (p, va_arg(ap, type))
switch (cheat)
{
case CHEAT_SCALE:
COPY(WRITEFIXED, fixed_t);
break;
case CHEAT_HURT:
COPY(WRITEINT32, INT32);
break;
}
#undef COPY
va_end(ap);
SendNetXCmd(XD_CHEAT, buf, p - buf);
}
// Only works for displayplayer, sorry!
static void Command_ResetCamera_f(void)
{
@ -5409,6 +5449,98 @@ static void Got_Automatecmd(UINT8 **cp, INT32 playernum)
}
}
static void Got_Cheat(UINT8 **cp, INT32 playernum)
{
UINT8 targetPlayer = READUINT8(*cp);
cheat_t cheat = READUINT8(*cp);
player_t *player;
if (cheat >= NUMBER_OF_CHEATS || !CV_CheatsEnabled() || targetPlayer >= MAXPLAYERS ||
playernode[targetPlayer] != playernode[playernum])
{
CONS_Alert(CONS_WARNING,
M_GetText ("Illegal cheat command received from %s\n"),
player_names[playernum]);
return;
}
player = &players[targetPlayer];
switch (cheat)
{
case CHEAT_NOCLIP: {
const char *status = "on";
if (!P_MobjWasRemoved(player->mo))
{
player->mo->flags ^= MF_NOCLIP;
if (!(player->mo->flags & MF_NOCLIP))
{
status = "off";
}
}
CV_CheaterWarning(targetPlayer, va("noclip %s", status));
break;
}
case CHEAT_GOD: {
const char *status = (player->pflags & PF_GODMODE) ? "off" : "on";
player->pflags ^= PF_GODMODE;
CV_CheaterWarning(targetPlayer, va("GOD MODE %s", status));
break;
}
case CHEAT_SCALE: {
const fixed_t smin = FRACUNIT/100;
const fixed_t smax = 100*FRACUNIT;
fixed_t s = READFIXED(*cp);
float f;
s = min(max(smin, s), smax);
f = FIXED_TO_FLOAT(s);
if (!P_MobjWasRemoved(player->mo))
{
player->mo->destscale = s;
}
CV_CheaterWarning(targetPlayer, va("scale = %d%s", (int)f, M_Ftrim(FIXED_TO_FLOAT(s))));
break;
}
case CHEAT_FLIP: {
if (!P_MobjWasRemoved(player->mo))
{
player->mo->flags2 ^= MF2_OBJECTFLIP;
}
CV_CheaterWarning(targetPlayer, "invert gravity");
break;
}
case CHEAT_HURT: {
INT32 damage = READINT32(*cp);
if (!P_MobjWasRemoved(player->mo))
{
P_DamageMobj(player->mo, NULL, NULL, damage, DMG_NORMAL);
}
CV_CheaterWarning(targetPlayer, va("%d damage to me", damage));
break;
}
case NUMBER_OF_CHEATS:
break;
}
}
/** Prints the number of displayplayers[0].
*
* \todo Possibly remove this; it was useful for debugging at one point.

View file

@ -179,6 +179,7 @@ typedef enum
XD_SCHEDULETASK, // 36
XD_SCHEDULECLEAR, // 37
XD_AUTOMATE, // 38
XD_CHEAT, // 39
MAXNETXCMD
} netxcmd_t;
@ -278,6 +279,8 @@ void Automate_Clear(void);
extern UINT32 livestudioaudience_timer;
void LiveStudioAudience(void);
void D_Cheat(INT32 playernum, INT32 cheat, ...);
// used for the player setup menu
UINT8 CanChangeSkin(INT32 playernum);

View file

@ -251,32 +251,18 @@ boolean cht_Responder(event_t *ev)
// command that can be typed at the console!
void Command_CheatNoClip_f(void)
{
player_t *plyr;
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER; // TODO: make netplay compatible
plyr = &players[consoleplayer];
if (!plyr->mo || P_MobjWasRemoved(plyr->mo))
return;
plyr->mo->flags ^= MF_NOCLIP;
CONS_Printf(M_GetText("No Clipping %s\n"), plyr->mo->flags & MF_NOCLIP ? M_GetText("On") : M_GetText("Off"));
D_Cheat(consoleplayer, CHEAT_NOCLIP);
}
void Command_CheatGod_f(void)
{
player_t *plyr;
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
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"));
D_Cheat(consoleplayer, CHEAT_GOD);
}
void Command_Scale_f(void)
@ -286,7 +272,6 @@ void Command_Scale_f(void)
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
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...
{
@ -294,29 +279,21 @@ void Command_Scale_f(void)
return;
}
if (!players[consoleplayer].mo)
return;
players[consoleplayer].mo->destscale = scale;
CONS_Printf(M_GetText("Scale set to %s\n"), COM_Argv(1));
D_Cheat(consoleplayer, CHEAT_SCALE, scale);
}
void Command_Gravflip_f(void)
{
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
if (players[consoleplayer].mo)
players[consoleplayer].mo->flags2 ^= MF2_OBJECTFLIP;
D_Cheat(consoleplayer, CHEAT_FLIP);
}
void Command_Hurtme_f(void)
{
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
if (COM_Argc() < 2)
{
@ -324,7 +301,7 @@ void Command_Hurtme_f(void)
return;
}
P_DamageMobj(players[consoleplayer].mo, NULL, NULL, atoi(COM_Argv(1)), DMG_NORMAL);
D_Cheat(consoleplayer, CHEAT_HURT, atoi(COM_Argv(1)));
}
void Command_RTeleport_f(void)

View file

@ -19,6 +19,16 @@
#include "p_mobj.h"
#include "command.h"
typedef enum {
CHEAT_NOCLIP,
CHEAT_GOD,
CHEAT_SCALE,
CHEAT_FLIP,
CHEAT_HURT,
NUMBER_OF_CHEATS
} cheat_t;
boolean cht_Responder(event_t *ev);
void cht_Init(void);