Skip to content

Commit 5857337

Browse files
committed
Use game/mod-provided screwdriver handlers if present
1 parent a68a3a0 commit 5857337

File tree

2 files changed

+84
-36
lines changed

2 files changed

+84
-36
lines changed

technic/mod.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
name = technic
22
depends = pipeworks, technic_worldgen, basic_materials
3-
optional_depends = mcl_core, mcl_sounds, default, bucket, mesecons, mesecons_mvps, digilines, digiline_remote, unified_inventory, dye, craftguide, i3, mtt, vizlib, moreores, mcl_buckets, mcl_explosions, mcl_craftguide
3+
optional_depends = mcl_core, mcl_sounds, default, bucket, mesecons, mesecons_mvps, digilines, digiline_remote, unified_inventory, dye, craftguide, i3, mtt, vizlib, moreores, mcl_buckets, mcl_explosions, mcl_craftguide, screwdriver

technic/tools/sonic_screwdriver.lua

+83-35
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,43 @@ local sonic_screwdriver_max_charge = 15000
33
local S = technic.getter
44
local mat = technic.materials
55

6-
-- screwdriver handler code reused from minetest/minetest_game screwdriver @a9ac480
7-
local ROTATE_FACE = 1
8-
local ROTATE_AXIS = 2
9-
10-
local function nextrange(x, max)
11-
x = x + 1
12-
if x > max then
13-
x = 0
6+
local screwdriver = screwdriver or nil
7+
if not screwdriver then
8+
local function nextrange(x, max)
9+
x = x + 1
10+
if x > max then
11+
x = 0
12+
end
13+
return x
1414
end
15-
return x
15+
16+
-- Simple and hacky rotation script, assumed facedir
17+
local function simple_rotate(pos, node, mode)
18+
local rotationPart = node.param2 % 32 -- get first 4 bits
19+
local preservePart = node.param2 - rotationPart
20+
21+
local axisdir = math.floor(rotationPart / 4)
22+
local rotation = rotationPart - axisdir * 4
23+
if mode == screwdriver.ROTATE_FACE then
24+
rotationPart = axisdir * 4 + nextrange(rotation, 3)
25+
elseif mode == screwdriver.ROTATE_AXIS then
26+
rotationPart = nextrange(axisdir, 5) * 4
27+
end
28+
29+
return preservePart + rotationPart
30+
end
31+
32+
-- local use only
33+
screwdriver = {
34+
ROTATE_FACE = 1,
35+
ROTATE_AXIS = 2,
36+
37+
rotate = setmetatable({}, {
38+
__index = function ()
39+
return simple_rotate
40+
end
41+
})
42+
}
1643
end
1744

1845
-- Handles rotation
@@ -21,45 +48,66 @@ local function screwdriver_handler(itemstack, user, pointed_thing, mode)
2148
return
2249
end
2350

51+
if technic.get_RE_charge(itemstack) < 100 then
52+
return itemstack
53+
end
54+
2455
local pos = pointed_thing.under
56+
local player_name = user and user:get_player_name() or ""
2557

26-
if minetest.is_protected(pos, user:get_player_name()) then
27-
minetest.record_protection_violation(pos, user:get_player_name())
58+
if minetest.is_protected(pos, player_name) then
59+
minetest.record_protection_violation(pos, player_name)
2860
return
2961
end
3062

3163
local node = minetest.get_node(pos)
3264
local ndef = minetest.registered_nodes[node.name]
33-
if not ndef or ndef.paramtype2 ~= "facedir" or
34-
(ndef.drawtype == "nodebox" and
35-
ndef.node_box.type ~= "fixed") or
36-
node.param2 == nil then
37-
return
65+
if not ndef then
66+
return itemstack
67+
end
68+
-- can we rotate this paramtype2?
69+
local fn = screwdriver.rotate[ndef.paramtype2]
70+
if not fn and not ndef.on_rotate then
71+
return itemstack
72+
end
73+
74+
local should_rotate = true
75+
local new_param2
76+
if fn then
77+
new_param2 = fn(pos, node, mode)
78+
if not new_param2 then
79+
-- rotation refused
80+
return itemstack
81+
end
82+
else
83+
new_param2 = node.param2
3884
end
3985

86+
-- Node provides a handler, so let the handler decide instead if the node can be rotated
4087
-- contrary to the default screwdriver, do not check for can_dig, to allow rotating machines with CLU's in them
4188
-- this is consistent with the previous sonic screwdriver
42-
43-
if not technic.use_RE_charge(itemstack, 100) then
44-
return
89+
if ndef.on_rotate then
90+
-- Copy pos and node because callback can modify it
91+
local result = ndef.on_rotate(vector.new(pos),
92+
{name = node.name, param1 = node.param1, param2 = node.param2},
93+
user, mode, new_param2)
94+
if result == false then -- Disallow rotation
95+
return itemstack
96+
elseif result == true then
97+
should_rotate = false
98+
end
99+
elseif ndef.on_rotate == false then
100+
return itemstack
45101
end
46102

47-
minetest.sound_play("technic_sonic_screwdriver", {pos = pos, gain = 0.3, max_hear_distance = 10}, true)
48-
49-
-- Set param2
50-
local rotationPart = node.param2 % 32 -- get first 4 bits
51-
local preservePart = node.param2 - rotationPart
52-
53-
local axisdir = math.floor(rotationPart / 4)
54-
local rotation = rotationPart - axisdir * 4
55-
if mode == ROTATE_FACE then
56-
rotationPart = axisdir * 4 + nextrange(rotation, 3)
57-
elseif mode == ROTATE_AXIS then
58-
rotationPart = nextrange(axisdir, 5) * 4
103+
if should_rotate and new_param2 ~= node.param2 then
104+
node.param2 = new_param2
105+
minetest.swap_node(pos, node)
106+
minetest.check_for_falling(pos)
107+
minetest.sound_play("technic_sonic_screwdriver", {pos = pos, gain = 0.3, max_hear_distance = 10}, true)
59108
end
60109

61-
node.param2 = preservePart + rotationPart
62-
minetest.swap_node(pos, node)
110+
technic.use_RE_charge(itemstack, 100)
63111

64112
return itemstack
65113
end
@@ -69,10 +117,10 @@ technic.register_power_tool("technic:sonic_screwdriver", {
69117
inventory_image = "technic_sonic_screwdriver.png",
70118
max_charge = sonic_screwdriver_max_charge,
71119
on_use = function(itemstack, user, pointed_thing)
72-
return screwdriver_handler(itemstack, user, pointed_thing, ROTATE_FACE)
120+
return screwdriver_handler(itemstack, user, pointed_thing, screwdriver.ROTATE_FACE)
73121
end,
74122
on_place = function(itemstack, user, pointed_thing)
75-
return screwdriver_handler(itemstack, user, pointed_thing, ROTATE_AXIS)
123+
return screwdriver_handler(itemstack, user, pointed_thing, screwdriver.ROTATE_AXIS)
76124
end,
77125
})
78126

0 commit comments

Comments
 (0)