diff --git a/src/game/data/battles.ts b/src/game/data/battles.ts index 24fc8a1..918594c 100644 --- a/src/game/data/battles.ts +++ b/src/game/data/battles.ts @@ -3843,7 +3843,7 @@ export const twentySeventhBattleScenario: BattleScenarioDefinition = { bonds: twentySeventhBattleBonds, mapTextureKey: 'battle-map-twenty-seventh', leaderUnitId: 'yizhou-leader-yang-huai', - quickVictoryTurnLimit: 48, + quickVictoryTurnLimit: 60, baseVictoryGold: 3760, objectives: [ { @@ -4102,15 +4102,82 @@ export const twentyNinthBattleScenario: BattleScenarioDefinition = { 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'], + recommendedUnits: [ + { unitId: 'liu-bei', role: 'reserve', reason: '낙성 외곽 마을을 안정시키는 명분이자 패배 조건의 중심입니다.' }, + { unitId: 'fa-zheng', role: 'support', reason: '오의 설득과 성문 장수들의 속내를 읽는 이번 전투의 새 정보 축입니다.' }, + { unitId: 'zhuge-liang', role: 'support', reason: '법정의 내부 정보를 전체 방어선과 다음 낙봉파 판단으로 연결합니다.' }, + { unitId: 'wei-yan', role: 'front', reason: '외곽 보병 전열과 고개 척후를 빠르게 열어 책사들의 시간을 벌어 줍니다.' }, + { unitId: 'huang-zhong', role: 'support', reason: '성벽 궁병과 산루 궁병을 안정적으로 견제합니다.' }, + { unitId: 'zhao-yun', role: 'flank', reason: '넓어진 외곽 맵에서 기병과 복병을 빠르게 차단합니다.' } + ], + recommendedClasses: [ + { label: '외곽 명분', classKeys: ['lord'], reason: '유비가 살아 남아야 마을 위무와 오의 설득의 명분이 유지됩니다.' }, + { label: '익주 정보', classKeys: ['strategist'], reason: '제갈량과 법정이 함께 있으면 성문 정보와 전열 판단이 안정됩니다.' }, + { label: '고개 돌파', classKeys: ['infantry', 'spearman'], reason: '위연 같은 전열 무장이 길목 보병을 열어야 책사가 움직일 수 있습니다.' }, + { label: '성벽 견제', classKeys: ['archer'], reason: '황충의 원거리 견제가 성벽 궁병과 산루 궁병을 억제합니다.' }, + { label: '기병 차단', classKeys: ['cavalry'], reason: '기동 장수가 넓은 외곽의 기병과 복병을 끊어 후방을 지킵니다.' } + ], + deploymentSlots: [ + { x: 4, y: 34, role: 'reserve', unitId: 'liu-bei', label: '마을 위무' }, + { x: 5, y: 34, role: 'support', unitId: 'zhuge-liang', label: '방어선 판단' }, + { x: 11, y: 36, role: 'support', unitId: 'fa-zheng', label: '성문 정보' }, + { x: 10, y: 33, role: 'front', unitId: 'wei-yan', label: '고개 돌파' }, + { x: 7, y: 35, role: 'support', unitId: 'huang-zhong', label: '성벽 견제' }, + { x: 8, y: 34, role: 'flank', unitId: 'zhao-yun', label: '기병 차단' } + ], + note: + '낙성 외곽전은 법정을 처음 실전 편성으로 시험하는 전장입니다. 법정과 제갈량을 함께 세우면 설득과 정보가 강해지지만, 방통까지 넣을지 전열 무장을 세울지 선택이 더 중요해집니다.' + }, map: twentyNinthBattleMap, units: twentyNinthBattleUnits, bonds: twentyNinthBattleBonds, mapTextureKey: 'battle-map-twenty-ninth', leaderUnitId: 'luo-leader-zhang-ren', - quickVictoryTurnLimit: 38, + quickVictoryTurnLimit: 48, baseVictoryGold: 4200, objectives: [ { @@ -4139,14 +4206,43 @@ export const twentyNinthBattleScenario: BattleScenarioDefinition = { kind: 'secure-terrain', label: '낙성 외곽 마을 안정', rewardGold: 1280, - terrain: 'village' + terrain: 'village', + targetTile: { x: 42, y: 20, radius: 20 }, + threatRadius: 0 + }, + { + id: 'luo-ridge-scouts', + kind: 'secure-terrain', + label: '고개 척후 차단', + rewardGold: 1220, + terrain: 'road', + targetTile: { x: 42, y: 23, radius: 18 }, + threatRadius: 0 + }, + { + id: 'luo-wall-archers', + kind: 'secure-terrain', + label: '성벽 궁병 억제', + rewardGold: 1260, + terrain: 'fort', + targetTile: { x: 50, y: 18, radius: 12 }, + threatRadius: 0 + }, + { + id: 'wu-yi-route', + kind: 'secure-terrain', + label: '오의 진영 압박', + rewardGold: 1320, + terrain: 'road', + targetTile: { x: 47, y: 23, radius: 9 }, + threatRadius: 0 }, { id: 'quick', kind: 'quick-victory', - label: '38턴 이내 승리', + label: '60턴 이내 승리', rewardGold: 1000, - maxTurn: 38 + maxTurn: 60 } ], defeatConditions: [ @@ -4154,6 +4250,14 @@ export const twentyNinthBattleScenario: BattleScenarioDefinition = { { kind: 'unit-defeated', unitId: 'zhuge-liang' } ], itemRewards: ['콩 14', '상처약 10', '탁주 6', '낙성 외곽 지도 +1', '오의 합류'], + campaignReward: { + supplies: ['콩 14', '상처약 10', '탁주 6'], + reputation: ['낙성 외곽 지도 +1', '오의 설득 명분 +1'], + recruits: ['wu-yi'], + unlockBattleId: 'thirtieth-battle-luofeng-ambush', + unlockLabel: '낙봉파 매복전 개방', + note: '낙성 외곽 마을과 성벽 사격선을 안정시켰습니다. 오의가 합류하고 낙봉파로 향하는 길이 열립니다.' + }, victoryPages: twentyNinthBattleVictoryPages, nextCampScene: 'CampScene' }; diff --git a/src/game/data/campaignFlow.ts b/src/game/data/campaignFlow.ts index a0c88e9..0cfa3a5 100644 --- a/src/game/data/campaignFlow.ts +++ b/src/game/data/campaignFlow.ts @@ -521,7 +521,7 @@ const sortieFlows: Record = { eyebrow: '다음 전장', title: thirtiethBattleScenario.title, description: - '낙성 외곽을 넘고 오의가 합류했습니다. 이제 낙봉파의 좁은 길을 통과해야 하며, 방통의 불길한 직감과 오의의 길 안내를 함께 살펴야 합니다.', + '낙성 외곽 마을과 성벽 사격선을 안정시키고 오의가 합류했습니다. 이제 낙봉파의 좁은 길을 통과해야 하며, 방통의 불길한 직감과 오의의 길 안내를 함께 살펴야 합니다.', rewardHint: `예상 보상: ${thirtiethBattleScenario.title} 개방 / 봉추 생환`, nextBattleId: thirtiethBattleScenario.id, campaignStep: 'thirtieth-battle', diff --git a/src/game/data/scenario.ts b/src/game/data/scenario.ts index 632c66c..dbb25b1 100644 --- a/src/game/data/scenario.ts +++ b/src/game/data/scenario.ts @@ -2148,7 +2148,7 @@ export const twentyNinthBattleIntroPages: StoryPage[] = [ chapter: '낙성의 바깥 성벽', background: 'story-yizhou-luo-road', speaker: '법정', - text: '부수관을 넘으면 낙성의 바깥 성벽이 기다립니다. 장임은 성 밖의 고개와 마을을 겹쳐 방어선을 세웠고, 성 안의 장수들은 아직 우리 뜻을 믿지 않습니다.' + text: '부수관을 넘으면 낙성의 바깥 성벽이 기다립니다. 장임은 성 밖 마을, 고개 척후, 성벽 궁병을 겹쳐 시간을 벌고 있고, 성 안의 장수들은 아직 우리 뜻을 믿지 않습니다.' }, { id: 'twenty-ninth-wu-yi-rumor', @@ -2156,7 +2156,7 @@ export const twentyNinthBattleIntroPages: StoryPage[] = [ chapter: '흔들리는 오의', background: 'story-yizhou-luo-road', speaker: '방통', - text: '오의는 성문을 지키지만 백성을 함부로 몰아붙이는 명령을 달가워하지 않는다고 합니다. 전장을 거칠게 밀지 않고 길을 열면, 그의 마음도 움직일 수 있습니다.' + text: '오의는 성문을 지키지만 백성을 방패처럼 쓰는 명령을 달가워하지 않는다고 합니다. 마을을 먼저 안정시키고 성벽의 사격선만 꺾는다면, 그의 마음도 움직일 수 있습니다.' }, { id: 'twenty-ninth-roster-pressure', @@ -2164,7 +2164,7 @@ export const twentyNinthBattleIntroPages: StoryPage[] = [ chapter: '법정의 첫 출전 선택', background: 'story-yizhou-luo-road', speaker: '제갈량', - text: '이번 전투부터 법정도 출전 후보입니다. 익주 내부 사정을 아는 법정을 데려가면 설득은 쉬워지지만, 무장을 줄이는 부담은 더 커집니다.' + text: '이번 전투부터 법정도 출전 후보입니다. 그를 데려가면 오의와 성문 장수들의 속내를 읽기 쉽지만, 책사가 늘어나는 만큼 고개를 열 전열 무장은 더 신중히 골라야 합니다.' }, { id: 'twenty-ninth-luo-sortie', @@ -2173,7 +2173,7 @@ export const twentyNinthBattleIntroPages: StoryPage[] = [ background: 'story-yizhou-luo-road', speaker: '유비', portrait: 'liuBei', - text: '낙성의 문을 여는 일은 칼보다 마음이 먼저요. 마을을 지키고 장임의 전열을 물리쳐, 성 안 사람들에게 우리가 어떤 군인지 보이겠소.' + text: '낙성의 문을 여는 일은 칼보다 마음이 먼저요. 마을을 지키고, 고개 척후와 성벽 궁병을 차례로 눌러 성 안 사람들에게 우리가 어떤 군인지 보이겠소.' } ]; @@ -2183,7 +2183,7 @@ export const twentyNinthBattleVictoryPages: StoryPage[] = [ bgm: 'militia-theme', chapter: '외곽 방어선 붕괴', background: 'story-yizhou-luo-road', - text: '장임은 낙성 안쪽으로 물러났고, 외곽 마을은 큰 피해 없이 유비군의 보호 아래 들어왔습니다. 성 안의 장수들은 유비군을 단순한 침입군으로만 볼 수 없게 되었습니다.' + text: '장임은 낙성 안쪽으로 물러났고, 외곽 마을과 성벽 사격선은 큰 피해 없이 유비군의 통제 아래 들어왔습니다. 성 안의 장수들은 유비군을 단순한 침입군으로만 볼 수 없게 되었습니다.' }, { id: 'twenty-ninth-wu-yi-joins', @@ -2191,7 +2191,7 @@ export const twentyNinthBattleVictoryPages: StoryPage[] = [ chapter: '오의의 합류', background: 'story-yizhou-luo-road', speaker: '오의', - text: '성문을 지킨다는 명분으로 백성을 몰아넣는 일은 장수의 길이 아니었습니다. 주공께서 마을을 먼저 살피셨으니, 이 오의도 낙성의 다음 길을 열겠습니다.' + text: '성문을 지킨다는 명분으로 백성을 몰아넣는 일은 장수의 길이 아니었습니다. 주공께서 마을을 먼저 살피고 사격선만 끊으셨으니, 이 오의도 낙성의 다음 길을 열겠습니다.' }, { id: 'twenty-ninth-next-luofeng', diff --git a/src/game/scenes/CampScene.ts b/src/game/scenes/CampScene.ts index fea3c82..0ce2144 100644 --- a/src/game/scenes/CampScene.ts +++ b/src/game/scenes/CampScene.ts @@ -1048,15 +1048,31 @@ const sortieRulesByBattleId: Partial