diff --git a/README.md b/README.md index efba26d..80422b3 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ Useful options: - `--sea-level L`: sea level, default `70`. - `--snow-line H`: snow threshold, default `sea-level + 38`. - `--trails`: enable trail and cabin prepass. +- `--wall`: build a brutalist border wall around the generated area. - `--format mca|bin`: write Minecraft region files or raw debug chunks. - `--out DIR`: output directory. diff --git a/worldgen-c/bin/worldgen b/worldgen-c/bin/worldgen index 20868a8..1815d62 100755 Binary files a/worldgen-c/bin/worldgen and b/worldgen-c/bin/worldgen differ diff --git a/worldgen-c/include/worldgen.h b/worldgen-c/include/worldgen.h index b47f549..4ba75c2 100644 --- a/worldgen-c/include/worldgen.h +++ b/worldgen-c/include/worldgen.h @@ -53,7 +53,11 @@ BLOCK_LADDER_N = 40, BLOCK_LADDER_S = 41, BLOCK_LADDER_W = 42, - BLOCK_LADDER_E = 43 + BLOCK_LADDER_E = 43, + BLOCK_SMOOTH_STONE = 44, + BLOCK_STONE_BRICKS = 45, + BLOCK_BLACKSTONE = 46, + BLOCK_IRON_BARS = 47 }; struct trail_segment; diff --git a/worldgen-c/src/main.c b/worldgen-c/src/main.c index 8e294e5..e27a2a5 100644 --- a/worldgen-c/src/main.c +++ b/worldgen-c/src/main.c @@ -144,7 +144,11 @@ static const block_state BLOCK_STATE_TABLE[] = { [BLOCK_LADDER_N] = {"minecraft:ladder", PROPS_LADDER_N, 2}, [BLOCK_LADDER_S] = {"minecraft:ladder", PROPS_LADDER_S, 2}, [BLOCK_LADDER_W] = {"minecraft:ladder", PROPS_LADDER_W, 2}, - [BLOCK_LADDER_E] = {"minecraft:ladder", PROPS_LADDER_E, 2} + [BLOCK_LADDER_E] = {"minecraft:ladder", PROPS_LADDER_E, 2}, + [BLOCK_SMOOTH_STONE] = {"minecraft:smooth_stone", NULL, 0}, + [BLOCK_STONE_BRICKS] = {"minecraft:stone_bricks", NULL, 0}, + [BLOCK_BLACKSTONE] = {"minecraft:blackstone", NULL, 0}, + [BLOCK_IRON_BARS] = {"minecraft:iron_bars", NULL, 0} }; static const block_state *get_block_state(uint16_t id) { diff --git a/worldgen-c/src/worldgen.c b/worldgen-c/src/worldgen.c index 53c0f93..48b9d90 100644 --- a/worldgen-c/src/worldgen.c +++ b/worldgen-c/src/worldgen.c @@ -3558,7 +3558,12 @@ static void generate_chunk_border_wall(worldgen_ctx *ctx, int chunk_x, int chunk 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; + const int wall_depth = 4; + const int wall_height = 18; + const int tower_depth = 9; + const int tower_height = 28; + const int tower_spacing = 32; + const int tower_half_width = 4; for (int dx = 0; dx < CHUNK_SIZE; ++dx) { for (int dz = 0; dz < CHUNK_SIZE; ++dz) { int world_x = chunk_x * CHUNK_SIZE + dx; @@ -3566,9 +3571,34 @@ static void generate_chunk_border_wall(worldgen_ctx *ctx, int chunk_x, int chunk 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; + int dist_min_x = world_x - ctx->wall_min_x; + int dist_max_x = ctx->wall_max_x - world_x; + int dist_min_z = world_z - ctx->wall_min_z; + int dist_max_z = ctx->wall_max_z - world_z; + int side_dist = dist_min_x; + int along = world_z; + if (dist_max_x < side_dist) { + side_dist = dist_max_x; + along = world_z; + } + if (dist_min_z < side_dist) { + side_dist = dist_min_z; + along = world_x; + } + if (dist_max_z < side_dist) { + side_dist = dist_max_z; + along = world_x; + } + + int phase = along % tower_spacing; + if (phase < 0) phase += tower_spacing; + int tower_offset = phase; + if (tower_offset > tower_spacing / 2) tower_offset = tower_spacing - tower_offset; + int near_corner = (dist_min_x < tower_depth || dist_max_x < tower_depth) && + (dist_min_z < tower_depth || dist_max_z < tower_depth); + int in_tower = side_dist < tower_depth && (tower_offset <= tower_half_width || near_corner); + int in_wall = side_dist < wall_depth || in_tower; + if (!in_wall) continue; column_data data = get_column_data(ctx, world_x, world_z); int visible_base = data.height; @@ -3577,7 +3607,8 @@ static void generate_chunk_border_wall(worldgen_ctx *ctx, int chunk_x, int chunk } if (visible_base >= CHUNK_HEIGHT - 1) continue; - int top = visible_base + wall_height; + int height = in_tower ? tower_height : wall_height; + int top = visible_base + height; if (top >= CHUNK_HEIGHT) top = CHUNK_HEIGHT - 1; for (int y = data.height + 1; y < CHUNK_HEIGHT; ++y) { @@ -3585,12 +3616,28 @@ static void generate_chunk_border_wall(worldgen_ctx *ctx, int chunk_x, int chunk } out->heightmap[dx][dz] = (uint16_t)data.height; - int start = data.height + 1; + int start = data.height - 3; if (start < 1) start = 1; for (int y = start; y <= top; ++y) { - uint16_t block = (y == top) ? BLOCK_OAK_PLANKS : BLOCK_STONE; + int rel_y = y - visible_base; + uint16_t block = BLOCK_SMOOTH_STONE; + if (rel_y <= 2 || rel_y % 6 == 0 || rel_y == height - 1) { + block = BLOCK_STONE_BRICKS; + } + if (in_tower && side_dist == 0 && rel_y >= 9 && rel_y <= 17 && + (tower_offset == 0 || (rel_y == 13 && tower_offset <= 3))) { + block = BLOCK_BLACKSTONE; + } else if (in_tower && side_dist == 1 && tower_offset == 0 && rel_y >= 4 && rel_y <= 7) { + block = BLOCK_IRON_BARS; + } else if (!in_tower && side_dist == 0 && rel_y >= 7 && rel_y <= 10 && phase % 16 == 8) { + block = BLOCK_IRON_BARS; + } set_block_with_height(out, dx, dz, y, block); } + if (top + 1 < CHUNK_HEIGHT && (side_dist == 0 || side_dist == wall_depth - 1 || in_tower) && + phase % 4 < 2) { + set_block_with_height(out, dx, dz, top + 1, BLOCK_STONE_BRICKS); + } } } }