diff --git a/worldeditadditions/lib/metaballs/init.lua b/worldeditadditions/lib/metaballs/init.lua index 729737c..78f3f09 100644 --- a/worldeditadditions/lib/metaballs/init.lua +++ b/worldeditadditions/lib/metaballs/init.lua @@ -9,7 +9,8 @@ local metaballs_ns = { remove = playerdata.remove, list = playerdata.list, list_pretty = playerdata.list_pretty, - clear = playerdata.clear + clear = playerdata.clear, + volume = playerdata.volume } return metaballs_ns diff --git a/worldeditadditions/lib/metaballs/playerdata.lua b/worldeditadditions/lib/metaballs/playerdata.lua index 8367573..4edf96f 100644 --- a/worldeditadditions/lib/metaballs/playerdata.lua +++ b/worldeditadditions/lib/metaballs/playerdata.lua @@ -74,7 +74,7 @@ local function remove(player_name, index) local success, metaball_list = list(player_name) if not success then return success, metaball_list end - if #metaball_list > index then + if index > #metaball_list then return false, "Error: Requested the removal of metaball "..tostring(index)..", but there are "..tostring(#metaball_list).." metaballs defined." end @@ -95,10 +95,31 @@ local function clear(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 + clear = clear, + volume = volume } diff --git a/worldeditadditions/lib/metaballs/render.lua b/worldeditadditions/lib/metaballs/render.lua index 4ef11d4..660c3e6 100644 --- a/worldeditadditions/lib/metaballs/render.lua +++ b/worldeditadditions/lib/metaballs/render.lua @@ -48,7 +48,7 @@ local function render(metaballs, replace_node, threshold) metaball_sum = metaball_sum + falloff end - if metaball_sum <= threshold then + if metaball_sum >= threshold then data[area:index(x, y, z)] = node_id_replace replaced = replaced + 1 end diff --git a/worldeditadditions_commands/commands/metaballs.lua b/worldeditadditions_commands/commands/metaball.lua similarity index 82% rename from worldeditadditions_commands/commands/metaballs.lua rename to worldeditadditions_commands/commands/metaball.lua index 311045a..6e00d04 100644 --- a/worldeditadditions_commands/commands/metaballs.lua +++ b/worldeditadditions_commands/commands/metaball.lua @@ -6,8 +6,8 @@ local Vector3 = wea.Vector3 -- ██ ██ ██ ██ ██ ████ ██ █████ -- ██ ██ ██ ██ ██ ██ ██ ██ -- ██████ ██████ ██ ██ ███████ -worldedit.register_command("metaballs", { - params = "add | remove | list | render [] | clear", +worldedit.register_command("metaball", { + params = "add | remove | render [] | 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, @@ -32,24 +32,33 @@ worldedit.register_command("metaballs", { 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[1].."'. The radius must be a positive integer." + 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[1].."'. The index to remove must be a positive integer." + 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 @@ -65,7 +74,7 @@ worldedit.register_command("metaballs", { end table.insert(subargs, replace_node) table.insert(subargs, threshold) - elseif subcommand ~= "list" and subcommand ~= "clear" then + elseif subcommand ~= "list" and subcommand ~= "clear" and subcommand ~= "volume" then return false, "Error: Unknown subcommand '"..parts[1].."'." end @@ -73,7 +82,7 @@ worldedit.register_command("metaballs", { end, nodes_needed = function(name, subcommand) if subcommand == "render" then - return worldedit.volume(worldedit.pos1[name], worldedit.pos2[name]) + return wea.metaballs.volume(name) else return 0 end @@ -81,13 +90,19 @@ worldedit.register_command("metaballs", { func = function(name, subcommand, subargs) local start_time = wea.get_ms_time() local message = "" - local append_time = true + 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 - append_time = false + 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 @@ -108,6 +123,7 @@ worldedit.register_command("metaballs", { 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] @@ -123,6 +139,7 @@ worldedit.register_command("metaballs", { 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 diff --git a/worldeditadditions_commands/init.lua b/worldeditadditions_commands/init.lua index bacbd60..ed8d1d7 100644 --- a/worldeditadditions_commands/init.lua +++ b/worldeditadditions_commands/init.lua @@ -39,7 +39,7 @@ dofile(we_c.modpath.."/commands/spiral2.lua") dofile(we_c.modpath.."/commands/copy.lua") dofile(we_c.modpath.."/commands/move.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/sculpt.lua")