pipeworks/item_transport.lua

480 lines
15 KiB
Lua
Raw Normal View History

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)
error("obsolete pipeworks.tube_item() called; change caller to use pipeworks.tube_inject_item() instead")
end
function pipeworks.tube_inject_item(pos, start_pos, velocity, item)
2013-12-15 11:35:11 +01:00
-- Take item in any format
local stack = ItemStack(item)
2014-08-14 16:22:03 +02:00
local obj = luaentity.add_entity(pos, "pipeworks:tubed_item")
obj:set_item(stack:to_string())
obj.start_pos = vector.new(start_pos)
obj:setvelocity(velocity)
--obj:set_color("red") -- todo: this is test-only code
2013-12-15 11:35:11 +01:00
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
local function set_filter_infotext(data, meta)
local infotext = data.wise_desc.." Filter-Injector"
if meta:get_int("slotseq_mode") == 2 then
infotext = infotext .. " (slot #"..meta:get_int("slotseq_index").." next)"
end
meta:set_string("infotext", infotext)
end
local function set_filter_formspec(data, meta)
local itemname = data.wise_desc.." Filter-Injector"
local formspec = "size[8,8.5]"..
"item_image[0,0;1,1;pipeworks:"..data.name.."]"..
"label[1,0;"..minetest.formspec_escape(itemname).."]"..
"label[0,1;Prefer item types:]"..
2014-08-14 16:22:03 +02:00
"list[current_name;main;0,1.5;8,2;]"..
fs_helpers.cycling_button(meta, "button[0,3.5;4,1", "slotseq_mode",
{"Sequence slots by Priority",
"Sequence slots Randomly",
"Sequence slots by Rotation"})..
"list[current_player;main;0,4.5;8,4;]"
meta:set_string("formspec", formspec)
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
2014-08-14 16:22:03 +02:00
-- todo SOON: this function has *way too many* parameters
local function grabAndFire(data,slotseq_mode,filtmeta,frominv,frominvname,frompos,fromnode,filtername,fromtube,fromdef,dir,all)
local sposes = {}
2013-12-21 10:16:58 +01:00
for spos,stack in ipairs(frominv:get_list(frominvname)) do
local matches
if filtername == "" then
matches = stack:get_name() ~= ""
else
matches = stack:get_name() == filtername
end
if matches then table.insert(sposes, spos) end
end
if #sposes == 0 then return false end
if slotseq_mode == 1 then
for i = #sposes, 2, -1 do
local j = math.random(i)
local t = sposes[j]
sposes[j] = sposes[i]
sposes[i] = t
end
elseif slotseq_mode == 2 then
local headpos = filtmeta:get_int("slotseq_index")
table.sort(sposes, function (a, b)
if a >= headpos then
if b < headpos then return true end
else
if b >= headpos then return false end
end
return a < b
end)
end
for _, spos in ipairs(sposes) do
local stack = frominv:get_stack(frominvname, spos)
local doRemove = stack:get_count()
if fromtube.can_remove then
doRemove = fromtube.can_remove(frompos, fromnode, stack, dir)
elseif fromdef.allow_metadata_inventory_take then
doRemove = fromdef.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
if slotseq_mode == 2 then
local nextpos = spos + 1
if nextpos > frominv:get_size(frominvname) then
nextpos = 1
end
filtmeta:set_int("slotseq_index", nextpos)
set_filter_infotext(data, filtmeta)
end
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 fromtube.remove_items then
2013-12-21 10:16:58 +01:00
-- it could be the entire stack...
item = fromtube.remove_items(frompos, fromnode, stack, dir, count)
2013-12-21 10:16:58 +01:00
else
item = stack:take_item(count)
frominv:set_stack(frominvname, spos, stack)
if fromdef.on_metadata_inventory_take then
fromdef.on_metadata_inventory_take(frompos, frominvname, spos, item, fakePlayer)
2013-12-21 10:16:58 +01:00
end
end
2014-08-14 16:22:03 +02:00
local pos = vector.add(frompos, vector.multiply(dir, 1.4))
local start_pos = vector.add(frompos, dir)
local item1 = pipeworks.tube_inject_item(pos, start_pos, dir, item)
return true-- only fire one item, please
2013-12-21 10:16:58 +01:00
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
local function punch_filter(data, filtpos, filtnode)
local filtmeta = minetest.get_meta(filtpos)
local filtinv = filtmeta:get_inventory()
2014-08-14 16:22:03 +02:00
local dir = minetest.facedir_to_right_dir(filtnode.param2)
local frompos = vector.subtract(filtpos, dir)
local fromnode = minetest.get_node(frompos)
if not fromnode then return end
local fromdef = minetest.registered_nodes[fromnode.name]
if not fromdef then return end
local fromtube = fromdef.tube
if not (fromtube and fromtube.input_inventory) then return end
local filters = {}
for _, filterstack in ipairs(filtinv:get_list("main")) do
local filtername = filterstack:get_name()
if filtername ~= "" then table.insert(filters, filtername) end
end
if #filters == 0 then table.insert(filters, "") end
local slotseq_mode = filtmeta:get_int("slotseq_mode")
local frommeta = minetest.get_meta(frompos)
local frominv = frommeta:get_inventory()
if fromtube.before_filter then fromtube.before_filter(frompos) end
for _, frominvname in ipairs(type(fromtube.input_inventory) == "table" and fromtube.input_inventory or {fromtube.input_inventory}) do
local done = false
for _, filtername in ipairs(filters) do
if grabAndFire(data, slotseq_mode, filtmeta, frominv, frominvname, frompos, fromnode, filtername, fromtube, fromdef, dir, data.stackwise) then
done = true
break
end
end
if done then break end
end
if fromtube.after_filter then fromtube.after_filter(frompos) end
end
for _, data in ipairs({
{
name = "filter",
wise_desc = "Itemwise",
stackwise = false,
},
{
name = "mese_filter",
wise_desc = "Stackwise",
stackwise = true,
},
}) do
minetest.register_node("pipeworks:"..data.name, {
description = data.wise_desc.." Filter-Injector",
tiles = {
"pipeworks_"..data.name.."_top.png",
"pipeworks_"..data.name.."_top.png",
"pipeworks_"..data.name.."_output.png",
"pipeworks_"..data.name.."_input.png",
"pipeworks_"..data.name.."_side.png",
"pipeworks_"..data.name.."_top.png",
},
paramtype2 = "facedir",
2014-08-14 16:22:03 +02:00
groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, mesecon = 2},
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
on_construct = function(pos)
local meta = minetest.get_meta(pos)
set_filter_formspec(data, meta)
set_filter_infotext(data, meta)
local inv = meta:get_inventory()
inv:set_size("main", 8*2)
end,
on_receive_fields = function(pos, formname, fields, sender)
2014-08-14 16:22:03 +02:00
fs_helpers.on_receive_fields(pos, fields)
local meta = minetest.get_meta(pos)
2014-08-14 16:22:03 +02:00
meta:set_int("slotseq_index", 1)
set_filter_formspec(data, meta)
set_filter_infotext(data, meta)
end,
2014-08-14 16:22:03 +02:00
can_dig = function(pos, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:is_empty("main")
end,
mesecons = {
effector = {
action_on = function(pos, node)
punch_filter(data, pos, node)
end,
},
},
2014-08-14 16:22:03 +02:00
tube = {connect_sides = {right = 1}},
on_punch = function (pos, node, puncher)
punch_filter(data, pos, node)
end,
})
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)
2014-08-14 16:22:03 +02:00
local next_positions = {}
local max_priority = 0
2013-12-21 08:46:55 +01:00
local cnode = minetest.get_node(pos)
local cmeta = minetest.get_meta(pos)
2013-12-15 11:35:11 +01:00
local can_go
2013-12-21 10:16:58 +01:00
local speed = math.abs(velocity.x + velocity.y + velocity.z)
2014-08-14 16:22:03 +02:00
if speed == 0 then
speed = 1
end
2013-12-21 10:16:58 +01:00
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
2014-08-14 16:22:03 +02:00
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
2014-08-14 16:22:03 +02:00
for _, vect in ipairs(can_go) do
local npos = vector.add(pos, vect)
2013-12-21 08:46:55 +01:00
local node = minetest.get_node(npos)
2014-08-14 16:22:03 +02:00
local tubedevice = minetest.get_item_group(node.name, "tubedevice")
local tube_def = minetest.registered_nodes[node.name].tube
local tube_priority = (tube_def and tube_def.priority) or 100
if tubedevice > 0 and tube_priority >= max_priority then
if not tube_def or not tube_def.can_insert or
2014-08-14 22:02:36 +02:00
tube_def.can_insert(npos, node, stack, vect) then
2014-08-14 16:22:03 +02:00
if tube_priority > max_priority then
max_priority = tube_priority
next_positions = {}
end
next_positions[#next_positions + 1] = {pos = npos, vect = vect}
2013-12-15 11:35:11 +01:00
end
end
end
2014-08-14 16:22:03 +02:00
if not next_positions[1] then
return false, nil
end
local n = (cmeta:get_int("tubedir") % (#next_positions)) + 1
if pipeworks.enable_cyclic_mode then
cmeta:set_int("tubedir", n)
2013-12-15 11:35:11 +01:00
end
2014-08-14 16:22:03 +02:00
local new_velocity = vector.multiply(next_positions[n].vect, vel.speed)
return true, new_velocity
2013-12-15 11:35:11 +01:00
end
minetest.register_entity("pipeworks:tubed_item", {
initial_properties = {
hp_max = 1,
physical = false,
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,
},
2014-08-14 16:22:03 +02:00
physical_state = false,
2014-08-14 16:22:03 +02:00
from_data = function(self, itemstring)
local stack = ItemStack(itemstring)
2014-08-14 16:22:03 +02:00
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
self.object:set_properties({
is_visible = true,
2014-08-14 16:22:03 +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)
end,
2014-08-14 16:22:03 +02:00
get_staticdata = luaentity.get_staticdata,
2014-08-14 21:18:48 +02:00
on_activate = function(self, staticdata) -- Legacy code, should be replaced later by luaentity.on_activate
if staticdata == "" or staticdata == nil then
return
end
if staticdata == "toremove" then
self.object:remove()
return
end
local item = minetest.deserialize(staticdata)
pipeworks.tube_inject_item(self.object:getpos(), item.start_pos, item.velocity, item.itemstring)
2014-08-14 21:18:48 +02:00
self.object:remove()
end,
2014-08-14 16:22:03 +02:00
})
minetest.register_entity("pipeworks:color_entity", {
initial_properties = {
hp_max = 1,
physical = false,
collisionbox = {0.1, 0.1, 0.1, 0.1, 0.1, 0.1},
visual = "cube",
visual_size = {x = 3.5, y = 3.5, z = 3.5}, -- todo: find correct size
textures = {""},
is_visible = false,
},
physical_state = false,
from_data = function(self, color)
local t = "pipeworks_color_"..color..".png"
local prop = {
is_visible = true,
visual = "cube",
textures = {t, t, t, t, t, t} -- todo: textures
}
self.object:set_properties(prop)
end,
2014-08-14 16:22:03 +02:00
get_staticdata = luaentity.get_staticdata,
on_activate = luaentity.on_activate,
})
luaentity.register_entity("pipeworks:tubed_item", {
itemstring = '',
item_entity = nil,
color_entity = nil,
color = nil,
start_pos = nil,
set_item = function(self, item)
local itemstring = ItemStack(item):to_string() -- Accept any input format
if self.itemstring == itemstring then
return
end
2014-08-14 16:22:03 +02:00
if self.item_entity then
self:remove_attached_entity(self.item_entity)
end
2014-08-14 16:22:03 +02:00
self.itemstring = itemstring
self.item_entity = self:add_attached_entity("pipeworks:tubed_item", itemstring)
end,
2014-08-14 16:22:03 +02:00
set_color = function(self, color)
if self.color == color then
return
end
self.color = color
if self.color_entity then
self:remove_attached_entity(self.color_entity)
end
if color then
self.color_entity = self:add_attached_entity("pipeworks:color_entity", color)
else
self.color_entity = nil
end
end,
on_step = function(self, dtime)
if self.start_pos == nil then
2014-08-14 16:22:03 +02:00
local pos = self:getpos()
self.start_pos = vector.round(pos)
self:setpos(pos)
2014-04-13 09:25:17 +02:00
end
2014-08-14 16:22:03 +02:00
local pos = self:getpos()
2014-04-13 09:25:17 +02:00
local stack = ItemStack(self.itemstring)
2014-08-14 16:22:03 +02:00
local drop_pos
2014-08-14 16:22:03 +02:00
local velocity = self:getvelocity()
2014-04-13 09:25:17 +02:00
local moved = false
local speed = math.abs(velocity.x + velocity.y + velocity.z)
2014-08-14 16:22:03 +02:00
if speed == 0 then
speed = 1
moved = true
end
local vel = {x = velocity.x / speed, y = velocity.y / speed, z = velocity.z / speed, speed = speed}
2014-04-13 09:25:17 +02:00
2014-08-14 16:22:03 +02:00
if vector.distance(pos, self.start_pos) >= 1 then
self.start_pos = vector.add(self.start_pos, vel)
moved = true
end
2014-04-13 09:25:17 +02:00
2014-08-14 16:22:03 +02:00
minetest.load_position(self.start_pos)
local node = minetest.get_node(self.start_pos)
2014-04-13 09:25:17 +02:00
if moved and minetest.get_item_group(node.name, "tubedevice_receiver") == 1 then
2014-08-14 16:22:03 +02:00
local leftover
2014-04-13 09:25:17 +02:00
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
2014-08-14 16:22:03 +02:00
velocity = vector.multiply(velocity, -1)
self:setvelocity(velocity)
2014-04-13 09:25:17 +02:00
self:set_item(leftover:to_string())
return
end
2014-04-13 09:25:17 +02:00
if moved then
2014-08-14 16:22:03 +02:00
local found_next, new_velocity = go_next(self.start_pos, velocity, stack) -- todo: color
if not found_next then
2014-04-13 09:25:17 +02:00
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-08-14 16:22:03 +02:00
return
2014-04-13 09:25:17 +02:00
end
end
2014-08-14 16:22:03 +02:00
if new_velocity and not vector.equals(velocity, new_velocity) then
self:setpos(self.start_pos)
self:setvelocity(new_velocity)
end
2014-04-13 09:25:17 +02:00
end
end
})
2014-08-14 16:22:03 +02:00
if minetest.get_modpath("mesecons_mvps") then
2014-01-03 13:29:38 +01:00
mesecon:register_mvps_unmov("pipeworks:tubed_item")
2014-08-14 16:22:03 +02:00
mesecon:register_mvps_unmov("pipeworks:color_entity")
2014-01-03 13:29:38 +01:00
mesecon:register_on_mvps_move(function(moved_nodes)
2014-08-14 16:22:03 +02:00
local moved = {}
2014-01-03 13:29:38 +01:00
for _, n in ipairs(moved_nodes) do
2014-08-14 16:22:03 +02:00
moved[minetest.hash_node_position(n.oldpos)] = vector.subtract(n.pos, n.oldpos)
2014-01-03 13:29:38 +01:00
end
2014-08-14 16:22:03 +02:00
for id, entity in pairs(luaentity.entities) do
if entity.name == "pipeworks:tubed_item" then
local pos = entity:getpos()
local rpos = vector.round(pos)
local dir = moved[minetest.hash_node_position(rpos)]
if dir then
entity:setpos(vector.add(pos, dir))
entity.start_pos = vector.add(entity.start_pos, dir)
end
2014-01-03 13:29:38 +01:00
end
end
end)
end