Add Changban refuge sortie chapter

This commit is contained in:
2026-06-23 06:33:37 +09:00
parent 2d4b08558d
commit 697ce8837d
11 changed files with 1047 additions and 23 deletions

View File

@@ -1736,7 +1736,7 @@ try {
if (
progressTabState?.activeTab !== 'progress' ||
progressTabState.campaignProgress?.completedKnown !== 17 ||
progressTabState.campaignProgress?.totalKnown !== 18 ||
progressTabState.campaignProgress?.totalKnown !== 19 ||
progressTabState.campaignProgress?.activeChapter?.title !== '적벽대전' ||
progressTabState.campaignProgress?.latestBattleTitle !== '융중 방문로' ||
progressTabState.campaignProgress?.nextBattleTitle !== '박망파 매복전'
@@ -1887,15 +1887,153 @@ try {
const postBowangProgressState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
if (
postBowangProgressState?.activeTab !== 'progress' ||
postBowangProgressState.campaignProgress?.completedKnown !== postBowangProgressState.campaignProgress?.totalKnown ||
postBowangProgressState.campaignProgress?.completedKnown !== 18 ||
postBowangProgressState.campaignProgress?.totalKnown !== 19 ||
postBowangProgressState.campaignProgress?.activeChapter?.title !== '적벽대전' ||
postBowangProgressState.campaignProgress?.latestBattleTitle !== '박망파 매복전' ||
postBowangProgressState.campaignProgress?.nextBattleTitle !== '준비 중'
postBowangProgressState.campaignProgress?.nextBattleTitle !== '장판파 피난로'
) {
throw new Error(`Expected post-Bowang progress tab to keep Red Cliffs active while next scenario is pending: ${JSON.stringify(postBowangProgressState?.campaignProgress)}`);
throw new Error(`Expected post-Bowang progress tab to point toward Changban refuge route: ${JSON.stringify(postBowangProgressState?.campaignProgress)}`);
}
await page.screenshot({ path: 'dist/verification-post-bowang-progress.png', fullPage: true });
await page.mouse.click(1120, 38);
await page.waitForTimeout(180);
const changbanSortieState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
if (
!changbanSortieState?.sortieVisible ||
!changbanSortieState.sortiePlan?.objectiveLine?.includes('장판파 피난로') ||
!changbanSortieState.sortieRoster?.some((unit) => unit.id === 'zhao-yun' && unit.recruited && unit.recommended) ||
!changbanSortieState.sortieRoster?.some((unit) => unit.id === 'zhang-fei' && unit.recommended) ||
!changbanSortieState.sortieRoster?.some((unit) => unit.id === 'zhuge-liang' && unit.recruited && unit.recommended) ||
changbanSortieState.sortieRoster?.length < 8 ||
changbanSortieState.sortiePlan?.maxCount !== 6
) {
throw new Error(`Expected eighteenth camp sortie prep to target Changban with Zhao Yun, Zhang Fei, and Zhuge Liang recommendations: ${JSON.stringify(changbanSortieState)}`);
}
assertSortieTacticalRoster(changbanSortieState, [
'liu-bei',
'guan-yu',
'zhang-fei',
'jian-yong',
'mi-zhu',
'sun-qian',
'zhao-yun',
'zhuge-liang'
]);
const changbanPriorityUnits = ['zhao-yun', 'zhang-fei', 'zhuge-liang'];
for (const unitId of changbanPriorityUnits) {
const currentSortieState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
if (!currentSortieState.sortieRoster?.some((unit) => unit.id === unitId && unit.selected)) {
const removable = currentSortieState.sortieRoster?.find(
(unit) => unit.selected && unit.id !== 'liu-bei' && !changbanPriorityUnits.includes(unit.id)
);
if (removable) {
await clickSortieRosterUnit(page, removable.id);
}
await clickSortieRosterUnit(page, unitId);
}
}
const changbanSortieReadyState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
if (
!changbanPriorityUnits.every((unitId) =>
changbanSortieReadyState.sortieRoster?.some((unit) => unit.id === unitId && unit.selected)
) ||
changbanSortieReadyState.sortiePlan?.selectedCount !== 6 ||
changbanSortieReadyState.sortiePlan?.recommendedSelectedCount < 5
) {
throw new Error(`Expected Changban sortie to deploy priority officers and preserve six-officer choice pressure: ${JSON.stringify(changbanSortieReadyState)}`);
}
await page.screenshot({ path: 'dist/verification-changban-sortie.png', fullPage: true });
await page.mouse.click(1068, 646);
await page.waitForFunction(() => {
const activeScenes = window.__HEROS_DEBUG__?.activeScenes() ?? [];
return activeScenes.includes('StoryScene');
});
await page.screenshot({ path: 'dist/verification-changban-story.png', fullPage: true });
for (let i = 0; i < 30; i += 1) {
const enteredNineteenthBattle = await page.evaluate(() => {
const state = window.__HEROS_DEBUG__?.battle();
return state?.scene === 'BattleScene' && state?.battleId === 'nineteenth-battle-changban-refuge';
});
if (enteredNineteenthBattle) {
break;
}
await page.keyboard.press('Space');
await page.waitForTimeout(320);
}
await page.waitForFunction(() => {
const state = window.__HEROS_DEBUG__?.battle();
return state?.scene === 'BattleScene' && state?.battleId === 'nineteenth-battle-changban-refuge' && state?.battleOutcome === null && state?.phase === 'idle';
});
await page.screenshot({ path: 'dist/verification-nineteenth-battle.png', fullPage: true });
const nineteenthBattleState = await page.evaluate(() => window.__HEROS_DEBUG__?.battle());
const nineteenthEnemies = nineteenthBattleState.units.filter((unit) => unit.faction === 'enemy');
const nineteenthAllies = nineteenthBattleState.units.filter((unit) => unit.faction === 'ally');
const nineteenthEnemyBehaviors = new Set(nineteenthEnemies.map((unit) => unit.ai));
if (
nineteenthBattleState.camera?.mapWidth !== 38 ||
nineteenthBattleState.camera?.mapHeight !== 28 ||
nineteenthBattleState.victoryConditionLabel !== '조순 퇴각' ||
nineteenthEnemies.length < 17 ||
!nineteenthEnemyBehaviors.has('aggressive') ||
!nineteenthEnemyBehaviors.has('guard') ||
!nineteenthEnemyBehaviors.has('hold') ||
!nineteenthEnemies.some((unit) => unit.id === 'changban-leader-cao-chun') ||
!nineteenthAllies.some((unit) => unit.id === 'zhao-yun') ||
!nineteenthAllies.some((unit) => unit.id === 'zhuge-liang')
) {
throw new Error(`Expected nineteenth battle to use Changban map, Cao Chun objective, mixed AI, Zhao Yun, and Zhuge Liang: ${JSON.stringify(nineteenthBattleState)}`);
}
await page.evaluate(() => window.__HEROS_DEBUG__?.forceBattleOutcome('victory'));
await page.waitForFunction(() => {
const state = window.__HEROS_DEBUG__?.battle();
return state?.battleOutcome === 'victory' && state?.phase === 'resolved' && state?.resultVisible === true;
});
await page.mouse.click(738, 642);
await page.waitForFunction(() => {
const activeScenes = window.__HEROS_DEBUG__?.activeScenes() ?? [];
return activeScenes.includes('CampScene');
});
const nineteenthCampState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
if (
nineteenthCampState?.campBattleId !== 'nineteenth-battle-changban-refuge' ||
nineteenthCampState.campTitle !== '장판파 돌파 후 군영' ||
nineteenthCampState.availableDialogueIds?.length !== 3 ||
!nineteenthCampState.availableDialogueIds.every((id) => id.endsWith('changban-refuge')) ||
nineteenthCampState.availableVisitIds?.length !== 2 ||
!nineteenthCampState.report?.bonds?.some((bond) => bond.id === 'liu-bei__zhao-yun') ||
!nineteenthCampState.report?.bonds?.some((bond) => bond.id === 'zhang-fei__zhuge-liang') ||
nineteenthCampState.rosterCollection?.total < 8 ||
nineteenthCampState.rosterCollection?.reserveTrainingCount < 2 ||
nineteenthCampState.rosterCollection?.reserveTrainingExp < 12
) {
throw new Error(`Expected nineteenth camp to expose Changban dialogue/visit sets, Zhao Yun bonds, and reserve growth: ${JSON.stringify(nineteenthCampState)}`);
}
await page.screenshot({ path: 'dist/verification-changban-camp.png', fullPage: true });
await page.mouse.click(966, 38);
await page.waitForTimeout(180);
const postChangbanProgressState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
if (
postChangbanProgressState?.activeTab !== 'progress' ||
postChangbanProgressState.campaignProgress?.completedKnown !== postChangbanProgressState.campaignProgress?.totalKnown ||
postChangbanProgressState.campaignProgress?.activeChapter?.title !== '적벽대전' ||
postChangbanProgressState.campaignProgress?.latestBattleTitle !== '장판파 피난로' ||
postChangbanProgressState.campaignProgress?.nextBattleTitle !== '준비 중'
) {
throw new Error(`Expected post-Changban progress tab to keep Red Cliffs active while Jiangdong envoy is pending: ${JSON.stringify(postChangbanProgressState?.campaignProgress)}`);
}
await page.screenshot({ path: 'dist/verification-post-changban-progress.png', fullPage: true });
await page.evaluate(() => window.__HEROS_GAME__?.scene.start('TitleScene'));
await page.waitForFunction(() => {
const activeScenes = window.__HEROS_DEBUG__?.activeScenes() ?? [];
@@ -1907,7 +2045,7 @@ try {
return activeScenes.includes('CampScene');
});
console.log(`Verified title-to-eighteenth-battle flow, recruit sortie selection, result states, and debug API at ${targetUrl}`);
console.log(`Verified title-to-nineteenth-battle flow, recruit sortie selection, result states, and debug API at ${targetUrl}`);
} finally {
await browser?.close();
if (serverProcess && !serverProcess.killed) {