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
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

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)
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

View File

@ -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)

View File

@ -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

View File

@ -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)
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
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
minetest.chat_send_all(node.name)
p6.y = p6.y + itter
if p6.y < 0 then
settlements.debug("find_surface4: y<0")
return nil
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
cnt = cnt+1
surface_node = get_node(p6)
end
settlements.debug("find_surface5: cnt_max overflow")
return nil
end
-------------------------------------------------------------------------------
-- check distance for new building