From 51df622fd60bf3a7336933b2dff5f0d15ab825ed Mon Sep 17 00:00:00 2001 From: Wickedness Date: Sat, 4 Jul 2026 18:04:06 +0900 Subject: [PATCH] Refine Jiangdong envoy battle flow --- src/game/data/battles.ts | 97 ++++++++++++++++++++++++++++++++--- src/game/data/campaignFlow.ts | 6 +-- src/game/data/scenario.ts | 12 ++--- src/game/scenes/CampScene.ts | 29 ++++++++--- 4 files changed, 121 insertions(+), 23 deletions(-) diff --git a/src/game/data/battles.ts b/src/game/data/battles.ts index 7d2cd16..b2ae04c 100644 --- a/src/game/data/battles.ts +++ b/src/game/data/battles.ts @@ -2672,16 +2672,80 @@ export const twentiethBattleScenario: BattleScenarioDefinition = { victoryConditionLabel: '문빙 퇴각', defeatConditionLabel: '유비, 제갈량 또는 손건 퇴각', 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, units: twentiethBattleUnits, bonds: twentiethBattleBonds, mapTextureKey: 'battle-map-twentieth', leaderUnitId: 'envoy-road-leader-wen-pin', - quickVictoryTurnLimit: 31, + quickVictoryTurnLimit: 38, baseVictoryGold: 2380, objectives: [ { @@ -2710,14 +2774,25 @@ export const twentiethBattleScenario: BattleScenarioDefinition = { kind: 'secure-terrain', label: '강나루 확보', 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', kind: 'quick-victory', - label: '31턴 이내 승리', + label: '38턴 이내 승리', rewardGold: 640, - maxTurn: 31 + maxTurn: 38 } ], defeatConditions: [ @@ -2726,6 +2801,14 @@ export const twentiethBattleScenario: BattleScenarioDefinition = { { kind: 'unit-defeated', unitId: 'sun-qian' } ], 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, nextCampScene: 'CampScene' }; diff --git a/src/game/data/campaignFlow.ts b/src/game/data/campaignFlow.ts index 8e8f779..0e20f2e 100644 --- a/src/game/data/campaignFlow.ts +++ b/src/game/data/campaignFlow.ts @@ -411,8 +411,8 @@ const sortieFlows: Record = { eyebrow: '다음 전장', title: twentiethBattleScenario.title, description: - '장판파에서 피난민 마을과 장판교 길목을 지켜 백성과 군을 다시 모았습니다. 이제 제갈량과 손건을 강나루까지 보내 강동 사절의 길을 열어야 합니다.', - rewardHint: `예상 보상: ${twentiethBattleScenario.title} 개방 / 피난민 보호·장판교 방어 기록`, + '장판파에서 피난민 마을과 장판교 길목을 지켜 백성과 군을 다시 모았습니다. 이제 제갈량과 손건이 사절 문서를 들고 강변 접선지와 강나루를 지나 강동으로 향해야 합니다.', + rewardHint: `예상 보상: ${twentiethBattleScenario.title} 개방 / 강동 사절 문서`, nextBattleId: twentiethBattleScenario.id, campaignStep: 'twentieth-battle', pages: [...nineteenthBattleVictoryPages, ...twentiethBattleIntroPages] @@ -422,7 +422,7 @@ const sortieFlows: Record = { eyebrow: '다음 전장', title: twentyFirstBattleScenario.title, description: - '강동으로 향하는 길이 열렸습니다. 제갈량과 손건이 손권과 주유를 설득한 뒤, 조조군 수군 선봉을 상대로 손유 동맹의 첫 전선을 세워야 합니다.', + '강변 접선지와 강나루가 열렸습니다. 제갈량과 손건이 손권과 주유를 설득한 뒤, 조조군 수군 선봉을 상대로 손유 동맹의 첫 전선을 세워야 합니다.', rewardHint: `예상 보상: ${twentyFirstBattleScenario.title} 개방 / 화공 논의 진전`, nextBattleId: twentyFirstBattleScenario.id, campaignStep: 'twenty-first-battle', diff --git a/src/game/data/scenario.ts b/src/game/data/scenario.ts index a2789d5..9484b39 100644 --- a/src/game/data/scenario.ts +++ b/src/game/data/scenario.ts @@ -1580,7 +1580,7 @@ export const twentiethBattleIntroPages: StoryPage[] = [ chapter: '강동으로 가는 길', background: 'story-red-cliffs', speaker: '손건', - text: '장판파의 피난로를 지나 유비군은 하구로 향합니다. 강동에 사절을 보내려면 조조군 추격대가 강나루를 닫기 전에 길을 열어야 합니다.' + text: '장판파의 피난로를 지나 유비군은 하구로 향합니다. 강동에 보낼 문서를 살리려면 강변 접선지와 강나루가 모두 열려 있어야 합니다.' }, { id: 'twentieth-zhuge-envoy-plan', @@ -1588,7 +1588,7 @@ export const twentiethBattleIntroPages: StoryPage[] = [ chapter: '사절의 문서', background: 'story-red-cliffs', speaker: '제갈량', - text: '강동은 조조를 두려워하지만, 싸울 계산이 서야 움직입니다. 손건의 문서와 장판파의 기록을 나루까지 지켜야 합니다.' + text: '강동은 조조를 두려워하지만, 싸울 계산이 서야 움직입니다. 장판파의 기록, 조조군의 남하 속도, 백성을 지킨 명분을 한 문서로 묶어 나루까지 지켜야 합니다.' }, { id: 'twentieth-generals-protect-envoy', @@ -1597,7 +1597,7 @@ export const twentiethBattleIntroPages: StoryPage[] = [ background: 'story-red-cliffs', speaker: '관우', portrait: 'guanYu', - text: '이번 길은 적을 많이 베는 것보다 사절을 온전히 보내는 일이 먼저입니다. 전열과 기동, 보급을 골고루 세우는 편성이 필요하겠습니다.' + text: '문빙의 기병이 길목을 끊으면 문서도 말도 강을 건너지 못합니다. 조운은 측면을 보고, 장비는 포구를 밀며, 저는 강변 전열을 받치겠습니다.' }, { id: 'twentieth-jiangdong-envoy-sortie', @@ -1606,7 +1606,7 @@ export const twentiethBattleIntroPages: StoryPage[] = [ background: 'story-red-cliffs', speaker: '유비', portrait: 'liuBei', - text: '선생과 손건이 강동에 닿아야 조조의 큰 군세를 막을 길이 열리오. 오늘은 칼끝만이 아니라 말과 문서를 지키는 싸움이오.' + text: '선생과 손건이 강동에 닿아야 조조의 큰 군세를 막을 길이 열리오. 강변 접선지와 강나루를 차례로 열고, 문빙의 추격을 여기서 끊읍시다.' } ]; @@ -1616,7 +1616,7 @@ export const twentiethBattleVictoryPages: StoryPage[] = [ bgm: 'militia-theme', chapter: '나루가 열리다', background: 'story-red-cliffs', - text: '문빙의 추격대가 물러서자 강나루의 문이 열렸습니다. 유비군은 피난 행렬을 뒤에 두고, 강동으로 향할 작은 배와 사절 문서를 지켜냈습니다.' + text: '문빙의 추격대가 물러서자 접선지의 불빛과 강나루의 문이 함께 열렸습니다. 유비군은 피난 행렬을 뒤에 두고, 강동으로 향할 작은 배와 사절 문서를 지켜냈습니다.' }, { id: 'twentieth-sun-qian-letter-ready', @@ -1624,7 +1624,7 @@ export const twentiethBattleVictoryPages: StoryPage[] = [ chapter: '손권에게 보낼 말', background: 'story-red-cliffs', speaker: '손건', - text: '강동에 전할 말은 이제 분명합니다. 조조의 남하, 장판파의 피난로, 그리고 주공께서 백성을 버리지 않았다는 사실을 함께 적겠습니다.' + text: '강동에 전할 말은 이제 분명합니다. 조조의 남하, 장판파의 피난로, 접선지를 지킨 전투, 그리고 주공께서 백성을 버리지 않았다는 사실을 함께 적겠습니다.' }, { id: 'twentieth-red-cliffs-near', diff --git a/src/game/scenes/CampScene.ts b/src/game/scenes/CampScene.ts index 2517005..1b524f3 100644 --- a/src/game/scenes/CampScene.ts +++ b/src/game/scenes/CampScene.ts @@ -803,15 +803,30 @@ const sortieRulesByBattleId: Partial