mods that hopefully work for a TechAge-based pack
This commit is contained in:
@@ -0,0 +1,296 @@
|
||||
--[[
|
||||
|
||||
Networks
|
||||
========
|
||||
|
||||
Copyright (C) 2021 Joachim Stolberg
|
||||
|
||||
AGPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Liquid API for liquid pumping and storing nodes
|
||||
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local S2P = minetest.string_to_pos
|
||||
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
|
||||
local M = minetest.get_meta
|
||||
local N = tubelib2.get_node_lvm
|
||||
local LQD = function(pos) return (minetest.registered_nodes[N(pos).name] or {}).liquid end
|
||||
|
||||
networks.liquid = {}
|
||||
networks.registered_networks.liquid = {}
|
||||
|
||||
-- return list of nodes {pos = ..., indir = ...} of given node_type
|
||||
local function get_network_table(pos, tlib2, outdir, node_type)
|
||||
local netw = networks.get_network_table(pos, tlib2, outdir)
|
||||
if netw then
|
||||
return netw[node_type] or {}
|
||||
end
|
||||
return {}
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- For all types of nodes
|
||||
-------------------------------------------------------------------------------
|
||||
-- names: list of node names
|
||||
-- tlib2: tubelib2 instance
|
||||
-- node_type: one of "pump", "tank", "junc"
|
||||
-- valid_sides: something like {"L", "R"} or nil
|
||||
-- liquid_callbacks = {
|
||||
-- capa = CAPACITY,
|
||||
-- peek = function(pos, indir), -- returns: liquid name
|
||||
-- put = function(pos, indir, name, amount), -- returns: liquid leftover or 0
|
||||
-- take = function(pos, indir, name, amount), -- returns: taken, name
|
||||
-- untake = function(pos, indir, name, amount), -- returns: leftover
|
||||
-- }
|
||||
function networks.liquid.register_nodes(names, tlib2, node_type, valid_sides, liquid_callbacks)
|
||||
if node_type == "pump" then
|
||||
assert(not valid_sides or type(valid_sides) == "table")
|
||||
valid_sides = valid_sides or {"B", "R", "F", "L", "D", "U"}
|
||||
elseif node_type == "tank" or node_type == "junc" then
|
||||
assert(not valid_sides or type(valid_sides) == "table")
|
||||
valid_sides = valid_sides or {"B", "R", "F", "L", "D", "U"}
|
||||
elseif node_type and type(node_type) == "string" then
|
||||
valid_sides = valid_sides or {"B", "R", "F", "L", "D", "U"}
|
||||
else
|
||||
error("parameter error")
|
||||
end
|
||||
|
||||
if node_type == "tank" then
|
||||
assert(type(liquid_callbacks) == "table")
|
||||
end
|
||||
|
||||
tlib2:add_secondary_node_names(names)
|
||||
networks.registered_networks.liquid[tlib2.tube_type] = tlib2
|
||||
|
||||
for _, name in ipairs(names) do
|
||||
local ndef = minetest.registered_nodes[name]
|
||||
local tbl = ndef.networks or {}
|
||||
tbl[tlib2.tube_type] = {ntype = node_type}
|
||||
minetest.override_item(name, {networks = tbl})
|
||||
minetest.override_item(name, {liquid = liquid_callbacks})
|
||||
tlib2:set_valid_sides(name, valid_sides)
|
||||
end
|
||||
end
|
||||
|
||||
-- To be called for each liquid network change via
|
||||
-- tubelib2_on_update2 or register_on_tube_update2
|
||||
function networks.liquid.update_network(pos, outdir, tlib2, node)
|
||||
local ndef = networks.net_def(pos, tlib2.tube_type)
|
||||
if ndef.ntype == "junc" then
|
||||
outdir = 0
|
||||
end
|
||||
networks.update_network(pos, outdir, tlib2, node)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Client/pump functions
|
||||
-------------------------------------------------------------------------------
|
||||
-- Determine and return liquid 'name' from the
|
||||
-- remote inventory.
|
||||
function networks.liquid.peek(pos, tlib2, outdir)
|
||||
assert(outdir)
|
||||
for _,item in ipairs(get_network_table(pos, tlib2, outdir, "tank")) do
|
||||
local liq = LQD(item.pos)
|
||||
if liq and liq.peek then
|
||||
return liq.peek(item.pos, item.indir)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Add given amount of liquid to the remote inventory.
|
||||
-- return leftover amount
|
||||
function networks.liquid.put(pos, tlib2, outdir, name, amount, show_debug_cube)
|
||||
assert(outdir)
|
||||
assert(name)
|
||||
assert(amount and amount > 0)
|
||||
for _,item in ipairs(get_network_table(pos, tlib2, outdir, "tank")) do
|
||||
local liq = LQD(item.pos)
|
||||
if liq and liq.put and liq.peek then
|
||||
-- wrong items?
|
||||
local peek = liq.peek(item.pos, item.indir)
|
||||
if peek and peek ~= name then return amount or 0 end
|
||||
if show_debug_cube then
|
||||
networks.set_marker(item.pos, "put", 1.1, 1)
|
||||
end
|
||||
amount = liq.put(item.pos, item.indir, name, amount)
|
||||
if not amount or amount == 0 then break end
|
||||
end
|
||||
end
|
||||
return amount or 0
|
||||
end
|
||||
|
||||
-- Take given amount of liquid from the remote inventory.
|
||||
-- return taken amount and item name
|
||||
function networks.liquid.take(pos, tlib2, outdir, name, amount, show_debug_cube)
|
||||
assert(outdir)
|
||||
assert(amount and amount > 0)
|
||||
local taken = 0
|
||||
for _,item in ipairs(get_network_table(pos, tlib2, outdir, "tank")) do
|
||||
local liq = LQD(item.pos)
|
||||
if liq and liq.take then
|
||||
if show_debug_cube then
|
||||
networks.set_marker(item.pos, "take", 1.1, 1)
|
||||
end
|
||||
taken, name = liq.take(item.pos, item.indir, name, amount)
|
||||
if taken and name and taken > 0 then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
return taken, name
|
||||
end
|
||||
|
||||
function networks.liquid.untake(pos, tlib2, outdir, name, amount)
|
||||
assert(outdir)
|
||||
assert(name)
|
||||
assert(amount)
|
||||
for _,item in ipairs(get_network_table(pos, tlib2, outdir, "tank")) do
|
||||
local liq = LQD(item.pos)
|
||||
if liq and liq.untake then
|
||||
amount = liq.untake(item.pos, item.indir, name, amount)
|
||||
if not amount or amount == 0 then break end
|
||||
end
|
||||
end
|
||||
return amount or 0
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Server/tank local functions
|
||||
-------------------------------------------------------------------------------
|
||||
function networks.liquid.is_empty(nvm)
|
||||
return not nvm.liquid or (nvm.liquid.amount or 0) <= 0
|
||||
end
|
||||
|
||||
function networks.liquid.get_amount(nvm)
|
||||
if nvm.liquid and nvm.liquid.amount then
|
||||
return nvm.liquid.amount
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function networks.liquid.get_item(nvm)
|
||||
local itemname = "<empty>"
|
||||
if nvm.liquid and nvm.liquid.amount and nvm.liquid.amount > 0 and nvm.liquid.name then
|
||||
itemname = nvm.liquid.name.." "..nvm.liquid.amount
|
||||
end
|
||||
return itemname
|
||||
end
|
||||
|
||||
function networks.liquid.srv_peek(nvm)
|
||||
nvm.liquid = nvm.liquid or {}
|
||||
nvm.liquid.amount = math.floor((nvm.liquid.amount or 0) + 0.5)
|
||||
return nvm.liquid.amount > 0 and nvm.liquid.name
|
||||
end
|
||||
|
||||
function networks.liquid.srv_put(nvm, name, amount, capa)
|
||||
assert(name)
|
||||
assert(capa and capa > 0)
|
||||
amount = math.floor((amount or 0) + 0.5)
|
||||
nvm.liquid = nvm.liquid or {}
|
||||
nvm.liquid.amount = nvm.liquid.amount or 0
|
||||
|
||||
if nvm.liquid.amount == 0 or not nvm.liquid.name then
|
||||
nvm.liquid.name = name
|
||||
nvm.liquid.amount = amount
|
||||
return 0
|
||||
elseif nvm.liquid.name == name then
|
||||
nvm.liquid.amount = nvm.liquid.amount or 0
|
||||
if nvm.liquid.amount + amount <= capa then
|
||||
nvm.liquid.amount = nvm.liquid.amount + amount
|
||||
return 0
|
||||
else
|
||||
local rest = nvm.liquid.amount + amount - capa
|
||||
nvm.liquid.amount = capa
|
||||
return rest
|
||||
end
|
||||
end
|
||||
return amount
|
||||
end
|
||||
|
||||
function networks.liquid.srv_take(nvm, name, amount)
|
||||
amount = math.floor((amount or 0) + 0.5)
|
||||
nvm.liquid = nvm.liquid or {}
|
||||
|
||||
if not name or nvm.liquid.name == name then
|
||||
name = nvm.liquid.name
|
||||
nvm.liquid.amount = nvm.liquid.amount or 0
|
||||
if nvm.liquid.amount > amount then
|
||||
nvm.liquid.amount = nvm.liquid.amount - amount
|
||||
return amount, name
|
||||
else
|
||||
local rest = nvm.liquid.amount
|
||||
local name = nvm.liquid.name
|
||||
nvm.liquid.amount = 0
|
||||
nvm.liquid.name = nil
|
||||
return rest, name
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Valve
|
||||
-------------------------------------------------------------------------------
|
||||
function networks.liquid.turn_valve_on(pos, tlib2, name_off, name_on)
|
||||
local node = N(pos)
|
||||
local meta = M(pos)
|
||||
if node.name == name_off then
|
||||
node.name = name_on
|
||||
minetest.swap_node(pos, node)
|
||||
tlib2:after_place_tube(pos)
|
||||
meta:set_int("networks_param2", node.param2)
|
||||
return true
|
||||
elseif meta:contains("networks_param2_copy") then
|
||||
meta:set_int("networks_param2", meta:get_int("networks_param2_copy"))
|
||||
tlib2:after_place_tube(pos)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function networks.liquid.turn_valve_off(pos, tlib2, name_off, name_on)
|
||||
local node = N(pos)
|
||||
local meta = M(pos)
|
||||
if node.name == name_on then
|
||||
node.name = name_off
|
||||
minetest.swap_node(pos, node)
|
||||
meta:set_int("networks_param2", 0)
|
||||
tlib2:after_dig_tube(pos, node)
|
||||
return true
|
||||
elseif meta:contains("networks_param2") then
|
||||
meta:set_int("networks_param2_copy", meta:get_int("networks_param2"))
|
||||
meta:set_int("networks_param2", 0)
|
||||
tlib2:after_dig_tube(pos, node)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Info/Tools
|
||||
-------------------------------------------------------------------------------
|
||||
-- Return list of liquids of connected tanks
|
||||
-- Node at pos must be a pump
|
||||
function networks.liquid.get_liquids(pos, tlib2)
|
||||
local tbl = {}
|
||||
for _, dir in ipairs(networks.get_node_connection_dirs(pos, tlib2.tube_type)) do
|
||||
for _,item in ipairs(get_network_table(pos, tlib2, dir, "tank")) do
|
||||
local liq = LQD(item.pos)
|
||||
if liq and liq.peek then
|
||||
local liq_name = liq.peek(item.pos, item.indir)
|
||||
if liq_name then
|
||||
local def = minetest.registered_items[liq_name] or minetest.registered_craftitems[liq_name]
|
||||
if def then
|
||||
tbl[def.description] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local out = {}
|
||||
for k,v in pairs(tbl) do
|
||||
out[#out + 1] = k
|
||||
end
|
||||
return out
|
||||
end
|
||||
Reference in New Issue
Block a user