]> git.lizzy.rs Git - worldedit.git/commitdiff
Implement //clearcut to delete trees, plants from generated terrain
authorsfan5 <sfan5@live.de>
Tue, 7 Apr 2020 01:05:30 +0000 (03:05 +0200)
committersfan5 <sfan5@live.de>
Tue, 7 Apr 2020 01:05:30 +0000 (03:05 +0200)
closes #165

ChatCommands.md
worldedit_commands/init.lua

index 3cd349c86b434205abc2aa5f7a7b13ee938a31bf..10668ce27b0e83d0161b850bdfd2146b58f5876a 100644 (file)
@@ -341,6 +341,14 @@ Removes any fluid node within the current WorldEdit region.
 \r
     //drain\r
 \r
+### `//clearcut`\r
+\r
+Removes any plant, tree or foilage-like nodes in the selected region.\r
+The idea is to remove anything that isn't part of the terrain, leaving a "natural" empty space ready for building.\r
+\r
+    //clearcut\r
+\r
+\r
 ### `//hide`\r
 \r
 Hide all nodes in the current WorldEdit region non-destructively.\r
index 32bbc6c1e98abb566a3596e66e44aea86207e310..cda517c0db2b64145508a9b73e0479975428b28d 100644 (file)
@@ -1180,6 +1180,85 @@ worldedit.register_command("drain", {
        end,\r
 })\r
 \r
+local clearcut_cache\r
+\r
+local function clearcut(pos1, pos2)\r
+       -- decide which nodes we consider plants\r
+       if clearcut_cache == nil then\r
+               clearcut_cache = {}\r
+               for name, def in pairs(minetest.registered_nodes) do\r
+                       local groups = def.groups or {}\r
+                       if (\r
+                               -- the groups say so\r
+                               groups.flower or groups.grass or groups.flora or groups.plant or\r
+                               groups.leaves or groups.tree or groups.leafdecay or groups.sapling or\r
+                               -- drawtype heuristic\r
+                               (def.is_ground_content and def.buildable_to and\r
+                                       (def.sunlight_propagates or not def.walkable)\r
+                                       and def.drawtype == "plantlike") or\r
+                               -- if it's flammable, it probably needs to go too\r
+                               (def.is_ground_content and not def.walkable and groups.flammable)\r
+                       ) then\r
+                               clearcut_cache[name] = true\r
+                       end\r
+               end\r
+       end\r
+       local plants = clearcut_cache\r
+\r
+       local count = 0\r
+       local prev, any\r
+\r
+       for x = pos1.x, pos2.x do\r
+       for z = pos1.z, pos2.z do\r
+               prev = false\r
+               any = false\r
+               -- first pass: remove floating nodes that would be left over\r
+               for y = pos1.y, pos2.y do\r
+                       local n = minetest.get_node({x=x, y=y, z=z}).name\r
+                       if plants[n] then\r
+                               prev = true\r
+                               any = true\r
+                       elseif prev then\r
+                               local def = minetest.registered_nodes[n] or {}\r
+                               local groups = def.groups or {}\r
+                               if groups.attached_node or (def.buildable_to and groups.falling_node) then\r
+                                       minetest.remove_node({x=x, y=y, z=z})\r
+                                       count = count + 1\r
+                               else\r
+                                       prev = false\r
+                               end\r
+                       end\r
+               end\r
+\r
+               -- second pass: remove plants, top-to-bottom to avoid item drops\r
+               if any then\r
+                       for y = pos2.y, pos1.y, -1 do\r
+                               local n = minetest.get_node({x=x, y=y, z=z}).name\r
+                               if plants[n] then\r
+                                       minetest.remove_node({x=x, y=y, z=z})\r
+                                       count = count + 1\r
+                               end\r
+                       end\r
+               end\r
+       end\r
+       end\r
+\r
+       return count\r
+end\r
+\r
+worldedit.register_command("clearcut", {\r
+       params = "",\r
+       description = "Remove any plant, tree or foilage-like nodes in the selected region",\r
+       privs = {worldedit=true},\r
+       require_pos = 2,\r
+       nodes_needed = check_region,\r
+       func = function(name)\r
+               local pos1, pos2 = worldedit.sort_pos(worldedit.pos1[name], worldedit.pos2[name])\r
+               local count = clearcut(pos1, pos2)\r
+               worldedit.player_notify(name, count .. " nodes removed")\r
+       end,\r
+})\r
+\r
 worldedit.register_command("hide", {\r
        params = "",\r
        description = "Hide all nodes in the current WorldEdit region non-destructively",\r