More accurate entity settling
Under heavy lag conditions, physical entities may land on the ground at any point during a time step, but if they have a lot of horizontal velocity then they may "slide" along the ground, and if we only check for settling based on their pos at step times, they may have already slid some distance dependent on luck and the actual amount of server lag. This means that under heavy lag conditions, items may spread out inconsistently from their landing positions and make a messy pile. Using the MT 5.3+ moveresult parameter of entity steps, we can easily find out when the initial ground contact occured, and use that as the settling position, which should be more consistent under lag conditions. This has the effect of making entities more consistently "sticky" so they always tend to stick at the point of initial contact and rarely slide or glance along the ground, unless they hit an edge/corner.
This commit is contained in:
parent
67e4c5d476
commit
f3bdf91dc6
@ -196,9 +196,20 @@ function nodecore.entity_settle_recurse(pos)
|
||||
entity_settle_recursing = nil
|
||||
end
|
||||
|
||||
local function groundpos(moveresult)
|
||||
if not (moveresult and moveresult.touching_ground) then return end
|
||||
local collisions = moveresult.collisions
|
||||
if not collisions then return end
|
||||
local first = collisions[1]
|
||||
if not (first and first.type == "node") then return end
|
||||
local pos = first.nodepos
|
||||
if not pos then return end
|
||||
return {x = pos.x, y = pos.y + 0.55, z = pos.z}
|
||||
end
|
||||
|
||||
function nodecore.entity_settle_check(on_settle, isnode)
|
||||
return function(self)
|
||||
local pos = self.object:get_pos()
|
||||
return function(self, _, moveresult)
|
||||
local pos = groundpos(moveresult) or self.object:get_pos()
|
||||
if not pos then return end
|
||||
if pos.y < nodecore.map_limit_min then
|
||||
pos.y = nodecore.map_limit_min
|
||||
|
@ -115,7 +115,7 @@ minetest.register_entity(":__builtin:falling_node", {
|
||||
on_step = function(self, ...)
|
||||
if not self.node then return self.object:remove() end
|
||||
nodecore.entity_update_maxy(self)
|
||||
if self:settle_check() then return end
|
||||
if self:settle_check(...) then return end
|
||||
|
||||
for _, func in ipairs(nodecore.registered_falling_node_steps) do
|
||||
if func(self, ...) == true then return end
|
||||
|
@ -85,13 +85,13 @@ minetest.register_entity(":__builtin:item", {
|
||||
end
|
||||
end),
|
||||
|
||||
on_step = function(self, dtime, ...)
|
||||
on_step = function(self, ...)
|
||||
if not self.itemstring then return self.object:remove() end
|
||||
nodecore.entity_update_maxy(self)
|
||||
if self:settle_check() then return end
|
||||
if self:settle_check(...) then return end
|
||||
|
||||
for _, func in ipairs(nodecore.registered_item_entity_steps) do
|
||||
if func(self, dtime, ...) == true then return end
|
||||
if func(self, ...) == true then return end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user