From b4402a94860621c325ba622a7478303e0e3fa3d2 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 28 Feb 2024 18:10:46 -0800 Subject: [PATCH] Do not let distancetofinish change too drastically - When updating nextwaypoint, check if distancetofinish jumps more than 32768 units (8192 in 1/4 scale maps) - If it jumps this much, do not update the waypoints - This prevents nextwaypoint from skipping ahead in a map where waypoints from later in the course overlap waypoints from earlier --- src/k_kart.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/k_kart.c b/src/k_kart.c index d20ee5147..d770b324c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -9834,6 +9834,11 @@ static void K_UpdateDistanceFromFinishLine(player_t *const player) } } +static UINT32 u32_delta(UINT32 x, UINT32 y) +{ + return x > y ? x - y : y - x; +} + /*-------------------------------------------------- static void K_UpdatePlayerWaypoints(player_t *const player) @@ -9847,6 +9852,9 @@ static void K_UpdateDistanceFromFinishLine(player_t *const player) --------------------------------------------------*/ static void K_UpdatePlayerWaypoints(player_t *const player) { + const UINT32 distance_threshold = FixedMul(32768, mapobjectscale); + + waypoint_t *const old_currentwaypoint = player->currentwaypoint; waypoint_t *const old_nextwaypoint = player->nextwaypoint; boolean updaterespawn = K_SetPlayerNextWaypoint(player); @@ -9855,6 +9863,19 @@ static void K_UpdatePlayerWaypoints(player_t *const player) player->distancetofinishprev = player->distancetofinish; K_UpdateDistanceFromFinishLine(player); + // Respawning should be a full reset. + UINT32 delta = u32_delta(player->distancetofinish, player->distancetofinishprev); + if (player->respawn.state == RESPAWNST_NONE && delta > distance_threshold) + { + CONS_Debug(DBG_GAMELOGIC, "Player %s: waypoint ID %d too far away (%u > %u)\n", + sizeu1(player - players), K_GetWaypointID(player->nextwaypoint), delta, distance_threshold); + + // Distance jump is too great, keep the old waypoints and recalculate distance. + player->currentwaypoint = old_currentwaypoint; + player->nextwaypoint = old_nextwaypoint; + K_UpdateDistanceFromFinishLine(player); + } + // Respawn point should only be updated when we're going to a nextwaypoint if ((updaterespawn) && (player->respawn.state == RESPAWNST_NONE) &&