forked from Kimapr/nodecore-skyblock
88 lines
2.6 KiB
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
|