Add Wudu Yinping campaign chapter
This commit is contained in:
@@ -3801,6 +3801,59 @@ export const fiftyNinthBattleVictoryPages: StoryPage[] = [
|
||||
}
|
||||
];
|
||||
|
||||
export const sixtiethBattleIntroPages: StoryPage[] = [
|
||||
{
|
||||
id: 'sixtieth-wudu-yinping-order',
|
||||
bgm: 'story-dark',
|
||||
chapter: '무도와 음평',
|
||||
background: 'story-militia',
|
||||
speaker: '제갈량',
|
||||
text: '진창의 성벽은 오래 물고 늘어질 곳이 아니었습니다. 이번에는 성을 치기보다 무도와 음평의 산길을 나누어 잡아, 북방의 두 고을을 촉한의 숨통으로 만들겠습니다.'
|
||||
},
|
||||
{
|
||||
id: 'sixtieth-guo-huai-relief',
|
||||
bgm: 'battle-prep',
|
||||
chapter: '곽회의 구원로',
|
||||
background: 'story-sortie',
|
||||
speaker: '강유',
|
||||
text: '곽회는 성을 지키는 장수가 아니라 길을 끊는 장수입니다. 제가 아는 천수 길로 앞을 보겠습니다. 다만 위연 장군의 돌파, 조운과 마대의 기병, 왕평의 산길 판단을 모두 한꺼번에 쓸 수는 없습니다.'
|
||||
},
|
||||
{
|
||||
id: 'sixtieth-two-commandery-supply',
|
||||
bgm: 'story-dark',
|
||||
chapter: '둘로 갈라진 보급',
|
||||
background: 'story-three-heroes',
|
||||
speaker: '황권',
|
||||
text: '무도와 음평을 동시에 안정시키려면 장부가 둘로 갈라집니다. 마량이 마을을 달래고, 왕평이 산길 표식을 세우며, 누가 빠르게 치고 누가 멈출지 출전 전에 정해야 합니다.'
|
||||
}
|
||||
];
|
||||
|
||||
export const sixtiethBattleVictoryPages: StoryPage[] = [
|
||||
{
|
||||
id: 'sixtieth-victory-commanderies-secured',
|
||||
bgm: 'militia-theme',
|
||||
chapter: '두 고을 확보',
|
||||
background: 'story-sortie',
|
||||
text: '촉한군은 무도와 음평의 길목을 차례로 눌러 곽회의 구원로를 늦췄습니다. 큰 성 하나를 무너뜨린 승리가 아니라, 북벌이 다시 숨 쉴 수 있는 산길을 확보한 승리였습니다.'
|
||||
},
|
||||
{
|
||||
id: 'sixtieth-victory-jiangwei-weiyan-choice',
|
||||
bgm: 'story-dark',
|
||||
chapter: '돌파 뒤의 지도',
|
||||
background: 'story-militia',
|
||||
speaker: '제갈량',
|
||||
text: '강유는 길을 읽었고 위연은 길이 열릴 때 망설이지 않았습니다. 하지만 둘이 함께 앞서갈수록 조운과 마대의 회수선, 왕평과 황권의 제동 장치가 더 중요해졌습니다.'
|
||||
},
|
||||
{
|
||||
id: 'sixtieth-next-northern-plan',
|
||||
bgm: 'story-dark',
|
||||
chapter: '다음 북방 계산',
|
||||
background: 'story-three-heroes',
|
||||
speaker: '마량',
|
||||
text: '무도와 음평의 백성에게는 오늘의 승리가 끝이 아니라 약속의 시작입니다. 다음 북벌에서는 얻은 땅을 지키는 장부와 다시 나아갈 장수의 마음을 함께 보아야 합니다.'
|
||||
}
|
||||
];
|
||||
|
||||
export const firstBattleMap: BattleMap = {
|
||||
width: 20,
|
||||
height: 18,
|
||||
@@ -4300,6 +4353,12 @@ export const fiftyNinthBattleMap: BattleMap = {
|
||||
terrain: createFiftyNinthBattleTerrain()
|
||||
};
|
||||
|
||||
export const sixtiethBattleMap: BattleMap = {
|
||||
width: 120,
|
||||
height: 102,
|
||||
terrain: createSixtiethBattleTerrain()
|
||||
};
|
||||
|
||||
export const firstBattleUnits: UnitData[] = [
|
||||
{
|
||||
id: 'liu-bei',
|
||||
@@ -17426,6 +17485,97 @@ export const fiftyNinthBattleUnits: UnitData[] = [
|
||||
createThirtyFirstEnemyUnit('northern-fifth-leader-hao-zhao', '학소', '진창 수비장', 'rebelLeader', 197, 1540, 362, 109, 35)
|
||||
];
|
||||
|
||||
const sixtiethBattleAllyPositions: Record<string, { x: number; y: number }> = {
|
||||
'guan-yu': { x: 18, y: 90 },
|
||||
'zhang-fei': { x: 24, y: 92 },
|
||||
'jian-yong': { x: 10, y: 97 },
|
||||
'mi-zhu': { x: 14, y: 98 },
|
||||
'sun-qian': { x: 19, y: 98 },
|
||||
'zhao-yun': { x: 31, y: 88 },
|
||||
'zhuge-liang': { x: 17, y: 87 },
|
||||
'ma-liang': { x: 22, y: 84 },
|
||||
'yi-ji': { x: 9, y: 100 },
|
||||
'gong-zhi': { x: 27, y: 98 },
|
||||
'huang-zhong': { x: 37, y: 86 },
|
||||
'wei-yan': { x: 43, y: 88 },
|
||||
'pang-tong': { x: 15, y: 83 },
|
||||
'fa-zheng': { x: 27, y: 82 },
|
||||
'wu-yi': { x: 45, y: 96 },
|
||||
'yan-yan': { x: 49, y: 89 },
|
||||
'li-yan': { x: 35, y: 81 },
|
||||
'huang-quan': { x: 12, y: 86 },
|
||||
'ma-chao': { x: 52, y: 85 },
|
||||
'ma-dai': { x: 56, y: 92 },
|
||||
'wang-ping': { x: 40, y: 81 },
|
||||
'jiang-wei': { x: 33, y: 84 }
|
||||
};
|
||||
|
||||
export const sixtiethBattleUnits: UnitData[] = [
|
||||
...[
|
||||
...firstBattleUnits.filter((unit) => unit.faction === 'ally' && unit.id !== 'liu-bei'),
|
||||
...xuzhouRecruitUnits,
|
||||
...caoBreakRecruitUnits,
|
||||
...liuBiaoRecruitUnits,
|
||||
...zhugeRecruitUnits,
|
||||
...jingzhouRecruitUnits,
|
||||
...guiyangRecruitUnits,
|
||||
...wulingRecruitUnits,
|
||||
...changshaRecruitUnits,
|
||||
...yizhouRecruitUnits,
|
||||
...fuPassRecruitUnits,
|
||||
...luoCastleRecruitUnits,
|
||||
...luoCastleProperRecruitUnits,
|
||||
...chengduPressureRecruitUnits,
|
||||
...chengduSurrenderRecruitUnits,
|
||||
...hanzhongOpeningRecruitUnits,
|
||||
...hanzhongScoutRecruitUnits,
|
||||
...hanzhongMainRecruitUnits,
|
||||
...jiangWeiRecruitUnits
|
||||
].map((unit) => placeScenarioUnit(unit, sixtiethBattleAllyPositions[unit.id] ?? { x: unit.x, y: unit.y })),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-scout-a', '무도 산길 척후병', '서쪽 고개 정찰', 'bandit', 198, 1000, 278, 50, 80),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-scout-b', '음평 하곡 척후병', '하곡 정찰', 'bandit', 198, 1000, 278, 61, 76),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-scout-c', '무도 산길 척후병', '중앙 갈림길 정찰', 'bandit', 199, 1012, 280, 74, 69),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-scout-d', '음평 하곡 척후병', '동쪽 하천 정찰', 'bandit', 199, 1012, 280, 87, 61),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-scout-e', '곽회 전초 척후병', '곽회 본영 정찰', 'bandit', 200, 1024, 282, 103, 47),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-scout-f', '북쪽 봉화 척후병', '북쪽 봉화 정찰', 'bandit', 200, 1024, 282, 116, 30),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-infantry-a', '위군 무도 보병', '서쪽 고개 보병', 'yellowTurban', 199, 1400, 336, 55, 75),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-infantry-b', '위군 음평 보병', '하곡 보병', 'yellowTurban', 199, 1400, 336, 65, 70),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-infantry-c', '위군 무도 보병', '중앙 보병', 'yellowTurban', 200, 1420, 340, 77, 64),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-infantry-d', '위군 음평 보병', '동쪽 물목 보병', 'yellowTurban', 200, 1420, 340, 90, 57),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-infantry-e', '위군 무도 보병', '방어선 보병', 'yellowTurban', 201, 1440, 344, 102, 50),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-infantry-f', '위군 음평 보병', '곽회 본영 보병', 'yellowTurban', 201, 1440, 344, 112, 38),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-infantry-g', '위군 보급 차단병', '군량로 차단 보병', 'yellowTurban', 202, 1460, 348, 95, 78),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-infantry-h', '북쪽 능선 보병', '북쪽 능선 보병', 'yellowTurban', 202, 1460, 348, 117, 20),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-archer-a', '무도 능선 궁병', '서쪽 능선 궁병', 'archer', 199, 1050, 290, 60, 65),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-archer-b', '음평 물목 궁병', '하곡 궁병', 'archer', 199, 1050, 290, 72, 60),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-archer-c', '무도 능선 궁병', '중앙 능선 궁병', 'archer', 200, 1062, 292, 86, 53),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-archer-d', '음평 물목 궁병', '동쪽 물목 궁병', 'archer', 201, 1074, 294, 98, 45),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-archer-e', '곽회 본영 궁병', '곽회 본영 궁병', 'archer', 201, 1074, 294, 110, 33),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-archer-f', '북쪽 봉화 궁병', '봉화대 궁병', 'archer', 202, 1086, 296, 118, 17),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-cavalry-a', '곽회 구원 기병', '서쪽 구원 기병', 'cavalry', 200, 1458, 354, 51, 68),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-cavalry-b', '곽회 구원 기병', '하곡 구원 기병', 'cavalry', 200, 1458, 354, 64, 65),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-cavalry-c', '곽회 구원 기병', '중앙 우회 기병', 'cavalry', 201, 1480, 358, 78, 58),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-cavalry-d', '곽회 구원 기병', '동쪽 우회 기병', 'cavalry', 202, 1502, 362, 92, 51),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-cavalry-e', '곽회 구원 기병', '본영 지원 기병', 'cavalry', 202, 1502, 362, 105, 43),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-cavalry-f', '곽회 구원 기병', '북쪽 차단 기병', 'cavalry', 203, 1524, 366, 116, 27),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-ridge-guard-a', '무도 고개 수비대', '서쪽 고개 수비', 'yellowTurban', 200, 1420, 342, 46, 55),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-ridge-guard-b', '음평 물길 수비대', '하곡 물길 수비', 'yellowTurban', 200, 1420, 342, 60, 49),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-ridge-guard-c', '무도 고개 수비대', '중앙 고개 수비', 'yellowTurban', 201, 1440, 346, 76, 41),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-ridge-guard-d', '음평 물길 수비대', '동쪽 물목 수비', 'yellowTurban', 201, 1440, 346, 92, 34),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-ridge-guard-e', '곽회 본영 수비대', '곽회 본영 수비', 'yellowTurban', 202, 1460, 350, 106, 26),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-ridge-guard-f', '북쪽 절벽 수비대', '북쪽 절벽 수비', 'yellowTurban', 202, 1460, 350, 118, 14),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-strategist-a', '위군 무도 군리', '무도 장부 군리', 'strategist', 200, 1120, 304, 74, 56),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-strategist-b', '위군 음평 군리', '음평 장부 군리', 'strategist', 201, 1132, 306, 88, 47),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-strategist-c', '곽회 본영 군리', '곽회 본영 군리', 'strategist', 201, 1132, 306, 102, 38),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-strategist-d', '위군 보급 군리', '군량 차단 군리', 'strategist', 202, 1144, 308, 108, 66),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-officer-wudu', '무도 수비장', '무도 고개 장수', 'rebelLeader', 203, 1500, 360, 86, 72),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-officer-yinping', '음평 수비장', '음평 물목 장수', 'rebelLeader', 203, 1500, 360, 101, 60),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-officer-fei-yao', '비요', '곽회 지원 장수', 'rebelLeader', 202, 1480, 356, 109, 70),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-officer-supply', '위군 군량 차단장', '두 고을 보급 차단 장수', 'rebelLeader', 201, 1460, 352, 80, 80),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-officer-relay', '위군 봉화 장수', '북쪽 봉화 장수', 'rebelLeader', 202, 1480, 356, 115, 25),
|
||||
createThirtyFirstEnemyUnit('northern-sixth-leader-guo-huai', '곽회', '위군 북방 구원 총대장', 'rebelLeader', 204, 1580, 372, 112, 36)
|
||||
];
|
||||
|
||||
export const firstBattleBonds: BattleBond[] = [
|
||||
{
|
||||
id: 'liu-bei__guan-yu',
|
||||
@@ -18703,6 +18853,46 @@ export const fiftyNinthBattleBonds: BattleBond[] = [
|
||||
...northernFifthBattleBonds
|
||||
].map(cloneBattleBondForScenario);
|
||||
|
||||
export const northernSixthBattleBonds: BattleBond[] = [
|
||||
{
|
||||
id: 'jiang-wei__wei-yan_northern-sixth',
|
||||
unitIds: ['jiang-wei', 'wei-yan'],
|
||||
title: '길을 여는 돌파',
|
||||
level: 48,
|
||||
exp: 0,
|
||||
description: '강유의 산길 판단과 위연의 돌파력이 맞물리면 무도와 음평의 좁은 갈림길에서도 빠르게 압박할 수 있습니다.'
|
||||
},
|
||||
{
|
||||
id: 'zhao-yun__ma-dai_northern-sixth',
|
||||
unitIds: ['zhao-yun', 'ma-dai'],
|
||||
title: '두 기병의 회수선',
|
||||
level: 56,
|
||||
exp: 0,
|
||||
description: '조운의 안정된 회수 기동과 마대의 서량 우회 감각이 함께하면 곽회의 구원 기병을 늦추면서도 본대와 끊어지지 않습니다.'
|
||||
},
|
||||
{
|
||||
id: 'wang-ping__huang-quan_northern-sixth',
|
||||
unitIds: ['wang-ping', 'huang-quan'],
|
||||
title: '산길과 장부',
|
||||
level: 50,
|
||||
exp: 0,
|
||||
description: '왕평의 산길 표식과 황권의 보급 장부가 맞물리면 두 고을을 얻은 뒤에도 군량선이 무너지지 않습니다.'
|
||||
},
|
||||
{
|
||||
id: 'ma-liang__jiang-wei_northern-sixth',
|
||||
unitIds: ['ma-liang', 'jiang-wei'],
|
||||
title: '새 고을의 약속',
|
||||
level: 42,
|
||||
exp: 0,
|
||||
description: '마량의 민심 문서와 강유의 천수 사람 이해가 함께하면 무도와 음평의 백성이 새 전선을 두려움만으로 보지 않게 됩니다.'
|
||||
}
|
||||
];
|
||||
|
||||
export const sixtiethBattleBonds: BattleBond[] = [
|
||||
...fiftyNinthBattleBonds,
|
||||
...northernSixthBattleBonds
|
||||
].map(cloneBattleBondForScenario);
|
||||
|
||||
function createEighthBattleTerrain(): TerrainType[][] {
|
||||
return Array.from({ length: 22 }, (_, y) =>
|
||||
Array.from({ length: 26 }, (_, x): TerrainType => {
|
||||
@@ -21946,6 +22136,81 @@ function createFiftyNinthBattleTerrain(): TerrainType[][] {
|
||||
);
|
||||
}
|
||||
|
||||
function createSixtiethBattleTerrain(): TerrainType[][] {
|
||||
return Array.from({ length: 102 }, (_, y) =>
|
||||
Array.from({ length: 120 }, (_, x): TerrainType => {
|
||||
if (
|
||||
(x >= 5 && x <= 11 && y >= 0 && y <= 101) ||
|
||||
(x >= 62 && x <= 68 && y >= 16 && y <= 101) ||
|
||||
(x >= 0 && x <= 119 && y >= 94)
|
||||
) {
|
||||
return 'river';
|
||||
}
|
||||
if (
|
||||
(x >= 9 && x <= 80 && y >= 86 && y <= 92) ||
|
||||
(x >= 23 && x <= 98 && y >= 75 && y <= 83) ||
|
||||
(x >= 48 && x <= 108 && y >= 63 && y <= 73) ||
|
||||
(x >= 76 && x <= 116 && y >= 49 && y <= 61) ||
|
||||
(x >= 92 && x <= 119 && y >= 35 && y <= 46) ||
|
||||
(x >= 30 && x <= 38 && y >= 68 && y <= 96) ||
|
||||
(x >= 54 && x <= 62 && y >= 55 && y <= 88) ||
|
||||
(x >= 84 && x <= 93 && y >= 41 && y <= 78)
|
||||
) {
|
||||
return 'road';
|
||||
}
|
||||
if (
|
||||
(x >= 0 && x <= 35 && y >= 58 && y <= 90) ||
|
||||
(x >= 42 && x <= 78 && y >= 72 && y <= 93) ||
|
||||
(x >= 88 && x <= 119 && y >= 66 && y <= 91) ||
|
||||
(x >= 14 && x <= 38 && y >= 42 && y <= 60)
|
||||
) {
|
||||
return 'forest';
|
||||
}
|
||||
if (
|
||||
(x >= 0 && x <= 49 && y <= 38) ||
|
||||
(x >= 46 && x <= 90 && y <= 32) ||
|
||||
(x >= 86 && x <= 119 && y <= 50) ||
|
||||
(x >= 98 && x <= 119 && y >= 44 && y <= 70)
|
||||
) {
|
||||
return 'hill';
|
||||
}
|
||||
if (
|
||||
(x <= 2 && y <= 92) ||
|
||||
(x >= 117 && y <= 86) ||
|
||||
(x >= 38 && x <= 44 && y >= 0 && y <= 62) ||
|
||||
(x >= 75 && x <= 81 && y >= 0 && y <= 44) ||
|
||||
(x >= 59 && x <= 66 && y >= 84 && y <= 101)
|
||||
) {
|
||||
return 'cliff';
|
||||
}
|
||||
if (
|
||||
(x >= 12 && x <= 28 && y >= 82 && y <= 92) ||
|
||||
(x >= 43 && x <= 62 && y >= 70 && y <= 82) ||
|
||||
(x >= 78 && x <= 96 && y >= 56 && y <= 68) ||
|
||||
(x >= 100 && x <= 116 && y >= 41 && y <= 54)
|
||||
) {
|
||||
return 'village';
|
||||
}
|
||||
if (
|
||||
(x >= 20 && x <= 45 && y >= 77 && y <= 90) ||
|
||||
(x >= 54 && x <= 79 && y >= 64 && y <= 76) ||
|
||||
(x >= 87 && x <= 110 && y >= 50 && y <= 63)
|
||||
) {
|
||||
return 'camp';
|
||||
}
|
||||
if (
|
||||
(x >= 48 && x <= 67 && y >= 45 && y <= 60) ||
|
||||
(x >= 72 && x <= 96 && y >= 35 && y <= 50) ||
|
||||
(x >= 94 && x <= 116 && y >= 44 && y <= 60) ||
|
||||
(x >= 102 && x <= 119 && y >= 14 && y <= 33)
|
||||
) {
|
||||
return 'fort';
|
||||
}
|
||||
return 'plain';
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function placeScenarioUnit(unit: UnitData, position: { x: number; y: number }): UnitData {
|
||||
return {
|
||||
...cloneUnitForScenario(unit),
|
||||
|
||||
Reference in New Issue
Block a user