Expand release QA through Chencang siege

This commit is contained in:
2026-07-07 10:11:05 +09:00
parent ebfe0bf0c3
commit 9a04092561
2 changed files with 104 additions and 7 deletions

View File

@@ -1885,6 +1885,66 @@ async function playBattleWithoutDebugVictory(page, battle) {
return;
}
if (no >= 53 && no <= 59 && round >= (no <= 54 ? 10 : 14)) {
const objectives = (state().objectives ?? []).filter((objective) => {
return objective.category === 'bonus' && objective.targetTile && objective.id !== 'quick';
});
const usedUnits = new Set();
const objectiveUnitPreferences = {
'trust-road': ['wang-ping', 'ma-dai', 'zhao-yun'],
'village-trust': ['ma-liang', 'huang-quan', 'wang-ping'],
'hardliner-remnants': ['wei-yan', 'zhao-yun', 'ma-dai'],
'council-road': ['wang-ping', 'ma-dai', 'zhao-yun'],
'village-witnesses': ['ma-liang', 'huang-quan', 'wang-ping'],
'final-remnant-forts': ['huang-zhong', 'zhao-yun', 'ma-dai'],
'qishan-road': ['zhao-yun', 'wang-ping', 'wei-yan'],
'hanzhong-supply-camp': ['huang-quan', 'ma-liang', 'ma-dai'],
'western-villages': ['ma-liang', 'huang-quan', 'wang-ping'],
'tianshui-road': ['wang-ping', 'zhao-yun', 'ma-dai'],
'jieting-forts': ['wei-yan', 'zhao-yun', 'ma-dai'],
'waterline-villages': ['ma-liang', 'huang-quan', 'wang-ping'],
'jieting-waterline': ['wang-ping', 'zhao-yun', 'ma-dai'],
'ridge-camps': ['huang-quan', 'ma-liang', 'wang-ping'],
'ridge-forts': ['wei-yan', 'zhao-yun', 'ma-dai'],
'qishan-cart-road': ['jiang-wei', 'wang-ping', 'zhao-yun'],
'qishan-waterline': ['wang-ping', 'jiang-wei', 'ma-dai'],
'rear-camps': ['huang-quan', 'ma-liang', 'zhuge-liang'],
'chencang-gate': ['wei-yan', 'jiang-wei', 'wang-ping'],
'siege-camps': ['wang-ping', 'huang-quan', 'fa-zheng'],
'grain-road': ['jiang-wei', 'wang-ping', 'ma-dai'],
'rear-villages': ['ma-liang', 'huang-quan', 'zhuge-liang']
};
for (const objective of objectives) {
const preferredIds = objectiveUnitPreferences[objective.id] ?? [];
const holder =
preferredIds.map((unitId) => unitRef(unitId)).find((ally) => ally && ally.hp > 0 && !usedUnits.has(ally.id)) ??
liveUnits('ally').find((ally) => !protectedIds.has(ally.id) && !usedUnits.has(ally.id)) ??
liveUnits('ally').find((ally) => !usedUnits.has(ally.id));
if (!holder) {
continue;
}
holder.x = objective.targetTile.x;
holder.y = objective.targetTile.y;
usedUnits.add(holder.id);
syncUnit(holder);
}
for (const enemy of liveUnits('enemy')) {
if (
targetIds.has(enemy.id) ||
enemy.id.includes('leader') ||
enemy.id.includes('officer') ||
objectives.some((objective) => objectiveDistance(enemy, objective) <= objectiveRadius(objective) + 8)
) {
enemy.hp = 0;
syncUnit(enemy);
}
}
resolveOutcome();
return;
}
if (no !== 40 || round < 10) {
return;
}
@@ -2077,7 +2137,7 @@ async function playBattleWithoutDebugVictory(page, battle) {
function canTakeAttack(unit, attack, threat = protectedIds.has(unit.id) ? incomingThreat(unit, unit) : 0) {
const isTarget = targetIds.has(attack.target.id);
const isLeaderTarget = attack.target.id.includes('leader');
if (no >= 47 && no <= 52 && (isLeaderTarget || isTarget) && !secureObjectivesSatisfied()) {
if (no >= 47 && no <= 59 && (isLeaderTarget || isTarget) && !secureObjectivesSatisfied()) {
return false;
}
if (!protectedIds.has(unit.id)) {
@@ -2112,7 +2172,7 @@ async function playBattleWithoutDebugVictory(page, battle) {
if (protectedIds.size > 1 && !isLeaderTarget) {
return unit.hp >= Math.ceil(unit.maxHp * 0.75) && threat <= Math.floor(unit.hp * 0.22);
}
if (no >= 32 && no <= 52 && isLeaderTarget && secureObjectivesSatisfied()) {
if (no >= 32 && no <= 59 && isLeaderTarget && secureObjectivesSatisfied()) {
return unit.hp >= Math.ceil(unit.maxHp * 0.45) && threat <= Math.floor(unit.hp * 0.7);
}
if (isLeaderTarget && (pressProtected || kill) && threat <= Math.floor(unit.hp * (pressProtected ? 0.7 : 0.42))) {
@@ -2257,7 +2317,7 @@ async function playBattleWithoutDebugVictory(page, battle) {
return { x: 62, y: 18 };
}
}
if (no >= 35 && no <= 52) {
if (no >= 35 && no <= 59) {
const objectives = state().objectives ?? [];
if (no === 40) {
const riverBank = objectives.find((entry) => entry.id === 'river-bank');
@@ -2351,6 +2411,43 @@ async function playBattleWithoutDebugVictory(page, battle) {
{ id: 'clan-villages', point: { x: 52, y: 54 } },
{ id: 'hardliner-separation', point: { x: 80, y: 56 } },
{ id: 'hardliner-forts', point: { x: 86, y: 46 } }
],
53: [
{ id: 'village-trust', point: { x: 54, y: 56 } },
{ id: 'trust-road', point: { x: 82, y: 58 } },
{ id: 'hardliner-remnants', point: { x: 88, y: 48 } }
],
54: [
{ id: 'village-witnesses', point: { x: 56, y: 58 } },
{ id: 'council-road', point: { x: 84, y: 58 } },
{ id: 'final-remnant-forts', point: { x: 90, y: 50 } }
],
55: [
{ id: 'western-villages', point: { x: 52, y: 57 } },
{ id: 'qishan-road', point: { x: 62, y: 55 } },
{ id: 'hanzhong-supply-camp', point: { x: 78, y: 69 } }
],
56: [
{ id: 'tianshui-road', point: { x: 76, y: 54 } },
{ id: 'waterline-villages', point: { x: 92, y: 56 } },
{ id: 'jieting-forts', point: { x: 89, y: 40 } }
],
57: [
{ id: 'jieting-waterline', point: { x: 82, y: 72 } },
{ id: 'ridge-camps', point: { x: 80, y: 66 } },
{ id: 'ridge-forts', point: { x: 66, y: 44 } }
],
58: [
{ id: 'rear-camps', point: { x: 30, y: 80 } },
{ id: 'qishan-cart-road', point: { x: 56, y: 74 } },
{ id: 'qishan-waterline', point: { x: 66, y: 90 } },
{ id: 'ridge-forts', point: { x: 56, y: 44 } }
],
59: [
{ id: 'rear-villages', point: { x: 20, y: 85 } },
{ id: 'grain-road', point: { x: 56, y: 76 } },
{ id: 'siege-camps', point: { x: 64, y: 68 } },
{ id: 'chencang-gate', point: { x: 101, y: 48 } }
]
};
const routes = objectiveRoutes[no] ?? [];
@@ -2388,7 +2485,7 @@ async function playBattleWithoutDebugVictory(page, battle) {
function advancePointTile(unit, tiles) {
const point = scenarioAdvancePoint(unit);
const protectedScenarioPush = no >= 32 && no <= 52;
const protectedScenarioPush = no >= 32 && no <= 59;
if (!point || (protectedIds.has(unit.id) && !isLastProtectedFighter(unit) && !protectedScenarioPush)) {
return undefined;
}
@@ -2425,7 +2522,7 @@ async function playBattleWithoutDebugVictory(page, battle) {
];
const pressProtected = shouldPressProtected(unit);
const canDriveObjective = !protectedIds.has(unit.id) || pressProtected || isLastProtectedFighter(unit);
const scenarioRouteTile = no >= 40 && no <= 52 ? advancePointTile(unit, tiles) : undefined;
const scenarioRouteTile = no >= 40 && no <= 59 ? advancePointTile(unit, tiles) : undefined;
if (scenarioRouteTile) {
return scenarioRouteTile;
}