3 -- Jewel ore generated in birch tree nodes in the giga tree decorations
4 -- in the Deep Forest biome.
5 -- The algorithm uses LVM to imitate Minetest's scatter ores,
6 -- since ores in Minetest are generated after decorations.
8 -- Fields of the original ore definition:
9 local clust_scarcity
= 11*11*11
10 local clust_num_ores
= 3
15 local gigatree_decoration_id
= minetest
.get_decoration_id("rp_default:gigatree")
18 if minetest
.registered_biomes
["Deep Forest"] then
19 biome_y
= minetest
.registered_biomes
["Deep Forest"].y_min
22 biome_y
= tonumber(minetest
.get_mapgen_setting("water_level")) or 1
28 local c_birch
= minetest
.get_content_id("rp_default:tree_birch")
29 local c_jewel_ore
= minetest
.get_content_id("rp_jewels:jewel_ore")
31 -- Generation algorithm:
34 -- Helper function to find a random minimum/maxium range of length clust_size.
35 -- Returned numbers are offsets.
36 local rnd_minmax
= function(pr
)
37 local min = pr
:next(- clust_size
+ 1, 0)
38 local max = min + (clust_size
- 1)
42 minetest
.set_gen_notify({decoration
=true}, {gigatree_decoration_id
})
43 minetest
.register_on_generated(function(minp
, maxp
, blockseed
)
44 if maxp
.y
< y_min
then
47 local ores_in_mapblock
= {}
48 local pr
= PseudoRandom(blockseed
)
50 if gigatree_decoration_id
then
51 -- Was a giga tree was found anywhere in generated area?
52 local mgobj
= minetest
.get_mapgen_object("gennotify")
53 local deco
= mgobj
["decoration#"..gigatree_decoration_id
]
54 deco_ok
= deco
and #deco
> 0
57 -- This code tries to imitate scatter ores in Minetest
58 local vm
, emin
, emax
= minetest
.get_mapgen_object("voxelmanip")
59 local area
= VoxelArea
:new({MinEdge
=emin
, MaxEdge
=emax
})
60 local data
= vm
:get_data(lvm_buffer
)
61 -- Interate through all nodes and place jewel ore in birch tree nodes
62 -- with a low chance (1/clust_scarcity)
63 for z
=minp
.z
, maxp
.z
do
64 for y
=math
.max(y_min
, minp
.y
), maxp
.y
do
65 for x
=minp
.x
, maxp
.x
do
66 local p_pos
= area
:index(x
,y
,z
)
67 if data
[p_pos
] == c_birch
then
70 bdata
= minetest
.get_biome_data({x
=x
,y
=math
.max(y
, biome_y
),z
=z
})
71 bname
= minetest
.get_biome_name(bdata
.biome
)
73 if ((not biome_exists
) or (bname
== "Deep Forest")) and pr
:next(1, clust_scarcity
) == 1 then
74 data
[p_pos
] = c_jewel_ore
75 table.insert(ores_in_mapblock
, {x
=x
,y
=y
,z
=z
})
81 -- If jewel ore was placed in the first phase, also place additional near the initial ore
82 for o
=1, #ores_in_mapblock
do
83 local start_ore
= ores_in_mapblock
[o
]
84 for n
=1, clust_num_ores
do
86 local axes
= {"z","y","x"}
89 -- New ores are placed within a randomly positioned bounding box
90 -- of size clust_size^3 around the initial ore
91 ore
[ax
] = start_ore
[ax
] + pr
:next(rnd_minmax(pr
))
92 -- Make sure we stay within minp, maxp
93 if ore
[ax
] < minp
[ax
] then
95 elseif ore
[ax
] > maxp
[ax
] then
99 local p_pos
= area
:index(ore
.x
, ore
.y
, ore
.z
)
100 -- The new random pos must also be a birch tree to generate a jewel ore
101 if data
[p_pos
] == c_birch
then
102 data
[p_pos
] = c_jewel_ore
106 -- Only write back to map when any ore was actually placed
107 if #ores_in_mapblock
> 0 then