Drastically simplified bot rubberbanding

This commit is contained in:
Sally Coolatta 2022-05-23 23:59:18 -04:00
parent 14053a55cd
commit c678146f0c
10 changed files with 69 additions and 192 deletions

View file

@ -556,8 +556,8 @@ fixed_t K_BotRubberband(player_t *player)
// Lv. 1: x0.75 min // Lv. 1: x0.75 min
// Lv. 5: x0.875 min // Lv. 5: x0.875 min
// Lv. 9: x1.0 min // Lv. 9: x1.0 min
// Lv. MAX: x1.0 min // Lv. MAX: x1.125 min
rubbermin = FRACUNIT - (((FRACUNIT/4) * (DIFFICULTBOT - min(DIFFICULTBOT, player->botvars.difficulty))) / (DIFFICULTBOT - 1)); rubbermin = FRACUNIT - (((FRACUNIT/4) * (DIFFICULTBOT - player->botvars.difficulty)) / (DIFFICULTBOT - 1));
if (rubberband > rubbermax) if (rubberband > rubbermax)
{ {
@ -571,97 +571,6 @@ fixed_t K_BotRubberband(player_t *player)
return rubberband; 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) 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) 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; fixed_t speedrad = rad/4;
if (speedmul > FRACUNIT) if (speedmul > FRACUNIT)

View file

@ -87,39 +87,6 @@ boolean K_BotCanTakeCut(player_t *player);
fixed_t K_BotRubberband(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); fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y, fixed_t cx, fixed_t cy);

View file

