Tree generation
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import { CHUNK_AREA, CHUNK_HEIGHT, CHUNK_SIZE, SEA_LEVEL } from "$/common/constants.ts";
|
||||
import { OctaveNoise2D } from "./noise.ts";
|
||||
import { OverworldTerrain, TerrainColumn } from "./terrain.ts";
|
||||
import { BIOME_TREES, grow_tree, tree_sites } from "./trees.ts";
|
||||
|
||||
// density is sampled every CELL_WIDTH blocks across and CELL_HEIGHT up, caves every CAVE_CELL_HEIGHT up since
|
||||
// tunnels are thinner than terrain features
|
||||
@@ -28,6 +29,8 @@ export interface OverworldBlocks {
|
||||
sand: number;
|
||||
snow: number;
|
||||
water: number;
|
||||
log: number;
|
||||
leaves: number;
|
||||
}
|
||||
|
||||
type Palette = "stone" | "dirt" | "grass" | "sand" | "snow";
|
||||
@@ -183,7 +186,8 @@ function generators_for(seed: string): SeedGenerators {
|
||||
return found;
|
||||
}
|
||||
|
||||
// fills blocks (indexed y * CHUNK_AREA + z * CHUNK_SIZE + x) and each column's surface height and biome
|
||||
// fills blocks (indexed y * CHUNK_AREA + z * CHUNK_SIZE + x) and each column's surface height and biome.
|
||||
// blocks trees put in other chunks go to spill
|
||||
export function generate_overworld(
|
||||
blocks: Uint32Array,
|
||||
heights: Int32Array,
|
||||
@@ -192,6 +196,7 @@ export function generate_overworld(
|
||||
chunk_z: number,
|
||||
seed: string,
|
||||
ids: OverworldBlocks,
|
||||
spill: (x: number, y: number, z: number, block: number) => void,
|
||||
) {
|
||||
const { terrain, snow_line, strata } = generators_for(seed);
|
||||
const x0 = chunk_x * CHUNK_SIZE;
|
||||
@@ -236,6 +241,40 @@ export function generate_overworld(
|
||||
fill_column(x, z);
|
||||
}
|
||||
}
|
||||
grow_trees();
|
||||
|
||||
function grow_trees() {
|
||||
const place = (x: number, y: number, z: number, block: "log" | "leaves") => {
|
||||
if (y < 0 || y >= CHUNK_HEIGHT) return;
|
||||
const lx = x - x0;
|
||||
const lz = z - z0;
|
||||
if (lx < 0 || lx >= CHUNK_SIZE || lz < 0 || lz >= CHUNK_SIZE) {
|
||||
// the other chunk only takes it where it has air
|
||||
spill(x, y, z, ids[block]);
|
||||
return;
|
||||
}
|
||||
const i = y * CHUNK_AREA + lz * CHUNK_SIZE + lx;
|
||||
const current = blocks[i];
|
||||
if (current === 0 || (block === "log" && current === ids.leaves)) {
|
||||
blocks[i] = ids[block];
|
||||
}
|
||||
};
|
||||
|
||||
for (const site of tree_sites(seed, chunk_x, chunk_z)) {
|
||||
const column = (site.z - z0) * CHUNK_SIZE + (site.x - x0);
|
||||
const trees = BIOME_TREES[biomes[column]];
|
||||
if (!trees || site.rng.next() >= trees.chance) continue;
|
||||
|
||||
// on soil with air above it, so never under water or on bare rock
|
||||
const ground_y = heights[column];
|
||||
const ground = blocks[ground_y * CHUNK_AREA + column];
|
||||
const above = blocks[(ground_y + 1) * CHUNK_AREA + column];
|
||||
if ((ground !== ids.grass && ground !== ids.dirt && ground !== ids.snow) || above !== 0) continue;
|
||||
|
||||
const kind = trees.kinds[Math.floor(site.rng.next() * trees.kinds.length)];
|
||||
grow_tree(kind, site.x, ground_y + 1, site.z, site.rng, place);
|
||||
}
|
||||
}
|
||||
|
||||
function fill_column(x: number, z: number) {
|
||||
const cell_x = Math.min(Math.floor(x / CELL_WIDTH), CORNERS - 2);
|
||||
|
||||
Reference in New Issue
Block a user