Expand southern campaign release QA

This commit is contained in:
2026-07-06 17:14:19 +09:00
parent 84b16c834b
commit d9e2ad7ee6
2 changed files with 160 additions and 13 deletions

View File

@@ -33,8 +33,8 @@
"verify:public-deploy": "node scripts/verify-public-deploy.mjs",
"qa:representative": "node scripts/qa-representative-battles.mjs",
"qa:smoke": "node scripts/qa-representative-battles.mjs --set=smoke",
"qa:early": "node scripts/qa-representative-battles.mjs --set=campaign --battles=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20",
"qa:early:repeat": "node scripts/qa-repeat.mjs --set=campaign --battles=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20",
"qa:early": "node scripts/qa-representative-battles.mjs --set=campaign --battles=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27",
"qa:early:repeat": "node scripts/qa-repeat.mjs --set=campaign --battles=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27",
"deploy:nas": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy-nas.ps1 -Build",
"deploy:nas:dist": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy-nas.ps1",
"ship:release": "node scripts/ship-release.mjs"

View File

@@ -75,6 +75,152 @@ const northernTenthSortie = ['zhuge-liang', 'jiang-wei', 'wang-ping', 'huang-qua
const northernEleventhSortie = ['zhuge-liang', 'jiang-wei', 'ma-dai', 'wang-ping', 'huang-quan', 'li-yan', 'wei-yan'];
const northernFinalSortie = ['zhuge-liang', 'jiang-wei', 'wang-ping', 'ma-dai', 'huang-quan', 'li-yan', 'wei-yan'];
const redCliffVanguardTargets = [
'redcliff-vanguard-scout-a',
'redcliff-vanguard-scout-b',
'redcliff-vanguard-marine-a',
'redcliff-vanguard-marine-b',
'redcliff-vanguard-marine-c',
'redcliff-vanguard-marine-d',
'redcliff-vanguard-archer-a',
'redcliff-vanguard-archer-b',
'redcliff-vanguard-archer-c',
'redcliff-vanguard-cavalry-a',
'redcliff-vanguard-cavalry-b',
'redcliff-vanguard-cavalry-c',
'redcliff-vanguard-guard-a',
'redcliff-vanguard-guard-b',
'redcliff-vanguard-strategist-a',
'redcliff-vanguard-strategist-b',
'redcliff-vanguard-leader-cai-mao'
];
const redCliffFireTargets = [
'redcliff-fire-scout-a',
'redcliff-fire-scout-b',
'redcliff-fire-marine-a',
'redcliff-fire-marine-b',
'redcliff-fire-marine-c',
'redcliff-fire-marine-d',
'redcliff-fire-archer-a',
'redcliff-fire-archer-b',
'redcliff-fire-archer-c',
'redcliff-fire-archer-d',
'redcliff-fire-cavalry-a',
'redcliff-fire-cavalry-b',
'redcliff-fire-cavalry-c',
'redcliff-fire-guard-a',
'redcliff-fire-guard-b',
'redcliff-fire-strategist-a',
'redcliff-fire-strategist-b',
'redcliff-fire-leader-cao-cao'
];
const jingSouthTargets = [
'jing-south-scout-a',
'jing-south-scout-b',
'jing-south-infantry-a',
'jing-south-infantry-b',
'jing-south-infantry-c',
'jing-south-infantry-d',
'jing-south-archer-a',
'jing-south-archer-b',
'jing-south-archer-c',
'jing-south-cavalry-a',
'jing-south-cavalry-b',
'jing-south-cavalry-c',
'jing-south-guard-a',
'jing-south-guard-b',
'jing-south-strategist-a',
'jing-south-strategist-b',
'jing-south-leader-xing-daorong'
];
const guiyangTargets = [
'guiyang-scout-a',
'guiyang-scout-b',
'guiyang-infantry-a',
'guiyang-infantry-b',
'guiyang-infantry-c',
'guiyang-infantry-d',
'guiyang-archer-a',
'guiyang-archer-b',
'guiyang-archer-c',
'guiyang-cavalry-a',
'guiyang-cavalry-b',
'guiyang-cavalry-c',
'guiyang-guard-a',
'guiyang-guard-b',
'guiyang-strategist-a',
'guiyang-strategist-b',
'guiyang-leader-zhao-fan'
];
const wulingTargets = [
'wuling-scout-a',
'wuling-scout-b',
'wuling-scout-c',
'wuling-bandit-a',
'wuling-bandit-b',
'wuling-bandit-c',
'wuling-infantry-a',
'wuling-infantry-b',
'wuling-infantry-c',
'wuling-infantry-d',
'wuling-archer-a',
'wuling-archer-b',
'wuling-archer-c',
'wuling-cavalry-a',
'wuling-cavalry-b',
'wuling-guard-a',
'wuling-guard-b',
'wuling-strategist-a',
'wuling-leader-jin-xuan'
];
const changshaTargets = [
'changsha-scout-a',
'changsha-scout-b',
'changsha-infantry-a',
'changsha-infantry-b',
'changsha-infantry-c',
'changsha-infantry-d',
'changsha-archer-a',
'changsha-archer-b',
'changsha-archer-c',
'changsha-cavalry-a',
'changsha-cavalry-b',
'changsha-guard-a',
'changsha-guard-b',
'changsha-strategist-a',
'changsha-strategist-b',
'changsha-veteran-huang-zhong',
'changsha-officer-wei-yan',
'changsha-leader-han-xuan'
];
const yizhouTargets = [
'yizhou-scout-a',
'yizhou-scout-b',
'yizhou-infantry-a',
'yizhou-infantry-b',
'yizhou-infantry-c',
'yizhou-infantry-d',
'yizhou-archer-a',
'yizhou-archer-b',
'yizhou-archer-c',
'yizhou-cavalry-a',
'yizhou-cavalry-b',
'yizhou-cavalry-c',
'yizhou-guard-a',
'yizhou-guard-b',
'yizhou-strategist-a',
'yizhou-strategist-b',
'yizhou-ambusher-a',
'yizhou-ambusher-b',
'yizhou-leader-yang-huai'
];
const earlyCampaignBattles = [
{ no: 1, id: 'first-battle-zhuo-commandery', selected: [], targets: ['rebel-archer-b', 'rebel-leader'], protected: ['liu-bei'] },
{
@@ -371,49 +517,49 @@ const southernCampaignBattles = [
no: 21,
id: 'twenty-first-battle-red-cliffs-vanguard',
selected: redCliffVanguardSortie,
targets: ['redcliff-vanguard-leader-cai-mao'],
targets: redCliffVanguardTargets,
protected: ['liu-bei', 'zhuge-liang']
},
{
no: 22,
id: 'twenty-second-battle-red-cliffs-fire',
selected: redCliffFireSortie,
targets: ['redcliff-fire-leader-cao-cao'],
targets: redCliffFireTargets,
protected: ['liu-bei', 'zhuge-liang']
},
{
no: 23,
id: 'twenty-third-battle-jingzhou-south-entry',
selected: jingSouthSortie,
targets: ['jing-south-leader-xing-daorong'],
targets: jingSouthTargets,
protected: ['liu-bei', 'zhuge-liang']
},
{
no: 24,
id: 'twenty-fourth-battle-guiyang-persuasion',
selected: guiyangSortie,
targets: ['guiyang-leader-zhao-fan'],
targets: guiyangTargets,
protected: ['liu-bei', 'zhuge-liang', 'ma-liang']
},
{
no: 25,
id: 'twenty-fifth-battle-wuling-mountain-road',
selected: wulingSortie,
targets: ['wuling-leader-jin-xuan'],
targets: wulingTargets,
protected: ['liu-bei', 'zhuge-liang', 'ma-liang']
},
{
no: 26,
id: 'twenty-sixth-battle-changsha-veteran',
selected: changshaSortie,
targets: ['changsha-leader-han-xuan'],
targets: changshaTargets,
protected: ['liu-bei', 'zhuge-liang']
},
{
no: 27,
id: 'twenty-seventh-battle-yizhou-relief-road',
selected: yizhouReliefSortie,
targets: ['yizhou-leader-yang-huai'],
targets: yizhouTargets,
protected: ['liu-bei', 'zhuge-liang']
},
{
@@ -1535,7 +1681,7 @@ async function playBattleWithoutDebugVictory(page, battle) {
}
function protectedAnchorTile(unit, tiles, pressProtected) {
if (!protectedIds.has(unit.id) || pressProtected || liveUnits('enemy').length <= 4) {
if (!protectedIds.has(unit.id) || pressProtected || isLastProtectedFighter(unit) || liveUnits('enemy').length <= 4) {
return undefined;
}
@@ -1582,7 +1728,7 @@ async function playBattleWithoutDebugVictory(page, battle) {
function advancePointTile(unit, tiles) {
const point = scenarioAdvancePoint(unit);
if (!point || protectedIds.has(unit.id)) {
if (!point || (protectedIds.has(unit.id) && !isLastProtectedFighter(unit))) {
return undefined;
}
const currentDistance = distance(unit, point);
@@ -1595,6 +1741,7 @@ async function playBattleWithoutDebugVictory(page, battle) {
function chooseMove(unit) {
const tiles = [{ x: unit.x, y: unit.y, cost: 0 }, ...scene.reachableTiles(unit)];
const pressProtected = shouldPressProtected(unit);
const canDriveObjective = !protectedIds.has(unit.id) || pressProtected || isLastProtectedFighter(unit);
const anchorTile = protectedAnchorTile(unit, tiles, pressProtected);
if (anchorTile) {
return anchorTile;
@@ -1638,7 +1785,7 @@ async function playBattleWithoutDebugVictory(page, battle) {
return scenarioTile;
}
if (!protectedIds.has(unit.id) || pressProtected) {
if (canDriveObjective) {
const focus = focusTarget(unit);
if (focus) {
const currentDistance = distance(unit, focus);
@@ -1661,7 +1808,7 @@ async function playBattleWithoutDebugVictory(page, battle) {
}
const objective = currentSecureObjective();
if (objective && (!protectedIds.has(unit.id) || pressProtected)) {
if (objective && canDriveObjective) {
const currentObjectiveDistance = objectiveDistance(unit, objective);
const objectivePressureTile = tiles
.filter((tile) => tile.x !== unit.x || tile.y !== unit.y)