Improve redwood titan shape
This commit is contained in:
@@ -1039,6 +1039,87 @@ static void place_branch_span(int x, int y, int z, int dx, int dz, int length, i
|
||||
}
|
||||
}
|
||||
|
||||
static int redwood_axis_log(int log_block, int dx, int dz) {
|
||||
if (log_block == BLOCK_OAK_LOG) {
|
||||
return (abs(dz) > abs(dx)) ? BLOCK_OAK_LOG_Z : BLOCK_OAK_LOG_X;
|
||||
}
|
||||
return log_block;
|
||||
}
|
||||
|
||||
static void place_redwood_leaf_disc(int cx, int cy, int cz, int radius, int trunk_x, int trunk_z,
|
||||
int trunk_radius, int leaf_block, rng_state *rng, double hole_prob,
|
||||
double edge_hole, block_list *out) {
|
||||
if (radius < 1) return;
|
||||
int r2 = radius * radius;
|
||||
for (int dx = -radius; dx <= radius; ++dx) {
|
||||
for (int dz = -radius; dz <= radius; ++dz) {
|
||||
int d2 = dx * dx + dz * dz;
|
||||
if (d2 > r2) continue;
|
||||
int wx = cx + dx;
|
||||
int wz = cz + dz;
|
||||
if (trunk_radius >= 0 && abs(wx - trunk_x) <= trunk_radius && abs(wz - trunk_z) <= trunk_radius) continue;
|
||||
double edge = radius > 0 ? sqrt((double)d2) / (double)radius : 0.0;
|
||||
double skip = hole_prob + edge * edge_hole;
|
||||
if (skip > 0.0 && rng_next_f64(rng) < skip) continue;
|
||||
block_list_push(out, wx, cy, wz, (uint16_t)leaf_block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void place_redwood_leaf_cluster(int cx, int cy, int cz, int trunk_x, int trunk_z,
|
||||
int radius, int leaf_block, rng_state *rng, block_list *out) {
|
||||
if (radius < 2) radius = 2;
|
||||
place_redwood_leaf_disc(cx, cy, cz, radius, trunk_x, trunk_z, 1, leaf_block, rng, 0.04, 0.12, out);
|
||||
place_redwood_leaf_disc(cx, cy - 1, cz, radius - 1, trunk_x, trunk_z, 1, leaf_block, rng, 0.08, 0.16, out);
|
||||
place_redwood_leaf_disc(cx, cy + 1, cz, radius - 1, trunk_x, trunk_z, 1, leaf_block, rng, 0.10, 0.18, out);
|
||||
if (radius > 2 && rng_next_f64(rng) < 0.55) {
|
||||
place_redwood_leaf_disc(cx, cy - 2, cz, 1, trunk_x, trunk_z, 1, leaf_block, rng, 0.0, 0.0, out);
|
||||
}
|
||||
}
|
||||
|
||||
static void place_redwood_branch(int x, int y, int z, int dx, int dz, int length,
|
||||
int log_block, int leaf_block, rng_state *rng, block_list *out) {
|
||||
if (length < 2) length = 2;
|
||||
int branch_log = redwood_axis_log(log_block, dx, dz);
|
||||
for (int step = 0; step < length; ++step) {
|
||||
int reach = 2 + step;
|
||||
int px = x + dx * reach;
|
||||
int pz = z + dz * reach;
|
||||
int py = y + ((step >= length - 2 && length > 3) ? 1 : 0);
|
||||
if (step >= length - 3) {
|
||||
place_redwood_leaf_cluster(px, py, pz, x, z, step == length - 1 ? 3 : 2, leaf_block, rng, out);
|
||||
} else if ((step & 1) == 1) {
|
||||
place_redwood_leaf_disc(px, py - 1, pz, 2, x, z, 1, leaf_block, rng, 0.18, 0.20, out);
|
||||
}
|
||||
}
|
||||
for (int step = 0; step < length; ++step) {
|
||||
int reach = 2 + step;
|
||||
int px = x + dx * reach;
|
||||
int pz = z + dz * reach;
|
||||
int py = y + ((step >= length - 2 && length > 3) ? 1 : 0);
|
||||
block_list_push(out, px, py, pz, (uint16_t)branch_log);
|
||||
}
|
||||
}
|
||||
|
||||
static void place_redwood_root(worldgen_ctx *ctx, int x, int y, int z, int dx, int dz,
|
||||
int length, int log_block, rng_state *rng, block_list *out) {
|
||||
int root_log = redwood_axis_log(log_block, dx, dz);
|
||||
for (int step = 2; step <= length; ++step) {
|
||||
int px = x + dx * step;
|
||||
int pz = z + dz * step;
|
||||
int ground = column_height(ctx, px, pz);
|
||||
if (ground <= 0 || ground >= CHUNK_HEIGHT - 2) continue;
|
||||
if (abs(ground - y) > 3) continue;
|
||||
int py = ground + 1;
|
||||
block_list_push(out, px, py, pz, (uint16_t)root_log);
|
||||
int stack = 4 - step + rng_range_inclusive(rng, 0, 1);
|
||||
if (stack < 0) stack = 0;
|
||||
for (int s = 1; s <= stack; ++s) {
|
||||
block_list_push(out, px, py + s, pz, (uint16_t)log_block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void clear_snow_block(worldgen_ctx *ctx, int x, int y, int z, block_list *out) {
|
||||
int block = sample_block(ctx, x, y, z);
|
||||
if (block == BLOCK_SNOW) {
|
||||
@@ -1441,53 +1522,90 @@ static void build_maple_ancient(worldgen_ctx *ctx, int x, int y, int z, int heig
|
||||
}
|
||||
|
||||
static void build_redwood_titan(worldgen_ctx *ctx, int x, int y, int z, int height, rng_state *rng, block_list *out, const tree_archetype *arch) {
|
||||
(void)ctx;
|
||||
int core_height = height + rng_range_inclusive(rng, 2, 7);
|
||||
if (core_height < 30) core_height = 30;
|
||||
if (core_height > 44) core_height = 44;
|
||||
if (y + core_height + 10 >= CHUNK_HEIGHT) {
|
||||
core_height = CHUNK_HEIGHT - y - 10;
|
||||
if (core_height < 24) core_height = 24;
|
||||
int core_height = height + rng_range_inclusive(rng, 3, 8);
|
||||
if (core_height < 32) core_height = 32;
|
||||
if (core_height > 46) core_height = 46;
|
||||
if (y + core_height + 9 >= CHUNK_HEIGHT) {
|
||||
core_height = CHUNK_HEIGHT - y - 9;
|
||||
if (core_height < 26) core_height = 26;
|
||||
}
|
||||
int taper_start = core_height - 6;
|
||||
|
||||
const int dirs8[8][2] = {
|
||||
{1, 0}, {-1, 0}, {0, 1}, {0, -1},
|
||||
{1, 1}, {1, -1}, {-1, 1}, {-1, -1}
|
||||
};
|
||||
int spire = 3 + rng_range_inclusive(rng, 0, 2);
|
||||
int crown_start = y + core_height / 2 + rng_range_inclusive(rng, 0, 2);
|
||||
|
||||
for (int cy = crown_start; cy <= y + core_height + 2; cy += 2) {
|
||||
int below_top = y + core_height + 2 - cy;
|
||||
int radius = 2 + below_top / 9;
|
||||
if (radius > 4) radius = 4;
|
||||
if (cy > y + core_height - 4) radius = 2;
|
||||
place_redwood_leaf_disc(x, cy, z, radius, x, z, 1, arch->leaf_block, rng, 0.08, 0.16, out);
|
||||
if (radius > 2) {
|
||||
place_redwood_leaf_disc(x, cy - 1, z, radius - 1, x, z, 1, arch->leaf_block, rng, 0.12, 0.20, out);
|
||||
}
|
||||
}
|
||||
|
||||
int whorls = 7 + rng_range_inclusive(rng, 0, 2);
|
||||
for (int w = 0; w < whorls; ++w) {
|
||||
int wy = crown_start + w * 3 + rng_range_inclusive(rng, -1, 1);
|
||||
if (wy > y + core_height - 2) break;
|
||||
int branch_count = 3 + rng_range_inclusive(rng, 0, 2);
|
||||
if (w >= whorls - 2) branch_count += 1;
|
||||
int base_len = 6 - w / 2 + rng_range_inclusive(rng, 0, 1);
|
||||
if (base_len < 3) base_len = 3;
|
||||
if (base_len > 6) base_len = 6;
|
||||
int start_dir = rng_range_inclusive(rng, 0, 7);
|
||||
for (int b = 0; b < branch_count; ++b) {
|
||||
int idx = (start_dir + b * 2 + rng_range_inclusive(rng, 0, 1)) & 7;
|
||||
int branch_len = base_len - rng_range_inclusive(rng, 0, 1);
|
||||
place_redwood_branch(x, wy, z, dirs8[idx][0], dirs8[idx][1], branch_len,
|
||||
arch->log_block, arch->leaf_block, rng, out);
|
||||
}
|
||||
}
|
||||
|
||||
for (int t = 0; t < 4; ++t) {
|
||||
int py = y + core_height - 2 + t * 2;
|
||||
int radius = (t < 2) ? 2 : 1;
|
||||
place_redwood_leaf_disc(x, py, z, radius, x, z, 0, arch->leaf_block, rng, 0.04, 0.10, out);
|
||||
}
|
||||
|
||||
int dead_nubs = 5 + rng_range_inclusive(rng, 0, 3);
|
||||
for (int n = 0; n < dead_nubs; ++n) {
|
||||
int idx = rng_range_inclusive(rng, 0, 7);
|
||||
int nub_y = y + core_height / 4 + rng_range_inclusive(rng, 0, core_height / 3);
|
||||
int nub_len = 2 + rng_range_inclusive(rng, 0, 1);
|
||||
int branch_log = redwood_axis_log(arch->log_block, dirs8[idx][0], dirs8[idx][1]);
|
||||
for (int step = 2; step <= nub_len + 1; ++step) {
|
||||
block_list_push(out, x + dirs8[idx][0] * step, nub_y, z + dirs8[idx][1] * step, (uint16_t)branch_log);
|
||||
}
|
||||
}
|
||||
|
||||
int taper_start = core_height - 7;
|
||||
for (int dy = 0; dy < core_height; ++dy) {
|
||||
int radius = (dy >= taper_start) ? 0 : 1;
|
||||
for (int dx = -radius; dx <= radius; ++dx) {
|
||||
for (int dz = -radius; dz <= radius; ++dz) {
|
||||
if (radius == 1 && abs(dx) == 1 && abs(dz) == 1 && dy > 12 && dy < taper_start - 2) {
|
||||
int corner_seed = (dy + (dx > 0 ? 2 : 0) + (dz > 0 ? 5 : 0)) % 7;
|
||||
if (corner_seed == 0 || corner_seed == 3) continue;
|
||||
}
|
||||
block_list_push(out, x + dx, y + dy, z + dz, (uint16_t)arch->log_block);
|
||||
}
|
||||
}
|
||||
if (dy < taper_start - 4 && dy > 2 && (dy % 5) == 0) {
|
||||
int rib = (dy / 5 + rng_range_inclusive(rng, 0, 3)) & 3;
|
||||
block_list_push(out, x + dirs8[rib][0] * 2, y + dy, z + dirs8[rib][1] * 2, (uint16_t)arch->log_block);
|
||||
}
|
||||
}
|
||||
int spire = 3 + rng_range_inclusive(rng, 0, 2);
|
||||
place_log_column(x, y + core_height, z, spire, arch->log_block, out);
|
||||
int canopy_base = y + core_height - 6;
|
||||
for (int ring = 0; ring < 4; ++ring) {
|
||||
int radius = 4 - ring;
|
||||
if (radius < 2) radius = 2;
|
||||
place_leaf_circle(x, canopy_base + ring, z, radius, arch->leaf_block, rng, 0.1, out);
|
||||
place_leaf_circle(x, canopy_base + ring + 1, z, radius - 1, arch->leaf_block, rng, 0.18, out);
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
int root_len = 3 + rng_range_inclusive(rng, 0, (i < 4) ? 2 : 1);
|
||||
place_redwood_root(ctx, x, y, z, dirs8[i][0], dirs8[i][1], root_len, arch->log_block, rng, out);
|
||||
}
|
||||
place_leaf_circle(x, canopy_base + 5, z, 2, arch->leaf_block, rng, 0.0, out);
|
||||
place_leaf_circle(x, canopy_base + 6, z, 1, arch->leaf_block, rng, 0.0, out);
|
||||
const int dirs[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
int buttress_height = 3 + rng_range_inclusive(rng, 0, 2);
|
||||
for (int step = 0; step < 2; ++step) {
|
||||
int px = x + dirs[i][0] * (2 + step);
|
||||
int pz = z + dirs[i][1] * (2 + step);
|
||||
int stack = buttress_height - step;
|
||||
if (stack < 1) stack = 1;
|
||||
for (int s = 0; s < stack; ++s) {
|
||||
block_list_push(out, px, y + s, pz, (uint16_t)arch->log_block);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
int branch_y = canopy_base - 3 - rng_range_inclusive(rng, 0, 3);
|
||||
int branch_len = 3 + rng_range_inclusive(rng, 0, 2);
|
||||
place_branch_span(x, branch_y, z, dirs[i][0], dirs[i][1], branch_len, 2, arch->log_block, arch->leaf_block, rng, out);
|
||||
}
|
||||
place_leaf_blob(x, canopy_base - 2, z, 4, 3, arch->leaf_block, rng, out);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
@@ -1536,7 +1654,7 @@ static void build_redwood_titan(worldgen_ctx *ctx, int x, int y, int z, int heig
|
||||
[TREE_OAK_ANCIENT] = {"oak_ancient", TREE_SPECIES_OAK, BLOCK_OAK_LOG, BLOCK_OAK_LEAVES, 12, 16, 6, 7, build_oak_ancient},
|
||||
[TREE_SPRUCE_ANCIENT] = {"spruce_ancient", TREE_SPECIES_SPRUCE, BLOCK_OAK_LOG, BLOCK_OAK_LEAVES, 12, 16, 5, 7, build_spruce_ancient},
|
||||
[TREE_MAPLE_ANCIENT] = {"maple_ancient", TREE_SPECIES_MAPLE, BLOCK_OAK_LOG, BLOCK_OAK_LEAVES, 11, 15, 6, 6, build_maple_ancient},
|
||||
[TREE_REDWOOD_TITAN] = {"redwood_titan", TREE_SPECIES_PINE, BLOCK_OAK_LOG, BLOCK_OAK_LEAVES, 28, 38, 4, 10, build_redwood_titan},
|
||||
[TREE_REDWOOD_TITAN] = {"redwood_titan", TREE_SPECIES_PINE, BLOCK_OAK_LOG, BLOCK_OAK_LEAVES, 28, 38, 5, 11, build_redwood_titan},
|
||||
};
|
||||
|
||||
static const int TREE_VARIANTS_OAK[] = {TREE_OAK_ROUND, TREE_OAK_SPRAWL, TREE_OAK_COLUMNAR, TREE_OAK_ANCIENT};
|
||||
|
||||
Reference in New Issue
Block a user