From a484f6a3fc2b4d4a8491217d0865c0a974c9f436 Mon Sep 17 00:00:00 2001 From: Mattia Migliorini Date: Mon, 9 Mar 2026 13:06:06 +0100 Subject: [PATCH] Move team renaming logic o assignTeams() --- src/core/game/GameImpl.ts | 58 ++------------------------------- src/core/game/TeamAssignment.ts | 55 ++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 57 deletions(-) diff --git a/src/core/game/GameImpl.ts b/src/core/game/GameImpl.ts index 38d20379c..abebd2252 100644 --- a/src/core/game/GameImpl.ts +++ b/src/core/game/GameImpl.ts @@ -49,7 +49,7 @@ import { RailNetwork } from "./RailNetwork"; import { createRailNetwork } from "./RailNetworkImpl"; import { Stats } from "./Stats"; import { StatsImpl } from "./StatsImpl"; -import { assignTeams, computeClanTeamName } from "./TeamAssignment"; +import { assignTeams } from "./TeamAssignment"; import { TerraNulliusImpl } from "./TerraNulliusImpl"; import { UnitGrid, UnitPredicate } from "./UnitGrid"; @@ -214,61 +214,7 @@ export class GameImpl implements Game { ...this._nations.map((n) => n.playerInfo), ]; const playerToTeam = assignTeams(allPlayers, this.playerTeams); - - // Only rename numbered teams (8+ team mode), not colored teams - const coloredTeamValues = Object.values(ColoredTeams); - const isNumberedTeams = !this.playerTeams.some((t) => - coloredTeamValues.includes(t), - ); - - if (isNumberedTeams) { - // Build reverse map: team → assigned players - const teamToPlayers = new Map(); - for (const [pi, team] of playerToTeam.entries()) { - if (team === "kicked") continue; - if (!teamToPlayers.has(team)) teamToPlayers.set(team, []); - teamToPlayers.get(team)!.push(pi); - } - - // Compute candidate names - const renameMap = new Map(); - for (const [oldTeam, teamPlayers] of teamToPlayers.entries()) { - const newName = computeClanTeamName(teamPlayers); - if (newName !== null && newName !== oldTeam) { - renameMap.set(oldTeam, newName); - } - } - - // Collision check: repeatedly remove renames that collide with existing - // team names or with each other until no more removals occur. - let changed = true; - while (changed) { - changed = false; - const existingNames = new Set( - this.playerTeams.filter((t) => !renameMap.has(t)), - ); - const newNames = Array.from(renameMap.values()); - for (const [oldTeam, newName] of renameMap.entries()) { - if ( - existingNames.has(newName) || - newNames.filter((n) => n === newName).length > 1 - ) { - renameMap.delete(oldTeam); - changed = true; - } - } - } - - // Apply renames to playerTeams array (preserves index order for teamSpawnArea) - this.playerTeams = this.playerTeams.map((t) => renameMap.get(t) ?? t); - - // Apply renames to playerToTeam - for (const [pi, team] of playerToTeam.entries()) { - if (team !== "kicked" && renameMap.has(team)) { - playerToTeam.set(pi, renameMap.get(team)!); - } - } - } + // this.playerTeams is updated in-place by assignTeams for (const [playerInfo, team] of playerToTeam.entries()) { if (team === "kicked") { diff --git a/src/core/game/TeamAssignment.ts b/src/core/game/TeamAssignment.ts index 3d0428a48..4b09fdeba 100644 --- a/src/core/game/TeamAssignment.ts +++ b/src/core/game/TeamAssignment.ts @@ -1,6 +1,6 @@ import { PseudoRandom } from "../PseudoRandom"; import { simpleHash } from "../Util"; -import { PlayerInfo, PlayerType, Team } from "./Game"; +import { ColoredTeams, PlayerInfo, PlayerType, Team } from "./Game"; export function assignTeams( players: PlayerInfo[], @@ -84,6 +84,59 @@ export function assignTeams( result.set(player, team); } + // Only rename numbered teams (8+ team mode), not colored teams + const coloredTeamValues = Object.values(ColoredTeams); + const isNumberedTeams = !teams.some((t) => coloredTeamValues.includes(t)); + + if (isNumberedTeams) { + // Build reverse map: team → assigned players + const teamToPlayers = new Map(); + for (const [pi, team] of result.entries()) { + if (team === "kicked") continue; + if (!teamToPlayers.has(team)) teamToPlayers.set(team, []); + teamToPlayers.get(team)!.push(pi); + } + + // Compute candidate names + const renameMap = new Map(); + for (const [oldTeam, teamPlayers] of teamToPlayers.entries()) { + const newName = computeClanTeamName(teamPlayers); + if (newName !== null && newName !== oldTeam) { + renameMap.set(oldTeam, newName); + } + } + + // Collision check: repeatedly remove renames that collide with existing + // team names or with each other until no more removals occur. + let changed = true; + while (changed) { + changed = false; + const existingNames = new Set(teams.filter((t) => !renameMap.has(t))); + const newNames = Array.from(renameMap.values()); + for (const [oldTeam, newName] of renameMap.entries()) { + if ( + existingNames.has(newName) || + newNames.filter((n) => n === newName).length > 1 + ) { + renameMap.delete(oldTeam); + changed = true; + } + } + } + + // Apply renames to teams array in-place (preserves index order for teamSpawnArea) + for (let i = 0; i < teams.length; i++) { + teams[i] = renameMap.get(teams[i]) ?? teams[i]; + } + + // Apply renames to result map + for (const [pi, team] of result.entries()) { + if (team !== "kicked" && renameMap.has(team)) { + result.set(pi, renameMap.get(team)!); + } + } + } + return result; }