diff options
author | Uberi <azhang9@gmail.com> | 2014-03-12 16:11:00 -0400 |
---|---|---|
committer | Uberi <azhang9@gmail.com> | 2014-03-12 16:11:00 -0400 |
commit | b29523db4df4d793165672cda8adb3090d8b9ffe (patch) | |
tree | 9687fad3b1a5eba923da970411e74c1b47c5d8dd | |
parent | 0dddffa544eb4aa5d2bcfae09b4f29db011b704d (diff) |
Implement full size checking for every possible command.
-rw-r--r-- | worldedit_commands/init.lua | 520 | ||||
-rw-r--r-- | worldedit_commands/safe.lua | 57 |
2 files changed, 303 insertions, 274 deletions
diff --git a/worldedit_commands/init.lua b/worldedit_commands/init.lua index 7338b7e..e26d40c 100644 --- a/worldedit_commands/init.lua +++ b/worldedit_commands/init.lua @@ -13,6 +13,7 @@ if minetest.place_schematic then end
dofile(minetest.get_modpath("worldedit_commands") .. "/mark.lua")
+dofile(minetest.get_modpath("worldedit_commands") .. "/safe.lua")
local get_position = function(name)
local pos1 = worldedit.pos1[name]
@@ -31,71 +32,6 @@ local get_node = function(name, nodename) return node
end
-
---`callback` is a callback to run when the user confirms
---`nodes_needed` is a function accepting `param`, `pos1`, and `pos2` to calculate the number of nodes needed
-local safe_region
-do --safe region wrapper function
- local safe_region_callback
- local safe_region_name
- local safe_region_param
- safe_region = function(callback, nodes_needed)
- nodes_needed = nodes_needed or worldedit.volume
- return function(name, param)
- --obtain positions
- local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
- if pos1 == nil or pos2 == nil then
- worldedit.player_notify(name, "no region selected")
- return nil
- end
-
- --check volume
- local count = nodes_needed(pos1, pos2, name, param)
- if not count or count < 10000 then
- return callback(name, param, pos1, pos2)
- end
-
- --save callback to call later
- safe_region_callback, safe_region_name, safe_region_param = callback, name, param
- worldedit.player_notify(name, "WARNING: this operation could affect up to " .. count .. " nodes; type //y to continue or //n to cancel")
- end
- end
-
- minetest.register_chatcommand("/y", {
- params = "",
- description = "Confirm a pending operation",
- func = function()
- local callback, name, param = safe_region_callback, safe_region_name, safe_region_param
- if not callback then
- worldedit.player_notify(name, "no operation pending")
- return
- end
-
- --obtain positions
- local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
- if pos1 == nil or pos2 == nil then
- worldedit.player_notify(name, "no region selected")
- return
- end
-
- safe_region_callback, safe_region_name, safe_region_param = nil, nil, nil --reset pending operation
- callback(name, param, pos1, pos2)
- end,
- })
-
- minetest.register_chatcommand("/n", {
- params = "",
- description = "Confirm a pending operation",
- func = function()
- if not safe_region_callback then
- worldedit.player_notify(name, "no operation pending")
- return
- end
- safe_region_callback, safe_region_name, safe_region_param = nil, nil, nil
- end,
- })
-end
-
worldedit.player_notify = function(name, message)
minetest.chat_send_player(name, "WorldEdit -!- " .. message, false)
end
@@ -135,7 +71,16 @@ worldedit.player_axis = function(name) return "z", dir.z > 0 and 1 or -1
end
+local check_region = function(name, param)
+ --obtain positions
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
+ if pos1 == nil or pos2 == nil then
+ worldedit.player_notify(name, "no region selected")
+ return nil
+ end
+ return worldedit.volume(pos1, pos2)
+end
minetest.register_chatcommand("/about", {
params = "",
@@ -344,259 +289,270 @@ minetest.register_chatcommand("/volume", { end,
})
+local check_set = function(name, param)
+ local node = get_node(name, param)
+ if not node then return nil end
+ return check_region(name, param)
+end
+
minetest.register_chatcommand("/set", {
params = "<node>",
description = "Set the current WorldEdit region to <node>",
privs = {worldedit=true},
- func = safe_region(function(name, param, pos1, pos2)
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
local node = get_node(name, param)
- if not node then return end
-
local count = worldedit.set(pos1, pos2, node)
worldedit.player_notify(name, count .. " nodes set")
- end),
+ end, check_set),
})
+local check_replace = function(name, param)
+ local found, _, searchnode, replacenode = param:find("^([^%s]+)%s+(.+)$")
+ if found == nil then
+ worldedit.player_notify(name, "invalid usage: " .. param)
+ return nil
+ end
+ local newsearchnode = worldedit.normalize_nodename(searchnode)
+ if not newsearchnode then
+ worldedit.player_notify(name, "invalid search node name: " .. searchnode)
+ return nil
+ end
+ local newreplacenode = worldedit.normalize_nodename(replacenode)
+ if not newreplacenode then
+ worldedit.player_notify(name, "invalid replace node name: " .. replacenode)
+ return nil
+ end
+ return check_region(name, param)
+end
+
minetest.register_chatcommand("/replace", {
params = "<search node> <replace node>",
description = "Replace all instances of <search node> with <replace node> in the current WorldEdit region",
privs = {worldedit=true},
- func = safe_region(function(name, param, pos1, pos2)
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
local found, _, searchnode, replacenode = param:find("^([^%s]+)%s+(.+)$")
- if found == nil then
- worldedit.player_notify(name, "invalid usage: " .. param)
- return
- end
local newsearchnode = worldedit.normalize_nodename(searchnode)
- if not newsearchnode then
- worldedit.player_notify(name, "invalid search node name: " .. searchnode)
- return
- end
local newreplacenode = worldedit.normalize_nodename(replacenode)
- if not newreplacenode then
- worldedit.player_notify(name, "invalid replace node name: " .. replacenode)
- return
- end
-
local count = worldedit.replace(pos1, pos2, newsearchnode, newreplacenode)
worldedit.player_notify(name, count .. " nodes replaced")
- end),
+ end, check_replace),
})
minetest.register_chatcommand("/replaceinverse", {
params = "<search node> <replace node>",
description = "Replace all nodes other than <search node> with <replace node> in the current WorldEdit region",
privs = {worldedit=true},
- func = safe_region(function(name, param, pos1, pos2)
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
local found, _, searchnode, replacenode = param:find("^([^%s]+)%s+(.+)$")
- if found == nil then
- worldedit.player_notify(name, "invalid usage: " .. param)
- return
- end
local newsearchnode = worldedit.normalize_nodename(searchnode)
- if not newsearchnode then
- worldedit.player_notify(name, "invalid search node name: " .. searchnode)
- return
- end
local newreplacenode = worldedit.normalize_nodename(replacenode)
- if not newreplacenode then
- worldedit.player_notify(name, "invalid replace node name: " .. replacenode)
- return
- end
-
local count = worldedit.replaceinverse(pos1, pos2, searchnode, replacenode)
worldedit.player_notify(name, count .. " nodes replaced")
- end),
+ end, check_replace),
})
+local check_sphere = function(name, param)
+ if worldedit.pos1[name] == nil then
+ worldedit.player_notify(name, "no position 1 selected")
+ return nil
+ end
+ local found, _, radius, nodename = param:find("^(%d+)%s+(.+)$")
+ if found == nil then
+ worldedit.player_notify(name, "invalid usage: " .. param)
+ return nil
+ end
+ local node = get_node(name, nodename)
+ if not node then return nil end
+ return math.ceil((4 * math.pi * (tonumber(radius) ^ 3)) / 3) --volume of sphere
+end
+
minetest.register_chatcommand("/hollowsphere", {
params = "<radius> <node>",
description = "Add hollow sphere centered at WorldEdit position 1 with radius <radius>, composed of <node>",
privs = {worldedit=true},
- func = function(name, param)
- local pos = get_position(name)
- if pos == nil then return end
-
+ func = safe_region(function(name, param)
+ local pos = worldedit.pos1[name]
local found, _, radius, nodename = param:find("^(%d+)%s+(.+)$")
- if found == nil then
- worldedit.player_notify(name, "invalid usage: " .. param)
- return
- end
local node = get_node(name, nodename)
- if not node then return end
-
local count = worldedit.hollow_sphere(pos, tonumber(radius), node)
worldedit.player_notify(name, count .. " nodes added")
- end,
+ end, check_sphere),
})
minetest.register_chatcommand("/sphere", {
params = "<radius> <node>",
description = "Add sphere centered at WorldEdit position 1 with radius <radius>, composed of <node>",
privs = {worldedit=true},
- func = function(name, param)
- local pos = get_position(name)
- if pos == nil then return end
-
+ func = safe_region(function(name, param)
+ local pos = worldedit.pos1[name]
local found, _, radius, nodename = param:find("^(%d+)%s+(.+)$")
- if found == nil then
- worldedit.player_notify(name, "invalid usage: " .. param)
- return
- end
local node = get_node(name, nodename)
- if not node then return end
-
local count = worldedit.sphere(pos, tonumber(radius), node)
worldedit.player_notify(name, count .. " nodes added")
- end,
+ end, check_sphere),
})
+local check_dome = function(name, param)
+ if worldedit.pos1[name] == nil then
+ worldedit.player_notify(name, "no position 1 selected")
+ return nil
+ end
+ local found, _, radius, nodename = param:find("^(%d+)%s+(.+)$")
+ if found == nil then
+ worldedit.player_notify(name, "invalid usage: " .. param)
+ return nil
+ end
+ local node = get_node(name, nodename)
+ if not node then return nil end
+ return math.ceil((2 * math.pi * (tonumber(radius) ^ 3)) / 3) --volume of dome
+end
+
minetest.register_chatcommand("/hollowdome", {
params = "<radius> <node>",
description = "Add hollow dome centered at WorldEdit position 1 with radius <radius>, composed of <node>",
privs = {worldedit=true},
- func = function(name, param)
- local pos = get_position(name)
- if pos == nil then return end
-
- local found, _, radius, nodename = param:find("^([+-]?%d+)%s+(.+)$")
- if found == nil then
- worldedit.player_notify(name, "invalid usage: " .. param)
- return
- end
+ func = safe_region(function(name, param)
+ local pos = worldedit.pos1[name]
+ local found, _, radius, nodename = param:find("^(%d+)%s+(.+)$")
local node = get_node(name, nodename)
- if not node then return end
-
local count = worldedit.hollow_dome(pos, tonumber(radius), node)
worldedit.player_notify(name, count .. " nodes added")
- end,
+ end, check_dome),
})
minetest.register_chatcommand("/dome", {
params = "<radius> <node>",
description = "Add dome centered at WorldEdit position 1 with radius <radius>, composed of <node>",
privs = {worldedit=true},
- func = function(name, param)
- local pos = get_position(name)
- if pos == nil then return end
-
- local found, _, radius, nodename = param:find("^([+-]?%d+)%s+(.+)$")
- if found == nil then
- worldedit.player_notify(name, "invalid usage: " .. param)
- return
- end
+ func = safe_region(function(name, param)
+ local pos = worldedit.pos1[name]
+ local found, _, radius, nodename = param:find("^(%d+)%s+(.+)$")
local node = get_node(name, nodename)
- if not node then return end
-
local count = worldedit.dome(pos, tonumber(radius), node)
worldedit.player_notify(name, count .. " nodes added")
- end,
+ end, check_dome),
})
+local check_cylinder = function(name, param)
+ if worldedit.pos1[name] == nil then
+ worldedit.player_notify(name, "no position 1 selected")
+ return nil
+ end
+ local found, _, axis, length, radius, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(.+)$")
+ if found == nil then
+ worldedit.player_notify(name, "invalid usage: " .. param)
+ return nil
+ end
+ local node = get_node(name, nodename)
+ if not node then return nil end
+ return math.ceil(math.pi * (tonumber(radius) ^ 2) * tonumber(length))
+end
+
minetest.register_chatcommand("/hollowcylinder", {
params = "x/y/z/? <length> <radius> <node>",
description = "Add hollow cylinder at WorldEdit position 1 along the x/y/z/? axis with length <length> and radius <radius>, composed of <node>",
privs = {worldedit=true},
- func = function(name, param)
- local pos = get_position(name)
- if pos == nil then return end
-
+ func = safe_region(function(name, param)
+ local pos = worldedit.pos1[name]
local found, _, axis, length, radius, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(.+)$")
- if found == nil then
- worldedit.player_notify(name, "invalid usage: " .. param)
- return
- end
- length, radius = tonumber(length), tonumber(radius)
+ length = tonumber(length)
if axis == "?" then
axis, sign = worldedit.player_axis(name)
length = length * sign
end
local node = get_node(name, nodename)
- if not node then return end
-
- local count = worldedit.hollow_cylinder(pos, axis, length, radius, node)
+ local count = worldedit.hollow_cylinder(pos, axis, length, tonumber(radius), node)
worldedit.player_notify(name, count .. " nodes added")
- end,
+ end, check_cylinder),
})
minetest.register_chatcommand("/cylinder", {
params = "x/y/z/? <length> <radius> <node>",
description = "Add cylinder at WorldEdit position 1 along the x/y/z/? axis with length <length> and radius <radius>, composed of <node>",
privs = {worldedit=true},
- func = function(name, param)
- local pos = get_position(name)
- if pos == nil then return end
-
+ func = safe_region(function(name, param)
+ local pos = worldedit.pos1[name]
local found, _, axis, length, radius, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(.+)$")
- if found == nil then
- worldedit.player_notify(name, "invalid usage: " .. param)
- return
- end
- length, radius = tonumber(length), tonumber(radius)
+ length = tonumber(length)
if axis == "?" then
axis, sign = worldedit.player_axis(name)
length = length * sign
end
local node = get_node(name, nodename)
- if not node then return end
-
- local count = worldedit.cylinder(pos, axis, length, radius, node)
+ local count = worldedit.cylinder(pos, axis, length, tonumber(radius), node)
worldedit.player_notify(name, count .. " nodes added")
- end,
+ end, check_cylinder),
})
minetest.register_chatcommand("/pyramid", {
params = "x/y/z/? <height> <node>",
description = "Add pyramid centered at WorldEdit position 1 along the x/y/z/? axis with height <height>, composed of <node>",
privs = {worldedit=true},
- func = function(name, param)
+ func = safe_region(function(name, param)
local pos = get_position(name)
- if pos == nil then return end
-
local found, _, axis, height, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(.+)$")
- if found == nil then
- worldedit.player_notify(name, "invalid usage: " .. param)
- return
- end
height = tonumber(height)
if axis == "?" then
axis, sign = worldedit.player_axis(name)
height = height * sign
end
local node = get_node(name, nodename)
- if not node then return end
-
local count = worldedit.pyramid(pos, axis, height, node)
worldedit.player_notify(name, count .. " nodes added")
end,
+ function(name, param)
+ if worldedit.pos1[name] == nil then
+ worldedit.player_notify(name, "no position 1 selected")
+ return nil
+ end
+ local found, _, axis, height, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(.+)$")
+ if found == nil then
+ worldedit.player_notify(name, "invalid usage: " .. param)
+ return nil
+ end
+ local node = get_node(name, nodename)
+ if not node then return nil end
+ height = tonumber(height)
+ return math.ceil(((height * 2 + 1) ^ 2) * height / 3)
+ end),
})
minetest.register_chatcommand("/spiral", {
params = "<length> <height> <space> <node>",
description = "Add spiral centered at WorldEdit position 1 with side length <length>, height <height>, space between walls <space>, composed of <node>",
privs = {worldedit=true},
- func = function(name, param)
- local pos = get_position(name)
- if pos == nil then return end
-
+ func = safe_region(function(name, param)
+ local pos = worldedit.pos1[name]
local found, _, length, height, space, nodename = param:find("^(%d+)%s+(%d+)%s+(%d+)%s+(.+)$")
- if found == nil then
- worldedit.player_notify(name, "invalid usage: " .. param)
- return
- end
local node = get_node(name, nodename)
- if not node then return end
-
local count = worldedit.spiral(pos, tonumber(length), tonumber(height), tonumber(space), node)
worldedit.player_notify(name, count .. " nodes added")
end,
+ function(name, param)
+ if worldedit.pos1[name] == nil then
+ worldedit.player_notify(name, "no position 1 selected")
+ return nil
+ end
+ local found, _, length, height, space, nodename = param:find("^(%d+)%s+(%d+)%s+(%d+)%s+(.+)$")
+ if found == nil then
+ worldedit.player_notify(name, "invalid usage: " .. param)
+ return nil
+ end
+ local node = get_node(name, nodename)
+ if not node then return nil end
+ return check_region(name, param)
+ end),
})
minetest.register_chatcommand("/copy", {
params = "x/y/z/? <amount>",
description = "Copy the current WorldEdit region along the x/y/z/? axis by <amount> nodes",
privs = {worldedit=true},
- func = safe_region(function(name, param, pos1, pos2)
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
local found, _, axis, amount = param:find("^([xyz%?])%s+([+-]?%d+)$")
if found == nil then
worldedit.player_notify(name, "invalid usage: " .. param)
@@ -610,6 +566,10 @@ minetest.register_chatcommand("/copy", { local count = worldedit.copy(pos1, pos2, axis, amount)
worldedit.player_notify(name, count .. " nodes copied")
+ end,
+ function(name, param)
+ local volume = check_region(name, param)
+ return volume and volume * 2 or volume
end),
})
@@ -617,7 +577,8 @@ minetest.register_chatcommand("/move", { params = "x/y/z/? <amount>",
description = "Move the current WorldEdit region along the x/y/z/? axis by <amount> nodes",
privs = {worldedit=true},
- func = safe_region(function(name, param, pos1, pos2)
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
local found, _, axis, amount = param:find("^([xyz%?])%s+([+-]?%d+)$")
if found == nil then
worldedit.player_notify(name, "invalid usage: " .. param)
@@ -636,33 +597,32 @@ minetest.register_chatcommand("/move", { worldedit.mark_pos1(name)
worldedit.mark_pos2(name)
worldedit.player_notify(name, count .. " nodes moved")
- end),
+ end, check_region),
})
minetest.register_chatcommand("/stack", {
params = "x/y/z/? <count>",
description = "Stack the current WorldEdit region along the x/y/z/? axis <count> times",
privs = {worldedit=true},
- func = safe_region(function(name, param, pos1, pos2)
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
local found, _, axis, repetitions = param:find("^([xyz%?])%s+([+-]?%d+)$")
- if found == nil then
- worldedit.player_notify(name, "invalid usage: " .. param)
- return
- end
repetitions = tonumber(repetitions)
if axis == "?" then
axis, sign = worldedit.player_axis(name)
repetitions = repetitions * sign
end
-
local count = worldedit.stack(pos1, pos2, axis, repetitions)
worldedit.player_notify(name, count .. " nodes stacked")
end,
- function(pos1, pos2, name, param)
+ function(name, param)
local found, _, axis, repetitions = param:find("^([xyz%?])%s+([+-]?%d+)$")
- if found then
- return tonumber(repetitions) * worldedit.volume(pos1, pos2)
+ if found == nil then
+ worldedit.player_notify(name, "invalid usage: " .. param)
end
+ local count = check_region(name, param)
+ if count then return (tonumber(repetitions) + 1) * count end
+ return nil
end),
})
@@ -670,17 +630,10 @@ minetest.register_chatcommand("/stretch", { params = "<stretchx> <stretchy> <stretchz>",
description = "Scale the current WorldEdit positions and region by a factor of <stretchx>, <stretchy>, <stretchz> along the X, Y, and Z axes, repectively, with position 1 as the origin",
privs = {worldedit=true},
- func = safe_region(function(name, param, pos1, pos2)
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
local found, _, stretchx, stretchy, stretchz = param:find("^(%d+)%s+(%d+)%s+(%d+)$")
- if found == nil then
- worldedit.player_notify(name, "invalid usage: " .. param)
- return
- end
stretchx, stretchy, stretchz = tonumber(stretchx), tonumber(stretchy), tonumber(stretchz)
- if stretchx == 0 or stretchy == 0 or stretchz == 0 then
- worldedit.player_notify(name, "invalid scaling factors: " .. param)
- end
-
local count, pos1, pos2 = worldedit.stretch(pos1, pos2, stretchx, stretchy, stretchz)
--reset markers to scaled positions
@@ -691,11 +644,19 @@ minetest.register_chatcommand("/stretch", { worldedit.player_notify(name, count .. " nodes stretched")
end,
- function(pos1, pos2, name, param)
+ function(name, param)
local found, _, stretchx, stretchy, stretchz = param:find("^(%d+)%s+(%d+)%s+(%d+)$")
- if found then
- return tonumber(stretchx) * tonumber(stretchy) * tonumber(stretchz) * worldedit.volume(pos1, pos2)
+ if found == nil then
+ worldedit.player_notify(name, "invalid usage: " .. param)
+ return nil
end
+ stretchx, stretchy, stretchz = tonumber(stretchx), tonumber(stretchy), tonumber(stretchz)
+ if stretchx == 0 or stretchy == 0 or stretchz == 0 then
+ worldedit.player_notify(name, "invalid scaling factors: " .. param)
+ end
+ local count = check_region(name, param)
+ if count then return tonumber(stretchx) * tonumber(stretchy) * tonumber(stretchz) * count end
+ return nil
end),
})
@@ -703,23 +664,11 @@ minetest.register_chatcommand("/transpose", { params = "x/y/z/? x/y/z/?",
description = "Transpose the current WorldEdit region along the x/y/z/? and x/y/z/? axes",
privs = {worldedit=true},
- func = safe_region(function(name, param, pos1, pos2)
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
local found, _, axis1, axis2 = param:find("^([xyz%?])%s+([xyz%?])$")
- if found == nil then
- worldedit.player_notify(name, "invalid usage: " .. param)
- return
- end
- if axis1 == "?" then
- axis1 = worldedit.player_axis(name)
- end
- if axis2 == "?" then
- axis2 = worldedit.player_axis(name)
- end
- if axis1 == axis2 then
- worldedit.player_notify(name, "invalid usage: axes must be different")
- return
- end
-
+ if axis1 == "?" then axis1 = worldedit.player_axis(name) end
+ if axis2 == "?" then axis2 = worldedit.player_axis(name) end
local count, pos1, pos2 = worldedit.transpose(pos1, pos2, axis1, axis2)
--reset markers to transposed positions
@@ -729,6 +678,18 @@ minetest.register_chatcommand("/transpose", { worldedit.mark_pos2(name)
worldedit.player_notify(name, count .. " nodes transposed")
+ end,
+ function(name, param)
+ local found, _, axis1, axis2 = param:find("^([xyz%?])%s+([xyz%?])$")
+ if found == nil then
+ worldedit.player_notify(name, "invalid usage: " .. param)
+ return nil
+ end
+ if axis1 == axis2 then
+ worldedit.player_notify(name, "invalid usage: axes must be different")
+ return nil
+ end
+ return check_region(name, param)
end),
})
@@ -736,17 +697,18 @@ minetest.register_chatcommand("/flip", { params = "x/y/z/?",
description = "Flip the current WorldEdit region along the x/y/z/? axis",
privs = {worldedit=true},
- func = safe_region(function(name, param, pos1, pos2)
- if param == "?" then
- param = worldedit.player_axis(name)
- end
- if param ~= "x" and param ~= "y" and param ~= "z" then
- worldedit.player_notify(name, "invalid usage: " .. param)
- return
- end
-
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
+ if param == "?" then param = worldedit.player_axis(name) end
local count = worldedit.flip(pos1, pos2, param)
worldedit.player_notify(name, count .. " nodes flipped")
+ end,
+ function(name, param)
+ if param ~= "x" and param ~= "y" and param ~= "z" and param ~= "?" then
+ worldedit.player_notify(name, "invalid usage: " .. param)
+ return nil
+ end
+ return check_region(name, param)
end),
})
@@ -754,20 +716,10 @@ minetest.register_chatcommand("/rotate", { params = "<axis> <angle>",
description = "Rotate the current WorldEdit region around the axis <axis> by angle <angle> (90 degree increment)",
privs = {worldedit=true},
- func = safe_region(function(name, param, pos1, pos2)
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
local found, _, axis, angle = param:find("^([xyz%?])%s+([+-]?%d+)$")
- if found == nil then
- worldedit.player_notify(name, "invalid usage: " .. param)
- return
- end
- if axis == "?" then
- axis = worldedit.player_axis(name)
- end
- if angle % 90 ~= 0 then
- worldedit.player_notify(name, "invalid usage: angle must be multiple of 90")
- return
- end
-
+ if axis == "?" then axis = worldedit.player_axis(name) end
local count, pos1, pos2 = worldedit.rotate(pos1, pos2, axis, angle)
--reset markers to rotated positions
@@ -777,6 +729,18 @@ minetest.register_chatcommand("/rotate", { worldedit.mark_pos2(name)
worldedit.player_notify(name, count .. " nodes rotated")
+ end,
+ function(name, param)
+ local found, _, axis, angle = param:find("^([xyz%?])%s+([+-]?%d+)$")
+ if found == nil then
+ worldedit.player_notify(name, "invalid usage: " .. param)
+ return nil
+ end
+ if angle % 90 ~= 0 then
+ worldedit.player_notify(name, "invalid usage: angle must be multiple of 90")
+ return nil
+ end
+ return check_region(name, param)
end),
})
@@ -784,20 +748,23 @@ minetest.register_chatcommand("/orient", { params = "<angle>",
description = "Rotate oriented nodes in the current WorldEdit region around the Y axis by angle <angle> (90 degree increment)",
privs = {worldedit=true},
- func = safe_region(function(name, param, pos1, pos2)
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
+ local found, _, angle = param:find("^([+-]?%d+)$")
+ local count = worldedit.orient(pos1, pos2, angle)
+ worldedit.player_notify(name, count .. " nodes oriented")
+ end,
+ function(name, param)
local found, _, angle = param:find("^([+-]?%d+)$")
if found == nil then
worldedit.player_notify(name, "invalid usage: " .. param)
- return
+ return nil
end
if angle % 90 ~= 0 then
worldedit.player_notify(name, "invalid usage: angle must be multiple of 90")
- return
+ return nil
end
-
- local count = worldedit.orient(pos1, pos2, angle)
-
- worldedit.player_notify(name, count .. " nodes oriented")
+ return check_region(name, param)
end),
})
@@ -805,7 +772,8 @@ minetest.register_chatcommand("/fixlight", { params = "",
description = "Fix the lighting in the current WorldEdit region",
privs = {worldedit=true},
- func = safe_region(function(name, param, pos1, pos2)
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
local count = worldedit.fixlight(pos1, pos2)
worldedit.player_notify(name, count .. " nodes updated")
end),
@@ -815,7 +783,8 @@ minetest.register_chatcommand("/hide", { params = "",
description = "Hide all nodes in the current WorldEdit region non-destructively",
privs = {worldedit=true},
- func = safe_region(function(name, param, pos1, pos2)
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
local count = worldedit.hide(pos1, pos2)
worldedit.player_notify(name, count .. " nodes hidden")
end),
@@ -825,33 +794,32 @@ minetest.register_chatcommand("/suppress", { params = "<node>",
description = "Suppress all <node> in the current WorldEdit region non-destructively",
privs = {worldedit=true},
- func = safe_region(function(name, param, pos1, pos2)
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
local node = get_node(name, param)
- if not node then return end
-
local count = worldedit.suppress(pos1, pos2, node)
worldedit.player_notify(name, count .. " nodes suppressed")
- end),
+ end, check_set),
})
minetest.register_chatcommand("/highlight", {
params = "<node>",
description = "Highlight <node> in the current WorldEdit region by hiding everything else non-destructively",
privs = {worldedit=true},
- func = safe_region(function(name, param, pos1, pos2)
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
local node = get_node(name, param)
- if not node then return end
-
local count = worldedit.highlight(pos1, pos2, node)
worldedit.player_notify(name, count .. " nodes highlighted")
- end),
+ end, check_set),
})
minetest.register_chatcommand("/restore", {
params = "",
description = "Restores nodes hidden with WorldEdit in the current WorldEdit region",
privs = {worldedit=true},
- func = safe_region(function(name, param, pos1, pos2)
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
local count = worldedit.restore(pos1, pos2)
worldedit.player_notify(name, count .. " nodes restored")
end),
@@ -861,7 +829,8 @@ minetest.register_chatcommand("/save", { params = "<file>",
description = "Save the current WorldEdit region to \"(world folder)/schems/<file>.we\"",
privs = {worldedit=true},
- func = safe_region(function(name, param, pos1, pos2)
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
if param == "" then
worldedit.player_notify(name, "invalid usage: " .. param)
return
@@ -1002,7 +971,8 @@ minetest.register_chatcommand("/luatransform", { params = "<code>",
description = "Executes <code> as a Lua chunk in the global namespace with the variable pos available, for each node in the current WorldEdit region",
privs = {worldedit=true, server=true},
- func = safe_region(function(name, param, pos1, pos2)
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
local admin = minetest.setting_get("name")
if not admin or not name == admin then
worldedit.player_notify(name, "this command can only be run by the server administrator")
@@ -1022,7 +992,8 @@ minetest.register_chatcommand("/mtschemcreate", { params = "<file>",
description = "Save the current WorldEdit region using the Minetest Schematic format to \"(world folder)/schems/<filename>.mts\"",
privs = {worldedit=true},
- func = safe_region(function(name, param, pos1, pos2)
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
if param == nil then
worldedit.player_notify(name, "No filename specified")
return
@@ -1111,7 +1082,8 @@ minetest.register_chatcommand("/clearobjects", { params = "",
description = "Clears all objects within the WorldEdit region",
privs = {worldedit=true},
- func = safe_region(function(name, param, pos1, pos2)
+ func = safe_region(function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
local count = worldedit.clearobjects(pos1, pos2)
worldedit.player_notify(name, count .. " objects cleared")
end),
diff --git a/worldedit_commands/safe.lua b/worldedit_commands/safe.lua new file mode 100644 index 0000000..6f83078 --- /dev/null +++ b/worldedit_commands/safe.lua @@ -0,0 +1,57 @@ +local safe_region_callback
+local safe_region_name
+local safe_region_param
+
+--`callback` is a callback to run when the user confirms
+--`nodes_needed` is a function accepting `param`, `pos1`, and `pos2` to calculate the number of nodes needed
+safe_region = function(callback, nodes_needed)
+ --default node volume calculation
+ nodes_needed = nodes_needed or check_region
+
+ return function(name, param)
+ --check if the operation applies to a safe number of nodes
+ local count = nodes_needed(name, param)
+ if count == nil then return end --invalid command
+ if count < 10000 then
+ return callback(name, param)
+ end
+
+ --save callback to call later
+ safe_region_callback, safe_region_name, safe_region_param = callback, name, param
+ worldedit.player_notify(name, "WARNING: this operation could affect up to " .. count .. " nodes; type //y to continue or //n to cancel")
+ end
+end
+
+minetest.register_chatcommand("/y", {
+ params = "",
+ description = "Confirm a pending operation",
+ func = function()
+ local callback, name, param = safe_region_callback, safe_region_name, safe_region_param
+ if not callback then
+ worldedit.player_notify(name, "no operation pending")
+ return
+ end
+
+ --obtain positions
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
+ if pos1 == nil or pos2 == nil then
+ worldedit.player_notify(name, "no region selected")
+ return
+ end
+
+ safe_region_callback, safe_region_name, safe_region_param = nil, nil, nil --reset pending operation
+ callback(name, param, pos1, pos2)
+ end,
+})
+
+minetest.register_chatcommand("/n", {
+ params = "",
+ description = "Confirm a pending operation",
+ func = function()
+ if not safe_region_callback then
+ worldedit.player_notify(name, "no operation pending")
+ return
+ end
+ safe_region_callback, safe_region_name, safe_region_param = nil, nil, nil
+ end,
+})
|