2013-10-29 19:08:23 +01:00
|
|
|
dofile(pipeworks.modpath.."/compat.lua")
|
2013-01-14 18:36:28 +01:00
|
|
|
|
2013-07-19 07:36:55 +02:00
|
|
|
--and an extra function for getting the right-facing vector
|
|
|
|
local function facedir_to_right_dir(facedir)
|
|
|
|
|
|
|
|
--find the other directions
|
2013-11-26 06:23:14 +01:00
|
|
|
local backdir = minetest.facedir_to_dir(facedir)
|
2013-07-19 07:36:55 +02:00
|
|
|
local topdir = ({[0]={x=0, y=1, z=0},
|
|
|
|
{x=0, y=0, z=1},
|
|
|
|
{x=0, y=0, z=-1},
|
|
|
|
{x=1, y=0, z=0},
|
|
|
|
{x=-1, y=0, z=0},
|
|
|
|
{x=0, y=-1, z=0}})[math.floor(facedir/4)]
|
|
|
|
|
|
|
|
--return a cross product
|
|
|
|
return {x=topdir.y*backdir.z - backdir.y*topdir.z,
|
|
|
|
y=topdir.z*backdir.x - backdir.z*topdir.x,
|
|
|
|
z=topdir.x*backdir.y - backdir.x*topdir.y}
|
|
|
|
end
|
|
|
|
|
2013-01-14 18:36:28 +01:00
|
|
|
minetest.register_craftitem("pipeworks:filter", {
|
2013-01-14 03:45:03 +01:00
|
|
|
description = "Filter",
|
|
|
|
stack_max = 99,
|
|
|
|
})
|
|
|
|
|
Multiple updates:
1) Refactor autoplace,
There was a lot of redundant code and like a dozen unneccessary string
scans for every node next to every tube placed! I put it all into
indexed tables and loops instead of bizarre and unexplainable variable
names and copy and pasted code. There was also no support for notifying
a chest when an item has been taken from it by a filter, so I added
something for that.
I also thought it prudent to fall back on the
allow_metadata_inventory_take function should a special can_remove not
exist. In fact if can_insert doesn't exist, it calls
allow_metadata_inventory_put instead.
I also added a thing for allowing pipes to attach to nodes of other
modules, without having to hard code type all those node names into
autoplace.lua. Basically node.tube.collects(i,param2) and i is the
direction from the pipe and param2 is the param2 of what it's pointing
at.
I also abstracted the inscrutable correlation between i and
param2 by trial and error (and the paramwand mod) into understandable
functions. There was no pipeworks namespace so I created it, and put
these functions into pipeworks.collects (as distinguished from a
node.tube.collects function, which uses those functions)
And now it's too late to cart my old clothes to the thrift store,
dangit.
2) My "node.tube.collects" idea might be redundant with the
node.tube.connect_sides thing, though possibly more versatile so I'll
leave it in.
3) I was using node.tube.connects and fancy functions for checking if it's
the sides or top or whatnot, and this connect_side thing came in. This
should make both my way and the way using connect_side work.
Also removed some debugging cruft
2013-10-15 05:45:07 +02:00
|
|
|
local fakePlayer = {
|
|
|
|
get_player_name = function() return ":pipeworks" end,
|
|
|
|
-- any other player functions called by allow_metadata_inventory_take anywhere...
|
|
|
|
-- perhaps a custom metaclass that errors specially when fakePlayer.<property> is not found?
|
|
|
|
}
|
|
|
|
|
2013-12-15 20:41:03 +01:00
|
|
|
function pipeworks.tube_item(pos, item)
|
2013-12-15 11:35:11 +01:00
|
|
|
-- Take item in any format
|
|
|
|
local stack = ItemStack(item)
|
|
|
|
local obj = minetest.add_entity(pos, "pipeworks:tubed_item")
|
|
|
|
obj:get_luaentity():set_item(stack:to_string())
|
|
|
|
return obj
|
|
|
|
end
|
|
|
|
|
Multiple updates:
1) Refactor autoplace,
There was a lot of redundant code and like a dozen unneccessary string
scans for every node next to every tube placed! I put it all into
indexed tables and loops instead of bizarre and unexplainable variable
names and copy and pasted code. There was also no support for notifying
a chest when an item has been taken from it by a filter, so I added
something for that.
I also thought it prudent to fall back on the
allow_metadata_inventory_take function should a special can_remove not
exist. In fact if can_insert doesn't exist, it calls
allow_metadata_inventory_put instead.
I also added a thing for allowing pipes to attach to nodes of other
modules, without having to hard code type all those node names into
autoplace.lua. Basically node.tube.collects(i,param2) and i is the
direction from the pipe and param2 is the param2 of what it's pointing
at.
I also abstracted the inscrutable correlation between i and
param2 by trial and error (and the paramwand mod) into understandable
functions. There was no pipeworks namespace so I created it, and put
these functions into pipeworks.collects (as distinguished from a
node.tube.collects function, which uses those functions)
And now it's too late to cart my old clothes to the thrift store,
dangit.
2) My "node.tube.collects" idea might be redundant with the
node.tube.connect_sides thing, though possibly more versatile so I'll
leave it in.
3) I was using node.tube.connects and fancy functions for checking if it's
the sides or top or whatnot, and this connect_side thing came in. This
should make both my way and the way using connect_side work.
Also removed some debugging cruft
2013-10-15 05:45:07 +02:00
|
|
|
-- adding two tube functions
|
2014-01-11 08:04:11 +01:00
|
|
|
-- can_remove(pos,node,stack,dir) returns the maximum number of items of that stack that can be removed
|
Multiple updates:
1) Refactor autoplace,
There was a lot of redundant code and like a dozen unneccessary string
scans for every node next to every tube placed! I put it all into
indexed tables and loops instead of bizarre and unexplainable variable
names and copy and pasted code. There was also no support for notifying
a chest when an item has been taken from it by a filter, so I added
something for that.
I also thought it prudent to fall back on the
allow_metadata_inventory_take function should a special can_remove not
exist. In fact if can_insert doesn't exist, it calls
allow_metadata_inventory_put instead.
I also added a thing for allowing pipes to attach to nodes of other
modules, without having to hard code type all those node names into
autoplace.lua. Basically node.tube.collects(i,param2) and i is the
direction from the pipe and param2 is the param2 of what it's pointing
at.
I also abstracted the inscrutable correlation between i and
param2 by trial and error (and the paramwand mod) into understandable
functions. There was no pipeworks namespace so I created it, and put
these functions into pipeworks.collects (as distinguished from a
node.tube.collects function, which uses those functions)
And now it's too late to cart my old clothes to the thrift store,
dangit.
2) My "node.tube.collects" idea might be redundant with the
node.tube.connect_sides thing, though possibly more versatile so I'll
leave it in.
3) I was using node.tube.connects and fancy functions for checking if it's
the sides or top or whatnot, and this connect_side thing came in. This
should make both my way and the way using connect_side work.
Also removed some debugging cruft
2013-10-15 05:45:07 +02:00
|
|
|
-- remove_items(pos,node,stack,dir,count) removes count items and returns them
|
|
|
|
-- both optional w/ sensible defaults and fallback to normal allow_* function
|
|
|
|
-- XXX: possibly change insert_object to insert_item
|
|
|
|
|
|
|
|
-- sname = the current name to allow for, or nil if it allows anything
|
|
|
|
|
2013-12-15 11:35:11 +01:00
|
|
|
local function grabAndFire(frominv,frominvname,frompos,fromnode,sname,tube,idef,dir,all)
|
2013-12-21 10:16:58 +01:00
|
|
|
for spos,stack in ipairs(frominv:get_list(frominvname)) do
|
|
|
|
if (sname == nil and stack:get_name() ~= "") or stack:get_name() == sname then
|
2014-01-11 08:04:11 +01:00
|
|
|
local doRemove = stack:get_count()
|
2013-12-21 10:16:58 +01:00
|
|
|
if tube.can_remove then
|
|
|
|
doRemove = tube.can_remove(frompos, fromnode, stack, dir)
|
|
|
|
elseif idef.allow_metadata_inventory_take then
|
2014-05-18 16:41:37 +02:00
|
|
|
doRemove = idef.allow_metadata_inventory_take(frompos, frominvname,spos, stack, fakePlayer)
|
2013-12-21 10:16:58 +01:00
|
|
|
end
|
|
|
|
-- stupid lack of continue statements grumble
|
2014-01-11 08:04:11 +01:00
|
|
|
if doRemove > 0 then
|
2013-12-21 10:16:58 +01:00
|
|
|
local item
|
|
|
|
local count
|
|
|
|
if all then
|
2014-01-11 08:04:11 +01:00
|
|
|
count = math.min(stack:get_count(), doRemove)
|
2013-12-21 10:16:58 +01:00
|
|
|
else
|
|
|
|
count = 1
|
|
|
|
end
|
|
|
|
if tube.remove_items then
|
|
|
|
-- it could be the entire stack...
|
|
|
|
item = tube.remove_items(frompos, fromnode, stack, dir, count)
|
|
|
|
else
|
|
|
|
item = stack:take_item(count)
|
|
|
|
frominv:set_stack(frominvname, spos, stack)
|
|
|
|
if idef.on_metadata_inventory_take then
|
2014-05-18 16:41:37 +02:00
|
|
|
idef.on_metadata_inventory_take(frompos, frominvname, spos, item, fakePlayer)
|
2013-12-21 10:16:58 +01:00
|
|
|
end
|
|
|
|
end
|
2014-01-10 21:26:14 +01:00
|
|
|
local item1 = pipeworks.tube_item(vector.add(frompos, vector.multiply(dir, 1.4)), item)
|
|
|
|
item1:get_luaentity().start_pos = vector.add(frompos, dir)
|
2013-12-21 10:16:58 +01:00
|
|
|
item1:setvelocity(dir)
|
|
|
|
item1:setacceleration({x=0, y=0, z=0})
|
2013-12-24 14:29:33 +01:00
|
|
|
return true-- only fire one item, please
|
2013-12-21 10:16:58 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2013-12-24 14:29:33 +01:00
|
|
|
return false
|
Multiple updates:
1) Refactor autoplace,
There was a lot of redundant code and like a dozen unneccessary string
scans for every node next to every tube placed! I put it all into
indexed tables and loops instead of bizarre and unexplainable variable
names and copy and pasted code. There was also no support for notifying
a chest when an item has been taken from it by a filter, so I added
something for that.
I also thought it prudent to fall back on the
allow_metadata_inventory_take function should a special can_remove not
exist. In fact if can_insert doesn't exist, it calls
allow_metadata_inventory_put instead.
I also added a thing for allowing pipes to attach to nodes of other
modules, without having to hard code type all those node names into
autoplace.lua. Basically node.tube.collects(i,param2) and i is the
direction from the pipe and param2 is the param2 of what it's pointing
at.
I also abstracted the inscrutable correlation between i and
param2 by trial and error (and the paramwand mod) into understandable
functions. There was no pipeworks namespace so I created it, and put
these functions into pipeworks.collects (as distinguished from a
node.tube.collects function, which uses those functions)
And now it's too late to cart my old clothes to the thrift store,
dangit.
2) My "node.tube.collects" idea might be redundant with the
node.tube.connect_sides thing, though possibly more versatile so I'll
leave it in.
3) I was using node.tube.connects and fancy functions for checking if it's
the sides or top or whatnot, and this connect_side thing came in. This
should make both my way and the way using connect_side work.
Also removed some debugging cruft
2013-10-15 05:45:07 +02:00
|
|
|
end
|
|
|
|
|
2013-01-14 18:36:28 +01:00
|
|
|
minetest.register_node("pipeworks:filter", {
|
2013-01-28 18:41:14 +01:00
|
|
|
description = "Filter",
|
2013-01-20 17:53:17 +01:00
|
|
|
tiles = {"pipeworks_filter_top.png", "pipeworks_filter_top.png", "pipeworks_filter_output.png",
|
|
|
|
"pipeworks_filter_input.png", "pipeworks_filter_side.png", "pipeworks_filter_top.png"},
|
2013-01-14 03:45:03 +01:00
|
|
|
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)
|
2013-07-01 05:55:07 +02:00
|
|
|
local meta = minetest.get_meta(pos)
|
2013-01-14 03:45:03 +01:00
|
|
|
meta:set_string("formspec",
|
2013-04-03 12:16:33 +02:00
|
|
|
"invsize[8,6.5;]"..
|
|
|
|
"list[current_name;main;0,0;8,2;]"..
|
|
|
|
"list[current_player;main;0,2.5;8,4;]")
|
2013-01-14 03:45:03 +01:00
|
|
|
meta:set_string("infotext", "Filter")
|
|
|
|
local inv = meta:get_inventory()
|
2014-06-14 15:35:39 +02:00
|
|
|
inv:set_size("main", 8*2)
|
2013-01-14 03:45:03 +01:00
|
|
|
end,
|
|
|
|
can_dig = function(pos,player)
|
2013-07-01 05:55:07 +02:00
|
|
|
local meta = minetest.get_meta(pos);
|
2013-01-14 03:45:03 +01:00
|
|
|
local inv = meta:get_inventory()
|
|
|
|
return inv:is_empty("main")
|
|
|
|
end,
|
2013-04-01 19:21:39 +02:00
|
|
|
after_place_node = function(pos)
|
2013-12-15 08:53:10 +01:00
|
|
|
pipeworks.scan_for_tube_objects(pos)
|
2013-04-01 19:21:39 +02:00
|
|
|
end,
|
rewrote autoplacement code to make it more aware of filters,
autocrafter, nodebreaker, deployer, and made sure each item will only
initiate a connection to those sides which can accept such. Fixed
various autorouting bugs as I ran across them. Autorouting for various
devices is now:
filters: left and right sides only
nodebreaker, deployer: back only
autocrafter: all six sides
chests: top, bottom, left, right, back (not front)
furnace: bottom, left, right, back (not the top or front)
2013-06-24 03:36:13 +02:00
|
|
|
after_dig_node = function(pos)
|
2013-12-15 08:53:10 +01:00
|
|
|
pipeworks.scan_for_tube_objects(pos)
|
rewrote autoplacement code to make it more aware of filters,
autocrafter, nodebreaker, deployer, and made sure each item will only
initiate a connection to those sides which can accept such. Fixed
various autorouting bugs as I ran across them. Autorouting for various
devices is now:
filters: left and right sides only
nodebreaker, deployer: back only
autocrafter: all six sides
chests: top, bottom, left, right, back (not front)
furnace: bottom, left, right, back (not the top or front)
2013-06-24 03:36:13 +02:00
|
|
|
end,
|
2013-01-14 03:45:03 +01:00
|
|
|
mesecons={effector={action_on=function(pos,node)
|
|
|
|
minetest.registered_nodes[node.name].on_punch(pos,node,nil)
|
|
|
|
end}},
|
2013-07-19 07:36:55 +02:00
|
|
|
tube={connect_sides={right=1}},
|
2013-01-14 03:45:03 +01:00
|
|
|
on_punch = function (pos, node, puncher)
|
2013-12-21 10:16:58 +01:00
|
|
|
local meta = minetest.get_meta(pos);
|
|
|
|
local inv = meta:get_inventory()
|
|
|
|
local dir = facedir_to_right_dir(node.param2)
|
|
|
|
local frompos = {x=pos.x - dir.x, y=pos.y - dir.y, z=pos.z - dir.z}
|
|
|
|
local fromnode=minetest.get_node(frompos)
|
|
|
|
if not fromnode then return end
|
|
|
|
local idef = minetest.registered_nodes[fromnode.name]
|
|
|
|
-- assert(idef)
|
|
|
|
local tube = idef.tube
|
|
|
|
if not (tube and tube.input_inventory) then
|
|
|
|
return
|
2013-01-14 03:45:03 +01:00
|
|
|
end
|
2014-02-10 20:18:18 +01:00
|
|
|
if tube.before_filter then
|
|
|
|
tube.before_filter(frompos)
|
|
|
|
end
|
2013-12-21 10:16:58 +01:00
|
|
|
local frommeta = minetest.get_meta(frompos)
|
|
|
|
local frominv = frommeta:get_inventory()
|
2014-05-23 19:49:35 +02:00
|
|
|
|
|
|
|
local function from_inventory(frominvname)
|
|
|
|
local sname
|
|
|
|
for _,filter in ipairs(inv:get_list("main")) do
|
|
|
|
sname = filter:get_name()
|
|
|
|
if sname ~= "" then
|
|
|
|
-- XXX: that's a lot of parameters
|
|
|
|
if grabAndFire(frominv, frominvname, frompos, fromnode, sname, tube, idef, dir) then
|
|
|
|
return true
|
|
|
|
end
|
2014-02-10 20:18:18 +01:00
|
|
|
end
|
2013-12-21 10:16:58 +01:00
|
|
|
end
|
2014-05-23 19:49:35 +02:00
|
|
|
if inv:is_empty("main") then
|
2014-07-02 12:42:33 +02:00
|
|
|
if grabAndFire(frominv, frominvname, frompos, fromnode, nil, tube, idef, dir) then
|
|
|
|
return true
|
|
|
|
end
|
2014-05-23 19:49:35 +02:00
|
|
|
end
|
|
|
|
return false
|
2013-12-21 10:16:58 +01:00
|
|
|
end
|
2014-05-23 19:49:35 +02:00
|
|
|
|
|
|
|
if type(tube.input_inventory) == "table" then
|
|
|
|
for _, i in ipairs(tube.input_inventory) do
|
|
|
|
if from_inventory(i) then -- fired an item
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else
|
|
|
|
from_inventory(tube.input_inventory)
|
2014-01-10 21:26:14 +01:00
|
|
|
end
|
2014-05-23 19:49:35 +02:00
|
|
|
|
2014-02-10 20:18:18 +01:00
|
|
|
if tube.after_filter then
|
|
|
|
tube.after_filter(frompos)
|
|
|
|
end
|
2013-12-21 10:16:58 +01:00
|
|
|
end,
|
2013-01-14 03:45:03 +01:00
|
|
|
})
|
|
|
|
|
2013-01-28 18:41:14 +01:00
|
|
|
minetest.register_craftitem("pipeworks:mese_filter", {
|
|
|
|
description = "Mese filter",
|
|
|
|
stack_max = 99,
|
|
|
|
})
|
|
|
|
|
|
|
|
minetest.register_node("pipeworks:mese_filter", {
|
|
|
|
description = "Mese filter",
|
|
|
|
tiles = {"pipeworks_mese_filter_top.png", "pipeworks_mese_filter_top.png", "pipeworks_mese_filter_output.png",
|
|
|
|
"pipeworks_mese_filter_input.png", "pipeworks_mese_filter_side.png", "pipeworks_mese_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)
|
2013-07-01 05:55:07 +02:00
|
|
|
local meta = minetest.get_meta(pos)
|
2013-01-28 18:41:14 +01:00
|
|
|
meta:set_string("formspec",
|
2013-04-03 12:16:33 +02:00
|
|
|
"invsize[8,6.5;]"..
|
|
|
|
"list[current_name;main;0,0;8,2;]"..
|
|
|
|
"list[current_player;main;0,2.5;8,4;]")
|
2013-01-28 18:41:14 +01:00
|
|
|
meta:set_string("infotext", "Mese filter")
|
|
|
|
local inv = meta:get_inventory()
|
2014-06-14 15:35:39 +02:00
|
|
|
inv:set_size("main", 8*2)
|
2013-01-28 18:41:14 +01:00
|
|
|
end,
|
|
|
|
can_dig = function(pos,player)
|
2013-07-01 05:55:07 +02:00
|
|
|
local meta = minetest.get_meta(pos);
|
2013-01-28 18:41:14 +01:00
|
|
|
local inv = meta:get_inventory()
|
|
|
|
return inv:is_empty("main")
|
|
|
|
end,
|
rewrote autoplacement code to make it more aware of filters,
autocrafter, nodebreaker, deployer, and made sure each item will only
initiate a connection to those sides which can accept such. Fixed
various autorouting bugs as I ran across them. Autorouting for various
devices is now:
filters: left and right sides only
nodebreaker, deployer: back only
autocrafter: all six sides
chests: top, bottom, left, right, back (not front)
furnace: bottom, left, right, back (not the top or front)
2013-06-24 03:36:13 +02:00
|
|
|
after_place_node = function(pos)
|
2013-12-15 08:53:10 +01:00
|
|
|
pipeworks.scan_for_tube_objects(pos)
|
rewrote autoplacement code to make it more aware of filters,
autocrafter, nodebreaker, deployer, and made sure each item will only
initiate a connection to those sides which can accept such. Fixed
various autorouting bugs as I ran across them. Autorouting for various
devices is now:
filters: left and right sides only
nodebreaker, deployer: back only
autocrafter: all six sides
chests: top, bottom, left, right, back (not front)
furnace: bottom, left, right, back (not the top or front)
2013-06-24 03:36:13 +02:00
|
|
|
end,
|
|
|
|
after_dig_node = function(pos)
|
2013-12-15 08:53:10 +01:00
|
|
|
pipeworks.scan_for_tube_objects(pos)
|
rewrote autoplacement code to make it more aware of filters,
autocrafter, nodebreaker, deployer, and made sure each item will only
initiate a connection to those sides which can accept such. Fixed
various autorouting bugs as I ran across them. Autorouting for various
devices is now:
filters: left and right sides only
nodebreaker, deployer: back only
autocrafter: all six sides
chests: top, bottom, left, right, back (not front)
furnace: bottom, left, right, back (not the top or front)
2013-06-24 03:36:13 +02:00
|
|
|
end,
|
2013-01-28 18:41:14 +01:00
|
|
|
mesecons={effector={action_on=function(pos,node)
|
|
|
|
minetest.registered_nodes[node.name].on_punch(pos,node,nil)
|
|
|
|
end}},
|
2013-07-19 07:36:55 +02:00
|
|
|
tube={connect_sides={right=1}},
|
2013-01-28 18:41:14 +01:00
|
|
|
on_punch = function (pos, node, puncher)
|
2013-12-21 10:16:58 +01:00
|
|
|
local meta = minetest.get_meta(pos);
|
|
|
|
local inv = meta:get_inventory()
|
|
|
|
local dir = facedir_to_right_dir(node.param2)
|
|
|
|
local frompos = {x=pos.x - dir.x, y=pos.y - dir.y, z=pos.z - dir.z}
|
|
|
|
local fromnode=minetest.get_node(frompos)
|
|
|
|
local idef = minetest.registered_nodes[fromnode.name]
|
|
|
|
-- assert(idef)
|
|
|
|
local tube = idef.tube
|
|
|
|
if not (tube and tube.input_inventory) then
|
|
|
|
return
|
2013-01-28 18:41:14 +01:00
|
|
|
end
|
2014-05-23 19:49:35 +02:00
|
|
|
|
|
|
|
if tube.before_filter then
|
|
|
|
tube.before_filter(frompos)
|
|
|
|
end
|
2013-12-21 10:16:58 +01:00
|
|
|
local frommeta = minetest.get_meta(frompos)
|
|
|
|
local frominv = frommeta:get_inventory()
|
2014-05-23 19:49:35 +02:00
|
|
|
|
|
|
|
local function from_inventory(frominvname)
|
|
|
|
local sname
|
|
|
|
for _,filter in ipairs(inv:get_list("main")) do
|
|
|
|
sname = filter:get_name()
|
|
|
|
if sname ~= "" then
|
|
|
|
-- XXX: that's a lot of parameters
|
|
|
|
if grabAndFire(frominv, frominvname, frompos, fromnode, sname, tube, idef, dir, true) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if inv:is_empty("main") then
|
2014-07-02 12:42:33 +02:00
|
|
|
if grabAndFire(frominv, frominvname, frompos, fromnode, nil, tube, idef, dir, true) then
|
|
|
|
return true
|
|
|
|
end
|
2014-05-23 19:49:35 +02:00
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
if type(tube.input_inventory) == "table" then
|
|
|
|
for _, i in ipairs(tube.input_inventory) do
|
|
|
|
if from_inventory(i) then -- fired an item
|
|
|
|
break
|
|
|
|
end
|
2013-12-21 10:16:58 +01:00
|
|
|
end
|
2014-05-23 19:49:35 +02:00
|
|
|
else
|
|
|
|
from_inventory(tube.input_inventory)
|
2013-12-21 10:16:58 +01:00
|
|
|
end
|
2014-05-23 19:49:35 +02:00
|
|
|
|
|
|
|
if tube.after_filter then
|
|
|
|
tube.after_filter(frompos)
|
2013-12-21 10:16:58 +01:00
|
|
|
end
|
|
|
|
end,
|
2013-01-28 18:41:14 +01:00
|
|
|
})
|
2013-01-14 03:45:03 +01:00
|
|
|
|
2013-06-05 15:54:03 +02:00
|
|
|
local function roundpos(pos)
|
|
|
|
return {x=math.floor(pos.x+0.5),y=math.floor(pos.y+0.5),z=math.floor(pos.z+0.5)}
|
|
|
|
end
|
|
|
|
|
2013-12-15 11:35:11 +01:00
|
|
|
local function addVect(pos,vect)
|
|
|
|
return {x=pos.x+vect.x,y=pos.y+vect.y,z=pos.z+vect.z}
|
|
|
|
end
|
|
|
|
|
2013-12-15 11:53:11 +01:00
|
|
|
local 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}}
|
2013-12-15 11:35:11 +01:00
|
|
|
|
2013-12-21 10:16:58 +01:00
|
|
|
function pipeworks.notvel(tbl, vel)
|
2013-12-15 11:35:11 +01:00
|
|
|
local tbl2={}
|
|
|
|
for _,val in ipairs(tbl) do
|
2013-12-21 10:16:58 +01:00
|
|
|
if val.x ~= -vel.x or val.y ~= -vel.y or val.z ~= -vel.z then table.insert(tbl2, val) end
|
2013-12-15 11:35:11 +01:00
|
|
|
end
|
|
|
|
return tbl2
|
|
|
|
end
|
|
|
|
|
2013-12-21 10:16:58 +01:00
|
|
|
local function go_next(pos, velocity, stack)
|
2013-12-21 08:46:55 +01:00
|
|
|
local chests = {}
|
|
|
|
local tubes = {}
|
|
|
|
local cnode = minetest.get_node(pos)
|
|
|
|
local cmeta = minetest.get_meta(pos)
|
2013-12-15 11:35:11 +01:00
|
|
|
local n
|
|
|
|
local can_go
|
2013-12-21 10:16:58 +01:00
|
|
|
local speed = math.abs(velocity.x + velocity.y + velocity.z)
|
|
|
|
local vel = {x = velocity.x/speed, y = velocity.y/speed, z = velocity.z/speed,speed=speed}
|
2013-12-21 08:46:55 +01:00
|
|
|
if speed >= 4.1 then
|
|
|
|
speed = 4
|
|
|
|
elseif speed >= 1.1 then
|
|
|
|
speed = speed-0.1
|
2013-12-15 11:35:11 +01:00
|
|
|
else
|
2013-12-21 08:46:55 +01:00
|
|
|
speed = 1
|
2013-12-15 11:35:11 +01:00
|
|
|
end
|
2014-04-13 09:25:17 +02:00
|
|
|
vel.speed = speed
|
2013-12-15 11:35:11 +01:00
|
|
|
if minetest.registered_nodes[cnode.name] and minetest.registered_nodes[cnode.name].tube and minetest.registered_nodes[cnode.name].tube.can_go then
|
2013-12-21 10:16:58 +01:00
|
|
|
can_go = minetest.registered_nodes[cnode.name].tube.can_go(pos, cnode, vel, stack)
|
2013-12-15 11:35:11 +01:00
|
|
|
else
|
2013-12-21 10:16:58 +01:00
|
|
|
can_go = pipeworks.notvel(adjlist, vel)
|
2013-12-15 11:35:11 +01:00
|
|
|
end
|
2013-12-15 12:10:03 +01:00
|
|
|
local meta = nil
|
2013-12-15 11:35:11 +01:00
|
|
|
for _,vect in ipairs(can_go) do
|
2013-12-21 08:46:55 +01:00
|
|
|
local npos = addVect(pos,vect)
|
|
|
|
local node = minetest.get_node(npos)
|
|
|
|
local tube_receiver = minetest.get_item_group(node.name,"tubedevice_receiver")
|
|
|
|
meta = minetest.get_meta(npos)
|
|
|
|
local tubelike = meta:get_int("tubelike")
|
|
|
|
if tube_receiver == 1 then
|
2013-12-15 11:35:11 +01:00
|
|
|
if minetest.registered_nodes[node.name].tube and
|
|
|
|
minetest.registered_nodes[node.name].tube.can_insert and
|
2013-12-21 10:16:58 +01:00
|
|
|
minetest.registered_nodes[node.name].tube.can_insert(npos, node, stack, vect) then
|
2013-12-21 08:46:55 +01:00
|
|
|
local i = #chests + 1
|
2013-12-21 10:16:58 +01:00
|
|
|
chests[i] = {}
|
|
|
|
chests[i].pos = npos
|
|
|
|
chests[i].vect = vect
|
2013-12-15 11:35:11 +01:00
|
|
|
end
|
2013-12-21 08:46:55 +01:00
|
|
|
elseif tubelike == 1 then
|
|
|
|
local i = #tubes + 1
|
2013-12-21 10:16:58 +01:00
|
|
|
tubes[i] = {}
|
|
|
|
tubes[i].pos = npos
|
|
|
|
tubes[i].vect = vect
|
2013-12-15 11:35:11 +01:00
|
|
|
end
|
|
|
|
end
|
2013-12-21 08:46:55 +01:00
|
|
|
if chests[1] == nil then--no chests found
|
|
|
|
if tubes[1] == nil then
|
2013-12-15 11:35:11 +01:00
|
|
|
return 0
|
|
|
|
else
|
2013-12-21 10:16:58 +01:00
|
|
|
n = (cmeta:get_int("tubedir")%(#tubes)) + 1
|
2013-12-15 11:35:11 +01:00
|
|
|
if pipeworks.enable_cyclic_mode then
|
2013-12-21 10:16:58 +01:00
|
|
|
cmeta:set_int("tubedir",n)
|
2013-12-15 11:35:11 +01:00
|
|
|
end
|
2013-12-21 08:46:55 +01:00
|
|
|
velocity.x = tubes[n].vect.x*vel.speed
|
|
|
|
velocity.y = tubes[n].vect.y*vel.speed
|
|
|
|
velocity.z = tubes[n].vect.z*vel.speed
|
2013-12-15 11:35:11 +01:00
|
|
|
end
|
|
|
|
else
|
2013-12-21 10:16:58 +01:00
|
|
|
n = (cmeta:get_int("tubedir")%(#chests))+1
|
2013-12-15 11:35:11 +01:00
|
|
|
if pipeworks.enable_cyclic_mode then
|
2013-12-21 10:16:58 +01:00
|
|
|
cmeta:set_int("tubedir",n)
|
2013-12-15 11:35:11 +01:00
|
|
|
end
|
2013-12-21 08:46:55 +01:00
|
|
|
velocity.x = chests[n].vect.x*speed
|
|
|
|
velocity.y = chests[n].vect.y*speed
|
|
|
|
velocity.z = chests[n].vect.z*speed
|
2013-12-15 11:35:11 +01:00
|
|
|
end
|
|
|
|
return 1
|
|
|
|
end
|
|
|
|
|
2013-01-14 18:36:28 +01:00
|
|
|
minetest.register_entity("pipeworks:tubed_item", {
|
2013-01-14 03:45:03 +01:00
|
|
|
initial_properties = {
|
|
|
|
hp_max = 1,
|
|
|
|
physical = false,
|
2013-06-21 08:56:21 +02:00
|
|
|
-- collisionbox = {0,0,0,0,0,0},
|
2014-07-01 18:42:52 +02:00
|
|
|
collisionbox = {0.1, 0.1, 0.1, 0.1, 0.1, 0.1},
|
2014-07-03 03:22:55 +02:00
|
|
|
visual = "wielditem",
|
|
|
|
visual_size = {x = 0.15, y = 0.15},
|
2013-01-14 03:45:03 +01:00
|
|
|
textures = {""},
|
2014-07-01 18:42:52 +02:00
|
|
|
spritediv = {x = 1, y = 1},
|
|
|
|
initial_sprite_basepos = {x = 0, y = 0},
|
2013-01-14 03:45:03 +01:00
|
|
|
is_visible = false,
|
2014-07-01 18:42:52 +02:00
|
|
|
start_pos = {},
|
|
|
|
route = {},
|
|
|
|
removed = false
|
2013-01-14 03:45:03 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
itemstring = '',
|
|
|
|
physical_state = false,
|
|
|
|
|
|
|
|
set_item = function(self, itemstring)
|
|
|
|
self.itemstring = itemstring
|
|
|
|
local stack = ItemStack(itemstring)
|
2014-07-03 03:22:55 +02:00
|
|
|
self.object:set_properties({
|
2013-01-14 03:45:03 +01:00
|
|
|
is_visible = true,
|
2014-07-03 03:22:55 +02:00
|
|
|
textures = { stack:get_name() },
|
|
|
|
})
|
|
|
|
local def = stack:get_definition()
|
|
|
|
self.object:setyaw((def and def.type == "node") and 0 or math.pi * 0.25)
|
2013-01-14 03:45:03 +01:00
|
|
|
end,
|
|
|
|
|
|
|
|
get_staticdata = function(self)
|
2014-07-01 18:42:52 +02:00
|
|
|
if self.start_pos == nil or self.removed then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
local velocity = self.object:getvelocity()
|
2014-04-13 09:25:17 +02:00
|
|
|
self.object:setpos(self.start_pos)
|
|
|
|
return minetest.serialize({
|
2014-07-01 18:42:52 +02:00
|
|
|
itemstring = self.itemstring,
|
|
|
|
velocity = velocity,
|
|
|
|
start_pos = self.start_pos
|
2014-04-13 09:25:17 +02:00
|
|
|
})
|
2013-01-14 03:45:03 +01:00
|
|
|
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,
|
2014-07-01 18:42:52 +02:00
|
|
|
|
|
|
|
remove = function(self)
|
|
|
|
self.object:remove()
|
|
|
|
self.removed = true
|
|
|
|
self.itemstring = ''
|
|
|
|
end,
|
2013-01-14 03:45:03 +01:00
|
|
|
|
|
|
|
on_step = function(self, dtime)
|
2014-07-01 18:42:52 +02:00
|
|
|
if self.removed then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
if self.start_pos == nil then
|
2014-04-13 09:25:17 +02:00
|
|
|
local pos = self.object:getpos()
|
2014-07-01 18:42:52 +02:00
|
|
|
self.start_pos = roundpos(pos)
|
2014-04-13 09:25:17 +02:00
|
|
|
end
|
2013-06-05 15:54:03 +02:00
|
|
|
local pos = self.object:getpos()
|
2014-04-13 09:25:17 +02:00
|
|
|
local node = minetest.get_node(pos)
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
|
|
local tubelike = meta:get_int("tubelike")
|
|
|
|
local stack = ItemStack(self.itemstring)
|
|
|
|
local drop_pos = nil
|
2013-01-14 03:45:03 +01:00
|
|
|
|
2014-07-01 18:42:52 +02:00
|
|
|
local velocity = self.object:getvelocity()
|
2013-01-14 18:36:28 +01:00
|
|
|
|
2014-04-13 09:25:17 +02:00
|
|
|
if velocity == nil then return end
|
2013-01-14 18:36:28 +01:00
|
|
|
|
2014-04-13 09:25:17 +02:00
|
|
|
local velocitycopy = {x = velocity.x, y = velocity.y, z = velocity.z}
|
|
|
|
|
|
|
|
local moved = false
|
2014-07-01 18:42:52 +02:00
|
|
|
local speed = math.abs(velocity.x + velocity.y + velocity.z)
|
|
|
|
local vel = {x = velocity.x / speed, y = velocity.y / speed, z = velocity.z / speed, speed = speed}
|
2014-04-13 09:25:17 +02:00
|
|
|
|
|
|
|
if math.abs(vel.x) == 1 then
|
2014-07-01 18:42:52 +02:00
|
|
|
local next_node = math.abs(pos.x - self.start_pos.x)
|
2014-04-13 09:25:17 +02:00
|
|
|
if next_node >= 1 then
|
2014-07-01 18:42:52 +02:00
|
|
|
self.start_pos.x = self.start_pos.x + vel.x
|
2014-04-13 09:25:17 +02:00
|
|
|
moved = true
|
|
|
|
end
|
|
|
|
elseif math.abs(vel.y) == 1 then
|
2014-07-01 18:42:52 +02:00
|
|
|
local next_node = math.abs(pos.y - self.start_pos.y)
|
|
|
|
if next_node >= 1 then
|
|
|
|
self.start_pos.y = self.start_pos.y + vel.y
|
|
|
|
moved = true
|
|
|
|
end
|
2014-04-13 09:25:17 +02:00
|
|
|
elseif math.abs(vel.z) == 1 then
|
2014-07-01 18:42:52 +02:00
|
|
|
local next_node = math.abs(pos.z - self.start_pos.z)
|
2014-04-13 09:25:17 +02:00
|
|
|
if next_node >= 1 then
|
2014-07-01 18:42:52 +02:00
|
|
|
self.start_pos.z = self.start_pos.z + vel.z
|
2014-04-13 09:25:17 +02:00
|
|
|
moved = true
|
|
|
|
end
|
2013-01-14 18:36:28 +01:00
|
|
|
end
|
2014-04-13 09:25:17 +02:00
|
|
|
|
|
|
|
local sposcopy = {x = self.start_pos.x, y = self.start_pos.y, z = self.start_pos.z}
|
|
|
|
|
|
|
|
node = minetest.get_node(self.start_pos)
|
|
|
|
if moved and minetest.get_item_group(node.name, "tubedevice_receiver") == 1 then
|
|
|
|
local leftover = nil
|
|
|
|
if minetest.registered_nodes[node.name].tube and minetest.registered_nodes[node.name].tube.insert_object then
|
|
|
|
leftover = minetest.registered_nodes[node.name].tube.insert_object(self.start_pos, node, stack, vel)
|
|
|
|
else
|
|
|
|
leftover = stack
|
|
|
|
end
|
|
|
|
if leftover:is_empty() then
|
2014-07-01 18:42:52 +02:00
|
|
|
self:remove()
|
2014-04-13 09:25:17 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
velocity.x = -velocity.x
|
|
|
|
velocity.y = -velocity.y
|
|
|
|
velocity.z = -velocity.z
|
|
|
|
self.object:setvelocity(velocity)
|
|
|
|
self:set_item(leftover:to_string())
|
2013-01-14 03:45:03 +01:00
|
|
|
return
|
2013-01-14 18:36:28 +01:00
|
|
|
end
|
2014-04-13 09:25:17 +02:00
|
|
|
|
|
|
|
if moved then
|
|
|
|
if go_next (self.start_pos, velocity, stack) == 0 then
|
|
|
|
drop_pos = minetest.find_node_near(vector.add(self.start_pos, velocity), 1, "air")
|
|
|
|
if drop_pos then
|
|
|
|
minetest.item_drop(stack, "", drop_pos)
|
2014-07-01 18:42:52 +02:00
|
|
|
self:remove()
|
2014-04-13 09:25:17 +02:00
|
|
|
end
|
2013-01-14 03:45:03 +01:00
|
|
|
end
|
|
|
|
end
|
2014-04-13 09:25:17 +02:00
|
|
|
|
|
|
|
if velocity.x~=velocitycopy.x or velocity.y~=velocitycopy.y or velocity.z~=velocitycopy.z or
|
|
|
|
self.start_pos.x~=sposcopy.x or self.start_pos.y~=sposcopy.y or self.start_pos.z~=sposcopy.z then
|
|
|
|
self.object:setpos(self.start_pos)
|
|
|
|
self.object:setvelocity(velocity)
|
|
|
|
end
|
2013-01-14 03:45:03 +01:00
|
|
|
end
|
|
|
|
})
|
|
|
|
|
2014-01-03 13:29:38 +01:00
|
|
|
if minetest.get_modpath("mesecons_mvps") ~= nil then
|
2014-05-23 19:49:35 +02:00
|
|
|
local function add_table(table,toadd)
|
|
|
|
local i = 1
|
|
|
|
while true do
|
|
|
|
o = table[i]
|
|
|
|
if o == toadd then return end
|
|
|
|
if o == nil then break end
|
|
|
|
i = i+1
|
|
|
|
end
|
|
|
|
table[i] = toadd
|
|
|
|
end
|
2014-01-03 13:29:38 +01:00
|
|
|
mesecon:register_mvps_unmov("pipeworks:tubed_item")
|
|
|
|
mesecon:register_on_mvps_move(function(moved_nodes)
|
|
|
|
local objects_to_move = {}
|
|
|
|
for _, n in ipairs(moved_nodes) do
|
|
|
|
local objects = minetest.get_objects_inside_radius(n.oldpos, 1)
|
|
|
|
for _, obj in ipairs(objects) do
|
|
|
|
local entity = obj:get_luaentity()
|
|
|
|
if entity and entity.name == "pipeworks:tubed_item" then
|
2014-05-23 19:49:35 +02:00
|
|
|
--objects_to_move[#objects_to_move+1] = obj
|
|
|
|
add_table(objects_to_move, obj)
|
2014-01-03 13:29:38 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if #objects_to_move > 0 then
|
|
|
|
local dir = vector.subtract(moved_nodes[1].pos, moved_nodes[1].oldpos)
|
|
|
|
for _, obj in ipairs(objects_to_move) do
|
|
|
|
local entity = obj:get_luaentity()
|
|
|
|
obj:setpos(vector.add(obj:getpos(), dir))
|
|
|
|
entity.start_pos = vector.add(entity.start_pos, dir)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
end
|