Skip to content

Commit 64fdb49

Browse files
committedDec 11, 2013
Rework screwdriver and add protection support
1 parent 47a49ec commit 64fdb49

File tree

2 files changed

+142
-187
lines changed

2 files changed

+142
-187
lines changed
 

‎mods/screwdriver/depends.txt

-1
This file was deleted.

‎mods/screwdriver/init.lua

+142-186
Original file line numberDiff line numberDiff line change
@@ -1,206 +1,162 @@
1-
minetest.register_tool("screwdriver:screwdriver", {
2-
description = "Screwdriver",
3-
inventory_image = "screwdriver.png",
4-
on_use = function(itemstack, user, pointed_thing)
5-
screwdriver_handler(itemstack,user,pointed_thing)
6-
return itemstack
7-
end,
8-
})
9-
10-
for i=1,4,1 do
11-
minetest.register_tool("screwdriver:screwdriver"..i, {
12-
description = "Screwdriver in Mode "..i,
13-
inventory_image = "screwdriver.png^tool_mode"..i..".png",
14-
wield_image = "screwdriver.png",
15-
groups = {not_in_creative_inventory=1},
16-
on_use = function(itemstack, user, pointed_thing)
17-
screwdriver_handler(itemstack,user,pointed_thing)
18-
return itemstack
19-
end,
20-
})
21-
end
22-
faces_table=
23-
{
24-
--look dir +X +Y +Z -Z -Y -X
25-
2 , 0 , 4 , 5 , 1 , 3 , -- rotate around y+ 0 - 3
26-
4 , 0 , 3 , 2 , 1 , 5 ,
27-
3 , 0 , 5 , 4 , 1 , 2 ,
28-
5 , 0 , 2 , 3 , 1 , 4 ,
291

30-
2 , 5 , 0 , 1 , 4 , 3 , -- rotate around z+ 4 - 7
31-
4 , 2 , 0 , 1 , 3 , 5 ,
32-
3 , 4 , 0 , 1 , 5 , 2 ,
33-
5 , 3 , 0 , 1 , 2 , 4 ,
2+
local mode_text = {
3+
{"Change rotation, Don't change axisdir."},
4+
{"Keep choosen face in front then rotate it."},
5+
{"Change axis dir, Reset rotation."},
6+
{"Bring top in front then rotate it."},
7+
}
348

35-
2 , 4 , 1 , 0 , 5 , 3 , -- rotate around z- 8 - 11
36-
4 , 3 , 1 , 0 , 2 , 5 ,
37-
3 , 5 , 1 , 0 , 4 , 2 ,
38-
5 , 2 , 1 , 0 , 3 , 4 ,
9+
local opposite_faces = {
10+
[0] = 5,
11+
[1] = 2,
12+
[2] = 1,
13+
[3] = 4,
14+
[4] = 3,
15+
[5] = 0,
16+
}
3917

40-
0 , 3 , 4 , 5 , 2 , 1 , -- rotate around x+ 12 - 15
41-
0 , 5 , 3 , 2 , 4 , 1 ,
42-
0 , 2 , 5 , 4 , 3 , 1 ,
43-
0 , 4 , 2 , 3 , 5 , 1 ,
18+
local function screwdriver_setmode(user,itemstack)
19+
local player_name = user:get_player_name()
20+
local item = itemstack:to_table()
21+
local mode = tonumber(itemstack:get_metadata())
22+
if not mode then
23+
minetest.chat_send_player(player_name, "Hold shift and use to change screwdriwer modes.")
24+
mode = 0
25+
end
26+
mode = mode + 1
27+
if mode == 5 then
28+
mode = 1
29+
end
30+
minetest.chat_send_player(player_name, "Screwdriver mode : "..mode.." - "..mode_text[mode][1] )
31+
itemstack:set_name("screwdriver:screwdriver"..mode)
32+
itemstack:set_metadata(mode)
33+
return itemstack
34+
end
4435

45-
1 , 2 , 4 , 5 , 3 , 0 , -- rotate around x- 16 - 19
46-
1 , 4 , 3 , 2 , 5 , 0 ,
47-
1 , 3 , 5 , 4 , 2 , 0 ,
48-
1 , 5 , 2 , 3 , 4 , 0 ,
36+
local function get_node_face(pointed_thing)
37+
local ax, ay, az = pointed_thing.above.x, pointed_thing.above.y, pointed_thing.above.z
38+
local ux, uy, uz = pointed_thing.under.x, pointed_thing.under.y, pointed_thing.under.z
39+
if ay > uy then return 0 -- Top
40+
elseif az > uz then return 1 -- Z+ side
41+
elseif az < uz then return 2 -- Z- side
42+
elseif ax > ux then return 3 -- X+ side
43+
elseif ax < ux then return 4 -- X- side
44+
elseif ay < uy then return 5 -- Bottom
45+
else
46+
error("pointed_thing.above and under are the same!")
47+
end
48+
end
4949

50-
3 , 1 , 4 , 5 , 0 , 2 , -- rotate around y- 20 - 23
51-
5 , 1 , 3 , 2 , 0 , 4 ,
52-
2 , 1 , 5 , 4 , 0 , 3 ,
53-
4 , 1 , 2 , 3 , 0 , 5
54-
}
50+
local function nextrange(x, max)
51+
x = x + 1
52+
if x > max then
53+
x = 0
54+
end
55+
return x
56+
end
5557

