forked from mtcontrib/pipeworks
code and registrations cleanup (#101)
* code and registrations cleanup * don't expose materials to global env --------- Co-authored-by: BuckarooBanzay <BuckarooBanzay@users.noreply.github.com>
This commit is contained in:
68
tubes/embedded_tube.lua
Normal file
68
tubes/embedded_tube.lua
Normal file
@ -0,0 +1,68 @@
|
||||
local materials = ...
|
||||
local S = minetest.get_translator("pipeworks")
|
||||
|
||||
local straight = function(pos, node, velocity, stack) return {velocity} end
|
||||
local steel_tex = "[combine:16x16^[noalpha^[colorize:#D3D3D3"
|
||||
if minetest.get_modpath("default") then steel_tex = "default_steel_block.png" end
|
||||
|
||||
-- register an embedded tube
|
||||
function pipeworks.register_embedded_tube(nodename, opts)
|
||||
minetest.register_node(nodename, {
|
||||
description = opts.description,
|
||||
tiles = {
|
||||
opts.base_texture,
|
||||
opts.base_texture,
|
||||
opts.base_texture,
|
||||
opts.base_texture,
|
||||
opts.base_texture .. "^pipeworks_tube_connection_metallic.png",
|
||||
opts.base_texture .. "^pipeworks_tube_connection_metallic.png",
|
||||
},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {
|
||||
cracky = 1,
|
||||
oddly_breakable_by_hand = 1,
|
||||
tubedevice = 1,
|
||||
dig_glass = 2,
|
||||
pickaxey=1,
|
||||
handy=1
|
||||
},
|
||||
_mcl_hardness = 0.8,
|
||||
legacy_facedir_simple = true,
|
||||
_sound_def = {
|
||||
key = "node_sound_stone_defaults",
|
||||
},
|
||||
tube = {
|
||||
connect_sides = {
|
||||
front = 1,
|
||||
back = 1
|
||||
},
|
||||
priority = 50,
|
||||
can_go = straight,
|
||||
can_insert = function(pos, node, stack, direction)
|
||||
local dir = minetest.facedir_to_dir(node.param2)
|
||||
return vector.equals(dir, direction) or vector.equals(vector.multiply(dir, -1), direction)
|
||||
end
|
||||
},
|
||||
after_place_node = pipeworks.after_place,
|
||||
after_dig_node = pipeworks.after_dig,
|
||||
on_rotate = pipeworks.on_rotate,
|
||||
})
|
||||
|
||||
minetest.register_craft( {
|
||||
output = nodename .. " 1",
|
||||
recipe = {
|
||||
{ opts.base_ingredient, opts.base_ingredient, opts.base_ingredient },
|
||||
{ opts.base_ingredient, "pipeworks:tube_1", opts.base_ingredient },
|
||||
{ opts.base_ingredient, opts.base_ingredient, opts.base_ingredient }
|
||||
},
|
||||
})
|
||||
pipeworks.ui_cat_tube_list[#pipeworks.ui_cat_tube_list+1] = nodename
|
||||
end
|
||||
|
||||
-- steelblock embedded tube
|
||||
pipeworks.register_embedded_tube("pipeworks:steel_block_embedded_tube", {
|
||||
description = S("Airtight steelblock embedded tube"),
|
||||
base_texture = steel_tex,
|
||||
base_ingredient = materials.steel_ingot
|
||||
})
|
1073
tubes/lua.lua
Normal file
1073
tubes/lua.lua
Normal file
File diff suppressed because it is too large
Load Diff
52
tubes/pane_embedded_tube.lua
Normal file
52
tubes/pane_embedded_tube.lua
Normal file
@ -0,0 +1,52 @@
|
||||
local S = minetest.get_translator("pipeworks")
|
||||
|
||||
local straight = function(pos, node, velocity, stack) return {velocity} end
|
||||
|
||||
local pane_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -9/64, -9/64, -8/16, 9/64, 9/64, 8/16 }, -- tube
|
||||
{ -8/16, -8/16, -1/16, 8/16, 8/16, 1/16 } -- pane
|
||||
}
|
||||
}
|
||||
|
||||
local texture_alpha_mode = minetest.features.use_texture_alpha_string_modes
|
||||
and "clip" or true
|
||||
|
||||
minetest.register_node("pipeworks:steel_pane_embedded_tube", {
|
||||
drawtype = "nodebox",
|
||||
description = S("Airtight panel embedded tube"),
|
||||
tiles = {
|
||||
pipeworks.make_tube_tile("pipeworks_pane_embedded_tube_sides.png^[transformR90"),
|
||||
pipeworks.make_tube_tile("pipeworks_pane_embedded_tube_sides.png^[transformR90"),
|
||||
pipeworks.make_tube_tile("pipeworks_pane_embedded_tube_sides.png"),
|
||||
pipeworks.make_tube_tile("pipeworks_pane_embedded_tube_sides.png"),
|
||||
pipeworks.make_tube_tile("pipeworks_pane_embedded_tube_ends.png"),
|
||||
pipeworks.make_tube_tile("pipeworks_pane_embedded_tube_ends.png"),
|
||||
},
|
||||
use_texture_alpha = texture_alpha_mode,
|
||||
node_box = pane_box,
|
||||
selection_box = pane_box,
|
||||
collision_box = pane_box,
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=1, oddly_breakable_by_hand = 1, tubedevice = 1, dig_glass = 2, pickaxey=1, handy=1},
|
||||
_mcl_hardness=0.8,
|
||||
legacy_facedir_simple = true,
|
||||
_sound_def = {
|
||||
key = "node_sound_stone_defaults",
|
||||
},
|
||||
tube = {
|
||||
connect_sides = {front = 1, back = 1,},
|
||||
priority = 50,
|
||||
can_go = straight,
|
||||
can_insert = function(pos, node, stack, direction)
|
||||
local dir = minetest.facedir_to_dir(node.param2)
|
||||
return vector.equals(dir, direction) or vector.equals(vector.multiply(dir, -1), direction)
|
||||
end,
|
||||
},
|
||||
after_place_node = pipeworks.after_place,
|
||||
after_dig_node = pipeworks.after_dig,
|
||||
on_rotate = pipeworks.on_rotate,
|
||||
})
|
||||
pipeworks.ui_cat_tube_list[#pipeworks.ui_cat_tube_list+1] = "pipeworks:steel_pane_embedded_tube"
|
280
tubes/registration.lua
Normal file
280
tubes/registration.lua
Normal file
@ -0,0 +1,280 @@
|
||||
-- This file supplies the various kinds of pneumatic tubes
|
||||
local S = minetest.get_translator("pipeworks")
|
||||
|
||||
local tubenodes = {}
|
||||
pipeworks.tubenodes = tubenodes
|
||||
|
||||
minetest.register_alias("pipeworks:tube", "pipeworks:tube_000000")
|
||||
|
||||
-- now, a function to define the tubes
|
||||
|
||||
local REGISTER_COMPATIBILITY = true
|
||||
|
||||
local vti = {4, 3, 2, 1, 6, 5}
|
||||
|
||||
local default_noctrs = { "pipeworks_tube_noctr.png" }
|
||||
local default_plain = { "pipeworks_tube_plain.png" }
|
||||
local default_ends = { "pipeworks_tube_end.png" }
|
||||
|
||||
local texture_mt = {
|
||||
__index = function(table, key)
|
||||
local size, idx = #table, tonumber(key)
|
||||
if size > 0 then -- avoid endless loops with empty tables
|
||||
while idx > size do idx = idx - size end
|
||||
return table[idx]
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
-- This will remove any semi-transparent pixels
|
||||
-- because that is still buggy in Minetest, force this as default
|
||||
local texture_alpha_mode = minetest.features.use_texture_alpha_string_modes
|
||||
and "clip" or true
|
||||
|
||||
local register_one_tube = function(name, tname, dropname, desc, plain, noctrs, ends, short, inv, special, connects, style)
|
||||
noctrs = noctrs or default_noctrs
|
||||
setmetatable(noctrs, texture_mt)
|
||||
plain = plain or default_plain
|
||||
setmetatable(plain, texture_mt)
|
||||
ends = ends or default_ends
|
||||
setmetatable(ends, texture_mt)
|
||||
short = short or "pipeworks_tube_short.png"
|
||||
inv = inv or "pipeworks_tube_inv.png"
|
||||
|
||||
local outboxes = {}
|
||||
local outsel = {}
|
||||
local outimgs = {}
|
||||
|
||||
for i = 1, 6 do
|
||||
outimgs[vti[i]] = plain[i]
|
||||
end
|
||||
|
||||
for _, v in ipairs(connects) do
|
||||
pipeworks.table_extend(outboxes, pipeworks.tube_boxes[v])
|
||||
table.insert(outsel, pipeworks.tube_selectboxes[v])
|
||||
outimgs[vti[v]] = noctrs[v]
|
||||
end
|
||||
|
||||
if #connects == 1 then
|
||||
local v = connects[1]
|
||||
v = v-1 + 2*(v%2) -- Opposite side
|
||||
outimgs[vti[v]] = ends[v]
|
||||
end
|
||||
|
||||
local tgroups = {snappy = 3, tube = 1, tubedevice = 1, not_in_creative_inventory = 1, dig_generic = 4, axey=1, handy=1, pickaxey=1}
|
||||
local tubedesc = string.format("%s %s", desc, dump(connects))
|
||||
local iimg = type(plain[1]) == "table" and plain[1].name or plain[1]
|
||||
local wscale = {x = 1, y = 1, z = 1}
|
||||
|
||||
if #connects == 0 then
|
||||
tgroups = {snappy = 3, tube = 1, tubedevice = 1, dig_generic = 4, axey=1, handy=1, pickaxey=1}
|
||||
tubedesc = desc
|
||||
iimg=inv
|
||||
outimgs = {
|
||||
short, short,
|
||||
ends[3],ends[4],
|
||||
short, short
|
||||
}
|
||||
outboxes = { -24/64, -9/64, -9/64, 24/64, 9/64, 9/64 }
|
||||
outsel = { -24/64, -10/64, -10/64, 24/64, 10/64, 10/64 }
|
||||
wscale = {x = 1, y = 1, z = 0.01}
|
||||
end
|
||||
|
||||
for i, tile in ipairs(outimgs) do
|
||||
outimgs[i] = pipeworks.make_tube_tile(tile)
|
||||
end
|
||||
|
||||
local rname = string.format("%s_%s", name, tname)
|
||||
table.insert(tubenodes, rname)
|
||||
|
||||
local nodedef = {
|
||||
description = tubedesc,
|
||||
drawtype = "nodebox",
|
||||
tiles = outimgs,
|
||||
use_texture_alpha = texture_alpha_mode,
|
||||
sunlight_propagates = true,
|
||||
inventory_image = iimg,
|
||||
wield_image = iimg,
|
||||
wield_scale = wscale,
|
||||
paramtype = "light",
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = outsel
|
||||
},
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = outboxes
|
||||
},
|
||||
groups = tgroups,
|
||||
_mcl_hardness=0.8,
|
||||
_sound_def = {
|
||||
key = "node_sound_wood_defaults",
|
||||
},
|
||||
walkable = true,
|
||||
stack_max = 99,
|
||||
basename = name,
|
||||
style = style,
|
||||
drop = string.format("%s_%s", name, dropname),
|
||||
tubelike = 1,
|
||||
tube = {
|
||||
connect_sides = {front = 1, back = 1, left = 1, right = 1, top = 1, bottom = 1},
|
||||
priority = 50
|
||||
},
|
||||
on_punch = function(pos, node, player, pointed)
|
||||
local playername = player:get_player_name()
|
||||
if minetest.is_protected(pos, playername) and not minetest.check_player_privs(playername, {protection_bypass=true}) then
|
||||
return minetest.node_punch(pos, node, player, pointed)
|
||||
end
|
||||
if pipeworks.check_and_wear_hammer(player) then
|
||||
local wieldname = player:get_wielded_item():get_name()
|
||||
pipeworks.logger(string.format("%s struck a tube at %s with %s to break it.", playername, minetest.pos_to_string(pos), wieldname))
|
||||
pipeworks.break_tube(pos)
|
||||
end
|
||||
return minetest.node_punch(pos, node, player, pointed)
|
||||
end,
|
||||
after_place_node = pipeworks.after_place,
|
||||
after_dig_node = pipeworks.after_dig,
|
||||
on_rotate = false,
|
||||
on_blast = function(pos, intensity)
|
||||
if not intensity or intensity > 1 + 3^0.5 then
|
||||
minetest.remove_node(pos)
|
||||
return {string.format("%s_%s", name, dropname)}
|
||||
end
|
||||
minetest.swap_node(pos, {name = "pipeworks:broken_tube_1"})
|
||||
pipeworks.scan_for_tube_objects(pos)
|
||||
end,
|
||||
check_for_pole = pipeworks.check_for_vert_tube,
|
||||
check_for_horiz_pole = pipeworks.check_for_horiz_tube,
|
||||
tubenumber = tonumber(tname)
|
||||
}
|
||||
if style == "6d" then
|
||||
nodedef.paramtype2 = "facedir"
|
||||
end
|
||||
|
||||
if special == nil then special = {} end
|
||||
|
||||
for key, value in pairs(special) do
|
||||
--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
|
||||
elseif key == "tube" then
|
||||
for key, val in pairs(value) do
|
||||
nodedef.tube[key] = val
|
||||
end
|
||||
else
|
||||
nodedef[key] = pipeworks.table_recursive_replace(value, "#id", tname)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node(rname, nodedef)
|
||||
end
|
||||
|
||||
local register_all_tubes = function(name, desc, plain, noctrs, ends, short, inv, special, old_registration)
|
||||
if old_registration then
|
||||
for xm = 0, 1 do
|
||||
for xp = 0, 1 do
|
||||
for ym = 0, 1 do
|
||||
for yp = 0, 1 do
|
||||
for zm = 0, 1 do
|
||||
for zp = 0, 1 do
|
||||
local connects = {}
|
||||
if xm == 1 then
|
||||
connects[#connects+1] = 1
|
||||
end
|
||||
if xp == 1 then
|
||||
connects[#connects+1] = 2
|
||||
end
|
||||
if ym == 1 then
|
||||
connects[#connects+1] = 3
|
||||
end
|
||||
if yp == 1 then
|
||||
connects[#connects+1] = 4
|
||||
end
|
||||
if zm == 1 then
|
||||
connects[#connects+1] = 5
|
||||
end
|
||||
if zp == 1 then
|
||||
connects[#connects+1] = 6
|
||||
end
|
||||
local tname = xm..xp..ym..yp..zm..zp
|
||||
register_one_tube(name, tname, "000000", desc, plain, noctrs, ends, short, inv, special, connects, "old")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
pipeworks.ui_cat_tube_list[#pipeworks.ui_cat_tube_list+1] = name.."_000000"
|
||||
else
|
||||
-- 6d tubes: uses only 10 nodes instead of 64, but the textures must be rotated
|
||||
local cconnects = {{}, {1}, {1, 2}, {1, 3}, {1, 3, 5}, {1, 2, 3}, {1, 2, 3, 5}, {1, 2, 3, 4}, {1, 2, 3, 4, 5}, {1, 2, 3, 4, 5, 6}}
|
||||
for index, connects in ipairs(cconnects) do
|
||||
register_one_tube(name, tostring(index), "1", desc, plain, noctrs, ends, short, inv, special, connects, "6d")
|
||||
end
|
||||
if REGISTER_COMPATIBILITY then
|
||||
local cname = name.."_compatibility"
|
||||
minetest.register_node(cname, {
|
||||
drawtype = "airlike",
|
||||
style = "6d",
|
||||
basename = name,
|
||||
inventory_image = inv,
|
||||
wield_image = inv,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
description = S("Pneumatic tube segment (legacy)"),
|
||||
after_place_node = pipeworks.after_place,
|
||||
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",
|
||||
})
|
||||
pipeworks.ui_cat_tube_list[#pipeworks.ui_cat_tube_list+1] = name.."_1"
|
||||
table.insert(tubenodes, cname)
|
||||
for xm = 0, 1 do
|
||||
for xp = 0, 1 do
|
||||
for ym = 0, 1 do
|
||||
for yp = 0, 1 do
|
||||
for zm = 0, 1 do
|
||||
for zp = 0, 1 do
|
||||
local tname = xm..xp..ym..yp..zm..zp
|
||||
minetest.register_alias(name.."_"..tname, cname)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
pipeworks.register_tube = function(name, def, ...)
|
||||
if type(def) == "table" then
|
||||
register_all_tubes(name, def.description,
|
||||
def.plain, def.noctr, def.ends, def.short,
|
||||
def.inventory_image, def.node_def, def.no_facedir)
|
||||
else
|
||||
-- we assert to be the old function with the second parameter being the description
|
||||
-- function(name, desc, plain, noctrs, ends, short, inv, special, old_registration)
|
||||
assert(type(def) == "string", "invalid arguments to pipeworks.register_tube")
|
||||
register_all_tubes(name, def, ...)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if REGISTER_COMPATIBILITY then
|
||||
minetest.register_abm({
|
||||
nodenames = {"group:tube_to_update"},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
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
|
||||
end
|
||||
})
|
||||
end
|
203
tubes/routing.lua
Normal file
203
tubes/routing.lua
Normal file
@ -0,0 +1,203 @@
|
||||
local S = minetest.get_translator("pipeworks")
|
||||
-- the default tube and default textures
|
||||
pipeworks.register_tube("pipeworks:tube", S("Pneumatic tube segment"))
|
||||
minetest.register_craft( {
|
||||
output = "pipeworks:tube_1 6",
|
||||
recipe = {
|
||||
{ "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" },
|
||||
{ "", "", "" },
|
||||
{ "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" }
|
||||
},
|
||||
})
|
||||
|
||||
-- The hammers that can be used to break/repair tubes
|
||||
local allowed_hammers = {
|
||||
"anvil:hammer",
|
||||
"cottages:hammer",
|
||||
"glooptest:hammer_steel",
|
||||
"glooptest:hammer_bronze",
|
||||
"glooptest:hammer_diamond",
|
||||
"glooptest:hammer_mese",
|
||||
"glooptest:hammer_alatro",
|
||||
"glooptest:hammer_arol"
|
||||
}
|
||||
|
||||
-- Convert the above list to a format that's easier to look up
|
||||
for _,hammer in ipairs(allowed_hammers) do
|
||||
allowed_hammers[hammer] = true
|
||||
end
|
||||
|
||||
-- Check if the player is holding a suitable hammer or not - if they are, apply wear to it
|
||||
function pipeworks.check_and_wear_hammer(player)
|
||||
local itemstack = player:get_wielded_item()
|
||||
local wieldname = itemstack:get_name()
|
||||
if allowed_hammers[wieldname] then
|
||||
itemstack:add_wear(1000)
|
||||
player:set_wielded_item(itemstack)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local nodecolor = 0xffff3030
|
||||
|
||||
pipeworks.register_tube("pipeworks:broken_tube", {
|
||||
description = S("Broken Tube"),
|
||||
plain = { { name = "pipeworks_broken_tube_plain.png", backface_culling = false, color = nodecolor } },
|
||||
noctr = { { name = "pipeworks_broken_tube_plain.png", backface_culling = false, color = nodecolor } },
|
||||
ends = { { name = "pipeworks_broken_tube_end.png", color = nodecolor } },
|
||||
short = { name = "pipeworks_broken_tube_short.png", color = nodecolor },
|
||||
node_def = {
|
||||
drop = "pipeworks:tube_1",
|
||||
groups = {not_in_creative_inventory = 1, tubedevice_receiver = 1},
|
||||
tube = {
|
||||
insert_object = function(pos, node, stack, direction)
|
||||
minetest.item_drop(stack, nil, pos)
|
||||
return ItemStack("")
|
||||
end,
|
||||
can_insert = function(pos,node,stack,direction)
|
||||
return true
|
||||
end,
|
||||
priority = 50,
|
||||
},
|
||||
on_punch = function(pos, node, puncher, pointed_thing)
|
||||
local itemstack = puncher:get_wielded_item()
|
||||
local wieldname = itemstack:get_name()
|
||||
local playername = puncher:get_player_name()
|
||||
local log_msg = playername.." struck a broken tube at "..minetest.pos_to_string(pos).."\n "
|
||||
local meta = minetest.get_meta(pos)
|
||||
local was_node = minetest.deserialize(meta:get_string("the_tube_was"))
|
||||
if not was_node then
|
||||
pipeworks.logger(log_msg.."but it can't be repaired.")
|
||||
return
|
||||
end
|
||||
if not pipeworks.check_and_wear_hammer(puncher) then
|
||||
if wieldname == "" then
|
||||
pipeworks.logger(log_msg.."by hand. It's not very effective.")
|
||||
if minetest.settings:get_bool("enable_damage") then
|
||||
minetest.chat_send_player(playername,S("Broken tubes may be a bit sharp. Perhaps try with a hammer?"))
|
||||
puncher:set_hp(puncher:get_hp()-1)
|
||||
end
|
||||
else
|
||||
pipeworks.logger(log_msg.."with "..wieldname.." but that tool is too weak.")
|
||||
end
|
||||
return
|
||||
end
|
||||
log_msg = log_msg.."with "..wieldname.." to repair it"
|
||||
local nodedef = minetest.registered_nodes[was_node.name]
|
||||
if nodedef then
|
||||
pipeworks.logger(log_msg..".")
|
||||
if nodedef.tube and nodedef.tube.on_repair then
|
||||
nodedef.tube.on_repair(pos, was_node)
|
||||
else
|
||||
minetest.swap_node(pos, { name = was_node.name, param2 = was_node.param2 })
|
||||
pipeworks.scan_for_tube_objects(pos)
|
||||
end
|
||||
else
|
||||
pipeworks.logger(log_msg.." but original node "..was_node.name.." is not registered anymore.")
|
||||
minetest.chat_send_player(playername, S("This tube cannot be repaired."))
|
||||
end
|
||||
end,
|
||||
allow_metadata_inventory_put = function()
|
||||
return 0
|
||||
end,
|
||||
allow_metadata_inventory_move = function()
|
||||
return 0
|
||||
end,
|
||||
allow_metadata_inventory_take = function()
|
||||
return 0
|
||||
end,
|
||||
}
|
||||
})
|
||||
|
||||
-- the high priority tube is a low-cpu replacement for sorting tubes in situations
|
||||
-- where players would use them for simple routing (turning off paths)
|
||||
-- without doing actual sorting, like at outputs of tubedevices that might both accept and eject items
|
||||
if pipeworks.enable_priority_tube then
|
||||
local color = "#ff3030:128"
|
||||
pipeworks.register_tube("pipeworks:priority_tube", {
|
||||
description = S("High Priority Tube Segment"),
|
||||
inventory_image = "pipeworks_tube_inv.png^[colorize:" .. color,
|
||||
plain = { { name = "pipeworks_tube_plain.png", color = nodecolor } },
|
||||
noctr = { { name = "pipeworks_tube_noctr.png", color = nodecolor } },
|
||||
ends = { { name = "pipeworks_tube_end.png", color = nodecolor } },
|
||||
short = { name = "pipeworks_tube_short.png", color = nodecolor },
|
||||
node_def = {
|
||||
tube = { priority = 150 } -- higher than tubedevices (100)
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
if pipeworks.enable_accelerator_tube then
|
||||
pipeworks.register_tube("pipeworks:accelerator_tube", {
|
||||
description = S("Accelerating Pneumatic Tube Segment"),
|
||||
inventory_image = "pipeworks_accelerator_tube_inv.png",
|
||||
plain = { "pipeworks_accelerator_tube_plain.png" },
|
||||
noctr = { "pipeworks_accelerator_tube_noctr.png" },
|
||||
ends = { "pipeworks_accelerator_tube_end.png" },
|
||||
short = "pipeworks_accelerator_tube_short.png",
|
||||
node_def = {
|
||||
tube = {can_go = function(pos, node, velocity, stack)
|
||||
velocity.speed = velocity.speed+1
|
||||
return pipeworks.notvel(pipeworks.meseadjlist, velocity)
|
||||
end}
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
if pipeworks.enable_crossing_tube then
|
||||
pipeworks.register_tube("pipeworks:crossing_tube", {
|
||||
description = S("Crossing Pneumatic Tube Segment"),
|
||||
inventory_image = "pipeworks_crossing_tube_inv.png",
|
||||
plain = { "pipeworks_crossing_tube_plain.png" },
|
||||
noctr = { "pipeworks_crossing_tube_noctr.png" },
|
||||
ends = { "pipeworks_crossing_tube_end.png" },
|
||||
short = "pipeworks_crossing_tube_short.png",
|
||||
node_def = {
|
||||
tube = {can_go = function(pos, node, velocity, stack) return {velocity} end }
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
local texture_alpha_mode = minetest.features.use_texture_alpha_string_modes
|
||||
and "clip" or true
|
||||
|
||||
if pipeworks.enable_one_way_tube then
|
||||
local 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"}
|
||||
for i, tile in ipairs(tiles) do
|
||||
tiles[i] = pipeworks.make_tube_tile(tile)
|
||||
end
|
||||
minetest.register_node("pipeworks:one_way_tube", {
|
||||
description = S("One way tube"),
|
||||
tiles = tiles,
|
||||
use_texture_alpha = texture_alpha_mode,
|
||||
paramtype2 = "facedir",
|
||||
drawtype = "nodebox",
|
||||
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, axey=1, handy=1, pickaxey=1},
|
||||
_mcl_hardness=0.8,
|
||||
_sound_def = {
|
||||
key = "node_sound_wood_defaults",
|
||||
},
|
||||
tube = {
|
||||
connect_sides = {left = 1, right = 1},
|
||||
can_go = function(pos, node, velocity, stack)
|
||||
return {velocity}
|
||||
end,
|
||||
can_insert = function(pos, node, stack, direction)
|
||||
local dir = pipeworks.facedir_to_right_dir(node.param2)
|
||||
return vector.equals(dir, direction)
|
||||
end,
|
||||
priority = 75 -- Higher than normal tubes, but lower than receivers
|
||||
},
|
||||
after_place_node = pipeworks.after_place,
|
||||
after_dig_node = pipeworks.after_dig,
|
||||
on_rotate = pipeworks.on_rotate,
|
||||
check_for_pole = pipeworks.check_for_vert_tube,
|
||||
check_for_horiz_pole = pipeworks.check_for_horiz_tube
|
||||
})
|
||||
pipeworks.ui_cat_tube_list[#pipeworks.ui_cat_tube_list+1] = "pipeworks:one_way_tube"
|
||||
end
|
247
tubes/signal.lua
Normal file
247
tubes/signal.lua
Normal file
@ -0,0 +1,247 @@
|
||||
local S = minetest.get_translator("pipeworks")
|
||||
|
||||
-- the minetest.after() calls below can sometimes trigger after a tube
|
||||
-- breaks, at which point item_exit() is no longer valid, so we have to make
|
||||
-- sure that there even IS a callback to run, first.
|
||||
|
||||
local function after_break(pos)
|
||||
local name = minetest.get_node(pos).name
|
||||
if minetest.registered_nodes[name].item_exit then
|
||||
minetest.registered_nodes[name].item_exit(pos)
|
||||
end
|
||||
end
|
||||
|
||||
if minetest.get_modpath("mesecons") and pipeworks.enable_detector_tube then
|
||||
local detector_tube_step = 5 * (tonumber(minetest.settings:get("dedicated_server_step")) or 0.09)
|
||||
pipeworks.register_tube("pipeworks:detector_tube_on", {
|
||||
description = S("Detecting Pneumatic Tube Segment on"),
|
||||
inventory_image = "pipeworks_detector_tube_inv.png",
|
||||
plain = { "pipeworks_detector_tube_plain.png" },
|
||||
node_def = {
|
||||
tube = {can_go = function(pos, node, velocity, stack)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local nitems = meta:get_int("nitems")+1
|
||||
meta:set_int("nitems", nitems)
|
||||
local saved_pos = vector.new(pos)
|
||||
minetest.after(detector_tube_step, after_break, saved_pos)
|
||||
return pipeworks.notvel(pipeworks.meseadjlist,velocity)
|
||||
end},
|
||||
groups = {mesecon = 2, not_in_creative_inventory = 1},
|
||||
drop = "pipeworks:detector_tube_off_1",
|
||||
mesecons = {receptor = {state = "on", rules = pipeworks.mesecons_rules}},
|
||||
item_exit = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local nitems = meta:get_int("nitems")-1
|
||||
local node = minetest.get_node(pos)
|
||||
local name = node.name
|
||||
local fdir = node.param2
|
||||
if nitems == 0 then
|
||||
minetest.set_node(pos, {name = string.gsub(name, "on", "off"), param2 = fdir})
|
||||
mesecon.receptor_off(pos, pipeworks.mesecons_rules)
|
||||
else
|
||||
meta:set_int("nitems", nitems)
|
||||
end
|
||||
end,
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("nitems", 1)
|
||||
minetest.after(detector_tube_step, after_break, pos)
|
||||
end,
|
||||
},
|
||||
})
|
||||
pipeworks.register_tube("pipeworks:detector_tube_off", {
|
||||
description = S("Detecting Pneumatic Tube Segment"),
|
||||
inventory_image = "pipeworks_detector_tube_inv.png",
|
||||
plain = { "pipeworks_detector_tube_plain.png" },
|
||||
node_def = {
|
||||
tube = {can_go = function(pos, node, velocity, stack)
|
||||
local node = minetest.get_node(pos)
|
||||
local name = node.name
|
||||
local fdir = node.param2
|
||||
minetest.set_node(pos,{name = string.gsub(name, "off", "on"), param2 = fdir})
|
||||
mesecon.receptor_on(pos, pipeworks.mesecons_rules)
|
||||
return pipeworks.notvel(pipeworks.meseadjlist, velocity)
|
||||
end},
|
||||
groups = {mesecon = 2},
|
||||
mesecons = {receptor = {state = "off", rules = pipeworks.mesecons_rules }},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft( {
|
||||
output = "pipeworks:detector_tube_off_1 2",
|
||||
recipe = {
|
||||
{ "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" },
|
||||
{ "mesecons:mesecon", "mesecons_materials:silicon", "mesecons:mesecon" },
|
||||
{ "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" }
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
local digiline_enabled = minetest.get_modpath("digilines") ~= nil
|
||||
if digiline_enabled and pipeworks.enable_digiline_detector_tube then
|
||||
pipeworks.register_tube("pipeworks:digiline_detector_tube", {
|
||||
description = S("Digiline Detecting Pneumatic Tube Segment"),
|
||||
inventory_image = "pipeworks_digiline_detector_tube_inv.png",
|
||||
plain = { "pipeworks_digiline_detector_tube_plain.png" },
|
||||
node_def = {
|
||||
tube = {can_go = function(pos, node, velocity, stack)
|
||||
local meta = minetest.get_meta(pos)
|
||||
|
||||
local setchan = meta:get_string("channel")
|
||||
|
||||
digiline:receptor_send(pos, digiline.rules.default, setchan, stack:to_table())
|
||||
|
||||
return pipeworks.notvel(pipeworks.meseadjlist, velocity)
|
||||
end},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("formspec",
|
||||
"size[8.5,2.2]"..
|
||||
"image[0.2,0;1,1;pipeworks_digiline_detector_tube_inv.png]"..
|
||||
"label[1.2,0.2;"..S("Digiline Detecting Tube").."]"..
|
||||
"field[0.5,1.6;4.6,1;channel;"..S("Channel")..";${channel}]"..
|
||||
"button[4.8,1.3;1.5,1;set_channel;"..S("Set").."]"..
|
||||
"button_exit[6.3,1.3;2,1;close;"..S("Close").."]"
|
||||
)
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
if (fields.quit and not fields.key_enter_field)
|
||||
or (fields.key_enter_field ~= "channel" and not fields.set_channel)
|
||||
or not pipeworks.may_configure(pos, sender) then
|
||||
return
|
||||
end
|
||||
if fields.channel then
|
||||
minetest.get_meta(pos):set_string("channel", fields.channel)
|
||||
end
|
||||
end,
|
||||
groups = {},
|
||||
digiline = {
|
||||
receptor = {},
|
||||
effector = {
|
||||
action = function(pos,node,channel,msg) end
|
||||
},
|
||||
wire = {
|
||||
rules = pipeworks.digilines_rules
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft( {
|
||||
output = "pipeworks:digiline_detector_tube_1 2",
|
||||
recipe = {
|
||||
{ "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" },
|
||||
{ "digilines:wire_std_00000000", "mesecons_materials:silicon", "digilines:wire_std_00000000" },
|
||||
{ "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" }
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
if minetest.get_modpath("mesecons") and pipeworks.enable_conductor_tube then
|
||||
pipeworks.register_tube("pipeworks:conductor_tube_off", {
|
||||
description = S("Conducting Pneumatic Tube Segment"),
|
||||
inventory_image = "pipeworks_conductor_tube_inv.png",
|
||||
short = "pipeworks_conductor_tube_short.png",
|
||||
plain = { "pipeworks_conductor_tube_plain.png" },
|
||||
noctr = { "pipeworks_conductor_tube_noctr.png" },
|
||||
ends = { "pipeworks_conductor_tube_end.png" },
|
||||
node_def = {
|
||||
groups = {mesecon = 2},
|
||||
mesecons = {conductor = {state = "off",
|
||||
rules = pipeworks.mesecons_rules,
|
||||
onstate = "pipeworks:conductor_tube_on_#id"}}
|
||||
},
|
||||
})
|
||||
pipeworks.register_tube("pipeworks:conductor_tube_on", {
|
||||
description = S("Conducting Pneumatic Tube Segment on"),
|
||||
inventory_image = "pipeworks_conductor_tube_inv.png",
|
||||
short = "pipeworks_conductor_tube_short.png",
|
||||
plain = { "pipeworks_conductor_tube_on_plain.png" },
|
||||
noctr = { "pipeworks_conductor_tube_on_noctr.png" },
|
||||
ends = { "pipeworks_conductor_tube_on_end.png" },
|
||||
node_def = {
|
||||
groups = {mesecon = 2, not_in_creative_inventory = 1},
|
||||
drop = "pipeworks:conductor_tube_off_1",
|
||||
mesecons = {conductor = {state = "on",
|
||||
rules = pipeworks.mesecons_rules,
|
||||
offstate = "pipeworks:conductor_tube_off_#id"}}
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "pipeworks:conductor_tube_off_1",
|
||||
recipe = {"pipeworks:tube_1", "mesecons:mesecon"}
|
||||
})
|
||||
end
|
||||
|
||||
if digiline_enabled and pipeworks.enable_digiline_conductor_tube then
|
||||
pipeworks.register_tube("pipeworks:digiline_conductor_tube", {
|
||||
description = S("Digiline Conducting Pneumatic Tube Segment"),
|
||||
inventory_image = "pipeworks_tube_inv.png^pipeworks_digiline_conductor_tube_inv.png",
|
||||
short = "pipeworks_tube_short.png^pipeworks_digiline_conductor_tube_short.png",
|
||||
plain = {"pipeworks_tube_plain.png^pipeworks_digiline_conductor_tube_plain.png"},
|
||||
noctr = {"pipeworks_tube_noctr.png^pipeworks_digiline_conductor_tube_noctr.png"},
|
||||
ends = {"pipeworks_tube_end.png^pipeworks_digiline_conductor_tube_end.png"},
|
||||
node_def = {digiline = {wire = {rules = pipeworks.digilines_rules}}},
|
||||
})
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "pipeworks:digiline_conductor_tube_1",
|
||||
recipe = {"pipeworks:tube_1", "digilines:wire_std_00000000"}
|
||||
})
|
||||
end
|
||||
|
||||
if digiline_enabled and pipeworks.enable_digiline_conductor_tube and
|
||||
pipeworks.enable_conductor_tube then
|
||||
pipeworks.register_tube("pipeworks:mesecon_and_digiline_conductor_tube_off", {
|
||||
description = S("Mesecon and Digiline Conducting Pneumatic Tube Segment"),
|
||||
inventory_image = "pipeworks_conductor_tube_inv.png^pipeworks_digiline_conductor_tube_inv.png",
|
||||
short = "pipeworks_conductor_tube_short.png^pipeworks_digiline_conductor_tube_short.png",
|
||||
plain = {"pipeworks_conductor_tube_plain.png^pipeworks_digiline_conductor_tube_plain.png"},
|
||||
noctr = {"pipeworks_conductor_tube_noctr.png^pipeworks_digiline_conductor_tube_noctr.png"},
|
||||
ends = {"pipeworks_conductor_tube_end.png^pipeworks_digiline_conductor_tube_end.png"},
|
||||
node_def = {
|
||||
digiline = {wire = {rules = pipeworks.digilines_rules}},
|
||||
groups = {mesecon = 2},
|
||||
mesecons = {conductor = {
|
||||
state = "off",
|
||||
rules = pipeworks.mesecons_rules,
|
||||
onstate = "pipeworks:mesecon_and_digiline_conductor_tube_on_#id"
|
||||
}},
|
||||
},
|
||||
})
|
||||
pipeworks.register_tube("pipeworks:mesecon_and_digiline_conductor_tube_on", {
|
||||
description = S("Mesecon and Digiline Conducting Pneumatic Tube Segment on"),
|
||||
inventory_image = "pipeworks_conductor_tube_inv.png^pipeworks_digiline_conductor_tube_inv.png",
|
||||
short = "pipeworks_conductor_tube_short.png^pipeworks_digiline_conductor_tube_short.png",
|
||||
plain = {"pipeworks_conductor_tube_on_plain.png^pipeworks_digiline_conductor_tube_plain.png"},
|
||||
noctr = {"pipeworks_conductor_tube_on_noctr.png^pipeworks_digiline_conductor_tube_noctr.png"},
|
||||
ends = {"pipeworks_conductor_tube_on_end.png^pipeworks_digiline_conductor_tube_end.png"},
|
||||
node_def = {
|
||||
digiline = {wire = {rules = pipeworks.digilines_rules}},
|
||||
groups = {mesecon = 2, not_in_creative_inventory = 1},
|
||||
drop = "pipeworks:mesecon_and_digiline_conductor_tube_off_1",
|
||||
mesecons = {conductor = {
|
||||
state = "on",
|
||||
rules = pipeworks.mesecons_rules,
|
||||
offstate = "pipeworks:mesecon_and_digiline_conductor_tube_off_#id"}
|
||||
},
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "pipeworks:mesecon_and_digiline_conductor_tube_off_1",
|
||||
recipe = {"pipeworks:tube_1", "mesecons:mesecon", "digilines:wire_std_00000000"}
|
||||
})
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "pipeworks:mesecon_and_digiline_conductor_tube_off_1",
|
||||
recipe = {"pipeworks:conductor_tube_off_1", "digilines:wire_std_00000000"}
|
||||
})
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "pipeworks:mesecon_and_digiline_conductor_tube_off_1",
|
||||
recipe = {"pipeworks:digiline_conductor_tube_1", "mesecons:mesecon"}
|
||||
})
|
||||
end
|
180
tubes/sorting.lua
Normal file
180
tubes/sorting.lua
Normal file
@ -0,0 +1,180 @@
|
||||
local S = minetest.get_translator("pipeworks")
|
||||
local fs_helpers = pipeworks.fs_helpers
|
||||
|
||||
if pipeworks.enable_mese_tube then
|
||||
local function update_formspec(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local old_formspec = meta:get_string("formspec")
|
||||
if string.find(old_formspec, "button1") then -- Old version
|
||||
local inv = meta:get_inventory()
|
||||
for i = 1, 6 do
|
||||
for _, stack in ipairs(inv:get_list("line"..i)) do
|
||||
minetest.add_item(pos, stack)
|
||||
end
|
||||
end
|
||||
end
|
||||
local buttons_formspec = ""
|
||||
for i = 0, 5 do
|
||||
buttons_formspec = buttons_formspec .. fs_helpers.cycling_button(meta,
|
||||
"image_button[9,"..(i+(i*0.25)+0.5)..";1,0.6", "l"..(i+1).."s",
|
||||
{
|
||||
pipeworks.button_off,
|
||||
pipeworks.button_on
|
||||
}
|
||||
)
|
||||
end
|
||||
local list_backgrounds = ""
|
||||
if minetest.get_modpath("i3") or minetest.get_modpath("mcl_formspec") then
|
||||
list_backgrounds = "style_type[box;colors=#666]"
|
||||
for i=0, 5 do
|
||||
for j=0, 5 do
|
||||
list_backgrounds = list_backgrounds .. "box[".. 1.5+(i*1.25) ..",".. 0.25+(j*1.25) ..";1,1;]"
|
||||
end
|
||||
end
|
||||
end
|
||||
local size = "10.2,13"
|
||||
meta:set_string("formspec",
|
||||
"formspec_version[2]"..
|
||||
"size["..size.."]"..
|
||||
pipeworks.fs_helpers.get_prepends(size)..
|
||||
"list[context;line1;1.5,0.25;6,1;]"..
|
||||
"list[context;line2;1.5,1.50;6,1;]"..
|
||||
"list[context;line3;1.5,2.75;6,1;]"..
|
||||
"list[context;line4;1.5,4.00;6,1;]"..
|
||||
"list[context;line5;1.5,5.25;6,1;]"..
|
||||
"list[context;line6;1.5,6.50;6,1;]"..
|
||||
list_backgrounds..
|
||||
"image[0.22,0.25;1,1;pipeworks_white.png]"..
|
||||
"image[0.22,1.50;1,1;pipeworks_black.png]"..
|
||||
"image[0.22,2.75;1,1;pipeworks_green.png]"..
|
||||
"image[0.22,4.00;1,1;pipeworks_yellow.png]"..
|
||||
"image[0.22,5.25;1,1;pipeworks_blue.png]"..
|
||||
"image[0.22,6.50;1,1;pipeworks_red.png]"..
|
||||
buttons_formspec..
|
||||
--"list[current_player;main;0,8;8,4;]" ..
|
||||
pipeworks.fs_helpers.get_inv(8)..
|
||||
"listring[current_player;main]" ..
|
||||
"listring[current_player;main]" ..
|
||||
"listring[context;line1]" ..
|
||||
"listring[current_player;main]" ..
|
||||
"listring[context;line2]" ..
|
||||
"listring[current_player;main]" ..
|
||||
"listring[context;line3]" ..
|
||||
"listring[current_player;main]" ..
|
||||
"listring[context;line4]" ..
|
||||
"listring[current_player;main]" ..
|
||||
"listring[context;line5]" ..
|
||||
"listring[current_player;main]" ..
|
||||
"listring[context;line6]"
|
||||
)
|
||||
end
|
||||
|
||||
pipeworks.register_tube("pipeworks:mese_tube", {
|
||||
description = S("Sorting Pneumatic Tube Segment"),
|
||||
inventory_image = "pipeworks_mese_tube_inv.png",
|
||||
noctr = {"pipeworks_mese_tube_noctr_1.png", "pipeworks_mese_tube_noctr_2.png", "pipeworks_mese_tube_noctr_3.png",
|
||||
"pipeworks_mese_tube_noctr_4.png", "pipeworks_mese_tube_noctr_5.png", "pipeworks_mese_tube_noctr_6.png"},
|
||||
plain = {"pipeworks_mese_tube_plain_1.png", "pipeworks_mese_tube_plain_2.png", "pipeworks_mese_tube_plain_3.png",
|
||||
"pipeworks_mese_tube_plain_4.png", "pipeworks_mese_tube_plain_5.png", "pipeworks_mese_tube_plain_6.png"},
|
||||
ends = { "pipeworks_mese_tube_end.png" },
|
||||
short = "pipeworks_mese_tube_short.png",
|
||||
no_facedir = true, -- Must use old tubes, since the textures are rotated with 6d ones
|
||||
node_def = {
|
||||
tube = {can_go = function(pos, node, velocity, stack)
|
||||
local tbl, tbln = {}, 0
|
||||
local found, foundn = {}, 0
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local name = stack:get_name()
|
||||
for i, vect in ipairs(pipeworks.meseadjlist) do
|
||||
local npos = vector.add(pos, vect)
|
||||
local node = minetest.get_node(npos)
|
||||
local reg_node = minetest.registered_nodes[node.name]
|
||||
if meta:get_int("l"..i.."s") == 1 and reg_node then
|
||||
local tube_def = reg_node.tube
|
||||
if not tube_def or not tube_def.can_insert or
|
||||
tube_def.can_insert(npos, node, stack, vect) then
|
||||
local invname = "line"..i
|
||||
local is_empty = true
|
||||
for _, st in ipairs(inv:get_list(invname)) do
|
||||
if not st:is_empty() then
|
||||
is_empty = false
|
||||
if st:get_name() == name then
|
||||
foundn = foundn + 1
|
||||
found[foundn] = vect
|
||||
end
|
||||
end
|
||||
end
|
||||
if is_empty then
|
||||
tbln = tbln + 1
|
||||
tbl[tbln] = vect
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return (foundn > 0) and found or tbl
|
||||
end},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
for i = 1, 6 do
|
||||
meta:set_int("l"..tostring(i).."s", 1)
|
||||
inv:set_size("line"..tostring(i), 6*1)
|
||||
end
|
||||
update_formspec(pos)
|
||||
meta:set_string("infotext", S("Sorting pneumatic tube"))
|
||||
end,
|
||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
if placer and placer:is_player() and placer:get_player_control().aux1 then
|
||||
local meta = minetest.get_meta(pos)
|
||||
for i = 1, 6 do
|
||||
meta:set_int("l"..tostring(i).."s", 0)
|
||||
end
|
||||
update_formspec(pos)
|
||||
end
|
||||
return pipeworks.after_place(pos, placer, itemstack, pointed_thing)
|
||||
end,
|
||||
on_punch = update_formspec,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
if (fields.quit and not fields.key_enter_field)
|
||||
or not pipeworks.may_configure(pos, sender) then
|
||||
return
|
||||
end
|
||||
fs_helpers.on_receive_fields(pos, fields)
|
||||
update_formspec(pos)
|
||||
end,
|
||||
can_dig = function(pos, player)
|
||||
update_formspec(pos) -- so non-virtual items would be dropped for old tubes
|
||||
return true
|
||||
end,
|
||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
if not pipeworks.may_configure(pos, player) then return 0 end
|
||||
update_formspec(pos) -- For old tubes
|
||||
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)
|
||||
if not pipeworks.may_configure(pos, player) then return 0 end
|
||||
update_formspec(pos) -- For old tubes
|
||||
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)
|
||||
if not pipeworks.may_configure(pos, player) then return 0 end
|
||||
update_formspec(pos) -- For old tubes
|
||||
local inv = minetest.get_meta(pos):get_inventory()
|
||||
|
||||
if from_list:match("line%d") and to_list:match("line%d") then
|
||||
return count
|
||||
else
|
||||
inv:set_stack(from_list, from_index, ItemStack(""))
|
||||
return 0
|
||||
end
|
||||
end,
|
||||
},
|
||||
})
|
||||
end
|
373
tubes/teleport.lua
Normal file
373
tubes/teleport.lua
Normal file
@ -0,0 +1,373 @@
|
||||
|
||||
local S = minetest.get_translator("pipeworks")
|
||||
local filename = minetest.get_worldpath().."/teleport_tubes" -- Only used for backward-compat
|
||||
local storage = minetest.get_mod_storage()
|
||||
|
||||
local enable_logging = minetest.settings:get_bool("pipeworks_log_teleport_tubes", false)
|
||||
|
||||
local has_digilines = minetest.get_modpath("digilines")
|
||||
|
||||
-- V1: Serialized text file indexed by vector position.
|
||||
-- V2: Serialized text file indexed by hash position.
|
||||
-- V3: Mod storage using serialized tables.
|
||||
-- V4: Mod storage using "<can_receive>:<channel>" format.
|
||||
local tube_db_version = 4
|
||||
local tube_db = {}
|
||||
local receiver_cache = {}
|
||||
|
||||
local function hash_pos(pos)
|
||||
vector.round(pos)
|
||||
return string.format("%.0f", minetest.hash_node_position(pos))
|
||||
end
|
||||
|
||||
local function serialize_tube(tube)
|
||||
return string.format("%d:%s", tube.cr, tube.channel)
|
||||
end
|
||||
|
||||
local function deserialize_tube(hash, str)
|
||||
local sep = str:sub(2, 2) == ":"
|
||||
local cr = tonumber(str:sub(1, 1))
|
||||
local channel = str:sub(3)
|
||||
if sep and cr and channel then
|
||||
local pos = minetest.get_position_from_hash(tonumber(hash))
|
||||
return {x = pos.x, y = pos.y, z = pos.z, cr = cr, channel = channel}
|
||||
end
|
||||
end
|
||||
|
||||
local function save_tube_db()
|
||||
receiver_cache = {}
|
||||
local fields = {version = tube_db_version}
|
||||
for key, val in pairs(tube_db) do
|
||||
fields[key] = serialize_tube(val)
|
||||
end
|
||||
storage:from_table({fields = fields})
|
||||
end
|
||||
|
||||
local function save_tube(hash)
|
||||
local tube = tube_db[hash]
|
||||
receiver_cache[tube.channel] = nil
|
||||
storage:set_string(hash, serialize_tube(tube))
|
||||
end
|
||||
|
||||
local function remove_tube(pos)
|
||||
local hash = hash_pos(pos)
|
||||
if tube_db[hash] then
|
||||
receiver_cache[tube_db[hash].channel] = nil
|
||||
tube_db[hash] = nil
|
||||
storage:set_string(hash, "")
|
||||
end
|
||||
end
|
||||
|
||||
local function migrate_tube_db()
|
||||
if storage:get_int("version") == 3 then
|
||||
for key, val in pairs(storage:to_table().fields) do
|
||||
if tonumber(key) then
|
||||
tube_db[key] = minetest.deserialize(val)
|
||||
elseif key ~= "version" then
|
||||
error("Unknown field in teleport tube database: "..key)
|
||||
end
|
||||
end
|
||||
save_tube_db()
|
||||
return
|
||||
end
|
||||
local file = io.open(filename, "r")
|
||||
if file then
|
||||
local content = file:read("*all")
|
||||
io.close(file)
|
||||
if content and content ~= "" then
|
||||
tube_db = minetest.deserialize(content)
|
||||
end
|
||||
end
|
||||
local version = tube_db.version or 0
|
||||
tube_db.version = nil
|
||||
if version < 2 then
|
||||
local tmp_db = {}
|
||||
for _, val in pairs(tube_db) do
|
||||
if val.channel ~= "" then -- Skip unconfigured tubes
|
||||
tmp_db[hash_pos(val)] = val
|
||||
end
|
||||
end
|
||||
tube_db = tmp_db
|
||||
end
|
||||
save_tube_db()
|
||||
end
|
||||
|
||||
local function read_tube_db()
|
||||
local version = storage:get_int("version")
|
||||
if version < tube_db_version then
|
||||
migrate_tube_db()
|
||||
elseif version > tube_db_version then
|
||||
error("Cannot read teleport tube database of version "..version)
|
||||
else
|
||||
for key, val in pairs(storage:to_table().fields) do
|
||||
if tonumber(key) then
|
||||
tube_db[key] = deserialize_tube(key, val)
|
||||
elseif key ~= "version" then
|
||||
error("Unknown field in teleport tube database: "..key)
|
||||
end
|
||||
end
|
||||
end
|
||||
tube_db.version = nil
|
||||
end
|
||||
|
||||
local function set_tube(pos, channel, cr)
|
||||
local hash = hash_pos(pos)
|
||||
local tube = tube_db[hash]
|
||||
if tube then
|
||||
if tube.channel ~= channel or tube.cr ~= cr then
|
||||
tube.channel = channel
|
||||
tube.cr = cr
|
||||
save_tube(hash)
|
||||
end
|
||||
else
|
||||
tube_db[hash] = {x = pos.x, y = pos.y, z = pos.z, channel = channel, cr = cr}
|
||||
save_tube(hash)
|
||||
end
|
||||
end
|
||||
|
||||
local function get_receivers(pos, channel)
|
||||
local hash = hash_pos(pos)
|
||||
local cache = receiver_cache[channel] or {}
|
||||
if cache[hash] then
|
||||
return cache[hash]
|
||||
end
|
||||
local receivers = {}
|
||||
for key, val in pairs(tube_db) do
|
||||
if val.cr == 1 and val.channel == channel and not vector.equals(val, pos) then
|
||||
minetest.load_area(val)
|
||||
local node_name = minetest.get_node(val).name
|
||||
if node_name:find("pipeworks:teleport_tube") then
|
||||
table.insert(receivers, val)
|
||||
else
|
||||
remove_tube(val)
|
||||
end
|
||||
end
|
||||
end
|
||||
cache[hash] = receivers
|
||||
receiver_cache[channel] = cache
|
||||
return receivers
|
||||
end
|
||||
|
||||
local help_text = minetest.formspec_escape(
|
||||
S("Channels are public by default").."\n"..
|
||||
S("Use <player>:<channel> for fully private channels").."\n"..
|
||||
S("Use <player>;<channel> for private receivers")
|
||||
)
|
||||
|
||||
local size = has_digilines and "8,5.9" or "8,4.4"
|
||||
|
||||
local formspec = "formspec_version[2]size["..size.."]"..
|
||||
pipeworks.fs_helpers.get_prepends(size)..
|
||||
"image[0.5,0.3;1,1;pipeworks_teleport_tube_inv.png]"..
|
||||
"label[1.75,0.8;"..S("Teleporting Tube").."]"..
|
||||
"field[0.5,1.7;5,0.8;channel;"..S("Channel")..";${channel}]"..
|
||||
"button_exit[5.5,1.7;2,0.8;save;"..S("Save").."]"..
|
||||
"label[6.5,0.6;"..S("Receive").."]"..
|
||||
"label[0.5,2.8;"..help_text.."]"
|
||||
|
||||
if has_digilines then
|
||||
formspec = formspec..
|
||||
"field[0.5,4.6;5,0.8;digiline_channel;"..S("Digiline Channel")..";${digiline_channel}]"..
|
||||
"button_exit[5.5,4.6;2,0.8;save;"..S("Save").."]"
|
||||
end
|
||||
|
||||
local function update_meta(meta)
|
||||
local channel = meta:get_string("channel")
|
||||
local cr = meta:get_int("can_receive") == 1
|
||||
if channel == "" then
|
||||
meta:set_string("infotext", S("Unconfigured Teleportation Tube"))
|
||||
else
|
||||
local desc = cr and "sending and receiving" or "sending"
|
||||
meta:set_string("infotext", S("Teleportation Tube @1 on '@2'", desc, channel))
|
||||
end
|
||||
local state = cr and "on" or "off"
|
||||
meta:set_string("formspec", formspec..
|
||||
"image_button[6.4,0.8;1,0.6;pipeworks_button_"..state..
|
||||
".png;cr_"..state..";;;false;pipeworks_button_interm.png]")
|
||||
end
|
||||
|
||||
local function update_tube(pos, channel, cr, player_name)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if meta:get_string("channel") == channel and meta:get_int("can_receive") == cr then
|
||||
return
|
||||
end
|
||||
if channel == "" then
|
||||
meta:set_string("channel", "")
|
||||
meta:set_int("can_receive", cr)
|
||||
remove_tube(pos)
|
||||
return
|
||||
end
|
||||
local name, mode = channel:match("^([^:;]+)([:;])")
|
||||
if name and mode and name ~= player_name then
|
||||
if mode == ":" then
|
||||
minetest.chat_send_player(player_name,
|
||||
S("Sorry, channel '@1' is reserved for exclusive use by @2", channel, name))
|
||||
return
|
||||
elseif mode == ";" and cr ~= 0 then
|
||||
minetest.chat_send_player(player_name,
|
||||
S("Sorry, receiving from channel '@1' is reserved for @2", channel, name))
|
||||
return
|
||||
end
|
||||
end
|
||||
meta:set_string("channel", channel)
|
||||
meta:set_int("can_receive", cr)
|
||||
set_tube(pos, channel, cr)
|
||||
end
|
||||
|
||||
local function receive_fields(pos, _, fields, sender)
|
||||
if not fields.channel or not pipeworks.may_configure(pos, sender) then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local channel = fields.channel:trim()
|
||||
local cr = meta:get_int("can_receive")
|
||||
if fields.cr_on then
|
||||
cr = 0
|
||||
elseif fields.cr_off then
|
||||
cr = 1
|
||||
end
|
||||
if has_digilines and fields.digiline_channel then
|
||||
meta:set_string("digiline_channel", fields.digiline_channel)
|
||||
end
|
||||
update_tube(pos, channel, cr, sender:get_player_name())
|
||||
update_meta(meta)
|
||||
end
|
||||
|
||||
local function can_go(pos, node, velocity, stack)
|
||||
velocity.x = 0
|
||||
velocity.y = 0
|
||||
velocity.z = 0
|
||||
local src_meta = minetest.get_meta(pos)
|
||||
local channel = src_meta:get_string("channel")
|
||||
if channel == "" then
|
||||
return {}
|
||||
end
|
||||
local receivers = get_receivers(pos, channel)
|
||||
if #receivers == 0 then
|
||||
return {}
|
||||
end
|
||||
local target = receivers[math.random(1, #receivers)]
|
||||
if enable_logging then
|
||||
local src_owner = src_meta:get_string("owner")
|
||||
local dst_meta = minetest.get_meta(pos)
|
||||
local dst_owner = dst_meta:get_string("owner")
|
||||
minetest.log("action", string.format("[pipeworks] %s teleported from %s (owner=%s) to %s (owner=%s) via %s",
|
||||
stack:to_string(), minetest.pos_to_string(pos), src_owner, minetest.pos_to_string(target), dst_owner, channel
|
||||
))
|
||||
end
|
||||
pos.x = target.x
|
||||
pos.y = target.y
|
||||
pos.z = target.z
|
||||
return pipeworks.meseadjlist
|
||||
end
|
||||
|
||||
local function repair_tube(pos, node)
|
||||
minetest.swap_node(pos, {name = node.name, param2 = node.param2})
|
||||
pipeworks.scan_for_tube_objects(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local channel = meta:get_string("channel")
|
||||
if channel ~= "" then
|
||||
set_tube(pos, channel, meta:get_int("can_receive"))
|
||||
end
|
||||
update_meta(meta)
|
||||
end
|
||||
|
||||
local function digiline_action(pos, _, digiline_channel, msg)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if digiline_channel ~= meta:get_string("digiline_channel") then
|
||||
return
|
||||
end
|
||||
local channel = meta:get_string("channel")
|
||||
local can_receive = meta:get_int("can_receive")
|
||||
if type(msg) == "string" then
|
||||
channel = msg
|
||||
elseif type(msg) == "table" then
|
||||
if type(msg.channel) == "string" then
|
||||
channel = msg.channel
|
||||
end
|
||||
if msg.can_receive == 1 or msg.can_receive == true then
|
||||
can_receive = 1
|
||||
elseif msg.can_receive == 0 or msg.can_receive == false then
|
||||
can_receive = 0
|
||||
end
|
||||
else
|
||||
return
|
||||
end
|
||||
local player_name = meta:get_string("owner")
|
||||
update_tube(pos, channel, can_receive, player_name)
|
||||
update_meta(meta)
|
||||
end
|
||||
|
||||
local def = {
|
||||
tube = {
|
||||
can_go = can_go,
|
||||
on_repair = repair_tube,
|
||||
},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("can_receive", 1) -- Enabled by default
|
||||
update_meta(meta)
|
||||
end,
|
||||
on_receive_fields = receive_fields,
|
||||
on_destruct = remove_tube,
|
||||
}
|
||||
|
||||
if has_digilines then
|
||||
def.after_place_node = function(pos, placer)
|
||||
-- Set owner for digilines
|
||||
minetest.get_meta(pos):set_string("owner", placer:get_player_name())
|
||||
pipeworks.after_place(pos)
|
||||
end
|
||||
def.digiline = {
|
||||
receptor = {
|
||||
rules = pipeworks.digilines_rules,
|
||||
},
|
||||
effector = {
|
||||
rules = pipeworks.digilines_rules,
|
||||
action = digiline_action,
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
pipeworks.register_tube("pipeworks:teleport_tube", {
|
||||
description = S("Teleporting Pneumatic Tube Segment"),
|
||||
inventory_image = "pipeworks_teleport_tube_inv.png",
|
||||
noctr = { "pipeworks_teleport_tube_noctr.png" },
|
||||
plain = { "pipeworks_teleport_tube_plain.png" },
|
||||
ends = { "pipeworks_teleport_tube_end.png" },
|
||||
short = "pipeworks_teleport_tube_short.png",
|
||||
node_def = def,
|
||||
})
|
||||
|
||||
if minetest.get_modpath("mesecons_mvps") then
|
||||
-- Update tubes when moved by pistons
|
||||
mesecon.register_on_mvps_move(function(moved_nodes)
|
||||
for _, n in ipairs(moved_nodes) do
|
||||
if n.node.name:find("pipeworks:teleport_tube") then
|
||||
local meta = minetest.get_meta(n.pos)
|
||||
set_tube(n.pos, meta:get_string("channel"), meta:get_int("can_receive"))
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Expose teleport tube database API for other mods
|
||||
pipeworks.tptube = {
|
||||
version = tube_db_version,
|
||||
hash = hash_pos,
|
||||
get_db = function() return tube_db end,
|
||||
save_tube_db = save_tube_db,
|
||||
set_tube = set_tube,
|
||||
save_tube = save_tube,
|
||||
update_tube = update_tube,
|
||||
update_meta = function(meta, cr)
|
||||
-- Legacy behaviour
|
||||
if cr ~= nil then
|
||||
meta:set_int("can_receive", cr and 1 or 0)
|
||||
end
|
||||
update_meta(meta)
|
||||
end,
|
||||
}
|
||||
|
||||
-- Load the database
|
||||
read_tube_db()
|
102
tubes/vacuum.lua
Normal file
102
tubes/vacuum.lua
Normal file
@ -0,0 +1,102 @@
|
||||
|
||||
local S = minetest.get_translator("pipeworks")
|
||||
|
||||
local enable_max = minetest.settings:get_bool("pipeworks_enable_items_per_tube_limit", true)
|
||||
local max_items = tonumber(minetest.settings:get("pipeworks_max_items_per_tube")) or 30
|
||||
max_items = math.ceil(max_items / 2) -- Limit vacuuming to half the max limit
|
||||
|
||||
local function vacuum(pos, radius)
|
||||
radius = radius + 0.5
|
||||
local min_pos = vector.subtract(pos, radius)
|
||||
local max_pos = vector.add(pos, radius)
|
||||
local count = 0
|
||||
for _, obj in pairs(minetest.get_objects_in_area(min_pos, max_pos)) do
|
||||
local entity = obj:get_luaentity()
|
||||
if entity and entity.name == "__builtin:item" then
|
||||
if entity.itemstring ~= "" then
|
||||
pipeworks.tube_inject_item(pos, pos, vector.new(0, 0, 0), entity.itemstring)
|
||||
entity.itemstring = ""
|
||||
count = count + 1
|
||||
end
|
||||
obj:remove()
|
||||
if enable_max and count >= max_items then
|
||||
return -- Don't break tube by vacuuming too many items
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function set_timer(pos)
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
-- Randomize timer so not all tubes vacuum at the same time
|
||||
timer:start(math.random(10, 20) * 0.1)
|
||||
end
|
||||
|
||||
if pipeworks.enable_sand_tube then
|
||||
pipeworks.register_tube("pipeworks:sand_tube", {
|
||||
description = S("Vacuuming Pneumatic Tube Segment"),
|
||||
inventory_image = "pipeworks_sand_tube_inv.png",
|
||||
short = "pipeworks_sand_tube_short.png",
|
||||
noctr = {"pipeworks_sand_tube_noctr.png"},
|
||||
plain = {"pipeworks_sand_tube_plain.png"},
|
||||
ends = {"pipeworks_sand_tube_end.png"},
|
||||
node_def = {
|
||||
groups = {vacuum_tube = 1},
|
||||
on_construct = set_timer,
|
||||
on_timer = function(pos, elapsed)
|
||||
vacuum(pos, 2)
|
||||
set_timer(pos)
|
||||
end,
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
if pipeworks.enable_mese_sand_tube then
|
||||
local formspec = "formspec_version[2]size[8,3]"..
|
||||
pipeworks.fs_helpers.get_prepends("8,3")..
|
||||
"image[0.5,0.3;1,1;pipeworks_mese_sand_tube_inv.png]"..
|
||||
"label[1.75,0.8;"..S("Adjustable Vacuuming Tube").."]"..
|
||||
"field[0.5,1.7;5,0.8;dist;"..S("Radius")..";${dist}]"..
|
||||
"button_exit[5.5,1.7;2,0.8;save;"..S("Save").."]"
|
||||
|
||||
pipeworks.register_tube("pipeworks:mese_sand_tube", {
|
||||
description = S("Adjustable Vacuuming Tube"),
|
||||
inventory_image = "pipeworks_mese_sand_tube_inv.png",
|
||||
short = "pipeworks_mese_sand_tube_short.png",
|
||||
noctr = {"pipeworks_mese_sand_tube_noctr.png"},
|
||||
plain = {"pipeworks_mese_sand_tube_plain.png"},
|
||||
ends = {"pipeworks_mese_sand_tube_end.png"},
|
||||
node_def = {
|
||||
groups = {vacuum_tube = 1},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("dist", 2)
|
||||
meta:set_string("formspec", formspec)
|
||||
meta:set_string("infotext", S("Adjustable Vacuuming Tube (@1m)", 2))
|
||||
set_timer(pos)
|
||||
end,
|
||||
on_timer = function(pos, elapsed)
|
||||
local radius = minetest.get_meta(pos):get_int("dist")
|
||||
vacuum(pos, radius)
|
||||
set_timer(pos)
|
||||
end,
|
||||
on_receive_fields = function(pos, _, fields, sender)
|
||||
if not fields.dist or not pipeworks.may_configure(pos, sender) then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local dist = math.min(math.max(tonumber(fields.dist) or 0, 0), 8)
|
||||
meta:set_int("dist", dist)
|
||||
meta:set_string("infotext", S("Adjustable Vacuuming Tube (@1m)", dist))
|
||||
end,
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_lbm({
|
||||
label = "Vacuum tube node timer starter",
|
||||
name = "pipeworks:vacuum_tube_start",
|
||||
nodenames = {"group:vacuum_tube"},
|
||||
run_at_every_load = false,
|
||||
action = set_timer,
|
||||
})
|
Reference in New Issue
Block a user