-- decorations.lua local emptynodes = { air = true, ignore = true, } local core_cid = minetest.get_content_id local function cid(name) if not name then return end local result pcall(function() --< try result = core_cid(name) end) if not result then print("[biomegen] Node " .. name .. " not found!") end return result end local function generate_deco_simple(deco, vm, pr, p, ceiling) local emin, emax = vm:get_emerged_area() local place_offset_y = deco.place_offset_y if ceiling then if p.y - place_offset_y - deco.height_max < emin.y then return 0 elseif p.y - 1 - place_offset_y > emax.y then return 0 end else if p.y + place_offset_y + deco.height_max > emax.y then return 0 elseif p.y + 1 + place_offset_y < emin.y then return 0 end end local decos = deco.decoration if #decos == 0 then return 0 end local nodename = decos[pr:next(1,#decos)] local height = deco.vary_height and pr:next(deco.height, deco.height_max) or deco.height local param2 = deco.vary_param2 and pr:next(deco.param2, deco.param2_max) or deco.param2 local force_placement = deco.flags.force_placement == true local direction = ceiling and -1 or 1 p.y = p.y + place_offset_y * direction for i=1, height do p.y = p.y + direction local node = vm:get_node_at(p) if not force_placement and not emptynodes[node.name] then break end node.name = nodename node.param2 = param2 vm:set_node_at(p, node) end return 1 end local function get_schematic_size(schem) if type(schem) == "table" then return schem.size elseif type(schem) == "string" then local mts = io.open(schem) if not mts then return {x=0, y=0, z=0} end mts:seek('set', 6) local sx1, sx2, sy1, sy2, sz1, sz2 = mts:read(6):byte() mts:close() return {x=sx1*256+sx2, y=sy1*256+sy2, z=sz1*256+sz2} end return {x=0, y=0, z=0} end local function generate_deco_schematic(deco, vm, pr, p, ceiling) local force_placement = deco.flags.force_placement == true local direction = ceiling and -1 or 1 if not deco.flags.place_center_y then if ceiling then local size = get_schematic_size(schem) p.y = p.y - deco.place_offset_y - size.y + 1 else p.y = p.y + deco.place_offset_y end end minetest.place_schematic_on_vmanip(vm, p, deco.schematic, deco.rotation, deco.replacements, force_placement, deco.schem_flags) return 1 end local function parse_node_list(raw_list) if not raw_list then return {} end local ilist = {} if type(raw_list) == "string" then raw_list = {raw_list} end for i, node in ipairs(raw_list) do if node:sub(1, 6) == "group:" then local groupname = node:sub(7, -1) for name, ndef in pairs(minetest.registered_nodes) do if ndef.groups and ndef.groups[groupname] and ndef.groups[groupname] > 0 then local id = cid(name) if id then ilist[id] = true end end end else local id = cid(node) if id then ilist[id] = true end end end return ilist end local function make_decolist() local decos = {} for i, a in pairs(minetest.registered_decorations) do local b = {} decos[i] = b b.name = a.name or "unnamed " .. i b.deco_type = a.deco_type or "simple" b.place_on = parse_node_list(a.place_on) b.sidelen = a.sidelen or 8 b.fill_ratio = a.fill_ratio or 0.02 local np = a.noise_params b.use_noise = false if np then b.use_noise = true b.noise = minetest.get_perlin(np) end b.use_biomes = false if a.biomes then local biomes_raw = a.biomes b.use_biomes = true if type(biomes_raw) == "table" then local biomes = {} b.biomes = biomes for i, biome in pairs(biomes_raw) do if type(biome) == "number" then biome = minetest.get_biome_name(biome) end biomes[biome] = true end else if type(biomes_raw) == "number" then biomes_raw = minetest.get_biome_name(biomes_raw) end b.biomes = {[biomes_raw] = true} end end b.y_min = a.y_min or -31000 b.y_max = a.y_max or 31000 b.spawn_by = parse_node_list(a.spawn_by) b.num_spawn_by = a.num_spawn_by or 0 local flags_raw = a.flags or "" local flags = {} b.flags = flags for i, flag in ipairs(flags_raw:split()) do flag = flag:trim() local status = true if flag:sub(1,2) == "no" then flag = flag:sub(3,-1) status = false end flags[flag] = status end if b.deco_type == "simple" then local a_deco = a.decoration if type(a_deco) == "string" then a_deco = {a_deco} end local b_deco = {} for _, deco in ipairs(a_deco) do if cid(deco) then table.insert(b_deco, deco) end end b.decoration = b_deco b.height = a.height or 1 b.height_max = math.max(a.height_max or b.height, b.height) b.vary_height = b.height < b.height_max b.param2 = a.param2 or 0 b.param2_max = math.max(a.params2_max or b.param2, b.height) b.vary_param2 = b.param2 < b.param2_max b.place_offset_y = a.place_offset_y or 0 b.generate = generate_deco_simple elseif b.deco_type == "schematic" then b.schematic = a.schematic b.replacements = a.replacements or {} b.rotation = a.rotation or 0 b.place_offset_y = a.place_offset_y or 0 local schem_flags = {} for _, flag in ipairs({'place_center_x', 'place_center_y', 'place_center_z'}) do if flags[flag] then table.insert(schem_flags, flag) end end b.schem_flags = table.concat(schem_flags, ',') b.generate = generate_deco_schematic end end return decos end return make_decolist