From dbcaf78044739625574939cea64304fbeae43e55 Mon Sep 17 00:00:00 2001 From: Evert Prants Date: Wed, 12 Dec 2018 21:06:10 +0200 Subject: [PATCH] fluid_lib now implements transfer ducts --- README.md | 18 +- fluid_tanks/init.lua | 8 +- fluid_tanks/register.lua | 15 ++ fluid_transfer/api.lua | 104 ++++++++ fluid_transfer/crafting.lua | 20 ++ fluid_transfer/depends.txt | 2 + fluid_transfer/init.lua | 16 ++ fluid_transfer/mod.conf | 3 + fluid_transfer/models/fluid_transfer_pump.obj | 185 +++++++++++++ fluid_transfer/network.lua | 252 ++++++++++++++++++ fluid_transfer/register.lua | 23 ++ .../textures/fluid_transfer_duct.png | Bin 0 -> 5386 bytes .../textures/fluid_transfer_pump.png | Bin 0 -> 5264 bytes 13 files changed, 640 insertions(+), 6 deletions(-) create mode 100644 fluid_tanks/register.lua create mode 100644 fluid_transfer/api.lua create mode 100644 fluid_transfer/crafting.lua create mode 100644 fluid_transfer/depends.txt create mode 100644 fluid_transfer/init.lua create mode 100644 fluid_transfer/mod.conf create mode 100644 fluid_transfer/models/fluid_transfer_pump.obj create mode 100644 fluid_transfer/network.lua create mode 100644 fluid_transfer/register.lua create mode 100644 fluid_transfer/textures/fluid_transfer_duct.png create mode 100644 fluid_transfer/textures/fluid_transfer_pump.png diff --git a/README.md b/README.md index 8e532c1..8df2b3a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Universal Fluid API -This API adds support for `fluid_buffers` inside nodes. This means that nodes can contain fluid. +This API adds support for `fluid_buffers` inside nodes. This means that nodes can contain fluid. Simple fluid transfer is also implemented in `fluid_transfer`. +This mod implements [node_io](https://github.com/auouymous/node_io). Note that while it is recommended that you install this mod also, it is not required in order to function. **Enable ALL the mods provided by this "modpack"!** ## How to Use 1. Add the node to the `fluid_container` group. @@ -18,6 +19,10 @@ This API adds support for `fluid_buffers` inside nodes. This means that nodes ca * **buffer_name_fluid** = `string` - Source node of the fluid. * **buffer_name_fluid_storage** = `int` - How much fluid there is in this buffer. +4. Register your node **(DO NOT MISS THIS STEP! TRANSFER WILL NOT WORK OTHERWISE!)**. + +Just call `fluid_lib.register_node(nodename)`. + ## API All numbers are in **milli-buckets** (1 bucket = 1000 mB). @@ -51,6 +56,17 @@ All numbers are in **milli-buckets** (1 bucket = 1000 mB). * `fluid_lib.take_from_buffer(pos, buffer, count)` * Actually takes the fluid. On success, returns the source block that was taken and how much was actually taken. +* `fluid_lib.register_node(nodename)` + * Registers a node that has fluid buffers. This is IMPORTANT! + +* `fluid_lib.register_extractor_node(nodename, nodedef)` + * Registers a node that can extract fluid from another node (in front of self) and put it into ducts. + * `fluid_pump_capacity` variable in nodedef determines how much fluid (in mB) this node can "pump" every second. + +* `fluid_lib.register_transfer_node(nodename, nodedef)` + * Registers a node that can transfer fluids. This is effectively a fluid duct. + * `duct_density` variable in nodedef determines the diameter of the duct (custom node_box is created). + * `bucket.register_liquid(source, flowing, itemname, inventory_image, name, groups, force_renew)` * Works exactly the same as the default `bucket` mod, except it adds callbacks to insert/take fluid from nodes. * `inventory_image` can be a **ColorString**. diff --git a/fluid_tanks/init.lua b/fluid_tanks/init.lua index eca4571..6e4aaa5 100644 --- a/fluid_tanks/init.lua +++ b/fluid_tanks/init.lua @@ -1,6 +1,8 @@ -- Fluid Tanks -- Copyright (c) 2018 Evert "Diamond" Prants +local modpath = minetest.get_modpath(minetest.get_current_modname()) + fluid_tanks = {} -- Preserve fluid count in the item stack dropped @@ -199,8 +201,4 @@ function fluid_tanks.register_tank(tankname, def) end end -fluid_tanks.register_tank("fluid_tanks:tank", { - description = "Fluid Tank", - capacity = 16000, - accepts = true, -}) +dofile(modpath.."/register.lua") diff --git a/fluid_tanks/register.lua b/fluid_tanks/register.lua new file mode 100644 index 0000000..3b2c25f --- /dev/null +++ b/fluid_tanks/register.lua @@ -0,0 +1,15 @@ + +fluid_tanks.register_tank("fluid_tanks:tank", { + description = "Fluid Tank", + capacity = 8000, + accepts = true, +}) + +minetest.register_craft({ + output = "fluid_tanks:tank", + recipe = { + {"default:glass", "default:glass", "default:glass"}, + {"default:glass", "default:steel_ingot", "default:glass"}, + {"default:glass", "default:glass", "default:glass"}, + } +}) diff --git a/fluid_transfer/api.lua b/fluid_transfer/api.lua new file mode 100644 index 0000000..d3f85d0 --- /dev/null +++ b/fluid_transfer/api.lua @@ -0,0 +1,104 @@ +-- Nodes for transferring fluids +-- All units are in millibuckets (1 bucket) + +-- This is the node that takes fluid from another node. +function fluid_lib.register_extractor_node(nodename, nodedef) + if not nodedef.groups then + nodedef.groups = {} + end + + nodedef.groups["fluid_transport_source"] = 1 + nodedef.paramtype2 = "facedir" + nodedef.legacy_facedir_simple = true + nodedef.on_timer = fluid_lib.transfer_timer_tick + + local orig_construct = nodedef.on_construct + nodedef.on_construct = function (pos) + local meta = minetest.get_meta(pos) + meta:set_int("fluid_store", 0) + meta:set_string("fluid", "") + + fluid_lib.refresh_node(pos) + + if orig_construct then + orig_construct(pos) + end + end + + nodedef.on_punch = function (pos, node, puncher, pointed_thing) + minetest.get_node_timer(pos):start(1.0) + minetest.node_punch(pos, node, puncher, pointed_thing) + end + + -- Default transfer capacity + if not nodedef.fluid_pump_capacity then + nodedef.fluid_pump_capacity = 1000 + end + + minetest.register_node(nodename, nodedef) +end + +-- This is the node that allows for fluid transfer. +function fluid_lib.register_transfer_node(nodename, nodedef) + if not nodedef.groups then + nodedef.groups = {} + end + + nodedef.groups["fluid_transport"] = 1 + + -- Duct node density + local cd = 1/7 + + if nodedef.duct_density then + cd = math.abs(nodedef.duct_density) + nodedef.duct_density = nil + end + + -- Default values, including the nodebox + local defaults = { + drawtype = "nodebox", + node_box = { + type = "connected", + fixed = { + {-cd, -cd, -cd, cd, cd, cd} + }, + connect_front = { + {-cd, -cd, -1/2, cd, cd, -cd} + }, + connect_back = { + {-cd, -cd, cd, cd, cd, 1/2} + }, + connect_top = { + {-cd, cd, -cd, cd, 1/2, cd} + }, + connect_bottom = { + {-cd, -1/2, -cd, cd, -cd, cd} + }, + connect_left = { + {-1/2, -cd, -cd, cd, cd, cd} + }, + connect_right = { + {cd, -cd, -cd, 1/2, cd, cd} + }, + }, + paramtype = "light", + connect_sides = { "top", "bottom", "front", "left", "back", "right" }, + is_ground_content = false, + connects_to = { + "group:fluid_transport", + "group:fluid_transport_source", + "group:fluid_container" + }, + } + + for k,v in pairs(defaults) do + if not nodedef[k] then + nodedef[k] = v + end + end + + nodedef.on_construct = fluid_lib.refresh_node + nodedef.after_destruct = fluid_lib.refresh_node + + minetest.register_node(nodename, nodedef) +end diff --git a/fluid_transfer/crafting.lua b/fluid_transfer/crafting.lua new file mode 100644 index 0000000..2900319 --- /dev/null +++ b/fluid_transfer/crafting.lua @@ -0,0 +1,20 @@ + +-- Duct +minetest.register_craft({ + output = "fluid_transfer:fluid_duct 8", + recipe = { + {"default:glass", "default:glass", "default:glass"}, + {"", "", ""}, + {"default:glass", "default:glass", "default:glass"}, + } +}) + +-- Pump +minetest.register_craft({ + output = "fluid_transfer:fluid_transfer_pump", + recipe = { + {"", "fluid_transfer:fluid_duct", ""}, + {"default:glass", "default:mese_crystal", "default:glass"}, + {"default:stone", "default:stone", "default:stone"}, + } +}) diff --git a/fluid_transfer/depends.txt b/fluid_transfer/depends.txt new file mode 100644 index 0000000..2cb79a4 --- /dev/null +++ b/fluid_transfer/depends.txt @@ -0,0 +1,2 @@ +fluid_lib +node_io? diff --git a/fluid_transfer/init.lua b/fluid_transfer/init.lua new file mode 100644 index 0000000..9da2a8a --- /dev/null +++ b/fluid_transfer/init.lua @@ -0,0 +1,16 @@ +-- Universal Fluid API implementation +-- Copyright (c) 2018 Evert "Diamond" Prants + +local modpath = minetest.get_modpath(minetest.get_current_modname()) + +-- Transfer network +dofile(modpath.."/network.lua") + +-- API for ducts and pumps +dofile(modpath.."/api.lua") + +-- Simple duct and pump +dofile(modpath.."/register.lua") + +-- Crafting recipes +dofile(modpath.."/crafting.lua") diff --git a/fluid_transfer/mod.conf b/fluid_transfer/mod.conf new file mode 100644 index 0000000..8e13276 --- /dev/null +++ b/fluid_transfer/mod.conf @@ -0,0 +1,3 @@ +name = fluid_transfer +depends = fluid_lib +optional_depends = node_io diff --git a/fluid_transfer/models/fluid_transfer_pump.obj b/fluid_transfer/models/fluid_transfer_pump.obj new file mode 100644 index 0000000..c328332 --- /dev/null +++ b/fluid_transfer/models/fluid_transfer_pump.obj @@ -0,0 +1,185 @@ +o Node +v 0.400000 0.400000 -0.370263 +v 0.400000 0.400000 -0.497499 +v -0.400000 0.400000 -0.497499 +v -0.400000 0.400000 -0.370263 +v 0.400000 -0.400000 -0.370263 +v 0.400000 -0.400000 -0.497499 +v -0.400000 -0.400000 -0.497499 +v -0.400000 -0.400000 -0.370263 +v 0.320000 0.320000 -0.243027 +v 0.320000 0.320000 -0.370263 +v -0.320000 0.320000 -0.370263 +v -0.320000 0.320000 -0.243027 +v 0.320000 -0.320000 -0.243027 +v 0.320000 -0.320000 -0.370263 +v -0.320000 -0.320000 -0.370263 +v -0.320000 -0.320000 -0.243027 +v 0.256000 0.256000 -0.115790 +v 0.256000 0.256000 -0.243027 +v -0.256000 0.256000 -0.243027 +v -0.256000 0.256000 -0.115790 +v 0.256000 -0.256000 -0.115790 +v 0.256000 -0.256000 -0.243026 +v -0.256000 -0.256000 -0.243026 +v -0.256000 -0.256000 -0.115790 +v 0.204800 0.204800 0.008210 +v 0.204800 0.204800 -0.119027 +v -0.204800 0.204800 -0.119027 +v -0.204800 0.204800 0.008210 +v 0.204800 -0.204800 0.008210 +v 0.204800 -0.204800 -0.119026 +v -0.204800 -0.204800 -0.119026 +v -0.204800 -0.204800 0.008210 +v 0.146894 0.146894 0.503596 +v 0.146894 0.146894 -0.002413 +v -0.146894 0.146894 -0.002413 +v -0.146894 0.146894 0.503596 +v 0.146894 -0.146894 0.503596 +v 0.146894 -0.146894 -0.002413 +v -0.146894 -0.146894 -0.002413 +v -0.146894 -0.146894 0.503596 +v 0.320665 0.320665 -0.497499 +v -0.320665 0.320665 -0.497499 +v 0.320664 -0.320665 -0.497499 +v -0.320665 -0.320665 -0.497499 +vt 0.712514 0.681510 +vt 0.975774 0.681510 +vt 0.975774 0.944770 +vt 0.712514 0.944770 +vt 0.712514 0.681510 +vt 0.975774 0.681510 +vt 0.975774 0.944770 +vt 0.712514 0.944770 +vt 0.975774 0.681510 +vt 0.975774 0.944770 +vt 0.712514 0.944770 +vt 0.315390 0.302988 +vt 0.315390 0.039728 +vt 0.315390 0.039728 +vt 0.315390 0.302988 +vt 0.712514 0.681510 +vt 0.975774 0.681510 +vt 0.975774 0.944770 +vt 0.052130 0.039728 +vt 0.315390 0.039728 +vt 0.315390 0.302988 +vt 0.052130 0.302988 +vt 0.052130 0.039728 +vt 0.315390 0.039728 +vt 0.315390 0.302988 +vt 0.052130 0.302988 +vt 0.052130 0.039728 +vt 0.315390 0.039728 +vt 0.315390 0.302988 +vt 0.052130 0.302988 +vt 0.315390 0.039728 +vt 0.315390 0.302988 +vt 0.052130 0.302988 +vt 0.052130 0.039728 +vt 0.315390 0.039728 +vt 0.052130 0.302988 +vt 0.052130 0.039728 +vt 0.315390 0.039728 +vt 0.315390 0.302988 +vt 0.315390 0.039728 +vt 0.315390 0.302988 +vt 0.052130 0.302988 +vt 0.052130 0.039728 +vt 0.315390 0.039728 +vt 0.315390 0.302988 +vt 0.052130 0.302988 +vt 0.052130 0.039728 +vt 0.315390 0.039728 +vt 0.315390 0.302988 +vt 0.052130 0.302988 +vt 0.315390 0.039728 +vt 0.315390 0.302988 +vt 0.052130 0.302988 +vt 0.052130 0.039728 +vt 0.315390 0.039728 +vt 0.052130 0.302988 +vt 0.052130 0.039728 +vt 0.315390 0.039728 +vt 0.315390 0.302988 +vt 0.315390 0.039728 +vt 0.315390 0.302988 +vt 0.052130 0.302988 +vt 0.113358 0.155808 +vt 0.139491 0.183677 +vt 0.052150 0.175815 +vt 0.070263 0.158170 +vt 0.118317 0.113646 +vt 0.075071 0.114371 +vt 0.052211 0.096257 +vt 0.139491 0.086694 +vt 0.975306 0.069495 +vt 0.371324 0.069495 +vt 0.371324 0.276848 +vt 0.975306 0.276848 +vt 0.975306 0.069495 +vt 0.975306 0.276848 +vt 0.371324 0.276849 +vt 0.371324 0.069495 +vt 0.975125 0.070933 +vt 0.975125 0.278286 +vt 0.371143 0.278286 +vt 0.371143 0.070933 +vt 0.371143 0.070933 +vt 0.371143 0.278286 +vt 0.975125 0.278286 +vt 0.975125 0.070933 +vt 0.043937 0.339371 +vt 0.658425 0.339371 +vt 0.658425 0.953858 +vt 0.043937 0.953858 +vt 0.052130 0.302988 +vt 0.315390 0.302988 +vt 0.315390 0.302988 +vt 0.052130 0.302988 +vt 0.315390 0.039728 +vt 0.052130 0.039728 +vt 0.052130 0.039728 +vt 0.315390 0.039728 +vt 0.052130 0.302988 +vt 0.315390 0.302988 +vt 0.315390 0.302988 +vt 0.052130 0.302988 +vn 0.0000 1.0000 -0.0000 +vn 0.0000 -1.0000 0.0000 +vn 1.0000 -0.0000 -0.0000 +vn 0.0000 0.0000 -1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +s off +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 5/5/2 8/6/2 7/7/2 6/8/2 +f 1/1/3 5/9/3 6/10/3 2/11/3 +f 3/12/4 2/13/4 41/14/4 42/15/4 +f 3/16/5 7/17/5 8/18/5 4/4/5 +f 5/19/6 1/20/6 4/21/6 8/22/6 +f 9/23/1 10/24/1 11/25/1 12/26/1 +f 13/27/2 16/28/2 15/29/2 14/30/2 +f 9/23/3 13/31/3 14/32/3 10/33/3 +f 10/34/4 14/35/4 15/29/4 11/36/4 +f 11/37/5 15/38/5 16/39/5 12/26/5 +f 13/27/6 9/40/6 12/41/6 16/42/6 +f 17/43/1 18/44/1 19/45/1 20/46/1 +f 21/47/2 24/48/2 23/49/2 22/50/2 +f 17/43/3 21/51/3 22/52/3 18/53/3 +f 18/54/4 22/55/4 23/49/4 19/56/4 +f 19/57/5 23/58/5 24/59/5 20/46/5 +f 21/47/6 17/60/6 20/61/6 24/62/6 +f 25/63/1 26/64/1 27/65/1 28/66/1 +f 29/67/2 32/68/2 31/69/2 30/70/2 +f 25/63/3 29/67/3 30/70/3 26/64/3 +f 27/65/5 31/69/5 32/68/5 28/66/5 +f 29/67/6 25/63/6 28/66/6 32/68/6 +f 33/71/1 34/72/1 35/73/1 36/74/1 +f 37/75/2 40/76/2 39/77/2 38/78/2 +f 33/79/3 37/80/3 38/81/3 34/82/3 +f 35/83/5 39/84/5 40/85/5 36/86/5 +f 41/87/4 43/88/4 44/89/4 42/90/4 +f 6/91/4 7/92/4 44/93/4 43/94/4 +f 7/95/4 3/96/4 42/97/4 44/98/4 +f 2/99/4 6/100/4 43/101/4 41/102/4 diff --git a/fluid_transfer/network.lua b/fluid_transfer/network.lua new file mode 100644 index 0000000..52d9bfc --- /dev/null +++ b/fluid_transfer/network.lua @@ -0,0 +1,252 @@ +local node_io_present = minetest.get_modpath("node_io") ~= nil +-- Network graphs are built eminating from provider nodes. +-- TODO: Caching + +--------------------- +-- Graph Functions -- +--------------------- + +local function flatten(map) + local list = {} + for key, value in pairs(map) do + list[#list + 1] = value + end + return list +end + +local function get_node_property(meta, pos, prop) + local value = meta:get_int(prop) + + if value == 0 or value == nil then + local nname = minetest.get_node(pos).name + local ndef = minetest.registered_nodes[nname] + value = ndef[prop] + end + + if not value then return 0 end + + return value +end + +local function face_front(pos, fd) + local back = minetest.facedir_to_dir(fd) + local front = table.copy(back) + + front.x = front.x * -1 + pos.x + front.y = front.y * -1 + pos.y + front.z = front.z * -1 + pos.z + + return front +end + +local function clear_networks_from_node(pos) + local meta = minetest.get_meta(pos) + meta:set_string("network_id", "") +end + +local function add_node(nodes, pos, pnodeid) + local node_id = minetest.hash_node_position(pos) + if nodes[node_id] then + return false + end + nodes[node_id] = pos + return true +end + +local function add_duct_node(nodes, pos, pnodeid, queue) + if add_node(nodes, pos, pnodeid) then + queue[#queue + 1] = pos + end +end + +local function check_node(targets, all_nodes, pos, p_pos, pnodeid, queue) + local node = minetest.get_node(pos) + local meta = minetest.get_meta(pos) + local ndef = minetest.registered_nodes[node.name] + + if minetest.get_item_group(node.name, "fluid_transport") > 0 then + add_duct_node(all_nodes, pos, pnodeid, queue) + return + end + + if not ndef['node_io_can_put_liquid'] or not ndef['node_io_can_put_liquid'](pos, node, "") then + return + end + + add_node(targets, pos, pnodeid) +end + +local function traverse_network(targets, all_nodes, pos, p_pos, pnodeid, queue) + local positions = { + {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+1, z=pos.z}, + {x=pos.x, y=pos.y-1, z=pos.z}, + {x=pos.x, y=pos.y, z=pos.z+1}, + {x=pos.x, y=pos.y, z=pos.z-1}} + for _, cur_pos in pairs(positions) do + check_node(targets, all_nodes, cur_pos, p_pos, pnodeid, queue) + end +end + +local function fluid_targets(p_pos, pos) + local provider = minetest.get_node(p_pos) + local pnodeid = minetest.pos_to_string(p_pos) + + local targets = {} + local queue = {} + local all_nodes = {} + + local node = minetest.get_node(pos) + local ndef = minetest.registered_nodes[node.name] + if node and minetest.get_item_group(node.name, "fluid_transport") > 0 then + add_duct_node(all_nodes, pos, pnodeid, queue) + elseif node and ndef['node_io_can_put_liquid'] and ndef['node_io_can_put_liquid'](pos, node, "") then + queue = {p_pos} + end + + while next(queue) do + local to_visit = {} + for _, posi in ipairs(queue) do + traverse_network(targets, all_nodes, posi, p_pos, pnodeid, to_visit) + end + queue = to_visit + end + + targets = flatten(targets) + all_nodes = flatten(all_nodes) + + return targets +end + +function fluid_lib.transfer_timer_tick(pos, elapsed) + local refresh = true + local node = minetest.get_node_or_nil(pos) + + if not node then + return false + end + + local meta = minetest.get_meta(pos) + local targets = {} + + -- Only allow the node directly behind to be a start of a network + local tpos = vector.add(minetest.facedir_to_dir(node.param2), pos) + local tnode = minetest.get_node(tpos) + local ndef = minetest.registered_nodes[tnode.name] + if minetest.get_item_group(tnode.name, "fluid_transport") == 0 and + (not ndef['node_io_can_put_liquid'] or not ndef['node_io_can_put_liquid'](tpos, tnode, "")) then + minetest.forceload_free_block(pos) + return + end + + -- Retrieve network + targets = fluid_targets(pos, tpos) + + -- No targets, don't proceed + if #targets == 0 then + return true + end + + -- Begin transfer + local srcpos = face_front(pos, node.param2) + local srcnode = minetest.get_node(srcpos) + + -- Make sure source node is not air + if not srcnode or srcnode.name == "air" then + return true + end + + local srcdef = minetest.registered_nodes[srcnode.name] + + -- Make sure source node is a registered fluid container + if not srcdef['node_io_can_take_liquid'] then + return false + end + + local c = srcdef.node_io_can_take_liquid(srcpos, srcnode, "") + if not c then return false end + + local srcmeta = minetest.get_meta(srcpos) + local srcdef = minetest.registered_nodes[srcnode.name] + local fl_size = srcdef.node_io_get_liquid_size(srcpos, srcnode, "") + local buffers = {} + for i = 1, fl_size do + buffers[i] = srcdef.node_io_get_liquid_name(srcpos, srcnode, "", i) + end + if not #buffers then return true end + + -- Limit the amount of fluid pumped per cycle + local pcapability = get_node_property(meta, pos, "fluid_pump_capacity") + local pumped = 0 + + -- Transfer some fluid here + for _,pos in pairs(targets) do + if not vector.equals(pos, srcpos) then + if pumped >= pcapability then break end + local destnode = minetest.get_node(pos) + local destdef = minetest.registered_nodes[destnode.name] + local pp = nil + + if destdef['node_io_can_put_liquid'] then + if destdef.node_io_can_put_liquid(pos, destnode, "") then + pp = {} + local fl_size = destdef.node_io_get_liquid_size(pos, destnode, "") + for i = 1, fl_size do + pp[i] = destdef.node_io_get_liquid_name(pos, destnode, "", i) + end + if not #pp then pp = nil end + end + end + + local changed = false + + if pp ~= nil then + for bindex,bfluid in pairs(pp) do + for aindex,afluid in pairs(buffers) do + if pumped >= pcapability then break end + if (afluid == bfluid or bfluid == "") then + local idef = destdef.node_io_room_for_liquid(pos, destnode, "", afluid, pcapability) + if idef > 0 then + local fluidcount = srcdef.node_io_get_liquid_stack(srcpos, srcnode, "", aindex):get_count() + local defc = math.min(fluidcount, idef) + local defi = srcdef.node_io_take_liquid(srcpos, srcnode, "", nil, afluid, defc) + if defi.millibuckets > 0 then + local lo = destdef.node_io_put_liquid(pos, destnode, "", nil, afluid, defi.millibuckets) + pumped = pumped + (defi.millibuckets - lo) + changed = true + end + end + end + end + end + end + + if changed then + minetest.get_node_timer(srcpos):start(1.0) + minetest.get_node_timer(pos):start(1.0) + end + end + end + + return refresh +end + +function fluid_lib.refresh_node(pos) + local t = minetest.get_node_timer(pos) + if t and not t:is_started() then + t:start(1.0) + end + + if node_io_present then + node_io.update_neighbors(pos) + end +end + +minetest.register_lbm({ + label = "Fluid Transfer Tick", + name = "fluid_transfer:fluid_transfer_tick", + nodenames = {"group:fluid_transport_source", "group:fluid_pump"}, + run_at_every_load = true, + action = fluid_lib.refresh_node, +}) diff --git a/fluid_transfer/register.lua b/fluid_transfer/register.lua new file mode 100644 index 0000000..362dbd8 --- /dev/null +++ b/fluid_transfer/register.lua @@ -0,0 +1,23 @@ + +fluid_lib.register_extractor_node("fluid_transfer:fluid_transfer_pump", { + description = "Fluid Transfer Pump\nPunch to start pumping", + tiles = {"fluid_transfer_pump.png"}, + drawtype = "mesh", + mesh = "fluid_transfer_pump.obj", + groups = {oddly_breakable_by_hand = 1, cracky = 1}, + paramtype = "light", + selection_box = { + type = "fixed", + fixed = { + {-0.4375, -0.4375, -0.5000, 0.4375, 0.4375, 0.000}, + {-0.1875, -0.1875, 0.000, 0.1875, 0.1875, 0.5000} + } + } +}) + +fluid_lib.register_transfer_node("fluid_transfer:fluid_duct", { + description = "Fluid Duct", + tiles = {"fluid_transfer_duct.png"}, + groups = {oddly_breakable_by_hand = 1, cracky = 1} +}) + diff --git a/fluid_transfer/textures/fluid_transfer_duct.png b/fluid_transfer/textures/fluid_transfer_duct.png new file mode 100644 index 0000000000000000000000000000000000000000..c067c92d23b86383052c868eeb09252c85f12ea5 GIT binary patch literal 5386 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 Gh<^Z%^i^B{ literal 0 HcmV?d00001