47 lines
1.5 KiB
JavaScript
47 lines
1.5 KiB
JavaScript
// Reads the per-terrain figures baked into generated tile dictionaries. A
|
|
// movement multiplier of 0 (an unauthored layer, or a non-land tile) falls back
|
|
// to a normal cost so a unit is never frozen.
|
|
|
|
import { key, parseKey } from "./hex.js";
|
|
|
|
export const DEFAULT_MOVEMENT_COST_MULTIPLIER = 1.0;
|
|
|
|
export class TerrainStats {
|
|
constructor(tiles) {
|
|
this._tiles = tiles;
|
|
this._minMovementCost = undefined;
|
|
}
|
|
|
|
_value(coords, field) {
|
|
const tile = this._tiles[key(coords.x, coords.y)];
|
|
return tile ? (tile[field] || 0) : 0;
|
|
}
|
|
|
|
populationMultiplier(coords) {
|
|
return this._value(coords, "populationMultiplier");
|
|
}
|
|
|
|
gdpMultiplier(coords) {
|
|
return this._value(coords, "gdpMultiplier");
|
|
}
|
|
|
|
movementCostMultiplier(coords) {
|
|
const value = this._value(coords, "movementCostMultiplier");
|
|
return value > 0 ? value : DEFAULT_MOVEMENT_COST_MULTIPLIER;
|
|
}
|
|
|
|
// Cheapest authored movement cost across every tile in use, so the A*
|
|
// heuristic never overestimates a path. The terrain is fixed once generated,
|
|
// so the scan is done once and cached.
|
|
minMovementCostMultiplier() {
|
|
if (this._minMovementCost !== undefined) return this._minMovementCost;
|
|
let cheapest = Infinity;
|
|
for (const k in this._tiles) {
|
|
const value = this.movementCostMultiplier(parseKey(k));
|
|
if (value < cheapest) cheapest = value;
|
|
}
|
|
this._minMovementCost = cheapest < Infinity ? cheapest : DEFAULT_MOVEMENT_COST_MULTIPLIER;
|
|
return this._minMovementCost;
|
|
}
|
|
}
|