Conflicts:
	mods/mesecons/mesecons/internal.lua
	mods/mesecons/mesecons/services.lua
	mods/mesecons/mesecons/util.lua
	mods/mesecons/mesecons_gates/init.lua
	mods/mesecons/mesecons_luacontroller/init.lua
	mods/mesecons/mesecons_movestones/init.lua
	mods/mesecons/mesecons_mvps/init.lua
	mods/mesecons/mesecons_pistons/init.lua
This commit is contained in:
LeMagnesium 2014-11-29 18:56:39 +01:00
commit 304080ff1d
230 changed files with 6746 additions and 136 deletions

844
mods/bobblocks/blocks.lua Normal file
View File

@ -0,0 +1,844 @@
-- BobBlocks mod by RabbiBob
-- State Changes
local update_bobblock = function (pos, node)
local nodename=""
local param2=""
--Switch Block State
if
-- Start Blocks
node.name == 'bobblocks:redblock_off' then nodename = 'bobblocks:redblock'
elseif node.name == 'bobblocks:redblock' then nodename = 'bobblocks:redblock_off'
elseif node.name == 'bobblocks:orangeblock_off' then nodename = 'bobblocks:orangeblock'
elseif node.name == 'bobblocks:orangeblock' then nodename = 'bobblocks:orangeblock_off'
elseif node.name == 'bobblocks:yellowblock_off' then nodename = 'bobblocks:yellowblock'
elseif node.name == 'bobblocks:yellowblock' then nodename = 'bobblocks:yellowblock_off'
elseif node.name == 'bobblocks:greenblock_off' then nodename = 'bobblocks:greenblock'
elseif node.name == 'bobblocks:greenblock' then nodename = 'bobblocks:greenblock_off'
elseif node.name == 'bobblocks:blueblock_off' then nodename = 'bobblocks:blueblock'
elseif node.name == 'bobblocks:blueblock' then nodename = 'bobblocks:blueblock_off'
elseif node.name == 'bobblocks:indigoblock_off' then nodename = 'bobblocks:indigoblock'
elseif node.name == 'bobblocks:indigoblock' then nodename = 'bobblocks:indigoblock_off'
elseif node.name == 'bobblocks:violetblock_off' then nodename = 'bobblocks:violetblock'
elseif node.name == 'bobblocks:violetblock' then nodename = 'bobblocks:violetblock_off'
elseif node.name == 'bobblocks:whiteblock_off' then nodename = 'bobblocks:whiteblock'
elseif node.name == 'bobblocks:whiteblock' then nodename = 'bobblocks:whiteblock_off'
-- Start Poles
elseif node.name == 'bobblocks:redpole_off' then nodename = 'bobblocks:redpole'
elseif node.name == 'bobblocks:redpole' then nodename = 'bobblocks:redpole_off'
elseif node.name == 'bobblocks:orangepole_off' then nodename = 'bobblocks:orangepole'
elseif node.name == 'bobblocks:orangepole' then nodename = 'bobblocks:orangepole_off'
elseif node.name == 'bobblocks:yellowpole_off' then nodename = 'bobblocks:yellowpole'
elseif node.name == 'bobblocks:yellowpole' then nodename = 'bobblocks:yellowpole_off'
elseif node.name == 'bobblocks:greenpole_off' then nodename = 'bobblocks:greenpole'
elseif node.name == 'bobblocks:greenpole' then nodename = 'bobblocks:greenpole_off'
elseif node.name == 'bobblocks:bluepole_off' then nodename = 'bobblocks:bluepole'
elseif node.name == 'bobblocks:bluepole' then nodename = 'bobblocks:bluepole_off'
elseif node.name == 'bobblocks:indigopole_off' then nodename = 'bobblocks:indigopole'
elseif node.name == 'bobblocks:indigopole' then nodename = 'bobblocks:indigopole_off'
elseif node.name == 'bobblocks:violetpole_off' then nodename = 'bobblocks:violetpole'
elseif node.name == 'bobblocks:violetpole' then nodename = 'bobblocks:violetpole_off'
elseif node.name == 'bobblocks:whitepole_off' then nodename = 'bobblocks:whitepole'
elseif node.name == 'bobblocks:whitepole' then nodename = 'bobblocks:whitepole_off'
end
minetest.env:add_node(pos, {name = nodename})
minetest.sound_play("bobblocks_glassblock",
{pos = pos, gain = 1.0, max_hear_distance = 32,})
end
-- Punch Blocks
local on_bobblock_punched = function (pos, node, puncher)
if
-- Start Blocks
node.name == 'bobblocks:redblock_off' or node.name == 'bobblocks:redblock' or
node.name == 'bobblocks:orangeblock_off' or node.name == 'bobblocks:orangeblock' or
node.name == 'bobblocks:yellowblock_off' or node.name == 'bobblocks:yellowblock' or
node.name == 'bobblocks:greenblock_off' or node.name == 'bobblocks:greenblock' or
node.name == 'bobblocks:blueblock_off' or node.name == 'bobblocks:blueblock' or
node.name == 'bobblocks:indigoblock_off' or node.name == 'bobblocks:indigoblock' or
node.name == 'bobblocks:violetblock_off' or node.name == 'bobblocks:violetblock' or
node.name == 'bobblocks:whiteblock_off' or node.name == 'bobblocks:whiteblock' or
--Start Poles
node.name == 'bobblocks:redpole_off' or node.name == 'bobblocks:redpole' or
node.name == 'bobblocks:orangepole_off' or node.name == 'bobblocks:orangepole' or
node.name == 'bobblocks:yellowpole_off' or node.name == 'bobblocks:yellowpole' or
node.name == 'bobblocks:greenpole_off' or node.name == 'bobblocks:greenpole' or
node.name == 'bobblocks:bluepole_off' or node.name == 'bobblocks:bluepole' or
node.name == 'bobblocks:indigopole_off' or node.name == 'bobblocks:indigopole' or
node.name == 'bobblocks:violetpole_off' or node.name == 'bobblocks:violetpole' or
node.name == 'bobblocks:whitepole_off' or node.name == 'bobblocks:whitepole'
then
update_bobblock(pos, node)
end
end
minetest.register_on_punchnode(on_bobblock_punched)
-- Nodes
-- Misc Node
minetest.register_node("bobblocks:btm", {
description = "Bobs TransMorgifier v5",
tile_images = {"bobblocks_btm_sides.png", "bobblocks_btm_sides.png", "bobblocks_btm_sides.png",
"bobblocks_btm_sides.png", "bobblocks_btm_sides.png", "bobblocks_btm.png"},
inventory_image = "bobblocks_btm.png",
paramtype2 = "facedir",
material = minetest.digprop_dirtlike(1.0),
legacy_facedir_simple = true,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,not_in_creative_inventory=1},
})
-- Start Block Nodes
minetest.register_node("bobblocks:redblock", {
description = "Red Block",
drawtype = "glasslike",
tile_images = {"bobblocks_redblock.png"},
inventory_image = minetest.inventorycube("bobblocks_redblock.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-0,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
mesecons = {conductor={
state = mesecon.state.on,
offstate = "bobblocks:redblock_off"
}}
})
minetest.register_node("bobblocks:redblock_off", {
description = "Red Block",
tile_images = {"bobblocks_redblock.png"},
is_ground_content = true,
alpha = WATER_ALPHA,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,not_in_creative_inventory=1},
drop = 'bobblocks:redblock',
mesecons = {conductor={
state = mesecon.state.off,
onstate = "bobblocks:redblock"
}}
})
minetest.register_node("bobblocks:orangeblock", {
description = "Orange Block",
drawtype = "glasslike",
tile_images = {"bobblocks_orangeblock.png"},
inventory_image = minetest.inventorycube("bobblocks_orangeblock.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-0,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
mesecons = {conductor={
state = mesecon.state.on,
offstate = "bobblocks:orangeblock_off"
}}
})
minetest.register_node("bobblocks:orangeblock_off", {
description = "Orange Block",
tile_images = {"bobblocks_orangeblock.png"},
is_ground_content = true,
alpha = WATER_ALPHA,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,not_in_creative_inventory=1},
drop = 'bobblocks:orangeblock',
mesecons = {conductor={
state = mesecon.state.off,
onstate = "bobblocks:orangeblock"
}}
})
minetest.register_node("bobblocks:yellowblock", {
description = "Yellow Block",
drawtype = "glasslike",
tile_images = {"bobblocks_yellowblock.png"},
inventory_image = minetest.inventorycube("bobblocks_yellowblock.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-0,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
mesecons = {conductor={
state = mesecon.state.on,
offstate = "bobblocks:yellowblock_off"
}}
})
minetest.register_node("bobblocks:yellowblock_off", {
description = "Yellow Block",
tile_images = {"bobblocks_yellowblock.png"},
is_ground_content = true,
alpha = WATER_ALPHA,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,not_in_creative_inventory=1},
drop = 'bobblocks:yellowblock',
mesecons = {conductor={
state = mesecon.state.off,
onstate = "bobblocks:yellowblock"
}}
})
minetest.register_node("bobblocks:greenblock", {
description = "Green Block",
drawtype = "glasslike",
tile_images = {"bobblocks_greenblock.png"},
inventory_image = minetest.inventorycube("bobblocks_greenblock.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-0,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
mesecons = {conductor={
state = mesecon.state.on,
offstate = "bobblocks:greenblock_off"
}}
})
minetest.register_node("bobblocks:greenblock_off", {
description = "Green Block",
tile_images = {"bobblocks_greenblock.png"},
is_ground_content = true,
alpha = WATER_ALPHA,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,not_in_creative_inventory=1},
drop = 'bobblocks:greenblock',
mesecons = {conductor={
state = mesecon.state.off,
onstate = "bobblocks:greenblock"
}}
})
minetest.register_node("bobblocks:blueblock", {
description = "Blue Block",
drawtype = "glasslike",
tile_images = {"bobblocks_blueblock.png"},
inventory_image = minetest.inventorycube("bobblocks_blueblock.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-0,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
mesecons = {conductor={
state = mesecon.state.on,
offstate = "bobblocks:blueblock_off"
}}
})
minetest.register_node("bobblocks:blueblock_off", {
description = "Blue Block",
tile_images = {"bobblocks_blueblock.png"},
is_ground_content = true,
alpha = WATER_ALPHA,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,not_in_creative_inventory=1},
drop = 'bobblocks:blueblock',
mesecons = {conductor={
state = mesecon.state.off,
onstate = "bobblocks:blueblock"
}}
})
minetest.register_node("bobblocks:indigoblock", {
description = "Indigo Block",
drawtype = "glasslike",
tile_images = {"bobblocks_indigoblock.png"},
inventory_image = minetest.inventorycube("bobblocks_indigoblock.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-0,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
mesecons = {conductor={
state = mesecon.state.on,
offstate = "bobblocks:indigoblock_off"
}}
})
minetest.register_node("bobblocks:indigoblock_off", {
description = "Indigo Block",
tile_images = {"bobblocks_indigoblock.png"},
is_ground_content = true,
alpha = WATER_ALPHA,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,not_in_creative_inventory=1},
drop = 'bobblocks:indigoblock',
mesecons = {conductor={
state = mesecon.state.off,
onstate = "bobblocks:indigoblock"
}}
})
minetest.register_node("bobblocks:violetblock", {
description = "Violet Block",
drawtype = "glasslike",
tile_images = {"bobblocks_violetblock.png"},
inventory_image = minetest.inventorycube("bobblocks_violetblock.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-0,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
mesecons = {conductor={
state = mesecon.state.on,
offstate = "bobblocks:violetblock_off"
}}
})
minetest.register_node("bobblocks:violetblock_off", {
description = "Violet Block",
tile_images = {"bobblocks_violetblock.png"},
is_ground_content = true,
alpha = WATER_ALPHA,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,not_in_creative_inventory=1},
drop = 'bobblocks:violetblock',
mesecons = {conductor={
state = mesecon.state.off,
onstate = "bobblocks:violetblock"
}}
})
minetest.register_node("bobblocks:whiteblock", {
description = "White Block",
drawtype = "glasslike",
tile_images = {"bobblocks_whiteblock.png"},
inventory_image = minetest.inventorycube("bobblocks_whiteblock.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-0,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
mesecons = {conductor={
state = mesecon.state.on,
offstate = "bobblocks:whiteblock_off"
}}
})
minetest.register_node("bobblocks:whiteblock_off", {
description = "White Block",
tile_images = {"bobblocks_whiteblock.png"},
is_ground_content = true,
alpha = WATER_ALPHA,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,not_in_creative_inventory=1},
drop = 'bobblocks:whiteblock',
mesecons = {conductor={
state = mesecon.state.off,
onstate = "bobblocks:whiteblock"
}}
})
minetest.register_node("bobblocks:greyblock", {
description = "Grey Block",
drawtype = "glasslike",
tile_images = {"bobblocks_greyblock.png"},
inventory_image = minetest.inventorycube("bobblocks_greyblock.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-0,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
mesecons = {conductor={
state = mesecon.state.on,
offstate = "bobblocks:greyblock_off"
}}
})
minetest.register_node("bobblocks:greyblock_off", {
description = "Grey Block",
tile_images = {"bobblocks_greyblock.png"},
is_ground_content = true,
alpha = WATER_ALPHA,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,not_in_creative_inventory=1},
drop = 'bobblocks:greyblock',
mesecons = {conductor={
state = mesecon.state.off,
onstate = "bobblocks:greyblock"
}}
})
-- Block Poles
minetest.register_node("bobblocks:redpole", {
description = "Red Pole",
drawtype = "fencelike",
tile_images = {"bobblocks_redblock.png"},
inventory_image = ("bobblocks_invredpole.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-0,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
mesecons = {conductor={
state = mesecon.state.on,
offstate = "bobblocks:redpole_off"
}}
})
minetest.register_node("bobblocks:redpole_off", {
description = "Red Pole",
drawtype = "fencelike",
tile_images = {"bobblocks_redblock.png"},
inventory_image = ("bobblocks_invredpole.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-10,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,not_in_creative_inventory=1},
drop = 'bobblocks:redpole',
mesecons = {conductor={
state = mesecon.state.off,
onstate = "bobblocks:redpole"
}}
})
minetest.register_node("bobblocks:orangepole", {
description = "Orange Pole",
drawtype = "fencelike",
tile_images = {"bobblocks_orangeblock.png"},
inventory_image = ("bobblocks_invorangepole.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-0,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
mesecons = {conductor={
state = mesecon.state.on,
offstate = "bobblocks:orangepole_off"
}}
})
minetest.register_node("bobblocks:orangepole_off", {
description = "Orange Pole",
drawtype = "fencelike",
tile_images = {"bobblocks_orangeblock.png"},
inventory_image = ("bobblocks_invorangepole.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-10,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,not_in_creative_inventory=1},
drop = 'bobblocks:orangepole',
mesecons = {conductor={
state = mesecon.state.off,
onstate = "bobblocks:orangepole"
}}
})
minetest.register_node("bobblocks:yellowpole", {
description = "Yellow Pole",
drawtype = "fencelike",
tile_images = {"bobblocks_yellowblock.png"},
inventory_image = ("bobblocks_invyellowpole.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-0,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
mesecons = {conductor={
state = mesecon.state.on,
offstate = "bobblocks:yellowpole_off"
}}
})
minetest.register_node("bobblocks:yellowpole_off", {
description = "Yellow Pole",
drawtype = "fencelike",
tile_images = {"bobblocks_yellowblock.png"},
inventory_image = ("bobblocks_invyellowpole.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-10,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,not_in_creative_inventory=1},
drop = 'bobblocks:yellowpole',
mesecons = {conductor={
state = mesecon.state.off,
onstate = "bobblocks:yellowpole"
}}
})
minetest.register_node("bobblocks:greenpole", {
description = "Green Pole",
drawtype = "fencelike",
tile_images = {"bobblocks_greenblock.png"},
inventory_image = ("bobblocks_invgreenpole.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-0,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
mesecons = {conductor={
state = mesecon.state.on,
offstate = "bobblocks:greenpole_off"
}}
})
minetest.register_node("bobblocks:greenpole_off", {
description = "Green Pole",
drawtype = "fencelike",
tile_images = {"bobblocks_greenblock.png"},
inventory_image = ("bobblocks_invgreenpole.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-10,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,not_in_creative_inventory=1},
drop = 'bobblocks:greenpole',
mesecons = {conductor={
state = mesecon.state.off,
onstate = "bobblocks:greenpole"
}}
})
minetest.register_node("bobblocks:bluepole", {
description = "Blue Pole",
drawtype = "fencelike",
tile_images = {"bobblocks_blueblock.png"},
inventory_image = ("bobblocks_invbluepole.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-0,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
mesecons = {conductor={
state = mesecon.state.on,
offstate = "bobblocks:bluepole_off"
}}
})
minetest.register_node("bobblocks:bluepole_off", {
description = "Blue Pole",
drawtype = "fencelike",
tile_images = {"bobblocks_blueblock.png"},
inventory_image = ("bobblocks_invbluepole.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-10,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,not_in_creative_inventory=1},
drop = 'bobblocks:bluepole',
mesecons = {conductor={
state = mesecon.state.off,
onstate = "bobblocks:bluepole"
}}
})
minetest.register_node("bobblocks:indigopole", {
description = "Indigo Pole",
drawtype = "fencelike",
tile_images = {"bobblocks_indigoblock.png"},
inventory_image = ("bobblocks_invindigopole.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-0,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
mesecons = {conductor={
state = mesecon.state.on,
offstate = "bobblocks:indigopole_off"
}}
})
minetest.register_node("bobblocks:indigopole_off", {
description = "Indigo Pole",
drawtype = "fencelike",
tile_images = {"bobblocks_indigoblock.png"},
inventory_image = ("bobblocks_invindigopole.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-10,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,not_in_creative_inventory=1},
drop = 'bobblocks:indigopole',
mesecons = {conductor={
state = mesecon.state.off,
onstate = "bobblocks:indigopole"
}}
})
minetest.register_node("bobblocks:violetpole", {
description = "Violet Pole",
drawtype = "fencelike",
tile_images = {"bobblocks_violetblock.png"},
inventory_image = ("bobblocks_invvioletpole.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-0,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
mesecons = {conductor={
state = mesecon.state.on,
offstate = "bobblocks:violetpole_off"
}}
})
minetest.register_node("bobblocks:violetpole_off", {
description = "Violet Pole",
drawtype = "fencelike",
tile_images = {"bobblocks_violetblock.png"},
inventory_image = ("bobblocks_invvioletpole.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-10,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,not_in_creative_inventory=1},
drop = 'bobblocks:violetpole',
mesecons = {conductor={
state = mesecon.state.off,
onstate = "bobblocks:violetpole"
}}
})
minetest.register_node("bobblocks:whitepole", {
description = "White Pole",
drawtype = "fencelike",
tile_images = {"bobblocks_whiteblock.png"},
inventory_image = ("bobblocks_invwhitepole.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-0,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
mesecons = {conductor={
state = mesecon.state.on,
offstate = "bobblocks:whitepole_off"
}}
})
minetest.register_node("bobblocks:whitepole_off", {
description = "White Pole",
drawtype = "fencelike",
tile_images = {"bobblocks_whiteblock.png"},
inventory_image = ("bobblocks_invwhitepole.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
light_source = LIGHT_MAX-10,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,not_in_creative_inventory=1},
drop = 'bobblocks:whitepole',
mesecons = {conductor={
state = mesecon.state.off,
onstate = "bobblocks:whitepole"
}}
})
minetest.register_node("bobblocks:greypole", {
description = "Grey Pole",
drawtype = "fencelike",
tile_images = {"bobblocks_greyblock.png"},
inventory_image = ("bobblocks_invgreypole.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_glass_defaults(),
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
--light_source = LIGHT_MAX-0,
})
-- Crafts
-- BTM
minetest.register_craft({
output = 'NodeItem "bobblocks:btm" 1',
recipe = {
{'node "default:glass" 1', 'node "default:torch" 1', 'node "default:leaves" 1',
'node "default:mese" 1','node "default:rat" 1'},
},
})
minetest.register_craft({
output = 'NodeItem "bobblocks:greyblock" 2',
recipe = {
{'node "default:glass" 1', 'node "default:torch" 1', 'node "default:cobble" 1'},
},
})
-- Red / Yellow / Blue / White
-- Red / Yellow -> Orange
-- Red / Blue -> Violet
-- Blue / Yellow -> Green
-- Red / Yellow / White -> Indigo
minetest.register_craft({
output = 'NodeItem "bobblocks:redblock" 2',
recipe = {
{'node "default:glass" 1', 'node "default:torch" 1', 'node "default:brick" 1'},
},
})
minetest.register_craft({
output = 'NodeItem "bobblocks:yellowblock" 2',
recipe = {
{'node "default:glass" 1', 'node "default:torch" 1', 'node "default:sand" 1'},
},
})
minetest.register_craft({
output = 'NodeItem "bobblocks:blueblock" 2',
recipe = {
{'node "default:glass" 1', 'node "default:torch" 1', 'node "default:gravel" 1'},
},
})
minetest.register_craft({
output = 'NodeItem "bobblocks:whiteblock" 2',
recipe = {
{'node "default:glass" 1', 'node "default:torch" 1', 'node "default:dirt" 1'},
},
})
minetest.register_craft({
output = 'NodeItem "bobblocks:orangeblock" 2',
recipe = {
{'node "bobblocks:redblock" 1', 'node "bobblocks:yellowblock" 1'},
},
})
minetest.register_craft({
output = 'NodeItem "bobblocks:violetblock" 2',
recipe = {
{'node "bobblocks:redblock" 1', 'node "bobblocks:blueblock" 1'},
},
})
minetest.register_craft({
output = 'NodeItem "bobblocks:greenblock" 2',
recipe = {
{'node "bobblocks:blueblock" 1', 'node "bobblocks:yellowblock" 1'},
},
})
minetest.register_craft({
output = 'NodeItem "bobblocks:indigoblock" 3',
recipe = {
{'node "bobblocks:redblock" 1', 'node "bobblocks:blueblock" 1', 'node "bobblocks:whiteblock" 1'},
},
})
-- Poles
minetest.register_craft({
output = 'NodeItem "bobblocks:redpole" 1',
recipe = {
{'node "bobblocks:redblock" 1', 'node "default:stick" 1'},
},
})
minetest.register_craft({
output = 'NodeItem "bobblocks:yellowpole" 1',
recipe = {
{'node "bobblocks:yellowblock" 1', 'node "default:stick" 1'},
},
})
minetest.register_craft({
output = 'NodeItem "bobblocks:bluepole" 1',
recipe = {
{'node "bobblocks:blueblock" 1', 'node "default:stick" 1'},
},
})
minetest.register_craft({
output = 'NodeItem "bobblocks:whitepole" 1',
recipe = {
{'node "bobblocks:whiteblock" 1', 'node "default:stick" 1'},
},
})
minetest.register_craft({
output = 'NodeItem "bobblocks:orangepole" 1',
recipe = {
{'node "bobblocks:orangeblock" 1', 'node "default:stick" 1'},
},
})
minetest.register_craft({
output = 'NodeItem "bobblocks:violetpole" 1',
recipe = {
{'node "bobblocks:violetblock" 1', 'node "default:stick" 1'},
},
})
minetest.register_craft({
output = 'NodeItem "bobblocks:greenpole" 1',
recipe = {
{'node "bobblocks:greenblock" 1', 'node "default:stick" 1'},
},
})
minetest.register_craft({
output = 'NodeItem "bobblocks:indigopole" 1',
recipe = {
{'node "bobblocks:indigoblock" 1', 'node "default:stick" 1'},
},
})
minetest.register_craft({
output = 'NodeItem "bobblocks:greypole" 1',
recipe = {
{'node "bobblocks:greyblock" 1', 'node "default:stick" 1'},
},
})
-- MESECON
-- Add jeija to bobblocks\default.txt and paste the below in at the bottom of bobblocks\blocks.lua

View File

@ -0,0 +1,2 @@
default
mesecons

95
mods/bobblocks/health.lua Normal file
View File

@ -0,0 +1,95 @@
local is_healthpack = function(node)
if node.name == 'bobblocks:health_off' or node.name == 'health_on' then
return true
end
return false
end
local update_healthpack = function (pos, node)
local nodename=""
local param2=""
--Switch HealthPack State
if node.name == 'bobblocks:health_off' then
nodename = 'bobblocks:health_on'
elseif node.name == 'bobblocks:health_on' then
nodename = 'bobblocks:health_off'
end
minetest.env:add_node(pos, {name = nodename})
end
local toggle_healthpack = function (pos, node)
if not is_healthgate(node) then return end
update_healthpack (pos, node, state)
end
local on_healthpack_punched = function (pos, node, puncher)
if node.name == 'bobblocks:health_off' or node.name == 'bobblocks:health_on' then
update_healthpack(pos, node)
end
end
-- Healing Node
minetest.register_node("bobblocks:health_off", {
description = "Health Pack 1 Off",
tile_images = {"bobblocks_health_off.png"},
inventory_image = "bobblocks_health_off.png",
paramtype2 = "facedir",
legacy_facedir_simple = true,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
is_ground_content = true,
walkable = false,
climbable = false,
mesecons = {conductor={
state = mesecon.state.off,
onstate = "bobblocks:health_on"
}}
})
minetest.register_node("bobblocks:health_on", {
description = "Health Pack 1 On",
tile_images = {"bobblocks_health_on.png"},
paramtype2 = "facedir",
legacy_facedir_simple = true,
light_source = LIGHT_MAX-0,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
is_ground_content = true,
walkable = false,
climbable = false,
drop = "bobblocks:health_off",
mesecons = {conductor={
state = mesecon.state.on,
offstate = "bobblocks:health_off"
}}
})
minetest.register_abm(
{nodenames = {"bobblocks:health_on"},
interval = 1.0,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local objs = minetest.env:get_objects_inside_radius(pos, 1)
for k, obj in pairs(objs) do
minetest.sound_play("bobblocks_health",
{pos = pos, gain = 1.0, max_hear_distance = 32,})
obj:set_hp(obj:get_hp()+5) -- give 2.5HP
minetest.env:remove_node(pos) -- remove the node after use
end
end,
})
--- Health
minetest.register_craft({
output = 'NodeItem "bobblocks:health_off" 1',
recipe = {
{'node "default:dirt" 1', 'node "default:paper" 1', 'node "default:apple" 2'},
},
})
minetest.register_on_punchnode(on_healthpack_punched)

View File

@ -0,0 +1,95 @@
local is_healthpack = function(node)
if node.name == 'bobblocks:health_off' or node.name == 'health_on' then
return true
end
return false
end
local update_healthpack = function (pos, node)
local nodename=""
local param2=""
--Switch HealthPack State
if node.name == 'bobblocks:health_off' then
nodename = 'bobblocks:health_on'
elseif node.name == 'bobblocks:health_on' then
nodename = 'bobblocks:health_off'
end
minetest.env:add_node(pos, {name = nodename})
end
local toggle_healthpack = function (pos, node)
if not is_healthgate(node) then return end
update_healthpack (pos, node, state)
end
local on_healthpack_punched = function (pos, node, puncher)
if node.name == 'bobblocks:health_off' or node.name == 'bobblocks:health_on' then
update_healthpack(pos, node)
end
end
-- Healing Node
minetest.register_node("bobblocks:health_off", {
description = "Health Pack 1 Off",
tile_images = {"bobblocks_health_off.png"},
inventory_image = "bobblocks_health_off.png",
paramtype2 = "facedir",
legacy_facedir_simple = true,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
is_ground_content = true,
walkable = false,
climbable = false,
mesecons = {conductor={
state = mesecon.state.off,
onstate = "bobblocks:health_on"
}}
})
minetest.register_node("bobblocks:health_on", {
description = "Health Pack 1 On",
tile_images = {"bobblocks_health_on.png"},
paramtype2 = "facedir",
legacy_facedir_simple = true,
light_source = LIGHT_MAX-0,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
is_ground_content = true,
walkable = false,
climbable = false,
drop = "bobblocks:health_off",
mesecons = {conductor={
state = mesecon.state.on,
offstate = "bobblocks:health_off"
}}
})
minetest.register_abm(
{nodenames = {"bobblocks:health_on"},
interval = 1.0,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local objs = minetest.env:get_objects_inside_radius(pos, 1)
for k, obj in pairs(objs) do
minetest.sound_play("bobblocks_health",
{pos = pos, gain = 1.0, max_hear_distance = 32,})
obj:set_hp(obj:get_hp()+3) -- give 3HP
minetest.env:remove_node(pos) -- remove the node after use
end
end,
})
--- Health
minetest.register_craft({
output = 'NodeItem "bobblocks:health_off" 1',
recipe = {
{'node "default:dirt" 1', 'node "default:paper" 1', 'node "default:apple" 2'},
},
})
minetest.register_on_punchnode(on_healthpack_punched)

8
mods/bobblocks/init.lua Normal file
View File

@ -0,0 +1,8 @@
print("[BobBlocks By minetest@rabbibob.com] Version 0.0.8 loading....")
dofile(minetest.get_modpath("bobblocks") .. "/blocks.lua")
print("[BobBlocks] loaded Blocks")
dofile(minetest.get_modpath("bobblocks") .. "/health.lua")
print("[BobBlocks] loaded Health")
dofile(minetest.get_modpath("bobblocks") .. "/trap.lua")
print("[BobBlocks] loaded Traps")
print("[BobBlocks By minetest@rabbibob.com] Version 0.0.8 loaded!")

11
mods/bobblocks/init.lua~ Normal file
View File

@ -0,0 +1,11 @@
print("[BobBlocks By minetest@rabbibob.com] Version 0.0.8 loading....")
print("[BobBlocks] loading Blocks")
dofile(minetest.get_modpath("bobblocks") .. "/blocks.lua")
print("[BobBlocks] loaded Blocks")
print("[BobBlocks] loading Health")
dofile(minetest.get_modpath("bobblocks") .. "/health.lua")
print("[BobBlocks] loaded Health")
print("[BobBlocks] loading Traps")
dofile(minetest.get_modpath("bobblocks") .. "/trap.lua")
print("[BobBlocks] loaded Traps")
print("[BobBlocks By minetest@rabbibob.com] Version 0.0.8 loaded!")

53
mods/bobblocks/readme.txt Normal file
View File

@ -0,0 +1,53 @@
-- BobBlocks v0.0.8
-- (Minetest 0.4.5 compatible 20130315)
-- http://forum.minetest.net/viewtopic.php?id=1274
--------------------------------------------------------------------------
--------------------------------------------------------------------------
-- Requirements: Mesecons --
-- http://forum.minetest.net/viewtopic.php?id=628 --
-- --
-- Does not support jeija or older version of Mesecons --
-- before 1/20/2013 --
-- http://forum.minetest.net/viewtopic.php?pid=64976#p64976 --
--------------------------------------------------------------------------
--------------------------------------------------------------------------
-- Colored Lit Blocks
---- Default state = Solid lit block
---- Secondary state (punch) = transparent unlit block
---- Mesecons activation [CONDUCTOR]
-- Colored Lit Poles
---- Default state = Solid lit block
---- Secondary state (punch) = unlit block
---- Mesecons activation [CONDUCTOR]
-- Health Kit
---- Default state = health kit inactive
---- Secondary state (punch) = health kit active +10HP when walked through
---- Mesecons activation [CONDUCTOR]
-- Trap
---- Default Grass (walkable off)
---- Spike Minor (1HP per hit)
------ Spikes can be 'set' and activated when walked over
---- Spike Major (100HP per hit)
------ Spikes can be 'set' and activated when walked over
# [ATTRIBUTION]
# Unless otherwise noted, all graphics & sounds
# created by Rabbi Bob
# Licensed under the GPLv2/later
# [GRAPHICS]
# minor & major spikes by Death Dealer
# License: WTFPL
# http://minetest.net/forum/viewtopic.php?id=1582
# [SOUNDS]
# bobblocks_glass
# Author: Ch0cchi
# http://www.freesound.org/people/Ch0cchi/sounds/15285/
# Edited by rabbibob
# bobblocks_trap_fall & bobblocks_trap_fall_major
# Author: Rock Savage
# http://www.freesound.org/people/Rock%20Savage/sounds/65924/#
# Edited by rabbibob
# bobblocks_health
# http://hamsterrepublic.com/ohrrpgce/Free_Sound_Effects.html

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

183
mods/bobblocks/trap.lua Normal file
View File

@ -0,0 +1,183 @@
-- State Changes
local update_bobtrap = function (pos, node)
local nodename=""
local param2=""
--Switch Trap State
if
-- Swap Traps
node.name == 'bobblocks:trap_spike' then nodename = 'bobblocks:trap_spike_set'
elseif node.name == 'bobblocks:trap_spike_set' then nodename = 'bobblocks:trap_spike'
elseif node.name == 'bobblocks:trap_spike_major' then nodename = 'bobblocks:trap_spike_major_set'
elseif node.name == 'bobblocks:trap_spike_major_set' then nodename = 'bobblocks:trap_spike_major'
end
minetest.env:add_node(pos, {name = nodename})
end
-- Punch Traps
local on_bobtrap_punched = function (pos, node, puncher)
if
-- Start Traps
node.name == 'bobblocks:trap_spike' or node.name == 'bobblocks:trap_spike_set' or
node.name == 'bobblocks:trap_spike_major' or node.name == 'bobblocks:trap_spike_major_set'
then
update_bobtrap(pos, node)
end
end
minetest.register_on_punchnode(on_bobtrap_punched)
--ABM (Spring The Traps)
minetest.register_abm(
{nodenames = {"bobblocks:trap_spike_set"},
interval = 1.0,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local objs = minetest.env:get_objects_inside_radius(pos, 1)
for k, obj in pairs(objs) do
update_bobtrap(pos, node)
end
end,
})
minetest.register_abm(
{nodenames = {"bobblocks:trap_spike_major_set"},
interval = 1.0,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local objs = minetest.env:get_objects_inside_radius(pos, 1)
for k, obj in pairs(objs) do
update_bobtrap(pos, node)
end
end,
})
-- Nodes
minetest.register_node("bobblocks:trap_grass", {
description = "Trap Grass",
tile_images = {"default_grass.png"},
paramtype2 = "facedir",
legacy_facedir_simple = true,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
is_ground_content = false,
walkable = false,
climbable = false,
})
minetest.register_node("bobblocks:trap_spike", {
description = "Trap Spike Minor",
drawtype = "plantlike",
visual_scale = 1,
tile_images = {"bobblocks_minorspike.png"},
inventory_image = ("bobblocks_minorspike.png"),
paramtype = "light",
walkable = false,
sunlight_propagates = true,
groups = {cracky=3,melty=3},
})
minetest.register_node("bobblocks:trap_spike_set", {
description = "Trap Spike Minor Set",
drawtype = "raillike",
visual_scale = 1,
tile_images = {"bobblocks_trap_set.png"},
paramtype = "light",
walkable = false,
sunlight_propagates = true,
groups = {cracky=3,melty=3,not_in_creative_inventory=1},
drop = 'bobblocks:trap_spike',
})
minetest.register_node("bobblocks:trap_spike_major", {
description = "Trap Spike Major",
drawtype = "plantlike",
visual_scale = 1,
tile_images = {"bobblocks_majorspike.png"},
inventory_image = ("bobblocks_majorspike.png"),
paramtype = "light",
walkable = false,
sunlight_propagates = true,
groups = {cracky=2,melty=2},
})
minetest.register_node("bobblocks:trap_spike_major_set", {
description = "Trap Spike Major Set",
drawtype = "raillike",
visual_scale = 1,
tile_images = {"bobblocks_trap_set.png"},
paramtype = "light",
walkable = false,
sunlight_propagates = true,
groups = {cracky=3,melty=3,not_in_creative_inventory=1},
drop = 'bobblocks:trap_spike_major',
})
-- Crafting
minetest.register_craft({
output = 'bobblocks:trap_spike',
recipe = {
{'', '', ''},
{'', 'default:cobble', ''},
{'default:cobble', 'default:apple', 'default:cobble'},
}
})
minetest.register_craft({
output = 'bobblocks:trap_spike_major',
recipe = {
{'', 'default:cobble', ''},
{'', 'default:apple', ''},
{'default:cobble', 'default:apple', 'default:cobble'},
}
})
minetest.register_craft({
output = 'bobblocks:trap_grass',
recipe = {
{'', '', ''},
{'', 'default:dirt', ''},
{'', 'default:stick', ''},
}
})
-- ABM
minetest.register_abm(
{nodenames = {"bobblocks:trap_spike"},
interval = 1.0,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local objs = minetest.env:get_objects_inside_radius(pos, 1)
for k, obj in pairs(objs) do
obj:set_hp(obj:get_hp()-1)
minetest.sound_play("bobblocks_trap_fall",
{pos = pos, gain = 1.0, max_hear_distance = 3,})
end
end,
})
minetest.register_abm(
{nodenames = {"bobblocks:trap_spike_major"},
interval = 1.0,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local objs = minetest.env:get_objects_inside_radius(pos, 1)
for k, obj in pairs(objs) do
obj:set_hp(obj:get_hp()-100)
minetest.sound_play("bobblocks_trap_fall",
{pos = pos, gain = 1.0, max_hear_distance = 3,})
end
end,
})

View File

@ -428,23 +428,28 @@ minetest.register_node("maptools:igniter", {
minetest.register_node("maptools:superapple", {
description = S("Super Apple"),
range = 12,
stack_max = 10000,
stack_max = 99,
drawtype = "plantlike",
visual_scale = 1.0,
tiles = {"maptools_superapple.png"},
inventory_image = "maptools_superapple.png",
paramtype = "light",
sunlight_propagates = true,
walkable = false,
selection_box = {
type = "fixed",
fixed = {-0.2, -0.5, -0.2, 0.2, 0, 0.2}
},
walkable = false,
groups = {fleshy=3, dig_immediate=3, not_in_creative_inventory = 0},
is_ground_content = true,
groups = {fleshy = 3, dig_immediate = 3, not_in_creative_inventory = 0, flammable = 2, leafdecay = 3, leafdecay_drop = 1},
on_use = minetest.item_eat(20),
sounds = default.node_sound_defaults(),
sounds = default.node_sound_leaves_defaults(),
after_place_node = function(pos, placer, itemstack)
if placer:is_player() then
minetest.set_node(pos, {name = "maptools:superapple", param2= 1})
end
end,
})
-- Items
minetest.register_craftitem("maptools:copper_coin", {

View File

@ -240,10 +240,14 @@ function mesecon.changesignal(pos, node, rulename, newstate, depth)
return
end
<<<<<<< HEAD
-- Include "change" in overwritecheck so that it cannot be overwritten
-- by "active" / "deactivate" that will be called upon the node at the same time.
local overwritecheck = {"change", rulename}
mesecon.queue:add_action(pos, "change", {rulename, newstate}, nil, overwritecheck, 1 / depth)
=======
mesecon.queue:add_action(pos, "change", {rulename, newstate}, nil, rulename, 1 / depth)
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
end
-- Conductors
@ -517,7 +521,14 @@ function mesecon.rules_link(output, input, dug_outputrules) --output/input are p
for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do
-- Check if input accepts from output
if mesecon.cmpPos(mesecon.addPosRule(input, inputrule), output) then
<<<<<<< HEAD
return true, inputrule
=======
if inputrule.sx == nil or outputrule.sx == nil
or mesecon.cmpSpecial(inputrule, outputrule) then
return true, inputrule
end
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
end
end
end
@ -537,7 +548,14 @@ function mesecon.rules_link_rule_all(output, rule)
for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do
-- Check if input accepts from output
if mesecon.cmpPos(mesecon.addPosRule(input, inputrule), output) then
<<<<<<< HEAD
table.insert(rules, inputrule)
=======
if inputrule.sx == nil or rule.sx == nil
or mesecon.cmpSpecial(inputrule, rule) then
table.insert(rules, inputrule)
end
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
end
end
return rules
@ -555,7 +573,14 @@ function mesecon.rules_link_rule_all_inverted(input, rule)
for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do
if mesecon.cmpPos(mesecon.addPosRule(output, outputrule), input) then
<<<<<<< HEAD
table.insert(rules, mesecon.invertRule(outputrule))
=======
if outputrule.sx == nil or rule.sx == nil
or mesecon.cmpSpecial(outputrule, rule) then
table.insert(rules, mesecon.invertRule(outputrule))
end
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
end
end
return rules
@ -592,7 +617,11 @@ function mesecon.is_powered(pos, rule)
local nn = minetest.get_node(np)
if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname))
or mesecon.is_receptor_on (nn.name)) then
<<<<<<< HEAD
table.insert(sourcepos, np)
=======
sourcepos.insert(np)
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
end
end
end

View File

@ -27,6 +27,7 @@ mesecon.on_placenode = function (pos, node)
-- Effectors: Send changesignal and activate or deactivate
if mesecon.is_effector(node.name) then
<<<<<<< HEAD
local powered_rules = {}
local unpowered_rules = {}
@ -48,6 +49,14 @@ mesecon.on_placenode = function (pos, node)
for _, r in ipairs(unpowered_rules) do
mesecon.deactivate(pos, node, r, 1)
end
=======
if mesecon.is_powered(pos) then
mesecon.changesignal(pos, node, mesecon.effector_get_rules(node), "on", 1)
mesecon.activate(pos, node, nil, 1)
else
mesecon.changesignal(pos, node, mesecon.effector_get_rules(node), "off", 1)
mesecon.deactivate(pos, node, nil, 1)
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
end
end
end

View File

@ -62,7 +62,11 @@ function mesecon.rule2bit(findrule, allrules)
end
for m,metarule in ipairs( allrules) do
for _, rule in ipairs(metarule ) do
<<<<<<< HEAD
if mesecon.cmpPos(findrule, rule) then
=======
if mesecon.cmpPos(findrule, rule) and mesecon.cmpSpecial(findrule, rule) then
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
return m
end
end
@ -82,7 +86,11 @@ function mesecon.rule2metaindex(findrule, allrules)
for m, metarule in ipairs( allrules) do
for _, rule in ipairs(metarule ) do
<<<<<<< HEAD
if mesecon.cmpPos(findrule, rule) then
=======
if mesecon.cmpPos(findrule, rule) and mesecon.cmpSpecial(findrule, rule) then
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
return m
end
end
@ -153,7 +161,11 @@ function mesecon.set_bit(binary,bit,value)
end
function mesecon.invertRule(r)
<<<<<<< HEAD
return {x = -r.x, y = -r.y, z = -r.z}
=======
return {x = -r.x, y = -r.y, z = -r.z, sx = r.sx, sy = r.sy, sz = r.sz}
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
end
function mesecon.addPosRule(p, r)
@ -164,6 +176,13 @@ function mesecon.cmpPos(p1, p2)
return (p1.x == p2.x and p1.y == p2.y and p1.z == p2.z)
end
<<<<<<< HEAD
=======
function mesecon.cmpSpecial(r1, r2)
return (r1.sx == r2.sx and r1.sy == r2.sy and r1.sz == r2.sz)
end
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
function mesecon.tablecopy(table) -- deep table copy
if type(table) ~= "table" then return table end -- no need to copy
local newtable = {}

View File

@ -39,8 +39,31 @@ local function set_gate(pos, node, state)
end
end
<<<<<<< HEAD
local function update_gate(pos, node, link, newstate)
local gate = minetest.registered_nodes[node.name]
=======
function set_gate(pos, on)
gate = get_gate(pos)
local meta = minetest.get_meta(pos)
if on ~= gate_state(pos) then
if mesecon.do_overheat(pos) then
pop_gate(pos)
else
local node = minetest.get_node(pos)
if on then
minetest.swap_node(pos, {name = "mesecons_gates:"..gate.."_on", param2=node.param2})
mesecon.receptor_on(pos,
gate_get_output_rules(node))
else
minetest.swap_node(pos, {name = "mesecons_gates:"..gate.."_off", param2=node.param2})
mesecon.receptor_off(pos,
gate_get_output_rules(node))
end
end
end
end
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
if gate.inputnumber == 1 then
set_gate(pos, node, gate.assess(newstate == "on"))
@ -54,6 +77,7 @@ local function update_gate(pos, node, link, newstate)
end
end
<<<<<<< HEAD
function register_gate(name, inputnumber, assess, recipe)
local get_inputrules = inputnumber == 2 and gate_get_input_rules_twoinputs or
gate_get_input_rules_oneinput
@ -100,6 +124,15 @@ function register_gate(name, inputnumber, assess, recipe)
})
minetest.register_craft({output = basename.."_off", recipe = recipe})
=======
function pop_gate(pos)
gate = get_gate(pos)
minetest.remove_node(pos)
minetest.after(0.2, function (pos)
mesecon.receptor_off(pos, mesecon.rules.flat)
end , pos) -- wait for pending parsings
minetest.add_item(pos, "mesecons_gates:"..gate.."_off")
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
end
register_gate("diode", 1, function (input) return input end,

View File

@ -82,9 +82,15 @@ local function get_real_port_states(pos)
local meta = minetest.get_meta(pos)
local L = {}
local n = meta:get_int("real_portstates") - 1
<<<<<<< HEAD
for _, name in ipairs(port_names) do
L[name] = ((n % 2) == 1)
n = math.floor(n / 2)
=======
for _, index in ipairs({"a", "b", "c", "d"}) do
L[index] = ((n%2) == 1)
n = math.floor(n/2)
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
end
return L
end
@ -99,7 +105,11 @@ local function merge_port_states(ports, vports)
}
end
<<<<<<< HEAD
local function generate_name(ports)
=======
local generate_name = function (ports)
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
local d = ports.d and 1 or 0
local c = ports.c and 1 or 0
local b = ports.b and 1 or 0
@ -169,6 +179,7 @@ local function overheat_off(pos)
end
<<<<<<< HEAD
local function overheat(pos, meta)
if mesecon.do_overheat(pos) then -- If too hot
local node = minetest.get_node(pos)
@ -178,6 +189,10 @@ local function overheat(pos, meta)
minetest.after(0.2, overheat_off, pos)
return true
end
=======
local overheat_off = function(pos)
mesecon.receptor_off(pos, mesecon.rules.flat)
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
end
------------------------
@ -224,9 +239,24 @@ local function remove_functions(x)
return x
end
<<<<<<< HEAD
local function get_interrupt(pos)
-- iid = interrupt id
local function interrupt(time, iid)
=======
local safe_serialize = function(value)
return minetest.serialize(deep_copy(value))
end
mesecon.queue:add_function("lc_interrupt", function (pos, luac_id, iid)
-- There is no luacontroller anymore / it has been reprogrammed / replaced
if (minetest.get_meta(pos):get_int("luac_id") ~= luac_id) then return end
lc_update(pos, {type="interrupt", iid = iid})
end)
local getinterrupt = function(pos)
local interrupt = function (time, iid) -- iid = interrupt id
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
if type(time) ~= "number" then return end
local luac_id = minetest.get_meta(pos):get_int("luac_id")
mesecon.queue:add_action(pos, "lc_interrupt", {luac_id, iid}, time, iid, 1)
@ -252,6 +282,7 @@ local safe_globals = {
local function create_environment(pos, mem, event)
-- Gather variables for the environment
local vports = minetest.registered_nodes[minetest.get_node(pos).name].virtual_portstates
<<<<<<< HEAD
local vports_copy = {}
for k, v in pairs(vports) do vports_copy[k] = v end
local rports = get_real_port_states(pos)
@ -323,6 +354,76 @@ local function create_environment(pos, mem, event)
difftime = os.difftime,
time = os.time,
},
=======
vports = {a = vports.a, b = vports.b, c = vports.c, d = vports.d}
local rports = get_real_portstates(pos)
return {
print = safe_print,
pin = merge_portstates(vports, rports),
port = vports,
interrupt = getinterrupt(pos),
digiline_send = getdigiline_send(pos),
mem = mem,
tostring = tostring,
tonumber = tonumber,
heat = minetest.get_meta(pos):get_int("heat"),
-- overheat_max Unit: actions per second, checks are every 1 second
heat_max = mesecon.setting("overheat_max", 20),
string = {
byte = string.byte,
char = string.char,
find = string.find,
format = string.format,
gmatch = string.gmatch,
gsub = string.gsub,
len = string.len,
lower = string.lower,
upper = string.upper,
match = string.match,
rep = string.rep,
reverse = string.reverse,
sub = string.sub,
},
math = {
abs = math.abs,
acos = math.acos,
asin = math.asin,
atan = math.atan,
atan2 = math.atan2,
ceil = math.ceil,
cos = math.cos,
cosh = math.cosh,
deg = math.deg,
exp = math.exp,
floor = math.floor,
fmod = math.fmod,
frexp = math.frexp,
huge = math.huge,
ldexp = math.ldexp,
log = math.log,
log10 = math.log10,
max = math.max,
min = math.min,
modf = math.modf,
pi = math.pi,
pow = math.pow,
rad = math.rad,
random = math.random,
sin = math.sin,
sinh = math.sinh,
sqrt = math.sqrt,
tan = math.tan,
tanh = math.tanh,
},
table = {
insert = table.insert,
maxn = table.maxn,
remove = table.remove,
sort = table.sort
},
event = event,
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
}
env._G = env
@ -361,7 +462,11 @@ local function create_sandbox(code, env)
return nil, "Binary code prohibited."
end
local f, msg = loadstring(code)
<<<<<<< HEAD
if not f then return nil, msg end
=======
if not f then return _, msg end
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
setfenv(f, env)
return function(...)
@ -403,10 +508,17 @@ local function run(pos, event)
-- Create environment
local env = create_environment(pos, mem, event)
<<<<<<< HEAD
-- Create the sandbox and execute code
local f, msg = create_sandbox(code, env)
if not f then return msg end
local success, msg = pcall(f)
=======
-- create the sandbox and execute code
local chunk, msg = create_sandbox (code, env)
if not chunk then return msg end
local success, msg = pcall(chunk)
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
if not success then return msg end
if type(env.port) ~= "table" then
return "Ports set are invalid."
@ -550,6 +662,7 @@ for d = 0, 1 do
"jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png"
},
<<<<<<< HEAD
inventory_image = top,
paramtype = "light",
groups = groups,
@ -576,6 +689,41 @@ for d = 0, 1 do
end,
is_luacontroller = true,
})
=======
inventory_image = top,
paramtype = "light",
groups = groups,
drop = BASENAME.."0000",
sunlight_propagates = true,
selection_box = selectionbox,
node_box = nodebox,
on_construct = reset_meta,
on_receive_fields = function(pos, formname, fields)
if not fields.program then
return
end
reset(pos)
reset_meta(pos, fields.code)
local err = lc_update(pos, {type="program"})
if err then
print(err)
reset_meta(pos, fields.code, err)
end
end,
sounds = default.node_sound_stone_defaults(),
mesecons = mesecons,
digiline = digiline,
virtual_portstates = { a = a == 1, -- virtual portstates are
b = b == 1, -- the ports the the
c = c == 1, -- controller powers itself
d = d == 1},-- so those that light up
after_dig_node = function (pos, node)
mesecon.receptor_off(pos, output_rules)
end,
is_luacontroller = true,
})
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
end
end
end

View File

@ -67,7 +67,11 @@ minetest.register_node("mesecons_movestones:movestone", {
local direction=mesecon.get_movestone_direction(pos)
if not direction then return end
minetest.remove_node(pos)
<<<<<<< HEAD
mesecon.on_dignode(pos, node)
=======
mesecon.update_autoconnect(pos)
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
minetest.add_entity(pos, "mesecons_movestones:movestone_entity")
end
}}
@ -151,7 +155,11 @@ minetest.register_node("mesecons_movestones:sticky_movestone", {
local direction=mesecon.get_movestone_direction(pos)
if not direction then return end
minetest.remove_node(pos)
<<<<<<< HEAD
mesecon.on_dignode(pos, node)
=======
mesecon.update_autoconnect(pos)
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
minetest.add_entity(pos, "mesecons_movestones:sticky_movestone_entity")
end
}}
@ -188,8 +196,12 @@ minetest.register_entity("mesecons_movestones:sticky_movestone_entity", {
if name ~= "air" and name ~= "ignore"
and ((not minetest.registered_nodes[name])
or minetest.registered_nodes[name].liquidtype == "none") then
<<<<<<< HEAD
mesecon.mvps_push(pos, self.lastdir,
mesecon.setting("movestone_max_push", 50))
=======
mesecon.mvps_push(pos, self.lastdir, MOVESTONE_MAXIMUM_PUSH)
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
--STICKY
mesecon.mvps_pull_all(pos, self.lastdir)
end
@ -201,7 +213,11 @@ minetest.register_entity("mesecons_movestones:sticky_movestone_entity", {
end
local success, stack, oldstack =
<<<<<<< HEAD
mesecon.mvps_push(pos, direction, mesecon.setting("movestone_max_push", 50))
=======
mesecon.mvps_push(pos, direction, MOVESTONE_MAXIMUM_PUSH)
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
if not success then -- Too large stack/stopper in the way
local nn = {name="mesecons_movestones:sticky_movestone"}
minetest.add_node(pos, nn)

View File

@ -94,7 +94,11 @@ function mesecon.mvps_push(pos, dir, maximum) -- pos: pos of mvps; dir: directio
-- add nodes
for _, n in ipairs(nodes) do
<<<<<<< HEAD
local np = mesecon.addPosRule(n.pos, dir)
=======
np = mesecon.addPosRule(n.pos, dir)
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
minetest.add_node(np, n.node)
minetest.get_meta(np):from_table(n.meta)
end
@ -123,8 +127,13 @@ mesecon.register_on_mvps_move(function(moved_nodes)
end)
function mesecon.mvps_pull_single(pos, dir) -- pos: pos of mvps; direction: direction of pull (matches push direction for sticky pistons)
<<<<<<< HEAD
local np = mesecon.addPosRule(pos, dir)
local nn = minetest.get_node(np)
=======
np = mesecon.addPosRule(pos, dir)
nn = minetest.get_node(np)
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
if ((not minetest.registered_nodes[nn.name]) --unregistered node
or minetest.registered_nodes[nn.name].liquidtype == "none") --non-liquid node

View File

@ -55,8 +55,13 @@ piston_get_direction = function(dir, node)
end
local piston_remove_pusher = function(pos, node)
<<<<<<< HEAD
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
local dir = piston_get_direction(pistonspec.dir, node)
=======
pistonspec = minetest.registered_nodes[node.name].mesecons_piston
dir = piston_get_direction(pistonspec.dir, node)
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
local pusherpos = mesecon.addPosRule(pos, dir)
local pushername = minetest.get_node(pusherpos).name
@ -100,9 +105,15 @@ local piston_off = function(pos, node)
piston_remove_pusher(pos, node)
if pistonspec.sticky then
<<<<<<< HEAD
local dir = piston_get_direction(pistonspec.dir, node)
local pullpos = mesecon.addPosRule(pos, dir)
local stack = mesecon.mvps_pull_single(pullpos, dir)
=======
dir = piston_get_direction(pistonspec.dir, node)
pullpos = mesecon.addPosRule(pos, dir)
stack = mesecon.mvps_pull_single(pullpos, dir)
>>>>>>> b86fd8cfa9dadcc359b95cdc1135488beae0f467
mesecon.mvps_process_stack(pos, dir, stack)
end
end

1
mods/pipeworks/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*~

17
mods/pipeworks/LICENSE Normal file
View File

@ -0,0 +1,17 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
----------
This license is commonly known as "WTFPL".

22
mods/pipeworks/README Normal file
View File

@ -0,0 +1,22 @@
This mod uses nodeboxes to supply a complete set of 3D pipes and tubes,
along devices that work with them.
See http://vanessae.github.io/pipeworks/ for detailed information about usage of this mod.
Unlike the previous version of this mod, these pipes are rounded, and when
placed, they'll automatically join together as needed. Pipes can go vertically
or horizontally, and there are enough nodes defined to allow for all possible
connections. Valves and pumps can only be placed horizontally, and will
automatically rotate and join with neighboring pipes as objects are added, as
well as joining with each other under certain circumstances.
Pipes come in two variants: one type bears one or more dark windows on each
pipe, suggesting they're empty, while the other type bears green-tinted
windows, as if full (the two colors should also be easy to select if you want
to change them in a paint program). These windows only appear on straight
lengths and on certain junctions.
This mod is a work in progress.
Please note that owing to the nature of this mod, I have opted to use 64px
textures. Anything less just looks terrible.

View File

@ -0,0 +1,184 @@
local autocrafterCache = {} -- caches some recipe data to avoid to call the slow function minetest.get_craft_result() every second
local function make_inventory_cache(invlist)
local l = {}
for _, stack in ipairs(invlist) do
l[stack:get_name()] = (l[stack:get_name()] or 0) + stack:get_count()
end
return l
end
local function autocraft(inventory, pos)
local recipe = inventory:get_list("recipe")
local recipe_last
local result
local new
if autocrafterCache[minetest.hash_node_position(pos)] == nil then
recipe_last = {}
for i = 1, 9 do
recipe_last[i] = recipe[i]
recipe[i] = ItemStack({name = recipe[i]:get_name(), count = 1})
end
result, new = minetest.get_craft_result({method = "normal", width = 3, items = recipe})
autocrafterCache[minetest.hash_node_position(pos)] = {["recipe"] = recipe, ["result"] = result, ["new"] = new}
else
local autocrafterCacheEntry = autocrafterCache[minetest.hash_node_position(pos)]
recipe_last = autocrafterCacheEntry["recipe"]
result = autocrafterCacheEntry["result"]
new = autocrafterCacheEntry["new"]
local recipeUnchanged = true
for i = 1, 9 do
if recipe[i]:get_name() ~= recipe_last[i]:get_name() then
recipeUnchanged = false
break
end
if recipe[i]:get_count() ~= recipe_last[i]:get_count() then
recipeUnchanged = false
break
end
end
if recipeUnchanged then
else
for i = 1, 9 do
recipe_last[i] = recipe[i]
recipe[i] = ItemStack({name = recipe[i]:get_name(), count = 1})
end
result, new = minetest.get_craft_result({method = "normal", width = 3, items = recipe})
autocrafterCache[minetest.hash_node_position(pos)] = {["recipe"] = recipe, ["result"] = result, ["new"] = new}
end
end
if result.item:is_empty() then return end
result = result.item
if not inventory:room_for_item("dst", result) then return end
local to_use = {}
for _, item in ipairs(recipe) do
if item~= nil and not item:is_empty() then
if to_use[item:get_name()] == nil then
to_use[item:get_name()] = 1
else
to_use[item:get_name()] = to_use[item:get_name()]+1
end
end
end
local invcache = make_inventory_cache(inventory:get_list("src"))
for itemname, number in pairs(to_use) do
if (not invcache[itemname]) or invcache[itemname] < number then return end
end
for itemname, number in pairs(to_use) do
for i = 1, number do -- We have to do that since remove_item does not work if count > stack_max
inventory:remove_item("src", ItemStack(itemname))
end
end
inventory:add_item("dst", result)
for i = 1, 9 do
inventory:add_item("dst", new.items[i])
end
end
local function update_autocrafter(pos)
local meta = minetest.get_meta(pos)
if meta:get_string("virtual_items") == "" then
meta:set_string("virtual_items", "1")
local inv = meta:get_inventory()
for _, stack in ipairs(inv:get_list("recipe")) do
minetest.item_drop(stack, "", pos)
end
end
end
minetest.register_node("pipeworks:autocrafter", {
description = "Autocrafter",
drawtype = "normal",
tiles = {"pipeworks_autocrafter.png"},
groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1},
tube = {insert_object = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:add_item("src", stack)
end,
can_insert = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:room_for_item("src", stack)
end,
input_inventory = "dst",
connect_sides = {left = 1, right = 1, front = 1, back = 1, top = 1, bottom = 1}},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec",
"size[8,11]"..
"list[current_name;recipe;0,0;3,3;]"..
"list[current_name;src;0,3.5;8,3;]"..
"list[current_name;dst;4,0;4,3;]"..
"list[current_player;main;0,7;8,4;]")
meta:set_string("infotext", "Autocrafter")
meta:set_string("virtual_items", "1")
local inv = meta:get_inventory()
inv:set_size("src", 3*8)
inv:set_size("recipe", 3*3)
inv:set_size("dst", 4*3)
end,
on_punch = update_autocrafter,
can_dig = function(pos, player)
update_autocrafter(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return (inv:is_empty("src") and inv:is_empty("dst"))
end,
after_place_node = function(pos)
pipeworks.scan_for_tube_objects(pos)
end,
after_dig_node = function(pos)
pipeworks.scan_for_tube_objects(pos)
autocrafterCache[minetest.hash_node_position(pos)] = nil
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
update_autocrafter(pos)
local inv = minetest.get_meta(pos):get_inventory()
if listname == "recipe" then
local stack_copy = ItemStack(stack)
stack_copy:set_count(1)
inv:set_stack(listname, index, stack_copy)
return 0
else
return stack:get_count()
end
end,
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
update_autocrafter(pos)
local inv = minetest.get_meta(pos):get_inventory()
if listname == "recipe" then
inv:set_stack(listname, index, ItemStack(""))
return 0
else
return stack:get_count()
end
end,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
update_autocrafter(pos)
local inv = minetest.get_meta(pos):get_inventory()
local stack = inv:get_stack(from_list, from_index)
stack:set_count(count)
if from_list == "recipe" then
inv:set_stack(from_list, from_index, ItemStack(""))
return 0
elseif to_list == "recipe" then
local stack_copy = ItemStack(stack)
stack_copy:set_count(1)
inv:set_stack(to_list, to_index, stack_copy)
return 0
else
return stack:get_count()
end
end,
})
minetest.register_abm({nodenames = {"pipeworks:autocrafter"}, interval = 1, chance = 1,
action = function(pos, node)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
autocraft(inv, pos)
end
})

View File

@ -0,0 +1,200 @@
-- autorouting for pipes
local tube_table = {[0] = 1, 2, 2, 4, 2, 4, 4, 5, 2, 3, 4, 6, 4, 6, 5, 7, 2, 4, 3, 6, 4, 5, 6, 7, 4, 6, 6, 8, 5, 7, 7, 9, 2, 4, 4, 5, 3, 6, 6, 7, 4, 6, 5, 7, 6, 8, 7, 9, 4, 5, 6, 7, 6, 7, 8, 9, 5, 7, 7, 9, 7, 9, 9, 10}
local tube_table_facedirs = {[0] = 0, 0, 5, 0, 3, 4, 3, 0, 2, 0, 2, 0, 6, 4, 3, 0, 7, 12, 5, 12, 7, 4, 5, 5, 18, 20, 16, 0, 7, 4, 7, 0, 1, 8, 1, 1, 1, 13, 1, 1, 10, 8, 2, 2, 17, 4, 3, 6, 9, 9, 9, 9, 21, 13, 1, 1, 10, 10, 11, 2, 19, 4, 3, 0}
local function autoroute_pipes(pos)
local nctr = minetest.get_node(pos)
local state = "_empty"
if (string.find(nctr.name, "pipeworks:pipe_") == nil) then return end
if (string.find(nctr.name, "_loaded") ~= nil) then state = "_loaded" end
local nsurround = pipeworks.scan_pipe_surroundings(pos)
if nsurround == 0 then nsurround = 9 end
minetest.add_node(pos, {name = "pipeworks:pipe_"..tube_table[nsurround]..state,
param2 = tube_table_facedirs[nsurround]})
end
function pipeworks.scan_for_pipe_objects(pos)
autoroute_pipes({ x=pos.x-1, y=pos.y , z=pos.z })
autoroute_pipes({ x=pos.x+1, y=pos.y , z=pos.z })
autoroute_pipes({ x=pos.x , y=pos.y-1, z=pos.z })
autoroute_pipes({ x=pos.x , y=pos.y+1, z=pos.z })
autoroute_pipes({ x=pos.x , y=pos.y , z=pos.z-1 })
autoroute_pipes({ x=pos.x , y=pos.y , z=pos.z+1 })
autoroute_pipes(pos)
end
-- auto-rotation code for various devices the tubes attach to
function pipeworks.scan_pipe_surroundings(pos)
local pxm=0
local pxp=0
local pym=0
local pyp=0
local pzm=0
local pzp=0
local nxm = minetest.get_node({ x=pos.x-1, y=pos.y , z=pos.z })
local nxp = minetest.get_node({ x=pos.x+1, y=pos.y , z=pos.z })
local nym = minetest.get_node({ x=pos.x , y=pos.y-1, z=pos.z })
local nyp = minetest.get_node({ x=pos.x , y=pos.y+1, z=pos.z })
local nzm = minetest.get_node({ x=pos.x , y=pos.y , z=pos.z-1 })
local nzp = minetest.get_node({ x=pos.x , y=pos.y , z=pos.z+1 })
if (string.find(nxm.name, "pipeworks:pipe_") ~= nil) then pxm=1 end
if (string.find(nxp.name, "pipeworks:pipe_") ~= nil) then pxp=1 end
if (string.find(nym.name, "pipeworks:pipe_") ~= nil) then pym=1 end
if (string.find(nyp.name, "pipeworks:pipe_") ~= nil) then pyp=1 end
if (string.find(nzm.name, "pipeworks:pipe_") ~= nil) then pzm=1 end
if (string.find(nzp.name, "pipeworks:pipe_") ~= nil) then pzp=1 end
-- Special handling for valves...
if (string.find(nxm.name, "pipeworks:valve") ~= nil)
and (nxm.param2 == 0 or nxm.param2 == 2) then
pxm=1
end
if (string.find(nxp.name, "pipeworks:valve") ~= nil)
and (nxp.param2 == 0 or nxp.param2 == 2) then
pxp=1
end
if (string.find(nzm.name, "pipeworks:valve") ~= nil)
and (nzm.param2 == 1 or nzm.param2 == 3) then
pzm=1
end
if (string.find(nzp.name, "pipeworks:valve") ~= nil)
and (nzp.param2 == 1 or nzp.param2 == 3) then
pzp=1
end
-- ...flow sensors...
if (string.find(nxm.name, "pipeworks:flow_sensor") ~= nil)
and (nxm.param2 == 0 or nxm.param2 == 2) then
pxm=1
end
if (string.find(nxp.name, "pipeworks:flow_sensor") ~= nil)
and (nxp.param2 == 0 or nxp.param2 == 2) then
pxp=1
end
if (string.find(nzm.name, "pipeworks:flow_sensor") ~= nil)
and (nzm.param2 == 1 or nzm.param2 == 3) then
pzm=1
end
if (string.find(nzp.name, "pipeworks:flow_sensor") ~= nil)
and (nzp.param2 == 1 or nzp.param2 == 3) then
pzp=1
end
-- ...spigots...
if (string.find(nxm.name, "pipeworks:spigot") ~= nil)
and nxm.param2 == 1 then
pxm=1
end
if (string.find(nxp.name, "pipeworks:spigot") ~= nil)
and nxp.param2 == 3 then
pxp=1
end
if (string.find(nzm.name, "pipeworks:spigot") ~= nil)
and nzm.param2 == 0 then
pzm=1
end
if (string.find(nzp.name, "pipeworks:spigot") ~= nil)
and nzp.param2 == 2 then
pzp=1
end
-- ...sealed pipe entry/exit...
if (string.find(nxm.name, "pipeworks:entry_panel") ~= nil)
and (nxm.param2 == 1 or nxm.param2 == 3) then
pxm=1
end
if (string.find(nxp.name, "pipeworks:entry_panel") ~= nil)
and (nxp.param2 == 1 or nxp.param2 == 3) then
pxp=1
end
if (string.find(nzm.name, "pipeworks:entry_panel") ~= nil)
and (nzm.param2 == 0 or nzm.param2 == 2) then
pzm=1
end
if (string.find(nzp.name, "pipeworks:entry_panel") ~= nil)
and (nzp.param2 == 0 or nzp.param2 == 2) then
pzp=1
end
if (string.find(nym.name, "pipeworks:entry_panel") ~= nil)
and nym.param2 == 13 then
pym=1
end
if (string.find(nyp.name, "pipeworks:entry_panel") ~= nil)
and nyp.param2 == 13 then
pyp=1
end
-- ...pumps, grates...
if (string.find(nym.name, "pipeworks:grating") ~= nil) or
(string.find(nym.name, "pipeworks:pump") ~= nil) then
pym=1
end
-- ...fountainheads...
if (string.find(nyp.name, "pipeworks:fountainhead") ~= nil) then
pyp=1
end
-- ... and storage tanks.
if (string.find(nym.name, "pipeworks:storage_tank_") ~= nil) then
pym=1
end
if (string.find(nyp.name, "pipeworks:storage_tank_") ~= nil) then
pyp=1
end
-- ...extra devices specified via the function's parameters
-- ...except that this part is not implemented yet
--
-- xxx = nxm, nxp, nym, nyp, nzm, or nzp depending on the direction to check
-- yyy = pxm, pxp, pym, pyp, pzm, or pzp accordingly.
--
-- if string.find(xxx.name, "modname:nodename") ~= nil then
-- yyy = 1
-- end
--
-- for example:
--
-- if string.find(nym.name, "aero:outlet") ~= nil then
-- pym = 1
-- end
--
return pxm+8*pxp+2*pym+16*pyp+4*pzm+32*pzp
end
function pipeworks.look_for_stackable_tanks(pos)
local tym = minetest.get_node({ x=pos.x , y=pos.y-1, z=pos.z })
if string.find(tym.name, "pipeworks:storage_tank_") ~= nil or
string.find(tym.name, "pipeworks:expansion_tank_") ~= nil then
minetest.add_node(pos, { name = "pipeworks:expansion_tank_0", param2 = tym.param2})
end
end

View File

@ -0,0 +1,130 @@
-- autorouting for pneumatic tubes
local function is_tube(nodename)
return table.contains(pipeworks.tubenodes, nodename)
end
--a function for determining which side of the node we are on
local function nodeside(node, tubedir)
if node.param2 < 0 or node.param2 > 23 then
node.param2 = 0
end
local backdir = minetest.facedir_to_dir(node.param2)
local back = vector.dot(backdir, tubedir)
if back == 1 then
return "back"
elseif back == -1 then
return "front"
end
local topdir = minetest.facedir_to_top_dir(node.param2)
local top = vector.dot(topdir, tubedir)
if top == 1 then
return "top"
elseif top == -1 then
return "bottom"
end
local rightdir = minetest.facedir_to_right_dir(node.param2)
local right = vector.dot(rightdir, tubedir)
if right == 1 then
return "right"
else
return "left"
end
end
local vts = {0, 3, 1, 4, 2, 5}
local tube_table = {[0] = 1, 2, 2, 4, 2, 4, 4, 5, 2, 3, 4, 6, 4, 6, 5, 7, 2, 4, 3, 6, 4, 5, 6, 7, 4, 6, 6, 8, 5, 7, 7, 9, 2, 4, 4, 5, 3, 6, 6, 7, 4, 6, 5, 7, 6, 8, 7, 9, 4, 5, 6, 7, 6, 7, 8, 9, 5, 7, 7, 9, 7, 9, 9, 10}
local tube_table_facedirs = {[0] = 0, 0, 5, 0, 3, 4, 3, 0, 2, 0, 2, 0, 6, 4, 3, 0, 7, 12, 5, 12, 7, 4, 5, 5, 18, 20, 16, 0, 7, 4, 7, 0, 1, 8, 1, 1, 1, 13, 1, 1, 10, 8, 2, 2, 17, 4, 3, 6, 9, 9, 9, 9, 21, 13, 1, 1, 10, 10, 11, 2, 19, 4, 3, 0}
local function tube_autoroute(pos)
local active = {0, 0, 0, 0, 0, 0}
local nctr = minetest.get_node(pos)
if not is_tube(nctr.name) then return end
local adjustments = {
{x = -1, y = 0, z = 0},
{x = 1, y = 0, z = 0},
{x = 0, y = -1, z = 0},
{x = 0, y = 1, z = 0},
{x = 0, y = 0, z = -1},
{x = 0, y = 0, z = 1}
}
-- xm = 1, xp = 2, ym = 3, yp = 4, zm = 5, zp = 6
local positions = {}
local nodes = {}
for i, adj in ipairs(adjustments) do
positions[i] = vector.add(pos, adj)
nodes[i] = minetest.get_node(positions[i])
end
for i, node in ipairs(nodes) do
local idef = minetest.registered_nodes[node.name]
-- handle the tubes themselves
if is_tube(node.name) then
active[i] = 1
-- handle new style connectors
elseif idef and idef.tube and idef.tube.connect_sides then
local dir = adjustments[i]
if idef.tube.connect_sides[nodeside(node, vector.multiply(dir, -1))] then
active[i] = 1
end
end
end
-- all sides checked, now figure which tube to use.
local nodedef = minetest.registered_nodes[nctr.name]
local basename = nodedef.basename
if nodedef.style == "old" then
local nsurround = ""
for i, n in ipairs(active) do
nsurround = nsurround..n
end
nctr.name = basename.."_"..nsurround
elseif nodedef.style == "6d" then
local s = 0
for i, n in ipairs(active) do
if n == 1 then
s = s + 2^vts[i]
end
end
nctr.name = basename.."_"..tube_table[s]
nctr.param2 = tube_table_facedirs[s]
end
minetest.swap_node(pos, nctr)
end
function pipeworks.scan_for_tube_objects(pos)
for side = 0, 6 do
tube_autoroute(vector.add(pos, directions.side_to_dir(side)))
end
end
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack)
if minetest.registered_items[newnode.name]
and minetest.registered_items[newnode.name].tube
and minetest.registered_items[newnode.name].tube.connect_sides then
pipeworks.scan_for_tube_objects(pos)
end
end)
minetest.register_on_dignode(function(pos, oldnode, digger)
if minetest.registered_items[oldnode.name]
and minetest.registered_items[oldnode.name].tube
and minetest.registered_items[oldnode.name].tube.connect_sides then
pipeworks.scan_for_tube_objects(pos)
end
end)
if minetest.get_modpath("mesecons_mvps") then
mesecon.register_on_mvps_move(function(moved_nodes)
for _, n in ipairs(moved_nodes) do
pipeworks.scan_for_tube_objects(n.pos)
pipeworks.scan_for_tube_objects(n.oldpos)
end
end)
end

View File

@ -0,0 +1,93 @@
Changelog
---------
2013-01-13: Tubes can transport items now! Namely, I added Novatux/Nore's item
transport mod as a default part of this mod, to make tubes do something useful!
Thanks to Nore and RealBadAngel for the code contributions!
2013-01-05: made storage tanks connect from top/bottom, made storage tank and
pipe textures use the ^ combine operator so they can show the actual liquid
going through the pipes/tanks.
2013-01-04 (a bit later): Made pipes able to carry water! It was just a minor
logic error resulting from moving the water flowing code into it's own file
when I originally imported it. Many thanks to Mauvebic for writing it!
2013-01-04: First stage of integrating Mauvebic's water flowing code. This is
experimental and doesn't move water yet - but at least it doesn't break
anything :-)
2013-01-01: Various minor tweaks to textures, facedir settings, some other
stuff. Changed crafting recipes to account for revamped pumps, valves, etc.
Now requires the moreores mod and most recent git (for mese crystal fragments)
to craft a pump. Added a "sealed" entry/exit panel (really just a horizontal
pipe with a metal panel overlayed into the middle). Also, tweaked pipes to
always drop the empty ones. Revamped pumps so that now they should sit in/on
liquid and be connected only from the top, relegated grates to decorational-
only, added outlet spigot. Got rid of a few obsolete textures. Got rid of
that whole _x and _z naming thing - now all directional devices (pumps, valves,
spigots, tanks) use facedir. Valves, spigots no longer auto-rotate to find
nearby pipes.
2012-09-17: Added test object for pneumatic tube autorouting code, made tubes
connect to it and any object that bears groups={tubedevice=1} (connects to any
side)
2012-09-05: All recipes doubled except for junglegrass -> plastic sheet (since
that is derived from home decor)
2012-09-02: Fixed plastic sheeting recipe. Added crafting recipes for various
objects, with options: If homedecor is installed, use the plastic sheeting
therein. If not, we define it manually. If the Technic mod is installed,
don't define any recipes at all. Also removed the extra "loaded!" messages and
tweaked the default pipe alias to point to something that is actually visible
:-)
2012-09-01: flattened wielded pipe segment.
2012-08-24: Added square-ish pneumatic tubes with their own autoplace code
(does not connect to steel pipes or pipe-oriented devices), then revised their
textures shortly after. Fixed a recursion bug that sometimes caused a stack
overflow. Old pipes were overriding the pipeworks:pipe defintion that belongs
with the new pipes.
2012-08-22: Added outlet grate, made it participate in autoplace algorithm.
Extended storage tank to show fill level in 10% steps (0% to 100%). Added
"expansion tank" that appears if the user stacks tanks upwards. (Downwards is
not checked).
2012-08-21: Made storage tank participate in autoplace algorithm. Tuned API a
little to allow for more flexible placement. Re-organized code a bit to allow
for some upcoming rules changes. Made storage tanks' upper/lower fittins and
intake grate participate in autoplace algorithm.
2012-08-20: Added temporary nodes for storage tank and intake grating, but
without autoplace.
2012-08-19: Pumps and valves now fully participate in the
auto-rotate/auto-place algorithm.
2012-08-18: Total rewrite again. All pipes are now nice and round-looking, and
they auto-connect! Also added temporary nodes for pump and valve (each with an
on/off setting - punch to change). No crafting recipes yet and the pipes still
don't do anything useful yet. Soon.
2012-08-06: Moved this changelog off the forum post and into a separate file.
2012-08-05 (multiple updates): Rewrote pipeworks to use loops and tables to
create the nodes. Requires far less code now. Added -X, +X, -Y, +Y, -Z, +Z
capped stubs and a short centered horizontal segment. Changed node definitions
so that the aforementioned "short centered" segment is given on dig/drop.
Renamed it to just "pipeworks:pipe" (and pipe_loaded). Added empty/loaded
indicator images to the capped ends, removed some redundant comments. Made the
empty/loaded indication at the capped end more prominent.
2012-07-21: Added screenshot showing pipes as they look now that nodebox
texture rotation is fixed.
2012-07-18: Changed the mod name and all internals to 'pipeworks' instead of
'pipes'... after a couple of mistakes :-)
2012-07-12: moved project to github.
2012-06-23: Initial release, followed by reworking the textures a bit.

146
mods/pipeworks/common.lua Normal file
View File

@ -0,0 +1,146 @@
----------------------
-- Vector functions --
----------------------
function vector.cross(a, b)
return {
x = a.y * b.z - a.z * b.y,
y = a.z * b.x - a.x * b.z,
z = a.x * b.y - a.y * b.x
}
end
function vector.dot(a, b)
return a.x * b.x + a.y * b.y + a.z * b.z
end
-----------------------
-- Facedir functions --
-----------------------
function minetest.facedir_to_top_dir(facedir)
return ({[0] = {x = 0, y = 1, z = 0},
{x = 0, y = 0, z = 1},
{x = 0, y = 0, z = -1},
{x = 1, y = 0, z = 0},
{x = -1, y = 0, z = 0},
{x = 0, y = -1, z = 0}})
[math.floor(facedir / 4)]
end
function minetest.facedir_to_right_dir(facedir)
return vector.cross(
minetest.facedir_to_top_dir(facedir),
minetest.facedir_to_dir(facedir)
)
end
directions = {}
function directions.side_to_dir(side)
return ({[0] = vector.new(),
vector.new( 0, 1, 0),
vector.new( 0, -1, 0),
vector.new( 1, 0, 0),
vector.new(-1, 0, 0),
vector.new( 0, 0, 1),
vector.new( 0, 0, -1)
})[side]
end
function directions.dir_to_side(dir)
local c = vector.dot(dir, vector.new(1, 2, 3)) + 4
return ({6, 2, 4, 0, 3, 1, 5})[c]
end
----------------------
-- String functions --
----------------------
--[[function string.split(str, sep)
local fields = {}
local index = 1
local expr = "([^"..sep.."])+"
string.gsub(str, expr, function(substring)
fields[index] = substring
index = index + 1
end)
return fields
end]]
function string.startswith(str, substr)
return str:sub(1, substr:len()) == substr
end
---------------------
-- Table functions --
---------------------
function table.contains(tbl, element)
for _, elt in pairs(tbl) do
if elt == element then
return true
end
end
return false
end
function table.extend(tbl, tbl2)
local index = #tbl + 1
for _, elt in ipairs(tbl2) do
tbl[index] = elt
index = index + 1
end
end
function table.recursive_replace(tbl, pattern, replace_with)
if type(tbl) == "table" then
local tbl2 = {}
for key, value in pairs(tbl) do
tbl2[key] = table.recursive_replace(value, pattern, replace_with)
end
return tbl2
elseif type(tbl) == "string" then
return tbl:gsub(pattern, replace_with)
else
return tbl
end
end
------------------------
-- Formspec functions --
------------------------
fs_helpers = {}
function fs_helpers.on_receive_fields(pos, fields)
local meta = minetest.get_meta(pos)
for field, value in pairs(fields) do
if field:startswith("fs_helpers_cycling:") then
local l = field:split(":")
local new_value = tonumber(l[2])
local meta_name = l[3]
meta:set_int(meta_name, new_value)
end
end
end
function fs_helpers.cycling_button(meta, base, meta_name, values)
local current_value = meta:get_int(meta_name)
local new_value = (current_value + 1) % (#values)
local text = values[current_value + 1]
local field = "fs_helpers_cycling:"..new_value..":"..meta_name
return base..";"..field..";"..minetest.formspec_escape(text).."]"
end
---------
-- Env --
---------
function minetest.load_position(pos)
if pos.x < -30912 or pos.y < -30912 or pos.z < -30912 or
pos.x > 30927 or pos.y > 30927 or pos.z > 30927 then return end
if minetest.get_node_or_nil(pos) then
return
end
local vm = minetest.get_voxel_manip()
vm:read_from_map(pos, pos)
end

130
mods/pipeworks/compat.lua Normal file
View File

@ -0,0 +1,130 @@
-- this bit of code modifies the default chests and furnaces to be compatible
-- with pipeworks.
minetest.override_item("default:furnace", {
tiles = {
"default_furnace_top.png^pipeworks_tube_connection_stony.png",
"default_furnace_bottom.png^pipeworks_tube_connection_stony.png",
"default_furnace_side.png^pipeworks_tube_connection_stony.png",
"default_furnace_side.png^pipeworks_tube_connection_stony.png",
"default_furnace_side.png^pipeworks_tube_connection_stony.png",
"default_furnace_front.png"
},
groups = {cracky = 2, tubedevice = 1, tubedevice_receiver = 1},
tube = {
insert_object = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if direction.y == 1 then
return inv:add_item("fuel",stack)
else
return inv:add_item("src",stack)
end
end,
can_insert = function(pos,node,stack,direction)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if direction.y == 1 then
return inv:room_for_item("fuel", stack)
else
return inv:room_for_item("src", stack)
end
end,
input_inventory = "dst",
connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1}
},
})
minetest.override_item("default:furnace_active", {
tiles = {
"default_furnace_top.png^pipeworks_tube_connection_stony.png",
"default_furnace_bottom.png^pipeworks_tube_connection_stony.png",
"default_furnace_side.png^pipeworks_tube_connection_stony.png",
"default_furnace_side.png^pipeworks_tube_connection_stony.png",
"default_furnace_side.png^pipeworks_tube_connection_stony.png",
{
image = "default_furnace_front_active.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 1.5
},
}
},
groups = {cracky = 2, tubedevice = 1, tubedevice_receiver = 1, not_in_creative_inventory = 1},
tube = {
insert_object = function(pos,node,stack,direction)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if direction.y == 1 then
return inv:add_item("fuel", stack)
else
return inv:add_item("src", stack)
end
end,
can_insert = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if direction.y == 1 then
return inv:room_for_item("fuel", stack)
else
return inv:room_for_item("src", stack)
end
end,
input_inventory = "dst",
connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1}
},
})
minetest.override_item("default:chest", {
tiles = {
"default_chest_top.png^pipeworks_tube_connection_wooden.png",
"default_chest_top.png^pipeworks_tube_connection_wooden.png",
"default_chest_side.png^pipeworks_tube_connection_wooden.png",
"default_chest_side.png^pipeworks_tube_connection_wooden.png",
"default_chest_side.png^pipeworks_tube_connection_wooden.png",
"default_chest_front.png"
},
groups = {choppy = 2, oddly_breakable_by_hand = 2, tubedevice = 1, tubedevice_receiver = 1},
tube = {
insert_object = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:add_item("main", stack)
end,
can_insert = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:room_for_item("main", stack)
end,
input_inventory = "main",
connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1}
},
})
minetest.override_item("default:chest_locked", {
tiles = {
"default_chest_top.png^pipeworks_tube_connection_wooden.png",
"default_chest_top.png^pipeworks_tube_connection_wooden.png",
"default_chest_side.png^pipeworks_tube_connection_wooden.png",
"default_chest_side.png^pipeworks_tube_connection_wooden.png",
"default_chest_side.png^pipeworks_tube_connection_wooden.png",
"default_chest_lock.png"
},
groups = {choppy = 2, oddly_breakable_by_hand = 2, tubedevice = 1, tubedevice_receiver = 1},
tube = {
insert_object = function(pos, node, stack, direction)
local meta = minetest.env:get_meta(pos)
local inv = meta:get_inventory()
return inv:add_item("main", stack)
end,
can_insert = function(pos, node, stack, direction)
local meta = minetest.env:get_meta(pos)
local inv = meta:get_inventory()
return inv:room_for_item("main", stack)
end,
connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1}
},
})

321
mods/pipeworks/crafts.lua Normal file
View File

@ -0,0 +1,321 @@
-- Crafting recipes for pipes
minetest.register_craft( {
output = "pipeworks:pipe_1_empty 12",
recipe = {
{ "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" },
{ "", "", "" },
{ "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" }
},
})
minetest.register_craft( {
output = "pipeworks:spigot 3",
recipe = {
{ "pipeworks:pipe_1_empty", "" },
{ "", "pipeworks:pipe_1_empty" },
},
})
minetest.register_craft( {
output = "pipeworks:entry_panel_empty 2",
recipe = {
{ "", "default:steel_ingot", "" },
{ "", "pipeworks:pipe_1_empty", "" },
{ "", "default:steel_ingot", "" },
},
})
-- Various ancillary pipe devices
minetest.register_craft( {
output = "pipeworks:pump_off 2",
recipe = {
{ "default:stone", "default:steel_ingot", "default:stone" },
{ "default:copper_ingot", "default:mese_crystal_fragment", "default:copper_ingot" },
{ "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" }
},
})
minetest.register_craft( {
output = "pipeworks:valve_off_empty 2",
recipe = {
{ "", "group:stick", "" },
{ "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" },
{ "", "default:steel_ingot", "" }
},
})
minetest.register_craft( {
output = "pipeworks:storage_tank_0 2",
recipe = {
{ "", "default:steel_ingot", "default:steel_ingot" },
{ "default:steel_ingot", "default:glass", "default:steel_ingot" },
{ "default:steel_ingot", "default:steel_ingot", "" }
},
})
minetest.register_craft( {
output = "pipeworks:grating 2",
recipe = {
{ "default:steel_ingot", "", "default:steel_ingot" },
{ "", "pipeworks:pipe_1_empty", "" },
{ "default:steel_ingot", "", "default:steel_ingot" }
},
})
minetest.register_craft( {
output = "pipeworks:flow_sensor_empty 2",
recipe = {
{ "pipeworks:pipe_1_empty", "mesecons:mesecon", "pipeworks:pipe_1_empty" },
},
})
minetest.register_craft( {
output = "pipeworks:fountainhead 2",
recipe = {
{ "pipeworks:pipe_1_empty" },
{ "pipeworks:pipe_1_empty" }
},
})
-- Crafting recipes for pneumatic tubes
-- If homedecor is not installed, we need to register its crafting chain for
-- plastic sheeting so that pipeworks remains compatible with it.
if minetest.get_modpath("homedecor") == nil then
minetest.register_craftitem(":homedecor:oil_extract", {
description = "Oil extract",
inventory_image = "homedecor_oil_extract.png",
})
minetest.register_craftitem(":homedecor:paraffin", {
description = "Unprocessed paraffin",
inventory_image = "homedecor_paraffin.png",
})
minetest.register_alias("homedecor:plastic_base", "homedecor:paraffin")
minetest.register_craftitem(":homedecor:plastic_sheeting", {
description = "Plastic sheet",
inventory_image = "homedecor_plastic_sheeting.png",
})
minetest.register_craft({
type = "shapeless",
output = "homedecor:oil_extract 4",
recipe = {
"group:leaves",
"group:leaves",
"group:leaves",
"group:leaves",
"group:leaves",
"group:leaves"
}
})
minetest.register_craft({
type = "cooking",
output = "homedecor:paraffin",
recipe = "homedecor:oil_extract",
})
minetest.register_craft({
type = "cooking",
output = "homedecor:plastic_sheeting",
recipe = "homedecor:paraffin",
})
minetest.register_craft({
type = "fuel",
recipe = "homedecor:oil_extract",
burntime = 30,
})
minetest.register_craft({
type = "fuel",
recipe = "homedecor:paraffin",
burntime = 30,
})
minetest.register_craft({
type = "fuel",
recipe = "homedecor:plastic_sheeting",
burntime = 30,
})
end
minetest.register_craft( {
output = "pipeworks:one_way_tube 2",
recipe = {
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" },
{ "group:stick", "default:mese_crystal", "homedecor:plastic_sheeting" },
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }
},
})
minetest.register_craft( {
output = "pipeworks:tube_1 6",
recipe = {
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" },
{ "", "", "" },
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }
},
})
minetest.register_craft( {
output = "pipeworks:mese_tube_1 2",
recipe = {
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" },
{ "", "default:mese_crystal", "" },
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }
},
})
minetest.register_craft( {
type = "shapeless",
output = "pipeworks:mese_tube_000000",
recipe = {
"pipeworks:tube_1",
"default:mese_crystal_fragment",
"default:mese_crystal_fragment",
"default:mese_crystal_fragment",
"default:mese_crystal_fragment"
},
})
minetest.register_craft( {
output = "pipeworks:conductor_tube_off_1 6",
recipe = {
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" },
{ "mesecons:mesecon", "mesecons:mesecon", "mesecons:mesecon" },
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }
},
})
minetest.register_craft( {
output = "pipeworks:detector_tube_off_1 2",
recipe = {
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" },
{ "mesecons:mesecon", "mesecons_materials:silicon", "mesecons:mesecon" },
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }
},
})
minetest.register_craft( {
output = "pipeworks:accelerator_tube_1 2",
recipe = {
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" },
{ "default:mese_crystal_fragment", "default:steel_ingot", "default:mese_crystal_fragment" },
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }
},
})
minetest.register_craft( {
output = "pipeworks:teleport_tube_1 2",
recipe = {
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" },
{ "default:desert_stone", "default:mese_block", "default:desert_stone" },
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }
},
})
minetest.register_craft( {
output = "pipeworks:sand_tube_1 2",
recipe = {
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" },
{ "default:sand", "default:sand", "default:sand" },
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }
},
})
minetest.register_craft( {
output = "pipeworks:sand_tube_1 2",
recipe = {
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" },
{ "default:desert_sand", "default:desert_sand", "default:desert_sand" },
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }
},
})
minetest.register_craft( {
output = "pipeworks:sand_tube_1",
recipe = {
{ "default:desert_sand", "pipeworks:tube_1", "default:desert_sand" },
},
})
minetest.register_craft( {
output = "pipeworks:mese_sand_tube_1 2",
recipe = {
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" },
{ "default:sand", "default:mese_crystal", "default:sand" },
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }
},
})
minetest.register_craft( {
output = "pipeworks:mese_sand_tube_1 2",
recipe = {
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" },
{ "default:desert_sand", "default:mese_crystal", "default:desert_sand" },
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }
},
})
minetest.register_craft( {
output = "pipeworks:crossing_tube_1 5",
recipe = {
{ "", "pipeworks:tube_1", "" },
{ "pipeworks:tube_1", "pipeworks:tube_1", "pipeworks:tube_1" },
{ "", "pipeworks:tube_1", "" }
},
})
minetest.register_craft( {
type = "shapeless",
output = "pipeworks:mese_sand_tube_1",
recipe = {
"pipeworks:sand_tube_1",
"default:mese_crystal_fragment",
"default:mese_crystal_fragment",
"default:mese_crystal_fragment",
"default:mese_crystal_fragment"
},
})
-- Various ancillary tube devices
minetest.register_craft( {
output = "pipeworks:filter 2",
recipe = {
{ "default:steel_ingot", "default:steel_ingot", "homedecor:plastic_sheeting" },
{ "group:stick", "default:mese_crystal", "homedecor:plastic_sheeting" },
{ "default:steel_ingot", "default:steel_ingot", "homedecor:plastic_sheeting" }
},
})
minetest.register_craft( {
output = "pipeworks:mese_filter 2",
recipe = {
{ "default:steel_ingot", "default:steel_ingot", "homedecor:plastic_sheeting" },
{ "group:stick", "default:mese", "homedecor:plastic_sheeting" },
{ "default:steel_ingot", "default:steel_ingot", "homedecor:plastic_sheeting" }
},
})
minetest.register_craft( {
output = "pipeworks:autocrafter 2",
recipe = {
{ "default:steel_ingot", "default:mese_crystal", "default:steel_ingot" },
{ "homedecor:plastic_sheeting", "default:steel_ingot", "homedecor:plastic_sheeting" },
{ "default:steel_ingot", "default:mese_crystal", "default:steel_ingot" }
},
})

