From 4ab8e7ca2c104ef51414a77520f2f3c788530317 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Thu, 12 Sep 2024 06:54:46 -0700 Subject: [PATCH 01/35] Deprecate scol, scube & srect --- Chat-Command-Reference.md | 27 +++---------- .../commands/selectors/scol.lua | 28 ++----------- .../commands/selectors/scube.lua | 39 ++----------------- .../commands/selectors/srect.lua | 34 ++-------------- 4 files changed, 15 insertions(+), 113 deletions(-) diff --git a/Chat-Command-Reference.md b/Chat-Command-Reference.md index 1256280..3380204 100644 --- a/Chat-Command-Reference.md +++ b/Chat-Command-Reference.md @@ -1201,33 +1201,18 @@ This also synchronises with WorldEdit, as all other WorldEditAdditions commands ### `//scol [ ] ` -Short for _select column_. Sets the pos2 at a set distance along 1 axis from pos1. If the axis isn't specified, defaults the direction you are facing. Implementation thanks to @VorTechnix. - -```weacmd -//scol 10 -//scol x 3 -``` +#### === DEPRECATED === +Please use `//srel` instead. ### `//srect [ []] ` -Short for _select rectangle_. Sets the pos2 at a set distance along 2 axes from pos1. If the axes aren't specified, defaults to positive y and the direction you are facing. Implementation thanks to @VorTechnix. - -```weacmd -//srect x z 10 -//srect 3 -//srect -z y 25 -``` +#### === DEPRECATED === +Please use `//srel` instead. ### `//scube [ [ []]] ` -Short for _select cube_. Sets the pos2 at a set distance along 3 axes from pos1. If the axes aren't specified, defaults to positive y, the direction you are facing and the axis to the left of facing. Implementation thanks to @VorTechnix. - -```weacmd -//scube 5 -//scube z a y 12 -//scube x z 3 -//scube -z 12 -``` +#### === DEPRECATED === +Please use `//srel` instead. ### `//scloud <0-6|stop|reset>` diff --git a/worldeditadditions_commands/commands/selectors/scol.lua b/worldeditadditions_commands/commands/selectors/scol.lua index 1ada5ac..24b7435 100644 --- a/worldeditadditions_commands/commands/selectors/scol.lua +++ b/worldeditadditions_commands/commands/selectors/scol.lua @@ -12,32 +12,10 @@ worldeditadditions_core.register_command("scol", { privs = {worldedit=true}, require_pos = 1, parse = function(params_text) - local vec, tmp = Vector3.new(0, 0, 0), {} - local find = wea_c.split(params_text, "%s", false) - local ax1, sn1, len = (tostring(find[1]):match('[xyz]') or "g"):sub(1,1), wea_c.getsign(find[1]), find[table.maxn(find)] - - tmp.len = tonumber(len) - -- If len == nil cancel the operation - if not tmp.len then return false, "No length specified." end - -- If ax1 is bad send "get" order - if ax1 == "g" then tmp.get = true - else vec[ax1] = sn1 * tmp.len end - - return true, vec, tmp - -- tmp carries: - -- The length (len) arguement to the main function for use if "get" is invoked there - -- The bool value "get" to tell the main function if it needs to populate missing information in vec + ------------------------- end, - func = function(name, vec, tmp) - if tmp.get then - local ax, dir = wea_c.player_axis2d(name) - vec[ax] = tmp.len * dir - end - - local pos2 = vec + Vector3.clone(worldedit.pos1[name]) - worldedit.pos2[name] = pos2 - worldedit.mark_pos2(name) - return true, "position 2 set to "..pos2 + func = function(name) + return true, "DEPRECATED: please use //srel instead..." end, }) diff --git a/worldeditadditions_commands/commands/selectors/scube.lua b/worldeditadditions_commands/commands/selectors/scube.lua index 0c7df3e..a2233d8 100644 --- a/worldeditadditions_commands/commands/selectors/scube.lua +++ b/worldeditadditions_commands/commands/selectors/scube.lua @@ -12,43 +12,10 @@ worldeditadditions_core.register_command("scube", { privs = { worldedit = true }, require_pos = 1, parse = function(params_text) - local vec, tmp = Vector3.new(0, 0, 0), {} - local find = wea_c.split(params_text, "%s", false) - local ax1, ax2, ax3 = (tostring(find[1]):match('[xyz]') or "g"):sub(1,1), (tostring(find[2]):match('[xyz]') or "g"):sub(1,1), - (tostring(find[3]):match('[xyz]') or "g"):sub(1,1) - local sn1, sn2, sn3, len = wea_c.getsign(find[1]), wea_c.getsign(find[2]), wea_c.getsign(find[3]), find[table.maxn(find)] - - tmp.len = tonumber(len) - -- If len is nill cancel the operation - if not tmp.len then return false, "No length specified." end - -- If axis is bad send "get" order - if ax1 == "g" then tmp.get = true - else vec[ax1] = sn1 * tmp.len end - if ax2 == "g" then tmp.get = true - else vec[ax2] = sn2 * tmp.len end - if ax3 == "g" then tmp.get = true - else vec[ax3] = sn3 * tmp.len end - - tmp.axes = ax1..","..ax2..","..ax3 - return true, vec, tmp - -- tmp carries: - -- The length (len) arguement to the main function for use if "get" is invoked there - -- The bool value "get" to tell the main function if it needs to populate missing information in vec - -- The string "axes" to tell the main function what axes are and/or need to be populated if "get" is invoked + ------------------------- end, - func = function(name, vec, tmp) - if tmp.get then - local ax, dir = wea_c.player_axis2d(name) - local _, left, sn = wea_c.axis_left(ax,dir) - if not tmp.axes:find("x") then vec.x = tmp.len * (ax == "x" and dir or sn) end - if not tmp.axes:find("z") then vec.z = tmp.len * (ax == "z" and dir or sn) end - if not tmp.axes:find("y") then vec.y = tmp.len end - end - - local pos2 = vec + Vector3.clone(worldedit.pos1[name]) - worldedit.pos2[name] = pos2 - worldedit.mark_pos2(name) - return true, "position 2 set to "..pos2 + func = function(name) + return true, "DEPRECATED: please use //srel instead..." end, }) diff --git a/worldeditadditions_commands/commands/selectors/srect.lua b/worldeditadditions_commands/commands/selectors/srect.lua index b0cb190..058094e 100644 --- a/worldeditadditions_commands/commands/selectors/srect.lua +++ b/worldeditadditions_commands/commands/selectors/srect.lua @@ -13,38 +13,10 @@ worldeditadditions_core.register_command("srect", { privs = { worldedit = true }, require_pos = 1, parse = function(params_text) - local vec, tmp = Vector3.new(0, 0, 0), {} - local find = wea_c.split(params_text, "%s", false) - local ax1, ax2 = (tostring(find[1]):match('[xyz]') or "g"):sub(1,1), (tostring(find[2]):match('[xyz]') or "g"):sub(1,1) - local sn1, sn2, len = wea_c.getsign(find[1]), wea_c.getsign(find[2]), find[table.maxn(find)] - - tmp.len = tonumber(len) - -- If len == nill cancel the operation - if not tmp.len then return false, "No length specified." end - -- If axis is bad send "get" order - if ax1 == "g" then tmp.get = true - else vec[ax1] = sn1 * tmp.len end - if ax2 == "g" then tmp.get = true - else vec[ax2] = sn2 * tmp.len end - - tmp.axes = ax1..","..ax2 - return true, vec, tmp - -- tmp carries: - -- The length (len) arguement to the main function for use if "get" is invoked there - -- The bool value "get" to tell the main function if it needs to populate missing information in vec - -- The string "axes" to tell the main function what axes are and/or need to be populated if "get" is invoked + ------------------------- end, - func = function(name, vec, tmp) - if tmp.get then - local ax, dir = wea_c.player_axis2d(name) - if not tmp.axes:find("[xz]") then vec[ax] = tmp.len * dir end - if not tmp.axes:find("y") then vec.y = tmp.len end - end - - local p2 = vec + Vector3.clone(worldedit.pos1[name]) - worldedit.pos2[name] = p2 - worldedit.mark_pos2(name) - return true, "position 2 set to "..p2 + func = function(name) + return true, "DEPRECATED: please use //srel instead..." end, }) From 8247a595b18f0e007f6b831fffcf05466dde917e Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Thu, 12 Sep 2024 08:04:21 -0700 Subject: [PATCH 02/35] re-aliasing --- .gitignore | 1 + .../commands/selectors/init.lua | 83 +++++++++++-------- 2 files changed, 50 insertions(+), 34 deletions(-) diff --git a/.gitignore b/.gitignore index 546dc51..76541c0 100644 --- a/.gitignore +++ b/.gitignore @@ -242,6 +242,7 @@ temp/ # VorTechnix stuff .vdev/ +*.old.lua # Created by https://www.toptal.com/developers/gitignore/api/archives # Edit at https://www.toptal.com/developers/gitignore?templates=archives diff --git a/worldeditadditions_commands/commands/selectors/init.lua b/worldeditadditions_commands/commands/selectors/init.lua index 00d5685..52056ed 100644 --- a/worldeditadditions_commands/commands/selectors/init.lua +++ b/worldeditadditions_commands/commands/selectors/init.lua @@ -1,34 +1,49 @@ --- ███████ ███████ ██ ███████ ██████ ████████ ██████ ██████ ███████ --- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ --- ███████ █████ ██ █████ ██ ██ ██ ██ ██████ ███████ --- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ --- ███████ ███████ ███████ ███████ ██████ ██ ██████ ██ ██ ███████ - --- Chat commands that operate on selections. - -local wea_cmdpath = worldeditadditions_commands.modpath .. "/commands/selectors/" -local weac = worldeditadditions_core - -dofile(wea_cmdpath.."srel.lua") -dofile(wea_cmdpath.."scentre.lua") -dofile(wea_cmdpath.."scloud.lua") -dofile(wea_cmdpath.."scol.lua") -dofile(wea_cmdpath.."scube.lua") -dofile(wea_cmdpath.."sfactor.lua") -dofile(wea_cmdpath.."smake.lua") -dofile(wea_cmdpath.."spop.lua") -dofile(wea_cmdpath.."spush.lua") -dofile(wea_cmdpath.."srect.lua") -dofile(wea_cmdpath.."sshift.lua") -dofile(wea_cmdpath.."sstack.lua") - -dofile(wea_cmdpath.."unmark.lua") -dofile(wea_cmdpath.."mark.lua") -dofile(wea_cmdpath.."pos1-2.lua") -dofile(wea_cmdpath.."reset.lua") - --- Aliases -weac.register_alias("sfac", "sfactor") - -weac.register_alias("1", "pos1", true) -- true = override target -weac.register_alias("2", "pos2", true) -- true = override target +-- ███████ ███████ ██ ███████ ██████ ████████ ██████ ██████ ███████ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ███████ █████ ██ █████ ██ ██ ██ ██ ██████ ███████ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ███████ ███████ ███████ ███████ ██████ ██ ██████ ██ ██ ███████ + +-- Chat commands that operate on selections. + +local wea_cmdpath = worldeditadditions_commands.modpath .. "/commands/selectors/" +local weac = worldeditadditions_core + +dofile(wea_cmdpath.."srel.lua") +dofile(wea_cmdpath.."scentre.lua") +dofile(wea_cmdpath.."scloud.lua") +dofile(wea_cmdpath.."smake.lua") +dofile(wea_cmdpath.."spop.lua") +dofile(wea_cmdpath.."spush.lua") +dofile(wea_cmdpath.."sshift.lua") +dofile(wea_cmdpath.."sstack.lua") + +--- DEPRECATED --- +dofile(wea_cmdpath.."scol.lua") +dofile(wea_cmdpath.."scube.lua") +dofile(wea_cmdpath.."srect.lua") +-- TODO: Deprecate this. +dofile(wea_cmdpath.."sfactor.lua") +--- END DEPRECATED --- + +dofile(wea_cmdpath.."unmark.lua") +dofile(wea_cmdpath.."mark.lua") +dofile(wea_cmdpath.."pos1-2.lua") +dofile(wea_cmdpath.."reset.lua") + +-- Aliases +weac.register_alias("sfac", "sfactor") + +-- Pre-subcommand aliases +weac.register_alias("s rel", "srel") +weac.register_alias("s centre", "scentre") +weac.register_alias("s cloud", "scloud") +weac.register_alias("s factor", "sfactor") +weac.register_alias("s make", "smake") +weac.register_alias("s pop", "spop") +weac.register_alias("s push", "spush") +weac.register_alias("s shift", "sshift") +weac.register_alias("s stack", "sstack") + +weac.register_alias("1", "pos1", true) -- true = override target +weac.register_alias("2", "pos2", true) -- true = override target From 005615df02c2a070e88b0ce90dff65bd6d51aed6 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Thu, 12 Sep 2024 09:09:07 -0700 Subject: [PATCH 03/35] spaces in aliases don't work --- .../commands/selectors/init.lua | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/worldeditadditions_commands/commands/selectors/init.lua b/worldeditadditions_commands/commands/selectors/init.lua index 52056ed..5473e03 100644 --- a/worldeditadditions_commands/commands/selectors/init.lua +++ b/worldeditadditions_commands/commands/selectors/init.lua @@ -34,16 +34,5 @@ dofile(wea_cmdpath.."reset.lua") -- Aliases weac.register_alias("sfac", "sfactor") --- Pre-subcommand aliases -weac.register_alias("s rel", "srel") -weac.register_alias("s centre", "scentre") -weac.register_alias("s cloud", "scloud") -weac.register_alias("s factor", "sfactor") -weac.register_alias("s make", "smake") -weac.register_alias("s pop", "spop") -weac.register_alias("s push", "spush") -weac.register_alias("s shift", "sshift") -weac.register_alias("s stack", "sstack") - weac.register_alias("1", "pos1", true) -- true = override target weac.register_alias("2", "pos2", true) -- true = override target From e24997dd80ba54b40692906d582027d4149ed957 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Thu, 12 Sep 2024 09:54:40 -0700 Subject: [PATCH 04/35] Update split.lua --- .../utils/strings/split.lua | 177 +++++++++--------- 1 file changed, 89 insertions(+), 88 deletions(-) diff --git a/worldeditadditions_core/utils/strings/split.lua b/worldeditadditions_core/utils/strings/split.lua index dbdaa74..2173dbd 100644 --- a/worldeditadditions_core/utils/strings/split.lua +++ b/worldeditadditions_core/utils/strings/split.lua @@ -1,89 +1,90 @@ --- Licence: GPLv2 (MPL-2.0 is compatible, so we can use this here) --- Source: https://stackoverflow.com/a/43582076/1460422 - --- gsplit: iterate over substrings in a string separated by a pattern --- --- Parameters: --- text (string) - the string to iterate over --- pattern (string) - the separator pattern --- plain (boolean) - if true (or truthy), pattern is interpreted as a plain --- string, not a Lua pattern --- --- Returns: iterator --- --- Usage: --- for substr in gsplit(text, pattern, plain) do --- doSomething(substr) --- end -local function gsplit(text, pattern, plain) - local splitStart, length = 1, #text - return function () - if splitStart then - local sepStart, sepEnd = string.find(text, pattern, splitStart, plain) - local ret - if not sepStart then - ret = string.sub(text, splitStart) - splitStart = nil - elseif sepEnd < sepStart then - -- Empty separator! - ret = string.sub(text, splitStart, sepStart) - if sepStart < length then - splitStart = sepStart + 1 - else - splitStart = nil - end - else - ret = sepStart > splitStart and string.sub(text, splitStart, sepStart - 1) or '' - splitStart = sepEnd + 1 - end - return ret - end - end -end - - ---- Split a string into substrings separated by a pattern. -- Deprecated --- @param text string The string to iterate over --- @param pattern string The separator pattern --- @param plain boolean If true (or truthy), pattern is interpreted as a --- plain string, not a Lua pattern --- @returns table A sequence table containing the substrings -local function dsplit(text, pattern, plain) - local ret = {} - for match in gsplit(text, pattern, plain) do - table.insert(ret, match) - end - return ret -end - ---- Split a string into substrings separated by a pattern. --- @param str string The string to iterate over --- @param dlm string The delimiter (separator) pattern --- @param plain boolean If true (or truthy), pattern is interpreted as a --- plain string, not a Lua pattern --- @returns table A sequence table containing the substrings -local function split(str,dlm,plain) - local pos, ret = 0, {} - local ins, i = str:find(dlm,pos,plain) - -- "if plain" shaves off some time in the while statement - if plain then - while ins do - table.insert(ret,str:sub(pos,ins - 1)) - pos = ins + #dlm - ins = str:find(dlm,pos,true) - end - else - while ins do - table.insert(ret,str:sub(pos,ins - 1)) - pos = i + 1 - ins, i = str:find(dlm,pos) - end - end - -- print(pos..","..#str) - if str:sub(pos,#str) ~= "" then - table.insert(ret,str:sub(pos,#str)) - end - return ret -end - +-- Licence: GPLv2 (MPL-2.0 is compatible, so we can use this here) +-- Source: https://stackoverflow.com/a/43582076/1460422 + +-- gsplit: iterate over substrings in a string separated by a pattern +-- +-- Parameters: +-- text (string) - the string to iterate over +-- pattern (string) - the separator pattern +-- plain (boolean) - if true (or truthy), pattern is interpreted as a plain +-- string, not a Lua pattern +-- +-- Returns: iterator +-- +-- Usage: +-- for substr in gsplit(text, pattern, plain) do +-- doSomething(substr) +-- end +local function gsplit(text, pattern, plain) + local splitStart, length = 1, #text + return function () + if splitStart then + local sepStart, sepEnd = string.find(text, pattern, splitStart, plain) + local ret + if not sepStart then + ret = string.sub(text, splitStart) + splitStart = nil + elseif sepEnd < sepStart then + -- Empty separator! + ret = string.sub(text, splitStart, sepStart) + if sepStart < length then + splitStart = sepStart + 1 + else + splitStart = nil + end + else + ret = sepStart > splitStart and string.sub(text, splitStart, sepStart - 1) or '' + splitStart = sepEnd + 1 + end + return ret + end + end +end + + +--- Split a string into substrings separated by a pattern. -- Deprecated +-- @param text string The string to iterate over +-- @param pattern string The separator pattern +-- @param plain boolean If true (or truthy), pattern is interpreted as a +-- plain string, not a Lua pattern +-- @returns table A sequence table containing the substrings +local function dsplit(text, pattern, plain) + local ret = {} + for match in gsplit(text, pattern, plain) do + table.insert(ret, match) + end + return ret +end + +--- Split a string into substrings separated by a pattern. +-- @param str string The string to iterate over +-- @param dlm string The delimiter (separator) pattern (default: "%s+") +-- @param plain boolean If true (or truthy), pattern is interpreted as a +-- plain string, not a Lua pattern +-- @returns table A sequence table containing the substrings +local function split(str,dlm,plain) + if not dlm then dlm = "%s+" end + local pos, ret = 0, {} + local ins, i = str:find(dlm,pos,plain) + -- "if plain" shaves off some time in the while statement + if plain then + while ins do + table.insert(ret,str:sub(pos,ins - 1)) + pos = ins + #dlm + ins = str:find(dlm,pos,true) + end + else + while ins do + table.insert(ret,str:sub(pos,ins - 1)) + pos = i + 1 + ins, i = str:find(dlm,pos) + end + end + -- print(pos..","..#str) + if str:sub(pos,#str) ~= "" then + table.insert(ret,str:sub(pos,#str)) + end + return ret +end + return split \ No newline at end of file From 78c418cb24b1374c315a421afc4eac636e2f662a Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Thu, 12 Sep 2024 09:55:02 -0700 Subject: [PATCH 05/35] pos_marker quick patch --- worldeditadditions_core/core/pos_marker_manage.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/worldeditadditions_core/core/pos_marker_manage.lua b/worldeditadditions_core/core/pos_marker_manage.lua index 2811439..51a8142 100644 --- a/worldeditadditions_core/core/pos_marker_manage.lua +++ b/worldeditadditions_core/core/pos_marker_manage.lua @@ -117,7 +117,8 @@ wea_c.entities.pos_marker:addEventListener("update_entity", function(event) ensure_player(event.player_name) if position_entities[event.player_name][event.i] == nil then - minetest.log("warning", "[wea core:pos_manage:EL/update_entity] position_entities".."["..tostring(event.player_name).."]["..tostring(event.i).."] doesnt exist, event object "..wea.inspect(event).."\nPlease check WEA is up to date and then report this in https://github.com/sbrl/Minetest-WorldEditAdditions/issues/105.") + minetest.log("warning", "[wea core:pos_manage:EL/update_entity] position_entities".."["..tostring(event.player_name).."]["..tostring(event.i).."] doesnt exist, event object [broken]"..--wea.inspect(event).. + "\nPlease check WEA is up to date and then report this in https://github.com/sbrl/Minetest-WorldEditAdditions/issues/105.") end wea_c.entities.pos_marker.delete( From 4dacd1059757c12b23fdb88c555692b295c9ce01 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Thu, 12 Sep 2024 15:05:57 -0700 Subject: [PATCH 06/35] sgrow, srel, sshrink UNSTABLE --- .../commands/selectors/init.lua | 4 +- .../commands/selectors/sgrow.lua | 40 ++++++++ .../commands/selectors/srel.lua | 93 +++++++------------ .../commands/selectors/sshrink.lua | 40 ++++++++ 4 files changed, 118 insertions(+), 59 deletions(-) create mode 100644 worldeditadditions_commands/commands/selectors/sgrow.lua create mode 100644 worldeditadditions_commands/commands/selectors/sshrink.lua diff --git a/worldeditadditions_commands/commands/selectors/init.lua b/worldeditadditions_commands/commands/selectors/init.lua index 5473e03..d1dc356 100644 --- a/worldeditadditions_commands/commands/selectors/init.lua +++ b/worldeditadditions_commands/commands/selectors/init.lua @@ -9,13 +9,15 @@ local wea_cmdpath = worldeditadditions_commands.modpath .. "/commands/selectors/" local weac = worldeditadditions_core -dofile(wea_cmdpath.."srel.lua") dofile(wea_cmdpath.."scentre.lua") dofile(wea_cmdpath.."scloud.lua") +dofile(wea_cmdpath.."sgrow.lua") dofile(wea_cmdpath.."smake.lua") dofile(wea_cmdpath.."spop.lua") dofile(wea_cmdpath.."spush.lua") +dofile(wea_cmdpath.."srel.lua") dofile(wea_cmdpath.."sshift.lua") +dofile(wea_cmdpath.."sshrink.lua") dofile(wea_cmdpath.."sstack.lua") --- DEPRECATED --- diff --git a/worldeditadditions_commands/commands/selectors/sgrow.lua b/worldeditadditions_commands/commands/selectors/sgrow.lua new file mode 100644 index 0000000..0a8863b --- /dev/null +++ b/worldeditadditions_commands/commands/selectors/sgrow.lua @@ -0,0 +1,40 @@ +-- local wea = worldeditadditions +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 + + +-- ███████ ██████ ██████ ██████ ██ ██ +-- ██ ██ ██ ██ ██ ██ ██ ██ +-- ███████ ██ ███ ██████ ██ ██ ██ █ ██ +-- ██ ██ ██ ██ ██ ██ ██ ██ ███ ██ +-- ███████ ██████ ██ ██ ██████ ███ ███ + + +worldeditadditions_core.register_command("srel", { + params = "[] [[] [...]]", + description = "Set WorldEdit region position 2 relative to position 1 and player facing.", + privs = { worldedit = true }, + require_pos = 0, + parse = function(params_text) + local ret = wea_c.split(params_text) + if #ret < 1 then return false, "SREL: No params found!" + else return true, ret end + end, + func = function(name, params_text) + local facing = wea_c.player_dir(name) + local min, max = wea_c.parse.directions(params_text, facing) + local pos1 = wea_c.pos.get(name, 1) + local pos2 = wea_c.pos.get(name, 2) + + if not pos2 then wea_c.pos.set(name, 2, pos1) + else pos1, pos2 = Vector3.sort(pos1, pos2) end + + pos1, pos2 = pos1:add(min), pos1:add(max) + + wea_c.pos.set_all(name, {pos1, pos2}) + return true, "Pos1 set to "..pos1..", Pos2 set to "..pos2 + end, +}) + +-- Tests +-- //srel front 5 left 3 y 2 diff --git a/worldeditadditions_commands/commands/selectors/srel.lua b/worldeditadditions_commands/commands/selectors/srel.lua index 75d30d3..214cd82 100644 --- a/worldeditadditions_commands/commands/selectors/srel.lua +++ b/worldeditadditions_commands/commands/selectors/srel.lua @@ -1,58 +1,35 @@ -local wea = worldeditadditions -local wea_c = worldeditadditions_core -local Vector3 = wea_c.Vector3 - - --- ███████ ██████ ███████ ██ --- ██ ██ ██ ██ ██ --- ███████ ██████ █████ ██ --- ██ ██ ██ ██ ██ --- ███████ ██ ██ ███████ ███████ -local function parse_with_name(name,args) - local vec, tmp = Vector3.new(0, 0, 0), {} - local find, _, i = {}, 0, 0 - repeat - _, i, tmp.proc = args:find("([%l%s+-]+%d+)%s*", i) - if tmp.proc:match("[xyz]") then - tmp.ax = tmp.proc:match("[xyz]") - tmp.dir = tonumber(tmp.proc:match("[+-]?%d+")) * (tmp.proc:match("-%l+") and -1 or 1) - else - tmp.ax, _ = wea_c.dir_to_xyz(name, tmp.proc:match("%l+")) - if not tmp.ax then return false, _ end - tmp.dir = tonumber(tmp.proc:match("[+-]?%d+")) * (tmp.proc:match("-%l+") and -1 or 1) * _ - end - vec[tmp.ax] = tmp.dir - until not args:find("([%l%s+-]+%d+)%s*", i) - return true, vec -end -worldeditadditions_core.register_command("srel", { - params = " [ [ ]]", - description = "Set WorldEdit region position 2 at set distances along 3 axes.", - privs = { worldedit = true }, - require_pos = 0, - parse = function(params_text) - if params_text:match("([%l%s+-]+%d+)") then return true, params_text - else return false, "No acceptable params found" end - end, - func = function(name, params_text) - local ret = "" - local _, vec = parse_with_name(name,params_text) - if not _ then return false, vec end - - if not worldedit.pos1[name] then - local pos = wea_c.player_vector(name) + Vector3.new(0.5, -0.5, 0.5) - pos = pos:floor() - worldedit.pos1[name] = pos - worldedit.mark_pos1(name) - ret = "position 1 set to "..pos..", " - end - - local p2 = vec + Vector3.clone(worldedit.pos1[name]) - worldedit.pos2[name] = p2 - worldedit.mark_pos2(name) - return true, ret.."position 2 set to "..p2 - end, -}) - --- Tests --- //srel front 5 left 3 y 2 +-- local wea = worldeditadditions +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 + + +-- ███████ ██████ ███████ ██ +-- ██ ██ ██ ██ ██ +-- ███████ ██████ █████ ██ +-- ██ ██ ██ ██ ██ +-- ███████ ██ ██ ███████ ███████ + + +worldeditadditions_core.register_command("srel", { + params = "[] [[] [...]]", + description = "Set WorldEdit region position 2 relative to position 1 and player facing.", + privs = { worldedit = true }, + require_pos = 0, + parse = function(params_text) + local ret = wea_c.split(params_text) + if #ret < 1 then return false, "SREL: No params found!" + else return true, ret end + end, + func = function(name, params_text) + local facing = wea_c.player_dir(name) + local vec = wea_c.parse.directions(params_text, facing, true) + local pos1 = wea_c.pos.get(name, 1) + local pos2 = pos1:add(vec) + + wea_c.pos.set_all(name, {pos1, pos2}) + return true, "Pos1 set to "..pos1..", Pos2 set to "..pos2 + end, +}) + +-- Tests +-- //srel front 5 left 3 y 2 diff --git a/worldeditadditions_commands/commands/selectors/sshrink.lua b/worldeditadditions_commands/commands/selectors/sshrink.lua new file mode 100644 index 0000000..4147f68 --- /dev/null +++ b/worldeditadditions_commands/commands/selectors/sshrink.lua @@ -0,0 +1,40 @@ +-- local wea = worldeditadditions +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 + + +-- ███████ ███████ ██ ██ ██████ ██ ███ ██ ██ ██ +-- ██ ██ ██ ██ ██ ██ ██ ████ ██ ██ ██ +-- ███████ ███████ ███████ ██████ ██ ██ ██ ██ █████ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ███████ ███████ ██ ██ ██ ██ ██ ██ ████ ██ ██ + + +worldeditadditions_core.register_command("srel", { + params = "[] [[] [...]]", + description = "Set WorldEdit region position 2 relative to position 1 and player facing.", + privs = { worldedit = true }, + require_pos = 0, + parse = function(params_text) + local ret = wea_c.split(params_text) + if #ret < 1 then return false, "SREL: No params found!" + else return true, ret end + end, + func = function(name, params_text) + local facing = wea_c.player_dir(name) + local min, max = wea_c.parse.directions(params_text, facing) + local pos1 = wea_c.pos.get(name, 1) + local pos2 = wea_c.pos.get(name, 2) + + if not pos2 then wea_c.pos.set(name, 2, pos1) + else pos1, pos2 = Vector3.sort(pos1, pos2) end + + pos1, pos2 = pos1:add(max), pos1:add(min) + + wea_c.pos.set_all(name, {pos1, pos2}) + return true, "Pos1 set to "..pos1..", Pos2 set to "..pos2 + end, +}) + +-- Tests +-- //srel front 5 left 3 y 2 From 4ff01bba4ec93dc7394fd2749e3fddc7a12a4530 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Thu, 12 Sep 2024 15:09:04 -0700 Subject: [PATCH 07/35] new commands registered --- worldeditadditions_commands/commands/selectors/sgrow.lua | 4 ++-- worldeditadditions_commands/commands/selectors/sshrink.lua | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/worldeditadditions_commands/commands/selectors/sgrow.lua b/worldeditadditions_commands/commands/selectors/sgrow.lua index 0a8863b..cf08490 100644 --- a/worldeditadditions_commands/commands/selectors/sgrow.lua +++ b/worldeditadditions_commands/commands/selectors/sgrow.lua @@ -10,9 +10,9 @@ local Vector3 = wea_c.Vector3 -- ███████ ██████ ██ ██ ██████ ███ ███ -worldeditadditions_core.register_command("srel", { +worldeditadditions_core.register_command("sgrow", { params = "[] [[] [...]]", - description = "Set WorldEdit region position 2 relative to position 1 and player facing.", + description = "Grow selection region", privs = { worldedit = true }, require_pos = 0, parse = function(params_text) diff --git a/worldeditadditions_commands/commands/selectors/sshrink.lua b/worldeditadditions_commands/commands/selectors/sshrink.lua index 4147f68..5fce5e9 100644 --- a/worldeditadditions_commands/commands/selectors/sshrink.lua +++ b/worldeditadditions_commands/commands/selectors/sshrink.lua @@ -10,9 +10,9 @@ local Vector3 = wea_c.Vector3 -- ███████ ███████ ██ ██ ██ ██ ██ ██ ████ ██ ██ -worldeditadditions_core.register_command("srel", { +worldeditadditions_core.register_command("shrink", { params = "[] [[] [...]]", - description = "Set WorldEdit region position 2 relative to position 1 and player facing.", + description = "Shrink selection region", privs = { worldedit = true }, require_pos = 0, parse = function(params_text) From 23aae6959f105a3ce81e5e9a099d4f59907b6042 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Thu, 12 Sep 2024 17:30:42 -0700 Subject: [PATCH 08/35] stabilizing fixes --- worldeditadditions_commands/commands/selectors/sgrow.lua | 3 ++- worldeditadditions_commands/commands/selectors/srel.lua | 5 ++++- worldeditadditions_commands/commands/selectors/sshrink.lua | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/worldeditadditions_commands/commands/selectors/sgrow.lua b/worldeditadditions_commands/commands/selectors/sgrow.lua index cf08490..2e86b5a 100644 --- a/worldeditadditions_commands/commands/selectors/sgrow.lua +++ b/worldeditadditions_commands/commands/selectors/sgrow.lua @@ -29,8 +29,9 @@ worldeditadditions_core.register_command("sgrow", { if not pos2 then wea_c.pos.set(name, 2, pos1) else pos1, pos2 = Vector3.sort(pos1, pos2) end - pos1, pos2 = pos1:add(min), pos1:add(max) + pos1, pos2 = pos1:add(min), pos2:add(max) + wea_c.pos.clear(name) wea_c.pos.set_all(name, {pos1, pos2}) return true, "Pos1 set to "..pos1..", Pos2 set to "..pos2 end, diff --git a/worldeditadditions_commands/commands/selectors/srel.lua b/worldeditadditions_commands/commands/selectors/srel.lua index 214cd82..3c5eb59 100644 --- a/worldeditadditions_commands/commands/selectors/srel.lua +++ b/worldeditadditions_commands/commands/selectors/srel.lua @@ -22,10 +22,13 @@ worldeditadditions_core.register_command("srel", { end, func = function(name, params_text) local facing = wea_c.player_dir(name) - local vec = wea_c.parse.directions(params_text, facing, true) + local vec, err = wea_c.parse.directions(params_text, facing, true) + if not vec then return false, err end + local pos1 = wea_c.pos.get(name, 1) local pos2 = pos1:add(vec) + wea_c.pos.clear(name) wea_c.pos.set_all(name, {pos1, pos2}) return true, "Pos1 set to "..pos1..", Pos2 set to "..pos2 end, diff --git a/worldeditadditions_commands/commands/selectors/sshrink.lua b/worldeditadditions_commands/commands/selectors/sshrink.lua index 5fce5e9..429b3c8 100644 --- a/worldeditadditions_commands/commands/selectors/sshrink.lua +++ b/worldeditadditions_commands/commands/selectors/sshrink.lua @@ -29,8 +29,9 @@ worldeditadditions_core.register_command("shrink", { if not pos2 then wea_c.pos.set(name, 2, pos1) else pos1, pos2 = Vector3.sort(pos1, pos2) end - pos1, pos2 = pos1:add(max), pos1:add(min) + pos1, pos2 = pos1:add(max), pos2:add(min) + wea_c.pos.clear(name) wea_c.pos.set_all(name, {pos1, pos2}) return true, "Pos1 set to "..pos1..", Pos2 set to "..pos2 end, From 981bdc2b76541fe4075249465b642bfb5d15a2bf Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Thu, 12 Sep 2024 17:45:19 -0700 Subject: [PATCH 09/35] tested: stable enough --- worldeditadditions_commands/commands/selectors/sgrow.lua | 2 +- worldeditadditions_commands/commands/selectors/sshrink.lua | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/worldeditadditions_commands/commands/selectors/sgrow.lua b/worldeditadditions_commands/commands/selectors/sgrow.lua index 2e86b5a..5c15570 100644 --- a/worldeditadditions_commands/commands/selectors/sgrow.lua +++ b/worldeditadditions_commands/commands/selectors/sgrow.lua @@ -17,7 +17,7 @@ worldeditadditions_core.register_command("sgrow", { require_pos = 0, parse = function(params_text) local ret = wea_c.split(params_text) - if #ret < 1 then return false, "SREL: No params found!" + if #ret < 1 then return false, "SGROW: No params found!" else return true, ret end end, func = function(name, params_text) diff --git a/worldeditadditions_commands/commands/selectors/sshrink.lua b/worldeditadditions_commands/commands/selectors/sshrink.lua index 429b3c8..6de886a 100644 --- a/worldeditadditions_commands/commands/selectors/sshrink.lua +++ b/worldeditadditions_commands/commands/selectors/sshrink.lua @@ -10,14 +10,14 @@ local Vector3 = wea_c.Vector3 -- ███████ ███████ ██ ██ ██ ██ ██ ██ ████ ██ ██ -worldeditadditions_core.register_command("shrink", { +worldeditadditions_core.register_command("sshrink", { params = "[] [[] [...]]", description = "Shrink selection region", privs = { worldedit = true }, require_pos = 0, parse = function(params_text) local ret = wea_c.split(params_text) - if #ret < 1 then return false, "SREL: No params found!" + if #ret < 1 then return false, "SSHRINK: No params found!" else return true, ret end end, func = function(name, params_text) From f51ed36f9ed803889f56c402ce4b497a07712c3c Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Thu, 12 Sep 2024 18:30:21 -0700 Subject: [PATCH 10/35] some optimization --- worldeditadditions_commands/commands/selectors/sgrow.lua | 1 - worldeditadditions_commands/commands/selectors/srel.lua | 1 - worldeditadditions_commands/commands/selectors/sshrink.lua | 1 - 3 files changed, 3 deletions(-) diff --git a/worldeditadditions_commands/commands/selectors/sgrow.lua b/worldeditadditions_commands/commands/selectors/sgrow.lua index 5c15570..f84a058 100644 --- a/worldeditadditions_commands/commands/selectors/sgrow.lua +++ b/worldeditadditions_commands/commands/selectors/sgrow.lua @@ -31,7 +31,6 @@ worldeditadditions_core.register_command("sgrow", { pos1, pos2 = pos1:add(min), pos2:add(max) - wea_c.pos.clear(name) wea_c.pos.set_all(name, {pos1, pos2}) return true, "Pos1 set to "..pos1..", Pos2 set to "..pos2 end, diff --git a/worldeditadditions_commands/commands/selectors/srel.lua b/worldeditadditions_commands/commands/selectors/srel.lua index 3c5eb59..de2e176 100644 --- a/worldeditadditions_commands/commands/selectors/srel.lua +++ b/worldeditadditions_commands/commands/selectors/srel.lua @@ -28,7 +28,6 @@ worldeditadditions_core.register_command("srel", { local pos1 = wea_c.pos.get(name, 1) local pos2 = pos1:add(vec) - wea_c.pos.clear(name) wea_c.pos.set_all(name, {pos1, pos2}) return true, "Pos1 set to "..pos1..", Pos2 set to "..pos2 end, diff --git a/worldeditadditions_commands/commands/selectors/sshrink.lua b/worldeditadditions_commands/commands/selectors/sshrink.lua index 6de886a..db27973 100644 --- a/worldeditadditions_commands/commands/selectors/sshrink.lua +++ b/worldeditadditions_commands/commands/selectors/sshrink.lua @@ -31,7 +31,6 @@ worldeditadditions_core.register_command("sshrink", { pos1, pos2 = pos1:add(max), pos2:add(min) - wea_c.pos.clear(name) wea_c.pos.set_all(name, {pos1, pos2}) return true, "Pos1 set to "..pos1..", Pos2 set to "..pos2 end, From 12747f652460337e4235037efea87de5d5a3be67 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Fri, 13 Sep 2024 02:54:38 +0100 Subject: [PATCH 11/35] pos_marker_manage: fix crash --- worldeditadditions_core/core/pos_marker_manage.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/worldeditadditions_core/core/pos_marker_manage.lua b/worldeditadditions_core/core/pos_marker_manage.lua index 51a8142..f7e3dae 100644 --- a/worldeditadditions_core/core/pos_marker_manage.lua +++ b/worldeditadditions_core/core/pos_marker_manage.lua @@ -117,8 +117,7 @@ wea_c.entities.pos_marker:addEventListener("update_entity", function(event) ensure_player(event.player_name) if position_entities[event.player_name][event.i] == nil then - minetest.log("warning", "[wea core:pos_manage:EL/update_entity] position_entities".."["..tostring(event.player_name).."]["..tostring(event.i).."] doesnt exist, event object [broken]"..--wea.inspect(event).. - "\nPlease check WEA is up to date and then report this in https://github.com/sbrl/Minetest-WorldEditAdditions/issues/105.") + minetest.log("warning", "[wea core:pos_manage:EL/update_entity] position_entities".."["..tostring(event.player_name).."]["..tostring(event.i).."] doesnt exist, event object "..wea_c.inspect(event).."\nPlease check WEA is up to date and then report this in https://github.com/sbrl/Minetest-WorldEditAdditions/issues/105.") end wea_c.entities.pos_marker.delete( From d1c4f9bd191bcdec7b2254d8fa6aa1a9e94ba7b5 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Fri, 13 Sep 2024 10:47:42 -0700 Subject: [PATCH 12/35] finish deprecation --- .../commands/selectors/scol.lua | 12 ++++++------ .../commands/selectors/scube.lua | 10 +++++----- .../commands/selectors/srect.lua | 10 +++++----- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/worldeditadditions_commands/commands/selectors/scol.lua b/worldeditadditions_commands/commands/selectors/scol.lua index 24b7435..be80ddb 100644 --- a/worldeditadditions_commands/commands/selectors/scol.lua +++ b/worldeditadditions_commands/commands/selectors/scol.lua @@ -7,15 +7,15 @@ local Vector3 = wea_c.Vector3 -- ██ ██ ██ ██ ██ -- ███████ ██████ ██████ ███████ worldeditadditions_core.register_command("scol", { - params = "[] ", - description = "Set WorldEdit region position 2 at a set distance along 1 axis.", - privs = {worldedit=true}, + params = "None", + description = "Deprecated.", + privs = { worldedit = true }, require_pos = 1, parse = function(params_text) - ------------------------- + return params_text end, - func = function(name) - return true, "DEPRECATED: please use //srel instead..." + func = function(name, paramtext) + return false, "DEPRECATED: please use //srel instead..." end, }) diff --git a/worldeditadditions_commands/commands/selectors/scube.lua b/worldeditadditions_commands/commands/selectors/scube.lua index a2233d8..14bf0e1 100644 --- a/worldeditadditions_commands/commands/selectors/scube.lua +++ b/worldeditadditions_commands/commands/selectors/scube.lua @@ -7,15 +7,15 @@ local Vector3 = wea_c.Vector3 -- ██ ██ ██ ██ ██ ██ ██ -- ███████ ██████ ██████ ██████ ███████ worldeditadditions_core.register_command("scube", { - params = "[ [ []]] ", - description = "Set WorldEdit region position 2 at a set distance along 3 axes.", + params = "None", + description = "Deprecated.", privs = { worldedit = true }, require_pos = 1, parse = function(params_text) - ------------------------- + return params_text end, - func = function(name) - return true, "DEPRECATED: please use //srel instead..." + func = function(name, paramtext) + return false, "DEPRECATED: please use //srel instead..." end, }) diff --git a/worldeditadditions_commands/commands/selectors/srect.lua b/worldeditadditions_commands/commands/selectors/srect.lua index 058094e..ab67808 100644 --- a/worldeditadditions_commands/commands/selectors/srect.lua +++ b/worldeditadditions_commands/commands/selectors/srect.lua @@ -8,15 +8,15 @@ local Vector3 = wea_c.Vector3 -- ██ ██ ██ ██ ██ ██ -- ███████ ██ ██ ███████ ██████ ██ worldeditadditions_core.register_command("srect", { - params = "[ []] ", - description = "Set WorldEdit region position 2 at a set distance along 2 axes.", + params = "None", + description = "Deprecated.", privs = { worldedit = true }, require_pos = 1, parse = function(params_text) - ------------------------- + return params_text end, - func = function(name) - return true, "DEPRECATED: please use //srel instead..." + func = function(name, paramtext) + return false, "DEPRECATED: please use //srel instead..." end, }) From 38b55712cc631c5fbd81c9a6bbc863977c8b8d1b Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Sun, 15 Sep 2024 09:15:22 -0700 Subject: [PATCH 13/35] scentre, sshift stable + housekeeping --- .../commands/selectors/scentre.lua | 68 +++++++++---------- .../commands/selectors/sgrow.lua | 2 + .../commands/selectors/srect.lua | 1 - .../commands/selectors/sshift.lua | 43 +++--------- .../commands/selectors/sshrink.lua | 2 + 5 files changed, 48 insertions(+), 68 deletions(-) diff --git a/worldeditadditions_commands/commands/selectors/scentre.lua b/worldeditadditions_commands/commands/selectors/scentre.lua index af589ff..1d88b75 100644 --- a/worldeditadditions_commands/commands/selectors/scentre.lua +++ b/worldeditadditions_commands/commands/selectors/scentre.lua @@ -1,35 +1,33 @@ -local wea_c = worldeditadditions_core -local Vector3 = wea_c.Vector3 - --- ███████ ██████ ███████ ███ ██ ████████ ███████ ██████ --- ██ ██ ██ ████ ██ ██ ██ ██ ██ --- ███████ ██ █████ ██ ██ ██ ██ █████ ██████ --- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ --- ███████ ██████ ███████ ██ ████ ██ ███████ ██ ██ -worldeditadditions_core.register_command("scentre", { - params = "", - description = "Set WorldEdit region positions 1 and 2 to the centre of the current selection.", - privs = {worldedit=true}, - require_pos = 2, - parse = function(params_text) - return true - end, - func = function(name) - local mean = Vector3.mean( - Vector3.clone(worldedit.pos1[name]), - Vector3.clone(worldedit.pos2[name]) - ) - local pos1, pos2 = Vector3.clone(mean), Vector3.clone(mean) - - pos1 = pos1:floor() - pos2 = pos2:ceil() - - worldedit.pos1[name], worldedit.pos2[name] = pos1, pos2 - worldedit.mark_pos1(name) - worldedit.mark_pos2(name) - - return true, "position 1 set to "..pos1..", position 2 set to "..pos2 - end, -}) - --- lua print(vecs.mean.x..", "..vecs.mean.y..", "..vecs.mean.z) +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 + +-- ███████ ██████ ███████ ███ ██ ████████ ███████ ██████ +-- ██ ██ ██ ████ ██ ██ ██ ██ ██ +-- ███████ ██ █████ ██ ██ ██ ██ █████ ██████ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ███████ ██████ ███████ ██ ████ ██ ███████ ██ ██ +worldeditadditions_core.register_command("scentre", { + params = "", + description = "Set WorldEdit region positions 1 and 2 to the centre of the current selection.", + privs = {worldedit=true}, + require_pos = 2, + parse = function(params_text) + return true + end, + func = function(name) + local mean = Vector3.mean( + Vector3.clone(wea_c.pos.get(name, 1)), + Vector3.clone(wea_c.pos.get(name, 2)) + ) + local pos1, pos2 = Vector3.clone(mean), Vector3.clone(mean) + + pos1 = pos1:floor() + pos2 = pos2:ceil() + + wea_c.pos.set_all(name, {pos1, pos2}) + + return true, "Pos1 set to "..pos1..", Pos2 set to "..pos2 + end, +}) + +-- lua print(vecs.mean.x..", "..vecs.mean.y..", "..vecs.mean.z) diff --git a/worldeditadditions_commands/commands/selectors/sgrow.lua b/worldeditadditions_commands/commands/selectors/sgrow.lua index f84a058..7cd48db 100644 --- a/worldeditadditions_commands/commands/selectors/sgrow.lua +++ b/worldeditadditions_commands/commands/selectors/sgrow.lua @@ -23,6 +23,8 @@ worldeditadditions_core.register_command("sgrow", { func = function(name, params_text) local facing = wea_c.player_dir(name) local min, max = wea_c.parse.directions(params_text, facing) + if not min then return false, max end + local pos1 = wea_c.pos.get(name, 1) local pos2 = wea_c.pos.get(name, 2) diff --git a/worldeditadditions_commands/commands/selectors/srect.lua b/worldeditadditions_commands/commands/selectors/srect.lua index ab67808..1333aa2 100644 --- a/worldeditadditions_commands/commands/selectors/srect.lua +++ b/worldeditadditions_commands/commands/selectors/srect.lua @@ -1,4 +1,3 @@ -local wea = worldeditadditions local wea_c = worldeditadditions_core local Vector3 = wea_c.Vector3 diff --git a/worldeditadditions_commands/commands/selectors/sshift.lua b/worldeditadditions_commands/commands/selectors/sshift.lua index 5ce1b54..e3894e2 100644 --- a/worldeditadditions_commands/commands/selectors/sshift.lua +++ b/worldeditadditions_commands/commands/selectors/sshift.lua @@ -1,4 +1,3 @@ -local wea = worldeditadditions local wea_c = worldeditadditions_core local Vector3 = worldeditadditions.Vector3 @@ -8,46 +7,26 @@ local Vector3 = worldeditadditions.Vector3 -- ██ ██ ██ ██ ██ ██ ██ -- ███████ ███████ ██ ██ ██ ██ ██ -local function parse_with_name(name,args) - local vec, tmp = Vector3.new(0, 0, 0), {} - local find, _, i = {}, 0, 0 - repeat - _, i, tmp.proc = args:find("([%l%s+-]+%d+)%s*", i) - if tmp.proc:match("[xyz]") then - tmp.ax = tmp.proc:match("[xyz]") - tmp.dir = tonumber(tmp.proc:match("[+-]?%d+")) * (tmp.proc:match("-%l+") and -1 or 1) - else - tmp.ax, _ = wea_c.dir_to_xyz(name, tmp.proc:match("%l+")) - if not tmp.ax then return false, _ end - tmp.dir = tonumber(tmp.proc:match("[+-]?%d+")) * (tmp.proc:match("-%l+") and -1 or 1) * _ - end - vec[tmp.ax] = tmp.dir - until not args:find("([%l%s+-]+%d+)%s*", i) - return true, vec -end - worldeditadditions_core.register_command("sshift", { - params = " [ [ ]]", + params = "[] [[] [...]]", description = "Shift the WorldEdit region in 3 dimensions.", privs = { worldedit = true }, require_pos = 2, parse = function(params_text) - if params_text:match("([%l%s+-]+%d+)") then return true, params_text - else return false, "No acceptable params found" end + local ret = wea_c.split(params_text) + if #ret < 1 then return false, "SSHIFT: No params found!" + else return true, ret end end, func = function(name, params_text) - local _, vec = parse_with_name(name,params_text) - if not _ then return false, vec end + local facing = wea_c.player_dir(name) + local vec, err = wea_c.parse.directions(params_text, facing, true) + if not vec then return false, err end - local pos1 = vec:add(worldedit.pos1[name]) - worldedit.pos1[name] = pos1 - worldedit.mark_pos1(name) + local pos1 = vec:add(wea_c.pos.get(name, 1)) + local pos2 = vec:add(wea_c.pos.get(name, 2)) - local pos2 = vec:add(worldedit.pos2[name]) - worldedit.pos2[name] = pos2 - worldedit.mark_pos2(name) - - return true, "Region shifted by " .. (vec.x + vec.y + vec.z) .. " nodes." + wea_c.pos.set_all(name, {pos1, pos2}) + return true, "Pos1 set to "..pos1..", Pos2 set to "..pos2 end, }) diff --git a/worldeditadditions_commands/commands/selectors/sshrink.lua b/worldeditadditions_commands/commands/selectors/sshrink.lua index db27973..923faa9 100644 --- a/worldeditadditions_commands/commands/selectors/sshrink.lua +++ b/worldeditadditions_commands/commands/selectors/sshrink.lua @@ -23,6 +23,8 @@ worldeditadditions_core.register_command("sshrink", { func = function(name, params_text) local facing = wea_c.player_dir(name) local min, max = wea_c.parse.directions(params_text, facing) + if not min then return false, max end + local pos1 = wea_c.pos.get(name, 1) local pos2 = wea_c.pos.get(name, 2) From 4c4fab189e3d4be28002b6642fc1e01cb98dcae6 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Sun, 15 Sep 2024 17:04:57 -0700 Subject: [PATCH 14/35] Update smake.lua --- .../commands/selectors/smake.lua | 264 +++++++++--------- 1 file changed, 131 insertions(+), 133 deletions(-) diff --git a/worldeditadditions_commands/commands/selectors/smake.lua b/worldeditadditions_commands/commands/selectors/smake.lua index 91ba3e0..1a1d1ef 100644 --- a/worldeditadditions_commands/commands/selectors/smake.lua +++ b/worldeditadditions_commands/commands/selectors/smake.lua @@ -1,133 +1,131 @@ -local wea = worldeditadditions -local wea_c = worldeditadditions_core -local Vector3 = wea_c.Vector3 - - --- ███████ ███ ███ █████ ██ ██ ███████ --- ██ ████ ████ ██ ██ ██ ██ ██ --- ███████ ██ ████ ██ ███████ █████ █████ --- ██ ██ ██ ██ ██ ██ ██ ██ ██ --- ███████ ██ ██ ██ ██ ██ ██ ███████ -worldeditadditions_core.register_command("smake", { - params = " [ []]", - description = "Make one or more axes of the current selection odd, even, or equal to another.", - privs = { worldedit = true }, - require_pos = 2, - parse = function(params_text) - -- Split params_text, check for missing arguments and fill in empty spots - local parts = wea_c.split(params_text, "%s+", false) - if #parts < 2 then - return false, "Error: Not enough arguments. Expected \" [ []]\"." - else - for i=3,4 do if not parts[i] then parts[i] = false end end - end - - -- Initialize local variables and sets - local oper, mode, targ, base = wea_c.table.unpack(parts) - local operSet, modeSet = wea_c.table.makeset {"equal", "odd", "even"}, wea_c.table.makeset {"grow", "shrink", "avg"} - - -- Main Logic - -- Check base if base is present and if so valid. - if base then - if base:match("[xyz]") then -- ensure correct base syntax - base = base:match("[xyz]") - else - return false, "Error: Invalid base \""..base.."\". Expected \"x\", \"y\" or \"z\"." - end - end - - -- Resolve target then mode (in that order incase mode is target). - if not targ then -- If no target set to default (xz) - targ = "xz" - elseif targ:match("[xyz]+") then -- ensure correct target syntax - targ = table.concat(wea_c.tochars(targ:match("[xyz]+"),true,true)) - else - return false, "Error: Invalid \""..targ.."\". Expected \"x\" and or \"y\" and or \"z\"." - end - - if mode == "average" then -- If mode is average set to avg - mode = "avg" - elseif mode:match("[xyz]+") then -- If target is actually base set vars to correct values. - base, targ, mode = targ:sub(1,1), table.concat(wea_c.tochars(mode:match("[xyz]+"),true,true)), false - elseif not modeSet[mode] and not base then -- If mode is invalid and base isn't present throw error - return false, "Error: Invalid \""..mode.."\". Expected \"grow\", \"shrink\", or \"average\"/\"avg\"." - end - - if base then - if oper ~= "equal" then base = false -- If operation isn't equalize we don't need - elseif targ:match(base) then -- Else check that base is not in target and return error if it is - return false, "Error: ("..base..") cannot be included in ("..targ..")." - end - end - - -- Check if operator is valid - if not operSet[oper] then - return false, "Error: Invalid operator \""..oper.."\". Expected \"odd\", \"even\" or \"equal\"." - end - - return true, oper, mode, targ, base - end, - func = function(name, oper, mode, targ, base) - local pos1, pos2 = Vector3.clone(worldedit.pos1[name]), Vector3.clone(worldedit.pos2[name]) - local eval -- Declare eval placeholder function to edit later - - local delta = pos2 - pos1 -- local delta equation: Vd(a) = V2(a) - V1(a) - local _tl = #targ -- Get targ length as a variable incase mode is "average"/"avg" - local targ = wea_c.tocharset(targ) -- Break up targ string into set table - local _m = 0 -- _m is the container to hold the max, min or average (depending on the mode) of the axes in targ - - -- set _m to the max, min or mean of the target axes depending on mode or base if it exists - if base then _m = delta[base] - elseif mode == "avg" then - for k,v in pairs(targ) do _m = _m + math.abs(delta[k]) end - _m = _m / _tl - elseif mode == "grow" then - for k,v in pairs(targ) do if math.abs(delta[k]) > _m then _m = math.abs(delta[k]) end end - else - -- Take output of next(targ), put it in a table, wrap the table in brackets to force evlauation so that - -- we can call the first element of that table to serve as the key for a call to delta. - _m = delta[({next(targ)})[1]] - for k,v in pairs(targ) do if math.abs(delta[k]) < _m then _m = math.abs(delta[k]) end end - end - - if oper == "even" then - eval = function(int) - local tmp, abs, neg = int / 2, math.abs(int), int < 0 - if math.floor(tmp) ~= tmp then - if mode == "avg" then - if int > _m then int = abs - 1 - else int = abs + 1 end - elseif mode == "shrink" and abs > 0 then int = abs - 1 - else int = abs + 1 end - end - if neg then int = int * -1 end -- Ensure correct facing direction - return int - end - elseif oper == "odd" then - eval = function(int) - local tmp, abs, neg = int / 2, math.abs(int), int < 0 - if math.floor(tmp) == tmp then - if mode == "avg" then - if int > _m then int = abs - 1 - else int = abs + 1 end - elseif mode == "shrink" and abs > 0 then int = abs - 1 - else int = abs + 1 end - end - if neg then int = int * -1 end - return int - end - else -- Case: oper == "equal" - eval = function(int) - -- Bug: shrink sets pos2 to pos1 - if int < 0 then return _m * -1 - else return _m end - end - end - - for k,v in pairs(targ) do delta[k] = eval(delta[k]) end - - worldedit.pos2[name] = pos1 + delta - worldedit.mark_pos2(name) - return true, "position 2 set to "..pos2 - end -}) +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 + + +-- ███████ ███ ███ █████ ██ ██ ███████ +-- ██ ████ ████ ██ ██ ██ ██ ██ +-- ███████ ██ ████ ██ ███████ █████ █████ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ███████ ██ ██ ██ ██ ██ ██ ███████ +worldeditadditions_core.register_command("smake", { + params = " [ []]", + description = "Make one or more axes of the current selection odd, even, or equal to another.", + privs = { worldedit = true }, + require_pos = 2, + parse = function(params_text) + -- Split params_text, check for missing arguments and fill in empty spots + local parts = wea_c.split(params_text, "%s+", false) + if #parts < 2 then + return false, "Error: Not enough arguments. Expected \" [ []]\"." + else + for i=3,4 do if not parts[i] then parts[i] = false end end + end + + -- Initialize local variables and sets + local oper, mode, targ, base = wea_c.table.unpack(parts) + local operSet, modeSet = wea_c.table.makeset {"equal", "odd", "even"}, wea_c.table.makeset {"grow", "shrink", "avg"} + + -- Main Logic + -- Check base if base is present and if so valid. + if base then + if base:match("[xyz]") then -- ensure correct base syntax + base = base:match("[xyz]") + else + return false, "Error: Invalid base \""..base.."\". Expected \"x\", \"y\" or \"z\"." + end + end + + -- Resolve target then mode (in that order incase mode is target). + if not targ then -- If no target set to default (xz) + targ = "xz" + elseif targ:match("[xyz]+") then -- ensure correct target syntax + targ = table.concat(wea_c.tochars(targ:match("[xyz]+"),true,true)) + else + return false, "Error: Invalid \""..targ.."\". Expected \"x\" and or \"y\" and or \"z\"." + end + + if mode == "average" then -- If mode is average set to avg + mode = "avg" + elseif mode:match("[xyz]+") then -- If target is actually base set vars to correct values. + base, targ, mode = targ:sub(1,1), table.concat(wea_c.tochars(mode:match("[xyz]+"),true,true)), false + elseif not modeSet[mode] and not base then -- If mode is invalid and base isn't present throw error + return false, "Error: Invalid \""..mode.."\". Expected \"grow\", \"shrink\", or \"average\"/\"avg\"." + end + + if base then + if oper ~= "equal" then base = false -- If operation isn't equalize we don't need + elseif targ:match(base) then -- Else check that base is not in target and return error if it is + return false, "Error: ("..base..") cannot be included in ("..targ..")." + end + end + + -- Check if operator is valid + if not operSet[oper] then + return false, "Error: Invalid operator \""..oper.."\". Expected \"odd\", \"even\" or \"equal\"." + end + + return true, oper, mode, targ, base + end, + func = function(name, oper, mode, targ, base) + local pos1, pos2 = Vector3.clone(wea_c.pos.get(name, 1)), Vector3.clone(wea_c.pos.get(name, 2)) + local eval -- Declare eval placeholder function to edit later + + local delta = pos2 - pos1 -- local delta equation: Vd(a) = V2(a) - V1(a) + local _tl = #targ -- Get targ length as a variable incase mode is "average"/"avg" + local targ = wea_c.tocharset(targ) -- Break up targ string into set table + local _m = 0 -- _m is the container to hold the max, min or average (depending on the mode) of the axes in targ + + -- set _m to the max, min or mean of the target axes depending on mode or base if it exists + if base then _m = delta[base] + elseif mode == "avg" then + for k,v in pairs(targ) do _m = _m + math.abs(delta[k]) end + _m = _m / _tl + elseif mode == "grow" then + for k,v in pairs(targ) do if math.abs(delta[k]) > _m then _m = math.abs(delta[k]) end end + else + -- Take output of next(targ), put it in a table, wrap the table in brackets to force evlauation so that + -- we can call the first element of that table to serve as the key for a call to delta. + _m = delta[({next(targ)})[1]] + for k,v in pairs(targ) do if math.abs(delta[k]) < _m then _m = math.abs(delta[k]) end end + end + + if oper == "even" then + eval = function(int) + local tmp, abs, neg = int / 2, math.abs(int), int < 0 + if math.floor(tmp) ~= tmp then + if mode == "avg" then + if int > _m then int = abs - 1 + else int = abs + 1 end + elseif mode == "shrink" and abs > 0 then int = abs - 1 + else int = abs + 1 end + end + if neg then int = int * -1 end -- Ensure correct facing direction + return int + end + elseif oper == "odd" then + eval = function(int) + local tmp, abs, neg = int / 2, math.abs(int), int < 0 + if math.floor(tmp) == tmp then + if mode == "avg" then + if int > _m then int = abs - 1 + else int = abs + 1 end + elseif mode == "shrink" and abs > 0 then int = abs - 1 + else int = abs + 1 end + end + if neg then int = int * -1 end + return int + end + else -- Case: oper == "equal" + eval = function(int) + -- Bug: shrink sets pos2 to pos1 + if int < 0 then return _m * -1 + else return _m end + end + end + + for k,_ in pairs(targ) do delta[k] = eval(delta[k]) end + + wea_c.pos.set(name, 2, pos1 + delta) + return true, "Pos2 set to "..pos2 + end +}) From d43c8212d263d9981ff161128f2c20acd13263c8 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Tue, 17 Sep 2024 12:29:34 -0700 Subject: [PATCH 15/35] Documentation Update --- CHANGELOG.md | 451 ++--- Chat-Command-Reference.md | 3471 +++++++++++++++++++------------------ 2 files changed, 1999 insertions(+), 1923 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a81b158..9b40630 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,221 +1,230 @@ -# WorldEditAdditions Changelog -It's about time I started a changelog! This will serve from now on as the main changelog for WorldEditAdditions. - -Note to self: See the bottom of this file for the release template text. - - -## v1.15: The untitled update (unreleased) -- Added the optional argument `all` to [`//unmark`](https://worldeditadditions.mooncarrot.space/Reference/#unmark) -- Added a (rather nuclear) fix (attempt 4) at finally exterminating all zombie region marker walls forever - - This is not a hotfix to avoid endless small releases fixing the bug, as it's clear it's much more difficult to fix on all systems than initially expected -- Added [`//nodeapply`](https://worldeditadditions.mooncarrot.space/Reference/#nodeapply), a generalisation of [`//airapply`](https://worldeditadditions.mooncarrot.space/Reference/#airapply) that works with a defined list of nodes. Check out [the reference](https://worldeditadditions.mooncarrot.space/Reference/#nodeapply) - it has some cool tricks to it! (thanks for suggesting, @kliv91 from the Discord server!) -- Added [`//ngroups`](https://worldeditadditions.mooncarrot.space/Reference/#ngroups), which lists the groups that a given node is a member of. Useful when paired with [`//nodeapply`](https://worldeditadditions.mooncarrot.space/Reference/#nodeapply)! -- Added [`//rotate+`](https://worldeditadditions.mooncarrot.space/Reference/#rotate) to rotate regions through arbitrary series of potentially non-axis-aligned rotations. **Does not support slabs/stairs yet,** but this is on the todo list! -- Added [`//speed`](https://worldeditadditions.mooncarrot.space/Reference/#rotate) to adjust your own movement speed - - Also added an associated [movement speed adjustment tool](https://worldeditadditions.mooncarrot.space/Reference/#movement), which looks like this: ![A picture of the move speed adjustment tool. It looks like a monarch butterfly.](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/dev/worldeditadditions_farwand/textures/worldeditadditions_movement.png) -- Added [`//set+`](https://worldeditadditions.mooncarrot.space/Reference/#set) for setting nodes and param2/light levels quickly. - - NOTE TO SELF: Setting light values doesn't appear to be working very well for some reason -- Added [`//ndef`](https://worldeditadditions.mooncarrot.space/Reference/#ndef) to print a given node's definition table. This is for debugging and development purposes. - -### Bugfixes and changes -- Don't warn on failed registration of `//flora` → [`//bonemeal`](https://worldeditadditions.mooncarrot.space/Reference/#bonemeal) if the `bonemeal` mod isn't installed (e.g. in MineClone2) - thanks @VorTechnix in #106 -- Improve documentation of [`//noise2d`](https://worldeditadditions.mooncarrot.space/Reference/#noise2d). If it still doesn't make sense, please let me know. It's a complicated command that needs reworking a bit to be easier to use. -- Alias `//napply` to [`//nodeapply`](https://worldeditadditions.mooncarrot.space/Reference/#nodeapply) - - -### Lua API changes -- Add `core.pos.get12(player_name, sort=false)` - - -## v1.14.5: The multipoint update, hotfix 5 (1st August 2023) -- Fix a bug where creative players in survival couldn't punch out position markers -- Added [`//listentities`](https://worldeditadditions.mooncarrot.space/Reference/#listentities), which lists all currently loaded `ObjectRef`s. This is intended for debugging mods - thanks to @Zughy in #103 - - -## v1.14.4: The multipoint update, hotfix 4 (31st July 2023) -- When any segment of the marker wall is punched, unmark the entire wall - thanks to @Zughy in #102 - - -## v1.14.3: The multipoint update, hotfix 3 (18th July 2023) -- Fix regions not remembering their state and being unresettable - - -## v1.14.2: The multipoint update, hotfix 2 (15th July 2023) -- Fix crash in `//subdivide`, again due to the new position system - - -## v1.14.1: The multipoint update, hotfix 1 (12th July 2023) - - Fix issue #100, which caused a crash as `//pos1` and `//pos2` allowed non-integer positions to be set - - -## v1.14: The multipoint update (11th July 2023) - - Add `//dome+`, which allows you to change the direction the dome is pointing in, and also create multiple domes at once - - Add `//metaball`, which renders 2 or more [metaballs](https://en.wikipedia.org/wiki/Metaballs) in Minetest - - Significant backend refactoring to tidy things up - - Add new multi-point selection wand ![A picture of the multi-point wand](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/worldeditadditions_farwand/textures/worldeditadditions_multiwand.png) to select many points at once. - - Implement custom region boxing UI, which replaces the WorldEdit region box when using WorldEditAdditions wands. - - Is backwards compatible with regular WorldEdit wands and tools, as WorldEditAdditions keeps the new positioning system in sync with WorldEdit's. - - The new multipoint wand required this as a prerequisite - - Add [`//pos`](https://worldeditadditions.mooncarrot.space/Reference/#pos), for setting any numbered point (i.e. not just pos1 and pos2, but pos3 and beyond) - - Add [`//spline`](https://worldeditadditions.mooncarrot.space/Reference/#spline), for drawing curved lines with an arbitrary number of points **(uses the new multi-point wand)** - - Add [`//revolve`](https://worldeditadditions.mooncarrot.space/Reference/#revolve), which makes multiple evenly-spaced rotated copies of the defined region **(uses the new multi-point wand)** - - [`//copy+`](https://worldeditadditions.mooncarrot.space/Reference/#copy), [`//move+`](https://worldeditadditions.mooncarrot.space/Reference/#move): - - Added support for integrated `airapply` mode, which replaces nodes at the target only if they are air - append `airapply`/`aa` to the command to use - - Respect node rotation (i.e. param2) when copying/moving - - Override `//move` and `//copy` by default - -### Bugfixes and changes - - Migrate from `depends.txt` to `mod.conf` - - Cloud wand: fix typo in item description. - - Commands that modify the terrain now ignore liquids - - `//sculpt`: - - Fix undefined `default` brush - - Change defaults to `circle`, `height=1`, and `brushsize=8`. - - Change argument ordering to put `height` after `brushsize` instead of the other way around - - `//hollow`: Fix safe region bug - - Make `//pos1`, `//1`, `//pos2`, `//2`, `//mark`, `//unmark`, and `//reset` aware of the new WEA positioning system - - -## v1.13: The transformational update (2nd January 2022) - - Add [`//sfactor`](https://worldeditadditions.mooncarrot.space/Reference/#sfactor) (_selection factor_) - Selection Tools by @VorTechnix are finished for now. - - Add [`//mface`](https://worldeditadditions.mooncarrot.space/Reference/#mface) (_measure facing_), [`//midpos`](https://worldeditadditions.mooncarrot.space/Reference/#midpos) (_measure middle position_), [`//msize`](https://worldeditadditions.mooncarrot.space/Reference/#msize) (_measure size_), [`//mtrig`](#mtrig) (_measure trigonometry_) - Measuring Tools implemented by @VorTechnix. - - Add [`//airapply`](https://worldeditadditions.mooncarrot.space/Reference/#airapply) for applying commands only to air nodes in the defined region - - Add [`//wcorner`](https://worldeditadditions.mooncarrot.space/Reference/#wcorner) (_wireframe corners_), [`//wbox`](https://worldeditadditions.mooncarrot.space/Reference/#wbox) (_wireframe box_), [`//wcompass`](https://worldeditadditions.mooncarrot.space/Reference/#wcompass) (_wireframe compass_) - Wireframes implemented by @VorTechnix. - - Add [`//for`](https://worldeditadditions.mooncarrot.space/Reference/#for) for executing commands while changing their arguments - Implemented by @VorTechnix. - - Add [`//sshift`](https://worldeditadditions.mooncarrot.space/Reference/#sshift) (_selection shift_) - WorldEdit cuboid manipulator replacements implemented by @VorTechnix. - - Add [`//noise2d`](https://worldeditadditions.mooncarrot.space/Reference/#noise2d) for perturbing terrain with multiple different noise functions - - Add [`//noiseapply2d`](https://worldeditadditions.mooncarrot.space/Reference/#noiseapply2d) for running commands on columns where a noise value is over a threshold - - Add [`//ellipsoid2`](https://worldeditadditions.mooncarrot.space/Reference/#ellipsoid2) which creates an ellipsoid that fills the defined region - - Add [`//spiral2`](https://worldeditadditions.mooncarrot.space/Reference/#spiral2) for creating both square and circular spirals - - Add [`//copy+`](https://worldeditadditions.mooncarrot.space/Reference/#copy) for copying a defined region across multiple axes at once - - Add [`//move+`](https://worldeditadditions.mooncarrot.space/Reference/#move) for moving a defined region across multiple axes at once - - Add [`//sculpt`](https://worldeditadditions.mooncarrot.space/Reference/#sculpt) and [`//sculptlist`](https://worldeditadditions.mooncarrot.space/Reference/#sculptlist) for sculpting terrain using a number of custom brushes. - - Use [luacheck](https://github.com/mpeterv/luacheck) to find and fix a large number of bugs and other issues [code quality from now on will be significantly improved] - - Multiple commands: Allow using quotes (`"thing"`, `'thing'`) to quote values when splitting - - [`//layers`](https://worldeditadditions.mooncarrot.space/Reference/#layers): Add optional slope constraint (inspired by [WorldPainter](https://worldpainter.net/)) - - [`//bonemeal`](https://worldeditadditions.mooncarrot.space/Reference/#bonemeal): Add optional node list constraint - - [`//walls`](https://worldeditadditions.mooncarrot.space/Reference/#walls): Add optional thickness argument - - [`//sstack`](https://worldeditadditions.mooncarrot.space/Reference/#sstack): Add human-readable approx volumes of regions in the selection stack - - -### Bugfixes - - `//floodfill`: Fix crash caused by internal refactoring of the `Queue` data structure - - `//spop`: Fix wording in displayed message - - Sapling alias compatibility: - - Correct alias of `default:sapling` from `oak` to `apple` (since it produces apples) - - `moretrees:apple_tree_sapling_ongen` from `apple` to `apple_moretrees` - - Add `plum` → `plumtree:sapling` - - Add `holly` ⇒ `hollytree:sapling` - - `//replacemix`: Improve error handling to avoid crashes (thanks, Jonathon for reporting via Discord!) - - Cloud wand: Improve chat message text - - Fix `bonemeal` mod detection to look for the global `bonemeal`, not whether the `bonemeal` mod name has been loaded - - `//bonemeal`: Fix argument parsing - - `//walls`: Prevent crash if no parameters are specified by defaulting to `dirt` as the replace_node - - `//maze`, `//maze3d`: - - Fix generated maze not reaching the very edge of the defined region - - Fix crash if no arguments are specified - - Fix automatic seed when generating many mazes in the same second (e.g. with `//for`, `//many`) - - `//convolve`: Fix those super tall pillars appearing randomly - - cloud wand: improve feedback messages sent to players - - `//forest`: Update sapling aliases for `bamboo` → `bambo:sprout` instead of `bamboo:sapling` - - -## v1.12: The selection tools update (26th June 2021) - - Add `//spush`, `//spop`, and `//sstack` - - Add `//srect` (_select rectangle_), `//scol` (_select column_), `//scube` (_select cube_) - thanks, @VorTechnix! - - Add `//scloud` (_select point cloud_), `//scentre` (_select centre node(s)_), `//srel` (_select relative_) - thanks, @VorTechnix! - - Add `//smake` (_selection make_) - thanks, @VorTechnix! - - Significantly refactored backend utility functions (more to come in future updates) - - Add new universal chance parsing - - Any `` can now either be a 1-in-N number (e.g. `4`, `10`), or a percentage chance (e.g. `50%`, `10%`). - - Caveat: Percentages are converted to a 1-in-N chance, but additionally that number is rounded down in some places - - `//torus`, `//hollowtorus`: Add optional new axes - - `//torus`, `//ellipsoid`: Add optional hollow keyword - @VorTechnix - - `//multi`: Add curly brace syntax for nesting command calls ([more information](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#multi-command_a-command_b-command_c-)) - - `//erode`: Add new `river` erosion algorithm for filling in potholes and removing pillars - -### Bugfixes - - `//bonemeal`: Try bonemealing everything that isn't an air block (#49) - - `//overlay`: Don't place nodes above water - - `//multi`: Improve resilience by handling some edge cases - - `//layers`: Fix crash due to outdated debug code - - `//erode`/snowballs: Fix assignment to undeclared variable - - `//floodfill`: Fix error handling - - -## v1.11: The big data update (25th January 2021) - - Add `//scale` (currently **experimental**) - - Scale operations that scale up and down at the same time are split into 2 separate operations automatically (scaling up is always performed first) - - `//count`: Make numbers human-readable - - Tip: Use a monospace font for the chat window, and the columns will be aligned! - - Add `//hollow` for hollowing out areas (a step towards parity with Minecraft WorldEdit) - - `//subdivide`: Improve performance of initial chunk counting algorithm - it should get started on the job _much_ quicker now (especially on large regions) - - `//subdivide`: Fix a bug where the entire defined region was emerged all at once instead of in chunks - - `//subdivide`: Fix performance & memory usage issues - - Fix passing arguments to the command being executed - - If you encounter any other issues with it over large areas (particularly 2000x150x2000 and larger), please let me know - - Bugfix: Fix obscure crash in calls to `human_size` ("unknown" will now be returned if passed junk) - - `//many` can now be used with commands with no arguments. - - `//conv`, `//erode`, `//fillcaves`: Treat liquids as air - - Add new [cloud wand](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#cloud-wand) - - `//conv`, `//erode`: Minor refactoring to improve code clarity - - -## v1.10: The tidyup update (16th January 2021) - - `//maze`: Fix some parts of generated mazes staying solid - - `//maze`, `//maze3d`: Allow non-number seeds (existing seeds aren't affected - they will still produce identical output) - - `//many`: Improve format of progress messages, add ETA - - `//subdivide`: Make asynchronous, and use `minetest.emerge_area()` to ensure areas are loaded before executing on a subdivision chunk - - This will ensure that `//subdivide`ing enormous regions should now function as expected. Want to level an entire rainforest with `//subdivide` and `//clearcut`? Now you can! :D - - Add `//line` for drawing simple lines - - -## v1.9: The Nature Update (20th September 2020) - - Add `//many` for executing a command many times in a row - - Add **experimental** `//erode` command - - Add `//fillcaves` command - fills in all air nodes beneath non air-nodes - - Add `//forest` command for quickly generating forests, and `//saplingaliases` to compliment it - - Add `//ellipsoidapply`: Like `//cubeapply`, but clips the result to an ellipsoid that is the size of the defined region. - - Fix some minor bugs and edge cases - - `//subdivide`: Print status update when completing the last chunk - - `//count`: Optimise by removing nested `for` loops - - -## v1.8: The Quality of Life Update (17th July 2020) - - Update `//multi` to display human readable times (e.g. `2.11mins` instead of `126600ms`) - - Far wand: Notify player when setting pos1 and pos2 - - Make timings more accurate (use `minetest.get_us_time()` instead of `os.clock()`) - - Add _experimental_ `//subdivide` command - - Attempt to fix a crash on startup due to a dependency issue (#21) - - -## v1.7: The Terrain Update! (21st June 2020) - - Added `//layers` (like WorldEdit for Minecraft's `//naturalize`) - - Added `//convolve` (advanced terrain smoothing inspired by image editors) - - Added far wand (like the regular WorldEdit wand, but with a configurable range that can extend to 100s of blocks) -[/list] - - -## Release text template -The text below is used as a template when making releases. - --------- - -INTRO - -See below the changelog for instructions on how to update. - -CHANGELOG HERE - - -## Updating -Updating depends on how you installed WorldEditAdditions. - - - UI in Minetest: There should be an update button for you to click in the mod menu - - ContentDB: Download the latest update from [here](https://content.minetest.net/packages/Starbeamrainbowlabs/worldeditadditions/) - - Git: `cd` to the WorldEditAdditions directory and run `git pull` (**Important:** Recently, WorldEditAdditions changed the default branch from `master` to `main`. If you're updating from before then, you'll need to re-clone the mod or else do some git-fu) - -After installing the update, don't forget to restart your client and / or server. - - --------- +# WorldEditAdditions Changelog +It's about time I started a changelog! This will serve from now on as the main changelog for WorldEditAdditions. + +Note to self: See the bottom of this file for the release template text. + + +## v1.15: The deprecation update (unreleased) +- Added the optional argument `all` to [`//unmark`](https://worldeditadditions.mooncarrot.space/Reference/#unmark) +- Added a (rather nuclear) fix (attempt 4) at finally exterminating all zombie region marker walls forever + - This is not a hotfix to avoid endless small releases fixing the bug, as it's clear it's much more difficult to fix on all systems than initially expected +- Added [`//nodeapply`](https://worldeditadditions.mooncarrot.space/Reference/#nodeapply), a generalisation of [`//airapply`](https://worldeditadditions.mooncarrot.space/Reference/#airapply) that works with a defined list of nodes. Check out [the reference](https://worldeditadditions.mooncarrot.space/Reference/#nodeapply) - it has some cool tricks to it! (thanks for suggesting, @kliv91 from the Discord server!) +- Added [`//ngroups`](https://worldeditadditions.mooncarrot.space/Reference/#ngroups), which lists the groups that a given node is a member of. Useful when paired with [`//nodeapply`](https://worldeditadditions.mooncarrot.space/Reference/#nodeapply)! +- Added [`//rotate+`](https://worldeditadditions.mooncarrot.space/Reference/#rotate) to rotate regions through arbitrary series of potentially non-axis-aligned rotations. **Does not support slabs/stairs yet,** but this is on the todo list! +- Added [`//speed`](https://worldeditadditions.mooncarrot.space/Reference/#rotate) to adjust your own movement speed + - Also added an associated [movement speed adjustment tool](https://worldeditadditions.mooncarrot.space/Reference/#movement), which looks like this: ![A picture of the move speed adjustment tool. It looks like a monarch butterfly.](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/dev/worldeditadditions_farwand/textures/worldeditadditions_movement.png) +- Added [`//set+`](https://worldeditadditions.mooncarrot.space/Reference/#set) for setting nodes and param2/light levels quickly. + - NOTE TO SELF: Setting light values doesn't appear to be working very well for some reason +- Added [`//ndef`](https://worldeditadditions.mooncarrot.space/Reference/#ndef) to print a given node's definition table. This is for debugging and development purposes. +- Added `//sgrow` and `//sshrink` and aliased them over WorldEdit equivalents (`//expand`, `//outset` and `//contract`, `//inset` respectively). +- Added Universal Axis Keyword (UAK) System parser. - Implementation by @VorTechnix + - See [UAK System reference] for details. (Note to self hook up hyperlink) + +### Bugfixes and changes +- Don't warn on failed registration of `//flora` → [`//bonemeal`](https://worldeditadditions.mooncarrot.space/Reference/#bonemeal) if the `bonemeal` mod isn't installed (e.g. in MineClone2) - thanks @VorTechnix in #106 +- Improve documentation of [`//noise2d`](https://worldeditadditions.mooncarrot.space/Reference/#noise2d). If it still doesn't make sense, please let me know. It's a complicated command that needs reworking a bit to be easier to use. +- Alias `//napply` to [`//nodeapply`](https://worldeditadditions.mooncarrot.space/Reference/#nodeapply) +- Re-factored selection tools to all use WEA position system and UAK Parser if applicable. - Re-factor by @VorTechnix +- `//sshift` now overrides `//shift` from WorldEdit. - Re-factor by @VorTechnix + +### Deprecations +- Deprecated `//scol`, `//srect` and `//scube`. Now that `//srel` is using UAK parser there is no need for them. - Deprecated by @VorTechnix +- Deprecated `//sfactor`. Now that `//sgrow` and `//sshrink` exist it is no longer needed. - Deprecated by @VorTechnix + + +### Lua API changes +- Add `core.pos.get12(player_name, sort=false)` + + +## v1.14.5: The multipoint update, hotfix 5 (1st August 2023) +- Fix a bug where creative players in survival couldn't punch out position markers +- Added [`//listentities`](https://worldeditadditions.mooncarrot.space/Reference/#listentities), which lists all currently loaded `ObjectRef`s. This is intended for debugging mods - thanks to @Zughy in #103 + + +## v1.14.4: The multipoint update, hotfix 4 (31st July 2023) +- When any segment of the marker wall is punched, unmark the entire wall - thanks to @Zughy in #102 + + +## v1.14.3: The multipoint update, hotfix 3 (18th July 2023) +- Fix regions not remembering their state and being unresettable + + +## v1.14.2: The multipoint update, hotfix 2 (15th July 2023) +- Fix crash in `//subdivide`, again due to the new position system + + +## v1.14.1: The multipoint update, hotfix 1 (12th July 2023) + - Fix issue #100, which caused a crash as `//pos1` and `//pos2` allowed non-integer positions to be set + + +## v1.14: The multipoint update (11th July 2023) + - Add `//dome+`, which allows you to change the direction the dome is pointing in, and also create multiple domes at once + - Add `//metaball`, which renders 2 or more [metaballs](https://en.wikipedia.org/wiki/Metaballs) in Minetest + - Significant backend refactoring to tidy things up + - Add new multi-point selection wand ![A picture of the multi-point wand](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/worldeditadditions_farwand/textures/worldeditadditions_multiwand.png) to select many points at once. + - Implement custom region boxing UI, which replaces the WorldEdit region box when using WorldEditAdditions wands. + - Is backwards compatible with regular WorldEdit wands and tools, as WorldEditAdditions keeps the new positioning system in sync with WorldEdit's. + - The new multipoint wand required this as a prerequisite + - Add [`//pos`](https://worldeditadditions.mooncarrot.space/Reference/#pos), for setting any numbered point (i.e. not just pos1 and pos2, but pos3 and beyond) + - Add [`//spline`](https://worldeditadditions.mooncarrot.space/Reference/#spline), for drawing curved lines with an arbitrary number of points **(uses the new multi-point wand)** + - Add [`//revolve`](https://worldeditadditions.mooncarrot.space/Reference/#revolve), which makes multiple evenly-spaced rotated copies of the defined region **(uses the new multi-point wand)** + - [`//copy+`](https://worldeditadditions.mooncarrot.space/Reference/#copy), [`//move+`](https://worldeditadditions.mooncarrot.space/Reference/#move): + - Added support for integrated `airapply` mode, which replaces nodes at the target only if they are air - append `airapply`/`aa` to the command to use + - Respect node rotation (i.e. param2) when copying/moving + - Override `//move` and `//copy` by default + +### Bugfixes and changes + - Migrate from `depends.txt` to `mod.conf` + - Cloud wand: fix typo in item description. + - Commands that modify the terrain now ignore liquids + - `//sculpt`: + - Fix undefined `default` brush + - Change defaults to `circle`, `height=1`, and `brushsize=8`. + - Change argument ordering to put `height` after `brushsize` instead of the other way around + - `//hollow`: Fix safe region bug + - Make `//pos1`, `//1`, `//pos2`, `//2`, `//mark`, `//unmark`, and `//reset` aware of the new WEA positioning system + + +## v1.13: The transformational update (2nd January 2022) + - Add [`//sfactor`](https://worldeditadditions.mooncarrot.space/Reference/#sfactor) (_selection factor_) - Selection Tools by @VorTechnix are finished for now. + - Add [`//mface`](https://worldeditadditions.mooncarrot.space/Reference/#mface) (_measure facing_), [`//midpos`](https://worldeditadditions.mooncarrot.space/Reference/#midpos) (_measure middle position_), [`//msize`](https://worldeditadditions.mooncarrot.space/Reference/#msize) (_measure size_), [`//mtrig`](#mtrig) (_measure trigonometry_) - Measuring Tools implemented by @VorTechnix. + - Add [`//airapply`](https://worldeditadditions.mooncarrot.space/Reference/#airapply) for applying commands only to air nodes in the defined region + - Add [`//wcorner`](https://worldeditadditions.mooncarrot.space/Reference/#wcorner) (_wireframe corners_), [`//wbox`](https://worldeditadditions.mooncarrot.space/Reference/#wbox) (_wireframe box_), [`//wcompass`](https://worldeditadditions.mooncarrot.space/Reference/#wcompass) (_wireframe compass_) - Wireframes implemented by @VorTechnix. + - Add [`//for`](https://worldeditadditions.mooncarrot.space/Reference/#for) for executing commands while changing their arguments - Implemented by @VorTechnix. + - Add [`//sshift`](https://worldeditadditions.mooncarrot.space/Reference/#sshift) (_selection shift_) - WorldEdit cuboid manipulator replacements implemented by @VorTechnix. + - Add [`//noise2d`](https://worldeditadditions.mooncarrot.space/Reference/#noise2d) for perturbing terrain with multiple different noise functions + - Add [`//noiseapply2d`](https://worldeditadditions.mooncarrot.space/Reference/#noiseapply2d) for running commands on columns where a noise value is over a threshold + - Add [`//ellipsoid2`](https://worldeditadditions.mooncarrot.space/Reference/#ellipsoid2) which creates an ellipsoid that fills the defined region + - Add [`//spiral2`](https://worldeditadditions.mooncarrot.space/Reference/#spiral2) for creating both square and circular spirals + - Add [`//copy+`](https://worldeditadditions.mooncarrot.space/Reference/#copy) for copying a defined region across multiple axes at once + - Add [`//move+`](https://worldeditadditions.mooncarrot.space/Reference/#move) for moving a defined region across multiple axes at once + - Add [`//sculpt`](https://worldeditadditions.mooncarrot.space/Reference/#sculpt) and [`//sculptlist`](https://worldeditadditions.mooncarrot.space/Reference/#sculptlist) for sculpting terrain using a number of custom brushes. + - Use [luacheck](https://github.com/mpeterv/luacheck) to find and fix a large number of bugs and other issues [code quality from now on will be significantly improved] + - Multiple commands: Allow using quotes (`"thing"`, `'thing'`) to quote values when splitting + - [`//layers`](https://worldeditadditions.mooncarrot.space/Reference/#layers): Add optional slope constraint (inspired by [WorldPainter](https://worldpainter.net/)) + - [`//bonemeal`](https://worldeditadditions.mooncarrot.space/Reference/#bonemeal): Add optional node list constraint + - [`//walls`](https://worldeditadditions.mooncarrot.space/Reference/#walls): Add optional thickness argument + - [`//sstack`](https://worldeditadditions.mooncarrot.space/Reference/#sstack): Add human-readable approx volumes of regions in the selection stack + + +### Bugfixes + - `//floodfill`: Fix crash caused by internal refactoring of the `Queue` data structure + - `//spop`: Fix wording in displayed message + - Sapling alias compatibility: + - Correct alias of `default:sapling` from `oak` to `apple` (since it produces apples) + - `moretrees:apple_tree_sapling_ongen` from `apple` to `apple_moretrees` + - Add `plum` → `plumtree:sapling` + - Add `holly` ⇒ `hollytree:sapling` + - `//replacemix`: Improve error handling to avoid crashes (thanks, Jonathon for reporting via Discord!) + - Cloud wand: Improve chat message text + - Fix `bonemeal` mod detection to look for the global `bonemeal`, not whether the `bonemeal` mod name has been loaded + - `//bonemeal`: Fix argument parsing + - `//walls`: Prevent crash if no parameters are specified by defaulting to `dirt` as the replace_node + - `//maze`, `//maze3d`: + - Fix generated maze not reaching the very edge of the defined region + - Fix crash if no arguments are specified + - Fix automatic seed when generating many mazes in the same second (e.g. with `//for`, `//many`) + - `//convolve`: Fix those super tall pillars appearing randomly + - cloud wand: improve feedback messages sent to players + - `//forest`: Update sapling aliases for `bamboo` → `bambo:sprout` instead of `bamboo:sapling` + + +## v1.12: The selection tools update (26th June 2021) + - Add `//spush`, `//spop`, and `//sstack` + - Add `//srect` (_select rectangle_), `//scol` (_select column_), `//scube` (_select cube_) - thanks, @VorTechnix! + - Add `//scloud` (_select point cloud_), `//scentre` (_select centre node(s)_), `//srel` (_select relative_) - thanks, @VorTechnix! + - Add `//smake` (_selection make_) - thanks, @VorTechnix! + - Significantly refactored backend utility functions (more to come in future updates) + - Add new universal chance parsing + - Any `` can now either be a 1-in-N number (e.g. `4`, `10`), or a percentage chance (e.g. `50%`, `10%`). + - Caveat: Percentages are converted to a 1-in-N chance, but additionally that number is rounded down in some places + - `//torus`, `//hollowtorus`: Add optional new axes + - `//torus`, `//ellipsoid`: Add optional hollow keyword - @VorTechnix + - `//multi`: Add curly brace syntax for nesting command calls ([more information](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#multi-command_a-command_b-command_c-)) + - `//erode`: Add new `river` erosion algorithm for filling in potholes and removing pillars + +### Bugfixes + - `//bonemeal`: Try bonemealing everything that isn't an air block (#49) + - `//overlay`: Don't place nodes above water + - `//multi`: Improve resilience by handling some edge cases + - `//layers`: Fix crash due to outdated debug code + - `//erode`/snowballs: Fix assignment to undeclared variable + - `//floodfill`: Fix error handling + + +## v1.11: The big data update (25th January 2021) + - Add `//scale` (currently **experimental**) + - Scale operations that scale up and down at the same time are split into 2 separate operations automatically (scaling up is always performed first) + - `//count`: Make numbers human-readable + - Tip: Use a monospace font for the chat window, and the columns will be aligned! + - Add `//hollow` for hollowing out areas (a step towards parity with Minecraft WorldEdit) + - `//subdivide`: Improve performance of initial chunk counting algorithm - it should get started on the job _much_ quicker now (especially on large regions) + - `//subdivide`: Fix a bug where the entire defined region was emerged all at once instead of in chunks + - `//subdivide`: Fix performance & memory usage issues + - Fix passing arguments to the command being executed + - If you encounter any other issues with it over large areas (particularly 2000x150x2000 and larger), please let me know + - Bugfix: Fix obscure crash in calls to `human_size` ("unknown" will now be returned if passed junk) + - `//many` can now be used with commands with no arguments. + - `//conv`, `//erode`, `//fillcaves`: Treat liquids as air + - Add new [cloud wand](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#cloud-wand) + - `//conv`, `//erode`: Minor refactoring to improve code clarity + + +## v1.10: The tidyup update (16th January 2021) + - `//maze`: Fix some parts of generated mazes staying solid + - `//maze`, `//maze3d`: Allow non-number seeds (existing seeds aren't affected - they will still produce identical output) + - `//many`: Improve format of progress messages, add ETA + - `//subdivide`: Make asynchronous, and use `minetest.emerge_area()` to ensure areas are loaded before executing on a subdivision chunk + - This will ensure that `//subdivide`ing enormous regions should now function as expected. Want to level an entire rainforest with `//subdivide` and `//clearcut`? Now you can! :D + - Add `//line` for drawing simple lines + + +## v1.9: The Nature Update (20th September 2020) + - Add `//many` for executing a command many times in a row + - Add **experimental** `//erode` command + - Add `//fillcaves` command - fills in all air nodes beneath non air-nodes + - Add `//forest` command for quickly generating forests, and `//saplingaliases` to compliment it + - Add `//ellipsoidapply`: Like `//cubeapply`, but clips the result to an ellipsoid that is the size of the defined region. + - Fix some minor bugs and edge cases + - `//subdivide`: Print status update when completing the last chunk + - `//count`: Optimise by removing nested `for` loops + + +## v1.8: The Quality of Life Update (17th July 2020) + - Update `//multi` to display human readable times (e.g. `2.11mins` instead of `126600ms`) + - Far wand: Notify player when setting pos1 and pos2 + - Make timings more accurate (use `minetest.get_us_time()` instead of `os.clock()`) + - Add _experimental_ `//subdivide` command + - Attempt to fix a crash on startup due to a dependency issue (#21) + + +## v1.7: The Terrain Update! (21st June 2020) + - Added `//layers` (like WorldEdit for Minecraft's `//naturalize`) + - Added `//convolve` (advanced terrain smoothing inspired by image editors) + - Added far wand (like the regular WorldEdit wand, but with a configurable range that can extend to 100s of blocks) +[/list] + + +## Release text template +The text below is used as a template when making releases. + +-------- + +INTRO + +See below the changelog for instructions on how to update. + +CHANGELOG HERE + + +## Updating +Updating depends on how you installed WorldEditAdditions. + + - UI in Minetest: There should be an update button for you to click in the mod menu + - ContentDB: Download the latest update from [here](https://content.minetest.net/packages/Starbeamrainbowlabs/worldeditadditions/) + - Git: `cd` to the WorldEditAdditions directory and run `git pull` (**Important:** Recently, WorldEditAdditions changed the default branch from `master` to `main`. If you're updating from before then, you'll need to re-clone the mod or else do some git-fu) + +After installing the update, don't forget to restart your client and / or server. + + +-------- diff --git a/Chat-Command-Reference.md b/Chat-Command-Reference.md index 3380204..1aa4716 100644 --- a/Chat-Command-Reference.md +++ b/Chat-Command-Reference.md @@ -1,1702 +1,1769 @@ -# Chat Command Reference - -This is the full chat command reference for WorldEditAdditions. Having trouble finding the section you want? Try the **[quick reference](https://github.com/sbrl/Minetest-WorldEditAdditions#quick-command-reference)** instead, which has links to back to sections of this document! - -**Check out the reference on the new website - it's even searchable: ** - -Other useful links: - - - [WorldEditAdditions quick reference](https://github.com/sbrl/Minetest-WorldEditAdditions#quick-command-reference) - - [WorldEditAdditions Chat Command Cookbook](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Cookbook.md) - - [WorldEdit Chat Command Reference](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md) - - [`we_env`](https://github.com/sfan5/we_env#readme) - -**Note:** If anything in this reference isn't clear, that's a bug. Please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new) (or even better a PR improving it) to let me know precisely which bit you don't understand and why. - -## Geometry - - -### `//metaball add | remove | render [] | list | clear | volume` -Draws two or more [metaballs](https://en.wikipedia.org/wiki/Metaballs). Based on a subcommand system, since each metaball may have a different radius. - -Calling `//metaball render ` actually makes changes to the world - all others manipulate an internal player-local list of metaballs to be drawn. - -#### `//metaball add ` -Adds a new metaball to the (player-local) list of metaballs to be draw with the given radius. The position of the new metaball is taken from pos1. - -```weacmd -//metaball add 5 -//metaball add 10 -//metaball add 65 -``` - -#### `//metaball remove ` -Removes the metaball with the given index from the list. See also `//metaball list`. - -```weacmd -//metaball remove 1 -//metaball remove 2 -//metaball remove 5 -``` - -#### `//metaball render []` -Renders the current list of metaballs to the world using replace_node to draw with. - -Threshold is a value that acts as an offset for large or small the metaballs should be. Defaults to 1, with larger values resulting in **smaller** metaballs and smaller values resulting in **larger** metaballs. It is not recommended to set threshold to a negative number. - -Does not clear the list of metaballs after rendering - see `//metaball clear` for that. - -```weacmd -//metaball render dirt -//metaball render glass -//metaball render stone -//metaball render stone 2 -//metaball render cobble 0.5 -``` - -#### `//metaball list` -Lists all the metaballs currently registered for the current player (all `//metaball` commands operate on the current player's metaball list only), and their indexes, positions, and sizes. Useful when using `//metaball remove ` to identify which metaball you want to remove. - -Example output: - -``` -Index Position Radius -1 (-495, 37, 150) 7 -2 (-506, 33, 142) 7 -3 (-516, 35, 152) 10 -``` - -```weacmd -//metaball list -``` - -#### `//metaball clear` -Clears the list of metaballs for the current player. - -```weacmd -//metaball clear -``` - -#### `//metaball volume` -Calculate an estimated volume of the metaballs currently in the list. - -```weacmd -//metaball volume -``` - - -### `//ellipsoid [h[ollow]]` -Creates a solid ellipsoid at position 1 with the radius `(rx, ry, rz)`. - -```weacmd -//ellipsoid 10 5 15 ice -//ellipsoid 3 5 10 dirt -//ellipsoid 20 10 40 air -//ellipsoid 14 5 8 steelblock h -//ellipsoid 7 4 7 papyrus hollow -``` - -### `//hollowellipsoid ` -Creates a hollow ellipsoid at position 1 with the radius `(rx, ry, rz)`. Works the same way as `//ellipsoid` does. - -```weacmd -//hollowellipsoid 10 5 15 glass -//hollowellipsoid 21 11 41 stone -``` - -### `//ellipsoid2 [ [h[ollow]]]` -Creates an (optionally hollow) solid ellipsoid that fills the defined region. - -```weacmd -//ellipsoid2 -//ellipsoid2 ice -//ellipsoid2 air -//ellipsoid2 steelblock h -//ellipsoid2 papyrus hollow -``` - - -### `//torus [ [h[ollow]]]` -Creates a solid torus at position 1 with the specified major and minor radii. The major radius is the distance from the centre of the torus to the centre of the circle bit, and the minor radius is the radius of the circle bit. - -The optional axes sets the axes upon which the torus will lay flat. Possible values: `xy` (the default), `xz`, `yz`. A single axis may also be specified (i.e. `x`, `y`, or `z`) - this will be interpreted as the axis that runs through the hole in the middle of the torus. - -```weacmd -//torus 15 5 stone -//torus 5 3 meselamp -//torus 10 6 sandstone xz -//torus 10 6 wool:red y -//torus 25 10 dirt xz hollow -``` - -### `//hollowtorus []` -Creates a hollow torus at position 1 with the radius major and minor radii. Works the same way as `//torus` does. - -```weacmd -//hollowtorus 10 5 glass -//hollowtorus 21 11 stone -//hollowtorus 18 6 dirt xz -``` - -### `//line [ []]` -Draw a line from position 1 to position 2, optionally with a given thickness. - -The radius can be thought of as the thickness of the line, and is defined as the distance from a given node to an imaginary line from pos1 to pos2. Defaults to drawing with dirt and a radius of 1. - -Floating-point values are fully supported for the radius. - -```weacmd -//line -//line stone -//line sandstone 3 -//line glass 0.5 -``` - -### `//hollow []` -Replaces nodes inside the defined region with air, but leaving a given number of nodes near the outermost edges alone. In other words, it makes the defined region hollow, while leaving walls around the edges of a given thickness (defaulting to a wall thickness of 1). - -Note that all air-like nodes are also left alone. - -```weacmd -//hollow -//hollow 2 -``` - -### `//maze [ [ []]]` -Generates a maze using replace_node as the walls and air as the paths. Uses [an algorithm of my own devising](https://starbeamrainbowlabs.com/blog/article.php?article=posts/070-Language-Review-Lua.html) (see also [this post of mine that has lots of eye candy :D](https://starbeamrainbowlabs.com/blog/article.php?article=posts/429-lua-blender-mazes.html)). It is guaranteed that you can get from every point to every other point in generated mazes, and there are no loops. - -Requires the currently selected area to be at least 3x3 on the x and z axes respectively. - -Mazes are generated from the bottom to the top of the defined region. In other words, the height of the walls of the maze is equal to the height of the defined region. - -The optional `path_length` and `path_width` arguments require additional explanation. When generating a maze, a multi-headed random walk is performed. When the generator decides to move forwards from a point, it does so `path_length` nodes at a time. `path_length` defaults to `2`. - -`path_width` is easier to explain. It defaults to `1`, and is basically the number of nodes wide the path generated is. - -Note that `path_width` must always be at least 1 less than the `path_length` in order to operate normally. - -Note also that since WorldEditAdditions v1.10, the seed doesn't have to be a number (but it can't contain spaces due to the parsing algorithm used). Non-numbers are hashed to a number using a simple (non-crypto-safe) hashing algorithm. - -The last example below shows how to set the path length and width: - -```weacmd -//maze ice -//maze stone 2 1 1234 -//maze dirt 4 2 56789 -//maze glass 2 1 minetestiscool -``` - - -### `//maze3d [ [ [ []]]]` -Same as `//maze`, but instead generates mazes in 3 dimensions instead of 2. Requires the currently selected area to be at least 3x3x3. - -The optional `path_depth` parameter defaults to `1` and allows customisation of the height of the paths generated. In other words, it customises the ceiling height, or the distance from the floor to the ceiling of the paths generated. - -To get a better look at the generated maze, try inverting it like so: - -```weacmd -//maze3d stone -//replace air dirt -//replace stone air -``` - -Additional examples: - -```weacmd -//maze3d glass -//maze3d bush_leaves 2 1 1 12345 -//maze3d dirt 4 2 2 -//maze3d stone 6 3 3 54321 -``` - - -### `//walls [ []]` -Creates vertical walls of `` around the inside edges of the defined region, optionally specifying the thickness thereof. Defaults to a replace node of `dirt` and a wall thickness of 1. - -```weacmd -//walls -//walls dirt -//walls stone -//walls goldblock -//walls sandstone 2 -//walls glass 4 -``` - - -### `//spiral2 [] [ [ [] ] ]` -Generates both square and circular spiral shapes with the given `` - defaulting to square spirals. The interval defines the gap between the spiral in nodes, and the acceleration defines by how much the interval should be increased (a value of 1 means 1 node per revolution). - -``` -//spiral2 -//spiral2 circle stone -//spiral2 square -//spiral2 circle -//spiral2 glass 5 -//spiral2 square desert_sand 3 1 -``` - - -### `//dome+ [ ...] [h[ollow]]` -Creates a dome shape (i.e. a hemisphere; half a sphere) with a specified radius of the defined node, optionally specifying the direction it should be pointing in (defaults to the positive y direction). - -For example, `//dome+ 5 stone y` creates a dome shape pointing upwards, but `//dome+ 5 stone -y` creates a dome shape pointing downwards. - -Multiple pointing direction axes can be chained together to create multiple domes on top of each other. Multiple conflicting directions will cancel each other out. - -If `h` or `hollow` is specified at the end, then the resulting dome shape is made hollow. - -``` -//dome+ 5 stone y -//dome+ 10 diamond -x -//dome+ 25 cactus y z -//dome+ 9 dirt x y z -``` - - -### `//spline [ []]` -Draws a curved line, using all the currently defined points as control points. The starting and ending widths of the line can be controlled, and the width will be linearly interpolated. - -**Note:** `//spline` uses the **new** WorldEditAdditions positions! Use the [multipoint wand](#multi-point-wand) to define the control points for the resulting line. - -For those interested, WorldEditAdditions uses the [chaikin curve algorithm](https://starbeamrainbowlabs.com/blog/article.php?article=posts/196-Chaikin-Curve-Generator.html) with linear interpolation for the width to draw the curve. - -```weacmd -//spline dirt 5 2 -//spline glass 3 -//spline bakedclay:violet 3 -``` - -![An example of what //spline can do.](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/.docs/images/reference/spline.jpeg) - -## Misc - - - -### `//rotate+ [ ...] [origin|o []]` -Rotates the defined region using the specified list of rotation operations, optionally around the defined rotation origin. For example, the following: - -```weacmd -//rotate+ y 45 -``` - -...will rotate the defined region around it's centre by 45° on the Y (vertical) axis. - -> [!IMPORTANT] -> There is a known issue in which holes appear in previously flat surfaces when rotating through non-axis-aligned rotations. The cause for this is currently unclear. -> -> If you can shed any light on this issue or make any suggestions, please get in touch. - -We can also extend this to rotate on multiple axes: - -```weacmd -//rotate+ z 90 y 45 -``` - -The rotations will be processed in order as specified from left to right. The following relative keywords are currently supported in place of an absolute axis name: - -Keyword | Meaning -------------|-------------------- -`right` | Rotates around the Y axis to the right - aka clockwise. -`left` | Rotates around the Y axis to the left - aka anticlockwise. - -A custom rotation origin can be specified too. This is done via the `origin` keyword and takes the form of specifying a position to rotate around instead of the default (picking the centre point between pos1 and pos2). For example: - -```weacmd -//rotate+ x 20 origin 3 -``` - -....will rotate 20° on the X axis around position 3. See the [multi-point wand](#multipoint) for more information on setting positions other than pos1 and pos2. - -The `origin` keyword's argument is optional, and if no position number is specified defaults to position 3. - -```weacmd -//rotate+ y 90 x 45 origin -//rotate+ y 90 x 45 o -//rotate+ x 60 origin 5 z 20 -``` - - -### `//floodfill [ []]` -Floods all connected nodes of the same type starting at _pos1_ with `` (which defaults to `water_source`), in a sphere with a radius of `` (which defaults to 50). - -```weacmd -//floodfill -//floodfill water_source 50 -//floodfill glass 25 -``` - - -### `//wbox ` -Sets the edges of the current selection to ``to create an outline of a rectangular prism. Useful for roughing in walls. - -In other words, creates a wireframe of a box defined by the current selection. - -```weacmd -//wbox silver_sandstone -//wbox dirt -``` - -### `//wcompass []` -Creates a compass around pos1 with a single node bead pointing north (+Z). - -```weacmd -//wcompass meselamp -//wcompass desert_cobble torch -//wcompass gold diamond -``` - -### `//wcorner ` -Set the corners of the current selection to ``. Useful for outlining building sites and setting boundaries. - -```weacmd -//wcorner glass -//wcorner stone_with_iron -``` - -### `//scale | [ [ ` -Advanced version of [`//stretch` from WorldEdit](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md#stretch-stretchx-stretchy-stretchz) that can scale both up and down at the same time by transparently splitting it into 2 different operations. Scaling up is *always* done before scaling down. - -Although the syntax looks complicated, it's really quite simple. The key concept to understand is that of the scale factor. It refers to how much the defined region should be scaled up or down by, and can be specified in multiple different ways: - -Scale Factor | Meaning -----------------|--------------------- -1 | Don't scale at all. -0.5 | Scale down by 50% -2 | Scale up by 2x, doubling the size -5 | Scale up by 5x, quintupling the size -20% | Scale down to 30% of the original size -1/3 | Scale down to 1 third of original size - -In short, you can specify the scale factor directly, as a percentage, or as 1 number divided by another number. - -> [!NOTE] -> `//scale` always scales in the _positive direction_ by default. This can be changed however - see below. - -With this in mind, there are 3 forms that you can tell `//scale` how you want to scale the defined region: - -#### Single Axis -If you just need to scale a single axis, you can tell `//scale` that like so: - -```weacmd -//scale -``` - -To give a concrete example: - -```weacmd -//scale y 2 -``` - -The above will scale the defined region in the positive y direction by 2 times, doubling the height. If you want to scale in the opposite direction, do this: - -```weacmd -//scale -y 2 -``` - -This will scale in the _negative_ y direction by 2 times (again, doubling the height). Some more examples: - -```weacmd -//scale z 50% -//scale -x 1/3 -``` - -#### All axes -To scale on all axes at once, `//scale` takes the shortcut syntax of specifying a single scale factor: - -```weacmd -//scale 2 -//scale 200% -``` - -Both of the above will scale the defined region up by 2 times in all directions. - -#### Multiple scale factors -If you want to specify different scale factors for difference axes, then `//scale` also supports a third syntax. Here's an example: - -```weacmd -//scale 2 3 4 -``` - -This will scale the defined region by 2x in the positive x, 3x in the positive y, and 4x in the positive z. As these are all scale factors, we can also use the syntax described above to scale up and down in the same operation: - -```weacmd -//scale 50% 2 1/4 -``` - -This will first scale in the positive y by 2x. Once that operation is completed, it will scale down to 50% size in the positive x and down to 25% size in the positive z. Note that if you want to scale down first and then scale up, you'll need to execute 2 separate commands. - -If you want to change the anchor point of the scaling operation too, `//scale` supports a final syntax like so: - -```weacmd -//scale 50% 2 1/4 1 -1 1 -``` - -By adding 3 extra numbers for the x, y, and z axes respectively, we can control the direction `//scale` performs the scaling operation. A value of 1 or greater indicates the positive direction of the axis, and a value of -1 or less indicates the negative direction of the axis. I recommend by [worldedit_hud_helper](https://content.minetest.net/packages/Starbeamrainbowlabs/worldedit_hud_helper/) mod for easily determining which direction is which. - -So in the above example, we scale in the positive x and z directions, and the negative y direction. - - -### `//copy+ [ [...]] [aa|airapply]` -Fully backwards-compatible with `//copy` from regular WorldEdit, but allows you to specify multiple axes at once in a single copy operation. Each successive axis in the list is specified in the form ` `, where: - - - `` is the name of the axis to move the defined region along - - `` is the number of nodes along the defined axis to move - -All of the following values are valid axes: - - - `x` - - `y` - - `z` - - `-x` - - `-y` - - `-z` - - `?` / `front` / `f` - - `back` / `b` - - `left` / `l` - - `right` / `r` - - `up` / `u` - - `down` / `d` - -Additionally all the absolute axis names (`x`/`y`/`z`/`-x`/`-y`/`-z`) may also be specified multiple times under the same count - e.g. `xy-z 6`. - -Finally, if the word `airapply` (or `aa` for short) is present at the end of the command invocation it enables the integrated airapply mode, which replaces target nodes only if they are air-like. - -``` -//copy+ x 6 -//copy+ y 10 z 4 -//copy+ front 6 left 5 -//copy+ ? 10 r 25 y 50 -//copy+ xz 50 front 22 -//copy+ yx 25 -//copy+ -xz-y 10 -//copy+ y 45 aa -//copy+ -y 15 z 5 airapply -``` - - -### `//move+ [ [...]] [aa|airapply]` -Identical to [`//copy+`](#copy), but instead moves the defined region instead of copying it. - -Note that the integrated `airapply` (`aa` for short) also works as in [`//copy+`](#copy), but remember that if a given target node is not *not* air-like and the integrated `airapply` mode is enabled, the source node is still moved from the source, but destroyed because it is can't be set at the target. - - -``` -//move+ x 6 -//move+ y 10 z 4 -//move+ front 6 left 5 -//move+ ? 10 r 25 y 50 -//move+ xz 50 front 22 -//move+ yx 25 -//move+ -xz-y 10 -//move+ back 20 aa -//move+ -z 45 y 3 airapply -``` - - -### `//replacemix [] [] [ []] [ []] ...` -Replaces a given node with a random mix of other nodes. Functions like `//mix`. - -This command is best explained with examples: - -```weacmd -//replacemix dirt stone -``` - -The above functions just like `//replace` - nothing special going on here. It replaces all `dirt` nodes with `stone`. - -Let's make it more interesting: - -```weacmd -//replacemix dirt 5 stone -``` - -The above replaces 1 in every 5 `dirt` nodes with `stone`. Let's get even fancier: - -```weacmd -//replacemix stone stone_with_diamond stone_with_gold -``` - -The above replaces `stone` nodes with a random mix of `stone_with_diamond` and `stone_with_gold` nodes. But wait - there's more! - -```weacmd -//replacemix stone stone_with_diamond stone_with_gold 4 -``` - -The above replaces `stone` nodes with a random mix of `stone_with_diamond` and `stone_with_gold` nodes as before, but this time in the ratio 1:4 (i.e. for every `stone_with_diamond` node there will be 4 `stone_with_gold` nodes). Note that the `1` for `stone_with_diamond` is implicit there. - -If we wanted to put all of the above features together into a single command, then we might do this: - -```weacmd -//replacemix dirt 3 sandstone 10 dry_dirt cobble 2 -``` - -The above replaces 1 in 3 `dirt` nodes with a mix of `sandstone`, `dry_dirt`, and `cobble` nodes in the ratio 10:1:2. Awesome! - -Since WorldEditAdditions v1.12, you can also use percentages: - -```weacmd -//replacemix dirt 33% sandstone 75% dry_dirt 10% cobble 15% -``` - -Note though that the percentages are internally converted to a 1-in-N chance and rounded down. - -Here are all the above examples together: - -```weacmd -//replacemix dirt stone -//replacemix dirt 5 stone -//replacemix stone stone_with_diamond stone_with_gold -//replacemix stone stone_with_diamond stone_with_gold 4 -//replacemix dirt 3 sandstone 10 dry_dirt cobble 2 -``` - - -### `//revolve []` -Makes a given number of copies of the currently defined region (bounded by pos1 and pos2) at a given number of equally spaced points rotated around a given pivot/origin point. - -For example, `//revolve 4` would make rotated copies of the currently defined region at intervals 0° (the source to copy), 90°, 180°, and 270° around the given pivot point. - -`pivot_point_number` is the number of the defined position that should act as the pivot point, or origin for the revolve operation. It defaults to the last position defined. Note that it cannot be pos1 or pos2, as these are used to define the region that should be rotated. Use the [multi-point wand](#multi) to define a position with an index of 3 or more. - -```weacmd -//revolve 4 -//revolve 6 6 -``` - - -## Terrain - - - -### `//convolve [[,]] []` -Advanced version of `//smooth` from we_env, and one of the few WorldEditAdditions commands to have any aliases (`//smoothadv` and `//conv`). - -Extracts a heightmap from the defined region and then proceeds to [convolve](https://en.wikipedia.org/wiki/Kernel_(image_processing)) over it with the specified kernel. The kernel can be thought of as the filter that will be applied to the heightmap. Once done, the newly convolved heightmap is applied to the terrain. - -Possible kernels: - -Kernel | Description -----------------|------------------------------ -[`box`](https://en.wikipedia.org/wiki/Box_blur) | A simple uniform box blur. -`pascal` | A kernel derived from the odd layers of [Pascal's Triangle](https://en.wikipedia.org/wiki/Pascal%27s_triangle). Slightly less smooth than a Gaussian blur. -[`gaussian`](https://en.wikipedia.org/wiki/Gaussian_blur) | The default. A Gaussian blur - should give the smoothest result, and also the most customisable - see below. - -If you can think of any other convolutional filters that would be useful, please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new). The code backing this command is very powerful and flexible, so adding additional convolutional filters should be pretty trivial. - -The width and height (if specified) refer to the dimensions of the kernel and must be odd integers and are separated by a single comma (and _no_ space). If the height is not specified, it defaults to the width. If using the `gaussian` kernel, the width and height must be identical. Larger kernels are slower, but produce a more smoothed effect and take more nearby nodes into account for every column. Defaults to a 5x5 kernel. - -The sigma value is only applicable to the `gaussian` kernel, and can be thought of as the 'smoothness' to apply. Greater values result in more smoothing. Default: 2. See the [Gaussian blur](https://en.wikipedia.org/wiki/Gaussian_blur) page on Wikipedia for some pictures showing the effect of the sigma value. - -```weacmd -//convolve -//convolve box 7 -//convolve pascal 11,3 -//convolve gaussian 7 -//convolve gaussian 9 10 -//convolve gaussian 5 0.2 -``` - - -### `//overlay [] [] [ []] ...` -Places `` in the last contiguous air space encountered above the first non-air node. In other words, overlays all top-most nodes in the specified area with ``. Optionally supports a mix of node names and chances, as `//mix` (WorldEdit) and `//replacemix` (WorldEditAdditions) does. - -Will also work in caves, as it scans columns of nodes from top to bottom, skipping every non-air node until it finds one - and only then will it start searching for a node to place the target node on top of. - -Note that all-air columns are skipped - so if you experience issues with it not overlaying correctly, try `//expand down 1` to add an extra node's space to your defined region. - -Note also that columns without any air nodes in them at all are also skipped, so try `//expand y 1` to add an extra layer to your defined region. - -```weacmd -//overlay grass -//overlay glass -//overlay grass_with_dirt -//overlay grass_with_dirt 10 dirt -//overlay grass_with_dirt 10 dirt 2 sand 1 -//overlay sandstone dirt 2 sand 5 -//overlay dirt 90% stone 10% -``` - - -### `//fillcaves []` -Fills in all airlike nodes beneath non airlike nodes, which gives the effect of filling in caves. Defaults to filling in with stone, but this can be customised. - -Note that the *entire* cave you want filling must be selected, as `//fillcaves` only operates within the defined region (ref #50). - -```weacmd -//fillcaves -//fillcaves dirt -//fillcaves brick -``` - - - -### `//layers [] [ []] [ []] ...` -Finds the first non-air node in each column and works downwards, replacing non-air nodes with a defined list of nodes in sequence. Like WorldEdit for Minecraft's `//naturalize` command, and also similar to [`we_env`'s `//populate`](https://github.com/sfan5/we_env). Speaking of, this command has `//naturalise` and `//naturalize` as aliases. Defaults to 1 layer of grass followed by 3 layers of dirt. - -Since WorldEditAdditions v1.13, a maximum and minimum slope is optionally accepted, and constrains the columns in the defined region that `//layers` will operate on. For example, specifying a value of `20` would mean that only columns with a slop less than or equal to 20° (degrees, not radians) will be operated on. A value of `45..60` would mean that only columns with a slope between 45° and 60° will be operated on. - -The list of nodes has a form similar to that of a chance list you might find in `//replacemix`, `//overlay`, or `//mix` - see the examples below. If the number of layers isn't specified, `1` is assumed (i.e. a single layer). - - -```weacmd -//layers dirt_with_grass dirt 3 -//layers sand 5 sandstone 4 desert_stone 2 -//layers brick stone 3 -//layers cobble 2 dirt -//layers 45..60 dirt_with_snow dirt 2 -//layers 30 snowblock dirt_with_snow dirt 2 -``` - - -### `//erode [ [ []] [ []] ...]` -Runs an erosion algorithm over the defined region, optionally passing a number of key - value pairs representing parameters that are passed to the chosen algorithm. This command is **experimental**, as the author is currently on-the-fence about the effects it produces. - -Works best if you run `//fillcaves` first, or otherwise have no air nodes below the top non-air node in each column. - -Currently implemented algorithms: - -Algorithm | Mode | Description -------------|-------|------------------- -`snowballs` | 2D | The default - based on [this blog post](https://jobtalle.com/simulating_hydraulic_erosion.html). Simulates snowballs rolling across the terrain, eroding & depositing material. Then runs a 3x3 gaussian kernel over the result (i.e. like the `//conv` / `//smoothadv` command). -`river` | 2D | Fills in potholes and lowers pillars using a cellular automata-like algorithm that analyses the height of neighbouring columns. - -Usage examples: - -```weacmd -//erode -//erode snowballs -//erode snowballs count 25000 -``` - -Each of the algorithms above have 1 or more parameters that they support. These are detailed below. - -#### Algorithm: `snowballs` -Based on the algorithm detailed in [this blog post](https://jobtalle.com/simulating_hydraulic_erosion.html) ([direct link to the source code](https://github.com/jobtalle/HydraulicErosion/blob/master/js/archipelago/island/terrain/erosionHydraulic.js)), devised by [Job Talle](https://jobtalle.com/). - -Parameter | Type | Default Value | Description ---------------------|-----------|-------------------|-------------------------- -rate_deposit | `float` | 0.03 | The rate at which snowballs will deposit material -rate_erosion | `float` | 0.04 | The rate at which snowballs will erode material -friction | `float` | 0.07 | More friction slows snowballs down more. -speed | `float` | 1 | Speed multiplier to apply to snowballs at each step. -max_steps | `float` | 80 | The maximum number of steps to simulate each snowball for. -velocity_hist_count | `float` | 3 | The number of previous history values to average when detecting whether a snowball has stopped or not -init_velocity | `float` | 0.25 | The maximum random initial velocity of a snowball for each component of the velocity vector. -scale_iterations | `float` | 0.04 | How much to scale erosion by as time goes on. Higher values mean that any given snowball will erode more later on as more steps pass. -maxdiff | `float` | 0.4 | The maximum difference in height (between 0 and 1) that is acceptable as a percentage of the defined region's height. -count | `float` | 25000 | The number of snowballs to simulate. -noconv | any | n/a | When set to any value, disables to automatic 3x3 gaussian convolution. - -Usage examples: - -```weacmd -//erode -//erode snowballs -//erode snowballs count 50000 -``` - -If you find any good combinations of these parameters, please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new) (or a PR!) and let me know! I'll include good combinations here, and possibly add a presets feature too. - -#### Algorithm: `river` -Ever been annoyed by small 1 wide holes or thin pillars all over the place? This command is for you! Does not operate on the very edge of the defined region, because the algorithm can't see the neighbours of those columns. - -Parameter | Type | Default Value | Description ---------------------|-----------|-------------------|-------------------------- -steps | `integer` | 1 | The number of rounds or passes of the algorithm to run. Useful if you have a 1x3 hole for instance, it will take at least 2 steps to fill it in - and more if it's deeper than 1 node. -lower_sides | `string` | 4,3 | Comma separated list of numbers. Columns with this many sides lower than it will be lowered in height by 1 node. -raise_sides | `string` | 4,3 | Comma separated list of numbers. Columns with this many sides higher than it will be raised in height by 1 node. -doraise | `boolean` | true | Whether to raise columns in height. If false, then no columns will be raised in height even if they are eligible to be so according to `raise_sides`. -dolower | `boolean` | true | Whether to lower columns in height. If false, then no columns will be lowered in height even if they are eligible to be so according to `lower_sides`. - -Usage examples: - -```weacmd -//erode river -//erode river steps 10 -``` - - -### `//noise2d [ []] [ []] ...]` -Applies 2D noise to the terrain in the defined region. Like `//erode`, this command accepts a number of different key-value parameters and provides a number of different underlying algorithms. - -In other words, this command changes the height of the terrain according to some noise function (e.g. Perlin noise): - -![//noise2d applies 2D noise as a modifier to terrain height.](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/dev/.docs/images/reference/noise2d.jpeg) - -It does so like this: - -1. Take coordinates of each column -2. Plug them through a noise function (see below) -3. Apply the generated noise value to the terrain. - -`//noise2d` has a number of parameters that let you adjust the mathematical properties of step 2, which are explained in the table below. - -Some terms that are useful to know: - -- **Scale:** How big or small the noise is. Lower values stretch it out to be bigger, and higher values squash it in. -- **Offset:** Noise is calculated by passing some coordinates into a function. -- **Perlin:** A noise algorithm. `//noise2d` defaults to this. - - -#### Table of parameters - -Parameter | Type | Default Value | Description -------------|-----------|---------------|----------------------- -algorithm | `string` | perlinmt | The 2D noise algorithm to apply - see below. -apply | `string¦integer` | 5 | How to apply the noise to the terrain - see below. -scale | `float` | 1 | Sets `scalex`, `scaley`, and `scalez` all at once. Consider also `//apply`. -scalex | `float` | 1 | The scale of the noise on the x axis. -scaley | `float` | 1 | The scale of the noise on the y axis. -scalez | `float` | 1 | The scale of the noise on the z axis. -offsetx | `float` | 1 | The offset to add to the x axis before calling the noise function. -offsety | `float` | 0 | The offset to add to the y axis before calling the noise function. -offsetz | `float` | 0 | The offset to add to the z axis before calling the noise function. -exponent | `float` | 0 | Raise the generated noise value (with a range of 0 to 1) to this power. Generally results in sharper peaks. -multiply | `float` | 1 | Multiply the generated noise value by this number -add | `float` | 0 | Add this number to the generated noise value. - -#### Apply -Different values of the `apply` parameter result in the generated noise values being applied in different ways: - -1. An integer indicates that the noise should be rescaled to a given amplitude (equal parts of the range above and below 0) before being added to the terrain heightmap.` -2. The exact string `add`: Noise values are added to each heightmap pixel. -3. The exact string `multiply`: Each heightmap pixel is multiplied by the corresponding noise value. - -An integer is the most common way to use `//noise2d`. So, for example: - -```weacmd -//noise2d apply 5 -``` - -...would alter the height of each column of nodes by at most 5 blocks either side, while: - -```weacmd -//noise2d apply 10 -``` - -...would alter the height by 10 blocks instead of 5. - -#### Types of noise -Another thing that can be changed is the noise algorithm. This changes what the noise that is applied to the terrain looks like. - -The following algorithms are currently available: - -Algorithm | Description -------------|-------------------------- -`perlinmt` | **Default**. Perlin noise, backed by Minetest's inbuilt `PerlinNoise` class. -`perlin` | Perlin noise, backed by a pure Lua perlin noise implementation. Functional, but currently contains artefacts I'm having difficulty tracking down. -`sin` | A sine wave created with `math.sin()`. -`white` | Random white noise. In other words, just random values. -`red` | Red noise - has a lower frequency than white noise. Ref [Noise Functions and Map Generation by Red Blob Games](https://www.redblobgames.com/articles/noise/introduction.html). -`infrared` | Even smoother than red noise. Tends to also be quite flat unless you use a slightly higher `apply` value (e.g. `20`). - -When specifying algorithm names, the `algorithm` parameter name is optional. For example, the following are both equivalent: - -```weacmd -//noise2d offsetx 4 perlin scale 0.2 -//noise2d offsetx 4 algorithm perlin scale 0.2 -``` - -#### Further examples -Example invocations: - -```weacmd -//noise2d sin scale 0.5 -//noise2d offsetx 20 perlin -//noise2d sin exponent 4 -``` - - -### `//sculptlist [preview]` -Lists all the available sculpting brushes for use with `//sculpt`. If the `preview` keyword is specified as an argument, then the brushes are also rendered in ASCII as a preview. See [`//sculpt`](#sculpt). - -``` -//sculptlist -//sculptlist preview -``` - - -### `//sculpt [ [ []]]` -Applies a specified brush to the terrain at position 1 with a given height and a given size. Multiple brushes exist (see [`//sculptlist`](#sculptlist)) - and are represented as a 2D grid of values between 0 and 1, which are then scaled to the specified height. The terrain around position 1 is first converted to a 2D heightmap (as in [`//convolve`](#convolve) before the brush "heightmap" is applied to it. - -Similar to [`//sphere`](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md#sphere-radius-node), [`//cubeapply 10 set`](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md#cubeapply-sizesizex-sizey-sizez-command-parameters), or [`//cylinder y 5 10 10 dirt`](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md#cylinder-xyz-length-radius1-radius2-node) (all from [WorldEdit](https://content.minetest.net/packages/sfan5/worldedit/)), but has a number of added advantages: - - - No accidental overhangs - - Multiple custom brushes (see below on how you can add your own!) - -A negative height value causes the terrain to be lowered by the specified number of nodes instead of raised. - -While sculpting brushes cannot yet be rotated, this is a known issue. Rotating sculpting brushes will be implemented in a future version of WorldEditAdditions. - -The selection of available brushes is limited at the moment, but see below on how to easily create your own! - -``` -//sculpt -//sculpt default 25 3 -//sculpt ellipse -//sculpt circle 50 3 -``` - -#### Create your own brushes -2 types of brush exist: - -1. Dynamic (lua-generated) brushes -2. Static brushes - -All brushes are located in `worldeditadditions/lib/sculpt/brushes` (relative to the root of WorldEditAdditions' installation directory). - -Lua-generated brushes are not the focus here, but are a file with the extension `.lua` and return a function that returns a brush - see other existing Lua-generated brushes for examples (and don't forget to update `worldeditadditions/lib/sculpt/.init.lua`). - -Static brushes on the other hand are simply a list of tab-separated values arranged in a grid. For example, here is a simple brush: - -```tsv -0 1 0 -1 2 1 -0 1 0 -``` - -Values are automatically rescaled to be between 0 and 1 based on the minimum and maximum values, so don't worry about which numbers to use. Static brushes are saved with the file extension `.brush.tsv` in the aforementioned directory, and are automatically rescanned when your Minetest server starts. While they can't be rescaled automatically to fix a target size (without creating multiple variants of a brush manually of course, though this may be implemented in the future), static brushes are much easier to create than dynamic brushes. - -To assist with the creation of static brushes, a tool exists to convert any image to a static brush: - - - -The tool can operate on the colour channel of your choice - red, green, blue, or alpha. - -If you've created a cool new brush (be it static or dynamic), **please contribute it to WorldEditAdditions**! That way, everyone can enjoy using your awesome brush. [WorldPainter](https://www.worldpainter.net/) has many brushes available in the community, but `//sculpt` for WorldEditAdditions is new so don't have the same sized collection yet :-) - -To contribute your new brush back, you can either [open a pull request](https://github.com/sbrl/Minetest-WorldEditAdditions/pulls) if you're confident using GitHub, or [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues) with your brush attached if not. - - - -## Flora - - - -### `//forest [] [] [] [ []] ...` -Plants and grows saplings to generate a forest. A density value is optionally taken, which controls the overall density of the forest that is generated. The `bonemeal` mod is required - just like for the [`//bonemeal`](#bonemeal-strength-chance) command. - -The density defaults to 1, acts like a multiplier, and is not affected by the chances of all saplings listed (e.g. you can have a sapling with a chance of 1-in-50, and the overall density of the forest will be unaffected). For example, 2 results in a forest twice as dense as the default, and 0.5 a forest half as dense as the default density. - -The tree types are provided as a list of names and 1-in-N chances, just like [`//overlay`](#overlay-node_name_a-chance_a-node_name_b-chance_b-node_name_n-chance_n-), `//mix`, `//layers`, etc. Unlike the aforementioned commands however, `//forest` has an additional layer of alias resolution to ease the process of determining what the name of the sapling is you want to use to generate forests with. See [`//saplingaliases`](#saplingaliases-aliasesall_saplings) for more details. - -Saplings are placed with [`//overlay`](#overlay-node_name_a-chance_a-node_name_b-chance_b-node_name_n-chance_n-) and grown using the same method that's used by the `//bonemeal` command. Up to 100 attempts are made to grow placed saplings. If all of those attempts fail (success is determined by whether the sapling is still present or not), the sapling is removed and the failure counter is incremented. - -Currently, the following mods are known to have aliases registered: - - - `default` - - [`moretrees`](https://content.minetest.net/packages/VanessaE/moretrees/) (warning: these saplings don't appear to work very well this command - assistance in debugging this would be very helpful) - - [`cool_trees`](https://content.minetest.net/packages/runs/cool_trees/) - -If you like, you can also reference the full name of a sapling node instead. The only requirements for saplings to be supported by this mod are: - -1. It can be bonemealed -2. It has the `sapling` group - -For example, the first 2 examples below are functionally equivalent. - -```weacmd -//forest aspen -//forest default:aspen_sapling -//forest 2 oak 3 aspen pine -//forest 0.5 acacia -``` - - -### `//saplingaliases [aliases|all_saplings]` -Lists all the currently registered sapling aliases in alphabetical order. These aliases can be used in the `//forest` subcommand. - -Optionally takes a single parameter, which is the operating mode. Current implemented operating modes: - -Mode | Description -----------------|---------------------- -`aliases` | The default. Lists all the currently registered sapling aliases in alphabetical order. -`all_saplings` | Spins through all the nodes currently registered in Minetest, and lists all the nodes that have the `sapling` group. - -```weacmd -//saplingaliases -//saplingaliases all_saplings -//saplingaliases aliases -``` - - - -### `//bonemeal [ [ [ [ ...]]]]` -Requires the [`bonemeal`](https://content.minetest.net/packages/TenPlus1/bonemeal/) ([repo](https://notabug.org/TenPlus1/bonemeal/)) mod (otherwise _WorldEditAdditions_ will not register this command and output a message to the server log). Alias: `//flora`. - -Bonemeals all eligible nodes in the current region. An eligible node is one that has an air node directly above it - note that just because a node is eligible doesn't mean to say that something will actually happen when the `bonemeal` mod bonemeals it. - -Optionally takes a strength value (that's passed to `bonemeal:on_use()`, the method in the `bonemeal` mod that is called to actually do the bonemealing). The strength value is a positive integer from 1 to 4 (i.e. 1, 2, 3, or 4) - the default is 1 (the lowest strength). - -I observe that a higher strength value gives a higher chance that something will actually grow. In the case of soil or sand nodes, I observe that it increases the area of effect of a single bonemeal action (thus at higher strengths generally you'll probably want a higher chance number - see below). See the [`bonemeal` mod README](https://notabug.org/TenPlus1/bonemeal) for more information. - -Also optionally takes a chance number. This is the chance that an eligible node will actually get bonemealed, and is a positive integer that defaults to 1. The chance number represents a 1-in-{number} chance to bonemeal any given eligible node, where {number} is the chance number. In other words, the higher the chance number the lower the chance that a node will be bonemealed. - -For example, a chance number of 2 would mean a 50% chance that any given eligible node will get bonemealed. A chance number of 16 would be a 6.25% chance, and a chance number of 25 would be 2%. - -Since WorldEditAdditions v1.12, a percentage chance is also supported. This is denoted by suffixing a number with a percent sign (e.g. `//bonemeal 1 25%`). - -Since WorldEditAdditions v1.13, a list of node names is also optionally supported. This will constrain bonemeal operations to be performed only on the node names listed. - - -```weacmd -//bonemeal -//bonemeal 3 25 -//bonemeal 4 -//bonemeal 1 10 -//bonemeal 2 15 -//bonemeal 2 10% -//bonemeal 2 10% dirt -//bonemeal 4 50 ethereal:grove_dirt -``` - - - -## Statistics - - - -### `//count` -Counts all the nodes in the defined region and returns the result along with calculated percentages (note that if the chat window used a monospace font, the returned result would be a perfect table. If someone has a ~~hack~~ solution to make the columns line up neatly, please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new) :D) - -> [!NOTE] -> The output of `//count` can be rather long sometimes, and Minetest by default only shows the last few lines of chat. Press F10 to show the full chat window that you can then scroll through to inspect the full output. - -```weacmd -//count -``` - - -### `//basename ` -Returns the absolute canonical name of a node, given an alias or partial node name. For example: - -```weacmd -//basename dirt -``` - -...will return `default:dirt`. Uses `worldedit.normalize_nodename(string)` under the hood. - -```weacmd -//basename stonebrick -//basename glass -``` - - -### `//ngroups [v[erbose]]` -Lists the groups that a given node is a member of. For example: - -```weacmd -//ngroups sand -``` - -Might return: - -``` -default:sand ∈ sand crumbly falling_node -``` - -Groups in Minetest can also have a numerical value greater than 0. Append `v` or `verbose` to see those values: - -```weacmd -//ngroups sand v -//ngroups sand verbose -``` - -...both of the above might produce an output like this: - -``` -default:sand ∈ sand=1 crumbly=3 falling_node=1 -``` - -Finally, the customary misc examples: - -```weacmd -//ngroups sand -//ngroups bakedclay:orange v -//ngroups cactus -//ngroups default:dry_shrub v -``` - -### `//ndef ` -Short for *Node Definition*. Prints the definition table for the node with the given name. In other words. the output could look a little like this: - -``` -stairs:stair_birch_wood { - description = (string) "Birch Wood Stair" - sounds = (table) { - dig = (table) { - name = (string) "default_dig_choppy" - gain = (number) 0.4 - } - place = (table) { - name = (string) "default_place_node_hard" - gain = (number) 1 - } - dug = (table) { - name = (string) "default_wood_footstep" - gain = (number) 1 - } - footstep = (table) { - name = (string) "default_wood_footstep" - gain = (number) 0.15 - } - } - name = (string) "stairs:stair_birch_wood" - light_source = (number) 0 - mod_origin = (string) "ethereal" - selection_box = (table) { - fixed = (table) { - 1 = (table) [truncated] - 2 = (table) [truncated] - } - type = (string) "fixed" - } - paramtype = (string) "light" - groups = (table) { - flammable = (number) 3 - stair = (number) 1 - choppy = (number) 2 - oddly_breakable_by_hand = (number) 1 - } - is_ground_content = (boolean) false - on_place = (function) function: 0x765b01d0edb8 - drawtype = (string) "nodebox" - tiles = (table) { - 1 = (table) { - name = (string) "moretrees_birch_wood.png" - backface_culling = (boolean) true - } - } - paramtype2 = (string) "facedir" - sunlight_propagates = (boolean) false - node_box = (table) { - fixed = (table) { - 1 = (table) [truncated] - 2 = (table) [truncated] - } - type = (string) "fixed" - } - type = (string) "node" -} -``` - -This command is intended for debugging and development purposes, but if you're implementing a mod yourself you might find it useful too. - -```weacmd -//ndef stone -//ndef stairs:stair_birch_wood -//ndef glass -``` - - - -## Selection - - -### `//unmark` -Hides the in-game UI that indicates where the current positions and region are located. - -This hides both the WorldEditAdditions *and* the WorldEdit UI if displayed, but does **not** change or remove any points that are registered. - -Should more than 2 points be defined, they are all hidden. - -```weacmd -//unmark -``` - -### `//mark` -Shows the in-game UI that indicates where the current positions and region are located once more. - -Should more than 2 points be defined, they are all shown once more. - -Often used after calling [`//unmark`](#unmark) - -```weacmd -//mark -``` - - -### `//pos1` -Sets pos1 to the location of the calling player. - -This is, as with all other WorldEditAdditions commands, seamlessly synchronised with WorldEdit, allowing you to use any combination of WorldEditAdditions and WorldEdit commands and tools without them desynchronising from one another. - -**Aliases:** `//1` - -```weacmd -//pos2 -``` - -### `//pos2` -Sets pos1 to the location of the calling player. - -This is, as with all other WorldEditAdditions commands, seamlessly synchronised with WorldEdit, allowing you to use any combination of WorldEditAdditions and WorldEdit commands and tools without them desynchronising from one another. - -**Aliases:** `//2` - -```weacmd -//pos2 -``` - -### `//pos ` -Sets position with the given index `` to the location of the calling player. - -Should the index be less than or equal to 2, then as with all other WorldEditAdditions commands, seamlessly synchronised with WorldEdit, allowing you to use any combination of WorldEditAdditions and WorldEdit commands and tools without them desynchronising from one another. - -Should the index be greater than 2, the position will only be registered in WorldEditAdditions, as WorldEdit does not support defining more than 2 points. - -If no index is specified, an error is returned and nothing is done. - -```weacmd -//pos 1 -//pos 3 -//pos 45 -//pos 2 -``` - -### `//reset` -Clears all positions defined and the defined region. - -This also synchronises with WorldEdit, as all other WorldEditAdditions commands do. - -```weacmd -//reset -``` - - -### `//scol [ ] ` -#### === DEPRECATED === -Please use `//srel` instead. - - -### `//srect [ []] ` -#### === DEPRECATED === -Please use `//srel` instead. - - -### `//scube [ [ []]] ` -#### === DEPRECATED === -Please use `//srel` instead. - - -### `//scloud <0-6|stop|reset>` -Short for _select point cloud_. Sets pos1 and pos2 to include the nodes you punch. Numbers 1-6 designate how many nodes you want to punch before the operation ends. 0 or stop terminate the operation so that any further nodes you punch won't be added to selection. Reset terminates operation if one is running and resets the selection area. - -```weacmd -//scloud 6 -//scloud 5 -//scloud stop -``` - - -### `//scentre` -Short for _select center_. Sets pos1 and pos2 to the centre point(s) of the current selection area. 1, 2, 4 or 8 nodes may be selected depending on what parts of the original selection are even in distance. Implementation thanks to @VorTechnix. - -```weacmd -//scentre -``` - -### `//srel [ [ ]]` -Short for _select relative_. Sets the pos2 at set distances along 3 axes relative to pos1. If pos1 is not set it will default to the node directly under the player. The axis arguments accept `x, y, z` as well as `up, down, left, right, front, back`. Left, right, front and back are relative to player facing direction. Negative (`-`) can be applied to the axis, the length or both. Implementation thanks to @VorTechnix. - -```weacmd -//srel front 5 -//srel y 12 right -2 -//srel left 3 up 5 -front 7 -//srel -z 12 -y -2 x -2 -``` - -### `//sshift [ [ ]]` -Short for _selection shift_. Shifts the WorldEdit region along 3 axes. The axis arguments accept `x, y, z` as well as `up, down, left, right, front, back`. Left, right, front and back are relative to player facing direction. Negative (`-`) can be applied to the axis, the length or both. Implementation thanks to @VorTechnix. - -```weacmd -//sshift back 4 -//sshift right -2 up 2 -//sshift -left 2 z -7 -y -4 -//sshift -z 12 -y -2 x -2 -``` - -### `//smake [ []]` -Short for _selection make_. Modifies existing selection by moving pos2. Allows you to make the selection an odd or even length on one or more axes or set two or more axes equal to each other or the longest, shortest or average of them. Implementation thanks to @VorTechnix. - -Usage examples: - -```weacmd -//smake odd shrink -//smake even avg xz -//smake equal grow xy -//smake equal average -//smake equal zy x -``` - -#### ``: odd|even|equal - -Value | Description ---------|--------------- -`odd` | Round up or down, based on mode, all axes specified in `` to the nearest odd length relative to pos1 -`even` | Round up or down, based on mode, all axes specified in `` to the nearest even length relative to pos1 -`equal` | Set `` axes length equal to the length of `` axis if specified or to the length of the largest, smallest or average of the `` axes based on mode. - -#### ``: grow|shrink|average - -#### *If `` == odd or even:* - -Value | Description -----------------|-------------- -`grow` | Grow each axis specified in `` to the nearest odd/even number to itself -`shrink` | Shrink each axis specified in `` to the nearest odd/even number to itself -`average`/`avg` | Takes the average of all axes specified in `` and then for each specified axis grows or shrinks it, depending on whether it is less than or greater than the average, to the nearest odd/even number to itself - -#### *If `` == equal:* -The `` argument can be omitted and will not be parsed if present if `` is specified - -Value | Description -----------------|--------------- -`grow` | Grow each axis specified in `` to the length of the longest specified axis -`shrink` | Shrink each axis specified in `` to the length of the shortest specified axis -`average`/`avg` | Set each axis specified in `` to the average length of all the specified axes -If `` | `` becomes optional. If present it will be ignored. - -#### Additional arguments: - -Name | Description -------------|------------------ -`` | Specify axes to perform operation on (default= xz)| -``: If `` == odd or even | Does nothing -``: If `` == equal | Overrides `` and sets all `` axes equal to itself - -### `//sfactor []` -Short for _selection factor_; alias: `//sfac`. Built specifically for use with `//maze`, this command sets targeted axes equal to the nearest multiple of `` based on the ``. - -Usage examples: - -```weacmd -//sfac grow 5 -//sfac avg 3 xy -``` - -#### ``: grow|shrink|average - -Value | Description ---------|-------------- -`grow` | Rounds the length of each target axis up to the nearest multiple of `` -`shrink` | Rounds the length of each target axis down to the nearest multiple of `` -`average`/`avg` | Takes the average of all axes specified in `` and then for each specified axis grows or shrinks it, depending on whether it is less than or greater than the average, to the nearest multiple of `` - -### `//sstack` -Displays the contents of your per-user selection stack. This stack can be pushed to and popped from rather like a stack of plates. See also `//spush` (for pushing to the selection stack) and `//spop` (for popping from the selection stack). - -```weacmd -//sstack -``` - -### `//spush` -Pushes the currently defined region onto your per-user selection stack. Does not otherwise alter the defined region. - -If the stack is full (currently the limit is set to 100 regions in the stack), then it will complain at you but otherwise will have no effect. - -Note that pos2 does _not_ need to be defined in order to use this. if it isn't defined, then a pos2 of `nil` will be pushed onto the stack instead. - -```weacmd -//spush -``` - -### `//spop` -Pops a selection off your per-user selection stack and applies it to the currently defined region. If pos2 from the item popped from the stack is nil, then pos2 is explicitly unset. If the stack is empty, this has no effect. - -```weacmd -//spop -``` - - - -## Measurement - - - -### `//mcount` -Alias for [`//count`](#count). - -``` -//mcount -``` - - -### `//mface` -Returns the horizontal (X/Z) axis or axes the player is looking along. -Aliases: `//mfacing`. - -``` -//mface -``` - - -### `//midpos` -Returns the coordinates of the centre of the current selection. - -``` -//midpos -``` - - -### `//msize` -Returns the lengths of the current selection on the X, Y and Z axes. - -``` -//msize -``` - - -### `//mtrig` -Returns the length of the diagonal from pos1 to pos2 and its angle on the XZ (horizontal) and Y (vertical) axes. - -``` -//mtrig -``` - - - -## Meta - - - -### `//subdivide ` -Splits the current WorldEdit region into `(, , )` sized chunks, and run `// ` over each chunk. - -Sometimes, we want to run a single command on a truly vast area. Usually, this results in running out of memory. If this was you, then this command is just what you need! It should be able to handle any sized region - the only limit is your patience for command to complete..... - -Note that this command only works with WorldEdit commands, and only those which require 2 points (e.g. `//torus` only requires a single point, so it wouldn't work very well - but `//set` or `//clearcut` would). - -Note also that `` should _not_ be prefixed with _any_ forward slashes - see the examples below. - -While other server commands can be executed while a `//subdivide` is running, `//subdivide` manipulates your player's defined region when running. This has the side-effect that you can check on where it has got up to with `//p get` for example - but means that attempting to change your pos1 & pos2 manually will have no effect until the `//subdivide` completes. - -> [!WARNING] -> Once started, this command cannot be stopped without restarting your server! This is the case with all WorldEdit commands, but it's worth a special mention here. - -```weacmd -//subdivide 10 10 10 set dirt -//subdivide 25 25 25 fixlight -``` - - -### `//multi .....` -Executes multi chat commands in sequence. Intended for _WorldEdit_ commands, but does work with others too. Don't forget a space between commands! - -```weacmd -//multi //set dirt //shift x 10 //set glass -``` - -Since WorldEditAdditions v1.12, curly brace syntax has also been introduced to allow nesting of commands: - -```weacmd -//multi //fixlight {//many 5 //bonemeal 3 100} -``` - -This syntax can also be nested arbitrarily in arbitrarily complex combinations, and can also be used multiple separate times in a single `//multi` invocation (if you find a bug, please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new)), though do remember that only `//multi` supports parsing out this syntax (e.g. if you want to nest multiple commands in a `//many` that's inside a `//multi`, you'll need a sub `//multi` there). - -In addition, this also allows for including a double forward slash in the argument list for a command, should you need to do so (e.g. `//multi //example {//bar //baz} //example` will be executed as 3 commands: `/example`, then `/bar` with an argument of `//baz`, then finally `/example`). - -```weacmd -//multi //1 //2 //shift z -10 //sphere 5 sand //shift z 20 //ellipsoid 5 3 5 ice -//multi //1 //hollowtorus 30 5 stone //hollowtorus 20 3 dirt //torus 10 2 dirt_with_grass -//multi /time 7:00 //1 //outset h 20 //outset v 5 //overlay dirt_with_grass //1 //2 //sphere 8 air //shift down 1 //floodfill //reset -``` - - -### `//many ` -Executes a single chat command many times in a row. Uses `minetest.after()` to yield to the main server thread to allow other things to happen at the same time, so technically you could have multiple `//many` calls going at once (but multithreading support is out of reach, so only a single one will be executing at the same time). - -Note that this isn't necessarily limited to executing WorldEdit / WorldEditAdditions commands. Combine with `//multi` (see above) execute multiple commands at once for even more power and flexibility! - -```weacmd -//many 10 //bonemeal 3 100 -//many 100 //multi //1 //2 //outset 20 //set dirt -``` - - -### `//ellipsoidapply ` -Executes the given command, and then clips the result to the largest ellipsoid that will fit inside the defined region. The specified command must obviously take 2 positions - so for example `//set`, `//replacemix`, and `//maze3d` will work, but `//sphere`, `//torus`, and `//floodfill` won't. - -For advanced users, `//multi` is also supported - but make sure your modifications stay within the defined region - otherwise they will not be affected by the ellipsoidal clipping operation. - -```weacmd -//ellipsoidapply set dirt -//ellipsoidapply maze3d dirt 4 2 2 -//ellipsoidapply erode -//ellipsoidapply replacemix sand bakedclay:red bakedclay:orange -//ellipsoidapply layers desert_sand sand 2 desert_sandstone 4 sandstone 10 -``` - - -### `//airapply ` -Like [`//ellipsoidapply`](#ellipsoidapply), but instead only keeps changes that replace airlike nodes, and discards any other changes made. - -As with `//ellipsoidapply` for advanced users `//multi` is also supported - but make sure your modifications stay within the defined region - otherwise they be kept regardless, as `//airapply` only applies the masking to the nodes in the defined region. - -```weacmd -//airapply set sandstone -//airapply maze3d dirt 4 2 2 -``` - - -### `//nodeapply [] [... ] -- ` -**Aliases:** `//napply` - -It's got `apply` in the name, so as you might imagine it works the same as [`//ellipsoidapply`](#ellipsoidapply), [`//airapply`](#airapply), [`//noiseapply2d`](#noiseapply2d), etc. Only changes made by the given command that replace nodes on the list given will be replaced. For example: - -```weacmd -//nodeapply dirt -- set stone -``` - -....is equivalent to `//replace dirt stone`, in that although `//set stone` will set all nodes to stone, `//nodeapply` will only keep the changes made by `//set` that affect dirt. - -There are some special keywords you can use too: - -Keyword | Meaning -----------------|----------------------------------- -`liquidlike` | Targets all nodes that behave like a liquid. -`airlike` | Targets all nodes that behave like air. Basically like [`//airapply`](#airapply). - -To give a further example, consider this: - -```weacmd -//nodeapply liquidlike -- set river_water_source -``` - -...this will replace all liquid-like nodes (e.g. water, lava, etc) with river water. - -In addition, any node names prefixed an at sign `@` are considered group names. For example: `@crumbly` would allow changes only to nodes that are a member of the `crumbly` group: - -```weacmd -//nodeapply @crumbly -- layers dirt_with_grass dirt 3 stone 10 -``` - -More misc examples to end this command description, as is customary: - -```weacmd -//nodeapply stone -- layers dirt_with_grass dirt 3 -//nodeapply stone dirt sand -- layers bakedclay:natural 3 bakedclay:orange 2 bakedclay:red 3 bakedclay:natural 3 -//nodeapply liquidlike -- set air -//nodeapply airlike -- mix stone 3 dirt 2 -``` - - -### `//noiseapply2d ` -Like [`//ellipsoidapply`](#ellipsoidapply), but instead only keeps changes where a noise function (defaults to `perlinmt`, see [`//noise2d`](#noise2d)) returns a value greater than a given threshold value. - -Also takes a scale value that controls the scale of the noise - -higher values result in smaller "blobs". If you're operating on small areas, then a value of at least 10 is advised as "blobs" are by default on the scale of ~50 nodes. - -As with `//ellipsoidapply` for advanced users `//multi` is also supported - but make sure your modifications stay within the defined region - otherwise they be kept regardless, as `//noiseapply2d` only applies the masking to the nodes in the defined region. - -Any suggestions on how to provide more customisability without making this command more difficult to use or significantly more inconsistent with other `//*apply` functions are welcome - please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new). - -```weacmd -//noiseapply2d 0.5 10 set dirt -//noiseapply2d 0.4 3 layers dirt_with_snow dirt 3 stone 10 -``` - -### `//for ... do // %% ` -For a given list of values, executes the specified command for each value, replacing `%%` with each value. Implementation thanks to @VorTechnix. - -To better illustrate what happens, consider the following command: - -``` -//for dirt stone glass do //replacemix air 10 %% -``` - -This is equivalent to executing the following 3 commands in sequence: - -``` -//replacemix air 10 dirt -//replacemix air 10 stone -//replacemix air 10 glass -``` - -Here are some more examples: - -``` -//for meselamp brick snowblock bamboo:wood do //multi //maze %% //sshift y 5 -//for 5 10 15 do //torus %% 3 dirt xz -//for 1 2 3 4 5 do //multi //hollowcylinder y 1 5 meselamp //shift y %% -``` - - -### `//listentities` -Lists all currently loaded ObjectRefs. Displays their IDs, Names (if possible), and positions. - -This command is intended for development and modding. You will not normally need to use this command using WorldEditAdditions. - -`//listentities` takes no arguments. - -``` -//listentities -``` - - -## Extras - - - -### `//speed []` -Adjusts your player movement speed to the specified value. In other words: - -```weacmd -//speed 2 -``` - -...will double your movement speed. - -This command also takes Minetest's "Fast mode" into account and adjusts accordingly. Relative adjustments can be done by prepending either a `+` to increase or `-` to decrease respectively. - -```weacmd -//speed +0.5 -//speed -3 -``` - - -### `//y` -Confirms the execution of a command if it could potentially affect a large number of nodes and take a while. This is a regular WorldEdit command. - - - -```weacmd -//y -``` - - -### `//n` -Prevents the execution of a command if it could potentially affect a large number of nodes and take a while. This is a regular WorldEdit command. - - - -```weacmd -//n -``` - - - -## Tools - - -### Movement speed adjustment tool -The movement speed adjustment tool, as the name suggests, adjusts your local player movement speed. It looks like this: ![A picture of the move speed adjustment tool. It looks like a monarch butterfly.](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/dev/worldeditadditions_farwand/textures/worldeditadditions_movement.png). - -Primary (left) clicking will increase your movement speed, and secondary (right) clicking will decrease it in x0.5 increments, down to a minimum of x0.5. - -Note this only affects **you**, and **not any other player**. - -See also [`//speed`](#speed). - -### Far Wand -The far wand (`worldeditadditions:farwand`) is a variant on the traditional WorldEdit wand (`worldedit:wand`). It looks like this: ![A picture of the far wand](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/worldeditadditions_farwand/textures/worldeditadditions_farwand.png) - -It functions very similarly to the regular WorldEdit wand, except that it has a _much_ longer range - which can be very useful for working on large-scale terrain for example. It also comes with an associated command to control it. - -Note that punching out the positions **does not unset them**. Use `//reset` to reset the defined region. - -### `//farwand skip_liquid (true|false) | maxdist ` -This command helps control the behaviour of the [WorldEditAdditions far wand](#far-wand) and [cloud wand](#cloud-wand). Calling it without any arguments shows the current status: - -```weacmd -//farwand -``` - -You can decide whether you can select liquids or not like so: - -```weacmd -//farwand skip_liquid true -//farwand skip_liquid false -``` - -You can change the maximum range with the `maxdist` subcommand: - -```weacmd -//farwand maxdist 1000 -//farwand maxdist 200 -//farwand maxdist 9999 -``` - -Note that the number there isn't in blocks (because hard maths). It is however proportional to the distance the wand will raycast looks for nodes, so a higher value will result in it raycasting further. - -### Cloud Wand -The cloud wand (`worldeditadditions:cloudwand`) is a another variant the above _Far Wand_. It looks like this: ![A picture of the far wand](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/worldeditadditions_farwand/textures/worldeditadditions_cloudwand.png) - -Unlike the other 2 wands, this wand functions in an additive manner. Left-click on a node to expand the currently defined region (creating a new one if one isn't defined already) to include that node. Right click to clear the currently defined region. - -It has the range of the _Far Wand_ mentioned above too, so you can select nodes from a great distance. It also abides by preferences set via the `//farwand` chat command. - -Note that punching out the positions **does not unset them**. Use `//reset` to reset the defined region. - - -### MultiPoint Wand -The third type of wand provided by WorldEditAdditions is completely different, in that it allows you to select up to **999 points** at once! It looks like this: ![A picture of the multi-point wand](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/worldeditadditions_farwand/textures/worldeditadditions_multiwand.png) - -It is important to note that (at present) the points selected by this wand **are not compatible with normal points**. This will change in the future, but requires a lot of work to implement. - -It has the following actions: - - - **Left click:** Add a new point - - **Right click:** Undo adding a point - -It has the range of the other wands mentioned above though, so you can select nodes from a great distance. It also abides by preferences set via the `//farwand` chat command. +# Chat Command Reference + +This is the full chat command reference for WorldEditAdditions. Having trouble finding the section you want? Try the **[quick reference](https://github.com/sbrl/Minetest-WorldEditAdditions#quick-command-reference)** instead, which has links to back to sections of this document! + +**Check out the reference on the new website - it's even searchable: ** + +Other useful links: + + - [WorldEditAdditions quick reference](https://github.com/sbrl/Minetest-WorldEditAdditions#quick-command-reference) + - [WorldEditAdditions Chat Command Cookbook](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Cookbook.md) + - [WorldEdit Chat Command Reference](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md) + - [`we_env`](https://github.com/sfan5/we_env#readme) + +**Note:** If anything in this reference isn't clear, that's a bug. Please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new) (or even better a PR improving it) to let me know precisely which bit you don't understand and why. + +## Geometry + + +### `//metaball add | remove | render [] | list | clear | volume` +Draws two or more [metaballs](https://en.wikipedia.org/wiki/Metaballs). Based on a subcommand system, since each metaball may have a different radius. + +Calling `//metaball render ` actually makes changes to the world - all others manipulate an internal player-local list of metaballs to be drawn. + +#### `//metaball add ` +Adds a new metaball to the (player-local) list of metaballs to be draw with the given radius. The position of the new metaball is taken from pos1. + +```weacmd +//metaball add 5 +//metaball add 10 +//metaball add 65 +``` + +#### `//metaball remove ` +Removes the metaball with the given index from the list. See also `//metaball list`. + +```weacmd +//metaball remove 1 +//metaball remove 2 +//metaball remove 5 +``` + +#### `//metaball render []` +Renders the current list of metaballs to the world using replace_node to draw with. + +Threshold is a value that acts as an offset for large or small the metaballs should be. Defaults to 1, with larger values resulting in **smaller** metaballs and smaller values resulting in **larger** metaballs. It is not recommended to set threshold to a negative number. + +Does not clear the list of metaballs after rendering - see `//metaball clear` for that. + +```weacmd +//metaball render dirt +//metaball render glass +//metaball render stone +//metaball render stone 2 +//metaball render cobble 0.5 +``` + +#### `//metaball list` +Lists all the metaballs currently registered for the current player (all `//metaball` commands operate on the current player's metaball list only), and their indexes, positions, and sizes. Useful when using `//metaball remove ` to identify which metaball you want to remove. + +Example output: + +``` +Index Position Radius +1 (-495, 37, 150) 7 +2 (-506, 33, 142) 7 +3 (-516, 35, 152) 10 +``` + +```weacmd +//metaball list +``` + +#### `//metaball clear` +Clears the list of metaballs for the current player. + +```weacmd +//metaball clear +``` + +#### `//metaball volume` +Calculate an estimated volume of the metaballs currently in the list. + +```weacmd +//metaball volume +``` + + +### `//ellipsoid [h[ollow]]` +Creates a solid ellipsoid at position 1 with the radius `(rx, ry, rz)`. + +```weacmd +//ellipsoid 10 5 15 ice +//ellipsoid 3 5 10 dirt +//ellipsoid 20 10 40 air +//ellipsoid 14 5 8 steelblock h +//ellipsoid 7 4 7 papyrus hollow +``` + +### `//hollowellipsoid ` +Creates a hollow ellipsoid at position 1 with the radius `(rx, ry, rz)`. Works the same way as `//ellipsoid` does. + +```weacmd +//hollowellipsoid 10 5 15 glass +//hollowellipsoid 21 11 41 stone +``` + +### `//ellipsoid2 [ [h[ollow]]]` +Creates an (optionally hollow) solid ellipsoid that fills the defined region. + +```weacmd +//ellipsoid2 +//ellipsoid2 ice +//ellipsoid2 air +//ellipsoid2 steelblock h +//ellipsoid2 papyrus hollow +``` + + +### `//torus [ [h[ollow]]]` +Creates a solid torus at position 1 with the specified major and minor radii. The major radius is the distance from the centre of the torus to the centre of the circle bit, and the minor radius is the radius of the circle bit. + +The optional axes sets the axes upon which the torus will lay flat. Possible values: `xy` (the default), `xz`, `yz`. A single axis may also be specified (i.e. `x`, `y`, or `z`) - this will be interpreted as the axis that runs through the hole in the middle of the torus. + +```weacmd +//torus 15 5 stone +//torus 5 3 meselamp +//torus 10 6 sandstone xz +//torus 10 6 wool:red y +//torus 25 10 dirt xz hollow +``` + +### `//hollowtorus []` +Creates a hollow torus at position 1 with the radius major and minor radii. Works the same way as `//torus` does. + +```weacmd +//hollowtorus 10 5 glass +//hollowtorus 21 11 stone +//hollowtorus 18 6 dirt xz +``` + +### `//line [ []]` +Draw a line from position 1 to position 2, optionally with a given thickness. + +The radius can be thought of as the thickness of the line, and is defined as the distance from a given node to an imaginary line from pos1 to pos2. Defaults to drawing with dirt and a radius of 1. + +Floating-point values are fully supported for the radius. + +```weacmd +//line +//line stone +//line sandstone 3 +//line glass 0.5 +``` + +### `//hollow []` +Replaces nodes inside the defined region with air, but leaving a given number of nodes near the outermost edges alone. In other words, it makes the defined region hollow, while leaving walls around the edges of a given thickness (defaulting to a wall thickness of 1). + +Note that all air-like nodes are also left alone. + +```weacmd +//hollow +//hollow 2 +``` + +### `//maze [ [ []]]` +Generates a maze using replace_node as the walls and air as the paths. Uses [an algorithm of my own devising](https://starbeamrainbowlabs.com/blog/article.php?article=posts/070-Language-Review-Lua.html) (see also [this post of mine that has lots of eye candy :D](https://starbeamrainbowlabs.com/blog/article.php?article=posts/429-lua-blender-mazes.html)). It is guaranteed that you can get from every point to every other point in generated mazes, and there are no loops. + +Requires the currently selected area to be at least 3x3 on the x and z axes respectively. + +Mazes are generated from the bottom to the top of the defined region. In other words, the height of the walls of the maze is equal to the height of the defined region. + +The optional `path_length` and `path_width` arguments require additional explanation. When generating a maze, a multi-headed random walk is performed. When the generator decides to move forwards from a point, it does so `path_length` nodes at a time. `path_length` defaults to `2`. + +`path_width` is easier to explain. It defaults to `1`, and is basically the number of nodes wide the path generated is. + +Note that `path_width` must always be at least 1 less than the `path_length` in order to operate normally. + +Note also that since WorldEditAdditions v1.10, the seed doesn't have to be a number (but it can't contain spaces due to the parsing algorithm used). Non-numbers are hashed to a number using a simple (non-crypto-safe) hashing algorithm. + +The last example below shows how to set the path length and width: + +```weacmd +//maze ice +//maze stone 2 1 1234 +//maze dirt 4 2 56789 +//maze glass 2 1 minetestiscool +``` + + +### `//maze3d [ [ [ []]]]` +Same as `//maze`, but instead generates mazes in 3 dimensions instead of 2. Requires the currently selected area to be at least 3x3x3. + +The optional `path_depth` parameter defaults to `1` and allows customisation of the height of the paths generated. In other words, it customises the ceiling height, or the distance from the floor to the ceiling of the paths generated. + +To get a better look at the generated maze, try inverting it like so: + +```weacmd +//maze3d stone +//replace air dirt +//replace stone air +``` + +Additional examples: + +```weacmd +//maze3d glass +//maze3d bush_leaves 2 1 1 12345 +//maze3d dirt 4 2 2 +//maze3d stone 6 3 3 54321 +``` + + +### `//walls [ []]` +Creates vertical walls of `` around the inside edges of the defined region, optionally specifying the thickness thereof. Defaults to a replace node of `dirt` and a wall thickness of 1. + +```weacmd +//walls +//walls dirt +//walls stone +//walls goldblock +//walls sandstone 2 +//walls glass 4 +``` + + +### `//spiral2 [] [ [ [] ] ]` +Generates both square and circular spiral shapes with the given `` - defaulting to square spirals. The interval defines the gap between the spiral in nodes, and the acceleration defines by how much the interval should be increased (a value of 1 means 1 node per revolution). + +``` +//spiral2 +//spiral2 circle stone +//spiral2 square +//spiral2 circle +//spiral2 glass 5 +//spiral2 square desert_sand 3 1 +``` + + +### `//dome+ [ ...] [h[ollow]]` +Creates a dome shape (i.e. a hemisphere; half a sphere) with a specified radius of the defined node, optionally specifying the direction it should be pointing in (defaults to the positive y direction). + +For example, `//dome+ 5 stone y` creates a dome shape pointing upwards, but `//dome+ 5 stone -y` creates a dome shape pointing downwards. + +Multiple pointing direction axes can be chained together to create multiple domes on top of each other. Multiple conflicting directions will cancel each other out. + +If `h` or `hollow` is specified at the end, then the resulting dome shape is made hollow. + +``` +//dome+ 5 stone y +//dome+ 10 diamond -x +//dome+ 25 cactus y z +//dome+ 9 dirt x y z +``` + + +### `//spline [ []]` +Draws a curved line, using all the currently defined points as control points. The starting and ending widths of the line can be controlled, and the width will be linearly interpolated. + +**Note:** `//spline` uses the **new** WorldEditAdditions positions! Use the [multipoint wand](#multi-point-wand) to define the control points for the resulting line. + +For those interested, WorldEditAdditions uses the [chaikin curve algorithm](https://starbeamrainbowlabs.com/blog/article.php?article=posts/196-Chaikin-Curve-Generator.html) with linear interpolation for the width to draw the curve. + +```weacmd +//spline dirt 5 2 +//spline glass 3 +//spline bakedclay:violet 3 +``` + +![An example of what //spline can do.](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/.docs/images/reference/spline.jpeg) + +## Misc + + + +### `//rotate+ [ ...] [origin|o []]` +Rotates the defined region using the specified list of rotation operations, optionally around the defined rotation origin. For example, the following: + +```weacmd +//rotate+ y 45 +``` + +...will rotate the defined region around it's centre by 45° on the Y (vertical) axis. + +> [!IMPORTANT] +> There is a known issue in which holes appear in previously flat surfaces when rotating through non-axis-aligned rotations. The cause for this is currently unclear. +> +> If you can shed any light on this issue or make any suggestions, please get in touch. + +We can also extend this to rotate on multiple axes: + +```weacmd +//rotate+ z 90 y 45 +``` + +The rotations will be processed in order as specified from left to right. The following relative keywords are currently supported in place of an absolute axis name: + +Keyword | Meaning +------------|-------------------- +`right` | Rotates around the Y axis to the right - aka clockwise. +`left` | Rotates around the Y axis to the left - aka anticlockwise. + +A custom rotation origin can be specified too. This is done via the `origin` keyword and takes the form of specifying a position to rotate around instead of the default (picking the centre point between pos1 and pos2). For example: + +```weacmd +//rotate+ x 20 origin 3 +``` + +....will rotate 20° on the X axis around position 3. See the [multi-point wand](#multipoint) for more information on setting positions other than pos1 and pos2. + +The `origin` keyword's argument is optional, and if no position number is specified defaults to position 3. + +```weacmd +//rotate+ y 90 x 45 origin +//rotate+ y 90 x 45 o +//rotate+ x 60 origin 5 z 20 +``` + + +### `//floodfill [ []]` +Floods all connected nodes of the same type starting at _pos1_ with `` (which defaults to `water_source`), in a sphere with a radius of `` (which defaults to 50). + +```weacmd +//floodfill +//floodfill water_source 50 +//floodfill glass 25 +``` + + +### `//wbox ` +Sets the edges of the current selection to ``to create an outline of a rectangular prism. Useful for roughing in walls. + +In other words, creates a wireframe of a box defined by the current selection. + +```weacmd +//wbox silver_sandstone +//wbox dirt +``` + +### `//wcompass []` +Creates a compass around pos1 with a single node bead pointing north (+Z). + +```weacmd +//wcompass meselamp +//wcompass desert_cobble torch +//wcompass gold diamond +``` + +### `//wcorner ` +Set the corners of the current selection to ``. Useful for outlining building sites and setting boundaries. + +```weacmd +//wcorner glass +//wcorner stone_with_iron +``` + +### `//scale | [ [ ` +Advanced version of [`//stretch` from WorldEdit](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md#stretch-stretchx-stretchy-stretchz) that can scale both up and down at the same time by transparently splitting it into 2 different operations. Scaling up is *always* done before scaling down. + +Although the syntax looks complicated, it's really quite simple. The key concept to understand is that of the scale factor. It refers to how much the defined region should be scaled up or down by, and can be specified in multiple different ways: + +Scale Factor | Meaning +----------------|--------------------- +1 | Don't scale at all. +0.5 | Scale down by 50% +2 | Scale up by 2x, doubling the size +5 | Scale up by 5x, quintupling the size +20% | Scale down to 30% of the original size +1/3 | Scale down to 1 third of original size + +In short, you can specify the scale factor directly, as a percentage, or as 1 number divided by another number. + +> [!NOTE] +> `//scale` always scales in the _positive direction_ by default. This can be changed however - see below. + +With this in mind, there are 3 forms that you can tell `//scale` how you want to scale the defined region: + +#### Single Axis +If you just need to scale a single axis, you can tell `//scale` that like so: + +```weacmd +//scale +``` + +To give a concrete example: + +```weacmd +//scale y 2 +``` + +The above will scale the defined region in the positive y direction by 2 times, doubling the height. If you want to scale in the opposite direction, do this: + +```weacmd +//scale -y 2 +``` + +This will scale in the _negative_ y direction by 2 times (again, doubling the height). Some more examples: + +```weacmd +//scale z 50% +//scale -x 1/3 +``` + +#### All axes +To scale on all axes at once, `//scale` takes the shortcut syntax of specifying a single scale factor: + +```weacmd +//scale 2 +//scale 200% +``` + +Both of the above will scale the defined region up by 2 times in all directions. + +#### Multiple scale factors +If you want to specify different scale factors for difference axes, then `//scale` also supports a third syntax. Here's an example: + +```weacmd +//scale 2 3 4 +``` + +This will scale the defined region by 2x in the positive x, 3x in the positive y, and 4x in the positive z. As these are all scale factors, we can also use the syntax described above to scale up and down in the same operation: + +```weacmd +//scale 50% 2 1/4 +``` + +This will first scale in the positive y by 2x. Once that operation is completed, it will scale down to 50% size in the positive x and down to 25% size in the positive z. Note that if you want to scale down first and then scale up, you'll need to execute 2 separate commands. + +If you want to change the anchor point of the scaling operation too, `//scale` supports a final syntax like so: + +```weacmd +//scale 50% 2 1/4 1 -1 1 +``` + +By adding 3 extra numbers for the x, y, and z axes respectively, we can control the direction `//scale` performs the scaling operation. A value of 1 or greater indicates the positive direction of the axis, and a value of -1 or less indicates the negative direction of the axis. I recommend by [worldedit_hud_helper](https://content.minetest.net/packages/Starbeamrainbowlabs/worldedit_hud_helper/) mod for easily determining which direction is which. + +So in the above example, we scale in the positive x and z directions, and the negative y direction. + + +### `//copy+ [ [...]] [aa|airapply]` +Fully backwards-compatible with `//copy` from regular WorldEdit, but allows you to specify multiple axes at once in a single copy operation. Each successive axis in the list is specified in the form ` `, where: + + - `` is the name of the axis to move the defined region along + - `` is the number of nodes along the defined axis to move + +All of the following values are valid axes: + + - `x` + - `y` + - `z` + - `-x` + - `-y` + - `-z` + - `?` / `front` / `f` + - `back` / `b` + - `left` / `l` + - `right` / `r` + - `up` / `u` + - `down` / `d` + +Additionally all the absolute axis names (`x`/`y`/`z`/`-x`/`-y`/`-z`) may also be specified multiple times under the same count - e.g. `xy-z 6`. + +Finally, if the word `airapply` (or `aa` for short) is present at the end of the command invocation it enables the integrated airapply mode, which replaces target nodes only if they are air-like. + +``` +//copy+ x 6 +//copy+ y 10 z 4 +//copy+ front 6 left 5 +//copy+ ? 10 r 25 y 50 +//copy+ xz 50 front 22 +//copy+ yx 25 +//copy+ -xz-y 10 +//copy+ y 45 aa +//copy+ -y 15 z 5 airapply +``` + + +### `//move+ [ [...]] [aa|airapply]` +Identical to [`//copy+`](#copy), but instead moves the defined region instead of copying it. + +Note that the integrated `airapply` (`aa` for short) also works as in [`//copy+`](#copy), but remember that if a given target node is not *not* air-like and the integrated `airapply` mode is enabled, the source node is still moved from the source, but destroyed because it is can't be set at the target. + + +``` +//move+ x 6 +//move+ y 10 z 4 +//move+ front 6 left 5 +//move+ ? 10 r 25 y 50 +//move+ xz 50 front 22 +//move+ yx 25 +//move+ -xz-y 10 +//move+ back 20 aa +//move+ -z 45 y 3 airapply +``` + + +### `//replacemix [] [] [ []] [ []] ...` +Replaces a given node with a random mix of other nodes. Functions like `//mix`. + +This command is best explained with examples: + +```weacmd +//replacemix dirt stone +``` + +The above functions just like `//replace` - nothing special going on here. It replaces all `dirt` nodes with `stone`. + +Let's make it more interesting: + +```weacmd +//replacemix dirt 5 stone +``` + +The above replaces 1 in every 5 `dirt` nodes with `stone`. Let's get even fancier: + +```weacmd +//replacemix stone stone_with_diamond stone_with_gold +``` + +The above replaces `stone` nodes with a random mix of `stone_with_diamond` and `stone_with_gold` nodes. But wait - there's more! + +```weacmd +//replacemix stone stone_with_diamond stone_with_gold 4 +``` + +The above replaces `stone` nodes with a random mix of `stone_with_diamond` and `stone_with_gold` nodes as before, but this time in the ratio 1:4 (i.e. for every `stone_with_diamond` node there will be 4 `stone_with_gold` nodes). Note that the `1` for `stone_with_diamond` is implicit there. + +If we wanted to put all of the above features together into a single command, then we might do this: + +```weacmd +//replacemix dirt 3 sandstone 10 dry_dirt cobble 2 +``` + +The above replaces 1 in 3 `dirt` nodes with a mix of `sandstone`, `dry_dirt`, and `cobble` nodes in the ratio 10:1:2. Awesome! + +Since WorldEditAdditions v1.12, you can also use percentages: + +```weacmd +//replacemix dirt 33% sandstone 75% dry_dirt 10% cobble 15% +``` + +Note though that the percentages are internally converted to a 1-in-N chance and rounded down. + +Here are all the above examples together: + +```weacmd +//replacemix dirt stone +//replacemix dirt 5 stone +//replacemix stone stone_with_diamond stone_with_gold +//replacemix stone stone_with_diamond stone_with_gold 4 +//replacemix dirt 3 sandstone 10 dry_dirt cobble 2 +``` + + +### `//revolve []` +Makes a given number of copies of the currently defined region (bounded by pos1 and pos2) at a given number of equally spaced points rotated around a given pivot/origin point. + +For example, `//revolve 4` would make rotated copies of the currently defined region at intervals 0° (the source to copy), 90°, 180°, and 270° around the given pivot point. + +`pivot_point_number` is the number of the defined position that should act as the pivot point, or origin for the revolve operation. It defaults to the last position defined. Note that it cannot be pos1 or pos2, as these are used to define the region that should be rotated. Use the [multi-point wand](#multi) to define a position with an index of 3 or more. + +```weacmd +//revolve 4 +//revolve 6 6 +``` + + +## Terrain + + + +### `//convolve [[,]] []` +Advanced version of `//smooth` from we_env, and one of the few WorldEditAdditions commands to have any aliases (`//smoothadv` and `//conv`). + +Extracts a heightmap from the defined region and then proceeds to [convolve](https://en.wikipedia.org/wiki/Kernel_(image_processing)) over it with the specified kernel. The kernel can be thought of as the filter that will be applied to the heightmap. Once done, the newly convolved heightmap is applied to the terrain. + +Possible kernels: + +Kernel | Description +----------------|------------------------------ +[`box`](https://en.wikipedia.org/wiki/Box_blur) | A simple uniform box blur. +`pascal` | A kernel derived from the odd layers of [Pascal's Triangle](https://en.wikipedia.org/wiki/Pascal%27s_triangle). Slightly less smooth than a Gaussian blur. +[`gaussian`](https://en.wikipedia.org/wiki/Gaussian_blur) | The default. A Gaussian blur - should give the smoothest result, and also the most customisable - see below. + +If you can think of any other convolutional filters that would be useful, please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new). The code backing this command is very powerful and flexible, so adding additional convolutional filters should be pretty trivial. + +The width and height (if specified) refer to the dimensions of the kernel and must be odd integers and are separated by a single comma (and _no_ space). If the height is not specified, it defaults to the width. If using the `gaussian` kernel, the width and height must be identical. Larger kernels are slower, but produce a more smoothed effect and take more nearby nodes into account for every column. Defaults to a 5x5 kernel. + +The sigma value is only applicable to the `gaussian` kernel, and can be thought of as the 'smoothness' to apply. Greater values result in more smoothing. Default: 2. See the [Gaussian blur](https://en.wikipedia.org/wiki/Gaussian_blur) page on Wikipedia for some pictures showing the effect of the sigma value. + +```weacmd +//convolve +//convolve box 7 +//convolve pascal 11,3 +//convolve gaussian 7 +//convolve gaussian 9 10 +//convolve gaussian 5 0.2 +``` + + +### `//overlay [] [] [ []] ...` +Places `` in the last contiguous air space encountered above the first non-air node. In other words, overlays all top-most nodes in the specified area with ``. Optionally supports a mix of node names and chances, as `//mix` (WorldEdit) and `//replacemix` (WorldEditAdditions) does. + +Will also work in caves, as it scans columns of nodes from top to bottom, skipping every non-air node until it finds one - and only then will it start searching for a node to place the target node on top of. + +Note that all-air columns are skipped - so if you experience issues with it not overlaying correctly, try `//expand down 1` to add an extra node's space to your defined region. + +Note also that columns without any air nodes in them at all are also skipped, so try `//expand y 1` to add an extra layer to your defined region. + +```weacmd +//overlay grass +//overlay glass +//overlay grass_with_dirt +//overlay grass_with_dirt 10 dirt +//overlay grass_with_dirt 10 dirt 2 sand 1 +//overlay sandstone dirt 2 sand 5 +//overlay dirt 90% stone 10% +``` + + +### `//fillcaves []` +Fills in all airlike nodes beneath non airlike nodes, which gives the effect of filling in caves. Defaults to filling in with stone, but this can be customised. + +Note that the *entire* cave you want filling must be selected, as `//fillcaves` only operates within the defined region (ref #50). + +```weacmd +//fillcaves +//fillcaves dirt +//fillcaves brick +``` + + + +### `//layers [] [ []] [ []] ...` +Finds the first non-air node in each column and works downwards, replacing non-air nodes with a defined list of nodes in sequence. Like WorldEdit for Minecraft's `//naturalize` command, and also similar to [`we_env`'s `//populate`](https://github.com/sfan5/we_env). Speaking of, this command has `//naturalise` and `//naturalize` as aliases. Defaults to 1 layer of grass followed by 3 layers of dirt. + +Since WorldEditAdditions v1.13, a maximum and minimum slope is optionally accepted, and constrains the columns in the defined region that `//layers` will operate on. For example, specifying a value of `20` would mean that only columns with a slop less than or equal to 20° (degrees, not radians) will be operated on. A value of `45..60` would mean that only columns with a slope between 45° and 60° will be operated on. + +The list of nodes has a form similar to that of a chance list you might find in `//replacemix`, `//overlay`, or `//mix` - see the examples below. If the number of layers isn't specified, `1` is assumed (i.e. a single layer). + + +```weacmd +//layers dirt_with_grass dirt 3 +//layers sand 5 sandstone 4 desert_stone 2 +//layers brick stone 3 +//layers cobble 2 dirt +//layers 45..60 dirt_with_snow dirt 2 +//layers 30 snowblock dirt_with_snow dirt 2 +``` + + +### `//erode [ [ []] [ []] ...]` +Runs an erosion algorithm over the defined region, optionally passing a number of key - value pairs representing parameters that are passed to the chosen algorithm. This command is **experimental**, as the author is currently on-the-fence about the effects it produces. + +Works best if you run `//fillcaves` first, or otherwise have no air nodes below the top non-air node in each column. + +Currently implemented algorithms: + +Algorithm | Mode | Description +------------|-------|------------------- +`snowballs` | 2D | The default - based on [this blog post](https://jobtalle.com/simulating_hydraulic_erosion.html). Simulates snowballs rolling across the terrain, eroding & depositing material. Then runs a 3x3 gaussian kernel over the result (i.e. like the `//conv` / `//smoothadv` command). +`river` | 2D | Fills in potholes and lowers pillars using a cellular automata-like algorithm that analyses the height of neighbouring columns. + +Usage examples: + +```weacmd +//erode +//erode snowballs +//erode snowballs count 25000 +``` + +Each of the algorithms above have 1 or more parameters that they support. These are detailed below. + +#### Algorithm: `snowballs` +Based on the algorithm detailed in [this blog post](https://jobtalle.com/simulating_hydraulic_erosion.html) ([direct link to the source code](https://github.com/jobtalle/HydraulicErosion/blob/master/js/archipelago/island/terrain/erosionHydraulic.js)), devised by [Job Talle](https://jobtalle.com/). + +Parameter | Type | Default Value | Description +--------------------|-----------|-------------------|-------------------------- +rate_deposit | `float` | 0.03 | The rate at which snowballs will deposit material +rate_erosion | `float` | 0.04 | The rate at which snowballs will erode material +friction | `float` | 0.07 | More friction slows snowballs down more. +speed | `float` | 1 | Speed multiplier to apply to snowballs at each step. +max_steps | `float` | 80 | The maximum number of steps to simulate each snowball for. +velocity_hist_count | `float` | 3 | The number of previous history values to average when detecting whether a snowball has stopped or not +init_velocity | `float` | 0.25 | The maximum random initial velocity of a snowball for each component of the velocity vector. +scale_iterations | `float` | 0.04 | How much to scale erosion by as time goes on. Higher values mean that any given snowball will erode more later on as more steps pass. +maxdiff | `float` | 0.4 | The maximum difference in height (between 0 and 1) that is acceptable as a percentage of the defined region's height. +count | `float` | 25000 | The number of snowballs to simulate. +noconv | any | n/a | When set to any value, disables to automatic 3x3 gaussian convolution. + +Usage examples: + +```weacmd +//erode +//erode snowballs +//erode snowballs count 50000 +``` + +If you find any good combinations of these parameters, please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new) (or a PR!) and let me know! I'll include good combinations here, and possibly add a presets feature too. + +#### Algorithm: `river` +Ever been annoyed by small 1 wide holes or thin pillars all over the place? This command is for you! Does not operate on the very edge of the defined region, because the algorithm can't see the neighbours of those columns. + +Parameter | Type | Default Value | Description +--------------------|-----------|-------------------|-------------------------- +steps | `integer` | 1 | The number of rounds or passes of the algorithm to run. Useful if you have a 1x3 hole for instance, it will take at least 2 steps to fill it in - and more if it's deeper than 1 node. +lower_sides | `string` | 4,3 | Comma separated list of numbers. Columns with this many sides lower than it will be lowered in height by 1 node. +raise_sides | `string` | 4,3 | Comma separated list of numbers. Columns with this many sides higher than it will be raised in height by 1 node. +doraise | `boolean` | true | Whether to raise columns in height. If false, then no columns will be raised in height even if they are eligible to be so according to `raise_sides`. +dolower | `boolean` | true | Whether to lower columns in height. If false, then no columns will be lowered in height even if they are eligible to be so according to `lower_sides`. + +Usage examples: + +```weacmd +//erode river +//erode river steps 10 +``` + + +### `//noise2d [ []] [ []] ...]` +Applies 2D noise to the terrain in the defined region. Like `//erode`, this command accepts a number of different key-value parameters and provides a number of different underlying algorithms. + +In other words, this command changes the height of the terrain according to some noise function (e.g. Perlin noise): + +![//noise2d applies 2D noise as a modifier to terrain height.](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/dev/.docs/images/reference/noise2d.jpeg) + +It does so like this: + +1. Take coordinates of each column +2. Plug them through a noise function (see below) +3. Apply the generated noise value to the terrain. + +`//noise2d` has a number of parameters that let you adjust the mathematical properties of step 2, which are explained in the table below. + +Some terms that are useful to know: + +- **Scale:** How big or small the noise is. Lower values stretch it out to be bigger, and higher values squash it in. +- **Offset:** Noise is calculated by passing some coordinates into a function. +- **Perlin:** A noise algorithm. `//noise2d` defaults to this. + + +#### Table of parameters + +Parameter | Type | Default Value | Description +------------|-----------|---------------|----------------------- +algorithm | `string` | perlinmt | The 2D noise algorithm to apply - see below. +apply | `string¦integer` | 5 | How to apply the noise to the terrain - see below. +scale | `float` | 1 | Sets `scalex`, `scaley`, and `scalez` all at once. Consider also `//apply`. +scalex | `float` | 1 | The scale of the noise on the x axis. +scaley | `float` | 1 | The scale of the noise on the y axis. +scalez | `float` | 1 | The scale of the noise on the z axis. +offsetx | `float` | 1 | The offset to add to the x axis before calling the noise function. +offsety | `float` | 0 | The offset to add to the y axis before calling the noise function. +offsetz | `float` | 0 | The offset to add to the z axis before calling the noise function. +exponent | `float` | 0 | Raise the generated noise value (with a range of 0 to 1) to this power. Generally results in sharper peaks. +multiply | `float` | 1 | Multiply the generated noise value by this number +add | `float` | 0 | Add this number to the generated noise value. + +#### Apply +Different values of the `apply` parameter result in the generated noise values being applied in different ways: + +1. An integer indicates that the noise should be rescaled to a given amplitude (equal parts of the range above and below 0) before being added to the terrain heightmap.` +2. The exact string `add`: Noise values are added to each heightmap pixel. +3. The exact string `multiply`: Each heightmap pixel is multiplied by the corresponding noise value. + +An integer is the most common way to use `//noise2d`. So, for example: + +```weacmd +//noise2d apply 5 +``` + +...would alter the height of each column of nodes by at most 5 blocks either side, while: + +```weacmd +//noise2d apply 10 +``` + +...would alter the height by 10 blocks instead of 5. + +#### Types of noise +Another thing that can be changed is the noise algorithm. This changes what the noise that is applied to the terrain looks like. + +The following algorithms are currently available: + +Algorithm | Description +------------|-------------------------- +`perlinmt` | **Default**. Perlin noise, backed by Minetest's inbuilt `PerlinNoise` class. +`perlin` | Perlin noise, backed by a pure Lua perlin noise implementation. Functional, but currently contains artefacts I'm having difficulty tracking down. +`sin` | A sine wave created with `math.sin()`. +`white` | Random white noise. In other words, just random values. +`red` | Red noise - has a lower frequency than white noise. Ref [Noise Functions and Map Generation by Red Blob Games](https://www.redblobgames.com/articles/noise/introduction.html). +`infrared` | Even smoother than red noise. Tends to also be quite flat unless you use a slightly higher `apply` value (e.g. `20`). + +When specifying algorithm names, the `algorithm` parameter name is optional. For example, the following are both equivalent: + +```weacmd +//noise2d offsetx 4 perlin scale 0.2 +//noise2d offsetx 4 algorithm perlin scale 0.2 +``` + +#### Further examples +Example invocations: + +```weacmd +//noise2d sin scale 0.5 +//noise2d offsetx 20 perlin +//noise2d sin exponent 4 +``` + + +### `//sculptlist [preview]` +Lists all the available sculpting brushes for use with `//sculpt`. If the `preview` keyword is specified as an argument, then the brushes are also rendered in ASCII as a preview. See [`//sculpt`](#sculpt). + +``` +//sculptlist +//sculptlist preview +``` + + +### `//sculpt [ [ []]]` +Applies a specified brush to the terrain at position 1 with a given height and a given size. Multiple brushes exist (see [`//sculptlist`](#sculptlist)) - and are represented as a 2D grid of values between 0 and 1, which are then scaled to the specified height. The terrain around position 1 is first converted to a 2D heightmap (as in [`//convolve`](#convolve) before the brush "heightmap" is applied to it. + +Similar to [`//sphere`](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md#sphere-radius-node), [`//cubeapply 10 set`](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md#cubeapply-sizesizex-sizey-sizez-command-parameters), or [`//cylinder y 5 10 10 dirt`](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md#cylinder-xyz-length-radius1-radius2-node) (all from [WorldEdit](https://content.minetest.net/packages/sfan5/worldedit/)), but has a number of added advantages: + + - No accidental overhangs + - Multiple custom brushes (see below on how you can add your own!) + +A negative height value causes the terrain to be lowered by the specified number of nodes instead of raised. + +While sculpting brushes cannot yet be rotated, this is a known issue. Rotating sculpting brushes will be implemented in a future version of WorldEditAdditions. + +The selection of available brushes is limited at the moment, but see below on how to easily create your own! + +``` +//sculpt +//sculpt default 25 3 +//sculpt ellipse +//sculpt circle 50 3 +``` + +#### Create your own brushes +2 types of brush exist: + +1. Dynamic (lua-generated) brushes +2. Static brushes + +All brushes are located in `worldeditadditions/lib/sculpt/brushes` (relative to the root of WorldEditAdditions' installation directory). + +Lua-generated brushes are not the focus here, but are a file with the extension `.lua` and return a function that returns a brush - see other existing Lua-generated brushes for examples (and don't forget to update `worldeditadditions/lib/sculpt/.init.lua`). + +Static brushes on the other hand are simply a list of tab-separated values arranged in a grid. For example, here is a simple brush: + +```tsv +0 1 0 +1 2 1 +0 1 0 +``` + +Values are automatically rescaled to be between 0 and 1 based on the minimum and maximum values, so don't worry about which numbers to use. Static brushes are saved with the file extension `.brush.tsv` in the aforementioned directory, and are automatically rescanned when your Minetest server starts. While they can't be rescaled automatically to fix a target size (without creating multiple variants of a brush manually of course, though this may be implemented in the future), static brushes are much easier to create than dynamic brushes. + +To assist with the creation of static brushes, a tool exists to convert any image to a static brush: + + + +The tool can operate on the colour channel of your choice - red, green, blue, or alpha. + +If you've created a cool new brush (be it static or dynamic), **please contribute it to WorldEditAdditions**! That way, everyone can enjoy using your awesome brush. [WorldPainter](https://www.worldpainter.net/) has many brushes available in the community, but `//sculpt` for WorldEditAdditions is new so don't have the same sized collection yet :-) + +To contribute your new brush back, you can either [open a pull request](https://github.com/sbrl/Minetest-WorldEditAdditions/pulls) if you're confident using GitHub, or [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues) with your brush attached if not. + + + +## Flora + + + +### `//forest [] [] [] [ []] ...` +Plants and grows saplings to generate a forest. A density value is optionally taken, which controls the overall density of the forest that is generated. The `bonemeal` mod is required - just like for the [`//bonemeal`](#bonemeal-strength-chance) command. + +The density defaults to 1, acts like a multiplier, and is not affected by the chances of all saplings listed (e.g. you can have a sapling with a chance of 1-in-50, and the overall density of the forest will be unaffected). For example, 2 results in a forest twice as dense as the default, and 0.5 a forest half as dense as the default density. + +The tree types are provided as a list of names and 1-in-N chances, just like [`//overlay`](#overlay-node_name_a-chance_a-node_name_b-chance_b-node_name_n-chance_n-), `//mix`, `//layers`, etc. Unlike the aforementioned commands however, `//forest` has an additional layer of alias resolution to ease the process of determining what the name of the sapling is you want to use to generate forests with. See [`//saplingaliases`](#saplingaliases-aliasesall_saplings) for more details. + +Saplings are placed with [`//overlay`](#overlay-node_name_a-chance_a-node_name_b-chance_b-node_name_n-chance_n-) and grown using the same method that's used by the `//bonemeal` command. Up to 100 attempts are made to grow placed saplings. If all of those attempts fail (success is determined by whether the sapling is still present or not), the sapling is removed and the failure counter is incremented. + +Currently, the following mods are known to have aliases registered: + + - `default` + - [`moretrees`](https://content.minetest.net/packages/VanessaE/moretrees/) (warning: these saplings don't appear to work very well this command - assistance in debugging this would be very helpful) + - [`cool_trees`](https://content.minetest.net/packages/runs/cool_trees/) + +If you like, you can also reference the full name of a sapling node instead. The only requirements for saplings to be supported by this mod are: + +1. It can be bonemealed +2. It has the `sapling` group + +For example, the first 2 examples below are functionally equivalent. + +```weacmd +//forest aspen +//forest default:aspen_sapling +//forest 2 oak 3 aspen pine +//forest 0.5 acacia +``` + + +### `//saplingaliases [aliases|all_saplings]` +Lists all the currently registered sapling aliases in alphabetical order. These aliases can be used in the `//forest` subcommand. + +Optionally takes a single parameter, which is the operating mode. Current implemented operating modes: + +Mode | Description +----------------|---------------------- +`aliases` | The default. Lists all the currently registered sapling aliases in alphabetical order. +`all_saplings` | Spins through all the nodes currently registered in Minetest, and lists all the nodes that have the `sapling` group. + +```weacmd +//saplingaliases +//saplingaliases all_saplings +//saplingaliases aliases +``` + + + +### `//bonemeal [ [ [ [ ...]]]]` +Requires the [`bonemeal`](https://content.minetest.net/packages/TenPlus1/bonemeal/) ([repo](https://notabug.org/TenPlus1/bonemeal/)) mod (otherwise _WorldEditAdditions_ will not register this command and output a message to the server log). Alias: `//flora`. + +Bonemeals all eligible nodes in the current region. An eligible node is one that has an air node directly above it - note that just because a node is eligible doesn't mean to say that something will actually happen when the `bonemeal` mod bonemeals it. + +Optionally takes a strength value (that's passed to `bonemeal:on_use()`, the method in the `bonemeal` mod that is called to actually do the bonemealing). The strength value is a positive integer from 1 to 4 (i.e. 1, 2, 3, or 4) - the default is 1 (the lowest strength). + +I observe that a higher strength value gives a higher chance that something will actually grow. In the case of soil or sand nodes, I observe that it increases the area of effect of a single bonemeal action (thus at higher strengths generally you'll probably want a higher chance number - see below). See the [`bonemeal` mod README](https://notabug.org/TenPlus1/bonemeal) for more information. + +Also optionally takes a chance number. This is the chance that an eligible node will actually get bonemealed, and is a positive integer that defaults to 1. The chance number represents a 1-in-{number} chance to bonemeal any given eligible node, where {number} is the chance number. In other words, the higher the chance number the lower the chance that a node will be bonemealed. + +For example, a chance number of 2 would mean a 50% chance that any given eligible node will get bonemealed. A chance number of 16 would be a 6.25% chance, and a chance number of 25 would be 2%. + +Since WorldEditAdditions v1.12, a percentage chance is also supported. This is denoted by suffixing a number with a percent sign (e.g. `//bonemeal 1 25%`). + +Since WorldEditAdditions v1.13, a list of node names is also optionally supported. This will constrain bonemeal operations to be performed only on the node names listed. + + +```weacmd +//bonemeal +//bonemeal 3 25 +//bonemeal 4 +//bonemeal 1 10 +//bonemeal 2 15 +//bonemeal 2 10% +//bonemeal 2 10% dirt +//bonemeal 4 50 ethereal:grove_dirt +``` + + + +## Statistics + + + +### `//count` +Counts all the nodes in the defined region and returns the result along with calculated percentages (note that if the chat window used a monospace font, the returned result would be a perfect table. If someone has a ~~hack~~ solution to make the columns line up neatly, please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new) :D) + +> [!NOTE] +> The output of `//count` can be rather long sometimes, and Minetest by default only shows the last few lines of chat. Press F10 to show the full chat window that you can then scroll through to inspect the full output. + +```weacmd +//count +``` + + +### `//basename ` +Returns the absolute canonical name of a node, given an alias or partial node name. For example: + +```weacmd +//basename dirt +``` + +...will return `default:dirt`. Uses `worldedit.normalize_nodename(string)` under the hood. + +```weacmd +//basename stonebrick +//basename glass +``` + + +### `//ngroups [v[erbose]]` +Lists the groups that a given node is a member of. For example: + +```weacmd +//ngroups sand +``` + +Might return: + +``` +default:sand ∈ sand crumbly falling_node +``` + +Groups in Minetest can also have a numerical value greater than 0. Append `v` or `verbose` to see those values: + +```weacmd +//ngroups sand v +//ngroups sand verbose +``` + +...both of the above might produce an output like this: + +``` +default:sand ∈ sand=1 crumbly=3 falling_node=1 +``` + +Finally, the customary misc examples: + +```weacmd +//ngroups sand +//ngroups bakedclay:orange v +//ngroups cactus +//ngroups default:dry_shrub v +``` + +### `//ndef ` +Short for *Node Definition*. Prints the definition table for the node with the given name. In other words. the output could look a little like this: + +``` +stairs:stair_birch_wood { + description = (string) "Birch Wood Stair" + sounds = (table) { + dig = (table) { + name = (string) "default_dig_choppy" + gain = (number) 0.4 + } + place = (table) { + name = (string) "default_place_node_hard" + gain = (number) 1 + } + dug = (table) { + name = (string) "default_wood_footstep" + gain = (number) 1 + } + footstep = (table) { + name = (string) "default_wood_footstep" + gain = (number) 0.15 + } + } + name = (string) "stairs:stair_birch_wood" + light_source = (number) 0 + mod_origin = (string) "ethereal" + selection_box = (table) { + fixed = (table) { + 1 = (table) [truncated] + 2 = (table) [truncated] + } + type = (string) "fixed" + } + paramtype = (string) "light" + groups = (table) { + flammable = (number) 3 + stair = (number) 1 + choppy = (number) 2 + oddly_breakable_by_hand = (number) 1 + } + is_ground_content = (boolean) false + on_place = (function) function: 0x765b01d0edb8 + drawtype = (string) "nodebox" + tiles = (table) { + 1 = (table) { + name = (string) "moretrees_birch_wood.png" + backface_culling = (boolean) true + } + } + paramtype2 = (string) "facedir" + sunlight_propagates = (boolean) false + node_box = (table) { + fixed = (table) { + 1 = (table) [truncated] + 2 = (table) [truncated] + } + type = (string) "fixed" + } + type = (string) "node" +} +``` + +This command is intended for debugging and development purposes, but if you're implementing a mod yourself you might find it useful too. + +```weacmd +//ndef stone +//ndef stairs:stair_birch_wood +//ndef glass +``` + + + +## Selection + + +### Unified Axis Keyword (UAK) System +The Unified Axis Keyword (UAK) System is an attempt to allow users to input direction and distance information in three dimensions using "natural" language. The key features include axis clumping, double negatives, relative directions, mirroring and compass directions (more information below). + +*Note: negatives can be applied to axes, directions **AND** distances* + +#### Relative Directions +|Key Words | Interpretation| +|----------|---------------| +|f[ront]\|facing\|? | The direction the player is facing most toward in the world +|b[ack]\|behind\|rear | The opposite of the direction the player is facing most toward in the world +|l[eft] | The direction to the left of the player +|r[ight] | The direction to the right of the player + +```weacmd +back 1 +f r 4 +-facing 13 +``` + +#### Compass Directions +|Key Words | Interpretation| +|----------|---------------| +|n[orth] | z +|s[outh] | -z +|e[ast] | x +|w[est] | -x +|u[p] | y +|d[own] | -y + +```weacmd +south 3 +north west 5 +e d -2 +``` + +#### Axis Clumping +Supported axes are `x`, `y`, `z`, `h`, `v`. All horizontal axes are covered by `h` and both vertical ones are covered by `v`. + +```weacmd +h 5 == xz -xz 5 == x 5 z 5 x -5 z -5 +v 5 == up down 5 == y -y 5 +vxz 5 == xyz -y 5 == xyz 5 y -5 +``` + +#### Inference and Omnidirectionality +The UAK parser takes command input that is split by whitespace and interprets it as a series of values preceded by directional cues. If a number is preceded by another number or nothing it assumes that the number is to be applied on all axes in both positive and negative directions. + +```weacmd +10 == hv 10 == xyz -xyz 10 +x 3 6 == x 3 hv 6 +``` + +From the above examples you can also see the principle of inference. All direction modifiers before a value are interpreted as belonging to that value. So `x v 5` is equivalent to `x 5 v 5` and `xv 5`. + +Because UAK attempts to parse "natural" language, there are many ways to express the same direction and distance. This caters to users with different ways of thinking and different play styles which will hopefully make the tools easier to use. + +--- +--- + +### `//unmark` +Hides the in-game UI that indicates where the current positions and region are located. + +This hides both the WorldEditAdditions *and* the WorldEdit UI if displayed, but does **not** change or remove any points that are registered. + +Should more than 2 points be defined, they are all hidden. + +```weacmd +//unmark +``` + +### `//mark` +Shows the in-game UI that indicates where the current positions and region are located once more. + +Should more than 2 points be defined, they are all shown once more. + +Often used after calling [`//unmark`](#unmark) + +```weacmd +//mark +``` + + +### `//pos1` +Sets pos1 to the location of the calling player. + +This is, as with all other WorldEditAdditions commands, seamlessly synchronised with WorldEdit, allowing you to use any combination of WorldEditAdditions and WorldEdit commands and tools without them desynchronising from one another. + +**Aliases:** `//1` + +```weacmd +//pos2 +``` + +### `//pos2` +Sets pos1 to the location of the calling player. + +This is, as with all other WorldEditAdditions commands, seamlessly synchronised with WorldEdit, allowing you to use any combination of WorldEditAdditions and WorldEdit commands and tools without them desynchronising from one another. + +**Aliases:** `//2` + +```weacmd +//pos2 +``` + +### `//pos ` +Sets position with the given index `` to the location of the calling player. + +Should the index be less than or equal to 2, then as with all other WorldEditAdditions commands, seamlessly synchronised with WorldEdit, allowing you to use any combination of WorldEditAdditions and WorldEdit commands and tools without them desynchronising from one another. + +Should the index be greater than 2, the position will only be registered in WorldEditAdditions, as WorldEdit does not support defining more than 2 points. + +If no index is specified, an error is returned and nothing is done. + +```weacmd +//pos 1 +//pos 3 +//pos 45 +//pos 2 +``` + +### `//reset` +Clears all positions defined and the defined region. + +This also synchronises with WorldEdit, as all other WorldEditAdditions commands do. + +```weacmd +//reset +``` + + +### `//scol [ ] ` +#### === DEPRECATED === +Please use `//srel` instead. + + +### `//srect [ []] ` +#### === DEPRECATED === +Please use `//srel` instead. + + +### `//scube [ [ []]] ` +#### === DEPRECATED === +Please use `//srel` instead. + + +### `//scloud <0-6|stop|reset>` +Short for _select point cloud_. Sets pos1 and pos2 to include the nodes you punch. Numbers 1-6 designate how many nodes you want to punch before the operation ends. 0 or stop terminate the operation so that any further nodes you punch won't be added to selection. Reset terminates operation if one is running and resets the selection area. + +```weacmd +//scloud 6 +//scloud 5 +//scloud stop +``` + + +### `//scentre` +Short for _select center_. Sets pos1 and pos2 to the centre point(s) of the current selection area. 1, 2, 4 or 8 nodes may be selected depending on what parts of the original selection are even in distance. Implementation thanks to @VorTechnix. + +```weacmd +//scentre +``` + +### `//srel ` +Short for _select relative_. Sets the pos2 at set distances along 3 axes relative to pos1. If pos1 is not set it will default to the node directly under the player. The axis arguments accept `x, y, z` as well as `up, down, left, right, front, back`. Left, right, front and back are relative to player facing direction. Negative (`-`) can be applied to the axis, the length or both. Implementation thanks to @VorTechnix. + +```weacmd +//srel front 5 +//srel y 12 right -2 +//srel left 3 up 5 -front 7 +//srel -z 12 -y -2 x -2 +``` + +### `//sgrow ` +Short for _selection grow_. Grows the current selection along specified axes/directions. +Aliases: `//extend`, `//outset`. + +```weacmd +//sgrow back 4 +//sgrow left -2 v r 2 +//sgrow h 4 +//sgrow -zy -2 x -2 +``` + +### `//sshrink ` +Short for _selection shrink_. Shrinks the current selection along specified axes/directions. +Aliases: `//contract`, `//inset`. + +```weacmd +//sshrink left 4 +//sshrink right -2 up 2 +//sshrink v 4 +//sshrink -hy 2 x -3 true +``` + +### `//sshift ` +Short for _selection shift_. Shifts the WorldEdit region along 3 axes. The axis arguments accept `x, y, z` as well as `up, down, left, right, front, back`. Left, right, front and back are relative to player facing direction. Negative (`-`) can be applied to the axis, the length or both. Implementation thanks to @VorTechnix. + +```weacmd +//sshift back 4 +//sshift right -2 up 2 +//sshift -left 2 z -7 -y -4 +//sshift -z 12 -y -2 x -2 +``` + +### `//smake [ []]` +Short for _selection make_. Modifies existing selection by moving pos2. Allows you to make the selection an odd or even length on one or more axes or set two or more axes equal to each other or the longest, shortest or average of them. Implementation thanks to @VorTechnix. + +Usage examples: + +```weacmd +//smake odd shrink +//smake even avg xz +//smake equal grow xy +//smake equal average +//smake equal zy x +``` + +#### ``: odd|even|equal + +Value | Description +--------|--------------- +`odd` | Round up or down, based on mode, all axes specified in `` to the nearest odd length relative to pos1 +`even` | Round up or down, based on mode, all axes specified in `` to the nearest even length relative to pos1 +`equal` | Set `` axes length equal to the length of `` axis if specified or to the length of the largest, smallest or average of the `` axes based on mode. + +#### ``: grow|shrink|average + +#### *If `` == odd or even:* + +Value | Description +----------------|-------------- +`grow` | Grow each axis specified in `` to the nearest odd/even number to itself +`shrink` | Shrink each axis specified in `` to the nearest odd/even number to itself +`average`/`avg` | Takes the average of all axes specified in `` and then for each specified axis grows or shrinks it, depending on whether it is less than or greater than the average, to the nearest odd/even number to itself + +#### *If `` == equal:* +The `` argument can be omitted and will not be parsed if present if `` is specified + +Value | Description +----------------|--------------- +`grow` | Grow each axis specified in `` to the length of the longest specified axis +`shrink` | Shrink each axis specified in `` to the length of the shortest specified axis +`average`/`avg` | Set each axis specified in `` to the average length of all the specified axes +If `` | `` becomes optional. If present it will be ignored. + +#### Additional arguments: + +Name | Description +------------|------------------ +`` | Specify axes to perform operation on (default= xz)| +``: If `` == odd or even | Does nothing +``: If `` == equal | Overrides `` and sets all `` axes equal to itself + +### `//sfactor []` +#### === Deprecated === +Use `//sgrow` and `//sshrink` instead. + +### `//sstack` +Displays the contents of your per-user selection stack. This stack can be pushed to and popped from rather like a stack of plates. See also `//spush` (for pushing to the selection stack) and `//spop` (for popping from the selection stack). + +```weacmd +//sstack +``` + +### `//spush` +Pushes the currently defined region onto your per-user selection stack. Does not otherwise alter the defined region. + +If the stack is full (currently the limit is set to 100 regions in the stack), then it will complain at you but otherwise will have no effect. + +Note that pos2 does _not_ need to be defined in order to use this. if it isn't defined, then a pos2 of `nil` will be pushed onto the stack instead. + +```weacmd +//spush +``` + +### `//spop` +Pops a selection off your per-user selection stack and applies it to the currently defined region. If pos2 from the item popped from the stack is nil, then pos2 is explicitly unset. If the stack is empty, this has no effect. + +```weacmd +//spop +``` + + + +## Measurement + + + +### `//mcount` +Alias for [`//count`](#count). + +``` +//mcount +``` + + +### `//mface` +Returns the horizontal (X/Z) axis or axes the player is looking along. +Aliases: `//mfacing`. + +``` +//mface +``` + + +### `//midpos` +Returns the coordinates of the centre of the current selection. + +``` +//midpos +``` + + +### `//msize` +Returns the lengths of the current selection on the X, Y and Z axes. + +``` +//msize +``` + + +### `//mtrig` +Returns the length of the diagonal from pos1 to pos2 and its angle on the XZ (horizontal) and Y (vertical) axes. + +``` +//mtrig +``` + + + +## Meta + + + +### `//subdivide ` +Splits the current WorldEdit region into `(, , )` sized chunks, and run `// ` over each chunk. + +Sometimes, we want to run a single command on a truly vast area. Usually, this results in running out of memory. If this was you, then this command is just what you need! It should be able to handle any sized region - the only limit is your patience for command to complete..... + +Note that this command only works with WorldEdit commands, and only those which require 2 points (e.g. `//torus` only requires a single point, so it wouldn't work very well - but `//set` or `//clearcut` would). + +Note also that `` should _not_ be prefixed with _any_ forward slashes - see the examples below. + +While other server commands can be executed while a `//subdivide` is running, `//subdivide` manipulates your player's defined region when running. This has the side-effect that you can check on where it has got up to with `//p get` for example - but means that attempting to change your pos1 & pos2 manually will have no effect until the `//subdivide` completes. + +> [!WARNING] +> Once started, this command cannot be stopped without restarting your server! This is the case with all WorldEdit commands, but it's worth a special mention here. + +```weacmd +//subdivide 10 10 10 set dirt +//subdivide 25 25 25 fixlight +``` + + +### `//multi .....` +Executes multi chat commands in sequence. Intended for _WorldEdit_ commands, but does work with others too. Don't forget a space between commands! + +```weacmd +//multi //set dirt //shift x 10 //set glass +``` + +Since WorldEditAdditions v1.12, curly brace syntax has also been introduced to allow nesting of commands: + +```weacmd +//multi //fixlight {//many 5 //bonemeal 3 100} +``` + +This syntax can also be nested arbitrarily in arbitrarily complex combinations, and can also be used multiple separate times in a single `//multi` invocation (if you find a bug, please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new)), though do remember that only `//multi` supports parsing out this syntax (e.g. if you want to nest multiple commands in a `//many` that's inside a `//multi`, you'll need a sub `//multi` there). + +In addition, this also allows for including a double forward slash in the argument list for a command, should you need to do so (e.g. `//multi //example {//bar //baz} //example` will be executed as 3 commands: `/example`, then `/bar` with an argument of `//baz`, then finally `/example`). + +```weacmd +//multi //1 //2 //shift z -10 //sphere 5 sand //shift z 20 //ellipsoid 5 3 5 ice +//multi //1 //hollowtorus 30 5 stone //hollowtorus 20 3 dirt //torus 10 2 dirt_with_grass +//multi /time 7:00 //1 //outset h 20 //outset v 5 //overlay dirt_with_grass //1 //2 //sphere 8 air //shift down 1 //floodfill //reset +``` + + +### `//many ` +Executes a single chat command many times in a row. Uses `minetest.after()` to yield to the main server thread to allow other things to happen at the same time, so technically you could have multiple `//many` calls going at once (but multithreading support is out of reach, so only a single one will be executing at the same time). + +Note that this isn't necessarily limited to executing WorldEdit / WorldEditAdditions commands. Combine with `//multi` (see above) execute multiple commands at once for even more power and flexibility! + +```weacmd +//many 10 //bonemeal 3 100 +//many 100 //multi //1 //2 //outset 20 //set dirt +``` + + +### `//ellipsoidapply ` +Executes the given command, and then clips the result to the largest ellipsoid that will fit inside the defined region. The specified command must obviously take 2 positions - so for example `//set`, `//replacemix`, and `//maze3d` will work, but `//sphere`, `//torus`, and `//floodfill` won't. + +For advanced users, `//multi` is also supported - but make sure your modifications stay within the defined region - otherwise they will not be affected by the ellipsoidal clipping operation. + +```weacmd +//ellipsoidapply set dirt +//ellipsoidapply maze3d dirt 4 2 2 +//ellipsoidapply erode +//ellipsoidapply replacemix sand bakedclay:red bakedclay:orange +//ellipsoidapply layers desert_sand sand 2 desert_sandstone 4 sandstone 10 +``` + + +### `//airapply ` +Like [`//ellipsoidapply`](#ellipsoidapply), but instead only keeps changes that replace airlike nodes, and discards any other changes made. + +As with `//ellipsoidapply` for advanced users `//multi` is also supported - but make sure your modifications stay within the defined region - otherwise they be kept regardless, as `//airapply` only applies the masking to the nodes in the defined region. + +```weacmd +//airapply set sandstone +//airapply maze3d dirt 4 2 2 +``` + + +### `//nodeapply [] [... ] -- ` +**Aliases:** `//napply` + +It's got `apply` in the name, so as you might imagine it works the same as [`//ellipsoidapply`](#ellipsoidapply), [`//airapply`](#airapply), [`//noiseapply2d`](#noiseapply2d), etc. Only changes made by the given command that replace nodes on the list given will be replaced. For example: + +```weacmd +//nodeapply dirt -- set stone +``` + +....is equivalent to `//replace dirt stone`, in that although `//set stone` will set all nodes to stone, `//nodeapply` will only keep the changes made by `//set` that affect dirt. + +There are some special keywords you can use too: + +Keyword | Meaning +----------------|----------------------------------- +`liquidlike` | Targets all nodes that behave like a liquid. +`airlike` | Targets all nodes that behave like air. Basically like [`//airapply`](#airapply). + +To give a further example, consider this: + +```weacmd +//nodeapply liquidlike -- set river_water_source +``` + +...this will replace all liquid-like nodes (e.g. water, lava, etc) with river water. + +In addition, any node names prefixed an at sign `@` are considered group names. For example: `@crumbly` would allow changes only to nodes that are a member of the `crumbly` group: + +```weacmd +//nodeapply @crumbly -- layers dirt_with_grass dirt 3 stone 10 +``` + +More misc examples to end this command description, as is customary: + +```weacmd +//nodeapply stone -- layers dirt_with_grass dirt 3 +//nodeapply stone dirt sand -- layers bakedclay:natural 3 bakedclay:orange 2 bakedclay:red 3 bakedclay:natural 3 +//nodeapply liquidlike -- set air +//nodeapply airlike -- mix stone 3 dirt 2 +``` + + +### `//noiseapply2d ` +Like [`//ellipsoidapply`](#ellipsoidapply), but instead only keeps changes where a noise function (defaults to `perlinmt`, see [`//noise2d`](#noise2d)) returns a value greater than a given threshold value. + +Also takes a scale value that controls the scale of the noise - -higher values result in smaller "blobs". If you're operating on small areas, then a value of at least 10 is advised as "blobs" are by default on the scale of ~50 nodes. + +As with `//ellipsoidapply` for advanced users `//multi` is also supported - but make sure your modifications stay within the defined region - otherwise they be kept regardless, as `//noiseapply2d` only applies the masking to the nodes in the defined region. + +Any suggestions on how to provide more customisability without making this command more difficult to use or significantly more inconsistent with other `//*apply` functions are welcome - please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new). + +```weacmd +//noiseapply2d 0.5 10 set dirt +//noiseapply2d 0.4 3 layers dirt_with_snow dirt 3 stone 10 +``` + +### `//for ... do // %% ` +For a given list of values, executes the specified command for each value, replacing `%%` with each value. Implementation thanks to @VorTechnix. + +To better illustrate what happens, consider the following command: + +``` +//for dirt stone glass do //replacemix air 10 %% +``` + +This is equivalent to executing the following 3 commands in sequence: + +``` +//replacemix air 10 dirt +//replacemix air 10 stone +//replacemix air 10 glass +``` + +Here are some more examples: + +``` +//for meselamp brick snowblock bamboo:wood do //multi //maze %% //sshift y 5 +//for 5 10 15 do //torus %% 3 dirt xz +//for 1 2 3 4 5 do //multi //hollowcylinder y 1 5 meselamp //shift y %% +``` + + +### `//listentities` +Lists all currently loaded ObjectRefs. Displays their IDs, Names (if possible), and positions. + +This command is intended for development and modding. You will not normally need to use this command using WorldEditAdditions. + +`//listentities` takes no arguments. + +``` +//listentities +``` + + +## Extras + + + +### `//speed []` +Adjusts your player movement speed to the specified value. In other words: + +```weacmd +//speed 2 +``` + +...will double your movement speed. + +This command also takes Minetest's "Fast mode" into account and adjusts accordingly. Relative adjustments can be done by prepending either a `+` to increase or `-` to decrease respectively. + +```weacmd +//speed +0.5 +//speed -3 +``` + + +### `//y` +Confirms the execution of a command if it could potentially affect a large number of nodes and take a while. This is a regular WorldEdit command. + + + +```weacmd +//y +``` + + +### `//n` +Prevents the execution of a command if it could potentially affect a large number of nodes and take a while. This is a regular WorldEdit command. + + + +```weacmd +//n +``` + + + +## Tools + + +### Movement speed adjustment tool +The movement speed adjustment tool, as the name suggests, adjusts your local player movement speed. It looks like this: ![A picture of the move speed adjustment tool. It looks like a monarch butterfly.](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/dev/worldeditadditions_farwand/textures/worldeditadditions_movement.png). + +Primary (left) clicking will increase your movement speed, and secondary (right) clicking will decrease it in x0.5 increments, down to a minimum of x0.5. + +Note this only affects **you**, and **not any other player**. + +See also [`//speed`](#speed). + +### Far Wand +The far wand (`worldeditadditions:farwand`) is a variant on the traditional WorldEdit wand (`worldedit:wand`). It looks like this: ![A picture of the far wand](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/worldeditadditions_farwand/textures/worldeditadditions_farwand.png) + +It functions very similarly to the regular WorldEdit wand, except that it has a _much_ longer range - which can be very useful for working on large-scale terrain for example. It also comes with an associated command to control it. + +Note that punching out the positions **does not unset them**. Use `//reset` to reset the defined region. + +### `//farwand skip_liquid (true|false) | maxdist ` +This command helps control the behaviour of the [WorldEditAdditions far wand](#far-wand) and [cloud wand](#cloud-wand). Calling it without any arguments shows the current status: + +```weacmd +//farwand +``` + +You can decide whether you can select liquids or not like so: + +```weacmd +//farwand skip_liquid true +//farwand skip_liquid false +``` + +You can change the maximum range with the `maxdist` subcommand: + +```weacmd +//farwand maxdist 1000 +//farwand maxdist 200 +//farwand maxdist 9999 +``` + +Note that the number there isn't in blocks (because hard maths). It is however proportional to the distance the wand will raycast looks for nodes, so a higher value will result in it raycasting further. + +### Cloud Wand +The cloud wand (`worldeditadditions:cloudwand`) is a another variant the above _Far Wand_. It looks like this: ![A picture of the far wand](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/worldeditadditions_farwand/textures/worldeditadditions_cloudwand.png) + +Unlike the other 2 wands, this wand functions in an additive manner. Left-click on a node to expand the currently defined region (creating a new one if one isn't defined already) to include that node. Right click to clear the currently defined region. + +It has the range of the _Far Wand_ mentioned above too, so you can select nodes from a great distance. It also abides by preferences set via the `//farwand` chat command. + +Note that punching out the positions **does not unset them**. Use `//reset` to reset the defined region. + + +### MultiPoint Wand +The third type of wand provided by WorldEditAdditions is completely different, in that it allows you to select up to **999 points** at once! It looks like this: ![A picture of the multi-point wand](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/worldeditadditions_farwand/textures/worldeditadditions_multiwand.png) + +It is important to note that (at present) the points selected by this wand **are not compatible with normal points**. This will change in the future, but requires a lot of work to implement. + +It has the following actions: + + - **Left click:** Add a new point + - **Right click:** Undo adding a point + +It has the range of the other wands mentioned above though, so you can select nodes from a great distance. It also abides by preferences set via the `//farwand` chat command. From a31e34f420c5697fab745efdec014a91ae53afaa Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Tue, 17 Sep 2024 12:30:21 -0700 Subject: [PATCH 16/35] sfactor deprecation --- .../commands/selectors/sfactor.lua | 109 ++++-------------- 1 file changed, 22 insertions(+), 87 deletions(-) diff --git a/worldeditadditions_commands/commands/selectors/sfactor.lua b/worldeditadditions_commands/commands/selectors/sfactor.lua index 4c86408..0babcc1 100644 --- a/worldeditadditions_commands/commands/selectors/sfactor.lua +++ b/worldeditadditions_commands/commands/selectors/sfactor.lua @@ -1,87 +1,22 @@ -local wea = worldeditadditions -local wea_c = worldeditadditions_core -local Vector3 = wea_c.Vector3 - - --- ███████ ███████ █████ ██████ ████████ ██████ ██████ --- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ --- ███████ █████ ███████ ██ ██ ██ ██ ██████ --- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ --- ███████ ██ ██ ██ ██████ ██ ██████ ██ ██ -worldeditadditions_core.register_command("sfactor", { - params = " []", - description = "Make the length of one or more target axes of the current selection to be multiple(s) of .", - privs = { worldedit = true }, - require_pos = 2, - parse = function(params_text) - local parts = wea_c.split(params_text, "%s+", false) - - if #parts < 2 then - return false, "Error: Not enough arguments. Expected \" []\"." - end - local mode, fac, targ = wea_c.table.unpack(parts) - local modeSet = wea_c.table.makeset {"grow", "shrink", "avg"} - - -- Mode parsing - if mode == "average" then -- If mode is average set to avg - mode = "avg" - elseif not modeSet[mode] then -- If mode is invalid throw error - return false, "Error: Invalid \""..mode.."\". Expected \"grow\", \"shrink\", or \"average\"/\"avg\"." - end - - -- Factor parsing - local factest = tonumber(fac) - if not factest then - return false, "Error: Invalid \""..fac.."\". Expected a number." - elseif factest < 2 then - return false, "Error: is too low. Expected a number equal to or greater than 2." - else - fac = math.floor(factest+0.5) - end - - -- Target parsing - if not targ then -- If no target set to default (xz) - targ = "xz" - elseif targ:match("[xyz]+") then -- ensure correct target syntax - targ = table.concat(wea_c.tochars(targ:match("[xyz]+"),true,true)) - else - return false, "Error: Invalid \""..targ.."\". Expected \"x\" and or \"y\" and or \"z\"." - end - - return true, mode, fac, targ - end, - func = function(name, mode, fac, targ) - local pos1, pos2 = Vector3.clone(worldedit.pos1[name]), Vector3.clone(worldedit.pos2[name]) - local delta = pos2 - pos1 -- local delta equation: Vd(a) = V2(a) - V1(a) - local _tl = #targ -- Get targ length as a variable incase mode is "average"/"avg" - local targ = wea_c.tocharset(targ) -- Break up targ string into set table - local _m = 0 -- _m is the container to hold the average of the axes in targ - - -- set _m to the max, min or mean of the target axes depending on mode (_tl is the length of targ) or base if it exists - if mode == "avg" then - for k,v in pairs(targ) do _m = _m + math.abs(delta[k]) end - _m = _m / _tl - end - - -- Equation: round(delta[] / factor) * factor - local eval = function(int,fac_inner) - local tmp, abs, neg = int / fac_inner, math.abs(int), int < 0 - - if mode == "avg" then - if int > _m then int = math.floor(abs / fac_inner) * fac_inner - else int = math.ceil(abs / fac_inner) * fac_inner end - elseif mode == "shrink" then int = math.floor(abs / fac_inner) * fac_inner - else int = math.ceil(abs / fac_inner) * fac_inner end - - if int < fac_inner then int = fac_inner end -- Ensure selection doesn't collapse to 0 - if neg then int = int * -1 end -- Ensure correct facing direction - return int - end - - for k,v in pairs(targ) do delta[k] = eval(delta[k],fac) end - - worldedit.pos2[name] = pos1 + delta - worldedit.mark_pos2(name) - return true, "position 2 set to "..pos2 - end -}) +local wea = worldeditadditions +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 + + +-- ███████ ███████ █████ ██████ ████████ ██████ ██████ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ███████ █████ ███████ ██ ██ ██ ██ ██████ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ███████ ██ ██ ██ ██████ ██ ██████ ██ ██ +worldeditadditions_core.register_command("sfactor", { + params = "None", + description = "Deprecated.", + privs = { worldedit = true }, + require_pos = 1, + parse = function(params_text) + return params_text + end, + func = function(name, paramtext) + return false, "DEPRECATED: please use //grow or //shrink instead..." + end +}) From 1a18d4c8d0b66d7916ad993f6263c390cfd8ea80 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Tue, 17 Sep 2024 12:31:02 -0700 Subject: [PATCH 17/35] params modification for UAK --- worldeditadditions_commands/commands/selectors/sgrow.lua | 2 +- worldeditadditions_commands/commands/selectors/srel.lua | 2 +- worldeditadditions_commands/commands/selectors/sshift.lua | 2 +- worldeditadditions_commands/commands/selectors/sshrink.lua | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/worldeditadditions_commands/commands/selectors/sgrow.lua b/worldeditadditions_commands/commands/selectors/sgrow.lua index 7cd48db..01a459c 100644 --- a/worldeditadditions_commands/commands/selectors/sgrow.lua +++ b/worldeditadditions_commands/commands/selectors/sgrow.lua @@ -11,7 +11,7 @@ local Vector3 = wea_c.Vector3 worldeditadditions_core.register_command("sgrow", { - params = "[] [[] [...]]", + params = "", description = "Grow selection region", privs = { worldedit = true }, require_pos = 0, diff --git a/worldeditadditions_commands/commands/selectors/srel.lua b/worldeditadditions_commands/commands/selectors/srel.lua index de2e176..7e99a2f 100644 --- a/worldeditadditions_commands/commands/selectors/srel.lua +++ b/worldeditadditions_commands/commands/selectors/srel.lua @@ -11,7 +11,7 @@ local Vector3 = wea_c.Vector3 worldeditadditions_core.register_command("srel", { - params = "[] [[] [...]]", + params = "", description = "Set WorldEdit region position 2 relative to position 1 and player facing.", privs = { worldedit = true }, require_pos = 0, diff --git a/worldeditadditions_commands/commands/selectors/sshift.lua b/worldeditadditions_commands/commands/selectors/sshift.lua index e3894e2..732ddd5 100644 --- a/worldeditadditions_commands/commands/selectors/sshift.lua +++ b/worldeditadditions_commands/commands/selectors/sshift.lua @@ -8,7 +8,7 @@ local Vector3 = worldeditadditions.Vector3 -- ███████ ███████ ██ ██ ██ ██ ██ worldeditadditions_core.register_command("sshift", { - params = "[] [[] [...]]", + params = "", description = "Shift the WorldEdit region in 3 dimensions.", privs = { worldedit = true }, require_pos = 2, diff --git a/worldeditadditions_commands/commands/selectors/sshrink.lua b/worldeditadditions_commands/commands/selectors/sshrink.lua index 923faa9..acb4de7 100644 --- a/worldeditadditions_commands/commands/selectors/sshrink.lua +++ b/worldeditadditions_commands/commands/selectors/sshrink.lua @@ -11,7 +11,7 @@ local Vector3 = wea_c.Vector3 worldeditadditions_core.register_command("sshrink", { - params = "[] [[] [...]]", + params = "", description = "Shrink selection region", privs = { worldedit = true }, require_pos = 0, From aaa976c2868a6f1202a73ec63e337d2a83b82412 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Tue, 17 Sep 2024 12:31:13 -0700 Subject: [PATCH 18/35] aliasing --- worldeditadditions_commands/commands/selectors/init.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/worldeditadditions_commands/commands/selectors/init.lua b/worldeditadditions_commands/commands/selectors/init.lua index d1dc356..9ff65c0 100644 --- a/worldeditadditions_commands/commands/selectors/init.lua +++ b/worldeditadditions_commands/commands/selectors/init.lua @@ -36,5 +36,12 @@ dofile(wea_cmdpath.."reset.lua") -- Aliases weac.register_alias("sfac", "sfactor") +weac.register_alias("sgrow", "expand", true) -- true = override target +weac.register_alias("sgrow", "outset", true) -- true = override target +weac.register_alias("sshrink", "contract", true) -- true = override target +weac.register_alias("sshrink", "inset", true) -- true = override target + +weac.register_alias("sshift", "shift", true) -- true = override target + weac.register_alias("1", "pos1", true) -- true = override target weac.register_alias("2", "pos2", true) -- true = override target From 753ead210249f10b27a34c32a9308d8a91be1d63 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Tue, 17 Sep 2024 14:10:02 -0700 Subject: [PATCH 19/35] UAK to UAS --- CHANGELOG.md | 12 ++++++------ Chat-Command-Reference.md | 15 ++++++--------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b40630..93c1e68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ It's about time I started a changelog! This will serve from now on as the main c Note to self: See the bottom of this file for the release template text. -## v1.15: The deprecation update (unreleased) +## v1.15: The direction update (unreleased) - Added the optional argument `all` to [`//unmark`](https://worldeditadditions.mooncarrot.space/Reference/#unmark) - Added a (rather nuclear) fix (attempt 4) at finally exterminating all zombie region marker walls forever - This is not a hotfix to avoid endless small releases fixing the bug, as it's clear it's much more difficult to fix on all systems than initially expected @@ -16,19 +16,19 @@ Note to self: See the bottom of this file for the release template text. - Added [`//set+`](https://worldeditadditions.mooncarrot.space/Reference/#set) for setting nodes and param2/light levels quickly. - NOTE TO SELF: Setting light values doesn't appear to be working very well for some reason - Added [`//ndef`](https://worldeditadditions.mooncarrot.space/Reference/#ndef) to print a given node's definition table. This is for debugging and development purposes. -- Added `//sgrow` and `//sshrink` and aliased them over WorldEdit equivalents (`//expand`, `//outset` and `//contract`, `//inset` respectively). -- Added Universal Axis Keyword (UAK) System parser. - Implementation by @VorTechnix - - See [UAK System reference] for details. (Note to self hook up hyperlink) +- Added `//sgrow` and `//sshrink` commands to enlarge and shrink selection regions and aliased them over WorldEdit equivalents (`//expand`, `//outset` and `//contract`, `//inset` respectively). +- Added Unified Axis Syntax (UAS) parser. - Implementation by @VorTechnix + - See [UAS System reference] for details. (Note to self hook up hyperlink) ### Bugfixes and changes - Don't warn on failed registration of `//flora` → [`//bonemeal`](https://worldeditadditions.mooncarrot.space/Reference/#bonemeal) if the `bonemeal` mod isn't installed (e.g. in MineClone2) - thanks @VorTechnix in #106 - Improve documentation of [`//noise2d`](https://worldeditadditions.mooncarrot.space/Reference/#noise2d). If it still doesn't make sense, please let me know. It's a complicated command that needs reworking a bit to be easier to use. - Alias `//napply` to [`//nodeapply`](https://worldeditadditions.mooncarrot.space/Reference/#nodeapply) -- Re-factored selection tools to all use WEA position system and UAK Parser if applicable. - Re-factor by @VorTechnix +- Re-factored selection tools to all use WEA position system and UAS Parser if applicable. - Re-factor by @VorTechnix - `//sshift` now overrides `//shift` from WorldEdit. - Re-factor by @VorTechnix ### Deprecations -- Deprecated `//scol`, `//srect` and `//scube`. Now that `//srel` is using UAK parser there is no need for them. - Deprecated by @VorTechnix +- Deprecated `//scol`, `//srect` and `//scube`. Now that `//srel` is using UAS parser there is no need for them. - Deprecated by @VorTechnix - Deprecated `//sfactor`. Now that `//sgrow` and `//sshrink` exist it is no longer needed. - Deprecated by @VorTechnix diff --git a/Chat-Command-Reference.md b/Chat-Command-Reference.md index 1aa4716..d3d9c88 100644 --- a/Chat-Command-Reference.md +++ b/Chat-Command-Reference.md @@ -1129,8 +1129,8 @@ This command is intended for debugging and development purposes, but if you're i ███████ ███████ ███████ ███████ ██████ ██ ██ ██████ ██ ████ --> -### Unified Axis Keyword (UAK) System -The Unified Axis Keyword (UAK) System is an attempt to allow users to input direction and distance information in three dimensions using "natural" language. The key features include axis clumping, double negatives, relative directions, mirroring and compass directions (more information below). +### Unified Axis Syntax (UAS) +The Unified Axis Syntax system allows users to input direction and distance information in three dimensions using "natural" language. The key features include axis clumping, double negatives, relative directions, mirroring and compass directions (more information below). *Note: negatives can be applied to axes, directions **AND** distances* @@ -1185,9 +1185,6 @@ From the above examples you can also see the principle of inference. All directi Because UAK attempts to parse "natural" language, there are many ways to express the same direction and distance. This caters to users with different ways of thinking and different play styles which will hopefully make the tools easier to use. ---- ---- - ### `//unmark` Hides the in-game UI that indicates where the current positions and region are located. @@ -1291,7 +1288,7 @@ Short for _select center_. Sets pos1 and pos2 to the centre point(s) of the curr //scentre ``` -### `//srel ` +### `//srel ` Short for _select relative_. Sets the pos2 at set distances along 3 axes relative to pos1. If pos1 is not set it will default to the node directly under the player. The axis arguments accept `x, y, z` as well as `up, down, left, right, front, back`. Left, right, front and back are relative to player facing direction. Negative (`-`) can be applied to the axis, the length or both. Implementation thanks to @VorTechnix. ```weacmd @@ -1301,7 +1298,7 @@ Short for _select relative_. Sets the pos2 at set distances along 3 axes relativ //srel -z 12 -y -2 x -2 ``` -### `//sgrow ` +### `//sgrow ` Short for _selection grow_. Grows the current selection along specified axes/directions. Aliases: `//extend`, `//outset`. @@ -1312,7 +1309,7 @@ Aliases: `//extend`, `//outset`. //sgrow -zy -2 x -2 ``` -### `//sshrink ` +### `//sshrink ` Short for _selection shrink_. Shrinks the current selection along specified axes/directions. Aliases: `//contract`, `//inset`. @@ -1323,7 +1320,7 @@ Aliases: `//contract`, `//inset`. //sshrink -hy 2 x -3 true ``` -### `//sshift ` +### `//sshift ` Short for _selection shift_. Shifts the WorldEdit region along 3 axes. The axis arguments accept `x, y, z` as well as `up, down, left, right, front, back`. Left, right, front and back are relative to player facing direction. Negative (`-`) can be applied to the axis, the length or both. Implementation thanks to @VorTechnix. ```weacmd From ea25e36f3cd57e2b0b2a99a063a51e7673c53929 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Tue, 17 Sep 2024 16:19:05 -0700 Subject: [PATCH 20/35] doc updates --- Chat-Command-Reference.md | 40 ++++++++++++++++++--------------------- README.md | 14 ++++++++------ 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/Chat-Command-Reference.md b/Chat-Command-Reference.md index d3d9c88..6ae04c8 100644 --- a/Chat-Command-Reference.md +++ b/Chat-Command-Reference.md @@ -1130,17 +1130,17 @@ This command is intended for debugging and development purposes, but if you're i --> ### Unified Axis Syntax (UAS) -The Unified Axis Syntax system allows users to input direction and distance information in three dimensions using "natural" language. The key features include axis clumping, double negatives, relative directions, mirroring and compass directions (more information below). +The Unified Axis Syntax system allows users to input direction and distance information in three dimensions using "natural" measurement syntax. The key features include axis clumping, double negatives, relative directions, mirroring and compass directions (more information below). *Note: negatives can be applied to axes, directions **AND** distances* #### Relative Directions |Key Words | Interpretation| |----------|---------------| -|f[ront]\|facing\|? | The direction the player is facing most toward in the world -|b[ack]\|behind\|rear | The opposite of the direction the player is facing most toward in the world -|l[eft] | The direction to the left of the player -|r[ight] | The direction to the right of the player +|`f[ront]\|facing\|?` | The direction the player is facing most toward in the world +|`b[ack]\|behind\|rear` | The opposite of the direction the player is facing most toward in the world +|`l[eft]` | The direction to the left of the player +|`r[ight]` | The direction to the right of the player ```weacmd back 1 @@ -1151,12 +1151,12 @@ f r 4 #### Compass Directions |Key Words | Interpretation| |----------|---------------| -|n[orth] | z -|s[outh] | -z -|e[ast] | x -|w[est] | -x -|u[p] | y -|d[own] | -y +|`n[orth]` | z +|`s[outh]` | -z +|`e[ast]` | x +|`w[est]` | -x +|`u[p]` | y +|`d[own]` | -y ```weacmd south 3 @@ -1167,23 +1167,19 @@ e d -2 #### Axis Clumping Supported axes are `x`, `y`, `z`, `h`, `v`. All horizontal axes are covered by `h` and both vertical ones are covered by `v`. -```weacmd -h 5 == xz -xz 5 == x 5 z 5 x -5 z -5 -v 5 == up down 5 == y -y 5 -vxz 5 == xyz -y 5 == xyz 5 y -5 -``` +- `h 5` == `xz -xz 5` == `x 5 z 5 x -5 z -5` +- `v 5` == `up down 5` == `y -y 5` +- `vxz 5` == `xyz -y 5` == `xyz 5 y -5` #### Inference and Omnidirectionality -The UAK parser takes command input that is split by whitespace and interprets it as a series of values preceded by directional cues. If a number is preceded by another number or nothing it assumes that the number is to be applied on all axes in both positive and negative directions. +The UAS parser takes command input that is split by whitespace and interprets it as a series of numbers preceded by directional cues. If a number is preceded by another number or nothing it assumes that the number is to be applied on all axes in both positive and negative directions. -```weacmd -10 == hv 10 == xyz -xyz 10 -x 3 6 == x 3 hv 6 -``` +- `10` == `hv 10` == `xyz -xyz 10` +- `x 3 6` == `x 3 hv 6` From the above examples you can also see the principle of inference. All direction modifiers before a value are interpreted as belonging to that value. So `x v 5` is equivalent to `x 5 v 5` and `xv 5`. -Because UAK attempts to parse "natural" language, there are many ways to express the same direction and distance. This caters to users with different ways of thinking and different play styles which will hopefully make the tools easier to use. +Because UAS parses "natural" measurement syntax, there are many ways to express the same direction and distance. This caters to users with different ways of thinking and different play styles which will hopefully make the tools easier to use. ### `//unmark` Hides the in-game UI that indicates where the current positions and region are located. diff --git a/README.md b/README.md index 992fb54..5c03eda 100644 --- a/README.md +++ b/README.md @@ -75,18 +75,20 @@ The detailed explanations have moved! Check them out [here](https://worldeditadd - [`//ngroups [v[erbose]]`](https://worldeditadditions.mooncarrot.space/Reference/#ngroups) ### Selection - - [`//scol [ ] `](https://worldeditadditions.mooncarrot.space/Reference/#scol) - - [`//srect [ []] `](https://worldeditadditions.mooncarrot.space/Reference/#srect) - - [`//scube [ [ []]] `](https://worldeditadditions.mooncarrot.space/Reference/#scube) + - [~~`//scol`~~ DEPRECATED](https://worldeditadditions.mooncarrot.space/Reference/#scol) + - [~~`//srect`~~ DEPRECATED](https://worldeditadditions.mooncarrot.space/Reference/#srect) + - [~~`//scube`~~ DEPRECATED](https://worldeditadditions.mooncarrot.space/Reference/#scube) - [`//scloud <0-6|stop|reset>`](https://worldeditadditions.mooncarrot.space/Reference/#scloud) - [`//scentre`](https://worldeditadditions.mooncarrot.space/Reference/#scentre) - - [`//srel [ [ ]]`](https://worldeditadditions.mooncarrot.space/Reference/#srel) + - [`//sgrow `](https://worldeditadditions.mooncarrot.space/Reference/#sgrow) + - [`//srel `](https://worldeditadditions.mooncarrot.space/Reference/#srel) - [`//smake [ []]`](https://worldeditadditions.mooncarrot.space/Reference/#smake) + - [`//sshrink `](https://worldeditadditions.mooncarrot.space/Reference/#sshrink) - [`//sstack`](https://worldeditadditions.mooncarrot.space/Reference/#sstack) - [`//spush`](https://worldeditadditions.mooncarrot.space/Reference/#spush) - [`//spop`](https://worldeditadditions.mooncarrot.space/Reference/#spop) - - [`//sshift [ [ ]]`](https://worldeditadditions.mooncarrot.space/Reference/#sshift) - - [`//sfactor []`](https://worldeditadditions.mooncarrot.space/Reference/#sfactor) + - [`//sshift `](https://worldeditadditions.mooncarrot.space/Reference/#sshift) + - [~~`//sfactor`~~ DEPRECATED](https://worldeditadditions.mooncarrot.space/Reference/#sfactor) - [`//pos `](https://worldeditadditions.mooncarrot.space/Reference/#pos) - [`//pos1`](https://worldeditadditions.mooncarrot.space/Reference/#pos1) - [`//pos2`](https://worldeditadditions.mooncarrot.space/Reference/#pos2) From 90f2fcb2abf6a58eb94b49f0535969ac6c245923 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Wed, 18 Sep 2024 21:00:51 -0700 Subject: [PATCH 21/35] added UAS Parse --- CHANGELOG.md | 1 + Chat-Command-Reference.md | 10 +++++++ README.md | 5 ++-- .../commands/uasparse.lua | 29 +++++++++++++++++++ 4 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 worldeditadditions_commands/commands/uasparse.lua diff --git a/CHANGELOG.md b/CHANGELOG.md index 93c1e68..b134f09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Note to self: See the bottom of this file for the release template text. - Added `//sgrow` and `//sshrink` commands to enlarge and shrink selection regions and aliased them over WorldEdit equivalents (`//expand`, `//outset` and `//contract`, `//inset` respectively). - Added Unified Axis Syntax (UAS) parser. - Implementation by @VorTechnix - See [UAS System reference] for details. (Note to self hook up hyperlink) +- Added `//uasparse` command to show the vectors produced by a given UAS expression. - Implementation by @VorTechnix ### Bugfixes and changes - Don't warn on failed registration of `//flora` → [`//bonemeal`](https://worldeditadditions.mooncarrot.space/Reference/#bonemeal) if the `bonemeal` mod isn't installed (e.g. in MineClone2) - thanks @VorTechnix in #106 diff --git a/Chat-Command-Reference.md b/Chat-Command-Reference.md index 6ae04c8..d6cffde 100644 --- a/Chat-Command-Reference.md +++ b/Chat-Command-Reference.md @@ -1118,6 +1118,16 @@ This command is intended for debugging and development purposes, but if you're i //ndef glass ``` +### `//uasparse ` +Short for *Unified Axis Syntax Parse*. Parses the given UAS expression and prints the resulting vectors to the chat window. + +```weacmd +//uasparse front right 5 +//uasparse y 12 h -2 +//uasparse left 3 up 5 -front 7 +//uasparse -z 12 -y -2 x -2 +``` + ## Selection diff --git a/README.md b/README.md index 5c03eda..71287e4 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ The detailed explanations have moved! Check them out [here](https://worldeditadd - [`//count`](https://worldeditadditions.mooncarrot.space/Reference/#count) - [`//basename `](https://worldeditadditions.mooncarrot.space/Reference/#basename) - [`//ngroups [v[erbose]]`](https://worldeditadditions.mooncarrot.space/Reference/#ngroups) + - [`//uasparse `](https://worldeditadditions.mooncarrot.space/Reference/#uasparse) _(new in v1.15)_ ### Selection - [~~`//scol`~~ DEPRECATED](https://worldeditadditions.mooncarrot.space/Reference/#scol) @@ -80,10 +81,10 @@ The detailed explanations have moved! Check them out [here](https://worldeditadd - [~~`//scube`~~ DEPRECATED](https://worldeditadditions.mooncarrot.space/Reference/#scube) - [`//scloud <0-6|stop|reset>`](https://worldeditadditions.mooncarrot.space/Reference/#scloud) - [`//scentre`](https://worldeditadditions.mooncarrot.space/Reference/#scentre) - - [`//sgrow `](https://worldeditadditions.mooncarrot.space/Reference/#sgrow) + - [`//sgrow `](https://worldeditadditions.mooncarrot.space/Reference/#sgrow) _(new in v1.15)_ - [`//srel `](https://worldeditadditions.mooncarrot.space/Reference/#srel) - [`//smake [ []]`](https://worldeditadditions.mooncarrot.space/Reference/#smake) - - [`//sshrink `](https://worldeditadditions.mooncarrot.space/Reference/#sshrink) + - [`//sshrink `](https://worldeditadditions.mooncarrot.space/Reference/#sshrink) _(new in v1.15)_ - [`//sstack`](https://worldeditadditions.mooncarrot.space/Reference/#sstack) - [`//spush`](https://worldeditadditions.mooncarrot.space/Reference/#spush) - [`//spop`](https://worldeditadditions.mooncarrot.space/Reference/#spop) diff --git a/worldeditadditions_commands/commands/uasparse.lua b/worldeditadditions_commands/commands/uasparse.lua new file mode 100644 index 0000000..44f0015 --- /dev/null +++ b/worldeditadditions_commands/commands/uasparse.lua @@ -0,0 +1,29 @@ +local wea_c = worldeditadditions_core +-- local Vector3 = wea_c.Vector3 + +-- ██ ██ █████ ███████ ██████ █████ ██████ ███████ ███████ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ██ ██ ███████ ███████ ██████ ███████ ██████ ███████ █████ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ██████ ██ ██ ███████ ██ ██ ██ ██ ██ ███████ ███████ + +worldeditadditions_core.register_command("uasparse", { + params = "", + description = "Returns min and max vectors for given inputs", + privs = { worldedit = true }, + -- require_pos = 2, + parse = function(params_text) + local ret = wea_c.split(params_text) + if #ret < 1 then return false, "UASPARSE: No params found!" + else return true, ret end + end, + func = function(name, params_text) + local facing = wea_c.player_dir(name) + local min, max = wea_c.parse.directions(params_text, facing) + if not min then + return false, max + else + return true, "Min: "..min.." Max: "..max + end + end +}) From d635bec9f3598b45f8e720c926fd59a91086c38d Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Wed, 18 Sep 2024 21:01:30 -0700 Subject: [PATCH 22/35] params fix --- worldeditadditions_commands/commands/selectors/sgrow.lua | 2 +- worldeditadditions_commands/commands/selectors/srel.lua | 2 +- worldeditadditions_commands/commands/selectors/sshift.lua | 2 +- worldeditadditions_commands/commands/selectors/sshrink.lua | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/worldeditadditions_commands/commands/selectors/sgrow.lua b/worldeditadditions_commands/commands/selectors/sgrow.lua index 01a459c..bf50e80 100644 --- a/worldeditadditions_commands/commands/selectors/sgrow.lua +++ b/worldeditadditions_commands/commands/selectors/sgrow.lua @@ -11,7 +11,7 @@ local Vector3 = wea_c.Vector3 worldeditadditions_core.register_command("sgrow", { - params = "", + params = "", description = "Grow selection region", privs = { worldedit = true }, require_pos = 0, diff --git a/worldeditadditions_commands/commands/selectors/srel.lua b/worldeditadditions_commands/commands/selectors/srel.lua index 7e99a2f..1d577c0 100644 --- a/worldeditadditions_commands/commands/selectors/srel.lua +++ b/worldeditadditions_commands/commands/selectors/srel.lua @@ -11,7 +11,7 @@ local Vector3 = wea_c.Vector3 worldeditadditions_core.register_command("srel", { - params = "", + params = "", description = "Set WorldEdit region position 2 relative to position 1 and player facing.", privs = { worldedit = true }, require_pos = 0, diff --git a/worldeditadditions_commands/commands/selectors/sshift.lua b/worldeditadditions_commands/commands/selectors/sshift.lua index 732ddd5..74d39ce 100644 --- a/worldeditadditions_commands/commands/selectors/sshift.lua +++ b/worldeditadditions_commands/commands/selectors/sshift.lua @@ -8,7 +8,7 @@ local Vector3 = worldeditadditions.Vector3 -- ███████ ███████ ██ ██ ██ ██ ██ worldeditadditions_core.register_command("sshift", { - params = "", + params = "", description = "Shift the WorldEdit region in 3 dimensions.", privs = { worldedit = true }, require_pos = 2, diff --git a/worldeditadditions_commands/commands/selectors/sshrink.lua b/worldeditadditions_commands/commands/selectors/sshrink.lua index acb4de7..560578b 100644 --- a/worldeditadditions_commands/commands/selectors/sshrink.lua +++ b/worldeditadditions_commands/commands/selectors/sshrink.lua @@ -11,7 +11,7 @@ local Vector3 = wea_c.Vector3 worldeditadditions_core.register_command("sshrink", { - params = "", + params = "", description = "Shrink selection region", privs = { worldedit = true }, require_pos = 0, From d6c452a221dd571db96172cb5c2a1012040da9ec Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Wed, 18 Sep 2024 21:01:46 -0700 Subject: [PATCH 23/35] hooked up UAS Parse --- worldeditadditions_commands/init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/worldeditadditions_commands/init.lua b/worldeditadditions_commands/init.lua index c9b2095..d0a9273 100644 --- a/worldeditadditions_commands/init.lua +++ b/worldeditadditions_commands/init.lua @@ -41,6 +41,7 @@ dofile(wea_cmd.modpath.."/commands/revolve.lua") dofile(wea_cmd.modpath.."/commands/rotate.lua") dofile(wea_cmd.modpath.."/commands/orient.lua") dofile(wea_cmd.modpath.."/commands/set.lua") +dofile(wea_cmd.modpath.."/commands/uasparse.lua") -- Meta Commands dofile(wea_cmd.modpath .. "/commands/meta/init.lua") From 61bfab240a24f0f356c5f2872ca5af92b207408d Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Wed, 18 Sep 2024 21:25:42 -0700 Subject: [PATCH 24/35] axes parser re-refactor tests passed --- .tests/parse/axes/axes_parser.test.lua | 9 +++ .../utils/parse/axes_parser.lua | 80 +++++++++---------- 2 files changed, 49 insertions(+), 40 deletions(-) diff --git a/.tests/parse/axes/axes_parser.test.lua b/.tests/parse/axes/axes_parser.test.lua index 00546cd..a698438 100644 --- a/.tests/parse/axes/axes_parser.test.lua +++ b/.tests/parse/axes/axes_parser.test.lua @@ -96,6 +96,15 @@ describe("parse_axes", function() assert.are.same(Vector3.new(40, 77, 99), maxv) end) + it("should infer that directions before a value are connected to that value", function() + local minv, maxv = parse_axes({ + "xy", "-x", "5" + }, facing_dirs.z_neg) + assert.is.truthy(minv) + assert.are.same(Vector3.new(-5, 0, 0), minv) + assert.are.same(Vector3.new(5, 5, 0), maxv) + end) + it("should return 2 0,0,0 vectors if no input", function() local minv, maxv = parse_axes({ -- No input diff --git a/worldeditadditions_core/utils/parse/axes_parser.lua b/worldeditadditions_core/utils/parse/axes_parser.lua index 678a050..d966256 100644 --- a/worldeditadditions_core/utils/parse/axes_parser.lua +++ b/worldeditadditions_core/utils/parse/axes_parser.lua @@ -23,7 +23,7 @@ else end ---- Unified Axis Keywords banks +--- Unified Axis Syntax banks local keywords = { -- Compass keywords compass = { @@ -36,7 +36,9 @@ local keywords = { ["w"] = "-x", ["west"] = "-x", ["-w"] = "x", ["-west"] = "x", ["u"] = "y", ["up"] = "y", + ["-u"] = "-y", ["-up"] = "-y", ["d"] = "-y", ["down"] = "-y", + ["-d"] = "y", ["-down"] = "y", }, -- Direction keywords @@ -90,9 +92,9 @@ function parse.num(str) else return false end end ---- Checks if a string is a valid Unified Axis Keyword. (Supports axis clumping) --- @param: str: String: Keyword instance to parse --- @returns: Key Instance: returns keyword type, processed keyword content and signed number (or nil) +--- Checks if a string is a valid Unified Axis Syntax. (Supports axis clumping) +-- @param: str: String: Keyword to parse +-- @returns: keyword type, processed keyword content and signed number (or nil) function parse.keyword(str) if type(str) ~= "string" then return "err", "Error: \""..tostring(str).."\" is not a string.", 404 @@ -135,68 +137,65 @@ end ---- Converts Unified Axis Keyword table into Vector3 instances. +--- Converts Unified Axis Syntax table into Vector3 instances. -- @param: tbl: Table: Keyword table to parse -- @param: facing: Table: Output from worldeditadditions_core.player_dir(name) -- @param: sum: Bool | String | nil: Return a single vector by summing the 2 output vectors together -- @returns: Vector3, [Vector3]: returns min, max Vector3 or sum Vector3 (if @param: sum ~= nil) -- if error: @returns: false, String: error message function parse.keytable(tbl, facing, sum) - local min, max = Vector3.new(), Vector3.new() - local expected = 1 - local tmp = {axes = {}, num = 0, sign = 1, mirror = false} + local min, max, mir= Vector3.new(), Vector3.new(), false + local neg, pos, v0 = Vector3.new(), Vector3.new(), Vector3.new() - --- Processes a number and adds it to the min and max vectors. - -- @param num The number to process. - -- @param axes The axes to apply the number to. - -- @param sign The sign of the number. - local function parseNumber(num, axes, sign) - if axes.rev then parseNumber(num, axes.rev, -sign) end - if num * sign >= 0 then - max = max:add(parse.vectorize(axes, num, sign)) + local function update(num) -- Update "min" and "max" + if num < 0 then + min, max = min:add(pos:mul(num)), max:add(neg:mul(num)) else - min = min:add(parse.vectorize(axes, num, sign)) + min, max = min:add(neg:mul(num)), max:add(pos:mul(num)) + end + neg, pos = v0:clone(), v0:clone() + end + + local function udir(axes, sign) -- Update "neg" and "pos" + if axes.rev then udir(axes.rev, -sign) end + for _, v in ipairs(axes) do + if sign < 0 then neg[v] = -1 + else pos[v] = 1 end end end - for i, v in ipairs(tbl) do + for i,v in ipairs(tbl) do if v:sub(1, 1) == "+" then v = v:sub(2) end - tmp.num = parse.num(v) + local num = parse.num(v) - if expected == 1 then - if tmp.num then - parseNumber(tmp.num, {"x", "y", "z", rev={"x", "y", "z"}}, tmp.sign) - else - local key_type, key_entry, key_sign = parse.keyword(v) + -- If we have a dimension add it to output + -- Else gather direction statements + if num then + -- Check for direction vectors + if neg == v0 and pos == v0 then + neg, pos = v0:add(-1), v0:add(1) + end + update(num) + else + local key_type, key_entry, key_sign = parse.keyword(v) if key_type == "axis" then - tmp.axes = key_entry - tmp.sign = key_sign + udir(key_entry, key_sign) elseif key_type == "dir" then - tmp.axes = {facing[key_entry].axis} - tmp.sign = facing[key_entry].sign * key_sign + udir({facing[key_entry].axis}, + facing[key_entry].sign * key_sign) elseif key_type == "rev" then - tmp.mirror = true + mir = true else return false, key_entry end - - expected = 2 - end - else - if tmp.num then - parseNumber(tmp.num, tmp.axes, tmp.sign) - expected = 1 - else - return false, "Error: Expected number after \""..tostring(tbl[i-1]).."\". Got \""..tostring(v).."\"." - end end end - if tmp.mirror and not sum then + if mir and not sum then max = max:max(min:abs()) min = max:multiply(-1) end @@ -209,6 +208,7 @@ function parse.keytable(tbl, facing, sum) end + return { keyword = parse.keyword, keytable = parse.keytable, From 41443f058e2b0034995e322866f4cb10654d61c1 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Thu, 19 Sep 2024 20:22:11 -0700 Subject: [PATCH 25/35] Doc update --- Chat-Command-Reference.md | 58 ++++++++++++++++++++++++++++++--------- README.md | 8 +++--- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/Chat-Command-Reference.md b/Chat-Command-Reference.md index d6cffde..ef675de 100644 --- a/Chat-Command-Reference.md +++ b/Chat-Command-Reference.md @@ -1262,19 +1262,36 @@ This also synchronises with WorldEdit, as all other WorldEditAdditions commands ``` -### `//scol [ ] ` -#### === DEPRECATED === -Please use `//srel` instead. +### `//scol [ ] {REMOVED (v1.15)}` +Short for _select column_. Sets the pos2 at a set distance along 1 axis from pos1. If the axis isn't specified, defaults the direction you are facing. Implementation thanks to @VorTechnix. + +```weacmd +**REMOVED** in favour of `//srel` +//scol 10 +//scol x 3 +``` + +### `//srect [ []] {REMOVED (v1.15)}` +Short for _select rectangle_. Sets the pos2 at a set distance along 2 axes from pos1. If the axes aren't specified, defaults to positive y and the direction you are facing. Implementation thanks to @VorTechnix. + +```weacmd +**REMOVED** in favour of `//srel` +//srect x z 10 +//srect 3 +//srect -z y 25 +``` -### `//srect [ []] ` -#### === DEPRECATED === -Please use `//srel` instead. +### `//scube [ [ []]] {REMOVED (v1.15)}` +Short for _select cube_. Sets the pos2 at a set distance along 3 axes from pos1. If the axes aren't specified, defaults to positive y, the direction you are facing and the axis to the left of facing. Implementation thanks to @VorTechnix. - -### `//scube [ [ []]] ` -#### === DEPRECATED === -Please use `//srel` instead. +```weacmd +**REMOVED** in favour of `//srel` +//scube 5 +//scube z a y 12 +//scube x z 3 +//scube -z 12 +``` ### `//scloud <0-6|stop|reset>` @@ -1385,9 +1402,24 @@ Name | Description ``: If `` == odd or even | Does nothing ``: If `` == equal | Overrides `` and sets all `` axes equal to itself -### `//sfactor []` -#### === Deprecated === -Use `//sgrow` and `//sshrink` instead. +### `//sfactor [] {REMOVED (v1.15)}` +Short for _selection factor_; alias: `//sfac`. Built specifically for use with `//maze`, this command sets targeted axes equal to the nearest multiple of `` based on the ``. + +Usage examples: + +```weacmd +**REMOVED** in favour of `//sgrow` and `//sshrink` +//sfac grow 5 +//sfac avg 3 xy +``` + +#### ``: grow|shrink|average + +Value | Description +--------|-------------- +`grow` | Rounds the length of each target axis up to the nearest multiple of `` +`shrink` | Rounds the length of each target axis down to the nearest multiple of `` +`average`/`avg` | Takes the average of all axes specified in `` and then for each specified axis grows or shrinks it, depending on whether it is less than or greater than the average, to the nearest multiple of `` ### `//sstack` Displays the contents of your per-user selection stack. This stack can be pushed to and popped from rather like a stack of plates. See also `//spush` (for pushing to the selection stack) and `//spop` (for popping from the selection stack). diff --git a/README.md b/README.md index 71287e4..f63744b 100644 --- a/README.md +++ b/README.md @@ -76,9 +76,9 @@ The detailed explanations have moved! Check them out [here](https://worldeditadd - [`//uasparse `](https://worldeditadditions.mooncarrot.space/Reference/#uasparse) _(new in v1.15)_ ### Selection - - [~~`//scol`~~ DEPRECATED](https://worldeditadditions.mooncarrot.space/Reference/#scol) - - [~~`//srect`~~ DEPRECATED](https://worldeditadditions.mooncarrot.space/Reference/#srect) - - [~~`//scube`~~ DEPRECATED](https://worldeditadditions.mooncarrot.space/Reference/#scube) + - [~~`//scol [ ] `~~](https://worldeditadditions.mooncarrot.space/Reference/#scol) (REMOVED in v1.15) + - [~~`//srect [ []] `~~](https://worldeditadditions.mooncarrot.space/Reference/#srect) (REMOVED in v1.15) + - [~~`//scube [ [ []]] `~~](https://worldeditadditions.mooncarrot.space/Reference/#scube) (REMOVED in v1.15) - [`//scloud <0-6|stop|reset>`](https://worldeditadditions.mooncarrot.space/Reference/#scloud) - [`//scentre`](https://worldeditadditions.mooncarrot.space/Reference/#scentre) - [`//sgrow `](https://worldeditadditions.mooncarrot.space/Reference/#sgrow) _(new in v1.15)_ @@ -89,7 +89,7 @@ The detailed explanations have moved! Check them out [here](https://worldeditadd - [`//spush`](https://worldeditadditions.mooncarrot.space/Reference/#spush) - [`//spop`](https://worldeditadditions.mooncarrot.space/Reference/#spop) - [`//sshift `](https://worldeditadditions.mooncarrot.space/Reference/#sshift) - - [~~`//sfactor`~~ DEPRECATED](https://worldeditadditions.mooncarrot.space/Reference/#sfactor) + - [~~`//sfactor []`~~](https://worldeditadditions.mooncarrot.space/Reference/#sfactor) (REMOVED in v1.15) - [`//pos `](https://worldeditadditions.mooncarrot.space/Reference/#pos) - [`//pos1`](https://worldeditadditions.mooncarrot.space/Reference/#pos1) - [`//pos2`](https://worldeditadditions.mooncarrot.space/Reference/#pos2) From 462332d5ad420ba34579c822875cd496c8be38cf Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Fri, 20 Sep 2024 09:47:58 -0700 Subject: [PATCH 26/35] Update Chat-Command-Reference.md --- Chat-Command-Reference.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Chat-Command-Reference.md b/Chat-Command-Reference.md index ef675de..404a727 100644 --- a/Chat-Command-Reference.md +++ b/Chat-Command-Reference.md @@ -1262,7 +1262,7 @@ This also synchronises with WorldEdit, as all other WorldEditAdditions commands ``` -### `//scol [ ] {REMOVED (v1.15)}` +### `//scol [ ] ` (**REMOVED** in v1.15) Short for _select column_. Sets the pos2 at a set distance along 1 axis from pos1. If the axis isn't specified, defaults the direction you are facing. Implementation thanks to @VorTechnix. ```weacmd @@ -1271,7 +1271,7 @@ Short for _select column_. Sets the pos2 at a set distance along 1 axis from pos //scol x 3 ``` -### `//srect [ []] {REMOVED (v1.15)}` +### `//srect [ []] ` (**REMOVED** in v1.15) Short for _select rectangle_. Sets the pos2 at a set distance along 2 axes from pos1. If the axes aren't specified, defaults to positive y and the direction you are facing. Implementation thanks to @VorTechnix. ```weacmd @@ -1282,7 +1282,7 @@ Short for _select rectangle_. Sets the pos2 at a set distance along 2 axes from ``` -### `//scube [ [ []]] {REMOVED (v1.15)}` +### `//scube [ [ []]] ` (**REMOVED** in v1.15) Short for _select cube_. Sets the pos2 at a set distance along 3 axes from pos1. If the axes aren't specified, defaults to positive y, the direction you are facing and the axis to the left of facing. Implementation thanks to @VorTechnix. ```weacmd @@ -1402,7 +1402,7 @@ Name | Description ``: If `` == odd or even | Does nothing ``: If `` == equal | Overrides `` and sets all `` axes equal to itself -### `//sfactor [] {REMOVED (v1.15)}` +### `//sfactor []` (**REMOVED** in v1.15) Short for _selection factor_; alias: `//sfac`. Built specifically for use with `//maze`, this command sets targeted axes equal to the nearest multiple of `` based on the ``. Usage examples: From 5415e213848d72d6dacfa663ba821a3b94182bd9 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Tue, 1 Oct 2024 06:48:08 -0700 Subject: [PATCH 27/35] Apply suggested title changes Co-authored-by: Starbeamrainbowlabs --- Chat-Command-Reference.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Chat-Command-Reference.md b/Chat-Command-Reference.md index 404a727..f4e3358 100644 --- a/Chat-Command-Reference.md +++ b/Chat-Command-Reference.md @@ -1262,7 +1262,9 @@ This also synchronises with WorldEdit, as all other WorldEditAdditions commands ``` -### `//scol [ ] ` (**REMOVED** in v1.15) +### `//scol [ ] ` +> [!WARNING] +> **REMOVED** in v1.15 in favour of [`//srel`](#srel) Short for _select column_. Sets the pos2 at a set distance along 1 axis from pos1. If the axis isn't specified, defaults the direction you are facing. Implementation thanks to @VorTechnix. ```weacmd @@ -1271,7 +1273,9 @@ Short for _select column_. Sets the pos2 at a set distance along 1 axis from pos //scol x 3 ``` -### `//srect [ []] ` (**REMOVED** in v1.15) +### `//srect [ []] ` +> [!WARNING] +> **REMOVED** in v1.15 in favour of [`//srel`](#srel) Short for _select rectangle_. Sets the pos2 at a set distance along 2 axes from pos1. If the axes aren't specified, defaults to positive y and the direction you are facing. Implementation thanks to @VorTechnix. ```weacmd @@ -1282,7 +1286,9 @@ Short for _select rectangle_. Sets the pos2 at a set distance along 2 axes from ``` -### `//scube [ [ []]] ` (**REMOVED** in v1.15) +### `//scube [ [ []]] ` +> [!WARNING] +> **REMOVED** in v1.15 in favour of [`//srel`](#srel) Short for _select cube_. Sets the pos2 at a set distance along 3 axes from pos1. If the axes aren't specified, defaults to positive y, the direction you are facing and the axis to the left of facing. Implementation thanks to @VorTechnix. ```weacmd @@ -1402,7 +1408,9 @@ Name | Description ``: If `` == odd or even | Does nothing ``: If `` == equal | Overrides `` and sets all `` axes equal to itself -### `//sfactor []` (**REMOVED** in v1.15) +### `//sfactor []` +> [!WARNING] +> **REMOVED** in v1.15 in favour of [`//sgrow`](#sgrow) and [`//sshrink`](#sshrink) Short for _selection factor_; alias: `//sfac`. Built specifically for use with `//maze`, this command sets targeted axes equal to the nearest multiple of `` based on the ``. Usage examples: From b884eb0e58986b01e418c1dce2fdb4da61663171 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Tue, 1 Oct 2024 06:49:04 -0700 Subject: [PATCH 28/35] Apply suggested removals Co-authored-by: Starbeamrainbowlabs --- Chat-Command-Reference.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Chat-Command-Reference.md b/Chat-Command-Reference.md index f4e3358..7279397 100644 --- a/Chat-Command-Reference.md +++ b/Chat-Command-Reference.md @@ -1268,7 +1268,6 @@ This also synchronises with WorldEdit, as all other WorldEditAdditions commands Short for _select column_. Sets the pos2 at a set distance along 1 axis from pos1. If the axis isn't specified, defaults the direction you are facing. Implementation thanks to @VorTechnix. ```weacmd -**REMOVED** in favour of `//srel` //scol 10 //scol x 3 ``` @@ -1279,7 +1278,6 @@ Short for _select column_. Sets the pos2 at a set distance along 1 axis from pos Short for _select rectangle_. Sets the pos2 at a set distance along 2 axes from pos1. If the axes aren't specified, defaults to positive y and the direction you are facing. Implementation thanks to @VorTechnix. ```weacmd -**REMOVED** in favour of `//srel` //srect x z 10 //srect 3 //srect -z y 25 @@ -1292,7 +1290,6 @@ Short for _select rectangle_. Sets the pos2 at a set distance along 2 axes from Short for _select cube_. Sets the pos2 at a set distance along 3 axes from pos1. If the axes aren't specified, defaults to positive y, the direction you are facing and the axis to the left of facing. Implementation thanks to @VorTechnix. ```weacmd -**REMOVED** in favour of `//srel` //scube 5 //scube z a y 12 //scube x z 3 @@ -1416,7 +1413,6 @@ Short for _selection factor_; alias: `//sfac`. Built specifically for use with ` Usage examples: ```weacmd -**REMOVED** in favour of `//sgrow` and `//sshrink` //sfac grow 5 //sfac avg 3 xy ``` From a7944299610df051bd69ba97c0c0441efa9e1475 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Tue, 1 Oct 2024 06:50:48 -0700 Subject: [PATCH 29/35] Show default values in param Co-authored-by: Starbeamrainbowlabs --- worldeditadditions_core/utils/strings/split.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldeditadditions_core/utils/strings/split.lua b/worldeditadditions_core/utils/strings/split.lua index 2173dbd..2436a74 100644 --- a/worldeditadditions_core/utils/strings/split.lua +++ b/worldeditadditions_core/utils/strings/split.lua @@ -58,7 +58,7 @@ end --- Split a string into substrings separated by a pattern. -- @param str string The string to iterate over --- @param dlm string The delimiter (separator) pattern (default: "%s+") +-- @param dlm="%s+" string The delimiter (separator) pattern. If a falsey value is passed, then the default value is used. -- @param plain boolean If true (or truthy), pattern is interpreted as a -- plain string, not a Lua pattern -- @returns table A sequence table containing the substrings From f399d475cc0a01fea9dc3a8fb7d730e2ab3aa995 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Tue, 1 Oct 2024 06:51:38 -0700 Subject: [PATCH 30/35] UASPARSE touchups Co-authored-by: Starbeamrainbowlabs --- worldeditadditions_commands/commands/uasparse.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worldeditadditions_commands/commands/uasparse.lua b/worldeditadditions_commands/commands/uasparse.lua index 44f0015..bf072f4 100644 --- a/worldeditadditions_commands/commands/uasparse.lua +++ b/worldeditadditions_commands/commands/uasparse.lua @@ -9,12 +9,12 @@ local wea_c = worldeditadditions_core worldeditadditions_core.register_command("uasparse", { params = "", - description = "Returns min and max vectors for given inputs", + description = "Debug command. Returns min and max vectors for given inputs", privs = { worldedit = true }, -- require_pos = 2, parse = function(params_text) local ret = wea_c.split(params_text) - if #ret < 1 then return false, "UASPARSE: No params found!" + if #ret < 1 then return false, "Error: No params found!" else return true, ret end end, func = function(name, params_text) From a48576a7ab6e30e57abd80fd1310ca707980ef4b Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Tue, 1 Oct 2024 06:53:32 -0700 Subject: [PATCH 31/35] Better errors? Co-authored-by: Starbeamrainbowlabs --- worldeditadditions_commands/commands/selectors/sshift.lua | 2 +- worldeditadditions_commands/commands/selectors/sshrink.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/worldeditadditions_commands/commands/selectors/sshift.lua b/worldeditadditions_commands/commands/selectors/sshift.lua index 74d39ce..79c8d44 100644 --- a/worldeditadditions_commands/commands/selectors/sshift.lua +++ b/worldeditadditions_commands/commands/selectors/sshift.lua @@ -14,7 +14,7 @@ worldeditadditions_core.register_command("sshift", { require_pos = 2, parse = function(params_text) local ret = wea_c.split(params_text) - if #ret < 1 then return false, "SSHIFT: No params found!" + if #ret < 1 then return false, "Error: No params found!" else return true, ret end end, func = function(name, params_text) diff --git a/worldeditadditions_commands/commands/selectors/sshrink.lua b/worldeditadditions_commands/commands/selectors/sshrink.lua index 560578b..cd69831 100644 --- a/worldeditadditions_commands/commands/selectors/sshrink.lua +++ b/worldeditadditions_commands/commands/selectors/sshrink.lua @@ -17,7 +17,7 @@ worldeditadditions_core.register_command("sshrink", { require_pos = 0, parse = function(params_text) local ret = wea_c.split(params_text) - if #ret < 1 then return false, "SSHRINK: No params found!" + if #ret < 1 then return false, "Error: No params found!" else return true, ret end end, func = function(name, params_text) From df2af2df7d193da432e18b6151fc1a812809f517 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Tue, 1 Oct 2024 07:48:32 -0700 Subject: [PATCH 32/35] Description Tweak for removed commands Co-authored-by: Starbeamrainbowlabs --- worldeditadditions_commands/commands/selectors/scol.lua | 2 +- worldeditadditions_commands/commands/selectors/scube.lua | 2 +- worldeditadditions_commands/commands/selectors/sfactor.lua | 4 ++-- worldeditadditions_commands/commands/selectors/srect.lua | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/worldeditadditions_commands/commands/selectors/scol.lua b/worldeditadditions_commands/commands/selectors/scol.lua index be80ddb..bc57bfc 100644 --- a/worldeditadditions_commands/commands/selectors/scol.lua +++ b/worldeditadditions_commands/commands/selectors/scol.lua @@ -8,7 +8,7 @@ local Vector3 = wea_c.Vector3 -- ███████ ██████ ██████ ███████ worldeditadditions_core.register_command("scol", { params = "None", - description = "Deprecated.", + description = "DEPRECATED: please use //srel instead.", privs = { worldedit = true }, require_pos = 1, parse = function(params_text) diff --git a/worldeditadditions_commands/commands/selectors/scube.lua b/worldeditadditions_commands/commands/selectors/scube.lua index 14bf0e1..f65ab02 100644 --- a/worldeditadditions_commands/commands/selectors/scube.lua +++ b/worldeditadditions_commands/commands/selectors/scube.lua @@ -8,7 +8,7 @@ local Vector3 = wea_c.Vector3 -- ███████ ██████ ██████ ██████ ███████ worldeditadditions_core.register_command("scube", { params = "None", - description = "Deprecated.", + description = "DEPRECATED: please use //srel instead.", privs = { worldedit = true }, require_pos = 1, parse = function(params_text) diff --git a/worldeditadditions_commands/commands/selectors/sfactor.lua b/worldeditadditions_commands/commands/selectors/sfactor.lua index 0babcc1..ef78473 100644 --- a/worldeditadditions_commands/commands/selectors/sfactor.lua +++ b/worldeditadditions_commands/commands/selectors/sfactor.lua @@ -10,9 +10,9 @@ local Vector3 = wea_c.Vector3 -- ███████ ██ ██ ██ ██████ ██ ██████ ██ ██ worldeditadditions_core.register_command("sfactor", { params = "None", - description = "Deprecated.", + description = "DEPRECATED: please use //grow or //shrink instead.", + privs = { worldedit = true }, - require_pos = 1, parse = function(params_text) return params_text end, diff --git a/worldeditadditions_commands/commands/selectors/srect.lua b/worldeditadditions_commands/commands/selectors/srect.lua index 1333aa2..fcb0f8c 100644 --- a/worldeditadditions_commands/commands/selectors/srect.lua +++ b/worldeditadditions_commands/commands/selectors/srect.lua @@ -8,7 +8,7 @@ local Vector3 = wea_c.Vector3 -- ███████ ██ ██ ███████ ██████ ██ worldeditadditions_core.register_command("srect", { params = "None", - description = "Deprecated.", + description = "DEPRECATED: please use //srel instead.", privs = { worldedit = true }, require_pos = 1, parse = function(params_text) From f4b3b09b26404b5d16885d503d543575f9ed3cbd Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Tue, 1 Oct 2024 07:58:08 -0700 Subject: [PATCH 33/35] Update init.lua Removed TODO --- worldeditadditions_commands/commands/selectors/init.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/worldeditadditions_commands/commands/selectors/init.lua b/worldeditadditions_commands/commands/selectors/init.lua index 9ff65c0..f5b4f95 100644 --- a/worldeditadditions_commands/commands/selectors/init.lua +++ b/worldeditadditions_commands/commands/selectors/init.lua @@ -24,7 +24,6 @@ dofile(wea_cmdpath.."sstack.lua") dofile(wea_cmdpath.."scol.lua") dofile(wea_cmdpath.."scube.lua") dofile(wea_cmdpath.."srect.lua") --- TODO: Deprecate this. dofile(wea_cmdpath.."sfactor.lua") --- END DEPRECATED --- From e811090527d060ec52a1a426f2d72889283ae510 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Tue, 1 Oct 2024 08:03:21 -0700 Subject: [PATCH 34/35] Position statements for command returns --- worldeditadditions_commands/commands/selectors/scentre.lua | 2 +- worldeditadditions_commands/commands/selectors/sgrow.lua | 2 +- worldeditadditions_commands/commands/selectors/smake.lua | 2 +- worldeditadditions_commands/commands/selectors/srel.lua | 2 +- worldeditadditions_commands/commands/selectors/sshift.lua | 2 +- worldeditadditions_commands/commands/selectors/sshrink.lua | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/worldeditadditions_commands/commands/selectors/scentre.lua b/worldeditadditions_commands/commands/selectors/scentre.lua index 1d88b75..ec8c31e 100644 --- a/worldeditadditions_commands/commands/selectors/scentre.lua +++ b/worldeditadditions_commands/commands/selectors/scentre.lua @@ -26,7 +26,7 @@ worldeditadditions_core.register_command("scentre", { wea_c.pos.set_all(name, {pos1, pos2}) - return true, "Pos1 set to "..pos1..", Pos2 set to "..pos2 + return true, "Position 1 to "..pos1..", Position 2 to "..pos2 end, }) diff --git a/worldeditadditions_commands/commands/selectors/sgrow.lua b/worldeditadditions_commands/commands/selectors/sgrow.lua index bf50e80..9ede412 100644 --- a/worldeditadditions_commands/commands/selectors/sgrow.lua +++ b/worldeditadditions_commands/commands/selectors/sgrow.lua @@ -34,7 +34,7 @@ worldeditadditions_core.register_command("sgrow", { pos1, pos2 = pos1:add(min), pos2:add(max) wea_c.pos.set_all(name, {pos1, pos2}) - return true, "Pos1 set to "..pos1..", Pos2 set to "..pos2 + return true, "Position 1 to "..pos1..", Position 2 to "..pos2 end, }) diff --git a/worldeditadditions_commands/commands/selectors/smake.lua b/worldeditadditions_commands/commands/selectors/smake.lua index 1a1d1ef..78309bb 100644 --- a/worldeditadditions_commands/commands/selectors/smake.lua +++ b/worldeditadditions_commands/commands/selectors/smake.lua @@ -126,6 +126,6 @@ worldeditadditions_core.register_command("smake", { for k,_ in pairs(targ) do delta[k] = eval(delta[k]) end wea_c.pos.set(name, 2, pos1 + delta) - return true, "Pos2 set to "..pos2 + return true, "Position 2 to "..pos2 end }) diff --git a/worldeditadditions_commands/commands/selectors/srel.lua b/worldeditadditions_commands/commands/selectors/srel.lua index 1d577c0..b0af141 100644 --- a/worldeditadditions_commands/commands/selectors/srel.lua +++ b/worldeditadditions_commands/commands/selectors/srel.lua @@ -29,7 +29,7 @@ worldeditadditions_core.register_command("srel", { local pos2 = pos1:add(vec) wea_c.pos.set_all(name, {pos1, pos2}) - return true, "Pos1 set to "..pos1..", Pos2 set to "..pos2 + return true, "Position 1 to "..pos1..", Position 2 to "..pos2 end, }) diff --git a/worldeditadditions_commands/commands/selectors/sshift.lua b/worldeditadditions_commands/commands/selectors/sshift.lua index 79c8d44..c115a65 100644 --- a/worldeditadditions_commands/commands/selectors/sshift.lua +++ b/worldeditadditions_commands/commands/selectors/sshift.lua @@ -26,7 +26,7 @@ worldeditadditions_core.register_command("sshift", { local pos2 = vec:add(wea_c.pos.get(name, 2)) wea_c.pos.set_all(name, {pos1, pos2}) - return true, "Pos1 set to "..pos1..", Pos2 set to "..pos2 + return true, "Position 1 to "..pos1..", Position 2 to "..pos2 end, }) diff --git a/worldeditadditions_commands/commands/selectors/sshrink.lua b/worldeditadditions_commands/commands/selectors/sshrink.lua index cd69831..e46ec67 100644 --- a/worldeditadditions_commands/commands/selectors/sshrink.lua +++ b/worldeditadditions_commands/commands/selectors/sshrink.lua @@ -34,7 +34,7 @@ worldeditadditions_core.register_command("sshrink", { pos1, pos2 = pos1:add(max), pos2:add(min) wea_c.pos.set_all(name, {pos1, pos2}) - return true, "Pos1 set to "..pos1..", Pos2 set to "..pos2 + return true, "Position 1 to "..pos1..", Position 2 to "..pos2 end, }) From 7a0d24f872accdcd6debdd64d9976d643317514e Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Tue, 1 Oct 2024 08:40:58 -0700 Subject: [PATCH 35/35] CRLF to LF --- CHANGELOG.md | 462 ++--- Chat-Command-Reference.md | 3616 ++++++++++++++++++------------------- 2 files changed, 2039 insertions(+), 2039 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b134f09..14bbe02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,231 +1,231 @@ -# WorldEditAdditions Changelog -It's about time I started a changelog! This will serve from now on as the main changelog for WorldEditAdditions. - -Note to self: See the bottom of this file for the release template text. - - -## v1.15: The direction update (unreleased) -- Added the optional argument `all` to [`//unmark`](https://worldeditadditions.mooncarrot.space/Reference/#unmark) -- Added a (rather nuclear) fix (attempt 4) at finally exterminating all zombie region marker walls forever - - This is not a hotfix to avoid endless small releases fixing the bug, as it's clear it's much more difficult to fix on all systems than initially expected -- Added [`//nodeapply`](https://worldeditadditions.mooncarrot.space/Reference/#nodeapply), a generalisation of [`//airapply`](https://worldeditadditions.mooncarrot.space/Reference/#airapply) that works with a defined list of nodes. Check out [the reference](https://worldeditadditions.mooncarrot.space/Reference/#nodeapply) - it has some cool tricks to it! (thanks for suggesting, @kliv91 from the Discord server!) -- Added [`//ngroups`](https://worldeditadditions.mooncarrot.space/Reference/#ngroups), which lists the groups that a given node is a member of. Useful when paired with [`//nodeapply`](https://worldeditadditions.mooncarrot.space/Reference/#nodeapply)! -- Added [`//rotate+`](https://worldeditadditions.mooncarrot.space/Reference/#rotate) to rotate regions through arbitrary series of potentially non-axis-aligned rotations. **Does not support slabs/stairs yet,** but this is on the todo list! -- Added [`//speed`](https://worldeditadditions.mooncarrot.space/Reference/#rotate) to adjust your own movement speed - - Also added an associated [movement speed adjustment tool](https://worldeditadditions.mooncarrot.space/Reference/#movement), which looks like this: ![A picture of the move speed adjustment tool. It looks like a monarch butterfly.](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/dev/worldeditadditions_farwand/textures/worldeditadditions_movement.png) -- Added [`//set+`](https://worldeditadditions.mooncarrot.space/Reference/#set) for setting nodes and param2/light levels quickly. - - NOTE TO SELF: Setting light values doesn't appear to be working very well for some reason -- Added [`//ndef`](https://worldeditadditions.mooncarrot.space/Reference/#ndef) to print a given node's definition table. This is for debugging and development purposes. -- Added `//sgrow` and `//sshrink` commands to enlarge and shrink selection regions and aliased them over WorldEdit equivalents (`//expand`, `//outset` and `//contract`, `//inset` respectively). -- Added Unified Axis Syntax (UAS) parser. - Implementation by @VorTechnix - - See [UAS System reference] for details. (Note to self hook up hyperlink) -- Added `//uasparse` command to show the vectors produced by a given UAS expression. - Implementation by @VorTechnix - -### Bugfixes and changes -- Don't warn on failed registration of `//flora` → [`//bonemeal`](https://worldeditadditions.mooncarrot.space/Reference/#bonemeal) if the `bonemeal` mod isn't installed (e.g. in MineClone2) - thanks @VorTechnix in #106 -- Improve documentation of [`//noise2d`](https://worldeditadditions.mooncarrot.space/Reference/#noise2d). If it still doesn't make sense, please let me know. It's a complicated command that needs reworking a bit to be easier to use. -- Alias `//napply` to [`//nodeapply`](https://worldeditadditions.mooncarrot.space/Reference/#nodeapply) -- Re-factored selection tools to all use WEA position system and UAS Parser if applicable. - Re-factor by @VorTechnix -- `//sshift` now overrides `//shift` from WorldEdit. - Re-factor by @VorTechnix - -### Deprecations -- Deprecated `//scol`, `//srect` and `//scube`. Now that `//srel` is using UAS parser there is no need for them. - Deprecated by @VorTechnix -- Deprecated `//sfactor`. Now that `//sgrow` and `//sshrink` exist it is no longer needed. - Deprecated by @VorTechnix - - -### Lua API changes -- Add `core.pos.get12(player_name, sort=false)` - - -## v1.14.5: The multipoint update, hotfix 5 (1st August 2023) -- Fix a bug where creative players in survival couldn't punch out position markers -- Added [`//listentities`](https://worldeditadditions.mooncarrot.space/Reference/#listentities), which lists all currently loaded `ObjectRef`s. This is intended for debugging mods - thanks to @Zughy in #103 - - -## v1.14.4: The multipoint update, hotfix 4 (31st July 2023) -- When any segment of the marker wall is punched, unmark the entire wall - thanks to @Zughy in #102 - - -## v1.14.3: The multipoint update, hotfix 3 (18th July 2023) -- Fix regions not remembering their state and being unresettable - - -## v1.14.2: The multipoint update, hotfix 2 (15th July 2023) -- Fix crash in `//subdivide`, again due to the new position system - - -## v1.14.1: The multipoint update, hotfix 1 (12th July 2023) - - Fix issue #100, which caused a crash as `//pos1` and `//pos2` allowed non-integer positions to be set - - -## v1.14: The multipoint update (11th July 2023) - - Add `//dome+`, which allows you to change the direction the dome is pointing in, and also create multiple domes at once - - Add `//metaball`, which renders 2 or more [metaballs](https://en.wikipedia.org/wiki/Metaballs) in Minetest - - Significant backend refactoring to tidy things up - - Add new multi-point selection wand ![A picture of the multi-point wand](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/worldeditadditions_farwand/textures/worldeditadditions_multiwand.png) to select many points at once. - - Implement custom region boxing UI, which replaces the WorldEdit region box when using WorldEditAdditions wands. - - Is backwards compatible with regular WorldEdit wands and tools, as WorldEditAdditions keeps the new positioning system in sync with WorldEdit's. - - The new multipoint wand required this as a prerequisite - - Add [`//pos`](https://worldeditadditions.mooncarrot.space/Reference/#pos), for setting any numbered point (i.e. not just pos1 and pos2, but pos3 and beyond) - - Add [`//spline`](https://worldeditadditions.mooncarrot.space/Reference/#spline), for drawing curved lines with an arbitrary number of points **(uses the new multi-point wand)** - - Add [`//revolve`](https://worldeditadditions.mooncarrot.space/Reference/#revolve), which makes multiple evenly-spaced rotated copies of the defined region **(uses the new multi-point wand)** - - [`//copy+`](https://worldeditadditions.mooncarrot.space/Reference/#copy), [`//move+`](https://worldeditadditions.mooncarrot.space/Reference/#move): - - Added support for integrated `airapply` mode, which replaces nodes at the target only if they are air - append `airapply`/`aa` to the command to use - - Respect node rotation (i.e. param2) when copying/moving - - Override `//move` and `//copy` by default - -### Bugfixes and changes - - Migrate from `depends.txt` to `mod.conf` - - Cloud wand: fix typo in item description. - - Commands that modify the terrain now ignore liquids - - `//sculpt`: - - Fix undefined `default` brush - - Change defaults to `circle`, `height=1`, and `brushsize=8`. - - Change argument ordering to put `height` after `brushsize` instead of the other way around - - `//hollow`: Fix safe region bug - - Make `//pos1`, `//1`, `//pos2`, `//2`, `//mark`, `//unmark`, and `//reset` aware of the new WEA positioning system - - -## v1.13: The transformational update (2nd January 2022) - - Add [`//sfactor`](https://worldeditadditions.mooncarrot.space/Reference/#sfactor) (_selection factor_) - Selection Tools by @VorTechnix are finished for now. - - Add [`//mface`](https://worldeditadditions.mooncarrot.space/Reference/#mface) (_measure facing_), [`//midpos`](https://worldeditadditions.mooncarrot.space/Reference/#midpos) (_measure middle position_), [`//msize`](https://worldeditadditions.mooncarrot.space/Reference/#msize) (_measure size_), [`//mtrig`](#mtrig) (_measure trigonometry_) - Measuring Tools implemented by @VorTechnix. - - Add [`//airapply`](https://worldeditadditions.mooncarrot.space/Reference/#airapply) for applying commands only to air nodes in the defined region - - Add [`//wcorner`](https://worldeditadditions.mooncarrot.space/Reference/#wcorner) (_wireframe corners_), [`//wbox`](https://worldeditadditions.mooncarrot.space/Reference/#wbox) (_wireframe box_), [`//wcompass`](https://worldeditadditions.mooncarrot.space/Reference/#wcompass) (_wireframe compass_) - Wireframes implemented by @VorTechnix. - - Add [`//for`](https://worldeditadditions.mooncarrot.space/Reference/#for) for executing commands while changing their arguments - Implemented by @VorTechnix. - - Add [`//sshift`](https://worldeditadditions.mooncarrot.space/Reference/#sshift) (_selection shift_) - WorldEdit cuboid manipulator replacements implemented by @VorTechnix. - - Add [`//noise2d`](https://worldeditadditions.mooncarrot.space/Reference/#noise2d) for perturbing terrain with multiple different noise functions - - Add [`//noiseapply2d`](https://worldeditadditions.mooncarrot.space/Reference/#noiseapply2d) for running commands on columns where a noise value is over a threshold - - Add [`//ellipsoid2`](https://worldeditadditions.mooncarrot.space/Reference/#ellipsoid2) which creates an ellipsoid that fills the defined region - - Add [`//spiral2`](https://worldeditadditions.mooncarrot.space/Reference/#spiral2) for creating both square and circular spirals - - Add [`//copy+`](https://worldeditadditions.mooncarrot.space/Reference/#copy) for copying a defined region across multiple axes at once - - Add [`//move+`](https://worldeditadditions.mooncarrot.space/Reference/#move) for moving a defined region across multiple axes at once - - Add [`//sculpt`](https://worldeditadditions.mooncarrot.space/Reference/#sculpt) and [`//sculptlist`](https://worldeditadditions.mooncarrot.space/Reference/#sculptlist) for sculpting terrain using a number of custom brushes. - - Use [luacheck](https://github.com/mpeterv/luacheck) to find and fix a large number of bugs and other issues [code quality from now on will be significantly improved] - - Multiple commands: Allow using quotes (`"thing"`, `'thing'`) to quote values when splitting - - [`//layers`](https://worldeditadditions.mooncarrot.space/Reference/#layers): Add optional slope constraint (inspired by [WorldPainter](https://worldpainter.net/)) - - [`//bonemeal`](https://worldeditadditions.mooncarrot.space/Reference/#bonemeal): Add optional node list constraint - - [`//walls`](https://worldeditadditions.mooncarrot.space/Reference/#walls): Add optional thickness argument - - [`//sstack`](https://worldeditadditions.mooncarrot.space/Reference/#sstack): Add human-readable approx volumes of regions in the selection stack - - -### Bugfixes - - `//floodfill`: Fix crash caused by internal refactoring of the `Queue` data structure - - `//spop`: Fix wording in displayed message - - Sapling alias compatibility: - - Correct alias of `default:sapling` from `oak` to `apple` (since it produces apples) - - `moretrees:apple_tree_sapling_ongen` from `apple` to `apple_moretrees` - - Add `plum` → `plumtree:sapling` - - Add `holly` ⇒ `hollytree:sapling` - - `//replacemix`: Improve error handling to avoid crashes (thanks, Jonathon for reporting via Discord!) - - Cloud wand: Improve chat message text - - Fix `bonemeal` mod detection to look for the global `bonemeal`, not whether the `bonemeal` mod name has been loaded - - `//bonemeal`: Fix argument parsing - - `//walls`: Prevent crash if no parameters are specified by defaulting to `dirt` as the replace_node - - `//maze`, `//maze3d`: - - Fix generated maze not reaching the very edge of the defined region - - Fix crash if no arguments are specified - - Fix automatic seed when generating many mazes in the same second (e.g. with `//for`, `//many`) - - `//convolve`: Fix those super tall pillars appearing randomly - - cloud wand: improve feedback messages sent to players - - `//forest`: Update sapling aliases for `bamboo` → `bambo:sprout` instead of `bamboo:sapling` - - -## v1.12: The selection tools update (26th June 2021) - - Add `//spush`, `//spop`, and `//sstack` - - Add `//srect` (_select rectangle_), `//scol` (_select column_), `//scube` (_select cube_) - thanks, @VorTechnix! - - Add `//scloud` (_select point cloud_), `//scentre` (_select centre node(s)_), `//srel` (_select relative_) - thanks, @VorTechnix! - - Add `//smake` (_selection make_) - thanks, @VorTechnix! - - Significantly refactored backend utility functions (more to come in future updates) - - Add new universal chance parsing - - Any `` can now either be a 1-in-N number (e.g. `4`, `10`), or a percentage chance (e.g. `50%`, `10%`). - - Caveat: Percentages are converted to a 1-in-N chance, but additionally that number is rounded down in some places - - `//torus`, `//hollowtorus`: Add optional new axes - - `//torus`, `//ellipsoid`: Add optional hollow keyword - @VorTechnix - - `//multi`: Add curly brace syntax for nesting command calls ([more information](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#multi-command_a-command_b-command_c-)) - - `//erode`: Add new `river` erosion algorithm for filling in potholes and removing pillars - -### Bugfixes - - `//bonemeal`: Try bonemealing everything that isn't an air block (#49) - - `//overlay`: Don't place nodes above water - - `//multi`: Improve resilience by handling some edge cases - - `//layers`: Fix crash due to outdated debug code - - `//erode`/snowballs: Fix assignment to undeclared variable - - `//floodfill`: Fix error handling - - -## v1.11: The big data update (25th January 2021) - - Add `//scale` (currently **experimental**) - - Scale operations that scale up and down at the same time are split into 2 separate operations automatically (scaling up is always performed first) - - `//count`: Make numbers human-readable - - Tip: Use a monospace font for the chat window, and the columns will be aligned! - - Add `//hollow` for hollowing out areas (a step towards parity with Minecraft WorldEdit) - - `//subdivide`: Improve performance of initial chunk counting algorithm - it should get started on the job _much_ quicker now (especially on large regions) - - `//subdivide`: Fix a bug where the entire defined region was emerged all at once instead of in chunks - - `//subdivide`: Fix performance & memory usage issues - - Fix passing arguments to the command being executed - - If you encounter any other issues with it over large areas (particularly 2000x150x2000 and larger), please let me know - - Bugfix: Fix obscure crash in calls to `human_size` ("unknown" will now be returned if passed junk) - - `//many` can now be used with commands with no arguments. - - `//conv`, `//erode`, `//fillcaves`: Treat liquids as air - - Add new [cloud wand](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#cloud-wand) - - `//conv`, `//erode`: Minor refactoring to improve code clarity - - -## v1.10: The tidyup update (16th January 2021) - - `//maze`: Fix some parts of generated mazes staying solid - - `//maze`, `//maze3d`: Allow non-number seeds (existing seeds aren't affected - they will still produce identical output) - - `//many`: Improve format of progress messages, add ETA - - `//subdivide`: Make asynchronous, and use `minetest.emerge_area()` to ensure areas are loaded before executing on a subdivision chunk - - This will ensure that `//subdivide`ing enormous regions should now function as expected. Want to level an entire rainforest with `//subdivide` and `//clearcut`? Now you can! :D - - Add `//line` for drawing simple lines - - -## v1.9: The Nature Update (20th September 2020) - - Add `//many` for executing a command many times in a row - - Add **experimental** `//erode` command - - Add `//fillcaves` command - fills in all air nodes beneath non air-nodes - - Add `//forest` command for quickly generating forests, and `//saplingaliases` to compliment it - - Add `//ellipsoidapply`: Like `//cubeapply`, but clips the result to an ellipsoid that is the size of the defined region. - - Fix some minor bugs and edge cases - - `//subdivide`: Print status update when completing the last chunk - - `//count`: Optimise by removing nested `for` loops - - -## v1.8: The Quality of Life Update (17th July 2020) - - Update `//multi` to display human readable times (e.g. `2.11mins` instead of `126600ms`) - - Far wand: Notify player when setting pos1 and pos2 - - Make timings more accurate (use `minetest.get_us_time()` instead of `os.clock()`) - - Add _experimental_ `//subdivide` command - - Attempt to fix a crash on startup due to a dependency issue (#21) - - -## v1.7: The Terrain Update! (21st June 2020) - - Added `//layers` (like WorldEdit for Minecraft's `//naturalize`) - - Added `//convolve` (advanced terrain smoothing inspired by image editors) - - Added far wand (like the regular WorldEdit wand, but with a configurable range that can extend to 100s of blocks) -[/list] - - -## Release text template -The text below is used as a template when making releases. - --------- - -INTRO - -See below the changelog for instructions on how to update. - -CHANGELOG HERE - - -## Updating -Updating depends on how you installed WorldEditAdditions. - - - UI in Minetest: There should be an update button for you to click in the mod menu - - ContentDB: Download the latest update from [here](https://content.minetest.net/packages/Starbeamrainbowlabs/worldeditadditions/) - - Git: `cd` to the WorldEditAdditions directory and run `git pull` (**Important:** Recently, WorldEditAdditions changed the default branch from `master` to `main`. If you're updating from before then, you'll need to re-clone the mod or else do some git-fu) - -After installing the update, don't forget to restart your client and / or server. - - --------- +# WorldEditAdditions Changelog +It's about time I started a changelog! This will serve from now on as the main changelog for WorldEditAdditions. + +Note to self: See the bottom of this file for the release template text. + + +## v1.15: The direction update (unreleased) +- Added the optional argument `all` to [`//unmark`](https://worldeditadditions.mooncarrot.space/Reference/#unmark) +- Added a (rather nuclear) fix (attempt 4) at finally exterminating all zombie region marker walls forever + - This is not a hotfix to avoid endless small releases fixing the bug, as it's clear it's much more difficult to fix on all systems than initially expected +- Added [`//nodeapply`](https://worldeditadditions.mooncarrot.space/Reference/#nodeapply), a generalisation of [`//airapply`](https://worldeditadditions.mooncarrot.space/Reference/#airapply) that works with a defined list of nodes. Check out [the reference](https://worldeditadditions.mooncarrot.space/Reference/#nodeapply) - it has some cool tricks to it! (thanks for suggesting, @kliv91 from the Discord server!) +- Added [`//ngroups`](https://worldeditadditions.mooncarrot.space/Reference/#ngroups), which lists the groups that a given node is a member of. Useful when paired with [`//nodeapply`](https://worldeditadditions.mooncarrot.space/Reference/#nodeapply)! +- Added [`//rotate+`](https://worldeditadditions.mooncarrot.space/Reference/#rotate) to rotate regions through arbitrary series of potentially non-axis-aligned rotations. **Does not support slabs/stairs yet,** but this is on the todo list! +- Added [`//speed`](https://worldeditadditions.mooncarrot.space/Reference/#rotate) to adjust your own movement speed + - Also added an associated [movement speed adjustment tool](https://worldeditadditions.mooncarrot.space/Reference/#movement), which looks like this: ![A picture of the move speed adjustment tool. It looks like a monarch butterfly.](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/dev/worldeditadditions_farwand/textures/worldeditadditions_movement.png) +- Added [`//set+`](https://worldeditadditions.mooncarrot.space/Reference/#set) for setting nodes and param2/light levels quickly. + - NOTE TO SELF: Setting light values doesn't appear to be working very well for some reason +- Added [`//ndef`](https://worldeditadditions.mooncarrot.space/Reference/#ndef) to print a given node's definition table. This is for debugging and development purposes. +- Added `//sgrow` and `//sshrink` commands to enlarge and shrink selection regions and aliased them over WorldEdit equivalents (`//expand`, `//outset` and `//contract`, `//inset` respectively). +- Added Unified Axis Syntax (UAS) parser. - Implementation by @VorTechnix + - See [UAS System reference] for details. (Note to self hook up hyperlink) +- Added `//uasparse` command to show the vectors produced by a given UAS expression. - Implementation by @VorTechnix + +### Bugfixes and changes +- Don't warn on failed registration of `//flora` → [`//bonemeal`](https://worldeditadditions.mooncarrot.space/Reference/#bonemeal) if the `bonemeal` mod isn't installed (e.g. in MineClone2) - thanks @VorTechnix in #106 +- Improve documentation of [`//noise2d`](https://worldeditadditions.mooncarrot.space/Reference/#noise2d). If it still doesn't make sense, please let me know. It's a complicated command that needs reworking a bit to be easier to use. +- Alias `//napply` to [`//nodeapply`](https://worldeditadditions.mooncarrot.space/Reference/#nodeapply) +- Re-factored selection tools to all use WEA position system and UAS Parser if applicable. - Re-factor by @VorTechnix +- `//sshift` now overrides `//shift` from WorldEdit. - Re-factor by @VorTechnix + +### Deprecations +- Deprecated `//scol`, `//srect` and `//scube`. Now that `//srel` is using UAS parser there is no need for them. - Deprecated by @VorTechnix +- Deprecated `//sfactor`. Now that `//sgrow` and `//sshrink` exist it is no longer needed. - Deprecated by @VorTechnix + + +### Lua API changes +- Add `core.pos.get12(player_name, sort=false)` + + +## v1.14.5: The multipoint update, hotfix 5 (1st August 2023) +- Fix a bug where creative players in survival couldn't punch out position markers +- Added [`//listentities`](https://worldeditadditions.mooncarrot.space/Reference/#listentities), which lists all currently loaded `ObjectRef`s. This is intended for debugging mods - thanks to @Zughy in #103 + + +## v1.14.4: The multipoint update, hotfix 4 (31st July 2023) +- When any segment of the marker wall is punched, unmark the entire wall - thanks to @Zughy in #102 + + +## v1.14.3: The multipoint update, hotfix 3 (18th July 2023) +- Fix regions not remembering their state and being unresettable + + +## v1.14.2: The multipoint update, hotfix 2 (15th July 2023) +- Fix crash in `//subdivide`, again due to the new position system + + +## v1.14.1: The multipoint update, hotfix 1 (12th July 2023) + - Fix issue #100, which caused a crash as `//pos1` and `//pos2` allowed non-integer positions to be set + + +## v1.14: The multipoint update (11th July 2023) + - Add `//dome+`, which allows you to change the direction the dome is pointing in, and also create multiple domes at once + - Add `//metaball`, which renders 2 or more [metaballs](https://en.wikipedia.org/wiki/Metaballs) in Minetest + - Significant backend refactoring to tidy things up + - Add new multi-point selection wand ![A picture of the multi-point wand](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/worldeditadditions_farwand/textures/worldeditadditions_multiwand.png) to select many points at once. + - Implement custom region boxing UI, which replaces the WorldEdit region box when using WorldEditAdditions wands. + - Is backwards compatible with regular WorldEdit wands and tools, as WorldEditAdditions keeps the new positioning system in sync with WorldEdit's. + - The new multipoint wand required this as a prerequisite + - Add [`//pos`](https://worldeditadditions.mooncarrot.space/Reference/#pos), for setting any numbered point (i.e. not just pos1 and pos2, but pos3 and beyond) + - Add [`//spline`](https://worldeditadditions.mooncarrot.space/Reference/#spline), for drawing curved lines with an arbitrary number of points **(uses the new multi-point wand)** + - Add [`//revolve`](https://worldeditadditions.mooncarrot.space/Reference/#revolve), which makes multiple evenly-spaced rotated copies of the defined region **(uses the new multi-point wand)** + - [`//copy+`](https://worldeditadditions.mooncarrot.space/Reference/#copy), [`//move+`](https://worldeditadditions.mooncarrot.space/Reference/#move): + - Added support for integrated `airapply` mode, which replaces nodes at the target only if they are air - append `airapply`/`aa` to the command to use + - Respect node rotation (i.e. param2) when copying/moving + - Override `//move` and `//copy` by default + +### Bugfixes and changes + - Migrate from `depends.txt` to `mod.conf` + - Cloud wand: fix typo in item description. + - Commands that modify the terrain now ignore liquids + - `//sculpt`: + - Fix undefined `default` brush + - Change defaults to `circle`, `height=1`, and `brushsize=8`. + - Change argument ordering to put `height` after `brushsize` instead of the other way around + - `//hollow`: Fix safe region bug + - Make `//pos1`, `//1`, `//pos2`, `//2`, `//mark`, `//unmark`, and `//reset` aware of the new WEA positioning system + + +## v1.13: The transformational update (2nd January 2022) + - Add [`//sfactor`](https://worldeditadditions.mooncarrot.space/Reference/#sfactor) (_selection factor_) - Selection Tools by @VorTechnix are finished for now. + - Add [`//mface`](https://worldeditadditions.mooncarrot.space/Reference/#mface) (_measure facing_), [`//midpos`](https://worldeditadditions.mooncarrot.space/Reference/#midpos) (_measure middle position_), [`//msize`](https://worldeditadditions.mooncarrot.space/Reference/#msize) (_measure size_), [`//mtrig`](#mtrig) (_measure trigonometry_) - Measuring Tools implemented by @VorTechnix. + - Add [`//airapply`](https://worldeditadditions.mooncarrot.space/Reference/#airapply) for applying commands only to air nodes in the defined region + - Add [`//wcorner`](https://worldeditadditions.mooncarrot.space/Reference/#wcorner) (_wireframe corners_), [`//wbox`](https://worldeditadditions.mooncarrot.space/Reference/#wbox) (_wireframe box_), [`//wcompass`](https://worldeditadditions.mooncarrot.space/Reference/#wcompass) (_wireframe compass_) - Wireframes implemented by @VorTechnix. + - Add [`//for`](https://worldeditadditions.mooncarrot.space/Reference/#for) for executing commands while changing their arguments - Implemented by @VorTechnix. + - Add [`//sshift`](https://worldeditadditions.mooncarrot.space/Reference/#sshift) (_selection shift_) - WorldEdit cuboid manipulator replacements implemented by @VorTechnix. + - Add [`//noise2d`](https://worldeditadditions.mooncarrot.space/Reference/#noise2d) for perturbing terrain with multiple different noise functions + - Add [`//noiseapply2d`](https://worldeditadditions.mooncarrot.space/Reference/#noiseapply2d) for running commands on columns where a noise value is over a threshold + - Add [`//ellipsoid2`](https://worldeditadditions.mooncarrot.space/Reference/#ellipsoid2) which creates an ellipsoid that fills the defined region + - Add [`//spiral2`](https://worldeditadditions.mooncarrot.space/Reference/#spiral2) for creating both square and circular spirals + - Add [`//copy+`](https://worldeditadditions.mooncarrot.space/Reference/#copy) for copying a defined region across multiple axes at once + - Add [`//move+`](https://worldeditadditions.mooncarrot.space/Reference/#move) for moving a defined region across multiple axes at once + - Add [`//sculpt`](https://worldeditadditions.mooncarrot.space/Reference/#sculpt) and [`//sculptlist`](https://worldeditadditions.mooncarrot.space/Reference/#sculptlist) for sculpting terrain using a number of custom brushes. + - Use [luacheck](https://github.com/mpeterv/luacheck) to find and fix a large number of bugs and other issues [code quality from now on will be significantly improved] + - Multiple commands: Allow using quotes (`"thing"`, `'thing'`) to quote values when splitting + - [`//layers`](https://worldeditadditions.mooncarrot.space/Reference/#layers): Add optional slope constraint (inspired by [WorldPainter](https://worldpainter.net/)) + - [`//bonemeal`](https://worldeditadditions.mooncarrot.space/Reference/#bonemeal): Add optional node list constraint + - [`//walls`](https://worldeditadditions.mooncarrot.space/Reference/#walls): Add optional thickness argument + - [`//sstack`](https://worldeditadditions.mooncarrot.space/Reference/#sstack): Add human-readable approx volumes of regions in the selection stack + + +### Bugfixes + - `//floodfill`: Fix crash caused by internal refactoring of the `Queue` data structure + - `//spop`: Fix wording in displayed message + - Sapling alias compatibility: + - Correct alias of `default:sapling` from `oak` to `apple` (since it produces apples) + - `moretrees:apple_tree_sapling_ongen` from `apple` to `apple_moretrees` + - Add `plum` → `plumtree:sapling` + - Add `holly` ⇒ `hollytree:sapling` + - `//replacemix`: Improve error handling to avoid crashes (thanks, Jonathon for reporting via Discord!) + - Cloud wand: Improve chat message text + - Fix `bonemeal` mod detection to look for the global `bonemeal`, not whether the `bonemeal` mod name has been loaded + - `//bonemeal`: Fix argument parsing + - `//walls`: Prevent crash if no parameters are specified by defaulting to `dirt` as the replace_node + - `//maze`, `//maze3d`: + - Fix generated maze not reaching the very edge of the defined region + - Fix crash if no arguments are specified + - Fix automatic seed when generating many mazes in the same second (e.g. with `//for`, `//many`) + - `//convolve`: Fix those super tall pillars appearing randomly + - cloud wand: improve feedback messages sent to players + - `//forest`: Update sapling aliases for `bamboo` → `bambo:sprout` instead of `bamboo:sapling` + + +## v1.12: The selection tools update (26th June 2021) + - Add `//spush`, `//spop`, and `//sstack` + - Add `//srect` (_select rectangle_), `//scol` (_select column_), `//scube` (_select cube_) - thanks, @VorTechnix! + - Add `//scloud` (_select point cloud_), `//scentre` (_select centre node(s)_), `//srel` (_select relative_) - thanks, @VorTechnix! + - Add `//smake` (_selection make_) - thanks, @VorTechnix! + - Significantly refactored backend utility functions (more to come in future updates) + - Add new universal chance parsing + - Any `` can now either be a 1-in-N number (e.g. `4`, `10`), or a percentage chance (e.g. `50%`, `10%`). + - Caveat: Percentages are converted to a 1-in-N chance, but additionally that number is rounded down in some places + - `//torus`, `//hollowtorus`: Add optional new axes + - `//torus`, `//ellipsoid`: Add optional hollow keyword - @VorTechnix + - `//multi`: Add curly brace syntax for nesting command calls ([more information](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#multi-command_a-command_b-command_c-)) + - `//erode`: Add new `river` erosion algorithm for filling in potholes and removing pillars + +### Bugfixes + - `//bonemeal`: Try bonemealing everything that isn't an air block (#49) + - `//overlay`: Don't place nodes above water + - `//multi`: Improve resilience by handling some edge cases + - `//layers`: Fix crash due to outdated debug code + - `//erode`/snowballs: Fix assignment to undeclared variable + - `//floodfill`: Fix error handling + + +## v1.11: The big data update (25th January 2021) + - Add `//scale` (currently **experimental**) + - Scale operations that scale up and down at the same time are split into 2 separate operations automatically (scaling up is always performed first) + - `//count`: Make numbers human-readable + - Tip: Use a monospace font for the chat window, and the columns will be aligned! + - Add `//hollow` for hollowing out areas (a step towards parity with Minecraft WorldEdit) + - `//subdivide`: Improve performance of initial chunk counting algorithm - it should get started on the job _much_ quicker now (especially on large regions) + - `//subdivide`: Fix a bug where the entire defined region was emerged all at once instead of in chunks + - `//subdivide`: Fix performance & memory usage issues + - Fix passing arguments to the command being executed + - If you encounter any other issues with it over large areas (particularly 2000x150x2000 and larger), please let me know + - Bugfix: Fix obscure crash in calls to `human_size` ("unknown" will now be returned if passed junk) + - `//many` can now be used with commands with no arguments. + - `//conv`, `//erode`, `//fillcaves`: Treat liquids as air + - Add new [cloud wand](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#cloud-wand) + - `//conv`, `//erode`: Minor refactoring to improve code clarity + + +## v1.10: The tidyup update (16th January 2021) + - `//maze`: Fix some parts of generated mazes staying solid + - `//maze`, `//maze3d`: Allow non-number seeds (existing seeds aren't affected - they will still produce identical output) + - `//many`: Improve format of progress messages, add ETA + - `//subdivide`: Make asynchronous, and use `minetest.emerge_area()` to ensure areas are loaded before executing on a subdivision chunk + - This will ensure that `//subdivide`ing enormous regions should now function as expected. Want to level an entire rainforest with `//subdivide` and `//clearcut`? Now you can! :D + - Add `//line` for drawing simple lines + + +## v1.9: The Nature Update (20th September 2020) + - Add `//many` for executing a command many times in a row + - Add **experimental** `//erode` command + - Add `//fillcaves` command - fills in all air nodes beneath non air-nodes + - Add `//forest` command for quickly generating forests, and `//saplingaliases` to compliment it + - Add `//ellipsoidapply`: Like `//cubeapply`, but clips the result to an ellipsoid that is the size of the defined region. + - Fix some minor bugs and edge cases + - `//subdivide`: Print status update when completing the last chunk + - `//count`: Optimise by removing nested `for` loops + + +## v1.8: The Quality of Life Update (17th July 2020) + - Update `//multi` to display human readable times (e.g. `2.11mins` instead of `126600ms`) + - Far wand: Notify player when setting pos1 and pos2 + - Make timings more accurate (use `minetest.get_us_time()` instead of `os.clock()`) + - Add _experimental_ `//subdivide` command + - Attempt to fix a crash on startup due to a dependency issue (#21) + + +## v1.7: The Terrain Update! (21st June 2020) + - Added `//layers` (like WorldEdit for Minecraft's `//naturalize`) + - Added `//convolve` (advanced terrain smoothing inspired by image editors) + - Added far wand (like the regular WorldEdit wand, but with a configurable range that can extend to 100s of blocks) +[/list] + + +## Release text template +The text below is used as a template when making releases. + +-------- + +INTRO + +See below the changelog for instructions on how to update. + +CHANGELOG HERE + + +## Updating +Updating depends on how you installed WorldEditAdditions. + + - UI in Minetest: There should be an update button for you to click in the mod menu + - ContentDB: Download the latest update from [here](https://content.minetest.net/packages/Starbeamrainbowlabs/worldeditadditions/) + - Git: `cd` to the WorldEditAdditions directory and run `git pull` (**Important:** Recently, WorldEditAdditions changed the default branch from `master` to `main`. If you're updating from before then, you'll need to re-clone the mod or else do some git-fu) + +After installing the update, don't forget to restart your client and / or server. + + +-------- diff --git a/Chat-Command-Reference.md b/Chat-Command-Reference.md index 7279397..b453302 100644 --- a/Chat-Command-Reference.md +++ b/Chat-Command-Reference.md @@ -1,1808 +1,1808 @@ -# Chat Command Reference - -This is the full chat command reference for WorldEditAdditions. Having trouble finding the section you want? Try the **[quick reference](https://github.com/sbrl/Minetest-WorldEditAdditions#quick-command-reference)** instead, which has links to back to sections of this document! - -**Check out the reference on the new website - it's even searchable: ** - -Other useful links: - - - [WorldEditAdditions quick reference](https://github.com/sbrl/Minetest-WorldEditAdditions#quick-command-reference) - - [WorldEditAdditions Chat Command Cookbook](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Cookbook.md) - - [WorldEdit Chat Command Reference](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md) - - [`we_env`](https://github.com/sfan5/we_env#readme) - -**Note:** If anything in this reference isn't clear, that's a bug. Please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new) (or even better a PR improving it) to let me know precisely which bit you don't understand and why. - -## Geometry - - -### `//metaball add | remove | render [] | list | clear | volume` -Draws two or more [metaballs](https://en.wikipedia.org/wiki/Metaballs). Based on a subcommand system, since each metaball may have a different radius. - -Calling `//metaball render ` actually makes changes to the world - all others manipulate an internal player-local list of metaballs to be drawn. - -#### `//metaball add ` -Adds a new metaball to the (player-local) list of metaballs to be draw with the given radius. The position of the new metaball is taken from pos1. - -```weacmd -//metaball add 5 -//metaball add 10 -//metaball add 65 -``` - -#### `//metaball remove ` -Removes the metaball with the given index from the list. See also `//metaball list`. - -```weacmd -//metaball remove 1 -//metaball remove 2 -//metaball remove 5 -``` - -#### `//metaball render []` -Renders the current list of metaballs to the world using replace_node to draw with. - -Threshold is a value that acts as an offset for large or small the metaballs should be. Defaults to 1, with larger values resulting in **smaller** metaballs and smaller values resulting in **larger** metaballs. It is not recommended to set threshold to a negative number. - -Does not clear the list of metaballs after rendering - see `//metaball clear` for that. - -```weacmd -//metaball render dirt -//metaball render glass -//metaball render stone -//metaball render stone 2 -//metaball render cobble 0.5 -``` - -#### `//metaball list` -Lists all the metaballs currently registered for the current player (all `//metaball` commands operate on the current player's metaball list only), and their indexes, positions, and sizes. Useful when using `//metaball remove ` to identify which metaball you want to remove. - -Example output: - -``` -Index Position Radius -1 (-495, 37, 150) 7 -2 (-506, 33, 142) 7 -3 (-516, 35, 152) 10 -``` - -```weacmd -//metaball list -``` - -#### `//metaball clear` -Clears the list of metaballs for the current player. - -```weacmd -//metaball clear -``` - -#### `//metaball volume` -Calculate an estimated volume of the metaballs currently in the list. - -```weacmd -//metaball volume -``` - - -### `//ellipsoid [h[ollow]]` -Creates a solid ellipsoid at position 1 with the radius `(rx, ry, rz)`. - -```weacmd -//ellipsoid 10 5 15 ice -//ellipsoid 3 5 10 dirt -//ellipsoid 20 10 40 air -//ellipsoid 14 5 8 steelblock h -//ellipsoid 7 4 7 papyrus hollow -``` - -### `//hollowellipsoid ` -Creates a hollow ellipsoid at position 1 with the radius `(rx, ry, rz)`. Works the same way as `//ellipsoid` does. - -```weacmd -//hollowellipsoid 10 5 15 glass -//hollowellipsoid 21 11 41 stone -``` - -### `//ellipsoid2 [ [h[ollow]]]` -Creates an (optionally hollow) solid ellipsoid that fills the defined region. - -```weacmd -//ellipsoid2 -//ellipsoid2 ice -//ellipsoid2 air -//ellipsoid2 steelblock h -//ellipsoid2 papyrus hollow -``` - - -### `//torus [ [h[ollow]]]` -Creates a solid torus at position 1 with the specified major and minor radii. The major radius is the distance from the centre of the torus to the centre of the circle bit, and the minor radius is the radius of the circle bit. - -The optional axes sets the axes upon which the torus will lay flat. Possible values: `xy` (the default), `xz`, `yz`. A single axis may also be specified (i.e. `x`, `y`, or `z`) - this will be interpreted as the axis that runs through the hole in the middle of the torus. - -```weacmd -//torus 15 5 stone -//torus 5 3 meselamp -//torus 10 6 sandstone xz -//torus 10 6 wool:red y -//torus 25 10 dirt xz hollow -``` - -### `//hollowtorus []` -Creates a hollow torus at position 1 with the radius major and minor radii. Works the same way as `//torus` does. - -```weacmd -//hollowtorus 10 5 glass -//hollowtorus 21 11 stone -//hollowtorus 18 6 dirt xz -``` - -### `//line [ []]` -Draw a line from position 1 to position 2, optionally with a given thickness. - -The radius can be thought of as the thickness of the line, and is defined as the distance from a given node to an imaginary line from pos1 to pos2. Defaults to drawing with dirt and a radius of 1. - -Floating-point values are fully supported for the radius. - -```weacmd -//line -//line stone -//line sandstone 3 -//line glass 0.5 -``` - -### `//hollow []` -Replaces nodes inside the defined region with air, but leaving a given number of nodes near the outermost edges alone. In other words, it makes the defined region hollow, while leaving walls around the edges of a given thickness (defaulting to a wall thickness of 1). - -Note that all air-like nodes are also left alone. - -```weacmd -//hollow -//hollow 2 -``` - -### `//maze [ [ []]]` -Generates a maze using replace_node as the walls and air as the paths. Uses [an algorithm of my own devising](https://starbeamrainbowlabs.com/blog/article.php?article=posts/070-Language-Review-Lua.html) (see also [this post of mine that has lots of eye candy :D](https://starbeamrainbowlabs.com/blog/article.php?article=posts/429-lua-blender-mazes.html)). It is guaranteed that you can get from every point to every other point in generated mazes, and there are no loops. - -Requires the currently selected area to be at least 3x3 on the x and z axes respectively. - -Mazes are generated from the bottom to the top of the defined region. In other words, the height of the walls of the maze is equal to the height of the defined region. - -The optional `path_length` and `path_width` arguments require additional explanation. When generating a maze, a multi-headed random walk is performed. When the generator decides to move forwards from a point, it does so `path_length` nodes at a time. `path_length` defaults to `2`. - -`path_width` is easier to explain. It defaults to `1`, and is basically the number of nodes wide the path generated is. - -Note that `path_width` must always be at least 1 less than the `path_length` in order to operate normally. - -Note also that since WorldEditAdditions v1.10, the seed doesn't have to be a number (but it can't contain spaces due to the parsing algorithm used). Non-numbers are hashed to a number using a simple (non-crypto-safe) hashing algorithm. - -The last example below shows how to set the path length and width: - -```weacmd -//maze ice -//maze stone 2 1 1234 -//maze dirt 4 2 56789 -//maze glass 2 1 minetestiscool -``` - - -### `//maze3d [ [ [ []]]]` -Same as `//maze`, but instead generates mazes in 3 dimensions instead of 2. Requires the currently selected area to be at least 3x3x3. - -The optional `path_depth` parameter defaults to `1` and allows customisation of the height of the paths generated. In other words, it customises the ceiling height, or the distance from the floor to the ceiling of the paths generated. - -To get a better look at the generated maze, try inverting it like so: - -```weacmd -//maze3d stone -//replace air dirt -//replace stone air -``` - -Additional examples: - -```weacmd -//maze3d glass -//maze3d bush_leaves 2 1 1 12345 -//maze3d dirt 4 2 2 -//maze3d stone 6 3 3 54321 -``` - - -### `//walls [ []]` -Creates vertical walls of `` around the inside edges of the defined region, optionally specifying the thickness thereof. Defaults to a replace node of `dirt` and a wall thickness of 1. - -```weacmd -//walls -//walls dirt -//walls stone -//walls goldblock -//walls sandstone 2 -//walls glass 4 -``` - - -### `//spiral2 [] [ [ [] ] ]` -Generates both square and circular spiral shapes with the given `` - defaulting to square spirals. The interval defines the gap between the spiral in nodes, and the acceleration defines by how much the interval should be increased (a value of 1 means 1 node per revolution). - -``` -//spiral2 -//spiral2 circle stone -//spiral2 square -//spiral2 circle -//spiral2 glass 5 -//spiral2 square desert_sand 3 1 -``` - - -### `//dome+ [ ...] [h[ollow]]` -Creates a dome shape (i.e. a hemisphere; half a sphere) with a specified radius of the defined node, optionally specifying the direction it should be pointing in (defaults to the positive y direction). - -For example, `//dome+ 5 stone y` creates a dome shape pointing upwards, but `//dome+ 5 stone -y` creates a dome shape pointing downwards. - -Multiple pointing direction axes can be chained together to create multiple domes on top of each other. Multiple conflicting directions will cancel each other out. - -If `h` or `hollow` is specified at the end, then the resulting dome shape is made hollow. - -``` -//dome+ 5 stone y -//dome+ 10 diamond -x -//dome+ 25 cactus y z -//dome+ 9 dirt x y z -``` - - -### `//spline [ []]` -Draws a curved line, using all the currently defined points as control points. The starting and ending widths of the line can be controlled, and the width will be linearly interpolated. - -**Note:** `//spline` uses the **new** WorldEditAdditions positions! Use the [multipoint wand](#multi-point-wand) to define the control points for the resulting line. - -For those interested, WorldEditAdditions uses the [chaikin curve algorithm](https://starbeamrainbowlabs.com/blog/article.php?article=posts/196-Chaikin-Curve-Generator.html) with linear interpolation for the width to draw the curve. - -```weacmd -//spline dirt 5 2 -//spline glass 3 -//spline bakedclay:violet 3 -``` - -![An example of what //spline can do.](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/.docs/images/reference/spline.jpeg) - -## Misc - - - -### `//rotate+ [ ...] [origin|o []]` -Rotates the defined region using the specified list of rotation operations, optionally around the defined rotation origin. For example, the following: - -```weacmd -//rotate+ y 45 -``` - -...will rotate the defined region around it's centre by 45° on the Y (vertical) axis. - -> [!IMPORTANT] -> There is a known issue in which holes appear in previously flat surfaces when rotating through non-axis-aligned rotations. The cause for this is currently unclear. -> -> If you can shed any light on this issue or make any suggestions, please get in touch. - -We can also extend this to rotate on multiple axes: - -```weacmd -//rotate+ z 90 y 45 -``` - -The rotations will be processed in order as specified from left to right. The following relative keywords are currently supported in place of an absolute axis name: - -Keyword | Meaning -------------|-------------------- -`right` | Rotates around the Y axis to the right - aka clockwise. -`left` | Rotates around the Y axis to the left - aka anticlockwise. - -A custom rotation origin can be specified too. This is done via the `origin` keyword and takes the form of specifying a position to rotate around instead of the default (picking the centre point between pos1 and pos2). For example: - -```weacmd -//rotate+ x 20 origin 3 -``` - -....will rotate 20° on the X axis around position 3. See the [multi-point wand](#multipoint) for more information on setting positions other than pos1 and pos2. - -The `origin` keyword's argument is optional, and if no position number is specified defaults to position 3. - -```weacmd -//rotate+ y 90 x 45 origin -//rotate+ y 90 x 45 o -//rotate+ x 60 origin 5 z 20 -``` - - -### `//floodfill [ []]` -Floods all connected nodes of the same type starting at _pos1_ with `` (which defaults to `water_source`), in a sphere with a radius of `` (which defaults to 50). - -```weacmd -//floodfill -//floodfill water_source 50 -//floodfill glass 25 -``` - - -### `//wbox ` -Sets the edges of the current selection to ``to create an outline of a rectangular prism. Useful for roughing in walls. - -In other words, creates a wireframe of a box defined by the current selection. - -```weacmd -//wbox silver_sandstone -//wbox dirt -``` - -### `//wcompass []` -Creates a compass around pos1 with a single node bead pointing north (+Z). - -```weacmd -//wcompass meselamp -//wcompass desert_cobble torch -//wcompass gold diamond -``` - -### `//wcorner ` -Set the corners of the current selection to ``. Useful for outlining building sites and setting boundaries. - -```weacmd -//wcorner glass -//wcorner stone_with_iron -``` - -### `//scale | [ [ ` -Advanced version of [`//stretch` from WorldEdit](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md#stretch-stretchx-stretchy-stretchz) that can scale both up and down at the same time by transparently splitting it into 2 different operations. Scaling up is *always* done before scaling down. - -Although the syntax looks complicated, it's really quite simple. The key concept to understand is that of the scale factor. It refers to how much the defined region should be scaled up or down by, and can be specified in multiple different ways: - -Scale Factor | Meaning -----------------|--------------------- -1 | Don't scale at all. -0.5 | Scale down by 50% -2 | Scale up by 2x, doubling the size -5 | Scale up by 5x, quintupling the size -20% | Scale down to 30% of the original size -1/3 | Scale down to 1 third of original size - -In short, you can specify the scale factor directly, as a percentage, or as 1 number divided by another number. - -> [!NOTE] -> `//scale` always scales in the _positive direction_ by default. This can be changed however - see below. - -With this in mind, there are 3 forms that you can tell `//scale` how you want to scale the defined region: - -#### Single Axis -If you just need to scale a single axis, you can tell `//scale` that like so: - -```weacmd -//scale -``` - -To give a concrete example: - -```weacmd -//scale y 2 -``` - -The above will scale the defined region in the positive y direction by 2 times, doubling the height. If you want to scale in the opposite direction, do this: - -```weacmd -//scale -y 2 -``` - -This will scale in the _negative_ y direction by 2 times (again, doubling the height). Some more examples: - -```weacmd -//scale z 50% -//scale -x 1/3 -``` - -#### All axes -To scale on all axes at once, `//scale` takes the shortcut syntax of specifying a single scale factor: - -```weacmd -//scale 2 -//scale 200% -``` - -Both of the above will scale the defined region up by 2 times in all directions. - -#### Multiple scale factors -If you want to specify different scale factors for difference axes, then `//scale` also supports a third syntax. Here's an example: - -```weacmd -//scale 2 3 4 -``` - -This will scale the defined region by 2x in the positive x, 3x in the positive y, and 4x in the positive z. As these are all scale factors, we can also use the syntax described above to scale up and down in the same operation: - -```weacmd -//scale 50% 2 1/4 -``` - -This will first scale in the positive y by 2x. Once that operation is completed, it will scale down to 50% size in the positive x and down to 25% size in the positive z. Note that if you want to scale down first and then scale up, you'll need to execute 2 separate commands. - -If you want to change the anchor point of the scaling operation too, `//scale` supports a final syntax like so: - -```weacmd -//scale 50% 2 1/4 1 -1 1 -``` - -By adding 3 extra numbers for the x, y, and z axes respectively, we can control the direction `//scale` performs the scaling operation. A value of 1 or greater indicates the positive direction of the axis, and a value of -1 or less indicates the negative direction of the axis. I recommend by [worldedit_hud_helper](https://content.minetest.net/packages/Starbeamrainbowlabs/worldedit_hud_helper/) mod for easily determining which direction is which. - -So in the above example, we scale in the positive x and z directions, and the negative y direction. - - -### `//copy+ [ [...]] [aa|airapply]` -Fully backwards-compatible with `//copy` from regular WorldEdit, but allows you to specify multiple axes at once in a single copy operation. Each successive axis in the list is specified in the form ` `, where: - - - `` is the name of the axis to move the defined region along - - `` is the number of nodes along the defined axis to move - -All of the following values are valid axes: - - - `x` - - `y` - - `z` - - `-x` - - `-y` - - `-z` - - `?` / `front` / `f` - - `back` / `b` - - `left` / `l` - - `right` / `r` - - `up` / `u` - - `down` / `d` - -Additionally all the absolute axis names (`x`/`y`/`z`/`-x`/`-y`/`-z`) may also be specified multiple times under the same count - e.g. `xy-z 6`. - -Finally, if the word `airapply` (or `aa` for short) is present at the end of the command invocation it enables the integrated airapply mode, which replaces target nodes only if they are air-like. - -``` -//copy+ x 6 -//copy+ y 10 z 4 -//copy+ front 6 left 5 -//copy+ ? 10 r 25 y 50 -//copy+ xz 50 front 22 -//copy+ yx 25 -//copy+ -xz-y 10 -//copy+ y 45 aa -//copy+ -y 15 z 5 airapply -``` - - -### `//move+ [ [...]] [aa|airapply]` -Identical to [`//copy+`](#copy), but instead moves the defined region instead of copying it. - -Note that the integrated `airapply` (`aa` for short) also works as in [`//copy+`](#copy), but remember that if a given target node is not *not* air-like and the integrated `airapply` mode is enabled, the source node is still moved from the source, but destroyed because it is can't be set at the target. - - -``` -//move+ x 6 -//move+ y 10 z 4 -//move+ front 6 left 5 -//move+ ? 10 r 25 y 50 -//move+ xz 50 front 22 -//move+ yx 25 -//move+ -xz-y 10 -//move+ back 20 aa -//move+ -z 45 y 3 airapply -``` - - -### `//replacemix [] [] [ []] [ []] ...` -Replaces a given node with a random mix of other nodes. Functions like `//mix`. - -This command is best explained with examples: - -```weacmd -//replacemix dirt stone -``` - -The above functions just like `//replace` - nothing special going on here. It replaces all `dirt` nodes with `stone`. - -Let's make it more interesting: - -```weacmd -//replacemix dirt 5 stone -``` - -The above replaces 1 in every 5 `dirt` nodes with `stone`. Let's get even fancier: - -```weacmd -//replacemix stone stone_with_diamond stone_with_gold -``` - -The above replaces `stone` nodes with a random mix of `stone_with_diamond` and `stone_with_gold` nodes. But wait - there's more! - -```weacmd -//replacemix stone stone_with_diamond stone_with_gold 4 -``` - -The above replaces `stone` nodes with a random mix of `stone_with_diamond` and `stone_with_gold` nodes as before, but this time in the ratio 1:4 (i.e. for every `stone_with_diamond` node there will be 4 `stone_with_gold` nodes). Note that the `1` for `stone_with_diamond` is implicit there. - -If we wanted to put all of the above features together into a single command, then we might do this: - -```weacmd -//replacemix dirt 3 sandstone 10 dry_dirt cobble 2 -``` - -The above replaces 1 in 3 `dirt` nodes with a mix of `sandstone`, `dry_dirt`, and `cobble` nodes in the ratio 10:1:2. Awesome! - -Since WorldEditAdditions v1.12, you can also use percentages: - -```weacmd -//replacemix dirt 33% sandstone 75% dry_dirt 10% cobble 15% -``` - -Note though that the percentages are internally converted to a 1-in-N chance and rounded down. - -Here are all the above examples together: - -```weacmd -//replacemix dirt stone -//replacemix dirt 5 stone -//replacemix stone stone_with_diamond stone_with_gold -//replacemix stone stone_with_diamond stone_with_gold 4 -//replacemix dirt 3 sandstone 10 dry_dirt cobble 2 -``` - - -### `//revolve []` -Makes a given number of copies of the currently defined region (bounded by pos1 and pos2) at a given number of equally spaced points rotated around a given pivot/origin point. - -For example, `//revolve 4` would make rotated copies of the currently defined region at intervals 0° (the source to copy), 90°, 180°, and 270° around the given pivot point. - -`pivot_point_number` is the number of the defined position that should act as the pivot point, or origin for the revolve operation. It defaults to the last position defined. Note that it cannot be pos1 or pos2, as these are used to define the region that should be rotated. Use the [multi-point wand](#multi) to define a position with an index of 3 or more. - -```weacmd -//revolve 4 -//revolve 6 6 -``` - - -## Terrain - - - -### `//convolve [[,]] []` -Advanced version of `//smooth` from we_env, and one of the few WorldEditAdditions commands to have any aliases (`//smoothadv` and `//conv`). - -Extracts a heightmap from the defined region and then proceeds to [convolve](https://en.wikipedia.org/wiki/Kernel_(image_processing)) over it with the specified kernel. The kernel can be thought of as the filter that will be applied to the heightmap. Once done, the newly convolved heightmap is applied to the terrain. - -Possible kernels: - -Kernel | Description -----------------|------------------------------ -[`box`](https://en.wikipedia.org/wiki/Box_blur) | A simple uniform box blur. -`pascal` | A kernel derived from the odd layers of [Pascal's Triangle](https://en.wikipedia.org/wiki/Pascal%27s_triangle). Slightly less smooth than a Gaussian blur. -[`gaussian`](https://en.wikipedia.org/wiki/Gaussian_blur) | The default. A Gaussian blur - should give the smoothest result, and also the most customisable - see below. - -If you can think of any other convolutional filters that would be useful, please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new). The code backing this command is very powerful and flexible, so adding additional convolutional filters should be pretty trivial. - -The width and height (if specified) refer to the dimensions of the kernel and must be odd integers and are separated by a single comma (and _no_ space). If the height is not specified, it defaults to the width. If using the `gaussian` kernel, the width and height must be identical. Larger kernels are slower, but produce a more smoothed effect and take more nearby nodes into account for every column. Defaults to a 5x5 kernel. - -The sigma value is only applicable to the `gaussian` kernel, and can be thought of as the 'smoothness' to apply. Greater values result in more smoothing. Default: 2. See the [Gaussian blur](https://en.wikipedia.org/wiki/Gaussian_blur) page on Wikipedia for some pictures showing the effect of the sigma value. - -```weacmd -//convolve -//convolve box 7 -//convolve pascal 11,3 -//convolve gaussian 7 -//convolve gaussian 9 10 -//convolve gaussian 5 0.2 -``` - - -### `//overlay [] [] [ []] ...` -Places `` in the last contiguous air space encountered above the first non-air node. In other words, overlays all top-most nodes in the specified area with ``. Optionally supports a mix of node names and chances, as `//mix` (WorldEdit) and `//replacemix` (WorldEditAdditions) does. - -Will also work in caves, as it scans columns of nodes from top to bottom, skipping every non-air node until it finds one - and only then will it start searching for a node to place the target node on top of. - -Note that all-air columns are skipped - so if you experience issues with it not overlaying correctly, try `//expand down 1` to add an extra node's space to your defined region. - -Note also that columns without any air nodes in them at all are also skipped, so try `//expand y 1` to add an extra layer to your defined region. - -```weacmd -//overlay grass -//overlay glass -//overlay grass_with_dirt -//overlay grass_with_dirt 10 dirt -//overlay grass_with_dirt 10 dirt 2 sand 1 -//overlay sandstone dirt 2 sand 5 -//overlay dirt 90% stone 10% -``` - - -### `//fillcaves []` -Fills in all airlike nodes beneath non airlike nodes, which gives the effect of filling in caves. Defaults to filling in with stone, but this can be customised. - -Note that the *entire* cave you want filling must be selected, as `//fillcaves` only operates within the defined region (ref #50). - -```weacmd -//fillcaves -//fillcaves dirt -//fillcaves brick -``` - - - -### `//layers [] [ []] [ []] ...` -Finds the first non-air node in each column and works downwards, replacing non-air nodes with a defined list of nodes in sequence. Like WorldEdit for Minecraft's `//naturalize` command, and also similar to [`we_env`'s `//populate`](https://github.com/sfan5/we_env). Speaking of, this command has `//naturalise` and `//naturalize` as aliases. Defaults to 1 layer of grass followed by 3 layers of dirt. - -Since WorldEditAdditions v1.13, a maximum and minimum slope is optionally accepted, and constrains the columns in the defined region that `//layers` will operate on. For example, specifying a value of `20` would mean that only columns with a slop less than or equal to 20° (degrees, not radians) will be operated on. A value of `45..60` would mean that only columns with a slope between 45° and 60° will be operated on. - -The list of nodes has a form similar to that of a chance list you might find in `//replacemix`, `//overlay`, or `//mix` - see the examples below. If the number of layers isn't specified, `1` is assumed (i.e. a single layer). - - -```weacmd -//layers dirt_with_grass dirt 3 -//layers sand 5 sandstone 4 desert_stone 2 -//layers brick stone 3 -//layers cobble 2 dirt -//layers 45..60 dirt_with_snow dirt 2 -//layers 30 snowblock dirt_with_snow dirt 2 -``` - - -### `//erode [ [ []] [ []] ...]` -Runs an erosion algorithm over the defined region, optionally passing a number of key - value pairs representing parameters that are passed to the chosen algorithm. This command is **experimental**, as the author is currently on-the-fence about the effects it produces. - -Works best if you run `//fillcaves` first, or otherwise have no air nodes below the top non-air node in each column. - -Currently implemented algorithms: - -Algorithm | Mode | Description -------------|-------|------------------- -`snowballs` | 2D | The default - based on [this blog post](https://jobtalle.com/simulating_hydraulic_erosion.html). Simulates snowballs rolling across the terrain, eroding & depositing material. Then runs a 3x3 gaussian kernel over the result (i.e. like the `//conv` / `//smoothadv` command). -`river` | 2D | Fills in potholes and lowers pillars using a cellular automata-like algorithm that analyses the height of neighbouring columns. - -Usage examples: - -```weacmd -//erode -//erode snowballs -//erode snowballs count 25000 -``` - -Each of the algorithms above have 1 or more parameters that they support. These are detailed below. - -#### Algorithm: `snowballs` -Based on the algorithm detailed in [this blog post](https://jobtalle.com/simulating_hydraulic_erosion.html) ([direct link to the source code](https://github.com/jobtalle/HydraulicErosion/blob/master/js/archipelago/island/terrain/erosionHydraulic.js)), devised by [Job Talle](https://jobtalle.com/). - -Parameter | Type | Default Value | Description ---------------------|-----------|-------------------|-------------------------- -rate_deposit | `float` | 0.03 | The rate at which snowballs will deposit material -rate_erosion | `float` | 0.04 | The rate at which snowballs will erode material -friction | `float` | 0.07 | More friction slows snowballs down more. -speed | `float` | 1 | Speed multiplier to apply to snowballs at each step. -max_steps | `float` | 80 | The maximum number of steps to simulate each snowball for. -velocity_hist_count | `float` | 3 | The number of previous history values to average when detecting whether a snowball has stopped or not -init_velocity | `float` | 0.25 | The maximum random initial velocity of a snowball for each component of the velocity vector. -scale_iterations | `float` | 0.04 | How much to scale erosion by as time goes on. Higher values mean that any given snowball will erode more later on as more steps pass. -maxdiff | `float` | 0.4 | The maximum difference in height (between 0 and 1) that is acceptable as a percentage of the defined region's height. -count | `float` | 25000 | The number of snowballs to simulate. -noconv | any | n/a | When set to any value, disables to automatic 3x3 gaussian convolution. - -Usage examples: - -```weacmd -//erode -//erode snowballs -//erode snowballs count 50000 -``` - -If you find any good combinations of these parameters, please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new) (or a PR!) and let me know! I'll include good combinations here, and possibly add a presets feature too. - -#### Algorithm: `river` -Ever been annoyed by small 1 wide holes or thin pillars all over the place? This command is for you! Does not operate on the very edge of the defined region, because the algorithm can't see the neighbours of those columns. - -Parameter | Type | Default Value | Description ---------------------|-----------|-------------------|-------------------------- -steps | `integer` | 1 | The number of rounds or passes of the algorithm to run. Useful if you have a 1x3 hole for instance, it will take at least 2 steps to fill it in - and more if it's deeper than 1 node. -lower_sides | `string` | 4,3 | Comma separated list of numbers. Columns with this many sides lower than it will be lowered in height by 1 node. -raise_sides | `string` | 4,3 | Comma separated list of numbers. Columns with this many sides higher than it will be raised in height by 1 node. -doraise | `boolean` | true | Whether to raise columns in height. If false, then no columns will be raised in height even if they are eligible to be so according to `raise_sides`. -dolower | `boolean` | true | Whether to lower columns in height. If false, then no columns will be lowered in height even if they are eligible to be so according to `lower_sides`. - -Usage examples: - -```weacmd -//erode river -//erode river steps 10 -``` - - -### `//noise2d [ []] [ []] ...]` -Applies 2D noise to the terrain in the defined region. Like `//erode`, this command accepts a number of different key-value parameters and provides a number of different underlying algorithms. - -In other words, this command changes the height of the terrain according to some noise function (e.g. Perlin noise): - -![//noise2d applies 2D noise as a modifier to terrain height.](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/dev/.docs/images/reference/noise2d.jpeg) - -It does so like this: - -1. Take coordinates of each column -2. Plug them through a noise function (see below) -3. Apply the generated noise value to the terrain. - -`//noise2d` has a number of parameters that let you adjust the mathematical properties of step 2, which are explained in the table below. - -Some terms that are useful to know: - -- **Scale:** How big or small the noise is. Lower values stretch it out to be bigger, and higher values squash it in. -- **Offset:** Noise is calculated by passing some coordinates into a function. -- **Perlin:** A noise algorithm. `//noise2d` defaults to this. - - -#### Table of parameters - -Parameter | Type | Default Value | Description -------------|-----------|---------------|----------------------- -algorithm | `string` | perlinmt | The 2D noise algorithm to apply - see below. -apply | `string¦integer` | 5 | How to apply the noise to the terrain - see below. -scale | `float` | 1 | Sets `scalex`, `scaley`, and `scalez` all at once. Consider also `//apply`. -scalex | `float` | 1 | The scale of the noise on the x axis. -scaley | `float` | 1 | The scale of the noise on the y axis. -scalez | `float` | 1 | The scale of the noise on the z axis. -offsetx | `float` | 1 | The offset to add to the x axis before calling the noise function. -offsety | `float` | 0 | The offset to add to the y axis before calling the noise function. -offsetz | `float` | 0 | The offset to add to the z axis before calling the noise function. -exponent | `float` | 0 | Raise the generated noise value (with a range of 0 to 1) to this power. Generally results in sharper peaks. -multiply | `float` | 1 | Multiply the generated noise value by this number -add | `float` | 0 | Add this number to the generated noise value. - -#### Apply -Different values of the `apply` parameter result in the generated noise values being applied in different ways: - -1. An integer indicates that the noise should be rescaled to a given amplitude (equal parts of the range above and below 0) before being added to the terrain heightmap.` -2. The exact string `add`: Noise values are added to each heightmap pixel. -3. The exact string `multiply`: Each heightmap pixel is multiplied by the corresponding noise value. - -An integer is the most common way to use `//noise2d`. So, for example: - -```weacmd -//noise2d apply 5 -``` - -...would alter the height of each column of nodes by at most 5 blocks either side, while: - -```weacmd -//noise2d apply 10 -``` - -...would alter the height by 10 blocks instead of 5. - -#### Types of noise -Another thing that can be changed is the noise algorithm. This changes what the noise that is applied to the terrain looks like. - -The following algorithms are currently available: - -Algorithm | Description -------------|-------------------------- -`perlinmt` | **Default**. Perlin noise, backed by Minetest's inbuilt `PerlinNoise` class. -`perlin` | Perlin noise, backed by a pure Lua perlin noise implementation. Functional, but currently contains artefacts I'm having difficulty tracking down. -`sin` | A sine wave created with `math.sin()`. -`white` | Random white noise. In other words, just random values. -`red` | Red noise - has a lower frequency than white noise. Ref [Noise Functions and Map Generation by Red Blob Games](https://www.redblobgames.com/articles/noise/introduction.html). -`infrared` | Even smoother than red noise. Tends to also be quite flat unless you use a slightly higher `apply` value (e.g. `20`). - -When specifying algorithm names, the `algorithm` parameter name is optional. For example, the following are both equivalent: - -```weacmd -//noise2d offsetx 4 perlin scale 0.2 -//noise2d offsetx 4 algorithm perlin scale 0.2 -``` - -#### Further examples -Example invocations: - -```weacmd -//noise2d sin scale 0.5 -//noise2d offsetx 20 perlin -//noise2d sin exponent 4 -``` - - -### `//sculptlist [preview]` -Lists all the available sculpting brushes for use with `//sculpt`. If the `preview` keyword is specified as an argument, then the brushes are also rendered in ASCII as a preview. See [`//sculpt`](#sculpt). - -``` -//sculptlist -//sculptlist preview -``` - - -### `//sculpt [ [ []]]` -Applies a specified brush to the terrain at position 1 with a given height and a given size. Multiple brushes exist (see [`//sculptlist`](#sculptlist)) - and are represented as a 2D grid of values between 0 and 1, which are then scaled to the specified height. The terrain around position 1 is first converted to a 2D heightmap (as in [`//convolve`](#convolve) before the brush "heightmap" is applied to it. - -Similar to [`//sphere`](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md#sphere-radius-node), [`//cubeapply 10 set`](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md#cubeapply-sizesizex-sizey-sizez-command-parameters), or [`//cylinder y 5 10 10 dirt`](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md#cylinder-xyz-length-radius1-radius2-node) (all from [WorldEdit](https://content.minetest.net/packages/sfan5/worldedit/)), but has a number of added advantages: - - - No accidental overhangs - - Multiple custom brushes (see below on how you can add your own!) - -A negative height value causes the terrain to be lowered by the specified number of nodes instead of raised. - -While sculpting brushes cannot yet be rotated, this is a known issue. Rotating sculpting brushes will be implemented in a future version of WorldEditAdditions. - -The selection of available brushes is limited at the moment, but see below on how to easily create your own! - -``` -//sculpt -//sculpt default 25 3 -//sculpt ellipse -//sculpt circle 50 3 -``` - -#### Create your own brushes -2 types of brush exist: - -1. Dynamic (lua-generated) brushes -2. Static brushes - -All brushes are located in `worldeditadditions/lib/sculpt/brushes` (relative to the root of WorldEditAdditions' installation directory). - -Lua-generated brushes are not the focus here, but are a file with the extension `.lua` and return a function that returns a brush - see other existing Lua-generated brushes for examples (and don't forget to update `worldeditadditions/lib/sculpt/.init.lua`). - -Static brushes on the other hand are simply a list of tab-separated values arranged in a grid. For example, here is a simple brush: - -```tsv -0 1 0 -1 2 1 -0 1 0 -``` - -Values are automatically rescaled to be between 0 and 1 based on the minimum and maximum values, so don't worry about which numbers to use. Static brushes are saved with the file extension `.brush.tsv` in the aforementioned directory, and are automatically rescanned when your Minetest server starts. While they can't be rescaled automatically to fix a target size (without creating multiple variants of a brush manually of course, though this may be implemented in the future), static brushes are much easier to create than dynamic brushes. - -To assist with the creation of static brushes, a tool exists to convert any image to a static brush: - - - -The tool can operate on the colour channel of your choice - red, green, blue, or alpha. - -If you've created a cool new brush (be it static or dynamic), **please contribute it to WorldEditAdditions**! That way, everyone can enjoy using your awesome brush. [WorldPainter](https://www.worldpainter.net/) has many brushes available in the community, but `//sculpt` for WorldEditAdditions is new so don't have the same sized collection yet :-) - -To contribute your new brush back, you can either [open a pull request](https://github.com/sbrl/Minetest-WorldEditAdditions/pulls) if you're confident using GitHub, or [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues) with your brush attached if not. - - - -## Flora - - - -### `//forest [] [] [] [ []] ...` -Plants and grows saplings to generate a forest. A density value is optionally taken, which controls the overall density of the forest that is generated. The `bonemeal` mod is required - just like for the [`//bonemeal`](#bonemeal-strength-chance) command. - -The density defaults to 1, acts like a multiplier, and is not affected by the chances of all saplings listed (e.g. you can have a sapling with a chance of 1-in-50, and the overall density of the forest will be unaffected). For example, 2 results in a forest twice as dense as the default, and 0.5 a forest half as dense as the default density. - -The tree types are provided as a list of names and 1-in-N chances, just like [`//overlay`](#overlay-node_name_a-chance_a-node_name_b-chance_b-node_name_n-chance_n-), `//mix`, `//layers`, etc. Unlike the aforementioned commands however, `//forest` has an additional layer of alias resolution to ease the process of determining what the name of the sapling is you want to use to generate forests with. See [`//saplingaliases`](#saplingaliases-aliasesall_saplings) for more details. - -Saplings are placed with [`//overlay`](#overlay-node_name_a-chance_a-node_name_b-chance_b-node_name_n-chance_n-) and grown using the same method that's used by the `//bonemeal` command. Up to 100 attempts are made to grow placed saplings. If all of those attempts fail (success is determined by whether the sapling is still present or not), the sapling is removed and the failure counter is incremented. - -Currently, the following mods are known to have aliases registered: - - - `default` - - [`moretrees`](https://content.minetest.net/packages/VanessaE/moretrees/) (warning: these saplings don't appear to work very well this command - assistance in debugging this would be very helpful) - - [`cool_trees`](https://content.minetest.net/packages/runs/cool_trees/) - -If you like, you can also reference the full name of a sapling node instead. The only requirements for saplings to be supported by this mod are: - -1. It can be bonemealed -2. It has the `sapling` group - -For example, the first 2 examples below are functionally equivalent. - -```weacmd -//forest aspen -//forest default:aspen_sapling -//forest 2 oak 3 aspen pine -//forest 0.5 acacia -``` - - -### `//saplingaliases [aliases|all_saplings]` -Lists all the currently registered sapling aliases in alphabetical order. These aliases can be used in the `//forest` subcommand. - -Optionally takes a single parameter, which is the operating mode. Current implemented operating modes: - -Mode | Description -----------------|---------------------- -`aliases` | The default. Lists all the currently registered sapling aliases in alphabetical order. -`all_saplings` | Spins through all the nodes currently registered in Minetest, and lists all the nodes that have the `sapling` group. - -```weacmd -//saplingaliases -//saplingaliases all_saplings -//saplingaliases aliases -``` - - - -### `//bonemeal [ [ [ [ ...]]]]` -Requires the [`bonemeal`](https://content.minetest.net/packages/TenPlus1/bonemeal/) ([repo](https://notabug.org/TenPlus1/bonemeal/)) mod (otherwise _WorldEditAdditions_ will not register this command and output a message to the server log). Alias: `//flora`. - -Bonemeals all eligible nodes in the current region. An eligible node is one that has an air node directly above it - note that just because a node is eligible doesn't mean to say that something will actually happen when the `bonemeal` mod bonemeals it. - -Optionally takes a strength value (that's passed to `bonemeal:on_use()`, the method in the `bonemeal` mod that is called to actually do the bonemealing). The strength value is a positive integer from 1 to 4 (i.e. 1, 2, 3, or 4) - the default is 1 (the lowest strength). - -I observe that a higher strength value gives a higher chance that something will actually grow. In the case of soil or sand nodes, I observe that it increases the area of effect of a single bonemeal action (thus at higher strengths generally you'll probably want a higher chance number - see below). See the [`bonemeal` mod README](https://notabug.org/TenPlus1/bonemeal) for more information. - -Also optionally takes a chance number. This is the chance that an eligible node will actually get bonemealed, and is a positive integer that defaults to 1. The chance number represents a 1-in-{number} chance to bonemeal any given eligible node, where {number} is the chance number. In other words, the higher the chance number the lower the chance that a node will be bonemealed. - -For example, a chance number of 2 would mean a 50% chance that any given eligible node will get bonemealed. A chance number of 16 would be a 6.25% chance, and a chance number of 25 would be 2%. - -Since WorldEditAdditions v1.12, a percentage chance is also supported. This is denoted by suffixing a number with a percent sign (e.g. `//bonemeal 1 25%`). - -Since WorldEditAdditions v1.13, a list of node names is also optionally supported. This will constrain bonemeal operations to be performed only on the node names listed. - - -```weacmd -//bonemeal -//bonemeal 3 25 -//bonemeal 4 -//bonemeal 1 10 -//bonemeal 2 15 -//bonemeal 2 10% -//bonemeal 2 10% dirt -//bonemeal 4 50 ethereal:grove_dirt -``` - - - -## Statistics - - - -### `//count` -Counts all the nodes in the defined region and returns the result along with calculated percentages (note that if the chat window used a monospace font, the returned result would be a perfect table. If someone has a ~~hack~~ solution to make the columns line up neatly, please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new) :D) - -> [!NOTE] -> The output of `//count` can be rather long sometimes, and Minetest by default only shows the last few lines of chat. Press F10 to show the full chat window that you can then scroll through to inspect the full output. - -```weacmd -//count -``` - - -### `//basename ` -Returns the absolute canonical name of a node, given an alias or partial node name. For example: - -```weacmd -//basename dirt -``` - -...will return `default:dirt`. Uses `worldedit.normalize_nodename(string)` under the hood. - -```weacmd -//basename stonebrick -//basename glass -``` - - -### `//ngroups [v[erbose]]` -Lists the groups that a given node is a member of. For example: - -```weacmd -//ngroups sand -``` - -Might return: - -``` -default:sand ∈ sand crumbly falling_node -``` - -Groups in Minetest can also have a numerical value greater than 0. Append `v` or `verbose` to see those values: - -```weacmd -//ngroups sand v -//ngroups sand verbose -``` - -...both of the above might produce an output like this: - -``` -default:sand ∈ sand=1 crumbly=3 falling_node=1 -``` - -Finally, the customary misc examples: - -```weacmd -//ngroups sand -//ngroups bakedclay:orange v -//ngroups cactus -//ngroups default:dry_shrub v -``` - -### `//ndef ` -Short for *Node Definition*. Prints the definition table for the node with the given name. In other words. the output could look a little like this: - -``` -stairs:stair_birch_wood { - description = (string) "Birch Wood Stair" - sounds = (table) { - dig = (table) { - name = (string) "default_dig_choppy" - gain = (number) 0.4 - } - place = (table) { - name = (string) "default_place_node_hard" - gain = (number) 1 - } - dug = (table) { - name = (string) "default_wood_footstep" - gain = (number) 1 - } - footstep = (table) { - name = (string) "default_wood_footstep" - gain = (number) 0.15 - } - } - name = (string) "stairs:stair_birch_wood" - light_source = (number) 0 - mod_origin = (string) "ethereal" - selection_box = (table) { - fixed = (table) { - 1 = (table) [truncated] - 2 = (table) [truncated] - } - type = (string) "fixed" - } - paramtype = (string) "light" - groups = (table) { - flammable = (number) 3 - stair = (number) 1 - choppy = (number) 2 - oddly_breakable_by_hand = (number) 1 - } - is_ground_content = (boolean) false - on_place = (function) function: 0x765b01d0edb8 - drawtype = (string) "nodebox" - tiles = (table) { - 1 = (table) { - name = (string) "moretrees_birch_wood.png" - backface_culling = (boolean) true - } - } - paramtype2 = (string) "facedir" - sunlight_propagates = (boolean) false - node_box = (table) { - fixed = (table) { - 1 = (table) [truncated] - 2 = (table) [truncated] - } - type = (string) "fixed" - } - type = (string) "node" -} -``` - -This command is intended for debugging and development purposes, but if you're implementing a mod yourself you might find it useful too. - -```weacmd -//ndef stone -//ndef stairs:stair_birch_wood -//ndef glass -``` - -### `//uasparse ` -Short for *Unified Axis Syntax Parse*. Parses the given UAS expression and prints the resulting vectors to the chat window. - -```weacmd -//uasparse front right 5 -//uasparse y 12 h -2 -//uasparse left 3 up 5 -front 7 -//uasparse -z 12 -y -2 x -2 -``` - - - -## Selection - - -### Unified Axis Syntax (UAS) -The Unified Axis Syntax system allows users to input direction and distance information in three dimensions using "natural" measurement syntax. The key features include axis clumping, double negatives, relative directions, mirroring and compass directions (more information below). - -*Note: negatives can be applied to axes, directions **AND** distances* - -#### Relative Directions -|Key Words | Interpretation| -|----------|---------------| -|`f[ront]\|facing\|?` | The direction the player is facing most toward in the world -|`b[ack]\|behind\|rear` | The opposite of the direction the player is facing most toward in the world -|`l[eft]` | The direction to the left of the player -|`r[ight]` | The direction to the right of the player - -```weacmd -back 1 -f r 4 --facing 13 -``` - -#### Compass Directions -|Key Words | Interpretation| -|----------|---------------| -|`n[orth]` | z -|`s[outh]` | -z -|`e[ast]` | x -|`w[est]` | -x -|`u[p]` | y -|`d[own]` | -y - -```weacmd -south 3 -north west 5 -e d -2 -``` - -#### Axis Clumping -Supported axes are `x`, `y`, `z`, `h`, `v`. All horizontal axes are covered by `h` and both vertical ones are covered by `v`. - -- `h 5` == `xz -xz 5` == `x 5 z 5 x -5 z -5` -- `v 5` == `up down 5` == `y -y 5` -- `vxz 5` == `xyz -y 5` == `xyz 5 y -5` - -#### Inference and Omnidirectionality -The UAS parser takes command input that is split by whitespace and interprets it as a series of numbers preceded by directional cues. If a number is preceded by another number or nothing it assumes that the number is to be applied on all axes in both positive and negative directions. - -- `10` == `hv 10` == `xyz -xyz 10` -- `x 3 6` == `x 3 hv 6` - -From the above examples you can also see the principle of inference. All direction modifiers before a value are interpreted as belonging to that value. So `x v 5` is equivalent to `x 5 v 5` and `xv 5`. - -Because UAS parses "natural" measurement syntax, there are many ways to express the same direction and distance. This caters to users with different ways of thinking and different play styles which will hopefully make the tools easier to use. - -### `//unmark` -Hides the in-game UI that indicates where the current positions and region are located. - -This hides both the WorldEditAdditions *and* the WorldEdit UI if displayed, but does **not** change or remove any points that are registered. - -Should more than 2 points be defined, they are all hidden. - -```weacmd -//unmark -``` - -### `//mark` -Shows the in-game UI that indicates where the current positions and region are located once more. - -Should more than 2 points be defined, they are all shown once more. - -Often used after calling [`//unmark`](#unmark) - -```weacmd -//mark -``` - - -### `//pos1` -Sets pos1 to the location of the calling player. - -This is, as with all other WorldEditAdditions commands, seamlessly synchronised with WorldEdit, allowing you to use any combination of WorldEditAdditions and WorldEdit commands and tools without them desynchronising from one another. - -**Aliases:** `//1` - -```weacmd -//pos2 -``` - -### `//pos2` -Sets pos1 to the location of the calling player. - -This is, as with all other WorldEditAdditions commands, seamlessly synchronised with WorldEdit, allowing you to use any combination of WorldEditAdditions and WorldEdit commands and tools without them desynchronising from one another. - -**Aliases:** `//2` - -```weacmd -//pos2 -``` - -### `//pos ` -Sets position with the given index `` to the location of the calling player. - -Should the index be less than or equal to 2, then as with all other WorldEditAdditions commands, seamlessly synchronised with WorldEdit, allowing you to use any combination of WorldEditAdditions and WorldEdit commands and tools without them desynchronising from one another. - -Should the index be greater than 2, the position will only be registered in WorldEditAdditions, as WorldEdit does not support defining more than 2 points. - -If no index is specified, an error is returned and nothing is done. - -```weacmd -//pos 1 -//pos 3 -//pos 45 -//pos 2 -``` - -### `//reset` -Clears all positions defined and the defined region. - -This also synchronises with WorldEdit, as all other WorldEditAdditions commands do. - -```weacmd -//reset -``` - - -### `//scol [ ] ` -> [!WARNING] -> **REMOVED** in v1.15 in favour of [`//srel`](#srel) -Short for _select column_. Sets the pos2 at a set distance along 1 axis from pos1. If the axis isn't specified, defaults the direction you are facing. Implementation thanks to @VorTechnix. - -```weacmd -//scol 10 -//scol x 3 -``` - -### `//srect [ []] ` -> [!WARNING] -> **REMOVED** in v1.15 in favour of [`//srel`](#srel) -Short for _select rectangle_. Sets the pos2 at a set distance along 2 axes from pos1. If the axes aren't specified, defaults to positive y and the direction you are facing. Implementation thanks to @VorTechnix. - -```weacmd -//srect x z 10 -//srect 3 -//srect -z y 25 -``` - - -### `//scube [ [ []]] ` -> [!WARNING] -> **REMOVED** in v1.15 in favour of [`//srel`](#srel) -Short for _select cube_. Sets the pos2 at a set distance along 3 axes from pos1. If the axes aren't specified, defaults to positive y, the direction you are facing and the axis to the left of facing. Implementation thanks to @VorTechnix. - -```weacmd -//scube 5 -//scube z a y 12 -//scube x z 3 -//scube -z 12 -``` - - -### `//scloud <0-6|stop|reset>` -Short for _select point cloud_. Sets pos1 and pos2 to include the nodes you punch. Numbers 1-6 designate how many nodes you want to punch before the operation ends. 0 or stop terminate the operation so that any further nodes you punch won't be added to selection. Reset terminates operation if one is running and resets the selection area. - -```weacmd -//scloud 6 -//scloud 5 -//scloud stop -``` - - -### `//scentre` -Short for _select center_. Sets pos1 and pos2 to the centre point(s) of the current selection area. 1, 2, 4 or 8 nodes may be selected depending on what parts of the original selection are even in distance. Implementation thanks to @VorTechnix. - -```weacmd -//scentre -``` - -### `//srel ` -Short for _select relative_. Sets the pos2 at set distances along 3 axes relative to pos1. If pos1 is not set it will default to the node directly under the player. The axis arguments accept `x, y, z` as well as `up, down, left, right, front, back`. Left, right, front and back are relative to player facing direction. Negative (`-`) can be applied to the axis, the length or both. Implementation thanks to @VorTechnix. - -```weacmd -//srel front 5 -//srel y 12 right -2 -//srel left 3 up 5 -front 7 -//srel -z 12 -y -2 x -2 -``` - -### `//sgrow ` -Short for _selection grow_. Grows the current selection along specified axes/directions. -Aliases: `//extend`, `//outset`. - -```weacmd -//sgrow back 4 -//sgrow left -2 v r 2 -//sgrow h 4 -//sgrow -zy -2 x -2 -``` - -### `//sshrink ` -Short for _selection shrink_. Shrinks the current selection along specified axes/directions. -Aliases: `//contract`, `//inset`. - -```weacmd -//sshrink left 4 -//sshrink right -2 up 2 -//sshrink v 4 -//sshrink -hy 2 x -3 true -``` - -### `//sshift ` -Short for _selection shift_. Shifts the WorldEdit region along 3 axes. The axis arguments accept `x, y, z` as well as `up, down, left, right, front, back`. Left, right, front and back are relative to player facing direction. Negative (`-`) can be applied to the axis, the length or both. Implementation thanks to @VorTechnix. - -```weacmd -//sshift back 4 -//sshift right -2 up 2 -//sshift -left 2 z -7 -y -4 -//sshift -z 12 -y -2 x -2 -``` - -### `//smake [ []]` -Short for _selection make_. Modifies existing selection by moving pos2. Allows you to make the selection an odd or even length on one or more axes or set two or more axes equal to each other or the longest, shortest or average of them. Implementation thanks to @VorTechnix. - -Usage examples: - -```weacmd -//smake odd shrink -//smake even avg xz -//smake equal grow xy -//smake equal average -//smake equal zy x -``` - -#### ``: odd|even|equal - -Value | Description ---------|--------------- -`odd` | Round up or down, based on mode, all axes specified in `` to the nearest odd length relative to pos1 -`even` | Round up or down, based on mode, all axes specified in `` to the nearest even length relative to pos1 -`equal` | Set `` axes length equal to the length of `` axis if specified or to the length of the largest, smallest or average of the `` axes based on mode. - -#### ``: grow|shrink|average - -#### *If `` == odd or even:* - -Value | Description -----------------|-------------- -`grow` | Grow each axis specified in `` to the nearest odd/even number to itself -`shrink` | Shrink each axis specified in `` to the nearest odd/even number to itself -`average`/`avg` | Takes the average of all axes specified in `` and then for each specified axis grows or shrinks it, depending on whether it is less than or greater than the average, to the nearest odd/even number to itself - -#### *If `` == equal:* -The `` argument can be omitted and will not be parsed if present if `` is specified - -Value | Description -----------------|--------------- -`grow` | Grow each axis specified in `` to the length of the longest specified axis -`shrink` | Shrink each axis specified in `` to the length of the shortest specified axis -`average`/`avg` | Set each axis specified in `` to the average length of all the specified axes -If `` | `` becomes optional. If present it will be ignored. - -#### Additional arguments: - -Name | Description -------------|------------------ -`` | Specify axes to perform operation on (default= xz)| -``: If `` == odd or even | Does nothing -``: If `` == equal | Overrides `` and sets all `` axes equal to itself - -### `//sfactor []` -> [!WARNING] -> **REMOVED** in v1.15 in favour of [`//sgrow`](#sgrow) and [`//sshrink`](#sshrink) -Short for _selection factor_; alias: `//sfac`. Built specifically for use with `//maze`, this command sets targeted axes equal to the nearest multiple of `` based on the ``. - -Usage examples: - -```weacmd -//sfac grow 5 -//sfac avg 3 xy -``` - -#### ``: grow|shrink|average - -Value | Description ---------|-------------- -`grow` | Rounds the length of each target axis up to the nearest multiple of `` -`shrink` | Rounds the length of each target axis down to the nearest multiple of `` -`average`/`avg` | Takes the average of all axes specified in `` and then for each specified axis grows or shrinks it, depending on whether it is less than or greater than the average, to the nearest multiple of `` - -### `//sstack` -Displays the contents of your per-user selection stack. This stack can be pushed to and popped from rather like a stack of plates. See also `//spush` (for pushing to the selection stack) and `//spop` (for popping from the selection stack). - -```weacmd -//sstack -``` - -### `//spush` -Pushes the currently defined region onto your per-user selection stack. Does not otherwise alter the defined region. - -If the stack is full (currently the limit is set to 100 regions in the stack), then it will complain at you but otherwise will have no effect. - -Note that pos2 does _not_ need to be defined in order to use this. if it isn't defined, then a pos2 of `nil` will be pushed onto the stack instead. - -```weacmd -//spush -``` - -### `//spop` -Pops a selection off your per-user selection stack and applies it to the currently defined region. If pos2 from the item popped from the stack is nil, then pos2 is explicitly unset. If the stack is empty, this has no effect. - -```weacmd -//spop -``` - - - -## Measurement - - - -### `//mcount` -Alias for [`//count`](#count). - -``` -//mcount -``` - - -### `//mface` -Returns the horizontal (X/Z) axis or axes the player is looking along. -Aliases: `//mfacing`. - -``` -//mface -``` - - -### `//midpos` -Returns the coordinates of the centre of the current selection. - -``` -//midpos -``` - - -### `//msize` -Returns the lengths of the current selection on the X, Y and Z axes. - -``` -//msize -``` - - -### `//mtrig` -Returns the length of the diagonal from pos1 to pos2 and its angle on the XZ (horizontal) and Y (vertical) axes. - -``` -//mtrig -``` - - - -## Meta - - - -### `//subdivide ` -Splits the current WorldEdit region into `(, , )` sized chunks, and run `// ` over each chunk. - -Sometimes, we want to run a single command on a truly vast area. Usually, this results in running out of memory. If this was you, then this command is just what you need! It should be able to handle any sized region - the only limit is your patience for command to complete..... - -Note that this command only works with WorldEdit commands, and only those which require 2 points (e.g. `//torus` only requires a single point, so it wouldn't work very well - but `//set` or `//clearcut` would). - -Note also that `` should _not_ be prefixed with _any_ forward slashes - see the examples below. - -While other server commands can be executed while a `//subdivide` is running, `//subdivide` manipulates your player's defined region when running. This has the side-effect that you can check on where it has got up to with `//p get` for example - but means that attempting to change your pos1 & pos2 manually will have no effect until the `//subdivide` completes. - -> [!WARNING] -> Once started, this command cannot be stopped without restarting your server! This is the case with all WorldEdit commands, but it's worth a special mention here. - -```weacmd -//subdivide 10 10 10 set dirt -//subdivide 25 25 25 fixlight -``` - - -### `//multi .....` -Executes multi chat commands in sequence. Intended for _WorldEdit_ commands, but does work with others too. Don't forget a space between commands! - -```weacmd -//multi //set dirt //shift x 10 //set glass -``` - -Since WorldEditAdditions v1.12, curly brace syntax has also been introduced to allow nesting of commands: - -```weacmd -//multi //fixlight {//many 5 //bonemeal 3 100} -``` - -This syntax can also be nested arbitrarily in arbitrarily complex combinations, and can also be used multiple separate times in a single `//multi` invocation (if you find a bug, please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new)), though do remember that only `//multi` supports parsing out this syntax (e.g. if you want to nest multiple commands in a `//many` that's inside a `//multi`, you'll need a sub `//multi` there). - -In addition, this also allows for including a double forward slash in the argument list for a command, should you need to do so (e.g. `//multi //example {//bar //baz} //example` will be executed as 3 commands: `/example`, then `/bar` with an argument of `//baz`, then finally `/example`). - -```weacmd -//multi //1 //2 //shift z -10 //sphere 5 sand //shift z 20 //ellipsoid 5 3 5 ice -//multi //1 //hollowtorus 30 5 stone //hollowtorus 20 3 dirt //torus 10 2 dirt_with_grass -//multi /time 7:00 //1 //outset h 20 //outset v 5 //overlay dirt_with_grass //1 //2 //sphere 8 air //shift down 1 //floodfill //reset -``` - - -### `//many ` -Executes a single chat command many times in a row. Uses `minetest.after()` to yield to the main server thread to allow other things to happen at the same time, so technically you could have multiple `//many` calls going at once (but multithreading support is out of reach, so only a single one will be executing at the same time). - -Note that this isn't necessarily limited to executing WorldEdit / WorldEditAdditions commands. Combine with `//multi` (see above) execute multiple commands at once for even more power and flexibility! - -```weacmd -//many 10 //bonemeal 3 100 -//many 100 //multi //1 //2 //outset 20 //set dirt -``` - - -### `//ellipsoidapply ` -Executes the given command, and then clips the result to the largest ellipsoid that will fit inside the defined region. The specified command must obviously take 2 positions - so for example `//set`, `//replacemix`, and `//maze3d` will work, but `//sphere`, `//torus`, and `//floodfill` won't. - -For advanced users, `//multi` is also supported - but make sure your modifications stay within the defined region - otherwise they will not be affected by the ellipsoidal clipping operation. - -```weacmd -//ellipsoidapply set dirt -//ellipsoidapply maze3d dirt 4 2 2 -//ellipsoidapply erode -//ellipsoidapply replacemix sand bakedclay:red bakedclay:orange -//ellipsoidapply layers desert_sand sand 2 desert_sandstone 4 sandstone 10 -``` - - -### `//airapply ` -Like [`//ellipsoidapply`](#ellipsoidapply), but instead only keeps changes that replace airlike nodes, and discards any other changes made. - -As with `//ellipsoidapply` for advanced users `//multi` is also supported - but make sure your modifications stay within the defined region - otherwise they be kept regardless, as `//airapply` only applies the masking to the nodes in the defined region. - -```weacmd -//airapply set sandstone -//airapply maze3d dirt 4 2 2 -``` - - -### `//nodeapply [] [... ] -- ` -**Aliases:** `//napply` - -It's got `apply` in the name, so as you might imagine it works the same as [`//ellipsoidapply`](#ellipsoidapply), [`//airapply`](#airapply), [`//noiseapply2d`](#noiseapply2d), etc. Only changes made by the given command that replace nodes on the list given will be replaced. For example: - -```weacmd -//nodeapply dirt -- set stone -``` - -....is equivalent to `//replace dirt stone`, in that although `//set stone` will set all nodes to stone, `//nodeapply` will only keep the changes made by `//set` that affect dirt. - -There are some special keywords you can use too: - -Keyword | Meaning -----------------|----------------------------------- -`liquidlike` | Targets all nodes that behave like a liquid. -`airlike` | Targets all nodes that behave like air. Basically like [`//airapply`](#airapply). - -To give a further example, consider this: - -```weacmd -//nodeapply liquidlike -- set river_water_source -``` - -...this will replace all liquid-like nodes (e.g. water, lava, etc) with river water. - -In addition, any node names prefixed an at sign `@` are considered group names. For example: `@crumbly` would allow changes only to nodes that are a member of the `crumbly` group: - -```weacmd -//nodeapply @crumbly -- layers dirt_with_grass dirt 3 stone 10 -``` - -More misc examples to end this command description, as is customary: - -```weacmd -//nodeapply stone -- layers dirt_with_grass dirt 3 -//nodeapply stone dirt sand -- layers bakedclay:natural 3 bakedclay:orange 2 bakedclay:red 3 bakedclay:natural 3 -//nodeapply liquidlike -- set air -//nodeapply airlike -- mix stone 3 dirt 2 -``` - - -### `//noiseapply2d ` -Like [`//ellipsoidapply`](#ellipsoidapply), but instead only keeps changes where a noise function (defaults to `perlinmt`, see [`//noise2d`](#noise2d)) returns a value greater than a given threshold value. - -Also takes a scale value that controls the scale of the noise - -higher values result in smaller "blobs". If you're operating on small areas, then a value of at least 10 is advised as "blobs" are by default on the scale of ~50 nodes. - -As with `//ellipsoidapply` for advanced users `//multi` is also supported - but make sure your modifications stay within the defined region - otherwise they be kept regardless, as `//noiseapply2d` only applies the masking to the nodes in the defined region. - -Any suggestions on how to provide more customisability without making this command more difficult to use or significantly more inconsistent with other `//*apply` functions are welcome - please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new). - -```weacmd -//noiseapply2d 0.5 10 set dirt -//noiseapply2d 0.4 3 layers dirt_with_snow dirt 3 stone 10 -``` - -### `//for ... do // %% ` -For a given list of values, executes the specified command for each value, replacing `%%` with each value. Implementation thanks to @VorTechnix. - -To better illustrate what happens, consider the following command: - -``` -//for dirt stone glass do //replacemix air 10 %% -``` - -This is equivalent to executing the following 3 commands in sequence: - -``` -//replacemix air 10 dirt -//replacemix air 10 stone -//replacemix air 10 glass -``` - -Here are some more examples: - -``` -//for meselamp brick snowblock bamboo:wood do //multi //maze %% //sshift y 5 -//for 5 10 15 do //torus %% 3 dirt xz -//for 1 2 3 4 5 do //multi //hollowcylinder y 1 5 meselamp //shift y %% -``` - - -### `//listentities` -Lists all currently loaded ObjectRefs. Displays their IDs, Names (if possible), and positions. - -This command is intended for development and modding. You will not normally need to use this command using WorldEditAdditions. - -`//listentities` takes no arguments. - -``` -//listentities -``` - - -## Extras - - - -### `//speed []` -Adjusts your player movement speed to the specified value. In other words: - -```weacmd -//speed 2 -``` - -...will double your movement speed. - -This command also takes Minetest's "Fast mode" into account and adjusts accordingly. Relative adjustments can be done by prepending either a `+` to increase or `-` to decrease respectively. - -```weacmd -//speed +0.5 -//speed -3 -``` - - -### `//y` -Confirms the execution of a command if it could potentially affect a large number of nodes and take a while. This is a regular WorldEdit command. - - - -```weacmd -//y -``` - - -### `//n` -Prevents the execution of a command if it could potentially affect a large number of nodes and take a while. This is a regular WorldEdit command. - - - -```weacmd -//n -``` - - - -## Tools - - -### Movement speed adjustment tool -The movement speed adjustment tool, as the name suggests, adjusts your local player movement speed. It looks like this: ![A picture of the move speed adjustment tool. It looks like a monarch butterfly.](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/dev/worldeditadditions_farwand/textures/worldeditadditions_movement.png). - -Primary (left) clicking will increase your movement speed, and secondary (right) clicking will decrease it in x0.5 increments, down to a minimum of x0.5. - -Note this only affects **you**, and **not any other player**. - -See also [`//speed`](#speed). - -### Far Wand -The far wand (`worldeditadditions:farwand`) is a variant on the traditional WorldEdit wand (`worldedit:wand`). It looks like this: ![A picture of the far wand](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/worldeditadditions_farwand/textures/worldeditadditions_farwand.png) - -It functions very similarly to the regular WorldEdit wand, except that it has a _much_ longer range - which can be very useful for working on large-scale terrain for example. It also comes with an associated command to control it. - -Note that punching out the positions **does not unset them**. Use `//reset` to reset the defined region. - -### `//farwand skip_liquid (true|false) | maxdist ` -This command helps control the behaviour of the [WorldEditAdditions far wand](#far-wand) and [cloud wand](#cloud-wand). Calling it without any arguments shows the current status: - -```weacmd -//farwand -``` - -You can decide whether you can select liquids or not like so: - -```weacmd -//farwand skip_liquid true -//farwand skip_liquid false -``` - -You can change the maximum range with the `maxdist` subcommand: - -```weacmd -//farwand maxdist 1000 -//farwand maxdist 200 -//farwand maxdist 9999 -``` - -Note that the number there isn't in blocks (because hard maths). It is however proportional to the distance the wand will raycast looks for nodes, so a higher value will result in it raycasting further. - -### Cloud Wand -The cloud wand (`worldeditadditions:cloudwand`) is a another variant the above _Far Wand_. It looks like this: ![A picture of the far wand](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/worldeditadditions_farwand/textures/worldeditadditions_cloudwand.png) - -Unlike the other 2 wands, this wand functions in an additive manner. Left-click on a node to expand the currently defined region (creating a new one if one isn't defined already) to include that node. Right click to clear the currently defined region. - -It has the range of the _Far Wand_ mentioned above too, so you can select nodes from a great distance. It also abides by preferences set via the `//farwand` chat command. - -Note that punching out the positions **does not unset them**. Use `//reset` to reset the defined region. - - -### MultiPoint Wand -The third type of wand provided by WorldEditAdditions is completely different, in that it allows you to select up to **999 points** at once! It looks like this: ![A picture of the multi-point wand](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/worldeditadditions_farwand/textures/worldeditadditions_multiwand.png) - -It is important to note that (at present) the points selected by this wand **are not compatible with normal points**. This will change in the future, but requires a lot of work to implement. - -It has the following actions: - - - **Left click:** Add a new point - - **Right click:** Undo adding a point - -It has the range of the other wands mentioned above though, so you can select nodes from a great distance. It also abides by preferences set via the `//farwand` chat command. +# Chat Command Reference + +This is the full chat command reference for WorldEditAdditions. Having trouble finding the section you want? Try the **[quick reference](https://github.com/sbrl/Minetest-WorldEditAdditions#quick-command-reference)** instead, which has links to back to sections of this document! + +**Check out the reference on the new website - it's even searchable: ** + +Other useful links: + + - [WorldEditAdditions quick reference](https://github.com/sbrl/Minetest-WorldEditAdditions#quick-command-reference) + - [WorldEditAdditions Chat Command Cookbook](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Cookbook.md) + - [WorldEdit Chat Command Reference](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md) + - [`we_env`](https://github.com/sfan5/we_env#readme) + +**Note:** If anything in this reference isn't clear, that's a bug. Please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new) (or even better a PR improving it) to let me know precisely which bit you don't understand and why. + +## Geometry + + +### `//metaball add | remove | render [] | list | clear | volume` +Draws two or more [metaballs](https://en.wikipedia.org/wiki/Metaballs). Based on a subcommand system, since each metaball may have a different radius. + +Calling `//metaball render ` actually makes changes to the world - all others manipulate an internal player-local list of metaballs to be drawn. + +#### `//metaball add ` +Adds a new metaball to the (player-local) list of metaballs to be draw with the given radius. The position of the new metaball is taken from pos1. + +```weacmd +//metaball add 5 +//metaball add 10 +//metaball add 65 +``` + +#### `//metaball remove ` +Removes the metaball with the given index from the list. See also `//metaball list`. + +```weacmd +//metaball remove 1 +//metaball remove 2 +//metaball remove 5 +``` + +#### `//metaball render []` +Renders the current list of metaballs to the world using replace_node to draw with. + +Threshold is a value that acts as an offset for large or small the metaballs should be. Defaults to 1, with larger values resulting in **smaller** metaballs and smaller values resulting in **larger** metaballs. It is not recommended to set threshold to a negative number. + +Does not clear the list of metaballs after rendering - see `//metaball clear` for that. + +```weacmd +//metaball render dirt +//metaball render glass +//metaball render stone +//metaball render stone 2 +//metaball render cobble 0.5 +``` + +#### `//metaball list` +Lists all the metaballs currently registered for the current player (all `//metaball` commands operate on the current player's metaball list only), and their indexes, positions, and sizes. Useful when using `//metaball remove ` to identify which metaball you want to remove. + +Example output: + +``` +Index Position Radius +1 (-495, 37, 150) 7 +2 (-506, 33, 142) 7 +3 (-516, 35, 152) 10 +``` + +```weacmd +//metaball list +``` + +#### `//metaball clear` +Clears the list of metaballs for the current player. + +```weacmd +//metaball clear +``` + +#### `//metaball volume` +Calculate an estimated volume of the metaballs currently in the list. + +```weacmd +//metaball volume +``` + + +### `//ellipsoid [h[ollow]]` +Creates a solid ellipsoid at position 1 with the radius `(rx, ry, rz)`. + +```weacmd +//ellipsoid 10 5 15 ice +//ellipsoid 3 5 10 dirt +//ellipsoid 20 10 40 air +//ellipsoid 14 5 8 steelblock h +//ellipsoid 7 4 7 papyrus hollow +``` + +### `//hollowellipsoid ` +Creates a hollow ellipsoid at position 1 with the radius `(rx, ry, rz)`. Works the same way as `//ellipsoid` does. + +```weacmd +//hollowellipsoid 10 5 15 glass +//hollowellipsoid 21 11 41 stone +``` + +### `//ellipsoid2 [ [h[ollow]]]` +Creates an (optionally hollow) solid ellipsoid that fills the defined region. + +```weacmd +//ellipsoid2 +//ellipsoid2 ice +//ellipsoid2 air +//ellipsoid2 steelblock h +//ellipsoid2 papyrus hollow +``` + + +### `//torus [ [h[ollow]]]` +Creates a solid torus at position 1 with the specified major and minor radii. The major radius is the distance from the centre of the torus to the centre of the circle bit, and the minor radius is the radius of the circle bit. + +The optional axes sets the axes upon which the torus will lay flat. Possible values: `xy` (the default), `xz`, `yz`. A single axis may also be specified (i.e. `x`, `y`, or `z`) - this will be interpreted as the axis that runs through the hole in the middle of the torus. + +```weacmd +//torus 15 5 stone +//torus 5 3 meselamp +//torus 10 6 sandstone xz +//torus 10 6 wool:red y +//torus 25 10 dirt xz hollow +``` + +### `//hollowtorus []` +Creates a hollow torus at position 1 with the radius major and minor radii. Works the same way as `//torus` does. + +```weacmd +//hollowtorus 10 5 glass +//hollowtorus 21 11 stone +//hollowtorus 18 6 dirt xz +``` + +### `//line [ []]` +Draw a line from position 1 to position 2, optionally with a given thickness. + +The radius can be thought of as the thickness of the line, and is defined as the distance from a given node to an imaginary line from pos1 to pos2. Defaults to drawing with dirt and a radius of 1. + +Floating-point values are fully supported for the radius. + +```weacmd +//line +//line stone +//line sandstone 3 +//line glass 0.5 +``` + +### `//hollow []` +Replaces nodes inside the defined region with air, but leaving a given number of nodes near the outermost edges alone. In other words, it makes the defined region hollow, while leaving walls around the edges of a given thickness (defaulting to a wall thickness of 1). + +Note that all air-like nodes are also left alone. + +```weacmd +//hollow +//hollow 2 +``` + +### `//maze [ [ []]]` +Generates a maze using replace_node as the walls and air as the paths. Uses [an algorithm of my own devising](https://starbeamrainbowlabs.com/blog/article.php?article=posts/070-Language-Review-Lua.html) (see also [this post of mine that has lots of eye candy :D](https://starbeamrainbowlabs.com/blog/article.php?article=posts/429-lua-blender-mazes.html)). It is guaranteed that you can get from every point to every other point in generated mazes, and there are no loops. + +Requires the currently selected area to be at least 3x3 on the x and z axes respectively. + +Mazes are generated from the bottom to the top of the defined region. In other words, the height of the walls of the maze is equal to the height of the defined region. + +The optional `path_length` and `path_width` arguments require additional explanation. When generating a maze, a multi-headed random walk is performed. When the generator decides to move forwards from a point, it does so `path_length` nodes at a time. `path_length` defaults to `2`. + +`path_width` is easier to explain. It defaults to `1`, and is basically the number of nodes wide the path generated is. + +Note that `path_width` must always be at least 1 less than the `path_length` in order to operate normally. + +Note also that since WorldEditAdditions v1.10, the seed doesn't have to be a number (but it can't contain spaces due to the parsing algorithm used). Non-numbers are hashed to a number using a simple (non-crypto-safe) hashing algorithm. + +The last example below shows how to set the path length and width: + +```weacmd +//maze ice +//maze stone 2 1 1234 +//maze dirt 4 2 56789 +//maze glass 2 1 minetestiscool +``` + + +### `//maze3d [ [ [ []]]]` +Same as `//maze`, but instead generates mazes in 3 dimensions instead of 2. Requires the currently selected area to be at least 3x3x3. + +The optional `path_depth` parameter defaults to `1` and allows customisation of the height of the paths generated. In other words, it customises the ceiling height, or the distance from the floor to the ceiling of the paths generated. + +To get a better look at the generated maze, try inverting it like so: + +```weacmd +//maze3d stone +//replace air dirt +//replace stone air +``` + +Additional examples: + +```weacmd +//maze3d glass +//maze3d bush_leaves 2 1 1 12345 +//maze3d dirt 4 2 2 +//maze3d stone 6 3 3 54321 +``` + + +### `//walls [ []]` +Creates vertical walls of `` around the inside edges of the defined region, optionally specifying the thickness thereof. Defaults to a replace node of `dirt` and a wall thickness of 1. + +```weacmd +//walls +//walls dirt +//walls stone +//walls goldblock +//walls sandstone 2 +//walls glass 4 +``` + + +### `//spiral2 [] [ [ [] ] ]` +Generates both square and circular spiral shapes with the given `` - defaulting to square spirals. The interval defines the gap between the spiral in nodes, and the acceleration defines by how much the interval should be increased (a value of 1 means 1 node per revolution). + +``` +//spiral2 +//spiral2 circle stone +//spiral2 square +//spiral2 circle +//spiral2 glass 5 +//spiral2 square desert_sand 3 1 +``` + + +### `//dome+ [ ...] [h[ollow]]` +Creates a dome shape (i.e. a hemisphere; half a sphere) with a specified radius of the defined node, optionally specifying the direction it should be pointing in (defaults to the positive y direction). + +For example, `//dome+ 5 stone y` creates a dome shape pointing upwards, but `//dome+ 5 stone -y` creates a dome shape pointing downwards. + +Multiple pointing direction axes can be chained together to create multiple domes on top of each other. Multiple conflicting directions will cancel each other out. + +If `h` or `hollow` is specified at the end, then the resulting dome shape is made hollow. + +``` +//dome+ 5 stone y +//dome+ 10 diamond -x +//dome+ 25 cactus y z +//dome+ 9 dirt x y z +``` + + +### `//spline [ []]` +Draws a curved line, using all the currently defined points as control points. The starting and ending widths of the line can be controlled, and the width will be linearly interpolated. + +**Note:** `//spline` uses the **new** WorldEditAdditions positions! Use the [multipoint wand](#multi-point-wand) to define the control points for the resulting line. + +For those interested, WorldEditAdditions uses the [chaikin curve algorithm](https://starbeamrainbowlabs.com/blog/article.php?article=posts/196-Chaikin-Curve-Generator.html) with linear interpolation for the width to draw the curve. + +```weacmd +//spline dirt 5 2 +//spline glass 3 +//spline bakedclay:violet 3 +``` + +![An example of what //spline can do.](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/.docs/images/reference/spline.jpeg) + +## Misc + + + +### `//rotate+ [ ...] [origin|o []]` +Rotates the defined region using the specified list of rotation operations, optionally around the defined rotation origin. For example, the following: + +```weacmd +//rotate+ y 45 +``` + +...will rotate the defined region around it's centre by 45° on the Y (vertical) axis. + +> [!IMPORTANT] +> There is a known issue in which holes appear in previously flat surfaces when rotating through non-axis-aligned rotations. The cause for this is currently unclear. +> +> If you can shed any light on this issue or make any suggestions, please get in touch. + +We can also extend this to rotate on multiple axes: + +```weacmd +//rotate+ z 90 y 45 +``` + +The rotations will be processed in order as specified from left to right. The following relative keywords are currently supported in place of an absolute axis name: + +Keyword | Meaning +------------|-------------------- +`right` | Rotates around the Y axis to the right - aka clockwise. +`left` | Rotates around the Y axis to the left - aka anticlockwise. + +A custom rotation origin can be specified too. This is done via the `origin` keyword and takes the form of specifying a position to rotate around instead of the default (picking the centre point between pos1 and pos2). For example: + +```weacmd +//rotate+ x 20 origin 3 +``` + +....will rotate 20° on the X axis around position 3. See the [multi-point wand](#multipoint) for more information on setting positions other than pos1 and pos2. + +The `origin` keyword's argument is optional, and if no position number is specified defaults to position 3. + +```weacmd +//rotate+ y 90 x 45 origin +//rotate+ y 90 x 45 o +//rotate+ x 60 origin 5 z 20 +``` + + +### `//floodfill [ []]` +Floods all connected nodes of the same type starting at _pos1_ with `` (which defaults to `water_source`), in a sphere with a radius of `` (which defaults to 50). + +```weacmd +//floodfill +//floodfill water_source 50 +//floodfill glass 25 +``` + + +### `//wbox ` +Sets the edges of the current selection to ``to create an outline of a rectangular prism. Useful for roughing in walls. + +In other words, creates a wireframe of a box defined by the current selection. + +```weacmd +//wbox silver_sandstone +//wbox dirt +``` + +### `//wcompass []` +Creates a compass around pos1 with a single node bead pointing north (+Z). + +```weacmd +//wcompass meselamp +//wcompass desert_cobble torch +//wcompass gold diamond +``` + +### `//wcorner ` +Set the corners of the current selection to ``. Useful for outlining building sites and setting boundaries. + +```weacmd +//wcorner glass +//wcorner stone_with_iron +``` + +### `//scale | [ [ ` +Advanced version of [`//stretch` from WorldEdit](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md#stretch-stretchx-stretchy-stretchz) that can scale both up and down at the same time by transparently splitting it into 2 different operations. Scaling up is *always* done before scaling down. + +Although the syntax looks complicated, it's really quite simple. The key concept to understand is that of the scale factor. It refers to how much the defined region should be scaled up or down by, and can be specified in multiple different ways: + +Scale Factor | Meaning +----------------|--------------------- +1 | Don't scale at all. +0.5 | Scale down by 50% +2 | Scale up by 2x, doubling the size +5 | Scale up by 5x, quintupling the size +20% | Scale down to 30% of the original size +1/3 | Scale down to 1 third of original size + +In short, you can specify the scale factor directly, as a percentage, or as 1 number divided by another number. + +> [!NOTE] +> `//scale` always scales in the _positive direction_ by default. This can be changed however - see below. + +With this in mind, there are 3 forms that you can tell `//scale` how you want to scale the defined region: + +#### Single Axis +If you just need to scale a single axis, you can tell `//scale` that like so: + +```weacmd +//scale +``` + +To give a concrete example: + +```weacmd +//scale y 2 +``` + +The above will scale the defined region in the positive y direction by 2 times, doubling the height. If you want to scale in the opposite direction, do this: + +```weacmd +//scale -y 2 +``` + +This will scale in the _negative_ y direction by 2 times (again, doubling the height). Some more examples: + +```weacmd +//scale z 50% +//scale -x 1/3 +``` + +#### All axes +To scale on all axes at once, `//scale` takes the shortcut syntax of specifying a single scale factor: + +```weacmd +//scale 2 +//scale 200% +``` + +Both of the above will scale the defined region up by 2 times in all directions. + +#### Multiple scale factors +If you want to specify different scale factors for difference axes, then `//scale` also supports a third syntax. Here's an example: + +```weacmd +//scale 2 3 4 +``` + +This will scale the defined region by 2x in the positive x, 3x in the positive y, and 4x in the positive z. As these are all scale factors, we can also use the syntax described above to scale up and down in the same operation: + +```weacmd +//scale 50% 2 1/4 +``` + +This will first scale in the positive y by 2x. Once that operation is completed, it will scale down to 50% size in the positive x and down to 25% size in the positive z. Note that if you want to scale down first and then scale up, you'll need to execute 2 separate commands. + +If you want to change the anchor point of the scaling operation too, `//scale` supports a final syntax like so: + +```weacmd +//scale 50% 2 1/4 1 -1 1 +``` + +By adding 3 extra numbers for the x, y, and z axes respectively, we can control the direction `//scale` performs the scaling operation. A value of 1 or greater indicates the positive direction of the axis, and a value of -1 or less indicates the negative direction of the axis. I recommend by [worldedit_hud_helper](https://content.minetest.net/packages/Starbeamrainbowlabs/worldedit_hud_helper/) mod for easily determining which direction is which. + +So in the above example, we scale in the positive x and z directions, and the negative y direction. + + +### `//copy+ [ [...]] [aa|airapply]` +Fully backwards-compatible with `//copy` from regular WorldEdit, but allows you to specify multiple axes at once in a single copy operation. Each successive axis in the list is specified in the form ` `, where: + + - `` is the name of the axis to move the defined region along + - `` is the number of nodes along the defined axis to move + +All of the following values are valid axes: + + - `x` + - `y` + - `z` + - `-x` + - `-y` + - `-z` + - `?` / `front` / `f` + - `back` / `b` + - `left` / `l` + - `right` / `r` + - `up` / `u` + - `down` / `d` + +Additionally all the absolute axis names (`x`/`y`/`z`/`-x`/`-y`/`-z`) may also be specified multiple times under the same count - e.g. `xy-z 6`. + +Finally, if the word `airapply` (or `aa` for short) is present at the end of the command invocation it enables the integrated airapply mode, which replaces target nodes only if they are air-like. + +``` +//copy+ x 6 +//copy+ y 10 z 4 +//copy+ front 6 left 5 +//copy+ ? 10 r 25 y 50 +//copy+ xz 50 front 22 +//copy+ yx 25 +//copy+ -xz-y 10 +//copy+ y 45 aa +//copy+ -y 15 z 5 airapply +``` + + +### `//move+ [ [...]] [aa|airapply]` +Identical to [`//copy+`](#copy), but instead moves the defined region instead of copying it. + +Note that the integrated `airapply` (`aa` for short) also works as in [`//copy+`](#copy), but remember that if a given target node is not *not* air-like and the integrated `airapply` mode is enabled, the source node is still moved from the source, but destroyed because it is can't be set at the target. + + +``` +//move+ x 6 +//move+ y 10 z 4 +//move+ front 6 left 5 +//move+ ? 10 r 25 y 50 +//move+ xz 50 front 22 +//move+ yx 25 +//move+ -xz-y 10 +//move+ back 20 aa +//move+ -z 45 y 3 airapply +``` + + +### `//replacemix [] [] [ []] [ []] ...` +Replaces a given node with a random mix of other nodes. Functions like `//mix`. + +This command is best explained with examples: + +```weacmd +//replacemix dirt stone +``` + +The above functions just like `//replace` - nothing special going on here. It replaces all `dirt` nodes with `stone`. + +Let's make it more interesting: + +```weacmd +//replacemix dirt 5 stone +``` + +The above replaces 1 in every 5 `dirt` nodes with `stone`. Let's get even fancier: + +```weacmd +//replacemix stone stone_with_diamond stone_with_gold +``` + +The above replaces `stone` nodes with a random mix of `stone_with_diamond` and `stone_with_gold` nodes. But wait - there's more! + +```weacmd +//replacemix stone stone_with_diamond stone_with_gold 4 +``` + +The above replaces `stone` nodes with a random mix of `stone_with_diamond` and `stone_with_gold` nodes as before, but this time in the ratio 1:4 (i.e. for every `stone_with_diamond` node there will be 4 `stone_with_gold` nodes). Note that the `1` for `stone_with_diamond` is implicit there. + +If we wanted to put all of the above features together into a single command, then we might do this: + +```weacmd +//replacemix dirt 3 sandstone 10 dry_dirt cobble 2 +``` + +The above replaces 1 in 3 `dirt` nodes with a mix of `sandstone`, `dry_dirt`, and `cobble` nodes in the ratio 10:1:2. Awesome! + +Since WorldEditAdditions v1.12, you can also use percentages: + +```weacmd +//replacemix dirt 33% sandstone 75% dry_dirt 10% cobble 15% +``` + +Note though that the percentages are internally converted to a 1-in-N chance and rounded down. + +Here are all the above examples together: + +```weacmd +//replacemix dirt stone +//replacemix dirt 5 stone +//replacemix stone stone_with_diamond stone_with_gold +//replacemix stone stone_with_diamond stone_with_gold 4 +//replacemix dirt 3 sandstone 10 dry_dirt cobble 2 +``` + + +### `//revolve []` +Makes a given number of copies of the currently defined region (bounded by pos1 and pos2) at a given number of equally spaced points rotated around a given pivot/origin point. + +For example, `//revolve 4` would make rotated copies of the currently defined region at intervals 0° (the source to copy), 90°, 180°, and 270° around the given pivot point. + +`pivot_point_number` is the number of the defined position that should act as the pivot point, or origin for the revolve operation. It defaults to the last position defined. Note that it cannot be pos1 or pos2, as these are used to define the region that should be rotated. Use the [multi-point wand](#multi) to define a position with an index of 3 or more. + +```weacmd +//revolve 4 +//revolve 6 6 +``` + + +## Terrain + + + +### `//convolve [[,]] []` +Advanced version of `//smooth` from we_env, and one of the few WorldEditAdditions commands to have any aliases (`//smoothadv` and `//conv`). + +Extracts a heightmap from the defined region and then proceeds to [convolve](https://en.wikipedia.org/wiki/Kernel_(image_processing)) over it with the specified kernel. The kernel can be thought of as the filter that will be applied to the heightmap. Once done, the newly convolved heightmap is applied to the terrain. + +Possible kernels: + +Kernel | Description +----------------|------------------------------ +[`box`](https://en.wikipedia.org/wiki/Box_blur) | A simple uniform box blur. +`pascal` | A kernel derived from the odd layers of [Pascal's Triangle](https://en.wikipedia.org/wiki/Pascal%27s_triangle). Slightly less smooth than a Gaussian blur. +[`gaussian`](https://en.wikipedia.org/wiki/Gaussian_blur) | The default. A Gaussian blur - should give the smoothest result, and also the most customisable - see below. + +If you can think of any other convolutional filters that would be useful, please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new). The code backing this command is very powerful and flexible, so adding additional convolutional filters should be pretty trivial. + +The width and height (if specified) refer to the dimensions of the kernel and must be odd integers and are separated by a single comma (and _no_ space). If the height is not specified, it defaults to the width. If using the `gaussian` kernel, the width and height must be identical. Larger kernels are slower, but produce a more smoothed effect and take more nearby nodes into account for every column. Defaults to a 5x5 kernel. + +The sigma value is only applicable to the `gaussian` kernel, and can be thought of as the 'smoothness' to apply. Greater values result in more smoothing. Default: 2. See the [Gaussian blur](https://en.wikipedia.org/wiki/Gaussian_blur) page on Wikipedia for some pictures showing the effect of the sigma value. + +```weacmd +//convolve +//convolve box 7 +//convolve pascal 11,3 +//convolve gaussian 7 +//convolve gaussian 9 10 +//convolve gaussian 5 0.2 +``` + + +### `//overlay [] [] [ []] ...` +Places `` in the last contiguous air space encountered above the first non-air node. In other words, overlays all top-most nodes in the specified area with ``. Optionally supports a mix of node names and chances, as `//mix` (WorldEdit) and `//replacemix` (WorldEditAdditions) does. + +Will also work in caves, as it scans columns of nodes from top to bottom, skipping every non-air node until it finds one - and only then will it start searching for a node to place the target node on top of. + +Note that all-air columns are skipped - so if you experience issues with it not overlaying correctly, try `//expand down 1` to add an extra node's space to your defined region. + +Note also that columns without any air nodes in them at all are also skipped, so try `//expand y 1` to add an extra layer to your defined region. + +```weacmd +//overlay grass +//overlay glass +//overlay grass_with_dirt +//overlay grass_with_dirt 10 dirt +//overlay grass_with_dirt 10 dirt 2 sand 1 +//overlay sandstone dirt 2 sand 5 +//overlay dirt 90% stone 10% +``` + + +### `//fillcaves []` +Fills in all airlike nodes beneath non airlike nodes, which gives the effect of filling in caves. Defaults to filling in with stone, but this can be customised. + +Note that the *entire* cave you want filling must be selected, as `//fillcaves` only operates within the defined region (ref #50). + +```weacmd +//fillcaves +//fillcaves dirt +//fillcaves brick +``` + + + +### `//layers [] [ []] [ []] ...` +Finds the first non-air node in each column and works downwards, replacing non-air nodes with a defined list of nodes in sequence. Like WorldEdit for Minecraft's `//naturalize` command, and also similar to [`we_env`'s `//populate`](https://github.com/sfan5/we_env). Speaking of, this command has `//naturalise` and `//naturalize` as aliases. Defaults to 1 layer of grass followed by 3 layers of dirt. + +Since WorldEditAdditions v1.13, a maximum and minimum slope is optionally accepted, and constrains the columns in the defined region that `//layers` will operate on. For example, specifying a value of `20` would mean that only columns with a slop less than or equal to 20° (degrees, not radians) will be operated on. A value of `45..60` would mean that only columns with a slope between 45° and 60° will be operated on. + +The list of nodes has a form similar to that of a chance list you might find in `//replacemix`, `//overlay`, or `//mix` - see the examples below. If the number of layers isn't specified, `1` is assumed (i.e. a single layer). + + +```weacmd +//layers dirt_with_grass dirt 3 +//layers sand 5 sandstone 4 desert_stone 2 +//layers brick stone 3 +//layers cobble 2 dirt +//layers 45..60 dirt_with_snow dirt 2 +//layers 30 snowblock dirt_with_snow dirt 2 +``` + + +### `//erode [ [ []] [ []] ...]` +Runs an erosion algorithm over the defined region, optionally passing a number of key - value pairs representing parameters that are passed to the chosen algorithm. This command is **experimental**, as the author is currently on-the-fence about the effects it produces. + +Works best if you run `//fillcaves` first, or otherwise have no air nodes below the top non-air node in each column. + +Currently implemented algorithms: + +Algorithm | Mode | Description +------------|-------|------------------- +`snowballs` | 2D | The default - based on [this blog post](https://jobtalle.com/simulating_hydraulic_erosion.html). Simulates snowballs rolling across the terrain, eroding & depositing material. Then runs a 3x3 gaussian kernel over the result (i.e. like the `//conv` / `//smoothadv` command). +`river` | 2D | Fills in potholes and lowers pillars using a cellular automata-like algorithm that analyses the height of neighbouring columns. + +Usage examples: + +```weacmd +//erode +//erode snowballs +//erode snowballs count 25000 +``` + +Each of the algorithms above have 1 or more parameters that they support. These are detailed below. + +#### Algorithm: `snowballs` +Based on the algorithm detailed in [this blog post](https://jobtalle.com/simulating_hydraulic_erosion.html) ([direct link to the source code](https://github.com/jobtalle/HydraulicErosion/blob/master/js/archipelago/island/terrain/erosionHydraulic.js)), devised by [Job Talle](https://jobtalle.com/). + +Parameter | Type | Default Value | Description +--------------------|-----------|-------------------|-------------------------- +rate_deposit | `float` | 0.03 | The rate at which snowballs will deposit material +rate_erosion | `float` | 0.04 | The rate at which snowballs will erode material +friction | `float` | 0.07 | More friction slows snowballs down more. +speed | `float` | 1 | Speed multiplier to apply to snowballs at each step. +max_steps | `float` | 80 | The maximum number of steps to simulate each snowball for. +velocity_hist_count | `float` | 3 | The number of previous history values to average when detecting whether a snowball has stopped or not +init_velocity | `float` | 0.25 | The maximum random initial velocity of a snowball for each component of the velocity vector. +scale_iterations | `float` | 0.04 | How much to scale erosion by as time goes on. Higher values mean that any given snowball will erode more later on as more steps pass. +maxdiff | `float` | 0.4 | The maximum difference in height (between 0 and 1) that is acceptable as a percentage of the defined region's height. +count | `float` | 25000 | The number of snowballs to simulate. +noconv | any | n/a | When set to any value, disables to automatic 3x3 gaussian convolution. + +Usage examples: + +```weacmd +//erode +//erode snowballs +//erode snowballs count 50000 +``` + +If you find any good combinations of these parameters, please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new) (or a PR!) and let me know! I'll include good combinations here, and possibly add a presets feature too. + +#### Algorithm: `river` +Ever been annoyed by small 1 wide holes or thin pillars all over the place? This command is for you! Does not operate on the very edge of the defined region, because the algorithm can't see the neighbours of those columns. + +Parameter | Type | Default Value | Description +--------------------|-----------|-------------------|-------------------------- +steps | `integer` | 1 | The number of rounds or passes of the algorithm to run. Useful if you have a 1x3 hole for instance, it will take at least 2 steps to fill it in - and more if it's deeper than 1 node. +lower_sides | `string` | 4,3 | Comma separated list of numbers. Columns with this many sides lower than it will be lowered in height by 1 node. +raise_sides | `string` | 4,3 | Comma separated list of numbers. Columns with this many sides higher than it will be raised in height by 1 node. +doraise | `boolean` | true | Whether to raise columns in height. If false, then no columns will be raised in height even if they are eligible to be so according to `raise_sides`. +dolower | `boolean` | true | Whether to lower columns in height. If false, then no columns will be lowered in height even if they are eligible to be so according to `lower_sides`. + +Usage examples: + +```weacmd +//erode river +//erode river steps 10 +``` + + +### `//noise2d [ []] [ []] ...]` +Applies 2D noise to the terrain in the defined region. Like `//erode`, this command accepts a number of different key-value parameters and provides a number of different underlying algorithms. + +In other words, this command changes the height of the terrain according to some noise function (e.g. Perlin noise): + +![//noise2d applies 2D noise as a modifier to terrain height.](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/dev/.docs/images/reference/noise2d.jpeg) + +It does so like this: + +1. Take coordinates of each column +2. Plug them through a noise function (see below) +3. Apply the generated noise value to the terrain. + +`//noise2d` has a number of parameters that let you adjust the mathematical properties of step 2, which are explained in the table below. + +Some terms that are useful to know: + +- **Scale:** How big or small the noise is. Lower values stretch it out to be bigger, and higher values squash it in. +- **Offset:** Noise is calculated by passing some coordinates into a function. +- **Perlin:** A noise algorithm. `//noise2d` defaults to this. + + +#### Table of parameters + +Parameter | Type | Default Value | Description +------------|-----------|---------------|----------------------- +algorithm | `string` | perlinmt | The 2D noise algorithm to apply - see below. +apply | `string¦integer` | 5 | How to apply the noise to the terrain - see below. +scale | `float` | 1 | Sets `scalex`, `scaley`, and `scalez` all at once. Consider also `//apply`. +scalex | `float` | 1 | The scale of the noise on the x axis. +scaley | `float` | 1 | The scale of the noise on the y axis. +scalez | `float` | 1 | The scale of the noise on the z axis. +offsetx | `float` | 1 | The offset to add to the x axis before calling the noise function. +offsety | `float` | 0 | The offset to add to the y axis before calling the noise function. +offsetz | `float` | 0 | The offset to add to the z axis before calling the noise function. +exponent | `float` | 0 | Raise the generated noise value (with a range of 0 to 1) to this power. Generally results in sharper peaks. +multiply | `float` | 1 | Multiply the generated noise value by this number +add | `float` | 0 | Add this number to the generated noise value. + +#### Apply +Different values of the `apply` parameter result in the generated noise values being applied in different ways: + +1. An integer indicates that the noise should be rescaled to a given amplitude (equal parts of the range above and below 0) before being added to the terrain heightmap.` +2. The exact string `add`: Noise values are added to each heightmap pixel. +3. The exact string `multiply`: Each heightmap pixel is multiplied by the corresponding noise value. + +An integer is the most common way to use `//noise2d`. So, for example: + +```weacmd +//noise2d apply 5 +``` + +...would alter the height of each column of nodes by at most 5 blocks either side, while: + +```weacmd +//noise2d apply 10 +``` + +...would alter the height by 10 blocks instead of 5. + +#### Types of noise +Another thing that can be changed is the noise algorithm. This changes what the noise that is applied to the terrain looks like. + +The following algorithms are currently available: + +Algorithm | Description +------------|-------------------------- +`perlinmt` | **Default**. Perlin noise, backed by Minetest's inbuilt `PerlinNoise` class. +`perlin` | Perlin noise, backed by a pure Lua perlin noise implementation. Functional, but currently contains artefacts I'm having difficulty tracking down. +`sin` | A sine wave created with `math.sin()`. +`white` | Random white noise. In other words, just random values. +`red` | Red noise - has a lower frequency than white noise. Ref [Noise Functions and Map Generation by Red Blob Games](https://www.redblobgames.com/articles/noise/introduction.html). +`infrared` | Even smoother than red noise. Tends to also be quite flat unless you use a slightly higher `apply` value (e.g. `20`). + +When specifying algorithm names, the `algorithm` parameter name is optional. For example, the following are both equivalent: + +```weacmd +//noise2d offsetx 4 perlin scale 0.2 +//noise2d offsetx 4 algorithm perlin scale 0.2 +``` + +#### Further examples +Example invocations: + +```weacmd +//noise2d sin scale 0.5 +//noise2d offsetx 20 perlin +//noise2d sin exponent 4 +``` + + +### `//sculptlist [preview]` +Lists all the available sculpting brushes for use with `//sculpt`. If the `preview` keyword is specified as an argument, then the brushes are also rendered in ASCII as a preview. See [`//sculpt`](#sculpt). + +``` +//sculptlist +//sculptlist preview +``` + + +### `//sculpt [ [ []]]` +Applies a specified brush to the terrain at position 1 with a given height and a given size. Multiple brushes exist (see [`//sculptlist`](#sculptlist)) - and are represented as a 2D grid of values between 0 and 1, which are then scaled to the specified height. The terrain around position 1 is first converted to a 2D heightmap (as in [`//convolve`](#convolve) before the brush "heightmap" is applied to it. + +Similar to [`//sphere`](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md#sphere-radius-node), [`//cubeapply 10 set`](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md#cubeapply-sizesizex-sizey-sizez-command-parameters), or [`//cylinder y 5 10 10 dirt`](https://github.com/Uberi/Minetest-WorldEdit/blob/master/ChatCommands.md#cylinder-xyz-length-radius1-radius2-node) (all from [WorldEdit](https://content.minetest.net/packages/sfan5/worldedit/)), but has a number of added advantages: + + - No accidental overhangs + - Multiple custom brushes (see below on how you can add your own!) + +A negative height value causes the terrain to be lowered by the specified number of nodes instead of raised. + +While sculpting brushes cannot yet be rotated, this is a known issue. Rotating sculpting brushes will be implemented in a future version of WorldEditAdditions. + +The selection of available brushes is limited at the moment, but see below on how to easily create your own! + +``` +//sculpt +//sculpt default 25 3 +//sculpt ellipse +//sculpt circle 50 3 +``` + +#### Create your own brushes +2 types of brush exist: + +1. Dynamic (lua-generated) brushes +2. Static brushes + +All brushes are located in `worldeditadditions/lib/sculpt/brushes` (relative to the root of WorldEditAdditions' installation directory). + +Lua-generated brushes are not the focus here, but are a file with the extension `.lua` and return a function that returns a brush - see other existing Lua-generated brushes for examples (and don't forget to update `worldeditadditions/lib/sculpt/.init.lua`). + +Static brushes on the other hand are simply a list of tab-separated values arranged in a grid. For example, here is a simple brush: + +```tsv +0 1 0 +1 2 1 +0 1 0 +``` + +Values are automatically rescaled to be between 0 and 1 based on the minimum and maximum values, so don't worry about which numbers to use. Static brushes are saved with the file extension `.brush.tsv` in the aforementioned directory, and are automatically rescanned when your Minetest server starts. While they can't be rescaled automatically to fix a target size (without creating multiple variants of a brush manually of course, though this may be implemented in the future), static brushes are much easier to create than dynamic brushes. + +To assist with the creation of static brushes, a tool exists to convert any image to a static brush: + + + +The tool can operate on the colour channel of your choice - red, green, blue, or alpha. + +If you've created a cool new brush (be it static or dynamic), **please contribute it to WorldEditAdditions**! That way, everyone can enjoy using your awesome brush. [WorldPainter](https://www.worldpainter.net/) has many brushes available in the community, but `//sculpt` for WorldEditAdditions is new so don't have the same sized collection yet :-) + +To contribute your new brush back, you can either [open a pull request](https://github.com/sbrl/Minetest-WorldEditAdditions/pulls) if you're confident using GitHub, or [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues) with your brush attached if not. + + + +## Flora + + + +### `//forest [] [] [] [ []] ...` +Plants and grows saplings to generate a forest. A density value is optionally taken, which controls the overall density of the forest that is generated. The `bonemeal` mod is required - just like for the [`//bonemeal`](#bonemeal-strength-chance) command. + +The density defaults to 1, acts like a multiplier, and is not affected by the chances of all saplings listed (e.g. you can have a sapling with a chance of 1-in-50, and the overall density of the forest will be unaffected). For example, 2 results in a forest twice as dense as the default, and 0.5 a forest half as dense as the default density. + +The tree types are provided as a list of names and 1-in-N chances, just like [`//overlay`](#overlay-node_name_a-chance_a-node_name_b-chance_b-node_name_n-chance_n-), `//mix`, `//layers`, etc. Unlike the aforementioned commands however, `//forest` has an additional layer of alias resolution to ease the process of determining what the name of the sapling is you want to use to generate forests with. See [`//saplingaliases`](#saplingaliases-aliasesall_saplings) for more details. + +Saplings are placed with [`//overlay`](#overlay-node_name_a-chance_a-node_name_b-chance_b-node_name_n-chance_n-) and grown using the same method that's used by the `//bonemeal` command. Up to 100 attempts are made to grow placed saplings. If all of those attempts fail (success is determined by whether the sapling is still present or not), the sapling is removed and the failure counter is incremented. + +Currently, the following mods are known to have aliases registered: + + - `default` + - [`moretrees`](https://content.minetest.net/packages/VanessaE/moretrees/) (warning: these saplings don't appear to work very well this command - assistance in debugging this would be very helpful) + - [`cool_trees`](https://content.minetest.net/packages/runs/cool_trees/) + +If you like, you can also reference the full name of a sapling node instead. The only requirements for saplings to be supported by this mod are: + +1. It can be bonemealed +2. It has the `sapling` group + +For example, the first 2 examples below are functionally equivalent. + +```weacmd +//forest aspen +//forest default:aspen_sapling +//forest 2 oak 3 aspen pine +//forest 0.5 acacia +``` + + +### `//saplingaliases [aliases|all_saplings]` +Lists all the currently registered sapling aliases in alphabetical order. These aliases can be used in the `//forest` subcommand. + +Optionally takes a single parameter, which is the operating mode. Current implemented operating modes: + +Mode | Description +----------------|---------------------- +`aliases` | The default. Lists all the currently registered sapling aliases in alphabetical order. +`all_saplings` | Spins through all the nodes currently registered in Minetest, and lists all the nodes that have the `sapling` group. + +```weacmd +//saplingaliases +//saplingaliases all_saplings +//saplingaliases aliases +``` + + + +### `//bonemeal [ [ [ [ ...]]]]` +Requires the [`bonemeal`](https://content.minetest.net/packages/TenPlus1/bonemeal/) ([repo](https://notabug.org/TenPlus1/bonemeal/)) mod (otherwise _WorldEditAdditions_ will not register this command and output a message to the server log). Alias: `//flora`. + +Bonemeals all eligible nodes in the current region. An eligible node is one that has an air node directly above it - note that just because a node is eligible doesn't mean to say that something will actually happen when the `bonemeal` mod bonemeals it. + +Optionally takes a strength value (that's passed to `bonemeal:on_use()`, the method in the `bonemeal` mod that is called to actually do the bonemealing). The strength value is a positive integer from 1 to 4 (i.e. 1, 2, 3, or 4) - the default is 1 (the lowest strength). + +I observe that a higher strength value gives a higher chance that something will actually grow. In the case of soil or sand nodes, I observe that it increases the area of effect of a single bonemeal action (thus at higher strengths generally you'll probably want a higher chance number - see below). See the [`bonemeal` mod README](https://notabug.org/TenPlus1/bonemeal) for more information. + +Also optionally takes a chance number. This is the chance that an eligible node will actually get bonemealed, and is a positive integer that defaults to 1. The chance number represents a 1-in-{number} chance to bonemeal any given eligible node, where {number} is the chance number. In other words, the higher the chance number the lower the chance that a node will be bonemealed. + +For example, a chance number of 2 would mean a 50% chance that any given eligible node will get bonemealed. A chance number of 16 would be a 6.25% chance, and a chance number of 25 would be 2%. + +Since WorldEditAdditions v1.12, a percentage chance is also supported. This is denoted by suffixing a number with a percent sign (e.g. `//bonemeal 1 25%`). + +Since WorldEditAdditions v1.13, a list of node names is also optionally supported. This will constrain bonemeal operations to be performed only on the node names listed. + + +```weacmd +//bonemeal +//bonemeal 3 25 +//bonemeal 4 +//bonemeal 1 10 +//bonemeal 2 15 +//bonemeal 2 10% +//bonemeal 2 10% dirt +//bonemeal 4 50 ethereal:grove_dirt +``` + + + +## Statistics + + + +### `//count` +Counts all the nodes in the defined region and returns the result along with calculated percentages (note that if the chat window used a monospace font, the returned result would be a perfect table. If someone has a ~~hack~~ solution to make the columns line up neatly, please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new) :D) + +> [!NOTE] +> The output of `//count` can be rather long sometimes, and Minetest by default only shows the last few lines of chat. Press F10 to show the full chat window that you can then scroll through to inspect the full output. + +```weacmd +//count +``` + + +### `//basename ` +Returns the absolute canonical name of a node, given an alias or partial node name. For example: + +```weacmd +//basename dirt +``` + +...will return `default:dirt`. Uses `worldedit.normalize_nodename(string)` under the hood. + +```weacmd +//basename stonebrick +//basename glass +``` + + +### `//ngroups [v[erbose]]` +Lists the groups that a given node is a member of. For example: + +```weacmd +//ngroups sand +``` + +Might return: + +``` +default:sand ∈ sand crumbly falling_node +``` + +Groups in Minetest can also have a numerical value greater than 0. Append `v` or `verbose` to see those values: + +```weacmd +//ngroups sand v +//ngroups sand verbose +``` + +...both of the above might produce an output like this: + +``` +default:sand ∈ sand=1 crumbly=3 falling_node=1 +``` + +Finally, the customary misc examples: + +```weacmd +//ngroups sand +//ngroups bakedclay:orange v +//ngroups cactus +//ngroups default:dry_shrub v +``` + +### `//ndef ` +Short for *Node Definition*. Prints the definition table for the node with the given name. In other words. the output could look a little like this: + +``` +stairs:stair_birch_wood { + description = (string) "Birch Wood Stair" + sounds = (table) { + dig = (table) { + name = (string) "default_dig_choppy" + gain = (number) 0.4 + } + place = (table) { + name = (string) "default_place_node_hard" + gain = (number) 1 + } + dug = (table) { + name = (string) "default_wood_footstep" + gain = (number) 1 + } + footstep = (table) { + name = (string) "default_wood_footstep" + gain = (number) 0.15 + } + } + name = (string) "stairs:stair_birch_wood" + light_source = (number) 0 + mod_origin = (string) "ethereal" + selection_box = (table) { + fixed = (table) { + 1 = (table) [truncated] + 2 = (table) [truncated] + } + type = (string) "fixed" + } + paramtype = (string) "light" + groups = (table) { + flammable = (number) 3 + stair = (number) 1 + choppy = (number) 2 + oddly_breakable_by_hand = (number) 1 + } + is_ground_content = (boolean) false + on_place = (function) function: 0x765b01d0edb8 + drawtype = (string) "nodebox" + tiles = (table) { + 1 = (table) { + name = (string) "moretrees_birch_wood.png" + backface_culling = (boolean) true + } + } + paramtype2 = (string) "facedir" + sunlight_propagates = (boolean) false + node_box = (table) { + fixed = (table) { + 1 = (table) [truncated] + 2 = (table) [truncated] + } + type = (string) "fixed" + } + type = (string) "node" +} +``` + +This command is intended for debugging and development purposes, but if you're implementing a mod yourself you might find it useful too. + +```weacmd +//ndef stone +//ndef stairs:stair_birch_wood +//ndef glass +``` + +### `//uasparse ` +Short for *Unified Axis Syntax Parse*. Parses the given UAS expression and prints the resulting vectors to the chat window. + +```weacmd +//uasparse front right 5 +//uasparse y 12 h -2 +//uasparse left 3 up 5 -front 7 +//uasparse -z 12 -y -2 x -2 +``` + + + +## Selection + + +### Unified Axis Syntax (UAS) +The Unified Axis Syntax system allows users to input direction and distance information in three dimensions using "natural" measurement syntax. The key features include axis clumping, double negatives, relative directions, mirroring and compass directions (more information below). + +*Note: negatives can be applied to axes, directions **AND** distances* + +#### Relative Directions +|Key Words | Interpretation| +|----------|---------------| +|`f[ront]\|facing\|?` | The direction the player is facing most toward in the world +|`b[ack]\|behind\|rear` | The opposite of the direction the player is facing most toward in the world +|`l[eft]` | The direction to the left of the player +|`r[ight]` | The direction to the right of the player + +```weacmd +back 1 +f r 4 +-facing 13 +``` + +#### Compass Directions +|Key Words | Interpretation| +|----------|---------------| +|`n[orth]` | z +|`s[outh]` | -z +|`e[ast]` | x +|`w[est]` | -x +|`u[p]` | y +|`d[own]` | -y + +```weacmd +south 3 +north west 5 +e d -2 +``` + +#### Axis Clumping +Supported axes are `x`, `y`, `z`, `h`, `v`. All horizontal axes are covered by `h` and both vertical ones are covered by `v`. + +- `h 5` == `xz -xz 5` == `x 5 z 5 x -5 z -5` +- `v 5` == `up down 5` == `y -y 5` +- `vxz 5` == `xyz -y 5` == `xyz 5 y -5` + +#### Inference and Omnidirectionality +The UAS parser takes command input that is split by whitespace and interprets it as a series of numbers preceded by directional cues. If a number is preceded by another number or nothing it assumes that the number is to be applied on all axes in both positive and negative directions. + +- `10` == `hv 10` == `xyz -xyz 10` +- `x 3 6` == `x 3 hv 6` + +From the above examples you can also see the principle of inference. All direction modifiers before a value are interpreted as belonging to that value. So `x v 5` is equivalent to `x 5 v 5` and `xv 5`. + +Because UAS parses "natural" measurement syntax, there are many ways to express the same direction and distance. This caters to users with different ways of thinking and different play styles which will hopefully make the tools easier to use. + +### `//unmark` +Hides the in-game UI that indicates where the current positions and region are located. + +This hides both the WorldEditAdditions *and* the WorldEdit UI if displayed, but does **not** change or remove any points that are registered. + +Should more than 2 points be defined, they are all hidden. + +```weacmd +//unmark +``` + +### `//mark` +Shows the in-game UI that indicates where the current positions and region are located once more. + +Should more than 2 points be defined, they are all shown once more. + +Often used after calling [`//unmark`](#unmark) + +```weacmd +//mark +``` + + +### `//pos1` +Sets pos1 to the location of the calling player. + +This is, as with all other WorldEditAdditions commands, seamlessly synchronised with WorldEdit, allowing you to use any combination of WorldEditAdditions and WorldEdit commands and tools without them desynchronising from one another. + +**Aliases:** `//1` + +```weacmd +//pos2 +``` + +### `//pos2` +Sets pos1 to the location of the calling player. + +This is, as with all other WorldEditAdditions commands, seamlessly synchronised with WorldEdit, allowing you to use any combination of WorldEditAdditions and WorldEdit commands and tools without them desynchronising from one another. + +**Aliases:** `//2` + +```weacmd +//pos2 +``` + +### `//pos ` +Sets position with the given index `` to the location of the calling player. + +Should the index be less than or equal to 2, then as with all other WorldEditAdditions commands, seamlessly synchronised with WorldEdit, allowing you to use any combination of WorldEditAdditions and WorldEdit commands and tools without them desynchronising from one another. + +Should the index be greater than 2, the position will only be registered in WorldEditAdditions, as WorldEdit does not support defining more than 2 points. + +If no index is specified, an error is returned and nothing is done. + +```weacmd +//pos 1 +//pos 3 +//pos 45 +//pos 2 +``` + +### `//reset` +Clears all positions defined and the defined region. + +This also synchronises with WorldEdit, as all other WorldEditAdditions commands do. + +```weacmd +//reset +``` + + +### `//scol [ ] ` +> [!WARNING] +> **REMOVED** in v1.15 in favour of [`//srel`](#srel) +Short for _select column_. Sets the pos2 at a set distance along 1 axis from pos1. If the axis isn't specified, defaults the direction you are facing. Implementation thanks to @VorTechnix. + +```weacmd +//scol 10 +//scol x 3 +``` + +### `//srect [ []] ` +> [!WARNING] +> **REMOVED** in v1.15 in favour of [`//srel`](#srel) +Short for _select rectangle_. Sets the pos2 at a set distance along 2 axes from pos1. If the axes aren't specified, defaults to positive y and the direction you are facing. Implementation thanks to @VorTechnix. + +```weacmd +//srect x z 10 +//srect 3 +//srect -z y 25 +``` + + +### `//scube [ [ []]] ` +> [!WARNING] +> **REMOVED** in v1.15 in favour of [`//srel`](#srel) +Short for _select cube_. Sets the pos2 at a set distance along 3 axes from pos1. If the axes aren't specified, defaults to positive y, the direction you are facing and the axis to the left of facing. Implementation thanks to @VorTechnix. + +```weacmd +//scube 5 +//scube z a y 12 +//scube x z 3 +//scube -z 12 +``` + + +### `//scloud <0-6|stop|reset>` +Short for _select point cloud_. Sets pos1 and pos2 to include the nodes you punch. Numbers 1-6 designate how many nodes you want to punch before the operation ends. 0 or stop terminate the operation so that any further nodes you punch won't be added to selection. Reset terminates operation if one is running and resets the selection area. + +```weacmd +//scloud 6 +//scloud 5 +//scloud stop +``` + + +### `//scentre` +Short for _select center_. Sets pos1 and pos2 to the centre point(s) of the current selection area. 1, 2, 4 or 8 nodes may be selected depending on what parts of the original selection are even in distance. Implementation thanks to @VorTechnix. + +```weacmd +//scentre +``` + +### `//srel ` +Short for _select relative_. Sets the pos2 at set distances along 3 axes relative to pos1. If pos1 is not set it will default to the node directly under the player. The axis arguments accept `x, y, z` as well as `up, down, left, right, front, back`. Left, right, front and back are relative to player facing direction. Negative (`-`) can be applied to the axis, the length or both. Implementation thanks to @VorTechnix. + +```weacmd +//srel front 5 +//srel y 12 right -2 +//srel left 3 up 5 -front 7 +//srel -z 12 -y -2 x -2 +``` + +### `//sgrow ` +Short for _selection grow_. Grows the current selection along specified axes/directions. +Aliases: `//extend`, `//outset`. + +```weacmd +//sgrow back 4 +//sgrow left -2 v r 2 +//sgrow h 4 +//sgrow -zy -2 x -2 +``` + +### `//sshrink ` +Short for _selection shrink_. Shrinks the current selection along specified axes/directions. +Aliases: `//contract`, `//inset`. + +```weacmd +//sshrink left 4 +//sshrink right -2 up 2 +//sshrink v 4 +//sshrink -hy 2 x -3 true +``` + +### `//sshift ` +Short for _selection shift_. Shifts the WorldEdit region along 3 axes. The axis arguments accept `x, y, z` as well as `up, down, left, right, front, back`. Left, right, front and back are relative to player facing direction. Negative (`-`) can be applied to the axis, the length or both. Implementation thanks to @VorTechnix. + +```weacmd +//sshift back 4 +//sshift right -2 up 2 +//sshift -left 2 z -7 -y -4 +//sshift -z 12 -y -2 x -2 +``` + +### `//smake [ []]` +Short for _selection make_. Modifies existing selection by moving pos2. Allows you to make the selection an odd or even length on one or more axes or set two or more axes equal to each other or the longest, shortest or average of them. Implementation thanks to @VorTechnix. + +Usage examples: + +```weacmd +//smake odd shrink +//smake even avg xz +//smake equal grow xy +//smake equal average +//smake equal zy x +``` + +#### ``: odd|even|equal + +Value | Description +--------|--------------- +`odd` | Round up or down, based on mode, all axes specified in `` to the nearest odd length relative to pos1 +`even` | Round up or down, based on mode, all axes specified in `` to the nearest even length relative to pos1 +`equal` | Set `` axes length equal to the length of `` axis if specified or to the length of the largest, smallest or average of the `` axes based on mode. + +#### ``: grow|shrink|average + +#### *If `` == odd or even:* + +Value | Description +----------------|-------------- +`grow` | Grow each axis specified in `` to the nearest odd/even number to itself +`shrink` | Shrink each axis specified in `` to the nearest odd/even number to itself +`average`/`avg` | Takes the average of all axes specified in `` and then for each specified axis grows or shrinks it, depending on whether it is less than or greater than the average, to the nearest odd/even number to itself + +#### *If `` == equal:* +The `` argument can be omitted and will not be parsed if present if `` is specified + +Value | Description +----------------|--------------- +`grow` | Grow each axis specified in `` to the length of the longest specified axis +`shrink` | Shrink each axis specified in `` to the length of the shortest specified axis +`average`/`avg` | Set each axis specified in `` to the average length of all the specified axes +If `` | `` becomes optional. If present it will be ignored. + +#### Additional arguments: + +Name | Description +------------|------------------ +`` | Specify axes to perform operation on (default= xz)| +``: If `` == odd or even | Does nothing +``: If `` == equal | Overrides `` and sets all `` axes equal to itself + +### `//sfactor []` +> [!WARNING] +> **REMOVED** in v1.15 in favour of [`//sgrow`](#sgrow) and [`//sshrink`](#sshrink) +Short for _selection factor_; alias: `//sfac`. Built specifically for use with `//maze`, this command sets targeted axes equal to the nearest multiple of `` based on the ``. + +Usage examples: + +```weacmd +//sfac grow 5 +//sfac avg 3 xy +``` + +#### ``: grow|shrink|average + +Value | Description +--------|-------------- +`grow` | Rounds the length of each target axis up to the nearest multiple of `` +`shrink` | Rounds the length of each target axis down to the nearest multiple of `` +`average`/`avg` | Takes the average of all axes specified in `` and then for each specified axis grows or shrinks it, depending on whether it is less than or greater than the average, to the nearest multiple of `` + +### `//sstack` +Displays the contents of your per-user selection stack. This stack can be pushed to and popped from rather like a stack of plates. See also `//spush` (for pushing to the selection stack) and `//spop` (for popping from the selection stack). + +```weacmd +//sstack +``` + +### `//spush` +Pushes the currently defined region onto your per-user selection stack. Does not otherwise alter the defined region. + +If the stack is full (currently the limit is set to 100 regions in the stack), then it will complain at you but otherwise will have no effect. + +Note that pos2 does _not_ need to be defined in order to use this. if it isn't defined, then a pos2 of `nil` will be pushed onto the stack instead. + +```weacmd +//spush +``` + +### `//spop` +Pops a selection off your per-user selection stack and applies it to the currently defined region. If pos2 from the item popped from the stack is nil, then pos2 is explicitly unset. If the stack is empty, this has no effect. + +```weacmd +//spop +``` + + + +## Measurement + + + +### `//mcount` +Alias for [`//count`](#count). + +``` +//mcount +``` + + +### `//mface` +Returns the horizontal (X/Z) axis or axes the player is looking along. +Aliases: `//mfacing`. + +``` +//mface +``` + + +### `//midpos` +Returns the coordinates of the centre of the current selection. + +``` +//midpos +``` + + +### `//msize` +Returns the lengths of the current selection on the X, Y and Z axes. + +``` +//msize +``` + + +### `//mtrig` +Returns the length of the diagonal from pos1 to pos2 and its angle on the XZ (horizontal) and Y (vertical) axes. + +``` +//mtrig +``` + + + +## Meta + + + +### `//subdivide ` +Splits the current WorldEdit region into `(, , )` sized chunks, and run `// ` over each chunk. + +Sometimes, we want to run a single command on a truly vast area. Usually, this results in running out of memory. If this was you, then this command is just what you need! It should be able to handle any sized region - the only limit is your patience for command to complete..... + +Note that this command only works with WorldEdit commands, and only those which require 2 points (e.g. `//torus` only requires a single point, so it wouldn't work very well - but `//set` or `//clearcut` would). + +Note also that `` should _not_ be prefixed with _any_ forward slashes - see the examples below. + +While other server commands can be executed while a `//subdivide` is running, `//subdivide` manipulates your player's defined region when running. This has the side-effect that you can check on where it has got up to with `//p get` for example - but means that attempting to change your pos1 & pos2 manually will have no effect until the `//subdivide` completes. + +> [!WARNING] +> Once started, this command cannot be stopped without restarting your server! This is the case with all WorldEdit commands, but it's worth a special mention here. + +```weacmd +//subdivide 10 10 10 set dirt +//subdivide 25 25 25 fixlight +``` + + +### `//multi .....` +Executes multi chat commands in sequence. Intended for _WorldEdit_ commands, but does work with others too. Don't forget a space between commands! + +```weacmd +//multi //set dirt //shift x 10 //set glass +``` + +Since WorldEditAdditions v1.12, curly brace syntax has also been introduced to allow nesting of commands: + +```weacmd +//multi //fixlight {//many 5 //bonemeal 3 100} +``` + +This syntax can also be nested arbitrarily in arbitrarily complex combinations, and can also be used multiple separate times in a single `//multi` invocation (if you find a bug, please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new)), though do remember that only `//multi` supports parsing out this syntax (e.g. if you want to nest multiple commands in a `//many` that's inside a `//multi`, you'll need a sub `//multi` there). + +In addition, this also allows for including a double forward slash in the argument list for a command, should you need to do so (e.g. `//multi //example {//bar //baz} //example` will be executed as 3 commands: `/example`, then `/bar` with an argument of `//baz`, then finally `/example`). + +```weacmd +//multi //1 //2 //shift z -10 //sphere 5 sand //shift z 20 //ellipsoid 5 3 5 ice +//multi //1 //hollowtorus 30 5 stone //hollowtorus 20 3 dirt //torus 10 2 dirt_with_grass +//multi /time 7:00 //1 //outset h 20 //outset v 5 //overlay dirt_with_grass //1 //2 //sphere 8 air //shift down 1 //floodfill //reset +``` + + +### `//many ` +Executes a single chat command many times in a row. Uses `minetest.after()` to yield to the main server thread to allow other things to happen at the same time, so technically you could have multiple `//many` calls going at once (but multithreading support is out of reach, so only a single one will be executing at the same time). + +Note that this isn't necessarily limited to executing WorldEdit / WorldEditAdditions commands. Combine with `//multi` (see above) execute multiple commands at once for even more power and flexibility! + +```weacmd +//many 10 //bonemeal 3 100 +//many 100 //multi //1 //2 //outset 20 //set dirt +``` + + +### `//ellipsoidapply ` +Executes the given command, and then clips the result to the largest ellipsoid that will fit inside the defined region. The specified command must obviously take 2 positions - so for example `//set`, `//replacemix`, and `//maze3d` will work, but `//sphere`, `//torus`, and `//floodfill` won't. + +For advanced users, `//multi` is also supported - but make sure your modifications stay within the defined region - otherwise they will not be affected by the ellipsoidal clipping operation. + +```weacmd +//ellipsoidapply set dirt +//ellipsoidapply maze3d dirt 4 2 2 +//ellipsoidapply erode +//ellipsoidapply replacemix sand bakedclay:red bakedclay:orange +//ellipsoidapply layers desert_sand sand 2 desert_sandstone 4 sandstone 10 +``` + + +### `//airapply ` +Like [`//ellipsoidapply`](#ellipsoidapply), but instead only keeps changes that replace airlike nodes, and discards any other changes made. + +As with `//ellipsoidapply` for advanced users `//multi` is also supported - but make sure your modifications stay within the defined region - otherwise they be kept regardless, as `//airapply` only applies the masking to the nodes in the defined region. + +```weacmd +//airapply set sandstone +//airapply maze3d dirt 4 2 2 +``` + + +### `//nodeapply [] [... ] -- ` +**Aliases:** `//napply` + +It's got `apply` in the name, so as you might imagine it works the same as [`//ellipsoidapply`](#ellipsoidapply), [`//airapply`](#airapply), [`//noiseapply2d`](#noiseapply2d), etc. Only changes made by the given command that replace nodes on the list given will be replaced. For example: + +```weacmd +//nodeapply dirt -- set stone +``` + +....is equivalent to `//replace dirt stone`, in that although `//set stone` will set all nodes to stone, `//nodeapply` will only keep the changes made by `//set` that affect dirt. + +There are some special keywords you can use too: + +Keyword | Meaning +----------------|----------------------------------- +`liquidlike` | Targets all nodes that behave like a liquid. +`airlike` | Targets all nodes that behave like air. Basically like [`//airapply`](#airapply). + +To give a further example, consider this: + +```weacmd +//nodeapply liquidlike -- set river_water_source +``` + +...this will replace all liquid-like nodes (e.g. water, lava, etc) with river water. + +In addition, any node names prefixed an at sign `@` are considered group names. For example: `@crumbly` would allow changes only to nodes that are a member of the `crumbly` group: + +```weacmd +//nodeapply @crumbly -- layers dirt_with_grass dirt 3 stone 10 +``` + +More misc examples to end this command description, as is customary: + +```weacmd +//nodeapply stone -- layers dirt_with_grass dirt 3 +//nodeapply stone dirt sand -- layers bakedclay:natural 3 bakedclay:orange 2 bakedclay:red 3 bakedclay:natural 3 +//nodeapply liquidlike -- set air +//nodeapply airlike -- mix stone 3 dirt 2 +``` + + +### `//noiseapply2d ` +Like [`//ellipsoidapply`](#ellipsoidapply), but instead only keeps changes where a noise function (defaults to `perlinmt`, see [`//noise2d`](#noise2d)) returns a value greater than a given threshold value. + +Also takes a scale value that controls the scale of the noise - -higher values result in smaller "blobs". If you're operating on small areas, then a value of at least 10 is advised as "blobs" are by default on the scale of ~50 nodes. + +As with `//ellipsoidapply` for advanced users `//multi` is also supported - but make sure your modifications stay within the defined region - otherwise they be kept regardless, as `//noiseapply2d` only applies the masking to the nodes in the defined region. + +Any suggestions on how to provide more customisability without making this command more difficult to use or significantly more inconsistent with other `//*apply` functions are welcome - please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new). + +```weacmd +//noiseapply2d 0.5 10 set dirt +//noiseapply2d 0.4 3 layers dirt_with_snow dirt 3 stone 10 +``` + +### `//for ... do // %% ` +For a given list of values, executes the specified command for each value, replacing `%%` with each value. Implementation thanks to @VorTechnix. + +To better illustrate what happens, consider the following command: + +``` +//for dirt stone glass do //replacemix air 10 %% +``` + +This is equivalent to executing the following 3 commands in sequence: + +``` +//replacemix air 10 dirt +//replacemix air 10 stone +//replacemix air 10 glass +``` + +Here are some more examples: + +``` +//for meselamp brick snowblock bamboo:wood do //multi //maze %% //sshift y 5 +//for 5 10 15 do //torus %% 3 dirt xz +//for 1 2 3 4 5 do //multi //hollowcylinder y 1 5 meselamp //shift y %% +``` + + +### `//listentities` +Lists all currently loaded ObjectRefs. Displays their IDs, Names (if possible), and positions. + +This command is intended for development and modding. You will not normally need to use this command using WorldEditAdditions. + +`//listentities` takes no arguments. + +``` +//listentities +``` + + +## Extras + + + +### `//speed []` +Adjusts your player movement speed to the specified value. In other words: + +```weacmd +//speed 2 +``` + +...will double your movement speed. + +This command also takes Minetest's "Fast mode" into account and adjusts accordingly. Relative adjustments can be done by prepending either a `+` to increase or `-` to decrease respectively. + +```weacmd +//speed +0.5 +//speed -3 +``` + + +### `//y` +Confirms the execution of a command if it could potentially affect a large number of nodes and take a while. This is a regular WorldEdit command. + + + +```weacmd +//y +``` + + +### `//n` +Prevents the execution of a command if it could potentially affect a large number of nodes and take a while. This is a regular WorldEdit command. + + + +```weacmd +//n +``` + + + +## Tools + + +### Movement speed adjustment tool +The movement speed adjustment tool, as the name suggests, adjusts your local player movement speed. It looks like this: ![A picture of the move speed adjustment tool. It looks like a monarch butterfly.](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/dev/worldeditadditions_farwand/textures/worldeditadditions_movement.png). + +Primary (left) clicking will increase your movement speed, and secondary (right) clicking will decrease it in x0.5 increments, down to a minimum of x0.5. + +Note this only affects **you**, and **not any other player**. + +See also [`//speed`](#speed). + +### Far Wand +The far wand (`worldeditadditions:farwand`) is a variant on the traditional WorldEdit wand (`worldedit:wand`). It looks like this: ![A picture of the far wand](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/worldeditadditions_farwand/textures/worldeditadditions_farwand.png) + +It functions very similarly to the regular WorldEdit wand, except that it has a _much_ longer range - which can be very useful for working on large-scale terrain for example. It also comes with an associated command to control it. + +Note that punching out the positions **does not unset them**. Use `//reset` to reset the defined region. + +### `//farwand skip_liquid (true|false) | maxdist ` +This command helps control the behaviour of the [WorldEditAdditions far wand](#far-wand) and [cloud wand](#cloud-wand). Calling it without any arguments shows the current status: + +```weacmd +//farwand +``` + +You can decide whether you can select liquids or not like so: + +```weacmd +//farwand skip_liquid true +//farwand skip_liquid false +``` + +You can change the maximum range with the `maxdist` subcommand: + +```weacmd +//farwand maxdist 1000 +//farwand maxdist 200 +//farwand maxdist 9999 +``` + +Note that the number there isn't in blocks (because hard maths). It is however proportional to the distance the wand will raycast looks for nodes, so a higher value will result in it raycasting further. + +### Cloud Wand +The cloud wand (`worldeditadditions:cloudwand`) is a another variant the above _Far Wand_. It looks like this: ![A picture of the far wand](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/worldeditadditions_farwand/textures/worldeditadditions_cloudwand.png) + +Unlike the other 2 wands, this wand functions in an additive manner. Left-click on a node to expand the currently defined region (creating a new one if one isn't defined already) to include that node. Right click to clear the currently defined region. + +It has the range of the _Far Wand_ mentioned above too, so you can select nodes from a great distance. It also abides by preferences set via the `//farwand` chat command. + +Note that punching out the positions **does not unset them**. Use `//reset` to reset the defined region. + + +### MultiPoint Wand +The third type of wand provided by WorldEditAdditions is completely different, in that it allows you to select up to **999 points** at once! It looks like this: ![A picture of the multi-point wand](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/worldeditadditions_farwand/textures/worldeditadditions_multiwand.png) + +It is important to note that (at present) the points selected by this wand **are not compatible with normal points**. This will change in the future, but requires a lot of work to implement. + +It has the following actions: + + - **Left click:** Add a new point + - **Right click:** Undo adding a point + +It has the range of the other wands mentioned above though, so you can select nodes from a great distance. It also abides by preferences set via the `//farwand` chat command.