From ad789d500a9518ad03f8870496d00738144af026 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Sat, 30 Oct 2021 02:46:25 +0100 Subject: [PATCH] Implement spiral square, but it's untested. It would also be awesome to customise the directional plane upon which the spiral is generated. It might actually be possible without melting my brain I think.... Looking at http://www.mathematische-basteleien.de/spiral.htm it should be possible to go this for circles too. But there's 1 particular function in Vector2.js that we need to port to Vector3.lua that we haven't yet which we'd need for that..... --- worldeditadditions/lib/spiral_square.lua | 83 ++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 worldeditadditions/lib/spiral_square.lua diff --git a/worldeditadditions/lib/spiral_square.lua b/worldeditadditions/lib/spiral_square.lua new file mode 100644 index 0000000..aa0b2fa --- /dev/null +++ b/worldeditadditions/lib/spiral_square.lua @@ -0,0 +1,83 @@ +local wea = worldeditadditions +local Vector3 = wea.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) + + + -- 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() + + local pos_current = centre:clone() + local pos_corner_last = pos_current:clone() + local side_length = 0 + local direction = Vector3.new(1, 0, 0) + local side_length_max = interval + + 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 + + if side_length > side_length_max then + side_length_max = side_length_max + interval + acceleration + + 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