Big villages overhaul
This commit is contained in:
parent
238c5a650e
commit
d89eec9d98
|
@ -2,7 +2,7 @@
|
|||
-------------------------------------------------------------------------------
|
||||
-- build schematic, replace material, rotation
|
||||
-------------------------------------------------------------------------------
|
||||
function settlements.build_schematic(vm, data, va, pos, building, replace_wall, name)
|
||||
function mcl_villages.build_schematic(vm, data, va, pos, building, replace_wall, name)
|
||||
-- get building node material for better integration to surrounding
|
||||
local platform_material = mcl_vars.get_node(pos)
|
||||
if not platform_material or (platform_material.name == "air" or platform_material.name == "ignore") then
|
||||
|
@ -36,7 +36,7 @@ function settlements.build_schematic(vm, data, va, pos, building, replace_wall,
|
|||
local height = schematic["size"]["y"]
|
||||
local possible_rotations = {"0", "90", "180", "270"}
|
||||
local rotation = possible_rotations[ math.random( #possible_rotations ) ]
|
||||
settlements.foundation(
|
||||
mcl_villages.foundation(
|
||||
pos,
|
||||
width,
|
||||
depth,
|
||||
|
@ -57,123 +57,125 @@ end]]
|
|||
-------------------------------------------------------------------------------
|
||||
-- initialize settlement_info
|
||||
-------------------------------------------------------------------------------
|
||||
function settlements.initialize_settlement_info(pr)
|
||||
function mcl_villages.initialize_settlement_info(pr)
|
||||
local count_buildings = {}
|
||||
|
||||
-- count_buildings table reset
|
||||
for k,v in pairs(settlements.schematic_table) do
|
||||
for k,v in pairs(mcl_villages.schematic_table) do
|
||||
count_buildings[v["name"]] = 0
|
||||
end
|
||||
|
||||
-- randomize number of buildings
|
||||
local number_of_buildings = pr:next(10, 25)
|
||||
local number_built = 1
|
||||
settlements.debug("Village ".. number_of_buildings)
|
||||
local number_built = 0
|
||||
mcl_villages.debug("Village ".. number_of_buildings)
|
||||
|
||||
return count_buildings, number_of_buildings, number_built
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- check ground for a single building
|
||||
-------------------------------------------------------------------------------
|
||||
local function try_place_building(pos_surface, building_all_info, rotation, settlement_info, pr)
|
||||
local fwidth, fdepth = building_all_info["hwidth"], building_all_info["hdepth"]
|
||||
if rotation == "90" or rotation == "270" then fwidth, fdepth = fdepth, fwidth end
|
||||
local fheight = building_all_info["hheight"]
|
||||
-- use building centers for better placement
|
||||
pos_surface.x = pos_surface.x - math.ceil(fwidth / 2)
|
||||
pos_surface.z = pos_surface.z - math.ceil(fdepth / 2)
|
||||
-- to find the y position, also check the corners
|
||||
local ys = {pos_surface.y}
|
||||
local pos_c
|
||||
pos_c = mcl_villages.find_surface_down(vector.new(pos_surface.x-1, pos_surface.y+fheight, pos_surface.z-1))
|
||||
if pos_c then table.insert(ys, pos_c.y) end
|
||||
pos_c = mcl_villages.find_surface_down(vector.new(pos_surface.x+fwidth+2, pos_surface.y+fheight, pos_surface.z-1))
|
||||
if pos_c then table.insert(ys, pos_c.y) end
|
||||
pos_c = mcl_villages.find_surface_down(vector.new(pos_surface.x-1, pos_surface.y+fheight, pos_surface.z+fdepth+2))
|
||||
if pos_c then table.insert(ys, pos_c.y) end
|
||||
pos_c = mcl_villages.find_surface_down(vector.new(pos_surface.x+fwidth+2, pos_surface.y+fheight, pos_surface.z+fdepth+2))
|
||||
if pos_c then table.insert(ys, pos_c.y) end
|
||||
table.sort(ys)
|
||||
-- well supported base, not too uneven?
|
||||
if #ys < 5 or ys[#ys]-ys[1] > fheight + 3 then return nil end
|
||||
pos_surface.y = ys[math.ceil(#ys/2)]
|
||||
-- check distance to other buildings
|
||||
if mcl_villages.check_distance(settlement_info, pos_surface, building_all_info["hsize"]) then
|
||||
return pos_surface
|
||||
end
|
||||
return nil
|
||||
end
|
||||
-------------------------------------------------------------------------------
|
||||
-- fill settlement_info
|
||||
--------------------------------------------------------------------------------
|
||||
function settlements.create_site_plan(maxp, minp, pr)
|
||||
local settlement_info = {}
|
||||
local building_all_info
|
||||
function mcl_villages.create_site_plan(minp, maxp, pr)
|
||||
local center = vector.new(math.floor((minp.x+maxp.x)/2),maxp.y,math.floor((minp.z+maxp.z)/2))
|
||||
minetest.log("action", "sudo make me a village at: " .. minetest.pos_to_string(center))
|
||||
local possible_rotations = {"0", "90", "180", "270"}
|
||||
local center_surface
|
||||
|
||||
-- find center of chunk
|
||||
local center = {
|
||||
x=math.floor((minp.x+maxp.x)/2),
|
||||
y=maxp.y,
|
||||
z=math.floor((minp.z+maxp.z)/2)
|
||||
}
|
||||
|
||||
-- find center_surface of chunk
|
||||
local center_surface , surface_material = settlements.find_surface(center, true)
|
||||
local chunks = {}
|
||||
chunks[mcl_vars.get_chunk_number(center)] = true
|
||||
|
||||
-- go build settlement around center
|
||||
if not center_surface then
|
||||
minetest.log("action", "Cannot build village at: " .. minetest.pos_to_string(center))
|
||||
return false
|
||||
else
|
||||
minetest.log("action", "Village built.")
|
||||
--minetest.log("action", "Build village at: " .. minetest.pos_to_string(center) .. " with surface material: " .. surface_material)
|
||||
end
|
||||
|
||||
-- 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 = settlements.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
|
||||
local count_buildings, number_of_buildings, number_built = mcl_villages.initialize_settlement_info(pr)
|
||||
local settlement_info = {}
|
||||
-- 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"]
|
||||
local x, y, z, r = center.x, maxp.y, center.z, 0
|
||||
-- draw j circles around center and increase radius by math.random(2,5)
|
||||
for j = 1,20 do
|
||||
-- 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 chunk_number = mcl_vars.get_chunk_number(pos1)
|
||||
local pos_surface, surface_material
|
||||
if chunks[chunk_number] then
|
||||
pos_surface, surface_material = settlements.find_surface(pos1)
|
||||
else
|
||||
chunks[chunk_number] = true
|
||||
pos_surface, surface_material = settlements.find_surface(pos1, true)
|
||||
end
|
||||
if not pos_surface then break end
|
||||
for j = 1,10 do
|
||||
for angle = 0, math.pi*2, 0.262 do -- 24 attempts on a circle
|
||||
local pos1 = vector.new(math.floor(x + r * math.cos(angle) + 0.5), y, math.floor(z - r * math.sin(angle) + 0.5))
|
||||
local pos_surface, surface_material = mcl_villages.find_surface(pos1, false)
|
||||
if pos_surface then
|
||||
local randomized_schematic_table = mcl_villages.shuffle(mcl_villages.schematic_table, pr)
|
||||
if #settlement_info == 0 then randomized_schematic_table = { mcl_villages.schematic_table[1] } end -- place town bell first
|
||||
-- pick schematic
|
||||
local size = #randomized_schematic_table
|
||||
for i = 1, #randomized_schematic_table do
|
||||
local building_all_info = randomized_schematic_table[i]
|
||||
-- already enough buildings of that type?
|
||||
if count_buildings[building_all_info["name"]] < building_all_info["max_num"]*number_of_buildings then
|
||||
local rotation = possible_rotations[pr:next(1, #possible_rotations)]
|
||||
local pos = try_place_building(pos_surface, building_all_info, rotation, settlement_info, pr)
|
||||
if pos then
|
||||
if #settlement_info == 0 then -- town bell
|
||||
center_surface, y = pos, pos.y + max_height_difference
|
||||
end
|
||||
-- limit height differences to town center
|
||||
if math.abs(pos.y - center_surface.y) > max_height_difference * 0.7 then
|
||||
break -- other buildings likely will not fit either
|
||||
end
|
||||
count_buildings[building_all_info["name"]] = count_buildings[building_all_info["name"]] +1
|
||||
number_built = number_built + 1
|
||||
|
||||
local randomized_schematic_table = shuffle(settlements.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
|
||||
pos.y = pos.y + (building_all_info["yadjust"] or 0)
|
||||
table.insert(settlement_info, {
|
||||
pos = pos,
|
||||
name = building_all_info["name"],
|
||||
hsize = building_all_info["hsize"],
|
||||
rotat = rotation,
|
||||
surface_mat = surface_material
|
||||
})
|
||||
-- minetest.log("action", "Placing "..building_all_info["name"].." at "..minetest.pos_to_string(pos))
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if number_of_buildings == number_built then
|
||||
break
|
||||
end
|
||||
end
|
||||
if number_of_buildings == number_built then
|
||||
break
|
||||
end
|
||||
if r == 0 then break end -- no angles in the very center
|
||||
end
|
||||
if number_built >= number_of_buildings then
|
||||
break
|
||||
end
|
||||
r = r + pr:next(2,5)
|
||||
if r > 35 then break end -- avoid touching neighboring blocks
|
||||
end
|
||||
settlements.debug("really ".. number_built)
|
||||
mcl_villages.debug("really ".. number_built)
|
||||
if number_built <= 8 then
|
||||
minetest.log("action", "Bad village location, could only place "..number_built.." buildings.")
|
||||
return
|
||||
end
|
||||
minetest.log("action", "Village completed at " .. minetest.pos_to_string(center))
|
||||
minetest.log("Village completed at " .. minetest.pos_to_string(center)) -- for debugging only
|
||||
return settlement_info
|
||||
end
|
||||
-------------------------------------------------------------------------------
|
||||
|
@ -201,6 +203,7 @@ local function spawn_iron_golem(pos)
|
|||
--minetest.log("action", "Attempt to spawn iron golem.")
|
||||
local p = minetest.find_node_near(pos,50,"mcl_core:grass_path")
|
||||
if p then
|
||||
p.y = p.y + 1
|
||||
local l=minetest.add_entity(p,"mobs_mc:iron_golem"):get_luaentity()
|
||||
if l then
|
||||
l._home = p
|
||||
|
@ -245,100 +248,63 @@ local function init_nodes(p1, p2, size, rotation, pr)
|
|||
if nodes and #nodes > 0 then
|
||||
for p=1, #nodes do
|
||||
local pos = nodes[p]
|
||||
settlements.fill_chest(pos, pr)
|
||||
mcl_villages.fill_chest(pos, pr)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function settlements.place_schematics(settlement_info, pr)
|
||||
function mcl_villages.place_schematics(settlement_info, pr)
|
||||
local building_all_info
|
||||
local lvm = VoxelManip()
|
||||
|
||||
for i, built_house in ipairs(settlement_info) do
|
||||
local is_last = i == #settlement_info
|
||||
|
||||
for j, schem in ipairs(settlements.schematic_table) do
|
||||
for j, schem in ipairs(mcl_villages.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"
|
||||
schem_lua = schem_lua:gsub("mcl_core:stonebrickcarved", "mcl_villages:stonebrickcarved")
|
||||
-- replace material
|
||||
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.
|
||||
-- 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
|
||||
local surface_material = settlement_info[i]["surface_mat"] or "mcl_core:stone"
|
||||
local platform_material = surface_material
|
||||
local schem_lua = building_all_info["schem_lua"]
|
||||
if not schem_lua then
|
||||
schem_lua = minetest.serialize_schematic(building_all_info["mts"], "lua", { lua_use_comments = false, lua_num_indent_spaces = 0 }) .. " return schematic"
|
||||
building_all_info["schem_lua"] = schem_lua
|
||||
end
|
||||
schem_lua = schem_lua:gsub("mcl_core:dirt_with_grass", platform_material)
|
||||
|
||||
--[[ Disable special junglewood for now.
|
||||
-- special material for spawning npcs
|
||||
schem_lua = schem_lua:gsub("mcl_core:junglewood", "settlements:junglewood")
|
||||
--]]
|
||||
|
||||
schem_lua = schem_lua:gsub("mcl_stairs:stair_wood_outer", "mcl_stairs:slab_wood")
|
||||
schem_lua = schem_lua:gsub("mcl_stairs:stair_stone_rough_outer", "air")
|
||||
|
||||
-- format schematic string
|
||||
local schematic = loadstring(schem_lua)()
|
||||
schem_lua = schem_lua:gsub('"mcl_core:dirt"', '"'..platform_material..'"')
|
||||
schem_lua = schem_lua:gsub('"mcl_core:dirt_with_grass"', '"'..surface_material..'"')
|
||||
local schematic = loadstring(mcl_villages.substitute_materials(pos, schem_lua, pr))()
|
||||
|
||||
local is_belltower = building_all_info["name"] == "belltower"
|
||||
|
||||
-- build foundation for the building an make room above
|
||||
|
||||
mcl_structures.place_schematic(
|
||||
-- already built the foundation for the building and made room above
|
||||
local sx, sy, sz = schematic.size.x, schematic.size.y, schematic.size.z
|
||||
local p2 = vector.new(pos.x+sx-1,pos.y+sy-1,pos.z+sz-1)
|
||||
lvm:read_from_map(pos, p2)
|
||||
minetest.place_schematic_on_vmanip(
|
||||
lvm,
|
||||
pos,
|
||||
schematic,
|
||||
rotation,
|
||||
nil,
|
||||
true,
|
||||
nil,
|
||||
function(p1, p2, size, rotation, pr)
|
||||
if is_belltower then
|
||||
spawn_iron_golem(p1)
|
||||
else
|
||||
init_nodes(p1, p2, size, rotation, pr)
|
||||
spawn_villagers(p1,p2)
|
||||
fix_village_water(p1,p2)
|
||||
end
|
||||
end,
|
||||
pr
|
||||
{ place_center_x = false, place_center_y = false, place_center_z = false }
|
||||
)
|
||||
lvm:write_to_map(true) -- FIXME: postpone
|
||||
if rotation == "90" or rotation == "270" then sx, sz = sz, sx end
|
||||
init_nodes(pos, p2, schematic.size, rotation, pr)
|
||||
|
||||
if is_belltower then
|
||||
spawn_iron_golem(pos)
|
||||
else
|
||||
spawn_villagers(pos,p2)
|
||||
fix_village_water(pos,p2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
-- switch for debugging
|
||||
function settlements.debug(message)
|
||||
function mcl_villages.debug(message)
|
||||
-- minetest.chat_send_all(message)
|
||||
-- minetest.log("warning", "[mcl_villages] "..message)
|
||||
minetest.log("verbose", "[mcl_villages] "..message)
|
||||
|
@ -20,44 +20,51 @@ local wallmaterial = {
|
|||
"mcl_core:sandstonesmooth2"
|
||||
}
|
||||
--]]
|
||||
settlements.surface_mat = {}
|
||||
-------------------------------------------------------------------------------
|
||||
-- Set array to list
|
||||
-- https://stackoverflow.com/questions/656199/search-for-an-item-in-a-lua-list
|
||||
-------------------------------------------------------------------------------
|
||||
function settlements.grundstellungen()
|
||||
settlements.surface_mat = settlements.Set {
|
||||
"mcl_core:dirt_with_grass",
|
||||
--"mcl_core:dry_dirt_with_grass",
|
||||
"mcl_core:dirt_with_grass_snow",
|
||||
--"mcl_core:dirt_with_dry_grass",
|
||||
"mcl_core:podzol",
|
||||
"mcl_core:sand",
|
||||
"mcl_core:redsand",
|
||||
--"mcl_core:silver_sand",
|
||||
"mcl_core:snow"
|
||||
}
|
||||
end
|
||||
--
|
||||
-- possible surfaces where buildings can be built
|
||||
--
|
||||
mcl_villages.surface_mat = {}
|
||||
mcl_villages.surface_mat["mcl_core:andesite"] = true
|
||||
mcl_villages.surface_mat["mcl_core:diorite"] = true
|
||||
mcl_villages.surface_mat["mcl_core:dirt"] = true
|
||||
mcl_villages.surface_mat["mcl_core:dirt_with_grass"] = true
|
||||
--mcl_villages.surface_mat["mcl_core:dirt_with_dry_grass"] = true
|
||||
mcl_villages.surface_mat["mcl_core:dirt_with_grass_snow"] = true
|
||||
--mcl_villages.surface_mat["mcl_core:dry_dirt_with_grass"] = true
|
||||
mcl_villages.surface_mat["mcl_core:grass_path"] = true
|
||||
mcl_villages.surface_mat["mcl_core:granite"] = true
|
||||
mcl_villages.surface_mat["mcl_core:podzol"] = true
|
||||
mcl_villages.surface_mat["mcl_core:redsand"] = true
|
||||
mcl_villages.surface_mat["mcl_core:sand"] = true
|
||||
mcl_villages.surface_mat["mcl_core:sandstone"] = true
|
||||
mcl_villages.surface_mat["mcl_core:sandstonesmooth"] = true
|
||||
mcl_villages.surface_mat["mcl_core:sandstonesmooth2"] = true
|
||||
--mcl_villages.surface_mat["mcl_core:silver_sand"] = true
|
||||
mcl_villages.surface_mat["mcl_core:snow"] = true
|
||||
mcl_villages.surface_mat["mcl_core:stone"] = true
|
||||
mcl_villages.surface_mat["mcl_core:stone_with_coal"] = true
|
||||
mcl_villages.surface_mat["mcl_core:stone_with_iron"] = true
|
||||
mcl_villages.surface_mat["mcl_colorblocks:hardened_clay"] = true
|
||||
mcl_villages.surface_mat["mcl_colorblocks:hardened_clay_orange"] = true
|
||||
mcl_villages.surface_mat["mcl_colorblocks:hardened_clay_red"] = true
|
||||
mcl_villages.surface_mat["mcl_colorblocks:hardened_clay_white"] = true
|
||||
|
||||
--
|
||||
-- path to schematics
|
||||
--
|
||||
schem_path = settlements.modpath.."/schematics/"
|
||||
schem_path = mcl_villages.modpath.."/schematics/"
|
||||
--
|
||||
-- list of schematics
|
||||
--
|
||||
local basic_pseudobiome_villages = minetest.settings:get_bool("basic_pseudobiome_villages", true)
|
||||
|
||||
settlements.schematic_table = {
|
||||
{name = "belltower", mts = schem_path.."belltower.mts", hwidth = 5, hdepth = 5, hheight = 9, hsize = 14, max_num = 0 , rplc = basic_pseudobiome_villages },
|
||||
mcl_villages.schematic_table = {
|
||||
{name = "belltower", mts = schem_path.."belltower.mts", hwidth = 5, hdepth = 5, hheight = 9, hsize = 14, max_num = 0.0001 , rplc = basic_pseudobiome_villages, yadjust = 1 },
|
||||
{name = "large_house", mts = schem_path.."large_house.mts", hwidth = 12, hdepth = 12, hheight = 9, hsize = 14, max_num = 0.08 , rplc = basic_pseudobiome_villages },
|
||||
{name = "blacksmith", mts = schem_path.."blacksmith.mts", hwidth = 8, hdepth = 11, hheight = 13, hsize = 13, max_num = 0.055, rplc = basic_pseudobiome_villages },
|
||||
{name = "blacksmith", mts = schem_path.."blacksmith.mts", hwidth = 8, hdepth = 11, hheight = 13, hsize = 13, max_num = 0.055 , rplc = basic_pseudobiome_villages },
|
||||
{name = "butcher", mts = schem_path.."butcher.mts", hwidth = 12, hdepth = 8, hheight = 10, hsize = 14, max_num = 0.03 , rplc = basic_pseudobiome_villages },
|
||||
{name = "church", mts = schem_path.."church.mts", hwidth = 13, hdepth = 13, hheight = 14, hsize = 15, max_num = 0.04 , rplc = basic_pseudobiome_villages },
|
||||
{name = "farm", mts = schem_path.."farm.mts", hwidth = 9, hdepth = 7, hheight = 13, hsize = 13, max_num = 0.1 , rplc = basic_pseudobiome_villages },
|
||||
{name = "farm", mts = schem_path.."farm.mts", hwidth = 9, hdepth = 7, hheight = 13, hsize = 13, max_num = 0.1 , rplc = basic_pseudobiome_villages, yadjust = 1 },
|
||||
{name = "lamp", mts = schem_path.."lamp.mts", hwidth = 3, hdepth = 4, hheight = 13, hsize = 10, max_num = 0.1 , rplc = false },
|
||||
{name = "library", mts = schem_path.."library.mts", hwidth = 12, hdepth = 12, hheight = 8, hsize = 13, max_num = 0.04 , rplc = basic_pseudobiome_villages },
|
||||
{name = "medium_house", mts = schem_path.."medium_house.mts", hwidth = 9, hdepth = 12, hheight = 8, hsize = 14, max_num = 0.08 , rplc = basic_pseudobiome_villages },
|
||||
|
@ -67,7 +74,7 @@ settlements.schematic_table = {
|
|||
}
|
||||
|
||||
--
|
||||
-- maximum allowed difference in height for building a sttlement
|
||||
-- maximum allowed difference in height for building a settlement
|
||||
--
|
||||
max_height_difference = 56
|
||||
--
|
||||
|
@ -75,3 +82,185 @@ max_height_difference = 56
|
|||
--
|
||||
half_map_chunk_size = 40
|
||||
--quarter_map_chunk_size = 20
|
||||
|
||||
--
|
||||
-- Biome based block substitutions
|
||||
--
|
||||
-- TODO maybe this should be in the biomes?
|
||||
mcl_villages.biome_map = {
|
||||
BambooJungle = "bamboo",
|
||||
BambooJungleEdge = "bamboo",
|
||||
BambooJungleEdgeM = "bamboo",
|
||||
BambooJungleM = "bamboo",
|
||||
|
||||
Jungle = "jungle",
|
||||
JungleEdge = "jungle",
|
||||
JungleEdgeM = "jungle",
|
||||
JungleM = "jungle",
|
||||
|
||||
Desert = "desert",
|
||||
|
||||
Savanna = "acacia",
|
||||
SavannaM = "acacia",
|
||||
|
||||
Mesa = "hardened_clay",
|
||||
MesaBryce = "hardened_clay ",
|
||||
MesaPlateauF = "hardened_clay",
|
||||
MesaPlateauFM = "hardened_clay",
|
||||
|
||||
MangroveSwamp = "mangrove",
|
||||
|
||||
RoofedForest = "dark_oak",
|
||||
|
||||
BirchForest = "birch",
|
||||
BirchForestM = "birch",
|
||||
|
||||
ColdTaiga = "spruce",
|
||||
ExtremeHills = "spruce",
|
||||
ExtremeHillsM = "spruce",
|
||||
IcePlains = "spruce",
|
||||
IcePlainsSpikes = "spruce",
|
||||
MegaSpruceTaiga = "spruce",
|
||||
MegaTaiga = "spruce",
|
||||
Taiga = "spruce",
|
||||
["ExtremeHills+"] = "spruce",
|
||||
|
||||
CherryGrove = "cherry",
|
||||
|
||||
-- no change
|
||||
--FlowerForest = "oak",
|
||||
--Forest = "oak",
|
||||
--MushroomIsland = "",
|
||||
--Plains = "oak",
|
||||
--StoneBeach = "",
|
||||
--SunflowerPlains = "oak",
|
||||
--Swampland = "oak",
|
||||
}
|
||||
|
||||
mcl_villages.material_substitions = {
|
||||
desert = {
|
||||
{ '"mcl_stairs:slab_oak([^"]*)"', '"mcl_stairs:slab_sandstonesmooth%1"' },
|
||||
{
|
||||
'"mesecons_pressureplates:pressure_plate_oak_([^"]+)"',
|
||||
'"mesecons_pressureplates:pressure_plate_birchwood_%1"',
|
||||
},
|
||||
{ '"mcl_doors:trapdoor_oak([^"]*)"', '"mcl_doors:birch_trapdoor%1"' },
|
||||
{ '"mcl_doors:door_oak([^"]*)"', '"mcl_doors:birch_door%1"' },
|
||||
|
||||
{ "mcl_core:cobble", "mcl_core:sandstone" },
|
||||
{ '"mcl_stairs:stair_cobble([^"]*)"', '"mcl_stairs:stair_sandstone%1"' },
|
||||
{ '"mcl_walls:cobble([^"]*)"', '"mcl_walls:sandstone%1"' },
|
||||
{ '"mcl_stairs:slab_cobble([^"]*)"', '"mcl_stairs:slab_sandstone%1"' },
|
||||
|
||||
{ '"mcl_core:stonebrick"', '"mcl_core:redsandstone"' },
|
||||
{ '"mcl_core:stonebrick_([^"]+)"', '"mcl_core:redsandstone_%1"' },
|
||||
{ '"mcl_walls:stonebrick([^"]*)"', '"mcl_walls:redsandstone%1"' },
|
||||
{ '"mcl_stairs:stair_stonebrick"', '"mcl_stairs:stair_redsandstone"' },
|
||||
{ '"mcl_stairs:stair_stonebrick_([^"]+)"', '"mcl_stairs:stair_redsandstone_%1"' },
|
||||
|
||||
{ '"mcl_stairs:slab_brick_block([^"]*)"', '"mcl_core:redsandstonesmooth2%1"' },
|
||||
{ '"mcl_core:brick_block"', '"mcl_core:redsandstonesmooth2"' },
|
||||
|
||||
{ "mcl_trees:tree_oak", "mcl_core:redsandstonecarved" },
|
||||
{ "mcl_trees:wood_oak", "mcl_core:redsandstonesmooth" },
|
||||
{ '"mcl_fences:oak_fence([^"]*)"', '"mcl_fences:birch_fence%1"' },
|
||||
{ '"mcl_stairs:stair_oak_bark([^"]*)"', '"mcl_stairs:stair_sandstonesmooth2%1"' },
|
||||
{ '"mcl_stairs:stair_oak([^"]*)"', '"mcl_stairs:stair_sandstonesmooth%1"' },
|
||||
},
|
||||
spruce = {
|
||||
{ '"mcl_stairs:slab_oak([^"]*)"', '"mcl_stairs:slab_sprucewood%1"' },
|
||||
{
|
||||
'"mesecons_pressureplates:pressure_plate_oak_([^"]+)"',
|
||||
'"mesecons_pressureplates:pressure_plate_sprucewood_%1"',
|
||||
},
|
||||
{ '"mcl_doors:trapdoor_oak([^"]*)"', '"mcl_doors:spruce_trapdoor%1"' },
|
||||
{ '"mcl_doors:door_oak([^"]*)"', '"mcl_doors:spruce_door%1"' },
|
||||
{ "mcl_trees:tree_oak", "mcl_trees:tree_spruce" },
|
||||
{ "mcl_trees:wood_oak", "mcl_trees:wood_spruce" },
|
||||
{ '"mcl_fences:oak_fence([^"]*)"', '"mcl_fences:spruce_fence%1"' },
|
||||
{ '"mcl_stairs:stair_oak([^"]*)"', '"mcl_stairs:stair_spruce%1"' },
|
||||
},
|
||||
birch = {
|
||||
{ '"mcl_stairs:slab_oak([^"]*)"', '"mcl_stairs:slab_birchwood%1"' },
|
||||
{
|
||||
'"mesecons_pressureplates:pressure_plate_oak_([^"]+)"',
|
||||
'"mesecons_pressureplates:pressure_plate_birchwood_%1"',
|
||||
},
|
||||
{ '"mcl_doors:trapdoor_oak([^"]*)"', '"mcl_doors:birch_trapdoor%1"' },
|
||||
{ '"mcl_doors:door_oak([^"]*)"', '"mcl_doors:birch_door%1"' },
|
||||
{ "mcl_trees:tree_oak", "mcl_trees:tree_birch" },
|
||||
{ "mcl_trees:wood_oak", "mcl_trees:wood_birch" },
|
||||
{ '"mcl_fences:oak_fence([^"]*)"', '"mcl_fences:birch_fence%1"' },
|
||||
{ '"mcl_stairs:stair_oak([^"]*)"', '"mcl_stairs:stair_birch%1"' },
|
||||
},
|
||||
acacia = {
|
||||
{ '"mcl_stairs:slab_oak([^"]*)"', '"mcl_stairs:slab_acaciawood%1"' },
|
||||
{
|
||||
'"mesecons_pressureplates:pressure_plate_oak_([^"]+)"',
|
||||
'"mesecons_pressureplates:pressure_plate_acaciawood_%1"',
|
||||
},
|
||||
{ '"mcl_doors:trapdoor_oak([^"]*)"', '"mcl_doors:acacia_trapdoor%1"' },
|
||||
{ '"mcl_doors:door_oak([^"]*)"', '"mcl_doors:acacia_door%1"' },
|
||||
{ "mcl_trees:tree_oak", "mcl_trees:tree_acacia" },
|
||||
{ "mcl_trees:wood_oak", "mcl_trees:wood_acacia" },
|
||||
{ '"mcl_fences:oak_fence([^"]*)"', '"mcl_fences:acacia_fence%1"' },
|
||||
{ '"mcl_stairs:stair_oak([^"]*)"', '"mcl_stairs:stair_acacia%1"' },
|
||||
},
|
||||
dark_oak = {
|
||||
{ '"mcl_stairs:slab_oak([^"]*)"', '"mcl_stairs:slab_darkwood%1"' },
|
||||
{
|
||||
'"mesecons_pressureplates:pressure_plate_oak_([^"]+)"',
|
||||
'"mesecons_pressureplates:pressure_plate_darkwood_%1"',
|
||||
},
|
||||
{ '"mcl_doors:trapdoor_oak([^"]*)"', '"mcl_doors:dark_oak_trapdoor%1"' },
|
||||
{ '"mcl_doors:door_oak([^"]*)"', '"mcl_doors:dark_oak_door%1"' },
|
||||
{ "mcl_trees:tree_oak", "mcl_trees:tree_dark_oak" },
|
||||
{ "mcl_trees:wood_oak", "mcl_trees:wood_dark_oak" },
|
||||
{ '"mcl_fences:oak_fence([^"]*)"', '"mcl_fences:dark_oak_fence%1"' },
|
||||
{ '"mcl_stairs:stair_oak([^"]*)"', '"mcl_stairs:stair_dark_oak%1"' },
|
||||
},
|
||||
jungle = {
|
||||
{ '"mcl_stairs:slab_oak([^"]*)"', '"mcl_stairs:slab_junglewood%1"' },
|
||||
{
|
||||
'"mesecons_pressureplates:pressure_plate_oak_([^"]+)"',
|
||||
'"mesecons_pressureplates:pressure_plate_junglewood_%1"',
|
||||
},
|
||||
{ '"mcl_doors:trapdoor_oak([^"]*)"', '"mcl_doors:jungle_trapdoor%1"' },
|
||||
{ '"mcl_doors:door_oak([^"]*)"', '"mcl_doors:jungle_door%1"' },
|
||||
{ "mcl_trees:tree_oak", "mcl_trees:tree_jungle" },
|
||||
{ "mcl_trees:wood_oak", "mcl_trees:wood_jungle" },
|
||||
{ '"mcl_fences:oak_fence([^"]*)"', '"mcl_fences:jungle_fence%1"' },
|
||||
{ '"mcl_stairs:stair_oak([^"]*)"', '"mcl_stairs:stair_jungle%1"' },
|
||||
},
|
||||
bamboo = {
|
||||
{ '"mcl_stairs:slab_oak([^"]*)"', '"mcl_stairs:slab_bamboo_block%1"' },
|
||||
{
|
||||
'"mesecons_pressureplates:pressure_plate_oak_([^"]+)"',
|
||||
'"mesecons_pressureplates:pressure_plate_bamboo_%1"',
|
||||
},
|
||||
{ '"mcl_doors:trapdoor_oak([^"]*)"', '"mcl_doors:trapdoor_bamboo%1"' },
|
||||
{ '"mcl_doors:door_oak([^"]*)"', '"mcl_doors:door_bamboo%1"' },
|
||||
|
||||
{ "mcl_core:cobble", "mcl_core:andesite" },
|
||||
{ '"mcl_stairs:stair_cobble([^"]*)"', '"mcl_stairs:stair_andesite%1"' },
|
||||
{ '"mcl_walls:cobble([^"]*)"', '"mcl_walls:andesite%1"' },
|
||||
{ '"mcl_stairs:slab_cobble([^"]*)"', '"mcl_stairs:slab_andesite%1"' },
|
||||
{ "mcl_trees:tree_oak", "mcl_trees:tree_bamboo" },
|
||||
{ "mcl_trees:wood_oak", "mcl_trees:wood_bamboo" },
|
||||
{ '"mcl_fences:oak_fence([^"]*)"', '"mcl_fences:bamboo_fence%1"' },
|
||||
{ '"mcl_stairs:stair_oak([^"]*)"', '"mcl_stairs:stair_bamboo%1"' },
|
||||
},
|
||||
cherry = {
|
||||
{ '"mcl_stairs:slab_oak([^"]*)"', '"mcl_stairs:slab_cherry_blossom%1"' },
|
||||
{
|
||||
'"mesecons_pressureplates:pressure_plate_oak_([^"]+)"',
|
||||
'"mesecons_pressureplates:pressure_plate_cherry_blossom_%1"',
|
||||
},
|
||||
{ '"mcl_doors:trapdoor_oak([^"]*)"', '"mcl_doors:trapdoor_cherry_blossom%1"' },
|
||||
{ '"mcl_doors:door_oak([^"]*)"', '"mcl_doors:door_cherry_blossom%1"' },
|
||||
{ "mcl_trees:tree_oak", "mcl_trees:tree_cherry_blossom" },
|
||||
{ "mcl_trees:wood_oak", "mcl_trees:wood_cherry_blossom" },
|
||||
{ '"mcl_fences:oak_fence([^"]*)"', '"mcl_fences:cherry_blossom_fence%1"' },
|
||||
{ '"mcl_stairs:stair_oak([^"]*)"', '"mcl_stairs:stair_cherry_blossom%1"' },
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,48 +1,71 @@
|
|||
local function mcl_log (message)
|
||||
mcl_util.mcl_log (message, "[Village - Foundation]")
|
||||
end
|
||||
|
||||
local foundation_materials = {}
|
||||
|
||||
foundation_materials["mcl_core:sand"] = "mcl_core:sandstone"
|
||||
--"mcl_core:sandstonecarved"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- function to fill empty space below baseplate when building on a hill
|
||||
-------------------------------------------------------------------------------
|
||||
function settlements.ground(pos, pr, platform_material) -- role model: Wendelsteinkircherl, Brannenburg
|
||||
local p2 = vector.new(pos)
|
||||
local cnt = 0
|
||||
|
||||
local mat = "mcl_core:dirt"
|
||||
if not platform_material then
|
||||
mat = "mcl_core:dirt"
|
||||
else
|
||||
mat = platform_material
|
||||
end
|
||||
|
||||
p2.y = p2.y-1
|
||||
while true do
|
||||
cnt = cnt+1
|
||||
if cnt > 20 then break end
|
||||
if cnt>pr:next(2,4) then
|
||||
if not platform_material then
|
||||
mat = "mcl_core:stone"
|
||||
end
|
||||
local function is_air(node)
|
||||
return not node or node.name == "air" or node.name == "ignore"
|
||||
end
|
||||
local function is_solid(node)
|
||||
if not node or node.name == "air" or node.name == "ignore" then return false end
|
||||
--if string.find(node.name,"leaf") then return false end
|
||||
--if string.find(node.name,"tree") then return false end
|
||||
local ndef = minetest.registered_nodes[node.name]
|
||||
return ndef and ndef.walkable
|
||||
end
|
||||
local function excavate(lvm,xi,yi,zi,pr)
|
||||
local pos, n, c = vector.new(xi,yi,zi), nil, 0
|
||||
local node = lvm:get_node_at(pos)
|
||||
if is_air(node) then return false end -- already empty, nothing to do
|
||||
pos.y = pos.y-1
|
||||
if not is_air(lvm:get_node_at(pos)) then return false end -- below is solid, do not clear above anymore
|
||||
-- count empty nodes below otherwise
|
||||
for x = xi-1,xi+1 do
|
||||
for z = zi-1,zi+1 do
|
||||
pos.x, pos.z = x, z
|
||||
if is_air(lvm:get_node_at(pos)) then c = c + 1 end
|
||||
end
|
||||
minetest.swap_node(p2, {name=mat})
|
||||
p2.y = p2.y-1
|
||||
end
|
||||
-- try to completely remove trees overhead
|
||||
if not string.find(node.name, "leaf") and not string.find(node.name, "tree") then
|
||||
-- stop randomly depending on fill, to narrow down the caves
|
||||
if pr:next(0,905) > c * 100 then return false end
|
||||
end
|
||||
lvm:set_node_at(vector.new(xi, yi, zi),{name="air"})
|
||||
return true -- modified
|
||||
end
|
||||
local function grow_foundation(lvm,xi,yi,zi,pr,surface_mat,platform_mat)
|
||||
local pos, n, c = vector.new(xi,yi,zi), nil, 0
|
||||
if is_solid(lvm:get_node_at(pos)) then return false end -- already solid, nothing to do
|
||||
pos.y = pos.y+1
|
||||
local cur = lvm:get_node_at(pos)
|
||||
if not is_solid(cur) then return false end -- above is empty, do not fill below
|
||||
if cur and cur.name and cur.name ~= surface_mat then platform_mat = cur.name end
|
||||
if pr:next(1,5) == 5 then -- randomly switch to stone sometimes
|
||||
platform_mat = "mcl_core:stone"
|
||||
end
|
||||
-- count solid nodes above otherwise
|
||||
for x = xi-1,xi+1 do
|
||||
for z = zi-1,zi+1 do
|
||||
pos.x, pos.z = x, z
|
||||
if is_solid(lvm:get_node_at(pos)) then c = c + 1 end
|
||||
end
|
||||
end
|
||||
-- stop randomly depending on fill, to narrow down the foundation
|
||||
if pr:next(0,905) > c * 100 then return false end
|
||||
lvm:set_node_at(vector.new(xi, yi, zi),{name=platform_mat})
|
||||
return true -- modified
|
||||
end
|
||||
-------------------------------------------------------------------------------
|
||||
-- function clear space above baseplate
|
||||
-------------------------------------------------------------------------------
|
||||
function settlements.terraform(settlement_info, pr)
|
||||
function mcl_villages.terraform(settlement_info, pr)
|
||||
local fheight, fwidth, fdepth, schematic_data
|
||||
--local lvm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local lvm = VoxelManip()
|
||||
|
||||
for i, built_house in ipairs(settlement_info) do
|
||||
-- pick right schematic_info to current built_house
|
||||
for j, schem in ipairs(settlements.schematic_table) do
|
||||
for j, schem in ipairs(mcl_villages.schematic_table) do
|
||||
if settlement_info[i]["name"] == schem["name"] then
|
||||
schematic_data = schem
|
||||
break
|
||||
|
@ -50,41 +73,187 @@ function settlements.terraform(settlement_info, pr)
|
|||
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"]
|
||||
fwidth, fdepth = schematic_data["hwidth"], schematic_data["hdepth"]
|
||||
else
|
||||
fwidth = schematic_data["hdepth"]
|
||||
fdepth = schematic_data["hwidth"]
|
||||
fwidth, fdepth = schematic_data["hdepth"], schematic_data["hwidth"]
|
||||
end
|
||||
--fheight = schematic_data["hheight"] * 3 -- remove trees and leaves above
|
||||
fheight = schematic_data["hheight"] -- remove trees and leaves above
|
||||
|
||||
-- use biome-specific materials
|
||||
local surface_mat = settlement_info[i]["surface_mat"]
|
||||
mcl_log("Surface material: " .. tostring(surface_mat))
|
||||
local platform_mat = foundation_materials[surface_mat]
|
||||
mcl_log("Foundation material: " .. tostring(platform_mat))
|
||||
mcl_villages.debug("Surface material: " .. tostring(surface_mat))
|
||||
local platform_mat = foundation_materials[surface_mat] or "mcl_core:dirt"
|
||||
mcl_villages.debug("Foundation material: " .. tostring(platform_mat))
|
||||
|
||||
--
|
||||
-- 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 *3 do
|
||||
if yi == 0 then
|
||||
local p = {x=pos.x+xi, y=pos.y, z=pos.z+zi}
|
||||
-- Pass in biome info and make foundations of same material (seed: apple for desert)
|
||||
settlements.ground(p, pr, platform_mat)
|
||||
else
|
||||
-- write ground
|
||||
-- local p = {x=pos.x+xi, y=pos.y+yi, z=pos.z+zi}
|
||||
-- local node = mcl_vars.get_node(p)
|
||||
-- if node and node.name ~= "air" then
|
||||
-- minetest.swap_node(p,{name="air"})
|
||||
-- end
|
||||
minetest.swap_node({x=pos.x+xi, y=pos.y+yi, z=pos.z+zi},{name="air"})
|
||||
lvm:read_from_map(vector.new(pos.x-2, pos.y-20, pos.z-2), vector.new(pos.x+fwidth+2, pos.y+fheight+20, pos.z+fdepth+2))
|
||||
-- TODO: further optimize by using raw data arrays instead of set_node_at. But OK for a first draft.
|
||||
lvm:get_data()
|
||||
-- excavate the needed volume, some headroom, and add a baseplate
|
||||
local p2 = vector.new(pos)
|
||||
for xi = pos.x,pos.x+fwidth-1 do
|
||||
for zi = pos.z,pos.z+fdepth-1 do
|
||||
lvm:set_node_at(vector.new(xi, pos.y+1, zi),{name="air"})
|
||||
-- pos.y+2 to pos.y+5 are filled larger below!
|
||||
for yi = pos.y+6,pos.y+fheight do
|
||||
lvm:set_node_at(vector.new(xi, yi, zi),{name="air"})
|
||||
end
|
||||
local cp = vector.new(xi, pos.y, zi)
|
||||
local cur = lvm:get_node_at(cp)
|
||||
if not is_solid(cur) or cur.name == platform_mat then
|
||||
lvm:set_node_at(cp, {name=surface_mat})
|
||||
end
|
||||
local cp = vector.new(xi, pos.y - 1, zi)
|
||||
local cur = lvm:get_node_at(cp)
|
||||
if not is_solid(cur) then
|
||||
lvm:set_node_at(cp, {name=platform_mat})
|
||||
end
|
||||
end
|
||||
end
|
||||
-- slightly widen the cave, to make easier to enter for mobs
|
||||
for xi = pos.x-1,pos.x+fwidth do
|
||||
for zi = pos.z-1,pos.z+fdepth do
|
||||
for yi = pos.y+2,pos.y+5 do
|
||||
lvm:set_node_at(vector.new(xi, yi, zi),{name="air"})
|
||||
end
|
||||
end
|
||||
end
|
||||
-- some extra gaps
|
||||
for xi = pos.x-2,pos.x+fwidth+1 do
|
||||
for zi = pos.z-2,pos.z+fdepth+1 do
|
||||
if pr:next(1,4) == 1 then
|
||||
for yi = pos.y+3,pos.y+5 do
|
||||
lvm:set_node_at(vector.new(xi, yi, zi),{name="air"})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- slightly widen the baseplate, to make easier to enter for mobs
|
||||
for xi = pos.x,pos.x+fwidth-1 do
|
||||
local cp = vector.new(xi, pos.y-1, pos.z)
|
||||
local cur = lvm:get_node_at(cp)
|
||||
if not is_solid(cur) then
|
||||
lvm:set_node_at(cp, {name=platform_mat})
|
||||
end
|
||||
local cp = vector.new(xi, pos.y-1, pos.z-1)
|
||||
local cur = lvm:get_node_at(cp)
|
||||
if not is_solid(cur) or cur.name == platform_mat then
|
||||
lvm:set_node_at(cp, {name=surface_mat})
|
||||
end
|
||||
local cp = vector.new(xi, pos.y-1, pos.z+fdepth-1)
|
||||
local cur = lvm:get_node_at(cp)
|
||||
if not is_solid(cur) then
|
||||
lvm:set_node_at(cp, {name=platform_mat})
|
||||
end
|
||||
local cp = vector.new(xi, pos.y-1, pos.z+fdepth)
|
||||
local cur = lvm:get_node_at(cp)
|
||||
if not is_solid(cur) or cur.name == platform_mat then
|
||||
lvm:set_node_at(cp, {name=surface_mat})
|
||||
end
|
||||
end
|
||||
for zi = pos.z,pos.z+fdepth-1 do
|
||||
local cp = vector.new(pos.x, pos.y-1, zi)
|
||||
local cur = lvm:get_node_at(cp)
|
||||
if not is_solid(cur) then
|
||||
lvm:set_node_at(cp, {name=platform_mat})
|
||||
end
|
||||
local cp = vector.new(pos.x-1, pos.y-1, zi)
|
||||
local cur = lvm:get_node_at(cp)
|
||||
if not is_solid(cur) or cur.name == platform_mat then
|
||||
lvm:set_node_at(cp, {name=surface_mat})
|
||||
end
|
||||
local cp = vector.new(pos.x+fwidth-1, pos.y-1, zi)
|
||||
local cur = lvm:get_node_at(cp)
|
||||
if not is_solid(cur) then
|
||||
lvm:set_node_at(cp, {name=platform_mat})
|
||||
end
|
||||
local cp = vector.new(pos.x+fwidth, pos.y-1, zi)
|
||||
local cur = lvm:get_node_at(cp)
|
||||
if not is_solid(cur) or cur.name == platform_mat then
|
||||
lvm:set_node_at(cp, {name=surface_mat})
|
||||
end
|
||||
end
|
||||
-- make some additional steps, along both x sides
|
||||
for xi = pos.x,pos.x+fwidth-1 do
|
||||
local cp = vector.new(xi, pos.y-3, pos.z-1)
|
||||
if is_solid(lvm:get_node_at(cp)) then
|
||||
cp = vector.new(xi, pos.y-2, pos.z-1)
|
||||
local cur = lvm:get_node_at(cp)
|
||||
if not is_solid(cur) or cur.name == platform_mat then
|
||||
lvm:set_node_at(cp, {name=surface_mat})
|
||||
end
|
||||
cp.z = pos.z-2
|
||||
cur = lvm:get_node_at(cp)
|
||||
if not is_solid(cur) or cur.name == platform_mat then
|
||||
lvm:set_node_at(cp, {name=surface_mat})
|
||||
end
|
||||
end
|
||||
local cp = vector.new(xi, pos.y-3, pos.z+fdepth)
|
||||
if is_solid(lvm:get_node_at(cp)) then
|
||||
cp = vector.new(xi, pos.y-2, pos.z+fdepth)
|
||||
local cur = lvm:get_node_at(cp)
|
||||
if not is_solid(cur) or cur.name == platform_mat then
|
||||
lvm:set_node_at(cp, {name=surface_mat})
|
||||
end
|
||||
cp.z = pos.z + fdepth + 1
|
||||
cur = lvm:get_node_at(cp)
|
||||
if not is_solid(cur) or cur.name == platform_mat then
|
||||
lvm:set_node_at(cp, {name=surface_mat})
|
||||
end
|
||||
end
|
||||
end
|
||||
-- make some additional steps, along both z sides
|
||||
for zi = pos.z,pos.z+fdepth-1 do
|
||||
local cp = vector.new(pos.x-1, pos.y-3, zi)
|
||||
if is_solid(lvm:get_node_at(cp)) then
|
||||
cp = vector.new(pos.x-1, pos.y-2, zi)
|
||||
local cur = lvm:get_node_at(cp)
|
||||
if not is_solid(cur) or cur.name == platform_mat then
|
||||
lvm:set_node_at(cp, {name=surface_mat})
|
||||
end
|
||||
cp.x = pos.x-2
|
||||
cur = lvm:get_node_at(cp)
|
||||
if not is_solid(cur) or cur.name == platform_mat then
|
||||
lvm:set_node_at(cp, {name=surface_mat})
|
||||
end
|
||||
end
|
||||
local cp = vector.new(pos.x+fwidth, pos.y-3, zi)
|
||||
if is_solid(lvm:get_node_at(cp)) then
|
||||
cp = vector.new(pos.x+fwidth, pos.y-2, zi)
|
||||
local cur = lvm:get_node_at(cp)
|
||||
if not is_solid(cur) or cur.name == platform_mat then
|
||||
lvm:set_node_at(cp, {name=surface_mat})
|
||||
end
|
||||
cp.x = pos.x+fwidth+1
|
||||
cur = lvm:get_node_at(cp)
|
||||
if not is_solid(cur) or cur.name == platform_mat then
|
||||
lvm:set_node_at(cp, {name=surface_mat})
|
||||
end
|
||||
end
|
||||
end
|
||||
-- cave some additional area overhead, try to make it interesting though
|
||||
for yi = pos.y+3,pos.y+fheight*3 do
|
||||
local active = false
|
||||
for xi = pos.x-2,pos.x+fwidth+1 do
|
||||
for zi = pos.z-2,pos.z+fdepth+1 do
|
||||
if excavate(lvm,xi,yi,zi,pr) then
|
||||
active = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if not active and yi > pos.y+fheight+5 then break end
|
||||
end
|
||||
-- construct additional baseplate below, also try to make it interesting
|
||||
for yi = pos.y-2,pos.y-20,-1 do
|
||||
local active = false
|
||||
for xi = pos.x-1,pos.x+fwidth do
|
||||
for zi = pos.z-1,pos.z+fdepth do
|
||||
if grow_foundation(lvm,xi,yi,zi,pr,surface_mat,platform_mat) then
|
||||
active = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if not active and yi < pos.y-5 then break end
|
||||
end
|
||||
lvm:write_to_map(false)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
settlements = {}
|
||||
settlements.modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
mcl_villages = {}
|
||||
mcl_villages.modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
|
||||
dofile(settlements.modpath.."/const.lua")
|
||||
dofile(settlements.modpath.."/utils.lua")
|
||||
dofile(settlements.modpath.."/foundation.lua")
|
||||
dofile(settlements.modpath.."/buildings.lua")
|
||||
dofile(settlements.modpath.."/paths.lua")
|
||||
--dofile(settlements.modpath.."/convert_lua_mts.lua")
|
||||
--
|
||||
-- load settlements on server
|
||||
--
|
||||
settlements.grundstellungen()
|
||||
local village_chance = tonumber(minetest.settings:get("mcl_villages_village_chance")) or 5
|
||||
|
||||
dofile(mcl_villages.modpath.."/const.lua")
|
||||
dofile(mcl_villages.modpath.."/utils.lua")
|
||||
dofile(mcl_villages.modpath.."/foundation.lua")
|
||||
dofile(mcl_villages.modpath.."/buildings.lua")
|
||||
dofile(mcl_villages.modpath.."/paths.lua")
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
|
||||
local villagegen={}
|
||||
--
|
||||
-- register block for npc spawn
|
||||
--
|
||||
|
@ -32,42 +28,20 @@ minetest.register_node("mcl_villages:stonebrickcarved", {
|
|||
|
||||
minetest.register_node("mcl_villages:structblock", {drawtype="airlike",groups = {not_in_creative_inventory=1},})
|
||||
|
||||
|
||||
|
||||
--[[ Enable for testing, but use MineClone2's own spawn code if/when merging.
|
||||
--
|
||||
-- register inhabitants
|
||||
--
|
||||
if minetest.get_modpath("mobs_mc") then
|
||||
mcl_mobs:register_spawn("mobs_mc:villager", --name
|
||||
{"mcl_core:stonebrickcarved"}, --nodes
|
||||
15, --max_light
|
||||
0, --min_light
|
||||
20, --chance
|
||||
7, --active_object_count
|
||||
31000, --max_height
|
||||
nil) --day_toggle
|
||||
end
|
||||
--]]
|
||||
|
||||
--
|
||||
-- on map generation, try to build a settlement
|
||||
--
|
||||
local function build_a_settlement(minp, maxp, blockseed)
|
||||
local pr = PseudoRandom(blockseed)
|
||||
if mcl_villages.village_exists(blockseed) then return end
|
||||
|
||||
-- fill settlement_info with buildings and their data
|
||||
local settlement_info = settlements.create_site_plan(maxp, minp, pr)
|
||||
local pr = PseudoRandom(blockseed)
|
||||
local settlement_info = mcl_villages.create_site_plan(minp, maxp, pr)
|
||||
if not settlement_info then return end
|
||||
|
||||
-- evaluate settlement_info and prepair terrain
|
||||
settlements.terraform(settlement_info, pr)
|
||||
|
||||
-- evaluate settlement_info and build paths between buildings
|
||||
settlements.paths(settlement_info)
|
||||
|
||||
-- evaluate settlement_info and place schematics
|
||||
settlements.place_schematics(settlement_info, pr)
|
||||
mcl_villages.terraform(settlement_info, pr)
|
||||
mcl_villages.place_schematics(settlement_info, pr)
|
||||
mcl_villages.paths(settlement_info)
|
||||
mcl_villages.add_village(blockseed, settlement_info)
|
||||
end
|
||||
|
||||
local function ecb_village(blockpos, action, calls_remaining, param)
|
||||
|
@ -76,33 +50,24 @@ local function ecb_village(blockpos, action, calls_remaining, param)
|
|||
build_a_settlement(minp, maxp, blockseed)
|
||||
end
|
||||
|
||||
local villagegen={}
|
||||
-- Disable natural generation in singlenode.
|
||||
local mg_name = minetest.get_mapgen_setting("mg_name")
|
||||
if mg_name ~= "singlenode" then
|
||||
mcl_mapgen_core.register_generator("villages", nil, function(minp, maxp, blockseed)
|
||||
if maxp.y < 0 then return end
|
||||
|
||||
-- randomly try to build settlements
|
||||
if blockseed % 77 ~= 17 then return end
|
||||
--minetest.log("Rng good. Generate attempt")
|
||||
|
||||
-- needed for manual and automated settlement building
|
||||
-- don't build settlements on (too) uneven terrain
|
||||
if maxp.y < 0 or village_chance == 0 then return end
|
||||
local pr = PseudoRandom(blockseed)
|
||||
if pr:next(0, 100) > village_chance then return end
|
||||
local n=minetest.get_node_or_nil(minp)
|
||||
if n and n.name == "mcl_villages:structblock" then return end
|
||||
--minetest.log("No existing village attempt here")
|
||||
|
||||
if villagegen[minetest.pos_to_string(minp)] ~= nil then return end
|
||||
|
||||
--minetest.log("Not in village gen. Put down placeholder: " .. minetest.pos_to_string(minp) .. " || " .. minetest.pos_to_string(maxp))
|
||||
--if n and n.name == "mcl_villages:structblock" then return end
|
||||
if n and n.name ~= "air" then return end
|
||||
minetest.set_node(minp,{name="mcl_villages:structblock"})
|
||||
|
||||
local height_difference = settlements.evaluate_heightmap()
|
||||
if not height_difference or height_difference > max_height_difference then
|
||||
minetest.log("action", "Do not spawn village here as heightmap not good")
|
||||
return
|
||||
end
|
||||
--minetest.log("Build me a village: " .. minetest.pos_to_string(minp) .. " || " .. minetest.pos_to_string(maxp))
|
||||
--[[minetest.emerge_area(
|
||||
minp, maxp, --vector.offset(minp, -16, -16, -16), vector.offset(maxp, 16, 16, 16),
|
||||
ecb_village,
|
||||
{ minp = vector.copy(minp), maxp = vector.copy(maxp), blockseed = blockseed }
|
||||
)]]--
|
||||
villagegen[minetest.pos_to_string(minp)]={minp=vector.new(minp), maxp=vector.new(maxp), blockseed=blockseed}
|
||||
end)
|
||||
end
|
||||
|
@ -125,15 +90,15 @@ if minetest.is_creative_enabled("") then
|
|||
minetest.register_craftitem("mcl_villages:tool", {
|
||||
description = S("mcl_villages build tool"),
|
||||
inventory_image = "default_tool_woodshovel.png",
|
||||
-- build ssettlement
|
||||
-- build settlement
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
if not pointed_thing.under then return end
|
||||
if not minetest.check_player_privs(placer, "server") then
|
||||
minetest.chat_send_player(placer:get_player_name(), S("Placement denied. You need the “server” privilege to place villages."))
|
||||
return
|
||||
end
|
||||
local minp = vector.subtract( pointed_thing.under, half_map_chunk_size)
|
||||
local maxp = vector.add( pointed_thing.under, half_map_chunk_size)
|
||||
local minp = vector.subtract(pointed_thing.under, half_map_chunk_size)
|
||||
local maxp = vector.add(pointed_thing.under, half_map_chunk_size)
|
||||
build_a_settlement(minp, maxp, math.random(0,32767))
|
||||
end
|
||||
})
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name = mcl_villages
|
||||
author = Rochambeau
|
||||
description = This mod adds settlements on world generation.
|
||||
depends = mcl_util, mcl_mapgen_core, mcl_structures, mcl_core, mcl_loot
|
||||
optional_depends = mcl_farming, mobs_mc
|
||||
depends = mcl_util, mcl_mapgen_core, mcl_structures, mcl_core, mcl_loot, mobs_mc
|
||||
optional_depends = mcl_farming
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
-------------------------------------------------------------------------------
|
||||
-- generate paths between buildings
|
||||
-------------------------------------------------------------------------------
|
||||
function settlements.paths(settlement_info)
|
||||
function mcl_villages.paths(settlement_info)
|
||||
local starting_point
|
||||
local end_point
|
||||
local distance
|
||||
|
@ -67,7 +67,7 @@ function settlements.paths(settlement_info)
|
|||
distance = dist_east_p_to_end
|
||||
end
|
||||
-- find surface of new starting point
|
||||
local surface_point, surface_mat = settlements.find_surface(starting_point)
|
||||
local surface_point, surface_mat = mcl_villages.find_surface(starting_point)
|
||||
-- replace surface node with mcl_core:grass_path
|
||||
if surface_point
|
||||
then
|
||||
|
|
|
@ -1,106 +1,105 @@
|
|||
local get_node = mcl_vars.get_node
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- function to copy tables
|
||||
-------------------------------------------------------------------------------
|
||||
function settlements.shallowCopy(original)
|
||||
function mcl_villages.shallowCopy(original)
|
||||
local copy = {}
|
||||
for key, value in pairs(original) do
|
||||
copy[key] = value
|
||||
end
|
||||
return copy
|
||||
end
|
||||
--
|
||||
--
|
||||
--
|
||||
function settlements.round(num, numDecimalPlaces)
|
||||
local mult = 10^(numDecimalPlaces or 0)
|
||||
return math.floor(num * mult + 0.5) / mult
|
||||
end
|
||||
|
||||
local function is_above_surface(name)
|
||||
return name == "air" or
|
||||
string.find(name,"grass") or
|
||||
string.find(name,"tree") or
|
||||
string.find(name,"leaves") or
|
||||
string.find(name,"snow") or
|
||||
string.find(name,"fern") or
|
||||
string.find(name,"flower") or
|
||||
string.find(name,"bush")
|
||||
end
|
||||
local get_node = mcl_vars.get_node
|
||||
function mcl_villages.find_surface_down(pos, surface_node)
|
||||
local p6 = vector.new(pos)
|
||||
surface_node = surface_node or get_node(p6) --, true, 1000000)
|
||||
if not surface_node then return end
|
||||
for y = p6.y - 1, math.max(0,p6.y - 120), -1 do
|
||||
p6.y = y
|
||||
local top_node = surface_node
|
||||
surface_node = get_node(p6)
|
||||
if not surface_node then return nil end
|
||||
if is_above_surface(top_node.name) then
|
||||
if mcl_villages.surface_mat[surface_node.name] then
|
||||
-- minetest.log("verbose", "Found "..surface_node.name.." below "..top_node.name)
|
||||
return p6, surface_node.name
|
||||
end
|
||||
else
|
||||
local ndef = minetest.registered_nodes[surface_node.name]
|
||||
if ndef and ndef.walkable then
|
||||
return nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function mcl_villages.find_surface_up(pos, surface_node)
|
||||
local p6 = vector.new(pos)
|
||||
surface_node = surface_node or get_node(p6) --, true, 1000000)
|
||||
if not surface_node then return end
|
||||
for y = p6.y + 1, p6.y + 50 do
|
||||
p6.y = y
|
||||
local top_node = get_node(p6)
|
||||
if not top_node then return nil end
|
||||
if is_above_surface(top_node.name) then
|
||||
if mcl_villages.surface_mat[surface_node.name] then
|
||||
-- minetest.log("verbose","Found "..surface_node.name.." below "..top_node.name)
|
||||
p6.y = p6.y - 1
|
||||
return p6, surface_node.name
|
||||
end
|
||||
else
|
||||
local ndef = minetest.registered_nodes[surface_node.name]
|
||||
if ndef and ndef.walkable then
|
||||
return nil
|
||||
end
|
||||
end
|
||||
surface_node = top_node
|
||||
end
|
||||
end
|
||||
-------------------------------------------------------------------------------
|
||||
-- function to find surface block y coordinate
|
||||
-- returns surface postion
|
||||
-------------------------------------------------------------------------------
|
||||
function settlements.find_surface(pos, wait)
|
||||
function mcl_villages.find_surface(pos, wait)
|
||||
local p6 = vector.new(pos)
|
||||
local cnt = 0
|
||||
local itter = 1 -- count up or down
|
||||
local cnt_max = 200
|
||||
-- check, in which direction to look for surface
|
||||
if p6.y < 0 then p6.y = 0 end -- start at water level
|
||||
local surface_node
|
||||
if wait then
|
||||
surface_node = get_node(p6, true, 10000000)
|
||||
else
|
||||
surface_node = get_node(p6)
|
||||
end
|
||||
if surface_node.name=="air" or surface_node.name=="ignore" then
|
||||
itter = -1
|
||||
-- downward, if starting position is empty
|
||||
if is_above_surface(surface_node.name) then
|
||||
return mcl_villages.find_surface_down(p6, surface_node)
|
||||
else
|
||||
return mcl_villages.find_surface_up(p6, surface_node)
|
||||
end
|
||||
-- go through nodes an find surface
|
||||
while cnt < cnt_max do
|
||||
-- Check Surface_node and Node above
|
||||
if surface_node and settlements.surface_mat[surface_node.name] then
|
||||
local surface_node_plus_1 = get_node({ x=p6.x, y=p6.y+1, z=p6.z})
|
||||
|
||||
if surface_node_plus_1 then
|
||||
|
||||
local surface_node_minus_1 = get_node({ x=p6.x, y=p6.y-1, z=p6.z})
|
||||
local is_leaf_below = minetest.get_item_group(surface_node_minus_1, "leaves") ~= 0 or
|
||||
string.find(surface_node_minus_1.name,"leaves")
|
||||
|
||||
if not is_leaf_below and ((string.find(surface_node_plus_1.name,"air") or
|
||||
string.find(surface_node_plus_1.name,"fern") or
|
||||
string.find(surface_node_plus_1.name,"flower") or
|
||||
string.find(surface_node_plus_1.name,"bush") or
|
||||
string.find(surface_node_plus_1.name,"tree") or
|
||||
string.find(surface_node_plus_1.name,"grass")) or
|
||||
string.find(surface_node_plus_1.name,"snow"))
|
||||
then
|
||||
settlements.debug("find_surface success: " ..surface_node.name.. " " .. surface_node_plus_1.name)
|
||||
settlements.debug("node below: " .. tostring(surface_node_minus_1.name))
|
||||
settlements.debug("node below leaves group: " .. tostring(minetest.get_item_group(surface_node_minus_1, "leaves")))
|
||||
return p6, surface_node.name
|
||||
else
|
||||
settlements.debug("find_surface2: wrong surface+1")
|
||||
end
|
||||
else
|
||||
settlements.debug("find_surface8: missing node or plus_1")
|
||||
end
|
||||
else
|
||||
settlements.debug("find_surface3: wrong surface "..surface_node.name.." at pos "..minetest.pos_to_string(p6))
|
||||
end
|
||||
|
||||
p6.y = p6.y + itter
|
||||
if p6.y < 0 then
|
||||
settlements.debug("find_surface4: y<0")
|
||||
return nil
|
||||
end
|
||||
cnt = cnt+1
|
||||
surface_node = get_node(p6)
|
||||
end
|
||||
settlements.debug("find_surface5: cnt_max overflow")
|
||||
return nil
|
||||
end
|
||||
-------------------------------------------------------------------------------
|
||||
-- check distance for new building
|
||||
-------------------------------------------------------------------------------
|
||||
function settlements.check_distance(settlement_info, building_pos, building_size)
|
||||
local distance
|
||||
function mcl_villages.check_distance(settlement_info, building_pos, building_size)
|
||||
for i, built_house in ipairs(settlement_info) do
|
||||
distance = math.sqrt(
|
||||
((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)))
|
||||
if distance < building_size or distance < built_house["hsize"] then
|
||||
return false
|
||||
end
|
||||
local dx, dz = building_pos.x - built_house["pos"].x, building_pos.z - built_house["pos"].z
|
||||
local dsq = dx*dx+dz*dz
|
||||
if dsq < building_size^2 or dsq < built_house["hsize"]^2 then return false end
|
||||
end
|
||||
return true
|
||||
end
|
||||
-------------------------------------------------------------------------------
|
||||
-- fill chests
|
||||
-------------------------------------------------------------------------------
|
||||
function settlements.fill_chest(pos, pr)
|
||||
function mcl_villages.fill_chest(pos, pr)
|
||||
-- initialize chest (mts chests don't have meta)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if meta:get_string("infotext") ~= "Chest" then
|
||||
|
@ -148,123 +147,93 @@ end
|
|||
-------------------------------------------------------------------------------
|
||||
-- initialize furnace
|
||||
-------------------------------------------------------------------------------
|
||||
function settlements.initialize_furnace(pos)
|
||||
-- find chests within radius
|
||||
local furnacepos = minetest.find_node_near(pos,
|
||||
7, --radius
|
||||
{"mcl_furnaces:furnace"})
|
||||
-- initialize furnacepos (mts furnacepos don't have meta)
|
||||
if furnacepos
|
||||
then
|
||||
local meta = minetest.get_meta(furnacepos)
|
||||
if meta:get_string("infotext") ~= "furnace"
|
||||
then
|
||||
minetest.registered_nodes["mcl_furnaces:furnace"].on_construct(furnacepos)
|
||||
end
|
||||
end
|
||||
function mcl_villages.initialize_furnace(pos)
|
||||
-- find chests within radius
|
||||
local furnacepos = minetest.find_node_near(pos,
|
||||
7, --radius
|
||||
{"mcl_furnaces:furnace"})
|
||||
-- initialize furnacepos (mts furnacepos don't have meta)
|
||||
if furnacepos then
|
||||
local meta = minetest.get_meta(furnacepos)
|
||||
if meta:get_string("infotext") ~= "furnace" then
|
||||
minetest.registered_nodes["mcl_furnaces:furnace"].on_construct(furnacepos)
|
||||
end
|
||||
end
|
||||
end
|
||||
-------------------------------------------------------------------------------
|
||||
-- initialize anvil
|
||||
-------------------------------------------------------------------------------
|
||||
function settlements.initialize_anvil(pos)
|
||||
-- find chests within radius
|
||||
local anvilpos = minetest.find_node_near(pos,
|
||||
7, --radius
|
||||
{"mcl_anvils:anvil"})
|
||||
-- initialize anvilpos (mts anvilpos don't have meta)
|
||||
if anvilpos
|
||||
then
|
||||
local meta = minetest.get_meta(anvilpos)
|
||||
if meta:get_string("infotext") ~= "anvil"
|
||||
then
|
||||
minetest.registered_nodes["mcl_anvils:anvil"].on_construct(anvilpos)
|
||||
end
|
||||
end
|
||||
function mcl_villages.initialize_anvil(pos)
|
||||
-- find chests within radius
|
||||
local anvilpos = minetest.find_node_near(pos,
|
||||
7, --radius
|
||||
{"mcl_anvils:anvil"})
|
||||
-- initialize anvilpos (mts anvilpos don't have meta)
|
||||
if anvilpos then
|
||||
local meta = minetest.get_meta(anvilpos)
|
||||
if meta:get_string("infotext") ~= "anvil" then
|
||||
minetest.registered_nodes["mcl_anvils:anvil"].on_construct(anvilpos)
|
||||
end
|
||||
end
|
||||
end
|
||||
-------------------------------------------------------------------------------
|
||||
-- randomize table
|
||||
-------------------------------------------------------------------------------
|
||||
function shuffle(tbl, pr)
|
||||
local table = settlements.shallowCopy(tbl)
|
||||
local size = #table
|
||||
for i = size, 1, -1 do
|
||||
local rand = pr:next(1, size)
|
||||
table[i], table[rand] = table[rand], table[i]
|
||||
function mcl_villages.shuffle(tbl, pr)
|
||||
local copy = {}
|
||||
for key, value in ipairs(tbl) do
|
||||
table.insert(copy, pr:next(1, #copy + 1), value)
|
||||
end
|
||||
return table
|
||||
return copy
|
||||
end
|
||||
-------------------------------------------------------------------------------
|
||||
-- evaluate heightmap
|
||||
-------------------------------------------------------------------------------
|
||||
function settlements.evaluate_heightmap()
|
||||
local heightmap = minetest.get_mapgen_object("heightmap")
|
||||
|
||||
if not heightmap then
|
||||
minetest.log("action", "No heightmap. That should not happen")
|
||||
return max_height_difference + 1
|
||||
end
|
||||
-- Load a schema and replace nodes in it based on biome
|
||||
function mcl_villages.substitute_materials(pos, schem_lua, pr)
|
||||
local modified_schem_lua = schem_lua
|
||||
local biome_data = minetest.get_biome_data(pos)
|
||||
local biome_name = minetest.get_biome_name(biome_data.biome)
|
||||
|
||||
--minetest.log("action", "heightmap size: " .. tostring(#heightmap))
|
||||
|
||||
-- max height and min height, initialize with impossible values for easier first time setting
|
||||
local max_y = -50000
|
||||
local min_y = 50000
|
||||
-- only evaluate the center square of heightmap 40 x 40
|
||||
local square_start = 1621
|
||||
local square_end = 1661
|
||||
for j = 1 , 40, 1 do
|
||||
if square_start >= #heightmap then
|
||||
--minetest.log("action", "Heightmap size reached. Go no further outside")
|
||||
break
|
||||
if mcl_villages.biome_map[biome_name] and mcl_villages.material_substitions[mcl_villages.biome_map[biome_name]] then
|
||||
for _, sub in pairs(mcl_villages.material_substitions[mcl_villages.biome_map[biome_name]]) do
|
||||
modified_schem_lua = modified_schem_lua:gsub(sub[1], sub[2])
|
||||
end
|
||||
for i = square_start, square_end, 1 do
|
||||
--minetest.log("action", "current hm index: " .. tostring(i) .. "current hm entry: " .. tostring(heightmap[i]))
|
||||
end
|
||||
|
||||
if i >= #heightmap then
|
||||
--minetest.log("action", "Heightmap size reached. Go no further")
|
||||
break
|
||||
end
|
||||
local current_hm_entry = heightmap[i]
|
||||
if current_hm_entry then
|
||||
-- skip buggy heightmaps, return high value. Converted mcl5 maps can be -31007
|
||||
if current_hm_entry == -31000 or heightmap[i] == 31000 then
|
||||
--minetest.log("action", "incorrect heighmap values. abandon")
|
||||
return max_height_difference + 1
|
||||
end
|
||||
if current_hm_entry < min_y then
|
||||
min_y = current_hm_entry
|
||||
end
|
||||
if current_hm_entry > max_y then
|
||||
max_y = current_hm_entry
|
||||
end
|
||||
else
|
||||
--minetest.log("action", "Failed to get hm index: " .. tostring(i) .. "and ... " .. tostring(#heightmap))
|
||||
end
|
||||
return modified_schem_lua
|
||||
end
|
||||
|
||||
local villages = {}
|
||||
local mod_storage = minetest.get_mod_storage()
|
||||
|
||||
local function lazy_load_village(name)
|
||||
if not villages[name] then
|
||||
local data = mod_storage:get("mcl_villages." .. name)
|
||||
if data then
|
||||
villages[name] = minetest.deserialize(data)
|
||||
end
|
||||
-- set next line
|
||||
square_start = square_start + 80
|
||||
square_end = square_end + 80
|
||||
end
|
||||
-- return the difference between highest and lowest pos in chunk
|
||||
local height_diff = max_y - min_y
|
||||
end
|
||||
|
||||
--minetest.log("action", "height_diff = " .. tostring(height_diff))
|
||||
|
||||
-- filter buggy heightmaps
|
||||
if height_diff <= 1 then
|
||||
return max_height_difference + 1
|
||||
function mcl_villages.get_village(name)
|
||||
lazy_load_village(name)
|
||||
if villages[name] then
|
||||
return table.copy(villages[name])
|
||||
end
|
||||
--minetest.log("action", "return heigh diff = " .. tostring(height_diff))
|
||||
-- debug info
|
||||
settlements.debug("heightdiff ".. height_diff)
|
||||
return height_diff
|
||||
end
|
||||
-------------------------------------------------------------------------------
|
||||
-- Set array to list
|
||||
-- https://stackoverflow.com/questions/656199/search-for-an-item-in-a-lua-list
|
||||
-------------------------------------------------------------------------------
|
||||
function settlements.Set (list)
|
||||
local set = {}
|
||||
for _, l in ipairs(list) do set[l] = true end
|
||||
return set
|
||||
|
||||
function mcl_villages.village_exists(name)
|
||||
lazy_load_village(name)
|
||||
return villages[name] ~= nil
|
||||
end
|
||||
|
||||
function mcl_villages.add_village(name, data)
|
||||
lazy_load_village(name)
|
||||
if villages[name] then
|
||||
minetest.log("info","Village already exists: " .. name )
|
||||
return false
|
||||
end
|
||||
|
||||
local new_village = {name = name, data = data}
|
||||
mod_storage:set_string("mcl_villages." .. name, minetest.serialize(new_village))
|
||||
return true
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue