Villages cleanup

kay27 2021-01-29 22:49:33 +04:00
parent b61ae6a61f
commit 30b4b9661c
7 changed files with 150 additions and 741 deletions

@ -61,8 +61,7 @@ function settlements.initialize_settlement_info(pr)
local count_buildings = {} local count_buildings = {}
-- count_buildings table reset -- count_buildings table reset
for k,v in pairs(schematic_table) do for k,v in pairs(settlements.schematic_table) do
-- local name = schematic_table[v]["name"]
count_buildings[v["name"]] = 0 count_buildings[v["name"]] = 0
end end
@ -74,96 +73,6 @@ function settlements.initialize_settlement_info(pr)
return count_buildings, number_of_buildings, number_built return count_buildings, number_of_buildings, number_built
end 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 -- fill settlement_info
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function settlements.create_site_plan(maxp, minp, pr) 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 -- initialize all settlement_info table
local count_buildings, number_of_buildings, number_built = settlements.initialize_settlement_info(pr) local count_buildings, number_of_buildings, number_built = settlements.initialize_settlement_info(pr)
-- first building is townhall in the center -- 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 ) ] local rotation = possible_rotations[ pr:next(1, #possible_rotations ) ]
-- add to settlement info table -- add to settlement info table
local index = 1 local index = 1
@ -216,7 +125,7 @@ function settlements.create_site_plan(maxp, minp, pr)
local pos_surface, surface_material = settlements.find_surface(pos1) local pos_surface, surface_material = settlements.find_surface(pos1)
if not pos_surface then break end 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 -- pick schematic
local size = #randomized_schematic_table local size = #randomized_schematic_table
for i = size, 1, -1 do for i = size, 1, -1 do
@ -255,80 +164,10 @@ end
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- evaluate settlement_info and place schematics -- 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) function settlements.place_schematics(settlement_info, pr)
local building_all_info local building_all_info
for i, built_house in ipairs(settlement_info) do 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 if settlement_info[i]["name"] == schem["name"] then
building_all_info = schem building_all_info = schem
break break
@ -338,7 +177,7 @@ function settlements.place_schematics(settlement_info, pr)
local pos = settlement_info[i]["pos"] local pos = settlement_info[i]["pos"]
local rotation = settlement_info[i]["rotat"] local rotation = settlement_info[i]["rotat"]
-- get building node material for better integration to surrounding -- 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) --platform_material_name = minetest.get_name_from_content_id(platform_material)
-- pick random material -- pick random material
--local material = wallmaterial[pr:next(1,#wallmaterial)] --local material = wallmaterial[pr:next(1,#wallmaterial)]
@ -350,7 +189,7 @@ function settlements.place_schematics(settlement_info, pr)
"lua", "lua",
{lua_use_comments = false, lua_num_indent_spaces = 0}).." return(schematic)" {lua_use_comments = false, lua_num_indent_spaces = 0}).." return(schematic)"
-- replace material -- 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. --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. -- 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 if platform_material == "mcl_core:snow" or platform_material == "mcl_core:dirt_with_grass_snow" or platform_material == "mcl_core:podzol" then

