impl sinkholes
This commit is contained in:
parent
d44076b32c
commit
dc8fc5ef87
3 changed files with 85 additions and 7 deletions
|
@ -168,6 +168,50 @@ export const NO_ISLAND: LobeGeneratorConstructor =
|
|||
return true;
|
||||
};
|
||||
|
||||
const SINKHOLE_BURNOUT = 1500;
|
||||
|
||||
/** carve out elevation */
|
||||
export const SINKHOLE: LobeGeneratorConstructor = (
|
||||
islands: IslandGrid,
|
||||
basePos: number
|
||||
) => {
|
||||
// emergency cutoff in case sinkhole ends up fighting a generator that terminates at a given elevation
|
||||
let ticks = 0;
|
||||
return () => {
|
||||
if (ticks++ < SINKHOLE_BURNOUT) {
|
||||
const sunk = islands.floodSearch(basePos, (tile) => tile < 0);
|
||||
|
||||
islands.sinkhole(islands.choose(sunk));
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
||||
/** carve out elevation more aggressively */
|
||||
export const WIDE_SINKHOLE: LobeGeneratorConstructor = (
|
||||
islands: IslandGrid,
|
||||
basePos: number
|
||||
) => {
|
||||
// emergency cutoff in case sinkhole ends up fighting a generator that terminates at a given elevation
|
||||
let ticks = 0;
|
||||
return () => {
|
||||
if (ticks++ < SINKHOLE_BURNOUT) {
|
||||
const sunk = islands.floodSearch(basePos, (tile) => tile < 0);
|
||||
|
||||
const sunkEdge = sunk.filter((pos) => islands.data[pos] >= WATER);
|
||||
|
||||
if (sunkEdge.length > 0) {
|
||||
islands.sinkhole(islands.choose(sunkEdge));
|
||||
} else {
|
||||
islands.sinkhole(islands.choose(sunk));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
||||
export const BIG_ISLANDS = [BIG_MOUNTAIN, BIG_BEACH, HILLY_FOREST];
|
||||
export const ROCKY_ISLANDS = [SMALL_MOUNTAIN, BIG_MOUNTAIN, HILLY_FOREST];
|
||||
export const GREEN_ISLANDS = [
|
||||
|
@ -186,3 +230,4 @@ export const ALL_ISLANDS = [
|
|||
HILLY_FOREST,
|
||||
ERODED_BEACH,
|
||||
];
|
||||
export const VOIDS = [NO_ISLAND, SINKHOLE, WIDE_SINKHOLE];
|
||||
|
|
|
@ -7,7 +7,9 @@ import {
|
|||
LobeGenerator,
|
||||
NO_ISLAND,
|
||||
ROCKY_ISLANDS,
|
||||
SINKHOLE,
|
||||
SMALL_ISLANDS,
|
||||
VOIDS,
|
||||
} from "./generators";
|
||||
|
||||
export class IslandGrid {
|
||||
|
@ -30,10 +32,10 @@ export class IslandGrid {
|
|||
this.choose(SMALL_ISLANDS),
|
||||
this.choose(ALL_ISLANDS),
|
||||
this.choose(ALL_ISLANDS),
|
||||
NO_ISLAND,
|
||||
NO_ISLAND,
|
||||
NO_ISLAND,
|
||||
NO_ISLAND,
|
||||
this.choose(VOIDS),
|
||||
this.choose(VOIDS),
|
||||
this.choose(VOIDS),
|
||||
this.choose(VOIDS),
|
||||
NO_ISLAND,
|
||||
NO_ISLAND,
|
||||
]);
|
||||
|
@ -126,10 +128,36 @@ export class IslandGrid {
|
|||
}
|
||||
|
||||
// flat, increase elevation
|
||||
const newValue = ++this.data[pos];
|
||||
if (newValue == ICECAP) {
|
||||
this.done = true;
|
||||
++this.data[pos];
|
||||
}
|
||||
|
||||
public sinkhole(pos: number): void {
|
||||
const higherNeighbors: number[] = [];
|
||||
|
||||
const check = (adjPos: number) => {
|
||||
if (this.data[adjPos] > this.data[pos]) {
|
||||
higherNeighbors.push(adjPos);
|
||||
}
|
||||
};
|
||||
|
||||
// try to pull from neighbors
|
||||
|
||||
check((pos - this.width - 1) % this.data.length);
|
||||
check((pos - this.width) % this.data.length);
|
||||
check((pos - this.width + 1) % this.data.length);
|
||||
check((pos - 1) % this.data.length);
|
||||
check((pos + 1) % this.data.length);
|
||||
check((pos + this.width - 1) % this.data.length);
|
||||
check((pos + this.width) % this.data.length);
|
||||
check((pos + this.width + 1) % this.data.length);
|
||||
|
||||
if (higherNeighbors.length > 0) {
|
||||
const uphill = higherNeighbors[this.rng() % higherNeighbors.length];
|
||||
return this.sinkhole(uphill);
|
||||
}
|
||||
|
||||
// flat, decrease elevation
|
||||
this.data[pos] = Math.max(this.data[pos] - 1, -3);
|
||||
}
|
||||
|
||||
public choose<T>(list: T[]) {
|
||||
|
|
|
@ -9,6 +9,11 @@ export function renderIslands(
|
|||
for (let x = 0; x < islands.width; x++) {
|
||||
const tile = islands.data[islands.xy(x, y)];
|
||||
switch (tile) {
|
||||
case -3:
|
||||
case -2:
|
||||
case -1:
|
||||
cx.fillStyle = "#000088";
|
||||
break;
|
||||
case WATER:
|
||||
cx.fillStyle = "blue";
|
||||
break;
|
||||
|
|
Loading…
Add table
Reference in a new issue