bug fixes and improvements
parent
3753b4aa92
commit
5a52d165c0
15
README.md
15
README.md
|
@ -15,7 +15,7 @@ Power networks consists of following node types:
|
||||||
- Consumers, nodes consuming power
|
- Consumers, nodes consuming power
|
||||||
- Storage nodes, nodes storing power
|
- Storage nodes, nodes storing power
|
||||||
- Cables, to build power connections
|
- Cables, to build power connections
|
||||||
- Junctions, to build power networks
|
- Junctions, to connect point to point connection to networks
|
||||||
- Switches, to turn on/off network segments
|
- Switches, to turn on/off network segments
|
||||||
|
|
||||||
All storage nodes in a network form a storage system. Storage systems are
|
All storage nodes in a network form a storage system. Storage systems are
|
||||||
|
@ -40,15 +40,15 @@ tbd.
|
||||||
|
|
||||||
### Test Nodes
|
### Test Nodes
|
||||||
|
|
||||||
The file `test.lua` includes test nodes of each kind. It can be used to
|
The file `./test/test_power.lua` includes test nodes of each kind of power nodes.
|
||||||
play with the features and to study the use of `networks`.
|
It can be used to play with the features and to study the use of `networks`.
|
||||||
|
|
||||||
- [G] a generator, which provides 20 units of power every 2 s
|
- [G] a generator, which provides 20 units of power every 2 s
|
||||||
- [C] a consumer, which need 5 units of power every 2 s
|
- [C] a consumer, which need 5 units of power every 2 s
|
||||||
|
|
||||||
Both nodes can be turned on/off by right-clicking.
|
|
||||||
|
|
||||||
- [S] a storage with 500 units capacity
|
- [S] a storage with 500 units capacity
|
||||||
|
|
||||||
|
All three nodes can be turned on/off by right-clicking.
|
||||||
|
|
||||||
- cable node for power transportation
|
- cable node for power transportation
|
||||||
- junction node for power distribution
|
- junction node for power distribution
|
||||||
- a power switch to turn on/off consumers
|
- a power switch to turn on/off consumers
|
||||||
|
@ -80,3 +80,6 @@ Required: tubelib2
|
||||||
**2021-05-25 V0.03**
|
**2021-05-25 V0.03**
|
||||||
- Add function `networks.get_power_data`
|
- Add function `networks.get_power_data`
|
||||||
- bug fixes and improvements
|
- bug fixes and improvements
|
||||||
|
|
||||||
|
**2021-05-29 V0.04**
|
||||||
|
- bug fixes and improvements
|
||||||
|
|
|
@ -36,7 +36,6 @@ function networks.hidden_node(pos, netw_type)
|
||||||
if ndef and ndef.networks then
|
if ndef and ndef.networks then
|
||||||
return ndef.networks[netw_type] or {}
|
return ndef.networks[netw_type] or {}
|
||||||
end
|
end
|
||||||
return {}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function networks.hidden_name(pos)
|
function networks.hidden_name(pos)
|
||||||
|
@ -93,7 +92,10 @@ function networks.use_metadata(tlib2)
|
||||||
-- Needed for hidden nodes, cause they don't have a 'tubelib2_on_update2' callback
|
-- Needed for hidden nodes, cause they don't have a 'tubelib2_on_update2' callback
|
||||||
-- and is used for all kind of nodes without own 'tubelib2_on_update2'
|
-- and is used for all kind of nodes without own 'tubelib2_on_update2'
|
||||||
tlib2:register_on_tube_update2(function(pos, outdir, tlib2, node)
|
tlib2:register_on_tube_update2(function(pos, outdir, tlib2, node)
|
||||||
networks.update_network(pos, outdir, tlib2)
|
if networks.is_junction(pos, node.name, tlib2) then
|
||||||
|
outdir = 0
|
||||||
|
end
|
||||||
|
networks.on_update_power_network(pos, outdir, tlib2)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
9
init.lua
9
init.lua
|
@ -13,19 +13,20 @@
|
||||||
networks = {}
|
networks = {}
|
||||||
|
|
||||||
-- Version for compatibility checks, see readme.md/history
|
-- Version for compatibility checks, see readme.md/history
|
||||||
networks.version = 0.03
|
networks.version = 0.04
|
||||||
|
|
||||||
if minetest.global_exists("tubelib2") and tubelib2.version < 2.1 then
|
if not minetest.global_exists("tubelib2") or tubelib2.version < 2.1 then
|
||||||
minetest.log("error", "[networks] Networks requires tubelib2 version 2.1 or newer!")
|
minetest.log("error", "[networks] Networks requires tubelib2 version 2.1 or newer!")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local MP = minetest.get_modpath("networks")
|
local MP = minetest.get_modpath("networks")
|
||||||
|
|
||||||
dofile(MP .. "/hidden.lua")
|
dofile(MP .. "/hidden.lua")
|
||||||
dofile(MP .. "/networks.lua")
|
dofile(MP .. "/networks.lua")
|
||||||
dofile(MP .. "/junction.lua")
|
dofile(MP .. "/junction.lua")
|
||||||
dofile(MP .. "/power.lua")
|
dofile(MP .. "/power.lua")
|
||||||
--dofile(MP .. "/liquids.lua")
|
--dofile(MP .. "/liquid.lua")
|
||||||
|
|
||||||
-- Only for testing/demo purposes
|
-- Only for testing/demo purposes
|
||||||
dofile(MP .. "/test.lua")
|
dofile(MP .. "/test/test_power.lua")
|
110
networks.lua
110
networks.lua
|
@ -66,18 +66,17 @@ local function debug()
|
||||||
end
|
end
|
||||||
tbl[#tbl+1] = "num_nodes = " .. network.num_nodes
|
tbl[#tbl+1] = "num_nodes = " .. network.num_nodes
|
||||||
print("Network " .. netw_num(netID) .. ": " .. table.concat(tbl, ", "))
|
print("Network " .. netw_num(netID) .. ": " .. table.concat(tbl, ", "))
|
||||||
|
end
|
||||||
|
|
||||||
for hash, item in pairs(NetIDs) do
|
for hash, item in pairs(NetIDs) do
|
||||||
tbl = {}
|
local tbl = {}
|
||||||
for dir = 0,6 do
|
for dir = 0,6 do
|
||||||
netID = item[dir]
|
local netID = item[dir]
|
||||||
if netID then
|
if netID then
|
||||||
tbl[#tbl+1] = "dir " .. dir .. " = netw " .. netw_num(netID)
|
tbl[#tbl+1] = "dir " .. dir .. " = netw " .. netw_num(netID)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
print("NetIDs " .. N(minetest.get_position_from_hash(hash)).name .. ": " .. table.concat(tbl, ", "))
|
|
||||||
end
|
end
|
||||||
|
print("NetIDs " .. N(minetest.get_position_from_hash(hash)).name .. ": " .. table.concat(tbl, ", "))
|
||||||
end
|
end
|
||||||
minetest.after(4, debug)
|
minetest.after(4, debug)
|
||||||
end
|
end
|
||||||
|
@ -90,7 +89,7 @@ end
|
||||||
local function net_def(pos, netw_type)
|
local function net_def(pos, netw_type)
|
||||||
local ndef = minetest.registered_nodes[N(pos).name]
|
local ndef = minetest.registered_nodes[N(pos).name]
|
||||||
if ndef and ndef.networks then
|
if ndef and ndef.networks then
|
||||||
return ndef.networks[netw_type] or {}
|
return ndef.networks[netw_type]
|
||||||
else
|
else
|
||||||
return hidden_node(pos, netw_type)
|
return hidden_node(pos, netw_type)
|
||||||
end
|
end
|
||||||
|
@ -99,7 +98,7 @@ end
|
||||||
local function net_def2(pos, node_name, netw_type)
|
local function net_def2(pos, node_name, netw_type)
|
||||||
local ndef = minetest.registered_nodes[node_name]
|
local ndef = minetest.registered_nodes[node_name]
|
||||||
if ndef and ndef.networks then
|
if ndef and ndef.networks then
|
||||||
return ndef.networks[netw_type] or {}
|
return ndef.networks[netw_type]
|
||||||
else
|
else
|
||||||
return hidden_node(pos, netw_type)
|
return hidden_node(pos, netw_type)
|
||||||
end
|
end
|
||||||
|
@ -179,12 +178,11 @@ local function store_node_connection_sides(pos, tlib2)
|
||||||
local node = N(pos)
|
local node = N(pos)
|
||||||
local val = 0
|
local val = 0
|
||||||
local ndef = net_def2(pos, node.name, tlib2.tube_type)
|
local ndef = net_def2(pos, node.name, tlib2.tube_type)
|
||||||
local sides = ndef.sides or ndef.get_sides and ndef.get_sides(pos, node)
|
if ndef then
|
||||||
if sides then
|
|
||||||
for dir = 1,6 do
|
for dir = 1,6 do
|
||||||
val = val * 2
|
val = val * 2
|
||||||
local side = DirToSide[outdir_to_dir(dir, node.param2)]
|
local side = DirToSide[outdir_to_dir(dir, node.param2)]
|
||||||
if sides[side] then
|
if ndef.sides[side] then
|
||||||
if connected(tlib2, pos, dir) then
|
if connected(tlib2, pos, dir) then
|
||||||
val = val + 1
|
val = val + 1
|
||||||
end
|
end
|
||||||
|
@ -218,15 +216,19 @@ end
|
||||||
-- check if the given tube dir into the node is valid
|
-- check if the given tube dir into the node is valid
|
||||||
local function valid_indir(pos, indir, node, net_name)
|
local function valid_indir(pos, indir, node, net_name)
|
||||||
local ndef = net_def2(pos, node.name, net_name)
|
local ndef = net_def2(pos, node.name, net_name)
|
||||||
local sides = ndef.sides or ndef.get_sides and ndef.get_sides(pos, node)
|
if ndef then
|
||||||
local side = DirToSide[indir_to_dir(indir, node.param2)]
|
local side = DirToSide[indir_to_dir(indir, node.param2)]
|
||||||
if not sides or sides and not sides[side] then return false end
|
if ndef.sides[side] then
|
||||||
return true
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function is_junction(pos, name, tube_type)
|
local function is_junction(pos, name, tlib2)
|
||||||
local ndef = net_def2(pos, name, tube_type)
|
local ndef = net_def2(pos, name, tlib2.tube_type)
|
||||||
return ndef.ntype == "junc"
|
if ndef then
|
||||||
|
return ndef.ntype == "junc"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Do the walk through the tubelib2 network.
|
-- Do the walk through the tubelib2 network.
|
||||||
|
@ -235,7 +237,7 @@ end
|
||||||
-- if outdir is given, only this dir is used
|
-- if outdir is given, only this dir is used
|
||||||
local function connection_walk(pos, outdir, indir, node, tlib2, clbk)
|
local function connection_walk(pos, outdir, indir, node, tlib2, clbk)
|
||||||
if clbk then clbk(pos, indir, node) end
|
if clbk then clbk(pos, indir, node) end
|
||||||
if outdir or is_junction(pos, node.name, tlib2.tube_type) then
|
if outdir or is_junction(pos, node.name, tlib2) then
|
||||||
for _,outdir in ipairs(get_outdirs(pos, tlib2, outdir)) do
|
for _,outdir in ipairs(get_outdirs(pos, tlib2, outdir)) do
|
||||||
local pos2, indir2 = tlib2:get_connected_node_pos(pos, outdir)
|
local pos2, indir2 = tlib2:get_connected_node_pos(pos, outdir)
|
||||||
local node = N(pos2)
|
local node = N(pos2)
|
||||||
|
@ -255,9 +257,12 @@ local function collect_network_nodes(pos, tlib2, outdir)
|
||||||
local netw_type = tlib2.tube_type
|
local netw_type = tlib2.tube_type
|
||||||
-- outdir corresponds to the indir coming from
|
-- outdir corresponds to the indir coming from
|
||||||
connection_walk(pos, outdir, Flip[outdir], node, tlib2, function(pos, indir, node)
|
connection_walk(pos, outdir, Flip[outdir], node, tlib2, function(pos, indir, node)
|
||||||
local ntype = net_def2(pos, node.name, netw_type).ntype
|
local ndef = net_def2(pos, node.name, netw_type)
|
||||||
if not netw[ntype] then netw[ntype] = {} end
|
if ndef then
|
||||||
netw[ntype][#netw[ntype] + 1] = {pos = pos, indir = indir}
|
local ntype = ndef.ntype
|
||||||
|
if not netw[ntype] then netw[ntype] = {} end
|
||||||
|
netw[ntype][#netw[ntype] + 1] = {pos = pos, indir = indir}
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
netw.ttl = minetest.get_gametime() + TTL
|
netw.ttl = minetest.get_gametime() + TTL
|
||||||
netw.num_nodes = NumNodes
|
netw.num_nodes = NumNodes
|
||||||
|
@ -327,13 +332,17 @@ local function get_netID_and_network(pos, tlib2, outdir)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- determine network ID (largest hash number of all nodes with given type)
|
-- determine network ID (largest hash number of all nodes with given type)
|
||||||
local function determine_netID(tlib2, netw, node_type)
|
local function determine_netID(netw)
|
||||||
local netID = 0
|
local netID = 0
|
||||||
for _, item in ipairs(netw[node_type] or {}) do
|
for node_type, table in pairs(netw) do
|
||||||
local outdir = Flip[item.indir]
|
if type(table) == "table" then
|
||||||
local new = minetest.hash_node_position(item.pos) * 8 + outdir
|
for _, item in ipairs(netw[node_type] or {}) do
|
||||||
if netID <= new then
|
local outdir = Flip[item.indir]
|
||||||
netID = new
|
local new = minetest.hash_node_position(item.pos) * 8 + outdir
|
||||||
|
if netID <= new then
|
||||||
|
netID = new
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return netID
|
return netID
|
||||||
|
@ -376,17 +385,41 @@ end
|
||||||
-- API Functions
|
-- API Functions
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- Table fo a 180 degree turn
|
-- Table fo a 180 degree turn: indir => outdir and vice versa
|
||||||
networks.Flip = Flip
|
networks.Flip = Flip
|
||||||
|
|
||||||
-- networks.net_def(pos, netw_type)
|
-- networks.net_def(pos, netw_type)
|
||||||
networks.net_def = net_def
|
networks.net_def = net_def
|
||||||
|
|
||||||
|
-- sides: outdir:
|
||||||
|
-- U
|
||||||
|
-- | B
|
||||||
|
-- | / 6 (N)
|
||||||
|
-- +--|-----+ | 1
|
||||||
|
-- / o /| | /
|
||||||
|
-- +--------+ | |/
|
||||||
|
-- L <----| |o----> R (W) 4 <-------+-------> 2 (O)
|
||||||
|
-- | o | | /|
|
||||||
|
-- | / | + / |
|
||||||
|
-- | / |/ 3 |
|
||||||
|
-- +-/------+ (S) 5
|
||||||
|
-- / |
|
||||||
|
-- F |
|
||||||
|
-- D
|
||||||
|
--
|
||||||
networks.AllSides = Sides -- table for all 6 node sides
|
networks.AllSides = Sides -- table for all 6 node sides
|
||||||
|
|
||||||
-- networks.side_to_outdir(pos, side)
|
-- networks.side_to_outdir(pos, side)
|
||||||
networks.side_to_outdir = side_to_outdir
|
networks.side_to_outdir = side_to_outdir
|
||||||
|
|
||||||
|
-- networks.is_junction(pos, name, tlib2)
|
||||||
|
networks.is_junction = is_junction
|
||||||
|
|
||||||
|
-- Retunrn sa simple number instead of the netID
|
||||||
|
-- For debuging purposes only
|
||||||
|
-- networks.netw_num(netID)
|
||||||
|
networks.netw_num = netw_num
|
||||||
|
|
||||||
-- networks.node_connections(pos, tlib2)
|
-- networks.node_connections(pos, tlib2)
|
||||||
--networks.node_connections = node_connections
|
--networks.node_connections = node_connections
|
||||||
|
|
||||||
|
@ -401,15 +434,14 @@ networks.MAX_NUM_NODES = MAX_NUM_NODES
|
||||||
|
|
||||||
-- To be called from each node via 'tubelib2_on_update2'
|
-- To be called from each node via 'tubelib2_on_update2'
|
||||||
-- 'output' is optional and only needed for nodes with dedicated
|
-- 'output' is optional and only needed for nodes with dedicated
|
||||||
-- pipe sides (e.g. pumps).
|
-- pipe sides. Junctions have to provide 0 (= same network on all sides).
|
||||||
function networks.update_network(pos, outdir, tlib2)
|
function networks.on_update_network(pos, outdir, tlib2)
|
||||||
store_node_connection_sides(pos, tlib2) -- update node internal data
|
store_node_connection_sides(pos, tlib2) -- update node internal data
|
||||||
delete_netID(pos, tlib2, outdir or 0) -- delete node netIDs and network
|
delete_netID(pos, tlib2, outdir or 0) -- delete node netIDs and network
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Provide or determine netID
|
-- Provide or determine netID
|
||||||
-- `node_type` is nedded to determine the netID
|
function networks.get_netID(pos, tlib2, outdir)
|
||||||
function networks.get_netID(pos, tlib2, outdir, node_type)
|
|
||||||
local netID = get_netID_and_network(pos, tlib2, outdir)
|
local netID = get_netID_and_network(pos, tlib2, outdir)
|
||||||
if netID then
|
if netID then
|
||||||
return netID
|
return netID
|
||||||
|
@ -417,7 +449,7 @@ function networks.get_netID(pos, tlib2, outdir, node_type)
|
||||||
|
|
||||||
local netw = collect_network_nodes(pos, tlib2, outdir)
|
local netw = collect_network_nodes(pos, tlib2, outdir)
|
||||||
if netw.num_nodes > 1 then
|
if netw.num_nodes > 1 then
|
||||||
netID = determine_netID(tlib2, netw, node_type)
|
netID = determine_netID(netw)
|
||||||
if netID > 0 then
|
if netID > 0 then
|
||||||
store_netID(tlib2, netw, netID)
|
store_netID(tlib2, netw, netID)
|
||||||
return netID
|
return netID
|
||||||
|
@ -427,6 +459,6 @@ end
|
||||||
|
|
||||||
-- Provide network with all node tables
|
-- Provide network with all node tables
|
||||||
function networks.get_network_table(pos, tlib2, outdir)
|
function networks.get_network_table(pos, tlib2, outdir)
|
||||||
local netID, netw = get_netID_and_network(pos, tlib2, outdir)
|
local _, netw = get_netID_and_network(pos, tlib2, outdir)
|
||||||
return netw or {}
|
return netw or {}
|
||||||
end
|
end
|
||||||
|
|
133
power.lua
133
power.lua
|
@ -16,31 +16,57 @@ local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
|
||||||
local M = minetest.get_meta
|
local M = minetest.get_meta
|
||||||
local N = tubelib2.get_node_lvm
|
local N = tubelib2.get_node_lvm
|
||||||
|
|
||||||
local DEFAULT_CAPA = 100
|
-- Storage parameters:
|
||||||
local Power = {} -- {netID = {curr_level, min_level, max_level, max_capa, sum_consumed, sum_provided, sum_available}}
|
-- capa = maximum value in power units
|
||||||
|
-- load = current value in power units
|
||||||
|
-- level = ratio value (load/capa) (0..1)
|
||||||
|
|
||||||
-- Determine level, capa and other network storage data
|
local Power = {} -- {netID = {curr_load, min_load, max_load, max_capa, consumed, provided, available}}
|
||||||
local function get_storage_data(pos, tlib2, outdir)
|
|
||||||
|
-- Determine load, capa and other power network data
|
||||||
|
local function get_power_data(pos, tlib2, outdir)
|
||||||
local netw = networks.get_network_table(pos, tlib2, outdir)
|
local netw = networks.get_network_table(pos, tlib2, outdir)
|
||||||
local max_capa = DEFAULT_CAPA
|
local max_capa = 0
|
||||||
local curr_level = 0
|
local curr_load = 0
|
||||||
|
-- Generators
|
||||||
|
for _,item in ipairs(netw.gen or {}) do
|
||||||
|
local ndef = minetest.registered_nodes[N(item.pos).name]
|
||||||
|
local data = ndef.get_generator_data(item.pos)
|
||||||
|
max_capa = max_capa + data.perf -- generator performance = capa
|
||||||
|
curr_load = curr_load + (data.level * data.perf)
|
||||||
|
end
|
||||||
|
-- Storage systems
|
||||||
for _,item in ipairs(netw.sto or {}) do
|
for _,item in ipairs(netw.sto or {}) do
|
||||||
local ndef = minetest.registered_nodes[N(item.pos).name]
|
local ndef = minetest.registered_nodes[N(item.pos).name]
|
||||||
local level, capa = ndef.get_storage_level(item.pos)
|
local data = ndef.get_storage_data(item.pos)
|
||||||
curr_level = curr_level + level
|
max_capa = max_capa + data.capa
|
||||||
max_capa = max_capa + capa
|
curr_load = curr_load + (data.level * data.capa)
|
||||||
end
|
end
|
||||||
return {
|
return {
|
||||||
curr_level = curr_level, -- network storage level
|
curr_load = curr_load, -- network storage value
|
||||||
min_level = curr_level, -- minimal storage level
|
min_load = curr_load, -- minimal storage value
|
||||||
max_level = curr_level, -- maximal storage level
|
max_load = curr_load, -- maximal storage value
|
||||||
max_capa = max_capa, -- network storage capacity
|
max_capa = max_capa, -- network storage capacity
|
||||||
consumed = 0, -- consumed power over all consumers
|
consumed = 0, -- consumed power over all consumers
|
||||||
provided = 0, -- provided power over all generators
|
provided = 0, -- provided power over all generators
|
||||||
available = 0, -- max. available power over all generators
|
available = 0, -- max. available power over all generators
|
||||||
|
num_nodes = netw.num_nodes,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Consumer/Generator/Storage
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- To be called for each power network change via
|
||||||
|
-- tubelib2_on_update2 or register_on_tube_update2
|
||||||
|
function networks.on_update_power_network(pos, outdir, tlib2)
|
||||||
|
local netID = networks.get_netID(pos, tlib2, outdir)
|
||||||
|
if netID then
|
||||||
|
Power[netID] = nil
|
||||||
|
end
|
||||||
|
networks.on_update_network(pos, outdir, tlib2)
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- Consumer
|
-- Consumer
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
@ -48,10 +74,10 @@ end
|
||||||
-- For consumers, outdir is optional
|
-- For consumers, outdir is optional
|
||||||
function networks.power_available(pos, tlib2, outdir)
|
function networks.power_available(pos, tlib2, outdir)
|
||||||
for _,outdir in ipairs(networks.get_outdirs(pos, tlib2, outdir)) do
|
for _,outdir in ipairs(networks.get_outdirs(pos, tlib2, outdir)) do
|
||||||
local netID = networks.get_netID(pos, tlib2, outdir, "gen")
|
local netID = networks.get_netID(pos, tlib2, outdir)
|
||||||
if netID then
|
if netID then
|
||||||
local pwr = Power[netID] or get_storage_data(pos, tlib2, outdir)
|
local pwr = Power[netID] or get_power_data(pos, tlib2, outdir)
|
||||||
return pwr.curr_level > 0
|
return pwr.curr_load > 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -59,19 +85,19 @@ end
|
||||||
-- For consumers, outdir is optional
|
-- For consumers, outdir is optional
|
||||||
function networks.consume_power(pos, tlib2, outdir, amount)
|
function networks.consume_power(pos, tlib2, outdir, amount)
|
||||||
for _,outdir in ipairs(networks.get_outdirs(pos, tlib2, outdir)) do
|
for _,outdir in ipairs(networks.get_outdirs(pos, tlib2, outdir)) do
|
||||||
local netID = networks.get_netID(pos, tlib2, outdir, "gen")
|
local netID = networks.get_netID(pos, tlib2, outdir)
|
||||||
if netID then
|
if netID then
|
||||||
local pwr = Power[netID] or get_storage_data(pos, tlib2, outdir)
|
local pwr = Power[netID] or get_power_data(pos, tlib2, outdir)
|
||||||
if pwr.curr_level >= amount then
|
if pwr.curr_load >= amount then
|
||||||
pwr.curr_level = pwr.curr_level - amount
|
pwr.curr_load = pwr.curr_load - amount
|
||||||
pwr.min_level = math.min(pwr.min_level, pwr.curr_level)
|
pwr.min_load = math.min(pwr.min_load, pwr.curr_load)
|
||||||
pwr.consumed = pwr.consumed + amount
|
pwr.consumed = pwr.consumed + amount
|
||||||
Power[netID] = pwr
|
Power[netID] = pwr
|
||||||
return amount
|
return amount
|
||||||
else
|
else
|
||||||
local consumed = pwr.curr_level
|
local consumed = pwr.curr_load
|
||||||
pwr.curr_level = 0
|
pwr.curr_load = 0
|
||||||
pwr.min_level = 0
|
pwr.min_load = 0
|
||||||
pwr.consumed = pwr.consumed + consumed
|
pwr.consumed = pwr.consumed + consumed
|
||||||
Power[netID] = pwr
|
Power[netID] = pwr
|
||||||
return consumed
|
return consumed
|
||||||
|
@ -88,27 +114,27 @@ end
|
||||||
-- cp1 and cp2 are control points for the charge regulator.
|
-- cp1 and cp2 are control points for the charge regulator.
|
||||||
-- From cp1 the charging power is reduced more and more and reaches zero at cp2.
|
-- From cp1 the charging power is reduced more and more and reaches zero at cp2.
|
||||||
function networks.provide_power(pos, tlib2, outdir, amount, cp1, cp2)
|
function networks.provide_power(pos, tlib2, outdir, amount, cp1, cp2)
|
||||||
local netID = networks.get_netID(pos, tlib2, outdir, "gen")
|
local netID = networks.get_netID(pos, tlib2, outdir)
|
||||||
if netID then
|
if netID then
|
||||||
local pwr = Power[netID] or get_storage_data(pos, tlib2, outdir)
|
local pwr = Power[netID] or get_power_data(pos, tlib2, outdir)
|
||||||
local x = pwr.curr_level / pwr.max_capa
|
local x = pwr.curr_load / pwr.max_capa
|
||||||
|
|
||||||
pwr.available = pwr.available + amount
|
pwr.available = pwr.available + amount
|
||||||
amount = math.min(amount, pwr.max_capa - pwr.curr_level)
|
amount = math.min(amount, pwr.max_capa - pwr.curr_load)
|
||||||
cp1 = cp1 or 0.5
|
cp1 = cp1 or 0.5
|
||||||
cp2 = cp2 or 1.0
|
cp2 = cp2 or 1.0
|
||||||
|
|
||||||
if x < cp1 then -- charge with full power
|
if x < cp1 then -- charge with full power
|
||||||
pwr.curr_level = pwr.curr_level + amount
|
pwr.curr_load = pwr.curr_load + amount
|
||||||
pwr.max_level = math.max(pwr.max_level, pwr.curr_level)
|
pwr.max_load = math.max(pwr.max_load, pwr.curr_load)
|
||||||
pwr.provided = pwr.provided + amount
|
pwr.provided = pwr.provided + amount
|
||||||
Power[netID] = pwr
|
Power[netID] = pwr
|
||||||
return amount
|
return amount
|
||||||
elseif x < cp2 then -- charge with reduced power
|
elseif x < cp2 then -- charge with reduced power
|
||||||
local factor = 1 - ((x - cp1) / (cp2 - cp1))
|
local factor = 1 - ((x - cp1) / (cp2 - cp1))
|
||||||
local provided = amount * factor
|
local provided = amount * factor
|
||||||
pwr.curr_level = pwr.curr_level + provided
|
pwr.curr_load = pwr.curr_load + provided
|
||||||
pwr.max_level = math.max(pwr.max_level, pwr.curr_level)
|
pwr.max_load = math.max(pwr.max_load, pwr.curr_load)
|
||||||
pwr.provided = pwr.provided + provided
|
pwr.provided = pwr.provided + provided
|
||||||
Power[netID] = pwr
|
Power[netID] = pwr
|
||||||
return provided
|
return provided
|
||||||
|
@ -122,23 +148,25 @@ end
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- Storage
|
-- Storage
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- Function returns the level/charge as ratio (0..1)
|
-- Function returns a table with storage level as ratio (0..1) and the
|
||||||
|
-- charging state (1 = charging, -1 = uncharging, or 0)
|
||||||
-- Param outdir is optional
|
-- Param outdir is optional
|
||||||
-- Function provides nil if no network is available
|
-- Function provides nil if no network is available
|
||||||
function networks.get_storage_level(pos, tlib2, outdir)
|
function networks.get_storage_level(pos, tlib2, outdir)
|
||||||
for _,outdir in ipairs(networks.get_outdirs(pos, tlib2, outdir)) do
|
for _,outdir in ipairs(networks.get_outdirs(pos, tlib2, outdir)) do
|
||||||
local netID = networks.get_netID(pos, tlib2, outdir, "gen")
|
local netID = networks.get_netID(pos, tlib2, outdir)
|
||||||
if netID then
|
if netID then
|
||||||
local pwr = Power[netID] or get_storage_data(pos, tlib2, outdir)
|
local pwr = Power[netID] or get_power_data(pos, tlib2, outdir)
|
||||||
return pwr.curr_level / pwr.max_capa
|
local charging = (pwr.provided > pwr.consumed and 1) or (pwr.provided < pwr.consumed and -1) or 0
|
||||||
|
return {level = pwr.curr_load / pwr.max_capa, charging = charging}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- To be called for each network storage change (dig/place storage nodes)
|
-- To be called for each network storage change (turn on/off of storage/generator nodes)
|
||||||
function networks.reinit_storage(pos, tlib2, outdir)
|
function networks.start_storage_calc(pos, tlib2, outdir)
|
||||||
for _,outdir in ipairs(networks.get_outdirs(pos, tlib2, outdir)) do
|
for _,outdir in ipairs(networks.get_outdirs(pos, tlib2, outdir)) do
|
||||||
local netID = networks.get_netID(pos, tlib2, outdir, "gen")
|
local netID = networks.get_netID(pos, tlib2, outdir)
|
||||||
if netID then
|
if netID then
|
||||||
Power[netID] = nil
|
Power[netID] = nil
|
||||||
end
|
end
|
||||||
|
@ -170,13 +198,13 @@ function networks.turn_switch_off(pos, tlib2, name_off, name_on)
|
||||||
if node.name == name_on then
|
if node.name == name_on then
|
||||||
node.name = name_off
|
node.name = name_off
|
||||||
minetest.swap_node(pos, node)
|
minetest.swap_node(pos, node)
|
||||||
tlib2:after_dig_tube(pos, node)
|
|
||||||
meta:set_int("tl2_param2", 0)
|
meta:set_int("tl2_param2", 0)
|
||||||
|
tlib2:after_dig_tube(pos, node)
|
||||||
return true
|
return true
|
||||||
elseif meta:contains("tl2_param2") then
|
elseif meta:contains("tl2_param2") then
|
||||||
meta:set_int("tl2_param2_copy", meta:get_int("tl2_param2"))
|
meta:set_int("tl2_param2_copy", meta:get_int("tl2_param2"))
|
||||||
meta:set_int("tl2_param2", 0)
|
meta:set_int("tl2_param2", 0)
|
||||||
tlib2:i(pos, node)
|
tlib2:after_dig_tube(pos, node)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -184,19 +212,20 @@ end
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- Statistics
|
-- Statistics
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
function networks.get_storage_data(pos, tlib2, outdir)
|
function networks.get_power_data(pos, tlib2, outdir)
|
||||||
for _,outdir in ipairs(networks.get_outdirs(pos, tlib2, outdir)) do
|
for _,outdir in ipairs(networks.get_outdirs(pos, tlib2, outdir)) do
|
||||||
local netID = networks.get_netID(pos, tlib2, outdir, "gen")
|
local netID = networks.get_netID(pos, tlib2, outdir)
|
||||||
if netID then
|
if netID then
|
||||||
local pwr = Power[netID] or get_storage_data(pos, tlib2, outdir)
|
local pwr = Power[netID] or get_power_data(pos, tlib2, outdir)
|
||||||
local res = {
|
local res = {
|
||||||
curr_level = pwr.curr_level,
|
curr_load = pwr.curr_load,
|
||||||
min_level = pwr.min_level,
|
min_load = pwr.min_load,
|
||||||
max_level = pwr.max_level,
|
max_load = pwr.max_load,
|
||||||
max_capa = pwr.max_capa,
|
max_capa = pwr.max_capa,
|
||||||
consumed = pwr.consumed,
|
consumed = pwr.consumed,
|
||||||
provided = pwr.provided,
|
provided = pwr.provided,
|
||||||
available = pwr.available,
|
available = pwr.available,
|
||||||
|
netw_num = networks.netw_num(netID),
|
||||||
}
|
}
|
||||||
pwr.consumed = 0
|
pwr.consumed = 0
|
||||||
pwr.provided = 0
|
pwr.provided = 0
|
||||||
|
@ -206,14 +235,14 @@ function networks.get_storage_data(pos, tlib2, outdir)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function networks.reset_storage_min_max(pos, tlib2, outdir)
|
function networks.reset_min_max_load_values(pos, tlib2, outdir)
|
||||||
for _,outdir in ipairs(networks.get_outdirs(pos, tlib2, outdir)) do
|
for _,outdir in ipairs(networks.get_outdirs(pos, tlib2, outdir)) do
|
||||||
local netID = networks.get_netID(pos, tlib2, outdir, "gen")
|
local netID = networks.get_netID(pos, tlib2, outdir)
|
||||||
if netID then
|
if netID then
|
||||||
local pwr = Power[netID] or get_storage_data(pos, tlib2, outdir)
|
local pwr = Power[netID] or get_power_data(pos, tlib2, outdir)
|
||||||
pwr.min_level = pwr.curr_level
|
pwr.min_load = pwr.curr_load
|
||||||
pwr.max_level = pwr.curr_level
|
pwr.max_load = pwr.curr_load
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,7 +30,7 @@ end
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
local Cable = tubelib2.Tube:new({
|
local Cable = tubelib2.Tube:new({
|
||||||
dirs_to_check = {1,2,3,4,5,6},
|
dirs_to_check = {1,2,3,4,5,6},
|
||||||
max_tube_length = 20,
|
max_tube_length = 100,
|
||||||
tube_type = "test",
|
tube_type = "test",
|
||||||
primary_node_names = {"networks:cableS", "networks:cableA", "networks:switch_on"},
|
primary_node_names = {"networks:cableS", "networks:cableA", "networks:switch_on"},
|
||||||
secondary_node_names = {
|
secondary_node_names = {
|
||||||
|
@ -86,7 +86,7 @@ if HIDDEN then
|
||||||
else
|
else
|
||||||
-- use own global callback
|
-- use own global callback
|
||||||
Cable:register_on_tube_update2(function(pos, outdir, tlib2, node)
|
Cable:register_on_tube_update2(function(pos, outdir, tlib2, node)
|
||||||
networks.update_network(pos, outdir, tlib2)
|
networks.on_update_power_network(pos, outdir, tlib2)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -177,11 +177,11 @@ networks.register_junction("networks:junction", size, Boxes, Cable, {
|
||||||
minetest.swap_node(pos, {name = name, param2 = 0})
|
minetest.swap_node(pos, {name = name, param2 = 0})
|
||||||
Cable:after_place_node(pos)
|
Cable:after_place_node(pos)
|
||||||
end,
|
end,
|
||||||
-- junctions need own 'tubelib2_on_update2', cause they provide 0 for outdir!
|
-- junction needs own 'tubelib2_on_update2', cause it provides 0 for outdir!
|
||||||
tubelib2_on_update2 = function(pos, outdir, tlib2, node)
|
tubelib2_on_update2 = function(pos, outdir, tlib2, node)
|
||||||
local name = "networks:junction"..networks.junction_type(pos, Cable)
|
local name = "networks:junction"..networks.junction_type(pos, Cable)
|
||||||
minetest.swap_node(pos, {name = name, param2 = 0})
|
minetest.swap_node(pos, {name = name, param2 = 0})
|
||||||
networks.update_network(pos, 0, tlib2)
|
networks.on_update_power_network(pos, 0, tlib2)
|
||||||
end,
|
end,
|
||||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||||
Cable:after_dig_node(pos)
|
Cable:after_dig_node(pos)
|
||||||
|
@ -245,6 +245,15 @@ minetest.register_node("networks:generator", {
|
||||||
M(pos):set_string("infotext", "providing "..round(mem.provided))
|
M(pos):set_string("infotext", "providing "..round(mem.provided))
|
||||||
minetest.get_node_timer(pos):start(CYCLE_TIME)
|
minetest.get_node_timer(pos):start(CYCLE_TIME)
|
||||||
end
|
end
|
||||||
|
networks.start_storage_calc(pos, Cable)
|
||||||
|
end,
|
||||||
|
get_generator_data = function(pos)
|
||||||
|
local mem = tubelib2.get_mem(pos)
|
||||||
|
if mem.running then
|
||||||
|
return {level = (mem.load or 0) / GEN_MAX, perf = GEN_MAX}
|
||||||
|
else
|
||||||
|
return {level = 0, perf = 0}
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
networks = {
|
networks = {
|
||||||
test = {
|
test = {
|
||||||
|
@ -377,28 +386,45 @@ minetest.register_node("networks:storage", {
|
||||||
tiles = {"networks_sto.png"},
|
tiles = {"networks_sto.png"},
|
||||||
on_timer = function(pos, elapsed)
|
on_timer = function(pos, elapsed)
|
||||||
local mem = tubelib2.get_mem(pos)
|
local mem = tubelib2.get_mem(pos)
|
||||||
local val = networks.get_storage_level(pos, Cable)
|
local data = networks.get_storage_level(pos, Cable)
|
||||||
if val then
|
if data then
|
||||||
mem.level = val * STORAGE_CAPA
|
mem.load = data.level * STORAGE_CAPA
|
||||||
|
local percent = data.level * 100
|
||||||
|
M(pos):set_string("infotext", "level = "..round(percent)..", charging = "..data.charging)
|
||||||
end
|
end
|
||||||
local percent = (mem.level or 0) / STORAGE_CAPA * 100
|
|
||||||
M(pos):set_string("infotext", "level = "..round(percent))
|
|
||||||
return true
|
return true
|
||||||
end,
|
end,
|
||||||
after_place_node = function(pos)
|
after_place_node = function(pos)
|
||||||
Cable:after_place_node(pos)
|
Cable:after_place_node(pos)
|
||||||
minetest.get_node_timer(pos):start(CYCLE_TIME)
|
|
||||||
tubelib2.init_mem(pos)
|
tubelib2.init_mem(pos)
|
||||||
networks.reinit_storage(pos, Cable)
|
M(pos):set_string("infotext", "off")
|
||||||
end,
|
end,
|
||||||
after_dig_node = function(pos, oldnode)
|
after_dig_node = function(pos, oldnode)
|
||||||
Cable:after_dig_node(pos)
|
Cable:after_dig_node(pos)
|
||||||
tubelib2.del_mem(pos)
|
tubelib2.del_mem(pos)
|
||||||
networks.reinit_storage(pos, Cable)
|
|
||||||
end,
|
end,
|
||||||
get_storage_level = function(pos)
|
on_rightclick = function(pos, node, clicker)
|
||||||
local mem = tubelib2.get_mem(pos)
|
local mem = tubelib2.get_mem(pos)
|
||||||
return mem.level or 0, STORAGE_CAPA
|
if mem.running then
|
||||||
|
mem.running = false
|
||||||
|
M(pos):set_string("infotext", "off")
|
||||||
|
minetest.get_node_timer(pos):stop()
|
||||||
|
else
|
||||||
|
mem.provided = mem.provided or 0
|
||||||
|
mem.running = true
|
||||||
|
local percent = (mem.load or 0) / STORAGE_CAPA * 100
|
||||||
|
M(pos):set_string("infotext", "level = "..round(percent))
|
||||||
|
minetest.get_node_timer(pos):start(CYCLE_TIME)
|
||||||
|
end
|
||||||
|
networks.start_storage_calc(pos, Cable)
|
||||||
|
end,
|
||||||
|
get_storage_data = function(pos)
|
||||||
|
local mem = tubelib2.get_mem(pos)
|
||||||
|
if mem.running then
|
||||||
|
return {level = (mem.load or 0) / STORAGE_CAPA, capa = STORAGE_CAPA}
|
||||||
|
else
|
||||||
|
return {level = 0, capa = 0}
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
networks = {
|
networks = {
|
||||||
test = {
|
test = {
|
||||||
|
@ -436,7 +462,7 @@ local function replace_node(itemstack, placer, pointed_thing)
|
||||||
gain = 1,
|
gain = 1,
|
||||||
max_hear_distance = 5})
|
max_hear_distance = 5})
|
||||||
elseif placer and placer.get_player_name then
|
elseif placer and placer.get_player_name then
|
||||||
minetest.chat_send_player(placer:get_player_name(), "Invalid fill material!")
|
minetest.chat_send_player(placer:get_player_name(), "Invalid fill material in inventory slot 1!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -528,6 +554,12 @@ minetest.register_node("networks:switch_off", {
|
||||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||||
Cable:after_dig_node(pos)
|
Cable:after_dig_node(pos)
|
||||||
end,
|
end,
|
||||||
|
networks = {
|
||||||
|
test = {
|
||||||
|
sides = {}, -- no connection sides
|
||||||
|
ntype = "con",
|
||||||
|
},
|
||||||
|
},
|
||||||
paramtype2 = "facedir", -- important!
|
paramtype2 = "facedir", -- important!
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
node_box = node_box,
|
node_box = node_box,
|
||||||
|
@ -550,12 +582,13 @@ minetest.register_chatcommand("power_data", {
|
||||||
local pos = player:get_pos()
|
local pos = player:get_pos()
|
||||||
pos.y = pos.y - 0.5
|
pos.y = pos.y - 0.5
|
||||||
pos = vector.round(pos)
|
pos = vector.round(pos)
|
||||||
local data = networks.get_storage_data(pos, Cable)
|
local data = networks.get_power_data(pos, Cable)
|
||||||
if data then
|
if data then
|
||||||
local s = string.format("generated = %u/%u, consumed = %u, storage level = %u/%u (min = %u, max = %u)",
|
local s = string.format("Netw %u: generated = %u/%u, consumed = %u, storage load = %u/%u (min = %u, max = %u)",
|
||||||
round(data.provided), data.available, round(data.consumed),
|
data.netw_num, round(data.provided),
|
||||||
round(data.curr_level), round(data.max_capa),
|
data.available, round(data.consumed),
|
||||||
round(data.min_level), round(data.max_level))
|
round(data.curr_load), round(data.max_capa),
|
||||||
|
round(data.min_load), round(data.max_load))
|
||||||
return true, s
|
return true, s
|
||||||
end
|
end
|
||||||
return false, "No valid node position!"
|
return false, "No valid node position!"
|
Loading…
Reference in New Issue