From d56be63249b47c558e39825cd0a850bfdecc01b5 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 27 Feb 2023 20:54:31 -0800 Subject: [PATCH 1/4] Battle: eliminate players killed by the Overtime Barrier - Players killed this way become invisible and unable to move. - Ends the match when one player is remaining. --- src/k_battle.c | 30 ++++++++++++++++++++---------- src/p_user.c | 5 +++++ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/k_battle.c b/src/k_battle.c index d2a2175dd..bad1f1694 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -92,6 +92,9 @@ void K_CheckBumpers(void) UINT8 i; UINT8 numingame = 0; UINT8 nobumpers = 0; + UINT8 eliminated = 0; + + const boolean singleplayer = (battlecapsules || bossinfo.valid); if (!(gametyperules & GTR_BUMPERS)) return; @@ -113,21 +116,28 @@ void K_CheckBumpers(void) { nobumpers++; } + + if (players[i].pflags & PF_ELIMINATED) + { + eliminated++; + } } - if (battlecapsules || bossinfo.valid) + if (singleplayer + ? nobumpers > 0 && nobumpers >= numingame + : eliminated >= numingame - 1) { - if (nobumpers > 0 && nobumpers >= numingame) + for (i = 0; i < MAXPLAYERS; i++) { - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - if (players[i].spectator) - continue; + if (!playeringame[i]) + continue; + if (players[i].spectator) + continue; + + if (singleplayer) players[i].pflags |= PF_NOCONTEST; - P_DoPlayerExit(&players[i]); - } + + P_DoPlayerExit(&players[i]); } return; } diff --git a/src/p_user.c b/src/p_user.c index f95d5afc1..6eb0417ef 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2773,6 +2773,11 @@ static void P_DeathThink(player_t *player) } } + if ((player->pflags & PF_ELIMINATED) && (gametyperules & GTR_BUMPERS)) + { + playerGone = true; + } + if (playerGone == false && player->deadtimer > TICRATE) { player->playerstate = PST_REBORN; From ccd933556dabaa8b87f4722aaf6af4ce93b74dc6 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 27 Feb 2023 20:56:12 -0800 Subject: [PATCH 2/4] Battle: activate director after dying to Overtime Barrier --- src/p_user.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index 6eb0417ef..ba8741adf 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -58,6 +58,7 @@ #include "k_terrain.h" // K_SpawnSplashForMobj #include "k_color.h" #include "k_follower.h" +#include "k_director.h" #ifdef HW3SOUND #include "hardware/hw3sound.h" @@ -2783,6 +2784,13 @@ static void P_DeathThink(player_t *player) player->playerstate = PST_REBORN; } + // TODO: support splitscreen + // Spectate another player after 2 seconds + if (player == &players[consoleplayer] && playerGone == true && (gametyperules & GTR_BUMPERS) && player->deadtimer == 2*TICRATE) + { + K_ToggleDirector(true); + } + // Keep time rolling if (!(player->exiting || mapreset) && !(player->pflags & PF_NOCONTEST) && !stoppedclock) { From a55ddef52813dc459eb9afa7370deab0273340c2 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 6 Mar 2023 22:55:01 -0800 Subject: [PATCH 3/4] Add cv_scrambleremoved, disable scramble on P_RemoveMobj Because Monitors and players leaving leak references, disable this crashing to be able to test other stuff at least. --- src/p_local.h | 7 +++++++ src/p_mobj.c | 10 ++++++---- src/r_main.c | 3 +++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index 12362a548..799f81a01 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -66,6 +66,10 @@ extern "C" { #define P_GetPlayerViewHeight(player) (41*player->mo->height/48) +#ifdef PARANOIA +#define SCRAMBLE_REMOVED // Force debug build to crash when Removed mobj is accessed +#endif + typedef enum { THINK_POLYOBJ, @@ -282,6 +286,9 @@ extern mapthing_t *itemrespawnque[ITEMQUESIZE]; extern tic_t itemrespawntime[ITEMQUESIZE]; extern size_t iquehead, iquetail; extern consvar_t cv_gravity, cv_movebob; +#ifdef SCRAMBLE_REMOVED +extern consvar_t cv_scrambleremoved; +#endif void P_RespawnBattleBoxes(void); mobjtype_t P_GetMobjtype(UINT16 mthingtype); diff --git a/src/p_mobj.c b/src/p_mobj.c index 80f413216..6e1c7b111 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -51,6 +51,8 @@ static CV_PossibleValue_t CV_BobSpeed[] = {{0, "MIN"}, {4*FRACUNIT, "MAX"}, {0, NULL}}; consvar_t cv_movebob = CVAR_INIT ("movebob", "1.0", CV_FLOAT|CV_SAVE, CV_BobSpeed, NULL); +consvar_t cv_scrambleremoved = CVAR_INIT ("scrambleremoved", "On", CV_NETVAR, CV_OnOff, NULL); + actioncache_t actioncachehead; static mobj_t *overlaycap = NULL; @@ -11059,9 +11061,6 @@ mapthing_t *itemrespawnque[ITEMQUESIZE]; tic_t itemrespawntime[ITEMQUESIZE]; size_t iquehead, iquetail; -#ifdef PARANOIA -#define SCRAMBLE_REMOVED // Force debug build to crash when Removed mobj is accessed -#endif void P_RemoveMobj(mobj_t *mobj) { I_Assert(mobj != NULL); @@ -11197,7 +11196,10 @@ void P_RemoveMobj(mobj_t *mobj) // DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error. #ifdef SCRAMBLE_REMOVED // Invalidate mobj_t data to cause crashes if accessed! - memset((UINT8 *)mobj + sizeof(thinker_t), 0xff, sizeof(mobj_t) - sizeof(thinker_t)); + if (cv_scrambleremoved.value) + { + memset((UINT8 *)mobj + sizeof(thinker_t), 0xff, sizeof(mobj_t) - sizeof(thinker_t)); + } #endif } diff --git a/src/r_main.c b/src/r_main.c index b00717810..901942510 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1651,6 +1651,9 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_maxportals); CV_RegisterVar(&cv_movebob); +#ifdef SCRAMBLE_REMOVED + CV_RegisterVar(&cv_scrambleremoved); +#endif // Frame interpolation/uncapped CV_RegisterVar(&cv_fpscap); From b8a503f56a66215ad6da5007dc0fd6f29a841389 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 6 Mar 2023 23:37:41 -0800 Subject: [PATCH 4/4] Always sync health to bumpers in P_KillPlayer Fixes Death Pit respawning in Battle. --- src/p_inter.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 7204741e2..ff4b9f916 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1934,13 +1934,12 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, return false; } - K_DestroyBumpers(player, 1); - switch (type) { case DMG_DEATHPIT: // Respawn kill types K_DoIngameRespawn(player); + player->mo->health -= K_DestroyBumpers(player, 1); return false; case DMG_SPECTATOR: // disappearifies, but still gotta put items back in play @@ -1997,10 +1996,11 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, P_SetTarget(&boom->target, player->mo); } - K_DestroyBumpers(player, player->bumpers); player->pflags |= PF_ELIMINATED; } + K_DestroyBumpers(player, player->bumpers); + return true; }