forked from mtcontrib/pipeworks
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
02322855d5
@ -275,7 +275,8 @@ minetest.register_node("pipeworks:autocrafter", {
|
||||
description = S("Autocrafter"),
|
||||
drawtype = "normal",
|
||||
tiles = {"pipeworks_autocrafter.png"},
|
||||
groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1, dig_generic = 1},
|
||||
groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1, dig_generic = 1, axey=5},
|
||||
_mcl_hardness=1.6,
|
||||
tube = {insert_object = function(pos, node, stack, direction)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
|
@ -149,7 +149,8 @@ function fs_helpers.get_inv(y)
|
||||
local inv_x = i3.settings.legacy_inventory and 0.75 or 0.22
|
||||
local inv_y = (y + 0.4) or 6.9
|
||||
local size, spacing = 1, 0.1
|
||||
local hotbar_len = i3.settings.hotbar_len
|
||||
local hotbar_len = i3.settings.hotbar_len or (i3.settings.legacy_inventory and 8 or 9)
|
||||
local inv_size = i3.settings.inv_size or (hotbar_len * 4)
|
||||
|
||||
table.insert(fs, "style_type[box;colors=#77777710,#77777710,#777,#777]")
|
||||
|
||||
@ -162,13 +163,13 @@ function fs_helpers.get_inv(y)
|
||||
|
||||
table.insert(fs, "style_type[box;colors=#666]")
|
||||
for i=0, 2 do
|
||||
for j=0, (i3.settings.legacy_inventory and 7 or 8) do
|
||||
for j=0, hotbar_len - 1 do
|
||||
table.insert(fs, "box["..0.2+(j*0.1)+(j*size)..","..(inv_y+size+spacing+0.05)+(i*0.1)+(i*size)..";"..size..","..size..";]")
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(fs, "style_type[list;size="..size..";spacing="..spacing.."]")
|
||||
table.insert(fs, "list[current_player;main;"..inv_x..","..(inv_y + 1.15)..";"..hotbar_len..","..(i3.settings.inv_size / hotbar_len)..";"..hotbar_len.."]")
|
||||
table.insert(fs, "list[current_player;main;"..inv_x..","..(inv_y + 1.15)..";"..hotbar_len..","..(inv_size / hotbar_len)..";"..hotbar_len.."]")
|
||||
else
|
||||
table.insert(fs, "list[current_player;main;0.22,"..y..";8,4;]")
|
||||
end
|
||||
|
18
crafts.lua
18
crafts.lua
@ -298,6 +298,24 @@ if pipeworks.enable_mese_tube then
|
||||
})
|
||||
end
|
||||
|
||||
if pipeworks.enable_sand_tube then
|
||||
minetest.register_craft( {
|
||||
output = "pipeworks:sand_tube_1 2",
|
||||
recipe = {
|
||||
{"basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet"},
|
||||
{"group:sand", "group:sand", "group:sand"},
|
||||
{"basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet"}
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft( {
|
||||
output = "pipeworks:sand_tube_1",
|
||||
recipe = {
|
||||
{"group:sand", "pipeworks:tube_1", "group:sand"},
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
if pipeworks.enable_mese_sand_tube then
|
||||
minetest.register_craft( {
|
||||
output = "pipeworks:mese_sand_tube_1 2",
|
||||
|
@ -14,7 +14,8 @@ minetest.register_node("pipeworks:steel_block_embedded_tube", {
|
||||
},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=1, oddly_breakable_by_hand = 1, tubedevice = 1, dig_glass = 2},
|
||||
groups = {cracky=1, oddly_breakable_by_hand = 1, tubedevice = 1, dig_glass = 2, pickaxey=5},
|
||||
_mcl_hardness=1.6,
|
||||
legacy_facedir_simple = true,
|
||||
_sound_def = {
|
||||
key = "node_sound_stone_defaults",
|
||||
@ -62,7 +63,8 @@ minetest.register_node("pipeworks:steel_pane_embedded_tube", {
|
||||
collision_box = pane_box,
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=1, oddly_breakable_by_hand = 1, tubedevice = 1, dig_glass = 2},
|
||||
groups = {cracky=1, oddly_breakable_by_hand = 1, tubedevice = 1, dig_glass = 2, pickaxey=5},
|
||||
_mcl_hardness=1.6,
|
||||
legacy_facedir_simple = true,
|
||||
_sound_def = {
|
||||
key = "node_sound_stone_defaults",
|
||||
|
52
devices.lua
52
devices.lua
@ -35,7 +35,7 @@ function pipeworks.rotate_on_place(itemstack, placer, pointed_thing)
|
||||
|
||||
else
|
||||
|
||||
local pitch = placer:get_look_pitch()
|
||||
local pitch = -placer:get_look_vertical()
|
||||
local above = pointed_thing.above
|
||||
local under = pointed_thing.under
|
||||
local fdir = minetest.dir_to_facedir(placer:get_look_dir())
|
||||
@ -133,9 +133,9 @@ for s in ipairs(states) do
|
||||
|
||||
local dgroups
|
||||
if states[s] == "off" then
|
||||
dgroups = {snappy=3, pipe=1, dig_generic = 4}
|
||||
dgroups = {snappy=3, pipe=1, dig_generic = 4, axey=5}
|
||||
else
|
||||
dgroups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4}
|
||||
dgroups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4, axey=5}
|
||||
end
|
||||
|
||||
local pumpname = "pipeworks:pump_"..states[s]
|
||||
@ -148,6 +148,7 @@ for s in ipairs(states) do
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = dgroups,
|
||||
_mcl_hardness=1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_metal_defaults",
|
||||
},
|
||||
@ -202,6 +203,7 @@ for s in ipairs(states) do
|
||||
fixed = { -5/16, -4/16, -8/16, 5/16, 5/16, 8/16 }
|
||||
},
|
||||
groups = dgroups,
|
||||
_mcl_hardness = 1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_metal_defaults",
|
||||
},
|
||||
@ -251,7 +253,8 @@ minetest.register_node(nodename_valve_loaded, {
|
||||
type = "fixed",
|
||||
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},
|
||||
groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4, axey=5},
|
||||
_mcl_hardness=1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_metal_defaults",
|
||||
},
|
||||
@ -303,7 +306,8 @@ minetest.register_node("pipeworks:grating", {
|
||||
},
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
groups = {snappy=3, pipe=1, dig_generic = 4},
|
||||
groups = {snappy=3, pipe=1, dig_generic = 4, axey=5},
|
||||
_mcl_hardness=1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_metal_defaults",
|
||||
},
|
||||
@ -330,7 +334,8 @@ minetest.register_node(nodename_spigot_empty, {
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=3, pipe=1, dig_generic = 4},
|
||||
groups = {snappy=3, pipe=1, dig_generic = 4, axey=5},
|
||||
_mcl_hardness=1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_metal_defaults",
|
||||
},
|
||||
@ -367,7 +372,8 @@ minetest.register_node(nodename_spigot_loaded, {
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4},
|
||||
groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4, axey=5},
|
||||
_mcl_hardness=1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_metal_defaults",
|
||||
},
|
||||
@ -425,7 +431,8 @@ minetest.register_node(nodename_panel_empty, {
|
||||
tiles = { "pipeworks_entry_panel.png" },
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=3, pipe=1, dig_generic = 4},
|
||||
groups = {snappy=3, pipe=1, dig_generic = 4, axey=5},
|
||||
_mcl_hardness=1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_metal_defaults",
|
||||
},
|
||||
@ -447,7 +454,8 @@ minetest.register_node(nodename_panel_loaded, {
|
||||
tiles = { "pipeworks_entry_panel.png" },
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4},
|
||||
groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4, axey=5},
|
||||
_mcl_hardness=1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_metal_defaults",
|
||||
},
|
||||
@ -479,7 +487,8 @@ minetest.register_node(nodename_sensor_empty, {
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=3, pipe=1, dig_generic = 4},
|
||||
groups = {snappy=3, pipe=1, dig_generic = 4, axey=5},
|
||||
_mcl_hardness=1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_metal_defaults",
|
||||
},
|
||||
@ -520,7 +529,8 @@ minetest.register_node(nodename_sensor_loaded, {
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4},
|
||||
groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4, axey=5},
|
||||
_mcl_hardness=1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_metal_defaults",
|
||||
},
|
||||
@ -567,12 +577,12 @@ new_flow_logic_register.transition_simple_set(sensor_pressure_set, { mesecons=pi
|
||||
-- TODO flow-logic-stub: these don't currently do anything under the new flow logic.
|
||||
for fill = 0, 10 do
|
||||
local filldesc=S("empty")
|
||||
local sgroups = {snappy=3, pipe=1, tankfill=fill+1, dig_generic = 4}
|
||||
local sgroups = {snappy=3, pipe=1, tankfill=fill+1, dig_generic = 4, axey=5}
|
||||
local image = nil
|
||||
|
||||
if fill ~= 0 then
|
||||
filldesc=S("@1% full", 10*fill)
|
||||
sgroups = {snappy=3, pipe=1, tankfill=fill+1, not_in_creative_inventory=1, dig_generic = 4}
|
||||
sgroups = {snappy=3, pipe=1, tankfill=fill+1, not_in_creative_inventory=1, dig_generic = 4, axey=5}
|
||||
image = "pipeworks_storage_tank_fittings.png"
|
||||
end
|
||||
|
||||
@ -589,7 +599,8 @@ for fill = 0, 10 do
|
||||
inventory_image = image,
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=3, pipe=1, tankfill=fill+1, not_in_creative_inventory=1, dig_generic = 4},
|
||||
groups = {snappy=3, pipe=1, tankfill=fill+1, not_in_creative_inventory=1, dig_generic = 4, axey=5},
|
||||
_mcl_hardness=1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_metal_defaults",
|
||||
},
|
||||
@ -620,6 +631,7 @@ for fill = 0, 10 do
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = sgroups,
|
||||
_mcl_hardness=1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_metal_defaults",
|
||||
},
|
||||
@ -648,7 +660,8 @@ minetest.register_node(nodename_fountain_empty, {
|
||||
tiles = { "pipeworks_fountainhead.png" },
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
groups = {snappy=3, pipe=1, dig_generic = 4},
|
||||
groups = {snappy=3, pipe=1, dig_generic = 4, axey=5},
|
||||
_mcl_hardness=1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_metal_defaults",
|
||||
},
|
||||
@ -685,7 +698,8 @@ minetest.register_node(nodename_fountain_loaded, {
|
||||
tiles = { "pipeworks_fountainhead.png" },
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4},
|
||||
groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4, axey=5},
|
||||
_mcl_hardness=1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_metal_defaults",
|
||||
},
|
||||
@ -737,7 +751,8 @@ minetest.register_node(nodename_sp_empty, {
|
||||
tiles = { "pipeworks_straight_pipe_empty.png" },
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=3, pipe=1, dig_generic = 4},
|
||||
groups = {snappy=3, pipe=1, dig_generic = 4, axey=5},
|
||||
_mcl_hardness=1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_metal_defaults",
|
||||
},
|
||||
@ -761,7 +776,8 @@ minetest.register_node(nodename_sp_loaded, {
|
||||
tiles = { "pipeworks_straight_pipe_loaded.png" },
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4},
|
||||
groups = {snappy=3, pipe=1, not_in_creative_inventory=1, dig_generic = 4, axey=5},
|
||||
_mcl_hardness=1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_metal_defaults",
|
||||
},
|
||||
|
@ -388,7 +388,8 @@ for _, data in ipairs({
|
||||
"pipeworks_"..data.name.."_top.png",
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, mesecon = 2},
|
||||
groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, mesecon = 2, axey=5},
|
||||
_mcl_hardness=1.6,
|
||||
legacy_facedir_simple = true,
|
||||
_sound_def = {
|
||||
key = "node_sound_wood_defaults",
|
||||
|
23
init.lua
23
init.lua
@ -153,7 +153,6 @@ dofile(pipeworks.modpath.."/flowing_logic.lua")
|
||||
dofile(pipeworks.modpath.."/tube_registration.lua")
|
||||
dofile(pipeworks.modpath.."/routing_tubes.lua")
|
||||
dofile(pipeworks.modpath.."/sorting_tubes.lua")
|
||||
dofile(pipeworks.modpath.."/vacuum_tubes.lua")
|
||||
dofile(pipeworks.modpath.."/signal_tubes.lua")
|
||||
dofile(pipeworks.modpath.."/decorative_tubes.lua")
|
||||
dofile(pipeworks.modpath.."/filter-injector.lua")
|
||||
@ -170,18 +169,28 @@ dofile(pipeworks.modpath..logicdir.."abms.lua")
|
||||
dofile(pipeworks.modpath..logicdir.."abm_register.lua")
|
||||
dofile(pipeworks.modpath..logicdir.."flowable_node_registry_install.lua")
|
||||
|
||||
if pipeworks.enable_pipes then dofile(pipeworks.modpath.."/pipes.lua") end
|
||||
if pipeworks.enable_teleport_tube then dofile(pipeworks.modpath.."/teleport_tube.lua") end
|
||||
if pipeworks.enable_pipe_devices then dofile(pipeworks.modpath.."/devices.lua") end
|
||||
if pipeworks.enable_pipes then
|
||||
dofile(pipeworks.modpath.."/pipes.lua")
|
||||
end
|
||||
if pipeworks.enable_teleport_tube then
|
||||
dofile(pipeworks.modpath.."/teleport_tube.lua")
|
||||
end
|
||||
if pipeworks.enable_pipe_devices then
|
||||
dofile(pipeworks.modpath.."/devices.lua")
|
||||
end
|
||||
if pipeworks.enable_redefines and (minetest.get_modpath("default") or minetest.get_modpath("hades_core")) then
|
||||
dofile(pipeworks.modpath.."/compat-chests.lua")
|
||||
dofile(pipeworks.modpath.."/compat-furnaces.lua")
|
||||
end
|
||||
if pipeworks.enable_autocrafter then dofile(pipeworks.modpath.."/autocrafter.lua") end
|
||||
if pipeworks.enable_lua_tube and
|
||||
(minetest.get_modpath("mesecons") or minetest.get_modpath("digilines")) then
|
||||
if pipeworks.enable_autocrafter then
|
||||
dofile(pipeworks.modpath.."/autocrafter.lua")
|
||||
end
|
||||
if pipeworks.enable_lua_tube and minetest.get_modpath("mesecons") then
|
||||
dofile(pipeworks.modpath.."/lua_tube.lua")
|
||||
end
|
||||
if pipeworks.enable_sand_tube or pipeworks.enable_mese_sand_tube then
|
||||
dofile(pipeworks.modpath.."/vacuum_tubes.lua")
|
||||
end
|
||||
|
||||
dofile(pipeworks.modpath.."/crafts.lua")
|
||||
|
||||
|
@ -26,7 +26,8 @@ if not minetest.get_modpath("auto_tree_tap") and
|
||||
"pipeworks_nodebreaker_back.png","pipeworks_nodebreaker_front_off.png"},
|
||||
is_ground_content = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2, mesecon = 2,tubedevice=1, not_in_creative_inventory=1 },
|
||||
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2, mesecon = 2,tubedevice=1, not_in_creative_inventory=1, axey=5},
|
||||
_mcl_hardness=1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_stone_defaults",
|
||||
},
|
||||
|
@ -865,7 +865,7 @@ for white = 0, 1 do
|
||||
tiles[3] = tiles[3]..tiles_on_off.R270:format(white == 1 and "on" or "off");
|
||||
tiles[4] = tiles[4]..tiles_on_off.R_90:format(white == 1 and "on" or "off");
|
||||
|
||||
local groups = {snappy = 3, tube = 1, tubedevice = 1, overheat = 1, dig_generic = 4}
|
||||
local groups = {snappy = 3, tube = 1, tubedevice = 1, overheat = 1, dig_generic = 4, axey=5}
|
||||
if red + blue + yellow + green + black + white ~= 0 then
|
||||
groups.not_in_creative_inventory = 1
|
||||
end
|
||||
@ -912,6 +912,7 @@ for white = 0, 1 do
|
||||
paramtype = "light",
|
||||
is_ground_content = false,
|
||||
groups = groups,
|
||||
_mcl_hardness=1.6,
|
||||
drop = BASENAME.."000000",
|
||||
sunlight_propagates = true,
|
||||
selection_box = selection_box,
|
||||
@ -1023,7 +1024,8 @@ minetest.register_node(BASENAME .. "_burnt", {
|
||||
is_burnt = true,
|
||||
paramtype = "light",
|
||||
is_ground_content = false,
|
||||
groups = {snappy = 3, tube = 1, tubedevice = 1, not_in_creative_inventory=1, dig_generic = 4},
|
||||
groups = {snappy = 3, tube = 1, tubedevice = 1, not_in_creative_inventory=1, dig_generic = 4, axey=5},
|
||||
_mcl_hardness=1.6,
|
||||
drop = BASENAME.."000000",
|
||||
sunlight_propagates = true,
|
||||
selection_box = selection_box,
|
||||
|
4
mod.conf
4
mod.conf
@ -1,5 +1,5 @@
|
||||
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.
|
||||
depends = basic_materials
|
||||
optional_depends = mesecons, mesecons_mvps, digilines, signs_lib, unified_inventory, default, screwdriver, fl_mapgen, sound_api, i3, hades_core, hades_furnaces, hades_chests
|
||||
min_minetest_version = 5.2.0
|
||||
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
|
||||
min_minetest_version = 5.4.0
|
||||
|
@ -37,11 +37,11 @@ for index, connects in ipairs(cconnects) do
|
||||
end
|
||||
--]]
|
||||
|
||||
local pgroups = {snappy = 3, pipe = 1, not_in_creative_inventory = 1, dig_generic = 4}
|
||||
local pgroups = {snappy = 3, pipe = 1, not_in_creative_inventory = 1, dig_generic = 4, axey=5}
|
||||
local pipedesc = S("Pipe Segment").." "..dump(connects)
|
||||
|
||||
if #connects == 0 then
|
||||
pgroups = {snappy = 3, tube = 1, dig_generic = 4}
|
||||
pgroups = {snappy = 3, tube = 1, dig_generic = 4, axey=5}
|
||||
pipedesc = S("Pipe Segment")
|
||||
end
|
||||
|
||||
@ -76,6 +76,7 @@ for index, connects in ipairs(cconnects) do
|
||||
fixed = outsel
|
||||
},
|
||||
groups = pgroups,
|
||||
_mcl_hardness=1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_metal_defaults",
|
||||
},
|
||||
@ -93,7 +94,7 @@ for index, connects in ipairs(cconnects) do
|
||||
pipenumber = index
|
||||
})
|
||||
|
||||
local pgroups = {snappy = 3, pipe = 1, not_in_creative_inventory = 1, dig_generic = 4}
|
||||
local pgroups = {snappy = 3, pipe = 1, not_in_creative_inventory = 1, dig_generic = 4, axey=5}
|
||||
|
||||
minetest.register_node("pipeworks:pipe_"..index.."_loaded", {
|
||||
description = pipedesc,
|
||||
@ -112,6 +113,7 @@ for index, connects in ipairs(cconnects) do
|
||||
fixed = outsel
|
||||
},
|
||||
groups = pgroups,
|
||||
_mcl_hardness = 1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_metal_defaults",
|
||||
},
|
||||
|
@ -168,7 +168,8 @@ if pipeworks.enable_one_way_tube then
|
||||
paramtype = "light",
|
||||
node_box = {type = "fixed",
|
||||
fixed = {{-1/2, -9/64, -9/64, 1/2, 9/64, 9/64}}},
|
||||
groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, tubedevice = 1},
|
||||
groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, tubedevice = 1, axey=5},
|
||||
_mcl_hardness=1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_wood_defaults",
|
||||
},
|
||||
|
@ -84,3 +84,6 @@ pipeworks_use_real_entities (Use Real Entities) bool true
|
||||
#A high value may cause issues with tube entity visuals.
|
||||
#A value 0.2 or above may cause issues with accelerator tubes.
|
||||
pipeworks_entity_update_interval (Entity Update Interval) float 0 0 0.8
|
||||
|
||||
# if set to true, items passing through teleport tubes will log log where they came from and where they went.
|
||||
pipeworks_log_teleport_tubes (Log Teleport Tubes) bool false
|
||||
|
@ -12,7 +12,7 @@ local function after_break(pos)
|
||||
end
|
||||
|
||||
if minetest.get_modpath("mesecons") and pipeworks.enable_detector_tube then
|
||||
local detector_tube_step = 5 * tonumber(minetest.settings:get("dedicated_server_step"))
|
||||
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",
|
||||
|
@ -1,190 +1,330 @@
|
||||
|
||||
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 filename = minetest.get_worldpath().."/teleport_tubes" -- Only used for backward-compat
|
||||
local storage = minetest.get_mod_storage()
|
||||
|
||||
local tp_tube_db = nil -- nil forces a read
|
||||
local tp_tube_db_version = 3.0
|
||||
local enable_logging = minetest.settings:get_bool("pipeworks_log_teleport_tubes", false)
|
||||
|
||||
-- cached rceiver list: hash(pos) => {receivers}
|
||||
local cache = {}
|
||||
local has_digilines = minetest.get_modpath("digilines")
|
||||
|
||||
local function hash(pos)
|
||||
return string.format("%.30g", minetest.hash_node_position(pos))
|
||||
-- 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()
|
||||
-- reset tp-tube cache
|
||||
cache = {}
|
||||
|
||||
local fields = {version = tp_tube_db_version}
|
||||
for key, val in pairs(tp_tube_db) do
|
||||
fields[key] = minetest.serialize(val)
|
||||
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_db_entry(hash)
|
||||
-- reset tp-tube cache
|
||||
cache = {}
|
||||
local function save_tube(hash)
|
||||
local tube = tube_db[hash]
|
||||
receiver_cache[tube.channel] = nil
|
||||
storage:set_string(hash, serialize_tube(tube))
|
||||
end
|
||||
|
||||
local val = tp_tube_db[hash]
|
||||
storage:set_string(hash, val and minetest.serialize(val) or "")
|
||||
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()
|
||||
local old_version = tp_tube_db.version or 0
|
||||
tp_tube_db.version = nil
|
||||
if old_version < 2.0 then
|
||||
local tmp_db = {}
|
||||
for _, val in pairs(tp_tube_db) do
|
||||
if(val.channel ~= "") then -- skip unconfigured tubes
|
||||
tmp_db[hash(val)] = val
|
||||
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
|
||||
tp_tube_db = tmp_db
|
||||
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 file = not storage:contains("version") and io.open(filename, "r")
|
||||
if not file then
|
||||
tp_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
|
||||
tp_tube_db[key] = minetest.deserialize(val)
|
||||
elseif key == "version" then
|
||||
tp_tube_db.version = tonumber(val)
|
||||
else
|
||||
error("Unknown field in teleport tube DB: " .. key)
|
||||
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
|
||||
|
||||
if tp_tube_db.version == nil then
|
||||
tp_tube_db.version = tp_tube_db_version
|
||||
storage:set_string("version", tp_tube_db.version)
|
||||
elseif tp_tube_db.version > tp_tube_db_version then
|
||||
error("Cannot read teleport tube DB of version " .. tp_tube_db.version)
|
||||
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
|
||||
local file_content = file:read("*all")
|
||||
io.close(file)
|
||||
|
||||
pipeworks.logger("Moving teleport tube DB into mod storage from " .. filename)
|
||||
|
||||
if file_content and file_content ~= "" then
|
||||
tp_tube_db = minetest.deserialize(file_content)
|
||||
else
|
||||
tp_tube_db = {version = 2.0}
|
||||
end
|
||||
tube_db[hash] = {x = pos.x, y = pos.y, z = pos.z, channel = channel, cr = cr}
|
||||
save_tube(hash)
|
||||
end
|
||||
|
||||
if(not tp_tube_db.version or tonumber(tp_tube_db.version) < tp_tube_db_version) then
|
||||
migrate_tube_db()
|
||||
end
|
||||
tp_tube_db.version = nil
|
||||
|
||||
return tp_tube_db
|
||||
end
|
||||
|
||||
-- debug formatter for coordinates used below
|
||||
local fmt = function(pos)
|
||||
return pos.x..", "..pos.y..", "..pos.z
|
||||
end
|
||||
|
||||
-- updates or adds a tube
|
||||
local function set_tube(pos, channel, can_receive)
|
||||
local tubes = tp_tube_db or read_tube_db()
|
||||
local hash = hash(pos)
|
||||
local tube = tubes[hash]
|
||||
if tube then
|
||||
tube.channel = channel
|
||||
tube.cr = can_receive
|
||||
save_tube_db_entry(hash)
|
||||
return
|
||||
end
|
||||
|
||||
-- we haven't found any tp tube to update, so lets add it
|
||||
-- but sanity check that the hash has not already been inserted.
|
||||
-- if so, complain very loudly and refuse the update so the player knows something is amiss.
|
||||
-- to catch regressions of https://github.com/minetest-mods/pipeworks/issues/166
|
||||
local existing = tp_tube_db[hash]
|
||||
if existing ~= nil then
|
||||
local e = "error"
|
||||
minetest.log(e, "pipeworks teleport tube update refused due to position hash collision")
|
||||
minetest.log(e, "collided hash: "..hash)
|
||||
minetest.log(e, "tried-to-place tube: "..fmt(pos))
|
||||
minetest.log(e, "existing tube: "..fmt(existing))
|
||||
return
|
||||
end
|
||||
|
||||
tp_tube_db[hash] = {x=pos.x,y=pos.y,z=pos.z,channel=channel,cr=can_receive}
|
||||
save_tube_db_entry(hash)
|
||||
end
|
||||
|
||||
local function remove_tube(pos)
|
||||
local tubes = tp_tube_db or read_tube_db()
|
||||
local hash = hash(pos)
|
||||
tubes[hash] = nil
|
||||
save_tube_db_entry(hash)
|
||||
end
|
||||
|
||||
local function read_node_with_vm(pos)
|
||||
local vm = VoxelManip()
|
||||
local MinEdge, MaxEdge = vm:read_from_map(pos, pos)
|
||||
local data = vm:get_data()
|
||||
local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge})
|
||||
return minetest.get_name_from_content_id(data[area:index(pos.x, pos.y, pos.z)])
|
||||
end
|
||||
|
||||
local function get_receivers(pos, channel)
|
||||
local hash = minetest.hash_node_position(pos)
|
||||
local hash = hash_pos(pos)
|
||||
local cache = receiver_cache[channel] or {}
|
||||
if cache[hash] then
|
||||
-- re-use cached result
|
||||
return cache[hash]
|
||||
end
|
||||
|
||||
local tubes = tp_tube_db or read_tube_db()
|
||||
local receivers = {}
|
||||
for key, val in pairs(tubes) do
|
||||
-- skip all non-receivers and the tube that it came from as early as possible, as this is called often
|
||||
if (val.cr == 1 and val.channel == channel and (val.x ~= pos.x or val.y ~= pos.y or val.z ~= pos.z)) then
|
||||
local is_loaded = (minetest.get_node_or_nil(val) ~= nil)
|
||||
local node_name = is_loaded and minetest.get_node(pos).name or read_node_with_vm(val)
|
||||
|
||||
if minetest.registered_nodes[node_name] and minetest.registered_nodes[node_name].is_teleport_tube then
|
||||
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
|
||||
tp_tube_db[key] = nil
|
||||
save_tube_db_entry(key)
|
||||
remove_tube(val)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- cache the result for next time
|
||||
cache[hash] = receivers
|
||||
receiver_cache[channel] = cache
|
||||
return receivers
|
||||
end
|
||||
|
||||
local function update_meta(meta, can_receive)
|
||||
meta:set_int("can_receive", can_receive and 1 or 0)
|
||||
local cr_state = can_receive and "on" or "off"
|
||||
local itext = 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 = "8.5,4"
|
||||
meta:set_string("formspec",
|
||||
"formspec_version[2]"..
|
||||
"size["..size.."]"..
|
||||
pipeworks.fs_helpers.get_prepends(size) ..
|
||||
"image[0.5,o;1,1;pipeworks_teleport_tube_inv.png]"..
|
||||
"label[1.5,0.5;"..S("Teleporting Tube").."]"..
|
||||
"field[0.5,1.6;4.3,0.75;channel;"..S("Channel")..";${channel}]"..
|
||||
"button[4.8,1.6;1.5,0.75;set_channel;"..S("Set").."]"..
|
||||
"label[7.0,0.5;"..S("Receive").."]"..
|
||||
"image_button[7.0,0.75;1,0.6;pipeworks_button_" .. cr_state .. ".png;cr" .. (can_receive and 0 or 1) .. ";;;false;pipeworks_button_interm.png]"..
|
||||
"button_exit[6.3,1.6;2,0.75;close;"..S("Close").."]"..
|
||||
"label[0.5,2.7;"..itext.."]")
|
||||
local help_text = 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", {
|
||||
@ -194,120 +334,14 @@ pipeworks.register_tube("pipeworks:teleport_tube", {
|
||||
plain = { "pipeworks_teleport_tube_plain.png" },
|
||||
ends = { "pipeworks_teleport_tube_end.png" },
|
||||
short = "pipeworks_teleport_tube_short.png",
|
||||
node_def = {
|
||||
is_teleport_tube = true,
|
||||
tube = {
|
||||
can_go = function(pos,node,velocity,stack)
|
||||
velocity.x = 0
|
||||
velocity.y = 0
|
||||
velocity.z = 0
|
||||
|
||||
local channel = minetest.get_meta(pos):get_string("channel")
|
||||
if channel == "" then return {} end
|
||||
|
||||
local target = get_receivers(pos, channel)
|
||||
if target[1] == nil then return {} end
|
||||
|
||||
local d = math.random(1,#target)
|
||||
pos.x = target[d].x
|
||||
pos.y = target[d].y
|
||||
pos.z = target[d].z
|
||||
return pipeworks.meseadjlist
|
||||
end,
|
||||
on_repair = function(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local channel = meta:get_string("channel")
|
||||
minetest.swap_node(pos, { name = node.name, param2 = node.param2 })
|
||||
pipeworks.scan_for_tube_objects(pos)
|
||||
if channel ~= "" then
|
||||
local can_receive = meta:get_int("can_receive")
|
||||
set_tube(pos, channel, can_receive)
|
||||
local cr_description = (can_receive == 1) and "sending and receiving" or "sending"
|
||||
meta:set_string("infotext", S("Teleportation Tube @1 on '@2'", cr_description, channel))
|
||||
end
|
||||
end
|
||||
},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
update_meta(meta, true)
|
||||
meta:set_string("infotext", S("Unconfigured Teleportation Tube"))
|
||||
end,
|
||||
on_receive_fields = function(pos,formname,fields,sender)
|
||||
if not fields.channel -- ignore escaping or clientside manipulation of the form
|
||||
or (fields.quit and not fields.key_enter_field)
|
||||
or not pipeworks.may_configure(pos, sender) then
|
||||
return
|
||||
end
|
||||
local new_channel = tostring(fields.channel):trim()
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
local can_receive = meta:get_int("can_receive")
|
||||
|
||||
-- check for private channels each time before actually changing anything
|
||||
-- to not even allow switching between can_receive states of private channels
|
||||
if new_channel ~= "" then
|
||||
local sender_name = sender:get_player_name()
|
||||
local name, mode = new_channel:match("^([^:;]+)([:;])")
|
||||
if name and mode and name ~= sender_name then
|
||||
--channels starting with '[name]:' can only be used by the named player
|
||||
if mode == ":" then
|
||||
minetest.chat_send_player(sender_name, S("Sorry, channel '@1' is reserved for exclusive use by @2",
|
||||
new_channel, name))
|
||||
return
|
||||
|
||||
--channels starting with '[name];' can be used by other players, but cannot be received from
|
||||
elseif mode == ";" and (fields.cr1 or (can_receive ~= 0 and not fields.cr0)) then
|
||||
minetest.chat_send_player(sender_name, S("Sorry, receiving from channel '@1' is reserved for @2",
|
||||
new_channel, name))
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local dirty = false
|
||||
|
||||
-- was the channel changed?
|
||||
local channel = meta:get_string("channel")
|
||||
if new_channel ~= channel and (fields.key_enter_field == "channel" or fields.set_channel) then
|
||||
channel = new_channel
|
||||
meta:set_string("channel", channel)
|
||||
dirty = true
|
||||
end
|
||||
|
||||
-- test if a can_receive button was pressed
|
||||
if fields.cr0 and can_receive ~= 0 then
|
||||
can_receive = 0
|
||||
update_meta(meta, false)
|
||||
dirty = true
|
||||
elseif fields.cr1 and can_receive ~= 1 then
|
||||
can_receive = 1
|
||||
update_meta(meta, true)
|
||||
dirty = true
|
||||
end
|
||||
|
||||
-- save if we changed something, handle the empty channel while we're at it
|
||||
if dirty then
|
||||
if channel ~= "" then
|
||||
set_tube(pos, channel, can_receive)
|
||||
local cr_description = (can_receive == 1) and "sending and receiving" or "sending"
|
||||
meta:set_string("infotext", S("Teleportation Tube @1 on '@2'", cr_description, channel))
|
||||
else
|
||||
-- remove empty channel tubes, to not have to search through them
|
||||
remove_tube(pos)
|
||||
meta:set_string("infotext", S("Unconfigured Teleportation Tube"))
|
||||
end
|
||||
end
|
||||
end,
|
||||
on_destruct = function(pos)
|
||||
remove_tube(pos)
|
||||
end
|
||||
},
|
||||
node_def = def,
|
||||
})
|
||||
|
||||
if minetest.get_modpath("mesecons_mvps") ~= nil then
|
||||
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 string.find(n.node.name, "pipeworks:teleport_tube") ~= nil then
|
||||
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
|
||||
@ -317,11 +351,21 @@ end
|
||||
|
||||
-- Expose teleport tube database API for other mods
|
||||
pipeworks.tptube = {
|
||||
hash = hash,
|
||||
version = tube_db_version,
|
||||
hash = hash_pos,
|
||||
get_db = function() return tube_db end,
|
||||
save_tube_db = save_tube_db,
|
||||
save_tube_db_entry = save_tube_db_entry,
|
||||
get_db = function() return tp_tube_db or read_tube_db() end,
|
||||
set_tube = set_tube,
|
||||
update_meta = update_meta,
|
||||
tp_tube_db_version = tp_tube_db_version
|
||||
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()
|
||||
|
@ -10,7 +10,8 @@ minetest.register_node("pipeworks:trashcan", {
|
||||
"pipeworks_trashcan_side.png",
|
||||
"pipeworks_trashcan_side.png",
|
||||
},
|
||||
groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1, dig_generic = 4},
|
||||
groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1, dig_generic = 4, axey=5},
|
||||
_mcl_hardness=1.6,
|
||||
tube = {
|
||||
insert_object = function(pos, node, stack, direction)
|
||||
return ItemStack("")
|
||||
|
@ -61,13 +61,13 @@ local register_one_tube = function(name, tname, dropname, desc, plain, noctrs, e
|
||||
outimgs[vti[v]] = ends[v]
|
||||
end
|
||||
|
||||
local tgroups = {snappy = 3, tube = 1, tubedevice = 1, not_in_creative_inventory = 1, dig_generic = 4}
|
||||
local tgroups = {snappy = 3, tube = 1, tubedevice = 1, not_in_creative_inventory = 1, dig_generic = 4, axey=5}
|
||||
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}
|
||||
tgroups = {snappy = 3, tube = 1, tubedevice = 1, dig_generic = 4, axey=5}
|
||||
tubedesc = desc
|
||||
iimg=inv
|
||||
outimgs = {
|
||||
@ -106,6 +106,7 @@ local register_one_tube = function(name, tname, dropname, desc, plain, noctrs, e
|
||||
fixed = outboxes
|
||||
},
|
||||
groups = tgroups,
|
||||
_mcl_hardness=1.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_wood_defaults",
|
||||
},
|
||||
|
173
vacuum_tubes.lua
173
vacuum_tubes.lua
@ -1,4 +1,37 @@
|
||||
|
||||
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"),
|
||||
@ -6,102 +39,64 @@ if pipeworks.enable_sand_tube then
|
||||
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}},
|
||||
})
|
||||
|
||||
minetest.register_craft( {
|
||||
output = "pipeworks:sand_tube_1 2",
|
||||
recipe = {
|
||||
{"basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet"},
|
||||
{"group:sand", "group:sand", "group:sand"},
|
||||
{"basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet"}
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft( {
|
||||
output = "pipeworks:sand_tube_1",
|
||||
recipe = {
|
||||
{"group:sand", "pipeworks:tube_1", "group:sand"},
|
||||
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
|
||||
pipeworks.register_tube("pipeworks:mese_sand_tube", {
|
||||
description = S("Adjustable Vacuuming Pneumatic Tube Segment"),
|
||||
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)
|
||||
local size = "6.0,2.4"
|
||||
meta:set_int("dist", 0)
|
||||
meta:set_string("formspec",
|
||||
"size["..size.."]"..
|
||||
pipeworks.fs_helpers.get_prepends(size) ..
|
||||
"image[0.2,0;1,1;pipeworks_mese_sand_tube_inv.png]"..
|
||||
"label[1.2,0.2;"..S("Adjustable Vacuuming Tube").."]"..
|
||||
"field[0.5,1.6;2.1,1;dist;"..S("Radius")..";${dist}]"..
|
||||
"button[2.3,1.3;1.5,1;set_dist;"..S("Set").."]"..
|
||||
"button_exit[3.8,1.3;2,1;close;"..S("Close").."]")
|
||||
meta:set_string("infotext", S("Adjustable Vacuuming Pneumatic Tube Segment"))
|
||||
end,
|
||||
on_receive_fields = function(pos,formname,fields,sender)
|
||||
if (fields.quit and not fields.key_enter_field)
|
||||
or (fields.key_enter_field ~= "dist" and not fields.set_dist)
|
||||
or not pipeworks.may_configure(pos, sender) then
|
||||
return
|
||||
end
|
||||
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").."]"
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
local dist = tonumber(fields.dist)
|
||||
if dist then
|
||||
dist = math.max(0, dist)
|
||||
dist = math.min(8, dist)
|
||||
meta:set_int("dist", dist)
|
||||
meta:set_string("infotext", S("Adjustable Vacuuming Pneumatic Tube Segment (@1m)", dist))
|
||||
end
|
||||
end,
|
||||
},
|
||||
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
|
||||
|
||||
local function vacuum(pos, radius)
|
||||
radius = radius + 0.5
|
||||
for _, object in pairs(minetest.get_objects_inside_radius(pos, math.sqrt(3) * radius)) do
|
||||
local lua_entity = object:get_luaentity()
|
||||
if not object:is_player() and lua_entity and lua_entity.name == "__builtin:item" then
|
||||
local obj_pos = object:get_pos()
|
||||
local minpos = vector.subtract(pos, radius)
|
||||
local maxpos = vector.add(pos, radius)
|
||||
if obj_pos.x >= minpos.x and obj_pos.x <= maxpos.x
|
||||
and obj_pos.y >= minpos.y and obj_pos.y <= maxpos.y
|
||||
and obj_pos.z >= minpos.z and obj_pos.z <= maxpos.z then
|
||||
if lua_entity.itemstring ~= "" then
|
||||
pipeworks.tube_inject_item(pos, pos, vector.new(0, 0, 0), lua_entity.itemstring)
|
||||
lua_entity.itemstring = ""
|
||||
end
|
||||
object:remove()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_abm({nodenames = {"group:vacuum_tube"},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
label = "Vacuum tubes",
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
if node.name:find("pipeworks:sand_tube") then
|
||||
vacuum(pos, 2)
|
||||
else
|
||||
local radius = minetest.get_meta(pos):get_int("dist")
|
||||
vacuum(pos, radius)
|
||||
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,
|
||||
})
|
||||
|
11
wielder.lua
11
wielder.lua
@ -146,7 +146,7 @@ local function register_wielder(data)
|
||||
data.fixup_node = data.fixup_node or function (pos, node) end
|
||||
data.fixup_oldmetadata = data.fixup_oldmetadata or function (m) return m end
|
||||
for _, state in ipairs({ "off", "on" }) do
|
||||
local groups = { snappy=2, choppy=2, oddly_breakable_by_hand=2, mesecon=2, tubedevice=1, tubedevice_receiver=1 }
|
||||
local groups = { snappy=2, choppy=2, oddly_breakable_by_hand=2, mesecon=2, tubedevice=1, tubedevice_receiver=1, axey=5 }
|
||||
if state == "on" then groups.not_in_creative_inventory = 1 end
|
||||
local tile_images = {}
|
||||
for _, face in ipairs({ "top", "bottom", "side2", "side1", "back", "front" }) do
|
||||
@ -199,6 +199,7 @@ local function register_wielder(data)
|
||||
paramtype2 = "facedir",
|
||||
tubelike = 1,
|
||||
groups = groups,
|
||||
_mcl_hardness=0.6,
|
||||
_sound_def = {
|
||||
key = "node_sound_stone_defaults",
|
||||
},
|
||||
@ -336,6 +337,10 @@ if pipeworks.enable_node_breaker then
|
||||
masquerade_as_owner = true,
|
||||
sneak = false,
|
||||
act = function(virtplayer, pointed_thing)
|
||||
if minetest.is_protected(vector.add(virtplayer:get_pos(), assumed_eye_pos), virtplayer:get_player_name()) then
|
||||
return
|
||||
end
|
||||
|
||||
--local dname = "nodebreaker.act() "
|
||||
local wieldstack = virtplayer:get_wielded_item()
|
||||
local oldwieldstack = ItemStack(wieldstack)
|
||||
@ -427,6 +432,10 @@ if pipeworks.enable_deployer then
|
||||
masquerade_as_owner = true,
|
||||
sneak = false,
|
||||
act = function(virtplayer, pointed_thing)
|
||||
if minetest.is_protected(vector.add(virtplayer:get_pos(), assumed_eye_pos), virtplayer:get_player_name()) then
|
||||
return
|
||||
end
|
||||
|
||||
local wieldstack = virtplayer:get_wielded_item()
|
||||
virtplayer:set_wielded_item((minetest.registered_items[wieldstack:get_name()] or {on_place=minetest.item_place}).on_place(wieldstack, virtplayer, pointed_thing) or wieldstack)
|
||||
end,
|
||||
|
Loading…
Reference in New Issue
Block a user