@ -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 if ((player->offroad && K_ApplyOffroad(player)) // Stuck in offroad, use it NOW
|| K_GetWaypointIsShortcut(player->nextwaypoint) == true // Going toward a shortcut! || 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->speedboost > (FRACUNIT/8) // Have another type of boost (tethering)
|| player->botvars.itemconfirm > 4*TICRATE) // Held onto it for too long || 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) 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)); fixed_t radius = FixedMul(2560 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
SINT8 throwdir = -1; SINT8 throwdir = -1;
boolean tryLookback = false; 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) 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)); fixed_t radius = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
SINT8 throwdir = -1; SINT8 throwdir = -1;
boolean tryLookback = false; 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) 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)); fixed_t radius = FixedMul(2560 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
SINT8 throwdir = 1; SINT8 throwdir = 1;
boolean tryLookback = false; boolean tryLookback = false;
@ -1165,7 +1165,7 @@ static void K_BotItemRings(player_t *player, ticcmd_t *cmd)
{ {
INT32 saferingsval = 16 - K_GetKartRingPower(player, false); 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) || player->speedboost > (FRACUNIT/5)) // Have another type of boost (tethering)
{ {
saferingsval -= 5; saferingsval -= 5;

View file

@ -2505,19 +2505,19 @@ static void K_drawKartSpeedometer(void)
{ {
case 1: // Sonic Drift 2 style percentage case 1: // Sonic Drift 2 style percentage
default: 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; labeln = 0;
break; break;
case 2: // Kilometers 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; labeln = 1;
break; break;
case 3: // Miles 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; labeln = 2;
break; break;
case 4: // Fracunits case 4: // Fracunits
convSpeed = FixedDiv(stplyr->speed, mapobjectscale)/FRACUNIT; // 1.0. duh. convSpeed = FixedDiv(stplyr->speed, mapobjectscale) / FRACUNIT; // 1.0. duh.
labeln = 3; labeln = 3;
break; break;
} }

View file

@ -1183,9 +1183,15 @@ static fixed_t K_PlayerWeight(mobj_t *mobj, mobj_t *against)
} }
else 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; 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) if (mobj->player->itemtype == KITEM_BUBBLESHIELD)
weight += 9*FRACUNIT; 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) 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 draftdistance;
fixed_t minDist; fixed_t minDist;
UINT8 leniency; UINT8 leniency;
@ -2033,7 +2039,7 @@ void K_SpawnDashDustRelease(player_t *player)
static fixed_t K_GetBrakeFXScale(player_t *player, fixed_t maxScale) static fixed_t K_GetBrakeFXScale(player_t *player, fixed_t maxScale)
{ {
fixed_t s = FixedDiv(player->speed, fixed_t s = FixedDiv(player->speed,
K_GetKartSpeed(player, false)); K_GetKartSpeed(player, false, false));
s = max(s, FRACUNIT); s = max(s, FRACUNIT);
s = min(s, maxScale); s = min(s, maxScale);
@ -2366,7 +2372,7 @@ void K_KartMoveAnimation(player_t *player)
{ {
const INT16 minturn = KART_FULLTURN/8; 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 fixed_t speedthreshold = player->mo->scale / 8;
const boolean onground = P_IsObjectOnGround(player->mo); const boolean onground = P_IsObjectOnGround(player->mo);
@ -2916,7 +2922,7 @@ boolean K_TripwirePassConditions(player_t *player)
player->sneakertimer || player->sneakertimer ||
player->growshrinktimer > 0 || player->growshrinktimer > 0 ||
player->flamedash || player->flamedash ||
player->speed > 2 * K_GetKartSpeed(player, false) player->speed > 2 * K_GetKartSpeed(player, false, true)
) )
return true; return true;
return false; return false;
@ -2934,7 +2940,7 @@ boolean K_WaterRun(player_t *player)
player->sneakertimer || player->sneakertimer ||
player->tiregrease || player->tiregrease ||
player->flamedash || player->flamedash ||
player->speed > 2 * K_GetKartSpeed(player, false) player->speed > 2 * K_GetKartSpeed(player, false, true)
) )
return true; return true;
return false; return false;
@ -3145,7 +3151,7 @@ fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed)
return finalspeed; 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); const boolean mobjValid = (player->mo != NULL && P_MobjWasRemoved(player->mo) == false);
fixed_t finalspeed = K_GetKartSpeedFromStat(player->kartspeed); 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)); finalspeed = FixedMul(finalspeed, K_GrowShrinkSpeedMul(player));
} }
if (K_PlayerUsesBotMovement(player))
{
finalspeed = FixedMul(finalspeed, K_BotTopSpeedRubberband(player));
}
finalspeed = FixedMul(finalspeed, player->boostpower + player->speedboost); finalspeed = FixedMul(finalspeed, player->boostpower + player->speedboost);
} }
if (dorubberband == true && K_PlayerUsesBotMovement(player) == true)
{
finalspeed = FixedMul(finalspeed, K_BotRubberband(player));
}
return finalspeed; return finalspeed;
} }
@ -3297,22 +3303,16 @@ SINT8 K_GetForwardMove(player_t *player)
fixed_t K_GetNewSpeed(player_t *player) fixed_t K_GetNewSpeed(player_t *player)
{ {
const fixed_t accelmax = 4000; 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); const fixed_t p_accel = K_GetKartAccel(player);
fixed_t newspeed, oldspeed, finalspeed; 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); 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 // Don't calculate the acceleration as ever being above top speed
if (oldspeed > p_speed) if (oldspeed > p_speed)
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; 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 )) if (( player->spinouttype & KSPIN_THRUST ))
{ {
// At spinout, player speed is increased to 1/4 their regular speed, moving them forward // At spinout, player speed is increased to 1/4 their regular speed, moving them forward
if (player->speed < K_GetKartSpeed(player, true)/4) fixed_t spd = K_GetKartSpeed(player, true, true) / 4;
P_InstaThrust(player->mo, player->mo->angle, FixedMul(K_GetKartSpeed(player, true)/4, player->mo->scale));
if (player->speed < spd)
P_InstaThrust(player->mo, player->mo->angle, FixedMul(spd, player->mo->scale));
S_StartSound(player->mo, sfx_slip); 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); K_AddHitLag(player->mo, 10, false);
if (state == TRIP_PASSED && player->spinouttimer && 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); 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; mobj_t *th;
fixed_t x, y, z; fixed_t x, y, z;
fixed_t topspeed = K_GetKartSpeed(source->player, false, false);
fixed_t finalspeed = speed; fixed_t finalspeed = speed;
fixed_t finalscale = mapobjectscale; fixed_t finalscale = mapobjectscale;
mobj_t *throwmo; mobj_t *throwmo;
if (source->player != NULL) if (source->player != NULL)
{ {
if (source->player->itemscale == ITEMSCALE_SHRINK) if (source->player->itemscale == ITEMSCALE_SHRINK)
{ {
// Nerf the base item speed a bit. // Nerf the base item speed a bit.
finalspeed = FixedMul(finalspeed, SHRINK_PHYSICS_SCALE); 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; angle_t input = source->angle - an;
boolean invert = (input > ANGLE_180); 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); input = InvAngle(input);
finalspeed = max(speed, FixedMul(speed, FixedMul( 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<<FRACBITS) - AngleFixed(input)) / 180) // multiply speed based on angle diff... i.e: don't do this for firing backward :V (((180<<FRACBITS) - AngleFixed(input)) / 180) // multiply speed based on angle diff... i.e: don't do this for firing backward :V
))); )));
} }
@ -4505,7 +4510,7 @@ static void K_SpawnAIZDust(player_t *player)
if (!P_IsObjectOnGround(player->mo)) if (!P_IsObjectOnGround(player->mo))
return; return;
if (player->speed <= K_GetKartSpeed(player, false)) if (player->speed <= K_GetKartSpeed(player, false, true))
return; return;
travelangle = K_MomentumAngle(player->mo); 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 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) // 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); //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); 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) if (leveltime & 1)
targz += 8*(2*FRACUNIT)/7; targz += 8*(2*FRACUNIT)/7;
else else
targz -= 8*(2*FRACUNIT)/7; targz -= 8*(2*FRACUNIT)/7;
}*/ }
*/
if (speed > dist) if (speed > dist)
P_InstaThrust(cur, cur->angle, 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 && if (K_GetKartButtons(player) & BT_BRAKE &&
P_IsObjectOnGround(player->mo) && P_IsObjectOnGround(player->mo) &&
K_GetKartSpeed(player, false) / 2 <= player->speed) K_GetKartSpeed(player, false, false) / 2 <= player->speed)
{ {
K_SpawnBrakeVisuals(player); K_SpawnBrakeVisuals(player);
} }
@ -8312,14 +8319,13 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue)
return 0; return 0;
} }
p_maxspeed = K_GetKartSpeed(player, false); p_maxspeed = K_GetKartSpeed(player, false, true);
p_speed = min(currentSpeed, (p_maxspeed * 2)); p_speed = min(currentSpeed, (p_maxspeed * 2));
weightadjust = FixedDiv((p_maxspeed * 3) - p_speed, (p_maxspeed * 3) + (player->kartweight * FRACUNIT)); weightadjust = FixedDiv((p_maxspeed * 3) - p_speed, (p_maxspeed * 3) + (player->kartweight * FRACUNIT));
if (K_PlayerUsesBotMovement(player)) if (K_PlayerUsesBotMovement(player))
{ {
turnfixed = FixedMul(turnfixed, 5*FRACUNIT/4); // Base increase to turning turnfixed = FixedMul(turnfixed, 5*FRACUNIT/4); // Base increase to turning
turnfixed = FixedMul(turnfixed, K_BotRubberband(player));
} }
if (player->drift != 0 && P_IsObjectOnGround(player->mo)) if (player->drift != 0 && P_IsObjectOnGround(player->mo))
@ -8365,7 +8371,7 @@ INT32 K_GetUnderwaterTurnAdjust(player_t *player)
steer = 9 * steer / 5; steer = 9 * steer / 5;
return FixedMul(steer, 8 * FixedDiv(player->speed, return FixedMul(steer, 8 * FixedDiv(player->speed,
2 * K_GetKartSpeed(player, false) / 3)); 2 * K_GetKartSpeed(player, false, true) / 3));
} }
else else
return 0; return 0;
@ -9317,13 +9323,6 @@ void K_AdjustPlayerFriction(player_t *player)
else else
player->mo->movefactor = FRACUNIT; 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);
}
} }
// //

View file

@ -124,7 +124,7 @@ INT16 K_GetSpindashChargeTime(player_t *player);
fixed_t K_GetSpindashChargeSpeed(player_t *player); fixed_t K_GetSpindashChargeSpeed(player_t *player);
fixed_t K_GrowShrinkSpeedMul(player_t *player); fixed_t K_GrowShrinkSpeedMul(player_t *player);
fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed); 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); fixed_t K_GetKartAccel(player_t *player);
UINT16 K_GetKartFlashing(player_t *player); UINT16 K_GetKartFlashing(player_t *player);
boolean K_PlayerShrinkCheat(player_t *player); boolean K_PlayerShrinkCheat(player_t *player);

View file

@ -3693,10 +3693,11 @@ static int lib_kGetKartSpeed(lua_State *L)
{ {
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
boolean doboostpower = lua_optboolean(L, 2); boolean doboostpower = lua_optboolean(L, 2);
boolean dorubberbanding = lua_optboolean(L, 3);
//HUDSAFE //HUDSAFE
if (!player) if (!player)
return LUA_ErrInvalid(L, "player_t"); return LUA_ErrInvalid(L, "player_t");
lua_pushfixed(L, K_GetKartSpeed(player, doboostpower)); lua_pushfixed(L, K_GetKartSpeed(player, doboostpower, dorubberbanding));
return 1; return 1;
} }

View file

@ -4980,7 +4980,7 @@ void A_DetonChase(mobj_t *actor)
fixed_t xyspeed, speed; fixed_t xyspeed, speed;
if (actor->target->player) if (actor->target->player)
speed = K_GetKartSpeed(actor->tracer->player, false); speed = K_GetKartSpeed(actor->tracer->player, false, false);
else else
speed = actor->target->info->speed; speed = actor->target->info->speed;
@ -13285,7 +13285,7 @@ void A_JawzChase(mobj_t *actor)
{ {
if (actor->tracer->player) 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)); topspeed = topspeed - FixedMul(speeddifference, FRACUNIT-FixedDiv(distaway, distbarrier));
} }
} }
@ -13615,7 +13615,7 @@ void A_SPBChase(mobj_t *actor)
else else
{ {
// 7/8ths max speed for Knuckles, 3/4ths max speed for min accel, exactly max speed for max accel // 7/8ths max speed for Knuckles, 3/4ths max speed for min accel, exactly max speed for max accel
defspeed = FixedMul(((fracmax+1)<<FRACBITS) - easiness, K_GetKartSpeed(actor->tracer->player, false)) / fracmax; defspeed = FixedMul(((fracmax+1)<<FRACBITS) - easiness, K_GetKartSpeed(actor->tracer->player, false, false)) / fracmax;
} }
// Be fairer on conveyors // 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! // 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 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 : (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); SpawnSPBSpeedLines(actor);
return; return;

View file

@ -2998,7 +2998,7 @@ boolean P_CanRunOnWater(player_t *player, ffloor_t *rover)
clip > -(player->mo->height / 2) && clip > -(player->mo->height / 2) &&
span > player->mo->height && span > player->mo->height &&
player->speed / 5 > abs(player->mo->momz) && player->speed / 5 > abs(player->mo->momz) &&
player->speed > K_GetKartSpeed(player, false) && player->speed > K_GetKartSpeed(player, false, false) &&
K_WaterRun(player) && K_WaterRun(player) &&
(rover->flags & FF_SWIMMABLE); (rover->flags & FF_SWIMMABLE);
} }

View file

@ -197,7 +197,7 @@ void P_CalcHeight(player_t *player)
fixed_t bob = 0; fixed_t bob = 0;
fixed_t pviewheight; fixed_t pviewheight;
mobj_t *mo = player->mo; 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. // Regular movement bobbing.
// Should not be calculated when not on ground (FIXTHIS?) // 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 // allow for being able to change direction on spring jumps without being accelerated into the void - Sryder
if (!P_IsObjectOnGround(player->mo)) 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); 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; fixed_t tempmomx, tempmomy;
if (oldMagnitude > K_GetKartSpeed(player, true)) if (oldMagnitude > topspeed)
{ {
if (newMagnitude > oldMagnitude) if (newMagnitude > oldMagnitude)
{ {
@ -1986,8 +1987,8 @@ static void P_3dMovement(player_t *player)
} }
else else
{ {
tempmomx = FixedMul(FixedDiv(player->mo->momx - player->cmomx, 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), K_GetKartSpeed(player, true)); //topspeed) tempmomy = FixedMul(FixedDiv(player->mo->momy - player->cmomy, newMagnitude), topspeed);
player->mo->momx = tempmomx + player->cmomx; player->mo->momx = tempmomx + player->cmomx;
player->mo->momy = tempmomy + player->cmomy; player->mo->momy = tempmomy + player->cmomy;
} }
@ -2256,8 +2257,8 @@ void P_MovePlayer(player_t *player)
&& (player->speed > runspd) && (player->speed > runspd)
&& player->mo->momz == 0 && player->carry != CR_SLIDING && !player->spectator) && 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, false);
fixed_t playerTopSpeed = K_GetKartSpeed(player, false); fixed_t trailScale = FixedMul(FixedDiv(player->speed - runspd, playerTopSpeed - runspd), mapobjectscale);
if (playerTopSpeed > runspd) if (playerTopSpeed > runspd)
trailScale = FixedMul(FixedDiv(player->speed - runspd, playerTopSpeed - runspd), mapobjectscale); trailScale = FixedMul(FixedDiv(player->speed - runspd, playerTopSpeed - runspd), mapobjectscale);