b0fc53089b
Add the new DeepRealms, inspired by Zeno's fork, and add the new salt crystal, obsidian, and coal dust biomes.
609 lines
16 KiB
Lua
609 lines
16 KiB
Lua
--CaveRealms functions.lua
|
|
|
|
--FUNCTIONS--
|
|
|
|
local H_LAG = caverealms.config.h_lag --15 --max height for stalagmites
|
|
local H_LAC = caverealms.config.h_lac --20 --...stalactites
|
|
local H_CRY = caverealms.config.h_cry --9 --max height of glow crystals
|
|
local H_CLAC = caverealms.config.h_clac --13 --max height of glow crystal stalactites
|
|
|
|
function caverealms:above_solid(x,y,z,area,data)
|
|
local c_air = minetest.get_content_id("air")
|
|
local ai = area:index(x,y+1,z-3)
|
|
if data[ai] == c_air then
|
|
return false
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
function caverealms:below_solid(x,y,z,area,data)
|
|
local c_air = minetest.get_content_id("air")
|
|
local ai = area:index(x,y-1,z-3)
|
|
if data[ai] == c_air then
|
|
return false
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
|
|
--stalagmite spawner
|
|
function caverealms:stalagmite(x,y,z, area, data)
|
|
|
|
if not caverealms:below_solid(x,y,z,area,data) then
|
|
return
|
|
end
|
|
|
|
--contest ids
|
|
local c_stone = minetest.get_content_id("default:stone")
|
|
|
|
local top = math.random(6,H_LAG) --grab a random height for the stalagmite
|
|
for j = 0, top do --y
|
|
for k = -3, 3 do
|
|
for l = -3, 3 do
|
|
if j == 0 then
|
|
if k*k + l*l <= 9 then
|
|
local vi = area:index(x+k, y+j, z+l-3)
|
|
data[vi] = c_stone
|
|
end
|
|
elseif j <= top/5 then
|
|
if k*k + l*l <= 4 then
|
|
local vi = area:index(x+k, y+j, z+l-3)
|
|
data[vi] = c_stone
|
|
end
|
|
elseif j <= top/5 * 3 then
|
|
if k*k + l*l <= 1 then
|
|
local vi = area:index(x+k, y+j, z+l-3)
|
|
data[vi] = c_stone
|
|
end
|
|
else
|
|
local vi = area:index(x, y+j, z-3)
|
|
data[vi] = c_stone
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--stalactite spawner
|
|
function caverealms:stalactite(x,y,z, area, data)
|
|
|
|
if not caverealms:above_solid(x,y,z,area,data) then
|
|
return
|
|
end
|
|
|
|
--contest ids
|
|
local c_stone = minetest.get_content_id("default:stone")--("caverealms:limestone")
|
|
|
|
local bot = math.random(-H_LAC, -6) --grab a random height for the stalagmite
|
|
for j = bot, 0 do --y
|
|
for k = -3, 3 do
|
|
for l = -3, 3 do
|
|
if j >= -1 then
|
|
if k*k + l*l <= 9 then
|
|
local vi = area:index(x+k, y+j, z+l-3)
|
|
data[vi] = c_stone
|
|
end
|
|
elseif j >= bot/5 then
|
|
if k*k + l*l <= 4 then
|
|
local vi = area:index(x+k, y+j, z+l-3)
|
|
data[vi] = c_stone
|
|
end
|
|
elseif j >= bot/5 * 3 then
|
|
if k*k + l*l <= 1 then
|
|
local vi = area:index(x+k, y+j, z+l-3)
|
|
data[vi] = c_stone
|
|
end
|
|
else
|
|
local vi = area:index(x, y+j, z-3)
|
|
data[vi] = c_stone
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--glowing crystal stalagmite spawner
|
|
function caverealms:crystal_stalagmite(x,y,z, area, data, biome)
|
|
|
|
if not caverealms:below_solid(x,y,z,area,data) then
|
|
return
|
|
end
|
|
|
|
--contest ids
|
|
local c_stone = minetest.get_content_id("default:stone")
|
|
local c_crystal = minetest.get_content_id("caverealms:glow_crystal")
|
|
local c_crystore = minetest.get_content_id("caverealms:glow_ore")
|
|
local c_emerald = minetest.get_content_id("caverealms:glow_emerald")
|
|
local c_emore = minetest.get_content_id("caverealms:glow_emerald_ore")
|
|
local c_mesecry = minetest.get_content_id("caverealms:glow_mese")
|
|
local c_meseore = minetest.get_content_id("default:stone_with_mese")
|
|
local c_ruby = minetest.get_content_id("caverealms:glow_ruby")
|
|
local c_rubore = minetest.get_content_id("caverealms:glow_ruby_ore")
|
|
local c_ameth = minetest.get_content_id("caverealms:glow_amethyst")
|
|
local c_amethore = minetest.get_content_id("caverealms:glow_amethyst_ore")
|
|
local c_ice = minetest.get_content_id("default:ice")
|
|
local c_thinice = minetest.get_content_id("caverealms:thin_ice")
|
|
|
|
--for randomness
|
|
local mode = 1
|
|
if math.random(15) == 1 then
|
|
mode = 2
|
|
end
|
|
if biome == 3 then
|
|
if math.random(25) == 1 then
|
|
mode = 2
|
|
else
|
|
mode = 1
|
|
end
|
|
end
|
|
if biome == 4 or biome == 5 then
|
|
if math.random(3) == 1 then
|
|
mode = 2
|
|
end
|
|
end
|
|
|
|
local stalids = {
|
|
{ {c_crystore, c_crystal}, {c_emore, c_emerald} },
|
|
{ {c_emore, c_emerald}, {c_crystore, c_crystal} },
|
|
{ {c_emore, c_emerald}, {c_meseore, c_mesecry} },
|
|
{ {c_ice, c_thinice}, {c_crystore, c_crystal}},
|
|
{ {c_ice, c_thinice}, {c_crystore, c_crystal}},
|
|
{ {c_rubore, c_ruby}, {c_meseore, c_mesecry}},
|
|
{ {c_crystore, c_crystal}, {c_rubore, c_ruby} },
|
|
{ {c_rubore, c_ruby}, {c_emore, c_emerald}},
|
|
{ {c_amethore, c_ameth}, {c_meseore, c_mesecry} },
|
|
}
|
|
|
|
local nid_a
|
|
local nid_b
|
|
local nid_s = c_stone --stone base, will be rewritten to ice in certain biomes
|
|
|
|
if biome > 3 and biome < 6 then
|
|
if mode == 1 then
|
|
nid_a = c_ice
|
|
nid_b = c_thinice
|
|
nid_s = c_ice
|
|
else
|
|
nid_a = c_crystore
|
|
nid_b = c_crystal
|
|
end
|
|
elseif mode == 1 then
|
|
nid_a = stalids[biome][1][1]
|
|
nid_b = stalids[biome][1][2]
|
|
else
|
|
nid_a = stalids[biome][2][1]
|
|
nid_b = stalids[biome][2][2]
|
|
end
|
|
|
|
local top = math.random(5,H_CRY) --grab a random height for the stalagmite
|
|
for j = 0, top do --y
|
|
for k = -3, 3 do
|
|
for l = -3, 3 do
|
|
if j == 0 then
|
|
if k*k + l*l <= 9 then
|
|
local vi = area:index(x+k, y+j, z+l-3)
|
|
data[vi] = nid_s
|
|
end
|
|
elseif j <= top/5 then
|
|
if k*k + l*l <= 4 then
|
|
local vi = area:index(x+k, y+j, z+l-3)
|
|
data[vi] = nid_a
|
|
end
|
|
elseif j <= top/5 * 3 then
|
|
if k*k + l*l <= 1 then
|
|
local vi = area:index(x+k, y+j, z+l-3)
|
|
data[vi] = nid_b
|
|
end
|
|
else
|
|
local vi = area:index(x, y+j, z-3)
|
|
data[vi] = nid_b
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--crystal stalactite spawner
|
|
function caverealms:crystal_stalactite(x,y,z, area, data, biome)
|
|
|
|
if not caverealms:above_solid(x,y,z,area,data) then
|
|
return
|
|
end
|
|
|
|
--contest ids
|
|
local c_stone = minetest.get_content_id("default:stone")
|
|
local c_crystore = minetest.get_content_id("caverealms:glow_ore")
|
|
local c_crystal = minetest.get_content_id("caverealms:glow_crystal")
|
|
local c_emerald = minetest.get_content_id("caverealms:glow_emerald")
|
|
local c_emore = minetest.get_content_id("caverealms:glow_emerald_ore")
|
|
local c_mesecry = minetest.get_content_id("caverealms:glow_mese")
|
|
local c_meseore = minetest.get_content_id("default:stone_with_mese")
|
|
local c_ruby = minetest.get_content_id("caverealms:glow_ruby")
|
|
local c_rubore = minetest.get_content_id("caverealms:glow_ruby_ore")
|
|
local c_ameth = minetest.get_content_id("caverealms:glow_amethyst")
|
|
local c_amethore = minetest.get_content_id("caverealms:glow_amethyst_ore")
|
|
local c_ice = minetest.get_content_id("default:ice")
|
|
local c_thinice = minetest.get_content_id("caverealms:hanging_thin_ice")
|
|
|
|
--for randomness
|
|
local mode = 1
|
|
if math.random(15) == 1 then
|
|
mode = 2
|
|
end
|
|
if biome == 3 then
|
|
if math.random(25) == 1 then
|
|
mode = 2
|
|
else
|
|
mode = 1
|
|
end
|
|
end
|
|
if biome == 4 or biome == 5 then
|
|
if math.random(3) == 1 then
|
|
mode = 2
|
|
end
|
|
end
|
|
|
|
local stalids = {
|
|
{ {c_crystore, c_crystal}, {c_emore, c_emerald} },
|
|
{ {c_emore, c_emerald}, {c_crystore, c_crystal} },
|
|
{ {c_emore, c_emerald}, {c_meseore, c_mesecry} },
|
|
{ {c_ice, c_thinice}, {c_crystore, c_crystal}},
|
|
{ {c_ice, c_thinice}, {c_crystore, c_crystal}},
|
|
{ {c_rubore, c_ruby}, {c_meseore, c_mesecry}},
|
|
{ {c_crystore, c_crystal}, {c_rubore, c_ruby} },
|
|
{ {c_rubore, c_ruby}, {c_emore, c_emerald}},
|
|
{ {c_amethore, c_ameth}, {c_meseore, c_mesecry} },
|
|
}
|
|
|
|
local nid_a
|
|
local nid_b
|
|
local nid_s = c_stone --stone base, will be rewritten to ice in certain biomes
|
|
|
|
if biome > 3 and biome < 6 then
|
|
if mode == 1 then
|
|
nid_a = c_ice
|
|
nid_b = c_thinice
|
|
nid_s = c_ice
|
|
else
|
|
nid_a = c_crystore
|
|
nid_b = c_crystal
|
|
end
|
|
elseif mode == 1 then
|
|
nid_a = stalids[biome][1][1]
|
|
nid_b = stalids[biome][1][2]
|
|
else
|
|
nid_a = stalids[biome][2][1]
|
|
nid_b = stalids[biome][2][2]
|
|
end
|
|
|
|
local bot = math.random(-H_CLAC, -6) --grab a random height for the stalagmite
|
|
for j = bot, 0 do --y
|
|
for k = -3, 3 do
|
|
for l = -3, 3 do
|
|
if j >= -1 then
|
|
if k*k + l*l <= 9 then
|
|
local vi = area:index(x+k, y+j, z+l-3)
|
|
data[vi] = nid_s
|
|
end
|
|
elseif j >= bot/5 then
|
|
if k*k + l*l <= 4 then
|
|
local vi = area:index(x+k, y+j, z+l-3)
|
|
data[vi] = nid_a
|
|
end
|
|
elseif j >= bot/5 * 3 then
|
|
if k*k + l*l <= 1 then
|
|
local vi = area:index(x+k, y+j, z+l-3)
|
|
data[vi] = nid_b
|
|
end
|
|
else
|
|
local vi = area:index(x, y+j, z-3)
|
|
data[vi] = nid_b
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--glowing crystal stalagmite spawner
|
|
function caverealms:salt_stalagmite(x,y,z, area, data, biome)
|
|
|
|
if not caverealms:below_solid(x,y,z,area,data) then
|
|
return
|
|
end
|
|
|
|
--contest ids
|
|
local c_stone = minetest.get_content_id("default:stone")
|
|
local c_salt = minetest.get_content_id("caverealms:salt_crystal")
|
|
|
|
local scale = math.random(2, 4)
|
|
if scale == 2 then
|
|
for j = -3, 3 do
|
|
for k = -3, 3 do
|
|
local vi = area:index(x+j, y, z+k)
|
|
data[vi] = c_stone
|
|
if math.abs(j) ~= 3 and math.abs(k) ~= 3 then
|
|
local vi = area:index(x+j, y+1, z+k)
|
|
data[vi] = c_stone
|
|
end
|
|
end
|
|
end
|
|
else
|
|
for j = -4, 4 do
|
|
for k = -4, 4 do
|
|
local vi = area:index(x+j, y, z+k)
|
|
data[vi] = c_stone
|
|
if math.abs(j) ~= 4 and math.abs(k) ~= 4 then
|
|
local vi = area:index(x+j, y+1, z+k)
|
|
data[vi] = c_stone
|
|
end
|
|
end
|
|
end
|
|
end
|
|
for j = 2, scale + 2 do --y
|
|
for k = -2, scale - 2 do
|
|
for l = -2, scale - 2 do
|
|
local vi = area:index(x+k, y+j, z+l)
|
|
data[vi] = c_salt -- make cube
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--function to create giant 'shrooms
|
|
function caverealms:giant_shroom(x, y, z, area, data)
|
|
|
|
if not caverealms:below_solid(x,y,z,area,data) then
|
|
return
|
|
end
|
|
|
|
--as usual, grab the content ID's
|
|
local c_stem = minetest.get_content_id("caverealms:mushroom_stem")
|
|
local c_cap = minetest.get_content_id("caverealms:mushroom_cap")
|
|
local c_gills = minetest.get_content_id("caverealms:mushroom_gills")
|
|
|
|
z = z - 5
|
|
--cap
|
|
for k = -5, 5 do
|
|
for l = -5, 5 do
|
|
if k*k + l*l <= 25 then
|
|
local vi = area:index(x+k, y+5, z+l)
|
|
data[vi] = c_cap
|
|
end
|
|
if k*k + l*l <= 16 then
|
|
local vi = area:index(x+k, y+6, z+l)
|
|
data[vi] = c_cap
|
|
vi = area:index(x+k, y+5, z+l)
|
|
data[vi] = c_gills
|
|
end
|
|
if k*k + l*l <= 9 then
|
|
local vi = area:index(x+k, y+7, z+l)
|
|
data[vi] = c_cap
|
|
end
|
|
if k*k + l*l <= 4 then
|
|
local vi = area:index(x+k, y+8, z+l)
|
|
data[vi] = c_cap
|
|
end
|
|
end
|
|
end
|
|
--stem
|
|
for j = 0, 5 do
|
|
for k = -1,1 do
|
|
local vi = area:index(x+k, y+j, z)
|
|
data[vi] = c_stem
|
|
if k == 0 then
|
|
local ai = area:index(x, y+j, z+1)
|
|
data[ai] = c_stem
|
|
ai = area:index(x, y+j, z-1)
|
|
data[ai] = c_stem
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function caverealms:legacy_giant_shroom(x, y, z, area, data) --leftovers :P
|
|
--as usual, grab the content ID's
|
|
local c_stem = minetest.get_content_id("caverealms:mushroom_stem")
|
|
local c_cap = minetest.get_content_id("caverealms:mushroom_cap")
|
|
|
|
z = z - 4
|
|
--cap
|
|
for k = -4, 4 do
|
|
for l = -4, 4 do
|
|
if k*k + l*l <= 16 then
|
|
local vi = area:index(x+k, y+5, z+l)
|
|
data[vi] = c_cap
|
|
end
|
|
if k*k + l*l <= 9 then
|
|
local vi = area:index(x+k, y+4, z+l)
|
|
data[vi] = c_cap
|
|
vi = area:index(x+k, y+6, z+l)
|
|
data[vi] = c_cap
|
|
end
|
|
if k*k + l*l <= 4 then
|
|
local vi = area:index(x+k, y+7, z+l)
|
|
data[vi] = c_cap
|
|
end
|
|
end
|
|
end
|
|
--stem
|
|
for j = 0, 4 do
|
|
for k = -1,1 do
|
|
local vi = area:index(x+k, y+j, z)
|
|
data[vi] = c_stem
|
|
if k == 0 then
|
|
local ai = area:index(x, y+j, z+1)
|
|
data[ai] = c_stem
|
|
ai = area:index(x, y+j, z-1)
|
|
data[ai] = c_stem
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Experimental and very geometric function to create giant octagonal crystals in a variety of random directions
|
|
-- Uses calculations for points on a sphere, lines in geometric space
|
|
-- CURRENTLY USELESS, NOT LIKELY TO BE IMPLEMENTED SOON
|
|
function caverealms:giant_shroom(x, y, z, area, data)
|
|
--Grab content id's... diamond is a placeholder
|
|
local c_crys = minetest.get_content_id("default:diamondblock")
|
|
|
|
local MAX_LEN = 25 --placeholder for a config file constant
|
|
local MIN_LEN = 10 --ditto
|
|
|
|
local target = {x=0, y=MAX_LEN, z=0} -- 3D space coordinate of the crystal's endpoint
|
|
|
|
local length = math.random(MIN_LEN, MAX_LEN) --get a random length for the crystal
|
|
local dir1 = math.random(0, 359) -- Random direction in degrees around a circle
|
|
local dir2 = math.random(0, 180) -- Random direction in a semicircle, for 3D location
|
|
|
|
--OK, so now make a 3D point out of those spherical coordinates...
|
|
target.x = math.ceil(length * math.cos(dir1 * 3.14/180)) --Round it up to make sure it's a nice integer for the coordinate system
|
|
target.z = math.ceil(length * math.sin(dir1 * 3.14/180))
|
|
--Y is also simple, just use dir2. Note that, due to how these calculations are carried out, this is not a coordinate on a perfect sphere. This is OK for our purposes.
|
|
target.y = math.ceil(length * math.sin(dir2 * 3.14/180))
|
|
|
|
-- Now, determine if the crystal should go up or down, based on where it is
|
|
if (caverealms:above_solid(x,y,z,area,data)) then
|
|
target.y = target.y * -1
|
|
end
|
|
|
|
--Bring the coordinates near the area you're generating
|
|
target.x = target.x + x
|
|
target.y = target.y + y
|
|
target.z = target.z + z
|
|
|
|
|
|
end
|
|
|
|
local CAVESPAWN = caverealms.config.cavespawn --false by default. Change to true in order to spawn in the caves when joining as a new player or respawning after death
|
|
local spawned = false;
|
|
local ydepth = -960;
|
|
|
|
if (CAVESPAWN) then
|
|
minetest.register_on_newplayer(function(player)
|
|
while spawned ~= true do
|
|
player:setpos({x=0,y=ydepth,z=0})
|
|
--minetest.after(2, function(player, ydepth)
|
|
spawnplayer(player, ydepth)
|
|
--end, player, ydepth)
|
|
ydepth = ydepth - 80
|
|
end
|
|
end)
|
|
|
|
minetest.register_on_respawnplayer(function(player)
|
|
while spawned ~= true do
|
|
player:setpos({x=0,y=ydepth,z=0})
|
|
--minetest.after(2, function(player, ydepth)
|
|
spawnplayer(player, ydepth)
|
|
--end, player, ydepth)
|
|
ydepth = ydepth - 80
|
|
end
|
|
return true
|
|
end)
|
|
end
|
|
|
|
-- Spawn player underground
|
|
function spawnplayer(player, ydepth)
|
|
|
|
local xsp
|
|
local ysp
|
|
local zsp
|
|
-- 3D noise for caves
|
|
|
|
local np_cave = {
|
|
offset = 0,
|
|
scale = 1,
|
|
spread = {x=512, y=256, z=512}, -- squashed 2:1
|
|
seed = 59033,
|
|
octaves = 6,
|
|
persist = 0.63
|
|
}
|
|
|
|
-- 3D noise for wave
|
|
|
|
local np_wave = {
|
|
offset = 0,
|
|
scale = 1,
|
|
spread = {x=256, y=256, z=256},
|
|
seed = -400000000089,
|
|
octaves = 3,
|
|
persist = 0.67
|
|
}
|
|
|
|
local YMIN = caverealms.config.ymin -- Approximate realm limits.
|
|
local YMAX = caverealms.config.ymax
|
|
local TCAVE = caverealms.config.tcave --0.5 -- Cave threshold. 1 = small rare caves, 0.5 = 1/3rd ground volume, 0 = 1/2 ground volume
|
|
local BLEND = 128 -- Cave blend distance near YMIN, YMAX
|
|
|
|
local yblmin = YMIN + BLEND * 1.5
|
|
local yblmax = YMAX - BLEND * 1.5
|
|
|
|
for chunk = 1, 64 do
|
|
print ("[caverealms] searching for spawn "..chunk)
|
|
local x0 = 80 * math.random(-32, 32) - 32
|
|
local z0 = 80 * math.random(-32, 32) - 32
|
|
local y0 = ydepth-32
|
|
local x1 = x0 + 79
|
|
local z1 = z0 + 79
|
|
local y1 = ydepth+47
|
|
|
|
local sidelen = 80
|
|
local chulens = {x=sidelen, y=sidelen, z=sidelen}
|
|
local minposxyz = {x=x0, y=y0, z=z0}
|
|
local minposxz = {x=x0, y=z0}
|
|
|
|
local nvals_cave = minetest.get_perlin_map(np_cave, chulens):get3dMap_flat(minposxyz) --cave noise for structure
|
|
local nvals_wave = minetest.get_perlin_map(np_wave, chulens):get3dMap_flat(minposxyz) --wavy structure of cavern ceilings and floors
|
|
|
|
local nixz = 1
|
|
local nixyz = 1
|
|
for z = z0, z1 do
|
|
for y = y0, y1 do
|
|
for x = x0, x1 do
|
|
local n_abscave = math.abs(nvals_cave[nixyz])
|
|
local n_abswave = math.abs(nvals_wave[nixyz])
|
|
|
|
local tcave --declare variable
|
|
--determine the overal cave threshold
|
|
if y < yblmin then
|
|
tcave = TCAVE + ((yblmin - y) / BLEND) ^ 2
|
|
elseif y > yblmax then
|
|
tcave = TCAVE + ((y - yblmax) / BLEND) ^ 2
|
|
else
|
|
tcave = TCAVE
|
|
end
|
|
|
|
--if y >= 1 and density > -0.01 and density < 0 then
|
|
if (nvals_cave[nixyz] + nvals_wave[nixyz])/2 > tcave + 0.005 and (nvals_cave[nixyz] + nvals_wave[nixyz])/2 < tcave + 0.015 then --if node falls within cave threshold
|
|
ysp = y + 1
|
|
xsp = x
|
|
zsp = z
|
|
break
|
|
end
|
|
nixz = nixz + 1
|
|
nixyz = nixyz + 1
|
|
end
|
|
if ysp then
|
|
break
|
|
end
|
|
nixz = nixz - 80
|
|
end
|
|
if ysp then
|
|
break
|
|
end
|
|
nixz = nixz + 80
|
|
end
|
|
if ysp then
|
|
break
|
|
end
|
|
end
|
|
print ("[caverealms] spawn player ("..xsp.." "..ysp.." "..zsp..")")
|
|
player:setpos({x=xsp, y=ysp, z=zsp})
|
|
spawned = true
|
|
end
|
|
|
|
--minetest.register_on_newplayer(function(player)
|
|
--spawnplayer(player)
|
|
--end)
|
|
|