MVPS: Improve object move (#367)

This commit is contained in:
DS 2017-10-08 17:18:47 +02:00 committed by Vitaliy
parent 37eb7f00e8
commit c4a1aa0b98

View File

@ -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