geodes_lib = {} local function set_geode_node(pos, node) local original_node = minetest.get_node(pos) if original_node.name ~= "air" then minetest.set_node(pos, node) end end local function generate_geode(pos, radius, core, core_alt, core_alt_chance, shell) local total_radius = radius+1+#(shell) --generate shell for _, layer in ipairs(shell) do for x = -total_radius, total_radius do for y = -total_radius, total_radius do for z = -total_radius, total_radius do if vector.distance(vector.new(x, y, z), vector.new()) < total_radius then set_geode_node(pos + vector.new(x, y, z), {name = layer}) end end end end total_radius = total_radius-1 end --generate core for x = -total_radius, total_radius do for y = -total_radius, total_radius do for z = -total_radius, total_radius do if vector.distance(vector.new(x, y, z), vector.new()) < total_radius then if math.random(1, core_alt_chance) == 1 then set_geode_node(pos + vector.new(x, y, z), {name = core_alt}) else set_geode_node(pos + vector.new(x, y, z), {name = core}) end end end end end total_radius = total_radius-1 --generate cavity for x = -total_radius, total_radius do for y = -total_radius, total_radius do for z = -total_radius, total_radius do if vector.distance(vector.new(x, y, z), vector.new()) < total_radius then minetest.set_node(pos + vector.new(x, y, z), {name = "air"}) end end end end end function geodes_lib:register_geode(data) local wherein = data.wherein local y_min = data.y_min local y_max = data.y_max local scarcity = data.scarcity local core = data.core local core_alt = data.core_alt local core_alt_chance = data.core_alt_chance local shell = data.shell local radius_min = data.radius_min local radius_max = data.radius_max local generation_chance = data.generation_chance or 100 minetest.register_node(core.."_technical_mapgen", { }) minetest.register_ore({ ore_type = "scatter", ore = core.."_technical_mapgen", wherein = wherein, clust_scarcity = scarcity*scarcity*scarcity, clust_num_ores = 1, clust_size = 1, y_min = y_min, y_max = y_max, }) minetest.register_lbm({ label = "Generate geodes", name = core.."_geode_generation", nodenames = core.."_technical_mapgen", run_at_every_load = true, action = function(pos, node) -- Check if the action should be taken if math.random(1, 100) <= generation_chance then generate_geode(pos, math.random(radius_min,radius_max), core, core_alt, core_alt_chance, shell) else -- Revert the node back to wherein state minetest.set_node(pos, {name = wherein}) end end, }) end