From 72f8924a7f85bea380370b8e28c65a7e05c467b4 Mon Sep 17 00:00:00 2001 From: Ryan <7389646+ryanbarlow97@users.noreply.github.com> Date: Fri, 2 Jan 2026 16:48:24 +0000 Subject: [PATCH] add mobile bomb flip support (#2737) closes #2678 ## Description: Update to enable bomb flip support by mobile users too image ---------------------------------------------------------------------------------------------------------------------------------------------------- Also, I slightly updated the player panel to make it more even and take up less space; - removed the huge header bar which took up too much space - fixed ui divider spacing Before: image After: image ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced ## Please put your Discord username so you can be contacted if a bug or regression is found: w.o.n --- resources/lang/en.json | 5 +- src/client/InputHandler.ts | 7 +- .../layers/NukeTrajectoryPreviewLayer.ts | 5 +- src/client/graphics/layers/PlayerPanel.ts | 157 +++++++++++------- 4 files changed, 108 insertions(+), 66 deletions(-) diff --git a/resources/lang/en.json b/resources/lang/en.json index 15a97768e..71af53a9a 100644 --- a/resources/lang/en.json +++ b/resources/lang/en.json @@ -700,7 +700,10 @@ "send_alliance": "Send Alliance", "send_troops": "Send Troops", "send_gold": "Send Gold", - "emotes": "Emojis" + "emotes": "Emojis", + "arc_up": "Upward arc", + "arc_down": "Downward arc", + "flip_rocket_trajectory": "Flip rocket trajectory" }, "send_troops_modal": { "title_with_name": "Send Troops to {name}", diff --git a/src/client/InputHandler.ts b/src/client/InputHandler.ts index e8d13c932..d01798445 100644 --- a/src/client/InputHandler.ts +++ b/src/client/InputHandler.ts @@ -89,7 +89,9 @@ export class GhostStructureChangedEvent implements GameEvent { constructor(public readonly ghostStructure: UnitType | null) {} } -export class SwapRocketDirectionEvent implements GameEvent {} +export class SwapRocketDirectionEvent implements GameEvent { + constructor(public readonly rocketDirectionUp: boolean) {} +} export class ShowBuildMenuEvent implements GameEvent { constructor( @@ -432,7 +434,8 @@ export class InputHandler { if (e.code === this.keybinds.swapDirection) { e.preventDefault(); - this.eventBus.emit(new SwapRocketDirectionEvent()); + const nextDirection = !this.uiState.rocketDirectionUp; + this.eventBus.emit(new SwapRocketDirectionEvent(nextDirection)); } // Shift-D to toggle performance overlay diff --git a/src/client/graphics/layers/NukeTrajectoryPreviewLayer.ts b/src/client/graphics/layers/NukeTrajectoryPreviewLayer.ts index 67632585d..32bd471f0 100644 --- a/src/client/graphics/layers/NukeTrajectoryPreviewLayer.ts +++ b/src/client/graphics/layers/NukeTrajectoryPreviewLayer.ts @@ -56,9 +56,8 @@ export class NukeTrajectoryPreviewLayer implements Layer { this.cachedSpawnTile = null; } }); - this.eventBus.on(SwapRocketDirectionEvent, () => { - // Toggle rocket direction - this.uiState.rocketDirectionUp = !this.uiState.rocketDirectionUp; + this.eventBus.on(SwapRocketDirectionEvent, (event) => { + this.uiState.rocketDirectionUp = event.rocketDirectionUp; // Force trajectory recalculation this.lastTargetTile = null; }); diff --git a/src/client/graphics/layers/PlayerPanel.ts b/src/client/graphics/layers/PlayerPanel.ts index bf2cde03a..b742ff49c 100644 --- a/src/client/graphics/layers/PlayerPanel.ts +++ b/src/client/graphics/layers/PlayerPanel.ts @@ -14,7 +14,11 @@ import { GameView, PlayerView } from "../../../core/game/GameView"; import { Emoji, flattenedEmojiTable } from "../../../core/Util"; import { actionButton } from "../../components/ui/ActionButton"; import "../../components/ui/Divider"; -import { CloseViewEvent, MouseUpEvent } from "../../InputHandler"; +import { + CloseViewEvent, + MouseUpEvent, + SwapRocketDirectionEvent, +} from "../../InputHandler"; import { SendAllianceRequestIntentEvent, SendBreakAllianceIntentEvent, @@ -77,6 +81,10 @@ export class PlayerPanel extends LitElement implements Layer { this.hide(); } }); + eventBus.on(SwapRocketDirectionEvent, (event) => { + this.uiState.rocketDirectionUp = event.rocketDirectionUp; + this.requestUpdate(); + }); } init() { this.eventBus.on(MouseUpEvent, () => { @@ -297,6 +305,12 @@ export class PlayerPanel extends LitElement implements Layer { this.hide(); } + private handleToggleRocketDirection(e: Event) { + e.stopPropagation(); + const next = !this.uiState.rocketDirectionUp; + this.eventBus.emit(new SwapRocketDirectionEvent(next)); + } + private identityChipProps(type: PlayerType) { switch (type) { case PlayerType.Nation: @@ -488,7 +502,7 @@ export class PlayerPanel extends LitElement implements Layer { text-white w-[140px] min-w-[140px] flex-shrink-0" > 💰 - + ${renderNumber(other.gold() || 0)} @@ -512,6 +526,28 @@ export class PlayerPanel extends LitElement implements Layer { `; } + private renderRocketDirectionToggle() { + return html` + + + `; + } + private renderStats(other: PlayerView, my: PlayerView) { return html` @@ -696,53 +732,53 @@ export class PlayerPanel extends LitElement implements Layer { : ""} - -
- ${other !== my - ? canEmbargo - ? actionButton({ - onClick: (e: MouseEvent) => - this.handleEmbargoClick(e, my, other), - icon: stopTradingIcon, - iconAlt: "Stop Trading", - title: translateText("player_panel.stop_trade"), - label: translateText("player_panel.stop_trade"), - type: "yellow", - }) - : actionButton({ - onClick: (e: MouseEvent) => - this.handleStopEmbargoClick(e, my, other), - icon: startTradingIcon, - iconAlt: "Start Trading", - title: translateText("player_panel.start_trade"), - label: translateText("player_panel.start_trade"), - type: "green", - }) - : ""} - ${canBreakAlliance - ? actionButton({ - onClick: (e: MouseEvent) => - this.handleBreakAllianceClick(e, my, other), - icon: breakAllianceIcon, - iconAlt: "Break Alliance", - title: translateText("player_panel.break_alliance"), - label: translateText("player_panel.break_alliance"), - type: "red", - }) - : ""} - ${canSendAllianceRequest - ? actionButton({ - onClick: (e: MouseEvent) => - this.handleAllianceClick(e, my, other), - icon: allianceIcon, - iconAlt: "Alliance", - title: translateText("player_panel.send_alliance"), - label: translateText("player_panel.send_alliance"), - type: "indigo", - }) - : ""} -
- + ${other === my + ? html`` + : html` +
+ ${canEmbargo + ? actionButton({ + onClick: (e: MouseEvent) => + this.handleEmbargoClick(e, my, other), + icon: stopTradingIcon, + iconAlt: "Stop Trading", + title: translateText("player_panel.stop_trade"), + label: translateText("player_panel.stop_trade"), + type: "yellow", + }) + : actionButton({ + onClick: (e: MouseEvent) => + this.handleStopEmbargoClick(e, my, other), + icon: startTradingIcon, + iconAlt: "Start Trading", + title: translateText("player_panel.start_trade"), + label: translateText("player_panel.start_trade"), + type: "green", + })} + ${canBreakAlliance + ? actionButton({ + onClick: (e: MouseEvent) => + this.handleBreakAllianceClick(e, my, other), + icon: breakAllianceIcon, + iconAlt: "Break Alliance", + title: translateText("player_panel.break_alliance"), + label: translateText("player_panel.break_alliance"), + type: "red", + }) + : ""} + ${canSendAllianceRequest + ? actionButton({ + onClick: (e: MouseEvent) => + this.handleAllianceClick(e, my, other), + icon: allianceIcon, + iconAlt: "Alliance", + title: translateText("player_panel.send_alliance"), + label: translateText("player_panel.send_alliance"), + type: "indigo", + }) + : ""} +
+ `} ${other === my ? html`
${actionButton({ @@ -845,16 +881,14 @@ export class PlayerPanel extends LitElement implements Layer {
-
- -
+
${this.renderResources(other)} + + ${other === my ? this.renderRocketDirectionToggle() : ""} + @@ -902,7 +939,7 @@ export class PlayerPanel extends LitElement implements Layer { ${this.renderAllianceExpiry()} - + ${this.renderActions(my, other)}