@ -5,11 +5,6 @@ settlements.debug = function(message)
minetest.log("verbose", "[mcl_villages] "..message) minetest.log("verbose", "[mcl_villages] "..message)
end end
-- switch for lvm
settlements.lvm = false
settlements.last_settlement = os.time()
--[[ Manually set in 'buildings.lua' --[[ Manually set in 'buildings.lua'
-- material to replace cobblestone with -- material to replace cobblestone with
wallmaterial = { wallmaterial = {
@ -56,43 +51,25 @@ schem_path = settlements.modpath.."/schematics/"
-- --
local basic_pseudobiome_villages = minetest.settings:get_bool("basic_pseudobiome_villages", false) local basic_pseudobiome_villages = minetest.settings:get_bool("basic_pseudobiome_villages", false)
if basic_pseudobiome_villages == true then settlements.schematic_table = {
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 = "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 = basic_pseudobiome_villages },
{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 = basic_pseudobiome_villages },
{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 = basic_pseudobiome_villages },
{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 = basic_pseudobiome_villages },
{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 = false },
{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 = basic_pseudobiome_villages },
{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 = 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 = "y"}, {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 = "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 = basic_pseudobiome_villages },
{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 = basic_pseudobiome_villages },
{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
-- --
-- list of settlements, load on server start up -- list of settlements, load on server start up
-- --
settlements_in_world = {} settlements_in_world = {}
-- --
-- min_distance between settlements
--
settlements.min_dist_settlements = 64
-- --
-- maximum allowed difference in height for building a sttlement -- maximum allowed difference in height for building a sttlement
-- --

@ -1,23 +1,22 @@
-- --
function settlements.convert_mts_to_lua() function settlements.convert_mts_to_lua()
local building = schem_path.."townhall.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.."church"..".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))
end end
function settlements.mts_save() function settlements.mts_save()
local f = assert(io.open(schem_path.."hut.lua", "r")) local f = assert(io.open(schem_path.."hut.lua", "r"))
local content = f:read("*all").." return(schematic2)" local content = f:read("*all").." return(schematic2)"
f:close() f:close()
local schematic2 = loadstring("schematic2 = "..content)() local schematic2 = loadstring("schematic2 = "..content)()
local seb = minetest.serialize_schematic(schematic2, "mts", {}) local seb = minetest.serialize_schematic(schematic2, "mts", {})
local filename = schem_path .. "hut2" .. ".mts" local filename = schem_path .. "hut2" .. ".mts"
filename = filename:gsub("\"", "\\\""):gsub("\\", "\\\\") filename = filename:gsub("\"", "\\\""):gsub("\\", "\\\\")
local file, err = io.open(filename, "wb") local file, err = io.open(filename, "wb")
@ -27,4 +26,4 @@ function settlements.mts_save()
file:close() file:close()
end end
print("Wrote: " .. filename) print("Wrote: " .. filename)
end end

@ -1,28 +1,6 @@
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- 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_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 function settlements.ground(pos, pr) -- role model: Wendelsteinkircherl, Brannenburg
local p2 = vector.new(pos) local p2 = vector.new(pos)
local cnt = 0 local cnt = 0
@ -41,113 +19,47 @@ end
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- function clear space above baseplate -- 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) function settlements.terraform(settlement_info, pr)
local fheight local fheight, fwidth, fdepth, schematic_data
local fwidth
local fdepth
local schematic_data
for i, built_house in ipairs(settlement_info) do for i, built_house in ipairs(settlement_info) do
-- pick right schematic_info to current built_house -- pick right schematic_info to current built_house
for j, schem in ipairs(schematic_table) do for j, schem in ipairs(settlements.schematic_table) do
if settlement_info[i]["name"] == schem["name"] if settlement_info[i]["name"] == schem["name"] then
then schematic_data = schem
schematic_data = schem break
break end
end end
end local pos = settlement_info[i]["pos"]
local pos = settlement_info[i]["pos"] if settlement_info[i]["rotat"] == "0" or settlement_info[i]["rotat"] == "180" then
if settlement_info[i]["rotat"] == "0" or settlement_info[i]["rotat"] == "180" fwidth = schematic_data["hwidth"]
then fdepth = schematic_data["hdepth"]
fwidth = schematic_data["hwidth"] else
fdepth = schematic_data["hdepth"] fwidth = schematic_data["hdepth"]
else fdepth = schematic_data["hwidth"]
fwidth = schematic_data["hdepth"] end
fdepth = schematic_data["hwidth"] --fheight = schematic_data["hheight"] * 3 -- remove trees and leaves above
end fheight = schematic_data["hheight"] -- remove trees and leaves above
--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
-- --
-- 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 xi = 0,fwidth-1 do for yi = 0,fheight *3 do
for zi = 0,fdepth-1 do if yi == 0 then
for yi = 0,fheight *3 do local p = {x=pos.x+xi, y=pos.y, z=pos.z+zi}
if yi == 0 then settlements.ground(p, pr)
local p = {x=pos.x+xi, y=pos.y, z=pos.z+zi} else
settlements.ground(p, pr) -- write ground
else local p = {x=pos.x+xi, y=pos.y+yi, z=pos.z+zi}
-- write ground minetest.forceload_block(p)
local p = {x=pos.x+xi, y=pos.y+yi, z=pos.z+zi} local node = minetest.get_node_or_nil(p)
minetest.forceload_block(p) if node and node.name ~= "air" then
local node = minetest.get_node_or_nil(p) minetest.swap_node(p,{name="air"})
if node then end
if node.name ~= "air" end
then end
minetest.swap_node(p,{name="air"}) end
end end
end end
end
end
end
end
end
end end

@ -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 = {}
settlements.modpath = minetest.get_modpath("mcl_villages"); settlements.modpath = minetest.get_modpath("mcl_villages")
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") --dofile(settlements.modpath.."/convert_lua_mts.lua")
-- --
-- load settlements on server -- load settlements on server
-- --
@ -55,42 +47,20 @@ end
-- on map generation, try to build a settlement -- on map generation, try to build a settlement
-- --
local function build_a_settlement_no_delay(minp, maxp, blockseed) local function build_a_settlement_no_delay(minp, maxp, blockseed)
local settlement_info
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)
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
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
if settlements.lvm == true then settlements.terraform(settlement_info, pr)
settlements.terraform_lvm(settlement_info, pr)
else
settlements.terraform(settlement_info, pr)
end
-- evaluate settlement_info and build paths between buildings -- evaluate settlement_info and build paths between buildings
if settlements.lvm == true then settlements.paths(settlement_info)
settlements.paths_lvm(settlement_info, minp)
else
settlements.paths(settlement_info)
end
-- evaluate settlement_info and place schematics -- evaluate settlement_info and place schematics
if settlements.lvm == true then settlements.place_schematics(settlement_info, pr)
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 -- evaluate settlement_info and initialize furnaces and chests
settlements.initialize_nodes(settlement_info, pr) settlements.initialize_nodes(settlement_info, pr)
@ -112,126 +82,27 @@ minetest.register_on_generated(function(minp, maxp, blockseed)
-- don't build settlement underground -- don't build settlement underground
if maxp.y < 0 then return end 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 -- don't build settlements on (too) uneven terrain
local height_difference = settlements.evaluate_heightmap(minp, maxp) local height_difference = settlements.evaluate_heightmap(minp, maxp)
if height_difference > max_height_difference then return end 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}) 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: -- 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}) -- minetest.after(3, ecb_build_a_settlement, nil, 1, 0, {minp = vector.new(minp), maxp=vector.new(maxp), blockseed=blockseed})
end) end)
-- -- manually place villages
-- manually place buildings, for debugging only if minetest.is_creative_enabled("") then
-- minetest.register_craftitem("mcl_villages:tool", {
minetest.register_craftitem("mcl_villages:tool", { description = "mcl_villages build tool",
description = "mcl_villages build tool", inventory_image = "default_tool_woodshovel.png",
inventory_image = "default_tool_woodshovel.png", -- build ssettlement
on_place = function(itemstack, placer, pointed_thing)
--[[ Disable on_use for now. if not pointed_thing.under then return end
-- build single house local minp = vector.subtract( pointed_thing.under, half_map_chunk_size)
-- local maxp = vector.add( pointed_thing.under, half_map_chunk_size)
on_use = function(itemstack, placer, pointed_thing) build_a_settlement_no_delay(minp, maxp, math.random(0,32767))
local center_surface = pointed_thing.under end
if center_surface then })
local building_all_info = {name = "blacksmith", end
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
})

@ -1,99 +1,6 @@
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- generate paths between buildings -- 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) function settlements.paths(settlement_info)
local starting_point local starting_point
local end_point local end_point

@ -1,5 +1,3 @@
mcl_villages = {}
local c_dirt_with_grass = minetest.get_content_id("mcl_core:dirt_with_grass") 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_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") --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 return math.floor(num * mult + 0.5) / mult
end 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 -- function to find surface block y coordinate
-- returns surface postion -- returns surface postion
@ -170,79 +117,58 @@ end
-- check distance for new building -- check distance for new building
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
function settlements.check_distance(settlement_info, building_pos, building_size) function settlements.check_distance(settlement_info, 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
distance = math.sqrt( distance = math.sqrt(
((building_pos.x - built_house["pos"].x)*(building_pos.x - built_house["pos"].x))+ ((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))) ((building_pos.z - built_house["pos"].z)*(building_pos.z - built_house["pos"].z)))
if distance < building_size or if distance < building_size or distance < built_house["hsize"] then
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
return false return false
end end
end end
return true return true
end 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 -- fill chests
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
function settlements.fill_chest(pos, pr) function settlements.fill_chest(pos, pr)
-- find chests within radius -- initialize chest (mts chests don't have meta)
--local chestpos = minetest.find_node_near(pos, 6, {"mcl_core:chest"}) local meta = minetest.get_meta(pos)
local chestpos = pos if meta:get_string("infotext") ~= "Chest" then
-- initialize chest (mts chests don't have meta) -- For MineClone2 0.70 or before
local meta = minetest.get_meta(chestpos) -- minetest.registered_nodes["mcl_chests:chest"].on_construct(pos)
if meta:get_string("infotext") ~= "Chest" then --
-- For MineClone2 0.70 or before -- For MineClone2 after commit 09ab1482b5 (the new entity chests)
-- minetest.registered_nodes["mcl_chests:chest"].on_construct(chestpos) minetest.registered_nodes["mcl_chests:chest_small"].on_construct(pos)
-- end
-- For MineClone2 after commit 09ab1482b5 (the new entity chests) -- fill chest
minetest.registered_nodes["mcl_chests:chest_small"].on_construct(chestpos) local inv = minetest.get_inventory( {type="node", pos=pos} )
end
-- fill chest local function get_treasures(pr)
local inv = minetest.get_inventory( {type="node", pos=chestpos} ) local loottable = {{
function mcl_villages.get_treasures(pr)
local loottable = {
{
stacks_min = 3, stacks_min = 3,
stacks_max = 8, stacks_max = 8,
items = { items = {
@ -264,14 +190,13 @@ function settlements.fill_chest(pos, pr)
{ itemstring = "mobs_mc:gold_horse_armor", weight = 1 }, { itemstring = "mobs_mc:gold_horse_armor", weight = 1 },
{ itemstring = "mobs_mc:diamond_horse_armor", weight = 1 }, { itemstring = "mobs_mc:diamond_horse_armor", weight = 1 },
} }
}, }}
}
local items = mcl_loot.get_multi_loot(loottable, pr) local items = mcl_loot.get_multi_loot(loottable, pr)
return items return items
end end
local items = mcl_villages.get_treasures(pr) local items = get_treasures(pr)
mcl_loot.fill_inventory(inv, "main", items) mcl_loot.fill_inventory(inv, "main", items)
end end
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@ -316,23 +241,23 @@ end
local building_all_info local building_all_info
function settlements.initialize_nodes(settlement_info, pr) function settlements.initialize_nodes(settlement_info, pr)
for i, built_house in ipairs(settlement_info) do 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 if settlement_info[i]["name"] == schem["name"] then
building_all_info = schem building_all_info = schem
break break
end end
end end
local width = building_all_info["hwidth"] local width = building_all_info["hwidth"]
local depth = building_all_info["hdepth"] local depth = building_all_info["hdepth"]
local height = building_all_info["hheight"] local height = building_all_info["hheight"]
local p = settlement_info[i]["pos"] local p = settlement_info[i]["pos"]
for yi = 1,height do for yi = 1,height do
for xi = 0,width do for xi = 0,width do
for zi = 0,depth do for zi = 0,depth do
local ptemp = {x=p.x+xi, y=p.y+yi, z=p.z+zi} 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 if node.name == "mcl_furnaces:furnace" or
node.name == "mcl_chests:chest" or node.name == "mcl_chests:chest" or
node.name == "mcl_anvils:anvil" then node.name == "mcl_anvils:anvil" then
@ -403,32 +328,11 @@ function settlements.evaluate_heightmap()
return height_diff return height_diff
end 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 -- Set array to list
-- https://stackoverflow.com/questions/656199/search-for-an-item-in-a-lua-list -- https://stackoverflow.com/questions/656199/search-for-an-item-in-a-lua-list
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
function settlements.Set (list) function settlements.Set (list)
local set = {} local set = {}
for _, l in ipairs(list) do set[l] = true end for _, l in ipairs(list) do set[l] = true end
return set return set
end end