From 3ac8b487599177533907901b643654b1b61067f3 Mon Sep 17 00:00:00 2001 From: Evert Prants Date: Mon, 18 Jun 2018 20:33:54 +0300 Subject: [PATCH] Fluid transfer! Works with melterns \(soon\)! --- README.md | 2 +- elepower_fapi/buffer.lua | 156 ++++++++++++++++++++++++++++++++ elepower_fapi/transfer.lua | 83 +++++------------ elepower_fapi/transfer_node.lua | 1 + 4 files changed, 183 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 8e4ac9d..9478bdc 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ A new *powerful* modpack for [Minetest](http://minetest.net)! ### Universal Electric Power API How is this any different from technic I hear you asking? Well, first of all, I have eliminated the concept of "tiers" in the **technic** sense, as all types of machines will now be accepting any conduit. Machines can be upgraded for speed and efficiency. -### (Planned) Universal Fluid Transfer API +### Universal Fluid Transfer API Exactly what it sounds like. Pipeworks failed to do this. ### (Planned) Universal Item Transfer API diff --git a/elepower_fapi/buffer.lua b/elepower_fapi/buffer.lua index e69de29..e9d0423 100644 --- a/elepower_fapi/buffer.lua +++ b/elepower_fapi/buffer.lua @@ -0,0 +1,156 @@ +-- This API is compatible with fluidity. +local fluidmod = minetest.get_modpath("fluidity") ~= nil + +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['ele_fluid_container'] and not ele.helpers.get_item_group(node.name, "fluidity_tank") then + return nil + end + + if fluidmod and ele.helpers.get_item_group(node.name, "fluidity_tank") then + return {fluidity = {}} + end + + return nodedef['ele_fluid_container'] +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_string(buffer .. "_fluid_storage") + local capacity = buffers[buffer].capacity + local accepts = buffers[buffer].accepts + + -- Fluidity tanks compatibility + if buffer == "fluidity" then + local ffluid, fluidcount, fcapacity, fbasetank, fmod = fluidity.tanks.get_tank_at(pos) + + fluid = ffluid + amount = fluidcount + accepts = true + capacity = fcapacity + end + + return { + fluid = fluid, + amount = amount, + accepts = accepts, + capacity = capacity, + } +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.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) 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 nil end + if bfdata.fluid ~= fluid and bfdata.fluid ~= "" then return nil 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 + + if buffer == "fluidity" then + return fluidity.tanks.fill_tank_at(pos, fluid, count, true) + 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 then return nil 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) + + if buffer == "fluidity" then + local fname, cf = fluidity.tanks.take_from_tank_at(pos, count, true) + if cf then + count = count - cf + end + return fname, count + end + + 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 fluid, take_count +end diff --git a/elepower_fapi/transfer.lua b/elepower_fapi/transfer.lua index 98fd084..84e7bac 100644 --- a/elepower_fapi/transfer.lua +++ b/elepower_fapi/transfer.lua @@ -3,8 +3,6 @@ -- Network cache elefluid.graphcache = {nodes = {}} -local fluidmod = minetest.get_modpath("fluidity") ~= nil - --------------------- -- Graph Functions -- --------------------- @@ -41,7 +39,8 @@ local function check_node(targets, all_nodes, pos, p_pos, pnodeid, queue) return end - if not ele.helpers.get_item_group(node.name, "ele_fluid_container") then + if not ele.helpers.get_item_group(node.name, "ele_fluid_container") and + not ele.helpers.get_item_group(node.name, "fluidity_tank") then return end @@ -87,7 +86,8 @@ local function fluid_targets(p_pos, positions) local node = minetest.get_node(pos) if node and ele.helpers.get_item_group(node.name, "elefluid_transport") then add_duct_node(all_nodes, pos, pnodeid, queue) - elseif node and ele.helpers.get_item_group(node.name, "ele_fluid_container") then + elseif node and (ele.helpers.get_item_group(node.name, "ele_fluid_container") or + ele.helpers.get_item_group(node.name, "fluidity_tank")) then queue = {p_pos} end @@ -178,13 +178,14 @@ minetest.register_abm({ end -- Make sure source node is a registered fluid container - if not ele.helpers.get_item_group(srcnode.name, "ele_fluid_container") then + if not ele.helpers.get_item_group(srcnode.name, "ele_fluid_container") and + not ele.helpers.get_item_group(srcnode.name, "fluidity_tank") then return end local srcmeta = minetest.get_meta(srcpos) local srcdef = minetest.registered_nodes[srcnode.name] - local buffers = srcdef['ele_fluid_buffers'] + local buffers = elefluid.get_node_buffers(srcpos) if not buffers then return nil end local pcapability = ele.helpers.get_node_property(meta, pos, "fluid_pump_capacity") @@ -192,64 +193,28 @@ minetest.register_abm({ -- Transfer some fluid here for _,pos in pairs(targets) do if not vector.equals(pos, srcpos) then - local nm = minetest.get_meta(pos) - local nd = minetest.get_node(pos) - local nc = minetest.registered_nodes[nd.name] - local pp = nc['ele_fluid_buffers'] + local pp = elefluid.get_node_buffers(pos) local changed = false if pp ~= nil then - for name, data in pairs(pp) do - for bname, buf in pairs(buffers) do - local target_fluid = nm:get_string(name.."_fluid") - local buffer_fluid = srcmeta:get_string(bname.."_fluid") + for name in pairs(pp) do + for bname in pairs(buffers) do + local buffer_data = elefluid.get_buffer_data(srcpos, bname) + local target_data = elefluid.get_buffer_data(pos, name) - local target_count = nm:get_int(name.."_fluid_storage") - local buffer_count = srcmeta:get_int(bname.."_fluid_storage") - - local apply = false - - if (target_fluid == buffer_fluid or target_fluid == "") and buffer_fluid ~= "" and buffer_count > 0 and - (data.accepts == true or data.accepts == buffer_fluid) then - local can_transfer_amnt = 0 - if buffer_count > pcapability then - can_transfer_amnt = pcapability - else - can_transfer_amnt = buffer_count - end - - if can_transfer_amnt > 0 then - local can_accept_amnt = 0 - if target_count + can_transfer_amnt > data.capacity then - can_accept_amnt = data.capacity - target_count - else - can_accept_amnt = can_transfer_amnt - end - - if can_accept_amnt > 0 then - target_count = target_count + can_accept_amnt - target_fluid = buffer_fluid - buffer_count = buffer_count - can_accept_amnt - - if buffer_count == 0 then - buffer_fluid = "" - end - - apply = true + if (target_data.fluid == buffer_data.fluid or target_data.fluid == "") and + buffer_data.fluid ~= "" and buffer_data.amount > 0 and + elefluid.buffer_accepts_fluid(pos, name, buffer_data.fluid) then + + if elefluid.can_insert_into_buffer(pos, name, buffer_data.fluid, pcapability) > 0 then + local res_f, count = elefluid.take_from_buffer(srcpos, bname, pcapability) + if count > 0 then + elefluid.insert_into_buffer(pos, name, res_f, count) + changed = true end end end - - if apply then - nm:set_string(name.."_fluid", target_fluid) - srcmeta:set_string(bname.."_fluid", buffer_fluid) - - nm:set_int(name.."_fluid_storage", target_count) - srcmeta:set_string(bname.."_fluid_storage", buffer_count) - - changed = true - end end end end @@ -277,7 +242,8 @@ local function check_connections(pos) local name = minetest.get_node(connected_pos).name if ele.helpers.get_item_group(name, "elefluid_transport") or ele.helpers.get_item_group(name, "ele_fluid_container") or - ele.helpers.get_item_group(name, "elefluid_transport_source") then + ele.helpers.get_item_group(name, "elefluid_transport_source") or + ele.helpers.get_item_group(name, "fluidity_tank") then table.insert(connections, connected_pos) end end @@ -318,7 +284,8 @@ function elefluid.clear_networks(pos) table.insert(network.all_nodes, pos) end - if ele.helpers.get_item_group(name, "ele_fluid_container") then + if ele.helpers.get_item_group(name, "ele_fluid_container") or + ele.helpers.get_item_group(name, "fluidity_tank") then meta:set_string("ele_network", network_id) table.insert(network.targets, pos) end diff --git a/elepower_fapi/transfer_node.lua b/elepower_fapi/transfer_node.lua index 3ac0625..d2befa2 100644 --- a/elepower_fapi/transfer_node.lua +++ b/elepower_fapi/transfer_node.lua @@ -82,6 +82,7 @@ function elefluid.register_transfer_duct(nodename, nodedef) "group:elefluid_transport", "group:elefluid_transport_source", "group:ele_fluid_container", + "group:fluidity_tank" }, }