mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-08-08 03:29:44 +00:00
rename Layer → Controller; drop canvas2D-era interface hooks
The Layer interface dates to the canvas2D era when each entry drew to
the shared 2D context via renderLayer(ctx). With canvas2D gone, nothing
draws there and the renderLayer hook is dead. Rename the interface
("main-thread analog of the worker's Execution") and trim it:
interface Controller {
init?: () => void;
tick?: () => void;
getTickIntervalMs?: () => number;
}
renderLayer / shouldTransform / redraw are gone.
Sweep across 28 files: from "./Layer" → "./Controller", implements
Layer → implements Controller, Layer[] / Map<Layer,…> →
Controller[] / Map<Controller,…>. Delete the no-op renderLayer +
shouldTransform method bodies that every layer had inherited.
GameRenderer drops the RedrawGraphicsEvent listener + redraw() fanout
(nothing implements redraw anymore) and the now-unused eventBus
constructor field.
One real case: AttackingTroopsOverlay.renderLayer wasn't a no-op — it
updates DOM label transforms each frame so labels track the WebGL
camera during pan/zoom. Rename to private updateLabelDOM() and start
a self-driven RAF in init() so the per-frame updates keep running.
Class names ending in "Layer" (UILayer, StructureIconsLayer, NameLayer,
etc.) intentionally left as-is — those are separate identifiers and
the class-rename / file-move is a follow-up.
407 tests pass.
This commit is contained in:
@@ -2,7 +2,6 @@ import { EventBus } from "../../core/EventBus";
|
|||||||
import { GameView } from "../../core/game/GameView";
|
import { GameView } from "../../core/game/GameView";
|
||||||
import { UserSettings } from "../../core/game/UserSettings";
|
import { UserSettings } from "../../core/game/UserSettings";
|
||||||
import { GameStartingModal } from "../GameStartingModal";
|
import { GameStartingModal } from "../GameStartingModal";
|
||||||
import { RefreshGraphicsEvent as RedrawGraphicsEvent } from "../InputHandler";
|
|
||||||
import { FrameProfiler } from "./FrameProfiler";
|
import { FrameProfiler } from "./FrameProfiler";
|
||||||
import { TransformHandler } from "./TransformHandler";
|
import { TransformHandler } from "./TransformHandler";
|
||||||
import { UIState } from "./UIState";
|
import { UIState } from "./UIState";
|
||||||
@@ -13,6 +12,7 @@ import { BuildMenu } from "./layers/BuildMenu";
|
|||||||
import { ChatDisplay } from "./layers/ChatDisplay";
|
import { ChatDisplay } from "./layers/ChatDisplay";
|
||||||
import { ChatModal } from "./layers/ChatModal";
|
import { ChatModal } from "./layers/ChatModal";
|
||||||
import { ControlPanel } from "./layers/ControlPanel";
|
import { ControlPanel } from "./layers/ControlPanel";
|
||||||
|
import { Controller } from "./layers/Controller";
|
||||||
import { EmojiTable } from "./layers/EmojiTable";
|
import { EmojiTable } from "./layers/EmojiTable";
|
||||||
import { EventsDisplay } from "./layers/EventsDisplay";
|
import { EventsDisplay } from "./layers/EventsDisplay";
|
||||||
import { GameLeftSidebar } from "./layers/GameLeftSidebar";
|
import { GameLeftSidebar } from "./layers/GameLeftSidebar";
|
||||||
@@ -20,7 +20,6 @@ import { GameRightSidebar } from "./layers/GameRightSidebar";
|
|||||||
import { HeadsUpMessage } from "./layers/HeadsUpMessage";
|
import { HeadsUpMessage } from "./layers/HeadsUpMessage";
|
||||||
import { ImmunityTimer } from "./layers/ImmunityTimer";
|
import { ImmunityTimer } from "./layers/ImmunityTimer";
|
||||||
import { InGamePromo } from "./layers/InGamePromo";
|
import { InGamePromo } from "./layers/InGamePromo";
|
||||||
import { Layer } from "./layers/Layer";
|
|
||||||
import { Leaderboard } from "./layers/Leaderboard";
|
import { Leaderboard } from "./layers/Leaderboard";
|
||||||
import { MainRadialMenu } from "./layers/MainRadialMenu";
|
import { MainRadialMenu } from "./layers/MainRadialMenu";
|
||||||
import { MultiTabModal } from "./layers/MultiTabModal";
|
import { MultiTabModal } from "./layers/MultiTabModal";
|
||||||
@@ -260,7 +259,7 @@ export function createRenderer(
|
|||||||
// When updating these layers please be mindful of the order.
|
// When updating these layers please be mindful of the order.
|
||||||
// Try to group layers by the return value of shouldTransform.
|
// Try to group layers by the return value of shouldTransform.
|
||||||
// Not grouping the layers may cause excessive calls to context.save() and context.restore().
|
// Not grouping the layers may cause excessive calls to context.save() and context.restore().
|
||||||
const layers: Layer[] = [
|
const layers: Controller[] = [
|
||||||
new UILayer(game, eventBus, transformHandler),
|
new UILayer(game, eventBus, transformHandler),
|
||||||
new StructureIconsLayer(game, eventBus, uiState, transformHandler),
|
new StructureIconsLayer(game, eventBus, uiState, transformHandler),
|
||||||
new AttackingTroopsOverlay(game, transformHandler, eventBus, userSettings),
|
new AttackingTroopsOverlay(game, transformHandler, eventBus, userSettings),
|
||||||
@@ -298,7 +297,6 @@ export function createRenderer(
|
|||||||
];
|
];
|
||||||
|
|
||||||
return new GameRenderer(
|
return new GameRenderer(
|
||||||
eventBus,
|
|
||||||
transformHandler,
|
transformHandler,
|
||||||
uiState,
|
uiState,
|
||||||
layers,
|
layers,
|
||||||
@@ -307,18 +305,16 @@ export function createRenderer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class GameRenderer {
|
export class GameRenderer {
|
||||||
private layerTickState = new Map<Layer, { lastTickAtMs: number }>();
|
private layerTickState = new Map<Controller, { lastTickAtMs: number }>();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private eventBus: EventBus,
|
|
||||||
public transformHandler: TransformHandler,
|
public transformHandler: TransformHandler,
|
||||||
public uiState: UIState,
|
public uiState: UIState,
|
||||||
private layers: Layer[],
|
private layers: Controller[],
|
||||||
private performanceOverlay: PerformanceOverlay,
|
private performanceOverlay: PerformanceOverlay,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
initialize() {
|
initialize() {
|
||||||
this.eventBus.on(RedrawGraphicsEvent, () => this.redraw());
|
|
||||||
this.layers.forEach((l) => l.init?.());
|
this.layers.forEach((l) => l.init?.());
|
||||||
|
|
||||||
window.addEventListener("resize", () =>
|
window.addEventListener("resize", () =>
|
||||||
@@ -329,14 +325,6 @@ export class GameRenderer {
|
|||||||
this.transformHandler.centerAll(0.9);
|
this.transformHandler.centerAll(0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
redraw() {
|
|
||||||
this.layers.forEach((l) => {
|
|
||||||
if (l.redraw) {
|
|
||||||
l.redraw();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
tick() {
|
tick() {
|
||||||
const nowMs = performance.now();
|
const nowMs = performance.now();
|
||||||
const shouldProfileTick = FrameProfiler.isEnabled();
|
const shouldProfileTick = FrameProfiler.isEnabled();
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
} from "../../../core/game/GameUpdates";
|
} from "../../../core/game/GameUpdates";
|
||||||
import { GameView, PlayerView } from "../../../core/game/GameView";
|
import { GameView, PlayerView } from "../../../core/game/GameView";
|
||||||
import { UserSettings } from "../../../core/game/UserSettings";
|
import { UserSettings } from "../../../core/game/UserSettings";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
|
|
||||||
// Parameters for the alert animation
|
// Parameters for the alert animation
|
||||||
const ALERT_SPEED = 1.6;
|
const ALERT_SPEED = 1.6;
|
||||||
@@ -16,7 +16,7 @@ const RETALIATION_WINDOW_TICKS = 15 * 10; // 15 seconds
|
|||||||
const ALERT_COOLDOWN_TICKS = 15 * 10; // 15 seconds
|
const ALERT_COOLDOWN_TICKS = 15 * 10; // 15 seconds
|
||||||
|
|
||||||
@customElement("alert-frame")
|
@customElement("alert-frame")
|
||||||
export class AlertFrame extends LitElement implements Layer {
|
export class AlertFrame extends LitElement implements Controller {
|
||||||
public game: GameView;
|
public game: GameView;
|
||||||
private userSettings: UserSettings = new UserSettings();
|
private userSettings: UserSettings = new UserSettings();
|
||||||
|
|
||||||
@@ -118,9 +118,6 @@ export class AlertFrame extends LitElement implements Layer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The alert frame is not affected by the camera transform
|
// The alert frame is not affected by the camera transform
|
||||||
shouldTransform(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private onBrokeAllianceUpdate(update: BrokeAllianceUpdate) {
|
private onBrokeAllianceUpdate(update: BrokeAllianceUpdate) {
|
||||||
const myPlayer = this.game.myPlayer();
|
const myPlayer = this.game.myPlayer();
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { UserSettings } from "../../../core/game/UserSettings";
|
|||||||
import { AlternateViewEvent } from "../../InputHandler";
|
import { AlternateViewEvent } from "../../InputHandler";
|
||||||
import { renderTroops } from "../../Utils";
|
import { renderTroops } from "../../Utils";
|
||||||
import { TransformHandler } from "../TransformHandler";
|
import { TransformHandler } from "../TransformHandler";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
|
|
||||||
// Match AttacksDisplay: aquarius for outgoing, red-400 for incoming.
|
// Match AttacksDisplay: aquarius for outgoing, red-400 for incoming.
|
||||||
const OUTGOING_COLOR = "var(--color-aquarius)";
|
const OUTGOING_COLOR = "var(--color-aquarius)";
|
||||||
@@ -51,7 +51,7 @@ interface AttackLabel {
|
|||||||
attackerTroops: number;
|
attackerTroops: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AttackingTroopsOverlay implements Layer {
|
export class AttackingTroopsOverlay implements Controller {
|
||||||
private container: HTMLDivElement;
|
private container: HTMLDivElement;
|
||||||
private labelTemplate: HTMLDivElement;
|
private labelTemplate: HTMLDivElement;
|
||||||
private labels = new Map<string, AttackLabel>();
|
private labels = new Map<string, AttackLabel>();
|
||||||
@@ -70,10 +70,6 @@ export class AttackingTroopsOverlay implements Layer {
|
|||||||
private readonly userSettings: UserSettings,
|
private readonly userSettings: UserSettings,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
shouldTransform(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this.container = document.createElement("div");
|
this.container = document.createElement("div");
|
||||||
this.container.style.position = "fixed";
|
this.container.style.position = "fixed";
|
||||||
@@ -91,6 +87,15 @@ export class AttackingTroopsOverlay implements Layer {
|
|||||||
this.container.style.display = this.isVisible ? "" : "none";
|
this.container.style.display = this.isVisible ? "" : "none";
|
||||||
};
|
};
|
||||||
this.eventBus.on(AlternateViewEvent, this.onAlternateView);
|
this.eventBus.on(AlternateViewEvent, this.onAlternateView);
|
||||||
|
|
||||||
|
// Self-driven RAF: DOM label positions must update every frame so the
|
||||||
|
// labels track the WebGL camera as the user pans/zooms. (Previously this
|
||||||
|
// ran via the now-deleted canvas2D RAF loop.)
|
||||||
|
const drive = () => {
|
||||||
|
this.updateLabelDOM();
|
||||||
|
requestAnimationFrame(drive);
|
||||||
|
};
|
||||||
|
requestAnimationFrame(drive);
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
@@ -200,7 +205,7 @@ export class AttackingTroopsOverlay implements Layer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLayer(_context: CanvasRenderingContext2D) {
|
private updateLabelDOM() {
|
||||||
const screenPosOld = this.transformHandler.worldToScreenCoordinates(
|
const screenPosOld = this.transformHandler.worldToScreenCoordinates(
|
||||||
new Cell(0, 0),
|
new Cell(0, 0),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ import {
|
|||||||
GoToUnitEvent,
|
GoToUnitEvent,
|
||||||
} from "../TransformHandler";
|
} from "../TransformHandler";
|
||||||
import { UIState } from "../UIState";
|
import { UIState } from "../UIState";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
const soldierIcon = assetUrl("images/SoldierIcon.svg");
|
const soldierIcon = assetUrl("images/SoldierIcon.svg");
|
||||||
const swordIcon = assetUrl("images/SwordIcon.svg");
|
const swordIcon = assetUrl("images/SwordIcon.svg");
|
||||||
|
|
||||||
@customElement("attacks-display")
|
@customElement("attacks-display")
|
||||||
export class AttacksDisplay extends LitElement implements Layer {
|
export class AttacksDisplay extends LitElement implements Controller {
|
||||||
public eventBus: EventBus;
|
public eventBus: EventBus;
|
||||||
public game: GameView;
|
public game: GameView;
|
||||||
public uiState: UIState;
|
public uiState: UIState;
|
||||||
@@ -110,12 +110,6 @@ export class AttacksDisplay extends LitElement implements Layer {
|
|||||||
this.requestUpdate();
|
this.requestUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldTransform(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderLayer(): void {}
|
|
||||||
|
|
||||||
private renderButton(options: {
|
private renderButton(options: {
|
||||||
content: any;
|
content: any;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import {
|
|||||||
import { renderNumber } from "../../Utils";
|
import { renderNumber } from "../../Utils";
|
||||||
import { TransformHandler } from "../TransformHandler";
|
import { TransformHandler } from "../TransformHandler";
|
||||||
import { UIState } from "../UIState";
|
import { UIState } from "../UIState";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
const warshipIcon = assetUrl("images/BattleshipIconWhite.svg");
|
const warshipIcon = assetUrl("images/BattleshipIconWhite.svg");
|
||||||
const cityIcon = assetUrl("images/CityIconWhite.svg");
|
const cityIcon = assetUrl("images/CityIconWhite.svg");
|
||||||
const factoryIcon = assetUrl("images/FactoryIconWhite.svg");
|
const factoryIcon = assetUrl("images/FactoryIconWhite.svg");
|
||||||
@@ -124,7 +124,7 @@ export const buildTable: BuildItemDisplay[][] = [
|
|||||||
export const flattenedBuildTable = buildTable.flat();
|
export const flattenedBuildTable = buildTable.flat();
|
||||||
|
|
||||||
@customElement("build-menu")
|
@customElement("build-menu")
|
||||||
export class BuildMenu extends LitElement implements Layer {
|
export class BuildMenu extends LitElement implements Controller {
|
||||||
public game: GameView;
|
public game: GameView;
|
||||||
public eventBus: EventBus;
|
public eventBus: EventBus;
|
||||||
public uiState: UIState;
|
public uiState: UIState;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
} from "../../../core/game/GameUpdates";
|
} from "../../../core/game/GameUpdates";
|
||||||
import { GameView } from "../../../core/game/GameView";
|
import { GameView } from "../../../core/game/GameView";
|
||||||
import { onlyImages } from "../../../core/Util";
|
import { onlyImages } from "../../../core/Util";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
|
|
||||||
interface ChatEvent {
|
interface ChatEvent {
|
||||||
description: string;
|
description: string;
|
||||||
@@ -20,7 +20,7 @@ interface ChatEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@customElement("chat-display")
|
@customElement("chat-display")
|
||||||
export class ChatDisplay extends LitElement implements Layer {
|
export class ChatDisplay extends LitElement implements Controller {
|
||||||
public eventBus: EventBus;
|
public eventBus: EventBus;
|
||||||
public game: GameView;
|
public game: GameView;
|
||||||
|
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ import { ClientID } from "../../../core/Schemas";
|
|||||||
import { AttackRatioEvent } from "../../InputHandler";
|
import { AttackRatioEvent } from "../../InputHandler";
|
||||||
import { renderNumber, renderTroops } from "../../Utils";
|
import { renderNumber, renderTroops } from "../../Utils";
|
||||||
import { UIState } from "../UIState";
|
import { UIState } from "../UIState";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
const goldCoinIcon = assetUrl("images/GoldCoinIcon.svg");
|
const goldCoinIcon = assetUrl("images/GoldCoinIcon.svg");
|
||||||
const soldierIcon = assetUrl("images/SoldierIcon.svg");
|
const soldierIcon = assetUrl("images/SoldierIcon.svg");
|
||||||
const swordIcon = assetUrl("images/SwordIcon.svg");
|
const swordIcon = assetUrl("images/SwordIcon.svg");
|
||||||
|
|
||||||
@customElement("control-panel")
|
@customElement("control-panel")
|
||||||
export class ControlPanel extends LitElement implements Layer {
|
export class ControlPanel extends LitElement implements Controller {
|
||||||
public game: GameView;
|
public game: GameView;
|
||||||
public clientID: ClientID;
|
public clientID: ClientID;
|
||||||
public eventBus: EventBus;
|
public eventBus: EventBus;
|
||||||
@@ -111,14 +111,6 @@ export class ControlPanel extends LitElement implements Layer {
|
|||||||
this.uiState.attackRatio = newRatio;
|
this.uiState.attackRatio = newRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLayer(context: CanvasRenderingContext2D) {
|
|
||||||
// Render any necessary canvas elements
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldTransform(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
setVisibile(visible: boolean) {
|
setVisibile(visible: boolean) {
|
||||||
this._isVisible = visible;
|
this._isVisible = visible;
|
||||||
this.requestUpdate();
|
this.requestUpdate();
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* Controller — the main-thread analog of the worker's Execution.
|
||||||
|
*
|
||||||
|
* A Controller subscribes to events / game state and drives some slice of
|
||||||
|
* the client side (input, UI state, view updates). The interface is just
|
||||||
|
* lifecycle hooks; all coordination happens via the EventBus and direct
|
||||||
|
* references the controller is given at construction time.
|
||||||
|
*
|
||||||
|
* Naming: previously "Layer" — the name was a leftover from the canvas2D
|
||||||
|
* era when each entry in the array drew to the same 2D context. Now nothing
|
||||||
|
* draws to a shared canvas, so they're plain controllers.
|
||||||
|
*/
|
||||||
|
export interface Controller {
|
||||||
|
/** Called once at game start. Subscribe to events / set up state here. */
|
||||||
|
init?: () => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called per game tick (10Hz). Optional — pure event subscribers can omit.
|
||||||
|
*
|
||||||
|
* If `getTickIntervalMs()` returns > 0, the controller is throttled to that
|
||||||
|
* wall-clock interval instead of running every tick.
|
||||||
|
*/
|
||||||
|
tick?: () => void;
|
||||||
|
|
||||||
|
/** Optional throttle on tick frequency, in milliseconds. */
|
||||||
|
getTickIntervalMs?: () => number;
|
||||||
|
}
|
||||||
@@ -29,7 +29,7 @@ import {
|
|||||||
SendAllianceRejectIntentEvent,
|
SendAllianceRejectIntentEvent,
|
||||||
SendAllianceRequestIntentEvent,
|
SendAllianceRequestIntentEvent,
|
||||||
} from "../../Transport";
|
} from "../../Transport";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
|
|
||||||
import { GameView, PlayerView, UnitView } from "../../../core/game/GameView";
|
import { GameView, PlayerView, UnitView } from "../../../core/game/GameView";
|
||||||
import { onlyImages } from "../../../core/Util";
|
import { onlyImages } from "../../../core/Util";
|
||||||
@@ -68,7 +68,7 @@ interface GameEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@customElement("events-display")
|
@customElement("events-display")
|
||||||
export class EventsDisplay extends LitElement implements Layer {
|
export class EventsDisplay extends LitElement implements Controller {
|
||||||
public eventBus: EventBus;
|
public eventBus: EventBus;
|
||||||
public game: GameView;
|
public game: GameView;
|
||||||
public uiState: UIState;
|
public uiState: UIState;
|
||||||
@@ -359,12 +359,6 @@ export class EventsDisplay extends LitElement implements Layer {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldTransform(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderLayer(): void {}
|
|
||||||
|
|
||||||
private removeAllianceRenewalEvents(allianceID: number) {
|
private removeAllianceRenewalEvents(allianceID: number) {
|
||||||
this.events = this.events.filter(
|
this.events = this.events.filter(
|
||||||
(event) =>
|
(event) =>
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import { GameMode, Team } from "../../../core/game/Game";
|
|||||||
import { GameView } from "../../../core/game/GameView";
|
import { GameView } from "../../../core/game/GameView";
|
||||||
import { Platform } from "../../Platform";
|
import { Platform } from "../../Platform";
|
||||||
import { getTranslatedPlayerTeamLabel, translateText } from "../../Utils";
|
import { getTranslatedPlayerTeamLabel, translateText } from "../../Utils";
|
||||||
|
import { Controller } from "./Controller";
|
||||||
import { ImmunityBarVisibleEvent } from "./ImmunityTimer";
|
import { ImmunityBarVisibleEvent } from "./ImmunityTimer";
|
||||||
import { Layer } from "./Layer";
|
|
||||||
import { SpawnBarVisibleEvent } from "./SpawnTimer";
|
import { SpawnBarVisibleEvent } from "./SpawnTimer";
|
||||||
const leaderboardRegularIcon = assetUrl(
|
const leaderboardRegularIcon = assetUrl(
|
||||||
"images/LeaderboardIconRegularWhite.svg",
|
"images/LeaderboardIconRegularWhite.svg",
|
||||||
@@ -18,7 +18,7 @@ const teamRegularIcon = assetUrl("images/TeamIconRegularWhite.svg");
|
|||||||
const teamSolidIcon = assetUrl("images/TeamIconSolidWhite.svg");
|
const teamSolidIcon = assetUrl("images/TeamIconSolidWhite.svg");
|
||||||
|
|
||||||
@customElement("game-left-sidebar")
|
@customElement("game-left-sidebar")
|
||||||
export class GameLeftSidebar extends LitElement implements Layer {
|
export class GameLeftSidebar extends LitElement implements Controller {
|
||||||
@state()
|
@state()
|
||||||
private isLeaderboardShow = false;
|
private isLeaderboardShow = false;
|
||||||
@state()
|
@state()
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import { crazyGamesSDK } from "../../CrazyGamesSDK";
|
|||||||
import { TogglePauseIntentEvent } from "../../InputHandler";
|
import { TogglePauseIntentEvent } from "../../InputHandler";
|
||||||
import { PauseGameIntentEvent, SendWinnerEvent } from "../../Transport";
|
import { PauseGameIntentEvent, SendWinnerEvent } from "../../Transport";
|
||||||
import { translateText } from "../../Utils";
|
import { translateText } from "../../Utils";
|
||||||
|
import { Controller } from "./Controller";
|
||||||
import { ImmunityBarVisibleEvent } from "./ImmunityTimer";
|
import { ImmunityBarVisibleEvent } from "./ImmunityTimer";
|
||||||
import { Layer } from "./Layer";
|
|
||||||
import { ShowReplayPanelEvent } from "./ReplayPanel";
|
import { ShowReplayPanelEvent } from "./ReplayPanel";
|
||||||
import { ShowSettingsModalEvent } from "./SettingsModal";
|
import { ShowSettingsModalEvent } from "./SettingsModal";
|
||||||
import { SpawnBarVisibleEvent } from "./SpawnTimer";
|
import { SpawnBarVisibleEvent } from "./SpawnTimer";
|
||||||
@@ -22,7 +22,7 @@ const fullscreenIcon = assetUrl("images/FullscreenIconWhite.svg");
|
|||||||
const exitFullscreenIcon = assetUrl("images/ExitFullscreenIconWhite.svg");
|
const exitFullscreenIcon = assetUrl("images/ExitFullscreenIconWhite.svg");
|
||||||
|
|
||||||
@customElement("game-right-sidebar")
|
@customElement("game-right-sidebar")
|
||||||
export class GameRightSidebar extends LitElement implements Layer {
|
export class GameRightSidebar extends LitElement implements Controller {
|
||||||
public game: GameView;
|
public game: GameView;
|
||||||
public eventBus: EventBus;
|
public eventBus: EventBus;
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import { GameType } from "../../../core/game/Game";
|
|||||||
import { GameUpdateType } from "../../../core/game/GameUpdates";
|
import { GameUpdateType } from "../../../core/game/GameUpdates";
|
||||||
import { GameView } from "../../../core/game/GameView";
|
import { GameView } from "../../../core/game/GameView";
|
||||||
import { translateText } from "../../Utils";
|
import { translateText } from "../../Utils";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
|
|
||||||
@customElement("heads-up-message")
|
@customElement("heads-up-message")
|
||||||
export class HeadsUpMessage extends LitElement implements Layer {
|
export class HeadsUpMessage extends LitElement implements Controller {
|
||||||
public game: GameView;
|
public game: GameView;
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ import { customElement } from "lit/decorators.js";
|
|||||||
import { EventBus, GameEvent } from "../../../core/EventBus";
|
import { EventBus, GameEvent } from "../../../core/EventBus";
|
||||||
import { GameMode } from "../../../core/game/Game";
|
import { GameMode } from "../../../core/game/Game";
|
||||||
import { GameView } from "../../../core/game/GameView";
|
import { GameView } from "../../../core/game/GameView";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
|
|
||||||
export class ImmunityBarVisibleEvent implements GameEvent {
|
export class ImmunityBarVisibleEvent implements GameEvent {
|
||||||
constructor(public readonly visible: boolean) {}
|
constructor(public readonly visible: boolean) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@customElement("immunity-timer")
|
@customElement("immunity-timer")
|
||||||
export class ImmunityTimer extends LitElement implements Layer {
|
export class ImmunityTimer extends LitElement implements Controller {
|
||||||
public game: GameView;
|
public game: GameView;
|
||||||
public eventBus: EventBus;
|
public eventBus: EventBus;
|
||||||
|
|
||||||
@@ -88,10 +88,6 @@ export class ImmunityTimer extends LitElement implements Layer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldTransform(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.isVisible || !this.isActive) {
|
if (!this.isVisible || !this.isActive) {
|
||||||
return html``;
|
return html``;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { LitElement, html } from "lit";
|
|||||||
import { customElement } from "lit/decorators.js";
|
import { customElement } from "lit/decorators.js";
|
||||||
import { GameView } from "../../../core/game/GameView";
|
import { GameView } from "../../../core/game/GameView";
|
||||||
import { crazyGamesSDK } from "../../CrazyGamesSDK";
|
import { crazyGamesSDK } from "../../CrazyGamesSDK";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
|
|
||||||
const AD_TYPES = [
|
const AD_TYPES = [
|
||||||
{ type: "standard_iab_left1", selectorId: "in-game-bottom-left-ad" },
|
{ type: "standard_iab_left1", selectorId: "in-game-bottom-left-ad" },
|
||||||
@@ -11,7 +11,7 @@ const AD_TYPES = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
@customElement("in-game-promo")
|
@customElement("in-game-promo")
|
||||||
export class InGamePromo extends LitElement implements Layer {
|
export class InGamePromo extends LitElement implements Controller {
|
||||||
public game: GameView;
|
public game: GameView;
|
||||||
|
|
||||||
private shouldShow: boolean = false;
|
private shouldShow: boolean = false;
|
||||||
@@ -169,10 +169,6 @@ export class InGamePromo extends LitElement implements Layer {
|
|||||||
this.requestUpdate();
|
this.requestUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldTransform(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.shouldShow) {
|
if (!this.shouldShow) {
|
||||||
return html``;
|
return html``;
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
export interface Layer {
|
|
||||||
init?: () => void;
|
|
||||||
tick?: () => void;
|
|
||||||
// Optional hint to throttle expensive ticks by wall-clock.
|
|
||||||
// If omitted or <= 0, the layer ticks whenever GameRenderer ticks.
|
|
||||||
getTickIntervalMs?: () => number;
|
|
||||||
renderLayer?: (context: CanvasRenderingContext2D) => void;
|
|
||||||
shouldTransform?: () => boolean;
|
|
||||||
redraw?: () => void;
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,7 @@ import { EventBus } from "../../../core/EventBus";
|
|||||||
import { GameView, PlayerView } from "../../../core/game/GameView";
|
import { GameView, PlayerView } from "../../../core/game/GameView";
|
||||||
import { formatPercentage, renderNumber } from "../../Utils";
|
import { formatPercentage, renderNumber } from "../../Utils";
|
||||||
import { GoToPlayerEvent } from "../TransformHandler";
|
import { GoToPlayerEvent } from "../TransformHandler";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
|
|
||||||
interface Entry {
|
interface Entry {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -20,7 +20,7 @@ interface Entry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@customElement("leader-board")
|
@customElement("leader-board")
|
||||||
export class Leaderboard extends LitElement implements Layer {
|
export class Leaderboard extends LitElement implements Controller {
|
||||||
public game: GameView | null = null;
|
public game: GameView | null = null;
|
||||||
public eventBus: EventBus | null = null;
|
public eventBus: EventBus | null = null;
|
||||||
|
|
||||||
@@ -157,12 +157,6 @@ export class Leaderboard extends LitElement implements Layer {
|
|||||||
this.eventBus.emit(new GoToPlayerEvent(player));
|
this.eventBus.emit(new GoToPlayerEvent(player));
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLayer(context: CanvasRenderingContext2D) {}
|
|
||||||
|
|
||||||
shouldTransform(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.visible) {
|
if (!this.visible) {
|
||||||
return html``;
|
return html``;
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import { TransformHandler } from "../TransformHandler";
|
|||||||
import { UIState } from "../UIState";
|
import { UIState } from "../UIState";
|
||||||
import { BuildMenu } from "./BuildMenu";
|
import { BuildMenu } from "./BuildMenu";
|
||||||
import { ChatIntegration } from "./ChatIntegration";
|
import { ChatIntegration } from "./ChatIntegration";
|
||||||
|
import { Controller } from "./Controller";
|
||||||
import { EmojiTable } from "./EmojiTable";
|
import { EmojiTable } from "./EmojiTable";
|
||||||
import { Layer } from "./Layer";
|
|
||||||
import { PlayerActionHandler } from "./PlayerActionHandler";
|
import { PlayerActionHandler } from "./PlayerActionHandler";
|
||||||
import { PlayerPanel } from "./PlayerPanel";
|
import { PlayerPanel } from "./PlayerPanel";
|
||||||
import { RadialMenu, RadialMenuConfig } from "./RadialMenu";
|
import { RadialMenu, RadialMenuConfig } from "./RadialMenu";
|
||||||
@@ -26,7 +26,7 @@ const swordIcon = assetUrl("images/SwordIconWhite.svg");
|
|||||||
import { ContextMenuEvent } from "../../InputHandler";
|
import { ContextMenuEvent } from "../../InputHandler";
|
||||||
|
|
||||||
@customElement("main-radial-menu")
|
@customElement("main-radial-menu")
|
||||||
export class MainRadialMenu extends LitElement implements Layer {
|
export class MainRadialMenu extends LitElement implements Controller {
|
||||||
private radialMenu: RadialMenu;
|
private radialMenu: RadialMenu;
|
||||||
|
|
||||||
private playerActionHandler: PlayerActionHandler;
|
private playerActionHandler: PlayerActionHandler;
|
||||||
@@ -173,14 +173,6 @@ export class MainRadialMenu extends LitElement implements Layer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLayer(context: CanvasRenderingContext2D) {
|
|
||||||
this.radialMenu.renderLayer(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldTransform(): boolean {
|
|
||||||
return this.radialMenu.shouldTransform();
|
|
||||||
}
|
|
||||||
|
|
||||||
closeMenu() {
|
closeMenu() {
|
||||||
if (this.radialMenu.isMenuVisible()) {
|
if (this.radialMenu.isMenuVisible()) {
|
||||||
this.radialMenu.hideRadialMenu();
|
this.radialMenu.hideRadialMenu();
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import { GameType } from "../../../core/game/Game";
|
|||||||
import { GameView } from "../../../core/game/GameView";
|
import { GameView } from "../../../core/game/GameView";
|
||||||
import { MultiTabDetector } from "../../MultiTabDetector";
|
import { MultiTabDetector } from "../../MultiTabDetector";
|
||||||
import { translateText } from "../../Utils";
|
import { translateText } from "../../Utils";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
|
|
||||||
@customElement("multi-tab-modal")
|
@customElement("multi-tab-modal")
|
||||||
export class MultiTabModal extends LitElement implements Layer {
|
export class MultiTabModal extends LitElement implements Controller {
|
||||||
public game: GameView;
|
public game: GameView;
|
||||||
|
|
||||||
private detector: MultiTabDetector;
|
private detector: MultiTabDetector;
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ import {
|
|||||||
import type { LangSelector } from "../../LangSelector";
|
import type { LangSelector } from "../../LangSelector";
|
||||||
import { translateText } from "../../Utils";
|
import { translateText } from "../../Utils";
|
||||||
import { FrameProfiler } from "../FrameProfiler";
|
import { FrameProfiler } from "../FrameProfiler";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
|
|
||||||
@customElement("performance-overlay")
|
@customElement("performance-overlay")
|
||||||
export class PerformanceOverlay extends LitElement implements Layer {
|
export class PerformanceOverlay extends LitElement implements Controller {
|
||||||
@property({ type: Object })
|
@property({ type: Object })
|
||||||
public eventBus!: EventBus;
|
public eventBus!: EventBus;
|
||||||
|
|
||||||
@@ -969,10 +969,6 @@ export class PerformanceOverlay extends LitElement implements Layer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldTransform(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private getPerformanceColor(fps: number): string {
|
private getPerformanceColor(fps: number): string {
|
||||||
if (fps >= 55) return "performance-good";
|
if (fps >= 55) return "performance-good";
|
||||||
if (fps >= 30) return "performance-warning";
|
if (fps >= 30) return "performance-warning";
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ import {
|
|||||||
IMAGE_ICON_KIND,
|
IMAGE_ICON_KIND,
|
||||||
} from "../PlayerIcons";
|
} from "../PlayerIcons";
|
||||||
import { TransformHandler } from "../TransformHandler";
|
import { TransformHandler } from "../TransformHandler";
|
||||||
|
import { Controller } from "./Controller";
|
||||||
import { ImmunityBarVisibleEvent } from "./ImmunityTimer";
|
import { ImmunityBarVisibleEvent } from "./ImmunityTimer";
|
||||||
import { Layer } from "./Layer";
|
|
||||||
import { CloseRadialMenuEvent } from "./RadialMenu";
|
import { CloseRadialMenuEvent } from "./RadialMenu";
|
||||||
import "./RelationSmiley";
|
import "./RelationSmiley";
|
||||||
import { SpawnBarVisibleEvent } from "./SpawnTimer";
|
import { SpawnBarVisibleEvent } from "./SpawnTimer";
|
||||||
@@ -68,7 +68,7 @@ function distSortUnitWorld(coord: { x: number; y: number }, game: GameView) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@customElement("player-info-overlay")
|
@customElement("player-info-overlay")
|
||||||
export class PlayerInfoOverlay extends LitElement implements Layer {
|
export class PlayerInfoOverlay extends LitElement implements Controller {
|
||||||
@property({ type: Object })
|
@property({ type: Object })
|
||||||
public game!: GameView;
|
public game!: GameView;
|
||||||
|
|
||||||
@@ -171,14 +171,6 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
|||||||
this.requestUpdate();
|
this.requestUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLayer(context: CanvasRenderingContext2D) {
|
|
||||||
// Implementation for Layer interface
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldTransform(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
setVisible(visible: boolean) {
|
setVisible(visible: boolean) {
|
||||||
this._isInfoVisible = visible;
|
this._isInfoVisible = visible;
|
||||||
this.requestUpdate();
|
this.requestUpdate();
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ import {
|
|||||||
} from "../../Utils";
|
} from "../../Utils";
|
||||||
import { UIState } from "../UIState";
|
import { UIState } from "../UIState";
|
||||||
import { ChatModal } from "./ChatModal";
|
import { ChatModal } from "./ChatModal";
|
||||||
|
import { Controller } from "./Controller";
|
||||||
import { EmojiTable } from "./EmojiTable";
|
import { EmojiTable } from "./EmojiTable";
|
||||||
import { Layer } from "./Layer";
|
|
||||||
import "./PlayerModerationModal";
|
import "./PlayerModerationModal";
|
||||||
import "./SendResourceModal";
|
import "./SendResourceModal";
|
||||||
const allianceIcon = assetUrl("images/AllianceIconWhite.svg");
|
const allianceIcon = assetUrl("images/AllianceIconWhite.svg");
|
||||||
@@ -53,7 +53,7 @@ const traitorIcon = assetUrl("images/TraitorIconLightRed.svg");
|
|||||||
const breakAllianceIcon = assetUrl("images/TraitorIconWhite.svg");
|
const breakAllianceIcon = assetUrl("images/TraitorIconWhite.svg");
|
||||||
|
|
||||||
@customElement("player-panel")
|
@customElement("player-panel")
|
||||||
export class PlayerPanel extends LitElement implements Layer {
|
export class PlayerPanel extends LitElement implements Controller {
|
||||||
public g: GameView;
|
public g: GameView;
|
||||||
public eventBus: EventBus;
|
public eventBus: EventBus;
|
||||||
public emojiTable: EmojiTable;
|
public emojiTable: EmojiTable;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { EventBus, GameEvent } from "../../../core/EventBus";
|
|||||||
import { CloseViewEvent } from "../../InputHandler";
|
import { CloseViewEvent } from "../../InputHandler";
|
||||||
import { PlaySoundEffectEvent } from "../../sound/Sounds";
|
import { PlaySoundEffectEvent } from "../../sound/Sounds";
|
||||||
import { getSvgAspectRatio, translateText } from "../../Utils";
|
import { getSvgAspectRatio, translateText } from "../../Utils";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
import {
|
import {
|
||||||
CenterButtonElement,
|
CenterButtonElement,
|
||||||
MenuElement,
|
MenuElement,
|
||||||
@@ -51,7 +51,7 @@ type CenterButtonState = "default" | "back";
|
|||||||
|
|
||||||
type RequiredRadialMenuConfig = Required<RadialMenuConfig>;
|
type RequiredRadialMenuConfig = Required<RadialMenuConfig>;
|
||||||
|
|
||||||
export class RadialMenu implements Layer {
|
export class RadialMenu implements Controller {
|
||||||
private menuElement: d3.Selection<HTMLDivElement, unknown, null, undefined>;
|
private menuElement: d3.Selection<HTMLDivElement, unknown, null, undefined>;
|
||||||
private tooltipElement: HTMLDivElement | null = null;
|
private tooltipElement: HTMLDivElement | null = null;
|
||||||
private isVisible: boolean = false;
|
private isVisible: boolean = false;
|
||||||
@@ -1341,14 +1341,6 @@ export class RadialMenu implements Layer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLayer(context: CanvasRenderingContext2D) {
|
|
||||||
// No need to render anything on the canvas
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldTransform(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private isReopeningAllowed(): boolean {
|
private isReopeningAllowed(): boolean {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const timeSinceHide = now - this.lastHideTime;
|
const timeSinceHide = now - this.lastHideTime;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
ReplaySpeedMultiplier,
|
ReplaySpeedMultiplier,
|
||||||
} from "../../utilities/ReplaySpeedMultiplier";
|
} from "../../utilities/ReplaySpeedMultiplier";
|
||||||
import { translateText } from "../../Utils";
|
import { translateText } from "../../Utils";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
|
|
||||||
export class ShowReplayPanelEvent {
|
export class ShowReplayPanelEvent {
|
||||||
constructor(
|
constructor(
|
||||||
@@ -18,7 +18,7 @@ export class ShowReplayPanelEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@customElement("replay-panel")
|
@customElement("replay-panel")
|
||||||
export class ReplayPanel extends LitElement implements Layer {
|
export class ReplayPanel extends LitElement implements Controller {
|
||||||
public game: GameView | undefined;
|
public game: GameView | undefined;
|
||||||
public eventBus: EventBus | undefined;
|
public eventBus: EventBus | undefined;
|
||||||
|
|
||||||
@@ -65,11 +65,6 @@ export class ReplayPanel extends LitElement implements Layer {
|
|||||||
this.eventBus?.emit(new ReplaySpeedChangeEvent(value));
|
this.eventBus?.emit(new ReplaySpeedChangeEvent(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLayer(_ctx: CanvasRenderingContext2D) {}
|
|
||||||
shouldTransform() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.visible) return html``;
|
if (!this.visible) return html``;
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
SetBackgroundMusicVolumeEvent,
|
SetBackgroundMusicVolumeEvent,
|
||||||
SetSoundEffectsVolumeEvent,
|
SetSoundEffectsVolumeEvent,
|
||||||
} from "../../sound/Sounds";
|
} from "../../sound/Sounds";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
const structureIcon = assetUrl("images/CityIconWhite.svg");
|
const structureIcon = assetUrl("images/CityIconWhite.svg");
|
||||||
const cursorPriceIcon = assetUrl("images/CursorPriceIconWhite.svg");
|
const cursorPriceIcon = assetUrl("images/CursorPriceIconWhite.svg");
|
||||||
const darkModeIcon = assetUrl("images/DarkModeIconWhite.svg");
|
const darkModeIcon = assetUrl("images/DarkModeIconWhite.svg");
|
||||||
@@ -35,7 +35,7 @@ export class ShowSettingsModalEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@customElement("settings-modal")
|
@customElement("settings-modal")
|
||||||
export class SettingsModal extends LitElement implements Layer {
|
export class SettingsModal extends LitElement implements Controller {
|
||||||
public eventBus: EventBus;
|
public eventBus: EventBus;
|
||||||
public userSettings: UserSettings;
|
public userSettings: UserSettings;
|
||||||
|
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ import { EventBus, GameEvent } from "../../../core/EventBus";
|
|||||||
import { GameMode, GameType, Team } from "../../../core/game/Game";
|
import { GameMode, GameType, Team } from "../../../core/game/Game";
|
||||||
import { GameView } from "../../../core/game/GameView";
|
import { GameView } from "../../../core/game/GameView";
|
||||||
import { TransformHandler } from "../TransformHandler";
|
import { TransformHandler } from "../TransformHandler";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
|
|
||||||
export class SpawnBarVisibleEvent implements GameEvent {
|
export class SpawnBarVisibleEvent implements GameEvent {
|
||||||
constructor(public readonly visible: boolean) {}
|
constructor(public readonly visible: boolean) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@customElement("spawn-timer")
|
@customElement("spawn-timer")
|
||||||
export class SpawnTimer extends LitElement implements Layer {
|
export class SpawnTimer extends LitElement implements Controller {
|
||||||
public game: GameView;
|
public game: GameView;
|
||||||
public eventBus: EventBus;
|
public eventBus: EventBus;
|
||||||
public transformHandler: TransformHandler;
|
public transformHandler: TransformHandler;
|
||||||
@@ -95,10 +95,6 @@ export class SpawnTimer extends LitElement implements Layer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldTransform(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.isVisible) {
|
if (!this.isVisible) {
|
||||||
return html``;
|
return html``;
|
||||||
|
|||||||
@@ -30,14 +30,14 @@ import {
|
|||||||
} from "../../Transport";
|
} from "../../Transport";
|
||||||
import { TransformHandler } from "../TransformHandler";
|
import { TransformHandler } from "../TransformHandler";
|
||||||
import { UIState } from "../UIState";
|
import { UIState } from "../UIState";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
|
|
||||||
/** True for nuke types (AtomBomb, HydrogenBomb): ghost is preserved after placement so user can place multiple or keep selection (Enter/key confirm). */
|
/** True for nuke types (AtomBomb, HydrogenBomb): ghost is preserved after placement so user can place multiple or keep selection (Enter/key confirm). */
|
||||||
export function shouldPreserveGhostAfterBuild(unitType: UnitType): boolean {
|
export function shouldPreserveGhostAfterBuild(unitType: UnitType): boolean {
|
||||||
return unitType === UnitType.AtomBomb || unitType === UnitType.HydrogenBomb;
|
return unitType === UnitType.AtomBomb || unitType === UnitType.HydrogenBomb;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class StructureIconsLayer implements Layer {
|
export class StructureIconsLayer implements Controller {
|
||||||
/** Current ghost (null when no build type is active). */
|
/** Current ghost (null when no build type is active). */
|
||||||
private ghostUnit: { buildableUnit: BuildableUnit } | null = null;
|
private ghostUnit: { buildableUnit: BuildableUnit } | null = null;
|
||||||
private readonly connectedAllySmallIds: Set<number> = new Set();
|
private readonly connectedAllySmallIds: Set<number> = new Set();
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
renderTroops,
|
renderTroops,
|
||||||
translateText,
|
translateText,
|
||||||
} from "../../Utils";
|
} from "../../Utils";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
|
|
||||||
interface TeamEntry {
|
interface TeamEntry {
|
||||||
teamName: string;
|
teamName: string;
|
||||||
@@ -26,7 +26,7 @@ interface TeamEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@customElement("team-stats")
|
@customElement("team-stats")
|
||||||
export class TeamStats extends LitElement implements Layer {
|
export class TeamStats extends LitElement implements Controller {
|
||||||
public game: GameView;
|
public game: GameView;
|
||||||
public eventBus: EventBus;
|
public eventBus: EventBus;
|
||||||
|
|
||||||
@@ -125,12 +125,6 @@ export class TeamStats extends LitElement implements Layer {
|
|||||||
this.requestUpdate();
|
this.requestUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLayer(context: CanvasRenderingContext2D) {}
|
|
||||||
|
|
||||||
shouldTransform(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.visible) return html``;
|
if (!this.visible) return html``;
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
} from "../../InputHandler";
|
} from "../../InputHandler";
|
||||||
import { MoveWarshipIntentEvent } from "../../Transport";
|
import { MoveWarshipIntentEvent } from "../../Transport";
|
||||||
import { TransformHandler } from "../TransformHandler";
|
import { TransformHandler } from "../TransformHandler";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
|
|
||||||
const WARSHIP_SELECTION_RADIUS = 10;
|
const WARSHIP_SELECTION_RADIUS = 10;
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ const WARSHIP_SELECTION_RADIUS = 10;
|
|||||||
* it stays in the Layer list for lifecycle hooks (init / tick / event
|
* it stays in the Layer list for lifecycle hooks (init / tick / event
|
||||||
* subscriptions).
|
* subscriptions).
|
||||||
*/
|
*/
|
||||||
export class UILayer implements Layer {
|
export class UILayer implements Controller {
|
||||||
// Currently selected single warship (game-logic readers use this; the
|
// Currently selected single warship (game-logic readers use this; the
|
||||||
// visual is drawn by WebGL SelectionBoxPass).
|
// visual is drawn by WebGL SelectionBoxPass).
|
||||||
private selectedUnit: UnitView | null = null;
|
private selectedUnit: UnitView | null = null;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
} from "../../InputHandler";
|
} from "../../InputHandler";
|
||||||
import { renderNumber, translateText } from "../../Utils";
|
import { renderNumber, translateText } from "../../Utils";
|
||||||
import { UIState } from "../UIState";
|
import { UIState } from "../UIState";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
const warshipIcon = assetUrl("images/BattleshipIconWhite.svg");
|
const warshipIcon = assetUrl("images/BattleshipIconWhite.svg");
|
||||||
const cityIcon = assetUrl("images/CityIconWhite.svg");
|
const cityIcon = assetUrl("images/CityIconWhite.svg");
|
||||||
const factoryIcon = assetUrl("images/FactoryIconWhite.svg");
|
const factoryIcon = assetUrl("images/FactoryIconWhite.svg");
|
||||||
@@ -31,7 +31,7 @@ const samLauncherIcon = assetUrl("images/SamLauncherIconWhite.svg");
|
|||||||
const defensePostIcon = assetUrl("images/ShieldIconWhite.svg");
|
const defensePostIcon = assetUrl("images/ShieldIconWhite.svg");
|
||||||
|
|
||||||
@customElement("unit-display")
|
@customElement("unit-display")
|
||||||
export class UnitDisplay extends LitElement implements Layer {
|
export class UnitDisplay extends LitElement implements Controller {
|
||||||
public game: GameView;
|
public game: GameView;
|
||||||
public eventBus: EventBus;
|
public eventBus: EventBus;
|
||||||
public uiState: UIState;
|
public uiState: UIState;
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ import {
|
|||||||
import { crazyGamesSDK } from "../../CrazyGamesSDK";
|
import { crazyGamesSDK } from "../../CrazyGamesSDK";
|
||||||
import { Platform } from "../../Platform";
|
import { Platform } from "../../Platform";
|
||||||
import { SendWinnerEvent } from "../../Transport";
|
import { SendWinnerEvent } from "../../Transport";
|
||||||
import { Layer } from "./Layer";
|
import { Controller } from "./Controller";
|
||||||
|
|
||||||
@customElement("win-modal")
|
@customElement("win-modal")
|
||||||
export class WinModal extends LitElement implements Layer {
|
export class WinModal extends LitElement implements Controller {
|
||||||
public game: GameView;
|
public game: GameView;
|
||||||
public eventBus: EventBus;
|
public eventBus: EventBus;
|
||||||
|
|
||||||
@@ -321,10 +321,4 @@ export class WinModal extends LitElement implements Layer {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLayer(/* context: CanvasRenderingContext2D */) {}
|
|
||||||
|
|
||||||
shouldTransform(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user