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;
|
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 BIG_ISLANDS = [BIG_MOUNTAIN, BIG_BEACH, HILLY_FOREST];
|
||||||
export const ROCKY_ISLANDS = [SMALL_MOUNTAIN, BIG_MOUNTAIN, HILLY_FOREST];
|
export const ROCKY_ISLANDS = [SMALL_MOUNTAIN, BIG_MOUNTAIN, HILLY_FOREST];
|
||||||
export const GREEN_ISLANDS = [
|
export const GREEN_ISLANDS = [
|
||||||
|
@ -186,3 +230,4 @@ export const ALL_ISLANDS = [
|
||||||
HILLY_FOREST,
|
HILLY_FOREST,
|
||||||
ERODED_BEACH,
|
ERODED_BEACH,
|
||||||
];
|
];
|
||||||
|
export const VOIDS = [NO_ISLAND, SINKHOLE, WIDE_SINKHOLE];
|
||||||
|
|
|
@ -7,7 +7,9 @@ import {
|
||||||
LobeGenerator,
|
LobeGenerator,
|
||||||
NO_ISLAND,
|
NO_ISLAND,
|
||||||
ROCKY_ISLANDS,
|
ROCKY_ISLANDS,
|
||||||
|
SINKHOLE,
|
||||||
SMALL_ISLANDS,
|
SMALL_ISLANDS,
|
||||||
|
VOIDS,
|
||||||
} from "./generators";
|
} from "./generators";
|
||||||
|
|
||||||
export class IslandGrid {
|
export class IslandGrid {
|
||||||
|
@ -30,10 +32,10 @@ export class IslandGrid {
|
||||||
this.choose(SMALL_ISLANDS),
|
this.choose(SMALL_ISLANDS),
|
||||||
this.choose(ALL_ISLANDS),
|
this.choose(ALL_ISLANDS),
|
||||||
this.choose(ALL_ISLANDS),
|
this.choose(ALL_ISLANDS),
|
||||||
NO_ISLAND,
|
this.choose(VOIDS),
|
||||||
NO_ISLAND,
|
this.choose(VOIDS),
|
||||||
NO_ISLAND,
|
this.choose(VOIDS),
|
||||||
NO_ISLAND,
|
this.choose(VOIDS),
|
||||||
NO_ISLAND,
|
NO_ISLAND,
|
||||||
NO_ISLAND,
|
NO_ISLAND,
|
||||||
]);
|
]);
|
||||||
|
@ -126,10 +128,36 @@ export class IslandGrid {
|
||||||
}
|
}
|
||||||
|
|
||||||
// flat, increase elevation
|
// flat, increase elevation
|
||||||
const newValue = ++this.data[pos];
|
++this.data[pos];
|
||||||
if (newValue == ICECAP) {
|
}
|
||||||
this.done = true;
|
|
||||||
|
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[]) {
|
public choose<T>(list: T[]) {
|
||||||
|
|
|
@ -9,6 +9,11 @@ export function renderIslands(
|
||||||
for (let x = 0; x < islands.width; x++) {
|
for (let x = 0; x < islands.width; x++) {
|
||||||
const tile = islands.data[islands.xy(x, y)];
|
const tile = islands.data[islands.xy(x, y)];
|
||||||
switch (tile) {
|
switch (tile) {
|
||||||
|
case -3:
|
||||||
|
case -2:
|
||||||
|
case -1:
|
||||||
|
cx.fillStyle = "#000088";
|
||||||
|
break;
|
||||||
case WATER:
|
case WATER:
|
||||||
cx.fillStyle = "blue";
|
cx.fillStyle = "blue";
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue