From 10a1f1af8e6219895ff0e3c664ededbb54412ebe Mon Sep 17 00:00:00 2001 From: evanpelle Date: Wed, 8 Jan 2025 09:48:40 -0800 Subject: [PATCH] thread_split: enable spawn highlight --- src/client/graphics/NameBoxCalculator.ts | 4 +- src/client/graphics/layers/TerritoryLayer.ts | 46 +++++++------------- src/core/GameRunner.ts | 2 +- src/core/configuration/DevConfig.ts | 2 +- src/core/execution/SpawnExecution.ts | 11 ++--- src/core/execution/Util.ts | 25 ++--------- src/core/game/GameImpl.ts | 3 ++ 7 files changed, 33 insertions(+), 60 deletions(-) diff --git a/src/client/graphics/NameBoxCalculator.ts b/src/client/graphics/NameBoxCalculator.ts index 62b7b2625..46aed9ef4 100644 --- a/src/client/graphics/NameBoxCalculator.ts +++ b/src/client/graphics/NameBoxCalculator.ts @@ -37,8 +37,8 @@ export function placeName(game: Game, player: Player): NameViewData { center = new Cell(center.x, center.y - fontSize / 3) return { - x: center.x, - y: center.y, + x: Math.ceil(center.x), + y: Math.ceil(center.y), size: fontSize, } } diff --git a/src/client/graphics/layers/TerritoryLayer.ts b/src/client/graphics/layers/TerritoryLayer.ts index 4087d7ae3..9431fe654 100644 --- a/src/client/graphics/layers/TerritoryLayer.ts +++ b/src/client/graphics/layers/TerritoryLayer.ts @@ -5,11 +5,9 @@ import { colord, Colord } from "colord"; import { bfs, dist, euclDist, euclideanDist } from "../../../core/Util"; import { Theme } from "../../../core/configuration/Config"; import { Layer } from "./Layer"; -import { TransformHandler } from "../TransformHandler"; import { EventBus } from "../../../core/EventBus"; -import { initRemoteSender } from "../../../core/Consolex"; import { AlternateViewEvent, DragEvent, MouseDownEvent } from "../../InputHandler"; -import { GameView } from "../../../core/GameView"; +import { GameView, PlayerView } from "../../../core/GameView"; export class TerritoryLayer implements Layer { private canvas: HTMLCanvasElement @@ -42,7 +40,7 @@ export class TerritoryLayer implements Layer { tick() { this.game.recentlyUpdatedTiles() - .forEach(t => this.enqueue(t)) + .forEach(t => this.enqueueTile(t)) if (!this.game.inSpawnPhase()) { @@ -53,24 +51,27 @@ export class TerritoryLayer implements Layer { } this.highlightContext.clearRect(0, 0, this.game.width(), this.game.height()); - const humans = this.game.players() + const humans = this.game.playerViews() .filter(p => p.type() == PlayerType.Human) - const alreadyPainted = new Set() for (const human of humans) { - for (const borderTile of human.borderTiles()) { - for (const neighbor of bfs(borderTile, euclDist(borderTile, 5))) { - if (!neighbor.hasOwner() && !alreadyPainted.has(neighbor)) { - this.paintHighlightCell(neighbor.cell(), this.theme.spawnHighlightColor(), 120) - alreadyPainted.add(neighbor) - } + const center = human.nameLocation() + if (!center) { + continue + } + const centerTile = this.game.tile(new Cell(center.x, center.y)) + if (!centerTile) { + continue + } + for (const tile of bfs(centerTile, euclDist(centerTile, 9))) { + if (!tile.hasOwner()) { + this.paintHighlightCell(tile.cell(), this.theme.spawnHighlightColor(), 255) } } } } init() { - this.eventBus.on(TileEvent, e => this.tileUpdate(e)) this.eventBus.on(AlternateViewEvent, e => { this.alternativeView = e.alternateView }) this.eventBus.on(DragEvent, e => { this.lastDragTime = Date.now() }) this.redraw() @@ -203,28 +204,13 @@ export class TerritoryLayer implements Layer { dist(event.unit.tile(), this.game.config().defensePostRange()) ).forEach(t => { if (t.isBorder()) { - this.enqueue(t) + this.enqueueTile(t) } }) } } - tileUpdate(event: TileEvent) { - this.enqueue(event.tile) - // if (this.game.inSpawnPhase()) { - // if (event.tile.owner().isPlayer()) { - // for (const border of (event.tile.owner() as Player).borderTiles()) { - // for (const neighbor of border.neighbors()) { - // if (!neighbor.hasOwner()) { - // this.paintHighlightCell(neighbor.cell(), this.theme.spawnHighlightColor(), 255) - // } - // } - // } - // } - // } - } - - enqueue(tile: Tile) { + enqueueTile(tile: Tile) { this.tileToRenderQueue.push({ tile: tile, lastUpdate: this.game.ticks() + this.random.nextFloat(0, .5) }) } diff --git a/src/core/GameRunner.ts b/src/core/GameRunner.ts index 274fd9d86..d6c23b558 100644 --- a/src/core/GameRunner.ts +++ b/src/core/GameRunner.ts @@ -68,7 +68,7 @@ export class GameRunner { this.currTurn++ this.game.executeNextTick() - if (this.game.ticks() % 10 == 0) { + if (this.game.inSpawnPhase() || this.game.ticks() % 10 == 0) { this.game.players() .forEach(p => this.playerToName.set(p.id(), placeName(this.game, p))) } diff --git a/src/core/configuration/DevConfig.ts b/src/core/configuration/DevConfig.ts index 7e4999d6f..43b01b7d9 100644 --- a/src/core/configuration/DevConfig.ts +++ b/src/core/configuration/DevConfig.ts @@ -19,7 +19,7 @@ export class DevConfig extends DefaultConfig { } numSpawnPhaseTurns(): number { - return this.gameConfig().gameType == GameType.Singleplayer ? 40 : 200 + return this.gameConfig().gameType == GameType.Singleplayer ? 400 : 200 // return 100 } diff --git a/src/core/execution/SpawnExecution.ts b/src/core/execution/SpawnExecution.ts index 81c8e1f45..f8d1e26c5 100644 --- a/src/core/execution/SpawnExecution.ts +++ b/src/core/execution/SpawnExecution.ts @@ -1,7 +1,7 @@ import { Cell, Execution, MutableGame, MutablePlayer, PlayerInfo, PlayerType } from "../game/Game" import { BotExecution } from "./BotExecution" import { PlayerExecution } from "./PlayerExecution" -import { getSpawnCells } from "./Util" +import { getSpawnTiles } from "./Util" export class SpawnExecution implements Execution { @@ -25,17 +25,18 @@ export class SpawnExecution implements Execution { } const existing = this.mg.players().find(p => p.id() == this.playerInfo.id) + const tile = this.mg.tile(this.cell) if (existing) { existing.tiles().forEach(t => existing.relinquish(t)) - getSpawnCells(this.mg, this.cell).forEach(c => { - existing.conquer(this.mg.tile(c)) + getSpawnTiles(tile).forEach(t => { + existing.conquer(t) }) return } const player = this.mg.addPlayer(this.playerInfo, this.mg.config().startManpower(this.playerInfo)) - getSpawnCells(this.mg, this.cell).forEach(c => { - player.conquer(this.mg.tile(c)) + getSpawnTiles(tile).forEach(t => { + player.conquer(t) }) this.mg.addExecution(new PlayerExecution(player.id())) if (player.type() == PlayerType.Bot) { diff --git a/src/core/execution/Util.ts b/src/core/execution/Util.ts index fe4a4c946..7c60e603d 100644 --- a/src/core/execution/Util.ts +++ b/src/core/execution/Util.ts @@ -1,27 +1,10 @@ import { Game, Cell, Tile } from "../game/Game"; +import { and, bfs, euclDist } from "../Util"; -export function getSpawnCells(gs: Game, cell: Cell): Cell[] { - let result: Cell[] = []; - for (let dx = -2; dx <= 2; dx++) { - for (let dy = -2; dy <= 2; dy++) { - let c = new Cell(cell.x + dx, cell.y + dy); - if (!gs.isOnMap(c)) { - continue; - } - if (Math.abs(dx) === 2 && Math.abs(dy) === 2) { - continue; - } - if (gs.tile(c).terrain().isWater()) { - continue; - } - if (gs.tile(c).hasOwner()) { - continue; - } - result.push(c); - } - } - return result; +export function getSpawnTiles(tile: Tile): Tile[] { + return Array.from(bfs(tile, euclDist(tile, 4))) + .filter(t => !t.hasOwner() && t.terrain().isLand()) } export function closestTwoTiles(x: Iterable, y: Iterable): { x: Tile, y: Tile } { diff --git a/src/core/game/GameImpl.ts b/src/core/game/GameImpl.ts index c7cc9e8c7..dfe3cebc1 100644 --- a/src/core/game/GameImpl.ts +++ b/src/core/game/GameImpl.ts @@ -332,6 +332,9 @@ export class GameImpl implements MutableGame { } conquer(owner: PlayerImpl, tile: Tile): void { + if (!tile.terrain().isLand()) { + throw Error(`cannot conquer water`) + } const tileImpl = tile as TileImpl let previousOwner = tileImpl._owner if (previousOwner.isPlayer()) {