diff --git a/src/d_main.cpp b/src/d_main.cpp index ffca321a5..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 0x602a099e28f12544 +#define ASSET_HASH_MAPPATCH_PK3 0x01a21a5e96a2a76b #ifdef USE_PATCH_FILE #define ASSET_HASH_PATCH_PK3 0x0000000000000000 #endif @@ -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); } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index b36c5a2a9..a9d160191 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); @@ -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", "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; char timedemo_csv_id[256]; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 4f32fed27..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; @@ -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 a31d77eef..b7cc5d967 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) @@ -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 @@ -466,11 +468,10 @@ 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 - INT32 driftamt; // Turning severity for a drift + botdrift_t driftstate; // Drifting state SINT8 driftturn; // Drifting turn direction tic_t drifttime; // Time spent drifting - boolean powersliding; // Are we powersliding? + tic_t driftlockout; // do not allow drifting for this many tics }; struct sonicloopcamvars_t diff --git a/src/k_bot.cpp b/src/k_bot.cpp index 9155bffb1..72bb4eb07 100644 --- a/src/k_bot.cpp +++ b/src/k_bot.cpp @@ -1068,6 +1068,23 @@ 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; + } + + if (lockout) + player->botvars.driftlockout = lockout; +} + #define MINBOTDRIFT (KART_FULLTURN * 2) / 3 // 0.66 /*-------------------------------------------------- @@ -1081,30 +1098,74 @@ 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 void K_BotStartDrift(player_t* player) { // Handle DRIFTING towards waypoints! boolean shouldDrift; - fixed_t botDriftSpeed, distToNext; - INT32 driftsetting, turnamt; + fixed_t botDriftSpeed; + driftSetting_e driftsetting = DRIFT_NONE; + fixed_t speedfactor = FixedDiv(player->speed, K_GetKartSpeed(player, false, false)); - if ((!(player->currentwaypoint)) || - (!(player->currentwaypoint->driftsettings))) + if (speedfactor < FRACUNIT/2) { - // No waypoints, nothing we can do here. - return 0; + // don't bother if we're going too slow + K_BotSetDriftState(player, DRIFTSTATE_AUTO, BOTDRIFTLOCKOUT); + return; } - turnamt = 0; - driftsetting = player->currentwaypoint->driftsettings; + 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) + gamespeed*50; + maxdist = FixedMul(maxdist, speedfactor * (player->botvars.driftstate == DRIFTSTATE_ACTIVE ? 1 : 2)); + + 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; 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) { - shouldDrift = false; - // Randomly decide to drift based on our skill at drifting, // and how fast we're moving. fixed_t driftpotential = P_RandomKey(MAXDRIFTSKILL); @@ -1112,71 +1173,36 @@ static INT32 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, - player->currentwaypoint->mobj->x, - player->currentwaypoint->mobj->y), - player->currentwaypoint->mobj->z); - - // If we're within distance, start drifting! - if (distToNext < player->currentwaypoint->mobj->radius) - { - shouldDrift = true; - turnamt = KART_FULLTURN; - } - } + 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 = -1; - player->botvars.powersliding = true; + driftturn = -2; break; case DRIFT_LEFT: - player->botvars.driftstate = DRIFTSTATE_ACTIVE; - player->botvars.driftturn = -1; - player->botvars.powersliding = false; + driftturn = -1; break; case DRIFT_PWRSLIDE_R: - player->botvars.driftstate = DRIFTSTATE_ACTIVE; - player->botvars.driftturn = 1; - player->botvars.powersliding = true; - turnamt *= -1; + driftturn = 2; break; case DRIFT_RIGHT: - player->botvars.driftstate = DRIFTSTATE_ACTIVE; - player->botvars.driftturn = 1; - player->botvars.powersliding = false; - turnamt *= -1; + driftturn = 1; break; - case DRIFT_END: - if (player->botvars.driftstate) - { - player->botvars.driftstate = DRIFTSTATE_ENDING; - player->botvars.driftturn = 0; - player->botvars.powersliding = false; - turnamt = INT32_MAX; // Tells the game not to modify turning. - } - break; - case DRIFT_NONE: default: - turnamt = 0; break; } + + player->botvars.driftturn = driftturn; + K_BotSetDriftState(player, DRIFTSTATE_STARTING, 0); } } - - return turnamt; } /*-------------------------------------------------- @@ -1197,16 +1223,23 @@ 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; + fixed_t speedfactor = FixedDiv(player->speed, K_GetKartSpeed(player, false, false)); I_Assert(predict != nullptr); moveangle = player->mo->angle; anglediff = AngleDeltaSigned(moveangle, destangle); + // line up for an incoming drift + if (player->botvars.driftstate == DRIFTSTATE_STARTING) + { + anglediff += FixedMul(ANG10-ANG2, speedfactor) * player->botvars.driftturn; + } + if (anglediff < 0) { turnsign = 1; @@ -1216,6 +1249,7 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * turnsign = -1; } + anglediff2 = anglediff; anglediff = abs(anglediff); turnamt = KART_FULLTURN * turnsign; @@ -1224,9 +1258,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? - cmd->buttons &= ~(BT_DRIFT); } else { @@ -1244,13 +1275,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 @@ -1279,55 +1303,48 @@ 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.driftstate != DRIFTSTATE_STARTING) // steer towards waypoints when starting drift { // Going the right way, don't turn at all. turnamt = 0; } - 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.drifttime) + if (player->botvars.driftstate == DRIFTSTATE_ACTIVE || player->botvars.driftstate == DRIFTSTATE_ENDING) { - // Confirm our drift angle. - if ((player->botvars.driftturn) - && (player->botvars.drifttime < 4)) - { - turnamt = KART_FULLTURN * -player->botvars.driftturn; - } - 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)); - } - } - cmd->buttons |= BT_DRIFT; + + fixed_t angofs = K_GetKartSpeedFromStat(5 - (player->kartspeed - 5), false) * -player->botvars.driftturn; + + // adjust for speed + angofs = FixedMul(angofs, speedfactor - (2-gamespeed)*FRACUNIT/4); + + fixed_t driftpower = angofs - FixedDiv(anglediff2, ANG1); + + // arbitrary divider on the final driftpower + driftpower /= FixedInt(cv_test2.value); + + // brakedrift if we're steering too hard + if (abs(driftpower) >= FRACUNIT) + cmd->buttons |= BT_BRAKE; + + // 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, turnvalue), -KART_FULLTURN, KART_FULLTURN); } + /* 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; @@ -1654,7 +1671,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); } @@ -1772,38 +1789,44 @@ 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. // Drift-ending waypoints will kill the drift timer, // so no need to worry about doing that ourselves. - player->botvars.driftamt = K_BotStartDrift(player); + K_BotStartDrift(player); - if (player->botvars.drifttime) - { - // 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)) - { - player->botvars.drifttime++; - } + INT32 limit = FixedInt(cv_test3.value) - gamespeed*5; + INT32 dtime = ++player->botvars.drifttime; - if (player->botvars.drifttime > BOTDRIFTTICS + 3) - { - player->botvars.drifttime = 0; - player->botvars.driftstate = DRIFTSTATE_AUTO; - } - } - else if ((player->botvars.driftamt) && (player->botvars.driftstate)) + // the faster we are going, the sooner we need to drift + fixed_t speedfactor = FixedDiv(player->speed, K_GetKartSpeed(player, false, false)); + + switch (player->botvars.driftstate) { - if (player->botvars.driftamt != INT32_MAX) + case DRIFTSTATE_STARTING: + limit = std::max(0, limit - FixedMul(TICRATE/5, speedfactor)); + if (dtime > limit) { - // Ready to drift! - player->botvars.drifttime++; + K_BotSetDriftState(player, DRIFTSTATE_ACTIVE, 0); } + break; + + case DRIFTSTATE_ENDING: + limit = std::max(0, limit - FixedMul(TICRATE/5, speedfactor)); + if (dtime > limit) + { + K_BotSetDriftState(player, DRIFTSTATE_AUTO, 0); + } + 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 a88cc3f0f..29c214624 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_STARTING] = "Starting", + [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)); +} + 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 37dad4b12..fd4018fcb 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); @@ -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); } //} diff --git a/src/p_map.c b/src/p_map.c index 270df41e8..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,10 +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.drifttime = 0; - mo->player->botvars.driftstate = DRIFTSTATE_AUTO; - mo->player->botvars.driftturn = 0; - mo->player->botvars.powersliding = false; + 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 2ff54f651..b608e3724 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -386,8 +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); + WRITEFIXED(save->p, players[i].outrun); WRITEUINT8(save->p, players[i].outruntime); @@ -718,8 +718,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].outrun = READFIXED(save->p); players[i].outruntime = READUINT8(save->p);