Item entities properly fall thru forms

This commit is contained in:
Aaron Suen 2021-11-27 15:08:40 -05:00
parent 3c071dba09
commit ce99412270
5 changed files with 58 additions and 25 deletions

View File

@ -81,6 +81,8 @@ do
minetest.after(0, regreport)
end
nodecore.add_item_raw = minetest.add_item
include("compat_clientversion")
include("compat_creative")
include("compat_issue10127")

View File

@ -142,13 +142,22 @@ function nodecore.stack_giveto(pos, player, node, def)
return stack:is_empty()
end
function nodecore.stack_settle(pos, stack, node, def)
function nodecore.stack_settle(pos, stack, node, def, inside)
stack = ItemStack(stack)
if stack:is_empty() then return stack end
node = node or minetest.get_node(pos)
def = def or minetest.registered_items[node.name] or {}
if not def.on_settle_item then return stack end
return def.on_settle_item(pos, node, stack)
return def.on_settle_item(pos, node, stack, inside)
end
function nodecore.stack_can_fall_in(pos, stack, node, def, ent)
stack = ItemStack(stack)
if stack:is_empty() then return end
node = node or minetest.get_node(pos)
def = def or minetest.registered_items[node.name] or {}
if not def.can_item_fall_in then return def.buildable_to end
return def.can_item_fall_in(pos, node, stack, ent)
end
local ejectdir
@ -214,7 +223,7 @@ function nodecore.item_eject(pos, stack, speed, qty, vel)
}
end
local p = {x = pos.x, y = pos.y + 0.25, z = pos.z}
local obj = minetest.add_item(p, stack)
local obj = nodecore.add_item_raw(p, stack)
if obj then obj:set_velocity(v) end
end
end

View File

@ -69,6 +69,15 @@ function nodecore.storebox_on_settle_item(pos, node, stack)
return nodecore.stack_add(pos, stack)
end
function nodecore.storebox_can_item_fall_in(pos, node)
if not nodecore.stack_get(pos):is_empty() then return end
local def = node and minetest.registered_items[node.name] or {}
if def.storebox_access and (not def.storebox_access(
{type = "node", above = {x = pos.x, y = pos.y + 1, z = pos.z},
under = pos}, pos, node)) then return end
return true
end
nodecore.register_on_register_item(function(_, def)
if def.type ~= "node" or (not def.groups) or (not def.groups.storebox) then return end
@ -91,4 +100,5 @@ nodecore.register_on_register_item(function(_, def)
def.on_punch = def.on_punch or nodecore.storebox_on_punch
def.stack_allow = def.stack_allow or nodecore.storebox_stack_allow
def.on_settle_item = def.on_settle_item or nodecore.storebox_on_settle_item
def.can_item_fall_in = def.can_item_fall_in or nodecore.storebox_can_item_fall_in
end)

View File

@ -14,6 +14,12 @@ minetest.after(0, function()
end
end)
local function nuke(self)
self.itemstring = ""
self.object:remove()
return true
end
nodecore.register_item_entity_on_settle(function(self, pos)
local curnode = minetest.get_node(pos)
if curnode.name == "ignore" then return end
@ -25,12 +31,15 @@ nodecore.register_item_entity_on_settle(function(self, pos)
then return end
local item = ItemStack(self.itemstring)
item = nodecore.stack_settle(pos, item, bnode)
if item:is_empty() then
self.itemstring = ""
self.object:remove()
return true
item = nodecore.stack_settle(pos, item, curnode, nil, true)
if item:is_empty() then return nuke(self) end
if nodecore.stack_can_fall_in(below, item, bnode, nil, self) then
self.object:set_pos({x = pos.x, y = pos.y - 0.55, z = pos.z})
self.object:set_velocity({x = 0, y = 0, z = 0})
return
end
item = nodecore.stack_settle(below, item, bnode)
if item:is_empty() then return nuke(self) end
if self.nextscan and nodecore.gametime < self.nextscan then return end
self.nextscan = (self.nextscan or nodecore.gametime) + 0.75 + 0.5 * math_random()
@ -41,11 +50,7 @@ nodecore.register_item_entity_on_settle(function(self, pos)
local n = minetest.get_node(p)
if stackonly[n.name] then
item = nodecore.stack_add(p, item)
if item:is_empty() then
self.itemstring = ""
self.object:remove()
return true
end
if item:is_empty() then return nuke(self) end
else
boxes[#boxes + 1] = p
end
@ -55,17 +60,12 @@ nodecore.register_item_entity_on_settle(function(self, pos)
nodecore.place_stack(p, item)
minetest.get_meta(p):set_string("tweenfrom",
minetest.serialize(self.object:get_pos()))
self.object:remove()
return true
return nuke(self)
end
end
for _, p in pairs(boxes) do
item = nodecore.stack_add(p, item)
if item:is_empty() then
self.itemstring = ""
self.object:remove()
return true
end
if item:is_empty() then return nuke(self) end
end
self.itemstring = item:to_string()
end)

View File

@ -29,12 +29,24 @@ minetest.register_node(modname .. ":form", {
return nodecore.stack_get(pos)
end
end,
on_settle_item = function(pos, node, stack, inside, ...)
if inside and nodecore.stack_can_fall_in({
x = pos.x,
y = pos.y - 1,
z = pos.z
}, stack) then return stack end
return nodecore.storebox_on_settle_item(pos, node, stack, inside, ...)
end,
on_stack_change = function(pos, _, stack)
nodecore.stack_set(pos, nodecore.stack_settle({
x = pos.x,
y = pos.y - 1,
z = pos.z
}, stack))
if stack:is_empty() then return end
print(stack:to_string())
if not nodecore.stack_can_fall_in({
x = pos.x,
y = pos.y - 1,
z = pos.z
}, stack) then return end
nodecore.stack_set(pos, "")
nodecore.item_eject(pos, stack)
end
})