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")
48 local WITCH_HUT_HEIGHT
= 3 -- Exact Y level to spawn witch huts at. This height refers to the height of the floor
50 -- End exit portal position. This is temporary.
51 -- TODO: Remove the exit portal generation when the ender dragon has been implemented.
52 local END_EXIT_PORTAL_POS
= table.copy(mcl_vars
.mg_end_platform_pos
)
53 END_EXIT_PORTAL_POS
.x
= END_EXIT_PORTAL_POS
.x
- 30
54 END_EXIT_PORTAL_POS
.z
= END_EXIT_PORTAL_POS
.z
- 3
55 END_EXIT_PORTAL_POS
.y
= END_EXIT_PORTAL_POS
.y
- 3
58 local c_bedrock
= minetest
.get_content_id("mcl_core:bedrock")
59 local c_obsidian
= minetest
.get_content_id("mcl_core:obsidian")
60 local c_stone
= minetest
.get_content_id("mcl_core:stone")
61 local c_dirt
= minetest
.get_content_id("mcl_core:dirt")
62 local c_dirt_with_grass
= minetest
.get_content_id("mcl_core:dirt_with_grass")
63 local c_dirt_with_grass_snow
= minetest
.get_content_id("mcl_core:dirt_with_grass_snow")
64 local c_sand
= minetest
.get_content_id("mcl_core:sand")
65 local c_sandstone
= minetest
.get_content_id("mcl_core:sandstone")
66 local c_redsand
= minetest
.get_content_id("mcl_core:redsand")
67 local c_redsandstone
= minetest
.get_content_id("mcl_core:redsandstone")
68 local c_void
= minetest
.get_content_id("mcl_core:void")
69 local c_lava
= minetest
.get_content_id("mcl_core:lava_source")
70 local c_water
= minetest
.get_content_id("mcl_core:water_source")
71 local c_soul_sand
= minetest
.get_content_id("mcl_nether:soul_sand")
72 local c_netherrack
= minetest
.get_content_id("mcl_nether:netherrack")
73 local c_nether_lava
= minetest
.get_content_id("mcl_nether:nether_lava_source")
74 local c_end_stone
= minetest
.get_content_id("mcl_end:end_stone")
75 local c_realm_barrier
= minetest
.get_content_id("mcl_core:realm_barrier")
76 local c_top_snow
= minetest
.get_content_id("mcl_core:snow")
77 local c_snow_block
= minetest
.get_content_id("mcl_core:snowblock")
78 local c_clay
= minetest
.get_content_id("mcl_core:clay")
79 local c_leaves
= minetest
.get_content_id("mcl_core:leaves")
80 local c_jungleleaves
= minetest
.get_content_id("mcl_core:jungleleaves")
81 local c_jungletree
= minetest
.get_content_id("mcl_core:jungletree")
82 local c_cocoa_1
= minetest
.get_content_id("mcl_cocoas:cocoa_1")
83 local c_cocoa_2
= minetest
.get_content_id("mcl_cocoas:cocoa_2")
84 local c_cocoa_3
= minetest
.get_content_id("mcl_cocoas:cocoa_3")
85 local c_vine
= minetest
.get_content_id("mcl_core:vine")
86 local c_air
= minetest
.CONTENT_AIR
92 -- Diorite, andesite and granite
93 local specialstones
= { "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite" }
94 for s
=1, #specialstones
do
95 local node
= specialstones
[s
]
96 minetest
.register_ore({
99 wherein
= {"mcl_core:stone"},
100 clust_scarcity
= 15*15*15,
103 y_min
= mcl_vars
.mg_overworld_min
,
104 y_max
= mcl_vars
.mg_overworld_max
,
106 minetest
.register_ore({
109 wherein
= {"mcl_core:stone"},
110 clust_scarcity
= 10*10*10,
113 y_min
= mcl_vars
.mg_overworld_min
,
114 y_max
= mcl_vars
.mg_overworld_max
,
118 local stonelike
= {"mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite"}
121 minetest
.register_ore({
123 ore
= "mcl_core:dirt",
125 clust_scarcity
= 15*15*15,
128 y_min
= mcl_vars
.mg_overworld_min
,
129 y_max
= mcl_vars
.mg_overworld_max
,
133 minetest
.register_ore({
135 ore
= "mcl_core:gravel",
137 clust_scarcity
= 14*14*14,
140 y_min
= mcl_vars
.mg_overworld_min
,
141 y_max
= mcl_worlds
.layer_to_y(111),
149 minetest
.register_ore({
150 ore_type
= "scatter",
151 ore
= "mcl_core:stone_with_coal",
153 clust_scarcity
= 525*3,
156 y_min
= mcl_vars
.mg_overworld_min
,
157 y_max
= mcl_worlds
.layer_to_y(50),
159 minetest
.register_ore({
160 ore_type
= "scatter",
161 ore
= "mcl_core:stone_with_coal",
163 clust_scarcity
= 510*3,
166 y_min
= mcl_vars
.mg_overworld_min
,
167 y_max
= mcl_worlds
.layer_to_y(50),
169 minetest
.register_ore({
170 ore_type
= "scatter",
171 ore
= "mcl_core:stone_with_coal",
173 clust_scarcity
= 500*3,
176 y_min
= mcl_vars
.mg_overworld_min
,
177 y_max
= mcl_worlds
.layer_to_y(50),
181 minetest
.register_ore({
182 ore_type
= "scatter",
183 ore
= "mcl_core:stone_with_coal",
185 clust_scarcity
= 550*3,
188 y_min
= mcl_worlds
.layer_to_y(51),
189 y_max
= mcl_worlds
.layer_to_y(80),
191 minetest
.register_ore({
192 ore_type
= "scatter",
193 ore
= "mcl_core:stone_with_coal",
195 clust_scarcity
= 525*3,
198 y_min
= mcl_worlds
.layer_to_y(51),
199 y_max
= mcl_worlds
.layer_to_y(80),
201 minetest
.register_ore({
202 ore_type
= "scatter",
203 ore
= "mcl_core:stone_with_coal",
205 clust_scarcity
= 500*3,
208 y_min
= mcl_worlds
.layer_to_y(51),
209 y_max
= mcl_worlds
.layer_to_y(80),
213 minetest
.register_ore({
214 ore_type
= "scatter",
215 ore
= "mcl_core:stone_with_coal",
217 clust_scarcity
= 600*3,
220 y_min
= mcl_worlds
.layer_to_y(81),
221 y_max
= mcl_worlds
.layer_to_y(128),
223 minetest
.register_ore({
224 ore_type
= "scatter",
225 ore
= "mcl_core:stone_with_coal",
227 clust_scarcity
= 550*3,
230 y_min
= mcl_worlds
.layer_to_y(81),
231 y_max
= mcl_worlds
.layer_to_y(128),
233 minetest
.register_ore({
234 ore_type
= "scatter",
235 ore
= "mcl_core:stone_with_coal",
237 clust_scarcity
= 500*3,
240 y_min
= mcl_worlds
.layer_to_y(81),
241 y_max
= mcl_worlds
.layer_to_y(128),
247 minetest
.register_ore({
248 ore_type
= "scatter",
249 ore
= "mcl_core:stone_with_iron",
251 clust_scarcity
= 830,
254 y_min
= mcl_vars
.mg_overworld_min
,
255 y_max
= mcl_worlds
.layer_to_y(39),
257 minetest
.register_ore({
258 ore_type
= "scatter",
259 ore
= "mcl_core:stone_with_iron",
261 clust_scarcity
= 1660,
264 y_min
= mcl_worlds
.layer_to_y(40),
265 y_max
= mcl_worlds
.layer_to_y(63),
273 minetest
.register_ore({
274 ore_type
= "scatter",
275 ore
= "mcl_core:stone_with_gold",
277 clust_scarcity
= 4775,
280 y_min
= mcl_vars
.mg_overworld_min
,
281 y_max
= mcl_worlds
.layer_to_y(30),
283 minetest
.register_ore({
284 ore_type
= "scatter",
285 ore
= "mcl_core:stone_with_gold",
287 clust_scarcity
= 6560,
290 y_min
= mcl_vars
.mg_overworld_min
,
291 y_max
= mcl_worlds
.layer_to_y(30),
295 minetest
.register_ore({
296 ore_type
= "scatter",
297 ore
= "mcl_core:stone_with_gold",
299 clust_scarcity
= 13000,
302 y_min
= mcl_worlds
.layer_to_y(31),
303 y_max
= mcl_worlds
.layer_to_y(33),
311 minetest
.register_ore({
312 ore_type
= "scatter",
313 ore
= "mcl_core:stone_with_diamond",
315 clust_scarcity
= 10000,
318 y_min
= mcl_vars
.mg_overworld_min
,
319 y_max
= mcl_worlds
.layer_to_y(12),
321 minetest
.register_ore({
322 ore_type
= "scatter",
323 ore
= "mcl_core:stone_with_diamond",
325 clust_scarcity
= 5000,
328 y_min
= mcl_vars
.mg_overworld_min
,
329 y_max
= mcl_worlds
.layer_to_y(12),
331 minetest
.register_ore({
332 ore_type
= "scatter",
333 ore
= "mcl_core:stone_with_diamond",
335 clust_scarcity
= 10000,
338 y_min
= mcl_vars
.mg_overworld_min
,
339 y_max
= mcl_worlds
.layer_to_y(12),
343 minetest
.register_ore({
344 ore_type
= "scatter",
345 ore
= "mcl_core:stone_with_diamond",
347 clust_scarcity
= 20000,
350 y_min
= mcl_worlds
.layer_to_y(13),
351 y_max
= mcl_worlds
.layer_to_y(15),
353 minetest
.register_ore({
354 ore_type
= "scatter",
355 ore
= "mcl_core:stone_with_diamond",
357 clust_scarcity
= 20000,
360 y_min
= mcl_worlds
.layer_to_y(13),
361 y_max
= mcl_worlds
.layer_to_y(15),
369 minetest
.register_ore({
370 ore_type
= "scatter",
371 ore
= "mcl_core:stone_with_redstone",
373 clust_scarcity
= 500,
376 y_min
= mcl_vars
.mg_overworld_min
,
377 y_max
= mcl_worlds
.layer_to_y(13),
379 minetest
.register_ore({
380 ore_type
= "scatter",
381 ore
= "mcl_core:stone_with_redstone",
383 clust_scarcity
= 800,
386 y_min
= mcl_vars
.mg_overworld_min
,
387 y_max
= mcl_worlds
.layer_to_y(13),
391 minetest
.register_ore({
392 ore_type
= "scatter",
393 ore
= "mcl_core:stone_with_redstone",
395 clust_scarcity
= 1000,
398 y_min
= mcl_worlds
.layer_to_y(13),
399 y_max
= mcl_worlds
.layer_to_y(15),
401 minetest
.register_ore({
402 ore_type
= "scatter",
403 ore
= "mcl_core:stone_with_redstone",
405 clust_scarcity
= 1600,
408 y_min
= mcl_worlds
.layer_to_y(13),
409 y_max
= mcl_worlds
.layer_to_y(15),
416 if mg_name
== "v6" then
417 -- Generate everywhere in v6, but rarely.
420 minetest
.register_ore({
421 ore_type
= "scatter",
422 ore
= "mcl_core:stone_with_emerald",
424 clust_scarcity
= 14340,
427 y_min
= mcl_vars
.mg_overworld_min
,
428 y_max
= mcl_worlds
.layer_to_y(29),
431 minetest
.register_ore({
432 ore_type
= "scatter",
433 ore
= "mcl_core:stone_with_emerald",
435 clust_scarcity
= 21510,
438 y_min
= mcl_worlds
.layer_to_y(30),
439 y_max
= mcl_worlds
.layer_to_y(32),
447 -- Common spawn (in the center)
448 minetest
.register_ore({
449 ore_type
= "scatter",
450 ore
= "mcl_core:stone_with_lapis",
452 clust_scarcity
= 10000,
455 y_min
= mcl_worlds
.layer_to_y(14),
456 y_max
= mcl_worlds
.layer_to_y(16),
459 -- Rare spawn (below center)
460 minetest
.register_ore({
461 ore_type
= "scatter",
462 ore
= "mcl_core:stone_with_lapis",
464 clust_scarcity
= 12000,
467 y_min
= mcl_worlds
.layer_to_y(10),
468 y_max
= mcl_worlds
.layer_to_y(13),
470 minetest
.register_ore({
471 ore_type
= "scatter",
472 ore
= "mcl_core:stone_with_lapis",
474 clust_scarcity
= 14000,
477 y_min
= mcl_worlds
.layer_to_y(6),
478 y_max
= mcl_worlds
.layer_to_y(9),
480 minetest
.register_ore({
481 ore_type
= "scatter",
482 ore
= "mcl_core:stone_with_lapis",
484 clust_scarcity
= 16000,
487 y_min
= mcl_worlds
.layer_to_y(2),
488 y_max
= mcl_worlds
.layer_to_y(5),
490 minetest
.register_ore({
491 ore_type
= "scatter",
492 ore
= "mcl_core:stone_with_lapis",
494 clust_scarcity
= 18000,
497 y_min
= mcl_worlds
.layer_to_y(0),
498 y_max
= mcl_worlds
.layer_to_y(2),
501 -- Rare spawn (above center)
502 minetest
.register_ore({
503 ore_type
= "scatter",
504 ore
= "mcl_core:stone_with_lapis",
506 clust_scarcity
= 12000,
509 y_min
= mcl_worlds
.layer_to_y(17),
510 y_max
= mcl_worlds
.layer_to_y(20),
512 minetest
.register_ore({
513 ore_type
= "scatter",
514 ore
= "mcl_core:stone_with_lapis",
516 clust_scarcity
= 14000,
519 y_min
= mcl_worlds
.layer_to_y(21),
520 y_max
= mcl_worlds
.layer_to_y(24),
522 minetest
.register_ore({
523 ore_type
= "scatter",
524 ore
= "mcl_core:stone_with_lapis",
526 clust_scarcity
= 16000,
529 y_min
= mcl_worlds
.layer_to_y(25),
530 y_max
= mcl_worlds
.layer_to_y(28),
532 minetest
.register_ore({
533 ore_type
= "scatter",
534 ore
= "mcl_core:stone_with_lapis",
536 clust_scarcity
= 18000,
539 y_min
= mcl_worlds
.layer_to_y(29),
540 y_max
= mcl_worlds
.layer_to_y(32),
542 minetest
.register_ore({
543 ore_type
= "scatter",
544 ore
= "mcl_core:stone_with_lapis",
546 clust_scarcity
= 32000,
549 y_min
= mcl_worlds
.layer_to_y(31),
550 y_max
= mcl_worlds
.layer_to_y(32),
553 if mg_name
~= "flat" then
555 -- Water and lava springs (single blocks of lava/water source)
556 -- Water appears at nearly every height, but not near the bottom
557 minetest
.register_ore({
558 ore_type
= "scatter",
559 ore
= "mcl_core:water_source",
560 wherein
= {"mcl_core:stone", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite", "mcl_core:dirt"},
561 clust_scarcity
= 9000,
564 y_min
= mcl_worlds
.layer_to_y(5),
565 y_max
= mcl_worlds
.layer_to_y(128),
568 -- Lava springs are rather common at -31 and below
569 minetest
.register_ore({
570 ore_type
= "scatter",
571 ore
= "mcl_core:lava_source",
573 clust_scarcity
= 2000,
576 y_min
= mcl_worlds
.layer_to_y(1),
577 y_max
= mcl_worlds
.layer_to_y(10),
580 minetest
.register_ore({
581 ore_type
= "scatter",
582 ore
= "mcl_core:lava_source",
584 clust_scarcity
= 9000,
587 y_min
= mcl_worlds
.layer_to_y(11),
588 y_max
= mcl_worlds
.layer_to_y(31),
591 -- Lava springs will become gradually rarer with increasing height
592 minetest
.register_ore({
593 ore_type
= "scatter",
594 ore
= "mcl_core:lava_source",
596 clust_scarcity
= 32000,
599 y_min
= mcl_worlds
.layer_to_y(32),
600 y_max
= mcl_worlds
.layer_to_y(47),
603 minetest
.register_ore({
604 ore_type
= "scatter",
605 ore
= "mcl_core:lava_source",
607 clust_scarcity
= 72000,
610 y_min
= mcl_worlds
.layer_to_y(48),
611 y_max
= mcl_worlds
.layer_to_y(61),
614 -- Lava may even appear above surface, but this is very rare
615 minetest
.register_ore({
616 ore_type
= "scatter",
617 ore
= "mcl_core:lava_source",
619 clust_scarcity
= 96000,
622 y_min
= mcl_worlds
.layer_to_y(62),
623 y_max
= mcl_worlds
.layer_to_y(127),
632 local function register_mgv6_decorations()
635 minetest
.register_decoration({
636 deco_type
= "simple",
637 place_on
= {"group:sand"},
642 spread
= {x
= 100, y
= 100, z
= 100},
648 y_max
= mcl_vars
.mg_overworld_max
,
649 decoration
= "mcl_core:cactus",
655 minetest
.register_decoration({
656 deco_type
= "simple",
657 place_on
= {"mcl_core:dirt", "mcl_core:coarse_dirt", "group:grass_block_no_snow", "group:sand", "mcl_core:podzol", "mcl_core:reeds"},
662 spread
= {x
= 100, y
= 100, z
= 100},
668 y_max
= mcl_vars
.mg_overworld_max
,
669 decoration
= "mcl_core:reeds",
672 spawn_by
= { "mcl_core:water_source", "group:frosted_ice" },
677 minetest
.register_decoration({
678 deco_type
= "schematic",
680 size
= { x
=1, y
=3, z
=1 },
682 { name
= "air", prob
= 0 },
683 { name
= "mcl_flowers:double_grass", param1
= 255, },
684 { name
= "mcl_flowers:double_grass_top", param1
= 255, },
688 ["mcl_flowers:tallgrass"] = "mcl_flowers:double_grass"
690 place_on
= {"group:grass_block_no_snow"},
695 spread
= {x
= 100, y
= 100, z
= 100},
701 y_max
= mcl_vars
.mg_overworld_max
,
705 minetest
.register_decoration({
706 deco_type
= "schematic",
708 size
= { x
=1, y
=3, z
=1 },
710 { name
= "air", prob
= 0 },
711 { name
= "mcl_flowers:double_fern", param1
=255, },
712 { name
= "mcl_flowers:double_fern_top", param1
=255, },
716 ["mcl_flowers:fern"] = "mcl_flowers:double_fern"
718 -- v6 hack: This makes sure large ferns only appear in jungles
719 spawn_by
= { "mcl_core:jungletree", "mcl_flowers:fern" },
721 place_on
= {"group:grass_block_no_snow"},
727 spread
= {x
= 250, y
= 250, z
= 250},
733 y_max
= mcl_vars
.mg_overworld_max
,
737 local register_large_flower
= function(name
, seed
, offset
)
738 minetest
.register_decoration({
739 deco_type
= "schematic",
741 size
= { x
=1, y
=3, z
=1 },
743 { name
= "air", prob
= 0 },
744 { name
= "mcl_flowers:"..name
, param1
=255, },
745 { name
= "mcl_flowers:"..name
.."_top", param1
=255, },
748 place_on
= {"group:grass_block_no_snow"},
754 spread
= {x
= 300, y
= 300, z
= 300},
760 y_max
= mcl_vars
.overworld_max
,
765 register_large_flower("rose_bush", 9350, -0.008)
766 register_large_flower("peony", 10450, -0.008)
767 register_large_flower("lilac", 10600, -0.007)
768 register_large_flower("sunflower", 2940, -0.005)
771 minetest
.register_decoration({
772 deco_type
= "schematic",
774 size
= { x
=1, y
=3, z
=1 },
776 { name
= "mcl_core:water_source", prob
= 0 },
777 { name
= "mcl_core:water_source" },
778 { name
= "mcl_flowers:waterlily", param1
= 255 },
781 place_on
= "mcl_core:dirt",
786 spread
= {x
= 200, y
= 200, z
= 200},
797 minetest
.register_decoration({
798 deco_type
= "schematic",
800 size
= { x
=1, y
=2, z
=1 },
802 { name
= "air", prob
= 0 },
803 { name
= "mcl_farming:pumpkin_face" },
806 place_on
= {"group:grass_block_no_snow"},
811 spread
= {x
= 250, y
= 250, z
= 250},
817 y_max
= mcl_vars
.overworld_max
,
822 minetest
.register_decoration({
823 deco_type
= "simple",
824 place_on
= {"group:grass_block_no_snow"},
829 spread
= {x
= 100, y
= 100, z
= 100},
835 y_max
= mcl_vars
.overworld_max
,
836 decoration
= "mcl_flowers:tallgrass",
838 minetest
.register_decoration({
839 deco_type
= "simple",
840 place_on
= {"group:grass_block_no_snow"},
845 spread
= {x
= 100, y
= 100, z
= 100},
851 y_max
= mcl_vars
.overworld_max
,
852 decoration
= "mcl_flowers:tallgrass",
854 -- Add a small amount of tall grass everywhere to avoid areas completely empty devoid of tall grass
855 minetest
.register_decoration({
856 deco_type
= "simple",
857 place_on
= {"group:grass_block_no_snow"},
861 y_max
= mcl_vars
.overworld_max
,
862 decoration
= "mcl_flowers:tallgrass",
865 local mushrooms
= {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown"}
866 local mseeds
= { 7133, 8244 }
867 for m
=1, #mushrooms
do
868 -- Mushrooms next to trees
869 minetest
.register_decoration({
870 deco_type
= "simple",
871 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"},
876 spread
= {x
= 100, y
= 100, z
= 100},
882 y_max
= mcl_vars
.mg_overworld_max
,
883 decoration
= mushrooms
[m
],
884 spawn_by
= { "mcl_core:tree", "mcl_core:sprucetree", "mcl_core:darktree", "mcl_core:birchtree", },
890 minetest
.register_decoration({
891 deco_type
= "simple",
892 place_on
= {"group:sand", "mcl_core:podzol", "mcl_core:dirt", "mcl_core:coarse_dirt", "group:hardened_clay"},
897 spread
= {x
= 100, y
= 100, z
= 100},
903 y_max
= mcl_vars
.mg_overworld_max
,
904 decoration
= "mcl_core:deadbush",
907 local function register_mgv6_flower(name
, seed
, offset
, y_max
)
908 if offset
== nil then
912 y_max
= mcl_vars
.mg_overworld_max
914 minetest
.register_decoration({
915 deco_type
= "simple",
916 place_on
= {"group:grass_block_no_snow"},
921 spread
= {x
= 100, y
= 100, z
= 100},
928 decoration
= "mcl_flowers:"..name
,
932 register_mgv6_flower("tulip_red", 436)
933 register_mgv6_flower("tulip_orange", 536)
934 register_mgv6_flower("tulip_pink", 636)
935 register_mgv6_flower("tulip_white", 736)
936 register_mgv6_flower("azure_bluet", 800)
937 register_mgv6_flower("dandelion", 8)
938 -- Allium is supposed to only appear in flower forest in MC. There are no flower forests in v6.
939 -- We compensate by making it slightly rarer in v6.
940 register_mgv6_flower("allium", 0, -0.001)
941 --[[ Blue orchid is supposed to appear in swamplands. There are no swamplands in v6.
942 We emulate swamplands by limiting the height to 5 levels above sea level,
943 which should be close to the water. ]]
944 register_mgv6_flower("blue_orchid", 64500, nil, mcl_worlds
.layer_to_y(67))
945 register_mgv6_flower("oxeye_daisy", 3490)
946 register_mgv6_flower("poppy", 9439)
950 -- Apply mapgen-specific mapgen code
951 if mg_name
== "v6" then
952 register_mgv6_decorations()
953 minetest
.set_mapgen_setting("mg_flags", "caves,nodungeons,decorations,light", true)
954 elseif mg_name
== "flat" then
955 local classic
= minetest
.get_mapgen_setting("mcl_superflat_classic")
956 if classic
== nil then
957 classic
= minetest
.settings
:get_bool("mcl_superflat_classic")
958 minetest
.set_mapgen_setting("mcl_superflat_classic", "true", true)
960 if classic
~= "false" then
961 -- Enforce superflat-like mapgen: No hills, lakes or caves
962 minetest
.set_mapgen_setting("mg_flags", "nocaves,nodungeons,nodecorations,light", true)
963 minetest
.set_mapgen_setting("mgflat_spflags", "nolakes,nohills", true)
965 -- If superflat mode is disabled, mapgen is way more liberal
966 minetest
.set_mapgen_setting("mg_flags", "caves,nodungeons,nodecorations,light", true)
969 minetest
.set_mapgen_setting("mg_flags", "caves,nodungeons,decorations,light", true)
972 -- Helper function for converting a MC probability to MT, with
973 -- regards to MapBlocks.
974 -- Some MC generated structures are generated on per-chunk
976 -- The MC probability is 1/x per Minecraft chunk (16×16).
978 -- x: The MC probability is 1/x.
979 -- minp, maxp: MapBlock limits
980 -- returns: Probability (1/return_value) for a single MT mapblock
981 local function minecraft_chunk_probability(x
, minp
, maxp
)
982 -- 256 is the MC chunk height
983 return x
* (((maxp
.x
-minp
.x
+1)*(maxp
.z
-minp
.z
+1)) / 256)
986 -- Takes an index of a biomemap table (from minetest.get_mapgen_object),
987 -- minp and maxp (from an on_generated callback) and returns the real world coordinates
989 -- Inverse function of xz_to_biomemap
990 local biomemap_to_xz
= function(index
, minp
, maxp
)
991 local xwidth
= maxp
.x
- minp
.x
+ 1
992 local zwidth
= maxp
.z
- minp
.z
+ 1
993 local x
= ((index
-1) % xwidth
) + minp
.x
994 local z
= ((index
-1) / zwidth
) + minp
.z
998 -- Takes x and z coordinates and minp and maxp of a generated chunk
999 -- (in on_generated callback) and returns a biomemap index)
1000 -- Inverse function of biomemap_to_xz
1001 local xz_to_biomemap_index
= function(x
, z
, minp
, maxp
)
1002 local xwidth
= maxp
.x
- minp
.x
+ 1
1003 local zwidth
= maxp
.z
- minp
.z
+ 1
1004 local minix
= x
% xwidth
1005 local miniz
= z
% zwidth
1007 return (minix
+ miniz
* zwidth
) + 1
1010 -- Perlin noise objects
1011 local perlin_structures
1012 local perlin_vines
, perlin_vines_fine
, perlin_vines_upwards
, perlin_vines_length
, perlin_vines_density
1015 local function generate_clay(minp
, maxp
, seed
, voxelmanip_data
, voxelmanip_area
, lvm_used
)
1016 -- TODO: Make clay generation reproducible for same seed.
1017 if maxp
.y
< -5 or minp
.y
> 0 then
1021 perlin_clay
= perlin_clay
or minetest
.get_perlin({
1024 spread
= {x
= 5, y
= 5, z
= 5},
1030 for y
=math
.max(minp
.y
, 0), math
.min(maxp
.y
, -8), -1 do
1031 -- Assume X and Z lengths are equal
1033 local divs
= (maxp
.x
-minp
.x
)/divlen
+1;
1034 for divx
=0+1,divs
-2 do
1035 for divz
=0+1,divs
-2 do
1036 -- Get position and shift it a bit randomly so the clay do not obviously appear in a grid
1037 local cx
= minp
.x
+ math
.floor((divx
+0.5)*divlen
) + math
.random(-1,1)
1038 local cz
= minp
.z
+ math
.floor((divz
+0.5)*divlen
) + math
.random(-1,1)
1040 local water_pos
= voxelmanip_area
:index(cx
, y
+1, cz
)
1041 local waternode
= voxelmanip_data
[water_pos
]
1042 local surface_pos
= voxelmanip_area
:index(cx
, y
, cz
)
1043 local surfacenode
= voxelmanip_data
[surface_pos
]
1045 local genrnd
= math
.random(1, 20)
1046 if genrnd
== 1 and perlin_clay
:get3d({x
=cx
,y
=y
,z
=cz
}) > 0 and waternode
== c_water
and
1047 (surfacenode
== c_dirt
or minetest
.get_item_group(minetest
.get_name_from_content_id(surfacenode
), "sand") == 1) then
1048 local diamondsize
= math
.random(1, 3)
1049 for x1
= -diamondsize
, diamondsize
do
1050 for z1
= -(diamondsize
- math
.abs(x1
)), diamondsize
- math
.abs(x1
) do
1051 local ccpos
= voxelmanip_area
:index(cx
+x1
, y
, cz
+z1
)
1052 local claycandidate
= voxelmanip_data
[ccpos
]
1053 if voxelmanip_data
[ccpos
] == c_dirt
or minetest
.get_item_group(minetest
.get_name_from_content_id(claycandidate
), "sand") == 1 then
1054 voxelmanip_data
[ccpos
] = c_clay
1066 -- TODO: Try to use more efficient structure generating code
1067 local function generate_structures(minp
, maxp
, seed
, biomemap
)
1068 local chunk_has_desert_well
= false
1069 local chunk_has_desert_temple
= false
1070 local chunk_has_igloo
= false
1071 local struct_min
, struct_max
= -3, 64
1072 if maxp
.y
>= struct_min
and minp
.y
<= struct_max
then
1073 -- Generate structures
1075 perlin_structures
= perlin_structures
or minetest
.get_perlin(329, 3, 0.6, 100)
1076 -- Assume X and Z lengths are equal
1078 local divs
= (maxp
.x
-minp
.x
)/divlen
+1;
1079 for divx
=0,divs
-1 do
1080 for divz
=0,divs
-1 do
1081 local x0
= minp
.x
+ math
.floor((divx
+0)*divlen
)
1082 local z0
= minp
.z
+ math
.floor((divz
+0)*divlen
)
1083 local x1
= minp
.x
+ math
.floor((divx
+1)*divlen
)
1084 local z1
= minp
.z
+ math
.floor((divz
+1)*divlen
)
1085 -- Determine amount from perlin noise
1086 local amount
= math
.floor(perlin_structures
:get2d({x
=x0
, y
=z0
}) * 9)
1087 -- Find random positions based on this random
1088 local pr
= PseudoRandom(seed
+1)
1090 local x
= pr
:next(x0
, x1
)
1091 local z
= pr
:next(z0
, z1
)
1092 -- Find ground level
1093 local ground_y
= nil
1094 for y
= struct_max
, struct_min
, -1 do
1095 local checknode
= minetest
.get_node_or_nil({x
=x
,y
=y
,z
=z
})
1096 if checknode
and minetest
.registered_nodes
[checknode
.name
].walkable
then
1103 local p
= {x
=x
,y
=ground_y
+1,z
=z
}
1104 local nn
= minetest
.get_node(p
).name
1105 -- Check if the node can be replaced
1106 if minetest
.registered_nodes
[nn
] and
1107 minetest
.registered_nodes
[nn
].buildable_to
then
1108 nn
= minetest
.get_node({x
=x
,y
=ground_y
,z
=z
}).name
1109 local struct
= false
1111 -- Desert temples and desert wells
1112 if nn
== "mcl_core:sand" or (nn
== "mcl_core:sandstone") then
1113 if not chunk_has_desert_temple
and not chunk_has_desert_well
and ground_y
> 3 then
1114 -- Spawn desert temple
1115 -- TODO: Check surface
1116 if math
.random(1,12000) == 1 then
1117 mcl_structures
.call_struct(p
, "desert_temple")
1118 chunk_has_desert_temple
= true
1121 if not chunk_has_desert_temple
and not chunk_has_desert_well
and ground_y
> 3 then
1122 local desert_well_prob
= minecraft_chunk_probability(1000, minp
, maxp
)
1124 -- Spawn desert well
1125 if math
.random(1, desert_well_prob
) == 1 then
1127 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")
1128 if #surface
>= 25 then
1129 mcl_structures
.call_struct(p
, "desert_well")
1130 chunk_has_desert_well
= true
1136 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
1137 if math
.random(1, 4400) == 1 then
1139 local floor = {x
=p
.x
+9, y
=p
.y
-1, z
=p
.z
+9}
1140 local surface
= minetest
.find_nodes_in_area({x
=p
.x
,y
=p
.y
-1,z
=p
.z
}, floor, "mcl_core:snowblock")
1141 local surface2
= minetest
.find_nodes_in_area({x
=p
.x
,y
=p
.y
-1,z
=p
.z
}, floor, "mcl_core:dirt_with_grass_snow")
1142 if #surface
+ #surface2
>= 63 then
1143 mcl_structures
.call_struct(p
, "igloo")
1144 chunk_has_igloo
= true
1150 if nn
== "mcl_core:sandstone" or nn
== "mcl_core:sand" and not chunk_has_desert_temple
and ground_y
> 3 then
1151 local fossil_prob
= minecraft_chunk_probability(64, minp
, maxp
)
1153 if math
.random(1, fossil_prob
) == 1 then
1154 -- Spawn fossil below desert surface between layers 40 and 49
1155 local p1
= {x
=p
.x
, y
=math
.random(mcl_worlds
.layer_to_y(40), mcl_worlds
.layer_to_y(49)), z
=p
.z
}
1156 -- Very rough check of the environment (we expect to have enough stonelike nodes).
1157 -- Fossils may still appear partially exposed in caves, but this is O.K.
1158 local p2
= vector
.add(p1
, 4)
1159 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"})
1161 if #nodes
>= 100 then -- >= 80%
1162 mcl_structures
.call_struct(p1
, "fossil")
1168 if ground_y
<= 0 and nn
== "mcl_core:dirt" then
1169 local prob
= minecraft_chunk_probability(48, minp
, maxp
)
1171 local swampland
= minetest
.get_biome_id("Swampland")
1172 local swampland_shore
= minetest
.get_biome_id("Swampland_shore")
1174 -- Where do witches live?
1176 local here_be_witches
= false
1177 if mg_name
== "v6" then
1178 -- In ye good ol' landes of v6, witches will settle at any
1180 here_be_witches
= true
1182 -- The townsfolk told me that witches live in the swamplands!
1183 local bi
= xz_to_biomemap_index(p
.x
, p
.z
, minp
, maxp
)
1184 if biomemap
[bi
] == swampland
or biomemap
[bi
] == swampland_shore
then
1185 here_be_witches
= true
1189 -- We still need a bit of luck!
1190 if here_be_witches
and math
.random(1, prob
) == 1 then
1191 local r
= tostring(math
.random(0, 3) * 90) -- "0", "90", "180" or 270"
1192 local p1
= {x
=p
.x
-1, y
=WITCH_HUT_HEIGHT
+2, z
=p
.z
-1}
1194 if r
== "0" or r
== "180" then
1195 size
= {x
=10, y
=4, z
=8}
1197 size
= {x
=8, y
=4, z
=10}
1199 local p2
= vector
.add(p1
, size
)
1201 -- This checks free space at the “body” of the hut and a bit around.
1202 -- ALL nodes must be free for the placement to succeed.
1203 local free_nodes
= minetest
.find_nodes_in_area(p1
, p2
, {"air", "mcl_core:water_source", "mcl_flowers:waterlily"})
1204 if #free_nodes
>= ((size
.x
+1)*(size
.y
+1)*(size
.z
+1)) then
1205 local place
= {x
=p
.x
, y
=WITCH_HUT_HEIGHT
-1, z
=p
.z
}
1207 -- FIXME: For some mysterious reason (black magic?) this
1208 -- function does sometimes NOT spawn the witch hut. One can only see the
1209 -- oak wood nodes in the water, but no hut. :-/
1210 mcl_structures
.call_struct(place
, "witch_hut", r
)
1212 -- TODO: Spawn witch in or around hut when the mob sucks less.
1214 local place_tree_if_free
= function(pos
, prev_result
)
1215 local nn
= minetest
.get_node(pos
).name
1216 if nn
== "mcl_flowers:waterlily" or nn
== "mcl_core:water_source" or nn
== "mcl_core:water_flowing" or nn
== "air" then
1217 minetest
.set_node(pos
, {name
="mcl_core:tree", param2
=0})
1231 elseif r
== "180" then
1238 elseif r
== "270" then
1245 elseif r
== "90" then
1253 for o
=1, #offsets
do
1255 for y
=place
.y
-1, place
.y
-64, -1 do
1256 local tpos
= vector
.add(place
, offsets
[o
])
1258 ok
= place_tree_if_free(tpos
, ok
)
1269 -- In other mapgens, ice spikes are generated as decorations.
1270 if mg_name
== "v6" and not chunk_has_igloo
and nn
== "mcl_core:snowblock" then
1271 local spike
= math
.random(1, 3000)
1274 local floor = {x
=p
.x
+4, y
=p
.y
-1, z
=p
.z
+4}
1275 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"})
1276 -- Check for collision with spruce
1277 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"})
1279 if #surface
>= 9 and #spruce_collisions
== 0 then
1280 mcl_structures
.call_struct(p
, "ice_spike_large")
1282 elseif spike
< 100 then
1284 local floor = {x
=p
.x
+6, y
=p
.y
-1, z
=p
.z
+6}
1285 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"})
1287 -- Check for collision with spruce
1288 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"})
1290 if #surface
>= 25 and #spruce_collisions
== 0 then
1291 mcl_structures
.call_struct(p
, "ice_spike_small")
1302 elseif minp
.y
<= END_EXIT_PORTAL_POS
.y
and maxp
.y
>= END_EXIT_PORTAL_POS
.y
and
1303 minp
.x
<= END_EXIT_PORTAL_POS
.x
and maxp
.x
>= END_EXIT_PORTAL_POS
.x
and
1304 minp
.z
<= END_EXIT_PORTAL_POS
.z
and maxp
.z
>= END_EXIT_PORTAL_POS
.z
then
1306 for y
=maxp
.y
, minp
.y
, -1 do
1307 local p
= {x
=END_EXIT_PORTAL_POS
.x
, y
=y
, z
=END_EXIT_PORTAL_POS
.z
}
1308 if minetest
.get_node(p
).name
== "mcl_end:end_stone" then
1309 mcl_structures
.call_struct(p
, "end_exit_portal")
1315 mcl_structures
.call_struct(END_EXIT_PORTAL_POS
, "end_exit_portal")
1320 -- Buffers for LuaVoxelManip
1321 local lvm_buffer
= {}
1322 local lvm_buffer_param2
= {}
1324 -- Generate tree decorations in the bounding box. This adds:
1325 -- * Cocoa at jungle trees
1326 -- * Jungle tree vines
1327 -- * Oak vines in swamplands
1328 local function generate_tree_decorations(minp
, maxp
, seed
, data
, param2_data
, area
, biomemap
, lvm_used
)
1333 local oaktree
, oakleaves
, jungletree
, jungleleaves
= {}, {}, {}, {}
1334 local swampland
= minetest
.get_biome_id("Swampland")
1335 local swampland_shore
= minetest
.get_biome_id("Swampland_shore")
1336 local jungle
= minetest
.get_biome_id("Jungle")
1337 local jungle_shore
= minetest
.get_biome_id("Jungle_shore")
1338 local jungle_m
= minetest
.get_biome_id("JungleM")
1339 local jungle_m_shore
= minetest
.get_biome_id("JungleM_shore")
1340 local jungle_edge
= minetest
.get_biome_id("JungleEdge")
1341 local jungle_edge_shore
= minetest
.get_biome_id("JungleEdge_shore")
1342 local jungle_edge_m
= minetest
.get_biome_id("JungleEdgeM")
1343 local jungle_edge_m_shore
= minetest
.get_biome_id("JungleEdgeM_shore")
1345 -- Modifier for Jungle M biome: More vines and cocoas
1346 local dense_vegetation
= false
1349 -- Biome map available: Check if the required biome (jungle or swampland)
1350 -- is in this mapchunk. We are only interested in trees in the correct biome.
1351 -- The nodes are added if the correct biome is *anywhere* in the mapchunk.
1352 -- TODO: Strictly generate vines in the correct biomes only.
1353 local swamp_biome_found
, jungle_biome_found
= false, false
1354 for b
=1, #biomemap
do
1355 local id
= biomemap
[b
]
1357 if not swamp_biome_found
and (id
== swampland
or id
== swampland_shore
) then
1358 oaktree
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:tree"})
1359 oakleaves
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:leaves"})
1360 swamp_biome_found
= true
1362 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
1363 jungletree
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:jungletree"})
1364 jungleleaves
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:jungleleaves"})
1365 jungle_biome_found
= true
1367 if not dense_vegetation
and (id
== jungle_m
or id
== jungle_m_shore
) then
1368 dense_vegetation
= true
1370 if swamp_biome_found
and jungle_biome_found
and dense_vegetation
then
1375 -- If there is no biome map, we just count all jungle things we can find.
1376 -- Oak vines will not be generated.
1377 jungletree
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:jungletree"})
1378 jungleleaves
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:jungleleaves"})
1381 local pos
, treepos
, dir
1383 local cocoachance
= 40
1384 if dense_vegetation
then
1388 -- Pass 1: Generate cocoas at jungle trees
1389 for n
= 1, #jungletree
do
1392 treepos
= table.copy(pos
)
1394 if minetest
.find_node_near(pos
, 1, {"mcl_core:jungleleaves"}) then
1396 dir
= math
.random(1, cocoachance
)
1400 elseif dir
== 2 then
1402 elseif dir
== 3 then
1404 elseif dir
== 4 then
1408 local p_pos
= area
:index(pos
.x
, pos
.y
, pos
.z
)
1409 local l
= minetest
.get_node_light(pos
)
1412 and data
[p_pos
] == c_air
1413 and l
~= nil and l
> 12 then
1414 local c
= math
.random(1, 3)
1416 data
[p_pos
] = c_cocoa_1
1418 data
[p_pos
] = c_cocoa_2
1420 data
[p_pos
] = c_cocoa_3
1422 param2_data
[p_pos
] = minetest
.dir_to_facedir(vector
.subtract(treepos
, pos
))
1429 -- Pass 2: Generate vines at jungle wood, jungle leaves in jungle and oak wood, oak leaves in swampland
1430 perlin_vines
= perlin_vines
or minetest
.get_perlin(555, 4, 0.6, 500)
1431 perlin_vines_fine
= perlin_vines_fine
or minetest
.get_perlin(43000, 3, 0.6, 1)
1432 perlin_vines_length
= perlin_vines_length
or minetest
.get_perlin(435, 4, 0.6, 75)
1433 perlin_vines_upwards
= perlin_vines_upwards
or minetest
.get_perlin(436, 3, 0.6, 10)
1434 perlin_vines_density
= perlin_vines_density
or minetest
.get_perlin(436, 3, 0.6, 500)
1436 -- Extra long vines in Jungle M
1437 local maxvinelength
= 7
1438 if dense_vegetation
then
1444 treething
= jungletree
1446 treething
= jungleleaves
1450 treething
= oakleaves
1453 for n
= 1, #treething
do
1456 treepos
= table.copy(pos
)
1466 local pos
= vector
.add(pos
, dirs
[d
])
1467 local p_pos
= area
:index(pos
.x
, pos
.y
, pos
.z
)
1469 local vine_threshold
= math
.max(0.33333, perlin_vines_density
:get2d(pos
))
1470 if dense_vegetation
then
1471 vine_threshold
= vine_threshold
* (2/3)
1474 if perlin_vines
:get2d(pos
) > -1.0 and perlin_vines_fine
:get3d(pos
) > vine_threshold
and data
[p_pos
] == c_air
then
1480 local param2
= minetest
.dir_to_wallmounted(rdir
)
1482 -- Determine growth direction
1483 local grow_upwards
= false
1484 -- Only possible on the wood, not on the leaves
1486 grow_upwards
= perlin_vines_upwards
:get3d(pos
) > 0.8
1488 if grow_upwards
then
1489 -- Grow vines up 1-4 nodes, even through jungleleaves.
1490 -- This may give climbing access all the way to the top of the tree :-)
1491 -- But this will be fairly rare.
1492 local length
= math
.ceil(math
.abs(perlin_vines_length
:get3d(pos
)) * 4)
1493 for l
=0, length
-1 do
1494 local t_pos
= area
:index(treepos
.x
, treepos
.y
, treepos
.z
)
1496 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
1497 data
[p_pos
] = c_vine
1498 param2_data
[p_pos
] = param2
1505 p_pos
= area
:index(pos
.x
, pos
.y
, pos
.z
)
1506 treepos
.y
= treepos
.y
+ 1
1509 -- Grow vines down, length between 1 and maxvinelength
1510 local length
= math
.ceil(math
.abs(perlin_vines_length
:get3d(pos
)) * maxvinelength
)
1511 for l
=0, length
-1 do
1512 if data
[p_pos
] == c_air
then
1513 data
[p_pos
] = c_vine
1514 param2_data
[p_pos
] = param2
1521 p_pos
= area
:index(pos
.x
, pos
.y
, pos
.z
)
1532 local pr_shroom
= PseudoRandom(os
.time()-24359)
1533 -- Generate mushrooms in caves manually.
1534 -- Minetest's API does not support decorations in caves yet. :-(
1535 local generate_underground_mushrooms
= function(minp
, maxp
, seed
)
1536 -- Generate rare underground mushrooms
1537 -- TODO: Make them appear in groups, use Perlin noise
1538 local min, max = mcl_vars
.mg_lava_overworld_max
+ 4, 0
1539 if minp
.y
> max or maxp
.y
< min then
1544 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"})
1546 for n
= 1, #stone
do
1547 bpos
= {x
= stone
[n
].x
, y
= stone
[n
].y
+ 1, z
= stone
[n
].z
}
1549 local l
= minetest
.get_node_light(bpos
, 0.5)
1550 if bpos
.y
>= min and bpos
.y
<= max and l
~= nil and l
<= 12 and pr_shroom
:next(1,1000) < 4 then
1551 if pr_shroom
:next(1,2) == 1 then
1552 minetest
.set_node(bpos
, {name
= "mcl_mushrooms:mushroom_brown"})
1554 minetest
.set_node(bpos
, {name
= "mcl_mushrooms:mushroom_red"})
1560 local pr_nether
= PseudoRandom(os
.time()+667)
1561 local nether_wart_chance
1562 if mg_name
== "v6" then
1563 nether_wart_chance
= 85
1565 nether_wart_chance
= 170
1567 -- Generate Nether decorations manually: Eternal fire, mushrooms, nether wart
1568 -- Minetest's API does not support decorations in caves yet. :-(
1569 local generate_nether_decorations
= function(minp
, maxp
, seed
)
1570 if minp
.y
> mcl_vars
.mg_nether_max
or maxp
.y
< mcl_vars
.mg_nether_min
then
1574 -- TODO: Generate everything based on Perlin noise instead of PseudoRandom
1577 local rack
= minetest
.find_nodes_in_area_under_air(minp
, maxp
, {"mcl_nether:netherrack"})
1578 local magma
= minetest
.find_nodes_in_area_under_air(minp
, maxp
, {"mcl_nether:magma"})
1579 local ssand
= minetest
.find_nodes_in_area_under_air(minp
, maxp
, {"mcl_nether:soul_sand"})
1581 -- Helper function to spawn “fake” decoration
1582 local special_deco
= function(nodes
, spawn_func
)
1583 for n
= 1, #nodes
do
1584 bpos
= {x
= nodes
[n
].x
, y
= nodes
[n
].y
+ 1, z
= nodes
[n
].z
}
1591 -- Eternal fire on netherrack
1592 special_deco(rack
, function(bpos
)
1593 -- Eternal fire on netherrack
1594 if pr_nether
:next(1,100) <= 3 then
1595 minetest
.set_node(bpos
, {name
= "mcl_fire:eternal_fire"})
1599 -- Eternal fire on magma cubes
1600 special_deco(magma
, function(bpos
)
1601 if pr_nether
:next(1,150) == 1 then
1602 minetest
.set_node(bpos
, {name
= "mcl_fire:eternal_fire"})
1606 -- Mushrooms on netherrack
1607 -- Note: Spawned *after* the fire because of light level checks
1608 special_deco(rack
, function(bpos
)
1609 local l
= minetest
.get_node_light(bpos
, 0.5)
1610 if bpos
.y
> mcl_vars
.mg_lava_nether_max
+ 6 and l
~= nil and l
<= 12 and pr_nether
:next(1,1000) <= 4 then
1611 -- TODO: Make mushrooms appear in groups, use Perlin noise
1612 if pr_nether
:next(1,2) == 1 then
1613 minetest
.set_node(bpos
, {name
= "mcl_mushrooms:mushroom_brown"})
1615 minetest
.set_node(bpos
, {name
= "mcl_mushrooms:mushroom_red"})
1620 -- Nether wart on soul sand
1621 -- TODO: Spawn in Nether fortresses
1622 special_deco(ssand
, function(bpos
)
1623 if pr_nether
:next(1, nether_wart_chance
) == 1 then
1624 minetest
.set_node(bpos
, {name
= "mcl_nether:nether_wart"})
1630 -- Below the bedrock, generate air/void
1631 minetest
.register_on_generated(function(minp
, maxp
, seed
)
1632 local vm
, emin
, emax
= minetest
.get_mapgen_object("voxelmanip")
1633 local data
= vm
:get_data(lvm_buffer
)
1634 local param2_data
= vm
:get_param2_data(lvm_buffer_param2
)
1635 local area
= VoxelArea
:new({MinEdge
=emin
, MaxEdge
=emax
})
1636 local lvm_used
= false
1641 -- Generate basic layer-based nodes: void, bedrock, realm barrier, lava seas, etc.
1642 -- Also perform some basic node replacements.
1644 -- Helper function to set all nodes in the layers between min and max.
1645 -- content_id: Node to set
1647 -- If content_id, node will be set only if it is equal to check.
1648 -- If function(pos_to_check, content_id_at_this_pos), will set node only if returns true.
1649 -- min, max: Minimum and maximum Y levels of the layers to set
1650 -- minp, maxp: minp, maxp of the on_generated
1651 -- lvm_used: Set to true if any node in this on_generated has been set before.
1653 -- returns true if any node was set and lvm_used otherwise
1654 local function set_layers(content_id
, check
, min, max, minp
, maxp
, lvm_used
)
1655 if (maxp
.y
>= min and minp
.y
<= max) then
1656 for y
= math
.max(min, minp
.y
), math
.min(max, maxp
.y
) do
1657 for x
= minp
.x
, maxp
.x
do
1658 for z
= minp
.z
, maxp
.z
do
1659 local p_pos
= area
:index(x
, y
, z
)
1661 if type(check
) == "function" and check({x
=x
,y
=y
,z
=z
}, data
[p_pos
]) then
1662 data
[p_pos
] = content_id
1664 elseif check
== data
[p_pos
] then
1665 data
[p_pos
] = content_id
1669 data
[p_pos
] = content_id
1680 lvm_used
= set_layers(c_void
, nil, -31000, mcl_vars
.mg_nether_min
-1, minp
, maxp
, lvm_used
)
1681 lvm_used
= set_layers(c_void
, nil, mcl_vars
.mg_nether_max
+1, mcl_vars
.mg_end_min
-1, minp
, maxp
, lvm_used
)
1682 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
)
1683 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
)
1685 -- Realm barrier between the Overworld void and the End
1686 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
)
1688 if mg_name
~= "singlenode" then
1691 if mcl_vars
.mg_bedrock_is_rough
then
1692 bedrock_check
= function(pos
)
1694 -- Bedrock layers with increasing levels of roughness, until a perfecly flat bedrock later at the bottom layer
1695 -- This code assumes a bedrock height of 5 layers.
1697 local diff
= mcl_vars
.mg_bedrock_overworld_max
- y
-- Overworld bedrock
1698 local ndiff1
= mcl_vars
.mg_bedrock_nether_bottom_max
- y
-- Nether bedrock, bottom
1699 local ndiff2
= mcl_vars
.mg_bedrock_nether_top_max
- y
-- Nether bedrock, ceiling
1702 if diff
== 0 or ndiff1
== 0 or ndiff2
== 4 then
1703 -- 50% bedrock chance
1705 elseif diff
== 1 or ndiff1
== 1 or ndiff2
== 3 then
1708 elseif diff
== 2 or ndiff1
== 2 or ndiff2
== 2 then
1711 elseif diff
== 3 or ndiff1
== 3 or ndiff2
== 1 then
1714 elseif diff
== 4 or ndiff1
== 4 or ndiff2
== 0 then
1718 -- Not in bedrock layer
1722 return math
.random(1, top
) <= top
-1
1728 lvm_used
= set_layers(c_bedrock
, bedrock_check
, mcl_vars
.mg_bedrock_overworld_min
, mcl_vars
.mg_bedrock_overworld_max
, minp
, maxp
, lvm_used
)
1729 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
)
1730 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
)
1733 if mg_name
== "flat" then
1734 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
)
1737 -- Big lava seas by replacing air below a certain height
1738 if mcl_vars
.mg_lava
then
1739 lvm_used
= set_layers(c_lava
, c_air
, mcl_vars
.mg_overworld_min
, mcl_vars
.mg_lava_overworld_max
, minp
, maxp
, lvm_used
)
1740 lvm_used
= set_layers(c_nether_lava
, c_air
, mcl_vars
.mg_nether_min
, mcl_vars
.mg_lava_nether_max
, minp
, maxp
, lvm_used
)
1743 -- Clay, vines, cocoas
1744 lvm_used
= generate_clay(minp
, maxp
, seed
, data
, area
, lvm_used
)
1746 biomemap
= minetest
.get_mapgen_object("biomemap")
1747 lvm_used
= generate_tree_decorations(minp
, maxp
, seed
, data
, param2_data
, area
, biomemap
, lvm_used
)
1749 ----- Interactive block fixing section -----
1750 ----- The section to perform basic block overrides of the core mapgen generated world. -----
1752 -- Snow and sand fixes. This code implements snow consistency
1753 -- and fixes floating sand.
1754 -- A snowy grass block must be below a top snow or snow block at all times.
1755 if minp
.y
<= mcl_vars
.mg_overworld_max
and maxp
.y
>= mcl_vars
.mg_overworld_min
then
1757 -- Put top snow on snowy grass blocks. The mapgen does not generate the top snow on its own.
1758 if mg_name
== "v6" then
1759 local snowdirt
= minetest
.find_nodes_in_area_under_air(minp
, maxp
, "mcl_core:dirt_with_grass_snow")
1760 for n
= 1, #snowdirt
do
1761 -- CHECKME: What happens at chunk borders?
1762 local p_pos
= area
:index(snowdirt
[n
].x
, snowdirt
[n
].y
+ 1, snowdirt
[n
].z
)
1764 data
[p_pos
] = c_top_snow
1767 if #snowdirt
> 1 then
1773 -- Clear snowy grass blocks without snow above to ensure consistency.
1774 -- Solidify floating sand to sandstone (both colors).
1776 local nodes
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:dirt_with_grass_snow", "mcl_core:sand", "mcl_core:redsand"})
1778 local p_pos
= area
:index(nodes
[n
].x
, nodes
[n
].y
, nodes
[n
].z
)
1779 local p_pos_above
= area
:index(nodes
[n
].x
, nodes
[n
].y
+1, nodes
[n
].z
)
1780 local p_pos_below
= area
:index(nodes
[n
].x
, nodes
[n
].y
-1, nodes
[n
].z
)
1781 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
1782 data
[p_pos
] = c_dirt_with_grass
1784 elseif p_pos_below
and data
[p_pos_below
] == c_air
or data
[p_pos_below
] == c_water
then
1785 if data
[p_pos
] == c_sand
then
1786 data
[p_pos
] = c_sandstone
1788 elseif data
[p_pos
] == c_redsand
then
1789 -- Note: This is the only place in which red sandstone is generatd
1790 data
[p_pos
] = c_redsandstone
1797 -- Nether block fixes:
1798 -- * Replace water with Nether lava.
1799 -- * Replace stone, sand dirt in v6 so the Nether works in v6.
1800 elseif minp
.y
<= mcl_vars
.mg_nether_max
and maxp
.y
>= mcl_vars
.mg_nether_min
then
1802 if mg_name
== "v6" then
1803 nodes
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"})
1805 nodes
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:water_source"})
1808 local p_pos
= area
:index(nodes
[n
].x
, nodes
[n
].y
, nodes
[n
].z
)
1809 if data
[p_pos
] == c_water
then
1810 data
[p_pos
] = c_nether_lava
1812 elseif data
[p_pos
] == c_stone
then
1813 data
[p_pos
] = c_netherrack
1815 elseif data
[p_pos
] == c_sand
or data
[p_pos
] == c_dirt
then
1816 data
[p_pos
] = c_soul_sand
1822 -- * Replace water with end stone or air (depending on height).
1823 -- * Remove stone, sand, dirt in v6 so our End map generator works in v6.
1824 -- * Generate spawn platform (End portal destination)
1825 elseif minp
.y
<= mcl_vars
.mg_end_max
and maxp
.y
>= mcl_vars
.mg_end_min
then
1827 if mg_name
== "v6" then
1828 nodes
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"})
1830 nodes
= minetest
.find_nodes_in_area(minp
, maxp
, {"mcl_core:water_source"})
1833 local y
= nodes
[n
].y
1834 local p_pos
= area
:index(nodes
[n
].x
, y
, nodes
[n
].z
)
1836 if data
[p_pos
] == c_water
then
1837 if y
<= mcl_vars
.mg_end_min
+ 104 and y
>= mcl_vars
.mg_end_min
+ 40 then
1838 data
[p_pos
] = c_end_stone
1844 elseif data
[p_pos
] == c_stone
or data
[p_pos
] == c_dirt
or data
[p_pos
] == c_sand
then
1851 -- Obsidian spawn platform
1852 if minp
.y
<= mcl_vars
.mg_end_platform_pos
.y
and maxp
.y
>= mcl_vars
.mg_end_platform_pos
.y
and
1853 minp
.x
<= mcl_vars
.mg_end_platform_pos
.x
and maxp
.x
>= mcl_vars
.mg_end_platform_pos
.z
and
1854 minp
.z
<= mcl_vars
.mg_end_platform_pos
.z
and maxp
.z
>= mcl_vars
.mg_end_platform_pos
.z
then
1855 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
1856 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
1857 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
1858 local p_pos
= area
:index(x
, y
, z
)
1859 if y
== mcl_vars
.mg_end_platform_pos
.y
then
1860 data
[p_pos
] = c_obsidian
1872 -- Final hackery: Set sun light level in the End.
1873 -- -26912 is at a mapchunk border.
1875 if minp
.y
>= -26912 and maxp
.y
<= mcl_vars
.mg_end_max
then
1876 vm
:set_lighting({day
=15, night
=15})
1879 if minp
.y
>= mcl_vars
.mg_end_min
and maxp
.y
<= -26911 then
1887 vm
:set_param2_data(param2_data
)
1888 vm
:calc_lighting(nil, nil, shadow
)
1893 if mg_name
~= "singlenode" then
1894 -- Generate special decorations
1895 generate_underground_mushrooms(minp
, maxp
, seed
)
1896 generate_nether_decorations(minp
, maxp
, seed
)
1897 generate_structures(minp
, maxp
, seed
, biomemap
)