diff --git a/mods/MAPGEN/mcl_villages/buildings.lua b/mods/MAPGEN/mcl_villages/buildings.lua index a71a22a8a..5e81c05bd 100644 --- a/mods/MAPGEN/mcl_villages/buildings.lua +++ b/mods/MAPGEN/mcl_villages/buildings.lua @@ -19,7 +19,7 @@ local function add_building(settlement, building, count_buildings) end end -local function layout_town(vm, minp, maxp, pr, input_settlement) +local function layout_town(minp, maxp, pr, input_settlement) local center = vector.new(pr:next(minp.x + 24, maxp.x - 24), maxp.y, pr:next(minp.z + 24, maxp.z - 24)) minetest.log("action", "[mcl_villages] sudo make me a village at: " .. minetest.pos_to_string(minp).." - "..minetest.pos_to_string(maxp)) local possible_rotations = {"0", "90", "180", "270"} @@ -57,7 +57,7 @@ local function layout_town(vm, minp, maxp, pr, input_settlement) -- ensure we have 3 space for terraforming, and avoid problems with VoxelManip if tlpos.x - 3 >= minp.x and tlpos.x + size.x + 3 <= maxp.x and tlpos.z + 3 >= minp.z and tlpos.z + size.y + 3 <= maxp.z then - local pos, surface_material = vl_terraforming.find_level_vm(vm, cpos, size, 6) + local pos, surface_material = vl_terraforming.find_level(cpos, size, 6) if pos and pos.y + size.y > maxp.y then pos = nil end -- check distance to other buildings. Note that we still want to add baseplates etc. if pos and mcl_villages.surface_mat[surface_material.name] and mcl_villages.check_distance(settlement, cpos, size.x, size.z, mindist) then @@ -98,7 +98,7 @@ local function layout_town(vm, minp, maxp, pr, input_settlement) return settlement end -function mcl_villages.create_site_plan(vm, minp, maxp, pr) +function mcl_villages.create_site_plan(minp, maxp, pr) local settlement = {} -- initialize all settlement_info table @@ -169,7 +169,7 @@ function mcl_villages.create_site_plan(vm, minp, maxp, pr) end table.insert(settlement, 1, bell_info) - return layout_town(vm, minp, maxp, pr, settlement) + return layout_town(minp, maxp, pr, settlement) end local function init_nodes(p1, p2, pr) @@ -194,8 +194,7 @@ local function init_nodes(p1, p2, pr) for _, n in pairs(nodes) do mcl_villages.fill_chest(n, pr) end end --- important: the vm will be written and then is outdated! -function mcl_villages.place_schematics(vm, settlement, blockseed, pr) +function mcl_villages.place_schematics(sminp, smaxp, settlement, blockseed, pr) -- first building is always the bell local bell_pos = vector.offset(settlement[1].minp, math.floor(settlement[1].size.x/2), 0, math.floor(settlement[1].size.z/2)) @@ -213,17 +212,14 @@ function mcl_villages.place_schematics(vm, settlement, blockseed, pr) -- the foundation and air space for the building was already built before -- minetest.log("action", "placing schematics for "..building.name.." at "..minetest.pos_to_string(minp).." on "..surface_material.name) - minetest.place_schematic_on_vmanip(vm, minp, schematic, rotation, nil, true, { place_center_x = false, place_center_y = false, place_center_z = false }) - mcl_villages.store_path_ends(vm, minp, maxp, cpos, blockseed, bell_pos) - mcl_villages.increase_no_paths(vm, minp, maxp) -- help the path finder + minetest.place_schematic(minp, schematic, rotation, nil, true, { place_center_x = false, place_center_y = false, place_center_z = false }) + mcl_villages.store_path_ends(minp, maxp, cpos, blockseed, bell_pos) + mcl_villages.increase_no_paths(minp, maxp) -- help the path finder end - local minp, maxp = vm:get_emerged_area() -- safe area for further processing - vm:write_to_map(true) -- for path finder and light - -- Path planning and placement - mcl_villages.paths(blockseed, minetest.get_biome_name(minetest.get_biome_data(bell_pos).biome), minp, maxp) - mcl_villages.clean_no_paths(minp, maxp) + mcl_villages.paths(blockseed, minetest.get_biome_name(minetest.get_biome_data(bell_pos).biome), sminp, smaxp) + mcl_villages.clean_no_paths(sminp, smaxp) -- Clean up paths and initialize nodes for i, building in ipairs(settlement) do init_nodes(building.minp, building.maxp, pr) @@ -335,7 +331,7 @@ function mcl_villages.post_process_village(blockseed) end -- Terraform for an entire village -function mcl_villages.terraform(vm, settlement, pr) +function mcl_villages.terraform(settlement, pr) -- TODO: sort top-down, then bottom-up, or opposite? -- we make the foundations 2 node wider than necessary, to have one node for path laying for i, building in ipairs(settlement) do @@ -343,7 +339,7 @@ function mcl_villages.terraform(vm, settlement, pr) local pos, size = building.pos, building.size pos = vector.offset(pos, -math.floor((size.x-1)/2), 0, -math.floor((size.z-1)/2)) -- TODO: allow different clearance for different buildings? - vl_terraforming.clearance_vm(vm, pos.x-1, pos.y, pos.z-1, size.x+2, size.y, size.z+2, 2, building.surface_mat, building.dust_mat, pr) + vl_terraforming.clearance(pos.x-1, pos.y, pos.z-1, size.x+2, size.y, size.z+2, 2, building.surface_mat, building.dust_mat, pr) end end for i, building in ipairs(settlement) do @@ -356,7 +352,7 @@ function mcl_villages.terraform(vm, settlement, pr) building.platform_mat = platform_mat -- remember for use in schematic placement building.stone_mat = stone_mat pos = vector.offset(pos, -math.floor((size.x-1)/2), 0, -math.floor((size.z-1)/2)) - vl_terraforming.foundation_vm(vm, pos.x-2, pos.y, pos.z-2, size.x+4, -5, size.z+4, 2, surface_mat, platform_mat, stone_mat, dust_mat, pr) + vl_terraforming.foundation(pos.x-2, pos.y, pos.z-2, size.x+4, -5, size.z+4, 2, surface_mat, platform_mat, stone_mat, dust_mat, pr) end end end diff --git a/mods/MAPGEN/mcl_villages/init.lua b/mods/MAPGEN/mcl_villages/init.lua index ede0b31d5..f3e4e942d 100644 --- a/mods/MAPGEN/mcl_villages/init.lua +++ b/mods/MAPGEN/mcl_villages/init.lua @@ -15,14 +15,12 @@ local function ecb_village(blockpos, action, calls_remaining, param) if calls_remaining >= 1 then return end if mcl_villages.village_exists(param.blockseed) then return end local pr = PcgRandom(param.blockseed) - local vm = VoxelManip(param.minp, param.maxp) - local settlement = mcl_villages.create_site_plan(vm, param.minp, param.maxp, pr) + local settlement = mcl_villages.create_site_plan(param.minp, param.maxp, pr) if not settlement then return false, false end -- all foundations first, then all buildings, to avoid damaging very close buildings - mcl_villages.terraform(vm, settlement, pr) - mcl_villages.place_schematics(vm, settlement, param.blockseed, pr) + mcl_villages.terraform(settlement, pr) + mcl_villages.place_schematics(param.minp, param.maxp, settlement, param.blockseed, pr) mcl_villages.add_village(param.blockseed, settlement) - --lvm:write_to_map(true) -- destorys paths as of now, as they are placed afterwards for _, on_village_placed_callback in pairs(mcl_villages.on_village_placed) do on_village_placed_callback(settlement, param.blockseed) end diff --git a/mods/MAPGEN/mcl_villages/paths.lua b/mods/MAPGEN/mcl_villages/paths.lua index 2058f6f64..f7e687e3d 100644 --- a/mods/MAPGEN/mcl_villages/paths.lua +++ b/mods/MAPGEN/mcl_villages/paths.lua @@ -3,6 +3,9 @@ ------------------------------------------------------------------------------- local light_threshold = tonumber(minetest.settings:get("mcl_villages_light_threshold")) or 5 +local get_node = core.get_node +local swap_node = core.swap_node + -- This ends up being a nested table. -- 1st level is the blockseed which is the village -- 2nd is the distance of the building from the bell @@ -20,7 +23,7 @@ end -- this can still run in LVM -- simple function to increase "no_paths" walls -function mcl_villages.increase_no_paths(vm, minp, maxp) +function mcl_villages.increase_no_paths(minp, maxp) local p = vector.zero() for z = minp.z, maxp.z do p.z = z @@ -28,12 +31,12 @@ function mcl_villages.increase_no_paths(vm, minp, maxp) p.x = x for y = minp.y, maxp.y - 1 do p.y = y - local n = vm:get_node_at(p) + local n = get_node(p) if n and n.name == "mcl_villages:no_paths" then p.y = y + 1 - n = vm:get_node_at(p) + n = get_node(p) if n and n.name == "air" then - vm:set_node_at(p, {name = "mcl_villages:no_paths" }) + swap_node(p, {name = "mcl_villages:no_paths" }) end end end @@ -42,7 +45,7 @@ function mcl_villages.increase_no_paths(vm, minp, maxp) end -- Insert end points in to the nested tables -function mcl_villages.store_path_ends(vm, minp, maxp, pos, blockseed, bell_pos) +function mcl_villages.store_path_ends(minp, maxp, pos, blockseed, bell_pos) -- We store by distance because we create paths far away from the bell first local dist = vector.distance(bell_pos, pos) local id = "block_" .. blockseed -- cannot use integers as keys @@ -55,10 +58,10 @@ function mcl_villages.store_path_ends(vm, minp, maxp, pos, blockseed, bell_pos) v.y = yi for xi = minp.x, maxp.x do v.x = xi - local n = vm:get_node_at(v) + local n = get_node(v) if n and n.name == "mcl_villages:path_endpoint" then table.insert(tab, vector.copy(v)) - vm:set_node_at(v, { name = "air" }) + swap_node(v, { name = "air" }) end end end @@ -80,19 +83,18 @@ local function place_lamp(pos, pr) ) end --- TODO: port this to lvm. local function smooth_path(path, passes, minp, maxp) -- bridge over water/laver for i = 2, #path - 1 do while true do local cur = path[i] - local node = minetest.get_node(cur).name + local node = get_node(cur).name if node == "air" and vector.in_area(cur, minp, maxp) then - local under = minetest.get_node(vector.offset(path[i], 0, -1, 0)).name + local under = get_node(vector.offset(path[i], 0, -1, 0)).name local udef = minetest.registered_nodes[under] -- do not build paths over leaves - if udef and udef.groups.leaves then - minetest.swap_node(path[i], {name="mcl_villages:no_paths"}) + if udef and (udef.groups.leaves or 0) > 0 then + swap_node(path[i], {name="mcl_villages:no_paths"}) return -- bad path end break @@ -115,7 +117,7 @@ local function smooth_path(path, passes, minp, maxp) local prev_y = path[i - 1].y local y = path[i].y local next_y = path[i + 1].y - local bump = minetest.get_node(path[i]).name + local bump = get_node(path[i]).name local bdef = minetest.registered_nodes[bump] -- TODO: also replace bamboo underneath with dirt here? @@ -126,14 +128,14 @@ local function smooth_path(path, passes, minp, maxp) or (y > prev_y and y > next_y) then -- Remove peaks to flatten path path[i].y = math.max(prev_y, next_y) - minetest.swap_node(path[i], { name = "air" }) + swap_node(path[i], { name = "air" }) changed = true elseif (y < next_y - 1 and y >= prev_y) -- large step or (y < prev_y - 1 and y >= next_y) -- large step or (y < prev_y and y < next_y) then -- Fill in dips to flatten path path[i].y = math.min(prev_y, next_y) - 1 -- to replace below first - minetest.swap_node(path[i], { name = "mcl_core:dirt" }) -- todo: use sand/sandstone in desert?, use slabs? + swap_node(path[i], { name = "mcl_core:dirt" }) -- todo: use sand/sandstone in desert?, use slabs? path[i].y = path[i].y + 1 -- above dirt changed = true end @@ -146,23 +148,22 @@ local function smooth_path(path, passes, minp, maxp) -- we may not yet have filled a gap for i = 2, #path - 1 do local below = vector.offset(path[y], 0, -1, 0) - local bdef = minetest.registered_nodes[minetest.get_node(path[i]).name] + local bdef = minetest.registered_nodes[get_node(path[i]).name] if bdef and not bdef.walkable then - minetest.swap_node(path[i], { name = "mcl_core:dirt" }) -- todo: use sand/sandstone in desert?, use slabs? + swap_node(path[i], { name = "mcl_core:dirt" }) -- todo: use sand/sandstone in desert?, use slabs? end end end]] return path end --- TODO: port this to lvm. local function place_path(path, pr, stair, slab) -- find water/lava below for i = 2, #path - 1 do local prev_y = path[i - 1].y local y = path[i].y local next_y = path[i + 1].y - local bump = minetest.get_node(path[i]).name + local bump = get_node(path[i]).name local bdef = minetest.registered_nodes[bump] if bdef and ((bdef.groups.water or 0) > 0 or (bdef.groups.lava or 0) > 0) then @@ -170,10 +171,10 @@ local function place_path(path, pr, stair, slab) local up_pos = vector.copy(path[i]) while true do up_pos.y = up_pos.y + 1 - local up_node = minetest.get_node(up_pos).name + local up_node = get_node(up_pos).name local udef = minetest.registered_nodes[up_node] if udef and (udef.groups.water or 0) == 0 and (udef.groups.lava or 0) == 0 then - minetest.swap_node(up_pos, { name = "air" }) + swap_node(up_pos, { name = "air" }) path[i] = up_pos break elseif not udef then break end -- ignore node encountered @@ -182,31 +183,31 @@ local function place_path(path, pr, stair, slab) end for i, pos in ipairs(path) do - local n0 = minetest.get_node(pos).name - if n0 ~= "air" then minetest.swap_node(pos, { name = "air" }) end + local n0 = get_node(pos).name + if n0 ~= "air" then swap_node(pos, { name = "air" }) end local under_pos = vector.offset(pos, 0, -1, 0) - local n = minetest.get_node(under_pos).name + local n = get_node(under_pos).name local ndef = minetest.registered_nodes[n] local groups = ndef and ndef.groups or {} local done = false if i > 1 and pos.y > path[i - 1].y then -- stairs up - if not groups.stair then + if (groups.stair or 0) == 0 then done = true local param2 = minetest.dir_to_facedir(vector.subtract(pos, path[i - 1])) - minetest.swap_node(under_pos, { name = stair, param2 = param2 }) + swap_node(under_pos, { name = stair, param2 = param2 }) end elseif i < #path-1 and pos.y > path[i + 1].y then -- stairs down - if not groups.stair then + if (groups.stair or 0) == 0 then done = true local param2 = minetest.dir_to_facedir(vector.subtract(pos, path[i + 1])) - minetest.swap_node(under_pos, { name = stair, param2 = param2 }) + swap_node(under_pos, { name = stair, param2 = param2 }) end - elseif not groups.stair and i > 1 and pos.y < path[i - 1].y then + elseif (groups.stair or 0) == 0 and i > 1 and pos.y < path[i - 1].y then -- stairs down - local n2 = minetest.get_node(vector.offset(path[i - 1], 0, -1, 0)).name + local n2 = get_node(vector.offset(path[i - 1], 0, -1, 0)).name if not minetest.get_item_group(n2, "stair") then done = true local param2 = minetest.dir_to_facedir(vector.subtract(path[i - 1], pos)) @@ -216,38 +217,38 @@ local function place_path(path, pr, stair, slab) minetest.add_node(pos, { name = stair, param2 = param2 }) pos.y = pos.y + 1 end - elseif not groups.stair and i < #path-1 and pos.y < path[i + 1].y then + elseif (groups.stair or 0) == 0 and i < #path-1 and pos.y < path[i + 1].y then -- stairs up - local n2 = minetest.get_node(vector.offset(path[i + 1], 0, -1, 0)).name + local n2 = get_node(vector.offset(path[i + 1], 0, -1, 0)).name if not minetest.get_item_group(n2, "stair") then done = true local param2 = minetest.dir_to_facedir(vector.subtract(path[i + 1], pos)) if i > 1 then -- uglier, but easier to walk up? param2 = minetest.dir_to_facedir(vector.subtract(pos, path[i - 1])) end - minetest.add_node(pos, { name = stair, param2 = param2 }) + swap_node(pos, { name = stair, param2 = param2 }) pos.y = pos.y + 1 end end -- flat if not done then - if groups.water then - minetest.add_node(under_pos, { name = slab }) - elseif groups.lava then - minetest.add_node(under_pos, { name = "mcl_stairs:slab_stone" }) - elseif groups.sand then - minetest.swap_node(under_pos, { name = "mcl_core:sandstonesmooth2" }) - elseif groups.soil and not groups.dirtifies_below_solid then - minetest.swap_node(under_pos, { name = "mcl_core:grass_path" }) + if (groups.water or 0) > 0 then + swap_node(under_pos, { name = slab }) + elseif (groups.lava or 0) > 0 then + swap_node(under_pos, { name = "mcl_stairs:slab_stone" }) + elseif (groups.sand or 0) > 0 then + swap_node(under_pos, { name = "mcl_core:sandstonesmooth2" }) + elseif (groups.soil or 0) > 0 and (groups.dirtifies_below_solid or 0) == 0 then + swap_node(under_pos, { name = "mcl_core:grass_path" }) end end -- Clear space for villagers to walk for j = 1, 2 do local over_pos = vector.offset(pos, 0, j, 0) - if minetest.get_node(over_pos).name ~= "air" then - minetest.swap_node(over_pos, { name = "air" }) + if get_node(over_pos).name ~= "air" then + swap_node(over_pos, { name = "air" }) end end end @@ -260,7 +261,7 @@ local function place_path(path, pr, stair, slab) ) -- todo: shuffle nn? for _, npos in ipairs(nn) do - local node = minetest.get_node(npos).name + local node = get_node(npos).name if node ~= "mcl_core:grass_path" and minetest.get_item_group(node, "stair") == 0 then if minetest.get_item_group(node, "wood_slab") ~= 0 then minetest.add_node(vector.offset(npos, 0, 1, 0), { name = "mcl_torches:torch", param2 = 1 }) diff --git a/mods/MAPGEN/vl_structures/emerge.lua b/mods/MAPGEN/vl_structures/emerge.lua index f315d9b3b..a0a34b12f 100644 --- a/mods/MAPGEN/vl_structures/emerge.lua +++ b/mods/MAPGEN/vl_structures/emerge.lua @@ -1,9 +1,11 @@ local vector_offset = vector.offset local floor = math.floor +local get_node = core.get_node local logging = minetest.settings:get_bool("vl_structures_logging", false) local mg_name = minetest.get_mapgen_setting("mg_name") + -- parse the prepare parameter local function parse_prepare(prepare) if prepare == nil or prepare == true then return vl_structures.DEFAULT_PREPARE end @@ -21,8 +23,6 @@ end local function emerge_schematics(blockpos, action, calls_remaining, param) if calls_remaining >= 1 then return end local start = os.clock() - local vm = VoxelManip() - vm:read_from_map(param.emin, param.emax) local startmain = os.clock() local pos, size, yoffset, def, pr = param.pos, param.size, param.yoffset or 0, param.def, param.pr local prepare, surface_mat = parse_prepare(param.prepare or def.prepare), param.surface_mat @@ -40,13 +40,13 @@ local function emerge_schematics(blockpos, action, calls_remaining, param) end -- hack to get dust nodes more often, in case the mapgen messed with biomes - local n = vm:get_node_at(vector_offset(param.opos, 0, 1, 0)) + local n = get_node(vector_offset(param.opos, 0, 1, 0)) if n.name == "mcl_core:snow" then dust_mat = n end -- Step 1: adjust ground to a more level position -- todo: also support checking ground of daughter schematics, but not used by current schematics if pos and size and prepare and tolerance_enabled(prepare.tolerance, prepare.mode) then - pos, surface_mat = vl_terraforming.find_level_vm(vm, pos, size, prepare.tolerance, prepare.mode) + pos, surface_mat = vl_terraforming.find_level(pos, size, prepare.tolerance, prepare.mode) if not pos then minetest.log("warning", "[vl_structures] Not spawning "..tostring(def.name or param.schematic.name).." at "..minetest.pos_to_string(param.pos).." because ground is too uneven.") return @@ -80,7 +80,7 @@ local function emerge_schematics(blockpos, action, calls_remaining, param) local yoff, ymax = prepare.clear_bottom or 0, size.y + yoffset + (prepare.clear_top or vl_structures.DEFAULT_PREPARE.clear_top) if prepare.clear_bottom == "top" or prepare.clear_bottom == "above" then yoff = size.y + yoffset end --minetest.log("action", "[vl_structures] clearing air "..minetest.pos_to_string(gp)..": ".. (size.x + padding * 2)..","..ymax..","..(size.z + padding * 2)) - vl_terraforming.clearance_vm(vm, gp.x, gp.y + yoff, gp.z, + vl_terraforming.clearance(gp.x, gp.y + yoff, gp.z, size.x + padding * 2, ymax - yoff, size.z + padding * 2, corners, node_top, node_dust, pr) -- clear for daughters @@ -98,7 +98,7 @@ local function emerge_schematics(blockpos, action, calls_remaining, param) local sy = ymax - yoff --minetest.log("action", "[vl_structures] clearing air "..minetest.pos_to_string(gp)..": ".. (dsize.x + padding * 2)..","..sy..","..(dsize.z + padding * 2)) if sy > 0 then - vl_terraforming.clearance_vm(vm, gp.x, gp.y + yoff, gp.z, + vl_terraforming.clearance(gp.x, gp.y + yoff, gp.z, dsize.x + padding * 2, ymax - yoff, dsize.z + padding * 2, corners, node_top, node_dust, pr) end @@ -110,7 +110,7 @@ local function emerge_schematics(blockpos, action, calls_remaining, param) if prepare.foundation then -- minetest.log("action", "[vl_structures] "..tostring(def.name or param.schematic.name).." fill foundation "..minetest.pos_to_string(gp).." with "..tostring(node_top.name).." "..tostring(node_filler.name).." "..tostring(node_dust and node_dust.name)) local depth = (type(prepare.foundation) == "number" and prepare.foundation) or vl_structures.DEFAULT_PREPARE.foundation - vl_terraforming.foundation_vm(vm, gp.x, gp.y - 1, gp.z, + vl_terraforming.foundation(gp.x, gp.y - 1, gp.z, size.x + padding * 2, depth, size.z + padding * 2, corners, node_top, node_filler, node_stone, node_dust, pr) -- foundation for daughters @@ -124,7 +124,7 @@ local function emerge_schematics(blockpos, action, calls_remaining, param) local gp = vector_offset(pos, dd.pos.x - floor((dsize.x-1)*0.5) - padding, dd.pos.y + (yoffset or 0), dd.pos.z - floor((dsize.z-1)*0.5) - padding) - vl_terraforming.foundation_vm(vm, gp.x, gp.y - 1, gp.z, + vl_terraforming.foundation(gp.x, gp.y - 1, gp.z, dsize.x + padding * 2, depth, dsize.z + padding * 2, corners, node_top, node_filler, node_stone, node_dust, pr) end @@ -133,17 +133,16 @@ local function emerge_schematics(blockpos, action, calls_remaining, param) end -- Step 3: place schematic on center position - minetest.place_schematic_on_vmanip(vm, pmin, param.schematic, param.rotation, param.replacements, param.force_placement, "") + minetest.place_schematic(pmin, param.schematic, param.rotation, param.replacements, param.force_placement, "") -- Step 3: place daughter schematics for _,tmp in ipairs(daughters) do local d, ds, rot = tmp[1], tmp[2], tmp[3] local p = vector_offset(pos, d.pos.x, d.pos.y + (yoffset or 0), d.pos.z) - minetest.place_schematic_on_vmanip(vm, p, ds, rot, d.replacements, d.force_placement, "place_center_x,place_center_z") + minetest.place_schematic(p, ds, rot, d.replacements, d.force_placement, "place_center_x,place_center_z") -- todo: allow after_place callbacks for daughter schematics? end local endmain = os.clock() -- TODO: step 4: sprinkle extra dust on top. - vm:write_to_map(true) -- Note: deliberately pos, p1 and p2 from the parent, as these are calls to the parent script if def.loot then vl_structures.fill_chests(pmin,pmax,def.loot,pr) end if def.construct_nodes then vl_structures.construct_nodes(pmin,pmax,def.construct_nodes) end