From 18c47b73e35a92e09c7749971b8873ad2e18c398 Mon Sep 17 00:00:00 2001 From: Wickedness Date: Sat, 4 Jul 2026 18:49:43 +0900 Subject: [PATCH] Refine Guiyang persuasion battle flow --- src/game/data/battles.ts | 120 +++++++++++++++++++++++++++++++--- src/game/data/campaignFlow.ts | 4 +- src/game/data/scenario.ts | 12 ++-- src/game/scenes/CampScene.ts | 29 ++++++-- 4 files changed, 140 insertions(+), 25 deletions(-) diff --git a/src/game/data/battles.ts b/src/game/data/battles.ts index 613bffd..20e1645 100644 --- a/src/game/data/battles.ts +++ b/src/game/data/battles.ts @@ -3271,23 +3271,87 @@ export const twentyFourthBattleScenario: BattleScenarioDefinition = { id: 'twenty-fourth-battle-guiyang-persuasion', 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: 'guan-yu', role: 'front', reason: '조범 친위대와 성문 보병을 받아낼 주력 전열입니다.' }, + { unitId: 'sun-qian', role: 'support', reason: '이적 합류로 이어질 외교 문안과 항복 조건을 정리합니다.' } + ], + recommendedClasses: [ + { label: '설득 명분', classKeys: ['lord'], reason: '유비가 살아 남아야 계양의 항복 명분이 유지됩니다.' }, + { label: '서신 문관', classKeys: ['strategist'], reason: '마량과 제갈량의 생존이 마을 안정과 이적 합류의 핵심입니다.' }, + { label: '성문 전열', classKeys: ['infantry', 'spearman'], reason: '조범 친위대와 성문 보병은 튼튼한 전열이 받아내야 합니다.' }, + { label: '남문 차단', classKeys: ['cavalry'], reason: '기동 장수가 산길 척후와 남문 기병을 먼저 끊어야 서신로가 열립니다.' } + ], + deploymentSlots: [ + { x: 5, y: 24, role: 'reserve', unitId: 'liu-bei', label: '설득 명분' }, + { x: 7, y: 22, role: 'front', unitId: 'guan-yu', label: '성문 전열' }, + { x: 9, y: 22, role: 'flank', unitId: 'zhao-yun', label: '남문 차단' }, + { x: 6, y: 24, role: 'support', unitId: 'zhuge-liang', label: '항복 조건' }, + { x: 8, y: 26, role: 'support', unitId: 'ma-liang', label: '백미 서신' }, + { x: 9, y: 25, role: 'support', unitId: 'sun-qian', label: '외교 문안' } + ], + note: '계양 설득전은 마량이 처음으로 필수 출전하는 전장입니다. 유비, 제갈량, 마량을 지키며 마을과 서신 길목을 안정시킨 뒤 성문 친위대를 압박하는 편성이 좋습니다.' + }, map: twentyFourthBattleMap, units: twentyFourthBattleUnits, bonds: twentyFourthBattleBonds, mapTextureKey: 'battle-map-twenty-fourth', leaderUnitId: 'guiyang-leader-zhao-fan', - quickVictoryTurnLimit: 33, + quickVictoryTurnLimit: 42, baseVictoryGold: 3180, objectives: [ { id: 'leader', - kind: 'defeat-leader', + kind: 'pacify-leader', label: '조범 항복', rewardGold: 2100, unitId: 'guiyang-leader-zhao-fan' @@ -3306,26 +3370,62 @@ export const twentyFourthBattleScenario: BattleScenarioDefinition = { rewardGold: 880, unitId: 'zhuge-liang' }, + { + id: 'ma-liang', + kind: 'keep-unit-alive', + label: '마량 생존', + rewardGold: 880, + unitId: 'ma-liang' + }, { id: 'guiyang-village', kind: 'secure-terrain', label: '계양 마을 안정', rewardGold: 1040, - terrain: 'village' + terrain: 'village', + targetTile: { x: 31, y: 18, radius: 8 }, + threatRadius: 0 + }, + { + id: 'letter-road', + kind: 'secure-terrain', + label: '서신 길목 확보', + rewardGold: 920, + terrain: 'village', + targetTile: { x: 35, y: 15, radius: 6 }, + threatRadius: 0 + }, + { + id: 'gate-pressure', + kind: 'secure-terrain', + label: '성문 친위대 압박', + rewardGold: 1120, + terrain: 'fort', + targetTile: { x: 40, y: 19, radius: 5 }, + threatRadius: 0 }, { id: 'quick', kind: 'quick-victory', - label: '33턴 이내 승리', + label: '42턴 이내 승리', rewardGold: 800, - maxTurn: 33 + maxTurn: 42 } ], 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: ['콩 10', '상처약 7', '탁주 4', '계양 설득 문서 +1', '이적 합류'], + campaignReward: { + supplies: ['콩 10', '상처약 7', '탁주 4'], + reputation: ['계양 설득 문서 +1', '계양 민심 안정 +1'], + recruits: ['yi-ji'], + unlockBattleId: 'twenty-fifth-battle-wuling-mountain-road', + unlockLabel: '무릉 산길 확보전 개방', + note: '마량의 서신과 유비군의 군율로 계양의 문을 열었습니다. 이적이 합류하고, 두 문사의 현지 정보가 무릉 산길 확보전으로 이어집니다.' + }, victoryPages: twentyFourthBattleVictoryPages, nextCampScene: 'CampScene' }; diff --git a/src/game/data/campaignFlow.ts b/src/game/data/campaignFlow.ts index 3c1577d..ecc2c5b 100644 --- a/src/game/data/campaignFlow.ts +++ b/src/game/data/campaignFlow.ts @@ -466,8 +466,8 @@ const sortieFlows: Record = { eyebrow: '다음 전장', title: twentyFifthBattleScenario.title, description: - '계양이 열리고 이적이 합류했습니다. 이제 마량과 이적의 형주 지식을 앞세워 험한 무릉 산길과 흩어진 마을을 이어야 합니다.', - rewardHint: `예상 보상: ${twentyFifthBattleScenario.title} 개방 / 공지 합류`, + '마량의 서신과 유비군의 군율로 계양의 문을 열었고, 이적이 합류했습니다. 이제 두 문사의 형주 지식을 앞세워 험한 무릉 산길과 흩어진 마을을 이어야 합니다.', + rewardHint: `예상 보상: ${twentyFifthBattleScenario.title} 개방 / 공지 합류 / 무릉 산길 정보`, nextBattleId: twentyFifthBattleScenario.id, campaignStep: 'twenty-fifth-battle', pages: [...twentyFourthBattleVictoryPages, ...twentyFifthBattleIntroPages] diff --git a/src/game/data/scenario.ts b/src/game/data/scenario.ts index 9305ccc..d543cc7 100644 --- a/src/game/data/scenario.ts +++ b/src/game/data/scenario.ts @@ -1830,7 +1830,7 @@ export const twentyFourthBattleIntroPages: StoryPage[] = [ chapter: '계양으로 가는 서신', background: 'story-yizhou', speaker: '마량', - text: '계양의 조범은 항복과 저항 사이에서 눈치를 보고 있습니다. 먼저 서신을 보내되, 길목의 군사들이 백성을 겁박하지 못하게 막아야 합니다.' + text: '계양의 조범은 항복과 저항 사이에서 눈치를 보고 있습니다. 제 서신이 마을 장로들에게 닿기 전, 길목 군사들이 백성을 겁박하지 못하게 막아야 합니다.' }, { id: 'twenty-fourth-zhuge-plan', @@ -1838,7 +1838,7 @@ export const twentyFourthBattleIntroPages: StoryPage[] = [ chapter: '칼보다 먼저 놓는 글', background: 'story-yizhou', speaker: '제갈량', - text: '이번 전투는 성을 불태우는 싸움이 아닙니다. 마을을 안정시키고 조범의 친위대를 물리치면, 계양은 스스로 문을 열 것입니다.' + text: '이번 전투는 성을 불태우는 싸움이 아닙니다. 남부 마을과 서신 길목을 안정시킨 뒤 조범의 친위대를 물리치면, 계양은 스스로 항복 조건을 따질 것입니다.' }, { id: 'twenty-fourth-yi-ji-rumor', @@ -1855,7 +1855,7 @@ export const twentyFourthBattleIntroPages: StoryPage[] = [ background: 'story-yizhou', speaker: '유비', portrait: 'liuBei', - text: '오늘의 목적은 계양을 꺾는 것이 아니라 열어 보이는 것이오. 마을을 지키고 성채를 압박하되, 백성이 다시 문을 닫지 않게 하시오.' + text: '오늘의 목적은 계양을 꺾는 것이 아니라 열어 보이는 것이오. 마량의 서신을 지키고 성채를 압박하되, 백성이 다시 문을 닫지 않게 하시오.' } ]; @@ -1865,7 +1865,7 @@ export const twentyFourthBattleVictoryPages: StoryPage[] = [ bgm: 'militia-theme', chapter: '계양의 문이 열리다', background: 'story-yizhou', - text: '조범의 친위대가 물러나자 계양의 성문은 불길이 아니라 서신 앞에서 열렸습니다. 유비군은 군율을 세우고 마을의 창고를 함부로 건드리지 않았습니다.' + text: '남부 마을과 서신 길목이 안정되고 조범의 친위대가 물러나자, 계양의 성문은 불길이 아니라 서신 앞에서 열렸습니다. 유비군은 마을 창고를 함부로 건드리지 않았습니다.' }, { id: 'twenty-fourth-yi-ji-joins', @@ -1873,7 +1873,7 @@ export const twentyFourthBattleVictoryPages: StoryPage[] = [ chapter: '이적의 합류', background: 'story-yizhou', speaker: '이적', - text: '주공께서 계양을 힘으로만 다루지 않으셨다는 말을 들었습니다. 형주의 글과 예가 필요하다면, 저도 붓과 길을 보태겠습니다.' + text: '마량의 서신과 주공의 군율을 보았습니다. 계양을 힘으로만 다루지 않는 군이라면, 형주의 글과 예를 아는 저도 붓과 길을 보태겠습니다.' }, { id: 'twenty-fourth-next-commandery', @@ -1881,7 +1881,7 @@ export const twentyFourthBattleVictoryPages: StoryPage[] = [ chapter: '험한 무릉의 길', background: 'story-yizhou', speaker: '제갈량', - text: '계양은 열렸지만 무릉의 산길은 아직 닫혀 있습니다. 다음에는 험한 길을 뚫고 흩어진 마을을 잇는 싸움이 될 것입니다.' + text: '계양은 열렸지만 무릉의 산길은 아직 닫혀 있습니다. 마량과 이적의 지도를 함께 펴고, 험한 길과 흩어진 마을을 잇는 싸움을 준비해야 합니다.' } ]; diff --git a/src/game/scenes/CampScene.ts b/src/game/scenes/CampScene.ts index 0fec5d9..49ba8b6 100644 --- a/src/game/scenes/CampScene.ts +++ b/src/game/scenes/CampScene.ts @@ -911,15 +911,30 @@ const sortieRulesByBattleId: Partial