56-
function screwdriver_handler (itemstack,user,pointed_thing)
57-
local keys=user:get_player_control()
58-
local player_name=user:get_player_name()
59-
local item=itemstack:to_table()
60-
if item["metadata"]=="" or keys["sneak"]==true then return screwdriver_setmode(user,itemstack) end
61-
local mode=tonumber((item["metadata"]))
62-
if pointed_thing.type~="node" then return end
63-
local pos=minetest.get_pointed_thing_position(pointed_thing,above)
64-
local node=minetest.get_node(pos)
65-
local node_name=node.name
66-
if minetest.registered_nodes[node_name].paramtype2 == "facedir" then
67-
if minetest.registered_nodes[node_name].drawtype == "nodebox" then
68-
if minetest.registered_nodes[node_name].node_box["type"]~="fixed" then return end
69-
end
70-
if node.param2==nil then return end
58+
local function screwdriver_handler(itemstack, user, pointed_thing)
59+
if pointed_thing.type ~= "node" then
60+
return
61+
end
62+
local pos = pointed_thing.under
63+
if minetest.is_protected(pos, user:get_player_name()) then
64+
minetest.record_protection_violation(pos, user:get_player_name())
65+
return
66+
end
67+
local keys = user:get_player_control()
68+
local player_name = user:get_player_name()
69+
local mode = tonumber(itemstack:get_metadata())
70+
if not mode or keys["sneak"] == true then
71+
return screwdriver_setmode(user, itemstack)
72+
end
73+
local node = minetest.get_node(pos)
74+
local node_name = node.name
75+
local ndef = minetest.registered_nodes[node.name]
76+
if ndef.paramtype2 == "facedir" then
77+
if ndef.drawtype == "nodebox" and ndef.node_box.type ~= "fixed" then
78+
return
79+
end
80+
if node.param2 == nil then
81+
return
82+
end
7183
-- Get ready to set the param2
72-
local n = node.param2
73-
local axisdir=math.floor(n/4)
74-
local rotation=n-axisdir*4
75-
if mode==1 then
76-
rotation=rotation+1
77-
if rotation>3 then rotation=0 end
78-
n=axisdir*4+rotation
79-
end
80-
81-
if mode==2 then
82-
local ppos=user:getpos()
83-
local pvect=user:get_look_dir()
84-
local face=get_node_face(pos,ppos,pvect)
85-
if face == nil then return end
86-
local index=convertFaceToIndex(face)
87-
local face1=faces_table[n*6+index+1]
88-
local found = 0
89-
while found == 0 do
90-
n=n+1
91-
if n>23 then n=0 end
92-
if faces_table[n*6+index+1]==face1 then found=1 end
84+
local n = node.param2
85+
local axisdir = math.floor(n / 4)
86+
local rotation = n - axisdir * 4
87+
if mode == 1 then
88+
n = axisdir * 4 + nextrange(rotation, 3)
89+
elseif mode == 2 then
90+
-- If you are pointing at the axisdir face or the
91+
-- opposite one then you can just rotate the node.
92+
-- Otherwise change the axisdir, avoiding the facing
93+
-- and opposite axes.
94+
local face = get_node_face(pointed_thing)
95+
if axisdir == face or axisdir == opposite_faces[face] then
96+
n = axisdir * 4 + nextrange(rotation, 3)
97+
else
98+
axisdir = nextrange(axisdir, 5)
99+
-- This is repeated because switching from the face
100+
-- can move to to the opposite and vice-versa
101+
if axisdir == face or axisdir == opposite_faces[face] then
102+
axisdir = nextrange(axisdir, 5)
93103
end
94-
end
95-
96-
if mode==3 then
97-
axisdir=axisdir+1
98-
if axisdir>5 then axisdir=0 end
99-
n=axisdir*4
100-
end
101-
102-
if mode==4 then
103-
local ppos=user:getpos()
104-
local pvect=user:get_look_dir()
105-
local face=get_node_face(pos,ppos,pvect)
106-
if face == nil then return end
107-
if axisdir == face then
108-
rotation=rotation+1
109-
if rotation>3 then rotation=0 end
110-
n=axisdir*4+rotation
111-
else
112-
n=face*4
104+
if axisdir == face or axisdir == opposite_faces[face] then
105+
axisdir = nextrange(axisdir, 5)
113106
end
107+
n = axisdir * 4
114108
end
115-
--print (dump(axisdir..", "..rotation))
116-
node.param2 = n
117-
minetest.swap_node(pos,node)
118-
local item=itemstack:to_table()
119-
local item_wear=tonumber((item["wear"]))
120-
item_wear=item_wear+327
121-
if item_wear>65535 then itemstack:clear() return itemstack end
122-
item["wear"]=tostring(item_wear)
123-
itemstack:replace(item)
109+
elseif mode == 3 then
110+
n = nextrange(axisdir, 5) * 4
111+
elseif mode == 4 then
112+
local face = get_node_face(pointed_thing)
113+
if axisdir == face then
114+
n = axisdir * 4 + nextrange(rotation, 3)
115+
else
116+
n = face * 4
117+
end
118+
end
119+
--print (dump(axisdir..", "..rotation))
120+
node.param2 = n
121+
minetest.swap_node(pos, node)
122+
local item_wear = tonumber(itemstack:get_wear())
123+
item_wear = item_wear + 327
124+
if item_wear > 65535 then
125+
itemstack:clear()
124126
return itemstack
127+
end
128+
itemstack:set_wear(item_wear)
129+
return itemstack
125130
end
126131
end
127132

128-
mode_text={
129-
{"Change rotation, Don't change axisdir."},
130-
{"Keep choosen face in front then rotate it."},
131-
{"Change axis dir, Reset rotation."},
132-
{"Bring top in front then rotate it."},
133-
}
134-
135-
function screwdriver_setmode(user,itemstack)
136-
local player_name=user:get_player_name()
137-
local item=itemstack:to_table()
138-
local mode
139-
if item["metadata"]=="" then
140-
minetest.chat_send_player(player_name,"Hold shift and use to change screwdriwer modes.")
141-
mode=0
142-
else mode=tonumber((item["metadata"]))
143-
end
144-
mode=mode+1
145-
if mode==5 then mode=1 end
146-
minetest.chat_send_player(player_name, "Screwdriver mode : "..mode.." - "..mode_text[mode][1] )
147-
item["name"]="screwdriver:screwdriver"..mode
148-
item["metadata"]=tostring(mode)
149-
itemstack:replace(item)
150-
return itemstack
151-
end
152-
153133
minetest.register_craft({
154-
output = "screwdriver:screwdriver",
155-
recipe = {
156-
{"default:steel_ingot"},
157-
{"group:stick"}
158-
}
134+
output = "screwdriver:screwdriver",
135+
recipe = {
136+
{"default:steel_ingot"},
137+
{"group:stick"}
138+
}
159139
})
160140

