visualization.lua 4.0 KB

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