75 lines
2.3 KiB
TypeScript
75 lines
2.3 KiB
TypeScript
|
import { BEACH, ICECAP, LIGHT_FOREST, MOUNTAIN, WATER } from "./data";
|
||
|
import { IslandGrid } from "./grid";
|
||
|
|
||
|
export type IsDone = boolean;
|
||
|
export type LobeGenerator = () => IsDone;
|
||
|
export type LobeGeneratorConstructor = (
|
||
|
islands: IslandGrid,
|
||
|
basePos: number
|
||
|
) => LobeGenerator;
|
||
|
|
||
|
/** form mountain with icecap */
|
||
|
export const BIG_MOUNTAIN: LobeGeneratorConstructor =
|
||
|
(islands: IslandGrid, basePos: number) => () => {
|
||
|
const mountainTiles = islands.floodSearch(
|
||
|
basePos,
|
||
|
(tile) => tile > MOUNTAIN
|
||
|
);
|
||
|
islands.dropWithin(mountainTiles);
|
||
|
|
||
|
return mountainTiles.some((pos) => islands.data[pos] == ICECAP);
|
||
|
};
|
||
|
|
||
|
/** form low-lying beach */
|
||
|
export const BEACH_LOBE: LobeGeneratorConstructor =
|
||
|
(islands: IslandGrid, basePos: number) => () => {
|
||
|
const islandTiles = islands.floodSearch(basePos, (tile) => tile > WATER);
|
||
|
|
||
|
const shoreTiles = islandTiles.filter((pos) => islands.data[pos] == WATER);
|
||
|
islands.dropWithin(shoreTiles);
|
||
|
|
||
|
return true;
|
||
|
};
|
||
|
|
||
|
/** form forested zone */
|
||
|
export const FOREST_LOBE: LobeGeneratorConstructor =
|
||
|
(islands: IslandGrid, basePos: number) => () => {
|
||
|
const islandTiles = islands.floodSearch(basePos, (tile) => tile > WATER);
|
||
|
|
||
|
// grow shore
|
||
|
const shoreTiles = islandTiles.filter((pos) => islands.data[pos] == WATER);
|
||
|
islands.dropWithin(shoreTiles);
|
||
|
|
||
|
// seed beach
|
||
|
const beachTiles = islandTiles.filter((pos) => islands.data[pos] == BEACH);
|
||
|
islands.dropWithin(beachTiles);
|
||
|
|
||
|
// expand forest
|
||
|
const forestLobe = islands.floodSearch(basePos, (tile) => tile > BEACH);
|
||
|
const forestTiles = forestLobe.filter(
|
||
|
(pos) => islands.data[pos] == LIGHT_FOREST
|
||
|
);
|
||
|
islands.dropWithin(forestTiles);
|
||
|
islands.dropWithin(forestTiles);
|
||
|
islands.dropWithin(forestTiles);
|
||
|
|
||
|
return true;
|
||
|
};
|
||
|
|
||
|
/** form low-lying beach with eroded sections */
|
||
|
export const ERODED_LOBE: LobeGeneratorConstructor =
|
||
|
(islands: IslandGrid, basePos: number) => () => {
|
||
|
const islandTiles = islands.floodSearch(basePos, (tile) => tile > WATER);
|
||
|
|
||
|
const shoreTiles = islandTiles.filter((pos) => islands.data[pos] == WATER);
|
||
|
islands.dropWithin(shoreTiles);
|
||
|
|
||
|
// erode
|
||
|
if (islandTiles.length > 1) {
|
||
|
const erodePos = islandTiles[islands.rng() % islandTiles.length];
|
||
|
islands.data[erodePos] = Math.max(islands.data[erodePos] - 1, WATER);
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
};
|