local core = worldeditadditions_core local Vector3 = core.Vector3 --- -- @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. -- -- This is NOT NECESSARILY the number of nodes in the target region..... since not every node in the target region will support reorientation. function worldeditadditions.orient(pos1, pos2, rotlist) pos1, pos2 = Vector3.sort(pos1, pos2) --- 1: Compile the rotation list local rotlist_c = core.rotation.rotlist_compile(rotlist) --- 2: Fetch the nodes in the specified area local manip, area = worldedit.manip_helpers.init(pos1, pos2) local data = manip:get_data() local data_param2 = manip:get_param2_data() local stats = { count = 0 } local cache_nodeid_2_param2_type = {} local cache_orient = {} local param2_cache = {} -- TODO rewrite with ref https://github.com/12Me21/screwdriver2/blob/master/init.lua#L75-L79 'cause this doesn't account for rotation properly for i in area:iterp(pos1, pos2) do -- nodeid = data[i] local param2_type = "none" if cache_nodeid_2_param2_type[data[i]] == nil then local node_name = minetest.get_name_from_content_id(data[i]) local ndef = minetest.registered_nodes[node_name] if type(ndef.paramtype2) ~= nil then param2_type = ndef.paramtype2 end cache_nodeid_2_param2_type[data[i]] = param2_type print("DEBUG orient CACHE:PARAM2 MISS node", node_name, "param2_type", param2_type) else param2_type = cache_nodeid_2_param2_type[data[i]] end print("DEBUG orient NODEID", data[i], "PARAM2_TYPE", param2_type) if param2_type ~= "none" then 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 print("DEBUG orient KEY", key, "BEFORE", data_param2[i], "AFTER", cache_orient[key]) data_param2[i] = cache_orient[key] stats.count = stats.count + 1 end end manip:set_param2_data(data_param2) manip:write_to_map(false) manip:update_map() --- 8: Return return true, stats end