Tune tree density/spacing and fix trail distance to use segments
- nearest_trail_distance2 now measures point-to-segment distance to each trail edge instead of only to stored points, with a single-point fallback. - Tree height scaling keeps canopy proportions; maturity adds subtle variation instead of shrinking young trees to bare poles. - Raise forest spawn probability and tighten spacing for denser, more coherent stands; redwoods cluster a bit closer. - Cabins near trails favor a wooded setback off the centerline; the spur still connects. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
@@ -2000,7 +2000,9 @@ static void generate_tree(worldgen_ctx *ctx, const tree_archetype *arch, int x,
|
||||
double maturity, rng_state *rng, block_list *out) {
|
||||
if (!arch) return;
|
||||
int height = rng_range_inclusive(rng, arch->min_height, arch->max_height);
|
||||
double height_scale = 0.62 + clamp01(maturity) * 0.38;
|
||||
/* Preserve the proportions expected by each canopy builder; maturity now
|
||||
* adds subtle height variation without reducing young trees to bare poles. */
|
||||
double height_scale = 0.86 + clamp01(maturity) * 0.14;
|
||||
height = (int)llround((double)height * height_scale);
|
||||
if (height < 4) height = 4;
|
||||
if (!can_place_tree(ctx, x, y, z, height, arch->space_radius, arch->canopy_extra)) {
|
||||
@@ -2972,10 +2974,10 @@ static void generate_chunk_cabins(worldgen_ctx *ctx, int chunk_x, int chunk_z, c
|
||||
double dist2 = nearest_trail_distance2(ctx, world_cx, world_cz, 1.0e12);
|
||||
double bonus = 0.0;
|
||||
double dist = sqrt(dist2);
|
||||
if (dist < 640.0) {
|
||||
double t = clamp01(1.0 - dist / 640.0);
|
||||
bonus += 0.45 * t;
|
||||
}
|
||||
/* Favor a wooded setback instead of putting the building footprint
|
||||
* directly on the centerline. The spur still handles the connection. */
|
||||
if (dist < 8.0) bonus -= (8.0 - dist) * 0.9;
|
||||
else if (dist < 96.0) bonus += 0.45 * clamp01(1.0 - fabs(dist - 20.0) / 76.0);
|
||||
score += bonus;
|
||||
}
|
||||
if (score > best_score) {
|
||||
@@ -3304,14 +3306,14 @@ static void generate_chunk_trees(worldgen_ctx *ctx, int chunk_x, int chunk_z, ch
|
||||
}
|
||||
/* Openings retain a few isolated field trees, while forest interiors
|
||||
* become substantially denser than their regenerating edges. */
|
||||
spawn_prob = (0.035 + density * 0.78) * altitude_factor;
|
||||
spawn_prob = (0.08 + density * 0.9) * altitude_factor;
|
||||
if (is_old_growth) {
|
||||
spawn_prob = clamp01(0.25 + grove_mask * 0.7) * altitude_factor;
|
||||
}
|
||||
}
|
||||
if (rng_next_f64(&rng) > spawn_prob) continue;
|
||||
double spacing = is_redwood ? (10.0 + (1.0 - stand_density) * 4.0)
|
||||
: (4.5 + (1.0 - cover) * 4.5 + maturity * 1.5);
|
||||
double spacing = is_redwood ? (8.0 + (1.0 - stand_density) * 3.0)
|
||||
: (3.5 + (1.0 - cover) * 2.5 + maturity * 0.75);
|
||||
if (!tree_wins_spacing(ctx, gx, gz, grid, candidate_x, candidate_z, spacing)) continue;
|
||||
|
||||
block_list tmp;
|
||||
@@ -3582,11 +3584,15 @@ static double nearest_trail_distance2(worldgen_ctx *ctx, int x, int z, double fa
|
||||
for (size_t i = 0; i < ctx->trail_segment_count; ++i) {
|
||||
trail_segment *seg = &ctx->trail_segments[i];
|
||||
if (!seg || seg->count < 1 || !seg->points) continue;
|
||||
for (int p = 0; p < seg->count; ++p) {
|
||||
int tx = seg->points[p * 2];
|
||||
int tz = seg->points[p * 2 + 1];
|
||||
double dx = (double)(tx - x);
|
||||
double dz = (double)(tz - z);
|
||||
for (int p = 0; p < seg->count - 1; ++p) {
|
||||
double d2 = point_segment_distance2((double)x, (double)z,
|
||||
(double)seg->points[p * 2], (double)seg->points[p * 2 + 1],
|
||||
(double)seg->points[(p + 1) * 2], (double)seg->points[(p + 1) * 2 + 1]);
|
||||
if (d2 < best) best = d2;
|
||||
}
|
||||
if (seg->count == 1) {
|
||||
double dx = (double)(seg->points[0] - x);
|
||||
double dz = (double)(seg->points[1] - z);
|
||||
double d2 = dx * dx + dz * dz;
|
||||
if (d2 < best) best = d2;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user