mirror of
https://github.com/ShadMOrdre/lib_materials.git
synced 2024-11-05 10:00:39 +01:00
49e350adb7
Modified ground cover ore defs. Fixed Dried Mud texture. Fixed lakes not clearing plants. Added settings for mapgen scaling and biome altitude range.
246 lines
8.4 KiB
Lua
246 lines
8.4 KiB
Lua
--[[
|
|
1. We choose a random position in the same way plants are placed. That's the root for our lake.
|
|
2. From there we go lx in the x direction and lz in the z direction. That gives us a rectangle.
|
|
3. We check the sides of the rectangle for air and itterate down until the rectangle is closed.
|
|
4. Now we repeat this itteration, but search for the opposite, not for solid nodes but for air.
|
|
5. As soon as we found the lower limit, we check if the bottom is sealed. Now we have some jar.
|
|
6. Now as we made sure no water can escape we can replace all air inside the volume with water.
|
|
--]]
|
|
|
|
--lib_lakes = {}
|
|
|
|
local c_air = minetest.get_content_id("air")
|
|
local c_ignore = minetest.get_content_id("ignore")
|
|
local c_lava = minetest.get_content_id("default:lava_source")
|
|
local c_water = minetest.get_content_id("lib_materials:fluid_water_source")
|
|
local c_ice = minetest.get_content_id("lib_materials:ice_default")
|
|
local c_murky = minetest.get_content_id("lib_materials:fluid_water_murky_source")
|
|
local c_dirty = minetest.get_content_id("lib_materials:fluid_water_dirty_source")
|
|
local c_muddy = minetest.get_content_id("lib_materials:fluid_water_river_muddy_source")
|
|
local c_quick_source = minetest.get_content_id("lib_materials:fluid_quicksand_source")
|
|
local c_quick = minetest.get_content_id("lib_materials:quicksand")
|
|
local c_mud_wet = minetest.get_content_id("lib_materials:mud_wet")
|
|
local c_mud_dried = minetest.get_content_id("lib_materials:dirt_mud_dried")
|
|
local c_fluid_id
|
|
|
|
--
|
|
-- Find position
|
|
--
|
|
|
|
minetest.register_on_generated(function(minp, maxp, seed)
|
|
if maxp.y <= 1024 and minp.y >= -32 then
|
|
local perlin1 = minetest.get_perlin(318, 3, 0.6, 100)
|
|
-- Lua Voxel Machine
|
|
local vm = minetest.get_voxel_manip()
|
|
local vm_minp, vm_maxp = vm:read_from_map({x=minp.x, y=minp.y, z=minp.z-16}, {x=maxp.x+16, y=maxp.y+16, z=maxp.z+16})
|
|
local a = VoxelArea:new{MinEdge=vm_minp, MaxEdge=vm_maxp}
|
|
local data = vm:get_data()
|
|
-- Assume X and Z lengths are equal
|
|
local divlen = 32
|
|
local divs = (maxp.x-minp.x)/divlen+1;
|
|
for divx=0,divs-1 do
|
|
for divz=0,divs-1 do
|
|
local x0 = minp.x + math.floor((divx+0)*divlen)
|
|
local z0 = minp.z + math.floor((divz+0)*divlen)
|
|
local x1 = minp.x + math.floor((divx+1)*divlen)
|
|
local z1 = minp.z + math.floor((divz+1)*divlen)
|
|
-- Determine amount from perlin noise
|
|
local amount = math.floor(perlin1:get2d({x=x0, y=z0}) * 5 + 10)
|
|
-- Find random positions based on this random
|
|
local pr = PseudoRandom(seed+486)
|
|
for i=0,amount do
|
|
local x = pr:next(x0, x1)
|
|
local z = pr:next(z0, z1)
|
|
local ground_y = nil
|
|
-- Prevent from starting underground
|
|
local nn = minetest.get_node({x=x,y=maxp.y,z=z}).name
|
|
if nn ~= "air" and nn ~= "ignore" then
|
|
return
|
|
end
|
|
-- Find groundlevel
|
|
for y=maxp.y,minp.y,-1 do
|
|
local nn = minetest.get_node({x=x,y=y,z=z}).name
|
|
if nn ~= "air" and nn~= "ignore" then
|
|
--local is_leaves = minetest.registered_nodes[nn].groups.leaves
|
|
--if is_leaves == nil or is_leaves == 0 then
|
|
-- ground_y = y
|
|
-- break
|
|
--end
|
|
local is_leaves = minetest.registered_nodes[nn].groups.leaves
|
|
local is_plant = minetest.registered_nodes[nn].groups.plant
|
|
local is_le_plant = minetest.registered_nodes[nn].groups.lib_ecology_plant
|
|
local is_flora = minetest.registered_nodes[nn].groups.flora
|
|
local is_flower = minetest.registered_nodes[nn].groups.flower
|
|
local is_growing = minetest.registered_nodes[nn].groups.growing
|
|
if is_leaves == nil or is_leaves == 0 or is_plant == nil or is_plant == 0 or is_le_plant == nil or is_le_plant == 0 or is_flora == nil or is_flora == 0 or is_flower == nil or is_flower == 0 or is_growing == nil or is_growing == 0 then
|
|
ground_y = y
|
|
break
|
|
end
|
|
end
|
|
end
|
|
if ground_y and ground_y >= 2 then
|
|
local p = {x=x,y=ground_y,z=z}
|
|
local ground_name = minetest.get_node(p)
|
|
local node_name = minetest.get_node(p).name
|
|
if ground_name == "default:water_source" or ground_name == "lib_materials:fluid_water_source" then return end
|
|
local lx = pr:next(10,30)
|
|
local lz = pr:next(10,30)
|
|
if string.match(node_name, "lib_materials:dirt_sandy") then
|
|
c_fluid_id = c_quick_source
|
|
end
|
|
--if string.match(node_name, "lib_materials:sand") then
|
|
-- c_fluid_id = c_quick
|
|
--end
|
|
if string.match(node_name, "lib_materials:dirt_with_rainforest_litter") then
|
|
c_fluid_id = c_murky
|
|
end
|
|
if string.match(node_name, "lib_materials:dirt_mud_01") then
|
|
c_fluid_id = c_muddy
|
|
end
|
|
if string.match(node_name, "lib_materials:dirt_clayey") then
|
|
c_fluid_id = c_muddy
|
|
end
|
|
if string.match(node_name, "lib_materials:sand_desert") then
|
|
c_fluid_id = c_mud_dried
|
|
end
|
|
if string.match(node_name, "lib_materials:sand") then
|
|
c_fluid_id = c_mud_dried
|
|
end
|
|
--if string.match(node_name, "lib_materials:dirt_with_grass_warm_semihumid_coastal") or string.match(node_name, "lib_materials:dirt_with_grass_temperate_semihumid_coastal") then
|
|
-- c_fluid_id = c_dirty
|
|
--end
|
|
--if string.match(node_name, "lib_materials:dirt_with_grass_warm_semihumid_lowland") or string.match(node_name, "lib_materials:dirt_with_grass_temperate_semihumid_lowland") then
|
|
-- c_fluid_id = c_dirty
|
|
--end
|
|
--if string.match(node_name, "lib_materials:dirt_with_grass_warm_semihumid_shelf") or string.match(node_name, "lib_materials:dirt_with_grass_temperate_semihumid_shelf") then
|
|
-- c_fluid_id = c_dirty
|
|
--end
|
|
--if string.match(node_name, "lib_materials:dirt_with_grass_warm_semihumid_highland") or string.match(node_name, "lib_materials:dirt_with_grass_temperate_semihumid_highland") then
|
|
-- c_fluid_id = c_dirty
|
|
--end
|
|
if string.match(node_name, "lib_materials:stone_bluestone") then
|
|
c_fluid_id = c_lava
|
|
end
|
|
if string.match(node_name, "snow") then
|
|
c_fluid_id = c_ice
|
|
end
|
|
if ground_y >= lib_materials.minheight_snow then
|
|
c_fluid_id = c_ice
|
|
end
|
|
-- if c_water == "" then
|
|
|
|
-- else
|
|
-- c_water = minetest.get_content_id("default:river_water_source")
|
|
-- end
|
|
lib_materials.lakes_fill(data, a, p, lx, lz)
|
|
--c_fluid_id = ""
|
|
end
|
|
|
|
end
|
|
end
|
|
end
|
|
-- Write to map
|
|
vm:set_data(data)
|
|
vm:write_to_map(data)
|
|
vm:update_map()
|
|
end
|
|
end)
|
|
|
|
--
|
|
-- Make lake
|
|
--
|
|
|
|
-- TODO: combine functions into one
|
|
local function check_x(data, a, x, y, z, lx, lz)
|
|
for xi = 0, lx do
|
|
local vi = a:index(x+xi, y, z)
|
|
if data[vi] == c_air or data[vi] == c_ignore then
|
|
return true
|
|
end
|
|
local vii = a:index(x+xi, y, z+lz)
|
|
if data[vii] == c_air or data[vii] == c_ignore then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
|
|
local function check_z(data, a, x, y, z, lx, lz)
|
|
for zi = 0, lz do
|
|
local vi = a:index(x, y, z+zi)
|
|
if data[vi] == c_air or data[vi] == c_ignore then
|
|
return true
|
|
end
|
|
local vii = a:index(x+lx, y, z+zi)
|
|
if data[vii] == c_air or data[vii] == c_ignore then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
|
|
local function leak(data, a, j, lx, lz)
|
|
for xi = 0, lx do
|
|
for zi = 0, lz do
|
|
local vi = a:index(xi, -j, zi)
|
|
if data[vi] == c_air or data[vi] == c_ignore then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function lib_materials.lakes_fill(data, a, pos, lx, lz)
|
|
local x, y, z = pos.x, pos.y, pos.z
|
|
local water_a = VoxelArea:new{MinEdge={x=0, y=-32, z=0}, MaxEdge={x=lx, y=0, z=lz}}
|
|
local water_buffer = {}
|
|
-- Find upper start
|
|
local i = 0
|
|
while i <= 16 do
|
|
if check_x(data, a, x, y-i, z, lx, lz) or check_z(data, a, x, y-i, z, lx, lz) then
|
|
i = i + 1
|
|
else
|
|
break
|
|
end
|
|
end
|
|
if i >= 16 then return end
|
|
-- Itterate downwards
|
|
local j = i
|
|
while j <= (i+16) do
|
|
if check_x(data, a, x, y-j, z, lx, lz) or check_z(data, a, x, y-j, z, lx, lz) then
|
|
j = j - 1
|
|
break
|
|
else
|
|
j = j + 1
|
|
end
|
|
end
|
|
if j >= i+16 then return end
|
|
-- print ('[lib_lakes] i = '.. i ..'')
|
|
-- print ('[lib_lakes] j = '.. j ..'')
|
|
-- Check bottom
|
|
if leak(data, a, j, lx, lz) then return end
|
|
-- Add volume to buffer
|
|
for xi = 0, lx do
|
|
for yi = -i, -j, -1 do
|
|
for zi = 0, lz do
|
|
water_buffer[water_a:index(xi, yi, zi)] = true
|
|
end
|
|
end
|
|
end
|
|
-- Add the water
|
|
for xi = water_a.MinEdge.x, water_a.MaxEdge.x do
|
|
for yi = water_a.MinEdge.y, water_a.MaxEdge.y do
|
|
for zi = water_a.MinEdge.z, water_a.MaxEdge.z do
|
|
if a:contains(x+xi, y+yi, z+zi) then
|
|
local vi = a:index(x+xi, y+yi, z+zi)
|
|
if data[vi] == c_air or data[vi] == c_ignore then
|
|
if water_buffer[water_a:index(xi, yi, zi)] then
|
|
data[vi] = c_fluid_id
|
|
-- print ('[lib_lakes] Wasser auf (' .. x+xi .. ',' .. y+yi .. ',' .. z+zi .. ')')
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|