3 #include "server/biomes.h"
4 #include "server/mapgen.h"
5 #include "server/trees.h"
6 #include "server/voxelctx.h"
11 static bool oak_condition(unused v3s32 pos, unused f64 humidity, unused f64 temperature, Biome biome, unused f64 factor, unused MapBlock *block, unused void *row_data, unused void *block_data)
13 return biome == BIOME_HILLS;
16 static void oak_tree_leaf(Voxelctx *ctx)
18 if (! voxelctx_is_alive(ctx))
22 voxelctx_cube(ctx, NODE_OAK_LEAVES, true);
26 voxelctx_x(ctx, 0.5f);
27 voxelctx_sx(ctx, 0.9f);
28 voxelctx_sy(ctx, 0.9f);
29 voxelctx_sz(ctx, 0.8f);
30 voxelctx_ry(ctx, 25.0f);
31 voxelctx_x(ctx, 0.4f);
36 static void oak_tree_top(Voxelctx *ctx)
38 if (! voxelctx_is_alive(ctx))
42 for (int i = 0; i < 8; i++) {
43 voxelctx_rz(ctx, 360.0f / 8.0f);
45 voxelctx_life(ctx, 8);
46 voxelctx_sy(ctx, 2.0f);
47 voxelctx_z(ctx, voxelctx_random(ctx, 0.0f, 5.0f));
48 voxelctx_s(ctx, 5.0f);
49 voxelctx_light(ctx, -0.4f);
50 voxelctx_sat(ctx, 0.5f);
51 voxelctx_hue(ctx, voxelctx_random(ctx, 60.0f, 20.0f));
52 voxelctx_ry(ctx, -45.0f);
59 static void oak_tree_part(Voxelctx *ctx, f32 n)
61 if (! voxelctx_is_alive(ctx))
65 for (int i = 1; i <= n; i++) {
66 voxelctx_z(ctx, 1.0f);
67 voxelctx_rz(ctx, voxelctx_random(ctx, 30.0f, 10.0f));
68 voxelctx_rx(ctx, voxelctx_random(ctx, 0.0f, 10.0f));
71 voxelctx_s(ctx, 4.0f);
72 voxelctx_x(ctx, 0.1f);
73 voxelctx_light(ctx, voxelctx_random(ctx, 0.0f, 0.1f));
74 //voxelctx_cylinder(ctx, NODE_OAK_WOOD, true);
75 voxelctx_cube(ctx, NODE_OAK_WOOD, true);
78 if (i == (int) (n - 2.0f)) {
87 static void oak_tree(v3s32 pos, List *changed_blocks)
89 Voxelctx *ctx = voxelctx_create(changed_blocks, MGS_TREES, pos);
91 voxelctx_hue(ctx, 40.0f);
92 voxelctx_light(ctx, -0.5f);
93 voxelctx_sat(ctx, 0.5f);
95 /*voxelctx_s(ctx, 50);
99 voxelctx_cube(ctx, NODE_OAK_LEAVES, true);
102 voxelctx_delete(ctx);
106 f32 n = voxelctx_random(ctx, 40.0f, 10.0f);
109 for (int i = 1; i <= 3; i++) {
110 voxelctx_rz(ctx, voxelctx_random(ctx, 120.0f, 45.0f));
112 voxelctx_y(ctx, 0.5f);
113 voxelctx_light(ctx, voxelctx_random(ctx, -0.3f, 0.05f));
114 oak_tree_part(ctx, n);
119 voxelctx_delete(ctx);
124 static bool pine_condition(unused v3s32 pos, unused f64 humidity, unused f64 temperature, Biome biome, unused f64 factor, unused MapBlock *block, unused void *row_data, unused void *block_data)
126 return biome == BIOME_MOUNTAIN;
129 static void pine_tree(v3s32 pos, List *changed_blocks)
131 s32 tree_top = (noise2d(pos.x, pos.z, 0, seed + SO_PINETREE_HEIGHT) * 0.5 + 0.5) * (35.0 - 20.0) + 20.0 + pos.y;
132 for (v3s32 tree_pos = pos; tree_pos.y < tree_top; tree_pos.y++) {
133 f64 branch_length = noise3d(tree_pos.x, tree_pos.y, tree_pos.z, 0, seed + SO_PINETREE_BRANCH) * 3.0;
142 s32 dir = (noise3d(tree_pos.x, tree_pos.y, tree_pos.z, 0, seed + SO_PINETREE_BRANCH_DIR) * 0.5 + 0.5) * 4.0;
144 for (v3s32 branch_pos = tree_pos; branch_length > 0; branch_length--, branch_pos = v3s32_add(branch_pos, dirs[dir]))
145 mapgen_set_node(branch_pos, map_node_create(NODE_PINE_WOOD, NULL, 0), MGS_TREES, changed_blocks);
147 mapgen_set_node(tree_pos, map_node_create(NODE_PINE_WOOD, NULL, 0), MGS_TREES, changed_blocks);
153 static bool palm_condition(v3s32 pos, unused f64 humidity, unused f64 temperature, Biome biome, unused f64 factor, unused MapBlock *block, void *row_data, unused void *block_data)
155 return biome == BIOME_OCEAN
156 && ocean_get_node_at((v3s32) {pos.x, pos.y - 0, pos.z}, 1, row_data) == NODE_AIR
157 && ocean_get_node_at((v3s32) {pos.x, pos.y - 1, pos.z}, 0, row_data) == NODE_SAND;
160 static void palm_branch(Voxelctx *ctx)
162 if (! voxelctx_is_alive(ctx))
165 voxelctx_cube(ctx, NODE_PALM_LEAVES, true);
167 voxelctx_z(ctx, 0.5f);
168 voxelctx_s(ctx, 0.8f);
169 voxelctx_rx(ctx, voxelctx_random(ctx, 20.0f, 4.0f));
170 voxelctx_z(ctx, 0.5f);
175 static void palm_tree(v3s32 pos, List *changed_blocks)
177 Voxelctx *ctx = voxelctx_create(changed_blocks, MGS_TREES, (v3s32) {pos.x, pos.y - 1, pos.z});
179 f32 s = voxelctx_random(ctx, 8.0f, 2.0f);
182 for (int i = 1; i <= s; i++) {
183 voxelctx_z(ctx, 1.0f);
185 voxelctx_s(ctx, 1.0f);
186 voxelctx_light(ctx, voxelctx_random(ctx, -0.8f, 0.1f));
187 voxelctx_sat(ctx, 0.5f);
188 voxelctx_cube(ctx, NODE_PALM_WOOD, true);
194 voxelctx_sat(ctx, 1.0f),
195 voxelctx_light(ctx, -0.5f);
196 voxelctx_hue(ctx, voxelctx_random(ctx, 50.0f, 30.0f));
199 for (int i = 0; i < 6; i++) {
200 voxelctx_rz(ctx, 360.0f / 6.0f);
201 voxelctx_rz(ctx, voxelctx_random(ctx, 0.0f, 10.0f));
203 voxelctx_light(ctx, voxelctx_random(ctx, 0.0f, 0.3f));
204 voxelctx_rx(ctx, 90.0f);
205 voxelctx_s(ctx, 2.0f);
211 voxelctx_delete(ctx);
214 TreeDef tree_definitions[NUM_TREES] = {
218 .probability = 0.0005f,
219 .area_probability = 0.3f,
220 .offset = SO_OAKTREE,
221 .area_offset = SO_OAKTREE_AREA,
222 .condition = &oak_condition,
223 .generate = &oak_tree,
228 .probability = 0.01f,
229 .area_probability = 0.1f,
230 .offset = SO_PINETREE,
231 .area_offset = SO_PINETREE_AREA,
232 .condition = &pine_condition,
233 .generate = &pine_tree,
238 .probability = 0.005f,
239 .area_probability = 0.5f,
240 .offset = SO_PALMTREE,
241 .area_offset = SO_PALMTREE_AREA,
242 .condition = &palm_condition,
243 .generate = &palm_tree,