1
0
mirror of https://github.com/Uberi/Minetest-WorldEdit.git synced 2025-10-16 07:35:27 +02:00

Minor maintenance changes

This commit is contained in:
sfan5
2025-09-20 13:29:01 +02:00
parent bf154b12c7
commit 1f9b8ef55b
9 changed files with 56 additions and 30 deletions

View File

@@ -107,7 +107,13 @@ Display the volume of the current WorldEdit region.
### `//deleteblocks` ### `//deleteblocks`
Delete the MapBlocks (16x16x16 units) that contain the selected region. This means that mapgen will be invoked for that area. As only whole MapBlocks get removed, the deleted area is usually larger than the selected one. Also, mapgen can trigger mechanisms like mud reflow or cavegen, which affects nodes (up to 112 nodes away) outside the MapBlock, so dont use this near buildings. Note that active entities are not part of a MapBlock and do not get deleted. Delete the MapBlocks (16x16x16 units) that contain the selected region.
This means that mapgen will run again for that area.
As only whole MapBlocks get removed, the deleted area is usually larger than the selected one.
Also, mapgen can trigger mechanisms like mud reflow or cavegen, which affects nodes (up to 112 nodes away) outside the MapBlock,
so dont use this near buildings.
Note that entities are not part of a MapBlock and will not get deleted (use `//clearobjects`).
//deleteblocks //deleteblocks
@@ -354,7 +360,9 @@ Removes any fluid node within the current WorldEdit region.
### `//clearcut` ### `//clearcut`
Removes any plant, tree or foilage-like nodes in the selected region. 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. The idea is to remove anything that isn't part of the terrain, leaving a "natural" empty space ready for building.
However note that this relies on heuristics.
//clearcut //clearcut
@@ -440,6 +448,7 @@ Valid values for `[rotation]` are 0, 90, 180 and 270.
### `//mtschemprob start/finish/get` ### `//mtschemprob start/finish/get`
After using `//mtschemprob start` all nodes punched will bring up a text field where a probablity can be entered. After using `//mtschemprob start` all nodes punched will bring up a text field where a probablity can be entered.
This mode can be left with `//mtschemprob finish`. `//mtschemprob get` will display the probabilities saved for the nodes. This mode can be left with `//mtschemprob finish`. `//mtschemprob get` will display the probabilities saved for the nodes.
//mtschemprob get //mtschemprob get
@@ -492,6 +501,7 @@ or vertically in the y axis using `v`.
Assigns the given `<command>` to the currently held brush item, it will be ran with the first pointed solid node (as determined via raycast) as Assigns the given `<command>` to the currently held brush item, it will be ran with the first pointed solid node (as determined via raycast) as
WorldEdit position 1 when using that specific brush item. WorldEdit position 1 when using that specific brush item.
Passing `none` instead clears the command assigned to the currently held brush item. Passing `none` instead clears the command assigned to the currently held brush item.
Note that this functionality requires the `worldedit_brush` mod enabled. Note that this functionality requires the `worldedit_brush` mod enabled.
//brush cube 8 8 8 Cobblestone //brush cube 8 8 8 Cobblestone
@@ -502,6 +512,7 @@ Note that this functionality requires the `worldedit_brush` mod enabled.
Selects a cube with side length of `<size>` around the WorldEdit position 1 and runs the given `<command>` on the newly selected region. Selects a cube with side length of `<size>` around the WorldEdit position 1 and runs the given `<command>` on the newly selected region.
If `<sizex>`, `<sizey>` and `<sizez>` are given, they instead specify the length of the cuboid in X, Y, Z direction. If `<sizex>`, `<sizey>` and `<sizez>` are given, they instead specify the length of the cuboid in X, Y, Z direction.
This is mostly useful for brushes since it allows commands such as `//replace` to be ran, but it can also be used standalone. This is mostly useful for brushes since it allows commands such as `//replace` to be ran, but it can also be used standalone.
//cubeapply 10 replaceinverse air default:water_source //cubeapply 10 replaceinverse air default:water_source

View File

@@ -1,4 +1,4 @@
--- WorldEdit mod for the Minetest engine --- WorldEdit mod for the Luanti engine
-- @module worldedit -- @module worldedit
-- @release 1.3 -- @release 1.3
-- @copyright 2012 sfan5, Anthony Zhang (Uberi/Temperest), and Brett O'Donnell (cornernote) -- @copyright 2012 sfan5, Anthony Zhang (Uberi/Temperest), and Brett O'Donnell (cornernote)

