Enhance sortie formation planning

This commit is contained in:
2026-06-23 02:33:34 +09:00
parent 683357f6a7
commit 041f798475
3 changed files with 271 additions and 23 deletions

View File

@@ -757,7 +757,7 @@ try {
}
assertSortieTacticalRoster(sixthCampSortieState, ['liu-bei', 'guan-yu', 'zhang-fei']);
await page.mouse.click(254, 450);
await clickSortieRosterUnit(page, 'guan-yu');
await page.waitForTimeout(220);
const sixthCampAfterSortieToggle = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
if (
@@ -858,7 +858,7 @@ try {
if (!seventhCampSortieState?.sortieVisible) {
throw new Error(`Expected seventh camp story bridge overlay: ${JSON.stringify(seventhCampSortieState)}`);
}
await page.mouse.click(256, 492);
await clickSortieRosterUnit(page, 'jian-yong');
await page.waitForTimeout(120);
const seventhCampRecruitSortieState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
if (!seventhCampRecruitSortieState.selectedSortieUnitIds?.includes('jian-yong')) {
@@ -940,7 +940,7 @@ try {
throw new Error(`Expected eighth camp sortie prep overlay: ${JSON.stringify(eighthCampSortieState)}`);
}
if (!eighthCampSortieState.selectedSortieUnitIds?.includes('mi-zhu')) {
await page.mouse.click(256, 516);
await clickSortieRosterUnit(page, 'mi-zhu');
await page.waitForTimeout(120);
}
const eighthCampMiZhuSortieState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
@@ -1024,7 +1024,7 @@ try {
throw new Error(`Expected ninth camp sortie prep overlay: ${JSON.stringify(ninthCampSortieState)}`);
}
if (!ninthCampSortieState.selectedSortieUnitIds?.includes('guan-yu')) {
await page.mouse.click(256, 420);
await clickSortieRosterUnit(page, 'guan-yu');
await page.waitForTimeout(120);
}
const ninthCampGuanYuSortieState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
@@ -1256,6 +1256,7 @@ function assertSortieTacticalRoster(state, requiredUnitIds) {
const invalidUnits = state.sortieRoster.filter((unit) => {
return (
!unit.classRole ||
!unit.formationRole ||
!unit.statLine?.includes('무 ') ||
!unit.statLine?.includes('지 ') ||
!unit.equipmentLine?.includes('Lv') ||
@@ -1272,4 +1273,32 @@ function assertSortieTacticalRoster(state, requiredUnitIds) {
if (!liuBei?.equipmentLine?.includes('자웅일대검')) {
throw new Error(`Expected Liu Bei sortie row to expose named treasure weapon: ${JSON.stringify(liuBei)}`);
}
if (
!state.sortiePlan ||
!state.sortiePlan.deploymentLine?.includes('전열') ||
!state.sortiePlan.objectiveLine ||
!Array.isArray(state.sortiePlan.formationSlots) ||
state.sortiePlan.formationSlots.length < 3 ||
typeof state.sortiePlan.activeBondCount !== 'number' ||
typeof state.sortiePlan.terrainScore !== 'number'
) {
throw new Error(`Expected sortie preparation to expose deployment plan, bond count, and terrain score: ${JSON.stringify(state.sortiePlan)}`);
}
}
async function clickSortieRosterUnit(page, unitId) {
const state = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
if (!state?.sortieVisible || !Array.isArray(state.sortieRoster)) {
throw new Error(`Cannot click sortie unit ${unitId}; sortie roster is not visible: ${JSON.stringify(state)}`);
}
const index = state.sortieRoster.findIndex((unit) => unit.id === unitId);
if (index < 0) {
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;
await page.mouse.click(254, 314 + 50 + index * rowGap);
await page.waitForTimeout(120);
}