mirror of
https://github.com/minetest-mods/magma_conduits.git
synced 2025-01-22 20:31:42 +01:00
Initial stab at volcano mapgen
This commit is contained in:
parent
ffeeb026dc
commit
bf6f683211
@ -29,6 +29,9 @@ setting("bool", "ameliorate_floods", true, "Ameliorate lava floods on the surfac
|
||||
setting("bool", "obsidian_lining", true, "Add an obsidian lining to magma conduits")
|
||||
setting("bool", "glowing_rock", true, "Cause rock adjacent to lava to convert into glowing form")
|
||||
setting("int", "remove_lava_above", 512, "Remove lava above this y level")
|
||||
setting("bool", "magma_veins", true, "Enable magma veins")
|
||||
setting("bool", "volcanoes", true, "Enable volcanoes")
|
||||
|
||||
-- Removing this setting on account of issue https://github.com/minetest/minetest/issues/7364
|
||||
--setting("int", "upper_limit", 512, "Upper extent of magma conduits")
|
||||
--setting("int", "lower_limit", -31000, "Lower extent of magma conduits")
|
||||
|
135
init.lua
135
init.lua
@ -6,138 +6,9 @@ dofile(modpath.."/voxelarea_iterator.lua")
|
||||
dofile(modpath.."/hot_rock.lua")
|
||||
|
||||
if magma_conduits.config.remove_default_lava then
|
||||
minetest.register_alias_force("mapgen_lava_source", "air") -- veins of lava are far more realistic
|
||||
minetest.register_alias_force("mapgen_lava_source", "air")
|
||||
end
|
||||
|
||||
-- Hard-coding on account of issue https://github.com/minetest/minetest/issues/7364
|
||||
local height_min = -31000 -- magma_conduits.config.lower_limit
|
||||
local height_max = 31000 --magma_conduits.config.upper_limit
|
||||
dofile(modpath.."/magma_veins.lua")
|
||||
dofile(modpath.."/volcanoes.lua")
|
||||
|
||||
minetest.register_ore({
|
||||
ore_type = "vein",
|
||||
ore = "default:lava_source",
|
||||
wherein = {
|
||||
"default:stone",
|
||||
"default:desert_stone",
|
||||
"default:sandstone",
|
||||
"default:stone_with_coal",
|
||||
"default:stone_with_iron",
|
||||
"default:stone_with_copper",
|
||||
"default:stone_with_tin",
|
||||
"default:stone_with_gold",
|
||||
"default:stone_with_diamond",
|
||||
"default:dirt",
|
||||
"default:dirt_with_grass",
|
||||
"default:dirt_with_dry_grass",
|
||||
"default:dirt_with_snow",
|
||||
"default:dirt_with_rainforest_litter",
|
||||
"default:dirt_with_coniferous_litter",
|
||||
"default:sand",
|
||||
"default:desert_sand",
|
||||
"default:silver_sand",
|
||||
"default:gravel",
|
||||
},
|
||||
column_height_min = 2,
|
||||
column_height_max = 6,
|
||||
y_min = height_min,
|
||||
y_max = height_max,
|
||||
noise_threshold = 0.9,
|
||||
noise_params = {
|
||||
offset = 0,
|
||||
scale = 3,
|
||||
spread = {x=magma_conduits.config.spread, y=magma_conduits.config.spread*2, z=magma_conduits.config.spread},
|
||||
seed = 25391,
|
||||
octaves = 4,
|
||||
persist = 0.5,
|
||||
flags = "eased",
|
||||
},
|
||||
random_factor = 0,
|
||||
})
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
local water_level = tonumber(minetest.get_mapgen_setting("water_level"))
|
||||
|
||||
local lava_y_cutoff = magma_conduits.config.remove_lava_above
|
||||
-- if the y cutoff is at or below water level, ameliorate_floods is pointless.
|
||||
local ameliorate_floods = magma_conduits.config.ameliorate_floods and lava_y_cutoff > water_level
|
||||
local obsidian_lining = magma_conduits.config.obsidian_lining
|
||||
|
||||
local c_air = minetest.get_content_id("air")
|
||||
local c_lava = minetest.get_content_id("default:lava_source")
|
||||
local c_stone = minetest.get_content_id("default:stone")
|
||||
local c_obsidian = minetest.get_content_id("default:obsidian")
|
||||
|
||||
local is_adjacent_to_air = function(area, data, x, y, z)
|
||||
return (data[area:index(x+1, y, z)] == c_air
|
||||
or data[area:index(x-1, y, z)] == c_air
|
||||
or data[area:index(x, y, z+1)] == c_air
|
||||
or data[area:index(x, y, z-1)] == c_air
|
||||
or data[area:index(x, y-1, z)] == c_air)
|
||||
end
|
||||
|
||||
local remove_unsupported_lava
|
||||
remove_unsupported_lava = function(area, data, vi, x, y, z)
|
||||
--if below water level, abort. Caverns are on their own.
|
||||
if y < water_level or y > lava_y_cutoff or not area:contains(x, y, z) then return end
|
||||
|
||||
if data[vi] == c_lava then
|
||||
if is_adjacent_to_air(area, data, x, y, z) then
|
||||
data[vi] = c_air
|
||||
for pi, x2, y2, z2 in area:iter_xyz(x-1, y, z-1, x+1, y+1, z+1) do
|
||||
if pi ~= vi and area:containsi(pi) then
|
||||
remove_unsupported_lava(area, data, pi, x2, y2, z2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- If we're adding glow versions of rock, then place glow obsidian directly.
|
||||
local obsidianize_id
|
||||
if magma_conduits.config.glowing_rock then
|
||||
obsidianize_id = minetest.get_content_id("magma_conduits:glow_obsidian")
|
||||
else
|
||||
obsidianize_id = c_obsidian
|
||||
end
|
||||
|
||||
local obsidianize = function(area, data, vi, x, y, z, minp, maxp)
|
||||
if data[vi] == c_lava then
|
||||
for pi in area:iter(math.max(x-1, minp.x), math.max(y-1, minp.y), math.max(z-1, minp.z),
|
||||
math.min(x+1, maxp.x), math.min(y+1, maxp.y), math.min(z+1, maxp.z)) do
|
||||
if data[pi] == c_stone then
|
||||
data[pi] = obsidianize_id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local data = {}
|
||||
|
||||
minetest.register_on_generated(function(minp, maxp, seed)
|
||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
|
||||
vm:get_data(data)
|
||||
|
||||
for vi, x, y, z in area:iterp_xyz(minp, maxp) do
|
||||
if y > lava_y_cutoff and data[vi] == c_lava then
|
||||
data[vi] = c_air
|
||||
else
|
||||
if obsidian_lining then
|
||||
obsidianize(area, data, vi, x, y, z, minp, maxp)
|
||||
end
|
||||
if ameliorate_floods then
|
||||
remove_unsupported_lava(area, data, vi, x, y, z)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--send data back to voxelmanip
|
||||
vm:set_data(data)
|
||||
--calc lighting
|
||||
vm:set_lighting({day = 0, night = 0})
|
||||
vm:calc_lighting()
|
||||
vm:update_liquids()
|
||||
--write it to world
|
||||
vm:write_to_map()
|
||||
end)
|
132
magma_veins.lua
Normal file
132
magma_veins.lua
Normal file
@ -0,0 +1,132 @@
|
||||
-- Hard-coding on account of issue https://github.com/minetest/minetest/issues/7364
|
||||
local height_min = -31000 -- magma_conduits.config.lower_limit
|
||||
local height_max = 31000 --magma_conduits.config.upper_limit
|
||||
|
||||
minetest.register_ore({
|
||||
ore_type = "vein",
|
||||
ore = "default:lava_source",
|
||||
wherein = {
|
||||
"default:stone",
|
||||
"default:desert_stone",
|
||||
"default:sandstone",
|
||||
"default:stone_with_coal",
|
||||
"default:stone_with_iron",
|
||||
"default:stone_with_copper",
|
||||
"default:stone_with_tin",
|
||||
"default:stone_with_gold",
|
||||
"default:stone_with_diamond",
|
||||
"default:dirt",
|
||||
"default:dirt_with_grass",
|
||||
"default:dirt_with_dry_grass",
|
||||
"default:dirt_with_snow",
|
||||
"default:dirt_with_rainforest_litter",
|
||||
"default:dirt_with_coniferous_litter",
|
||||
"default:sand",
|
||||
"default:desert_sand",
|
||||
"default:silver_sand",
|
||||
"default:gravel",
|
||||
},
|
||||
column_height_min = 2,
|
||||
column_height_max = 6,
|
||||
y_min = height_min,
|
||||
y_max = height_max,
|
||||
noise_threshold = 0.9,
|
||||
noise_params = {
|
||||
offset = 0,
|
||||
scale = 3,
|
||||
spread = {x=magma_conduits.config.spread, y=magma_conduits.config.spread*2, z=magma_conduits.config.spread},
|
||||
seed = 25391,
|
||||
octaves = 4,
|
||||
persist = 0.5,
|
||||
flags = "eased",
|
||||
},
|
||||
random_factor = 0,
|
||||
})
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
local water_level = tonumber(minetest.get_mapgen_setting("water_level"))
|
||||
|
||||
local lava_y_cutoff = magma_conduits.config.remove_lava_above
|
||||
-- if the y cutoff is at or below water level, ameliorate_floods is pointless.
|
||||
local ameliorate_floods = magma_conduits.config.ameliorate_floods and lava_y_cutoff > water_level
|
||||
local obsidian_lining = magma_conduits.config.obsidian_lining
|
||||
|
||||
local c_air = minetest.get_content_id("air")
|
||||
local c_lava = minetest.get_content_id("default:lava_source")
|
||||
local c_stone = minetest.get_content_id("default:stone")
|
||||
local c_obsidian = minetest.get_content_id("default:obsidian")
|
||||
|
||||
local is_adjacent_to_air = function(area, data, x, y, z)
|
||||
return (data[area:index(x+1, y, z)] == c_air
|
||||
or data[area:index(x-1, y, z)] == c_air
|
||||
or data[area:index(x, y, z+1)] == c_air
|
||||
or data[area:index(x, y, z-1)] == c_air
|
||||
or data[area:index(x, y-1, z)] == c_air)
|
||||
end
|
||||
|
||||
local remove_unsupported_lava
|
||||
remove_unsupported_lava = function(area, data, vi, x, y, z)
|
||||
--if below water level, abort. Caverns are on their own.
|
||||
if y < water_level or y > lava_y_cutoff or not area:contains(x, y, z) then return end
|
||||
|
||||
if data[vi] == c_lava then
|
||||
if is_adjacent_to_air(area, data, x, y, z) then
|
||||
data[vi] = c_air
|
||||
for pi, x2, y2, z2 in area:iter_xyz(x-1, y, z-1, x+1, y+1, z+1) do
|
||||
if pi ~= vi and area:containsi(pi) then
|
||||
remove_unsupported_lava(area, data, pi, x2, y2, z2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- If we're adding glow versions of rock, then place glow obsidian directly.
|
||||
local obsidianize_id
|
||||
if magma_conduits.config.glowing_rock then
|
||||
obsidianize_id = minetest.get_content_id("magma_conduits:glow_obsidian")
|
||||
else
|
||||
obsidianize_id = c_obsidian
|
||||
end
|
||||
|
||||
local obsidianize = function(area, data, vi, x, y, z, minp, maxp)
|
||||
if data[vi] == c_lava then
|
||||
for pi in area:iter(math.max(x-1, minp.x), math.max(y-1, minp.y), math.max(z-1, minp.z),
|
||||
math.min(x+1, maxp.x), math.min(y+1, maxp.y), math.min(z+1, maxp.z)) do
|
||||
if data[pi] == c_stone then
|
||||
data[pi] = obsidianize_id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local data = {}
|
||||
|
||||
minetest.register_on_generated(function(minp, maxp, seed)
|
||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
|
||||
vm:get_data(data)
|
||||
|
||||
for vi, x, y, z in area:iterp_xyz(minp, maxp) do
|
||||
if y > lava_y_cutoff and data[vi] == c_lava then
|
||||
data[vi] = c_air
|
||||
else
|
||||
if obsidian_lining then
|
||||
obsidianize(area, data, vi, x, y, z, minp, maxp)
|
||||
end
|
||||
if ameliorate_floods then
|
||||
remove_unsupported_lava(area, data, vi, x, y, z)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--send data back to voxelmanip
|
||||
vm:set_data(data)
|
||||
--calc lighting
|
||||
vm:set_lighting({day = 0, night = 0})
|
||||
vm:calc_lighting()
|
||||
vm:update_liquids()
|
||||
--write it to world
|
||||
vm:write_to_map()
|
||||
end)
|
@ -3,4 +3,6 @@ magma_conduits_ameliorate_floods (Ameliorate lava floods on the surface) bool tr
|
||||
magma_conduits_obsidian_lining (Adds an obsidian lining to magma conduits) bool true
|
||||
magma_conduits_remove_default_lava (Remove default mapgen lava) bool true
|
||||
magma_conduits_glowing_rock (Cause rock adjacent to lava to convert into "glowing" form) bool true
|
||||
magma_conduits_remove_lava_above (Removes any lava above this y level) int 512
|
||||
magma_conduits_remove_lava_above (Removes any lava above this y level) int 512
|
||||
magma_conduits_magma_veins (Enable magma veins) bool true
|
||||
magma_conduits_volcanoes (Enable volcanoes) bool true
|
187
volcanoes.lua
Normal file
187
volcanoes.lua
Normal file
@ -0,0 +1,187 @@
|
||||
local depth_root = -3000
|
||||
local depth_base = -50
|
||||
local depth_maxwidth = -10
|
||||
local depth_maxpeak = 200
|
||||
local depth_minpeak = 20
|
||||
local radius_vent = 5
|
||||
local radius_lining = 7
|
||||
local slope_min = 0.25
|
||||
local slope_max = 1.75
|
||||
local chunk_size = 1000
|
||||
|
||||
local c_air = minetest.get_content_id("air")
|
||||
local c_lava = minetest.get_content_id("default:lava_source")
|
||||
local c_lining = minetest.get_content_id("default:obsidian")
|
||||
local c_hot_lining = minetest.get_content_id("default:obsidian")
|
||||
local c_cone = minetest.get_content_id("default:stone")
|
||||
local c_ash = minetest.get_content_id("default:gravel")
|
||||
local c_soil = minetest.get_content_id("default:dirt_with_grass")
|
||||
local c_plug = minetest.get_content_id("default:obsidian")
|
||||
|
||||
local c_stone = minetest.get_content_id("default:stone")
|
||||
local c_water = minetest.get_content_id("default:water_source")
|
||||
|
||||
if magma_conduits.config.glowing_rock then
|
||||
c_hot_lining = minetest.get_content_id("magma_conduits:glow_obsidian")
|
||||
end
|
||||
|
||||
local mapgen_seed = tonumber(minetest.get_mapgen_setting("seed"))
|
||||
|
||||
-- derived values
|
||||
|
||||
local radius_cone_max = (depth_maxpeak-depth_maxwidth)/(2*slope_min)
|
||||
local depth_maxwidth_dist = depth_maxwidth-depth_base
|
||||
local depth_maxpeak_dist = depth_maxpeak-depth_maxwidth
|
||||
|
||||
local scatter_2d = function(min_xz, gridscale, border_width)
|
||||
local bordered_scale = gridscale - 2 * border_width
|
||||
local point = {}
|
||||
point.x = math.random() * bordered_scale + min_xz.x + border_width
|
||||
point.y = 0
|
||||
point.z = math.random() * bordered_scale + min_xz.z + border_width
|
||||
return point
|
||||
end
|
||||
|
||||
local get_volcano = function(pos)
|
||||
local corner_xz = {x = math.floor(pos.x / chunk_size) * chunk_size, z = math.floor(pos.z / chunk_size) * chunk_size}
|
||||
|
||||
local next_seed = math.random(1, 1000000000)
|
||||
math.randomseed(corner_xz.x + corner_xz.z * 2 ^ 8 + mapgen_seed)
|
||||
|
||||
local location = scatter_2d(corner_xz, chunk_size, radius_cone_max)
|
||||
local depth_peak = math.random(depth_minpeak, depth_maxpeak)
|
||||
local depth_lava = math.random(depth_peak - 50, depth_peak)
|
||||
local slope = math.random() * (slope_max - slope_min) + slope_min
|
||||
|
||||
local state = math.random()
|
||||
|
||||
math.randomseed(next_seed)
|
||||
return {location = location, depth_peak = depth_peak, depth_lava = depth_lava, slope = slope, state = state}
|
||||
end
|
||||
|
||||
local perlin_params = {
|
||||
offset = 0,
|
||||
scale = 1,
|
||||
spread = {x=30, y=30, z=30},
|
||||
seed = -40901,
|
||||
octaves = 3,
|
||||
persist = 0.67
|
||||
}
|
||||
local nvals_perlin_buffer = {}
|
||||
local nobj_perlin = nil
|
||||
local data = {}
|
||||
|
||||
minetest.register_on_generated(function(minp, maxp, seed)
|
||||
|
||||
if minp.y > depth_maxpeak then
|
||||
return
|
||||
end
|
||||
|
||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
|
||||
vm:get_data(data)
|
||||
|
||||
local minx = minp.x
|
||||
local minz = minp.z
|
||||
local sidelen = maxp.x - minp.x + 1 --length of a mapblock
|
||||
local chunk_lengths = {x = sidelen, y = sidelen, z = sidelen} --table of chunk edges
|
||||
|
||||
nobj_perlin = nobj_perlin or minetest.get_perlin_map(perlin_params, chunk_lengths)
|
||||
local nvals_perlin = nobj_perlin:get3dMap_flat(minp, nvals_perlin_buffer) -- switch to get_3d_map_flat for minetest v0.5
|
||||
local noise_area = VoxelArea:new{MinEdge=minp, MaxEdge=maxp}
|
||||
local noise_iterator = noise_area:iterp(minp, maxp)
|
||||
|
||||
local volcano = get_volcano(minp)
|
||||
|
||||
minetest.debug(dump(volcano))
|
||||
|
||||
local x_coord = volcano.location.x
|
||||
local z_coord = volcano.location.z
|
||||
local depth_lava = volcano.depth_lava
|
||||
local depth_peak = volcano.depth_peak
|
||||
local base_radius = (depth_peak - depth_maxwidth) * volcano.slope + radius_lining
|
||||
|
||||
local state = volcano.state
|
||||
|
||||
local dirtstuff
|
||||
if state < 0.5 then
|
||||
dirtstuff = c_soil
|
||||
else
|
||||
dirtstuff = c_ash
|
||||
end
|
||||
|
||||
for vi, x, y, z in area:iterp_xyz(minp, maxp) do
|
||||
|
||||
local vi3d = noise_iterator()
|
||||
|
||||
local distance_perturbation = (nvals_perlin[vi3d]+1)*10
|
||||
local distance = vector.distance({x=x, y=y, z=z}, {x=x_coord, y=y, z=z_coord}) - distance_perturbation
|
||||
|
||||
if distance > base_radius * 2.5 then
|
||||
return
|
||||
end
|
||||
|
||||
local pipestuff
|
||||
local liningstuff
|
||||
if y < depth_lava + math.random() * 1.1 then
|
||||
if state < 0.25 then
|
||||
pipestuff = c_plug -- extinct volcano
|
||||
liningstuff = c_lining
|
||||
else
|
||||
pipestuff = c_lava
|
||||
liningstuff = c_hot_lining
|
||||
end
|
||||
else
|
||||
if state < 0.5 then
|
||||
pipestuff = c_plug -- dormant volcano
|
||||
liningstuff = c_lining
|
||||
else
|
||||
pipestuff = c_air -- active volcano
|
||||
liningstuff = c_lining
|
||||
end
|
||||
end
|
||||
|
||||
if y < depth_base then -- pipe
|
||||
if distance < radius_vent then
|
||||
data[vi] = pipestuff
|
||||
elseif distance < radius_lining then
|
||||
if data[vi] == c_stone or data[vi] == c_water then
|
||||
data[vi] = liningstuff
|
||||
end
|
||||
end
|
||||
elseif y < depth_maxwidth then -- root
|
||||
if distance < radius_vent then
|
||||
data[vi] = pipestuff
|
||||
elseif distance < radius_lining then
|
||||
data[vi] = liningstuff
|
||||
elseif distance < radius_lining + ((y - depth_base)/depth_maxwidth_dist) * base_radius then
|
||||
data[vi] = c_cone
|
||||
end
|
||||
elseif y < depth_peak then -- cone
|
||||
if vector.distance({x=x, y=y, z=z}, {x=x_coord, y=depth_peak, z=z_coord}) - distance_perturbation < radius_lining * 2.5 then
|
||||
data[vi] = c_air -- caldera
|
||||
elseif distance < radius_vent then
|
||||
data[vi] = pipestuff
|
||||
elseif distance < radius_lining then
|
||||
data[vi] = liningstuff
|
||||
elseif distance < y * -volcano.slope + base_radius then
|
||||
data[vi] = c_cone
|
||||
elseif distance < y * -volcano.slope + base_radius + nvals_perlin[vi3d]*-4 then
|
||||
data[vi] = dirtstuff
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--minetest.generate_decorations(vm, minp, maxp)
|
||||
--minetest.generate_ores(vm, minp, maxp)
|
||||
|
||||
--send data back to voxelmanip
|
||||
vm:set_data(data)
|
||||
--calc lighting
|
||||
vm:set_lighting({day = 0, night = 0})
|
||||
vm:calc_lighting()
|
||||
vm:update_liquids()
|
||||
--write it to world
|
||||
vm:write_to_map()
|
||||
end)
|
Loading…
Reference in New Issue
Block a user