Add Bowang ambush sortie chapter
This commit is contained in:
@@ -1735,15 +1735,139 @@ try {
|
||||
const progressTabState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
|
||||
if (
|
||||
progressTabState?.activeTab !== 'progress' ||
|
||||
progressTabState.campaignProgress?.completedKnown !== progressTabState.campaignProgress?.totalKnown ||
|
||||
progressTabState.campaignProgress?.completedKnown !== 17 ||
|
||||
progressTabState.campaignProgress?.totalKnown !== 18 ||
|
||||
progressTabState.campaignProgress?.activeChapter?.title !== '적벽대전' ||
|
||||
progressTabState.campaignProgress?.latestBattleTitle !== '융중 방문로' ||
|
||||
progressTabState.campaignProgress?.nextBattleTitle !== '준비 중'
|
||||
progressTabState.campaignProgress?.nextBattleTitle !== '박망파 매복전'
|
||||
) {
|
||||
throw new Error(`Expected progress tab to summarize completed known campaign and point toward Red Cliffs: ${JSON.stringify(progressTabState?.campaignProgress)}`);
|
||||
throw new Error(`Expected progress tab to summarize Wolong completion and point toward Bowang ambush: ${JSON.stringify(progressTabState?.campaignProgress)}`);
|
||||
}
|
||||
await page.screenshot({ path: 'dist/verification-campaign-progress.png', fullPage: true });
|
||||
|
||||
await page.mouse.click(1120, 38);
|
||||
await page.waitForTimeout(160);
|
||||
const seventeenthCampBowangSortieState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
|
||||
if (
|
||||
!seventeenthCampBowangSortieState?.sortieVisible ||
|
||||
!seventeenthCampBowangSortieState.sortiePlan?.objectiveLine?.includes('박망파 매복전') ||
|
||||
!seventeenthCampBowangSortieState.sortieRoster?.some((unit) => unit.id === 'zhuge-liang' && unit.recruited && unit.recommended) ||
|
||||
seventeenthCampBowangSortieState.sortieRoster?.length < 8 ||
|
||||
seventeenthCampBowangSortieState.sortiePlan?.maxCount !== 6
|
||||
) {
|
||||
throw new Error(`Expected seventeenth camp sortie prep to target Bowang ambush with Zhuge Liang as a selectable recruit: ${JSON.stringify(seventeenthCampBowangSortieState)}`);
|
||||
}
|
||||
assertSortieTacticalRoster(seventeenthCampBowangSortieState, [
|
||||
'liu-bei',
|
||||
'guan-yu',
|
||||
'zhang-fei',
|
||||
'jian-yong',
|
||||
'mi-zhu',
|
||||
'sun-qian',
|
||||
'zhao-yun',
|
||||
'zhuge-liang'
|
||||
]);
|
||||
if (!seventeenthCampBowangSortieState.sortieRoster?.some((unit) => unit.id === 'zhuge-liang' && unit.selected)) {
|
||||
const selectedReserveCandidate = ['jian-yong', 'mi-zhu'].find((unitId) =>
|
||||
seventeenthCampBowangSortieState.sortieRoster?.some((unit) => unit.id === unitId && unit.selected)
|
||||
);
|
||||
if (selectedReserveCandidate) {
|
||||
await clickSortieRosterUnit(page, selectedReserveCandidate);
|
||||
}
|
||||
await clickSortieRosterUnit(page, 'zhuge-liang');
|
||||
}
|
||||
const bowangSortieWithZhugeState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
|
||||
if (
|
||||
!bowangSortieWithZhugeState.sortieRoster?.some((unit) => unit.id === 'zhuge-liang' && unit.selected) ||
|
||||
bowangSortieWithZhugeState.sortiePlan?.selectedCount !== 6 ||
|
||||
bowangSortieWithZhugeState.sortiePlan?.recommendedSelectedCount < 4
|
||||
) {
|
||||
throw new Error(`Expected Zhuge Liang to be selectable and deployed for Bowang ambush: ${JSON.stringify(bowangSortieWithZhugeState)}`);
|
||||
}
|
||||
await page.screenshot({ path: 'dist/verification-bowang-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-bowang-story.png', fullPage: true });
|
||||
|
||||
for (let i = 0; i < 26; i += 1) {
|
||||
const enteredEighteenthBattle = await page.evaluate(() => {
|
||||
const state = window.__HEROS_DEBUG__?.battle();
|
||||
return state?.scene === 'BattleScene' && state?.battleId === 'eighteenth-battle-bowang-ambush';
|
||||
});
|
||||
if (enteredEighteenthBattle) {
|
||||
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 === 'eighteenth-battle-bowang-ambush' && state?.battleOutcome === null && state?.phase === 'idle';
|
||||
});
|
||||
await page.screenshot({ path: 'dist/verification-eighteenth-battle.png', fullPage: true });
|
||||
|
||||
const eighteenthBattleState = await page.evaluate(() => window.__HEROS_DEBUG__?.battle());
|
||||
const eighteenthEnemies = eighteenthBattleState.units.filter((unit) => unit.faction === 'enemy');
|
||||
const eighteenthAllies = eighteenthBattleState.units.filter((unit) => unit.faction === 'ally');
|
||||
const eighteenthEnemyBehaviors = new Set(eighteenthEnemies.map((unit) => unit.ai));
|
||||
if (
|
||||
eighteenthBattleState.camera?.mapWidth !== 36 ||
|
||||
eighteenthBattleState.camera?.mapHeight !== 26 ||
|
||||
eighteenthBattleState.victoryConditionLabel !== '하후돈 퇴각' ||
|
||||
eighteenthEnemies.length < 16 ||
|
||||
!eighteenthEnemyBehaviors.has('aggressive') ||
|
||||
!eighteenthEnemyBehaviors.has('guard') ||
|
||||
!eighteenthEnemyBehaviors.has('hold') ||
|
||||
!eighteenthEnemies.some((unit) => unit.id === 'bowang-leader-xiahou-dun') ||
|
||||
!eighteenthAllies.some((unit) => unit.id === 'zhuge-liang')
|
||||
) {
|
||||
throw new Error(`Expected eighteenth battle to use Bowang map, Xiahou Dun objective, mixed AI, and deployed Zhuge Liang: ${JSON.stringify(eighteenthBattleState)}`);
|
||||
}
|
||||
|
||||
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 eighteenthCampState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
|
||||
if (
|
||||
eighteenthCampState?.campBattleId !== 'eighteenth-battle-bowang-ambush' ||
|
||||
eighteenthCampState.campTitle !== '박망파 승전 후 군영' ||
|
||||
eighteenthCampState.availableDialogueIds?.length !== 3 ||
|
||||
!eighteenthCampState.availableDialogueIds.every((id) => id.endsWith('bowang-ambush')) ||
|
||||
eighteenthCampState.availableVisitIds?.length !== 2 ||
|
||||
!eighteenthCampState.report?.bonds?.some((bond) => bond.id === 'zhang-fei__zhuge-liang') ||
|
||||
!eighteenthCampState.report?.bonds?.some((bond) => bond.id === 'sun-qian__zhuge-liang')
|
||||
) {
|
||||
throw new Error(`Expected eighteenth camp to expose Bowang dialogue/visit sets and Zhuge bond expansion: ${JSON.stringify(eighteenthCampState)}`);
|
||||
}
|
||||
await page.screenshot({ path: 'dist/verification-bowang-camp.png', fullPage: true });
|
||||
|
||||
await page.mouse.click(966, 38);
|
||||
await page.waitForTimeout(180);
|
||||
const postBowangProgressState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
|
||||
if (
|
||||
postBowangProgressState?.activeTab !== 'progress' ||
|
||||
postBowangProgressState.campaignProgress?.completedKnown !== postBowangProgressState.campaignProgress?.totalKnown ||
|
||||
postBowangProgressState.campaignProgress?.activeChapter?.title !== '적벽대전' ||
|
||||
postBowangProgressState.campaignProgress?.latestBattleTitle !== '박망파 매복전' ||
|
||||
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)}`);
|
||||
}
|
||||
await page.screenshot({ path: 'dist/verification-post-bowang-progress.png', fullPage: true });
|
||||
|
||||
await page.evaluate(() => window.__HEROS_GAME__?.scene.start('TitleScene'));
|
||||
await page.waitForFunction(() => {
|
||||
const activeScenes = window.__HEROS_DEBUG__?.activeScenes() ?? [];
|
||||
@@ -1755,7 +1879,7 @@ try {
|
||||
return activeScenes.includes('CampScene');
|
||||
});
|
||||
|
||||
console.log(`Verified title-to-seventeenth-battle flow, recruit sortie selection, result states, and debug API at ${targetUrl}`);
|
||||
console.log(`Verified title-to-eighteenth-battle flow, recruit sortie selection, result states, and debug API at ${targetUrl}`);
|
||||
} finally {
|
||||
await browser?.close();
|
||||
if (serverProcess && !serverProcess.killed) {
|
||||
@@ -1871,7 +1995,7 @@ async function clickSortieRosterUnit(page, unitId) {
|
||||
throw new Error(`Cannot click sortie unit ${unitId}; unit is missing from roster: ${JSON.stringify(state.sortieRoster)}`);
|
||||
}
|
||||
|
||||
const rowGap = state.sortieRoster.length > 5 ? 38 : state.sortieRoster.length > 4 ? 43 : 48;
|
||||
const rowGap = state.sortieRoster.length > 7 ? 30 : state.sortieRoster.length > 5 ? 38 : state.sortieRoster.length > 4 ? 43 : 48;
|
||||
await page.mouse.click(254, 314 + 50 + index * rowGap);
|
||||
await page.waitForTimeout(120);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user