Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
48b8d18
Do not assume we don't need canAttack if units is undefined. Some cod…
VariableVince Feb 15, 2026
074aa48
Move BUILDABLE_TYPES to Game.ts, rename as BuildMenuTypes and add Pla…
VariableVince Feb 15, 2026
5139a38
Some more small perf and maintainability gains
VariableVince Feb 15, 2026
aae3bdd
Remove unused properties from DefaultConfig unitInfo (already unused …
VariableVince Feb 15, 2026
fdb8fdd
Typesafety: add new type PlayerBuildableUnitType so callers of buidab…
VariableVince Feb 16, 2026
6725fe7
More logical position for buildableNukeTypes
VariableVince Feb 16, 2026
954c7f7
Remove redundant imports
VariableVince Feb 16, 2026
9be10ab
Fixes
VariableVince Feb 16, 2026
a4beca5
Woops
VariableVince Feb 16, 2026
19cd340
Rabbit
VariableVince Feb 16, 2026
3c6390b
Prettier
VariableVince Feb 16, 2026
3263ff0
Remove unused getPlayerActions from PlayerActionHandler, the only pot…
VariableVince Feb 16, 2026
cbb3586
Rabbit
VariableVince Feb 16, 2026
60dedc0
Introduce playerBuildables to only get buildable units, because Struc…
VariableVince Feb 16, 2026
6ec0689
BuildMenu now also only uses playerBuildables instead of playerActions
VariableVince Feb 16, 2026
0ebbb11
Fixes
VariableVince Feb 16, 2026
e279462
Remove the already unused PlayerActions from StructureIconsLayer
VariableVince Feb 16, 2026
7775847
Even more type safety
VariableVince Feb 16, 2026
ea1467a
Rabbit
VariableVince Feb 16, 2026
902356d
Rabbit
VariableVince Feb 16, 2026
805c989
Remove unused attackTypes array
VariableVince Feb 16, 2026
4f53db6
UnitsDisplay also only needs buildables. Also consolidation and perf …
VariableVince Feb 16, 2026
0ac2257
Remove existing pascal case usage from RadialMenuElements
VariableVince Feb 16, 2026
4f48194
Revert part of change, should not closeMenu if buildableUnit isn't found
VariableVince Feb 16, 2026
973356f
Small simplification
VariableVince Feb 16, 2026
5e39189
Merge branch 'main' into some-leftovers
VariableVince Feb 17, 2026
87a8793
Small naming consistency thing
VariableVince Feb 17, 2026
109db46
Small inconsistency
VariableVince Feb 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions src/client/ClientGameRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
import { createPartialGameRecord, replacer } from "../core/Util";
import { ServerConfig } from "../core/configuration/Config";
import { getConfig } from "../core/configuration/ConfigLoader";
import { PlayerActions, UnitType } from "../core/game/Game";
import { PlayerActions, StructureTypes, UnitType } from "../core/game/Game";
import { TileRef } from "../core/game/GameMap";
import { GameMapLoader } from "../core/game/GameMapLoader";
import {
Expand Down Expand Up @@ -557,13 +557,12 @@ export class ClientGameRunner {
if (myPlayer === null) return;
this.myPlayer = myPlayer;
}
this.myPlayer.actions(tile).then((actions) => {
if (this.myPlayer === null) return;
this.myPlayer.actions(tile, [UnitType.TransportShip]).then((actions) => {
if (actions.canAttack) {
this.eventBus.emit(
new SendAttackIntentEvent(
this.gameView.owner(tile).id(),
this.myPlayer.troops() * this.renderer.uiState.attackRatio,
this.myPlayer!.troops() * this.renderer.uiState.attackRatio,
),
);
} else if (this.canAutoBoat(actions, tile)) {
Expand Down Expand Up @@ -601,7 +600,7 @@ export class ClientGameRunner {
}

private findAndUpgradeNearestBuilding(clickedTile: TileRef) {
this.myPlayer!.actions(clickedTile).then((actions) => {
this.myPlayer!.actions(clickedTile, StructureTypes).then((actions) => {
const upgradeUnits: {
unitId: number;
unitType: UnitType;
Expand Down Expand Up @@ -654,7 +653,7 @@ export class ClientGameRunner {
this.myPlayer = myPlayer;
}

this.myPlayer.actions(tile).then((actions) => {
this.myPlayer.actions(tile, [UnitType.TransportShip]).then((actions) => {
if (this.canBoatAttack(actions) !== false) {
this.sendBoatAttackIntent(tile);
}
Expand All @@ -673,13 +672,12 @@ export class ClientGameRunner {
this.myPlayer = myPlayer;
}

this.myPlayer.actions(tile).then((actions) => {
if (this.myPlayer === null) return;
this.myPlayer.actions(tile, null).then((actions) => {
if (actions.canAttack) {
this.eventBus.emit(
new SendAttackIntentEvent(
this.gameView.owner(tile).id(),
this.myPlayer.troops() * this.renderer.uiState.attackRatio,
this.myPlayer!.troops() * this.renderer.uiState.attackRatio,
),
);
}
Expand Down
6 changes: 3 additions & 3 deletions src/client/InputHandler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { EventBus, GameEvent } from "../core/EventBus";
import { UnitType } from "../core/game/Game";
import { PlayerBuildableUnitType, UnitType } from "../core/game/Game";
import { UnitView } from "../core/game/GameView";
import { UserSettings } from "../core/game/UserSettings";
import { UIState } from "./graphics/UIState";
Expand Down Expand Up @@ -86,7 +86,7 @@ export class ToggleStructureEvent implements GameEvent {
}

export class GhostStructureChangedEvent implements GameEvent {
constructor(public readonly ghostStructure: UnitType | null) {}
constructor(public readonly ghostStructure: PlayerBuildableUnitType | null) {}
}

export class SwapRocketDirectionEvent implements GameEvent {
Expand Down Expand Up @@ -591,7 +591,7 @@ export class InputHandler {
this.eventBus.emit(new ContextMenuEvent(event.clientX, event.clientY));
}

private setGhostStructure(ghostStructure: UnitType | null) {
private setGhostStructure(ghostStructure: PlayerBuildableUnitType | null) {
this.uiState.ghostStructure = ghostStructure;
this.eventBus.emit(new GhostStructureChangedEvent(ghostStructure));
}
Expand Down
4 changes: 2 additions & 2 deletions src/client/graphics/UIState.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { UnitType } from "../../core/game/Game";
import { PlayerBuildableUnitType } from "../../core/game/Game";

export interface UIState {
attackRatio: number;
ghostStructure: UnitType | null;
ghostStructure: PlayerBuildableUnitType | null;
overlappingRailroads: number[];
rocketDirectionUp: boolean;
}
27 changes: 13 additions & 14 deletions src/client/graphics/layers/BuildMenu.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { LitElement, css, html } from "lit";
import { css, html, LitElement } from "lit";
import { customElement, state } from "lit/decorators.js";
import { translateText } from "../../../client/Utils";
import { EventBus } from "../../../core/EventBus";
import {
BuildableUnit,
BuildMenuTypes,
Gold,
PlayerActions,
PlayerBuildableUnitType,
UnitType,
} from "../../../core/game/Game";
import { TileRef } from "../../../core/game/GameMap";
Expand Down Expand Up @@ -37,7 +38,7 @@ import samlauncherIcon from "/images/SamLauncherIconWhite.svg?url";
import shieldIcon from "/images/ShieldIconWhite.svg?url";

export interface BuildItemDisplay {
unitType: UnitType;
unitType: PlayerBuildableUnitType;
icon: string;
description?: string;
key?: string;
Expand Down Expand Up @@ -88,7 +89,6 @@ export const buildTable: BuildItemDisplay[][] = [
key: "unit_type.missile_silo",
countable: true,
},
// needs new icon
{
unitType: UnitType.SAMLauncher,
icon: samlauncherIcon,
Expand Down Expand Up @@ -128,7 +128,7 @@ export class BuildMenu extends LitElement implements Layer {
public eventBus: EventBus;
public uiState: UIState;
private clickedTile: TileRef;
public playerActions: PlayerActions | null;
public playerBuildables: BuildableUnit[] | null = null;
private filteredBuildTable: BuildItemDisplay[][] = buildTable;
public transformHandler: TransformHandler;

Expand Down Expand Up @@ -359,19 +359,18 @@ export class BuildMenu extends LitElement implements Layer {
private _hidden = true;

public canBuildOrUpgrade(item: BuildItemDisplay): boolean {
if (this.game?.myPlayer() === null || this.playerActions === null) {
if (this.game?.myPlayer() === null || this.playerBuildables === null) {
return false;
}
const buildableUnits = this.playerActions?.buildableUnits ?? [];
const unit = buildableUnits.filter((u) => u.type === item.unitType);
const unit = this.playerBuildables.filter((u) => u.type === item.unitType);
if (unit.length === 0) {
return false;
}
return unit[0].canBuild !== false || unit[0].canUpgrade !== false;
}

public cost(item: BuildItemDisplay): Gold {
for (const bu of this.playerActions?.buildableUnits ?? []) {
for (const bu of this.playerBuildables ?? []) {
if (bu.type === item.unitType) {
return bu.cost;
}
Expand Down Expand Up @@ -419,7 +418,7 @@ export class BuildMenu extends LitElement implements Layer {
(row) => html`
<div class="build-row">
${row.map((item) => {
const buildableUnit = this.playerActions?.buildableUnits.find(
const buildableUnit = this.playerBuildables?.find(
(bu) => bu.type === item.unitType,
);
if (buildableUnit === undefined) {
Expand Down Expand Up @@ -492,13 +491,13 @@ export class BuildMenu extends LitElement implements Layer {
private refresh() {
this.game
.myPlayer()
?.actions(this.clickedTile)
.then((actions) => {
this.playerActions = actions;
?.buildables(this.clickedTile, BuildMenuTypes)
.then((buildables) => {
this.playerBuildables = buildables;
this.requestUpdate();
});

// removed disabled buildings from the buildtable
// remove disabled buildings from the buildtable
this.filteredBuildTable = this.getBuildableUnits();
}

Expand Down
2 changes: 1 addition & 1 deletion src/client/graphics/layers/MainRadialMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export class MainRadialMenu extends LitElement implements Layer {
screenX: number | null = null,
screenY: number | null = null,
) {
this.buildMenu.playerActions = actions;
this.buildMenu.playerBuildables = actions.buildableUnits;

const tileOwner = this.game.owner(tile);
const recipient = tileOwner.isPlayer() ? (tileOwner as PlayerView) : null;
Expand Down
12 changes: 6 additions & 6 deletions src/client/graphics/layers/NukeTrajectoryPreviewLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class NukeTrajectoryPreviewLayer implements Layer {
private lastTrajectoryUpdate: number = 0;
private lastTargetTile: TileRef | null = null;
private currentGhostStructure: UnitType | null = null;
// Cache spawn tile to avoid expensive player.actions() calls
// Cache spawn tile to avoid expensive player.buildables() calls
private cachedSpawnTile: TileRef | null = null;

constructor(
Expand Down Expand Up @@ -75,7 +75,7 @@ export class NukeTrajectoryPreviewLayer implements Layer {
}

/**
* Update trajectory preview - called from tick() to cache spawn tile via expensive player.actions() call
* Update trajectory preview - called from tick() to cache spawn tile via expensive player.buildables() call
* This only runs when target tile changes, minimizing worker thread communication
*/
private updateTrajectoryPreview() {
Expand Down Expand Up @@ -138,14 +138,14 @@ export class NukeTrajectoryPreviewLayer implements Layer {

// Get buildable units to find spawn tile (expensive call - only on tick when tile changes)
player
.actions(targetTile, [ghostStructure])
.then((actions) => {
.buildables(targetTile, [ghostStructure])
.then((buildables) => {
// Ignore stale results if target changed
if (this.lastTargetTile !== targetTile) {
return;
}

const buildableUnit = actions.buildableUnits.find(
const buildableUnit = buildables.find(
(bu) => bu.type === ghostStructure,
);

Expand All @@ -171,7 +171,7 @@ export class NukeTrajectoryPreviewLayer implements Layer {

/**
* Update trajectory path - called from renderLayer() each frame for smooth visual feedback
* Uses cached spawn tile to avoid expensive player.actions() calls
* Uses cached spawn tile to avoid expensive player.buildables() calls
*/
private updateTrajectoryPath() {
const ghostStructure = this.currentGhostStructure;
Expand Down
8 changes: 0 additions & 8 deletions src/client/graphics/layers/PlayerActionHandler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { EventBus } from "../../../core/EventBus";
import { PlayerActions } from "../../../core/game/Game";
import { TileRef } from "../../../core/game/GameMap";
import { PlayerView } from "../../../core/game/GameView";
import {
Expand All @@ -23,13 +22,6 @@ export class PlayerActionHandler {
private uiState: UIState,
) {}

async getPlayerActions(
player: PlayerView,
tile: TileRef,
): Promise<PlayerActions> {
return await player.actions(tile);
}

handleAttack(player: PlayerView, targetId: string | null) {
this.eventBus.emit(
new SendAttackIntentEvent(
Expand Down
2 changes: 1 addition & 1 deletion src/client/graphics/layers/PlayerPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export class PlayerPanel extends LitElement implements Layer {
// Refresh actions & alliance expiry
const myPlayer = this.g.myPlayer();
if (myPlayer !== null && myPlayer.isAlive()) {
this.actions = await myPlayer.actions(this.tile);
this.actions = await myPlayer.actions(this.tile, null);
if (this.actions?.interaction?.allianceExpiresAt !== undefined) {
const expiresAt = this.actions.interaction.allianceExpiresAt;
const remainingTicks = expiresAt - this.g.ticks();
Expand Down
Loading
Loading