diff --git a/config.js b/config.js index 435c65f..28df04c 100644 --- a/config.js +++ b/config.js @@ -10,13 +10,14 @@ export const TUNE = { reach: 1.3, aiReach: 1.6, // tight contact radius: the assist positions you, the tap must be honest swingWindup: 0.06, // s before contact window opens swingWindow: 0.16, // s contact window length - // ALL FOUR PACE NUMBERS ARE 1.3x THEIR ORIGINALS (16/12 and 19/22) — the whole ball, tennis and + // ALL FOUR PACE NUMBERS ARE 1.2x THEIR ORIGINALS (16/12 and 19/22) — the whole ball, tennis and // splatter, his and theirs, moved together so nothing about the relative feel shifts. - baseShotSpeed: 20.8, qualityShotSpeed: 15.6, // horizontal m/s = base + q*quality; perfect timing = real pace + baseShotSpeed: 19.2, qualityShotSpeed: 14.4, // horizontal m/s = base + q*quality; perfect timing = real pace // the slingshot's pace range. Weighted hard toward QUALITY so a full draw is a smash you can - // see: 27 m/s floppy at the minimum pull, 53 m/s at full. (baseShotSpeed above is the rally - // volley — shared with tennis mode and the CPU, and scaled with them.) - serveSpeed: 24.7, serveQualitySpeed: 28.6, + // see: 26 m/s floppy at the minimum pull, 49 m/s at full — the draw nearly DOUBLES the pace, + // which is the "harder pull, faster ball" relationship, and it is in serveQualitySpeed's share + // of the pair. (baseShotSpeed is the rally volley — shared with tennis and the CPU.) + serveSpeed: 22.8, serveQualitySpeed: 26.4, serveSpin: 1.3, // extra gravity a full-power serve carries (was a fixed 0.35). Without it the // net-clearance loop ate the whole smash: a flat fast ball can't get over the // tape AND come down on a target, so it got throttled back to walking pace. diff --git a/gameplay.js b/gameplay.js index 2a854bc..8207e7a 100644 --- a/gameplay.js +++ b/gameplay.js @@ -861,6 +861,12 @@ function tryGunBurst() { // slingshot serve, stage one: the pull-back starts the toss animation. The ball rises while // you aim (dotted line, render.js); the release (dragServe) fires it. Only from a fresh pretoss. export function serveToss() { + // A NEW WIND-UP ENDS THE LAST SHOT'S FOLLOW-THROUGH. Without this he latched: hitServe sets + // pose 'serve' with poseT 0, that only expires after POSE_TIME, and the pull frame is only drawn + // from 'idle' — so firing faster than 0.38 s reset the timer before it could ever expire and he + // was welded into p_smash. Racket permanently up, balls appearing out of it, no wind-up at all, + // which is precisely the late-game rapid-fire look. Clearing it here restores pull/smash/pull. + if (score.server === 'P' && P.pose === 'serve') { P.pose = 'idle'; P.poseT = 0; } if (score.server === 'P' && G.phase === 'pretoss' && !ball.active) tossBall(P); }