1
0
mirror of https://github.com/mt-mods/pipeworks.git synced 2024-11-18 00:08:28 +01:00
pipeworks/item_transport.lua

531 lines
16 KiB
Lua
Raw Normal View History

dofile(pipeworks.modpath.."/compat.lua")
--and an extra function for getting the right-facing vector
local function facedir_to_right_dir(facedir)
--find the other directions
local backdir = minetest.facedir_to_dir(facedir)
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
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?
}
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
-- 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
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
if doRemove > 0 then
2013-12-21 10:16:58 +01:00
local item
local count
if all then
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
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})
return true-- only fire one item, please
2013-12-21 10:16:58 +01:00
end
end
end
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
minetest.register_node("pipeworks:filter", {
description = "Itemwise Filter",
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"},
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.get_meta(pos)
meta:set_string("formspec",
"invsize[8,6.5;]"..
"list[current_name;main;0,0;8,2;]"..
"list[current_player;main;0,2.5;8,4;]")
meta:set_string("infotext", "Itemwise Filter")
local inv = meta:get_inventory()
2014-06-14 15:35:39 +02:00
inv:set_size("main", 8*2)
end,
can_dig = function(pos,player)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
return inv:is_empty("main")
end,
after_place_node = function(pos)
pipeworks.scan_for_tube_objects(pos)
end,
after_dig_node = function(pos)
pipeworks.scan_for_tube_objects(pos)
end,
mesecons={effector={action_on=function(pos,node)
minetest.registered_nodes[node.name].on_punch(pos,node,nil)
end}},
tube={connect_sides={right=1}},
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
end
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()
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
end
2013-12-21 10:16:58 +01:00
end
if inv:is_empty("main") then
if grabAndFire(frominv, frominvname, frompos, fromnode, nil, tube, idef, dir) then
return true
end
end
return false
2013-12-21 10:16:58 +01:00
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
end
else
from_inventory(tube.input_inventory)
end
if tube.after_filter then
tube.after_filter(frompos)
end
2013-12-21 10:16:58 +01:00
end,
})
2013-01-28 18:41:14 +01:00
minetest.register_node("pipeworks:mese_filter", {
description = "Stackwise Filter",
2013-01-28 18:41:14 +01:00
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)
local meta = minetest.get_meta(pos)
2013-01-28 18:41:14 +01:00
meta:set_string("formspec",
"invsize[8,6.5;]"..
"list[current_name;main;0,0;8,2;]"..
"list[current_player;main;0,2.5;8,4;]")
meta:set_string("infotext", "Stackwise Filter")
2013-01-28 18:41:14 +01:00
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)
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,
after_place_node = function(pos)
pipeworks.scan_for_tube_objects(pos)
end,
after_dig_node = function(pos)
pipeworks.scan_for_tube_objects(pos)
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}},
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
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()
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
if grabAndFire(frominv, frominvname, frompos, fromnode, nil, tube, idef, dir, true) then
return true
end
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
else
from_inventory(tube.input_inventory)
2013-12-21 10:16:58 +01:00
end
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-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
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
minetest.register_entity("pipeworks:tubed_item", {
initial_properties = {
hp_max = 1,
physical = false,
-- collisionbox = {0,0,0,0,0,0},
collisionbox = {0.1, 0.1, 0.1, 0.1, 0.1, 0.1},
visual = "wielditem",
visual_size = {x = 0.15, y = 0.15},
textures = {""},
spritediv = {x = 1, y = 1},
initial_sprite_basepos = {x = 0, y = 0},
is_visible = false,
start_pos = {},
route = {},
removed = false
},
itemstring = '',
physical_state = false,
set_item = function(self, itemstring)
self.itemstring = itemstring
local stack = ItemStack(itemstring)
self.object:set_properties({
is_visible = true,
textures = { stack:get_name() },
})
local def = stack:get_definition()
self.object:setyaw((def and def.type == "node") and 0 or math.pi * 0.25)
end,
get_staticdata = function(self)
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({
itemstring = self.itemstring,
velocity = velocity,
start_pos = self.start_pos
2014-04-13 09:25:17 +02: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,
remove = function(self)
self.object:remove()
self.removed = true
self.itemstring = ''
end,
on_step = function(self, dtime)
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()
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
local velocity = self.object:getvelocity()
2014-04-13 09:25:17 +02:00
if velocity == nil then return end
2014-04-13 09:25:17 +02:00
local velocitycopy = {x = velocity.x, y = velocity.y, z = velocity.z}
local moved = false
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
local next_node = math.abs(pos.x - self.start_pos.x)
2014-04-13 09:25:17 +02:00
if next_node >= 1 then
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
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
local next_node = math.abs(pos.z - self.start_pos.z)
2014-04-13 09:25:17 +02:00
if next_node >= 1 then
self.start_pos.z = self.start_pos.z + vel.z
2014-04-13 09:25:17 +02:00
moved = true
end
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
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())
return
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)
self:remove()
2014-04-13 09:25:17 +02:00
end
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
end
})
2014-01-03 13:29:38 +01:00
if minetest.get_modpath("mesecons_mvps") ~= nil then
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
--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