Update installation instructions - adopted from Wuzzy's notes.
[insidethebox/insidethebox_wuzzy.git] / mods / screwdriver / init.lua
blob673c1a44be30e920bca8492aa81d3bf223a12cfe
2 --[[
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,
19 MA 02111-1307 USA
21 ]]--
23 screwdriver = {}
25 local function nextrange(x, max)
26 x = x + 1
27 if x > max then
28 x = 0
29 end
30 return x
31 end
33 screwdriver.ROTATE_FACE = 1
34 screwdriver.ROTATE_AXIS = 2
35 screwdriver.disallow = function(pos, node, user, mode, new_param2)
36 return false
37 end
38 screwdriver.rotate_simple = function(pos, node, user, mode, new_param2)
39 if mode ~= screwdriver.ROTATE_FACE then
40 return false
41 end
42 end
44 -- Handles rotation
45 screwdriver.handler = function(itemstack, user, pointed_thing, mode, uses)
46 if pointed_thing.type ~= "node" then
47 return
48 end
50 local pos = pointed_thing.under
52 if not boxes.can_edit(user) then
53 return
54 end
55 if minetest.is_protected(pos, user:get_player_name()) then
56 minetest.record_protection_violation(pos, user:get_player_name())
57 return
58 end
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
64 return
65 end
66 -- Compute param2
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
75 end
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
87 return
88 elseif result == true then
89 should_rotate = false
90 end
91 else
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
97 return
98 end
100 if ndef.can_dig and not ndef.can_dig(pos, user) then
101 return
105 if should_rotate then
106 node.param2 = new_param2
107 minetest.swap_node(pos, node)
110 return itemstack
113 -- Screwdriver
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)
119 return itemstack
120 end,
121 on_place = function(itemstack, user, pointed_thing)
122 screwdriver.handler(itemstack, user, pointed_thing, screwdriver.ROTATE_AXIS, 200)
123 return itemstack
124 end,