diff --git a/src/client/InputHandler.ts b/src/client/InputHandler.ts index 1c12cf61b..c5778968d 100644 --- a/src/client/InputHandler.ts +++ b/src/client/InputHandler.ts @@ -519,10 +519,12 @@ export class InputHandler { } // Two-phase build keybind matching: exact code match first, then digit/Numpad alias. - const matchedBuild = this.resolveBuildKeybind(e.code, e.shiftKey); - if (matchedBuild !== null) { - e.preventDefault(); - this.setGhostStructure(matchedBuild); + if (this.canUseBuildKeybinds()) { + const matchedBuild = this.resolveBuildKeybind(e.code, e.shiftKey); + if (matchedBuild !== null) { + e.preventDefault(); + this.setGhostStructure(matchedBuild); + } } if (this.keybindMatchesEvent(e, this.keybinds.requestAlliance)) { @@ -943,6 +945,11 @@ export class InputHandler { return null; } + private canUseBuildKeybinds(): boolean { + const myPlayer = this.gameView.myPlayer?.(); + return !this.gameView.inSpawnPhase() && myPlayer?.isAlive() === true; + } + private getPinchDistance(): number { const pointerEvents = Array.from(this.pointers.values()); const dx = pointerEvents[0].clientX - pointerEvents[1].clientX; diff --git a/tests/InputHandler.test.ts b/tests/InputHandler.test.ts index 19633f96a..3da402e6f 100644 --- a/tests/InputHandler.test.ts +++ b/tests/InputHandler.test.ts @@ -9,7 +9,7 @@ import { import { UIState } from "../src/client/graphics/UIState"; import { EventBus } from "../src/core/EventBus"; import { UnitType } from "../src/core/game/Game"; -import { GameView } from "../src/core/game/GameView"; +import { GameView, PlayerView } from "../src/core/game/GameView"; import { KEYBINDS_KEY, UserSettings } from "../src/core/game/UserSettings"; class MockPointerEvent { @@ -49,7 +49,10 @@ describe("InputHandler AutoUpgrade", () => { testSettings = new UserSettings(); testSettings.removeCached(KEYBINDS_KEY, false); - mockGameView = { inSpawnPhase: () => false } as GameView; + mockGameView = { + inSpawnPhase: () => false, + myPlayer: () => ({ isAlive: () => true }), + } as GameView; mockCanvas = document.createElement("canvas"); mockCanvas.width = 800; mockCanvas.height = 600; @@ -626,6 +629,17 @@ describe("InputHandler AutoUpgrade", () => { ); expect(inputHandler["uiState"].ghostStructure).toBe(UnitType.MIRV); }); + + test("does not set ghost structure when the player is dead", () => { + mockGameView.myPlayer = () => + ({ isAlive: () => false }) as unknown as PlayerView; + + window.dispatchEvent( + new KeyboardEvent("keyup", { code: "Numpad1", key: "1" }), + ); + + expect(inputHandler["uiState"].ghostStructure).toBeNull(); + }); }); describe("Build keybind two-phase matching (exact code first, then digit/Numpad alias)", () => {