round3: G1 gd_answer提前一小节(根因=排程压窗起点) + G2教学降难DDA + G3 count-in修复(根因=未重排调度队列) + G4 escape目标链 + G5 simon双击根治(重听改上滑,重录3句) + G6轮成功/破纪录 + G7 space方向呼喊 + 22语音文件 + guide93断言全绿
This commit is contained in:
@@ -1,13 +1,16 @@
|
||||
/**
|
||||
* 《节拍行者》新手会话剧本:首局完整走教学 T1-T3 → 曲目一(90 BPM);
|
||||
* 曲中下滑呼出菜单逛一圈再恢复;第一乐句故意整句漏掉(连 2 Miss 触发向导
|
||||
* 「慢了半拍」提示),之后跟着领奏把一曲打完到结算。
|
||||
* 《节拍行者》新手会话剧本:首局完整走教学 T1-T3(第 2 句故意连错两遍,
|
||||
* 触发 round3 G2 的「降速 25% 重演 + gd_slow」,跟着慢速领奏做对后恢复正常)
|
||||
* → 曲目一(90 BPM);曲中下滑呼出菜单逛一圈再恢复(round3 G3:恢复先听
|
||||
* gd_count「四拍之后,继续」,再跟 4 拍底鼓 count-in 进场;首个应答窗口前
|
||||
* 整整 1 小节有 gd_answer+turn 交接标记);第一乐句故意整句漏掉(连 2 Miss
|
||||
* 触发向导「慢了半拍」提示),之后跟着领奏把一曲打完到结算。
|
||||
*/
|
||||
export function describe(game) {
|
||||
switch (game.phase) {
|
||||
case 'intro': return '开场旁白在播,单击可以跳过';
|
||||
case 'tut': return game._cues.length
|
||||
? `教学:听领奏,下一小节照样打(${game._cues.map((c) => c.gesture).join('→')})`
|
||||
? `教学:听领奏,下一小节照样打(${game._cues.map((c) => c.gesture).join('→')})${game._tutRate < 1 ? '(领奏已放慢 25%)' : ''}`
|
||||
: '教学准备中,听鼓点';
|
||||
case 'select': return '选曲:左右滑换曲,单击开始,下滑回大厅';
|
||||
case 'main': {
|
||||
@@ -33,6 +36,26 @@ export async function session(ctx, mock) {
|
||||
for (let step = 0; step < 3; step++) {
|
||||
await ctx.waitCond(() => game.phase === 'tut' && game._cues.length > 0 && game._tutAttempts.length === 0);
|
||||
ctx.status(`教学第 ${step + 1}/3 句`);
|
||||
if (step === 1) {
|
||||
// round3 G2 剧本:这一句故意连错两遍(整句不出手),听它放慢一些再带着打。
|
||||
// 注意 _tutEvaluate 判定即把 _phaseEnd 置 Infinity 防重入——等待一律挂
|
||||
// 「持久里程碑」条件(_tutFails/_tutSlowUsed),别挂阶段末时刻。
|
||||
await ctx.waitCond(() => game._tutFails === 1); // 失败①:没出手
|
||||
ctx.status('第一遍没敢出手,先听它归因');
|
||||
await ctx.waitCond(() => game._phaseEnd < 1e8 && t() < game._phaseEnd - 1); // 纠正链播完、重新领奏
|
||||
ctx.status('又重新领奏了一遍,还是没敢出手');
|
||||
await ctx.waitCond(() => game._tutSlowUsed === true); // 失败② → 触发降速重演
|
||||
await ctx.waitCond(() => game._phaseEnd < 1e8 && t() < game._phaseEnd - 1); // gd_slow 播完、慢速领奏已排
|
||||
ctx.status('听到「我放慢一些,跟着试试」——领奏降速 25% 重演,这回跟着慢拍打');
|
||||
for (const cue of game._cues) {
|
||||
const at = cue.expected - (cue.gesture === 'tap' ? -0.28 : 0.04);
|
||||
await ctx.waitCond(() => t() >= at || cue.judged);
|
||||
if (cue.judged) continue;
|
||||
await ctx.gesture(cue.gesture);
|
||||
}
|
||||
await ctx.waitCond(() => game._tutIdx > step || game.phase !== 'tut');
|
||||
continue;
|
||||
}
|
||||
for (const cue of game._cues) {
|
||||
const at = cue.expected - (cue.gesture === 'tap' ? -0.28 : 0.04); // tap 补偿引擎 ~300ms 延迟
|
||||
await ctx.waitCond(() => t() >= at || cue.judged);
|
||||
@@ -42,10 +65,11 @@ export async function session(ctx, mock) {
|
||||
await ctx.waitCond(() => game._tutIdx > step || game.phase !== 'tut');
|
||||
}
|
||||
await ctx.waitCond(() => game.phase === 'main');
|
||||
ctx.status('教学完毕,曲目一《启程》90 拍开始');
|
||||
ctx.status('教学完毕,曲目一《启程》90 拍开始。领奏响之前先听到「现在跟着我打」');
|
||||
|
||||
// 曲中逛菜单:下滑呼出(模态暂停)→ 听选项 → 下滑恢复
|
||||
await ctx.waitVirtual(2500);
|
||||
//(round3 G3:恢复先播「四拍之后,继续」,再跟 4 拍底鼓 count-in 进场)
|
||||
await ctx.waitCond(() => t() >= game._bgmT0 + 1.5);
|
||||
await ctx.gesture('down');
|
||||
await ctx.waitCond(() => game.phase === 'menu');
|
||||
ctx.status('曲中暂停,进了菜单');
|
||||
@@ -54,6 +78,7 @@ export async function session(ctx, mock) {
|
||||
ctx.note('还是想打完这首,下滑回去');
|
||||
await ctx.gesture('down'); // 恢复
|
||||
await ctx.waitCond(() => game.phase === 'main');
|
||||
ctx.status('听到「四拍之后,继续」,跟着四下底鼓数拍进来了');
|
||||
|
||||
// 第一乐句故意整句不打:连 2 次 Miss → 向导 gd_miss
|
||||
const firstPhrase = game._cues.filter((c) => c.phrase === 0);
|
||||
|
||||
Reference in New Issue
Block a user