fun_caves/deco_water.lua
2016-05-23 05:50:17 -05:00

100 lines
4 KiB
Lua

local node = fun_caves.node
local light_depth = -13
local water_level = 1
local water_lily_biomes = {}
for _, i in pairs({"rainforest_swamp", "rainforest", "savanna_swamp", "savanna", "deciduous_forest_swamp", "deciduous_forest", }) do
water_lily_biomes[i] = true
end
local coral_biomes = {}
for _, i in pairs({"desert_ocean", "savanna_ocean", "rainforest_ocean", }) do
coral_biomes[i] = true
end
plant_noise = {offset = 0.0, scale = 1.0, spread = {x = 200, y = 200, z = 200}, seed = 33, octaves = 3, persist = 0.7, lacunarity = 2.0}
local function surround(data, area, ivm)
local n
-- Check to make sure that a plant root is fully surrounded.
-- This is due to the kludgy way you have to make water plants
-- in minetest, to avoid bubbles.
for x1 = -1,1,2 do
n = data[ivm+x1]
if n == node("default:river_water_source") or n == node("default:water_source") or n == node("air") then
return false
end
end
for z1 = -area.zstride,area.zstride,2*area.zstride do
n = data[ivm+z1]
if n == node("default:river_water_source") or n == node("default:water_source") or n == node("air") then
return false
end
end
return true
end
function fun_caves.decorate_water(data, area, minp, maxp, pos, ivm, biome_in, pn)
if pos.y < light_depth then
return
end
local biome = biome_in
local node_below = data[ivm - area.ystride]
local node_above = data[ivm + area.ystride]
local inside = false
if pos.x < maxp.x and pos.y < maxp.y and pos.z < maxp.z and pos.x > minp.x and pos.y > minp.y and pos.z > minp.z then
inside = true
end
if pos.y < water_level and data[ivm] == node("default:sand") and node_above == node("default:water_source") and data[ivm + area.ystride * 2] == node("default:water_source") and coral_biomes[biome] and pn < -0.1 and math.random(5) == 1 and surround(data, area, ivm) then
return node("fun_caves:staghorn_coral_water_sand")
elseif pos.y < water_level and node_below == node("default:sand") and node_above == node("default:water_source") and data[ivm] == node("default:water_source") and coral_biomes[biome] and pn < -0.1 and math.random(5) < 3 then
local sr = math.random(65)
if sr < 4 then
return node("fun_caves:brain_coral")
elseif sr < 6 then
return node("fun_caves:dragon_eye")
elseif sr < 65 then
return node("fun_caves:pillar_coral")
end
elseif inside and (node_above == node("default:water_source") or node_above == node("default:river_water_source")) and (data[ivm] == node("default:sand") or data[ivm] == node("default:dirt")) then
-- Check the biomes and plant water plants, if called for.
if not surround(data, area, ivm) then
return
end
for _, desc in pairs(fun_caves.water_plants) do
if desc.content_id then
if not fun_caves.node_match_cache[desc.content_id] then
fun_caves.node_match_cache[desc.content_id] = {}
end
if not fun_caves.node_match_cache[desc.content_id][data[ivm]] then
-- This is a great way to match all node type strings
-- against a given node (or nodes). However, it's slow.
-- To speed it up, we cache the results for each plant
-- on each node, and avoid calling find_nodes every time.
local posm, count = minetest.find_nodes_in_area(pos, pos, desc.place_on)
if #posm > 0 then
fun_caves.node_match_cache[desc.content_id][data[ivm]] = "good"
else
fun_caves.node_match_cache[desc.content_id][data[ivm]] = "bad"
end
end
if fun_caves.node_match_cache[desc.content_id][data[ivm]] == "good" and desc.fill_ratio and (not desc.biomes or (biome and desc.biomes and table.contains(desc.biomes, biome))) and math.random() <= desc.fill_ratio then
return desc.content_id
end
end
end
elseif pos.y > minp.y and node_below == node("default:river_water_source") and data[ivm] == node("air") and water_lily_biomes[biome] and pn > 0.5 and math.random(15) == 1 then
-- on top of the water
-- I haven't figured out what the decoration manager is
-- doing with the noise functions, but this works ok.
return node("flowers:waterlily")
end
end