Break villages

This commit is contained in:
kay27 2022-02-06 06:46:21 +04:00
parent 991a08636c
commit 4ae1bf711d
5 changed files with 57 additions and 131 deletions

View File

@ -480,7 +480,6 @@ function mcl_mapgen.get_voxel_manip(vm_context)
return vm_context.vm return vm_context.vm
end end
local CS_NODES = mcl_mapgen.CS_NODES
function mcl_mapgen.clamp_to_chunk(x, size) function mcl_mapgen.clamp_to_chunk(x, size)
if not size then if not size then
minetest.log("warning", "[mcl_mapgen] Couldn't clamp " .. tostring(x) .. " - missing size") 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 end
return x - overflow return x - overflow
end end
function mcl_mapgen.get_chunk_beginning(x) function mcl_mapgen.get_chunk_beginning(x)
return x - ((x + central_chunk_min_pos) % CS_NODES) return x - ((x + central_chunk_min_pos) % CS_NODES)
end end
function mcl_mapgen.get_chunk_ending(x)
return mcl_mapgen.get_chunk_beginning(x) + LAST_NODE_IN_CHUNK
end

View File

@ -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) function settlements.initialize_settlement_info(pr)
local count_buildings = {} local count_buildings = {}
@ -75,18 +16,14 @@ end
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- fill settlement_info -- 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 settlement_info = {}
local building_all_info local building_all_info
local possible_rotations = {"0", "90", "180", "270"}
-- find center of chunk -- find center of chunk
local center = { local center = vector.add(minp, mcl_mapgen.HALF_CS_NODES)
x=math.floor((minp.x+maxp.x)/2),
y=maxp.y,
z=math.floor((minp.z+maxp.z)/2)
}
-- find center_surface of chunk -- 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 = {} local chunks = {}
chunks[mcl_mapgen.get_chunk_number(center)] = true 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) pos_surface, surface_material = settlements.find_surface(pos1)
else else
chunks[chunk_number] = true chunks[chunk_number] = true
pos_surface, surface_material = settlements.find_surface(pos1, true) pos_surface, surface_material = settlements.find_surface(pos1)
end end
if not pos_surface then break end if not pos_surface then break end

View File

@ -59,7 +59,7 @@ local function build_a_settlement(minp, maxp, blockseed)
local pr = PseudoRandom(blockseed) local pr = PseudoRandom(blockseed)
-- fill settlement_info with buildings and their data -- 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 if not settlement_info then return end
-- evaluate settlement_info and prepair terrain -- evaluate settlement_info and prepair terrain
@ -74,33 +74,37 @@ end
-- Disable natural generation in singlenode. -- Disable natural generation in singlenode.
local mg_name = minetest.get_mapgen_setting("mg_name") 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 if mg_name ~= "singlenode" then
mcl_mapgen.register_mapgen(function(minp, maxp, blockseed) mcl_mapgen.register_mapgen(function(minp, maxp, blockseed)
-- local str1 = (maxp.y >= 0 and blockseed % 77 == 17) and "YES" or "no" -- 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)) -- 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 -- 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 -- 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 -- 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: -- 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 min, max = 9999999, -9999999
local pr1=PseudoRandom(blockseed) local pr = PseudoRandom(blockseed)
for i=1,pr1:next(5,10) do for i = 1, pr:next(5,10) do
local x = pr1:next(0, 40) + minp.x + 19 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 z = pr1:next(0, 40) + minp.z + 19 local surface_point = settlements.find_surface(pos)
local y = minetest_get_spawn_level(x, z) if not surface_point then return end
if not y then return end local y = surface_point.y
if y < (min or y+1) then min = y end min = math.min(y, min)
if y > (max or y-1) then max = y end max = math.max(y, max)
end 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) build_a_settlement(minp, maxp, blockseed)
end, mcl_mapgen.order.VILLAGES) end, mcl_mapgen.order.VILLAGES)

View File

@ -1,5 +1,5 @@
name = mcl_villages name = mcl_villages
author = Rochambeau author = Rochambeau, MysticTempest, kay27
description = This mod adds settlements on world generation. 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 optional_depends = mcl_farming, mobs_mc

View File

@ -1,4 +1,4 @@
local get_node = mcl_mapgen.get_far_node local get_node = minetest.get_node
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- function to copy tables -- function to copy tables
@ -22,55 +22,36 @@ end
-- function to find surface block y coordinate -- function to find surface block y coordinate
-- returns surface postion -- returns surface postion
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
function settlements.find_surface(pos, wait) function settlements.find_surface(pos)
local p6 = vector.new(pos) local p6 = vector.new(pos)
local cnt = 0 p6.y = mcl_mapgen.get_chunk_ending(p6.y)
local itter = 1 -- count up or down local ymin = mcl_mapgen.get_chunk_beginning(p6.y)
local cnt_max = 200 local node = get_node(p6)
-- check, in which direction to look for surface minetest.chat_send_all(node.name)
local surface_node if node.name ~= "air" then return end
if wait then while true do
surface_node = get_node(p6, true, 10000000) p6.y = p6.y - 1
else if p6.y < ymin then return end
surface_node = get_node(p6) node = get_node(p6)
if settlements.surface_mat[node.name] then
break
end 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))
end end
minetest.chat_send_all(node.name)
p6.y = p6.y + itter local prev_node = minetest.get_node(vector.new(p6.x, p6.y + 1, p6.z))
if p6.y < 0 then local name = prev_node.name
settlements.debug("find_surface4: y<0") if (string.find(name, "air")
return nil 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 end
cnt = cnt+1
surface_node = get_node(p6)
end
settlements.debug("find_surface5: cnt_max overflow")
return nil
end end
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- check distance for new building -- check distance for new building