@@ -3,16 +3,43 @@ local sonic_screwdriver_max_charge = 15000
33local S = technic .getter
44local 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+ }
1643end
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
65113end
@@ -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