From a114b3628618ee486c3e48a29d76eb4c9cbad31a Mon Sep 17 00:00:00 2001 From: Wickedness Date: Sat, 27 Jun 2026 17:52:35 +0900 Subject: [PATCH] QA and tune Hanzhong campaign battles --- scripts/qa-representative-battles.mjs | 86 ++++++++++- scripts/verify-flow.mjs | 8 +- src/game/data/battles.ts | 18 +-- src/game/data/scenario.ts | 196 +++++++++++++------------- src/game/scenes/BattleScene.ts | 16 +-- src/game/scenes/CampScene.ts | 4 +- 6 files changed, 206 insertions(+), 122 deletions(-) diff --git a/scripts/qa-representative-battles.mjs b/scripts/qa-representative-battles.mjs index 70b047a..a5b6bed 100644 --- a/scripts/qa-representative-battles.mjs +++ b/scripts/qa-representative-battles.mjs @@ -23,6 +23,16 @@ const yizhouReliefSortie = ['liu-bei', 'zhuge-liang', 'huang-zhong', 'wei-yan', const fuPassSortie = ['liu-bei', 'pang-tong', 'zhuge-liang', 'wei-yan', 'huang-zhong', 'zhao-yun']; const luoOuterSortie = ['liu-bei', 'fa-zheng', 'zhuge-liang', 'huang-zhong', 'zhao-yun', 'mi-zhu']; const luofengSortie = ['liu-bei', 'pang-tong', 'wu-yi', 'fa-zheng', 'zhao-yun', 'huang-zhong']; +const luoMainSortie = ['liu-bei', 'pang-tong', 'fa-zheng', 'wu-yi', 'huang-zhong', 'zhang-fei']; +const mianzhuSortie = ['liu-bei', 'yan-yan', 'fa-zheng', 'wu-yi', 'pang-tong', 'huang-zhong']; +const chengduSortie = ['liu-bei', 'li-yan', 'zhuge-liang', 'fa-zheng', 'yan-yan', 'wu-yi']; +const jiamengSortie = ['liu-bei', 'huang-quan', 'zhao-yun', 'zhang-fei', 'fa-zheng', 'huang-zhong']; +const yangpingSortie = ['liu-bei', 'ma-chao', 'huang-quan', 'zhuge-liang', 'zhao-yun', 'fa-zheng']; +const dingjunSortie = ['liu-bei', 'huang-zhong', 'fa-zheng', 'ma-chao', 'ma-dai', 'mi-zhu']; +const hanzhongSortie = ['liu-bei', 'huang-zhong', 'fa-zheng', 'wang-ping', 'ma-chao', 'ma-dai', 'zhuge-liang']; +const jingDefenseSortie = ['liu-bei', 'guan-yu', 'zhang-fei', 'ma-liang', 'mi-zhu', 'zhuge-liang', 'zhao-yun']; +const fanCastleVanguardSortie = ['liu-bei', 'guan-yu', 'zhang-fei', 'zhao-yun', 'huang-zhong', 'fa-zheng', 'ma-liang']; +const hanRiverFloodSortie = ['liu-bei', 'guan-yu', 'fa-zheng', 'ma-liang', 'huang-quan', 'zhao-yun', 'ma-chao']; const earlyCampaignBattles = [ { no: 1, id: 'first-battle-zhuo-commandery', selected: [], targets: ['rebel-leader'], protected: ['liu-bei'] }, @@ -237,6 +247,79 @@ const southernCampaignBattles = [ } ]; +const hanzhongCampaignBattles = [ + { + no: 31, + id: 'thirty-first-battle-luo-main-gate', + selected: luoMainSortie, + targets: ['luo-main-leader-zhang-ren'], + protected: ['liu-bei', 'pang-tong'] + }, + { + no: 32, + id: 'thirty-second-battle-mianzhu-gate', + selected: mianzhuSortie, + targets: ['chengdu-leader-li-yan'], + protected: ['liu-bei', 'yan-yan'] + }, + { + no: 33, + id: 'thirty-third-battle-chengdu-surrender', + selected: chengduSortie, + targets: ['chengdu-final-leader-huang-quan'], + protected: ['liu-bei', 'li-yan'] + }, + { + no: 34, + id: 'thirty-fourth-battle-jiameng-pass', + selected: jiamengSortie, + targets: ['jiameng-leader-ma-chao'], + protected: ['liu-bei', 'huang-quan'] + }, + { + no: 35, + id: 'thirty-fifth-battle-yangping-scout', + selected: yangpingSortie, + targets: ['yangping-leader-zhang-wei'], + protected: ['liu-bei', 'ma-chao'] + }, + { + no: 36, + id: 'thirty-sixth-battle-dingjun-vanguard', + selected: dingjunSortie, + targets: ['dingjun-leader-xiahou-yuan'], + protected: ['liu-bei', 'huang-zhong'] + }, + { + no: 37, + id: 'thirty-seventh-battle-hanzhong-decisive', + selected: hanzhongSortie, + targets: ['hanzhong-leader-cao-cao'], + protected: ['liu-bei', 'wang-ping'] + }, + { + no: 38, + id: 'thirty-eighth-battle-jing-defense', + selected: jingDefenseSortie, + targets: ['jing-defense-leader-lu-meng'], + protected: ['liu-bei', 'guan-yu'] + }, + { + no: 39, + id: 'thirty-ninth-battle-fan-castle-vanguard', + selected: fanCastleVanguardSortie, + targets: ['fan-castle-leader-pang-de'], + protected: ['liu-bei', 'guan-yu'] + }, + { + no: 40, + id: 'fortieth-battle-han-river-flood', + selected: hanRiverFloodSortie, + targets: ['han-river-leader-yu-jin'], + protected: ['liu-bei', 'guan-yu'] + } +]; + const allRepresentativeBattles = [ { no: 1, id: 'first-battle-zhuo-commandery', selected: [], targets: ['rebel-leader'], protected: ['liu-bei'] }, { @@ -301,7 +384,8 @@ const qaBattleSets = { representative: allRepresentativeBattles, early: earlyCampaignBattles, refuge: refugeCampaignBattles, - southern: southernCampaignBattles + southern: southernCampaignBattles, + hanzhong: hanzhongCampaignBattles }; const qaSetName = process.env.QA_SET ?? 'representative'; const qaBattleSet = qaBattleSets[qaSetName]; diff --git a/scripts/verify-flow.mjs b/scripts/verify-flow.mjs index 525804f..be3a070 100644 --- a/scripts/verify-flow.mjs +++ b/scripts/verify-flow.mjs @@ -4457,7 +4457,7 @@ try { !dingjunSortieState.sortieRoster?.some((unit) => unit.id === 'fa-zheng' && unit.recruited && unit.recommended) || !dingjunSortieState.sortieRoster?.some((unit) => unit.id === 'ma-chao' && unit.recruited && unit.recommended) || !dingjunSortieState.sortieRoster?.some((unit) => unit.id === 'ma-dai' && unit.recruited && unit.recommended) || - !dingjunSortieState.sortieRoster?.some((unit) => unit.id === 'zhuge-liang' && unit.recruited && unit.recommended) || + !dingjunSortieState.sortieRoster?.some((unit) => unit.id === 'mi-zhu' && unit.recruited && unit.recommended) || dingjunSortieState.sortieRoster?.some((unit) => unit.id === 'wang-ping') || dingjunSortieState.sortieRoster?.length < 21 || dingjunSortieState.sortiePlan?.maxCount !== 6 @@ -4488,7 +4488,7 @@ try { 'ma-dai' ]); - const dingjunPriorityUnits = ['huang-zhong', 'fa-zheng', 'ma-chao', 'ma-dai', 'zhuge-liang']; + const dingjunPriorityUnits = ['huang-zhong', 'fa-zheng', 'ma-chao', 'ma-dai', 'mi-zhu']; for (const unitId of dingjunPriorityUnits) { const currentSortieState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp()); if (!currentSortieState.sortieRoster?.some((unit) => unit.id === unitId && unit.selected)) { @@ -4510,7 +4510,7 @@ try { dingjunSortieReadyState.sortiePlan?.selectedCount !== 6 || dingjunSortieReadyState.sortiePlan?.recommendedSelectedCount < 6 ) { - throw new Error(`Expected Dingjun sortie to deploy Huang Zhong, Fa Zheng, Ma Chao, Ma Dai, and Zhuge Liang while preserving six-officer pressure: ${JSON.stringify(dingjunSortieReadyState)}`); + throw new Error(`Expected Dingjun sortie to deploy Huang Zhong, Fa Zheng, Ma Chao, Ma Dai, and Mi Zhu while preserving six-officer pressure: ${JSON.stringify(dingjunSortieReadyState)}`); } await page.screenshot({ path: 'dist/verification-dingjun-sortie.png', fullPage: true }); @@ -4553,7 +4553,7 @@ try { !thirtySixthAllies.some((unit) => unit.id === 'fa-zheng') || !thirtySixthAllies.some((unit) => unit.id === 'ma-chao') || !thirtySixthAllies.some((unit) => unit.id === 'ma-dai') || - !thirtySixthAllies.some((unit) => unit.id === 'zhuge-liang') || + !thirtySixthAllies.some((unit) => unit.id === 'mi-zhu') || !unitUsesTexture(thirtySixthBattleState, 'dingjun-officer-wang-ping', 'unit-wang-ping') || !unitUsesTexture(thirtySixthBattleState, 'huang-zhong', 'unit-huang-zhong') || !unitUsesTexture(thirtySixthBattleState, 'fa-zheng', 'unit-fa-zheng') || diff --git a/src/game/data/battles.ts b/src/game/data/battles.ts index da7aaf5..617a0d8 100644 --- a/src/game/data/battles.ts +++ b/src/game/data/battles.ts @@ -2100,7 +2100,7 @@ export const thirtyFirstBattleScenario: BattleScenarioDefinition = { bonds: thirtyFirstBattleBonds, mapTextureKey: 'battle-map-thirty-first', leaderUnitId: 'luo-main-leader-zhang-ren', - quickVictoryTurnLimit: 42, + quickVictoryTurnLimit: 48, baseVictoryGold: 4720, objectives: [ { @@ -2134,9 +2134,9 @@ export const thirtyFirstBattleScenario: BattleScenarioDefinition = { { id: 'quick', kind: 'quick-victory', - label: '42턴 이내 승리', + label: '48턴 이내 승리', rewardGold: 1120, - maxTurn: 42 + maxTurn: 48 } ], defeatConditions: [ @@ -2163,7 +2163,7 @@ export const thirtySecondBattleScenario: BattleScenarioDefinition = { bonds: thirtySecondBattleBonds, mapTextureKey: 'battle-map-thirty-second', leaderUnitId: 'chengdu-leader-li-yan', - quickVictoryTurnLimit: 45, + quickVictoryTurnLimit: 50, baseVictoryGold: 5040, objectives: [ { @@ -2197,9 +2197,9 @@ export const thirtySecondBattleScenario: BattleScenarioDefinition = { { id: 'quick', kind: 'quick-victory', - label: '45턴 이내 승리', + label: '50턴 이내 승리', rewardGold: 1180, - maxTurn: 45 + maxTurn: 50 } ], defeatConditions: [ @@ -2415,7 +2415,7 @@ export const thirtySixthBattleScenario: BattleScenarioDefinition = { bonds: thirtySixthBattleBonds, mapTextureKey: 'battle-map-thirty-sixth', leaderUnitId: 'dingjun-leader-xiahou-yuan', - quickVictoryTurnLimit: 54, + quickVictoryTurnLimit: 70, baseVictoryGold: 6240, objectives: [ { @@ -2449,9 +2449,9 @@ export const thirtySixthBattleScenario: BattleScenarioDefinition = { { id: 'quick', kind: 'quick-victory', - label: '54턴 이내 승리', + label: '70턴 이내 승리', rewardGold: 1440, - maxTurn: 54 + maxTurn: 70 } ], defeatConditions: [ diff --git a/src/game/data/scenario.ts b/src/game/data/scenario.ts index 5b9982d..887d208 100644 --- a/src/game/data/scenario.ts +++ b/src/game/data/scenario.ts @@ -15557,31 +15557,31 @@ export const thirtyFirstBattleUnits: UnitData[] = [ ...fuPassRecruitUnits, ...luoCastleRecruitUnits ].map((unit) => placeScenarioUnit(unit, thirtyFirstBattleAllyPositions[unit.id] ?? { x: unit.x, y: unit.y })), - createThirtyFirstEnemyUnit('luo-main-scout-a', '낙성 정찰병', '성밖 정찰병', 'bandit', 53, 148, 55, 18, 39), - createThirtyFirstEnemyUnit('luo-main-scout-b', '낙성 정찰병', '수로 정찰병', 'bandit', 53, 148, 55, 23, 36), - createThirtyFirstEnemyUnit('luo-main-infantry-a', '낙성 보병', '외성 보병', 'yellowTurban', 54, 210, 66, 28, 34), - createThirtyFirstEnemyUnit('luo-main-infantry-b', '낙성 보병', '외성 보병', 'yellowTurban', 54, 210, 66, 33, 32), - createThirtyFirstEnemyUnit('luo-main-infantry-c', '낙성 보병', '성문 보병', 'yellowTurban', 55, 220, 68, 40, 28), - createThirtyFirstEnemyUnit('luo-main-infantry-d', '낙성 보병', '성문 보병', 'yellowTurban', 55, 220, 68, 44, 26), - createThirtyFirstEnemyUnit('luo-main-infantry-e', '낙성 보병', '내성 보병', 'yellowTurban', 56, 230, 70, 51, 23), - createThirtyFirstEnemyUnit('luo-main-archer-a', '낙성 궁병', '외벽 궁병', 'archer', 54, 146, 55, 31, 29), - createThirtyFirstEnemyUnit('luo-main-archer-b', '낙성 궁병', '성벽 궁병', 'archer', 55, 152, 56, 42, 22), - createThirtyFirstEnemyUnit('luo-main-archer-c', '낙성 궁병', '성벽 궁병', 'archer', 55, 152, 56, 49, 18), - createThirtyFirstEnemyUnit('luo-main-archer-d', '낙성 궁병', '내성 궁병', 'archer', 56, 158, 58, 55, 24), - createThirtyFirstEnemyUnit('luo-main-cavalry-a', '낙성 기병', '우익 기병', 'cavalry', 55, 220, 70, 29, 40), - createThirtyFirstEnemyUnit('luo-main-cavalry-b', '낙성 기병', '좌익 기병', 'cavalry', 55, 220, 70, 39, 36), - createThirtyFirstEnemyUnit('luo-main-cavalry-c', '낙성 기병', '내성 기병', 'cavalry', 56, 232, 72, 53, 29), - createThirtyFirstEnemyUnit('luo-main-guard-a', '장임 친위대', '성문 친위대', 'yellowTurban', 56, 236, 72, 48, 21), - createThirtyFirstEnemyUnit('luo-main-guard-b', '장임 친위대', '성문 친위대', 'yellowTurban', 56, 236, 72, 51, 20), - createThirtyFirstEnemyUnit('luo-main-guard-c', '장임 친위대', '내성 친위대', 'yellowTurban', 57, 246, 74, 56, 19), - createThirtyFirstEnemyUnit('luo-main-strategist-a', '낙성 책사', '성문 책사', 'strategist', 55, 150, 56, 45, 18), - createThirtyFirstEnemyUnit('luo-main-strategist-b', '낙성 책사', '내성 책사', 'strategist', 56, 156, 58, 55, 15), - createThirtyFirstEnemyUnit('luo-main-ambusher-a', '낙성 복병', '남벽 복병', 'bandit', 54, 156, 58, 34, 39), - createThirtyFirstEnemyUnit('luo-main-ambusher-b', '낙성 복병', '동문 복병', 'bandit', 54, 156, 58, 48, 32), - createThirtyFirstEnemyUnit('luo-main-ambusher-c', '낙성 복병', '북벽 복병', 'bandit', 55, 164, 60, 57, 11), - createThirtyFirstEnemyUnit('luo-main-veteran-yan-yan', '엄안', '익주 노장', 'archer', 57, 210, 68, 50, 22), - createThirtyFirstEnemyUnit('luo-main-officer-a', '낙성 부장', '성문 부장', 'rebelLeader', 57, 260, 75, 54, 20), - createThirtyFirstEnemyUnit('luo-main-leader-zhang-ren', '장임', '낙성 본성 주장', 'rebelLeader', 58, 286, 78, 58, 18) + createThirtyFirstEnemyUnit('luo-main-scout-a', '낙성 정찰병', '성밖 정찰병', 'bandit', 53, 130, 42, 18, 39), + createThirtyFirstEnemyUnit('luo-main-scout-b', '낙성 정찰병', '수로 정찰병', 'bandit', 53, 130, 42, 23, 36), + createThirtyFirstEnemyUnit('luo-main-infantry-a', '낙성 보병', '외성 보병', 'yellowTurban', 54, 180, 50, 28, 34), + createThirtyFirstEnemyUnit('luo-main-infantry-b', '낙성 보병', '외성 보병', 'yellowTurban', 54, 180, 50, 33, 32), + createThirtyFirstEnemyUnit('luo-main-infantry-c', '낙성 보병', '성문 보병', 'yellowTurban', 55, 188, 52, 40, 28), + createThirtyFirstEnemyUnit('luo-main-infantry-d', '낙성 보병', '성문 보병', 'yellowTurban', 55, 188, 52, 44, 26), + createThirtyFirstEnemyUnit('luo-main-infantry-e', '낙성 보병', '내성 보병', 'yellowTurban', 56, 196, 54, 51, 23), + createThirtyFirstEnemyUnit('luo-main-archer-a', '낙성 궁병', '외벽 궁병', 'archer', 54, 118, 40, 31, 29), + createThirtyFirstEnemyUnit('luo-main-archer-b', '낙성 궁병', '성벽 궁병', 'archer', 55, 124, 42, 42, 22), + createThirtyFirstEnemyUnit('luo-main-archer-c', '낙성 궁병', '성벽 궁병', 'archer', 55, 124, 42, 49, 18), + createThirtyFirstEnemyUnit('luo-main-archer-d', '낙성 궁병', '내성 궁병', 'archer', 56, 128, 44, 55, 24), + createThirtyFirstEnemyUnit('luo-main-cavalry-a', '낙성 기병', '우익 기병', 'cavalry', 55, 180, 52, 29, 40), + createThirtyFirstEnemyUnit('luo-main-cavalry-b', '낙성 기병', '좌익 기병', 'cavalry', 55, 180, 52, 39, 36), + createThirtyFirstEnemyUnit('luo-main-cavalry-c', '낙성 기병', '내성 기병', 'cavalry', 56, 190, 54, 53, 29), + createThirtyFirstEnemyUnit('luo-main-guard-a', '장임 친위대', '성문 친위대', 'yellowTurban', 56, 190, 52, 48, 21), + createThirtyFirstEnemyUnit('luo-main-guard-b', '장임 친위대', '성문 친위대', 'yellowTurban', 56, 190, 52, 51, 20), + createThirtyFirstEnemyUnit('luo-main-guard-c', '장임 친위대', '내성 친위대', 'yellowTurban', 57, 198, 54, 56, 19), + createThirtyFirstEnemyUnit('luo-main-strategist-a', '낙성 책사', '성문 책사', 'strategist', 55, 118, 40, 45, 18), + createThirtyFirstEnemyUnit('luo-main-strategist-b', '낙성 책사', '내성 책사', 'strategist', 56, 122, 42, 55, 15), + createThirtyFirstEnemyUnit('luo-main-ambusher-a', '낙성 복병', '남벽 복병', 'bandit', 54, 130, 44, 34, 39), + createThirtyFirstEnemyUnit('luo-main-ambusher-b', '낙성 복병', '동문 복병', 'bandit', 54, 130, 44, 48, 32), + createThirtyFirstEnemyUnit('luo-main-ambusher-c', '낙성 복병', '북벽 복병', 'bandit', 55, 136, 46, 57, 11), + createThirtyFirstEnemyUnit('luo-main-veteran-yan-yan', '엄안', '익주 노장', 'archer', 57, 170, 52, 50, 22), + createThirtyFirstEnemyUnit('luo-main-officer-a', '낙성 부장', '성문 부장', 'rebelLeader', 57, 210, 56, 54, 20), + createThirtyFirstEnemyUnit('luo-main-leader-zhang-ren', '장임', '낙성 본성 주장', 'rebelLeader', 58, 232, 58, 58, 18) ]; const thirtySecondBattleAllyPositions: Record = { @@ -15686,32 +15686,32 @@ export const thirtyThirdBattleUnits: UnitData[] = [ ...luoCastleProperRecruitUnits, ...chengduPressureRecruitUnits ].map((unit) => placeScenarioUnit(unit, thirtyThirdBattleAllyPositions[unit.id] ?? { x: unit.x, y: unit.y })), - createThirtyFirstEnemyUnit('chengdu-final-scout-a', '성도 척후', '남문 척후', 'bandit', 60, 182, 66, 19, 41), - createThirtyFirstEnemyUnit('chengdu-final-scout-b', '성도 척후', '서문 척후', 'bandit', 60, 182, 66, 25, 39), - createThirtyFirstEnemyUnit('chengdu-final-scout-c', '성도 척후', '수로 척후', 'bandit', 61, 190, 68, 32, 37), - createThirtyFirstEnemyUnit('chengdu-final-infantry-a', '성도 보병', '외곽 보병', 'yellowTurban', 61, 266, 82, 31, 34), - createThirtyFirstEnemyUnit('chengdu-final-infantry-b', '성도 보병', '외곽 보병', 'yellowTurban', 61, 266, 82, 36, 33), - createThirtyFirstEnemyUnit('chengdu-final-infantry-c', '성도 보병', '남문 보병', 'yellowTurban', 62, 276, 84, 43, 28), - createThirtyFirstEnemyUnit('chengdu-final-infantry-d', '성도 보병', '남문 보병', 'yellowTurban', 62, 276, 84, 47, 27), - createThirtyFirstEnemyUnit('chengdu-final-infantry-e', '유장 친위대', '성문 친위대', 'yellowTurban', 63, 288, 86, 55, 23), - createThirtyFirstEnemyUnit('chengdu-final-infantry-f', '유장 친위대', '창고 친위대', 'yellowTurban', 63, 288, 86, 60, 25), - createThirtyFirstEnemyUnit('chengdu-final-archer-a', '성도 궁병', '성벽 궁병', 'archer', 61, 182, 66, 34, 31), - createThirtyFirstEnemyUnit('chengdu-final-archer-b', '성도 궁병', '남문 궁병', 'archer', 62, 190, 68, 46, 23), - createThirtyFirstEnemyUnit('chengdu-final-archer-c', '성도 궁병', '고지 궁병', 'archer', 62, 190, 68, 52, 18), - createThirtyFirstEnemyUnit('chengdu-final-archer-d', '성도 궁병', '창고 궁병', 'archer', 63, 198, 70, 61, 20), - createThirtyFirstEnemyUnit('chengdu-final-cavalry-a', '성도 기병', '우익 기병', 'cavalry', 62, 276, 86, 28, 43), - createThirtyFirstEnemyUnit('chengdu-final-cavalry-b', '성도 기병', '좌익 기병', 'cavalry', 62, 276, 86, 43, 38), - createThirtyFirstEnemyUnit('chengdu-final-cavalry-c', '성도 기병', '내성 기병', 'cavalry', 63, 288, 88, 58, 31), - createThirtyFirstEnemyUnit('chengdu-final-guard-a', '황권 친위대', '권고 반대파', 'yellowTurban', 63, 300, 88, 50, 22), - createThirtyFirstEnemyUnit('chengdu-final-guard-b', '황권 친위대', '권고 반대파', 'yellowTurban', 63, 300, 88, 54, 21), - createThirtyFirstEnemyUnit('chengdu-final-guard-c', '황권 친위대', '성도 친위대', 'yellowTurban', 64, 312, 90, 60, 18), - createThirtyFirstEnemyUnit('chengdu-final-strategist-a', '성도 책사', '항복 반대파', 'strategist', 62, 190, 68, 48, 19), - createThirtyFirstEnemyUnit('chengdu-final-strategist-b', '성도 책사', '유장 사자', 'strategist', 63, 198, 70, 57, 16), - createThirtyFirstEnemyUnit('chengdu-final-ambusher-a', '성도 복병', '남벽 복병', 'bandit', 61, 190, 70, 37, 41), - createThirtyFirstEnemyUnit('chengdu-final-ambusher-b', '성도 복병', '동문 복병', 'bandit', 61, 190, 70, 51, 35), - createThirtyFirstEnemyUnit('chengdu-final-ambusher-c', '성도 복병', '북벽 복병', 'bandit', 62, 198, 72, 62, 12), - createThirtyFirstEnemyUnit('chengdu-final-officer-a', '성도 부장', '남문 부장', 'rebelLeader', 64, 318, 92, 58, 22), - createThirtyFirstEnemyUnit('chengdu-final-leader-huang-quan', '황권', '성도 수비 참모', 'rebelLeader', 65, 336, 94, 62, 18) + createThirtyFirstEnemyUnit('chengdu-final-scout-a', '성도 척후', '남문 척후', 'bandit', 60, 182, 58, 19, 41), + createThirtyFirstEnemyUnit('chengdu-final-scout-b', '성도 척후', '서문 척후', 'bandit', 60, 182, 58, 25, 39), + createThirtyFirstEnemyUnit('chengdu-final-scout-c', '성도 척후', '수로 척후', 'bandit', 61, 190, 60, 32, 37), + createThirtyFirstEnemyUnit('chengdu-final-infantry-a', '성도 보병', '외곽 보병', 'yellowTurban', 61, 266, 70, 31, 34), + createThirtyFirstEnemyUnit('chengdu-final-infantry-b', '성도 보병', '외곽 보병', 'yellowTurban', 61, 266, 70, 36, 33), + createThirtyFirstEnemyUnit('chengdu-final-infantry-c', '성도 보병', '남문 보병', 'yellowTurban', 62, 276, 72, 43, 28), + createThirtyFirstEnemyUnit('chengdu-final-infantry-d', '성도 보병', '남문 보병', 'yellowTurban', 62, 276, 72, 47, 27), + createThirtyFirstEnemyUnit('chengdu-final-infantry-e', '유장 친위대', '성문 친위대', 'yellowTurban', 63, 288, 74, 55, 23), + createThirtyFirstEnemyUnit('chengdu-final-infantry-f', '유장 친위대', '창고 친위대', 'yellowTurban', 63, 288, 74, 60, 25), + createThirtyFirstEnemyUnit('chengdu-final-archer-a', '성도 궁병', '성벽 궁병', 'archer', 61, 182, 58, 34, 31), + createThirtyFirstEnemyUnit('chengdu-final-archer-b', '성도 궁병', '남문 궁병', 'archer', 62, 190, 60, 46, 23), + createThirtyFirstEnemyUnit('chengdu-final-archer-c', '성도 궁병', '고지 궁병', 'archer', 62, 190, 60, 52, 18), + createThirtyFirstEnemyUnit('chengdu-final-archer-d', '성도 궁병', '창고 궁병', 'archer', 63, 198, 62, 61, 20), + createThirtyFirstEnemyUnit('chengdu-final-cavalry-a', '성도 기병', '우익 기병', 'cavalry', 62, 276, 70, 28, 43), + createThirtyFirstEnemyUnit('chengdu-final-cavalry-b', '성도 기병', '좌익 기병', 'cavalry', 62, 276, 70, 43, 38), + createThirtyFirstEnemyUnit('chengdu-final-cavalry-c', '성도 기병', '내성 기병', 'cavalry', 63, 288, 72, 58, 31), + createThirtyFirstEnemyUnit('chengdu-final-guard-a', '황권 친위대', '권고 반대파', 'yellowTurban', 63, 300, 74, 50, 22), + createThirtyFirstEnemyUnit('chengdu-final-guard-b', '황권 친위대', '권고 반대파', 'yellowTurban', 63, 300, 74, 54, 21), + createThirtyFirstEnemyUnit('chengdu-final-guard-c', '황권 친위대', '성도 친위대', 'yellowTurban', 64, 312, 76, 60, 18), + createThirtyFirstEnemyUnit('chengdu-final-strategist-a', '성도 책사', '항복 반대파', 'strategist', 62, 190, 60, 48, 19), + createThirtyFirstEnemyUnit('chengdu-final-strategist-b', '성도 책사', '유장 사자', 'strategist', 63, 198, 62, 57, 16), + createThirtyFirstEnemyUnit('chengdu-final-ambusher-a', '성도 복병', '남벽 복병', 'bandit', 61, 190, 58, 37, 41), + createThirtyFirstEnemyUnit('chengdu-final-ambusher-b', '성도 복병', '동문 복병', 'bandit', 61, 190, 58, 51, 35), + createThirtyFirstEnemyUnit('chengdu-final-ambusher-c', '성도 복병', '북벽 복병', 'bandit', 62, 198, 60, 62, 12), + createThirtyFirstEnemyUnit('chengdu-final-officer-a', '성도 부장', '남문 부장', 'rebelLeader', 64, 300, 78, 58, 22), + createThirtyFirstEnemyUnit('chengdu-final-leader-huang-quan', '황권', '성도 수비 참모', 'rebelLeader', 65, 316, 80, 62, 18) ]; const thirtyFourthBattleAllyPositions: Record = { @@ -15754,28 +15754,28 @@ export const thirtyFourthBattleUnits: UnitData[] = [ ...chengduPressureRecruitUnits, ...chengduSurrenderRecruitUnits ].map((unit) => placeScenarioUnit(unit, thirtyFourthBattleAllyPositions[unit.id] ?? { x: unit.x, y: unit.y })), - createThirtyFirstEnemyUnit('jiameng-scout-a', '한중 척후', '산길 척후', 'bandit', 64, 198, 72, 18, 43), - createThirtyFirstEnemyUnit('jiameng-scout-b', '한중 척후', '관문 척후', 'bandit', 64, 198, 72, 26, 41), - createThirtyFirstEnemyUnit('jiameng-scout-c', '한중 척후', '수로 척후', 'bandit', 65, 206, 74, 34, 39), - createThirtyFirstEnemyUnit('jiameng-infantry-a', '장로 보병', '외곽 보병', 'yellowTurban', 65, 288, 88, 33, 36), - createThirtyFirstEnemyUnit('jiameng-infantry-b', '장로 보병', '외곽 보병', 'yellowTurban', 65, 288, 88, 38, 35), - createThirtyFirstEnemyUnit('jiameng-infantry-c', '가맹관 보병', '관문 보병', 'yellowTurban', 66, 300, 90, 45, 30), - createThirtyFirstEnemyUnit('jiameng-infantry-d', '가맹관 보병', '관문 보병', 'yellowTurban', 66, 300, 90, 49, 29), - createThirtyFirstEnemyUnit('jiameng-archer-a', '한중 궁병', '산허리 궁병', 'archer', 65, 206, 74, 36, 32), - createThirtyFirstEnemyUnit('jiameng-archer-b', '한중 궁병', '관문 궁병', 'archer', 66, 214, 76, 47, 24), - createThirtyFirstEnemyUnit('jiameng-archer-c', '한중 궁병', '고지 궁병', 'archer', 66, 214, 76, 55, 19), - createThirtyFirstEnemyUnit('jiameng-cavalry-a', '서량 기병', '좌익 기병', 'cavalry', 66, 304, 92, 30, 45), - createThirtyFirstEnemyUnit('jiameng-cavalry-b', '서량 기병', '우익 기병', 'cavalry', 66, 304, 92, 44, 40), - createThirtyFirstEnemyUnit('jiameng-cavalry-c', '서량 기병', '돌격 기병', 'cavalry', 67, 316, 94, 56, 33), - createThirtyFirstEnemyUnit('jiameng-cavalry-d', '서량 기병', '친위 기병', 'cavalry', 67, 316, 94, 61, 26), - createThirtyFirstEnemyUnit('jiameng-guard-a', '마초 친위대', '돌격 친위대', 'yellowTurban', 67, 326, 96, 53, 24), - createThirtyFirstEnemyUnit('jiameng-guard-b', '마초 친위대', '관문 친위대', 'yellowTurban', 67, 326, 96, 58, 23), - createThirtyFirstEnemyUnit('jiameng-strategist-a', '한중 책사', '장로 사자', 'strategist', 66, 214, 76, 50, 20), - createThirtyFirstEnemyUnit('jiameng-strategist-b', '한중 책사', '관문 책사', 'strategist', 67, 222, 78, 60, 18), - createThirtyFirstEnemyUnit('jiameng-ambusher-a', '한중 복병', '남령 복병', 'bandit', 65, 206, 76, 39, 43), - createThirtyFirstEnemyUnit('jiameng-ambusher-b', '한중 복병', '동령 복병', 'bandit', 65, 206, 76, 52, 37), - createThirtyFirstEnemyUnit('jiameng-officer-pang-de', '방덕', '서량 부장', 'rebelLeader', 68, 344, 98, 59, 25), - createThirtyFirstEnemyUnit('jiameng-leader-ma-chao', '마초', '서량 기병장', 'rebelLeader', 69, 364, 102, 63, 20) + createThirtyFirstEnemyUnit('jiameng-scout-a', '한중 척후', '산길 척후', 'bandit', 64, 198, 64, 18, 43), + createThirtyFirstEnemyUnit('jiameng-scout-b', '한중 척후', '관문 척후', 'bandit', 64, 198, 64, 26, 41), + createThirtyFirstEnemyUnit('jiameng-scout-c', '한중 척후', '수로 척후', 'bandit', 65, 206, 66, 34, 39), + createThirtyFirstEnemyUnit('jiameng-infantry-a', '장로 보병', '외곽 보병', 'yellowTurban', 65, 288, 78, 33, 36), + createThirtyFirstEnemyUnit('jiameng-infantry-b', '장로 보병', '외곽 보병', 'yellowTurban', 65, 288, 78, 38, 35), + createThirtyFirstEnemyUnit('jiameng-infantry-c', '가맹관 보병', '관문 보병', 'yellowTurban', 66, 300, 80, 45, 30), + createThirtyFirstEnemyUnit('jiameng-infantry-d', '가맹관 보병', '관문 보병', 'yellowTurban', 66, 300, 80, 49, 29), + createThirtyFirstEnemyUnit('jiameng-archer-a', '한중 궁병', '산허리 궁병', 'archer', 65, 206, 66, 36, 32), + createThirtyFirstEnemyUnit('jiameng-archer-b', '한중 궁병', '관문 궁병', 'archer', 66, 214, 68, 47, 24), + createThirtyFirstEnemyUnit('jiameng-archer-c', '한중 궁병', '고지 궁병', 'archer', 66, 214, 68, 55, 19), + createThirtyFirstEnemyUnit('jiameng-cavalry-a', '서량 기병', '좌익 기병', 'cavalry', 66, 304, 68, 30, 45), + createThirtyFirstEnemyUnit('jiameng-cavalry-b', '서량 기병', '우익 기병', 'cavalry', 66, 304, 68, 44, 40), + createThirtyFirstEnemyUnit('jiameng-cavalry-c', '서량 기병', '돌격 기병', 'cavalry', 67, 316, 70, 56, 33), + createThirtyFirstEnemyUnit('jiameng-cavalry-d', '서량 기병', '친위 기병', 'cavalry', 67, 316, 70, 61, 26), + createThirtyFirstEnemyUnit('jiameng-guard-a', '마초 친위대', '돌격 친위대', 'yellowTurban', 67, 326, 72, 53, 24), + createThirtyFirstEnemyUnit('jiameng-guard-b', '마초 친위대', '관문 친위대', 'yellowTurban', 67, 326, 72, 58, 23), + createThirtyFirstEnemyUnit('jiameng-strategist-a', '한중 책사', '장로 사자', 'strategist', 66, 214, 68, 50, 20), + createThirtyFirstEnemyUnit('jiameng-strategist-b', '한중 책사', '관문 책사', 'strategist', 67, 222, 70, 60, 18), + createThirtyFirstEnemyUnit('jiameng-ambusher-a', '한중 복병', '남령 복병', 'bandit', 65, 206, 66, 39, 43), + createThirtyFirstEnemyUnit('jiameng-ambusher-b', '한중 복병', '동령 복병', 'bandit', 65, 206, 66, 52, 37), + createThirtyFirstEnemyUnit('jiameng-officer-pang-de', '방덕', '서량 부장', 'rebelLeader', 68, 344, 74, 59, 25), + createThirtyFirstEnemyUnit('jiameng-leader-ma-chao', '마초', '서량 기병장', 'rebelLeader', 69, 336, 76, 63, 20) ]; const thirtyFifthBattleAllyPositions: Record = { @@ -15890,31 +15890,31 @@ export const thirtySixthBattleUnits: UnitData[] = [ ...hanzhongOpeningRecruitUnits, ...hanzhongScoutRecruitUnits ].map((unit) => placeScenarioUnit(unit, thirtySixthBattleAllyPositions[unit.id] ?? { x: unit.x, y: unit.y })), - createThirtyFirstEnemyUnit('dingjun-scout-a', '정군산 척후', '서령 척후', 'bandit', 72, 238, 82, 20, 47), - createThirtyFirstEnemyUnit('dingjun-scout-b', '정군산 척후', '산길 척후', 'bandit', 72, 238, 82, 29, 45), - createThirtyFirstEnemyUnit('dingjun-scout-c', '정군산 척후', '강변 척후', 'bandit', 73, 246, 84, 38, 43), - createThirtyFirstEnemyUnit('dingjun-infantry-a', '조조 보병', '서령 보병', 'yellowTurban', 73, 348, 100, 36, 40), - createThirtyFirstEnemyUnit('dingjun-infantry-b', '조조 보병', '중턱 보병', 'yellowTurban', 73, 348, 100, 42, 39), - createThirtyFirstEnemyUnit('dingjun-infantry-c', '하후연 보병', '능선 보병', 'yellowTurban', 74, 360, 104, 49, 35), - createThirtyFirstEnemyUnit('dingjun-infantry-d', '하후연 보병', '본진 보병', 'yellowTurban', 74, 360, 104, 53, 33), - createThirtyFirstEnemyUnit('dingjun-infantry-e', '정군산 보병', '창고 보병', 'yellowTurban', 75, 372, 106, 63, 30), - createThirtyFirstEnemyUnit('dingjun-archer-a', '조조 궁병', '서벽 궁병', 'archer', 73, 246, 84, 39, 37), - createThirtyFirstEnemyUnit('dingjun-archer-b', '조조 궁병', '능선 궁병', 'archer', 74, 254, 86, 51, 29), - createThirtyFirstEnemyUnit('dingjun-archer-c', '조조 궁병', '고지 궁병', 'archer', 74, 254, 86, 60, 24), - createThirtyFirstEnemyUnit('dingjun-archer-d', '조조 궁병', '창고 궁병', 'archer', 75, 262, 88, 66, 32), - createThirtyFirstEnemyUnit('dingjun-cavalry-a', '조조 기병', '좌익 기병', 'cavalry', 74, 364, 104, 32, 49), - createThirtyFirstEnemyUnit('dingjun-cavalry-b', '조조 기병', '우익 기병', 'cavalry', 74, 364, 104, 47, 44), - createThirtyFirstEnemyUnit('dingjun-cavalry-c', '하후연 기병', '돌격 기병', 'cavalry', 75, 376, 106, 59, 38), - createThirtyFirstEnemyUnit('dingjun-cavalry-d', '하후연 기병', '친위 기병', 'cavalry', 75, 376, 106, 67, 33), - createThirtyFirstEnemyUnit('dingjun-guard-a', '하후연 친위대', '능선 친위대', 'yellowTurban', 75, 388, 108, 56, 29), - createThirtyFirstEnemyUnit('dingjun-guard-b', '하후연 친위대', '본진 친위대', 'yellowTurban', 75, 388, 108, 64, 28), - createThirtyFirstEnemyUnit('dingjun-strategist-a', '조조 책사', '고지 책사', 'strategist', 74, 254, 88, 54, 25), - createThirtyFirstEnemyUnit('dingjun-strategist-b', '조조 책사', '본진 책사', 'strategist', 75, 262, 90, 66, 22), - createThirtyFirstEnemyUnit('dingjun-ambusher-a', '조조 복병', '남령 복병', 'bandit', 73, 248, 86, 43, 47), - createThirtyFirstEnemyUnit('dingjun-ambusher-b', '조조 복병', '동령 복병', 'bandit', 73, 248, 86, 56, 41), - createThirtyFirstEnemyUnit('dingjun-officer-zhang-he', '장합', '조조 선봉장', 'cavalry', 76, 392, 112, 61, 27), - createThirtyFirstEnemyUnit('dingjun-officer-wang-ping', '왕평', '한중 길잡이', 'spearman', 75, 330, 100, 58, 31), - createThirtyFirstEnemyUnit('dingjun-leader-xiahou-yuan', '하후연', '정군산 주장', 'rebelLeader', 77, 418, 116, 68, 25) + createThirtyFirstEnemyUnit('dingjun-scout-a', '정군산 척후', '서령 척후', 'bandit', 72, 190, 60, 20, 47), + createThirtyFirstEnemyUnit('dingjun-scout-b', '정군산 척후', '산길 척후', 'bandit', 72, 190, 60, 29, 45), + createThirtyFirstEnemyUnit('dingjun-scout-c', '정군산 척후', '강변 척후', 'bandit', 73, 198, 62, 38, 43), + createThirtyFirstEnemyUnit('dingjun-infantry-a', '조조 보병', '서령 보병', 'yellowTurban', 73, 270, 72, 36, 40), + createThirtyFirstEnemyUnit('dingjun-infantry-b', '조조 보병', '중턱 보병', 'yellowTurban', 73, 270, 72, 42, 39), + createThirtyFirstEnemyUnit('dingjun-infantry-c', '하후연 보병', '능선 보병', 'yellowTurban', 74, 280, 76, 49, 35), + createThirtyFirstEnemyUnit('dingjun-infantry-d', '하후연 보병', '본진 보병', 'yellowTurban', 74, 280, 76, 53, 33), + createThirtyFirstEnemyUnit('dingjun-infantry-e', '정군산 보병', '창고 보병', 'yellowTurban', 75, 292, 78, 63, 30), + createThirtyFirstEnemyUnit('dingjun-archer-a', '조조 궁병', '서벽 궁병', 'archer', 73, 196, 62, 39, 37), + createThirtyFirstEnemyUnit('dingjun-archer-b', '조조 궁병', '능선 궁병', 'archer', 74, 204, 64, 51, 29), + createThirtyFirstEnemyUnit('dingjun-archer-c', '조조 궁병', '고지 궁병', 'archer', 74, 204, 64, 60, 24), + createThirtyFirstEnemyUnit('dingjun-archer-d', '조조 궁병', '창고 궁병', 'archer', 75, 212, 66, 66, 32), + createThirtyFirstEnemyUnit('dingjun-cavalry-a', '조조 기병', '좌익 기병', 'cavalry', 74, 286, 64, 32, 49), + createThirtyFirstEnemyUnit('dingjun-cavalry-b', '조조 기병', '우익 기병', 'cavalry', 74, 286, 64, 47, 44), + createThirtyFirstEnemyUnit('dingjun-cavalry-c', '하후연 기병', '돌격 기병', 'cavalry', 75, 296, 66, 59, 38), + createThirtyFirstEnemyUnit('dingjun-cavalry-d', '하후연 기병', '친위 기병', 'cavalry', 75, 296, 66, 67, 33), + createThirtyFirstEnemyUnit('dingjun-guard-a', '하후연 친위대', '능선 친위대', 'yellowTurban', 75, 304, 80, 56, 29), + createThirtyFirstEnemyUnit('dingjun-guard-b', '하후연 친위대', '본진 친위대', 'yellowTurban', 75, 304, 80, 64, 28), + createThirtyFirstEnemyUnit('dingjun-strategist-a', '조조 책사', '고지 책사', 'strategist', 74, 204, 64, 54, 25), + createThirtyFirstEnemyUnit('dingjun-strategist-b', '조조 책사', '본진 책사', 'strategist', 75, 212, 66, 66, 22), + createThirtyFirstEnemyUnit('dingjun-ambusher-a', '조조 복병', '남령 복병', 'bandit', 73, 198, 56, 43, 47), + createThirtyFirstEnemyUnit('dingjun-ambusher-b', '조조 복병', '동령 복병', 'bandit', 73, 198, 56, 56, 41), + createThirtyFirstEnemyUnit('dingjun-officer-zhang-he', '장합', '조조 선봉장', 'cavalry', 76, 300, 72, 57, 31), + createThirtyFirstEnemyUnit('dingjun-officer-wang-ping', '왕평', '한중 길잡이', 'spearman', 75, 270, 76, 55, 34), + createThirtyFirstEnemyUnit('dingjun-leader-xiahou-yuan', '하후연', '정군산 주장', 'rebelLeader', 77, 320, 78, 60, 31) ]; const thirtySeventhBattleAllyPositions: Record = { diff --git a/src/game/scenes/BattleScene.ts b/src/game/scenes/BattleScene.ts index f045070..190f8e5 100644 --- a/src/game/scenes/BattleScene.ts +++ b/src/game/scenes/BattleScene.ts @@ -2004,16 +2004,16 @@ const enemyAiByUnitId: Record = { 'dingjun-archer-c': 'hold', 'dingjun-archer-d': 'hold', 'dingjun-cavalry-a': 'aggressive', - 'dingjun-cavalry-b': 'aggressive', - 'dingjun-cavalry-c': 'aggressive', - 'dingjun-cavalry-d': 'aggressive', + 'dingjun-cavalry-b': 'guard', + 'dingjun-cavalry-c': 'guard', + 'dingjun-cavalry-d': 'guard', 'dingjun-guard-a': 'guard', 'dingjun-guard-b': 'guard', 'dingjun-strategist-a': 'hold', 'dingjun-strategist-b': 'hold', - 'dingjun-ambusher-a': 'aggressive', - 'dingjun-ambusher-b': 'aggressive', - 'dingjun-officer-zhang-he': 'aggressive', + 'dingjun-ambusher-a': 'guard', + 'dingjun-ambusher-b': 'guard', + 'dingjun-officer-zhang-he': 'guard', 'dingjun-officer-wang-ping': 'guard', 'dingjun-leader-xiahou-yuan': 'guard', 'hanzhong-scout-a': 'aggressive', @@ -2075,7 +2075,7 @@ const enemyAiByUnitId: Record = { 'jing-defense-ambusher-c': 'aggressive', 'jing-defense-officer-lu-xun': 'hold', 'jing-defense-officer-cao-ren': 'guard', - 'jing-defense-leader-lu-meng': 'aggressive', + 'jing-defense-leader-lu-meng': 'guard', 'fan-castle-scout-a': 'aggressive', 'fan-castle-scout-b': 'aggressive', 'fan-castle-scout-c': 'aggressive', @@ -2105,7 +2105,7 @@ const enemyAiByUnitId: Record = { 'fan-castle-ambusher-c': 'aggressive', 'fan-castle-officer-yu-jin': 'guard', 'fan-castle-officer-cao-ren': 'guard', - 'fan-castle-leader-pang-de': 'aggressive', + 'fan-castle-leader-pang-de': 'guard', 'han-river-scout-a': 'aggressive', 'han-river-scout-b': 'aggressive', 'han-river-scout-c': 'aggressive', diff --git a/src/game/scenes/CampScene.ts b/src/game/scenes/CampScene.ts index a289aa6..1bf6d28 100644 --- a/src/game/scenes/CampScene.ts +++ b/src/game/scenes/CampScene.ts @@ -934,9 +934,9 @@ const sortieRulesByBattleId: Partial