From 23408e7d3bcaf837660a349498076d1a628b510e Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 29 Sep 2022 03:53:30 -0700 Subject: [PATCH 1/2] Let savecheckpoint work online, work at all Actually respawns you at this location! :smiley: Uses object Z position instead of floor height. --- src/d_netcmd.c | 21 +++++++++++++++++++++ src/d_player.h | 1 + src/k_respawn.c | 8 +++++++- src/m_cheat.c | 12 ++++++------ src/m_cheat.h | 1 + src/p_saveg.c | 2 ++ 6 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e95df4d75..fb0db9c37 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1995,6 +1995,12 @@ void D_Cheat(INT32 playernum, INT32 cheat, ...) switch (cheat) { + case CHEAT_SAVECHECKPOINT: + COPY(WRITEFIXED, fixed_t); // x + COPY(WRITEFIXED, fixed_t); // y + COPY(WRITEFIXED, fixed_t); // z + break; + case CHEAT_RINGS: case CHEAT_LIVES: // If you're confused why 'int' instead of @@ -5502,6 +5508,21 @@ static void Got_Cheat(UINT8 **cp, INT32 playernum) break; } + case CHEAT_SAVECHECKPOINT: { + fixed_t x = READFIXED(*cp); + fixed_t y = READFIXED(*cp); + fixed_t z = READFIXED(*cp); + + player->respawn.pointx = x; + player->respawn.pointy = y; + player->respawn.pointz = z; + player->respawn.manual = true; + + CV_CheaterWarning(targetPlayer, va("temporary checkpoint created at %d, %d, %d", + x / FRACUNIT, y / FRACUNIT, z / FRACUNIT)); + break; + } + case CHEAT_RINGS: { SINT8 rings = READSINT8(*cp); diff --git a/src/d_player.h b/src/d_player.h index 28d126b55..406069c16 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -296,6 +296,7 @@ typedef struct respawnvars_s UINT32 distanceleft; // How far along the course to respawn you tic_t dropdash; // Drop Dash charge timer boolean truedeath; // Your soul has left your body + boolean manual; // Respawn coords were manually set, please respawn exactly there } respawnvars_t; // player_t struct for all bot variables diff --git a/src/k_respawn.c b/src/k_respawn.c index 94bb04e18..227cf221f 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -157,7 +157,13 @@ void K_DoIngameRespawn(player_t *player) P_ResetPlayer(player); // Set up respawn position if invalid - if (player->respawn.wp != NULL && leveltime >= starttime) + if (player->respawn.manual == true) + { + player->respawn.distanceleft = 0; + player->respawn.pointz += K_RespawnOffset(player, player->respawn.flip); + player->respawn.manual = false; // one respawn only! + } + else if (player->respawn.wp != NULL && leveltime >= starttime) { const UINT32 dist = RESPAWN_DIST + (player->airtime * 48); player->respawn.distanceleft = (dist * mapobjectscale) / FRACUNIT; diff --git a/src/m_cheat.c b/src/m_cheat.c index 70758b864..a324dfda1 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -686,15 +686,15 @@ void Command_Dumplua_f(void) void Command_Savecheckpoint_f(void) { + mobj_t *thing = players[consoleplayer].mo; + REQUIRE_CHEATS; REQUIRE_INLEVEL; - REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible - players[consoleplayer].respawn.pointx = players[consoleplayer].mo->x; - players[consoleplayer].respawn.pointy = players[consoleplayer].mo->y; - players[consoleplayer].respawn.pointz = players[consoleplayer].mo->floorz; - - CONS_Printf(M_GetText("Temporary checkpoint created at %d, %d, %d\n"), players[consoleplayer].respawn.pointx, players[consoleplayer].respawn.pointy, players[consoleplayer].respawn.pointz); + if (!P_MobjWasRemoved(thing)) + { + D_Cheat(consoleplayer, CHEAT_SAVECHECKPOINT, thing->x, thing->y, thing->z); + } } // Like M_GetAllEmeralds() but for console devmode junkies. diff --git a/src/m_cheat.h b/src/m_cheat.h index e12366b0f..0fe483d99 100644 --- a/src/m_cheat.h +++ b/src/m_cheat.h @@ -22,6 +22,7 @@ typedef enum { CHEAT_NOCLIP, CHEAT_GOD, + CHEAT_SAVECHECKPOINT, CHEAT_RINGS, CHEAT_LIVES, CHEAT_SCALE, diff --git a/src/p_saveg.c b/src/p_saveg.c index 233056f21..a6a987909 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -394,6 +394,7 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, players[i].respawn.distanceleft); WRITEUINT32(save_p, players[i].respawn.dropdash); WRITEUINT8(save_p, players[i].respawn.truedeath); + WRITEUINT8(save_p, players[i].respawn.manual); // botvars_t WRITEUINT8(save_p, players[i].botvars.difficulty); @@ -691,6 +692,7 @@ static void P_NetUnArchivePlayers(void) players[i].respawn.distanceleft = READUINT32(save_p); players[i].respawn.dropdash = READUINT32(save_p); players[i].respawn.truedeath = READUINT8(save_p); + players[i].respawn.manual = READUINT8(save_p); // botvars_t players[i].botvars.difficulty = READUINT8(save_p); From 13a17fa0f855cdf0a0771a21a1e5b3bb037430e2 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 29 Sep 2022 07:44:50 -0700 Subject: [PATCH 2/2] Disable checkpoint saved by savecheckpoint when disabling cheats What a mouthful. --- src/p_user.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_user.c b/src/p_user.c index a02b8e223..28371486a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4466,6 +4466,7 @@ void P_ResetPlayerCheats(void) continue; player->pflags &= ~(PF_GODMODE); + player->respawn.manual = false; if (P_MobjWasRemoved(thing)) continue;