Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mvps: improve object move #367

Merged
merged 4 commits into from
Oct 8, 2017
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
mvps: improve object move
  • Loading branch information
Desour committed Sep 9, 2017
commit 4b19bdd0762dc2156f3ee5a5b464363e8661094d
69 changes: 41 additions & 28 deletions mesecons_mvps/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -205,37 +205,50 @@ end)

function mesecon.mvps_move_objects(pos, dir, nodestack)
local objects_to_move = {}

-- Move object at tip of stack, pushpos is position at tip of stack
local pushpos = vector.add(pos, vector.multiply(dir, #nodestack))

local objects = minetest.get_objects_inside_radius(pushpos, 1)
for _, obj in ipairs(objects) do
table.insert(objects_to_move, obj)
local dir_k
local dir_l
for k, v in pairs(dir) do
if v ~= 0 then
dir_k = k
dir_l = v
break
end
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)
for id, obj in pairs(minetest.object_refs) do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems horribly, but that’s the only way; MT itself does the same, all the time...

local obj_pos = obj:get_pos()
local cbox = obj:get_properties().collisionbox
local min_pos = vector.add(obj_pos, vector.new(cbox[1], cbox[2], cbox[3]))
local max_pos = vector.add(obj_pos, vector.new(cbox[4], cbox[5], cbox[6]))
local ok = true
for k, v in pairs(pos) do
local edge1, edge2
if k ~= dir_k then
edge1 = v - 0.5
edge2 = v + 0.5
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Objects lying on top of the nodestack aren't moved anymore. Bad?

You mean, when pushing horizontally? That’s acceptable, but may be fixed by increasing (slightly) constant here, if I understand the code correctly.

else
edge1 = v - 0.5 * dir_l
edge2 = v + (#nodestack + 0.5) * dir_l
-- Make sure, edge1 is more than edge2:
if edge1 > edge2 then
edge1, edge2 = edge2, edge1
end
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

edges may be pre-calculated

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

? This works well enough imo, I can't find a simpler way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This exact way, but before for id, obj in pairs(minetest.object_refs) do and not in the inner loop.

if min_pos[k] > edge2 or max_pos[k] < edge1 then
ok = false
break
end
end
end

for _, obj in ipairs(objects_to_move) do
local entity = obj:get_luaentity()
if not entity or not mesecon.is_mvps_unmov(entity.name) then
local np = vector.add(obj:getpos(), dir)

--move only if destination is not solid
local nn = minetest.get_node(np)
if not ((not minetest.registered_nodes[nn.name])
or minetest.registered_nodes[nn.name].walkable) then
obj:setpos(np)
if ok then
local ent = obj:get_luaentity()
if not ent or not mesecon.is_mvps_unmov(ent.name) then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if ent and ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not (ent and …)

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]
if (node_def and not node_def.walkable) or
math.abs(obj_pos[dir_k]) <= #nodestack - 0.5 + math.abs(pos[dir_k]) then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if signs of pos[dir_k] and obj_pos[dir_k] are different?

obj:move_to(np)
end
end
end
end
Expand Down