3 #include "environment.h"
5 #include "server/biomes.h"
6 #include "server/server_node.h"
7 #include "server/server_terrain.h"
8 #include "server/terrain_gen.h"
9 #include "server/tree.h"
11 s32 terrain_gen_get_base_height(v2s32 pos)
14 * (pnoise2d(U32(pos.x) / 32.0, U32(pos.y) / 32.0, 0.45, 5, seed + OFFSET_HEIGHT) * 16.0 + 0.0)
15 * (pnoise2d(U32(pos.x) / 256.0, U32(pos.y) / 256.0, 0.45, 5, seed + OFFSET_HILLYNESS) * 0.5 + 0.5)
19 // generate a chunk (does not manage chunk state or threading)
20 void terrain_gen_chunk(TerrainChunk *chunk, List *changed_chunks)
22 TerrainChunkMeta *meta = chunk->extra;
24 BiomeArgsChunk chunk_args;
25 BiomeArgsRow row_args;
26 BiomeArgsHeight height_args;
27 BiomeArgsGenerate generate_args;
28 TreeArgsCondition condition_args;
30 chunk_args.chunk = condition_args.chunk = chunk;
31 chunk_args.changed_chunks = generate_args.changed_chunks = changed_chunks;
34 chunk->pos.x * CHUNK_SIZE,
35 chunk->pos.y * CHUNK_SIZE,
36 chunk->pos.z * CHUNK_SIZE,
39 unsigned char *chunk_data[COUNT_BIOME] = {NULL};
40 bool has_biome[COUNT_BIOME] = {false};
42 for (s32 x = 0; x < CHUNK_SIZE; x++) {
43 s32 pos_x = chunkp.x + x;
45 for (s32 z = 0; z < CHUNK_SIZE; z++) {
46 row_args.pos = height_args.pos = (v2s32) {pos_x, chunkp.z + z};
48 condition_args.biome = get_biome(row_args.pos, &condition_args.factor);
49 BiomeDef *biome_def = &biomes[condition_args.biome];
51 height_args.factor = generate_args.factor = row_args.factor
52 = condition_args.factor;
54 if (biome_def->chunk_data_size && !chunk_data[condition_args.biome])
55 chunk_data[condition_args.biome] = malloc(biome_def->chunk_data_size);
57 chunk_args.chunk_data = row_args.chunk_data = height_args.chunk_data =
58 generate_args.chunk_data = condition_args.chunk_data =
59 chunk_data[condition_args.biome];
61 if (!has_biome[condition_args.biome]) {
62 if (biome_def->before_chunk)
63 biome_def->before_chunk(&chunk_args);
65 has_biome[condition_args.biome] = true;
68 unsigned char row_data[biome_def->row_data_size];
69 row_args.row_data = height_args.row_data = generate_args.row_data =
70 condition_args.row_data = row_data;
72 if (biome_def->before_row)
73 biome_def->before_row(&row_args);
75 height_args.height = terrain_gen_get_base_height(height_args.pos);
76 s32 height = biome_def->height(&height_args);
78 for (s32 y = 0; y < CHUNK_SIZE; y++) {
79 generate_args.offset = (v3s32) {x, y, z};
81 generate_args.pos = condition_args.pos = (v3s32)
82 {row_args.pos.x, chunkp.y + y, row_args.pos.y};
83 generate_args.diff = generate_args.pos.y - height;
85 generate_args.humidity = condition_args.humidity =
86 get_humidity(generate_args.pos);
87 generate_args.temperature = condition_args.temperature =
88 get_temperature(generate_args.pos);
90 NodeType node = biome_def->generate(&generate_args);
93 && generate_args.diff <= 1
94 && generate_args.temperature < 0.0
98 if (generate_args.diff == 1) for (int i = 0; i < NUM_TREES; i++) {
99 TreeDef *def = &tree_def[i];
101 if (def->condition(&condition_args)
102 && noise2d(condition_args.pos.x, condition_args.pos.z, 0, seed + def->offset) * 0.5 + 0.5 < def->probability
103 && 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) {
104 def->generate(condition_args.pos, changed_chunks);
109 terrain_lock_chunk(chunk);
110 if (meta->tgsb.raw.nodes[x][y][z] <= STAGE_TERRAIN) {
111 chunk->data[x][y][z] = server_node_create(node);
112 meta->tgsb.raw.nodes[x][y][z] = STAGE_TERRAIN;
114 pthread_mutex_unlock(&chunk->mtx);
117 if (biome_def->after_row)
118 biome_def->after_row(&row_args);
122 for (Biome i = 0; i < COUNT_BIOME; i++) {
124 chunk_args.chunk_data = chunk_data[i];
126 if (biomes[i].after_chunk)
127 biomes[i].after_chunk(&chunk_args);
129 if (chunk_args.chunk_data)
130 free(chunk_args.chunk_data);