Merge branch 'basic-replay-cheats' into 'master'

Basic replay/spectator "cheats"

See merge request KartKrew/Kart!1613
This commit is contained in:
Oni 2023-11-18 00:57:46 +00:00
commit db36fc516f
3 changed files with 105 additions and 12 deletions

View file

@ -70,6 +70,7 @@
#include "k_powerup.h"
#include "k_roulette.h"
#include "k_bans.h"
#include "k_director.h"
#ifdef SRB2_CONFIG_ENABLE_WEBM_MOVIES
#include "m_avrecorder.h"
@ -1461,6 +1462,33 @@ void D_SendPlayerConfig(UINT8 n)
WeaponPref_Send(n);
}
static camera_t *LocalMutableCamera(INT32 playernum)
{
if (demo.playback)
{
// TODO: could have splitscreen support
if (!camera[0].freecam)
{
return NULL;
}
return &camera[0];
}
if (G_IsPartyLocal(playernum))
{
UINT8 viewnum = G_PartyPosition(playernum);
camera_t *cam = &camera[viewnum];
if (cam->freecam || (players[playernum].spectator && !K_DirectorIsAvailable(viewnum)))
{
return cam;
}
}
return NULL;
}
void D_Cheat(INT32 playernum, INT32 cheat, ...)
{
va_list ap;
@ -1468,12 +1496,62 @@ void D_Cheat(INT32 playernum, INT32 cheat, ...)
UINT8 buf[64];
UINT8 *p = buf;
camera_t *cam;
if ((cam = LocalMutableCamera(playernum)))
{
switch (cheat)
{
case CHEAT_RELATIVE_TELEPORT:
va_start(ap, cheat);
cam->x += va_arg(ap, fixed_t);
cam->y += va_arg(ap, fixed_t);
cam->z += va_arg(ap, fixed_t);
va_end(ap);
return;
case CHEAT_TELEPORT:
va_start(ap, cheat);
cam->x = va_arg(ap, fixed_t);
cam->y = va_arg(ap, fixed_t);
cam->z = va_arg(ap, fixed_t);
va_end(ap);
return;
case CHEAT_ANGLE:
va_start(ap, cheat);
cam->angle = va_arg(ap, angle_t);
va_end(ap);
return;
default:
break;
}
}
if (!CV_CheatsEnabled())
{
CONS_Printf("This cannot be used without cheats enabled.\n");
return;
}
if (demo.playback && cheat == CHEAT_DEVMODE)
{
// There is no networking in demos, but devmode is
// too useful to be inaccessible!
// TODO: maybe allow everything, even though it would
// desync replays? May be useful for debugging.
va_start(ap, cheat);
cht_debug = va_arg(ap, UINT32);
va_end(ap);
return;
}
// sanity check
if (demo.playback)
{
return;
}
WRITEUINT8(p, playernum);
WRITEUINT8(p, cheat);

View file

@ -285,6 +285,9 @@ boolean cht_Interpret(const char *password)
{ CONS_Printf(M_GetText("OBJECTPLACE must be enabled.\n")); return; }
#define REQUIRE_INLEVEL if (gamestate != GS_LEVEL || demo.playback)\
{ CONS_Printf(M_GetText("You must be in a level (and not a replay) to use this.\n")); return; }
#define REQUIRE_INLEVEL_OR_REPLAY if (gamestate != GS_LEVEL)\
{ CONS_Printf(M_GetText("You must be in a level to use this.\n")); return; }
#define REQUIRE_SINGLEPLAYER if (netgame)\
@ -361,7 +364,7 @@ void Command_RTeleport_f(void)
float z = atof(COM_Argv(3));
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_INLEVEL_OR_REPLAY;
if (COM_Argc() != 4)
{
@ -380,7 +383,7 @@ void Command_Teleport_f(void)
float z = atof(COM_Argv(3));
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_INLEVEL_OR_REPLAY;
if (COM_Argc() != 4)
{
@ -615,7 +618,7 @@ void Command_Goto_f(void)
const waypoint_t *wayp = K_GetWaypointFromID(id);
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_INLEVEL_OR_REPLAY;
if (COM_Argc() != 2)
{
@ -639,7 +642,7 @@ void Command_Angle_f(void)
const angle_t angle = FixedAngle(FLOAT_TO_FIXED(anglef));
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_INLEVEL_OR_REPLAY;
D_Cheat(consoleplayer, CHEAT_ANGLE, angle);
}
@ -661,7 +664,7 @@ void Command_RespawnAt_f(void)
void Command_GotoSkybox_f(void)
{
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_INLEVEL_OR_REPLAY;
mobj_t *skybox = players[consoleplayer].skybox.viewpoint;

View file

@ -452,10 +452,10 @@ void ST_drawDebugInfo(void)
{
INT32 height = 192;
const UINT8 screen = cv_devmode_screen.value - 1;
const UINT8 screen = min(r_splitscreen, cv_devmode_screen.value - 1);
// devmode_screen = 1..4
stplyr = &players[displayplayers[min(r_splitscreen, screen)]];
stplyr = &players[displayplayers[screen]];
if (!stplyr->mo)
return;
@ -472,11 +472,23 @@ void ST_drawDebugInfo(void)
if (cht_debug & DBG_BASIC)
{
const fixed_t d = AngleFixed(stplyr->mo->angle);
V_DrawRightAlignedString(320, height - 24, V_MONOSPACE, va("X: %6d", stplyr->mo->x>>FRACBITS));
V_DrawRightAlignedString(320, height - 16, V_MONOSPACE, va("Y: %6d", stplyr->mo->y>>FRACBITS));
V_DrawRightAlignedString(320, height - 8, V_MONOSPACE, va("Z: %6d", stplyr->mo->z>>FRACBITS));
V_DrawRightAlignedString(320, height, V_MONOSPACE, va("A: %6d", FixedInt(d)));
camera_t *cam = &camera[screen];
if (stplyr->spectator || cam->freecam)
{
const fixed_t d = AngleFixed(cam->angle);
V_DrawRightAlignedString(320, height - 24, V_MONOSPACE, va("X: %6d", cam->x>>FRACBITS));
V_DrawRightAlignedString(320, height - 16, V_MONOSPACE, va("Y: %6d", cam->y>>FRACBITS));
V_DrawRightAlignedString(320, height - 8, V_MONOSPACE, va("Z: %6d", cam->z>>FRACBITS));
V_DrawRightAlignedString(320, height, V_MONOSPACE, va("A: %6d", FixedInt(d)));
}
else
{
const fixed_t d = AngleFixed(stplyr->mo->angle);
V_DrawRightAlignedString(320, height - 24, V_MONOSPACE, va("X: %6d", stplyr->mo->x>>FRACBITS));
V_DrawRightAlignedString(320, height - 16, V_MONOSPACE, va("Y: %6d", stplyr->mo->y>>FRACBITS));
V_DrawRightAlignedString(320, height - 8, V_MONOSPACE, va("Z: %6d", stplyr->mo->z>>FRACBITS));
V_DrawRightAlignedString(320, height, V_MONOSPACE, va("A: %6d", FixedInt(d)));
}
height -= 40;
}