Files
OpenFrontIO/src/core/game/TileImpl.ts
T
2025-02-01 12:05:11 -08:00

156 lines
4.0 KiB
TypeScript

import { Tile, Cell, TerrainType, Player, TerraNullius, MutablePlayer, TerrainTile, DefenseBonus, MutableTile, TileUpdate, GameUpdateType, TerrainTileKey } from "./Game";
import { TerrainMapImpl, TerrainTileImpl } from "./TerrainMapLoader";
import { GameImpl } from "./GameImpl";
import { PlayerImpl } from "./PlayerImpl";
import { TerraNulliusImpl } from "./TerraNulliusImpl";
import { GameMap, TileRef } from "./GameMap";
export class TileImpl implements MutableTile {
constructor(
private readonly gs: GameImpl,
private ref_: TileRef
) { }
terrain(): TerrainTile {
return new TerrainRef(this.gs.map(), this.ref_)
}
neighborsWrapped(): Tile[] {
// TODO: implement!
return this.neighbors()
}
ref(): TileRef {
return this.ref_
}
toUpdate(): TileUpdate {
return {
type: GameUpdateType.Tile,
pos: {
x: this.x(),
y: this.y()
},
ownerID: this.owner().smallID(),
hasFallout: this.hasFallout(),
hasDefenseBonus: this.hasDefenseBonus(),
isBorder: this.isBorder(),
}
}
hasFallout(): boolean {
return this.gs.map().hasFallout(this.ref_)
}
type(): TerrainType {
return this.gs.map().getTerrainType(this.ref_)
}
hasDefenseBonus(): boolean {
return this.defenseBonuses.length > 0
}
defenseBonus(player: Player): number {
// TODO!
return 0
// if (this.owner() == player) {
// throw Error(`cannot get defense bonus of tile already owned by player, ${player}`)
// }
// let bonusAmount = 0
// for (const bonus of this._defenseBonuses) {
// if (bonus.unit.owner() != player) {
// bonusAmount += bonus.amount
// }
// }
// return Math.max(bonusAmount, 1)
}
defenseBonuses(): DefenseBonus[] {
// TODO!
return []
}
borders(other: Player | TerraNullius): boolean {
for (const n of this.neighbors()) {
if (n.owner() == other) {
return true;
}
}
return false;
}
hasOwner(): boolean { return this.owner().smallID() != 0 }
owner(): MutablePlayer | TerraNullius {
const ownerID = this.gs.map().ownerID(this.ref_)
if (ownerID == 0) {
return this.gs.terraNullius()
}
return this.gs.playerBySmallID(ownerID) as MutablePlayer
}
isBorder(): boolean { return this.gs.map().isBorder(this.ref_); }
cell(): Cell { return new Cell(this.x(), this.y()); }
x(): number {
return this.gs.map().x(this.ref_)
}
y(): number {
return this.gs.map().y(this.ref_)
}
neighbors(): Tile[] {
return this.gs.neighbors(this)
}
}
export class TerrainRef implements TerrainTile {
constructor(private map: GameMap, private ref: TileRef) { }
isLand(): boolean {
return this.map.isLand(this.ref)
}
isShore(): boolean {
return this.map.isShore(this.ref)
}
isOceanShore(): boolean {
return this.isShore() && this.neighbors().filter(n => n.isOcean()).length > 0;
}
isWater(): boolean {
return !this.map.isLand(this.ref)
}
isShorelineWater(): boolean {
return this.isWater() && this.isShore()
}
isOcean(): boolean {
return this.map.isOcean(this.ref)
}
isLake(): boolean {
return this.isWater() && !this.isOcean()
}
type(): TerrainType {
return this.map.getTerrainType(this.ref)
}
magnitude(): number {
return this.map.magnitude(this.ref)
}
equals(other: TerrainTile): boolean {
return this.ref == (other as TerrainRef).ref
}
cell(): Cell {
return this.map.cell(this.ref)
}
neighbors(): TerrainTile[] {
return this.map.neighbors(this.ref).map(tr => new TerrainRef(this.map, tr))
}
cost(): number {
return this.map.cost(this.ref)
}
}