Story phase 2: the transformation and the prologue
At match point of an act's cup final the beaten finalist does not fall. The ceremony lands (the loot, still a plain card), then the applause is cut, the camera closes in, and on the turn he bursts and the act's boss stands where he stood, growing into the frame with his name and "GAME 10". He runs out of the picture to the left while the stands empty onto the court, and game 1 of the chapter begins without a cut: the crowd that came down is its first wave. The interlude holds serving, spawns and the boss's AI through the scene. The prologue is one game of tennis against a living opponent with the old transformation exactly as written; when it hands over, act I's cup takes the court. Two new tests. v380, staging only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
75b450f105
commit
ff63c832cc
6 files changed
+153
-21
No files matched your search
@@ -3653,7 +3653,7 @@ function intoStory(act, cp) {
|
||||
G.modal = null; G.modalQ.length = 0;
|
||||
}
|
||||
function winStoryCup() {
|
||||
for (let i = 0; i < 120 * 60 && G.story && G.story.part === 'cup'; i++) {
|
||||
for (let i = 0; i < 120 * 60 && G.story && (G.story.part === 'cup' || G.story.part === 'morph'); i++) {
|
||||
G.modal = null; G.modalQ.length = 0; G.hp = G.hpMax;
|
||||
if (G.match && !G.match.ending && !G.matchFall && G.phase === 'pretoss' && !(G.interlude && G.interlude.introT > 0))
|
||||
resolveInterlude('P', 'test');
|
||||
@@ -3695,6 +3695,48 @@ test('THE STORY: the act\'s cup is won into its chapter — no promotion, the st
|
||||
assert.equal(G.runGames, cfg.STORY.base(1), 'the chapter starts at its own game 1');
|
||||
});
|
||||
|
||||
test('THE STORY: the beaten finalist grows into the act boss, runs off, and game 1 begins without a cut', () => {
|
||||
intoStory(1, 'cup');
|
||||
const cup = G.match.cup;
|
||||
cup.round = cup.rounds.length - 1; cup.g = cup.rounds[cup.round].need - 1; // match point of the final
|
||||
G.match.opp = cup.rung = cup.rounds[cup.round].band[0];
|
||||
let seen = { morph: false, boss: null, grew: 0, left: false, crowd: 0, served: false };
|
||||
for (let i = 0; i < 60 * 60 && !(G.story && G.story.part === 'chap'); i++) {
|
||||
G.modal = null; G.modalQ.length = 0; G.hp = G.hpMax;
|
||||
if (G.match && !G.match.ending && !G.matchFall && G.phase === 'pretoss' && !(G.interlude && G.interlude.introT > 0))
|
||||
resolveInterlude('P', 'test');
|
||||
update(DT);
|
||||
if (G.story && G.story.part === 'morph') {
|
||||
seen.morph = true;
|
||||
assert.ok(G.interlude, 'nothing serves or spawns through the scene');
|
||||
const b = zombies.find(z => z.variant === 'B');
|
||||
if (b) { seen.boss = b.art.name; seen.grew = Math.max(seen.grew, b.scale); if (b.x < -6) seen.left = true; }
|
||||
seen.crowd = Math.max(seen.crowd, zombies.filter(z => z.variant === 'a' || z.variant === 'b').length);
|
||||
}
|
||||
}
|
||||
assert.ok(seen.morph, 'the final ends in the transformation');
|
||||
assert.equal(seen.boss, cfg.storyBossArt(1, 'end').name, 'the keeper grows into the groundskeeper');
|
||||
assert.ok(seen.left, 'he runs out of the frame');
|
||||
assert.ok(seen.crowd >= 3, 'the stands empty onto the court');
|
||||
assert.equal(G.story && G.story.part, 'chap', 'game 1 of the chapter');
|
||||
assert.ok(!zombies.some(z => z.variant === 'B'), 'the boss is gone until game ten');
|
||||
assert.ok(zombies.length >= 3, 'the crowd that came down is the first wave — no cut, no clear');
|
||||
assert.ok(!G.interlude, 'play is open');
|
||||
});
|
||||
|
||||
test('THE STORY: the prologue is a living match that turns, and then the first act opens', () => {
|
||||
restartRun();
|
||||
prof.prof.story = { act: 1, cp: 'pro', rack: [], tries: 0 };
|
||||
assert.equal(G.mode, 'tennis', 'a real match');
|
||||
assert.ok(startStory());
|
||||
G.modal = null; G.modalQ.length = 0;
|
||||
assert.equal(G.story.part, 'pro');
|
||||
forceZombies(); // the old turn, exactly as written
|
||||
for (let i = 0; i < 20 * 60 && !(G.match && G.match.cup); i++) { G.modal = null; G.modalQ.length = 0; update(DT); }
|
||||
assert.equal(prof.prof.story.cp, 'cup', 'the prologue is behind you');
|
||||
assert.ok(G.match && G.match.cup && G.story && G.story.part === 'cup', 'act I\'s cup takes the court');
|
||||
});
|
||||
|
||||
test('THE STORY: a chapter has no duel, a mid-boss checkpoint at five and the act boss at ten', () => {
|
||||
prof.prof.lg = 1;
|
||||
intoStory(2, 'chap');
|
||||
|
||||
Reference in new issue
Block a user