From cb7164a52fb60b1e7251cf855777e151805e7890 Mon Sep 17 00:00:00 2001 From: Evan Date: Tue, 17 Mar 2026 19:02:55 -0700 Subject: [PATCH] Place footer ad during spawn phase (#3458) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description: Show the "footer_ad" ad type during the spawn phase. Screenshot 2026-03-17 at 7 01 37 PM ## 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: evan --- src/client/Main.ts | 9 +++- src/client/graphics/layers/InGamePromo.ts | 55 ++++++++++++++++++++++- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/client/Main.ts b/src/client/Main.ts index 55406ed30..1241fe060 100644 --- a/src/client/Main.ts +++ b/src/client/Main.ts @@ -180,12 +180,17 @@ declare global { ramp: { que: Array<() => void>; passiveMode: boolean; - spaAddAds: (ads: Array<{ type: string; selectorId: string }>) => void; - destroyUnits: (adType: string) => void; + spaAddAds: (ads: Array<{ type: string; selectorId?: string }>) => void; + destroyUnits: (adType: string | string[]) => Promise; settings?: { slots?: any; }; spaNewPage: (url?: string) => void; + spaAds: (config?: { + ads?: Array<{ type: string; selectorId?: string }>; + countPageview?: boolean; + path?: string; + }) => void; // Video ad methods onPlayerReady: (() => void) | null; addUnits: (units: Array<{ type: string }>) => Promise; diff --git a/src/client/graphics/layers/InGamePromo.ts b/src/client/graphics/layers/InGamePromo.ts index a160e5924..097bf5bd6 100644 --- a/src/client/graphics/layers/InGamePromo.ts +++ b/src/client/graphics/layers/InGamePromo.ts @@ -5,19 +5,71 @@ import { Layer } from "./Layer"; const AD_TYPE = "standard_iab_left1"; const AD_CONTAINER_ID = "in-game-bottom-left-ad"; +const BOTTOM_RAIL_TYPE = "bottom_rail"; @customElement("in-game-promo") export class InGamePromo extends LitElement implements Layer { public game: GameView; private shouldShow: boolean = false; + private bottomRailActive: boolean = false; + private cornerAdShown: boolean = false; createRenderRoot() { return this; } init() { - this.showAd(); + this.showBottomRail(); + } + + tick() { + if (!this.game.inSpawnPhase()) { + if (this.bottomRailActive) { + this.destroyBottomRail(); + } + if (!this.cornerAdShown) { + this.cornerAdShown = true; + this.showAd(); + } + } + } + + private showBottomRail(): void { + if (!window.adsEnabled) return; + if (!this.game.inSpawnPhase()) return; + if (!window.ramp) { + console.warn("Playwire RAMP not available for bottom_rail ad"); + return; + } + + this.bottomRailActive = true; + try { + window.ramp.que.push(() => { + try { + window.ramp.spaAddAds([{ type: BOTTOM_RAIL_TYPE }]); + console.log("Bottom rail ad loaded during spawn phase"); + } catch (e) { + console.error("Failed to add bottom_rail ad:", e); + } + }); + } catch (error) { + console.error("Failed to load bottom_rail ad:", error); + } + } + + private destroyBottomRail(): void { + if (!this.bottomRailActive) return; + this.bottomRailActive = false; + + if (!window.ramp) return; + + try { + window.ramp.spaAds({ ads: [], countPageview: false }); + console.log("Bottom rail ad destroyed via spaAds after spawn phase"); + } catch (e) { + console.error("Error destroying bottom_rail ad:", e); + } } private showAd(): void { @@ -59,6 +111,7 @@ export class InGamePromo extends LitElement implements Layer { } public hideAd(): void { + this.destroyBottomRail(); if (!window.ramp) { console.warn("Playwire RAMP not available for in-game ad"); return;