From fa09c1beea65373c7cb2994fa2105abf79413bde 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 7743ef4bb..0bdc61aef 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -7501,6 +7501,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) @@ -7514,6 +7519,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); @@ -7521,6 +7529,19 @@ static void K_UpdatePlayerWaypoints(player_t *const player) // Update prev value (used for grief prevention code) 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) &&