mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-12-24 04:25:01 +00:00
It doesn't have any syntax errors, so I guess there's only one way to find out if it actually works :P
This commit is contained in:
commit
02b54e6215
7 changed files with 135 additions and 0 deletions
0
modpack.txt
Normal file
0
modpack.txt
Normal file
1
worldeditadditions/depends.txt
Normal file
1
worldeditadditions/depends.txt
Normal file
|
@ -0,0 +1 @@
|
|||
worldedit
|
66
worldeditadditions/floodfill.lua
Normal file
66
worldeditadditions/floodfill.lua
Normal file
|
@ -0,0 +1,66 @@
|
|||
--- 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
|
8
worldeditadditions/init.lua
Normal file
8
worldeditadditions/init.lua
Normal file
|
@ -0,0 +1,8 @@
|
|||
--- WorldEditAdditions
|
||||
-- @module worldeditadditions
|
||||
-- @release 0.1
|
||||
-- @copyright 2018 Starbeamrainbowlabs
|
||||
-- @license Mozilla Public License, 2.0
|
||||
-- @author Starbeamrainbowlabs
|
||||
|
||||
worldedit.floodfill = require "floodfill"
|
31
worldeditadditions/queue.lua
Normal file
31
worldeditadditions/queue.lua
Normal file
|
@ -0,0 +1,31 @@
|
|||
--- 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
|
1
worldeditadditions_commands/depends.txt
Normal file
1
worldeditadditions_commands/depends.txt
Normal file
|
@ -0,0 +1 @@
|
|||
worldeditadditions
|
28
worldeditadditions_commands/init.lua
Normal file
28
worldeditadditions_commands/init.lua
Normal file
|
@ -0,0 +1,28 @@
|
|||
--- WorldEditAdditions-ChatCommands
|
||||
-- @module worldeditadditions_commands
|
||||
-- @release 0.1
|
||||
-- @copyright 2018 Starbeamrainbowlabs
|
||||
-- @license Mozilla Public License, 2.0
|
||||
-- @author Starbeamrainbowlabs
|
||||
|
||||
minetest.register_chatcommand("/floodfill", {
|
||||
params = "<replace_node> [<radius>]",
|
||||
description = "Floods all connected nodes of the same type starting at pos1 with <replace_node>, in a box-shape with a radius of <radius>, which defaults to 50.",
|
||||
privs = { worldedit = true },
|
||||
-- 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
|
||||
end
|
||||
if found == nil then
|
||||
replace_node = "default:water_source"
|
||||
end
|
||||
|
||||
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")
|
||||
end
|
||||
})
|
Loading…
Reference in a new issue