diff --git a/src/d_player.h b/src/d_player.h index 47a9e1bdf..2f27838bf 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -939,6 +939,8 @@ struct player_t UINT16 infinitether; // Generic infinitether time, used for infinitether leniency. + UINT8 finalfailsafe; // When you can't Ringshooter, force respawn as a last ditch effort! + UINT8 lastsafelap; mobj_t *stumbleIndicator; diff --git a/src/k_kart.c b/src/k_kart.c index c481cb13a..a8545530d 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8616,6 +8616,20 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) K_RemoveGrowShrink(player); } + if (player->respawn.state == RESPAWNST_NONE && (player->cmd.buttons & BT_RESPAWN) == BT_RESPAWN) + { + player->finalfailsafe++; // Decremented by ringshooter to "freeze" this timer + if (player->finalfailsafe >= 4*TICRATE) + { + K_DoIngameRespawn(player); + player->finalfailsafe = 0; + } + } + else + { + player->finalfailsafe = 0; + } + if (player->superring) { player->nextringaward++; diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index be0e0b9d3..e7d603c6f 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -341,6 +341,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->trickcharge); else if (fastcmp(field,"infinitether")) lua_pushinteger(L, plr->infinitether); + else if (fastcmp(field,"finalfailsafe")) + lua_pushinteger(L, plr->finalfailsafe); else if (fastcmp(field,"lastsafelap")) lua_pushinteger(L, plr->lastsafelap); else if (fastcmp(field,"instaWhipCharge")) @@ -841,6 +843,8 @@ static int player_set(lua_State *L) plr->trickcharge = luaL_checkinteger(L, 3); else if (fastcmp(field,"infinitether")) plr->infinitether = luaL_checkinteger(L, 3); + else if (fastcmp(field,"finalfailsafe")) + plr->finalfailsafe = luaL_checkinteger(L, 3); else if (fastcmp(field,"lastsafelap")) plr->lastsafelap = luaL_checkinteger(L, 3); else if (fastcmp(field,"instaWhipCharge")) diff --git a/src/objects/ring-shooter.c b/src/objects/ring-shooter.c index eee9a6d80..43869c12b 100644 --- a/src/objects/ring-shooter.c +++ b/src/objects/ring-shooter.c @@ -688,6 +688,10 @@ void Obj_RingShooterInput(player_t *player) if (AllowRingShooter(player) == true && (player->cmd.buttons & BT_RESPAWN) == BT_RESPAWN) { + // "Freeze" final-failsafe timer if we're eligible to ringshooter, but don't reset it. + if (player->finalfailsafe) + player->finalfailsafe--; + if (P_MobjWasRemoved(base) == true) { SpawnRingShooter(player); diff --git a/src/p_saveg.c b/src/p_saveg.c index 26b600fa1..88bb493d7 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -567,6 +567,8 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT16(save->p, players[i].infinitether); + WRITEUINT8(save->p, players[i].finalfailsafe); + WRITEUINT8(save->p, players[i].lastsafelap); WRITEMEM(save->p, players[i].public_key, PUBKEYLENGTH); @@ -1126,6 +1128,8 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].infinitether = READUINT16(save->p); + players[i].finalfailsafe = READUINT8(save->p); + players[i].lastsafelap = READUINT8(save->p); READMEM(save->p, players[i].public_key, PUBKEYLENGTH);