279 lines
7.1 KiB
Lua
279 lines
7.1 KiB
Lua
-- Fun_Caves mapgen.lua
|
|
-- Copyright Duane Robertson (duane@duanerobertson.com), 2017
|
|
-- Distributed under the LGPLv2.1 (https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html)
|
|
|
|
|
|
local DEBUG
|
|
local max_depth = -28000
|
|
local seed_noise = {offset = 0, scale = 32768, seed = 5202, spread = {x = 80, y = 80, z = 80}, octaves = 2, persist = 0.4, lacunarity = 2}
|
|
fun_caves_mod.use_bi_hi = true
|
|
|
|
|
|
local ground_nodes = {}
|
|
ground_nodes[minetest.get_content_id('default:stone')] = true
|
|
ground_nodes[minetest.get_content_id('default:desert_stone')] = true
|
|
ground_nodes[minetest.get_content_id('default:sandstone')] = true
|
|
ground_nodes[minetest.get_content_id('default:dirt')] = true
|
|
ground_nodes[minetest.get_content_id('default:sand')] = true
|
|
ground_nodes[minetest.get_content_id('default:dirt_with_grass')] = true
|
|
ground_nodes[minetest.get_content_id('default:dirt_with_snow')] = true
|
|
ground_nodes[minetest.get_content_id('default:dirt_with_dry_grass')] = true
|
|
|
|
|
|
-- This tables looks up nodes that aren't already stored.
|
|
local node = setmetatable({}, {
|
|
__index = function(t, k)
|
|
if not (t and k and type(t) == 'table') then
|
|
return
|
|
end
|
|
|
|
t[k] = minetest.get_content_id(k)
|
|
return t[k]
|
|
end
|
|
})
|
|
|
|
local data = {}
|
|
|
|
|
|
fun_caves_mod.cave_biomes = {
|
|
algae = {
|
|
biome_val_low = 0,
|
|
biome_val_high = 0.2,
|
|
ceiling_node = 'fun_caves:stone_with_algae',
|
|
dirt = 'default:dirt',
|
|
dirt_chance = 10,
|
|
floor_node = 'fun_caves:stone_with_algae',
|
|
fungi = true,
|
|
stalactite = 'fun_caves:stalactite_slimy',
|
|
stalactite_chance = 12,
|
|
stalagmite = 'fun_caves:stalagmite_slimy',
|
|
stalagmite_chance = 12,
|
|
stone_depth = 1,
|
|
underwater = true,
|
|
},
|
|
coal = {
|
|
biome_val_low = 0.5,
|
|
biome_val_high = 0.6,
|
|
ceiling_node = 'fun_caves:black_sand',
|
|
deco = 'default:coalblock',
|
|
deco_chance = 100,
|
|
floor_node = 'fun_caves:black_sand',
|
|
stalagmite = 'fun_caves:constant_flame',
|
|
stalagmite_chance = 50,
|
|
stone_depth = 2,
|
|
underwater = false,
|
|
},
|
|
hot = {
|
|
biome_val_low = 0.6,
|
|
biome_val_high = 99,
|
|
ceiling_node = 'fun_caves:hot_cobble',
|
|
floor_node = 'fun_caves:hot_cobble',
|
|
fluid = 'default:lava_source',
|
|
fluid_chance = 300,
|
|
stalagmite = fun_caves_mod.hot_spikes,
|
|
stalagmite_chance = 50,
|
|
stone_depth = 1,
|
|
underwater = false,
|
|
},
|
|
ice = {
|
|
biome_val_low = -99,
|
|
biome_val_high = -0.6,
|
|
ceiling_node = 'default:ice',
|
|
floor_node = 'default:ice',
|
|
stalactite = 'fun_caves:icicle_down',
|
|
stalactite_chance = 12,
|
|
stalagmite = 'fun_caves:icicle_up',
|
|
stalagmite_chance = 12,
|
|
stone_depth = 2,
|
|
underwater = true,
|
|
},
|
|
ice_thin = {
|
|
biome_val_low = -0.6,
|
|
biome_val_high = -0.5,
|
|
ceiling_node = 'fun_caves:thin_ice',
|
|
floor_node = 'fun_caves:thin_ice',
|
|
stone_depth = 2,
|
|
underwater = true,
|
|
},
|
|
lichen = {
|
|
biome_val_low = -0.3,
|
|
biome_val_high = 0,
|
|
ceiling_node = 'fun_caves:stone_with_lichen',
|
|
dirt = 'default:dirt',
|
|
dirt_chance = 10,
|
|
floor_node = 'fun_caves:stone_with_lichen',
|
|
fungi = true,
|
|
stalactite = 'fun_caves:stalactite',
|
|
stalactite_chance = 12,
|
|
stalagmite = 'fun_caves:stalagmite',
|
|
stalagmite_chance = 12,
|
|
stone_depth = 1,
|
|
underwater = true,
|
|
},
|
|
lichen_dead = {
|
|
biome_val_low = -0.6,
|
|
biome_val_high = -0.5,
|
|
ceiling_node = 'fun_caves:stone_with_lichen',
|
|
floor_node = 'fun_caves:stone_with_lichen',
|
|
stalactite = 'fun_caves:stalactite',
|
|
stalactite_chance = 12,
|
|
stalagmite = 'fun_caves:stalagmite',
|
|
stalagmite_chance = 12,
|
|
stone_depth = 1,
|
|
underwater = true,
|
|
},
|
|
moss = {
|
|
biome_val_low = -0.5,
|
|
biome_val_high = -0.3,
|
|
ceiling_node = 'fun_caves:stone_with_moss',
|
|
deco = 'fun_caves:glowing_fungal_stone',
|
|
deco_chance = 50,
|
|
floor_node = 'fun_caves:stone_with_moss',
|
|
fluid = 'default:water_source',
|
|
fluid_chance = 300,
|
|
stalactite = 'fun_caves:stalactite_mossy',
|
|
stalactite_chance = 12,
|
|
stalagmite = 'fun_caves:stalagmite_mossy',
|
|
stalagmite_chance = 12,
|
|
stone_depth = 1,
|
|
underwater = true,
|
|
},
|
|
salt = {
|
|
biome_val_low = 0.2,
|
|
biome_val_high = 0.35,
|
|
ceiling_node = 'fun_caves:stone_with_salt',
|
|
deco = 'fun_caves:radioactive_ore',
|
|
deco_chance = 500,
|
|
floor_node = 'fun_caves:stone_with_salt',
|
|
stone_depth = 2,
|
|
underwater = false,
|
|
},
|
|
sand = {
|
|
biome_val_low = 0.35,
|
|
biome_val_high = 0.5,
|
|
ceiling_node = 'default:sand',
|
|
floor_node = 'default:sand',
|
|
stone_depth = 2,
|
|
underwater = true,
|
|
},
|
|
}
|
|
|
|
|
|
local function generate(p_minp, p_maxp, seed)
|
|
if not (p_minp and p_maxp and seed) then
|
|
return
|
|
end
|
|
|
|
local minp, maxp = p_minp, p_maxp
|
|
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
|
if not (vm and emin and emax) then
|
|
return
|
|
end
|
|
|
|
vm:get_data(data)
|
|
local heightmap
|
|
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
|
local csize = vector.add(vector.subtract(maxp, minp), 1)
|
|
local write
|
|
|
|
|
|
if minetest.get_modpath('ramoid') and ramoid_mod and ramoid_mod.ramoid_depth then
|
|
local avg = (minp.y + maxp.y) / 2
|
|
if avg > (ramoid_mod.ramoid_depth - 1) * 80 - 32 and avg < ramoid_mod.ramoid_depth * 80 - 32 then
|
|
return
|
|
end
|
|
end
|
|
|
|
if minetest.get_modpath('underworlds') and underworlds_mod and underworlds_mod.underzones then
|
|
local avg = (minp.y + maxp.y) / 2
|
|
for _, uz in pairs(underworlds_mod.underzones) do
|
|
if avg <= uz.upper_bound and avg >= uz.lower_bound then
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
if fun_caves_mod.use_bi_hi then
|
|
heightmap = minetest.get_mapgen_object("heightmap")
|
|
end
|
|
|
|
|
|
-- Correct heightmap.
|
|
if maxp.y < -300 or minp.y > 300 then
|
|
for i = 1, #heightmap do
|
|
heightmap[i] = (maxp.y < 0) and max_depth or - max_depth
|
|
end
|
|
else
|
|
local index = 0
|
|
for z = minp.z, maxp.z do
|
|
for x = minp.x, maxp.x do
|
|
index = index + 1
|
|
|
|
local height = heightmap[index]
|
|
if height and height < maxp.y - 1 and height > minp.y then
|
|
--nop
|
|
else
|
|
height = - max_depth
|
|
local ivm2 = area:index(x, maxp.y + 8, z)
|
|
for y = maxp.y + 8, minp.y - 8, -1 do
|
|
if ground_nodes[data[ivm2]] then
|
|
height = (y < maxp.y + 8) and y or max_depth
|
|
break
|
|
end
|
|
ivm2 = ivm2 - area.ystride
|
|
end
|
|
heightmap[index] = height
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
for fake_loop = 1, 1 do
|
|
if fun_caves_mod.cavegen and fun_caves_mod.decogen then
|
|
local h2, write_cave
|
|
write_cave = fun_caves_mod.cavegen(minp, maxp, data, area, node, heightmap)
|
|
write = write or write_cave
|
|
|
|
local write_deco
|
|
write_deco = fun_caves_mod.decogen(minp, maxp, data, area, node, heightmap)
|
|
write = write or write_deco
|
|
end
|
|
end
|
|
|
|
|
|
if write then
|
|
vm:set_data(data)
|
|
|
|
if DEBUG then
|
|
vm:set_lighting({day = 8, night = 8})
|
|
else
|
|
vm:set_lighting({day = 0, night = 0}, minp, maxp)
|
|
vm:calc_lighting()
|
|
end
|
|
vm:update_liquids()
|
|
vm:write_to_map()
|
|
end
|
|
end
|
|
|
|
|
|
if fun_caves_mod.path then
|
|
dofile(fun_caves_mod.path .. "/cavegen.lua")
|
|
dofile(fun_caves_mod.path .. "/deco.lua")
|
|
end
|
|
|
|
|
|
local function pgenerate(...)
|
|
local status, err = pcall(generate, ...)
|
|
--local status, err = true
|
|
--generate(...)
|
|
if not status then
|
|
print('Fun Caves: Could not generate terrain:')
|
|
print(dump(err))
|
|
collectgarbage("collect")
|
|
end
|
|
end
|
|
|
|
|
|
-- Inserting helps to ensure that fun_caves_mod operates first.
|
|
--table.insert(minetest.registered_on_generateds, 1, pgenerate)
|
|
minetest.register_on_generated(pgenerate)
|