From b5d7434caa6e3f2e67b002d75ca8a16a2c5a23bc Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 5 Feb 2021 21:34:16 -0500 Subject: [PATCH 01/14] Turn confirm goes back to neutral when they aren't trying to turn. --- src/k_bot.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/k_bot.c b/src/k_bot.c index 21cd4f18e..e1217357a 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -720,11 +720,15 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) // Complete override of all ticcmd functionality if (LUAh_BotTiccmd(player, cmd)) + { return; + } // Start boost handler if (leveltime <= starttime) { + // TODO: Move towards finish line during position, but not too close. + tic_t length = (TICRATE/6); tic_t boosthold = starttime - K_GetSpindashChargeTime(player); @@ -869,6 +873,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) if (turnamt > 0) { + // Count up if (player->botvars.turnconfirm < BOTTURNCONFIRM) { player->botvars.turnconfirm++; @@ -876,11 +881,24 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) } else if (turnamt < 0) { + // Count down if (player->botvars.turnconfirm > -BOTTURNCONFIRM) { player->botvars.turnconfirm--; } } + else + { + // Back to neutral + if (player->botvars.turnconfirm < 0) + { + player->botvars.turnconfirm++; + } + else if (player->botvars.turnconfirm > 0) + { + player->botvars.turnconfirm--; + } + } if (abs(player->botvars.turnconfirm) >= BOTTURNCONFIRM) { From 79d5867c5e6c6a4d3f067901b6d4e37e5e2fdba7 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 5 Feb 2021 22:44:31 -0500 Subject: [PATCH 02/14] Add spindashing logic for bots They will charge a spindash when they're moving too slow, don't have another boost, and aren't flashing. --- src/k_bot.c | 119 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 97 insertions(+), 22 deletions(-) diff --git a/src/k_bot.c b/src/k_bot.c index e1217357a..811efe54b 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -686,6 +686,84 @@ static botprediction_t *K_CreateBotPrediction(player_t *player) return predict; } +/*-------------------------------------------------- + static UINT8 K_TrySpindash(player_t *player) + + Determines conditions where the bot should attempt to spindash. + + Input Arguments:- + player - Bot player to check. + + Return:- + 0 to make the bot drive normally, 1 to e-brake, 2 to e-brake & charge spindash. + (TODO: make this an enum) +--------------------------------------------------*/ +static UINT8 K_TrySpindash(player_t *player) +{ + const tic_t difficultyModifier = (TICRATE/6); + + if (player->kartstuff[k_spindashboost] || player->kartstuff[k_tiregrease]) + { + // You just released a spindash, you don't need to try again yet, jeez. + return 0; + } + + // Try "start boosts" first + if (leveltime == starttime+1) + { + // Forces them to release, even if they haven't fully charged. + // Don't want them to keep charging if they didn't have time to. + return 0; + } + + if (leveltime <= starttime) + { + INT32 boosthold = starttime - K_GetSpindashChargeTime(player); + + boosthold -= (MAXBOTDIFFICULTY - player->botvars.difficulty) * difficultyModifier; + + if (leveltime >= (unsigned)boosthold) + { + // Start charging... + return 2; + } + else + { + // Just hold your ground and e-brake. + return 1; + } + } + + // Logic for normal racing. + if (player->powers[pw_flashing] > 0) + { + // Don't bother trying to spindash. + // Trying to spindash while flashing is fine during POSITION, but not during the actual race. + return 0; + } + + if (player->speed < K_GetKartSpeed(player, false) / 4 // Below the speed threshold + && player->kartstuff[k_speedboost] < (FRACUNIT/8)) // If you have other boosts, you can probably trust it. + { + INT32 chargingPoint = (K_GetSpindashChargeTime(player) + difficultyModifier); + + // Release quicker the higher the difficulty is. + // Sounds counter-productive, but that's actually the best strategy after the race has started. + chargingPoint -= player->botvars.difficulty * difficultyModifier; + + if (player->kartstuff[k_spindash] > chargingPoint) + { + // Time to release. + return 0; + } + + return 2; + } + + // We're doing just fine, we don't need to spindash, thanks. + return 0; +} + /*-------------------------------------------------- void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) @@ -694,6 +772,7 @@ static botprediction_t *K_CreateBotPrediction(player_t *player) void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) { botprediction_t *predict = NULL; + UINT8 spindash = 0; INT32 turnamt = 0; // Can't build a ticcmd if we aren't spawned... @@ -724,26 +803,6 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) return; } - // Start boost handler - if (leveltime <= starttime) - { - // TODO: Move towards finish line during position, but not too close. - - tic_t length = (TICRATE/6); - tic_t boosthold = starttime - K_GetSpindashChargeTime(player); - - cmd->buttons |= BT_EBRAKEMASK; - - boosthold -= (MAXBOTDIFFICULTY - player->botvars.difficulty) * length; - - if (leveltime >= boosthold) - { - cmd->buttons |= BT_DRIFT; - } - - return; - } - // Handle steering towards waypoints! if (player->nextwaypoint != NULL && player->nextwaypoint->mobj != NULL && !P_MobjWasRemoved(player->nextwaypoint->mobj)) { @@ -857,8 +916,24 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) } } - // Handle item usage - K_BotItemUsage(player, cmd, turnamt); + // Spindashing + spindash = K_TrySpindash(player); + + if (spindash > 0) + { + cmd->buttons |= BT_EBRAKEMASK; + + if (spindash == 2 && player->speed < 6*mapobjectscale) + { + cmd->buttons |= BT_DRIFT; + } + } + else + { + // Handle item usage here, so they don't pointlessly try to use rings/sneakers while charging a spindash. + // TODO: Allowing projectile items like orbinaut while e-braking would probably be fine, maybe just pass in the spindash variable? + K_BotItemUsage(player, cmd, turnamt); + } if (turnamt != 0) { From fb1d495b5c6ba97d018959a4ed93f9d5e2ae6e18 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 6 Feb 2021 01:40:39 -0500 Subject: [PATCH 03/14] Bots can recover from dying Rogue code that came back from vanilla --- src/p_user.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 0df4aa756..87997cedc 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2632,9 +2632,6 @@ static void P_DeathThink(player_t *player) if (player->deadtimer < INT32_MAX) player->deadtimer++; - if (player->bot) // don't allow bots to do any of the below, B_CheckRespawn does all they need for respawning already - goto notrealplayer; - if ((player->pflags & PF_GAMETYPEOVER) && (gametyperules & GTR_CIRCUIT)) { player->karthud[khud_timeovercam]++; @@ -2677,8 +2674,6 @@ static void P_DeathThink(player_t *player) } } -notrealplayer: - if (!player->mo) return; From 2344d94a6e3532442aa1b80c59eede08093e7692 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 6 Feb 2021 01:40:58 -0500 Subject: [PATCH 04/14] Minor adjustments to starting difficulty calculations for big GPs --- src/k_grandprix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_grandprix.c b/src/k_grandprix.c index 57e31a885..e46a6a7be 100644 --- a/src/k_grandprix.c +++ b/src/k_grandprix.c @@ -167,9 +167,9 @@ void K_InitGrandPrixBots(void) difficultylevels[10] = max(1, startingdifficulty-5); difficultylevels[11] = max(1, startingdifficulty-6); difficultylevels[12] = max(1, startingdifficulty-6); - difficultylevels[13] = max(1, startingdifficulty-6); + difficultylevels[13] = max(1, startingdifficulty-7); difficultylevels[14] = max(1, startingdifficulty-7); - difficultylevels[15] = max(1, startingdifficulty-7); + difficultylevels[15] = max(1, startingdifficulty-8); } for (i = 0; i < MAXPLAYERS; i++) From efb636aebe4362babfe94902aa374c26be4392af Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 6 Feb 2021 05:14:15 -0500 Subject: [PATCH 05/14] Bots do things during POSITION --- src/k_bot.c | 123 ++++++++++++++++++++++++++++++++++++++++++--------- src/k_race.c | 2 +- src/k_race.h | 2 + 3 files changed, 105 insertions(+), 22 deletions(-) diff --git a/src/k_bot.c b/src/k_bot.c index 811efe54b..9432638af 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -26,6 +26,7 @@ #include "d_ticcmd.h" #include "m_random.h" #include "r_things.h" // numskins +#include "k_race.h" // finishBeamLine /*-------------------------------------------------- @@ -521,6 +522,26 @@ fixed_t K_BotFrictionRubberband(player_t *player, fixed_t frict) --------------------------------------------------*/ fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y, fixed_t cx, fixed_t cy) { +#if 1 + // This function ended up with overflow issues (and too much) + // I'm kinda tired of looking at this so I'mma just gonna wildly cheat + + vertex_t v1, v2; // fake vertexes + line_t junk; // fake linedef + vertex_t result; + + v1.x = v1x; + v1.y = v1y; + + v2.x = v2x; + v2.y = v2y; + + junk.v1 = &v1; + junk.v2 = &v2; + + P_ClosestPointOnLine(cx, cy, &junk, &result); + return R_PointToDist2(cx, cy, result.x, result.y); +#else fixed_t v1toc[2] = {cx - v1x, cy - v1y}; fixed_t v1tov2[2] = {v2x - v1x, v2y - v1y}; @@ -540,7 +561,8 @@ fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t px = v1x + FixedMul(v1tov2[0], t); py = v1y + FixedMul(v1tov2[1], t); - return P_AproxDistance(cx - px, cy - py); + return FixedHypot(cx - px, cy - py); +#endif } /*-------------------------------------------------- @@ -709,14 +731,14 @@ static UINT8 K_TrySpindash(player_t *player) } // Try "start boosts" first - if (leveltime == starttime+1) + if (leveltime == starttime) { // Forces them to release, even if they haven't fully charged. // Don't want them to keep charging if they didn't have time to. return 0; } - if (leveltime <= starttime) + if (leveltime < starttime) { INT32 boosthold = starttime - K_GetSpindashChargeTime(player); @@ -772,6 +794,7 @@ static UINT8 K_TrySpindash(player_t *player) void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) { botprediction_t *predict = NULL; + boolean trySpindash = false; UINT8 spindash = 0; INT32 turnamt = 0; @@ -784,19 +807,16 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) // Remove any existing controls memset(cmd, 0, sizeof(ticcmd_t)); - if (gamestate != GS_LEVEL - || player->mo->scale <= 1) // funny post-finish death + if ( + gamestate != GS_LEVEL + || player->mo->scale <= 1 + || player->playerstate == PST_DEAD + ) { // No need to do anything else. return; } - if (player->playerstate == PST_DEAD) - { - cmd->buttons |= BT_ACCELERATE; - return; - } - // Complete override of all ticcmd functionality if (LUAh_BotTiccmd(player, cmd)) { @@ -916,22 +936,83 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) } } - // Spindashing - spindash = K_TrySpindash(player); - - if (spindash > 0) + if (leveltime <= starttime && finishBeamLine != NULL) { - cmd->buttons |= BT_EBRAKEMASK; + const fixed_t distBase = 1024*mapobjectscale; + const fixed_t distAdjust = 64*mapobjectscale; - if (spindash == 2 && player->speed < 6*mapobjectscale) + const fixed_t closeDist = distBase + (distAdjust * (9 - player->kartweight)); + const fixed_t farDist = closeDist + (distAdjust * 2); + + fixed_t distToFinish = K_DistanceOfLineFromPoint( + finishBeamLine->v1->x, finishBeamLine->v1->y, + finishBeamLine->v2->x, finishBeamLine->v2->y, + player->mo->x, player->mo->y + ); + + // Don't run the spindash code at all until we're in the right place + trySpindash = false; + + // If you're too far, enable spindash & stay still. + // If you're too close, start backing up. + + if (player - players == displayplayers[0]) { - cmd->buttons |= BT_DRIFT; + CONS_Printf("closeDist: %d\n", closeDist / FRACUNIT); + CONS_Printf("farDist: %d\n", farDist / FRACUNIT); + CONS_Printf("distToFinish: %d\n", distToFinish / FRACUNIT); + CONS_Printf("========\n"); + } + + if (distToFinish < closeDist) + { + // Silly way of getting us to reverse, but it respects the above code + // where we figure out what the shape of the track looks like. + UINT16 oldButtons = cmd->buttons; + + cmd->buttons &= ~(BT_ACCELERATE|BT_BRAKE); + + if (oldButtons & BT_ACCELERATE) + { + cmd->buttons |= BT_BRAKE; + } + + if (oldButtons & BT_BRAKE) + { + cmd->buttons |= BT_ACCELERATE; + } + + cmd->forwardmove = -cmd->forwardmove; + } + else if (distToFinish < farDist) + { + // We're in about the right place, spindash now. + cmd->forwardmove = 0; + trySpindash = true; } } - else + + if (trySpindash == true) { - // Handle item usage here, so they don't pointlessly try to use rings/sneakers while charging a spindash. - // TODO: Allowing projectile items like orbinaut while e-braking would probably be fine, maybe just pass in the spindash variable? + // Spindashing + spindash = K_TrySpindash(player); + + if (spindash > 0) + { + cmd->buttons |= BT_EBRAKEMASK; + cmd->forwardmove = 0; + + if (spindash == 2 && player->speed < 6*mapobjectscale) + { + cmd->buttons |= BT_DRIFT; + } + } + } + + if (spindash == 0) + { + // Don't pointlessly try to use rings/sneakers while charging a spindash. + // TODO: Allowing projectile items like orbinaut while e-braking would be nice, maybe just pass in the spindash variable? K_BotItemUsage(player, cmd, turnamt); } diff --git a/src/k_race.c b/src/k_race.c index 7d65ee2e6..0ac9cb679 100644 --- a/src/k_race.c +++ b/src/k_race.c @@ -41,7 +41,7 @@ #include "k_bot.h" #include "k_hud.h" -static line_t *finishBeamLine = NULL; +line_t *finishBeamLine = NULL; static mobj_t *beamPoints[2]; static UINT8 numBeamPoints = 0; diff --git a/src/k_race.h b/src/k_race.h index 13d870f8e..b9021893e 100644 --- a/src/k_race.h +++ b/src/k_race.h @@ -14,6 +14,8 @@ #include "r_defs.h" +extern line_t *finishBeamLine; + #define FINISHLINEBEAM_SPACING (48*mapobjectscale) /*-------------------------------------------------- From e0f931072cfcd14757036f3a8a89343d02ef42aa Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 6 Feb 2021 05:14:54 -0500 Subject: [PATCH 06/14] Leftover from old comment --- src/k_bot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_bot.c b/src/k_bot.c index 9432638af..b3c2abe9e 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -523,7 +523,7 @@ fixed_t K_BotFrictionRubberband(player_t *player, fixed_t frict) fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y, fixed_t cx, fixed_t cy) { #if 1 - // This function ended up with overflow issues (and too much) + // This function ended up with overflow issues // I'm kinda tired of looking at this so I'mma just gonna wildly cheat vertex_t v1, v2; // fake vertexes From c58b5e92a193254f0cc87569ca26be0a817e8e9d Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 11 Feb 2021 16:25:35 -0500 Subject: [PATCH 07/14] Fixed weird issues with finish beam dist, properly use old behavior without beam, make bots get way closer --- src/k_bot.c | 62 +++++++++++++++++++++-------------------------------- 1 file changed, 24 insertions(+), 38 deletions(-) diff --git a/src/k_bot.c b/src/k_bot.c index b3c2abe9e..3eb52519e 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -520,49 +520,35 @@ fixed_t K_BotFrictionRubberband(player_t *player, fixed_t frict) See header file for description. --------------------------------------------------*/ -fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y, fixed_t cx, fixed_t cy) +fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y, fixed_t px, fixed_t py) { -#if 1 - // This function ended up with overflow issues - // I'm kinda tired of looking at this so I'mma just gonna wildly cheat - - vertex_t v1, v2; // fake vertexes - line_t junk; // fake linedef - vertex_t result; - - v1.x = v1x; - v1.y = v1y; - - v2.x = v2x; - v2.y = v2y; - - junk.v1 = &v1; - junk.v2 = &v2; - - P_ClosestPointOnLine(cx, cy, &junk, &result); - return R_PointToDist2(cx, cy, result.x, result.y); -#else - fixed_t v1toc[2] = {cx - v1x, cy - v1y}; - fixed_t v1tov2[2] = {v2x - v1x, v2y - v1y}; - - fixed_t mag = FixedMul(v1tov2[0], v1tov2[0]) + FixedMul(v1tov2[1], v1tov2[1]); - fixed_t dot = FixedMul(v1toc[0], v1tov2[0]) + FixedMul(v1toc[1], v1tov2[1]); + // Copy+paste from P_ClosestPointOnLine :pensive: + fixed_t startx = v1x; + fixed_t starty = v1y; + fixed_t dx = v2x - v1x; + fixed_t dy = v2y - v1y; + fixed_t cx, cy; + fixed_t vx, vy; + fixed_t magnitude; fixed_t t; - fixed_t px, py; - if (mag == 0) - { - return 0; - } + cx = px - startx; + cy = py - starty; - t = FixedDiv(dot, mag); + vx = dx; + vy = dy; - px = v1x + FixedMul(v1tov2[0], t); - py = v1y + FixedMul(v1tov2[1], t); + magnitude = R_PointToDist2(v2x, v2y, startx, starty); + vx = FixedDiv(vx, magnitude); + vy = FixedDiv(vy, magnitude); - return FixedHypot(cx - px, cy - py); -#endif + t = (FixedMul(vx, cx) + FixedMul(vy, cy)); + + vx = FixedMul(vx, t); + vy = FixedMul(vy, t); + + return R_PointToDist2(px, py, startx + vx, starty + vy); } /*-------------------------------------------------- @@ -794,7 +780,7 @@ static UINT8 K_TrySpindash(player_t *player) void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) { botprediction_t *predict = NULL; - boolean trySpindash = false; + boolean trySpindash = true; UINT8 spindash = 0; INT32 turnamt = 0; @@ -938,7 +924,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) if (leveltime <= starttime && finishBeamLine != NULL) { - const fixed_t distBase = 1024*mapobjectscale; + const fixed_t distBase = 384*mapobjectscale; const fixed_t distAdjust = 64*mapobjectscale; const fixed_t closeDist = distBase + (distAdjust * (9 - player->kartweight)); From 1f7fd96e3266d0c9e0ea7a459b3f5a6a4c5e4233 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 11 Feb 2021 19:08:44 -0500 Subject: [PATCH 08/14] Bot controller linedef Controls bot behavior while they're touching a tagged sector. X texture offset is angle to force the bot in (0 is east, 90 is north, 180 is west, 270 is south) Y texture offset is trick type -- if a bot enters the sector while in trick panel state, then they'll do the input for the trick. Without the effect present, they'll do nothing and eventually tumble. Y offset 1 does a left trick, 2 is right, 3 is forward, 4 is back/up. --- src/k_bot.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++--- src/p_spec.c | 2 + 2 files changed, 123 insertions(+), 6 deletions(-) diff --git a/src/k_bot.c b/src/k_bot.c index 3eb52519e..88ba76495 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -772,6 +772,67 @@ static UINT8 K_TrySpindash(player_t *player) return 0; } +/*-------------------------------------------------- + static INT16 K_FindBotController(mobj_t *mo) + + Finds if any bot controller linedefs are tagged to the bot's sector. + + Input Arguments:- + mo - The bot player's mobj. + + Return:- + Line number of the bot controller. -1 if it doesn't exist. +--------------------------------------------------*/ +static INT16 K_FindBotController(mobj_t *mo) +{ + msecnode_t *node; + ffloor_t *rover; + INT16 lineNum = -1; + + I_Assert(mo != NULL); + I_Assert(!P_MobjWasRemoved(mo)); + + for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) + { + if (!node->m_sector) + { + continue; + } + + lineNum = P_FindSpecialLineFromTag(2004, node->m_sector->tag, -1); + + if (lineNum != -1) + { + return lineNum; + } + + for (rover = node->m_sector->ffloors; rover; rover = rover->next) + { + sector_t *rs = NULL; + + if (!(rover->flags & FF_EXISTS)) + { + continue; + } + + if (mo->z > *rover->topheight || mo->z + mo->height < *rover->bottomheight) + { + continue; + } + + rs = §ors[rover->secnum]; + lineNum = P_FindSpecialLineFromTag(2004, rs->tag, -1); + + if (lineNum != -1) + { + return lineNum; + } + } + } + + return -1; +} + /*-------------------------------------------------- void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) @@ -783,6 +844,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) boolean trySpindash = true; UINT8 spindash = 0; INT32 turnamt = 0; + INT16 botController = -1; // Can't build a ticcmd if we aren't spawned... if (!player->mo) @@ -809,18 +871,71 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) return; } - // Handle steering towards waypoints! - if (player->nextwaypoint != NULL && player->nextwaypoint->mobj != NULL && !P_MobjWasRemoved(player->nextwaypoint->mobj)) + botController = K_FindBotController(player->mo); + + if (player->trickpanel != 0) { + // Trick panel state -- do nothing until a controller line is found, in which case do a trick. + + if (player->trickpanel == 1 && botController != -1) + { + line_t *controllerLine = &lines[botController]; + INT32 type = (sides[controllerLine->sidenum[0]].rowoffset / FRACUNIT); + + // Y Offset: Trick type + switch (type) + { + case 1: + cmd->turning = KART_FULLTURN; + break; + case 2: + cmd->turning = -KART_FULLTURN; + break; + case 3: + cmd->buttons |= BT_FORWARD; + break; + case 4: + cmd->buttons |= BT_BACKWARD; + break; + } + } + + // Don't do anything else. + return; + } + + if ((player->nextwaypoint != NULL + && player->nextwaypoint->mobj != NULL + && !P_MobjWasRemoved(player->nextwaypoint->mobj)) + || (botController != -1)) + { + // Handle steering towards waypoints! SINT8 turnsign = 0; angle_t destangle, moveangle, angle; INT16 anglediff; - predict = K_CreateBotPrediction(player); + if (botController != -1) + { + const fixed_t dist = (player->mo->radius * 4); + line_t *controllerLine = &lines[botController]; + + // X Offset: Movement direction + destangle = FixedAngle(sides[controllerLine->sidenum[0]].textureoffset); + + // Overwritten prediction + predict = Z_Calloc(sizeof(botprediction_t), PU_LEVEL, NULL); + + predict->x = player->mo->x + FixedMul(dist, FINECOSINE(destangle >> ANGLETOFINESHIFT)); + predict->y = player->mo->y + FixedMul(dist, FINESINE(destangle >> ANGLETOFINESHIFT)); + predict->radius = (DEFAULT_WAYPOINT_RADIUS / 4) * mapobjectscale; + } + else + { + predict = K_CreateBotPrediction(player); + destangle = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y); + } - destangle = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y); moveangle = player->mo->angle; - angle = (moveangle - destangle); if (angle < ANGLE_180) @@ -846,7 +961,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) else { const fixed_t playerwidth = (player->mo->radius * 2); - const fixed_t realrad = predict->radius - (playerwidth * 4); // Remove a "safe" distance away from the edges of the road + fixed_t realrad = predict->radius - (playerwidth * 4); // Remove a "safe" distance away from the edges of the road fixed_t rad = realrad; fixed_t dirdist = K_DistanceOfLineFromPoint( player->mo->x, player->mo->y, diff --git a/src/p_spec.c b/src/p_spec.c index 96caeacc9..97fb66c06 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6955,6 +6955,8 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 2003: // Respawn Line break; + case 2004: // Bot controller + break; default: break; From 9bf22934811ce49b5d7c40467caf657231c9205a Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 12 Feb 2021 02:07:47 -0500 Subject: [PATCH 09/14] Increase rubberband range --- src/k_bot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_bot.c b/src/k_bot.c index 88ba76495..60cf61d0d 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -297,7 +297,7 @@ boolean K_BotCanTakeCut(player_t *player) --------------------------------------------------*/ static UINT32 K_BotRubberbandDistance(player_t *player) { - const UINT32 spacing = FixedDiv(512 * FRACUNIT, K_GetKartGameSpeedScalar(gamespeed)) / FRACUNIT; + const UINT32 spacing = FixedDiv(640 * FRACUNIT, K_GetKartGameSpeedScalar(gamespeed)) / FRACUNIT; const UINT8 portpriority = player - players; UINT8 pos = 0; UINT8 i; From f236fcc5e228af54df685ce4434af58da4a3d2d1 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 12 Feb 2021 02:08:10 -0500 Subject: [PATCH 10/14] Decrease max top speed rubberband --- src/k_bot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_bot.c b/src/k_bot.c index 60cf61d0d..0d687d8cd 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -430,8 +430,8 @@ fixed_t K_BotTopSpeedRubberband(player_t *player) } else { - // Max at +25% for level 9 bots - rubberband = FRACUNIT + ((rubberband - FRACUNIT) / 4); + // Max at +10% for level 9 bots + rubberband = FRACUNIT + ((rubberband - FRACUNIT) / 10); } // Only allow you to go faster than your regular top speed if you're facing the right direction From 87158825b6bf4ce392e229501f39a1c27ab9b8f1 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 12 Feb 2021 02:36:03 -0500 Subject: [PATCH 11/14] Increase base bot top speed depending on difficulty --- src/k_kart.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 2f01f2dc0..162eca3c1 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2470,10 +2470,17 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) finalspeed = FixedMul(finalspeed, FRACUNIT + (sphereAdd * player->spheres)); } - if (K_PlayerUsesBotMovement(player) && player->botvars.rival == true) + if (K_PlayerUsesBotMovement(player)) { - // +10% top speed for the rival - finalspeed = FixedMul(finalspeed, 11*FRACUNIT/10); + // Increase bot speed by 1-10% depending on difficulty + fixed_t add = (player->botvars.difficulty * (FRACUNIT/10)) / 9; + finalspeed = FixedMul(finalspeed, FRACUNIT + add); + + if (player->botvars.rival == true) + { + // +10% top speed for the rival + finalspeed = FixedMul(finalspeed, 11*FRACUNIT/10); + } } if (player->mo && !P_MobjWasRemoved(player->mo)) From ce9ece3c0b030b849e9c061248946cef11e4901b Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 12 Feb 2021 03:19:57 -0500 Subject: [PATCH 12/14] Increase ring power for bots --- src/k_kart.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 162eca3c1..15070c61c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2473,7 +2473,7 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) if (K_PlayerUsesBotMovement(player)) { // Increase bot speed by 1-10% depending on difficulty - fixed_t add = (player->botvars.difficulty * (FRACUNIT/10)) / 9; + fixed_t add = (player->botvars.difficulty * (FRACUNIT/10)) / MAXBOTDIFFICULTY; finalspeed = FixedMul(finalspeed, FRACUNIT + add); if (player->botvars.rival == true) @@ -6845,7 +6845,15 @@ void K_UpdateDistanceFromFinishLine(player_t *const player) INT32 K_GetKartRingPower(player_t *player) { - return (((9 - player->kartspeed) + (9 - player->kartweight)) / 2); + INT32 ringPower = ((9 - player->kartspeed) + (9 - player->kartweight)) / 2; + + if (K_PlayerUsesBotMovement(player)) + { + // Double for Lv. 9 + ringPower += (player->botvars.difficulty * ringPower) / MAXBOTDIFFICULTY; + } + + return ringPower; } // Returns false if this player being placed here causes them to collide with any other player From f134c07c0024717908c965729f071b85d35152d9 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 12 Feb 2021 03:20:43 -0500 Subject: [PATCH 13/14] Severely decrease spindash threshold --- src/k_bot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_bot.c b/src/k_bot.c index 0d687d8cd..ee9ab2cb6 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -750,7 +750,7 @@ static UINT8 K_TrySpindash(player_t *player) return 0; } - if (player->speed < K_GetKartSpeed(player, false) / 4 // Below the speed threshold + if (player->speed < 10*mapobjectscale // Below the speed threshold && player->kartstuff[k_speedboost] < (FRACUNIT/8)) // If you have other boosts, you can probably trust it. { INT32 chargingPoint = (K_GetSpindashChargeTime(player) + difficultyModifier); From 8734db6cfda3c53f6e70715cd8eed21ff7f044a8 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 12 Feb 2021 11:21:35 -0500 Subject: [PATCH 14/14] Remove prints --- src/k_bot.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/k_bot.c b/src/k_bot.c index ee9ab2cb6..9fcee08ce 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -1057,14 +1057,6 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) // If you're too far, enable spindash & stay still. // If you're too close, start backing up. - if (player - players == displayplayers[0]) - { - CONS_Printf("closeDist: %d\n", closeDist / FRACUNIT); - CONS_Printf("farDist: %d\n", farDist / FRACUNIT); - CONS_Printf("distToFinish: %d\n", distToFinish / FRACUNIT); - CONS_Printf("========\n"); - } - if (distToFinish < closeDist) { // Silly way of getting us to reverse, but it respects the above code