View File

@@ -5,7 +5,7 @@
--------------------- ---------------------
local vec = vector.new local vec = vector.new
local vecw = function(axis, n, base) local vecw = function(axis, n, base)
local ret = vec(base) local ret = vector.copy(base)
ret[axis] = n ret[axis] = n
return ret return ret
end end

View File

@@ -9,7 +9,7 @@ local brush_on_use = function(itemstack, placer)
if cmd == "" then if cmd == "" then
worldedit.player_notify(name, worldedit.player_notify(name,
S("This brush is not bound, use @1 to bind a command to it.", S("This brush is not bound, use @1 to bind a command to it.",
minetest.colorize("#00ffff", "//brush")), "info") minetest.colorize("#0ff", "//brush")), "info")
return false return false
end end
@@ -100,7 +100,7 @@ worldedit.register_command("brush", {
local cmddef = worldedit.registered_commands[cmd] local cmddef = worldedit.registered_commands[cmd]
if cmddef == nil or cmddef.require_pos ~= 1 then if cmddef == nil or cmddef.require_pos ~= 1 then
return false, S("@1 cannot be used with brushes", return false, S("@1 cannot be used with brushes",
minetest.colorize("#00ffff", "//"..cmd)) minetest.colorize("#0ff", "//"..cmd))
end end
-- Try parsing command params so we can give the user feedback -- Try parsing command params so we can give the user feedback
@@ -112,7 +112,7 @@ worldedit.register_command("brush", {
meta:set_string("command", cmd) meta:set_string("command", cmd)
meta:set_string("params", params) meta:set_string("params", params)
local fullcmd = minetest.colorize("#00ffff", "//"..cmd) .. " " .. params local fullcmd = minetest.colorize("#0ff", "//"..cmd) .. " " .. params
meta:set_string("description", meta:set_string("description",
minetest.registered_tools["worldedit:brush"].description .. ": " .. fullcmd) minetest.registered_tools["worldedit:brush"].description .. ": " .. fullcmd)
worldedit.player_notify(name, S("Brush assigned to command: @1", fullcmd), "ok") worldedit.player_notify(name, S("Brush assigned to command: @1", fullcmd), "ok")

View File

@@ -238,7 +238,7 @@ worldedit.register_command("cubeapply", {
local cmddef = worldedit.registered_commands[cmd] local cmddef = worldedit.registered_commands[cmd]
if cmddef == nil or cmddef.require_pos ~= 2 then if cmddef == nil or cmddef.require_pos ~= 2 then
return false, S("invalid usage: @1 cannot be used with cubeapply", return false, S("invalid usage: @1 cannot be used with cubeapply",
minetest.colorize("#00ffff", "//"..cmd)) minetest.colorize("#0ff", "//"..cmd))
end end
-- run parsing of target command -- run parsing of target command
local parsed = {cmddef.parse(args)} local parsed = {cmddef.parse(args)}

View File

@@ -25,6 +25,15 @@ local function copy_state(which, name)
end end
end end
local function compare_state(state, old_state)
for i, v in ipairs(state) do
if not (v == nil and old_state[i] == nil) and not vector.equals(v, old_state[i]) then
return false
end
end
return true
end
local function chatcommand_handler(cmd_name, name, param) local function chatcommand_handler(cmd_name, name, param)
local def = assert(worldedit.registered_commands[cmd_name]) local def = assert(worldedit.registered_commands[cmd_name])
@@ -66,11 +75,7 @@ local function chatcommand_handler(cmd_name, name, param)
local old_state = copy_state(def.require_pos, name) local old_state = copy_state(def.require_pos, name)
safe_region(name, count, function() safe_region(name, count, function()
local state = copy_state(def.require_pos, name) local state = copy_state(def.require_pos, name)
local ok = true if not compare_state(state, old_state) then
for i, v in ipairs(state) do
ok = ok and ( (v == nil and old_state[i] == nil) or vector.equals(v, old_state[i]) )
end
if not ok then
worldedit.player_notify(name, S("ERROR: the operation was cancelled because the region has changed."), "error") worldedit.player_notify(name, S("ERROR: the operation was cancelled because the region has changed."), "error")
return return
end end
@@ -111,6 +116,7 @@ function worldedit.register_command(name, def)
def.require_pos = def.require_pos or 0 def.require_pos = def.require_pos or 0
assert(def.require_pos >= 0 and def.require_pos < 3) assert(def.require_pos >= 0 and def.require_pos < 3)
if def.params == "" and not def.parse then if def.params == "" and not def.parse then
-- FIXME: shouldn't this check for param to be empty?
def.parse = function(param) return true end def.parse = function(param) return true end
else else
assert(def.parse) assert(def.parse)
@@ -124,7 +130,7 @@ function worldedit.register_command(name, def)
end--]] end--]]
-- disable further modification -- disable further modification
setmetatable(def, {__newindex = {}}) setmetatable(def, {__newindex = function() end})
minetest.register_chatcommand("/" .. name, { minetest.register_chatcommand("/" .. name, {
privs = def.privs, privs = def.privs,
@@ -172,7 +178,9 @@ function worldedit.player_notify(name, message, typ)
minetest.chat_send_player(name, table.concat(t, " ")) minetest.chat_send_player(name, table.concat(t, " "))
end end
-- Determines the axis in which a player is facing, returning an axis ("x", "y", or "z") and the sign (1 or -1) -- Determines the axis in which a player is facing
-- @return axis ("x", "y", or "z") and the sign (1 or -1)
-- @note Not part of API
function worldedit.player_axis(name) function worldedit.player_axis(name)
local player = minetest.get_player_by_name(name) local player = minetest.get_player_by_name(name)
if not player then if not player then
@@ -200,7 +208,7 @@ worldedit.register_command("about", {
worldedit.player_notify(name, S("WorldEdit @1".. worldedit.player_notify(name, S("WorldEdit @1"..
" is available on this server. Type @2 to get a list of ".. " is available on this server. Type @2 to get a list of "..
"commands, or find more information at @3", "commands, or find more information at @3",
worldedit.version_string, minetest.colorize("#00ffff", "//help"), worldedit.version_string, minetest.colorize("#0ff", "//help"),
"https://github.com/Uberi/Minetest-WorldEdit" "https://github.com/Uberi/Minetest-WorldEdit"
), "info") ), "info")
end, end,
@@ -209,10 +217,10 @@ worldedit.register_command("about", {
-- initially copied from builtin/chatcommands.lua -- initially copied from builtin/chatcommands.lua
local function help_command(name, param) local function help_command(name, param)
local function format_help_line(cmd, def, follow_alias) local function format_help_line(cmd, def, follow_alias)
local msg = minetest.colorize("#00ffff", "//"..cmd) local msg = minetest.colorize("#0ff", "//"..cmd)
if def.name ~= cmd then if def.name ~= cmd then
msg = msg .. ": " .. S("alias to @1", msg = msg .. ": " .. S("alias to @1",
minetest.colorize("#00ffff", "//"..def.name)) minetest.colorize("#0ff", "//"..def.name))
if follow_alias then if follow_alias then
msg = msg .. "\n" .. format_help_line(def.name, def) msg = msg .. "\n" .. format_help_line(def.name, def)
end end
@@ -255,7 +263,7 @@ local function help_command(name, param)
end end
end end
table.sort(list) table.sort(list)
local help = minetest.colorize("#00ffff", "//help") local help = minetest.colorize("#0ff", "//help")
return true, S("Available commands: @1@n" return true, S("Available commands: @1@n"
.. "Use '@2' to get more information," .. "Use '@2' to get more information,"
.. " or '@3' to list everything.", .. " or '@3' to list everything.",

View File

@@ -1,6 +1,4 @@
-- Strips any kind of escape codes (translation, colors) from a string local strip_escapes = minetest.strip_escapes or function(input)
-- https://github.com/minetest/minetest/blob/53dd7819277c53954d1298dfffa5287c306db8d0/src/util/string.cpp#L777
local function strip_escapes(input)
local s = function(idx) return input:sub(idx, idx) end local s = function(idx) return input:sub(idx, idx) end
local out = "" local out = ""
local i = 1 local i = 1
@@ -22,12 +20,14 @@ local function strip_escapes(input)
end end
i = i + 1 i = i + 1
end end
--print(("%q -> %q"):format(input, out))
return out return out
end end
local function string_endswith(full, part) local function string_endswith(full, part)
return full:find(part, 1, true) == #full - #part + 1 if #full < #part then
return false
end
return full:sub(-#part) == part
end end
local description_cache = nil local description_cache = nil
@@ -35,7 +35,9 @@ local description_cache = nil
-- normalizes node "description" `nodename`, returning a string (or nil) -- normalizes node "description" `nodename`, returning a string (or nil)
worldedit.normalize_nodename = function(nodename) worldedit.normalize_nodename = function(nodename)
nodename = nodename:gsub("^%s*(.-)%s*$", "%1") -- strip spaces nodename = nodename:gsub("^%s*(.-)%s*$", "%1") -- strip spaces
if nodename == "" then return nil end if nodename == "" then
return nil
end
local fullname = ItemStack({name=nodename}):get_name() -- resolve aliases local fullname = ItemStack({name=nodename}):get_name() -- resolve aliases
if minetest.registered_nodes[fullname] or fullname == "air" then -- full name if minetest.registered_nodes[fullname] or fullname == "air" then -- full name
@@ -51,9 +53,12 @@ worldedit.normalize_nodename = function(nodename)
if description_cache == nil then if description_cache == nil then
-- cache stripped descriptions -- cache stripped descriptions
-- Note: since we don't handle translations this will work only in the original
-- language of the description (English)
description_cache = {} description_cache = {}
for key, value in pairs(minetest.registered_nodes) do for key, def in pairs(minetest.registered_nodes) do
local desc = strip_escapes(value.description):gsub("\n.*", "", 1):lower() local desc = def.short_description or (def.description or ""):gsub("\n.*", "", 1)
desc = strip_escapes(desc):lower()
if desc ~= "" then if desc ~= "" then
description_cache[key] = desc description_cache[key] = desc
end end

View File

@@ -95,6 +95,7 @@ worldedit.register_command("unmark", {
local function set_pos1(name, pos) local function set_pos1(name, pos)
assert(pos) assert(pos)
pos = vector.round(pos)
worldedit.pos1[name] = pos worldedit.pos1[name] = pos
worldedit.mark_pos1(name) worldedit.mark_pos1(name)
worldedit.player_notify(name, S("position @1 set to @2", 1, minetest.pos_to_string(pos)), "ok") worldedit.player_notify(name, S("position @1 set to @2", 1, minetest.pos_to_string(pos)), "ok")
@@ -102,6 +103,7 @@ end
local function set_pos2(name, pos) local function set_pos2(name, pos)
assert(pos) assert(pos)
pos = vector.round(pos)
worldedit.pos2[name] = pos worldedit.pos2[name] = pos
worldedit.mark_pos2(name) worldedit.mark_pos2(name)
worldedit.player_notify(name, S("position @1 set to @2", 2, minetest.pos_to_string(pos)), "ok") worldedit.player_notify(name, S("position @1 set to @2", 2, minetest.pos_to_string(pos)), "ok")
@@ -115,7 +117,7 @@ worldedit.register_command("pos1", {
func = function(name) func = function(name)
local player = minetest.get_player_by_name(name) local player = minetest.get_player_by_name(name)
if not player then return end if not player then return end
set_pos1(name, vector.round(player:get_pos())) set_pos1(name, player:get_pos())
end, end,
}) })
@@ -127,7 +129,7 @@ worldedit.register_command("pos2", {
func = function(name) func = function(name)
local player = minetest.get_player_by_name(name) local player = minetest.get_player_by_name(name)
if not player then return end if not player then return end
set_pos2(name, vector.round(player:get_pos())) set_pos2(name, player:get_pos())
end, end,
}) })

View File

@@ -20,8 +20,8 @@ local function safe_region(name, count, callback)
count_str = minetest.colorize("#f33", count_str:sub(1, -7)) .. count_str:sub(-6, -1) count_str = minetest.colorize("#f33", count_str:sub(1, -7)) .. count_str:sub(-6, -1)
end end
local yes_cmd = minetest.colorize("#00ffff", "//y") local yes_cmd = minetest.colorize("#0ff", "//y")
local no_cmd = minetest.colorize("#00ffff", "//n") local no_cmd = minetest.colorize("#0ff", "//n")
local msg = S("WARNING: this operation could affect up to @1 nodes; type @2 to continue or @3 to cancel", local msg = S("WARNING: this operation could affect up to @1 nodes; type @2 to continue or @3 to cancel",
count_str, yes_cmd, no_cmd) count_str, yes_cmd, no_cmd)
worldedit.player_notify(name, msg, "info") worldedit.player_notify(name, msg, "info")