|
|
|
|
@@ -51,6 +51,7 @@ import {
|
|
|
|
|
mengHuoPacificationBonds,
|
|
|
|
|
mengHuoSecondCaptureBonds,
|
|
|
|
|
nanzhongRecoveryBonds,
|
|
|
|
|
northernEighthBattleBonds,
|
|
|
|
|
northernFifthBattleBonds,
|
|
|
|
|
northernFourthBattleBonds,
|
|
|
|
|
northernFirstBattleBonds,
|
|
|
|
|
@@ -447,9 +448,10 @@ const campaignTimelineChapters: CampaignTimelineChapter[] = [
|
|
|
|
|
'fifty-eighth-battle-qishan-retreat',
|
|
|
|
|
'fifty-ninth-battle-chencang-siege',
|
|
|
|
|
'sixtieth-battle-wudu-yinping',
|
|
|
|
|
'sixty-first-battle-hanzhong-rain-defense'
|
|
|
|
|
'sixty-first-battle-hanzhong-rain-defense',
|
|
|
|
|
'sixty-second-battle-qishan-renewed-offensive'
|
|
|
|
|
],
|
|
|
|
|
nextHints: ['한중 창고 정비', '출전 무장 재편', '기산 출진로', '천수·가정 방면', '강유 합류', '진창 공성 재계산', '무도·음평 확보', '한중 우로 방어']
|
|
|
|
|
nextHints: ['한중 창고 정비', '출전 무장 재편', '기산 출진로', '천수·가정 방면', '강유 합류', '진창 공성 재계산', '무도·음평 확보', '한중 우로 방어', '기산 재출정']
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
@@ -514,7 +516,8 @@ const campBattleIds = {
|
|
|
|
|
fiftyEighth: 'fifty-eighth-battle-qishan-retreat',
|
|
|
|
|
fiftyNinth: 'fifty-ninth-battle-chencang-siege',
|
|
|
|
|
sixtieth: 'sixtieth-battle-wudu-yinping',
|
|
|
|
|
sixtyFirst: 'sixty-first-battle-hanzhong-rain-defense'
|
|
|
|
|
sixtyFirst: 'sixty-first-battle-hanzhong-rain-defense',
|
|
|
|
|
sixtySecond: 'sixty-second-battle-qishan-renewed-offensive'
|
|
|
|
|
} as const;
|
|
|
|
|
|
|
|
|
|
const defaultRequiredSortieUnitIds = ['liu-bei'];
|
|
|
|
|
@@ -1281,6 +1284,23 @@ const sortieRulesByBattleId: Partial<Record<BattleScenarioId, SortieRuleDefiniti
|
|
|
|
|
{ unitId: 'ma-dai', reason: '서량 기병의 우회 감각으로 음평 물목과 조진 기병의 측면 압박을 견제합니다.' }
|
|
|
|
|
],
|
|
|
|
|
note: '한중 우로 방어전은 추천 무장이 9명으로 출전 제한보다 둘 많습니다. 새 고을 보급을 지킬 장부 담당, 빗길 표식, 반격 돌파, 기병 회수 중 무엇을 뒤에 남길지 정해야 합니다.'
|
|
|
|
|
},
|
|
|
|
|
'sixty-second-battle-qishan-renewed-offensive': {
|
|
|
|
|
maxUnits: 7,
|
|
|
|
|
requiredUnitIds: ['zhuge-liang'],
|
|
|
|
|
excludedUnitIds: ['liu-bei'],
|
|
|
|
|
recommended: [
|
|
|
|
|
{ unitId: 'zhuge-liang', reason: '노성 앞 지연선을 상대하며 전진과 회수, 보급과 민심을 동시에 나누어야 하는 총지휘관입니다.' },
|
|
|
|
|
{ unitId: 'jiang-wei', reason: '지켜 낸 무도·음평 길을 다시 공격로로 바꾸는 길잡이입니다. 사마의의 지연선을 먼저 읽어야 합니다.' },
|
|
|
|
|
{ unitId: 'wei-yan', reason: '노성 앞 지연선을 짧게 흔들 돌파 장수입니다. 다만 장합의 추격과 돌아올 길을 함께 계산해야 합니다.' },
|
|
|
|
|
{ unitId: 'zhao-yun', reason: '깊이 들어간 부대를 회수하고 예비대를 묶어 장합 기병의 추격을 늦춥니다.' },
|
|
|
|
|
{ unitId: 'wang-ping', reason: '기산 산길의 표식과 회수선을 세워 공격로가 퇴로를 잃지 않게 합니다.' },
|
|
|
|
|
{ unitId: 'huang-quan', reason: '한중 우로 장부를 공세 가능량으로 환산해 보급 붕괴를 막습니다.' },
|
|
|
|
|
{ unitId: 'ma-liang', reason: '노성 앞 마을과 새 보급로의 고시문을 정리해 북벌 명분을 실제 약속으로 보이게 합니다.' },
|
|
|
|
|
{ unitId: 'li-yan', reason: '수레와 운송 지연을 후방에서 관리합니다. 전장에 데려가면 보급 위기는 줄지만 기동 선택이 줄어듭니다.' },
|
|
|
|
|
{ unitId: 'ma-dai', reason: '서량 기병의 측면 감각으로 곽회의 차단로와 동쪽 물목을 견제합니다.' }
|
|
|
|
|
],
|
|
|
|
|
note: '기산 재출정전은 추천 무장이 9명입니다. 공격로를 열 장수, 돌아올 표식을 세울 장수, 후방 장부를 맡길 장수 중 둘을 반드시 군영에 남겨야 합니다.'
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -1362,6 +1382,23 @@ const sortieRulesByCampaignStep: Partial<Record<CampaignStep, SortieRuleDefiniti
|
|
|
|
|
{ unitId: 'ma-dai', reason: '음평 물목의 기병 우회로를 다음 측면 대응 기준으로 정리합니다.' }
|
|
|
|
|
],
|
|
|
|
|
note: '한중 우로 방어 이후도 엔딩이 아니라 방어 책임이 넓어진 다음 북벌 준비입니다. 지킨 길을 공격로로 바꾸려면 누가 전방에 나가고 누가 보급을 붙들지 다시 골라야 합니다.'
|
|
|
|
|
},
|
|
|
|
|
'sixty-second-camp': {
|
|
|
|
|
maxUnits: 7,
|
|
|
|
|
requiredUnitIds: ['zhuge-liang'],
|
|
|
|
|
excludedUnitIds: ['liu-bei'],
|
|
|
|
|
recommended: [
|
|
|
|
|
{ unitId: 'zhuge-liang', reason: '기산 재출정 이후 더 깊은 북방 계산을 다시 세워야 하는 중심입니다.' },
|
|
|
|
|
{ unitId: 'jiang-wei', reason: '노성 앞에서 확인한 위군 지연선을 다음 공격로 지도로 정리합니다.' },
|
|
|
|
|
{ unitId: 'wei-yan', reason: '돌파가 성과를 냈을 때 어디까지 허용할지 다음 군령으로 남깁니다.' },
|
|
|
|
|
{ unitId: 'zhao-yun', reason: '장합 추격을 견딘 회수 기동을 예비대 훈련 기준으로 정리합니다.' },
|
|
|
|
|
{ unitId: 'wang-ping', reason: '기산 회수 표식과 진영 정지선을 다음 전선의 안전장치로 남깁니다.' },
|
|
|
|
|
{ unitId: 'huang-quan', reason: '노성 앞 공세가 실제로 소모한 군량과 남은 장부를 계산합니다.' },
|
|
|
|
|
{ unitId: 'ma-liang', reason: '전방 마을 안심 약속과 고시문을 다음 북벌 명분으로 이어 줍니다.' },
|
|
|
|
|
{ unitId: 'li-yan', reason: '운송 지연과 예비 수레 배정을 후방 기준으로 다시 정리합니다.' },
|
|
|
|
|
{ unitId: 'ma-dai', reason: '곽회 차단로 대응과 서량 기병 우회 기준을 다음 측면 운용에 반영합니다.' }
|
|
|
|
|
],
|
|
|
|
|
note: '기산 재출정 이후도 엔딩이 아니라 더 깊어진 북방 전선 준비입니다. 이긴 길을 지킬 사람과 더 깊이 들어갈 사람을 나누어 보십시오.'
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -6555,6 +6592,87 @@ const campDialogues: CampDialogue[] = [
|
|
|
|
|
rewardExp: 30
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 'northern-eighth-jiangwei-weiyan-forward',
|
|
|
|
|
title: '앞길을 여는 칼끝',
|
|
|
|
|
availableAfterBattleIds: [campBattleIds.sixtySecond],
|
|
|
|
|
unitIds: ['jiang-wei', 'wei-yan'],
|
|
|
|
|
bondId: 'jiang-wei__wei-yan_northern-eighth',
|
|
|
|
|
rewardExp: 100,
|
|
|
|
|
lines: [
|
|
|
|
|
'강유: 노성 앞에서는 빠른 길이 곧 안전한 길은 아니었습니다. 먼저 열어도 돌아올 표식이 없으면 길이 아닙니다.',
|
|
|
|
|
'위연: 그렇다면 다음에는 그대가 길을 고르고 내가 길을 넓히겠소. 대신 멈출 곳도 처음부터 말해 주시오.',
|
|
|
|
|
'강유: 전진선과 회수선을 함께 그리겠습니다. 돌파가 장수의 고집이 아니라 군의 길이 되도록 하겠습니다.'
|
|
|
|
|
],
|
|
|
|
|
choices: [
|
|
|
|
|
{
|
|
|
|
|
id: 'mark-breakthrough-return-line',
|
|
|
|
|
label: '돌파선과 회수선을 함께 긋는다',
|
|
|
|
|
response: '강유는 낮은 길을 지도에 표시했고, 위연은 그 선을 넘어설 때 필요한 깃발 신호를 따로 정했습니다.',
|
|
|
|
|
rewardExp: 35
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 'set-lucheng-pressure-rhythm',
|
|
|
|
|
label: '노성 압박 호흡을 맞춘다',
|
|
|
|
|
response: '위연은 성급한 돌파 대신 강유의 정찰 보고가 닿는 박자에 맞춰 전열을 흔들기로 했습니다.',
|
|
|
|
|
rewardExp: 32
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 'northern-eighth-zhaoyun-wangping-return',
|
|
|
|
|
title: '회수선의 표식',
|
|
|
|
|
availableAfterBattleIds: [campBattleIds.sixtySecond],
|
|
|
|
|
unitIds: ['zhao-yun', 'wang-ping'],
|
|
|
|
|
bondId: 'zhao-yun__wang-ping_northern-eighth',
|
|
|
|
|
rewardExp: 98,
|
|
|
|
|
lines: [
|
|
|
|
|
'조운: 장합의 기병은 길이 열린 순간보다 돌아가는 순간을 노렸습니다.',
|
|
|
|
|
'왕평: 그래서 표식은 앞에만 세우면 안 됩니다. 돌아오는 병사가 어둠 속에서도 볼 수 있어야 합니다.',
|
|
|
|
|
'조운: 다음에는 예비대가 표식을 따라 먼저 움직이겠습니다. 병사들이 표식을 보면 제 깃발도 함께 보게 하겠습니다.'
|
|
|
|
|
],
|
|
|
|
|
choices: [
|
|
|
|
|
{
|
|
|
|
|
id: 'pair-reserve-with-road-markers',
|
|
|
|
|
label: '예비대와 표식을 묶는다',
|
|
|
|
|
response: '왕평은 산길 표식을 다시 세웠고, 조운은 예비대가 어느 표식을 보면 즉시 움직일지 훈련 명령에 적었습니다.',
|
|
|
|
|
rewardExp: 34
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 'test-zhanghe-pursuit-drill',
|
|
|
|
|
label: '장합 추격 대비를 훈련한다',
|
|
|
|
|
response: '조운의 기동대가 일부러 늦게 물러났고, 왕평은 그 길목마다 병사들이 헷갈린 지점을 따로 고쳤습니다.',
|
|
|
|
|
rewardExp: 31
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 'northern-eighth-huangquan-maliang-ledger',
|
|
|
|
|
title: '장부와 고시문',
|
|
|
|
|
availableAfterBattleIds: [campBattleIds.sixtySecond],
|
|
|
|
|
unitIds: ['huang-quan', 'ma-liang'],
|
|
|
|
|
bondId: 'huang-quan__ma-liang_northern-eighth',
|
|
|
|
|
rewardExp: 96,
|
|
|
|
|
lines: [
|
|
|
|
|
'황권: 공세가 성공해도 장부가 비면 마을은 승리보다 징발을 먼저 기억합니다.',
|
|
|
|
|
'마량: 그래서 고시문은 승전 뒤가 아니라 출정 전부터 준비되어야 합니다. 약속이 늦으면 민심도 늦습니다.',
|
|
|
|
|
'황권: 다음 장부에는 군량 수치 옆에 고시문 날짜를 함께 적겠습니다.'
|
|
|
|
|
],
|
|
|
|
|
choices: [
|
|
|
|
|
{
|
|
|
|
|
id: 'bind-ledger-to-proclamation',
|
|
|
|
|
label: '장부와 고시문 날짜를 묶는다',
|
|
|
|
|
response: '황권은 군량 배분표 옆에 마량의 고시문 날짜를 적었고, 마량은 약속한 배분이 실제 수레에 실리는지 확인했습니다.',
|
|
|
|
|
rewardExp: 33
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 'prepare-front-village-reassurance',
|
|
|
|
|
label: '전방 마을 안심 문서를 준비한다',
|
|
|
|
|
response: '마량은 노성 앞 마을에 붙일 문서를 고쳤고, 황권은 그 문서가 지킬 수 있는 군량 수치를 함께 봉했습니다.',
|
|
|
|
|
rewardExp: 30
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
@@ -9341,6 +9459,36 @@ const campVisits: CampVisitDefinition[] = [
|
|
|
|
|
itemRewards: ['쌀 34', '상처약 24']
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 'northern-eighth-lucheng-supply-table',
|
|
|
|
|
title: '노성 앞 보급 탁자',
|
|
|
|
|
location: '기산 재출정 군막',
|
|
|
|
|
availableAfterBattleIds: [campBattleIds.sixtySecond],
|
|
|
|
|
bondId: 'huang-quan__ma-liang_northern-eighth',
|
|
|
|
|
description: '황권과 마량이 노성 앞 전진로, 마을 안심 약속, 다음 북벌의 실제 군량 여유를 하나의 탁자 위에서 맞춥니다.',
|
|
|
|
|
lines: [
|
|
|
|
|
'마량: 전투가 이긴 뒤에 붙이는 고시문은 늦습니다. 마을은 군량이 지나간 자리를 먼저 봅니다.',
|
|
|
|
|
'황권: 그렇다면 장부의 첫 줄을 병사 몫이 아니라 지나갈 마을 몫으로 두겠습니다.',
|
|
|
|
|
'군막의 탁자에는 노성 앞 길과 회수 진영, 전방 마을의 약속이 한 장의 지도로 묶였습니다.'
|
|
|
|
|
],
|
|
|
|
|
choices: [
|
|
|
|
|
{
|
|
|
|
|
id: 'seal-lucheng-supply-ledger',
|
|
|
|
|
label: '기산 재출정 장부를 봉한다',
|
|
|
|
|
response: '황권은 노성 앞에서 쓴 군량과 남은 수레를 봉했고, 마량은 그 장부를 다음 고시문 기준으로 삼았습니다.',
|
|
|
|
|
bondExp: 82,
|
|
|
|
|
itemRewards: ['기산 재출정 장부 1']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 'reserve-front-village-grain',
|
|
|
|
|
label: '전방 마을 예비 군량을 남긴다',
|
|
|
|
|
response: '마량은 마을 이름을 하나씩 불렀고, 황권은 그 이름 옆에 실제로 남길 군량 숫자를 적었습니다.',
|
|
|
|
|
bondExp: 76,
|
|
|
|
|
gold: 2860,
|
|
|
|
|
itemRewards: ['쌀 36', '상처약 26']
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
@@ -9450,7 +9598,8 @@ export class CampScene extends Phaser.Scene {
|
|
|
|
|
battleId === campBattleIds.fiftyEighth ||
|
|
|
|
|
battleId === campBattleIds.fiftyNinth ||
|
|
|
|
|
battleId === campBattleIds.sixtieth ||
|
|
|
|
|
battleId === campBattleIds.sixtyFirst
|
|
|
|
|
battleId === campBattleIds.sixtyFirst ||
|
|
|
|
|
battleId === campBattleIds.sixtySecond
|
|
|
|
|
) {
|
|
|
|
|
this.campaign = ensureCampaignRosterUnits(
|
|
|
|
|
[
|
|
|
|
|
@@ -9471,7 +9620,7 @@ export class CampScene extends Phaser.Scene {
|
|
|
|
|
...hanzhongOpeningRecruitUnits,
|
|
|
|
|
...hanzhongScoutRecruitUnits,
|
|
|
|
|
...hanzhongMainRecruitUnits,
|
|
|
|
|
...(battleId === campBattleIds.fiftySeventh || battleId === campBattleIds.fiftyEighth || battleId === campBattleIds.fiftyNinth || battleId === campBattleIds.sixtieth || battleId === campBattleIds.sixtyFirst ? jiangWeiRecruitUnits : [])
|
|
|
|
|
...(battleId === campBattleIds.fiftySeventh || battleId === campBattleIds.fiftyEighth || battleId === campBattleIds.fiftyNinth || battleId === campBattleIds.sixtieth || battleId === campBattleIds.sixtyFirst || battleId === campBattleIds.sixtySecond ? jiangWeiRecruitUnits : [])
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
...xuzhouRecruitBonds,
|
|
|
|
|
@@ -9511,12 +9660,13 @@ export class CampScene extends Phaser.Scene {
|
|
|
|
|
...mengHuoFinalCaptureBonds,
|
|
|
|
|
...northernFirstBattleBonds,
|
|
|
|
|
...northernSecondBattleBonds,
|
|
|
|
|
...(battleId === campBattleIds.fiftySeventh || battleId === campBattleIds.fiftyEighth || battleId === campBattleIds.fiftyNinth || battleId === campBattleIds.sixtieth || battleId === campBattleIds.sixtyFirst ? northernThirdBattleBonds : []),
|
|
|
|
|
...(battleId === campBattleIds.fiftySeventh || battleId === campBattleIds.fiftyEighth || battleId === campBattleIds.fiftyNinth || battleId === campBattleIds.sixtieth || battleId === campBattleIds.sixtyFirst ? jiangWeiRecruitBonds : []),
|
|
|
|
|
...(battleId === campBattleIds.fiftyEighth || battleId === campBattleIds.fiftyNinth || battleId === campBattleIds.sixtieth || battleId === campBattleIds.sixtyFirst ? northernFourthBattleBonds : []),
|
|
|
|
|
...(battleId === campBattleIds.fiftyNinth || battleId === campBattleIds.sixtieth || battleId === campBattleIds.sixtyFirst ? northernFifthBattleBonds : []),
|
|
|
|
|
...(battleId === campBattleIds.sixtieth || battleId === campBattleIds.sixtyFirst ? northernSixthBattleBonds : []),
|
|
|
|
|
...(battleId === campBattleIds.sixtyFirst ? northernSeventhBattleBonds : [])
|
|
|
|
|
...(battleId === campBattleIds.fiftySeventh || battleId === campBattleIds.fiftyEighth || battleId === campBattleIds.fiftyNinth || battleId === campBattleIds.sixtieth || battleId === campBattleIds.sixtyFirst || battleId === campBattleIds.sixtySecond ? northernThirdBattleBonds : []),
|
|
|
|
|
...(battleId === campBattleIds.fiftySeventh || battleId === campBattleIds.fiftyEighth || battleId === campBattleIds.fiftyNinth || battleId === campBattleIds.sixtieth || battleId === campBattleIds.sixtyFirst || battleId === campBattleIds.sixtySecond ? jiangWeiRecruitBonds : []),
|
|
|
|
|
...(battleId === campBattleIds.fiftyEighth || battleId === campBattleIds.fiftyNinth || battleId === campBattleIds.sixtieth || battleId === campBattleIds.sixtyFirst || battleId === campBattleIds.sixtySecond ? northernFourthBattleBonds : []),
|
|
|
|
|
...(battleId === campBattleIds.fiftyNinth || battleId === campBattleIds.sixtieth || battleId === campBattleIds.sixtyFirst || battleId === campBattleIds.sixtySecond ? northernFifthBattleBonds : []),
|
|
|
|
|
...(battleId === campBattleIds.sixtieth || battleId === campBattleIds.sixtyFirst || battleId === campBattleIds.sixtySecond ? northernSixthBattleBonds : []),
|
|
|
|
|
...(battleId === campBattleIds.sixtyFirst || battleId === campBattleIds.sixtySecond ? northernSeventhBattleBonds : []),
|
|
|
|
|
...(battleId === campBattleIds.sixtySecond ? northernEighthBattleBonds : [])
|
|
|
|
|
]
|
|
|
|
|
);
|
|
|
|
|
this.report = this.campaign.firstBattleReport ?? this.report;
|
|
|
|
|
@@ -10157,6 +10307,9 @@ export class CampScene extends Phaser.Scene {
|
|
|
|
|
if (this.campaign?.step === 'northern-campaign-prep-camp') {
|
|
|
|
|
return '북벌 준비 군영';
|
|
|
|
|
}
|
|
|
|
|
if (battleId === campBattleIds.sixtySecond) {
|
|
|
|
|
return '기산 재출정 후 군영';
|
|
|
|
|
}
|
|
|
|
|
if (battleId === campBattleIds.sixtyFirst) {
|
|
|
|
|
return '한중 우로 방어 후 군영';
|
|
|
|
|
}
|
|
|
|
|
|