find_ground.lua 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. local cache = {}
  2. local function is_walkable(cid)
  3. local cached = cache[cid]
  4. if cached ~= nil then return cached end
  5. local n = minetest.get_name_from_content_id(cid)
  6. local d = minetest.registered_nodes[n]
  7. if not d then return nil end
  8. cache[cid] = (d.walkable == true)
  9. return (d.walkable == true)
  10. end
  11. function hb4.find_walkable_in_area_under_unwalkable(minp, maxp)
  12. -- Adjust max Y up 1 node (because we need to check node-above for each pos).
  13. maxp = vector.add(maxp, {x=0, y=1, z=0})
  14. local voxel = VoxelManip()
  15. local emin, emax = voxel:read_from_map(minp, maxp)
  16. local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax})
  17. local data = voxel:get_data()
  18. -- Will store the positions of ground nodes.
  19. local targets = {}
  20. for x = minp.x, maxp.x, 1 do
  21. for y = minp.y, (maxp.y - 1), 1 do
  22. for z = minp.z, maxp.z, 1 do
  23. local v1 = area:index(x, y, z)
  24. local v2 = area:index(x, y + 1, z)
  25. local d1 = data[v1]
  26. local d2 = data[v2]
  27. local w1 = is_walkable(d1)
  28. local w2 = is_walkable(d2)
  29. -- A nil return means the node is undefined.
  30. if w1 == true and w2 == false then
  31. targets[#targets + 1] = {x=x, y=y+1, z=z}
  32. end
  33. end
  34. end
  35. end
  36. return targets
  37. end