summaryrefslogtreecommitdiff
path: root/worldedit_commands
diff options
context:
space:
mode:
Diffstat (limited to 'worldedit_commands')
-rw-r--r--worldedit_commands/init.lua145
-rw-r--r--worldedit_commands/safe.lua11
2 files changed, 126 insertions, 30 deletions
diff --git a/worldedit_commands/init.lua b/worldedit_commands/init.lua
index 325a31c..6b6d2a7 100644
--- a/worldedit_commands/init.lua
+++ b/worldedit_commands/init.lua
@@ -23,6 +23,7 @@ local function get_position(name) --position 1 retrieval function for when not u
return pos1
end
+-- normalize_nodename wrapper for convenience purposes
local function get_node(name, nodename)
local node = worldedit.normalize_nodename(nodename)
if not node then
@@ -36,26 +37,46 @@ function worldedit.player_notify(name, message)
minetest.chat_send_player(name, "WorldEdit -!- " .. message, false)
end
---determines whether `nodename` is a valid node name, returning a boolean
+local function string_endswith(full, part)
+ return full:find(part, 1, true) == #full - #part + 1
+end
+
+-- normalizes node "description" `nodename`, returning a string (or nil)
worldedit.normalize_nodename = function(nodename)
- nodename = nodename:gsub("^%s*(.-)%s*$", "%1")
+ nodename = nodename:gsub("^%s*(.-)%s*$", "%1") -- strip spaces
if nodename == "" then return nil end
- local fullname = ItemStack({name=nodename}):get_name() --resolve aliases of node names to full names
- if minetest.registered_nodes[fullname] or fullname == "air" then --directly found node name or alias of nodename
+
+ local fullname = ItemStack({name=nodename}):get_name() -- resolve aliases
+ if minetest.registered_nodes[fullname] or fullname == "air" then -- full name
return fullname
end
for key, value in pairs(minetest.registered_nodes) do
- if key:find(":" .. nodename, 1, true) then --found in mod
+ if string_endswith(key, ":" .. nodename) then -- matches name (w/o mod part)
return key
end
end
- nodename = nodename:lower() --lowercase both for case insensitive comparison
+ nodename = nodename:lower() -- lowercase both for case insensitive comparison
for key, value in pairs(minetest.registered_nodes) do
- if value.description:lower() == nodename then --found in description
+ local desc = value.description:lower()
+ if desc == nodename then -- matches description
return key
end
+ if string_endswith(desc, " block") and desc == nodename.." block" then
+ -- fuzzy description match (e.g. "Steel" == "Steel Block")
+ return key
+ end
+ end
+
+ local match = nil
+ for key, value in pairs(minetest.registered_nodes) do
+ if value.description:lower():find(nodename, 1, true) ~= nil then
+ if match ~= nil then
+ return nil
+ end
+ match = key -- substring description match (only if no ambiguities)
+ end
end
- return nil
+ return match
end
-- Determines the axis in which a player is facing, returning an axis ("x", "y", or "z") and the sign (1 or -1)
@@ -377,16 +398,32 @@ minetest.register_chatcommand("/set", {
privs = {worldedit=true},
func = safe_region(function(name, param)
local node = get_node(name, param)
- if not node then
- worldedit.player_notify(name, "Could not identify node \"" .. param .. "\"")
- return
- end
+ if not node then return end
local count = worldedit.set(worldedit.pos1[name], worldedit.pos2[name], node)
worldedit.player_notify(name, count .. " nodes set")
end, check_region),
})
+minetest.register_chatcommand("/param2", {
+ params = "<param2>",
+ description = "Set param2 of all nodes in the current WorldEdit region to <param2>",
+ privs = {worldedit=true},
+ func = safe_region(function(name, param)
+ local param2 = tonumber(param)
+ if not param2 then
+ worldedit.player_notify(name, "Invalid or missing param2 argument")
+ return
+ elseif param2 < 0 or param2 > 255 then
+ worldedit.player_notify(name, "Param2 is out of range (must be between 0 and 255 inclusive)!")
+ return
+ end
+
+ local count = worldedit.set_param2(worldedit.pos1[name], worldedit.pos2[name], param2)
+ worldedit.player_notify(name, count .. " nodes altered")
+ end, check_region),
+})
+
minetest.register_chatcommand("/mix", {
params = "<node1> ...",
description = "Fill the current WorldEdit region with a random mix of <node1>, ...",
@@ -395,10 +432,7 @@ minetest.register_chatcommand("/mix", {
local nodes = {}
for nodename in param:gmatch("[^%s]+") do
local node = get_node(name, nodename)
- if not node then
- worldedit.player_notify(name, "Could not identify node \"" .. name .. "\"")
- return
- end
+ if not node then return end
nodes[#nodes + 1] = node
end
@@ -455,6 +489,45 @@ minetest.register_chatcommand("/replaceinverse", {
end, check_replace),
})
+local check_cube = function(name, param)
+ if worldedit.pos1[name] == nil then
+ worldedit.player_notify(name, "no position 1 selected")
+ return nil
+ end
+ local found, _, w, h, l, 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 tonumber(w) * tonumber(h) * tonumber(l)
+end
+
+minetest.register_chatcommand("/hollowcube", {
+ params = "<width> <height> <length> <node>",
+ description = "Add a hollow cube with its ground level centered at WorldEdit position 1 with dimensions <width> x <height> x <length>, composed of <node>.",
+ privs = {worldedit=true},
+ func = safe_region(function(name, param)
+ local found, _, w, h, l, nodename = param:find("^(%d+)%s+(%d+)%s+(%d+)%s+(.+)$")
+ local node = get_node(name, nodename)
+ local count = worldedit.cube(worldedit.pos1[name], tonumber(w), tonumber(h), tonumber(l), node, true)
+ worldedit.player_notify(name, count .. " nodes added")
+ end, check_cube),
+})
+
+minetest.register_chatcommand("/cube", {
+ params = "<width> <height> <length> <node>",
+ description = "Add a cube with its ground level centered at WorldEdit position 1 with dimensions <width> x <height> x <length>, composed of <node>.",
+ privs = {worldedit=true},
+ func = safe_region(function(name, param)
+ local found, _, w, h, l, nodename = param:find("^(%d+)%s+(%d+)%s+(%d+)%s+(.+)$")
+ local node = get_node(name, nodename)
+ local count = worldedit.cube(worldedit.pos1[name], tonumber(w), tonumber(h), tonumber(l), node)
+ worldedit.player_notify(name, count .. " nodes added")
+ end, check_cube),
+})
+
local check_sphere = function(name, param)
if worldedit.pos1[name] == nil then
worldedit.player_notify(name, "no position 1 selected")
@@ -538,46 +611,65 @@ local check_cylinder = function(name, param)
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+(.+)$")
+ -- two radii
+ local found, _, axis, length, radius1, radius2, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(%d+)%s+(.+)$")
+ if found == nil then
+ -- single radius
+ found, _, axis, length, radius1, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(.+)$")
+ radius2 = radius1
+ end
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))
+ local radius = math.max(tonumber(radius1), tonumber(radius2))
+ return math.ceil(math.pi * (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>",
+ params = "x/y/z/? <length> <radius1> [radius2] <node>",
+ description = "Add hollow cylinder at WorldEdit position 1 along the x/y/z/? axis with length <length>, base radius <radius1> (and top radius [radius2]), composed of <node>",
privs = {worldedit=true},
func = safe_region(function(name, param)
- local found, _, axis, length, radius, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(.+)$")
+ -- two radii
+ local found, _, axis, length, radius1, radius2, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(%d+)%s+(.+)$")
+ if found == nil then
+ -- single radius
+ found, _, axis, length, radius1, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(.+)$")
+ radius2 = radius1
+ end
length = tonumber(length)
if axis == "?" then
axis, sign = worldedit.player_axis(name)
length = length * sign
end
local node = get_node(name, nodename)
- local count = worldedit.cylinder(worldedit.pos1[name], axis, length, tonumber(radius), node, true)
+ local count = worldedit.cylinder(worldedit.pos1[name], axis, length, tonumber(radius1), tonumber(radius2), node, true)
worldedit.player_notify(name, count .. " nodes added")
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>",
+ params = "x/y/z/? <length> <radius1> [radius2] <node>",
+ description = "Add cylinder at WorldEdit position 1 along the x/y/z/? axis with length <length>, base radius <radius1> (and top radius [radius2]), composed of <node>",
privs = {worldedit=true},
func = safe_region(function(name, param)
- local found, _, axis, length, radius, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(.+)$")
+ -- two radii
+ local found, _, axis, length, radius1, radius2, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(%d+)%s+(.+)$")
+ if found == nil then
+ -- single radius
+ found, _, axis, length, radius1, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(.+)$")
+ radius2 = radius1
+ end
length = tonumber(length)
if axis == "?" then
axis, sign = worldedit.player_axis(name)
length = length * sign
end
local node = get_node(name, nodename)
- local count = worldedit.cylinder(worldedit.pos1[name], axis, length, tonumber(radius), node)
+ local count = worldedit.cylinder(worldedit.pos1[name], axis, length, tonumber(radius1), tonumber(radius2), node)
worldedit.player_notify(name, count .. " nodes added")
end, check_cylinder),
})
@@ -696,6 +788,7 @@ minetest.register_chatcommand("/move", {
end
amount = tonumber(amount)
if axis == "?" then
+ local sign
axis, sign = worldedit.player_axis(name)
amount = amount * sign
end
diff --git a/worldedit_commands/safe.lua b/worldedit_commands/safe.lua
index a93e393..0bd30d7 100644
--- a/worldedit_commands/safe.lua
+++ b/worldedit_commands/safe.lua
@@ -1,6 +1,8 @@
local safe_region_callback = {}
local safe_region_param = {}
+worldedit._override_safe_regions = false -- internal use ONLY!
+
local function check_region(name, param)
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name] --obtain positions
if pos1 == nil or pos2 == nil then
@@ -20,7 +22,7 @@ local function safe_region(callback, nodes_needed)
--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
+ if worldedit._override_safe_regions or count < 10000 then
return callback(name, param)
end
@@ -44,20 +46,21 @@ minetest.register_chatcommand("/y", {
return
end
- safe_region_callback[name], safe_region_param[name] = nil, nil --reset pending operation
+ reset_pending(name)
callback(name, param)
end,
})
minetest.register_chatcommand("/n", {
params = "",
- description = "Confirm a pending operation",
+ description = "Abort a pending operation",
func = function(name)
if not safe_region_callback[name] then
worldedit.player_notify(name, "no operation pending")
return
end
- safe_region_callback[name], safe_region_param[name] = nil, nil
+
+ reset_pending(name)
end,
})