Update helptext of obsidian
[MineClone/MineClone2.git] / mods / MAPGEN / mcl_mapgen_core / init.lua
blobe292ac25de49538a5f762c8cc365eeb602982e82
1 --
2 -- Aliases for map generator outputs
3 --
5 minetest.register_alias("mapgen_air", "air")
6 minetest.register_alias("mapgen_stone", "mcl_core:stone")
7 minetest.register_alias("mapgen_tree", "mcl_core:tree")
8 minetest.register_alias("mapgen_leaves", "mcl_core:leaves")
9 minetest.register_alias("mapgen_jungletree", "mcl_core:jungletree")
10 minetest.register_alias("mapgen_jungleleaves", "mcl_core:jungleleaves")
11 minetest.register_alias("mapgen_pine_tree", "mcl_core:sprucetree")
12 minetest.register_alias("mapgen_pine_needles", "mcl_core:spruceleaves")
14 minetest.register_alias("mapgen_apple", "mcl_core:leaves")
15 minetest.register_alias("mapgen_water_source", "mcl_core:water_source")
16 minetest.register_alias("mapgen_dirt", "mcl_core:dirt")
17 minetest.register_alias("mapgen_dirt_with_grass", "mcl_core:dirt_with_grass")
18 minetest.register_alias("mapgen_dirt_with_snow", "mcl_core:dirt_with_grass_snow")
19 minetest.register_alias("mapgen_sand", "mcl_core:sand")
20 minetest.register_alias("mapgen_gravel", "mcl_core:gravel")
21 minetest.register_alias("mapgen_clay", "mcl_core:clay")
22 minetest.register_alias("mapgen_lava_source", "air") -- Built-in lava generator is too unpredictable, we generate lava on our own
23 minetest.register_alias("mapgen_cobble", "mcl_core:cobble")
24 minetest.register_alias("mapgen_mossycobble", "mcl_core:mossycobble")
25 minetest.register_alias("mapgen_junglegrass", "mcl_flowers:fern")
26 minetest.register_alias("mapgen_stone_with_coal", "mcl_core:stone_with_coal")
27 minetest.register_alias("mapgen_stone_with_iron", "mcl_core:stone_with_iron")
28 minetest.register_alias("mapgen_desert_sand", "mcl_core:sand")
29 minetest.register_alias("mapgen_desert_stone", "mcl_core:sandstone")
30 minetest.register_alias("mapgen_sandstone", "mcl_core:sandstone")
31 if minetest.get_modpath("mclx_core") then
32 minetest.register_alias("mapgen_river_water_source", "mclx_core:river_water_source")
33 else
34 minetest.register_alias("mapgen_river_water_source", "mcl_core:water_source")
35 end
36 minetest.register_alias("mapgen_snow", "mcl_core:snow")
37 minetest.register_alias("mapgen_snowblock", "mcl_core:snowblock")
38 minetest.register_alias("mapgen_ice", "mcl_core:ice")
40 minetest.register_alias("mapgen_stair_cobble", "mcl_stairs:stair_cobble")
41 minetest.register_alias("mapgen_sandstonebrick", "mcl_core:sandstonesmooth")
42 minetest.register_alias("mapgen_stair_sandstonebrick", "mcl_stairs:stair_sandstone")
43 minetest.register_alias("mapgen_stair_sandstone_block", "mcl_stairs:stair_sandstone")
44 minetest.register_alias("mapgen_stair_desert_stone", "mcl_stairs:stair_sandstone")
46 local mg_name = minetest.get_mapgen_setting("mg_name")
47 local superflat = mg_name == "flat" and minetest.get_mapgen_setting("mcl_superflat_classic") == "true"
49 local WITCH_HUT_HEIGHT = 3 -- Exact Y level to spawn witch huts at. This height refers to the height of the floor
51 -- End exit portal position. This is temporary.
52 -- TODO: Remove the exit portal generation when the ender dragon has been implemented.
53 local END_EXIT_PORTAL_POS = table.copy(mcl_vars.mg_end_platform_pos)
54 END_EXIT_PORTAL_POS.x = END_EXIT_PORTAL_POS.x - 30
55 END_EXIT_PORTAL_POS.z = END_EXIT_PORTAL_POS.z - 3
56 END_EXIT_PORTAL_POS.y = END_EXIT_PORTAL_POS.y - 3
58 -- Content IDs
59 local c_bedrock = minetest.get_content_id("mcl_core:bedrock")
60 local c_obsidian = minetest.get_content_id("mcl_core:obsidian")
61 local c_stone = minetest.get_content_id("mcl_core:stone")
62 local c_dirt = minetest.get_content_id("mcl_core:dirt")
63 local c_dirt_with_grass = minetest.get_content_id("mcl_core:dirt_with_grass")
64 local c_dirt_with_grass_snow = minetest.get_content_id("mcl_core:dirt_with_grass_snow")
65 local c_sand = minetest.get_content_id("mcl_core:sand")
66 local c_sandstone = minetest.get_content_id("mcl_core:sandstone")
67 local c_void = minetest.get_content_id("mcl_core:void")
68 local c_lava = minetest.get_content_id("mcl_core:lava_source")
69 local c_water = minetest.get_content_id("mcl_core:water_source")
70 local c_soul_sand = minetest.get_content_id("mcl_nether:soul_sand")
71 local c_netherrack = minetest.get_content_id("mcl_nether:netherrack")
72 local c_nether_lava = minetest.get_content_id("mcl_nether:nether_lava_source")
73 local c_end_stone = minetest.get_content_id("mcl_end:end_stone")
74 local c_realm_barrier = minetest.get_content_id("mcl_core:realm_barrier")
75 local c_top_snow = minetest.get_content_id("mcl_core:snow")
76 local c_snow_block = minetest.get_content_id("mcl_core:snowblock")
77 local c_clay = minetest.get_content_id("mcl_core:clay")
78 local c_leaves = minetest.get_content_id("mcl_core:leaves")
79 local c_jungleleaves = minetest.get_content_id("mcl_core:jungleleaves")
80 local c_jungletree = minetest.get_content_id("mcl_core:jungletree")
81 local c_cocoa_1 = minetest.get_content_id("mcl_cocoas:cocoa_1")
82 local c_cocoa_2 = minetest.get_content_id("mcl_cocoas:cocoa_2")
83 local c_cocoa_3 = minetest.get_content_id("mcl_cocoas:cocoa_3")
84 local c_vine = minetest.get_content_id("mcl_core:vine")
85 local c_air = minetest.CONTENT_AIR
88 -- Ore generation
91 -- Diorite, andesite and granite
92 local specialstones = { "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite" }
93 for s=1, #specialstones do
94 local node = specialstones[s]
95 minetest.register_ore({
96 ore_type = "blob",
97 ore = node,
98 wherein = {"mcl_core:stone"},
99 clust_scarcity = 15*15*15,
100 clust_num_ores = 33,
101 clust_size = 5,
102 y_min = mcl_vars.mg_overworld_min,
103 y_max = mcl_vars.mg_overworld_max,
105 minetest.register_ore({
106 ore_type = "blob",
107 ore = node,
108 wherein = {"mcl_core:stone"},
109 clust_scarcity = 10*10*10,
110 clust_num_ores = 58,
111 clust_size = 7,
112 y_min = mcl_vars.mg_overworld_min,
113 y_max = mcl_vars.mg_overworld_max,
117 local stonelike = {"mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite"}
119 -- Dirt
120 minetest.register_ore({
121 ore_type = "blob",
122 ore = "mcl_core:dirt",
123 wherein = stonelike,
124 clust_scarcity = 15*15*15,
125 clust_num_ores = 33,
126 clust_size = 4,
127 y_min = mcl_vars.mg_overworld_min,
128 y_max = mcl_vars.mg_overworld_max,
131 -- Gravel
132 minetest.register_ore({
133 ore_type = "blob",
134 ore = "mcl_core:gravel",
135 wherein = stonelike,
136 clust_scarcity = 14*14*14,
137 clust_num_ores = 33,
138 clust_size = 5,
139 y_min = mcl_vars.mg_overworld_min,
140 y_max = mcl_worlds.layer_to_y(111),
144 -- Coal
147 -- Common spawn
148 minetest.register_ore({
149 ore_type = "scatter",
150 ore = "mcl_core:stone_with_coal",
151 wherein = stonelike,
152 clust_scarcity = 525*3,
153 clust_num_ores = 5,
154 clust_size = 3,
155 y_min = mcl_vars.mg_overworld_min,
156 y_max = mcl_worlds.layer_to_y(50),
158 minetest.register_ore({
159 ore_type = "scatter",
160 ore = "mcl_core:stone_with_coal",
161 wherein = stonelike,
162 clust_scarcity = 510*3,
163 clust_num_ores = 8,
164 clust_size = 3,
165 y_min = mcl_vars.mg_overworld_min,
166 y_max = mcl_worlds.layer_to_y(50),
168 minetest.register_ore({
169 ore_type = "scatter",
170 ore = "mcl_core:stone_with_coal",
171 wherein = stonelike,
172 clust_scarcity = 500*3,
173 clust_num_ores = 12,
174 clust_size = 3,
175 y_min = mcl_vars.mg_overworld_min,
176 y_max = mcl_worlds.layer_to_y(50),
179 -- Medium-rare spawn
180 minetest.register_ore({
181 ore_type = "scatter",
182 ore = "mcl_core:stone_with_coal",
183 wherein = stonelike,
184 clust_scarcity = 550*3,
185 clust_num_ores = 4,
186 clust_size = 2,
187 y_min = mcl_worlds.layer_to_y(51),
188 y_max = mcl_worlds.layer_to_y(80),
190 minetest.register_ore({
191 ore_type = "scatter",
192 ore = "mcl_core:stone_with_coal",
193 wherein = stonelike,
194 clust_scarcity = 525*3,
195 clust_num_ores = 6,
196 clust_size = 3,
197 y_min = mcl_worlds.layer_to_y(51),
198 y_max = mcl_worlds.layer_to_y(80),
200 minetest.register_ore({
201 ore_type = "scatter",
202 ore = "mcl_core:stone_with_coal",
203 wherein = stonelike,
204 clust_scarcity = 500*3,
205 clust_num_ores = 8,
206 clust_size = 3,
207 y_min = mcl_worlds.layer_to_y(51),
208 y_max = mcl_worlds.layer_to_y(80),
211 -- Rare spawn
212 minetest.register_ore({
213 ore_type = "scatter",
214 ore = "mcl_core:stone_with_coal",
215 wherein = stonelike,
216 clust_scarcity = 600*3,
217 clust_num_ores = 3,
218 clust_size = 2,
219 y_min = mcl_worlds.layer_to_y(81),
220 y_max = mcl_worlds.layer_to_y(128),
222 minetest.register_ore({
223 ore_type = "scatter",
224 ore = "mcl_core:stone_with_coal",
225 wherein = stonelike,
226 clust_scarcity = 550*3,
227 clust_num_ores = 4,
228 clust_size = 3,
229 y_min = mcl_worlds.layer_to_y(81),
230 y_max = mcl_worlds.layer_to_y(128),
232 minetest.register_ore({
233 ore_type = "scatter",
234 ore = "mcl_core:stone_with_coal",
235 wherein = stonelike,
236 clust_scarcity = 500*3,
237 clust_num_ores = 5,
238 clust_size = 3,
239 y_min = mcl_worlds.layer_to_y(81),
240 y_max = mcl_worlds.layer_to_y(128),
244 -- Iron
246 minetest.register_ore({
247 ore_type = "scatter",
248 ore = "mcl_core:stone_with_iron",
249 wherein = stonelike,
250 clust_scarcity = 830,
251 clust_num_ores = 5,
252 clust_size = 3,
253 y_min = mcl_vars.mg_overworld_min,
254 y_max = mcl_worlds.layer_to_y(39),
256 minetest.register_ore({
257 ore_type = "scatter",
258 ore = "mcl_core:stone_with_iron",
259 wherein = stonelike,
260 clust_scarcity = 1660,
261 clust_num_ores = 4,
262 clust_size = 2,
263 y_min = mcl_worlds.layer_to_y(40),
264 y_max = mcl_worlds.layer_to_y(63),
268 -- Gold
271 -- Common spawn
272 minetest.register_ore({
273 ore_type = "scatter",
274 ore = "mcl_core:stone_with_gold",
275 wherein = stonelike,
276 clust_scarcity = 4775,
277 clust_num_ores = 5,
278 clust_size = 3,
279 y_min = mcl_vars.mg_overworld_min,
280 y_max = mcl_worlds.layer_to_y(30),
282 minetest.register_ore({
283 ore_type = "scatter",
284 ore = "mcl_core:stone_with_gold",
285 wherein = stonelike,
286 clust_scarcity = 6560,
287 clust_num_ores = 7,
288 clust_size = 3,
289 y_min = mcl_vars.mg_overworld_min,
290 y_max = mcl_worlds.layer_to_y(30),
293 -- Rare spawn
294 minetest.register_ore({
295 ore_type = "scatter",
296 ore = "mcl_core:stone_with_gold",
297 wherein = stonelike,
298 clust_scarcity = 13000,
299 clust_num_ores = 4,
300 clust_size = 2,
301 y_min = mcl_worlds.layer_to_y(31),
302 y_max = mcl_worlds.layer_to_y(33),
306 -- Diamond
309 -- Common spawn
310 minetest.register_ore({
311 ore_type = "scatter",
312 ore = "mcl_core:stone_with_diamond",
313 wherein = stonelike,
314 clust_scarcity = 10000,
315 clust_num_ores = 4,
316 clust_size = 3,
317 y_min = mcl_vars.mg_overworld_min,
318 y_max = mcl_worlds.layer_to_y(12),
320 minetest.register_ore({
321 ore_type = "scatter",
322 ore = "mcl_core:stone_with_diamond",
323 wherein = stonelike,
324 clust_scarcity = 5000,
325 clust_num_ores = 2,
326 clust_size = 2,
327 y_min = mcl_vars.mg_overworld_min,
328 y_max = mcl_worlds.layer_to_y(12),
330 minetest.register_ore({
331 ore_type = "scatter",
332 ore = "mcl_core:stone_with_diamond",
333 wherein = stonelike,
334 clust_scarcity = 10000,
335 clust_num_ores = 8,
336 clust_size = 3,
337 y_min = mcl_vars.mg_overworld_min,
338 y_max = mcl_worlds.layer_to_y(12),
341 -- Rare spawn
342 minetest.register_ore({
343 ore_type = "scatter",
344 ore = "mcl_core:stone_with_diamond",
345 wherein = stonelike,
346 clust_scarcity = 20000,
347 clust_num_ores = 1,
348 clust_size = 1,
349 y_min = mcl_worlds.layer_to_y(13),
350 y_max = mcl_worlds.layer_to_y(15),
352 minetest.register_ore({
353 ore_type = "scatter",
354 ore = "mcl_core:stone_with_diamond",
355 wherein = stonelike,
356 clust_scarcity = 20000,
357 clust_num_ores = 2,
358 clust_size = 2,
359 y_min = mcl_worlds.layer_to_y(13),
360 y_max = mcl_worlds.layer_to_y(15),
364 -- Redstone
367 -- Common spawn
368 minetest.register_ore({
369 ore_type = "scatter",
370 ore = "mcl_core:stone_with_redstone",
371 wherein = stonelike,
372 clust_scarcity = 500,
373 clust_num_ores = 4,
374 clust_size = 3,
375 y_min = mcl_vars.mg_overworld_min,
376 y_max = mcl_worlds.layer_to_y(13),
378 minetest.register_ore({
379 ore_type = "scatter",
380 ore = "mcl_core:stone_with_redstone",
381 wherein = stonelike,
382 clust_scarcity = 800,
383 clust_num_ores = 7,
384 clust_size = 4,
385 y_min = mcl_vars.mg_overworld_min,
386 y_max = mcl_worlds.layer_to_y(13),
389 -- Rare spawn
390 minetest.register_ore({
391 ore_type = "scatter",
392 ore = "mcl_core:stone_with_redstone",
393 wherein = stonelike,
394 clust_scarcity = 1000,
395 clust_num_ores = 4,
396 clust_size = 3,
397 y_min = mcl_worlds.layer_to_y(13),
398 y_max = mcl_worlds.layer_to_y(15),
400 minetest.register_ore({
401 ore_type = "scatter",
402 ore = "mcl_core:stone_with_redstone",
403 wherein = stonelike,
404 clust_scarcity = 1600,
405 clust_num_ores = 7,
406 clust_size = 4,
407 y_min = mcl_worlds.layer_to_y(13),
408 y_max = mcl_worlds.layer_to_y(15),
412 -- Emerald
415 if mg_name == "v6" then
416 -- Generate everywhere in v6, but rarely.
418 -- Common spawn
419 minetest.register_ore({
420 ore_type = "scatter",
421 ore = "mcl_core:stone_with_emerald",
422 wherein = stonelike,
423 clust_scarcity = 14340,
424 clust_num_ores = 1,
425 clust_size = 1,
426 y_min = mcl_vars.mg_overworld_min,
427 y_max = mcl_worlds.layer_to_y(29),
429 -- Rare spawn
430 minetest.register_ore({
431 ore_type = "scatter",
432 ore = "mcl_core:stone_with_emerald",
433 wherein = stonelike,
434 clust_scarcity = 21510,
435 clust_num_ores = 1,
436 clust_size = 1,
437 y_min = mcl_worlds.layer_to_y(30),
438 y_max = mcl_worlds.layer_to_y(32),
443 -- Lapis Lazuli
446 -- Common spawn (in the center)
447 minetest.register_ore({
448 ore_type = "scatter",
449 ore = "mcl_core:stone_with_lapis",
450 wherein = stonelike,
451 clust_scarcity = 10000,
452 clust_num_ores = 7,
453 clust_size = 4,
454 y_min = mcl_worlds.layer_to_y(14),
455 y_max = mcl_worlds.layer_to_y(16),
458 -- Rare spawn (below center)
459 minetest.register_ore({
460 ore_type = "scatter",
461 ore = "mcl_core:stone_with_lapis",
462 wherein = stonelike,
463 clust_scarcity = 12000,
464 clust_num_ores = 6,
465 clust_size = 3,
466 y_min = mcl_worlds.layer_to_y(10),
467 y_max = mcl_worlds.layer_to_y(13),
469 minetest.register_ore({
470 ore_type = "scatter",
471 ore = "mcl_core:stone_with_lapis",
472 wherein = stonelike,
473 clust_scarcity = 14000,
474 clust_num_ores = 5,
475 clust_size = 3,
476 y_min = mcl_worlds.layer_to_y(6),
477 y_max = mcl_worlds.layer_to_y(9),
479 minetest.register_ore({
480 ore_type = "scatter",
481 ore = "mcl_core:stone_with_lapis",
482 wherein = stonelike,
483 clust_scarcity = 16000,
484 clust_num_ores = 4,
485 clust_size = 3,
486 y_min = mcl_worlds.layer_to_y(2),
487 y_max = mcl_worlds.layer_to_y(5),
489 minetest.register_ore({
490 ore_type = "scatter",
491 ore = "mcl_core:stone_with_lapis",
492 wherein = stonelike,
493 clust_scarcity = 18000,
494 clust_num_ores = 3,
495 clust_size = 2,
496 y_min = mcl_worlds.layer_to_y(0),
497 y_max = mcl_worlds.layer_to_y(2),
500 -- Rare spawn (above center)
501 minetest.register_ore({
502 ore_type = "scatter",
503 ore = "mcl_core:stone_with_lapis",
504 wherein = stonelike,
505 clust_scarcity = 12000,
506 clust_num_ores = 6,
507 clust_size = 3,
508 y_min = mcl_worlds.layer_to_y(17),
509 y_max = mcl_worlds.layer_to_y(20),
511 minetest.register_ore({
512 ore_type = "scatter",
513 ore = "mcl_core:stone_with_lapis",
514 wherein = stonelike,
515 clust_scarcity = 14000,
516 clust_num_ores = 5,
517 clust_size = 3,
518 y_min = mcl_worlds.layer_to_y(21),
519 y_max = mcl_worlds.layer_to_y(24),
521 minetest.register_ore({
522 ore_type = "scatter",
523 ore = "mcl_core:stone_with_lapis",
524 wherein = stonelike,
525 clust_scarcity = 16000,
526 clust_num_ores = 4,
527 clust_size = 3,
528 y_min = mcl_worlds.layer_to_y(25),
529 y_max = mcl_worlds.layer_to_y(28),
531 minetest.register_ore({
532 ore_type = "scatter",
533 ore = "mcl_core:stone_with_lapis",
534 wherein = stonelike,
535 clust_scarcity = 18000,
536 clust_num_ores = 3,
537 clust_size = 2,
538 y_min = mcl_worlds.layer_to_y(29),
539 y_max = mcl_worlds.layer_to_y(32),
541 minetest.register_ore({
542 ore_type = "scatter",
543 ore = "mcl_core:stone_with_lapis",
544 wherein = stonelike,
545 clust_scarcity = 32000,
546 clust_num_ores = 1,
547 clust_size = 1,
548 y_min = mcl_worlds.layer_to_y(31),
549 y_max = mcl_worlds.layer_to_y(32),
552 if not superflat then
553 -- Water and lava springs (single blocks of lava/water source)
554 -- Water appears at nearly every height, but not near the bottom
555 minetest.register_ore({
556 ore_type = "scatter",
557 ore = "mcl_core:water_source",
558 wherein = {"mcl_core:stone", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite", "mcl_core:dirt"},
559 clust_scarcity = 9000,
560 clust_num_ores = 1,
561 clust_size = 1,
562 y_min = mcl_worlds.layer_to_y(5),
563 y_max = mcl_worlds.layer_to_y(128),
566 -- Lava springs are rather common at -31 and below
567 minetest.register_ore({
568 ore_type = "scatter",
569 ore = "mcl_core:lava_source",
570 wherein = stonelike,
571 clust_scarcity = 2000,
572 clust_num_ores = 1,
573 clust_size = 1,
574 y_min = mcl_worlds.layer_to_y(1),
575 y_max = mcl_worlds.layer_to_y(10),
578 minetest.register_ore({
579 ore_type = "scatter",
580 ore = "mcl_core:lava_source",
581 wherein = stonelike,
582 clust_scarcity = 9000,
583 clust_num_ores = 1,
584 clust_size = 1,
585 y_min = mcl_worlds.layer_to_y(11),
586 y_max = mcl_worlds.layer_to_y(31),
589 -- Lava springs will become gradually rarer with increasing height
590 minetest.register_ore({
591 ore_type = "scatter",
592 ore = "mcl_core:lava_source",
593 wherein = stonelike,
594 clust_scarcity = 32000,
595 clust_num_ores = 1,
596 clust_size = 1,
597 y_min = mcl_worlds.layer_to_y(32),
598 y_max = mcl_worlds.layer_to_y(47),
601 minetest.register_ore({
602 ore_type = "scatter",
603 ore = "mcl_core:lava_source",
604 wherein = stonelike,
605 clust_scarcity = 72000,
606 clust_num_ores = 1,
607 clust_size = 1,
608 y_min = mcl_worlds.layer_to_y(48),
609 y_max = mcl_worlds.layer_to_y(61),
612 -- Lava may even appear above surface, but this is very rare
613 minetest.register_ore({
614 ore_type = "scatter",
615 ore = "mcl_core:lava_source",
616 wherein = stonelike,
617 clust_scarcity = 96000,
618 clust_num_ores = 1,
619 clust_size = 1,
620 y_min = mcl_worlds.layer_to_y(62),
621 y_max = mcl_worlds.layer_to_y(127),
625 local function register_mgv6_decorations()
627 -- Cacti
628 minetest.register_decoration({
629 deco_type = "simple",
630 place_on = {"group:sand"},
631 sidelen = 16,
632 noise_params = {
633 offset = -0.012,
634 scale = 0.024,
635 spread = {x = 100, y = 100, z = 100},
636 seed = 257,
637 octaves = 3,
638 persist = 0.6
640 y_min = 4,
641 y_max = mcl_vars.mg_overworld_max,
642 decoration = "mcl_core:cactus",
643 height = 1,
644 height_max = 3,
647 -- Sugar canes
648 minetest.register_decoration({
649 deco_type = "simple",
650 place_on = {"mcl_core:dirt", "mcl_core:coarse_dirt", "group:grass_block_no_snow", "group:sand", "mcl_core:podzol", "mcl_core:reeds"},
651 sidelen = 16,
652 noise_params = {
653 offset = -0.3,
654 scale = 0.7,
655 spread = {x = 100, y = 100, z = 100},
656 seed = 465,
657 octaves = 3,
658 persist = 0.7
660 y_min = 1,
661 y_max = mcl_vars.mg_overworld_max,
662 decoration = "mcl_core:reeds",
663 height = 1,
664 height_max = 3,
665 spawn_by = { "mcl_core:water_source", "group:frosted_ice" },
666 num_spawn_by = 1,
669 -- Doubletall grass
670 minetest.register_decoration({
671 deco_type = "schematic",
672 schematic = {
673 size = { x=1, y=3, z=1 },
674 data = {
675 { name = "air", prob = 0 },
676 { name = "mcl_flowers:double_grass", param1 = 255, },
677 { name = "mcl_flowers:double_grass_top", param1 = 255, },
680 place_on = {"group:grass_block_no_snow"},
681 sidelen = 8,
682 noise_params = {
683 offset = -0.0025,
684 scale = 0.03,
685 spread = {x = 100, y = 100, z = 100},
686 seed = 420,
687 octaves = 3,
688 persist = 0.0,
690 y_min = 1,
691 y_max = mcl_vars.mg_overworld_max,
694 -- Large ferns
695 minetest.register_decoration({
696 deco_type = "schematic",
697 schematic = {
698 size = { x=1, y=3, z=1 },
699 data = {
700 { name = "air", prob = 0 },
701 { name = "mcl_flowers:double_fern", param1=255, },
702 { name = "mcl_flowers:double_fern_top", param1=255, },
705 -- v6 hack: This makes sure large ferns only appear in jungles
706 spawn_by = { "mcl_core:jungletree", "mcl_flowers:fern" },
707 num_spawn_by = 1,
708 place_on = {"group:grass_block_no_snow"},
710 sidelen = 16,
711 noise_params = {
712 offset = 0,
713 scale = 0.01,
714 spread = {x = 250, y = 250, z = 250},
715 seed = 333,
716 octaves = 2,
717 persist = 0.66,
719 y_min = 1,
720 y_max = mcl_vars.mg_overworld_max,
723 -- Large flowers
724 local register_large_flower = function(name, seed, offset)
725 minetest.register_decoration({
726 deco_type = "schematic",
727 schematic = {
728 size = { x=1, y=3, z=1 },
729 data = {
730 { name = "air", prob = 0 },
731 { name = "mcl_flowers:"..name, param1=255, },
732 { name = "mcl_flowers:"..name.."_top", param1=255, },
735 place_on = {"group:grass_block_no_snow"},
737 sidelen = 16,
738 noise_params = {
739 offset = offset,
740 scale = 0.01,
741 spread = {x = 300, y = 300, z = 300},
742 seed = seed,
743 octaves = 5,
744 persist = 0.62,
746 y_min = 1,
747 y_max = mcl_vars.overworld_max,
748 flags = "",
752 register_large_flower("rose_bush", 9350, -0.008)
753 register_large_flower("peony", 10450, -0.008)
754 register_large_flower("lilac", 10600, -0.007)
755 register_large_flower("sunflower", 2940, -0.005)
757 -- Lily pad
758 minetest.register_decoration({
759 deco_type = "schematic",
760 schematic = {
761 size = { x=1, y=3, z=1 },
762 data = {
763 { name = "mcl_core:water_source", prob = 0 },
764 { name = "mcl_core:water_source" },
765 { name = "mcl_flowers:waterlily", param1 = 255 },
768 place_on = "mcl_core:dirt",
769 sidelen = 16,
770 noise_params = {
771 offset = -0.12,
772 scale = 0.3,
773 spread = {x = 200, y = 200, z = 200},
774 seed = 503,
775 octaves = 6,
776 persist = 0.7,
778 y_min = 0,
779 y_max = 0,
780 rotation = "random",
783 -- Pumpkin
784 minetest.register_decoration({
785 deco_type = "simple",
786 decoration = "mcl_farming:pumpkin_face",
787 param2 = 0,
788 param2_max = 3,
789 place_on = {"group:grass_block_no_snow"},
790 sidelen = 16,
791 noise_params = {
792 offset = -0.008,
793 scale = 0.00666,
794 spread = {x = 250, y = 250, z = 250},
795 seed = 666,
796 octaves = 6,
797 persist = 0.666
799 y_min = 1,
800 y_max = mcl_vars.overworld_max,
803 -- Melon
804 minetest.register_decoration({
805 deco_type = "simple",
806 place_on = {"group:grass_block_no_snow"},
807 sidelen = 16,
808 noise_params = {
809 offset = 0.002,
810 scale = 0.006,
811 spread = {x = 250, y = 250, z = 250},
812 seed = 333,
813 octaves = 3,
814 persist = 0.6
816 -- Small trick to make sure melon spawn in jungles
817 spawn_by = { "mcl_core:jungletree", "mcl_flowers:fern" },
818 num_spawn_by = 1,
819 y_min = 1,
820 y_max = 40,
821 decoration = "mcl_farming:melon",
824 -- Tall grass
825 minetest.register_decoration({
826 deco_type = "simple",
827 place_on = {"group:grass_block_no_snow"},
828 sidelen = 8,
829 noise_params = {
830 offset = 0.01,
831 scale = 0.3,
832 spread = {x = 100, y = 100, z = 100},
833 seed = 420,
834 octaves = 3,
835 persist = 0.6
837 y_min = 1,
838 y_max = mcl_vars.overworld_max,
839 decoration = "mcl_flowers:tallgrass",
841 minetest.register_decoration({
842 deco_type = "simple",
843 place_on = {"group:grass_block_no_snow"},
844 sidelen = 8,
845 noise_params = {
846 offset = 0.04,
847 scale = 0.03,
848 spread = {x = 100, y = 100, z = 100},
849 seed = 420,
850 octaves = 3,
851 persist = 0.6
853 y_min = 1,
854 y_max = mcl_vars.overworld_max,
855 decoration = "mcl_flowers:tallgrass",
858 -- Seagrass and kelp
859 local materials = {"dirt","sand"}
860 for i=1, #materials do
861 local mat = materials[i]
863 minetest.register_decoration({
864 deco_type = "simple",
865 spawn_by = {"group:water"},
866 num_spawn_by = 1,
867 place_on = {"mcl_core:"..mat},
868 sidelen = 8,
869 noise_params = {
870 offset = 0.04,
871 scale = 0.3,
872 spread = {x = 100, y = 100, z = 100},
873 seed = 421,
874 octaves = 3,
875 persist = 0.6
877 flags = "force_placement",
878 place_offset_y = -1,
879 y_min = mcl_vars.overworld_min,
880 y_max = 0,
881 decoration = "mcl_ocean:seagrass_"..mat,
883 minetest.register_decoration({
884 deco_type = "simple",
885 spawn_by = {"group:water"},
886 num_spawn_by = 1,
887 place_on = {"mcl_core:mat"},
888 sidelen = 8,
889 noise_params = {
890 offset = 0.08,
891 scale = 0.03,
892 spread = {x = 100, y = 100, z = 100},
893 seed = 421,
894 octaves = 3,
895 persist = 0.6
897 flags = "force_placement",
898 place_offset_y = -1,
899 y_min = mcl_vars.overworld_min,
900 y_max = -5,
901 decoration = "mcl_ocean:seagrass_"..mat,
904 minetest.register_decoration({
905 deco_type = "simple",
906 spawn_by = {"group:water"},
907 num_spawn_by = 1,
908 place_on = {"mcl_core:"..mat},
909 sidelen = 16,
910 noise_params = {
911 offset = 0.01,
912 scale = 0.01,
913 spread = {x = 300, y = 300, z = 300},
914 seed = 505,
915 octaves = 5,
916 persist = 0.62,
918 flags = "force_placement",
919 place_offset_y = -1,
920 y_min = mcl_vars.overworld_min,
921 y_max = -6,
922 decoration = "mcl_ocean:kelp_"..mat,
923 param2 = 16,
924 param2_max = 96,
926 minetest.register_decoration({
927 deco_type = "simple",
928 spawn_by = {"group:water"},
929 num_spawn_by = 1,
930 place_on = {"mcl_core:"..mat},
931 sidelen = 16,
932 noise_params = {
933 offset = 0.01,
934 scale = 0.01,
935 spread = {x = 100, y = 100, z = 100},
936 seed = 506,
937 octaves = 5,
938 persist = 0.62,
940 flags = "force_placement",
941 place_offset_y = -1,
942 y_min = mcl_vars.overworld_min,
943 y_max = -15,
944 decoration = "mcl_ocean:kelp_"..mat,
945 param2 = 32,
946 param2_max = 160,
951 -- Wet Sponge
952 -- TODO: Remove this when we got ocean monuments
953 minetest.register_decoration({
954 deco_type = "simple",
955 decoration = "mcl_sponges:sponge_wet",
956 spawn_by = {"group:water"},
957 num_spawn_by = 1,
958 place_on = {"mcl_core:dirt","mcl_core:sand"},
959 sidelen = 16,
960 noise_params = {
961 offset = 0.00295,
962 scale = 0.006,
963 spread = {x = 250, y = 250, z = 250},
964 seed = 999,
965 octaves = 3,
966 persist = 0.666
968 flags = "force_placement",
969 y_min = mcl_vars.mg_lava_overworld_max + 5,
970 y_max = -20,
973 -- Add a small amount of tall grass everywhere to avoid areas completely empty devoid of tall grass
974 minetest.register_decoration({
975 deco_type = "simple",
976 place_on = {"group:grass_block_no_snow"},
977 sidelen = 8,
978 fill_ratio = 0.004,
979 y_min = 1,
980 y_max = mcl_vars.overworld_max,
981 decoration = "mcl_flowers:tallgrass",
984 local mushrooms = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown"}
985 local mseeds = { 7133, 8244 }
986 for m=1, #mushrooms do
987 -- Mushrooms next to trees
988 minetest.register_decoration({
989 deco_type = "simple",
990 place_on = {"group:grass_block_no_snow", "mcl_core:dirt", "mcl_core:podzol", "mcl_core:mycelium", "mcl_core:stone", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite"},
991 sidelen = 16,
992 noise_params = {
993 offset = 0.04,
994 scale = 0.04,
995 spread = {x = 100, y = 100, z = 100},
996 seed = mseeds[m],
997 octaves = 3,
998 persist = 0.6
1000 y_min = 1,
1001 y_max = mcl_vars.mg_overworld_max,
1002 decoration = mushrooms[m],
1003 spawn_by = { "mcl_core:tree", "mcl_core:sprucetree", "mcl_core:darktree", "mcl_core:birchtree", },
1004 num_spawn_by = 1,
1008 -- Dead bushes
1009 minetest.register_decoration({
1010 deco_type = "simple",
1011 place_on = {"group:sand", "mcl_core:podzol", "mcl_core:dirt", "mcl_core:coarse_dirt", "group:hardened_clay"},
1012 sidelen = 16,
1013 noise_params = {
1014 offset = 0,
1015 scale = 0.035,
1016 spread = {x = 100, y = 100, z = 100},
1017 seed = 1972,
1018 octaves = 3,
1019 persist = 0.6
1021 y_min = 4,
1022 y_max = mcl_vars.mg_overworld_max,
1023 decoration = "mcl_core:deadbush",
1026 local function register_mgv6_flower(name, seed, offset, y_max)
1027 if offset == nil then
1028 offset = 0
1030 if y_max == nil then
1031 y_max = mcl_vars.mg_overworld_max
1033 minetest.register_decoration({
1034 deco_type = "simple",
1035 place_on = {"group:grass_block_no_snow"},
1036 sidelen = 16,
1037 noise_params = {
1038 offset = offset,
1039 scale = 0.006,
1040 spread = {x = 100, y = 100, z = 100},
1041 seed = seed,
1042 octaves = 3,
1043 persist = 0.6
1045 y_min = 1,
1046 y_max = y_max,
1047 decoration = "mcl_flowers:"..name,
1051 register_mgv6_flower("tulip_red", 436)
1052 register_mgv6_flower("tulip_orange", 536)
1053 register_mgv6_flower("tulip_pink", 636)
1054 register_mgv6_flower("tulip_white", 736)
1055 register_mgv6_flower("azure_bluet", 800)
1056 register_mgv6_flower("dandelion", 8)
1057 -- Allium is supposed to only appear in flower forest in MC. There are no flower forests in v6.
1058 -- We compensate by making it slightly rarer in v6.
1059 register_mgv6_flower("allium", 0, -0.001)
1060 --[[ Blue orchid is supposed to appear in swamplands. There are no swamplands in v6.
1061 We emulate swamplands by limiting the height to 5 levels above sea level,
1062 which should be close to the water. ]]
1063 register_mgv6_flower("blue_orchid", 64500, nil, mcl_worlds.layer_to_y(67))
1064 register_mgv6_flower("oxeye_daisy", 3490)
1065 register_mgv6_flower("poppy", 9439)
1067 -- Put top snow on snowy grass blocks. The v6 mapgen does not generate the top snow on its own.
1068 minetest.register_decoration({
1069 deco_type = "simple",
1070 place_on = {"group:grass_block_snow"},
1071 sidelen = 16,
1072 fill_ratio = 11.0, -- complete coverage
1073 y_min = 1,
1074 y_max = mcl_vars.mg_overworld_max,
1075 decoration = "mcl_core:snow",
1080 local mg_flags = minetest.settings:get_flags("mg_flags")
1082 -- Inform other mods of dungeon setting for MCL2-style dungeons
1083 mcl_vars.mg_dungeons = mg_flags.dungeons and not superflat
1085 -- Disable builtin dungeons, we provide our own dungeons
1086 mg_flags.dungeons = false
1088 -- Apply mapgen-specific mapgen code
1089 if mg_name == "v6" then
1090 register_mgv6_decorations()
1091 elseif superflat then
1092 -- Enforce superflat-like mapgen: no caves, decor, lakes and hills
1093 mg_flags.caves = false
1094 mg_flags.decorations = false
1095 minetest.set_mapgen_setting("mgflat_spflags", "nolakes,nohills", true)
1098 local mg_flags_str = ""
1099 for k,v in pairs(mg_flags) do
1100 if v == false then
1101 k = "no" .. k
1103 mg_flags_str = mg_flags_str .. k .. ","
1105 if string.len(mg_flags_str) > 0 then
1106 mg_flags_str = string.sub(mg_flags_str, 1, string.len(mg_flags_str)-1)
1108 minetest.set_mapgen_setting("mg_flags", mg_flags_str, true)
1110 -- Helper function for converting a MC probability to MT, with
1111 -- regards to MapBlocks.
1112 -- Some MC generated structures are generated on per-chunk
1113 -- probability.
1114 -- The MC probability is 1/x per Minecraft chunk (16×16).
1116 -- x: The MC probability is 1/x.
1117 -- minp, maxp: MapBlock limits
1118 -- returns: Probability (1/return_value) for a single MT mapblock
1119 local function minecraft_chunk_probability(x, minp, maxp)
1120 -- 256 is the MC chunk height
1121 return x * (((maxp.x-minp.x+1)*(maxp.z-minp.z+1)) / 256)
1124 -- Takes an index of a biomemap table (from minetest.get_mapgen_object),
1125 -- minp and maxp (from an on_generated callback) and returns the real world coordinates
1126 -- as X, Z.
1127 -- Inverse function of xz_to_biomemap
1128 local biomemap_to_xz = function(index, minp, maxp)
1129 local xwidth = maxp.x - minp.x + 1
1130 local zwidth = maxp.z - minp.z + 1
1131 local x = ((index-1) % xwidth) + minp.x
1132 local z = ((index-1) / zwidth) + minp.z
1133 return x, z
1136 -- Takes x and z coordinates and minp and maxp of a generated chunk
1137 -- (in on_generated callback) and returns a biomemap index)
1138 -- Inverse function of biomemap_to_xz
1139 local xz_to_biomemap_index = function(x, z, minp, maxp)
1140 local xwidth = maxp.x - minp.x + 1
1141 local zwidth = maxp.z - minp.z + 1
1142 local minix = x % xwidth
1143 local miniz = z % zwidth
1145 return (minix + miniz * zwidth) + 1
1148 -- Perlin noise objects
1149 local perlin_structures
1150 local perlin_vines, perlin_vines_fine, perlin_vines_upwards, perlin_vines_length, perlin_vines_density
1151 local perlin_clay
1153 local function generate_clay(minp, maxp, seed, voxelmanip_data, voxelmanip_area, lvm_used)
1154 -- TODO: Make clay generation reproducible for same seed.
1155 if maxp.y < -5 or minp.y > 0 then
1156 return lvm_used
1159 perlin_clay = perlin_clay or minetest.get_perlin({
1160 offset = 0.5,
1161 scale = 0.2,
1162 spread = {x = 5, y = 5, z = 5},
1163 seed = -316,
1164 octaves = 1,
1165 persist = 0.0
1168 for y=math.max(minp.y, 0), math.min(maxp.y, -8), -1 do
1169 -- Assume X and Z lengths are equal
1170 local divlen = 4
1171 local divs = (maxp.x-minp.x)/divlen+1;
1172 for divx=0+1,divs-2 do
1173 for divz=0+1,divs-2 do
1174 -- Get position and shift it a bit randomly so the clay do not obviously appear in a grid
1175 local cx = minp.x + math.floor((divx+0.5)*divlen) + math.random(-1,1)
1176 local cz = minp.z + math.floor((divz+0.5)*divlen) + math.random(-1,1)
1178 local water_pos = voxelmanip_area:index(cx, y+1, cz)
1179 local waternode = voxelmanip_data[water_pos]
1180 local surface_pos = voxelmanip_area:index(cx, y, cz)
1181 local surfacenode = voxelmanip_data[surface_pos]
1183 local genrnd = math.random(1, 20)
1184 if genrnd == 1 and perlin_clay:get_3d({x=cx,y=y,z=cz}) > 0 and waternode == c_water and
1185 (surfacenode == c_dirt or minetest.get_item_group(minetest.get_name_from_content_id(surfacenode), "sand") == 1) then
1186 local diamondsize = math.random(1, 3)
1187 for x1 = -diamondsize, diamondsize do
1188 for z1 = -(diamondsize - math.abs(x1)), diamondsize - math.abs(x1) do
1189 local ccpos = voxelmanip_area:index(cx+x1, y, cz+z1)
1190 local claycandidate = voxelmanip_data[ccpos]
1191 if voxelmanip_data[ccpos] == c_dirt or minetest.get_item_group(minetest.get_name_from_content_id(claycandidate), "sand") == 1 then
1192 voxelmanip_data[ccpos] = c_clay
1193 lvm_used = true
1201 return lvm_used
1204 -- TODO: Try to use more efficient structure generating code
1205 local function generate_structures(minp, maxp, seed, biomemap)
1206 local chunk_has_desert_well = false
1207 local chunk_has_desert_temple = false
1208 local chunk_has_igloo = false
1209 local struct_min, struct_max = -3, 64
1210 if maxp.y >= struct_min and minp.y <= struct_max then
1211 -- Generate structures
1213 perlin_structures = perlin_structures or minetest.get_perlin(329, 3, 0.6, 100)
1214 -- Assume X and Z lengths are equal
1215 local divlen = 5
1216 local divs = (maxp.x-minp.x)/divlen+1;
1217 for divx=0,divs-1 do
1218 for divz=0,divs-1 do
1219 local x0 = minp.x + math.floor((divx+0)*divlen)
1220 local z0 = minp.z + math.floor((divz+0)*divlen)
1221 local x1 = minp.x + math.floor((divx+1)*divlen)
1222 local z1 = minp.z + math.floor((divz+1)*divlen)
1223 -- Determine amount from perlin noise
1224 local amount = math.floor(perlin_structures:get_2d({x=x0, y=z0}) * 9)
1225 -- Find random positions based on this random
1226 local pr = PseudoRandom(seed+1)
1227 for i=0, amount do
1228 local x = pr:next(x0, x1)
1229 local z = pr:next(z0, z1)
1230 -- Find ground level
1231 local ground_y = nil
1232 for y = struct_max, struct_min, -1 do
1233 local checknode = minetest.get_node_or_nil({x=x,y=y,z=z})
1234 if checknode then
1235 local def = minetest.registered_nodes[checknode.name]
1236 if def and def.walkable then
1237 ground_y = y
1238 break
1243 if ground_y then
1244 local p = {x=x,y=ground_y+1,z=z}
1245 local nn = minetest.get_node(p).name
1246 -- Check if the node can be replaced
1247 if minetest.registered_nodes[nn] and
1248 minetest.registered_nodes[nn].buildable_to then
1249 nn = minetest.get_node({x=x,y=ground_y,z=z}).name
1250 local struct = false
1252 -- Desert temples and desert wells
1253 if nn == "mcl_core:sand" or (nn == "mcl_core:sandstone") then
1254 if not chunk_has_desert_temple and not chunk_has_desert_well and ground_y > 3 then
1255 -- Spawn desert temple
1256 -- TODO: Check surface
1257 if math.random(1,12000) == 1 then
1258 mcl_structures.call_struct(p, "desert_temple")
1259 chunk_has_desert_temple = true
1262 if not chunk_has_desert_temple and not chunk_has_desert_well and ground_y > 3 then
1263 local desert_well_prob = minecraft_chunk_probability(1000, minp, maxp)
1265 -- Spawn desert well
1266 if math.random(1, desert_well_prob) == 1 then
1267 -- Check surface
1268 local surface = minetest.find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, {x=p.x+5, y=p.y-1, z=p.z+5}, "mcl_core:sand")
1269 if #surface >= 25 then
1270 mcl_structures.call_struct(p, "desert_well")
1271 chunk_has_desert_well = true
1276 -- Igloos
1277 elseif not chunk_has_igloo and (nn == "mcl_core:snowblock" or nn == "mcl_core:snow" or (minetest.get_item_group(nn, "grass_block_snow") == 1)) then
1278 if math.random(1, 4400) == 1 then
1279 -- Check surface
1280 local floor = {x=p.x+9, y=p.y-1, z=p.z+9}
1281 local surface = minetest.find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, floor, "mcl_core:snowblock")
1282 local surface2 = minetest.find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, floor, "mcl_core:dirt_with_grass_snow")
1283 if #surface + #surface2 >= 63 then
1284 mcl_structures.call_struct(p, "igloo")
1285 chunk_has_igloo = true
1290 -- Fossil
1291 if nn == "mcl_core:sandstone" or nn == "mcl_core:sand" and not chunk_has_desert_temple and ground_y > 3 then
1292 local fossil_prob = minecraft_chunk_probability(64, minp, maxp)
1294 if math.random(1, fossil_prob) == 1 then
1295 -- Spawn fossil below desert surface between layers 40 and 49
1296 local p1 = {x=p.x, y=math.random(mcl_worlds.layer_to_y(40), mcl_worlds.layer_to_y(49)), z=p.z}
1297 -- Very rough check of the environment (we expect to have enough stonelike nodes).
1298 -- Fossils may still appear partially exposed in caves, but this is O.K.
1299 local p2 = vector.add(p1, 4)
1300 local nodes = minetest.find_nodes_in_area(p1, p2, {"mcl_core:sandstone", "mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite", "mcl_core:stone_with_coal", "mcl_core:dirt", "mcl_core:gravel"})
1302 if #nodes >= 100 then -- >= 80%
1303 mcl_structures.call_struct(p1, "fossil")
1308 -- Witch hut
1309 if ground_y <= 0 and nn == "mcl_core:dirt" then
1310 local prob = minecraft_chunk_probability(48, minp, maxp)
1311 if math.random(1, prob) == 1 then
1313 local swampland = minetest.get_biome_id("Swampland")
1314 local swampland_shore = minetest.get_biome_id("Swampland_shore")
1316 -- Where do witches live?
1318 local here_be_witches = false
1319 if mg_name == "v6" then
1320 -- v6: In Normal biome
1321 if biomeinfo.get_v6_biome(p) == "Normal" then
1322 here_be_witches = true
1324 else
1325 -- Other mapgens: In swampland biome
1326 local bi = xz_to_biomemap_index(p.x, p.z, minp, maxp)
1327 if biomemap[bi] == swampland or biomemap[bi] == swampland_shore then
1328 here_be_witches = true
1332 if here_be_witches then
1333 local r = tostring(math.random(0, 3) * 90) -- "0", "90", "180" or 270"
1334 local p1 = {x=p.x-1, y=WITCH_HUT_HEIGHT+2, z=p.z-1}
1335 local size
1336 if r == "0" or r == "180" then
1337 size = {x=10, y=4, z=8}
1338 else
1339 size = {x=8, y=4, z=10}
1341 local p2 = vector.add(p1, size)
1343 -- This checks free space at the “body” of the hut and a bit around.
1344 -- ALL nodes must be free for the placement to succeed.
1345 local free_nodes = minetest.find_nodes_in_area(p1, p2, {"air", "mcl_core:water_source", "mcl_flowers:waterlily"})
1346 if #free_nodes >= ((size.x+1)*(size.y+1)*(size.z+1)) then
1347 local place = {x=p.x, y=WITCH_HUT_HEIGHT-1, z=p.z}
1349 -- FIXME: For some mysterious reason (black magic?) this
1350 -- function does sometimes NOT spawn the witch hut. One can only see the
1351 -- oak wood nodes in the water, but no hut. :-/
1352 mcl_structures.call_struct(place, "witch_hut", r)
1354 -- TODO: Spawn witch in or around hut when the mob sucks less.
1356 local place_tree_if_free = function(pos, prev_result)
1357 local nn = minetest.get_node(pos).name
1358 if nn == "mcl_flowers:waterlily" or nn == "mcl_core:water_source" or nn == "mcl_core:water_flowing" or nn == "air" then
1359 minetest.set_node(pos, {name="mcl_core:tree", param2=0})
1360 return prev_result
1361 else
1362 return false
1365 local offsets
1366 if r == "0" then
1367 offsets = {
1368 {x=1, y=0, z=1},
1369 {x=1, y=0, z=5},
1370 {x=6, y=0, z=1},
1371 {x=6, y=0, z=5},
1373 elseif r == "180" then
1374 offsets = {
1375 {x=2, y=0, z=1},
1376 {x=2, y=0, z=5},
1377 {x=7, y=0, z=1},
1378 {x=7, y=0, z=5},
1380 elseif r == "270" then
1381 offsets = {
1382 {x=1, y=0, z=1},
1383 {x=5, y=0, z=1},
1384 {x=1, y=0, z=6},
1385 {x=5, y=0, z=6},
1387 elseif r == "90" then
1388 offsets = {
1389 {x=1, y=0, z=2},
1390 {x=5, y=0, z=2},
1391 {x=1, y=0, z=7},
1392 {x=5, y=0, z=7},
1395 for o=1, #offsets do
1396 local ok = true
1397 for y=place.y-1, place.y-64, -1 do
1398 local tpos = vector.add(place, offsets[o])
1399 tpos.y = y
1400 ok = place_tree_if_free(tpos, ok)
1401 if not ok then
1402 break
1411 -- Ice spikes in v6
1412 -- In other mapgens, ice spikes are generated as decorations.
1413 if mg_name == "v6" and not chunk_has_igloo and nn == "mcl_core:snowblock" then
1414 local spike = math.random(1, 58000)
1415 if spike < 3 then
1416 -- Check surface
1417 local floor = {x=p.x+4, y=p.y-1, z=p.z+4}
1418 local surface = minetest.find_nodes_in_area({x=p.x+1,y=p.y-1,z=p.z+1}, floor, {"mcl_core:snowblock"})
1419 -- Check for collision with spruce
1420 local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+2,z=p.z+1}, {x=p.x+4, y=p.y+6, z=p.z+4}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"})
1422 if #surface >= 9 and #spruce_collisions == 0 then
1423 mcl_structures.call_struct(p, "ice_spike_large")
1425 elseif spike < 100 then
1426 -- Check surface
1427 local floor = {x=p.x+6, y=p.y-1, z=p.z+6}
1428 local surface = minetest.find_nodes_in_area({x=p.x+1,y=p.y-1,z=p.z+1}, floor, {"mcl_core:snowblock", "mcl_core:dirt_with_grass_snow"})
1430 -- Check for collision with spruce
1431 local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+1,z=p.z+1}, {x=p.x+6, y=p.y+6, z=p.z+6}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"})
1433 if #surface >= 25 and #spruce_collisions == 0 then
1434 mcl_structures.call_struct(p, "ice_spike_small")
1444 -- End exit portal
1445 elseif minp.y <= END_EXIT_PORTAL_POS.y and maxp.y >= END_EXIT_PORTAL_POS.y and
1446 minp.x <= END_EXIT_PORTAL_POS.x and maxp.x >= END_EXIT_PORTAL_POS.x and
1447 minp.z <= END_EXIT_PORTAL_POS.z and maxp.z >= END_EXIT_PORTAL_POS.z then
1448 local built = false
1449 for y=maxp.y, minp.y, -1 do
1450 local p = {x=END_EXIT_PORTAL_POS.x, y=y, z=END_EXIT_PORTAL_POS.z}
1451 if minetest.get_node(p).name == "mcl_end:end_stone" then
1452 mcl_structures.call_struct(p, "end_exit_portal")
1453 built = true
1454 break
1457 if not built then
1458 mcl_structures.call_struct(END_EXIT_PORTAL_POS, "end_exit_portal")
1463 -- Buffers for LuaVoxelManip
1464 local lvm_buffer = {}
1465 local lvm_buffer_param2 = {}
1467 -- Generate tree decorations in the bounding box. This adds:
1468 -- * Cocoa at jungle trees
1469 -- * Jungle tree vines
1470 -- * Oak vines in swamplands
1471 local function generate_tree_decorations(minp, maxp, seed, data, param2_data, area, biomemap, lvm_used)
1472 if maxp.y < 0 then
1473 return lvm_used
1476 local oaktree, oakleaves, jungletree, jungleleaves = {}, {}, {}, {}
1477 local swampland = minetest.get_biome_id("Swampland")
1478 local swampland_shore = minetest.get_biome_id("Swampland_shore")
1479 local jungle = minetest.get_biome_id("Jungle")
1480 local jungle_shore = minetest.get_biome_id("Jungle_shore")
1481 local jungle_m = minetest.get_biome_id("JungleM")
1482 local jungle_m_shore = minetest.get_biome_id("JungleM_shore")
1483 local jungle_edge = minetest.get_biome_id("JungleEdge")
1484 local jungle_edge_shore = minetest.get_biome_id("JungleEdge_shore")
1485 local jungle_edge_m = minetest.get_biome_id("JungleEdgeM")
1486 local jungle_edge_m_shore = minetest.get_biome_id("JungleEdgeM_shore")
1488 -- Modifier for Jungle M biome: More vines and cocoas
1489 local dense_vegetation = false
1491 if biomemap then
1492 -- Biome map available: Check if the required biome (jungle or swampland)
1493 -- is in this mapchunk. We are only interested in trees in the correct biome.
1494 -- The nodes are added if the correct biome is *anywhere* in the mapchunk.
1495 -- TODO: Strictly generate vines in the correct biomes only.
1496 local swamp_biome_found, jungle_biome_found = false, false
1497 for b=1, #biomemap do
1498 local id = biomemap[b]
1500 if not swamp_biome_found and (id == swampland or id == swampland_shore) then
1501 oaktree = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:tree"})
1502 oakleaves = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:leaves"})
1503 swamp_biome_found = true
1505 if not jungle_biome_found and (id == jungle or id == jungle_shore or id == jungle_m or id == jungle_m_shore or id == jungle_edge or id == jungle_edge_shore or id == jungle_edge_m or id == jungle_edge_m_shore) then
1506 jungletree = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungletree"})
1507 jungleleaves = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungleleaves"})
1508 jungle_biome_found = true
1510 if not dense_vegetation and (id == jungle_m or id == jungle_m_shore) then
1511 dense_vegetation = true
1513 if swamp_biome_found and jungle_biome_found and dense_vegetation then
1514 break
1517 else
1518 -- If there is no biome map, we just count all jungle things we can find.
1519 -- Oak vines will not be generated.
1520 jungletree = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungletree"})
1521 jungleleaves = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungleleaves"})
1524 local pos, treepos, dir
1526 local cocoachance = 40
1527 if dense_vegetation then
1528 cocoachance = 32
1531 -- Pass 1: Generate cocoas at jungle trees
1532 for n = 1, #jungletree do
1534 pos = table.copy(jungletree[n])
1535 treepos = table.copy(pos)
1537 if minetest.find_node_near(pos, 1, {"mcl_core:jungleleaves"}) then
1539 dir = math.random(1, cocoachance)
1541 if dir == 1 then
1542 pos.z = pos.z + 1
1543 elseif dir == 2 then
1544 pos.z = pos.z - 1
1545 elseif dir == 3 then
1546 pos.x = pos.x + 1
1547 elseif dir == 4 then
1548 pos.x = pos.x -1
1551 local p_pos = area:index(pos.x, pos.y, pos.z)
1552 local l = minetest.get_node_light(pos)
1554 if dir < 5
1555 and data[p_pos] == c_air
1556 and l ~= nil and l > 12 then
1557 local c = math.random(1, 3)
1558 if c == 1 then
1559 data[p_pos] = c_cocoa_1
1560 elseif c == 2 then
1561 data[p_pos] = c_cocoa_2
1562 else
1563 data[p_pos] = c_cocoa_3
1565 param2_data[p_pos] = minetest.dir_to_facedir(vector.subtract(treepos, pos))
1566 lvm_used = true
1572 -- Pass 2: Generate vines at jungle wood, jungle leaves in jungle and oak wood, oak leaves in swampland
1573 perlin_vines = perlin_vines or minetest.get_perlin(555, 4, 0.6, 500)
1574 perlin_vines_fine = perlin_vines_fine or minetest.get_perlin(43000, 3, 0.6, 1)
1575 perlin_vines_length = perlin_vines_length or minetest.get_perlin(435, 4, 0.6, 75)
1576 perlin_vines_upwards = perlin_vines_upwards or minetest.get_perlin(436, 3, 0.6, 10)
1577 perlin_vines_density = perlin_vines_density or minetest.get_perlin(436, 3, 0.6, 500)
1579 -- Extra long vines in Jungle M
1580 local maxvinelength = 7
1581 if dense_vegetation then
1582 maxvinelength = 14
1584 local treething
1585 for i=1, 4 do
1586 if i==1 then
1587 treething = jungletree
1588 elseif i == 2 then
1589 treething = jungleleaves
1590 elseif i == 3 then
1591 treething = oaktree
1592 elseif i == 4 then
1593 treething = oakleaves
1596 for n = 1, #treething do
1597 pos = treething[n]
1599 treepos = table.copy(pos)
1601 local dirs = {
1602 {x=1,y=0,z=0},
1603 {x=-1,y=0,z=0},
1604 {x=0,y=0,z=1},
1605 {x=0,y=0,z=-1},
1608 for d = 1, #dirs do
1609 local pos = vector.add(pos, dirs[d])
1610 local p_pos = area:index(pos.x, pos.y, pos.z)
1612 local vine_threshold = math.max(0.33333, perlin_vines_density:get_2d(pos))
1613 if dense_vegetation then
1614 vine_threshold = vine_threshold * (2/3)
1617 if perlin_vines:get_2d(pos) > -1.0 and perlin_vines_fine:get_3d(pos) > vine_threshold and data[p_pos] == c_air then
1619 local rdir = {}
1620 rdir.x = -dirs[d].x
1621 rdir.y = dirs[d].y
1622 rdir.z = -dirs[d].z
1623 local param2 = minetest.dir_to_wallmounted(rdir)
1625 -- Determine growth direction
1626 local grow_upwards = false
1627 -- Only possible on the wood, not on the leaves
1628 if i == 1 then
1629 grow_upwards = perlin_vines_upwards:get_3d(pos) > 0.8
1631 if grow_upwards then
1632 -- Grow vines up 1-4 nodes, even through jungleleaves.
1633 -- This may give climbing access all the way to the top of the tree :-)
1634 -- But this will be fairly rare.
1635 local length = math.ceil(math.abs(perlin_vines_length:get_3d(pos)) * 4)
1636 for l=0, length-1 do
1637 local t_pos = area:index(treepos.x, treepos.y, treepos.z)
1639 if (data[p_pos] == c_air or data[p_pos] == c_jungleleaves or data[p_pos] == c_leaves) and mcl_core.supports_vines(minetest.get_name_from_content_id(data[t_pos])) then
1640 data[p_pos] = c_vine
1641 param2_data[p_pos] = param2
1642 lvm_used = true
1644 else
1645 break
1647 pos.y = pos.y + 1
1648 p_pos = area:index(pos.x, pos.y, pos.z)
1649 treepos.y = treepos.y + 1
1651 else
1652 -- Grow vines down, length between 1 and maxvinelength
1653 local length = math.ceil(math.abs(perlin_vines_length:get_3d(pos)) * maxvinelength)
1654 for l=0, length-1 do
1655 if data[p_pos] == c_air then
1656 data[p_pos] = c_vine
1657 param2_data[p_pos] = param2
1658 lvm_used = true
1660 else
1661 break
1663 pos.y = pos.y - 1
1664 p_pos = area:index(pos.x, pos.y, pos.z)
1672 return lvm_used
1675 local pr_shroom = PseudoRandom(os.time()-24359)
1676 -- Generate mushrooms in caves manually.
1677 -- Minetest's API does not support decorations in caves yet. :-(
1678 local generate_underground_mushrooms = function(minp, maxp, seed)
1679 -- Generate rare underground mushrooms
1680 -- TODO: Make them appear in groups, use Perlin noise
1681 local min, max = mcl_vars.mg_lava_overworld_max + 4, 0
1682 if minp.y > max or maxp.y < min then
1683 return
1686 local bpos
1687 local stone = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_core:stone", "mcl_core:dirt", "mcl_core:mycelium", "mcl_core:podzol", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite", "mcl_core:stone_with_coal", "mcl_core:stone_with_iron", "mcl_core:stone_with_gold"})
1689 for n = 1, #stone do
1690 bpos = {x = stone[n].x, y = stone[n].y + 1, z = stone[n].z }
1692 local l = minetest.get_node_light(bpos, 0.5)
1693 if bpos.y >= min and bpos.y <= max and l ~= nil and l <= 12 and pr_shroom:next(1,1000) < 4 then
1694 if pr_shroom:next(1,2) == 1 then
1695 minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_brown"})
1696 else
1697 minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_red"})
1703 local pr_nether = PseudoRandom(os.time()+667)
1704 local nether_wart_chance
1705 if mg_name == "v6" then
1706 nether_wart_chance = 85
1707 else
1708 nether_wart_chance = 170
1710 -- Generate Nether decorations manually: Eternal fire, mushrooms, nether wart
1711 -- Minetest's API does not support decorations in caves yet. :-(
1712 local generate_nether_decorations = function(minp, maxp, seed)
1713 if minp.y > mcl_vars.mg_nether_max or maxp.y < mcl_vars.mg_nether_min then
1714 return
1717 -- TODO: Generate everything based on Perlin noise instead of PseudoRandom
1719 local bpos
1720 local rack = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:netherrack"})
1721 local magma = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:magma"})
1722 local ssand = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:soul_sand"})
1724 -- Helper function to spawn “fake” decoration
1725 local special_deco = function(nodes, spawn_func)
1726 for n = 1, #nodes do
1727 bpos = {x = nodes[n].x, y = nodes[n].y + 1, z = nodes[n].z }
1729 spawn_func(bpos)
1734 -- Eternal fire on netherrack
1735 special_deco(rack, function(bpos)
1736 -- Eternal fire on netherrack
1737 if pr_nether:next(1,100) <= 3 then
1738 minetest.set_node(bpos, {name = "mcl_fire:eternal_fire"})
1740 end)
1742 -- Eternal fire on magma cubes
1743 special_deco(magma, function(bpos)
1744 if pr_nether:next(1,150) == 1 then
1745 minetest.set_node(bpos, {name = "mcl_fire:eternal_fire"})
1747 end)
1749 -- Mushrooms on netherrack
1750 -- Note: Spawned *after* the fire because of light level checks
1751 special_deco(rack, function(bpos)
1752 local l = minetest.get_node_light(bpos, 0.5)
1753 if bpos.y > mcl_vars.mg_lava_nether_max + 6 and l ~= nil and l <= 12 and pr_nether:next(1,1000) <= 4 then
1754 -- TODO: Make mushrooms appear in groups, use Perlin noise
1755 if pr_nether:next(1,2) == 1 then
1756 minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_brown"})
1757 else
1758 minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_red"})
1761 end)
1763 -- Nether wart on soul sand
1764 -- TODO: Spawn in Nether fortresses
1765 special_deco(ssand, function(bpos)
1766 if pr_nether:next(1, nether_wart_chance) == 1 then
1767 minetest.set_node(bpos, {name = "mcl_nether:nether_wart"})
1769 end)
1773 -- Below the bedrock, generate air/void
1774 minetest.register_on_generated(function(minp, maxp, seed)
1775 local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
1776 local data = vm:get_data(lvm_buffer)
1777 local param2_data = vm:get_param2_data(lvm_buffer_param2)
1778 local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax})
1779 local aream = VoxelArea:new({MinEdge={x=minp.x, y=0, z=minp.z}, MaxEdge={x=maxp.x, y=0, z=maxp.z}})
1780 local lvm_used = false
1781 local biomemap
1783 local ymin, ymax
1785 -- Generate basic layer-based nodes: void, bedrock, realm barrier, lava seas, etc.
1786 -- Also perform some basic node replacements.
1788 -- Helper function to set all nodes in the layers between min and max.
1789 -- content_id: Node to set
1790 -- check: optional.
1791 -- If content_id, node will be set only if it is equal to check.
1792 -- If function(pos_to_check, content_id_at_this_pos), will set node only if returns true.
1793 -- min, max: Minimum and maximum Y levels of the layers to set
1794 -- minp, maxp: minp, maxp of the on_generated
1795 -- lvm_used: Set to true if any node in this on_generated has been set before.
1797 -- returns true if any node was set and lvm_used otherwise
1798 local function set_layers(content_id, check, min, max, minp, maxp, lvm_used)
1799 if (maxp.y >= min and minp.y <= max) then
1800 for y = math.max(min, minp.y), math.min(max, maxp.y) do
1801 for x = minp.x, maxp.x do
1802 for z = minp.z, maxp.z do
1803 local p_pos = area:index(x, y, z)
1804 if check then
1805 if type(check) == "function" and check({x=x,y=y,z=z}, data[p_pos]) then
1806 data[p_pos] = content_id
1807 lvm_used = true
1808 elseif check == data[p_pos] then
1809 data[p_pos] = content_id
1810 lvm_used = true
1812 else
1813 data[p_pos] = content_id
1814 lvm_used = true
1820 return lvm_used
1823 -- The Void
1824 lvm_used = set_layers(c_void, nil, -31000, mcl_vars.mg_nether_min-1, minp, maxp, lvm_used)
1825 lvm_used = set_layers(c_void, nil, mcl_vars.mg_nether_max+1, mcl_vars.mg_end_min-1, minp, maxp, lvm_used)
1826 lvm_used = set_layers(c_void, nil, mcl_vars.mg_end_max+1, mcl_vars.mg_realm_barrier_overworld_end_min-1, minp, maxp, lvm_used)
1827 lvm_used = set_layers(c_void, nil, mcl_vars.mg_realm_barrier_overworld_end_max+1, mcl_vars.mg_overworld_min-1, minp, maxp, lvm_used)
1829 -- Realm barrier between the Overworld void and the End
1830 lvm_used = set_layers(c_realm_barrier, nil, mcl_vars.mg_realm_barrier_overworld_end_min, mcl_vars.mg_realm_barrier_overworld_end_max, minp, maxp, lvm_used)
1832 if mg_name ~= "singlenode" then
1833 -- Bedrock
1834 local bedrock_check
1835 if mcl_vars.mg_bedrock_is_rough then
1836 bedrock_check = function(pos)
1837 local y = pos.y
1838 -- Bedrock layers with increasing levels of roughness, until a perfecly flat bedrock later at the bottom layer
1839 -- This code assumes a bedrock height of 5 layers.
1841 local diff = mcl_vars.mg_bedrock_overworld_max - y -- Overworld bedrock
1842 local ndiff1 = mcl_vars.mg_bedrock_nether_bottom_max - y -- Nether bedrock, bottom
1843 local ndiff2 = mcl_vars.mg_bedrock_nether_top_max - y -- Nether bedrock, ceiling
1845 local top
1846 if diff == 0 or ndiff1 == 0 or ndiff2 == 4 then
1847 -- 50% bedrock chance
1848 top = 2
1849 elseif diff == 1 or ndiff1 == 1 or ndiff2 == 3 then
1850 -- 66.666...%
1851 top = 3
1852 elseif diff == 2 or ndiff1 == 2 or ndiff2 == 2 then
1853 -- 75%
1854 top = 4
1855 elseif diff == 3 or ndiff1 == 3 or ndiff2 == 1 then
1856 -- 90%
1857 top = 10
1858 elseif diff == 4 or ndiff1 == 4 or ndiff2 == 0 then
1859 -- 100%
1860 return true
1861 else
1862 -- Not in bedrock layer
1863 return false
1866 return math.random(1, top) <= top-1
1868 else
1869 bedrock_check = nil
1872 lvm_used = set_layers(c_bedrock, bedrock_check, mcl_vars.mg_bedrock_overworld_min, mcl_vars.mg_bedrock_overworld_max, minp, maxp, lvm_used)
1873 lvm_used = set_layers(c_bedrock, bedrock_check, mcl_vars.mg_bedrock_nether_bottom_min, mcl_vars.mg_bedrock_nether_bottom_max, minp, maxp, lvm_used)
1874 lvm_used = set_layers(c_bedrock, bedrock_check, mcl_vars.mg_bedrock_nether_top_min, mcl_vars.mg_bedrock_nether_top_max, minp, maxp, lvm_used)
1876 -- Flat Nether
1877 if mg_name == "flat" then
1878 lvm_used = set_layers(c_air, nil, mcl_vars.mg_flat_nether_floor, mcl_vars.mg_flat_nether_ceiling, minp, maxp, lvm_used)
1881 -- Big lava seas by replacing air below a certain height
1882 if mcl_vars.mg_lava then
1883 lvm_used = set_layers(c_lava, c_air, mcl_vars.mg_overworld_min, mcl_vars.mg_lava_overworld_max, emin, emax, lvm_used)
1884 lvm_used = set_layers(c_nether_lava, c_air, mcl_vars.mg_nether_min, mcl_vars.mg_lava_nether_max, emin, emax, lvm_used)
1887 -- Clay, vines, cocoas
1888 lvm_used = generate_clay(minp, maxp, seed, data, area, lvm_used)
1890 biomemap = minetest.get_mapgen_object("biomemap")
1891 lvm_used = generate_tree_decorations(minp, maxp, seed, data, param2_data, area, biomemap, lvm_used)
1893 ----- Interactive block fixing section -----
1894 ----- The section to perform basic block overrides of the core mapgen generated world. -----
1896 -- Snow and sand fixes. This code implements snow consistency
1897 -- and fixes floating sand and cut plants.
1898 -- A snowy grass block must be below a top snow or snow block at all times.
1899 if emin.y <= mcl_vars.mg_overworld_max and emax.y >= mcl_vars.mg_overworld_min then
1900 -- v6 mapgen:
1901 if mg_name == "v6" then
1903 --[[ Remove broken double plants caused by v6 weirdness.
1904 v6 might break the bottom part of double plants because of how it works.
1905 There are 3 possibilities:
1906 1) Jungle: Top part is placed on top of a jungle tree or fern (=v6 jungle grass).
1907 This is because the schematic might be placed even if some nodes of it
1908 could not be placed because the destination was already occupied.
1909 TODO: A better fix for this would be if schematics could abort placement
1910 altogether if ANY of their nodes could not be placed.
1911 2) Cavegen: Removes the bottom part, the upper part floats
1912 3) Mudflow: Same as 2) ]]
1913 local plants = minetest.find_nodes_in_area(emin, emax, "group:double_plant")
1914 for n = 1, #plants do
1915 local node = vm:get_node_at(plants[n])
1916 local is_top = minetest.get_item_group(node.name, "double_plant") == 2
1917 if is_top then
1918 local p_pos = area:index(plants[n].x, plants[n].y-1, plants[n].z)
1919 if p_pos then
1920 node = vm:get_node_at({x=plants[n].x, y=plants[n].y-1, z=plants[n].z})
1921 local is_bottom = minetest.get_item_group(node.name, "double_plant") == 1
1922 if not is_bottom then
1923 p_pos = area:index(plants[n].x, plants[n].y, plants[n].z)
1924 data[p_pos] = c_air
1925 lvm_used = true
1932 -- Non-v6 mapgens:
1933 else
1934 -- Set param2 (=color) of grass blocks.
1935 -- Clear snowy grass blocks without snow above to ensure consistency.
1936 local nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:dirt_with_grass", "mcl_core:dirt_with_grass_snow"})
1937 for n=1, #nodes do
1938 local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z)
1939 local p_pos_above = area:index(nodes[n].x, nodes[n].y+1, nodes[n].z)
1940 local p_pos_below = area:index(nodes[n].x, nodes[n].y-1, nodes[n].z)
1941 local b_pos = aream:index(nodes[n].x, 0, nodes[n].z)
1942 local bn = minetest.get_biome_name(biomemap[b_pos])
1943 if bn then
1944 local biome = minetest.registered_biomes[bn]
1945 if biome then
1946 if biome._mcl_biome_type then
1947 param2_data[p_pos] = biome._mcl_palette_index
1948 lvm_used = true
1952 if data[p_pos] == c_dirt_with_grass_snow and p_pos_above and data[p_pos_above] ~= c_top_snow and data[p_pos_above] ~= c_snow_block then
1953 data[p_pos] = c_dirt_with_grass
1954 lvm_used = true
1959 -- Nether block fixes:
1960 -- * Replace water with Nether lava.
1961 -- * Replace stone, sand dirt in v6 so the Nether works in v6.
1962 elseif emin.y <= mcl_vars.mg_nether_max and emax.y >= mcl_vars.mg_nether_min then
1963 local nodes
1964 if mg_name == "v6" then
1965 nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"})
1966 else
1967 nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source"})
1969 for n=1, #nodes do
1970 local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z)
1971 if data[p_pos] == c_water then
1972 data[p_pos] = c_nether_lava
1973 lvm_used = true
1974 elseif data[p_pos] == c_stone then
1975 data[p_pos] = c_netherrack
1976 lvm_used = true
1977 elseif data[p_pos] == c_sand or data[p_pos] == c_dirt then
1978 data[p_pos] = c_soul_sand
1979 lvm_used = true
1983 -- End block fixes:
1984 -- * Replace water with end stone or air (depending on height).
1985 -- * Remove stone, sand, dirt in v6 so our End map generator works in v6.
1986 -- * Generate spawn platform (End portal destination)
1987 elseif emin.y <= mcl_vars.mg_end_max and emax.y >= mcl_vars.mg_end_min then
1988 local nodes
1989 if mg_name == "v6" then
1990 nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"})
1991 else
1992 nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source"})
1994 for n=1, #nodes do
1995 local y = nodes[n].y
1996 local p_pos = area:index(nodes[n].x, y, nodes[n].z)
1998 if data[p_pos] == c_water or data[p_pos] == c_stone or data[p_pos] == c_dirt or data[p_pos] == c_sand then
1999 data[p_pos] = c_air
2000 lvm_used = true
2005 -- Obsidian spawn platform
2006 if minp.y <= mcl_vars.mg_end_platform_pos.y and maxp.y >= mcl_vars.mg_end_platform_pos.y and
2007 minp.x <= mcl_vars.mg_end_platform_pos.x and maxp.x >= mcl_vars.mg_end_platform_pos.z and
2008 minp.z <= mcl_vars.mg_end_platform_pos.z and maxp.z >= mcl_vars.mg_end_platform_pos.z then
2009 for x=math.max(minp.x, mcl_vars.mg_end_platform_pos.x-2), math.min(maxp.x, mcl_vars.mg_end_platform_pos.x+2) do
2010 for z=math.max(minp.z, mcl_vars.mg_end_platform_pos.z-2), math.min(maxp.z, mcl_vars.mg_end_platform_pos.z+2) do
2011 for y=math.max(minp.y, mcl_vars.mg_end_platform_pos.y), math.min(maxp.y, mcl_vars.mg_end_platform_pos.y+2) do
2012 local p_pos = area:index(x, y, z)
2013 if y == mcl_vars.mg_end_platform_pos.y then
2014 data[p_pos] = c_obsidian
2015 else
2016 data[p_pos] = c_air
2021 lvm_used = true
2026 -- Final hackery: Set sun light level in the End.
2027 -- -26912 is at a mapchunk border.
2028 local shadow
2029 if minp.y >= -26912 and maxp.y <= mcl_vars.mg_end_max then
2030 vm:set_lighting({day=15, night=15})
2031 lvm_used = true
2033 if minp.y >= mcl_vars.mg_end_min and maxp.y <= -26911 then
2034 shadow = false
2035 lvm_used = true
2038 -- Write stuff
2039 if lvm_used then
2040 vm:set_data(data)
2041 vm:set_param2_data(param2_data)
2042 vm:calc_lighting(nil, nil, shadow)
2043 vm:write_to_map()
2044 vm:update_liquids()
2047 if mg_name ~= "singlenode" then
2048 -- Generate special decorations
2049 generate_underground_mushrooms(minp, maxp, seed)
2050 generate_nether_decorations(minp, maxp, seed)
2051 generate_structures(minp, maxp, seed, biomemap)
2053 end)