Initial commit
|
@ -0,0 +1,16 @@
|
|||
# underworlds
|
||||
|
||||
This mod adds large underworlds to Minetest. Each is an open horizontal plane with different characteristics. The underzones table in init.lua contains all the data on each plane, including how far underground to generate it.
|
||||
|
||||
![screenshot](https://raw.githubusercontent.com/duane-r/underworlds/master/screenshot-2.png)
|
||||
![screenshot](https://raw.githubusercontent.com/duane-r/underworlds/master/screenshot-4.png)
|
||||
![screenshot](https://raw.githubusercontent.com/duane-r/underworlds/master/screenshot-5.png)
|
||||
|
||||
|
||||
The source is available on github.
|
||||
|
||||
Code: LGPL2
|
||||
|
||||
Mod dependencies: default
|
||||
|
||||
Download: https://github.com/duane-r/underworlds/archive/master.zip
|
|
@ -0,0 +1,267 @@
|
|||
-- Underworlds deco.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 newnode
|
||||
local light_max = default.light_max or 10
|
||||
|
||||
|
||||
if not minetest.registered_items['fun_caves:stalactite'] then
|
||||
-- Speleothems can be made into cobblestone, to get them out of inventory.
|
||||
minetest.register_craft({
|
||||
output = "default:cobble",
|
||||
recipe = {
|
||||
{"", "", ""},
|
||||
{"underworlds:stalactite", "underworlds:stalactite", ""},
|
||||
{"underworlds:stalactite", "underworlds:stalactite", ""},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:cobble",
|
||||
recipe = {
|
||||
{"", "", ""},
|
||||
{"underworlds:stalagmite", "underworlds:stalagmite", ""},
|
||||
{"underworlds:stalagmite", "underworlds:stalagmite", ""},
|
||||
},
|
||||
})
|
||||
|
||||
-- What's a cave without speleothems?
|
||||
local spel = {
|
||||
{type1="stalactite", type2="stalagmite", tile="default_stone.png"},
|
||||
{type1="stalactite_slimy", type2="stalagmite_slimy", tile="default_stone.png^underworlds_algae.png"},
|
||||
{type1="stalactite_mossy", type2="stalagmite_mossy", tile="default_stone.png^underworlds_moss.png"},
|
||||
{type1="icicle_down", type2="icicle_up", desc="Icicle", tile="caverealms_thin_ice.png", drop="default:ice"},
|
||||
}
|
||||
|
||||
for _, desc in pairs(spel) do
|
||||
minetest.register_node("underworlds:"..desc.type1, {
|
||||
description = (desc.desc or "Stalactite"),
|
||||
tiles = {desc.tile},
|
||||
is_ground_content = true,
|
||||
walkable = false,
|
||||
paramtype = "light",
|
||||
drop = (desc.drop or "underworlds:stalactite"),
|
||||
drawtype = "nodebox",
|
||||
node_box = { type = "fixed",
|
||||
fixed = {
|
||||
{-0.07, 0.0, -0.07, 0.07, 0.5, 0.07},
|
||||
{-0.04, -0.25, -0.04, 0.04, 0.0, 0.04},
|
||||
{-0.02, -0.5, -0.02, 0.02, 0.25, 0.02},
|
||||
} },
|
||||
groups = {rock=1, cracky=3},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("underworlds:"..desc.type2, {
|
||||
description = (desc.desc or "Stalagmite"),
|
||||
tiles = {desc.tile},
|
||||
is_ground_content = true,
|
||||
walkable = false,
|
||||
paramtype = "light",
|
||||
drop = "underworlds:stalagmite",
|
||||
drawtype = "nodebox",
|
||||
node_box = { type = "fixed",
|
||||
fixed = {
|
||||
{-0.07, -0.5, -0.07, 0.07, 0.0, 0.07},
|
||||
{-0.04, 0.0, -0.04, 0.04, 0.25, 0.04},
|
||||
{-0.02, 0.25, -0.02, 0.02, 0.5, 0.02},
|
||||
} },
|
||||
groups = {rock=1, cracky=3},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
if not minetest.registered_items['fun_caves:hot_stone'] then
|
||||
-- stone, hot
|
||||
minetest.register_node("underworlds:hot_stone", {
|
||||
description = "Hot Stone",
|
||||
tiles = {"default_desert_stone.png^[colorize:#FF0000:150"},
|
||||
is_ground_content = true,
|
||||
groups = {crumbly=2, surface_hot=3},
|
||||
light_source = light_max - 5,
|
||||
damage_per_second = 1,
|
||||
sounds = default.node_sound_stone_defaults({
|
||||
footstep = {name="default_stone_footstep", gain=0.25},
|
||||
}),
|
||||
})
|
||||
end
|
||||
|
||||
if not minetest.registered_items['fun_caves:glowing_fungal_stone'] then
|
||||
-- Glowing fungal stone provides an eerie light.
|
||||
minetest.register_node("underworlds:glowing_fungal_stone", {
|
||||
description = "Glowing Fungal Stone",
|
||||
tiles = {"default_stone.png^vmg_glowing_fungal.png",},
|
||||
is_ground_content = true,
|
||||
light_source = light_max - 4,
|
||||
groups = {cracky=3, stone=1},
|
||||
drop = {items={ {items={"default:cobble"},}, {items={"underworlds:glowing_fungus",},},},},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
-- Glowing fungus grows underground.
|
||||
minetest.register_craftitem("underworlds:glowing_fungus", {
|
||||
description = "Glowing Fungus",
|
||||
drawtype = "plantlike",
|
||||
paramtype = "light",
|
||||
tiles = {"vmg_glowing_fungus.png"},
|
||||
inventory_image = "vmg_glowing_fungus.png",
|
||||
groups = {dig_immediate = 3},
|
||||
})
|
||||
end
|
||||
|
||||
if not minetest.registered_items['fun_caves:black_sand'] then
|
||||
-- black (oily) sand
|
||||
local newnode = underworlds_mod.clone_node("default:sand")
|
||||
newnode.description = "Black Sand"
|
||||
newnode.tiles = {"underworlds_black_sand.png"}
|
||||
newnode.groups['falling_node'] = 0
|
||||
minetest.register_node("underworlds:black_sand", newnode)
|
||||
end
|
||||
|
||||
if not minetest.registered_items['fun_caves:hot_cobble'] then
|
||||
-- cobble, hot - cobble with lava instead of mortar XD
|
||||
minetest.register_node("underworlds:hot_cobble", {
|
||||
description = "Hot Cobble",
|
||||
tiles = {"caverealms_hot_cobble.png"},
|
||||
is_ground_content = true,
|
||||
groups = {crumbly=2, surface_hot=3},
|
||||
--light_source = 2,
|
||||
damage_per_second = 1,
|
||||
sounds = default.node_sound_stone_defaults({
|
||||
footstep = {name="default_stone_footstep", gain=0.25},
|
||||
}),
|
||||
})
|
||||
end
|
||||
|
||||
newnode = underworlds_mod.clone_node("default:water_source")
|
||||
newnode.description = "Poisonous Water"
|
||||
newnode.groups.poison = 3
|
||||
newnode.light_source = 6
|
||||
newnode.liquid_alternative_flowing = "underworlds:water_poison_flowing"
|
||||
newnode.liquid_alternative_source = "underworlds:water_poison_source"
|
||||
newnode.post_effect_color = {a = 103, r = 108, g = 128, b = 64}
|
||||
newnode.special_tiles[1].name = "underworlds_water_poison_source_animated.png"
|
||||
newnode.tiles[1].name = "underworlds_water_poison_source_animated.png"
|
||||
minetest.register_node("underworlds:water_poison_source", newnode)
|
||||
|
||||
newnode = underworlds_mod.clone_node("default:water_flowing")
|
||||
newnode.description = "Poisonous Water"
|
||||
newnode.groups.poison = 3
|
||||
newnode.light_source = 6
|
||||
newnode.liquid_alternative_flowing = "underworlds:water_poison_flowing"
|
||||
newnode.liquid_alternative_source = "underworlds:water_poison_source"
|
||||
newnode.post_effect_color = {a = 103, r = 108, g = 128, b = 64}
|
||||
newnode.special_tiles[1].name = "underworlds_water_poison_flowing_animated.png"
|
||||
newnode.tiles[1] = "underworlds_water_poison.png"
|
||||
minetest.register_node("underworlds:water_poison_flowing", newnode)
|
||||
|
||||
if not minetest.registered_items['fun_caves:thin_ice'] then
|
||||
-- ice, thin -- transparent
|
||||
minetest.register_node("underworlds:thin_ice", {
|
||||
description = "Thin Ice",
|
||||
tiles = {"caverealms_thin_ice.png"},
|
||||
is_ground_content = true,
|
||||
groups = {cracky=3},
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
use_texture_alpha = true,
|
||||
light_source = 1,
|
||||
drawtype = "glasslike",
|
||||
sunlight_propagates = true,
|
||||
freezemelt = "default:water_source",
|
||||
paramtype = "light",
|
||||
})
|
||||
end
|
||||
|
||||
-- Iron, hot
|
||||
newnode = underworlds_mod.clone_node("default:steelblock")
|
||||
newnode.description = "Hot Iron Block"
|
||||
newnode.tiles = {"default_steel_block.png^[colorize:#FF3000:150"}
|
||||
newnode.groups.surface_hot=3
|
||||
newnode.light_source = 3
|
||||
minetest.register_node("underworlds:hot_iron", newnode)
|
||||
|
||||
-- Brass, hot
|
||||
newnode = underworlds_mod.clone_node("default:steelblock")
|
||||
newnode.description = "Hot Brass Block"
|
||||
newnode.tiles = {"default_steel_block.png^[colorize:#FFBF00:150"}
|
||||
newnode.groups.surface_hot=3
|
||||
newnode.light_source = 2
|
||||
minetest.register_node("underworlds:hot_brass", newnode)
|
||||
|
||||
-- Polluted dirt
|
||||
newnode = underworlds_mod.clone_node("default:dirt")
|
||||
newnode.description = "Polluted Dirt"
|
||||
newnode.tiles = {"default_dirt.png^[colorize:#100020:100"}
|
||||
newnode.groups.soil = 0
|
||||
minetest.register_node("underworlds:polluted_dirt", newnode)
|
||||
|
||||
-- Bare branches
|
||||
minetest.register_node('underworlds:sticks_default', {
|
||||
description = 'Sticks',
|
||||
drawtype = 'allfaces_optional',
|
||||
waving = 1,
|
||||
visual_scale = 1.3,
|
||||
tiles = {'underworlds_dry_twigs.png'},
|
||||
paramtype = 'light',
|
||||
is_ground_content = false,
|
||||
drop = 'default:stick 2',
|
||||
groups = {snappy = 3, leafdecay = 3, flammable = 2, leaves = 1},
|
||||
})
|
||||
|
||||
-- Black leaves
|
||||
newnode = underworlds_mod.clone_node("default:leaves")
|
||||
newnode.description = "Blackened Leaves"
|
||||
newnode.tiles = {"default_leaves.png^[colorize:#100020:200"}
|
||||
newnode.special_tiles = {"default_leaves_simple.png^[colorize:#100020:200"}
|
||||
newnode.groups = {snappy = 3, flammable = 2}
|
||||
minetest.register_node("underworlds:leaves_black", newnode)
|
||||
|
||||
|
||||
underworlds_mod.schematics = {}
|
||||
do
|
||||
local w, h, d = 5, 8, 5
|
||||
local s = underworlds_mod.schematic_array(w, h, d)
|
||||
|
||||
for y = 0, math.floor(h/2)-1 do
|
||||
s.data[2*d*h + y*d + 2 + 1].name = 'default:tree'
|
||||
s.data[2*d*h + y*d + 2 + 1].param1 = 255
|
||||
end
|
||||
|
||||
for z = 0, d-1 do
|
||||
for y = math.floor(h/2), h-1 do
|
||||
for x = 0, w-1 do
|
||||
if y < h - 1 or (x ~= 0 and x ~= w-1 and z ~= 0 and z ~= d-1) then
|
||||
if math.random(2) == 1 then
|
||||
s.data[z*d*h + y*d + x + 1].name = 'underworlds:leaves_black'
|
||||
else
|
||||
s.data[z*d*h + y*d + x + 1].name = 'underworlds:sticks_default'
|
||||
end
|
||||
|
||||
if y == h-1 or x == 0 or x == w-1 or z == 0 or z == d-1 then
|
||||
s.data[z*d*h + y*d + x + 1].param1 = 150
|
||||
else
|
||||
s.data[z*d*h + y*d + x + 1].param1 = 225
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for z = math.floor(d/2)-1, math.floor(d/2)+1, 2 do
|
||||
for x = math.floor(w/2)-1, math.floor(w/2)+1, 2 do
|
||||
s.data[z*d*h + math.floor(h/2)*d + x + 1].name = 'default:tree'
|
||||
s.data[z*d*h + math.floor(h/2)*d + x + 1].param1 = 150
|
||||
end
|
||||
end
|
||||
|
||||
for y = 0, h-1 do
|
||||
if y / 3 == math.floor(y / 3) then
|
||||
s.yslice_prob[#s.yslice_prob+1] = {ypos=y,prob=170}
|
||||
end
|
||||
end
|
||||
|
||||
underworlds_mod.schematics['decaying_tree'] = s
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
default
|
|
@ -0,0 +1,194 @@
|
|||
-- Underworlds init.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)
|
||||
|
||||
|
||||
underworlds_mod = {}
|
||||
underworlds_mod.version = "1.0"
|
||||
underworlds_mod.path = minetest.get_modpath(minetest.get_current_modname())
|
||||
underworlds_mod.world = minetest.get_worldpath()
|
||||
|
||||
|
||||
underworlds_mod.underzones = {
|
||||
Caina = {
|
||||
name = 'Caina',
|
||||
ceiling_node = 'default:ice',
|
||||
column_node = 'default:ice',
|
||||
column_node_rare = 'underworlds:thin_ice',
|
||||
floor_node = 'default:ice',
|
||||
high_chunk = -2,
|
||||
low_chunk = -4,
|
||||
regular_columns = false,
|
||||
stalactite = 'underworlds:icicle_down',
|
||||
stalactite_chance = 12,
|
||||
stone_depth = 2,
|
||||
vary = true,
|
||||
},
|
||||
Phlegethos = {
|
||||
name = 'Phlegethos',
|
||||
ceiling_node = 'underworlds:black_sand',
|
||||
column_node = 'default:stone',
|
||||
column_node_rare = 'underworlds:hot_stone',
|
||||
floor_node = 'underworlds:hot_cobble',
|
||||
fluid = 'default:lava_source',
|
||||
fluid_chance = 1200,
|
||||
high_chunk = -6,
|
||||
low_chunk = -8,
|
||||
lake = 'default:lava_source',
|
||||
lake_level = 5,
|
||||
regular_columns = false,
|
||||
stone_depth = 1,
|
||||
vary = true,
|
||||
},
|
||||
Dis = {
|
||||
name = 'Dis',
|
||||
ceiling_height = 2,
|
||||
ceiling_node = 'underworlds:hot_brass',
|
||||
city = true,
|
||||
column_node = 'default:steelblock',
|
||||
floor_depth = 10,
|
||||
floor_node = 'underworlds:hot_brass',
|
||||
high_chunk = -10,
|
||||
low_chunk = -10,
|
||||
regular_columns = true,
|
||||
stone_depth = 1,
|
||||
vary = false,
|
||||
},
|
||||
Minauros = {
|
||||
name = 'Minauros',
|
||||
ceiling_node = 'underworlds:black_sand',
|
||||
column_node = 'underworlds:polluted_dirt',
|
||||
column_node_rare = 'underworlds:glowing_fungal_stone',
|
||||
floor_node = 'underworlds:polluted_dirt',
|
||||
fluid = 'underworlds:water_poison_source',
|
||||
fluid_chance = 2000,
|
||||
high_chunk = -12,
|
||||
lake = 'underworlds:water_poison_source',
|
||||
lake_level = 10,
|
||||
low_chunk = -14,
|
||||
regular_columns = false,
|
||||
stone_depth = 2,
|
||||
vary = true,
|
||||
},
|
||||
Styx = {
|
||||
name = 'Styx',
|
||||
ceiling_node = 'default:dirt',
|
||||
floor_node = 'default:dirt',
|
||||
high_chunk = -16,
|
||||
low_chunk = -20,
|
||||
regular_columns = false,
|
||||
stone_depth = 2,
|
||||
sea_chunk = -16,
|
||||
vary = true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, uz in pairs(underworlds_mod.underzones) do
|
||||
if uz.low_chunk and uz.high_chunk then
|
||||
uz.lower_bound = uz.low_chunk * 80 - 32
|
||||
uz.floor = uz.lower_bound + (uz.floor_depth or 20)
|
||||
uz.upper_bound = uz.high_chunk * 80 + 47
|
||||
uz.ceiling = uz.upper_bound - (uz.ceiling_height or 20)
|
||||
end
|
||||
if uz.sea_chunk then
|
||||
uz.sealevel = uz.sea_chunk * 80
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function underworlds_mod.clone_node(name)
|
||||
if not (name and type(name) == 'string') then
|
||||
return
|
||||
end
|
||||
|
||||
local node = minetest.registered_nodes[name]
|
||||
local node2 = table.copy(node)
|
||||
return node2
|
||||
end
|
||||
|
||||
|
||||
underworlds_mod.place_schematic = function(minp, maxp, data, p2data, area, node, pos, schem, center)
|
||||
if not (minp and maxp and data and p2data and area and node and pos and schem and type(data) == 'table' and type(p2data) == 'table' and type(schem) == 'table') then
|
||||
return
|
||||
end
|
||||
|
||||
local rot = math.random(4) - 1
|
||||
local yslice = {}
|
||||
if schem.yslice_prob then
|
||||
for _, ys in pairs(schem.yslice_prob) do
|
||||
yslice[ys.ypos] = ys.prob
|
||||
end
|
||||
end
|
||||
|
||||
if center then
|
||||
pos.x = pos.x - math.floor(schem.size.x / 2)
|
||||
pos.z = pos.z - math.floor(schem.size.z / 2)
|
||||
end
|
||||
|
||||
for z1 = 0, schem.size.z - 1 do
|
||||
for x1 = 0, schem.size.x - 1 do
|
||||
local x, z
|
||||
if rot == 0 then
|
||||
x, z = x1, z1
|
||||
elseif rot == 1 then
|
||||
x, z = schem.size.z - z1 - 1, x1
|
||||
elseif rot == 2 then
|
||||
x, z = schem.size.x - x1 - 1, schem.size.z - z1 - 1
|
||||
elseif rot == 3 then
|
||||
x, z = z1, schem.size.x - x1 - 1
|
||||
end
|
||||
local dz = pos.z - minp.z + z
|
||||
local dx = pos.x - minp.x + x
|
||||
if pos.x + x > minp.x and pos.x + x < maxp.x and pos.z + z > minp.z and pos.z + z < maxp.z then
|
||||
local ivm = area:index(pos.x + x, pos.y, pos.z + z)
|
||||
local isch = z1 * schem.size.y * schem.size.x + x1 + 1
|
||||
local math_random = math.random
|
||||
for y = 0, schem.size.y - 1 do
|
||||
local dy = pos.y - minp.y + y
|
||||
if yslice[y] or 255 >= math_random(255) then
|
||||
local prob = schem.data[isch].prob or schem.data[isch].param1 or 255
|
||||
if prob >= math_random(255) and schem.data[isch].name ~= "air" then
|
||||
data[ivm] = node[schem.data[isch].name]
|
||||
end
|
||||
local param2 = schem.data[isch].param2 or 0
|
||||
p2data[ivm] = param2
|
||||
end
|
||||
|
||||
ivm = ivm + area.ystride
|
||||
isch = isch + schem.size.x
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Create and initialize a table for a schematic.
|
||||
function underworlds_mod.schematic_array(width, height, depth)
|
||||
if not (width and height and depth and type(width) == 'number' and type(height) == 'number' and type(depth) == 'number') then
|
||||
return
|
||||
end
|
||||
|
||||
-- Dimensions of data array.
|
||||
local s = {size={x=width, y=height, z=depth}}
|
||||
s.data = {}
|
||||
|
||||
for z = 0,depth-1 do
|
||||
for y = 0,height-1 do
|
||||
for x = 0,width-1 do
|
||||
local i = z*width*height + y*width + x + 1
|
||||
s.data[i] = {}
|
||||
s.data[i].name = "air"
|
||||
s.data[i].param1 = 000
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
s.yslice_prob = {}
|
||||
|
||||
return s
|
||||
end
|
||||
|
||||
|
||||
dofile(underworlds_mod.path .. "/deco.lua")
|
||||
dofile(underworlds_mod.path .. "/mapgen.lua")
|
|
@ -0,0 +1,102 @@
|
|||
-- Underworlds 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 = true
|
||||
local max_depth = 31000
|
||||
local seed_noise = {offset = 0, scale = 32768, seed = 5202, spread = {x = 80, y = 80, z = 80}, octaves = 2, persist = 0.4, lacunarity = 2}
|
||||
|
||||
|
||||
-- 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 = {}
|
||||
local p2data = {}
|
||||
|
||||
|
||||
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)
|
||||
p2data = vm:get_param2_data()
|
||||
local heightmap
|
||||
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local csize = vector.add(vector.subtract(maxp, minp), 1)
|
||||
|
||||
-- use the same seed (based on perlin noise).
|
||||
do
|
||||
local seed = minetest.get_perlin(seed_noise):get2d({x=minp.x, y=minp.z})
|
||||
if not (seed and type(seed) == 'number') then
|
||||
return
|
||||
end
|
||||
|
||||
math.randomseed(seed)
|
||||
end
|
||||
|
||||
local write = false
|
||||
if not underworlds_mod.underzones then
|
||||
return
|
||||
end
|
||||
|
||||
do
|
||||
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
|
||||
write = underworlds_mod.undergen(minp, maxp, data, p2data, area, node, uz)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if write then
|
||||
vm:set_data(data)
|
||||
vm:set_param2_data(p2data)
|
||||
|
||||
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 underworlds_mod.path then
|
||||
dofile(underworlds_mod.path .. "/undergen.lua")
|
||||
end
|
||||
|
||||
|
||||
local function pgenerate(...)
|
||||
local status, err = pcall(generate, ...)
|
||||
--local status, err = true
|
||||
--generate(...)
|
||||
if not status then
|
||||
print('Treegen: Could not generate terrain:')
|
||||
print(dump(err))
|
||||
collectgarbage("collect")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
minetest.register_on_generated(pgenerate)
|
After Width: | Height: | Size: 83 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 431 B |
After Width: | Height: | Size: 679 B |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 321 B |
After Width: | Height: | Size: 818 B |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 618 B |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 5.0 KiB |
|
@ -0,0 +1,245 @@
|
|||
-- Underworlds undergen.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)
|
||||
|
||||
|
||||
underworlds_mod.cave_width = 0.05 -- figurative width
|
||||
local max_depth = 31000
|
||||
|
||||
|
||||
local terrain_noise = {offset = 15, scale = 10, seed = 3721, spread = {x = 40, y = 40, z = 40}, octaves = 3, persist = 1, lacunarity = 2}
|
||||
|
||||
|
||||
underworlds_mod.undergen = function(minp, maxp, data, p2data, area, node, underzone)
|
||||
if not (minp and maxp and data and area and node and type(data) == 'table' and underzone and underworlds_mod.underzones) then
|
||||
return
|
||||
end
|
||||
|
||||
local csize = vector.add(vector.subtract(maxp, minp), 1)
|
||||
local map_max = {x = csize.x, y = csize.y + 2, z = csize.z}
|
||||
local map_min = {x = minp.x, y = minp.y - 1, z = minp.z}
|
||||
|
||||
local terrain = minetest.get_perlin_map(terrain_noise, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp.x, y=minp.z})
|
||||
if not terrain then
|
||||
return
|
||||
end
|
||||
|
||||
local math_random = math.random
|
||||
local dis_map = {}
|
||||
if underzone and underzone.city then
|
||||
for i = 0, 10, 2 do
|
||||
dis_map[i] = {}
|
||||
for j = 0, 10, 2 do
|
||||
dis_map[i][j] = math_random(6)
|
||||
if dis_map[i][j] == 6 then
|
||||
dis_map[i][j] = 5 + math_random(10)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local write = false
|
||||
|
||||
local index = 0
|
||||
local index3d = 0
|
||||
local cave_width = underworlds_mod.cave_width
|
||||
local styx_sea_level = underworlds_mod.underzones['Styx'].sealevel
|
||||
for z = minp.z, maxp.z do
|
||||
for x = minp.x, maxp.x do
|
||||
index = index + 1
|
||||
index3d = (z - minp.z) * (csize.y + 2) * csize.x + (x - minp.x) + 1
|
||||
local ivm = area:index(x, minp.y-1, z)
|
||||
|
||||
local column = 0
|
||||
if terrain[index] < 30 then
|
||||
column = 1
|
||||
elseif terrain[index] < 35 then
|
||||
column = 2
|
||||
end
|
||||
|
||||
for y = minp.y-1, maxp.y+1 do
|
||||
if underzone.regular_columns and (x - minp.x) < 8 and (z - minp.z) < 8 then
|
||||
data[ivm] = node[underzone.column_node]
|
||||
write = true
|
||||
elseif underzone.column_node and not underzone.regular_columns and column == 2 then
|
||||
if underzone.column_node_rare and math.random(70) == 1 then
|
||||
data[ivm] = node[underzone.column_node_rare]
|
||||
else
|
||||
data[ivm] = node[underzone.column_node]
|
||||
end
|
||||
write = true
|
||||
elseif (y < underzone.ceiling - (underzone.vary and terrain[index] or 0) and y > underzone.floor + (underzone.vary and terrain[index] or 0)) then
|
||||
if underzone.sealevel and y <= underzone.sealevel then
|
||||
data[ivm] = node["default:water_source"]
|
||||
elseif underzone.lake and y < underzone.floor + underzone.lake_level then
|
||||
data[ivm] = node[underzone.lake]
|
||||
else
|
||||
data[ivm] = node["air"]
|
||||
end
|
||||
write = true
|
||||
elseif y < underzone.ceiling + 10 - (underzone.vary and terrain[index] or 0) then
|
||||
data[ivm] = node["default:stone"]
|
||||
elseif y > underzone.floor - 10 + (underzone.vary and terrain[index] or 0) then
|
||||
data[ivm] = node["default:stone"]
|
||||
end
|
||||
|
||||
ivm = ivm + area.ystride
|
||||
index3d = index3d + csize.x
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local math_floor = math.floor
|
||||
|
||||
for z = minp.z, maxp.z do
|
||||
for x = minp.x, maxp.x do
|
||||
index = index + 1
|
||||
index3d = (z - minp.z) * (csize.y + 2) * csize.x + (x - minp.x) + 1
|
||||
local ivm = area:index(x, minp.y-1, z)
|
||||
|
||||
--local column = 0
|
||||
--if terrain[index] < 30 then
|
||||
-- column = 1
|
||||
--elseif terrain[index] < 35 then
|
||||
-- column = 2
|
||||
--end
|
||||
|
||||
for y = minp.y-1, maxp.y+1 do
|
||||
local node_below
|
||||
if y > minp.y then
|
||||
node_below = data[ivm - area.ystride]
|
||||
end
|
||||
local node_above = data[ivm + area.ystride]
|
||||
|
||||
for deco_non_loop = 1, 1 do
|
||||
if data[ivm] == node["default:stone"] then
|
||||
if node_above == node["air"] and underzone.dirt and math_random(underzone.dirt_chance) == 1 then
|
||||
data[ivm] = node[underzone.dirt]
|
||||
write = true
|
||||
break
|
||||
end
|
||||
|
||||
local air_above = false
|
||||
for i = 1, underzone.stone_depth do
|
||||
if data[ivm + area.ystride * i] == node["air"] or (y < styx_sea_level and data[ivm + area.ystride * i] == node["default:water_source"]) then
|
||||
air_above = true
|
||||
end
|
||||
end
|
||||
|
||||
if air_above then
|
||||
if underzone.deco and math_random(underzone.deco_chance) == 1 then
|
||||
data[ivm] = node[underzone.deco]
|
||||
write = true
|
||||
break
|
||||
else
|
||||
data[ivm] = node[underzone.floor_node]
|
||||
write = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local air_below = false
|
||||
for i = 1, underzone.stone_depth do
|
||||
if data[ivm - area.ystride * i] == node["air"] then
|
||||
air_below = true
|
||||
end
|
||||
end
|
||||
|
||||
if not air_above and underzone.floor_node == "default:sand" then
|
||||
data[ivm] = node["default:sandstone"]
|
||||
write = true
|
||||
break
|
||||
end
|
||||
|
||||
if air_below then
|
||||
if underzone.deco and math_random(underzone.deco_chance) == 1 then
|
||||
data[ivm] = node[underzone.deco]
|
||||
write = true
|
||||
break
|
||||
else
|
||||
data[ivm] = node[underzone.ceiling_node]
|
||||
write = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- smallest city generator ever
|
||||
if underzone.city and data[ivm] == node['air'] and math_floor((x - minp.x) / 8) % 2 == 0 and math_floor((z - minp.z) / 8) % 2 == 0 and y - underzone.floor < dis_map[math_floor((x - minp.x) / 8)][math_floor((z - minp.z) / 8)] * 4 + 1 and y - underzone.floor >= 0 then
|
||||
local dx = (x - minp.x) % 16
|
||||
local dy = y - underzone.floor + 1
|
||||
local dz = (z - minp.z) % 16
|
||||
if dx == 1 and dz == 1 then
|
||||
data[ivm] = node["default:ladder_steel"]
|
||||
p2data[ivm] = 3
|
||||
--write_p2 = true
|
||||
elseif ((dx == 0 or dx == 7) and (dz % 3 ~= 2 or dy % 4 == 0)) or ((dz == 0 or dz == 7) and (dx % 3 ~= 2 or dy % 4 == 0)) then
|
||||
data[ivm] = node["underworlds:hot_iron"]
|
||||
elseif dy % 4 == 0 then
|
||||
data[ivm] = node["underworlds:hot_brass"]
|
||||
end
|
||||
write = true
|
||||
break
|
||||
end
|
||||
|
||||
if data[ivm] == node["air"] and y < maxp.y then
|
||||
-- hanging down
|
||||
-- stone hasn't yet been changed
|
||||
if underzone.stalactite and node_above == node["default:stone"] and math_random(underzone.stalactite_chance) == 1 then
|
||||
data[ivm] = node[underzone.stalactite]
|
||||
write = true
|
||||
break
|
||||
end
|
||||
|
||||
-- fluids
|
||||
if y > minp.y and underzone.fluid and node_below == node[underzone.floor_node] and math_random(underzone.fluid_chance) == 1 then
|
||||
data[ivm] = node[underzone.fluid]
|
||||
write = true
|
||||
break
|
||||
|
||||
-- standing up
|
||||
elseif node_below == node[underzone.floor_node] and underzone.stalagmite and math_random(underzone.stalagmite_chance) == 1 then
|
||||
if type(underzone.stalagmite) == 'table' then
|
||||
data[ivm] = node[underzone.stalagmite[math_random(#underzone.stalagmite)]]
|
||||
else
|
||||
data[ivm] = node[underzone.stalagmite]
|
||||
end
|
||||
write = true
|
||||
break
|
||||
|
||||
-- vegetation
|
||||
elseif node_below == node["underworlds:polluted_dirt"] then
|
||||
if math_random(10) == 1 then
|
||||
data[ivm] = node["default:dry_shrub"]
|
||||
write = true
|
||||
break
|
||||
elseif math_random(50) == 1 then
|
||||
local air_count = 0
|
||||
local pos = {}
|
||||
local j
|
||||
for i = 1, 9 do
|
||||
j = ivm + area.ystride * i
|
||||
if j <= #data and data[j] == node["air"] then
|
||||
air_count = air_count + 1
|
||||
end
|
||||
end
|
||||
if air_count > 6 then
|
||||
pos.x = x
|
||||
pos.y = y
|
||||
pos.z = z
|
||||
underworlds_mod.place_schematic(minp, maxp, data, p2data, area, node, pos, underworlds_mod.schematics['decaying_tree'], true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ivm = ivm + area.ystride
|
||||
index3d = index3d + csize.x
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return write
|
||||
end
|