Add stair ramps to border wall walks
This commit is contained in:
@@ -3643,6 +3643,99 @@ static void generate_chunk_trails(worldgen_ctx *ctx, int chunk_x, int chunk_z, c
|
||||
}
|
||||
}
|
||||
|
||||
static int border_wall_anchor_base(worldgen_ctx *ctx, int side, int anchor_along, int wall_center) {
|
||||
int center_x = anchor_along;
|
||||
int center_z = anchor_along;
|
||||
switch (side) {
|
||||
case 0:
|
||||
center_x = ctx->wall_min_x + wall_center;
|
||||
break;
|
||||
case 1:
|
||||
center_x = ctx->wall_max_x - wall_center;
|
||||
break;
|
||||
case 2:
|
||||
center_z = ctx->wall_min_z + wall_center;
|
||||
break;
|
||||
case 3:
|
||||
center_z = ctx->wall_max_z - wall_center;
|
||||
break;
|
||||
}
|
||||
|
||||
int smoothed_base = 0;
|
||||
int weight_sum = 0;
|
||||
int highest_sample_base = 0;
|
||||
const int sample_offsets[5] = {-32, -16, 0, 16, 32};
|
||||
const int sample_weights[5] = {1, 2, 4, 2, 1};
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
int sx = center_x;
|
||||
int sz = center_z;
|
||||
if (side < 2) {
|
||||
sz += sample_offsets[i];
|
||||
} else {
|
||||
sx += sample_offsets[i];
|
||||
}
|
||||
if (sx < ctx->wall_min_x) sx = ctx->wall_min_x;
|
||||
if (sx > ctx->wall_max_x) sx = ctx->wall_max_x;
|
||||
if (sz < ctx->wall_min_z) sz = ctx->wall_min_z;
|
||||
if (sz > ctx->wall_max_z) sz = ctx->wall_max_z;
|
||||
column_data sample = get_column_data(ctx, sx, sz);
|
||||
int sample_base = sample.height;
|
||||
if (sample.has_water && sample.water_surface > sample_base) sample_base = sample.water_surface;
|
||||
if (i == 0 || sample_base > highest_sample_base) highest_sample_base = sample_base;
|
||||
smoothed_base += sample_base * sample_weights[i];
|
||||
weight_sum += sample_weights[i];
|
||||
}
|
||||
smoothed_base /= weight_sum;
|
||||
if (highest_sample_base > smoothed_base + 8) {
|
||||
smoothed_base += (highest_sample_base - smoothed_base - 8 + 1) / 2;
|
||||
}
|
||||
if (smoothed_base < 1) smoothed_base = 1;
|
||||
if (smoothed_base > CHUNK_HEIGHT - 2) smoothed_base = CHUNK_HEIGHT - 2;
|
||||
return smoothed_base;
|
||||
}
|
||||
|
||||
static int border_wall_ramp_base(worldgen_ctx *ctx, int side, int along, int wall_center, int tower_spacing) {
|
||||
int anchor = floor_div_int(along + tower_spacing / 2, tower_spacing) * tower_spacing;
|
||||
int current_base = border_wall_anchor_base(ctx, side, anchor, wall_center);
|
||||
|
||||
int next_anchor = anchor + tower_spacing;
|
||||
int next_boundary = anchor + tower_spacing / 2;
|
||||
int next_base = border_wall_anchor_base(ctx, side, next_anchor, wall_center);
|
||||
int next_delta = next_base - current_base;
|
||||
if (next_delta != 0) {
|
||||
int next_span = clamp_int(abs(next_delta), 6, tower_spacing - 8);
|
||||
int next_start = next_boundary - next_span / 2;
|
||||
int next_end = next_start + next_span;
|
||||
if (along >= next_start && along <= next_end) {
|
||||
int progress = along - next_start;
|
||||
return current_base + (next_delta * progress + (next_delta > 0 ? next_span / 2 : -next_span / 2)) / next_span;
|
||||
}
|
||||
}
|
||||
|
||||
int prev_anchor = anchor - tower_spacing;
|
||||
int prev_boundary = anchor - tower_spacing / 2;
|
||||
int prev_base = border_wall_anchor_base(ctx, side, prev_anchor, wall_center);
|
||||
int prev_delta = current_base - prev_base;
|
||||
if (prev_delta != 0) {
|
||||
int prev_span = clamp_int(abs(prev_delta), 6, tower_spacing - 8);
|
||||
int prev_start = prev_boundary - prev_span / 2;
|
||||
int prev_end = prev_start + prev_span;
|
||||
if (along >= prev_start && along <= prev_end) {
|
||||
int progress = along - prev_start;
|
||||
return prev_base + (prev_delta * progress + (prev_delta > 0 ? prev_span / 2 : -prev_span / 2)) / prev_span;
|
||||
}
|
||||
}
|
||||
|
||||
return current_base;
|
||||
}
|
||||
|
||||
static uint16_t border_wall_ramp_stair_block(int side, int slope) {
|
||||
if (side < 2) {
|
||||
return (slope > 0) ? BLOCK_STONE_BRICK_STAIRS_S : BLOCK_STONE_BRICK_STAIRS_N;
|
||||
}
|
||||
return (slope > 0) ? BLOCK_STONE_BRICK_STAIRS_E : BLOCK_STONE_BRICK_STAIRS_W;
|
||||
}
|
||||
|
||||
static void generate_chunk_border_wall(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_data *out) {
|
||||
if (!ctx->enable_wall) return;
|
||||
if (ctx->wall_min_x > ctx->wall_max_x || ctx->wall_min_z > ctx->wall_max_z) return;
|
||||
@@ -3734,57 +3827,10 @@ static void generate_chunk_border_wall(worldgen_ctx *ctx, int chunk_x, int chunk
|
||||
continue;
|
||||
}
|
||||
|
||||
int center_x = world_x;
|
||||
int center_z = world_z;
|
||||
int base_along = floor_div_int(along + tower_spacing / 2, tower_spacing) * tower_spacing;
|
||||
switch (side) {
|
||||
case 0:
|
||||
center_x = ctx->wall_min_x + wall_center;
|
||||
center_z = base_along;
|
||||
break;
|
||||
case 1:
|
||||
center_x = ctx->wall_max_x - wall_center;
|
||||
center_z = base_along;
|
||||
break;
|
||||
case 2:
|
||||
center_x = base_along;
|
||||
center_z = ctx->wall_min_z + wall_center;
|
||||
break;
|
||||
case 3:
|
||||
center_x = base_along;
|
||||
center_z = ctx->wall_max_z - wall_center;
|
||||
break;
|
||||
}
|
||||
int smoothed_base = 0;
|
||||
int weight_sum = 0;
|
||||
int highest_sample_base = 0;
|
||||
const int sample_offsets[5] = {-32, -16, 0, 16, 32};
|
||||
const int sample_weights[5] = {1, 2, 4, 2, 1};
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
int sx = center_x;
|
||||
int sz = center_z;
|
||||
if (side < 2) {
|
||||
sz += sample_offsets[i];
|
||||
} else {
|
||||
sx += sample_offsets[i];
|
||||
}
|
||||
if (sx < ctx->wall_min_x) sx = ctx->wall_min_x;
|
||||
if (sx > ctx->wall_max_x) sx = ctx->wall_max_x;
|
||||
if (sz < ctx->wall_min_z) sz = ctx->wall_min_z;
|
||||
if (sz > ctx->wall_max_z) sz = ctx->wall_max_z;
|
||||
column_data sample = get_column_data(ctx, sx, sz);
|
||||
int sample_base = sample.height;
|
||||
if (sample.has_water && sample.water_surface > sample_base) sample_base = sample.water_surface;
|
||||
if (i == 0 || sample_base > highest_sample_base) highest_sample_base = sample_base;
|
||||
smoothed_base += sample_base * sample_weights[i];
|
||||
weight_sum += sample_weights[i];
|
||||
}
|
||||
smoothed_base /= weight_sum;
|
||||
if (highest_sample_base > smoothed_base + 8) {
|
||||
smoothed_base += (highest_sample_base - smoothed_base - 8 + 1) / 2;
|
||||
}
|
||||
if (smoothed_base < 1) smoothed_base = 1;
|
||||
if (smoothed_base > CHUNK_HEIGHT - 2) smoothed_base = CHUNK_HEIGHT - 2;
|
||||
int smoothed_base = border_wall_ramp_base(ctx, side, along, wall_center, tower_spacing);
|
||||
int prev_base = border_wall_ramp_base(ctx, side, along - 1, wall_center, tower_spacing);
|
||||
int next_base = border_wall_ramp_base(ctx, side, along + 1, wall_center, tower_spacing);
|
||||
int ramp_slope = next_base - prev_base;
|
||||
|
||||
int height = in_tower ? tower_height : wall_height;
|
||||
int top = smoothed_base + height;
|
||||
@@ -3819,7 +3865,9 @@ static void generate_chunk_border_wall(worldgen_ctx *ctx, int chunk_x, int chunk
|
||||
if (rel_y <= 2 || rel_y % 6 == 0 || rel_y == height - 1) {
|
||||
block = BLOCK_STONE_BRICKS;
|
||||
}
|
||||
if (side_dist >= wall_center - 1 && side_dist <= wall_center + 1 && rel_y == height) {
|
||||
if (side_dist >= wall_center - 1 && side_dist <= wall_center + 1 && rel_y == height && ramp_slope != 0) {
|
||||
block = border_wall_ramp_stair_block(side, ramp_slope);
|
||||
} else if (side_dist >= wall_center - 1 && side_dist <= wall_center + 1 && rel_y == height) {
|
||||
block = BLOCK_STONE_BRICKS;
|
||||
}
|
||||
if (ladder_face && rel_y >= 2 && rel_y <= height) {
|
||||
|
||||
Reference in New Issue
Block a user