Add Jiameng Pass Ma Chao chapter

This commit is contained in:
2026-06-23 13:01:25 +09:00
parent aca7d6568a
commit edbdaac773
11 changed files with 878 additions and 40 deletions

View File

@@ -19,6 +19,8 @@ import {
fuPassRecruitUnits,
guiyangRecruitBonds,
guiyangRecruitUnits,
hanzhongOpeningRecruitBonds,
hanzhongOpeningRecruitUnits,
jingzhouRecruitBonds,
jingzhouRecruitUnits,
liuBiaoRecruitBonds,
@@ -337,7 +339,7 @@ const campaignTimelineChapters: CampaignTimelineChapter[] = [
title: '촉한 건국',
period: '한실을 잇는 깃발',
description: '여러 전장을 지나 촉한을 세우고 북벌을 바라보는 장기 목표입니다.',
battleIds: [],
battleIds: ['thirty-fourth-battle-jiameng-pass'],
nextHints: ['왕업 선언', '오호대장군', '북벌 준비']
}
];
@@ -375,7 +377,8 @@ const campBattleIds = {
thirtieth: 'thirtieth-battle-luofeng-ambush',
thirtyFirst: 'thirty-first-battle-luo-main-gate',
thirtySecond: 'thirty-second-battle-mianzhu-gate',
thirtyThird: 'thirty-third-battle-chengdu-surrender'
thirtyThird: 'thirty-third-battle-chengdu-surrender',
thirtyFourth: 'thirty-fourth-battle-jiameng-pass'
} as const;
const requiredSortieUnitIds = new Set(['liu-bei']);
@@ -746,6 +749,18 @@ const sortieRulesByBattleId: Partial<Record<BattleScenarioId, SortieRuleDefiniti
{ unitId: 'wu-yi', reason: '성도 외곽 길과 창고 위치를 아는 현지 장수입니다.' }
],
note: '성도 항복 권고전은 열여덟 명 중 여섯 명만 출전합니다. 새로 합류한 이엄을 데려가면 설득과 생존 목표가 맞물리고, 책사 비중을 늘리면 항복 명분이 강해집니다.'
},
'thirty-fourth-battle-jiameng-pass': {
maxUnits: 6,
recommended: [
{ unitId: 'liu-bei', reason: '가맹관에서 마초를 받아들일 명분과 패배 조건의 중심입니다.' },
{ unitId: 'huang-quan', reason: '황권의 첫 출전입니다. 익주 북문과 한중 길을 해석하는 현지 참모입니다.' },
{ unitId: 'zhao-yun', reason: '서량 기병의 돌격을 기동으로 받아내고 역습하기 좋습니다.' },
{ unitId: 'zhang-fei', reason: '마초의 돌격을 정면에서 받아낼 전열 압박이 필요합니다.' },
{ unitId: 'fa-zheng', reason: '마초가 장로에게 마음을 다 주지 못한 틈을 읽는 책사입니다.' },
{ unitId: 'huang-zhong', reason: '산허리 궁병과 기병 돌격을 안정적으로 견제합니다.' }
],
note: '가맹관 마초 대면전은 열아홉 명 중 여섯 명만 출전합니다. 황권을 데려가면 한중 길 해석과 생존 목표가 맞물리고, 기병 대응 무장을 고르는 압박이 커집니다.'
}
};
@@ -3503,6 +3518,87 @@ const campDialogues: CampDialogue[] = [
rewardExp: 12
}
]
},
{
id: 'liu-ma-after-jiameng',
title: '떠도는 창과 새 깃발',
availableAfterBattleIds: [campBattleIds.thirtyFourth],
unitIds: ['liu-bei', 'ma-chao'],
bondId: 'liu-bei__ma-chao',
rewardExp: 40,
lines: [
'마초: 저는 조조를 미워했고, 장로에게 기대었으나 마음 둘 곳을 찾지 못했습니다.',
'유비: 떠돌던 창도 지킬 백성과 뜻을 만나면 깃발 아래 설 수 있소. 그대의 용맹을 사람을 살리는 데 쓰시오.',
'마초: 그렇다면 서량의 창은 더는 원한만 좇지 않겠습니다. 유비공의 깃발 아래에서 북쪽 길을 열겠습니다.'
],
choices: [
{
id: 'accept-ma-chao-oath',
label: '마초의 맹세를 받아들인다',
response: '유비가 직접 마초의 창을 들어 올리자, 서량 기병들은 새 깃발 앞에서 고개를 숙였습니다.',
rewardExp: 15
},
{
id: 'ask-ma-chao-hanzhong-road',
label: '한중 길을 묻는다',
response: '마초는 장로군의 관문, 기병이 달릴 수 있는 능선, 조조군의 감시 지점을 지도에 표시했습니다.',
rewardExp: 14
}
]
},
{
id: 'zhao-ma-after-jiameng',
title: '백마와 금마초',
availableAfterBattleIds: [campBattleIds.thirtyFourth],
unitIds: ['zhao-yun', 'ma-chao'],
bondId: 'zhao-yun__ma-chao',
rewardExp: 36,
lines: [
'조운: 서량 기병의 돌격은 빠르나, 빠른 창일수록 돌아올 길도 보아야 합니다.',
'마초: 백마 장군의 말은 조용하지만 빈틈이 없군. 내 창은 때로 너무 멀리 나갔습니다.',
'조운: 다음 전장에서는 서로의 말발굽이 너무 멀어지지 않게 합시다.'
],
choices: [
{
id: 'practice-cavalry-turn',
label: '기병 회전을 연습한다',
response: '조운의 절제된 말놀림과 마초의 폭발적인 돌격이 이어지며, 기병대의 움직임이 한층 깊어졌습니다.',
rewardExp: 13
},
{
id: 'share-scouting-pace',
label: '정찰 속도를 맞춘다',
response: '두 장수는 빠른 돌파와 안전한 귀환의 간격을 맞추며 한중 전선의 정찰 기준을 세웠습니다.',
rewardExp: 12
}
]
},
{
id: 'zhang-ma-after-jiameng',
title: '호통과 돌격',
availableAfterBattleIds: [campBattleIds.thirtyFourth],
unitIds: ['zhang-fei', 'ma-chao'],
bondId: 'zhang-fei__ma-chao',
rewardExp: 36,
lines: [
'장비: 하하! 네놈 창끝이 제법 매섭더군. 그래도 내 앞에서는 한 번 멈췄지 않느냐!',
'마초: 장비 장군의 호통도 말발굽을 흔들 만큼 거칠었습니다. 다음에는 같은 방향으로 흔들어 보지요.',
'장비: 좋다! 누가 먼저 적진을 갈라 놓는지 겨뤄 보자.'
],
choices: [
{
id: 'promise-front-duel',
label: '전열 돌파를 겨룬다',
response: '장비와 마초가 웃으며 창을 맞대자, 병사들은 다음 전열 돌파가 조금 두려우면서도 기대된다고 수군거렸습니다.',
rewardExp: 13
},
{
id: 'split-shock-roles',
label: '돌격 역할을 나눈다',
response: '장비는 좁은 길을 부수고, 마초는 열린 측면을 파고드는 방식으로 서로의 돌격을 나누었습니다.',
rewardExp: 12
}
]
}
];
@@ -4612,6 +4708,66 @@ const campVisits: CampVisitDefinition[] = [
itemRewards: ['한중 길 초안 1']
}
]
},
{
id: 'jiameng-stable-mustering',
title: '가맹관 마구간 정비',
location: '가맹관 마구간',
availableAfterBattleIds: [campBattleIds.thirtyFourth],
bondId: 'liu-bei__ma-chao',
description: '마초가 합류한 뒤 서량 기병의 말과 유비군의 보급 체계를 함께 맞춥니다.',
lines: [
'마초: 서량 말은 성질이 급합니다. 배불리 먹이고 달릴 길을 먼저 보여 주어야 힘을 냅니다.',
'유비: 우리 군영의 말과 사람도 그대의 길에 맞추어 배워야 하오. 북쪽 길은 이제 함께 열 길이오.',
'마구간에는 새로 들어온 서량 말의 숨소리가 가득했고, 병사들은 다음 출전 명단을 떠올리며 고삐를 고쳤습니다.'
],
choices: [
{
id: 'align-cavalry-feed',
label: '말먹이 기준을 맞춘다',
response: '서량 말의 먹이와 휴식 기준이 정리되자, 마초의 기병대가 유비군의 행군 속도에 맞춰 움직이기 시작했습니다.',
bondExp: 30,
itemRewards: ['콩 8', '탁주 3']
},
{
id: 'mark-cavalry-routes',
label: '기병 돌파로를 표시한다',
response: '마초가 지도 위에 기병이 달릴 수 있는 능선과 피해야 할 늪길을 표시했습니다.',
bondExp: 28,
gold: 520,
itemRewards: ['서량 말먹이 1']
}
]
},
{
id: 'hanzhong-front-council',
title: '한중 전선 회의',
location: '가맹관 본막',
availableAfterBattleIds: [campBattleIds.thirtyFourth],
bondId: 'zhao-yun__ma-chao',
description: '조운과 마초가 한중으로 이어지는 관문, 산길, 기병 운용을 놓고 다음 출전 구성을 논의합니다.',
lines: [
'조운: 가맹관을 넘었다고 길이 열린 것은 아닙니다. 좁은 산길에서는 빠른 말도 한 번 멈춰야 합니다.',
'마초: 멈출 곳을 알면 더 세게 달릴 수 있지요. 장로의 군세와 조조의 눈이 모두 북쪽 길에 걸려 있습니다.',
'본막의 지도 위에는 한중 전선과 촉한 건국의 다음 숙제가 한 줄로 이어졌습니다.'
],
choices: [
{
id: 'plan-hanzhong-scouting',
label: '한중 정찰을 준비한다',
response: '조운의 정찰 기준과 마초의 기병 감각이 합쳐져, 다음 장의 출전 후보가 더 분명해졌습니다.',
bondExp: 30,
itemRewards: ['한중 정찰도 1']
},
{
id: 'divide-pass-roles',
label: '관문 돌파 역할을 나눈다',
response: '조운은 후방을 지키고 마초는 전열을 찌르는 방식으로, 두 기병장의 역할이 정리되었습니다.',
bondExp: 28,
gold: 540,
itemRewards: ['가맹관 전술 기록 1']
}
]
}
];
@@ -4698,6 +4854,47 @@ export class CampScene extends Phaser.Scene {
return;
}
if (battleId === campBattleIds.thirtyFourth) {
this.campaign = ensureCampaignRosterUnits(
[
...xuzhouRecruitUnits,
...caoBreakRecruitUnits,
...liuBiaoRecruitUnits,
...zhugeRecruitUnits,
...jingzhouRecruitUnits,
...guiyangRecruitUnits,
...wulingRecruitUnits,
...changshaRecruitUnits,
...yizhouRecruitUnits,
...fuPassRecruitUnits,
...luoCastleRecruitUnits,
...luoCastleProperRecruitUnits,
...chengduPressureRecruitUnits,
...chengduSurrenderRecruitUnits,
...hanzhongOpeningRecruitUnits
],
[
...xuzhouRecruitBonds,
...caoBreakRecruitBonds,
...liuBiaoRecruitBonds,
...zhugeRecruitBonds,
...jingzhouRecruitBonds,
...guiyangRecruitBonds,
...wulingRecruitBonds,
...changshaRecruitBonds,
...yizhouRecruitBonds,
...fuPassRecruitBonds,
...luoCastleRecruitBonds,
...luoCastleProperRecruitBonds,
...chengduPressureRecruitBonds,
...chengduSurrenderRecruitBonds,
...hanzhongOpeningRecruitBonds
]
);
this.report = this.campaign.firstBattleReport ?? this.report;
return;
}
if (battleId === campBattleIds.thirtyThird) {
this.campaign = ensureCampaignRosterUnits(
[
@@ -5050,6 +5247,9 @@ export class CampScene extends Phaser.Scene {
private currentCampTitle() {
const battleId = this.currentCampBattleId();
if (battleId === campBattleIds.thirtyFourth) {
return '가맹관 대면전 후 군영';
}
if (battleId === campBattleIds.thirtyThird) {
return '성도 항복 후 군영';
}