diff --git a/src/client/graphics/layers/StructureLayer.ts b/src/client/graphics/layers/StructureLayer.ts index 6e98fe681..94f904a7c 100644 --- a/src/client/graphics/layers/StructureLayer.ts +++ b/src/client/graphics/layers/StructureLayer.ts @@ -72,6 +72,12 @@ export class StructureLayer implements Layer { private handlePortEvent(event: UnitEvent) { if (!this.anchorImageLoaded) return; + bfs(event.unit.tile(), euclDist(event.unit.tile(), 8)) + .forEach(t => this.clearCell(t.cell())); + + if (!event.unit.isActive()) { + return + } // Create a temporary canvas to process the anchor icon const tempCanvas = document.createElement('canvas'); const tempContext = tempCanvas.getContext('2d'); diff --git a/src/core/configuration/DevConfig.ts b/src/core/configuration/DevConfig.ts index 133237fdc..22007c4ca 100644 --- a/src/core/configuration/DevConfig.ts +++ b/src/core/configuration/DevConfig.ts @@ -6,7 +6,7 @@ export const devConfig = new class extends DefaultConfig { return 95 } numSpawnPhaseTurns(): number { - return 20 + return 80 } gameCreationRate(): number { return 20 * 1000 diff --git a/src/core/execution/PortExecution.ts b/src/core/execution/PortExecution.ts index b6c7ce048..20abd3d5a 100644 --- a/src/core/execution/PortExecution.ts +++ b/src/core/execution/PortExecution.ts @@ -1,5 +1,5 @@ import { BuildValidator } from "../game/BuildValidator"; -import { AllPlayers, BuildItem, BuildItems, Cell, Execution, MutableGame, MutablePlayer, PlayerID, UnitType } from "../game/Game"; +import { AllPlayers, BuildItem, BuildItems, Cell, Execution, MutableGame, MutablePlayer, MutableUnit, Player, PlayerID, UnitType } from "../game/Game"; import { bfs, dist, manhattanDist } from "../Util"; export class PortExecution implements Execution { @@ -7,6 +7,7 @@ export class PortExecution implements Execution { private active = true private mg: MutableGame private player: MutablePlayer + private port: MutableUnit constructor( private _owner: PlayerID, @@ -20,24 +21,32 @@ export class PortExecution implements Execution { } tick(ticks: number): void { - const tile = this.mg.tile(this.cell) - if (!new BuildValidator(this.mg).canBuild(this.player, tile, BuildItems.Port)) { - console.warn(`player ${this.player} cannot build port at ${this.cell}`) + if (this.port == null) { + const tile = this.mg.tile(this.cell) + if (!new BuildValidator(this.mg).canBuild(this.player, tile, BuildItems.Port)) { + console.warn(`player ${this.player} cannot build port at ${this.cell}`) + this.active = false + return + } + const spawns = Array.from(bfs(tile, dist(tile, 20))) + .filter(t => t.isOceanShore() && t.owner() == this.player) + .sort((a, b) => manhattanDist(a.cell(), tile.cell()) - manhattanDist(b.cell(), tile.cell())) + + if (spawns.length == 0) { + console.warn(`cannot find spawn for port`) + this.active = false + return + } + this.port = this.player.addUnit(UnitType.Port, 0, spawns[0]) + } + if (!this.port.tile().hasOwner()) { + this.port.delete() this.active = false return } - const spawns = Array.from(bfs(tile, dist(tile, 20))) - .filter(t => t.isOceanShore() && t.owner() == this.player) - .sort((a, b) => manhattanDist(a.cell(), tile.cell()) - manhattanDist(b.cell(), tile.cell())) - - if (spawns.length == 0) { - console.warn(`cannot find spawn for port`) - this.active = false - return + if (this.port.tile().owner() != this.port.owner()) { + this.port.setOwner(this.port.tile().owner() as Player) } - - this.player.addUnit(UnitType.Port, 0, spawns[0]) - this.active = false } owner(): MutablePlayer { diff --git a/src/core/game/Game.ts b/src/core/game/Game.ts index a2c22af84..5e560ca7b 100644 --- a/src/core/game/Game.ts +++ b/src/core/game/Game.ts @@ -40,7 +40,8 @@ export class BuildItem { } export const BuildItems = { - Nuke: new BuildItem(UnitType.Nuke, 1_000_000), + // Nuke: new BuildItem(UnitType.Nuke, 1_000_000), + Nuke: new BuildItem(UnitType.Nuke, 10), Destroyer: new BuildItem(UnitType.Destroyer, 10), Port: new BuildItem(UnitType.Port, 0) } as const; @@ -170,6 +171,7 @@ export interface MutableUnit extends Unit { owner(): MutablePlayer setTroops(troops: number): void delete(): void + setOwner(newOwner: Player): void } export interface TerraNullius { diff --git a/src/core/game/UnitImpl.ts b/src/core/game/UnitImpl.ts index 249c30ea3..5d411068a 100644 --- a/src/core/game/UnitImpl.ts +++ b/src/core/game/UnitImpl.ts @@ -1,4 +1,4 @@ -import { MutableUnit, Tile, TerraNullius, UnitType } from "./Game"; +import { MutableUnit, Tile, TerraNullius, UnitType, Player } from "./Game"; import { GameImpl } from "./GameImpl"; import { PlayerImpl } from "./PlayerImpl"; import { TerraNulliusImpl } from "./TerraNulliusImpl"; @@ -37,6 +37,11 @@ export class UnitImpl implements MutableUnit { return this._owner; } + setOwner(newOwner: Player): void { + this._owner = newOwner as PlayerImpl + this.g.fireUnitUpdateEvent(this, this.tile()) + } + delete(): void { this._owner._units = this._owner._units.filter(b => b != this); this._active = false;