From 219f8d74a0259efc4c2b3538edb0d749902b69ae Mon Sep 17 00:00:00 2001 From: Antonio Martinez Date: Thu, 22 May 2025 16:35:53 -0400 Subject: [PATCH] Bot grip experiment --- src/d_player.h | 2 ++ src/k_bot.cpp | 8 ++++++-- src/k_hud.cpp | 2 ++ src/k_kart.c | 9 +++++++-- src/p_user.c | 3 +++ 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index d22f6f734..f056ca978 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -420,6 +420,8 @@ struct botvars_t UINT8 roulettePriority; // What items to go for on the roulette tic_t rouletteTimeout; // If it takes too long to decide, try lowering priority until we find something valid. + + angle_t predictionError; // How bad is our momentum angle relative to where we're trying to go? }; // player_t struct for round-specific condition tracking diff --git a/src/k_bot.cpp b/src/k_bot.cpp index 041a0be38..bc086c649 100644 --- a/src/k_bot.cpp +++ b/src/k_bot.cpp @@ -1427,10 +1427,11 @@ static INT32 K_HandleBotTrack(const player_t *player, ticcmd_t *cmd, botpredicti I_Assert(predict != nullptr); destangle = K_BotSmoothLanding(player, destangle); - moveangle = player->mo->angle + K_GetUnderwaterTurnAdjust(player); anglediff = AngleDeltaSigned(moveangle, destangle); + cmd->angle = std::min(destangle - moveangle, moveangle - destangle) >> TICCMD_REDUCE; + if (anglediff < 0) { turnsign = 1; @@ -1712,7 +1713,7 @@ static void K_BuildBotPodiumTiccmd(const player_t *player, ticcmd_t *cmd) Build ticcmd for bots with a style of BOT_STYLE_NORMAL --------------------------------------------------*/ -static void K_BuildBotTiccmdNormal(const player_t *player, ticcmd_t *cmd) +static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd) { precise_t t = 0; @@ -1724,6 +1725,9 @@ static void K_BuildBotTiccmdNormal(const player_t *player, ticcmd_t *cmd) UINT8 spindash = 0; INT32 turnamt = 0; + cmd->angle = 0; // For bots, this is used to transmit prediction error to gamelogic. + // Will be overwritten by K_HandleBotTrack if we have a destination. + if (!(gametyperules & GTR_BOTS) // No bot behaviors || K_GetNumWaypoints() == 0 // No waypoints || leveltime <= introtime // During intro camera diff --git a/src/k_hud.cpp b/src/k_hud.cpp index 616861b37..1aae11443 100644 --- a/src/k_hud.cpp +++ b/src/k_hud.cpp @@ -6689,6 +6689,8 @@ static void K_DrawBotDebugger(void) V_DrawSmallString(8, 66, 0, va("Complexity: %d", K_GetTrackComplexity())); V_DrawSmallString(8, 70, 0, va("Bot modifier: %.2f", FixedToFloat(K_BotMapModifier()))); + + V_DrawSmallString(8, 76, 0, va("Prediction error: %d", bot->botvars.predictionError)); } static void K_DrawGPRankDebugger(void) diff --git a/src/k_kart.c b/src/k_kart.c index 0371c1134..9c0264568 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -13022,14 +13022,19 @@ fixed_t K_PlayerBaseFriction(const player_t *player, fixed_t original) // A bit extra friction to help them without drifting. // Remove this line once they can drift. - frict -= extraFriction; + // frict -= extraFriction; + + angle_t MAXERROR = 45*ANG1; + fixed_t errorfrict = Easing_Linear(min(FRACUNIT, FixedDiv(player->botvars.predictionError, MAXERROR)), 0, FRACUNIT>>2); + + frict -= errorfrict; // Bots gain more traction as they rubberband. const fixed_t traction_value = FixedMul(player->botvars.rubberband, max(FRACUNIT, K_BotMapModifier())); if (traction_value > FRACUNIT) { const fixed_t traction_mul = traction_value - FRACUNIT; - frict -= FixedMul(extraFriction, traction_mul); + // frict -= FixedMul(extraFriction, traction_mul); } } } diff --git a/src/p_user.c b/src/p_user.c index 9e811dc01..c487f8ea3 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2321,6 +2321,9 @@ static void P_UpdatePlayerAngle(player_t *player) { // You're a bot. Go where you're supposed to go player->steering = targetsteering; + // But the "angle" field of this ticcmd stores your prediction error, + // which we use to apply friction. Transfer it! + player->botvars.predictionError = player->cmd.angle << TICCMD_REDUCE; } else if ((!(player->cmd.flags & TICCMD_RECEIVED)) && (!!(player->oldcmd.flags && TICCMD_RECEIVED))) {