Initial commit

master
Duane Robertson 2017-01-29 04:54:50 -06:00
parent d809ac4a7b
commit 25ca1fb5f9
21 changed files with 826 additions and 0 deletions

16
README.md Normal file
View File

@ -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

267
deco.lua Normal file
View File

@ -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

1
depends.txt Normal file
View File

@ -0,0 +1 @@
default

194
init.lua Normal file
View File

@ -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")

102
mapgen.lua Normal file
View File

@ -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)

1
mod.conf Normal file
View File

@ -0,0 +1 @@
name = underworlds

BIN
screenshot-2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

BIN
screenshot-4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

BIN
screenshot-5.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 679 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 818 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

245
undergen.lua Normal file
View File

@ -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