Add Jing Province defense vanguard chapter

This commit is contained in:
2026-06-23 15:00:54 +09:00
parent 63ac73f08b
commit 8585fec6b5
11 changed files with 898 additions and 48 deletions

View File

@@ -26,6 +26,7 @@ import {
hanzhongMainRecruitUnits,
hanzhongScoutRecruitBonds,
hanzhongScoutRecruitUnits,
jingDefenseBonds,
jingzhouRecruitBonds,
jingzhouRecruitUnits,
liuBiaoRecruitBonds,
@@ -348,7 +349,8 @@ const campaignTimelineChapters: CampaignTimelineChapter[] = [
'thirty-fourth-battle-jiameng-pass',
'thirty-fifth-battle-yangping-scout',
'thirty-sixth-battle-dingjun-vanguard',
'thirty-seventh-battle-hanzhong-decisive'
'thirty-seventh-battle-hanzhong-decisive',
'thirty-eighth-battle-jing-defense'
],
nextHints: ['왕업 선언', '오호대장군', '북벌 준비']
}
@@ -391,7 +393,8 @@ const campBattleIds = {
thirtyFourth: 'thirty-fourth-battle-jiameng-pass',
thirtyFifth: 'thirty-fifth-battle-yangping-scout',
thirtySixth: 'thirty-sixth-battle-dingjun-vanguard',
thirtySeventh: 'thirty-seventh-battle-hanzhong-decisive'
thirtySeventh: 'thirty-seventh-battle-hanzhong-decisive',
thirtyEighth: 'thirty-eighth-battle-jing-defense'
} as const;
const requiredSortieUnitIds = new Set(['liu-bei']);
@@ -811,6 +814,19 @@ const sortieRulesByBattleId: Partial<Record<BattleScenarioId, SortieRuleDefiniti
{ unitId: 'zhuge-liang', reason: '한중 승리 이후 한중왕 즉위와 촉한 건국 흐름까지 설계합니다.' }
],
note: '한중 결전은 스물두 명 중 일곱 명만 출전합니다. 왕평까지 합류한 뒤 처음으로 출전 슬롯이 늘지만, 여전히 핵심 무장과 보조 참모를 모두 담기는 어렵습니다.'
},
'thirty-eighth-battle-jing-defense': {
maxUnits: 7,
recommended: [
{ unitId: 'liu-bei', reason: '촉한의 이름을 세운 뒤 형주 방위 명분을 직접 확인합니다.' },
{ unitId: 'guan-yu', reason: '형주 방위 전초전의 핵심 장수이며 생존 목표입니다.' },
{ unitId: 'zhang-fei', reason: '관우의 전열 압박을 보조하며 강한 정면 대응을 맡습니다.' },
{ unitId: 'ma-liang', reason: '형주 민심과 강변 마을을 읽는 현지 책사입니다.' },
{ unitId: 'mi-zhu', reason: '강릉과 나루 사이 보급을 안정시키는 군량관입니다.' },
{ unitId: 'zhuge-liang', reason: '촉한 건국 직후 형주 전선의 정치적 위험을 해석합니다.' },
{ unitId: 'zhao-yun', reason: '강변 기동대와 기병 대응을 안정적으로 맡습니다.' }
],
note: '형주 방위 전초전은 스물두 명 중 일곱 명만 출전합니다. 관우를 중심으로 민심, 보급, 기동을 어떻게 묶을지 고르는 전투입니다.'
}
};
@@ -3892,6 +3908,87 @@ const campDialogues: CampDialogue[] = [
rewardExp: 13
}
]
},
{
id: 'guan-ma-after-jing-defense',
title: '형주 문무',
availableAfterBattleIds: [campBattleIds.thirtyEighth],
unitIds: ['guan-yu', 'ma-liang'],
bondId: 'guan-yu__ma-liang',
rewardExp: 40,
lines: [
'마량: 형주는 칼보다 먼저 민심이 흔들리는 곳입니다. 봉화대 하나를 세우는 일도 백성에게는 약속으로 보입니다.',
'관우: 내 칼이 먼저 서면 백성이 두려워하겠지. 그대의 붓이 길을 가리켜 주면, 칼은 그 뒤를 따르겠소.',
'마량: 그렇다면 강릉의 문서와 나루의 곡식을 함께 묶겠습니다. 백성이 먼저 안심해야 군도 오래 섭니다.'
],
choices: [
{
id: 'bind-jing-letters',
label: '형주 문서를 정리한다',
response: '관우는 마량에게 군령과 민심 고시를 함께 맡겼고, 형주 방위의 말길이 조금 더 단단해졌습니다.',
rewardExp: 15
},
{
id: 'share-front-duty',
label: '전선 책임을 나눈다',
response: '마량은 봉화대와 마을의 순서를 다시 적었고, 관우는 병사들에게 백성을 먼저 안심시키라 명했습니다.',
rewardExp: 14
}
]
},
{
id: 'guan-mi-after-jing-defense',
title: '강릉 보급',
availableAfterBattleIds: [campBattleIds.thirtyEighth],
unitIds: ['guan-yu', 'mi-zhu'],
bondId: 'guan-yu__mi-zhu',
rewardExp: 38,
lines: [
'미축: 강릉의 창고는 큰데, 강을 오가는 길은 좁습니다. 나루가 흔들리면 병력보다 곡식이 먼저 끊깁니다.',
'관우: 적이 칼을 들기 전에 군량을 흔드는 셈이군. 그대가 길을 맡아 주면 나는 봉화대를 지키겠소.',
'미축: 그리하겠습니다. 보급은 조용해야 하지만, 끊겼을 때는 가장 크게 들리는 법입니다.'
],
choices: [
{
id: 'secure-river-stores',
label: '강릉 창고를 나눈다',
response: '미축은 창고를 작은 단위로 나누어 표식을 붙였고, 관우군의 나루 보급선이 더 질겨졌습니다.',
rewardExp: 14
},
{
id: 'guard-supply-boats',
label: '보급선 호위를 세운다',
response: '관우는 보급선에 소규모 호위를 붙였고, 미축은 강변 상인들의 불안을 누그러뜨렸습니다.',
rewardExp: 13
}
]
},
{
id: 'guan-wang-after-jing-defense',
title: '강과 산의 방어',
availableAfterBattleIds: [campBattleIds.thirtyEighth],
unitIds: ['guan-yu', 'wang-ping'],
bondId: 'guan-yu__wang-ping',
rewardExp: 36,
lines: [
'왕평: 한중의 산길과 형주의 강길은 다르지만, 길을 잃은 병사가 무너지는 것은 같습니다.',
'관우: 그대는 길을 보는 눈이 있소. 강변에서도 산길의 차분함을 잃지 말아 주시오.',
'왕평: 급히 쫓는 병사는 물가에서 더 흔들립니다. 저는 퇴로와 표식을 먼저 세우겠습니다.'
],
choices: [
{
id: 'mark-jing-retreat-routes',
label: '퇴로 표식을 세운다',
response: '왕평은 강변과 숲길의 표식을 정리했고, 관우는 기동대가 무리하게 깊이 들어가지 않도록 명했습니다.',
rewardExp: 13
},
{
id: 'teach-river-discipline',
label: '강변 진형을 익힌다',
response: '왕평의 차분한 훈련으로 강변 병사들의 이동 순서가 안정되었고, 관우는 그 실용성을 높이 샀습니다.',
rewardExp: 12
}
]
}
];
@@ -5241,6 +5338,66 @@ const campVisits: CampVisitDefinition[] = [
itemRewards: ['말먹이 2', '활시위 2']
}
]
},
{
id: 'jing-beacon-repair',
title: '형주 봉화대 보수',
location: '강릉 북쪽 봉화대',
availableAfterBattleIds: [campBattleIds.thirtyEighth],
bondId: 'guan-yu__ma-liang',
description: '관우와 마량이 강릉 북쪽 봉화대를 돌아보며, 위와 오의 움직임을 빠르게 알릴 길을 정비합니다.',
lines: [
'마량: 봉화가 늦으면 강릉은 적을 눈앞에 두고서야 알게 됩니다.',
'관우: 봉화대가 칼보다 먼저 움직여야 하겠군. 이곳은 반드시 고치겠소.',
'병사들은 젖은 장작을 걷어 내고 새 기둥을 세우며, 강변 초소의 신호 순서를 다시 익혔습니다.'
],
choices: [
{
id: 'raise-beacon-watch',
label: '봉화 감시조를 세운다',
response: '감시조가 밤낮으로 교대하게 되어 형주의 첫 경보선이 더 빨라졌습니다.',
bondExp: 32,
itemRewards: ['형주 봉화도 1']
},
{
id: 'share-warning-orders',
label: '경보 군령을 돌린다',
response: '마량은 각 마을에 같은 경보 문구를 전했고, 관우군의 대응 순서가 선명해졌습니다.',
bondExp: 30,
gold: 640,
itemRewards: ['상처약 4']
}
]
},
{
id: 'jing-river-patrol',
title: '강릉 나루 순찰',
location: '강릉 동쪽 나루',
availableAfterBattleIds: [campBattleIds.thirtyEighth],
bondId: 'guan-yu__mi-zhu',
description: '관우와 미축이 상선과 군량선을 함께 살피며, 다음 형주 전선을 위한 강변 보급을 다집니다.',
lines: [
'미축: 상선이 두려워하면 군량선도 늦어집니다. 나루의 신뢰가 전선의 속도입니다.',
'관우: 백성이 오가는 길을 지켜야 군도 부끄럽지 않소.',
'강변 상인들은 군량 표식을 새로 확인했고, 병사들은 짐을 옮기는 순서를 다시 맞췄습니다.'
],
choices: [
{
id: 'escort-river-merchants',
label: '상선 호위를 약속한다',
response: '나루 상인들이 길을 다시 열며 관우군의 강변 보급이 안정되었습니다.',
bondExp: 30,
gold: 700,
itemRewards: ['콩 10']
},
{
id: 'store-river-medicine',
label: '나루 약재를 비축한다',
response: '미축은 상처약과 탁주를 군량선 가까이에 나누어 실었고, 장기전 준비가 조금 더 단단해졌습니다.',
bondExp: 28,
itemRewards: ['상처약 5', '탁주 2']
}
]
}
];
@@ -5327,6 +5484,53 @@ export class CampScene extends Phaser.Scene {
return;
}
if (battleId === campBattleIds.thirtyEighth) {
this.campaign = ensureCampaignRosterUnits(
[
...xuzhouRecruitUnits,
...caoBreakRecruitUnits,
...liuBiaoRecruitUnits,
...zhugeRecruitUnits,
...jingzhouRecruitUnits,
...guiyangRecruitUnits,
...wulingRecruitUnits,
...changshaRecruitUnits,
...yizhouRecruitUnits,
...fuPassRecruitUnits,
...luoCastleRecruitUnits,
...luoCastleProperRecruitUnits,
...chengduPressureRecruitUnits,
...chengduSurrenderRecruitUnits,
...hanzhongOpeningRecruitUnits,
...hanzhongScoutRecruitUnits,
...hanzhongMainRecruitUnits
],
[
...xuzhouRecruitBonds,
...caoBreakRecruitBonds,
...liuBiaoRecruitBonds,
...zhugeRecruitBonds,
...jingzhouRecruitBonds,
...guiyangRecruitBonds,
...wulingRecruitBonds,
...changshaRecruitBonds,
...yizhouRecruitBonds,
...fuPassRecruitBonds,
...luoCastleRecruitBonds,
...luoCastleProperRecruitBonds,
...chengduPressureRecruitBonds,
...chengduSurrenderRecruitBonds,
...hanzhongOpeningRecruitBonds,
...hanzhongScoutRecruitBonds,
...hanzhongMainRecruitBonds,
...hanzhongDecisiveBonds,
...jingDefenseBonds
]
);
this.report = this.campaign.firstBattleReport ?? this.report;
return;
}
if (battleId === campBattleIds.thirtySeventh) {
this.campaign = ensureCampaignRosterUnits(
[
@@ -5860,6 +6064,9 @@ export class CampScene extends Phaser.Scene {
if (this.campaign?.step === 'hanzhong-king-camp') {
return '한중왕 즉위 준비 군영';
}
if (battleId === campBattleIds.thirtyEighth) {
return '형주 방위 전초전 후 군영';
}
if (battleId === campBattleIds.thirtySeventh) {
return '한중 결전 후 군영';
}
@@ -6981,13 +7188,11 @@ export class CampScene extends Phaser.Scene {
activeChapterIndex,
activeChapter,
latestBattleTitle: latestBattleId ? getBattleScenario(latestBattleId).title : '없음',
nextBattleTitle: this.campaign?.step === 'shu-han-foundation-camp'
? '형주 방위 긴장'
: nextBattleId
? getBattleScenario(nextBattleId).title
: flow.campaignStep
? flow.title
: '준비 중'
nextBattleTitle: nextBattleId
? getBattleScenario(nextBattleId).title
: flow.campaignStep
? flow.title
: '준비 중'
};
}