mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-12-23 03:55:01 +00:00
Add //count
This commit is contained in:
parent
f0dc2f5a3c
commit
f3a8c1dd64
8 changed files with 144 additions and 25 deletions
|
@ -6,15 +6,19 @@
|
|||
-- @author Starbeamrainbowlabs
|
||||
|
||||
worldeditadditions = {}
|
||||
worldeditadditions.modpath = minetest.get_modpath("worldeditadditions")
|
||||
dofile(worldeditadditions.modpath.."/utils/strings.lua")
|
||||
dofile(worldeditadditions.modpath.."/utils/numbers.lua")
|
||||
|
||||
dofile(minetest.get_modpath("worldeditadditions") .. "/utils.lua")
|
||||
dofile(minetest.get_modpath("worldeditadditions") .. "/lib/floodfill.lua")
|
||||
dofile(minetest.get_modpath("worldeditadditions") .. "/lib/overlay.lua")
|
||||
dofile(minetest.get_modpath("worldeditadditions") .. "/lib/ellipsoid.lua")
|
||||
dofile(minetest.get_modpath("worldeditadditions") .. "/lib/torus.lua")
|
||||
dofile(minetest.get_modpath("worldeditadditions") .. "/lib/maze2d.lua")
|
||||
dofile(minetest.get_modpath("worldeditadditions") .. "/lib/maze3d.lua")
|
||||
dofile(worldeditadditions.modpath.."/utils.lua")
|
||||
dofile(worldeditadditions.modpath.."/lib/floodfill.lua")
|
||||
dofile(worldeditadditions.modpath.."/lib/overlay.lua")
|
||||
dofile(worldeditadditions.modpath.."/lib/ellipsoid.lua")
|
||||
dofile(worldeditadditions.modpath.."/lib/torus.lua")
|
||||
dofile(worldeditadditions.modpath.."/lib/walls.lua")
|
||||
dofile(worldeditadditions.modpath.."/lib/maze2d.lua")
|
||||
dofile(worldeditadditions.modpath.."/lib/maze3d.lua")
|
||||
|
||||
dofile(minetest.get_modpath("worldeditadditions") .. "/lib/walls.lua")
|
||||
dofile(worldeditadditions.modpath.."/lib/count.lua")
|
||||
|
||||
dofile(minetest.get_modpath("worldeditadditions") .. "/lib/bonemeal.lua")
|
||||
dofile(worldeditadditions.modpath.."/lib/bonemeal.lua")
|
||||
|
|
48
worldeditadditions/lib/count.lua
Normal file
48
worldeditadditions/lib/count.lua
Normal file
|
@ -0,0 +1,48 @@
|
|||
--- Counts the nodes in a given area.
|
||||
-- @module worldeditadditions.count
|
||||
|
||||
-- ██████ ██████ ██ ██ ███ ██ ████████
|
||||
-- ██ ██ ██ ██ ██ ████ ██ ██
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ██████ ██████ ██████ ██ ████ ██
|
||||
function worldeditadditions.count(pos1, pos2)
|
||||
pos1, pos2 = worldedit.sort_pos(pos1, pos2)
|
||||
-- pos2 will always have the highest co-ordinates now
|
||||
|
||||
-- Fetch the nodes in the specified area
|
||||
local manip, area = worldedit.manip_helpers.init(pos1, pos2)
|
||||
local data = manip:get_data()
|
||||
|
||||
-- z y x is the preferred loop order (because CPU cache I'd guess, since then we're iterating linearly through the data array)
|
||||
local counts = {}
|
||||
for z = pos2.z, pos1.z, -1 do
|
||||
for y = pos2.y, pos1.y, -1 do
|
||||
for x = pos2.x, pos1.x, -1 do
|
||||
local next = data[area:index(x, y, z)]
|
||||
if not counts[next] then
|
||||
counts[next] = 0
|
||||
end
|
||||
counts[next] = counts[next] + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local total = worldedit.volume(pos1, pos2)
|
||||
|
||||
local results = {}
|
||||
for node_name, count in pairs(counts) do
|
||||
table.insert(results, {
|
||||
count,
|
||||
tostring(worldeditadditions.round((count / total) * 100, 2)).."%",
|
||||
minetest.get_name_from_content_id(node_name)
|
||||
})
|
||||
end
|
||||
table.sort(results, function(a, b) return a[1] < b[1] end)
|
||||
|
||||
-- Save the modified nodes back to disk & return
|
||||
-- No need to save - this function doesn't actually change anything
|
||||
-- worldedit.manip_helpers.finish(manip, data)
|
||||
|
||||
return true, results, total
|
||||
end
|
|
@ -1,7 +1,5 @@
|
|||
local we_c = worldeditadditions_commands
|
||||
|
||||
-- From http://lua-users.org/wiki/SimpleRound
|
||||
function we_c.round(num, numDecimalPlaces)
|
||||
function worldeditadditions.round(num, numDecimalPlaces)
|
||||
local mult = 10^(numDecimalPlaces or 0)
|
||||
return math.floor(num * mult + 0.5) / mult
|
||||
end
|
|
@ -1,9 +1,6 @@
|
|||
-- Licence: GPLv2 (MPL-2.0 is compatible, so we can use this here)
|
||||
-- Source: https://stackoverflow.com/a/43582076/1460422
|
||||
|
||||
local we_c = worldeditadditions_commands
|
||||
|
||||
|
||||
-- gsplit: iterate over substrings in a string separated by a pattern
|
||||
--
|
||||
-- Parameters:
|
||||
|
@ -18,7 +15,7 @@ local we_c = worldeditadditions_commands
|
|||
-- for substr in gsplit(text, pattern, plain) do
|
||||
-- doSomething(substr)
|
||||
-- end
|
||||
function we_c.gsplit(text, pattern, plain)
|
||||
function worldeditadditions.gsplit(text, pattern, plain)
|
||||
local splitStart, length = 1, #text
|
||||
return function ()
|
||||
if splitStart then
|
||||
|
@ -54,10 +51,49 @@ end
|
|||
-- string, not a Lua pattern
|
||||
--
|
||||
-- Returns: table (a sequence table containing the substrings)
|
||||
function we_c.split(text, pattern, plain)
|
||||
function worldeditadditions.split(text, pattern, plain)
|
||||
local ret = {}
|
||||
for match in we_c.gsplit(text, pattern, plain) do
|
||||
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
|
||||
|
||||
function worldeditadditions.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
|
|
@ -15,7 +15,7 @@ worldedit.register_command("bonemeal", {
|
|||
params_text = "1"
|
||||
end
|
||||
|
||||
local parts = we_c.split(params_text, "%s+", false)
|
||||
local parts = worldeditadditions.split(params_text, "%s+", false)
|
||||
|
||||
local strength = 1
|
||||
local chance = 1
|
||||
|
@ -52,7 +52,7 @@ worldedit.register_command("bonemeal", {
|
|||
-- nodes_bonemealed is an error message here because success == false
|
||||
return success, nodes_bonemealed
|
||||
end
|
||||
local percentage = we_c.round((nodes_bonemealed / candidates)*100, 2)
|
||||
local percentage = worldeditadditions.round((nodes_bonemealed / candidates)*100, 2)
|
||||
local time_taken = os.clock() - start_time
|
||||
|
||||
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")
|
||||
|
|
35
worldeditadditions_commands/commands/count.lua
Normal file
35
worldeditadditions_commands/commands/count.lua
Normal file
|
@ -0,0 +1,35 @@
|
|||
local we_c = worldeditadditions_commands
|
||||
|
||||
-- ██████ ██████ ██ ██ ███ ██ ████████
|
||||
-- ██ ██ ██ ██ ██ ████ ██ ██
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ██████ ██████ ██████ ██ ████ ██
|
||||
worldedit.register_command("count", {
|
||||
params = "",
|
||||
description = "Counts all the nodes in the defined region.",
|
||||
privs = { worldedit = true },
|
||||
require_pos = 2,
|
||||
parse = function(params_text)
|
||||
return true
|
||||
end,
|
||||
nodes_needed = function(name)
|
||||
-- We don't actually modify anything, but without returning a
|
||||
-- number here safe_region doesn't work
|
||||
return worldedit.volume(worldedit.pos1[name], worldedit.pos2[name])
|
||||
end,
|
||||
func = function(name)
|
||||
local start_time = os.clock()
|
||||
|
||||
local success, counts, total = worldeditadditions.count(worldedit.pos1[name], worldedit.pos2[name], target_node)
|
||||
local result = worldeditadditions.make_ascii_table(counts).."\n"..
|
||||
string.rep("=", 6 + #tostring(total) + 6).."\n"..
|
||||
"Total "..total.." nodes\n"
|
||||
|
||||
local time_taken = os.clock() - start_time
|
||||
|
||||
|
||||
minetest.log("action", name.." used //count at "..worldeditadditions.vector.tostring(worldedit.pos1[name]).." - "..worldeditadditions.vector.tostring(worldedit.pos1[name])..", counting "..total.." nodes in "..time_taken.."s")
|
||||
return true, result
|
||||
end
|
||||
})
|
|
@ -11,7 +11,7 @@ local function parse_params_maze(params_text, is_3d)
|
|||
return false, "No arguments specified"
|
||||
end
|
||||
|
||||
local parts = we_c.split(params_text, "%s+", false)
|
||||
local parts = worldeditadditions.split(params_text, "%s+", false)
|
||||
|
||||
local replace_node = parts[1]
|
||||
local seed = os.time()
|
||||
|
|
|
@ -10,9 +10,6 @@ local we_c = worldeditadditions_commands
|
|||
|
||||
we_c.modpath = minetest.get_modpath("worldeditadditions_commands")
|
||||
|
||||
dofile(we_c.modpath.."/utils/strings.lua")
|
||||
dofile(we_c.modpath.."/utils/numbers.lua")
|
||||
|
||||
dofile(we_c.modpath.."/multi.lua")
|
||||
|
||||
-- We no longer need our own implementation of safe_region thanks to @sfan5's
|
||||
|
@ -24,9 +21,10 @@ dofile(we_c.modpath.."/commands/floodfill.lua")
|
|||
dofile(we_c.modpath.."/commands/overlay.lua")
|
||||
dofile(we_c.modpath.."/commands/ellipsoid.lua")
|
||||
dofile(we_c.modpath.."/commands/torus.lua")
|
||||
dofile(we_c.modpath.."/commands/walls.lua")
|
||||
dofile(we_c.modpath.."/commands/maze.lua")
|
||||
|
||||
dofile(we_c.modpath.."/commands/walls.lua")
|
||||
dofile(we_c.modpath.."/commands/count.lua")
|
||||
|
||||
-- Don't registry the //bonemeal command if the bonemeal mod isn't present
|
||||
if minetest.get_modpath("bonemeal") then
|
||||
|
|
Loading…
Reference in a new issue