diff --git a/worldeditadditions/init.lua b/worldeditadditions/init.lua index 6342b07..a46e9d4 100644 --- a/worldeditadditions/init.lua +++ b/worldeditadditions/init.lua @@ -55,6 +55,7 @@ dofile(worldeditadditions.modpath.."/lib/bonemeal.lua") dofile(worldeditadditions.modpath.."/lib/forest.lua") dofile(worldeditadditions.modpath.."/lib/ellipsoidapply.lua") +dofile(worldeditadditions.modpath.."/lib/airapply.lua") dofile(worldeditadditions.modpath.."/lib/subdivide.lua") dofile(worldeditadditions.modpath.."/lib/selection/stack.lua") diff --git a/worldeditadditions/lib/airapply.lua b/worldeditadditions/lib/airapply.lua index 761d3d0..99236bb 100644 --- a/worldeditadditions/lib/airapply.lua +++ b/worldeditadditions/lib/airapply.lua @@ -35,12 +35,13 @@ function worldeditadditions.airapply(pos1, pos2, func) 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 i = area:index(x, y, z) - local old_is_airlike = worldeditadditions.is_airlike(data_before[i]) + local i_before = area_before:index(x, y, z) + local i_after = area_after:index(x, y, z) + local old_is_airlike = worldeditadditions.is_airlike(data_before[i_before]) -- Roll everything that replaces nodes that aren't airlike if not old_is_airlike then - data_after[area_after:index(x, y, z)] = data_before[area_before:index(x, y, z)] + data_after[i_after] = data_before[i_before] end end end diff --git a/worldeditadditions_commands/commands/meta/airapply.lua b/worldeditadditions_commands/commands/meta/airapply.lua new file mode 100644 index 0000000..89e2a6b --- /dev/null +++ b/worldeditadditions_commands/commands/meta/airapply.lua @@ -0,0 +1,69 @@ +-- ███████ ██ ██ ██ ██████ ███████ ███████ █████ ██████ ██████ ██ ██ ██ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- █████ ██ ██ ██ ██████ ███████ █████ ███████ ██████ ██████ ██ ████ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ███████ ███████ ███████ ██ ██ ███████ ███████ ██ ██ ██ ██ ███████ ██ + +worldedit.register_command("airapply", { + params = " ", + description = "Executes the given command (automatically prepending '//'), but only on non-air nodes within the defined region.", + privs = { worldedit = true }, + require_pos = 2, + parse = function(params_text) + if params_text == "" then return false, "Error: No command specified." end + + local cmd_name, args_text = params_text:match("([^%s]+)%s+(.+)") + if not cmd_name then + cmd_name = params_text + args_text = "" + end + + -- Note that we search the worldedit commands here, not the minetest ones + local cmd_we = worldedit.registered_commands[cmd_name] + if cmd_we == nil then + return false, "Error: "..cmd_name.." isn't a valid command." + end + if cmd_we.require_pos ~= 2 then + return false, "Error: The command "..cmd_name.." exists, but doesn't take 2 positions and so can't be used with //airapply." + end + + -- Run parsing of target command + -- Lifted from cubeapply in WorldEdit + local args_parsed = {cmd_we.parse(args_text)} + if not table.remove(args_parsed, 1) then + return false, args_parsed[1] + end + + return true, cmd_we, args_parsed + end, + nodes_needed = function(name) + local pos1, pos2 = worldedit.sort_pos(worldedit.pos1[name], worldedit.pos2[name]) + return math.ceil(4/3 * math.pi * (pos2.x - pos1.x)/2 * (pos2.y - pos1.y)/2 * (pos2.z - pos1.z)/2) + end, + func = function(name, cmd, args_parsed) + if not minetest.check_player_privs(name, cmd.privs) then + return false, "Your privileges are insufficient to execute the command '"..cmd_name.."'." + end + + local pos1, pos2 = worldeditadditions.Vector3.sort( + worldedit.pos1[name], + worldedit.pos2[name] + ) + + + local success, stats_time = worldeditadditions.airapply( + pos1, pos2, + function() + cmd.func(name, worldeditadditions.table.unpack(args_parsed)) + end, args + ) + + + local time_overhead = 100 - worldeditadditions.round((stats_time.fn / stats_time.all) * 100, 3) + local text_time_all = worldeditadditions.format.human_time(stats_time.all) + local text_time_fn = worldeditadditions.format.human_time(stats_time.fn) + + minetest.log("action", name.." used //airapply at "..pos1.." - "..pos2.." in "..text_time_all) + return true, "Complete in "..text_time_all.." ("..text_time_fn.." fn, "..time_overhead.."% airapply overhead)" + end +}) diff --git a/worldeditadditions_commands/init.lua b/worldeditadditions_commands/init.lua index 3cf7e39..9b7796e 100644 --- a/worldeditadditions_commands/init.lua +++ b/worldeditadditions_commands/init.lua @@ -41,6 +41,7 @@ dofile(we_c.modpath.."/commands/meta/multi.lua") dofile(we_c.modpath.."/commands/meta/many.lua") dofile(we_c.modpath.."/commands/meta/subdivide.lua") dofile(we_c.modpath.."/commands/meta/ellipsoidapply.lua") +dofile(we_c.modpath.."/commands/meta/airapply.lua") -- Selection Tools dofile(we_c.modpath.."/commands/selectors/init.lua")