Make floating vines decay

Also destroy them immediately with leafdecay and when try try to grow but notice they have been floating the whole time.
This commit is contained in:
Wuzzy 2017-11-02 23:21:04 +01:00
parent 71f9250fcf
commit 1e2343d649
2 changed files with 78 additions and 15 deletions

View File

@ -934,6 +934,13 @@ minetest.register_abm({
chance = 4, chance = 4,
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
-- First of all, check if we are even supported, otherwise, let's die!
if not mcl_core.check_vines_supported(pos, node) then
minetest.remove_node(pos)
core.check_for_falling(pos)
return
end
local neighbor_offsets = { local neighbor_offsets = {
{ x=1, y=0, z=0 }, { x=1, y=0, z=0 },
{ x=-1, y=0, z=0 }, { x=-1, y=0, z=0 },
@ -1010,7 +1017,9 @@ minetest.register_abm({
mcl_core.supports_vines = function(nodename) mcl_core.supports_vines = function(nodename)
local def = minetest.registered_nodes[nodename] local def = minetest.registered_nodes[nodename]
-- Rules: 1) walkable 2) full cube -- Rules: 1) walkable 2) full cube
return def.walkable and ((not def.node_box) or def.node_box.type == "regular") return def.walkable and
(def.node_box == nil or def.node_box.type == "regular") and
(def.collision_box == nil or def.collision_box.type == "regular")
end end
-- Leaf Decay -- Leaf Decay
@ -1098,10 +1107,75 @@ minetest.register_abm({
-- Remove node -- Remove node
minetest.remove_node(p0) minetest.remove_node(p0)
core.check_for_falling(p0) core.check_for_falling(p0)
-- Kill depending vines immediately to skip the vines decay delay
local surround = {
{ x = 0, y = 0, z = -1 },
{ x = 0, y = 0, z = 1 },
{ x = -1, y = 0, z = 0 },
{ x = 1, y = 0, z = 0 },
{ x = 0, y = -1, z = -1 },
}
for s=1, #surround do
local spos = vector.add(p0, surround[s])
local maybe_vine = minetest.get_node(spos)
local surround_inverse = vector.multiply(surround[s], -1)
if maybe_vine.name == "mcl_core:vine" and (not mcl_core.check_vines_supported(spos, maybe_vine)) then
minetest.remove_node(spos)
core.check_for_falling(spos)
end
end
end end
end end
}) })
-- Remove vines which are not supported by anything, similar to leaf decay.
--[[ TODO: Vines are supposed to die immediately when they supporting block is destroyed.
But doing this in Minetest would be too complicated / hacky. This vines decay is a simple
way to make sure that all floating vines are destroyed eventually. ]]
minetest.register_abm({
label = "Vines decay",
nodenames = {"mcl_core:vine"},
neighbors = {"air"},
-- A low interval and a high inverse chance spreads the load
interval = 3,
chance = 5,
action = function(p0, node, _, _)
if not mcl_core.check_vines_supported(p0, node) then
-- Vines must die!
minetest.remove_node(p0)
-- Just in case a falling node happens to float above vines
core.check_for_falling(p0)
end
end
})
--[[ Call this for vines nodes only.
Given the pos and node of a vines node, this returns true if the vines are supported
and false if the vines are currently floating.
Vines are considered supported if they face a walkable+solid block or hang from a vines node above. ]]
function mcl_core.check_vines_supported(pos, node)
local supported = false
local dir = minetest.wallmounted_to_dir(node.param2)
local pos1 = vector.add(pos, dir)
local node_neighbor = minetest.get_node(pos1)
-- Check if vines are attached to a solid block.
-- If ignore, we assume its solid.
if node_neighbor.name == "ignore" or mcl_core.supports_vines(node_neighbor.name) then
supported = true
elseif dir.y == 0 then
-- Vines are not attached, now we check if the vines are “hanging” below another vines block
-- of equal orientation.
local pos2 = vector.add(pos, {x=0, y=1, z=0})
local node2 = minetest.get_node(pos2)
-- Again, ignore means we assume its supported
if node2.name == "ignore" or (node2.name == "mcl_core:vine" and node2.param2 == node.param2) then
supported = true
end
end
return supported
end
---- FUNCTIONS FOR SNOWED NODES ---- ---- FUNCTIONS FOR SNOWED NODES ----
-- These are nodes which change their appearence when they are below a snow cover -- These are nodes which change their appearence when they are below a snow cover
-- and turn back into “normal” when the snow cover is removed. -- and turn back into “normal” when the snow cover is removed.

View File

@ -118,14 +118,9 @@ minetest.register_node("mcl_core:vine", {
end end
end end
-- Only allow placement on solid nodes
if (not groups) or (not groups.solid) then
return itemstack
end
-- Only place on full cubes -- Only place on full cubes
if not mcl_core.supports_vines(node.name) then if not mcl_core.supports_vines(node.name) then
return return itemstack
end end
local above = pointed_thing.above local above = pointed_thing.above
@ -150,15 +145,9 @@ minetest.register_node("mcl_core:vine", {
after_destruct = function(pos, oldnode) after_destruct = function(pos, oldnode)
local below = {x=pos.x, y=pos.y-1, z=pos.z} local below = {x=pos.x, y=pos.y-1, z=pos.z}
local belownode = minetest.get_node(below) local belownode = minetest.get_node(below)
if belownode.name == oldnode.name and belownode.param2 == belownode.param2 then if belownode.name == oldnode.name and mcl_core.check_vines_supported(below, belownode) then
local dir = minetest.wallmounted_to_dir(belownode.param2)
local support = vector.add(below, dir)
local supportnode = minetest.get_node(support)
-- supporting block = walkable + solid
if not minetest.registered_nodes[supportnode.name].walkable and minetest.get_item_group(supportnode.name, "solid") ~= 1 then
minetest.remove_node(below) minetest.remove_node(below)
end end
end
end, end,