diff --git a/src/game/scenes/BattleScene.ts b/src/game/scenes/BattleScene.ts index 615efba..d71ecb2 100644 --- a/src/game/scenes/BattleScene.ts +++ b/src/game/scenes/BattleScene.ts @@ -5763,6 +5763,11 @@ export class BattleScene extends Phaser.Scene { ? `${remaining}명의 아군이 아직 행동할 수 있습니다.` : '모든 아군이 행동했습니다. 턴 종료 여부를 선택하세요.'; const completionMessage = `${message}\n${turnHint}`; + + if (remaining > 0 && this.focusNextActionableAlly(unit, completionMessage)) { + return; + } + this.renderRosterPanel('ally', completionMessage); if (remaining === 0) { @@ -5771,6 +5776,55 @@ export class BattleScene extends Phaser.Scene { } } + private actionableAllies() { + return battleUnits.filter((unit) => unit.faction === 'ally' && unit.hp > 0 && !this.actedUnitIds.has(unit.id)); + } + + private firstActionableAlly() { + return this.actionableAllies()[0]; + } + + private nextActionableAllyAfter(completedUnit: UnitData) { + const allies = battleUnits.filter((unit) => unit.faction === 'ally' && unit.hp > 0); + const startIndex = allies.findIndex((unit) => unit.id === completedUnit.id); + const start = startIndex >= 0 ? startIndex : 0; + + for (let offset = 1; offset <= allies.length; offset += 1) { + const candidate = allies[(start + offset) % allies.length]; + if (!this.actedUnitIds.has(candidate.id)) { + return candidate; + } + } + + return undefined; + } + + private focusActionableAlly(unit: UnitData, message?: string) { + if (this.activeFaction !== 'ally' || this.battleOutcome || unit.hp <= 0 || this.actedUnitIds.has(unit.id)) { + return false; + } + + this.centerCameraOnTile(unit.x, unit.y); + this.selectUnit(unit); + + if (this.phase === 'moving' && this.selectedUnit?.id === unit.id && message) { + this.renderUnitDetail(unit, message); + } + + return this.phase === 'moving' && this.selectedUnit?.id === unit.id; + } + + private focusNextActionableAlly(completedUnit: UnitData, completionMessage: string) { + const nextUnit = this.nextActionableAllyAfter(completedUnit); + if (!nextUnit) { + return false; + } + + const summary = completionMessage.split('\n')[0] || `${completedUnit.name} 행동 완료`; + this.renderSituationPanel(`${summary}\n다음 행동: ${nextUnit.name}`); + return this.focusActionableAlly(nextUnit, `${summary}\n다음 행동: ${nextUnit.name}\n이동할 파란 칸을 선택하세요.`); + } + private resolveBattleOutcomeIfNeeded() { if (this.battleOutcome) { return true; @@ -10162,7 +10216,14 @@ export class BattleScene extends Phaser.Scene { this.updateObjectiveTracker(); this.checkBattleEvents(); this.centerCameraOnAllyLine(); - this.renderRosterPanel('ally', [`${this.turnNumber}턴 아군 차례입니다.`, recoveryMessage, '행동할 장수를 선택하세요.'].filter(Boolean).join('\n')); + const turnMessage = [`${this.turnNumber}턴 아군 차례입니다.`, recoveryMessage, '행동할 장수를 선택하세요.'].filter(Boolean).join('\n'); + this.renderRosterPanel('ally', turnMessage); + + const firstUnit = this.firstActionableAlly(); + if (firstUnit) { + this.renderSituationPanel(`${this.turnNumber}턴 아군 차례입니다.\n다음 행동: ${firstUnit.name}`); + this.focusActionableAlly(firstUnit, [`${this.turnNumber}턴 아군 차례입니다.`, recoveryMessage, '이동할 파란 칸을 선택하세요.'].filter(Boolean).join('\n')); + } } private applyTerrainRecovery(faction: ActiveFaction) {