2 -- Aliases for map generator outputs
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")
34 minetest
.register_alias("mapgen_river_water_source", "mcl_core:water_source")
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
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
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({
98 wherein
= {"mcl_core:stone"},
99 clust_scarcity
= 15*15*15,
102 y_min
= mcl_vars
.mg_overworld_min
,
103 y_max
= mcl_vars
.mg_overworld_max
,
105 minetest
.register_ore({
108 wherein
= {"mcl_core:stone"},
109 clust_scarcity
= 10*10*10,
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"}
120 minetest
.register_ore({
122 ore
= "mcl_core:dirt",
124 clust_scarcity
= 15*15*15,
127 y_min
= mcl_vars
.mg_overworld_min
,
128 y_max
= mcl_vars
.mg_overworld_max
,
132 minetest
.register_ore({
134 ore
= "mcl_core:gravel",
136 clust_scarcity
= 14*14*14,
139 y_min
= mcl_vars
.mg_overworld_min
,
140 y_max
= mcl_worlds
.layer_to_y(111),
148 minetest
.register_ore({
149 ore_type
= "scatter",
150 ore
= "mcl_core:stone_with_coal",
152 clust_scarcity
= 525*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",
162 clust_scarcity
= 510*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",
172 clust_scarcity
= 500*3,
175 y_min
= mcl_vars
.mg_overworld_min
,
176 y_max
= mcl_worlds
.layer_to_y(50),
180 minetest
.register_ore({
181 ore_type
= "scatter",
182 ore
= "mcl_core:stone_with_coal",
184 clust_scarcity
= 550*3,
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",
194 clust_scarcity
= 525*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",
204 clust_scarcity
= 500*3,
207 y_min
= mcl_worlds
.layer_to_y(51),
208 y_max
= mcl_worlds
.layer_to_y(80),
212 minetest
.register_ore({
213 ore_type
= "scatter",
214 ore
= "mcl_core:stone_with_coal",
216 clust_scarcity
= 600*3,
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",
226 clust_scarcity
= 550*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",
236 clust_scarcity
= 500*3,
239 y_min
= mcl_worlds
.layer_to_y(81),
240 y_max
= mcl_worlds
.layer_to_y(128),
246 minetest
.register_ore({
247 ore_type
= "scatter",
248 ore
= "mcl_core:stone_with_iron",
250 clust_scarcity
= 830,
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",
260 clust_scarcity
= 1660,
263 y_min
= mcl_worlds
.layer_to_y(40),
264 y_max
= mcl_worlds
.layer_to_y(63),
272 minetest
.register_ore({
273 ore_type
= "scatter",
274 ore
= "mcl_core:stone_with_gold",
276 clust_scarcity
= 4775,
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",
286 clust_scarcity
= 6560,
289 y_min
= mcl_vars
.mg_overworld_min
,
290 y_max
= mcl_worlds
.layer_to_y(30),
294 minetest
.register_ore({
295 ore_type
= "scatter",
296 ore
= "mcl_core:stone_with_gold",
298 clust_scarcity
= 13000,
301 y_min
= mcl_worlds
.layer_to_y(31),
302 y_max
= mcl_worlds
.layer_to_y(33),
310 minetest
.register_ore({
311 ore_type
= "scatter",
312 ore
= "mcl_core:stone_with_diamond",
314 clust_scarcity
= 10000,
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",
324 clust_scarcity
= 5000,
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",
334 clust_scarcity
= 10000,
337 y_min
= mcl_vars
.mg_overworld_min
,
338 y_max
= mcl_worlds
.layer_to_y(12),
342 minetest
.register_ore({
343 ore_type
= "scatter",
344 ore
= "mcl_core:stone_with_diamond",
346 clust_scarcity
= 20000,
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",
356 clust_scarcity
= 20000,
359 y_min
= mcl_worlds
.layer_to_y(13),
360 y_max
= mcl_worlds
.layer_to_y(15),
368 minetest
.register_ore({
369 ore_type
= "scatter",
370 ore
= "mcl_core:stone_with_redstone",
372 clust_scarcity
= 500,
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",
382 clust_scarcity
= 800,
385 y_min
= mcl_vars
.mg_overworld_min
,
386 y_max
= mcl_worlds
.layer_to_y(13),
390 minetest
.register_ore({
391 ore_type
= "scatter",
392 ore
= "mcl_core:stone_with_redstone",
394 clust_scarcity
= 1000,
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",
404 clust_scarcity
= 1600,
407 y_min
= mcl_worlds
.layer_to_y(13),
408 y_max
= mcl_worlds
.layer_to_y(15),
415 if mg_name
== "v6" then
416 -- Generate everywhere in v6, but rarely.
419 minetest
.register_ore({
420 ore_type
= "scatter",
421 ore
= "mcl_core:stone_with_emerald",
423 clust_scarcity
= 14340,
426 y_min
= mcl_vars
.mg_overworld_min
,
427 y_max
= mcl_worlds
.layer_to_y(29),
430 minetest
.register_ore({
431 ore_type
= "scatter",
432 ore
= "mcl_core:stone_with_emerald",
434 clust_scarcity
= 21510,
437 y_min
= mcl_worlds
.layer_to_y(30),
438 y_max
= mcl_worlds
.layer_to_y(32),
446 -- Common spawn (in the center)
447 minetest
.register_ore({
448 ore_type
= "scatter",
449 ore
= "mcl_core:stone_with_lapis",
451 clust_scarcity
= 10000,
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",
463 clust_scarcity
= 12000,
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",
473 clust_scarcity
= 14000,
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",
483 clust_scarcity
= 16000,
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",
493 clust_scarcity
= 18000,
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",
505 clust_scarcity
= 12000,
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",
515 clust_scarcity
= 14000,
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",
525 clust_scarcity
= 16000,
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",
535 clust_scarcity
= 18000,
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",
545 clust_scarcity
= 32000,
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,
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",
571 clust_scarcity
= 2000,
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",
582 clust_scarcity
= 9000,
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",
594 clust_scarcity
= 32000,
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",
605 clust_scarcity
= 72000,
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",
617 clust_scarcity
= 96000,
620 y_min
= mcl_worlds
.layer_to_y(62),
621 y_max
= mcl_worlds
.layer_to_y(127),
625 local function register_mgv6_decorations()
628 minetest
.register_decoration({
629 deco_type
= "simple",
630 place_on
= {"group:sand"},
635 spread
= {x
= 100, y
= 100, z
= 100},
641 y_max
= mcl_vars
.mg_overworld_max
,
642 decoration
= "mcl_core:cactus",
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"},
655 spread
= {x
= 100, y
= 100, z
= 100},
661 y_max
= mcl_vars
.mg_overworld_max
,
662 decoration
= "mcl_core:reeds",
665 spawn_by
= { "mcl_core:water_source", "group:frosted_ice" },
670 minetest
.register_decoration({
671 deco_type
= "schematic",
673 size
= { x
=1, y
=3, z
=1 },
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"},
685 spread
= {x
= 100, y
= 100, z
= 100},
691 y_max
= mcl_vars
.mg_overworld_max
,
695 minetest
.register_decoration({
696 deco_type
= "schematic",
698 size
= { x
=1, y
=3, z
=1 },
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" },
708 place_on
= {"group:grass_block_no_snow"},
714 spread
= {x
= 250, y
= 250, z
= 250},
720 y_max
= mcl_vars
.mg_overworld_max
,
724 local register_large_flower
= function(name
, seed
, offset
)
725 minetest
.register_decoration({
726 deco_type
= "schematic",
728 size
= { x
=1, y
=3, z
=1 },
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"},
741 spread
= {x
= 300, y
= 300, z
= 300},
747 y_max
= mcl_vars
.overworld_max
,
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)
758 minetest
.register_decoration({
759 deco_type
= "schematic",
761 size
= { x
=1, y
=3, z
=1 },
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",
773 spread
= {x
= 200, y
= 200, z
= 200},
784 minetest
.register_decoration({
785 deco_type
= "simple",
786 decoration
= "mcl_farming:pumpkin_face",
789 place_on
= {"group:grass_block_no_snow"},
794 spread
= {x
= 250, y
= 250, z
= 250},
800 y_max
= mcl_vars
.overworld_max
,
804 minetest
.register_decoration({
805 deco_type
= "simple",
806 place_on
= {"group:grass_block_no_snow"},
811 spread
= {x
= 250, y
= 250, z
= 250},
816 -- Small trick to make sure melon spawn in jungles
817 spawn_by
= { "mcl_core:jungletree", "mcl_flowers:fern" },
821 decoration
= "mcl_farming:melon",
825 minetest
.register_decoration({
826 deco_type
= "simple",
827 place_on
= {"group:grass_block_no_snow"},
832 spread
= {x
= 100, y
= 100, z
= 100},
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"},
848 spread
= {x
= 100, y
= 100, z
= 100},
854 y_max
= mcl_vars
.overworld_max
,
855 decoration
= "mcl_flowers:tallgrass",
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"},
867 place_on
= {"mcl_core:"..mat
},
872 spread
= {x
= 100, y
= 100, z
= 100},
877 flags
= "force_placement",
879 y_min
= mcl_vars
.overworld_min
,
881 decoration
= "mcl_ocean:seagrass_"..mat
,
883 minetest
.register_decoration({
884 deco_type
= "simple",
885 spawn_by
= {"group:water"},
887 place_on
= {"mcl_core:mat"},
892 spread
= {x
= 100, y
= 100, z
= 100},
897 flags
= "force_placement",
899 y_min
= mcl_vars
.overworld_min
,
901 decoration
= "mcl_ocean:seagrass_"..mat
,
904 minetest
.register_decoration({
905 deco_type
= "simple",
906 spawn_by
= {"group:water"},
908 place_on
= {"mcl_core:"..mat
},
913 spread
= {x
= 300, y
= 300, z
= 300},
918 flags
= "force_placement",
920 y_min
= mcl_vars
.overworld_min
,
922 decoration
= "mcl_ocean:kelp_"..mat
,
926 minetest
.register_decoration({
927 deco_type
= "simple",
928 spawn_by
= {"group:water"},
930 place_on
= {"mcl_core:"..mat
},
935 spread
= {x
= 100, y
= 100, z
= 100},
940 flags
= "force_placement",
942 y_min
= mcl_vars
.overworld_min
,
944 decoration
= "mcl_ocean:kelp_"..mat
,
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"},
958 place_on
= {"mcl_core:dirt","mcl_core:sand"},
963 spread
= {x
= 250, y
= 250, z
= 250},
968 flags
= "force_placement",
969 y_min
= mcl_vars
.mg_lava_overworld_max
+ 5,
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"},
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"},
995 spread
= {x
= 100, y
= 100, z
= 100},
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", },
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"},
1016 spread
= {x
= 100, y
= 100, z
= 100},
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
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"},
1040 spread
= {x
= 100, y
= 100, z
= 100},
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"},
1072 fill_ratio
= 11.0, -- complete coverage
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
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
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
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
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
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
1159 perlin_clay
= perlin_clay
or minetest
.get_perlin({
1162 spread
= {x
= 5, y
= 5, z
= 5},
1168 for y
=math
.max(minp
.y
, 0), math
.min(maxp
.y
, -8), -1 do
1169 -- Assume X and Z lengths are equal
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
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
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)
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
})
1235 local def
= minetest
.registered_nodes
[checknode
.name
]
1236 if def
and def
.walkable
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
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
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
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
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")
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
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}
1336 if r
== "0" or r
== "180" then
1337 size
= {x
=10, y
=4, z
=8}
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})
1373 elseif r
== "180" then
1380 elseif r
== "270" then
1387 elseif r
== "90" then
1395 for o
=1, #offsets
do
1397 for y
=place
.y
-1, place
.y
-64, -1 do
1398 local tpos
= vector
.add(place
, offsets
[o
])
1400 ok
= place_tree_if_free(tpos
, ok
)
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)
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
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")
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
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")
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
)
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
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
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
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
)
1543 elseif dir
== 2 then
1545 elseif dir
== 3 then
1547 elseif dir
== 4 then
1551 local p_pos
= area
:index(pos
.x
, pos
.y
, pos
.z
)
1552 local l
= minetest
.get_node_light(pos
)
1555 and data
[p_pos
] == c_air
1556 and l
~= nil and l
> 12 then
1557 local c
= math
.random(1, 3)
1559 data
[p_pos
] = c_cocoa_1
1561 data
[p_pos
] = c_cocoa_2
1563 data
[p_pos
] = c_cocoa_3
1565 param2_data
[p_pos
] = minetest
.dir_to_facedir(vector
.subtract(treepos
, pos
))
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
1587 treething
= jungletree
1589 treething
= jungleleaves
1593 treething
= oakleaves
1596 for n
= 1, #treething
do
1599 treepos
= table.copy(pos
)
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
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
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
1648 p_pos
= area
:index(pos
.x
, pos
.y
, pos
.z
)
1649 treepos
.y
= treepos
.y
+ 1
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
1664 p_pos
= area
:index(pos
.x
, pos
.y
, pos
.z
)
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
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"})
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
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
1717 -- TODO: Generate everything based on Perlin noise instead of PseudoRandom
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
}
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"})
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"})
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"})
1758 minetest
.set_node(bpos
, {name
= "mcl_mushrooms:mushroom_red"})
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"})
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
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
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
)
1805 if type(check
) == "function" and check({x
=x
,y
=y
,z
=z
}, data
[p_pos
]) then
1806 data
[p_pos
] = content_id
1808 elseif check
== data
[p_pos
] then
1809 data
[p_pos
] = content_id
1813 data
[p_pos
] = content_id
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
1835 if mcl_vars
.mg_bedrock_is_rough
then
1836 bedrock_check
= function(pos
)
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
1846 if diff
== 0 or ndiff1
== 0 or ndiff2
== 4 then
1847 -- 50% bedrock chance
1849 elseif diff
== 1 or ndiff1
== 1 or ndiff2
== 3 then
1852 elseif diff
== 2 or ndiff1
== 2 or ndiff2
== 2 then
1855 elseif diff
== 3 or ndiff1
== 3 or ndiff2
== 1 then
1858 elseif diff
== 4 or ndiff1
== 4 or ndiff2
== 0 then
1862 -- Not in bedrock layer
1866 return math
.random(1, top
) <= top
-1
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
)
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
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
1918 local p_pos
= area
:index(plants
[n
].x
, plants
[n
].y
-1, plants
[n
].z
)
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
)
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"})
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
])
1944 local biome
= minetest
.registered_biomes
[bn
]
1946 if biome
._mcl_biome_type
then
1947 param2_data
[p_pos
] = biome
._mcl_palette_index
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
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
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"})
1967 nodes
= minetest
.find_nodes_in_area(emin
, emax
, {"mcl_core:water_source"})
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
1974 elseif data
[p_pos
] == c_stone
then
1975 data
[p_pos
] = c_netherrack
1977 elseif data
[p_pos
] == c_sand
or data
[p_pos
] == c_dirt
then
1978 data
[p_pos
] = c_soul_sand
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
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"})
1992 nodes
= minetest
.find_nodes_in_area(emin
, emax
, {"mcl_core:water_source"})
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
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
2026 -- Final hackery: Set sun light level in the End.
2027 -- -26912 is at a mapchunk border.
2029 if minp
.y
>= -26912 and maxp
.y
<= mcl_vars
.mg_end_max
then
2030 vm
:set_lighting({day
=15, night
=15})
2033 if minp
.y
>= mcl_vars
.mg_end_min
and maxp
.y
<= -26911 then
2041 vm
:set_param2_data(param2_data
)
2042 vm
:calc_lighting(nil, nil, shadow
)
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
)