diff --git a/worldeditadditions/floodfill.lua b/worldeditadditions/floodfill.lua index 2d37e11..2fb6adc 100644 --- a/worldeditadditions/floodfill.lua +++ b/worldeditadditions/floodfill.lua @@ -1,20 +1,52 @@ --- Flood-fill command for complex lakes etc. -- @module worldeditadditions.floodfill -local Queue = require "queue" +------------------------------------------------------------------------------- +--- A Queue implementation, taken & adapted from https://www.lua.org/pil/11.4.html +-- @submodule worldeditadditions.utils.queue -local function floodfill(start_pos, radius, replace_node) +local Queue = {} +function Queue.new() + return { first = 0, last = -1 } +end + +function Queue.enqueue(queue, value) + local new_last = queue.last + 1 + queue.last = new_last + queue[new_last] = value +end + +function Queue.is_empty(queue) + return queue.first > queue.last +end + +function Queue.dequeue(queue) + local first = queue.first + if Queue.is_empty(queue) then + error("Error: The queue is empty!") + end + + local value = queue[first] + queue[first] = nil -- Help the garbage collector out + queue.first = first + 1 + return value +end + +------------------------------------------------------------------------------- + + +function worldedit.floodfill(start_pos, radius, replace_node) -- Calculate the area we want to modify - local pos1, pos2 = centre_pos - pos1.x = pos1.x - radius - pos1.z = pos1.z - radius - pos2.x = pos2.x + radius - pos2.y = pos2.y + radius - pos2.z = pos2.z + radius + local pos1 = vector.add(start_pos, { x = radius, y = 0, z = radius }) + local pos2 = vector.subtract(start_pos, { x = radius, y = radius, z = radius }) pos1, pos2 = worldedit.sort_pos(pos1, pos2) -- Just in case + minetest.log("action", "radius: " .. radius) + minetest.log("action", "pos1: (" .. pos1.x .. ", " .. pos1.y .. ", " .. pos1.z .. ")") + minetest.log("action", "pos2: (" .. pos2.x .. ", " .. pos2.y .. ", " .. pos2.z .. ")") + -- Fetch the nodes in the specified area - local manip, area = worldedit.manip_helpers.init() + local manip, area = worldedit.manip_helpers.init(pos1, pos2) local data = manip:get_data() -- Setup for the floodfill operation itself @@ -23,6 +55,8 @@ local function floodfill(start_pos, radius, replace_node) local search_id = data[start_pos_index] local replace_id = minetest.get_content_id(replace_node) + minetest.log("action", "ids: " .. search_id .. " -> " .. replace_id) + local count = 0 local remaining_nodes = Queue.new() Queue.enqueue(remaining_nodes, start_pos_index) diff --git a/worldeditadditions/init.lua b/worldeditadditions/init.lua index c6da867..5f818e8 100644 --- a/worldeditadditions/init.lua +++ b/worldeditadditions/init.lua @@ -5,4 +5,4 @@ -- @license Mozilla Public License, 2.0 -- @author Starbeamrainbowlabs -worldedit.floodfill = require "floodfill" +dofile(minetest.get_modpath("worldeditadditions") .. "/floodfill.lua") diff --git a/worldeditadditions/queue.lua b/worldeditadditions/queue.lua deleted file mode 100644 index 44e725b..0000000 --- a/worldeditadditions/queue.lua +++ /dev/null @@ -1,31 +0,0 @@ ---- A Queue implementation, taken & adapted from https://www.lua.org/pil/11.4.html --- @module worldeditadditions.utils.queue - -local Queue = {} -function Queue.new() - return { first = 0, last = -1 } -end - -function Queue.enqueue(queue, value) - local new_last = queue.last + 1 - queue.last = new_last - queue[new_last] = value -end - -function Queue.is_empty(queue) - return new_first > queue.last -end - -function Queue.dequeue(queue) - local first = queue.first - if Queue.is_empty(queue) then - error("Error: The queue is empty!") - end - - local value = queue[first] - queue[first] = nil -- Help the garbage collector out - list.first = first + 1 - return value -end - -return Queue diff --git a/worldeditadditions_commands/init.lua b/worldeditadditions_commands/init.lua index df479f8..20e3ec7 100644 --- a/worldeditadditions_commands/init.lua +++ b/worldeditadditions_commands/init.lua @@ -12,17 +12,23 @@ minetest.register_chatcommand("/floodfill", { -- TODO: Integrate will the safe_region feature of regular worldedit func = function(name, params_text) local found, _, replace_node, radius = params_text:find("([a-z:_\\-]+)%s+([0-9]+)") + if found == nil then found, _, replace_node = params_text:find("([a-z:_\\-]+)") - radius = 50 + radius = 25 end if found == nil then replace_node = "default:water_source" end + radius = tonumber(radius) + + replace_node = worldedit.normalize_nodename(replace_node) + + minetest.log("action", "Floodfill settings - node: " .. replace_node .. ", radius: " .. radius) local nodes_replaced = worldedit.floodfill(worldedit.pos1[name], radius, replace_node) worldedit.player_notify(name, nodes_replaced .. " replaced") - minetest.log("action", name .. "used floodfill at (" .. worldedit.pos1.x .. "," .. worldedit.pos1.y .. "," .. worldedit.pos1.z .. "), replacing " .. nodes_replaced .. " nodes") + minetest.log("action", name .. "used floodfill at (" .. worldedit.pos1[name].x .. "," .. worldedit.pos1[name].y .. "," .. worldedit.pos1[name].z .. "), replacing " .. nodes_replaced .. " nodes") end })