From 85e342c08c666ba2fb742f4c135efd7f435bf6b0 Mon Sep 17 00:00:00 2001 From: The4codeblocks <72419529+The4codeblocks@users.noreply.github.com> Date: Wed, 14 May 2025 12:52:22 -0500 Subject: [PATCH] Sonic Screwdriver: Support every paramtype2 (#662) --- technic/tools/sonic_screwdriver.lua | 98 +++++++++++++++++++++-------- 1 file changed, 71 insertions(+), 27 deletions(-) diff --git a/technic/tools/sonic_screwdriver.lua b/technic/tools/sonic_screwdriver.lua index ceb52a1..9886346 100644 --- a/technic/tools/sonic_screwdriver.lua +++ b/technic/tools/sonic_screwdriver.lua @@ -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 @@ -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 + end + rotation = rotation % 24 + + new_param2 = aux * dir_component + rotation + else + return + end + local meta = technic.get_stack_meta(itemstack) local charge = meta:get_int("technic:charge") if charge < 100 then @@ -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) - 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