mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-12-23 03:55:01 +00:00
92 lines
3.7 KiB
Lua
92 lines
3.7 KiB
Lua
local wea_c = worldeditadditions_core
|
|
local Vector3 = wea_c.Vector3
|
|
|
|
-- ███████ ██████ ██ ██████ █████ ██
|
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██
|
|
-- ███████ ██████ ██ ██████ ███████ ██
|
|
-- ██ ██ ██ ██ ██ ██ ██ ██
|
|
-- ███████ ██ ██ ██ ██ ██ ██ ███████
|
|
--
|
|
-- ███████ ██████ ██ ██ █████ ██████ ███████
|
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
|
-- ███████ ██ ██ ██ ██ ███████ ██████ █████
|
|
-- ██ ██ ▄▄ ██ ██ ██ ██ ██ ██ ██ ██
|
|
-- ███████ ██████ ██████ ██ ██ ██ ██ ███████
|
|
-- ▀▀
|
|
|
|
--- Creates a square spiral that fills the defined region.
|
|
-- @param pos1 Vector3 The 1st position of the defined region.
|
|
-- @param pos2 Vector3 The 2nd position of the defined region.
|
|
-- @param target_node Vector3 The *normalised* name of the node to use to build the square spiral with.
|
|
-- @param interval number The distance between the walls of the spiral.
|
|
-- @param acceleration=0 number Increate the interval by this number every time we hit a corner of the square spiral.
|
|
-- @returns bool,number|string A success boolean value, followed by either the number of the nodes set or an error message string.
|
|
function worldeditadditions.spiral_square(pos1, pos2, target_node, interval, acceleration)
|
|
if not acceleration then acceleration = 0 end
|
|
|
|
pos1, pos2 = Vector3.sort(pos1, pos2)
|
|
local volume = pos2:subtract(pos1)
|
|
local volume_half = volume:divide(2)
|
|
|
|
-- print("DEBUG:spiral_square | pos1: "..pos1..", pos2: "..pos2..", target_node: "..target_node, "interval:"..interval..", acceleration: "..acceleration)
|
|
|
|
|
|
-- Fetch the nodes in the specified area
|
|
local manip, area = worldedit.manip_helpers.init(pos1, pos2)
|
|
local data = manip:get_data()
|
|
|
|
local node_id = minetest.get_content_id(target_node)
|
|
|
|
local count = 0 -- The number of nodes replaced
|
|
|
|
local centre = pos2:subtract(pos1):floor():divide(2):add(pos1)
|
|
|
|
local pos_current = centre:clone():floor()
|
|
local side_length = 0
|
|
local direction = Vector3.new(1, 0, 0)
|
|
local side_length_max = interval + 1
|
|
local sides_complete = 0
|
|
-- local sides_acc = 0
|
|
|
|
while pos_current:is_contained(pos1, pos2) do
|
|
|
|
for y = pos2.y, pos1.y, -1 do
|
|
data[area:index(pos_current.x, y, pos_current.z)] = node_id
|
|
count = count + 1
|
|
end
|
|
|
|
pos_current = pos_current:add(direction)
|
|
side_length = side_length + 1
|
|
|
|
-- print("DEBUG cpos", pos_current, "side_length", side_length, "side_length_max", side_length_max, "direction", direction)
|
|
|
|
if side_length >= side_length_max then
|
|
sides_complete = sides_complete + 1
|
|
-- sides_acc = sides_acc + 1
|
|
if sides_complete % 2 == 0 then
|
|
-- sides_acc = 0
|
|
side_length_max = side_length_max + interval + acceleration + 1
|
|
end
|
|
side_length = 0
|
|
|
|
if direction.x == 0 and direction.z == 1 then
|
|
direction.x = 1
|
|
direction.z = 0
|
|
elseif direction.x == 1 and direction.z == 0 then
|
|
direction.x = 0
|
|
direction.z = -1
|
|
elseif direction.x == 0 and direction.z == -1 then
|
|
direction.x = -1
|
|
direction.z = 0
|
|
else
|
|
direction.x = 0
|
|
direction.z = 1
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Save the modified nodes back to disk & return
|
|
worldedit.manip_helpers.finish(manip, data)
|
|
|
|
return true, count
|
|
end
|