fix: isolate camp save modal input

This commit is contained in:
2026-07-29 10:10:31 +09:00
parent ed5b6b2a8a
commit f0fae7199a
2 changed files with 185 additions and 13 deletions

View File

@@ -11515,6 +11515,7 @@ export class CampScene extends Phaser.Scene {
private saveSlotConfirmObjects: Phaser.GameObjects.GameObject[] = [];
private navigationBlockerObjects: Phaser.GameObjects.GameObject[] = [];
private pendingSaveSlot?: number;
private handledCampShortcutEvents = new WeakSet<KeyboardEvent>();
private pendingVictoryRewardReport?: CampaignVictoryRewardReport;
private victoryRewardLedgerReport?: CampaignVictoryRewardReport;
private victorySettlementArrival?: VictorySettlementArrival;
@@ -11841,7 +11842,7 @@ export class CampScene extends Phaser.Scene {
musicVolume: this.campSoundscape.music.volume,
ambienceVolume: this.campSoundscape.ambience.volume
});
this.input.keyboard?.on('keydown-ESC', () => this.handleEscapeKey());
this.input.keyboard?.on('keydown-ESC', (event: KeyboardEvent) => this.handleEscapeKey(event));
this.input.keyboard?.on('keydown-ENTER', (event: KeyboardEvent) => this.handleSortieEnterKey(event));
this.input.keyboard?.on('keydown', (event: KeyboardEvent) => {
if (
@@ -13409,6 +13410,25 @@ export class CampScene extends Phaser.Scene {
panel.setDepth(depth);
panel.setStrokeStyle(2, palette.gold, 0.86);
panel.setInteractive();
panel.on(
'pointerdown',
(
_pointer: Phaser.Input.Pointer,
_localX: number,
_localY: number,
event?: { stopPropagation: () => void }
) => event?.stopPropagation()
);
panel.on(
'wheel',
(
_pointer: Phaser.Input.Pointer,
_deltaX: number,
_deltaY: number,
_deltaZ: number,
event?: { stopPropagation: () => void }
) => event?.stopPropagation()
);
this.trackCampSaveSlot(panel);
const title = this.add.text(left + 22, top + 16, '수동 저장 기록', this.textStyle(22, '#f2e3bf', true));
@@ -13436,7 +13456,13 @@ export class CampScene extends Phaser.Scene {
const close = this.add.text(left + width - 58, top + 18, '닫기', this.textStyle(14, '#d8b15f', true));
close.setDepth(depth + 2);
close.setInteractive({ useHandCursor: true });
close.on('pointerdown', () => {
close.on('pointerdown', (
_pointer: Phaser.Input.Pointer,
_localX: number,
_localY: number,
event?: { stopPropagation: () => void }
) => {
event?.stopPropagation();
soundDirector.playSelect();
this.hideCampSaveSlotPanel();
});
@@ -13505,7 +13531,15 @@ export class CampScene extends Phaser.Scene {
saveLabel.setDepth(depth + 1);
this.trackCampSaveSlot(saveLabel);
const run = () => this.requestSaveCampToSlot(summary.slot);
const run = (
_pointer: Phaser.Input.Pointer,
_localX: number,
_localY: number,
event?: { stopPropagation: () => void }
) => {
event?.stopPropagation();
this.requestSaveCampToSlot(summary.slot);
};
[row, title, keycap, keyText, detail, meta, saveLabel].forEach((object) => {
object.setInteractive({ useHandCursor: true });
object.on('pointerdown', run);
@@ -13572,6 +13606,29 @@ export class CampScene extends Phaser.Scene {
shade.setOrigin(0);
shade.setDepth(depth - 1);
shade.setInteractive();
shade.on(
'pointerdown',
(
_pointer: Phaser.Input.Pointer,
_localX: number,
_localY: number,
event?: { stopPropagation: () => void }
) => {
event?.stopPropagation();
soundDirector.playSelect();
this.hideCampSaveConfirm();
}
);
shade.on(
'wheel',
(
_pointer: Phaser.Input.Pointer,
_deltaX: number,
_deltaY: number,
_deltaZ: number,
event?: { stopPropagation: () => void }
) => event?.stopPropagation()
);
this.trackCampSaveConfirm(shade);
const panel = this.add.rectangle(x, y, width, height, 0x111a24, 0.99);
@@ -13579,6 +13636,25 @@ export class CampScene extends Phaser.Scene {
panel.setDepth(depth);
panel.setStrokeStyle(2, palette.gold, 0.9);
panel.setInteractive();
panel.on(
'pointerdown',
(
_pointer: Phaser.Input.Pointer,
_localX: number,
_localY: number,
event?: { stopPropagation: () => void }
) => event?.stopPropagation()
);
panel.on(
'wheel',
(
_pointer: Phaser.Input.Pointer,
_deltaX: number,
_deltaY: number,
_deltaZ: number,
event?: { stopPropagation: () => void }
) => event?.stopPropagation()
);
this.trackCampSaveConfirm(panel);
const title = this.add.text(x + 22, y + 18, `슬롯 ${summary.slot} 덮어쓰기`, this.textStyle(20, '#f2e3bf', true));
@@ -13608,7 +13684,15 @@ export class CampScene extends Phaser.Scene {
confirm.setPadding(14, 5, 14, 5);
confirm.setBackgroundColor('#6d4420');
confirm.setInteractive({ useHandCursor: true });
confirm.on('pointerdown', () => this.confirmCampSaveOverwrite());
confirm.on('pointerdown', (
_pointer: Phaser.Input.Pointer,
_localX: number,
_localY: number,
event?: { stopPropagation: () => void }
) => {
event?.stopPropagation();
this.confirmCampSaveOverwrite();
});
this.trackCampSaveConfirm(confirm);
const cancel = this.add.text(x + width - 70, y + 126, '취소', this.textStyle(14, '#d8b15f', true));
@@ -13616,7 +13700,13 @@ export class CampScene extends Phaser.Scene {
cancel.setPadding(14, 5, 14, 5);
cancel.setBackgroundColor('#1a2630');
cancel.setInteractive({ useHandCursor: true });
cancel.on('pointerdown', () => {
cancel.on('pointerdown', (
_pointer: Phaser.Input.Pointer,
_localX: number,
_localY: number,
event?: { stopPropagation: () => void }
) => {
event?.stopPropagation();
soundDirector.playSelect();
this.hideCampSaveConfirm();
});
@@ -14267,7 +14357,31 @@ export class CampScene extends Phaser.Scene {
return true;
}
private handleEscapeKey() {
private acceptCampShortcutEvent(
event: KeyboardEvent,
shortcut: 'escape' | 'enter'
) {
const matches =
shortcut === 'escape'
? event.key === 'Escape' || event.code === 'Escape'
: event.key === 'Enter' ||
event.code === 'Enter' ||
event.code === 'NumpadEnter';
if (
!matches ||
event.repeat ||
this.handledCampShortcutEvents.has(event)
) {
return false;
}
this.handledCampShortcutEvents.add(event);
return true;
}
private handleEscapeKey(event: KeyboardEvent) {
if (!this.acceptCampShortcutEvent(event, 'escape')) {
return;
}
if (this.navigationPending) {
return;
}
@@ -14335,7 +14449,10 @@ export class CampScene extends Phaser.Scene {
}
private handleSortieEnterKey(event: KeyboardEvent) {
if (event.repeat || this.navigationPending) {
if (
!this.acceptCampShortcutEvent(event, 'enter') ||
this.navigationPending
) {
return;
}
if (