Refine Jiangdong envoy battle flow

This commit is contained in:
2026-07-04 18:04:06 +09:00
parent 3336b5edbc
commit 51df622fd6
4 changed files with 121 additions and 23 deletions

View File

@@ -2672,16 +2672,80 @@ export const twentiethBattleScenario: BattleScenarioDefinition = {
victoryConditionLabel: '문빙 퇴각', victoryConditionLabel: '문빙 퇴각',
defeatConditionLabel: '유비, 제갈량 또는 손건 퇴각', defeatConditionLabel: '유비, 제갈량 또는 손건 퇴각',
openingObjectiveLines: [ openingObjectiveLines: [
'장판파를 벗어난 유비군은 강동과 손잡을 사절을 보내야 합니다. 문빙의 추격대가 강나루기 전에 길을 열어야 합니다.', '장판파를 벗어난 유비군은 강동에 보낼 사절 문서를 하구 나루까지 옮겨야 합니다. 문빙의 추격대가 강변 길목과 포구기 전에 길을 열어야 합니다.',
'이번 전투는 제갈량과 손건을 지키는 것이 핵심입니다. 전열이 다리목을 붙들고, 기동 장수가 추격 기병을 끊어야 사절 문서가 강동으로 향할 수 있습니다.', '제갈량과 손건은 뒤에서 문서와 회담 논리를 지키고, 조운은 추격 기병을 끊으며 전열 장수는 강변 길목을 붙드십시오.',
'문빙을 퇴각시키고 강나루를 확보하십시오. 제갈량과 손건이 살아남으면 적벽대전으로 향할 외교 명분이 완성됩니다.' '문빙을 퇴각시키고 강변 접선지와 강나루를 확보하십시오. 제갈량과 손건이 살아남으면 적벽대전으로 향할 외교 명분이 완성됩니다.'
], ],
tacticalGuide: {
summary: '서남쪽 피난 진영에서 출발해 강변 접선지를 잡고, 길목의 추격 기병을 끊은 뒤 동쪽 강나루를 열어 문빙을 몰아내는 사절 호위전입니다.',
route: '서남 피난 진영 → 강변 접선지 → 하구 나루 → 문빙 본대',
focus:
'제갈량과 손건을 무리하게 앞으로 세우지 말고, 조운으로 중간 추격 기병을 끊어 사절 문서가 지나갈 틈을 만드십시오. 관우와 장비는 강변 길목의 보병을 받아내고, 유비는 후방에서 사절단의 퇴로를 유지해야 합니다.',
roles: [
'유비: 후방 지휘와 사절단 퇴로 유지',
'제갈량: 강동 설득 논리와 책략 지원',
'손건: 사절 문서와 회담 기록 보존',
'조운: 추격 기병 차단과 측면 호위',
'관우: 강변 길목 전열 유지',
'장비: 포구 수비대 돌파'
],
events: {
'village-approach': {
title: '강변 접선지 접근',
lines: [
'이 접선지를 잡으면 사절 문서를 나루까지 옮길 길이 보입니다.',
'제갈량과 손건은 전열 뒤에 두고, 조운이 먼저 추격 기병을 끊어 통로를 여십시오.'
]
},
'cavalry-approach': {
title: '추격 기병 압박',
lines: [
'문빙의 기병이 강변 길목으로 파고듭니다.',
'조운을 측면으로 돌리고 관우와 장비가 길목을 눌러야 사절단이 뒤에서 무너지지 않습니다.'
]
},
'leader-wavering': {
title: '문빙 본대 동요',
lines: [
'접선지와 포구가 모두 열리자 문빙의 추격선이 길게 늘어졌습니다.',
'남은 수비대를 정리하고 문빙을 몰아내면 강동 회담으로 이어질 길이 열립니다.'
]
}
}
},
sortie: {
sortieLimit: 6,
requiredUnits: ['liu-bei', 'zhuge-liang', 'sun-qian'],
recommendedUnits: [
{ unitId: 'liu-bei', role: 'reserve', reason: '사절을 보내는 결단과 패배 조건의 중심입니다.' },
{ unitId: 'zhuge-liang', role: 'support', reason: '강동 설득 논리를 지키는 핵심 인물이며 반드시 보호해야 합니다.' },
{ unitId: 'sun-qian', role: 'support', reason: '사절 문서와 회담 기록을 맡는 생존 목표입니다.' },
{ unitId: 'zhao-yun', role: 'flank', reason: '추격 기병을 끊고 사절의 측면을 지키는 데 좋습니다.' },
{ unitId: 'guan-yu', role: 'front', reason: '강변 길목에서 보병 전열과 포구 수비대를 받아냅니다.' },
{ unitId: 'zhang-fei', role: 'front', reason: '포구 수비대를 빠르게 흔들어 사절단이 길게 물리지 않게 합니다.' }
],
recommendedClasses: [
{ label: '사절 보호', classKeys: ['strategist'], reason: '제갈량과 손건을 안전하게 유지해야 강동 회담으로 이어집니다.' },
{ label: '후방 지휘', classKeys: ['lord'], reason: '유비가 퇴로를 붙들어야 사절단이 끊기지 않습니다.' },
{ label: '기병 차단', classKeys: ['cavalry'], reason: '조운 같은 기동 장수가 중간 추격 기병을 먼저 끊어야 합니다.' },
{ label: '길목 전열', classKeys: ['infantry', 'spearman'], reason: '강변 길목과 포구 수비대를 안정적으로 받아낼 전열이 필요합니다.' }
],
deploymentSlots: [
{ x: 4, y: 22, role: 'reserve', unitId: 'liu-bei', label: '후방 지휘' },
{ x: 5, y: 20, role: 'front', unitId: 'guan-yu', label: '강변 전열' },
{ x: 6, y: 23, role: 'front', unitId: 'zhang-fei', label: '포구 돌파' },
{ x: 8, y: 21, role: 'flank', unitId: 'zhao-yun', label: '측면 호위' },
{ x: 6, y: 21, role: 'support', unitId: 'zhuge-liang', label: '회담 논리' },
{ x: 4, y: 24, role: 'support', unitId: 'sun-qian', label: '사절 문서' }
],
note: '강동 사절로는 제갈량과 손건을 무사히 나루까지 보내는 전투입니다. 유비는 후방 지휘, 조운은 측면 호위, 관우와 장비는 강변 길목과 포구 돌파를 맡는 편성이 안정적입니다.'
},
map: twentiethBattleMap, map: twentiethBattleMap,
units: twentiethBattleUnits, units: twentiethBattleUnits,
bonds: twentiethBattleBonds, bonds: twentiethBattleBonds,
mapTextureKey: 'battle-map-twentieth', mapTextureKey: 'battle-map-twentieth',
leaderUnitId: 'envoy-road-leader-wen-pin', leaderUnitId: 'envoy-road-leader-wen-pin',
quickVictoryTurnLimit: 31, quickVictoryTurnLimit: 38,
baseVictoryGold: 2380, baseVictoryGold: 2380,
objectives: [ objectives: [
{ {
@@ -2710,14 +2774,25 @@ export const twentiethBattleScenario: BattleScenarioDefinition = {
kind: 'secure-terrain', kind: 'secure-terrain',
label: '강나루 확보', label: '강나루 확보',
rewardGold: 860, rewardGold: 860,
terrain: 'fort' terrain: 'fort',
targetTile: { x: 35, y: 18, radius: 5 },
threatRadius: 0
},
{
id: 'envoy-rendezvous',
kind: 'secure-terrain',
label: '강변 접선지 확보',
rewardGold: 720,
terrain: 'village',
targetTile: { x: 29, y: 16, radius: 5 },
threatRadius: 0
}, },
{ {
id: 'quick', id: 'quick',
kind: 'quick-victory', kind: 'quick-victory',
label: '31턴 이내 승리', label: '38턴 이내 승리',
rewardGold: 640, rewardGold: 640,
maxTurn: 31 maxTurn: 38
} }
], ],
defeatConditions: [ defeatConditions: [
@@ -2726,6 +2801,14 @@ export const twentiethBattleScenario: BattleScenarioDefinition = {
{ kind: 'unit-defeated', unitId: 'sun-qian' } { kind: 'unit-defeated', unitId: 'sun-qian' }
], ],
itemRewards: ['콩 8', '상처약 6', '탁주 3', '강동 사절 문서 +1', '화공 논의 +1'], itemRewards: ['콩 8', '상처약 6', '탁주 3', '강동 사절 문서 +1', '화공 논의 +1'],
campaignReward: {
supplies: ['콩 8', '상처약 6', '탁주 3'],
equipment: ['강동 사절 문서 1'],
reputation: ['강동 회담 명분 +1', '화공 논의 +1'],
unlockBattleId: 'twenty-first-battle-red-cliffs-vanguard',
unlockLabel: '적벽 전초전 개방',
note: '강변 접선지와 강나루를 확보해 제갈량과 손건이 손권·주유에게 전할 회담 명분을 완성합니다.'
},
victoryPages: twentiethBattleVictoryPages, victoryPages: twentiethBattleVictoryPages,
nextCampScene: 'CampScene' nextCampScene: 'CampScene'
}; };

View File

@@ -411,8 +411,8 @@ const sortieFlows: Record<string, SortieFlow> = {
eyebrow: '다음 전장', eyebrow: '다음 전장',
title: twentiethBattleScenario.title, title: twentiethBattleScenario.title,
description: description:
'장판파에서 피난민 마을과 장판교 길목을 지켜 백성과 군을 다시 모았습니다. 이제 제갈량과 손건을 강나루까지 보내 강동 사절의 길을 열어야 합니다.', '장판파에서 피난민 마을과 장판교 길목을 지켜 백성과 군을 다시 모았습니다. 이제 제갈량과 손건이 사절 문서를 들고 강변 접선지와 강나루를 지나 강동으로 향해야 합니다.',
rewardHint: `예상 보상: ${twentiethBattleScenario.title} 개방 / 피난민 보호·장판교 방어 기록`, rewardHint: `예상 보상: ${twentiethBattleScenario.title} 개방 / 강동 사절 문서`,
nextBattleId: twentiethBattleScenario.id, nextBattleId: twentiethBattleScenario.id,
campaignStep: 'twentieth-battle', campaignStep: 'twentieth-battle',
pages: [...nineteenthBattleVictoryPages, ...twentiethBattleIntroPages] pages: [...nineteenthBattleVictoryPages, ...twentiethBattleIntroPages]
@@ -422,7 +422,7 @@ const sortieFlows: Record<string, SortieFlow> = {
eyebrow: '다음 전장', eyebrow: '다음 전장',
title: twentyFirstBattleScenario.title, title: twentyFirstBattleScenario.title,
description: description:
'강동으로 향하는 길이 열렸습니다. 제갈량과 손건이 손권과 주유를 설득한 뒤, 조조군 수군 선봉을 상대로 손유 동맹의 첫 전선을 세워야 합니다.', '강변 접선지와 강나루가 열렸습니다. 제갈량과 손건이 손권과 주유를 설득한 뒤, 조조군 수군 선봉을 상대로 손유 동맹의 첫 전선을 세워야 합니다.',
rewardHint: `예상 보상: ${twentyFirstBattleScenario.title} 개방 / 화공 논의 진전`, rewardHint: `예상 보상: ${twentyFirstBattleScenario.title} 개방 / 화공 논의 진전`,
nextBattleId: twentyFirstBattleScenario.id, nextBattleId: twentyFirstBattleScenario.id,
campaignStep: 'twenty-first-battle', campaignStep: 'twenty-first-battle',

View File

@@ -1580,7 +1580,7 @@ export const twentiethBattleIntroPages: StoryPage[] = [
chapter: '강동으로 가는 길', chapter: '강동으로 가는 길',
background: 'story-red-cliffs', background: 'story-red-cliffs',
speaker: '손건', speaker: '손건',
text: '장판파의 피난로를 지나 유비군은 하구로 향합니다. 강동에 사절을 보내려면 조조군 추격대가 강나루를 닫기 전에 길을 열어야 합니다.' text: '장판파의 피난로를 지나 유비군은 하구로 향합니다. 강동에 보낼 문서를 살리려면 강변 접선지와 강나루가 모두 열려 있어야 합니다.'
}, },
{ {
id: 'twentieth-zhuge-envoy-plan', id: 'twentieth-zhuge-envoy-plan',
@@ -1588,7 +1588,7 @@ export const twentiethBattleIntroPages: StoryPage[] = [
chapter: '사절의 문서', chapter: '사절의 문서',
background: 'story-red-cliffs', background: 'story-red-cliffs',
speaker: '제갈량', speaker: '제갈량',
text: '강동은 조조를 두려워하지만, 싸울 계산이 서야 움직입니다. 손건의 문서와 장판파의 기록을 나루까지 지켜야 합니다.' text: '강동은 조조를 두려워하지만, 싸울 계산이 서야 움직입니다. 장판파의 기록, 조조군의 남하 속도, 백성을 지킨 명분을 한 문서로 묶어 나루까지 지켜야 합니다.'
}, },
{ {
id: 'twentieth-generals-protect-envoy', id: 'twentieth-generals-protect-envoy',
@@ -1597,7 +1597,7 @@ export const twentiethBattleIntroPages: StoryPage[] = [
background: 'story-red-cliffs', background: 'story-red-cliffs',
speaker: '관우', speaker: '관우',
portrait: 'guanYu', portrait: 'guanYu',
text: '이번 길은 적을 많이 베는 것보다 사절을 온전히 보내는 일이 먼저입니다. 전열과 기동, 보급을 골고루 세우는 편성이 필요하겠습니다.' text: '문빙의 기병이 길목을 끊으면 문서도 말도 강을 건너지 못합니다. 조운은 측면을 보고, 장비는 포구를 밀며, 저는 강변 전열을 받치겠습니다.'
}, },
{ {
id: 'twentieth-jiangdong-envoy-sortie', id: 'twentieth-jiangdong-envoy-sortie',
@@ -1606,7 +1606,7 @@ export const twentiethBattleIntroPages: StoryPage[] = [
background: 'story-red-cliffs', background: 'story-red-cliffs',
speaker: '유비', speaker: '유비',
portrait: 'liuBei', portrait: 'liuBei',
text: '선생과 손건이 강동에 닿아야 조조의 큰 군세를 막을 길이 열리오. 오늘은 칼끝만이 아니라 말과 문서를 지키는 싸움이오.' text: '선생과 손건이 강동에 닿아야 조조의 큰 군세를 막을 길이 열리오. 강변 접선지와 강나루를 차례로 열고, 문빙의 추격을 여기서 끊읍시다.'
} }
]; ];
@@ -1616,7 +1616,7 @@ export const twentiethBattleVictoryPages: StoryPage[] = [
bgm: 'militia-theme', bgm: 'militia-theme',
chapter: '나루가 열리다', chapter: '나루가 열리다',
background: 'story-red-cliffs', background: 'story-red-cliffs',
text: '문빙의 추격대가 물러서자 강나루의 문이 열렸습니다. 유비군은 피난 행렬을 뒤에 두고, 강동으로 향할 작은 배와 사절 문서를 지켜냈습니다.' text: '문빙의 추격대가 물러서자 접선지의 불빛과 강나루의 문이 함께 열렸습니다. 유비군은 피난 행렬을 뒤에 두고, 강동으로 향할 작은 배와 사절 문서를 지켜냈습니다.'
}, },
{ {
id: 'twentieth-sun-qian-letter-ready', id: 'twentieth-sun-qian-letter-ready',
@@ -1624,7 +1624,7 @@ export const twentiethBattleVictoryPages: StoryPage[] = [
chapter: '손권에게 보낼 말', chapter: '손권에게 보낼 말',
background: 'story-red-cliffs', background: 'story-red-cliffs',
speaker: '손건', speaker: '손건',
text: '강동에 전할 말은 이제 분명합니다. 조조의 남하, 장판파의 피난로, 그리고 주공께서 백성을 버리지 않았다는 사실을 함께 적겠습니다.' text: '강동에 전할 말은 이제 분명합니다. 조조의 남하, 장판파의 피난로, 접선지를 지킨 전투, 그리고 주공께서 백성을 버리지 않았다는 사실을 함께 적겠습니다.'
}, },
{ {
id: 'twentieth-red-cliffs-near', id: 'twentieth-red-cliffs-near',

View File

@@ -803,15 +803,30 @@ const sortieRulesByBattleId: Partial<Record<BattleScenarioId, SortieRuleDefiniti
}, },
'twentieth-battle-jiangdong-envoy': { 'twentieth-battle-jiangdong-envoy': {
maxUnits: 6, maxUnits: 6,
requiredUnitIds: ['liu-bei', 'zhuge-liang', 'sun-qian'],
recommended: [ recommended: [
{ unitId: 'liu-bei', reason: '사절을 보내는 결단과 패배 조건의 중심입니다.' }, { unitId: 'liu-bei', role: 'reserve', reason: '사절을 보내는 결단과 패배 조건의 중심입니다.' },
{ unitId: 'zhuge-liang', reason: '강동 설득 핵심 인물이며 반드시 보호해야 할 사절입니다.' }, { unitId: 'zhuge-liang', role: 'support', reason: '강동 설득 논리를 지키는 핵심 인물이며 반드시 보호해야 니다.' },
{ unitId: 'sun-qian', reason: '문서와 외교 명분을 지니고 있어 이번 전투의 생존 목표입니다.' }, { unitId: 'sun-qian', role: 'support', reason: '사절 문서와 회담 기록을 맡는 생존 목표입니다.' },
{ unitId: 'zhao-yun', reason: '추격 기병을 끊고 사절의 측면을 지키는 데 좋습니다.' }, { unitId: 'zhao-yun', role: 'flank', reason: '추격 기병을 끊고 사절의 측면을 지키는 데 좋습니다.' },
{ unitId: 'guan-yu', reason: '강나루 보병과 포구 수비대를 받아낼 전열 핵심입니다.' }, { unitId: 'guan-yu', role: 'front', reason: '강변 길목에서 보병 전열과 포구 수비대를 받아니다.' },
{ unitId: 'zhang-fei', reason: '포구 수비대를 빠르게 흔들어 사절단이 길게 물리지 않게 합니다.' } { unitId: 'zhang-fei', role: 'front', reason: '포구 수비대를 빠르게 흔들어 사절단이 길게 물리지 않게 합니다.' }
], ],
note: '강동 사절로는 보호 대상이 많은 전장입니다. 제갈량과 손건을 뒤에 두고, 관우·장비·조운으로 전열과 기동을 두껍게 세우십시오.' recommendedClasses: [
{ label: '사절 보호', classKeys: ['strategist'], reason: '제갈량과 손건을 안전하게 유지해야 강동 회담으로 이어집니다.' },
{ label: '후방 지휘', classKeys: ['lord'], reason: '유비가 퇴로를 붙들어야 사절단이 끊기지 않습니다.' },
{ label: '기병 차단', classKeys: ['cavalry'], reason: '조운 같은 기동 장수가 중간 추격 기병을 먼저 끊어야 합니다.' },
{ label: '길목 전열', classKeys: ['infantry', 'spearman'], reason: '강변 길목과 포구 수비대를 안정적으로 받아낼 전열이 필요합니다.' }
],
deploymentSlots: [
{ x: 4, y: 22, role: 'reserve', unitId: 'liu-bei', label: '후방 지휘' },
{ x: 5, y: 20, role: 'front', unitId: 'guan-yu', label: '강변 전열' },
{ x: 6, y: 23, role: 'front', unitId: 'zhang-fei', label: '포구 돌파' },
{ x: 8, y: 21, role: 'flank', unitId: 'zhao-yun', label: '측면 호위' },
{ x: 6, y: 21, role: 'support', unitId: 'zhuge-liang', label: '회담 논리' },
{ x: 4, y: 24, role: 'support', unitId: 'sun-qian', label: '사절 문서' }
],
note: '강동 사절로는 제갈량과 손건을 무사히 나루까지 보내는 전투입니다. 유비는 후방 지휘, 조운은 측면 호위, 관우와 장비는 강변 길목과 포구 돌파를 맡는 편성이 안정적입니다.'
}, },
'twenty-first-battle-red-cliffs-vanguard': { 'twenty-first-battle-red-cliffs-vanguard': {
maxUnits: 6, maxUnits: 6,