mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-08-21 05:54:06 +02:00
67 lines
1.9 KiB
Lua
67 lines
1.9 KiB
Lua
|
--- Flood-fill command for complex lakes etc.
|
||
|
-- @module worldeditadditions.floodfill
|
||
|
|
||
|
local Queue = require "queue"
|
||
|
|
||
|
local function 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
|
||
|
pos1, pos2 = worldedit.sort_pos(pos1, pos2) -- Just in case
|
||
|
|
||
|
-- Fetch the nodes in the specified area
|
||
|
local manip, area = worldedit.manip_helpers.init()
|
||
|
local data = manip:get_data()
|
||
|
|
||
|
-- Setup for the floodfill operation itself
|
||
|
local start_pos_index = area:index(start_pos.x, start_pos.y, start_pos.z);
|
||
|
|
||
|
local search_id = data[start_pos_index]
|
||
|
local replace_id = minetest.get_content_id(replace_node)
|
||
|
|
||
|
local count = 0
|
||
|
local remaining_nodes = Queue.new()
|
||
|
Queue.enqueue(remaining_nodes, start_pos_index)
|
||
|
|
||
|
-- Do the floodfill
|
||
|
while Queue.is_empty(remaining_nodes) == false do
|
||
|
local cur = Queue.dequeue(remaining_nodes)
|
||
|
|
||
|
-- TODO: Check distance from start_pos
|
||
|
|
||
|
-- Replace this node
|
||
|
data[cur] = replace_id
|
||
|
count = count + 1
|
||
|
|
||
|
-- Check all the nearby nodes
|
||
|
-- We don't need to go upwards here, since we're filling in lake-style
|
||
|
if data[cur + 1] == search_id then -- +X
|
||
|
Queue.enqueue(remaining_nodes, cur + 1)
|
||
|
end
|
||
|
if data[cur - 1] == search_id then -- -X
|
||
|
Queue.enqueue(remaining_nodes, cur - 1)
|
||
|
end
|
||
|
if data[cur + area.zstride] == search_id then -- +Z
|
||
|
Queue.enqueue(remaining_nodes, cur + area.zstride)
|
||
|
end
|
||
|
if data[cur - area.zstride] == search_id then -- -Z
|
||
|
Queue.enqueue(remaining_nodes, cur - area.zstride)
|
||
|
end
|
||
|
if data[cur - area.ystride] == search_id then -- -Y
|
||
|
Queue.enqueue(remaining_nodes, cur - area.ystride)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- Save the modified nodes back to disk & return
|
||
|
worldedit.manip_helpers.finish(manip, data)
|
||
|
|
||
|
return count
|
||
|
end
|
||
|
|
||
|
|
||
|
return floodfill
|