forked from MineClone5/MineClone5
94 lines
2.8 KiB
Lua
94 lines
2.8 KiB
Lua
local radius_min = 3
|
|
local radius_max = mcl_mapgen.HALF_BS
|
|
local layers = {
|
|
{
|
|
[8] = "mcl_blackstone:basalt_polished",
|
|
[92] = "mcl_deepslate:deepslate",
|
|
},
|
|
{
|
|
[100] = "mcl_amethyst:calcite",
|
|
},
|
|
{
|
|
[85] = "mcl_amethyst:amethyst_block",
|
|
[15] = "mcl_amethyst:budding_amethyst_block",
|
|
},
|
|
{
|
|
[98] = "mcl_amethyst:amethyst_block",
|
|
[2] = "mcl_amethyst:budding_amethyst_block",
|
|
},
|
|
{
|
|
[100] = "air",
|
|
}
|
|
}
|
|
|
|
local function round(v)
|
|
if v < 0 then
|
|
return math.ceil(v - 0.5)
|
|
end
|
|
return math.floor(v + 0.5)
|
|
end
|
|
|
|
local function place(pos, rotation, pr)
|
|
local radius1 = vector.new(
|
|
-pr:next(radius_min, radius_max),
|
|
-pr:next(radius_min, radius_max),
|
|
-pr:next(radius_min, radius_max)
|
|
)
|
|
local radius2 = vector.new(
|
|
pr:next(radius_min, radius_max),
|
|
pr:next(radius_min, radius_max),
|
|
pr:next(radius_min, radius_max)
|
|
)
|
|
local layer_radius = pr:next(radius_min, radius_max)
|
|
local radius1_normalized = vector.normalize(radius1)
|
|
local radius2_normalized = vector.normalize(radius2)
|
|
local pos = vector.subtract(pos, radius1)
|
|
for x = radius1.x, radius2.x do
|
|
local max_x = (x < 0) and radius1.x or radius2.x
|
|
for y = radius1.y, radius2.y do
|
|
local max_y = (y < 0) and radius1.y or radius2.y
|
|
for z = radius1.z, radius2.z do
|
|
local max_z = (z < 0) and radius1.z or radius2.z
|
|
local normal_abs = vector.new(x / max_x, y / max_y, z / max_z)
|
|
local inverted_layer = round(vector.length(normal_abs) * layer_radius)
|
|
if inverted_layer <= layer_radius then
|
|
local layer = math.min(math.max(1, layer_radius - inverted_layer + 1), #layers)
|
|
local offset = vector.new(x, y, z)
|
|
local node_pos = pos + offset
|
|
local node_candidates = layers[layer]
|
|
local node_name
|
|
local chance_index = pr:next(1, 100)
|
|
local current_weight = 0
|
|
for chance, node_name_iterated in pairs(node_candidates) do
|
|
if chance_index <= current_weight + chance then
|
|
node_name = node_name_iterated
|
|
break
|
|
end
|
|
current_weight = current_weight + chance
|
|
end
|
|
minetest.swap_node(node_pos, {name = node_name})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
mcl_structures.register_structure({
|
|
name = "amethyst_geode",
|
|
place_function = place,
|
|
})
|
|
|
|
local decrease_scan_area = 1
|
|
local mapblock_opacity_placement_threshold = 0.98
|
|
local threshold = math.floor(((mcl_mapgen.BS - 2 * decrease_scan_area)^3) * mapblock_opacity_placement_threshold)
|
|
local upper_than = mcl_mapgen.overworld.bedrock_max
|
|
mcl_mapgen.register_mapgen_block(function(minp, maxp, blockseed)
|
|
local y = minp.y
|
|
if y <= upper_than then return end
|
|
local pr = PseudoRandom(blockseed + 143)
|
|
if pr:next(1, 120) ~= 54 then return end
|
|
local opacity_counter = #minetest.find_nodes_in_area(vector.add(minp, decrease_scan_area), vector.subtract(maxp, decrease_scan_area), "group:opaque")
|
|
if opacity_counter < threshold then return end
|
|
place(minp, nil, pr)
|
|
end)
|