forked from minetest-mods/mesecons
MVPS: Improve object move (#367)
This commit is contained in:
parent
37eb7f00e8
commit
c4a1aa0b98
|
@ -213,37 +213,52 @@ end)
|
||||||
|
|
||||||
function mesecon.mvps_move_objects(pos, dir, nodestack)
|
function mesecon.mvps_move_objects(pos, dir, nodestack)
|
||||||
local objects_to_move = {}
|
local objects_to_move = {}
|
||||||
|
local dir_k
|
||||||
-- Move object at tip of stack, pushpos is position at tip of stack
|
local dir_l
|
||||||
local pushpos = vector.add(pos, vector.multiply(dir, #nodestack))
|
for k, v in pairs(dir) do
|
||||||
|
if v ~= 0 then
|
||||||
local objects = minetest.get_objects_inside_radius(pushpos, 1)
|
dir_k = k
|
||||||
for _, obj in ipairs(objects) do
|
dir_l = v
|
||||||
table.insert(objects_to_move, obj)
|
break
|
||||||
end
|
|
||||||
|
|
||||||
-- Move objects lying/standing on the stack (before it was pushed - oldstack)
|
|
||||||
if tonumber(minetest.setting_get("movement_gravity")) > 0 and dir.y == 0 then
|
|
||||||
-- If gravity positive and dir horizontal, push players standing on the stack
|
|
||||||
for _, n in ipairs(nodestack) do
|
|
||||||
local p_above = vector.add(n.pos, {x=0, y=1, z=0})
|
|
||||||
local objects = minetest.get_objects_inside_radius(p_above, 1)
|
|
||||||
for _, obj in ipairs(objects) do
|
|
||||||
table.insert(objects_to_move, obj)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
for id, obj in pairs(minetest.object_refs) do
|
||||||
for _, obj in ipairs(objects_to_move) do
|
local obj_pos = obj:get_pos()
|
||||||
local entity = obj:get_luaentity()
|
local cbox = obj:get_properties().collisionbox
|
||||||
if not entity or not mesecon.is_mvps_unmov(entity.name) then
|
local min_pos = vector.add(obj_pos, vector.new(cbox[1], cbox[2], cbox[3]))
|
||||||
local np = vector.add(obj:getpos(), dir)
|
local max_pos = vector.add(obj_pos, vector.new(cbox[4], cbox[5], cbox[6]))
|
||||||
|
local ok = true
|
||||||
--move only if destination is not solid
|
for k, v in pairs(pos) do
|
||||||
local nn = minetest.get_node(np)
|
local edge1, edge2
|
||||||
if not ((not minetest.registered_nodes[nn.name])
|
if k ~= dir_k then
|
||||||
or minetest.registered_nodes[nn.name].walkable) then
|
edge1 = v - 0.51 -- More than 0.5 to move objects near to the stack.
|
||||||
obj:setpos(np)
|
edge2 = v + 0.51
|
||||||
|
else
|
||||||
|
edge1 = v - 0.5 * dir_l
|
||||||
|
edge2 = v + (#nodestack + 0.5) * dir_l
|
||||||
|
-- Make sure, edge1 is bigger than edge2:
|
||||||
|
if edge1 > edge2 then
|
||||||
|
edge1, edge2 = edge2, edge1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if min_pos[k] > edge2 or max_pos[k] < edge1 then
|
||||||
|
ok = false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if ok then
|
||||||
|
local ent = obj:get_luaentity()
|
||||||
|
if obj:is_player() or (ent and not mesecon.is_mvps_unmov(ent.name)) then
|
||||||
|
local np = vector.add(obj_pos, dir)
|
||||||
|
-- Move only if destination is not solid or object is inside stack:
|
||||||
|
local nn = minetest.get_node(np)
|
||||||
|
local node_def = minetest.registered_nodes[nn.name]
|
||||||
|
local obj_offset = dir_l * (obj_pos[dir_k] - pos[dir_k])
|
||||||
|
if (node_def and not node_def.walkable) or
|
||||||
|
(obj_offset >= 0 and
|
||||||
|
obj_offset <= #nodestack - 0.5) then
|
||||||
|
obj:move_to(np)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user