From 18c90673f79770884ae533cbb3948c17890c02aa Mon Sep 17 00:00:00 2001 From: Wickedness Date: Sat, 4 Jul 2026 22:49:48 +0900 Subject: [PATCH] Refine Yiling vanguard battle flow --- src/game/data/battles.ts | 85 +++++++++++++++++++++++++++++++++- src/game/data/scenario.ts | 10 ++-- src/game/scenes/BattleScene.ts | 12 +++++ src/game/scenes/CampScene.ts | 30 +++++++++--- 4 files changed, 123 insertions(+), 14 deletions(-) diff --git a/src/game/data/battles.ts b/src/game/data/battles.ts index c52b1fd..06874d6 100644 --- a/src/game/data/battles.ts +++ b/src/game/data/battles.ts @@ -6486,6 +6486,75 @@ export const fortyFifthBattleScenario: BattleScenarioDefinition = { '오군은 정면 결전을 피하고 숲길, 강변, 나루에 전초선을 깔았습니다. 길게 늘어선 진영이 끊기지 않게 강변 보급로를 확보하십시오.', '장비, 조운, 마초처럼 돌파와 기동에 강한 장수로 선봉을 밀고, 제갈량과 황권처럼 보급과 화계를 읽는 참모를 곁에 두면 안정적입니다.' ], + tacticalGuide: { + summary: + '이릉 진격로는 형주 상실 뒤 유비군이 강동을 향해 깊게 들어가는 첫 전투입니다. 오군은 크게 맞붙지 않고 숲길, 강변 진영, 나루 보급점을 끊어 촉한군을 길게 늘어뜨리려 합니다.', + route: '서쪽 강변 진영 정비 -> 중앙 숲길 전초선 돌파 -> 동진로 보급점 확보 -> 남쪽 나루 견제 -> 육손 전초선 압박', + focus: + '분노로 빠르게 밀어붙이되, 강변 진영과 동진 보급점을 놓치면 다음 이릉 화공전에서 긴 군막과 보급 위험이 더 자연스럽게 이어집니다.', + roles: [ + '유비: 복수전의 주장입니다. 후방 강변 진영을 붙들며 전선이 너무 길어지지 않게 해야 합니다.', + '장비: 중앙 숲길을 밀어 여는 선봉입니다. 오군 보병이 길목을 닫기 전에 먼저 전열을 흔듭니다.', + '조운: 강변과 숲길 사이를 오가며 끊어진 아군을 잇는 기동 축입니다.', + '마초: 동쪽 기병과 전초선을 강하게 눌러 오군의 유인을 늦춥니다.', + '제갈량/황권: 보급로와 화공 위험을 읽고 강변 진영, 나루, 동진로 목표를 안정시킵니다.', + '마량: 형주 잔병과 현지 민심을 수습해 길어진 전선의 사기를 붙듭니다.' + ], + events: { + 'village-approach': { + title: '동진 보급점', + lines: [ + '황권: 저 보급점이 비면 군막이 길게 늘어져도 서로를 살필 방법이 없습니다.', + '유비: 앞으로 나아가되 돌아올 길도 끊기지 않게 하라.' + ] + }, + 'enemy-posture': { + title: '물러서는 오군', + lines: [ + '제갈량: 오군은 패해서 물러나는 것이 아닙니다. 우리 진영이 길어지는 때를 기다리고 있습니다.', + '장비: 숨는 적도 길목을 끊으면 결국 칼 앞에 나올 것이다.' + ] + }, + 'leader-wavering': { + title: '육손의 전초선', + lines: [ + '육손: 촉군의 기세는 거세나 군막은 길고 마음은 급하다. 아직 큰불을 놓을 때가 아니다.', + '마량: 전초선을 넘더라도 강변의 표식과 보급 말뚝을 남겨야 합니다.' + ] + } + } + }, + sortie: { + sortieLimit: 7, + requiredUnits: ['liu-bei'], + recommendedUnits: [ + { unitId: 'liu-bei', role: 'reserve', reason: '형주 상실 뒤 이릉으로 향하는 복수전의 주장입니다.' }, + { unitId: 'zhang-fei', role: 'front', reason: '중앙 숲길을 빠르게 밀어 여는 강한 선봉입니다.' }, + { unitId: 'zhao-yun', role: 'flank', reason: '강변과 숲길 사이를 오가며 늘어진 진영을 보강합니다.' }, + { unitId: 'ma-chao', role: 'flank', reason: '오군 기병과 동쪽 전초선을 강하게 맞받아칩니다.' }, + { unitId: 'zhuge-liang', role: 'support', reason: '육손의 기다림과 화공 위험을 먼저 읽습니다.' }, + { unitId: 'huang-quan', role: 'support', reason: '긴 보급로와 강변 진영의 안전을 계산합니다.' }, + { unitId: 'ma-liang', role: 'support', reason: '형주 잔병과 현지 민심을 다독이는 연결 축입니다.' } + ], + recommendedClasses: [ + { label: '복수전 주장', classKeys: ['lord'], reason: '유비 생존과 후방 진영 유지가 패배 조건을 안정시킵니다.' }, + { label: '숲길 돌파', classKeys: ['infantry', 'spearman'], reason: '중앙 숲길 전초선을 빠르게 밀어야 전선이 늘어지지 않습니다.' }, + { label: '강변 기동', classKeys: ['cavalry'], reason: '강변과 동쪽 전초선 사이의 긴 거리를 빠르게 메웁니다.' }, + { label: '원거리 견제', classKeys: ['archer'], reason: '숲그늘 궁병과 나루 수군을 안전하게 눌러 줍니다.' }, + { label: '보급 판단', classKeys: ['strategist'], reason: '보급점, 나루, 화공 위험을 읽어 다음 전투의 피해를 줄입니다.' } + ], + deploymentSlots: [ + { x: 14, y: 36, role: 'reserve', unitId: 'liu-bei', label: '복수전 주장' }, + { x: 16, y: 39, role: 'front', unitId: 'zhang-fei', label: '숲길 선봉' }, + { x: 18, y: 34, role: 'flank', unitId: 'zhao-yun', label: '강변 기동' }, + { x: 23, y: 34, role: 'flank', unitId: 'ma-chao', label: '동쪽 압박' }, + { x: 8, y: 38, role: 'support', unitId: 'zhuge-liang', label: '화공 대비' }, + { x: 8, y: 33, role: 'support', unitId: 'huang-quan', label: '보급 계산' }, + { x: 13, y: 32, role: 'support', unitId: 'ma-liang', label: '잔병 수습' } + ], + note: + '이릉 진격로는 이기는 것보다 진영을 너무 길게 흩지 않는 것이 핵심입니다. 선봉으로 중앙 숲길을 열고, 기동 병종으로 강변과 동쪽 보급점을 이어 주십시오.' + }, map: fortyFifthBattleMap, units: fortyFifthBattleUnits, bonds: fortyFifthBattleBonds, @@ -6513,14 +6582,18 @@ export const fortyFifthBattleScenario: BattleScenarioDefinition = { kind: 'secure-terrain', label: '강변 진영 확보', rewardGold: 3120, - terrain: 'camp' + terrain: 'camp', + targetTile: { x: 52, y: 42, radius: 5 }, + threatRadius: 0 }, { id: 'yiling-road', kind: 'secure-terrain', label: '동진로 보급점 확보', rewardGold: 2480, - terrain: 'village' + terrain: 'village', + targetTile: { x: 74, y: 34, radius: 5 }, + threatRadius: 0 }, { id: 'quick', @@ -6532,6 +6605,14 @@ export const fortyFifthBattleScenario: BattleScenarioDefinition = { ], defeatConditions: [{ kind: 'unit-defeated', unitId: 'liu-bei' }], itemRewards: ['콩 46', '상처약 36', '탁주 15', '이릉 동진 지도 1', '강변 진영 말뚝 1'], + campaignReward: { + supplies: ['콩 46', '상처약 36', '탁주 15'], + equipment: ['이릉 동진 지도 1', '강변 진영 말뚝 1'], + reputation: ['오군 전초선 표식 1'], + unlockLabel: '이릉 화공전', + note: + '이릉으로 향하는 첫 길은 열렸지만, 촉한군의 진영은 강변과 숲길을 따라 길게 늘어졌습니다. 다음 군영에서는 군막 간격과 화공 대비를 먼저 점검해야 합니다.' + }, victoryPages: fortyFifthBattleVictoryPages, nextCampScene: 'CampScene' }; diff --git a/src/game/data/scenario.ts b/src/game/data/scenario.ts index 34203a7..cb96ed6 100644 --- a/src/game/data/scenario.ts +++ b/src/game/data/scenario.ts @@ -3234,7 +3234,7 @@ export const fortyFifthBattleIntroPages: StoryPage[] = [ background: 'story-yiling-baidi', speaker: '유비', portrait: 'liuBei', - text: '형주의 상실은 땅 하나를 잃은 일이 아니오. 함께 세운 뜻이 강동의 말과 불길에 찢긴 일이오. 이릉으로 가는 길을 열어, 무너진 의리를 다시 묻겠소.' + text: '형주의 상실은 땅 하나를 잃은 일이 아니오. 함께 세운 뜻이 강동의 말과 불길에 찢긴 일이오. 하지만 군막이 흩어지면 복수도 길을 잃소. 강변 진영을 세우고 이릉으로 가는 첫 길을 열겠소.' }, { id: 'forty-fifth-zhuge-warning', @@ -3242,7 +3242,7 @@ export const fortyFifthBattleIntroPages: StoryPage[] = [ chapter: '분노와 군략', background: 'story-yiling-baidi', speaker: '제갈량', - text: '분노는 군을 움직이지만, 오래 버티게 하지는 못합니다. 오군은 산림과 물길을 이용해 긴 보급로를 태우려 할 것입니다. 먼저 이릉으로 향하는 동진로를 열고 진영을 흩어지지 않게 해야 합니다.' + text: '오군은 크게 맞붙지 않고 숲길과 나루를 비워 두는 척할 것입니다. 중앙 숲길을 뚫더라도 강변 진영과 동진 보급점에 표식을 남기십시오. 그 표식이 다음 화공의 피해를 가를 것입니다.' }, { id: 'forty-fifth-sortie', @@ -3251,7 +3251,7 @@ export const fortyFifthBattleIntroPages: StoryPage[] = [ background: 'story-yiling-baidi', speaker: '유비', portrait: 'liuBei', - text: '장강을 따라 깊이 들어가면 돌아올 길도 길어지오. 동진로의 숲과 나루를 안정시키고, 오군 선봉을 밀어 이릉 전쟁의 첫 진영을 세우시오.' + text: '장비는 숲길 선봉을 맡고, 조운과 마초는 강변과 동쪽 길을 잇게 하라. 참모들은 보급 말뚝을 세우라. 오늘의 목표는 오군 전초선 격파와 이릉 진격로 확보요.' } ]; @@ -3261,7 +3261,7 @@ export const fortyFifthBattleVictoryPages: StoryPage[] = [ bgm: 'militia-theme', chapter: '세워진 복수의 진', background: 'story-yiling-baidi', - text: '이릉으로 향하는 첫 진격로가 열렸습니다. 유비군은 강가와 숲 사이에 진영을 세웠지만, 긴 보급로와 뜨거운 여름 바람은 이미 다음 위기를 예고했습니다.' + text: '오군 전초선은 물러났고, 강변 진영과 동진 보급점에는 촉한의 말뚝이 박혔습니다. 그러나 군막은 강가와 숲 사이로 길게 늘어졌고, 뜨거운 바람은 마른 풀을 흔들고 있었습니다.' }, { id: 'forty-fifth-lu-xun-watches', @@ -3269,7 +3269,7 @@ export const fortyFifthBattleVictoryPages: StoryPage[] = [ chapter: '육손의 침묵', background: 'story-yiling-baidi', speaker: '제갈량', - text: '오군은 크게 맞붙지 않았습니다. 육손은 물러난 것이 아니라 기다리고 있습니다. 진영이 길게 늘어설수록, 불길 하나가 군 전체를 흔들 수 있습니다.' + text: '이긴 듯 보이나 오군은 힘을 아꼈습니다. 육손은 물러난 것이 아니라 기다리고 있습니다. 보급 말뚝 사이가 멀어질수록, 불길 하나가 군 전체를 흔들 수 있습니다.' }, { id: 'forty-fifth-next-yiling-main', diff --git a/src/game/scenes/BattleScene.ts b/src/game/scenes/BattleScene.ts index b1711e5..f093024 100644 --- a/src/game/scenes/BattleScene.ts +++ b/src/game/scenes/BattleScene.ts @@ -10721,6 +10721,15 @@ export class BattleScene extends Phaser.Scene { this.hideMapMenu(); } + private isPointerOnSidePanel(pointer: Phaser.Input.Pointer) { + return ( + pointer.x >= this.layout.panelX && + pointer.x <= this.layout.panelX + this.layout.panelWidth && + pointer.y >= this.layout.panelY && + pointer.y <= this.layout.panelY + this.layout.panelHeight + ); + } + private handleLeftClick(pointer: Phaser.Input.Pointer) { if (this.battleOutcome) { return; @@ -10732,6 +10741,9 @@ export class BattleScene extends Phaser.Scene { } if (this.phase === 'deployment') { + if (this.isPointerOnSidePanel(pointer)) { + return; + } const tile = this.pointerToTile(pointer); if (tile) { this.handleDeploymentTileClick(tile.x, tile.y); diff --git a/src/game/scenes/CampScene.ts b/src/game/scenes/CampScene.ts index a9cdd7d..6f0a6e7 100644 --- a/src/game/scenes/CampScene.ts +++ b/src/game/scenes/CampScene.ts @@ -1515,14 +1515,30 @@ const sortieRulesByBattleId: Partial