From f423c046ac848c9afe2559d78c5e8eca2f5b5a7b Mon Sep 17 00:00:00 2001 From: chelsea Date: Sat, 2 May 2026 19:26:44 -0500 Subject: [PATCH] Add generated area border wall option --- worldgen-c/include/worldgen.h | 2 ++ worldgen-c/src/main.c | 22 +++++++++++++++- worldgen-c/src/worldgen.c | 47 +++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/worldgen-c/include/worldgen.h b/worldgen-c/include/worldgen.h index cc9d06e..b47f549 100644 --- a/worldgen-c/include/worldgen.h +++ b/worldgen-c/include/worldgen.h @@ -77,6 +77,8 @@ typedef struct { int sea_level; int world_seed; int enable_trails; + int enable_wall; + int wall_min_x, wall_max_x, wall_min_z, wall_max_z; int snow_line; struct trail_segment *trail_segments; size_t trail_segment_count; diff --git a/worldgen-c/src/main.c b/worldgen-c/src/main.c index 93985fa..8e294e5 100644 --- a/worldgen-c/src/main.c +++ b/worldgen-c/src/main.c @@ -51,6 +51,8 @@ typedef struct { int snow_line; pthread_mutex_t *log_mu; int enable_trails; + int enable_wall; + int wall_min_x, wall_max_x, wall_min_z, wall_max_z; results_buffer *results; struct trail_segment *trail_segments; size_t trail_segment_count; @@ -593,7 +595,7 @@ static void write_regions(const char *out_dir, region_accum *regions, size_t reg static void usage(const char *prog) { fprintf(stderr, "Usage: %s [--radius R] [--center-x X --center-z Z] [--min-x MX --max-x MX --min-z MZ --max-z MZ]\n" - " [--threads N] [--seed S] [--sea-level L] [--snow-line H] [--format mca|bin] [--trails] [--out DIR]\n", + " [--threads N] [--seed S] [--sea-level L] [--snow-line H] [--format mca|bin] [--trails] [--wall] [--out DIR]\n", prog); } @@ -665,6 +667,11 @@ static void *worker_fn(void *ptr) { worldgen_ctx ctx; worldgen_init(&ctx, args->world_seed, args->sea_level, args->snow_line); ctx.enable_trails = args->enable_trails; + ctx.enable_wall = args->enable_wall; + ctx.wall_min_x = args->wall_min_x; + ctx.wall_max_x = args->wall_max_x; + ctx.wall_min_z = args->wall_min_z; + ctx.wall_max_z = args->wall_max_z; if (args->trail_segments && args->trail_segment_count > 0) { ctx.trail_segments = args->trail_segments; ctx.trail_segment_count = args->trail_segment_count; @@ -714,6 +721,7 @@ int main(int argc, char **argv) { int sea_level = 70; int snow_line = INT_MIN; int enable_trails = 0; + int enable_wall = 0; const char *out_dir = "output"; output_format format = FORMAT_MCA; @@ -759,6 +767,8 @@ int main(int argc, char **argv) { } } else if (strcmp(argv[i], "--trails") == 0) { enable_trails = 1; + } else if (strcmp(argv[i], "--wall") == 0) { + enable_wall = 1; } else if ((strcmp(argv[i], "--out") == 0 || strcmp(argv[i], "--output") == 0) && i + 1 < argc) { out_dir = argv[++i]; } else if (strcmp(argv[i], "--help") == 0) { @@ -789,6 +799,11 @@ int main(int argc, char **argv) { int world_max_x = max_x * CHUNK_SIZE + (CHUNK_SIZE - 1); int world_min_z = min_z * CHUNK_SIZE; int world_max_z = max_z * CHUNK_SIZE + (CHUNK_SIZE - 1); + pre_ctx.enable_wall = enable_wall; + pre_ctx.wall_min_x = world_min_x; + pre_ctx.wall_max_x = world_max_x; + pre_ctx.wall_min_z = world_min_z; + pre_ctx.wall_max_z = world_max_z; if (enable_trails) { worldgen_prepass(&pre_ctx, world_min_x, world_max_x, world_min_z, world_max_z); prepass_ready = 1; @@ -834,6 +849,11 @@ int main(int argc, char **argv) { .snow_line = snow_line, .log_mu = &log_mu, .enable_trails = enable_trails, + .enable_wall = enable_wall, + .wall_min_x = world_min_x, + .wall_max_x = world_max_x, + .wall_min_z = world_min_z, + .wall_max_z = world_max_z, .results = &results, .trail_segments = prepass_ready ? pre_ctx.trail_segments : NULL, .trail_segment_count = prepass_ready ? pre_ctx.trail_segment_count : 0, diff --git a/worldgen-c/src/worldgen.c b/worldgen-c/src/worldgen.c index 3e68cd5..53c0f93 100644 --- a/worldgen-c/src/worldgen.c +++ b/worldgen-c/src/worldgen.c @@ -138,6 +138,7 @@ static void generate_chunk_redwood_floor(worldgen_ctx *ctx, int chunk_x, int chu static void generate_chunk_grass(worldgen_ctx *ctx, int chunk_x, int chunk_z, column_data columns[CHUNK_SIZE][CHUNK_SIZE], chunk_data *out); static void generate_chunk_flowers(worldgen_ctx *ctx, int chunk_x, int chunk_z, column_data columns[CHUNK_SIZE][CHUNK_SIZE], chunk_data *out); static void generate_chunk_cabins(worldgen_ctx *ctx, int chunk_x, int chunk_z, column_data columns[CHUNK_SIZE][CHUNK_SIZE], chunk_data *out); +static void generate_chunk_border_wall(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_data *out); static void ensure_trail_prepass(worldgen_ctx *ctx, int chunk_x, int chunk_z); static void append_trail_segment(worldgen_ctx *ctx, int ax, int az, int bx, int bz, int *points, int count); static int *smooth_trail_polyline(worldgen_ctx *ctx, int *points, int count, int *out_count); @@ -3553,6 +3554,47 @@ static void generate_chunk_trails(worldgen_ctx *ctx, int chunk_x, int chunk_z, c } } +static void generate_chunk_border_wall(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_data *out) { + if (!ctx->enable_wall) return; + if (ctx->wall_min_x > ctx->wall_max_x || ctx->wall_min_z > ctx->wall_max_z) return; + + const int wall_height = 9; + for (int dx = 0; dx < CHUNK_SIZE; ++dx) { + for (int dz = 0; dz < CHUNK_SIZE; ++dz) { + int world_x = chunk_x * CHUNK_SIZE + dx; + int world_z = chunk_z * CHUNK_SIZE + dz; + if (world_x < ctx->wall_min_x || world_x > ctx->wall_max_x) continue; + if (world_z < ctx->wall_min_z || world_z > ctx->wall_max_z) continue; + + int on_border = world_x == ctx->wall_min_x || world_x == ctx->wall_max_x || + world_z == ctx->wall_min_z || world_z == ctx->wall_max_z; + if (!on_border) continue; + + column_data data = get_column_data(ctx, world_x, world_z); + int visible_base = data.height; + if (data.has_water && data.water_surface > visible_base) { + visible_base = data.water_surface; + } + if (visible_base >= CHUNK_HEIGHT - 1) continue; + + int top = visible_base + wall_height; + if (top >= CHUNK_HEIGHT) top = CHUNK_HEIGHT - 1; + + for (int y = data.height + 1; y < CHUNK_HEIGHT; ++y) { + out->blocks[y][dx][dz] = BLOCK_AIR; + } + out->heightmap[dx][dz] = (uint16_t)data.height; + + int start = data.height + 1; + if (start < 1) start = 1; + for (int y = start; y <= top; ++y) { + uint16_t block = (y == top) ? BLOCK_OAK_PLANKS : BLOCK_STONE; + set_block_with_height(out, dx, dz, y, block); + } + } + } +} + // --------------------------------------------------------------------------- // Public API // --------------------------------------------------------------------------- @@ -3561,6 +3603,9 @@ void worldgen_init(worldgen_ctx *ctx, int world_seed, int sea_level, int snow_li ctx->sea_level = sea_level; ctx->snow_line = snow_line; ctx->enable_trails = 0; + ctx->enable_wall = 0; + ctx->wall_min_x = ctx->wall_max_x = 0; + ctx->wall_min_z = ctx->wall_max_z = 0; ctx->trail_segments = NULL; ctx->trail_segment_count = 0; ctx->trail_segment_cap = 0; @@ -3650,4 +3695,6 @@ void worldgen_generate_chunk(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_ } } block_list_free(&trees); + + generate_chunk_border_wall(ctx, chunk_x, chunk_z, out); }