summaryrefslogtreecommitdiff
path: root/item_transport.lua
diff options
context:
space:
mode:
authorVanessa Ezekowitz <vanessaezekowitz@gmail.com>2013-01-13 21:45:03 -0500
committerVanessa Ezekowitz <vanessaezekowitz@gmail.com>2013-01-13 21:45:03 -0500
commit109729cfb27efd816238f094a738a8ac23e83dda (patch)
tree2a1f2f7419e14c7974e3d05c7b1148054581c27f /item_transport.lua
parent14102d7c3ad8f7e4aef271294a74c28e7e851bc2 (diff)
downloadpipeworks-109729cfb27efd816238f094a738a8ac23e83dda.tar
pipeworks-109729cfb27efd816238f094a738a8ac23e83dda.tar.gz
pipeworks-109729cfb27efd816238f094a738a8ac23e83dda.tar.bz2
pipeworks-109729cfb27efd816238f094a738a8ac23e83dda.tar.xz
pipeworks-109729cfb27efd816238f094a738a8ac23e83dda.zip
Added Nore's item transport mod and integrated it into pipeworks
Items can now flow from one chest (or Nore's filter object) to another via the pneumatic tubes! Thanks to Nore and RealBadAngel for the code. Note that this mod has to redefine the default chests and furnaces (see compat.lua) in order to add some new group definitions so that tubes can appear to connect to these objects.
Diffstat (limited to 'item_transport.lua')
-rw-r--r--item_transport.lua331
1 files changed, 331 insertions, 0 deletions
diff --git a/item_transport.lua b/item_transport.lua
new file mode 100644
index 0000000..aad3d85
--- /dev/null
+++ b/item_transport.lua
@@ -0,0 +1,331 @@
+minetest.register_craftitem(":item_transport:filter", {
+ description = "Filter",
+ stack_max = 99,
+})
+
+minetest.register_node(":item_transport:filter", {
+ description = "filter",
+ tiles = {"filter_top.png", "filter_top.png", "filter_output.png",
+ "filter_input.png", "filter_side.png", "filter_top.png"},
+ paramtype2 = "facedir",
+ groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,tubedevice=1,mesecon=2},
+ legacy_facedir_simple = true,
+ sounds = default.node_sound_wood_defaults(),
+ on_construct = function(pos)
+ local meta = minetest.env:get_meta(pos)
+ meta:set_string("formspec",
+ "invsize[9,9;]"..
+ "list[current_name;main;0,2;8,2;]"..
+ "list[current_player;main;0,5;8,4;]")
+ meta:set_string("infotext", "Filter")
+ local inv = meta:get_inventory()
+ inv:set_size("main", 8*4)
+ end,
+ can_dig = function(pos,player)
+ local meta = minetest.env:get_meta(pos);
+ local inv = meta:get_inventory()
+ return inv:is_empty("main")
+ end,
+ mesecons={effector={action_on=function(pos,node)
+ minetest.registered_nodes[node.name].on_punch(pos,node,nil)
+ end}},
+ on_punch = function (pos, node, puncher)
+ local meta = minetest.env:get_meta(pos);
+ local inv = meta:get_inventory()
+ local frompos
+ local dir
+ if node.param2==0 then
+ frompos={x=pos.x-1,y=pos.y,z=pos.z}
+ dir={x=1,y=0,z=0}
+ elseif node.param2==1 then
+ frompos={x=pos.x,y=pos.y,z=pos.z+1}
+ dir={x=0,y=0,z=-1}
+ elseif node.param2==2 then
+ frompos={x=pos.x+1,y=pos.y,z=pos.z}
+ dir={x=-1,y=0,z=0}
+ else
+ frompos={x=pos.x,y=pos.y,z=pos.z-1}
+ dir={x=0,y=0,z=1}
+ end
+ local fromnode=minetest.env:get_node(frompos)
+ local frominv
+ if not (minetest.registered_nodes[fromnode.name].tube and
+ minetest.registered_nodes[fromnode.name].tube.input_inventory) then
+ return
+ end
+ local frommeta=minetest.env:get_meta(frompos)
+ local frominvname=minetest.registered_nodes[fromnode.name].tube.input_inventory
+ local frominv=frommeta:get_inventory()
+ for _,filter in ipairs(inv:get_list("main")) do
+ local sname=filter:get_name()
+ if sname ~="" then
+ for spos,stack in ipairs(frominv:get_list(frominvname)) do
+ if stack:get_name()==sname then
+ item=stack:take_item()
+ frominv:set_stack(frominvname,spos,stack)
+ pos1=pos
+ item1=tube_item({x=pos1.x,y=pos1.y,z=pos1.z},item)
+ item1:get_luaentity().start_pos = {x=pos1.x,y=pos1.y,z=pos1.z}
+ item1:setvelocity(dir)
+ item1:setacceleration({x=0, y=0, z=0})
+ return
+ end
+ end
+ end
+ end
+ if inv:is_empty("main") then
+ for spos,stack in ipairs(frominv:get_list(frominvname)) do
+ if stack:get_name()~="" then
+ item=stack:take_item()
+ frominv:set_stack(frominvname,spos,stack)
+ pos1=pos
+ item1=tube_item({x=pos1.x,y=pos1.y,z=pos1.z},item)
+ item1:get_luaentity().start_pos = {x=pos1.x,y=pos1.y,z=pos1.z}
+ item1:setvelocity(dir)
+ item1:setacceleration({x=0, y=0, z=0})
+ return
+ end
+ end
+ end
+end,
+})
+
+
+function tube_item(pos, item)
+ -- Take item in any format
+ local stack = ItemStack(item)
+ local obj = minetest.env:add_entity(pos, "item_transport:tubed_item")
+ obj:get_luaentity():set_item(stack:to_string())
+ return obj
+end
+
+minetest.register_entity(":item_transport:tubed_item", {
+ initial_properties = {
+ hp_max = 1,
+ physical = false,
+ collisionbox = {0,0,0,0,0,0},
+ visual = "sprite",
+ visual_size = {x=0.5, y=0.5},
+ textures = {""},
+ spritediv = {x=1, y=1},
+ initial_sprite_basepos = {x=0, y=0},
+ is_visible = false,
+ start_pos={},
+ route={}
+ },
+
+ itemstring = '',
+ physical_state = false,
+
+ set_item = function(self, itemstring)
+ self.itemstring = itemstring
+ local stack = ItemStack(itemstring)
+ local itemtable = stack:to_table()
+ local itemname = nil
+ if itemtable then
+ itemname = stack:to_table().name
+ end
+ local item_texture = nil
+ local item_type = ""
+ if minetest.registered_items[itemname] then
+ item_texture = minetest.registered_items[itemname].inventory_image
+ item_type = minetest.registered_items[itemname].type
+ end
+ prop = {
+ is_visible = true,
+ visual = "sprite",
+ textures = {"unknown_item.png"}
+ }
+ if item_texture and item_texture ~= "" then
+ prop.visual = "sprite"
+ prop.textures = {item_texture}
+ prop.visual_size = {x=0.3, y=0.3}
+ else
+ prop.visual = "wielditem"
+ prop.textures = {itemname}
+ prop.visual_size = {x=0.15, y=0.15}
+ end
+ self.object:set_properties(prop)
+ end,
+
+ get_staticdata = function(self)
+
+ return minetest.serialize({
+ itemstring=self.itemstring,
+ velocity=self.object:getvelocity(),
+ start_pos=self.start_pos
+ })
+ end,
+
+ on_activate = function(self, staticdata)
+ if staticdata=="" or staticdata==nil then return end
+ local item = minetest.deserialize(staticdata)
+ local stack = ItemStack(item.itemstring)
+ local itemtable = stack:to_table()
+ local itemname = nil
+ if itemtable then
+ itemname = stack:to_table().name
+ end
+
+ if itemname then
+ self.start_pos=item.start_pos
+ self.object:setvelocity(item.velocity)
+ self.object:setacceleration({x=0, y=0, z=0})
+ self.object:setpos(item.start_pos)
+ end
+ self:set_item(item.itemstring)
+ end,
+
+ on_step = function(self, dtime)
+ if self.start_pos then
+ local pos = self.object:getpos()
+ local node = minetest.env:get_node(pos)
+ local meta = minetest.env:get_meta(pos)
+ tubelike=meta:get_int("tubelike")
+ local stack = ItemStack(self.itemstring)
+ local drop_pos=nil
+
+ local velocity=self.object:getvelocity()
+
+ if velocity==nil then return end
+
+ if minetest.get_item_group(node.name,"tubedevice_receiver")==1 then
+ leftover = minetest.registered_nodes[node.name].tube.insert_object(pos,node,stack,velocity)
+ drop_pos=minetest.env:find_node_near(pos,1,"air")
+ if drop_pos and not leftover:is_empty() then minetest.item_drop(leftover,"",drop_pos) end
+ self.object:remove()
+ return
+ end
+
+ if math.abs(velocity.x)==1 then
+ local next_node=math.abs(pos.x-self.start_pos.x)
+ if next_node >= 1 then
+ self.start_pos.x=self.start_pos.x+velocity.x
+ if go_next (self.start_pos, velocity, stack)==0 then
+ drop_pos=minetest.env:find_node_near({x=self.start_pos.x,y=self.start_pos.y,z=self.start_pos.z+velocity.x}, 1, "air")
+ if drop_pos then minetest.item_drop(stack, "", drop_pos) end
+ self.object:remove()
+ end
+ self.object:setpos(self.start_pos)
+ self.object:setvelocity(velocity)
+ return
+ end
+ end
+
+ if math.abs(velocity.y)==1 then
+ local next_node=math.abs(pos.y-self.start_pos.y)
+ if next_node >= 1 then
+ self.start_pos.y=self.start_pos.y+velocity.y
+ if go_next (self.start_pos, velocity, stack)==0 then
+ drop_pos=minetest.env:find_node_near({x=self.start_pos.x+velocity.x,y=self.start_pos.y+velocity.y,z=self.start_pos.z+velocity.z}, 1, "air")
+ if drop_pos then minetest.item_drop(stack, "", drop_pos) end
+ self.object:remove()
+ end
+ self.object:setpos(self.start_pos)
+ self.object:setvelocity(velocity)
+ return
+ end
+ end
+
+ if math.abs(velocity.z)==1 then
+ local next_node=math.abs(pos.z-self.start_pos.z)
+ if next_node >= 1 then
+ self.start_pos.z=self.start_pos.z+velocity.z
+ if go_next (self.start_pos, velocity, stack)==0 then
+ drop_pos=minetest.env:find_node_near({x=self.start_pos.x+velocity.x,y=self.start_pos.y+velocity.y,z=self.start_pos.z+velocity.z}, 1, "air")
+ if drop_pos then minetest.item_drop(stack, "", drop_pos) end
+ self.object:remove()
+ end
+ self.object:setpos(self.start_pos)
+ self.object:setvelocity(velocity)
+ return
+ end
+ end
+ end
+
+end
+})
+
+
+function addVect(pos,vect)
+return {x=pos.x+vect.x,y=pos.y+vect.y,z=pos.z+vect.z}
+end
+
+adjlist={{x=0,y=0,z=1},{x=0,y=0,z=-1},{x=0,y=1,z=0},{x=0,y=-1,z=0},{x=1,y=0,z=0},{x=-1,y=0,z=0}}
+
+function go_next(pos,velocity,stack)
+ print(dump(pos))
+ local chests={}
+ local tubes={}
+ local cmeta=minetest.env:get_meta(pos)
+ local node
+ local meta
+ local tubelike
+ local tube_receiver
+ local len=1
+ local n
+ for _,vect in ipairs(adjlist) do
+ if vect.x~=-velocity.x or vect.y~=-velocity.y or vect.z~=-velocity.z then
+ npos=addVect(pos,vect)
+ node=minetest.env:get_node(npos)
+ tube_receiver=minetest.get_item_group(node.name,"tubedevice_receiver")
+ --tubelike=minetest.get_item_group(node.name,"tubelike")
+ meta=minetest.env:get_meta(npos)
+ tubelike=meta:get_int("tubelike")
+ if tube_receiver==1 then
+ if minetest.registered_nodes[node.name].tube.can_insert(npos,node,stack,vect) then
+ local i=1
+ repeat
+ if chests[i]==nil then break end
+ i=i+1
+ until false
+ chests[i]={}
+ chests[i].pos=npos
+ chests[i].vect=vect
+ end
+ elseif tubelike==1 then
+ local i=1
+ repeat
+ if tubes[i]==nil then break end
+ i=i+1
+ until false
+ tubes[i]={}
+ tubes[i].pos=npos
+ tubes[i].vect=vect
+ end
+ end
+ end
+ if chests[1]==nil then--no chests found
+ if tubes[1]==nil then
+ return 0
+ else
+ local i=1
+ repeat
+ if tubes[i]==nil then break end
+ i=i+1
+ until false
+ n=meta:get_int("tubedir")+1
+ if n==i then
+ n=1
+ end
+ meta:set_int("tubedir",n)
+ velocity.x=tubes[n].vect.x
+ velocity.y=tubes[n].vect.y
+ velocity.z=tubes[n].vect.z
+ end
+ else
+ local i=1
+ repeat
+ if chests[i]==nil then break end
+ i=i+1
+ until false
+ n=meta:get_int("tubedir")+1
+ if n==i then
+ n=1
+ end
+ velocity.x=chests[n].vect.x
+ velocity.y=chests[n].vect.y
+ velocity.z=chests[n].vect.z
+ end
+ return 1
+end