From 109729cfb27efd816238f094a738a8ac23e83dda Mon Sep 17 00:00:00 2001 From: Vanessa Ezekowitz Date: Sun, 13 Jan 2013 21:45:03 -0500 Subject: 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. --- item_transport.lua | 331 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 item_transport.lua (limited to 'item_transport.lua') 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 -- cgit v1.2.3