4 #include "environment.h"
6 #include "server/biomes.h"
7 #include "server/server_node.h"
8 #include "server/server_terrain.h"
9 #include "server/terrain_gen.h"
10 #include "server/tree.h"
12 s32 terrain_gen_get_base_height(v2s32 pos)
15 * (pnoise2d(U32(pos.x) / 32.0, U32(pos.y) / 32.0, 0.45, 5, seed + OFFSET_HEIGHT) * 16.0 + 0.0)
16 * (pnoise2d(U32(pos.x) / 256.0, U32(pos.y) / 256.0, 0.45, 5, seed + OFFSET_HILLYNESS) * 0.5 + 0.5)
20 // generate a chunk (does not manage chunk state or threading)
21 void terrain_gen_chunk(TerrainChunk *chunk, List *changed_chunks)
23 TerrainChunkMeta *meta = chunk->extra;
25 BiomeArgsChunk chunk_args;
26 BiomeArgsRow row_args;
27 BiomeArgsHeight height_args;
28 BiomeArgsGenerate generate_args;
29 TreeArgsCondition condition_args;
31 chunk_args.chunk = condition_args.chunk = chunk;
32 chunk_args.changed_chunks = generate_args.changed_chunks = changed_chunks;
35 chunk->pos.x * CHUNK_SIZE,
36 chunk->pos.y * CHUNK_SIZE,
37 chunk->pos.z * CHUNK_SIZE,
40 unsigned char *chunk_data[COUNT_BIOME] = {NULL};
41 bool has_biome[COUNT_BIOME] = {false};
43 for (s32 x = 0; x < CHUNK_SIZE; x++) {
44 s32 pos_x = chunkp.x + x;
46 for (s32 z = 0; z < CHUNK_SIZE; z++) {
47 row_args.pos = height_args.pos = (v2s32) {pos_x, chunkp.z + z};
49 condition_args.biome = get_biome(row_args.pos, &condition_args.factor);
50 BiomeDef *biome_def = &biomes[condition_args.biome];
52 height_args.factor = generate_args.factor = row_args.factor
53 = condition_args.factor;
55 if (biome_def->chunk_data_size && !chunk_data[condition_args.biome])
56 chunk_data[condition_args.biome] = malloc(biome_def->chunk_data_size);
58 chunk_args.chunk_data = row_args.chunk_data = height_args.chunk_data =
59 generate_args.chunk_data = condition_args.chunk_data =
60 chunk_data[condition_args.biome];
62 if (!has_biome[condition_args.biome]) {
63 if (biome_def->before_chunk)
64 biome_def->before_chunk(&chunk_args);
66 has_biome[condition_args.biome] = true;
69 unsigned char row_data[biome_def->row_data_size];
70 row_args.row_data = height_args.row_data = generate_args.row_data =
71 condition_args.row_data = row_data;
73 if (biome_def->before_row)
74 biome_def->before_row(&row_args);
76 height_args.height = terrain_gen_get_base_height(height_args.pos);
77 s32 height = biome_def->height(&height_args);
79 for (s32 y = 0; y < CHUNK_SIZE; y++) {
80 generate_args.offset = (v3s32) {x, y, z};
82 generate_args.pos = condition_args.pos = (v3s32)
83 {row_args.pos.x, chunkp.y + y, row_args.pos.y};
84 generate_args.diff = generate_args.pos.y - height;
86 generate_args.humidity = condition_args.humidity =
87 get_humidity(generate_args.pos);
88 generate_args.temperature = condition_args.temperature =
89 get_temperature(generate_args.pos);
91 NodeType node = biome_def->generate(&generate_args);
94 && generate_args.diff <= 1
95 && generate_args.temperature < 0.0
99 if (generate_args.diff == 1) for (int i = 0; i < NUM_TREES; i++) {
100 TreeDef *def = &tree_def[i];
102 if (def->condition(&condition_args)
103 && noise2d(condition_args.pos.x, condition_args.pos.z, 0, seed + def->offset) * 0.5 + 0.5 < def->probability
104 && smooth2d(U32(condition_args.pos.x) / def->spread, U32(condition_args.pos.z) / def->spread, 0, seed + def->area_offset) * 0.5 + 0.5 < def->area_probability) {
105 def->generate(condition_args.pos, changed_chunks);
110 assert(pthread_rwlock_wrlock(&chunk->lock) == 0);
111 if (meta->tgsb.raw.nodes[x][y][z] <= STAGE_TERRAIN) {
112 chunk->data[x][y][z] = server_node_create(node);
113 meta->tgsb.raw.nodes[x][y][z] = STAGE_TERRAIN;
115 pthread_rwlock_unlock(&chunk->lock);
118 if (biome_def->after_row)
119 biome_def->after_row(&row_args);
123 for (Biome i = 0; i < COUNT_BIOME; i++) {
125 chunk_args.chunk_data = chunk_data[i];
127 if (biomes[i].after_chunk)
128 biomes[i].after_chunk(&chunk_args);
130 if (chunk_args.chunk_data)
131 free(chunk_args.chunk_data);