Compare commits
18 Commits
7f10f3536a
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a06f34d99 | ||
|
|
e2436f6e24 | ||
|
|
afbf333622 | ||
|
|
acd5eaa52f | ||
|
|
84a0435312 | ||
|
|
46f1d24e9d | ||
|
|
aed76c3b1b | ||
|
|
95bd106a3b | ||
|
|
127e706bcb | ||
|
|
335b35d416 | ||
|
|
d0f3c9a048 | ||
|
|
f93ebff0b9 | ||
|
|
17c9634c0f | ||
|
|
32d2b09b9f | ||
|
|
f423c046ac | ||
|
|
1addbada63 | ||
|
|
d5fd7e6bb5 | ||
|
|
7861ab63f0 |
20
README.md
20
README.md
@@ -64,6 +64,7 @@ Useful options:
|
|||||||
- `--sea-level L`: sea level, default `70`.
|
- `--sea-level L`: sea level, default `70`.
|
||||||
- `--snow-line H`: snow threshold, default `sea-level + 38`.
|
- `--snow-line H`: snow threshold, default `sea-level + 38`.
|
||||||
- `--trails`: enable trail and cabin prepass.
|
- `--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.
|
- `--format mca|bin`: write Minecraft region files or raw debug chunks.
|
||||||
- `--out DIR`: output directory.
|
- `--out DIR`: output directory.
|
||||||
|
|
||||||
@@ -73,11 +74,30 @@ Features
|
|||||||
- Redwoods are enabled automatically. The biome classifier marks high-rainfall,
|
- Redwoods are enabled automatically. The biome classifier marks high-rainfall,
|
||||||
higher-relief areas as redwood forest, then places titan trees, dirt/mulch
|
higher-relief areas as redwood forest, then places titan trees, dirt/mulch
|
||||||
floor cover, tall grass, and occasional fallen logs.
|
floor cover, tall grass, and occasional fallen logs.
|
||||||
|
- General forests grow as broad, coherent oak, maple, birch, pine, spruce,
|
||||||
|
walnut, and cypress stands with occasional companion species. Seeded
|
||||||
|
clearings, sparse field trees, regenerating edges, mature interiors, variable
|
||||||
|
tree height, and irregular crown spacing keep the distribution from resolving
|
||||||
|
into a uniform grid.
|
||||||
- Cabins are enabled automatically. With `--trails`, cabins only try to spawn on
|
- Cabins are enabled automatically. With `--trails`, cabins only try to spawn on
|
||||||
chunks crossed by the trail network so their spur paths can connect to roads.
|
chunks crossed by the trail network so their spur paths can connect to roads.
|
||||||
Without `--trails`, cabins can still spawn, but they are rarer and unconnected.
|
Without `--trails`, cabins can still spawn, but they are rarer and unconnected.
|
||||||
|
- Cabin generation includes compact homesteads, longhouses, two-story houses,
|
||||||
|
L-shaped cabins, cross-gabled lodges, mixed-height tower lodges, and rambling
|
||||||
|
multi-wing cabins. Roof direction, wing height, material palette, windows,
|
||||||
|
porches, chimneys, decay, and path width vary by design.
|
||||||
|
- Seeded woodland-community regions raise the local cabin frequency and give
|
||||||
|
their roads permission to bridge narrowly bounded water at exact sea level.
|
||||||
|
Eligible crossings must have nearby dry banks on both sides; deep water,
|
||||||
|
broad lakes, and open ocean remain impassable. Bridges use raised spruce
|
||||||
|
decks, timber supports, and intermittent edge posts rather than gravel fill.
|
||||||
- Trails are optional because they need a prepass over the target area. Use
|
- Trails are optional because they need a prepass over the target area. Use
|
||||||
`--trails` when you want roads and better-connected cabins.
|
`--trails` when you want roads and better-connected cabins.
|
||||||
|
- Long roads search a broad terrain corridor and prefer valley floors, gentle
|
||||||
|
contour-following grades, low ridge crossings, and stable side slopes. Deep
|
||||||
|
water remains impassable; shallow water is crossed only when the detour cost
|
||||||
|
is greater, keeping fords and causeways short. Short cabin spurs use looser
|
||||||
|
engineering constraints so they can still reach the main network.
|
||||||
|
|
||||||
Minecraft Version
|
Minecraft Version
|
||||||
-----------------
|
-----------------
|
||||||
|
|||||||
Binary file not shown.
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#define CHUNK_SIZE 16
|
#define CHUNK_SIZE 16
|
||||||
#define CHUNK_HEIGHT 256
|
#define CHUNK_HEIGHT 256
|
||||||
|
#define WORLDGEN_HEIGHT_CACHE_SIZE 32768
|
||||||
|
|
||||||
enum BlockId {
|
enum BlockId {
|
||||||
BLOCK_BEDROCK = 0,
|
BLOCK_BEDROCK = 0,
|
||||||
@@ -52,7 +53,27 @@
|
|||||||
BLOCK_LADDER_N = 40,
|
BLOCK_LADDER_N = 40,
|
||||||
BLOCK_LADDER_S = 41,
|
BLOCK_LADDER_S = 41,
|
||||||
BLOCK_LADDER_W = 42,
|
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,
|
||||||
|
BLOCK_STONE_BRICK_STAIRS_E = 48,
|
||||||
|
BLOCK_STONE_BRICK_STAIRS_W = 49,
|
||||||
|
BLOCK_STONE_BRICK_STAIRS_N = 50,
|
||||||
|
BLOCK_STONE_BRICK_STAIRS_S = 51,
|
||||||
|
BLOCK_DANDELION = 52,
|
||||||
|
BLOCK_AZURE_BLUET = 53,
|
||||||
|
BLOCK_OXEYE_DAISY = 54,
|
||||||
|
BLOCK_CORNFLOWER = 55,
|
||||||
|
BLOCK_LILY_OF_THE_VALLEY = 56,
|
||||||
|
BLOCK_FERN = 57,
|
||||||
|
BLOCK_CLAY = 58,
|
||||||
|
BLOCK_SEAGRASS = 59,
|
||||||
|
BLOCK_IRON_BARS_NS = 60,
|
||||||
|
BLOCK_IRON_BARS_EW = 61,
|
||||||
|
BLOCK_SPRUCE_STAIRS_N = 62,
|
||||||
|
BLOCK_SPRUCE_STAIRS_S = 63
|
||||||
};
|
};
|
||||||
|
|
||||||
struct trail_segment;
|
struct trail_segment;
|
||||||
@@ -64,17 +85,27 @@ typedef struct {
|
|||||||
uint16_t blocks[CHUNK_HEIGHT][CHUNK_SIZE][CHUNK_SIZE];
|
uint16_t blocks[CHUNK_HEIGHT][CHUNK_SIZE][CHUNK_SIZE];
|
||||||
} chunk_data;
|
} chunk_data;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int x;
|
||||||
|
int z;
|
||||||
|
int value;
|
||||||
|
uint8_t valid;
|
||||||
|
} worldgen_height_cache_entry;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
simplex_noise noise;
|
simplex_noise noise;
|
||||||
int sea_level;
|
int sea_level;
|
||||||
int world_seed;
|
int world_seed;
|
||||||
int enable_trails;
|
int enable_trails;
|
||||||
|
int enable_wall;
|
||||||
|
int wall_min_x, wall_max_x, wall_min_z, wall_max_z;
|
||||||
int snow_line;
|
int snow_line;
|
||||||
struct trail_segment *trail_segments;
|
struct trail_segment *trail_segments;
|
||||||
size_t trail_segment_count;
|
size_t trail_segment_count;
|
||||||
size_t trail_segment_cap;
|
size_t trail_segment_cap;
|
||||||
int prepass_done;
|
int prepass_done;
|
||||||
int prepass_min_x, prepass_max_x, prepass_min_z, prepass_max_z;
|
int prepass_min_x, prepass_max_x, prepass_min_z, prepass_max_z;
|
||||||
|
worldgen_height_cache_entry height_cache[WORLDGEN_HEIGHT_CACHE_SIZE];
|
||||||
} worldgen_ctx;
|
} worldgen_ctx;
|
||||||
|
|
||||||
void worldgen_init(worldgen_ctx *ctx, int world_seed, int sea_level, int snow_line);
|
void worldgen_init(worldgen_ctx *ctx, int world_seed, int sea_level, int snow_line);
|
||||||
@@ -83,5 +114,7 @@ void worldgen_prepass(worldgen_ctx *ctx, int min_x, int max_x, int min_z, int ma
|
|||||||
void worldgen_free_trails(worldgen_ctx *ctx);
|
void worldgen_free_trails(worldgen_ctx *ctx);
|
||||||
int worldgen_debug_biome(worldgen_ctx *ctx, int x, int z);
|
int worldgen_debug_biome(worldgen_ctx *ctx, int x, int z);
|
||||||
double worldgen_debug_redwood_mask(worldgen_ctx *ctx, int x, int z);
|
double worldgen_debug_redwood_mask(worldgen_ctx *ctx, int x, int z);
|
||||||
|
double worldgen_debug_community_strength(worldgen_ctx *ctx, int x, int z);
|
||||||
|
int worldgen_debug_bridge_site(worldgen_ctx *ctx, int x, int z, int dir_x, int dir_z);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ typedef struct {
|
|||||||
int snow_line;
|
int snow_line;
|
||||||
pthread_mutex_t *log_mu;
|
pthread_mutex_t *log_mu;
|
||||||
int enable_trails;
|
int enable_trails;
|
||||||
|
int enable_wall;
|
||||||
|
int wall_min_x, wall_max_x, wall_min_z, wall_max_z;
|
||||||
results_buffer *results;
|
results_buffer *results;
|
||||||
struct trail_segment *trail_segments;
|
struct trail_segment *trail_segments;
|
||||||
size_t trail_segment_count;
|
size_t trail_segment_count;
|
||||||
@@ -84,6 +86,8 @@ static const kv_pair PROPS_WATER[] = {{"level", "0"}};
|
|||||||
static const kv_pair PROPS_LEAVES[] = {{"distance", "1"}, {"persistent", "false"}};
|
static const kv_pair PROPS_LEAVES[] = {{"distance", "1"}, {"persistent", "false"}};
|
||||||
static const kv_pair PROPS_STAIRS_E[] = {{"facing", "east"}, {"half", "bottom"}, {"shape", "straight"}, {"waterlogged", "false"}};
|
static const kv_pair PROPS_STAIRS_E[] = {{"facing", "east"}, {"half", "bottom"}, {"shape", "straight"}, {"waterlogged", "false"}};
|
||||||
static const kv_pair PROPS_STAIRS_W[] = {{"facing", "west"}, {"half", "bottom"}, {"shape", "straight"}, {"waterlogged", "false"}};
|
static const kv_pair PROPS_STAIRS_W[] = {{"facing", "west"}, {"half", "bottom"}, {"shape", "straight"}, {"waterlogged", "false"}};
|
||||||
|
static const kv_pair PROPS_STAIRS_N[] = {{"facing", "north"}, {"half", "bottom"}, {"shape", "straight"}, {"waterlogged", "false"}};
|
||||||
|
static const kv_pair PROPS_STAIRS_S[] = {{"facing", "south"}, {"half", "bottom"}, {"shape", "straight"}, {"waterlogged", "false"}};
|
||||||
static const kv_pair PROPS_DOOR_S_LOWER[] = {{"facing", "south"}, {"half", "lower"}, {"hinge", "left"}, {"open", "false"}, {"powered", "false"}};
|
static const kv_pair PROPS_DOOR_S_LOWER[] = {{"facing", "south"}, {"half", "lower"}, {"hinge", "left"}, {"open", "false"}, {"powered", "false"}};
|
||||||
static const kv_pair PROPS_DOOR_S_UPPER[] = {{"facing", "south"}, {"half", "upper"}, {"hinge", "left"}, {"open", "false"}, {"powered", "false"}};
|
static const kv_pair PROPS_DOOR_S_UPPER[] = {{"facing", "south"}, {"half", "upper"}, {"hinge", "left"}, {"open", "false"}, {"powered", "false"}};
|
||||||
static const kv_pair PROPS_DOOR_N_LOWER[] = {{"facing", "north"}, {"half", "lower"}, {"hinge", "left"}, {"open", "false"}, {"powered", "false"}};
|
static const kv_pair PROPS_DOOR_N_LOWER[] = {{"facing", "north"}, {"half", "lower"}, {"hinge", "left"}, {"open", "false"}, {"powered", "false"}};
|
||||||
@@ -96,6 +100,8 @@ static const kv_pair PROPS_LADDER_N[] = {{"facing", "north"}, {"waterlogged", "f
|
|||||||
static const kv_pair PROPS_LADDER_S[] = {{"facing", "south"}, {"waterlogged", "false"}};
|
static const kv_pair PROPS_LADDER_S[] = {{"facing", "south"}, {"waterlogged", "false"}};
|
||||||
static const kv_pair PROPS_LADDER_W[] = {{"facing", "west"}, {"waterlogged", "false"}};
|
static const kv_pair PROPS_LADDER_W[] = {{"facing", "west"}, {"waterlogged", "false"}};
|
||||||
static const kv_pair PROPS_LADDER_E[] = {{"facing", "east"}, {"waterlogged", "false"}};
|
static const kv_pair PROPS_LADDER_E[] = {{"facing", "east"}, {"waterlogged", "false"}};
|
||||||
|
static const kv_pair PROPS_IRON_BARS_NS[] = {{"east", "false"}, {"north", "true"}, {"south", "true"}, {"waterlogged", "false"}, {"west", "false"}};
|
||||||
|
static const kv_pair PROPS_IRON_BARS_EW[] = {{"east", "true"}, {"north", "false"}, {"south", "false"}, {"waterlogged", "false"}, {"west", "true"}};
|
||||||
static const size_t BLOCK_STATE_CAP = 256;
|
static const size_t BLOCK_STATE_CAP = 256;
|
||||||
static const int32_t DATA_VERSION = 2730; /* Java Edition 1.17.1; includes copper ore. */
|
static const int32_t DATA_VERSION = 2730; /* Java Edition 1.17.1; includes copper ore. */
|
||||||
static const block_state BLOCK_STATE_TABLE[] = {
|
static const block_state BLOCK_STATE_TABLE[] = {
|
||||||
@@ -142,7 +148,27 @@ static const block_state BLOCK_STATE_TABLE[] = {
|
|||||||
[BLOCK_LADDER_N] = {"minecraft:ladder", PROPS_LADDER_N, 2},
|
[BLOCK_LADDER_N] = {"minecraft:ladder", PROPS_LADDER_N, 2},
|
||||||
[BLOCK_LADDER_S] = {"minecraft:ladder", PROPS_LADDER_S, 2},
|
[BLOCK_LADDER_S] = {"minecraft:ladder", PROPS_LADDER_S, 2},
|
||||||
[BLOCK_LADDER_W] = {"minecraft:ladder", PROPS_LADDER_W, 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},
|
||||||
|
[BLOCK_STONE_BRICK_STAIRS_E] = {"minecraft:stone_brick_stairs", PROPS_STAIRS_E, 4},
|
||||||
|
[BLOCK_STONE_BRICK_STAIRS_W] = {"minecraft:stone_brick_stairs", PROPS_STAIRS_W, 4},
|
||||||
|
[BLOCK_STONE_BRICK_STAIRS_N] = {"minecraft:stone_brick_stairs", PROPS_STAIRS_N, 4},
|
||||||
|
[BLOCK_STONE_BRICK_STAIRS_S] = {"minecraft:stone_brick_stairs", PROPS_STAIRS_S, 4},
|
||||||
|
[BLOCK_DANDELION] = {"minecraft:dandelion", NULL, 0},
|
||||||
|
[BLOCK_AZURE_BLUET] = {"minecraft:azure_bluet", NULL, 0},
|
||||||
|
[BLOCK_OXEYE_DAISY] = {"minecraft:oxeye_daisy", NULL, 0},
|
||||||
|
[BLOCK_CORNFLOWER] = {"minecraft:cornflower", NULL, 0},
|
||||||
|
[BLOCK_LILY_OF_THE_VALLEY] = {"minecraft:lily_of_the_valley", NULL, 0},
|
||||||
|
[BLOCK_FERN] = {"minecraft:fern", NULL, 0},
|
||||||
|
[BLOCK_CLAY] = {"minecraft:clay", NULL, 0},
|
||||||
|
[BLOCK_SEAGRASS] = {"minecraft:seagrass", NULL, 0},
|
||||||
|
[BLOCK_IRON_BARS_NS] = {"minecraft:iron_bars", PROPS_IRON_BARS_NS, 5},
|
||||||
|
[BLOCK_IRON_BARS_EW] = {"minecraft:iron_bars", PROPS_IRON_BARS_EW, 5},
|
||||||
|
[BLOCK_SPRUCE_STAIRS_N] = {"minecraft:spruce_stairs", PROPS_STAIRS_N, 4},
|
||||||
|
[BLOCK_SPRUCE_STAIRS_S] = {"minecraft:spruce_stairs", PROPS_STAIRS_S, 4}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const block_state *get_block_state(uint16_t id) {
|
static const block_state *get_block_state(uint16_t id) {
|
||||||
@@ -296,18 +322,18 @@ static int64_t to_signed64(uint64_t v) {
|
|||||||
|
|
||||||
static void pack_bits(const uint16_t *indices, size_t count, int bits_per_value, int64_t *out_longs, size_t out_count) {
|
static void pack_bits(const uint16_t *indices, size_t count, int bits_per_value, int64_t *out_longs, size_t out_count) {
|
||||||
memset(out_longs, 0, out_count * sizeof(int64_t));
|
memset(out_longs, 0, out_count * sizeof(int64_t));
|
||||||
|
int values_per_long = 64 / bits_per_value;
|
||||||
|
if (values_per_long < 1) values_per_long = 1;
|
||||||
for (size_t idx = 0; idx < count; ++idx) {
|
for (size_t idx = 0; idx < count; ++idx) {
|
||||||
uint64_t value = indices[idx];
|
uint64_t value = indices[idx];
|
||||||
size_t bit_index = idx * (size_t)bits_per_value;
|
size_t long_id = idx / (size_t)values_per_long;
|
||||||
size_t long_id = bit_index / 64;
|
size_t offset = (idx % (size_t)values_per_long) * (size_t)bits_per_value;
|
||||||
size_t offset = bit_index % 64;
|
if (long_id >= out_count) continue;
|
||||||
uint64_t *target = (uint64_t *)&out_longs[long_id];
|
uint64_t *target = (uint64_t *)&out_longs[long_id];
|
||||||
*target |= value << offset;
|
*target |= value << offset;
|
||||||
int spill = (int)(offset + bits_per_value - 64);
|
}
|
||||||
if (spill > 0 && long_id + 1 < out_count) {
|
for (size_t i = 0; i < out_count; ++i) {
|
||||||
uint64_t *next = (uint64_t *)&out_longs[long_id + 1];
|
out_longs[i] = to_signed64((uint64_t)out_longs[i]);
|
||||||
*next |= value >> (bits_per_value - spill);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,6 +359,13 @@ static void pack_heightmap(const chunk_data *chunk, int64_t *out_longs, size_t o
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int column_contains_water(const chunk_data *chunk, int x, int z) {
|
||||||
|
for (int y = 1; y < CHUNK_HEIGHT; ++y) {
|
||||||
|
if (chunk->blocks[y][x][z] == BLOCK_WATER) return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int section_has_blocks(const chunk_data *chunk, int section_y) {
|
static int section_has_blocks(const chunk_data *chunk, int section_y) {
|
||||||
int y_base = section_y * 16;
|
int y_base = section_y * 16;
|
||||||
for (int y = 0; y < 16; ++y) {
|
for (int y = 0; y < 16; ++y) {
|
||||||
@@ -394,7 +427,9 @@ static void write_section(buf *b, const chunk_data *chunk, int section_y) {
|
|||||||
int needed = (int)ceil(log2((double)palette_len));
|
int needed = (int)ceil(log2((double)palette_len));
|
||||||
if (needed > bits) bits = needed;
|
if (needed > bits) bits = needed;
|
||||||
}
|
}
|
||||||
size_t packed_count = ((size_t)idx * (size_t)bits + 63) / 64;
|
size_t values_per_long = (size_t)(64 / bits);
|
||||||
|
if (values_per_long < 1) values_per_long = 1;
|
||||||
|
size_t packed_count = ((size_t)idx + values_per_long - 1) / values_per_long;
|
||||||
int64_t *packed = (int64_t *)calloc(packed_count, sizeof(int64_t));
|
int64_t *packed = (int64_t *)calloc(packed_count, sizeof(int64_t));
|
||||||
if (!packed) return;
|
if (!packed) return;
|
||||||
pack_bits(block_indices, idx, bits, packed, packed_count);
|
pack_bits(block_indices, idx, bits, packed, packed_count);
|
||||||
@@ -424,7 +459,11 @@ static void write_section(buf *b, const chunk_data *chunk, int section_y) {
|
|||||||
|
|
||||||
static void build_chunk_nbt(const chunk_data *chunk, buf *out) {
|
static void build_chunk_nbt(const chunk_data *chunk, buf *out) {
|
||||||
int32_t biomes[256];
|
int32_t biomes[256];
|
||||||
for (int i = 0; i < 256; ++i) biomes[i] = 1; // Plains biome
|
for (int z = 0; z < CHUNK_SIZE; ++z) {
|
||||||
|
for (int x = 0; x < CHUNK_SIZE; ++x) {
|
||||||
|
biomes[z * CHUNK_SIZE + x] = column_contains_water(chunk, x, z) ? 0 : 1; // Ocean or plains
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int64_t heightmap[37];
|
int64_t heightmap[37];
|
||||||
pack_heightmap(chunk, heightmap, 37);
|
pack_heightmap(chunk, heightmap, 37);
|
||||||
@@ -593,7 +632,7 @@ static void write_regions(const char *out_dir, region_accum *regions, size_t reg
|
|||||||
static void usage(const char *prog) {
|
static void usage(const char *prog) {
|
||||||
fprintf(stderr,
|
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"
|
"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);
|
prog);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -665,6 +704,11 @@ static void *worker_fn(void *ptr) {
|
|||||||
worldgen_ctx ctx;
|
worldgen_ctx ctx;
|
||||||
worldgen_init(&ctx, args->world_seed, args->sea_level, args->snow_line);
|
worldgen_init(&ctx, args->world_seed, args->sea_level, args->snow_line);
|
||||||
ctx.enable_trails = args->enable_trails;
|
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) {
|
if (args->trail_segments && args->trail_segment_count > 0) {
|
||||||
ctx.trail_segments = args->trail_segments;
|
ctx.trail_segments = args->trail_segments;
|
||||||
ctx.trail_segment_count = args->trail_segment_count;
|
ctx.trail_segment_count = args->trail_segment_count;
|
||||||
@@ -682,14 +726,12 @@ static void *worker_fn(void *ptr) {
|
|||||||
chunk_data chunk;
|
chunk_data chunk;
|
||||||
worldgen_generate_chunk(&ctx, job.x, job.z, &chunk);
|
worldgen_generate_chunk(&ctx, job.x, job.z, &chunk);
|
||||||
if (args->results) {
|
if (args->results) {
|
||||||
pthread_mutex_lock(&args->results->mutex);
|
|
||||||
size_t result_idx = atomic_fetch_add(&args->results->count, 1);
|
size_t result_idx = atomic_fetch_add(&args->results->count, 1);
|
||||||
if (result_idx < args->results->capacity) {
|
if (result_idx < args->results->capacity) {
|
||||||
args->results->chunks[result_idx].chunk_x = chunk.chunk_x;
|
args->results->chunks[result_idx].chunk_x = chunk.chunk_x;
|
||||||
args->results->chunks[result_idx].chunk_z = chunk.chunk_z;
|
args->results->chunks[result_idx].chunk_z = chunk.chunk_z;
|
||||||
memcpy(&args->results->chunks[result_idx].data, &chunk, sizeof(chunk_data));
|
memcpy(&args->results->chunks[result_idx].data, &chunk, sizeof(chunk_data));
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&args->results->mutex);
|
|
||||||
} else {
|
} else {
|
||||||
write_chunk_file(args->out_dir, &chunk);
|
write_chunk_file(args->out_dir, &chunk);
|
||||||
}
|
}
|
||||||
@@ -716,6 +758,7 @@ int main(int argc, char **argv) {
|
|||||||
int sea_level = 70;
|
int sea_level = 70;
|
||||||
int snow_line = INT_MIN;
|
int snow_line = INT_MIN;
|
||||||
int enable_trails = 0;
|
int enable_trails = 0;
|
||||||
|
int enable_wall = 0;
|
||||||
const char *out_dir = "output";
|
const char *out_dir = "output";
|
||||||
output_format format = FORMAT_MCA;
|
output_format format = FORMAT_MCA;
|
||||||
|
|
||||||
@@ -761,6 +804,8 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
} else if (strcmp(argv[i], "--trails") == 0) {
|
} else if (strcmp(argv[i], "--trails") == 0) {
|
||||||
enable_trails = 1;
|
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) {
|
} else if ((strcmp(argv[i], "--out") == 0 || strcmp(argv[i], "--output") == 0) && i + 1 < argc) {
|
||||||
out_dir = argv[++i];
|
out_dir = argv[++i];
|
||||||
} else if (strcmp(argv[i], "--help") == 0) {
|
} else if (strcmp(argv[i], "--help") == 0) {
|
||||||
@@ -791,6 +836,11 @@ int main(int argc, char **argv) {
|
|||||||
int world_max_x = max_x * CHUNK_SIZE + (CHUNK_SIZE - 1);
|
int world_max_x = max_x * CHUNK_SIZE + (CHUNK_SIZE - 1);
|
||||||
int world_min_z = min_z * CHUNK_SIZE;
|
int world_min_z = min_z * CHUNK_SIZE;
|
||||||
int world_max_z = max_z * CHUNK_SIZE + (CHUNK_SIZE - 1);
|
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) {
|
if (enable_trails) {
|
||||||
worldgen_prepass(&pre_ctx, world_min_x, world_max_x, world_min_z, world_max_z);
|
worldgen_prepass(&pre_ctx, world_min_x, world_max_x, world_min_z, world_max_z);
|
||||||
prepass_ready = 1;
|
prepass_ready = 1;
|
||||||
@@ -836,6 +886,11 @@ int main(int argc, char **argv) {
|
|||||||
.snow_line = snow_line,
|
.snow_line = snow_line,
|
||||||
.log_mu = &log_mu,
|
.log_mu = &log_mu,
|
||||||
.enable_trails = enable_trails,
|
.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,
|
.results = &results,
|
||||||
.trail_segments = prepass_ready ? pre_ctx.trail_segments : NULL,
|
.trail_segments = prepass_ready ? pre_ctx.trail_segments : NULL,
|
||||||
.trail_segment_count = prepass_ready ? pre_ctx.trail_segment_count : 0,
|
.trail_segment_count = prepass_ready ? pre_ctx.trail_segment_count : 0,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -10,6 +10,7 @@ static int is_cabin_block(uint16_t block) {
|
|||||||
block == BLOCK_OAK_LOG_X || block == BLOCK_OAK_LOG_Z ||
|
block == BLOCK_OAK_LOG_X || block == BLOCK_OAK_LOG_Z ||
|
||||||
block == BLOCK_SPRUCE_LOG_X || block == BLOCK_SPRUCE_LOG_Z ||
|
block == BLOCK_SPRUCE_LOG_X || block == BLOCK_SPRUCE_LOG_Z ||
|
||||||
block == BLOCK_GLASS_PANE || block == BLOCK_GLASS || block == BLOCK_SPRUCE_STAIRS_E || block == BLOCK_SPRUCE_STAIRS_W ||
|
block == BLOCK_GLASS_PANE || block == BLOCK_GLASS || block == BLOCK_SPRUCE_STAIRS_E || block == BLOCK_SPRUCE_STAIRS_W ||
|
||||||
|
block == BLOCK_SPRUCE_STAIRS_N || block == BLOCK_SPRUCE_STAIRS_S ||
|
||||||
block == BLOCK_LADDER_N || block == BLOCK_LADDER_S || block == BLOCK_LADDER_E || block == BLOCK_LADDER_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_N_LOWER || block == BLOCK_SPRUCE_DOOR_N_UPPER ||
|
||||||
block == BLOCK_SPRUCE_DOOR_S_LOWER || block == BLOCK_SPRUCE_DOOR_S_UPPER ||
|
block == BLOCK_SPRUCE_DOOR_S_LOWER || block == BLOCK_SPRUCE_DOOR_S_UPPER ||
|
||||||
@@ -78,6 +79,8 @@ int main(int argc, char **argv) {
|
|||||||
long cabin_columns = 0;
|
long cabin_columns = 0;
|
||||||
long gravel_columns = 0;
|
long gravel_columns = 0;
|
||||||
long cabin_gravel_columns = 0;
|
long cabin_gravel_columns = 0;
|
||||||
|
long bridge_deck_columns = 0;
|
||||||
|
long eligible_bridge_columns = 0;
|
||||||
long tall_log_columns = 0;
|
long tall_log_columns = 0;
|
||||||
long max_oak_log_run = 0;
|
long max_oak_log_run = 0;
|
||||||
long biome_columns[4] = {0, 0, 0, 0};
|
long biome_columns[4] = {0, 0, 0, 0};
|
||||||
@@ -96,8 +99,11 @@ int main(int argc, char **argv) {
|
|||||||
if (biome >= 0 && biome < 4) ++biome_columns[biome];
|
if (biome >= 0 && biome < 4) ++biome_columns[biome];
|
||||||
double redwood_mask = worldgen_debug_redwood_mask(&ctx, wx, wz);
|
double redwood_mask = worldgen_debug_redwood_mask(&ctx, wx, wz);
|
||||||
if (redwood_mask > max_redwood_mask) max_redwood_mask = redwood_mask;
|
if (redwood_mask > max_redwood_mask) max_redwood_mask = redwood_mask;
|
||||||
|
if (worldgen_debug_bridge_site(&ctx, wx, wz, 1, 0) ||
|
||||||
|
worldgen_debug_bridge_site(&ctx, wx, wz, 0, 1)) ++eligible_bridge_columns;
|
||||||
int has_cabin = 0;
|
int has_cabin = 0;
|
||||||
int has_gravel = 0;
|
int has_gravel = 0;
|
||||||
|
int has_bridge_deck = 0;
|
||||||
int current_run = 0;
|
int current_run = 0;
|
||||||
int best_run = 0;
|
int best_run = 0;
|
||||||
for (int y = 1; y < CHUNK_HEIGHT; ++y) {
|
for (int y = 1; y < CHUNK_HEIGHT; ++y) {
|
||||||
@@ -109,6 +115,8 @@ int main(int argc, char **argv) {
|
|||||||
if (block == BLOCK_GRAVEL) {
|
if (block == BLOCK_GRAVEL) {
|
||||||
has_gravel = 1;
|
has_gravel = 1;
|
||||||
}
|
}
|
||||||
|
if (block == BLOCK_SPRUCE_PLANKS && y > 1 && chunk.blocks[y - 1][lx][lz] == BLOCK_WATER)
|
||||||
|
has_bridge_deck = 1;
|
||||||
if (block == BLOCK_OAK_LOG) {
|
if (block == BLOCK_OAK_LOG) {
|
||||||
++current_run;
|
++current_run;
|
||||||
if (current_run > best_run) best_run = current_run;
|
if (current_run > best_run) best_run = current_run;
|
||||||
@@ -120,6 +128,7 @@ int main(int argc, char **argv) {
|
|||||||
if (best_run >= 40) ++tall_log_columns;
|
if (best_run >= 40) ++tall_log_columns;
|
||||||
if (has_cabin) ++cabin_columns;
|
if (has_cabin) ++cabin_columns;
|
||||||
if (has_gravel) ++gravel_columns;
|
if (has_gravel) ++gravel_columns;
|
||||||
|
if (has_bridge_deck) ++bridge_deck_columns;
|
||||||
if (has_cabin && has_gravel) {
|
if (has_cabin && has_gravel) {
|
||||||
++cabin_gravel_columns;
|
++cabin_gravel_columns;
|
||||||
}
|
}
|
||||||
@@ -133,6 +142,8 @@ int main(int argc, char **argv) {
|
|||||||
printf("cabin_columns=%ld\n", cabin_columns);
|
printf("cabin_columns=%ld\n", cabin_columns);
|
||||||
printf("gravel_columns=%ld\n", gravel_columns);
|
printf("gravel_columns=%ld\n", gravel_columns);
|
||||||
printf("cabin_gravel_columns=%ld\n", cabin_gravel_columns);
|
printf("cabin_gravel_columns=%ld\n", cabin_gravel_columns);
|
||||||
|
printf("bridge_deck_columns=%ld\n", bridge_deck_columns);
|
||||||
|
printf("eligible_bridge_columns=%ld\n", eligible_bridge_columns);
|
||||||
printf("tall_oak_log_columns=%ld\n", tall_log_columns);
|
printf("tall_oak_log_columns=%ld\n", tall_log_columns);
|
||||||
printf("max_oak_log_run=%ld\n", max_oak_log_run);
|
printf("max_oak_log_run=%ld\n", max_oak_log_run);
|
||||||
printf("biome_west_ky=%ld\n", biome_columns[0]);
|
printf("biome_west_ky=%ld\n", biome_columns[0]);
|
||||||
|
|||||||
Reference in New Issue
Block a user