Add respawnat command, lightsnake to a specific waypoint

This commit is contained in:
James R 2023-04-24 15:02:53 -07:00
parent 35728a00e3
commit 94e3a6450b
3 changed files with 88 additions and 0 deletions

View file

@ -1109,6 +1109,7 @@ void D_RegisterClientCommands(void)
COM_AddCommand("grayscale", Command_Grayscale_f);
COM_AddCommand("goto", Command_Goto_f);
COM_AddCommand("angle", Command_Angle_f);
COM_AddCommand("respawnat", Command_RespawnAt_f);
CV_RegisterVar(&cv_renderhitbox);
CV_RegisterVar(&cv_devmode_screen);
@ -2034,6 +2035,10 @@ void D_Cheat(INT32 playernum, INT32 cheat, ...)
case CHEAT_ANGLE:
COPY(WRITEANGLE, angle_t);
break;
case CHEAT_RESPAWNAT:
COPY(WRITEINT32, INT32);
break;
}
#undef COPY
@ -6017,6 +6022,73 @@ static void Got_Cheat(UINT8 **cp, INT32 playernum)
break;
}
case CHEAT_RESPAWNAT: {
INT32 id = READINT32(*cp);
waypoint_t *finish = K_GetFinishLineWaypoint();
waypoint_t *waypoint = K_GetWaypointFromID(id);
path_t path = {0};
boolean retryBackwards = false;
const UINT32 baseDist = FixedMul(RESPAWN_DIST, mapobjectscale);
CV_CheaterWarning(targetPlayer, va("respawnat %d", id));
if (waypoint == NULL)
{
CONS_Alert(CONS_WARNING, "respawnat: no waypoint with that ID\n");
break;
}
// First, just try to go forward normally
if (K_PathfindToWaypoint(player->respawn.wp, waypoint, &path, false, false))
{
// If the path forward is too short, extend it by moving the origin behind
if (path.totaldist < baseDist)
{
retryBackwards = true;
}
else
{
size_t i;
for (i = 0; i < path.numnodes; ++i)
{
// If we had to cross the finish line, this waypoint is behind us
if (path.array[i].nodedata == finish)
{
retryBackwards = true;
break;
}
}
}
Z_Free(path.array);
}
else
{
retryBackwards = true;
}
if (retryBackwards)
{
memset(&path, 0, sizeof path);
if (!K_PathfindThruCircuit(waypoint, baseDist, &path, false, true))
{
CONS_Alert(CONS_WARNING, "respawnat: no path to waypoint\n");
break;
}
// Update origin since lightsnake must go forwards
player->respawn.wp = path.array[path.numnodes - 1].nodedata;
Z_Free(path.array);
}
player->respawn.state = RESPAWNST_NONE;
K_DoIngameRespawn(player);
player->respawn.distanceleft = retryBackwards ? baseDist : path.totaldist;
break;
}
case NUMBER_OF_CHEATS:
break;
}

View file

@ -614,6 +614,20 @@ void Command_Angle_f(void)
D_Cheat(consoleplayer, CHEAT_ANGLE, angle);
}
void Command_RespawnAt_f(void)
{
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
if (COM_Argc() != 2)
{
CONS_Printf(M_GetText("respawnat <waypoint id>: lightsnake to a specific waypoint\n"));
return;
}
D_Cheat(consoleplayer, CHEAT_RESPAWNAT, atoi(COM_Argv(1)));
}
//
// OBJECTPLACE (and related variables)
//

View file

@ -38,6 +38,7 @@ typedef enum {
CHEAT_GIVEITEM,
CHEAT_SCORE,
CHEAT_ANGLE,
CHEAT_RESPAWNAT,
NUMBER_OF_CHEATS
} cheat_t;
@ -86,6 +87,7 @@ void Command_Weather_f(void);
void Command_Grayscale_f(void);
void Command_Goto_f(void);
void Command_Angle_f(void);
void Command_RespawnAt_f(void);
#ifdef _DEBUG
void Command_CauseCfail_f(void);
#endif