@@ -213,37 +213,52 @@ end)
213
213
214
214
function mesecon .mvps_move_objects (pos , dir , nodestack )
215
215
local objects_to_move = {}
216
-
217
- -- Move object at tip of stack, pushpos is position at tip of stack
218
- local pushpos = vector .add (pos , vector .multiply (dir , # nodestack ))
219
-
220
- local objects = minetest .get_objects_inside_radius (pushpos , 1 )
221
- for _ , obj in ipairs (objects ) do
222
- table.insert (objects_to_move , obj )
216
+ local dir_k
217
+ local dir_l
218
+ for k , v in pairs (dir ) do
219
+ if v ~= 0 then
220
+ dir_k = k
221
+ dir_l = v
222
+ break
223
+ end
223
224
end
224
-
225
- -- Move objects lying/standing on the stack (before it was pushed - oldstack)
226
- if tonumber (minetest .setting_get (" movement_gravity" )) > 0 and dir .y == 0 then
227
- -- If gravity positive and dir horizontal, push players standing on the stack
228
- for _ , n in ipairs (nodestack ) do
229
- local p_above = vector .add (n .pos , {x = 0 , y = 1 , z = 0 })
230
- local objects = minetest .get_objects_inside_radius (p_above , 1 )
231
- for _ , obj in ipairs (objects ) do
232
- table.insert (objects_to_move , obj )
225
+ for id , obj in pairs (minetest .object_refs ) do
226
+ local obj_pos = obj :get_pos ()
227
+ local cbox = obj :get_properties ().collisionbox
228
+ local min_pos = vector .add (obj_pos , vector .new (cbox [1 ], cbox [2 ], cbox [3 ]))
229
+ local max_pos = vector .add (obj_pos , vector .new (cbox [4 ], cbox [5 ], cbox [6 ]))
230
+ local ok = true
231
+ for k , v in pairs (pos ) do
232
+ local edge1 , edge2
233
+ if k ~= dir_k then
234
+ edge1 = v - 0.51 -- More than 0.5 to move objects near to the stack.
235
+ edge2 = v + 0.51
236
+ else
237
+ edge1 = v - 0.5 * dir_l
238
+ edge2 = v + (# nodestack + 0.5 ) * dir_l
239
+ -- Make sure, edge1 is bigger than edge2:
240
+ if edge1 > edge2 then
241
+ edge1 , edge2 = edge2 , edge1
242
+ end
243
+ end
244
+ if min_pos [k ] > edge2 or max_pos [k ] < edge1 then
245
+ ok = false
246
+ break
233
247
end
234
248
end
235
- end
236
-
237
- for _ , obj in ipairs (objects_to_move ) do
238
- local entity = obj :get_luaentity ()
239
- if not entity or not mesecon .is_mvps_unmov (entity .name ) then
240
- local np = vector .add (obj :getpos (), dir )
241
-
242
- -- move only if destination is not solid
243
- local nn = minetest .get_node (np )
244
- if not ((not minetest .registered_nodes [nn .name ])
245
- or minetest .registered_nodes [nn .name ].walkable ) then
246
- obj :setpos (np )
249
+ if ok then
250
+ local ent = obj :get_luaentity ()
251
+ if obj :is_player () or (ent and not mesecon .is_mvps_unmov (ent .name )) then
252
+ local np = vector .add (obj_pos , dir )
253
+ -- Move only if destination is not solid or object is inside stack:
254
+ local nn = minetest .get_node (np )
255
+ local node_def = minetest .registered_nodes [nn .name ]
256
+ local obj_offset = dir_l * (obj_pos [dir_k ] - pos [dir_k ])
257
+ if (node_def and not node_def .walkable ) or
258
+ (obj_offset >= 0 and
259
+ obj_offset <= # nodestack - 0.5 ) then
260
+ obj :move_to (np )
261
+ end
247
262
end
248
263
end
249
264
end
0 commit comments