|
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 , |
29 | 1 |
|
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 | +} |
34 | 8 |
|
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 | +} |
39 | 17 |
|
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 |
44 | 35 |
|
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 |
49 | 49 |
|
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 |
55 | 57 |
|
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 |
71 | 83 | -- 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) |
93 | 103 | 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) |
113 | 106 | end
|
| 107 | + n = axisdir * 4 |
114 | 108 | 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() |
124 | 126 | return itemstack
|
| 127 | + end |
| 128 | + itemstack:set_wear(item_wear) |
| 129 | + return itemstack |
125 | 130 | end
|
126 | 131 | end
|
127 | 132 |
|
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 |
| - |
153 | 133 | 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 | + } |
159 | 139 | })
|
160 | 140 |
|
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 | +}) |
197 | 149 |
|
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 | + }) |
205 | 161 | end
|
206 | 162 |
|
0 commit comments