Auto-focus next ally after actions

This commit is contained in:
2026-07-02 23:14:51 +09:00
parent eee2c52b39
commit 85b1f23ec2

View File

@@ -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) {