@@ -270,16 +270,24 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sti
270270 return true , nodes , oldstack
271271end
272272
273- -- Returns whether the given area intersects any nodes in the given set of position hashes.
273+ -- Returns whether the given area intersects any nodes in the given set of position hashes,
274+ -- or any walkable nodes in the map if no set is given.
274275local function area_intersects_nodes (min_pos , max_pos , positions )
275276 min_pos = vector .round (min_pos )
276277 max_pos = vector .round (max_pos )
277278 local pos = vector .new (min_pos )
278279 while pos .x <= max_pos .x do
279280 while pos .y <= max_pos .y do
280281 while pos .z <= max_pos .z do
281- if positions [minetest .hash_node_position (pos )] then
282- return true
282+ if positions then
283+ if positions [minetest .hash_node_position (pos )] then
284+ return true
285+ end
286+ else
287+ local def = minetest .registered_nodes [minetest .get_node (pos ).name ]
288+ if def .walkable then
289+ return true
290+ end
283291 end
284292 pos .z = pos .z + 1
285293 end
@@ -368,15 +376,13 @@ function mesecon.mvps_move_objects(pos, dir, nodestack, movefactor)
368376 if ok then
369377 local ent = obj :get_luaentity ()
370378 if obj :is_player () or (ent and not mesecon .is_mvps_unmov (ent .name )) then
371- local np = vector .add (obj_pos , dir )
372379 -- Move only if destination is not solid or object is inside stack:
373- local nn = minetest .get_node (np )
374- local node_def = minetest .registered_nodes [nn .name ]
375- local obj_offset = dir_l * (obj_pos [dir_k ] - pos [dir_k ])
376- if (node_def and not node_def .walkable ) or
377- (obj_offset >= 0 and
378- obj_offset <= # nodestack - 0.5 ) then
379- obj :move_to (np )
380+ -- (A small bias is added to prevent rounding issues.)
381+ local min_pos = vector .offset (obj_pos , cbox [1 ] + 0.01 , cbox [2 ] + 0.01 , cbox [3 ] + 0.01 )
382+ local max_pos = vector .offset (obj_pos , cbox [4 ] - 0.01 , cbox [5 ] - 0.01 , cbox [6 ] - 0.01 )
383+ if not area_intersects_nodes (vector .add (min_pos , dir ), vector .add (max_pos , dir )) or
384+ area_intersects_nodes (min_pos , max_pos , moved_positions ) then
385+ obj :move_to (vector .add (obj_pos , dir ))
380386 end
381387 end
382388 end
0 commit comments