Don't generate bedrock and lava in singlenode
[MineClone/MineClone2.git] / mods / MAPGEN / mcl_mapgen_core / init.lua
blob5343ab1e0bca5fa1307d754723e4e3a0bebae18b
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
46 -- Content IDs
47 local c_bedrock = minetest.get_content_id("mcl_core:bedrock")
48 local c_stone = minetest.get_content_id("mcl_core:stone")
49 local c_dirt = minetest.get_content_id("mcl_core:dirt")
50 local c_dirt_with_grass = minetest.get_content_id("mcl_core:dirt_with_grass")
51 local c_dirt_with_grass_snow = minetest.get_content_id("mcl_core:dirt_with_grass_snow")
52 local c_sand = minetest.get_content_id("mcl_core:sand")
53 local c_sandstone = minetest.get_content_id("mcl_core:sandstone")
54 local c_redsand = minetest.get_content_id("mcl_core:redsand")
55 local c_redsandstone = minetest.get_content_id("mcl_core:redsandstone")
56 local c_void = minetest.get_content_id("mcl_core:void")
57 local c_lava = minetest.get_content_id("mcl_core:lava_source")
58 local c_water = minetest.get_content_id("mcl_core:water_source")
59 local c_soul_sand = minetest.get_content_id("mcl_nether:soul_sand")
60 local c_netherrack = minetest.get_content_id("mcl_nether:netherrack")
61 local c_nether_lava = minetest.get_content_id("mcl_nether:nether_lava_source")
62 local c_end_stone = minetest.get_content_id("mcl_end:end_stone")
63 local c_realm_barrier = minetest.get_content_id("mcl_core:realm_barrier")
64 local c_top_snow = minetest.get_content_id("mcl_core:snow")
65 local c_snow_block = minetest.get_content_id("mcl_core:snowblock")
66 local c_clay = minetest.get_content_id("mcl_core:clay")
67 local c_leaves = minetest.get_content_id("mcl_core:leaves")
68 local c_jungleleaves = minetest.get_content_id("mcl_core:jungleleaves")
69 local c_jungletree = minetest.get_content_id("mcl_core:jungletree")
70 local c_cocoa_1 = minetest.get_content_id("mcl_cocoas:cocoa_1")
71 local c_cocoa_2 = minetest.get_content_id("mcl_cocoas:cocoa_2")
72 local c_cocoa_3 = minetest.get_content_id("mcl_cocoas:cocoa_3")
73 local c_vine = minetest.get_content_id("mcl_core:vine")
74 local c_air = minetest.CONTENT_AIR
77 -- Ore generation
80 -- Diorite, andesite and granite
81 local specialstones = { "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite" }
82 for s=1, #specialstones do
83 local node = specialstones[s]
84 minetest.register_ore({
85 ore_type = "blob",
86 ore = node,
87 wherein = {"mcl_core:stone"},
88 clust_scarcity = 15*15*15,
89 clust_num_ores = 33,
90 clust_size = 5,
91 y_min = mcl_vars.mg_overworld_min,
92 y_max = mcl_vars.mg_overworld_max,
94 minetest.register_ore({
95 ore_type = "blob",
96 ore = node,
97 wherein = {"mcl_core:stone"},
98 clust_scarcity = 10*10*10,
99 clust_num_ores = 58,
100 clust_size = 7,
101 y_min = mcl_vars.mg_overworld_min,
102 y_max = mcl_vars.mg_overworld_max,
106 local stonelike = {"mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite"}
108 -- Dirt
109 minetest.register_ore({
110 ore_type = "blob",
111 ore = "mcl_core:dirt",
112 wherein = stonelike,
113 clust_scarcity = 15*15*15,
114 clust_num_ores = 33,
115 clust_size = 4,
116 y_min = mcl_vars.mg_overworld_min,
117 y_max = mcl_vars.mg_overworld_max,
120 -- Gravel
121 minetest.register_ore({
122 ore_type = "blob",
123 ore = "mcl_core:gravel",
124 wherein = stonelike,
125 clust_scarcity = 14*14*14,
126 clust_num_ores = 33,
127 clust_size = 5,
128 y_min = mcl_vars.mg_overworld_min,
129 y_max = mcl_util.layer_to_y(111),
133 -- Coal
136 -- Common spawn
137 minetest.register_ore({
138 ore_type = "scatter",
139 ore = "mcl_core:stone_with_coal",
140 wherein = stonelike,
141 clust_scarcity = 525*3,
142 clust_num_ores = 5,
143 clust_size = 3,
144 y_min = mcl_vars.mg_overworld_min,
145 y_max = mcl_util.layer_to_y(50),
147 minetest.register_ore({
148 ore_type = "scatter",
149 ore = "mcl_core:stone_with_coal",
150 wherein = stonelike,
151 clust_scarcity = 510*3,
152 clust_num_ores = 8,
153 clust_size = 3,
154 y_min = mcl_vars.mg_overworld_min,
155 y_max = mcl_util.layer_to_y(50),
157 minetest.register_ore({
158 ore_type = "scatter",
159 ore = "mcl_core:stone_with_coal",
160 wherein = stonelike,
161 clust_scarcity = 500*3,
162 clust_num_ores = 12,
163 clust_size = 3,
164 y_min = mcl_vars.mg_overworld_min,
165 y_max = mcl_util.layer_to_y(50),
168 -- Medium-rare spawn
169 minetest.register_ore({
170 ore_type = "scatter",
171 ore = "mcl_core:stone_with_coal",
172 wherein = stonelike,
173 clust_scarcity = 550*3,
174 clust_num_ores = 4,
175 clust_size = 2,
176 y_min = mcl_util.layer_to_y(51),
177 y_max = mcl_util.layer_to_y(80),
179 minetest.register_ore({
180 ore_type = "scatter",
181 ore = "mcl_core:stone_with_coal",
182 wherein = stonelike,
183 clust_scarcity = 525*3,
184 clust_num_ores = 6,
185 clust_size = 3,
186 y_min = mcl_util.layer_to_y(51),
187 y_max = mcl_util.layer_to_y(80),
189 minetest.register_ore({
190 ore_type = "scatter",
191 ore = "mcl_core:stone_with_coal",
192 wherein = stonelike,
193 clust_scarcity = 500*3,
194 clust_num_ores = 8,
195 clust_size = 3,
196 y_min = mcl_util.layer_to_y(51),
197 y_max = mcl_util.layer_to_y(80),
200 -- Rare spawn
201 minetest.register_ore({
202 ore_type = "scatter",
203 ore = "mcl_core:stone_with_coal",
204 wherein = stonelike,
205 clust_scarcity = 600*3,
206 clust_num_ores = 3,
207 clust_size = 2,
208 y_min = mcl_util.layer_to_y(81),
209 y_max = mcl_util.layer_to_y(128),
211 minetest.register_ore({
212 ore_type = "scatter",
213 ore = "mcl_core:stone_with_coal",
214 wherein = stonelike,
215 clust_scarcity = 550*3,
216 clust_num_ores = 4,
217 clust_size = 3,
218 y_min = mcl_util.layer_to_y(81),
219 y_max = mcl_util.layer_to_y(128),
221 minetest.register_ore({
222 ore_type = "scatter",
223 ore = "mcl_core:stone_with_coal",
224 wherein = stonelike,
225 clust_scarcity = 500*3,
226 clust_num_ores = 5,
227 clust_size = 3,
228 y_min = mcl_util.layer_to_y(81),
229 y_max = mcl_util.layer_to_y(128),
233 -- Iron
235 minetest.register_ore({
236 ore_type = "scatter",
237 ore = "mcl_core:stone_with_iron",
238 wherein = stonelike,
239 clust_scarcity = 830,
240 clust_num_ores = 5,
241 clust_size = 3,
242 y_min = mcl_vars.mg_overworld_min,
243 y_max = mcl_util.layer_to_y(39),
245 minetest.register_ore({
246 ore_type = "scatter",
247 ore = "mcl_core:stone_with_iron",
248 wherein = stonelike,
249 clust_scarcity = 1660,
250 clust_num_ores = 4,
251 clust_size = 2,
252 y_min = mcl_util.layer_to_y(40),
253 y_max = mcl_util.layer_to_y(63),
257 -- Gold
260 -- Common spawn
261 minetest.register_ore({
262 ore_type = "scatter",
263 ore = "mcl_core:stone_with_gold",
264 wherein = stonelike,
265 clust_scarcity = 4775,
266 clust_num_ores = 5,
267 clust_size = 3,
268 y_min = mcl_vars.mg_overworld_min,
269 y_max = mcl_util.layer_to_y(30),
271 minetest.register_ore({
272 ore_type = "scatter",
273 ore = "mcl_core:stone_with_gold",
274 wherein = stonelike,
275 clust_scarcity = 6560,
276 clust_num_ores = 7,
277 clust_size = 3,
278 y_min = mcl_vars.mg_overworld_min,
279 y_max = mcl_util.layer_to_y(30),
282 -- Rare spawn
283 minetest.register_ore({
284 ore_type = "scatter",
285 ore = "mcl_core:stone_with_gold",
286 wherein = stonelike,
287 clust_scarcity = 13000,
288 clust_num_ores = 4,
289 clust_size = 2,
290 y_min = mcl_util.layer_to_y(31),
291 y_max = mcl_util.layer_to_y(33),
294 -- Bonus spawn in Mesa
295 if mg_name ~= "v6" then
296 minetest.register_ore({
297 ore_type = "scatter",
298 ore = "mcl_core:stone_with_gold",
299 wherein = stonelike,
300 clust_scarcity = 3333,
301 clust_num_ores = 5,
302 clust_size = 3,
303 y_min = mcl_util.layer_to_y(32),
304 y_max = mcl_util.layer_to_y(79),
305 biomes = { "Mesa", "Mesa_sandlevel", "Mesa_ocean", "Mesa_deep_ocean", "Mesa_underground" },
310 -- Diamond
313 -- Common spawn
314 minetest.register_ore({
315 ore_type = "scatter",
316 ore = "mcl_core:stone_with_diamond",
317 wherein = stonelike,
318 clust_scarcity = 10000,
319 clust_num_ores = 4,
320 clust_size = 3,
321 y_min = mcl_vars.mg_overworld_min,
322 y_max = mcl_util.layer_to_y(12),
324 minetest.register_ore({
325 ore_type = "scatter",
326 ore = "mcl_core:stone_with_diamond",
327 wherein = stonelike,
328 clust_scarcity = 5000,
329 clust_num_ores = 2,
330 clust_size = 2,
331 y_min = mcl_vars.mg_overworld_min,
332 y_max = mcl_util.layer_to_y(12),
334 minetest.register_ore({
335 ore_type = "scatter",
336 ore = "mcl_core:stone_with_diamond",
337 wherein = stonelike,
338 clust_scarcity = 10000,
339 clust_num_ores = 8,
340 clust_size = 3,
341 y_min = mcl_vars.mg_overworld_min,
342 y_max = mcl_util.layer_to_y(12),
345 -- Rare spawn
346 minetest.register_ore({
347 ore_type = "scatter",
348 ore = "mcl_core:stone_with_diamond",
349 wherein = stonelike,
350 clust_scarcity = 20000,
351 clust_num_ores = 1,
352 clust_size = 1,
353 y_min = mcl_util.layer_to_y(13),
354 y_max = mcl_util.layer_to_y(15),
356 minetest.register_ore({
357 ore_type = "scatter",
358 ore = "mcl_core:stone_with_diamond",
359 wherein = stonelike,
360 clust_scarcity = 20000,
361 clust_num_ores = 2,
362 clust_size = 2,
363 y_min = mcl_util.layer_to_y(13),
364 y_max = mcl_util.layer_to_y(15),
368 -- Redstone
371 -- Common spawn
372 minetest.register_ore({
373 ore_type = "scatter",
374 ore = "mcl_core:stone_with_redstone",
375 wherein = stonelike,
376 clust_scarcity = 500,
377 clust_num_ores = 4,
378 clust_size = 3,
379 y_min = mcl_vars.mg_overworld_min,
380 y_max = mcl_util.layer_to_y(13),
382 minetest.register_ore({
383 ore_type = "scatter",
384 ore = "mcl_core:stone_with_redstone",
385 wherein = stonelike,
386 clust_scarcity = 800,
387 clust_num_ores = 7,
388 clust_size = 4,
389 y_min = mcl_vars.mg_overworld_min,
390 y_max = mcl_util.layer_to_y(13),
393 -- Rare spawn
394 minetest.register_ore({
395 ore_type = "scatter",
396 ore = "mcl_core:stone_with_redstone",
397 wherein = stonelike,
398 clust_scarcity = 1000,
399 clust_num_ores = 4,
400 clust_size = 3,
401 y_min = mcl_util.layer_to_y(13),
402 y_max = mcl_util.layer_to_y(15),
404 minetest.register_ore({
405 ore_type = "scatter",
406 ore = "mcl_core:stone_with_redstone",
407 wherein = stonelike,
408 clust_scarcity = 1600,
409 clust_num_ores = 7,
410 clust_size = 4,
411 y_min = mcl_util.layer_to_y(13),
412 y_max = mcl_util.layer_to_y(15),
416 -- Emerald
419 if mg_name == "v6" then
420 -- Generate everywhere in v6, but rarely.
422 -- Common spawn
423 minetest.register_ore({
424 ore_type = "scatter",
425 ore = "mcl_core:stone_with_emerald",
426 wherein = stonelike,
427 clust_scarcity = 14340,
428 clust_num_ores = 1,
429 clust_size = 1,
430 y_min = mcl_vars.mg_overworld_min,
431 y_max = mcl_util.layer_to_y(29),
433 -- Rare spawn
434 minetest.register_ore({
435 ore_type = "scatter",
436 ore = "mcl_core:stone_with_emerald",
437 wherein = stonelike,
438 clust_scarcity = 21510,
439 clust_num_ores = 1,
440 clust_size = 1,
441 y_min = mcl_util.layer_to_y(30),
442 y_max = mcl_util.layer_to_y(32),
444 else
445 -- Generate in Extreme Hills biome only
447 minetest.register_ore({
448 ore_type = "scatter",
449 ore = "mcl_core:stone_with_emerald",
450 wherein = stonelike,
451 clust_scarcity = 16384,
452 clust_num_ores = 1,
453 clust_size = 1,
454 y_min = mcl_util.layer_to_y(4),
455 y_max = mcl_util.layer_to_y(32),
456 biomes = { "ExtremeHills", "ExtremeHills_beach", "ExtremeHills_ocean", "ExtremeHills_deep_ocean", "ExtremeHills_underground" },
461 -- Lapis Lazuli
464 -- Common spawn (in the center)
465 minetest.register_ore({
466 ore_type = "scatter",
467 ore = "mcl_core:stone_with_lapis",
468 wherein = stonelike,
469 clust_scarcity = 10000,
470 clust_num_ores = 7,
471 clust_size = 4,
472 y_min = mcl_util.layer_to_y(14),
473 y_max = mcl_util.layer_to_y(16),
476 -- Rare spawn (below center)
477 minetest.register_ore({
478 ore_type = "scatter",
479 ore = "mcl_core:stone_with_lapis",
480 wherein = stonelike,
481 clust_scarcity = 12000,
482 clust_num_ores = 6,
483 clust_size = 3,
484 y_min = mcl_util.layer_to_y(10),
485 y_max = mcl_util.layer_to_y(13),
487 minetest.register_ore({
488 ore_type = "scatter",
489 ore = "mcl_core:stone_with_lapis",
490 wherein = stonelike,
491 clust_scarcity = 14000,
492 clust_num_ores = 5,
493 clust_size = 3,
494 y_min = mcl_util.layer_to_y(6),
495 y_max = mcl_util.layer_to_y(9),
497 minetest.register_ore({
498 ore_type = "scatter",
499 ore = "mcl_core:stone_with_lapis",
500 wherein = stonelike,
501 clust_scarcity = 16000,
502 clust_num_ores = 4,
503 clust_size = 3,
504 y_min = mcl_util.layer_to_y(2),
505 y_max = mcl_util.layer_to_y(5),
507 minetest.register_ore({
508 ore_type = "scatter",
509 ore = "mcl_core:stone_with_lapis",
510 wherein = stonelike,
511 clust_scarcity = 18000,
512 clust_num_ores = 3,
513 clust_size = 2,
514 y_min = mcl_util.layer_to_y(0),
515 y_max = mcl_util.layer_to_y(2),
518 -- Rare spawn (above center)
519 minetest.register_ore({
520 ore_type = "scatter",
521 ore = "mcl_core:stone_with_lapis",
522 wherein = stonelike,
523 clust_scarcity = 12000,
524 clust_num_ores = 6,
525 clust_size = 3,
526 y_min = mcl_util.layer_to_y(17),
527 y_max = mcl_util.layer_to_y(20),
529 minetest.register_ore({
530 ore_type = "scatter",
531 ore = "mcl_core:stone_with_lapis",
532 wherein = stonelike,
533 clust_scarcity = 14000,
534 clust_num_ores = 5,
535 clust_size = 3,
536 y_min = mcl_util.layer_to_y(21),
537 y_max = mcl_util.layer_to_y(24),
539 minetest.register_ore({
540 ore_type = "scatter",
541 ore = "mcl_core:stone_with_lapis",
542 wherein = stonelike,
543 clust_scarcity = 16000,
544 clust_num_ores = 4,
545 clust_size = 3,
546 y_min = mcl_util.layer_to_y(25),
547 y_max = mcl_util.layer_to_y(28),
549 minetest.register_ore({
550 ore_type = "scatter",
551 ore = "mcl_core:stone_with_lapis",
552 wherein = stonelike,
553 clust_scarcity = 18000,
554 clust_num_ores = 3,
555 clust_size = 2,
556 y_min = mcl_util.layer_to_y(29),
557 y_max = mcl_util.layer_to_y(32),
559 minetest.register_ore({
560 ore_type = "scatter",
561 ore = "mcl_core:stone_with_lapis",
562 wherein = stonelike,
563 clust_scarcity = 32000,
564 clust_num_ores = 1,
565 clust_size = 1,
566 y_min = mcl_util.layer_to_y(31),
567 y_max = mcl_util.layer_to_y(32),
570 if mg_name ~= "flat" then
572 -- Water and lava springs (single blocks of lava/water source)
573 -- Water appears at nearly every height, but not near the bottom
574 minetest.register_ore({
575 ore_type = "scatter",
576 ore = "mcl_core:water_source",
577 wherein = {"mcl_core:stone", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite", "mcl_core:dirt"},
578 clust_scarcity = 9000,
579 clust_num_ores = 1,
580 clust_size = 1,
581 y_min = mcl_util.layer_to_y(5),
582 y_max = mcl_util.layer_to_y(128),
585 -- Lava springs are rather common at -31 and below
586 minetest.register_ore({
587 ore_type = "scatter",
588 ore = "mcl_core:lava_source",
589 wherein = stonelike,
590 clust_scarcity = 2000,
591 clust_num_ores = 1,
592 clust_size = 1,
593 y_min = mcl_util.layer_to_y(1),
594 y_max = mcl_util.layer_to_y(10),
597 minetest.register_ore({
598 ore_type = "scatter",
599 ore = "mcl_core:lava_source",
600 wherein = stonelike,
601 clust_scarcity = 9000,
602 clust_num_ores = 1,
603 clust_size = 1,
604 y_min = mcl_util.layer_to_y(11),
605 y_max = mcl_util.layer_to_y(31),
608 -- Lava springs will become gradually rarer with increasing height
609 minetest.register_ore({
610 ore_type = "scatter",
611 ore = "mcl_core:lava_source",
612 wherein = stonelike,
613 clust_scarcity = 32000,
614 clust_num_ores = 1,
615 clust_size = 1,
616 y_min = mcl_util.layer_to_y(32),
617 y_max = mcl_util.layer_to_y(47),
620 minetest.register_ore({
621 ore_type = "scatter",
622 ore = "mcl_core:lava_source",
623 wherein = stonelike,
624 clust_scarcity = 72000,
625 clust_num_ores = 1,
626 clust_size = 1,
627 y_min = mcl_util.layer_to_y(48),
628 y_max = mcl_util.layer_to_y(61),
631 -- Lava may even appear above surface, but this is very rare
632 minetest.register_ore({
633 ore_type = "scatter",
634 ore = "mcl_core:lava_source",
635 wherein = stonelike,
636 clust_scarcity = 96000,
637 clust_num_ores = 1,
638 clust_size = 1,
639 y_min = mcl_util.layer_to_y(62),
640 y_max = mcl_util.layer_to_y(127),
645 -- Rarely replace stone with stone monster eggs.
646 -- In v6 this can happen anywhere, in other mapgens only in Extreme Hills.
647 local monster_egg_scarcity
648 if mg_name == "v6" then
649 monster_egg_scarcity = 28 * 28 * 28
650 else
651 monster_egg_scarcity = 26 * 26 * 26
653 minetest.register_ore({
654 ore_type = "scatter",
655 ore = "mcl_monster_eggs:monster_egg_stone",
656 wherein = "mcl_core:stone",
657 clust_scarcity = monster_egg_scarcity,
658 clust_num_ores = 3,
659 clust_size = 2,
660 y_min = mcl_vars.mg_overworld_min,
661 y_max = mcl_util.layer_to_y(61),
662 biomes = { "ExtremeHills", "ExtremeHills_beach", "ExtremeHills_ocean", "ExtremeHills_deep_ocean", "ExtremeHills_underground" },
666 local function register_mgv6_decorations()
668 -- Cacti
669 minetest.register_decoration({
670 deco_type = "simple",
671 place_on = {"group:sand"},
672 sidelen = 16,
673 noise_params = {
674 offset = -0.012,
675 scale = 0.024,
676 spread = {x = 100, y = 100, z = 100},
677 seed = 257,
678 octaves = 3,
679 persist = 0.6
681 y_min = 4,
682 y_max = mcl_vars.mg_overworld_max,
683 decoration = "mcl_core:cactus",
684 height = 1,
685 height_max = 3,
688 -- Sugar canes
689 minetest.register_decoration({
690 deco_type = "simple",
691 place_on = {"mcl_core:dirt", "mcl_core:coarse_dirt", "mcl_core:dirt_with_grass", "group:sand", "mcl_core:podzol", "mcl_core:reeds"},
692 sidelen = 16,
693 noise_params = {
694 offset = -0.3,
695 scale = 0.7,
696 spread = {x = 100, y = 100, z = 100},
697 seed = 465,
698 octaves = 3,
699 persist = 0.7
701 y_min = 1,
702 y_max = mcl_vars.mg_overworld_max,
703 decoration = "mcl_core:reeds",
704 height = 1,
705 height_max = 3,
706 spawn_by = { "mcl_core:water_source", "group:frosted_ice" },
707 num_spawn_by = 1,
710 -- Doubletall grass
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:double_grass", param1 = 255, },
718 { name = "mcl_flowers:double_grass_top", param1 = 255, },
721 replacements = {
722 ["mcl_flowers:tallgrass"] = "mcl_flowers:double_grass"
724 place_on = {"mcl_core:dirt_with_grass"},
725 sidelen = 8,
726 noise_params = {
727 offset = -0.0025,
728 scale = 0.03,
729 spread = {x = 100, y = 100, z = 100},
730 seed = 420,
731 octaves = 3,
732 persist = 0.0,
734 y_min = 1,
735 y_max = mcl_vars.mg_overworld_max,
738 -- Large ferns
739 minetest.register_decoration({
740 deco_type = "schematic",
741 schematic = {
742 size = { x=1, y=3, z=1 },
743 data = {
744 { name = "air", prob = 0 },
745 { name = "mcl_flowers:double_fern", param1=255, },
746 { name = "mcl_flowers:double_fern_top", param1=255, },
749 replacements = {
750 ["mcl_flowers:fern"] = "mcl_flowers:double_fern"
752 -- v6 hack: This makes sure large ferns only appear in jungles
753 spawn_by = { "mcl_core:jungletree", "mcl_flowers:fern" },
754 num_spawn_by = 1,
755 place_on = {"mcl_core:dirt_with_grass"},
757 sidelen = 16,
758 noise_params = {
759 offset = 0,
760 scale = 0.01,
761 spread = {x = 250, y = 250, z = 250},
762 seed = 333,
763 octaves = 2,
764 persist = 0.66,
766 y_min = 1,
767 y_max = mcl_vars.mg_overworld_max,
770 -- Large flowers
771 local register_large_flower = function(name, seed, offset)
772 minetest.register_decoration({
773 deco_type = "schematic",
774 schematic = {
775 size = { x=1, y=3, z=1 },
776 data = {
777 { name = "air", prob = 0 },
778 { name = "mcl_flowers:"..name, param1=255, },
779 { name = "mcl_flowers:"..name.."_top", param1=255, },
782 place_on = {"mcl_core:dirt_with_grass"},
784 sidelen = 16,
785 noise_params = {
786 offset = offset,
787 scale = 0.01,
788 spread = {x = 300, y = 300, z = 300},
789 seed = seed,
790 octaves = 5,
791 persist = 0.62,
793 y_min = 1,
794 y_max = mcl_vars.overworld_max,
795 flags = "",
799 register_large_flower("rose_bush", 9350, -0.008)
800 register_large_flower("peony", 10450, -0.008)
801 register_large_flower("lilac", 10600, -0.007)
802 register_large_flower("sunflower", 2940, -0.005)
804 -- Lily pad
805 minetest.register_decoration({
806 deco_type = "schematic",
807 schematic = {
808 size = { x=1, y=3, z=1 },
809 data = {
810 { name = "mcl_core:water_source", prob = 0 },
811 { name = "mcl_core:water_source" },
812 { name = "mcl_flowers:waterlily", param1 = 255 },
815 place_on = "mcl_core:dirt",
816 sidelen = 16,
817 noise_params = {
818 offset = -0.12,
819 scale = 0.3,
820 spread = {x = 200, y = 200, z = 200},
821 seed = 503,
822 octaves = 6,
823 persist = 0.7,
825 y_min = 0,
826 y_max = 0,
827 rotation = "random",
830 -- Pumpkin
831 minetest.register_decoration({
832 deco_type = "schematic",
833 schematic = {
834 size = { x=1, y=2, z=1 },
835 data = {
836 { name = "air", prob = 0 },
837 { name = "mcl_farming:pumpkin_face" },
840 place_on = {"mcl_core:dirt_with_grass"},
841 sidelen = 16,
842 noise_params = {
843 offset = -0.008,
844 scale = 0.00666,
845 spread = {x = 250, y = 250, z = 250},
846 seed = 666,
847 octaves = 6,
848 persist = 0.666
850 y_min = 1,
851 y_max = mcl_vars.overworld_max,
852 rotation = "random",
855 -- Tall grass
856 minetest.register_decoration({
857 deco_type = "simple",
858 place_on = {"mcl_core:dirt_with_grass"},
859 sidelen = 8,
860 noise_params = {
861 offset = 0.01,
862 scale = 0.3,
863 spread = {x = 100, y = 100, z = 100},
864 seed = 420,
865 octaves = 3,
866 persist = 0.6
868 y_min = 1,
869 y_max = mcl_vars.overworld_max,
870 decoration = "mcl_flowers:tallgrass",
872 minetest.register_decoration({
873 deco_type = "simple",
874 place_on = {"mcl_core:dirt_with_grass"},
875 sidelen = 8,
876 noise_params = {
877 offset = 0.04,
878 scale = 0.03,
879 spread = {x = 100, y = 100, z = 100},
880 seed = 420,
881 octaves = 3,
882 persist = 0.6
884 y_min = 1,
885 y_max = mcl_vars.overworld_max,
886 decoration = "mcl_flowers:tallgrass",
888 -- Add a small amount of tall grass everywhere to avoid areas completely empty devoid of tall grass
889 minetest.register_decoration({
890 deco_type = "simple",
891 place_on = {"mcl_core:dirt_with_grass"},
892 sidelen = 8,
893 fill_ratio = 0.004,
894 y_min = 1,
895 y_max = mcl_vars.overworld_max,
896 decoration = "mcl_flowers:tallgrass",
899 local mushrooms = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown"}
900 local mseeds = { 7133, 8244 }
901 for m=1, #mushrooms do
902 -- Mushrooms next to trees
903 minetest.register_decoration({
904 deco_type = "simple",
905 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"},
906 sidelen = 16,
907 noise_params = {
908 offset = 0.04,
909 scale = 0.04,
910 spread = {x = 100, y = 100, z = 100},
911 seed = mseeds[m],
912 octaves = 3,
913 persist = 0.6
915 y_min = 1,
916 y_max = mcl_vars.mg_overworld_max,
917 decoration = mushrooms[m],
918 spawn_by = { "mcl_core:tree", "mcl_core:sprucetree", "mcl_core:darktree", "mcl_core:birchtree", },
919 num_spawn_by = 1,
923 -- Dead bushes
924 minetest.register_decoration({
925 deco_type = "simple",
926 place_on = {"group:sand", "mcl_core:podzol", "mcl_core:dirt", "mcl_core:coarse_dirt", "group:hardened_clay"},
927 sidelen = 16,
928 noise_params = {
929 offset = 0,
930 scale = 0.035,
931 spread = {x = 100, y = 100, z = 100},
932 seed = 1972,
933 octaves = 3,
934 persist = 0.6
936 y_min = 4,
937 y_max = mcl_vars.mg_overworld_max,
938 decoration = "mcl_core:deadbush",
941 local function register_mgv6_flower(name, seed, offset, y_max)
942 if offset == nil then
943 offset = 0
945 if y_max == nil then
946 y_max = mcl_vars.mg_overworld_max
948 minetest.register_decoration({
949 deco_type = "simple",
950 place_on = {"mcl_core:dirt_with_grass"},
951 sidelen = 16,
952 noise_params = {
953 offset = offset,
954 scale = 0.006,
955 spread = {x = 100, y = 100, z = 100},
956 seed = seed,
957 octaves = 3,
958 persist = 0.6
960 y_min = 1,
961 y_max = y_max,
962 decoration = "mcl_flowers:"..name,
966 register_mgv6_flower("tulip_red", 436)
967 register_mgv6_flower("tulip_orange", 536)
968 register_mgv6_flower("tulip_pink", 636)
969 register_mgv6_flower("tulip_white", 736)
970 register_mgv6_flower("azure_bluet", 800)
971 register_mgv6_flower("dandelion", 8)
972 -- Allium is supposed to only appear in flower forest in MC. There are no flower forests in v6.
973 -- We compensate by making it slightly rarer in v6.
974 register_mgv6_flower("allium", 0, -0.001)
975 --[[ Blue orchid is supposed to appear in swamplands. There are no swamplands in v6.
976 We emulate swamplands by limiting the height to 5 levels above sea level,
977 which should be close to the water. ]]
978 register_mgv6_flower("blue_orchid", 64500, nil, mcl_util.layer_to_y(67))
979 register_mgv6_flower("oxeye_daisy", 3490)
980 register_mgv6_flower("poppy", 9439)
984 -- Apply mapgen-specific mapgen code
985 if mg_name == "v6" then
986 register_mgv6_decorations()
987 minetest.set_mapgen_setting("mg_flags", "caves,nodungeons,decorations,light", true)
988 elseif mg_name == "flat" then
989 local classic = minetest.get_mapgen_setting("mcl_superflat_classic")
990 if classic == nil then
991 classic = minetest.settings:get_bool("mcl_superflat_classic")
992 minetest.set_mapgen_setting("mcl_superflat_classic", "true", true)
994 if classic ~= "false" then
995 -- Enforce superflat-like mapgen: No hills, lakes or caves
996 minetest.set_mapgen_setting("mg_flags", "nocaves,nodungeons,nodecorations,light", true)
997 minetest.set_mapgen_setting("mgflat_spflags", "nolakes,nohills", true)
998 else
999 -- If superflat mode is disabled, mapgen is way more liberal
1000 minetest.set_mapgen_setting("mg_flags", "caves,nodungeons,nodecorations,light", true)
1002 else
1003 minetest.set_mapgen_setting("mg_flags", "caves,nodungeons,decorations,light", true)
1006 -- Helper function for converting a MC probability to MT, with
1007 -- regards to MapBlocks.
1008 -- Some MC generated structures are generated on per-chunk
1009 -- probability.
1010 -- The MC probability is 1/x per Minecraft chunk (16×16).
1012 -- x: The MC probability is 1/x.
1013 -- minp, maxp: MapBlock limits
1014 -- returns: Probability (1/return_value) for a single MT mapblock
1015 local function minecraft_chunk_probability(x, minp, maxp)
1016 -- 256 is the MC chunk height
1017 return x * (((maxp.x-minp.x+1)*(maxp.z-minp.z+1)) / 256)
1020 -- Takes an index of a biomemap table (from minetest.get_mapgen_object),
1021 -- minp and maxp (from an on_generated callback) and returns the real world coordinates
1022 -- as X, Z.
1023 -- Inverse function of xz_to_biomemap
1024 local biomemap_to_xz = function(index, minp, maxp)
1025 local xwidth = maxp.x - minp.x + 1
1026 local zwidth = maxp.z - minp.z + 1
1027 local x = ((index-1) % xwidth) + minp.x
1028 local z = ((index-1) / zwidth) + minp.z
1029 return x, z
1032 -- Takes x and z coordinates and minp and maxp of a generated chunk
1033 -- (in on_generated callback) and returns a biomemap index)
1034 -- Inverse function of biomemap_to_xz
1035 local xz_to_biomemap_index = function(x, z, minp, maxp)
1036 local xwidth = maxp.x - minp.x + 1
1037 local zwidth = maxp.z - minp.z + 1
1038 local minix = x % xwidth
1039 local miniz = z % zwidth
1041 return (minix + miniz * zwidth) + 1
1044 -- Perlin noise objects
1045 local perlin_structures
1046 local perlin_vines, perlin_vines_fine, perlin_vines_upwards, perlin_vines_length, perlin_vines_density
1047 local perlin_clay
1049 local function generate_clay(minp, maxp, seed, voxelmanip_data, voxelmanip_area, lvm_used)
1050 -- TODO: Make clay generation reproducible for same seed.
1051 if maxp.y < -5 or minp.y > 0 then
1052 return lvm_used
1055 perlin_clay = perlin_clay or minetest.get_perlin({
1056 offset = 0.5,
1057 scale = 0.2,
1058 spread = {x = 5, y = 5, z = 5},
1059 seed = -316,
1060 octaves = 1,
1061 persist = 0.0
1064 for y=math.max(minp.y, 0), math.min(maxp.y, -8), -1 do
1065 -- Assume X and Z lengths are equal
1066 local divlen = 4
1067 local divs = (maxp.x-minp.x)/divlen+1;
1068 for divx=0+1,divs-2 do
1069 for divz=0+1,divs-2 do
1070 -- Get position and shift it a bit randomly so the clay do not obviously appear in a grid
1071 local cx = minp.x + math.floor((divx+0.5)*divlen) + math.random(-1,1)
1072 local cz = minp.z + math.floor((divz+0.5)*divlen) + math.random(-1,1)
1074 local water_pos = voxelmanip_area:index(cx, y+1, cz)
1075 local waternode = voxelmanip_data[water_pos]
1076 local surface_pos = voxelmanip_area:index(cx, y, cz)
1077 local surfacenode = voxelmanip_data[surface_pos]
1079 local genrnd = math.random(1, 20)
1080 if genrnd == 1 and perlin_clay:get3d({x=cx,y=y,z=cz}) > 0 and waternode == c_water and
1081 (surfacenode == c_dirt or minetest.get_item_group(minetest.get_name_from_content_id(surfacenode), "sand") == 1) then
1082 local diamondsize = math.random(1, 3)
1083 for x1 = -diamondsize, diamondsize do
1084 for z1 = -(diamondsize - math.abs(x1)), diamondsize - math.abs(x1) do
1085 local ccpos = voxelmanip_area:index(cx+x1, y, cz+z1)
1086 local claycandidate = voxelmanip_data[ccpos]
1087 if voxelmanip_data[ccpos] == c_dirt or minetest.get_item_group(minetest.get_name_from_content_id(claycandidate), "sand") == 1 then
1088 voxelmanip_data[ccpos] = c_clay
1089 lvm_used = true
1097 return lvm_used
1100 -- TODO: Try to use more efficient structure generating code
1101 local function generate_structures(minp, maxp, seed, biomemap)
1102 local chunk_has_desert_well = false
1103 local chunk_has_desert_temple = false
1104 local chunk_has_igloo = false
1105 local struct_min, struct_max = -3, 64
1106 if maxp.y >= struct_min and minp.y <= struct_max then
1107 -- Generate structures
1109 perlin_structures = perlin_structures or minetest.get_perlin(329, 3, 0.6, 100)
1110 -- Assume X and Z lengths are equal
1111 local divlen = 5
1112 local divs = (maxp.x-minp.x)/divlen+1;
1113 for divx=0,divs-1 do
1114 for divz=0,divs-1 do
1115 local x0 = minp.x + math.floor((divx+0)*divlen)
1116 local z0 = minp.z + math.floor((divz+0)*divlen)
1117 local x1 = minp.x + math.floor((divx+1)*divlen)
1118 local z1 = minp.z + math.floor((divz+1)*divlen)
1119 -- Determine amount from perlin noise
1120 local amount = math.floor(perlin_structures:get2d({x=x0, y=z0}) * 9)
1121 -- Find random positions based on this random
1122 local pr = PseudoRandom(seed+1)
1123 for i=0, amount do
1124 local x = pr:next(x0, x1)
1125 local z = pr:next(z0, z1)
1126 -- Find ground level
1127 local ground_y = nil
1128 for y = struct_max, struct_min, -1 do
1129 local checknode = minetest.get_node({x=x,y=y,z=z}).name
1130 if minetest.registered_nodes[checknode].walkable then
1131 ground_y = y
1132 break
1136 if ground_y then
1137 local p = {x=x,y=ground_y+1,z=z}
1138 local nn = minetest.get_node(p).name
1139 -- Check if the node can be replaced
1140 if minetest.registered_nodes[nn] and
1141 minetest.registered_nodes[nn].buildable_to then
1142 nn = minetest.get_node({x=x,y=ground_y,z=z}).name
1143 local struct = false
1145 -- Desert temples and desert wells
1146 if nn == "mcl_core:sand" or (nn == "mcl_core:sandstone") then
1147 if not chunk_has_desert_temple and not chunk_has_desert_well and ground_y > 3 then
1148 -- Spawn desert temple
1149 -- TODO: Check surface
1150 if math.random(1,12000) == 1 then
1151 mcl_structures.call_struct(p, "desert_temple")
1152 chunk_has_desert_temple = true
1155 if not chunk_has_desert_temple and not chunk_has_desert_well and ground_y > 3 then
1156 local desert_well_prob = minecraft_chunk_probability(1000, minp, maxp)
1158 -- Spawn desert well
1159 if math.random(1, desert_well_prob) == 1 then
1160 -- Check surface
1161 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")
1162 if #surface >= 25 then
1163 mcl_structures.call_struct(p, "desert_well")
1164 chunk_has_desert_well = true
1169 -- Igloos
1170 elseif not chunk_has_igloo and (nn == "mcl_core:snowblock" or nn == "mcl_core:snow" or nn == "mcl_core:dirt_with_grass_snow") then
1171 if math.random(1, 4400) == 1 then
1172 -- Check surface
1173 local floor = {x=p.x+9, y=p.y-1, z=p.z+9}
1174 local surface = minetest.find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, floor, "mcl_core:snowblock")
1175 local surface2 = minetest.find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, floor, "mcl_core:dirt_with_grass_snow")
1176 if #surface + #surface2 >= 63 then
1177 mcl_structures.call_struct(p, "igloo")
1178 chunk_has_igloo = true
1183 -- Fossil
1184 if nn == "mcl_core:sandstone" or nn == "mcl_core:sand" and not chunk_has_desert_temple and ground_y > 3 then
1185 local fossil_prob = minecraft_chunk_probability(64, minp, maxp)
1187 if math.random(1, fossil_prob) == 1 then
1188 -- Spawn fossil below desert surface between layers 40 and 49
1189 local p1 = {x=p.x, y=math.random(mcl_util.layer_to_y(40), mcl_util.layer_to_y(49)), z=p.z}
1190 -- Very rough check of the environment (we expect to have enough stonelike nodes).
1191 -- Fossils may still appear partially exposed in caves, but this is O.K.
1192 local p2 = vector.add(p1, 4)
1193 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"})
1195 if #nodes >= 100 then -- >= 80%
1196 mcl_structures.call_struct(p1, "fossil")
1201 -- Witch hut
1202 if ground_y <= 0 and nn == "mcl_core:dirt" then
1203 local prob = minecraft_chunk_probability(48, minp, maxp)
1205 local swampland = minetest.get_biome_id("Swampland")
1206 local swampland_shore = minetest.get_biome_id("Swampland_shore")
1208 -- Where do witches live?
1210 local here_be_witches = false
1211 if mg_name == "v6" then
1212 -- In ye good ol' landes of v6, witches will settle at any
1213 -- shores of dirt.
1214 here_be_witches = true
1215 else
1216 -- The townsfolk told me that witches live in the swamplands!
1217 local bi = xz_to_biomemap_index(p.x, p.z, minp, maxp)
1218 if biomemap[bi] == swampland or biomemap[bi] == swampland_shore then
1219 here_be_witches = true
1223 -- We still need a bit of luck!
1224 if here_be_witches and math.random(1, prob) == 1 then
1225 local r = tostring(math.random(0, 3) * 90) -- "0", "90", "180" or 270"
1226 local p1 = {x=p.x-1, y=WITCH_HUT_HEIGHT+2, z=p.z-1}
1227 local size
1228 if r == "0" or r == "180" then
1229 size = {x=10, y=4, z=8}
1230 else
1231 size = {x=8, y=4, z=10}
1233 local p2 = vector.add(p1, size)
1235 -- This checks free space at the “body” of the hut and a bit around.
1236 -- ALL nodes must be free for the placement to succeed.
1237 local free_nodes = minetest.find_nodes_in_area(p1, p2, {"air", "mcl_core:water_source", "mcl_flowers:waterlily"})
1238 if #free_nodes >= ((size.x+1)*(size.y+1)*(size.z+1)) then
1239 local place = {x=p.x, y=WITCH_HUT_HEIGHT-1, z=p.z}
1241 -- FIXME: For some mysterious reason (black magic?) this
1242 -- function does sometimes NOT spawn the witch hut. One can only see the
1243 -- oak wood nodes in the water, but no hut. :-/
1244 mcl_structures.call_struct(place, "witch_hut", r)
1246 -- TODO: Spawn witch in or around hut when the mob sucks less.
1248 local place_tree_if_free = function(pos, prev_result)
1249 local nn = minetest.get_node(pos).name
1250 if nn == "mcl_flowers:waterlily" or nn == "mcl_core:water_source" or nn == "mcl_core:water_flowing" or nn == "air" then
1251 minetest.set_node(pos, {name="mcl_core:tree", param2=0})
1252 return prev_result
1253 else
1254 return false
1257 local offsets
1258 if r == "0" then
1259 offsets = {
1260 {x=1, y=0, z=1},
1261 {x=1, y=0, z=5},
1262 {x=6, y=0, z=1},
1263 {x=6, y=0, z=5},
1265 elseif r == "180" then
1266 offsets = {
1267 {x=2, y=0, z=1},
1268 {x=2, y=0, z=5},
1269 {x=7, y=0, z=1},
1270 {x=7, y=0, z=5},
1272 elseif r == "270" then
1273 offsets = {
1274 {x=1, y=0, z=1},
1275 {x=5, y=0, z=1},
1276 {x=1, y=0, z=6},
1277 {x=5, y=0, z=6},
1279 elseif r == "90" then
1280 offsets = {
1281 {x=1, y=0, z=2},
1282 {x=5, y=0, z=2},
1283 {x=1, y=0, z=7},
1284 {x=5, y=0, z=7},
1287 for o=1, #offsets do
1288 local ok = true
1289 for y=place.y-1, place.y-64, -1 do
1290 local tpos = vector.add(place, offsets[o])
1291 tpos.y = y
1292 ok = place_tree_if_free(tpos, ok)
1293 if not ok then
1294 break
1302 -- Ice spikes in v6
1303 -- In other mapgens, ice spikes are generated as decorations.
1304 if mg_name == "v6" and not chunk_has_igloo and nn == "mcl_core:snowblock" then
1305 local spike = math.random(1, 3000)
1306 if spike < 3 then
1307 -- Check surface
1308 local floor = {x=p.x+4, y=p.y-1, z=p.z+4}
1309 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"})
1310 -- Check for collision with spruce
1311 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"})
1313 if #surface >= 9 and #spruce_collisions == 0 then
1314 mcl_structures.call_struct(p, "ice_spike_large")
1316 elseif spike < 100 then
1317 -- Check surface
1318 local floor = {x=p.x+6, y=p.y-1, z=p.z+6}
1319 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"})
1321 -- Check for collision with spruce
1322 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"})
1324 if #surface >= 25 and #spruce_collisions == 0 then
1325 mcl_structures.call_struct(p, "ice_spike_small")
1338 -- Buffers for LuaVoxelManip
1339 local lvm_buffer = {}
1340 local lvm_buffer_param2 = {}
1342 -- Generate tree decorations in the bounding box. This adds:
1343 -- * Cocoa at jungle trees
1344 -- * Jungle tree vines
1345 -- * Oak vines in swamplands
1346 local function generate_tree_decorations(minp, maxp, seed, data, param2_data, area, biomemap, lvm_used)
1347 if maxp.y < 0 then
1348 return lvm_used
1351 local oaktree, oakleaves, jungletree, jungleleaves = {}, {}, {}, {}
1352 local swampland = minetest.get_biome_id("Swampland")
1353 local swampland_shore = minetest.get_biome_id("Swampland_shore")
1354 local jungle = minetest.get_biome_id("Jungle")
1355 local jungle_shore = minetest.get_biome_id("Jungle_shore")
1356 local jungle_m = minetest.get_biome_id("JungleM")
1357 local jungle_m_shore = minetest.get_biome_id("JungleM_shore")
1358 local jungle_edge = minetest.get_biome_id("JungleEdge")
1359 local jungle_edge_shore = minetest.get_biome_id("JungleEdge_shore")
1360 local jungle_edge_m = minetest.get_biome_id("JungleEdgeM")
1361 local jungle_edge_m_shore = minetest.get_biome_id("JungleEdgeM_shore")
1363 -- Modifier for Jungle M biome: More vines and cocoas
1364 local dense_vegetation = false
1366 if biomemap then
1367 -- Biome map available: Check if the required biome (jungle or swampland)
1368 -- is in this mapchunk. We are only interested in trees in the correct biome.
1369 -- The nodes are added if the correct biome is *anywhere* in the mapchunk.
1370 -- TODO: Strictly generate vines in the correct biomes only.
1371 local swamp_biome_found, jungle_biome_found = false, false
1372 for b=1, #biomemap do
1373 local id = biomemap[b]
1375 if not swamp_biome_found and (id == swampland or id == swampland_shore) then
1376 oaktree = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:tree"})
1377 oakleaves = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:leaves"})
1378 swamp_biome_found = true
1380 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
1381 jungletree = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungletree"})
1382 jungleleaves = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungleleaves"})
1383 jungle_biome_found = true
1385 if not dense_vegetation and (id == jungle_m or id == jungle_m_shore) then
1386 dense_vegetation = true
1388 if swamp_biome_found and jungle_biome_found and dense_vegetation then
1389 break
1392 else
1393 -- If there is no biome map, we just count all jungle things we can find.
1394 -- Oak vines will not be generated.
1395 jungletree = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungletree"})
1396 jungleleaves = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungleleaves"})
1399 local pos, treepos, dir
1401 local cocoachance = 40
1402 if dense_vegetation then
1403 cocoachance = 32
1406 -- Pass 1: Generate cocoas at jungle trees
1407 for n = 1, #jungletree do
1409 pos = jungletree[n]
1410 treepos = table.copy(pos)
1412 if minetest.find_node_near(pos, 1, {"mcl_core:jungleleaves"}) then
1414 dir = math.random(1, cocoachance)
1416 if dir == 1 then
1417 pos.z = pos.z + 1
1418 elseif dir == 2 then
1419 pos.z = pos.z - 1
1420 elseif dir == 3 then
1421 pos.x = pos.x + 1
1422 elseif dir == 4 then
1423 pos.x = pos.x -1
1426 local p_pos = area:index(pos.x, pos.y, pos.z)
1428 if dir < 5
1429 and data[p_pos] == c_air
1430 and minetest.get_node_light(pos) > 12 then
1431 local c = math.random(1, 3)
1432 if c == 1 then
1433 data[p_pos] = c_cocoa_1
1434 elseif c == 2 then
1435 data[p_pos] = c_cocoa_2
1436 else
1437 data[p_pos] = c_cocoa_3
1439 param2_data[p_pos] = minetest.dir_to_facedir(vector.subtract(treepos, pos))
1440 lvm_used = true
1446 -- Pass 2: Generate vines at jungle wood, jungle leaves in jungle and oak wood, oak leaves in swampland
1447 perlin_vines = perlin_vines or minetest.get_perlin(555, 4, 0.6, 500)
1448 perlin_vines_fine = perlin_vines_fine or minetest.get_perlin(43000, 3, 0.6, 1)
1449 perlin_vines_length = perlin_vines_length or minetest.get_perlin(435, 4, 0.6, 75)
1450 perlin_vines_upwards = perlin_vines_upwards or minetest.get_perlin(436, 3, 0.6, 10)
1451 perlin_vines_density = perlin_vines_density or minetest.get_perlin(436, 3, 0.6, 500)
1453 -- Extra long vines in Jungle M
1454 local maxvinelength = 7
1455 if dense_vegetation then
1456 maxvinelength = 14
1458 local treething
1459 for i=1, 4 do
1460 if i==1 then
1461 treething = jungletree
1462 elseif i == 2 then
1463 treething = jungleleaves
1464 elseif i == 3 then
1465 treething = oaktree
1466 elseif i == 4 then
1467 treething = oakleaves
1470 for n = 1, #treething do
1471 pos = treething[n]
1473 treepos = table.copy(pos)
1475 local dirs = {
1476 {x=1,y=0,z=0},
1477 {x=-1,y=0,z=0},
1478 {x=0,y=0,z=1},
1479 {x=0,y=0,z=-1},
1482 for d = 1, #dirs do
1483 local pos = vector.add(pos, dirs[d])
1484 local p_pos = area:index(pos.x, pos.y, pos.z)
1486 local vine_threshold = math.max(0.33333, perlin_vines_density:get2d(pos))
1487 if dense_vegetation then
1488 vine_threshold = vine_threshold * (2/3)
1491 if perlin_vines:get2d(pos) > -1.0 and perlin_vines_fine:get3d(pos) > vine_threshold and data[p_pos] == c_air then
1493 local param2 = minetest.dir_to_wallmounted(vector.subtract(treepos, pos))
1495 -- Determine growth direction
1496 local grow_upwards = false
1497 -- Only possible on the wood, not on the leaves
1498 if i == 1 then
1499 grow_upwards = perlin_vines_upwards:get3d(pos) > 0.8
1501 if grow_upwards then
1502 -- Grow vines up 1-4 nodes, even through jungleleaves.
1503 -- This may give climbing access all the way to the top of the tree :-)
1504 -- But this will be fairly rare.
1505 local length = math.ceil(math.abs(perlin_vines_length:get3d(pos)) * 4)
1506 for l=0, length-1 do
1507 local t_pos = area:index(treepos.x, treepos.y, treepos.z)
1509 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
1510 data[p_pos] = c_vine
1511 param2_data[p_pos] = param2
1512 lvm_used = true
1514 else
1515 break
1517 pos.y = pos.y + 1
1518 p_pos = area:index(pos.x, pos.y, pos.z)
1519 treepos.y = treepos.y + 1
1521 else
1522 -- Grow vines down, length between 1 and maxvinelength
1523 local length = math.ceil(math.abs(perlin_vines_length:get3d(pos)) * maxvinelength)
1524 for l=0, length-1 do
1525 if data[p_pos] == c_air then
1526 data[p_pos] = c_vine
1527 param2_data[p_pos] = param2
1528 lvm_used = true
1530 else
1531 break
1533 pos.y = pos.y - 1
1534 p_pos = area:index(pos.x, pos.y, pos.z)
1542 return lvm_used
1545 local pr_shroom = PseudoRandom(os.time()-24359)
1546 -- Generate mushrooms in caves manually.
1547 -- Minetest's API does not support decorations in caves yet. :-(
1548 local generate_underground_mushrooms = function(minp, maxp, seed)
1549 -- Generate rare underground mushrooms
1550 -- TODO: Make them appear in groups, use Perlin noise
1551 local min, max = mcl_vars.mg_lava_overworld_max + 4, 0
1552 if minp.y > max or maxp.y < min then
1553 return
1556 local bpos
1557 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"})
1559 for n = 1, #stone do
1560 bpos = {x = stone[n].x, y = stone[n].y + 1, z = stone[n].z }
1562 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
1563 if pr_shroom:next(1,2) == 1 then
1564 minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_brown"})
1565 else
1566 minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_red"})
1572 local pr_nether = PseudoRandom(os.time()+667)
1573 -- Generate Nether decorations manually: Eternal fire, mushrooms, nether wart
1574 -- Minetest's API does not support decorations in caves yet. :-(
1575 local generate_nether_decorations = function(minp, maxp, seed)
1576 if minp.y > mcl_vars.mg_nether_max or maxp.y < mcl_vars.mg_nether_min then
1577 return
1580 -- TODO: Generate everything based on Perlin noise instead of PseudoRandom
1582 local bpos
1583 local rack = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:netherrack"})
1584 local magma = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:magma"})
1585 local ssand = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:soul_sand"})
1587 -- Helper function to spawn “fake” decoration
1588 local special_deco = function(nodes, spawn_func)
1589 for n = 1, #nodes do
1590 bpos = {x = nodes[n].x, y = nodes[n].y + 1, z = nodes[n].z }
1592 spawn_func(bpos)
1597 -- Eternal fire on netherrack
1598 special_deco(rack, function(bpos)
1599 -- Eternal fire on netherrack
1600 if pr_nether:next(1,100) <= 3 then
1601 minetest.set_node(bpos, {name = "mcl_fire:eternal_fire"})
1603 end)
1605 -- Eternal fire on magma cubes
1606 special_deco(magma, function(bpos)
1607 if pr_nether:next(1,150) == 1 then
1608 minetest.set_node(bpos, {name = "mcl_fire:eternal_fire"})
1610 end)
1612 -- Mushrooms on netherrack
1613 -- Note: Spawned *after* the fire because of light level checks
1614 special_deco(rack, function(bpos)
1615 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
1616 -- TODO: Make mushrooms appear in groups, use Perlin noise
1617 if pr_nether:next(1,2) == 1 then
1618 minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_brown"})
1619 else
1620 minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_red"})
1623 end)
1625 -- Nether wart on soul sand
1626 -- TODO: Spawn in Nether fortresses
1627 special_deco(ssand, function(bpos)
1628 if pr_nether:next(1,170) == 1 then
1629 minetest.set_node(bpos, {name = "mcl_nether:nether_wart"})
1631 end)
1635 -- Below the bedrock, generate air/void
1636 minetest.register_on_generated(function(minp, maxp, seed)
1637 local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
1638 local data = vm:get_data(lvm_buffer)
1639 local param2_data = vm:get_param2_data(lvm_buffer_param2)
1640 local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax})
1641 local lvm_used = false
1643 local ymin, ymax
1645 -- Generate basic layer-based nodes: void, bedrock, realm barrier, lava seas, etc.
1646 -- Also perform some basic node replacements.
1648 -- Helper function to set all nodes in the layers between min and max.
1649 -- content_id: Node to set
1650 -- check: optional.
1651 -- If content_id, node will be set only if it is equal to check.
1652 -- If function(pos_to_check, content_id_at_this_pos), will set node only if returns true.
1653 -- min, max: Minimum and maximum Y levels of the layers to set
1654 -- minp, maxp: minp, maxp of the on_generated
1655 -- lvm_used: Set to true if any node in this on_generated has been set before.
1657 -- returns true if any node was set and lvm_used otherwise
1658 local function set_layers(content_id, check, min, max, minp, maxp, lvm_used)
1659 if (maxp.y >= min and minp.y <= max) then
1660 for y = math.max(min, minp.y), math.min(max, maxp.y) do
1661 for x = minp.x, maxp.x do
1662 for z = minp.z, maxp.z do
1663 local p_pos = area:index(x, y, z)
1664 if check then
1665 if type(check) == "function" and check({x=x,y=y,z=z}, data[p_pos]) then
1666 data[p_pos] = content_id
1667 lvm_used = true
1668 elseif check == data[p_pos] then
1669 data[p_pos] = content_id
1670 lvm_used = true
1672 else
1673 data[p_pos] = content_id
1674 lvm_used = true
1680 return lvm_used
1683 -- The Void
1684 lvm_used = set_layers(c_void, nil, -31000, mcl_vars.mg_nether_min-1, minp, maxp, lvm_used)
1685 lvm_used = set_layers(c_void, nil, mcl_vars.mg_nether_max+1, mcl_vars.mg_end_min-1, minp, maxp, lvm_used)
1686 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)
1687 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)
1689 -- Realm barrier between the Overworld void and the End
1690 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)
1692 if mg_name ~= "singlenode" then
1693 -- Bedrock
1694 local bedrock_check
1695 if mcl_vars.mg_bedrock_is_rough then
1696 bedrock_check = function(pos)
1697 local y = pos.y
1698 -- Bedrock layers with increasing levels of roughness, until a perfecly flat bedrock later at the bottom layer
1699 -- This code assumes a bedrock height of 5 layers.
1701 local diff = mcl_vars.mg_bedrock_overworld_max - y -- Overworld bedrock
1702 local ndiff1 = mcl_vars.mg_bedrock_nether_bottom_max - y -- Nether bedrock, bottom
1703 local ndiff2 = mcl_vars.mg_bedrock_nether_top_max - y -- Nether bedrock, ceiling
1705 local top
1706 if diff == 0 or ndiff1 == 0 or ndiff2 == 4 then
1707 -- 50% bedrock chance
1708 top = 2
1709 elseif diff == 1 or ndiff1 == 1 or ndiff2 == 3 then
1710 -- 66.666...%
1711 top = 3
1712 elseif diff == 2 or ndiff1 == 2 or ndiff2 == 2 then
1713 -- 75%
1714 top = 4
1715 elseif diff == 3 or ndiff1 == 3 or ndiff2 == 1 then
1716 -- 90%
1717 top = 10
1718 elseif diff == 4 or ndiff1 == 4 or ndiff2 == 0 then
1719 -- 100%
1720 return true
1721 else
1722 -- Not in bedrock layer
1723 return false
1726 return math.random(1, top) <= top-1
1728 else
1729 bedrock_check = nil
1732 lvm_used = set_layers(c_bedrock, bedrock_check, mcl_vars.mg_bedrock_overworld_min, mcl_vars.mg_bedrock_overworld_max, minp, maxp, lvm_used)
1733 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)
1734 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)
1736 -- Flat Nether
1737 if mg_name == "flat" then
1738 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)
1741 -- Big lava seas by replacing air below a certain height
1742 if mcl_vars.mg_lava then
1743 lvm_used = set_layers(c_lava, c_air, mcl_vars.mg_overworld_min, mcl_vars.mg_lava_overworld_max, minp, maxp, lvm_used)
1744 lvm_used = set_layers(c_nether_lava, c_air, mcl_vars.mg_nether_min, mcl_vars.mg_lava_nether_max, minp, maxp, lvm_used)
1747 -- Clay, vines, cocoas
1748 lvm_used = generate_clay(minp, maxp, seed, data, area, lvm_used)
1750 local biomemap = minetest.get_mapgen_object("biomemap")
1751 lvm_used = generate_tree_decorations(minp, maxp, seed, data, param2_data, area, biomemap, lvm_used)
1753 ----- Interactive block fixing section -----
1754 ----- The section to perform basic block overrides of the core mapgen generated world. -----
1756 -- Snow and sand fixes. This code implements snow consistency
1757 -- and fixes floating sand.
1758 -- A snowy grass block must be below a top snow or snow block at all times.
1759 if minp.y <= mcl_vars.mg_overworld_max and maxp.y >= mcl_vars.mg_overworld_min then
1760 -- v6 mapgen:
1761 -- Put top snow on snowy grass blocks. The mapgen does not generate the top snow on its own.
1762 if mg_name == "v6" then
1763 local snowdirt = minetest.find_nodes_in_area_under_air(minp, maxp, "mcl_core:dirt_with_grass_snow")
1764 for n = 1, #snowdirt do
1765 -- CHECKME: What happens at chunk borders?
1766 local p_pos = area:index(snowdirt[n].x, snowdirt[n].y + 1, snowdirt[n].z)
1767 if p_pos then
1768 data[p_pos] = c_top_snow
1771 if #snowdirt > 1 then
1772 lvm_used = true
1776 -- Non-v6 mapgens:
1777 -- Clear snowy grass blocks without snow above to ensure consistency.
1778 -- Solidify floating sand to sandstone (both colors).
1779 else
1780 --local nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:dirt_with_grass_snow"})
1781 local nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:dirt_with_grass_snow", "mcl_core:sand", "mcl_core:redsand"})
1782 for n=1, #nodes do
1783 local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z)
1784 local p_pos_above = area:index(nodes[n].x, nodes[n].y+1, nodes[n].z)
1785 local p_pos_below = area:index(nodes[n].x, nodes[n].y-1, nodes[n].z)
1786 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
1787 data[p_pos] = c_dirt_with_grass
1788 lvm_used = true
1789 elseif p_pos_below and data[p_pos_below] == c_air or data[p_pos_below] == c_water then
1790 if data[p_pos] == c_sand then
1791 data[p_pos] = c_sandstone
1792 lvm_used = true
1793 elseif data[p_pos] == c_redsand then
1794 -- Note: This is the only place in which red sandstone is generatd
1795 data[p_pos] = c_redsandstone
1796 lvm_used = true
1802 -- Nether block fixes:
1803 -- * Replace water with Nether lava.
1804 -- * Replace stone, sand dirt in v6 so the Nether works in v6.
1805 elseif minp.y <= mcl_vars.mg_nether_max and maxp.y >= mcl_vars.mg_nether_min then
1806 local nodes
1807 if mg_name == "v6" then
1808 nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"})
1809 else
1810 nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source"})
1812 for n=1, #nodes do
1813 local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z)
1814 if data[p_pos] == c_water then
1815 data[p_pos] = c_nether_lava
1816 lvm_used = true
1817 elseif data[p_pos] == c_stone then
1818 data[p_pos] = c_netherrack
1819 lvm_used = true
1820 elseif data[p_pos] == c_sand or data[p_pos] == c_dirt then
1821 data[p_pos] = c_soul_sand
1822 lvm_used = true
1826 -- End block fixes:
1827 -- * Replace water with end stone or air (depending on height).
1828 -- * Remove stone, sand, dirt in v6 so our End map generator works in v6.
1829 elseif minp.y <= mcl_vars.mg_end_max and maxp.y >= mcl_vars.mg_end_min then
1830 local nodes
1831 if mg_name == "v6" then
1832 nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"})
1833 else
1834 nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source"})
1836 for n=1, #nodes do
1837 local y = nodes[n].y
1838 local p_pos = area:index(nodes[n].x, y, nodes[n].z)
1840 if data[p_pos] == c_water then
1841 if y <= mcl_vars.mg_end_min + 104 and y >= mcl_vars.mg_end_min + 40 then
1842 data[p_pos] = c_end_stone
1843 lvm_used = true
1844 else
1845 data[p_pos] = c_air
1846 lvm_used = true
1848 elseif data[p_pos] == c_stone or data[p_pos] == c_dirt or data[p_pos] == c_sand then
1849 data[p_pos] = c_air
1850 lvm_used = true
1857 -- Final hackery: Set sun light level in the End.
1858 -- -26912 is at a mapchunk border.
1859 local shadow
1860 if minp.y >= -26912 and maxp.y <= mcl_vars.mg_end_max then
1861 vm:set_lighting({day=15, night=15})
1862 lvm_used = true
1864 if minp.y >= mcl_vars.mg_end_min and maxp.y <= -26911 then
1865 shadow = false
1866 lvm_used = true
1869 -- Write stuff
1870 if lvm_used then
1871 vm:set_data(data)
1872 vm:set_param2_data(param2_data)
1873 vm:calc_lighting(nil, nil, shadow)
1874 vm:write_to_map()
1875 vm:update_liquids()
1878 if mg_name ~= "singlenode" then
1879 -- Generate special decorations
1880 generate_underground_mushrooms(minp, maxp, seed)
1881 generate_nether_decorations(minp, maxp, seed)
1882 generate_structures(minp, maxp, seed, biomemap)
1884 end)