Add log cabin variants and fix palette
This commit is contained in:
@@ -74,10 +74,23 @@ typedef struct {
|
||||
} block_state;
|
||||
|
||||
static const kv_pair PROPS_LOG_AXIS[] = {{"axis", "y"}};
|
||||
static const kv_pair PROPS_LOG_AXIS_X[] = {{"axis", "x"}};
|
||||
static const kv_pair PROPS_LOG_AXIS_Z[] = {{"axis", "z"}};
|
||||
static const kv_pair PROPS_GRASS[] = {{"snowy", "false"}};
|
||||
static const kv_pair PROPS_WATER[] = {{"level", "0"}};
|
||||
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_W[] = {{"facing", "west"}, {"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_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_UPPER[] = {{"facing", "north"}, {"half", "upper"}, {"hinge", "left"}, {"open", "false"}, {"powered", "false"}};
|
||||
static const kv_pair PROPS_DOOR_W_LOWER[] = {{"facing", "west"}, {"half", "lower"}, {"hinge", "left"}, {"open", "false"}, {"powered", "false"}};
|
||||
static const kv_pair PROPS_DOOR_W_UPPER[] = {{"facing", "west"}, {"half", "upper"}, {"hinge", "left"}, {"open", "false"}, {"powered", "false"}};
|
||||
static const kv_pair PROPS_DOOR_E_LOWER[] = {{"facing", "east"}, {"half", "lower"}, {"hinge", "left"}, {"open", "false"}, {"powered", "false"}};
|
||||
static const kv_pair PROPS_DOOR_E_UPPER[] = {{"facing", "east"}, {"half", "upper"}, {"hinge", "left"}, {"open", "false"}, {"powered", "false"}};
|
||||
|
||||
static const size_t BLOCK_STATE_CAP = 256;
|
||||
static const block_state BLOCK_STATE_TABLE[] = {
|
||||
[BLOCK_BEDROCK] = {"minecraft:bedrock", NULL, 0},
|
||||
[BLOCK_STONE] = {"minecraft:stone", NULL, 0},
|
||||
@@ -94,7 +107,30 @@ static const block_state BLOCK_STATE_TABLE[] = {
|
||||
[BLOCK_GRAVEL] = {"minecraft:gravel", NULL, 0},
|
||||
[BLOCK_SNOW] = {"minecraft:snow", NULL, 0},
|
||||
[BLOCK_TALL_GRASS] = {"minecraft:grass", NULL, 0},
|
||||
[BLOCK_WILDFLOWER] = {"minecraft:poppy", NULL, 0}
|
||||
[BLOCK_WILDFLOWER] = {"minecraft:poppy", NULL, 0},
|
||||
[BLOCK_COPPER_ORE] = {"minecraft:copper_ore", NULL, 0},
|
||||
[BLOCK_IRON_ORE] = {"minecraft:iron_ore", NULL, 0},
|
||||
[BLOCK_GOLD_ORE] = {"minecraft:gold_ore", NULL, 0},
|
||||
[BLOCK_REDSTONE_ORE] = {"minecraft:redstone_ore", NULL, 0},
|
||||
[BLOCK_LAPIS_ORE] = {"minecraft:lapis_ore", NULL, 0},
|
||||
[BLOCK_DIAMOND_ORE] = {"minecraft:diamond_ore", NULL, 0},
|
||||
[BLOCK_OAK_PLANKS] = {"minecraft:oak_planks", NULL, 0},
|
||||
[BLOCK_SPRUCE_PLANKS] = {"minecraft:spruce_planks", NULL, 0},
|
||||
[BLOCK_OAK_LOG_X] = {"minecraft:oak_log", PROPS_LOG_AXIS_X, 1},
|
||||
[BLOCK_OAK_LOG_Z] = {"minecraft:oak_log", PROPS_LOG_AXIS_Z, 1},
|
||||
[BLOCK_SPRUCE_LOG_X] = {"minecraft:spruce_log", PROPS_LOG_AXIS_X, 1},
|
||||
[BLOCK_SPRUCE_LOG_Z] = {"minecraft:spruce_log", PROPS_LOG_AXIS_Z, 1},
|
||||
[BLOCK_GLASS_PANE] = {"minecraft:glass_pane", NULL, 0},
|
||||
[BLOCK_SPRUCE_DOOR_S_LOWER] = {"minecraft:spruce_door", PROPS_DOOR_S_LOWER, 5},
|
||||
[BLOCK_SPRUCE_DOOR_S_UPPER] = {"minecraft:spruce_door", PROPS_DOOR_S_UPPER, 5},
|
||||
[BLOCK_SPRUCE_DOOR_N_LOWER] = {"minecraft:spruce_door", PROPS_DOOR_N_LOWER, 5},
|
||||
[BLOCK_SPRUCE_DOOR_N_UPPER] = {"minecraft:spruce_door", PROPS_DOOR_N_UPPER, 5},
|
||||
[BLOCK_SPRUCE_DOOR_W_LOWER] = {"minecraft:spruce_door", PROPS_DOOR_W_LOWER, 5},
|
||||
[BLOCK_SPRUCE_DOOR_W_UPPER] = {"minecraft:spruce_door", PROPS_DOOR_W_UPPER, 5},
|
||||
[BLOCK_SPRUCE_DOOR_E_LOWER] = {"minecraft:spruce_door", PROPS_DOOR_E_LOWER, 5},
|
||||
[BLOCK_SPRUCE_DOOR_E_UPPER] = {"minecraft:spruce_door", PROPS_DOOR_E_UPPER, 5},
|
||||
[BLOCK_SPRUCE_STAIRS_E] = {"minecraft:spruce_stairs", PROPS_STAIRS_E, 4},
|
||||
[BLOCK_SPRUCE_STAIRS_W] = {"minecraft:spruce_stairs", PROPS_STAIRS_W, 4}
|
||||
};
|
||||
|
||||
static const block_state *get_block_state(uint16_t id) {
|
||||
@@ -308,9 +344,9 @@ static void write_palette_entry(buf *b, const block_state *state) {
|
||||
}
|
||||
|
||||
static void write_section(buf *b, const chunk_data *chunk, int section_y) {
|
||||
int palette_index[16];
|
||||
for (size_t i = 0; i < 16; ++i) palette_index[i] = -1;
|
||||
const block_state *palette_states[16];
|
||||
int palette_index[BLOCK_STATE_CAP];
|
||||
for (size_t i = 0; i < BLOCK_STATE_CAP; ++i) palette_index[i] = -1;
|
||||
const block_state *palette_states[BLOCK_STATE_CAP];
|
||||
uint16_t block_indices[4096];
|
||||
size_t palette_len = 0;
|
||||
|
||||
@@ -322,10 +358,13 @@ static void write_section(buf *b, const chunk_data *chunk, int section_y) {
|
||||
for (int z = 0; z < CHUNK_SIZE; ++z) {
|
||||
for (int x = 0; x < CHUNK_SIZE; ++x) {
|
||||
uint16_t bid = chunk->blocks[gy][x][z];
|
||||
if (bid >= BLOCK_STATE_CAP) continue;
|
||||
if (palette_index[bid] == -1) {
|
||||
palette_index[bid] = (int)palette_len;
|
||||
palette_states[palette_len] = get_block_state(bid);
|
||||
palette_len++;
|
||||
if (palette_len < BLOCK_STATE_CAP) {
|
||||
palette_len++;
|
||||
}
|
||||
}
|
||||
block_indices[idx++] = (uint16_t)palette_index[bid];
|
||||
}
|
||||
|
||||
@@ -118,15 +118,23 @@ static inline double clamp01(double v) {
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline int clamp_int(int v, int min_v, int max_v) {
|
||||
if (v < min_v) return min_v;
|
||||
if (v > max_v) return max_v;
|
||||
return v;
|
||||
}
|
||||
|
||||
static int ground_slope(worldgen_ctx *ctx, int x, int z);
|
||||
static uint16_t select_surface_block(worldgen_ctx *ctx, const column_data *data, int world_x, int world_z);
|
||||
static void generate_chunk_trails(worldgen_ctx *ctx, int chunk_x, int chunk_z, column_data columns[CHUNK_SIZE][CHUNK_SIZE], chunk_data *out);
|
||||
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 trail_node_position(worldgen_ctx *ctx, int node_x, int node_z, double spacing, double *out_x, double *out_z);
|
||||
static void carve_trail_pad(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_data *out, column_data columns[CHUNK_SIZE][CHUNK_SIZE], int center_x, int center_z, int radius, int target_height);
|
||||
static double old_growth_plains_mask(worldgen_ctx *ctx, int x, int z);
|
||||
static double old_growth_grove_mask(worldgen_ctx *ctx, int x, int z);
|
||||
static uint16_t generate_normal_ores(worldgen_ctx *ctx, int x, int y, int z, const column_data *col);
|
||||
|
||||
static uint32_t hash_coords(int x, int z, uint32_t seed) {
|
||||
uint32_t h = (uint32_t)(x * 374761393 + z * 668265263) ^ seed;
|
||||
@@ -134,6 +142,25 @@ static uint32_t hash_coords(int x, int z, uint32_t seed) {
|
||||
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;
|
||||
h = (h ^ (h >> 13)) * 1274126177u;
|
||||
return h ^ (h >> 16);
|
||||
}
|
||||
|
||||
static void set_block_with_height(chunk_data *chunk, int local_x, int local_z, int y, uint16_t id) {
|
||||
if (local_x < 0 || local_x >= CHUNK_SIZE || local_z < 0 || local_z >= CHUNK_SIZE) return;
|
||||
if (y < 0 || y >= CHUNK_HEIGHT) return;
|
||||
chunk->blocks[y][local_x][local_z] = id;
|
||||
if (id != BLOCK_AIR) {
|
||||
uint16_t current = chunk->heightmap[local_x][local_z];
|
||||
if ((uint16_t)y > current) {
|
||||
chunk->heightmap[local_x][local_z] = (uint16_t)y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static double worley_distance(int x, int z, double scale, uint32_t seed) {
|
||||
double px = x * scale;
|
||||
double pz = z * scale;
|
||||
@@ -156,6 +183,25 @@ static double worley_distance(int x, int z, double scale, uint32_t seed) {
|
||||
return min_dist;
|
||||
}
|
||||
|
||||
static double ore_depth_weight(int y, int top, int bottom) {
|
||||
if (y > top || y < bottom) return 0.0;
|
||||
if (top <= bottom) return 1.0;
|
||||
double span = (double)(top - bottom);
|
||||
if (span <= 0.0) return 1.0;
|
||||
double weight = (double)(top - y) / span;
|
||||
if (weight < 0.0) weight = 0.0;
|
||||
if (weight > 1.0) weight = 1.0;
|
||||
return weight;
|
||||
}
|
||||
|
||||
static double ore_cluster_field(worldgen_ctx *ctx, int x, int y, int z, double scale, double offset) {
|
||||
double n = simplex_noise3(&ctx->noise,
|
||||
x * scale + offset,
|
||||
y * scale * 0.9 - offset * 0.37,
|
||||
z * scale - offset * 0.21);
|
||||
return n * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
static double old_growth_plains_mask(worldgen_ctx *ctx, int x, int z) {
|
||||
(void)ctx;
|
||||
double coarse = worley_distance(x + 21000, z - 21000, 0.00065, 0x9E3779B9u);
|
||||
@@ -547,7 +593,7 @@ static int sample_block(worldgen_ctx *ctx, int x, int y, int z) {
|
||||
if (generate_coal(ctx, x, y, z, data.height, data.biome)) {
|
||||
return BLOCK_COAL;
|
||||
}
|
||||
return BLOCK_STONE;
|
||||
return (int)generate_normal_ores(ctx, x, y, z, &data);
|
||||
}
|
||||
if (y < data.height) return BLOCK_DIRT;
|
||||
if (y == data.height) {
|
||||
@@ -1285,7 +1331,549 @@ static void generate_chunk_flowers(worldgen_ctx *ctx, int chunk_x, int chunk_z,
|
||||
}
|
||||
}
|
||||
|
||||
static int column_has_trail_surface(chunk_data *chunk, int chunk_x, int chunk_z, int world_x, int world_z) {
|
||||
static void place_log_line(chunk_data *chunk, int chunk_origin_x, int chunk_origin_z,
|
||||
int x0, int z0, int x1, int z1, int y, uint16_t block,
|
||||
int door_x, int door_z, int door_clear_top,
|
||||
rng_state *rng, double skip_prob) {
|
||||
int dx = (x1 > x0) ? 1 : (x1 < x0 ? -1 : 0);
|
||||
int dz = (z1 > z0) ? 1 : (z1 < z0 ? -1 : 0);
|
||||
int length = (dx != 0) ? abs(x1 - x0) : abs(z1 - z0);
|
||||
int respect_door = (door_x != INT_MIN && door_z != INT_MIN);
|
||||
for (int i = 0; i <= length; ++i) {
|
||||
int wx = x0 + dx * i;
|
||||
int wz = z0 + dz * i;
|
||||
if (respect_door && wx == door_x && wz == door_z && y <= door_clear_top) continue;
|
||||
if (rng && skip_prob > 0.0 && rng_next_f64(rng) < skip_prob) continue;
|
||||
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, y, block);
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int offset_x;
|
||||
int offset_z;
|
||||
int half_w;
|
||||
int half_l;
|
||||
} cabin_rect;
|
||||
|
||||
#define CABIN_MAX_RECTS 4
|
||||
|
||||
typedef struct {
|
||||
const cabin_rect *rects;
|
||||
size_t rect_count;
|
||||
int wall_height;
|
||||
int stories;
|
||||
uint16_t floor_block;
|
||||
uint16_t roof_block;
|
||||
uint16_t log_x_block;
|
||||
uint16_t log_z_block;
|
||||
uint16_t corner_log;
|
||||
uint16_t stair_e_block;
|
||||
uint16_t stair_w_block;
|
||||
uint16_t window_block;
|
||||
double log_decay;
|
||||
double plank_decay;
|
||||
double window_chance;
|
||||
double door_decay;
|
||||
int door_rect_index;
|
||||
} cabin_blueprint;
|
||||
|
||||
static const cabin_rect CABIN_RECT_SMALL[] = {
|
||||
{0, 0, 2, 3}
|
||||
};
|
||||
|
||||
static const cabin_rect CABIN_RECT_LONG[] = {
|
||||
{0, 0, 3, 4}
|
||||
};
|
||||
|
||||
static const cabin_rect CABIN_RECT_TWO_STORY[] = {
|
||||
{0, 0, 3, 3}
|
||||
};
|
||||
|
||||
static const cabin_rect CABIN_RECT_L_SHAPE[] = {
|
||||
{0, 0, 3, 3},
|
||||
{3, -2, 2, 2}
|
||||
};
|
||||
|
||||
static const cabin_blueprint CABIN_BLUEPRINTS[] = {
|
||||
{
|
||||
CABIN_RECT_SMALL,
|
||||
sizeof(CABIN_RECT_SMALL) / sizeof(CABIN_RECT_SMALL[0]),
|
||||
3,
|
||||
1,
|
||||
BLOCK_SPRUCE_PLANKS,
|
||||
BLOCK_OAK_PLANKS,
|
||||
BLOCK_OAK_LOG_X,
|
||||
BLOCK_OAK_LOG_Z,
|
||||
BLOCK_OAK_LOG,
|
||||
BLOCK_SPRUCE_STAIRS_E,
|
||||
BLOCK_SPRUCE_STAIRS_W,
|
||||
BLOCK_GLASS_PANE,
|
||||
0.04,
|
||||
0.25,
|
||||
0.45,
|
||||
0.35,
|
||||
0
|
||||
},
|
||||
{
|
||||
CABIN_RECT_LONG,
|
||||
sizeof(CABIN_RECT_LONG) / sizeof(CABIN_RECT_LONG[0]),
|
||||
4,
|
||||
1,
|
||||
BLOCK_OAK_PLANKS,
|
||||
BLOCK_SPRUCE_PLANKS,
|
||||
BLOCK_SPRUCE_LOG_X,
|
||||
BLOCK_SPRUCE_LOG_Z,
|
||||
BLOCK_OAK_LOG,
|
||||
BLOCK_SPRUCE_STAIRS_E,
|
||||
BLOCK_SPRUCE_STAIRS_W,
|
||||
BLOCK_GLASS_PANE,
|
||||
0.05,
|
||||
0.3,
|
||||
0.4,
|
||||
0.4,
|
||||
0
|
||||
},
|
||||
{
|
||||
CABIN_RECT_TWO_STORY,
|
||||
sizeof(CABIN_RECT_TWO_STORY) / sizeof(CABIN_RECT_TWO_STORY[0]),
|
||||
4,
|
||||
2,
|
||||
BLOCK_SPRUCE_PLANKS,
|
||||
BLOCK_SPRUCE_PLANKS,
|
||||
BLOCK_OAK_LOG_X,
|
||||
BLOCK_OAK_LOG_Z,
|
||||
BLOCK_OAK_LOG,
|
||||
BLOCK_SPRUCE_STAIRS_E,
|
||||
BLOCK_SPRUCE_STAIRS_W,
|
||||
BLOCK_GLASS_PANE,
|
||||
0.04,
|
||||
0.22,
|
||||
0.5,
|
||||
0.3,
|
||||
0
|
||||
},
|
||||
{
|
||||
CABIN_RECT_L_SHAPE,
|
||||
sizeof(CABIN_RECT_L_SHAPE) / sizeof(CABIN_RECT_L_SHAPE[0]),
|
||||
3,
|
||||
1,
|
||||
BLOCK_OAK_PLANKS,
|
||||
BLOCK_OAK_PLANKS,
|
||||
BLOCK_OAK_LOG_X,
|
||||
BLOCK_OAK_LOG_Z,
|
||||
BLOCK_OAK_LOG,
|
||||
BLOCK_SPRUCE_STAIRS_E,
|
||||
BLOCK_SPRUCE_STAIRS_W,
|
||||
BLOCK_GLASS_PANE,
|
||||
0.04,
|
||||
0.28,
|
||||
0.45,
|
||||
0.4,
|
||||
0
|
||||
}
|
||||
};
|
||||
|
||||
static void update_columns_for_rect(column_data columns[CHUNK_SIZE][CHUNK_SIZE], int chunk_origin_x, int chunk_origin_z,
|
||||
int x0, int x1, int z0, int z1, int new_height) {
|
||||
for (int wz = z0 - 1; wz <= z1 + 1; ++wz) {
|
||||
for (int wx = x0 - 1; wx <= x1 + 1; ++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;
|
||||
if (columns[lx][lz].height < new_height) {
|
||||
columns[lx][lz].height = new_height;
|
||||
columns[lx][lz].has_water = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void build_cabin_roof(const cabin_blueprint *bp, int chunk_x, int chunk_z, chunk_data *chunk,
|
||||
int rect_center_x, int rect_center_z, int half_w, int half_l,
|
||||
int roof_base_y, rng_state *rng) {
|
||||
int chunk_origin_x = chunk_x * CHUNK_SIZE;
|
||||
int chunk_origin_z = chunk_z * CHUNK_SIZE;
|
||||
int overhang = 1;
|
||||
int x0 = rect_center_x - half_w;
|
||||
int x1 = rect_center_x + half_w;
|
||||
int z0 = rect_center_z - half_l;
|
||||
int z1 = rect_center_z + half_l;
|
||||
int layers = half_w + 3;
|
||||
for (int layer = 0; layer < layers; ++layer) {
|
||||
int start_x = (x0 - overhang) + layer;
|
||||
int end_x = (x1 + overhang) - layer;
|
||||
if (start_x > end_x) break;
|
||||
int y = roof_base_y + layer + 1;
|
||||
for (int wz = z0 - overhang; wz <= z1 + overhang; ++wz) {
|
||||
for (int wx = start_x; wx <= end_x; ++wx) {
|
||||
if (rng && bp->plank_decay > 0.0 && rng_next_f64(rng) < bp->plank_decay * 0.2) continue;
|
||||
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, y, bp->roof_block);
|
||||
}
|
||||
}
|
||||
for (int wz = z0 - overhang; wz <= z1 + overhang; ++wz) {
|
||||
int east_x = end_x + 1;
|
||||
int west_x = start_x - 1;
|
||||
int lx_e = east_x - chunk_origin_x;
|
||||
int lx_w = west_x - chunk_origin_x;
|
||||
int lz = wz - chunk_origin_z;
|
||||
if (lx_e >= 0 && lx_e < CHUNK_SIZE && lz >= 0 && lz < CHUNK_SIZE) {
|
||||
set_block_with_height(chunk, lx_e, lz, y, bp->stair_e_block);
|
||||
}
|
||||
if (lx_w >= 0 && lx_w < CHUNK_SIZE && lz >= 0 && lz < CHUNK_SIZE) {
|
||||
set_block_with_height(chunk, lx_w, lz, y, bp->stair_w_block);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void place_wall_window(chunk_data *chunk, int chunk_origin_x, int chunk_origin_z,
|
||||
int wx, int wz, int window_y, uint16_t window_block) {
|
||||
int lx = wx - chunk_origin_x;
|
||||
int lz = wz - chunk_origin_z;
|
||||
if (lx < 0 || lx >= CHUNK_SIZE || lz < 0 || lz >= CHUNK_SIZE) return;
|
||||
set_block_with_height(chunk, lx, lz, window_y, window_block);
|
||||
}
|
||||
|
||||
static void build_cabin_rect(worldgen_ctx *ctx, const cabin_blueprint *bp, const cabin_rect *rect,
|
||||
int chunk_x, int chunk_z, chunk_data *chunk, column_data columns[CHUNK_SIZE][CHUNK_SIZE],
|
||||
int rect_center_x, int rect_center_z, int base_floor_y,
|
||||
int door_x, int door_z, int door_side, int has_door, rng_state *rng) {
|
||||
(void)ctx;
|
||||
int chunk_origin_x = chunk_x * CHUNK_SIZE;
|
||||
int chunk_origin_z = chunk_z * CHUNK_SIZE;
|
||||
int x0 = rect_center_x - rect->half_w;
|
||||
int x1 = rect_center_x + rect->half_w;
|
||||
int z0 = rect_center_z - rect->half_l;
|
||||
int z1 = rect_center_z + rect->half_l;
|
||||
int clear_top = base_floor_y + bp->wall_height * bp->stories + 6;
|
||||
|
||||
for (int wz = z0 - 2; wz <= z1 + 2; ++wz) {
|
||||
for (int wx = x0 - 2; wx <= x1 + 2; ++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;
|
||||
for (int y = base_floor_y; y <= clear_top && y < CHUNK_HEIGHT; ++y) {
|
||||
set_block_with_height(chunk, lx, lz, y, BLOCK_AIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int story = 0; story < bp->stories; ++story) {
|
||||
int story_floor = base_floor_y + story * bp->wall_height;
|
||||
if (story_floor >= CHUNK_HEIGHT - 4) break;
|
||||
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, story_floor, bp->floor_block);
|
||||
}
|
||||
}
|
||||
int story_has_door = has_door && story == 0;
|
||||
int door_clear_top = story_has_door ? (story_floor + 2) : story_floor;
|
||||
int door_x_story = story_has_door ? door_x : INT_MIN;
|
||||
int door_z_story = story_has_door ? door_z : INT_MIN;
|
||||
for (int h = 0; h < bp->wall_height; ++h) {
|
||||
int yy = story_floor + 1 + h;
|
||||
if (yy >= CHUNK_HEIGHT - 2) break;
|
||||
int extend_x = ((story * bp->wall_height + h) % 2 == 0);
|
||||
double base_skip = bp->log_decay;
|
||||
double extend_skip = bp->log_decay * 0.6;
|
||||
int north_start_x = extend_x ? x0 - 1 : x0;
|
||||
int north_end_x = extend_x ? x1 + 1 : x1;
|
||||
int south_start_x = extend_x ? x0 - 1 : x0;
|
||||
int south_end_x = extend_x ? x1 + 1 : x1;
|
||||
if (extend_x) {
|
||||
place_log_line(chunk, chunk_origin_x, chunk_origin_z, x0, z0, x0, z1, yy, bp->log_z_block,
|
||||
door_x_story, door_z_story, door_clear_top, rng, base_skip);
|
||||
place_log_line(chunk, chunk_origin_x, chunk_origin_z, x1, z0, x1, z1, yy, bp->log_z_block,
|
||||
door_x_story, door_z_story, door_clear_top, rng, base_skip);
|
||||
place_log_line(chunk, chunk_origin_x, chunk_origin_z, north_start_x, z0, north_end_x, z0, yy, bp->log_x_block,
|
||||
door_x_story, door_z_story, door_clear_top, rng, extend_skip);
|
||||
place_log_line(chunk, chunk_origin_x, chunk_origin_z, south_start_x, z1, south_end_x, z1, yy, bp->log_x_block,
|
||||
door_x_story, door_z_story, door_clear_top, rng, extend_skip);
|
||||
} else {
|
||||
int west_start_z = z0 - 1;
|
||||
int west_end_z = z1 + 1;
|
||||
int east_start_z = z0 - 1;
|
||||
int east_end_z = z1 + 1;
|
||||
place_log_line(chunk, chunk_origin_x, chunk_origin_z, north_start_x, z0, north_end_x, z0, yy, bp->log_x_block,
|
||||
door_x_story, door_z_story, door_clear_top, rng, base_skip);
|
||||
place_log_line(chunk, chunk_origin_x, chunk_origin_z, south_start_x, z1, south_end_x, z1, yy, bp->log_x_block,
|
||||
door_x_story, door_z_story, door_clear_top, rng, base_skip);
|
||||
place_log_line(chunk, chunk_origin_x, chunk_origin_z, x0, west_start_z, x0, west_end_z, yy, bp->log_z_block,
|
||||
door_x_story, door_z_story, door_clear_top, rng, extend_skip);
|
||||
place_log_line(chunk, chunk_origin_x, chunk_origin_z, x1, east_start_z, x1, east_end_z, yy, bp->log_z_block,
|
||||
door_x_story, door_z_story, door_clear_top, rng, extend_skip);
|
||||
}
|
||||
}
|
||||
|
||||
if (bp->window_block && bp->window_chance > 0.0) {
|
||||
int window_y = story_floor + 2;
|
||||
for (int wx = x0 + 1; wx <= x1 - 1; wx += 2) {
|
||||
if (story_has_door && door_side == 0 && wx == door_x) continue;
|
||||
if (rng_next_f64(rng) < bp->window_chance) {
|
||||
place_wall_window(chunk, chunk_origin_x, chunk_origin_z, wx, z0, window_y, bp->window_block);
|
||||
}
|
||||
if (story_has_door && door_side == 1 && wx == door_x) continue;
|
||||
if (rng_next_f64(rng) < bp->window_chance) {
|
||||
place_wall_window(chunk, chunk_origin_x, chunk_origin_z, wx, z1, window_y, bp->window_block);
|
||||
}
|
||||
}
|
||||
for (int wz = z0 + 1; wz <= z1 - 1; wz += 2) {
|
||||
if (story_has_door && door_side == 2 && wz == door_z) continue;
|
||||
if (rng_next_f64(rng) < bp->window_chance) {
|
||||
place_wall_window(chunk, chunk_origin_x, chunk_origin_z, x0, wz, window_y, bp->window_block);
|
||||
}
|
||||
if (story_has_door && door_side == 3 && wz == door_z) continue;
|
||||
if (rng_next_f64(rng) < bp->window_chance) {
|
||||
place_wall_window(chunk, chunk_origin_x, chunk_origin_z, x1, wz, window_y, bp->window_block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (story_has_door) {
|
||||
if (rng_next_f64(rng) >= bp->door_decay) {
|
||||
uint16_t lower = BLOCK_SPRUCE_DOOR_S_LOWER;
|
||||
uint16_t upper = BLOCK_SPRUCE_DOOR_S_UPPER;
|
||||
switch (door_side) {
|
||||
case 0: lower = BLOCK_SPRUCE_DOOR_N_LOWER; upper = BLOCK_SPRUCE_DOOR_N_UPPER; break;
|
||||
case 1: lower = BLOCK_SPRUCE_DOOR_S_LOWER; upper = BLOCK_SPRUCE_DOOR_S_UPPER; break;
|
||||
case 2: lower = BLOCK_SPRUCE_DOOR_W_LOWER; upper = BLOCK_SPRUCE_DOOR_W_UPPER; break;
|
||||
case 3: lower = BLOCK_SPRUCE_DOOR_E_LOWER; upper = BLOCK_SPRUCE_DOOR_E_UPPER; break;
|
||||
}
|
||||
int lx = door_x - chunk_origin_x;
|
||||
int lz = door_z - chunk_origin_z;
|
||||
if (lx >= 0 && lx < CHUNK_SIZE && lz >= 0 && lz < CHUNK_SIZE) {
|
||||
set_block_with_height(chunk, lx, lz, story_floor + 1, lower);
|
||||
set_block_with_height(chunk, lx, lz, story_floor + 2, upper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int roof_base = base_floor_y + bp->wall_height * bp->stories;
|
||||
build_cabin_roof(bp, chunk_x, chunk_z, chunk, rect_center_x, rect_center_z, rect->half_w, rect->half_l, roof_base, rng);
|
||||
|
||||
if (has_door) {
|
||||
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 pad_x = door_x + step_x;
|
||||
int pad_z = door_z + step_z;
|
||||
int lx = pad_x - chunk_origin_x;
|
||||
int lz = pad_z - chunk_origin_z;
|
||||
if (lx >= 0 && lx < CHUNK_SIZE && lz >= 0 && lz < CHUNK_SIZE) {
|
||||
set_block_with_height(chunk, lx, lz, base_floor_y, BLOCK_GRAVEL);
|
||||
}
|
||||
}
|
||||
|
||||
update_columns_for_rect(columns, chunk_origin_x, chunk_origin_z, x0, x1, z0, z1, roof_base + 2);
|
||||
}
|
||||
|
||||
static int try_place_cabin(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_data *chunk, column_data columns[CHUNK_SIZE][CHUNK_SIZE],
|
||||
int center_x, int center_z, const cabin_blueprint *bp, rng_state *rng) {
|
||||
int chunk_origin_x = chunk_x * CHUNK_SIZE;
|
||||
int chunk_origin_z = chunk_z * CHUNK_SIZE;
|
||||
if (bp->rect_count == 0 || bp->rect_count > CABIN_MAX_RECTS) return 0;
|
||||
int rect_center_x[CABIN_MAX_RECTS];
|
||||
int rect_center_z[CABIN_MAX_RECTS];
|
||||
int rect_x0[CABIN_MAX_RECTS];
|
||||
int rect_x1[CABIN_MAX_RECTS];
|
||||
int rect_z0[CABIN_MAX_RECTS];
|
||||
int rect_z1[CABIN_MAX_RECTS];
|
||||
int min_h = INT_MAX;
|
||||
int max_h = INT_MIN;
|
||||
for (size_t i = 0; i < bp->rect_count; ++i) {
|
||||
const cabin_rect *rect = &bp->rects[i];
|
||||
int rcx = center_x + rect->offset_x;
|
||||
int rcz = center_z + rect->offset_z;
|
||||
int x0 = rcx - rect->half_w;
|
||||
int x1 = rcx + rect->half_w;
|
||||
int z0 = rcz - rect->half_l;
|
||||
int z1 = rcz + rect->half_l;
|
||||
if (x0 < chunk_origin_x + 1 || x1 > chunk_origin_x + CHUNK_SIZE - 2) return 0;
|
||||
if (z0 < chunk_origin_z + 1 || z1 > chunk_origin_z + CHUNK_SIZE - 2) return 0;
|
||||
rect_center_x[i] = rcx;
|
||||
rect_center_z[i] = rcz;
|
||||
rect_x0[i] = x0;
|
||||
rect_x1[i] = x1;
|
||||
rect_z0[i] = z0;
|
||||
rect_z1[i] = z1;
|
||||
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 (col.height < min_h) min_h = col.height;
|
||||
if (col.height > max_h) max_h = col.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (min_h == INT_MAX) return 0;
|
||||
if (max_h - min_h > 3) return 0;
|
||||
int base_floor_y = min_h + 1;
|
||||
if (base_floor_y + bp->wall_height * bp->stories + 6 >= CHUNK_HEIGHT) return 0;
|
||||
|
||||
int door_rect_index = clamp_int(bp->door_rect_index, 0, (int)bp->rect_count - 1);
|
||||
int door_side = rng_range_inclusive(rng, 0, 3);
|
||||
int door_x = rect_center_x[door_rect_index];
|
||||
int door_z = rect_z0[door_rect_index];
|
||||
if (door_side == 1) door_z = rect_z1[door_rect_index];
|
||||
if (door_side == 2) {
|
||||
door_x = rect_x0[door_rect_index];
|
||||
door_z = rect_center_z[door_rect_index];
|
||||
} else if (door_side == 3) {
|
||||
door_x = rect_x1[door_rect_index];
|
||||
door_z = rect_center_z[door_rect_index];
|
||||
}
|
||||
int door_offset = rng_range_inclusive(rng, -1, 1);
|
||||
if (door_side == 0 || door_side == 1) {
|
||||
door_x = clamp_int(door_x + door_offset, rect_x0[door_rect_index] + 1, rect_x1[door_rect_index] - 1);
|
||||
} else {
|
||||
door_z = clamp_int(door_z + door_offset, rect_z0[door_rect_index] + 1, rect_z1[door_rect_index] - 1);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < bp->rect_count; ++i) {
|
||||
int has_door = (int)i == door_rect_index;
|
||||
build_cabin_rect(ctx, bp, &bp->rects[i], chunk_x, chunk_z, chunk, columns,
|
||||
rect_center_x[i], rect_center_z[i], base_floor_y,
|
||||
door_x, door_z, door_side, has_door, rng);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void generate_chunk_cabins(worldgen_ctx *ctx, int chunk_x, int chunk_z, column_data columns[CHUNK_SIZE][CHUNK_SIZE], chunk_data *out) {
|
||||
uint64_t seed = (uint64_t)ctx->world_seed * 6364136223846793005ULL + (uint64_t)chunk_x * 374761393ULL + (uint64_t)chunk_z * 668265263ULL;
|
||||
rng_state rng;
|
||||
rng_seed(&rng, seed ^ 0xCAB1A5u);
|
||||
double noise = simplex_noise2(&ctx->noise, (chunk_x * CHUNK_SIZE + 5000) * 0.0006, (chunk_z * CHUNK_SIZE - 5000) * 0.0006) * 0.5 + 0.5;
|
||||
double spawn_chance = 0.015 + noise * 0.02;
|
||||
if (rng_next_f64(&rng) > spawn_chance) return;
|
||||
size_t blueprint_count = sizeof(CABIN_BLUEPRINTS) / sizeof(CABIN_BLUEPRINTS[0]);
|
||||
int attempts = 1 + (rng_next_f64(&rng) < 0.2 ? 1 : 0);
|
||||
while (attempts-- > 0) {
|
||||
const cabin_blueprint *bp = &CABIN_BLUEPRINTS[rng_range_inclusive(&rng, 0, (int)blueprint_count - 1)];
|
||||
int min_local_x = 2;
|
||||
int max_local_x = CHUNK_SIZE - 3;
|
||||
int min_local_z = 2;
|
||||
int max_local_z = CHUNK_SIZE - 3;
|
||||
for (size_t i = 0; i < bp->rect_count; ++i) {
|
||||
const cabin_rect *rect = &bp->rects[i];
|
||||
int req_min_x = rect->half_w - rect->offset_x + 1;
|
||||
int req_max_x = CHUNK_SIZE - 2 - (rect->half_w + rect->offset_x);
|
||||
int req_min_z = rect->half_l - rect->offset_z + 1;
|
||||
int req_max_z = CHUNK_SIZE - 2 - (rect->half_l + rect->offset_z);
|
||||
if (req_min_x > min_local_x) min_local_x = req_min_x;
|
||||
if (req_max_x < max_local_x) max_local_x = req_max_x;
|
||||
if (req_min_z > min_local_z) min_local_z = req_min_z;
|
||||
if (req_max_z < max_local_z) max_local_z = req_max_z;
|
||||
}
|
||||
if (min_local_x >= max_local_x - 1 || min_local_z >= max_local_z - 1) continue;
|
||||
int local_cx = rng_range_inclusive(&rng, min_local_x, max_local_x);
|
||||
int local_cz = rng_range_inclusive(&rng, min_local_z, max_local_z);
|
||||
int world_cx = chunk_x * CHUNK_SIZE + local_cx;
|
||||
int world_cz = chunk_z * CHUNK_SIZE + local_cz;
|
||||
if (try_place_cabin(ctx, chunk_x, chunk_z, out, columns, world_cx, world_cz, bp, &rng)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t generate_normal_ores(worldgen_ctx *ctx, int x, int y, int z, const column_data *col) {
|
||||
uint32_t seed = (uint32_t)ctx->world_seed;
|
||||
double cluster;
|
||||
double chance;
|
||||
double weight;
|
||||
uint32_t h;
|
||||
|
||||
weight = ore_depth_weight(y, 16, 0);
|
||||
if (weight > 0.0) {
|
||||
cluster = ore_cluster_field(ctx, x, y, z, 0.032, 19000.0);
|
||||
if (cluster > 0.78) {
|
||||
chance = 0.003 + weight * 0.02;
|
||||
h = hash_coords3(x, y, z, seed ^ 0x0D14F1A3u);
|
||||
if ((h & 0xFFFF) <= (uint32_t)(chance * 65535.0)) {
|
||||
return BLOCK_DIAMOND_ORE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
weight = ore_depth_weight(y, 20, 0);
|
||||
if (weight > 0.0) {
|
||||
cluster = ore_cluster_field(ctx, x, y, z, 0.028, 12000.0);
|
||||
if (cluster > 0.65) {
|
||||
chance = 0.01 + weight * 0.12;
|
||||
h = hash_coords3(x, y, z, seed ^ 0x0BADC0DEu);
|
||||
if ((h & 0xFFFF) <= (uint32_t)(chance * 65535.0)) {
|
||||
return BLOCK_REDSTONE_ORE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
weight = ore_depth_weight(y, 24, 2);
|
||||
if (weight > 0.0) {
|
||||
cluster = ore_cluster_field(ctx, x, y, z, 0.026, 15000.0);
|
||||
if (cluster > 0.67) {
|
||||
chance = 0.006 + weight * 0.07;
|
||||
h = hash_coords3(x, y, z, seed ^ 0x1A5150Eu);
|
||||
if ((h & 0xFFFF) <= (uint32_t)(chance * 65535.0)) {
|
||||
return BLOCK_LAPIS_ORE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
weight = ore_depth_weight(y, 32, 0);
|
||||
if (weight > 0.0) {
|
||||
cluster = ore_cluster_field(ctx, x, y, z, 0.02, 8000.0);
|
||||
if (cluster > 0.63) {
|
||||
double altitude = (double)(col->height - ctx->sea_level);
|
||||
double mountain = clamp01(altitude / 40.0);
|
||||
chance = (0.008 + weight * 0.06) * (1.0 + mountain * 0.8);
|
||||
h = hash_coords3(x, y, z, seed ^ 0x90ADCAFEu);
|
||||
if ((h & 0xFFFF) <= (uint32_t)(chance * 65535.0)) {
|
||||
return BLOCK_GOLD_ORE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
weight = ore_depth_weight(y, 68, -4);
|
||||
if (weight > 0.0) {
|
||||
cluster = ore_cluster_field(ctx, x, y, z, 0.018, 6000.0);
|
||||
if (cluster > 0.58) {
|
||||
double biome_bonus = (col->biome == BIOME_EAST_KY_RIDGEBREAKS) ? 0.05 : 0.0;
|
||||
chance = 0.04 + weight * 0.25 + biome_bonus;
|
||||
h = hash_coords3(x, y, z, seed ^ 0x1B0EFACEu);
|
||||
if ((h & 0xFFFF) <= (uint32_t)(chance * 65535.0)) {
|
||||
return BLOCK_IRON_ORE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
weight = ore_depth_weight(y, 92, 10);
|
||||
if (weight > 0.0) {
|
||||
cluster = ore_cluster_field(ctx, x, y, z, 0.015, 4200.0);
|
||||
if (cluster > 0.62) {
|
||||
double plains_bonus = (col->biome == BIOME_WEST_KY_COALFIELDS) ? 0.05 : 0.0;
|
||||
chance = 0.03 + weight * 0.18 + plains_bonus;
|
||||
h = hash_coords3(x, y, z, seed ^ 0xC0FFEE12u);
|
||||
if ((h & 0xFFFF) <= (uint32_t)(chance * 65535.0)) {
|
||||
return BLOCK_COPPER_ORE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return BLOCK_STONE;
|
||||
}
|
||||
|
||||
static int column_has_manmade_surface(chunk_data *chunk, int chunk_x, int chunk_z, int world_x, int world_z) {
|
||||
int local_x = world_x - chunk_x * CHUNK_SIZE;
|
||||
int local_z = world_z - chunk_z * CHUNK_SIZE;
|
||||
if (local_x < 0 || local_x >= CHUNK_SIZE || local_z < 0 || local_z >= CHUNK_SIZE) return 0;
|
||||
@@ -1293,7 +1881,17 @@ static int column_has_trail_surface(chunk_data *chunk, int chunk_x, int chunk_z,
|
||||
uint16_t block = chunk->blocks[y][local_x][local_z];
|
||||
if (block == BLOCK_AIR) continue;
|
||||
if (block == BLOCK_WATER) return 0;
|
||||
return block == BLOCK_GRAVEL;
|
||||
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_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) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1373,7 +1971,7 @@ static void generate_chunk_trees(worldgen_ctx *ctx, int chunk_x, int chunk_z, ch
|
||||
if (surface == BLOCK_SNOW) {
|
||||
base_y = data.height;
|
||||
}
|
||||
if (column_has_trail_surface(chunk, chunk_x, chunk_z, candidate_x, candidate_z)) {
|
||||
if (column_has_manmade_surface(chunk, chunk_x, chunk_z, candidate_x, candidate_z)) {
|
||||
block_list_free(&tmp);
|
||||
continue;
|
||||
}
|
||||
@@ -1863,10 +2461,10 @@ void worldgen_generate_chunk(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_
|
||||
if (y == 0) {
|
||||
id = BLOCK_BEDROCK;
|
||||
} else if (y < cd.height - 3) {
|
||||
if (generate_coal(ctx, chunk_x * CHUNK_SIZE + dx, y, chunk_z * CHUNK_SIZE + dz, cd.height, cd.biome)) {
|
||||
if (generate_coal(ctx, world_x, y, world_z, cd.height, cd.biome)) {
|
||||
id = BLOCK_COAL;
|
||||
} else {
|
||||
id = BLOCK_STONE;
|
||||
id = (int)generate_normal_ores(ctx, world_x, y, world_z, &cd);
|
||||
}
|
||||
} else if (y < cd.height) {
|
||||
id = BLOCK_DIRT;
|
||||
@@ -1886,6 +2484,7 @@ void worldgen_generate_chunk(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_
|
||||
generate_chunk_trails(ctx, chunk_x, chunk_z, columns, out);
|
||||
}
|
||||
|
||||
generate_chunk_cabins(ctx, chunk_x, chunk_z, columns, out);
|
||||
generate_chunk_grass(ctx, chunk_x, chunk_z, columns, out);
|
||||
generate_chunk_flowers(ctx, chunk_x, chunk_z, columns, out);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user