Skip to content

Commit

Permalink
Implement //clearcut to delete trees, plants from generated terrain
Browse files Browse the repository at this point in the history
closes #165
  • Loading branch information
sfan5 committed Apr 7, 2020
1 parent 37de177 commit 0f5dcc7
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
8 changes: 8 additions & 0 deletions ChatCommands.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,14 @@ Removes any fluid node within the current WorldEdit region.

//drain

### `//clearcut`

Removes any plant, tree or foilage-like nodes in the selected region.
The idea is to remove anything that isn't part of the terrain, leaving a "natural" empty space ready for building.

//clearcut


### `//hide`

Hide all nodes in the current WorldEdit region non-destructively.
Expand Down
79 changes: 79 additions & 0 deletions worldedit_commands/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,85 @@ worldedit.register_command("drain", {
end,
})

local clearcut_cache

local function clearcut(pos1, pos2)
-- decide which nodes we consider plants
if clearcut_cache == nil then
clearcut_cache = {}
for name, def in pairs(minetest.registered_nodes) do
local groups = def.groups or {}
if (
-- the groups say so
groups.flower or groups.grass or groups.flora or groups.plant or
groups.leaves or groups.tree or groups.leafdecay or groups.sapling or
-- drawtype heuristic
(def.is_ground_content and def.buildable_to and
(def.sunlight_propagates or not def.walkable)
and def.drawtype == "plantlike") or
-- if it's flammable, it probably needs to go too
(def.is_ground_content and not def.walkable and groups.flammable)
) then
clearcut_cache[name] = true
end
end
end
local plants = clearcut_cache

local count = 0
local prev, any

for x = pos1.x, pos2.x do
for z = pos1.z, pos2.z do
prev = false
any = false
-- first pass: remove floating nodes that would be left over
for y = pos1.y, pos2.y do
local n = minetest.get_node({x=x, y=y, z=z}).name
if plants[n] then
prev = true
any = true
elseif prev then
local def = minetest.registered_nodes[n] or {}
local groups = def.groups or {}
if groups.attached_node or (def.buildable_to and groups.falling_node) then
minetest.remove_node({x=x, y=y, z=z})
count = count + 1
else
prev = false
end
end
end

-- second pass: remove plants, top-to-bottom to avoid item drops
if any then
for y = pos2.y, pos1.y, -1 do
local n = minetest.get_node({x=x, y=y, z=z}).name
if plants[n] then
minetest.remove_node({x=x, y=y, z=z})
count = count + 1
end
end
end
end
end

return count
end

worldedit.register_command("clearcut", {
params = "",
description = "Remove any plant, tree or foilage-like nodes in the selected region",
privs = {worldedit=true},
require_pos = 2,
nodes_needed = check_region,
func = function(name)
local pos1, pos2 = worldedit.sort_pos(worldedit.pos1[name], worldedit.pos2[name])
local count = clearcut(pos1, pos2)
worldedit.player_notify(name, count .. " nodes removed")
end,
})

worldedit.register_command("hide", {
params = "",
description = "Hide all nodes in the current WorldEdit region non-destructively",
Expand Down

0 comments on commit 0f5dcc7

Please sign in to comment.