From 9bf6b5af742b9a0f4e54b119433d98fca620ab50 Mon Sep 17 00:00:00 2001 From: evanpelle Date: Wed, 27 May 2026 15:54:17 -0700 Subject: [PATCH] fix(render): only show transport attack rings for the local player's boats Filter extractAttackRings to the local player's smallID so FxAttackRingPass only draws rings on the player's own transports. Drop the unused extractAttackRingsFromIds variant and the dead frame/index.ts barrel re-exports. --- src/client/render/frame/derive/AttackRings.ts | 25 ++----------------- src/client/render/frame/index.ts | 13 ---------- src/client/view/GameView.ts | 8 +++++- 3 files changed, 9 insertions(+), 37 deletions(-) diff --git a/src/client/render/frame/derive/AttackRings.ts b/src/client/render/frame/derive/AttackRings.ts index fbe025839..c78f57403 100644 --- a/src/client/render/frame/derive/AttackRings.ts +++ b/src/client/render/frame/derive/AttackRings.ts @@ -8,34 +8,13 @@ import { UT_TRANSPORT } from "../../types"; export function extractAttackRings( units: ReadonlyMap, mapW: number, - ownerFilter?: number, + owner: number, ): AttackRingInput[] { const rings: AttackRingInput[] = []; for (const u of units.values()) { if (u.unitType !== UT_TRANSPORT) continue; if (u.targetTile === null || !u.isActive || u.retreating) continue; - if (ownerFilter !== undefined && u.ownerID !== ownerFilter) continue; - const t = u.targetTile; - rings.push({ x: t % mapW, y: (t - (t % mapW)) / mapW, unitId: u.id }); - } - return rings; -} - -/** - * Targeted variant — iterates only pre-classified transport IDs instead of all units. - * Used by the live path where UnitClassifier maintains the transport ID set. - */ -export function extractAttackRingsFromIds( - transportIds: readonly number[], - units: ReadonlyMap, - mapW: number, - ownerFilter?: number, -): AttackRingInput[] { - const rings: AttackRingInput[] = []; - for (const id of transportIds) { - const u = units.get(id); - if (!u || u.targetTile === null || !u.isActive || u.retreating) continue; - if (ownerFilter !== undefined && u.ownerID !== ownerFilter) continue; + if (u.ownerID !== owner) continue; const t = u.targetTile; rings.push({ x: t % mapW, y: (t - (t % mapW)) / mapW, unitId: u.id }); } diff --git a/src/client/render/frame/index.ts b/src/client/render/frame/index.ts index ddcb4fa55..86b43b0ef 100644 --- a/src/client/render/frame/index.ts +++ b/src/client/render/frame/index.ts @@ -1,19 +1,6 @@ // Re-export the boundary contract type export type { FrameData } from "../types"; -// Shared derive functions -export { computeAllianceClusters } from "./derive/AllianceClusters"; -export { - extractAttackRings, - extractAttackRingsFromIds, -} from "./derive/AttackRings"; -export { - extractNukeTelegraphs, - extractNukeTelegraphsFromIds, -} from "./derive/NukeTelegraphs"; -export { computePlayerStatus } from "./derive/PlayerStatus"; -export { buildRelationMatrix, buildTeamMap } from "./derive/RelationMatrix"; - // Upload export type { RelationMatrixResult } from "./derive/RelationMatrix"; export { uploadFrameData } from "./Upload"; diff --git a/src/client/view/GameView.ts b/src/client/view/GameView.ts index 9db7f6052..92a62538d 100644 --- a/src/client/view/GameView.ts +++ b/src/client/view/GameView.ts @@ -494,7 +494,13 @@ export class GameView implements GameMap { this._unitStates, this._map.width(), ); - f.attackRings = extractAttackRings(this._unitStates, this._map.width()); + f.attackRings = this._myPlayer + ? extractAttackRings( + this._unitStates, + this._map.width(), + this._myPlayer.smallID(), + ) + : []; f.structuresDirty = this._structuresDirty; // First populate: signal "full upload required" by nulling changedTiles.