add opt-in falling_node collision for non-walkable nodes.

make falling_node entities land on nodes with `supports_falling = true`
in their definitions.
This commit is contained in:
trans_soup 2023-10-19 14:07:47 +02:00
parent c0ef9c3677
commit 6bb71aa341
1 changed files with 40 additions and 4 deletions

View File

@ -2,11 +2,11 @@ local entity = minetest.registered_entities["__builtin:falling_node"]
local original_try_place = entity.try_place
local old_try_place = entity.try_place
local after_land_callbacks = {}
entity.try_place = function (self, bcp, bcn)
local result = original_try_place(self, bcp, bcn)
local result = old_try_place(self, bcp, bcn)
-- `result` will be true if the falling node landed successfully (afaict from reading `/builtin/game/falling.lua` in the minetest source).
if result then
-- `bcp` is actually the node 0.7 nodes (rounded) below the falling_node entity.
@ -34,11 +34,11 @@ end)
local original_on_step = entity.on_step
local old_on_step = entity.on_step
local on_step_callbacks = {}
entity.on_step = function (self, dtime, moveresult)
local result = original_on_step(self, dtime, moveresult)
local result = old_on_step(self, dtime, moveresult)
for _, callback in pairs(on_step_callbacks) do
callback(self, dtime, moveresult)
end
@ -65,3 +65,39 @@ blockgame.register_on_falling_node_step(function (entity, delta_time, move_resul
end
end)
-- make falling nodes collide with `walkable = false` nodes if they are also `supports_falling = true`.
blockgame.register_on_falling_node_step(function (entity, delta_time, move_result)
local pos = entity.object:get_pos()
if not pos then return end
local below = pos:offset(0, -0.7, 0) -- same offset as in `/builtin/game/falling.lua`
local node = minetest.get_node(below)
if node == "air" then return end
local def = minetest.registered_nodes[node.name]
if not def then return end
if def.walkable or not def.supports_falling then return end
local success = entity:try_place(below, node)
if not success then
local drops = minetest.get_node_drops(entity.node, "")
for _, item in pairs(drops) do
minetest.add_item(pos, item)
end
end
entity.object:remove()
end)
local old_check = minetest.check_single_for_falling
function minetest.check_single_for_falling (pos, ...)
local node = minetest.get_node(pos:offset(0, -1, 0))
local def = minetest.registered_nodes[node.name]
if def and def.supports_falling then return false end
return old_check(pos, ...)
end