mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-24 23:54:35 +00:00
140 lines
3.7 KiB
TypeScript
140 lines
3.7 KiB
TypeScript
import { Tile, Cell, TerrainType, Player, TerraNullius, MutablePlayer, TerrainTile, DefenseBonus } from "./Game";
|
|
import { SearchNode } from "../pathfinding/AStar";
|
|
import { TerrainTileImpl } from "./TerrainMapLoader";
|
|
import { GameImpl } from "./GameImpl";
|
|
import { PlayerImpl } from "./PlayerImpl";
|
|
import { TerraNulliusImpl } from "./TerraNulliusImpl";
|
|
|
|
|
|
export class TileImpl implements Tile {
|
|
|
|
public _isBorder = false;
|
|
private _neighbors: Tile[] = null;
|
|
|
|
public _defenseBonuses: DefenseBonus[] = []
|
|
|
|
constructor(
|
|
private readonly gs: GameImpl,
|
|
public _owner: PlayerImpl | TerraNulliusImpl,
|
|
private readonly _cell: Cell,
|
|
private readonly _terrain: TerrainTileImpl
|
|
) { }
|
|
|
|
terrainType(): TerrainType {
|
|
return this._terrain.type
|
|
}
|
|
|
|
defenseBonus(player: Player): number {
|
|
if (this.owner() == player) {
|
|
throw Error(`cannot get defense bonus of tile already owned by 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[] {
|
|
return this._defenseBonuses
|
|
}
|
|
|
|
neighborsWrapped(): Tile[] {
|
|
const x = this._cell.x;
|
|
const y = this._cell.y;
|
|
const ns: Tile[] = [];
|
|
|
|
// Check top neighbor
|
|
if (y > 0) {
|
|
ns.push(this.gs.map[x][y - 1]);
|
|
}
|
|
|
|
// Check bottom neighbor
|
|
if (y < this.gs.height() - 1) {
|
|
ns.push(this.gs.map[x][y + 1]);
|
|
}
|
|
|
|
// Check left neighbor (wrap around)
|
|
if (x > 0) {
|
|
ns.push(this.gs.map[x - 1][y]);
|
|
} else {
|
|
ns.push(this.gs.map[this.gs.width() - 1][y]);
|
|
}
|
|
|
|
// Check right neighbor (wrap around)
|
|
if (x < this.gs.width() - 1) {
|
|
ns.push(this.gs.map[x + 1][y]);
|
|
} else {
|
|
ns.push(this.gs.map[0][y]);
|
|
}
|
|
return ns;
|
|
}
|
|
isLake(): boolean {
|
|
return !this.isLand() && !this.isOcean();
|
|
}
|
|
isOcean(): boolean {
|
|
return this._terrain.ocean;
|
|
}
|
|
magnitude(): number {
|
|
return this._terrain.magnitude;
|
|
}
|
|
isShore(): boolean {
|
|
return this.isLand() && this._terrain.shoreline;
|
|
}
|
|
isOceanShore(): boolean {
|
|
return this.isShore() && this.neighbors().filter(n => n.isOcean()).length > 0;
|
|
}
|
|
isShorelineWater(): boolean {
|
|
return this.isWater() && this._terrain.shoreline;
|
|
}
|
|
isLand(): boolean {
|
|
return this._terrain.land;
|
|
}
|
|
isWater(): boolean {
|
|
return !this._terrain.land;
|
|
}
|
|
terrain(): TerrainType {
|
|
return this._terrain.type;
|
|
}
|
|
|
|
borders(other: Player | TerraNullius): boolean {
|
|
for (const n of this.neighbors()) {
|
|
if (n.owner() == other) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
onShore(): boolean {
|
|
return this.neighbors()
|
|
.filter(t => t.isWater())
|
|
.length > 0;
|
|
}
|
|
|
|
hasOwner(): boolean { return this._owner != this.gs._terraNullius; }
|
|
owner(): MutablePlayer | TerraNullius { return this._owner; }
|
|
isBorder(): boolean { return this._isBorder; }
|
|
isInterior(): boolean { return this.hasOwner() && !this.isBorder(); }
|
|
cell(): Cell { return this._cell; }
|
|
x(): number {
|
|
return this._cell.x
|
|
}
|
|
y(): number {
|
|
return this._cell.y
|
|
}
|
|
|
|
neighbors(): Tile[] {
|
|
if (this._neighbors == null) {
|
|
this._neighbors = this.gs.neighbors(this);
|
|
}
|
|
return this._neighbors;
|
|
}
|
|
|
|
cost(): number {
|
|
return this.magnitude() < 10 ? 2 : 1
|
|
};
|
|
}
|