visualization.lua 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. --- Functions for visibly hiding nodes
  2. -- @module worldedit.visualization
  3. minetest.register_node("worldedit:placeholder", {
  4. drawtype = "airlike",
  5. paramtype = "light",
  6. sunlight_propagates = true,
  7. diggable = false,
  8. walkable = false,
  9. groups = {not_in_creative_inventory=1},
  10. })
  11. --- Hides all nodes in a region defined by positions `pos1` and `pos2` by
  12. -- non-destructively replacing them with invisible nodes.
  13. -- @return The number of nodes hidden.
  14. function worldedit.hide(pos1, pos2)
  15. pos1, pos2 = worldedit.sort_pos(pos1, pos2)
  16. worldedit.keep_loaded(pos1, pos2)
  17. local pos = {x=pos1.x, y=0, z=0}
  18. local get_node, get_meta, swap_node = minetest.get_node,
  19. minetest.get_meta, minetest.swap_node
  20. while pos.x <= pos2.x do
  21. pos.y = pos1.y
  22. while pos.y <= pos2.y do
  23. pos.z = pos1.z
  24. while pos.z <= pos2.z do
  25. local node = get_node(pos)
  26. if node.name ~= "air" and node.name ~= "worldedit:placeholder" then
  27. -- Save the node's original name
  28. get_meta(pos):set_string("worldedit_placeholder", node.name)
  29. -- Swap in placeholder node
  30. node.name = "worldedit:placeholder"
  31. swap_node(pos, node)
  32. end
  33. pos.z = pos.z + 1
  34. end
  35. pos.y = pos.y + 1
  36. end
  37. pos.x = pos.x + 1
  38. end
  39. return worldedit.volume(pos1, pos2)
  40. end
  41. --- Suppresses all instances of `node_name` in a region defined by positions
  42. -- `pos1` and `pos2` by non-destructively replacing them with invisible nodes.
  43. -- @return The number of nodes suppressed.
  44. function worldedit.suppress(pos1, pos2, node_name)
  45. -- Ignore placeholder supression
  46. if node_name == "worldedit:placeholder" then
  47. return 0
  48. end
  49. pos1, pos2 = worldedit.sort_pos(pos1, pos2)
  50. worldedit.keep_loaded(pos1, pos2)
  51. local nodes = minetest.find_nodes_in_area(pos1, pos2, node_name)
  52. local get_node, get_meta, swap_node = minetest.get_node,
  53. minetest.get_meta, minetest.swap_node
  54. for _, pos in ipairs(nodes) do
  55. local node = get_node(pos)
  56. -- Save the node's original name
  57. get_meta(pos):set_string("worldedit_placeholder", node.name)
  58. -- Swap in placeholder node
  59. node.name = "worldedit:placeholder"
  60. swap_node(pos, node)
  61. end
  62. return #nodes
  63. end
  64. --- Highlights all instances of `node_name` in a region defined by positions
  65. -- `pos1` and `pos2` by non-destructively hiding all other nodes.
  66. -- @return The number of nodes found.
  67. function worldedit.highlight(pos1, pos2, node_name)
  68. pos1, pos2 = worldedit.sort_pos(pos1, pos2)
  69. worldedit.keep_loaded(pos1, pos2)
  70. local pos = {x=pos1.x, y=0, z=0}
  71. local get_node, get_meta, swap_node = minetest.get_node,
  72. minetest.get_meta, minetest.swap_node
  73. local count = 0
  74. while pos.x <= pos2.x do
  75. pos.y = pos1.y
  76. while pos.y <= pos2.y do
  77. pos.z = pos1.z
  78. while pos.z <= pos2.z do
  79. local node = get_node(pos)
  80. if node.name == node_name then -- Node found
  81. count = count + 1
  82. elseif node.name ~= "worldedit:placeholder" then -- Hide other nodes
  83. -- Save the node's original name
  84. get_meta(pos):set_string("worldedit_placeholder", node.name)
  85. -- Swap in placeholder node
  86. node.name = "worldedit:placeholder"
  87. swap_node(pos, node)
  88. end
  89. pos.z = pos.z + 1
  90. end
  91. pos.y = pos.y + 1
  92. end
  93. pos.x = pos.x + 1
  94. end
  95. return count
  96. end
  97. -- Restores all nodes hidden with WorldEdit functions in a region defined
  98. -- by positions `pos1` and `pos2`.
  99. -- @return The number of nodes restored.
  100. function worldedit.restore(pos1, pos2)
  101. local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
  102. worldedit.keep_loaded(pos1, pos2)
  103. local nodes = minetest.find_nodes_in_area(pos1, pos2, "worldedit:placeholder")
  104. local get_node, get_meta, swap_node = minetest.get_node,
  105. minetest.get_meta, minetest.swap_node
  106. for _, pos in ipairs(nodes) do
  107. local node = get_node(pos)
  108. local meta = get_meta(pos)
  109. local data = meta:to_table()
  110. node.name = data.fields.worldedit_placeholder
  111. data.fields.worldedit_placeholder = nil
  112. meta:from_table(data)
  113. swap_node(pos, node)
  114. end
  115. return #nodes
  116. end