1
0
mirror of https://github.com/mt-mods/pipeworks.git synced 2025-06-29 14:50:41 +02:00

11 Commits

Author SHA1 Message Date
3a01f3f8ca fix chest duplication bug
closes #118
2024-03-17 20:06:35 +01:00
1577af738f Autocrafter multi group ingredient (#115)
* check for non-zero group value

in theory groups can have negative values too.

* fix #114 multi group recipe items

Fix the bug that prevented crafting with recipes
that had ingredients that need to match multiple
groups.

* comments and whitespace changes

* fix faulty empty table check
2024-03-13 17:31:38 +01:00
8828183bef remove nan values from digiline messages 2024-03-12 14:17:29 +11:00
ce263da6d5 also accept strings of tags in digilines and lua
fixes #116
2024-03-07 14:56:19 +11:00
6c66a2f43c Tags support (#107)
Signed-off-by: Slava Zanko <slavazanko@gmail.com>
Co-authored-by: Slava Zanko <slava.zanko@godel.shellenergy.co.uk>
Co-authored-by: BuckarooBanzay <BuckarooBanzay@users.noreply.github.com>
Co-authored-by: OgelGames <olliverdc28@gmail.com>
2024-03-03 22:48:27 +11:00
8724c28939 switch to using xcompat (#113) 2024-03-03 12:37:46 +01:00
cb2a59131c Make wielder nodes not ground content (#112)
nodebreaker, deployer and dispenser
2024-03-03 14:52:23 +13:00
c7b153f1ef Is ground content (#110)
* trashcan isn't ground content

* pipes aren't ground content

* auto tree tap isn't ground content

* filter-injectors aren't ground content

* devices aren't ground content

also some whitespace indentation fixes

* is_ground_content

* autocrafter isn't ground content

* tubes aren't ground content

* pane_embedded_tube isn't ground content

* embedded_tube isn't ground content

* routing tubes aren't ground content

* whitespace fix indentation
2024-02-26 18:44:40 -05:00
96dca7e540 Fix autocrafter crafting bug (#108) 2024-02-08 21:01:54 +11:00
c87522c526 export pipeworks.tptube.remove_tube (#105)
Co-authored-by: BuckarooBanzay <BuckarooBanzay@users.noreply.github.com>
2024-01-28 16:08:24 -05:00
6d824a318a Tube repair fixes (#102)
* restart vacuum tube node timers after repair

* clear metadata value after repair
2024-01-14 10:10:24 +01:00
38 changed files with 393 additions and 144 deletions

View File

@ -20,6 +20,7 @@ read_globals = {
-- mods -- mods
"default", "mesecon", "digiline", "default", "mesecon", "digiline",
"screwdriver", "unified_inventory", "screwdriver", "unified_inventory",
"i3", "mcl_experience", "awards" "i3", "mcl_experience", "awards",
"xcompat",
} }

View File

@ -4,6 +4,7 @@ local S = minetest.get_translator("pipeworks")
local autocrafterCache = {} local autocrafterCache = {}
local craft_time = 1 local craft_time = 1
local next = next
local function count_index(invlist) local function count_index(invlist)
local index = {} local index = {}
@ -48,7 +49,9 @@ local function get_matching_craft(output_name, example_recipe)
elseif recipe_item_name:sub(1, 6) == "group:" then elseif recipe_item_name:sub(1, 6) == "group:" then
group = recipe_item_name:sub(7) group = recipe_item_name:sub(7)
for example_item_name, _ in pairs(index_example) do for example_item_name, _ in pairs(index_example) do
if minetest.get_item_group(example_item_name, group) > 0 then if minetest.get_item_group(
example_item_name, group) ~= 0
then
score = score + 1 score = score + 1
break break
end end
@ -57,6 +60,7 @@ local function get_matching_craft(output_name, example_recipe)
end end
if best_score < score then if best_score < score then
best_index = i best_index = i
best_score = score
end end
end end
@ -88,22 +92,27 @@ local function get_craft(pos, inventory, hash)
return craft return craft
end end
-- From a consumption table with groups and an inventory index, build -- From a consumption table with groups and an inventory index,
-- a consumption table without groups -- build a consumption table without groups
local function calculate_consumption(inv_index, consumption_with_groups) local function calculate_consumption(inv_index, consumption_with_groups)
inv_index = table.copy(inv_index) inv_index = table.copy(inv_index)
consumption_with_groups = table.copy(consumption_with_groups) consumption_with_groups = table.copy(consumption_with_groups)
-- table of items to actually consume
local consumption = {} local consumption = {}
local groups = {} -- table of ingredients defined as one or more groups each
local grouped_ingredients = {}
-- First consume all non-group requirements -- First consume all non-group requirements
-- This is done to avoid consuming a non-group item which is also -- This is done to avoid consuming a non-group item which
-- in a group -- is also in a group
for key, count in pairs(consumption_with_groups) do for key, count in pairs(consumption_with_groups) do
if key:sub(1, 6) == "group:" then if key:sub(1, 6) == "group:" then
groups[#groups + 1] = key:sub(7, #key) -- build table with group recipe items while looping
grouped_ingredients[key] = key:sub(7):split(',')
else else
-- if the item to consume doesn't exist in inventory
-- or not enough of them, abort crafting
if not inv_index[key] or inv_index[key] < count then if not inv_index[key] or inv_index[key] < count then
return nil return nil
end end
@ -117,28 +126,45 @@ local function calculate_consumption(inv_index, consumption_with_groups)
end end
end end
-- helper function to resolve matching ingredients with multiple group
-- requirements
local function ingredient_groups_match_item(ingredient_groups, name)
local found = 0
local count_ingredient_groups = #ingredient_groups
for i = 1, count_ingredient_groups do
if minetest.get_item_group(name,
ingredient_groups[i]) ~= 0
then
found = found + 1
end
end
return found == count_ingredient_groups
end
-- Next, resolve groups using the remaining items in the inventory -- Next, resolve groups using the remaining items in the inventory
local take if next(grouped_ingredients) ~= nil then
if #groups > 0 then local take
for itemname, count in pairs(inv_index) do for itemname, count in pairs(inv_index) do
if count > 0 then if count > 0 then
local def = minetest.registered_items[itemname] -- groupname is the string as defined by recipe.
local item_groups = def and def.groups or {} -- e.g. group:dye,color_blue
for i = 1, #groups do -- groups holds the group names split into a list
local group = groups[i] -- ready to be passed to core.get_item_group()
local groupname = "group:" .. group for groupname, groups in pairs(grouped_ingredients) do
if item_groups[group] and item_groups[group] >= 1 if consumption_with_groups[groupname] > 0
and consumption_with_groups[groupname] > 0 and ingredient_groups_match_item(groups, itemname)
then then
take = math.min(count, consumption_with_groups[groupname]) take = math.min(count,
consumption_with_groups[groupname])
consumption_with_groups[groupname] = consumption_with_groups[groupname] =
consumption_with_groups[groupname] - take consumption_with_groups[groupname] - take
assert(consumption_with_groups[groupname] >= 0) assert(consumption_with_groups[groupname] >= 0)
consumption[itemname] = consumption[itemname] =
(consumption[itemname] or 0) + take (consumption[itemname] or 0) + take
inv_index[itemname] = inv_index[itemname] - take inv_index[itemname] =
inv_index[itemname] - take
assert(inv_index[itemname] >= 0) assert(inv_index[itemname] >= 0)
end end
end end
@ -432,6 +458,7 @@ minetest.register_node("pipeworks:autocrafter", {
drawtype = "normal", drawtype = "normal",
tiles = {"pipeworks_autocrafter.png"}, tiles = {"pipeworks_autocrafter.png"},
groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1, dig_generic = 1, axey=1, handy=1, pickaxey=1}, groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1, dig_generic = 1, axey=1, handy=1, pickaxey=1},
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
tube = {insert_object = function(pos, node, stack, direction) tube = {insert_object = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)

View File

@ -3,6 +3,11 @@ Changelog
2024-02-26 (SwissalpS)
set is_ground_content to false for various nodes.
2023-06-22 (SwissalpS, rubenwardy) 2023-06-22 (SwissalpS, rubenwardy)
groups support in recipe. Set recipe as usual via recipe formspec or digilines. groups support in recipe. Set recipe as usual via recipe formspec or digilines.
Autocrafter now resolves matching recipe using groups so that items in input Autocrafter now resolves matching recipe using groups so that items in input

View File

@ -111,6 +111,12 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end end
minetest.after(0.2, function() minetest.after(0.2, function()
if minetest.get_modpath("default") then if minetest.get_modpath("default") then
local current_node = minetest.get_node(pos)
if current_node.name ~= "default:" .. swap .. "_open" then
-- the chest has already been replaced, don't try to replace what's there.
-- see: https://github.com/minetest/minetest_game/pull/3046
return
end
minetest.swap_node(pos, { name = "default:" .. swap, param2 = node.param2 }) minetest.swap_node(pos, { name = "default:" .. swap, param2 = node.param2 })
end end

View File

@ -1,5 +1,5 @@
-- Crafting recipes for pipes -- Crafting recipes for pipes
local materials = ... local materials = xcompat.materials
minetest.register_craft( { minetest.register_craft( {
output = "pipeworks:pipe_1_empty 12", output = "pipeworks:pipe_1_empty 12",
@ -151,7 +151,7 @@ minetest.register_craft( {
output = "pipeworks:teleport_tube_1 2", output = "pipeworks:teleport_tube_1 2",
recipe = { 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" },
{ materials.desert_stone, materials.teleporter, materials.desert_stone }, { materials.desert_stone, materials.mese, materials.desert_stone },
{ "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" } { "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" }
}, },
}) })
@ -223,6 +223,26 @@ if pipeworks.enable_mese_tube then
}) })
end end
if pipeworks.enable_item_tags and pipeworks.enable_tag_tube then
minetest.register_craft( {
output = "pipeworks:tag_tube_000000 2",
recipe = {
{ "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" },
{ materials.book, materials.mese_crystal, materials.book },
{ "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" }
},
})
minetest.register_craft( {
type = "shapeless",
output = "pipeworks:tag_tube_000000",
recipe = {
"pipeworks:mese_tube_000000",
materials.book,
},
})
end
if pipeworks.enable_sand_tube then if pipeworks.enable_sand_tube then
minetest.register_craft( { minetest.register_craft( {
output = "pipeworks:sand_tube_1 2", output = "pipeworks:sand_tube_1 2",

View File

@ -4,6 +4,8 @@ local prefix = "pipeworks_"
local settings = { local settings = {
enable_pipes = true, enable_pipes = true,
enable_item_tags = true,
enable_tag_tube = true,
enable_lowpoly = false, enable_lowpoly = false,
enable_autocrafter = true, enable_autocrafter = true,
enable_deployer = true, enable_deployer = true,

View File

@ -148,6 +148,7 @@ for s in ipairs(states) do
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
groups = dgroups, groups = dgroups,
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_metal_defaults", key = "node_sound_metal_defaults",
@ -203,6 +204,7 @@ for s in ipairs(states) do
fixed = { -5/16, -4/16, -8/16, 5/16, 5/16, 8/16 } fixed = { -5/16, -4/16, -8/16, 5/16, 5/16, 8/16 }
}, },
groups = dgroups, groups = dgroups,
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_metal_defaults", key = "node_sound_metal_defaults",
@ -254,10 +256,11 @@ minetest.register_node(nodename_valve_loaded, {
fixed = { -5/16, -4/16, -8/16, 5/16, 5/16, 8/16 } fixed = { -5/16, -4/16, -8/16, 5/16, 5/16, 8/16 }
}, },
groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4, axey=1, handy=1, pickaxey=1}, groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4, axey=1, handy=1, pickaxey=1},
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_metal_defaults", key = "node_sound_metal_defaults",
}, },
walkable = true, walkable = true,
on_place = pipeworks.rotate_on_place, on_place = pipeworks.rotate_on_place,
after_dig_node = function(pos) after_dig_node = function(pos)
@ -307,10 +310,11 @@ minetest.register_node("pipeworks:grating", {
sunlight_propagates = true, sunlight_propagates = true,
paramtype = "light", paramtype = "light",
groups = {snappy=3, pipe=1, dig_generic = 4, axey=1, handy=1, pickaxey=1}, groups = {snappy=3, pipe=1, dig_generic = 4, axey=1, handy=1, pickaxey=1},
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_metal_defaults", key = "node_sound_metal_defaults",
}, },
walkable = true, walkable = true,
pipe_connections = { top = 1 }, pipe_connections = { top = 1 },
after_place_node = function(pos) after_place_node = function(pos)
@ -335,10 +339,11 @@ minetest.register_node(nodename_spigot_empty, {
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {snappy=3, pipe=1, dig_generic = 4, axey=1, handy=1, pickaxey=1}, groups = {snappy=3, pipe=1, dig_generic = 4, axey=1, handy=1, pickaxey=1},
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_metal_defaults", key = "node_sound_metal_defaults",
}, },
walkable = true, walkable = true,
pipe_connections = { left=1, right=1, front=1, back=1, pipe_connections = { left=1, right=1, front=1, back=1,
left_param2 = 3, right_param2 = 1, front_param2 = 2, back_param2 = 0 }, left_param2 = 3, right_param2 = 1, front_param2 = 2, back_param2 = 0 },
@ -373,10 +378,11 @@ minetest.register_node(nodename_spigot_loaded, {
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4, axey=1, handy=1, pickaxey=1}, groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4, axey=1, handy=1, pickaxey=1},
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_metal_defaults", key = "node_sound_metal_defaults",
}, },
walkable = true, walkable = true,
pipe_connections = { left=1, right=1, front=1, back=1, pipe_connections = { left=1, right=1, front=1, back=1,
left_param2 = 3, right_param2 = 1, front_param2 = 2, back_param2 = 0 }, left_param2 = 3, right_param2 = 1, front_param2 = 2, back_param2 = 0 },
@ -432,10 +438,11 @@ minetest.register_node(nodename_panel_empty, {
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {snappy=3, pipe=1, dig_generic = 4, axey=1, handy=1, pickaxey=1}, groups = {snappy=3, pipe=1, dig_generic = 4, axey=1, handy=1, pickaxey=1},
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_metal_defaults", key = "node_sound_metal_defaults",
}, },
walkable = true, walkable = true,
on_place = pipeworks.rotate_on_place, on_place = pipeworks.rotate_on_place,
after_dig_node = function(pos) after_dig_node = function(pos)
@ -455,10 +462,11 @@ minetest.register_node(nodename_panel_loaded, {
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4, axey=1, handy=1, pickaxey=1}, groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4, axey=1, handy=1, pickaxey=1},
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_metal_defaults", key = "node_sound_metal_defaults",
}, },
walkable = true, walkable = true,
on_place = pipeworks.rotate_on_place, on_place = pipeworks.rotate_on_place,
after_dig_node = function(pos) after_dig_node = function(pos)
@ -488,10 +496,11 @@ minetest.register_node(nodename_sensor_empty, {
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {snappy=3, pipe=1, dig_generic = 4, axey=1, handy=1, pickaxey=1}, groups = {snappy=3, pipe=1, dig_generic = 4, axey=1, handy=1, pickaxey=1},
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_metal_defaults", key = "node_sound_metal_defaults",
}, },
walkable = true, walkable = true,
on_place = pipeworks.rotate_on_place, on_place = pipeworks.rotate_on_place,
after_dig_node = function(pos) after_dig_node = function(pos)
@ -530,10 +539,11 @@ minetest.register_node(nodename_sensor_loaded, {
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4, axey=1, handy=1, pickaxey=1}, groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4, axey=1, handy=1, pickaxey=1},
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_metal_defaults", key = "node_sound_metal_defaults",
}, },
walkable = true, walkable = true,
on_place = pipeworks.rotate_on_place, on_place = pipeworks.rotate_on_place,
after_dig_node = function(pos) after_dig_node = function(pos)
@ -600,6 +610,7 @@ for fill = 0, 10 do
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {snappy=3, pipe=1, tankfill=fill+1, not_in_creative_inventory=1, dig_generic = 4, axey=1, handy=1, pickaxey=1}, groups = {snappy=3, pipe=1, tankfill=fill+1, not_in_creative_inventory=1, dig_generic = 4, axey=1, handy=1, pickaxey=1},
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_metal_defaults", key = "node_sound_metal_defaults",
@ -631,6 +642,7 @@ for fill = 0, 10 do
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
groups = sgroups, groups = sgroups,
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_metal_defaults", key = "node_sound_metal_defaults",
@ -661,10 +673,11 @@ minetest.register_node(nodename_fountain_empty, {
sunlight_propagates = true, sunlight_propagates = true,
paramtype = "light", paramtype = "light",
groups = {snappy=3, pipe=1, dig_generic = 4, axey=1, handy=1, pickaxey=1}, groups = {snappy=3, pipe=1, dig_generic = 4, axey=1, handy=1, pickaxey=1},
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_metal_defaults", key = "node_sound_metal_defaults",
}, },
walkable = true, walkable = true,
pipe_connections = { bottom = 1 }, pipe_connections = { bottom = 1 },
after_place_node = function(pos) after_place_node = function(pos)
@ -699,10 +712,11 @@ minetest.register_node(nodename_fountain_loaded, {
sunlight_propagates = true, sunlight_propagates = true,
paramtype = "light", paramtype = "light",
groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4, axey=1, handy=1, pickaxey=1}, groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4, axey=1, handy=1, pickaxey=1},
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_metal_defaults", key = "node_sound_metal_defaults",
}, },
walkable = true, walkable = true,
pipe_connections = { bottom = 1 }, pipe_connections = { bottom = 1 },
after_place_node = function(pos) after_place_node = function(pos)
@ -752,10 +766,11 @@ minetest.register_node(nodename_sp_empty, {
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {snappy=3, pipe=1, dig_generic = 4, axey=1, handy=1, pickaxey=1}, groups = {snappy=3, pipe=1, dig_generic = 4, axey=1, handy=1, pickaxey=1},
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_metal_defaults", key = "node_sound_metal_defaults",
}, },
walkable = true, walkable = true,
on_place = pipeworks.rotate_on_place, on_place = pipeworks.rotate_on_place,
after_dig_node = function(pos) after_dig_node = function(pos)
@ -777,10 +792,11 @@ minetest.register_node(nodename_sp_loaded, {
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4, axey=1, handy=1, pickaxey=1}, groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4, axey=1, handy=1, pickaxey=1},
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_metal_defaults", key = "node_sound_metal_defaults",
}, },
walkable = true, walkable = true,
on_place = pipeworks.rotate_on_place, on_place = pipeworks.rotate_on_place,
after_dig_node = function(pos) after_dig_node = function(pos)

