Improve final unit move turn prompt
This commit is contained in:
@@ -237,7 +237,7 @@ try {
|
||||
throw new Error(`Expected positional bond bonuses and reduced counter damage: ${JSON.stringify(combatMechanicsProbe)}`);
|
||||
}
|
||||
|
||||
const moveWaitTurnPromptState = await page.evaluate(() => {
|
||||
const moveWaitTurnPromptStates = await page.evaluate(() => {
|
||||
const scene = window.__HEROS_GAME__?.scene.getScene('BattleScene');
|
||||
const state = window.__HEROS_DEBUG__?.battle();
|
||||
const lastAlly = state?.units?.find((unit) => unit.id === 'zhang-fei');
|
||||
@@ -261,11 +261,26 @@ try {
|
||||
|
||||
scene.selectUnit(liveLastAlly);
|
||||
scene.moveSelectedUnit(liveLastAlly.x, liveLastAlly.y);
|
||||
const postMoveState = window.__HEROS_DEBUG__?.battle();
|
||||
scene.completeUnitAction(liveLastAlly, 'wait');
|
||||
return window.__HEROS_DEBUG__?.battle();
|
||||
const postWaitState = window.__HEROS_DEBUG__?.battle();
|
||||
return { postMoveState, postWaitState };
|
||||
});
|
||||
if (!moveWaitTurnPromptState?.turnPromptVisible || moveWaitTurnPromptState.phase !== 'idle') {
|
||||
throw new Error(`Expected move-wait completion to show turn-end prompt: ${JSON.stringify(moveWaitTurnPromptState)}`);
|
||||
if (
|
||||
!moveWaitTurnPromptStates?.postMoveState?.turnPromptVisible ||
|
||||
moveWaitTurnPromptStates.postMoveState.turnPromptMode !== 'post-move' ||
|
||||
moveWaitTurnPromptStates.postMoveState.phase !== 'command' ||
|
||||
moveWaitTurnPromptStates.postMoveState.pendingMove?.unitId !== 'zhang-fei' ||
|
||||
moveWaitTurnPromptStates.postMoveState.actedUnitIds?.includes('zhang-fei')
|
||||
) {
|
||||
throw new Error(`Expected final ally move to show post-move turn prompt: ${JSON.stringify(moveWaitTurnPromptStates)}`);
|
||||
}
|
||||
if (
|
||||
!moveWaitTurnPromptStates.postWaitState?.turnPromptVisible ||
|
||||
moveWaitTurnPromptStates.postWaitState.turnPromptMode !== 'turn-end' ||
|
||||
moveWaitTurnPromptStates.postWaitState.phase !== 'idle'
|
||||
) {
|
||||
throw new Error(`Expected move-wait completion to show turn-end prompt: ${JSON.stringify(moveWaitTurnPromptStates)}`);
|
||||
}
|
||||
|
||||
await page.evaluate(() => {
|
||||
|
||||
@@ -1015,6 +1015,17 @@ type MapMenuAction = 'endTurn' | 'threat' | 'save' | 'load' | 'roster' | 'bond'
|
||||
type EnemyAiBehavior = 'aggressive' | 'guard' | 'hold';
|
||||
type BattleOutcome = 'victory' | 'defeat';
|
||||
type SaveSlotMode = 'save' | 'load';
|
||||
type TurnPromptMode = 'turn-end' | 'post-move';
|
||||
|
||||
type TurnEndPromptOptions = {
|
||||
mode?: TurnPromptMode;
|
||||
title?: string;
|
||||
body?: string;
|
||||
primaryLabel?: string;
|
||||
secondaryLabel?: string;
|
||||
primaryAction?: () => void;
|
||||
secondaryAction?: () => void;
|
||||
};
|
||||
|
||||
type BattleSceneData = {
|
||||
battleId?: string;
|
||||
@@ -2716,6 +2727,7 @@ export class BattleScene extends Phaser.Scene {
|
||||
private alertDismissEvent?: Phaser.Time.TimerEvent;
|
||||
private battleEventObjects: Phaser.GameObjects.GameObject[] = [];
|
||||
private turnPromptObjects: Phaser.GameObjects.GameObject[] = [];
|
||||
private turnPromptMode?: TurnPromptMode;
|
||||
private combatCutInObjects: Phaser.GameObjects.GameObject[] = [];
|
||||
private resultObjects: Phaser.GameObjects.GameObject[] = [];
|
||||
private resultGaugeAnimations: ResultGaugeAnimation[] = [];
|
||||
@@ -3403,8 +3415,38 @@ export class BattleScene extends Phaser.Scene {
|
||||
this.moveUnitView(unit, x, y, view);
|
||||
}
|
||||
this.showCommandMenu(unit, pointer?.x ?? targetX, pointer?.y ?? targetY);
|
||||
const finalAllyHint = this.remainingAllyCount() === 1 ? '\n마지막 미행동 장수입니다. 대기를 선택하면 턴 종료 확인이 열립니다.' : '';
|
||||
const isFinalAlly = this.remainingAllyCount() === 1;
|
||||
const finalAllyHint = isFinalAlly ? '\n마지막 미행동 장수입니다. 바로 턴 종료 확인을 선택할 수 있습니다.' : '';
|
||||
this.renderUnitDetail(unit, `공격, 책략, 도구, 대기 중 하나를 선택하세요.\n우클릭하면 이동을 취소합니다.${finalAllyHint}`);
|
||||
|
||||
if (isFinalAlly) {
|
||||
this.showPostMoveTurnEndPrompt(unit);
|
||||
return;
|
||||
}
|
||||
|
||||
this.hideTurnEndPrompt();
|
||||
}
|
||||
|
||||
private showPostMoveTurnEndPrompt(unit: UnitData) {
|
||||
this.showTurnEndPrompt(undefined, {
|
||||
mode: 'post-move',
|
||||
title: '마지막 장수 이동 완료',
|
||||
body: '대기로 행동을 마치고 턴을 종료할까요?',
|
||||
primaryLabel: '대기 후 턴 종료',
|
||||
secondaryLabel: '명령 선택',
|
||||
primaryAction: () => {
|
||||
if (this.phase !== 'command' || this.selectedUnit?.id !== unit.id || this.actedUnitIds.has(unit.id)) {
|
||||
this.hideTurnEndPrompt();
|
||||
return;
|
||||
}
|
||||
|
||||
this.completeUnitAction(unit, 'wait');
|
||||
if (this.activeFaction === 'ally' && !this.battleOutcome) {
|
||||
this.endAllyTurn();
|
||||
}
|
||||
},
|
||||
secondaryAction: () => this.hideTurnEndPrompt()
|
||||
});
|
||||
}
|
||||
|
||||
private canMoveTo(unit: UnitData, x: number, y: number) {
|
||||
@@ -3768,6 +3810,7 @@ export class BattleScene extends Phaser.Scene {
|
||||
return;
|
||||
}
|
||||
if (choicePointer.leftButtonDown()) {
|
||||
this.hideTurnEndPrompt();
|
||||
if (command === 'strategy' || command === 'item') {
|
||||
this.showUsableMenu(unit, command, choicePointer.x, choicePointer.y);
|
||||
return;
|
||||
@@ -4013,6 +4056,7 @@ export class BattleScene extends Phaser.Scene {
|
||||
return;
|
||||
}
|
||||
|
||||
this.hideTurnEndPrompt();
|
||||
this.phase = 'targeting';
|
||||
this.targetingAction = action;
|
||||
this.selectedUsable = usable;
|
||||
@@ -4041,6 +4085,7 @@ export class BattleScene extends Phaser.Scene {
|
||||
return;
|
||||
}
|
||||
|
||||
this.hideTurnEndPrompt();
|
||||
this.phase = 'targeting';
|
||||
this.targetingAction = usable.command;
|
||||
this.selectedUsable = usable;
|
||||
@@ -8014,6 +8059,7 @@ export class BattleScene extends Phaser.Scene {
|
||||
this.selectedUnit = unit;
|
||||
this.pendingMove = undefined;
|
||||
this.hideCommandMenu();
|
||||
this.hideTurnEndPrompt();
|
||||
this.updateMiniMap();
|
||||
soundDirector.playSelect();
|
||||
|
||||
@@ -8396,11 +8442,12 @@ export class BattleScene extends Phaser.Scene {
|
||||
});
|
||||
}
|
||||
|
||||
private showTurnEndPrompt(message?: string) {
|
||||
private showTurnEndPrompt(message?: string, options: TurnEndPromptOptions = {}) {
|
||||
this.hideTurnEndPrompt();
|
||||
this.turnPromptMode = options.mode ?? 'turn-end';
|
||||
|
||||
const width = 360;
|
||||
const height = 156;
|
||||
const width = 388;
|
||||
const height = 162;
|
||||
const left = this.layout.mapX + this.layout.mapWidth / 2 - width / 2;
|
||||
const top = this.layout.mapY + this.layout.mapHeight / 2 - height / 2;
|
||||
const panel = this.add.rectangle(left, top, width, height, 0x101821, 0.96);
|
||||
@@ -8409,7 +8456,7 @@ export class BattleScene extends Phaser.Scene {
|
||||
panel.setStrokeStyle(2, palette.gold, 0.9);
|
||||
this.turnPromptObjects.push(panel);
|
||||
|
||||
const title = this.add.text(left + width / 2, top + 26, '모든 아군의 행동이 종료되었습니다.', {
|
||||
const title = this.add.text(left + width / 2, top + 26, options.title ?? '모든 아군의 행동이 종료되었습니다.', {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '20px',
|
||||
color: '#f2e3bf',
|
||||
@@ -8419,31 +8466,38 @@ export class BattleScene extends Phaser.Scene {
|
||||
title.setDepth(41);
|
||||
this.turnPromptObjects.push(title);
|
||||
|
||||
const body = this.add.text(left + width / 2, top + 58, '턴을 종료하시겠습니까?', {
|
||||
const body = this.add.text(left + width / 2, top + 58, options.body ?? '턴을 종료하시겠습니까?', {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '17px',
|
||||
color: '#d4dce6'
|
||||
color: '#d4dce6',
|
||||
align: 'center',
|
||||
wordWrap: { width: width - 44, useAdvancedWrap: true }
|
||||
});
|
||||
body.setOrigin(0.5);
|
||||
body.setDepth(41);
|
||||
this.turnPromptObjects.push(body);
|
||||
|
||||
const primaryLabel = options.primaryLabel ?? '턴 종료';
|
||||
const secondaryLabel = options.secondaryLabel ?? '전장 확인';
|
||||
const primaryAction = options.primaryAction ?? (() => this.endAllyTurn());
|
||||
const secondaryAction = options.secondaryAction ?? (() => this.hideTurnEndPrompt());
|
||||
const buttonWidth = 136;
|
||||
const buttons = [
|
||||
{ label: '턴 종료', x: left + 106, action: () => this.endAllyTurn() },
|
||||
{ label: '전장 확인', x: left + 254, action: () => this.hideTurnEndPrompt() }
|
||||
{ label: primaryLabel, x: left + 119, action: primaryAction, primary: true },
|
||||
{ label: secondaryLabel, x: left + 269, action: secondaryAction, primary: false }
|
||||
];
|
||||
|
||||
buttons.forEach(({ label, x, action }) => {
|
||||
const bg = this.add.rectangle(x, top + 112, 116, 36, 0x1a2630, 0.95);
|
||||
buttons.forEach(({ label, x, action, primary }) => {
|
||||
const bg = this.add.rectangle(x, top + 116, buttonWidth, 36, 0x1a2630, 0.95);
|
||||
bg.setDepth(41);
|
||||
bg.setStrokeStyle(1, label === '턴 종료' ? palette.gold : palette.blue, 0.72);
|
||||
bg.setStrokeStyle(1, primary ? palette.gold : palette.blue, 0.72);
|
||||
bg.setInteractive({ useHandCursor: true });
|
||||
bg.on('pointerover', () => bg.setFillStyle(0x283947, 0.98));
|
||||
bg.on('pointerout', () => bg.setFillStyle(0x1a2630, 0.95));
|
||||
bg.on('pointerdown', action);
|
||||
this.turnPromptObjects.push(bg);
|
||||
|
||||
const text = this.add.text(x, top + 112, label, {
|
||||
const text = this.add.text(x, top + 116, label, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '16px',
|
||||
color: '#f2e3bf',
|
||||
@@ -8462,6 +8516,7 @@ export class BattleScene extends Phaser.Scene {
|
||||
private hideTurnEndPrompt() {
|
||||
this.turnPromptObjects.forEach((object) => object.destroy());
|
||||
this.turnPromptObjects = [];
|
||||
this.turnPromptMode = undefined;
|
||||
}
|
||||
|
||||
private pushBattleLog(message: string) {
|
||||
@@ -9180,6 +9235,7 @@ export class BattleScene extends Phaser.Scene {
|
||||
mapBackgroundReady: this.mapBackground?.texture.key === battleScenario.mapTextureKey,
|
||||
resultVisible: this.resultObjects.length > 0,
|
||||
turnPromptVisible: this.turnPromptObjects.length > 0,
|
||||
turnPromptMode: this.turnPromptMode ?? null,
|
||||
markerCount: this.markers.length,
|
||||
threatMarkerCount: this.markers.filter((marker) => marker.getData('markerType') === 'threat').length,
|
||||
enemyMoveMarkerCount: this.markers.filter((marker) => marker.getData('markerType') === 'enemy-move').length,
|
||||
|
||||
Reference in New Issue
Block a user