diff --git a/src/d_player.h b/src/d_player.h index d7c87bc58..ec68fd9d1 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -106,8 +106,9 @@ typedef enum PF_ANALOGSTICK = 1<<14, // This player is using an analog joystick PF_TRUSTWAYPOINTS = 1<<15, // Do not activate lap cheat prevention next time finish line distance is updated + PF_FREEZEWAYPOINTS = 1<<16, // Skip the next waypoint/finish line distance update - //16-17 free, was previously itemflags stuff + //1<<17 free, was previously itemflags stuff PF_DRIFTINPUT = 1<<18, // Drifting! PF_GETSPARKS = 1<<19, // Can get sparks diff --git a/src/deh_tables.c b/src/deh_tables.c index cbdc39fc2..56141c56e 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4049,7 +4049,7 @@ const char *const PLAYERFLAG_LIST[] = { "ANALOGSTICK", // This player is using an analog joystick "TRUSTWAYPOINTS", // Do not activate lap cheat prevention next time finish line distance is updated - "\x01", // Free + "FREEZEWAYPOINTS", // Skip the next waypoint/finish line distance update "\x01", // Free "DRIFTINPUT", // Drifting! diff --git a/src/k_kart.c b/src/k_kart.c index b233bd9fb..63bfda0ac 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -10013,6 +10013,12 @@ static UINT32 u32_delta(UINT32 x, UINT32 y) --------------------------------------------------*/ static void K_UpdatePlayerWaypoints(player_t *const player) { + if (player->pflags & PF_FREEZEWAYPOINTS) + { + player->pflags &= ~PF_FREEZEWAYPOINTS; + return; + } + const UINT32 distance_threshold = FixedMul(32768, mapobjectscale); waypoint_t *const old_currentwaypoint = player->currentwaypoint; diff --git a/src/k_respawn.c b/src/k_respawn.c index d2da452db..824dfa9e5 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -203,15 +203,7 @@ void K_DoIngameRespawn(player_t *player) { if (player->respawn.fromRingShooter == true) { - waypoint_t *finishline = K_GetFinishLineWaypoint(); waypoint_t *prevWP = player->respawn.wp; - // Laps don't decrement while respawning, so don't cross behind the finish line - while (prevWP->numprevwaypoints > 0 && prevWP != finishline) - { - prevWP = prevWP->prevwaypoints[0]; - if (K_GetWaypointIsSpawnpoint(prevWP) == true) - break; - } const UINT32 dist = (player->airtime * 48); player->respawn.distanceleft = (dist * mapobjectscale) / FRACUNIT; diff --git a/src/p_map.c b/src/p_map.c index cd27930ed..3156c9b21 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3147,6 +3147,26 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff, Try { P_CrossSpecialLine(ld, oldside, thing); } + else if (ld->special == 2001 && thing->player) // Finish Line + { + // ~~ WAYPOINT BULLSHIT ~~ + // Right on the line, P_PointOnLineSide may + // disagree with P_TraceWaypointTraversal. + // If this happens, nextwaypoint may update + // ahead of the finish line before the player + // crosses it. + // This bloats the finish line distance and + // triggers lap cheat prevention, preventing + // the player from gaining a lap. + // Since this only seems like it can happen + // very near to the line, simply don't update + // waypoints if the player is touching the + // line but hasn't crossed it. + // This will cause distancetofinish to jump + // but only for a very short distance (the + // radius of the player). + thing->player->pflags |= PF_FREEZEWAYPOINTS; + } } // Currently this just iterates all checkpoints.