version 2.0

master
Kilarin 2014-04-21 22:43:00 -05:00
parent 7508b50394
commit 6250dad1d9
5 changed files with 165 additions and 32 deletions

View File

@ -1,3 +1,5 @@
Bridge Tool Version 2.0
A bridge building tool for minetest A bridge building tool for minetest
Author Kilarin (Donald Hines) Author Kilarin (Donald Hines)
@ -9,4 +11,17 @@ steel ingot, ,steel ingot
, steel ingot , , steel ingot ,
,mese crystal fragment, ,mese crystal fragment,
Point the tool and right click to place nodes from the inventory stack directly to the right of the tool
Left click to change mode between
1: Build forward
2: Build diagonally down
3: Build diagonally up
Left click while holding down the "sneak" key to change the width between 1 and 3.
My son helped me with some ideas for this mod. I got a lot of code examples from the screwdriver mod in minetest_game by RealBadAngel, Maciej Kasatkin. I also copied and modified the screwdriver's mode number images for use in the bridge tool inventory images. They are licensed CC BY-SA 3.0 http://creativecommons.org/licenses/by-sa/3.0/ The source code is licensed CC0 http://creativecommons.org/about/cc0 My son helped me with some ideas for this mod. I got a lot of code examples from the screwdriver mod in minetest_game by RealBadAngel, Maciej Kasatkin. I also copied and modified the screwdriver's mode number images for use in the bridge tool inventory images. They are licensed CC BY-SA 3.0 http://creativecommons.org/licenses/by-sa/3.0/ The source code is licensed CC0 http://creativecommons.org/about/cc0
Topywo suggested adding wear, correcting down stair orientation, and using not_in_creative_inventory=1
Sokomine suggested adding width so that you could build 2 or 3 wide.

182
init.lua
View File

