mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-12-24 12:35:01 +00:00
87 lines
3.4 KiB
Lua
87 lines
3.4 KiB
Lua
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
|