From 58cdead7aa19be2479d6bd26176289a0eb8ab65c Mon Sep 17 00:00:00 2001 From: Wickedness Date: Sat, 4 Jul 2026 18:59:46 +0900 Subject: [PATCH] Refine Wuling mountain road battle flow --- src/game/data/battles.ts | 124 +++++++++++++++++++++++++++++++--- src/game/data/campaignFlow.ts | 4 +- src/game/data/scenario.ts | 14 ++-- src/game/scenes/CampScene.ts | 29 ++++++-- 4 files changed, 144 insertions(+), 27 deletions(-) diff --git a/src/game/data/battles.ts b/src/game/data/battles.ts index 20e1645..e4cfaa1 100644 --- a/src/game/data/battles.ts +++ b/src/game/data/battles.ts @@ -3434,24 +3434,90 @@ export const twentyFifthBattleScenario: BattleScenarioDefinition = { id: 'twenty-fifth-battle-wuling-mountain-road', title: '무릉 산길 확보전', victoryConditionLabel: '김선 퇴각', - defeatConditionLabel: '유비 또는 제갈량 퇴각', + 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', 'ma-liang'], + recommendedUnits: [ + { unitId: 'liu-bei', role: 'reserve', reason: '무릉 군율의 명분이자 패배 조건의 중심입니다.' }, + { unitId: 'ma-liang', role: 'support', reason: '무릉 산길과 마을 이름을 읽어 지점 목표를 연결하는 핵심 문사입니다.' }, + { unitId: 'zhuge-liang', role: 'support', reason: '좁은 산길 전열과 김선 설득 조건을 판단하는 작전 핵심입니다.' }, + { unitId: 'zhao-yun', role: 'flank', reason: '능선 척후와 산길 기병을 빠르게 끊어 고갯길을 안정시킵니다.' }, + { unitId: 'zhang-fei', role: 'front', reason: '협곡 보병 전열을 밀어내며 산길 입구를 여는 돌파 역할입니다.' }, + { unitId: 'yi-ji', role: 'support', reason: '공지에게 보낼 서약 문안과 백성 보호 명분을 정리합니다.' } + ], + recommendedClasses: [ + { label: '군율 명분', classKeys: ['lord'], reason: '유비가 살아 남아야 무릉 마을이 유비군의 약속을 믿습니다.' }, + { label: '산길 문사', classKeys: ['strategist'], reason: '마량과 제갈량, 이적의 문안이 마을 안정과 공지 합류로 이어집니다.' }, + { label: '협곡 전열', classKeys: ['infantry', 'spearman'], reason: '좁은 길의 보병 전열은 튼튼한 돌파 장수가 받아내야 합니다.' }, + { label: '능선 차단', classKeys: ['cavalry'], reason: '기동 장수가 척후와 기병을 끊어야 산길 목표를 놓치지 않습니다.' } + ], + deploymentSlots: [ + { x: 4, y: 28, role: 'reserve', unitId: 'liu-bei', label: '군율 중심' }, + { x: 6, y: 28, role: 'front', unitId: 'zhang-fei', label: '협곡 돌파' }, + { x: 8, y: 26, role: 'flank', unitId: 'zhao-yun', label: '능선 차단' }, + { x: 5, y: 29, role: 'support', unitId: 'zhuge-liang', label: '산길 계책' }, + { x: 7, y: 31, role: 'support', unitId: 'ma-liang', label: '마을 기록' }, + { x: 9, y: 28, role: 'support', unitId: 'yi-ji', label: '서약 문안' } + ], + note: + '무릉 산길 확보전은 마량과 이적의 형주 지식이 처음 함께 쓰이는 전장입니다. 산길 입구를 열고, 마을과 창고를 안정시킨 뒤 김선을 물러나게 하십시오.' + }, map: twentyFifthBattleMap, units: twentyFifthBattleUnits, bonds: twentyFifthBattleBonds, mapTextureKey: 'battle-map-twenty-fifth', leaderUnitId: 'wuling-leader-jin-xuan', - quickVictoryTurnLimit: 34, + quickVictoryTurnLimit: 44, baseVictoryGold: 3360, objectives: [ { id: 'leader', - kind: 'defeat-leader', - label: '김선 퇴각', + kind: 'pacify-leader', + label: '김선 설복', rewardGold: 2200, unitId: 'wuling-leader-jin-xuan' }, @@ -3469,26 +3535,62 @@ export const twentyFifthBattleScenario: BattleScenarioDefinition = { rewardGold: 900, unitId: 'zhuge-liang' }, + { + id: 'ma-liang', + kind: 'keep-unit-alive', + label: '마량 생존', + rewardGold: 880, + unitId: 'ma-liang' + }, + { + id: 'mountain-pass', + kind: 'secure-terrain', + label: '산길 주로 확보', + rewardGold: 900, + terrain: 'road', + targetTile: { x: 38, y: 20, radius: 9 }, + threatRadius: 0 + }, { id: 'wuling-village', kind: 'secure-terrain', label: '무릉 마을 안정', rewardGold: 1080, - terrain: 'village' + terrain: 'village', + targetTile: { x: 37, y: 23, radius: 10 }, + threatRadius: 0 + }, + { + id: 'supply-store', + kind: 'secure-terrain', + label: '산길 창고 확보', + rewardGold: 1040, + terrain: 'village', + targetTile: { x: 38, y: 24, radius: 7 }, + threatRadius: 0 }, { id: 'quick', kind: 'quick-victory', - label: '34턴 이내 승리', + label: '44턴 이내 승리', rewardGold: 840, - maxTurn: 34 + maxTurn: 44 } ], defeatConditions: [ { kind: 'unit-defeated', unitId: 'liu-bei' }, - { kind: 'unit-defeated', unitId: 'zhuge-liang' } + { kind: 'unit-defeated', unitId: 'zhuge-liang' }, + { kind: 'unit-defeated', unitId: 'ma-liang' } ], itemRewards: ['콩 11', '상처약 8', '탁주 4', '무릉 산길 지도 +1', '공지 합류'], + campaignReward: { + supplies: ['콩 11', '상처약 8', '탁주 4'], + reputation: ['무릉 산길 지도 +1', '무릉 마을 서약 +1'], + recruits: ['gong-zhi'], + unlockBattleId: 'twenty-sixth-battle-changsha-veteran', + unlockLabel: '장사 노장 대면전 개방', + note: '마량과 이적의 문안으로 무릉 산길과 마을을 안정시켰습니다. 공지가 합류하고, 장사로 향하는 길이 열립니다.' + }, victoryPages: twentyFifthBattleVictoryPages, nextCampScene: 'CampScene' }; diff --git a/src/game/data/campaignFlow.ts b/src/game/data/campaignFlow.ts index ecc2c5b..cc04fcf 100644 --- a/src/game/data/campaignFlow.ts +++ b/src/game/data/campaignFlow.ts @@ -477,8 +477,8 @@ const sortieFlows: Record = { eyebrow: '다음 전장', title: twentySixthBattleScenario.title, description: - '무릉 산길이 열리고 공지가 합류했습니다. 이제 장사의 노장 황충과 의심 많은 한현을 마주하며 형주 남부 확보의 큰 고비를 넘어야 합니다.', - rewardHint: `예상 보상: ${twentySixthBattleScenario.title} 개방 / 황충·위연 합류`, + '서쪽 고갯길, 남쪽 마을, 동쪽 창고가 이어지며 무릉 산길이 열렸고 공지가 합류했습니다. 이제 장사의 노장 황충과 의심 많은 한현을 마주하며 형주 남부 확보의 큰 고비를 넘어야 합니다.', + rewardHint: `예상 보상: ${twentySixthBattleScenario.title} 개방 / 공지의 무릉 길 정보 / 황충·위연 합류`, nextBattleId: twentySixthBattleScenario.id, campaignStep: 'twenty-sixth-battle', pages: [...twentyFifthBattleVictoryPages, ...twentySixthBattleIntroPages] diff --git a/src/game/data/scenario.ts b/src/game/data/scenario.ts index d543cc7..0eec47c 100644 --- a/src/game/data/scenario.ts +++ b/src/game/data/scenario.ts @@ -1892,7 +1892,7 @@ export const twentyFifthBattleIntroPages: StoryPage[] = [ chapter: '무릉의 닫힌 산길', background: 'story-yizhou', speaker: '마량', - text: '무릉은 계양처럼 성문 하나만 바라보는 땅이 아닙니다. 산길과 작은 마을이 흩어져 있어, 길을 잃으면 군량도 마음도 끊어집니다.' + text: '계양에서 얻은 길 이름을 이적 선생의 기록과 맞춰 보았습니다. 서쪽 고갯길, 남쪽 마을, 동쪽 창고가 이어지지 않으면 무릉은 길마다 닫힐 것입니다.' }, { id: 'twenty-fifth-yi-ji-letter', @@ -1900,7 +1900,7 @@ export const twentyFifthBattleIntroPages: StoryPage[] = [ chapter: '먼저 보내는 예', background: 'story-yizhou', speaker: '이적', - text: '김선은 강하게 버티려 하지만, 아래 장수 공지는 백성의 피해를 걱정한다고 들었습니다. 산길 마을을 지키면 그에게 말이 닿을 것입니다.' + text: '김선은 강하게 버티려 하지만 공지는 백성 피해를 걱정한다고 들었습니다. 마을과 창고를 지키면, 항복 권유가 협박이 아니라 약속으로 들릴 것입니다.' }, { id: 'twenty-fifth-zhuge-formation', @@ -1908,7 +1908,7 @@ export const twentyFifthBattleIntroPages: StoryPage[] = [ chapter: '좁은 길의 진형', background: 'story-yizhou', speaker: '제갈량', - text: '좁은 산길에서는 무장이 많다고 곧 힘이 되는 것이 아닙니다. 앞길을 여는 자, 마을을 달래는 자, 보급을 잇는 자를 골라야 합니다.' + text: '장비는 협곡 보병을 밀고, 조운은 능선 척후와 기병을 끊으십시오. 마량과 이적은 뒤에서 길 이름과 서약 문안을 맞추면 됩니다.' }, { id: 'twenty-fifth-wuling-sortie', @@ -1917,7 +1917,7 @@ export const twentyFifthBattleIntroPages: StoryPage[] = [ background: 'story-yizhou', speaker: '유비', portrait: 'liuBei', - text: '산길을 불태우지 말고 이어야 하오. 무릉의 길과 마을을 지켜 내면, 닫힌 마음도 함께 열릴 것이오.' + text: '산길을 빼앗는 것이 아니라 이어야 하오. 백성이 다니는 길과 창고를 지켜 내면, 무릉의 닫힌 마음도 함께 열릴 것이오.' } ]; @@ -1927,7 +1927,7 @@ export const twentyFifthBattleVictoryPages: StoryPage[] = [ bgm: 'militia-theme', chapter: '무릉의 길이 이어지다', background: 'story-yizhou', - text: '김선의 산길 방어선이 무너지자 무릉의 마을들은 먼저 불안한 문을 열었습니다. 유비군은 산길 창고를 봉하고 백성의 길을 지켰습니다.' + text: '서쪽 고갯길과 남쪽 마을, 동쪽 창고가 차례로 안정되자 김선의 산길 방어선은 무너졌습니다. 유비군은 창고를 봉하고 백성이 오가던 길을 지켰습니다.' }, { id: 'twenty-fifth-gong-zhi-joins', @@ -1935,7 +1935,7 @@ export const twentyFifthBattleVictoryPages: StoryPage[] = [ chapter: '공지의 결심', background: 'story-yizhou', speaker: '공지', - text: '무릉을 힘으로만 누르지 않으셨군요. 백성을 앞세우는 군이라면, 저도 산길과 고을의 형세를 바쳐 따르겠습니다.' + text: '무릉을 힘으로만 누르지 않으셨군요. 마량 선생의 지도와 이적 선생의 서약문을 보았습니다. 저도 산길과 고을의 형세를 바쳐 따르겠습니다.' }, { id: 'twenty-fifth-changsha-shadow', @@ -1943,7 +1943,7 @@ export const twentyFifthBattleVictoryPages: StoryPage[] = [ chapter: '장사의 노장', background: 'story-yizhou', speaker: '제갈량', - text: '무릉까지 길이 이어졌습니다. 남은 장사에는 황충이라는 노장이 있습니다. 다음 싸움은 힘보다 예우와 인내를 시험할 것입니다.' + text: '무릉의 길이 이어졌으니 장사로 향할 수 있습니다. 그곳에는 황충이라는 노장이 있습니다. 다음 싸움은 힘보다 예우와 인내를 시험할 것입니다.' } ]; diff --git a/src/game/scenes/CampScene.ts b/src/game/scenes/CampScene.ts index 49ba8b6..07c6105 100644 --- a/src/game/scenes/CampScene.ts +++ b/src/game/scenes/CampScene.ts @@ -938,15 +938,30 @@ const sortieRulesByBattleId: Partial