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
Author Kilarin (Donald Hines)
@ -9,4 +11,17 @@ steel ingot, ,steel ingot
, steel ingot ,
,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
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)
--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 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
--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 = {
{"Forward"},
@ -18,13 +29,20 @@ function yaw_in_degrees(player)
return yaw
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
--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.
--But I've always liked degrees better.
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}
if yaw<0 then --DOWN
posout.y=posout.y-1
@ -52,18 +70,47 @@ end --pos_to_string
--attempts to place the item and update inventory
function item_place(stack,player,pointed,inv,idx)
--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())
function item_place(stack,player,pointed,inv,idx,mode)
local player_name = player:get_player_name()
--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
stack, success = minetest.item_place(stack, player, pointed)
if success then --if item was placed, put modified stack back in inv
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
return stack,success
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
--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 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
item=bridgetool_switchmode(item,player,pointed)
mode,width=get_bridgetool_meta(item)
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)
if pointed.type=="node" and pointed.under ~= nil then
--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
pointed.above=offset_pos(pointed.under,999)
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
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
--remove the extra stone whether success on block 2 or not
minetest.node_dig(holdforward,minetest.get_node(holdforward),player)
--remove the extra stone whether success on block 2 or not
minetest.node_dig(holdforward,minetest.get_node(holdforward),player)
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 ~= nil
return item
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
--also deals with sneak-leftclick which sets width
function bridgetool_switchmode(item, player, pointed) --pointed is ignored
local player_name = player:get_player_name() --for chat messages
local mode = tonumber(item:get_metadata())
if not mode then --if item has not been used and mode not set yet:
mode=0
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")
end
mode = mode + 1
if mode > 3 then
mode = 1
end
minetest.chat_send_player(player_name, "bridge tool mode : "..mode.." - "..mode_text[mode][1])
item:set_name("bridgetool:bridge_tool"..mode)
item:set_metadata(mode)
mode,width=get_bridgetool_meta(item)
if mode==nil or width==nil then
--if item has not been used and mode not set yet,
--or a pre-width item that needs to have width added
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=1
width=1
else --valid mode and width
local keys = player:get_player_control()
if keys["sneak"] == true then
width=width+1
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
end
end --bridgetool_switchmode
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", {
description = "Bridge Tool",
inventory_image = "bridgetool_wield.png",
@ -156,12 +251,35 @@ minetest.register_craft({
on_use = bridgetool_switchmode
})
for i = 1, 3 do
minetest.register_tool("bridgetool:bridge_tool"..i, {
description = "Bridge Tool mode "..i,
inventory_image = "bridgetool_m"..i..".png",
wield_image = "bridgetool_wield.png^[transformR90",
on_place = bridgetool_place,
on_use = bridgetool_switchmode
})
end
--these are the different tools for all 3 differen modes and widths
--bridgetool:bridge_tool11 12 13 21 22 23 31 32 33
--the reason for having different tools defined is so they can have
--an inventory image telling which mode/width the tool is in
--note that we set these to NOT show up in the creative inventory (Thanks Topywo for that advice!)
for m = 1, 3 do
for w = 1, 3 do
minetest.register_tool("bridgetool:bridge_tool"..m..w, {
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