diff --git a/CHANGELOG.md b/CHANGELOG.md index caecfe9..72787a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Note to self: See the bottom of this file for the release template text. ## v1.13: Untitled update (unreleased) - Add `//sfactor` (_selection factor_) - Selection Tools by @VorTechnix are finished for now. + - Add `mface` (_measure facing_), `midpos` (_measure middle position_), `msize` (_measure size_), `mtrig` (_measure trigonometry_) - Measuring Tools implemented by @VorTechnix. ## v1.12: The selection tools update (26th June 2021) - Add `//spush`, `//spop`, and `//sstack` diff --git a/Chat-Command-Reference.md b/Chat-Command-Reference.md index a60c543..a2410eb 100644 --- a/Chat-Command-Reference.md +++ b/Chat-Command-Reference.md @@ -780,6 +780,42 @@ Pops a selection off your per-user selection stack and applies it to the current //spop ``` +## `//mcount` +Alias for [`//count`](#count). + +``` +//mcount +``` + +## `//mface` +Returns the horizontal (X/Z) axis or axes the player is looking along. +Aliases: `//mfacing`. + +``` +//mface +``` + +## `//midpos` +Returns the coordinates of the centre of the current selection. + +``` +//midpos +``` + +## `//msize` +Returns the lengths of the current selection on the X, Y and Z axes. + +``` +//msize +``` + +## `//mtrig` +Returns the length of the diagonal from pos1 to pos2 and its angle on the XZ (horizontal) and Y (vertical) axes. + +``` +//mtrig +``` + ## `//y` Confirms the execution of a command if it could potentially affect a large number of nodes and take a while. This is a regular WorldEdit command. diff --git a/README.md b/README.md index 0db3fd5..58a7adc 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,13 @@ The detailed explanations have moved! Check them out [here](https://github.com/s - [`//sstack`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#sstack) - [`//spush`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#spush) - [`//spop`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#spop) - + +### Measure + - [`//mface`](Chat-Command-Reference.md#mface) + - [`//midpos`](Chat-Command-Reference.md#midpos) + - [`//msize`](Chat-Command-Reference.md#msize) + - [`//mtrig`](Chat-Command-Reference.md#mtrig) + ### Meta - [`//multi ....`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#multi-command_a-command_b-command_c-) - [`//many `](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#many-times-command) _(new in v1.9)_ diff --git a/worldeditadditions/utils/tables/table_tostring.lua b/worldeditadditions/utils/tables/table_tostring.lua index e6e8250..4a13586 100644 --- a/worldeditadditions/utils/tables/table_tostring.lua +++ b/worldeditadditions/utils/tables/table_tostring.lua @@ -4,17 +4,14 @@ -- @param new_line string key value pair delimiter -- @return string concatenated table pairs local function table_tostring(tbl, sep, new_line) - if type(sep) ~= "string" then sep = ": " end - if type(new_line) ~= "string" then new_line = ", " end - local ret = {} - if type(tbl) ~= "table" then return "Error: input not table!" end - for key,value in pairs(tbl) do - ret:append(key) - ret:append(sep) - ret:append(value) - ret:append(new_line) - end - return ret:concat("") + if type(sep) ~= "string" then sep = ": " end + if type(new_line) ~= "string" then new_line = ", " end + local ret = {} + if type(tbl) ~= "table" then return "Error: input not table!" end + for key,value in pairs(tbl) do + table.insert(ret,tostring(key) .. sep .. tostring(value) .. new_line) + end + return table.concat(ret,"") end return table_tostring diff --git a/worldeditadditions_commands/commands/measure/init.lua b/worldeditadditions_commands/commands/measure/init.lua new file mode 100644 index 0000000..126e1ec --- /dev/null +++ b/worldeditadditions_commands/commands/measure/init.lua @@ -0,0 +1,14 @@ +-- ███ ███ ███████ █████ ███████ ██ ██ ██████ ███████ +-- ████ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ██ ████ ██ █████ ███████ ███████ ██ ██ ██████ █████ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ██ ██ ███████ ██ ██ ███████ ██████ ██ ██ ███████ + +-- Chat commands that measure things. + +local we_cm = worldeditadditions_commands.modpath .. "/commands/measure/" + +dofile(we_cm.."mface.lua") +dofile(we_cm.."midpos.lua") +dofile(we_cm.."msize.lua") +dofile(we_cm.."mtrig.lua") diff --git a/worldeditadditions_commands/commands/measure/mface.lua b/worldeditadditions_commands/commands/measure/mface.lua new file mode 100644 index 0000000..53249e6 --- /dev/null +++ b/worldeditadditions_commands/commands/measure/mface.lua @@ -0,0 +1,37 @@ +-- ███ ███ ███████ █████ ██████ ███████ +-- ████ ████ ██ ██ ██ ██ ██ +-- ██ ████ ██ █████ ███████ ██ █████ +-- ██ ██ ██ ██ ██ ██ ██ ██ +-- ██ ██ ██ ██ ██ ██████ ███████ +local wea = worldeditadditions +worldedit.register_command("mface", { + params = "", + description = "Return player facing axis.", + privs = { worldedit = true }, + require_pos = 0, + parse = function(params_text) + return true + end, + func = function(name, params_text) + local str = "You are facing " + local dir = minetest.get_player_by_name(name):get_look_dir() + + if math.abs(dir.z) > math.abs(dir.x) then + if dir.z < 0 then str = str.."-Z" + else str = str.."Z" end + if math.abs(dir.x) >= 0.35 then -- Alternate value: 1/3 + if dir.x < 0 then str = str.."-X" + else str = str.."X" end + end + else + if dir.x < 0 then str = str.."-X" + else str = str.."X" end + if math.abs(dir.z) >= 0.35 then -- Alternate value: 1/3 + if dir.z < 0 then str = str.."-Z" + else str = str.."Z" end + end + end + + return true, str + end, +}) diff --git a/worldeditadditions_commands/commands/measure/midpos.lua b/worldeditadditions_commands/commands/measure/midpos.lua new file mode 100644 index 0000000..a2fee5f --- /dev/null +++ b/worldeditadditions_commands/commands/measure/midpos.lua @@ -0,0 +1,21 @@ +-- ███ ███ ██ ██████ ██████ ██████ ███████ +-- ████ ████ ██ ██ ██ ██ ██ ██ ██ ██ +-- ██ ████ ██ ██ ██ ██ ██████ ██ ██ ███████ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ██ ██ ██ ██████ ██ ██████ ███████ +local wea = worldeditadditions +worldedit.register_command("midpos", { + params = "", + description = "Return the mid point of current selection.", + privs = { worldedit = true }, + require_pos = 2, + parse = function(params_text) + return true + end, + func = function(name, params_text) + local str = "The centre of the current selection is at " + local vec = wea.vector.mean(worldedit.pos1[name],worldedit.pos2[name]) + + return true, str .. wea.table.tostring(vec) + end, +}) diff --git a/worldeditadditions_commands/commands/measure/msize.lua b/worldeditadditions_commands/commands/measure/msize.lua new file mode 100644 index 0000000..648f02f --- /dev/null +++ b/worldeditadditions_commands/commands/measure/msize.lua @@ -0,0 +1,22 @@ +-- ███ ███ ███████ ██ ███████ ███████ +-- ████ ████ ██ ██ ███ ██ +-- ██ ████ ██ ███████ ██ ███ █████ +-- ██ ██ ██ ██ ██ ███ ██ +-- ██ ██ ███████ ██ ███████ ███████ +local wea = worldeditadditions +worldedit.register_command("msize", { + params = "", + description = "Return the length of each axis of current selection.", + privs = { worldedit = true }, + require_pos = 2, + parse = function(params_text) + return true + end, + func = function(name, params_text) + local str = "The dimensions of the current selection are " + local vec = vector.subtract(worldedit.pos2[name],worldedit.pos1[name]) + wea.vector.abs(vec) + + return true, str .. "x: " .. vec.x .. ", y: " .. vec.y .. ", z: " .. vec.z + end, +}) diff --git a/worldeditadditions_commands/commands/measure/mtrig.lua b/worldeditadditions_commands/commands/measure/mtrig.lua new file mode 100644 index 0000000..90a28c4 --- /dev/null +++ b/worldeditadditions_commands/commands/measure/mtrig.lua @@ -0,0 +1,25 @@ +-- ███ ███ ████████ ██████ ██ ██████ +-- ████ ████ ██ ██ ██ ██ ██ +-- ██ ████ ██ ██ ██████ ██ ██ ███ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ██ ██ ██ ██ ██ ██ ██████ +local wea = worldeditadditions +local v3 = worldeditadditions.Vector3 +worldedit.register_command("mtrig", { + params = "", + description = "Return the length of and angles of an imginary line between pos1 and pos2 in the selection.", + privs = { worldedit = true }, + require_pos = 2, + parse = function(params_text) + return true + end, + func = function(name, params_text) + local str = "The measurements of the line from pos1 to pos2 are Length (D): " + local vec = v3.subtract(worldedit.pos2[name],worldedit.pos1[name]):abs() + local len = vec:length() + str = str..wea.round(len, 4)..", ∠XZ: ".. + wea.round(math.deg(math.atan(vec.z/vec.x)), 4).."°, ∠DY: ".. + wea.round(math.deg(math.asin(vec.y/len)), 4).."°" + return true, str + end, +}) diff --git a/worldeditadditions_commands/commands/selectors/init.lua b/worldeditadditions_commands/commands/selectors/init.lua index 84a05cb..8e9ac32 100644 --- a/worldeditadditions_commands/commands/selectors/init.lua +++ b/worldeditadditions_commands/commands/selectors/init.lua @@ -6,17 +6,16 @@ -- Chat commands that operate on selections. -local we_c = worldeditadditions_commands -we_c.modpath = minetest.get_modpath("worldeditadditions_commands") +local we_cm = worldeditadditions_commands.modpath .. "/commands/selectors/" -dofile(we_c.modpath.."/commands/selectors/srel.lua") -dofile(we_c.modpath.."/commands/selectors/scentre.lua") -dofile(we_c.modpath.."/commands/selectors/scloud.lua") -dofile(we_c.modpath.."/commands/selectors/scol.lua") -dofile(we_c.modpath.."/commands/selectors/scube.lua") -dofile(we_c.modpath.."/commands/selectors/sfactor.lua") -dofile(we_c.modpath.."/commands/selectors/smake.lua") -dofile(we_c.modpath.."/commands/selectors/spop.lua") -dofile(we_c.modpath.."/commands/selectors/spush.lua") -dofile(we_c.modpath.."/commands/selectors/srect.lua") -dofile(we_c.modpath.."/commands/selectors/sstack.lua") +dofile(we_cm.."srel.lua") +dofile(we_cm.."scentre.lua") +dofile(we_cm.."scloud.lua") +dofile(we_cm.."scol.lua") +dofile(we_cm.."scube.lua") +dofile(we_cm.."sfactor.lua") +dofile(we_cm.."smake.lua") +dofile(we_cm.."spop.lua") +dofile(we_cm.."spush.lua") +dofile(we_cm.."srect.lua") +dofile(we_cm.."sstack.lua") diff --git a/worldeditadditions_commands/depends.txt b/worldeditadditions_commands/depends.txt index db6f73b..3f0059a 100644 --- a/worldeditadditions_commands/depends.txt +++ b/worldeditadditions_commands/depends.txt @@ -2,5 +2,5 @@ worldeditadditions worldedit_commands worldedit_shortcommands worldedit -worldeditadditions_debug? +worldeditdebug? bonemeal? diff --git a/worldeditadditions_commands/init.lua b/worldeditadditions_commands/init.lua index 9b7796e..441da46 100644 --- a/worldeditadditions_commands/init.lua +++ b/worldeditadditions_commands/init.lua @@ -46,6 +46,9 @@ dofile(we_c.modpath.."/commands/meta/airapply.lua") -- Selection Tools dofile(we_c.modpath.."/commands/selectors/init.lua") +-- Measure Tools +dofile(we_c.modpath.."/commands/measure/init.lua") + dofile(we_c.modpath.."/commands/extra/saplingaliases.lua") dofile(we_c.modpath.."/commands/extra/basename.lua") @@ -78,6 +81,9 @@ worldedit.alias_command("naturalize", "layers") worldedit.alias_command("flora", "bonemeal") -worldedit.alias_command("mcount", "count") - +-- Selection Tools worldedit.alias_command("sfac", "sfactor") + +-- Measure Tools +worldedit.alias_command("mcount", "count") +worldedit.alias_command("mfacing", "mface") diff --git a/worldeditadditions_core/depends.txt b/worldeditadditions_core/depends.txt new file mode 100644 index 0000000..c4f6871 --- /dev/null +++ b/worldeditadditions_core/depends.txt @@ -0,0 +1 @@ +worldedit? diff --git a/worldeditadditions_core/init.lua b/worldeditadditions_core/init.lua new file mode 100644 index 0000000..e4e22ad --- /dev/null +++ b/worldeditadditions_core/init.lua @@ -0,0 +1,18 @@ +--- WorldEditAdditions-Core +-- @module worldeditadditions_core +-- @release 1.13 +-- @copyright 2021 Starbeamrainbowlabs and VorTechnix +-- @license Mozilla Public License, 2.0 +-- @author Starbeamrainbowlabs and VorTechnix + +worldeditadditions_core = {} +local we_c = worldeditadditions_core + +we_c.modpath = minetest.get_modpath("worldeditadditions_core") + +-- Initialise WorldEdit stuff if the WorldEdit mod is not present +if not minetest.get_modpath("worldedit") then + dofile(we_c.modpath.."/worldedit/init.lua") +end + +dofile(we_c.modpath.."/register/init.lua") diff --git a/worldeditadditions_core/register/check.lua b/worldeditadditions_core/register/check.lua new file mode 100644 index 0000000..1dfb87b --- /dev/null +++ b/worldeditadditions_core/register/check.lua @@ -0,0 +1,14 @@ +function worldeditadditions_core.register_command(def) + local def = table.copy(def) + assert(name and #name > 0) + assert(def.privs) + def.require_pos = def.require_pos or 0 + assert(def.require_pos >= 0 and def.require_pos < 3) + if def.params == "" and not def.parse then + def.parse = function(params_text) return true end + else + assert(def.parse) + end + assert(def.nodes_needed == nil or type(def.nodes_needed) == "function") + assert(def.func) +end diff --git a/worldeditadditions_core/register/handler.lua b/worldeditadditions_core/register/handler.lua new file mode 100644 index 0000000..b80c4a6 --- /dev/null +++ b/worldeditadditions_core/register/handler.lua @@ -0,0 +1,40 @@ +function worldeditadditions_core.chatcommand_handler(cmd_name, name, param) + local def = assert(worldedit.registered_commands[cmd_name]) + + 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 diff --git a/worldeditadditions_core/register/init.lua b/worldeditadditions_core/register/init.lua new file mode 100644 index 0000000..2ebb6c5 --- /dev/null +++ b/worldeditadditions_core/register/init.lua @@ -0,0 +1,14 @@ +-- ██████ ███████ ██████ ██ ███████ ████████ ███████ ██████ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ██████ █████ ██ ███ ██ ███████ ██ █████ ██████ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ██ ██ ███████ ██████ ██ ███████ ██ ███████ ██ ██ + +-- 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") diff --git a/worldeditadditions_core/register/override.lua b/worldeditadditions_core/register/override.lua new file mode 100644 index 0000000..bf7bb4e --- /dev/null +++ b/worldeditadditions_core/register/override.lua @@ -0,0 +1,18 @@ +local we_c = worldeditadditions_core +function we_c.override_command(name, def) + local success, def = we_c.check(def) + + if not success then + return false, def + 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 diff --git a/worldeditadditions_core/register/register.lua b/worldeditadditions_core/register/register.lua new file mode 100644 index 0000000..2a93120 --- /dev/null +++ b/worldeditadditions_core/register/register.lua @@ -0,0 +1,18 @@ +local we_c = worldeditadditions_core +function we_c.register_command(name, def) + local success, def = we_c.check(def) + + if not success then + return false, def + 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 diff --git a/worldeditadditions_core/worldedit/init.lua b/worldeditadditions_core/worldedit/init.lua new file mode 100644 index 0000000..fc4fd8b --- /dev/null +++ b/worldeditadditions_core/worldedit/init.lua @@ -0,0 +1,5 @@ +--- WorldEdit dependencies for WorldEditAdditions + +worldedit = { + registered_commands = {} +}