Remove river carving and add flowers
This commit is contained in:
Binary file not shown.
@@ -23,7 +23,8 @@
|
|||||||
BLOCK_SAND = 11,
|
BLOCK_SAND = 11,
|
||||||
BLOCK_GRAVEL = 12,
|
BLOCK_GRAVEL = 12,
|
||||||
BLOCK_SNOW = 13,
|
BLOCK_SNOW = 13,
|
||||||
BLOCK_TALL_GRASS = 14
|
BLOCK_TALL_GRASS = 14,
|
||||||
|
BLOCK_WILDFLOWER = 15
|
||||||
};
|
};
|
||||||
|
|
||||||
struct trail_segment;
|
struct trail_segment;
|
||||||
|
|||||||
@@ -93,7 +93,8 @@ static const block_state BLOCK_STATE_TABLE[] = {
|
|||||||
[BLOCK_SAND] = {"minecraft:sand", NULL, 0},
|
[BLOCK_SAND] = {"minecraft:sand", NULL, 0},
|
||||||
[BLOCK_GRAVEL] = {"minecraft:gravel", NULL, 0},
|
[BLOCK_GRAVEL] = {"minecraft:gravel", NULL, 0},
|
||||||
[BLOCK_SNOW] = {"minecraft:snow", NULL, 0},
|
[BLOCK_SNOW] = {"minecraft:snow", NULL, 0},
|
||||||
[BLOCK_TALL_GRASS] = {"minecraft:grass", NULL, 0}
|
[BLOCK_TALL_GRASS] = {"minecraft:grass", NULL, 0},
|
||||||
|
[BLOCK_WILDFLOWER] = {"minecraft:poppy", NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const block_state *get_block_state(uint16_t id) {
|
static const block_state *get_block_state(uint16_t id) {
|
||||||
|
|||||||
@@ -119,11 +119,12 @@ static inline double clamp01(double v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int ground_slope(worldgen_ctx *ctx, int x, int z);
|
static int ground_slope(worldgen_ctx *ctx, int x, int z);
|
||||||
static void apply_flat_river(worldgen_ctx *ctx, int x, int z, column_data *data);
|
|
||||||
static uint16_t select_surface_block(worldgen_ctx *ctx, const column_data *data, int world_x, int world_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_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_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 trail_node_position(worldgen_ctx *ctx, int node_x, int node_z, double spacing, double *out_x, double *out_z);
|
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_plains_mask(worldgen_ctx *ctx, int x, int z);
|
||||||
static double old_growth_grove_mask(worldgen_ctx *ctx, int x, int z);
|
static double old_growth_grove_mask(worldgen_ctx *ctx, int x, int z);
|
||||||
|
|
||||||
@@ -343,36 +344,10 @@ static column_data get_column_data(worldgen_ctx *ctx, int x, int z) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply_flat_river(ctx, x, z, &data);
|
|
||||||
data.biome = classify_biome(ctx, x, z, data.height);
|
data.biome = classify_biome(ctx, x, z, data.height);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apply_flat_river(worldgen_ctx *ctx, int x, int z, column_data *data) {
|
|
||||||
if (data->is_local_basin) return;
|
|
||||||
if (data->height > ctx->sea_level + 8) return;
|
|
||||||
double warp_x = x + simplex_noise2(&ctx->noise, x * 0.004, z * 0.004) * 25.0;
|
|
||||||
double warp_z = z + simplex_noise2(&ctx->noise, (x + 12000) * 0.004, (z - 12000) * 0.004) * 25.0;
|
|
||||||
double river_noise = simplex_noise2(&ctx->noise, warp_x * 0.0005, warp_z * 0.0005);
|
|
||||||
double channel = 1.0 - fabs(river_noise);
|
|
||||||
if (channel < 0.985) return;
|
|
||||||
double strength = (channel - 0.985) / 0.015;
|
|
||||||
if (strength > 1.0) strength = 1.0;
|
|
||||||
if (strength < 0.0) strength = 0.0;
|
|
||||||
int surface = ctx->sea_level - 1;
|
|
||||||
if (surface < 2) surface = 2;
|
|
||||||
int depth = 2 + (int)(strength * 3.5);
|
|
||||||
int target_height = surface - depth;
|
|
||||||
if (target_height < 1) target_height = 1;
|
|
||||||
if (target_height >= data->height) return;
|
|
||||||
data->height = target_height;
|
|
||||||
data->has_water = 1;
|
|
||||||
data->water_surface = surface;
|
|
||||||
data->basin_rim = surface;
|
|
||||||
data->basin_depth = surface - target_height;
|
|
||||||
data->is_local_basin = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Ore generation (coal seams)
|
// Ore generation (coal seams)
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -1270,7 +1245,60 @@ static void generate_chunk_grass(worldgen_ctx *ctx, int chunk_x, int chunk_z, co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void generate_chunk_trees(worldgen_ctx *ctx, int chunk_x, int chunk_z, block_list *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) {
|
||||||
|
for (int dx = 0; dx < CHUNK_SIZE; ++dx) {
|
||||||
|
for (int dz = 0; dz < CHUNK_SIZE; ++dz) {
|
||||||
|
column_data cd = columns[dx][dz];
|
||||||
|
if (cd.height <= 0 || cd.height >= CHUNK_HEIGHT - 2) continue;
|
||||||
|
int world_x = chunk_x * CHUNK_SIZE + dx;
|
||||||
|
int world_z = chunk_z * CHUNK_SIZE + dz;
|
||||||
|
if (out->blocks[cd.height][dx][dz] != BLOCK_GRASS) continue;
|
||||||
|
if (out->blocks[cd.height + 1][dx][dz] != BLOCK_AIR) continue;
|
||||||
|
int slope = ground_slope(ctx, world_x, world_z);
|
||||||
|
if (slope > 3) continue;
|
||||||
|
double meadow = simplex_noise2(&ctx->noise, (world_x + 5400) * 0.012, (world_z - 5400) * 0.012) * 0.5 + 0.5;
|
||||||
|
double bloom = simplex_noise2(&ctx->noise, (world_x - 8100) * 0.0035, (world_z + 8100) * 0.0035) * 0.5 + 0.5;
|
||||||
|
double humidity = simplex_noise2(&ctx->noise, (world_x + 12000) * 0.0045, (world_z - 12000) * 0.0045) * 0.5 + 0.5;
|
||||||
|
double fertility = clamp01(meadow * 0.6 + humidity * 0.4);
|
||||||
|
double chance = 0.03 + fertility * 0.18 + bloom * 0.12;
|
||||||
|
if (cd.height < ctx->sea_level) chance *= 0.6;
|
||||||
|
double slope_penalty = clamp01((double)slope / 4.0);
|
||||||
|
chance *= (1.0 - slope_penalty * 0.7);
|
||||||
|
uint32_t h = hash_coords(world_x + 30000, world_z - 30000, (uint32_t)(ctx->world_seed ^ 0xA511E9B5u));
|
||||||
|
double roll = (double)(h & 0xFFFF) / 65535.0;
|
||||||
|
if (roll > chance) continue;
|
||||||
|
out->blocks[cd.height + 1][dx][dz] = BLOCK_WILDFLOWER;
|
||||||
|
static const int offsets[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
int nx = dx + offsets[i][0];
|
||||||
|
int nz = dz + offsets[i][1];
|
||||||
|
if (nx < 0 || nx >= CHUNK_SIZE || nz < 0 || nz >= CHUNK_SIZE) continue;
|
||||||
|
column_data nd = columns[nx][nz];
|
||||||
|
if (nd.height <= 0 || nd.height >= CHUNK_HEIGHT - 2) continue;
|
||||||
|
if (out->blocks[nd.height][nx][nz] != BLOCK_GRASS) continue;
|
||||||
|
if (out->blocks[nd.height + 1][nx][nz] != BLOCK_AIR) continue;
|
||||||
|
uint32_t nh = hash_coords(world_x + offsets[i][0] + 60000, world_z + offsets[i][1] - 60000, (uint32_t)(ctx->world_seed ^ 0xF00DBAAu));
|
||||||
|
if ((nh & 0xFFFF) > 24000) continue;
|
||||||
|
out->blocks[nd.height + 1][nx][nz] = BLOCK_WILDFLOWER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int column_has_trail_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;
|
||||||
|
for (int y = CHUNK_HEIGHT - 2; y >= 1; --y) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void generate_chunk_trees(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_data *chunk, block_list *out) {
|
||||||
const int grid = 5;
|
const int grid = 5;
|
||||||
const int margin = 4;
|
const int margin = 4;
|
||||||
const int min_tree_alt = ctx->sea_level - 2;
|
const int min_tree_alt = ctx->sea_level - 2;
|
||||||
@@ -1345,6 +1373,10 @@ static void generate_chunk_trees(worldgen_ctx *ctx, int chunk_x, int chunk_z, bl
|
|||||||
if (surface == BLOCK_SNOW) {
|
if (surface == BLOCK_SNOW) {
|
||||||
base_y = data.height;
|
base_y = data.height;
|
||||||
}
|
}
|
||||||
|
if (column_has_trail_surface(chunk, chunk_x, chunk_z, candidate_x, candidate_z)) {
|
||||||
|
block_list_free(&tmp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
generate_tree(ctx, arch, candidate_x, base_y, candidate_z, &rng, &tmp);
|
generate_tree(ctx, arch, candidate_x, base_y, candidate_z, &rng, &tmp);
|
||||||
if (tmp.count == 0) {
|
if (tmp.count == 0) {
|
||||||
block_list_free(&tmp);
|
block_list_free(&tmp);
|
||||||
@@ -1408,6 +1440,7 @@ static uint32_t trail_segment_hash(int ax, int az, int bx, int bz, uint32_t seed
|
|||||||
|
|
||||||
static int should_connect_trail_nodes(worldgen_ctx *ctx, int node_x0, int node_z0, int node_x1, int node_z1) {
|
static int should_connect_trail_nodes(worldgen_ctx *ctx, int node_x0, int node_z0, int node_x1, int node_z1) {
|
||||||
if (node_x0 == node_x1 && node_z0 == node_z1) return 0;
|
if (node_x0 == node_x1 && node_z0 == node_z1) return 0;
|
||||||
|
uint32_t seg_hash = trail_segment_hash(node_x0, node_z0, node_x1, node_z1, (uint32_t)ctx->world_seed ^ 0xB37D4A91u);
|
||||||
double ax, az, bx, bz;
|
double ax, az, bx, bz;
|
||||||
trail_node_position(ctx, node_x0, node_z0, TRAIL_NODE_SPACING, &ax, &az);
|
trail_node_position(ctx, node_x0, node_z0, TRAIL_NODE_SPACING, &ax, &az);
|
||||||
trail_node_position(ctx, node_x1, node_z1, TRAIL_NODE_SPACING, &bx, &bz);
|
trail_node_position(ctx, node_x1, node_z1, TRAIL_NODE_SPACING, &bx, &bz);
|
||||||
@@ -1447,20 +1480,28 @@ static int should_connect_trail_nodes(worldgen_ctx *ctx, int node_x0, int node_z
|
|||||||
} else {
|
} else {
|
||||||
base += 0.05;
|
base += 0.05;
|
||||||
}
|
}
|
||||||
if (dx == 0.0 || dz == 0.0) {
|
int axis_edge = (dx == 0.0 || dz == 0.0);
|
||||||
base += 0.05;
|
if (axis_edge) {
|
||||||
|
double corridor = simplex_noise2(&ctx->noise, (mid_x + 50000.0) * 0.0007, (mid_z - 50000.0) * 0.0007) * 0.5 + 0.5;
|
||||||
|
double penalty = 0.22 + corridor * 0.3;
|
||||||
|
base -= penalty;
|
||||||
|
if (grid_len <= 1.05) {
|
||||||
|
double axis_gate = 0.22 + corridor * 0.35;
|
||||||
|
double axis_rand = ((seg_hash >> 8) & 0xFFFF) / 65535.0;
|
||||||
|
if (axis_rand > axis_gate) {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
if (dx == dz && dx > 0.1) {
|
}
|
||||||
base += 0.03;
|
} else if (dx == dz && dx > 0.1) {
|
||||||
|
base += 0.07;
|
||||||
}
|
}
|
||||||
base += (alignment - 0.5) * 0.2;
|
base += (alignment - 0.5) * 0.2;
|
||||||
base += (ridge_bias - 0.5) * 0.15;
|
base += (ridge_bias - 0.5) * 0.15;
|
||||||
double texture = simplex_noise2(&ctx->noise, mid_x * 0.0012, mid_z * 0.0012) * 0.5 + 0.5;
|
double texture = simplex_noise2(&ctx->noise, mid_x * 0.0012, mid_z * 0.0012) * 0.5 + 0.5;
|
||||||
base += (texture - 0.5) * 0.15;
|
base += (texture - 0.5) * 0.15;
|
||||||
if (base < 0.02) base = 0.02;
|
if (base < 0.02) base = 0.02;
|
||||||
if (base > 0.9) base = 0.9;
|
if (base > 0.85) base = 0.85;
|
||||||
uint32_t h = trail_segment_hash(node_x0, node_z0, node_x1, node_z1, (uint32_t)ctx->world_seed ^ 0xB37D4A91u);
|
double r = (seg_hash + 1.0) / 4294967296.0;
|
||||||
double r = (h + 1.0) / 4294967296.0;
|
|
||||||
return r < base;
|
return r < base;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1670,18 +1711,46 @@ static void place_trail_column(chunk_data *out, column_data columns[CHUNK_SIZE][
|
|||||||
columns[local_x][local_z].height = target_height;
|
columns[local_x][local_z].height = target_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
if (radius < 1) radius = 1;
|
||||||
|
(void)ctx;
|
||||||
|
int radius_sq = radius * radius;
|
||||||
|
for (int dz = -radius; dz <= radius; ++dz) {
|
||||||
|
for (int dx = -radius; dx <= radius; ++dx) {
|
||||||
|
if (dx * dx + dz * dz > radius_sq) continue;
|
||||||
|
int wx = center_x + dx;
|
||||||
|
int wz = center_z + dz;
|
||||||
|
place_trail_column(out, columns, chunk_x, chunk_z, wx, wz, target_height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void carve_trail_span(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_data *out, column_data columns[CHUNK_SIZE][CHUNK_SIZE], int x0, int z0, int x1, int z1, int width) {
|
static void carve_trail_span(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_data *out, column_data columns[CHUNK_SIZE][CHUNK_SIZE], int x0, int z0, int x1, int z1, int width) {
|
||||||
int dx = abs(x1 - x0);
|
double tx = (double)(x1 - x0);
|
||||||
int sx = (x0 < x1) ? 1 : -1;
|
double tz = (double)(z1 - z0);
|
||||||
int dz = abs(z1 - z0);
|
double len = sqrt(tx * tx + tz * tz);
|
||||||
int sz = (z0 < z1) ? 1 : -1;
|
|
||||||
int err = dx - dz;
|
|
||||||
int last_height = INT32_MIN;
|
|
||||||
const int max_step_up = 1;
|
const int max_step_up = 1;
|
||||||
const int max_step_down = 1;
|
const int max_step_down = 1;
|
||||||
const double carry_weight = 0.65;
|
const double carry_weight = 0.65;
|
||||||
while (1) {
|
if (len < 0.0001) {
|
||||||
column_data data = get_column_data(ctx, x0, z0);
|
column_data data = get_column_data(ctx, x0, z0);
|
||||||
|
carve_trail_pad(ctx, chunk_x, chunk_z, out, columns, x0, z0, width - 1, data.height);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int steps = (int)ceil(len / 0.5);
|
||||||
|
if (steps < 1) steps = 1;
|
||||||
|
double nx = -tz / len;
|
||||||
|
double nz = tx / len;
|
||||||
|
int last_height = INT32_MIN;
|
||||||
|
int start_height = INT32_MIN;
|
||||||
|
double half_width = (double)width / 2.0;
|
||||||
|
for (int i = 0; i <= steps; ++i) {
|
||||||
|
double t = (double)i / (double)steps;
|
||||||
|
double px = x0 + tx * t;
|
||||||
|
double pz = z0 + tz * t;
|
||||||
|
int wx = (int)llround(px);
|
||||||
|
int wz = (int)llround(pz);
|
||||||
|
column_data data = get_column_data(ctx, wx, wz);
|
||||||
int target = data.height;
|
int target = data.height;
|
||||||
if (last_height != INT32_MIN) {
|
if (last_height != INT32_MIN) {
|
||||||
double blended = carry_weight * (double)last_height + (1.0 - carry_weight) * (double)target;
|
double blended = carry_weight * (double)last_height + (1.0 - carry_weight) * (double)target;
|
||||||
@@ -1691,31 +1760,27 @@ static void carve_trail_span(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_
|
|||||||
} else if (target < last_height - max_step_down) {
|
} else if (target < last_height - max_step_down) {
|
||||||
target = last_height - max_step_down;
|
target = last_height - max_step_down;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
start_height = target;
|
||||||
}
|
}
|
||||||
last_height = target;
|
last_height = target;
|
||||||
double tx = x1 - x0;
|
for (double w = -half_width; w <= half_width + 0.01; w += 0.5) {
|
||||||
double tz = z1 - z0;
|
double ox = px + nx * w;
|
||||||
double len = sqrt(tx * tx + tz * tz);
|
double oz = pz + nz * w;
|
||||||
double nx = 0.0, nz = 0.0;
|
int fx = (int)llround(ox);
|
||||||
if (len > 0.0001) {
|
int fz = (int)llround(oz);
|
||||||
nx = -tz / len;
|
place_trail_column(out, columns, chunk_x, chunk_z, fx, fz, target);
|
||||||
nz = tx / len;
|
|
||||||
}
|
}
|
||||||
for (int w = -width / 2; w <= width / 2; ++w) {
|
|
||||||
int wx = x0 + (int)llround(nx * w);
|
|
||||||
int wz = z0 + (int)llround(nz * w);
|
|
||||||
place_trail_column(out, columns, chunk_x, chunk_z, wx, wz, target);
|
|
||||||
}
|
}
|
||||||
if (x0 == x1 && z0 == z1) break;
|
int pad_radius = width - 1;
|
||||||
int err2 = 2 * err;
|
int dx = x1 - x0;
|
||||||
if (err2 > -dz) {
|
int dz = z1 - z0;
|
||||||
err -= dz;
|
int use_pads = (abs(dx) > 0 && abs(dz) > 0);
|
||||||
x0 += sx;
|
if (use_pads && start_height != INT32_MIN) {
|
||||||
}
|
carve_trail_pad(ctx, chunk_x, chunk_z, out, columns, x0, z0, pad_radius, start_height);
|
||||||
if (err2 < dx) {
|
|
||||||
err += dx;
|
|
||||||
z0 += sz;
|
|
||||||
}
|
}
|
||||||
|
if (use_pads && last_height != INT32_MIN) {
|
||||||
|
carve_trail_pad(ctx, chunk_x, chunk_z, out, columns, x1, z1, pad_radius, last_height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1822,11 +1887,12 @@ void worldgen_generate_chunk(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_
|
|||||||
}
|
}
|
||||||
|
|
||||||
generate_chunk_grass(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);
|
||||||
|
|
||||||
// Tree overlay
|
// Tree overlay
|
||||||
block_list trees;
|
block_list trees;
|
||||||
block_list_init(&trees);
|
block_list_init(&trees);
|
||||||
generate_chunk_trees(ctx, chunk_x, chunk_z, &trees);
|
generate_chunk_trees(ctx, chunk_x, chunk_z, out, &trees);
|
||||||
for (size_t i = 0; i < trees.count; ++i) {
|
for (size_t i = 0; i < trees.count; ++i) {
|
||||||
int lx = trees.items[i].x - chunk_x * CHUNK_SIZE;
|
int lx = trees.items[i].x - chunk_x * CHUNK_SIZE;
|
||||||
int lz = trees.items[i].z - chunk_z * CHUNK_SIZE;
|
int lz = trees.items[i].z - chunk_z * CHUNK_SIZE;
|
||||||
|
|||||||
Reference in New Issue
Block a user