From 3445e6b6e6eecc04a8e9c90bb7f7324bdcb280f5 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Fri, 4 Apr 2025 22:31:35 -0400 Subject: [PATCH] Fix new waypoint jank --- src/d_player.h | 11 ++-- src/deh_tables.c | 3 +- src/k_kart.c | 146 ++++++++++++++++++++++++++++------------------- src/p_map.c | 20 +++++++ 4 files changed, 114 insertions(+), 66 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 02c1f32b9..03fac8868 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -102,13 +102,14 @@ typedef enum PF_UPDATEMYRESPAWN = 1<<19, PF_FLIPCAM = 1<<20, + PF_TRUSTWAYPOINTS = 1<<21, // Do not activate lap cheat prevention next time finish line distance is updated + PF_FREEZEWAYPOINTS = 1<<22, // Skip the next waypoint/finish line distance update + PF_HITFINISHLINE = 1<<23, // Already hit the finish line this tic + PF_WRONGWAY = 1<<24, // Moving the wrong way with respect to waypoints? - PF_HITFINISHLINE = 1<<22, // Already hit the finish line this tic - PF_WRONGWAY = 1<<23, // Moving the wrong way with respect to waypoints? - - PF_SHRINKME = 1<<24, // "Shrink me" cheat preference - PF_SHRINKACTIVE = 1<<25, // "Shrink me" cheat is in effect. (Can't be disabled mid-race) + PF_SHRINKME = 1<<25, // "Shrink me" cheat preference + PF_SHRINKACTIVE = 1<<26, // "Shrink me" cheat is in effect. (Can't be disabled mid-race) // up to 1<<30 is free PF_SLIDING = 1<<31, diff --git a/src/deh_tables.c b/src/deh_tables.c index ab4f4d6fd..d8b904ab1 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -270,8 +270,9 @@ const char *const PLAYERFLAG_LIST[] = { "UPDATEMYRESPAWN", "FLIPCAM", - "TRUSTWAYPOINTS", + "TRUSTWAYPOINTS", // Do not activate lap cheat prevention next time finish line distance is updated + "FREEZEWAYPOINTS", // Skip the next waypoint/finish line distance update "HITFINISHLINE", // Already hit the finish line this tic "WRONGWAY", // Moving the wrong way with respect to waypoints? diff --git a/src/k_kart.c b/src/k_kart.c index 0f0d30d94..26367e76d 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -7403,7 +7403,11 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) else if (player->bigwaypointgap == AUTORESPAWN_THRESHOLD) { S_StartSound(player->mo, sfx_s26d); - CONS_Printf("You are going the wrong way! You will automatically respawn in 7 seconds.\n"); + if (player == &players[consoleplayer]) + { + // Alert them. + CONS_Printf("You are going the wrong way! You will automatically respawn in 7 seconds.\n"); + } } } @@ -7977,7 +7981,6 @@ boolean K_SafeRespawnPosition(mobj_t * mo) } // if rover is valid and bestfofheight is closer then bestsectorheight and bestpoheight - // probably should consider flip if (result.result == RESPAWNRS_ROVER) { // Check if rover is bad based on both its terrain, and sector specials. @@ -8015,7 +8018,6 @@ boolean K_SafeRespawnPosition(mobj_t * mo) } // if po is valid and bestpoheight is closer then bestsectorheight and bestpoheight - // probably should consider flip else if (result.result == RESPAWNRS_PO) { // Check if po is bad based on both its terrain, and sector specials. @@ -8052,7 +8054,6 @@ boolean K_SafeRespawnPosition(mobj_t * mo) } } // if everything else is not closest check sector - // probably should consider flip else if (result.result == RESPAWNRS_SECTOR) { // Check if sector is bad based on both its terrain, and sector specials. @@ -8136,7 +8137,12 @@ static boolean K_SetPlayerNextWaypoint(player_t *player) waypoint_t *waypoint = K_GetBestWaypointForMobj(player->mo, player->currentwaypoint); // Our current waypoint. - player->currentwaypoint = bestwaypoint = waypoint; + bestwaypoint = waypoint; + + if (bestwaypoint != NULL) + { + player->currentwaypoint = bestwaypoint; + } // check the waypoint's location in relation to the player // If it's generally in front, it's fine, otherwise, use the best next/previous waypoint. @@ -8151,9 +8157,6 @@ static boolean K_SetPlayerNextWaypoint(player_t *player) angle_t angledelta = ANGLE_180; angle_t momdelta = ANGLE_180; - // Remove WRONG WAY flag. - player->pflags &= ~PF_WRONGWAY; - angledelta = playerangle - angletowaypoint; if (angledelta > ANGLE_180) { @@ -8175,6 +8178,7 @@ static boolean K_SetPlayerNextWaypoint(player_t *player) { angle_t nextbestdelta = ANGLE_90; angle_t nextbestmomdelta = ANGLE_90; + angle_t nextbestanydelta = ANGLE_MAX; size_t i = 0U; if ((waypoint->nextwaypoints != NULL) && (waypoint->numnextwaypoints > 0U)) @@ -8216,8 +8220,19 @@ static boolean K_SetPlayerNextWaypoint(player_t *player) momdelta = InvAngle(momdelta); } - if (angledelta < nextbestdelta || momdelta < nextbestmomdelta) + if (angledelta < nextbestanydelta || momdelta < nextbestanydelta) { + nextbestanydelta = min(angledelta, momdelta); + + if (nextbestanydelta >= ANGLE_90) + continue; + + // Wanted to use a next waypoint, so remove WRONG WAY flag. + // Done here instead of when set, because of finish line + // hacks meaning we might not actually use this one, but + // we still want to acknowledge we're facing the right way. + player->pflags &= ~PF_WRONGWAY; + if (waypoint->nextwaypoints[i] != finishline) // Allow finish line. { if (P_TraceWaypointTraversal(player->mo, waypoint->nextwaypoints[i]->mobj) == false) @@ -8300,6 +8315,10 @@ static boolean K_SetPlayerNextWaypoint(player_t *player) break; } } + else + { + bestwaypoint = waypoint->prevwaypoints[i]; + } nextbestdelta = angledelta; nextbestmomdelta = momdelta; @@ -8313,16 +8332,19 @@ static boolean K_SetPlayerNextWaypoint(player_t *player) } } - if ((!P_IsObjectOnGround(player->mo) - || player->respawn - || P_CheckDeathPitCollide(player->mo) - || P_InQuicksand(player->mo) - || !player->mo->health) - ) + if (!P_IsObjectOnGround(player->mo)) { updaterespawn = false; } + if (player->respawn + || P_CheckDeathPitCollide(player->mo) + || P_InQuicksand(player->mo) + || !player->mo->health) + { + updaterespawn = false; + } + if (player->pflags & PF_UPDATEMYRESPAWN) { updaterespawn = true; @@ -8340,6 +8362,7 @@ static boolean K_SetPlayerNextWaypoint(player_t *player) return updaterespawn; } + /*-------------------------------------------------- static void K_UpdateDistanceFromFinishLine(player_t *const player) @@ -8620,6 +8643,12 @@ static void K_MobjFudgeRespawn(player_t *player, const mobj_t *const mobj) --------------------------------------------------*/ 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; @@ -8631,7 +8660,6 @@ 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 (delta > distance_threshold && !player->respawn && // Respawning should be a full reset. @@ -8647,7 +8675,7 @@ static void K_UpdatePlayerWaypoints(player_t *const player) CONS_Debug(DBG_GAMELOGIC, debug_args); #undef debug_args - if (!cv_kartdebuglap.value) + if (!cv_kartdebuglap.value && !player->exiting) { // Distance jump is too great, keep the old waypoints and old distance. player->currentwaypoint = old_currentwaypoint; @@ -8670,11 +8698,8 @@ static void K_UpdatePlayerWaypoints(player_t *const player) // While the player was in the "bigwaypointgap" state, laps did not change from crossing finish lines. // So reset the lap back to normal, in case they were able to get behind the line. - if (!K_UsingLegacyCheckpoints()) - { - player->laps = player->lastsafelap; - player->starpostnum = player->lastsafestarpost; - } + player->laps = player->lastsafelap; + player->starpostnum = player->lastsafestarpost; } } @@ -9234,37 +9259,30 @@ void K_KartUpdatePosition(player_t *player) return; } - for (i = 0; i < MAXPLAYERS; i++) { - if (!playeringame[i] || players[i].spectator || !players[i].mo) - continue; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator || !players[i].mo) + continue; - if (gametyperules & GTR_CIRCUIT) - { - if (player->exiting) // End of match standings + if (gametyperules & GTR_CIRCUIT) { - // Only time matters - if (players[i].realtime < player->realtime) - position++; - } - else - { - // I'm a lap behind this player OR - // My distance to the finish line is higher, so I'm behind - if ((players[i].laps > player->laps) - || (players[i].distancetofinish < player->distancetofinish)) + if (player->exiting) // End of match standings { - position++; + // Only time matters + if (players[i].realtime < player->realtime) + position++; + } + else + { + // I'm a lap behind this player OR + // My distance to the finish line is higher, so I'm behind + if ((players[i].laps > player->laps) + || (players[i].distancetofinish < player->distancetofinish)) + { + position++; + } } - } - } - else - { - if (player->exiting) // End of match standings - { - // Only score matters - if (players[i].roundscore > player->roundscore) - position++; } else { @@ -9276,11 +9294,20 @@ void K_KartUpdatePosition(player_t *player) } else { - // I have less points than but the same bumpers as this player OR - // I have less bumpers than this player - if ((players[i].bumper == player->bumper && players[i].roundscore > player->roundscore) - || (players[i].bumper > player->bumper)) - position++; + if (player->exiting) // End of match standings + { + // Only score matters + if (players[i].roundscore > player->roundscore) + position++; + } + else + { + // I have less points than but the same bumpers as this player OR + // I have less bumpers than this player + if ((players[i].bumper == player->bumper && players[i].roundscore > player->roundscore) + || (players[i].bumper > player->bumper)) + position++; + } } } } @@ -9289,8 +9316,10 @@ void K_KartUpdatePosition(player_t *player) if (leveltime < starttime || oldposition == 0) oldposition = position; - if (oldposition != position) // Changed places? + if (position != oldposition) // Changed places? + { player->positiondelay = 10; // Position number growth + } player->position = position; } @@ -9407,11 +9436,8 @@ void K_UpdateAllPlayerPositions(void) if (player->respawn > 0 && player->lastsafelap != player->laps) { - if (!K_UsingLegacyCheckpoints()) - { - player->laps = player->lastsafelap; - player->starpostnum = player->lastsafestarpost; - } + player->laps = player->lastsafelap; + player->starpostnum = player->lastsafestarpost; } K_UpdatePlayerWaypoints(player); @@ -9423,7 +9449,7 @@ void K_UpdateAllPlayerPositions(void) { if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) { - if (K_UsingLegacyCheckpoints()) + if (K_UsingLegacyCheckpoints() && !(gametype == GT_BATTLE)) K_KartLegacyUpdatePosition(&players[i]); else K_KartUpdatePosition(&players[i]); diff --git a/src/p_map.c b/src/p_map.c index a90273543..18f0edde2 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2843,6 +2843,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; + } } }