Support descriptions and partial node names in chat commands (e.g., `//set blue lightstone`, `//replace piston_normal_off bronze block`).

This commit is contained in:
Anthony Zhang 2013-06-12 19:59:13 -04:00
parent f1cfc47189
commit 74018dab99
3 changed files with 130 additions and 91 deletions

View File

@ -51,93 +51,93 @@ Display the volume of the current WorldEdit region.
Set the current WorldEdit region to <node>.
//set dirt
//set default:glass
//set mesecons:mesecon
//set cactus
//set Bronze Block
//set mesecons:wire_00000000_off
### //replace <search node> <replace node>
Replace all instances of <search node> with <replace node> in the current WorldEdit region.
//replace cobble stone
//replace default:steelblock glass
//replace dirt flowers:flower_waterlily
//replace flowers:flower_rose flowers:flower_tulip
//replace Cobblestone cactus
//replace lightstone_blue glass
//replace dirt Bronze Block
//replace mesecons:wire_00000000_off flowers:flower_tulip
### //replaceinverse <search node> <replace node>
Replace all nodes other than <search node> with <replace node> in the current WorldEdit region.
//replaceinverse air stone
//replaceinverse water_source default:dirt
//replaceinverse mesecons:mesecon air
//replaceinverse default:steelblock default:glass
//replaceinverse Cobblestone cactus
//replaceinverse flowers:flower_waterlily glass
//replaceinverse dirt Bronze Block
//replaceinverse mesecons:wire_00000000_off flowers:flower_tulip
### //hollowsphere <radius> <node>
Add hollow sphere at WorldEdit position 1 with radius <radius>, composed of <node>.
//hollowsphere 5 dirt
//hollowsphere 12 default:glass
//hollowsphere 17 mesecons:mesecon
//hollowsphere 5 Diamond Block
//hollowsphere 12 glass
//hollowsphere 17 mesecons:wire_00000000_off
### //sphere <radius> <node>
Add sphere at WorldEdit position 1 with radius <radius>, composed of <node>.
//sphere 5 dirt
//sphere 12 default:glass
//sphere 17 mesecons:mesecon
//sphere 5 Diamond Block
//sphere 12 glass
//sphere 17 mesecons:wire_00000000_off
### //hollowdome <radius> <node>
Add hollow dome at WorldEdit position 1 with radius <radius>, composed of <node>.
//hollowdome 5 dirt
//hollowdome 12 default:glass
//hollowdome 17 mesecons:mesecon
//hollowdome 5 Diamond Block
//hollowdome 12 glass
//hollowdome 17 mesecons:wire_00000000_off
### //dome <radius> <node>
Add dome at WorldEdit position 1 with radius <radius>, composed of <node>.
//dome 5 dirt
//dome 12 default:glass
//dome 17 mesecons:mesecon
//dome 5 Diamond Block
//dome 12 glass
//dome 17 mesecons:wire_00000000_off
### //hollowcylinder x/y/z/? <length> <radius> <node>
Add hollow cylinder at WorldEdit position 1 along the x/y/z/? axis with length <length> and radius <radius>, composed of <node>.
//hollowcylinder x +5 8 dirt
//hollowcylinder y 28 10 default:glass
//hollowcylinder z -12 3 mesecons:mesecon
//hollowcylinder ? 2 4 stone
//hollowcylinder x +5 8 Bronze Block
//hollowcylinder y 28 10 glass
//hollowcylinder z -12 3 mesecons:wire_00000000_off
//hollowcylinder ? 2 4 default:stone
### //cylinder x/y/z/? <length> <radius> <node>
Add cylinder at WorldEdit position 1 along the x/y/z/? axis with length <length> and radius <radius>, composed of <node>.
//cylinder x +5 8 dirt
//cylinder y 28 10 default:glass
//cylinder z -12 3 mesecons:mesecon
//cylinder ? 2 4 stone
//cylinder x +5 8 Bronze Block
//cylinder y 28 10 glass
//cylinder z -12 3 mesecons:wire_00000000_off
//cylinder ? 2 4 default:stone
### //pyramid <height> <node>
Add pyramid at WorldEdit position 1 with height <height>, composed of <node>.
//pyramid 8 dirt
//pyramid 5 default:glass
//pyramid 2 stone
//pyramid 8 Diamond Block
//pyramid 5 glass
//pyramid 2 mesecons:wire_00000000_off
### //spiral <width> <height> <spacer> <node>
Add spiral at WorldEdit position 1 with width <width>, height <height>, space between walls <spacer>, composed of <node>.
//spiral 20 5 3 dirt
//spiral 5 2 1 default:glass
//spiral 7 1 5 stone
//spiral 20 5 3 Diamond Block
//spiral 5 2 1 glass
//spiral 7 1 5 mesecons:wire_00000000_off
### //copy x/y/z/? <amount>
@ -218,17 +218,17 @@ Hide all nodes in the current WorldEdit region non-destructively.
Suppress all <node> in the current WorldEdit region non-destructively.
//suppress dirt
//suppress default:glass
//suppress mesecons:mesecon
//suppress Diamond Block
//suppress glass
//suppress mesecons:wire_00000000_off
### //highlight <node>
Highlight <node> in the current WorldEdit region by hiding everything else non-destructively.
//highlight dirt
//highlight default:glass
//highlight mesecons:mesecon
//highlight Diamond Block
//highlight glass
//highlight mesecons:wire_00000000_off
### //restore

