diff --git a/src/game/data/battles.ts b/src/game/data/battles.ts index f717d14..5b6241f 100644 --- a/src/game/data/battles.ts +++ b/src/game/data/battles.ts @@ -4438,12 +4438,79 @@ export const thirtyFirstBattleScenario: BattleScenarioDefinition = { '엄안이 성 안의 노장으로 버티고 있습니다. 황충, 법정, 오의를 데려가면 성벽 궁병과 항복 설득을 함께 압박하기 좋습니다.', '유비와 방통을 지키며 장임을 격파하십시오. 낙성이 열리면 익주 심부와 성도 압박으로 나아갑니다.' ], + tacticalGuide: { + summary: + '낙성 본성 공략은 성문을 힘으로 여는 싸움이면서 동시에 익주 백성의 마음을 닫지 않는 싸움입니다. 외성 민가를 안정시키고 성벽 궁병을 억제한 뒤, 법정과 오의가 엄안에게 항복의 명분을 보여 주어야 합니다.', + route: '서남 유비군 진영 → 외성 민가 안정 → 성벽 사격선 억제 → 낙성 성문 확보 → 엄안 예우 압박 → 장임 본성 격파', + focus: + '방통은 성문 돌파 순서를 계산하고, 법정과 오의는 엄안 설득의 말길을 엽니다. 황충은 성벽 궁병을 견제하고 장비는 성문 친위대를 짧게 무너뜨리는 역할이 분명합니다.', + roles: [ + '유비: 낙성 항복 명분과 패배 조건의 중심', + '방통: 성문 돌파 순서와 퇴로 계산', + '법정: 엄안 설득과 익주 장수 심리 판단', + '오의: 낙성 내부 지형과 성문 방어 습관 안내', + '황충: 성벽 궁병과 엄안의 원거리 압박 견제', + '장비: 성문 친위대를 밀어내는 정면 돌파' + ], + events: { + 'village-approach': { + title: '외성 민가 안정', + lines: [ + '법정: 저 민가를 먼저 안정시키면 성 안의 노장들도 유비공의 군율을 보게 됩니다.', + '유비: 성문을 열기 전에 백성의 마음을 지키시오. 낙성은 빼앗는 성이 아니라 맡겨 받는 성이어야 하오.' + ] + }, + 'cavalry-approach': { + title: '성문 기병 견제', + lines: [ + '장비: 성문 앞 기병이 옆구리를 찌르려 한다. 내가 먼저 흔들어 놓겠다!', + '오의: 저 기병을 묶어야 성벽 궁병의 사격선으로 끌려 들어가지 않습니다.' + ] + }, + 'leader-wavering': { + title: '엄안의 마음이 움직이다', + lines: [ + '성문과 민가가 안정되자 엄안의 병사들이 더는 백성을 방패로 삼으려 하지 않습니다.', + '엄안: 성을 치면서도 백성을 해치지 않는 군이라... 노장이 외면하기 어려운 길이로군.' + ] + } + } + }, + sortie: { + sortieLimit: 6, + requiredUnits: ['liu-bei', 'pang-tong'], + recommendedUnits: [ + { unitId: 'liu-bei', role: 'reserve', reason: '낙성 항복 명분이자 패배 조건의 중심입니다.' }, + { unitId: 'pang-tong', role: 'support', reason: '성문 돌파 순서와 퇴로를 함께 계산하는 핵심 책사입니다.' }, + { unitId: 'fa-zheng', role: 'support', reason: '엄안 설득과 익주 장수 심리 판단을 맡습니다.' }, + { unitId: 'wu-yi', role: 'flank', reason: '낙성 내부 지형과 성문 방어 습관을 아는 새 합류 장수입니다.' }, + { unitId: 'huang-zhong', role: 'support', reason: '성벽 궁병과 노장 엄안의 원거리 압박에 대응하기 좋습니다.' }, + { unitId: 'zhang-fei', role: 'front', 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: 39, role: 'reserve', unitId: 'liu-bei', label: '항복 명분' }, + { x: 9, y: 38, role: 'support', unitId: 'pang-tong', label: '성문 설계' }, + { x: 11, y: 40, role: 'support', unitId: 'fa-zheng', label: '엄안 설득' }, + { x: 12, y: 38, role: 'flank', unitId: 'wu-yi', label: '내성 길' }, + { x: 7, y: 39, role: 'support', unitId: 'huang-zhong', label: '성벽 견제' }, + { x: 4, y: 41, role: 'front', unitId: 'zhang-fei', label: '성문 돌파' } + ], + note: + '낙성 본성 공략은 성문을 여는 힘과 항복을 받아낼 명분을 함께 봐야 합니다. 법정·오의를 세우면 엄안 설득이 선명해지고, 장비·황충을 세우면 성문 돌파가 안정됩니다.' + }, map: thirtyFirstBattleMap, units: thirtyFirstBattleUnits, bonds: thirtyFirstBattleBonds, mapTextureKey: 'battle-map-thirty-first', leaderUnitId: 'luo-main-leader-zhang-ren', - quickVictoryTurnLimit: 48, + quickVictoryTurnLimit: 66, baseVictoryGold: 4720, objectives: [ { @@ -4467,19 +4534,48 @@ export const thirtyFirstBattleScenario: BattleScenarioDefinition = { rewardGold: 1220, unitId: 'pang-tong' }, + { + id: 'outer-village', + kind: 'secure-terrain', + label: '외성 민가 안정', + rewardGold: 1320, + terrain: 'village', + targetTile: { x: 46, y: 25, radius: 14 }, + threatRadius: 0 + }, + { + id: 'wall-archers', + kind: 'secure-terrain', + label: '성벽 궁병 억제', + rewardGold: 1380, + terrain: 'fort', + targetTile: { x: 49, y: 18, radius: 15 }, + threatRadius: 0 + }, { id: 'main-gate', kind: 'secure-terrain', label: '낙성 성문 확보', - rewardGold: 1480, - terrain: 'fort' + rewardGold: 1520, + terrain: 'fort', + targetTile: { x: 52, y: 21, radius: 14 }, + threatRadius: 0 + }, + { + id: 'yan-yan-honor', + kind: 'secure-terrain', + label: '엄안 예우 압박', + rewardGold: 1420, + terrain: 'fort', + targetTile: { x: 50, y: 22, radius: 14 }, + threatRadius: 0 }, { id: 'quick', kind: 'quick-victory', - label: '48턴 이내 승리', + label: '66턴 이내 승리', rewardGold: 1120, - maxTurn: 48 + maxTurn: 66 } ], defeatConditions: [ @@ -4487,6 +4583,14 @@ export const thirtyFirstBattleScenario: BattleScenarioDefinition = { { kind: 'unit-defeated', unitId: 'pang-tong' } ], itemRewards: ['콩 16', '상처약 12', '탁주 7', '낙성 항복 권고문 +1', '엄안 합류'], + campaignReward: { + supplies: ['콩 16', '상처약 12', '탁주 7'], + reputation: ['낙성 항복 권고문 +1', '엄안 예우 +1'], + recruits: ['yan-yan'], + unlockBattleId: 'thirty-second-battle-mianzhu-gate', + unlockLabel: '면죽관 압박전 개방', + note: '낙성 성문을 열고 외성 민가를 안정시켜 엄안이 합류했습니다. 성도 앞 면죽관으로 향합니다.' + }, victoryPages: thirtyFirstBattleVictoryPages, nextCampScene: 'CampScene' }; diff --git a/src/game/data/campaignFlow.ts b/src/game/data/campaignFlow.ts index d2454aa..be7126c 100644 --- a/src/game/data/campaignFlow.ts +++ b/src/game/data/campaignFlow.ts @@ -543,7 +543,7 @@ const sortieFlows: Record = { eyebrow: '다음 전장', title: thirtySecondBattleScenario.title, description: - '낙성 본성이 열리고 엄안이 합류했습니다. 이제 엄안의 첫 출전과 법정·오의의 길 안내를 엮어 성도 앞 면죽관을 압박해야 합니다.', + '낙성 본성의 성문과 외성 민가를 안정시키며 엄안이 합류했습니다. 이제 엄안의 첫 출전과 법정·오의의 길 안내를 엮어 성도 앞 면죽관을 압박해야 합니다.', rewardHint: `예상 보상: ${thirtySecondBattleScenario.title} 개방 / 이엄 합류`, nextBattleId: thirtySecondBattleScenario.id, campaignStep: 'thirty-second-battle', diff --git a/src/game/data/scenario.ts b/src/game/data/scenario.ts index ffb9b32..1c63773 100644 --- a/src/game/data/scenario.ts +++ b/src/game/data/scenario.ts @@ -2272,7 +2272,7 @@ export const thirtyFirstBattleIntroPages: StoryPage[] = [ chapter: '낙성 본성의 문', background: 'story-yizhou-luo-road', speaker: '법정', - text: '장임은 낙봉파에서 물러난 뒤 낙성 본성의 문을 모두 닫았습니다. 성벽은 높고, 성 안의 장수들은 아직 유비공의 뜻을 의심하고 있습니다.' + text: '장임은 낙봉파에서 물러난 뒤 낙성 본성의 문을 모두 닫았습니다. 성벽 궁병은 길목을 내려다보고, 외성 민가는 전장 한복판에 놓였습니다.' }, { id: 'thirty-first-veteran-wall', @@ -2280,7 +2280,7 @@ export const thirtyFirstBattleIntroPages: StoryPage[] = [ chapter: '노장 엄안', background: 'story-yizhou-luo-road', speaker: '오의', - text: '성 안에는 엄안이라는 노장이 있습니다. 장임과 뜻을 같이해 버티고 있으나, 백성을 해치지 않겠다는 약속을 보이면 마음이 움직일 수 있습니다.' + text: '성 안에는 엄안이라는 노장이 있습니다. 장임과 함께 버티고 있으나, 민가를 안정시키고 성문을 질서 있게 열면 그도 유비공의 군율을 보게 될 것입니다.' }, { id: 'thirty-first-siege-choice', @@ -2288,7 +2288,7 @@ export const thirtyFirstBattleIntroPages: StoryPage[] = [ chapter: '돌파와 설득', background: 'story-yizhou-luo-road', speaker: '제갈량', - text: '성문을 부수는 힘만으로는 낙성을 얻을 수 없습니다. 방통, 법정, 오의를 함께 쓰면 설득의 길이 열리고, 무장을 더 세우면 짧은 돌파가 가능해집니다.' + text: '외성 민가를 먼저 안정시키고, 성벽 궁병의 사격선을 끊은 뒤 성문을 잡으십시오. 방통은 돌파 순서를, 법정과 오의는 엄안에게 보일 명분을 맡기면 됩니다.' }, { id: 'thirty-first-sortie', @@ -2297,7 +2297,7 @@ export const thirtyFirstBattleIntroPages: StoryPage[] = [ background: 'story-yizhou-luo-road', speaker: '유비', portrait: 'liuBei', - text: '성문을 열되 백성의 마음은 닫지 않겠소. 장임의 방어선을 깨고 엄안 같은 장수에게 우리가 지키려는 뜻을 보여 주시오.' + text: '성문은 열되 백성의 마음은 닫지 않겠소. 민가를 지키고, 성벽의 활을 잠재우고, 엄안 같은 장수에게 우리가 지키려는 뜻을 보여 주시오.' } ]; @@ -2307,7 +2307,7 @@ export const thirtyFirstBattleVictoryPages: StoryPage[] = [ bgm: 'militia-theme', chapter: '낙성의 문이 열리다', background: 'story-yizhou-luo-road', - text: '낙성 본성의 문은 마침내 열렸습니다. 성벽 위의 깃발은 내려갔고, 장임의 마지막 방어선도 유비군의 꾸준한 압박 앞에 무너졌습니다.' + text: '낙성 본성의 문은 마침내 열렸습니다. 외성 민가는 큰 피해를 피했고, 성벽 위의 깃발은 내려갔으며, 장임의 마지막 방어선도 무너졌습니다.' }, { id: 'thirty-first-yan-yan-joins', @@ -2323,7 +2323,7 @@ export const thirtyFirstBattleVictoryPages: StoryPage[] = [ chapter: '성도 압박의 길', background: 'story-yizhou-luo-road', speaker: '법정', - text: '낙성이 열렸으니 익주의 심장부가 흔들립니다. 이제 유비군은 성도를 향한 길에서 더 많은 항복과 저항을 동시에 맞이하게 될 것입니다.' + text: '낙성이 열린 방식이 곧 다음 설득의 증거가 됩니다. 엄안의 합류를 앞세우면 성도 앞 면죽관에서도 저항과 항복이 함께 흔들릴 것입니다.' } ]; diff --git a/src/game/scenes/CampScene.ts b/src/game/scenes/CampScene.ts index 1ab037e..d3a42cc 100644 --- a/src/game/scenes/CampScene.ts +++ b/src/game/scenes/CampScene.ts @@ -1104,15 +1104,31 @@ const sortieRulesByBattleId: Partial