2024-06-04 23:49:41 +02:00
local core = worldeditadditions_core
local Vector3 = core.Vector3
2024-05-25 15:45:56 +02:00
---
-- @module worldeditadditions
-- ██████ ██████ ██ ███████ ███ ██ ████████
-- ██ ██ ██ ██ ██ ██ ████ ██ ██
-- ██ ██ ██████ ██ █████ ██ ██ ██ ██
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ██████ ██ ██ ██ ███████ ██ ████ ██
--- Re-orients the nodes in the given region around a given origin point using a set of rotations.
-- TODO Learn quaternions and make this more effiient.
-- @param pos1 Vector3 Position 1 of the region to orient nodes in.
-- @param pos2 Vector3 Position 2 of the region to orient nodes in.
-- @param rotlist table<{axis: string, rad: number}> The list of rotations. Rotations will be processed in order. Each rotation is a table with a SINGLE axis as a string (x, y, z, -x, -y, or -z; the axis parameter), and an amount in radians to rotate by (the rad parameter).
-- @returns bool,string|table<{changed: number}> A success boolean (true == success; false == failure), followed by either an error message as a string if success == false or a table of statistics if success == true.
--
-- Currently the only parameter in the statistics table is changed, which is a number representing the number of nodes that were rotated.
--
2024-06-04 23:49:41 +02:00
-- This is NOT NECESSARILY the number of nodes in the target region..... since not every node in the target region will support reorientation.
2024-05-25 15:45:56 +02:00
function worldeditadditions . orient ( pos1 , pos2 , rotlist )
pos1 , pos2 = Vector3.sort ( pos1 , pos2 )
--- 1: Compile the rotation list
2024-06-04 23:49:41 +02:00
local rotlist_c = core.rotation . rotlist_compile ( rotlist )
2024-05-25 15:45:56 +02:00
--- 2: Fetch the nodes in the specified area
local manip , area = worldedit.manip_helpers . init ( pos1 , pos2 )
local data = manip : get_data ( )
2024-06-04 23:49:41 +02:00
local data_param2 = manip : get_param2_data ( )
2024-05-25 15:45:56 +02:00
local stats = {
count = 0
}
2024-06-04 23:49:41 +02:00
local cache_nodeid_2_param2_type = { }
local cache_orient = { }
2024-05-25 15:45:56 +02:00
local param2_cache = { }
2024-08-18 21:59:16 +02:00
-- TODO rewrite with ref https://github.com/12Me21/screwdriver2/blob/master/init.lua#L75-L79 'cause this doesn't account for rotation properly
2024-05-25 15:45:56 +02:00
for i in area : iterp ( pos1 , pos2 ) do
2024-06-04 23:49:41 +02:00
-- nodeid = data[i]
local param2_type = " none "
if cache_nodeid_2_param2_type [ data [ i ] ] == nil then
2024-06-05 00:07:05 +02:00
local node_name = minetest.get_name_from_content_id ( data [ i ] )
local ndef = minetest.registered_nodes [ node_name ]
2024-06-04 23:49:41 +02:00
if type ( ndef.paramtype2 ) ~= nil then
param2_type = ndef.paramtype2
end
cache_nodeid_2_param2_type [ data [ i ] ] = param2_type
2024-06-05 00:07:05 +02:00
print ( " DEBUG orient CACHE:PARAM2 MISS node " , node_name , " param2_type " , param2_type )
2024-06-04 23:49:41 +02:00
else
param2_type = cache_nodeid_2_param2_type [ data [ i ] ]
end
2024-05-25 15:45:56 +02:00
2024-06-05 00:07:05 +02:00
print ( " DEBUG orient NODEID " , data [ i ] , " PARAM2_TYPE " , param2_type )
if param2_type ~= " none " then
2024-06-04 23:49:41 +02:00
local key = param2_type .. " | " .. data_param2 [ i ]
if cache_orient [ key ] == nil then
cache_orient [ key ] = core.param2 . orient (
data_param2 [ i ] ,
param2_type ,
rotlist_c
)
end
2024-06-05 00:07:05 +02:00
print ( " DEBUG orient KEY " , key , " BEFORE " , data_param2 [ i ] , " AFTER " , cache_orient [ key ] )
2024-06-04 23:49:41 +02:00
data_param2 [ i ] = cache_orient [ key ]
stats.count = stats.count + 1
end
2024-05-25 15:45:56 +02:00
end
2024-06-04 23:49:41 +02:00
manip : set_param2_data ( data_param2 )
manip : write_to_map ( false )
manip : update_map ( )
2024-05-25 15:45:56 +02:00
--- 8: Return
return true , stats
end