mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-11-26 09:03:01 +00:00
Merge branch 'main' into VorTechnix
This commit is contained in:
commit
8789b39d1d
79 changed files with 713 additions and 253 deletions
|
@ -6,6 +6,7 @@ Note to self: See the bottom of this file for the release template text.
|
||||||
|
|
||||||
## v1.14: The untitled update (unreleased)
|
## v1.14: The untitled update (unreleased)
|
||||||
- Add `//dome+`, which allows you to change the direction the dome is pointing in, and also create multiple domes at once
|
- 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
|
||||||
- Migrate from `depends.txt` to `mod.conf`
|
- Migrate from `depends.txt` to `mod.conf`
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ When actually implementing stuff, here are a few guidelines that I recommend to
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██ ████ ██ ██ ██ ██ ███████
|
-- ██ ████ ██ ██ ██ ██ ███████
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
worldedit.register_command("{name}", {
|
worldeditadditions_core.register_command("{name}", {
|
||||||
params = "<argument> <argument=default> <option1|option2|...> [<optional_argument> <optional_argument2> ...] | [<optional_argument> [<optional_argument2>]]",
|
params = "<argument> <argument=default> <option1|option2|...> [<optional_argument> <optional_argument2> ...] | [<optional_argument> [<optional_argument2>]]",
|
||||||
description = "A **brief** description of what this command does",
|
description = "A **brief** description of what this command does",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -59,11 +59,11 @@ dofile(wea.modpath.."/lib/scale.lua")
|
||||||
dofile(wea.modpath.."/lib/spiral_square.lua")
|
dofile(wea.modpath.."/lib/spiral_square.lua")
|
||||||
dofile(wea.modpath.."/lib/spiral_circle.lua")
|
dofile(wea.modpath.."/lib/spiral_circle.lua")
|
||||||
dofile(wea.modpath.."/lib/dome.lua")
|
dofile(wea.modpath.."/lib/dome.lua")
|
||||||
dofile(wea.modpath.."/lib/metaballs.lua")
|
|
||||||
dofile(wea.modpath.."/lib/conv/conv.lua")
|
dofile(wea.modpath.."/lib/conv/conv.lua")
|
||||||
dofile(wea.modpath.."/lib/erode/erode.lua")
|
dofile(wea.modpath.."/lib/erode/erode.lua")
|
||||||
dofile(wea.modpath.."/lib/noise/init.lua")
|
dofile(wea.modpath.."/lib/noise/init.lua")
|
||||||
wea.sculpt = dofile(wea.modpath.."/lib/sculpt/init.lua")
|
wea.sculpt = dofile(wea.modpath.."/lib/sculpt/init.lua")
|
||||||
|
wea.metaballs = dofile(wea.modpath.."/lib/metaballs/init.lua")
|
||||||
|
|
||||||
dofile(wea.modpath.."/lib/copy.lua")
|
dofile(wea.modpath.."/lib/copy.lua")
|
||||||
dofile(wea.modpath.."/lib/move.lua")
|
dofile(wea.modpath.."/lib/move.lua")
|
||||||
|
|
16
worldeditadditions/lib/metaballs/init.lua
Normal file
16
worldeditadditions/lib/metaballs/init.lua
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
local wea = worldeditadditions
|
||||||
|
local wea_m = wea.modpath .. "/lib/metaballs/"
|
||||||
|
|
||||||
|
local playerdata = dofile(wea_m.."playerdata.lua")
|
||||||
|
|
||||||
|
local metaballs_ns = {
|
||||||
|
render = dofile(wea_m.."render.lua"),
|
||||||
|
add = playerdata.add,
|
||||||
|
remove = playerdata.remove,
|
||||||
|
list = playerdata.list,
|
||||||
|
list_pretty = playerdata.list_pretty,
|
||||||
|
clear = playerdata.clear,
|
||||||
|
volume = playerdata.volume
|
||||||
|
}
|
||||||
|
|
||||||
|
return metaballs_ns
|
125
worldeditadditions/lib/metaballs/playerdata.lua
Normal file
125
worldeditadditions/lib/metaballs/playerdata.lua
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
local wea = worldeditadditions
|
||||||
|
local Vector3 = wea.Vector3
|
||||||
|
|
||||||
|
local metaballdata = {}
|
||||||
|
|
||||||
|
--- Adds a new metaball for a given player at the specified position with a specified radius.
|
||||||
|
-- @param player_name string The name of the player.
|
||||||
|
-- @param pos Vector3 The position of the metaball.
|
||||||
|
-- @param radius number The radius of the metaball.
|
||||||
|
-- @returns bool,number The number of metaballs now defined for the given player.
|
||||||
|
local function add(player_name, pos, radius)
|
||||||
|
local pos = Vector3.clone(pos)
|
||||||
|
|
||||||
|
if type(player_name) ~= "string" then
|
||||||
|
return false, "Error: Invalid player name specified."
|
||||||
|
end
|
||||||
|
if type(radius) ~= "number" then
|
||||||
|
return false, "Error: Expected the radius to be of type number, but got value of type "..type(radius).." instead."
|
||||||
|
end
|
||||||
|
if radius < 1 then
|
||||||
|
return false, "The minimum radius of a metaball is 1, but got a radius of "..tostring(radius).."."
|
||||||
|
end
|
||||||
|
|
||||||
|
if not metaballdata[player_name] then
|
||||||
|
metaballdata[player_name] = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- TODO: Limit the number of metaballs that can be defined?
|
||||||
|
table.insert(metaballdata[player_name], {
|
||||||
|
pos = pos,
|
||||||
|
radius = radius
|
||||||
|
})
|
||||||
|
|
||||||
|
return true, #metaballdata[player_name]
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns a list of all metaballs defined for the given player.
|
||||||
|
-- @param player_name string The name of the player.
|
||||||
|
-- @returns bool,[{ pos: Vector3, radius: number }, ...] A list of metaballs for the given player.
|
||||||
|
local function list(player_name)
|
||||||
|
if type(player_name) ~= "string" then
|
||||||
|
return false, "Error: Invalid player name specified."
|
||||||
|
end
|
||||||
|
|
||||||
|
if not metaballdata[player_name] then return {} end
|
||||||
|
|
||||||
|
return true, metaballdata[player_name]
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns a pretty-printed list of metaballs for the given player.
|
||||||
|
-- @param player_name string The name of the player.
|
||||||
|
-- @returns bool,string A pretty-printed list of metaballs for the given player.
|
||||||
|
local function list_pretty(player_name)
|
||||||
|
local success, metaball_list = list(player_name)
|
||||||
|
if not success then return success, metaball_list end
|
||||||
|
|
||||||
|
local rows = { { "Index", "Position", "Radius" } }
|
||||||
|
for i,metaball in ipairs(metaball_list) do
|
||||||
|
table.insert(rows, {
|
||||||
|
i,
|
||||||
|
metaball.pos,
|
||||||
|
metaball.radius
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
return true, wea.format.make_ascii_table(rows).."\n---------------------------\nTotal "..tostring(#metaball_list).." metaballs"
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Removes the metaball with the specified index for a given player.
|
||||||
|
-- @param player_name string The name of the player.
|
||||||
|
-- @param index number The index of the metaball to remove.
|
||||||
|
-- @returns bool,number The number of metaballs now defined for the given player.
|
||||||
|
local function remove(player_name, index)
|
||||||
|
local success, metaball_list = list(player_name)
|
||||||
|
if not success then return success, metaball_list end
|
||||||
|
|
||||||
|
if index > #metaball_list then
|
||||||
|
return false, "Error: Requested the removal of metaball "..tostring(index)..", but there are "..tostring(#metaball_list).." metaballs defined."
|
||||||
|
end
|
||||||
|
|
||||||
|
table.remove(metaball_list, index)
|
||||||
|
|
||||||
|
return #metaball_list
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Removes all the currently defined metaballs for the given player.
|
||||||
|
-- @param player_name string The name of the player.
|
||||||
|
-- @returns bool,number The number of metaballs that WERE defined for the given player.
|
||||||
|
local function clear(player_name)
|
||||||
|
local success, metaball_list = list(player_name)
|
||||||
|
if not success then return success, metaball_list end
|
||||||
|
|
||||||
|
metaballdata[player_name] = {}
|
||||||
|
|
||||||
|
return #metaball_list
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Calculates the total volume that the currently defined metaballs are expected to take up.
|
||||||
|
-- @param player_name string The name of the player.
|
||||||
|
-- @returns bool,number The total volume that the currently defined metaballs are expected to take up.
|
||||||
|
local function volume(player_name)
|
||||||
|
local success, metaball_list = list(player_name)
|
||||||
|
if not success then return success, metaball_list end
|
||||||
|
|
||||||
|
if #metaball_list == 0 then return 0 end
|
||||||
|
|
||||||
|
local pos1 = metaball_list[1].pos
|
||||||
|
local pos2 = pos1
|
||||||
|
|
||||||
|
for i,metaball in ipairs(metaball_list) do
|
||||||
|
pos1 = Vector3.min(pos1, metaball.pos - metaball.radius)
|
||||||
|
pos2 = Vector3.max(pos2, metaball.pos + metaball.radius)
|
||||||
|
end
|
||||||
|
|
||||||
|
return (pos2 - pos1):area()
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
add = add,
|
||||||
|
list = list,
|
||||||
|
list_pretty = list_pretty,
|
||||||
|
remove = remove,
|
||||||
|
clear = clear,
|
||||||
|
volume = volume
|
||||||
|
}
|
|
@ -10,7 +10,7 @@ local Vector3 = wea.Vector3
|
||||||
-- direction the point should point.
|
-- direction the point should point.
|
||||||
-- @param metaballs [{pos: Vector3, radius: number}] Aa list of metaballs to render. Each metaball should be a table with 2 properties: pos - the position of the centre of the metaball as a Vector3, and radius - the radius of the metaball.
|
-- @param metaballs [{pos: Vector3, radius: number}] Aa list of metaballs to render. Each metaball should be a table with 2 properties: pos - the position of the centre of the metaball as a Vector3, and radius - the radius of the metaball.
|
||||||
-- @param replace_node string The fully qualified name of the node to use to make the dome with.
|
-- @param replace_node string The fully qualified name of the node to use to make the dome with.
|
||||||
function worldeditadditions.metaballs(metaballs, replace_node, threshold)
|
local function render(metaballs, replace_node, threshold)
|
||||||
local pos1, pos2
|
local pos1, pos2
|
||||||
if not threshold then threshold = 1 end
|
if not threshold then threshold = 1 end
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ function worldeditadditions.metaballs(metaballs, replace_node, threshold)
|
||||||
metaball_sum = metaball_sum + falloff
|
metaball_sum = metaball_sum + falloff
|
||||||
end
|
end
|
||||||
|
|
||||||
if metaball_sum <= threshold then
|
if metaball_sum >= threshold then
|
||||||
data[area:index(x, y, z)] = node_id_replace
|
data[area:index(x, y, z)] = node_id_replace
|
||||||
replaced = replaced + 1
|
replaced = replaced + 1
|
||||||
end
|
end
|
||||||
|
@ -61,3 +61,6 @@ function worldeditadditions.metaballs(metaballs, replace_node, threshold)
|
||||||
|
|
||||||
return true, replaced
|
return true, replaced
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return render
|
|
@ -1,4 +1,4 @@
|
||||||
name = worldeditadditions
|
name = worldeditadditions
|
||||||
description = Extra tools and commands to extend WorldEdit for Minetest
|
description = Extra tools and commands to extend WorldEdit for Minetest
|
||||||
depends = worldedit
|
depends = worldedit
|
||||||
optional_depends = bonemeal, cool_trees, default, moretrees, ethereal
|
optional_depends = worldeditadditions_core, bonemeal, cool_trees, default, moretrees, ethereal
|
||||||
|
|
23
worldeditadditions_commands/aliases.lua
Normal file
23
worldeditadditions_commands/aliases.lua
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
local wea_c = worldeditadditions_core
|
||||||
|
|
||||||
|
wea_c.register_alias("smoothadv", "convolve")
|
||||||
|
wea_c.register_alias("conv", "convolve")
|
||||||
|
|
||||||
|
wea_c.register_alias("naturalise", "layers")
|
||||||
|
wea_c.register_alias("naturalize", "layers")
|
||||||
|
|
||||||
|
wea_c.register_alias("flora", "bonemeal")
|
||||||
|
|
||||||
|
-- Measure Tools
|
||||||
|
wea_c.register_alias("mcount", "count")
|
||||||
|
wea_c.register_alias("mfacing", "mface")
|
||||||
|
|
||||||
|
|
||||||
|
--- Overrides to core WorldEdit commands
|
||||||
|
-- These are commented out for now, as they could be potentially dangerous to stability
|
||||||
|
-- Thorough testing is required of our replacement commands before these are uncommented
|
||||||
|
-- TODO: Depend on worldeditadditions_core before uncommenting this
|
||||||
|
-- BUG: //move+ seems to be leaving stuff behind for some strange reason --@sbrl 2021-12-26
|
||||||
|
-- worldeditadditions_core.alias_override("copy", "copy+")
|
||||||
|
-- worldeditadditions_core.alias_override("move", "move+") -- MAY have issues where it doesn't overwrite the old region properly, but haven't been able to reliably reproduce this
|
||||||
|
-- worldeditadditions_core.alias_override("replace", "replacemix")
|
|
@ -6,7 +6,7 @@ local wea = worldeditadditions
|
||||||
-- ██████ ██ ██ ██ ██ ██ █████ ██ ████ ██ █████ ███████ ██
|
-- ██████ ██ ██ ██ ██ ██ █████ ██ ████ ██ █████ ███████ ██
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██████ ██████ ██ ████ ███████ ██ ██ ███████ ██ ██ ███████
|
-- ██████ ██████ ██ ████ ███████ ██ ██ ███████ ██ ██ ███████
|
||||||
worldedit.register_command("bonemeal", {
|
worldeditadditions_core.register_command("bonemeal", {
|
||||||
params = "[<strength> [<chance> [<node_name> [<node_name> ...]]]]",
|
params = "[<strength> [<chance> [<node_name> [<node_name> ...]]]]",
|
||||||
description = "Bonemeals everything that's bonemeal-able that has an air node directly above it. Optionally takes a strength value to use (default: 1, maximum: 4), and a chance to actually bonemeal an eligible node (positive integer; nodes have a 1-in-<chance> chance to be bonemealed; higher values mean a lower chance; default: 1 - 100% chance).",
|
description = "Bonemeals everything that's bonemeal-able that has an air node directly above it. Optionally takes a strength value to use (default: 1, maximum: 4), and a chance to actually bonemeal an eligible node (positive integer; nodes have a 1-in-<chance> chance to be bonemealed; higher values mean a lower chance; default: 1 - 100% chance).",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -6,7 +6,7 @@ local Vector3 = wea.Vector3
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ █████
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ █████
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██████ ██████ ██ ████ ████ ██████ ███████ ████ ███████
|
-- ██████ ██████ ██ ████ ████ ██████ ███████ ████ ███████
|
||||||
worldedit.register_command("convolve", {
|
worldeditadditions_core.register_command("convolve", {
|
||||||
params = "<kernel> [<width>[,<height>]] [<sigma>]",
|
params = "<kernel> [<width>[,<height>]] [<sigma>]",
|
||||||
description = "Advanced version of //smooth from we_env. Convolves over the defined region with the given kernel. Possible kernels: box, pascal, gaussian. The width & height (if specified) must be odd integers. If the height is not specified, it defaults to the width. gaussian should give the smoothest result, but the width & height must be identical. The sigma value is only applicable to gaussian kernels, and can be thought of as the 'smoothness' to apply.",
|
description = "Advanced version of //smooth from we_env. Convolves over the defined region with the given kernel. Possible kernels: box, pascal, gaussian. The width & height (if specified) must be odd integers. If the height is not specified, it defaults to the width. gaussian should give the smoothest result, but the width & height must be identical. The sigma value is only applicable to gaussian kernels, and can be thought of as the 'smoothness' to apply.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -24,7 +24,7 @@ end
|
||||||
-- ██ ██ ██ ██████ ████
|
-- ██ ██ ██ ██████ ████
|
||||||
-- ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██
|
||||||
-- ██████ ██████ ██ ██
|
-- ██████ ██████ ██ ██
|
||||||
worldedit.register_command("copy+", { -- TODO: Make this an override
|
worldeditadditions_core.register_command("copy+", { -- TODO: Make this an override
|
||||||
params = "<axis:x|y|z|-x|-y|-z|?|front|back|left|right|up|down> <count> [<axis> <count> [...]]",
|
params = "<axis:x|y|z|-x|-y|-z|?|front|back|left|right|up|down> <count> [<axis> <count> [...]]",
|
||||||
description = "Copies the defined region to another location - potentially across multiple axes at once.",
|
description = "Copies the defined region to another location - potentially across multiple axes at once.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██████ ██████ ██████ ██ ████ ██
|
-- ██████ ██████ ██████ ██ ████ ██
|
||||||
worldedit.register_command("count", {
|
worldeditadditions_core.register_command("count", {
|
||||||
params = "",
|
params = "",
|
||||||
description = "Counts all the nodes in the defined region.",
|
description = "Counts all the nodes in the defined region.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -25,7 +25,7 @@ end
|
||||||
-- ██ ██ ██ ██ ██ ████ ██ █████
|
-- ██ ██ ██ ██ ██ ████ ██ █████
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██████ ██████ ██ ██ ███████
|
-- ██████ ██████ ██ ██ ███████
|
||||||
worldedit.register_command("dome+", { -- TODO: Make this an override
|
worldeditadditions_core.register_command("dome+", { -- TODO: Make this an override
|
||||||
params = "<radius> <replace_node> [<pointing_dir:x|y|z|-x|-y|-z|?|front|back|left|right|up|down> ...] [h[ollow]]",
|
params = "<radius> <replace_node> [<pointing_dir:x|y|z|-x|-y|-z|?|front|back|left|right|up|down> ...] [h[ollow]]",
|
||||||
description = "Creates a dome shape with a specified radius of the defined node, optionally specifying the direction it should be pointing in (defaults to the positive y direction).",
|
description = "Creates a dome shape with a specified radius of the defined node, optionally specifying the direction it should be pointing in (defaults to the positive y direction).",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -30,7 +30,7 @@ local function parse_params_ellipsoid(params_text)
|
||||||
return true, replace_node, radius, hollow
|
return true, replace_node, radius, hollow
|
||||||
end
|
end
|
||||||
|
|
||||||
worldedit.register_command("ellipsoid", {
|
worldeditadditions_core.register_command("ellipsoid", {
|
||||||
params = "<rx> <ry> <rz> <replace_node> [h[ollow]]",
|
params = "<rx> <ry> <rz> <replace_node> [h[ollow]]",
|
||||||
description = "Creates a 3D ellipsoid with a radius of (rx, ry, rz) at pos1, filled with <replace_node>.",
|
description = "Creates a 3D ellipsoid with a radius of (rx, ry, rz) at pos1, filled with <replace_node>.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
@ -53,7 +53,7 @@ worldedit.register_command("ellipsoid", {
|
||||||
})
|
})
|
||||||
|
|
||||||
-- TODO: This duplicates a lot of code. Perhaps we can trim it down a bit?
|
-- TODO: This duplicates a lot of code. Perhaps we can trim it down a bit?
|
||||||
worldedit.register_command("hollowellipsoid", {
|
worldeditadditions_core.register_command("hollowellipsoid", {
|
||||||
params = "<rx> <ry> <rz> <replace_node>",
|
params = "<rx> <ry> <rz> <replace_node>",
|
||||||
description = "Creates a 3D hollow ellipsoid with a radius of (rx, ry, rz) at pos1, made out of <replace_node>.",
|
description = "Creates a 3D hollow ellipsoid with a radius of (rx, ry, rz) at pos1, made out of <replace_node>.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
-- ███████ ███████ ███████ ██ ██ ███████ ██████ ██ ██████
|
-- ███████ ███████ ███████ ██ ██ ███████ ██████ ██ ██████
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
|
|
||||||
worldedit.register_command("ellipsoid2", {
|
worldeditadditions_core.register_command("ellipsoid2", {
|
||||||
params = "[<replace_node:dirt> [h[ollow]]]",
|
params = "[<replace_node:dirt> [h[ollow]]]",
|
||||||
description = "Creates am optionally hollow 3D ellipsoid that fills the defined region, filled with <replace_node>.",
|
description = "Creates am optionally hollow 3D ellipsoid that fills the defined region, filled with <replace_node>.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
-- █████ ██████ ██ ██ ██ ██ █████
|
-- █████ ██████ ██ ██ ██ ██ █████
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ███████ ██ ██ ██████ ██████ ███████
|
-- ███████ ██ ██ ██████ ██████ ███████
|
||||||
worldedit.register_command("erode", {
|
worldeditadditions_core.register_command("erode", {
|
||||||
params = "[<snowballs|river> [<key_1> [<value_1>]] [<key_2> [<value_2>]] ...]",
|
params = "[<snowballs|river> [<key_1> [<value_1>]] [<key_2> [<value_2>]] ...]",
|
||||||
description = "**experimental** Runs the specified erosion algorithm over the given defined region. This may occur in 2d or 3d. Currently implemented algorithms: snowballs (default;2d hydraulic-like). Also optionally takes an arbitrary set of key - value pairs representing parameters to pass to the algorithm. See the full documentation for details.",
|
description = "**experimental** Runs the specified erosion algorithm over the given defined region. This may occur in 2d or 3d. Currently implemented algorithms: snowballs (default;2d hydraulic-like). Also optionally takes an arbitrary set of key - value pairs representing parameters to pass to the algorithm. See the full documentation for details.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
-- ██████ ███████ ███████ █████ ██ ██ ██ ███████ ██ ████ ██ █████
|
-- ██████ ███████ ███████ █████ ██ ██ ██ ███████ ██ ████ ██ █████
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██████ ██ ██ ███████ ███████ ██ ████ ██ ██ ██ ██ ███████
|
-- ██████ ██ ██ ███████ ███████ ██ ████ ██ ██ ██ ██ ███████
|
||||||
worldedit.register_command("basename", {
|
worldeditadditions_core.register_command("basename", {
|
||||||
params = "<nodealias>",
|
params = "<nodealias>",
|
||||||
description = "Returns the base name of nodes that use a given alias.",
|
description = "Returns the base name of nodes that use a given alias.",
|
||||||
privs = {worldedit = true},
|
privs = {worldedit = true},
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
-- █████ ██ ██ ██ ██ ███████ ██ ██ █████ ███████
|
-- █████ ██ ██ ██ ██ ███████ ██ ██ █████ ███████
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██ ██ ███████ ███████ ██████ ██ ██ ████ ███████ ███████
|
-- ██ ██ ███████ ███████ ██████ ██ ██ ████ ███████ ███████
|
||||||
worldedit.register_command("fillcaves", {
|
worldeditadditions_core.register_command("fillcaves", {
|
||||||
params = "[<node_name>]",
|
params = "[<node_name>]",
|
||||||
description = "Fills in all airlike nodes beneath the first non-airlike node detected in each column.",
|
description = "Fills in all airlike nodes beneath the first non-airlike node detected in each column.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
-- █████ ██ ██ ██ ██ ██ ██ ██ █████ ██ ██ ██
|
-- █████ ██ ██ ██ ██ ██ ██ ██ █████ ██ ██ ██
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██ ███████ ██████ ██████ ██████ ██ ██ ███████ ███████
|
-- ██ ███████ ██████ ██████ ██████ ██ ██ ███████ ███████
|
||||||
worldedit.register_command("floodfill", {
|
worldeditadditions_core.register_command("floodfill", {
|
||||||
params = "[<replace_node> [<radius>]]",
|
params = "[<replace_node> [<radius>]]",
|
||||||
description = "Floods all connected nodes of the same type starting at pos1 with <replace_node> (which defaults to `water_source`), in a sphere with a radius of <radius> (which defaults to 20).",
|
description = "Floods all connected nodes of the same type starting at pos1 with <replace_node> (which defaults to `water_source`), in a sphere with a radius of <radius> (which defaults to 20).",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -6,7 +6,7 @@ local wea = worldeditadditions
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██ ██████ ██ ██ ███████ ███████ ██
|
-- ██ ██████ ██ ██ ███████ ███████ ██
|
||||||
|
|
||||||
worldedit.register_command("forest", {
|
worldeditadditions_core.register_command("forest", {
|
||||||
params = "[<density>] <sapling_a> [<chance_a>] <sapling_b> [<chance_b>] [<sapling_N> [<chance_N>]] ...",
|
params = "[<density>] <sapling_a> [<chance_a>] <sapling_b> [<chance_b>] [<sapling_N> [<chance_N>]] ...",
|
||||||
description = "Plants and grows trees in the defined region according to the given list of sapling names and chances and density factor. The density controls the relative density of the resulting forest, and defaults to 1 (floating-point numbers allowed). Higher chance numbers result in a lower relative chance with respect to other saplings in the list. Saplings that fail to grow are subsequently removed (this will affect pre-existing saplings too).",
|
description = "Plants and grows trees in the defined region according to the given list of sapling names and chances and density factor. The density controls the relative density of the resulting forest, and defaults to 1 (floating-point numbers allowed). Higher chance numbers result in a lower relative chance with respect to other saplings in the list. Saplings that fail to grow are subsequently removed (this will affect pre-existing saplings too).",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
-- ███████ ██ ██ ██ ██ ██ ██ ██ █ ██
|
-- ███████ ██ ██ ██ ██ ██ ██ ██ █ ██
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██
|
||||||
-- ██ ██ ██████ ███████ ███████ ██████ ███ ███
|
-- ██ ██ ██████ ███████ ███████ ██████ ███ ███
|
||||||
worldedit.register_command("hollow", {
|
worldeditadditions_core.register_command("hollow", {
|
||||||
params = "[<wall_thickness>]",
|
params = "[<wall_thickness>]",
|
||||||
description = "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 leaving walls of a given thickness (default: 1)",
|
description = "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 leaving walls of a given thickness (default: 1)",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -26,7 +26,7 @@ end
|
||||||
-- ██ ██ ██ ██ █████ ██████ ██ ███████ ████
|
-- ██ ██ ██ ██ █████ ██████ ██ ███████ ████
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██████ ████ ███████ ██ ██ ███████ ██ ██ ██
|
-- ██████ ████ ███████ ██ ██ ███████ ██ ██ ██
|
||||||
worldedit.register_command("layers", {
|
worldeditadditions_core.register_command("layers", {
|
||||||
params = "[<max_slope|min_slope..max_slope>] [<node_name_1> [<layer_count_1>]] [<node_name_2> [<layer_count_2>]] ...",
|
params = "[<max_slope|min_slope..max_slope>] [<node_name_1> [<layer_count_1>]] [<node_name_2> [<layer_count_2>]] ...",
|
||||||
description = "Replaces the topmost non-airlike nodes with layers of the given nodes from top to bottom. Like WorldEdit for MC's //naturalize command. Optionally takes a maximum or minimum and maximum slope value. If a column's slope value falls outside the defined range, then it's skipped. Default: dirt_with_grass dirt 3",
|
description = "Replaces the topmost non-airlike nodes with layers of the given nodes from top to bottom. Like WorldEdit for MC's //naturalize command. Optionally takes a maximum or minimum and maximum slope value. If a column's slope value falls outside the defined range, then it's skipped. Default: dirt_with_grass dirt 3",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
-- ██ ██ ██ ██ ██ █████
|
-- ██ ██ ██ ██ ██ █████
|
||||||
-- ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██
|
||||||
-- ███████ ██ ██ ████ ███████
|
-- ███████ ██ ██ ████ ███████
|
||||||
worldedit.register_command("line", {
|
worldeditadditions_core.register_command("line", {
|
||||||
params = "[<replace_node> [<radius>]]",
|
params = "[<replace_node> [<radius>]]",
|
||||||
description = "Draws a line of a given radius (default: 1) from pos1 to pos2 in the given node (default: dirt).",
|
description = "Draws a line of a given radius (default: 1) from pos1 to pos2 in the given node (default: dirt).",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
local we_c = worldeditadditions_commands
|
local wea_c = worldeditadditions_core
|
||||||
local Vector3 = worldeditadditions.Vector3
|
local Vector3 = worldeditadditions.Vector3
|
||||||
|
|
||||||
local function parse_params_maze(params_text, is_3d)
|
local function parse_params_maze(params_text, is_3d)
|
||||||
|
@ -61,7 +61,7 @@ end
|
||||||
-- ██ ██ ██ ██ ██ ███ ██
|
-- ██ ██ ██ ██ ██ ███ ██
|
||||||
-- ██ ██ ██ ██ ███████ ███████
|
-- ██ ██ ██ ██ ███████ ███████
|
||||||
|
|
||||||
worldedit.register_command("maze", {
|
wea_c.register_command("maze", {
|
||||||
params = "<replace_node> [<path_length> [<path_width> [<seed>]]]",
|
params = "<replace_node> [<path_length> [<path_width> [<seed>]]]",
|
||||||
description = "Generates a maze covering the currently selected area (must be at least 3x3 on the x,z axes) with replace_node as the walls. Optionally takes a (integer) seed and the path length and width (see the documentation in the worldeditadditions README for more information).",
|
description = "Generates a maze covering the currently selected area (must be at least 3x3 on the x,z axes) with replace_node as the walls. Optionally takes a (integer) seed and the path length and width (see the documentation in the worldeditadditions README for more information).",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
@ -100,7 +100,7 @@ worldedit.register_command("maze", {
|
||||||
-- ██ ██ ██ ██ ██ ███ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ███ ██ ██ ██ ██
|
||||||
-- ██ ██ ██ ██ ███████ ███████ ██████ ██████
|
-- ██ ██ ██ ██ ███████ ███████ ██████ ██████
|
||||||
|
|
||||||
worldedit.register_command("maze3d", {
|
wea_c.register_command("maze3d", {
|
||||||
params = "<replace_node> [<path_length> [<path_width> [<path_depth> [<seed>]]]]",
|
params = "<replace_node> [<path_length> [<path_width> [<path_depth> [<seed>]]]]",
|
||||||
description = "Generates a 3d maze covering the currently selected area (must be at least 3x3x3) with replace_node as the walls. Optionally takes a (integer) seed and the path length, width, and depth (see the documentation in the worldeditadditions README for more information).",
|
description = "Generates a 3d maze covering the currently selected area (must be at least 3x3x3) with replace_node as the walls. Optionally takes a (integer) seed and the path length, width, and depth (see the documentation in the worldeditadditions README for more information).",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██ ██ ██ ██ ██ ██████ ███████
|
-- ██ ██ ██ ██ ██ ██████ ███████
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
worldedit.register_command("mface", {
|
worldeditadditions_core.register_command("mface", {
|
||||||
params = "",
|
params = "",
|
||||||
description = "Return player facing axis.",
|
description = "Return player facing axis.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██ ██ ██ ██████ ██ ██████ ███████
|
-- ██ ██ ██ ██████ ██ ██████ ███████
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
worldedit.register_command("midpos", {
|
worldeditadditions_core.register_command("midpos", {
|
||||||
params = "",
|
params = "",
|
||||||
description = "Return the mid point of current selection.",
|
description = "Return the mid point of current selection.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
-- ██ ██ ██ ██ ██ ███ ██
|
-- ██ ██ ██ ██ ██ ███ ██
|
||||||
-- ██ ██ ███████ ██ ███████ ███████
|
-- ██ ██ ███████ ██ ███████ ███████
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
worldedit.register_command("msize", {
|
worldeditadditions_core.register_command("msize", {
|
||||||
params = "",
|
params = "",
|
||||||
description = "Return the length of each axis of current selection.",
|
description = "Return the length of each axis of current selection.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
-- ██ ██ ██ ██ ██ ██ ██████
|
-- ██ ██ ██ ██ ██ ██ ██████
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
local v3 = worldeditadditions.Vector3
|
local v3 = worldeditadditions.Vector3
|
||||||
worldedit.register_command("mtrig", {
|
worldeditadditions_core.register_command("mtrig", {
|
||||||
params = "",
|
params = "",
|
||||||
description = "Return the length of and angles of an imginary line between pos1 and pos2 in the selection.",
|
description = "Return the length of and angles of an imginary line between pos1 and pos2 in the selection.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
-- ███████ ██ ██████ ███████ ██████ ██████ ██ ████
|
-- ███████ ██ ██████ ███████ ██████ ██████ ██ ████
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ███████ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ███████ ██
|
||||||
|
local wea_c = worldeditadditions_core
|
||||||
|
|
||||||
|
worldeditadditions_core.register_command("airapply", {
|
||||||
worldedit.register_command("airapply", {
|
|
||||||
params = "<command_name> <args>",
|
params = "<command_name> <args>",
|
||||||
description = "Executes the given command (automatically prepending '//'), but only on non-air nodes within the defined region.",
|
description = "Executes the given command (automatically prepending '//'), but only on non-air nodes within the defined region.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
@ -20,7 +20,7 @@ worldedit.register_command("airapply", {
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Note that we search the worldedit commands here, not the minetest ones
|
-- Note that we search the worldedit commands here, not the minetest ones
|
||||||
local cmd_we = worldedit.registered_commands[cmd_name]
|
local cmd_we = wea_c.fetch_command_def(cmd_name)
|
||||||
if cmd_we == nil then
|
if cmd_we == nil then
|
||||||
return false, "Error: "..cmd_name.." isn't a valid command."
|
return false, "Error: "..cmd_name.." isn't a valid command."
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
-- █████ ██ ██ ██ ██████ ███████ █████ ███████ ██████ ██████ ██ ████
|
-- █████ ██ ██ ██ ██████ ███████ █████ ███████ ██████ ██████ ██ ████
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ███████ ███████ ███████ ██ ██ ███████ ███████ ██ ██ ██ ██ ███████ ██
|
-- ███████ ███████ ███████ ██ ██ ███████ ███████ ██ ██ ██ ██ ███████ ██
|
||||||
|
local wea_c = worldeditadditions_core
|
||||||
|
|
||||||
worldedit.register_command("ellipsoidapply", {
|
worldeditadditions_core.register_command("ellipsoidapply", {
|
||||||
params = "<command_name> <args>",
|
params = "<command_name> <args>",
|
||||||
description = "Executes the given command (automatically prepending '//'), clipping the result with an ellipse given by the defined region.",
|
description = "Executes the given command (automatically prepending '//'), clipping the result with an ellipse given by the defined region.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
@ -21,7 +22,7 @@ worldedit.register_command("ellipsoidapply", {
|
||||||
-- print("cmd_name", cmd_name, "args_text", args_text)
|
-- print("cmd_name", cmd_name, "args_text", args_text)
|
||||||
|
|
||||||
-- Note that we search the worldedit commands here, not the minetest ones
|
-- Note that we search the worldedit commands here, not the minetest ones
|
||||||
local cmd_we = worldedit.registered_commands[cmd_name]
|
local cmd_we = wea_c.fetch_command_def(cmd_name)
|
||||||
if cmd_we == nil then
|
if cmd_we == nil then
|
||||||
return false, "Error: "..cmd_name.." isn't a valid command."
|
return false, "Error: "..cmd_name.." isn't a valid command."
|
||||||
end
|
end
|
||||||
|
|
|
@ -45,7 +45,7 @@ local function step(params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
worldedit.register_command("for", {
|
worldeditadditions_core.register_command("for", {
|
||||||
params = "<value1> <value2> <value3>... do //<command> <arg> %% <arg>",
|
params = "<value1> <value2> <value3>... do //<command> <arg> %% <arg>",
|
||||||
description = "Executes a chat command for each value before \" do \" replacing any instances of \"%%\" with those values. The forward slashes at the beginning of the chat command must be the same as if you were executing it normally.",
|
description = "Executes a chat command for each value before \" do \" replacing any instances of \"%%\" with those values. The forward slashes at the beginning of the chat command must be the same as if you were executing it normally.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -45,7 +45,7 @@ local function step(params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
worldedit.register_command("macro", {
|
worldeditadditions_core.register_command("macro", {
|
||||||
params = "<file> [<delay=0>]",
|
params = "<file> [<delay=0>]",
|
||||||
description = "Load commands from \"(world folder)/macros/<file>[.weamac | .wmac]\" with position 1 of the current WorldEdit region as the origin.",
|
description = "Load commands from \"(world folder)/macros/<file>[.weamac | .wmac]\" with position 1 of the current WorldEdit region as the origin.",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
-- ██ ██ ██ ██ ██ ██ ███████ █████ ███████ ██████ ██████ ██ ████ █████ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ███████ █████ ███████ ██████ ██████ ██ ████ █████ ██ ██
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██ ████ ██████ ██ ███████ ███████ ██ ██ ██ ██ ███████ ██ ███████ ██████
|
-- ██ ████ ██████ ██ ███████ ███████ ██ ██ ██ ██ ███████ ██ ███████ ██████
|
||||||
|
local wea_c = worldeditadditions_core
|
||||||
|
|
||||||
|
|
||||||
worldedit.register_command("noiseapply2d", {
|
worldeditadditions_core.register_command("noiseapply2d", {
|
||||||
params = "<threshold> <scale> <command_name> <args>",
|
params = "<threshold> <scale> <command_name> <args>",
|
||||||
description = "Executes the given command (automatically prepending '//'), but uses a 2d noise function with both a threshold value (a number between 0 and 1) and a scale value (number, 1 = normal scale, for small areas 10+ is recommended) to filter where in the defined region it's applied.",
|
description = "Executes the given command (automatically prepending '//'), but uses a 2d noise function with both a threshold value (a number between 0 and 1) and a scale value (number, 1 = normal scale, for small areas 10+ is recommended) to filter where in the defined region it's applied.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
@ -19,7 +20,7 @@ worldedit.register_command("noiseapply2d", {
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Note that we search the worldedit commands here, not the minetest ones
|
-- Note that we search the worldedit commands here, not the minetest ones
|
||||||
local cmd_we = worldedit.registered_commands[cmd_name]
|
local cmd_we = wea_c.fetch_command_def(cmd_name)
|
||||||
if cmd_we == nil then
|
if cmd_we == nil then
|
||||||
return false, "Error: "..cmd_name.." isn't a valid command."
|
return false, "Error: "..cmd_name.." isn't a valid command."
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
|
local wea_c = worldeditadditions_core
|
||||||
|
|
||||||
-- Test command:
|
-- Test command:
|
||||||
-- //multi //fp set1 1330 60 5455 //fp set2 1355 35 5430 //subdivide 10 10 10 fixlight //y
|
-- //multi //fp set1 1330 60 5455 //fp set2 1355 35 5430 //subdivide 10 10 10 fixlight //y
|
||||||
|
|
||||||
local function will_trigger_saferegion(name, cmd_name, args)
|
local function will_trigger_saferegion(name, cmd_name, args)
|
||||||
if not worldedit.registered_commands[cmd_name] then return nil, "Error: That worldedit command could not be found (perhaps it hasn't been upgraded to worldedit.register_command() yet?)" end
|
local def = wea_c.fetch_command_def(cmd_name)
|
||||||
local def = worldedit.registered_commands[cmd_name]
|
if not def then return nil, "Error: That worldedit command could not be found (perhaps it hasn't been upgraded to worldedit.register_command() yet?)" end
|
||||||
if not def.parse then return nil, "Error: No parse method found (this is a bug)." end
|
if not def.parse then return nil, "Error: No parse method found (this is a bug)." end
|
||||||
|
|
||||||
local parsed = {def.parse(args)}
|
local parsed = {def.parse(args)}
|
||||||
|
@ -29,7 +30,7 @@ local function emerge_stats_tostring(tbl_emerge)
|
||||||
return table.concat(result, ", ")
|
return table.concat(result, ", ")
|
||||||
end
|
end
|
||||||
|
|
||||||
worldedit.register_command("subdivide", {
|
worldeditadditions_core.register_command("subdivide", {
|
||||||
params = "<size_x> <size_y> <size_z> <command> <params>",
|
params = "<size_x> <size_y> <size_z> <command> <params>",
|
||||||
description = "Subdivides the given worldedit area into chunks and runs a worldedit command multiple times to cover the defined region. Note that the given command must NOT be prepended with any forward slashes - just like //cubeapply.",
|
description = "Subdivides the given worldedit area into chunks and runs a worldedit command multiple times to cover the defined region. Note that the given command must NOT be prepended with any forward slashes - just like //cubeapply.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
@ -57,7 +58,7 @@ worldedit.register_command("subdivide", {
|
||||||
|
|
||||||
local cmd_name = parts[4]
|
local cmd_name = parts[4]
|
||||||
|
|
||||||
if not worldedit.registered_commands[cmd_name] then
|
if not wea_c.fetch_command_def(cmd_name) then
|
||||||
return false, "Error: The worldedit command '"..parts[4].."' does not exist (try /help)."
|
return false, "Error: The worldedit command '"..parts[4].."' does not exist (try /help)."
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -73,7 +74,7 @@ worldedit.register_command("subdivide", {
|
||||||
local pos1, pos2 = worldedit.sort_pos(worldedit.pos1[name], worldedit.pos2[name])
|
local pos1, pos2 = worldedit.sort_pos(worldedit.pos1[name], worldedit.pos2[name])
|
||||||
local volume = worldedit.volume(pos1, pos2)
|
local volume = worldedit.volume(pos1, pos2)
|
||||||
|
|
||||||
local cmd = worldedit.registered_commands[cmd_name]
|
local cmd = wea_c.fetch_command_def(cmd_name)
|
||||||
-- Note that we don't need to check for //multi privileges, as it does it at runtime
|
-- Note that we don't need to check for //multi privileges, as it does it at runtime
|
||||||
if not minetest.check_player_privs(name, cmd.privs) then
|
if not minetest.check_player_privs(name, cmd.privs) then
|
||||||
return false, "Error: Your privileges are unsufficient to run '"..cmd_name.."'."
|
return false, "Error: Your privileges are unsufficient to run '"..cmd_name.."'."
|
||||||
|
|
155
worldeditadditions_commands/commands/metaball.lua
Normal file
155
worldeditadditions_commands/commands/metaball.lua
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
local wea = worldeditadditions
|
||||||
|
local Vector3 = wea.Vector3
|
||||||
|
|
||||||
|
-- ██████ ██████ ███ ███ ███████
|
||||||
|
-- ██ ██ ██ ██ ████ ████ ██
|
||||||
|
-- ██ ██ ██ ██ ██ ████ ██ █████
|
||||||
|
-- ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
|
-- ██████ ██████ ██ ██ ███████
|
||||||
|
worldeditadditions_core.register_command("metaball", {
|
||||||
|
params = "add <radius> | remove <index> | render <replace_node> [<threshold=1>] | list | clear | volume",
|
||||||
|
description = "Defines and creates metaballs. After using the add subcommand to define 1 or more metaballs (uses pos1), the render subcommand can then be used to create the metaballs as nodes.",
|
||||||
|
privs = { worldedit = true },
|
||||||
|
require_pos = 1,
|
||||||
|
parse = function(params_text)
|
||||||
|
if not params_text then params_text = "" end
|
||||||
|
|
||||||
|
local parts = wea.split_shell(params_text)
|
||||||
|
|
||||||
|
if #parts < 1 then
|
||||||
|
return false, "Error: Not enough arguments (see /help /dome for usage information)."
|
||||||
|
end
|
||||||
|
|
||||||
|
local subcommand = parts[1]
|
||||||
|
local subargs = {}
|
||||||
|
|
||||||
|
if subcommand == "delete" then subcommand = "remove" end
|
||||||
|
if subcommand == "deleteall" then subcommand = "clear" end
|
||||||
|
if subcommand == "append" then subcommand = "add" end
|
||||||
|
if subcommand == "list" then subcommand = "list" end
|
||||||
|
if subcommand == "make" then subcommand = "render" end
|
||||||
|
if subcommand == "generate" then subcommand = "render" end
|
||||||
|
if subcommand == "create" then subcommand = "render" end
|
||||||
|
|
||||||
|
if subcommand == "add" then
|
||||||
|
if #parts < 2 then
|
||||||
|
return false, "Error: Not enough arguments."
|
||||||
|
end
|
||||||
|
local radius = tonumber(parts[2])
|
||||||
|
if not radius then
|
||||||
|
return false, "Error: Invalid radius '"..parts[2].."'. The radius must be a positive integer."
|
||||||
|
end
|
||||||
|
if radius < 1 then
|
||||||
|
return false, "Error: The minimum radius size is 1, but you entered "..tostring(radius).."."
|
||||||
|
end
|
||||||
|
table.insert(subargs, radius)
|
||||||
|
elseif subcommand == "remove" then
|
||||||
|
if #parts < 2 then
|
||||||
|
return false, "Error: Not enough arguments."
|
||||||
|
end
|
||||||
|
local index = tonumber(parts[2])
|
||||||
|
if not index then
|
||||||
|
return false, "Error: Invalid index '"..parts[2].."'. The index to remove must be a positive integer."
|
||||||
|
end
|
||||||
|
if index < 1 then
|
||||||
|
return false, "Error: The minimum index size is 1, but you entered "..tostring(index).."."
|
||||||
|
end
|
||||||
|
table.insert(subargs, index)
|
||||||
|
elseif subcommand == "render" then
|
||||||
|
if #parts < 2 then
|
||||||
|
return false, "Error: Not enough arguments."
|
||||||
|
end
|
||||||
|
local replace_node = worldedit.normalize_nodename(parts[2])
|
||||||
|
local threshold = 1
|
||||||
|
|
||||||
|
if not replace_node then
|
||||||
|
return false, "Error: Invalid replace_node '"..parts[2].."'."
|
||||||
|
end
|
||||||
|
|
||||||
|
if #parts >= 3 then
|
||||||
|
threshold = tonumber(parts[3])
|
||||||
|
if not threshold then
|
||||||
|
return false, "Error: The threshold value must be a valid number (a floating-point number is ok)."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
table.insert(subargs, replace_node)
|
||||||
|
table.insert(subargs, threshold)
|
||||||
|
elseif subcommand ~= "list" and subcommand ~= "clear" and subcommand ~= "volume" then
|
||||||
|
return false, "Error: Unknown subcommand '"..parts[1].."'."
|
||||||
|
end
|
||||||
|
|
||||||
|
return true, subcommand, subargs
|
||||||
|
end,
|
||||||
|
nodes_needed = function(name, subcommand)
|
||||||
|
if subcommand == "render" then
|
||||||
|
return wea.metaballs.volume(name)
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
func = function(name, subcommand, subargs)
|
||||||
|
local start_time = wea.get_ms_time()
|
||||||
|
local message = ""
|
||||||
|
local append_time = false
|
||||||
|
if subcommand == "list" then
|
||||||
|
local success, list = wea.metaballs.list_pretty(name)
|
||||||
|
if not success then return success, list end
|
||||||
|
|
||||||
|
message = list
|
||||||
|
elseif subcommand == "volume" then
|
||||||
|
local success, metaballs_list = wea.metaballs.list(name)
|
||||||
|
if not success then return success, metaballs_list end
|
||||||
|
local success2, volume = wea.metaballs.volume(name)
|
||||||
|
if not success2 then return success2, volume end
|
||||||
|
|
||||||
|
message = #metaballs_list.." will take up to "..tostring(volume).." nodes of space"
|
||||||
|
elseif subcommand == "clear" then
|
||||||
|
local success, metaballs_cleared = wea.metaballs.clear(name)
|
||||||
|
if not success then return success, metaballs_cleared end
|
||||||
|
|
||||||
|
message = tostring(metaballs_cleared).." cleared"
|
||||||
|
elseif subcommand == "remove" then
|
||||||
|
local index = subargs[1]
|
||||||
|
|
||||||
|
local success, metaballs_count = wea.metaballs.remove(name, index)
|
||||||
|
if not success then return success, metaballs_count end
|
||||||
|
|
||||||
|
message = "metaball at index "..tostring(index).." removed - "..metaballs_count.." metaballs remain"
|
||||||
|
elseif subcommand == "add" then
|
||||||
|
local pos = Vector3.clone(worldedit.pos1[name])
|
||||||
|
local radius = subargs[1]
|
||||||
|
|
||||||
|
local success, metaballs_count = wea.metaballs.add(name, pos, radius)
|
||||||
|
if not success then return success, metaballs_count end
|
||||||
|
|
||||||
|
message = "added metaball at "..pos.." with radius "..tostring(radius).." - "..metaballs_count.." metaballs are now defined"
|
||||||
|
append_time = false
|
||||||
|
elseif subcommand == "render" then
|
||||||
|
local replace_node = subargs[1]
|
||||||
|
local threshold = subargs[2]
|
||||||
|
|
||||||
|
local success, metaballs = wea.metaballs.list(name)
|
||||||
|
if not success then return success, metaballs end
|
||||||
|
|
||||||
|
if #metaballs < 2 then
|
||||||
|
return false, "Error: At least 2 metaballs must be defined to render them."
|
||||||
|
end
|
||||||
|
|
||||||
|
local success2, nodes_replaced = wea.metaballs.render(metaballs, replace_node, threshold)
|
||||||
|
if not success2 then return success2, nodes_replaced end
|
||||||
|
|
||||||
|
message = nodes_replaced.." nodes replaced using "..tostring(#metaballs).." metaballs"
|
||||||
|
append_time = true
|
||||||
|
end
|
||||||
|
|
||||||
|
local time_taken = wea.get_ms_time() - start_time
|
||||||
|
|
||||||
|
|
||||||
|
if append_time then
|
||||||
|
message = message.." in "..wea.format.human_time(time_taken)
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.log("action", name.." used //metaballs "..subcommand.." in "..wea.format.human_time(time_taken))
|
||||||
|
return true, message
|
||||||
|
end
|
||||||
|
})
|
|
@ -24,7 +24,7 @@ end
|
||||||
-- ██ ████ ██ ██ ██ ██ ██ █████
|
-- ██ ████ ██ ██ ██ ██ ██ █████
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██ ██ ██████ ████ ███████
|
-- ██ ██ ██████ ████ ███████
|
||||||
worldedit.register_command("move+", { -- TODO: Make this an override
|
worldeditadditions_core.register_command("move+", { -- TODO: Make this an override
|
||||||
params = "<axis:x|y|z|-x|-y|-z|?|front|back|left|right|up|down> <count> [<axis> <count> [...]]",
|
params = "<axis:x|y|z|-x|-y|-z|?|front|back|left|right|up|down> <count> [<axis> <count> [...]]",
|
||||||
description = "Moves the defined region to another location - potentially across multiple axes at once.",
|
description = "Moves the defined region to another location - potentially across multiple axes at once.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
|
|
||||||
worldedit.register_command("noise2d", {
|
worldeditadditions_core.register_command("noise2d", {
|
||||||
params = "[<key_1> [<value_1>]] [<key_2> [<value_2>]] ...]",
|
params = "[<key_1> [<value_1>]] [<key_2> [<value_2>]] ...]",
|
||||||
description = "Applies 2d random noise to the terrain as a 2d heightmap in the defined region. Optionally takes an arbitrary set of key - value pairs representing parameters that control the properties of the noise and how it's applied. See the full documentation for details of these parameters and what they do.",
|
description = "Applies 2d random noise to the terrain as a 2d heightmap in the defined region. Optionally takes an arbitrary set of key - value pairs representing parameters that control the properties of the noise and how it's applied. See the full documentation for details of these parameters and what they do.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
-- ██ ██ ██ ██ █████ ██████ ██ ███████ ████
|
-- ██ ██ ██ ██ █████ ██████ ██ ███████ ████
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██████ ████ ███████ ██ ██ ███████ ██ ██ ██
|
-- ██████ ████ ███████ ██ ██ ███████ ██ ██ ██
|
||||||
worldedit.register_command("overlay", {
|
worldeditadditions_core.register_command("overlay", {
|
||||||
params = "<replace_node_a> [<chance_a>] <replace_node_b> [<chance_b>] [<replace_node_N> [<chance_N>]] ...",
|
params = "<replace_node_a> [<chance_a>] <replace_node_b> [<chance_b>] [<replace_node_N> [<chance_N>]] ...",
|
||||||
description = "Places <replace_node_a> 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 <replace_node_a>. Optionally supports a mix of nodes and chances, as in //mix and //replacemix.",
|
description = "Places <replace_node_a> 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 <replace_node_a>. Optionally supports a mix of nodes and chances, as in //mix and //replacemix.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -5,7 +5,7 @@ local wea = worldeditadditions
|
||||||
-- ██████ █████ ██████ ██ ███████ ██ █████ ██ ████ ██ ██ ███
|
-- ██████ █████ ██████ ██ ███████ ██ █████ ██ ████ ██ ██ ███
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██ ██ ███████ ██ ███████ ██ ██ ██████ ███████ ██ ██ ██ ██ ██
|
-- ██ ██ ███████ ██ ███████ ██ ██ ██████ ███████ ██ ██ ██ ██ ██
|
||||||
worldedit.register_command("replacemix", {
|
worldeditadditions_core.register_command("replacemix", {
|
||||||
params = "<target_node> [<chance>] <replace_node_a> [<chance_a>] [<replace_node_b> [<chance_b>]] [<replace_node_N> [<chance_N>]] ...",
|
params = "<target_node> [<chance>] <replace_node_a> [<chance_a>] [<replace_node_b> [<chance_b>]] [<replace_node_N> [<chance_N>]] ...",
|
||||||
description = "Replaces target_node with a mix of other nodes. Functions simmilarly to //mix. <chance> is optional and the chance to replace the target node at all. replace_node_a is the node to replace target_node with. If multiple nodes are specified in a space separated list, then when replacing an instance of target_node one is randomly chosen from the list. Just like with //mix, if a positive integer is present after a replace_node, that adds a weighting to that particular node making it more common.",
|
description = "Replaces target_node with a mix of other nodes. Functions simmilarly to //mix. <chance> is optional and the chance to replace the target node at all. replace_node_a is the node to replace target_node with. If multiple nodes are specified in a space separated list, then when replacing an instance of target_node one is randomly chosen from the list. Just like with //mix, if a positive integer is present after a replace_node, that adds a weighting to that particular node making it more common.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -22,7 +22,7 @@ end
|
||||||
-- ███████ ██ ███████ ██ █████
|
-- ███████ ██ ███████ ██ █████
|
||||||
-- ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██
|
||||||
-- ███████ ██████ ██ ██ ███████ ███████
|
-- ███████ ██████ ██ ██ ███████ ███████
|
||||||
worldedit.register_command("scale", {
|
worldeditadditions_core.register_command("scale", {
|
||||||
params = "<axis> <scale_factor> | <factor_x> [<factor_y> <factor_z> [<anchor_x> <anchor_y> <anchor_z>]]",
|
params = "<axis> <scale_factor> | <factor_x> [<factor_y> <factor_z> [<anchor_x> <anchor_y> <anchor_z>]]",
|
||||||
description = "Combined scale up / down. Takes either an axis name + a scale factor (e.g. y 3 or -z 2; negative values swap the anchor point for the scale operation), or 3 scale factor values for x, y, and z respectively. In the latter mode, a set of anchors can also be specified, which indicate which size the scale operation should be anchored to.",
|
description = "Combined scale up / down. Takes either an axis name + a scale factor (e.g. y 3 or -z 2; negative values swap the anchor point for the scale operation), or 3 scale factor values for x, y, and z respectively. In the latter mode, a set of anchors can also be specified, which indicate which size the scale operation should be anchored to.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -7,7 +7,7 @@ local Vector3 = wea.Vector3
|
||||||
-- ███████ ██ ██ ██ ██ ██████ ██
|
-- ███████ ██ ██ ██ ██ ██████ ██
|
||||||
-- ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ███████ ██████ ██████ ███████ ██ ██
|
-- ███████ ██████ ██████ ███████ ██ ██
|
||||||
worldedit.register_command("sculpt", {
|
worldeditadditions_core.register_command("sculpt", {
|
||||||
params = "[<brush_name=default> [<height=5> [<brush_size=10>]]]",
|
params = "[<brush_name=default> [<height=5> [<brush_size=10>]]]",
|
||||||
description = "Applies a sculpting brush to the terrain with a given height. See //sculptlist to list all available brushes. Note that while the brush size is configurable, the actual brush size you end up with may be slightly different to that which you request due to brush size restrictions.",
|
description = "Applies a sculpting brush to the terrain with a given height. See //sculptlist to list all available brushes. Note that while the brush size is configurable, the actual brush size you end up with may be slightly different to that which you request due to brush size restrictions.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ███████ ██████ ███████ ██ ████ ██ ███████ ██ ██
|
-- ███████ ██████ ███████ ██ ████ ██ ███████ ██ ██
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
worldedit.register_command("scentre", {
|
worldeditadditions_core.register_command("scentre", {
|
||||||
params = "",
|
params = "",
|
||||||
description = "Set WorldEdit region positions 1 and 2 to the centre of the current selection.",
|
description = "Set WorldEdit region positions 1 and 2 to the centre of the current selection.",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
|
|
|
@ -14,7 +14,7 @@ minetest.register_on_punchnode(function(pos, node, puncher)
|
||||||
else wea.add_pos[name] = nil end
|
else wea.add_pos[name] = nil end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
worldedit.register_command("scloud", {
|
worldeditadditions_core.register_command("scloud", {
|
||||||
params = "<0-6|stop|reset>",
|
params = "<0-6|stop|reset>",
|
||||||
description = "Set and add to WorldEdit region by punching up to six nodes that define the maximums of your target",
|
description = "Set and add to WorldEdit region by punching up to six nodes that define the maximums of your target",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
-- ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██
|
||||||
-- ███████ ██████ ██████ ███████
|
-- ███████ ██████ ██████ ███████
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
worldedit.register_command("scol", {
|
worldeditadditions_core.register_command("scol", {
|
||||||
params = "[<axis1>] <length>",
|
params = "[<axis1>] <length>",
|
||||||
description = "Set WorldEdit region position 2 at a set distance along 1 axis.",
|
description = "Set WorldEdit region position 2 at a set distance along 1 axis.",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
-- ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ███████ ██████ ██████ ██████ ███████
|
-- ███████ ██████ ██████ ██████ ███████
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
worldedit.register_command("scube", {
|
worldeditadditions_core.register_command("scube", {
|
||||||
params = "[<axis1> [<axis2> [<axis3>]]] <length>",
|
params = "[<axis1> [<axis2> [<axis3>]]] <length>",
|
||||||
description = "Set WorldEdit region position 2 at a set distance along 3 axes.",
|
description = "Set WorldEdit region position 2 at a set distance along 3 axes.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ███████ ██ ██ ██ ██████ ██ ██████ ██ ██
|
-- ███████ ██ ██ ██ ██████ ██ ██████ ██ ██
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
worldedit.register_command("sfactor", {
|
worldeditadditions_core.register_command("sfactor", {
|
||||||
params = "<mode> <factor> [<target=xz>]",
|
params = "<mode> <factor> [<target=xz>]",
|
||||||
description = "Make the length of one or more target axes of the current selection to be multiple(s) of <factor>.",
|
description = "Make the length of one or more target axes of the current selection to be multiple(s) of <factor>.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ███████ ██ ██ ██ ██ ██ ██ ███████
|
-- ███████ ██ ██ ██ ██ ██ ██ ███████
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
worldedit.register_command("smake", {
|
worldeditadditions_core.register_command("smake", {
|
||||||
params = "<operation:odd|even|equal> <mode:grow|shrink|average> [<target=xyz> [<base>]]",
|
params = "<operation:odd|even|equal> <mode:grow|shrink|average> [<target=xyz> [<base>]]",
|
||||||
description = "Make one or more axes of the current selection odd, even, or equal to another.",
|
description = "Make one or more axes of the current selection odd, even, or equal to another.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
-- ███████ ██████ ██ ██ ██████
|
-- ███████ ██████ ██ ██ ██████
|
||||||
-- ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██
|
||||||
-- ███████ ██ ██████ ██
|
-- ███████ ██ ██████ ██
|
||||||
worldedit.register_command("spop", {
|
worldeditadditions_core.register_command("spop", {
|
||||||
params = "",
|
params = "",
|
||||||
description = "Pops a region off your (per-user) selection stack.",
|
description = "Pops a region off your (per-user) selection stack.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
-- ███████ ██████ ██ ██ ███████ ███████
|
-- ███████ ██████ ██ ██ ███████ ███████
|
||||||
-- ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ███████ ██ ██████ ███████ ██ ██
|
-- ███████ ██ ██████ ███████ ██ ██
|
||||||
worldedit.register_command("spush", {
|
worldeditadditions_core.register_command("spush", {
|
||||||
params = "",
|
params = "",
|
||||||
description = "Pushes the currently defined region onto your (per-user) selection stack.",
|
description = "Pushes the currently defined region onto your (per-user) selection stack.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
-- ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██
|
||||||
-- ███████ ██ ██ ███████ ██████ ██
|
-- ███████ ██ ██ ███████ ██████ ██
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
worldedit.register_command("srect", {
|
worldeditadditions_core.register_command("srect", {
|
||||||
params = "[<axis1> [<axis2>]] <length>",
|
params = "[<axis1> [<axis2>]] <length>",
|
||||||
description = "Set WorldEdit region position 2 at a set distance along 2 axes.",
|
description = "Set WorldEdit region position 2 at a set distance along 2 axes.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -21,7 +21,7 @@ local function parse_with_name(name,args)
|
||||||
until not args:find("([%l%s+-]+%d+)%s*", i)
|
until not args:find("([%l%s+-]+%d+)%s*", i)
|
||||||
return true, vec
|
return true, vec
|
||||||
end
|
end
|
||||||
worldedit.register_command("srel", {
|
worldeditadditions_core.register_command("srel", {
|
||||||
params = "<axis1> <length1> [<axis2> <length2> [<axis3> <length3>]]",
|
params = "<axis1> <length1> [<axis2> <length2> [<axis3> <length3>]]",
|
||||||
description = "Set WorldEdit region position 2 at set distances along 3 axes.",
|
description = "Set WorldEdit region position 2 at set distances along 3 axes.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -22,7 +22,7 @@ local function parse_with_name(name,args)
|
||||||
until not args:find("([%l%s+-]+%d+)%s*", i)
|
until not args:find("([%l%s+-]+%d+)%s*", i)
|
||||||
return true, vec
|
return true, vec
|
||||||
end
|
end
|
||||||
worldedit.register_command("sshift", {
|
worldeditadditions_core.register_command("sshift", {
|
||||||
params = "<axis1> <distance1> [<axis2> <distance2> [<axis3> <distance3>]]",
|
params = "<axis1> <distance1> [<axis2> <distance2> [<axis3> <distance3>]]",
|
||||||
description = "Shift the WorldEdit region in 3 dimensions.",
|
description = "Shift the WorldEdit region in 3 dimensions.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
-- ███████ ███████ ██ ███████ ██ █████
|
-- ███████ ███████ ██ ███████ ██ █████
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ███████ ███████ ██ ██ ██ ██████ ██ ██
|
-- ███████ ███████ ██ ██ ██ ██████ ██ ██
|
||||||
worldedit.register_command("sstack", {
|
worldeditadditions_core.register_command("sstack", {
|
||||||
params = "",
|
params = "",
|
||||||
description = "Displays the contents of your (per-user) selection stack.",
|
description = "Displays the contents of your (per-user) selection stack.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
local Vector3 = wea.Vector3
|
local Vector3 = wea.Vector3
|
||||||
|
|
||||||
worldedit.register_command("spiral2", {
|
worldeditadditions_core.register_command("spiral2", {
|
||||||
params = "[<circle|square>] [<replace_node=dirt> [<interval=3> [<acceleration=0>] ] ]",
|
params = "[<circle|square>] [<replace_node=dirt> [<interval=3> [<acceleration=0>] ] ]",
|
||||||
description = "Generates a spiral that fills the defined region using the specified replace node. The spiral is either square (default) or circular in shape. The interval specifies the distance between the walls of the spiral, and the acceleration specifies how quickly this value should increase.",
|
description = "Generates a spiral that fills the defined region using the specified replace node. The spiral is either square (default) or circular in shape. The interval specifies the distance between the walls of the spiral, and the acceleration specifies how quickly this value should increase.",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -52,7 +52,7 @@ local function parse_params_torus(params_text)
|
||||||
return true, replace_node, major_radius, minor_radius, axes, hollow
|
return true, replace_node, major_radius, minor_radius, axes, hollow
|
||||||
end
|
end
|
||||||
|
|
||||||
worldedit.register_command("torus", {
|
worldeditadditions_core.register_command("torus", {
|
||||||
params = "<major_radius> <minor_radius> <replace_node> [<axes=xy> [h[ollow]]]",
|
params = "<major_radius> <minor_radius> <replace_node> [<axes=xy> [h[ollow]]]",
|
||||||
description = "Creates a 3D torus with a major radius of <major_radius> and a minor radius of <minor_radius> at pos1, filled with <replace_node>, on axes <axes> (i.e. 2 axis names: xz, zy, etc).",
|
description = "Creates a 3D torus with a major radius of <major_radius> and a minor radius of <minor_radius> at pos1, filled with <replace_node>, on axes <axes> (i.e. 2 axis names: xz, zy, etc).",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
@ -81,7 +81,7 @@ worldedit.register_command("torus", {
|
||||||
})
|
})
|
||||||
|
|
||||||
-- TODO: This duplicates a lot of code. Perhaps we can trim it down a bit?
|
-- TODO: This duplicates a lot of code. Perhaps we can trim it down a bit?
|
||||||
worldedit.register_command("hollowtorus", {
|
worldeditadditions_core.register_command("hollowtorus", {
|
||||||
params = "<major_radius> <minor_radius> <replace_node> [<axes=xy>]",
|
params = "<major_radius> <minor_radius> <replace_node> [<axes=xy>]",
|
||||||
description = "Creates a 3D hollow torus with a major radius of <major_radius> and a minor radius of <minor_radius> at pos1, made out of <replace_node>, on axes <axes> (i.e. 2 axis names: xz, zy, etc).",
|
description = "Creates a 3D hollow torus with a major radius of <major_radius> and a minor radius of <minor_radius> at pos1, made out of <replace_node>, on axes <axes> (i.e. 2 axis names: xz, zy, etc).",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
-- ██ █ ██ ███████ ██ ██ ███████
|
-- ██ █ ██ ███████ ██ ██ ███████
|
||||||
-- ██ ███ ██ ██ ██ ██ ██ ██
|
-- ██ ███ ██ ██ ██ ██ ██ ██
|
||||||
-- ███ ███ ██ ██ ███████ ███████ ███████
|
-- ███ ███ ██ ██ ███████ ███████ ███████
|
||||||
worldedit.register_command("walls", {
|
worldeditadditions_core.register_command("walls", {
|
||||||
params = "[<replace_node=dirt> [<thickness=1>]]",
|
params = "[<replace_node=dirt> [<thickness=1>]]",
|
||||||
description = "Creates vertical walls of <replace_node> around the inside edges of the defined region. Optionally specifies a thickness for the walls to be created (defaults to 1)",
|
description = "Creates vertical walls of <replace_node> around the inside edges of the defined region. Optionally specifies a thickness for the walls to be created (defaults to 1)",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
-- ███ ███ ██████ ██████ ██ ██
|
-- ███ ███ ██████ ██████ ██ ██
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
local v3 = worldeditadditions.Vector3
|
local v3 = worldeditadditions.Vector3
|
||||||
worldedit.register_command("wbox", {
|
worldeditadditions_core.register_command("wbox", {
|
||||||
params = "<replace_node>",
|
params = "<replace_node>",
|
||||||
description = "Sets the edges of the current selection to <replace_node>",
|
description = "Sets the edges of the current selection to <replace_node>",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
-- ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ███ ███ ██████ ██████ ██ ██ ██ ██ ██ ███████ ███████
|
-- ███ ███ ██████ ██████ ██ ██ ██ ██ ██ ███████ ███████
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
worldedit.register_command("wcompass", {
|
worldeditadditions_core.register_command("wcompass", {
|
||||||
params = "<replace_node> [<bead_node>]",
|
params = "<replace_node> [<bead_node>]",
|
||||||
description = "Creates a compass around pos1 with a single node bead pointing north (+Z).",
|
description = "Creates a compass around pos1 with a single node bead pointing north (+Z).",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
-- ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ███ ███ ██████ ██████ ██ ██ ██ ████ ███████ ██ ██
|
-- ███ ███ ██████ ██████ ██ ██ ██ ████ ███████ ██ ██
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
worldedit.register_command("wcorner", {
|
worldeditadditions_core.register_command("wcorner", {
|
||||||
params = "<replace_node>",
|
params = "<replace_node>",
|
||||||
description = "Set the corners of the current selection to <replace_node>",
|
description = "Set the corners of the current selection to <replace_node>",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
-- The strategy here is not to have duplicate content, but to pull data from
|
-- The strategy here is not to have duplicate content, but to pull data from
|
||||||
-- existing sources.
|
-- existing sources.
|
||||||
-- Long-form article descriptions: Chat-Command-Reference.md
|
-- Long-form article descriptions: Chat-Command-Reference.md
|
||||||
-- Short descriptions: Undecided, but maybe worldedit.registered_commands
|
-- Short descriptions: Undecided, but maybe from the registered command definition?
|
||||||
|
|
||||||
worldeditadditions.doc = {}
|
worldeditadditions.doc = {}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ dofile(we_c.modpath.."/commands/spiral2.lua")
|
||||||
dofile(we_c.modpath.."/commands/copy.lua")
|
dofile(we_c.modpath.."/commands/copy.lua")
|
||||||
dofile(we_c.modpath.."/commands/move.lua")
|
dofile(we_c.modpath.."/commands/move.lua")
|
||||||
dofile(we_c.modpath.."/commands/dome.lua")
|
dofile(we_c.modpath.."/commands/dome.lua")
|
||||||
|
dofile(we_c.modpath.."/commands/metaball.lua")
|
||||||
dofile(we_c.modpath.."/commands/count.lua")
|
dofile(we_c.modpath.."/commands/count.lua")
|
||||||
dofile(we_c.modpath.."/commands/sculpt.lua")
|
dofile(we_c.modpath.."/commands/sculpt.lua")
|
||||||
|
|
||||||
|
@ -80,24 +80,4 @@ end
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
|
|
||||||
worldedit.alias_command("smoothadv", "convolve")
|
dofile(we_c.modpath.."/aliases.lua")
|
||||||
worldedit.alias_command("conv", "convolve")
|
|
||||||
|
|
||||||
worldedit.alias_command("naturalise", "layers")
|
|
||||||
worldedit.alias_command("naturalize", "layers")
|
|
||||||
|
|
||||||
worldedit.alias_command("flora", "bonemeal")
|
|
||||||
|
|
||||||
-- Measure Tools
|
|
||||||
worldedit.alias_command("mcount", "count")
|
|
||||||
worldedit.alias_command("mfacing", "mface")
|
|
||||||
|
|
||||||
|
|
||||||
--- Overrides to core WorldEdit commands
|
|
||||||
-- These are commented out for now, as they could be potentially dangerous to stability
|
|
||||||
-- Thorough testing is required of our replacement commands before these are uncommented
|
|
||||||
-- TODO: Depend on worldeditadditions_core before uncommenting this
|
|
||||||
-- BUG: //move+ seems to be leaving stuff behind for some strange reason --@sbrl 2021-12-26
|
|
||||||
-- worldeditadditions_core.alias_override("copy", "copy+")
|
|
||||||
-- worldeditadditions_core.alias_override("move", "move+") -- MAY have issues where it doesn't overwrite the old region properly, but haven't been able to reliably reproduce this
|
|
||||||
-- worldeditadditions_core.alias_override("replace", "replacemix")
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
name = worldeditadditions_commands
|
name = worldeditadditions_commands
|
||||||
description = worldeditadditions: chat command interfaces
|
description = worldeditadditions: chat command interfaces
|
||||||
depends = worldeditadditions, worldedit_commands, worldedit_shortcommands, worldedit
|
depends = worldeditadditions, worldeditadditions_core, worldedit_commands, worldedit_shortcommands, worldedit
|
||||||
optional_depends = worldeditdebug, bonemeal
|
optional_depends = worldeditdebug, bonemeal
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
# worldeditadditions_core
|
# worldeditadditions_core
|
||||||
|
|
||||||
This mod's purpose is to provide a solid base upon which the rest of WorldEditAdditions can function. Once it is complete, we will be able to mark our dependency on `worldedit` itself optional. To get to that point though will still require a significant effort in implementing enhanced versions of all existing WorldEdit commands. If you've got some free time and a great idea for a command, please do open a pull request! :D
|
This mod's purpose is to provide a solid base upon which the rest of WorldEditAdditions can function. Once it is complete, we will be able to mark our dependency on `worldedit` itself optional. To get to that point though will still require a significant effort in implementing enhanced versions of all existing WorldEdit commands. If you've got some free time and a great idea for a command, please do open a pull request! :D
|
||||||
|
|
||||||
|
In short, `worldeditadditions_core` is a reimplementation of a number of underlying parts of the worldedit engine. Parts of `worldeditadditions_core` are likely to look very similar to parts of WorldEdit - this is because inspiration was taken from Uberi/WorldEdit when implementing `worldeditadditions_core`.
|
||||||
|
|
20
worldeditadditions_core/core/fetch_command_def.lua
Normal file
20
worldeditadditions_core/core/fetch_command_def.lua
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
|
||||||
|
--- Fetches the definition of a WorldEditAdditions or WorldEdit command
|
||||||
|
-- Does not support fetching generic Minetest commands - check
|
||||||
|
-- minetest.chatcommands for this.
|
||||||
|
-- @param cmdname string The name of the command to fetch the definition for.
|
||||||
|
local function fetch_command_def(cmdname)
|
||||||
|
local wea_c = worldeditadditions_core
|
||||||
|
|
||||||
|
if wea_c.registered_commands[cmdname] then
|
||||||
|
return wea_c.registered_commands[cmdname]
|
||||||
|
end
|
||||||
|
if minetest.global_exists("worldedit") and worldedit.registered_commands and worldedit.registered_commands[cmdname] then
|
||||||
|
return worldedit.registered_commands[cmdname]
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return fetch_command_def
|
|
@ -0,0 +1,8 @@
|
||||||
|
local wea_c = worldeditadditions_core
|
||||||
|
|
||||||
|
--- WorldEdit shim just in case WorldEdit doesn't exist.
|
||||||
|
-- Eventually this will go away.
|
||||||
|
worldedit = {
|
||||||
|
-- Note that you want worldeditadditions_core.registered_commands, and not worldedit.registered_commands! This table is not guaranteed to contain all command definitions in the future, whereas worldedit command definitions are guaranteed to be imported into this worldeditadditions_core.registered_commands.
|
||||||
|
registered_commands = { }
|
||||||
|
}
|
15
worldeditadditions_core/core/integrations/worldedit.lua
Normal file
15
worldeditadditions_core/core/integrations/worldedit.lua
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
local wea_c = worldeditadditions_core
|
||||||
|
|
||||||
|
|
||||||
|
for name,definition in pairs(worldedit.registered_commands) do
|
||||||
|
-- This check should not be needed since worldeditadditions_commands
|
||||||
|
-- depends on this mod (so it will overwrite any worldedit definitions,
|
||||||
|
-- since worldedit is loaded first), but it's here just in case
|
||||||
|
if not wea_c.registered_commands[name] then
|
||||||
|
-- The Minetest chat command should already be imported here, so we
|
||||||
|
-- just need to import worldedit chat command definition here
|
||||||
|
wea_c.registered_commands[name] = definition
|
||||||
|
else
|
||||||
|
minetest.log("info", "Skipping registration of worldedit command "..name..", as it's already a registered worldeditadditions command")
|
||||||
|
end
|
||||||
|
end
|
17
worldeditadditions_core/core/lib/human_size.lua
Normal file
17
worldeditadditions_core/core/lib/human_size.lua
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
-- TODO: This is duplicated from worldeditadditions/utils. We should consider moving worldeditadditions/utils to worldeditadditions_core. Perhaps also we could move the definition of the worldeditadditions namespace to worldeditadditions_core too?
|
||||||
|
|
||||||
|
--- Formats (usually large) numbers as human-readable strings.
|
||||||
|
-- Ported from PHP: https://github.com/sbrl/Pepperminty-Wiki/blob/0a81c940c5803856db250b29f54658476bc81e21/core/05-functions.php#L67
|
||||||
|
-- @param n number The number to format.
|
||||||
|
-- @param decimals number The number of decimal places to show.
|
||||||
|
-- @return string A formatted string that represents the given input number.
|
||||||
|
local function human_size(n, decimals)
|
||||||
|
local sizes = { "", "K", "M", "G", "T", "P", "E", "Y", "Z" }
|
||||||
|
local factor = math.floor((#tostring(n) - 1) / 3)
|
||||||
|
local multiplier = 10^(decimals or 0)
|
||||||
|
local result = math.floor(0.5 + (n / math.pow(1000, factor)) * multiplier) / multiplier
|
||||||
|
return result .. sizes[factor+1]
|
||||||
|
end
|
||||||
|
|
||||||
|
return human_size
|
40
worldeditadditions_core/core/register_alias.lua
Normal file
40
worldeditadditions_core/core/register_alias.lua
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
|
||||||
|
local wea_c = worldeditadditions_core
|
||||||
|
|
||||||
|
local function register_alias(cmdname_target, cmdname_source, override)
|
||||||
|
if override == nil then override = false end
|
||||||
|
|
||||||
|
local def_source = wea_c.fetch_command_def(cmdname_source)
|
||||||
|
|
||||||
|
if not def_source then
|
||||||
|
minetest.log("error", "worldeditadditions_core: Failed to register alias for "..cmdname_source.." → "..cmdname_target..", as the source command doesn't exist.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if wea_c.fetch_command_def(cmdname_target) and not override then
|
||||||
|
minetest.log("error", "worldeditadditions_core: Failed to register alias for "..cmdname_source.." → "..cmdname_target..", as the target command exists and override wasn't set to true.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
print("DEBUG ALIAS source "..cmdname_source.." target "..cmdname_target)
|
||||||
|
|
||||||
|
if minetest.chatcommands["/"..cmdname_target] then
|
||||||
|
minetest.override_chatcommand(
|
||||||
|
"/"..cmdname_target,
|
||||||
|
minetest.chatcommands["/"..cmdname_source]
|
||||||
|
)
|
||||||
|
else
|
||||||
|
minetest.register_chatcommand(
|
||||||
|
"/"..cmdname_target,
|
||||||
|
minetest.chatcommands["/"..cmdname_source]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
wea_c.registered_commands[cmdname_target] = wea_c.registered_commands[cmdname_source]
|
||||||
|
|
||||||
|
if minetest.global_exists("worldedit") then
|
||||||
|
worldedit.registered_commands[cmdname_target] = worldedit.registered_commands[cmdname_source]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return register_alias
|
66
worldeditadditions_core/core/register_command.lua
Normal file
66
worldeditadditions_core/core/register_command.lua
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
-- ██████ ███████ ██████ ██ ███████ ████████ ███████ ██████
|
||||||
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
|
-- ██████ █████ ██ ███ ██ ███████ ██ █████ ██████
|
||||||
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
|
-- ██ ██ ███████ ██████ ██ ███████ ██ ███████ ██ ██
|
||||||
|
|
||||||
|
-- WorldEditAdditions chat command registration
|
||||||
|
local wea_c = worldeditadditions_core
|
||||||
|
local run_command = dofile(wea_c.modpath.."/core/run_command.lua")
|
||||||
|
|
||||||
|
local function log_error(cmdname, error_message)
|
||||||
|
minetest.log("error", "register_command("..cmdname..") error: "..error_message)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function register_command(cmdname, options)
|
||||||
|
|
||||||
|
---
|
||||||
|
-- 1: Validation
|
||||||
|
---
|
||||||
|
if type(options.params) ~= "string" then
|
||||||
|
log_error(cmdname, "The params option is not a string.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if type(options.description) ~= "string" then
|
||||||
|
log_error(cmdname, "The description option is not a string.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if type(options.parse) ~= "function" then
|
||||||
|
log_error(cmdname, "The parse option is not a function.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if type(options.func) ~= "function" then
|
||||||
|
log_error(cmdname, "The func option is not a function.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if wea_c.registered_commands[cmdname] and options.override ~= true then
|
||||||
|
log_error(cmdname, "A WorldEditAdditions command with that name is registered, but the option override is not set to true.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
-- 2: Normalisation
|
||||||
|
---
|
||||||
|
if not options.privs then options.privs = {} end
|
||||||
|
if not options.require_pos then options.require_pos = 0 end
|
||||||
|
if not options.nodes_needed then options.nodes_needed = function() return 0 end end
|
||||||
|
|
||||||
|
---
|
||||||
|
-- 3: Registration
|
||||||
|
---
|
||||||
|
minetest.register_chatcommand("/"..cmdname, {
|
||||||
|
params = options.params,
|
||||||
|
description = options.description,
|
||||||
|
privs = options.privs,
|
||||||
|
func = function(player_name, paramtext)
|
||||||
|
run_command(cmdname, options, player_name, paramtext)
|
||||||
|
end
|
||||||
|
})
|
||||||
|
wea_c.registered_commands[cmdname] = options
|
||||||
|
if minetest.global_exists("worldedit") then
|
||||||
|
worldedit.registered_commands[cmdname] = options
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return register_command
|
55
worldeditadditions_core/core/run_command.lua
Normal file
55
worldeditadditions_core/core/run_command.lua
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
-- WARNING: safe_region MUST NOT be imported more than once, as it defines chat commands. If you want to import it again elsewhere, check first that multiple dofile() calls don't execute a file more than once.
|
||||||
|
local wea_c = worldeditadditions_core
|
||||||
|
local safe_region = dofile(wea_c.modpath.."/core/safe_region.lua")
|
||||||
|
local human_size = dofile(wea_c.modpath.."/core/lib/human_size.lua")
|
||||||
|
|
||||||
|
-- TODO: Reimplement worldedit.player_notify(player_name, msg_text)
|
||||||
|
|
||||||
|
local function run_command_stage2(player_name, func, parse_result)
|
||||||
|
local success, result_message = func(player_name, unpack(parse_result))
|
||||||
|
if result_message then
|
||||||
|
-- TODO: If we were unsuccessfull, then colour the message red
|
||||||
|
worldedit.player_notify(player_name, result_message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function run_command(cmdname, options, player_name, paramtext)
|
||||||
|
if options.require_pos > 0 and not worldedit.pos1[player_name] then
|
||||||
|
worldedit.player_notify(player_name, "Error: pos1 must be selected to use this command.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if options.require_pos > 1 and not worldedit.pos2[player_name] then
|
||||||
|
worldedit.player_notify(player_name, "Error: Both pos1 and pos2 must be selected (together making a region) to use this command.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local parse_result = { options.parse(paramtext) }
|
||||||
|
local success = table.remove(parse_result, 1)
|
||||||
|
if not success then
|
||||||
|
worldedit.player_notify(player_name, parse_result[1] or "Invalid usage (no further error message was provided by the command. This is probably a bug.)")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if options.nodes_needed then
|
||||||
|
local potential_changes = options.nodes_needed(player_name, unpack(parse_result))
|
||||||
|
|
||||||
|
local limit = wea_c.safe_region_limit_default
|
||||||
|
if wea_c.safe_region_limits[player_name] then
|
||||||
|
limit = wea_c.safe_region_limits[player_name]
|
||||||
|
end
|
||||||
|
|
||||||
|
if potential_changes > limit then
|
||||||
|
worldedit.player_notify(player_name, "/"..cmdname.." "..paramtext.."' may affect up to "..human_size(potential_changes).." nodes. Type //y to continue, or //n to cancel (see the //saferegion command to control when this message appears).")
|
||||||
|
safe_region(player_name, cmdname, function()
|
||||||
|
run_command_stage2(player_name, options.func, parse_result)
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
run_command_stage2(player_name, options.func, parse_result)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
run_command_stage2(player_name, options.func, parse_result)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return run_command
|
65
worldeditadditions_core/core/safe_region.lua
Normal file
65
worldeditadditions_core/core/safe_region.lua
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
|
||||||
|
-- ███████ █████ ███████ ███████ ██████ ███████ ██████ ██ ██████ ███ ██
|
||||||
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██
|
||||||
|
-- ███████ ███████ █████ █████ ██████ █████ ██ ███ ██ ██ ██ ██ ██ ██
|
||||||
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
|
-- ███████ ██ ██ ██ ███████ ██ ██ ███████ ██████ ██ ██████ ██ ████
|
||||||
|
|
||||||
|
local worldedit_command_y, worldedit_command_n
|
||||||
|
|
||||||
|
if minetest.global_exists("worldedit") then
|
||||||
|
worldedit_command_y = minetest.chatcommands["/y"].func
|
||||||
|
worldedit_command_n = minetest.chatcommands["/n"].func
|
||||||
|
end
|
||||||
|
|
||||||
|
--- A table that holds at most 1 pending function call per player.
|
||||||
|
local pending_calls = {}
|
||||||
|
|
||||||
|
--- Captures the given function in the safe_region subsystem for later execution.
|
||||||
|
-- @param player_name string The name of the player.
|
||||||
|
-- @param cmdname string The name of the command being executed.
|
||||||
|
-- @param func function The function to execute later. Will be passed NO ARGUMENTS should it ever get executed in the future (this is not guaranteed).
|
||||||
|
-- @returns nil
|
||||||
|
local function safe_region(player_name, cmdname, func)
|
||||||
|
pending_calls[player_name] = {
|
||||||
|
cmdname = cmdname,
|
||||||
|
func = func
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.override_chatcommand("/y", {
|
||||||
|
params = "",
|
||||||
|
description = "Run a pending operation that was captured by the safe region system earlier.",
|
||||||
|
func = function(player_name)
|
||||||
|
if pending_calls[player_name] == nil then
|
||||||
|
if minetest.global_exists("worldedit") and worldedit_command_y ~= nil then
|
||||||
|
worldedit_command_y(player_name)
|
||||||
|
else
|
||||||
|
worldedit.player_notify(player_name, "There aren't any pending operations at the moment.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
pending_calls[player_name].func()
|
||||||
|
pending_calls[player_name] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.override_chatcommand("/n", {
|
||||||
|
params = "",
|
||||||
|
description = "Abort a pending operation that was captured by the safe region system.",
|
||||||
|
func = function(player_name)
|
||||||
|
if pending_calls[player_name] == nil then
|
||||||
|
if minetest.global_exists("worldedit") and worldedit_command_y ~= nil then
|
||||||
|
worldedit_command_n(player_name)
|
||||||
|
else
|
||||||
|
worldedit.player_notify(player_name, "There aren't any operations pending, so there's nothing to abort.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
worldedit.player_notify(player_name, "Aborting captured command /"..pending_calls[player_name].cmdname..".")
|
||||||
|
pending_calls[player_name] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
return safe_region
|
|
@ -5,14 +5,32 @@
|
||||||
-- @license Mozilla Public License, 2.0
|
-- @license Mozilla Public License, 2.0
|
||||||
-- @author Starbeamrainbowlabs and VorTechnix
|
-- @author Starbeamrainbowlabs and VorTechnix
|
||||||
|
|
||||||
worldeditadditions_core = {}
|
-- local temp = true
|
||||||
local we_c = worldeditadditions_core
|
-- if temp then return end
|
||||||
|
-- This mod isn't finished yet, so it will not be executed for now.
|
||||||
|
|
||||||
|
|
||||||
|
local modpath = minetest.get_modpath("worldeditadditions_core")
|
||||||
|
|
||||||
|
worldeditadditions_core = {
|
||||||
|
modpath = modpath,
|
||||||
|
registered_commands = {},
|
||||||
|
-- Storage for per-player node limits before safe_region kicks in.
|
||||||
|
-- TODO: Persist these to disk.
|
||||||
|
safe_region_limits = {},
|
||||||
|
-- The default limit for new players on the number of potential nodes changed before safe_region kicks in.
|
||||||
|
safe_region_limit_default = 100000,
|
||||||
|
}
|
||||||
|
|
||||||
|
local wea_c = worldeditadditions_core
|
||||||
|
wea_c.register_command = dofile(modpath.."/core/register_command.lua")
|
||||||
|
wea_c.fetch_command_def = dofile(modpath.."/core/fetch_command_def.lua")
|
||||||
|
wea_c.register_alias = dofile(modpath.."/core/register_alias.lua")
|
||||||
|
|
||||||
we_c.modpath = minetest.get_modpath("worldeditadditions_core")
|
|
||||||
|
|
||||||
-- Initialise WorldEdit stuff if the WorldEdit mod is not present
|
-- Initialise WorldEdit stuff if the WorldEdit mod is not present
|
||||||
if not minetest.get_modpath("worldedit") then
|
if minetest.global_exists("worldedit") then
|
||||||
dofile(we_c.modpath.."/worldedit/init.lua")
|
dofile(wea_c.modpath.."/core/integrations/worldedit.lua")
|
||||||
|
else
|
||||||
|
dofile(wea_c.modpath.."/core/integrations/noworldedit.lua")
|
||||||
end
|
end
|
||||||
|
|
||||||
dofile(we_c.modpath.."/register/init.lua")
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
name = worldeditadditions_core
|
name = worldeditadditions_core
|
||||||
description = worldeditadditions: core components
|
description = worldeditadditions: core components
|
||||||
optional_depends = worldedit
|
optional_depends = worldedit, worldedit_commands, worldedit_shortcommands
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
function worldeditadditions_core.check_command(name, def)
|
|
||||||
if not (name and #name > 0) then
|
|
||||||
return false, "Error: No command name."
|
|
||||||
end
|
|
||||||
if not def.privs then
|
|
||||||
return false, "Error: privs is nill. Expected table."
|
|
||||||
end
|
|
||||||
def.require_pos = def.require_pos or 0
|
|
||||||
if not (def.require_pos >= 0 and def.require_pos < 3) then
|
|
||||||
return false, "Error: require_pos must be greater than -1 and less than 3."
|
|
||||||
end
|
|
||||||
if not def.parse then
|
|
||||||
if def.params == "" then
|
|
||||||
def.parse = function(params_text) return true end
|
|
||||||
else
|
|
||||||
return false, "Error: parse function is invalid."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not (def.nodes_needed == nil or type(def.nodes_needed) == "function") then
|
|
||||||
return false, "Error: nodes_needed must be nil or function."
|
|
||||||
end
|
|
||||||
if not def.func then
|
|
||||||
return false, "Error: main function is invalid."
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
|
@ -1,40 +0,0 @@
|
||||||
function worldeditadditions_core.chatcommand_handler(cmd_name, name, param)
|
|
||||||
local def = assert(worldedit.registered_commands[cmd_name], "Error: Failed to locate worldedit command definition for command '"..name.."' (this is probably a bug).")
|
|
||||||
|
|
||||||
if def.require_pos == 2 then
|
|
||||||
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
|
|
||||||
if pos1 == nil or pos2 == nil then
|
|
||||||
worldedit.player_notify(name, "no region selected")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
elseif def.require_pos == 1 then
|
|
||||||
local pos1 = worldedit.pos1[name]
|
|
||||||
if pos1 == nil then
|
|
||||||
worldedit.player_notify(name, "no position 1 selected")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local parsed = {def.parse(param)}
|
|
||||||
local success = table.remove(parsed, 1)
|
|
||||||
if not success then
|
|
||||||
worldedit.player_notify(name, parsed[1] or "invalid usage")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if def.nodes_needed then
|
|
||||||
local count = def.nodes_needed(name, unpack(parsed))
|
|
||||||
safe_region(name, count, function()
|
|
||||||
local success, msg = def.func(name, unpack(parsed))
|
|
||||||
if msg then
|
|
||||||
minetest.chat_send_player(name, msg)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
else
|
|
||||||
-- no "safe region" check
|
|
||||||
local success, msg = def.func(name, unpack(parsed))
|
|
||||||
if msg then
|
|
||||||
minetest.chat_send_player(name, msg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,14 +0,0 @@
|
||||||
-- ██████ ███████ ██████ ██ ███████ ████████ ███████ ██████
|
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
|
||||||
-- ██████ █████ ██ ███ ██ ███████ ██ █████ ██████
|
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
|
||||||
-- ██ ██ ███████ ██████ ██ ███████ ██ ███████ ██ ██
|
|
||||||
|
|
||||||
-- WorldEditAdditions Register/Overwrite Functions
|
|
||||||
|
|
||||||
local we_cm = worldeditadditions_core.modpath .. "/register/"
|
|
||||||
|
|
||||||
dofile(we_cm.."check.lua")
|
|
||||||
dofile(we_cm.."handler.lua")
|
|
||||||
dofile(we_cm.."register.lua")
|
|
||||||
dofile(we_cm.."override.lua")
|
|
|
@ -1,35 +0,0 @@
|
||||||
local we_c = worldeditadditions_core
|
|
||||||
function we_c.override_command(name, def)
|
|
||||||
local def = table.copy(def)
|
|
||||||
local success, err = we_c.check_command(name, def)
|
|
||||||
|
|
||||||
if not success then
|
|
||||||
error(err)
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.override_chatcommand("/" .. name, {
|
|
||||||
privs = def.privs,
|
|
||||||
params = def.params,
|
|
||||||
description = def.description,
|
|
||||||
func = function(player_name, param)
|
|
||||||
return we_c.chatcommand_handler(name, player_name, param)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
worldedit.registered_commands[name] = def
|
|
||||||
end
|
|
||||||
|
|
||||||
function we_c.alias_override(alias, original)
|
|
||||||
if not worldedit.registered_commands[original] then
|
|
||||||
minetest.log("error", "worldedit_shortcommands: original " .. original .. " does not exist")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if minetest.chatcommands["/" .. alias] then
|
|
||||||
minetest.override_chatcommand("/" .. alias, minetest.chatcommands["/" .. original])
|
|
||||||
worldedit.registered_commands[alias] = worldedit.registered_commands[original]
|
|
||||||
else
|
|
||||||
minetest.register_chatcommand("/" .. alias, minetest.chatcommands["/" .. original])
|
|
||||||
worldedit.registered_commands[alias] = worldedit.registered_commands[original]
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,32 +0,0 @@
|
||||||
local we_c = worldeditadditions_core
|
|
||||||
function we_c.register_command(name, def)
|
|
||||||
local def = table.copy(def)
|
|
||||||
local success, err = we_c.check_command(name, def)
|
|
||||||
if not success then
|
|
||||||
return false, err
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_chatcommand("/" .. name, {
|
|
||||||
privs = def.privs,
|
|
||||||
params = def.params,
|
|
||||||
description = def.description,
|
|
||||||
func = function(player_name, param)
|
|
||||||
return we_c.chatcommand_handler(name, player_name, param)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
worldedit.registered_commands[name] = def
|
|
||||||
end
|
|
||||||
|
|
||||||
function we_c.alias_command(alias, original)
|
|
||||||
if not worldedit.registered_commands[original] then
|
|
||||||
minetest.log("error", "worldedit_shortcommands: original " .. original .. " does not exist")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if minetest.chatcommands["/" .. alias] then
|
|
||||||
minetest.log("error", "worldedit_shortcommands: alias " .. alias .. " already exists")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_chatcommand("/" .. alias, minetest.chatcommands["/" .. original])
|
|
||||||
worldedit.registered_commands[alias] = worldedit.registered_commands[original]
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
--- WorldEdit shim just in case WorldEdit doesn't exist
|
|
||||||
|
|
||||||
worldedit = {
|
|
||||||
registered_commands = { }
|
|
||||||
}
|
|
Loading…
Reference in a new issue