161-
function get_node_face(pos,ppos,pvect)
162-
ppos={x=ppos.x-pos.x,y=ppos.y-pos.y+1.5,z=ppos.z-pos.z}
163-
if pvect.x>0 then
164-
local t=(-0.5-ppos.x)/pvect.x
165-
local y_int=ppos.y+t*pvect.y
166-
local z_int=ppos.z+t*pvect.z
167-
if y_int>-0.4 and y_int<0.4 and z_int>-0.4 and z_int<0.4 then return 4 end
168-
elseif pvect.x<0 then
169-
local t=(0.5-ppos.x)/pvect.x
170-
local y_int=ppos.y+t*pvect.y
171-
local z_int=ppos.z+t*pvect.z
172-
if y_int>-0.4 and y_int<0.4 and z_int>-0.4 and z_int<0.4 then return 3 end
173-
end
174-
if pvect.y>0 then
175-
local t=(-0.5-ppos.y)/pvect.y
176-
local x_int=ppos.x+t*pvect.x
177-
local z_int=ppos.z+t*pvect.z
178-
if x_int>-0.4 and x_int<0.4 and z_int>-0.4 and z_int<0.4 then return 5 end
179-
elseif pvect.y<0 then
180-
local t=(0.5-ppos.y)/pvect.y
181-
local x_int=ppos.x+t*pvect.x
182-
local z_int=ppos.z+t*pvect.z
183-
if x_int>-0.4 and x_int<0.4 and z_int>-0.4 and z_int<0.4 then return 0 end
184-
end
185-
if pvect.z>0 then
186-
local t=(-0.5-ppos.z)/pvect.z
187-
local x_int=ppos.x+t*pvect.x
188-
local y_int=ppos.y+t*pvect.y
189-
if x_int>-0.4 and x_int<0.4 and y_int>-0.4 and y_int<0.4 then return 2 end
190-
elseif pvect.z<0 then
191-
local t=(0.5-ppos.z)/pvect.z
192-
local x_int=ppos.x+t*pvect.x
193-
local y_int=ppos.y+t*pvect.y
194-
if x_int>-0.4 and x_int<0.4 and y_int>-0.4 and y_int<0.4 then return 1 end
195-
end
196-
end
141+
minetest.register_tool("screwdriver:screwdriver", {
142+
description = "Screwdriver",
143+
inventory_image = "screwdriver.png",
144+
on_use = function(itemstack, user, pointed_thing)
145+
screwdriver_handler(itemstack, user, pointed_thing)
146+
return itemstack
147+
end,
148+
})
197149

198-
function convertFaceToIndex (face)
199-
if face==0 then return 1 end
200-
if face==1 then return 2 end
201-
if face==2 then return 3 end
202-
if face==3 then return 0 end
203-
if face==4 then return 5 end
204-
if face==5 then return 4 end
150+
for i = 1, 4 do
151+
minetest.register_tool("screwdriver:screwdriver"..i, {
152+
description = "Screwdriver in Mode "..i,
153+
inventory_image = "screwdriver.png^tool_mode"..i..".png",
154+
wield_image = "screwdriver.png",
155+
groups = {not_in_creative_inventory=1},
156+
on_use = function(itemstack, user, pointed_thing)
157+
screwdriver_handler(itemstack, user, pointed_thing)
158+
return itemstack
159+
end,
160+
})
205161
end
206162

0 commit comments

Comments
 (0)
Please sign in to comment.