diff --git a/src/d_player.h b/src/d_player.h index 2fc8bb62b..c0e3a361a 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -107,6 +107,8 @@ typedef enum PF_SHRINKME = 1<<28, // "Shrink me" cheat preference PF_SHRINKACTIVE = 1<<29, // "Shrink me" cheat is in effect. (Can't be disabled mid-race) + PF_VOID = 1<<30, // Removed from reality! When leaving hitlag, reenable visibility+collision and kill speed. + // up to 1<<31 is free } pflags_t; @@ -579,6 +581,8 @@ struct player_t tic_t ebrakefor; // Ebrake timer, used for visuals. + UINT16 faultflash; // Used for misc FAULT visuals + UINT32 roundscore; // battle score this round UINT8 emeralds; UINT8 bumpers; diff --git a/src/k_kart.c b/src/k_kart.c index 9c9feac0f..081b1b124 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -7788,6 +7788,37 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->superring--; } + if (player->pflags & PF_VOID) // Returning from FAULT VOID + { + player->pflags &= ~PF_VOID; + player->mo->renderflags &= ~RF_DONTDRAW; + player->mo->flags &= ~MF_NOCLIPTHING; + player->mo->momx = 0; + player->mo->momy = 0; + player->mo->momz = 0; + player->nocontrol = 0; + player->driftboost = 0; + player->strongdriftboost = 0; + player->tiregrease = 0; + player->sneakertimer = 0; + player->spindashboost = 0; + player->flashing = TICRATE/2; + player->ringboost = 0; + player->driftboost = player->strongdriftboost = 0; + player->gateBoost = 0; + } + + if (player->pflags & PF_FAULT && player->nocontrol) // Hold player on respawn platform, no fair skipping long POSITION areas + { + if (rainbowstartavailable && ((leveltime <= starttime) || (leveltime - starttime < 10*TICRATE))) + { + player->nocontrol = 50; + player->mo->renderflags |= RF_DONTDRAW; + player->mo->flags |= MF_NOCLIPTHING; + } + } + + if (player->stealingtimer == 0 && player->rocketsneakertimer) player->rocketsneakertimer--; diff --git a/src/k_respawn.c b/src/k_respawn.c index 873d00fd7..98661ad35 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -119,6 +119,8 @@ void K_DoFault(player_t *player) S_StartSound(player->mo, sfx_s3k83); player->karthud[khud_fault] = 1; player->pflags |= PF_FAULT; + player->mo->renderflags |= RF_DONTDRAW; + player->mo->flags |= MF_NOCLIPTHING; } } @@ -147,7 +149,12 @@ void K_DoIngameRespawn(player_t *player) // FAULT if (leveltime < starttime) + { + if (!(mapheaderinfo[gamemap-1]->levelflags & LF_SECTIONRACE)) + player->respawn.wp = K_GetFinishLineWaypoint()->prevwaypoints[0]; K_DoFault(player); + } + player->ringboost = 0; player->driftboost = player->strongdriftboost = 0; @@ -163,7 +170,7 @@ void K_DoIngameRespawn(player_t *player) player->respawn.pointz += K_RespawnOffset(player, player->respawn.flip); player->respawn.manual = false; // one respawn only! } - else if (player->respawn.wp != NULL && leveltime >= starttime) + else if (player->respawn.wp != NULL) { const UINT32 dist = RESPAWN_DIST + (player->airtime * 48); player->respawn.distanceleft = (dist * mapobjectscale) / FRACUNIT; @@ -272,7 +279,7 @@ void K_DoIngameRespawn(player_t *player) player->respawn.init = true; player->respawn.airtimer = player->airtime; - player->respawn.truedeath = false; + player->respawn.truedeath = !!(player->pflags & PF_FAULT); } /*-------------------------------------------------- @@ -612,6 +619,9 @@ static void K_DropDashWait(player_t *player) if (player->nocontrol == 0) player->respawn.timer--; + if (player->pflags & PF_FAULT) + return; + if (leveltime % 8 == 0) { const UINT8 ns = 8; diff --git a/src/p_mobj.c b/src/p_mobj.c index e83417123..e5b125bb8 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9805,6 +9805,17 @@ void P_MobjThinker(mobj_t *mobj) mobj->eflags |= MFE_PAUSED; mobj->hitlag--; + if (mobj->player != NULL && mobj->player->faultflash > 0) + { + ClearFakePlayerSkin(mobj->player); + if (mobj->player->faultflash & 1) + mobj->renderflags |= RF_DONTDRAW; + else + mobj->renderflags &= ~RF_DONTDRAW; + + mobj->player->faultflash--; + } + if (mobj->type == MT_DROPTARGET && mobj->reactiontime > 0 && mobj->hitlag == 2) { mobj->spritexscale = FRACUNIT; diff --git a/src/p_spec.c b/src/p_spec.c index 95f9d923f..7af6c6e7c 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1909,10 +1909,24 @@ static void K_HandleLapIncrement(player_t *player) { if (leveltime < starttime && !(gametyperules & GTR_ROLLINGSTART)) { - // Will fault the player - K_DoIngameRespawn(player); + // freeze 'em until fault penalty is over + player->mo->hitlag = starttime - leveltime + TICRATE*3; + P_ResetPlayer(player); + player->pflags |= PF_VOID; + player->mo->renderflags |= RF_DONTDRAW; + player->mo->flags |= MF_NOCLIPTHING; + player->nocontrol = UINT16_MAX; + player->hyudorotimer = UINT16_MAX; + player->speed = 0; + K_StripItems(player); + player->faultflash = TICRATE/3; + ClearFakePlayerSkin(player); + S_StartSound(player->mo, sfx_s3k8a); + P_MoveOrigin(player->mo, player->mo->old_x, player->mo->old_y, player->mo->z); + return; } - else if ((player->starpostnum == numstarposts) || (player->laps == 0)) + + if ((player->starpostnum == numstarposts) || (player->laps == 0)) { size_t i = 0; UINT8 nump = 0; @@ -1948,7 +1962,7 @@ static void K_HandleLapIncrement(player_t *player) player->karthud[khud_lapanimation] = 80; } - if (rainbowstartavailable == true) + if (rainbowstartavailable == true && player->mo->hitlag == 0) { S_StartSound(player->mo, sfx_s23c); player->startboost = 125; diff --git a/src/p_user.c b/src/p_user.c index 078f6e5ad..88a4f98ed 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4210,7 +4210,14 @@ void P_PlayerThink(player_t *player) if (player->nocontrol && player->nocontrol < UINT16_MAX) { if (!(--player->nocontrol)) - player->pflags &= ~PF_FAULT; + { + if (player->pflags & PF_FAULT) + { + player->pflags &= ~PF_FAULT; + player->mo->renderflags &= ~RF_DONTDRAW; + player->mo->flags &= ~MF_NOCLIPTHING; + } + } } else player->nocontrol = 0; diff --git a/src/r_skins.c b/src/r_skins.c index 8e236904b..d6294fa0d 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -433,7 +433,7 @@ void SetRandomFakePlayerSkin(player_t* player, boolean fast) SetFakePlayerSkin(player, i); - if (player->mo && player->spectator == false) + if (player->mo && player->spectator == false && !(player->pflags & PF_VOID)) { S_StartSound(player->mo, sfx_kc33); S_StartSound(player->mo, sfx_cdfm44); @@ -448,6 +448,7 @@ void SetRandomFakePlayerSkin(player_t* player, boolean fast) P_SetTarget(&box->target, parent); box->angle = FixedAngle((baseangle + j*90) * FRACUNIT); box->flags2 |= MF2_AMBUSH; + box->renderflags |= parent->renderflags; if (fast) { box->extravalue1 = 10; // Rotation rate @@ -500,7 +501,7 @@ void ClearFakePlayerSkin(player_t* player) if ((flags & SF_IRONMAN) && !P_MobjWasRemoved(player->mo)) { SetFakePlayerSkin(player, skinid); - if (player->spectator == false) + if (player->spectator == false && player->mo->hitlag == 0) { S_StartSound(player->mo, sfx_s3k9f); K_SpawnMagicianParticles(player->mo, 5);