Skip to content

support every paramtype2 #662

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 14, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 71 additions & 27 deletions technic/tools/sonic_screwdriver.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,6 @@ technic.register_power_tool("technic:sonic_screwdriver", sonic_screwdriver_max_c
local ROTATE_FACE = 1
local ROTATE_AXIS = 2

local function nextrange(x, max)
x = x + 1
if x > max then
x = 0
end
return x
end

-- Handles rotation
local function screwdriver_handler(itemstack, user, pointed_thing, mode)
if pointed_thing.type ~= "node" then
Expand All @@ -31,16 +23,80 @@ local function screwdriver_handler(itemstack, user, pointed_thing, mode)

local node = minetest.get_node(pos)
local ndef = minetest.registered_nodes[node.name]
if not ndef or not ndef.paramtype2 == "facedir" or
(ndef.drawtype == "nodebox" and
not ndef.node_box.type == "fixed") or
node.param2 == nil then
return
end

if not ndef then return end

local paramtype2 = ndef.paramtype2

-- contrary to the default screwdriver, do not check for can_dig, to allow rotating machines with CLU's in them
-- this is consistent with the previous sonic screwdriver

-- Set param2
local new_param2
local param2 = node.param2

local dirs_per_axis = 4

local dir_components = {
-- 2^5, 5 bits
facedir = 32,
colorfacedir = 32,
colordegrotate = 32,

-- 2^2, 2 bits
["4dir"] = 4, -- lua doesn't like it when vars start with a digit
color4dir = 4,
}

local dir_component = dir_components[paramtype2]

local floor = math.floor
-- non-direction data is preserved whether it be color or otherwise
if (paramtype2 == "facedir") or (paramtype2 == "colorfacedir") then
local aux = floor(param2 / dir_component)
local dir = param2 % dir_component

if mode == ROTATE_FACE then
dir = (floor(param2 / dirs_per_axis)) * dirs_per_axis + ((dir + 1) % dirs_per_axis)
elseif mode == ROTATE_AXIS then
dir = ((floor(param2 / dirs_per_axis) + 1) * dirs_per_axis) % 24
end

new_param2 = aux * dir_component + dir
elseif (paramtype2 == "4dir") or (paramtype2 == "color4dir") then
local aux = floor(param2 / dir_component)
local dir = param2 % dir_component

if mode == ROTATE_FACE then
dir = (dir + 1) % dirs_per_axis
elseif mode == ROTATE_AXIS then
dir = 0
end

new_param2 = aux * dir_component + dir
elseif (paramtype2 == "degrotate") then
if mode == ROTATE_FACE then
new_param2 = param2 + 1
elseif mode == ROTATE_AXIS then
new_param2 = param2 + 20
end
new_param2 = new_param2 % 240
elseif (paramtype2 == "colordegrotate") then
local aux = floor(param2 / dir_component)
local rotation = param2 % dir_component

if mode == ROTATE_FACE then
rotation = rotation + 1
elseif mode == ROTATE_AXIS then
rotation = rotation + 4
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I use paramtype2 = "degrotate", in the nodedef of "default:aspen_sapling" (nodes.lua), the rotation oddly jumps in this case. There is no such anomaly with paramtype2 = "degrotate",.
Is it because you're using modulo 32 in L94, but modulo 24 in L101?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

describe the jump
(%32 is bitwise extraction, %24 is rotation modulo)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry. I meant that colordegorate jumps oddly whereas degrotate works well.
It turns out this code is not flawed but my perception. It simply turned too far to notice at a stationary viewing position. When following the node around in its rotation, there is no such "glitch" or "jump".
Resolved.

end
rotation = rotation % 24

new_param2 = aux * dir_component + rotation
else
return
end
Copy link
Member

@SmallJoker SmallJoker May 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idea: You could move this code up such that a final else case could be used for return. It would effectively deduplicate the lines L38-47.

Admittedly this code does not look great (magic numbers and many different cases) but I don't see much that could be done to improve it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be done


local meta = technic.get_stack_meta(itemstack)
local charge = meta:get_int("technic:charge")
if charge < 100 then
Expand All @@ -49,19 +105,7 @@ local function screwdriver_handler(itemstack, user, pointed_thing, mode)

minetest.sound_play("technic_sonic_screwdriver", {pos = pos, gain = 0.3, max_hear_distance = 10})

-- Set param2
local rotationPart = node.param2 % 32 -- get first 4 bits
local preservePart = node.param2 - rotationPart

local axisdir = math.floor(rotationPart / 4)
local rotation = rotationPart - axisdir * 4
if mode == ROTATE_FACE then
rotationPart = axisdir * 4 + nextrange(rotation, 3)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

luacheck is yet unhappy technic/tools/sonic_screwdriver.lua:11:16: unused function nextrange
To fix that, you could ignore the warning (I hope it's the correct code) or remove the function.

-- luacheck: push ignore 211
local function foobar()
end
-- luacheck: pop

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the function

done: 150e738

elseif mode == ROTATE_AXIS then
rotationPart = nextrange(axisdir, 5) * 4
end

node.param2 = preservePart + rotationPart
node.param2 = new_param2
minetest.swap_node(pos, node)

if not technic.creative_mode then
Expand Down