forked from mtcontrib/pipeworks
Major rewrite of items in tubes
This commit is contained in:
parent
a9866aa5d5
commit
d5480f5ff0
110
autoplace_tubes.lua
Normal file → Executable file
110
autoplace_tubes.lua
Normal file → Executable file
|
@ -1,72 +1,38 @@
|
|||
-- autorouting for pneumatic tubes
|
||||
|
||||
local function in_table(table,element)
|
||||
for _,el in ipairs(table) do
|
||||
if el==element then return true end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function is_tube(nodename)
|
||||
return in_table(pipeworks.tubenodes,nodename)
|
||||
end
|
||||
|
||||
if pipeworks == nil then
|
||||
pipeworks = {}
|
||||
return table.contains(pipeworks.tubenodes, nodename)
|
||||
end
|
||||
|
||||
--a function for determining which side of the node we are on
|
||||
local function nodeside(node, tubedir)
|
||||
if node and (node.param2 < 0 or node.param2 > 23) then node.param2 = 0 end
|
||||
|
||||
--get a vector pointing back
|
||||
local backdir = minetest.facedir_to_dir(node.param2)
|
||||
|
||||
--check whether the vector is equivalent to the tube direction; if it is, the tube's on the backside
|
||||
if backdir.x == tubedir.x and backdir.y == tubedir.y and backdir.z == tubedir.z then
|
||||
return "back"
|
||||
if node.param2 < 0 or node.param2 > 23 then
|
||||
node.param2 = 0
|
||||
end
|
||||
|
||||
--check whether the vector is antiparallel with the tube direction; that indicates the front
|
||||
if backdir.x == -tubedir.x and backdir.y == -tubedir.y and backdir.z == -tubedir.z then
|
||||
local backdir = minetest.facedir_to_dir(node.param2)
|
||||
local back = vector.dot(backdir, tubedir)
|
||||
if back == 1 then
|
||||
return "back"
|
||||
elseif back == -1 then
|
||||
return "front"
|
||||
end
|
||||
|
||||
--facedir is defined in terms of the top-bottom axis of the node; we'll take advantage of that
|
||||
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(node.param2/4)]
|
||||
|
||||
--is this the top?
|
||||
if topdir.x == tubedir.x and topdir.y == tubedir.y and topdir.z == tubedir.z then
|
||||
local topdir = minetest.facedir_to_top_dir(node.param2)
|
||||
local top = vector.dot(topdir, tubedir)
|
||||
if top == 1 then
|
||||
return "top"
|
||||
end
|
||||
|
||||
--or the bottom?
|
||||
if topdir.x == -tubedir.x and topdir.y == -tubedir.y and topdir.z == -tubedir.z then
|
||||
elseif top == -1 then
|
||||
return "bottom"
|
||||
end
|
||||
|
||||
--we shall apply some maths to obtain the right-facing vector
|
||||
local rightdir = {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}
|
||||
|
||||
--is this the right side?
|
||||
if rightdir.x == tubedir.x and rightdir.y == tubedir.y and rightdir.z == tubedir.z then
|
||||
local rightdir = minetest.facedir_to_right_dir(node.param2)
|
||||
local right = vector.dot(rightdir, tubedir)
|
||||
if right == 1 then
|
||||
return "right"
|
||||
end
|
||||
|
||||
--or the left?
|
||||
if rightdir.x == -tubedir.x and rightdir.y == -tubedir.y and rightdir.z == -tubedir.z then
|
||||
else
|
||||
return "left"
|
||||
end
|
||||
|
||||
--we should be done by now; initiate panic mode
|
||||
minetest.log("error", "nodeside has been confused by its parameters; see pipeworks autoplace_tubes.lua, line 78")
|
||||
end
|
||||
|
||||
local vts = {0, 3, 1, 4, 2, 5}
|
||||
|
@ -78,23 +44,23 @@ local function tube_autoroute(pos)
|
|||
if not is_tube(nctr.name) then return end
|
||||
|
||||
local adjustments = {
|
||||
{ x=-1, y=0, z=0 },
|
||||
{ x=1, y=0, z=0 },
|
||||
{ x=0, y=-1, z=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},
|
||||
{x = 0, y = 1, z = 0},
|
||||
{x = 0, y = 0, z = -1},
|
||||
{x = 0, y = 0, z = 1}
|
||||
}
|
||||
-- xm = 1, xp = 2, ym = 3, yp = 4, zm = 5, zp = 6
|
||||
|
||||
local positions = {}
|
||||
local nodes = {}
|
||||
for i,adj in ipairs(adjustments) do
|
||||
positions[i] = {x=pos.x+adj.x, y=pos.y+adj.y, z=pos.z+adj.z}
|
||||
for i, adj in ipairs(adjustments) do
|
||||
positions[i] = vector.add(pos, adj)
|
||||
nodes[i] = minetest.get_node(positions[i])
|
||||
end
|
||||
|
||||
for i,node in ipairs(nodes) do
|
||||
for i, node in ipairs(nodes) do
|
||||
local idef = minetest.registered_nodes[node.name]
|
||||
-- handle the tubes themselves
|
||||
if is_tube(node.name) then
|
||||
|
@ -102,7 +68,9 @@ local function tube_autoroute(pos)
|
|||
-- handle new style connectors
|
||||
elseif idef and idef.tube and idef.tube.connect_sides then
|
||||
local dir = adjustments[i]
|
||||
if idef.tube.connect_sides[nodeside(node, {x=-dir.x, y=-dir.y, z=-dir.z})] then active[i] = 1 end
|
||||
if idef.tube.connect_sides[nodeside(node, vector.multiply(dir, -1))] then
|
||||
active[i] = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -110,18 +78,17 @@ local function tube_autoroute(pos)
|
|||
|
||||
local nodedef = minetest.registered_nodes[nctr.name]
|
||||
local basename = nodedef.basename
|
||||
local newname
|
||||
if nodedef.style == "old" then
|
||||
local nsurround = ""
|
||||
for i,n in ipairs(active) do
|
||||
nsurround = nsurround .. n
|
||||
for i, n in ipairs(active) do
|
||||
nsurround = nsurround..n
|
||||
end
|
||||
nctr.name = basename.."_"..nsurround
|
||||
elseif nodedef.style == "6d" then
|
||||
local s = 0
|
||||
for i,n in ipairs(active) do
|
||||
for i, n in ipairs(active) do
|
||||
if n == 1 then
|
||||
s = s+2^vts[i]
|
||||
s = s + 2^vts[i]
|
||||
end
|
||||
end
|
||||
nctr.name = basename.."_"..tube_table[s]
|
||||
|
@ -131,14 +98,9 @@ local function tube_autoroute(pos)
|
|||
end
|
||||
|
||||
function pipeworks.scan_for_tube_objects(pos)
|
||||
if not pos or not pos.x or not pos.y or not pos.z then return end
|
||||
tube_autoroute({ x=pos.x-1, y=pos.y , z=pos.z })
|
||||
tube_autoroute({ x=pos.x+1, y=pos.y , z=pos.z })
|
||||
tube_autoroute({ x=pos.x , y=pos.y-1, z=pos.z })
|
||||
tube_autoroute({ x=pos.x , y=pos.y+1, z=pos.z })
|
||||
tube_autoroute({ x=pos.x , y=pos.y , z=pos.z-1 })
|
||||
tube_autoroute({ x=pos.x , y=pos.y , z=pos.z+1 })
|
||||
tube_autoroute(pos)
|
||||
for side = 0, 6 do
|
||||
tube_autoroute(vector.add(pos, directions.side_to_dir(side)))
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack)
|
||||
|
@ -157,7 +119,7 @@ minetest.register_on_dignode(function(pos, oldnode, digger)
|
|||
end
|
||||
end)
|
||||
|
||||
if minetest.get_modpath("mesecons_mvps") ~= nil then
|
||||
if minetest.get_modpath("mesecons_mvps") then
|
||||
mesecon:register_on_mvps_move(function(moved_nodes)
|
||||
for _, n in ipairs(moved_nodes) do
|
||||
pipeworks.scan_for_tube_objects(n.pos)
|
||||
|
|
144
common.lua
Executable file
144
common.lua
Executable file
|
@ -0,0 +1,144 @@
|
|||
----------------------
|
||||
-- Vector functions --
|
||||
----------------------
|
||||
|
||||
function vector.cross(a, b)
|
||||
return {
|
||||
x = a.y * b.z - a.z * b.y,
|
||||
y = a.z * b.x - a.x * b.z,
|
||||
z = a.x * b.y - a.y * b.x
|
||||
}
|
||||
end
|
||||
|
||||
function vector.dot(a, b)
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z
|
||||
end
|
||||
|
||||
-----------------------
|
||||
-- Facedir functions --
|
||||
-----------------------
|
||||
|
||||
function minetest.facedir_to_top_dir(facedir)
|
||||
return ({[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)]
|
||||
end
|
||||
|
||||
function minetest.facedir_to_right_dir(facedir)
|
||||
return vector.cross(
|
||||
minetest.facedir_to_top_dir(facedir),
|
||||
minetest.facedir_to_dir(facedir)
|
||||
)
|
||||
end
|
||||
|
||||
directions = {}
|
||||
function directions.side_to_dir(side)
|
||||
return ({[0] = vector.new(),
|
||||
vector.new( 0, 1, 0),
|
||||
vector.new( 0, -1, 0),
|
||||
vector.new( 1, 0, 0),
|
||||
vector.new(-1, 0, 0),
|
||||
vector.new( 0, 0, 1),
|
||||
vector.new( 0, 0, -1)
|
||||
})[side]
|
||||
end
|
||||
|
||||
function directions.dir_to_side(dir)
|
||||
local c = vector.dot(dir, vector.new(1, 2, 3)) + 4
|
||||
return ({6, 2, 4, 0, 3, 1, 5})[c]
|
||||
end
|
||||
|
||||
----------------------
|
||||
-- String functions --
|
||||
----------------------
|
||||
|
||||
--[[function string.split(str, sep)
|
||||
local fields = {}
|
||||
local index = 1
|
||||
local expr = "([^"..sep.."])+"
|
||||
string.gsub(str, expr, function(substring)
|
||||
fields[index] = substring
|
||||
index = index + 1
|
||||
end)
|
||||
return fields
|
||||
end]]
|
||||
|
||||
function string.startswith(str, substr)
|
||||
return str:sub(1, substr:len()) == substr
|
||||
end
|
||||
|
||||
---------------------
|
||||
-- Table functions --
|
||||
---------------------
|
||||
|
||||
function table.contains(tbl, element)
|
||||
for _, elt in pairs(tbl) do
|
||||
if elt == element then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function table.extend(tbl, tbl2)
|
||||
local index = #tbl + 1
|
||||
for _, elt in ipairs(tbl2) do
|
||||
tbl[index] = elt
|
||||
index = index + 1
|
||||
end
|
||||
end
|
||||
|
||||
function table.recursive_replace(tbl, pattern, replace_with)
|
||||
if type(tbl) == "table" then
|
||||
local tbl2 = {}
|
||||
for key, value in pairs(tbl) do
|
||||
tbl2[key] = table.recursive_replace(value, pattern, replace_with)
|
||||
end
|
||||
return tbl2
|
||||
elseif type(tbl) == "string" then
|
||||
return tbl:gsub(pattern, replace_with)
|
||||
else
|
||||
return tbl
|
||||
end
|
||||
end
|
||||
|
||||
------------------------
|
||||
-- Formspec functions --
|
||||
------------------------
|
||||
|
||||
fs_helpers = {}
|
||||
function fs_helpers.on_receive_fields(pos, fields)
|
||||
local meta = minetest.get_meta(pos)
|
||||
for field, value in pairs(fields) do
|
||||
if field:startswith("fs_helpers_cycling:") then
|
||||
local l = field:split(":")
|
||||
local new_value = tonumber(l[2])
|
||||
local meta_name = l[3]
|
||||
meta:set_int(meta_name, new_value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function fs_helpers.cycling_button(meta, base, meta_name, values)
|
||||
local current_value = meta:get_int(meta_name)
|
||||
local new_value = (current_value + 1) % (#values)
|
||||
local text = values[current_value + 1]
|
||||
local field = "fs_helpers_cycling:"..new_value..":"..meta_name
|
||||
return base..";"..field..";"..text.."]"
|
||||
end
|
||||
|
||||
---------
|
||||
-- Env --
|
||||
---------
|
||||
|
||||
function minetest.load_position(pos)
|
||||
if minetest.get_node_or_nil(pos) then
|
||||
return
|
||||
end
|
||||
local vm = minetest.get_voxel_manip()
|
||||
vm:read_from_map(pos, pos)
|
||||
end
|
2
init.lua
Normal file → Executable file
2
init.lua
Normal file → Executable file
|
@ -106,9 +106,11 @@ end
|
|||
-------------------------------------------
|
||||
-- Load the various other parts of the mod
|
||||
|
||||
dofile(pipeworks.modpath.."/common.lua")
|
||||
dofile(pipeworks.modpath.."/models.lua")
|
||||
dofile(pipeworks.modpath.."/autoplace_pipes.lua")
|
||||
dofile(pipeworks.modpath.."/autoplace_tubes.lua")
|
||||
dofile(pipeworks.modpath.."/luaentity.lua")
|
||||
dofile(pipeworks.modpath.."/item_transport.lua")
|
||||
dofile(pipeworks.modpath.."/flowing_logic.lua")
|
||||
dofile(pipeworks.modpath.."/crafts.lua")
|
||||
|
|
395
item_transport.lua
Normal file → Executable file
395
item_transport.lua
Normal file → Executable file
|
@ -1,34 +1,17 @@
|
|||
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
|
||||
|
||||
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)
|
||||
function pipeworks.tube_item(pos, start_pos, velocity, item)
|
||||
-- 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())
|
||||
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
|
||||
return obj
|
||||
end
|
||||
|
||||
|
@ -52,19 +35,16 @@ local function set_filter_formspec(data, meta)
|
|||
"item_image[0,0;1,1;pipeworks:"..data.name.."]"..
|
||||
"label[1,0;"..minetest.formspec_escape(itemname).."]"..
|
||||
"label[0,1;Prefer item types:]"..
|
||||
"list[current_name;main;0,1.5;8,2;]"
|
||||
local slotseq_mode = meta:get_int("slotseq_mode")
|
||||
if slotseq_mode == 1 then
|
||||
formspec = formspec .. "button[0,3.5;4,1;slotseq_mode2;Sequence slots Randomly]"
|
||||
elseif slotseq_mode == 2 then
|
||||
formspec = formspec .. "button[0,3.5;4,1;slotseq_mode0;Sequence slots by Rotation]"
|
||||
else
|
||||
formspec = formspec .. "button[0,3.5;4,1;slotseq_mode1;Sequence slots by Priority]"
|
||||
end
|
||||
formspec = formspec .. "list[current_player;main;0,4.5;8,4;]"
|
||||
"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
|
||||
|
||||
-- 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 = {}
|
||||
for spos,stack in ipairs(frominv:get_list(frominvname)) do
|
||||
|
@ -130,10 +110,9 @@ local function grabAndFire(data,slotseq_mode,filtmeta,frominv,frominvname,frompo
|
|||
fromdef.on_metadata_inventory_take(frompos, frominvname, spos, item, fakePlayer)
|
||||
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)
|
||||
item1:setvelocity(dir)
|
||||
item1:setacceleration({x=0, y=0, z=0})
|
||||
local pos = vector.add(frompos, vector.multiply(dir, 1.4))
|
||||
local start_pos = vector.add(frompos, dir)
|
||||
local item1 = pipeworks.tube_item(pos, start_pos, dir, item)
|
||||
return true-- only fire one item, please
|
||||
end
|
||||
end
|
||||
|
@ -143,8 +122,8 @@ end
|
|||
local function punch_filter(data, filtpos, filtnode)
|
||||
local filtmeta = minetest.get_meta(filtpos)
|
||||
local filtinv = filtmeta:get_inventory()
|
||||
local dir = facedir_to_right_dir(filtnode.param2)
|
||||
local frompos = {x=filtpos.x - dir.x, y=filtpos.y - dir.y, z=filtpos.z - dir.z}
|
||||
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]
|
||||
|
@ -197,7 +176,7 @@ for _, data in ipairs({
|
|||
"pipeworks_"..data.name.."_top.png",
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,tubedevice=1,mesecon=2},
|
||||
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)
|
||||
|
@ -208,28 +187,17 @@ for _, data in ipairs({
|
|||
inv:set_size("main", 8*2)
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
fs_helpers.on_receive_fields(pos, fields)
|
||||
local meta = minetest.get_meta(pos)
|
||||
for k, _ in pairs(fields) do
|
||||
if k:sub(1, 12) == "slotseq_mode" then
|
||||
local mode = tonumber(k:sub(13, 13))
|
||||
meta:set_int("slotseq_mode", mode)
|
||||
meta:set_int("slotseq_index", mode == 2 and 1 or 0)
|
||||
end
|
||||
end
|
||||
meta:set_int("slotseq_index", 1)
|
||||
set_filter_formspec(data, meta)
|
||||
set_filter_infotext(data, meta)
|
||||
end,
|
||||
can_dig = function(pos,player)
|
||||
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)
|
||||
|
@ -237,21 +205,13 @@ for _, data in ipairs({
|
|||
end,
|
||||
},
|
||||
},
|
||||
tube={connect_sides={right=1}},
|
||||
tube = {connect_sides = {right = 1}},
|
||||
on_punch = function (pos, node, puncher)
|
||||
punch_filter(data, pos, node)
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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}}
|
||||
|
||||
function pipeworks.notvel(tbl, vel)
|
||||
|
@ -263,18 +223,20 @@ function pipeworks.notvel(tbl, vel)
|
|||
end
|
||||
|
||||
local function go_next(pos, velocity, stack)
|
||||
local chests = {}
|
||||
local tubes = {}
|
||||
local next_positions = {}
|
||||
local max_priority = 0
|
||||
local cnode = minetest.get_node(pos)
|
||||
local cmeta = minetest.get_meta(pos)
|
||||
local n
|
||||
local can_go
|
||||
local speed = math.abs(velocity.x + velocity.y + velocity.z)
|
||||
if speed == 0 then
|
||||
speed = 1
|
||||
end
|
||||
local vel = {x = velocity.x/speed, y = velocity.y/speed, z = velocity.z/speed,speed=speed}
|
||||
if speed >= 4.1 then
|
||||
speed = 4
|
||||
elseif speed >= 1.1 then
|
||||
speed = speed-0.1
|
||||
speed = speed - 0.1
|
||||
else
|
||||
speed = 1
|
||||
end
|
||||
|
@ -284,58 +246,40 @@ local function go_next(pos, velocity, stack)
|
|||
else
|
||||
can_go = pipeworks.notvel(adjlist, vel)
|
||||
end
|
||||
local meta = nil
|
||||
for _,vect in ipairs(can_go) do
|
||||
local npos = addVect(pos,vect)
|
||||
for _, vect in ipairs(can_go) do
|
||||
local npos = vector.add(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
|
||||
if minetest.registered_nodes[node.name].tube and
|
||||
minetest.registered_nodes[node.name].tube.can_insert and
|
||||
minetest.registered_nodes[node.name].tube.can_insert(npos, node, stack, vect) then
|
||||
local i = #chests + 1
|
||||
chests[i] = {}
|
||||
chests[i].pos = npos
|
||||
chests[i].vect = vect
|
||||
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
|
||||
tubedef.can_insert(npos, node, stack, vect) then
|
||||
if tube_priority > max_priority then
|
||||
max_priority = tube_priority
|
||||
next_positions = {}
|
||||
end
|
||||
next_positions[#next_positions + 1] = {pos = npos, vect = vect}
|
||||
end
|
||||
elseif tubelike == 1 then
|
||||
local i = #tubes + 1
|
||||
tubes[i] = {}
|
||||
tubes[i].pos = npos
|
||||
tubes[i].vect = vect
|
||||
end
|
||||
end
|
||||
if chests[1] == nil then--no chests found
|
||||
if tubes[1] == nil then
|
||||
return 0
|
||||
else
|
||||
n = (cmeta:get_int("tubedir")%(#tubes)) + 1
|
||||
if pipeworks.enable_cyclic_mode then
|
||||
cmeta:set_int("tubedir",n)
|
||||
end
|
||||
velocity.x = tubes[n].vect.x*vel.speed
|
||||
velocity.y = tubes[n].vect.y*vel.speed
|
||||
velocity.z = tubes[n].vect.z*vel.speed
|
||||
end
|
||||
else
|
||||
n = (cmeta:get_int("tubedir")%(#chests))+1
|
||||
if pipeworks.enable_cyclic_mode then
|
||||
cmeta:set_int("tubedir",n)
|
||||
end
|
||||
velocity.x = chests[n].vect.x*speed
|
||||
velocity.y = chests[n].vect.y*speed
|
||||
velocity.z = chests[n].vect.z*speed
|
||||
|
||||
if not next_positions[1] then
|
||||
return false, nil
|
||||
end
|
||||
return 1
|
||||
|
||||
local n = (cmeta:get_int("tubedir") % (#next_positions)) + 1
|
||||
if pipeworks.enable_cyclic_mode then
|
||||
cmeta:set_int("tubedir", n)
|
||||
end
|
||||
local new_velocity = vector.multiply(next_positions[n].vect, vel.speed)
|
||||
return true, new_velocity
|
||||
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},
|
||||
|
@ -343,113 +287,126 @@ minetest.register_entity("pipeworks:tubed_item", {
|
|||
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
|
||||
from_data = function(self, 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()
|
||||
self.object:setpos(self.start_pos)
|
||||
return minetest.serialize({
|
||||
itemstring = self.itemstring,
|
||||
velocity = velocity,
|
||||
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)
|
||||
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:set_item(item.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 = luaentity.get_staticdata,
|
||||
on_activate = luaentity.on_activate,
|
||||
})
|
||||
|
||||
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,
|
||||
|
||||
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
|
||||
if self.item_entity then
|
||||
self:remove_attached_entity(self.item_entity)
|
||||
end
|
||||
self.itemstring = itemstring
|
||||
self.item_entity = self:add_attached_entity("pipeworks:tubed_item", itemstring)
|
||||
end,
|
||||
|
||||
remove = function(self)
|
||||
self.object:remove()
|
||||
self.removed = true
|
||||
self.itemstring = ''
|
||||
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.removed then
|
||||
return
|
||||
end
|
||||
if self.start_pos == nil then
|
||||
local pos = self.object:getpos()
|
||||
self.start_pos = roundpos(pos)
|
||||
local pos = self:getpos()
|
||||
self.start_pos = vector.round(pos)
|
||||
self:setpos(pos)
|
||||
end
|
||||
local pos = self.object:getpos()
|
||||
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()
|
||||
|
||||
if velocity == nil then return end
|
||||
|
||||
local velocitycopy = {x = velocity.x, y = velocity.y, z = velocity.z}
|
||||
local pos = self:getpos()
|
||||
local stack = ItemStack(self.itemstring)
|
||||
local drop_pos
|
||||
|
||||
local velocity = self:getvelocity()
|
||||
|
||||
local moved = false
|
||||
local speed = math.abs(velocity.x + velocity.y + velocity.z)
|
||||
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}
|
||||
|
||||
if math.abs(vel.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 + vel.x
|
||||
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
|
||||
elseif math.abs(vel.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 + vel.z
|
||||
moved = true
|
||||
end
|
||||
if vector.distance(pos, self.start_pos) >= 1 then
|
||||
self.start_pos = vector.add(self.start_pos, vel)
|
||||
moved = true
|
||||
end
|
||||
|
||||
local sposcopy = {x = self.start_pos.x, y = self.start_pos.y, z = self.start_pos.z}
|
||||
|
||||
node = minetest.get_node(self.start_pos)
|
||||
minetest.load_position(self.start_pos)
|
||||
local node = minetest.get_node(self.start_pos)
|
||||
if moved and minetest.get_item_group(node.name, "tubedevice_receiver") == 1 then
|
||||
local leftover = nil
|
||||
local leftover
|
||||
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
|
||||
|
@ -459,62 +416,48 @@ minetest.register_entity("pipeworks:tubed_item", {
|
|||
self:remove()
|
||||
return
|
||||
end
|
||||
velocity.x = -velocity.x
|
||||
velocity.y = -velocity.y
|
||||
velocity.z = -velocity.z
|
||||
self.object:setvelocity(velocity)
|
||||
velocity = vector.multiply(velocity, -1)
|
||||
self:setvelocity(velocity)
|
||||
self:set_item(leftover:to_string())
|
||||
return
|
||||
end
|
||||
|
||||
if moved then
|
||||
if go_next (self.start_pos, velocity, stack) == 0 then
|
||||
local found_next, new_velocity = go_next(self.start_pos, velocity, stack) -- todo: color
|
||||
if not found_next 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()
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
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)
|
||||
|
||||
if new_velocity and not vector.equals(velocity, new_velocity) then
|
||||
self:setpos(self.start_pos)
|
||||
self:setvelocity(new_velocity)
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
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
|
||||
if minetest.get_modpath("mesecons_mvps") then
|
||||
mesecon:register_mvps_unmov("pipeworks:tubed_item")
|
||||
mesecon:register_mvps_unmov("pipeworks:color_entity")
|
||||
mesecon:register_on_mvps_move(function(moved_nodes)
|
||||
local objects_to_move = {}
|
||||
local moved = {}
|
||||
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)
|
||||
end
|
||||
end
|
||||
moved[minetest.hash_node_position(n.oldpos)] = vector.subtract(n.pos, n.oldpos)
|
||||
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)
|
||||
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
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
|
335
luaentity.lua
Executable file
335
luaentity.lua
Executable file
|
@ -0,0 +1,335 @@
|
|||
local max_entity_id = 1000000000000 -- If you need more, there's a problem with your code
|
||||
|
||||
luaentity = {}
|
||||
|
||||
luaentity.registered_entities = {}
|
||||
|
||||
local filename = minetest.get_worldpath().."/luaentities"
|
||||
local function read_file()
|
||||
local f = io.open(filename, "r")
|
||||
if f == nil then return {} end
|
||||
local t = f:read("*all")
|
||||
f:close()
|
||||
if t == "" or t == nil then return {} end
|
||||
return minetest.deserialize(t)
|
||||
end
|
||||
|
||||
local function write_file(tbl)
|
||||
local f = io.open(filename, "w")
|
||||
f:write(minetest.serialize(tbl))
|
||||
f:close()
|
||||
end
|
||||
|
||||
local function read_entities()
|
||||
local t = read_file()
|
||||
for _, entity in pairs(t) do
|
||||
setmetatable(entity, luaentity.registered_entities[entity.name])
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
local function write_entities()
|
||||
for _, entity in pairs(luaentity.entities) do
|
||||
setmetatable(entity, nil)
|
||||
for _, attached in pairs(entity._attached_entities) do
|
||||
if attached.entity then
|
||||
attached.entity:remove()
|
||||
attached.entity = nil
|
||||
end
|
||||
end
|
||||
entity._attached_entities_master = nil
|
||||
end
|
||||
write_file(luaentity.entities)
|
||||
end
|
||||
|
||||
minetest.after(0, function()
|
||||
luaentity.entities = read_entities()
|
||||
end)
|
||||
minetest.register_on_shutdown(write_entities)
|
||||
-- todo: load that from file (datastorage?) -> don't forget about metatables (are those serialized?) / do not blindly save -> the attached_entities have to be removed
|
||||
luaentity.entities_index = 0
|
||||
|
||||
local function get_blockpos(pos)
|
||||
return {x = math.floor(pos.x / 16),
|
||||
y = math.floor(pos.y / 16),
|
||||
z = math.floor(pos.z / 16)}
|
||||
end
|
||||
|
||||
local active_blocks = {} -- These only contain active blocks near players (i.e., not forceloaded ones)
|
||||
local handle_active_blocks_step = 2
|
||||
local handle_active_blocks_timer = 0
|
||||
minetest.register_globalstep(function(dtime)
|
||||
handle_active_blocks_timer = handle_active_blocks_timer + dtime
|
||||
if handle_active_blocks_timer >= handle_active_blocks_step then
|
||||
handle_active_blocks_timer = handle_active_blocks_timer - handle_active_blocks_step
|
||||
local active_block_range = tonumber(minetest.setting_get("active_block_range"))
|
||||
local new_active_blocks = {}
|
||||
for _, player in ipairs(minetest.get_connected_players()) do
|
||||
local blockpos = get_blockpos(player:getpos())
|
||||
local minp = vector.subtract(blockpos, active_block_range)
|
||||
local maxp = vector.add(blockpos, active_block_range)
|
||||
|
||||
for x = minp.x, maxp.x do
|
||||
for y = minp.y, maxp.y do
|
||||
for z = minp.z, maxp.z do
|
||||
local pos = {x = x, y = y, z = z}
|
||||
new_active_blocks[minetest.hash_node_position(pos)] = pos
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
active_blocks = new_active_blocks
|
||||
-- todo: callbacks on block load/unload
|
||||
end
|
||||
end)
|
||||
|
||||
local function is_active(pos)
|
||||
return active_blocks[minetest.hash_node_position(get_blockpos(pos))] ~= nil
|
||||
end
|
||||
|
||||
local entitydef_default = {
|
||||
_attach = function(self, attached, attach_to)
|
||||
local attached_def = self._attached_entities[attached]
|
||||
local attach_to_def = self._attached_entities[attach_to]
|
||||
attached_def.entity:set_attach(
|
||||
attach_to_def.entity, "",
|
||||
vector.subtract(attached_def.offset, attach_to_def.offset), -- todo: Does not work because is object space
|
||||
vector.new(0, 0, 0)
|
||||
)
|
||||
end,
|
||||
_set_master = function(self, index)
|
||||
self._attached_entities_master = index
|
||||
if not index then
|
||||
return
|
||||
end
|
||||
local def = self._attached_entities[index]
|
||||
if not def.entity then
|
||||
return
|
||||
end
|
||||
def.entity:setpos(vector.add(self._pos, def.offset))
|
||||
def.entity:setvelocity(self._velocity)
|
||||
def.entity:setacceleration(self._acceleration)
|
||||
end,
|
||||
_attach_all = function(self)
|
||||
local master = self._attached_entities_master
|
||||
if not master then
|
||||
return
|
||||
end
|
||||
for id, entity in pairs(self._attached_entities) do
|
||||
if id ~= master and entity.entity then
|
||||
self:_attach(id, master)
|
||||
end
|
||||
end
|
||||
end,
|
||||
_detach_all = function(self)
|
||||
local master = self._attached_entities_master
|
||||
for id, entity in pairs(self._attached_entities) do
|
||||
if id ~= master and entity.entity then
|
||||
entity.entity:set_detach()
|
||||
end
|
||||
end
|
||||
end,
|
||||
_add_attached = function(self, index)
|
||||
local entity = self._attached_entities[index]
|
||||
if entity.entity then
|
||||
return
|
||||
end
|
||||
local entity_pos = vector.add(self._pos, entity.offset)
|
||||
if not is_active(entity_pos) then
|
||||
return
|
||||
end
|
||||
local ent = minetest.add_entity(entity_pos, entity.name):get_luaentity()
|
||||
ent:from_data(entity.data)
|
||||
ent.parent_id = self._id
|
||||
ent.attached_id = index
|
||||
entity.entity = ent.object
|
||||
local master = self._attached_entities_master
|
||||
if master then
|
||||
self:_attach(index, master)
|
||||
else
|
||||
self:_set_master(index)
|
||||
end
|
||||
end,
|
||||
_remove_attached = function(self, index)
|
||||
local master = self._attached_entities_master
|
||||
local entity = self._attached_entities[index]
|
||||
local ent = entity.entity
|
||||
entity.entity = nil
|
||||
if index == master then
|
||||
self:_detach_all()
|
||||
local newmaster
|
||||
for id, attached in pairs(self._attached_entities) do
|
||||
if id ~= master and attached.entity then
|
||||
newmaster = id
|
||||
break
|
||||
end
|
||||
end
|
||||
self:_set_master(newmaster)
|
||||
self:_attach_all()
|
||||
elseif master and ent then
|
||||
ent:set_detach()
|
||||
end
|
||||
if ent then
|
||||
ent:remove()
|
||||
end
|
||||
end,
|
||||
_add_loaded = function(self)
|
||||
for id, _ in pairs(self._attached_entities) do
|
||||
self:_add_attached(id)
|
||||
end
|
||||
end,
|
||||
getid = function(self)
|
||||
return self._id
|
||||
end,
|
||||
getpos = function(self)
|
||||
return vector.new(self._pos)
|
||||
end,
|
||||
setpos = function(self, pos)
|
||||
self._pos = vector.new(pos)
|
||||
--for _, entity in pairs(self._attached_entities) do
|
||||
-- if entity.entity then
|
||||
-- entity.entity:setpos(vector.add(self._pos, entity.offset))
|
||||
-- end
|
||||
--end
|
||||
local master = self._attached_entities_master
|
||||
if master then
|
||||
local master_def = self._attached_entities[master]
|
||||
master_def.entity:setpos(vector.add(self._pos, master_def.offset))
|
||||
end
|
||||
end,
|
||||
getvelocity = function(self)
|
||||
return vector.new(self._velocity)
|
||||
end,
|
||||
setvelocity = function(self, velocity)
|
||||
self._velocity = vector.new(velocity)
|
||||
local master = self._attached_entities_master
|
||||
if master then
|
||||
self._attached_entities[master].entity:setvelocity(self._velocity)
|
||||
end
|
||||
end,
|
||||
getacceleration = function(self)
|
||||
return vector.new(self._acceleration)
|
||||
end,
|
||||
setacceleration = function(self, acceleration)
|
||||
self._acceleration = vector.new(acceleration)
|
||||
local master = self._attached_entities_master
|
||||
if master then
|
||||
self._attached_entities[master].entity:setacceleration(self._acceleration)
|
||||
end
|
||||
end,
|
||||
remove = function(self)
|
||||
self:_detach_all()
|
||||
for _, entity in pairs(self._attached_entities) do
|
||||
if entity.entity then
|
||||
entity.entity:remove()
|
||||
end
|
||||
end
|
||||
luaentity.entities[self._id] = nil
|
||||
end,
|
||||
add_attached_entity = function(self, name, data, offset)
|
||||
local index = #self._attached_entities + 1
|
||||
self._attached_entities[index] = {
|
||||
name = name,
|
||||
data = data,
|
||||
offset = vector.new(offset),
|
||||
}
|
||||
self:_add_attached(index)
|
||||
return index
|
||||
end,
|
||||
remove_attached_entity = function(self, index)
|
||||
self:_remove_attached(index)
|
||||
self._attached_entities[index] = nil
|
||||
end,
|
||||
}
|
||||
|
||||
function luaentity.register_entity(name, prototype)
|
||||
-- name = check_modname_prefix(name)
|
||||
prototype.name = name
|
||||
setmetatable(prototype, {__index = entitydef_default})
|
||||
prototype.__index = prototype -- Make it possible to use it as metatable
|
||||
luaentity.registered_entities[name] = prototype
|
||||
end
|
||||
|
||||
-- function luaentity.get_entity_definition(entity)
|
||||
-- return luaentity.registered_entities[entity.name]
|
||||
-- end
|
||||
|
||||
function luaentity.add_entity(pos, name)
|
||||
local index = luaentity.entities_index
|
||||
while luaentity.entities[index] do
|
||||
index = index + 1
|
||||
if index >= max_entity_id then
|
||||
index = 0
|
||||
end
|
||||
end
|
||||
luaentity.entities_index = index
|
||||
|
||||
local entity = {
|
||||
name = name,
|
||||
_id = index,
|
||||
_pos = vector.new(pos),
|
||||
_velocity = {x = 0, y = 0, z = 0},
|
||||
_acceleration = {x = 0, y = 0, z = 0},
|
||||
_attached_entities = {},
|
||||
}
|
||||
|
||||
local prototype = luaentity.registered_entities[name]
|
||||
setmetatable(entity, prototype) -- Default to prototype for other methods
|
||||
luaentity.entities[index] = entity
|
||||
|
||||
if entity.on_activate then
|
||||
entity:on_activate()
|
||||
end
|
||||
return entity
|
||||
end
|
||||
|
||||
-- todo: check if remove in get_staticdata works
|
||||
function luaentity.get_staticdata(self)
|
||||
local parent = luaentity.entities[self.parent_id]
|
||||
if parent and parent._remove_attached then
|
||||
parent:_remove_attached(self.attached_id)
|
||||
end
|
||||
return "toremove"
|
||||
end
|
||||
|
||||
function luaentity.on_activate(self, staticdata)
|
||||
if staticdata == "toremove" then
|
||||
self.object:remove()
|
||||
end
|
||||
end
|
||||
|
||||
function luaentity.get_objects_inside_radius(pos, radius)
|
||||
local objects = {}
|
||||
local index = 1
|
||||
for id, entity in pairs(luaentity.entities) do
|
||||
if vector.distance(pos, entity:getpos()) <= radius then
|
||||
objects[index] = entity
|
||||
index = index + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
for id, entity in pairs(luaentity.entities) do
|
||||
local master = entity._attached_entities_master
|
||||
if master then
|
||||
local master_def = entity._attached_entities[master]
|
||||
local master_entity = master_def.entity
|
||||
entity._pos = vector.subtract(master_entity:getpos(), master_def.offset)
|
||||
entity._velocity = master_entity:getvelocity()
|
||||
entity._acceleration = master_entity:getacceleration()
|
||||
else
|
||||
entity._pos = vector.add(vector.add(
|
||||
entity._pos,
|
||||
vector.multiply(entity._velocity, dtime)),
|
||||
vector.multiply(entity._acceleration, 0.5 * dtime * dtime))
|
||||
entity._velocity = vector.add(
|
||||
entity._velocity,
|
||||
vector.multiply(entity._acceleration, dtime))
|
||||
end
|
||||
entity:_add_loaded()
|
||||
if entity.on_step then
|
||||
entity:on_step(dtime)
|
||||
end
|
||||
end
|
||||
end)
|
10
trashcan.lua
10
trashcan.lua
|
@ -9,15 +9,13 @@ minetest.register_node("pipeworks:trashcan", {
|
|||
"pipeworks_trashcan_side.png",
|
||||
"pipeworks_trashcan_side.png",
|
||||
},
|
||||
groups = { snappy = 3, tubedevice = 1, tubedevice_receiver = 1 },
|
||||
groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1},
|
||||
tube = {
|
||||
insert_object = function(pos, node, stack, direction)
|
||||
return ItemStack("")
|
||||
end,
|
||||
can_insert = function(pos, node, stack, direction)
|
||||
return true
|
||||
end,
|
||||
connect_sides = { left = 1, right = 1, front = 1, back = 1, top = 1, bottom = 1 },
|
||||
end,
|
||||
connect_sides = {left = 1, right = 1, front = 1, back = 1, top = 1, bottom = 1},
|
||||
priority = 1, -- Lower than anything else
|
||||
},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
|
|
271
tubes.lua
Normal file → Executable file
271
tubes.lua
Normal file → Executable file
|
@ -20,7 +20,7 @@ local register_one_tube = function(name, tname, dropname, desc, plain, noctrs, e
|
|||
end
|
||||
|
||||
for _, v in ipairs(connects) do
|
||||
pipeworks.add_node_box(outboxes, pipeworks.tube_boxes[v])
|
||||
table.extend(outboxes, pipeworks.tube_boxes[v])
|
||||
table.insert(outsel, pipeworks.tube_selectboxes[v])
|
||||
outimgs[vti[v]] = noctrs[v]
|
||||
end
|
||||
|
@ -31,13 +31,13 @@ local register_one_tube = function(name, tname, dropname, desc, plain, noctrs, e
|
|||
outimgs[vti[v]] = ends[v]
|
||||
end
|
||||
|
||||
local tgroups = {snappy = 3, tube = 1, not_in_creative_inventory = 1}
|
||||
local tgroups = {snappy = 3, tube = 1, tubedevice = 1, not_in_creative_inventory = 1}
|
||||
local tubedesc = desc.." "..dump(connects).."... You hacker, you."
|
||||
local iimg = plain[1]
|
||||
local wscale = {x = 1, y = 1, z = 1}
|
||||
|
||||
if #connects == 0 then
|
||||
tgroups = {snappy = 3, tube = 1}
|
||||
tgroups = {snappy = 3, tube = 1, tubedevice = 1}
|
||||
tubedesc = desc
|
||||
iimg=inv
|
||||
outimgs = {
|
||||
|
@ -50,7 +50,8 @@ local register_one_tube = function(name, tname, dropname, desc, plain, noctrs, e
|
|||
wscale = {x = 1, y = 1, z = 0.01}
|
||||
end
|
||||
|
||||
table.insert(pipeworks.tubenodes, name.."_"..tname)
|
||||
local rname = name.."_"..tname
|
||||
table.insert(pipeworks.tubenodes, rname)
|
||||
|
||||
local nodedef = {
|
||||
description = tubedesc,
|
||||
|
@ -62,7 +63,7 @@ local register_one_tube = function(name, tname, dropname, desc, plain, noctrs, e
|
|||
wield_scale = wscale,
|
||||
paramtype = "light",
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
type = "fixed",
|
||||
fixed = outsel
|
||||
},
|
||||
node_box = {
|
||||
|
@ -77,26 +78,22 @@ local register_one_tube = function(name, tname, dropname, desc, plain, noctrs, e
|
|||
style = style,
|
||||
drop = name.."_"..dropname,
|
||||
tubelike = 1,
|
||||
tube = {connect_sides = {front = 1, back = 1, left = 1, right = 1, top = 1, bottom = 1}},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("tubelike", 1)
|
||||
if minetest.registered_nodes[name.."_"..tname].on_construct_ then
|
||||
minetest.registered_nodes[name.."_"..tname].on_construct_(pos)
|
||||
end
|
||||
end,
|
||||
after_place_node = function(pos)
|
||||
tube = {
|
||||
connect_sides = {front = 1, back = 1, left = 1, right = 1, top = 1, bottom = 1},
|
||||
priority = 50
|
||||
},
|
||||
--[[after_place_node = function(pos)
|
||||
pipeworks.scan_for_tube_objects(pos)
|
||||
if minetest.registered_nodes[name.."_"..tname].after_place_node_ then
|
||||
minetest.registered_nodes[name.."_"..tname].after_place_node_(pos)
|
||||
if minetest.registered_nodes[rname].after_place_node_ then
|
||||
minetest.registered_nodes[rname].after_place_node_(pos)
|
||||
end
|
||||
end,
|
||||
after_dig_node = function(pos)
|
||||
pipeworks.scan_for_tube_objects(pos)
|
||||
if minetest.registered_nodes[name.."_"..tname].after_dig_node_ then
|
||||
minetest.registered_nodes[name.."_"..tname].after_dig_node_(pos)
|
||||
if minetest.registered_nodes[rname].after_dig_node_ then
|
||||
minetest.registered_nodes[rname].after_dig_node_(pos)
|
||||
end
|
||||
end
|
||||
end]]
|
||||
}
|
||||
if style == "6d" then
|
||||
nodedef.paramtype2 = "facedir"
|
||||
|
@ -105,9 +102,9 @@ local register_one_tube = function(name, tname, dropname, desc, plain, noctrs, e
|
|||
if special == nil then special = {} end
|
||||
|
||||
for key, value in pairs(special) do
|
||||
if key == "on_construct" or key == "after_dig_node" or key == "after_place_node" then
|
||||
nodedef[key.."_"] = value
|
||||
elseif key == "groups" then
|
||||
--if key == "after_dig_node" or key == "after_place_node" then
|
||||
-- nodedef[key.."_"] = value
|
||||
if key == "groups" then
|
||||
for group, val in pairs(value) do
|
||||
nodedef.groups[group] = val
|
||||
end
|
||||
|
@ -115,19 +112,12 @@ local register_one_tube = function(name, tname, dropname, desc, plain, noctrs, e
|
|||
for key, val in pairs(value) do
|
||||
nodedef.tube[key] = val
|
||||
end
|
||||
elseif type(value) == "table" then
|
||||
nodedef[key] = pipeworks.replace_name(value, "#id", tname)
|
||||
elseif type(value) == "string" then
|
||||
nodedef[key] = string.gsub(value, "#id", tname)
|
||||
else
|
||||
nodedef[key] = value
|
||||
nodedef[key] = table.recursive_replace(value, "#id", tname)
|
||||
end
|
||||
end
|
||||
|
||||
local prefix = ":"
|
||||
if string.find(name, "pipeworks:") then prefix = "" end
|
||||
|
||||
minetest.register_node(prefix..name.."_"..tname, nodedef)
|
||||
minetest.register_node(rname, nodedef)
|
||||
end
|
||||
|
||||
pipeworks.register_tube = function(name, desc, plain, noctrs, ends, short, inv, special, old_registration)
|
||||
|
@ -181,22 +171,18 @@ pipeworks.register_tube = function(name, desc, plain, noctrs, ends, short, inv,
|
|||
wield_image = inv,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
description = desc.." (legacy)",
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("tubelike", 1)
|
||||
end,
|
||||
after_place_node = function(pos)
|
||||
description = "Pneumatic tube segment (legacy)",
|
||||
--[[after_place_node = function(pos)
|
||||
pipeworks.scan_for_tube_objects(pos)
|
||||
if minetest.registered_nodes[name.."_1"].after_place_node_ then
|
||||
minetest.registered_nodes[name.."_1"].after_place_node_(pos)
|
||||
end
|
||||
end,
|
||||
groups = {not_in_creative_inventory = 1, tube_to_update = 1},
|
||||
end,]]
|
||||
groups = {not_in_creative_inventory = 1, tube_to_update = 1, tube = 1},
|
||||
tube = {connect_sides = {front = 1, back = 1, left = 1, right = 1, top = 1, bottom = 1}},
|
||||
drop = name.."_1",
|
||||
})
|
||||
table.insert(pipeworks.tubenodes,cname)
|
||||
table.insert(pipeworks.tubenodes, cname)
|
||||
for xm = 0, 1 do
|
||||
for xp = 0, 1 do
|
||||
for ym = 0, 1 do
|
||||
|
@ -221,8 +207,8 @@ if REGISTER_COMPATIBILITY then
|
|||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
local minp = {x = pos.x-1, y = pos.y-1, z = pos.z-1}
|
||||
local maxp = {x = pos.x+1, y = pos.y+1, z = pos.z+1}
|
||||
local minp = vector.subtract(pos, 1)
|
||||
local maxp = vector.add(pos, 1)
|
||||
if table.getn(minetest.find_nodes_in_area(minp, maxp, "ignore")) == 0 then
|
||||
pipeworks.scan_for_tube_objects(pos)
|
||||
end
|
||||
|
@ -241,7 +227,7 @@ local end_textures = {"pipeworks_tube_end.png", "pipeworks_tube_end.png", "pipew
|
|||
local short_texture = "pipeworks_tube_short.png"
|
||||
local inv_texture = "pipeworks_tube_inv.png"
|
||||
|
||||
pipeworks.register_tube("pipeworks:tube", "Pneumatic Tube Segment", plain_textures, noctr_textures, end_textures, short_texture, inv_texture)
|
||||
pipeworks.register_tube("pipeworks:tube", "Pneumatic tube segment", plain_textures, noctr_textures, end_textures, short_texture, inv_texture)
|
||||
|
||||
if pipeworks.enable_mese_tube then
|
||||
local mese_noctr_textures = {"pipeworks_mese_tube_noctr_1.png", "pipeworks_mese_tube_noctr_2.png", "pipeworks_mese_tube_noctr_3.png",
|
||||
|
@ -252,6 +238,39 @@ if pipeworks.enable_mese_tube then
|
|||
"pipeworks_mese_tube_end.png", "pipeworks_mese_tube_end.png", "pipeworks_mese_tube_end.png"}
|
||||
local mese_short_texture = "pipeworks_mese_tube_short.png"
|
||||
local mese_inv_texture = "pipeworks_mese_tube_inv.png"
|
||||
local function update_formspec(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local old_formspec = meta:get_string("formspec")
|
||||
if string.find(old_formspec, "button0") then -- Old version
|
||||
local inv = meta:get_inventory()
|
||||
for i = 1, 6 do
|
||||
for _, stack in ipairs(inv:get_list("line"..i)) do
|
||||
minetest.item_drop(stack, "", pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
meta:set_string("formspec",
|
||||
"size[8,11]"..
|
||||
"list[current_name;line1;1,0;6,1;]"..
|
||||
"list[current_name;line2;1,1;6,1;]"..
|
||||
"list[current_name;line3;1,2;6,1;]"..
|
||||
"list[current_name;line4;1,3;6,1;]"..
|
||||
"list[current_name;line5;1,4;6,1;]"..
|
||||
"list[current_name;line6;1,5;6,1;]"..
|
||||
"image[0,0;1,1;pipeworks_white.png]"..
|
||||
"image[0,1;1,1;pipeworks_black.png]"..
|
||||
"image[0,2;1,1;pipeworks_green.png]"..
|
||||
"image[0,3;1,1;pipeworks_yellow.png]"..
|
||||
"image[0,4;1,1;pipeworks_blue.png]"..
|
||||
"image[0,5;1,1;pipeworks_red.png]"..
|
||||
fs_helpers.cycling_button(meta, "button[7,0;1,1", "b1s", {"Off", "On"})..
|
||||
fs_helpers.cycling_button(meta, "button[7,1;1,1", "b2s", {"Off", "On"})..
|
||||
fs_helpers.cycling_button(meta, "button[7,2;1,1", "b3s", {"Off", "On"})..
|
||||
fs_helpers.cycling_button(meta, "button[7,3;1,1", "b4s", {"Off", "On"})..
|
||||
fs_helpers.cycling_button(meta, "button[7,4;1,1", "b5s", {"Off", "On"})..
|
||||
fs_helpers.cycling_button(meta, "button[7,5;1,1", "b6s", {"Off", "On"})..
|
||||
"list[current_player;main;0,7;8,4;]")
|
||||
end
|
||||
pipeworks.register_tube("pipeworks:mese_tube", "Sorting Pneumatic Tube Segment", mese_plain_textures, mese_noctr_textures,
|
||||
mese_end_textures, mese_short_texture, mese_inv_texture,
|
||||
{tube = {can_go = function(pos, node, velocity, stack)
|
||||
|
@ -266,6 +285,7 @@ if pipeworks.enable_mese_tube then
|
|||
if st:get_name() == name then
|
||||
found = true
|
||||
table.insert(tbl, vect)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -288,71 +308,37 @@ if pipeworks.enable_mese_tube then
|
|||
meta:set_int("l"..tostring(i).."s", 1)
|
||||
inv:set_size("line"..tostring(i), 6*1)
|
||||
end
|
||||
meta:set_string("formspec",
|
||||
"size[8,11]"..
|
||||
"list[current_name;line1;1,0;6,1;]"..
|
||||
"list[current_name;line2;1,1;6,1;]"..
|
||||
"list[current_name;line3;1,2;6,1;]"..
|
||||
"list[current_name;line4;1,3;6,1;]"..
|
||||
"list[current_name;line5;1,4;6,1;]"..
|
||||
"list[current_name;line6;1,5;6,1;]"..
|
||||
"image[0,0;1,1;pipeworks_white.png]"..
|
||||
"image[0,1;1,1;pipeworks_black.png]"..
|
||||
"image[0,2;1,1;pipeworks_green.png]"..
|
||||
"image[0,3;1,1;pipeworks_yellow.png]"..
|
||||
"image[0,4;1,1;pipeworks_blue.png]"..
|
||||
"image[0,5;1,1;pipeworks_red.png]"..
|
||||
"button[7,0;1,1;button10;On]"..
|
||||
"button[7,1;1,1;button20;On]"..
|
||||
"button[7,2;1,1;button30;On]"..
|
||||
"button[7,3;1,1;button40;On]"..
|
||||
"button[7,4;1,1;button50;On]"..
|
||||
"button[7,5;1,1;button60;On]"..
|
||||
"list[current_player;main;0,7;8,4;]")
|
||||
meta:set_string("infotext", "Sorting Pneumatic Tube Segment")
|
||||
update_formspec(pos)
|
||||
meta:set_string("infotext", "Mese pneumatic tube")
|
||||
end,
|
||||
on_punch = update_formspec,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local i
|
||||
if fields.quit then return end
|
||||
for key, _ in pairs(fields) do
|
||||
if key:sub(1, 6) == "button" then
|
||||
local i = key:sub(7, 7)
|
||||
local s = key:sub(8, 8)
|
||||
if s == "" then s = 1 - meta:get_int("l"..i.."s") end
|
||||
meta:set_int("l"..i.."s", s)
|
||||
end
|
||||
end
|
||||
local frm = "size[8,11]"..
|
||||
"list[current_name;line1;1,0;6,1;]"..
|
||||
"list[current_name;line2;1,1;6,1;]"..
|
||||
"list[current_name;line3;1,2;6,1;]"..
|
||||
"list[current_name;line4;1,3;6,1;]"..
|
||||
"list[current_name;line5;1,4;6,1;]"..
|
||||
"list[current_name;line6;1,5;6,1;]"..
|
||||
"image[0,0;1,1;pipeworks_white.png]"..
|
||||
"image[0,1;1,1;pipeworks_black.png]"..
|
||||
"image[0,2;1,1;pipeworks_green.png]"..
|
||||
"image[0,3;1,1;pipeworks_yellow.png]"..
|
||||
"image[0,4;1,1;pipeworks_blue.png]"..
|
||||
"image[0,5;1,1;pipeworks_red.png]"
|
||||
for i = 1, 6 do
|
||||
local st = meta:get_int("l"..tostring(i).."s")
|
||||
if st == 0 then
|
||||
frm = frm.."button[7,"..tostring(i-1)..";1,1;button"..tostring(i).."1;Off]"
|
||||
else
|
||||
frm = frm.."button[7,"..tostring(i-1)..";1,1;button"..tostring(i).."0;On]"
|
||||
end
|
||||
end
|
||||
frm = frm.."list[current_player;main;0,7;8,4;]"
|
||||
meta:set_string("formspec", frm)
|
||||
fs_helpers.on_receive_fields(pos, fields)
|
||||
update_formspec(pos)
|
||||
end,
|
||||
can_dig = function(pos, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return (inv:is_empty("line1") and inv:is_empty("line2") and inv:is_empty("line3") and
|
||||
inv:is_empty("line4") and inv:is_empty("line5") and inv:is_empty("line6"))
|
||||
end
|
||||
end,
|
||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
local inv = minetest.get_meta(pos):get_inventory()
|
||||
local stack_copy = ItemStack(stack)
|
||||
stack_copy:set_count(1)
|
||||
inv:set_stack(listname, index, stack_copy)
|
||||
return 0
|
||||
end,
|
||||
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||
local inv = minetest.get_meta(pos):get_inventory()
|
||||
inv:set_stack(listname, index, ItemStack(""))
|
||||
return 0
|
||||
end,
|
||||
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
local inv = minetest.get_meta(pos):get_inventory()
|
||||
inv:set_stack(from_list, from_index, ItemStack(""))
|
||||
return 0
|
||||
end,
|
||||
}, true) -- Must use old tubes, since the textures are rotated with 6d ones
|
||||
end
|
||||
|
||||
|
@ -360,6 +346,7 @@ if pipeworks.enable_detector_tube then
|
|||
local detector_plain_textures = {"pipeworks_detector_tube_plain.png", "pipeworks_detector_tube_plain.png", "pipeworks_detector_tube_plain.png",
|
||||
"pipeworks_detector_tube_plain.png", "pipeworks_detector_tube_plain.png", "pipeworks_detector_tube_plain.png"}
|
||||
local detector_inv_texture = "pipeworks_detector_tube_inv.png"
|
||||
local detector_tube_step = 2 * tonumber(minetest.setting_get("dedicated_server_step"))
|
||||
pipeworks.register_tube("pipeworks:detector_tube_on", "Detecting Pneumatic Tube Segment on (you hacker you)", detector_plain_textures, noctr_textures,
|
||||
end_textures, short_texture, detector_inv_texture,
|
||||
{tube = {can_go = function(pos, node, velocity, stack)
|
||||
|
@ -367,12 +354,8 @@ if pipeworks.enable_detector_tube then
|
|||
local name = minetest.get_node(pos).name
|
||||
local nitems = meta:get_int("nitems")+1
|
||||
meta:set_int("nitems", nitems)
|
||||
local saved_pos = { x = pos.x, y = pos.y, z = pos.z }
|
||||
minetest.after(0, function ()
|
||||
minetest.after(0, function ()
|
||||
minetest.after(0, minetest.registered_nodes[name].item_exit, saved_pos)
|
||||
end)
|
||||
end)
|
||||
local saved_pos = vector.new(pos)
|
||||
minetest.after(detector_tube_step, minetest.registered_nodes[name].item_exit, saved_pos)
|
||||
return pipeworks.notvel(pipeworks.meseadjlist,velocity)
|
||||
end},
|
||||
groups = {mesecon = 2, not_in_creative_inventory = 1},
|
||||
|
@ -396,13 +379,11 @@ if pipeworks.enable_detector_tube then
|
|||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("nitems", 1)
|
||||
local name = minetest.get_node(pos).name
|
||||
local saved_pos = { x = pos.x, y = pos.y, z = pos.z }
|
||||
minetest.after(0, function ()
|
||||
minetest.after(0, function ()
|
||||
minetest.after(0, minetest.registered_nodes[name].item_exit, saved_pos)
|
||||
end)
|
||||
end)
|
||||
end})
|
||||
local saved_pos = vector.new(pos)
|
||||
minetest.after(detector_tube_step, minetest.registered_nodes[name].item_exit, saved_pos)
|
||||
|
||||
end
|
||||
})
|
||||
pipeworks.register_tube("pipeworks:detector_tube_off", "Detecting Pneumatic Tube Segment", detector_plain_textures, noctr_textures,
|
||||
end_textures, short_texture, detector_inv_texture,
|
||||
{tube = {can_go = function(pos, node, velocity, stack)
|
||||
|
@ -474,7 +455,6 @@ if pipeworks.enable_accelerator_tube then
|
|||
end
|
||||
|
||||
if pipeworks.enable_crossing_tube then
|
||||
-- FIXME: The textures are not the correct ones
|
||||
local crossing_noctr_textures = {"pipeworks_crossing_tube_noctr.png", "pipeworks_crossing_tube_noctr.png", "pipeworks_crossing_tube_noctr.png",
|
||||
"pipeworks_crossing_tube_noctr.png", "pipeworks_crossing_tube_noctr.png", "pipeworks_crossing_tube_noctr.png"}
|
||||
local crossing_plain_textures = {"pipeworks_crossing_tube_plain.png" ,"pipeworks_crossing_tube_plain.png", "pipeworks_crossing_tube_plain.png",
|
||||
|
@ -513,10 +493,7 @@ if pipeworks.enable_sand_tube then
|
|||
for _, object in ipairs(minetest.get_objects_inside_radius(pos, 2)) do
|
||||
if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then
|
||||
if object:get_luaentity().itemstring ~= "" then
|
||||
local titem = pipeworks.tube_item(pos,object:get_luaentity().itemstring)
|
||||
titem:get_luaentity().start_pos = {x = pos.x, y = pos.y-1, z = pos.z}
|
||||
titem:setvelocity({x = 0.01, y = 1, z = -0.01})
|
||||
titem:setacceleration({x = 0, y = 0, z = 0})
|
||||
pipeworks.tube_item(pos, pos, vector.new(0, 0, 0), object:get_luaentity().itemstring)
|
||||
end
|
||||
object:get_luaentity().itemstring = ""
|
||||
object:remove()
|
||||
|
@ -576,10 +553,7 @@ if pipeworks.enable_mese_sand_tube then
|
|||
for _,object in ipairs(get_objects_with_square_radius(pos, minetest.env:get_meta(pos):get_int("dist"))) do
|
||||
if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then
|
||||
if object:get_luaentity().itemstring ~= "" then
|
||||
local titem = pipeworks.tube_item(pos, object:get_luaentity().itemstring)
|
||||
titem:get_luaentity().start_pos = {x = pos.x, y = pos.y-1, z = pos.z}
|
||||
titem:setvelocity({x = 0.01, y = 1, z = -0.01})
|
||||
titem:setacceleration({x = 0, y = 0, z = 0})
|
||||
pipeworks.tube_item(pos, pos, vector.new(0, 0, 0), object:get_luaentity().itemstring)
|
||||
end
|
||||
object:get_luaentity().itemstring = ""
|
||||
object:remove()
|
||||
|
@ -589,26 +563,9 @@ if pipeworks.enable_mese_sand_tube then
|
|||
})
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
if pipeworks.enable_one_way_tube then
|
||||
minetest.register_node("pipeworks:one_way_tube", {
|
||||
description = "One-way Pneumatic Tube Segment",
|
||||
description = "One way tube",
|
||||
tiles = {"pipeworks_one_way_tube_top.png", "pipeworks_one_way_tube_top.png", "pipeworks_one_way_tube_output.png",
|
||||
"pipeworks_one_way_tube_input.png", "pipeworks_one_way_tube_side.png", "pipeworks_one_way_tube_top.png"},
|
||||
paramtype2 = "facedir",
|
||||
|
@ -616,35 +573,19 @@ if pipeworks.enable_one_way_tube then
|
|||
paramtype = "light",
|
||||
node_box = {type = "fixed",
|
||||
fixed = {{-1/2, -9/64, -9/64, 1/2, 9/64, 9/64}}},
|
||||
groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, tubedevice = 1, tubedevice_receiver = 1},
|
||||
groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, tubedevice = 1},
|
||||
legacy_facedir_simple = true,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
on_construct = function(pos)
|
||||
minetest.get_meta(pos):set_int("tubelike", 1)
|
||||
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,
|
||||
tube = {connect_sides = {left = 1, right = 1},
|
||||
tube = {
|
||||
connect_sides = {left = 1, right = 1},
|
||||
can_go = function(pos, node, velocity, stack)
|
||||
return velocity
|
||||
end,
|
||||
insert_object = function(pos, node, stack, direction)
|
||||
item1 = pipeworks.tube_item(pos, stack)
|
||||
item1:get_luaentity().start_pos = pos
|
||||
item1:setvelocity({x = direction.x*direction.speed, y = direction.y*direction.speed, z = direction.z*direction.speed})
|
||||
item1:setacceleration({x = 0, y = 0, z = 0})
|
||||
return ItemStack("")
|
||||
return {velocity}
|
||||
end,
|
||||
can_insert = function(pos, node, stack, direction)
|
||||
local dir = facedir_to_right_dir(node.param2)
|
||||
if dir.x == direction.x and dir.y == direction.y and dir.z == direction.z then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end},
|
||||
local dir = minetest.facedir_to_right_dir(node.param2)
|
||||
return vector.equals(dir, direction)
|
||||
end,
|
||||
priority = 75 -- Higher than normal tubes, but lower than receivers
|
||||
},
|
||||
})
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user