The rush picks a lane and commits to it, and stops on a strike line
"They just overrun you without a chance" — two reasons, and the second one only existed because of the first. IT FOLLOWED YOU. The rush tracked your x every frame it was running, so the sidestep was decoration: it simply came across and took you anyway. The lane is LOCKED when the rush starts now. You get the whole 2.2 s run-up to leave it, and what it runs down is that line, not you. AND IT LANDED ON YOU. A rush that stopped at your feet left the boss standing there afterwards, and nothing gets you out from under that — dodgeCool is 0.5 s against a 0.28 s i-frame, so the second contact kills you while the first is still fading. It stops on a STRIKE LINE 0.4 m short instead, reached on the same frame the rush timer expires, so it turns and withdraws the instant it arrives. The version of this that ran the rush THROUGH you and out the far side is why bossStrike is a short stop and not an overrun: a body past the baseline is deleted and scores a point, so the boss quietly despawned itself mid-fight and left the fight running with nothing in it. Measured, 45 s against the seller, the champion's third phase and the physio: stand still and the first rush kills you (4.1 s); step out of the lane and you survive all of it — seven or eight rushes, one sidestep each, the boss on court the whole time and out at its line between them where you can hit it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d57433ed2b
commit
482c7cdce4
2 files changed
+25
-10
No files matched your search
+17
-10
@@ -174,10 +174,16 @@ function bossAI(zb, dt) {
|
||||
zb.moveT -= dt;
|
||||
const v = TUNE.bossChargeV * (A.speedMul ?? 1);
|
||||
if (zb.charging) {
|
||||
const dx = P.x - zb.x;
|
||||
zb.x += Math.sign(dx) * Math.min(Math.abs(dx), TUNE.bossStrafe * dt); // it tracks your lane SLOWLY: a sidestep beats it
|
||||
zb.z = Math.min(P.z, zb.z + zb.chargeV * dt); // AT you and NO FURTHER: unclamped it ran
|
||||
if (zb.moveT <= 0) { zb.charging = false; zb.moveT = TUNE.bossChargeRest; } // off the back of the court
|
||||
// IT COMMITTED TO A LANE AND IT IS RUNNING DOWN THAT LANE, whatever you do next. Tracking your
|
||||
// x for the whole rush made the sidestep meaningless — it just followed you across and ran you
|
||||
// over ("they overrun you without a chance"), and stopping the rush ON you left it standing
|
||||
// there afterwards, where the 0.5 s dodge cooldown cannot outrun a 0.28 s i-frame. So: the
|
||||
// lane is locked when the rush begins, you get the entire run-up to leave it, and the rush
|
||||
// ends on a STRIKE LINE just in front of you, on the same frame the rush timer expires, so it
|
||||
// turns and withdraws the instant it arrives. A rush that misses is over.
|
||||
zb.x += Math.sign(zb.lane - zb.x) * Math.min(Math.abs(zb.lane - zb.x), TUNE.bossStrafe * 2 * dt);
|
||||
zb.z += zb.chargeV * dt;
|
||||
if (zb.moveT <= 0) { zb.charging = false; zb.moveT = TUNE.bossChargeRest; } // spent: it turns and walks back
|
||||
} else {
|
||||
// AND IT FALLS BACK. A rush that ended where it landed left the boss parked on top of you for
|
||||
// the rest of the fight: dodge or die every two seconds, with no window to hit it and nothing
|
||||
@@ -187,13 +193,14 @@ function bossAI(zb, dt) {
|
||||
// PASSES: you dodge it, and the ground it gives up again is your turn to hit it.
|
||||
const home = TUNE.bossZMax, sp = v * (A.retreat ?? 1.3) * dt; // toward its LINE, from either side:
|
||||
zb.z += Math.sign(home - zb.z) * Math.min(Math.abs(home - zb.z), sp); // backward off a rush, forward on the way in
|
||||
// THE RUSH IS TIMED, NOT PACED. Whatever ground the retreat left between you, it covers it in
|
||||
// bossChargeT — so every charge arrives, and every charge takes the same readable run-up to do
|
||||
// it. Paced at a flat speed instead, the same fix that stopped it camping on you also stopped
|
||||
// it ever reaching you: it started each rush from the band and ran out of clock 8 m short.
|
||||
if (zb.moveT <= 0) {
|
||||
// THE RUSH IS TIMED, NOT PACED, and it always begins FROM THE LINE — never from wherever a
|
||||
// half-finished retreat happened to leave it, which is how a rush could start on your toes
|
||||
// with no run-up to read. It covers the whole distance in bossChargeT, so the approach looks
|
||||
// the same every time whatever the design's speed.
|
||||
if (zb.moveT <= 0 && Math.abs(zb.z - home) < 0.1) {
|
||||
zb.charging = true; zb.moveT = TUNE.bossChargeT;
|
||||
zb.chargeV = Math.max(v, (P.z - zb.z) / TUNE.bossChargeT);
|
||||
zb.lane = P.x; // the lane, locked. You have the run-up to leave it.
|
||||
zb.chargeV = (P.z - TUNE.bossStrike - zb.z) / TUNE.bossChargeT;
|
||||
}
|
||||
}
|
||||
} else if (style === 'shadow') {
|
||||
|
||||
Reference in new issue
Block a user