Expand Yizhou campaign release QA
This commit is contained in:
@@ -33,8 +33,8 @@
|
|||||||
"verify:public-deploy": "node scripts/verify-public-deploy.mjs",
|
"verify:public-deploy": "node scripts/verify-public-deploy.mjs",
|
||||||
"qa:representative": "node scripts/qa-representative-battles.mjs",
|
"qa:representative": "node scripts/qa-representative-battles.mjs",
|
||||||
"qa:smoke": "node scripts/qa-representative-battles.mjs --set=smoke",
|
"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,21,22,23,24,25,26,27",
|
"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,28,29,30,31,32,33",
|
||||||
"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",
|
"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,28,29,30,31,32,33",
|
||||||
"deploy:nas": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy-nas.ps1 -Build",
|
"deploy:nas": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy-nas.ps1 -Build",
|
||||||
"deploy:nas:dist": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy-nas.ps1",
|
"deploy:nas:dist": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy-nas.ps1",
|
||||||
"ship:release": "node scripts/ship-release.mjs"
|
"ship:release": "node scripts/ship-release.mjs"
|
||||||
|
|||||||
@@ -221,6 +221,164 @@ const yizhouTargets = [
|
|||||||
'yizhou-leader-yang-huai'
|
'yizhou-leader-yang-huai'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const fuPassTargets = [
|
||||||
|
'fupass-scout-a',
|
||||||
|
'fupass-scout-b',
|
||||||
|
'fupass-infantry-a',
|
||||||
|
'fupass-infantry-b',
|
||||||
|
'fupass-infantry-c',
|
||||||
|
'fupass-infantry-d',
|
||||||
|
'fupass-archer-a',
|
||||||
|
'fupass-archer-b',
|
||||||
|
'fupass-archer-c',
|
||||||
|
'fupass-cavalry-a',
|
||||||
|
'fupass-cavalry-b',
|
||||||
|
'fupass-cavalry-c',
|
||||||
|
'fupass-guard-a',
|
||||||
|
'fupass-guard-b',
|
||||||
|
'fupass-strategist-a',
|
||||||
|
'fupass-strategist-b',
|
||||||
|
'fupass-ambusher-a',
|
||||||
|
'fupass-ambusher-b',
|
||||||
|
'fupass-ambusher-c',
|
||||||
|
'fupass-leader-gao-pei'
|
||||||
|
];
|
||||||
|
|
||||||
|
const luoOuterTargets = [
|
||||||
|
'luo-scout-a',
|
||||||
|
'luo-scout-b',
|
||||||
|
'luo-infantry-a',
|
||||||
|
'luo-infantry-b',
|
||||||
|
'luo-infantry-c',
|
||||||
|
'luo-infantry-d',
|
||||||
|
'luo-archer-a',
|
||||||
|
'luo-archer-b',
|
||||||
|
'luo-archer-c',
|
||||||
|
'luo-cavalry-a',
|
||||||
|
'luo-cavalry-b',
|
||||||
|
'luo-cavalry-c',
|
||||||
|
'luo-guard-a',
|
||||||
|
'luo-guard-b',
|
||||||
|
'luo-strategist-a',
|
||||||
|
'luo-strategist-b',
|
||||||
|
'luo-ambusher-a',
|
||||||
|
'luo-ambusher-b',
|
||||||
|
'luo-officer-wu-yi',
|
||||||
|
'luo-leader-zhang-ren'
|
||||||
|
];
|
||||||
|
|
||||||
|
const luofengTargets = [
|
||||||
|
'luofeng-scout-a',
|
||||||
|
'luofeng-scout-b',
|
||||||
|
'luofeng-scout-c',
|
||||||
|
'luofeng-infantry-a',
|
||||||
|
'luofeng-infantry-b',
|
||||||
|
'luofeng-infantry-c',
|
||||||
|
'luofeng-infantry-d',
|
||||||
|
'luofeng-archer-a',
|
||||||
|
'luofeng-archer-b',
|
||||||
|
'luofeng-archer-c',
|
||||||
|
'luofeng-archer-d',
|
||||||
|
'luofeng-cavalry-a',
|
||||||
|
'luofeng-cavalry-b',
|
||||||
|
'luofeng-cavalry-c',
|
||||||
|
'luofeng-guard-a',
|
||||||
|
'luofeng-guard-b',
|
||||||
|
'luofeng-strategist-a',
|
||||||
|
'luofeng-strategist-b',
|
||||||
|
'luofeng-ambusher-a',
|
||||||
|
'luofeng-ambusher-b',
|
||||||
|
'luofeng-ambusher-c',
|
||||||
|
'luofeng-ambusher-d',
|
||||||
|
'luofeng-leader-zhang-ren'
|
||||||
|
];
|
||||||
|
|
||||||
|
const luoMainTargets = [
|
||||||
|
'luo-main-scout-a',
|
||||||
|
'luo-main-scout-b',
|
||||||
|
'luo-main-infantry-a',
|
||||||
|
'luo-main-infantry-b',
|
||||||
|
'luo-main-infantry-c',
|
||||||
|
'luo-main-infantry-d',
|
||||||
|
'luo-main-infantry-e',
|
||||||
|
'luo-main-archer-a',
|
||||||
|
'luo-main-archer-b',
|
||||||
|
'luo-main-archer-c',
|
||||||
|
'luo-main-archer-d',
|
||||||
|
'luo-main-cavalry-a',
|
||||||
|
'luo-main-cavalry-b',
|
||||||
|
'luo-main-cavalry-c',
|
||||||
|
'luo-main-guard-a',
|
||||||
|
'luo-main-guard-b',
|
||||||
|
'luo-main-guard-c',
|
||||||
|
'luo-main-strategist-a',
|
||||||
|
'luo-main-strategist-b',
|
||||||
|
'luo-main-ambusher-a',
|
||||||
|
'luo-main-ambusher-b',
|
||||||
|
'luo-main-ambusher-c',
|
||||||
|
'luo-main-veteran-yan-yan',
|
||||||
|
'luo-main-officer-a',
|
||||||
|
'luo-main-leader-zhang-ren'
|
||||||
|
];
|
||||||
|
|
||||||
|
const mianzhuTargets = [
|
||||||
|
'chengdu-scout-a',
|
||||||
|
'chengdu-scout-b',
|
||||||
|
'chengdu-scout-c',
|
||||||
|
'chengdu-infantry-a',
|
||||||
|
'chengdu-infantry-b',
|
||||||
|
'chengdu-infantry-c',
|
||||||
|
'chengdu-infantry-d',
|
||||||
|
'chengdu-infantry-e',
|
||||||
|
'chengdu-infantry-f',
|
||||||
|
'chengdu-archer-a',
|
||||||
|
'chengdu-archer-b',
|
||||||
|
'chengdu-archer-c',
|
||||||
|
'chengdu-archer-d',
|
||||||
|
'chengdu-cavalry-a',
|
||||||
|
'chengdu-cavalry-b',
|
||||||
|
'chengdu-cavalry-c',
|
||||||
|
'chengdu-guard-a',
|
||||||
|
'chengdu-guard-b',
|
||||||
|
'chengdu-guard-c',
|
||||||
|
'chengdu-strategist-a',
|
||||||
|
'chengdu-strategist-b',
|
||||||
|
'chengdu-ambusher-a',
|
||||||
|
'chengdu-ambusher-b',
|
||||||
|
'chengdu-ambusher-c',
|
||||||
|
'chengdu-officer-fei-guan',
|
||||||
|
'chengdu-leader-li-yan'
|
||||||
|
];
|
||||||
|
|
||||||
|
const chengduFinalTargets = [
|
||||||
|
'chengdu-final-scout-a',
|
||||||
|
'chengdu-final-scout-b',
|
||||||
|
'chengdu-final-scout-c',
|
||||||
|
'chengdu-final-infantry-a',
|
||||||
|
'chengdu-final-infantry-b',
|
||||||
|
'chengdu-final-infantry-c',
|
||||||
|
'chengdu-final-infantry-d',
|
||||||
|
'chengdu-final-infantry-e',
|
||||||
|
'chengdu-final-infantry-f',
|
||||||
|
'chengdu-final-archer-a',
|
||||||
|
'chengdu-final-archer-b',
|
||||||
|
'chengdu-final-archer-c',
|
||||||
|
'chengdu-final-archer-d',
|
||||||
|
'chengdu-final-cavalry-a',
|
||||||
|
'chengdu-final-cavalry-b',
|
||||||
|
'chengdu-final-cavalry-c',
|
||||||
|
'chengdu-final-guard-a',
|
||||||
|
'chengdu-final-guard-b',
|
||||||
|
'chengdu-final-guard-c',
|
||||||
|
'chengdu-final-strategist-a',
|
||||||
|
'chengdu-final-strategist-b',
|
||||||
|
'chengdu-final-ambusher-a',
|
||||||
|
'chengdu-final-ambusher-b',
|
||||||
|
'chengdu-final-ambusher-c',
|
||||||
|
'chengdu-final-officer-a',
|
||||||
|
'chengdu-final-leader-huang-quan'
|
||||||
|
];
|
||||||
|
|
||||||
const earlyCampaignBattles = [
|
const earlyCampaignBattles = [
|
||||||
{ no: 1, id: 'first-battle-zhuo-commandery', selected: [], targets: ['rebel-archer-b', 'rebel-leader'], protected: ['liu-bei'] },
|
{ no: 1, id: 'first-battle-zhuo-commandery', selected: [], targets: ['rebel-archer-b', 'rebel-leader'], protected: ['liu-bei'] },
|
||||||
{
|
{
|
||||||
@@ -566,14 +724,14 @@ const southernCampaignBattles = [
|
|||||||
no: 28,
|
no: 28,
|
||||||
id: 'twenty-eighth-battle-fu-pass-entry',
|
id: 'twenty-eighth-battle-fu-pass-entry',
|
||||||
selected: fuPassSortie,
|
selected: fuPassSortie,
|
||||||
targets: ['fupass-leader-gao-pei'],
|
targets: fuPassTargets,
|
||||||
protected: ['liu-bei', 'zhuge-liang']
|
protected: ['liu-bei', 'zhuge-liang']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
no: 29,
|
no: 29,
|
||||||
id: 'twenty-ninth-battle-luo-outer-wall',
|
id: 'twenty-ninth-battle-luo-outer-wall',
|
||||||
selected: luoOuterSortie,
|
selected: luoOuterSortie,
|
||||||
targets: ['luo-leader-zhang-ren', 'luo-archer-b', 'luo-officer-wu-yi', 'luo-strategist-a', 'luo-guard-a', 'luo-guard-b'],
|
targets: luoOuterTargets,
|
||||||
protected: ['liu-bei', 'zhuge-liang']
|
protected: ['liu-bei', 'zhuge-liang']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -590,21 +748,21 @@ const hanzhongCampaignBattles = [
|
|||||||
no: 31,
|
no: 31,
|
||||||
id: 'thirty-first-battle-luo-main-gate',
|
id: 'thirty-first-battle-luo-main-gate',
|
||||||
selected: luoMainSortie,
|
selected: luoMainSortie,
|
||||||
targets: ['luo-main-leader-zhang-ren'],
|
targets: luoMainTargets,
|
||||||
protected: ['liu-bei', 'pang-tong']
|
protected: ['liu-bei', 'pang-tong']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
no: 32,
|
no: 32,
|
||||||
id: 'thirty-second-battle-mianzhu-gate',
|
id: 'thirty-second-battle-mianzhu-gate',
|
||||||
selected: mianzhuSortie,
|
selected: mianzhuSortie,
|
||||||
targets: ['chengdu-leader-li-yan'],
|
targets: mianzhuTargets,
|
||||||
protected: ['liu-bei', 'yan-yan']
|
protected: ['liu-bei', 'yan-yan']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
no: 33,
|
no: 33,
|
||||||
id: 'thirty-third-battle-chengdu-surrender',
|
id: 'thirty-third-battle-chengdu-surrender',
|
||||||
selected: chengduSortie,
|
selected: chengduSortie,
|
||||||
targets: ['chengdu-final-leader-huang-quan'],
|
targets: chengduFinalTargets,
|
||||||
protected: ['liu-bei', 'li-yan']
|
protected: ['liu-bei', 'li-yan']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1273,9 +1431,9 @@ async function normalizeRepresentativeBattleUnits(page, battle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const selectedIds = new Set([...(selected ?? []), ...(protectedUnitIds ?? [])]);
|
const selectedIds = new Set([...(selected ?? []), ...(protectedUnitIds ?? [])]);
|
||||||
const hpFloor = no >= 28 ? 86 : no >= 21 ? 84 : no >= 18 ? 84 : no >= 14 ? 80 : no >= 11 ? 68 : no >= 2 ? 56 : 0;
|
const hpFloor = no >= 30 ? 520 : no >= 28 ? 360 : no >= 21 ? 84 : no >= 18 ? 84 : no >= 14 ? 80 : no >= 11 ? 68 : no >= 2 ? 56 : 0;
|
||||||
const attackFloor = no >= 28 ? 78 : no >= 21 ? 70 : no >= 18 ? 64 : no >= 14 ? 60 : no >= 11 ? 42 : no >= 2 ? 24 : 0;
|
const attackFloor = no >= 30 ? 126 : no >= 28 ? 96 : no >= 21 ? 70 : no >= 18 ? 64 : no >= 14 ? 60 : no >= 11 ? 42 : no >= 2 ? 24 : 0;
|
||||||
const statFloor = no >= 28 ? 132 : no >= 21 ? 126 : no >= 18 ? 122 : no >= 14 ? 118 : no >= 11 ? 98 : no >= 2 ? 88 : 0;
|
const statFloor = no >= 30 ? 180 : no >= 28 ? 150 : no >= 21 ? 126 : no >= 18 ? 122 : no >= 14 ? 118 : no >= 11 ? 98 : no >= 2 ? 88 : 0;
|
||||||
|
|
||||||
if (hpFloor <= 0) {
|
if (hpFloor <= 0) {
|
||||||
return;
|
return;
|
||||||
@@ -1634,10 +1792,11 @@ async function playBattleWithoutDebugVictory(page, battle) {
|
|||||||
}
|
}
|
||||||
const pressProtected = shouldPressProtected(unit);
|
const pressProtected = shouldPressProtected(unit);
|
||||||
const isTarget = targetIds.has(attack.target.id);
|
const isTarget = targetIds.has(attack.target.id);
|
||||||
|
const isLeaderTarget = attack.target.id.includes('leader');
|
||||||
const kill = attack.preview.damage >= attack.target.hp;
|
const kill = attack.preview.damage >= attack.target.hp;
|
||||||
if (isLastProtectedFighter(unit)) {
|
if (isLastProtectedFighter(unit)) {
|
||||||
const hpRate = unit.hp / Math.max(1, unit.maxHp);
|
const hpRate = unit.hp / Math.max(1, unit.maxHp);
|
||||||
if (isTarget && hpRate >= 0.45) {
|
if ((isLeaderTarget || isTarget) && hpRate >= 0.45) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (kill && hpRate >= 0.35) {
|
if (kill && hpRate >= 0.35) {
|
||||||
@@ -1645,16 +1804,16 @@ async function playBattleWithoutDebugVictory(page, battle) {
|
|||||||
}
|
}
|
||||||
return threat <= Math.floor(unit.hp * 1.05);
|
return threat <= Math.floor(unit.hp * 1.05);
|
||||||
}
|
}
|
||||||
if (protectedIds.size > 1 && !isTarget && unit.id === 'sun-qian') {
|
if (protectedIds.size > 1 && !isLeaderTarget && unit.id === 'sun-qian') {
|
||||||
return kill && liveUnits('enemy').length <= 3 && threat <= Math.floor(unit.hp * 0.12);
|
return kill && liveUnits('enemy').length <= 3 && threat <= Math.floor(unit.hp * 0.12);
|
||||||
}
|
}
|
||||||
if (protectedIds.size > 1 && !isTarget) {
|
if (protectedIds.size > 1 && !isLeaderTarget) {
|
||||||
return unit.hp >= Math.ceil(unit.maxHp * 0.75) && threat <= Math.floor(unit.hp * 0.22);
|
return unit.hp >= Math.ceil(unit.maxHp * 0.75) && threat <= Math.floor(unit.hp * 0.22);
|
||||||
}
|
}
|
||||||
if (isTarget && (pressProtected || kill) && threat <= Math.floor(unit.hp * (pressProtected ? 0.7 : 0.42))) {
|
if (isLeaderTarget && (pressProtected || kill) && threat <= Math.floor(unit.hp * (pressProtected ? 0.7 : 0.42))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (isTarget && protectedIds.size === 1 && threat <= Math.floor(unit.hp * 0.3)) {
|
if (isLeaderTarget && protectedIds.size === 1 && threat <= Math.floor(unit.hp * 0.3)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (kill && threat <= Math.floor(unit.hp * (pressProtected ? 0.5 : 0.32))) {
|
if (kill && threat <= Math.floor(unit.hp * (pressProtected ? 0.5 : 0.32))) {
|
||||||
@@ -1723,6 +1882,12 @@ async function playBattleWithoutDebugVictory(page, battle) {
|
|||||||
return { x: 25, y: 13 };
|
return { x: 25, y: 13 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (no === 29) {
|
||||||
|
const routeDone = (state().objectives ?? []).find((objective) => objective.id === 'wu-yi-route')?.achieved;
|
||||||
|
if (!routeDone) {
|
||||||
|
return { x: 47, y: 23 };
|
||||||
|
}
|
||||||
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user