From 30b4b9661ca1852f95114dd4422657738e5a5b37 Mon Sep 17 00:00:00 2001 From: kay27 Date: Fri, 29 Jan 2021 22:49:33 +0400 Subject: [PATCH] Villages cleanup --- mods/MAPGEN/mcl_villages/buildings.lua | 173 +--------------- mods/MAPGEN/mcl_villages/const.lua | 51 ++--- mods/MAPGEN/mcl_villages/convert_lua_mts.lua | 27 ++- mods/MAPGEN/mcl_villages/foundation.lua | 170 ++++------------ mods/MAPGEN/mcl_villages/init.lua | 173 ++-------------- mods/MAPGEN/mcl_villages/paths.lua | 93 --------- mods/MAPGEN/mcl_villages/utils.lua | 204 +++++-------------- 7 files changed, 150 insertions(+), 741 deletions(-) diff --git a/mods/MAPGEN/mcl_villages/buildings.lua b/mods/MAPGEN/mcl_villages/buildings.lua index db52bf2cc..05f08bdcc 100644 --- a/mods/MAPGEN/mcl_villages/buildings.lua +++ b/mods/MAPGEN/mcl_villages/buildings.lua @@ -61,8 +61,7 @@ function settlements.initialize_settlement_info(pr) local count_buildings = {} -- count_buildings table reset - for k,v in pairs(schematic_table) do - -- local name = schematic_table[v]["name"] + for k,v in pairs(settlements.schematic_table) do count_buildings[v["name"]] = 0 end @@ -74,96 +73,6 @@ function settlements.initialize_settlement_info(pr) return count_buildings, number_of_buildings, number_built end ------------------------------------------------------------------------------- --- fill settlement_info with LVM --------------------------------------------------------------------------------- -function settlements.create_site_plan_lvm(maxp, minp, pr) - local settlement_info = {} - local building_all_info - local possible_rotations = {"0", "90", "180", "270"} - -- find center of chunk - local center = { - x=maxp.x-half_map_chunk_size, - y=maxp.y, - z=maxp.z-half_map_chunk_size - } - -- find center_surface of chunk - local center_surface, surface_material = settlements.find_surface_lvm(center, minp) - -- go build settlement around center - if not center_surface then return false end - - -- add settlement to list - table.insert(settlements_in_world, center_surface) - -- save list to file - settlements.save() - -- initialize all settlement_info table - local count_buildings, number_of_buildings, number_built = settlements.initialize_settlement_info(pr) - -- first building is townhall in the center - building_all_info = schematic_table[1] - local rotation = possible_rotations[ pr:next(1, #possible_rotations ) ] - -- add to settlement info table - local index = 1 - settlement_info[index] = { - pos = center_surface, - name = building_all_info["name"], - hsize = building_all_info["hsize"], - rotat = rotation, - surface_mat = surface_material - } - -- increase index for following buildings - index = index + 1 - -- now some buildings around in a circle, radius = size of town center - local x, z, r = center_surface.x, center_surface.z, building_all_info["hsize"] - -- draw j circles around center and increase radius by math.random(2,5) - for j = 1,20 do - if number_built < number_of_buildings then - -- set position on imaginary circle - for j = 0, 360, 15 do - local angle = j * math.pi / 180 - local ptx, ptz = x + r * math.cos( angle ), z + r * math.sin( angle ) - ptx = settlements.round(ptx, 0) - ptz = settlements.round(ptz, 0) - local pos1 = { x=ptx, y=center_surface.y+50, z=ptz} - local pos_surface, surface_material = settlements.find_surface_lvm(pos1, minp) - if not pos_surface then break end - - local randomized_schematic_table = shuffle(schematic_table, pr) - -- pick schematic - local size = #randomized_schematic_table - for i = size, 1, -1 do - -- already enough buildings of that type? - if count_buildings[randomized_schematic_table[i]["name"]] < randomized_schematic_table[i]["max_num"]*number_of_buildings then - building_all_info = randomized_schematic_table[i] - -- check distance to other buildings - local distance_to_other_buildings_ok = settlements.check_distance(settlement_info, pos_surface, building_all_info["hsize"]) - if distance_to_other_buildings_ok then - -- count built houses - count_buildings[building_all_info["name"]] = count_buildings[building_all_info["name"]] +1 - - rotation = possible_rotations[ pr:next(1, #possible_rotations ) ] - number_built = number_built + 1 - settlement_info[index] = { - pos = pos_surface, - name = building_all_info["name"], - hsize = building_all_info["hsize"], - rotat = rotation, - surface_mat = surface_material - } - index = index + 1 - break - end - end - end - if number_of_buildings == number_built then - break - end - end - r = r + pr:next(2,5) - end - end - settlements.debug("really ".. number_built) - return settlement_info -end -------------------------------------------------------------------------------- -- fill settlement_info -------------------------------------------------------------------------------- function settlements.create_site_plan(maxp, minp, pr) @@ -188,7 +97,7 @@ function settlements.create_site_plan(maxp, minp, pr) -- initialize all settlement_info table local count_buildings, number_of_buildings, number_built = settlements.initialize_settlement_info(pr) -- first building is townhall in the center - building_all_info = schematic_table[1] + building_all_info = settlements.schematic_table[1] local rotation = possible_rotations[ pr:next(1, #possible_rotations ) ] -- add to settlement info table local index = 1 @@ -216,7 +125,7 @@ function settlements.create_site_plan(maxp, minp, pr) local pos_surface, surface_material = settlements.find_surface(pos1) if not pos_surface then break end - local randomized_schematic_table = shuffle(schematic_table, pr) + local randomized_schematic_table = shuffle(settlements.schematic_table, pr) -- pick schematic local size = #randomized_schematic_table for i = size, 1, -1 do @@ -255,80 +164,10 @@ end ------------------------------------------------------------------------------- -- evaluate settlement_info and place schematics ------------------------------------------------------------------------------- -function settlements.place_schematics_lvm(settlement_info, pr) - for i, built_house in ipairs(settlement_info) do - for j, schem in ipairs(schematic_table) do - if settlement_info[i]["name"] == schem["name"] then - building_all_info = schem - break - end - end - - local pos = settlement_info[i]["pos"] - local rotation = settlement_info[i]["rotat"] - -- get building node material for better integration to surrounding - local platform_material = settlement_info[i]["surface_mat"] - platform_material_name = minetest.get_name_from_content_id(platform_material) - -- pick random material - --local material = wallmaterial[pr:next(1,#wallmaterial)] - -- - local building = building_all_info["mts"] - local replace_wall = building_all_info["rplc"] - -- schematic conversion to lua - local schem_lua = minetest.serialize_schematic(building, - "lua", - {lua_use_comments = false, lua_num_indent_spaces = 0}).." return(schematic)" - -- replace material - if replace_wall == "y" then - --Note, block substitution isn't matching node names exactly; so nodes that are to be substituted that have the same prefixes cause bugs. - -- Example: Attempting to swap out 'mcl_core:stonebrick'; which has multiple, additional sub-variants: (carved, cracked, mossy). Will currently cause issues, so leaving disabled. - if platform_material == "mcl_core:snow" or platform_material == "mcl_core:dirt_with_grass_snow" or platform_material == "mcl_core:podzol" then - schem_lua = schem_lua:gsub("mcl_core:tree", "mcl_core:sprucetree") - schem_lua = schem_lua:gsub("mcl_core:wood", "mcl_core:sprucewood") - --schem_lua = schem_lua:gsub("mcl_fences:fence", "mcl_fences:spruce_fence") - --schem_lua = schem_lua:gsub("mcl_stairs:slab_wood_top", "mcl_stairs:slab_sprucewood_top") - --schem_lua = schem_lua:gsub("mcl_stairs:stair_wood", "mcl_stairs:stair_sprucewood") - --schem_lua = schem_lua:gsub("mesecons_pressureplates:pressure_plate_wood_off", "mesecons_pressureplates:pressure_plate_sprucewood_off") - elseif platform_material == "mcl_core:sand" or platform_material == "mcl_core:redsand" then - schem_lua = schem_lua:gsub("mcl_core:tree", "mcl_core:sandstonecarved") - schem_lua = schem_lua:gsub("mcl_core:cobble", "mcl_core:sandstone") - schem_lua = schem_lua:gsub("mcl_core:wood", "mcl_core:sandstonesmooth") - --schem_lua = schem_lua:gsub("mcl_fences:fence", "mcl_fences:birch_fence") - --schem_lua = schem_lua:gsub("mcl_stairs:slab_wood_top", "mcl_stairs:slab_birchwood_top") - --schem_lua = schem_lua:gsub("mcl_stairs:stair_wood", "mcl_stairs:stair_birchwood") - --schem_lua = schem_lua:gsub("mesecons_pressureplates:pressure_plate_wood_off", "mesecons_pressureplates:pressure_plate_birchwood_off") - --schem_lua = schem_lua:gsub("mcl_stairs:stair_stonebrick", "mcl_stairs:stair_redsandstone") - --schem_lua = schem_lua:gsub("mcl_core:stonebrick", "mcl_core:redsandstonesmooth") - schem_lua = schem_lua:gsub("mcl_core:brick_block", "mcl_core:redsandstone") - end - end - schem_lua = schem_lua:gsub("mcl_core:dirt_with_grass", platform_material_name) - - --[[ Disable special junglewood for now. - -- special material for spawning npcs - schem_lua = schem_lua:gsub("mcl_core:junglewood", "settlements:junglewood") - --]] - -- format schematic string - local schematic = loadstring(schem_lua)() - -- build foundation for the building an make room above - -- place schematic - - minetest.place_schematic_on_vmanip( - vm, - pos, - schematic, - rotation, - nil, - true) - end -end -------------------------------------------------------------------------------- --- evaluate settlement_info and place schematics -------------------------------------------------------------------------------- function settlements.place_schematics(settlement_info, pr) local building_all_info for i, built_house in ipairs(settlement_info) do - for j, schem in ipairs(schematic_table) do + for j, schem in ipairs(settlements.schematic_table) do if settlement_info[i]["name"] == schem["name"] then building_all_info = schem break @@ -338,7 +177,7 @@ function settlements.place_schematics(settlement_info, pr) local pos = settlement_info[i]["pos"] local rotation = settlement_info[i]["rotat"] -- get building node material for better integration to surrounding - local platform_material = settlement_info[i]["surface_mat"] + local platform_material = settlement_info[i]["surface_mat"] --platform_material_name = minetest.get_name_from_content_id(platform_material) -- pick random material --local material = wallmaterial[pr:next(1,#wallmaterial)] @@ -350,7 +189,7 @@ function settlements.place_schematics(settlement_info, pr) "lua", {lua_use_comments = false, lua_num_indent_spaces = 0}).." return(schematic)" -- replace material - if replace_wall == "y" then + if replace_wall then --Note, block substitution isn't matching node names exactly; so nodes that are to be substituted that have the same prefixes cause bugs. -- Example: Attempting to swap out 'mcl_core:stonebrick'; which has multiple, additional sub-variants: (carved, cracked, mossy). Will currently cause issues, so leaving disabled. if platform_material == "mcl_core:snow" or platform_material == "mcl_core:dirt_with_grass_snow" or platform_material == "mcl_core:podzol" then diff --git a/mods/MAPGEN/mcl_villages/const.lua b/mods/MAPGEN/mcl_villages/const.lua index 20eeecd38..09c174342 100644 --- a/mods/MAPGEN/mcl_villages/const.lua +++ b/mods/MAPGEN/mcl_villages/const.lua @@ -5,11 +5,6 @@ settlements.debug = function(message) minetest.log("verbose", "[mcl_villages] "..message) end --- switch for lvm -settlements.lvm = false - -settlements.last_settlement = os.time() - --[[ Manually set in 'buildings.lua' -- material to replace cobblestone with wallmaterial = { @@ -56,43 +51,25 @@ schem_path = settlements.modpath.."/schematics/" -- local basic_pseudobiome_villages = minetest.settings:get_bool("basic_pseudobiome_villages", false) -if basic_pseudobiome_villages == true then - schematic_table = { - {name = "large_house", mts = schem_path.."large_house.mts", hwidth = 11, hdepth = 12, hheight = 9, hsize = 14, max_num = 0.08, rplc = "y"}, - {name = "blacksmith", mts = schem_path.."blacksmith.mts", hwidth = 7, hdepth = 7, hheight = 13, hsize = 13, max_num = 0.055, rplc = "y"}, - {name = "butcher", mts = schem_path.."butcher.mts", hwidth = 11, hdepth = 8, hheight = 10, hsize = 14, max_num = 0.03, rplc = "y"}, - {name = "church", mts = schem_path.."church.mts", hwidth = 13, hdepth = 13, hheight = 14, hsize = 15, max_num = 0.04, rplc = "y"}, - {name = "farm", mts = schem_path.."farm.mts", hwidth = 7, hdepth = 7, hheight = 13, hsize = 13, max_num = 0.1, rplc = "y"}, - {name = "lamp", mts = schem_path.."lamp.mts", hwidth = 3, hdepth = 3, hheight = 13, hsize = 10, max_num = 0.1, rplc = "n"}, - {name = "library", mts = schem_path.."library.mts", hwidth = 12, hdepth = 12, hheight = 8, hsize = 13, max_num = 0.04, rplc = "y"}, - {name = "medium_house", mts = schem_path.."medium_house.mts", hwidth = 8, hdepth = 12, hheight = 8, hsize = 14, max_num = 0.08, rplc = "y"}, - {name = "small_house", mts = schem_path.."small_house.mts", hwidth = 9, hdepth = 7, hheight = 8, hsize = 13, max_num = 0.7, rplc = "y"}, - {name = "tavern", mts = schem_path.."tavern.mts", hwidth = 11, hdepth = 10, hheight = 10, hsize = 13, max_num = 0.050, rplc = "y"}, - {name = "well", mts = schem_path.."well.mts", hwidth = 6, hdepth = 8, hheight = 6, hsize = 10, max_num = 0.045, rplc = "y"}, - } -else - schematic_table = { - {name = "large_house", mts = schem_path.."large_house.mts", hwidth = 11, hdepth = 12, hheight = 9, hsize = 14, max_num = 0.08, rplc = "n"}, - {name = "blacksmith", mts = schem_path.."blacksmith.mts", hwidth = 7, hdepth = 7, hheight = 13, hsize = 13, max_num = 0.055, rplc = "n"}, - {name = "butcher", mts = schem_path.."butcher.mts", hwidth = 11, hdepth = 8, hheight = 10, hsize = 14, max_num = 0.03, rplc = "n"}, - {name = "church", mts = schem_path.."church.mts", hwidth = 13, hdepth = 13, hheight = 14, hsize = 15, max_num = 0.04, rplc = "n"}, - {name = "farm", mts = schem_path.."farm.mts", hwidth = 7, hdepth = 7, hheight = 13, hsize = 13, max_num = 0.1, rplc = "n"}, - {name = "lamp", mts = schem_path.."lamp.mts", hwidth = 3, hdepth = 3, hheight = 13, hsize = 10, max_num = 0.1, rplc = "n"}, - {name = "library", mts = schem_path.."library.mts", hwidth = 12, hdepth = 12, hheight = 8, hsize = 13, max_num = 0.04, rplc = "n"}, - {name = "medium_house", mts = schem_path.."medium_house.mts", hwidth = 8, hdepth = 12, hheight = 8, hsize = 14, max_num = 0.08, rplc = "n"}, - {name = "small_house", mts = schem_path.."small_house.mts", hwidth = 9, hdepth = 7, hheight = 8, hsize = 13, max_num = 0.7, rplc = "n"}, - {name = "tavern", mts = schem_path.."tavern.mts", hwidth = 11, hdepth = 10, hheight = 10, hsize = 13, max_num = 0.050, rplc = "n"}, - {name = "well", mts = schem_path.."well.mts", hwidth = 6, hdepth = 8, hheight = 6, hsize = 10, max_num = 0.045, rplc = "n"}, - } -end +settlements.schematic_table = { + {name = "large_house", mts = schem_path.."large_house.mts", hwidth = 11, hdepth = 12, hheight = 9, hsize = 14, max_num = 0.08 , rplc = basic_pseudobiome_villages }, + {name = "blacksmith", mts = schem_path.."blacksmith.mts", hwidth = 7, hdepth = 7, hheight = 13, hsize = 13, max_num = 0.055, rplc = basic_pseudobiome_villages }, + {name = "butcher", mts = schem_path.."butcher.mts", hwidth = 11, hdepth = 8, hheight = 10, hsize = 14, max_num = 0.03 , rplc = basic_pseudobiome_villages }, + {name = "church", mts = schem_path.."church.mts", hwidth = 13, hdepth = 13, hheight = 14, hsize = 15, max_num = 0.04 , rplc = basic_pseudobiome_villages }, + {name = "farm", mts = schem_path.."farm.mts", hwidth = 7, hdepth = 7, hheight = 13, hsize = 13, max_num = 0.1 , rplc = basic_pseudobiome_villages }, + {name = "lamp", mts = schem_path.."lamp.mts", hwidth = 3, hdepth = 3, hheight = 13, hsize = 10, max_num = 0.1 , rplc = false }, + {name = "library", mts = schem_path.."library.mts", hwidth = 12, hdepth = 12, hheight = 8, hsize = 13, max_num = 0.04 , rplc = basic_pseudobiome_villages }, + {name = "medium_house", mts = schem_path.."medium_house.mts", hwidth = 8, hdepth = 12, hheight = 8, hsize = 14, max_num = 0.08 , rplc = basic_pseudobiome_villages }, + {name = "small_house", mts = schem_path.."small_house.mts", hwidth = 9, hdepth = 7, hheight = 8, hsize = 13, max_num = 0.7 , rplc = basic_pseudobiome_villages }, + {name = "tavern", mts = schem_path.."tavern.mts", hwidth = 11, hdepth = 10, hheight = 10, hsize = 13, max_num = 0.050, rplc = basic_pseudobiome_villages }, + {name = "well", mts = schem_path.."well.mts", hwidth = 6, hdepth = 8, hheight = 6, hsize = 10, max_num = 0.045, rplc = basic_pseudobiome_villages }, +} + -- -- list of settlements, load on server start up -- settlements_in_world = {} -- --- min_distance between settlements --- -settlements.min_dist_settlements = 64 -- -- maximum allowed difference in height for building a sttlement -- diff --git a/mods/MAPGEN/mcl_villages/convert_lua_mts.lua b/mods/MAPGEN/mcl_villages/convert_lua_mts.lua index e66905ba0..cf30e0066 100644 --- a/mods/MAPGEN/mcl_villages/convert_lua_mts.lua +++ b/mods/MAPGEN/mcl_villages/convert_lua_mts.lua @@ -1,23 +1,22 @@ -- function settlements.convert_mts_to_lua() - local building = schem_path.."townhall.mts" - local str = minetest.serialize_schematic(building, "lua", {lua_use_comments = true, lua_num_indent_spaces = 0}).." return(schematic)" - local schematic = loadstring(str)() - local file = io.open(schem_path.."church"..".lua", "w") - file:write(dump(schematic)) - file:close() -print(dump(schematic)) + local building = schem_path.."townhall.mts" + local str = minetest.serialize_schematic(building, "lua", {lua_use_comments = true, lua_num_indent_spaces = 0}).." return(schematic)" + local schematic = loadstring(str)() + local file = io.open(schem_path.."church"..".lua", "w") + file:write(dump(schematic)) + file:close() + print(dump(schematic)) end - function settlements.mts_save() - local f = assert(io.open(schem_path.."hut.lua", "r")) - local content = f:read("*all").." return(schematic2)" - f:close() + local f = assert(io.open(schem_path.."hut.lua", "r")) + local content = f:read("*all").." return(schematic2)" + f:close() - local schematic2 = loadstring("schematic2 = "..content)() - local seb = minetest.serialize_schematic(schematic2, "mts", {}) + local schematic2 = loadstring("schematic2 = "..content)() + local seb = minetest.serialize_schematic(schematic2, "mts", {}) local filename = schem_path .. "hut2" .. ".mts" filename = filename:gsub("\"", "\\\""):gsub("\\", "\\\\") local file, err = io.open(filename, "wb") @@ -27,4 +26,4 @@ function settlements.mts_save() file:close() end print("Wrote: " .. filename) -end \ No newline at end of file +end diff --git a/mods/MAPGEN/mcl_villages/foundation.lua b/mods/MAPGEN/mcl_villages/foundation.lua index 677b4efdb..15936ef4c 100644 --- a/mods/MAPGEN/mcl_villages/foundation.lua +++ b/mods/MAPGEN/mcl_villages/foundation.lua @@ -1,28 +1,6 @@ ------------------------------------------------------------------------------- -- function to fill empty space below baseplate when building on a hill ------------------------------------------------------------------------------- -function settlements.ground_lvm(pos, pr) -- role model: Wendelsteinkircherl, Brannenburg - local c_dirt = minetest.get_content_id("mcl_core:dirt") - local c_stone = minetest.get_content_id("mcl_core:stone") - -- - local p2 = vector.new(pos) - local cnt = 0 - local mat = c_dirt - p2.y = p2.y-1 - while true do - cnt = cnt+1 - if cnt > 20 then break end - if cnt>pr:next(2,4) then mat = c_stone end - --minetest.swap_node(p2, {name="mcl_core:"..mat}) - local vi = va:index(p2.x, p2.y, p2.z) - data[vi] = mat - p2.y = p2.y-1 - end - -- return data -end -------------------------------------------------------------------------------- --- function to fill empty space below baseplate when building on a hill -------------------------------------------------------------------------------- function settlements.ground(pos, pr) -- role model: Wendelsteinkircherl, Brannenburg local p2 = vector.new(pos) local cnt = 0 @@ -41,113 +19,47 @@ end ------------------------------------------------------------------------------- -- function clear space above baseplate ------------------------------------------------------------------------------- -function settlements.terraform_lvm(settlement_info, pr) - local c_air = minetest.get_content_id("air") - local fheight - local fwidth - local fdepth - - - for i, built_house in ipairs(settlement_info) do - -- pick right schematic_info to current built_house - for j, schem in ipairs(schematic_table) do - if settlement_info[i]["name"] == schem["name"] - then - schematic_data = schem - break - end - end - local pos = settlement_info[i]["pos"] - if settlement_info[i]["rotat"] == "0" or settlement_info[i]["rotat"] == "180" - then - fwidth = schematic_data["hwidth"] - fdepth = schematic_data["hdepth"] - else - fwidth = schematic_data["hdepth"] - fdepth = schematic_data["hwidth"] - end - fheight = schematic_data["hheight"] * 3 -- remove trees and leaves above - -- - -- now that every info is available -> create platform and clear space above - -- - for zi = 0,fdepth-1 do - for yi = 0,fheight do - for xi = 0,fwidth-1 do - if yi == 0 then - local p = {x=pos.x+xi, y=pos.y, z=pos.z+zi} - settlements.ground_lvm(p, pr) - else - --break --todo - -- write ground - local vi = va:index(pos.x+xi, pos.y+yi, pos.z+zi) - if data[vi] ~= c_air - --local node = minetest.get_node_or_nil({x=p5.x+xi, y=p5.y+yi, z=p5.z+zi}) - --if node then - --if node.name ~= "air" - then - --minetest.swap_node({x=pos.x+xi, y=pos.y+yi, z=pos.z+zi},{name="air"}) - data[vi] = c_air - end - end - end - end - end - - end -end -------------------------------------------------------------------------------- --- function clear space above baseplate -------------------------------------------------------------------------------- function settlements.terraform(settlement_info, pr) - local fheight - local fwidth - local fdepth - local schematic_data + local fheight, fwidth, fdepth, schematic_data - for i, built_house in ipairs(settlement_info) do - -- pick right schematic_info to current built_house - for j, schem in ipairs(schematic_table) do - if settlement_info[i]["name"] == schem["name"] - then - schematic_data = schem - break - end - end - local pos = settlement_info[i]["pos"] - if settlement_info[i]["rotat"] == "0" or settlement_info[i]["rotat"] == "180" - then - fwidth = schematic_data["hwidth"] - fdepth = schematic_data["hdepth"] - else - fwidth = schematic_data["hdepth"] - fdepth = schematic_data["hwidth"] - end - --fheight = schematic_data["hheight"] * 3 -- remove trees and leaves above - fheight = schematic_data["hheight"] -- remove trees and leaves above - -- - -- now that every info is available -> create platform and clear space above - -- - for xi = 0,fwidth-1 do - for zi = 0,fdepth-1 do - for yi = 0,fheight *3 do - if yi == 0 then - local p = {x=pos.x+xi, y=pos.y, z=pos.z+zi} - settlements.ground(p, pr) - else - -- write ground - local p = {x=pos.x+xi, y=pos.y+yi, z=pos.z+zi} - minetest.forceload_block(p) - local node = minetest.get_node_or_nil(p) - if node then - if node.name ~= "air" - then - minetest.swap_node(p,{name="air"}) - end - end - end - end - end - end - - end + for i, built_house in ipairs(settlement_info) do + -- pick right schematic_info to current built_house + for j, schem in ipairs(settlements.schematic_table) do + if settlement_info[i]["name"] == schem["name"] then + schematic_data = schem + break + end + end + local pos = settlement_info[i]["pos"] + if settlement_info[i]["rotat"] == "0" or settlement_info[i]["rotat"] == "180" then + fwidth = schematic_data["hwidth"] + fdepth = schematic_data["hdepth"] + else + fwidth = schematic_data["hdepth"] + fdepth = schematic_data["hwidth"] + end + --fheight = schematic_data["hheight"] * 3 -- remove trees and leaves above + fheight = schematic_data["hheight"] -- remove trees and leaves above + -- + -- now that every info is available -> create platform and clear space above + -- + for xi = 0,fwidth-1 do + for zi = 0,fdepth-1 do + for yi = 0,fheight *3 do + if yi == 0 then + local p = {x=pos.x+xi, y=pos.y, z=pos.z+zi} + settlements.ground(p, pr) + else + -- write ground + local p = {x=pos.x+xi, y=pos.y+yi, z=pos.z+zi} + minetest.forceload_block(p) + local node = minetest.get_node_or_nil(p) + if node and node.name ~= "air" then + minetest.swap_node(p,{name="air"}) + end + end + end + end + end + end end diff --git a/mods/MAPGEN/mcl_villages/init.lua b/mods/MAPGEN/mcl_villages/init.lua index a931d9523..61e370d58 100644 --- a/mods/MAPGEN/mcl_villages/init.lua +++ b/mods/MAPGEN/mcl_villages/init.lua @@ -1,20 +1,12 @@ --- eclipse debugging lines ---require("debugger")(idehost, ideport, idekey) - ---zerobrane debugging lines ---package.cpath = package.cpath .. ";/usr/share/lua/5.2/?.so" ---package.path = package.path .. ";/usr/share/zbstudio/lualibs/mobdebug/?.lua" ---require('mobdebug').start() - settlements = {} -settlements.modpath = minetest.get_modpath("mcl_villages"); +settlements.modpath = minetest.get_modpath("mcl_villages") dofile(settlements.modpath.."/const.lua") dofile(settlements.modpath.."/utils.lua") dofile(settlements.modpath.."/foundation.lua") dofile(settlements.modpath.."/buildings.lua") dofile(settlements.modpath.."/paths.lua") -dofile(settlements.modpath.."/convert_lua_mts.lua") +--dofile(settlements.modpath.."/convert_lua_mts.lua") -- -- load settlements on server -- @@ -55,42 +47,20 @@ end -- on map generation, try to build a settlement -- local function build_a_settlement_no_delay(minp, maxp, blockseed) - local settlement_info local pr = PseudoRandom(blockseed) - -- + -- fill settlement_info with buildings and their data - -- - if settlements.lvm == true then - -- get LVM of current chunk - local vm, data, va, emin, emax = settlements.getlvm(minp, maxp) - settlement_info = settlements.create_site_plan_lvm(maxp, minp, pr) - else - settlement_info = settlements.create_site_plan(maxp, minp, pr) - end + local settlement_info = settlements.create_site_plan(maxp, minp, pr) if not settlement_info then return end -- evaluate settlement_info and prepair terrain - if settlements.lvm == true then - settlements.terraform_lvm(settlement_info, pr) - else - settlements.terraform(settlement_info, pr) - end + settlements.terraform(settlement_info, pr) -- evaluate settlement_info and build paths between buildings - if settlements.lvm == true then - settlements.paths_lvm(settlement_info, minp) - else - settlements.paths(settlement_info) - end + settlements.paths(settlement_info) -- evaluate settlement_info and place schematics - if settlements.lvm == true then - vm:set_data(data) - settlements.place_schematics_lvm(settlement_info, pr) - vm:write_to_map(true) - else - settlements.place_schematics(settlement_info, pr) - end + settlements.place_schematics(settlement_info, pr) -- evaluate settlement_info and initialize furnaces and chests settlements.initialize_nodes(settlement_info, pr) @@ -112,126 +82,27 @@ minetest.register_on_generated(function(minp, maxp, blockseed) -- don't build settlement underground if maxp.y < 0 then return end - -- don't build settlements too close to each other - --[[ - local center_of_chunk = { - x=maxp.x-half_map_chunk_size, - y=maxp.y-half_map_chunk_size, - z=maxp.z-half_map_chunk_size - } - local dist_ok = settlements.check_distance_other_settlements(center_of_chunk) - if dist_ok == false then return end - ]] - -- don't build settlements on (too) uneven terrain local height_difference = settlements.evaluate_heightmap(minp, maxp) if height_difference > max_height_difference then return end + -- new way - slow :((((( minetest.emerge_area(vector.subtract(minp,24), vector.add(maxp,24), ecb_build_a_settlement, {minp = vector.new(minp), maxp=vector.new(maxp), blockseed=blockseed}) -- old way - wait 3 seconds: -- minetest.after(3, ecb_build_a_settlement, nil, 1, 0, {minp = vector.new(minp), maxp=vector.new(maxp), blockseed=blockseed}) end) --- --- manually place buildings, for debugging only --- -minetest.register_craftitem("mcl_villages:tool", { - description = "mcl_villages build tool", - inventory_image = "default_tool_woodshovel.png", - - --[[ Disable on_use for now. - -- build single house - -- - on_use = function(itemstack, placer, pointed_thing) - local center_surface = pointed_thing.under - if center_surface then - local building_all_info = {name = "blacksmith", - mts = schem_path.."blacksmith.mts", - hsize = 13, - max_num = 0.9, - rplc = "n"} - settlements.build_schematic(center_surface, - building_all_info["mts"], - building_all_info["rplc"], - building_all_info["name"]) - --- settlements.convert_mts_to_lua() --- settlements.mts_save() - end - end, ---]] - -- - -- build ssettlement - -- - on_place = function(itemstack, placer, pointed_thing) - local pr = PseudoRandom(math.random(0,32767)) - -- enable debug routines - local center_surface = pointed_thing.under - if center_surface then - local minp = { - x=center_surface.x-half_map_chunk_size, - y=center_surface.y-half_map_chunk_size, - z=center_surface.z-half_map_chunk_size - } - local maxp = { - x=center_surface.x+half_map_chunk_size, - y=center_surface.y+half_map_chunk_size, - z=center_surface.z+half_map_chunk_size - } - -- - -- get LVM of current chunk - -- - local vm, data, va, emin, emax = settlements.getlvm(minp, maxp) - -- - -- fill settlement_info with buildings and their data - -- - local start_time = os.time() - local settlement_info - if settlements.lvm == true then - settlement_info = settlements.create_site_plan_lvm(maxp, minp, pr) - else - settlement_info = settlements.create_site_plan(maxp, minp, pr) - end - if not settlement_info then return end - -- - -- evaluate settlement_info and prepair terrain - -- - if settlements.lvm == true then - settlements.terraform_lvm(settlement_info, pr) - else - settlements.terraform(settlement_info, pr) - end - - -- - -- evaluate settlement_info and build paths between buildings - -- - if settlements.lvm == true then - settlements.paths_lvm(settlement_info, minp) - else - settlements.paths(settlement_info) - end - -- - -- evaluate settlement_info and place schematics - -- - if settlements.lvm == true then - vm:set_data(data) - settlements.place_schematics_lvm(settlement_info, pr) - vm:write_to_map(true) - else - settlements.place_schematics(settlement_info, pr) - end - - -- - -- evaluate settlement_info and initialize furnaces and chests - -- - settlements.initialize_nodes(settlement_info, pr) - local end_time = os.time() - minetest.chat_send_all("Time ".. end_time - start_time) --- - --settlements.convert_mts_to_lua() - --settlements.mts_save() - - end - end - }) - +-- manually place villages +if minetest.is_creative_enabled("") then + minetest.register_craftitem("mcl_villages:tool", { + description = "mcl_villages build tool", + inventory_image = "default_tool_woodshovel.png", + -- build ssettlement + on_place = function(itemstack, placer, pointed_thing) + if not pointed_thing.under then return end + local minp = vector.subtract( pointed_thing.under, half_map_chunk_size) + local maxp = vector.add( pointed_thing.under, half_map_chunk_size) + build_a_settlement_no_delay(minp, maxp, math.random(0,32767)) + end + }) +end diff --git a/mods/MAPGEN/mcl_villages/paths.lua b/mods/MAPGEN/mcl_villages/paths.lua index 71347502d..4973171a6 100644 --- a/mods/MAPGEN/mcl_villages/paths.lua +++ b/mods/MAPGEN/mcl_villages/paths.lua @@ -1,99 +1,6 @@ ------------------------------------------------------------------------------- -- generate paths between buildings ------------------------------------------------------------------------------- -function settlements.paths_lvm(settlement_info, minp) - local c_grasspath = minetest.get_content_id("mcl_core:grass_path") - local starting_point - local end_point - local distance - --for k,v in pairs(settlement_info) do - starting_point = settlement_info[1]["pos"] - for o,p in pairs(settlement_info) do - - end_point = settlement_info[o]["pos"] - if starting_point ~= end_point - then - -- loop until end_point is reched (distance == 0) - while true do - - -- define surrounding pos to starting_point - local north_p = {x=starting_point.x+1, y=starting_point.y, z=starting_point.z} - local south_p = {x=starting_point.x-1, y=starting_point.y, z=starting_point.z} - local west_p = {x=starting_point.x, y=starting_point.y, z=starting_point.z+1} - local east_p = {x=starting_point.x, y=starting_point.y, z=starting_point.z-1} - -- measure distance to end_point - local dist_north_p_to_end = math.sqrt( - ((north_p.x - end_point.x)*(north_p.x - end_point.x))+ - ((north_p.z - end_point.z)*(north_p.z - end_point.z)) - ) - local dist_south_p_to_end = math.sqrt( - ((south_p.x - end_point.x)*(south_p.x - end_point.x))+ - ((south_p.z - end_point.z)*(south_p.z - end_point.z)) - ) - local dist_west_p_to_end = math.sqrt( - ((west_p.x - end_point.x)*(west_p.x - end_point.x))+ - ((west_p.z - end_point.z)*(west_p.z - end_point.z)) - ) - local dist_east_p_to_end = math.sqrt( - ((east_p.x - end_point.x)*(east_p.x - end_point.x))+ - ((east_p.z - end_point.z)*(east_p.z - end_point.z)) - ) - -- evaluate which pos is closer to the end_point - if dist_north_p_to_end <= dist_south_p_to_end and - dist_north_p_to_end <= dist_west_p_to_end and - dist_north_p_to_end <= dist_east_p_to_end - then - starting_point = north_p - distance = dist_north_p_to_end - - elseif dist_south_p_to_end <= dist_north_p_to_end and - dist_south_p_to_end <= dist_west_p_to_end and - dist_south_p_to_end <= dist_east_p_to_end - then - starting_point = south_p - distance = dist_south_p_to_end - - elseif dist_west_p_to_end <= dist_north_p_to_end and - dist_west_p_to_end <= dist_south_p_to_end and - dist_west_p_to_end <= dist_east_p_to_end - then - starting_point = west_p - distance = dist_west_p_to_end - - elseif dist_east_p_to_end <= dist_north_p_to_end and - dist_east_p_to_end <= dist_south_p_to_end and - dist_east_p_to_end <= dist_west_p_to_end - then - starting_point = east_p - distance = dist_east_p_to_end - end - -- find surface of new starting point - local surface_point, surface_mat = settlements.find_surface_lvm(starting_point, minp) - -- replace surface node with mcl_core:grass_path - if surface_point - then - local vi = va:index(surface_point.x, surface_point.y, surface_point.z) - data[vi] = c_grasspath - - --minetest.swap_node(surface_point,{name="mcl_core:grass_path"}) - -- don't set y coordinate, surface might be too low or high - starting_point.x = surface_point.x - starting_point.z = surface_point.z - end - if distance <= 1 or - starting_point == end_point - then - break - end - end - end - end - --end - --return data -end -------------------------------------------------------------------------------- --- generate paths between buildings -------------------------------------------------------------------------------- function settlements.paths(settlement_info) local starting_point local end_point diff --git a/mods/MAPGEN/mcl_villages/utils.lua b/mods/MAPGEN/mcl_villages/utils.lua index c55a55adb..96d540b57 100644 --- a/mods/MAPGEN/mcl_villages/utils.lua +++ b/mods/MAPGEN/mcl_villages/utils.lua @@ -1,5 +1,3 @@ -mcl_villages = {} - local c_dirt_with_grass = minetest.get_content_id("mcl_core:dirt_with_grass") local c_dirt_with_snow = minetest.get_content_id("mcl_core:dirt_with_grass_snow") --local c_dirt_with_dry_grass = minetest.get_content_id("mcl_core:dirt_with_dry_grass") @@ -43,57 +41,6 @@ function settlements.round(num, numDecimalPlaces) return math.floor(num * mult + 0.5) / mult end -------------------------------------------------------------------------------- --- function to find surface block y coordinate -------------------------------------------------------------------------------- -function settlements.find_surface_lvm(pos, minp) - --ab hier altes verfahren - local p6 = vector.new(pos) - local surface_mat = { - c_dirt_with_grass, - c_dirt_with_snow, - --c_dirt_with_dry_grass, - c_podzol, - c_sand, - c_desert_sand, - c_snow - } - local cnt = 0 - local itter -- count up or down - local cnt_max = 200 - -- starting point for looking for surface - local vi = va:index(p6.x, p6.y, p6.z) - if data[vi] == nil then return nil end - local tmp = minetest.get_name_from_content_id(data[vi]) - if data[vi] == c_air then - itter = -1 - else - itter = 1 - end - while cnt < cnt_max do - cnt = cnt+1 - local vi = va:index(p6.x, p6.y, p6.z) --- local tmp = minetest.get_name_from_content_id(data[vi]) --- if vi == nil --- then --- return nil --- end - for i, mats in ipairs(surface_mat) do - local node_check = va:index(p6.x, p6.y+1, p6.z) - if node_check and vi and data[vi] == mats and - (data[node_check] ~= c_water_source and - data[node_check] ~= c_water_flowing - ) - then - local tmp = minetest.get_name_from_content_id(data[node_check]) - return p6, mats - end - end - p6.y = p6.y + itter - if p6.y < 0 then return nil end - end - return nil --]] -end ------------------------------------------------------------------------------- -- function to find surface block y coordinate -- returns surface postion @@ -170,79 +117,58 @@ end -- check distance for new building ------------------------------------------------------------------------------- function settlements.check_distance(settlement_info, building_pos, building_size) - local distance - for i, built_house in ipairs(settlement_info) do - distance = math.sqrt( - ((building_pos.x - built_house["pos"].x)*(building_pos.x - built_house["pos"].x))+ - ((building_pos.z - built_house["pos"].z)*(building_pos.z - built_house["pos"].z))) - if distance < building_size or - distance < built_house["hsize"] - then - return false - end - end - return true -end -------------------------------------------------------------------------------- --- save list of generated settlements -------------------------------------------------------------------------------- -function settlements.save() - local file = io.open(minetest.get_worldpath().."/settlements.txt", "w") - if file then - file:write(minetest.serialize(settlements_in_world)) - file:close() - end -end -------------------------------------------------------------------------------- --- load list of generated settlements -------------------------------------------------------------------------------- -function settlements.load() - local file = io.open(minetest.get_worldpath().."/settlements.txt", "r") - if file then - local table = minetest.deserialize(file:read("*all")) - if type(table) == "table" then - return table - end - end - return {} -end -------------------------------------------------------------------------------- --- check distance to other settlements -------------------------------------------------------------------------------- ---[[ -function settlements.check_distance_other_settlements(center_new_chunk) - -- local min_dist_settlements = 300 - for i, pos in ipairs(settlements_in_world) do - local distance = vector.distance(center_new_chunk, pos) - -- minetest.chat_send_all("dist ".. distance) - if distance < settlements.min_dist_settlements then + local distance + for i, built_house in ipairs(settlement_info) do + distance = math.sqrt( + ((building_pos.x - built_house["pos"].x)*(building_pos.x - built_house["pos"].x))+ + ((building_pos.z - built_house["pos"].z)*(building_pos.z - built_house["pos"].z))) + if distance < building_size or distance < built_house["hsize"] then return false end end return true end -]] +------------------------------------------------------------------------------- +-- save list of generated settlements +------------------------------------------------------------------------------- +function settlements.save() + local file = io.open(minetest.get_worldpath().."/settlements.txt", "w") + if file then + file:write(minetest.serialize(settlements_in_world)) + file:close() + end +end +------------------------------------------------------------------------------- +-- load list of generated settlements +------------------------------------------------------------------------------- +function settlements.load() + local file = io.open(minetest.get_worldpath().."/settlements.txt", "r") + if file then + local table = minetest.deserialize(file:read("*all")) + if type(table) == "table" then + return table + end + end + return {} +end ------------------------------------------------------------------------------- -- fill chests ------------------------------------------------------------------------------- function settlements.fill_chest(pos, pr) - -- find chests within radius - --local chestpos = minetest.find_node_near(pos, 6, {"mcl_core:chest"}) - local chestpos = pos - -- initialize chest (mts chests don't have meta) - local meta = minetest.get_meta(chestpos) - if meta:get_string("infotext") ~= "Chest" then - -- For MineClone2 0.70 or before - -- minetest.registered_nodes["mcl_chests:chest"].on_construct(chestpos) - -- - -- For MineClone2 after commit 09ab1482b5 (the new entity chests) - minetest.registered_nodes["mcl_chests:chest_small"].on_construct(chestpos) - end - -- fill chest - local inv = minetest.get_inventory( {type="node", pos=chestpos} ) - function mcl_villages.get_treasures(pr) - local loottable = { - { + -- initialize chest (mts chests don't have meta) + local meta = minetest.get_meta(pos) + if meta:get_string("infotext") ~= "Chest" then + -- For MineClone2 0.70 or before + -- minetest.registered_nodes["mcl_chests:chest"].on_construct(pos) + -- + -- For MineClone2 after commit 09ab1482b5 (the new entity chests) + minetest.registered_nodes["mcl_chests:chest_small"].on_construct(pos) + end + -- fill chest + local inv = minetest.get_inventory( {type="node", pos=pos} ) + + local function get_treasures(pr) + local loottable = {{ stacks_min = 3, stacks_max = 8, items = { @@ -264,14 +190,13 @@ function settlements.fill_chest(pos, pr) { itemstring = "mobs_mc:gold_horse_armor", weight = 1 }, { itemstring = "mobs_mc:diamond_horse_armor", weight = 1 }, } - }, - } + }} local items = mcl_loot.get_multi_loot(loottable, pr) return items end -local items = mcl_villages.get_treasures(pr) -mcl_loot.fill_inventory(inv, "main", items) + local items = get_treasures(pr) + mcl_loot.fill_inventory(inv, "main", items) end ------------------------------------------------------------------------------- @@ -316,23 +241,23 @@ end local building_all_info function settlements.initialize_nodes(settlement_info, pr) for i, built_house in ipairs(settlement_info) do - for j, schem in ipairs(schematic_table) do + for j, schem in ipairs(settlements.schematic_table) do if settlement_info[i]["name"] == schem["name"] then building_all_info = schem break end end - local width = building_all_info["hwidth"] - local depth = building_all_info["hdepth"] - local height = building_all_info["hheight"] + local width = building_all_info["hwidth"] + local depth = building_all_info["hdepth"] + local height = building_all_info["hheight"] local p = settlement_info[i]["pos"] for yi = 1,height do for xi = 0,width do for zi = 0,depth do local ptemp = {x=p.x+xi, y=p.y+yi, z=p.z+zi} - local node = minetest.get_node(ptemp) + local node = minetest.get_node(ptemp) if node.name == "mcl_furnaces:furnace" or node.name == "mcl_chests:chest" or node.name == "mcl_anvils:anvil" then @@ -403,32 +328,11 @@ function settlements.evaluate_heightmap() return height_diff end ------------------------------------------------------------------------------- --- get LVM of current chunk -------------------------------------------------------------------------------- -function settlements.getlvm(minp, maxp) - local vm = minetest.get_voxel_manip() - local emin, emax = vm:read_from_map(minp, maxp) - local va = VoxelArea:new{ - MinEdge = emin, - MaxEdge = emax - } - local data = vm:get_data() - return vm, data, va, emin, emax -end -------------------------------------------------------------------------------- --- get LVM of current chunk -------------------------------------------------------------------------------- -function settlements.setlvm(vm, data) - -- Write data - vm:set_data(data) - vm:write_to_map(true) -end -------------------------------------------------------------------------------- -- Set array to list -- https://stackoverflow.com/questions/656199/search-for-an-item-in-a-lua-list ------------------------------------------------------------------------------- function settlements.Set (list) - local set = {} - for _, l in ipairs(list) do set[l] = true end - return set + local set = {} + for _, l in ipairs(list) do set[l] = true end + return set end