central power distribution function added

power terminal improvements
bauxite and reactor added
This commit is contained in:
Joachim Stolberg 2019-10-17 21:26:39 +02:00
parent 10c1700270
commit 7b180200bc
15 changed files with 381 additions and 154 deletions

View File

@ -79,6 +79,16 @@ local function set_pos_list(player, lPos)
player:set_attribute("techage_forceload_blocks", minetest.serialize(lPos))
end
local function shoe_flbs(pos, name, range)
local pos1 = {x=pos.x-range, y=pos.y-range, z=pos.z-range}
local pos2 = {x=pos.x+range, y=pos.y+range, z=pos.z+range}
for _,npos in ipairs(minetest.find_nodes_in_area(pos1, pos2, {"techage:forceload"})) do
local _pos1, _pos2 = calc_area(npos)
local owner = M(npos):get_string("owner")
techage.mark_region(name, _pos1, _pos2, owner)
end
end
local function get_data(pos, player)
local pos1, pos2 = calc_area(pos)
local num = #minetest.deserialize(player:get_attribute("techage_forceload_blocks")) or 0
@ -86,24 +96,27 @@ local function get_data(pos, player)
return pos1, pos2, num, max
end
local function formspec(player)
local lPos = get_pos_list(player)
local tRes = {}
for idx,pos in ipairs(lPos) do
local pos1, pos2 = calc_area(pos)
local ypos = 0.2 + idx * 0.4
tRes[#tRes+1] = idx
tRes[#tRes+1] = minetest.formspec_escape(P2S(pos1))
tRes[#tRes+1] = "to"
tRes[#tRes+1] = minetest.formspec_escape(P2S(pos2))
local function formspec(name)
local player = minetest.get_player_by_name(name)
if player then
local lPos = get_pos_list(player)
local tRes = {}
for idx,pos in ipairs(lPos) do
local pos1, pos2 = calc_area(pos)
local ypos = 0.2 + idx * 0.4
tRes[#tRes+1] = idx
tRes[#tRes+1] = minetest.formspec_escape(P2S(pos1))
tRes[#tRes+1] = "to"
tRes[#tRes+1] = minetest.formspec_escape(P2S(pos2))
end
return "size[7,9]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"label[0,0;List of your Forceload Blocks:]"..
"tablecolumns[text,width=1.2;text,width=12;text,width=1.6;text,width=12]"..
"table[0,0.6;6.8,8.4;output;"..table.concat(tRes, ",")..";1]"
end
return "size[7,9]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"label[0,0;List of your Forceload Blocks:]"..
"tablecolumns[text,width=1.2;text,width=12;text,width=1.6;text,width=12]"..
"table[0,0.6;6.8,8.4;output;"..table.concat(tRes, ",")..";1]"
end
@ -151,10 +164,13 @@ minetest.register_node("techage:forceload", {
end,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
if M(pos):get_string("owner") == clicker:get_player_name() or
minetest.check_player_privs(clicker:get_player_name(), "server") then
local s = formspec(clicker)
minetest.show_formspec(clicker:get_player_name(), "techage:forceload", s)
local owner = M(pos):get_string("owner")
local name = clicker:get_player_name()
if name == owner or minetest.check_player_privs(name, "server") then
local s = formspec(owner)
if s then
minetest.show_formspec(owner, "techage:forceload", s)
end
end
end,
@ -201,3 +217,20 @@ minetest.register_on_leaveplayer(function(player)
end
end)
minetest.register_chatcommand("forceload", {
params = "",
description = "Forceloadblöcke der Umgebung 64x64x64 anzeigen",
func = function(name, param)
if minetest.check_player_privs(name, "superminer") then
local player = minetest.get_player_by_name(name)
if player then
local pos = player:get_pos()
pos = vector.round(pos)
shoe_flbs(pos, name, 64)
end
else
return false, "Priv missing"
end
end,
})

View File

@ -293,4 +293,5 @@ techage.add_grinder_recipe({input="default:pine_tree", output="default:pine_need
techage.add_grinder_recipe({input="default:acacia_tree", output="default:acacia_leaves 8"})
techage.add_grinder_recipe({input="default:aspen_tree", output="default:aspen_leaves 8"})
techage.add_grinder_recipe({input="techage:bauxite_cobble", output="techage:bauxite_gravel"})

View File

@ -24,7 +24,7 @@ function techage.unmark_region(name)
end
end
function techage.mark_region(name, pos1, pos2)
function techage.mark_region(name, pos1, pos2, owner)
techage.unmark_region(name)
@ -41,6 +41,9 @@ function techage.mark_region(name, pos1, pos2)
--collisionbox = {-sizex, -sizey, -thickness, sizex, sizey, thickness},
collisionbox = {0,0,0, 0,0,0},
})
if owner then
marker:set_nametag_attributes({text = owner})
end
marker:get_luaentity().player_name = name
table.insert(markers, marker)
end

32
chemistry/reactor.lua Normal file
View File

@ -0,0 +1,32 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
GPL v3
See LICENSE.txt for more information
TA4 Reactor
]]--
local S = techage.S
minetest.register_node("techage:ta4_reactor", {
description = S("TA4 Reactor"),
tiles = {"techage_reactor_side.png"},
drawtype = "mesh",
mesh = "techage_boiler_large.obj",
selection_box = {
type = "fixed",
fixed = {-13/32, -16/32, -13/32, 13/32, 16/32, 13/32},
},
paramtype2 = "facedir",
on_rotate = screwdriver.disallow,
groups = {cracky=2},
is_ground_content = false,
sounds = default.node_sound_stone_defaults(),
})

View File

@ -13,20 +13,18 @@
]]--
-- for lazy programmers
local P = minetest.string_to_pos
local P2P = 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 = function(pos) return minetest.get_node(pos).name end
local S = techage.S
local BLOCKING_TIME = 2
local CYCLE_TIME = 2
local PWR_CAPA = 0.1
local COUNTDOWN = 5
local Param2ToDir = {
[0] = 6,
[1] = 5,
[2] = 2,
[3] = 4,
[4] = 1,
[5] = 3,
}
local Cable = techage.ElectricCable
local power = techage.power
local function collect_network_data(pos, mem)
local data = {
@ -39,74 +37,57 @@ local function collect_network_data(pos, mem)
fcel = {},
other = {},
}
local add = function(kind, attr, val)
data[kind][attr] = (data[kind][attr] or 0) + (val or 0)
end
local max = function(kind, attr, val)
data[kind][attr] = math.max((data[kind][attr] or 0), (val or 0))
end
local add = function(tbl, mem, nomi, real)
tbl.num = (tbl.num or 0) + 1
tbl.load = (tbl.load or 0) + (((mem.pwr_node_alive_cnt or 0) > 0) and 1 or 0)
tbl.nomi = (tbl.nomi or 0) + (nomi or 0)
tbl.real = (tbl.real or 0) + (((mem.pwr_node_alive_cnt or 0) > 0) and (real or 0) or 0)
end
local nnodes = techage.power.limited_connection_walk(pos,
function(pos, node, mem, num_hops, num_nodes)
if node.name == "techage:generator" or node.name == "techage:generator_on" then
add("fuel", "num", 1)
add("fuel", "nomi", mem.pwr_available)
add("fuel", "curr", mem.provided)
add(data.fuel, mem, mem.pwr_available, mem.provided)
elseif node.name == "techage:ta3_akku" then
add("akku", "num", 1)
add("akku", "nomi", mem.pwr_could_provide)
add("akku", "curr", mem.delivered)
add(data.akku, mem, mem.pwr_could_provide, mem.delivered)
elseif node.name == "techage:heatexchanger1" then
add("stor", "num", 1)
add("stor", "nomi", mem.pwr_could_provide)
add("stor", "curr", mem.delivered)
add(data.stor, mem, mem.pwr_could_provide, mem.delivered)
elseif node.name == "techage:tiny_generator" or node.name == "techage:tiny_generator_on" then
add("fuel", "num", 1)
add("fuel", "nomi", mem.pwr_available)
add("fuel", "curr", mem.provided)
add(data.fuel, mem, mem.pwr_available, mem.provided)
elseif node.name == "techage:ta4_solar_inverter" then
add("solar", "num", 1)
add("solar", "nomi", mem.pwr_available)
add("solar", "curr", mem.delivered)
add(data.solar, mem, mem.pwr_available, mem.delivered)
elseif node.name == "techage:ta4_wind_turbine" then
add("wind", "num", 1)
add("wind", "nomi", mem.pwr_available)
add("wind", "curr", mem.delivered)
add(data.wind, mem, mem.pwr_available, mem.delivered)
elseif node.name == "techage:ta4_fuelcell" or node.name == "techage:ta4_fuelcell_on" then
add("fcel", "num", 1)
add("fcel", "nomi", mem.pwr_available)
add("fcel", "curr", mem.provided)
add(data.fcel, mem, mem.pwr_available, mem.provided)
elseif node.name == "techage:ta4_electrolyzer" or node.name == "techage:ta4_electrolyzer_on" then
add("elec", "num", 1)
add("elec", "nomi", -(mem.pwr_could_need or 0))
add("elec", "curr", -(mem.consumed or 0))
add(data.elec, mem, -(mem.pwr_could_need or 0), -(mem.consumed or 0))
elseif mem.pwr_needed and mem.pwr_needed > 0 and (mem.pwr_node_alive_cnt or 0) > 0 then
add("other", "num", 1)
add("other", "nomi", -mem.pwr_needed)
add("other", "curr", mem.pwr_state == 3 and -mem.pwr_needed)
add(data.other, mem, -(mem.pwr_needed or 0), (-mem.pwr_needed or 0))
end
end
)
return data, nnodes
end
local function formspec(pos)
local jpos = minetest.deserialize(M(pos):get_string("junction_pos"))
local data, nnodes = collect_network_data(jpos, tubelib2.get_mem(jpos))
local function formspec(pos, mem)
local data, nnodes = collect_network_data(pos, mem)
local get = function(kind)
return (data[kind].num or 0).." / "..(data[kind].curr or 0).." ku / "..(data[kind].nomi or 0).. " ku"
return (data[kind].load or 0).." / "..(data[kind].num or 0).." : "..
(data[kind].curr or 0).." / "..(data[kind].nomi or 0).. " ku"
end
local alarm = ""
if nnodes > (techage.MAX_NUM_NODES - 50) then
alarm = " (max. "..(techage.MAX_NUM_NODES).." !!!)"
end
local update = mem.countdown > 0 and mem.countdown or S("Update")
return "size[9.5,8.2]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"label[2,0.0;"..S("Network Data").."]"..
"label[3,0.7;"..S("(number / current / max.)").."]"..
"label[1,0.7;"..S("(Num. nodes loaded / max. : Power current / max.)").."]"..
"label[0,1.4;"..S("TA3 Coal/oil")..":]".. "label[5,1.4;"..get("fuel").."]"..
"label[0,2.1;"..S("TA3 Akku")..":]".. "label[5,2.1;"..get("akku").."]"..
"label[0,2.8;"..S("TA4 Solar Inverter")..":]".. "label[5,2.8;"..get("solar").."]"..
@ -116,11 +97,20 @@ local function formspec(pos)
"label[0,5.6;"..S("TA4 Fuel Cell")..":]".. "label[5,5.6;"..get("fcel").."]"..
"label[0,6.3;"..S("Other consumers")..":]".. "label[5,6.3;"..get("other").."]"..
"label[0,7;"..S("Number of nodes").." : "..nnodes..alarm.."]"..
"button[2.5,7.5;2,1;update;"..S("Update").."]"
"button[3.5,7.5;2,1;update;"..update.."]"
end
local function update_formspec(pos)
M(pos):set_string("formspec", formspec(pos))
local function node_timer(pos, elapsed)
local mem = tubelib2.get_mem(pos)
power.generator_alive(pos, mem)
mem.countdown = mem.countdown or 0
if mem.countdown > 0 then
mem.countdown = mem.countdown - 1
M(pos):set_string("formspec", formspec(pos, mem))
end
return true
end
minetest.register_node("techage:ta3_power_terminal", {
@ -142,31 +132,19 @@ minetest.register_node("techage:ta3_power_terminal", {
},
},
after_place_node = function(pos, placer, itemstack)
local node = minetest.get_node(pos)
local outdir = techage.side_to_outdir("B", node.param2)
local jpos = tubelib2.get_pos(pos, outdir)
local mem = tubelib2.init_mem(pos)
mem.blocked_until = 0
local meta = M(pos)
meta:set_string("junction_pos", minetest.serialize(jpos))
meta:set_string("formspec", formspec(pos))
end,
on_receive_fields = function(pos, formname, fields, player)
local mem = tubelib2.get_mem(pos)
mem.blocked_until = mem.blocked_until or minetest.get_gametime()
if fields.update and mem.blocked_until < minetest.get_gametime() then
M(pos):set_string("formspec", formspec(pos))
mem.blocked_until = minetest.get_gametime() + BLOCKING_TIME
minetest.after(BLOCKING_TIME + 1, update_formspec, pos)
end
mem.countdown = COUNTDOWN
end,
on_rightclick = function(pos, node, clicker)
M(pos):set_string("formspec", formspec(pos))
local mem = tubelib2.get_mem(pos)
minetest.get_node_timer(pos):start(CYCLE_TIME)
power.generator_start(pos, mem, PWR_CAPA)
mem.countdown = COUNTDOWN
end,
on_timer = node_timer,
paramtype2 = "facedir",
paramtype = "light",
on_rotate = screwdriver.disallow,
@ -176,6 +154,19 @@ minetest.register_node("techage:ta3_power_terminal", {
sounds = default.node_sound_metal_defaults(),
})
techage.power.register_node({"techage:ta3_power_terminal"}, {
power_network = Cable,
conn_sides = {"B"},
after_place_node = function(pos)
local mem = tubelib2.init_mem(pos)
minetest.get_node_timer(pos):start(CYCLE_TIME)
power.generator_start(pos, mem, PWR_CAPA)
local meta = M(pos)
mem.countdown = 0
meta:set_string("formspec", formspec(pos, mem))
end,
})
minetest.register_craft({
output = "techage:ta3_power_terminal",
recipe = {

View File

@ -20,7 +20,7 @@ minetest.register_craftitem("techage:hydrogen", {
})
minetest.register_craftitem("techage:ta4_fuelcellstack", {
description = S("TA4 Fuell Cell Stack"),
description = S("TA4 Fuel Cell Stack"),
inventory_image = "techage_fc_stack_inv.png",
})

View File

@ -59,8 +59,12 @@ else
-- Nodes1
dofile(MP.."/nodes/baborium.lua")
dofile(MP.."/nodes/usmium.lua")
--dofile(MP.."/nodes/bauxit.lua")
-- Power networks
dofile(MP.."/power/schedule.lua")
--dofile(MP.."/power/distribute.lua")
--dofile(MP.."/power/test.lua")
dofile(MP.."/power/power.lua")
dofile(MP.."/power/power2.lua")
dofile(MP.."/power/junction.lua")
@ -202,7 +206,7 @@ else
dofile(MP.."/energy_storage/nodes.lua")
-- Chemistry
--dofile(MP.."/chemistry/reaktor.lua")
--dofile(MP.."/chemistry/reactor.lua")
-- Hydrogen
dofile(MP.."/hydrogen/hydrogen.lua")

View File

@ -1,7 +1,7 @@
# textdomain: techage
#### TA3 Terminal ####@n@nSend commands to your machines@nand output text messages from your@nmachines to the Terminal.@n@nCommand syntax:@n cmd <num> <cmnd>@n@nexample: cmd 181 on@n<num> is the number of the node to which the command is sent@n'on' is the command to turn machines/nodes on@nFurther commands can be retrieved by clicking on@nmachines/nodes with the Techage Info Tool.@n@nLocal commands:@n- clear @= clear screen@n- help @= this message@n- pub @= switch to public use@n- priv @= switch to private use@nTo program a user button with a command:@n set <button-num> <button-text> <command>@ne.g. 'set 1 ON cmd 123 on'@n=
(number / current / max.)=(Anzahl / aktuell / max.)
(Num. nodes loaded / max. : Power current / max.)=(Anz. Blöcke geladen / max. : Strom aktuell / max.)
Allow to dig/place Techage power lines nearby power poles=Erlaubt TODO
Ash=Asche
Autocrafter=Autocrafter
@ -20,6 +20,9 @@ Basalt Gravel=Basaltkies
Basalt Stone=Basaltgestein
Basalt Stone Block=Basaltsteinblock
Basalt Stone Brick=Basaltsteinziegel
Bauxite Cobblestone=Bauxit Kopfsteinpflaster
Bauxite Gravel=Bauxit Kies
Bauxite Stone=Bauxit
Biome=Biom
Block configured items for open ports=Blockiere konfigurierte Gegenstände für offene Ausgänge
Build derrick=Errichte Ölturm
@ -62,6 +65,7 @@ Oil Drill Box=Ölbohrkiste
Oil Pumpjack=Ölpumpe
Oil Source=Erdöl
Oil amount:=Ölmenge:
Other consumers=Weitere Verbraucher
Outp=Ergeb.
Plan=Plan
Position=Position
@ -163,6 +167,7 @@ TA4 Electrolyzer=TA4 Elektrolyseur
TA4 Energy Storage=TA4 Energiespeicher
TA4 Epoxide Resin=TA4 Epoxidharz
TA4 Fuel Cell=TA4 Brennstoffzelle
TA4 Fuel Cell Stack=Brennstoffzellenstapel
TA4 Generator=TA4 Generator
TA4 Heat Exchanger=TA4 Wärmetauscher
TA4 Heat Exchanger 1=TA4 Wärmetauscher 1
@ -176,6 +181,7 @@ TA4 Pillar=TA4 Säule
TA4 Pipe=TA4 Röhre
TA4 Pipe Inlet=TA4 Rohrzulauf
TA4 Protected Chest=TA4 Gesicherte Kiste
TA4 Reactor=Reaktor
TA4 Rotor Blade=TA4 Rotorblatt
TA4 Silicon Wafer=TA4 Silizium-Wafer
TA4 Solar Carrier Module=TA4 Solar Trägermodul
@ -227,6 +233,8 @@ added=hinzugefügt wird
added or removed=hinzugefügt oder entfernt wird
commands like: help=Kommandos wie: help
connected with=verbunden mit
light=Licht
power=Strom
removed=entfernt
stopped=gestoppt
##### not used anymore #####

View File

@ -1,5 +1,5 @@
#### TA3 Terminal ####@n@nSend commands to your machines@nand output text messages from your@nmachines to the Terminal.@n@nCommand syntax:@n cmd <num> <cmnd>@n@nexample: cmd 181 on@n<num> is the number of the node to which the command is sent@n'on' is the command to turn machines/nodes on@nFurther commands can be retrieved by clicking on@nmachines/nodes with the Techage Info Tool.@n@nLocal commands:@n- clear @= clear screen@n- help @= this message@n- pub @= switch to public use@n- priv @= switch to private use@nTo program a user button with a command:@n set <button-num> <button-text> <command>@ne.g. 'set 1 ON cmd 123 on'@n=
(number / current / max.)=
(Num. nodes loaded / max. : Power current / max.)=
Allow to dig/place Techage power lines nearby power poles=
Ash=
Autocrafter=
@ -18,6 +18,9 @@ Basalt Gravel=
Basalt Stone=
Basalt Stone Block=
Basalt Stone Brick=
Bauxite Cobblestone=
Bauxite Gravel=
Bauxite Stone=
Biome=
Block configured items for open ports=
Build derrick=
@ -60,6 +63,7 @@ Oil Drill Box=
Oil Pumpjack=
Oil Source=
Oil amount:=
Other consumers=
Outp=
Plan=
Position=
@ -161,6 +165,7 @@ TA4 Electrolyzer=
TA4 Energy Storage=
TA4 Epoxide Resin=
TA4 Fuel Cell=
TA4 Fuel Cell Stack=
TA4 Generator=
TA4 Heat Exchanger=
TA4 Heat Exchanger 1=
@ -174,6 +179,7 @@ TA4 Pillar=
TA4 Pipe=
TA4 Pipe Inlet=
TA4 Protected Chest=
TA4 Reactor=
TA4 Rotor Blade=
TA4 Silicon Wafer=
TA4 Solar Carrier Module=
@ -225,5 +231,7 @@ added=
added or removed=
commands like: help=
connected with=
light=
power=
removed=
stopped=

61
nodes/bauxit.lua Normal file
View File

@ -0,0 +1,61 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
GPL v3
See LICENSE.txt for more information
Bauxite
]]--
local S = techage.S
minetest.register_node("techage:bauxite_stone", {
description = S("Bauxite Stone"),
tiles = {"default_desert_stone.png^techage_bauxit_overlay.png^[colorize:#800000:80"},
groups = {cracky = 3, stone = 1},
drop = 'techage:bauxite_cobble',
sounds = default.node_sound_stone_defaults(),
--paramtype = "light",
--light_source = minetest.LIGHT_MAX
})
minetest.register_node("techage:bauxite_cobble", {
description = S("Bauxite Cobblestone"),
tiles = {"default_desert_cobble.png^[colorize:#800000:80"},
is_ground_content = false,
groups = {cracky = 3, stone = 2},
sounds = default.node_sound_stone_defaults(),
})
minetest.register_node("techage:bauxite_gravel", {
description = S("Bauxite Gravel"),
tiles = {"default_gravel.png^[colorize:#9b1f06:180"},
is_ground_content = false,
groups = {crumbly = 2, falling_node = 1},
sounds = default.node_sound_gravel_defaults(),
})
minetest.register_ore({
ore_type = "blob",
ore = "techage:bauxite_stone",
wherein = {"default:stone"},
clust_scarcity = 12 * 12 * 12,
clust_size = 5,
y_max = -100,
y_min = -200,
noise_threshold = 0.0,
noise_params = {
offset = 0.5,
scale = 0.2,
spread = {x = 8, y = 8, z = 8},
seed = 1234, --2316,
octaves = 1,
persist = 0.0
},
biomes = {"underground"}
})

View File

@ -220,16 +220,14 @@ local function min(val, max)
end
local function accounting(pos, mem)
if mem.pwr_is_master then
-- calculate the primary and secondary supply and demand
mem.mst_supply1 = min(mem.mst_needed1 + mem.mst_needed2, mem.mst_available1)
mem.mst_demand1 = min(mem.mst_needed1, mem.mst_available1 + mem.mst_available2)
mem.mst_supply2 = min(mem.mst_demand1 - mem.mst_supply1, mem.mst_available2)
mem.mst_demand2 = min(mem.mst_supply1 - mem.mst_demand1, mem.mst_available1)
mem.mst_reserve = (mem.mst_available1 + mem.mst_available2) - mem.mst_needed1
if D.sts then D.dbg("needed = "..mem.mst_needed1.."/"..mem.mst_needed2..", available = "..mem.mst_available1.."/"..mem.mst_available2) end
if D.sts then D.dbg("supply = "..mem.mst_supply1.."/"..mem.mst_supply2..", demand = "..mem.mst_demand1.."/"..mem.mst_demand2..", reserve = "..mem.mst_reserve) end
end
-- calculate the primary and secondary supply and demand
mem.mst_supply1 = min(mem.mst_needed1 + mem.mst_needed2, mem.mst_available1)
mem.mst_demand1 = min(mem.mst_needed1, mem.mst_available1 + mem.mst_available2)
mem.mst_supply2 = min(mem.mst_demand1 - mem.mst_supply1, mem.mst_available2)
mem.mst_demand2 = min(mem.mst_supply1 - mem.mst_demand1, mem.mst_available1)
mem.mst_reserve = (mem.mst_available1 + mem.mst_available2) - mem.mst_needed1
if D.sts then D.dbg("needed = "..mem.mst_needed1.."/"..mem.mst_needed2..", available = "..mem.mst_available1.."/"..mem.mst_available2) end
if D.sts then D.dbg("supply = "..mem.mst_supply1.."/"..mem.mst_supply2..", demand = "..mem.mst_demand1.."/"..mem.mst_demand2..", reserve = "..mem.mst_reserve) end
end
local function connection_walk(pos, clbk)
@ -318,10 +316,16 @@ local function store_master(pos, master_pos)
pos_already_reached(pos)
connection_walk(pos, function(pos, mem)
mem.pwr_master_pos = master_pos
mem.pwr_is_master = false
end)
end
local function master_mem(mem)
if mem.pwr_master_pos then
local netkey = minetest.hash_node_position(mem.pwr_master_pos)
return techage.schedule.get_network(netkey)
end
end
local function handle_generator(mst_mem, mem, pos, power_available)
-- for next cycle
mst_mem.mst_available1 = (mst_mem.mst_available1 or 0) + power_available
@ -420,33 +424,32 @@ local function turn_off_nodes(mst_pos)
end
local function determine_new_master(pos, mem)
local was_master = mem.pwr_is_master
mem.pwr_is_master = false
local mpos = determine_master(pos)
store_master(pos, mpos)
if mpos then
local mmem = tubelib2.get_mem(mpos)
mmem.pwr_is_master = true
mmem.mst_num_nodes = NumNodes
elseif was_master then -- no master any more
-- delete data
mem.mst_supply1 = 0
mem.mst_supply2 = 0
mem.mst_reserve = 0
end
return was_master or mem.pwr_is_master
mem.pwr_master_pos = mpos
return true
end
-- called from master position
local function power_distribution(pos, mem, dec)
if D.pwr then D.dbg("power_distribution") end
if mem.pwr_is_master then
mem.mst_needed1 = 0
mem.mst_needed2 = 0
mem.mst_available1 = 0
mem.mst_available2 = 0
-- called from all nodes
local function trigger_network(pos, mem)
if mem.pwr_master_pos then
local netkey = minetest.hash_node_position(mem.pwr_master_pos)
local network = techage.schedule.get_network(netkey) or
techage.schedule.add_network(netkey, {mst_pos = mem.pwr_master_pos})
network.alive = 10
else
print("node without master_pos "..N(pos).." at "..S(pos))
end
trigger_nodes(pos, mem, dec or 0)
end
-- called from global timer
function techage.power.power_distribution(time, pos, mem)
if D.pwr then D.dbg("power_distribution"..math.floor(time).." "..N(pos)) end
mem.mst_needed1 = 0
mem.mst_needed2 = 0
mem.mst_available1 = 0
mem.mst_available2 = 0
trigger_nodes(pos, mem, 1)
accounting(pos, mem)
end
@ -458,14 +461,8 @@ end
function techage.power.network_changed(pos, mem)
if D.pwr then D.dbg("network_changed") end
mem.pwr_node_alive_cnt = (mem.pwr_cycle_time or 2)/2 + 1
if determine_new_master(pos, mem) then -- new master?
power_distribution(pos, mem)
elseif not mem.pwr_master_pos then -- no master?
turn_off_nodes(pos)
elseif not next(mem.connections) then -- isolated?
if mem.pwr_needed then -- consumer?
consumer_turn_off(pos, mem)
end
if determine_new_master(pos, mem) then -- new master
trigger_network(pos, mem)
end
end
@ -477,7 +474,7 @@ function techage.power.generator_start(pos, mem, available)
mem.pwr_cycle_time = 2
mem.pwr_available = available
if determine_new_master(pos, mem) then -- new master
power_distribution(pos, mem)
trigger_network(pos, mem)
end
end
@ -489,15 +486,13 @@ function techage.power.generator_stop(pos, mem)
mem.pwr_node_alive_cnt = 0
mem.pwr_available = 0
if determine_new_master(pos, mem) then -- last available master
power_distribution(pos, mem)
trigger_network(pos, mem)
end
end
function techage.power.generator_alive(pos, mem)
mem.pwr_node_alive_cnt = 2
if mem.pwr_is_master then
power_distribution(pos, mem, 1)
end
trigger_network(pos, mem)
return mem.pwr_provided or 0
end
@ -531,8 +526,8 @@ end
-- Lamp related function to speed up the turn on
function techage.power.power_available(pos, mem, needed)
if mem.pwr_master_pos and (mem.pwr_power_provided_cnt or 0) > 0 then
mem = tubelib2.get_mem(mem.pwr_master_pos)
if (mem.mst_reserve or 0) >= needed then
mem = master_mem(mem)
if mem and (mem.mst_reserve or 0) >= needed then
mem.mst_reserve = (mem.mst_reserve or 0) - needed
return true
end
@ -544,14 +539,16 @@ end
function techage.power.power_accounting(pos, mem)
if mem.pwr_master_pos and (mem.pwr_power_provided_cnt or 0) > 0 then
mem.pwr_power_provided_cnt = (mem.pwr_power_provided_cnt or 0) - 1
mem = tubelib2.get_mem(mem.pwr_master_pos)
return {
prim_available = mem.mst_available1 or 0,
sec_available = mem.mst_available2 or 0,
prim_needed = mem.mst_needed1 or 0,
sec_needed = mem.mst_needed2 or 0,
num_nodes = mem.mst_num_nodes or 0,
}
mem = master_mem(mem)
if mem then
return {
prim_available = mem.mst_available1 or 0,
sec_available = mem.mst_available2 or 0,
prim_needed = mem.mst_needed1 or 0,
sec_needed = mem.mst_needed2 or 0,
num_nodes = mem.mst_num_nodes or 0,
}
end
end
return {
prim_available = 0,
@ -570,7 +567,7 @@ function techage.power.secondary_start(pos, mem, available, needed)
mem.pwr_could_provide = available
mem.pwr_could_need = needed
if determine_new_master(pos, mem) then -- new master
power_distribution(pos, mem)
trigger_network(pos, mem)
end
end
@ -580,7 +577,7 @@ function techage.power.secondary_stop(pos, mem)
mem.pwr_could_need = 0
mem.pwr_needed2 = 0
if determine_new_master(pos, mem) then -- last available master
power_distribution(pos, mem)
trigger_network(pos, mem)
end
end
@ -597,7 +594,7 @@ function techage.power.secondary_alive(pos, mem, capa_curr, capa_max)
mem.pwr_node_alive_cnt = 2
if mem.pwr_is_master then
if D.pwr then D.dbg("secondary_alive is master") end
power_distribution(pos, mem, 1)
trigger_network(pos, mem)
end
if mem.pwr_master_pos then
return mem.pwr_provided or 0

View File

@ -102,6 +102,8 @@ local function add_connection(mem, pos, out_dir, peer_pos, peer_in_dir, power)
else
mem.connections[out_dir] = {pos = peer_pos, in_dir = peer_in_dir}
end
-- update network for power scheduling
techage.power.network_changed(pos, mem)
end
function techage.power.register_node(names, pwr_def)

87
power/schedule.lua Normal file
View File

@ -0,0 +1,87 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
GPL v3
See LICENSE.txt for more information
Global power Job Scheduler
]]--
-- for lazy programmers
local P2P = 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 = function(pos) return minetest.get_node(pos).name end
local CYCLE_TIME = 2.0
techage.schedule = {}
local NetList = {}
local JobQueue = {}
local first = 0
local last = -1
local LocalTime = 0
local function push(item)
last = last + 1
item.time = LocalTime + CYCLE_TIME
JobQueue[last] = item
end
local function pop()
if first > last then return end
local item = JobQueue[first]
if item.time <= LocalTime then
JobQueue[first] = nil -- to allow garbage collection
first = first + 1
return item
end
end
-- Scheduler
minetest.register_globalstep(function(dtime)
LocalTime = LocalTime + dtime
local item = pop()
while item do
local network = NetList[item.netkey]
if network and network.alive and network.alive >= 0 then
--techage.distribute.power_distribution(LocalTime, network)
techage.power.power_distribution(LocalTime, network.mst_pos, network)
network.alive = network.alive - 1
push(item)
else
NetList[item.netkey] = nil
end
item = pop()
end
end)
function techage.schedule.add_network(netkey, network)
if netkey then
if NetList[netkey] then -- already scheduled
NetList[netkey] = network
else
NetList[netkey] = network
push({netkey = netkey})
end
return NetList[netkey]
end
end
function techage.schedule.has_network(netkey)
if netkey then
return NetList[netkey] ~= nil
end
end
function techage.schedule.get_network(netkey)
if netkey then
return NetList[netkey]
end
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB