diff --git a/src/d_clisrv.c b/src/d_clisrv.c index ea3cd0eb1..2eb5930fa 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -5758,6 +5758,27 @@ static void SV_Maketic(void) { INT32 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + // We didn't receive this tic + if ((netcmds[maketic % BACKUPTICS][i].flags & TICCMD_RECEIVED) == 0) + { + ticcmd_t * ticcmd = &netcmds[(maketic ) % BACKUPTICS][i]; + ticcmd_t *prevticcmd = &netcmds[(maketic - 1) % BACKUPTICS][i]; + + // We didn't receive this tic + { + DEBFILE(va("MISS tic%4d for player %d\n", maketic, i)); + // Copy the input from the previous tic + *ticcmd = *prevticcmd; + ticcmd->flags &= ~TICCMD_RECEIVED; + } + } + } + // Moved here so bots and packetloss indication doesn't break.... G_MoveTiccmd(netcmds[maketic % BACKUPTICS], playercmds, MAXPLAYERS); diff --git a/src/k_kart.c b/src/k_kart.c index 3dbf0142c..186e9436e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -466,19 +466,36 @@ fixed_t K_GetKartGameSpeedScalar(SINT8 value) //{ SRB2kart p_user.c Stuff -static fixed_t K_PlayerWeight(mobj_t *mobj, mobj_t *against) +#define WORSTINVBUMPPOWER (FRACUNIT / 14) +#define INVBUMPBOTTLENECK (FRACUNIT - (WORSTINVBUMPPOWER)) + +static fixed_t K_PlayerWeight(mobj_t* mobj, mobj_t* against) { - fixed_t weight = 5*FRACUNIT; + fixed_t weight = 5 * FRACUNIT; + const boolean invinisalt = K_IsKartItemAlternate(KITEM_INVINCIBILITY); if (!mobj->player) return weight; - if (against && !P_MobjWasRemoved(against) && against->player - && ((!P_PlayerInPain(against->player) && P_PlayerInPain(mobj->player)) // You're hurt - || (K_GetShieldFromPlayer(against->player) == KSHIELD_BUBBLE // They have a Bubble Shield - && K_GetShieldFromPlayer(mobj->player) != KSHIELD_BUBBLE))) // and you don't + if (against && !P_MobjWasRemoved(against) && against->player) { - weight = 0; // This player does not cause any bump action + if ((!P_PlayerInPain(against->player) && + P_PlayerInPain(mobj->player)) // You're hurt + || (K_GetShieldFromPlayer(against->player) == + KSHIELD_BUBBLE // They have a Bubble Shield + && K_GetShieldFromPlayer(mobj->player) != KSHIELD_BUBBLE)) // and you don't + { + weight = 0; // This player does not cause any bump action + } + else if (invinisalt && against->player->invincibilitytimer) + { + // Scale Alt. Invin. weight to their power. At full power, you get shoved + // off! Might cause less shitty-feeling bumpcheck moments. + weight = max(0, + FRACUNIT - FixedMul((against->player->kartweight) * FRACUNIT, + K_InvincibilityGradient( + against->player->invincibilitytimer))); + } } else { @@ -488,19 +505,39 @@ static fixed_t K_PlayerWeight(mobj_t *mobj, mobj_t *against) weight = (mobj->player->kartweight) * FRACUNIT; - if (K_GetShieldFromPlayer(mobj->player) == KSHIELD_BUBBLE && mobj->player->bubblecool == 0) + if (invinisalt && mobj->player->invincibilitytimer) + { + // Cap the gradient at 1.0 to prevent exaggerated nonsense. + fixed_t mygradient = min( + FRACUNIT, K_InvincibilityGradient(mobj->player->invincibilitytimer)); + + // Scale Alt. Invin. weight to your power. At full power, they get shoved + // off! Might cause less shitty-feeling bumpcheck moments. + weight = FixedMul(weight, mygradient); + + // Like the Bubble Shield, nerf bumps a good bit to make them feel less + // ridiculous. As your power depletes, this nerf gets less necessary, so + // scale it to match. + weight = + FixedMul(weight, FRACUNIT - FixedMul(INVBUMPBOTTLENECK, mygradient)); + } + else if (K_GetShieldFromPlayer(mobj->player) == KSHIELD_BUBBLE && + mobj->player->bubblecool == 0) { weight = max(BUBBLEMINWEIGHT, weight); - weight = FixedMul(weight, FRACUNIT/16); + weight = FixedMul(weight, FRACUNIT / 16); } if (mobj->player->speed > spd) - weight += (mobj->player->speed - spd)/8; + weight += (mobj->player->speed - spd) / 8; } return weight; } +#undef INVBUMPBOTTLENECK +#undef WORSTINVBUMPPOWER + fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against) { fixed_t weight = 5*FRACUNIT;