View File

@ -20,6 +20,16 @@ When an axis is specified in a WorldEdit command, it is specified as one of the
The value ? represents the axis the player is currently facing. If the player is facing more than one axis, the axis the player face direction is closest to will be used.
Nodes
-----
Node names are required for many types of commands that identify or modify specific types of nodes. They can be specified in a number of ways.
First, by description - the tooltip that appears when hovering over the item in an inventory. This is case insensitive and includes values such as "Cobblestone" and "bronze block". Note that certain commands (namely, `//replace` and `//replaceinverse`) do not support descriptions that contain spaces in the `<searchnode>` field.
Second, by name - the node name that is defined by code, but without the mod name prefix. This is case sensitive and includes values such as "piston_normal_off" and "cactus". Nodes defined in the `default` mod always take precedence over other nodes when searching for the correct one, and if there are multiple possible nodes (such as "a:celery" and "b:celery"), one is chosen in no particular order.
Finally, by full name - the unambiguous identifier of the node, prefixes and all. This is case sensitive and includes values such as "default:stone" and "mesecons:wire_00000000_off".
Regions
-------
Most WorldEdit commands operate on regions. Regions are a set of two positions that define a 3D cube. They are local to each player and chat commands affect only the region for the player giving the commands.

View File

@ -12,9 +12,23 @@ worldedit.player_notify = function(name, message)
end
--determines whether `nodename` is a valid node name, returning a boolean
worldedit.node_is_valid = function(nodename)
return minetest.registered_nodes[nodename] ~= nil
or minetest.registered_nodes["default:" .. nodename] ~= nil
worldedit.normalize_nodename = function(nodename)
if minetest.registered_nodes[nodename] then --directly found node name
return nodename
elseif minetest.registered_nodes["default:" .. nodename] then --found node name in default
return "default:" .. nodename
end
for key, value in pairs(minetest.registered_nodes) do
if key:find(":" .. nodename, 1, true) then --found in mod
return key
end
end
for key, value in pairs(minetest.registered_nodes) do
if value.description:lower() == nodename:lower() then --found in description
return key
end
end
return nil
end
--determines the axis in which a player is facing, returning an axis ("x", "y", or "z") and the sign (1 or -1)
@ -178,7 +192,8 @@ minetest.register_chatcommand("/set", {
return
end
if param == "" or not worldedit.node_is_valid(param) then
local node = worldedit.normalize_nodename(param)
if param == "" or not node then
worldedit.player_notify(name, "invalid node name: " .. param)
return
end
@ -188,7 +203,7 @@ minetest.register_chatcommand("/set", {
tenv = worldedit.queue_aliasenv
end
local count = worldedit.set(pos1, pos2, param, tenv)
local count = worldedit.set(pos1, pos2, node, tenv)
worldedit.player_notify(name, count .. " nodes set")
end,
})
@ -204,16 +219,18 @@ minetest.register_chatcommand("/replace", {
return
end
local found, _, searchnode, replacenode = param:find("^([^%s]+)%s+([^%s]+)$")
local found, _, searchnode, replacenode = param:find("^([^%s]+)%s+(.+)$")
if found == nil then
worldedit.player_notify(name, "invalid usage: " .. param)
return
end
if not worldedit.node_is_valid(searchnode) then
local newsearchnode = worldedit.normalize_nodename(searchnode)
if not newsearchnode then
worldedit.player_notify(name, "invalid search node name: " .. searchnode)
return
end
if not worldedit.node_is_valid(replacenode) then
local newreplacenode = worldedit.normalize_nodename(replacenode)
if not newreplacenode then
worldedit.player_notify(name, "invalid replace node name: " .. replacenode)
return
end
@ -222,7 +239,7 @@ minetest.register_chatcommand("/replace", {
if worldedit.ENABLE_QUEUE then
tenv = worldedit.queue_aliasenv
end
local count = worldedit.replace(pos1, pos2, searchnode, replacenode, tenv)
local count = worldedit.replace(pos1, pos2, newsearchnode, newreplacenode, tenv)
worldedit.player_notify(name, count .. " nodes replaced")
end,
})
@ -238,16 +255,18 @@ minetest.register_chatcommand("/replaceinverse", {
return
end
local found, _, searchnode, replacenode = param:find("^([^%s]+)%s+([^%s]+)$")
local found, _, searchnode, replacenode = param:find("^([^%s]+)%s+(.+)$")
if found == nil then
worldedit.player_notify(name, "invalid usage: " .. param)
return
end
if not worldedit.node_is_valid(searchnode) then
local newsearchnode = worldedit.normalize_nodename(searchnode)
if not newsearchnode then
worldedit.player_notify(name, "invalid search node name: " .. searchnode)
return
end
if not worldedit.node_is_valid(replacenode) then
local newreplacenode = worldedit.normalize_nodename(replacenode)
if not newreplacenode then
worldedit.player_notify(name, "invalid replace node name: " .. replacenode)
return
end
@ -272,13 +291,14 @@ minetest.register_chatcommand("/hollowsphere", {
return
end
local found, _, radius, nodename = param:find("^(%d+)%s+([^%s]+)$")
local found, _, radius, nodename = param:find("^(%d+)%s+(.+)$")
if found == nil then
worldedit.player_notify(name, "invalid usage: " .. param)
return
end
if not worldedit.node_is_valid(nodename) then
worldedit.player_notify(name, "invalid node name: " .. param)
local node = worldedit.normalize_nodename(nodename)
if not node then
worldedit.player_notify(name, "invalid node name: " .. nodename)
return
end
@ -286,7 +306,7 @@ minetest.register_chatcommand("/hollowsphere", {
if worldedit.ENABLE_QUEUE then
tenv = worldedit.queue_aliasenv
end
local count = worldedit.hollow_sphere(pos, tonumber(radius), nodename, tenv)
local count = worldedit.hollow_sphere(pos, tonumber(radius), node, tenv)
worldedit.player_notify(name, count .. " nodes added")
end,
})
@ -302,13 +322,14 @@ minetest.register_chatcommand("/sphere", {
return
end
local found, _, radius, nodename = param:find("^(%d+)%s+([^%s]+)$")
local found, _, radius, nodename = param:find("^(%d+)%s+(.+)$")
if found == nil then
worldedit.player_notify(name, "invalid usage: " .. param)
return
end
if not worldedit.node_is_valid(nodename) then
worldedit.player_notify(name, "invalid node name: " .. param)
local node = worldedit.normalize_nodename(nodename)
if not node then
worldedit.player_notify(name, "invalid node name: " .. nodename)
return
end
@ -316,7 +337,7 @@ minetest.register_chatcommand("/sphere", {
if worldedit.ENABLE_QUEUE then
tenv = worldedit.queue_aliasenv
end
local count = worldedit.sphere(pos, tonumber(radius), nodename, tenv)
local count = worldedit.sphere(pos, tonumber(radius), node, tenv)
worldedit.player_notify(name, count .. " nodes added")
end,
})
@ -332,13 +353,14 @@ minetest.register_chatcommand("/hollowdome", {
return
end
local found, _, radius, nodename = param:find("^(%d+)%s+([^%s]+)$")
local found, _, radius, nodename = param:find("^(%d+)%s+(.+)$")
if found == nil then
worldedit.player_notify(name, "invalid usage: " .. param)
return
end
if not worldedit.node_is_valid(nodename) then
worldedit.player_notify(name, "invalid node name: " .. param)
local node = worldedit.normalize_nodename(nodename)
if not node then
worldedit.player_notify(name, "invalid node name: " .. nodename)
return
end
@ -346,7 +368,7 @@ minetest.register_chatcommand("/hollowdome", {
if worldedit.ENABLE_QUEUE then
tenv = worldedit.queue_aliasenv
end
local count = worldedit.hollow_dome(pos, tonumber(radius), nodename, tenv)
local count = worldedit.hollow_dome(pos, tonumber(radius), node, tenv)
worldedit.player_notify(name, count .. " nodes added")
end,
})
@ -362,13 +384,14 @@ minetest.register_chatcommand("/dome", {
return
end
local found, _, radius, nodename = param:find("^(%d+)%s+([^%s]+)$")
local found, _, radius, nodename = param:find("^(%d+)%s+(.+)$")
if found == nil then
worldedit.player_notify(name, "invalid usage: " .. param)
return
end
if not worldedit.node_is_valid(nodename) then
worldedit.player_notify(name, "invalid node name: " .. param)
local node = worldedit.normalize_nodename(nodename)
if not node then
worldedit.player_notify(name, "invalid node name: " .. nodename)
return
end
@ -376,7 +399,7 @@ minetest.register_chatcommand("/dome", {
if worldedit.ENABLE_QUEUE then
tenv = worldedit.queue_aliasenv
end
local count = worldedit.dome(pos, tonumber(radius), nodename, tenv)
local count = worldedit.dome(pos, tonumber(radius), node, tenv)
worldedit.player_notify(name, count .. " nodes added")
end,
})
@ -392,7 +415,7 @@ minetest.register_chatcommand("/hollowcylinder", {
return
end
local found, _, axis, length, radius, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+([^%s]+)$")
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
@ -401,8 +424,9 @@ minetest.register_chatcommand("/hollowcylinder", {
axis, sign = worldedit.player_axis(name)
length = length * sign
end
if not worldedit.node_is_valid(nodename) then
worldedit.player_notify(name, "invalid node name: " .. param)
local node = worldedit.normalize_nodename(nodename)
if not node then
worldedit.player_notify(name, "invalid node name: " .. nodename)
return
end
@ -410,7 +434,7 @@ minetest.register_chatcommand("/hollowcylinder", {
if worldedit.ENABLE_QUEUE then
tenv = worldedit.queue_aliasenv
end
local count = worldedit.hollow_cylinder(pos, axis, tonumber(length), tonumber(radius), nodename, tenv)
local count = worldedit.hollow_cylinder(pos, axis, tonumber(length), tonumber(radius), node, tenv)
worldedit.player_notify(name, count .. " nodes added")
end,
})
@ -426,7 +450,7 @@ minetest.register_chatcommand("/cylinder", {
return
end
local found, _, axis, length, radius, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+([^%s]+)$")
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
@ -435,8 +459,9 @@ minetest.register_chatcommand("/cylinder", {
axis, sign = worldedit.player_axis(name)
length = length * sign
end
if not worldedit.node_is_valid(nodename) then
worldedit.player_notify(name, "invalid node name: " .. param)
local node = worldedit.normalize_nodename(nodename)
if not node then
worldedit.player_notify(name, "invalid node name: " .. nodename)
return
end
@ -444,7 +469,7 @@ minetest.register_chatcommand("/cylinder", {
if worldedit.ENABLE_QUEUE then
tenv = worldedit.queue_aliasenv
end
local count = worldedit.cylinder(pos, axis, tonumber(length), tonumber(radius), nodename, tenv)
local count = worldedit.cylinder(pos, axis, tonumber(length), tonumber(radius), node, tenv)
worldedit.player_notify(name, count .. " nodes added")
end,
})
@ -460,13 +485,14 @@ minetest.register_chatcommand("/pyramid", {
return
end
local found, _, size, nodename = param:find("(%d+)%s+([^%s]+)$")
local found, _, size, nodename = param:find("(%d+)%s+(.+)$")
if found == nil then
worldedit.player_notify(name, "invalid usage: " .. param)
return
end
if not worldedit.node_is_valid(nodename) then
worldedit.player_notify(name, "invalid node name: " .. param)
local node = worldedit.normalize_nodename(nodename)
if not node then
worldedit.player_notify(name, "invalid node name: " .. nodename)
return
end
@ -474,7 +500,7 @@ minetest.register_chatcommand("/pyramid", {
if worldedit.ENABLE_QUEUE then
tenv = worldedit.queue_aliasenv
end
local count = worldedit.pyramid(pos, tonumber(size), nodename, tenv)
local count = worldedit.pyramid(pos, tonumber(size), node, tenv)
worldedit.player_notify(name, count .. " nodes added")
end,
})
@ -490,13 +516,14 @@ minetest.register_chatcommand("/spiral", {
return
end
local found, _, width, height, space, nodename = param:find("(%d+)%s+(%d+)%s+(%d+)%s+([^%s]+)$")
local found, _, width, height, space, nodename = param:find("(%d+)%s+(%d+)%s+(%d+)%s+(.+)$")
if found == nil then
worldedit.player_notify(name, "invalid usage: " .. param)
return
end
if not worldedit.node_is_valid(nodename) then
worldedit.player_notify(name, "invalid node name: " .. param)
local node = worldedit.normalize_nodename(nodename)
if not node then
worldedit.player_notify(name, "invalid node name: " .. nodename)
return
end
@ -504,7 +531,7 @@ minetest.register_chatcommand("/spiral", {
if worldedit.ENABLE_QUEUE then
tenv = worldedit.queue_aliasenv
end
local count = worldedit.spiral(pos, tonumber(width), tonumber(height), tonumber(space), nodename, tenv)
local count = worldedit.spiral(pos, tonumber(width), tonumber(height), tonumber(space), node, tenv)
worldedit.player_notify(name, count .. " nodes added")
end,
})
@ -793,7 +820,8 @@ minetest.register_chatcommand("/suppress", {
return
end
if param == "" or not worldedit.node_is_valid(param) then
local node = worldedit.node_is_valid(param)
if param == "" or not node then
worldedit.player_notify(name, "invalid node name: " .. param)
return
end
@ -802,7 +830,7 @@ minetest.register_chatcommand("/suppress", {
if worldedit.ENABLE_QUEUE then
tenv = worldedit.queue_aliasenv
end
local count = worldedit.suppress(pos1, pos2, param, tenv)
local count = worldedit.suppress(pos1, pos2, node, tenv)
worldedit.player_notify(name, count .. " nodes suppressed")
end,
})
@ -818,7 +846,8 @@ minetest.register_chatcommand("/highlight", {
return
end
if param == "" or not worldedit.node_is_valid(param) then
local node = worldedit.node_is_valid(param)
if param == "" or not node then
worldedit.player_notify(name, "invalid node name: " .. param)
return
end
@ -827,7 +856,7 @@ minetest.register_chatcommand("/highlight", {
if worldedit.ENABLE_QUEUE then
tenv = worldedit.queue_aliasenv
end
local count = worldedit.highlight(pos1, pos2, param, tenv)
local count = worldedit.highlight(pos1, pos2, node, tenv)
worldedit.player_notify(name, count .. " nodes highlighted")
end,
})