bug fixes and improvements

master
Joachim Stolberg 2021-05-29 20:57:48 +02:00
parent 3753b4aa92
commit 5a52d165c0
6 changed files with 223 additions and 123 deletions

View File

@ -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

View File

@ -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

View File

@ -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")

View File

@ -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
View File

@ -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

View File

@ -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!"