Rewrite fluid transfer to use Node IO
This commit is contained in:
parent
606f572317
commit
534fb41fb4
152
elepower_fapi/buffer.lua
Normal file
152
elepower_fapi/buffer.lua
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
-- Fluid buffer support functions.
|
||||||
|
|
||||||
|
local function node_data(pos)
|
||||||
|
local node = minetest.get_node(pos)
|
||||||
|
local nodedef = minetest.registered_nodes[node.name]
|
||||||
|
return node, nodedef
|
||||||
|
end
|
||||||
|
|
||||||
|
function elefluid.get_node_buffers(pos)
|
||||||
|
local node, nodedef = node_data(pos)
|
||||||
|
if not nodedef['fluid_buffers'] then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return nodedef['fluid_buffers']
|
||||||
|
end
|
||||||
|
|
||||||
|
function elefluid.get_buffer_data(pos, buffer)
|
||||||
|
local node, nodedef = node_data(pos)
|
||||||
|
local buffers = elefluid.get_node_buffers(pos)
|
||||||
|
|
||||||
|
if not buffers[buffer] then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local fluid = meta:get_string(buffer .. "_fluid")
|
||||||
|
local amount = meta:get_int(buffer .. "_fluid_storage")
|
||||||
|
local capacity = buffers[buffer].capacity
|
||||||
|
local accepts = buffers[buffer].accepts
|
||||||
|
local drainable = buffers[buffer].drainable
|
||||||
|
|
||||||
|
if drainable == nil then
|
||||||
|
drainable = true
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
fluid = fluid,
|
||||||
|
amount = amount,
|
||||||
|
accepts = accepts,
|
||||||
|
capacity = capacity,
|
||||||
|
drainable = drainable,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function elefluid.buffer_accepts_fluid(pos, buffer, fluid)
|
||||||
|
local bfdata = elefluid.get_buffer_data(pos, buffer)
|
||||||
|
if not bfdata then return false end
|
||||||
|
|
||||||
|
if bfdata.fluid ~= "" and bfdata.fluid ~= fluid then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if bfdata.accepts == true or bfdata.accepts == fluid then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(bfdata.accepts) ~= "table" then
|
||||||
|
bfdata.accepts = { bfdata.accepts }
|
||||||
|
end
|
||||||
|
|
||||||
|
for _,pf in pairs(bfdata.accepts) do
|
||||||
|
if pf == fluid then
|
||||||
|
return true
|
||||||
|
elseif pf:match("^group") and ele.helpers.get_item_group(fluid, pf:gsub("group:", "")) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function elefluid.can_insert_into_buffer(pos, buffer, fluid, count)
|
||||||
|
local bfdata = elefluid.get_buffer_data(pos, buffer)
|
||||||
|
if not bfdata then return 0 end
|
||||||
|
if not elefluid.buffer_accepts_fluid(pos, buffer, fluid) then return 0 end
|
||||||
|
|
||||||
|
local can_put = 0
|
||||||
|
if bfdata.amount + count > bfdata.capacity then
|
||||||
|
can_put = bfdata.capacity - bfdata.amount
|
||||||
|
else
|
||||||
|
can_put = count
|
||||||
|
end
|
||||||
|
|
||||||
|
return can_put
|
||||||
|
end
|
||||||
|
|
||||||
|
function elefluid.insert_into_buffer(pos, buffer, fluid, count)
|
||||||
|
local bfdata = elefluid.get_buffer_data(pos, buffer)
|
||||||
|
if not bfdata then return nil end
|
||||||
|
if bfdata.fluid ~= fluid and bfdata.fluid ~= "" then return nil end
|
||||||
|
|
||||||
|
local can_put = elefluid.can_insert_into_buffer(pos, buffer, fluid, count)
|
||||||
|
|
||||||
|
if can_put == 0 then return count end
|
||||||
|
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
meta:set_int(buffer .. "_fluid_storage", bfdata.amount + can_put)
|
||||||
|
meta:set_string(buffer .. "_fluid", fluid)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function elefluid.can_take_from_buffer(pos, buffer, count)
|
||||||
|
local bfdata = elefluid.get_buffer_data(pos, buffer)
|
||||||
|
if not bfdata or not bfdata.drainable then return 0 end
|
||||||
|
|
||||||
|
local amount = bfdata.amount
|
||||||
|
local take_count = 0
|
||||||
|
|
||||||
|
if amount < count then
|
||||||
|
take_count = amount
|
||||||
|
else
|
||||||
|
take_count = count
|
||||||
|
end
|
||||||
|
|
||||||
|
return take_count
|
||||||
|
end
|
||||||
|
|
||||||
|
function elefluid.take_from_buffer(pos, buffer, count)
|
||||||
|
local bfdata = elefluid.get_buffer_data(pos, buffer)
|
||||||
|
if not bfdata then return nil end
|
||||||
|
|
||||||
|
local fluid = bfdata.fluid
|
||||||
|
local amount = bfdata.amount
|
||||||
|
|
||||||
|
local take_count = elefluid.can_take_from_buffer(pos, buffer, count)
|
||||||
|
|
||||||
|
local new_storage = amount - take_count
|
||||||
|
if new_storage == 0 then
|
||||||
|
fluid = ""
|
||||||
|
end
|
||||||
|
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
meta:set_int(buffer .. "_fluid_storage", new_storage)
|
||||||
|
meta:set_string(buffer .. "_fluid", fluid)
|
||||||
|
|
||||||
|
return bfdata.fluid, take_count
|
||||||
|
end
|
||||||
|
|
||||||
|
function elefluid.buffer_to_string(buffer)
|
||||||
|
if not buffer then return "" end
|
||||||
|
local amount = elefluid.comma_value(buffer.amount)
|
||||||
|
local capacity = elefluid.comma_value(buffer.capacity)
|
||||||
|
local description = "Empty"
|
||||||
|
|
||||||
|
if buffer.fluid ~= "" then
|
||||||
|
description = elefluid.cleanse_node_description(buffer.fluid)
|
||||||
|
end
|
||||||
|
|
||||||
|
return ("%s (%s / %s %s)"):format(description, amount, capacity, elefluid.unit)
|
||||||
|
end
|
@ -1,2 +1,3 @@
|
|||||||
elepower_papi
|
elepower_papi
|
||||||
fluid_lib
|
fluid_lib
|
||||||
|
node_io?
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
name = elepower_fapi
|
name = elepower_fapi
|
||||||
description = Elepower Fluid Transfer API
|
description = Elepower Fluid Transfer API
|
||||||
depends = elepower_papi,fluid_lib
|
depends = elepower_papi,fluid_lib
|
||||||
|
optional_depends = node_io
|
||||||
|
@ -64,9 +64,10 @@ local function fluid_targets(p_pos, pos)
|
|||||||
local all_nodes = {}
|
local all_nodes = {}
|
||||||
|
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
|
local ndef = minetest.registered_nodes[node.name]
|
||||||
if node and ele.helpers.get_item_group(node.name, "elefluid_transport") then
|
if node and ele.helpers.get_item_group(node.name, "elefluid_transport") then
|
||||||
add_duct_node(all_nodes, pos, pnodeid, queue)
|
add_duct_node(all_nodes, pos, pnodeid, queue)
|
||||||
elseif node and ele.helpers.get_item_group(node.name, "fluid_container") then
|
elseif node and ndef['node_io_put_liquid'] and ndef['node_io_room_for_liquid'] then
|
||||||
queue = {p_pos}
|
queue = {p_pos}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -98,8 +99,9 @@ function elefluid.transfer_timer_tick(pos, elapsed)
|
|||||||
-- Only allow the node directly behind to be a start of a network
|
-- 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 tpos = vector.add(minetest.facedir_to_dir(node.param2), pos)
|
||||||
local tname = minetest.get_node(tpos).name
|
local tname = minetest.get_node(tpos).name
|
||||||
|
local ndef = minetest.registered_nodes[tname]
|
||||||
if not ele.helpers.get_item_group(tname, "elefluid_transport") and
|
if not ele.helpers.get_item_group(tname, "elefluid_transport") and
|
||||||
not ele.helpers.get_item_group(tname, "fluid_container") then
|
not ndef['node_io_put_liquid'] and ndef['node_io_room_for_liquid'] then
|
||||||
minetest.forceload_free_block(pos)
|
minetest.forceload_free_block(pos)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -121,15 +123,24 @@ function elefluid.transfer_timer_tick(pos, elapsed)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local srcdef = minetest.registered_nodes[srcnode.name]
|
||||||
|
|
||||||
-- Make sure source node is a registered fluid container
|
-- Make sure source node is a registered fluid container
|
||||||
if not ele.helpers.get_item_group(srcnode.name, "fluid_container") then
|
if not srcdef['node_io_take_liquid'] or not srcdef['node_io_can_take_liquid'] then
|
||||||
return true
|
return false
|
||||||
end
|
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 srcmeta = minetest.get_meta(srcpos)
|
||||||
local srcdef = minetest.registered_nodes[srcnode.name]
|
local srcdef = minetest.registered_nodes[srcnode.name]
|
||||||
local buffers = fluid_lib.get_node_buffers(srcpos)
|
local fl_size = srcdef.node_io_get_liquid_size(srcpos, srcnode, "")
|
||||||
if not buffers then return true end
|
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
|
-- Limit the amount of fluid pumped per cycle
|
||||||
local pcapability = ele.helpers.get_node_property(meta, pos, "fluid_pump_capacity")
|
local pcapability = ele.helpers.get_node_property(meta, pos, "fluid_pump_capacity")
|
||||||
@ -139,29 +150,37 @@ function elefluid.transfer_timer_tick(pos, elapsed)
|
|||||||
for _,pos in pairs(targets) do
|
for _,pos in pairs(targets) do
|
||||||
if not vector.equals(pos, srcpos) then
|
if not vector.equals(pos, srcpos) then
|
||||||
if pumped >= pcapability then break end
|
if pumped >= pcapability then break end
|
||||||
local pp = fluid_lib.get_node_buffers(pos)
|
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
|
local changed = false
|
||||||
|
|
||||||
if pp ~= nil then
|
if pp ~= nil then
|
||||||
for name in pairs(pp) do
|
for bindex,bfluid in pairs(pp) do
|
||||||
for bname in pairs(buffers) do
|
for aindex,afluid in pairs(buffers) do
|
||||||
if pumped >= pcapability then break end
|
if pumped >= pcapability then break end
|
||||||
local buffer_data = fluid_lib.get_buffer_data(srcpos, bname)
|
if (afluid == bfluid or bfluid == "") then
|
||||||
local target_data = fluid_lib.get_buffer_data(pos, name)
|
local defi = srcdef.node_io_take_liquid(srcpos, srcnode, "", nil, afluid, pcapability)
|
||||||
|
if defi.millibuckets > 0 then
|
||||||
if (target_data.fluid == buffer_data.fluid or target_data.fluid == "") and
|
local idef = destdef.node_io_room_for_liquid(pos, destnode, "", afluid, defi.millibuckets)
|
||||||
buffer_data.fluid ~= "" and buffer_data.amount > 0 and
|
if idef > 0 then
|
||||||
(buffer_data.drainable == nil or buffer_data.drainable == true) and
|
local lo = destdef.node_io_put_liquid(pos, destnode, "", nil, afluid, idef)
|
||||||
fluid_lib.buffer_accepts_fluid(pos, name, buffer_data.fluid) then
|
idef = idef - lo
|
||||||
|
|
||||||
if fluid_lib.can_insert_into_buffer(pos, name, buffer_data.fluid, pcapability) > 0 then
|
|
||||||
local res_f, count = fluid_lib.take_from_buffer(srcpos, bname, pcapability)
|
|
||||||
if count > 0 then
|
|
||||||
fluid_lib.insert_into_buffer(pos, name, res_f, count)
|
|
||||||
pumped = pumped + count
|
|
||||||
changed = true
|
|
||||||
end
|
end
|
||||||
|
pumped = pumped + idef
|
||||||
|
changed = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
default
|
default
|
||||||
pipeworks?
|
pipeworks?
|
||||||
tubelib?
|
tubelib?
|
||||||
|
mesecons?
|
||||||
|
node_io?
|
||||||
|
@ -311,6 +311,46 @@ function ele.register_base_device(nodename, nodedef)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Node IO Support
|
||||||
|
if minetest.get_modpath("node_io") and (nodedef.groups["tubedevice"] or nodedef.groups["tube"]) then
|
||||||
|
nodedef.node_io_can_put_item = function(pos, node, side) return true end
|
||||||
|
nodedef.node_io_room_for_item = function(pos, node, side, itemstack, count)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
local istack_real = ItemStack(itemstack)
|
||||||
|
istack_real:set_count(count)
|
||||||
|
return inv:room_for_item("src", istack_real)
|
||||||
|
end
|
||||||
|
nodedef.node_io_put_item = function(pos, node, side, putter, itemstack)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
return inv:add_item("src", itemstack)
|
||||||
|
end
|
||||||
|
nodedef.node_io_can_take_item = function(pos, node, side) return true end
|
||||||
|
nodedef.node_io_get_item_size = function(pos, node, side)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
return inv:get_size("dst")
|
||||||
|
end
|
||||||
|
nodedef.node_io_get_item_name = function(pos, node, side, index)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
return inv:get_stack("dst", index):get_name()
|
||||||
|
end
|
||||||
|
nodedef.node_io_get_item_stack = function(pos, node, side, index)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
return inv:get_stack("dst", index)
|
||||||
|
end
|
||||||
|
nodedef.node_io_take_item = function(pos, node, side, taker, want_item, want_count)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
local stack = ItemStack(want_item)
|
||||||
|
stack:set_count(want_count)
|
||||||
|
return inv:take_item("dst", stack)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Mesecons support
|
-- Mesecons support
|
||||||
if mc then
|
if mc then
|
||||||
nodedef["mesecons"] = mesecons_def
|
nodedef["mesecons"] = mesecons_def
|
||||||
@ -376,6 +416,14 @@ function ele.register_base_device(nodename, nodedef)
|
|||||||
|
|
||||||
tubelib.register_node(nodename, extras, tubelib_tube)
|
tubelib.register_node(nodename, extras, tubelib_tube)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- nodeio fluids
|
||||||
|
if nodedef.groups and nodedef.groups['fluid_container'] then
|
||||||
|
fluid_lib.register_node(nodename)
|
||||||
|
if active_name then
|
||||||
|
fluid_lib.register_node(active_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function ele.register_machine(nodename, nodedef)
|
function ele.register_machine(nodename, nodedef)
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
name = elepower_papi
|
name = elepower_papi
|
||||||
description = Elepower Power Network API
|
description = Elepower Power Network API
|
||||||
optional_depends = default,pipeworks,tubelib,mesecons
|
depends = default
|
||||||
|
optional_depends = pipeworks,tubelib,mesecons,node_io
|
||||||
|
Loading…
Reference in New Issue
Block a user