mirror of
https://github.com/minetest/minetest.git
synced 2024-12-23 14:42:24 +01:00
parent
3475759d1a
commit
b9377f26a1
@ -34,7 +34,6 @@ core.register_entity(":__builtin:item", {
|
|||||||
|
|
||||||
itemstring = "",
|
itemstring = "",
|
||||||
moving_state = true,
|
moving_state = true,
|
||||||
slippery_state = false,
|
|
||||||
physical_state = true,
|
physical_state = true,
|
||||||
-- Item expiry
|
-- Item expiry
|
||||||
age = 0,
|
age = 0,
|
||||||
@ -157,7 +156,7 @@ core.register_entity(":__builtin:item", {
|
|||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
on_step = function(self, dtime)
|
on_step = function(self, dtime, moveresult)
|
||||||
self.age = self.age + dtime
|
self.age = self.age + dtime
|
||||||
if time_to_live > 0 and self.age > time_to_live then
|
if time_to_live > 0 and self.age > time_to_live then
|
||||||
self.itemstring = ""
|
self.itemstring = ""
|
||||||
@ -178,6 +177,36 @@ core.register_entity(":__builtin:item", {
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if self.force_out then
|
||||||
|
-- This code runs after the entity got a push from the is_stuck code.
|
||||||
|
-- It makes sure the entity is entirely outside the solid node
|
||||||
|
local c = self.object:get_properties().collisionbox
|
||||||
|
local s = self.force_out_start
|
||||||
|
local f = self.force_out
|
||||||
|
local ok = (f.x > 0 and pos.x + c[1] > s.x + 0.5) or
|
||||||
|
(f.y > 0 and pos.y + c[2] > s.y + 0.5) or
|
||||||
|
(f.z > 0 and pos.z + c[3] > s.z + 0.5) or
|
||||||
|
(f.x < 0 and pos.x + c[4] < s.x - 0.5) or
|
||||||
|
(f.z < 0 and pos.z + c[6] < s.z - 0.5)
|
||||||
|
if ok then
|
||||||
|
-- Item was successfully forced out
|
||||||
|
self.force_out = nil
|
||||||
|
self:enable_physics()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not self.physical_state then
|
||||||
|
return -- Don't do anything
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(moveresult)
|
||||||
|
if not moveresult.collides then
|
||||||
|
-- future TODO: items should probably decelerate in air
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Push item out when stuck inside solid node
|
||||||
local is_stuck = false
|
local is_stuck = false
|
||||||
local snode = core.get_node_or_nil(pos)
|
local snode = core.get_node_or_nil(pos)
|
||||||
if snode then
|
if snode then
|
||||||
@ -187,7 +216,6 @@ core.register_entity(":__builtin:item", {
|
|||||||
and (sdef.node_box == nil or sdef.node_box.type == "regular")
|
and (sdef.node_box == nil or sdef.node_box.type == "regular")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Push item out when stuck inside solid node
|
|
||||||
if is_stuck then
|
if is_stuck then
|
||||||
local shootdir
|
local shootdir
|
||||||
local order = {
|
local order = {
|
||||||
@ -223,69 +251,49 @@ core.register_entity(":__builtin:item", {
|
|||||||
self.force_out_start = vector.round(pos)
|
self.force_out_start = vector.round(pos)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
elseif self.force_out then
|
|
||||||
-- This code runs after the entity got a push from the above code.
|
|
||||||
-- It makes sure the entity is entirely outside the solid node
|
|
||||||
local c = self.object:get_properties().collisionbox
|
|
||||||
local s = self.force_out_start
|
|
||||||
local f = self.force_out
|
|
||||||
local ok = (f.x > 0 and pos.x + c[1] > s.x + 0.5) or
|
|
||||||
(f.y > 0 and pos.y + c[2] > s.y + 0.5) or
|
|
||||||
(f.z > 0 and pos.z + c[3] > s.z + 0.5) or
|
|
||||||
(f.x < 0 and pos.x + c[4] < s.x - 0.5) or
|
|
||||||
(f.z < 0 and pos.z + c[6] < s.z - 0.5)
|
|
||||||
if ok then
|
|
||||||
-- Item was successfully forced out
|
|
||||||
self.force_out = nil
|
|
||||||
self:enable_physics()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self.physical_state then
|
node = nil -- ground node we're colliding with
|
||||||
return -- Don't do anything
|
if moveresult.touching_ground then
|
||||||
|
for _, info in ipairs(moveresult.collisions) do
|
||||||
|
if info.axis == "y" then
|
||||||
|
node = core.get_node(info.node_pos)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Slide on slippery nodes
|
-- Slide on slippery nodes
|
||||||
local vel = self.object:get_velocity()
|
|
||||||
local def = node and core.registered_nodes[node.name]
|
local def = node and core.registered_nodes[node.name]
|
||||||
local is_moving = (def and not def.walkable) or
|
local keep_movement = false
|
||||||
vel.x ~= 0 or vel.y ~= 0 or vel.z ~= 0
|
|
||||||
local is_slippery = false
|
|
||||||
|
|
||||||
if def and def.walkable then
|
if def then
|
||||||
local slippery = core.get_item_group(node.name, "slippery")
|
local slippery = core.get_item_group(node.name, "slippery")
|
||||||
is_slippery = slippery ~= 0
|
local vel = self.object:get_velocity()
|
||||||
if is_slippery and (math.abs(vel.x) > 0.2 or math.abs(vel.z) > 0.2) then
|
if slippery ~= 0 and (math.abs(vel.x) > 0.1 or math.abs(vel.z) > 0.1) then
|
||||||
-- Horizontal deceleration
|
-- Horizontal deceleration
|
||||||
local slip_factor = 4.0 / (slippery + 4)
|
local factor = math.min(4 / (slippery + 4) * dtime, 1)
|
||||||
self.object:set_acceleration({
|
self.object:set_velocity({
|
||||||
x = -vel.x * slip_factor,
|
x = vel.x * (1 - factor),
|
||||||
y = 0,
|
y = 0,
|
||||||
z = -vel.z * slip_factor
|
z = vel.z * (1 - factor)
|
||||||
})
|
})
|
||||||
elseif vel.y == 0 then
|
keep_movement = true
|
||||||
is_moving = false
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.moving_state == is_moving and
|
if not keep_movement then
|
||||||
self.slippery_state == is_slippery then
|
self.object:set_velocity({x=0, y=0, z=0})
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.moving_state == keep_movement then
|
||||||
-- Do not update anything until the moving state changes
|
-- Do not update anything until the moving state changes
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
self.moving_state = keep_movement
|
||||||
|
|
||||||
self.moving_state = is_moving
|
-- Only collect items if not moving
|
||||||
self.slippery_state = is_slippery
|
if self.moving_state then
|
||||||
|
|
||||||
if is_moving then
|
|
||||||
self.object:set_acceleration({x = 0, y = -gravity, z = 0})
|
|
||||||
else
|
|
||||||
self.object:set_acceleration({x = 0, y = 0, z = 0})
|
|
||||||
self.object:set_velocity({x = 0, y = 0, z = 0})
|
|
||||||
end
|
|
||||||
|
|
||||||
--Only collect items if not moving
|
|
||||||
if is_moving then
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
-- Collect the items around to merge with
|
-- Collect the items around to merge with
|
||||||
|
Loading…
Reference in New Issue
Block a user