diff --git a/src/core/game/UnitGrid.ts b/src/core/game/UnitGrid.ts index 62e703a68..027f1b33f 100644 --- a/src/core/game/UnitGrid.ts +++ b/src/core/game/UnitGrid.ts @@ -3,7 +3,7 @@ import { GameMap, TileRef } from "./GameMap"; import { UnitView } from "./GameView"; export class UnitGrid { - private grid: Set[][]; + private grid: Map>[][]; private readonly cellSize = 100; constructor(private gm: GameMap) { @@ -12,7 +12,7 @@ export class UnitGrid { .map(() => Array(Math.ceil(gm.width() / this.cellSize)) .fill(null) - .map(() => new Set()), + .map(() => new Map>()), ); } @@ -27,7 +27,15 @@ export class UnitGrid { const [gridX, gridY] = this.getGridCoords(this.gm.x(tile), this.gm.y(tile)); if (this.isValidCell(gridX, gridY)) { - this.grid[gridY][gridX].add(unit); + const unitSet = this.grid[gridY][gridX].get(unit.type()); + if (unitSet !== undefined) { + unitSet.add(unit); + } else { + this.grid[gridY][gridX].set( + unit.type(), + new Set([unit]), + ); + } } } @@ -41,7 +49,10 @@ export class UnitGrid { const [gridX, gridY] = this.getGridCoords(this.gm.x(tile), this.gm.y(tile)); if (this.isValidCell(gridX, gridY)) { - this.grid[gridY][gridX].delete(unit); + const unitSet = this.grid[gridY][gridX].get(unit.type()); + if (unitSet !== undefined) { + unitSet.delete(unit); + } } } @@ -134,14 +145,17 @@ export class UnitGrid { const typeSet = Array.isArray(types) ? new Set(types) : new Set([types]); for (let cy = startGridY; cy <= endGridY; cy++) { for (let cx = startGridX; cx <= endGridX; cx++) { - for (const unit of this.grid[cy][cx]) { - if (!typeSet.has(unit.type())) continue; - if (!unit.isActive()) continue; - const distSquared = this.squaredDistanceFromTile(unit, tile); - if (distSquared > rangeSquared) continue; - const value = { unit, distSquared }; - if (predicate !== undefined && !predicate(value)) continue; - nearby.push(value); + for (const type of typeSet) { + const unitSet = this.grid[cy][cx].get(type); + if (unitSet === undefined) continue; + for (const unit of unitSet) { + if (!unit.isActive()) continue; + const distSquared = this.squaredDistanceFromTile(unit, tile); + if (distSquared > rangeSquared) continue; + const value = { unit, distSquared }; + if (predicate !== undefined && !predicate(value)) continue; + nearby.push(value); + } } } } @@ -162,12 +176,10 @@ export class UnitGrid { const rangeSquared = searchRange * searchRange; for (let cy = startGridY; cy <= endGridY; cy++) { for (let cx = startGridX; cx <= endGridX; cx++) { - for (const unit of this.grid[cy][cx]) { - if ( - unit.type() === type && - unit.owner().id() === playerId && - unit.isActive() - ) { + const unitSet = this.grid[cy][cx].get(type); + if (unitSet === undefined) continue; + for (const unit of unitSet) { + if (unit.owner().id() === playerId && unit.isActive()) { const distSquared = this.squaredDistanceFromTile(unit, tile); if (distSquared <= rangeSquared) { return true;