View File

@ -0,0 +1,19 @@
-- Various settings
pipeworks.enable_pipes = true
pipeworks.enable_autocrafter = true
pipeworks.enable_deployer = true
pipeworks.enable_dispenser = true
pipeworks.enable_node_breaker = true
pipeworks.enable_teleport_tube = true
pipeworks.enable_pipe_devices = true
pipeworks.enable_redefines = true
pipeworks.enable_mese_tube = true
pipeworks.enable_detector_tube = true
pipeworks.enable_conductor_tube = true
pipeworks.enable_accelerator_tube = true
pipeworks.enable_crossing_tube = true
pipeworks.enable_sand_tube = true
pipeworks.enable_mese_sand_tube = true
pipeworks.enable_one_way_tube = true
pipeworks.enable_cyclic_mode = true

View File

@ -0,0 +1,3 @@
default
mesecons?
mesecons_mvps?

702
mods/pipeworks/devices.lua Normal file
View File

@ -0,0 +1,702 @@
-- List of devices that should participate in the autoplace algorithm
local pipereceptor_on = nil
local pipereceptor_off = nil
if mesecon then
pipereceptor_on = {
receptor = {
state = mesecon.state.on,
rules = pipeworks.mesecons_rules
}
}
pipereceptor_off = {
receptor = {
state = mesecon.state.off,
rules = pipeworks.mesecons_rules
}
}
end
local pipes_devicelist = {
"pump",
"valve",
"storage_tank_0",
"storage_tank_1",
"storage_tank_2",
"storage_tank_3",
"storage_tank_4",
"storage_tank_5",
"storage_tank_6",
"storage_tank_7",
"storage_tank_8",
"storage_tank_9",
"storage_tank_10"
}
-- Now define the nodes.
local states = { "on", "off" }
local dgroups = ""
local pumpboxes = {}
for s in ipairs(states) do
if states[s] == "off" then
dgroups = {snappy=3, pipe=1}
else
dgroups = {snappy=3, pipe=1, not_in_creative_inventory=1}
end
pumpboxes = {}
pipeworks.add_node_box(pumpboxes, pipeworks.pipe_pumpbody)
pipeworks.add_node_box(pumpboxes, pipeworks.pipe_topstub)
minetest.register_node("pipeworks:pump_"..states[s], {
description = "Pump/Intake Module",
drawtype = "nodebox",
tiles = {
"pipeworks_pump_top.png",
"pipeworks_pump_bottom.png",
"pipeworks_pump_sides.png",
"pipeworks_pump_sides.png",
"pipeworks_pump_sides.png",
"pipeworks_pump_"..states[s]..".png"
},
paramtype = "light",
paramtype2 = "facedir",
selection_box = {
type = "fixed",
fixed = { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }
},
node_box = {
type = "fixed",
fixed = pumpboxes
},
groups = dgroups,
sounds = default.node_sound_wood_defaults(),
walkable = true,
after_place_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
after_dig_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
drop = "pipeworks:pump_off",
mesecons = {effector = {
action_on = function (pos, node)
minetest.add_node(pos,{name="pipeworks:pump_on", param2 = node.param2})
end,
action_off = function (pos, node)
minetest.add_node(pos,{name="pipeworks:pump_off", param2 = node.param2})
end
}},
on_punch = function(pos, node, puncher)
local fdir = minetest.get_node(pos).param2
minetest.add_node(pos, { name = "pipeworks:pump_"..states[3-s], param2 = fdir })
end
})
local valveboxes = {}
pipeworks.add_node_box(valveboxes, pipeworks.pipe_leftstub)
pipeworks.add_node_box(valveboxes, pipeworks.pipe_valvebody)
if states[s] == "off" then
pipeworks.add_node_box(valveboxes, pipeworks.pipe_valvehandle_off)
else
pipeworks.add_node_box(valveboxes, pipeworks.pipe_valvehandle_on)
end
pipeworks.add_node_box(valveboxes, pipeworks.pipe_rightstub)
local tilex = "pipeworks_valvebody_ends.png"
local tilez = "pipeworks_valvebody_sides.png"
minetest.register_node("pipeworks:valve_"..states[s].."_empty", {
description = "Valve",
drawtype = "nodebox",
tiles = {
"pipeworks_valvebody_top_"..states[s]..".png",
"pipeworks_valvebody_bottom.png",
tilex,
tilex,
tilez,
tilez,
},
sunlight_propagates = true,
paramtype = "light",
paramtype2 = "facedir",
selection_box = {
type = "fixed",
fixed = { -8/16, -4/16, -5/16, 8/16, 5/16, 5/16 }
},
node_box = {
type = "fixed",
fixed = valveboxes
},
groups = dgroups,
sounds = default.node_sound_wood_defaults(),
walkable = true,
after_place_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
after_dig_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
drop = "pipeworks:valve_off_empty",
mesecons = {effector = {
action_on = function (pos, node)
minetest.add_node(pos,{name="pipeworks:valve_on_empty", param2 = node.param2})
end,
action_off = function (pos, node)
minetest.add_node(pos,{name="pipeworks:valve_off_empty", param2 = node.param2})
end
}},
on_punch = function(pos, node, puncher)
local fdir = minetest.get_node(pos).param2
minetest.add_node(pos, { name = "pipeworks:valve_"..states[3-s].."_empty", param2 = fdir })
end
})
end
local valveboxes = {}
pipeworks.add_node_box(valveboxes, pipeworks.pipe_leftstub)
pipeworks.add_node_box(valveboxes, pipeworks.pipe_valvebody)
pipeworks.add_node_box(valveboxes, pipeworks.pipe_rightstub)
pipeworks.add_node_box(valveboxes, pipeworks.pipe_valvehandle_on)
minetest.register_node("pipeworks:valve_on_loaded", {
description = "Valve",
drawtype = "nodebox",
tiles = {
"pipeworks_valvebody_top_on.png",
"pipeworks_valvebody_bottom.png",
"pipeworks_valvebody_ends.png",
"pipeworks_valvebody_ends.png",
"pipeworks_valvebody_sides.png",
"pipeworks_valvebody_sides.png",
},
sunlight_propagates = true,
paramtype = "light",
paramtype2 = "facedir",
selection_box = {
type = "fixed",
fixed = { -8/16, -4/16, -5/16, 8/16, 5/16, 5/16 }
},
node_box = {
type = "fixed",
fixed = valveboxes
},
groups = {snappy=3, pipe=1, not_in_creative_inventory=1},
sounds = default.node_sound_wood_defaults(),
walkable = true,
after_place_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
after_dig_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
drop = "pipeworks:valve_off_empty",
mesecons = {effector = {
action_on = function (pos, node)
minetest.add_node(pos,{name="pipeworks:valve_on_empty", param2 = node.param2})
end,
action_off = function (pos, node)
minetest.add_node(pos,{name="pipeworks:valve_off_empty", param2 = node.param2})
end
}},
on_punch = function(pos, node, puncher)
local fdir = minetest.get_node(pos).param2
minetest.add_node(pos, { name = "pipeworks:valve_off_empty", param2 = fdir })
end
})
-- grating
minetest.register_node("pipeworks:grating", {
description = "Decorative grating",
tiles = {
"pipeworks_grating_top.png",
"pipeworks_grating_sides.png",
"pipeworks_grating_sides.png",
"pipeworks_grating_sides.png",
"pipeworks_grating_sides.png",
"pipeworks_grating_sides.png"
},
sunlight_propagates = true,
paramtype = "light",
groups = {snappy=3, pipe=1},
sounds = default.node_sound_wood_defaults(),
walkable = true,
after_place_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
after_dig_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
})
-- outlet spigot
local spigotboxes = {}
pipeworks.add_node_box(spigotboxes, pipeworks.pipe_backstub)
pipeworks.add_node_box(spigotboxes, pipeworks.spigot_bottomstub)
pipeworks.add_node_box(spigotboxes, pipeworks.pipe_bendsphere)
local spigotboxes_pouring = {}
pipeworks.add_node_box(spigotboxes_pouring, pipeworks.spigot_stream)
pipeworks.add_node_box(spigotboxes_pouring, pipeworks.pipe_backstub)
pipeworks.add_node_box(spigotboxes_pouring, pipeworks.spigot_bottomstub)
pipeworks.add_node_box(spigotboxes_pouring, pipeworks.pipe_bendsphere)
minetest.register_node("pipeworks:spigot", {
description = "Spigot outlet",
drawtype = "nodebox",
tiles = {
"pipeworks_spigot_sides.png",
"pipeworks_pipe_end_empty.png",
"pipeworks_spigot_sides.png",
"pipeworks_spigot_sides.png",
"pipeworks_pipe_end_empty.png",
"pipeworks_spigot_sides.png"
},
sunlight_propagates = true,
paramtype = "light",
paramtype2 = "facedir",
groups = {snappy=3, pipe=1},
sounds = default.node_sound_wood_defaults(),
walkable = true,
after_place_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
after_dig_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
node_box = {
type = "fixed",
fixed = spigotboxes,
},
selection_box = {
type = "fixed",
fixed = { -2/16, -6/16, -2/16, 2/16, 2/16, 8/16 }
}
})
minetest.register_node("pipeworks:spigot_pouring", {
description = "Spigot outlet",
drawtype = "nodebox",
tiles = {
"pipeworks_spigot_sides.png",
"default_water.png^pipeworks_spigot_bottom2.png",
{ name = "default_water_flowing_animated.png^pipeworks_spigot_sides2.png",
animation = {
type = "vertical_frames",
aspect_w=16,
aspect_h=16,
length=0.8
}
},
{ name = "default_water_flowing_animated.png^pipeworks_spigot_sides2.png",
animation = {
type = "vertical_frames",
aspect_w=16,
aspect_h=16,
length=0.8
}
},
{ name = "default_water_flowing_animated.png^pipeworks_spigot_sides2.png",
animation = {
type = "vertical_frames",
aspect_w=16,
aspect_h=16,
length=0.8
}
},
{ name = "default_water_flowing_animated.png^pipeworks_spigot_sides2.png",
animation = {
type = "vertical_frames",
aspect_w=16,
aspect_h=16,
length=0.8
}
},
},
sunlight_propagates = true,
paramtype = "light",
paramtype2 = "facedir",
groups = {snappy=3, pipe=1, not_in_creative_inventory=1},
sounds = default.node_sound_wood_defaults(),
walkable = true,
after_place_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
after_dig_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
node_box = {
type = "fixed",
fixed = spigotboxes_pouring,
},
selection_box = {
type = "fixed",
fixed = { -2/16, -6/16, -2/16, 2/16, 2/16, 8/16 }
},
drop = "pipeworks:spigot",
})
-- sealed pipe entry/exit (horizontal pipe passing through a metal
-- wall, for use in places where walls should look like they're airtight)
local airtightboxes = {}
pipeworks.add_node_box(airtightboxes, pipeworks.pipe_frontstub)
pipeworks.add_node_box(airtightboxes, pipeworks.pipe_backstub)
pipeworks.add_node_box(airtightboxes, pipeworks.entry_panel)
minetest.register_node("pipeworks:entry_panel_empty", {
description = "Airtight Pipe entry/exit",
drawtype = "nodebox",
tiles = {
"pipeworks_plain.png",
"pipeworks_plain.png",
"pipeworks_plain.png",
"pipeworks_plain.png",
"pipeworks_pipe_end_empty.png",
"pipeworks_pipe_end_empty.png"
},
paramtype = "light",
paramtype2 = "facedir",
groups = {snappy=3, pipe=1},
sounds = default.node_sound_wood_defaults(),
walkable = true,
after_place_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
after_dig_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
node_box = {
type = "fixed",
fixed = airtightboxes,
},
selection_box = {
type = "fixed",
fixed = {
{ -2/16, -2/16, -8/16, 2/16, 2/16, 8/16 },
{ -8/16, -8/16, -1/16, 8/16, 8/16, 1/16 }
}
},
on_place = function(itemstack, placer, pointed_thing)
if not pipeworks.node_is_owned(pointed_thing.under, placer)
and not pipeworks.node_is_owned(pointed_thing.above, placer) then
local node = minetest.get_node(pointed_thing.under)
if not minetest.registered_nodes[node.name]
or not minetest.registered_nodes[node.name].on_rightclick then
local pitch = placer:get_look_pitch()
local above = pointed_thing.above
local under = pointed_thing.under
local fdir = minetest.dir_to_facedir(placer:get_look_dir())
local undernode = minetest.get_node(under)
local abovenode = minetest.get_node(above)
local uname = undernode.name
local aname = abovenode.name
local isabove = (above.x == under.x) and (above.z == under.z) and (pitch > 0)
local pos1 = above
if above.x == under.x
and above.z == under.z
and ( string.find(uname, "pipeworks:pipe_")
or string.find(uname, "pipeworks:storage_")
or string.find(uname, "pipeworks:expansion_")
or ( string.find(uname, "pipeworks:grating") and not isabove )
or ( string.find(uname, "pipeworks:pump_") and not isabove )
or ( string.find(uname, "pipeworks:entry_panel")
and undernode.param2 == 13 )
)
then
fdir = 13
end
if minetest.registered_nodes[uname]["buildable_to"] then
pos1 = under
end
if not minetest.registered_nodes[minetest.get_node(pos1).name]["buildable_to"] then return end
minetest.add_node(pos1, {name = "pipeworks:entry_panel_empty", param2 = fdir })
pipeworks.scan_for_pipe_objects(pos1)
if not pipeworks.expect_infinite_stacks then
itemstack:take_item()
end
else
minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack)
end
end
return itemstack
end
})
minetest.register_node("pipeworks:entry_panel_loaded", {
description = "Airtight Pipe entry/exit",
drawtype = "nodebox",
tiles = {
"pipeworks_plain.png",
"pipeworks_plain.png",
"pipeworks_plain.png",
"pipeworks_plain.png",
"pipeworks_pipe_end_empty.png",
"pipeworks_pipe_end_empty.png"
},
paramtype = "light",
paramtype2 = "facedir",
groups = {snappy=3, pipe=1, not_in_creative_inventory=1},
sounds = default.node_sound_wood_defaults(),
walkable = true,
after_place_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
after_dig_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
node_box = {
type = "fixed",
fixed = airtightboxes,
},
selection_box = {
type = "fixed",
fixed = {
{ -2/16, -2/16, -8/16, 2/16, 2/16, 8/16 },
{ -8/16, -8/16, -1/16, 8/16, 8/16, 1/16 }
}
},
drop = "pipeworks:entry_panel_empty"
})
local sensorboxes = {}
pipeworks.add_node_box(sensorboxes, pipeworks.pipe_leftstub)
pipeworks.add_node_box(sensorboxes, pipeworks.pipe_sensorbody)
pipeworks.add_node_box(sensorboxes, pipeworks.pipe_rightstub)
minetest.register_node("pipeworks:flow_sensor_empty", {
description = "Flow Sensor",
drawtype = "nodebox",
tiles = {
"pipeworks_plain.png",
"pipeworks_plain.png",
"pipeworks_plain.png",
"pipeworks_plain.png",
"pipeworks_windowed_empty.png",
"pipeworks_windowed_empty.png"
},
sunlight_propagates = true,
paramtype = "light",
paramtype2 = "facedir",
groups = {snappy=3, pipe=1},
sounds = default.node_sound_wood_defaults(),
walkable = true,
after_place_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
after_dig_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
on_construct = function(pos)
if mesecon then
mesecon.receptor_off(pos, rules)
end
end,
node_box = {
type = "fixed",
fixed = sensorboxes,
},
selection_box = {
type = "fixed",
fixed = {
{ -8/16, -2/16, -2/16, 8/16, 2/16, 2/16 },
}
},
mesecons = pipereceptor_off
})
minetest.register_node("pipeworks:flow_sensor_loaded", {
description = "Flow sensor (on)",
drawtype = "nodebox",
tiles = {
"pipeworks_plain.png",
"pipeworks_plain.png",
"pipeworks_plain.png",
"pipeworks_plain.png",
"pipeworks_sensor_sides_on.png",
"pipeworks_sensor_sides_on.png"
},
sunlight_propagates = true,
paramtype = "light",
paramtype2 = "facedir",
groups = {snappy=3, pipe=1, not_in_creative_inventory=1},
sounds = default.node_sound_wood_defaults(),
walkable = true,
after_place_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
after_dig_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
on_construct = function(pos)
if mesecon then
mesecon.receptor_on(pos, rules)
end
end,
node_box = {
type = "fixed",
fixed = sensorboxes,
},
selection_box = {
type = "fixed",
fixed = {
{ -8/16, -2/16, -2/16, 8/16, 2/16, 2/16 },
}
},
drop = "pipeworks:flow_sensor_empty",
mesecons = pipereceptor_on
})
-- tanks
for fill = 0, 10 do
local filldesc="empty"
local sgroups = {snappy=3, pipe=1, tankfill=fill+1}
local image = nil
if fill ~= 0 then
filldesc=fill.."0% full"
sgroups = {snappy=3, pipe=1, tankfill=fill+1, not_in_creative_inventory=1}
image = "pipeworks_storage_tank_fittings.png"
end
minetest.register_node("pipeworks:expansion_tank_"..fill, {
description = "Expansion Tank ("..filldesc..")... You hacker, you.",
tiles = {
"pipeworks_storage_tank_fittings.png",
"pipeworks_storage_tank_fittings.png",
"pipeworks_storage_tank_back.png",
"pipeworks_storage_tank_back.png",
"pipeworks_storage_tank_back.png",
pipeworks.liquid_texture.."^pipeworks_storage_tank_front_"..fill..".png"
},
inventory_image = image,
paramtype = "light",
paramtype2 = "facedir",
groups = {snappy=3, pipe=1, tankfill=fill+1, not_in_creative_inventory=1},
sounds = default.node_sound_wood_defaults(),
walkable = true,
drop = "pipeworks:storage_tank_0",
after_place_node = function(pos)
pipeworks.look_for_stackable_tanks(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
after_dig_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
})
minetest.register_node("pipeworks:storage_tank_"..fill, {
description = "Fluid Storage Tank ("..filldesc..")",
tiles = {
"pipeworks_storage_tank_fittings.png",
"pipeworks_storage_tank_fittings.png",
"pipeworks_storage_tank_back.png",
"pipeworks_storage_tank_back.png",
"pipeworks_storage_tank_back.png",
pipeworks.liquid_texture.."^pipeworks_storage_tank_front_"..fill..".png"
},
inventory_image = image,
paramtype = "light",
paramtype2 = "facedir",
groups = sgroups,
sounds = default.node_sound_wood_defaults(),
walkable = true,
drop = "pipeworks:storage_tank_0",
after_place_node = function(pos)
pipeworks.look_for_stackable_tanks(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
after_dig_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
})
end
-- fountainhead
minetest.register_node("pipeworks:fountainhead", {
description = "Fountainhead",
drawtype = "nodebox",
tiles = {
"pipeworks_fountainhead_top.png",
"pipeworks_pipe_end.png",
"pipeworks_plain.png",
},
sunlight_propagates = true,
paramtype = "light",
groups = {snappy=3, pipe=1},
sounds = default.node_sound_wood_defaults(),
walkable = true,
after_place_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
after_dig_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
on_construct = function(pos)
if mesecon then
mesecon.receptor_on(pos, rules)
end
end,
node_box = {
type = "fixed",
fixed = pipeworks.fountainhead_model ,
},
selection_box = {
type = "fixed",
fixed = { -2/16, -8/16, -2/16, 2/16, 8/16, 2/16 }
},
})
minetest.register_node("pipeworks:fountainhead_pouring", {
description = "Fountainhead",
drawtype = "nodebox",
tiles = {
"pipeworks_fountainhead_top.png",
"pipeworks_pipe_end.png",
"pipeworks_plain.png",
},
sunlight_propagates = true,
paramtype = "light",
groups = {snappy=3, pipe=1, not_in_creative_inventory=1},
sounds = default.node_sound_wood_defaults(),
walkable = true,
after_place_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
after_dig_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
on_construct = function(pos)
if mesecon then
mesecon.receptor_on(pos, rules)
end
end,
node_box = {
type = "fixed",
fixed = pipeworks.fountainhead_model,
},
selection_box = {
type = "fixed",
fixed = { -2/16, -8/16, -2/16, 2/16, 8/16, 2/16 },
},
drop = "pipeworks:fountainhead"
})
minetest.register_alias("pipeworks:valve_off_loaded", "pipeworks:valve_off_empty")

View File

@ -0,0 +1,121 @@
-- This file provides the actual flow and pathfinding logic that makes water
-- move through the pipes.
--
-- Contributed by mauvebic, 2013-01-03, rewritten a bit by Vanessa Ezekowitz
--
local finitewater = minetest.setting_getbool("liquid_finite")
pipeworks.check_for_liquids = function(pos)
local coords = {
{x=pos.x,y=pos.y-1,z=pos.z},
{x=pos.x,y=pos.y+1,z=pos.z},
{x=pos.x-1,y=pos.y,z=pos.z},
{x=pos.x+1,y=pos.y,z=pos.z},
{x=pos.x,y=pos.y,z=pos.z-1},
{x=pos.x,y=pos.y,z=pos.z+1}, }
for i =1,6 do
local name = minetest.get_node(coords[i]).name
if name and string.find(name,"water") then
if finitewater then minetest.remove_node(coords[i]) end
return true
end
end
return false
end
pipeworks.check_for_inflows = function(pos,node)
local coords = {
{x=pos.x,y=pos.y-1,z=pos.z},
{x=pos.x,y=pos.y+1,z=pos.z},
{x=pos.x-1,y=pos.y,z=pos.z},
{x=pos.x+1,y=pos.y,z=pos.z},
{x=pos.x,y=pos.y,z=pos.z-1},
{x=pos.x,y=pos.y,z=pos.z+1}, }
local newnode = false
local source = false
for i =1,6 do
if newnode then break end
local name = minetest.get_node(coords[i]).name
if name and (name == "pipeworks:pump_on" and pipeworks.check_for_liquids(coords[i])) or string.find(name,"_loaded") then
if string.find(name,"_loaded") then
source = minetest.get_meta(coords[i]):get_string("source")
if source == minetest.pos_to_string(pos) then break end
end
newnode = string.gsub(node.name,"empty","loaded")
source = {x=coords[i].x,y=coords[i].y,z=coords[i].z}
end
end
if newnode then
minetest.add_node(pos,{name=newnode, param2 = node.param2})
minetest.get_meta(pos):set_string("source",minetest.pos_to_string(source))
end
end
pipeworks.check_sources = function(pos,node)
local sourcepos = minetest.string_to_pos(minetest.get_meta(pos):get_string("source"))
if not sourcepos then return end
local source = minetest.get_node(sourcepos).name
local newnode = false
if source and not ((source == "pipeworks:pump_on" and pipeworks.check_for_liquids(sourcepos)) or string.find(source,"_loaded") or source == "ignore" ) then
newnode = string.gsub(node.name,"loaded","empty")
end
if newnode then
minetest.add_node(pos,{name=newnode, param2 = node.param2})
minetest.get_meta(pos):set_string("source","")
end
end
pipeworks.spigot_check = function(pos, node)
local belowname = minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}).name
if belowname and (belowname == "air" or belowname == "default:water_flowing" or belowname == "default:water_source") then
local spigotname = minetest.get_node(pos).name
local fdir=node.param2
local check = {
{x=pos.x,y=pos.y,z=pos.z+1},
{x=pos.x+1,y=pos.y,z=pos.z},
{x=pos.x,y=pos.y,z=pos.z-1},
{x=pos.x-1,y=pos.y,z=pos.z}
}
local near_node = minetest.get_node(check[fdir+1])
if near_node and string.find(near_node.name, "_loaded") then
if spigotname and spigotname == "pipeworks:spigot" then
minetest.add_node(pos,{name = "pipeworks:spigot_pouring", param2 = fdir})
if finitewater or belowname ~= "default:water_source" then
minetest.add_node({x=pos.x,y=pos.y-1,z=pos.z},{name = "default:water_source"})
end
end
else
if spigotname == "pipeworks:spigot_pouring" then
minetest.add_node({x=pos.x,y=pos.y,z=pos.z},{name = "pipeworks:spigot", param2 = fdir})
if belowname == "default:water_source" and not finitewater then
minetest.remove_node({x=pos.x,y=pos.y-1,z=pos.z})
end
end
end
end
end
pipeworks.fountainhead_check = function(pos, node)
local abovename = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}).name
if abovename and (abovename == "air" or abovename == "default:water_flowing" or abovename == "default:water_source") then
local fountainhead_name = minetest.get_node(pos).name
local near_node = minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z})
if near_node and string.find(near_node.name, "_loaded") then
if fountainhead_name and fountainhead_name == "pipeworks:fountainhead" then
minetest.add_node(pos,{name = "pipeworks:fountainhead_pouring"})
if finitewater or abovename ~= "default:water_source" then
minetest.add_node({x=pos.x,y=pos.y+1,z=pos.z},{name = "default:water_source"})
end
end
else
if fountainhead_name == "pipeworks:fountainhead_pouring" then
minetest.add_node({x=pos.x,y=pos.y,z=pos.z},{name = "pipeworks:fountainhead"})
if abovename == "default:water_source" and not finitewater then
minetest.remove_node({x=pos.x,y=pos.y+1,z=pos.z})
end
end
end
end
end

