Story phase 4: help when stuck, the arcade opens with the story
- From the third attempt at a checkpoint, the death screen offers TRY AGAIN · WITH HELP, at most two tiers, said openly. In the cup the help is fresher legs and a longer swing; in gore, one more heart and a slower director and horde. Every checkpoint passed resets the offer. - The arcade shows only what the story has opened. Training and Classic open after act I, the Climb after II, Splatter Gore after III, and hosting a friend after IV (joining stays free). Locked doors are shown greyed with the act that opens them. - The non-story endings point at the story instead of the cup. - Store switches for the free tier (act I's card points at the full game) and a premium arcade, both off. - The prologue's HUD no longer overlaps the kill pips. PROJECT.md logs phases 1-4. One new test. v382, staging only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ce27bbc48b
commit
789bf41a9a
10 files changed
+191
-34
No files matched your search
@@ -90,7 +90,7 @@ globalThis.getComputedStyle = () => ({ paddingTop: '0' });
|
||||
const state = await import('./src/state.js');
|
||||
const { G, P, O, score, ball, setupPoint } = state;
|
||||
const { ringCue, predictLanding, solveShot, update, forceZombies, startGore, splatPoint, restartRun, leaguePace, duelSkill, tinLadder, deliverTin, peerK: _peerK, legLevel: _legLevel, winLevel: _winLevel, assistK: _assistK, flickTarget, flatCount, swayOf, keyPressed, classicGame, serveApexY, assistK, rallyFeel, barrelGap, machCap, hitServe, cheer, inCourt } = await import('./src/gameplay.js');
|
||||
const { startDuel, resolveInterlude, startBossFight, endBossFight, startDrill: _startDrill, endDrill, startMatch: _startMatch, endMatch, FALL_LEN, startNetVs, endNetVs, startStory, startStoryChapter } = await import('./src/beats.js');
|
||||
const { startDuel, resolveInterlude, startBossFight, endBossFight, startDrill: _startDrill, endDrill, startMatch: _startMatch, endMatch, FALL_LEN, startNetVs, endNetVs, startStory, startStoryChapter, startHorde } = await import('./src/beats.js');
|
||||
const { mirror, netMsg, netTest, netTick, netAgain } = await import('./src/net.js');
|
||||
// the drill's first-sight modal freezes the world (that is what modals do) — dismiss it the way a
|
||||
// player would, so the tests step a live court
|
||||
@@ -3787,6 +3787,26 @@ test('THE STORY: death is not permadeath — it banks nothing and restarts from
|
||||
assert.equal(G.hp, G.hpMax);
|
||||
});
|
||||
|
||||
test('THE STORY: the help offer — fresher legs and a longer swing in the cup, a heart and a slower horde in gore', () => {
|
||||
const H = cfg.STORY_HELP;
|
||||
intoStory(1, 'cup');
|
||||
const leg0 = _legLevel(), win0 = _winLevel();
|
||||
G.story.help = 2;
|
||||
assert.ok(Math.abs(_legLevel() / leg0 - (1 + 2 * H.run)) < 1e-9, 'legs');
|
||||
assert.ok(Math.abs(_winLevel() / win0 - (1 + 2 * H.window)) < 1e-9, 'swing window');
|
||||
endMatch(); G.story = null;
|
||||
prof.prof.story.help = 2;
|
||||
intoStory(1, 'chap');
|
||||
prof.prof.story.help = 2;
|
||||
G.story = null; assert.ok(startStoryChapter(false));
|
||||
assert.equal(G.hpMax, TUNE.playerHp + 2 * H.heart, 'a heart per tier');
|
||||
G.sets = [1, 0]; startHorde();
|
||||
const slow = G.horde.rate;
|
||||
G.horde = null; G.story.help = 0; startHorde();
|
||||
assert.ok(Math.abs(G.horde.rate / slow - (1 + 2 * H.slow)) < 1e-9, 'the horde comes slower');
|
||||
G.horde = null;
|
||||
});
|
||||
|
||||
test('THE STORY: a barrel holds what the act has earned', () => {
|
||||
intoStory(1, 'chap');
|
||||
const seen = new Set();
|
||||
|
||||
Reference in new issue
Block a user