diff --git a/resources/images/ofm/MASTER_2025.png b/resources/images/ofm/MASTER_2025.png deleted file mode 100644 index 908de96f4..000000000 Binary files a/resources/images/ofm/MASTER_2025.png and /dev/null differ diff --git a/resources/images/ofm/logo_MASTER_2025.png b/resources/images/ofm/logo_MASTER_2025.png deleted file mode 100644 index c6e625982..000000000 Binary files a/resources/images/ofm/logo_MASTER_2025.png and /dev/null differ diff --git a/src/client/TerritoryPatternsModal.ts b/src/client/TerritoryPatternsModal.ts index b7b3938a8..24226c0f9 100644 --- a/src/client/TerritoryPatternsModal.ts +++ b/src/client/TerritoryPatternsModal.ts @@ -37,6 +37,8 @@ export class TerritoryPatternsModal extends LitElement { private userSettings: UserSettings = new UserSettings(); + private isActive = false; + constructor() { super(); } @@ -44,7 +46,6 @@ export class TerritoryPatternsModal extends LitElement { connectedCallback() { super.connectedCallback(); this.selectedPattern = this.userSettings.getSelectedPattern(); - window.addEventListener("keydown", this.handleKeyDown); this.updateComplete.then(() => { const containers = this.renderRoot.querySelectorAll(".preview-container"); if (this.resizeObserver) { @@ -54,12 +55,11 @@ export class TerritoryPatternsModal extends LitElement { } this.updatePreview(); }); + this.open(); } disconnectedCallback() { super.disconnectedCallback(); - window.removeEventListener("keydown", this.handleKeyDown); - this.resizeObserver.disconnect(); } async onUserMe(userMeResponse: UserMeResponse | null) { @@ -220,6 +220,7 @@ export class TerritoryPatternsModal extends LitElement { } render() { + if (!this.isActive) return html``; return html` ${this.renderTooltip()} (); const DEFAULT_PATTERN_B64 = "AAAAAA"; // Empty 2x2 pattern const COLOR_SET = [0, 0, 0, 255]; // Black const COLOR_UNSET = [255, 255, 255, 255]; // White @@ -344,11 +351,14 @@ export function generatePreviewDataUrl( width?: number, height?: number, ): string { + pattern ??= DEFAULT_PATTERN_B64; + + if (patternCache.has(pattern)) { + return patternCache.get(pattern)!; + } + // Calculate canvas size - const decoder = new PatternDecoder( - pattern ?? DEFAULT_PATTERN_B64, - base64url.decode, - ); + const decoder = new PatternDecoder(pattern, base64url.decode); const scaledWidth = decoder.scaledWidth(); const scaledHeight = decoder.scaledHeight(); @@ -384,5 +394,7 @@ export function generatePreviewDataUrl( // Create a data URL ctx.putImageData(imageData, 0, 0); - return canvas.toDataURL("image/png"); + const dataUrl = canvas.toDataURL("image/png"); + patternCache.set(pattern, dataUrl); + return dataUrl; } diff --git a/src/client/graphics/GameRenderer.ts b/src/client/graphics/GameRenderer.ts index bc4d3406d..e9842cab6 100644 --- a/src/client/graphics/GameRenderer.ts +++ b/src/client/graphics/GameRenderer.ts @@ -183,6 +183,7 @@ export function createRenderer( } chatModal.g = game; chatModal.eventBus = eventBus; + chatModal.initEventBus(); const multiTabModal = document.querySelector( "multi-tab-modal", diff --git a/src/client/graphics/layers/ChatModal.ts b/src/client/graphics/layers/ChatModal.ts index 6c0413f59..a8fe2e862 100644 --- a/src/client/graphics/layers/ChatModal.ts +++ b/src/client/graphics/layers/ChatModal.ts @@ -6,6 +6,7 @@ import { GameView, PlayerView } from "../../../core/game/GameView"; import quickChatData from "../../../../resources/QuickChat.json"; import { EventBus } from "../../../core/EventBus"; +import { CloseViewEvent } from "../../InputHandler"; import { SendQuickChatEvent } from "../../Transport"; import { translateText } from "../../Utils"; @@ -172,6 +173,14 @@ export class ChatModal extends LitElement { `; } + initEventBus() { + this.eventBus.on(CloseViewEvent, (e) => { + if (!this.hidden) { + this.close(); + } + }); + } + private selectCategory(categoryId: string) { this.selectedCategory = categoryId; this.selectedPhraseText = null; diff --git a/src/client/graphics/layers/EmojiTable.ts b/src/client/graphics/layers/EmojiTable.ts index 542c24d37..b61c7d6a0 100644 --- a/src/client/graphics/layers/EmojiTable.ts +++ b/src/client/graphics/layers/EmojiTable.ts @@ -5,7 +5,7 @@ import { AllPlayers } from "../../../core/game/Game"; import { GameView, PlayerView } from "../../../core/game/GameView"; import { TerraNulliusImpl } from "../../../core/game/TerraNulliusImpl"; import { emojiTable, flattenedEmojiTable } from "../../../core/Util"; -import { ShowEmojiMenuEvent } from "../../InputHandler"; +import { CloseViewEvent, ShowEmojiMenuEvent } from "../../InputHandler"; import { SendEmojiIntentEvent } from "../../Transport"; import { TransformHandler } from "../TransformHandler"; @@ -48,6 +48,11 @@ export class EmojiTable extends LitElement { this.hideTable(); }); }); + this.eventBus.on(CloseViewEvent, (e) => { + if (!this.hidden) { + this.hideTable(); + } + }); } private onEmojiClicked: (emoji: string) => void = () => {}; diff --git a/src/client/graphics/layers/PlayerPanel.ts b/src/client/graphics/layers/PlayerPanel.ts index 4abe315d9..7d78a2a20 100644 --- a/src/client/graphics/layers/PlayerPanel.ts +++ b/src/client/graphics/layers/PlayerPanel.ts @@ -13,7 +13,7 @@ import { AllPlayers, PlayerActions } from "../../../core/game/Game"; import { TileRef } from "../../../core/game/GameMap"; import { GameView, PlayerView } from "../../../core/game/GameView"; import { flattenedEmojiTable } from "../../../core/Util"; -import { MouseUpEvent } from "../../InputHandler"; +import { CloseViewEvent, MouseUpEvent } from "../../InputHandler"; import { SendAllianceRequestIntentEvent, SendBreakAllianceIntentEvent, @@ -167,6 +167,10 @@ export class PlayerPanel extends LitElement implements Layer { init() { this.eventBus.on(MouseUpEvent, () => this.hide()); + this.eventBus.on(CloseViewEvent, (e) => { + this.hide(); + }); + this.ctModal = document.querySelector("chat-modal") as ChatModal; } diff --git a/src/client/graphics/layers/RadialMenu.ts b/src/client/graphics/layers/RadialMenu.ts index b8e26af9f..652bff522 100644 --- a/src/client/graphics/layers/RadialMenu.ts +++ b/src/client/graphics/layers/RadialMenu.ts @@ -1,6 +1,7 @@ import * as d3 from "d3"; import backIcon from "../../../../resources/images/BackIconWhite.svg"; import { EventBus, GameEvent } from "../../../core/EventBus"; +import { CloseViewEvent } from "../../InputHandler"; import { Layer } from "./Layer"; import { CenterButtonElement, @@ -102,6 +103,9 @@ export class RadialMenu implements Layer { init() { this.createMenuElement(); this.createTooltipElement(); + this.eventBus.on(CloseViewEvent, (e) => { + this.hideRadialMenu(); + }); } private createMenuElement() { diff --git a/src/client/graphics/layers/WinModal.ts b/src/client/graphics/layers/WinModal.ts index 2e3b4667b..25b4ff42c 100644 --- a/src/client/graphics/layers/WinModal.ts +++ b/src/client/graphics/layers/WinModal.ts @@ -1,6 +1,5 @@ import { LitElement, css, html } from "lit"; import { customElement, state } from "lit/decorators.js"; -import logo from "../../../../resources/images/ofm/logo_MASTER_2025.png"; import { translateText } from "../../../client/Utils"; import { EventBus } from "../../../core/EventBus"; import { GameUpdateType } from "../../../core/game/GameUpdates"; @@ -22,9 +21,6 @@ export class WinModal extends LitElement implements Layer { @state() showButtons = false; - @state() - private showSteamContent = Math.random() > 0.5; - private _title: string; // Override to prevent shadow DOM creation @@ -142,9 +138,7 @@ export class WinModal extends LitElement implements Layer { return html`

${this._title || ""}

- ${this.showSteamContent - ? this.steamWishlist() - : this.openfrontMasters()} + ${this.innerHtml()}
@@ -159,7 +153,7 @@ export class WinModal extends LitElement implements Layer { `; } - steamWishlist() { + innerHtml() { return html`

`; } - openfrontMasters() { - return html`

- OpenFront Masters - - Watch the best compete in the - OpenFront Masters - -

`; - } - show() { this.eventBus.emit(new GutterAdModalEvent(true)); setTimeout(() => { diff --git a/src/core/execution/MIRVExecution.ts b/src/core/execution/MIRVExecution.ts index 6b2b66a23..9a6075b68 100644 --- a/src/core/execution/MIRVExecution.ts +++ b/src/core/execution/MIRVExecution.ts @@ -47,6 +47,17 @@ export class MirvExecution implements Execution { // Record stats this.mg.stats().bombLaunch(this.player, this.targetPlayer, UnitType.MIRV); + + // Betrayal on launch + if (this.targetPlayer.isPlayer()) { + const alliance = this.player.allianceWith(this.targetPlayer); + if (alliance !== null) { + this.player.breakAlliance(alliance); + } + if (this.targetPlayer !== this.player) { + this.targetPlayer.updateRelation(this.player, -100); + } + } } tick(ticks: number): void { @@ -118,15 +129,6 @@ export class MirvExecution implements Execution { ), ); } - if (this.targetPlayer.isPlayer()) { - const alliance = this.player.allianceWith(this.targetPlayer); - if (alliance !== null) { - this.player.breakAlliance(alliance); - } - if (this.targetPlayer !== this.player) { - this.targetPlayer.updateRelation(this.player, -100); - } - } this.nuke.delete(false); }