130
mods/pipeworks/init.lua Normal file
View File

@ -0,0 +1,130 @@
-- Pipeworks mod by Vanessa Ezekowitz - 2013-07-13
--
-- This mod supplies various steel pipes and plastic pneumatic tubes
-- and devices that they can connect to.
--
-- License: WTFPL
--
pipeworks = {}
local DEBUG = false
pipeworks.worldpath = minetest.get_worldpath()
pipeworks.modpath = minetest.get_modpath("pipeworks")
dofile(pipeworks.modpath.."/default_settings.txt")
-- Read the external config file if it exists.
if io.open(pipeworks.worldpath.."/pipeworks_settings.txt","r") then
dofile(pipeworks.worldpath.."/pipeworks_settings.txt")
io.close()
end
-- Random variables
pipeworks.expect_infinite_stacks = true
if minetest.get_modpath("unified_inventory") or not minetest.setting_getbool("creative_mode") then
pipeworks.expect_infinite_stacks = false
end
pipeworks.meseadjlist={{x=0,y=0,z=1},{x=0,y=0,z=-1},{x=0,y=1,z=0},{x=0,y=-1,z=0},{x=1,y=0,z=0},{x=-1,y=0,z=0}}
pipeworks.rules_all = {{x=0, y=0, z=1},{x=0, y=0, z=-1},{x=1, y=0, z=0},{x=-1, y=0, z=0},
{x=0, y=1, z=1},{x=0, y=1, z=-1},{x=1, y=1, z=0},{x=-1, y=1, z=0},
{x=0, y=-1, z=1},{x=0, y=-1, z=-1},{x=1, y=-1, z=0},{x=-1, y=-1, z=0},
{x=0, y=1, z=0}, {x=0, y=-1, z=0}}
pipeworks.mesecons_rules={{x=0,y=0,z=1},{x=0,y=0,z=-1},{x=1,y=0,z=0},{x=-1,y=0,z=0},{x=0,y=1,z=0},{x=0,y=-1,z=0}}
pipeworks.liquid_texture = "default_water.png"
-- Helper functions
function pipeworks.fix_image_names(table, replacement)
local outtable={}
for i in ipairs(table) do
outtable[i]=string.gsub(table[i], "_XXXXX", replacement)
end
return outtable
end
function pipeworks.add_node_box(t, b)
for i in ipairs(b)
do table.insert(t, b[i])
end
end
function pipeworks.node_is_owned(pos, placer)
local ownername = false
if type(IsPlayerNodeOwner) == "function" then -- node_ownership mod
if HasOwner(pos, placer) then -- returns true if the node is owned
if not IsPlayerNodeOwner(pos, placer:get_player_name()) then
if type(getLastOwner) == "function" then -- ...is an old version
ownername = getLastOwner(pos)
elseif type(GetNodeOwnerName) == "function" then -- ...is a recent version
ownername = GetNodeOwnerName(pos)
else
ownername = S("someone")
end
end
end
elseif type(isprotect)=="function" then -- glomie's protection mod
if not isprotect(5, pos, placer) then
ownername = S("someone")
end
elseif type(protector)=="table" and type(protector.can_dig)=="function" then -- Zeg9's protection mod
if not protector.can_dig(5, pos, placer) then
ownername = S("someone")
end
end
if ownername ~= false then
minetest.chat_send_player( placer:get_player_name(), S("Sorry, %s owns that spot."):format(ownername) )
return true
else
return false
end
end
function pipeworks.replace_name(tbl,tr,name)
local ntbl={}
for key,i in pairs(tbl) do
if type(i)=="string" then
ntbl[key]=string.gsub(i,tr,name)
elseif type(i)=="table" then
ntbl[key]=pipeworks.replace_name(i,tr,name)
else
ntbl[key]=i
end
end
return ntbl
end
-------------------------------------------
-- Load the various other parts of the mod
dofile(pipeworks.modpath.."/common.lua")
dofile(pipeworks.modpath.."/models.lua")
dofile(pipeworks.modpath.."/autoplace_pipes.lua")
dofile(pipeworks.modpath.."/autoplace_tubes.lua")
dofile(pipeworks.modpath.."/luaentity.lua")
dofile(pipeworks.modpath.."/item_transport.lua")
dofile(pipeworks.modpath.."/flowing_logic.lua")
dofile(pipeworks.modpath.."/crafts.lua")
dofile(pipeworks.modpath.."/tubes.lua")
dofile(pipeworks.modpath.."/trashcan.lua")
dofile(pipeworks.modpath.."/wielder.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_redefines then dofile(pipeworks.modpath.."/compat.lua") end
if pipeworks.enable_autocrafter then dofile(pipeworks.modpath.."/autocrafter.lua") end
minetest.register_alias("pipeworks:pipe", "pipeworks:pipe_110000_empty")
print("Pipeworks loaded!")

View File

@ -0,0 +1,487 @@
local function delay(x)
return (function() return x end)
end
function pipeworks.tube_item(pos, item)
error("obsolete pipeworks.tube_item() called; change caller to use pipeworks.tube_inject_item() instead")
end
function pipeworks.tube_inject_item(pos, start_pos, velocity, item)
-- Take item in any format
local stack = ItemStack(item)
local obj = luaentity.add_entity(pos, "pipeworks:tubed_item")
obj:set_item(stack:to_string())
obj.start_pos = vector.new(start_pos)
obj:setvelocity(velocity)
--obj:set_color("red") -- todo: this is test-only code
return obj
end
-- adding two tube functions
-- can_remove(pos,node,stack,dir) returns the maximum number of items of that stack that can be removed
-- remove_items(pos,node,stack,dir,count) removes count items and returns them
-- both optional w/ sensible defaults and fallback to normal allow_* function
-- XXX: possibly change insert_object to insert_item
local function set_filter_infotext(data, meta)
local infotext = data.wise_desc.." Filter-Injector"
if meta:get_int("slotseq_mode") == 2 then
infotext = infotext .. " (slot #"..meta:get_int("slotseq_index").." next)"
end
meta:set_string("infotext", infotext)
end
local function set_filter_formspec(data, meta)
local itemname = data.wise_desc.." Filter-Injector"
local formspec = "size[8,8.5]"..
"item_image[0,0;1,1;pipeworks:"..data.name.."]"..
"label[1,0;"..minetest.formspec_escape(itemname).."]"..
"label[0,1;Prefer item types:]"..
"list[current_name;main;0,1.5;8,2;]"..
fs_helpers.cycling_button(meta, "button[0,3.5;4,1", "slotseq_mode",
{"Sequence slots by Priority",
"Sequence slots Randomly",
"Sequence slots by Rotation"})..
"list[current_player;main;0,4.5;8,4;]"
meta:set_string("formspec", formspec)
end
-- todo SOON: this function has *way too many* parameters
local function grabAndFire(data,slotseq_mode,filtmeta,frominv,frominvname,frompos,fromnode,filtername,fromtube,fromdef,dir,fakePlayer,all)
local sposes = {}
for spos,stack in ipairs(frominv:get_list(frominvname)) do
local matches
if filtername == "" then
matches = stack:get_name() ~= ""
else
matches = stack:get_name() == filtername
end
if matches then table.insert(sposes, spos) end
end
if #sposes == 0 then return false end
if slotseq_mode == 1 then
for i = #sposes, 2, -1 do
local j = math.random(i)
local t = sposes[j]
sposes[j] = sposes[i]
sposes[i] = t
end
elseif slotseq_mode == 2 then
local headpos = filtmeta:get_int("slotseq_index")
table.sort(sposes, function (a, b)
if a >= headpos then
if b < headpos then return true end
else
if b >= headpos then return false end
end
return a < b
end)
end
for _, spos in ipairs(sposes) do
local stack = frominv:get_stack(frominvname, spos)
local doRemove = stack:get_count()
if fromtube.can_remove then
doRemove = fromtube.can_remove(frompos, fromnode, stack, dir)
elseif fromdef.allow_metadata_inventory_take then
doRemove = fromdef.allow_metadata_inventory_take(frompos, frominvname,spos, stack, fakePlayer)
end
-- stupid lack of continue statements grumble
if doRemove > 0 then
if slotseq_mode == 2 then
local nextpos = spos + 1
if nextpos > frominv:get_size(frominvname) then
nextpos = 1
end
filtmeta:set_int("slotseq_index", nextpos)
set_filter_infotext(data, filtmeta)
end
local item
local count
if all then
count = math.min(stack:get_count(), doRemove)
else
count = 1
end
if fromtube.remove_items then
-- it could be the entire stack...
item = fromtube.remove_items(frompos, fromnode, stack, dir, count)
else
item = stack:take_item(count)
frominv:set_stack(frominvname, spos, stack)
if fromdef.on_metadata_inventory_take then
fromdef.on_metadata_inventory_take(frompos, frominvname, spos, item, fakePlayer)
end
end
local pos = vector.add(frompos, vector.multiply(dir, 1.4))
local start_pos = vector.add(frompos, dir)
local item1 = pipeworks.tube_inject_item(pos, start_pos, dir, item)
return true-- only fire one item, please
end
end
return false
end
local function punch_filter(data, filtpos, filtnode)
local filtmeta = minetest.get_meta(filtpos)
local filtinv = filtmeta:get_inventory()
local owner = filtmeta:get_string("owner")
local fakePlayer = {
get_player_name = delay(owner),
} -- TODO: use a mechanism as the wielder one
local dir = minetest.facedir_to_right_dir(filtnode.param2)
local frompos = vector.subtract(filtpos, dir)
local fromnode = minetest.get_node(frompos)
if not fromnode then return end
local fromdef = minetest.registered_nodes[fromnode.name]
if not fromdef then return end
local fromtube = fromdef.tube
if not (fromtube and fromtube.input_inventory) then return end
local filters = {}
for _, filterstack in ipairs(filtinv:get_list("main")) do
local filtername = filterstack:get_name()
if filtername ~= "" then table.insert(filters, filtername) end
end
if #filters == 0 then table.insert(filters, "") end
local slotseq_mode = filtmeta:get_int("slotseq_mode")
local frommeta = minetest.get_meta(frompos)
local frominv = frommeta:get_inventory()
if fromtube.before_filter then fromtube.before_filter(frompos) end
for _, frominvname in ipairs(type(fromtube.input_inventory) == "table" and fromtube.input_inventory or {fromtube.input_inventory}) do
local done = false
for _, filtername in ipairs(filters) do
if grabAndFire(data, slotseq_mode, filtmeta, frominv, frominvname, frompos, fromnode, filtername, fromtube, fromdef, dir, fakePlayer, data.stackwise) then
done = true
break
end
end
if done then break end
end
if fromtube.after_filter then fromtube.after_filter(frompos) end
end
for _, data in ipairs({
{
name = "filter",
wise_desc = "Itemwise",
stackwise = false,
},
{
name = "mese_filter",
wise_desc = "Stackwise",
stackwise = true,
},
}) do
minetest.register_node("pipeworks:"..data.name, {
description = data.wise_desc.." Filter-Injector",
tiles = {
"pipeworks_"..data.name.."_top.png",
"pipeworks_"..data.name.."_top.png",
"pipeworks_"..data.name.."_output.png",
"pipeworks_"..data.name.."_input.png",
"pipeworks_"..data.name.."_side.png",
"pipeworks_"..data.name.."_top.png",
},
paramtype2 = "facedir",
groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, mesecon = 2},
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
on_construct = function(pos)
local meta = minetest.get_meta(pos)
set_filter_formspec(data, meta)
set_filter_infotext(data, meta)
local inv = meta:get_inventory()
inv:set_size("main", 8*2)
end,
after_place_node = function (pos, placer)
minetest.get_meta(pos):set_string("owner", placer:get_player_name())
end,
on_receive_fields = function(pos, formname, fields, sender)
fs_helpers.on_receive_fields(pos, fields)
local meta = minetest.get_meta(pos)
meta:set_int("slotseq_index", 1)
set_filter_formspec(data, meta)
set_filter_infotext(data, meta)
end,
can_dig = function(pos, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:is_empty("main")
end,
mesecons = {
effector = {
action_on = function(pos, node)
punch_filter(data, pos, node)
end,
},
},
tube = {connect_sides = {right = 1}},
on_punch = function (pos, node, puncher)
punch_filter(data, pos, node)
end,
})
end
local adjlist={{x=0,y=0,z=1},{x=0,y=0,z=-1},{x=0,y=1,z=0},{x=0,y=-1,z=0},{x=1,y=0,z=0},{x=-1,y=0,z=0}}
function pipeworks.notvel(tbl, vel)
local tbl2={}
for _,val in ipairs(tbl) do
if val.x ~= -vel.x or val.y ~= -vel.y or val.z ~= -vel.z then table.insert(tbl2, val) end
end
return tbl2
end
local function go_next(pos, velocity, stack)
local next_positions = {}
local max_priority = 0
local cnode = minetest.get_node(pos)
local cmeta = minetest.get_meta(pos)
local can_go
local speed = math.abs(velocity.x + velocity.y + velocity.z)
if speed == 0 then
speed = 1
end
local vel = {x = velocity.x/speed, y = velocity.y/speed, z = velocity.z/speed,speed=speed}
if speed >= 4.1 then
speed = 4
elseif speed >= 1.1 then
speed = speed - 0.1
else
speed = 1
end
vel.speed = speed
if minetest.registered_nodes[cnode.name] and minetest.registered_nodes[cnode.name].tube and minetest.registered_nodes[cnode.name].tube.can_go then
can_go = minetest.registered_nodes[cnode.name].tube.can_go(pos, cnode, vel, stack)
else
can_go = pipeworks.notvel(adjlist, vel)
end
for _, vect in ipairs(can_go) do
local npos = vector.add(pos, vect)
local node = minetest.get_node(npos)
local reg_node = minetest.registered_nodes[node.name]
if reg_node then
local tube_def = reg_node.tube
local tubedevice = minetest.get_item_group(node.name, "tubedevice")
local tube_priority = (tube_def and tube_def.priority) or 100
if tubedevice > 0 and tube_priority >= max_priority then
if not tube_def or not tube_def.can_insert or
tube_def.can_insert(npos, node, stack, vect) then
if tube_priority > max_priority then
max_priority = tube_priority
next_positions = {}
end
next_positions[#next_positions + 1] = {pos = npos, vect = vect}
end
end
end
end
if not next_positions[1] then
return false, nil
end
local n = (cmeta:get_int("tubedir") % (#next_positions)) + 1
if pipeworks.enable_cyclic_mode then
cmeta:set_int("tubedir", n)
end
local new_velocity = vector.multiply(next_positions[n].vect, vel.speed)
return true, new_velocity
end
minetest.register_entity("pipeworks:tubed_item", {
initial_properties = {
hp_max = 1,
physical = false,
collisionbox = {0.1, 0.1, 0.1, 0.1, 0.1, 0.1},
visual = "wielditem",
visual_size = {x = 0.15, y = 0.15},
textures = {""},
spritediv = {x = 1, y = 1},
initial_sprite_basepos = {x = 0, y = 0},
is_visible = false,
},
physical_state = false,
from_data = function(self, itemstring)
local stack = ItemStack(itemstring)
local itemtable = stack:to_table()
local itemname = nil
if itemtable then
itemname = stack:to_table().name
end
local item_texture = nil
local item_type = ""
if minetest.registered_items[itemname] then
item_texture = minetest.registered_items[itemname].inventory_image
item_type = minetest.registered_items[itemname].type
end
self.object:set_properties({
is_visible = true,
textures = {stack:get_name()}
})
local def = stack:get_definition()
self.object:setyaw((def and def.type == "node") and 0 or math.pi * 0.25)
end,
get_staticdata = luaentity.get_staticdata,
on_activate = function(self, staticdata) -- Legacy code, should be replaced later by luaentity.on_activate
if staticdata == "" or staticdata == nil then
return
end
if staticdata == "toremove" then
self.object:remove()
return
end
local item = minetest.deserialize(staticdata)
pipeworks.tube_inject_item(self.object:getpos(), item.start_pos, item.velocity, item.itemstring)
self.object:remove()
end,
})
minetest.register_entity("pipeworks:color_entity", {
initial_properties = {
hp_max = 1,
physical = false,
collisionbox = {0.1, 0.1, 0.1, 0.1, 0.1, 0.1},
visual = "cube",
visual_size = {x = 3.5, y = 3.5, z = 3.5}, -- todo: find correct size
textures = {""},
is_visible = false,
},
physical_state = false,
from_data = function(self, color)
local t = "pipeworks_color_"..color..".png"
local prop = {
is_visible = true,
visual = "cube",
textures = {t, t, t, t, t, t} -- todo: textures
}
self.object:set_properties(prop)
end,
get_staticdata = luaentity.get_staticdata,
on_activate = luaentity.on_activate,
})
luaentity.register_entity("pipeworks:tubed_item", {
itemstring = '',
item_entity = nil,
color_entity = nil,
color = nil,
start_pos = nil,
set_item = function(self, item)
local itemstring = ItemStack(item):to_string() -- Accept any input format
if self.itemstring == itemstring then
return
end
if self.item_entity then
self:remove_attached_entity(self.item_entity)
end
self.itemstring = itemstring
self.item_entity = self:add_attached_entity("pipeworks:tubed_item", itemstring)
end,
set_color = function(self, color)
if self.color == color then
return
end
self.color = color
if self.color_entity then
self:remove_attached_entity(self.color_entity)
end
if color then
self.color_entity = self:add_attached_entity("pipeworks:color_entity", color)
else
self.color_entity = nil
end
end,
on_step = function(self, dtime)
if self.start_pos == nil then
local pos = self:getpos()
self.start_pos = vector.round(pos)
self:setpos(pos)
end
local pos = self:getpos()
local stack = ItemStack(self.itemstring)
local drop_pos
local velocity = self:getvelocity()
local moved = false
local speed = math.abs(velocity.x + velocity.y + velocity.z)
if speed == 0 then
speed = 1
moved = true
end
local vel = {x = velocity.x / speed, y = velocity.y / speed, z = velocity.z / speed, speed = speed}
if vector.distance(pos, self.start_pos) >= 1 then
self.start_pos = vector.add(self.start_pos, vel)
moved = true
end
minetest.load_position(self.start_pos)
local node = minetest.get_node(self.start_pos)
if moved and minetest.get_item_group(node.name, "tubedevice_receiver") == 1 then
local leftover
if minetest.registered_nodes[node.name].tube and minetest.registered_nodes[node.name].tube.insert_object then
leftover = minetest.registered_nodes[node.name].tube.insert_object(self.start_pos, node, stack, vel)
else
leftover = stack
end
if leftover:is_empty() then
self:remove()
return
end
velocity = vector.multiply(velocity, -1)
self:setvelocity(velocity)
self:set_item(leftover:to_string())
return
end
if moved then
local found_next, new_velocity = go_next(self.start_pos, velocity, stack) -- todo: color
if not found_next then
drop_pos = minetest.find_node_near(vector.add(self.start_pos, velocity), 1, "air")
if drop_pos then
minetest.item_drop(stack, "", drop_pos)
self:remove()
return
end
end
if new_velocity and not vector.equals(velocity, new_velocity) then
self:setpos(self.start_pos)
self:setvelocity(new_velocity)
end
end
end
})
if minetest.get_modpath("mesecons_mvps") then
mesecon.register_mvps_unmov("pipeworks:tubed_item")
mesecon.register_mvps_unmov("pipeworks:color_entity")
mesecon.register_on_mvps_move(function(moved_nodes)
local moved = {}
for _, n in ipairs(moved_nodes) do
moved[minetest.hash_node_position(n.oldpos)] = vector.subtract(n.pos, n.oldpos)
end
for id, entity in pairs(luaentity.entities) do
if entity.name == "pipeworks:tubed_item" then
local pos = entity:getpos()
local rpos = vector.round(pos)
local dir = moved[minetest.hash_node_position(rpos)]
if dir then
entity:setpos(vector.add(pos, dir))
entity.start_pos = vector.add(entity.start_pos, dir)
end
end
end
end)
end

60
mods/pipeworks/legacy.lua Normal file
View File

@ -0,0 +1,60 @@
if not minetest.get_modpath("auto_tree_tap") and
minetest.get_modpath("technic") then
minetest.register_abm({
nodenames = { "auto_tree_tap:off", "auto_tree_tap:on" },
chance = 1,
interval = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local fdir = node.param2
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_size("pick", 1)
inv:set_size("ghost_pick", 1)
inv:set_size("main", 100)
minetest.set_node(pos, {name = "pipeworks:nodebreaker_off", param2 = fdir})
minetest.registered_nodes["pipeworks:nodebreaker_off"].on_punch(pos, node)
inv:set_stack("pick", 1, ItemStack("technic:treetap"))
end
})
minetest.register_node(":auto_tree_tap:off", {
description = "Auto-Tap",
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"},
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 },
mesecons= {effector={rules=pipeworks.rules_all,action_on=node_breaker_on, action_off=node_breaker_off}},
sounds = default.node_sound_stone_defaults(),
tube = {connect_sides={back=1}},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_size("pick", 1)
inv:set_stack("pick", 1, ItemStack("default:pick_mese"))
end,
after_place_node = function (pos, placer)
pipeworks.scan_for_tube_objects(pos, placer)
local placer_pos = placer:getpos()
--correct for the player's height
if placer:is_player() then placer_pos.y = placer_pos.y + 1.5 end
--correct for 6d facedir
if placer_pos then
local dir = {
x = pos.x - placer_pos.x,
y = pos.y - placer_pos.y,
z = pos.z - placer_pos.z
}
local node = minetest.get_node(pos)
node.param2 = minetest.dir_to_facedir(dir, true)
minetest.set_node(pos, node)
minetest.log("action", "real (6d) facedir: " .. node.param2)
end
end,
after_dig_node = pipeworks.scan_for_tube_objects,
})
end

View File

@ -0,0 +1,334 @@
local max_entity_id = 1000000000000 -- If you need more, there's a problem with your code
luaentity = {}
luaentity.registered_entities = {}
local filename = minetest.get_worldpath().."/luaentities"
local function read_file()
local f = io.open(filename, "r")
if f == nil then return {} end
local t = f:read("*all")
f:close()
if t == "" or t == nil then return {} end
return minetest.deserialize(t)
end
local function write_file(tbl)
local f = io.open(filename, "w")
f:write(minetest.serialize(tbl))
f:close()
end
local function read_entities()
local t = read_file()
for _, entity in pairs(t) do
setmetatable(entity, luaentity.registered_entities[entity.name])
end
return t
end
local function write_entities()
for _, entity in pairs(luaentity.entities) do
setmetatable(entity, nil)
for _, attached in pairs(entity._attached_entities) do
if attached.entity then
attached.entity:remove()
attached.entity = nil
end
end
entity._attached_entities_master = nil
end
write_file(luaentity.entities)
end
minetest.register_on_shutdown(write_entities)
luaentity.entities_index = 0
local function get_blockpos(pos)
return {x = math.floor(pos.x / 16),
y = math.floor(pos.y / 16),
z = math.floor(pos.z / 16)}
end
local active_blocks = {} -- These only contain active blocks near players (i.e., not forceloaded ones)
local handle_active_blocks_step = 2
local handle_active_blocks_timer = 0
minetest.register_globalstep(function(dtime)
handle_active_blocks_timer = handle_active_blocks_timer + dtime
if handle_active_blocks_timer >= handle_active_blocks_step then
handle_active_blocks_timer = handle_active_blocks_timer - handle_active_blocks_step
local active_block_range = tonumber(minetest.setting_get("active_block_range")) or 2
local new_active_blocks = {}
for _, player in ipairs(minetest.get_connected_players()) do
local blockpos = get_blockpos(player:getpos())
local minp = vector.subtract(blockpos, active_block_range)
local maxp = vector.add(blockpos, active_block_range)
for x = minp.x, maxp.x do
for y = minp.y, maxp.y do
for z = minp.z, maxp.z do
local pos = {x = x, y = y, z = z}
new_active_blocks[minetest.hash_node_position(pos)] = pos
end
end
end
end
active_blocks = new_active_blocks
-- todo: callbacks on block load/unload
end
end)
local function is_active(pos)
return active_blocks[minetest.hash_node_position(get_blockpos(pos))] ~= nil
end
local entitydef_default = {
_attach = function(self, attached, attach_to)
local attached_def = self._attached_entities[attached]
local attach_to_def = self._attached_entities[attach_to]
attached_def.entity:set_attach(
attach_to_def.entity, "",
vector.subtract(attached_def.offset, attach_to_def.offset), -- todo: Does not work because is object space
vector.new(0, 0, 0)
)
end,
_set_master = function(self, index)
self._attached_entities_master = index
if not index then
return
end
local def = self._attached_entities[index]
if not def.entity then
return
end
def.entity:setpos(vector.add(self._pos, def.offset))
def.entity:setvelocity(self._velocity)
def.entity:setacceleration(self._acceleration)
end,
_attach_all = function(self)
local master = self._attached_entities_master
if not master then
return
end
for id, entity in pairs(self._attached_entities) do
if id ~= master and entity.entity then
self:_attach(id, master)
end
end
end,
_detach_all = function(self)
local master = self._attached_entities_master
for id, entity in pairs(self._attached_entities) do
if id ~= master and entity.entity then
entity.entity:set_detach()
end
end
end,
_add_attached = function(self, index)
local entity = self._attached_entities[index]
if entity.entity then
return
end
local entity_pos = vector.add(self._pos, entity.offset)
if not is_active(entity_pos) then
return
end
local ent = minetest.add_entity(entity_pos, entity.name):get_luaentity()
ent:from_data(entity.data)
ent.parent_id = self._id
ent.attached_id = index
entity.entity = ent.object
local master = self._attached_entities_master
if master then
self:_attach(index, master)
else
self:_set_master(index)
end
end,
_remove_attached = function(self, index)
local master = self._attached_entities_master
local entity = self._attached_entities[index]
local ent = entity.entity
entity.entity = nil
if index == master then
self:_detach_all()
local newmaster
for id, attached in pairs(self._attached_entities) do
if id ~= master and attached.entity then
newmaster = id
break
end
end
self:_set_master(newmaster)
self:_attach_all()
elseif master and ent then
ent:set_detach()
end
if ent then
ent:remove()
end
end,
_add_loaded = function(self)
for id, _ in pairs(self._attached_entities) do
self:_add_attached(id)
end
end,
getid = function(self)
return self._id
end,
getpos = function(self)
return vector.new(self._pos)
end,
setpos = function(self, pos)
self._pos = vector.new(pos)
--for _, entity in pairs(self._attached_entities) do
-- if entity.entity then
-- entity.entity:setpos(vector.add(self._pos, entity.offset))
-- end
--end
local master = self._attached_entities_master
if master then
local master_def = self._attached_entities[master]
master_def.entity:setpos(vector.add(self._pos, master_def.offset))
end
end,
getvelocity = function(self)
return vector.new(self._velocity)
end,
setvelocity = function(self, velocity)
self._velocity = vector.new(velocity)
local master = self._attached_entities_master
if master then
self._attached_entities[master].entity:setvelocity(self._velocity)
end
end,
getacceleration = function(self)
return vector.new(self._acceleration)
end,
setacceleration = function(self, acceleration)
self._acceleration = vector.new(acceleration)
local master = self._attached_entities_master
if master then
self._attached_entities[master].entity:setacceleration(self._acceleration)
end
end,
remove = function(self)
self:_detach_all()
for _, entity in pairs(self._attached_entities) do
if entity.entity then
entity.entity:remove()
end
end
luaentity.entities[self._id] = nil
end,
add_attached_entity = function(self, name, data, offset)
local index = #self._attached_entities + 1
self._attached_entities[index] = {
name = name,
data = data,
offset = vector.new(offset),
}
self:_add_attached(index)
return index
end,
remove_attached_entity = function(self, index)
self:_remove_attached(index)
self._attached_entities[index] = nil
end,
}
function luaentity.register_entity(name, prototype)
-- name = check_modname_prefix(name)
prototype.name = name
setmetatable(prototype, {__index = entitydef_default})
prototype.__index = prototype -- Make it possible to use it as metatable
luaentity.registered_entities[name] = prototype
end
-- function luaentity.get_entity_definition(entity)
-- return luaentity.registered_entities[entity.name]
-- end
function luaentity.add_entity(pos, name)
local index = luaentity.entities_index
while luaentity.entities[index] do
index = index + 1
if index >= max_entity_id then
index = 0
end
end
luaentity.entities_index = index
local entity = {
name = name,
_id = index,
_pos = vector.new(pos),
_velocity = {x = 0, y = 0, z = 0},
_acceleration = {x = 0, y = 0, z = 0},
_attached_entities = {},
}
local prototype = luaentity.registered_entities[name]
setmetatable(entity, prototype) -- Default to prototype for other methods
luaentity.entities[index] = entity
if entity.on_activate then
entity:on_activate()
end
return entity
end
-- todo: check if remove in get_staticdata works
function luaentity.get_staticdata(self)
local parent = luaentity.entities[self.parent_id]
if parent and parent._remove_attached then
parent:_remove_attached(self.attached_id)
end
return "toremove"
end
function luaentity.on_activate(self, staticdata)
if staticdata == "toremove" then
self.object:remove()
end
end
function luaentity.get_objects_inside_radius(pos, radius)
local objects = {}
local index = 1
for id, entity in pairs(luaentity.entities) do
if vector.distance(pos, entity:getpos()) <= radius then
objects[index] = entity
index = index + 1
end
end
end
minetest.register_globalstep(function(dtime)
if not luaentity.entities then
luaentity.entities = read_entities()
end
for id, entity in pairs(luaentity.entities) do
local master = entity._attached_entities_master
if master then
local master_def = entity._attached_entities[master]
local master_entity = master_def.entity
entity._pos = vector.subtract(master_entity:getpos(), master_def.offset)
entity._velocity = master_entity:getvelocity()
entity._acceleration = master_entity:getacceleration()
else
entity._pos = vector.add(vector.add(
entity._pos,
vector.multiply(entity._velocity, dtime)),
vector.multiply(entity._acceleration, 0.5 * dtime * dtime))
entity._velocity = vector.add(
entity._velocity,
vector.multiply(entity._acceleration, dtime))
end
entity:_add_loaded()
if entity.on_step then
entity:on_step(dtime)
end
end
end)

202
mods/pipeworks/models.lua Normal file
View File

@ -0,0 +1,202 @@
---------------------
-- The various models
-- Pipe models
pipeworks.pipe_leftstub = {
{ -32/64, -2/64, -6/64, 1/64, 2/64, 6/64 }, -- pipe segment against -X face
{ -32/64, -4/64, -5/64, 1/64, 4/64, 5/64 },
{ -32/64, -5/64, -4/64, 1/64, 5/64, 4/64 },
{ -32/64, -6/64, -2/64, 1/64, 6/64, 2/64 },
{ -32/64, -3/64, -8/64, -30/64, 3/64, 8/64 }, -- (the flange for it)
{ -32/64, -5/64, -7/64, -30/64, 5/64, 7/64 },
{ -32/64, -6/64, -6/64, -30/64, 6/64, 6/64 },
{ -32/64, -7/64, -5/64, -30/64, 7/64, 5/64 },
{ -32/64, -8/64, -3/64, -30/64, 8/64, 3/64 }
}
pipeworks.pipe_rightstub = {
{ -1/64, -2/64, -6/64, 32/64, 2/64, 6/64 }, -- pipe segment against +X face
{ -1/64, -4/64, -5/64, 32/64, 4/64, 5/64 },
{ -1/64, -5/64, -4/64, 32/64, 5/64, 4/64 },
{ -1/64, -6/64, -2/64, 32/64, 6/64, 2/64 },
{ 30/64, -3/64, -8/64, 32/64, 3/64, 8/64 }, -- (the flange for it)
{ 30/64, -5/64, -7/64, 32/64, 5/64, 7/64 },
{ 30/64, -6/64, -6/64, 32/64, 6/64, 6/64 },
{ 30/64, -7/64, -5/64, 32/64, 7/64, 5/64 },
{ 30/64, -8/64, -3/64, 32/64, 8/64, 3/64 }
}
pipeworks.pipe_bottomstub = {
{ -2/64, -32/64, -6/64, 2/64, 1/64, 6/64 }, -- pipe segment against -Y face
{ -4/64, -32/64, -5/64, 4/64, 1/64, 5/64 },
{ -5/64, -32/64, -4/64, 5/64, 1/64, 4/64 },
{ -6/64, -32/64, -2/64, 6/64, 1/64, 2/64 },
{ -3/64, -32/64, -8/64, 3/64, -30/64, 8/64 }, -- (the flange for it)
{ -5/64, -32/64, -7/64, 5/64, -30/64, 7/64 },
{ -6/64, -32/64, -6/64, 6/64, -30/64, 6/64 },
{ -7/64, -32/64, -5/64, 7/64, -30/64, 5/64 },
{ -8/64, -32/64, -3/64, 8/64, -30/64, 3/64 }
}
pipeworks.pipe_topstub = {
{ -2/64, -1/64, -6/64, 2/64, 32/64, 6/64 }, -- pipe segment against +Y face
{ -4/64, -1/64, -5/64, 4/64, 32/64, 5/64 },
{ -5/64, -1/64, -4/64, 5/64, 32/64, 4/64 },
{ -6/64, -1/64, -2/64, 6/64, 32/64, 2/64 },
{ -3/64, 30/64, -8/64, 3/64, 32/64, 8/64 }, -- (the flange for it)
{ -5/64, 30/64, -7/64, 5/64, 32/64, 7/64 },
{ -6/64, 30/64, -6/64, 6/64, 32/64, 6/64 },
{ -7/64, 30/64, -5/64, 7/64, 32/64, 5/64 },
{ -8/64, 30/64, -3/64, 8/64, 32/64, 3/64 }
}
pipeworks.pipe_frontstub = {
{ -6/64, -2/64, -32/64, 6/64, 2/64, 1/64 }, -- pipe segment against -Z face
{ -5/64, -4/64, -32/64, 5/64, 4/64, 1/64 },
{ -4/64, -5/64, -32/64, 4/64, 5/64, 1/64 },
{ -2/64, -6/64, -32/64, 2/64, 6/64, 1/64 },
{ -8/64, -3/64, -32/64, 8/64, 3/64, -30/64 }, -- (the flange for it)
{ -7/64, -5/64, -32/64, 7/64, 5/64, -30/64 },
{ -6/64, -6/64, -32/64, 6/64, 6/64, -30/64 },
{ -5/64, -7/64, -32/64, 5/64, 7/64, -30/64 },
{ -3/64, -8/64, -32/64, 3/64, 8/64, -30/64 }
}
pipeworks.pipe_backstub = {
{ -6/64, -2/64, -1/64, 6/64, 2/64, 32/64 }, -- pipe segment against -Z face
{ -5/64, -4/64, -1/64, 5/64, 4/64, 32/64 },
{ -4/64, -5/64, -1/64, 4/64, 5/64, 32/64 },
{ -2/64, -6/64, -1/64, 2/64, 6/64, 32/64 },
{ -8/64, -3/64, 30/64, 8/64, 3/64, 32/64 }, -- (the flange for it)
{ -7/64, -5/64, 30/64, 7/64, 5/64, 32/64 },
{ -6/64, -6/64, 30/64, 6/64, 6/64, 32/64 },
{ -5/64, -7/64, 30/64, 5/64, 7/64, 32/64 },
{ -3/64, -8/64, 30/64, 3/64, 8/64, 32/64 }
}
pipeworks.pipe_boxes = {pipeworks.pipe_leftstub, pipeworks.pipe_rightstub, pipeworks.pipe_bottomstub, pipeworks.pipe_topstub, pipeworks.pipe_frontstub, pipeworks.pipe_backstub}
pipeworks.pipe_selectboxes = {
{ -32/64, -8/64, -8/64, 8/64, 8/64, 8/64 },
{ -8/64 , -8/64, -8/64, 32/64, 8/64, 8/64 },
{ -8/64 , -32/64, -8/64, 8/64, 8/64, 8/64 },
{ -8/64 , -8/64, -8/64, 8/64, 32/64, 8/64 },
{ -8/64 , -8/64, -32/64, 8/64, 8/64, 8/64 },
{ -8/64 , -8/64, -8/64, 8/64, 8/64, 32/64 }
}
pipeworks.pipe_bendsphere = {
{ -4/64, -4/64, -4/64, 4/64, 4/64, 4/64 },
{ -5/64, -3/64, -3/64, 5/64, 3/64, 3/64 },
{ -3/64, -5/64, -3/64, 3/64, 5/64, 3/64 },
{ -3/64, -3/64, -5/64, 3/64, 3/64, 5/64 }
}
-- Tube models
pipeworks.tube_leftstub = {
{ -32/64, -9/64, -9/64, 9/64, 9/64, 9/64 }, -- tube segment against -X face
}
pipeworks.tube_rightstub = {
{ -9/64, -9/64, -9/64, 32/64, 9/64, 9/64 }, -- tube segment against +X face
}
pipeworks.tube_bottomstub = {
{ -9/64, -32/64, -9/64, 9/64, 9/64, 9/64 }, -- tube segment against -Y face
}
pipeworks.tube_topstub = {
{ -9/64, -9/64, -9/64, 9/64, 32/64, 9/64 }, -- tube segment against +Y face
}
pipeworks.tube_frontstub = {
{ -9/64, -9/64, -32/64, 9/64, 9/64, 9/64 }, -- tube segment against -Z face
}
pipeworks.tube_backstub = {
{ -9/64, -9/64, -9/64, 9/64, 9/64, 32/64 }, -- tube segment against -Z face
}
pipeworks.tube_boxes = {pipeworks.tube_leftstub, pipeworks.tube_rightstub, pipeworks.tube_bottomstub, pipeworks.tube_topstub, pipeworks.tube_frontstub, pipeworks.tube_backstub}
pipeworks.tube_selectboxes = {
{ -32/64, -10/64, -10/64, 10/64, 10/64, 10/64 },
{ -10/64 , -10/64, -10/64, 32/64, 10/64, 10/64 },
{ -10/64 , -32/64, -10/64, 10/64, 10/64, 10/64 },
{ -10/64 , -10/64, -10/64, 10/64, 32/64, 10/64 },
{ -10/64 , -10/64, -32/64, 10/64, 10/64, 10/64 },
{ -10/64 , -10/64, -10/64, 10/64, 10/64, 32/64 }
}
-- Device models
pipeworks.pipe_pumpbody = {
{ -7/16, -6/16, -7/16, 7/16, 5/16, 7/16 },
{ -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }
}
pipeworks.pipe_valvebody = {
{ -4/16, -4/16, -4/16, 4/16, 4/16, 4/16 }
}
pipeworks.pipe_valvehandle_on = {
{ -5/16, 4/16, -1/16, 0, 5/16, 1/16 }
}
pipeworks.pipe_valvehandle_off = {
{ -1/16, 4/16, -5/16, 1/16, 5/16, 0 }
}
pipeworks.pipe_sensorbody = {
{ -3/16, -2/16, -2/16, 3/16, 2/16, 2/16 }
}
pipeworks.spigot_bottomstub = {
{ -2/64, -16/64, -6/64, 2/64, 1/64, 6/64 }, -- pipe segment against -Y face
{ -4/64, -16/64, -5/64, 4/64, 1/64, 5/64 },
{ -5/64, -16/64, -4/64, 5/64, 1/64, 4/64 },
{ -6/64, -16/64, -2/64, 6/64, 1/64, 2/64 },
{ -3/64, -16/64, -8/64, 3/64, -14/64, 8/64 }, -- (the flange for it)
{ -5/64, -16/64, -7/64, 5/64, -14/64, 7/64 },
{ -6/64, -16/64, -6/64, 6/64, -14/64, 6/64 },
{ -7/64, -16/64, -5/64, 7/64, -14/64, 5/64 },
{ -8/64, -16/64, -3/64, 8/64, -14/64, 3/64 }
}
pipeworks.spigot_stream = {
{ -3/64, (-41/64)-0.01, -5/64, 3/64, -16/64, 5/64 },
{ -4/64, (-41/64)-0.01, -4/64, 4/64, -16/64, 4/64 },
{ -5/64, (-41/64)-0.01, -3/64, 5/64, -16/64, 3/64 }
}
pipeworks.entry_panel = {
{ -8/16, -8/16, -1/16, 8/16, 8/16, 1/16 }
}
pipeworks.fountainhead_model = {
{ -2/64, -32/64, -6/64, 2/64, 21/64, 6/64 }, -- main segment
{ -4/64, -32/64, -5/64, 4/64, 21/64, 5/64 },
{ -5/64, -32/64, -4/64, 5/64, 21/64, 4/64 },
{ -6/64, -32/64, -2/64, 6/64, 21/64, 2/64 },
{ -3/64, -32/64, -8/64, 3/64, -30/64, 8/64 }, -- bottom flange
{ -5/64, -32/64, -7/64, 5/64, -30/64, 7/64 },
{ -6/64, -32/64, -6/64, 6/64, -30/64, 6/64 },
{ -7/64, -32/64, -5/64, 7/64, -30/64, 5/64 },
{ -8/64, -32/64, -3/64, 8/64, -30/64, 3/64 },
{ -3/64, 20/64, -8/64, 3/64, 32/64, 8/64 }, -- top flange/outlet
{ -5/64, 20/64, -7/64, 5/64, 32/64, 7/64 },
{ -6/64, 20/64, -6/64, 6/64, 32/64, 6/64 },
{ -7/64, 20/64, -5/64, 7/64, 32/64, 5/64 },
{ -8/64, 20/64, -3/64, 8/64, 32/64, 3/64 }
}

226
mods/pipeworks/pipes.lua Normal file
View File

@ -0,0 +1,226 @@
-- This file supplies the steel pipes
local REGISTER_COMPATIBILITY = true
local pipes_empty_nodenames = {}
local pipes_full_nodenames = {}
local vti = {4, 3, 2, 1, 6, 5}
local cconnects = {{}, {1}, {1, 2}, {1, 3}, {1, 3, 5}, {1, 2, 3}, {1, 2, 3, 5}, {1, 2, 3, 4}, {1, 2, 3, 4, 5}, {1, 2, 3, 4, 5, 6}}
for index, connects in ipairs(cconnects) do
local outboxes = {}
local outsel = {}
local outimgs = {}
for i = 1, 6 do
outimgs[vti[i]] = "pipeworks_plain.png"
end
local jx = 0
local jy = 0
local jz = 0
for _, v in ipairs(connects) do
if v == 1 or v == 2 then
jx = jx + 1
elseif v == 3 or v == 4 then
jy = jy + 1
else
jz = jz + 1
end
pipeworks.add_node_box(outboxes, pipeworks.pipe_boxes[v])
table.insert(outsel, pipeworks.pipe_selectboxes[v])
outimgs[vti[v]] = "pipeworks_pipe_end.png"
end
if #connects == 1 then
local v = connects[1]
v = v-1 + 2*(v%2) -- Opposite side
outimgs[vti[v]] = "^pipeworks_plain.png"
end
if #connects >= 2 then
pipeworks.add_node_box(outboxes, pipeworks.pipe_bendsphere)
end
if jx == 2 and jy ~= 2 and jz ~= 2 then
outimgs[5] = pipeworks.liquid_texture.."^pipeworks_windowed_XXXXX.png"
outimgs[6] = outimgs[5]
end
local pgroups = {snappy = 3, pipe = 1, not_in_creative_inventory = 1}
local pipedesc = "Pipe segement".." "..dump(connects).."... You hacker, you."
local image = nil
if #connects == 0 then
pgroups = {snappy = 3, tube = 1}
pipedesc = "Pipe segment"
image = "pipeworks_pipe_inv.png"
end
--table.insert(pipeworks.tubenodes, name.."_"..tname)
minetest.register_node("pipeworks:pipe_"..index.."_empty", {
description = pipedesc,
drawtype = "nodebox",
tiles = pipeworks.fix_image_names(outimgs, "_empty"),
sunlight_propagates = true,
inventory_image = image,
wield_image = image,
paramtype = "light",
paramtype2 = "facedir",
selection_box = {
type = "fixed",
fixed = outsel
},
node_box = {
type = "fixed",
fixed = outboxes
},
groups = pgroups,
sounds = default.node_sound_wood_defaults(),
walkable = true,
drop = "pipeworks:pipe_1_empty",
after_place_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
after_dig_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end
})
local pgroups = {snappy = 3, pipe = 1, not_in_creative_inventory = 1}
minetest.register_node("pipeworks:pipe_"..index.."_loaded", {
description = pipedesc,
drawtype = "nodebox",
tiles = pipeworks.fix_image_names(outimgs, "_loaded"),
sunlight_propagates = true,
paramtype = "light",
paramtype2 = "facedir",
selection_box = {
type = "fixed",
fixed = outsel
},
node_box = {
type = "fixed",
fixed = outboxes
},
groups = pgroups,
sounds = default.node_sound_wood_defaults(),
walkable = true,
drop = "pipeworks:pipe_1_empty",
after_place_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
after_dig_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end
})
table.insert(pipes_empty_nodenames, "pipeworks:pipe_"..index.."_empty")
table.insert(pipes_full_nodenames, "pipeworks:pipe_"..index.."_loaded")
end
if REGISTER_COMPATIBILITY then
local cempty = "pipeworks:pipe_compatibility_empty"
local cloaded = "pipeworks:pipe_compatibility_loaded"
minetest.register_node(cempty, {
drawtype = "airlike",
sunlight_propagates = true,
paramtype = "light",
inventory_image = "pipeworks_pipe_inv.png",
wield_image = "pipeworks_pipe_inv.png",
description = "Pipe Segment (legacy)",
groups = {not_in_creative_inventory = 1, pipe_to_update = 1},
drop = "pipeworks:pipe_1_empty",
after_place_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
})
minetest.register_node(cloaded, {
drawtype = "airlike",
sunlight_propagates = true,
paramtype = "light",
inventory_image = "pipeworks_pipe_inv.png",
groups = {not_in_creative_inventory = 1, pipe_to_update = 1},
drop = "pipeworks:pipe_1_empty",
after_place_node = function(pos)
pipeworks.scan_for_pipe_objects(pos)
end,
})
for xm = 0, 1 do
for xp = 0, 1 do
for ym = 0, 1 do
for yp = 0, 1 do
for zm = 0, 1 do
for zp = 0, 1 do
local pname = xm..xp..ym..yp..zm..zp
minetest.register_alias("pipeworks:pipe_"..pname.."_empty", cempty)
minetest.register_alias("pipeworks:pipe_"..pname.."_loaded", cloaded)
end
end
end
end
end
end
minetest.register_abm({
nodenames = {"group:pipe_to_update"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local minp = {x = pos.x-1, y = pos.y-1, z = pos.z-1}
local maxp = {x = pos.x+1, y = pos.y+1, z = pos.z+1}
if table.getn(minetest.find_nodes_in_area(minp, maxp, "ignore")) == 0 then
pipeworks.scan_for_pipe_objects(pos)
end
end
})
end
table.insert(pipes_empty_nodenames,"pipeworks:valve_on_empty")
table.insert(pipes_empty_nodenames,"pipeworks:valve_off_empty")
table.insert(pipes_empty_nodenames,"pipeworks:entry_panel_empty")
table.insert(pipes_empty_nodenames,"pipeworks:flow_sensor_empty")
table.insert(pipes_full_nodenames,"pipeworks:valve_on_loaded")
table.insert(pipes_full_nodenames,"pipeworks:entry_panel_loaded")
table.insert(pipes_full_nodenames,"pipeworks:flow_sensor_loaded")
minetest.register_abm({
nodenames = pipes_empty_nodenames,
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
pipeworks.check_for_inflows(pos,node)
end
})
minetest.register_abm({
nodenames = pipes_full_nodenames,
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
pipeworks.check_sources(pos,node)
end
})
minetest.register_abm({
nodenames = {"pipeworks:spigot","pipeworks:spigot_pouring"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
pipeworks.spigot_check(pos,node)
end
})
minetest.register_abm({
nodenames = {"pipeworks:fountainhead","pipeworks:fountainhead_pouring"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
pipeworks.fountainhead_check(pos,node)
end
})

View File

@ -0,0 +1,181 @@
local filename=minetest.get_worldpath() .. "/teleport_tubes"
local function read_file()
local f = io.open(filename, "r")
if f == nil then return {} end
local t = f:read("*all")
f:close()
if t == "" or t == nil then return {} end
return minetest.deserialize(t)
end
local function write_file(tbl)
local f = io.open(filename, "w")
f:write(minetest.serialize(tbl))
f:close()
end
local function update_pos_in_file(pos)
local tbl=read_file()
for _, val in ipairs(tbl) do
if val.x == pos.x and val.y == pos.y and val.z == pos.z then
local meta = minetest.get_meta(val)
val.channel = meta:get_string("channel")
val.cr = meta:get_int("can_receive")
end
end
write_file(tbl)
end
local function add_tube_in_file(pos,channel, cr)
local tbl=read_file()
for _,val in ipairs(tbl) do
if val.x==pos.x and val.y==pos.y and val.z==pos.z then
return
end
end
table.insert(tbl,{x=pos.x,y=pos.y,z=pos.z,channel=channel,cr=cr})
write_file(tbl)
end
local function remove_tube_in_file(pos)
local tbl = read_file()
local newtbl = {}
for _, val in ipairs(tbl) do
if val.x ~= pos.x or val.y ~= pos.y or val.z ~= pos.z then
table.insert(newtbl, val)
end
end
write_file(newtbl)
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_tubes_in_file(pos,channel)
local tbl = read_file()
local newtbl = {}
local changed = false
for _, val in ipairs(tbl) do
local meta = minetest.get_meta(val)
local name = read_node_with_vm(val)
local is_loaded = (minetest.get_node_or_nil(val) ~= nil)
local is_teleport_tube = minetest.registered_nodes[name] and minetest.registered_nodes[name].is_teleport_tube
if is_teleport_tube then
if is_loaded and (val.channel ~= meta:get_string("channel") or val.cr ~= meta:get_int("can_receive")) then
val.channel = meta:get_string("channel")
val.cr = meta:get_int("can_receive")
changed = true
end
if val.cr == 1 and val.channel == channel and (val.x ~= pos.x or val.y ~= pos.y or val.z ~= pos.z) then
table.insert(newtbl, val)
end
else
val.to_remove = true
changed = true
end
end
if changed then
local updated = {}
for _, val in ipairs(tbl) do
if not val.to_remove then
table.insert(updated, val)
end
end
write_file(updated)
end
return newtbl
end
local teleport_noctr_textures={"pipeworks_teleport_tube_noctr.png","pipeworks_teleport_tube_noctr.png","pipeworks_teleport_tube_noctr.png",
"pipeworks_teleport_tube_noctr.png","pipeworks_teleport_tube_noctr.png","pipeworks_teleport_tube_noctr.png"}
local teleport_plain_textures={"pipeworks_teleport_tube_plain.png","pipeworks_teleport_tube_plain.png","pipeworks_teleport_tube_plain.png",
"pipeworks_teleport_tube_plain.png","pipeworks_teleport_tube_plain.png","pipeworks_teleport_tube_plain.png"}
local teleport_end_textures={"pipeworks_teleport_tube_end.png","pipeworks_teleport_tube_end.png","pipeworks_teleport_tube_end.png",
"pipeworks_teleport_tube_end.png","pipeworks_teleport_tube_end.png","pipeworks_teleport_tube_end.png"}
local teleport_short_texture="pipeworks_teleport_tube_short.png"
local teleport_inv_texture="pipeworks_teleport_tube_inv.png"
local function set_teleport_tube_formspec(meta)
local cr = meta:get_int("can_receive") ~= 0
meta:set_string("formspec","size[10.5,1;]"..
"field[0,0.5;7,1;channel;Channel:;${channel}]"..
"button[8,0;2.5,1;"..(cr and "cr0" or "cr1")..";"..
(cr and "Send and Receive" or "Send only").."]")
end
pipeworks.register_tube("pipeworks:teleport_tube","Teleporting Pneumatic Tube Segment",teleport_plain_textures,
teleport_noctr_textures,teleport_end_textures,teleport_short_texture,teleport_inv_texture, {
is_teleport_tube = true,
tube = {
can_go = function(pos,node,velocity,stack)
velocity.x = 0
velocity.y = 0
velocity.z = 0
local meta = minetest.get_meta(pos)
local channel = meta:get_string("channel")
local target = get_tubes_in_file(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_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("channel","")
meta:set_int("can_receive",1)
add_tube_in_file(pos,"")
set_teleport_tube_formspec(meta)
end,
on_receive_fields = function(pos,formname,fields,sender)
local meta = minetest.get_meta(pos)
--check for private channels
if fields.channel ~= nil then
local name, mode = fields.channel:match("^([^:;]+)([:;])")
if name and mode and name ~= sender:get_player_name() then
--channels starting with '[name]:' can only be used by the named player
if mode == ":" then
minetest.chat_send_player(sender:get_player_name(), "Sorry, channel '"..fields.channel.."' is reserved for exclusive use by "..name)
return
--channels starting with '[name];' can be used by other players, but cannot be received from
elseif mode == ";" and (fields.cr1 or (meta:get_int("can_receive") ~= 0 and not fields.cr0)) then
minetest.chat_send_player(sender:get_player_name(), "Sorry, receiving from channel '"..fields.channel.."' is reserved for "..name)
return
end
end
end
if fields.channel==nil then fields.channel=meta:get_string("channel") end
meta:set_string("channel",fields.channel)
remove_tube_in_file(pos)
if fields.cr0 then meta:set_int("can_receive", 0) end
if fields.cr1 then meta:set_int("can_receive", 1) end
local cr = meta:get_int("can_receive")
add_tube_in_file(pos, fields.channel, meta:get_int("can_receive"))
set_teleport_tube_formspec(meta)
end,
on_destruct = function(pos)
remove_tube_in_file(pos)
end})
if minetest.get_modpath("mesecons_mvps") ~= nil then
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
update_pos_in_file(n.pos)
end
end
end)
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 755 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 819 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 560 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 841 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 841 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 841 B

Some files were not shown because too many files have changed in this diff Show More