Update worldgen exporter features

This commit is contained in:
chelsea
2026-05-02 13:54:15 -05:00
parent 5bb1e05acf
commit 2f11a5b5fa
9 changed files with 320 additions and 27 deletions

View File

@@ -158,14 +158,19 @@ static column_data get_column_data(worldgen_ctx *ctx, int x, int z);
static int generate_coal(worldgen_ctx *ctx, int x, int y, int z, int column_height, biome_id biome);
static uint32_t hash_coords(int x, int z, uint32_t seed) {
uint32_t h = (uint32_t)(x * 374761393 + z * 668265263) ^ seed;
uint32_t ux = (uint32_t)x;
uint32_t uz = (uint32_t)z;
uint32_t h = (ux * 374761393u + uz * 668265263u) ^ seed;
h = (h ^ (h >> 13)) * 1274126177u;
return h ^ (h >> 16);
}
static uint32_t hash_coords3(int x, int y, int z, uint32_t seed) {
uint32_t h = (uint32_t)(x * 374761393 + y * 668265263 + z * 362827313) ^ seed;
h ^= (uint32_t)y * 0x9E3779B9u;
uint32_t ux = (uint32_t)x;
uint32_t uy = (uint32_t)y;
uint32_t uz = (uint32_t)z;
uint32_t h = (ux * 374761393u + uy * 668265263u + uz * 362827313u) ^ seed;
h ^= uy * 0x9E3779B9u;
h = (h ^ (h >> 13)) * 1274126177u;
return h ^ (h >> 16);
}
@@ -417,6 +422,18 @@ static void set_block_with_height(chunk_data *chunk, int local_x, int local_z, i
}
}
static int is_cabin_structure_block(uint16_t block) {
return block == BLOCK_SPRUCE_PLANKS || block == BLOCK_OAK_PLANKS ||
block == BLOCK_OAK_LOG_X || block == BLOCK_OAK_LOG_Z ||
block == BLOCK_SPRUCE_LOG_X || block == BLOCK_SPRUCE_LOG_Z ||
block == BLOCK_GLASS_PANE || block == BLOCK_SPRUCE_STAIRS_E || block == BLOCK_SPRUCE_STAIRS_W ||
block == BLOCK_LADDER_N || block == BLOCK_LADDER_S || block == BLOCK_LADDER_E || block == BLOCK_LADDER_W ||
block == BLOCK_SPRUCE_DOOR_N_LOWER || block == BLOCK_SPRUCE_DOOR_N_UPPER ||
block == BLOCK_SPRUCE_DOOR_S_LOWER || block == BLOCK_SPRUCE_DOOR_S_UPPER ||
block == BLOCK_SPRUCE_DOOR_E_LOWER || block == BLOCK_SPRUCE_DOOR_E_UPPER ||
block == BLOCK_SPRUCE_DOOR_W_LOWER || block == BLOCK_SPRUCE_DOOR_W_UPPER;
}
static double worley_distance(int x, int z, double scale, uint32_t seed) {
double px = x * scale;
double pz = z * scale;
@@ -527,16 +544,16 @@ static int local_relief(worldgen_ctx *ctx, int x, int z, int center_height) {
}
static biome_id classify_biome(worldgen_ctx *ctx, int x, int z, int column_height) {
int slope = local_relief(ctx, x, z, column_height);
double redwood = redwood_biome_mask(ctx, x, z, column_height, slope);
if (redwood > 0.18) {
return BIOME_REDWOOD_FOREST;
}
double old_growth = old_growth_plains_mask(ctx, x, z);
if (old_growth > 0.6) {
return BIOME_OLD_GROWTH_PLAINS;
}
double blend = region_blend(ctx, x, z);
int slope = local_relief(ctx, x, z, column_height);
double redwood = redwood_biome_mask(ctx, x, z, column_height, slope);
if (redwood > 0.62) {
return BIOME_REDWOOD_FOREST;
}
double slope_score = clamp01((double)slope / 10.0);
double relief = clamp01((double)(column_height - ctx->sea_level) / 45.0);
double jitter = simplex_noise2(&ctx->noise, (x - 17000) * 0.001, (z + 17000) * 0.001) * 0.1;
@@ -547,6 +564,15 @@ static biome_id classify_biome(worldgen_ctx *ctx, int x, int z, int column_heigh
return BIOME_WEST_KY_COALFIELDS;
}
int worldgen_debug_biome(worldgen_ctx *ctx, int x, int z) {
return (int)classify_biome(ctx, x, z, column_height(ctx, x, z));
}
double worldgen_debug_redwood_mask(worldgen_ctx *ctx, int x, int z) {
int height = column_height(ctx, x, z);
return redwood_biome_mask(ctx, x, z, height, local_relief(ctx, x, z, height));
}
static void block_list_init(block_list *list) {
list->items = NULL;
list->count = 0;
@@ -2049,6 +2075,14 @@ static void build_cabin_rect(worldgen_ctx *ctx, const cabin_blueprint *bp, const
}
}
}
for (int wz = z0; wz <= z1; ++wz) {
for (int wx = x0; wx <= x1; ++wx) {
int lx = wx - chunk_origin_x;
int lz = wz - chunk_origin_z;
if (lx < 0 || lx >= CHUNK_SIZE || lz < 0 || lz >= CHUNK_SIZE) continue;
set_block_with_height(chunk, lx, lz, base_floor_y, foundation_block);
}
}
int ladder_hole_x = INT_MIN;
int ladder_hole_z = INT_MIN;
@@ -2249,13 +2283,19 @@ static int try_place_cabin(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_da
if (rect_overlaps_mask(occupancy, chunk_origin_x, chunk_origin_z, x0, x1, z0, z1, 3)) {
return 0;
}
for (int wz = z0 - 2; wz <= z1 + 2; ++wz) {
for (int wx = x0 - 2; wx <= x1 + 2; ++wx) {
if (wx < chunk_origin_x || wx >= chunk_origin_x + CHUNK_SIZE) continue;
if (wz < chunk_origin_z || wz >= chunk_origin_z + CHUNK_SIZE) continue;
if (column_has_manmade_surface(chunk, chunk_x, chunk_z, wx, wz)) return 0;
}
}
for (int wz = z0; wz <= z1; ++wz) {
for (int wx = x0; wx <= x1; ++wx) {
int lx = wx - chunk_origin_x;
int lz = wz - chunk_origin_z;
column_data col = columns[lx][lz];
if (col.has_water && col.height < col.water_surface) return 0;
if (column_has_manmade_surface(chunk, chunk_x, chunk_z, wx, wz)) return 0;
if (col.height < min_h) min_h = col.height;
if (col.height > max_h) max_h = col.height;
}
@@ -2438,8 +2478,8 @@ static void connect_cabin_to_trail(worldgen_ctx *ctx, int chunk_x, int chunk_z,
int door_x, int door_z, int door_side, int path_width) {
int step_x = (door_side == 2) ? -1 : (door_side == 3) ? 1 : 0;
int step_z = (door_side == 0) ? -1 : (door_side == 1) ? 1 : 0;
int start_x = door_x + step_x;
int start_z = door_z + step_z;
int start_x = door_x + step_x * 3;
int start_z = door_z + step_z * 3;
int spur_len = 24;
if (path_width < 2) path_width = 2;
carve_cabin_path(ctx, chunk_x, chunk_z, chunk, columns, start_x, start_z, step_x, step_z, spur_len, path_width);
@@ -2568,20 +2608,9 @@ static int column_has_manmade_surface(chunk_data *chunk, int chunk_x, int chunk_
if (local_x < 0 || local_x >= CHUNK_SIZE || local_z < 0 || local_z >= CHUNK_SIZE) return 0;
for (int y = CHUNK_HEIGHT - 2; y >= 1; --y) {
uint16_t block = chunk->blocks[y][local_x][local_z];
if (block == BLOCK_AIR) continue;
if (block == BLOCK_WATER) return 0;
if (block == BLOCK_GRAVEL || block == BLOCK_SPRUCE_PLANKS || block == BLOCK_OAK_PLANKS ||
block == BLOCK_OAK_LOG_X || block == BLOCK_OAK_LOG_Z ||
block == BLOCK_SPRUCE_LOG_X || block == BLOCK_SPRUCE_LOG_Z ||
block == BLOCK_GLASS_PANE || block == BLOCK_SPRUCE_STAIRS_E || block == BLOCK_SPRUCE_STAIRS_W ||
block == BLOCK_LADDER_N || block == BLOCK_LADDER_S || block == BLOCK_LADDER_E || block == BLOCK_LADDER_W ||
block == BLOCK_SPRUCE_DOOR_N_LOWER || block == BLOCK_SPRUCE_DOOR_N_UPPER ||
block == BLOCK_SPRUCE_DOOR_S_LOWER || block == BLOCK_SPRUCE_DOOR_S_UPPER ||
block == BLOCK_SPRUCE_DOOR_E_LOWER || block == BLOCK_SPRUCE_DOOR_E_UPPER ||
block == BLOCK_SPRUCE_DOOR_W_LOWER || block == BLOCK_SPRUCE_DOOR_W_UPPER) {
if (block == BLOCK_GRAVEL || is_cabin_structure_block(block)) {
return 1;
}
return 0;
}
return 0;
}
@@ -3153,6 +3182,12 @@ static void place_trail_column(chunk_data *out, column_data columns[CHUNK_SIZE][
int original_height = columns[local_x][local_z].height;
if (original_height < 1) original_height = target_height;
for (int y = 1; y < CHUNK_HEIGHT; ++y) {
if (is_cabin_structure_block(out->blocks[y][local_x][local_z])) {
return;
}
}
for (int y = target_height - 1; y >= 1; --y) {
uint16_t block = out->blocks[y][local_x][local_z];
if (block == BLOCK_AIR || block == BLOCK_WATER) {