Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rework screwdriver and add protection support
- Loading branch information
1 parent
47a49ec
commit 64fdb49
Showing
2 changed files
with
142 additions
and
187 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,206 +1,162 @@ | ||
minetest.register_tool("screwdriver:screwdriver", { | ||
description = "Screwdriver", | ||
inventory_image = "screwdriver.png", | ||
on_use = function(itemstack, user, pointed_thing) | ||
screwdriver_handler(itemstack,user,pointed_thing) | ||
return itemstack | ||
end, | ||
}) | ||
|
||
for i=1,4,1 do | ||
minetest.register_tool("screwdriver:screwdriver"..i, { | ||
description = "Screwdriver in Mode "..i, | ||
inventory_image = "screwdriver.png^tool_mode"..i..".png", | ||
wield_image = "screwdriver.png", | ||
groups = {not_in_creative_inventory=1}, | ||
on_use = function(itemstack, user, pointed_thing) | ||
screwdriver_handler(itemstack,user,pointed_thing) | ||
return itemstack | ||
end, | ||
}) | ||
end | ||
faces_table= | ||
{ | ||
--look dir +X +Y +Z -Z -Y -X | ||
2 , 0 , 4 , 5 , 1 , 3 , -- rotate around y+ 0 - 3 | ||
4 , 0 , 3 , 2 , 1 , 5 , | ||
3 , 0 , 5 , 4 , 1 , 2 , | ||
5 , 0 , 2 , 3 , 1 , 4 , | ||
|
||
2 , 5 , 0 , 1 , 4 , 3 , -- rotate around z+ 4 - 7 | ||
4 , 2 , 0 , 1 , 3 , 5 , | ||
3 , 4 , 0 , 1 , 5 , 2 , | ||
5 , 3 , 0 , 1 , 2 , 4 , | ||
local mode_text = { | ||
{"Change rotation, Don't change axisdir."}, | ||
{"Keep choosen face in front then rotate it."}, | ||
{"Change axis dir, Reset rotation."}, | ||
{"Bring top in front then rotate it."}, | ||
} | ||
|
||
2 , 4 , 1 , 0 , 5 , 3 , -- rotate around z- 8 - 11 | ||
4 , 3 , 1 , 0 , 2 , 5 , | ||
3 , 5 , 1 , 0 , 4 , 2 , | ||
5 , 2 , 1 , 0 , 3 , 4 , | ||
local opposite_faces = { | ||
[0] = 5, | ||
[1] = 2, | ||
[2] = 1, | ||
[3] = 4, | ||
[4] = 3, | ||
[5] = 0, | ||
} | ||
|
||
0 , 3 , 4 , 5 , 2 , 1 , -- rotate around x+ 12 - 15 | ||
0 , 5 , 3 , 2 , 4 , 1 , | ||
0 , 2 , 5 , 4 , 3 , 1 , | ||
0 , 4 , 2 , 3 , 5 , 1 , | ||
local function screwdriver_setmode(user,itemstack) | ||
local player_name = user:get_player_name() | ||
local item = itemstack:to_table() | ||
local mode = tonumber(itemstack:get_metadata()) | ||
if not mode then | ||
minetest.chat_send_player(player_name, "Hold shift and use to change screwdriwer modes.") | ||
mode = 0 | ||
end | ||
mode = mode + 1 | ||
if mode == 5 then | ||
mode = 1 | ||
end | ||
minetest.chat_send_player(player_name, "Screwdriver mode : "..mode.." - "..mode_text[mode][1] ) | ||
itemstack:set_name("screwdriver:screwdriver"..mode) | ||
itemstack:set_metadata(mode) | ||
return itemstack | ||
end | ||
|
||
1 , 2 , 4 , 5 , 3 , 0 , -- rotate around x- 16 - 19 | ||
1 , 4 , 3 , 2 , 5 , 0 , | ||
1 , 3 , 5 , 4 , 2 , 0 , | ||
1 , 5 , 2 , 3 , 4 , 0 , | ||
local function get_node_face(pointed_thing) | ||
local ax, ay, az = pointed_thing.above.x, pointed_thing.above.y, pointed_thing.above.z | ||
local ux, uy, uz = pointed_thing.under.x, pointed_thing.under.y, pointed_thing.under.z | ||
if ay > uy then return 0 -- Top | ||
elseif az > uz then return 1 -- Z+ side | ||
elseif az < uz then return 2 -- Z- side | ||
elseif ax > ux then return 3 -- X+ side | ||
elseif ax < ux then return 4 -- X- side | ||
elseif ay < uy then return 5 -- Bottom | ||
else | ||
error("pointed_thing.above and under are the same!") | ||
end | ||
end | ||
|
||
3 , 1 , 4 , 5 , 0 , 2 , -- rotate around y- 20 - 23 | ||
5 , 1 , 3 , 2 , 0 , 4 , | ||
2 , 1 , 5 , 4 , 0 , 3 , | ||
4 , 1 , 2 , 3 , 0 , 5 | ||
} | ||
local function nextrange(x, max) | ||
x = x + 1 | ||
if x > max then | ||
x = 0 | ||
end | ||
return x | ||
end | ||
|
||
function screwdriver_handler (itemstack,user,pointed_thing) | ||
local keys=user:get_player_control() | ||
local player_name=user:get_player_name() | ||
local item=itemstack:to_table() | ||
if item["metadata"]=="" or keys["sneak"]==true then return screwdriver_setmode(user,itemstack) end | ||
local mode=tonumber((item["metadata"])) | ||
if pointed_thing.type~="node" then return end | ||
local pos=minetest.get_pointed_thing_position(pointed_thing,above) | ||
local node=minetest.get_node(pos) | ||
local node_name=node.name | ||
if minetest.registered_nodes[node_name].paramtype2 == "facedir" then | ||
if minetest.registered_nodes[node_name].drawtype == "nodebox" then | ||
if minetest.registered_nodes[node_name].node_box["type"]~="fixed" then return end | ||
end | ||
if node.param2==nil then return end | ||
local function screwdriver_handler(itemstack, user, pointed_thing) | ||
if pointed_thing.type ~= "node" then | ||
return | ||
end | ||
local pos = pointed_thing.under | ||
if minetest.is_protected(pos, user:get_player_name()) then | ||
minetest.record_protection_violation(pos, user:get_player_name()) | ||
return | ||
end | ||
local keys = user:get_player_control() | ||
local player_name = user:get_player_name() | ||
local mode = tonumber(itemstack:get_metadata()) | ||
if not mode or keys["sneak"] == true then | ||
return screwdriver_setmode(user, itemstack) | ||
end | ||
local node = minetest.get_node(pos) | ||
local node_name = node.name | ||
local ndef = minetest.registered_nodes[node.name] | ||
if ndef.paramtype2 == "facedir" then | ||
if ndef.drawtype == "nodebox" and ndef.node_box.type ~= "fixed" then | ||
return | ||
end | ||
if node.param2 == nil then | ||
return | ||
end | ||
-- Get ready to set the param2 | ||
local n = node.param2 | ||
local axisdir=math.floor(n/4) | ||
local rotation=n-axisdir*4 | ||
if mode==1 then | ||
rotation=rotation+1 | ||
if rotation>3 then rotation=0 end | ||
n=axisdir*4+rotation | ||
end | ||
|
||
if mode==2 then | ||
local ppos=user:getpos() | ||
local pvect=user:get_look_dir() | ||
local face=get_node_face(pos,ppos,pvect) | ||
if face == nil then return end | ||
local index=convertFaceToIndex(face) | ||
local face1=faces_table[n*6+index+1] | ||
local found = 0 | ||
while found == 0 do | ||
n=n+1 | ||
if n>23 then n=0 end | ||
if faces_table[n*6+index+1]==face1 then found=1 end | ||
local n = node.param2 | ||
local axisdir = math.floor(n / 4) | ||
local rotation = n - axisdir * 4 | ||
if mode == 1 then | ||
n = axisdir * 4 + nextrange(rotation, 3) | ||
elseif mode == 2 then | ||
-- If you are pointing at the axisdir face or the | ||
-- opposite one then you can just rotate the node. | ||
-- Otherwise change the axisdir, avoiding the facing | ||
-- and opposite axes. | ||
local face = get_node_face(pointed_thing) | ||
if axisdir == face or axisdir == opposite_faces[face] then | ||
n = axisdir * 4 + nextrange(rotation, 3) | ||
else | ||
axisdir = nextrange(axisdir, 5) | ||
-- This is repeated because switching from the face | ||
-- can move to to the opposite and vice-versa | ||
if axisdir == face or axisdir == opposite_faces[face] then | ||
axisdir = nextrange(axisdir, 5) | ||
end | ||
end | ||
|
||
if mode==3 then | ||
axisdir=axisdir+1 | ||
if axisdir>5 then axisdir=0 end | ||
n=axisdir*4 | ||
end | ||
|
||
if mode==4 then | ||
local ppos=user:getpos() | ||
local pvect=user:get_look_dir() | ||
local face=get_node_face(pos,ppos,pvect) | ||
if face == nil then return end | ||
if axisdir == face then | ||
rotation=rotation+1 | ||
if rotation>3 then rotation=0 end | ||
n=axisdir*4+rotation | ||
else | ||
n=face*4 | ||
if axisdir == face or axisdir == opposite_faces[face] then | ||
axisdir = nextrange(axisdir, 5) | ||
end | ||
n = axisdir * 4 | ||
end | ||
--print (dump(axisdir..", "..rotation)) | ||
node.param2 = n | ||
minetest.swap_node(pos,node) | ||
local item=itemstack:to_table() | ||
local item_wear=tonumber((item["wear"])) | ||
item_wear=item_wear+327 | ||
if item_wear>65535 then itemstack:clear() return itemstack end | ||
item["wear"]=tostring(item_wear) | ||
itemstack:replace(item) | ||
elseif mode == 3 then | ||
n = nextrange(axisdir, 5) * 4 | ||
elseif mode == 4 then | ||
local face = get_node_face(pointed_thing) | ||
if axisdir == face then | ||
n = axisdir * 4 + nextrange(rotation, 3) | ||
else | ||
n = face * 4 | ||
end | ||
end | ||
--print (dump(axisdir..", "..rotation)) | ||
node.param2 = n | ||
minetest.swap_node(pos, node) | ||
local item_wear = tonumber(itemstack:get_wear()) | ||
item_wear = item_wear + 327 | ||
if item_wear > 65535 then | ||
itemstack:clear() | ||
return itemstack | ||
end | ||
itemstack:set_wear(item_wear) | ||
return itemstack | ||
end | ||
end | ||
|
||
mode_text={ | ||
{"Change rotation, Don't change axisdir."}, | ||
{"Keep choosen face in front then rotate it."}, | ||
{"Change axis dir, Reset rotation."}, | ||
{"Bring top in front then rotate it."}, | ||
} | ||
|
||
function screwdriver_setmode(user,itemstack) | ||
local player_name=user:get_player_name() | ||
local item=itemstack:to_table() | ||
local mode | ||
if item["metadata"]=="" then | ||
minetest.chat_send_player(player_name,"Hold shift and use to change screwdriwer modes.") | ||
mode=0 | ||
else mode=tonumber((item["metadata"])) | ||
end | ||
mode=mode+1 | ||
if mode==5 then mode=1 end | ||
minetest.chat_send_player(player_name, "Screwdriver mode : "..mode.." - "..mode_text[mode][1] ) | ||
item["name"]="screwdriver:screwdriver"..mode | ||
item["metadata"]=tostring(mode) | ||
itemstack:replace(item) | ||
return itemstack | ||
end | ||
|
||
minetest.register_craft({ | ||
output = "screwdriver:screwdriver", | ||
recipe = { | ||
{"default:steel_ingot"}, | ||
{"group:stick"} | ||
} | ||
output = "screwdriver:screwdriver", | ||
recipe = { | ||
{"default:steel_ingot"}, | ||
{"group:stick"} | ||
} | ||
}) | ||
|
||
function get_node_face(pos,ppos,pvect) | ||
ppos={x=ppos.x-pos.x,y=ppos.y-pos.y+1.5,z=ppos.z-pos.z} | ||
if pvect.x>0 then | ||
local t=(-0.5-ppos.x)/pvect.x | ||
local y_int=ppos.y+t*pvect.y | ||
local z_int=ppos.z+t*pvect.z | ||
if y_int>-0.4 and y_int<0.4 and z_int>-0.4 and z_int<0.4 then return 4 end | ||
elseif pvect.x<0 then | ||
local t=(0.5-ppos.x)/pvect.x | ||
local y_int=ppos.y+t*pvect.y | ||
local z_int=ppos.z+t*pvect.z | ||
if y_int>-0.4 and y_int<0.4 and z_int>-0.4 and z_int<0.4 then return 3 end | ||
end | ||
if pvect.y>0 then | ||
local t=(-0.5-ppos.y)/pvect.y | ||
local x_int=ppos.x+t*pvect.x | ||
local z_int=ppos.z+t*pvect.z | ||
if x_int>-0.4 and x_int<0.4 and z_int>-0.4 and z_int<0.4 then return 5 end | ||
elseif pvect.y<0 then | ||
local t=(0.5-ppos.y)/pvect.y | ||
local x_int=ppos.x+t*pvect.x | ||
local z_int=ppos.z+t*pvect.z | ||
if x_int>-0.4 and x_int<0.4 and z_int>-0.4 and z_int<0.4 then return 0 end | ||
end | ||
if pvect.z>0 then | ||
local t=(-0.5-ppos.z)/pvect.z | ||
local x_int=ppos.x+t*pvect.x | ||
local y_int=ppos.y+t*pvect.y | ||
if x_int>-0.4 and x_int<0.4 and y_int>-0.4 and y_int<0.4 then return 2 end | ||
elseif pvect.z<0 then | ||
local t=(0.5-ppos.z)/pvect.z | ||
local x_int=ppos.x+t*pvect.x | ||
local y_int=ppos.y+t*pvect.y | ||
if x_int>-0.4 and x_int<0.4 and y_int>-0.4 and y_int<0.4 then return 1 end | ||
end | ||
end | ||
minetest.register_tool("screwdriver:screwdriver", { | ||
description = "Screwdriver", | ||
inventory_image = "screwdriver.png", | ||
on_use = function(itemstack, user, pointed_thing) | ||
screwdriver_handler(itemstack, user, pointed_thing) | ||
return itemstack | ||
end, | ||
}) | ||
|
||
function convertFaceToIndex (face) | ||
if face==0 then return 1 end | ||
if face==1 then return 2 end | ||
if face==2 then return 3 end | ||
if face==3 then return 0 end | ||
if face==4 then return 5 end | ||
if face==5 then return 4 end | ||
for i = 1, 4 do | ||
minetest.register_tool("screwdriver:screwdriver"..i, { | ||
description = "Screwdriver in Mode "..i, | ||
inventory_image = "screwdriver.png^tool_mode"..i..".png", | ||
wield_image = "screwdriver.png", | ||
groups = {not_in_creative_inventory=1}, | ||
on_use = function(itemstack, user, pointed_thing) | ||
screwdriver_handler(itemstack, user, pointed_thing) | ||
return itemstack | ||
end, | ||
}) | ||
end | ||
|