diff --git a/mods/CORE/mcl_mapgen/init.lua b/mods/CORE/mcl_mapgen/init.lua index d751e9eb4..3cc455a88 100644 --- a/mods/CORE/mcl_mapgen/init.lua +++ b/mods/CORE/mcl_mapgen/init.lua @@ -480,7 +480,6 @@ function mcl_mapgen.get_voxel_manip(vm_context) return vm_context.vm end -local CS_NODES = mcl_mapgen.CS_NODES function mcl_mapgen.clamp_to_chunk(x, size) if not size then minetest.log("warning", "[mcl_mapgen] Couldn't clamp " .. tostring(x) .. " - missing size") @@ -504,6 +503,11 @@ function mcl_mapgen.clamp_to_chunk(x, size) end return x - overflow end + function mcl_mapgen.get_chunk_beginning(x) return x - ((x + central_chunk_min_pos) % CS_NODES) end + +function mcl_mapgen.get_chunk_ending(x) + return mcl_mapgen.get_chunk_beginning(x) + LAST_NODE_IN_CHUNK +end diff --git a/mods/MAPGEN/mcl_villages/buildings.lua b/mods/MAPGEN/mcl_villages/buildings.lua index 0860ce9a5..2e9011a22 100644 --- a/mods/MAPGEN/mcl_villages/buildings.lua +++ b/mods/MAPGEN/mcl_villages/buildings.lua @@ -1,62 +1,3 @@ ---[[ -------------------------------------------------------------------------------- --- build schematic, replace material, rotation -------------------------------------------------------------------------------- -function settlements.build_schematic(vm, data, va, pos, building, replace_wall, name) - -- get building node material for better integration to surrounding - local platform_material = mcl_vars.get_node(pos) - if not platform_material or (platform_material.name == "air" or platform_material.name == "ignore") then - return - end - platform_material = platform_material.name - -- pick random material - local material = wallmaterial[math.random(1,#wallmaterial)] - -- 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 - schem_lua = schem_lua:gsub("mcl_core:cobble", material) - end - schem_lua = schem_lua:gsub("mcl_core:dirt_with_grass", - platform_material) - --- 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 - local width = schematic["size"]["x"] - local depth = schematic["size"]["z"] - local height = schematic["size"]["y"] - local possible_rotations = {"0", "90", "180", "270"} - local rotation = possible_rotations[ math.random( #possible_rotations ) ] - settlements.foundation( - pos, - width, - depth, - height, - rotation) - vm:set_data(data) - -- place schematic - - minetest.place_schematic_on_vmanip( - vm, - pos, - schematic, - rotation, - nil, - true) - vm:write_to_map(true) -end]] -------------------------------------------------------------------------------- --- initialize settlement_info -------------------------------------------------------------------------------- function settlements.initialize_settlement_info(pr) local count_buildings = {} @@ -75,18 +16,14 @@ end ------------------------------------------------------------------------------- -- fill settlement_info -------------------------------------------------------------------------------- -function settlements.create_site_plan(maxp, minp, pr) +local possible_rotations = {"0", "90", "180", "270"} +function settlements.create_site_plan(minp, maxp, pr) local settlement_info = {} local building_all_info - local possible_rotations = {"0", "90", "180", "270"} -- find center of chunk - local center = { - x=math.floor((minp.x+maxp.x)/2), - y=maxp.y, - z=math.floor((minp.z+maxp.z)/2) - } + local center = vector.add(minp, mcl_mapgen.HALF_CS_NODES) -- find center_surface of chunk - local center_surface , surface_material = settlements.find_surface(center, true) + local center_surface , surface_material = settlements.find_surface(center) local chunks = {} chunks[mcl_mapgen.get_chunk_number(center)] = true @@ -130,7 +67,7 @@ function settlements.create_site_plan(maxp, minp, pr) pos_surface, surface_material = settlements.find_surface(pos1) else chunks[chunk_number] = true - pos_surface, surface_material = settlements.find_surface(pos1, true) + pos_surface, surface_material = settlements.find_surface(pos1) end if not pos_surface then break end diff --git a/mods/MAPGEN/mcl_villages/init.lua b/mods/MAPGEN/mcl_villages/init.lua index 47ca91f2e..fa4f2b7b7 100644 --- a/mods/MAPGEN/mcl_villages/init.lua +++ b/mods/MAPGEN/mcl_villages/init.lua @@ -59,7 +59,7 @@ local function build_a_settlement(minp, maxp, blockseed) local pr = PseudoRandom(blockseed) -- fill settlement_info with buildings and their data - local settlement_info = settlements.create_site_plan(maxp, minp, pr) + local settlement_info = settlements.create_site_plan(minp, maxp, pr) if not settlement_info then return end -- evaluate settlement_info and prepair terrain @@ -74,33 +74,37 @@ end -- Disable natural generation in singlenode. local mg_name = minetest.get_mapgen_setting("mg_name") +local scan_last_node = (mcl_mapgen.CS - 2) * mcl_mapgen.BS - 1 +local scan_offset = mcl_mapgen.BS if mg_name ~= "singlenode" then mcl_mapgen.register_mapgen(function(minp, maxp, blockseed) -- local str1 = (maxp.y >= 0 and blockseed % 77 == 17) and "YES" or "no" -- minetest.log("action","[mcl_villages] " .. str1 .. ": minp=" .. minetest.pos_to_string(minp) .. ", maxp=" .. minetest.pos_to_string(maxp) .. ", blockseed=" .. tostring(blockseed)) -- don't build settlement underground - if maxp.y < 0 then return end + local y_max = maxp.y + if y_max < -30 then return end -- randomly try to build settlements - if blockseed % 77 ~= 17 then return end + -- if blockseed % 77 ~= 17 then return end -- don't build settlements on (too) uneven terrain -- lame and quick replacement of `heightmap` by kay27 - we maybe need to restore `heightmap` analysis if there will be a way for the engine to avoid cavegen conflicts: -------------------------------------------------------------------------- - local height_difference, min, max - local pr1=PseudoRandom(blockseed) - for i=1,pr1:next(5,10) do - local x = pr1:next(0, 40) + minp.x + 19 - local z = pr1:next(0, 40) + minp.z + 19 - local y = minetest_get_spawn_level(x, z) - if not y then return end - if y < (min or y+1) then min = y end - if y > (max or y-1) then max = y end + local min, max = 9999999, -9999999 + local pr = PseudoRandom(blockseed) + for i = 1, pr:next(5,10) do + local pos = vector.add(vector.new(pr:next(0, scan_last_node) + scan_offset, 0, pr:next(0, scan_last_node) + scan_offset), minp) + local surface_point = settlements.find_surface(pos) + if not surface_point then return end + local y = surface_point.y + min = math.min(y, min) + max = math.max(y, max) end - height_difference = max - min + 1 + local height_difference = max - min -------------------------------------------------------------------------- - if height_difference > max_height_difference then return end + minetest.chat_send_all("height diff="..height_difference) + if height_difference > 10 then return end build_a_settlement(minp, maxp, blockseed) end, mcl_mapgen.order.VILLAGES) diff --git a/mods/MAPGEN/mcl_villages/mod.conf b/mods/MAPGEN/mcl_villages/mod.conf index d8e2aa7d4..c8e0d8149 100644 --- a/mods/MAPGEN/mcl_villages/mod.conf +++ b/mods/MAPGEN/mcl_villages/mod.conf @@ -1,5 +1,5 @@ name = mcl_villages -author = Rochambeau +author = Rochambeau, MysticTempest, kay27 description = This mod adds settlements on world generation. -depends = mcl_util, mcl_mapgen_core, mcl_structures, mcl_core, mcl_loot +depends = mcl_util, mcl_mapgen_core, mcl_structures, mcl_core, mcl_loot, mcl_mapgen optional_depends = mcl_farming, mobs_mc diff --git a/mods/MAPGEN/mcl_villages/utils.lua b/mods/MAPGEN/mcl_villages/utils.lua index 1d94ead0c..589b04403 100644 --- a/mods/MAPGEN/mcl_villages/utils.lua +++ b/mods/MAPGEN/mcl_villages/utils.lua @@ -1,4 +1,4 @@ -local get_node = mcl_mapgen.get_far_node +local get_node = minetest.get_node ------------------------------------------------------------------------------- -- function to copy tables @@ -22,55 +22,36 @@ end -- function to find surface block y coordinate -- returns surface postion ------------------------------------------------------------------------------- -function settlements.find_surface(pos, wait) +function settlements.find_surface(pos) local p6 = vector.new(pos) - local cnt = 0 - local itter = 1 -- count up or down - local cnt_max = 200 - -- check, in which direction to look for surface - local surface_node - if wait then - surface_node = get_node(p6, true, 10000000) - else - surface_node = get_node(p6) - end - if surface_node.name=="air" or surface_node.name=="ignore" then - itter = -1 - end - -- go through nodes an find surface - while cnt < cnt_max do - -- Check Surface_node and Node above - -- - if settlements.surface_mat[surface_node.name] then - local surface_node_plus_1 = get_node({ x=p6.x, y=p6.y+1, z=p6.z}) - if surface_node_plus_1 and surface_node and - (string.find(surface_node_plus_1.name,"air") or - string.find(surface_node_plus_1.name,"snow") or - string.find(surface_node_plus_1.name,"fern") or - string.find(surface_node_plus_1.name,"flower") or - string.find(surface_node_plus_1.name,"bush") or - string.find(surface_node_plus_1.name,"tree") or - string.find(surface_node_plus_1.name,"grass")) - then - settlements.debug("find_surface7: " ..surface_node.name.. " " .. surface_node_plus_1.name) - return p6, surface_node.name - else - settlements.debug("find_surface2: wrong surface+1") - end - else - settlements.debug("find_surface3: wrong surface "..surface_node.name.." at pos "..minetest.pos_to_string(p6)) + p6.y = mcl_mapgen.get_chunk_ending(p6.y) + local ymin = mcl_mapgen.get_chunk_beginning(p6.y) + local node = get_node(p6) + minetest.chat_send_all(node.name) + if node.name ~= "air" then return end + while true do + p6.y = p6.y - 1 + if p6.y < ymin then return end + node = get_node(p6) + if settlements.surface_mat[node.name] then + break end + end + minetest.chat_send_all(node.name) - p6.y = p6.y + itter - if p6.y < 0 then - settlements.debug("find_surface4: y<0") - return nil - end - cnt = cnt+1 - surface_node = get_node(p6) + local prev_node = minetest.get_node(vector.new(p6.x, p6.y + 1, p6.z)) + local name = prev_node.name + if (string.find(name, "air") + or string.find(name, "snow") + or string.find(name, "fern") + or string.find(name, "flower") + or string.find(name, "bush") + or string.find(name, "tree") + or string.find(name, "grass") + ) then + minetest.chat_send_all("found! "..node.name..", "..minetest.pos_to_string(p6)) + return p6, node.name end - settlements.debug("find_surface5: cnt_max overflow") - return nil end ------------------------------------------------------------------------------- -- check distance for new building