blockgame/mods/bg_api/fall_fix.lua
trans_soup 96ebbe8e0e improve fall_fix.
make the position passed to callbacks be the position where the
falling_node entity landed, rather than the position it tries to land
on/in.

note that if the node it lands on has its `paramtype2` set to
`"leveled"` then this new position might be empty after a landing.
2023-10-19 11:25:12 +02:00

67 lines
2.1 KiB
Lua

local entity = minetest.registered_entities["__builtin:falling_node"]
local original_try_place = entity.try_place
local after_land_callbacks = {}
entity.try_place = function (self, bcp, bcn)
local result = original_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.
-- the vector addition here makes it be the position where the entity itself landed.
-- if it landed on something layered, this new position might be air when the callbacks are called.
local pos = bcp + vector.new(0, 1, 0)
for _, callback in pairs(after_land_callbacks) do
callback(pos, bcn, self)
end
end
return result
end
function blockgame.register_after_falling_node_lands (callback)
table.insert(after_land_callbacks, callback)
end
blockgame.register_after_falling_node_lands(function (pos, node)
local def = minetest.registered_nodes[node.name]
if type(def.after_landing) == "function" then
def.after_landing(pos, node)
end
end)
local original_on_step = entity.on_step
local on_step_callbacks = {}
entity.on_step = function (self, dtime, moveresult)
local result = original_on_step(self, dtime, moveresult)
for _, callback in pairs(on_step_callbacks) do
callback(self, dtime, moveresult)
end
return result
end
function blockgame.register_on_falling_node_step (callback)
table.insert(on_step_callbacks, callback)
end
-- keep track of velocity a falling_node had before landing
-- so that code hooked into the landing can check "how fast was this moving?"
blockgame.register_on_falling_node_step(function (entity, delta_time, move_result)
local velocity = entity.object:get_velocity()
-- let `previous_velocity` be (0, 0, 0) at the very first step
if not entity.fall_velocity then
entity.fall_velocity = vector.new(0, 0, 0)
end
-- keep track of moving velocity, not still velocity
if velocity and (vector.length(velocity) ~= 0) then
entity.fall_velocity = vector.copy(velocity)
end
end)