Generate witch huts slightly deeper
[MineClone/MineClone2.git] / mods / MAPGEN / mcl_mapgen_core / init.lua
blob9a65f0f7df166be7f69719134eee895ee1f13846
1 --
2 -- Aliases for map generator outputs
3 --
5 minetest.register_alias("mapgen_air", "air")
6 minetest.register_alias("mapgen_stone", "mcl_core:stone")
7 minetest.register_alias("mapgen_tree", "mcl_core:tree")
8 minetest.register_alias("mapgen_leaves", "mcl_core:leaves")
9 minetest.register_alias("mapgen_jungletree", "mcl_core:jungletree")
10 minetest.register_alias("mapgen_jungleleaves", "mcl_core:jungleleaves")
11 minetest.register_alias("mapgen_pine_tree", "mcl_core:sprucetree")
12 minetest.register_alias("mapgen_pine_needles", "mcl_core:spruceleaves")
14 minetest.register_alias("mapgen_apple", "mcl_core:leaves")
15 minetest.register_alias("mapgen_water_source", "mcl_core:water_source")
16 minetest.register_alias("mapgen_dirt", "mcl_core:dirt")
17 minetest.register_alias("mapgen_dirt_with_grass", "mcl_core:dirt_with_grass")
18 minetest.register_alias("mapgen_dirt_with_snow", "mcl_core:dirt_with_grass_snow")
19 minetest.register_alias("mapgen_sand", "mcl_core:sand")
20 minetest.register_alias("mapgen_gravel", "mcl_core:gravel")
21 minetest.register_alias("mapgen_clay", "mcl_core:clay")
22 minetest.register_alias("mapgen_lava_source", "air") -- Built-in lava generator is too unpredictable, we generate lava on our own
23 minetest.register_alias("mapgen_cobble", "mcl_core:cobble")
24 minetest.register_alias("mapgen_mossycobble", "mcl_core:mossycobble")
25 minetest.register_alias("mapgen_junglegrass", "mcl_flowers:fern")
26 minetest.register_alias("mapgen_stone_with_coal", "mcl_core:stone_with_coal")
27 minetest.register_alias("mapgen_stone_with_iron", "mcl_core:stone_with_iron")
28 minetest.register_alias("mapgen_desert_sand", "mcl_core:sand")
29 minetest.register_alias("mapgen_desert_stone", "mcl_core:sandstone")
30 minetest.register_alias("mapgen_sandstone", "mcl_core:sandstone")
31 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
47 -- Ore generation
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({
55 ore_type = "blob",
56 ore = node,
57 wherein = {"mcl_core:stone"},
58 clust_scarcity = 15*15*15,
59 clust_num_ores = 33,
60 clust_size = 5,
61 y_min = mcl_vars.mg_overworld_min,
62 y_max = mcl_vars.mg_overworld_max,
64 minetest.register_ore({
65 ore_type = "blob",
66 ore = node,
67 wherein = {"mcl_core:stone"},
68 clust_scarcity = 10*10*10,
69 clust_num_ores = 58,
70 clust_size = 7,
71 y_min = mcl_vars.mg_overworld_min,
72 y_max = mcl_vars.mg_overworld_max,
74 end
76 local stonelike = {"mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite"}
78 -- Dirt
79 minetest.register_ore({
80 ore_type = "blob",
81 ore = "mcl_core:dirt",
82 wherein = stonelike,
83 clust_scarcity = 15*15*15,
84 clust_num_ores = 33,
85 clust_size = 4,
86 y_min = mcl_vars.mg_overworld_min,
87 y_max = mcl_vars.mg_overworld_max,
90 -- Gravel
91 minetest.register_ore({
92 ore_type = "blob",
93 ore = "mcl_core:gravel",
94 wherein = stonelike,
95 clust_scarcity = 14*14*14,
96 clust_num_ores = 33,
97 clust_size = 5,
98 y_min = mcl_vars.mg_overworld_min,
99 y_max = mcl_util.layer_to_y(111),
103 -- Coal
106 -- Common spawn
107 minetest.register_ore({
108 ore_type = "scatter",
109 ore = "mcl_core:stone_with_coal",
110 wherein = stonelike,
111 clust_scarcity = 525*3,
112 clust_num_ores = 5,
113 clust_size = 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",
120 wherein = stonelike,
121 clust_scarcity = 510*3,
122 clust_num_ores = 8,
123 clust_size = 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",
130 wherein = stonelike,
131 clust_scarcity = 500*3,
132 clust_num_ores = 12,
133 clust_size = 3,
134 y_min = mcl_vars.mg_overworld_min,
135 y_max = mcl_util.layer_to_y(50),
138 -- Medium-rare spawn
139 minetest.register_ore({
140 ore_type = "scatter",
141 ore = "mcl_core:stone_with_coal",
142 wherein = stonelike,
143 clust_scarcity = 550*3,
144 clust_num_ores = 4,
145 clust_size = 2,
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",
152 wherein = stonelike,
153 clust_scarcity = 525*3,
154 clust_num_ores = 6,
155 clust_size = 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",
162 wherein = stonelike,
163 clust_scarcity = 500*3,
164 clust_num_ores = 8,
165 clust_size = 3,
166 y_min = mcl_util.layer_to_y(51),
167 y_max = mcl_util.layer_to_y(80),
170 -- Rare spawn
171 minetest.register_ore({
172 ore_type = "scatter",
173 ore = "mcl_core:stone_with_coal",
174 wherein = stonelike,
175 clust_scarcity = 600*3,
176 clust_num_ores = 3,
177 clust_size = 2,
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",
184 wherein = stonelike,
185 clust_scarcity = 550*3,
186 clust_num_ores = 4,
187 clust_size = 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",
194 wherein = stonelike,
195 clust_scarcity = 500*3,
196 clust_num_ores = 5,
197 clust_size = 3,
198 y_min = mcl_util.layer_to_y(81),
199 y_max = mcl_util.layer_to_y(128),
203 -- Iron
205 minetest.register_ore({
206 ore_type = "scatter",
207 ore = "mcl_core:stone_with_iron",
208 wherein = stonelike,
209 clust_scarcity = 830,
210 clust_num_ores = 5,
211 clust_size = 3,
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",
218 wherein = stonelike,
219 clust_scarcity = 1660,
220 clust_num_ores = 4,
221 clust_size = 2,
222 y_min = mcl_util.layer_to_y(40),
223 y_max = mcl_util.layer_to_y(63),
227 -- Gold
230 -- Common spawn
231 minetest.register_ore({
232 ore_type = "scatter",
233 ore = "mcl_core:stone_with_gold",
234 wherein = stonelike,
235 clust_scarcity = 4775,
236 clust_num_ores = 5,
237 clust_size = 3,
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",
244 wherein = stonelike,
245 clust_scarcity = 6560,
246 clust_num_ores = 7,
247 clust_size = 3,
248 y_min = mcl_vars.mg_overworld_min,
249 y_max = mcl_util.layer_to_y(30),
252 -- Rare spawn
253 minetest.register_ore({
254 ore_type = "scatter",
255 ore = "mcl_core:stone_with_gold",
256 wherein = stonelike,
257 clust_scarcity = 13000,
258 clust_num_ores = 4,
259 clust_size = 2,
260 y_min = mcl_util.layer_to_y(31),
261 y_max = mcl_util.layer_to_y(33),
268 -- Diamond
271 -- Common spawn
272 minetest.register_ore({
273 ore_type = "scatter",
274 ore = "mcl_core:stone_with_diamond",
275 wherein = stonelike,
276 clust_scarcity = 10000,
277 clust_num_ores = 4,
278 clust_size = 3,
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",
285 wherein = stonelike,
286 clust_scarcity = 5000,
287 clust_num_ores = 2,
288 clust_size = 2,
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",
295 wherein = stonelike,
296 clust_scarcity = 10000,
297 clust_num_ores = 8,
298 clust_size = 3,
299 y_min = mcl_vars.mg_overworld_min,
300 y_max = mcl_util.layer_to_y(12),
303 -- Rare spawn
304 minetest.register_ore({
305 ore_type = "scatter",
306 ore = "mcl_core:stone_with_diamond",
307 wherein = stonelike,
308 clust_scarcity = 20000,
309 clust_num_ores = 1,
310 clust_size = 1,
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",
317 wherein = stonelike,
318 clust_scarcity = 20000,
319 clust_num_ores = 2,
320 clust_size = 2,
321 y_min = mcl_util.layer_to_y(13),
322 y_max = mcl_util.layer_to_y(15),
326 -- Redstone
329 -- Common spawn
330 minetest.register_ore({
331 ore_type = "scatter",
332 ore = "mcl_core:stone_with_redstone",
333 wherein = stonelike,
334 clust_scarcity = 500,
335 clust_num_ores = 4,
336 clust_size = 3,
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",
343 wherein = stonelike,
344 clust_scarcity = 800,
345 clust_num_ores = 7,
346 clust_size = 4,
347 y_min = mcl_vars.mg_overworld_min,
348 y_max = mcl_util.layer_to_y(13),
351 -- Rare spawn
352 minetest.register_ore({
353 ore_type = "scatter",
354 ore = "mcl_core:stone_with_redstone",
355 wherein = stonelike,
356 clust_scarcity = 1000,
357 clust_num_ores = 4,
358 clust_size = 3,
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",
365 wherein = stonelike,
366 clust_scarcity = 1600,
367 clust_num_ores = 7,
368 clust_size = 4,
369 y_min = mcl_util.layer_to_y(13),
370 y_max = mcl_util.layer_to_y(15),
374 -- Emerald
377 -- Common spawn
378 minetest.register_ore({
379 ore_type = "scatter",
380 ore = "mcl_core:stone_with_emerald",
381 wherein = stonelike,
382 clust_scarcity = 14340,
383 clust_num_ores = 1,
384 clust_size = 1,
385 y_min = mcl_vars.mg_overworld_min,
386 y_max = mcl_util.layer_to_y(29),
388 -- Rare spawn
389 minetest.register_ore({
390 ore_type = "scatter",
391 ore = "mcl_core:stone_with_emerald",
392 wherein = stonelike,
393 clust_scarcity = 21510,
394 clust_num_ores = 1,
395 clust_size = 1,
396 y_min = mcl_util.layer_to_y(30),
397 y_max = mcl_util.layer_to_y(32),
401 -- Lapis Lazuli
404 -- Common spawn (in the center)
405 minetest.register_ore({
406 ore_type = "scatter",
407 ore = "mcl_core:stone_with_lapis",
408 wherein = stonelike,
409 clust_scarcity = 10000,
410 clust_num_ores = 7,
411 clust_size = 4,
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",
420 wherein = stonelike,
421 clust_scarcity = 12000,
422 clust_num_ores = 6,
423 clust_size = 3,
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",
430 wherein = stonelike,
431 clust_scarcity = 14000,
432 clust_num_ores = 5,
433 clust_size = 3,
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",
440 wherein = stonelike,
441 clust_scarcity = 16000,
442 clust_num_ores = 4,
443 clust_size = 3,
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",
450 wherein = stonelike,
451 clust_scarcity = 18000,
452 clust_num_ores = 3,
453 clust_size = 2,
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",
462 wherein = stonelike,
463 clust_scarcity = 12000,
464 clust_num_ores = 6,
465 clust_size = 3,
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",
472 wherein = stonelike,
473 clust_scarcity = 14000,
474 clust_num_ores = 5,
475 clust_size = 3,
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",
482 wherein = stonelike,
483 clust_scarcity = 16000,
484 clust_num_ores = 4,
485 clust_size = 3,
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",
492 wherein = stonelike,
493 clust_scarcity = 18000,
494 clust_num_ores = 3,
495 clust_size = 2,
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",
502 wherein = stonelike,
503 clust_scarcity = 32000,
504 clust_num_ores = 1,
505 clust_size = 1,
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,
519 clust_num_ores = 1,
520 clust_size = 1,
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",
529 wherein = stonelike,
530 clust_scarcity = 2000,
531 clust_num_ores = 1,
532 clust_size = 1,
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",
540 wherein = stonelike,
541 clust_scarcity = 9000,
542 clust_num_ores = 1,
543 clust_size = 1,
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",
552 wherein = stonelike,
553 clust_scarcity = 32000,
554 clust_num_ores = 1,
555 clust_size = 1,
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",
563 wherein = stonelike,
564 clust_scarcity = 72000,
565 clust_num_ores = 1,
566 clust_size = 1,
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",
575 wherein = stonelike,
576 clust_scarcity = 96000,
577 clust_num_ores = 1,
578 clust_size = 1,
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
589 else
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,
597 clust_num_ores = 3,
598 clust_size = 2,
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()
607 -- Cacti
608 minetest.register_decoration({
609 deco_type = "simple",
610 place_on = {"group:sand"},
611 sidelen = 16,
612 noise_params = {
613 offset = -0.012,
614 scale = 0.024,
615 spread = {x = 100, y = 100, z = 100},
616 seed = 257,
617 octaves = 3,
618 persist = 0.6
620 y_min = 4,
621 y_max = mcl_vars.mg_overworld_max,
622 decoration = "mcl_core:cactus",
623 height = 1,
624 height_max = 3,
627 -- Sugar canes
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"},
631 sidelen = 16,
632 noise_params = {
633 offset = 0.3,
634 scale = 0.7,
635 spread = {x = 100, y = 100, z = 100},
636 seed = 2,
637 octaves = 3,
638 persist = 0.7
640 y_min = 1,
641 y_max = mcl_vars.mg_overworld_max,
642 decoration = "mcl_core:reeds",
643 height = 1,
644 height_max = 3,
645 spawn_by = { "mcl_core:water_source", "group:frosted_ice" },
646 num_spawn_by = 1,
649 -- Doubletall grass
650 minetest.register_decoration({
651 deco_type = "schematic",
652 schematic = {
653 size = { x=1, y=3, z=1 },
654 data = {
655 { name = "air", prob = 0 },
656 { name = "mcl_flowers:double_grass", param1 = 255, },
657 { name = "mcl_flowers:double_grass_top", param1 = 255, },
660 replacements = {
661 ["mcl_flowers:tallgrass"] = "mcl_flowers:double_grass"
663 place_on = {"mcl_core:dirt_with_grass"},
664 sidelen = 16,
665 noise_params = {
666 offset = -0.01,
667 scale = 0.03,
668 spread = {x = 300, y = 300, z = 300},
669 seed = 420,
670 octaves = 2,
671 persist = 0.6,
673 y_min = 1,
674 y_max = mcl_vars.mg_overworld_max,
677 -- Large ferns
678 minetest.register_decoration({
679 deco_type = "schematic",
680 schematic = {
681 size = { x=1, y=3, z=1 },
682 data = {
683 { name = "air", prob = 0 },
684 { name = "mcl_flowers:double_fern", param1=255, },
685 { name = "mcl_flowers:double_fern_top", param1=255, },
688 replacements = {
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" },
693 num_spawn_by = 1,
694 place_on = {"mcl_core:podzol"},
696 sidelen = 16,
697 noise_params = {
698 offset = 0,
699 scale = 0.01,
700 spread = {x = 250, y = 250, z = 250},
701 seed = 333,
702 octaves = 2,
703 persist = 0.66,
705 y_min = 1,
706 y_max = mcl_vars.mg_overworld_max,
709 -- Large flowers
710 local register_large_flower = function(name, seed, offset)
711 minetest.register_decoration({
712 deco_type = "schematic",
713 schematic = {
714 size = { x=1, y=3, z=1 },
715 data = {
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"},
723 sidelen = 16,
724 noise_params = {
725 offset = offset,
726 scale = 0.01,
727 spread = {x = 300, y = 300, z = 300},
728 seed = seed,
729 octaves = 5,
730 persist = 0.62,
732 y_min = 1,
733 y_max = mcl_vars.overworld_max,
734 flags = "",
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)
743 -- Lily pad
744 minetest.register_decoration({
745 deco_type = "schematic",
746 schematic = {
747 size = { x=1, y=3, z=1 },
748 data = {
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",
755 sidelen = 16,
756 noise_params = {
757 offset = -0.12,
758 scale = 0.3,
759 spread = {x = 200, y = 200, z = 200},
760 seed = 503,
761 octaves = 6,
762 persist = 0.7,
764 y_min = 0,
765 y_max = 0,
766 rotation = "random",
769 -- Pumpkin
770 minetest.register_decoration({
771 deco_type = "schematic",
772 schematic = {
773 size = { x=1, y=2, z=1 },
774 data = {
775 { name = "air", prob = 0 },
776 { name = "mcl_farming:pumpkin_face" },
779 place_on = {"mcl_core:dirt_with_grass"},
780 sidelen = 16,
781 noise_params = {
782 offset = -0.008,
783 scale = 0.00666,
784 spread = {x = 250, y = 250, z = 250},
785 seed = 666,
786 octaves = 6,
787 persist = 0.666
789 y_min = 1,
790 y_max = mcl_vars.overworld_max,
791 rotation = "random",
794 -- Tall grass
795 minetest.register_decoration({
796 deco_type = "simple",
797 place_on = {"mcl_core:dirt_with_grass"},
798 sidelen = 8,
799 noise_params = {
800 offset = 0.01,
801 scale = 0.3,
802 spread = {x = 500, y = 500, z = 500},
803 seed = 420,
804 octaves = 2,
805 persist = 0.6
807 y_min = 1,
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"},
816 sidelen = 8,
817 fill_ratio = 0.001,
818 y_min = 1,
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"},
830 sidelen = 16,
831 noise_params = {
832 offset = 0.04,
833 scale = 0.04,
834 spread = {x = 100, y = 100, z = 100},
835 seed = mseeds[m],
836 octaves = 3,
837 persist = 0.6
839 y_min = 1,
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", },
843 num_spawn_by = 1,
847 -- Dead bushes
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"},
851 sidelen = 16,
852 noise_params = {
853 offset = 0,
854 scale = 0.035,
855 spread = {x = 100, y = 100, z = 100},
856 seed = 1972,
857 octaves = 3,
858 persist = 0.6
860 y_min = 4,
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
867 offset = 0
869 if y_max == 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"},
875 sidelen = 16,
876 noise_params = {
877 offset = offset,
878 scale = 0.006,
879 spread = {x = 100, y = 100, z = 100},
880 seed = seed,
881 octaves = 3,
882 persist = 0.6
884 y_min = 1,
885 y_max = y_max,
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)
922 else
923 -- If superflat mode is disabled, mapgen is way more liberal
924 minetest.set_mapgen_setting("mg_flags", "caves,nodungeons,nodecorations,light", true)
926 else
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
933 -- probability.
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
946 -- as X, Z.
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
953 return x, 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
979 -- Generate clay
980 -- Assume X and Z lengths are equal
981 local divlen = 4
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
1000 is_shallow = false
1002 if is_shallow 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
1022 local divlen = 5
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)
1034 for i=0, amount do
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
1042 ground_y = y
1043 break
1047 if ground_y 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
1071 -- Check surface
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
1080 -- Igloos
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
1083 -- Check surface
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
1094 -- Fossil
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")
1112 -- Witch hut
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
1124 -- shores of dirt.
1125 here_be_witches = true
1126 else
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}
1140 else
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})
1162 return prev_result
1163 else
1164 return false
1167 local offsets
1168 if r == "0" then
1169 offsets = {
1170 {x=1, y=0, z=1},
1171 {x=1, y=0, z=5},
1172 {x=6, y=0, z=1},
1173 {x=6, y=0, z=5},
1175 elseif r == "180" then
1176 offsets = {
1177 {x=2, y=0, z=1},
1178 {x=2, y=0, z=5},
1179 {x=7, y=0, z=1},
1180 {x=7, y=0, z=5},
1182 elseif r == "270" then
1183 offsets = {
1184 {x=1, y=0, z=1},
1185 {x=5, y=0, z=1},
1186 {x=1, y=0, z=6},
1187 {x=5, y=0, z=6},
1189 elseif r == "90" then
1190 offsets = {
1191 {x=1, y=0, z=2},
1192 {x=5, y=0, z=2},
1193 {x=1, y=0, z=7},
1194 {x=5, y=0, z=7},
1197 for o=1, #offsets do
1198 local ok = true
1199 for y=place.y-1, place.y-64, -1 do
1200 local tpos = vector.add(place, offsets[o])
1201 tpos.y = y
1202 ok = place_tree_if_free(tpos, ok)
1203 if not ok then
1204 break
1212 -- Ice spikes in v6
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)
1216 if spike < 3 then
1217 -- Check surface
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
1227 -- Check surface
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")
1246 end)
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)
1256 if maxp.y < 0 then
1257 return
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")
1268 if biomemap then
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
1287 break
1290 else
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
1302 pos = jungletree[n]
1303 treepos = table.copy(pos)
1305 if minetest.find_node_near(pos, 1, {"mcl_core:jungleleaves"}) then
1307 dir = math.random(1, 40)
1309 if dir == 1 then
1310 pos.z = pos.z + 1
1311 elseif dir == 2 then
1312 pos.z = pos.z - 1
1313 elseif dir == 3 then
1314 pos.x = pos.x + 1
1315 elseif dir == 4 then
1316 pos.x = pos.x -1
1319 local nn = minetest.get_node(pos).name
1321 if dir < 5
1322 and nn == "air"
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)
1339 local treething
1340 for i=1, 4 do
1341 if i==1 then
1342 treething = jungletree
1343 elseif i == 2 then
1344 treething = jungleleaves
1345 elseif i == 3 then
1346 treething = oaktree
1347 elseif i == 4 then
1348 treething = oakleaves
1351 for n = 1, #treething do
1352 pos = treething[n]
1354 treepos = table.copy(pos)
1356 local dirs = {
1357 {x=1,y=0,z=0},
1358 {x=-1,y=0,z=0},
1359 {x=0,y=0,z=1},
1360 {x=0,y=0,z=-1},
1363 for d = 1, #dirs do
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
1370 local newnode = {
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
1378 if i == 1 then
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)
1391 else
1392 break
1394 pos.y = pos.y + 1
1395 treepos.y = treepos.y + 1
1397 else
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)
1403 else
1404 break
1406 pos.y = pos.y - 1
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
1423 return
1426 local bpos
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"})
1435 else
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
1447 return
1450 -- TODO: Generate everything based on Perlin noise instead of PseudoRandom
1452 local bpos
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 }
1462 spawn_func(bpos)
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"})
1473 end)
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"})
1480 end)
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"})
1489 else
1490 minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_red"})
1493 end)
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"})
1501 end)
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
1535 local ymin, ymax
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
1542 -- check: optional.
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)
1556 if check then
1557 if type(check) == "function" and check({x=x,y=y,z=z}, data[p_pos]) then
1558 data[p_pos] = content_id
1559 lvm_used = true
1560 elseif check == data[p_pos] then
1561 data[p_pos] = content_id
1562 lvm_used = true
1564 else
1565 data[p_pos] = content_id
1566 lvm_used = true
1572 return lvm_used
1575 -- The Void
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)
1584 -- Bedrock
1585 local bedrock_check
1586 if mcl_vars.mg_bedrock_is_rough then
1587 bedrock_check = function(pos)
1588 local y = pos.y
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
1596 local top
1597 if diff == 0 or ndiff1 == 0 or ndiff2 == 4 then
1598 -- 50% bedrock chance
1599 top = 2
1600 elseif diff == 1 or ndiff1 == 1 or ndiff2 == 3 then
1601 -- 66.666...%
1602 top = 3
1603 elseif diff == 2 or ndiff1 == 2 or ndiff2 == 2 then
1604 -- 75%
1605 top = 4
1606 elseif diff == 3 or ndiff1 == 3 or ndiff2 == 1 then
1607 -- 90%
1608 top = 10
1609 elseif diff == 4 or ndiff1 == 4 or ndiff2 == 0 then
1610 -- 100%
1611 return true
1612 else
1613 -- Not in bedrock layer
1614 return false
1617 return math.random(1, top) <= top-1
1619 else
1620 bedrock_check = nil
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)
1627 -- Flat Nether
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
1645 -- v6 mapgen:
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)
1652 if p_pos then
1653 data[p_pos] = c_top_snow
1656 if #snowdirt > 1 then
1657 lvm_used = true
1661 -- Non-v6 mapgens:
1662 -- Clear snowy grass blocks without snow above to ensure consistency.
1663 -- Solidify floating sand to sandstone (both colors).
1664 else
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"})
1667 for n=1, #nodes do
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
1673 lvm_used = true
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
1677 lvm_used = true
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
1681 lvm_used = true
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
1691 local nodes
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"})
1694 else
1695 nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source"})
1697 for n=1, #nodes do
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
1701 lvm_used = true
1702 elseif data[p_pos] == c_stone then
1703 data[p_pos] = c_netherrack
1704 lvm_used = true
1705 elseif data[p_pos] == c_sand or data[p_pos] == c_dirt then
1706 data[p_pos] = c_soul_sand
1707 lvm_used = true
1711 -- End block fixes:
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"})
1717 else
1718 nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source"})
1720 for n=1, #nodes do
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
1727 lvm_used = true
1728 else
1729 data[p_pos] = c_air
1730 lvm_used = true
1732 elseif data[p_pos] == c_stone or data[p_pos] == c_dirt or data[p_pos] == c_sand then
1733 data[p_pos] = c_air
1734 lvm_used = true
1742 -- Final hackery: Set sun light level in the End.
1743 -- -26912 is at a mapchunk border.
1744 local shadow
1745 if minp.y >= -26912 and maxp.y <= mcl_vars.mg_end_max then
1746 vm:set_lighting({day=15, night=15})
1747 lvm_used = true
1749 if minp.y >= mcl_vars.mg_end_min and maxp.y <= -26911 then
1750 shadow = false
1751 lvm_used = true
1754 -- Write stuff
1755 if lvm_used then
1756 vm:set_data(data)
1757 vm:calc_lighting(nil, nil, shadow)
1758 vm:update_liquids()
1759 vm:write_to_map()
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)
1768 end)