From 8877e356f029196e38beefd871256cc7c0b110e0 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Sat, 20 Mar 2021 01:48:56 +0000 Subject: [PATCH] refactor: refactor utils/strings.lua into multiple files --- worldeditadditions/init.lua | 6 +- worldeditadditions/lib/conv/conv.lua | 4 +- worldeditadditions/lib/count.lua | 2 +- worldeditadditions/lib/erode/erode.lua | 4 +- worldeditadditions/lib/erode/snowballs.lua | 2 +- worldeditadditions/utils/format/array_2d.lua | 20 ++ .../utils/format/ascii_table.lua | 32 ++ .../utils/format/human_size.lua | 13 + .../utils/format/human_time.lua | 28 ++ worldeditadditions/utils/format/init.lua | 8 + worldeditadditions/utils/format/map.lua | 10 + .../utils/format/node_distribution.lua | 23 ++ .../utils/node_identification.lua | 2 +- worldeditadditions/utils/parse/init.lua | 5 + worldeditadditions/utils/parse/map.lua | 23 ++ worldeditadditions/utils/parse/seed.lua | 17 + .../utils/parse/weighted_nodes.lua | 63 ++++ worldeditadditions/utils/strings.lua | 308 ------------------ worldeditadditions/utils/strings/init.lua | 2 + worldeditadditions/utils/strings/polyfill.lua | 35 ++ worldeditadditions/utils/strings/split.lua | 60 ++++ .../commands/bonemeal.lua | 2 +- .../commands/convolve.lua | 2 +- .../commands/count.lua | 4 +- .../commands/ellipsoid.lua | 4 +- .../commands/erode.lua | 4 +- .../commands/extra/saplingaliases.lua | 2 +- .../commands/fillcaves.lua | 2 +- .../commands/floodfill.lua | 2 +- .../commands/forest.lua | 10 +- .../commands/hollow.lua | 2 +- .../commands/layers.lua | 4 +- worldeditadditions_commands/commands/line.lua | 2 +- worldeditadditions_commands/commands/maze.lua | 6 +- .../commands/meta/ellipsoidapply.lua | 4 +- .../commands/meta/many.lua | 12 +- .../commands/meta/multi.lua | 4 +- .../commands/meta/subdivide.lua | 10 +- .../commands/overlay.lua | 4 +- .../commands/replacemix.lua | 9 +- .../commands/scale.lua | 2 +- .../commands/torus.lua | 4 +- .../commands/walls.lua | 2 +- 43 files changed, 401 insertions(+), 363 deletions(-) create mode 100644 worldeditadditions/utils/format/array_2d.lua create mode 100644 worldeditadditions/utils/format/ascii_table.lua create mode 100644 worldeditadditions/utils/format/human_size.lua create mode 100644 worldeditadditions/utils/format/human_time.lua create mode 100644 worldeditadditions/utils/format/init.lua create mode 100644 worldeditadditions/utils/format/map.lua create mode 100644 worldeditadditions/utils/format/node_distribution.lua create mode 100644 worldeditadditions/utils/parse/init.lua create mode 100644 worldeditadditions/utils/parse/map.lua create mode 100644 worldeditadditions/utils/parse/seed.lua create mode 100644 worldeditadditions/utils/parse/weighted_nodes.lua delete mode 100644 worldeditadditions/utils/strings.lua create mode 100644 worldeditadditions/utils/strings/init.lua create mode 100644 worldeditadditions/utils/strings/polyfill.lua create mode 100644 worldeditadditions/utils/strings/split.lua diff --git a/worldeditadditions/init.lua b/worldeditadditions/init.lua index 9799692..fa4a8ac 100644 --- a/worldeditadditions/init.lua +++ b/worldeditadditions/init.lua @@ -8,7 +8,11 @@ worldeditadditions = {} worldeditadditions.modpath = minetest.get_modpath("worldeditadditions") dofile(worldeditadditions.modpath.."/utils/vector.lua") -dofile(worldeditadditions.modpath.."/utils/strings.lua") + +dofile(worldeditadditions.modpath.."/utils/strings/init.lua") +dofile(worldeditadditions.modpath.."/utils/format/init.lua") +dofile(worldeditadditions.modpath.."/utils/parse/init.lua") + dofile(worldeditadditions.modpath.."/utils/numbers.lua") dofile(worldeditadditions.modpath.."/utils/nodes.lua") dofile(worldeditadditions.modpath.."/utils/node_identification.lua") diff --git a/worldeditadditions/lib/conv/conv.lua b/worldeditadditions/lib/conv/conv.lua index 9489058..52818f8 100644 --- a/worldeditadditions/lib/conv/conv.lua +++ b/worldeditadditions/lib/conv/conv.lua @@ -68,9 +68,9 @@ function worldeditadditions.convolve(pos1, pos2, kernel, kernel_size) ) -- print("original") - -- worldeditadditions.print_2d(heightmap, (pos2.z - pos1.z) + 1) + -- worldeditadditions.format.array_2d(heightmap, (pos2.z - pos1.z) + 1) -- print("transformed") - -- worldeditadditions.print_2d(heightmap_conv, (pos2.z - pos1.z) + 1) + -- worldeditadditions.format.array_2d(heightmap_conv, (pos2.z - pos1.z) + 1) worldeditadditions.apply_heightmap_changes( pos1, pos2, area, data, diff --git a/worldeditadditions/lib/count.lua b/worldeditadditions/lib/count.lua index a3c6974..3e11ec6 100644 --- a/worldeditadditions/lib/count.lua +++ b/worldeditadditions/lib/count.lua @@ -37,7 +37,7 @@ function worldeditadditions.count(pos1, pos2, do_human_counts) if do_human_counts then for key,item in pairs(results) do - item[1] = worldeditadditions.human_size(item[1], 2) + item[1] = worldeditadditions.format.human_size(item[1], 2) end end diff --git a/worldeditadditions/lib/erode/erode.lua b/worldeditadditions/lib/erode/erode.lua index 4fb5127..cd7466d 100644 --- a/worldeditadditions/lib/erode/erode.lua +++ b/worldeditadditions/lib/erode/erode.lua @@ -20,8 +20,8 @@ function worldeditadditions.erode.run(pos1, pos2, algorithm, params) local heightmap_eroded = worldeditadditions.shallowcopy(heightmap) -- print("[erode.run] algorithm: "..algorithm..", params:"); - -- print(worldeditadditions.map_stringify(params)) - -- worldeditadditions.print_2d(heightmap, heightmap_size.x) + -- print(worldeditadditions.format.map(params)) + -- worldeditadditions.format.array_2d(heightmap, heightmap_size.x) local success, msg, stats if algorithm == "snowballs" then success, msg = worldeditadditions.erode.snowballs(heightmap, heightmap_eroded, heightmap_size, region_height, params) diff --git a/worldeditadditions/lib/erode/snowballs.lua b/worldeditadditions/lib/erode/snowballs.lua index ced0766..34fce59 100644 --- a/worldeditadditions/lib/erode/snowballs.lua +++ b/worldeditadditions/lib/erode/snowballs.lua @@ -90,7 +90,7 @@ function worldeditadditions.erode.snowballs(heightmap_initial, heightmap, height worldeditadditions.table_apply(params_custom, params) -- print("[erode/snowballs] params: ") - -- print(worldeditadditions.map_stringify(params)) + -- print(worldeditadditions.format.map(params)) local normals = worldeditadditions.calculate_normals(heightmap, heightmap_size) diff --git a/worldeditadditions/utils/format/array_2d.lua b/worldeditadditions/utils/format/array_2d.lua new file mode 100644 index 0000000..8af7a8a --- /dev/null +++ b/worldeditadditions/utils/format/array_2d.lua @@ -0,0 +1,20 @@ +--- Prints a 2d array of numbers formatted like a JS TypedArray (e.g. like a manip node list or a convolutional kernel) +-- In other words, the numbers should be formatted as a single flat array. +-- @param tbl number[] The ZERO-indexed list of numbers +-- @param width number The width of 2D array. +function worldeditadditions.format.array_2d(tbl, width) + print("==== count: "..#tbl..", width:"..width.." ====") + local display_width = 1 + for _i,value in pairs(tbl) do + display_width = math.max(display_width, #tostring(value)) + end + display_width = display_width + 2 + local next = {} + for i=0, #tbl do + table.insert(next, worldeditadditions.str_padstart(tostring(tbl[i]), display_width)) + if #next == width then + print(table.concat(next, "")) + next = {} + end + end +end diff --git a/worldeditadditions/utils/format/ascii_table.lua b/worldeditadditions/utils/format/ascii_table.lua new file mode 100644 index 0000000..dcf62db --- /dev/null +++ b/worldeditadditions/utils/format/ascii_table.lua @@ -0,0 +1,32 @@ + +--- Makes a human-readable table of data. +-- Data should be a 2D array - i.e. a table of tables. The nested tables should +-- contain a list of items for a single row. +-- If total is specified, then a grand total is printed at the bottom - this is +-- useful when you want to print a node list. +-- @param data table[] A table of tables. Each subtable is a single row of the tabulated output. +-- @returns string The input table of tables formatted into a nice ASCII table. +function worldeditadditions.format.make_ascii_table(data) + local extra_padding = 2 + local result = {} + local max_lengths = {} + for y = 1, #data, 1 do + for x = 1, #data[y], 1 do + if not max_lengths[x] then + max_lengths[x] = 0 + end + max_lengths[x] = math.max(max_lengths[x], #tostring(data[y][x]) + extra_padding) + end + end + + for _key, row in ipairs(data) do + local row_result = {} + for i = 1, #row, 1 do + row_result[#row_result + 1] = worldeditadditions.str_padend(tostring(row[i]), max_lengths[i], " ") + end + result[#result+1] = table.concat(row_result, "") + end + + -- TODO: Add multi-column support here + return table.concat(result, "\n") +end diff --git a/worldeditadditions/utils/format/human_size.lua b/worldeditadditions/utils/format/human_size.lua new file mode 100644 index 0000000..2403ff0 --- /dev/null +++ b/worldeditadditions/utils/format/human_size.lua @@ -0,0 +1,13 @@ + +--- 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. +function worldeditadditions.format.human_size(n, decimals) + 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 diff --git a/worldeditadditions/utils/format/human_time.lua b/worldeditadditions/utils/format/human_time.lua new file mode 100644 index 0000000..0f9a87f --- /dev/null +++ b/worldeditadditions/utils/format/human_time.lua @@ -0,0 +1,28 @@ + +--- Converts a float milliseconds into a human-readable string. +-- Ported from PHP human_time from Pepperminty Wiki: https://github.com/sbrl/Pepperminty-Wiki/blob/fa81f0d/core/05-functions.php#L82-L104 +-- @param ms float The number of milliseconds to convert. +-- @return string A human-readable string representing the input ms. +function worldeditadditions.format.human_time(ms) + if type(ms) ~= "number" then return "unknown" end + local tokens = { + { 31536000 * 1000, 'year' }, + { 2592000 * 1000, 'month' }, + { 604800 * 1000, 'week' }, + { 86400 * 1000, 'day' }, + { 3600 * 1000, 'hr' }, + { 60 * 1000, 'min' }, + { 1 * 1000, 's' }, + { 1, 'ms'} + } + + for _,pair in pairs(tokens) do + if ms > pair[1] or pair[2] == "ms" then + local unit = pair[2] + if ms > 60 * 1000 and math.floor(ms / pair[1]) > 1 then + unit = unit.."s" + end + return string.format("%.2f", ms / pair[1])..unit + end + end +end diff --git a/worldeditadditions/utils/format/init.lua b/worldeditadditions/utils/format/init.lua new file mode 100644 index 0000000..b06d7b4 --- /dev/null +++ b/worldeditadditions/utils/format/init.lua @@ -0,0 +1,8 @@ +worldeditadditions.format = {} + +dofile(worldeditadditions.modpath.."/utils/format/array_2d.lua") +dofile(worldeditadditions.modpath.."/utils/format/node_distribution.lua") +dofile(worldeditadditions.modpath.."/utils/format/ascii_table.lua") +dofile(worldeditadditions.modpath.."/utils/format/map.lua") +dofile(worldeditadditions.modpath.."/utils/format/human_time.lua") +dofile(worldeditadditions.modpath.."/utils/format/human_size.lua") diff --git a/worldeditadditions/utils/format/map.lua b/worldeditadditions/utils/format/map.lua new file mode 100644 index 0000000..57f1fc1 --- /dev/null +++ b/worldeditadditions/utils/format/map.lua @@ -0,0 +1,10 @@ +--- Formats a key-value table of values as a string. +-- @param map table The table of key-value pairs to format. +-- @returns string The given table of key-value pairs formatted as a string. +function worldeditadditions.format.map(map) + local result = {} + for key, value in pairs(map) do + table.insert(result, key.."\t"..value) + end + return table.concat(result, "\n") +end diff --git a/worldeditadditions/utils/format/node_distribution.lua b/worldeditadditions/utils/format/node_distribution.lua new file mode 100644 index 0000000..f1e0c29 --- /dev/null +++ b/worldeditadditions/utils/format/node_distribution.lua @@ -0,0 +1,23 @@ + +--- Turns an associative node_id → count table into a human-readable list. +-- @param distribution table A node distribution in the format { node_name = count, .... }. +-- @param nodes_total number The total number of nodes in the distribution. +-- @param add_total bool Whether to add a grand total to the bottom or not. Default: no +function worldeditadditions.format.node_distribution(distribution, nodes_total, add_total) + local distribution_data = {} + for node_id, count in pairs(distribution) do + table.insert(distribution_data, { + count, + tostring(worldeditadditions.round((count / nodes_total) * 100, 2)).."%", + minetest.get_name_from_content_id(node_id) + }) + end + local result = worldeditadditions.format.make_ascii_table(distribution_data) + + if add_total == true then + result = result..string.rep("=", 6 + #tostring(nodes_total) + 6).."\n".. + "Total "..nodes_total.." nodes\n" + end + + return result +end diff --git a/worldeditadditions/utils/node_identification.lua b/worldeditadditions/utils/node_identification.lua index 5375cb6..c3e83c1 100644 --- a/worldeditadditions/utils/node_identification.lua +++ b/worldeditadditions/utils/node_identification.lua @@ -25,7 +25,7 @@ function worldeditadditions.is_airlike(id) return true end -- Just in case - if worldeditadditions.string_starts(this_node_name, "wielded_light") then + if worldeditadditions.str_starts(this_node_name, "wielded_light") then return true end -- Just in case diff --git a/worldeditadditions/utils/parse/init.lua b/worldeditadditions/utils/parse/init.lua new file mode 100644 index 0000000..c40d7d0 --- /dev/null +++ b/worldeditadditions/utils/parse/init.lua @@ -0,0 +1,5 @@ +worldeditadditions.parse = {} + +dofile(worldeditadditions.modpath.."/utils/parse/weighted_nodes.lua") +dofile(worldeditadditions.modpath.."/utils/parse/map.lua") +dofile(worldeditadditions.modpath.."/utils/parse/seed.lua") diff --git a/worldeditadditions/utils/parse/map.lua b/worldeditadditions/utils/parse/map.lua new file mode 100644 index 0000000..ce7cef6 --- /dev/null +++ b/worldeditadditions/utils/parse/map.lua @@ -0,0 +1,23 @@ + +--- Parses a map of key-value pairs into a table. +-- For example, "count 25000 speed 0.8 rate_erosion 0.006" would be parsed into +-- the following table: { count = 25000, speed = 0.8, rate_erosion = 0.006 }. +-- @param params_text string The string to parse. +-- @returns table A table of key-value pairs parsed out from the given string. +function worldeditadditions.parse.map(params_text) + local result = {} + local parts = worldeditadditions.split(params_text, "%s+", false) + + local last_key = nil + for i, part in ipairs(parts) do + if i % 2 == 0 then -- Lua starts at 1 :-/ + -- Try converting to a number to see if it works + local part_converted = tonumber(part) + if as_number == nil then part_converted = part end + result[last_key] = part + else + last_key = part + end + end + return true, result +end diff --git a/worldeditadditions/utils/parse/seed.lua b/worldeditadditions/utils/parse/seed.lua new file mode 100644 index 0000000..6f83bd3 --- /dev/null +++ b/worldeditadditions/utils/parse/seed.lua @@ -0,0 +1,17 @@ +--- Makes a seed from a string. +-- If the input is a number, it is returned as-is. +-- If the input is a string and can be converted to a number with tonumber(), +-- the output of tonumber() is returned. +-- Otherwise, the string is converted to a number via a simple hashing algorithm +-- (caution: certainlly NOT crypto-secure!). +-- @param {string} str The string to convert. +-- @source https://stackoverflow.com/a/2624210/1460422 The idea came from here +function worldeditadditions.parse.seed(str) + if type(str) == "number" then return str end + if tonumber(str) ~= nil then return tonumber(str) end + local result = 0 + for i = 1, #str do + result = (result*91) + (string.byte(str:sub(i, i)) * 31) + end + return result +end diff --git a/worldeditadditions/utils/parse/weighted_nodes.lua b/worldeditadditions/utils/parse/weighted_nodes.lua new file mode 100644 index 0000000..ef5db74 --- /dev/null +++ b/worldeditadditions/utils/parse/weighted_nodes.lua @@ -0,0 +1,63 @@ + +--- Parses a list of strings as a list of weighted nodes - e.g. like in +-- the //mix command. Example: "dirt 5 stone sand 2". +-- @param parts string[] The list of strings to parse (try worldeditadditions.split) +-- @param as_list bool If true, then table.insert() successive { node = string, weight = number } subtables when parsing instead of populating as an associative array. +-- @param func_normalise callable If specified, the given function will be used to normalise node names instead of worldedit.normalize_nodename. A single argument is passed containing the un-normalised node name, and the return value is assumed to be the normalised node name. +-- @returns table A table in the form node_name => weight. +function worldeditadditions.parse.weighted_nodes(parts, as_list, func_normalise) + if as_list == nil then as_list = false end + local MODE_EITHER = 1 + local MODE_NODE = 2 + + local result = {} + local mode = MODE_NODE + local last_node_name = nil + for i, part in ipairs(parts) do + -- print("i: "..i..", part: "..part) + if mode == MODE_NODE then + -- print("mode: node"); + local next + if not func_normalise then next = worldedit.normalize_nodename(part) + else next = func_normalise(part) end + if not next then + return false, "Error: Invalid node name '"..part.."'" + end + last_node_name = next + mode = MODE_EITHER + elseif mode == MODE_EITHER then + -- print("mode: either"); + local chance = tonumber(part) + if not chance then + -- print("not a chance, trying a node name") + local node_name + if not func_normalise then node_name = worldedit.normalize_nodename(part) + else node_name = func_normalise(part) end + + if not node_name then + return false, "Error: Invalid number '"..tostring(part).."'" + end + if last_node_name then + if as_list then table.insert(result, { node = last_node_name, weight = 1 }) + else result[last_node_name] = 1 end + end + last_node_name = node_name + mode = MODE_EITHER + else + -- print("it's a chance: ", chance, "for", last_node_name) + chance = math.floor(chance) + if as_list then table.insert(result, { node = last_node_name, weight = chance }) + else result[last_node_name] = chance end + last_node_name = nil + mode = MODE_NODE + end + end + end + if last_node_name then + -- print("caught trailing node name: ", last_node_name) + if as_list then table.insert(result, { node = last_node_name, weight = 1 }) + else result[last_node_name] = 1 end + end + + return true, result +end diff --git a/worldeditadditions/utils/strings.lua b/worldeditadditions/utils/strings.lua deleted file mode 100644 index aa33947..0000000 --- a/worldeditadditions/utils/strings.lua +++ /dev/null @@ -1,308 +0,0 @@ --- Licence: GPLv2 (MPL-2.0 is compatible, so we can use this here) --- Source: https://stackoverflow.com/a/43582076/1460422 - --- gsplit: iterate over substrings in a string separated by a pattern --- --- Parameters: --- text (string) - the string to iterate over --- pattern (string) - the separator pattern --- plain (boolean) - if true (or truthy), pattern is interpreted as a plain --- string, not a Lua pattern --- --- Returns: iterator --- --- Usage: --- for substr in gsplit(text, pattern, plain) do --- doSomething(substr) --- end -function worldeditadditions.gsplit(text, pattern, plain) - local splitStart, length = 1, #text - return function () - if splitStart then - local sepStart, sepEnd = string.find(text, pattern, splitStart, plain) - local ret - if not sepStart then - ret = string.sub(text, splitStart) - splitStart = nil - elseif sepEnd < sepStart then - -- Empty separator! - ret = string.sub(text, splitStart, sepStart) - if sepStart < length then - splitStart = sepStart + 1 - else - splitStart = nil - end - else - ret = sepStart > splitStart and string.sub(text, splitStart, sepStart - 1) or '' - splitStart = sepEnd + 1 - end - return ret - end - end -end - - --- split: split a string into substrings separated by a pattern. --- --- Parameters: --- text (string) - the string to iterate over --- pattern (string) - the separator pattern --- plain (boolean) - if true (or truthy), pattern is interpreted as a plain --- string, not a Lua pattern --- --- Returns: table (a sequence table containing the substrings) -function worldeditadditions.split(text, pattern, plain) - local ret = {} - for match in worldeditadditions.gsplit(text, pattern, plain) do - table.insert(ret, match) - end - return ret -end - - ---- Pads str to length len with char from right --- @source https://snipplr.com/view/13092/strlpad--pad-string-to-the-left -function worldeditadditions.str_padend(str, len, char) - if char == nil then char = ' ' end - return str .. string.rep(char, len - #str) -end ---- Pads str to length len with char from left --- Adapted from the above -function worldeditadditions.str_padstart(str, len, char) - if char == nil then char = ' ' end - return string.rep(char, len - #str) .. str -end - ---- Equivalent to string.startsWith in JS --- @param str string The string to operate on --- @param start number The start string to look for --- @returns bool Whether start is present at the beginning of str -function worldeditadditions.string_starts(str,start) - return string.sub(str,1,string.len(start))==start -end - ---- Prints a 2d array of numbers formatted like a JS TypedArray (e.g. like a manip node list or a convolutional kernel) --- In other words, the numbers should be formatted as a single flat array. --- @param tbl number[] The ZERO-indexed list of numbers --- @param width number The width of 2D array. -function worldeditadditions.print_2d(tbl, width) - print("==== count: "..#tbl..", width:"..width.." ====") - local display_width = 1 - for _i,value in pairs(tbl) do - display_width = math.max(display_width, #tostring(value)) - end - display_width = display_width + 2 - local next = {} - for i=0, #tbl do - table.insert(next, worldeditadditions.str_padstart(tostring(tbl[i]), display_width)) - if #next == width then - print(table.concat(next, "")) - next = {} - end - end -end - - - ---- Turns an associative node_id → count table into a human-readable list. --- Works well with worldeditadditions.make_ascii_table(). -function worldeditadditions.node_distribution_to_list(distribution, nodes_total) - local distribution_data = {} - for node_id, count in pairs(distribution) do - table.insert(distribution_data, { - count, - tostring(worldeditadditions.round((count / nodes_total) * 100, 2)).."%", - minetest.get_name_from_content_id(node_id) - }) - end - return distribution_data -end - ---- Makes a human-readable table of data. --- Data should be a 2D array - i.e. a table of tables. The nested tables should --- contain a list of items for a single row. --- If total is specified, then a grand total is printed at the bottom - this is --- useful when you want to print a node list - works well with --- worldeditadditions.node_distribution_to_list(). -function worldeditadditions.make_ascii_table(data, total) - local extra_padding = 2 - local result = {} - local max_lengths = {} - for y = 1, #data, 1 do - for x = 1, #data[y], 1 do - if not max_lengths[x] then - max_lengths[x] = 0 - end - max_lengths[x] = math.max(max_lengths[x], #tostring(data[y][x]) + extra_padding) - end - end - - for _key, row in ipairs(data) do - local row_result = {} - for i = 1, #row, 1 do - row_result[#row_result + 1] = worldeditadditions.str_padend(tostring(row[i]), max_lengths[i], " ") - end - result[#result+1] = table.concat(row_result, "") - end - - if total then - result[#result+1] = string.rep("=", 6 + #tostring(total) + 6).."\n".. - "Total "..total.." nodes\n" - end - - -- TODO: Add multi-column support here - return table.concat(result, "\n") -end - ---- Parses a list of strings as a list of weighted nodes - e.g. like in the //mix command. --- @param parts string[] The list of strings to parse (try worldeditadditions.split) --- @param as_list bool If true, then table.insert() successive { node = string, weight = number } subtables when parsing instead of populating as an associative array. --- @param func_normalise callable If specified, the given function will be used to normalise node names instead of worldedit.normalize_nodename. A single argument is passed containing the un-normalised node name, and the return value is assumed to be the normalised node name. --- @returns table A table in the form node_name => weight. -function worldeditadditions.parse_weighted_nodes(parts, as_list, func_normalise) - if as_list == nil then as_list = false end - local MODE_EITHER = 1 - local MODE_NODE = 2 - - local result = {} - local mode = MODE_NODE - local last_node_name = nil - for i, part in ipairs(parts) do - -- print("i: "..i..", part: "..part) - if mode == MODE_NODE then - -- print("mode: node"); - local next - if not func_normalise then next = worldedit.normalize_nodename(part) - else next = func_normalise(part) end - if not next then - return false, "Error: Invalid node name '"..part.."'" - end - last_node_name = next - mode = MODE_EITHER - elseif mode == MODE_EITHER then - -- print("mode: either"); - local chance = tonumber(part) - if not chance then - -- print("not a chance, trying a node name") - local node_name - if not func_normalise then node_name = worldedit.normalize_nodename(part) - else node_name = func_normalise(part) end - - if not node_name then - return false, "Error: Invalid number '"..tostring(part).."'" - end - if last_node_name then - if as_list then table.insert(result, { node = last_node_name, weight = 1 }) - else result[last_node_name] = 1 end - end - last_node_name = node_name - mode = MODE_EITHER - else - -- print("it's a chance: ", chance, "for", last_node_name) - chance = math.floor(chance) - if as_list then table.insert(result, { node = last_node_name, weight = chance }) - else result[last_node_name] = chance end - last_node_name = nil - mode = MODE_NODE - end - end - end - if last_node_name then - -- print("caught trailing node name: ", last_node_name) - if as_list then table.insert(result, { node = last_node_name, weight = 1 }) - else result[last_node_name] = 1 end - end - - return true, result -end - -function worldeditadditions.parse_map(params_text) - local result = {} - local parts = worldeditadditions.split(params_text, "%s+", false) - - local last_key = nil - for i, part in ipairs(parts) do - if i % 2 == 0 then -- Lua starts at 1 :-/ - -- Try converting to a number to see if it works - local part_converted = tonumber(part) - if as_number == nil then part_converted = part end - result[last_key] = part - else - last_key = part - end - end - return true, result -end - -function worldeditadditions.map_stringify(map) - local result = {} - for key, value in pairs(map) do - table.insert(result, key.."\t"..value) - end - return table.concat(result, "\n") -end - ---- Converts a float milliseconds into a human-readable string. --- Ported from PHP human_time from Pepperminty Wiki: https://github.com/sbrl/Pepperminty-Wiki/blob/fa81f0d/core/05-functions.php#L82-L104 --- @param ms float The number of milliseconds to convert. --- @return string A human-readable string representing the input ms. -function worldeditadditions.human_time(ms) - if type(ms) ~= "number" then return "unknown" end - local tokens = { - { 31536000 * 1000, 'year' }, - { 2592000 * 1000, 'month' }, - { 604800 * 1000, 'week' }, - { 86400 * 1000, 'day' }, - { 3600 * 1000, 'hr' }, - { 60 * 1000, 'min' }, - { 1 * 1000, 's' }, - { 1, 'ms'} - } - - for _,pair in pairs(tokens) do - if ms > pair[1] or pair[2] == "ms" then - local unit = pair[2] - if ms > 60 * 1000 and math.floor(ms / pair[1]) > 1 then - unit = unit.."s" - end - return string.format("%.2f", ms / pair[1])..unit - end - end -end - ---- 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. -function worldeditadditions.human_size(n, decimals) - 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 - - ---- Makes a seed from a string. --- If the input is a number, it is returned as-is. --- If the input is a string and can be converted to a number with tonumber(), --- the output of tonumber() is returned. --- Otherwise, the string is converted to a number via a simple hashing algorithm --- (caution: certainlly NOT crypto-secure!). --- @param {string} str The string to convert. --- @source https://stackoverflow.com/a/2624210/1460422 The idea came from here -function worldeditadditions.makeseed(str) - if type(str) == "number" then return str end - if tonumber(str) ~= nil then return tonumber(str) end - local result = 0 - for i = 1, #str do - result = (result*91) + (string.byte(str:sub(i, i)) * 31) - end - return result -end - --- From http://lua-users.org/wiki/StringTrim -function worldeditadditions.trim(s) - return (s:gsub("^%s*(.-)%s*$", "%1")) -end diff --git a/worldeditadditions/utils/strings/init.lua b/worldeditadditions/utils/strings/init.lua new file mode 100644 index 0000000..c62cc67 --- /dev/null +++ b/worldeditadditions/utils/strings/init.lua @@ -0,0 +1,2 @@ +dofile(worldeditadditions.modpath.."/utils/strings/split.lua") +dofile(worldeditadditions.modpath.."/utils/strings/polyfill.lua") diff --git a/worldeditadditions/utils/strings/polyfill.lua b/worldeditadditions/utils/strings/polyfill.lua new file mode 100644 index 0000000..d362353 --- /dev/null +++ b/worldeditadditions/utils/strings/polyfill.lua @@ -0,0 +1,35 @@ +--[[ +Functions that operate on strings that *really* should be present in the Lua +standard library, but somehow aren't. +A good rule of thumb is to ask "does Javascript have a built-in function for +this?". If yes, then your implementation probably belongs here. +]]-- + +--- Pads str to length len with char from right +-- @source https://snipplr.com/view/13092/strlpad--pad-string-to-the-left +function worldeditadditions.str_padend(str, len, char) + if char == nil then char = ' ' end + return str .. string.rep(char, len - #str) +end +--- Pads str to length len with char from left +-- Adapted from the above +function worldeditadditions.str_padstart(str, len, char) + if char == nil then char = ' ' end + return string.rep(char, len - #str) .. str +end + +--- Equivalent to string.startsWith in JS +-- @param str string The string to operate on +-- @param start number The start string to look for +-- @returns bool Whether start is present at the beginning of str +function worldeditadditions.str_starts(str,start) + return string.sub(str,1,string.len(start))==start +end + +--- Trims whitespace from a string from the beginning and the end. +-- From http://lua-users.org/wiki/StringTrim +-- @param str string The string to trim the whitespace from. +-- @returns string A copy of the original string with the whitespace trimmed. +function worldeditadditions.trim(str) + return (str:gsub("^%s*(.-)%s*$", "%1")) +end diff --git a/worldeditadditions/utils/strings/split.lua b/worldeditadditions/utils/strings/split.lua new file mode 100644 index 0000000..90e2b6d --- /dev/null +++ b/worldeditadditions/utils/strings/split.lua @@ -0,0 +1,60 @@ +-- Licence: GPLv2 (MPL-2.0 is compatible, so we can use this here) +-- Source: https://stackoverflow.com/a/43582076/1460422 + +-- gsplit: iterate over substrings in a string separated by a pattern +-- +-- Parameters: +-- text (string) - the string to iterate over +-- pattern (string) - the separator pattern +-- plain (boolean) - if true (or truthy), pattern is interpreted as a plain +-- string, not a Lua pattern +-- +-- Returns: iterator +-- +-- Usage: +-- for substr in gsplit(text, pattern, plain) do +-- doSomething(substr) +-- end +function worldeditadditions.gsplit(text, pattern, plain) + local splitStart, length = 1, #text + return function () + if splitStart then + local sepStart, sepEnd = string.find(text, pattern, splitStart, plain) + local ret + if not sepStart then + ret = string.sub(text, splitStart) + splitStart = nil + elseif sepEnd < sepStart then + -- Empty separator! + ret = string.sub(text, splitStart, sepStart) + if sepStart < length then + splitStart = sepStart + 1 + else + splitStart = nil + end + else + ret = sepStart > splitStart and string.sub(text, splitStart, sepStart - 1) or '' + splitStart = sepEnd + 1 + end + return ret + end + end +end + + +-- split: split a string into substrings separated by a pattern. +-- +-- Parameters: +-- text (string) - the string to iterate over +-- pattern (string) - the separator pattern +-- plain (boolean) - if true (or truthy), pattern is interpreted as a plain +-- string, not a Lua pattern +-- +-- Returns: table (a sequence table containing the substrings) +function worldeditadditions.split(text, pattern, plain) + local ret = {} + for match in worldeditadditions.gsplit(text, pattern, plain) do + table.insert(ret, match) + end + return ret +end diff --git a/worldeditadditions_commands/commands/bonemeal.lua b/worldeditadditions_commands/commands/bonemeal.lua index 5551cb7..4223115 100644 --- a/worldeditadditions_commands/commands/bonemeal.lua +++ b/worldeditadditions_commands/commands/bonemeal.lua @@ -58,6 +58,6 @@ worldedit.register_command("bonemeal", { if candidates == 0 then percentage = 0 end minetest.log("action", name .. " used //bonemeal at "..worldeditadditions.vector.tostring(worldedit.pos1[name]).." - "..worldeditadditions.vector.tostring(worldedit.pos2[name])..", bonemealing " .. nodes_bonemealed.." nodes (out of "..candidates.." nodes) at strength "..strength.." in "..time_taken.."s") - return true, nodes_bonemealed.." out of "..candidates.." (~"..percentage.."%) candidates bonemealed in "..worldeditadditions.human_time(time_taken) + return true, nodes_bonemealed.." out of "..candidates.." (~"..percentage.."%) candidates bonemealed in "..worldeditadditions.format.human_time(time_taken) end }) diff --git a/worldeditadditions_commands/commands/convolve.lua b/worldeditadditions_commands/commands/convolve.lua index 3af7002..da12810 100644 --- a/worldeditadditions_commands/commands/convolve.lua +++ b/worldeditadditions_commands/commands/convolve.lua @@ -67,6 +67,6 @@ worldedit.register_command("convolve", { minetest.log("action", name.." used //convolve at "..worldeditadditions.vector.tostring(worldedit.pos1[name]).." - "..worldeditadditions.vector.tostring(worldedit.pos2[name])..", adding "..stats.added.." nodes and removing "..stats.removed.." nodes in "..time_taken.."s") - return true, "Added "..stats.added.." and removed "..stats.removed.." nodes in " .. worldeditadditions.human_time(time_taken) + return true, "Added "..stats.added.." and removed "..stats.removed.." nodes in " .. worldeditadditions.format.human_time(time_taken) end }) diff --git a/worldeditadditions_commands/commands/count.lua b/worldeditadditions_commands/commands/count.lua index 00731e8..3a65d29 100644 --- a/worldeditadditions_commands/commands/count.lua +++ b/worldeditadditions_commands/commands/count.lua @@ -24,14 +24,14 @@ worldedit.register_command("count", { true ) - local result = worldeditadditions.make_ascii_table(counts).."\n".. + local result = worldeditadditions.format.make_ascii_table(counts).."\n".. string.rep("=", 6 + #tostring(total) + 6).."\n".. "Total "..total.." nodes\n" local time_taken = worldeditadditions.get_ms_time() - start_time - minetest.log("action", name.." used //count at "..worldeditadditions.vector.tostring(worldedit.pos1[name]).." - "..worldeditadditions.vector.tostring(worldedit.pos2[name])..", counting "..total.." nodes in "..worldeditadditions.human_time(time_taken)) + minetest.log("action", name.." used //count at "..worldeditadditions.vector.tostring(worldedit.pos1[name]).." - "..worldeditadditions.vector.tostring(worldedit.pos2[name])..", counting "..total.." nodes in "..worldeditadditions.format.human_time(time_taken)) return true, result end }) diff --git a/worldeditadditions_commands/commands/ellipsoid.lua b/worldeditadditions_commands/commands/ellipsoid.lua index 4bb1c51..47e1b25 100644 --- a/worldeditadditions_commands/commands/ellipsoid.lua +++ b/worldeditadditions_commands/commands/ellipsoid.lua @@ -48,7 +48,7 @@ worldedit.register_command("ellipsoid", { local time_taken = worldeditadditions.get_ms_time() - start_time minetest.log("action", name .. " used //ellipsoid at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. ", replacing " .. replaced .. " nodes in " .. time_taken .. "s") - return true, replaced .. " nodes replaced in " .. worldeditadditions.human_time(time_taken) + return true, replaced .. " nodes replaced in " .. worldeditadditions.format.human_time(time_taken) end }) @@ -71,6 +71,6 @@ worldedit.register_command("hollowellipsoid", { local time_taken = worldeditadditions.get_ms_time() - start_time minetest.log("action", name .. " used //hollowellipsoid at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. ", replacing " .. replaced .. " nodes in " .. time_taken .. "s") - return true, replaced .. " nodes replaced in " .. worldeditadditions.human_time(time_taken) + return true, replaced .. " nodes replaced in " .. worldeditadditions.format.human_time(time_taken) end }) diff --git a/worldeditadditions_commands/commands/erode.lua b/worldeditadditions_commands/commands/erode.lua index 4fc1c37..807d2ce 100644 --- a/worldeditadditions_commands/commands/erode.lua +++ b/worldeditadditions_commands/commands/erode.lua @@ -22,7 +22,7 @@ worldedit.register_command("erode", { return false, "Failed to split params_text into 2 parts (this is probably a bug)" end - local success, map = worldeditadditions.parse_map(params) + local success, map = worldeditadditions.parse.map(params) if not success then return success, map end return true, algorithm, map end, @@ -39,6 +39,6 @@ worldedit.register_command("erode", { local time_taken = worldeditadditions.get_ms_time() - start_time minetest.log("action", name .. " used //erode "..algorithm.." at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. ", adding " .. stats.added .. " nodes and removing " .. stats.removed .. " nodes in " .. time_taken .. "s") - return true, msg.."\n"..stats.added .. " nodes added and " .. stats.removed .. " nodes removed in " .. worldeditadditions.human_time(time_taken) + return true, msg.."\n"..stats.added .. " nodes added and " .. stats.removed .. " nodes removed in " .. worldeditadditions.format.human_time(time_taken) end }) diff --git a/worldeditadditions_commands/commands/extra/saplingaliases.lua b/worldeditadditions_commands/commands/extra/saplingaliases.lua index a495ca6..5dcb6ac 100644 --- a/worldeditadditions_commands/commands/extra/saplingaliases.lua +++ b/worldeditadditions_commands/commands/extra/saplingaliases.lua @@ -23,7 +23,7 @@ minetest.register_chatcommand("/saplingaliases", { table.insert(display, { node_name, alias }) end table.sort(display, function(a, b) return a[2] < b[2] end) - table.insert(msg, worldeditadditions.make_ascii_table(display)) + table.insert(msg, worldeditadditions.format.make_ascii_table(display)) elseif params_text == "all_saplings" then local results = worldeditadditions.registered_nodes_by_group("sapling") table.insert(msg, "Sapling-like nodes:\n") diff --git a/worldeditadditions_commands/commands/fillcaves.lua b/worldeditadditions_commands/commands/fillcaves.lua index 3a764a7..1b1cbe6 100644 --- a/worldeditadditions_commands/commands/fillcaves.lua +++ b/worldeditadditions_commands/commands/fillcaves.lua @@ -31,6 +31,6 @@ worldedit.register_command("fillcaves", { local time_taken = worldeditadditions.get_ms_time() - start_time minetest.log("action", name .. " used //fillcaves at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. ", replacing " .. stats.replaced .. " nodes in " .. time_taken .. "s") - return true, stats.replaced .. " nodes replaced in " .. worldeditadditions.human_time(time_taken) + return true, stats.replaced .. " nodes replaced in " .. worldeditadditions.format.human_time(time_taken) end }) diff --git a/worldeditadditions_commands/commands/floodfill.lua b/worldeditadditions_commands/commands/floodfill.lua index 4dc63e7..0412eaa 100644 --- a/worldeditadditions_commands/commands/floodfill.lua +++ b/worldeditadditions_commands/commands/floodfill.lua @@ -44,6 +44,6 @@ worldedit.register_command("floodfill", { end minetest.log("action", name .. " used //floodfill at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. ", replacing " .. nodes_replaced .. " nodes in " .. time_taken .. "s") - return true, nodes_replaced .. " nodes replaced in " .. worldeditadditions.human_time(time_taken) + return true, nodes_replaced .. " nodes replaced in " .. worldeditadditions.format.human_time(time_taken) end }) diff --git a/worldeditadditions_commands/commands/forest.lua b/worldeditadditions_commands/commands/forest.lua index e9d8336..14810f6 100644 --- a/worldeditadditions_commands/commands/forest.lua +++ b/worldeditadditions_commands/commands/forest.lua @@ -17,7 +17,7 @@ worldedit.register_command("forest", { params_text = params_text:sub(#match_start + 1) -- everything starts at 1 in Lua :-/ end - local success, sapling_list = worldeditadditions.parse_weighted_nodes( + local success, sapling_list = worldeditadditions.parse.weighted_nodes( worldeditadditions.split(params_text, "%s+", false), false, function(name) @@ -42,10 +42,12 @@ worldedit.register_command("forest", { sapling_list ) if not success then return success, stats end - local time_taken = worldeditadditions.human_time(worldeditadditions.get_ms_time() - start_time) + local time_taken = worldeditadditions.format.human_time(worldeditadditions.get_ms_time() - start_time) - local distribution_display = worldeditadditions.make_ascii_table( - worldeditadditions.node_distribution_to_list(stats.placed, stats.successes) + local distribution_display = worldeditadditions.format.node_distribution( + stats.placed, + stats.successes, + false -- no grand total at the bottom ) minetest.log("action", name.." used //forest at "..worldeditadditions.vector.tostring(worldedit.pos1[name]).." - "..worldeditadditions.vector.tostring(worldedit.pos2[name])..", "..stats.successes.." trees placed, averaging "..stats.attempts_avg.." growth attempts / tree and "..stats.failures.." failed attempts in "..time_taken) diff --git a/worldeditadditions_commands/commands/hollow.lua b/worldeditadditions_commands/commands/hollow.lua index f4f0115..40adc05 100644 --- a/worldeditadditions_commands/commands/hollow.lua +++ b/worldeditadditions_commands/commands/hollow.lua @@ -43,6 +43,6 @@ worldedit.register_command("hollow", { if not success then return success, changes end minetest.log("action", name .. " used //hollow at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. ", replacing " .. changes.replaced .. " nodes in " .. time_taken .. "s") - return true, changes.replaced .. " nodes replaced in " .. worldeditadditions.human_time(time_taken) + return true, changes.replaced .. " nodes replaced in " .. worldeditadditions.format.human_time(time_taken) end }) diff --git a/worldeditadditions_commands/commands/layers.lua b/worldeditadditions_commands/commands/layers.lua index ddef8c4..28dd8da 100644 --- a/worldeditadditions_commands/commands/layers.lua +++ b/worldeditadditions_commands/commands/layers.lua @@ -13,7 +13,7 @@ worldedit.register_command("layers", { params_text = "dirt_with_grass dirt 3" end - local success, node_list = worldeditadditions.parse_weighted_nodes( + local success, node_list = worldeditadditions.parse.weighted_nodes( worldeditadditions.split(params_text, "%s+", false), true ) @@ -28,6 +28,6 @@ worldedit.register_command("layers", { local time_taken = worldeditadditions.get_ms_time() - start_time minetest.log("action", name .. " used //layers at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. ", replacing " .. changes.replaced .. " nodes and skipping " .. changes.skipped_columns .. " columns in " .. time_taken .. "s") - return true, changes.replaced .. " nodes replaced and " .. changes.skipped_columns .. " columns skipped in " .. worldeditadditions.human_time(time_taken) + return true, changes.replaced .. " nodes replaced and " .. changes.skipped_columns .. " columns skipped in " .. worldeditadditions.format.human_time(time_taken) end }) diff --git a/worldeditadditions_commands/commands/line.lua b/worldeditadditions_commands/commands/line.lua index c911d45..644fafa 100644 --- a/worldeditadditions_commands/commands/line.lua +++ b/worldeditadditions_commands/commands/line.lua @@ -47,6 +47,6 @@ worldedit.register_command("line", { if success == false then return false, stats end minetest.log("action", name .. " used //line at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. ", replacing " .. stats.replaced .. " nodes in " .. time_taken .. "s") - return true, stats.replaced .. " nodes replaced in " .. worldeditadditions.human_time(time_taken) + return true, stats.replaced .. " nodes replaced in " .. worldeditadditions.format.human_time(time_taken) end }) diff --git a/worldeditadditions_commands/commands/maze.lua b/worldeditadditions_commands/commands/maze.lua index fabac5e..042812f 100644 --- a/worldeditadditions_commands/commands/maze.lua +++ b/worldeditadditions_commands/commands/maze.lua @@ -27,7 +27,7 @@ local function parse_params_maze(params_text, is_3d) path_depth = tonumber(parts[4]) end if #parts >= param_index_seed then - seed = worldeditadditions.makeseed(parts[param_index_seed]) + seed = worldeditadditions.parse.seed(parts[param_index_seed]) end replace_node = worldedit.normalize_nodename(replace_node) @@ -76,7 +76,7 @@ worldedit.register_command("maze", { local time_taken = worldeditadditions.get_ms_time() - start_time minetest.log("action", name .. " used //maze at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. " - "..worldeditadditions.vector.tostring(worldedit.pos2[name])..", replacing " .. replaced .. " nodes in " .. time_taken .. "s") - return true, replaced .. " nodes replaced in " .. worldeditadditions.human_time(time_taken) + return true, replaced .. " nodes replaced in " .. worldeditadditions.format.human_time(time_taken) end }) @@ -107,6 +107,6 @@ worldedit.register_command("maze3d", { minetest.log("action", name .. " used //maze3d at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. " - "..worldeditadditions.vector.tostring(worldedit.pos2[name])..", replacing " .. replaced .. " nodes in " .. time_taken .. "s") - return true, replaced .. " nodes replaced in " .. worldeditadditions.human_time(time_taken) + return true, replaced .. " nodes replaced in " .. worldeditadditions.format.human_time(time_taken) end }) diff --git a/worldeditadditions_commands/commands/meta/ellipsoidapply.lua b/worldeditadditions_commands/commands/meta/ellipsoidapply.lua index 8a89dab..652dce0 100644 --- a/worldeditadditions_commands/commands/meta/ellipsoidapply.lua +++ b/worldeditadditions_commands/commands/meta/ellipsoidapply.lua @@ -56,7 +56,7 @@ worldedit.register_command("ellipsoidapply", { ) local time_overhead = 100 - worldeditadditions.round((stats_time.fn / stats_time.all) * 100, 3) - minetest.log("action", name.." used //ellipsoidapply at "..worldeditadditions.vector.tostring(worldedit.pos1[name]).." - "..worldeditadditions.vector.tostring(worldedit.pos2[name]).." in "..worldeditadditions.human_time(stats_time.all)) - return true, "Complete in "..worldeditadditions.human_time(stats_time.all).." ("..worldeditadditions.human_time(stats_time.fn).." fn, "..time_overhead.."% ellipsoidapply overhead)" + minetest.log("action", name.." used //ellipsoidapply at "..worldeditadditions.vector.tostring(worldedit.pos1[name]).." - "..worldeditadditions.vector.tostring(worldedit.pos2[name]).." in "..worldeditadditions.format.human_time(stats_time.all)) + return true, "Complete in "..worldeditadditions.format.human_time(stats_time.all).." ("..worldeditadditions.format.human_time(stats_time.fn).." fn, "..time_overhead.."% ellipsoidapply overhead)" end }) diff --git a/worldeditadditions_commands/commands/meta/many.lua b/worldeditadditions_commands/commands/meta/many.lua index 5307f56..d5165f1 100644 --- a/worldeditadditions_commands/commands/meta/many.lua +++ b/worldeditadditions_commands/commands/meta/many.lua @@ -34,9 +34,9 @@ local function step(params) full_cmd, (params.i + 1), params.count, ((params.i + 1) / params.count)*100, - worldeditadditions.human_time(params.times[#params.times] or 0), - worldeditadditions.human_time(worldeditadditions.average(params.times)), - worldeditadditions.human_time(worldeditadditions.eta( + worldeditadditions.format.human_time(params.times[#params.times] or 0), + worldeditadditions.format.human_time(worldeditadditions.average(params.times)), + worldeditadditions.format.human_time(worldeditadditions.eta( params.times, params.i, params.count @@ -60,8 +60,8 @@ local function step(params) table.insert(done_message, string.format("Executed '"..full_cmd.."' %d times in %s (~%s / time)", #params.times, - worldeditadditions.human_time(total_time), - worldeditadditions.human_time( + worldeditadditions.format.human_time(total_time), + worldeditadditions.format.human_time( worldeditadditions.average(params.times) ) ) @@ -70,7 +70,7 @@ local function step(params) if #params.times < 10 then local message_parts = {} for j=1,#params.times do - table.insert(message_parts, worldeditadditions.human_time(params.times[j])) + table.insert(message_parts, worldeditadditions.format.human_time(params.times[j])) end table.insert(done_message, "; ") table.insert(done_message, table.concat(message_parts, ", ")) diff --git a/worldeditadditions_commands/commands/meta/multi.lua b/worldeditadditions_commands/commands/meta/multi.lua index 1be4dca..c63da7d 100644 --- a/worldeditadditions_commands/commands/meta/multi.lua +++ b/worldeditadditions_commands/commands/meta/multi.lua @@ -75,12 +75,12 @@ minetest.register_chatcommand("/multi", { table.insert(done_message, string.format("Executed %d commands in %s (", #times, - worldeditadditions.human_time(total_time) + worldeditadditions.format.human_time(total_time) ) ) local message_parts = {} for j=1,#times do - table.insert(message_parts, worldeditadditions.human_time(times[j])) + table.insert(message_parts, worldeditadditions.format.human_time(times[j])) end table.insert(done_message, table.concat(message_parts, ", ")) table.insert(done_message, ")") diff --git a/worldeditadditions_commands/commands/meta/subdivide.lua b/worldeditadditions_commands/commands/meta/subdivide.lua index 8e8cb60..00b0779 100644 --- a/worldeditadditions_commands/commands/meta/subdivide.lua +++ b/worldeditadditions_commands/commands/meta/subdivide.lua @@ -130,10 +130,10 @@ worldedit.register_command("subdivide", { msg_prefix, stats.chunks_completed, stats.chunks_total, (stats.chunks_completed / stats.chunks_total) * 100, - wea.human_time(math.floor(stats.times.step_last)), -- the time is an integer anyway because precision - wea.human_time(wea.average(stats.times.steps)), + worldeditadditions.format.human_time(math.floor(stats.times.step_last)), -- the time is an integer anyway because precision + worldeditadditions.format.human_time(wea.average(stats.times.steps)), stats.emerge_overhead * 100, - wea.human_time(stats.eta) + worldeditadditions.format.human_time(stats.eta) ) ) time_last_msg = wea.get_ms_time() @@ -150,13 +150,13 @@ worldedit.register_command("subdivide", { wea.vector.tostring(pos2), stats.chunks_completed, stats.volume_nodes, - wea.human_time(stats.times.total) + worldeditadditions.format.human_time(stats.times.total) )) worldedit.player_notify(name, string.format( "%sComplete: %d chunks processed in %s (%.2f%% emerge overhead, emerge totals: %s)", msg_prefix, stats.chunks_completed, - wea.human_time(stats.times.total), + worldeditadditions.format.human_time(stats.times.total), stats.emerge_overhead * 100, emerge_stats_tostring(stats.emerge) )) diff --git a/worldeditadditions_commands/commands/overlay.lua b/worldeditadditions_commands/commands/overlay.lua index a1e0c52..ad0ddf5 100644 --- a/worldeditadditions_commands/commands/overlay.lua +++ b/worldeditadditions_commands/commands/overlay.lua @@ -9,7 +9,7 @@ worldedit.register_command("overlay", { privs = { worldedit = true }, require_pos = 2, parse = function(params_text) - local success, node_list = worldeditadditions.parse_weighted_nodes( + local success, node_list = worldeditadditions.parse.weighted_nodes( worldeditadditions.split(params_text, "%s+", false) ) return success, node_list @@ -25,6 +25,6 @@ worldedit.register_command("overlay", { local time_taken = worldeditadditions.get_ms_time() - start_time minetest.log("action", name .. " used //overlay at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. ", replacing " .. changes.updated .. " nodes and skipping " .. changes.skipped_columns .. " columns in " .. time_taken .. "s") - return true, changes.updated .. " nodes replaced and " .. changes.skipped_columns .. " columns skipped in " .. worldeditadditions.human_time(time_taken) + return true, changes.updated .. " nodes replaced and " .. changes.skipped_columns .. " columns skipped in " .. worldeditadditions.format.human_time(time_taken) end }) diff --git a/worldeditadditions_commands/commands/replacemix.lua b/worldeditadditions_commands/commands/replacemix.lua index 83b22a2..965cd2c 100644 --- a/worldeditadditions_commands/commands/replacemix.lua +++ b/worldeditadditions_commands/commands/replacemix.lua @@ -78,9 +78,10 @@ worldedit.register_command("replacemix", { local nodes_total = worldedit.volume(worldedit.pos1[name], worldedit.pos2[name]) local percentage_replaced = worldeditadditions.round((changed / candidates)*100, 2) - local distribution_table = worldeditadditions.make_ascii_table( - worldeditadditions.node_distribution_to_list(distribution, changed), - changed + local distribution_table = worldeditadditions.format.node_distribution( + distribution, + changed, + true -- Add a grand total to the bottom ) local time_taken = worldeditadditions.get_ms_time() - start_time @@ -88,6 +89,6 @@ worldedit.register_command("replacemix", { minetest.log("action", name .. " used //replacemix at "..worldeditadditions.vector.tostring(worldedit.pos1[name]).." - "..worldeditadditions.vector.tostring(worldedit.pos2[name])..", replacing " .. changed.." nodes (out of "..nodes_total.." nodes) in "..time_taken.."s") - return true, distribution_table..changed.." out of "..candidates.." (~"..percentage_replaced.."%) candidates replaced in "..worldeditadditions.human_time(time_taken) + return true, distribution_table..changed.." out of "..candidates.." (~"..percentage_replaced.."%) candidates replaced in "..worldeditadditions.format.human_time(time_taken) end }) diff --git a/worldeditadditions_commands/commands/scale.lua b/worldeditadditions_commands/commands/scale.lua index d3e724e..43044bd 100644 --- a/worldeditadditions_commands/commands/scale.lua +++ b/worldeditadditions_commands/commands/scale.lua @@ -122,6 +122,6 @@ worldedit.register_command("scale", { minetest.log("action", name.." used //scale at "..worldeditadditions.vector.tostring(worldedit.pos1[name]).." - "..worldeditadditions.vector.tostring(worldedit.pos2[name])..", updating "..stats.updated.." nodes in "..time_taken.."s") - return true, stats.updated.." nodes updated in " .. worldeditadditions.human_time(time_taken) + return true, stats.updated.." nodes updated in " .. worldeditadditions.format.human_time(time_taken) end }) diff --git a/worldeditadditions_commands/commands/torus.lua b/worldeditadditions_commands/commands/torus.lua index 021ac5a..0d6d4a7 100644 --- a/worldeditadditions_commands/commands/torus.lua +++ b/worldeditadditions_commands/commands/torus.lua @@ -46,7 +46,7 @@ worldedit.register_command("torus", { local time_taken = worldeditadditions.get_ms_time() - start_time minetest.log("action", name .. " used //torus at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. ", replacing " .. replaced .. " nodes in " .. time_taken .. "s") - return true, replaced .. " nodes replaced in " .. worldeditadditions.human_time(time_taken) + return true, replaced .. " nodes replaced in " .. worldeditadditions.format.human_time(time_taken) end }) @@ -69,6 +69,6 @@ worldedit.register_command("hollowtorus", { local time_taken = worldeditadditions.get_ms_time() - start_time minetest.log("action", name .. " used //hollowtorus at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. ", replacing " .. replaced .. " nodes in " .. time_taken .. "s") - return true, replaced .. " nodes replaced in " .. worldeditadditions.human_time(time_taken) + return true, replaced .. " nodes replaced in " .. worldeditadditions.format.human_time(time_taken) end }) diff --git a/worldeditadditions_commands/commands/walls.lua b/worldeditadditions_commands/commands/walls.lua index b67953d..1ca777e 100644 --- a/worldeditadditions_commands/commands/walls.lua +++ b/worldeditadditions_commands/commands/walls.lua @@ -29,6 +29,6 @@ worldedit.register_command("walls", { local time_taken = worldeditadditions.get_ms_time() - start_time minetest.log("action", name .. " used //walls from "..worldeditadditions.vector.tostring(worldedit.pos1[name]).." to "..worldeditadditions.vector.tostring(worldedit.pos1[name])..", replacing " .. replaced .. " nodes in " .. time_taken .. "s") - return true, replaced .. " nodes replaced in " .. worldeditadditions.human_time(time_taken) + return true, replaced .. " nodes replaced in " .. worldeditadditions.format.human_time(time_taken) end })