diff --git a/src/client/view/GameView.ts b/src/client/view/GameView.ts index 6dd2d9fcc..283e571b3 100644 --- a/src/client/view/GameView.ts +++ b/src/client/view/GameView.ts @@ -76,6 +76,8 @@ export class GameView implements GameMap { import("../render/types").PlayerState >(); private _unitStates = new Map(); + /** smallID → team, for the renderer's relation matrix (team games). */ + private _teams = new Map(); private updatedTiles: TileRef[] = []; private updatedTerrainTiles: TileRef[] = []; @@ -327,6 +329,10 @@ export class GameView implements GameMap { ); this._players.set(pu.id, player); this._playerStates.set(pu.smallID!, player.state); + const team = player.team(); + if (team !== null) { + this._teams.set(pu.smallID!, team); + } } }); @@ -472,7 +478,7 @@ export class GameView implements GameMap { isTransitiveTarget: (sid) => this._myPlayer?.hasTransitiveTarget(sid) ?? false, }); - const rel = buildRelationMatrix(this._playerStates); + const rel = buildRelationMatrix(this._playerStates, this._teams); f.relationMatrix = rel.matrix; f.relationSize = rel.size; f.allianceClusters = computeAllianceClusters(this._playerStates); diff --git a/tests/client/view/GameView.test.ts b/tests/client/view/GameView.test.ts index 6ed1c1f72..f520aba9f 100644 --- a/tests/client/view/GameView.test.ts +++ b/tests/client/view/GameView.test.ts @@ -466,4 +466,24 @@ describe("GameView.frameData() — renderer contract", () => { game.update(makeEmptyGu(2)); expect(game.frameData().structuresDirty).toBe(false); }); + + it("frame.relationMatrix marks same-team players as friendly (team games)", () => { + const RELATION_FRIENDLY = 1; + const RELATION_NEUTRAL = 0; + const game = makeGameView(); + game.update( + withPlayers(1, [ + makePlayerUpdate({ id: "alice", smallID: 1, team: "red" }), + makePlayerUpdate({ id: "bob", smallID: 2, team: "red" }), + makePlayerUpdate({ id: "carol", smallID: 3, team: "blue" }), + ]), + ); + const { relationMatrix, relationSize } = game.frameData(); + // Teammates (no explicit alliance) are friendly both ways. + expect(relationMatrix[1 * relationSize + 2]).toBe(RELATION_FRIENDLY); + expect(relationMatrix[2 * relationSize + 1]).toBe(RELATION_FRIENDLY); + // Cross-team players stay neutral. + expect(relationMatrix[1 * relationSize + 3]).toBe(RELATION_NEUTRAL); + expect(relationMatrix[3 * relationSize + 1]).toBe(RELATION_NEUTRAL); + }); });