added simple ground raising for villages to prevent floating villages near cliffs
This commit is contained in:
parent
048616b0b3
commit
5e4f7fa639
@ -74,13 +74,15 @@ if minetest.setting_getbool("fixlight_command_enable") then
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
function util.nodefunc(pos1, pos2, name, func)
|
function util.nodefunc(pos1, pos2, name, func, nomanip)
|
||||||
-- function based off fixlight
|
-- function based off fixlight
|
||||||
-- call a function for every node of a single type
|
-- call a function for every node of a single type
|
||||||
local pos1, pos2 = util.sort_pos(pos1, pos2)
|
local pos1, pos2 = util.sort_pos(pos1, pos2)
|
||||||
|
|
||||||
local manip = minetest.get_voxel_manip()
|
if not nomanip then
|
||||||
manip:read_from_map(pos1, pos2)
|
local manip = minetest.get_voxel_manip()
|
||||||
|
manip:read_from_map(pos1, pos2)
|
||||||
|
end
|
||||||
|
|
||||||
local nodes = minetest.find_nodes_in_area(pos1, pos2, name)
|
local nodes = minetest.find_nodes_in_area(pos1, pos2, name)
|
||||||
for _, pos in ipairs(nodes) do
|
for _, pos in ipairs(nodes) do
|
||||||
@ -99,13 +101,15 @@ function util.getvoxelmanip(pos1, pos2)
|
|||||||
return manip
|
return manip
|
||||||
end
|
end
|
||||||
|
|
||||||
function util.remove_area(pos1, pos2)
|
function util.remove_area(pos1, pos2, nomanip)
|
||||||
-- function based off fixlight
|
-- function based off fixlight
|
||||||
-- call a function for every node of a single type
|
-- call a function for every node of a single type
|
||||||
local pos1, pos2 = util.sort_pos(pos1, pos2)
|
local pos1, pos2 = util.sort_pos(pos1, pos2)
|
||||||
|
|
||||||
local manip = minetest.get_voxel_manip()
|
if not nomanip then
|
||||||
manip:read_from_map(pos1, pos2)
|
local manip = minetest.get_voxel_manip()
|
||||||
|
manip:read_from_map(pos1, pos2)
|
||||||
|
end
|
||||||
|
|
||||||
for i = pos1.x, pos2.x-1 do
|
for i = pos1.x, pos2.x-1 do
|
||||||
for j = pos1.y, pos2.y-1 do
|
for j = pos1.y, pos2.y-1 do
|
||||||
@ -118,13 +122,15 @@ function util.remove_area(pos1, pos2)
|
|||||||
manip:write_to_map()
|
manip:write_to_map()
|
||||||
end
|
end
|
||||||
|
|
||||||
function util.areafunc(pos1, pos2, func)
|
function util.areafunc(pos1, pos2, func, nomanip)
|
||||||
-- function based off fixlight
|
-- function based off fixlight
|
||||||
-- call a function for every node of a single type
|
-- call a function for every node of a single type
|
||||||
local pos1, pos2 = util.sort_pos(pos1, pos2)
|
local pos1, pos2 = util.sort_pos(pos1, pos2)
|
||||||
|
|
||||||
local manip = minetest.get_voxel_manip()
|
if not nomanip then
|
||||||
manip:read_from_map(pos1, pos2)
|
local manip = minetest.get_voxel_manip()
|
||||||
|
manip:read_from_map(pos1, pos2)
|
||||||
|
end
|
||||||
|
|
||||||
for i = pos1.x, pos2.x-1 do
|
for i = pos1.x, pos2.x-1 do
|
||||||
for j = pos1.y, pos2.y-1 do
|
for j = pos1.y, pos2.y-1 do
|
||||||
@ -135,13 +141,15 @@ function util.areafunc(pos1, pos2, func)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function util.reconstruct(pos1, pos2)
|
function util.reconstruct(pos1, pos2, nomanip)
|
||||||
-- function based off fixlight
|
-- function based off fixlight
|
||||||
-- force a re-construction of the nodes in an area, for fixing missing metadata in schematics
|
-- force a re-construction of the nodes in an area, for fixing missing metadata in schematics
|
||||||
local pos1, pos2 = util.sort_pos(pos1, pos2)
|
local pos1, pos2 = util.sort_pos(pos1, pos2)
|
||||||
|
|
||||||
local manip = minetest.get_voxel_manip()
|
if not nomanip then
|
||||||
manip:read_from_map(pos1, pos2)
|
local manip = minetest.get_voxel_manip()
|
||||||
|
manip:read_from_map(pos1, pos2)
|
||||||
|
end
|
||||||
|
|
||||||
-- fix chests
|
-- fix chests
|
||||||
local nodes = minetest.find_nodes_in_area(pos1, pos2, "default:chest")
|
local nodes = minetest.find_nodes_in_area(pos1, pos2, "default:chest")
|
||||||
|
@ -142,39 +142,90 @@ village.chunktypes = {
|
|||||||
"orchard",
|
"orchard",
|
||||||
}
|
}
|
||||||
|
|
||||||
function village.get_area_height(minp, maxp)
|
function village.lift_ground(pos, scanheight)
|
||||||
local minp, maxp = util.sort_pos(minp, maxp)
|
-- assume ground is lower than pos.y
|
||||||
|
|
||||||
local avg = 0
|
local topnode = nil
|
||||||
local amt = 0
|
local topdepth = 0
|
||||||
|
|
||||||
for y = minp.y, maxp.y-1 do
|
local fillernode = nil
|
||||||
for x = minp.x, maxp.x-1 do
|
local fillerdepth = 0
|
||||||
for z = minp.z, maxp.z-1 do
|
|
||||||
if minetest.get_node({x = x, y = y, z = z}).name == "air" or minetest.get_node({x = x, y = y, z = z}).name == "ignore" then
|
local stonenode = nil
|
||||||
avg = avg + y
|
|
||||||
amt = amt + 1
|
for y = pos.y, pos.y - scanheight, -1 do
|
||||||
|
local p = {x = pos.x, y = y, z = pos.z}
|
||||||
|
|
||||||
|
local nn = minetest.get_node(p).name
|
||||||
|
local an = minetest.get_node({x = p.x, y = p.y + 1, z = p.z}).name
|
||||||
|
|
||||||
|
if nn ~= "air" then
|
||||||
|
local nd = minetest.registered_nodes[nn]
|
||||||
|
if not nd.buildable_to then -- avoid grass, fluids, etc.
|
||||||
|
if topnode == nil and nn ~= an then
|
||||||
|
topnode = nn
|
||||||
|
elseif fillernode == nil and nn ~= an then
|
||||||
|
fillernode = nn
|
||||||
|
else
|
||||||
|
stonenode = nn
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if fillernode and not stonenode then
|
||||||
|
fillerdepth = fillerdepth + 1
|
||||||
|
elseif topnode and not fillernode then
|
||||||
|
topdepth = topdepth + 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
avg = avg / amt
|
if topnode == nil then
|
||||||
|
topnode = "default:dirt_with_grass"
|
||||||
|
topdepth = 1
|
||||||
|
end
|
||||||
|
if fillernode == nil then
|
||||||
|
fillernode = "default:dirt"
|
||||||
|
fillerdepth = 3
|
||||||
|
end
|
||||||
|
if stonenode == nil then
|
||||||
|
stonenode = fillernode
|
||||||
|
end
|
||||||
|
|
||||||
return avg
|
for y = pos.y - scanheight, pos.y do
|
||||||
|
local p = {x = pos.x, y = y, z = pos.z}
|
||||||
|
|
||||||
|
local th = pos.y - y
|
||||||
|
|
||||||
|
if th <= fillerdepth - topdepth then
|
||||||
|
minetest.set_node(p, {name = fillernode})
|
||||||
|
elseif th <= topdepth then
|
||||||
|
minetest.set_node(p, {name = topnode})
|
||||||
|
else
|
||||||
|
minetest.set_node(p, {name = stonenode})
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function village.spawn_chunk(pos, orient, replace, pr, chunktype, nofill)
|
function village.spawn_chunk(pos, orient, replace, pr, chunktype, nofill)
|
||||||
util.getvoxelmanip(pos, {x = pos.x+12, y = pos.y+16, z = pos.z+12})
|
util.getvoxelmanip(pos, {x = pos.x+12, y = pos.y+12, z = pos.z+12})
|
||||||
|
|
||||||
if nofill ~= true then
|
if nofill ~= true then
|
||||||
|
util.nodefunc(
|
||||||
|
{x = pos.x-6, y = pos.y-7, z = pos.z-6},
|
||||||
|
{x = pos.x+17, y = pos.y-6, z = pos.z+17},
|
||||||
|
"air",
|
||||||
|
function(pos)
|
||||||
|
village.lift_ground(pos, 15) -- distance to lift ground; larger numbers will be slower
|
||||||
|
end, true)
|
||||||
|
|
||||||
minetest.place_schematic(
|
minetest.place_schematic(
|
||||||
{x = pos.x, y = pos.y, z = pos.z},
|
pos,
|
||||||
mp.."/schematics/village_empty.mts",
|
mp.."/schematics/village_empty.mts",
|
||||||
"0",
|
"0",
|
||||||
{},
|
{},
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
|
||||||
minetest.place_schematic(
|
minetest.place_schematic(
|
||||||
{x = pos.x-6, y = pos.y-5, z = pos.z-6},
|
{x = pos.x-6, y = pos.y-5, z = pos.z-6},
|
||||||
mp.."/schematics/village_filler.mts",
|
mp.."/schematics/village_filler.mts",
|
||||||
@ -192,24 +243,24 @@ function village.spawn_chunk(pos, orient, replace, pr, chunktype, nofill)
|
|||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
|
||||||
util.reconstruct(pos, {x = pos.x+12, y = pos.y+16, z = pos.z+12})
|
util.reconstruct(pos, {x = pos.x+12, y = pos.y+12, z = pos.z+12})
|
||||||
util.fixlight(pos, {x = pos.x+12, y = pos.y+16, z = pos.z+12})
|
util.fixlight(pos, {x = pos.x+12, y = pos.y+12, z = pos.z+12})
|
||||||
util.nodefunc(
|
util.nodefunc(
|
||||||
pos,
|
pos,
|
||||||
{x = pos.x+12, y = pos.y+16, z = pos.z+12},
|
{x = pos.x+12, y = pos.y+12, z = pos.z+12},
|
||||||
"default:chest",
|
"default:chest",
|
||||||
function(pos)
|
function(pos)
|
||||||
goodies.fill(pos, chunktype, pr, "main", 3)
|
goodies.fill(pos, chunktype, pr, "main", 3)
|
||||||
end)
|
end, true)
|
||||||
util.nodefunc(
|
util.nodefunc(
|
||||||
pos,
|
pos,
|
||||||
{x = pos.x+12, y = pos.y+16, z = pos.z+12},
|
{x = pos.x+12, y = pos.y+12, z = pos.z+12},
|
||||||
"music:player",
|
"music:player",
|
||||||
function(pos)
|
function(pos)
|
||||||
if pr:next(1, 2) > 1 then
|
if pr:next(1, 2) > 1 then
|
||||||
minetest.remove_node(pos)
|
minetest.remove_node(pos)
|
||||||
end
|
end
|
||||||
end)
|
end, true)
|
||||||
|
|
||||||
local chunkdef = village.chunkdefs[chunktype]
|
local chunkdef = village.chunkdefs[chunktype]
|
||||||
if chunkdef ~= nil then
|
if chunkdef ~= nil then
|
||||||
@ -217,7 +268,7 @@ function village.spawn_chunk(pos, orient, replace, pr, chunktype, nofill)
|
|||||||
if chunkdef.entity_chance ~= nil and pr:next(1, chunkdef.entity_chance) == 1 then
|
if chunkdef.entity_chance ~= nil and pr:next(1, chunkdef.entity_chance) == 1 then
|
||||||
util.nodefunc(
|
util.nodefunc(
|
||||||
pos,
|
pos,
|
||||||
{x = pos.x+12, y = pos.y+16, z = pos.z+12},
|
{x = pos.x+12, y = pos.y+12, z = pos.z+12},
|
||||||
"village:entity_spawner",
|
"village:entity_spawner",
|
||||||
function(pos)
|
function(pos)
|
||||||
minetest.remove_node(pos)
|
minetest.remove_node(pos)
|
||||||
@ -229,12 +280,12 @@ function village.spawn_chunk(pos, orient, replace, pr, chunktype, nofill)
|
|||||||
|
|
||||||
util.nodefunc(
|
util.nodefunc(
|
||||||
pos,
|
pos,
|
||||||
{x = pos.x+12, y = pos.y+16, z = pos.z+12},
|
{x = pos.x+12, y = pos.y+12, z = pos.z+12},
|
||||||
"village:entity_spawner",
|
"village:entity_spawner",
|
||||||
function(pos)
|
function(pos)
|
||||||
table.insert(ent_spawns, pos)
|
table.insert(ent_spawns, pos)
|
||||||
minetest.remove_node(pos)
|
minetest.remove_node(pos)
|
||||||
end)
|
end, true)
|
||||||
|
|
||||||
if #ent_spawns > 0 then
|
if #ent_spawns > 0 then
|
||||||
for ent, amt in pairs(chunkdef.entities) do
|
for ent, amt in pairs(chunkdef.entities) do
|
||||||
@ -253,13 +304,13 @@ function village.spawn_chunk(pos, orient, replace, pr, chunktype, nofill)
|
|||||||
if chunktype == "forge" then
|
if chunktype == "forge" then
|
||||||
util.nodefunc(
|
util.nodefunc(
|
||||||
pos,
|
pos,
|
||||||
{x = pos.x+12, y = pos.y+16, z = pos.z+12},
|
{x = pos.x+12, y = pos.y+12, z = pos.z+12},
|
||||||
"default:furnace",
|
"default:furnace",
|
||||||
function(pos)
|
function(pos)
|
||||||
goodies.fill(pos, "FURNACE_SRC", pr, "src", 1)
|
goodies.fill(pos, "FURNACE_SRC", pr, "src", 1)
|
||||||
goodies.fill(pos, "FURNACE_DST", pr, "dst", 1)
|
goodies.fill(pos, "FURNACE_DST", pr, "dst", 1)
|
||||||
goodies.fill(pos, "FURNACE_FUEL", pr, "fuel", 1)
|
goodies.fill(pos, "FURNACE_FUEL", pr, "fuel", 1)
|
||||||
end)
|
end, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -282,15 +333,17 @@ function village.spawn_road(pos, houses, built, roads, depth, pr)
|
|||||||
nextpos.x = nextpos.x + 12
|
nextpos.x = nextpos.x + 12
|
||||||
end
|
end
|
||||||
|
|
||||||
if built[minetest.hash_node_position(nextpos)] == nil then
|
local hnp = minetest.hash_node_position(nextpos)
|
||||||
built[minetest.hash_node_position(nextpos)] = true
|
|
||||||
|
if built[hnp] == nil then
|
||||||
|
built[hnp] = true
|
||||||
if depth <= 0 or pr:next(1, 8) < 6 then
|
if depth <= 0 or pr:next(1, 8) < 6 then
|
||||||
houses[minetest.hash_node_position(nextpos)] = {pos = nextpos, front = pos}
|
houses[hnp] = {pos = nextpos, front = pos}
|
||||||
|
|
||||||
local structure = util.choice_element(village.chunktypes, pr)
|
local structure = util.choice_element(village.chunktypes, pr)
|
||||||
village.spawn_chunk(nextpos, orient, {}, pr, structure)
|
village.spawn_chunk(nextpos, orient, {}, pr, structure)
|
||||||
else
|
else
|
||||||
roads[minetest.hash_node_position(nextpos)] = {pos = nextpos}
|
roads[hnp] = {pos = nextpos}
|
||||||
village.spawn_road(nextpos, houses, built, roads, depth - 1, pr)
|
village.spawn_road(nextpos, houses, built, roads, depth - 1, pr)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -314,23 +367,29 @@ function village.spawn_village(pos, pr)
|
|||||||
local built = {}
|
local built = {}
|
||||||
local roads = {}
|
local roads = {}
|
||||||
|
|
||||||
|
local spawnpos = pos
|
||||||
|
|
||||||
village.spawn_chunk(pos, "0", {}, pr, "well")
|
village.spawn_chunk(pos, "0", {}, pr, "well")
|
||||||
built[minetest.hash_node_position(pos)] = true
|
built[minetest.hash_node_position(pos)] = true
|
||||||
|
|
||||||
|
local t1 = os.clock()
|
||||||
village.spawn_road(pos, houses, built, roads, depth, pr)
|
village.spawn_road(pos, houses, built, roads, depth, pr)
|
||||||
|
print(string.format("Took %.2fms to spawn village", (os.clock() - t1) * 1000))
|
||||||
|
|
||||||
local function connects(pos, nextpos)
|
local function connects(pos, nextpos)
|
||||||
if houses[minetest.hash_node_position(nextpos)] ~= nil then
|
local hnp = minetest.hash_node_position(nextpos)
|
||||||
if vector.equals(houses[minetest.hash_node_position(nextpos)].front, pos) then
|
|
||||||
|
if houses[hnp] ~= nil then
|
||||||
|
if vector.equals(houses[hnp].front, pos) then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if roads[minetest.hash_node_position(nextpos)] ~= nil then
|
if roads[hnp] ~= nil then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
if vector.equals(pos, nextpos) then
|
if vector.equals(pos, nextpos) or vector.equals(nextpos, spawnpos) then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user