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 minetest
.register_alias("mapgen_river_water_source", "mcl_core:water_source")
32 minetest
.register_alias("mapgen_snow", "mcl_core:snow")
33 minetest
.register_alias("mapgen_snowblock", "mcl_core:snowblock")
34 minetest
.register_alias("mapgen_ice", "mcl_core:ice")
36 minetest
.register_alias("mapgen_stair_cobble", "mcl_stairs:stair_cobble")
37 minetest
.register_alias("mapgen_sandstonebrick", "mcl_core:sandstonesmooth")
38 minetest
.register_alias("mapgen_stair_sandstonebrick", "mcl_stairs:stair_sandstone")
39 minetest
.register_alias("mapgen_stair_sandstone_block", "mcl_stairs:stair_sandstone")
40 minetest
.register_alias("mapgen_stair_desert_stone", "mcl_stairs:stair_sandstone")
42 local mg_name
= minetest
.get_mapgen_setting("mg_name")
44 local WITCH_HUT_HEIGHT
= 3 -- Exact Y level to spawn witch huts at. This height refers to the height of the floor
50 -- Diorite, andesite and granite
51 local specialstones
= { "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite" }
52 for s
=1, #specialstones
do
53 local node
= specialstones
[s
]
54 minetest
.register_ore({
57 wherein
= {"mcl_core:stone"},
58 clust_scarcity
= 15*15*15,
61 y_min
= mcl_vars
.mg_overworld_min
,
62 y_max
= mcl_vars
.mg_overworld_max
,
64 minetest
.register_ore({
67 wherein
= {"mcl_core:stone"},
68 clust_scarcity
= 10*10*10,
71 y_min
= mcl_vars
.mg_overworld_min
,
72 y_max
= mcl_vars
.mg_overworld_max
,
76 local stonelike
= {"mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite"}
79 minetest
.register_ore({
81 ore
= "mcl_core:dirt",
83 clust_scarcity
= 15*15*15,
86 y_min
= mcl_vars
.mg_overworld_min
,
87 y_max
= mcl_vars
.mg_overworld_max
,
91 minetest
.register_ore({
93 ore
= "mcl_core:gravel",
95 clust_scarcity
= 14*14*14,
98 y_min
= mcl_vars
.mg_overworld_min
,
99 y_max
= mcl_util
.layer_to_y(111),
107 minetest
.register_ore({
108 ore_type
= "scatter",
109 ore
= "mcl_core:stone_with_coal",
111 clust_scarcity
= 525*3,
114 y_min
= mcl_vars
.mg_overworld_min
,
115 y_max
= mcl_util
.layer_to_y(50),
117 minetest
.register_ore({
118 ore_type
= "scatter",
119 ore
= "mcl_core:stone_with_coal",
121 clust_scarcity
= 510*3,
124 y_min
= mcl_vars
.mg_overworld_min
,
125 y_max
= mcl_util
.layer_to_y(50),
127 minetest
.register_ore({
128 ore_type
= "scatter",
129 ore
= "mcl_core:stone_with_coal",
131 clust_scarcity
= 500*3,
134 y_min
= mcl_vars
.mg_overworld_min
,
135 y_max
= mcl_util
.layer_to_y(50),
139 minetest
.register_ore({
140 ore_type
= "scatter",
141 ore
= "mcl_core:stone_with_coal",
143 clust_scarcity
= 550*3,
146 y_min
= mcl_util
.layer_to_y(51),
147 y_max
= mcl_util
.layer_to_y(80),
149 minetest
.register_ore({
150 ore_type
= "scatter",
151 ore
= "mcl_core:stone_with_coal",
153 clust_scarcity
= 525*3,
156 y_min
= mcl_util
.layer_to_y(51),
157 y_max
= mcl_util
.layer_to_y(80),
159 minetest
.register_ore({
160 ore_type
= "scatter",
161 ore
= "mcl_core:stone_with_coal",
163 clust_scarcity
= 500*3,
166 y_min
= mcl_util
.layer_to_y(51),
167 y_max
= mcl_util
.layer_to_y(80),
171 minetest
.register_ore({
172 ore_type
= "scatter",
173 ore
= "mcl_core:stone_with_coal",
175 clust_scarcity
= 600*3,
178 y_min
= mcl_util
.layer_to_y(81),
179 y_max
= mcl_util
.layer_to_y(128),
181 minetest
.register_ore({
182 ore_type
= "scatter",
183 ore
= "mcl_core:stone_with_coal",
185 clust_scarcity
= 550*3,
188 y_min
= mcl_util
.layer_to_y(81),
189 y_max
= mcl_util
.layer_to_y(128),
191 minetest
.register_ore({
192 ore_type
= "scatter",
193 ore
= "mcl_core:stone_with_coal",
195 clust_scarcity
= 500*3,
198 y_min
= mcl_util
.layer_to_y(81),
199 y_max
= mcl_util
.layer_to_y(128),
205 minetest
.register_ore({
206 ore_type
= "scatter",
207 ore
= "mcl_core:stone_with_iron",
209 clust_scarcity
= 830,
212 y_min
= mcl_vars
.mg_overworld_min
,
213 y_max
= mcl_util
.layer_to_y(39),
215 minetest
.register_ore({
216 ore_type
= "scatter",
217 ore
= "mcl_core:stone_with_iron",
219 clust_scarcity
= 1660,
222 y_min
= mcl_util
.layer_to_y(40),
223 y_max
= mcl_util
.layer_to_y(63),
231 minetest
.register_ore({
232 ore_type
= "scatter",
233 ore
= "mcl_core:stone_with_gold",
235 clust_scarcity
= 4775,
238 y_min
= mcl_vars
.mg_overworld_min
,
239 y_max
= mcl_util
.layer_to_y(30),
241 minetest
.register_ore({
242 ore_type
= "scatter",
243 ore
= "mcl_core:stone_with_gold",
245 clust_scarcity
= 6560,
248 y_min
= mcl_vars
.mg_overworld_min
,
249 y_max
= mcl_util
.layer_to_y(30),
253 minetest
.register_ore({
254 ore_type
= "scatter",
255 ore
= "mcl_core:stone_with_gold",
257 clust_scarcity
= 13000,
260 y_min
= mcl_util
.layer_to_y(31),
261 y_max
= mcl_util
.layer_to_y(33),
272 minetest
.register_ore({
273 ore_type
= "scatter",
274 ore
= "mcl_core:stone_with_diamond",
276 clust_scarcity
= 10000,
279 y_min
= mcl_vars
.mg_overworld_min
,
280 y_max
= mcl_util
.layer_to_y(12),
282 minetest
.register_ore({
283 ore_type
= "scatter",
284 ore
= "mcl_core:stone_with_diamond",
286 clust_scarcity
= 5000,
289 y_min
= mcl_vars
.mg_overworld_min
,
290 y_max
= mcl_util
.layer_to_y(12),
292 minetest
.register_ore({
293 ore_type
= "scatter",
294 ore
= "mcl_core:stone_with_diamond",
296 clust_scarcity
= 10000,
299 y_min
= mcl_vars
.mg_overworld_min
,
300 y_max
= mcl_util
.layer_to_y(12),
304 minetest
.register_ore({
305 ore_type
= "scatter",
306 ore
= "mcl_core:stone_with_diamond",
308 clust_scarcity
= 20000,
311 y_min
= mcl_util
.layer_to_y(13),
312 y_max
= mcl_util
.layer_to_y(15),
314 minetest
.register_ore({
315 ore_type
= "scatter",
316 ore
= "mcl_core:stone_with_diamond",
318 clust_scarcity
= 20000,
321 y_min
= mcl_util
.layer_to_y(13),
322 y_max
= mcl_util
.layer_to_y(15),
330 minetest
.register_ore({
331 ore_type
= "scatter",
332 ore
= "mcl_core:stone_with_redstone",
334 clust_scarcity
= 500,
337 y_min
= mcl_vars
.mg_overworld_min
,
338 y_max
= mcl_util
.layer_to_y(13),
340 minetest
.register_ore({
341 ore_type
= "scatter",
342 ore
= "mcl_core:stone_with_redstone",
344 clust_scarcity
= 800,
347 y_min
= mcl_vars
.mg_overworld_min
,
348 y_max
= mcl_util
.layer_to_y(13),
352 minetest
.register_ore({
353 ore_type
= "scatter",
354 ore
= "mcl_core:stone_with_redstone",
356 clust_scarcity
= 1000,
359 y_min
= mcl_util
.layer_to_y(13),
360 y_max
= mcl_util
.layer_to_y(15),
362 minetest
.register_ore({
363 ore_type
= "scatter",
364 ore
= "mcl_core:stone_with_redstone",
366 clust_scarcity
= 1600,
369 y_min
= mcl_util
.layer_to_y(13),
370 y_max
= mcl_util
.layer_to_y(15),
378 minetest
.register_ore({
379 ore_type
= "scatter",
380 ore
= "mcl_core:stone_with_emerald",
382 clust_scarcity
= 14340,
385 y_min
= mcl_vars
.mg_overworld_min
,
386 y_max
= mcl_util
.layer_to_y(29),
389 minetest
.register_ore({
390 ore_type
= "scatter",
391 ore
= "mcl_core:stone_with_emerald",
393 clust_scarcity
= 21510,
396 y_min
= mcl_util
.layer_to_y(30),
397 y_max
= mcl_util
.layer_to_y(32),
404 -- Common spawn (in the center)
405 minetest
.register_ore({
406 ore_type
= "scatter",
407 ore
= "mcl_core:stone_with_lapis",
409 clust_scarcity
= 10000,
412 y_min
= mcl_util
.layer_to_y(14),
413 y_max
= mcl_util
.layer_to_y(16),
416 -- Rare spawn (below center)
417 minetest
.register_ore({
418 ore_type
= "scatter",
419 ore
= "mcl_core:stone_with_lapis",
421 clust_scarcity
= 12000,
424 y_min
= mcl_util
.layer_to_y(10),
425 y_max
= mcl_util
.layer_to_y(13),
427 minetest
.register_ore({
428 ore_type
= "scatter",
429 ore
= "mcl_core:stone_with_lapis",
431 clust_scarcity
= 14000,
434 y_min
= mcl_util
.layer_to_y(6),
435 y_max
= mcl_util
.layer_to_y(9),
437 minetest
.register_ore({
438 ore_type
= "scatter",
439 ore
= "mcl_core:stone_with_lapis",
441 clust_scarcity
= 16000,
444 y_min
= mcl_util
.layer_to_y(2),
445 y_max
= mcl_util
.layer_to_y(5),
447 minetest
.register_ore({
448 ore_type
= "scatter",
449 ore
= "mcl_core:stone_with_lapis",
451 clust_scarcity
= 18000,
454 y_min
= mcl_util
.layer_to_y(0),
455 y_max
= mcl_util
.layer_to_y(2),
458 -- Rare spawn (above center)
459 minetest
.register_ore({
460 ore_type
= "scatter",
461 ore
= "mcl_core:stone_with_lapis",
463 clust_scarcity
= 12000,
466 y_min
= mcl_util
.layer_to_y(17),
467 y_max
= mcl_util
.layer_to_y(20),
469 minetest
.register_ore({
470 ore_type
= "scatter",
471 ore
= "mcl_core:stone_with_lapis",
473 clust_scarcity
= 14000,
476 y_min
= mcl_util
.layer_to_y(21),
477 y_max
= mcl_util
.layer_to_y(24),
479 minetest
.register_ore({
480 ore_type
= "scatter",
481 ore
= "mcl_core:stone_with_lapis",
483 clust_scarcity
= 16000,
486 y_min
= mcl_util
.layer_to_y(25),
487 y_max
= mcl_util
.layer_to_y(28),
489 minetest
.register_ore({
490 ore_type
= "scatter",
491 ore
= "mcl_core:stone_with_lapis",
493 clust_scarcity
= 18000,
496 y_min
= mcl_util
.layer_to_y(29),
497 y_max
= mcl_util
.layer_to_y(32),
499 minetest
.register_ore({
500 ore_type
= "scatter",
501 ore
= "mcl_core:stone_with_lapis",
503 clust_scarcity
= 32000,
506 y_min
= mcl_util
.layer_to_y(31),
507 y_max
= mcl_util
.layer_to_y(32),
510 if mg_name
~= "flat" then
512 -- Water and lava springs (single blocks of lava/water source)
513 -- Water appears at nearly every height, but not near the bottom
514 minetest
.register_ore({
515 ore_type
= "scatter",
516 ore
= "mcl_core:water_source",
517 wherein
= {"mcl_core:stone", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite", "mcl_core:dirt"},
518 clust_scarcity
= 9000,
521 y_min
= mcl_util
.layer_to_y(5),
522 y_max
= mcl_util
.layer_to_y(128),
525 -- Lava springs are rather common at -31 and below
526 minetest
.register_ore({
527 ore_type
= "scatter",
528 ore
= "mcl_core:lava_source",
530 clust_scarcity
= 2000,
533 y_min
= mcl_util
.layer_to_y(1),
534 y_max
= mcl_util
.layer_to_y(10),
537 minetest
.register_ore({
538 ore_type
= "scatter",
539 ore
= "mcl_core:lava_source",
541 clust_scarcity
= 9000,
544 y_min
= mcl_util
.layer_to_y(11),
545 y_max
= mcl_util
.layer_to_y(31),
548 -- Lava springs will become gradually rarer with increasing height
549 minetest
.register_ore({
550 ore_type
= "scatter",
551 ore
= "mcl_core:lava_source",
553 clust_scarcity
= 32000,
556 y_min
= mcl_util
.layer_to_y(32),
557 y_max
= mcl_util
.layer_to_y(47),
560 minetest
.register_ore({
561 ore_type
= "scatter",
562 ore
= "mcl_core:lava_source",
564 clust_scarcity
= 72000,
567 y_min
= mcl_util
.layer_to_y(48),
568 y_max
= mcl_util
.layer_to_y(61),
571 -- Lava may even appear above surface, but this is very rare
572 minetest
.register_ore({
573 ore_type
= "scatter",
574 ore
= "mcl_core:lava_source",
576 clust_scarcity
= 96000,
579 y_min
= mcl_util
.layer_to_y(62),
580 y_max
= mcl_util
.layer_to_y(127),
585 -- Rarely replace stone with stone monster eggs
586 local monster_egg_scarcity
587 if mg_name
== "v6" then
588 monster_egg_scarcity
= 28 * 28 * 28
590 monster_egg_scarcity
= 22 * 22 * 22
592 minetest
.register_ore({
593 ore_type
= "scatter",
594 ore
= "mcl_monster_eggs:monster_egg_stone",
595 wherein
= "mcl_core:stone",
596 clust_scarcity
= monster_egg_scarcity
,
599 y_min
= mcl_vars
.mg_overworld_min
,
600 y_max
= mcl_vars
.mg_overworld_max
,
601 -- TODO: Limit by biome
605 local function register_mgv6_decorations()
608 minetest
.register_decoration({
609 deco_type
= "simple",
610 place_on
= {"group:sand"},
615 spread
= {x
= 100, y
= 100, z
= 100},
621 y_max
= mcl_vars
.mg_overworld_max
,
622 decoration
= "mcl_core:cactus",
628 minetest
.register_decoration({
629 deco_type
= "simple",
630 place_on
= {"mcl_core:dirt", "mcl_core:coarse_dirt", "mcl_core:dirt_with_grass", "group:sand", "mcl_core:podzol", "mcl_core:reeds"},
635 spread
= {x
= 100, y
= 100, z
= 100},
641 y_max
= mcl_vars
.mg_overworld_max
,
642 decoration
= "mcl_core:reeds",
645 spawn_by
= { "mcl_core:water_source", "group:frosted_ice" },
650 minetest
.register_decoration({
651 deco_type
= "schematic",
653 size
= { x
=1, y
=3, z
=1 },
655 { name
= "air", prob
= 0 },
656 { name
= "mcl_flowers:double_grass", param1
= 255, },
657 { name
= "mcl_flowers:double_grass_top", param1
= 255, },
661 ["mcl_flowers:tallgrass"] = "mcl_flowers:double_grass"
663 place_on
= {"mcl_core:dirt_with_grass"},
668 spread
= {x
= 300, y
= 300, z
= 300},
674 y_max
= mcl_vars
.mg_overworld_max
,
678 minetest
.register_decoration({
679 deco_type
= "schematic",
681 size
= { x
=1, y
=3, z
=1 },
683 { name
= "air", prob
= 0 },
684 { name
= "mcl_flowers:double_fern", param1
=255, },
685 { name
= "mcl_flowers:double_fern_top", param1
=255, },
689 ["mcl_flowers:fern"] = "mcl_flowers:double_fern"
691 -- v6 hack: This makes sure large ferns only appear in jungles
692 spawn_by
= { "mcl_core:jungletree", "mcl_flowers:fern" },
694 place_on
= {"mcl_core:podzol"},
700 spread
= {x
= 250, y
= 250, z
= 250},
706 y_max
= mcl_vars
.mg_overworld_max
,
710 local register_large_flower
= function(name
, seed
, offset
)
711 minetest
.register_decoration({
712 deco_type
= "schematic",
714 size
= { x
=1, y
=3, z
=1 },
716 { name
= "air", prob
= 0 },
717 { name
= "mcl_flowers:"..name
, param1
=255, },
718 { name
= "mcl_flowers:"..name
.."_top", param1
=255, },
721 place_on
= {"mcl_core:dirt_with_grass"},
727 spread
= {x
= 300, y
= 300, z
= 300},
733 y_max
= mcl_vars
.overworld_max
,
738 register_large_flower("rose_bush", 9350, -0.008)
739 register_large_flower("peony", 10450, -0.008)
740 register_large_flower("lilac", 10600, -0.007)
741 register_large_flower("sunflower", 2940, -0.005)
744 minetest
.register_decoration({
745 deco_type
= "schematic",
747 size
= { x
=1, y
=3, z
=1 },
749 { name
= "mcl_core:water_source", prob
= 0 },
750 { name
= "mcl_core:water_source" },
751 { name
= "mcl_flowers:waterlily", param1
= 255 },
754 place_on
= "mcl_core:dirt",
759 spread
= {x
= 200, y
= 200, z
= 200},
770 minetest
.register_decoration({
771 deco_type
= "schematic",
773 size
= { x
=1, y
=2, z
=1 },
775 { name
= "air", prob
= 0 },
776 { name
= "mcl_farming:pumpkin_face" },
779 place_on
= {"mcl_core:dirt_with_grass"},
784 spread
= {x
= 250, y
= 250, z
= 250},
790 y_max
= mcl_vars
.overworld_max
,
795 minetest
.register_decoration({
796 deco_type
= "simple",
797 place_on
= {"mcl_core:dirt_with_grass"},
802 spread
= {x
= 500, y
= 500, z
= 500},
808 y_max
= mcl_vars
.overworld_max
,
809 decoration
= "mcl_flowers:tallgrass",
812 -- Add a small amount of tall grass everywhere to avoid areas completely empty devoid of tall grass
813 minetest
.register_decoration({
814 deco_type
= "simple",
815 place_on
= {"mcl_core:dirt_with_grass"},
819 y_max
= mcl_vars
.overworld_max
,
820 decoration
= "mcl_flowers:tallgrass",
823 local mushrooms
= {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown"}
824 local mseeds
= { 7133, 8244 }
825 for m
=1, #mushrooms
do
826 -- Mushrooms next to trees
827 minetest
.register_decoration({
828 deco_type
= "simple",
829 place_on
= {"mcl_core:dirt_with_grass", "mcl_core:dirt", "mcl_core:podzol", "mcl_core:mycelium", "mcl_core:stone", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite"},
834 spread
= {x
= 100, y
= 100, z
= 100},
840 y_max
= mcl_vars
.mg_overworld_max
,
841 decoration
= mushrooms
[m
],
842 spawn_by
= { "mcl_core:tree", "mcl_core:sprucetree", "mcl_core:darktree", "mcl_core:birchtree", },
848 minetest
.register_decoration({
849 deco_type
= "simple",
850 place_on
= {"group:sand", "mcl_core:podzol", "mcl_core:dirt", "mcl_core:coarse_dirt", "group:hardened_clay"},
855 spread
= {x
= 100, y
= 100, z
= 100},
861 y_max
= mcl_vars
.mg_overworld_max
,
862 decoration
= "mcl_core:deadbush",
865 local function register_mgv6_flower(name
, seed
, offset
, y_max
)
866 if offset
== nil then
870 y_max
= mcl_vars
.mg_overworld_max
872 minetest
.register_decoration({
873 deco_type
= "simple",
874 place_on
= {"mcl_core:dirt_with_grass"},
879 spread
= {x
= 100, y
= 100, z
= 100},
886 decoration
= "mcl_flowers:"..name
,
890 register_mgv6_flower("tulip_red", 436)
891 register_mgv6_flower("tulip_orange", 536)
892 register_mgv6_flower("tulip_pink", 636)
893 register_mgv6_flower("tulip_white", 736)
894 register_mgv6_flower("azure_bluet", 800)
895 register_mgv6_flower("dandelion", 8)
896 -- Allium is supposed to only appear in flower forest in MC. There are no flower forests in v6.
897 -- We compensate by making it slightly rarer in v6.
898 register_mgv6_flower("allium", 0, -0.001)
899 --[[ Blue orchid is supposed to appear in swamplands. There are no swamplands in v6.
900 We emulate swamplands by limiting the height to 5 levels above sea level,
901 which should be close to the water. ]]
902 register_mgv6_flower("blue_orchid", 64500, nil, mcl_util
.layer_to_y(67))
903 register_mgv6_flower("oxeye_daisy", 3490)
904 register_mgv6_flower("poppy", 9439)
908 -- Apply mapgen-specific mapgen code
909 if mg_name
== "v6" then
910 register_mgv6_decorations()
911 minetest
.set_mapgen_setting("mg_flags", "caves,nodungeons,decorations,light", true)
912 elseif mg_name
== "flat" then
913 local classic
= minetest
.get_mapgen_setting("mcl_superflat_classic")
914 if classic
== nil then
915 classic
= minetest
.settings
:get_bool("mcl_superflat_classic")
916 minetest
.set_mapgen_setting("mcl_superflat_classic", "true", true)
918 if classic
~= "false" then
919 -- Enforce superflat-like mapgen: No hills, lakes or caves
920 minetest
.set_mapgen_setting("mg_flags", "nocaves,nodungeons,nodecorations,light", true)
921 minetest
.set_mapgen_setting("mgflat_spflags", "nolakes,nohills", true)
923 -- If superflat mode is disabled, mapgen is way more liberal
924 minetest
.set_mapgen_setting("mg_flags", "caves,nodungeons,nodecorations,light", true)
927 minetest
.set_mapgen_setting("mg_flags", "caves,nodungeons,decorations,light", true)
930 -- Helper function for converting a MC probability to MT, with
931 -- regards to MapBlocks.
932 -- Some MC generated structures are generated on per-chunk
934 -- The MC probability is 1/x per Minecraft chunk (16×16).
936 -- x: The MC probability is 1/x.
937 -- minp, maxp: MapBlock limits
938 -- returns: Probability (1/return_value) for a single MT mapblock
939 local function minecraft_chunk_probability(x
, minp
, maxp
)
940 -- 256 is the MC chunk height
941 return x
* (((maxp
.x
-minp
.x
+1)*(maxp
.z
-minp
.z
+1)) / 256)
944 -- Takes an index of a biomemap table (from minetest.get_mapgen_object),
945 -- minp and maxp (from an on_generated callback) and returns the real world coordinates
947 -- Inverse function of xz_to_biomemap
948 local biomemap_to_xz
= function(index
, minp
, maxp
)
949 local xwidth
= maxp
.x
- minp
.x
+ 1
950 local zwidth
= maxp
.z
- minp
.z
+ 1
951 local x
= ((index
-1) % xwidth
) + minp
.x
952 local z
= ((index
-1) / zwidth
) + minp
.z
956 -- Takes x and z coordinates and minp and maxp of a generated chunk
957 -- (in on_generated callback) and returns a biomemap index)
958 -- Inverse function of biomemap_to_xz
959 local xz_to_biomemap_index
= function(x
, z
, minp
, maxp
)
960 local xwidth
= maxp
.x
- minp
.x
+ 1
961 local zwidth
= maxp
.z
- minp
.z
+ 1
962 local minix
= x
% xwidth
963 local miniz
= z
% zwidth
965 return (minix
+ miniz
* zwidth
) + 1
968 -- Perlin noise objects
969 local perlin_structures
970 local perlin_vines
, perlin_vines_fine
, perlin_vines_upwards
, perlin_vines_length
, perlin_vines_density
972 -- Generate clay and structures
973 -- TODO: Try to use more efficient structure generating code
974 minetest
.register_on_generated(function(minp
, maxp
, seed
)
975 local chunk_has_desert_well
= false
976 local chunk_has_desert_temple
= false
977 local chunk_has_igloo
= false
978 if maxp
.y
>= 2 and minp
.y
<= 0 then
980 -- Assume X and Z lengths are equal
982 local divs
= (maxp
.x
-minp
.x
)/divlen
+1;
983 for divx
=0+1,divs
-1-1 do
984 for divz
=0+1,divs
-1-1 do
985 local cx
= minp
.x
+ math
.floor((divx
+0.5)*divlen
)
986 local cz
= minp
.z
+ math
.floor((divz
+0.5)*divlen
)
987 if minetest
.get_node({x
=cx
,y
=1,z
=cz
}).name
== "mcl_core:water_source" and
988 minetest
.get_item_group(minetest
.get_node({x
=cx
,y
=0,z
=cz
}).name
, "sand") == 1 then
989 local is_shallow
= true
990 local num_water_around
= 0
991 if minetest
.get_node({x
=cx
-divlen
*2,y
=1,z
=cz
+0}).name
== "mcl_core:water_source" then
992 num_water_around
= num_water_around
+ 1 end
993 if minetest
.get_node({x
=cx
+divlen
*2,y
=1,z
=cz
+0}).name
== "mcl_core:water_source" then
994 num_water_around
= num_water_around
+ 1 end
995 if minetest
.get_node({x
=cx
+0,y
=1,z
=cz
-divlen
*2}).name
== "mcl_core:water_source" then
996 num_water_around
= num_water_around
+ 1 end
997 if minetest
.get_node({x
=cx
+0,y
=1,z
=cz
+divlen
*2}).name
== "mcl_core:water_source" then
998 num_water_around
= num_water_around
+ 1 end
999 if num_water_around
>= 2 then
1003 for x1
=-divlen
,divlen
do
1004 for z1
=-divlen
,divlen
do
1005 if minetest
.get_item_group(minetest
.get_node({x
=cx
+x1
,y
=0,z
=cz
+z1
}).name
, "sand") == 1 then
1006 minetest
.set_node({x
=cx
+x1
,y
=0,z
=cz
+z1
}, {name
="mcl_core:clay"})
1015 local struct_min
, struct_max
= -3, 64
1016 if maxp
.y
>= struct_min
and minp
.y
<= struct_max
then
1017 local biomemap
= minetest
.get_mapgen_object("biomemap")
1018 -- Generate structures
1020 perlin_structures
= perlin_structures
or minetest
.get_perlin(329, 3, 0.6, 100)
1021 -- Assume X and Z lengths are equal
1023 local divs
= (maxp
.x
-minp
.x
)/divlen
+1;
1024 for divx
=0,divs
-1 do
1025 for divz
=0,divs
-1 do
1026 local x0
= minp
.x
+ math
.floor((divx
+0)*divlen
)
1027 local z0
= minp
.z
+ math
.floor((divz
+0)*divlen
)
1028 local x1
= minp
.x
+ math
.floor((divx
+1)*divlen
)
1029 local z1
= minp
.z
+ math
.floor((divz
+1)*divlen
)
1030 -- Determine amount from perlin noise
1031 local amount
= math
.floor(perlin_structures
:get2d({x
=x0
, y
=z0
}) * 9)
1032 -- Find random positions based on this random
1033 local pr
= PseudoRandom(seed
+1)
1035 local x
= pr
:next(x0
, x1
)
1036 local z
= pr
:next(z0
, z1
)
1037 -- Find ground level
1038 local ground_y
= nil
1039 for y
= struct_max
, struct_min
, -1 do
1040 local checknode
= minetest
.get_node({x
=x
,y
=y
,z
=z
}).name
1041 if minetest
.registered_nodes
[checknode
].walkable
then
1048 local p
= {x
=x
,y
=ground_y
+1,z
=z
}
1049 local nn
= minetest
.get_node(p
).name
1050 -- Check if the node can be replaced
1051 if minetest
.registered_nodes
[nn
] and
1052 minetest
.registered_nodes
[nn
].buildable_to
then
1053 nn
= minetest
.get_node({x
=x
,y
=ground_y
,z
=z
}).name
1054 local struct
= false
1056 -- Desert temples and desert wells
1057 if nn
== "mcl_core:sand" or (nn
== "mcl_core:sandstone") then
1058 if not chunk_has_desert_temple
and not chunk_has_desert_well
and ground_y
> 3 then
1059 -- Spawn desert temple
1060 -- TODO: Check surface
1061 if math
.random(1,12000) == 1 then
1062 mcl_structures
.call_struct(p
, "desert_temple")
1063 chunk_has_desert_temple
= true
1066 if not chunk_has_desert_temple
and not chunk_has_desert_well
and ground_y
> 3 then
1067 local desert_well_prob
= minecraft_chunk_probability(1000, minp
, maxp
)
1069 -- Spawn desert well
1070 if math
.random(1, desert_well_prob
) == 1 then
1072 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")
1073 if #surface
>= 25 then
1074 mcl_structures
.call_struct(p
, "desert_well")
1075 chunk_has_desert_well
= true
1081 elseif not chunk_has_igloo
and (nn
== "mcl_core:snowblock" or nn
== "mcl_core:snow" or nn
== "mcl_core:dirt_with_grass_snow") then
1082 if math
.random(1, 4400) == 1 then
1084 local floor = {x
=p
.x
+9, y
=p
.y
-1, z
=p
.z
+9}
1085 local surface
= minetest
.find_nodes_in_area({x
=p
.x
,y
=p
.y
-1,z
=p
.z
}, floor, "mcl_core:snowblock")
1086 local surface2
= minetest
.find_nodes_in_area({x
=p
.x
,y
=p
.y
-1,z
=p
.z
}, floor, "mcl_core:dirt_with_grass_snow")
1087 if #surface
+ #surface2
>= 63 then
1088 mcl_structures
.call_struct(p
, "igloo")
1089 chunk_has_igloo
= true
1095 if nn
== "mcl_core:sandstone" or nn
== "mcl_core:sand" and not chunk_has_desert_temple
and ground_y
> 3 then
1096 local fossil_prob
= minecraft_chunk_probability(64, minp
, maxp
)
1098 if math
.random(1, fossil_prob
) == 1 then
1099 -- Spawn fossil below desert surface between layers 40 and 49
1100 local p1
= {x
=p
.x
, y
=math
.random(mcl_util
.layer_to_y(40), mcl_util
.layer_to_y(49)), z
=p
.z
}
1101 -- Very rough check of the environment (we expect to have enough stonelike nodes).
1102 -- Fossils may still appear partially exposed in caves, but this is O.K.
1103 local p2
= vector
.add(p1
, 4)
1104 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"})
1106 if #nodes
>= 100 then -- >= 80%
1107 mcl_structures
.call_struct(p1
, "fossil")
1113 if ground_y
<= 0 and nn
== "mcl_core:dirt" then
1114 local prob
= minecraft_chunk_probability(48, minp
, maxp
)
1116 local swampland
= minetest
.get_biome_id("jungle_edge")
1117 local swampland_shore
= minetest
.get_biome_id("jungle_edge_ocean")
1119 -- Where do witches live?
1121 local here_be_witches
= false
1122 if mg_name
== "v6" then
1123 -- In ye good ol' landes of v6, witches will settle at any
1125 here_be_witches
= true
1127 -- The townsfolk told me that witches live in the swamplands!
1128 local bi
= xz_to_biomemap_index(p
.x
, p
.z
, minp
, maxp
)
1129 if biomemap
[bi
] == swampland
or biomemap
[bi
] == swampland_shore
then
1130 here_be_witches
= true
1134 -- We still need a bit of luck!
1135 if here_be_witches
and math
.random(1, prob
) == 1 then
1136 local r
= tostring(math
.random(0, 3) * 90) -- "0", "90", "180" or 270"
1137 local p1
= {x
=p
.x
-1, y
=WITCH_HUT_HEIGHT
+2, z
=p
.z
-1}
1138 if r
== "0" or r
== "180" then
1139 size
= {x
=10, y
=4, z
=8}
1141 size
= {x
=8, y
=4, z
=10}
1143 local p2
= vector
.add(p1
, size
)
1145 -- This checks free space at the “body” of the hut and a bit around.
1146 -- ALL nodes must be free for the placement to succeed.
1147 local free_nodes
= minetest
.find_nodes_in_area(p1
, p2
, {"air", "mcl_core:water_source", "mcl_flowers:waterlily"})
1148 if #free_nodes
>= ((size
.x
+1)*(size
.y
+1)*(size
.z
+1)) then
1149 local place
= {x
=p
.x
, y
=WITCH_HUT_HEIGHT
-1, z
=p
.z
}
1151 -- FIXME: For some mysterious reason (black magic?) this
1152 -- function does sometimes NOT spawn the witch hut. One can only see the
1153 -- oak wood nodes in the water, but no hut. :-/
1154 mcl_structures
.call_struct(place
, "witch_hut", r
)
1156 -- TODO: Spawn witch in or around hut when the mob sucks less.
1158 local place_tree_if_free
= function(pos
, prev_result
)
1159 local nn
= minetest
.get_node(pos
).name
1160 if nn
== "mcl_flowers:waterlily" or nn
== "mcl_core:water_source" or nn
== "mcl_core:water_flowing" or nn
== "air" then
1161 minetest
.set_node(pos
, {name
="mcl_core:tree", param2
=0})
1175 elseif r
== "180" then
1182 elseif r
== "270" then
1189 elseif r
== "90" then
1197 for o
=1, #offsets
do
1199 for y
=place
.y
-1, place
.y
-64, -1 do
1200 local tpos
= vector
.add(place
, offsets
[o
])
1202 ok
= place_tree_if_free(tpos
, ok
)
1213 -- In other mapgens, ice spikes are generated as decorations.
1214 if mg_name
== "v6" and not chunk_has_igloo
and nn
== "mcl_core:snowblock" then
1215 local spike
= math
.random(1, 3000)
1218 local floor = {x
=p
.x
+4, y
=p
.y
-1, z
=p
.z
+4}
1219 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"})
1220 -- Check for collision with spruce
1221 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"})
1223 if #surface
>= 9 and #spruce_collisions
== 0 then
1224 mcl_structures
.call_struct(p
, "ice_spike_large")
1226 elseif spike
< 100 then
1228 local floor = {x
=p
.x
+6, y
=p
.y
-1, z
=p
.z
+6}
1229 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"})
1231 -- Check for collision with spruce
1232 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"})
1234 if #surface
>= 25 and #spruce_collisions
== 0 then
1235 mcl_structures
.call_struct(p
, "ice_spike_small")
1248 -- Buffer for LuaVoxelManip
1249 local lvm_buffer
= {}
1251 -- Generate tree decorations in the bounding box. This adds:
1252 -- * Cocoa at jungle trees
1253 -- * Jungle tree vines
1254 -- * Oak vines in swamplands
1255 local function generate_tree_decorations(minp
, maxp
, biomemap
)
1260 local oaktree
, oakleaves
, jungletree
, jungleleaves
= {}, {}, {}, {}
1261 local swampland
= minetest
.get_biome_id("swampland")
1262 local swampland_shore
= minetest
.get_biome_id("swampland_shore")
1263 local jungle
= minetest
.get_biome_id("jungle")
1264 local jungle_shore
= minetest
.get_biome_id("jungle_shore")
1265 local jungle_edge
= minetest
.get_biome_id("jungle_edge")
1266 local jungle_edge_shore
= minetest
.get_biome_id("jungle_edge_shore")
1269 -- Biome map available: Check if the required biome (jungle or swampland)
1270 -- is in this mapchunk. We are only interested in trees in the correct biome.
1271 -- The nodes are added if the correct biome is *anywhere* in the mapchunk.
1272 -- TODO: Strictly generate vines in the correct biomes only.
1273 local swamp_biome_found
, jungle_biome_found
= false, false
1274 for b
=1, #biomemap
do
1275 local id
= biomemap
[b
]
1277 if not swamp_biome_found
and (id
== swampland
or id
== swampland_shore
) then
1278 oaktree
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:tree"})
1279 oakleaves
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:leaves"})
1280 swamp_biome_found
= true
1281 elseif not jungle_biome_found
and (id
== jungle
or id
== jungle_shore
or id
== jungle_edge
or id
== jungle_edge_shore
) then
1282 jungletree
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:jungletree"})
1283 jungleleaves
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:jungleleaves"})
1284 jungle_biome_found
= true
1286 if swamp_biome_found
and jungle_biome_found
then
1291 -- If there is no biome map, we just count all jungle things we can find.
1292 -- Oak vines will not be generated.
1293 jungletree
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:jungletree"})
1294 jungleleaves
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:jungleleaves"})
1297 local pos
, treepos
, dir
1299 -- Pass 1: Generate cocoas at jungle trees
1300 for n
= 1, #jungletree
do
1303 treepos
= table.copy(pos
)
1305 if minetest
.find_node_near(pos
, 1, {"mcl_core:jungleleaves"}) then
1307 dir
= math
.random(1, 40)
1311 elseif dir
== 2 then
1313 elseif dir
== 3 then
1315 elseif dir
== 4 then
1319 local nn
= minetest
.get_node(pos
).name
1323 and minetest
.get_node_light(pos
) > 12 then
1324 minetest
.swap_node(pos
, {
1325 name
= "mcl_cocoas:cocoa_" .. tostring(math
.random(1, 3)),
1326 param2
= minetest
.dir_to_facedir(vector
.subtract(treepos
, pos
))
1333 -- Pass 2: Generate vines at jungle wood, jungle leaves in jungle and oak wood, oak leaves in swampland
1334 perlin_vines
= perlin_vines
or minetest
.get_perlin(555, 4, 0.6, 500)
1335 perlin_vines_fine
= perlin_vines_fine
or minetest
.get_perlin(43000, 3, 0.6, 1)
1336 perlin_vines_length
= perlin_vines_length
or minetest
.get_perlin(435, 4, 0.6, 75)
1337 perlin_vines_upwards
= perlin_vines_upwards
or minetest
.get_perlin(436, 3, 0.6, 10)
1338 perlin_vines_density
= perlin_vines_density
or minetest
.get_perlin(436, 3, 0.6, 500)
1342 treething
= jungletree
1344 treething
= jungleleaves
1348 treething
= oakleaves
1351 for n
= 1, #treething
do
1354 treepos
= table.copy(pos
)
1364 local pos
= vector
.add(pos
, dirs
[d
])
1366 local nn
= minetest
.get_node(pos
).name
1368 if perlin_vines
:get2d(pos
) > -1.0 and perlin_vines_fine
:get3d(pos
) > math
.max(0.33333, perlin_vines_density
:get2d(pos
)) and nn
== "air" then
1371 name
= "mcl_core:vine",
1372 param2
= minetest
.dir_to_wallmounted(vector
.subtract(treepos
, pos
))
1375 -- Determine growth direction
1376 local grow_upwards
= false
1377 -- Only possible on the wood, not on the leaves
1379 grow_upwards
= perlin_vines_upwards
:get3d(pos
) > 0.8
1381 if grow_upwards
then
1382 -- Grow vines up 1-4 nodes, even through jungleleaves.
1383 -- This may give climbing access all the way to the top of the tree :-)
1384 -- But this will be fairly rare.
1385 local length
= math
.ceil(math
.abs(perlin_vines_length
:get3d(pos
)) * 4)
1386 for l
=0, length
-1 do
1387 local tnn
= minetest
.get_node(treepos
).name
1388 local nn
= minetest
.get_node(pos
).name
1389 if (nn
== "air" or nn
== "mcl_core:jungleleaves" or nn
== "mcl_core:leaves") and mcl_core
.supports_vines(tnn
) then
1390 minetest
.set_node(pos
, newnode
)
1395 treepos
.y
= treepos
.y
+ 1
1398 -- Grow vines down 1-7 nodes
1399 local length
= math
.ceil(math
.abs(perlin_vines_length
:get3d(pos
)) * 7)
1400 for l
=0, length
-1 do
1401 if minetest
.get_node(pos
).name
== "air" then
1402 minetest
.set_node(pos
, newnode
)
1415 local pr_shroom
= PseudoRandom(os
.time()-24359)
1416 -- Generate mushrooms in caves manually.
1417 -- Minetest's API does not support decorations in caves yet. :-(
1418 local generate_underground_mushrooms
= function(minp
, maxp
)
1419 -- Generate rare underground mushrooms
1420 -- TODO: Make them appear in groups, use Perlin noise
1421 local min, max = mcl_vars
.mg_lava_overworld_max
+ 4, 0
1422 if minp
.y
> max or maxp
.y
< min then
1427 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"})
1429 for n
= 1, #stone
do
1430 bpos
= {x
= stone
[n
].x
, y
= stone
[n
].y
+ 1, z
= stone
[n
].z
}
1432 if bpos
.y
>= min and bpos
.y
<= max and minetest
.get_node_light(bpos
, 0.5) <= 12 and pr_shroom
:next(1,1000) < 4 then
1433 if pr_shroom
:next(1,2) == 1 then
1434 minetest
.set_node(bpos
, {name
= "mcl_mushrooms:mushroom_brown"})
1436 minetest
.set_node(bpos
, {name
= "mcl_mushrooms:mushroom_red"})
1442 local pr_nether
= PseudoRandom(os
.time()+667)
1443 -- Generate Nether decorations manually: Eternal fire, mushrooms, nether wart
1444 -- Minetest's API does not support decorations in caves yet. :-(
1445 local generate_nether_decorations
= function(minp
, maxp
)
1446 if minp
.y
> mcl_vars
.mg_nether_max
or maxp
.y
< mcl_vars
.mg_nether_min
then
1450 -- TODO: Generate everything based on Perlin noise instead of PseudoRandom
1453 local rack
= minetest
.find_nodes_in_area_under_air(minp
, maxp
, {"mcl_nether:netherrack"})
1454 local magma
= minetest
.find_nodes_in_area_under_air(minp
, maxp
, {"mcl_nether:magma"})
1455 local ssand
= minetest
.find_nodes_in_area_under_air(minp
, maxp
, {"mcl_nether:soul_sand"})
1457 -- Helper function to spawn “fake” decoration
1458 local special_deco
= function(nodes
, spawn_func
)
1459 for n
= 1, #nodes
do
1460 bpos
= {x
= nodes
[n
].x
, y
= nodes
[n
].y
+ 1, z
= nodes
[n
].z
}
1467 -- Eternal fire on netherrack
1468 special_deco(rack
, function(bpos
)
1469 -- Eternal fire on netherrack
1470 if pr_nether
:next(1,100) <= 3 then
1471 minetest
.set_node(bpos
, {name
= "mcl_fire:eternal_fire"})
1475 -- Eternal fire on magma cubes
1476 special_deco(magma
, function(bpos
)
1477 if pr_nether
:next(1,150) == 1 then
1478 minetest
.set_node(bpos
, {name
= "mcl_fire:eternal_fire"})
1482 -- Mushrooms on netherrack
1483 -- Note: Spawned *after* the fire because of light level checks
1484 special_deco(rack
, function(bpos
)
1485 if bpos
.y
> mcl_vars
.mg_lava_nether_max
+ 6 and minetest
.get_node_light(bpos
, 0.5) <= 12 and pr_nether
:next(1,1000) <= 4 then
1486 -- TODO: Make mushrooms appear in groups, use Perlin noise
1487 if pr_nether
:next(1,2) == 1 then
1488 minetest
.set_node(bpos
, {name
= "mcl_mushrooms:mushroom_brown"})
1490 minetest
.set_node(bpos
, {name
= "mcl_mushrooms:mushroom_red"})
1495 -- Nether wart on soul sand
1496 -- TODO: Spawn in Nether fortresses
1497 special_deco(ssand
, function(bpos
)
1498 if pr_nether
:next(1,170) == 1 then
1499 minetest
.set_node(bpos
, {name
= "mcl_nether:nether_wart"})
1505 local GEN_MAX
= mcl_vars
.mg_lava_overworld_max
or mcl_vars
.mg_overworld_max
1507 local c_bedrock
= minetest
.get_content_id("mcl_core:bedrock")
1508 local c_stone
= minetest
.get_content_id("mcl_core:stone")
1509 local c_dirt
= minetest
.get_content_id("mcl_core:dirt")
1510 local c_dirt_with_grass
= minetest
.get_content_id("mcl_core:dirt_with_grass")
1511 local c_dirt_with_grass_snow
= minetest
.get_content_id("mcl_core:dirt_with_grass_snow")
1512 local c_sand
= minetest
.get_content_id("mcl_core:sand")
1513 local c_sandstone
= minetest
.get_content_id("mcl_core:sandstone")
1514 local c_redsand
= minetest
.get_content_id("mcl_core:redsand")
1515 local c_redsandstone
= minetest
.get_content_id("mcl_core:redsandstone")
1516 local c_void
= minetest
.get_content_id("mcl_core:void")
1517 local c_lava
= minetest
.get_content_id("mcl_core:lava_source")
1518 local c_water
= minetest
.get_content_id("mcl_core:water_source")
1519 local c_soul_sand
= minetest
.get_content_id("mcl_nether:soul_sand")
1520 local c_netherrack
= minetest
.get_content_id("mcl_nether:netherrack")
1521 local c_nether_lava
= minetest
.get_content_id("mcl_nether:nether_lava_source")
1522 local c_end_stone
= minetest
.get_content_id("mcl_end:end_stone")
1523 local c_realm_barrier
= minetest
.get_content_id("mcl_core:realm_barrier")
1524 local c_top_snow
= minetest
.get_content_id("mcl_core:snow")
1525 local c_snow_block
= minetest
.get_content_id("mcl_core:snowblock")
1526 local c_air
= minetest
.get_content_id("air")
1528 -- Below the bedrock, generate air/void
1529 minetest
.register_on_generated(function(minp
, maxp
)
1530 local vm
, emin
, emax
= minetest
.get_mapgen_object("voxelmanip")
1531 local data
= vm
:get_data(lvm_buffer
)
1532 local area
= VoxelArea
:new({MinEdge
=emin
, MaxEdge
=emax
})
1533 local lvm_used
= false
1537 -- Generate basic layer-based nodes: void, bedrock, realm barrier, lava seas, etc.
1538 -- Also perform some basic node replacements.
1540 -- Helper function to set all nodes in the layers between min and max.
1541 -- content_id: Node to set
1543 -- If content_id, node will be set only if it is equal to check.
1544 -- If function(pos_to_check, content_id_at_this_pos), will set node only if returns true.
1545 -- min, max: Minimum and maximum Y levels of the layers to set
1546 -- minp, maxp: minp, maxp of the on_generated
1547 -- lvm_used: Set to true if any node in this on_generated has been set before.
1549 -- returns true if any node was set and lvm_used otherwise
1550 local function set_layers(content_id
, check
, min, max, minp
, maxp
, lvm_used
)
1551 if (maxp
.y
>= min and minp
.y
<= max) then
1552 for y
= math
.max(min, minp
.y
), math
.min(max, maxp
.y
) do
1553 for x
= minp
.x
, maxp
.x
do
1554 for z
= minp
.z
, maxp
.z
do
1555 local p_pos
= area
:index(x
, y
, z
)
1557 if type(check
) == "function" and check({x
=x
,y
=y
,z
=z
}, data
[p_pos
]) then
1558 data
[p_pos
] = content_id
1560 elseif check
== data
[p_pos
] then
1561 data
[p_pos
] = content_id
1565 data
[p_pos
] = content_id
1576 lvm_used
= set_layers(c_void
, nil, -31000, mcl_vars
.mg_nether_min
-1, minp
, maxp
, lvm_used
)
1577 lvm_used
= set_layers(c_void
, nil, mcl_vars
.mg_nether_max
+1, mcl_vars
.mg_end_min
-1, minp
, maxp
, lvm_used
)
1578 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
)
1579 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
)
1581 -- Realm barrier between the Overworld void and the End
1582 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
)
1586 if mcl_vars
.mg_bedrock_is_rough
then
1587 bedrock_check
= function(pos
)
1589 -- Bedrock layers with increasing levels of roughness, until a perfecly flat bedrock later at the bottom layer
1590 -- This code assumes a bedrock height of 5 layers.
1592 local diff
= mcl_vars
.mg_bedrock_overworld_max
- y
-- Overworld bedrock
1593 local ndiff1
= mcl_vars
.mg_bedrock_nether_bottom_max
- y
-- Nether bedrock, bottom
1594 local ndiff2
= mcl_vars
.mg_bedrock_nether_top_max
- y
-- Nether bedrock, ceiling
1597 if diff
== 0 or ndiff1
== 0 or ndiff2
== 4 then
1598 -- 50% bedrock chance
1600 elseif diff
== 1 or ndiff1
== 1 or ndiff2
== 3 then
1603 elseif diff
== 2 or ndiff1
== 2 or ndiff2
== 2 then
1606 elseif diff
== 3 or ndiff1
== 3 or ndiff2
== 1 then
1609 elseif diff
== 4 or ndiff1
== 4 or ndiff2
== 0 then
1613 -- Not in bedrock layer
1617 return math
.random(1, top
) <= top
-1
1623 lvm_used
= set_layers(c_bedrock
, bedrock_check
, mcl_vars
.mg_bedrock_overworld_min
, mcl_vars
.mg_bedrock_overworld_max
, minp
, maxp
, lvm_used
)
1624 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
)
1625 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
)
1628 if mg_name
== "flat" then
1629 lvm_used
= set_layers(c_air
, nil, mcl_vars
.mg_bedrock_nether_bottom_max
+ 4, mcl_vars
.mg_bedrock_nether_bottom_max
+ 52, minp
, maxp
, lvm_used
)
1632 -- Big lava seas by replacing air below a certain height
1633 if mcl_vars
.mg_lava
then
1634 lvm_used
= set_layers(c_lava
, c_air
, mcl_vars
.mg_overworld_min
, mcl_vars
.mg_lava_overworld_max
, minp
, maxp
, lvm_used
)
1635 lvm_used
= set_layers(c_nether_lava
, c_air
, mcl_vars
.mg_nether_min
, mcl_vars
.mg_lava_nether_max
, minp
, maxp
, lvm_used
)
1638 ----- Interactive block fixing section -----
1639 ----- The section to perform basic block overrides of the core mapgen generated world. -----
1641 -- Snow and sand fixes. This code implements snow consistency
1642 -- and fixes floating sand.
1643 -- A snowy grass block must be below a top snow or snow block at all times.
1644 if minp
.y
<= mcl_vars
.mg_overworld_max
and maxp
.y
>= mcl_vars
.mg_overworld_min
then
1646 -- Put top snow on snowy grass blocks. The mapgen does not generate the top snow on its own.
1647 if mg_name
== "v6" then
1648 local snowdirt
= minetest
.find_nodes_in_area_under_air(minp
, maxp
, "mcl_core:dirt_with_grass_snow")
1649 for n
= 1, #snowdirt
do
1650 -- CHECKME: What happens at chunk borders?
1651 local p_pos
= area
:index(snowdirt
[n
].x
, snowdirt
[n
].y
+ 1, snowdirt
[n
].z
)
1653 data
[p_pos
] = c_top_snow
1656 if #snowdirt
> 1 then
1662 -- Clear snowy grass blocks without snow above to ensure consistency.
1663 -- Solidify floating sand to sandstone (both colors).
1665 --local nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:dirt_with_grass_snow"})
1666 local nodes
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:dirt_with_grass_snow", "mcl_core:sand", "mcl_core:redsand"})
1668 local p_pos
= area
:index(nodes
[n
].x
, nodes
[n
].y
, nodes
[n
].z
)
1669 local p_pos_above
= area
:index(nodes
[n
].x
, nodes
[n
].y
+1, nodes
[n
].z
)
1670 local p_pos_below
= area
:index(nodes
[n
].x
, nodes
[n
].y
-1, nodes
[n
].z
)
1671 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
1672 data
[p_pos
] = c_dirt_with_grass
1674 elseif p_pos_below
and data
[p_pos_below
] == c_air
or data
[p_pos_below
] == c_water
then
1675 if data
[p_pos
] == c_sand
then
1676 data
[p_pos
] = c_sandstone
1678 elseif data
[p_pos
] == c_redsand
then
1679 -- Note: This is the only place in which red sandstone is generatd
1680 data
[p_pos
] = c_redsandstone
1687 -- Nether block fixes:
1688 -- * Replace water with Nether lava.
1689 -- * Replace stone, sand dirt in v6 so the Nether works in v6.
1690 elseif minp
.y
<= mcl_vars
.mg_nether_max
and maxp
.y
>= mcl_vars
.mg_nether_min
then
1692 if mg_name
== "v6" then
1693 nodes
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"})
1695 nodes
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:water_source"})
1698 local p_pos
= area
:index(nodes
[n
].x
, nodes
[n
].y
, nodes
[n
].z
)
1699 if data
[p_pos
] == c_water
then
1700 data
[p_pos
] = c_nether_lava
1702 elseif data
[p_pos
] == c_stone
then
1703 data
[p_pos
] = c_netherrack
1705 elseif data
[p_pos
] == c_sand
or data
[p_pos
] == c_dirt
then
1706 data
[p_pos
] = c_soul_sand
1712 -- * Replace water with end stone or air (depending on height).
1713 -- * Remove stone, sand, dirt in v6 so our End map generator works in v6.
1714 elseif minp
.y
<= mcl_vars
.mg_end_max
and maxp
.y
>= mcl_vars
.mg_end_min
then
1715 if mg_name
== "v6" then
1716 nodes
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"})
1718 nodes
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:water_source"})
1721 local y
= nodes
[n
].y
1722 local p_pos
= area
:index(nodes
[n
].x
, y
, nodes
[n
].z
)
1724 if data
[p_pos
] == c_water
then
1725 if y
<= mcl_vars
.mg_end_min
+ 104 and y
>= mcl_vars
.mg_end_min
+ 40 then
1726 data
[p_pos
] = c_end_stone
1732 elseif data
[p_pos
] == c_stone
or data
[p_pos
] == c_dirt
or data
[p_pos
] == c_sand
then
1742 -- Final hackery: Set sun light level in the End.
1743 -- -26912 is at a mapchunk border.
1745 if minp
.y
>= -26912 and maxp
.y
<= mcl_vars
.mg_end_max
then
1746 vm
:set_lighting({day
=15, night
=15})
1749 if minp
.y
>= mcl_vars
.mg_end_min
and maxp
.y
<= -26911 then
1757 vm
:calc_lighting(nil, nil, shadow
)
1762 local biomemap
= minetest
.get_mapgen_object("biomemap")
1764 -- Generate special decorations
1765 generate_underground_mushrooms(minp
, maxp
)
1766 generate_tree_decorations(minp
, maxp
, biomemap
)
1767 generate_nether_decorations(minp
, maxp
)