@ -1,8 +1,19 @@
-----------------------------
-- Bridge Tool version 2.0 --
-----------------------------
--This code was written by Kilarin (Donald Hines) --This code was written by Kilarin (Donald Hines)
--License:CC0, you can do whatever you wish with it. --License:CC0, you can do whatever you wish with it.
--The numbers for the modes in the textures for this mode were copied and modified from --The numbers for the modes in the textures for this mode were copied and modified from
--the screwdriver mod by RealBadAngel, Maciej Kasatkin (which were originally liscened --the screwdriver mod by RealBadAngel, Maciej Kasatkin (which were originally licensed
--as CC BY-SA --as CC BY-SA
--Topywo suggested adding wear, correcting down stair orientation, and using not_in_creative_inventory=1
--Sokomine suggested adding width so that you could build 2 or 3 wide.
local bridgetool = {
WEAR_PER_USE=0
--set this value to something higher than zero if you want bridge tool to wear out
}
local mode_text = { local mode_text = {
{"Forward"}, {"Forward"},
@ -18,13 +29,20 @@ function yaw_in_degrees(player)
return yaw return yaw
end end
function rotate_yaw(yaw,rotate)
local newyaw=yaw+rotate
if newyaw>360 then newyaw=newyaw-360 end
if newyaw<0 then newyaw=newyaw+360 end
return newyaw
end --rotate_yaw
--returns a node that has been offset in the indicated direction --returns a node that has been offset in the indicated direction
--0+z,90-x,180-z,270+x: and <0 down -y, >360 up +y --0+z,90-x,180-z,270+x: and <0 down -y, >360 up +y
--I really could have, and probably should have, done this in radians. --I really could have, and probably should have, done this in radians.
--But I've always liked degrees better. --But I've always liked degrees better.
function offset_pos(posin,yaw) function offset_pos(posin,yaw)
print("** offset_pos yaw=",yaw," posin=",pos_to_string(posin)) --print("** offset_pos yaw=",yaw," posin=",pos_to_string(posin))
local posout = {x=posin.x,y=posin.y,z=posin.z} local posout = {x=posin.x,y=posin.y,z=posin.z}
if yaw<0 then --DOWN if yaw<0 then --DOWN
posout.y=posout.y-1 posout.y=posout.y-1
@ -52,18 +70,47 @@ end --pos_to_string
--attempts to place the item and update inventory --attempts to place the item and update inventory
function item_place(stack,player,pointed,inv,idx) function item_place(stack,player,pointed,inv,idx,mode)
--local player_name = player:get_player_name() local player_name = player:get_player_name()
--minetest.chat_send_all(player_name,"--placing pointed.type="..pointed.type.." above "..pos_to_string(pointed.above).." under "..pos_to_string(pointed.under).." stack="..stack:to_string()) --minetest.chat_send_player(player_name,"--placing pointed.type="..pointed.type.." above "..pos_to_string(pointed.above).." under "..pos_to_string(pointed.under).." stack="..stack:to_string())
local success local success
stack, success = minetest.item_place(stack, player, pointed) stack, success = minetest.item_place(stack, player, pointed)
if success then --if item was placed, put modified stack back in inv if success then --if item was placed, put modified stack back in inv
inv:set_stack("main", idx, stack) inv:set_stack("main", idx, stack)
--also check for rotation of stairs
local itemname=stack:get_name()
--minetest.chat_send_player(player_name,"name="..itemname.." gig="..minetest.get_item_group(itemname,"stairs"))
--should be able to do this with get_item_group but I cant make it work
if mode~=nil and mode==2 and -- if mode=2(down)
itemname~=nil and string.len(itemname)>7 and
string.sub(itemname,1,7)=="stairs:" then --and item is stairs
local node = minetest.get_node(pointed.above)
--minetest.chat_send_player(player_name,"Param2="..node.param2)
node.param2=node.param2+2
if node.param2>3 then node.param2=node.param2-4 end
minetest.swap_node(pointed.above, node)
end --stair
end --success end --success
return stack,success return stack,success
end --item_place end --item_place
-- add wear and tear to the bridge tool
function bridgetool_wear(item)
if bridgetool.WEAR_PER_USE > 0 then
local item_wear = tonumber(item:get_wear())
item_wear = item_wear + bridgetool.WEAR_PER_USE
if item_wear > 65535 then
item:clear()
return item
end
item:set_wear(item_wear)
return item
else
return item
end
end --bridgetool_wear
--This function is for use when the bridge tool is right clicked --This function is for use when the bridge tool is right clicked
--it finds the inventory item stack immediatly to the right of the bridge tool --it finds the inventory item stack immediatly to the right of the bridge tool
@ -82,10 +129,14 @@ function bridgetool_place(item, player, pointed)
local success local success
local yaw = yaw_in_degrees(player) --cause degrees just work better for my brain local yaw = yaw_in_degrees(player) --cause degrees just work better for my brain
-------------- --------------
local mode = tonumber(item:get_metadata()) local mode
local width
mode,width=get_bridgetool_meta(item)
if not mode then if not mode then
item=bridgetool_switchmode(item,player,pointed) item=bridgetool_switchmode(item,player,pointed)
mode,width=get_bridgetool_meta(item)
end end
--minetest.chat_send_player(player_name, "pointed.type="..pointed.type.." above "..pos_to_string(pointed.above).." under "..pos_to_string(pointed.under).." yaw="..yaw.." mode="..mode) --minetest.chat_send_player(player_name, "pointed.type="..pointed.type.." above "..pos_to_string(pointed.above).." under "..pos_to_string(pointed.under).." yaw="..yaw.." mode="..mode)
if pointed.type=="node" and pointed.under ~= nil then if pointed.type=="node" and pointed.under ~= nil then
--all three modes start by placing a block forward in the yaw direction --all three modes start by placing a block forward in the yaw direction
@ -107,35 +158,79 @@ function bridgetool_place(item, player, pointed)
--try to place above the new block --try to place above the new block
pointed.above=offset_pos(pointed.under,999) pointed.above=offset_pos(pointed.under,999)
end --mode 2 - 3 end --mode 2 - 3
stack,success=item_place(stack,player,pointed,inv,idx) stack,success=item_place(stack,player,pointed,inv,idx,mode)
if not success then if not success then
minetest.chat_send_player(player_name, "bridge tool: unable to place "..mode_text[mode][1].." at "..pos_to_string(pointed.above)) minetest.chat_send_player(player_name, "bridge tool: unable to place "..mode_text[mode][1].." at "..pos_to_string(pointed.above))
end --if not success block 2 end --if not success block 2
--remove the extra stone whether success on block 2 or not --remove the extra stone whether success on block 2 or not
minetest.node_dig(holdforward,minetest.get_node(holdforward),player) minetest.node_dig(holdforward,minetest.get_node(holdforward),player)
end -- if not success block 1 elseif succes block 1 and mode 2 or 3 end -- if not success block 1 elseif succes block 1 and mode 2 or 3
--now try for the width
if success then --only proceed with width if last block placed was a success
item=bridgetool_wear(item)
for w=2,width do
pointed.under=pointed.above --block 2 is now the under block
local right90=rotate_yaw(yaw,-90)
pointed.above=offset_pos(pointed.under,right90)
--minetest.chat_send_player(player_name, " yaw="..yaw.." right90="..right90.." under="..pos_to_string(pointed.under).." above="..pos_to_string(pointed.above))
stack,success=item_place(stack,player,pointed,inv,idx)
if not success then
minetest.chat_send_player(player_name, "bridge tool: unable to place width "..w.." at "..pos_to_string(pointed.above))
break
else
item=bridgetool_wear(item)
end --if not success
end --for
end --if success
end --pointed.type="node" and pointed.under~=nil end --pointed.type="node" and pointed.under~=nil
end --pointed ~= nil end --pointed ~= nil
return item
end --function bridgetool_place end --function bridgetool_place
--returns mode and width
function get_bridgetool_meta(item)
local metadata = item:get_metadata()
if not metadata or string.len(metadata)<3 then
--not metadata means mode and width have never been set
--metadata<3 means tool was created with a bridgetool 1.0 and doesn't have width set
return nil, nil
else --valid metadata
local mode=tonumber(string.sub(metadata,1,1))
local width=tonumber(string.sub(metadata,3,3))
return mode, width
end -- if not metadata
end --get_bridgetool_meta
--on left click switch the mode of the bridge tool --on left click switch the mode of the bridge tool
--also deals with sneak-leftclick which sets width
function bridgetool_switchmode(item, player, pointed) --pointed is ignored function bridgetool_switchmode(item, player, pointed) --pointed is ignored
local player_name = player:get_player_name() --for chat messages local player_name = player:get_player_name() --for chat messages
local mode = tonumber(item:get_metadata()) mode,width=get_bridgetool_meta(item)
if not mode then --if item has not been used and mode not set yet: if mode==nil or width==nil then
mode=0 --if item has not been used and mode not set yet,
minetest.chat_send_player(player_name, "Left click to change mode between 1:Forward, 2:Down, 3:Up, Right click to place, uses inventory stack directly to right of bridge tool") --or a pre-width item that needs to have width added
end minetest.chat_send_player(player_name, "Left click to change mode between 1:Forward, 2:Down, 3:Up, Leftclick+Sneak to change width, Right click to place, uses inventory stack directly to right of bridge tool")
mode = mode + 1 mode=1
if mode > 3 then width=1
mode = 1 else --valid mode and width
end local keys = player:get_player_control()
minetest.chat_send_player(player_name, "bridge tool mode : "..mode.." - "..mode_text[mode][1]) if keys["sneak"] == true then
item:set_name("bridgetool:bridge_tool"..mode) width=width+1
item:set_metadata(mode) if width>3 then width=1 end
else
mode=mode+1
if mode>3 then mode=1 end
end --if sneak
end --not mode==nil
--minetest.chat_send_player(player_name, "bridge tool mode : "..mode.." - "..mode_text[mode][1].." width="..width)
item:set_name("bridgetool:bridge_tool"..mode..width)
item:set_metadata(mode..":"..width)
return item return item
end end --bridgetool_switchmode
minetest.register_craft({ minetest.register_craft({
@ -147,7 +242,7 @@ minetest.register_craft({
} }
}) })
--this one appears in crafting lists and when you first craft the item
minetest.register_tool("bridgetool:bridge_tool", { minetest.register_tool("bridgetool:bridge_tool", {
description = "Bridge Tool", description = "Bridge Tool",
inventory_image = "bridgetool_wield.png", inventory_image = "bridgetool_wield.png",
@ -156,12 +251,35 @@ minetest.register_craft({
on_use = bridgetool_switchmode on_use = bridgetool_switchmode
}) })
for i = 1, 3 do --these are the different tools for all 3 differen modes and widths
minetest.register_tool("bridgetool:bridge_tool"..i, { --bridgetool:bridge_tool11 12 13 21 22 23 31 32 33
description = "Bridge Tool mode "..i, --the reason for having different tools defined is so they can have
inventory_image = "bridgetool_m"..i..".png", --an inventory image telling which mode/width the tool is in
wield_image = "bridgetool_wield.png^[transformR90", --note that we set these to NOT show up in the creative inventory (Thanks Topywo for that advice!)
on_place = bridgetool_place, for m = 1, 3 do
on_use = bridgetool_switchmode for w = 1, 3 do
}) minetest.register_tool("bridgetool:bridge_tool"..m..w, {
end description = "Bridge Tool mode "..m.." width "..w,
inventory_image = "bridgetool_m"..m..".png^bridgetool_w"..w..".png",
wield_image = "bridgetool_wield.png^[transformR90",
groups = {not_in_creative_inventory=1},
on_place = bridgetool_place,
on_use = bridgetool_switchmode
})
end --for w
end --for m
--temporary for backwards compatibility, remove this after a version or two
--since previously made tools will be named bridgetool_1 2 or 3, leaving this
--here ensures they will load and switch to bridgetool_11 etc on the first left click
for m = 1, 3 do
minetest.register_tool("bridgetool:bridge_tool"..m, {
description = "Bridge Tool mode "..m,
inventory_image = "bridgetool_m"..m..".png",
wield_image = "bridgetool_wield.png^[transformR90",
groups = {not_in_creative_inventory=1},
on_place = bridgetool_place,
on_use = bridgetool_switchmode
})
end --for m

BIN
textures/bridgetool_w1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

BIN
textures/bridgetool_w2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

BIN
textures/bridgetool_w3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B