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);