nodecore-skyblock/mods/nc_sponge/cultivate.lua

88 lines
2.6 KiB
Lua

-- LUALOCALS < ---------------------------------------------------------
local ItemStack, math, minetest, nodecore, pairs, vector
= ItemStack, math, minetest, nodecore, pairs, vector
local math_pow, math_random
= math.pow, math.random
-- LUALOCALS > ---------------------------------------------------------
local modname = minetest.get_current_modname()
local growdirs = nodecore.dirs()
local living = modname .. ":sponge_living"
nodecore.register_limited_abm({
label = "Sponge Growth",
interval = 10,
chance = 1000,
limited_max = 100,
nodenames = {living},
neighbors = {"group:water"},
action = function(pos)
local total = 0
if nodecore.scan_flood(pos, 6,
function(p, d)
if d >= 6 then return true end
if minetest.get_node(p).name ~= living then return false end
total = total + 1
if total >= 20 then return true end
end
) then return end
pos = vector.add(pos, growdirs[math_random(1, #growdirs)])
local node = minetest.get_node_or_nil(pos)
local def = node and minetest.registered_nodes[node.name]
local grp = def and def.groups and def.groups.water
if (not grp) or (grp < 1) then return end
local below = {x = pos.x, y = pos.y - 1, z = pos.z}
node = minetest.get_node(below)
if (math_random() > 0.1) or (node.name ~= living) then
def = minetest.registered_nodes[node.name]
grp = def and def.groups and def.groups.sand
if (not grp) or (grp < 1) then return end
end
minetest.set_node(pos, {name = living})
end
})
-- A living sponge can be dug intact, RARELY, and ONLY if surrounded
-- on all sides and edges (X/Z plane) by other living sponges.
local digpos
local old_node_dig = minetest.node_dig
minetest.node_dig = function(pos, node, ...)
if (node and node.name) ~= living then
return old_node_dig(pos, node, ...)
end
local function helper(...)
digpos = nil
return ...
end
digpos = pos
return helper(old_node_dig(pos, node, ...))
end
local old_get_node_drops = minetest.get_node_drops
minetest.get_node_drops = function(...)
local drops = old_get_node_drops(...)
if not digpos then return drops end
local neighbors = #minetest.find_nodes_in_area(
{x = digpos.x - 1, y = digpos.y - 1, z = digpos.z - 1},
{x = digpos.x + 1, y = digpos.y + 1, z = digpos.z + 1},
{living})
if neighbors >= 5 then
local prob = math_pow(2, neighbors - 5) * 0.005
if math_random() <= prob then return drops end
end
drops = drops or {}
for k, v in pairs(drops) do
v = ItemStack(v)
if v:get_name() == living then
v:set_name(modname .. ":sponge_wet")
end
drops[k] = v
end
return drops
end