diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 4953f58f5..3b8f4f523 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -5805,6 +5805,8 @@ static void CL_SendClientCmd(void) { // Gentlemens' ping. lagDelay = min(lowest_lag, MAXGENTLEMENDELAY); + if (server) // Clients have to wait for the gamestate to make it back. Servers don't! + lagDelay *= 2; // Simulate the HELLFUCK NIGHTMARE of a complete round trip. } packetsize = sizeof (clientcmd_pak); diff --git a/src/k_kart.c b/src/k_kart.c index 48f1afaa8..dda407cd2 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3088,10 +3088,7 @@ static void K_GetKartBoostPower(player_t *player) numboosts++; \ speedboost += FixedDiv(s, FRACUNIT + (metabolism * (numboosts-1))); \ accelboost += FixedDiv(a, FRACUNIT + (metabolism * (numboosts-1))); \ - if (K_Sliptiding(player)) \ - handleboost += FixedDiv(h, FRACUNIT + (metabolism * (numboosts-1))/4); \ - else \ - handleboost = max(h, handleboost); \ + handleboost = max(h, handleboost); \ } if (player->sneakertimer) // Sneaker @@ -8965,9 +8962,19 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) return K_GetKartDriftValue(player, countersteer); } - if (player->handleboost > 0) + fixed_t finalhandleboost = player->handleboost; + + // If you're sliptiding, don't interact with handling boosts. + // You need turning power proportional to your speed, no matter what! + fixed_t topspeed = K_GetKartSpeed(player, false, false); + if (K_Sliptiding(player)) { - turnfixed = FixedMul(turnfixed, FRACUNIT + player->handleboost); + finalhandleboost = FixedMul(5*SLIPTIDEHANDLING/4, FixedDiv(player->speed, topspeed)); + } + + if (finalhandleboost > 0) + { + turnfixed = FixedMul(turnfixed, FRACUNIT + finalhandleboost); } if (player->curshield == KSHIELD_TOP) @@ -9208,6 +9215,9 @@ static void K_KartDrift(player_t *player, boolean onground) // Stop drifting player->drift = player->driftcharge = player->aizdriftstrat = 0; player->pflags &= ~(PF_BRAKEDRIFT|PF_GETSPARKS); + // And take away wavedash properties: advanced cornering demands advanced finesse + player->sliptideZip = 0; + player->sliptideZipBoost = 0; } else if ((player->pflags & PF_DRIFTINPUT) && player->drift != 0) { @@ -9300,21 +9310,37 @@ static void K_KartDrift(player_t *player, boolean onground) player->pflags &= ~PF_DRIFTEND; } + // No longer meet the conditions to sliptide? + // We'll spot you the sliptide as long as you keep turning, but no charging wavedashes. + boolean keepsliptide = false; + if ((player->handleboost < (SLIPTIDEHANDLING/2)) || (!player->steering) || (!player->aizdriftstrat) || (player->steering > 0) != (player->aizdriftstrat > 0)) { - if (!player->drift) - player->aizdriftstrat = 0; + if (!player->drift && player->steering && player->aizdriftstrat && player->sliptideZip // If we were sliptiding last tic, + && (player->steering > 0) == (player->aizdriftstrat > 0) // we're steering in the right direction, + && player->speed >= K_GetKartSpeed(player, false, true)) // and we're above the threshold to spawn dust... + { + keepsliptide = true; // Then keep your current sliptide, but note the behavior change for sliptidezip handling. + } else - player->aizdriftstrat = ((player->drift > 0) ? 1 : -1); + { + if (!player->drift) + player->aizdriftstrat = 0; + else + player->aizdriftstrat = ((player->drift > 0) ? 1 : -1); + } } - else if (player->aizdriftstrat && !player->drift) + + if ((player->aizdriftstrat && !player->drift) + || (keepsliptide)) { K_SpawnAIZDust(player); - player->sliptideZip++; + if (!keepsliptide) + player->sliptideZip++; if (player->sliptideZip == MIN_WAVEDASH_CHARGE) S_StartSound(player->mo, sfx_waved5); @@ -9333,9 +9359,12 @@ static void K_KartDrift(player_t *player, boolean onground) } } - if (!K_Sliptiding(player)) + if (player->mo->eflags & MFE_UNDERWATER) + player->aizdriftstrat = 0; + + if (!K_Sliptiding(player) || keepsliptide) { - if (K_IsLosingSliptideZip(player) && player->sliptideZip > 0) + if (!keepsliptide && K_IsLosingSliptideZip(player) && player->sliptideZip > 0) { if (!S_SoundPlaying(player->mo, sfx_waved2)) S_StartSoundAtVolume(player->mo, sfx_waved2, 255/2); // Losing combo time, going to boost @@ -9693,6 +9722,8 @@ boolean K_PlayerEBrake(player_t *player) SINT8 K_Sliptiding(player_t *player) { + if (player->mo->eflags & MFE_UNDERWATER) + return 0; return player->drift ? 0 : player->aizdriftstrat; } diff --git a/src/p_user.c b/src/p_user.c index 71d8eb630..a9a2f24a4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2206,8 +2206,8 @@ static void P_UpdatePlayerAngle(player_t *player) { // With a full slam on the analog stick, how far could we steer in either direction? INT16 steeringRight = K_UpdateSteeringValue(player->steering, KART_FULLTURN); - angle_t maxTurnRight = K_GetKartTurnValue(player, steeringRight) << TICCMD_REDUCE; INT16 steeringLeft = K_UpdateSteeringValue(player->steering, -KART_FULLTURN); + angle_t maxTurnRight = K_GetKartTurnValue(player, steeringRight) << TICCMD_REDUCE; angle_t maxTurnLeft = K_GetKartTurnValue(player, steeringLeft) << TICCMD_REDUCE; // Grab local camera angle from ticcmd. Where do we actually want to go? @@ -2218,18 +2218,15 @@ static void P_UpdatePlayerAngle(player_t *player) // That means undoing them takes the same amount of time as doing them. // This can lead to oscillating death spiral states on a multi-tic correction, as we swing past the target angle. // So before we go into death-spirals, if our predicton is _almost_ right... - angle_t leniency = (2*ANG1/3) * min(player->cmd.latency, 6); + angle_t leniency = (4*ANG1/3) * min(player->cmd.latency, 6); // Don't force another turning tic, just give them the desired angle! - if (targetDelta == angleChange || player->pflags & PF_DRIFTEND || K_Sliptiding(player) || (maxTurnRight == 0 && maxTurnLeft == 0)) + if (targetDelta == angleChange || K_Sliptiding(player) || (maxTurnRight == 0 && maxTurnLeft == 0)) { - // We are where we need to be. - // ...Or we aren't, but shouldn't be able to steer. + // Either we're dead on, we can't steer, or we're in a special handling state. + // Stuff like sliptiding requires some blind-faith steering: + // if a camera correction stops our turn input, the sliptide randomly fails! player->steering = targetsteering; - // Alternatively, while in DRIFTEND we want to trust inputs for a bit, not camera. - // The game client doesn't know we're DRIFTEND until after a response gets back, - // so we momentarily ignore the camera angle and let the server trust our inputs instead. - // That way, even if you're steering blind, you get the intended "kick-out" effect. } else {