View File

@ -14,20 +14,29 @@ local function set_filter_formspec(data, meta)
local formspec local formspec
if data.digiline then if data.digiline then
local form_height = 3
if pipeworks.enable_item_tags then
form_height = 4
end
formspec = formspec =
"size[8.5,3]".. ("size[8.5,%f]"):format(form_height) ..
"item_image[0.2,0;1,1;pipeworks:"..data.name.."]".. "item_image[0.2,0;1,1;pipeworks:"..data.name.."]"..
"label[1.2,0.2;"..minetest.formspec_escape(itemname).."]".. "label[1.2,0.2;"..minetest.formspec_escape(itemname).."]"..
"field[0.5,1.6;4.6,1;channel;"..S("Channel")..";${channel}]".. "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[4.8,1.3;1.5,1;set_channel;"..S("Set").."]"..
fs_helpers.cycling_button(meta, "button[0.2,2.3;4.05,1", "slotseq_mode", fs_helpers.cycling_button(meta, ("button[0.2,%f;4.05,1"):format(form_height - 0.7), "slotseq_mode",
{S("Sequence slots by Priority"), {S("Sequence slots by Priority"),
S("Sequence slots Randomly"), S("Sequence slots Randomly"),
S("Sequence slots by Rotation")}).. S("Sequence slots by Rotation")})..
fs_helpers.cycling_button(meta, "button[4.25,2.3;4.05,1", "exmatch_mode", fs_helpers.cycling_button(meta, ("button[4.25,%f;4.05,1"):format(form_height - 0.7), "exmatch_mode",
{S("Exact match - off"), {S("Exact match - off"),
S("Exact match - on")}).. S("Exact match - on")})..
"button_exit[6.3,1.3;2,1;close;"..S("Close").."]" ("button_exit[6.3,%f;2,1;close;" .. S("Close") .. "]"):format(form_height - 1.7)
if pipeworks.enable_item_tags then
formspec = formspec ..
("field[0.5,%f;4.6,1;item_tags;"):format(form_height - 1.4) .. S("Item Tags") .. ";${item_tags}]" ..
("button[4.8,%f;1.5,1;set_item_tags;"):format(form_height - 1.7) .. S("Set") .. "]"
end
else else
local exmatch_button = "" local exmatch_button = ""
if data.stackwise then if data.stackwise then
@ -62,6 +71,11 @@ local function set_filter_formspec(data, meta)
exmatch_button.. exmatch_button..
pipeworks.fs_helpers.get_inv(6).. pipeworks.fs_helpers.get_inv(6)..
"listring[]" "listring[]"
if pipeworks.enable_item_tags then
formspec = formspec ..
"field[5.8,0.5;3,0.8;item_tags;" .. S("Item Tags") .. ";${item_tags}]" ..
"button[9,0.3;1,1.1;set_item_tags;" .. S("Set") .. "]"
end
end end
meta:set_string("formspec", formspec) meta:set_string("formspec", formspec)
end end
@ -123,6 +137,7 @@ local function punch_filter(data, filtpos, filtnode, msg)
local slotseq_mode local slotseq_mode
local exmatch_mode local exmatch_mode
local item_tags = pipeworks.sanitize_tags(filtmeta:get_string("item_tags"))
local filters = {} local filters = {}
if data.digiline then if data.digiline then
local function add_filter(name, group, count, wear, metadata) local function add_filter(name, group, count, wear, metadata)
@ -186,6 +201,12 @@ local function punch_filter(data, filtpos, filtnode, msg)
set_filter_formspec(data, filtmeta) set_filter_formspec(data, filtmeta)
end end
if type(msg.tags) == "table" or type(msg.tags) == "string" then
item_tags = pipeworks.sanitize_tags(msg.tags)
elseif type(msg.tag) == "string" then
item_tags = pipeworks.sanitize_tags({msg.tag})
end
if msg.nofire then if msg.nofire then
return return
end end
@ -339,7 +360,7 @@ local function punch_filter(data, filtpos, filtnode, msg)
local pos = vector.add(frompos, vector.multiply(dir, 1.4)) local pos = vector.add(frompos, vector.multiply(dir, 1.4))
local start_pos = vector.add(frompos, dir) local start_pos = vector.add(frompos, dir)
pipeworks.tube_inject_item(pos, start_pos, dir, item, pipeworks.tube_inject_item(pos, start_pos, dir, item,
fakePlayer:get_player_name()) fakePlayer:get_player_name(), item_tags)
return true -- only fire one item, please return true -- only fire one item, please
end end
end end
@ -389,6 +410,7 @@ for _, data in ipairs({
}, },
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, mesecon = 2, axey=1, handy=1, pickaxey=1}, groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, mesecon = 2, axey=1, handy=1, pickaxey=1},
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
legacy_facedir_simple = true, legacy_facedir_simple = true,
_sound_def = { _sound_def = {
@ -456,6 +478,10 @@ for _, data in ipairs({
end end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if pipeworks.enable_item_tags and fields.item_tags and (fields.key_enter_field == "item_tags" or fields.set_item_tags) then
local tags = pipeworks.sanitize_tags(fields.item_tags)
meta:set_string("item_tags", table.concat(tags, ","))
end
--meta:set_int("slotseq_index", 1) --meta:set_int("slotseq_index", 1)
set_filter_formspec(data, meta) set_filter_formspec(data, meta)
set_filter_infotext(data, meta) set_filter_infotext(data, meta)
@ -477,6 +503,10 @@ for _, data in ipairs({
fs_helpers.on_receive_fields(pos, fields) fs_helpers.on_receive_fields(pos, fields)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_int("slotseq_index", 1) meta:set_int("slotseq_index", 1)
if pipeworks.enable_item_tags and fields.item_tags and (fields.key_enter_field == "item_tags" or fields.set_item_tags) then
local tags = pipeworks.sanitize_tags(fields.item_tags)
meta:set_string("item_tags", table.concat(tags, ","))
end
set_filter_formspec(data, meta) set_filter_formspec(data, meta)
set_filter_infotext(data, meta) set_filter_infotext(data, meta)
end end

View File

@ -61,15 +61,13 @@ dofile(pipeworks.modpath.."/flowing_logic.lua")
dofile(pipeworks.modpath.."/filter-injector.lua") dofile(pipeworks.modpath.."/filter-injector.lua")
dofile(pipeworks.modpath.."/trashcan.lua") dofile(pipeworks.modpath.."/trashcan.lua")
dofile(pipeworks.modpath.."/wielder.lua") dofile(pipeworks.modpath.."/wielder.lua")
local materials = loadfile(pipeworks.modpath.."/materials.lua")()
dofile(pipeworks.modpath.."/tubes/registration.lua") dofile(pipeworks.modpath.."/tubes/registration.lua")
dofile(pipeworks.modpath.."/tubes/routing.lua") dofile(pipeworks.modpath.."/tubes/routing.lua")
dofile(pipeworks.modpath.."/tubes/sorting.lua") dofile(pipeworks.modpath.."/tubes/sorting.lua")
dofile(pipeworks.modpath.."/tubes/signal.lua") dofile(pipeworks.modpath.."/tubes/signal.lua")
loadfile(pipeworks.modpath.."/tubes/embedded_tube.lua")(materials) dofile(pipeworks.modpath.."/tubes/embedded_tube.lua")
dofile(pipeworks.modpath.."/tubes/pane_embedded_tube.lua") dofile(pipeworks.modpath.."/tubes/pane_embedded_tube.lua")
dofile(pipeworks.modpath.."/tubes/tags.lua")
if pipeworks.enable_teleport_tube then if pipeworks.enable_teleport_tube then
dofile(pipeworks.modpath.."/tubes/teleport.lua") dofile(pipeworks.modpath.."/tubes/teleport.lua")
@ -111,7 +109,7 @@ if pipeworks.enable_autocrafter then
dofile(pipeworks.modpath.."/autocrafter.lua") dofile(pipeworks.modpath.."/autocrafter.lua")
end end
loadfile(pipeworks.modpath.."/crafts.lua")(materials) dofile(pipeworks.modpath.."/crafts.lua")
minetest.register_alias("pipeworks:pipe", "pipeworks:pipe_110000_empty") minetest.register_alias("pipeworks:pipe", "pipeworks:pipe_110000_empty")

View File

@ -3,11 +3,36 @@ local enable_max_limit = minetest.settings:get_bool("pipeworks_enable_items_per_
local max_tube_limit = tonumber(minetest.settings:get("pipeworks_max_items_per_tube")) or 30 local max_tube_limit = tonumber(minetest.settings:get("pipeworks_max_items_per_tube")) or 30
if enable_max_limit == nil then enable_max_limit = true end if enable_max_limit == nil then enable_max_limit = true end
if pipeworks.enable_item_tags then
local max_tag_length = tonumber(minetest.settings:get("pipeworks_max_item_tag_length")) or 32
local max_tags = tonumber(minetest.settings:get("pipeworks_max_item_tags")) or 16
function pipeworks.sanitize_tags(tags)
if type(tags) == "string" then
tags = tags:split(",")
end
local sanitized = {}
for i, tag in ipairs(tags) do
if type(tag) == "string" then
tag = tag:gsub("[%s,]", "") -- Remove whitespace and commas
tag = tag:gsub("%$%b%{%}", "") -- Remove special ${key} values
if tag ~= "" then
table.insert(sanitized, tag:sub(1, max_tag_length))
end
end
if #sanitized >= max_tags then
break
end
end
return sanitized
end
end
function pipeworks.tube_item(pos, item) function pipeworks.tube_item(pos, item)
error("obsolete pipeworks.tube_item() called; change caller to use pipeworks.tube_inject_item() instead") error("obsolete pipeworks.tube_item() called; change caller to use pipeworks.tube_inject_item() instead")
end end
function pipeworks.tube_inject_item(pos, start_pos, velocity, item, owner) function pipeworks.tube_inject_item(pos, start_pos, velocity, item, owner, tags)
-- Take item in any format -- Take item in any format
local stack = ItemStack(item) local stack = ItemStack(item)
local obj = luaentity.add_entity(pos, "pipeworks:tubed_item") local obj = luaentity.add_entity(pos, "pipeworks:tubed_item")
@ -15,6 +40,7 @@ function pipeworks.tube_inject_item(pos, start_pos, velocity, item, owner)
obj.start_pos = vector.new(start_pos) obj.start_pos = vector.new(start_pos)
obj:set_velocity(velocity) obj:set_velocity(velocity)
obj.owner = owner obj.owner = owner
obj.tags = tags
--obj:set_color("red") -- todo: this is test-only code --obj:set_color("red") -- todo: this is test-only code
return obj return obj
end end
@ -79,13 +105,14 @@ end
-- compatibility behaviour for the existing can_go() callbacks, -- compatibility behaviour for the existing can_go() callbacks,
-- which can only specify a list of possible positions. -- which can only specify a list of possible positions.
local function go_next_compat(pos, cnode, cmeta, cycledir, vel, stack, owner) local function go_next_compat(pos, cnode, cmeta, cycledir, vel, stack, owner, tags)
local next_positions = {} local next_positions = {}
local max_priority = 0 local max_priority = 0
local can_go local can_go
if minetest.registered_nodes[cnode.name] and minetest.registered_nodes[cnode.name].tube and minetest.registered_nodes[cnode.name].tube.can_go then local def = minetest.registered_nodes[cnode.name]
can_go = minetest.registered_nodes[cnode.name].tube.can_go(pos, cnode, vel, stack) if def and def.tube and def.tube.can_go then
can_go = def.tube.can_go(pos, cnode, vel, stack, tags)
else else
local adjlist_string = minetest.get_meta(pos):get_string("adjlist") local adjlist_string = minetest.get_meta(pos):get_string("adjlist")
local adjlist = minetest.deserialize(adjlist_string) or default_adjlist -- backward compat: if not found, use old behavior: all directions local adjlist = minetest.deserialize(adjlist_string) or default_adjlist -- backward compat: if not found, use old behavior: all directions
@ -144,7 +171,7 @@ end
-- * a "multi-mode" data table (or nil if N/A) where a stack was split apart. -- * a "multi-mode" data table (or nil if N/A) where a stack was split apart.
-- if this is not nil, the luaentity spawns new tubed items for each new fragment stack, -- if this is not nil, the luaentity spawns new tubed items for each new fragment stack,
-- then deletes itself (i.e. the original item stack). -- then deletes itself (i.e. the original item stack).
local function go_next(pos, velocity, stack, owner) local function go_next(pos, velocity, stack, owner, tags)
local cnode = minetest.get_node(pos) local cnode = minetest.get_node(pos)
local cmeta = minetest.get_meta(pos) local cmeta = minetest.get_meta(pos)
local speed = math.abs(velocity.x + velocity.y + velocity.z) local speed = math.abs(velocity.x + velocity.y + velocity.z)
@ -172,7 +199,7 @@ local function go_next(pos, velocity, stack, owner)
-- n is the new value of the cycle counter. -- n is the new value of the cycle counter.
-- XXX: this probably needs cleaning up after being split out, -- XXX: this probably needs cleaning up after being split out,
-- seven args is a bit too many -- seven args is a bit too many
local n, found, new_velocity, multimode = go_next_compat(pos, cnode, cmeta, cycledir, vel, stack, owner) local n, found, new_velocity, multimode = go_next_compat(pos, cnode, cmeta, cycledir, vel, stack, owner, tags)
-- if not using output cycling, -- if not using output cycling,
-- don't update the field so it stays the same for the next item. -- don't update the field so it stays the same for the next item.
@ -276,6 +303,7 @@ luaentity.register_entity("pipeworks:tubed_item", {
color_entity = nil, color_entity = nil,
color = nil, color = nil,
start_pos = nil, start_pos = nil,
tags = nil,
set_item = function(self, item) set_item = function(self, item)
local itemstring = ItemStack(item):to_string() -- Accept any input format local itemstring = ItemStack(item):to_string() -- Accept any input format
@ -337,8 +365,9 @@ luaentity.register_entity("pipeworks:tubed_item", {
local node = minetest.get_node(self.start_pos) local node = minetest.get_node(self.start_pos)
if minetest.get_item_group(node.name, "tubedevice_receiver") == 1 then if minetest.get_item_group(node.name, "tubedevice_receiver") == 1 then
local leftover local leftover
if minetest.registered_nodes[node.name].tube and minetest.registered_nodes[node.name].tube.insert_object then local def = minetest.registered_nodes[node.name]
leftover = minetest.registered_nodes[node.name].tube.insert_object(self.start_pos, node, stack, vel, self.owner) if def.tube and def.tube.insert_object then
leftover = def.tube.insert_object(self.start_pos, node, stack, vel, self.owner)
else else
leftover = stack leftover = stack
end end
@ -353,7 +382,14 @@ luaentity.register_entity("pipeworks:tubed_item", {
return return
end end
local found_next, new_velocity, multimode = go_next(self.start_pos, velocity, stack, self.owner) -- todo: color local tags
if pipeworks.enable_item_tags then
tags = self.tags or {}
end
local found_next, new_velocity, multimode = go_next(self.start_pos, velocity, stack, self.owner, tags) -- todo: color
if pipeworks.enable_item_tags then
self.tags = #tags > 0 and tags or nil
end
local rev_vel = vector.multiply(velocity, -1) local rev_vel = vector.multiply(velocity, -1)
local rev_dir = vector.direction(self.start_pos,vector.add(self.start_pos,rev_vel)) local rev_dir = vector.direction(self.start_pos,vector.add(self.start_pos,rev_vel))
local rev_node = minetest.get_node(vector.round(vector.add(self.start_pos,rev_dir))) local rev_node = minetest.get_node(vector.round(vector.add(self.start_pos,rev_dir)))

View File

@ -24,7 +24,7 @@ if not minetest.get_modpath("auto_tree_tap") and
description = S("Auto-Tap"), description = S("Auto-Tap"),
tiles = {"pipeworks_nodebreaker_top_off.png","pipeworks_nodebreaker_bottom_off.png","pipeworks_nodebreaker_side2_off.png","pipeworks_nodebreaker_side1_off.png", tiles = {"pipeworks_nodebreaker_top_off.png","pipeworks_nodebreaker_bottom_off.png","pipeworks_nodebreaker_side2_off.png","pipeworks_nodebreaker_side1_off.png",
"pipeworks_nodebreaker_back.png","pipeworks_nodebreaker_front_off.png"}, "pipeworks_nodebreaker_back.png","pipeworks_nodebreaker_front_off.png"},
is_ground_content = true, is_ground_content = false,
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2, mesecon = 2,tubedevice=1, not_in_creative_inventory=1, axey=1, handy=1, pickaxey=1}, groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2, mesecon = 2,tubedevice=1, not_in_creative_inventory=1, axey=1, handy=1, pickaxey=1},
_mcl_hardness=0.8, _mcl_hardness=0.8,

View File

@ -1,67 +0,0 @@
local materials = {
stone = "default:stone",
desert_stone = "default:desert_stone",
desert_sand = "default:desert_sand",
chest = "default:chest",
copper_ingot = "default:copper_ingot",
steel_ingot = "default:steel_ingot",
gold_ingot = "default:gold_ingot",
mese = "default:mese",
mese_crystal = "default:mese_crystal",
mese_crystal_fragment = "default:mese_crystal_fragment",
teleporter = "default:mese",
glass = "default:glass"
}
if minetest.get_modpath("mcl_core") then
materials = {
stone = "mcl_core:stone",
desert_stone = "mcl_core:redsandstone",
desert_sand = "mcl_core:sand",
chest = "mcl_chests:chest",
steel_ingot = "mcl_core:iron_ingot",
gold_ingot = "mcl_core:gold_ingot",
mese = "mesecons_torch:redstoneblock",
mese_crystal = "mesecons:redstone",
mese_crystal_fragment = "mesecons:redstone",
teleporter = "mesecons_torch:redstoneblock",
copper_ingot = "mcl_copper:copper_ingot",
glass = "mcl_core:glass",
}
elseif minetest.get_modpath("fl_ores") and minetest.get_modpath("fl_stone") then
materials = {
stone = "fl_stone:stone",
desert_stone = "fl_stone:desert_stone",
desert_sand = "fl_stone:desert_sand",
chest = "fl_storage:wood_chest",
steel_ingot = "fl_ores:iron_ingot",
gold_ingot = "fl_ores:gold_ingot",
mese = "fl_ores:iron_ingot",
mese_crystal = "fl_ores:iron_ingot",
mese_crystal_fragment = "fl_ores:iron_ingot",
teleporter = "fl_ores:iron_ingot",
copper_ingot = "fl_ores:copper_ingot",
glass = "fl_glass:framed_glass",
}
elseif minetest.get_modpath("hades_core") then
materials = {
stone = "hades_core:stone",
desert_stone = "hades_core:stone_baked",
desert_sand = "hades_core:volcanic_sand",
chest = "hades_chests:chest";
steel_ingot = "hades_core:steel_ingot",
gold_ingot = "hades_core:gold_ingot",
mese = "hades_core:mese",
mese_crystal = "hades_core:mese_crystal",
mese_crystal_fragment = "hades_core:mese_crystal_fragment",
teleporter = "hades_materials:teleporter_device",
copper_ingot = "hades_core:copper_ingot",
tin_ingot = "hades_core:tin_ingot",
glass = "hades_core:glass",
}
if minetest.get_modpath("hades_default") then
materials.desert_sand = "hades_default:desert_sand"
end
end
return materials

View File

@ -1,5 +1,5 @@
name = pipeworks name = pipeworks
description = This mod uses mesh nodes and nodeboxes to supply a complete set of 3D pipes and tubes, along with devices that work with them. description = This mod uses mesh nodes and nodeboxes to supply a complete set of 3D pipes and tubes, along with devices that work with them.
depends = basic_materials depends = basic_materials, xcompat
optional_depends = mesecons, mesecons_mvps, digilines, signs_lib, unified_inventory, default, screwdriver, fl_mapgen, sound_api, i3, hades_core, hades_furnaces, hades_chests, mcl_mapgen_core, mcl_barrels, mcl_furnaces, mcl_experience optional_depends = mesecons, mesecons_mvps, digilines, signs_lib, unified_inventory, default, screwdriver, fl_mapgen, sound_api, i3, hades_core, hades_furnaces, hades_chests, mcl_mapgen_core, mcl_barrels, mcl_furnaces, mcl_experience
min_minetest_version = 5.5.0 min_minetest_version = 5.5.0

View File

@ -76,6 +76,7 @@ for index, connects in ipairs(cconnects) do
fixed = outsel fixed = outsel
}, },
groups = pgroups, groups = pgroups,
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_metal_defaults", key = "node_sound_metal_defaults",
@ -113,6 +114,7 @@ for index, connects in ipairs(cconnects) do
fixed = outsel fixed = outsel
}, },
groups = pgroups, groups = pgroups,
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_metal_defaults", key = "node_sound_metal_defaults",
@ -151,6 +153,7 @@ if REGISTER_COMPATIBILITY then
paramtype = "light", paramtype = "light",
description = S("Pipe Segment (legacy)"), description = S("Pipe Segment (legacy)"),
groups = {not_in_creative_inventory = 1, pipe_to_update = 1}, groups = {not_in_creative_inventory = 1, pipe_to_update = 1},
is_ground_content = false,
drop = "pipeworks:pipe_1_empty", drop = "pipeworks:pipe_1_empty",
after_place_node = function(pos) after_place_node = function(pos)
pipeworks.scan_for_pipe_objects(pos) pipeworks.scan_for_pipe_objects(pos)
@ -163,6 +166,7 @@ if REGISTER_COMPATIBILITY then
sunlight_propagates = true, sunlight_propagates = true,
paramtype = "light", paramtype = "light",
groups = {not_in_creative_inventory = 1, pipe_to_update = 1}, groups = {not_in_creative_inventory = 1, pipe_to_update = 1},
is_ground_content = false,
drop = "pipeworks:pipe_1_empty", drop = "pipeworks:pipe_1_empty",
after_place_node = function(pos) after_place_node = function(pos)
pipeworks.scan_for_pipe_objects(pos) pipeworks.scan_for_pipe_objects(pos)

Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 769 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 753 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 864 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 865 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 863 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 864 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 871 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

View File

@ -11,6 +11,7 @@ minetest.register_node("pipeworks:trashcan", {
"pipeworks_trashcan_side.png", "pipeworks_trashcan_side.png",
}, },
groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1, dig_generic = 4, axey=1, handy=1, pickaxey=1}, groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1, dig_generic = 4, axey=1, handy=1, pickaxey=1},
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
tube = { tube = {
insert_object = function(pos, node, stack, direction) insert_object = function(pos, node, stack, direction)

View File

@ -1,4 +1,4 @@
local materials = ... local materials = xcompat.materials
local S = minetest.get_translator("pipeworks") local S = minetest.get_translator("pipeworks")
local straight = function(pos, node, velocity, stack) return {velocity} end local straight = function(pos, node, velocity, stack) return {velocity} end
@ -27,6 +27,7 @@ function pipeworks.register_embedded_tube(nodename, opts)
pickaxey=1, pickaxey=1,
handy=1 handy=1
}, },
is_ground_content = false,
_mcl_hardness = 0.8, _mcl_hardness = 0.8,
legacy_facedir_simple = true, legacy_facedir_simple = true,
_sound_def = { _sound_def = {

View File

@ -370,7 +370,10 @@ local function clean_and_weigh_digiline_message(msg, back_references)
return msg, #msg + 25 return msg, #msg + 25
elseif t == "number" then elseif t == "number" then
-- Numbers are passed by value so need not be touched, and cost 8 bytes -- Numbers are passed by value so need not be touched, and cost 8 bytes
-- as all numbers in Lua are doubles. -- as all numbers in Lua are doubles. NaN values are removed.
if msg ~= msg then
return nil, 0
end
return msg, 8 return msg, 8
elseif t == "boolean" then elseif t == "boolean" then
-- Booleans are passed by value so need not be touched, and cost 1 -- Booleans are passed by value so need not be touched, and cost 1
@ -945,7 +948,7 @@ for white = 0, 1 do
tube = { tube = {
connect_sides = {front = 1, back = 1, left = 1, right = 1, top = 1, bottom = 1}, connect_sides = {front = 1, back = 1, left = 1, right = 1, top = 1, bottom = 1},
priority = 50, priority = 50,
can_go = function(pos, node, velocity, stack) can_go = function(pos, node, velocity, stack, tags)
local src = {name = nil} local src = {name = nil}
-- add color of the incoming tube explicitly; referring to rules, in case they change later -- add color of the incoming tube explicitly; referring to rules, in case they change later
for _, rule in pairs(rules) do for _, rule in pairs(rules) do
@ -960,12 +963,33 @@ for white = 0, 1 do
itemstring = stack:to_string(), itemstring = stack:to_string(),
item = stack:to_table(), item = stack:to_table(),
velocity = velocity, velocity = velocity,
tags = table.copy(tags),
side = src.name,
}) })
if not succ or type(msg) ~= "string" then if not succ then
return go_back(velocity) return go_back(velocity)
end end
local r = rules[msg] if type(msg) == "string" then
return r and {r} or go_back(velocity) local side = rules[msg]
return side and {side} or go_back(velocity)
elseif type(msg) == "table" then
if pipeworks.enable_item_tags then
local new_tags
if type(msg.tags) == "table" or type(msg.tags) == "string" then
new_tags = pipeworks.sanitize_tags(msg.tags)
elseif type(msg.tag) == "string" then
new_tags = pipeworks.sanitize_tags({msg.tag})
end
if new_tags then
for i=1, math.max(#tags, #new_tags) do
tags[i] = new_tags[i]
end
end
end
local side = rules[msg.side]
return side and {side} or go_back(velocity)
end
return go_back(velocity)
end, end,
}, },
after_place_node = pipeworks.after_place, after_place_node = pipeworks.after_place,

View File

@ -31,11 +31,12 @@ minetest.register_node("pipeworks:steel_pane_embedded_tube", {
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {cracky=1, oddly_breakable_by_hand = 1, tubedevice = 1, dig_glass = 2, pickaxey=1, handy=1}, groups = {cracky=1, oddly_breakable_by_hand = 1, tubedevice = 1, dig_glass = 2, pickaxey=1, handy=1},
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
legacy_facedir_simple = true, legacy_facedir_simple = true,
_sound_def = { _sound_def = {
key = "node_sound_stone_defaults", key = "node_sound_stone_defaults",
}, },
tube = { tube = {
connect_sides = {front = 1, back = 1,}, connect_sides = {front = 1, back = 1,},
priority = 50, priority = 50,

View File

@ -106,6 +106,7 @@ local register_one_tube = function(name, tname, dropname, desc, plain, noctrs, e
fixed = outboxes fixed = outboxes
}, },
groups = tgroups, groups = tgroups,
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_wood_defaults", key = "node_sound_wood_defaults",
@ -227,6 +228,7 @@ local register_all_tubes = function(name, desc, plain, noctrs, ends, short, inv,
description = S("Pneumatic tube segment (legacy)"), description = S("Pneumatic tube segment (legacy)"),
after_place_node = pipeworks.after_place, after_place_node = pipeworks.after_place,
groups = {not_in_creative_inventory = 1, tube_to_update = 1, tube = 1}, groups = {not_in_creative_inventory = 1, tube_to_update = 1, tube = 1},
is_ground_content = false,
tube = {connect_sides = {front = 1, back = 1, left = 1, right = 1, top = 1, bottom = 1}}, tube = {connect_sides = {front = 1, back = 1, left = 1, right = 1, top = 1, bottom = 1}},
drop = name.."_1", drop = name.."_1",
}) })

View File

@ -50,6 +50,7 @@ pipeworks.register_tube("pipeworks:broken_tube", {
node_def = { node_def = {
drop = "pipeworks:tube_1", drop = "pipeworks:tube_1",
groups = {not_in_creative_inventory = 1, tubedevice_receiver = 1}, groups = {not_in_creative_inventory = 1, tubedevice_receiver = 1},
is_ground_content = false,
tube = { tube = {
insert_object = function(pos, node, stack, direction) insert_object = function(pos, node, stack, direction)
minetest.item_drop(stack, nil, pos) minetest.item_drop(stack, nil, pos)
@ -179,6 +180,7 @@ if pipeworks.enable_one_way_tube then
node_box = {type = "fixed", node_box = {type = "fixed",
fixed = {{-1/2, -9/64, -9/64, 1/2, 9/64, 9/64}}}, 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}, groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, tubedevice = 1, axey=1, handy=1, pickaxey=1},
is_ground_content = false,
_mcl_hardness=0.8, _mcl_hardness=0.8,
_sound_def = { _sound_def = {
key = "node_sound_wood_defaults", key = "node_sound_wood_defaults",

139
tubes/tags.lua Normal file
View File

@ -0,0 +1,139 @@
local S = minetest.get_translator("pipeworks")
local fs_helpers = pipeworks.fs_helpers
if not pipeworks.enable_item_tags or not pipeworks.enable_tag_tube then return end
local help_text = minetest.formspec_escape(
S("Separate multiple tags using commas.").."\n"..
S("Use \"<none>\" to match items without tags.")
)
local update_formspec = function(pos)
local meta = minetest.get_meta(pos)
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 size = "10.2,9"
meta:set_string("formspec",
"formspec_version[2]" ..
"size[" .. size .. "]" ..
pipeworks.fs_helpers.get_prepends(size) ..
"field[1.5,0.25;7.25,1;tags1;;${tags1}]" ..
"field[1.5,1.5;7.25,1;tags2;;${tags2}]" ..
"field[1.5,2.75;7.25,1;tags3;;${tags3}]" ..
"field[1.5,4.0;7.25,1;tags4;;${tags4}]" ..
"field[1.5,5.25;7.25,1;tags5;;${tags5}]" ..
"field[1.5,6.5;7.25,1;tags6;;${tags6}]" ..
"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 ..
"label[0.22,7.9;"..help_text.."]"..
"button[7.25,7.8;1.5,0.8;set_item_tags;" .. S("Set") .. "]"
)
end
pipeworks.register_tube("pipeworks:tag_tube", {
description = S("Tag Sorting Pneumatic Tube Segment"),
inventory_image = "pipeworks_tag_tube_inv.png",
noctr = { "pipeworks_tag_tube_noctr_1.png", "pipeworks_tag_tube_noctr_2.png", "pipeworks_tag_tube_noctr_3.png",
"pipeworks_tag_tube_noctr_4.png", "pipeworks_tag_tube_noctr_5.png", "pipeworks_tag_tube_noctr_6.png" },
plain = { "pipeworks_tag_tube_plain_1.png", "pipeworks_tag_tube_plain_2.png", "pipeworks_tag_tube_plain_3.png",
"pipeworks_tag_tube_plain_4.png", "pipeworks_tag_tube_plain_5.png", "pipeworks_tag_tube_plain_6.png" },
ends = { "pipeworks_tag_tube_end.png" },
short = "pipeworks_tag_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, tags)
local tbl, tbln = {}, 0
local found, foundn = {}, 0
local meta = minetest.get_meta(pos)
local tag_hash = {}
if #tags > 0 then
for _,tag in ipairs(tags) do
tag_hash[tag] = true
end
else
tag_hash["<none>"] = true -- Matches items without tags
end
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 side_tags = meta:get_string("tags" .. i)
if side_tags ~= "" then
side_tags = pipeworks.sanitize_tags(side_tags)
for _,tag in ipairs(side_tags) do
if tag_hash[tag] then
foundn = foundn + 1
found[foundn] = vect
break
end
end
else
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)
for i = 1, 6 do
meta:set_int("l" .. tostring(i) .. "s", 1)
end
update_formspec(pos)
meta:set_string("infotext", S("Tag 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_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
local meta = minetest.get_meta(pos)
for i = 1, 6 do
local field_name = "tags" .. tostring(i)
if fields[field_name] then
local tags = pipeworks.sanitize_tags(fields[field_name])
meta:set_string(field_name, table.concat(tags, ","))
end
end
fs_helpers.on_receive_fields(pos, fields)
update_formspec(pos)
end,
can_dig = function(pos, player)
return true
end,
},
})

View File

@ -357,6 +357,7 @@ pipeworks.tptube = {
hash = hash_pos, hash = hash_pos,
get_db = function() return tube_db end, get_db = function() return tube_db end,
save_tube_db = save_tube_db, save_tube_db = save_tube_db,
remove_tube = remove_tube,
set_tube = set_tube, set_tube = set_tube,
save_tube = save_tube, save_tube = save_tube,
update_tube = update_tube, update_tube = update_tube,

View File

@ -195,7 +195,7 @@ local function register_wielder(data)
return stack:get_count() return stack:get_count()
end, end,
}, },
is_ground_content = true, is_ground_content = false,
paramtype2 = "facedir", paramtype2 = "facedir",
tubelike = 1, tubelike = 1,
groups = groups, groups = groups,