From c678146f0c61b3f2a65bbff92bbfdc2a13e66779 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 23 May 2022 23:59:18 -0400 Subject: [PATCH 1/8] Drastically simplified bot rubberbanding --- src/k_bot.c | 97 ++--------------------------------------------- src/k_bot.h | 33 ---------------- src/k_botitem.c | 10 ++--- src/k_hud.c | 8 ++-- src/k_kart.c | 83 ++++++++++++++++++++-------------------- src/k_kart.h | 2 +- src/lua_baselib.c | 3 +- src/p_enemy.c | 8 ++-- src/p_mobj.c | 2 +- src/p_user.c | 15 ++++---- 10 files changed, 69 insertions(+), 192 deletions(-) diff --git a/src/k_bot.c b/src/k_bot.c index 3481f8156..f64904866 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -556,8 +556,8 @@ fixed_t K_BotRubberband(player_t *player) // Lv. 1: x0.75 min // Lv. 5: x0.875 min // Lv. 9: x1.0 min - // Lv. MAX: x1.0 min - rubbermin = FRACUNIT - (((FRACUNIT/4) * (DIFFICULTBOT - min(DIFFICULTBOT, player->botvars.difficulty))) / (DIFFICULTBOT - 1)); + // Lv. MAX: x1.125 min + rubbermin = FRACUNIT - (((FRACUNIT/4) * (DIFFICULTBOT - player->botvars.difficulty)) / (DIFFICULTBOT - 1)); if (rubberband > rubbermax) { @@ -571,97 +571,6 @@ fixed_t K_BotRubberband(player_t *player) return rubberband; } -/*-------------------------------------------------- - fixed_t K_BotTopSpeedRubberband(player_t *player) - - See header file for description. ---------------------------------------------------*/ -fixed_t K_BotTopSpeedRubberband(player_t *player) -{ - fixed_t rubberband = K_BotRubberband(player); - - if (rubberband <= FRACUNIT) - { - // Never go below your regular top speed - rubberband = FRACUNIT; - } - else - { - // Max at +20% for level 9 bots - rubberband = FRACUNIT + ((rubberband - FRACUNIT) / 5); - } - - // Only allow you to go faster than your regular top speed if you're facing the right direction - if (rubberband > FRACUNIT && player->mo != NULL && player->nextwaypoint != NULL) - { - const INT16 mindiff = 30; - const INT16 maxdiff = 60; - INT16 anglediff = 0; - fixed_t amt = rubberband - FRACUNIT; - angle_t destangle = R_PointToAngle2( - player->mo->x, player->mo->y, - player->nextwaypoint->mobj->x, player->nextwaypoint->mobj->y - ); - angle_t angle = player->mo->angle - destangle; - - if (angle < ANGLE_180) - { - anglediff = AngleFixed(angle) >> FRACBITS; - } - else - { - anglediff = 360 - (AngleFixed(angle) >> FRACBITS); - } - - anglediff = abs(anglediff); - - if (anglediff >= maxdiff) - { - rubberband = FRACUNIT; - } - else if (anglediff > mindiff) - { - amt = (amt * (maxdiff - anglediff)) / mindiff; - rubberband = FRACUNIT + amt; - } - } - - return rubberband; -} - -/*-------------------------------------------------- - fixed_t K_BotFrictionRubberband(player_t *player, fixed_t frict) - - See header file for description. ---------------------------------------------------*/ -fixed_t K_BotFrictionRubberband(player_t *player, fixed_t frict) -{ - const fixed_t value = 20776; - fixed_t rubberband = K_BotRubberband(player) - FRACUNIT; - fixed_t newFrict = frict; - - if (rubberband <= 0) - { - // Never get weaker than normal friction - return frict; - } - - if (player->tiregrease > 0) - { - // Bots will lose all of their momentum without this. - return frict; - } - - newFrict = frict - FixedMul(value, rubberband); - - if (newFrict < 0) - newFrict = 0; - if (newFrict > FRACUNIT) - newFrict = FRACUNIT; - - return newFrict; -} - /*-------------------------------------------------- fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y, fixed_t cx, fixed_t cy) @@ -1148,7 +1057,7 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * if (dirdist <= rad) { - fixed_t speedmul = FixedDiv(K_BotSpeedScaled(player, player->speed), K_GetKartSpeed(player, false)); + fixed_t speedmul = FixedDiv(K_BotSpeedScaled(player, player->speed), K_GetKartSpeed(player, false, false)); fixed_t speedrad = rad/4; if (speedmul > FRACUNIT) diff --git a/src/k_bot.h b/src/k_bot.h index d608fe367..0762c86e9 100644 --- a/src/k_bot.h +++ b/src/k_bot.h @@ -87,39 +87,6 @@ boolean K_BotCanTakeCut(player_t *player); fixed_t K_BotRubberband(player_t *player); -/*-------------------------------------------------- - fixed_t K_BotTopSpeedRubberband(player_t *player); - - Gives a multiplier for a bot's rubberbanding. - Adjusted from K_BotRubberband to be used for top speed. - - Input Arguments:- - player - Player to check. - - Return:- - A multiplier in fixed point scale. ---------------------------------------------------*/ - -fixed_t K_BotTopSpeedRubberband(player_t *player); - - -/*-------------------------------------------------- - fixed_t K_BotFrictionRubberband(player_t *player, fixed_t frict); - - Gives a multiplier for a bot's rubberbanding. - Adjusted from K_BotRubberband to be used for friction. - - Input Arguments:- - player - Player to check. - frict - Friction value to adjust. - - Return:- - The new friction value. ---------------------------------------------------*/ - -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); diff --git a/src/k_botitem.c b/src/k_botitem.c index 465c45adb..9b3cdbd6a 100644 --- a/src/k_botitem.c +++ b/src/k_botitem.c @@ -471,7 +471,7 @@ static void K_BotItemSneaker(player_t *player, ticcmd_t *cmd) { if ((player->offroad && K_ApplyOffroad(player)) // Stuck in offroad, use it NOW || K_GetWaypointIsShortcut(player->nextwaypoint) == true // Going toward a shortcut! - || player->speed < K_GetKartSpeed(player, false)/2 // Being slowed down too much + || player->speed < K_GetKartSpeed(player, false, true) / 2 // Being slowed down too much || player->speedboost > (FRACUNIT/8) // Have another type of boost (tethering) || player->botvars.itemconfirm > 4*TICRATE) // Held onto it for too long { @@ -830,7 +830,7 @@ static void K_BotItemEggmanExplosion(player_t *player, ticcmd_t *cmd) --------------------------------------------------*/ static void K_BotItemOrbinaut(player_t *player, ticcmd_t *cmd) { - const fixed_t topspeed = K_GetKartSpeed(player, false); + const fixed_t topspeed = K_GetKartSpeed(player, false, true); fixed_t radius = FixedMul(2560 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)); SINT8 throwdir = -1; boolean tryLookback = false; @@ -888,7 +888,7 @@ static void K_BotItemOrbinaut(player_t *player, ticcmd_t *cmd) --------------------------------------------------*/ static void K_BotItemDropTarget(player_t *player, ticcmd_t *cmd) { - const fixed_t topspeed = K_GetKartSpeed(player, false); + const fixed_t topspeed = K_GetKartSpeed(player, false, true); fixed_t radius = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)); SINT8 throwdir = -1; boolean tryLookback = false; @@ -946,7 +946,7 @@ static void K_BotItemDropTarget(player_t *player, ticcmd_t *cmd) --------------------------------------------------*/ static void K_BotItemJawz(player_t *player, ticcmd_t *cmd) { - const fixed_t topspeed = K_GetKartSpeed(player, false); + const fixed_t topspeed = K_GetKartSpeed(player, false, true); fixed_t radius = FixedMul(2560 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)); SINT8 throwdir = 1; boolean tryLookback = false; @@ -1165,7 +1165,7 @@ static void K_BotItemRings(player_t *player, ticcmd_t *cmd) { INT32 saferingsval = 16 - K_GetKartRingPower(player, false); - if (player->speed < K_GetKartSpeed(player, false)/2 // Being slowed down too much + if (player->speed < K_GetKartSpeed(player, false, true) / 2 // Being slowed down too much || player->speedboost > (FRACUNIT/5)) // Have another type of boost (tethering) { saferingsval -= 5; diff --git a/src/k_hud.c b/src/k_hud.c index 3861f2e08..2f0a43b24 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -2505,19 +2505,19 @@ static void K_drawKartSpeedometer(void) { case 1: // Sonic Drift 2 style percentage default: - convSpeed = (stplyr->speed * 100) / K_GetKartSpeed(stplyr, false); // Based on top speed! + convSpeed = (stplyr->speed * 100) / K_GetKartSpeed(stplyr, false, true); // Based on top speed! labeln = 0; break; case 2: // Kilometers - convSpeed = FixedDiv(FixedMul(stplyr->speed, 142371), mapobjectscale)/FRACUNIT; // 2.172409058 + convSpeed = FixedDiv(FixedMul(stplyr->speed, 142371), mapobjectscale) / FRACUNIT; // 2.172409058 labeln = 1; break; case 3: // Miles - convSpeed = FixedDiv(FixedMul(stplyr->speed, 88465), mapobjectscale)/FRACUNIT; // 1.349868774 + convSpeed = FixedDiv(FixedMul(stplyr->speed, 88465), mapobjectscale) / FRACUNIT; // 1.349868774 labeln = 2; break; case 4: // Fracunits - convSpeed = FixedDiv(stplyr->speed, mapobjectscale)/FRACUNIT; // 1.0. duh. + convSpeed = FixedDiv(stplyr->speed, mapobjectscale) / FRACUNIT; // 1.0. duh. labeln = 3; break; } diff --git a/src/k_kart.c b/src/k_kart.c index 81374d9c6..609bb6323 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1183,9 +1183,15 @@ static fixed_t K_PlayerWeight(mobj_t *mobj, mobj_t *against) } else { + // Applies rubberbanding, to prevent rubberbanding bots + // from causing super crazy bumps. + fixed_t spd = K_GetKartSpeed(mobj->player, false, true); + weight = (mobj->player->kartweight) * FRACUNIT; - if (mobj->player->speed > K_GetKartSpeed(mobj->player, false)) - weight += (mobj->player->speed - K_GetKartSpeed(mobj->player, false))/8; + + if (mobj->player->speed > spd) + weight += (mobj->player->speed - spd) / 8; + if (mobj->player->itemtype == KITEM_BUBBLESHIELD) weight += 9*FRACUNIT; } @@ -1754,7 +1760,7 @@ static void K_DrawDraftCombiring(player_t *player, player_t *victim, fixed_t cur */ static void K_UpdateDraft(player_t *player) { - fixed_t topspd = K_GetKartSpeed(player, false); + fixed_t topspd = K_GetKartSpeed(player, false, false); fixed_t draftdistance; fixed_t minDist; UINT8 leniency; @@ -2033,7 +2039,7 @@ void K_SpawnDashDustRelease(player_t *player) static fixed_t K_GetBrakeFXScale(player_t *player, fixed_t maxScale) { fixed_t s = FixedDiv(player->speed, - K_GetKartSpeed(player, false)); + K_GetKartSpeed(player, false, false)); s = max(s, FRACUNIT); s = min(s, maxScale); @@ -2366,7 +2372,7 @@ void K_KartMoveAnimation(player_t *player) { const INT16 minturn = KART_FULLTURN/8; - const fixed_t fastspeed = (K_GetKartSpeed(player, false) * 17) / 20; // 85% + const fixed_t fastspeed = (K_GetKartSpeed(player, false, true) * 17) / 20; // 85% const fixed_t speedthreshold = player->mo->scale / 8; const boolean onground = P_IsObjectOnGround(player->mo); @@ -2916,7 +2922,7 @@ boolean K_TripwirePassConditions(player_t *player) player->sneakertimer || player->growshrinktimer > 0 || player->flamedash || - player->speed > 2 * K_GetKartSpeed(player, false) + player->speed > 2 * K_GetKartSpeed(player, false, true) ) return true; return false; @@ -2934,7 +2940,7 @@ boolean K_WaterRun(player_t *player) player->sneakertimer || player->tiregrease || player->flamedash || - player->speed > 2 * K_GetKartSpeed(player, false) + player->speed > 2 * K_GetKartSpeed(player, false, true) ) return true; return false; @@ -3145,7 +3151,7 @@ fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed) return finalspeed; } -fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) +fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower, boolean dorubberband) { const boolean mobjValid = (player->mo != NULL && P_MobjWasRemoved(player->mo) == false); fixed_t finalspeed = K_GetKartSpeedFromStat(player->kartspeed); @@ -3179,14 +3185,14 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) finalspeed = FixedMul(finalspeed, K_GrowShrinkSpeedMul(player)); } - if (K_PlayerUsesBotMovement(player)) - { - finalspeed = FixedMul(finalspeed, K_BotTopSpeedRubberband(player)); - } - finalspeed = FixedMul(finalspeed, player->boostpower + player->speedboost); } + if (dorubberband == true && K_PlayerUsesBotMovement(player) == true) + { + finalspeed = FixedMul(finalspeed, K_BotRubberband(player)); + } + return finalspeed; } @@ -3297,22 +3303,16 @@ SINT8 K_GetForwardMove(player_t *player) fixed_t K_GetNewSpeed(player_t *player) { const fixed_t accelmax = 4000; - const fixed_t p_speed = K_GetKartSpeed(player, true); + const fixed_t p_speed = K_GetKartSpeed(player, true, true); const fixed_t p_accel = K_GetKartAccel(player); fixed_t newspeed, oldspeed, finalspeed; - fixed_t orig = ORIG_FRICTION; - - if (K_PlayerUsesBotMovement(player)) - { - orig = K_BotFrictionRubberband(player, ORIG_FRICTION); - } oldspeed = R_PointToDist2(0, 0, player->rmomx, player->rmomy); // FixedMul(P_AproxDistance(player->rmomx, player->rmomy), player->mo->scale); // Don't calculate the acceleration as ever being above top speed if (oldspeed > p_speed) oldspeed = p_speed; - newspeed = FixedDiv(FixedDiv(FixedMul(oldspeed, accelmax - p_accel) + FixedMul(p_speed, p_accel), accelmax), orig); + newspeed = FixedDiv(FixedDiv(FixedMul(oldspeed, accelmax - p_accel) + FixedMul(p_speed, p_accel), accelmax), ORIG_FRICTION); finalspeed = newspeed - oldspeed; @@ -3530,8 +3530,11 @@ void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 typ if (( player->spinouttype & KSPIN_THRUST )) { // At spinout, player speed is increased to 1/4 their regular speed, moving them forward - if (player->speed < K_GetKartSpeed(player, true)/4) - P_InstaThrust(player->mo, player->mo->angle, FixedMul(K_GetKartSpeed(player, true)/4, player->mo->scale)); + fixed_t spd = K_GetKartSpeed(player, true, true) / 4; + + if (player->speed < spd) + P_InstaThrust(player->mo, player->mo->angle, FixedMul(spd, player->mo->scale)); + S_StartSound(player->mo, sfx_slip); } @@ -3701,7 +3704,7 @@ void K_ApplyTripWire(player_t *player, tripwirestate_t state) K_AddHitLag(player->mo, 10, false); if (state == TRIP_PASSED && player->spinouttimer && - player->speed > 2* K_GetKartSpeed(player, false)) + player->speed > 2 * K_GetKartSpeed(player, false, true)) { K_TumblePlayer(player, NULL, NULL); } @@ -4033,19 +4036,21 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I { mobj_t *th; fixed_t x, y, z; + fixed_t topspeed = K_GetKartSpeed(source->player, false, false); fixed_t finalspeed = speed; fixed_t finalscale = mapobjectscale; mobj_t *throwmo; if (source->player != NULL) { + if (source->player->itemscale == ITEMSCALE_SHRINK) { // Nerf the base item speed a bit. finalspeed = FixedMul(finalspeed, SHRINK_PHYSICS_SCALE); } - if (source->player->speed > K_GetKartSpeed(source->player, false)) + if (source->player->speed > topspeed) { angle_t input = source->angle - an; boolean invert = (input > ANGLE_180); @@ -4053,7 +4058,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I input = InvAngle(input); finalspeed = max(speed, FixedMul(speed, FixedMul( - FixedDiv(source->player->speed, K_GetKartSpeed(source->player, false)), // Multiply speed to be proportional to your own, boosted maxspeed. + FixedDiv(source->player->speed, topspeed), // Multiply speed to be proportional to your own, boosted maxspeed. (((180<mo)) return; - if (player->speed <= K_GetKartSpeed(player, false)) + if (player->speed <= K_GetKartSpeed(player, false, true)) return; travelangle = K_MomentumAngle(player->mo); @@ -5651,7 +5656,7 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) mo->player->tricktime = 0; // Reset post-hitlag timer // Setup the boost for potential upwards trick, at worse, make it your regular max speed. (boost = curr speed*1.25) - mo->player->trickboostpower = max(FixedDiv(mo->player->speed, K_GetKartSpeed(mo->player, false)) - FRACUNIT, 0)*125/100; + mo->player->trickboostpower = max(FixedDiv(mo->player->speed, K_GetKartSpeed(mo->player, false, false)) - FRACUNIT, 0)*125/100; //CONS_Printf("Got boost: %d%\n", mo->player->trickboostpower*100 / FRACUNIT); } @@ -6534,14 +6539,16 @@ static void K_MoveHeldObjects(player_t *player) cur->angle = R_PointToAngle2(cur->x, cur->y, targx, targy); - /*if (P_IsObjectOnGround(player->mo) && player->speed > 0 && player->bananadrag > TICRATE - && P_RandomChance(min(FRACUNIT/2, FixedDiv(player->speed, K_GetKartSpeed(player, false))/2))) + /* + if (P_IsObjectOnGround(player->mo) && player->speed > 0 && player->bananadrag > TICRATE + && P_RandomChance(min(FRACUNIT/2, FixedDiv(player->speed, K_GetKartSpeed(player, false, false))/2))) { if (leveltime & 1) targz += 8*(2*FRACUNIT)/7; else targz -= 8*(2*FRACUNIT)/7; - }*/ + } + */ if (speed > dist) P_InstaThrust(cur, cur->angle, speed-dist); @@ -7642,7 +7649,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (K_GetKartButtons(player) & BT_BRAKE && P_IsObjectOnGround(player->mo) && - K_GetKartSpeed(player, false) / 2 <= player->speed) + K_GetKartSpeed(player, false, false) / 2 <= player->speed) { K_SpawnBrakeVisuals(player); } @@ -8312,14 +8319,13 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) return 0; } - p_maxspeed = K_GetKartSpeed(player, false); + p_maxspeed = K_GetKartSpeed(player, false, true); p_speed = min(currentSpeed, (p_maxspeed * 2)); weightadjust = FixedDiv((p_maxspeed * 3) - p_speed, (p_maxspeed * 3) + (player->kartweight * FRACUNIT)); if (K_PlayerUsesBotMovement(player)) { turnfixed = FixedMul(turnfixed, 5*FRACUNIT/4); // Base increase to turning - turnfixed = FixedMul(turnfixed, K_BotRubberband(player)); } if (player->drift != 0 && P_IsObjectOnGround(player->mo)) @@ -8365,7 +8371,7 @@ INT32 K_GetUnderwaterTurnAdjust(player_t *player) steer = 9 * steer / 5; return FixedMul(steer, 8 * FixedDiv(player->speed, - 2 * K_GetKartSpeed(player, false) / 3)); + 2 * K_GetKartSpeed(player, false, true) / 3)); } else return 0; @@ -9317,13 +9323,6 @@ void K_AdjustPlayerFriction(player_t *player) else player->mo->movefactor = FRACUNIT; } - - // Don't go too far above your top speed when rubberbanding - // Down here, because we do NOT want to modify movefactor - if (K_PlayerUsesBotMovement(player)) - { - player->mo->friction = K_BotFrictionRubberband(player, player->mo->friction); - } } // diff --git a/src/k_kart.h b/src/k_kart.h index 20c8cd33f..567cfda99 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -124,7 +124,7 @@ INT16 K_GetSpindashChargeTime(player_t *player); fixed_t K_GetSpindashChargeSpeed(player_t *player); fixed_t K_GrowShrinkSpeedMul(player_t *player); fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed); -fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower); +fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower, boolean dorubberbanding); fixed_t K_GetKartAccel(player_t *player); UINT16 K_GetKartFlashing(player_t *player); boolean K_PlayerShrinkCheat(player_t *player); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 944ab49bc..a461ac80b 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3693,10 +3693,11 @@ static int lib_kGetKartSpeed(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); boolean doboostpower = lua_optboolean(L, 2); + boolean dorubberbanding = lua_optboolean(L, 3); //HUDSAFE if (!player) return LUA_ErrInvalid(L, "player_t"); - lua_pushfixed(L, K_GetKartSpeed(player, doboostpower)); + lua_pushfixed(L, K_GetKartSpeed(player, doboostpower, dorubberbanding)); return 1; } diff --git a/src/p_enemy.c b/src/p_enemy.c index 65f00e116..efc83aca3 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4980,7 +4980,7 @@ void A_DetonChase(mobj_t *actor) fixed_t xyspeed, speed; if (actor->target->player) - speed = K_GetKartSpeed(actor->tracer->player, false); + speed = K_GetKartSpeed(actor->tracer->player, false, false); else speed = actor->target->info->speed; @@ -13285,7 +13285,7 @@ void A_JawzChase(mobj_t *actor) { if (actor->tracer->player) { - fixed_t speeddifference = abs(topspeed - min(actor->tracer->player->speed, K_GetKartSpeed(actor->tracer->player, false))); + fixed_t speeddifference = abs(topspeed - min(actor->tracer->player->speed, K_GetKartSpeed(actor->tracer->player, false, false))); topspeed = topspeed - FixedMul(speeddifference, FRACUNIT-FixedDiv(distaway, distbarrier)); } } @@ -13615,7 +13615,7 @@ void A_SPBChase(mobj_t *actor) else { // 7/8ths max speed for Knuckles, 3/4ths max speed for min accel, exactly max speed for max accel - defspeed = FixedMul(((fracmax+1)<tracer->player, false)) / fracmax; + defspeed = FixedMul(((fracmax+1)<tracer->player, false, false)) / fracmax; } // Be fairer on conveyors @@ -13695,7 +13695,7 @@ void A_SPBChase(mobj_t *actor) // Red speed lines for when it's gaining on its target. A tell for when you're starting to lose too much speed! if (R_PointToDist2(0, 0, actor->momx, actor->momy) > (actor->tracer->player ? (16*actor->tracer->player->speed)/15 : (16*R_PointToDist2(0, 0, actor->tracer->momx, actor->tracer->momy))/15) // Going faster than the target - && xyspeed > K_GetKartSpeed(actor->tracer->player, false)/4) // Don't display speedup lines at pitifully low speeds + && xyspeed > K_GetKartSpeed(actor->tracer->player, false, false) / 4) // Don't display speedup lines at pitifully low speeds SpawnSPBSpeedLines(actor); return; diff --git a/src/p_mobj.c b/src/p_mobj.c index 433ff4931..8315f7665 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2998,7 +2998,7 @@ boolean P_CanRunOnWater(player_t *player, ffloor_t *rover) clip > -(player->mo->height / 2) && span > player->mo->height && player->speed / 5 > abs(player->mo->momz) && - player->speed > K_GetKartSpeed(player, false) && + player->speed > K_GetKartSpeed(player, false, false) && K_WaterRun(player) && (rover->flags & FF_SWIMMABLE); } diff --git a/src/p_user.c b/src/p_user.c index dbf716925..22d52b258 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -197,7 +197,7 @@ void P_CalcHeight(player_t *player) fixed_t bob = 0; fixed_t pviewheight; mobj_t *mo = player->mo; - fixed_t bobmul = FRACUNIT - FixedDiv(FixedHypot(player->rmomx, player->rmomy), K_GetKartSpeed(player, false)); + fixed_t bobmul = FRACUNIT - FixedDiv(FixedHypot(player->rmomx, player->rmomy), K_GetKartSpeed(player, false, false)); // Regular movement bobbing. // Should not be calculated when not on ground (FIXTHIS?) @@ -1969,11 +1969,12 @@ static void P_3dMovement(player_t *player) // allow for being able to change direction on spring jumps without being accelerated into the void - Sryder if (!P_IsObjectOnGround(player->mo)) { + fixed_t topspeed = K_GetKartSpeed(player, true, true); newMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0); - if (newMagnitude > K_GetKartSpeed(player, true)) //topspeed) + if (newMagnitude > topspeed) { fixed_t tempmomx, tempmomy; - if (oldMagnitude > K_GetKartSpeed(player, true)) + if (oldMagnitude > topspeed) { if (newMagnitude > oldMagnitude) { @@ -1986,8 +1987,8 @@ static void P_3dMovement(player_t *player) } else { - tempmomx = FixedMul(FixedDiv(player->mo->momx - player->cmomx, newMagnitude), K_GetKartSpeed(player, true)); //topspeed) - tempmomy = FixedMul(FixedDiv(player->mo->momy - player->cmomy, newMagnitude), K_GetKartSpeed(player, true)); //topspeed) + tempmomx = FixedMul(FixedDiv(player->mo->momx - player->cmomx, newMagnitude), topspeed); + tempmomy = FixedMul(FixedDiv(player->mo->momy - player->cmomy, newMagnitude), topspeed); player->mo->momx = tempmomx + player->cmomx; player->mo->momy = tempmomy + player->cmomy; } @@ -2256,8 +2257,8 @@ void P_MovePlayer(player_t *player) && (player->speed > runspd) && player->mo->momz == 0 && player->carry != CR_SLIDING && !player->spectator) { - fixed_t trailScale = FixedMul(FixedDiv(player->speed - runspd, K_GetKartSpeed(player, false) - runspd), mapobjectscale); - fixed_t playerTopSpeed = K_GetKartSpeed(player, false); + fixed_t playerTopSpeed = K_GetKartSpeed(player, false, false); + fixed_t trailScale = FixedMul(FixedDiv(player->speed - runspd, playerTopSpeed - runspd), mapobjectscale); if (playerTopSpeed > runspd) trailScale = FixedMul(FixedDiv(player->speed - runspd, playerTopSpeed - runspd), mapobjectscale); From 529a99bc1710da88e71b2bf33e50fdab29dc6016 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 24 May 2022 14:37:43 -0400 Subject: [PATCH 2/8] Bot Controller E2 disables their movement entirely --- src/k_bot.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/k_bot.c b/src/k_bot.c index f64904866..0b8c75371 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -1278,6 +1278,12 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) return; } + if (botController != NULL && (botController->flags & ML_EFFECT2)) + { + // Disable bot controls entirely. + return; + } + destangle = player->mo->angle; if (botController != NULL && (botController->flags & ML_EFFECT1)) From a896d7333400d52ac90ced388ced77224ca4ce1e Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 24 May 2022 15:28:36 -0400 Subject: [PATCH 3/8] Precalculate bot controller & rubberbanding These both require a couple loops to preform each, which probably adds up over multiple bots. Let's just precalculate them at the start of bot ticcmd. --- src/d_player.h | 3 +++ src/g_game.c | 3 +++ src/k_bot.c | 42 +++++++++++++++++++++++++++++++++++------- src/k_bot.h | 16 ++++++++++++++++ src/k_kart.c | 2 +- src/p_saveg.c | 4 ++++ src/p_user.c | 2 +- 7 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 606415a71..24a0c0403 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -290,6 +290,9 @@ typedef struct botvars_s UINT8 diffincrease; // In GP: bot difficulty will increase this much next round boolean rival; // If true, they're the GP rival + fixed_t rubberband; // Bot rubberband value + UINT16 controller; // Special bot controller linedef ID + tic_t itemdelay; // Delay before using item at all tic_t itemconfirm; // When high enough, they will use their item diff --git a/src/g_game.c b/src/g_game.c index 21467e592..13194abf9 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2403,6 +2403,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->kickstartaccel = kickstartaccel; p->tripWireState = TRIP_NONE; + p->botvars.rubberband = FRACUNIT; + p->botvars.controller = UINT16_MAX; + memcpy(&p->respawn, &respawn, sizeof (p->respawn)); if (follower) diff --git a/src/k_bot.c b/src/k_bot.c index 0b8c75371..f9dad809a 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -489,7 +489,6 @@ fixed_t K_BotRubberband(player_t *player) fixed_t rubberband = FRACUNIT; fixed_t rubbermax, rubbermin; player_t *firstplace = NULL; - line_t *botController = NULL; UINT8 i; if (player->exiting) @@ -498,14 +497,17 @@ fixed_t K_BotRubberband(player_t *player) return FRACUNIT; } - botController = K_FindBotController(player->mo); - - if (botController != NULL) + if (player->botvars.controller != UINT16_MAX) { - // No Climb Flag: Disable rubberbanding - if (botController->flags & ML_NOCLIMB) + const line_t *botController = &lines[player->botvars.controller]; + + if (botController != NULL) { - return FRACUNIT; + // No Climb Flag: Disable rubberbanding + if (botController->flags & ML_NOCLIMB) + { + return FRACUNIT; + } } } @@ -571,6 +573,22 @@ fixed_t K_BotRubberband(player_t *player) return rubberband; } +/*-------------------------------------------------- + fixed_t K_UpdateRubberband(player_t *player) + + See header file for description. +--------------------------------------------------*/ +fixed_t K_UpdateRubberband(player_t *player) +{ + fixed_t dest = K_BotRubberband(player); + fixed_t ret = player->botvars.rubberband; + + // Ease into the new value. + ret += (dest - player->botvars.rubberband) >> 3; + + return ret; +} + /*-------------------------------------------------- fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y, fixed_t cx, fixed_t cy) @@ -1269,6 +1287,16 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) } botController = K_FindBotController(player->mo); + if (botController == NULL) + { + player->botvars.controller = UINT16_MAX; + } + else + { + player->botvars.controller = lines - botController; + } + + player->botvars.rubberband = K_UpdateRubberband(player); if (player->trickpanel != 0) { diff --git a/src/k_bot.h b/src/k_bot.h index 0762c86e9..f03187205 100644 --- a/src/k_bot.h +++ b/src/k_bot.h @@ -87,6 +87,22 @@ boolean K_BotCanTakeCut(player_t *player); fixed_t K_BotRubberband(player_t *player); +/*-------------------------------------------------- + fixed_t K_UpdateRubberband(player_t *player); + + Eases the current rubberbanding value to the + new one, calculated by K_BotRubberband. + + Input Arguments:- + player - Player to update. + + Return:- + The new rubberband multiplier, in fixed point scale. +--------------------------------------------------*/ + +fixed_t K_UpdateRubberband(player_t *player); + + /*-------------------------------------------------- fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y, fixed_t cx, fixed_t cy); diff --git a/src/k_kart.c b/src/k_kart.c index 609bb6323..1248714eb 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3190,7 +3190,7 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower, boolean dorubberb if (dorubberband == true && K_PlayerUsesBotMovement(player) == true) { - finalspeed = FixedMul(finalspeed, K_BotRubberband(player)); + finalspeed = FixedMul(finalspeed, player->botvars.rubberband); } return finalspeed; diff --git a/src/p_saveg.c b/src/p_saveg.c index f6819eb9c..bcd12e8e3 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -371,6 +371,8 @@ static void P_NetArchivePlayers(void) WRITEUINT8(save_p, players[i].botvars.difficulty); WRITEUINT8(save_p, players[i].botvars.diffincrease); WRITEUINT8(save_p, players[i].botvars.rival); + WRITEFIXED(save_p, players[i].botvars.rubberband); + WRITEUINT16(save_p, players[i].botvars.controller); WRITEUINT32(save_p, players[i].botvars.itemdelay); WRITEUINT32(save_p, players[i].botvars.itemconfirm); WRITESINT8(save_p, players[i].botvars.turnconfirm); @@ -647,6 +649,8 @@ static void P_NetUnArchivePlayers(void) players[i].botvars.difficulty = READUINT8(save_p); players[i].botvars.diffincrease = READUINT8(save_p); players[i].botvars.rival = (boolean)READUINT8(save_p); + players[i].botvars.rubberband = READFIXED(save_p); + players[i].botvars.controller = READUINT16(save_p); players[i].botvars.itemdelay = READUINT32(save_p); players[i].botvars.itemconfirm = READUINT32(save_p); players[i].botvars.turnconfirm = READSINT8(save_p); diff --git a/src/p_user.c b/src/p_user.c index 22d52b258..fde4465c3 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1939,7 +1939,7 @@ static void P_3dMovement(player_t *player) // Make rubberbanding bots slow down faster if (K_PlayerUsesBotMovement(player)) { - fixed_t rubberband = K_BotRubberband(player) - FRACUNIT; + fixed_t rubberband = player->botvars.rubberband - FRACUNIT; if (rubberband > 0) { From 6afa7dfc4bb5148fb8d90ce21b1080cd51425778 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 24 May 2022 15:44:27 -0400 Subject: [PATCH 4/8] Set tmx & tmy for P_LineOpening in bot code (The more this issue happens, the more we need to take the GZDoom approach of keeping this shit in a struct that you have to put in as a function argument, instead of global variable hellzone...) --- src/p_sight.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_sight.c b/src/p_sight.c index cdc8df864..ca2ba77cd 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -729,6 +729,8 @@ static boolean P_CrossBotTraversalSubsector(size_t num, register traceblocking_t } // set openrange, opentop, openbottom + tmx = tb->compareThing->x; + tmy = tb->compareThing->y; P_LineOpening(line, tb->compareThing); maxstep = P_GetThingStepUp(tb->compareThing); From abb5cf71b88d171f912d7a7063d161a1f3b0bec3 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 24 May 2022 17:30:42 -0400 Subject: [PATCH 5/8] Waypoint sight improvements - Reorganized bot traversal - Blocking line traversal includes tripwire - Next waypoint detection uses blocking line trace now (this means bots can't sit outside of a tripwire wanting to go through it) --- src/k_kart.c | 12 ++++++++++++ src/k_waypoint.c | 8 +++++++- src/p_sight.c | 37 ++++++++++++++++++++++++++++--------- 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 1248714eb..91d73c254 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -7929,6 +7929,12 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player) if (angledelta < nextbestdelta || momdelta < nextbestmomdelta) { + if (P_TraceBlockingLines(player->mo, waypoint->nextwaypoints[i]->mobj) == false) + { + // Save sight checks when all of the other checks pass, so we only do it if we have to + continue; + } + bestwaypoint = waypoint->nextwaypoints[i]; if (angledelta < nextbestdelta) @@ -7975,6 +7981,12 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player) if (angledelta < nextbestdelta && momdelta < nextbestmomdelta) { + if (P_TraceBlockingLines(player->mo, waypoint->prevwaypoints[i]->mobj) == false) + { + // Save sight checks when all of the other checks pass, so we only do it if we have to + continue; + } + bestwaypoint = waypoint->prevwaypoints[i]; nextbestdelta = angledelta; diff --git a/src/k_waypoint.c b/src/k_waypoint.c index 06d0a1a84..357731bd9 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -361,6 +361,12 @@ waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj) // remember: huge radius if (closestdist <= rad && checkdist <= rad && finishline != NULL) { + if (!P_TraceBlockingLines(mobj, checkwaypoint->mobj)) + { + // Save sight checks when all of the other checks pass, so we only do it if we have to + continue; + } + // If the mobj is touching multiple waypoints at once, // then solve ties by taking the one closest to the finish line. // Prevents position from flickering wildly when taking turns. @@ -375,7 +381,7 @@ waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj) { if (!P_TraceBlockingLines(mobj, checkwaypoint->mobj)) { - // Save sight checks for the end, so we only do it if we have to + // Save sight checks when all of the other checks pass, so we only do it if we have to continue; } diff --git a/src/p_sight.c b/src/p_sight.c index ca2ba77cd..4faffcf32 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -578,6 +578,15 @@ static boolean P_CrossBlockingSubsector(size_t num, register traceblocking_t *tb // This line will always block us return false; } + + if (tb->compareThing->player != NULL) + { + if (P_IsLineTripWire(line) == true && K_TripwirePass(tb->compareThing->player) == false) + { + // Can't go through trip wire. + return false; + } + } } // passed the subsector ok @@ -728,6 +737,15 @@ static boolean P_CrossBotTraversalSubsector(size_t num, register traceblocking_t return false; } + if (tb->compareThing->player != NULL) + { + if (P_IsLineTripWire(line) == true && K_TripwirePass(tb->compareThing->player) == false) + { + // Can't go through trip wire. + return false; + } + } + // set openrange, opentop, openbottom tmx = tb->compareThing->x; tmy = tb->compareThing->y; @@ -742,10 +760,13 @@ static boolean P_CrossBotTraversalSubsector(size_t num, register traceblocking_t return false; } - // Treat damage sectors like walls if (tb->compareThing->player != NULL) { - boolean alreadyHates = K_BotHatesThisSector(tb->compareThing->player, tb->compareThing->subsector->sector, tb->compareThing->x, tb->compareThing->y); + // Treat damage sectors like walls + boolean alreadyHates = K_BotHatesThisSector( + tb->compareThing->player, tb->compareThing->subsector->sector, + tb->compareThing->x, tb->compareThing->y + ); if (alreadyHates == false) { @@ -755,18 +776,16 @@ static boolean P_CrossBotTraversalSubsector(size_t num, register traceblocking_t P_ClosestPointOnLine(tb->compareThing->x, tb->compareThing->y, line, &pos); lineside = P_PointOnLineSide(tb->compareThing->x, tb->compareThing->y, line); - if (K_BotHatesThisSector(tb->compareThing->player, ((lineside == 1) ? line->frontsector : line->backsector), pos.x, pos.y)) + if (K_BotHatesThisSector( + tb->compareThing->player, + ((lineside == 1) ? line->frontsector : line->backsector), + pos.x, pos.y + )) { // This line does not block us, but we don't want to be in it. return false; } } - - if (P_IsLineTripWire(line) == true && K_TripwirePass(tb->compareThing->player) == false) - { - // Can't go through trip wire. - return false; - } } } From 2cbcc8f91433df874c58028ee7e42a522b62101d Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 26 May 2022 00:25:54 -0400 Subject: [PATCH 6/8] Adjust acceleration for rubberbanding Since your acceleration is tied to your top speed, we need to do this to ensure we're ONLY increasing the top speed, and not how fast they make it to that top speed. --- src/k_kart.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index a39543711..0d7ec9cd0 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3298,11 +3298,18 @@ fixed_t K_GetNewSpeed(player_t *player) { const fixed_t accelmax = 4000; const fixed_t p_speed = K_GetKartSpeed(player, true, true); - const fixed_t p_accel = K_GetKartAccel(player); + fixed_t p_accel = K_GetKartAccel(player); fixed_t newspeed, oldspeed, finalspeed; - oldspeed = R_PointToDist2(0, 0, player->rmomx, player->rmomy); // FixedMul(P_AproxDistance(player->rmomx, player->rmomy), player->mo->scale); + if (K_PlayerUsesBotMovement(player) == true && player->botvars.rubberband > 0) + { + // Acceleration is tied to top speed... + // so if we want JUST a top speed boost, we have to do this... + p_accel = FixedDiv(p_accel, player->botvars.rubberband); + } + + oldspeed = R_PointToDist2(0, 0, player->rmomx, player->rmomy); // Don't calculate the acceleration as ever being above top speed if (oldspeed > p_speed) oldspeed = p_speed; From 828e5e7c8126fcc1a51aee50b50e63182beed948 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 26 May 2022 00:29:51 -0400 Subject: [PATCH 7/8] Rival bot in GP gets x2 tether power increment --- src/k_kart.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 0d7ec9cd0..170e5a361 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1856,7 +1856,16 @@ static void K_UpdateDraft(player_t *player) // Draft power is used later in K_GetKartBoostPower, ranging from 0 for normal speed and FRACUNIT for max draft speed. // How much this increments every tic biases toward acceleration! (min speed gets 1.5% per tic, max speed gets 0.5% per tic) if (player->draftpower < FRACUNIT) - player->draftpower += (FRACUNIT/200) + ((9 - player->kartspeed) * ((3*FRACUNIT)/1600)); + { + fixed_t add = (FRACUNIT/200) + ((9 - player->kartspeed) * ((3*FRACUNIT)/1600));; + player->draftpower += add; + + if (player->bot && player->botvars.rival) + { + // Double speed for the rival! + player->draftpower += add; + } + } if (player->draftpower > FRACUNIT) player->draftpower = FRACUNIT; @@ -3162,7 +3171,7 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower, boolean dorubberb fixed_t add = (player->botvars.difficulty * (FRACUNIT/10)) / DIFFICULTBOT; finalspeed = FixedMul(finalspeed, FRACUNIT + add); - if (player->botvars.rival == true) + if (player->bot && player->botvars.rival) { // +10% top speed for the rival finalspeed = FixedMul(finalspeed, 11*FRACUNIT/10); From 8b8933fa1a29fbf28d5eb07c906c10e9b4ec2b13 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 27 May 2022 02:49:36 -0400 Subject: [PATCH 8/8] Fix incorrectly gotten bot controller line ID --- 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 f9dad809a..5664a7193 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -1293,7 +1293,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) } else { - player->botvars.controller = lines - botController; + player->botvars.controller = botController - lines; } player->botvars.rubberband = K_UpdateRubberband(player);