optimizing and banchmarking lvm versus get/set_node

master
Rochambeau 2018-07-29 20:41:28 +02:00
parent 3a7e65d8ad
commit a205ecec4f
8 changed files with 7494 additions and 397 deletions

View File

@ -1,16 +1,12 @@
local count_buildings ={} local count_buildings ={}
-- iterate over whole table to get all keys -- iterate over whole table to get all keys
local keyset = {}
for k in pairs(schematic_table) do
table.insert(keyset, k)
end
--local variables for buildings --local variables for buildings
local building_all_info local building_all_info
local number_of_buildings local number_of_buildings
local number_built local number_built
-- -------------------------------------------------------------------------------
-- build schematic, replace material, rotation -- build schematic, replace material, rotation
-- -------------------------------------------------------------------------------
function settlements.build_schematic(vm, data, va, pos, building, replace_wall, name) function settlements.build_schematic(vm, data, va, pos, building, replace_wall, name)
-- get building node material for better integration to surrounding -- get building node material for better integration to surrounding
local platform_material = minetest.get_node_or_nil(pos) local platform_material = minetest.get_node_or_nil(pos)
@ -42,199 +38,27 @@ function settlements.build_schematic(vm, data, va, pos, building, replace_wall,
local possible_rotations = {"0", "90", "180", "270"} local possible_rotations = {"0", "90", "180", "270"}
local rotation = possible_rotations[ math.random( #possible_rotations ) ] local rotation = possible_rotations[ math.random( #possible_rotations ) ]
settlements.foundation( settlements.foundation(
vm,
data,
va,
pos, pos,
width, width,
depth, depth,
height, height,
rotation) rotation)
vm:set_data(data)
-- place schematic -- place schematic
minetest.after(3, function() --increase waiting time, if "block not found" in debug.txt
minetest.place_schematic(pos, minetest.place_schematic_on_vmanip(
schematic, vm,
rotation, pos,
nil, schematic,
true) rotation,
-- initialize special nodes (chests, furnace) nil,
minetest.after(2, settlements.initialize_nodes, pos, width, depth, height) true)
end) vm:write_to_map(true)
end end
-- -------------------------------------------------------------------------------
-- placing buildings within lvm -- initialize settlement_info
-- -------------------------------------------------------------------------------
function settlements.place_settlement_lvm(vm, data, va, minp, maxp) function settlements.initialize_settlement_info()
-- 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_surcafe of chunk
local center_surface = settlements.find_surface_lvm(center, data, va)
-- go build settlement around center
if center_surface then
-- add settlement to list
table.insert(settlements_in_world,
center_surface)
-- save list to file
settlements.save()
-- initialize all settlement information
settlements.initialize_settlement()
-- build well in the center
building_all_info = schematic_table[1]
settlements.build_schematic(
vm,
data,
va,
center_surface,
building_all_info["mts"],
building_all_info["rplc"],
building_all_info["name"])
-- add to settlement info table
local index = 1
settlement_info[index] = {pos = center_surface,
name = building_all_info["name"],
hsize = building_all_info["hsize"]}
--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, z=ptz}
--
local pos_surface = settlements.find_surface_lvm(pos1, data, va)
--local pos_surface = settlements.find_surface(pos1)
if pos_surface
then
if settlements.pick_next_building(pos_surface)
then
settlements.build_schematic(
vm,
data,
va,
pos_surface,
building_all_info["mts"],
building_all_info["rplc"],
building_all_info["name"]
)
number_built = number_built + 1
settlement_info[index] = {
pos = pos_surface,
name = building_all_info["name"],
hsize = building_all_info["hsize"]
}
index = index + 1
if number_of_buildings == number_built
then
break
end
end
else
break
end
end
r = r + math.random(2,5)
end
end
if settlements.debug == true
then
minetest.chat_send_all("really ".. number_built)
end
minetest.after(2, settlements.paths)
-- settlements.paths()
end
end
--
-- placing buildings in circles around center
--
function settlements.place_settlement_circle(minp, maxp)
-- find center of chunk
local center = {
x=maxp.x-half_map_chunk_size,
y=maxp.y-half_map_chunk_size,
z=maxp.z-half_map_chunk_size
}
-- find center_surcafe of chunk
local center_surface = settlements.find_surface(center)
-- go build settlement around center
if center_surface then
-- add settlement to list
table.insert(settlements_in_world,
center_surface)
-- save list to file
settlements.save()
-- initialize all settlement information
settlements.initialize_settlement()
-- build well in the center
building_all_info = schematic_table[1]
settlements.build_schematic(
center_surface,
building_all_info["mts"],
building_all_info["rplc"],
building_all_info["name"])
-- add to settlement info table
local index = 1
settlement_info[index] = {pos = center_surface,
name = building_all_info["name"],
hsize = building_all_info["hsize"]}
--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 )
local pos1 = { x=ptx, y=center_surface.y, z=ptz}
--
local pos_surface = settlements.find_surface(pos1)
if pos_surface
then
if settlements.pick_next_building(pos_surface)
then
settlements.build_schematic(pos_surface,
building_all_info["mts"],
building_all_info["rplc"],
building_all_info["name"])
number_built = number_built + 1
settlement_info[index] = {pos = pos_surface,
name = building_all_info["name"],
hsize = building_all_info["hsize"]}
index = index + 1
if number_of_buildings == number_built
then
break
end
end
else
break
end
end
r = r + math.random(2,5)
end
end
if settlements.debug == true
then
minetest.chat_send_all("really ".. number_built)
end
minetest.after(2, settlements.paths)
-- settlements.paths()
end
end
function settlements.initialize_settlement()
-- settlement_info table reset -- settlement_info table reset
for k,v in pairs(settlement_info) do for k,v in pairs(settlement_info) do
settlement_info[k] = nil settlement_info[k] = nil
@ -253,9 +77,9 @@ function settlements.initialize_settlement()
minetest.chat_send_all("settlement ".. number_of_buildings) minetest.chat_send_all("settlement ".. number_of_buildings)
end end
end end
-- -------------------------------------------------------------------------------
-- everything necessary to pick a fitting next building -- everything necessary to pick a fitting next building
-- -------------------------------------------------------------------------------
function settlements.pick_next_building(pos_surface) function settlements.pick_next_building(pos_surface)
local randomized_schematic_table = shuffle(schematic_table) local randomized_schematic_table = shuffle(schematic_table)
-- pick schematic -- pick schematic
@ -276,4 +100,273 @@ function settlements.pick_next_building(pos_surface)
end end
end end
return nil return nil
end end
-------------------------------------------------------------------------------
-- fill settlement_info with LVM
--------------------------------------------------------------------------------
function settlements.create_site_plan_lvm(maxp, minp)
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_surcafe of chunk
local center_surface , surface_material = settlements.find_surface_lvm(center, minp)
-- go build settlement around center
if center_surface then
-- add settlement to list
table.insert(settlements_in_world,
center_surface)
-- save list to file
settlements.save()
-- initialize all settlement_info table
settlements.initialize_settlement_info()
-- first building is townhall in the center
building_all_info = schematic_table[1]
local rotation = possible_rotations[ math.random( #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 pos_surface
then
if settlements.pick_next_building(pos_surface)
then
rotation = possible_rotations[ math.random( #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
if number_of_buildings == number_built
then
break
end
end
else
break
end
end
r = r + math.random(2,5)
end
end
if settlements.debug == true
then
minetest.chat_send_all("really ".. number_built)
end
return true
else
return false
end
end
-------------------------------------------------------------------------------
-- fill settlement_info
--------------------------------------------------------------------------------
function settlements.create_site_plan(maxp, minp)
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_surcafe of chunk
local center_surface , surface_material = settlements.find_surface(center)
-- go build settlement around center
if center_surface then
-- add settlement to list
table.insert(settlements_in_world,
center_surface)
-- save list to file
settlements.save()
-- initialize all settlement_info table
settlements.initialize_settlement_info()
-- first building is townhall in the center
building_all_info = schematic_table[1]
local rotation = possible_rotations[ math.random( #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(pos1)
if pos_surface
then
if settlements.pick_next_building(pos_surface)
then
rotation = possible_rotations[ math.random( #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
if number_of_buildings == number_built
then
break
end
end
else
break
end
end
r = r + math.random(2,5)
end
end
if settlements.debug == true
then
minetest.chat_send_all("really ".. number_built)
end
return true
else
return false
end
end
-------------------------------------------------------------------------------
-- evaluate settlement_info and place schematics
-------------------------------------------------------------------------------
function settlements.place_schematics_lvm()
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[math.random(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
schem_lua = schem_lua:gsub("default:cobble", material)
end
schem_lua = schem_lua:gsub("default:dirt_with_grass",
platform_material_name)
-- special material for spawning npcs
schem_lua = schem_lua:gsub("default: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()
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[math.random(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
schem_lua = schem_lua:gsub("default:cobble", material)
end
schem_lua = schem_lua:gsub("default:dirt_with_grass",
platform_material)
-- special material for spawning npcs
schem_lua = schem_lua:gsub("default: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(
pos,
schematic,
rotation,
nil,
true)
end
end

View File

@ -3,6 +3,10 @@
-- --
settlements.debug = false settlements.debug = false
-- --
-- switch for lvm
settlements.lvm = false
--
--
-- material to replace cobblestone with -- material to replace cobblestone with
-- --
wallmaterial = { wallmaterial = {
@ -25,14 +29,14 @@ schem_path = settlements.modpath.."/schematics/"
-- list of schematics -- list of schematics
-- --
schematic_table = { schematic_table = {
{name = "townhall", mts = schem_path.."townhall.mts", hsize = 15, max_num = 0, rplc = "n"}, {name = "townhall", mts = schem_path.."townhall.mts", hwidth = 10, hdepth = 11, hheight = 12, hsize = 15, max_num = 0, rplc = "n"},
{name = "well", mts = schem_path.."well.mts", hsize = 11, max_num = 0.045, rplc = "n"}, {name = "well", mts = schem_path.."well.mts", hwidth = 5, hdepth = 5, hheight = 13, hsize = 11, max_num = 0.045, rplc = "n"},
{name = "hut", mts = schem_path.."hut.mts", hsize = 11, max_num = 0.9, rplc = "y"}, {name = "hut", mts = schem_path.."hut.mts", hwidth = 7, hdepth = 7, hheight = 13, hsize = 11, max_num = 0.9, rplc = "y"},
{name = "garden", mts = schem_path.."garden.mts", hsize = 11, max_num = 0.1, rplc = "n"}, {name = "garden", mts = schem_path.."garden.mts", hwidth = 7, hdepth = 7, hheight = 13, hsize = 11, max_num = 0.1, rplc = "n"},
{name = "lamp", mts = schem_path.."lamp.mts", hsize = 10, 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 = "tower", mts = schem_path.."tower.mts", hsize = 11, max_num = 0.055, rplc = "n"}, {name = "tower", mts = schem_path.."tower.mts", hwidth = 7, hdepth = 7, hheight = 13, hsize = 11, max_num = 0.055, rplc = "n"},
{name = "church", mts = schem_path.."church.mts", hsize = 17, max_num = 0.050, rplc = "n"}, {name = "church", mts = schem_path.."church.mts", hwidth = 7, hdepth = 10, hheight = 13, hsize = 17, max_num = 0.050, rplc = "n"},
{name = "blacksmith", mts = schem_path.."blacksmith.mts", hsize = 11, max_num = 0.050, rplc = "n"}, {name = "blacksmith", mts = schem_path.."blacksmith.mts", hwidth = 7, hdepth = 7, hheight = 13, hsize = 11, max_num = 0.050, rplc = "n"},
} }
-- --
-- temporary info for currentliy built settlement (position of each building) -- temporary info for currentliy built settlement (position of each building)

View File

@ -1,9 +1,9 @@
-- --
function settlements.convert_mts_to_lua() function settlements.convert_mts_to_lua()
local building = schem_path.."hut.mts" 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 str = minetest.serialize_schematic(building, "lua", {lua_use_comments = true, lua_num_indent_spaces = 0}).." return(schematic)"
local schematic = loadstring(str)() local schematic = loadstring(str)()
local file = io.open(schem_path.."hut"..".lua", "w") local file = io.open(schem_path.."church"..".lua", "w")
file:write(dump(schematic)) file:write(dump(schematic))
file:close() file:close()
print(dump(schematic)) print(dump(schematic))

View File

@ -1,11 +1,11 @@
-- -------------------------------------------------------------------------------
-- function to fill empty space below baseplate when building on a hill -- function to fill empty space below baseplate when building on a hill
-- -------------------------------------------------------------------------------
function settlements.ground(vm, data, va, pos) -- role model: Wendelsteinkircherl, Brannenburg function settlements.ground_lvm(pos) -- role model: Wendelsteinkircherl, Brannenburg
local c_dirt = minetest.get_content_id("default:dirt") local c_dirt = minetest.get_content_id("default:dirt")
local c_stone = minetest.get_content_id("default:stone") local c_stone = minetest.get_content_id("default:stone")
-- --
local p2 = pos local p2 = settlements.shallowCopy(pos)
local cnt = 0 local cnt = 0
local mat = c_dirt local mat = c_dirt
p2.y = p2.y-1 p2.y = p2.y-1
@ -18,44 +18,133 @@ function settlements.ground(vm, data, va, pos) -- role model: Wendelsteinkircher
data[vi] = mat data[vi] = mat
p2.y = p2.y-1 p2.y = p2.y-1
end end
return data -- return data
end end
-- -------------------------------------------------------------------------------
-- function to fill empty space below baseplate when building on a hill -- function to fill empty space below baseplate when building on a hill
-- -------------------------------------------------------------------------------
function settlements.foundation(vm, data, va, pos, width, depth, height, rotation) function settlements.ground(pos) -- role model: Wendelsteinkircherl, Brannenburg
local p2 = settlements.shallowCopy(pos)
local cnt = 0
local mat = "default:dirt"
p2.y = p2.y-1
while true do
cnt = cnt+1
if cnt > 20 then break end
if cnt>math.random(2,4)
then
mat = "default:stone"
end
minetest.swap_node(p2, {name=mat})
p2.y = p2.y-1
end
end
-------------------------------------------------------------------------------
-- function clear space above baseplate
-------------------------------------------------------------------------------
function settlements.terraform_lvm()
local c_air = minetest.get_content_id("air") local c_air = minetest.get_content_id("air")
local p5 = settlements.shallowCopy(pos) local fheight
local fheight = height * 3 -- remove trees and leaves above
local fwidth local fwidth
local fdepth local fdepth
if rotation == "0" or rotation == "180" then
fwidth = width
fdepth = depth for i, built_house in ipairs(settlement_info) do
else -- pick right schematic_info to current built_house
fwidth = depth for j, schem in ipairs(schematic_table) do
fdepth = width if settlement_info[i]["name"] == schem["name"]
end then
for yi = 0,fheight do schematic_data = schem
for xi = 0,fwidth-1 do break
for zi = 0,fdepth-1 do end
if yi == 0 then end
local p = {x=p5.x+xi, y=p5.y, z=p5.z+zi} local pos = settlement_info[i]["pos"]
data = settlements.ground(vm, data, va, p) if settlement_info[i]["rotat"] == "0" or settlement_info[i]["rotat"] == "180"
else then
-- write ground fwidth = schematic_data["hwidth"]
local vi = va:index(p5.x+xi, p5.y+yi, p5.z+zi) fdepth = schematic_data["hdepth"]
if data[vi] ~= c_air else
--local node = minetest.get_node_or_nil({x=p5.x+xi, y=p5.y+yi, z=p5.z+zi}) fwidth = schematic_data["hdepth"]
--if node then 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)
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" --if node.name ~= "air"
then then
--minetest.swap_node({x=p5.x+xi, y=p5.y+yi, z=p5.z+zi},{name="air"}) --minetest.swap_node({x=pos.x+xi, y=pos.y+yi, z=pos.z+zi},{name="air"})
data[vi] = c_air data[vi] = c_air
end
end end
end end
end end
end end
end
end
-------------------------------------------------------------------------------
-- function clear space above baseplate
-------------------------------------------------------------------------------
function settlements.terraform()
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 xi = 0,fwidth-1 do
for zi = 0,fdepth-1 do
for yi = 0,fheight do
if yi == 0 then
local p = {x=pos.x+xi, y=pos.y, z=pos.z+zi}
settlements.ground(p)
else
-- write ground
local node = minetest.get_node_or_nil({x=pos.x+xi, y=pos.y+yi, z=pos.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"})
end
end
end
end
end
end
end end
settlements.setlvm(vm, data)
end end

160
init.lua
View File

@ -5,11 +5,14 @@
settlements = {} settlements = {}
settlements.modpath = minetest.get_modpath("settlements"); settlements.modpath = minetest.get_modpath("settlements");
vm, data, va, emin, emax = 1
dofile(settlements.modpath.."/const.lua") dofile(settlements.modpath.."/const.lua")
dofile(settlements.modpath.."/utils.lua") dofile(settlements.modpath.."/utils.lua")
dofile(settlements.modpath.."/foundation.lua") dofile(settlements.modpath.."/foundation.lua")
dofile(settlements.modpath.."/buildings.lua") dofile(settlements.modpath.."/buildings.lua")
dofile(settlements.modpath.."/paths.lua") dofile(settlements.modpath.."/paths.lua")
dofile(settlements.modpath.."/convert_lua_mts.lua")
-- --
-- load settlements on server -- load settlements on server
-- --
@ -48,10 +51,14 @@ end
-- on map generation, try to build a settlement -- on map generation, try to build a settlement
-- --
minetest.register_on_generated(function(minp, maxp) minetest.register_on_generated(function(minp, maxp)
--
-- needed for manual and automated settlement building
--
heightmap = minetest.get_mapgen_object("heightmap")
-- --
-- randomly try to build settlements -- randomly try to build settlements
-- --
if math.random(1,10)<9 then if math.random(1,10)<7 then
-- --
-- don't build settlement underground -- don't build settlement underground
-- --
@ -72,10 +79,6 @@ minetest.register_on_generated(function(minp, maxp)
return return
end end
-- --
-- get LVM of current chunk
--
local vm, data, va, emin, emax = settlements.getlvm(minp, maxp)
--
-- don't build settlements on (too) uneven terrain -- don't build settlements on (too) uneven terrain
-- --
local height_difference = settlements.evaluate_heightmap(minp, maxp) local height_difference = settlements.evaluate_heightmap(minp, maxp)
@ -84,11 +87,66 @@ minetest.register_on_generated(function(minp, maxp)
then then
return return
end end
-- -- waiting necessary for chunk to load, otherwise, townhall is not in the middle, no map found behind townhall
-- if nothing prevents the settlement -> do it minetest.after(2, function()
--
--settlements.place_settlement_circle(minp, maxp)
settlements.place_settlement_lvm(vm, data, va, minp, maxp) --
-- if nothing prevents the settlement -> do it
--
--
-- fill settlement_info with buildings and their data
--
if settlements.lvm == true
then
--
-- get LVM of current chunk
--
vm, data, va, emin, emax = settlements.getlvm(minp, maxp)
suitable_place_found = settlements.create_site_plan_lvm(maxp, minp)
else
suitable_place_found = settlements.create_site_plan(maxp, minp)
end
if not suitable_place_found
then
return
end
--
-- evaluate settlement_info and prepair terrain
--
if settlements.lvm == true
then
settlements.terraform_lvm()
else
settlements.terraform()
end
--
-- evaluate settlement_info and build paths between buildings
--
if settlements.lvm == true
then
settlements.paths_lvm(minp)
else
settlements.paths()
end
--
-- evaluate settlement_info and place schematics
--
if settlements.lvm == true
then
vm:set_data(data)
settlements.place_schematics_lvm()
vm:write_to_map(true)
else
settlements.place_schematics()
end
--
-- evaluate settlement_info and initialize furnaces and chests
--
settlements.initialize_nodes()
end)
end end
end) end)
@ -105,14 +163,14 @@ minetest.register_craftitem("settlements:tool", {
local center_surface = pointed_thing.under local center_surface = pointed_thing.under
if center_surface then if center_surface then
local building_all_info = {name = "blacksmith", local building_all_info = {name = "blacksmith",
mts = schem_path.."blacksmith.mts", mts = schem_path.."blacksmith.mts",
hsize = 13, hsize = 13,
max_num = 0.9, max_num = 0.9,
rplc = "n"} rplc = "n"}
settlements.build_schematic(center_surface, settlements.build_schematic(center_surface,
building_all_info["mts"], building_all_info["mts"],
building_all_info["rplc"], building_all_info["rplc"],
building_all_info["name"]) building_all_info["name"])
-- settlements.convert_mts_to_lua() -- settlements.convert_mts_to_lua()
-- settlements.mts_save() -- settlements.mts_save()
@ -130,17 +188,71 @@ minetest.register_craftitem("settlements:tool", {
x=center_surface.x-half_map_chunk_size, x=center_surface.x-half_map_chunk_size,
y=center_surface.y-half_map_chunk_size, y=center_surface.y-half_map_chunk_size,
z=center_surface.z-half_map_chunk_size z=center_surface.z-half_map_chunk_size
} }
local maxp = { local maxp = {
x=center_surface.x+half_map_chunk_size, x=center_surface.x+half_map_chunk_size,
y=center_surface.y+half_map_chunk_size, y=center_surface.y+half_map_chunk_size,
z=center_surface.z+half_map_chunk_size z=center_surface.z+half_map_chunk_size
} }
-- --
-- get LVM of current chunk -- get LVM of current chunk
-- --
local vm, data, va, emin, emax = settlements.getlvm(minp, maxp) vm, data, va, emin, emax = settlements.getlvm(minp, maxp)
settlements.place_settlement_lvm(vm, data, va, minp, maxp) --
-- fill settlement_info with buildings and their data
--
local start_time = os.time()
if settlements.lvm == true
then
suitable_place_found = settlements.create_site_plan_lvm(maxp, minp)
else
suitable_place_found = settlements.create_site_plan(maxp, minp)
end
if not suitable_place_found
then
return
end
--
-- evaluate settlement_info and prepair terrain
--
if settlements.lvm == true
then
settlements.terraform_lvm()
else
settlements.terraform()
end
--
-- evaluate settlement_info and build paths between buildings
--
if settlements.lvm == true
then
settlements.paths_lvm(minp)
else
settlements.paths()
end
--
-- evaluate settlement_info and place schematics
--
if settlements.lvm == true
then
vm:set_data(data)
settlements.place_schematics_lvm()
vm:write_to_map(true)
else
settlements.place_schematics()
end
--
-- evaluate settlement_info and initialize furnaces and chests
--
settlements.initialize_nodes()
local end_time = os.time()
minetest.chat_send_all("Zeit ".. end_time - start_time)
--
--settlements.convert_mts_to_lua()
--settlements.mts_save()
end end
end end
}) })

238
paths.lua
View File

@ -1,88 +1,180 @@
-- -------------------------------------------------------------------------------
-- generate paths between buildings -- generate paths between buildings
-- -------------------------------------------------------------------------------
function settlements.paths_lvm(minp)
local c_gravel = minetest.get_content_id("default:gravel")
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 default:gravel
if surface_point
then
local vi = va:index(surface_point.x, surface_point.y, surface_point.z)
data[vi] = c_gravel
--minetest.swap_node(surface_point,{name="default:gravel"})
-- 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() function settlements.paths()
local starting_point local starting_point
local end_point local end_point
local distance local distance
--for k,v in pairs(settlement_info) do --for k,v in pairs(settlement_info) do
starting_point = settlement_info[1]["pos"] starting_point = settlement_info[1]["pos"]
for o,p in pairs(settlement_info) do for o,p in pairs(settlement_info) do
end_point = settlement_info[o]["pos"] end_point = settlement_info[o]["pos"]
if starting_point ~= end_point if starting_point ~= end_point
then then
-- loop until end_point is reched (distance == 0) -- loop until end_point is reched (distance == 0)
while true do while true do
-- define surrounding pos to starting_point -- define surrounding pos to starting_point
local north_p = {x=starting_point.x+1, y=starting_point.y, z=starting_point.z} 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 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 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} local east_p = {x=starting_point.x, y=starting_point.y, z=starting_point.z-1}
-- measure distance to end_point -- measure distance to end_point
local dist_north_p_to_end = math.sqrt( local dist_north_p_to_end = math.sqrt(
((north_p.x - end_point.x)*(north_p.x - end_point.x))+ ((north_p.x - end_point.x)*(north_p.x - end_point.x))+
((north_p.z - end_point.z)*(north_p.z - end_point.z)) ((north_p.z - end_point.z)*(north_p.z - end_point.z))
) )
local dist_south_p_to_end = math.sqrt( local dist_south_p_to_end = math.sqrt(
((south_p.x - end_point.x)*(south_p.x - end_point.x))+ ((south_p.x - end_point.x)*(south_p.x - end_point.x))+
((south_p.z - end_point.z)*(south_p.z - end_point.z)) ((south_p.z - end_point.z)*(south_p.z - end_point.z))
) )
local dist_west_p_to_end = math.sqrt( local dist_west_p_to_end = math.sqrt(
((west_p.x - end_point.x)*(west_p.x - end_point.x))+ ((west_p.x - end_point.x)*(west_p.x - end_point.x))+
((west_p.z - end_point.z)*(west_p.z - end_point.z)) ((west_p.z - end_point.z)*(west_p.z - end_point.z))
) )
local dist_east_p_to_end = math.sqrt( local dist_east_p_to_end = math.sqrt(
((east_p.x - end_point.x)*(east_p.x - end_point.x))+ ((east_p.x - end_point.x)*(east_p.x - end_point.x))+
((east_p.z - end_point.z)*(east_p.z - end_point.z)) ((east_p.z - end_point.z)*(east_p.z - end_point.z))
) )
-- evaluate which pos is closer to the end_point -- evaluate which pos is closer to the end_point
if dist_north_p_to_end <= dist_south_p_to_end and 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_west_p_to_end and
dist_north_p_to_end <= dist_east_p_to_end dist_north_p_to_end <= dist_east_p_to_end
then then
starting_point = north_p starting_point = north_p
distance = dist_north_p_to_end distance = dist_north_p_to_end
elseif dist_south_p_to_end <= dist_north_p_to_end and 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_west_p_to_end and
dist_south_p_to_end <= dist_east_p_to_end dist_south_p_to_end <= dist_east_p_to_end
then then
starting_point = south_p starting_point = south_p
distance = dist_south_p_to_end distance = dist_south_p_to_end
elseif dist_west_p_to_end <= dist_north_p_to_end and 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_south_p_to_end and
dist_west_p_to_end <= dist_east_p_to_end dist_west_p_to_end <= dist_east_p_to_end
then then
starting_point = west_p starting_point = west_p
distance = dist_west_p_to_end distance = dist_west_p_to_end
elseif dist_east_p_to_end <= dist_north_p_to_end and 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_south_p_to_end and
dist_east_p_to_end <= dist_west_p_to_end dist_east_p_to_end <= dist_west_p_to_end
then then
starting_point = east_p starting_point = east_p
distance = dist_east_p_to_end distance = dist_east_p_to_end
end end
-- find surface of new starting point -- find surface of new starting point
local surface_point = settlements.find_surface(starting_point) local surface_point, surface_mat = settlements.find_surface(starting_point)
-- replace surface node with default:gravel -- replace surface node with default:gravel
if surface_point if surface_point
then then
minetest.swap_node(surface_point,{name="default:gravel"}) minetest.swap_node(surface_point,{name="default:gravel"})
-- don't set y coordinate, surface might be too low or high -- don't set y coordinate, surface might be too low or high
starting_point.x = surface_point.x starting_point.x = surface_point.x
starting_point.z = surface_point.z starting_point.z = surface_point.z
end end
if distance <= 1 or if distance <= 1 or
starting_point == end_point starting_point == end_point
then then
break break
end
end end
end end
end end
--end end
end end

6659
schematics/church.lua Normal file

File diff suppressed because it is too large Load Diff

172
utils.lua
View File

@ -21,9 +21,10 @@ local c_bush_stem = minetest.get_content_id("default:bush_stem
local c_a_bush_leaves = minetest.get_content_id("default:acacia_bush_leaves") local c_a_bush_leaves = minetest.get_content_id("default:acacia_bush_leaves")
local c_a_bush_stem = minetest.get_content_id("default:acacia_bush_stem") local c_a_bush_stem = minetest.get_content_id("default:acacia_bush_stem")
local c_water_source = minetest.get_content_id("default:water_source") local c_water_source = minetest.get_content_id("default:water_source")
-- local c_water_flowing = minetest.get_content_id("default:water_flowing")
-------------------------------------------------------------------------------
-- function to copy tables -- function to copy tables
-- -------------------------------------------------------------------------------
function settlements.shallowCopy(original) function settlements.shallowCopy(original)
local copy = {} local copy = {}
for key, value in pairs(original) do for key, value in pairs(original) do
@ -38,10 +39,42 @@ function settlements.round(num, numDecimalPlaces)
local mult = 10^(numDecimalPlaces or 0) local mult = 10^(numDecimalPlaces or 0)
return math.floor(num * mult + 0.5) / mult return math.floor(num * mult + 0.5) / mult
end end
-------------------------------------------------------------------------------
-- --
-------------------------------------------------------------------------------
function settlements.find_surface_heightmap(pos, minp)
local surface_mat = {
c_dirt_with_grass,
c_dirt_with_snow ,
c_dirt_with_dry_grass,
c_dirt_with_coniferous_litter,
c_sand,
c_desert_sand
}
local p6 = settlements.shallowCopy(pos)
local heightmap = minetest.get_mapgen_object("heightmap")
-- get height of current pos p6
local hm_i = (p6.x - minp.x + 1) + (((p6.z - minp.z)) * 80)
p6.y = heightmap[hm_i]
local vi = va:index(p6.x, p6.y, p6.z)
local viname = minetest.get_name_from_content_id(data[vi])
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
)
then
-- local tmp = minetest.get_name_from_content_id(data[node_check])
return p6, mats
end
end
end
-------------------------------------------------------------------------------
-- function to find surface block y coordinate -- function to find surface block y coordinate
-- -------------------------------------------------------------------------------
function settlements.find_surface_lvm(pos, data, va) function settlements.find_surface_lvm(pos, minp)
--ab hier altes verfahren
local p6 = settlements.shallowCopy(pos) local p6 = settlements.shallowCopy(pos)
local surface_mat = { local surface_mat = {
c_dirt_with_grass, c_dirt_with_grass,
@ -50,14 +83,14 @@ function settlements.find_surface_lvm(pos, data, va)
c_dirt_with_coniferous_litter, c_dirt_with_coniferous_litter,
c_sand, c_sand,
c_desert_sand c_desert_sand
} }
local cnt = 0 local cnt = 0
local itter -- count up or down local itter -- count up or down
local cnt_max = 200 local cnt_max = 200
-- starting point for looking for surface -- starting point for looking for surface
local vi = va:index(p6.x, p6.y, p6.z) local vi = va:index(p6.x, p6.y, p6.z)
if data[vi] == nil then return nil end if data[vi] == nil then return nil end
-- local tmp = minetest.get_name_from_content_id(data[vi]) local tmp = minetest.get_name_from_content_id(data[vi])
if data[vi] == c_air then if data[vi] == c_air then
itter = -1 itter = -1
else else
@ -74,22 +107,23 @@ function settlements.find_surface_lvm(pos, data, va)
for i, mats in ipairs(surface_mat) do for i, mats in ipairs(surface_mat) do
local node_check = va:index(p6.x, p6.y+1, p6.z) local node_check = va:index(p6.x, p6.y+1, p6.z)
if node_check and vi and data[vi] == mats and if node_check and vi and data[vi] == mats and
(data[node_check] ~= c_water_source (data[node_check] ~= c_water_source and
) data[node_check] ~= c_water_flowing
)
then then
-- local tmp = minetest.get_name_from_content_id(data[node_check]) local tmp = minetest.get_name_from_content_id(data[node_check])
return p6 return p6, mats
end end
end end
p6.y = p6.y + itter p6.y = p6.y + itter
if p6.y < 0 then return nil end if p6.y < 0 then return nil end
end end
return nil return nil --]]
end 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) function settlements.find_surface(pos)
local p6 = settlements.shallowCopy(pos) local p6 = settlements.shallowCopy(pos)
-- --
@ -110,7 +144,6 @@ function settlements.find_surface(pos)
-- check, in which direction to look for surface -- check, in which direction to look for surface
local s = minetest.get_node_or_nil(p6) local s = minetest.get_node_or_nil(p6)
if s and string.find(s.name,"air") then if s and string.find(s.name,"air") then
--p6.y = p6.y+50
itter = -1 itter = -1
else else
itter = 1 itter = 1
@ -130,7 +163,7 @@ function settlements.find_surface(pos)
string.find(node_check.name,"tree") or string.find(node_check.name,"tree") or
string.find(node_check.name,"grass")) string.find(node_check.name,"grass"))
then then
return p6 return p6, mats
end end
end end
p6.y = p6.y + itter p6.y = p6.y + itter
@ -138,9 +171,9 @@ function settlements.find_surface(pos)
end end
return nil return nil
end end
-- -------------------------------------------------------------------------------
-- check distance for new building -- check distance for new building
-- -------------------------------------------------------------------------------
function settlements.check_distance(building_pos, building_size) function settlements.check_distance(building_pos, building_size)
local distance local distance
for i, built_house in ipairs(settlement_info) do for i, built_house in ipairs(settlement_info) do
@ -155,9 +188,9 @@ function settlements.check_distance(building_pos, building_size)
end end
return true return true
end end
-- -------------------------------------------------------------------------------
-- save list of generated settlements -- save list of generated settlements
-- -------------------------------------------------------------------------------
function settlements.save() function settlements.save()
local file = io.open(minetest.get_worldpath().."/settlements.txt", "w") local file = io.open(minetest.get_worldpath().."/settlements.txt", "w")
if file then if file then
@ -165,9 +198,9 @@ function settlements.save()
file:close() file:close()
end end
end end
-- -------------------------------------------------------------------------------
-- load list of generated settlements -- load list of generated settlements
-- -------------------------------------------------------------------------------
function settlements.load() function settlements.load()
local file = io.open(minetest.get_worldpath().."/settlements.txt", "r") local file = io.open(minetest.get_worldpath().."/settlements.txt", "r")
if file then if file then
@ -178,9 +211,9 @@ function settlements.load()
end end
return {} return {}
end end
-- -------------------------------------------------------------------------------
-- check distance to other settlements -- check distance to other settlements
-- -------------------------------------------------------------------------------
function settlements.check_distance_other_settlements(center_new_chunk) function settlements.check_distance_other_settlements(center_new_chunk)
local min_dist_settlements = 300 local min_dist_settlements = 300
for i, pos in ipairs(settlements_in_world) do for i, pos in ipairs(settlements_in_world) do
@ -191,12 +224,13 @@ function settlements.check_distance_other_settlements(center_new_chunk)
end end
return true return true
end end
-- -------------------------------------------------------------------------------
-- fill chests -- fill chests
-- -------------------------------------------------------------------------------
function settlements.fill_chest(pos) function settlements.fill_chest(pos)
-- find chests within radius -- find chests within radius
local chestpos = minetest.find_node_near(pos, 6, {"default:chest"}) --local chestpos = minetest.find_node_near(pos, 6, {"default:chest"})
local chestpos = pos
-- initialize chest (mts chests don't have meta) -- initialize chest (mts chests don't have meta)
local meta = minetest.get_meta(chestpos) local meta = minetest.get_meta(chestpos)
if meta:get_string("infotext") ~= "Chest" then if meta:get_string("infotext") ~= "Chest" then
@ -228,9 +262,9 @@ function settlements.fill_chest(pos)
inv:add_item("main", "default:sword_steel "..math.random(0,1)) inv:add_item("main", "default:sword_steel "..math.random(0,1))
end end
end end
-- -------------------------------------------------------------------------------
-- initialize furnace -- initialize furnace
-- -------------------------------------------------------------------------------
function settlements.initialize_furnace(pos) function settlements.initialize_furnace(pos)
-- find chests within radius -- find chests within radius
local furnacepos = minetest.find_node_near(pos, local furnacepos = minetest.find_node_near(pos,
@ -246,33 +280,47 @@ function settlements.initialize_furnace(pos)
end end
end end
end end
-- -------------------------------------------------------------------------------
-- initialize furnace, chests, bookshelves -- initialize furnace, chests, bookshelves
-- -------------------------------------------------------------------------------
function settlements.initialize_nodes(pos, width, depth, height) function settlements.initialize_nodes()
local p = settlements.shallowCopy(pos) for i, built_house in ipairs(settlement_info) do
for yi = 1,height do for j, schem in ipairs(schematic_table) do
for xi = 0,width do if settlement_info[i]["name"] == schem["name"]
for zi = 0,depth do then
local ptemp = {x=p.x+xi, y=p.y+yi, z=p.z+zi} building_all_info = schem
local node = minetest.get_node(ptemp) break
if node.name == "default:furnace" or end
node.name == "default:chest" or end
node.name == "default:bookshelf"
then local width = building_all_info["hwidth"]
minetest.registered_nodes[node.name].on_construct(ptemp) local depth = building_all_info["hdepth"]
end local height = building_all_info["hheight"]
-- when chest is found -> fill with stuff
if node.name == "default:chest" then local p = settlement_info[i]["pos"]
minetest.after(3,settlements.fill_chest,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)
if node.name == "default:furnace" or
node.name == "default:chest" or
node.name == "default:bookshelf"
then
minetest.registered_nodes[node.name].on_construct(ptemp)
end
-- when chest is found -> fill with stuff
if node.name == "default:chest" then
minetest.after(3,settlements.fill_chest,ptemp)
end
end end
end end
end end
end end
end end
-- -------------------------------------------------------------------------------
-- randomize table -- randomize table
-- -------------------------------------------------------------------------------
function shuffle(tbl) function shuffle(tbl)
local table = settlements.shallowCopy(tbl) local table = settlements.shallowCopy(tbl)
local size = #table local size = #table
@ -282,9 +330,9 @@ function shuffle(tbl)
end end
return table return table
end end
-- -------------------------------------------------------------------------------
-- get heightmap -- get heightmap
-- -------------------------------------------------------------------------------
function settlements.determine_heightmap(data, va, minp, maxp) function settlements.determine_heightmap(data, va, minp, maxp)
-- max height and min height, initialize with impossible values for easier first time setting -- max height and min height, initialize with impossible values for easier first time setting
local max_y = -100 local max_y = -100
@ -325,17 +373,16 @@ function settlements.determine_heightmap(data, va, minp, maxp)
-- return the difference between highest and lowest pos in chunk -- return the difference between highest and lowest pos in chunk
return max_y - min_y return max_y - min_y
end end
-- -------------------------------------------------------------------------------
-- evaluate heightmap -- evaluate heightmap
-- -------------------------------------------------------------------------------
function settlements.evaluate_heightmap(minp, maxp) function settlements.evaluate_heightmap()
-- max height and min height, initialize with impossible values for easier first time setting -- max height and min height, initialize with impossible values for easier first time setting
local max_y = -50000 local max_y = -50000
local min_y = 50000 local min_y = 50000
-- only evaluate the center square of heightmap 40 x 40 -- only evaluate the center square of heightmap 40 x 40
local square_start = 1621 local square_start = 1621
local square_end = 1661 local square_end = 1661
local heightmap = minetest.get_mapgen_object("heightmap")
for j = 1 , 40, 1 do for j = 1 , 40, 1 do
for i = square_start, square_end, 1 do for i = square_start, square_end, 1 do
-- skip buggy heightmaps, return high value -- skip buggy heightmaps, return high value
@ -371,9 +418,9 @@ function settlements.evaluate_heightmap(minp, maxp)
end end
return height_diff return height_diff
end end
-- -------------------------------------------------------------------------------
-- get LVM of current chunk -- get LVM of current chunk
-- -------------------------------------------------------------------------------
function settlements.getlvm(minp, maxp) function settlements.getlvm(minp, maxp)
local vm = minetest.get_voxel_manip() local vm = minetest.get_voxel_manip()
local emin, emax = vm:read_from_map(minp, maxp) local emin, emax = vm:read_from_map(minp, maxp)
@ -383,11 +430,12 @@ function settlements.getlvm(minp, maxp)
} }
local data = vm:get_data() local data = vm:get_data()
return vm, data, va, emin, emax return vm, data, va, emin, emax
end-- end
-------------------------------------------------------------------------------
-- get LVM of current chunk -- get LVM of current chunk
-- -------------------------------------------------------------------------------
function settlements.setlvm(vm, data) function settlements.setlvm(vm, data)
-- Write data -- Write data
vm:set_data(data) vm:set_data(data)
vm:write_to_map(true) vm:write_to_map(true)
end end