196 lines
5.6 KiB
Lua
196 lines
5.6 KiB
Lua
|
-- param2 rotation table from:
|
||
|
-- https://forum.minetest.net/viewtopic.php?p=73195&sid=1d2d2e4e76ce2ef9c84646481a4b84bc#p73195
|
||
|
-- Axis * 4 + Rotation = Facedir
|
||
|
-- First in pair is axis
|
||
|
-- Second in pair is rotation
|
||
|
local raw_facedir = {
|
||
|
x = {
|
||
|
{{3, 0}, {3, 1}, {3, 2}, {3, 3}},
|
||
|
{{4, 0}, {4, 3}, {4, 2}, {4, 1}},
|
||
|
{{0, 0}, {1, 0}, {5, 2}, {2, 0}},
|
||
|
{{0, 1}, {1, 1}, {5, 3}, {2, 1}},
|
||
|
{{0, 2}, {1, 2}, {5, 0}, {2, 2}},
|
||
|
{{0, 3}, {1, 3}, {5, 1}, {2, 3}}
|
||
|
},
|
||
|
y = {
|
||
|
{{0, 0}, {0, 1}, {0, 2}, {0, 3}},
|
||
|
{{5, 0}, {5, 3}, {5, 2}, {5, 1}},
|
||
|
{{1, 0}, {3, 1}, {2, 2}, {4, 3}},
|
||
|
{{2, 0}, {4, 1}, {1, 2}, {3, 3}},
|
||
|
{{3, 0}, {2, 1}, {4, 2}, {1, 3}},
|
||
|
{{4, 0}, {1, 1}, {3, 2}, {2, 3}}
|
||
|
},
|
||
|
z = {
|
||
|
{{1, 0}, {1, 1}, {1, 2}, {1, 3}},
|
||
|
{{2, 0}, {2, 3}, {2, 2}, {2, 1}},
|
||
|
{{0, 0}, {4, 0}, {5, 0}, {3, 0}},
|
||
|
{{0, 1}, {4, 1}, {5, 1}, {3, 1}},
|
||
|
{{0, 2}, {4, 2}, {5, 2}, {3, 2}},
|
||
|
{{0, 3}, {4, 3}, {5, 3}, {3, 3}}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
local facedir_rot = {}
|
||
|
|
||
|
local function pair_to_param2(pair)
|
||
|
return pair[1] * 4 + pair[2]
|
||
|
end
|
||
|
|
||
|
for axis, raw_rot in pairs(raw_facedir) do
|
||
|
facedir_rot[axis] = {}
|
||
|
for j, pair_list in pairs(raw_rot) do
|
||
|
for i = 1, 4 do
|
||
|
local back_index = i - 1
|
||
|
if back_index == 0 then
|
||
|
back_index = 4
|
||
|
end
|
||
|
local next_index = i + 1
|
||
|
if next_index == 5 then
|
||
|
next_index = 1
|
||
|
end
|
||
|
local back = pair_to_param2(pair_list[back_index])
|
||
|
local next = pair_to_param2(pair_list[next_index])
|
||
|
local current = pair_to_param2(pair_list[i])
|
||
|
facedir_rot[axis][current] = {next, back}
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local raw_wallmounted = {
|
||
|
x = {4, 0, 5, 1},
|
||
|
y = {2, 4, 3, 5},
|
||
|
z = {3, 0, 2, 1},
|
||
|
}
|
||
|
|
||
|
local wallmounted_rot = {}
|
||
|
|
||
|
for axis, rots in pairs(raw_wallmounted) do
|
||
|
wallmounted_rot[axis] = {}
|
||
|
local param2s_unused = {
|
||
|
[0] = true, [1] = true, [2] = true,
|
||
|
[3] = true, [4] = true, [5] = true}
|
||
|
for i = 1, 4 do
|
||
|
local back_index = i - 1
|
||
|
if back_index == 0 then
|
||
|
back_index = 4
|
||
|
end
|
||
|
local next_index = i + 1
|
||
|
if next_index == 5 then
|
||
|
next_index = 1
|
||
|
end
|
||
|
local current = rots[i]
|
||
|
local back = rots[back_index]
|
||
|
local next = rots[next_index]
|
||
|
wallmounted_rot[axis][current] = {back, next}
|
||
|
param2s_unused[current] = nil
|
||
|
end
|
||
|
|
||
|
for param2, bool in pairs(param2s_unused) do
|
||
|
wallmounted_rot[axis][param2] = {param2, param2}
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function edit.rotate_param2(node, rot_vect)
|
||
|
local def = minetest.registered_items[node.name]
|
||
|
if not node.param2 or not def then return end
|
||
|
local paramtype2 = def.paramtype2
|
||
|
local is_wallmounted = paramtype2 == "wallmounted" or paramtype2 == "colorwallmounted"
|
||
|
local is_facedir = paramtype2 == "facedir" or paramtype2 == "colorfacedir"
|
||
|
local rot_table = is_facedir and facedir_rot or wallmounted_rot
|
||
|
if is_facedir or is_wallmounted then
|
||
|
local param2_rot = node.param2 % 32 -- Get first 5 bits
|
||
|
if is_wallmounted then
|
||
|
param2_rot = node.param2 % 8 -- Get first 3 bits
|
||
|
end
|
||
|
local param2_other = node.param2 - param2_rot
|
||
|
for axis, target_rot in pairs(rot_vect) do
|
||
|
if target_rot ~= 0 then
|
||
|
local direction = math.sign(target_rot)
|
||
|
for rot = direction, target_rot / (math.pi / 2), direction do
|
||
|
if target_rot > 0 then
|
||
|
param2_rot = rot_table[axis][param2_rot][1]
|
||
|
else
|
||
|
param2_rot = rot_table[axis][param2_rot][2]
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
node.param2 = param2_other + param2_rot
|
||
|
elseif paramtype2 == "degrotate" or paramtype2 == "colordegrotate" then
|
||
|
local param2_rot
|
||
|
local deg_per_unit
|
||
|
if paramtype2 == "degrotate" then
|
||
|
param2_rot = node.param2
|
||
|
deg_per_unit = 1.5
|
||
|
else
|
||
|
param2_rot = node.param2 % 32 -- Get first 5 bits
|
||
|
deg_per_unit = 15
|
||
|
end
|
||
|
local param2_other = node.param2 - param2_rot
|
||
|
local rot = param2_rot * deg_per_unit / 180 * math.pi
|
||
|
|
||
|
rot = rot + rot_vect.y
|
||
|
rot = rot % (math.pi * 2)
|
||
|
if rot < 0 then
|
||
|
rot = rot + math.pi * 2
|
||
|
end
|
||
|
|
||
|
param2_rot = math.round(rot / math.pi * 180 / deg_per_unit)
|
||
|
node.param2 = param2_other + param2_rot
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function screwdriver_run(player, pointed_thing, rotate_y)
|
||
|
if not edit.on_place_checks(player) then return end
|
||
|
if pointed_thing.type ~= "node" then return end
|
||
|
local pos = pointed_thing.under
|
||
|
local node = minetest.get_node(pos)
|
||
|
local def = minetest.registered_items[node.name]
|
||
|
if not def then return end
|
||
|
local rot = vector.new(0, 0, 0)
|
||
|
local paramtype2 = def.paramtype2
|
||
|
if paramtype2 == "degrotate" or paramtype2 == "colordegrotate" then
|
||
|
if rotate_y then
|
||
|
local deg = paramtype2 == "degrotate" and 1.5 or 15
|
||
|
rot.y = deg / 180 * math.pi
|
||
|
if player:get_player_control().aux1 then
|
||
|
rot.y = rot.y * 4
|
||
|
end
|
||
|
end
|
||
|
else
|
||
|
if rotate_y then
|
||
|
rot = vector.new(0, math.pi / 2, 0)
|
||
|
else
|
||
|
local player_pos = player:get_pos()
|
||
|
local diff = vector.subtract(player_pos, pos)
|
||
|
local abs_diff = vector.apply(diff, math.abs)
|
||
|
if abs_diff.x > abs_diff.z then
|
||
|
local sign = (diff.x > 0) and 1 or -1
|
||
|
rot = vector.new(0, 0, math.pi / 2 * sign)
|
||
|
else
|
||
|
local sign = (diff.z < 0) and 1 or -1
|
||
|
rot = vector.new(math.pi / 2 * sign, 0, 0)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
local old_node = table.copy(node)
|
||
|
edit.rotate_param2(node, rot)
|
||
|
if def.on_rotate then
|
||
|
def.on_rotate(pos, old_node, player, 1, node.param2)
|
||
|
end
|
||
|
minetest.swap_node(pos, node)
|
||
|
end
|
||
|
|
||
|
minetest.register_tool("edit:screwdriver", {
|
||
|
description = "Edit Screwdriver",
|
||
|
inventory_image = "edit_screwdriver.png",
|
||
|
on_use = function(itemstack, user, pointed_thing)
|
||
|
screwdriver_run(user, pointed_thing, true)
|
||
|
return itemstack
|
||
|
end,
|
||
|
on_place = function(itemstack, user, pointed_thing)
|
||
|
screwdriver_run(user, pointed_thing, false)
|
||
|
return itemstack
|
||
|
end,
|
||
|
})
|