4 screwdriver - Copyright (C) RealBadAngel, minetest developers
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public License
8 as published by the Free Software Foundation; either version 2.1
9 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25 local function nextrange(x
, max)
33 screwdriver
.ROTATE_FACE
= 1
34 screwdriver
.ROTATE_AXIS
= 2
35 screwdriver
.disallow
= function(pos
, node
, user
, mode
, new_param2
)
38 screwdriver
.rotate_simple
= function(pos
, node
, user
, mode
, new_param2
)
39 if mode
~= screwdriver
.ROTATE_FACE
then
45 screwdriver
.handler
= function(itemstack
, user
, pointed_thing
, mode
, uses
)
46 if pointed_thing
.type ~= "node" then
50 local pos
= pointed_thing
.under
52 if not boxes
.can_edit(user
) then
55 if minetest
.is_protected(pos
, user
:get_player_name()) then
56 minetest
.record_protection_violation(pos
, user
:get_player_name())
60 local node
= minetest
.get_node(pos
)
61 local ndef
= minetest
.registered_nodes
[node
.name
]
62 -- verify node is facedir (expected to be rotatable)
63 if not ndef
or ndef
.paramtype2
~= "facedir" then
67 local rotationPart
= node
.param2
% 32 -- get first 4 bits
68 local preservePart
= node
.param2
- rotationPart
69 local axisdir
= math
.floor(rotationPart
/ 4)
70 local rotation
= rotationPart
- axisdir
* 4
71 if mode
== screwdriver
.ROTATE_FACE
then
72 rotationPart
= axisdir
* 4 + nextrange(rotation
, 3)
73 elseif mode
== screwdriver
.ROTATE_AXIS
then
74 rotationPart
= nextrange(axisdir
, 5) * 4
77 local new_param2
= preservePart
+ rotationPart
78 local should_rotate
= true
80 if ndef
and ndef
.on_rotate
then
81 -- Node provides a handler, so let the handler decide instead if the node can be rotated
82 -- Copy pos and node because callback can modify it
83 local result
= ndef
.on_rotate(vector
.new(pos
),
84 {name
= node
.name
, param1
= node
.param1
, param2
= node
.param2
},
85 user
, mode
, new_param2
)
86 if result
== false then -- Disallow rotation
88 elseif result
== true then
92 if not ndef
or not ndef
.paramtype2
== "facedir" or
93 ndef
.on_rotate
== false or
94 (ndef
.drawtype
== "nodebox" and
95 not ndef
.node_box
.type == "fixed") or
96 node
.param2
== nil then
100 if ndef
.can_dig
and not ndef
.can_dig(pos
, user
) then
105 if should_rotate
then
106 node
.param2
= new_param2
107 minetest
.swap_node(pos
, node
)
114 minetest
.register_tool("screwdriver:screwdriver", {
115 description
= "Screwdriver\nLeft-click rotates face\nRight-click rotates axis",
116 inventory_image
= "screwdriver.png",
117 on_use
= function(itemstack
, user
, pointed_thing
)
118 screwdriver
.handler(itemstack
, user
, pointed_thing
, screwdriver
.ROTATE_FACE
, 200)
121 on_place
= function(itemstack
, user
, pointed_thing
)
122 screwdriver
.handler(itemstack
, user
, pointed_thing
, screwdriver
.ROTATE_AXIS
, 200)