From 8aba05d5039631d057a0b2415449021ccaaac0e8 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Thu, 15 May 2025 14:38:07 -0400 Subject: [PATCH 1/9] [PATCH] Try to make bots better at drifting By GenericHeroGuy --- src/d_player.h | 2 ++ src/k_bot.cpp | 73 +++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 63 insertions(+), 12 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index f2de78d0f..dbc7d008e 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -471,6 +471,8 @@ struct botvars_t SINT8 driftturn; // Drifting turn direction tic_t drifttime; // Time spent drifting boolean powersliding; // Are we powersliding? + tic_t drifttimeout; // do not allow drifting for this many tics + tic_t driftending; // number of tics to force turning towards waypoint }; struct sonicloopcamvars_t diff --git a/src/k_bot.cpp b/src/k_bot.cpp index 8f568205f..2b0a65b70 100644 --- a/src/k_bot.cpp +++ b/src/k_bot.cpp @@ -1088,15 +1088,41 @@ static INT32 K_BotStartDrift(player_t* player) fixed_t botDriftSpeed, distToNext; INT32 driftsetting, turnamt; - if ((!(player->currentwaypoint)) || - (!(player->currentwaypoint->driftsettings))) + waypoint_t *wp = player->nextwaypoint; // player->currentwaypoint + + if (!wp || !wp->driftsettings) { // No waypoints, nothing we can do here. return 0; } + if (player->botvars.drifttimeout) + { + player->botvars.drifttimeout--; + return 0; + } + + if (player->speed < 10 * player->mo->scale) + { + // don't bother if we can't even drift + player->botvars.drifttime = 0; + player->botvars.driftstate = DRIFTSTATE_AUTO; + player->botvars.driftturn = 0; + player->botvars.powersliding = false; + + player->botvars.drifttimeout = TICRATE/2; + return 0; + } + + if (player->speed > K_GetKartSpeed(player, false, false) + 10*player->mo->scale) + { + // likewise, don't bother if we're going too fast + player->botvars.drifttimeout = TICRATE/4; + return 0; + } + turnamt = 0; - driftsetting = player->currentwaypoint->driftsettings; + driftsetting = wp->driftsettings; botDriftSpeed = FixedMul(K_GetKartSpeed(player, false, false), FixedPercentage(BOTDRIFTPERCENT)); @@ -1119,12 +1145,15 @@ static INT32 K_BotStartDrift(player_t* player) player->mo->z, R_PointToDist2(player->mo->x, player->mo->y, - player->currentwaypoint->mobj->x, - player->currentwaypoint->mobj->y), - player->currentwaypoint->mobj->z); + wp->mobj->x, + wp->mobj->y), + wp->mobj->z); + + // adjust for weight stat + distToNext -= (player->kartweight - 3) * 40*mapobjectscale; // If we're within distance, start drifting! - if (distToNext < player->currentwaypoint->mobj->radius) + if (distToNext < wp->mobj->radius*2) { shouldDrift = true; turnamt = KART_FULLTURN; @@ -1204,7 +1233,7 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * I_Assert(predict != nullptr); - moveangle = player->mo->angle; + moveangle = player->mo->angle - ANG2*2*player->drift; anglediff = AngleDeltaSigned(moveangle, destangle); if (anglediff < 0) @@ -1279,12 +1308,15 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * cmd->buttons |= BT_ACCELERATE; cmd->forwardmove = MAXPLMOVE; - if (dirdist <= rad) + if (dirdist <= rad && !player->botvars.driftending) { // Going the right way, don't turn at all. turnamt = 0; } + if (player->botvars.driftending) + player->botvars.driftending--; + fixed_t minspeed = (10 * player->mo->scale); // 0.5 on Easy, 1.0 on Normal, 1.5 on Hard. @@ -1294,10 +1326,26 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * if (player->botvars.drifttime) { // Confirm our drift angle. - if ((player->botvars.driftturn) - && (player->botvars.drifttime < 4)) + if (player->botvars.driftturn) { - turnamt = KART_FULLTURN * -player->botvars.driftturn; + fixed_t driftpower = FixedDiv(ANGLE_90 - anglediff - (ANG15*player->botvars.driftturn), ANGLE_90); + + // brakedrift if we're steering too hard + if (driftpower >= 21*FRACUNIT/20) + { + cmd->buttons |= BT_BRAKE; + } + + if (player->botvars.drifttime < 4) + { + driftpower = FRACUNIT; + } + else + { + driftpower = FixedMul(driftpower, FRACUNIT/3 + (player->kartweight * FRACUNIT/15)); + } + + turnamt = std::min(KART_FULLTURN, FixedMul(driftpower, KART_FULLTURN) * -player->botvars.driftturn); } else if ((player->botvars.powersliding) && (player->speed >= minspeed)) { @@ -1790,6 +1838,7 @@ void K_UpdateBotGameplayVars(player_t *player) { player->botvars.drifttime = 0; player->botvars.driftstate = DRIFTSTATE_AUTO; + player->botvars.driftending = TICRATE/2; } } else if ((player->botvars.driftamt) && (player->botvars.driftstate)) From 6657cd2c4636ee52bde33727ae9cf829c13d63a0 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Thu, 22 May 2025 23:27:32 +0200 Subject: [PATCH 2/9] What!? Help me! --- src/d_netcmd.c | 4 +++ src/d_netcmd.h | 2 ++ src/d_player.h | 3 +- src/k_bot.cpp | 83 ++++++++++++++++++++++++-------------------------- src/k_kart.c | 4 +++ 5 files changed, 51 insertions(+), 45 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index ead568b36..424137203 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -627,6 +627,10 @@ consvar_t cv_schedule = CVAR_INIT ("schedule", "On", CV_NETVAR|CV_CALL, CV_OnOff consvar_t cv_automate = CVAR_INIT ("automate", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_test1 = CVAR_INIT ("test1", "-25", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); +consvar_t cv_test2 = CVAR_INIT ("test2", "55", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); +consvar_t cv_test3 = CVAR_INIT ("test3", "0", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); + char timedemo_name[256]; boolean timedemo_csv; char timedemo_csv_id[256]; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 4f32fed27..81a9d991d 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -209,6 +209,8 @@ extern consvar_t cv_director; extern consvar_t cv_schedule; +extern consvar_t cv_test1, cv_test2, cv_test3; + extern char timedemo_name[256]; extern boolean timedemo_csv; extern char timedemo_csv_id[256]; diff --git a/src/d_player.h b/src/d_player.h index 6a04660e9..10ad95782 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -467,12 +467,13 @@ struct botvars_t fixed_t driftskill; // The bot's "skill" at drifts. // Determines how soon a bot starts to drift. INT32 driftstate; // Drifting state - INT32 driftamt; // Turning severity for a drift SINT8 driftturn; // Drifting turn direction tic_t drifttime; // Time spent drifting boolean powersliding; // Are we powersliding? tic_t drifttimeout; // do not allow drifting for this many tics tic_t driftending; // number of tics to force turning towards waypoint + + INT32 wpdriftstate; // drift state from waypoint }; struct sonicloopcamvars_t diff --git a/src/k_bot.cpp b/src/k_bot.cpp index 2b0a65b70..8492d2e98 100644 --- a/src/k_bot.cpp +++ b/src/k_bot.cpp @@ -1081,25 +1081,25 @@ static void K_WaypointGetDirectionVector(waypoint_t *wp1, waypoint_t *wp2, vecto Return:- Override value for turn amount. --------------------------------------------------*/ -static INT32 K_BotStartDrift(player_t* player) +static boolean K_BotStartDrift(player_t* player) { // Handle DRIFTING towards waypoints! boolean shouldDrift; fixed_t botDriftSpeed, distToNext; - INT32 driftsetting, turnamt; + INT32 driftsetting; waypoint_t *wp = player->nextwaypoint; // player->currentwaypoint if (!wp || !wp->driftsettings) { // No waypoints, nothing we can do here. - return 0; + return false; } if (player->botvars.drifttimeout) { player->botvars.drifttimeout--; - return 0; + return false; } if (player->speed < 10 * player->mo->scale) @@ -1111,17 +1111,17 @@ static INT32 K_BotStartDrift(player_t* player) player->botvars.powersliding = false; player->botvars.drifttimeout = TICRATE/2; - return 0; + return false; } if (player->speed > K_GetKartSpeed(player, false, false) + 10*player->mo->scale) { // likewise, don't bother if we're going too fast player->botvars.drifttimeout = TICRATE/4; - return 0; + return false; } - turnamt = 0; + shouldDrift = false; driftsetting = wp->driftsettings; botDriftSpeed = FixedMul(K_GetKartSpeed(player, false, false), FixedPercentage(BOTDRIFTPERCENT)); @@ -1129,8 +1129,6 @@ static INT32 K_BotStartDrift(player_t* player) if (((driftsetting)) && (driftsetting <= DRIFT_END)) { - shouldDrift = false; - // Randomly decide to drift based on our skill at drifting, // and how fast we're moving. fixed_t driftpotential = P_RandomKey(MAXDRIFTSKILL); @@ -1156,7 +1154,6 @@ static INT32 K_BotStartDrift(player_t* player) if (distToNext < wp->mobj->radius*2) { shouldDrift = true; - turnamt = KART_FULLTURN; } } } @@ -1167,45 +1164,48 @@ static INT32 K_BotStartDrift(player_t* player) switch (driftsetting) { case DRIFT_PWRSLIDE_L: + player->botvars.wpdriftstate = -2; player->botvars.driftstate = DRIFTSTATE_ACTIVE; player->botvars.driftturn = -1; player->botvars.powersliding = true; break; case DRIFT_LEFT: + player->botvars.wpdriftstate = -1; player->botvars.driftstate = DRIFTSTATE_ACTIVE; player->botvars.driftturn = -1; player->botvars.powersliding = false; break; case DRIFT_PWRSLIDE_R: + player->botvars.wpdriftstate = 2; player->botvars.driftstate = DRIFTSTATE_ACTIVE; player->botvars.driftturn = 1; player->botvars.powersliding = true; - turnamt *= -1; break; case DRIFT_RIGHT: + player->botvars.wpdriftstate = 1; player->botvars.driftstate = DRIFTSTATE_ACTIVE; player->botvars.driftturn = 1; player->botvars.powersliding = false; - turnamt *= -1; break; case DRIFT_END: + player->botvars.wpdriftstate = 0; if (player->botvars.driftstate) { player->botvars.driftstate = DRIFTSTATE_ENDING; - player->botvars.driftturn = 0; + //player->botvars.driftturn = 0; player->botvars.powersliding = false; - turnamt = INT32_MAX; // Tells the game not to modify turning. + shouldDrift = false; // Tells the game not to modify turning. } break; case DRIFT_NONE: default: - turnamt = 0; + shouldDrift = false; break; } } } - return turnamt; + return shouldDrift; } /*-------------------------------------------------- @@ -1226,14 +1226,14 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * ZoneScoped; // Handle steering towards waypoints! - INT32 turnamt = 0, driftamt = 0; + INT32 turnamt = 0; SINT8 turnsign = 0; angle_t moveangle; - INT32 anglediff; + INT32 anglediff, anglediff2; I_Assert(predict != nullptr); - moveangle = player->mo->angle - ANG2*2*player->drift; + moveangle = player->mo->angle; anglediff = AngleDeltaSigned(moveangle, destangle); if (anglediff < 0) @@ -1245,6 +1245,7 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * turnsign = -1; } + anglediff2 = anglediff; anglediff = abs(anglediff); turnamt = KART_FULLTURN * turnsign; @@ -1323,30 +1324,35 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * INT32 mindriftamt = FixedMul(MINBOTDRIFT * (cv_kartspeed.value + 1), 2 * FRACUNIT); // Start or continue a drift. - if (player->botvars.drifttime) + if (player->botvars.driftstate != DRIFTSTATE_AUTO) { + if (player->botvars.drifttime > 1) + cmd->buttons |= BT_DRIFT; + // Confirm our drift angle. - if (player->botvars.driftturn) + //if (player->botvars.driftturn) { - fixed_t driftpower = FixedDiv(ANGLE_90 - anglediff - (ANG15*player->botvars.driftturn), ANGLE_90); + fixed_t driftpower = (cv_test1.value*player->botvars.driftturn - FixedDiv(anglediff2, 11930464))/(FixedInt(cv_test2.value) - std::max(0, TICRATE/2 - player->botvars.drifttime)); // brakedrift if we're steering too hard - if (driftpower >= 21*FRACUNIT/20) + if (abs(driftpower) >= 21*FRACUNIT/20) { cmd->buttons |= BT_BRAKE; } - if (player->botvars.drifttime < 4) + /*if (player->botvars.drifttime < 4) { driftpower = FRACUNIT; } - else + else*/ { driftpower = FixedMul(driftpower, FRACUNIT/3 + (player->kartweight * FRACUNIT/15)); } - turnamt = std::min(KART_FULLTURN, FixedMul(driftpower, KART_FULLTURN) * -player->botvars.driftturn); + turnamt = std::clamp(FixedMul(driftpower, KART_FULLTURN), -KART_FULLTURN, KART_FULLTURN); + //CONS_Printf("%03d %03d\n", anglediff2/ANG1, FixedMul(driftpower, KART_FULLTURN)); } + /* else if ((player->botvars.powersliding) && (player->speed >= minspeed)) { // Force a mostly inward drift during powerslides. @@ -1359,23 +1365,15 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * turnamt = std::min(-MINBOTDRIFT, std::max(-mindriftamt, turnamt)); } } - - cmd->buttons |= BT_DRIFT; + */ } + /* else if ((turnamt) && (player->botvars.driftstate == DRIFTSTATE_AUTO) && (turnpower > FixedPercentage(DRIFTSTARTPCT))) { // TODO: Figure out a drift prediction system. } - else if ((player->botvars.driftamt < 2) && (player->botvars.driftstate)) - { - cmd->buttons |= BT_DRIFT; - - if (player->botvars.driftamt != INT32_MAX) - { - turnamt = driftamt; - } - } + */ } return turnamt; @@ -1820,7 +1818,7 @@ void K_UpdateBotGameplayVars(player_t *player) // Figure out if we need to drift. // Drift-ending waypoints will kill the drift timer, // so no need to worry about doing that ourselves. - player->botvars.driftamt = K_BotStartDrift(player); + boolean startdrift = K_BotStartDrift(player); if (player->botvars.drifttime) { @@ -1841,13 +1839,10 @@ void K_UpdateBotGameplayVars(player_t *player) player->botvars.driftending = TICRATE/2; } } - else if ((player->botvars.driftamt) && (player->botvars.driftstate)) + else if (startdrift && player->botvars.driftstate) { - if (player->botvars.driftamt != INT32_MAX) - { - // Ready to drift! - player->botvars.drifttime++; - } + // Ready to drift! + player->botvars.drifttime++; } } diff --git a/src/k_kart.c b/src/k_kart.c index 8a4126db7..fd73bc6ee 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -344,6 +344,10 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartdriftefx); CV_RegisterVar(&cv_driftsparkpulse); CV_RegisterVar(&cv_saltyhop); + + CV_RegisterVar(&cv_test1); + CV_RegisterVar(&cv_test2); + CV_RegisterVar(&cv_test3); } //} From 4812a25f9534c5cb5a419a088b8cda0afde92242 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Fri, 23 May 2025 18:35:00 +0200 Subject: [PATCH 3/9] AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --- src/d_main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/d_main.cpp b/src/d_main.cpp index 4c0194331..82c2a5284 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1884,9 +1884,11 @@ void D_SRB2Main(void) // ... unless you're in a dedicated server. Yes, technically this means you can view any level by // running a dedicated server and joining it yourself, but that's better than making dedicated server's // lives hell. +#if 0 if (!dedicated && M_MapLocked(pstartmap)) I_Error("You need to unlock this level before you can warp to it!\n"); else +#endif { D_MapChange(pstartmap, gametype, (cv_kartencore.value == 1), true, 0, false, false); } From abd496bd61f7d0075915e6ab23466f5284ab2c6a Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Fri, 23 May 2025 21:11:42 +0200 Subject: [PATCH 4/9] Behavior fixes, changed variables, an actual bot debugging HUD --- src/d_netcmd.c | 2 +- src/d_netcmd.h | 2 +- src/d_player.h | 11 +++--- src/k_bot.cpp | 93 +++++++++++++------------------------------------- src/k_hud.c | 24 +++++++++++++ src/k_kart.c | 2 +- src/p_map.c | 4 +-- src/p_saveg.c | 6 ++-- 8 files changed, 60 insertions(+), 84 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 424137203..cc6feaf7d 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -524,7 +524,7 @@ consvar_t cv_kartdebughuddrop = CVAR_INIT ("kartdebughuddrop", "Off", CV_NETVAR| static CV_PossibleValue_t kartdebugwaypoint_cons_t[] = {{0, "Off"}, {1, "Forwards"}, {2, "Backwards"}, {0, NULL}}; consvar_t cv_kartdebugwaypoints = CVAR_INIT ("kartdebugwaypoints", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugwaypoint_cons_t, NULL); consvar_t cv_kartdebuglap = CVAR_INIT ("kartdebuglap", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugwaypoint_cons_t, NULL); -consvar_t cv_kartdebugbotpredict = CVAR_INIT ("kartdebugbotpredict", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL); +consvar_t cv_kartdebugbot = CVAR_INIT ("kartdebugbot", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL); consvar_t cv_kartdebugcheckpoint = CVAR_INIT ("kartdebugcheckpoint", "Off", CV_NOSHOWHELP, CV_OnOff, NULL); consvar_t cv_kartdebugnodes = CVAR_INIT ("kartdebugnodes", "Off", CV_NOSHOWHELP, CV_OnOff, NULL); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 81a9d991d..7cba6b304 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -173,7 +173,7 @@ extern consvar_t cv_votetime; extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugdistribution, cv_kartdebughuddrop; extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes, cv_kartdebugcolorize, cv_kartdebugdirector; -extern consvar_t cv_kartdebugwaypoints, cv_kartdebuglap,cv_kartdebugbotpredict; +extern consvar_t cv_kartdebugwaypoints, cv_kartdebuglap, cv_kartdebugbot; extern consvar_t cv_itemfinder; diff --git a/src/d_player.h b/src/d_player.h index 10ad95782..c067aed00 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -424,8 +424,8 @@ typedef enum // Minimum turning percentage for an auto drift to begin. #define DRIFTSTARTPCT (45) -#define DRIFTTICMUL (43690) // FRACUNIT * 0.66 -#define BOTDRIFTTICS (FixedMul(TICRATE, DRIFTTICMUL)) +#define BOTDRIFTTICS (2*TICRATE/3) +#define BOTDRIFTLOCKOUT (TICRATE/2) #define MAXDRIFTSKILL (FRACUNIT/2) @@ -466,14 +466,11 @@ struct botvars_t // Drift-relevant data below: fixed_t driftskill; // The bot's "skill" at drifts. // Determines how soon a bot starts to drift. - INT32 driftstate; // Drifting state + botdrift_t driftstate; // Drifting state SINT8 driftturn; // Drifting turn direction tic_t drifttime; // Time spent drifting - boolean powersliding; // Are we powersliding? - tic_t drifttimeout; // do not allow drifting for this many tics + tic_t driftlockout; // do not allow drifting for this many tics tic_t driftending; // number of tics to force turning towards waypoint - - INT32 wpdriftstate; // drift state from waypoint }; struct sonicloopcamvars_t diff --git a/src/k_bot.cpp b/src/k_bot.cpp index 8492d2e98..0cee84077 100644 --- a/src/k_bot.cpp +++ b/src/k_bot.cpp @@ -1096,28 +1096,25 @@ static boolean K_BotStartDrift(player_t* player) return false; } - if (player->botvars.drifttimeout) + if (player->botvars.driftlockout) { - player->botvars.drifttimeout--; + // things are not working out in our favor return false; } if (player->speed < 10 * player->mo->scale) { // don't bother if we can't even drift - player->botvars.drifttime = 0; player->botvars.driftstate = DRIFTSTATE_AUTO; - player->botvars.driftturn = 0; - player->botvars.powersliding = false; - - player->botvars.drifttimeout = TICRATE/2; + player->botvars.driftlockout = BOTDRIFTLOCKOUT; return false; } if (player->speed > K_GetKartSpeed(player, false, false) + 10*player->mo->scale) { // likewise, don't bother if we're going too fast - player->botvars.drifttimeout = TICRATE/4; + player->botvars.driftstate = DRIFTSTATE_AUTO; + player->botvars.driftlockout = BOTDRIFTLOCKOUT/2; return false; } @@ -1164,36 +1161,25 @@ static boolean K_BotStartDrift(player_t* player) switch (driftsetting) { case DRIFT_PWRSLIDE_L: - player->botvars.wpdriftstate = -2; player->botvars.driftstate = DRIFTSTATE_ACTIVE; - player->botvars.driftturn = -1; - player->botvars.powersliding = true; + player->botvars.driftturn = -2; break; case DRIFT_LEFT: - player->botvars.wpdriftstate = -1; player->botvars.driftstate = DRIFTSTATE_ACTIVE; player->botvars.driftturn = -1; - player->botvars.powersliding = false; break; case DRIFT_PWRSLIDE_R: - player->botvars.wpdriftstate = 2; player->botvars.driftstate = DRIFTSTATE_ACTIVE; - player->botvars.driftturn = 1; - player->botvars.powersliding = true; + player->botvars.driftturn = 2; break; case DRIFT_RIGHT: - player->botvars.wpdriftstate = 1; player->botvars.driftstate = DRIFTSTATE_ACTIVE; player->botvars.driftturn = 1; - player->botvars.powersliding = false; break; case DRIFT_END: - player->botvars.wpdriftstate = 0; if (player->botvars.driftstate) { player->botvars.driftstate = DRIFTSTATE_ENDING; - //player->botvars.driftturn = 0; - player->botvars.powersliding = false; shouldDrift = false; // Tells the game not to modify turning. } break; @@ -1256,7 +1242,8 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * cmd->buttons |= BT_BRAKE; // Why would we need to drift? - cmd->buttons &= ~(BT_DRIFT); + player->botvars.driftstate = DRIFTSTATE_AUTO; + player->botvars.driftlockout = BOTDRIFTLOCKOUT; } else { @@ -1274,13 +1261,6 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * realrad = playerwidth; } - // Nonesensical and hacky. Figure out a better way eventually. - fixed_t turnpower = - FRACUNIT - - FixedMul( - FRACUNIT, - FixedDiv(std::max(0, ANGLE_90 - anglediff), ANGLE_90)); - // Become more precise based on how hard you need to turn // This makes predictions into turns a little nicer // Facing 90 degrees away from the predicted point gives you 0 radius @@ -1318,10 +1298,8 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * if (player->botvars.driftending) player->botvars.driftending--; - fixed_t minspeed = (10 * player->mo->scale); - // 0.5 on Easy, 1.0 on Normal, 1.5 on Hard. - INT32 mindriftamt = FixedMul(MINBOTDRIFT * (cv_kartspeed.value + 1), 2 * FRACUNIT); + //INT32 mindriftamt = FixedMul(MINBOTDRIFT * (cv_kartspeed.value + 1), 2 * FRACUNIT); // Start or continue a drift. if (player->botvars.driftstate != DRIFTSTATE_AUTO) @@ -1329,43 +1307,17 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * if (player->botvars.drifttime > 1) cmd->buttons |= BT_DRIFT; - // Confirm our drift angle. - //if (player->botvars.driftturn) + fixed_t driftpower = (cv_test1.value*player->botvars.driftturn - FixedDiv(anglediff2, 11930464))/(FixedInt(cv_test2.value) - std::max(0, TICRATE/2 - player->botvars.drifttime)); + + // brakedrift if we're steering too hard + if (abs(driftpower) >= 21*FRACUNIT/20) { - fixed_t driftpower = (cv_test1.value*player->botvars.driftturn - FixedDiv(anglediff2, 11930464))/(FixedInt(cv_test2.value) - std::max(0, TICRATE/2 - player->botvars.drifttime)); - - // brakedrift if we're steering too hard - if (abs(driftpower) >= 21*FRACUNIT/20) - { - cmd->buttons |= BT_BRAKE; - } - - /*if (player->botvars.drifttime < 4) - { - driftpower = FRACUNIT; - } - else*/ - { - driftpower = FixedMul(driftpower, FRACUNIT/3 + (player->kartweight * FRACUNIT/15)); - } - - turnamt = std::clamp(FixedMul(driftpower, KART_FULLTURN), -KART_FULLTURN, KART_FULLTURN); - //CONS_Printf("%03d %03d\n", anglediff2/ANG1, FixedMul(driftpower, KART_FULLTURN)); + cmd->buttons |= BT_BRAKE; } - /* - else if ((player->botvars.powersliding) && (player->speed >= minspeed)) - { - // Force a mostly inward drift during powerslides. - if (player->botvars.driftturn < 0) - { - turnamt = std::min(KART_FULLTURN, std::max(mindriftamt, turnamt)); - } - else - { - turnamt = std::min(-MINBOTDRIFT, std::max(-mindriftamt, turnamt)); - } - } - */ + + driftpower = FixedMul(driftpower, FRACUNIT/3 + (player->kartweight * FRACUNIT/15)); + + turnamt = std::clamp(FixedMul(driftpower, KART_FULLTURN), -KART_FULLTURN, KART_FULLTURN); } /* else if ((turnamt) && (player->botvars.driftstate == DRIFTSTATE_AUTO) && @@ -1695,7 +1647,7 @@ static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd) // Free the prediction we made earlier if (predict != nullptr) { - if (cv_kartdebugbotpredict.value != 0 && player - players == displayplayers[0] && !(paused || P_AutoPause())) + if (cv_kartdebugbot.value != 0 && player - players == displayplayers[0] && !(paused || P_AutoPause())) { K_DrawPredictionDebug(predict, player); } @@ -1800,6 +1752,9 @@ void K_UpdateBotGameplayVars(player_t *player) player->botvars.turnconfirm += player->cmd.bot.turnconfirm; + if (player->botvars.driftlockout) + player->botvars.driftlockout--; + // Is a bot not making any progress? Kill it and respawn at next waypoint. K_IncrementBotRespawn(player, &player->botvars.respawnconfirm, BOTRESPAWNCONFIRM); @@ -1832,7 +1787,7 @@ void K_UpdateBotGameplayVars(player_t *player) player->botvars.drifttime++; } - if (player->botvars.drifttime > BOTDRIFTTICS + 3) + if (player->botvars.drifttime > BOTDRIFTTICS) { player->botvars.drifttime = 0; player->botvars.driftstate = DRIFTSTATE_AUTO; diff --git a/src/k_hud.c b/src/k_hud.c index a88cc3f0f..e766d3299 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4813,6 +4813,29 @@ static void K_DrawWaypointDebugger(void) V_DrawString(8, 176, 0, va("Finishline Distance: %d", stplyr->distancetofinish)); } +static void K_DrawBotDebugger(void) +{ + if (!cv_kartdebugbot.value || !stplyr->bot) + return; + + if (stplyrnum != 0) // only for p1 + return; + + INT32 vflags = V_6WIDTHSPACE|V_ALLOWLOWERCASE; + + static const char *driftstates[] = { + [DRIFTSTATE_AUTO] = "Auto", + [DRIFTSTATE_ACTIVE] = "Active", + [DRIFTSTATE_ENDING] = "Ending", + }; + + V_DrawThinString(24, 100, vflags, va("Drift state: %s", driftstates[stplyr->botvars.driftstate])); + V_DrawThinString(24, 108, vflags|(stplyr->botvars.driftlockout ? V_ORANGEMAP : 0), va("Drift lockout: %d", stplyr->botvars.driftlockout)); + V_DrawThinString(24, 116, vflags, va("Drift turn: %d", stplyr->botvars.driftturn)); + V_DrawThinString(24, 124, vflags, va("Drift timer: %d", stplyr->botvars.drifttime)); + V_DrawThinString(24, 132, vflags, va("Drift end time: %d", stplyr->botvars.driftending)); +} + void K_drawKartHUD(void) { boolean islonesome = false; @@ -5048,5 +5071,6 @@ void K_drawKartHUD(void) } K_DrawWaypointDebugger(); + K_DrawBotDebugger(); K_DrawDirectorDebugger(); } diff --git a/src/k_kart.c b/src/k_kart.c index fd73bc6ee..fc5867070 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -266,7 +266,7 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartdebughuddrop); CV_RegisterVar(&cv_kartdebugwaypoints); CV_RegisterVar(&cv_kartdebuglap); - CV_RegisterVar(&cv_kartdebugbotpredict); + CV_RegisterVar(&cv_kartdebugbot); CV_RegisterVar(&cv_kartdebugcheckpoint); CV_RegisterVar(&cv_kartdebugnodes); diff --git a/src/p_map.c b/src/p_map.c index 270df41e8..fe5cff01d 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3691,10 +3691,8 @@ static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result) } // Regardless of bumpspark, tell bots to stop drifting if they bonk a wall. - mo->player->botvars.drifttime = 0; mo->player->botvars.driftstate = DRIFTSTATE_AUTO; - mo->player->botvars.driftturn = 0; - mo->player->botvars.powersliding = false; + mo->player->botvars.driftlockout = BOTDRIFTLOCKOUT; if (!cv_kartbumpspring.value || modeattacking != ATTACKING_NONE) { diff --git a/src/p_saveg.c b/src/p_saveg.c index 4f41f8383..0c7777074 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -386,7 +386,8 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEINT32(save->p, players[i].botvars.driftstate); WRITESINT8(save->p, players[i].botvars.driftturn); WRITEUINT32(save->p, players[i].botvars.drifttime); - WRITEUINT8(save->p, players[i].botvars.powersliding); + WRITEUINT32(save->p, players[i].botvars.driftlockout); + WRITEUINT32(save->p, players[i].botvars.driftending); WRITEFIXED(save->p, players[i].outrun); WRITEUINT8(save->p, players[i].outruntime); @@ -718,7 +719,8 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].botvars.driftstate = READINT32(save->p); players[i].botvars.driftturn = READSINT8(save->p); players[i].botvars.drifttime = READUINT32(save->p); - players[i].botvars.powersliding = (boolean)READUINT8(save->p); + players[i].botvars.driftlockout = READUINT32(save->p); + players[i].botvars.driftending = READUINT32(save->p); players[i].outrun = READFIXED(save->p); players[i].outruntime = READUINT8(save->p); From 481053a232b8d5f06606ec824a8e19db299f68e7 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Sat, 24 May 2025 00:29:34 +0200 Subject: [PATCH 5/9] An attempt at timing and setting up drifts --- src/d_netcmd.c | 4 +- src/d_player.h | 13 ++-- src/k_bot.cpp | 194 ++++++++++++++++++++++++++++--------------------- src/k_bot.h | 17 +++++ src/k_hud.c | 2 + src/p_map.c | 5 +- src/p_saveg.c | 4 +- 7 files changed, 148 insertions(+), 91 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index cc6feaf7d..95ca7a60d 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -627,9 +627,9 @@ consvar_t cv_schedule = CVAR_INIT ("schedule", "On", CV_NETVAR|CV_CALL, CV_OnOff consvar_t cv_automate = CVAR_INIT ("automate", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_test1 = CVAR_INIT ("test1", "-25", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); +consvar_t cv_test1 = CVAR_INIT ("test1", "-45", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); consvar_t cv_test2 = CVAR_INIT ("test2", "55", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); -consvar_t cv_test3 = CVAR_INIT ("test3", "0", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); +consvar_t cv_test3 = CVAR_INIT ("test3", "250", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); char timedemo_name[256]; boolean timedemo_csv; diff --git a/src/d_player.h b/src/d_player.h index c067aed00..f009ca891 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -438,11 +438,13 @@ typedef enum BOT_STYLE__MAX } botStyle_e; -typedef enum { - DRIFTSTATE_AUTO=0, - DRIFTSTATE_ACTIVE, - DRIFTSTATE_ENDING, - NUMDRIFTSTATES +typedef enum +{ + DRIFTSTATE_AUTO, + DRIFTSTATE_STARTING, + DRIFTSTATE_ACTIVE, + DRIFTSTATE_ENDING, + NUMDRIFTSTATES } botdrift_t; // player_t struct for all bot variables @@ -471,6 +473,7 @@ struct botvars_t tic_t drifttime; // Time spent drifting tic_t driftlockout; // do not allow drifting for this many tics tic_t driftending; // number of tics to force turning towards waypoint + UINT32 driftdist; // distance to finish when drift state changes }; struct sonicloopcamvars_t diff --git a/src/k_bot.cpp b/src/k_bot.cpp index 0cee84077..13fb31995 100644 --- a/src/k_bot.cpp +++ b/src/k_bot.cpp @@ -1068,6 +1068,24 @@ static void K_WaypointGetDirectionVector(waypoint_t *wp1, waypoint_t *wp2, vecto FV3_Normalize(a_o); } +/*-------------------------------------------------- + void K_BotSetDriftState(player_t *player, botdrift_t newstate, tic_t lockout) + + See header file for description. +--------------------------------------------------*/ +void K_BotSetDriftState(player_t *player, botdrift_t newstate, tic_t lockout) +{ + if (newstate != player->botvars.driftstate) + { + player->botvars.driftstate = newstate; + player->botvars.drifttime = 0; + player->botvars.driftdist = player->distancetofinish; + } + + if (lockout) + player->botvars.driftlockout = lockout; +} + #define MINBOTDRIFT (KART_FULLTURN * 2) / 3 // 0.66 /*-------------------------------------------------- @@ -1081,7 +1099,7 @@ static void K_WaypointGetDirectionVector(waypoint_t *wp1, waypoint_t *wp2, vecto Return:- Override value for turn amount. --------------------------------------------------*/ -static boolean K_BotStartDrift(player_t* player) +static void K_BotStartDrift(player_t* player) { // Handle DRIFTING towards waypoints! boolean shouldDrift; @@ -1093,29 +1111,27 @@ static boolean K_BotStartDrift(player_t* player) if (!wp || !wp->driftsettings) { // No waypoints, nothing we can do here. - return false; - } - - if (player->botvars.driftlockout) - { - // things are not working out in our favor - return false; + return; } if (player->speed < 10 * player->mo->scale) { // don't bother if we can't even drift - player->botvars.driftstate = DRIFTSTATE_AUTO; - player->botvars.driftlockout = BOTDRIFTLOCKOUT; - return false; + K_BotSetDriftState(player, DRIFTSTATE_AUTO, BOTDRIFTLOCKOUT); + return; } - if (player->speed > K_GetKartSpeed(player, false, false) + 10*player->mo->scale) + if (player->speed > K_GetKartSpeed(player, true, true) + 10*player->mo->scale) { // likewise, don't bother if we're going too fast - player->botvars.driftstate = DRIFTSTATE_AUTO; - player->botvars.driftlockout = BOTDRIFTLOCKOUT/2; - return false; + K_BotSetDriftState(player, DRIFTSTATE_AUTO, BOTDRIFTLOCKOUT/2); + return; + } + + if (player->botvars.driftlockout) + { + // things are not working out in our favor + return; } shouldDrift = false; @@ -1123,8 +1139,13 @@ static boolean K_BotStartDrift(player_t* player) botDriftSpeed = FixedMul(K_GetKartSpeed(player, false, false), FixedPercentage(BOTDRIFTPERCENT)); - if (((driftsetting)) && - (driftsetting <= DRIFT_END)) + if (driftsetting == DRIFT_END) + { + if (player->botvars.driftstate != DRIFTSTATE_AUTO) + K_BotSetDriftState(player, DRIFTSTATE_ENDING, 0); + } + else if (driftsetting > DRIFT_NONE && driftsetting < DRIFT_END + && player->botvars.driftstate == DRIFTSTATE_AUTO) { // Randomly decide to drift based on our skill at drifting, // and how fast we're moving. @@ -1133,65 +1154,50 @@ static boolean K_BotStartDrift(player_t* player) if ((driftpotential <= player->botvars.driftskill) && (botDriftSpeed <= player->speed)) { + // Get our distance from the waypoint. + distToNext = R_PointToDist2( + 0, + player->mo->z, + R_PointToDist2(player->mo->x, + player->mo->y, + wp->mobj->x, + wp->mobj->y), + wp->mobj->z); + + // If we're within distance, start drifting! + if (distToNext < wp->mobj->radius*2) { - // Get our distance from the waypoint. - distToNext = R_PointToDist2( - 0, - player->mo->z, - R_PointToDist2(player->mo->x, - player->mo->y, - wp->mobj->x, - wp->mobj->y), - wp->mobj->z); - - // adjust for weight stat - distToNext -= (player->kartweight - 3) * 40*mapobjectscale; - - // If we're within distance, start drifting! - if (distToNext < wp->mobj->radius*2) - { - shouldDrift = true; - } + shouldDrift = true; } } if (shouldDrift) { // Start our drift based on the waypoint's drift settings. + SINT8 driftturn = 0; + switch (driftsetting) { case DRIFT_PWRSLIDE_L: - player->botvars.driftstate = DRIFTSTATE_ACTIVE; - player->botvars.driftturn = -2; + driftturn = -2; break; case DRIFT_LEFT: - player->botvars.driftstate = DRIFTSTATE_ACTIVE; - player->botvars.driftturn = -1; + driftturn = -1; break; case DRIFT_PWRSLIDE_R: - player->botvars.driftstate = DRIFTSTATE_ACTIVE; - player->botvars.driftturn = 2; + driftturn = 2; break; case DRIFT_RIGHT: - player->botvars.driftstate = DRIFTSTATE_ACTIVE; - player->botvars.driftturn = 1; + driftturn = 1; break; - case DRIFT_END: - if (player->botvars.driftstate) - { - player->botvars.driftstate = DRIFTSTATE_ENDING; - shouldDrift = false; // Tells the game not to modify turning. - } - break; - case DRIFT_NONE: default: - shouldDrift = false; break; } + + player->botvars.driftturn = driftturn; + K_BotSetDriftState(player, DRIFTSTATE_STARTING, 0); } } - - return shouldDrift; } /*-------------------------------------------------- @@ -1222,6 +1228,13 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * moveangle = player->mo->angle; anglediff = AngleDeltaSigned(moveangle, destangle); + // line up for an incoming drift + if (player->botvars.driftstate == DRIFTSTATE_STARTING) + { + fixed_t speedfactor = FixedDiv(player->speed, K_GetKartSpeed(player, true, true)); + anglediff += FixedMul(ANG10-ANG2, speedfactor) * player->botvars.driftturn; + } + if (anglediff < 0) { turnsign = 1; @@ -1242,8 +1255,7 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * cmd->buttons |= BT_BRAKE; // Why would we need to drift? - player->botvars.driftstate = DRIFTSTATE_AUTO; - player->botvars.driftlockout = BOTDRIFTLOCKOUT; + K_BotSetDriftState(player, DRIFTSTATE_AUTO, BOTDRIFTLOCKOUT); } else { @@ -1289,25 +1301,23 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * cmd->buttons |= BT_ACCELERATE; cmd->forwardmove = MAXPLMOVE; - if (dirdist <= rad && !player->botvars.driftending) + if (dirdist <= rad + && player->botvars.driftstate != DRIFTSTATE_STARTING // steer towards waypoints when starting drift + && player->botvars.driftending == 0) // ...and after releasing a drift { // Going the right way, don't turn at all. turnamt = 0; } - if (player->botvars.driftending) - player->botvars.driftending--; - // 0.5 on Easy, 1.0 on Normal, 1.5 on Hard. //INT32 mindriftamt = FixedMul(MINBOTDRIFT * (cv_kartspeed.value + 1), 2 * FRACUNIT); // Start or continue a drift. - if (player->botvars.driftstate != DRIFTSTATE_AUTO) + if (player->botvars.driftstate == DRIFTSTATE_ACTIVE || player->botvars.driftstate == DRIFTSTATE_ENDING) { - if (player->botvars.drifttime > 1) - cmd->buttons |= BT_DRIFT; + cmd->buttons |= BT_DRIFT; - fixed_t driftpower = (cv_test1.value*player->botvars.driftturn - FixedDiv(anglediff2, 11930464))/(FixedInt(cv_test2.value) - std::max(0, TICRATE/2 - player->botvars.drifttime)); + fixed_t driftpower = ((cv_test1.value - std::max(0, TICRATE/4 - player->botvars.drifttime)*2)*player->botvars.driftturn - FixedDiv(anglediff2, 11930464))/FixedInt(cv_test2.value); // brakedrift if we're steering too hard if (abs(driftpower) >= 21*FRACUNIT/20) @@ -1755,6 +1765,9 @@ void K_UpdateBotGameplayVars(player_t *player) if (player->botvars.driftlockout) player->botvars.driftlockout--; + if (player->botvars.driftending) + player->botvars.driftending--; + // Is a bot not making any progress? Kill it and respawn at next waypoint. K_IncrementBotRespawn(player, &player->botvars.respawnconfirm, BOTRESPAWNCONFIRM); @@ -1773,31 +1786,50 @@ void K_UpdateBotGameplayVars(player_t *player) // Figure out if we need to drift. // Drift-ending waypoints will kill the drift timer, // so no need to worry about doing that ourselves. - boolean startdrift = K_BotStartDrift(player); + K_BotStartDrift(player); - if (player->botvars.drifttime) + player->botvars.drifttime++; + + // drift start is based on finishline distance since the drift waypoint was encountered + // once dist goes up and hits the threshold, start a drift + INT32 dist = player->botvars.driftdist - player->distancetofinish; + + // adjust for weight stat + //dist += (player->kartweight - 5) * 30; + + // the faster we are going, the sooner we need to drift + fixed_t speedfactor = FixedDiv(player->speed, K_GetKartSpeed(player, true, true)); + + switch (player->botvars.driftstate) { - // Continue the drift until we go over the threshold. - // Only increment when we're finishing our drift, or - // just starting it! - if (((player->botvars.driftstate == DRIFTSTATE_ENDING) || - (player->botvars.driftstate == DRIFTSTATE_AUTO)) || - (player->botvars.drifttime < 4)) + case DRIFTSTATE_STARTING: + // if we take too long to start drifting, just give up + if (player->botvars.drifttime > 2*TICRATE/3) { - player->botvars.drifttime++; + K_BotSetDriftState(player, DRIFTSTATE_AUTO, BOTDRIFTLOCKOUT); + break; } - if (player->botvars.drifttime > BOTDRIFTTICS) + dist = FixedMul(dist, 3*speedfactor/2 - FRACUNIT/2); + + if (dist > FixedInt(cv_test3.value)) { - player->botvars.drifttime = 0; - player->botvars.driftstate = DRIFTSTATE_AUTO; + K_BotSetDriftState(player, DRIFTSTATE_ACTIVE, 0); + } + break; + + case DRIFTSTATE_ENDING: + dist = FixedMul(dist, FRACUNIT/2 + speedfactor/2); + + if (dist > FixedInt(cv_test3.value)) + { + K_BotSetDriftState(player, DRIFTSTATE_AUTO, 0); player->botvars.driftending = TICRATE/2; } - } - else if (startdrift && player->botvars.driftstate) - { - // Ready to drift! - player->botvars.drifttime++; + break; + + default: + break; } } diff --git a/src/k_bot.h b/src/k_bot.h index 2f56c569a..e01c87380 100644 --- a/src/k_bot.h +++ b/src/k_bot.h @@ -390,6 +390,23 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt); fixed_t K_BotDetermineDriftSkill(player_t *player); +/*-------------------------------------------------- + void K_BotSetDriftState(player_t *player, botdrift_t newstate, tic_t lockout) + + Changes a bot's drift state. + Resets the drift timer if the old and new state are different. + + Input Arguments:- + player - Player to set drift state for. + newstate - The new drift state. + lockout - If non-zero, apply drift lockout for this many tics. + + Return:- + None +--------------------------------------------------*/ + +void K_BotSetDriftState(player_t *player, botdrift_t newstate, tic_t lockout); + #ifdef __cplusplus } // extern "C" diff --git a/src/k_hud.c b/src/k_hud.c index e766d3299..a483f9033 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4825,6 +4825,7 @@ static void K_DrawBotDebugger(void) static const char *driftstates[] = { [DRIFTSTATE_AUTO] = "Auto", + [DRIFTSTATE_STARTING] = "Starting", [DRIFTSTATE_ACTIVE] = "Active", [DRIFTSTATE_ENDING] = "Ending", }; @@ -4834,6 +4835,7 @@ static void K_DrawBotDebugger(void) V_DrawThinString(24, 116, vflags, va("Drift turn: %d", stplyr->botvars.driftturn)); V_DrawThinString(24, 124, vflags, va("Drift timer: %d", stplyr->botvars.drifttime)); V_DrawThinString(24, 132, vflags, va("Drift end time: %d", stplyr->botvars.driftending)); + V_DrawThinString(24, 140, vflags, va("Drift dist: %d", stplyr->botvars.driftdist - stplyr->distancetofinish)); } void K_drawKartHUD(void) diff --git a/src/p_map.c b/src/p_map.c index fe5cff01d..f515c0d99 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -42,6 +42,8 @@ #include "m_perfstats.h" // ps_checkposition_calls +#include "k_bot.h" + tm_t g_tm = {0}; void P_RestoreTMStruct(tm_t tmrestore) @@ -3691,8 +3693,7 @@ static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result) } // Regardless of bumpspark, tell bots to stop drifting if they bonk a wall. - mo->player->botvars.driftstate = DRIFTSTATE_AUTO; - mo->player->botvars.driftlockout = BOTDRIFTLOCKOUT; + K_BotSetDriftState(mo->player, DRIFTSTATE_AUTO, BOTDRIFTLOCKOUT); if (!cv_kartbumpspring.value || modeattacking != ATTACKING_NONE) { diff --git a/src/p_saveg.c b/src/p_saveg.c index 0c7777074..334cb17b6 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -388,6 +388,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT32(save->p, players[i].botvars.drifttime); WRITEUINT32(save->p, players[i].botvars.driftlockout); WRITEUINT32(save->p, players[i].botvars.driftending); + WRITEUINT32(save->p, players[i].botvars.driftdist); WRITEFIXED(save->p, players[i].outrun); WRITEUINT8(save->p, players[i].outruntime); @@ -721,7 +722,8 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].botvars.drifttime = READUINT32(save->p); players[i].botvars.driftlockout = READUINT32(save->p); players[i].botvars.driftending = READUINT32(save->p); - + players[i].botvars.driftdist = READUINT32(save->p); + players[i].outrun = READFIXED(save->p); players[i].outruntime = READUINT8(save->p); From 9ef9e41dba59021c67ec74b786ec8c20d51e6071 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Sun, 25 May 2025 02:33:29 +0200 Subject: [PATCH 6/9] Use prediction/pathfinding for drift waypoints --- src/d_main.cpp | 2 +- src/d_netcmd.c | 6 +-- src/d_player.h | 1 - src/k_bot.cpp | 118 ++++++++++++++++++++++++------------------------- src/k_hud.c | 1 - src/p_saveg.c | 4 +- 6 files changed, 64 insertions(+), 68 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 82c2a5284..004f33f64 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -87,7 +87,7 @@ #define ASSET_HASH_CHARS_KART 0x1e68a3e01aa5c68b #define ASSET_HASH_MAPS_KART 0x38558ed00da41ce9 #define ASSET_HASH_MAIN_PK3 0x90bc93435f9aa4c4 -#define ASSET_HASH_MAPPATCH_PK3 0xc789aadf69a0bcf9 +#define ASSET_HASH_MAPPATCH_PK3 0x6a8f4d3080d40af3 #ifdef USE_PATCH_FILE #define ASSET_HASH_PATCH_PK3 0x0000000000000000 #endif diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 95ca7a60d..08fc58835 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -627,9 +627,9 @@ consvar_t cv_schedule = CVAR_INIT ("schedule", "On", CV_NETVAR|CV_CALL, CV_OnOff consvar_t cv_automate = CVAR_INIT ("automate", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_test1 = CVAR_INIT ("test1", "-45", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); -consvar_t cv_test2 = CVAR_INIT ("test2", "55", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); -consvar_t cv_test3 = CVAR_INIT ("test3", "250", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); +consvar_t cv_test1 = CVAR_INIT ("test1", "400", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); +consvar_t cv_test2 = CVAR_INIT ("test2", "0.1", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); +consvar_t cv_test3 = CVAR_INIT ("test3", "10", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); char timedemo_name[256]; boolean timedemo_csv; diff --git a/src/d_player.h b/src/d_player.h index f009ca891..0391121c5 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -473,7 +473,6 @@ struct botvars_t tic_t drifttime; // Time spent drifting tic_t driftlockout; // do not allow drifting for this many tics tic_t driftending; // number of tics to force turning towards waypoint - UINT32 driftdist; // distance to finish when drift state changes }; struct sonicloopcamvars_t diff --git a/src/k_bot.cpp b/src/k_bot.cpp index 13fb31995..e04b2f6c7 100644 --- a/src/k_bot.cpp +++ b/src/k_bot.cpp @@ -1079,7 +1079,6 @@ void K_BotSetDriftState(player_t *player, botdrift_t newstate, tic_t lockout) { player->botvars.driftstate = newstate; player->botvars.drifttime = 0; - player->botvars.driftdist = player->distancetofinish; } if (lockout) @@ -1103,25 +1102,18 @@ static void K_BotStartDrift(player_t* player) { // Handle DRIFTING towards waypoints! boolean shouldDrift; - fixed_t botDriftSpeed, distToNext; - INT32 driftsetting; + fixed_t botDriftSpeed; + driftSetting_e driftsetting = DRIFT_NONE; + fixed_t speedfactor = FixedDiv(player->speed, K_GetKartSpeed(player, false, false)); - waypoint_t *wp = player->nextwaypoint; // player->currentwaypoint - - if (!wp || !wp->driftsettings) - { - // No waypoints, nothing we can do here. - return; - } - - if (player->speed < 10 * player->mo->scale) + if (speedfactor < FRACUNIT/2) { // don't bother if we can't even drift K_BotSetDriftState(player, DRIFTSTATE_AUTO, BOTDRIFTLOCKOUT); return; } - if (player->speed > K_GetKartSpeed(player, true, true) + 10*player->mo->scale) + if (speedfactor > 4*FRACUNIT/3) { // likewise, don't bother if we're going too fast K_BotSetDriftState(player, DRIFTSTATE_AUTO, BOTDRIFTLOCKOUT/2); @@ -1134,8 +1126,34 @@ static void K_BotStartDrift(player_t* player) return; } + // check for waypoints ahead of us with drift settings, based on our current speed + path_t path = {0}; + INT32 maxdist = FixedInt(cv_test1.value); + maxdist = FixedMul(maxdist, speedfactor + cv_test2.value); + + if (maxdist >= 0 && K_PathfindThruCircuit(player->currentwaypoint, maxdist, &path, false, false)) + { + for (size_t i = 0; i < path.numnodes; i++) + { + waypoint_t *wp = static_cast(path.array[i].nodedata); + if (wp->driftsettings) + driftsetting = static_cast(wp->driftsettings); + + // don't break on DRIFT_END waypoints, + // we could miss a drift waypoint right in front of it! + if (driftsetting != DRIFT_NONE && driftsetting != DRIFT_END) + break; + } + Z_Free(path.array); + } + + if (driftsetting == DRIFT_NONE) + { + // No waypoints, nothing we can do here. + return; + } + shouldDrift = false; - driftsetting = wp->driftsettings; botDriftSpeed = FixedMul(K_GetKartSpeed(player, false, false), FixedPercentage(BOTDRIFTPERCENT)); @@ -1154,21 +1172,7 @@ static void K_BotStartDrift(player_t* player) if ((driftpotential <= player->botvars.driftskill) && (botDriftSpeed <= player->speed)) { - // Get our distance from the waypoint. - distToNext = R_PointToDist2( - 0, - player->mo->z, - R_PointToDist2(player->mo->x, - player->mo->y, - wp->mobj->x, - wp->mobj->y), - wp->mobj->z); - - // If we're within distance, start drifting! - if (distToNext < wp->mobj->radius*2) - { - shouldDrift = true; - } + shouldDrift = true; } if (shouldDrift) @@ -1222,6 +1226,7 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * SINT8 turnsign = 0; angle_t moveangle; INT32 anglediff, anglediff2; + fixed_t speedfactor = FixedDiv(player->speed, K_GetKartSpeed(player, false, false)); I_Assert(predict != nullptr); @@ -1231,7 +1236,6 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * // line up for an incoming drift if (player->botvars.driftstate == DRIFTSTATE_STARTING) { - fixed_t speedfactor = FixedDiv(player->speed, K_GetKartSpeed(player, true, true)); anglediff += FixedMul(ANG10-ANG2, speedfactor) * player->botvars.driftturn; } @@ -1253,9 +1257,6 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * // Wrong way! cmd->forwardmove = -MAXPLMOVE; cmd->buttons |= BT_BRAKE; - - // Why would we need to drift? - K_BotSetDriftState(player, DRIFTSTATE_AUTO, BOTDRIFTLOCKOUT); } else { @@ -1317,13 +1318,23 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * { cmd->buttons |= BT_DRIFT; - fixed_t driftpower = ((cv_test1.value - std::max(0, TICRATE/4 - player->botvars.drifttime)*2)*player->botvars.driftturn - FixedDiv(anglediff2, 11930464))/FixedInt(cv_test2.value); + fixed_t angofs = -45*FRACUNIT; + + // steer a bit harder when starting a drift + angofs -= std::max(0, TICRATE/4 - player->botvars.drifttime)*2; + + // steer harder when above 75% speed + //if (speedfactor > 3*FRACUNIT/4) + //angofs = FixedMul(angofs, FRACUNIT/4 + 3*speedfactor/4); + + fixed_t driftpower = angofs*player->botvars.driftturn - FixedDiv(anglediff2, ANG1); + + // arbitrary divider on the final driftpower + driftpower /= 55; // brakedrift if we're steering too hard - if (abs(driftpower) >= 21*FRACUNIT/20) - { + if (abs(driftpower) >= FRACUNIT) cmd->buttons |= BT_BRAKE; - } driftpower = FixedMul(driftpower, FRACUNIT/3 + (player->kartweight * FRACUNIT/15)); @@ -1781,6 +1792,11 @@ void K_UpdateBotGameplayVars(player_t *player) player->botvars.respawnconfirm = 0; } + else if (player->cmd.forwardmove < 0) + { + // stop drifting if we're reversing + K_BotSetDriftState(player, DRIFTSTATE_AUTO, BOTDRIFTLOCKOUT); + } else { // Figure out if we need to drift. @@ -1788,40 +1804,24 @@ void K_UpdateBotGameplayVars(player_t *player) // so no need to worry about doing that ourselves. K_BotStartDrift(player); - player->botvars.drifttime++; - - // drift start is based on finishline distance since the drift waypoint was encountered - // once dist goes up and hits the threshold, start a drift - INT32 dist = player->botvars.driftdist - player->distancetofinish; - - // adjust for weight stat - //dist += (player->kartweight - 5) * 30; + tic_t limit, dtime = ++player->botvars.drifttime; // the faster we are going, the sooner we need to drift - fixed_t speedfactor = FixedDiv(player->speed, K_GetKartSpeed(player, true, true)); + fixed_t speedfactor = FixedDiv(player->speed, K_GetKartSpeed(player, false, false)); switch (player->botvars.driftstate) { case DRIFTSTATE_STARTING: - // if we take too long to start drifting, just give up - if (player->botvars.drifttime > 2*TICRATE/3) - { - K_BotSetDriftState(player, DRIFTSTATE_AUTO, BOTDRIFTLOCKOUT); - break; - } - - dist = FixedMul(dist, 3*speedfactor/2 - FRACUNIT/2); - - if (dist > FixedInt(cv_test3.value)) + limit = std::max(0, FixedInt(cv_test3.value) - FixedMul(TICRATE/5, speedfactor)); + if (dtime > limit) { K_BotSetDriftState(player, DRIFTSTATE_ACTIVE, 0); } break; case DRIFTSTATE_ENDING: - dist = FixedMul(dist, FRACUNIT/2 + speedfactor/2); - - if (dist > FixedInt(cv_test3.value)) + limit = std::max(0, FixedInt(cv_test3.value) - FixedMul(TICRATE/5, speedfactor)); + if (dtime > limit) { K_BotSetDriftState(player, DRIFTSTATE_AUTO, 0); player->botvars.driftending = TICRATE/2; diff --git a/src/k_hud.c b/src/k_hud.c index a483f9033..a82020237 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4835,7 +4835,6 @@ static void K_DrawBotDebugger(void) V_DrawThinString(24, 116, vflags, va("Drift turn: %d", stplyr->botvars.driftturn)); V_DrawThinString(24, 124, vflags, va("Drift timer: %d", stplyr->botvars.drifttime)); V_DrawThinString(24, 132, vflags, va("Drift end time: %d", stplyr->botvars.driftending)); - V_DrawThinString(24, 140, vflags, va("Drift dist: %d", stplyr->botvars.driftdist - stplyr->distancetofinish)); } void K_drawKartHUD(void) diff --git a/src/p_saveg.c b/src/p_saveg.c index 334cb17b6..5a739562b 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -388,8 +388,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT32(save->p, players[i].botvars.drifttime); WRITEUINT32(save->p, players[i].botvars.driftlockout); WRITEUINT32(save->p, players[i].botvars.driftending); - WRITEUINT32(save->p, players[i].botvars.driftdist); - + WRITEFIXED(save->p, players[i].outrun); WRITEUINT8(save->p, players[i].outruntime); @@ -722,7 +721,6 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].botvars.drifttime = READUINT32(save->p); players[i].botvars.driftlockout = READUINT32(save->p); players[i].botvars.driftending = READUINT32(save->p); - players[i].botvars.driftdist = READUINT32(save->p); players[i].outrun = READFIXED(save->p); players[i].outruntime = READUINT8(save->p); From 553ce473b114d47e13848452baeaf44d2c7f2214 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Mon, 26 May 2025 23:53:24 +0200 Subject: [PATCH 7/9] Use turnvalue for handling instead of some weird approximation --- src/k_bot.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/k_bot.cpp b/src/k_bot.cpp index 2d531725f..2ab8bbeb6 100644 --- a/src/k_bot.cpp +++ b/src/k_bot.cpp @@ -1120,12 +1120,6 @@ static void K_BotStartDrift(player_t* player) return; } - if (player->botvars.driftlockout) - { - // things are not working out in our favor - return; - } - // check for waypoints ahead of us with drift settings, based on our current speed path_t path = {0}; INT32 maxdist = FixedInt(cv_test1.value); @@ -1150,6 +1144,16 @@ static void K_BotStartDrift(player_t* player) if (driftsetting == DRIFT_NONE) { // No waypoints, nothing we can do here. + // ...except decrement driftlockout! + // do this here to prevent chaining drifts after messing up + if (player->botvars.driftlockout) + player->botvars.driftlockout--; + return; + } + + if (player->botvars.driftlockout) + { + // things are not working out in our favor return; } @@ -1336,9 +1340,11 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * if (abs(driftpower) >= FRACUNIT) cmd->buttons |= BT_BRAKE; - driftpower = FixedMul(driftpower, FRACUNIT/3 + (player->kartweight * FRACUNIT/15)); + // get the raw turn value and "invert" it (higher weight needs harder steering!) + INT16 turnvalue = abs(K_GetKartTurnValue(player, KART_FULLTURN * (player->botvars.driftturn < 0 ? 1 : -1))); + turnvalue = 541 - (turnvalue - 541); // weight 5 = 541 - turnamt = std::clamp(FixedMul(driftpower, KART_FULLTURN), -KART_FULLTURN, KART_FULLTURN); + turnamt = std::clamp(FixedMul(driftpower, turnvalue), -KART_FULLTURN, KART_FULLTURN); } /* else if ((turnamt) && (player->botvars.driftstate == DRIFTSTATE_AUTO) && @@ -1778,9 +1784,6 @@ void K_UpdateBotGameplayVars(player_t *player) player->botvars.turnconfirm += player->cmd.bot.turnconfirm; - if (player->botvars.driftlockout) - player->botvars.driftlockout--; - if (player->botvars.driftending) player->botvars.driftending--; From 7fbf5830a76ee36d0947763b89ba516f16b05252 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Tue, 27 May 2025 17:05:09 +0200 Subject: [PATCH 8/9] Trying to handle various different speeds... --- src/d_netcmd.c | 6 +++--- src/d_player.h | 1 - src/k_bot.cpp | 53 ++++++++++++++++++++------------------------------ src/k_hud.c | 1 - src/p_saveg.c | 2 -- 5 files changed, 24 insertions(+), 39 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index d48a4e0c9..a9d160191 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -627,9 +627,9 @@ consvar_t cv_schedule = CVAR_INIT ("schedule", "On", CV_NETVAR|CV_CALL, CV_OnOff consvar_t cv_automate = CVAR_INIT ("automate", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_test1 = CVAR_INIT ("test1", "400", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); -consvar_t cv_test2 = CVAR_INIT ("test2", "0.1", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); -consvar_t cv_test3 = CVAR_INIT ("test3", "10", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); +consvar_t cv_test1 = CVAR_INIT ("test1", "200", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); +consvar_t cv_test2 = CVAR_INIT ("test2", "40", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); +consvar_t cv_test3 = CVAR_INIT ("test3", "18", CV_NETVAR|CV_FLOAT, CV_Signed, NULL); char timedemo_name[256]; boolean timedemo_csv; diff --git a/src/d_player.h b/src/d_player.h index 0391121c5..b7cc5d967 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -472,7 +472,6 @@ struct botvars_t SINT8 driftturn; // Drifting turn direction tic_t drifttime; // Time spent drifting tic_t driftlockout; // do not allow drifting for this many tics - tic_t driftending; // number of tics to force turning towards waypoint }; struct sonicloopcamvars_t diff --git a/src/k_bot.cpp b/src/k_bot.cpp index 2ab8bbeb6..72bb4eb07 100644 --- a/src/k_bot.cpp +++ b/src/k_bot.cpp @@ -1108,22 +1108,29 @@ static void K_BotStartDrift(player_t* player) if (speedfactor < FRACUNIT/2) { - // don't bother if we can't even drift + // don't bother if we're going too slow K_BotSetDriftState(player, DRIFTSTATE_AUTO, BOTDRIFTLOCKOUT); return; } - if (speedfactor > 4*FRACUNIT/3) + if (speedfactor > (6-gamespeed)*FRACUNIT/3) { // likewise, don't bother if we're going too fast K_BotSetDriftState(player, DRIFTSTATE_AUTO, BOTDRIFTLOCKOUT/2); return; } + if (player->botvars.driftlockout) + { + // things are not working out in our favor + player->botvars.driftlockout--; + return; + } + // check for waypoints ahead of us with drift settings, based on our current speed path_t path = {0}; - INT32 maxdist = FixedInt(cv_test1.value); - maxdist = FixedMul(maxdist, speedfactor + cv_test2.value); + INT32 maxdist = FixedInt(cv_test1.value) + gamespeed*50; + maxdist = FixedMul(maxdist, speedfactor * (player->botvars.driftstate == DRIFTSTATE_ACTIVE ? 1 : 2)); if (maxdist >= 0 && K_PathfindThruCircuit(player->currentwaypoint, maxdist, &path, false, false)) { @@ -1144,16 +1151,6 @@ static void K_BotStartDrift(player_t* player) if (driftsetting == DRIFT_NONE) { // No waypoints, nothing we can do here. - // ...except decrement driftlockout! - // do this here to prevent chaining drifts after messing up - if (player->botvars.driftlockout) - player->botvars.driftlockout--; - return; - } - - if (player->botvars.driftlockout) - { - // things are not working out in our favor return; } @@ -1307,8 +1304,7 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * cmd->forwardmove = MAXPLMOVE; if (dirdist <= rad - && player->botvars.driftstate != DRIFTSTATE_STARTING // steer towards waypoints when starting drift - && player->botvars.driftending == 0) // ...and after releasing a drift + && player->botvars.driftstate != DRIFTSTATE_STARTING) // steer towards waypoints when starting drift { // Going the right way, don't turn at all. turnamt = 0; @@ -1322,19 +1318,15 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * { cmd->buttons |= BT_DRIFT; - fixed_t angofs = -45*FRACUNIT; + fixed_t angofs = K_GetKartSpeedFromStat(5 - (player->kartspeed - 5), false) * -player->botvars.driftturn; - // steer a bit harder when starting a drift - angofs -= std::max(0, TICRATE/4 - player->botvars.drifttime)*2; + // adjust for speed + angofs = FixedMul(angofs, speedfactor - (2-gamespeed)*FRACUNIT/4); - // steer harder when above 75% speed - //if (speedfactor > 3*FRACUNIT/4) - //angofs = FixedMul(angofs, FRACUNIT/4 + 3*speedfactor/4); - - fixed_t driftpower = angofs*player->botvars.driftturn - FixedDiv(anglediff2, ANG1); + fixed_t driftpower = angofs - FixedDiv(anglediff2, ANG1); // arbitrary divider on the final driftpower - driftpower /= 55; + driftpower /= FixedInt(cv_test2.value); // brakedrift if we're steering too hard if (abs(driftpower) >= FRACUNIT) @@ -1784,9 +1776,6 @@ void K_UpdateBotGameplayVars(player_t *player) player->botvars.turnconfirm += player->cmd.bot.turnconfirm; - if (player->botvars.driftending) - player->botvars.driftending--; - // Is a bot not making any progress? Kill it and respawn at next waypoint. K_IncrementBotRespawn(player, &player->botvars.respawnconfirm, BOTRESPAWNCONFIRM); @@ -1812,7 +1801,8 @@ void K_UpdateBotGameplayVars(player_t *player) // so no need to worry about doing that ourselves. K_BotStartDrift(player); - tic_t limit, dtime = ++player->botvars.drifttime; + INT32 limit = FixedInt(cv_test3.value) - gamespeed*5; + INT32 dtime = ++player->botvars.drifttime; // the faster we are going, the sooner we need to drift fixed_t speedfactor = FixedDiv(player->speed, K_GetKartSpeed(player, false, false)); @@ -1820,7 +1810,7 @@ void K_UpdateBotGameplayVars(player_t *player) switch (player->botvars.driftstate) { case DRIFTSTATE_STARTING: - limit = std::max(0, FixedInt(cv_test3.value) - FixedMul(TICRATE/5, speedfactor)); + limit = std::max(0, limit - FixedMul(TICRATE/5, speedfactor)); if (dtime > limit) { K_BotSetDriftState(player, DRIFTSTATE_ACTIVE, 0); @@ -1828,11 +1818,10 @@ void K_UpdateBotGameplayVars(player_t *player) break; case DRIFTSTATE_ENDING: - limit = std::max(0, FixedInt(cv_test3.value) - FixedMul(TICRATE/5, speedfactor)); + limit = std::max(0, limit - FixedMul(TICRATE/5, speedfactor)); if (dtime > limit) { K_BotSetDriftState(player, DRIFTSTATE_AUTO, 0); - player->botvars.driftending = TICRATE/2; } break; diff --git a/src/k_hud.c b/src/k_hud.c index a82020237..29c214624 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4834,7 +4834,6 @@ static void K_DrawBotDebugger(void) V_DrawThinString(24, 108, vflags|(stplyr->botvars.driftlockout ? V_ORANGEMAP : 0), va("Drift lockout: %d", stplyr->botvars.driftlockout)); V_DrawThinString(24, 116, vflags, va("Drift turn: %d", stplyr->botvars.driftturn)); V_DrawThinString(24, 124, vflags, va("Drift timer: %d", stplyr->botvars.drifttime)); - V_DrawThinString(24, 132, vflags, va("Drift end time: %d", stplyr->botvars.driftending)); } void K_drawKartHUD(void) diff --git a/src/p_saveg.c b/src/p_saveg.c index 7dcb868d3..b608e3724 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -387,7 +387,6 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITESINT8(save->p, players[i].botvars.driftturn); WRITEUINT32(save->p, players[i].botvars.drifttime); WRITEUINT32(save->p, players[i].botvars.driftlockout); - WRITEUINT32(save->p, players[i].botvars.driftending); WRITEFIXED(save->p, players[i].outrun); WRITEUINT8(save->p, players[i].outruntime); @@ -720,7 +719,6 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].botvars.driftturn = READSINT8(save->p); players[i].botvars.drifttime = READUINT32(save->p); players[i].botvars.driftlockout = READUINT32(save->p); - players[i].botvars.driftending = READUINT32(save->p); players[i].outrun = READFIXED(save->p); players[i].outruntime = READUINT8(save->p); From 454c62413e4504e9250891764f085f5de831fb0d Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Tue, 27 May 2025 17:21:42 +0200 Subject: [PATCH 9/9] Update hash --- src/d_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index a446cd8ae..6ad776040 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -87,7 +87,7 @@ #define ASSET_HASH_CHARS_KART 0x1e68a3e01aa5c68b #define ASSET_HASH_MAPS_KART 0x38558ed00da41ce9 #define ASSET_HASH_MAIN_PK3 0x3bbd056a4ce5e993 -#define ASSET_HASH_MAPPATCH_PK3 0x6a8f4d3080d40af3 +#define ASSET_HASH_MAPPATCH_PK3 0x01a21a5e96a2a76b #ifdef USE_PATCH_FILE #define ASSET_HASH_PATCH_PK3 0x0000000000000000 #endif